125
125
// of fixed-size values.
126
126
// Bytes read from r are decoded using the specified byte order
127
127
// and written to successive fields of the data.
128
// When reading into structs, the field data for fields with
129
// blank (_) field names is skipped; i.e., blank field names
130
// may be used for padding.
128
131
func Read(r io.Reader, order ByteOrder, data interface{}) error {
129
132
// Fast path for basic types.
130
133
if n := intDestSize(data); n != 0 {
165
168
return errors.New("binary.Read: invalid type " + d.Type().String())
169
return errors.New("binary.Read: invalid type " + v.Type().String())
170
size, err := dataSize(v)
172
return errors.New("binary.Read: " + err.Error())
171
174
d := &decoder{order: order, buf: make([]byte, size)}
172
175
if _, err := io.ReadFull(r, d.buf); err != nil {
181
184
// values, or a pointer to such data.
182
185
// Bytes written to w are encoded using the specified byte order
183
186
// and read from successive fields of the data.
187
// When writing structs, zero values are written for fields
188
// with blank (_) field names.
184
189
func Write(w io.Writer, order ByteOrder, data interface{}) error {
185
190
// Fast path for basic types.
239
244
_, err := w.Write(bs)
248
// Fallback to reflect-based encoding.
242
249
v := reflect.Indirect(reflect.ValueOf(data))
245
return errors.New("binary.Write: invalid type " + v.Type().String())
250
size, err := dataSize(v)
252
return errors.New("binary.Write: " + err.Error())
247
254
buf := make([]byte, size)
248
255
e := &encoder{order: order, buf: buf}
250
_, err := w.Write(buf)
257
_, err = w.Write(buf)
254
261
// Size returns how many bytes Write would generate to encode the value v, which
255
262
// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.
256
263
func Size(v interface{}) int {
257
return dataSize(reflect.Indirect(reflect.ValueOf(v)))
264
n, err := dataSize(reflect.Indirect(reflect.ValueOf(v)))
260
271
// dataSize returns the number of bytes the actual data represented by v occupies in memory.
261
272
// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice
262
273
// it returns the length of the slice times the element size and does not count the memory
263
274
// occupied by the header.
264
func dataSize(v reflect.Value) int {
275
func dataSize(v reflect.Value) (int, error) {
265
276
if v.Kind() == reflect.Slice {
266
elem := sizeof(v.Type().Elem())
277
elem, err := sizeof(v.Type().Elem())
270
return v.Len() * elem
281
return v.Len() * elem, nil
272
283
return sizeof(v.Type())
275
func sizeof(t reflect.Type) int {
286
func sizeof(t reflect.Type) (int, error) {
276
287
switch t.Kind() {
277
288
case reflect.Array:
278
n := sizeof(t.Elem())
289
n, err := sizeof(t.Elem())
293
return t.Len() * n, nil
284
295
case reflect.Struct:
286
297
for i, n := 0, t.NumField(); i < n; i++ {
287
s := sizeof(t.Field(i).Type)
298
s, err := sizeof(t.Field(i).Type)
295
306
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
296
307
reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
297
308
reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
309
return int(t.Size()), nil
303
type decoder struct {
308
type encoder struct {
311
return 0, errors.New("invalid type " + t.String())
313
322
func (d *decoder) uint8() uint8 {
381
390
case reflect.Struct:
382
392
l := v.NumField()
383
393
for i := 0; i < l; i++ {
394
// Note: Calling v.CanSet() below is an optimization.
395
// It would be sufficient to check the field name,
396
// but creating the StructField info for each field is
397
// costly (run "go test -bench=ReadStruct" and compare
398
// results when making changes to this code).
399
if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
387
406
case reflect.Slice:
520
func (d *decoder) skip(v reflect.Value) {
525
func (e *encoder) skip(v reflect.Value) {
527
for i := range e.buf[0:n] {
495
533
// intDestSize returns the size of the integer that ptrType points to,
496
534
// or 0 if the type is not supported.
497
535
func intDestSize(ptrType interface{}) int {