github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/proto/protowire/decode.go (about)

     1  package protowire
     2  
     3  import (
     4  	"math"
     5  )
     6  
     7  const (
     8  	_ = -iota
     9  	errCodeTruncated
    10  	errCodeFieldNumber
    11  	errCodeOverflow
    12  	errCodeReserved
    13  	errCodeEndGroup
    14  	errCodeRecursionDepth
    15  )
    16  
    17  type BinaryDecoder struct{}
    18  
    19  // ConsumeVarint parses b as a varint-encoded uint64, reporting its length.
    20  // This returns a negative length upon an error (see ParseError).
    21  func ConsumeVarint(b []byte) (v uint64, n int) {
    22  	var y uint64
    23  	if len(b) <= 0 {
    24  		return 0, errCodeTruncated
    25  	}
    26  	v = uint64(b[0])
    27  	if v < 0x80 {
    28  		return v, 1
    29  	}
    30  	v -= 0x80
    31  
    32  	if len(b) <= 1 {
    33  		return 0, errCodeTruncated
    34  	}
    35  	y = uint64(b[1])
    36  	v += y << 7
    37  	if y < 0x80 {
    38  		return v, 2
    39  	}
    40  	v -= 0x80 << 7
    41  
    42  	if len(b) <= 2 {
    43  		return 0, errCodeTruncated
    44  	}
    45  	y = uint64(b[2])
    46  	v += y << 14
    47  	if y < 0x80 {
    48  		return v, 3
    49  	}
    50  	v -= 0x80 << 14
    51  
    52  	if len(b) <= 3 {
    53  		return 0, errCodeTruncated
    54  	}
    55  	y = uint64(b[3])
    56  	v += y << 21
    57  	if y < 0x80 {
    58  		return v, 4
    59  	}
    60  	v -= 0x80 << 21
    61  
    62  	if len(b) <= 4 {
    63  		return 0, errCodeTruncated
    64  	}
    65  	y = uint64(b[4])
    66  	v += y << 28
    67  	if y < 0x80 {
    68  		return v, 5
    69  	}
    70  	v -= 0x80 << 28
    71  
    72  	if len(b) <= 5 {
    73  		return 0, errCodeTruncated
    74  	}
    75  	y = uint64(b[5])
    76  	v += y << 35
    77  	if y < 0x80 {
    78  		return v, 6
    79  	}
    80  	v -= 0x80 << 35
    81  
    82  	if len(b) <= 6 {
    83  		return 0, errCodeTruncated
    84  	}
    85  	y = uint64(b[6])
    86  	v += y << 42
    87  	if y < 0x80 {
    88  		return v, 7
    89  	}
    90  	v -= 0x80 << 42
    91  
    92  	if len(b) <= 7 {
    93  		return 0, errCodeTruncated
    94  	}
    95  	y = uint64(b[7])
    96  	v += y << 49
    97  	if y < 0x80 {
    98  		return v, 8
    99  	}
   100  	v -= 0x80 << 49
   101  
   102  	if len(b) <= 8 {
   103  		return 0, errCodeTruncated
   104  	}
   105  	y = uint64(b[8])
   106  	v += y << 56
   107  	if y < 0x80 {
   108  		return v, 9
   109  	}
   110  	v -= 0x80 << 56
   111  
   112  	if len(b) <= 9 {
   113  		return 0, errCodeTruncated
   114  	}
   115  	y = uint64(b[9])
   116  	v += y << 63
   117  	if y < 2 {
   118  		return v, 10
   119  	}
   120  	return 0, errCodeOverflow
   121  }
   122  
   123  // ConsumeFixed32 parses b as a little-endian uint32, reporting its length.
   124  // This returns a negative length upon an error (see ParseError).
   125  func ConsumeFixed32(b []byte) (v uint32, n int) {
   126  	if len(b) < 4 {
   127  		return 0, errCodeTruncated
   128  	}
   129  	v = uint32(b[0])<<0 | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
   130  	return v, 4
   131  }
   132  
   133  // ConsumeFixed64 parses b as a little-endian uint64, reporting its length.
   134  // This returns a negative length upon an error (see ParseError).
   135  func ConsumeFixed64(b []byte) (v uint64, n int) {
   136  	if len(b) < 8 {
   137  		return 0, errCodeTruncated
   138  	}
   139  	v = uint64(b[0])<<0 | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
   140  	return v, 8
   141  }
   142  
   143  // ConsumeBytes parses b as a length-prefixed bytes value, reporting its length.
   144  // This returns a negative length upon an error (see ParseError).
   145  func ConsumeBytes(b []byte) (v []byte, n int, all int) {
   146  	m, n := ConsumeVarint(b)
   147  	if n < 0 {
   148  		return nil, n, n
   149  	}
   150  	if m > uint64(len(b[n:])) {
   151  		return nil, errCodeTruncated, errCodeTruncated
   152  	}
   153  	return b[n:][:m], n, n + int(m) // V's bytes, L's bytelen, (L+V)'s bytelen
   154  }
   155  
   156  // DecodeZigZag decodes a zig-zag-encoded uint64 as an int64.
   157  //
   158  //	Input:  {…,  5,  3,  1,  0,  2,  4,  6, …}
   159  //	Output: {…, -3, -2, -1,  0, +1, +2, +3, …}
   160  func DecodeZigZag(x uint64) int64 {
   161  	return int64(x>>1) ^ int64(x)<<63>>63
   162  }
   163  
   164  func (BinaryDecoder) DecodeBool(b []byte) (bool, int) {
   165  	v, n := ConsumeVarint(b)
   166  	return int8(v) == 1, n
   167  }
   168  
   169  func (BinaryDecoder) DecodeByte(b []byte) byte {
   170  	return byte(b[0])
   171  }
   172  
   173  func (BinaryDecoder) DecodeInt32(b []byte) (int32, int) {
   174  	v, n := ConsumeVarint(b)
   175  	return int32(v), n
   176  }
   177  
   178  func (BinaryDecoder) DecodeSint32(b []byte) (int32, int) {
   179  	v, n := ConsumeVarint(b)
   180  	return int32(DecodeZigZag(v & math.MaxUint32)), n
   181  }
   182  
   183  func (BinaryDecoder) DecodeUint32(b []byte) (uint32, int) {
   184  	v, n := ConsumeVarint(b)
   185  	return uint32(v), n
   186  }
   187  
   188  func (BinaryDecoder) DecodeInt64(b []byte) (int64, int) {
   189  	v, n := ConsumeVarint(b)
   190  	return int64(v), n
   191  }
   192  
   193  func (BinaryDecoder) DecodeSint64(b []byte) (int64, int) {
   194  	v, n := ConsumeVarint(b)
   195  	return DecodeZigZag(v), n
   196  }
   197  
   198  func (BinaryDecoder) DecodeUint64(b []byte) (uint64, int) {
   199  	v, n := ConsumeVarint(b)
   200  	return v, n
   201  }
   202  
   203  func (BinaryDecoder) DecodeSfixed32(b []byte) (int32, int) {
   204  	v, n := ConsumeFixed32(b)
   205  	return int32(v), n
   206  }
   207  
   208  func (BinaryDecoder) DecodeFixed32(b []byte) (uint32, int) {
   209  	v, n := ConsumeFixed32(b)
   210  	return v, n
   211  }
   212  
   213  func (BinaryDecoder) DecodeFloat32(b []byte) (float32, int) {
   214  	v, n := ConsumeFixed32(b)
   215  	return math.Float32frombits(v), n
   216  }
   217  
   218  func (BinaryDecoder) DecodeSfixed64(b []byte) (int64, int) {
   219  	v, n := ConsumeFixed64(b)
   220  	return int64(v), n
   221  }
   222  
   223  func (BinaryDecoder) DecodeFixed64(b []byte) (uint64, int) {
   224  	v, n := ConsumeFixed64(b)
   225  	return v, n
   226  }
   227  
   228  func (BinaryDecoder) DecodeDouble(b []byte) (float64, int) {
   229  	v, n := ConsumeFixed64(b)
   230  	return math.Float64frombits(v), n
   231  }
   232  
   233  func (BinaryDecoder) DecodeString(b []byte) (string, int, int) {
   234  	v, n, all := ConsumeBytes(b)
   235  	return string(v), n, all
   236  }
   237  
   238  func (BinaryDecoder) DecodeBytes(b []byte) ([]byte, int, int) {
   239  	v, n, all := ConsumeBytes(b)
   240  	return v, n, all
   241  }