Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
October 22, 2021 01:09 am GMT

CONVERT BYTE SLICE TO AND FROM OTHER TYPES

package mainimport (    "fmt"    "reflect"    "unsafe")//byte slice pointer to string pointer convertionfunc bsPtrToStrPtr(bsPtr *[]byte) (strPtr *string) {    return (*string)(unsafe.Pointer(bsPtr))}//string pointer to byte slice pointer convertionfunc strPtrToBsPtr(strPtr *string) (bsPtr *[]byte) {    bsPtr = (*[]byte)(unsafe.Pointer(strPtr))    //the capacity of *bsPtr still not set    //so it must be set with the length of *strPtr    //setting its capacity must be done via reflection to reach their header    (*reflect.SliceHeader)(unsafe.Pointer(bsPtr)).Cap = (*reflect.SliceHeader)(unsafe.Pointer(strPtr)).Len    return}//byte slice pointer to int64 pointer convertionfunc bsPtrToInt64Ptr(bsPtr *[]byte) (int64Ptr *int64) {    return (*int64)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(bsPtr)).Data))}//int64 pointer to byte slice pointer convertionfunc int64PtrToBsPtr(int64Ptr *int64, bsPtr *[]byte) {    //int64 does not have header like string, so we can not do like this :    //bsPtr = (*[]byte)(unsafe.Pointer(int64Ptr)    //like on string convertion above    //if we do that, the SliceHeader.Data of *bsPtr will contain    //value (*int64Ptr), not pointer (int64Ptr) as it should be    slcHdr := (*reflect.SliceHeader)(unsafe.Pointer(bsPtr))    slcHdr.Data = uintptr(unsafe.Pointer(int64Ptr))    slcHdr.Len = 8 //we know that the size of int64 is 8 byte    slcHdr.Cap = 8}//reverse byte slicefunc 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 main() {    bs := []byte("test 123")    strPtr := bsPtrToStrPtr(&bs)    fmt.Printf("byte slice: %s, type: %T; string: %s, type: %T
", bs, bs, *strPtr, *strPtr) //be noticed that if we change bs value(must have same length with original value), //then the value of *strPtr also changed bs = []byte("123 test") fmt.Printf("byte slice: %s, type: %T; string: %s, type: %T
", bs, bs, *strPtr, *strPtr) //and vice versa *strPtr = "wertyuio" fmt.Printf("byte slice: %s, type: %T; string: %s, type: %T
", bs, bs, *strPtr, *strPtr) fmt.Println("byte slice, length:", len(bs), "& capacity:", cap(bs), ";string length:", len(*strPtr)) fmt.Println() str := "asdfghjkl" bsPtr := strPtrToBsPtr(&str) fmt.Printf("byte slice: %s, type: %T; string: %s, type: %T
", *bsPtr, *bsPtr, str, str) //be noticed that if we change str value(must have same length with original value), //then the value of *bsPtr also changed str = "lkjhgfdsa" fmt.Printf("byte slice: %s, type: %T; string: %s, type: %T
", *bsPtr, *bsPtr, str, str) //and vice versa *bsPtr = []byte("1234S6789") fmt.Printf("byte slice: %s, type: %T; string: %s, type: %T
", *bsPtr, *bsPtr, str, str) fmt.Println("byte slice, length:", len(*bsPtr), "& capacity:", cap(*bsPtr), ";string length:", len(str)) fmt.Println() //in slice, int64 allocation size is 8 bytes, index-0 hold LSB, index-7 hold MSB //LSB: least significant byte mean if we change that byte will only change little amount of the value //MSB: most significant byte mean the opposite of that I mentioned above bs = []byte{0x15, 0x81, 0xe9, 0x7d, 0xf4, 0x10, 0x22, 0x11} int64Ptr := bsPtrToInt64Ptr(&bs) //if we print byte slice, it will be displayed as how we write it on code //from index-0 will be displayed on leftmost, to last index will be displayed on rightmost fmt.Printf("byte slice: %x, type: %T
", bs, bs) //however as int64 value, it will print MSB on leftmost and LSB on rightmost fmt.Printf("int64(hex): %x, type: %T
", *int64Ptr, *int64Ptr) //bs = []byte{0xb1, 0x1c, 0x6c, 0xb1, 0xf4, 0x10, 0x22, 0x11} *int64Ptr = 1234567890987654321 //if we change the int64 value, the byte slice value will also change fmt.Printf("byte slice: %x, type: %T
", bs, bs) fmt.Printf("int64(hex): %x, type: %T
", *int64Ptr, *int64Ptr) fmt.Println() _int64 := int64(1234543210987656789) int64PtrToBsPtr(&_int64, &bs) fmt.Printf("byte slice: %x, type: %T
", bs, bs) fmt.Printf("int64(hex): %x, type: %T
", _int64, _int64) _int64 = int64(1231231230321321321) //bs = []byte{0x69, 0x65, 0xab, 0xd7, 0x47, 0x36, 0x16, 0x11} fmt.Printf("byte slice: %x, type: %T
", bs, bs) fmt.Printf("int64(hex): %x, type: %T
", _int64, _int64) fmt.Println() //other thing that also we must pay attention is about endianness (big endian & little endian) //i found this article that might be worth it to read : //https://www.freecodecamp.org/news/what-is-endianness-big-endian-vs-little-endian/ //to correct the endianness maybe we need byte slice reversal function : bs = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f} fmt.Printf("before reverse process: %x
", bs) reverse(bs) fmt.Printf("after reverse process: %x
", bs)}

build output :
bytesliceconversion_go

playground : https://play.golang.org/p/TCvWw1mf4kG


Original Link: https://dev.to/birowo/convert-byte-slice-to-and-from-other-types-4jkd

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To