encbuffer.go 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. // Copyright 2022 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package rlp
  17. import (
  18. "io"
  19. "math/big"
  20. "reflect"
  21. "sync"
  22. )
  23. type encBuffer struct {
  24. str []byte // string data, contains everything except list headers
  25. lheads []listhead // all list headers
  26. lhsize int // sum of sizes of all encoded list headers
  27. sizebuf [9]byte // auxiliary buffer for uint encoding
  28. }
  29. // The global encBuffer pool.
  30. var encBufferPool = sync.Pool{
  31. New: func() interface{} { return new(encBuffer) },
  32. }
  33. func getEncBuffer() *encBuffer {
  34. buf := encBufferPool.Get().(*encBuffer)
  35. buf.reset()
  36. return buf
  37. }
  38. func (buf *encBuffer) reset() {
  39. buf.lhsize = 0
  40. buf.str = buf.str[:0]
  41. buf.lheads = buf.lheads[:0]
  42. }
  43. // size returns the length of the encoded data.
  44. func (buf *encBuffer) size() int {
  45. return len(buf.str) + buf.lhsize
  46. }
  47. // makeBytes creates the encoder output.
  48. func (w *encBuffer) makeBytes() []byte {
  49. out := make([]byte, w.size())
  50. w.copyTo(out)
  51. return out
  52. }
  53. func (w *encBuffer) copyTo(dst []byte) {
  54. strpos := 0
  55. pos := 0
  56. for _, head := range w.lheads {
  57. // write string data before header
  58. n := copy(dst[pos:], w.str[strpos:head.offset])
  59. pos += n
  60. strpos += n
  61. // write the header
  62. enc := head.encode(dst[pos:])
  63. pos += len(enc)
  64. }
  65. // copy string data after the last list header
  66. copy(dst[pos:], w.str[strpos:])
  67. }
  68. // writeTo writes the encoder output to w.
  69. func (buf *encBuffer) writeTo(w io.Writer) (err error) {
  70. strpos := 0
  71. for _, head := range buf.lheads {
  72. // write string data before header
  73. if head.offset-strpos > 0 {
  74. n, err := w.Write(buf.str[strpos:head.offset])
  75. strpos += n
  76. if err != nil {
  77. return err
  78. }
  79. }
  80. // write the header
  81. enc := head.encode(buf.sizebuf[:])
  82. if _, err = w.Write(enc); err != nil {
  83. return err
  84. }
  85. }
  86. if strpos < len(buf.str) {
  87. // write string data after the last list header
  88. _, err = w.Write(buf.str[strpos:])
  89. }
  90. return err
  91. }
  92. // Write implements io.Writer and appends b directly to the output.
  93. func (buf *encBuffer) Write(b []byte) (int, error) {
  94. buf.str = append(buf.str, b...)
  95. return len(b), nil
  96. }
  97. // writeBool writes b as the integer 0 (false) or 1 (true).
  98. func (buf *encBuffer) writeBool(b bool) {
  99. if b {
  100. buf.str = append(buf.str, 0x01)
  101. } else {
  102. buf.str = append(buf.str, 0x80)
  103. }
  104. }
  105. func (buf *encBuffer) writeUint64(i uint64) {
  106. if i == 0 {
  107. buf.str = append(buf.str, 0x80)
  108. } else if i < 128 {
  109. // fits single byte
  110. buf.str = append(buf.str, byte(i))
  111. } else {
  112. s := putint(buf.sizebuf[1:], i)
  113. buf.sizebuf[0] = 0x80 + byte(s)
  114. buf.str = append(buf.str, buf.sizebuf[:s+1]...)
  115. }
  116. }
  117. func (buf *encBuffer) writeBytes(b []byte) {
  118. if len(b) == 1 && b[0] <= 0x7F {
  119. // fits single byte, no string header
  120. buf.str = append(buf.str, b[0])
  121. } else {
  122. buf.encodeStringHeader(len(b))
  123. buf.str = append(buf.str, b...)
  124. }
  125. }
  126. func (buf *encBuffer) writeString(s string) {
  127. buf.writeBytes([]byte(s))
  128. }
  129. // wordBytes is the number of bytes in a big.Word
  130. const wordBytes = (32 << (uint64(^big.Word(0)) >> 63)) / 8
  131. // writeBigInt writes i as an integer.
  132. func (w *encBuffer) writeBigInt(i *big.Int) {
  133. bitlen := i.BitLen()
  134. if bitlen <= 64 {
  135. w.writeUint64(i.Uint64())
  136. return
  137. }
  138. // Integer is larger than 64 bits, encode from i.Bits().
  139. // The minimal byte length is bitlen rounded up to the next
  140. // multiple of 8, divided by 8.
  141. length := ((bitlen + 7) & -8) >> 3
  142. w.encodeStringHeader(length)
  143. w.str = append(w.str, make([]byte, length)...)
  144. index := length
  145. buf := w.str[len(w.str)-length:]
  146. for _, d := range i.Bits() {
  147. for j := 0; j < wordBytes && index > 0; j++ {
  148. index--
  149. buf[index] = byte(d)
  150. d >>= 8
  151. }
  152. }
  153. }
  154. // list adds a new list header to the header stack. It returns the index of the header.
  155. // Call listEnd with this index after encoding the content of the list.
  156. func (buf *encBuffer) list() int {
  157. buf.lheads = append(buf.lheads, listhead{offset: len(buf.str), size: buf.lhsize})
  158. return len(buf.lheads) - 1
  159. }
  160. func (buf *encBuffer) listEnd(index int) {
  161. lh := &buf.lheads[index]
  162. lh.size = buf.size() - lh.offset - lh.size
  163. if lh.size < 56 {
  164. buf.lhsize++ // length encoded into kind tag
  165. } else {
  166. buf.lhsize += 1 + intsize(uint64(lh.size))
  167. }
  168. }
  169. func (buf *encBuffer) encode(val interface{}) error {
  170. rval := reflect.ValueOf(val)
  171. writer, err := cachedWriter(rval.Type())
  172. if err != nil {
  173. return err
  174. }
  175. return writer(rval, buf)
  176. }
  177. func (buf *encBuffer) encodeStringHeader(size int) {
  178. if size < 56 {
  179. buf.str = append(buf.str, 0x80+byte(size))
  180. } else {
  181. sizesize := putint(buf.sizebuf[1:], uint64(size))
  182. buf.sizebuf[0] = 0xB7 + byte(sizesize)
  183. buf.str = append(buf.str, buf.sizebuf[:sizesize+1]...)
  184. }
  185. }
  186. // encReader is the io.Reader returned by EncodeToReader.
  187. // It releases its encbuf at EOF.
  188. type encReader struct {
  189. buf *encBuffer // the buffer we're reading from. this is nil when we're at EOF.
  190. lhpos int // index of list header that we're reading
  191. strpos int // current position in string buffer
  192. piece []byte // next piece to be read
  193. }
  194. func (r *encReader) Read(b []byte) (n int, err error) {
  195. for {
  196. if r.piece = r.next(); r.piece == nil {
  197. // Put the encode buffer back into the pool at EOF when it
  198. // is first encountered. Subsequent calls still return EOF
  199. // as the error but the buffer is no longer valid.
  200. if r.buf != nil {
  201. encBufferPool.Put(r.buf)
  202. r.buf = nil
  203. }
  204. return n, io.EOF
  205. }
  206. nn := copy(b[n:], r.piece)
  207. n += nn
  208. if nn < len(r.piece) {
  209. // piece didn't fit, see you next time.
  210. r.piece = r.piece[nn:]
  211. return n, nil
  212. }
  213. r.piece = nil
  214. }
  215. }
  216. // next returns the next piece of data to be read.
  217. // it returns nil at EOF.
  218. func (r *encReader) next() []byte {
  219. switch {
  220. case r.buf == nil:
  221. return nil
  222. case r.piece != nil:
  223. // There is still data available for reading.
  224. return r.piece
  225. case r.lhpos < len(r.buf.lheads):
  226. // We're before the last list header.
  227. head := r.buf.lheads[r.lhpos]
  228. sizebefore := head.offset - r.strpos
  229. if sizebefore > 0 {
  230. // String data before header.
  231. p := r.buf.str[r.strpos:head.offset]
  232. r.strpos += sizebefore
  233. return p
  234. }
  235. r.lhpos++
  236. return head.encode(r.buf.sizebuf[:])
  237. case r.strpos < len(r.buf.str):
  238. // String data at the end, after all list headers.
  239. p := r.buf.str[r.strpos:]
  240. r.strpos = len(r.buf.str)
  241. return p
  242. default:
  243. return nil
  244. }
  245. }
  246. func encBufferFromWriter(w io.Writer) *encBuffer {
  247. switch w := w.(type) {
  248. case EncoderBuffer:
  249. return w.buf
  250. case *EncoderBuffer:
  251. return w.buf
  252. case *encBuffer:
  253. return w
  254. default:
  255. return nil
  256. }
  257. }
  258. // EncoderBuffer is a buffer for incremental encoding.
  259. //
  260. // The zero value is NOT ready for use. To get a usable buffer,
  261. // create it using NewEncoderBuffer or call Reset.
  262. type EncoderBuffer struct {
  263. buf *encBuffer
  264. dst io.Writer
  265. ownBuffer bool
  266. }
  267. // NewEncoderBuffer creates an encoder buffer.
  268. func NewEncoderBuffer(dst io.Writer) EncoderBuffer {
  269. var w EncoderBuffer
  270. w.Reset(dst)
  271. return w
  272. }
  273. // Reset truncates the buffer and sets the output destination.
  274. func (w *EncoderBuffer) Reset(dst io.Writer) {
  275. if w.buf != nil && !w.ownBuffer {
  276. panic("can't Reset derived EncoderBuffer")
  277. }
  278. // If the destination writer has an *encBuffer, use it.
  279. // Note that w.ownBuffer is left false here.
  280. if dst != nil {
  281. if outer := encBufferFromWriter(dst); outer != nil {
  282. *w = EncoderBuffer{outer, nil, false}
  283. return
  284. }
  285. }
  286. // Get a fresh buffer.
  287. if w.buf == nil {
  288. w.buf = encBufferPool.Get().(*encBuffer)
  289. w.ownBuffer = true
  290. }
  291. w.buf.reset()
  292. w.dst = dst
  293. }
  294. // Flush writes encoded RLP data to the output writer. This can only be called once.
  295. // If you want to re-use the buffer after Flush, you must call Reset.
  296. func (w *EncoderBuffer) Flush() error {
  297. var err error
  298. if w.dst != nil {
  299. err = w.buf.writeTo(w.dst)
  300. }
  301. // Release the internal buffer.
  302. if w.ownBuffer {
  303. encBufferPool.Put(w.buf)
  304. }
  305. *w = EncoderBuffer{}
  306. return err
  307. }
  308. // ToBytes returns the encoded bytes.
  309. func (w *EncoderBuffer) ToBytes() []byte {
  310. return w.buf.makeBytes()
  311. }
  312. // AppendToBytes appends the encoded bytes to dst.
  313. func (w *EncoderBuffer) AppendToBytes(dst []byte) []byte {
  314. size := w.buf.size()
  315. out := append(dst, make([]byte, size)...)
  316. w.buf.copyTo(out[len(dst):])
  317. return out
  318. }
  319. // Write appends b directly to the encoder output.
  320. func (w EncoderBuffer) Write(b []byte) (int, error) {
  321. return w.buf.Write(b)
  322. }
  323. // WriteBool writes b as the integer 0 (false) or 1 (true).
  324. func (w EncoderBuffer) WriteBool(b bool) {
  325. w.buf.writeBool(b)
  326. }
  327. // WriteUint64 encodes an unsigned integer.
  328. func (w EncoderBuffer) WriteUint64(i uint64) {
  329. w.buf.writeUint64(i)
  330. }
  331. // WriteBigInt encodes a big.Int as an RLP string.
  332. // Note: Unlike with Encode, the sign of i is ignored.
  333. func (w EncoderBuffer) WriteBigInt(i *big.Int) {
  334. w.buf.writeBigInt(i)
  335. }
  336. // WriteBytes encodes b as an RLP string.
  337. func (w EncoderBuffer) WriteBytes(b []byte) {
  338. w.buf.writeBytes(b)
  339. }
  340. // WriteBytes encodes s as an RLP string.
  341. func (w EncoderBuffer) WriteString(s string) {
  342. w.buf.writeString(s)
  343. }
  344. // List starts a list. It returns an internal index. Call EndList with
  345. // this index after encoding the content to finish the list.
  346. func (w EncoderBuffer) List() int {
  347. return w.buf.list()
  348. }
  349. // ListEnd finishes the given list.
  350. func (w EncoderBuffer) ListEnd(index int) {
  351. w.buf.listEnd(index)
  352. }