msgpack/slice.go

286 lines
4.9 KiB
Go

package msgpack
import (
"fmt"
"io"
"reflect"
"github.com/vmihailenco/bufio"
)
func (e *Encoder) encodeBytesLen(l int) error {
switch {
case l < 32:
if err := e.W.WriteByte(fixRawLowCode | uint8(l)); err != nil {
return err
}
case l < 65536:
if err := e.write([]byte{
raw16Code,
byte(l >> 8),
byte(l),
}); err != nil {
return err
}
default:
if err := e.write([]byte{
raw32Code,
byte(l >> 24),
byte(l >> 16),
byte(l >> 8),
byte(l),
}); err != nil {
return err
}
}
return nil
}
func (e *Encoder) EncodeString(v string) error {
if err := e.encodeBytesLen(len(v)); err != nil {
return err
}
return e.writeString(v)
}
func (e *Encoder) EncodeBytes(v []byte) error {
if v == nil {
return e.EncodeNil()
}
if err := e.encodeBytesLen(len(v)); err != nil {
return err
}
return e.write(v)
}
func (e *Encoder) encodeSliceLen(l int) error {
switch {
case l < 16:
if err := e.W.WriteByte(fixArrayLowCode | byte(l)); err != nil {
return err
}
case l < 65536:
if err := e.write([]byte{array16Code, byte(l >> 8), byte(l)}); err != nil {
return err
}
default:
if err := e.write([]byte{
array32Code,
byte(l >> 24),
byte(l >> 16),
byte(l >> 8),
byte(l),
}); err != nil {
return err
}
}
return nil
}
func (e *Encoder) encodeStringSlice(s []string) error {
if s == nil {
return e.EncodeNil()
}
if err := e.encodeSliceLen(len(s)); err != nil {
return err
}
for _, v := range s {
if err := e.EncodeString(v); err != nil {
return err
}
}
return nil
}
func (e *Encoder) encodeSlice(v reflect.Value) error {
switch v.Type().Elem().Kind() {
case reflect.Uint8:
return e.EncodeBytes(v.Bytes())
}
l := v.Len()
if err := e.encodeSliceLen(l); err != nil {
return err
}
for i := 0; i < l; i++ {
if err := e.EncodeValue(v.Index(i)); err != nil {
return err
}
}
return nil
}
func (d *Decoder) DecodeBytesLen() (int, error) {
c, err := d.R.ReadByte()
if err != nil {
return 0, err
}
if c == nilCode {
return -1, nil
} else if c >= fixRawLowCode && c <= fixRawHighCode {
return int(c & fixRawMask), nil
}
switch c {
case raw16Code:
n, err := d.uint16()
return int(n), err
case raw32Code:
n, err := d.uint32()
return int(n), err
}
return 0, fmt.Errorf("msgpack: invalid code %x decoding bytes length", c)
}
func (d *Decoder) DecodeBytes() ([]byte, error) {
n, err := d.DecodeBytesLen()
if err != nil {
return nil, err
}
if n == -1 {
return nil, nil
}
b := make([]byte, n)
_, err = io.ReadFull(d.R, b)
if err != nil {
return nil, err
}
return b, nil
}
func (d *Decoder) bytesValue(value reflect.Value) error {
v, err := d.DecodeBytes()
if err != nil {
return err
}
value.SetBytes(v)
return nil
}
func (d *Decoder) DecodeString() (string, error) {
n, err := d.DecodeBytesLen()
if err != nil {
return "", err
}
if n == -1 {
return "", nil
}
b, err := d.R.ReadN(n)
if err == bufio.ErrBufferFull {
newB := make([]byte, n)
n := copy(newB, b)
b = newB
_, err := io.ReadFull(d.R, newB[n:])
if err != nil {
return "", err
}
} else if err != nil {
return "", err
}
return string(b), nil
}
func (d *Decoder) stringValue(value reflect.Value) error {
v, err := d.DecodeString()
if err != nil {
return err
}
value.SetString(v)
return nil
}
func (d *Decoder) DecodeSliceLen() (int, error) {
c, err := d.R.ReadByte()
if err != nil {
return 0, err
}
if c == nilCode {
return -1, nil
} else if c >= fixArrayLowCode && c <= fixArrayHighCode {
return int(c & fixArrayMask), nil
}
switch c {
case array16Code:
n, err := d.uint16()
return int(n), err
case array32Code:
n, err := d.uint32()
return int(n), err
}
return 0, fmt.Errorf("msgpack: invalid code %x decoding array length", c)
}
func (d *Decoder) decodeIntoStrings(sp *[]string) error {
n, err := d.DecodeSliceLen()
if err != nil {
return err
}
if n == -1 {
return nil
}
s := *sp
if s == nil || len(s) < n {
s = make([]string, n)
}
for i := 0; i < n; i++ {
v, err := d.DecodeString()
if err != nil {
return err
}
s[i] = v
}
*sp = s
return nil
}
func (d *Decoder) DecodeSlice() ([]interface{}, error) {
n, err := d.DecodeSliceLen()
if err != nil {
return nil, err
}
if n == -1 {
return nil, nil
}
s := make([]interface{}, n)
for i := 0; i < n; i++ {
v, err := d.DecodeInterface()
if err != nil {
return nil, err
}
s[i] = v
}
return s, nil
}
func (d *Decoder) sliceValue(v reflect.Value) error {
elemType := v.Type().Elem()
switch elemType.Kind() {
case reflect.Uint8:
b, err := d.DecodeBytes()
if err != nil {
return err
}
v.SetBytes(b)
return nil
}
n, err := d.DecodeSliceLen()
if err != nil {
return err
}
if v.Len() < n || (v.Kind() == reflect.Slice && v.IsNil()) {
v.Set(reflect.MakeSlice(v.Type(), n, n))
}
for i := 0; i < n; i++ {
sv := v.Index(i)
if err := d.DecodeValue(sv); err != nil {
return err
}
}
return nil
}