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) {
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)
+ }
}
}