encode.gno
1.71 Kb · 96 lines
1package rlp
2
3// EncodeBytes returns the RLP string encoding of b.
4func EncodeBytes(b []byte) []byte {
5 out := make([]byte, 0, bytesSize(b))
6 return appendBytes(out, b)
7}
8
9// EncodeList returns the RLP list encoding of already-encoded items.
10func EncodeList(items ...[]byte) []byte {
11 size := 0
12 for _, item := range items {
13 size += len(item)
14 }
15
16 out := make([]byte, 0, listSize(size))
17
18 out = appendHeader(out, 0xC0, uint64(size))
19 for _, item := range items {
20 out = append(out, item...)
21 }
22
23 return out
24}
25
26func appendBytes(out []byte, b []byte) []byte {
27 if len(b) == 1 && b[0] <= 0x7f {
28 return append(out, b[0])
29 }
30
31 out = appendHeader(out, 0x80, uint64(len(b)))
32
33 return append(out, b...)
34}
35
36func bytesSize(b []byte) int {
37 n := len(b)
38 if n == 1 && b[0] <= 0x7f {
39 return 1
40 }
41
42 return headerSize(n) + n
43}
44
45func listSize(contentSize int) int {
46 return headerSize(contentSize) + contentSize
47}
48
49func appendHeader(out []byte, baseTag byte, size uint64) []byte {
50 if size < 56 {
51 return append(out, baseTag+byte(size))
52 }
53
54 n := intSize(size)
55 out = append(out, baseTag+55+byte(n))
56
57 return appendBigEndianUint(out, size, n)
58}
59
60// appendBigEndianUint appends the n low-order bytes of x to out, big-endian.
61func appendBigEndianUint(out []byte, x uint64, n int) []byte {
62 for i := n - 1; i >= 0; i-- {
63 out = append(out, byte(x>>uint(i*8)))
64 }
65
66 return out
67}
68
69func headerSize(payloadSize int) int {
70 if payloadSize < 56 {
71 return 1
72 }
73
74 return 1 + intSize(uint64(payloadSize))
75}
76
77func intSize(x uint64) int {
78 switch {
79 case x < 1<<8:
80 return 1
81 case x < 1<<16:
82 return 2
83 case x < 1<<24:
84 return 3
85 case x < 1<<32:
86 return 4
87 case x < 1<<40:
88 return 5
89 case x < 1<<48:
90 return 6
91 case x < 1<<56:
92 return 7
93 default:
94 return 8
95 }
96}