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 }