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

     1  package protowire
     2  
     3  import (
     4  	"math"
     5  	"math/bits"
     6  )
     7  
     8  type BinaryEncoder struct{}
     9  
    10  // VarintEncode encodes a uint64 value as a varint-encoded byte slice.
    11  // AppendVarint appends v to b as a varint-encoded uint64.
    12  func AppendVarint(b []byte, v uint64) []byte {
    13  	switch {
    14  	case v < 1<<7:
    15  		b = append(b, byte(v))
    16  	case v < 1<<14:
    17  		b = append(b,
    18  			byte((v>>0)&0x7f|0x80),
    19  			byte(v>>7))
    20  	case v < 1<<21:
    21  		b = append(b,
    22  			byte((v>>0)&0x7f|0x80),
    23  			byte((v>>7)&0x7f|0x80),
    24  			byte(v>>14))
    25  	case v < 1<<28:
    26  		b = append(b,
    27  			byte((v>>0)&0x7f|0x80),
    28  			byte((v>>7)&0x7f|0x80),
    29  			byte((v>>14)&0x7f|0x80),
    30  			byte(v>>21))
    31  	case v < 1<<35:
    32  		b = append(b,
    33  			byte((v>>0)&0x7f|0x80),
    34  			byte((v>>7)&0x7f|0x80),
    35  			byte((v>>14)&0x7f|0x80),
    36  			byte((v>>21)&0x7f|0x80),
    37  			byte(v>>28))
    38  	case v < 1<<42:
    39  		b = append(b,
    40  			byte((v>>0)&0x7f|0x80),
    41  			byte((v>>7)&0x7f|0x80),
    42  			byte((v>>14)&0x7f|0x80),
    43  			byte((v>>21)&0x7f|0x80),
    44  			byte((v>>28)&0x7f|0x80),
    45  			byte(v>>35))
    46  	case v < 1<<49:
    47  		b = append(b,
    48  			byte((v>>0)&0x7f|0x80),
    49  			byte((v>>7)&0x7f|0x80),
    50  			byte((v>>14)&0x7f|0x80),
    51  			byte((v>>21)&0x7f|0x80),
    52  			byte((v>>28)&0x7f|0x80),
    53  			byte((v>>35)&0x7f|0x80),
    54  			byte(v>>42))
    55  	case v < 1<<56:
    56  		b = append(b,
    57  			byte((v>>0)&0x7f|0x80),
    58  			byte((v>>7)&0x7f|0x80),
    59  			byte((v>>14)&0x7f|0x80),
    60  			byte((v>>21)&0x7f|0x80),
    61  			byte((v>>28)&0x7f|0x80),
    62  			byte((v>>35)&0x7f|0x80),
    63  			byte((v>>42)&0x7f|0x80),
    64  			byte(v>>49))
    65  	case v < 1<<63:
    66  		b = append(b,
    67  			byte((v>>0)&0x7f|0x80),
    68  			byte((v>>7)&0x7f|0x80),
    69  			byte((v>>14)&0x7f|0x80),
    70  			byte((v>>21)&0x7f|0x80),
    71  			byte((v>>28)&0x7f|0x80),
    72  			byte((v>>35)&0x7f|0x80),
    73  			byte((v>>42)&0x7f|0x80),
    74  			byte((v>>49)&0x7f|0x80),
    75  			byte(v>>56))
    76  	default:
    77  		b = append(b,
    78  			byte((v>>0)&0x7f|0x80),
    79  			byte((v>>7)&0x7f|0x80),
    80  			byte((v>>14)&0x7f|0x80),
    81  			byte((v>>21)&0x7f|0x80),
    82  			byte((v>>28)&0x7f|0x80),
    83  			byte((v>>35)&0x7f|0x80),
    84  			byte((v>>42)&0x7f|0x80),
    85  			byte((v>>49)&0x7f|0x80),
    86  			byte((v>>56)&0x7f|0x80),
    87  			1)
    88  	}
    89  	return b
    90  }
    91  
    92  // AppendFixed32 appends v to b as a little-endian uint32.
    93  func AppendFixed32(b []byte, v uint32) []byte {
    94  	return append(b,
    95  		byte(v>>0),
    96  		byte(v>>8),
    97  		byte(v>>16),
    98  		byte(v>>24))
    99  }
   100  
   101  // AppendFixed64 appends v to b as a little-endian uint64.
   102  func AppendFixed64(b []byte, v uint64) []byte {
   103  	return append(b,
   104  		byte(v>>0),
   105  		byte(v>>8),
   106  		byte(v>>16),
   107  		byte(v>>24),
   108  		byte(v>>32),
   109  		byte(v>>40),
   110  		byte(v>>48),
   111  		byte(v>>56))
   112  }
   113  
   114  // EncodeZigZag encodes an int64 as a zig-zag-encoded uint64.
   115  //
   116  //	Input:  {…, -3, -2, -1,  0, +1, +2, +3, …}
   117  //	Output: {…,  5,  3,  1,  0,  2,  4,  6, …}
   118  func EncodeZigZag(v int64) uint64 {
   119  	return uint64(v<<1) ^ uint64(v>>63)
   120  }
   121  
   122  // SizeVarint returns the encoded size of a varint.
   123  // The size is guaranteed to be within 1 and 10, inclusive.
   124  func SizeVarint(v uint64) int {
   125  	// This computes 1 + (bits.Len64(v)-1)/7.
   126  	// 9/64 is a good enough approximation of 1/7
   127  	return int(9*uint32(bits.Len64(v))+64) / 64
   128  }
   129  
   130  // SizeFixed32 returns the encoded size of a fixed32; which is always 4.
   131  func SizeFixed32() int {
   132  	return 4
   133  }
   134  
   135  // SizeFixed64 returns the encoded size of a fixed64; which is always 8.
   136  func SizeFixed64() int {
   137  	return 8
   138  }
   139  
   140  // encode each proto kind into bytes
   141  func (BinaryEncoder) EncodeBool(b []byte, v bool) []byte {
   142  	if v {
   143  		return append(b, 1)
   144  	}
   145  	return append(b, 0)
   146  }
   147  
   148  func (BinaryEncoder) EncodeByte(b []byte, v byte) []byte {
   149  	return append(b, v)
   150  }
   151  
   152  func (BinaryEncoder) EncodeEnum(b []byte, v int32) []byte {
   153  	return AppendVarint(b, uint64(v))
   154  }
   155  
   156  func (BinaryEncoder) EncodeInt32(b []byte, v int32) []byte {
   157  	return AppendVarint(b, uint64(v))
   158  }
   159  
   160  func (BinaryEncoder) EncodeSint32(b []byte, v int32) []byte {
   161  	return AppendVarint(b, EncodeZigZag(int64(v)))
   162  }
   163  
   164  func (BinaryEncoder) EncodeUint32(b []byte, v uint32) []byte {
   165  	return AppendVarint(b, uint64(v))
   166  }
   167  
   168  func (BinaryEncoder) EncodeInt64(b []byte, v int64) []byte {
   169  	return AppendVarint(b, uint64(v))
   170  }
   171  
   172  func (BinaryEncoder) EncodeSint64(b []byte, v int64) []byte {
   173  	return AppendVarint(b, EncodeZigZag(v))
   174  }
   175  
   176  func (BinaryEncoder) EncodeUint64(b []byte, v uint64) []byte {
   177  	return AppendVarint(b, v)
   178  }
   179  
   180  func (BinaryEncoder) EncodeSfixed32(b []byte, v int32) []byte {
   181  	return AppendFixed32(b, uint32(v))
   182  }
   183  
   184  func (BinaryEncoder) EncodeFixed32(b []byte, v uint32) []byte {
   185  	return AppendFixed32(b, v)
   186  }
   187  
   188  func (BinaryEncoder) EncodeFloat32(b []byte, v float32) []byte {
   189  	return AppendFixed32(b, math.Float32bits(v))
   190  }
   191  
   192  func (BinaryEncoder) EncodeSfixed64(b []byte, v int64) []byte {
   193  	return AppendFixed64(b, uint64(v))
   194  }
   195  
   196  func (BinaryEncoder) EncodeFixed64(b []byte, v uint64) []byte {
   197  	return AppendFixed64(b, v)
   198  }
   199  
   200  func (BinaryEncoder) EncodeDouble(b []byte, v float64) []byte {
   201  	return AppendFixed64(b, math.Float64bits(v))
   202  }
   203  
   204  func (BinaryEncoder) EncodeString(b []byte, v string) []byte {
   205  	return append(AppendVarint(b, uint64(len(v))), v...)
   206  }
   207  
   208  func (BinaryEncoder) EncodeBytes(b []byte, v []byte) []byte {
   209  	return append(AppendVarint(b, uint64(len(v))), v...)
   210  }