github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/encoding/blockchain/blockchain.go (about)

     1  // Package blockchain provides the tools for encoding
     2  // data primitives in blockchain structures
     3  package blockchain
     4  
     5  import (
     6  	"encoding/binary"
     7  	"errors"
     8  	"io"
     9  	"math"
    10  	"sync"
    11  
    12  	"github.com/bytom/bytom/encoding/bufpool"
    13  )
    14  
    15  var bufPool = sync.Pool{New: func() interface{} { return new([9]byte) }}
    16  
    17  var ErrRange = errors.New("value out of range")
    18  
    19  // Reader wraps a buffer and provides utilities for decoding
    20  // data primitives in blockchain structures. Its various read
    21  // calls may return a slice of the underlying buffer.
    22  type Reader struct {
    23  	buf []byte
    24  }
    25  
    26  // NewReader constructs a new reader with the provided bytes. It
    27  // does not create a copy of the bytes, so the caller is responsible
    28  // for copying the bytes if necessary.
    29  func NewReader(b []byte) *Reader {
    30  	return &Reader{buf: b}
    31  }
    32  
    33  // Len returns the number of unread bytes.
    34  func (r *Reader) Len() int {
    35  	return len(r.buf)
    36  }
    37  
    38  // ReadByte reads and returns the next byte from the input.
    39  //
    40  // It implements the io.ByteReader interface.
    41  func (r *Reader) ReadByte() (byte, error) {
    42  	if len(r.buf) == 0 {
    43  		return 0, io.EOF
    44  	}
    45  
    46  	b := r.buf[0]
    47  	r.buf = r.buf[1:]
    48  	return b, nil
    49  }
    50  
    51  // Read reads up to len(p) bytes into p. It implements
    52  // the io.Reader interface.
    53  func (r *Reader) Read(p []byte) (n int, err error) {
    54  	n = copy(p, r.buf)
    55  	r.buf = r.buf[n:]
    56  	if len(r.buf) == 0 {
    57  		err = io.EOF
    58  	}
    59  	return
    60  }
    61  
    62  func ReadVarint31(r *Reader) (uint32, error) {
    63  	val, err := binary.ReadUvarint(r)
    64  	if err != nil {
    65  		return 0, err
    66  	}
    67  	if val > math.MaxInt32 {
    68  		return 0, ErrRange
    69  	}
    70  	return uint32(val), nil
    71  }
    72  
    73  func ReadVarint63(r *Reader) (uint64, error) {
    74  	val, err := binary.ReadUvarint(r)
    75  	if err != nil {
    76  		return 0, err
    77  	}
    78  	if val > math.MaxInt64 {
    79  		return 0, ErrRange
    80  	}
    81  	return val, nil
    82  }
    83  
    84  func ReadVarstr31(r *Reader) ([]byte, error) {
    85  	l, err := ReadVarint31(r)
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  	if l == 0 {
    90  		return nil, nil
    91  	}
    92  	if int(l) > len(r.buf) {
    93  		return nil, io.ErrUnexpectedEOF
    94  	}
    95  	str := r.buf[:l]
    96  	r.buf = r.buf[l:]
    97  	return str, nil
    98  }
    99  
   100  // ReadVarstrList reads a varint31 length prefix followed by
   101  // that many varstrs.
   102  func ReadVarstrList(r *Reader) (result [][]byte, err error) {
   103  	nelts, err := ReadVarint31(r)
   104  	if err != nil {
   105  		return nil, err
   106  	}
   107  	if nelts == 0 {
   108  		return nil, nil
   109  	}
   110  
   111  	for ; nelts > 0 && err == nil; nelts-- {
   112  		var s []byte
   113  		s, err = ReadVarstr31(r)
   114  		result = append(result, s)
   115  	}
   116  	if len(result) < int(nelts) {
   117  		err = io.ErrUnexpectedEOF
   118  	}
   119  	return result, err
   120  }
   121  
   122  // ReadExtensibleString reads a varint31 length prefix and that many
   123  // bytes from r. It then calls the given function to consume those
   124  // bytes, returning any unconsumed suffix.
   125  func ReadExtensibleString(r *Reader, f func(*Reader) error) (suffix []byte, err error) {
   126  	s, err := ReadVarstr31(r)
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  
   131  	sr := NewReader(s)
   132  	err = f(sr)
   133  	if err != nil {
   134  		return nil, err
   135  	}
   136  	return sr.buf, nil
   137  }
   138  
   139  func WriteVarint31(w io.Writer, val uint64) (int, error) {
   140  	if val > math.MaxInt32 {
   141  		return 0, ErrRange
   142  	}
   143  	buf := bufPool.Get().(*[9]byte)
   144  	n := binary.PutUvarint(buf[:], val)
   145  	b, err := w.Write(buf[:n])
   146  	bufPool.Put(buf)
   147  	return b, err
   148  }
   149  
   150  func WriteVarint63(w io.Writer, val uint64) (int, error) {
   151  	if val > math.MaxInt64 {
   152  		return 0, ErrRange
   153  	}
   154  	buf := bufPool.Get().(*[9]byte)
   155  	n := binary.PutUvarint(buf[:], val)
   156  	b, err := w.Write(buf[:n])
   157  	bufPool.Put(buf)
   158  	return b, err
   159  }
   160  
   161  func WriteVarstr31(w io.Writer, str []byte) (int, error) {
   162  	n, err := WriteVarint31(w, uint64(len(str)))
   163  	if err != nil {
   164  		return n, err
   165  	}
   166  	n2, err := w.Write(str)
   167  	return n + n2, err
   168  }
   169  
   170  // WriteVarstrList writes a varint31 length prefix followed by the
   171  // elements of l as varstrs.
   172  func WriteVarstrList(w io.Writer, l [][]byte) (int, error) {
   173  	n, err := WriteVarint31(w, uint64(len(l)))
   174  	if err != nil {
   175  		return n, err
   176  	}
   177  	for _, s := range l {
   178  		n2, err := WriteVarstr31(w, s)
   179  		n += n2
   180  		if err != nil {
   181  			return n, err
   182  		}
   183  	}
   184  	return n, err
   185  }
   186  
   187  // WriteExtensibleString sends the output of the given function, plus
   188  // the given suffix, to w, together with a varint31 length prefix.
   189  func WriteExtensibleString(w io.Writer, suffix []byte, f func(io.Writer) error) (int, error) {
   190  	buf := bufpool.Get()
   191  	defer bufpool.Put(buf)
   192  	err := f(buf)
   193  	if err != nil {
   194  		return 0, err
   195  	}
   196  	if len(suffix) > 0 {
   197  		_, err := buf.Write(suffix)
   198  		if err != nil {
   199  			return 0, err
   200  		}
   201  	}
   202  	return WriteVarstr31(w, buf.Bytes())
   203  }