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  }