From 0b643ea0976f7bbd3cebef08c449090869701226 Mon Sep 17 00:00:00 2001 From: "Joe Richey joerichey@google.com" Date: Mon, 17 Jul 2017 15:40:02 -0700 Subject: util: Add conversions for byte/pointer arrays --- util/util.go | 12 ++++++++++++ util/util_test.go | 41 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 4 deletions(-) (limited to 'util') diff --git a/util/util.go b/util/util.go index 32e5c06..792b66c 100644 --- a/util/util.go +++ b/util/util.go @@ -37,6 +37,18 @@ func Ptr(slice []byte) unsafe.Pointer { return unsafe.Pointer(&slice[0]) } +// ByteSlice takes a pointer to some data and views it as a slice of bytes. +// Note, indexing into this slice is unsafe. +func ByteSlice(ptr unsafe.Pointer) []byte { + return (*[1 << 30]byte)(ptr)[:] +} + +// PointerSlice takes a pointer to an array of pointers and views it as a slice +// of pointers. Note, indexing into this slice is unsafe. +func PointerSlice(ptr unsafe.Pointer) []unsafe.Pointer { + return (*[1 << 30]unsafe.Pointer)(ptr)[:] +} + // Index returns the first index i such that inVal == inArray[i]. // ok is true if we find a match, false otherwise. func Index(inVal int64, inArray []int64) (index int, ok bool) { diff --git a/util/util_test.go b/util/util_test.go index 33ce2ff..7739edd 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -20,19 +20,52 @@ package util import ( + "bytes" "testing" + "unsafe" ) const offset = 3 +var ( + byteArr = []byte{'a', 'b', 'c', 'd'} + ptrArr = []*int{&a, &b, &c, &d} + a = 1 + b = 2 + c = 3 + d = 4 +) + // Make sure the address behaves well under slicing func TestPtrOffset(t *testing.T) { - arr := []byte{'a', 'b', 'c', 'd'} - i1 := uintptr(Ptr(arr[offset:])) - i2 := uintptr(Ptr(arr)) + i1 := uintptr(Ptr(byteArr[offset:])) + i2 := uintptr(Ptr(byteArr)) if i1 != i2+offset { - t.Fatalf("pointers %v and %v do not have an offset of %v", i1, i2, offset) + t.Errorf("pointers %v and %v do not have an offset of %v", i1, i2, offset) + } +} + +// Tests that the ByteSlice method essentially reverses the Ptr method +func TestByteSlice(t *testing.T) { + ptr := Ptr(byteArr) + generatedArr := ByteSlice(ptr)[:len(byteArr)] + + if !bytes.Equal(byteArr, generatedArr) { + t.Errorf("generated array (%v) and original array (%v) do not agree", + generatedArr, byteArr) + } +} + +// Tests that the PointerSlice method correctly handles Go Pointers +func TestPointerSlice(t *testing.T) { + arrPtr := unsafe.Pointer(&ptrArr[0]) + + // Convert an array of unsafe pointers to int pointers. + for i, ptr := range PointerSlice(arrPtr)[:len(ptrArr)] { + if ptrArr[i] != (*int)(ptr) { + t.Errorf("generated array and original array disagree at %d", i) + } } } -- cgit v1.2.3