github.com/theQRL/go-zond@v0.1.1/rlp/encbuffer.go (about)

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