package binary
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"time"
|
|
)
|
|
|
|
type Codec interface {
|
|
WriteTo(io.Writer, interface{}, *int64, *error)
|
|
ReadFrom(io.Reader, *int64, *error) interface{}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
const (
|
|
typeNil = byte(0x00)
|
|
typeByte = byte(0x01)
|
|
typeInt8 = byte(0x02)
|
|
// typeUInt8 = byte(0x03)
|
|
typeInt16 = byte(0x04)
|
|
typeUInt16 = byte(0x05)
|
|
typeInt32 = byte(0x06)
|
|
typeUInt32 = byte(0x07)
|
|
typeInt64 = byte(0x08)
|
|
typeUInt64 = byte(0x09)
|
|
typeString = byte(0x10)
|
|
typeByteSlice = byte(0x11)
|
|
typeTime = byte(0x20)
|
|
)
|
|
|
|
var BasicCodec = basicCodec{}
|
|
|
|
type basicCodec struct{}
|
|
|
|
func (bc basicCodec) WriteTo(w io.Writer, o interface{}, n *int64, err *error) {
|
|
switch o.(type) {
|
|
case nil:
|
|
WriteByte(w, typeNil, n, err)
|
|
case byte:
|
|
WriteByte(w, typeByte, n, err)
|
|
WriteByte(w, o.(byte), n, err)
|
|
case int8:
|
|
WriteByte(w, typeInt8, n, err)
|
|
WriteInt8(w, o.(int8), n, err)
|
|
//case uint8:
|
|
// WriteByte(w, typeUInt8, n, err)
|
|
// WriteUInt8(w, o.(uint8), n, err)
|
|
case int16:
|
|
WriteByte(w, typeInt16, n, err)
|
|
WriteInt16(w, o.(int16), n, err)
|
|
case uint16:
|
|
WriteByte(w, typeUInt16, n, err)
|
|
WriteUInt16(w, o.(uint16), n, err)
|
|
case int32:
|
|
WriteByte(w, typeInt32, n, err)
|
|
WriteInt32(w, o.(int32), n, err)
|
|
case uint32:
|
|
WriteByte(w, typeUInt32, n, err)
|
|
WriteUInt32(w, o.(uint32), n, err)
|
|
case int64:
|
|
WriteByte(w, typeInt64, n, err)
|
|
WriteInt64(w, o.(int64), n, err)
|
|
case uint64:
|
|
WriteByte(w, typeUInt64, n, err)
|
|
WriteUInt64(w, o.(uint64), n, err)
|
|
case string:
|
|
WriteByte(w, typeString, n, err)
|
|
WriteString(w, o.(string), n, err)
|
|
case []byte:
|
|
WriteByte(w, typeByteSlice, n, err)
|
|
WriteByteSlice(w, o.([]byte), n, err)
|
|
case time.Time:
|
|
WriteByte(w, typeTime, n, err)
|
|
WriteTime(w, o.(time.Time), n, err)
|
|
default:
|
|
panic("Unsupported type")
|
|
}
|
|
return
|
|
}
|
|
|
|
func (bc basicCodec) ReadFrom(r io.Reader, n *int64, err *error) interface{} {
|
|
type_ := ReadByte(r, n, err)
|
|
switch type_ {
|
|
case typeNil:
|
|
return nil
|
|
case typeByte:
|
|
return ReadByte(r, n, err)
|
|
case typeInt8:
|
|
return ReadInt8(r, n, err)
|
|
//case typeUInt8:
|
|
// return ReadUInt8(r, n, err)
|
|
case typeInt16:
|
|
return ReadInt16(r, n, err)
|
|
case typeUInt16:
|
|
return ReadUInt16(r, n, err)
|
|
case typeInt32:
|
|
return ReadInt32(r, n, err)
|
|
case typeUInt32:
|
|
return ReadUInt32(r, n, err)
|
|
case typeInt64:
|
|
return ReadInt64(r, n, err)
|
|
case typeUInt64:
|
|
return ReadUInt64(r, n, err)
|
|
case typeString:
|
|
return ReadString(r, n, err)
|
|
case typeByteSlice:
|
|
return ReadByteSlice(r, n, err)
|
|
case typeTime:
|
|
return ReadTime(r, n, err)
|
|
default:
|
|
panic("Unsupported type")
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Creates an adapter codec for Binary things.
|
|
// Resulting Codec can be used with merkle/*.
|
|
type BinaryCodec struct {
|
|
decoder func(io.Reader, *int64, *error) interface{}
|
|
}
|
|
|
|
func NewBinaryCodec(decoder func(io.Reader, *int64, *error) interface{}) *BinaryCodec {
|
|
return &BinaryCodec{decoder}
|
|
}
|
|
|
|
func (ca *BinaryCodec) WriteTo(w io.Writer, o interface{}, n *int64, err *error) {
|
|
if bo, ok := o.(Binary); ok {
|
|
WriteTo(w, BinaryBytes(bo), n, err)
|
|
} else {
|
|
*err = errors.New("BinaryCodec expected Binary object")
|
|
}
|
|
}
|
|
|
|
func (ca *BinaryCodec) ReadFrom(r io.Reader, n *int64, err *error) interface{} {
|
|
return ca.decoder(r, n, err)
|
|
}
|