rlp.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. package common
  2. import (
  3. "bytes"
  4. "fmt"
  5. "math/big"
  6. "reflect"
  7. )
  8. type RlpEncode interface {
  9. RlpEncode() []byte
  10. }
  11. type RlpEncodeDecode interface {
  12. RlpEncode
  13. RlpValue() []interface{}
  14. }
  15. type RlpEncodable interface {
  16. RlpData() interface{}
  17. }
  18. func Rlp(encoder RlpEncode) []byte {
  19. return encoder.RlpEncode()
  20. }
  21. type RlpEncoder struct {
  22. rlpData []byte
  23. }
  24. func NewRlpEncoder() *RlpEncoder {
  25. encoder := &RlpEncoder{}
  26. return encoder
  27. }
  28. func (coder *RlpEncoder) EncodeData(rlpData interface{}) []byte {
  29. return Encode(rlpData)
  30. }
  31. const (
  32. RlpEmptyList = 0x80
  33. RlpEmptyStr = 0x40
  34. )
  35. const rlpEof = -1
  36. func Char(c []byte) int {
  37. if len(c) > 0 {
  38. return int(c[0])
  39. }
  40. return rlpEof
  41. }
  42. func DecodeWithReader(reader *bytes.Buffer) interface{} {
  43. var slice []interface{}
  44. // Read the next byte
  45. char := Char(reader.Next(1))
  46. switch {
  47. case char <= 0x7f:
  48. return char
  49. case char <= 0xb7:
  50. return reader.Next(int(char - 0x80))
  51. case char <= 0xbf:
  52. length := ReadVarInt(reader.Next(int(char - 0xb7)))
  53. return reader.Next(int(length))
  54. case char <= 0xf7:
  55. length := int(char - 0xc0)
  56. for i := 0; i < length; i++ {
  57. obj := DecodeWithReader(reader)
  58. slice = append(slice, obj)
  59. }
  60. return slice
  61. case char <= 0xff:
  62. length := ReadVarInt(reader.Next(int(char - 0xf7)))
  63. for i := uint64(0); i < length; i++ {
  64. obj := DecodeWithReader(reader)
  65. slice = append(slice, obj)
  66. }
  67. return slice
  68. default:
  69. panic(fmt.Sprintf("byte not supported: %q", char))
  70. }
  71. return slice
  72. }
  73. var (
  74. directRlp = big.NewInt(0x7f)
  75. numberRlp = big.NewInt(0xb7)
  76. zeroRlp = big.NewInt(0x0)
  77. )
  78. func intlen(i int64) (length int) {
  79. for i > 0 {
  80. i = i >> 8
  81. length++
  82. }
  83. return
  84. }
  85. func Encode(object interface{}) []byte {
  86. var buff bytes.Buffer
  87. if object != nil {
  88. switch t := object.(type) {
  89. case *Value:
  90. buff.Write(Encode(t.Val))
  91. case RlpEncodable:
  92. buff.Write(Encode(t.RlpData()))
  93. // Code dup :-/
  94. case int:
  95. buff.Write(Encode(big.NewInt(int64(t))))
  96. case uint:
  97. buff.Write(Encode(big.NewInt(int64(t))))
  98. case int8:
  99. buff.Write(Encode(big.NewInt(int64(t))))
  100. case int16:
  101. buff.Write(Encode(big.NewInt(int64(t))))
  102. case int32:
  103. buff.Write(Encode(big.NewInt(int64(t))))
  104. case int64:
  105. buff.Write(Encode(big.NewInt(t)))
  106. case uint16:
  107. buff.Write(Encode(big.NewInt(int64(t))))
  108. case uint32:
  109. buff.Write(Encode(big.NewInt(int64(t))))
  110. case uint64:
  111. buff.Write(Encode(big.NewInt(int64(t))))
  112. case byte:
  113. buff.Write(Encode(big.NewInt(int64(t))))
  114. case *big.Int:
  115. // Not sure how this is possible while we check for nil
  116. if t == nil {
  117. buff.WriteByte(0xc0)
  118. } else {
  119. buff.Write(Encode(t.Bytes()))
  120. }
  121. case Bytes:
  122. buff.Write(Encode([]byte(t)))
  123. case []byte:
  124. if len(t) == 1 && t[0] <= 0x7f {
  125. buff.Write(t)
  126. } else if len(t) < 56 {
  127. buff.WriteByte(byte(len(t) + 0x80))
  128. buff.Write(t)
  129. } else {
  130. b := big.NewInt(int64(len(t)))
  131. buff.WriteByte(byte(len(b.Bytes()) + 0xb7))
  132. buff.Write(b.Bytes())
  133. buff.Write(t)
  134. }
  135. case string:
  136. buff.Write(Encode([]byte(t)))
  137. case []interface{}:
  138. // Inline function for writing the slice header
  139. WriteSliceHeader := func(length int) {
  140. if length < 56 {
  141. buff.WriteByte(byte(length + 0xc0))
  142. } else {
  143. b := big.NewInt(int64(length))
  144. buff.WriteByte(byte(len(b.Bytes()) + 0xf7))
  145. buff.Write(b.Bytes())
  146. }
  147. }
  148. var b bytes.Buffer
  149. for _, val := range t {
  150. b.Write(Encode(val))
  151. }
  152. WriteSliceHeader(len(b.Bytes()))
  153. buff.Write(b.Bytes())
  154. default:
  155. // This is how it should have been from the start
  156. // needs refactoring (@fjl)
  157. v := reflect.ValueOf(t)
  158. switch v.Kind() {
  159. case reflect.Slice:
  160. var b bytes.Buffer
  161. for i := 0; i < v.Len(); i++ {
  162. b.Write(Encode(v.Index(i).Interface()))
  163. }
  164. blen := b.Len()
  165. if blen < 56 {
  166. buff.WriteByte(byte(blen) + 0xc0)
  167. } else {
  168. ilen := byte(intlen(int64(blen)))
  169. buff.WriteByte(ilen + 0xf7)
  170. t := make([]byte, ilen)
  171. for i := byte(0); i < ilen; i++ {
  172. t[ilen-i-1] = byte(blen >> (i * 8))
  173. }
  174. buff.Write(t)
  175. }
  176. buff.ReadFrom(&b)
  177. }
  178. }
  179. } else {
  180. // Empty list for nil
  181. buff.WriteByte(0xc0)
  182. }
  183. return buff.Bytes()
  184. }
  185. // TODO Use a bytes.Buffer instead of a raw byte slice.
  186. // Cleaner code, and use draining instead of seeking the next bytes to read
  187. func Decode(data []byte, pos uint64) (interface{}, uint64) {
  188. var slice []interface{}
  189. char := int(data[pos])
  190. switch {
  191. case char <= 0x7f:
  192. return data[pos], pos + 1
  193. case char <= 0xb7:
  194. b := uint64(data[pos]) - 0x80
  195. return data[pos+1 : pos+1+b], pos + 1 + b
  196. case char <= 0xbf:
  197. b := uint64(data[pos]) - 0xb7
  198. b2 := ReadVarInt(data[pos+1 : pos+1+b])
  199. return data[pos+1+b : pos+1+b+b2], pos + 1 + b + b2
  200. case char <= 0xf7:
  201. b := uint64(data[pos]) - 0xc0
  202. prevPos := pos
  203. pos++
  204. for i := uint64(0); i < b; {
  205. var obj interface{}
  206. // Get the next item in the data list and append it
  207. obj, prevPos = Decode(data, pos)
  208. slice = append(slice, obj)
  209. // Increment i by the amount bytes read in the previous
  210. // read
  211. i += (prevPos - pos)
  212. pos = prevPos
  213. }
  214. return slice, pos
  215. case char <= 0xff:
  216. l := uint64(data[pos]) - 0xf7
  217. b := ReadVarInt(data[pos+1 : pos+1+l])
  218. pos = pos + l + 1
  219. prevPos := b
  220. for i := uint64(0); i < uint64(b); {
  221. var obj interface{}
  222. obj, prevPos = Decode(data, pos)
  223. slice = append(slice, obj)
  224. i += (prevPos - pos)
  225. pos = prevPos
  226. }
  227. return slice, pos
  228. default:
  229. panic(fmt.Sprintf("byte not supported: %q", char))
  230. }
  231. return slice, 0
  232. }