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 }