1 // Package blockchain provides the tools for encoding
2 // data primitives in blockchain structures
13 var ErrRange = errors.New("value out of range")
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.
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}
29 // Len returns the number of unread bytes.
30 func (r *Reader) Len() int {
34 // ReadByte reads and returns the next byte from the input.
36 // It implements the io.ByteReader interface.
37 func (r *Reader) ReadByte() (byte, error) {
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) {
58 func ReadVarint31(r *Reader) (uint32, error) {
59 val, err := binary.ReadUvarint(r)
63 if val > math.MaxInt32 {
66 return uint32(val), nil
69 func ReadVarint63(r *Reader) (uint64, error) {
70 val, err := binary.ReadUvarint(r)
74 if val > math.MaxInt64 {
80 func ReadVarstr31(r *Reader) ([]byte, error) {
81 l, err := ReadVarint31(r)
88 if int(l) > len(r.buf) {
89 return nil, io.ErrUnexpectedEOF
96 // ReadVarstrList reads a varint31 length prefix followed by
98 func ReadVarstrList(r *Reader) (result [][]byte, err error) {
99 nelts, err := ReadVarint31(r)
107 for ; nelts > 0 && err == nil; nelts-- {
109 s, err = ReadVarstr31(r)
110 result = append(result, s)
112 if len(result) < int(nelts) {
113 err = io.ErrUnexpectedEOF
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)
128 if err = f(sr); err != nil {
134 func WriteVarint31(w io.Writer, val uint64) (int, error) {
135 if val > math.MaxInt32 {
140 n := binary.PutUvarint(buf[:], val)
141 b, err := w.Write(buf[:n])
145 func WriteVarint63(w io.Writer, val uint64) (int, error) {
146 if val > math.MaxInt64 {
151 n := binary.PutUvarint(buf[:], val)
152 b, err := w.Write(buf[:n])
156 func WriteVarstr31(w io.Writer, str []byte) (int, error) {
157 n, err := WriteVarint31(w, uint64(len(str)))
162 n2, err := w.Write(str)
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)))
174 for _, s := range l {
175 n2, err := WriteVarstr31(w, s)
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 {
193 if _, err := buf.Write(suffix); err != nil {
197 return WriteVarstr31(w, buf.Bytes())