summaryrefslogtreecommitdiff
path: root/libgo/go/encoding/binary/binary.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/encoding/binary/binary.go')
-rw-r--r--libgo/go/encoding/binary/binary.go61
1 files changed, 58 insertions, 3 deletions
diff --git a/libgo/go/encoding/binary/binary.go b/libgo/go/encoding/binary/binary.go
index 8c2d1d9da47..a99ca019949 100644
--- a/libgo/go/encoding/binary/binary.go
+++ b/libgo/go/encoding/binary/binary.go
@@ -26,6 +26,7 @@ import (
"io"
"math"
"reflect"
+ "sync"
)
// A ByteOrder specifies how to convert byte sequences into
@@ -184,6 +185,10 @@ func Read(r io.Reader, order ByteOrder, data interface{}) error {
*data = int64(order.Uint64(bs))
case *uint64:
*data = order.Uint64(bs)
+ case *float32:
+ *data = math.Float32frombits(order.Uint32(bs))
+ case *float64:
+ *data = math.Float64frombits(order.Uint64(bs))
case []bool:
for i, x := range bs { // Easier to loop over the input for 8-bit values.
data[i] = x != 0
@@ -218,8 +223,20 @@ func Read(r io.Reader, order ByteOrder, data interface{}) error {
for i := range data {
data[i] = order.Uint64(bs[8*i:])
}
+ case []float32:
+ for i := range data {
+ data[i] = math.Float32frombits(order.Uint32(bs[4*i:]))
+ }
+ case []float64:
+ for i := range data {
+ data[i] = math.Float64frombits(order.Uint64(bs[8*i:]))
+ }
+ default:
+ n = 0 // fast path doesn't apply
+ }
+ if n != 0 {
+ return nil
}
- return nil
}
// Fallback to reflect-based decoding.
@@ -338,6 +355,22 @@ func Write(w io.Writer, order ByteOrder, data interface{}) error {
for i, x := range v {
order.PutUint64(bs[8*i:], x)
}
+ case *float32:
+ order.PutUint32(bs, math.Float32bits(*v))
+ case float32:
+ order.PutUint32(bs, math.Float32bits(v))
+ case []float32:
+ for i, x := range v {
+ order.PutUint32(bs[4*i:], math.Float32bits(x))
+ }
+ case *float64:
+ order.PutUint64(bs, math.Float64bits(*v))
+ case float64:
+ order.PutUint64(bs, math.Float64bits(v))
+ case []float64:
+ for i, x := range v {
+ order.PutUint64(bs[8*i:], math.Float64bits(x))
+ }
}
_, err := w.Write(bs)
return err
@@ -363,18 +396,32 @@ func Size(v interface{}) int {
return dataSize(reflect.Indirect(reflect.ValueOf(v)))
}
+var structSize sync.Map // map[reflect.Type]int
+
// dataSize returns the number of bytes the actual data represented by v occupies in memory.
// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice
// it returns the length of the slice times the element size and does not count the memory
// occupied by the header. If the type of v is not acceptable, dataSize returns -1.
func dataSize(v reflect.Value) int {
- if v.Kind() == reflect.Slice {
+ switch v.Kind() {
+ case reflect.Slice:
if s := sizeof(v.Type().Elem()); s >= 0 {
return s * v.Len()
}
return -1
+
+ case reflect.Struct:
+ t := v.Type()
+ if size, ok := structSize.Load(t); ok {
+ return size.(int)
+ }
+ size := sizeof(t)
+ structSize.Store(t, size)
+ return size
+
+ default:
+ return sizeof(v.Type())
}
- return sizeof(v.Type())
}
// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.
@@ -677,6 +724,14 @@ func intDataSize(data interface{}) int {
return 8 * len(data)
case []uint64:
return 8 * len(data)
+ case float32, *float32:
+ return 4
+ case float64, *float64:
+ return 8
+ case []float32:
+ return 4 * len(data)
+ case []float64:
+ return 8 * len(data)
}
return 0
}