Skip to content
This repository has been archived by the owner on May 8, 2019. It is now read-only.

Commit

Permalink
cleanups and test improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
dchenk committed Apr 15, 2018
1 parent e7dcf5d commit 1a96793
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 108 deletions.
5 changes: 2 additions & 3 deletions msgp/number.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import (
// It can decode itself from any of the native MessagePack number types.
// The zero-value of Number is Int(0).
type Number struct {
// Internally, this is just a tagged union.
// The raw bits of the number are stored the
// same way regardless.
// Internally, this is just a tagged union. The raw bits of
// the number are stored the same way regardless.
bits uint64
typ Type
}
Expand Down
84 changes: 17 additions & 67 deletions msgp/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ func (mw *Writer) WriteBool(b bool) error {
return mw.push(mfalse)
}

// WriteString writes a messagepack string to the writer.
// WriteString writes a MessagePack string to the writer.
// (This is NOT an implementation of io.StringWriter)
func (mw *Writer) WriteString(s string) error {
sz := uint32(len(s))
Expand Down Expand Up @@ -446,8 +446,7 @@ func (mw *Writer) WriteStringHeader(sz uint32) error {
}
}

// WriteStringFromBytes writes a 'str' object
// from a []byte.
// WriteStringFromBytes writes a 'str' object from a []byte.
func (mw *Writer) WriteStringFromBytes(str []byte) error {
sz := uint32(len(str))
var err error
Expand Down Expand Up @@ -553,8 +552,8 @@ func (mw *Writer) WriteTime(t time.Time) error {
return nil
}

// WriteIntf writes the concrete type of 'v'.
// WriteIntf will error if 'v' is not one of the following:
// WriteIntf writes the concrete type of v.
// WriteIntf will error if v is not one of the following:
// - A bool, float, string, []byte, int, uint, or complex
// - A map of supported types (with string keys)
// - An array or slice of supported types
Expand Down Expand Up @@ -637,47 +636,45 @@ func (mw *Writer) WriteIntf(v interface{}) error {
return &ErrUnsupportedType{val.Type()}
}

func (mw *Writer) writeMap(v reflect.Value) (err error) {
func (mw *Writer) writeMap(v reflect.Value) error {
if v.Type().Key().Kind() != reflect.String {
return errors.New("msgp: map keys must be strings")
}
ks := v.MapKeys()
err = mw.WriteMapHeader(uint32(len(ks)))
err := mw.WriteMapHeader(uint32(len(ks)))
if err != nil {
return
return err
}
for _, key := range ks {
val := v.MapIndex(key)
err = mw.WriteString(key.String())
if err != nil {
return
return err
}
err = mw.WriteIntf(val.Interface())
if err != nil {
return
return err
}
}
return
return nil
}

func (mw *Writer) writeSlice(v reflect.Value) (err error) {
// is []byte
if v.Type().ConvertibleTo(btsType) {
func (mw *Writer) writeSlice(v reflect.Value) error {
if v.Type().ConvertibleTo(btsType) { // is []byte
return mw.WriteBytes(v.Bytes())
}

sz := uint32(v.Len())
err = mw.WriteArrayHeader(sz)
err := mw.WriteArrayHeader(sz)
if err != nil {
return
return err
}
for i := uint32(0); i < sz; i++ {
err = mw.WriteIntf(v.Index(int(i)).Interface())
if err != nil {
return
return err
}
}
return
return nil
}

func (mw *Writer) writeStruct(v reflect.Value) error {
Expand All @@ -687,56 +684,9 @@ func (mw *Writer) writeStruct(v reflect.Value) error {
return fmt.Errorf("msgp: unsupported type: %s", v.Type())
}

func (mw *Writer) writeVal(v reflect.Value) error {

if !isSupported(v.Kind()) {
return fmt.Errorf("msgp: msgp/enc: type %q not supported", v.Type())
}

// shortcut for nil values
if v.IsNil() {
return mw.WriteNil()
}

switch v.Kind() {
case reflect.Bool:
return mw.WriteBool(v.Bool())

case reflect.Float32, reflect.Float64:
return mw.WriteFloat64(v.Float())
case reflect.Complex64, reflect.Complex128:
return mw.WriteComplex128(v.Complex())
case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int8:
return mw.WriteInt64(v.Int())
case reflect.Interface, reflect.Ptr:
if v.IsNil() {
mw.WriteNil()
}
return mw.writeVal(v.Elem())
case reflect.Map:
return mw.writeMap(v)
case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint8:
return mw.WriteUint64(v.Uint())
case reflect.String:
return mw.WriteString(v.String())
case reflect.Slice, reflect.Array:
return mw.writeSlice(v)
case reflect.Struct:
return mw.writeStruct(v)
}

return fmt.Errorf("msgp: msgp/enc: type %q not supported", v.Type())

}

// isSupported says if k is encodable.
func isSupported(k reflect.Kind) bool {
switch k {
case reflect.Func, reflect.Chan, reflect.Invalid, reflect.UnsafePointer:
return false
default:
return true
}
return k != reflect.Func && k != reflect.Chan && k != reflect.Invalid && k != reflect.UnsafePointer
}

// GuessSize guesses the size of the underlying value of 'i'. If the underlying value is not
Expand Down
15 changes: 6 additions & 9 deletions msgp/write_bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,17 @@ func ensure(b []byte, sz int) ([]byte, int) {

// AppendMapHeader appends a map header with the given size to b.
func AppendMapHeader(b []byte, sz uint32) []byte {
switch {
case sz <= 15:
if sz <= 15 {
return append(b, wfixmap(uint8(sz)))

case sz <= math.MaxUint16:
}
if sz <= math.MaxUint16 {
o, n := ensure(b, 3)
prefixu16(o[n:], mmap16, uint16(sz))
return o

default:
o, n := ensure(b, 5)
prefixu32(o[n:], mmap32, sz)
return o
}
o, n := ensure(b, 5)
prefixu32(o[n:], mmap32, sz)
return o
}

// AppendArrayHeader appends an array header with the given size to b.
Expand Down
2 changes: 1 addition & 1 deletion msgp/write_bytes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ func TestIssue116(t *testing.T) {
}

var buf bytes.Buffer

w := NewWriter(&buf)

w.WriteInt64(math.MinInt64)
w.Flush()
i, err = NewReader(&buf).ReadInt64()
Expand Down
64 changes: 36 additions & 28 deletions msgp/write_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ func RandBytes(sz int) []byte {
}

func TestWriteMapHeader(t *testing.T) {

tests := []struct {
Sz uint32
Outbytes []byte
Sz uint32
Out []byte
}{
{0, []byte{mfixmap}},
{1, []byte{mfixmap | byte(1)}},
Expand All @@ -45,22 +46,23 @@ func TestWriteMapHeader(t *testing.T) {
}

var buf bytes.Buffer
var err error
wr := NewWriter(&buf)
for _, test := range tests {

for i, test := range tests {
buf.Reset()
err = wr.WriteMapHeader(test.Sz)
err := wr.WriteMapHeader(test.Sz)
if err != nil {
t.Error(err)
}
err = wr.Flush()
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(buf.Bytes(), test.Outbytes) {
t.Errorf("Expected bytes %x; got %x", test.Outbytes, buf.Bytes())
if !bytes.Equal(buf.Bytes(), test.Out) {
t.Errorf("(case %d) expected bytes %x; got %x", i, test.Out, buf.Bytes())
}
}

}

func BenchmarkWriteMapHeader(b *testing.B) {
Expand All @@ -77,9 +79,10 @@ func BenchmarkWriteMapHeader(b *testing.B) {
}

func TestWriteArrayHeader(t *testing.T) {

tests := []struct {
Sz uint32
Outbytes []byte
Sz uint32
Out []byte
}{
{0, []byte{mfixarray}},
{1, []byte{mfixarray | byte(1)}},
Expand All @@ -88,74 +91,79 @@ func TestWriteArrayHeader(t *testing.T) {
}

var buf bytes.Buffer
var err error
wr := NewWriter(&buf)
for _, test := range tests {

for i, test := range tests {
buf.Reset()
err = wr.WriteArrayHeader(test.Sz)
err := wr.WriteArrayHeader(test.Sz)
if err != nil {
t.Error(err)
}
err = wr.Flush()
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(buf.Bytes(), test.Outbytes) {
t.Errorf("Expected bytes %x; got %x", test.Outbytes, buf.Bytes())
if !bytes.Equal(buf.Bytes(), test.Out) {
t.Errorf("(case %d) expected bytes %x; got %x", i, test.Out, buf.Bytes())
}
}

}

func TestReadWriteStringHeader(t *testing.T) {

sizes := []uint32{0, 5, 8, 19, 150, tuint16, tuint32}

var buf bytes.Buffer
var err error
wr := NewWriter(&buf)
for _, sz := range sizes {

for i, sz := range sizes {
buf.Reset()
err = wr.WriteStringHeader(sz)
err := wr.WriteStringHeader(sz)
if err != nil {
t.Fatal(err)
}
err = wr.Flush()
if err != nil {
t.Fatal(err)
}
var nsz uint32
nsz, err = NewReader(&buf).ReadStringHeader()
nsz, err := NewReader(&buf).ReadStringHeader()
if err != nil {
t.Fatal(err)
}
if nsz != sz {
t.Errorf("put in size %d but got out size %d", sz, nsz)
t.Errorf("(case %d) put in size %d but got out size %d", i, sz, nsz)
}
}

}

func TestReadWriteBytesHeader(t *testing.T) {

sizes := []uint32{0, 5, 8, 19, 150, tuint16, tuint32}

var buf bytes.Buffer
var err error
wr := NewWriter(&buf)
for _, sz := range sizes {

for i, sz := range sizes {
buf.Reset()
err = wr.WriteBytesHeader(sz)
err := wr.WriteBytesHeader(sz)
if err != nil {
t.Fatal(err)
}
err = wr.Flush()
if err != nil {
t.Fatal(err)
}
var nsz uint32
nsz, err = NewReader(&buf).ReadBytesHeader()
nsz, err := NewReader(&buf).ReadBytesHeader()
if err != nil {
t.Fatal(err)
}
if nsz != sz {
t.Errorf("put in size %d but got out size %d", sz, nsz)
t.Errorf("(case %d) put in size %d but got out size %d", i, sz, nsz)
}
}

}

func BenchmarkWriteArrayHeader(b *testing.B) {
Expand Down Expand Up @@ -193,7 +201,7 @@ func TestWriteNil(t *testing.T) {
func TestWriteFloat64(t *testing.T) {
var buf bytes.Buffer
wr := NewWriter(&buf)

rand.Seed(time.Now().Unix())
for i := 0; i < 10000; i++ {
buf.Reset()
flt := (rand.Float64() - 0.5) * math.MaxFloat64
Expand Down Expand Up @@ -279,7 +287,7 @@ func TestWriteInt64(t *testing.T) {
}

if buf.Len() > 9 {
t.Errorf("buffer length should be <= 9; it's %d", buf.Len())
t.Errorf("buffer length should be <= 9 but is %d", buf.Len())
}
}
}
Expand Down

0 comments on commit 1a96793

Please sign in to comment.