github.com/philpearl/plenc@v0.0.15/plenccodec/int.go (about) 1 package plenccodec 2 3 import ( 4 "fmt" 5 "unsafe" 6 7 "github.com/philpearl/plenc/plenccore" 8 ) 9 10 // IntCodec is a coddec for an int 11 type IntCodec[T int | int8 | int16 | int32 | int64] struct{} 12 13 // size returns the number of bytes needed to encode a Int 14 func (IntCodec[T]) size(ptr unsafe.Pointer) int { 15 return plenccore.SizeVarInt(int64(*(*T)(ptr))) 16 } 17 18 // append encodes a Int 19 func (IntCodec[T]) append(data []byte, ptr unsafe.Pointer) []byte { 20 return plenccore.AppendVarInt(data, int64(*(*T)(ptr))) 21 } 22 23 // Read decodes a Int 24 func (IntCodec[T]) Read(data []byte, ptr unsafe.Pointer, wt plenccore.WireType) (n int, err error) { 25 i, n := plenccore.ReadVarInt(data) 26 if n < 0 { 27 return 0, fmt.Errorf("corrupt var int") 28 } 29 *(*T)(ptr) = T(i) 30 return n, nil 31 } 32 33 // New creates a pointer to a new Int 34 func (c IntCodec[T]) New() unsafe.Pointer { 35 return unsafe.Pointer(new(T)) 36 } 37 38 // WireType returns the wire type used to encode this type 39 func (c IntCodec[T]) WireType() plenccore.WireType { 40 return plenccore.WTVarInt 41 } 42 43 // Omit indicates whether this field should be omitted 44 func (c IntCodec[T]) Omit(ptr unsafe.Pointer) bool { 45 return *(*T)(ptr) == 0 46 } 47 48 func (c IntCodec[T]) Descriptor() Descriptor { 49 return Descriptor{Type: FieldTypeInt} 50 } 51 52 func (c IntCodec[T]) Size(ptr unsafe.Pointer, tag []byte) int { 53 return c.size(ptr) + len(tag) 54 } 55 56 func (c IntCodec[T]) Append(data []byte, ptr unsafe.Pointer, tag []byte) []byte { 57 data = append(data, tag...) 58 return c.append(data, ptr) 59 } 60 61 // FlatIntCodec is for signed ints that aren't zig-zag encoded. Use this with 62 // ints that are almost always positive. 63 type FlatIntCodec[T uint | uint8 | uint16 | uint32 | uint64] struct { 64 UintCodec[T] 65 } 66 67 func (c FlatIntCodec[T]) Descriptor() Descriptor { 68 return Descriptor{Type: FieldTypeFlatInt} 69 } 70 71 // UintCodec is a coddec for a uint 72 type UintCodec[T uint | uint8 | uint16 | uint32 | uint64] struct{} 73 74 // size returns the number of bytes needed to encode a Int 75 func (UintCodec[T]) size(ptr unsafe.Pointer) int { 76 return plenccore.SizeVarUint(uint64(*(*T)(ptr))) 77 } 78 79 // append encodes a Int 80 func (UintCodec[T]) append(data []byte, ptr unsafe.Pointer) []byte { 81 return plenccore.AppendVarUint(data, uint64(*(*T)(ptr))) 82 } 83 84 // Read decodes a Int 85 func (UintCodec[T]) Read(data []byte, ptr unsafe.Pointer, wt plenccore.WireType) (n int, err error) { 86 i, n := plenccore.ReadVarUint(data) 87 if n < 0 { 88 return 0, fmt.Errorf("corrupt var int") 89 } 90 *(*T)(ptr) = T(i) 91 return n, nil 92 } 93 94 // New creates a pointer to a new Int 95 func (c UintCodec[T]) New() unsafe.Pointer { 96 return unsafe.Pointer(new(T)) 97 } 98 99 // WireType returns the wire type used to encode this type 100 func (c UintCodec[T]) WireType() plenccore.WireType { 101 return plenccore.WTVarInt 102 } 103 104 // Omit indicates whether this field should be omitted 105 func (c UintCodec[T]) Omit(ptr unsafe.Pointer) bool { 106 return *(*T)(ptr) == 0 107 } 108 109 func (c UintCodec[T]) Descriptor() Descriptor { 110 return Descriptor{Type: FieldTypeUint} 111 } 112 113 func (c UintCodec[T]) Size(ptr unsafe.Pointer, tag []byte) int { 114 return c.size(ptr) + len(tag) 115 } 116 117 func (c UintCodec[T]) Append(data []byte, ptr unsafe.Pointer, tag []byte) []byte { 118 data = append(data, tag...) 119 return c.append(data, ptr) 120 }