166 lines
3.3 KiB
Go
166 lines
3.3 KiB
Go
|
package binary
|
||
|
|
||
|
import (
|
||
|
"encoding/binary"
|
||
|
"io"
|
||
|
"math"
|
||
|
)
|
||
|
|
||
|
func NewDecoder(input io.Reader) *Decoder {
|
||
|
return &Decoder{
|
||
|
input: input,
|
||
|
compressInput: NewCompressReader(input),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type Decoder struct {
|
||
|
compress bool
|
||
|
input io.Reader
|
||
|
compressInput io.Reader
|
||
|
scratch [binary.MaxVarintLen64]byte
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) SelectCompress(compress bool) {
|
||
|
decoder.compress = compress
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) Get() io.Reader {
|
||
|
if decoder.compress {
|
||
|
return decoder.compressInput
|
||
|
}
|
||
|
return decoder.input
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) Bool() (bool, error) {
|
||
|
v, err := decoder.ReadByte()
|
||
|
if err != nil {
|
||
|
return false, err
|
||
|
}
|
||
|
return v == 1, nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) Uvarint() (uint64, error) {
|
||
|
return binary.ReadUvarint(decoder)
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) Int8() (int8, error) {
|
||
|
v, err := decoder.ReadByte()
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
return int8(v), nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) Int16() (int16, error) {
|
||
|
v, err := decoder.UInt16()
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
return int16(v), nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) Int32() (int32, error) {
|
||
|
v, err := decoder.UInt32()
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
return int32(v), nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) Int64() (int64, error) {
|
||
|
v, err := decoder.UInt64()
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
return int64(v), nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) UInt8() (uint8, error) {
|
||
|
v, err := decoder.ReadByte()
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
return uint8(v), nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) UInt16() (uint16, error) {
|
||
|
if _, err := decoder.Get().Read(decoder.scratch[:2]); err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
return uint16(decoder.scratch[0]) | uint16(decoder.scratch[1])<<8, nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) UInt32() (uint32, error) {
|
||
|
if _, err := decoder.Get().Read(decoder.scratch[:4]); err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
return uint32(decoder.scratch[0]) |
|
||
|
uint32(decoder.scratch[1])<<8 |
|
||
|
uint32(decoder.scratch[2])<<16 |
|
||
|
uint32(decoder.scratch[3])<<24, nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) UInt64() (uint64, error) {
|
||
|
if _, err := decoder.Get().Read(decoder.scratch[:8]); err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
return uint64(decoder.scratch[0]) |
|
||
|
uint64(decoder.scratch[1])<<8 |
|
||
|
uint64(decoder.scratch[2])<<16 |
|
||
|
uint64(decoder.scratch[3])<<24 |
|
||
|
uint64(decoder.scratch[4])<<32 |
|
||
|
uint64(decoder.scratch[5])<<40 |
|
||
|
uint64(decoder.scratch[6])<<48 |
|
||
|
uint64(decoder.scratch[7])<<56, nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) Float32() (float32, error) {
|
||
|
v, err := decoder.UInt32()
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
return math.Float32frombits(v), nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) Float64() (float64, error) {
|
||
|
v, err := decoder.UInt64()
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
return math.Float64frombits(v), nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) Fixed(ln int) ([]byte, error) {
|
||
|
if reader, ok := decoder.Get().(FixedReader); ok {
|
||
|
return reader.Fixed(ln)
|
||
|
}
|
||
|
buf := make([]byte, ln)
|
||
|
if _, err := decoder.Get().Read(buf); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return buf, nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) String() (string, error) {
|
||
|
strlen, err := decoder.Uvarint()
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
str, err := decoder.Fixed(int(strlen))
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
return string(str), nil
|
||
|
}
|
||
|
|
||
|
func (decoder *Decoder) ReadByte() (byte, error) {
|
||
|
if _, err := decoder.Get().Read(decoder.scratch[:1]); err != nil {
|
||
|
return 0x0, err
|
||
|
}
|
||
|
return decoder.scratch[0], nil
|
||
|
}
|
||
|
|
||
|
type FixedReader interface {
|
||
|
Fixed(ln int) ([]byte, error)
|
||
|
}
|