2022-10-07 15:30:45 +08:00
|
|
|
package encoding
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
// SizeOfPVarInt32 return the buffer size after encoding value as PVarInt32
|
|
|
|
func SizeOfPVarInt32(value int32) int {
|
|
|
|
return sizeOfPVarInt(int64(value), 32)
|
|
|
|
}
|
|
|
|
|
|
|
|
// EncodePVarInt32 encode value as PVarInt32 to buffer
|
|
|
|
func (codec *VarCodec) EncodePVarInt32(buffer []byte, value int32) error {
|
|
|
|
return codec.encodePVarInt(buffer, int64(value))
|
|
|
|
}
|
|
|
|
|
|
|
|
// DecodePVarInt32 decode to value as PVarInt32 from buffer
|
|
|
|
func (codec *VarCodec) DecodePVarInt32(buffer []byte, value *int32) error {
|
|
|
|
var val = int64(*value)
|
|
|
|
var err = codec.decodePVarInt(buffer, &val)
|
|
|
|
*value = int32(val)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// SizeOfPVarUInt32 return the buffer size after encoding value as PVarUInt32
|
|
|
|
func SizeOfPVarUInt32(value uint32) int {
|
|
|
|
return sizeOfPVarInt(int64(int32(value)), 32)
|
|
|
|
}
|
|
|
|
|
|
|
|
// EncodePVarUInt32 encode value as PVarUInt32 to buffer
|
|
|
|
func (codec *VarCodec) EncodePVarUInt32(buffer []byte, value uint32) error {
|
|
|
|
return codec.encodePVarInt(buffer, int64(int32(value)))
|
|
|
|
}
|
|
|
|
|
|
|
|
// DecodePVarUInt32 decode to value as PVarUInt32 from buffer
|
|
|
|
func (codec *VarCodec) DecodePVarUInt32(buffer []byte, value *uint32) error {
|
|
|
|
var val = int64(int32(*value))
|
|
|
|
var err = codec.decodePVarInt(buffer, &val)
|
|
|
|
*value = uint32(val)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// SizeOfPVarInt64 return the buffer size after encoding value as PVarInt64
|
|
|
|
func SizeOfPVarInt64(value int64) int {
|
|
|
|
return sizeOfPVarInt(value, 64)
|
|
|
|
}
|
|
|
|
|
|
|
|
// EncodePVarInt64 encode value as PVarInt64 to buffer
|
|
|
|
func (codec *VarCodec) EncodePVarInt64(buffer []byte, value int64) error {
|
|
|
|
return codec.encodePVarInt(buffer, value)
|
|
|
|
}
|
|
|
|
|
|
|
|
// DecodePVarInt64 decode to value as PVarInt64 from buffer
|
|
|
|
func (codec *VarCodec) DecodePVarInt64(buffer []byte, value *int64) error {
|
|
|
|
return codec.decodePVarInt(buffer, value)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SizeOfPVarUInt64 return the buffer size after encoding value as PVarUInt64
|
|
|
|
func SizeOfPVarUInt64(value uint64) int {
|
|
|
|
return sizeOfPVarInt(int64(value), 64)
|
|
|
|
}
|
|
|
|
|
|
|
|
// EncodePVarUInt64 encode value as PVarUInt64 to buffer
|
|
|
|
func (codec *VarCodec) EncodePVarUInt64(buffer []byte, value uint64) error {
|
|
|
|
return codec.encodePVarInt(buffer, int64(value))
|
|
|
|
}
|
|
|
|
|
|
|
|
// DecodePVarUInt64 decode to value as PVarUInt64 from buffer
|
|
|
|
func (codec *VarCodec) DecodePVarUInt64(buffer []byte, value *uint64) error {
|
|
|
|
var val = int64(*value)
|
|
|
|
var err = codec.decodePVarInt(buffer, &val)
|
|
|
|
*value = uint64(val)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func sizeOfPVarInt(value int64, width int) int {
|
2022-10-07 15:41:18 +08:00
|
|
|
const unit = 7 // a bit width of encoding unit
|
2022-10-07 15:30:45 +08:00
|
|
|
|
|
|
|
var lead = value >> (width - 1)
|
|
|
|
for size := width / unit; size > 0; size-- {
|
|
|
|
var lookAhead = value >> (size*unit - 1)
|
|
|
|
if lookAhead != lead {
|
|
|
|
return size + 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
func (codec *VarCodec) encodePVarInt(buffer []byte, value int64) error {
|
|
|
|
if codec == nil || codec.Size == 0 {
|
|
|
|
return errors.New("nothing to encode")
|
|
|
|
}
|
|
|
|
if codec.Ptr >= len(buffer) {
|
|
|
|
return ErrBufferInsufficient
|
|
|
|
}
|
|
|
|
|
2022-10-07 15:41:18 +08:00
|
|
|
const unit = 7 // a bit width of encoding unit
|
2022-10-07 15:30:45 +08:00
|
|
|
const more = -1 << 7 // continuation bits
|
|
|
|
for codec.Size > 1 {
|
|
|
|
codec.Size--
|
|
|
|
var part = value >> (codec.Size * unit)
|
|
|
|
|
|
|
|
buffer[codec.Ptr] = byte(part | more)
|
|
|
|
codec.Ptr++
|
|
|
|
|
|
|
|
if codec.Ptr >= len(buffer) {
|
|
|
|
return ErrBufferInsufficient
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const mask = -1 ^ (-1 << unit) // mask for encoding unit
|
|
|
|
codec.Size = 0
|
|
|
|
buffer[codec.Ptr] = byte(value & mask)
|
|
|
|
codec.Ptr++
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (codec *VarCodec) decodePVarInt(buffer []byte, value *int64) error {
|
|
|
|
if codec == nil {
|
|
|
|
return errors.New("nothing to decode")
|
|
|
|
}
|
|
|
|
if codec.Ptr >= len(buffer) {
|
|
|
|
return ErrBufferInsufficient
|
|
|
|
}
|
|
|
|
|
2022-10-07 15:41:18 +08:00
|
|
|
const unit = 7 // a bit width of encoding unit
|
2022-10-07 15:30:45 +08:00
|
|
|
if codec.Size == 0 { // initialize sign bit
|
2022-10-07 15:41:18 +08:00
|
|
|
const flag = 8 - unit // a bit of width for non-encoding bits
|
2022-10-07 15:30:45 +08:00
|
|
|
*value = int64(int8(buffer[codec.Ptr]) << flag >> unit)
|
|
|
|
}
|
|
|
|
|
|
|
|
const mask = -1 ^ (-1 << unit) // mask for encoding unit
|
|
|
|
for {
|
|
|
|
var part = int8(buffer[codec.Ptr])
|
|
|
|
codec.Ptr++
|
|
|
|
|
|
|
|
codec.Size++
|
2022-10-07 15:41:18 +08:00
|
|
|
*value = (*value << unit) | int64(mask&part)
|
2022-10-07 15:30:45 +08:00
|
|
|
|
|
|
|
if part >= 0 { // it's the last byte
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if codec.Ptr >= len(buffer) {
|
|
|
|
return ErrBufferInsufficient
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|