OSDN Git Service

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