mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-23 09:41:38 +00:00
Added README docs for account/binary and renamed UInt -> Uint etc.
This commit is contained in:
167
binary/README.md
Normal file
167
binary/README.md
Normal file
@ -0,0 +1,167 @@
|
||||
# `tendermint/binary`
|
||||
|
||||
The `binary` submodule encodes primary types and structs into bytes.
|
||||
|
||||
## Primary types
|
||||
|
||||
uint\*, int\*, string, time, byteslice and byteslice-slice types can be
|
||||
encoded and decoded with the following methods:
|
||||
|
||||
The following writes `o uint64` to `w io.Writer`, and increments `n` and/or sets `err`
|
||||
```go
|
||||
WriteUint64(o uint64, w io.Writer, n *int64, err *error)
|
||||
|
||||
// Typical usage:
|
||||
buf, n, err := new(bytes.Buffer), new(int64), new(error)
|
||||
WriteUint64(uint64(x), buf, n, err)
|
||||
if *err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The following reads a `uint64` from `r io.Reader`, and increments `n` and/or sets `err`
|
||||
```go
|
||||
var o = ReadUint64(r io.Reader, n *int64, err *error)
|
||||
```
|
||||
|
||||
Similar methods for `uint32`, `uint16`, `uint8`, `int64`, `int32`, `int16`, `int8` exist.
|
||||
Protobuf variable length encoding is done with `uint` and `int` types:
|
||||
```go
|
||||
WriteUvarint(o uint, w io.Writer, n *int64, err *error)
|
||||
var o = ReadUvarint(r io.Reader, n *int64, err *error)
|
||||
```
|
||||
|
||||
Byteslices can be written with:
|
||||
```go
|
||||
WriteByteSlice(bz []byte, w io.Writer, n *int64, err *error)
|
||||
```
|
||||
|
||||
Byteslices (and all slices such as byteslice-slices) are prepended with
|
||||
`uvarint` encoded length, so `ReadByteSlice()` knows how many bytes to read.
|
||||
|
||||
Note that there is no type information encoded -- the caller is assumed to know what types
|
||||
to decode.
|
||||
|
||||
## Struct Types
|
||||
|
||||
Struct types can be automatically encoded with reflection. Unlike json-encoding, no field
|
||||
name or type information is encoded. Field values are simply encoded in order.
|
||||
|
||||
```go
|
||||
type Foo struct {
|
||||
MyString string
|
||||
MyUint32 uint32
|
||||
myPrivateBytes []byte
|
||||
}
|
||||
|
||||
foo := Foo{"my string", math.MaxUint32, []byte("my private bytes")}
|
||||
|
||||
buf, n, err := new(bytes.Buffer), new(int64), new(error)
|
||||
WriteBinary(foo, buf, n, err)
|
||||
|
||||
// fmt.Printf("%X", buf.Bytes()) gives:
|
||||
// 096D7920737472696E67FFFFFFFF
|
||||
// 09: uvarint encoded length of string "my string"
|
||||
// 6D7920737472696E67: bytes of string "my string"
|
||||
// FFFFFFFF: bytes for MaxUint32
|
||||
// Note that the unexported "myPrivateBytes" isn't encoded.
|
||||
|
||||
foo2 := ReadBinary(Foo{}, buf, n, err).(Foo)
|
||||
|
||||
// Or, to decode onto a pointer:
|
||||
foo2 := ReadBinary(&Foo{}, buf, n, err).(*Foo)
|
||||
```
|
||||
|
||||
WriteBinary and ReadBinary can encode/decode structs recursively. However, interface field
|
||||
values are a bit more complicated.
|
||||
|
||||
```go
|
||||
type Greeter interface {
|
||||
Greet() string
|
||||
}
|
||||
|
||||
type Dog struct{}
|
||||
func (d Dog) Greet() string { return "Woof!" }
|
||||
|
||||
type Cat struct{}
|
||||
func (c Cat) Greet() string { return "Meow!" }
|
||||
|
||||
type Foo struct {
|
||||
Greeter
|
||||
}
|
||||
|
||||
foo := Foo{Dog{}}
|
||||
|
||||
buf, n, err := new(bytes.Buffer), new(int64), new(error)
|
||||
WriteBinary(foo, buf, n, err)
|
||||
|
||||
// This errors with "Unknown field type interface"
|
||||
foo2 := ReadBinary(Foo{}, buf, n, err)
|
||||
```
|
||||
|
||||
In the above example, `ReadBinary()` fails because the `Greeter` field for `Foo{}`
|
||||
is ambiguous -- it could be either a `Dog{}` or a `Cat{}`, like a union structure.
|
||||
In this case, the user must define a custom encoder/decoder as follows:
|
||||
|
||||
```go
|
||||
const (
|
||||
GreeterTypeDog = byte(0x01)
|
||||
GreeterTypeCat = byte(0x02)
|
||||
)
|
||||
|
||||
func GreeterEncoder(o interface{}, w io.Writer, n *int64, err *error) {
|
||||
switch o.(type) {
|
||||
case Dog:
|
||||
WriteByte(GreeterTypeDog, w, n, err)
|
||||
WriteBinary(o, w, n, err)
|
||||
case Cat:
|
||||
WriteByte(GreeterTypeCat, w, n, err)
|
||||
WriteBinary(o, w, n, err)
|
||||
default:
|
||||
*err = errors.New(fmt.Sprintf("Unknown greeter type %v", o))
|
||||
}
|
||||
}
|
||||
|
||||
func GreeterDecoder(r io.Reader, n *int64, err *error) interface{} {
|
||||
switch t := ReadByte(r, n, err); t {
|
||||
case GreeterTypeDog:
|
||||
return ReadBinary(Dog{}, r, n, err)
|
||||
case GreeterTypeCat:
|
||||
return ReadBinary(Cat{}, r, n, err)
|
||||
default:
|
||||
*err = errors.New(fmt.Sprintf("Unknown greeter type byte %X", t))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// This tells the reflection system to use the custom encoder/decoder functions
|
||||
// for encoding/decoding interface struct-field types.
|
||||
var _ = RegisterType(&TypeInfo{
|
||||
Type: reflect.TypeOf((*Greeter)(nil)).Elem(),
|
||||
Encoder: GreeterEncoder,
|
||||
Decoder: GreeterDecoder,
|
||||
})
|
||||
```
|
||||
|
||||
Sometimes you want to always prefix a globally unique type byte while encoding,
|
||||
whether or not the declared type is an interface or concrete type.
|
||||
In this case, you can declare a "TypeByte() byte" function on the struct (as
|
||||
a value receiver, not a pointer receiver!), and you can skip the declaration of
|
||||
a custom decoder.
|
||||
|
||||
```go
|
||||
|
||||
type Dog struct{}
|
||||
func (d Dog) TypeByte() byte { return GreeterTypeDog }
|
||||
func (d Dog) Greet() string { return "Woof!" }
|
||||
|
||||
type Cat struct{}
|
||||
func (c Cat) TypeByte() byte { return GreeterTypeCat }
|
||||
func (c Cat) Greet() string { return "Meow!" }
|
||||
|
||||
var _ = RegisterType(&TypeInfo{
|
||||
Type: reflect.TypeOf((*Greeter)(nil)).Elem(),
|
||||
Decoder: GreeterDecoder,
|
||||
})
|
||||
```
|
@ -5,12 +5,12 @@ import (
|
||||
)
|
||||
|
||||
func WriteByteSlice(bz []byte, w io.Writer, n *int64, err *error) {
|
||||
WriteUVarInt(uint(len(bz)), w, n, err)
|
||||
WriteUvarint(uint(len(bz)), w, n, err)
|
||||
WriteTo(bz, w, n, err)
|
||||
}
|
||||
|
||||
func ReadByteSlice(r io.Reader, n *int64, err *error) []byte {
|
||||
length := ReadUVarInt(r, n, err)
|
||||
length := ReadUvarint(r, n, err)
|
||||
if *err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -22,7 +22,7 @@ func ReadByteSlice(r io.Reader, n *int64, err *error) []byte {
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
func WriteByteSlices(bzz [][]byte, w io.Writer, n *int64, err *error) {
|
||||
WriteUVarInt(uint(len(bzz)), w, n, err)
|
||||
WriteUvarint(uint(len(bzz)), w, n, err)
|
||||
for _, bz := range bzz {
|
||||
WriteByteSlice(bz, w, n, err)
|
||||
if *err != nil {
|
||||
@ -32,7 +32,7 @@ func WriteByteSlices(bzz [][]byte, w io.Writer, n *int64, err *error) {
|
||||
}
|
||||
|
||||
func ReadByteSlices(r io.Reader, n *int64, err *error) [][]byte {
|
||||
length := ReadUVarInt(r, n, err)
|
||||
length := ReadUvarint(r, n, err)
|
||||
if *err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -21,15 +21,15 @@ type Codec struct {
|
||||
const (
|
||||
typeByte = byte(0x01)
|
||||
typeInt8 = byte(0x02)
|
||||
// typeUInt8 = byte(0x03)
|
||||
// typeUint8 = byte(0x03)
|
||||
typeInt16 = byte(0x04)
|
||||
typeUInt16 = byte(0x05)
|
||||
typeUint16 = byte(0x05)
|
||||
typeInt32 = byte(0x06)
|
||||
typeUInt32 = byte(0x07)
|
||||
typeUint32 = byte(0x07)
|
||||
typeInt64 = byte(0x08)
|
||||
typeUInt64 = byte(0x09)
|
||||
typeVarInt = byte(0x0A)
|
||||
typeUVarInt = byte(0x0B)
|
||||
typeUint64 = byte(0x09)
|
||||
typeVarint = byte(0x0A)
|
||||
typeUvarint = byte(0x0B)
|
||||
typeString = byte(0x10)
|
||||
typeByteSlice = byte(0x11)
|
||||
typeTime = byte(0x20)
|
||||
@ -46,32 +46,32 @@ func BasicCodecEncoder(o interface{}, w io.Writer, n *int64, err *error) {
|
||||
WriteByte(typeInt8, w, n, err)
|
||||
WriteInt8(o.(int8), w, n, err)
|
||||
//case uint8:
|
||||
// WriteByte( typeUInt8, w, n, err)
|
||||
// WriteUInt8( o.(uint8), w, n, err)
|
||||
// WriteByte( typeUint8, w, n, err)
|
||||
// WriteUint8( o.(uint8), w, n, err)
|
||||
case int16:
|
||||
WriteByte(typeInt16, w, n, err)
|
||||
WriteInt16(o.(int16), w, n, err)
|
||||
case uint16:
|
||||
WriteByte(typeUInt16, w, n, err)
|
||||
WriteUInt16(o.(uint16), w, n, err)
|
||||
WriteByte(typeUint16, w, n, err)
|
||||
WriteUint16(o.(uint16), w, n, err)
|
||||
case int32:
|
||||
WriteByte(typeInt32, w, n, err)
|
||||
WriteInt32(o.(int32), w, n, err)
|
||||
case uint32:
|
||||
WriteByte(typeUInt32, w, n, err)
|
||||
WriteUInt32(o.(uint32), w, n, err)
|
||||
WriteByte(typeUint32, w, n, err)
|
||||
WriteUint32(o.(uint32), w, n, err)
|
||||
case int64:
|
||||
WriteByte(typeInt64, w, n, err)
|
||||
WriteInt64(o.(int64), w, n, err)
|
||||
case uint64:
|
||||
WriteByte(typeUInt64, w, n, err)
|
||||
WriteUInt64(o.(uint64), w, n, err)
|
||||
WriteByte(typeUint64, w, n, err)
|
||||
WriteUint64(o.(uint64), w, n, err)
|
||||
case int:
|
||||
WriteByte(typeVarInt, w, n, err)
|
||||
WriteVarInt(o.(int), w, n, err)
|
||||
WriteByte(typeVarint, w, n, err)
|
||||
WriteVarint(o.(int), w, n, err)
|
||||
case uint:
|
||||
WriteByte(typeUVarInt, w, n, err)
|
||||
WriteUVarInt(o.(uint), w, n, err)
|
||||
WriteByte(typeUvarint, w, n, err)
|
||||
WriteUvarint(o.(uint), w, n, err)
|
||||
case string:
|
||||
WriteByte(typeString, w, n, err)
|
||||
WriteString(o.(string), w, n, err)
|
||||
@ -93,24 +93,24 @@ func BasicCodecDecoder(r io.Reader, n *int64, err *error) (o interface{}) {
|
||||
o = ReadByte(r, n, err)
|
||||
case typeInt8:
|
||||
o = ReadInt8(r, n, err)
|
||||
//case typeUInt8:
|
||||
// o = ReadUInt8(r, n, err)
|
||||
//case typeUint8:
|
||||
// o = ReadUint8(r, n, err)
|
||||
case typeInt16:
|
||||
o = ReadInt16(r, n, err)
|
||||
case typeUInt16:
|
||||
o = ReadUInt16(r, n, err)
|
||||
case typeUint16:
|
||||
o = ReadUint16(r, n, err)
|
||||
case typeInt32:
|
||||
o = ReadInt32(r, n, err)
|
||||
case typeUInt32:
|
||||
o = ReadUInt32(r, n, err)
|
||||
case typeUint32:
|
||||
o = ReadUint32(r, n, err)
|
||||
case typeInt64:
|
||||
o = ReadInt64(r, n, err)
|
||||
case typeUInt64:
|
||||
o = ReadUInt64(r, n, err)
|
||||
case typeVarInt:
|
||||
o = ReadVarInt(r, n, err)
|
||||
case typeUVarInt:
|
||||
o = ReadUVarInt(r, n, err)
|
||||
case typeUint64:
|
||||
o = ReadUint64(r, n, err)
|
||||
case typeVarint:
|
||||
o = ReadVarint(r, n, err)
|
||||
case typeUvarint:
|
||||
o = ReadUvarint(r, n, err)
|
||||
case typeString:
|
||||
o = ReadString(r, n, err)
|
||||
case typeByteSlice:
|
||||
|
@ -28,13 +28,13 @@ func ReadInt8(r io.Reader, n *int64, err *error) int8 {
|
||||
return int8(ReadByte(r, n, err))
|
||||
}
|
||||
|
||||
// UInt8
|
||||
// Uint8
|
||||
|
||||
func WriteUInt8(i uint8, w io.Writer, n *int64, err *error) {
|
||||
func WriteUint8(i uint8, w io.Writer, n *int64, err *error) {
|
||||
WriteByte(byte(i), w, n, err)
|
||||
}
|
||||
|
||||
func ReadUInt8(r io.Reader, n *int64, err *error) uint8 {
|
||||
func ReadUint8(r io.Reader, n *int64, err *error) uint8 {
|
||||
return uint8(ReadByte(r, n, err))
|
||||
}
|
||||
|
||||
@ -53,41 +53,41 @@ func ReadInt16(r io.Reader, n *int64, err *error) int16 {
|
||||
return int16(binary.LittleEndian.Uint16(buf))
|
||||
}
|
||||
|
||||
// UInt16
|
||||
// Uint16
|
||||
|
||||
func WriteUInt16(i uint16, w io.Writer, n *int64, err *error) {
|
||||
func WriteUint16(i uint16, w io.Writer, n *int64, err *error) {
|
||||
buf := make([]byte, 2)
|
||||
binary.LittleEndian.PutUint16(buf, uint16(i))
|
||||
*n += 2
|
||||
WriteTo(buf, w, n, err)
|
||||
}
|
||||
|
||||
func ReadUInt16(r io.Reader, n *int64, err *error) uint16 {
|
||||
func ReadUint16(r io.Reader, n *int64, err *error) uint16 {
|
||||
buf := make([]byte, 2)
|
||||
ReadFull(buf, r, n, err)
|
||||
return uint16(binary.LittleEndian.Uint16(buf))
|
||||
}
|
||||
|
||||
// []UInt16
|
||||
// []Uint16
|
||||
|
||||
func WriteUInt16s(iz []uint16, w io.Writer, n *int64, err *error) {
|
||||
WriteUInt32(uint32(len(iz)), w, n, err)
|
||||
func WriteUint16s(iz []uint16, w io.Writer, n *int64, err *error) {
|
||||
WriteUint32(uint32(len(iz)), w, n, err)
|
||||
for _, i := range iz {
|
||||
WriteUInt16(i, w, n, err)
|
||||
WriteUint16(i, w, n, err)
|
||||
if *err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ReadUInt16s(r io.Reader, n *int64, err *error) []uint16 {
|
||||
length := ReadUInt32(r, n, err)
|
||||
func ReadUint16s(r io.Reader, n *int64, err *error) []uint16 {
|
||||
length := ReadUint32(r, n, err)
|
||||
if *err != nil {
|
||||
return nil
|
||||
}
|
||||
iz := make([]uint16, length)
|
||||
for j := uint32(0); j < length; j++ {
|
||||
ii := ReadUInt16(r, n, err)
|
||||
ii := ReadUint16(r, n, err)
|
||||
if *err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -111,16 +111,16 @@ func ReadInt32(r io.Reader, n *int64, err *error) int32 {
|
||||
return int32(binary.LittleEndian.Uint32(buf))
|
||||
}
|
||||
|
||||
// UInt32
|
||||
// Uint32
|
||||
|
||||
func WriteUInt32(i uint32, w io.Writer, n *int64, err *error) {
|
||||
func WriteUint32(i uint32, w io.Writer, n *int64, err *error) {
|
||||
buf := make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(buf, uint32(i))
|
||||
*n += 4
|
||||
WriteTo(buf, w, n, err)
|
||||
}
|
||||
|
||||
func ReadUInt32(r io.Reader, n *int64, err *error) uint32 {
|
||||
func ReadUint32(r io.Reader, n *int64, err *error) uint32 {
|
||||
buf := make([]byte, 4)
|
||||
ReadFull(buf, r, n, err)
|
||||
return uint32(binary.LittleEndian.Uint32(buf))
|
||||
@ -141,47 +141,47 @@ func ReadInt64(r io.Reader, n *int64, err *error) int64 {
|
||||
return int64(binary.LittleEndian.Uint64(buf))
|
||||
}
|
||||
|
||||
// UInt64
|
||||
// Uint64
|
||||
|
||||
func WriteUInt64(i uint64, w io.Writer, n *int64, err *error) {
|
||||
func WriteUint64(i uint64, w io.Writer, n *int64, err *error) {
|
||||
buf := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(buf, uint64(i))
|
||||
*n += 8
|
||||
WriteTo(buf, w, n, err)
|
||||
}
|
||||
|
||||
func ReadUInt64(r io.Reader, n *int64, err *error) uint64 {
|
||||
func ReadUint64(r io.Reader, n *int64, err *error) uint64 {
|
||||
buf := make([]byte, 8)
|
||||
ReadFull(buf, r, n, err)
|
||||
return uint64(binary.LittleEndian.Uint64(buf))
|
||||
}
|
||||
|
||||
// VarInt
|
||||
// Varint
|
||||
|
||||
func WriteVarInt(i int, w io.Writer, n *int64, err *error) {
|
||||
func WriteVarint(i int, w io.Writer, n *int64, err *error) {
|
||||
buf := make([]byte, 9)
|
||||
n_ := int64(binary.PutVarint(buf, int64(i)))
|
||||
*n += n_
|
||||
WriteTo(buf[:n_], w, n, err)
|
||||
}
|
||||
|
||||
func ReadVarInt(r io.Reader, n *int64, err *error) int {
|
||||
func ReadVarint(r io.Reader, n *int64, err *error) int {
|
||||
res, n_, err_ := readVarint(r)
|
||||
*n += n_
|
||||
*err = err_
|
||||
return int(res)
|
||||
}
|
||||
|
||||
// UVarInt
|
||||
// Uvarint
|
||||
|
||||
func WriteUVarInt(i uint, w io.Writer, n *int64, err *error) {
|
||||
func WriteUvarint(i uint, w io.Writer, n *int64, err *error) {
|
||||
buf := make([]byte, 9)
|
||||
n_ := int64(binary.PutUvarint(buf, uint64(i)))
|
||||
*n += n_
|
||||
WriteTo(buf[:n_], w, n, err)
|
||||
}
|
||||
|
||||
func ReadUVarInt(r io.Reader, n *int64, err *error) uint {
|
||||
func ReadUvarint(r io.Reader, n *int64, err *error) uint {
|
||||
res, n_, err_ := readUvarint(r)
|
||||
*n += n_
|
||||
*err = err_
|
||||
|
@ -105,7 +105,7 @@ func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err *
|
||||
rv.Set(reflect.ValueOf(byteslice))
|
||||
} else {
|
||||
// Read length
|
||||
length := int(ReadUVarInt(r, n, err))
|
||||
length := int(ReadUvarint(r, n, err))
|
||||
sliceRv := reflect.MakeSlice(rt, length, length)
|
||||
// Read elems
|
||||
for i := 0; i < length; i++ {
|
||||
@ -131,43 +131,43 @@ func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err *
|
||||
rv.SetString(str)
|
||||
|
||||
case reflect.Int64:
|
||||
num := ReadUInt64(r, n, err)
|
||||
num := ReadUint64(r, n, err)
|
||||
rv.SetInt(int64(num))
|
||||
|
||||
case reflect.Int32:
|
||||
num := ReadUInt32(r, n, err)
|
||||
num := ReadUint32(r, n, err)
|
||||
rv.SetInt(int64(num))
|
||||
|
||||
case reflect.Int16:
|
||||
num := ReadUInt16(r, n, err)
|
||||
num := ReadUint16(r, n, err)
|
||||
rv.SetInt(int64(num))
|
||||
|
||||
case reflect.Int8:
|
||||
num := ReadUInt8(r, n, err)
|
||||
num := ReadUint8(r, n, err)
|
||||
rv.SetInt(int64(num))
|
||||
|
||||
case reflect.Int:
|
||||
num := ReadUVarInt(r, n, err)
|
||||
num := ReadUvarint(r, n, err)
|
||||
rv.SetInt(int64(num))
|
||||
|
||||
case reflect.Uint64:
|
||||
num := ReadUInt64(r, n, err)
|
||||
num := ReadUint64(r, n, err)
|
||||
rv.SetUint(uint64(num))
|
||||
|
||||
case reflect.Uint32:
|
||||
num := ReadUInt32(r, n, err)
|
||||
num := ReadUint32(r, n, err)
|
||||
rv.SetUint(uint64(num))
|
||||
|
||||
case reflect.Uint16:
|
||||
num := ReadUInt16(r, n, err)
|
||||
num := ReadUint16(r, n, err)
|
||||
rv.SetUint(uint64(num))
|
||||
|
||||
case reflect.Uint8:
|
||||
num := ReadUInt8(r, n, err)
|
||||
num := ReadUint8(r, n, err)
|
||||
rv.SetUint(uint64(num))
|
||||
|
||||
case reflect.Uint:
|
||||
num := ReadUVarInt(r, n, err)
|
||||
num := ReadUvarint(r, n, err)
|
||||
rv.SetUint(uint64(num))
|
||||
|
||||
default:
|
||||
@ -220,7 +220,7 @@ func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err
|
||||
} else {
|
||||
// Write length
|
||||
length := rv.Len()
|
||||
WriteUVarInt(uint(length), w, n, err)
|
||||
WriteUvarint(uint(length), w, n, err)
|
||||
// Write elems
|
||||
for i := 0; i < length; i++ {
|
||||
elemRv := rv.Index(i)
|
||||
@ -255,22 +255,22 @@ func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err
|
||||
WriteInt8(int8(rv.Int()), w, n, err)
|
||||
|
||||
case reflect.Int:
|
||||
WriteVarInt(int(rv.Int()), w, n, err)
|
||||
WriteVarint(int(rv.Int()), w, n, err)
|
||||
|
||||
case reflect.Uint64:
|
||||
WriteUInt64(rv.Uint(), w, n, err)
|
||||
WriteUint64(rv.Uint(), w, n, err)
|
||||
|
||||
case reflect.Uint32:
|
||||
WriteUInt32(uint32(rv.Uint()), w, n, err)
|
||||
WriteUint32(uint32(rv.Uint()), w, n, err)
|
||||
|
||||
case reflect.Uint16:
|
||||
WriteUInt16(uint16(rv.Uint()), w, n, err)
|
||||
WriteUint16(uint16(rv.Uint()), w, n, err)
|
||||
|
||||
case reflect.Uint8:
|
||||
WriteUInt8(uint8(rv.Uint()), w, n, err)
|
||||
WriteUint8(uint8(rv.Uint()), w, n, err)
|
||||
|
||||
case reflect.Uint:
|
||||
WriteUVarInt(uint(rv.Uint()), w, n, err)
|
||||
WriteUvarint(uint(rv.Uint()), w, n, err)
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("Unknown field type %v", rt.Kind()))
|
||||
|
@ -5,12 +5,12 @@ import "io"
|
||||
// String
|
||||
|
||||
func WriteString(s string, w io.Writer, n *int64, err *error) {
|
||||
WriteUInt32(uint32(len(s)), w, n, err)
|
||||
WriteUvarint(uint(len(s)), w, n, err)
|
||||
WriteTo([]byte(s), w, n, err)
|
||||
}
|
||||
|
||||
func ReadString(r io.Reader, n *int64, err *error) string {
|
||||
length := ReadUInt32(r, n, err)
|
||||
length := ReadUvarint(r, n, err)
|
||||
if *err != nil {
|
||||
return ""
|
||||
}
|
||||
|
Reference in New Issue
Block a user