...
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
33 package custom
34
35 import (
36 "bytes"
37 "encoding/json"
38 "errors"
39 )
40
41 type Uint128 [2]uint64
42
43 func (u Uint128) Marshal() ([]byte, error) {
44 buffer := make([]byte, 16)
45 _, err := u.MarshalTo(buffer)
46 return buffer, err
47 }
48
49 func (u Uint128) MarshalTo(data []byte) (n int, err error) {
50 PutLittleEndianUint128(data, 0, u)
51 return 16, nil
52 }
53
54 func GetLittleEndianUint64(b []byte, offset int) uint64 {
55 v := uint64(b[offset+7]) << 56
56 v += uint64(b[offset+6]) << 48
57 v += uint64(b[offset+5]) << 40
58 v += uint64(b[offset+4]) << 32
59 v += uint64(b[offset+3]) << 24
60 v += uint64(b[offset+2]) << 16
61 v += uint64(b[offset+1]) << 8
62 v += uint64(b[offset])
63 return v
64 }
65
66 func PutLittleEndianUint64(b []byte, offset int, v uint64) {
67 b[offset] = byte(v)
68 b[offset+1] = byte(v >> 8)
69 b[offset+2] = byte(v >> 16)
70 b[offset+3] = byte(v >> 24)
71 b[offset+4] = byte(v >> 32)
72 b[offset+5] = byte(v >> 40)
73 b[offset+6] = byte(v >> 48)
74 b[offset+7] = byte(v >> 56)
75 }
76
77 func PutLittleEndianUint128(buffer []byte, offset int, v [2]uint64) {
78 PutLittleEndianUint64(buffer, offset, v[0])
79 PutLittleEndianUint64(buffer, offset+8, v[1])
80 }
81
82 func GetLittleEndianUint128(buffer []byte, offset int) (value [2]uint64) {
83 value[0] = GetLittleEndianUint64(buffer, offset)
84 value[1] = GetLittleEndianUint64(buffer, offset+8)
85 return
86 }
87
88 func (u *Uint128) Unmarshal(data []byte) error {
89 if data == nil {
90 u = nil
91 return nil
92 }
93 if len(data) == 0 {
94 pu := Uint128{}
95 *u = pu
96 return nil
97 }
98 if len(data) != 16 {
99 return errors.New("Uint128: invalid length")
100 }
101 pu := Uint128(GetLittleEndianUint128(data, 0))
102 *u = pu
103 return nil
104 }
105
106 func (u Uint128) MarshalJSON() ([]byte, error) {
107 data, err := u.Marshal()
108 if err != nil {
109 return nil, err
110 }
111 return json.Marshal(data)
112 }
113
114 func (u Uint128) Size() int {
115 return 16
116 }
117
118 func (u *Uint128) UnmarshalJSON(data []byte) error {
119 v := new([]byte)
120 err := json.Unmarshal(data, v)
121 if err != nil {
122 return err
123 }
124 return u.Unmarshal(*v)
125 }
126
127 func (this Uint128) Equal(that Uint128) bool {
128 return this == that
129 }
130
131 func (this Uint128) Compare(that Uint128) int {
132 thisdata, err := this.Marshal()
133 if err != nil {
134 panic(err)
135 }
136 thatdata, err := that.Marshal()
137 if err != nil {
138 panic(err)
139 }
140 return bytes.Compare(thisdata, thatdata)
141 }
142
143 type randy interface {
144 Intn(n int) int
145 }
146
147 func NewPopulatedUint128(r randy) *Uint128 {
148 data := make([]byte, 16)
149 for i := 0; i < 16; i++ {
150 data[i] = byte(r.Intn(255))
151 }
152 u := Uint128(GetLittleEndianUint128(data, 0))
153 return &u
154 }
155
View as plain text