github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/protokit/wire_type.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 "encoding/binary" 10 "fmt" 11 "io" 12 "math" 13 ) 14 15 const ( 16 WireTypeBits = 3 17 MaxVarintSize = binary.MaxVarintLen64 18 MinVarintSize = 1 19 MaxFieldID = math.MaxUint32 >> WireTypeBits 20 maskWireType = 1<<WireTypeBits - 1 21 ) 22 23 type WireType uint8 24 25 const ( 26 WireVarint WireType = iota 27 WireFixed64 28 WireBytes 29 WireStartGroup 30 WireEndGroup 31 WireFixed32 32 33 MaxWireType = iota - 1 34 ) 35 36 type UintDecoderFunc func(io.ByteReader) (uint64, error) 37 type UintEncoderFunc func(io.ByteWriter, uint64) error 38 39 type UintByteDecoderFunc func([]byte) (uint64, int, error) 40 type UintByteEncoderFunc func([]byte, uint64) (int, error) 41 42 var wireTypes = []struct { 43 name string 44 decodeFn UintDecoderFunc 45 encodeFn UintEncoderFunc 46 byteDecodeFn UintByteDecoderFunc 47 byteEncodeFn UintByteEncoderFunc 48 fieldSizeFn func(uint64) uint64 49 minSize, maxSize int8 50 }{ 51 WireFixed64: {"fixed64", DecodeFixed64, EncodeFixed64, 52 DecodeFixed64FromBytesWithError, EncodeFixed64ToBytes, 53 nil, 8, 8}, 54 55 WireFixed32: {"fixed32", DecodeFixed32, func(w io.ByteWriter, u uint64) error { 56 if u > math.MaxUint32 { 57 panic(errOverflow) 58 } 59 return EncodeFixed32(w, uint32(u)) 60 }, DecodeFixed32FromBytesWithError, func(b []byte, u uint64) (int, error) { 61 if u > math.MaxUint32 { 62 panic(errOverflow) 63 } 64 return EncodeFixed32ToBytes(b, uint32(u)) 65 }, 66 nil, 4, 4}, 67 68 WireVarint: {"varint", DecodeVarint, EncodeVarint, 69 DecodeVarintFromBytesWithError, EncodeVarintToBytesWithError, 70 func(u uint64) uint64 { 71 return uint64(SizeVarint64(u)) 72 }, 73 1, MaxVarintSize}, 74 75 WireBytes: {"bytes", DecodeVarint, EncodeVarint, 76 DecodeVarintFromBytesWithError, EncodeVarintToBytesWithError, 77 func(u uint64) uint64 { 78 return uint64(SizeVarint64(u)) + u 79 }, 80 1, -1}, 81 82 WireStartGroup: {name: "groupStart"}, 83 WireEndGroup: {name: "groupEnd"}, 84 } 85 86 func (v WireType) IsValid() bool { 87 return v <= MaxWireType 88 } 89 90 func (v WireType) Tag(fieldID int) WireTag { 91 if fieldID <= 0 || fieldID > MaxFieldID { 92 panic("illegal value") 93 } 94 return WireTag(fieldID<<WireTypeBits | int(v)) 95 } 96 97 const maxMask = int(^uint(0) >> 1) 98 99 func (v WireType) DataSize() (minSize, maxSize int) { 100 min, max := int(wireTypes[v].minSize), int(wireTypes[v].maxSize) 101 if min <= 0 { 102 panic("illegal value") 103 } 104 return min, max & maxMask /* converts -1 to maxInt */ 105 } 106 107 func (v WireType) FieldSize(tagSize int, u uint64) uint64 { 108 sizeFn := wireTypes[v].fieldSizeFn 109 if sizeFn != nil { 110 return sizeFn(u) + uint64(tagSize) 111 } 112 if wireTypes[v].minSize == 0 { 113 panic("illegal value") 114 } 115 return uint64(wireTypes[v].minSize) + uint64(tagSize) 116 } 117 118 func (v WireType) UintDecoder() (UintDecoderFunc, error) { 119 if v <= MaxWireType { 120 return wireTypes[v].decodeFn, nil 121 } 122 return nil, fmt.Errorf("unsupported wire type %x", v) 123 } 124 125 func (v WireType) UintEncoder() (UintEncoderFunc, error) { 126 if v <= MaxWireType { 127 return wireTypes[v].encodeFn, nil 128 } 129 return nil, fmt.Errorf("unsupported wire type %x", v) 130 } 131 132 func (v WireType) UintByteDecoder() (UintByteDecoderFunc, error) { 133 if v <= MaxWireType { 134 return wireTypes[v].byteDecodeFn, nil 135 } 136 return nil, fmt.Errorf("unsupported wire type %x", v) 137 } 138 139 func (v WireType) UintByteEncoder() (UintByteEncoderFunc, error) { 140 if v <= MaxWireType { 141 return wireTypes[v].byteEncodeFn, nil 142 } 143 return nil, fmt.Errorf("unsupported wire type %x", v) 144 } 145 146 func (v WireType) String() string { 147 if v <= MaxWireType { 148 if s := wireTypes[v].name; s != "" { 149 return s 150 } 151 } 152 return fmt.Sprintf("unknown%d", v) 153 } 154 155 func (v WireType) ReadValue(r io.ByteReader) (uint64, error) { 156 decodeFn, err := v.UintDecoder() 157 if err != nil { 158 return 0, err 159 } 160 return decodeFn(r) 161 } 162 163 func (v WireType) WriteValue(w io.ByteWriter, u uint64) error { 164 encodeFn, err := v.UintEncoder() 165 if err != nil { 166 return err 167 } 168 return encodeFn(w, u) 169 } 170 171 func (v WireType) WriteValueToBytes(b []byte, u uint64) (int, error) { 172 encodeFn, err := v.UintByteEncoder() 173 if err != nil { 174 return 0, err 175 } 176 return encodeFn(b, u) 177 } 178 179 func (v WireType) ReadValueFromBytes(b []byte) (uint64, int, error) { 180 decodeFn, err := v.UintByteDecoder() 181 if err != nil { 182 return 0, 0, err 183 } 184 return decodeFn(b) 185 }