adding float and double as types with name and size tests (#51)

add translate to type cases

replace float compare by Nextafter and Nextafter32

add parser for floats and doubles

add float and double parsers

add support for doubles and floats in FormatFrom functions

add ReadFloats and ReadDoubles for context

add float32 and double encoder

merging

merge

add float and double parsers

add ReadFloats and ReadDoubles for context

add float32 and double encoder

removing log alias from parser

removing log alias from parser_test

removing log alias from type

removing log alias from type_test

removing log alias from value_context

removing aliases from value_contex_test

removing log alias from value_encoder

removing log alias from value_encoder_test

update parser slices from floats and doubles

merge

update values for tests

raise exception when parsing with different expected size
pull/52/head
Wendel Hime 2020-12-09 03:40:27 -03:00 committed by GitHub
parent b3f4f3b4b7
commit 325de3c5bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 520 additions and 57 deletions

View File

@ -2,6 +2,7 @@ package exifcommon
import (
"bytes"
"math"
"encoding/binary"
@ -135,6 +136,50 @@ func (p *Parser) ParseLongs(data []byte, unitCount uint32, byteOrder binary.Byte
return value, nil
}
// ParseFloats knows how to encode an encoded list of floats.
func (p *Parser) ParseFloats(data []byte, unitCount uint32, byteOrder binary.ByteOrder) (value []float32, err error) {
defer func() {
if state := recover(); state != nil {
err = log.Wrap(state.(error))
}
}()
count := int(unitCount)
if len(data) != (TypeFloat.Size() * count) {
log.Panic(ErrNotEnoughData)
}
value = make([]float32, count)
for i := 0; i < count; i++ {
value[i] = math.Float32frombits(byteOrder.Uint32(data[i*4 : (i+1)*4]))
}
return value, nil
}
// ParseDoubles knows how to encode an encoded list of doubles.
func (p *Parser) ParseDoubles(data []byte, unitCount uint32, byteOrder binary.ByteOrder) (value []float64, err error) {
defer func() {
if state := recover(); state != nil {
err = log.Wrap(state.(error))
}
}()
count := int(unitCount)
if len(data) != (TypeDouble.Size() * count) {
log.Panic(ErrNotEnoughData)
}
value = make([]float64, count)
for i := 0; i < count; i++ {
value[i] = math.Float64frombits(byteOrder.Uint64(data[i*8 : (i+1)*8]))
}
return value, nil
}
// ParseRationals knows how to parse an encoded list of unsigned rationals.
func (p *Parser) ParseRationals(data []byte, unitCount uint32, byteOrder binary.ByteOrder) (value []Rational, err error) {
defer func() {

View File

@ -2,6 +2,7 @@ package exifcommon
import (
"bytes"
"math"
"reflect"
"testing"
@ -170,6 +171,78 @@ func TestParser_ParseLongs__Multiple(t *testing.T) {
}
}
func TestParser_ParseFloats__Single(t *testing.T) {
p := new(Parser)
encoded := []byte{0x40, 0x49, 0x0f, 0xdb}
value, err := p.ParseFloats(encoded, 1, TestDefaultByteOrder)
log.PanicIf(err)
expectedResult := []float32{3.14159265}
for i, v := range value {
if v < expectedResult[i] ||
v >= math.Nextafter32(expectedResult[i], expectedResult[i]+1) {
t.Fatalf("Encoding not correct (1): %v", value)
}
}
}
func TestParser_ParseFloats__Multiple(t *testing.T) {
p := new(Parser)
encoded := []byte{0x40, 0x49, 0x0f, 0xdb, 0x40, 0x2d, 0xf8, 0x54}
value, err := p.ParseFloats(encoded, 2, TestDefaultByteOrder)
log.PanicIf(err)
expectedResult := []float32{3.14159265, 2.71828182}
for i, v := range value {
if v < expectedResult[i] ||
v >= math.Nextafter32(expectedResult[i], expectedResult[i]+1) {
t.Fatalf("Encoding not correct (1): %v", value)
}
}
}
func TestParser_ParseDoubles__Single(t *testing.T) {
p := new(Parser)
encoded := []byte{0x40, 0x09, 0x21, 0xfb, 0x53, 0xc8, 0xd4, 0xf1}
value, err := p.ParseDoubles(encoded, 1, TestDefaultByteOrder)
log.PanicIf(err)
expectedResult := []float64{3.14159265}
for i, v := range value {
if v < expectedResult[i] ||
v >= math.Nextafter(expectedResult[i], expectedResult[i]+1) {
t.Fatalf("Encoding not correct (1): %v", value)
}
}
}
func TestParser_ParseDoubles__Multiple(t *testing.T) {
p := new(Parser)
encoded := []byte{0x40, 0x09, 0x21, 0xfb, 0x53, 0xc8, 0xd4, 0xf1,
0x40, 0x05, 0xbf, 0x0a, 0x89, 0xf1, 0xb0, 0xdd}
value, err := p.ParseDoubles(encoded, 2, TestDefaultByteOrder)
log.PanicIf(err)
expectedResult := []float64{3.14159265, 2.71828182}
for i, v := range value {
if v < expectedResult[i] ||
v >= math.Nextafter(expectedResult[i], expectedResult[i]+1) {
t.Fatalf("Encoding not correct: %v", value)
}
}
}
func TestParser_ParseRationals__Single(t *testing.T) {
p := new(Parser)

View File

@ -64,6 +64,12 @@ const (
// TypeSignedRational describes an encoded list of signed rationals.
TypeSignedRational TagTypePrimitive = 10
// TypeFloat describes an encoded list of floats
TypeFloat TagTypePrimitive = 11
// TypeDouble describes an encoded list of doubles.
TypeDouble TagTypePrimitive = 12
// TypeAsciiNoNul is just a pseudo-type, for our own purposes.
TypeAsciiNoNul TagTypePrimitive = 0xf0
)
@ -75,23 +81,19 @@ func (typeType TagTypePrimitive) String() string {
// Size returns the size of one atomic unit of the type.
func (tagType TagTypePrimitive) Size() int {
if tagType == TypeByte {
switch tagType {
case TypeByte, TypeAscii, TypeAsciiNoNul:
return 1
} else if tagType == TypeAscii || tagType == TypeAsciiNoNul {
return 1
} else if tagType == TypeShort {
case TypeShort:
return 2
} else if tagType == TypeLong {
case TypeLong, TypeSignedLong, TypeFloat:
return 4
} else if tagType == TypeRational {
case TypeRational, TypeSignedRational, TypeDouble:
return 8
} else if tagType == TypeSignedLong {
return 4
} else if tagType == TypeSignedRational {
return 8
} else {
log.Panicf("can not determine tag-value size for type (%d): [%s]", tagType, TypeNames[tagType])
default:
log.Panicf("can not determine tag-value size for type (%d): [%s]",
tagType,
TypeNames[tagType])
// Never called.
return 0
}
@ -110,6 +112,8 @@ func (tagType TagTypePrimitive) IsValid() bool {
tagType == TypeRational ||
tagType == TypeSignedLong ||
tagType == TypeSignedRational ||
tagType == TypeFloat ||
tagType == TypeDouble ||
tagType == TypeUndefined
}
@ -124,6 +128,8 @@ var (
TypeUndefined: "UNDEFINED",
TypeSignedLong: "SLONG",
TypeSignedRational: "SRATIONAL",
TypeFloat: "FLOAT",
TypeDouble: "DOUBLE",
TypeAsciiNoNul: "_ASCII_NO_NUL",
}
@ -186,36 +192,23 @@ func FormatFromType(value interface{}, justFirst bool) (phrase string, err error
}
return t, nil
case []uint16:
if len(t) == 0 {
case []uint16, []uint32, []int32, []float64, []float32:
val := reflect.ValueOf(t)
if val.Len() == 0 {
return "", nil
}
if justFirst == true {
var valueSuffix string
if len(t) > 1 {
if val.Len() > 1 {
valueSuffix = "..."
}
return fmt.Sprintf("%v%s", t[0], valueSuffix), nil
return fmt.Sprintf("%v%s", val.Index(0), valueSuffix), nil
}
return fmt.Sprintf("%v", t), nil
case []uint32:
if len(t) == 0 {
return "", nil
}
if justFirst == true {
var valueSuffix string
if len(t) > 1 {
valueSuffix = "..."
}
return fmt.Sprintf("%v%s", t[0], valueSuffix), nil
}
return fmt.Sprintf("%v", t), nil
return fmt.Sprintf("%v", val), nil
case []Rational:
if len(t) == 0 {
return "", nil
@ -240,21 +233,6 @@ func FormatFromType(value interface{}, justFirst bool) (phrase string, err error
}
return fmt.Sprintf("%v", parts), nil
case []int32:
if len(t) == 0 {
return "", nil
}
if justFirst == true {
var valueSuffix string
if len(t) > 1 {
valueSuffix = "..."
}
return fmt.Sprintf("%v%s", t[0], valueSuffix), nil
}
return fmt.Sprintf("%v", t), nil
case []SignedRational:
if len(t) == 0 {
return "", nil
@ -348,6 +326,16 @@ func FormatFromBytes(rawBytes []byte, tagType TagTypePrimitive, justFirst bool,
value, err = parser.ParseLongs(rawBytes, unitCount, byteOrder)
log.PanicIf(err)
case TypeFloat:
var err error
value, err = parser.ParseFloats(rawBytes, unitCount, byteOrder)
log.PanicIf(err)
case TypeDouble:
var err error
value, err = parser.ParseDoubles(rawBytes, unitCount, byteOrder)
log.PanicIf(err)
case TypeRational:
var err error
@ -432,6 +420,16 @@ func TranslateStringToType(tagType TagTypePrimitive, valueString string) (value
log.PanicIf(err)
return int32(n), nil
} else if tagType == TypeFloat {
n, err := strconv.ParseFloat(valueString, 32)
log.PanicIf(err)
return float32(n), nil
} else if tagType == TypeDouble {
n, err := strconv.ParseFloat(valueString, 64)
log.PanicIf(err)
return float64(n), nil
} else if tagType == TypeSignedRational {
parts := strings.SplitN(valueString, "/", 2)

View File

@ -1,6 +1,7 @@
package exifcommon
import (
"math"
"testing"
"github.com/dsoprea/go-logging"
@ -54,6 +55,18 @@ func TestTypeSignedRational_String(t *testing.T) {
}
}
func TestTypeFloat_String(t *testing.T) {
if TypeFloat.String() != "FLOAT" {
t.Fatalf("Type name not correct (float): [%s]", TypeFloat.String())
}
}
func TestTypeDouble_String(t *testing.T) {
if TypeDouble.String() != "DOUBLE" {
t.Fatalf("Type name not correct (double): [%s]", TypeDouble.String())
}
}
func TestTypeByte_Size(t *testing.T) {
if TypeByte.Size() != 1 {
t.Fatalf("Type size not correct (byte): (%d)", TypeByte.Size())
@ -102,6 +115,18 @@ func TestTypeSignedRational_Size(t *testing.T) {
}
}
func TestTypeFloat_Size(t *testing.T) {
if TypeFloat.Size() != 4 {
t.Fatalf("Type size not correct (float): (%d)", TypeFloat.Size())
}
}
func TestTypeDouble_Size(t *testing.T) {
if TypeDouble.Size() != 8 {
t.Fatalf("Type size not correct (double): (%d)", TypeDouble.Size())
}
}
func TestFormat__Byte(t *testing.T) {
r := []byte{1, 2, 3, 4, 5, 6, 7, 8}
@ -157,6 +182,30 @@ func TestFormat__Long(t *testing.T) {
}
}
func TestFormat__Float(t *testing.T) {
r := []byte{0x3f, 0x80, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00}
s, err := FormatFromBytes(r, TypeFloat, false, TestDefaultByteOrder)
log.PanicIf(err)
if s != "[1 2]" {
t.Fatalf("Format output not correct (floats): [%s]", s)
}
}
func TestFormat__Double(t *testing.T) {
r := []byte{0x40, 0x09, 0x21, 0xfb, 0x53, 0xc8, 0xd4, 0xf1,
0x40, 0x05, 0xbf, 0x0a, 0x89, 0xf1, 0xb0, 0xdd}
s, err := FormatFromBytes(r, TypeDouble, false, TestDefaultByteOrder)
log.PanicIf(err)
if s != "[3.14159265 2.71828182]" {
t.Fatalf("Format output not correct (doubles): [%s]", s)
}
}
func TestFormat__Rational(t *testing.T) {
r := []byte{
0, 0, 0, 1, 0, 0, 0, 2,
@ -261,6 +310,26 @@ func TestTranslateStringToType__TypeLong(t *testing.T) {
}
}
func TestTranslateStringToType__TypeFloat(t *testing.T) {
v, err := TranslateStringToType(TypeFloat, "3.14159265")
log.PanicIf(err)
expected := float32(3.14159265)
if v.(float32) < expected || v.(float32) >= math.Nextafter32(expected, expected+1) {
t.Fatalf("Translation of string to type not correct (float32): %v", v)
}
}
func TestTranslateStringToType__TypeDouble(t *testing.T) {
v, err := TranslateStringToType(TypeDouble, "3.14159265")
log.PanicIf(err)
expected := float64(3.14159265)
if v.(float64) < expected || v.(float64) >= math.Nextafter(expected, expected+1) {
t.Fatalf("Translation of string to type not correct (double): %v", v)
}
}
func TestTranslateStringToType__TypeRational(t *testing.T) {
v, err := TranslateStringToType(TypeRational, "11/22")
log.PanicIf(err)

View File

@ -315,6 +315,40 @@ func (vc *ValueContext) ReadLongs() (value []uint32, err error) {
return value, nil
}
// ReadFloats parses the list of encoded, floats from the value-context.
func (vc *ValueContext) ReadFloats() (value []float32, err error) {
defer func() {
if state := recover(); state != nil {
err = log.Wrap(state.(error))
}
}()
rawValue, err := vc.readRawEncoded()
log.PanicIf(err)
value, err = parser.ParseFloats(rawValue, vc.unitCount, vc.byteOrder)
log.PanicIf(err)
return value, nil
}
// ReadDoubles parses the list of encoded, doubles from the value-context.
func (vc *ValueContext) ReadDoubles() (value []float64, err error) {
defer func() {
if state := recover(); state != nil {
err = log.Wrap(state.(error))
}
}()
rawValue, err := vc.readRawEncoded()
log.PanicIf(err)
value, err = parser.ParseDoubles(rawValue, vc.unitCount, vc.byteOrder)
log.PanicIf(err)
return value, nil
}
// ReadRationals parses the list of encoded, unsigned rationals from the value-
// context.
func (vc *ValueContext) ReadRationals() (value []Rational, err error) {

View File

@ -2,6 +2,7 @@ package exifcommon
import (
"bytes"
"math"
"reflect"
"testing"
@ -950,6 +951,72 @@ func TestValueContext_ReadLongs(t *testing.T) {
}
}
func TestValueContext_ReadFloats(t *testing.T) {
unitCount := uint32(2)
rawValueOffset := []byte{0, 0, 0, 4}
valueOffset := uint32(4)
data := []byte{0x40, 0x49, 0x0f, 0xdb, 0x40, 0x2d, 0xf8, 0x54}
addressableData := []byte{0, 0, 0, 0}
addressableData = append(addressableData, data...)
sb := rifs.NewSeekableBufferWithBytes(addressableData)
vc := NewValueContext(
"aa/bb",
0x1234,
unitCount,
valueOffset,
rawValueOffset,
sb,
TypeFloat,
TestDefaultByteOrder)
value, err := vc.ReadFloats()
log.PanicIf(err)
expectedResult := []float32{3.14159265, 2.71828182}
for i, v := range value {
if v < expectedResult[i] || v >= math.Nextafter32(expectedResult[i], expectedResult[i]+1) {
t.Fatalf("ReadFloats expecting %v, received %v", expectedResult[i], v)
}
}
}
func TestValueContext_ReadDoubles(t *testing.T) {
unitCount := uint32(2)
rawValueOffset := []byte{0, 0, 0, 4}
valueOffset := uint32(4)
data := []byte{0x40, 0x09, 0x21, 0xfb, 0x53, 0xc8, 0xd4, 0xf1,
0x40, 0x05, 0xbf, 0x0a, 0x89, 0xf1, 0xb0, 0xdd}
addressableData := []byte{0, 0, 0, 0}
addressableData = append(addressableData, data...)
sb := rifs.NewSeekableBufferWithBytes(addressableData)
vc := NewValueContext(
"aa/bb",
0x1234,
unitCount,
valueOffset,
rawValueOffset,
sb,
TypeDouble,
TestDefaultByteOrder)
value, err := vc.ReadDoubles()
log.PanicIf(err)
expectedResult := []float64{3.14159265, 2.71828182}
for i, v := range value {
if v < expectedResult[i] || v >= math.Nextafter(expectedResult[i], expectedResult[i]+1) {
t.Fatalf("ReadDoubles expecting %v, received %v", expectedResult[i], v)
}
}
}
func TestValueContext_ReadRationals(t *testing.T) {
unitCount := uint32(2)

View File

@ -2,6 +2,7 @@ package exifcommon
import (
"bytes"
"math"
"reflect"
"time"
@ -113,6 +114,44 @@ func (ve *ValueEncoder) encodeLongs(value []uint32) (ed EncodedData, err error)
return ed, nil
}
func (ve *ValueEncoder) encodeFloats(value []float32) (ed EncodedData, err error) {
defer func() {
if state := recover(); state != nil {
err = log.Wrap(state.(error))
}
}()
ed.UnitCount = uint32(len(value))
ed.Encoded = make([]byte, ed.UnitCount*4)
for i := uint32(0); i < ed.UnitCount; i++ {
ve.byteOrder.PutUint32(ed.Encoded[i*4:(i+1)*4], math.Float32bits(value[i]))
}
ed.Type = TypeFloat
return ed, nil
}
func (ve *ValueEncoder) encodeDoubles(value []float64) (ed EncodedData, err error) {
defer func() {
if state := recover(); state != nil {
err = log.Wrap(state.(error))
}
}()
ed.UnitCount = uint32(len(value))
ed.Encoded = make([]byte, ed.UnitCount*8)
for i := uint32(0); i < ed.UnitCount; i++ {
ve.byteOrder.PutUint64(ed.Encoded[i*8:(i+1)*8], math.Float64bits(value[i]))
}
ed.Type = TypeDouble
return ed, nil
}
func (ve *ValueEncoder) encodeRationals(value []Rational) (ed EncodedData, err error) {
defer func() {
if state := recover(); state != nil {
@ -190,33 +229,38 @@ func (ve *ValueEncoder) Encode(value interface{}) (ed EncodedData, err error) {
}
}()
switch value.(type) {
switch t := value.(type) {
case []byte:
ed, err = ve.encodeBytes(value.([]byte))
ed, err = ve.encodeBytes(t)
log.PanicIf(err)
case string:
ed, err = ve.encodeAscii(value.(string))
ed, err = ve.encodeAscii(t)
log.PanicIf(err)
case []uint16:
ed, err = ve.encodeShorts(value.([]uint16))
ed, err = ve.encodeShorts(t)
log.PanicIf(err)
case []uint32:
ed, err = ve.encodeLongs(value.([]uint32))
ed, err = ve.encodeLongs(t)
log.PanicIf(err)
case []float32:
ed, err = ve.encodeFloats(t)
log.PanicIf(err)
case []float64:
ed, err = ve.encodeDoubles(t)
log.PanicIf(err)
case []Rational:
ed, err = ve.encodeRationals(value.([]Rational))
ed, err = ve.encodeRationals(t)
log.PanicIf(err)
case []int32:
ed, err = ve.encodeSignedLongs(value.([]int32))
ed, err = ve.encodeSignedLongs(t)
log.PanicIf(err)
case []SignedRational:
ed, err = ve.encodeSignedRationals(value.([]SignedRational))
ed, err = ve.encodeSignedRationals(t)
log.PanicIf(err)
case time.Time:
// For convenience, if the user doesn't want to deal with translation
// semantics with timestamps.
t := value.(time.Time)
s := ExifFullTimestampString(t)
ed, err = ve.encodeAscii(s)

View File

@ -2,6 +2,7 @@ package exifcommon
import (
"bytes"
"math"
"reflect"
"testing"
"time"
@ -173,6 +174,80 @@ func TestValueEncoder_encodeLongs__Cycle(t *testing.T) {
}
}
func TestValueEncoder_encodeFloats__Cycle(t *testing.T) {
byteOrder := TestDefaultByteOrder
ve := NewValueEncoder(byteOrder)
original := []float32{3.14159265, 2.71828182, 51.0, 68.0, 85.0}
ed, err := ve.encodeFloats(original)
log.PanicIf(err)
if ed.Type != TypeFloat {
t.Fatalf("IFD type not expected.")
}
expected := []byte{
0x40, 0x49, 0x0f, 0xdb,
0x40, 0x2d, 0xf8, 0x54,
0x42, 0x4c, 0x00, 0x00,
0x42, 0x88, 0x00, 0x00,
0x42, 0xaa, 0x00, 0x00,
}
if bytes.Equal(ed.Encoded, expected) != true {
t.Fatalf("Data not encoded correctly.")
} else if ed.UnitCount != 5 {
t.Fatalf("Unit-count not correct.")
}
recovered, err := parser.ParseFloats(ed.Encoded, ed.UnitCount, byteOrder)
log.PanicIf(err)
for i, v := range recovered {
if v < original[i] || v >= math.Nextafter32(original[i], original[i]+1) {
t.Fatalf("ReadFloats expecting %v, received %v", original[i], v)
}
}
}
func TestValueEncoder_encodeDoubles__Cycle(t *testing.T) {
byteOrder := TestDefaultByteOrder
ve := NewValueEncoder(byteOrder)
original := []float64{3.14159265, 2.71828182, 954877.1230695, 68.0, 85.0}
ed, err := ve.encodeDoubles(original)
log.PanicIf(err)
if ed.Type != TypeDouble {
t.Fatalf("IFD type not expected.")
}
expected := []byte{
0x40, 0x09, 0x21, 0xfb, 0x53, 0xc8, 0xd4, 0xf1,
0x40, 0x05, 0xbf, 0x0a, 0x89, 0xf1, 0xb0, 0xdd,
0x41, 0x2d, 0x23, 0xfa, 0x3f, 0x02, 0xf7, 0x2b,
0x40, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
}
if reflect.DeepEqual(ed.Encoded, expected) != true {
t.Fatalf("Data not encoded correctly.")
} else if ed.UnitCount != 5 {
t.Fatalf("Unit-count not correct.")
}
recovered, err := parser.ParseDoubles(ed.Encoded, ed.UnitCount, byteOrder)
log.PanicIf(err)
for i, v := range recovered {
if v < original[i] || v >= math.Nextafter(original[i], original[i]+1) {
t.Fatalf("ReadDoubles expecting %v, received %v", original[i], v)
}
}
}
func TestValueEncoder_encodeRationals__Cycle(t *testing.T) {
byteOrder := TestDefaultByteOrder
ve := NewValueEncoder(byteOrder)
@ -431,6 +506,64 @@ func TestValueEncoder_Encode__Long(t *testing.T) {
}
}
func TestValueEncoder_Encode__Float(t *testing.T) {
byteOrder := TestDefaultByteOrder
ve := NewValueEncoder(byteOrder)
original := []float32{3.14159265, 2.71828182, 51.0, 68.0, 85.0}
ed, err := ve.Encode(original)
log.PanicIf(err)
if ed.Type != TypeFloat {
t.Fatalf("IFD type not expected.")
}
expected := []byte{
0x40, 0x49, 0x0f, 0xdb,
0x40, 0x2d, 0xf8, 0x54,
0x42, 0x4c, 0x00, 0x00,
0x42, 0x88, 0x00, 0x00,
0x42, 0xaa, 0x00, 0x00,
}
if bytes.Equal(ed.Encoded, expected) != true {
t.Fatalf("Data not encoded correctly.")
} else if ed.UnitCount != 5 {
t.Fatalf("Unit-count not correct.")
}
}
func TestValueEncoder_Encode__Doubles(t *testing.T) {
byteOrder := TestDefaultByteOrder
ve := NewValueEncoder(byteOrder)
original := []float64{3.14159265, 2.71828182, 954877.1230695, 68.0, 85.0}
ed, err := ve.Encode(original)
log.PanicIf(err)
if ed.Type != TypeDouble {
t.Fatalf("IFD type not expected.")
}
expected := []byte{
0x40, 0x09, 0x21, 0xfb, 0x53, 0xc8, 0xd4, 0xf1,
0x40, 0x05, 0xbf, 0x0a, 0x89, 0xf1, 0xb0, 0xdd,
0x41, 0x2d, 0x23, 0xfa, 0x3f, 0x02, 0xf7, 0x2b,
0x40, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
}
if bytes.Equal(ed.Encoded, expected) != true {
t.Fatalf("Data not encoded correctly.")
} else if ed.UnitCount != 5 {
t.Fatalf("Unit-count not correct.")
}
}
func TestValueEncoder_Encode__Rational(t *testing.T) {
byteOrder := TestDefaultByteOrder
ve := NewValueEncoder(byteOrder)