mq_coder/encoding/nvarint.go

133 lines
3.6 KiB
Go

package encoding
import (
"errors"
)
// SizeOfNVarInt32 return the buffer size after encoding value as NVarInt32
func SizeOfNVarInt32(value int32) int {
return sizeOfNVarInt(int64(value), 32)
}
// EncodeNVarInt32 encode value as NVarInt32 to buffer
func (codec *VarCodec) EncodeNVarInt32(buffer []byte, value int32) error {
return codec.encodeNVarInt(buffer, int64(value))
}
// DecodeNVarInt32 decode to value as NVarInt32 from buffer
func (codec *VarCodec) DecodeNVarInt32(buffer []byte, value *int32) error {
var val = int64(*value)
var err = codec.decodeNVarInt(buffer, &val)
*value = int32(val)
return err
}
// SizeOfNVarUInt32 return the buffer size after encoding value as NVarUInt32
func SizeOfNVarUInt32(value uint32) int {
return sizeOfNVarInt(int64(int32(value)), 32)
}
// EncodeNVarUInt32 encode value as NVarUInt32 to buffer
func (codec *VarCodec) EncodeNVarUInt32(buffer []byte, value uint32) error {
return codec.encodeNVarInt(buffer, int64(int32(value)))
}
// DecodeNVarUInt32 decode to value as NVarUInt32 from buffer
func (codec *VarCodec) DecodeNVarUInt32(buffer []byte, value *uint32) error {
var val = int64(int32(*value))
var err = codec.decodeNVarInt(buffer, &val)
*value = uint32(val)
return err
}
// SizeOfNVarInt64 return the buffer size after encoding value as NVarInt64
func SizeOfNVarInt64(value int64) int {
return sizeOfNVarInt(value, 64)
}
// EncodeNVarInt64 encode value as NVarInt64 to buffer
func (codec *VarCodec) EncodeNVarInt64(buffer []byte, value int64) error {
return codec.encodeNVarInt(buffer, value)
}
// DecodeNVarInt64 decode to value as NVarInt64 from buffer
func (codec *VarCodec) DecodeNVarInt64(buffer []byte, value *int64) error {
return codec.decodeNVarInt(buffer, value)
}
// SizeOfNVarUInt64 return the buffer size after encoding value as NVarUInt64
func SizeOfNVarUInt64(value uint64) int {
return sizeOfNVarInt(int64(value), 64)
}
// EncodeNVarUInt64 encode value as NVarUInt64 to buffer
func (codec *VarCodec) EncodeNVarUInt64(buffer []byte, value uint64) error {
return codec.encodeNVarInt(buffer, int64(value))
}
// DecodeNVarUInt64 decode to value as NVarUInt64 from buffer
func (codec *VarCodec) DecodeNVarUInt64(buffer []byte, value *uint64) error {
var val = int64(*value)
var err = codec.decodeNVarInt(buffer, &val)
*value = uint64(val)
return err
}
// SizeOfNVarInt return the buffer size after encoding value as NVarInt
func sizeOfNVarInt(value int64, width int) int {
const unit = 8 // bit width of encoding unit
var lead = value >> (width - 1)
for size := width / unit - 1; size > 0; size-- {
var lookAhead = value >> (size*unit - 1)
if lookAhead != lead {
return size + 1
}
}
return 1
}
func (codec *VarCodec) encodeNVarInt(buffer []byte, value int64) error {
if codec == nil || codec.Size == 0 {
return errors.New("nothing to encode")
}
const unit = 8 // bit width of encoding unit
for codec.Size > 0 {
if codec.Ptr >= len(buffer) {
return ErrBufferInsufficient
}
codec.Size--
buffer[codec.Ptr] = byte(value >> (codec.Size * unit))
codec.Ptr++
}
return nil
}
func (codec *VarCodec) decodeNVarInt(buffer []byte, value *int64) error {
if codec == nil || codec.Size == 0 {
return errors.New("nothing to decode")
}
const unit = 8 // bit width of encoding unit
if codec.Size > 0 { // initialize sign bit
if codec.Ptr >= len(buffer) {
return ErrBufferInsufficient
}
*value = int64(int8(buffer[codec.Ptr]) >> (unit - 1))
codec.Size = -codec.Size
}
for codec.Size < 0 {
if codec.Ptr >= len(buffer) {
return ErrBufferInsufficient
}
codec.Size++
*value = (*value << unit) | int64(buffer[codec.Ptr])
codec.Ptr++
}
return nil
}