blob: 1d98ab140c5183c9c9bb66dbaa4428e6c2fa684b [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package vom
import (
"fmt"
"math"
"reflect"
"strings"
"testing"
)
func TestBinaryEncodeDecode(t *testing.T) {
tests := []struct {
v interface{}
hex string
}{
{false, "00"},
{true, "01"},
{byte(0x80), "80"},
{byte(0xbf), "bf"},
{byte(0xc0), "c0"},
{byte(0xdf), "df"},
{byte(0xe0), "e0"},
{byte(0xef), "ef"},
{uint64(0), "00"},
{uint64(1), "01"},
{uint64(2), "02"},
{uint64(127), "7f"},
{uint64(128), "ff80"},
{uint64(255), "ffff"},
{uint64(256), "fe0100"},
{uint64(257), "fe0101"},
{uint64(0xffff), "feffff"},
{uint64(0xffffff), "fdffffff"},
{uint64(0xffffffff), "fcffffffff"},
{uint64(0xffffffffff), "fbffffffffff"},
{uint64(0xffffffffffff), "faffffffffffff"},
{uint64(0xffffffffffffff), "f9ffffffffffffff"},
{uint64(0xffffffffffffffff), "f8ffffffffffffffff"},
{int64(0), "00"},
{int64(1), "02"},
{int64(2), "04"},
{int64(63), "7e"},
{int64(64), "ff80"},
{int64(65), "ff82"},
{int64(127), "fffe"},
{int64(128), "fe0100"},
{int64(129), "fe0102"},
{int64(math.MaxInt16), "fefffe"},
{int64(math.MaxInt32), "fcfffffffe"},
{int64(math.MaxInt64), "f8fffffffffffffffe"},
{int64(-1), "01"},
{int64(-2), "03"},
{int64(-64), "7f"},
{int64(-65), "ff81"},
{int64(-66), "ff83"},
{int64(-128), "ffff"},
{int64(-129), "fe0101"},
{int64(-130), "fe0103"},
{int64(math.MinInt16), "feffff"},
{int64(math.MinInt32), "fcffffffff"},
{int64(math.MinInt64), "f8ffffffffffffffff"},
{float64(0), "00"},
{float64(1), "fef03f"},
{float64(17), "fe3140"},
{float64(18), "fe3240"},
{"", "00"},
{"abc", "03616263"},
{"defghi", "06646566676869"},
}
for _, test := range tests {
// Test encode
encbuf := newEncbuf()
var buf []byte
switch val := test.v.(type) {
case byte:
binaryEncodeControl(encbuf, val)
case bool:
binaryEncodeBool(encbuf, val)
case uint64:
binaryEncodeUint(encbuf, val)
buf = make([]byte, maxEncodedUintBytes)
buf = buf[binaryEncodeUintEnd(buf, val):]
case int64:
binaryEncodeInt(encbuf, val)
buf = make([]byte, maxEncodedUintBytes)
buf = buf[binaryEncodeIntEnd(buf, val):]
case float64:
binaryEncodeFloat(encbuf, val)
case string:
binaryEncodeString(encbuf, val)
}
if got, want := fmt.Sprintf("%x", encbuf.Bytes()), test.hex; got != want {
t.Errorf("binary encode %T(%v): GOT 0x%v WANT 0x%v", test.v, test.v, got, want)
}
if buf != nil {
if got, want := fmt.Sprintf("%x", buf), test.hex; got != want {
t.Errorf("binary encode end %T(%v): GOT 0x%v WANT 0x%v", test.v, test.v, got, want)
}
}
// Test decode
var bin string
if _, err := fmt.Sscanf(test.hex, "%x", &bin); err != nil {
t.Errorf("couldn't scan 0x%v as hex: %v", test.hex, err)
continue
}
// TODO(toddw): Add peek tests.
decbuf := newDecbuf(strings.NewReader(bin))
decbufSkip := newDecbuf(strings.NewReader(bin))
var v interface{}
var err, errSkip error
switch tv := test.v.(type) {
case byte:
v = test.v
var match bool
if match, err = binaryDecodeControlOnly(decbuf, tv); !match {
err = fmt.Errorf("non control byte")
}
errSkip = decbufSkip.Skip(1)
case bool:
v, err = binaryDecodeBool(decbuf)
errSkip = binarySkipUint(decbufSkip)
case uint64:
v, err = binaryDecodeUint(decbuf)
errSkip = binarySkipUint(decbufSkip)
case int64:
v, err = binaryDecodeInt(decbuf)
errSkip = binarySkipUint(decbufSkip)
case float64:
v, err = binaryDecodeFloat(decbuf)
errSkip = binarySkipUint(decbufSkip)
case string:
v, err = binaryDecodeString(decbuf)
errSkip = binarySkipString(decbufSkip)
}
// Check decode results
if err != nil {
t.Errorf("binary decode %T(0x%v): %v", test.v, test.hex, err)
continue
}
if !reflect.DeepEqual(v, test.v) {
t.Errorf("binary decode %T(0x%v): got %v, want %v", test.v, test.hex, v, test.v)
continue
}
if err := decbuf.Fill(1); err == nil {
t.Errorf("binary decode %T(0x%v): leftover bytes", test.v, test.hex)
continue
}
// Check skip results
if errSkip != nil {
t.Errorf("binary skip %T(0x%v): %v", test.v, test.hex, errSkip)
continue
}
if err := decbufSkip.Fill(1); err == nil {
t.Errorf("binary skip %T(0x%v): leftover bytes", test.v, test.hex)
continue
}
}
}