An Interest In:
Web News this Week
- March 21, 2024
- March 20, 2024
- March 19, 2024
- March 18, 2024
- March 17, 2024
- March 16, 2024
- March 15, 2024
October 22, 2021 01:09 am GMT
Original Link: https://dev.to/birowo/convert-byte-slice-to-and-from-other-types-4jkd
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)}
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:
Tweet
View Full Article
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To