This repository has been archived by the owner on Jan 4, 2018. It is now read-only.
forked from glycerine/go-capnproto
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaddress.go
103 lines (82 loc) · 2.66 KB
/
address.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package capnp
// An Address is an index inside a segment's data (in bytes).
type Address uint32
// addSize returns the address a+sz.
func (a Address) addSize(sz Size) Address {
return a.element(1, sz)
}
// element returns the address a+i*sz.
func (a Address) element(i int32, sz Size) Address {
return a + Address(sz.times(i))
}
// addOffset returns the address a+o.
func (a Address) addOffset(o DataOffset) Address {
return a + Address(o)
}
// A Size is a size (in bytes).
type Size uint32
// wordSize is the number of bytes in a Cap'n Proto word.
const wordSize Size = 8
// maxSize is the maximum representable size.
const maxSize Size = 1<<32 - 1
// times returns the size sz*n.
func (sz Size) times(n int32) Size {
result := int64(sz) * int64(n)
if result > int64(maxSize) {
panic(errOverlarge)
}
return Size(result)
}
// padToWord adds padding to sz to make it divisible by wordSize.
func (sz Size) padToWord() Size {
n := Size(wordSize - 1)
return (sz + n) &^ n
}
// DataOffset is an offset in bytes from the beginning of a struct's data section.
type DataOffset uint32
// ObjectSize records section sizes for a struct or list.
type ObjectSize struct {
DataSize Size
PointerCount uint16
}
// isZero reports whether sz is the zero size.
func (sz ObjectSize) isZero() bool {
return sz.DataSize == 0 && sz.PointerCount == 0
}
// isOneByte reports whether the object size is one byte (for Text/Data element sizes).
func (sz ObjectSize) isOneByte() bool {
return sz.DataSize == 1 && sz.PointerCount == 0
}
// isValid reports whether sz's fields are in range.
func (sz ObjectSize) isValid() bool {
return sz.DataSize <= 0xffff*wordSize
}
// pointerSize returns the number of bytes the pointer section occupies.
func (sz ObjectSize) pointerSize() Size {
return wordSize.times(int32(sz.PointerCount))
}
// totalSize returns the number of bytes that the object occupies.
func (sz ObjectSize) totalSize() Size {
return sz.DataSize + sz.pointerSize()
}
// dataWordCount returns the number of words in the data section.
func (sz ObjectSize) dataWordCount() int32 {
if sz.DataSize%wordSize != 0 {
panic("data size not aligned by word")
}
return int32(sz.DataSize / wordSize)
}
// totalWordCount returns the number of words that the object occupies.
func (sz ObjectSize) totalWordCount() int32 {
return sz.dataWordCount() + int32(sz.PointerCount)
}
// BitOffset is an offset in bits from the beginning of a struct's data section.
type BitOffset uint32
// offset returns the equivalent byte offset.
func (bit BitOffset) offset() DataOffset {
return DataOffset(bit / 8)
}
// mask returns the bitmask for the bit.
func (bit BitOffset) mask() byte {
return byte(1 << (bit % 8))
}