github.com/kamalshkeir/kencoding@v0.0.2-0.20230409043843-44b609a0475a/proto/encode.go (about)

     1  package proto
     2  
     3  import (
     4  	"encoding/binary"
     5  	"io"
     6  	"unsafe"
     7  )
     8  
     9  // EncodeTag encodes a pair of field number and wire type into a protobuf tag.
    10  func EncodeTag(f FieldNumber, t WireType) uint64 {
    11  	return uint64(f)<<3 | uint64(t)
    12  }
    13  
    14  // EncodeZigZag returns v as a zig-zag encoded value.
    15  func EncodeZigZag(v int64) uint64 {
    16  	return encodeZigZag64(v)
    17  }
    18  
    19  func encodeZigZag64(v int64) uint64 {
    20  	return (uint64(v) << 1) ^ uint64(v>>63)
    21  }
    22  
    23  func encodeZigZag32(v int32) uint32 {
    24  	return (uint32(v) << 1) ^ uint32(v>>31)
    25  }
    26  
    27  type encodeFunc = func([]byte, unsafe.Pointer, flags) (int, error)
    28  
    29  func encodeVarint(b []byte, v uint64) (int, error) {
    30  	n := sizeOfVarint(v)
    31  
    32  	if len(b) < n {
    33  		return 0, io.ErrShortBuffer
    34  	}
    35  
    36  	switch n {
    37  	case 1:
    38  		b[0] = byte(v)
    39  
    40  	case 2:
    41  		b[0] = byte(v) | 0x80
    42  		b[1] = byte(v >> 7)
    43  
    44  	case 3:
    45  		b[0] = byte(v) | 0x80
    46  		b[1] = byte(v>>7) | 0x80
    47  		b[2] = byte(v >> 14)
    48  
    49  	case 4:
    50  		b[0] = byte(v) | 0x80
    51  		b[1] = byte(v>>7) | 0x80
    52  		b[2] = byte(v>>14) | 0x80
    53  		b[3] = byte(v >> 21)
    54  
    55  	case 5:
    56  		b[0] = byte(v) | 0x80
    57  		b[1] = byte(v>>7) | 0x80
    58  		b[2] = byte(v>>14) | 0x80
    59  		b[3] = byte(v>>21) | 0x80
    60  		b[4] = byte(v >> 28)
    61  
    62  	case 6:
    63  		b[0] = byte(v) | 0x80
    64  		b[1] = byte(v>>7) | 0x80
    65  		b[2] = byte(v>>14) | 0x80
    66  		b[3] = byte(v>>21) | 0x80
    67  		b[4] = byte(v>>28) | 0x80
    68  		b[5] = byte(v >> 35)
    69  
    70  	case 7:
    71  		b[0] = byte(v) | 0x80
    72  		b[1] = byte(v>>7) | 0x80
    73  		b[2] = byte(v>>14) | 0x80
    74  		b[3] = byte(v>>21) | 0x80
    75  		b[4] = byte(v>>28) | 0x80
    76  		b[5] = byte(v>>35) | 0x80
    77  		b[6] = byte(v >> 42)
    78  
    79  	case 8:
    80  		b[0] = byte(v) | 0x80
    81  		b[1] = byte(v>>7) | 0x80
    82  		b[2] = byte(v>>14) | 0x80
    83  		b[3] = byte(v>>21) | 0x80
    84  		b[4] = byte(v>>28) | 0x80
    85  		b[5] = byte(v>>35) | 0x80
    86  		b[6] = byte(v>>42) | 0x80
    87  		b[7] = byte(v >> 49)
    88  
    89  	case 9:
    90  		b[0] = byte(v) | 0x80
    91  		b[1] = byte(v>>7) | 0x80
    92  		b[2] = byte(v>>14) | 0x80
    93  		b[3] = byte(v>>21) | 0x80
    94  		b[4] = byte(v>>28) | 0x80
    95  		b[5] = byte(v>>35) | 0x80
    96  		b[6] = byte(v>>42) | 0x80
    97  		b[7] = byte(v>>49) | 0x80
    98  		b[8] = byte(v >> 56)
    99  
   100  	case 10:
   101  		b[0] = byte(v) | 0x80
   102  		b[1] = byte(v>>7) | 0x80
   103  		b[2] = byte(v>>14) | 0x80
   104  		b[3] = byte(v>>21) | 0x80
   105  		b[4] = byte(v>>28) | 0x80
   106  		b[5] = byte(v>>35) | 0x80
   107  		b[6] = byte(v>>42) | 0x80
   108  		b[7] = byte(v>>49) | 0x80
   109  		b[8] = byte(v>>56) | 0x80
   110  		b[9] = byte(v >> 63)
   111  	}
   112  
   113  	return n, nil
   114  }
   115  
   116  func encodeVarintZigZag(b []byte, v int64) (int, error) {
   117  	return encodeVarint(b, encodeZigZag64(v))
   118  }
   119  
   120  func encodeLE32(b []byte, v uint32) (int, error) {
   121  	if len(b) < 4 {
   122  		return 0, io.ErrShortBuffer
   123  	}
   124  	binary.LittleEndian.PutUint32(b, v)
   125  	return 4, nil
   126  }
   127  
   128  func encodeLE64(b []byte, v uint64) (int, error) {
   129  	if len(b) < 8 {
   130  		return 0, io.ErrShortBuffer
   131  	}
   132  	binary.LittleEndian.PutUint64(b, v)
   133  	return 8, nil
   134  }
   135  
   136  func encodeTag(b []byte, f fieldNumber, t wireType) (int, error) {
   137  	return encodeVarint(b, uint64(f)<<3|uint64(t))
   138  }