...
1 package danger
2
3 import (
4 "fmt"
5 "reflect"
6 "unsafe"
7 )
8
9 const maxInt = uintptr(int(^uint(0) >> 1))
10
11 func SubsliceOffset(data []byte, subslice []byte) int {
12 datap := (*reflect.SliceHeader)(unsafe.Pointer(&data))
13 hlp := (*reflect.SliceHeader)(unsafe.Pointer(&subslice))
14
15 if hlp.Data < datap.Data {
16 panic(fmt.Errorf("subslice address (%d) is before data address (%d)", hlp.Data, datap.Data))
17 }
18 offset := hlp.Data - datap.Data
19
20 if offset > maxInt {
21 panic(fmt.Errorf("slice offset larger than int (%d)", offset))
22 }
23
24 intoffset := int(offset)
25
26 if intoffset > datap.Len {
27 panic(fmt.Errorf("slice offset (%d) is farther than data length (%d)", intoffset, datap.Len))
28 }
29
30 if intoffset+hlp.Len > datap.Len {
31 panic(fmt.Errorf("slice ends (%d+%d) is farther than data length (%d)", intoffset, hlp.Len, datap.Len))
32 }
33
34 return intoffset
35 }
36
37 func BytesRange(start []byte, end []byte) []byte {
38 if start == nil || end == nil {
39 panic("cannot call BytesRange with nil")
40 }
41 startp := (*reflect.SliceHeader)(unsafe.Pointer(&start))
42 endp := (*reflect.SliceHeader)(unsafe.Pointer(&end))
43
44 if startp.Data > endp.Data {
45 panic(fmt.Errorf("start pointer address (%d) is after end pointer address (%d)", startp.Data, endp.Data))
46 }
47
48 l := startp.Len
49 endLen := int(endp.Data-startp.Data) + endp.Len
50 if endLen > l {
51 l = endLen
52 }
53
54 if l > startp.Cap {
55 panic(fmt.Errorf("range length is larger than capacity"))
56 }
57
58 return start[:l]
59 }
60
61 func Stride(ptr unsafe.Pointer, size uintptr, offset int) unsafe.Pointer {
62
63
64 return unsafe.Pointer(uintptr(ptr) + uintptr(int(size)*offset))
65 }
66
View as plain text