github.com/fmstephe/unsafeutil@v1.0.0/convert_test.go (about)

     1  package unsafeutil
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  	"unsafe"
     7  )
     8  
     9  func TestStringToBytes(t *testing.T) {
    10  	s := "string"
    11  	b := StringToBytes(s)
    12  	// Should have the same length
    13  	if len(s) != len(b) {
    14  		t.Errorf("Converted bytes have different length (%d) than the string (%d)", len(b), len(s))
    15  	}
    16  	if len(s) != cap(b) {
    17  		t.Errorf("Converted bytes have capacity (%d) beyond the length of string (%d)", cap(b), len(s))
    18  	}
    19  	// Should have same content
    20  	if s != string(b) {
    21  		t.Errorf("Converted bytes has different value %q than the string %q", string(b), s)
    22  	}
    23  	// Should point to the same data in memory
    24  	sData := (*(*reflect.StringHeader)(unsafe.Pointer(&s))).Data
    25  	bData := (*(*reflect.SliceHeader)(unsafe.Pointer(&b))).Data
    26  	if sData != bData {
    27  		t.Errorf("Converted bytes points to different data %d than the string %d", sData, bData)
    28  	}
    29  }
    30  
    31  func TestBytesToString(t *testing.T) {
    32  	b := []byte("bytes!")
    33  	s := BytesToString(b)
    34  	// Should have the same length
    35  	if len(s) != len(b) {
    36  		t.Errorf("Converted string has a different length (%d) than the bytes (%d)", len(s), len(b))
    37  	}
    38  	// Should have same content
    39  	if s != string(b) {
    40  		t.Errorf("Converted string has a different value %q than the bytes %q", s, string(b))
    41  	}
    42  	// Should point to the same data in memory
    43  	sData := (*(*reflect.StringHeader)(unsafe.Pointer(&s))).Data
    44  	bData := (*(*reflect.SliceHeader)(unsafe.Pointer(&b))).Data
    45  	if sData != bData {
    46  		t.Errorf("Converted string points to different data %d than the bytes %d", sData, bData)
    47  	}
    48  }
    49  
    50  // Check we don't access the entire byte slice's capacity
    51  func TestBytesToString_WithUnusedBytes(t *testing.T) {
    52  	// make a long slice of bytes
    53  	bLongDontUse := []byte("bytes! and all these other bytes")
    54  	// just take the first 6 characters
    55  	b := bLongDontUse[:6]
    56  	s := BytesToString(b)
    57  	// Should have the same length
    58  	if len(s) != len(b) {
    59  		t.Errorf("Converted string has a different length (%d) than the bytes (%d)", len(s), len(b))
    60  	}
    61  	// Should have same content
    62  	if s != string(b) {
    63  		t.Errorf("Converted string has a different value %q than the bytes %q", s, string(b))
    64  	}
    65  	// Should point to the same data in memory
    66  	sData := (*(*reflect.StringHeader)(unsafe.Pointer(&s))).Data
    67  	bData := (*(*reflect.SliceHeader)(unsafe.Pointer(&b))).Data
    68  	if sData != bData {
    69  		t.Errorf("Converted string points to different data %d than the bytes %d", sData, bData)
    70  	}
    71  }
    72  
    73  func TestStringHeadersCompatible(t *testing.T) {
    74  	// Check to make sure string header is what reflect thinks it is.
    75  	// They should be the same except for the type of the data field.
    76  	if unsafe.Sizeof(stringHeader{}) != unsafe.Sizeof(reflect.StringHeader{}) {
    77  		t.Errorf("stringHeader layout has changed ours %#v theirs %#v", stringHeader{}, reflect.StringHeader{})
    78  	}
    79  	x := stringHeader{}
    80  	y := reflect.StringHeader{}
    81  	x.data = unsafe.Pointer(y.Data)
    82  	y.Data = uintptr(x.data)
    83  	x.stringLen = y.Len
    84  	y.Len = x.stringLen
    85  	// If we can do all of that then the two structs are compatible
    86  }
    87  
    88  func TestSliceHeadersCompatible(t *testing.T) {
    89  	// Check to make sure string header is what reflect thinks it is.
    90  	// They should be the same except for the type of the data field.
    91  	if unsafe.Sizeof(sliceHeader{}) != unsafe.Sizeof(reflect.SliceHeader{}) {
    92  		t.Errorf("sliceHeader layout has changed ours %#v theirs %#v", sliceHeader{}, reflect.SliceHeader{})
    93  	}
    94  	x := sliceHeader{}
    95  	y := reflect.SliceHeader{}
    96  	x.data = unsafe.Pointer(y.Data)
    97  	y.Data = uintptr(x.data)
    98  	x.sliceLen = y.Len
    99  	y.Len = x.sliceLen
   100  	x.sliceCap = y.Cap
   101  	y.Cap = x.sliceCap
   102  	// If we can do all of that then the two structs are compatible
   103  }