github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/protokit/decode.go (about)

     1  // Copyright 2020 Insolar Network Ltd.
     2  // All rights reserved.
     3  // This material is licensed under the Insolar License version 1.0,
     4  // available at https://github.com/insolar/assured-ledger/blob/master/LICENSE.md.
     5  
     6  package protokit
     7  
     8  import (
     9  	"errors"
    10  	"fmt"
    11  	"io"
    12  )
    13  
    14  var errOverflow = errors.New("proto: uint32 overflow")
    15  
    16  func DecodeVarint(r io.ByteReader) (uint64, error) {
    17  	b, err := r.ReadByte()
    18  	if err != nil {
    19  		return 0, err
    20  	}
    21  	return decodeVarint(b, r)
    22  }
    23  
    24  // Continues to read Varint that was stated with the given (b)
    25  // See also binary.ReadUvarint(r) here
    26  func decodeVarint(b byte, r io.ByteReader) (n uint64, err error) {
    27  	v := uint64(b & 0x7F)
    28  
    29  	for i := uint8(7); i < 64; i += 7 {
    30  		if b&0x80 == 0 {
    31  			return v, nil
    32  		}
    33  		if b, err = r.ReadByte(); err != nil {
    34  			return 0, err
    35  		}
    36  		v |= uint64(b&0x7F) << i
    37  	}
    38  
    39  	if b > 1 {
    40  		return 0, errOverflow
    41  	}
    42  	return v, nil
    43  }
    44  
    45  func DecodeFixed64(r io.ByteReader) (uint64, error) {
    46  	if v, err := DecodeFixed32(r); err != nil {
    47  		return 0, err
    48  	} else if v2, err := DecodeFixed32(r); err != nil {
    49  		return 0, err
    50  	} else {
    51  		return v2<<32 | v, nil
    52  	}
    53  }
    54  
    55  func DecodeFixed32(r io.ByteReader) (v uint64, err error) {
    56  	// NB! uint64 result is NOT a mistake
    57  	var b byte
    58  	if b, err = r.ReadByte(); err != nil {
    59  		return 0, err
    60  	}
    61  	v = uint64(b)
    62  	if b, err = r.ReadByte(); err != nil {
    63  		return 0, err
    64  	}
    65  	v |= uint64(b) << 8
    66  	if b, err = r.ReadByte(); err != nil {
    67  		return 0, err
    68  	}
    69  	v |= uint64(b) << 16
    70  	if b, err = r.ReadByte(); err != nil {
    71  		return 0, err
    72  	}
    73  	v |= uint64(b) << 24
    74  	return v, nil
    75  }
    76  
    77  func DecodeFixed64FromBytes(b []byte) (uint64, int) {
    78  	_ = b[7]
    79  	v := uint64(b[0])
    80  	v |= uint64(b[1]) << 8
    81  	v |= uint64(b[2]) << 16
    82  	v |= uint64(b[3]) << 24
    83  	v |= uint64(b[4]) << 32
    84  	v |= uint64(b[5]) << 40
    85  	v |= uint64(b[6]) << 48
    86  	v |= uint64(b[7]) << 56
    87  
    88  	return v, 8
    89  }
    90  
    91  func DecodeFixed64FromBytesWithError(b []byte) (v uint64, n int, err error) {
    92  	if len(b) < 8 {
    93  		return 0, 0, io.ErrUnexpectedEOF
    94  	}
    95  	v, n = DecodeFixed64FromBytes(b)
    96  	return
    97  }
    98  
    99  func DecodeFixed32FromBytes(b []byte) (uint64, int) {
   100  	// NB! uint64 result is NOT a mistake
   101  	_ = b[3]
   102  	v := uint64(b[0])
   103  	v |= uint64(b[1]) << 8
   104  	v |= uint64(b[2]) << 16
   105  	v |= uint64(b[3]) << 24
   106  
   107  	return v, 4
   108  }
   109  
   110  func DecodeFixed32FromBytesWithError(b []byte) (v uint64, n int, err error) {
   111  	// NB! uint64 result is NOT a mistake
   112  	if len(b) < 4 {
   113  		return 0, 0, io.ErrUnexpectedEOF
   114  	}
   115  	v, n = DecodeFixed32FromBytes(b)
   116  	return
   117  }
   118  
   119  func DecodeVarintFromBytes(bb []byte) (u uint64, n int) {
   120  	b := bb[0]
   121  
   122  	v := uint64(b & 0x7F)
   123  
   124  	for i := uint8(7); i < 64; i += 7 {
   125  		n++
   126  		if b&0x80 == 0 {
   127  			return v, n
   128  		}
   129  		b = bb[n]
   130  		v |= uint64(b&0x7F) << i
   131  	}
   132  
   133  	if b > 1 {
   134  		return 0, 0 // errOverflow
   135  	}
   136  	n++
   137  	return v, n
   138  }
   139  
   140  func DecodeVarintFromBytesWithError(bb []byte) (u uint64, n int, err error) {
   141  	if len(bb) == 0 {
   142  		return 0, 0, io.ErrUnexpectedEOF
   143  	}
   144  	b := bb[0]
   145  
   146  	v := uint64(b & 0x7F)
   147  
   148  	for i := uint8(7); i < 64; i += 7 {
   149  		n++
   150  		if b&0x80 == 0 {
   151  			return v, n, nil
   152  		}
   153  		if len(bb) <= n {
   154  			return 0, 0, io.ErrUnexpectedEOF
   155  		}
   156  		b = bb[n]
   157  		v |= uint64(b&0x7F) << i
   158  	}
   159  
   160  	if b > 1 {
   161  		return 0, 0, errOverflow
   162  	}
   163  	n++
   164  	return v, n, nil
   165  }
   166  
   167  func IsValidFirstByteOfTag(firstByte byte) bool {
   168  	return firstByte > maskWireType && WireType(firstByte&maskWireType).IsValid()
   169  }
   170  
   171  func (v WireType) IsValidFirstByte(firstByte byte) bool {
   172  	return firstByte > maskWireType && firstByte&maskWireType == byte(v) && v.IsValid()
   173  }
   174  
   175  func (v WireTag) IsValidFirstByte(firstByte byte) bool {
   176  	switch {
   177  	case !IsValidFirstByteOfTag(firstByte):
   178  		return false
   179  	case v <= 0xFF:
   180  		return firstByte == byte(v)
   181  	default:
   182  		return firstByte == byte(v)|0x80
   183  	}
   184  }
   185  
   186  func _readTag(firstByte byte, r io.ByteReader) (wt WireTag, err error) {
   187  	var x uint64
   188  	x, err = decodeVarint(firstByte, r)
   189  	if err != nil {
   190  		return 0, err
   191  	}
   192  	return SafeWireTag(x)
   193  }
   194  
   195  func TryReadAnyTag(r io.ByteScanner) (wt WireTag, err error) {
   196  	var b byte
   197  	b, err = r.ReadByte()
   198  	switch {
   199  	case err != nil:
   200  		return 0, err
   201  	case !IsValidFirstByteOfTag(b):
   202  		return 0, r.UnreadByte()
   203  	}
   204  	return _readTag(b, r)
   205  }
   206  
   207  func MustReadAnyTag(r io.ByteReader) (wt WireTag, err error) {
   208  	var b byte
   209  	b, err = r.ReadByte()
   210  	switch {
   211  	case err != nil:
   212  		return 0, err
   213  	case !IsValidFirstByteOfTag(b):
   214  		return 0, fmt.Errorf("invalid wire tag, wrong first byte: %x", b)
   215  	}
   216  	return _readTag(b, r)
   217  }
   218  
   219  func MustReadAnyTagValue(r io.ByteReader) (rt WireTag, u uint64, err error) {
   220  	rt, err = MustReadAnyTag(r)
   221  	if err != nil {
   222  		return 0, 0, err
   223  	}
   224  	u, err = rt.ReadValue(r)
   225  	return
   226  }
   227  
   228  func TryReadAnyTagValue(r io.ByteScanner) (rt WireTag, u uint64, err error) {
   229  	rt, err = TryReadAnyTag(r)
   230  	if err != nil || rt.IsZero() {
   231  		return 0, 0, err
   232  	}
   233  	u, err = rt.ReadValue(r)
   234  	return
   235  }
   236  
   237  func (v WireTag) TryReadTag(r io.ByteScanner) (WireTag, error) {
   238  	b, err := r.ReadByte()
   239  	switch {
   240  	case err != nil:
   241  		return 0, err
   242  	case !v.IsValidFirstByte(b):
   243  		return 0, r.UnreadByte()
   244  	}
   245  	var rt WireTag
   246  	rt, err = _readTag(b, r)
   247  	if err != nil {
   248  		return 0, err
   249  	}
   250  	return rt, rt.CheckTag(v)
   251  }
   252  
   253  func (v WireType) TryReadTag(r io.ByteScanner) (WireTag, error) {
   254  	b, err := r.ReadByte()
   255  	switch {
   256  	case err != nil:
   257  		return 0, err
   258  	case !v.IsValidFirstByte(b):
   259  		return 0, r.UnreadByte()
   260  	}
   261  	var rt WireTag
   262  	rt, err = _readTag(b, r)
   263  	if err != nil {
   264  		return 0, err
   265  	}
   266  	return rt, rt.CheckType(v)
   267  }
   268  
   269  func (v WireTag) ReadTag(r io.ByteReader) error {
   270  	rt, err := MustReadAnyTag(r)
   271  	if err != nil {
   272  		return err
   273  	}
   274  	return rt.CheckTag(v)
   275  }
   276  
   277  func (v WireType) ReadTag(r io.ByteReader) (WireTag, error) {
   278  	rt, err := MustReadAnyTag(r)
   279  	if err != nil {
   280  		return rt, err
   281  	}
   282  	return rt, rt.CheckType(v)
   283  }
   284  
   285  func (v WireTag) ReadTagValue(r io.ByteReader) (uint64, error) {
   286  	err := v.ReadTag(r)
   287  	if err != nil {
   288  		return 0, err
   289  	}
   290  	return v.ReadValue(r)
   291  }
   292  
   293  func (v WireType) ReadTagValue(r io.ByteReader) (WireTag, uint64, error) {
   294  	rt, err := v.ReadTag(r)
   295  	if err != nil {
   296  		return rt, 0, err
   297  	}
   298  	var u uint64
   299  	u, err = rt.ReadValue(r)
   300  	return rt, u, err
   301  }