Encoders for ints and floats now convert compatible values

* Any int that fits in the destination int type will be accepted
* Any float that fits in the destination float type will be accepted
scan-io
Jack Christensen 2014-06-20 10:48:45 -05:00
parent 4efa61bf5b
commit 51cada7b74
2 changed files with 120 additions and 16 deletions

View File

@ -6,6 +6,7 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"io" "io"
"math"
"regexp" "regexp"
"strconv" "strconv"
"time" "time"
@ -197,9 +198,31 @@ func decodeInt8FromBinary(mr *MessageReader, size int32) interface{} {
} }
func encodeInt8(w io.Writer, value interface{}) error { func encodeInt8(w io.Writer, value interface{}) error {
v, ok := value.(int64) var v int64
if !ok { switch value := value.(type) {
return fmt.Errorf("Expected int64, received %T", value) case int8:
v = int64(value)
case uint8:
v = int64(value)
case int16:
v = int64(value)
case uint16:
v = int64(value)
case int32:
v = int64(value)
case uint32:
v = int64(value)
case int64:
v = int64(value)
case uint64:
if value > math.MaxInt64 {
return fmt.Errorf("uint64 %d is larger than max int64 %d", value, math.MaxInt64)
}
v = int64(value)
case int:
v = int64(value)
default:
return fmt.Errorf("Expected integer representable in int64, received %T %v", value, value)
} }
err := binary.Write(w, binary.BigEndian, int32(8)) err := binary.Write(w, binary.BigEndian, int32(8))
@ -227,9 +250,46 @@ func decodeInt2FromBinary(mr *MessageReader, size int32) interface{} {
} }
func encodeInt2(w io.Writer, value interface{}) error { func encodeInt2(w io.Writer, value interface{}) error {
v, ok := value.(int16) var v int16
if !ok { switch value := value.(type) {
return fmt.Errorf("Expected int16, received %T", value) case int8:
v = int16(value)
case uint8:
v = int16(value)
case int16:
v = int16(value)
case uint16:
if value > math.MaxInt16 {
return fmt.Errorf("%T %d is larger than max int16 %d", value, value, math.MaxInt16)
}
v = int16(value)
case int32:
if value > math.MaxInt16 {
return fmt.Errorf("%T %d is larger than max int16 %d", value, value, math.MaxInt16)
}
v = int16(value)
case uint32:
if value > math.MaxInt16 {
return fmt.Errorf("%T %d is larger than max int16 %d", value, value, math.MaxInt16)
}
v = int16(value)
case int64:
if value > math.MaxInt16 {
return fmt.Errorf("%T %d is larger than max int16 %d", value, value, math.MaxInt16)
}
v = int16(value)
case uint64:
if value > math.MaxInt16 {
return fmt.Errorf("%T %d is larger than max int16 %d", value, value, math.MaxInt16)
}
v = int16(value)
case int:
if value > math.MaxInt16 {
return fmt.Errorf("%T %d is larger than max int16 %d", value, value, math.MaxInt16)
}
v = int16(value)
default:
return fmt.Errorf("Expected integer representable in int16, received %T %v", value, value)
} }
err := binary.Write(w, binary.BigEndian, int32(2)) err := binary.Write(w, binary.BigEndian, int32(2))
@ -257,9 +317,40 @@ func decodeInt4FromBinary(mr *MessageReader, size int32) interface{} {
} }
func encodeInt4(w io.Writer, value interface{}) error { func encodeInt4(w io.Writer, value interface{}) error {
v, ok := value.(int32) var v int32
if !ok { switch value := value.(type) {
return fmt.Errorf("Expected int32, received %T", value) case int8:
v = int32(value)
case uint8:
v = int32(value)
case int16:
v = int32(value)
case uint16:
v = int32(value)
case int32:
v = int32(value)
case uint32:
if value > math.MaxInt32 {
return fmt.Errorf("%T %d is larger than max int64 %d", value, value, math.MaxInt32)
}
v = int32(value)
case int64:
if value > math.MaxInt32 {
return fmt.Errorf("%T %d is larger than max int64 %d", value, value, math.MaxInt32)
}
v = int32(value)
case uint64:
if value > math.MaxInt32 {
return fmt.Errorf("%T %d is larger than max int64 %d", value, value, math.MaxInt32)
}
v = int32(value)
case int:
if value > math.MaxInt32 {
return fmt.Errorf("%T %d is larger than max int64 %d", value, value, math.MaxInt32)
}
v = int32(value)
default:
return fmt.Errorf("Expected integer representable in int32, received %T %v", value, value)
} }
err := binary.Write(w, binary.BigEndian, int32(4)) err := binary.Write(w, binary.BigEndian, int32(4))
@ -290,9 +381,17 @@ func decodeFloat4FromBinary(mr *MessageReader, size int32) interface{} {
} }
func encodeFloat4(w io.Writer, value interface{}) error { func encodeFloat4(w io.Writer, value interface{}) error {
v, ok := value.(float32) var v float32
if !ok { switch value := value.(type) {
return fmt.Errorf("Expected float32, received %T", value) case float32:
v = float32(value)
case float64:
if value > math.MaxFloat32 {
return fmt.Errorf("%T %f is larger than max float32 %f", value, math.MaxFloat32)
}
v = float32(value)
default:
return fmt.Errorf("Expected float representable in float32, received %T %v", value, value)
} }
err := binary.Write(w, binary.BigEndian, int32(4)) err := binary.Write(w, binary.BigEndian, int32(4))
@ -323,9 +422,14 @@ func decodeFloat8FromBinary(mr *MessageReader, size int32) interface{} {
} }
func encodeFloat8(w io.Writer, value interface{}) error { func encodeFloat8(w io.Writer, value interface{}) error {
v, ok := value.(float64) var v float64
if !ok { switch value := value.(type) {
return fmt.Errorf("Expected float64, received %T", value) case float32:
v = float64(value)
case float64:
v = float64(value)
default:
return fmt.Errorf("Expected float representable in float64, received %T %v", value, value)
} }
err := binary.Write(w, binary.BigEndian, int32(8)) err := binary.Write(w, binary.BigEndian, int32(8))

View File

@ -19,7 +19,7 @@ func TestTranscodeError(t *testing.T) {
switch { switch {
case err == nil: case err == nil:
t.Error("Expected transcode error to return error, but it didn't") t.Error("Expected transcode error to return error, but it didn't")
case err.Error() == "Expected int32, received string": case err.Error() == "Expected integer representable in int32, received string wrong":
// Correct behavior // Correct behavior
default: default:
t.Errorf("Expected transcode error, received %v", err) t.Errorf("Expected transcode error, received %v", err)