-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtype.go
311 lines (261 loc) · 7.47 KB
/
type.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
package rlp
import (
"math/big"
)
// RLP is a raw RLP encoded data that can be decoded into any other type later.
type RLP []byte
// Decode decodes RLP encoded data into the given value.
func (r RLP) Decode(dst Decoder) error {
_, err := dst.DecodeRLP(r)
return err
}
// Length returns the length of the string or number of items in the list.
// If the item is invalid, it returns 0.
func (r RLP) Length() int {
switch {
case r.IsString():
_, dataLen, _, _ := decodePrefix(r)
return int(dataLen)
case r.IsList():
_, dataLen, prefixLen, err := decodePrefix(r)
if err != nil {
return 0
}
totalLen := int(dataLen + uint64(prefixLen))
if len(r) < totalLen {
return 0
}
n := 0
d := r[prefixLen:totalLen]
for ; len(d) > 0; n++ {
_, dataLen, prefixLen, err := decodePrefix(d)
if err != nil {
return 0
}
totalLen := int(dataLen + uint64(prefixLen))
if totalLen > len(d) || totalLen == 0 {
return 0
}
d = d[totalLen:]
}
return n
}
return 0
}
// String attempts to decode itself as a string. If the decoding is
// successful, it returns the decoded string.
func (r RLP) String() (v String, err error) {
_, err = (&v).DecodeRLP(r)
return
}
// Bytes attempts to decode itself as a byte slice. If the decoding is
// successful, it returns the decoded byte slice.
func (r RLP) Bytes() (v Bytes, err error) {
_, err = (&v).DecodeRLP(r)
return
}
// List attempts to decode itself as a list. If the decoding is
// successful, it returns the decoded list.
func (r RLP) List() (l TypedList[RLP], err error) {
_, err = (&l).DecodeRLP(r)
return
}
// Uint attempts to decode itself as an uint64. If the decoding is
// successful, it returns the decoded uint64.
func (r RLP) Uint() (v Uint, err error) {
_, err = (&v).DecodeRLP(r)
return
}
// BigInt attempts to decode itself as a big.Int. If the decoding is
// successful, it returns the decoded big.Int.
func (r RLP) BigInt() (v *BigInt, err error) {
v = new(BigInt)
_, err = v.DecodeRLP(r)
return
}
// IsString returns true if the encoded data is an RLP string.
// Do not confuse this with the Go string type; an RLP string could be decoded
// as a string, byte slice, uint64, or big.Int.
// If the RLP data is empty, it returns false.
func (r RLP) IsString() bool {
if len(r) == 0 {
return false
}
return r[0] <= longStringMax
}
// IsList returns true if the encoded data is an RLP list.
// If the RLP data is empty, it returns false.
func (r RLP) IsList() bool {
if len(r) == 0 {
return false
}
return r[0] >= listOffset
}
// EncodeRLP implements the Encoder interface.
func (r RLP) EncodeRLP() ([]byte, error) {
return r, nil
}
// DecodeRLP implements the Decoder interface.
func (r *RLP) DecodeRLP(data []byte) (int, error) {
_, dataLen, prefixLen, err := decodePrefix(data)
if err != nil {
return 0, err
}
totalLen := int(dataLen + uint64(prefixLen))
if totalLen > len(data) {
return 0, ErrUnexpectedEndOfData
}
*r = data[:totalLen]
return totalLen, nil
}
// String is a string type that can be encoded and decoded to/from RLP.
type String string
// Get returns the string value.
func (s String) Get() string {
return string(s)
}
// Set sets the string value.
func (s *String) Set(value string) {
*s = String(value)
}
// EncodeRLP implements the Encoder interface.
func (s String) EncodeRLP() ([]byte, error) {
return encodeString(string(s))
}
// DecodeRLP implements the Decoder interface.
func (s *String) DecodeRLP(data []byte) (int, error) {
return decodeString(data, (*string)(s))
}
// Bytes is a byte slice type that can be encoded and decoded to/from RLP.
type Bytes []byte
// Get returns the byte slice value.
func (b Bytes) Get() []byte {
return b
}
// Set sets the byte slice value.
func (b *Bytes) Set(value []byte) {
*b = value
}
// Ptr returns a pointer to the byte slice value.
func (b *Bytes) Ptr() *[]byte {
return (*[]byte)(b)
}
// EncodeRLP implements the Encoder interface.
func (b Bytes) EncodeRLP() ([]byte, error) {
return encodeBytes(b)
}
// DecodeRLP implements the Decoder interface.
func (b *Bytes) DecodeRLP(data []byte) (int, error) {
return decodeBytes(data, (*[]byte)(b))
}
// Uint is an uint64 type that can be encoded and decoded to/from RLP.
type Uint uint64
// Get returns the uint64 value.
func (u Uint) Get() uint64 {
return uint64(u)
}
// Ptr returns a pointer to the uint64 value.
func (u *Uint) Ptr() *uint64 {
return (*uint64)(u)
}
// Set sets the uint64 value.
func (u *Uint) Set(value uint64) {
*u = Uint(value)
}
// EncodeRLP implements the Encoder interface.
func (u Uint) EncodeRLP() ([]byte, error) {
return encodeUint(uint64(u))
}
// DecodeRLP implements the Decoder interface.
func (u *Uint) DecodeRLP(data []byte) (int, error) {
return decodeUint(data, (*uint64)(u))
}
// BigInt is a big.Int type that can be encoded and decoded to/from RLP.
type BigInt big.Int
// Get returns the big.Int value.
func (b BigInt) Get() *big.Int {
return (*big.Int)(&b)
}
// Ptr returns a pointer to the big.Int value.
func (b *BigInt) Ptr() *big.Int {
return (*big.Int)(b)
}
// Set sets the big.Int value.
func (b *BigInt) Set(value *big.Int) {
(*big.Int)(b).Set(value)
}
// EncodeRLP implements the Encoder interface.
func (b BigInt) EncodeRLP() ([]byte, error) {
return encodeBigInt((*big.Int)(&b))
}
// DecodeRLP implements the Decoder interface.
func (b *BigInt) DecodeRLP(data []byte) (int, error) {
return decodeBigInt(data, (*big.Int)(b))
}
// List represents a list of RLP items.
//
// List items must implement the Encoder interface if the list is being encoded,
// or the Decoder interface if the list is being decoded. Otherwise, the encoding
// or decoding will fail.
//
// During decoding, the data is decoded into existing items if they are already
// in the list. Otherwise, the items are decoded into RLP types.
type List []any
// Get returns the slice of items.
func (l List) Get() []any {
return l
}
// Ptr returns a pointer to the slice of items.
func (l *List) Ptr() *[]any {
return (*[]any)(l)
}
// Set sets the slice of items.
func (l *List) Set(items ...any) {
*l = items
}
// Add appends the given items to the list.
func (l *List) Add(items ...any) {
*l = append(*l, items...)
}
// EncodeRLP implements the Encoder interface.
func (l List) EncodeRLP() ([]byte, error) {
return encodeList(l)
}
// DecodeRLP implements the Decoder interface.
func (l *List) DecodeRLP(data []byte) (int, error) {
return decodeList(data, (*[]any)(l))
}
// TypedList represents a RLP list of a specific type.
//
// The T type must implement the Encoder interface if the list is being encoded,
// or the Decoder interface if the list is being decoded. Otherwise, the encoding
// or decoding will fail.
//
// During decoding, the data is decoded into existing items if they are already
// in the list. If the list is shorter than the data, new items are appended to
// the list.
type TypedList[T any] []*T
// Get returns the slice of items.
func (l TypedList[T]) Get() []*T {
return l
}
// Ptr returns a pointer to the slice of items.
func (l *TypedList[T]) Ptr() *[]*T {
return (*[]*T)(l)
}
// Set sets the slice of items.
func (l *TypedList[T]) Set(items ...*T) {
*l = items
}
// Add appends the given items to the list.
func (l *TypedList[T]) Add(items ...*T) {
*l = append(*l, items...)
}
// EncodeRLP implements the Encoder interface.
func (l TypedList[T]) EncodeRLP() ([]byte, error) {
return encodeTypedList(l)
}
// DecodeRLP implements the Decoder interface.
func (l *TypedList[T]) DecodeRLP(data []byte) (int, error) {
return decodeTypedList(data, (*[]*T)(l), func() *T { return new(T) })
}