diff --git a/codec.go b/codec.go new file mode 100644 index 0000000..08426e1 --- /dev/null +++ b/codec.go @@ -0,0 +1,47 @@ +package hopp + +import "fmt" + +type anyInt16 interface { ~uint16 | ~int16 } +type anyInt64 interface { ~uint64 | ~int64 } + +// decodeI16 decodes a 16 bit integer from the given data. +func decodeI16[T anyInt16](data []byte) (T, error) { + if len(data) != 2 { return 0, fmt.Errorf("decoding int16: %w", ErrWrongBufferLength) } + return T(data[0]) << 8 | T(data[1]), nil +} + +// encodeI16 encodes a 16 bit integer into the given buffer. +func encodeI16[T anyInt16](buffer []byte, value T) error { + if len(buffer) != 2 { return fmt.Errorf("encoding int16: %w", ErrWrongBufferLength) } + buffer[0] = byte(value >> 8) + buffer[1] = byte(value) + return nil +} + +// decodeI64 decodes a 64 bit integer from the given data. +func decodeI64[T anyInt64](data []byte) (T, error) { + if len(data) != 8 { return 0, fmt.Errorf("decoding int64: %w", ErrWrongBufferLength) } + return T(data[0]) << 56 | + T(data[1]) << 48 | + T(data[2]) << 40 | + T(data[3]) << 32 | + T(data[4]) << 24 | + T(data[5]) << 16 | + T(data[6]) << 8 | + T(data[7]), nil +} + +// encodeI64 encodes a 64 bit integer into the given buffer. +func encodeI64[T anyInt64](buffer []byte, value T) error { + if len(buffer) != 8 { return fmt.Errorf("encoding int64: %w", ErrWrongBufferLength) } + buffer[0] = byte(value >> 56) + buffer[1] = byte(value >> 48) + buffer[2] = byte(value >> 40) + buffer[3] = byte(value >> 32) + buffer[4] = byte(value >> 24) + buffer[5] = byte(value >> 16) + buffer[6] = byte(value >> 8) + buffer[7] = byte(value) + return nil +} diff --git a/error.go b/error.go index 20bf6b3..3a78a4d 100644 --- a/error.go +++ b/error.go @@ -9,6 +9,7 @@ type Error string; const ( ErrIntegerOverflow Error = "integer overflow" ErrMessageMalformed Error = "message is malformed" ErrTablePairMissing Error = "required table pair is missing" + ErrWrongBufferLength Error = "wrong buffer length" ) // Error implements the error interface.