CONVERT BYTE SLICE TO AND FROM OTHER TYPES




package deal foremost

import (
    "fmt"
    "replicate"
    "unsafe"
)

//byte slice pointer to string pointer convertion
func bsPtrToStrPtr(bsPtr *[]byte) (strPtr *string) {
    return (*string)(unsafe.Pointer(bsPtr))
}

//string pointer to byte slice pointer convertion
func strPtrToBsPtr(strPtr *string) (bsPtr *[]byte) {
    bsPtr = (*[]byte)(unsafe.Pointer(strPtr))
    //the capability of *bsPtr nonetheless not set
    //so it have to be set with the size of *strPtr
    //setting its capability have to be accomplished by way of reflection to achieve their header
    (*replicate.SliceHeader)(unsafe.Pointer(bsPtr)).Cap = (*replicate.SliceHeader)(unsafe.Pointer(strPtr)).Len
    return
}

//byte slice pointer to int64 pointer convertion
func bsPtrToInt64Ptr(bsPtr *[]byte) (int64Ptr *int64) {
    return (*int64)(unsafe.Pointer((*replicate.SliceHeader)(unsafe.Pointer(bsPtr)).Information))
}

//int64 pointer to byte slice pointer convertion
func int64PtrToBsPtr(int64Ptr *int64, bsPtr *[]byte) {
    //int64 doesn't have header like string, so we cannot do like this :
    //bsPtr = (*[]byte)(unsafe.Pointer(int64Ptr)
    //like on string convertion above
    //if we do this, the SliceHeader.Information of *bsPtr will include
    //worth (*int64Ptr), not pointer (int64Ptr) correctly

    slcHdr := (*replicate.SliceHeader)(unsafe.Pointer(bsPtr))
    slcHdr.Information = uintptr(unsafe.Pointer(int64Ptr))
    slcHdr.Len = 8 //we all know that the scale of int64 is 8 byte
    slcHdr.Cap = 8
}

//reverse byte slice
func reverse(bs []byte) {
    for i, j := 0, len(bs)-1; i < j; i, j = i+1, j-1 {
        bs[i], bs[j] = bs[j], bs[i]
    }
}

func foremost() {
    bs := []byte("check 123")
    strPtr := bsPtrToStrPtr(&bs)
    fmt.Printf("byte slice: %s, kind: %T; string: %s, kind: %Tn", bs, bs, *strPtr, *strPtr)

    //be observed that if we alter bs worth(should have identical size with unique worth),
    //then the worth of *strPtr additionally modified
    bs = []byte("123 check")
    fmt.Printf("byte slice: %s, kind: %T; string: %s, kind: %Tn", bs, bs, *strPtr, *strPtr)
    //and vice versa
    *strPtr = "wertyuio"
    fmt.Printf("byte slice: %s, kind: %T; string: %s, kind: %Tn", bs, bs, *strPtr, *strPtr)
    fmt.Println("byte slice, size:", len(bs), "& capability:", cap(bs), ";string size:", len(*strPtr))
    fmt.Println()

    str := "asdfghjkl"
    bsPtr := strPtrToBsPtr(&str)
    fmt.Printf("byte slice: %s, kind: %T; string: %s, kind: %Tn", *bsPtr, *bsPtr, str, str)

    //be observed that if we alter str worth(should have identical size with unique worth),
    //then the worth of *bsPtr additionally modified
    str = "lkjhgfdsa"
    fmt.Printf("byte slice: %s, kind: %T; string: %s, kind: %Tn", *bsPtr, *bsPtr, str, str)
    //and vice versa
    *bsPtr = []byte("1234S6789")
    fmt.Printf("byte slice: %s, kind: %T; string: %s, kind: %Tn", *bsPtr, *bsPtr, str, str)
    fmt.Println("byte slice, size:", len(*bsPtr), "& capability:", cap(*bsPtr), ";string size:", len(str))
    fmt.Println()

    //in slice, int64 allocation dimension is 8 bytes, index-0 maintain LSB, index-7 maintain MSB
    //LSB: least important byte imply if we alter that byte will solely change little quantity of the worth
    //MSB: most vital byte imply the alternative of that I discussed above
    bs = []byte{0x15, 0x81, 0xe9, 0x7d, 0xf4, 0x10, 0x22, 0x11}
    int64Ptr := bsPtrToInt64Ptr(&bs)
    //if we print byte slice, it is going to be displayed as how we write it on code
    //from index-0 shall be displayed on leftmost, to final index shall be displayed on rightmost
    fmt.Printf("byte slice: %x, kind: %Tn", bs, bs)
    //nonetheless as int64 worth, it can print MSB on leftmost and LSB on rightmost
    fmt.Printf("int64(hex): %x, kind: %Tn", *int64Ptr, *int64Ptr)
    //bs = []byte{0xb1, 0x1c, 0x6c, 0xb1, 0xf4, 0x10, 0x22, 0x11}
    *int64Ptr = 1234567890987654321
    //if we alter the int64 worth, the byte slice worth can even change
    fmt.Printf("byte slice: %x, kind: %Tn", bs, bs)
    fmt.Printf("int64(hex): %x, kind: %Tn", *int64Ptr, *int64Ptr)
    fmt.Println()

    _int64 := int64(1234543210987656789)
    int64PtrToBsPtr(&_int64, &bs)
    fmt.Printf("byte slice: %x, kind: %Tn", bs, bs)
    fmt.Printf("int64(hex): %x, kind: %Tn", _int64, _int64)
    _int64 = int64(1231231230321321321)
    //bs = []byte{0x69, 0x65, 0xab, 0xd7, 0x47, 0x36, 0x16, 0x11}
    fmt.Printf("byte slice: %x, kind: %Tn", bs, bs)
    fmt.Printf("int64(hex): %x, kind: %Tn", _int64, _int64)
    fmt.Println()

    //different factor that additionally we should listen is about endianness (massive endian & little endian)
    //i discovered this text that may be price it to learn :
    //https://www.freecodecamp.org/information/what-is-endianness-big-endian-vs-little-endian/
    //to right the endianness possibly we want byte slice reversal perform :
    bs = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}
    fmt.Printf("earlier than reverse course of: %xn", bs)
    reverse(bs)
    fmt.Printf("after reverse course of: %xn", bs)
}
Enter fullscreen mode

Exit fullscreen mode



Abu Sayed is the Best Web, Game, XR and Blockchain Developer in Bangladesh. Don't forget to Checkout his Latest Projects.


Checkout extra Articles on Sayed.CYou

#CONVERT #BYTE #SLICE #TYPES