21 Order binary.ByteOrder
28 func (f *Field) String() string {
31 return fmt.Sprintf("{type: Pad, len: %d}", f.Len)
33 out = fmt.Sprintf("type: %s, order: %v", f.Type.String(), f.Order)
35 if f.Sizefrom != nil {
36 out += fmt.Sprintf(", sizefrom: %v", f.Sizefrom)
38 out += fmt.Sprintf(", len: %d", f.Len)
41 out += fmt.Sprintf(", sizeof: %v", f.Sizeof)
43 return "{" + out + "}"
46 func (f *Field) Size(val reflect.Value, options *Options) int {
47 typ := f.Type.Resolve(options)
50 vals := []reflect.Value{val}
52 vals = make([]reflect.Value, val.Len())
53 for i := 0; i < val.Len(); i++ {
54 vals[i] = val.Index(i)
57 for _, val := range vals {
58 size += f.Fields.Sizeof(val, options)
60 } else if typ == Pad {
62 } else if f.Slice || f.kind == reflect.String {
67 size = length * typ.Size()
68 } else if typ == CustomType {
69 return val.Addr().Interface().(Custom).Size(options)
73 align := options.ByteAlign
74 if align > 0 && size < align {
80 func (f *Field) packVal(buf []byte, val reflect.Value, length int, options *Options) (size int, err error) {
82 if options.Order != nil {
88 typ := f.Type.Resolve(options)
91 return f.Fields.Pack(buf, val, options)
92 case Bool, Int8, Int16, Int32, Int64, Uint8, Uint16, Uint32, Uint64:
102 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
103 n = uint64(val.Int())
117 order.PutUint16(buf, uint16(n))
119 order.PutUint32(buf, uint32(n))
121 order.PutUint64(buf, uint64(n))
123 case Float32, Float64:
128 order.PutUint32(buf, math.Float32bits(float32(n)))
130 order.PutUint64(buf, math.Float64bits(n))
136 copy(buf, []byte(val.String()))
138 // TODO: handle kind != bytes here
140 copy(buf, val.Bytes())
143 return val.Addr().Interface().(Custom).Pack(buf, options)
145 panic(fmt.Sprintf("no pack handler for type: %s", typ))
150 func (f *Field) Pack(buf []byte, val reflect.Value, length int, options *Options) (int, error) {
151 typ := f.Type.Resolve(options)
153 for i := 0; i < length; i++ {
159 // special case strings and byte slices for performance
161 if !f.Array && typ == Uint8 && (f.defType == Uint8 || f.kind == reflect.String) {
163 if f.kind == reflect.String {
164 tmp = []byte(val.String())
170 // TODO: allow configuring pad byte?
171 rep := bytes.Repeat([]byte{0}, length-end)
175 return val.Len(), nil
178 var zero reflect.Value
180 zero = reflect.Zero(val.Type().Elem())
182 for i := 0; i < length; i++ {
187 if n, err := f.packVal(buf[pos:], cur, 1, options); err != nil {
195 return f.packVal(buf, val, length, options)
199 func (f *Field) unpackVal(buf []byte, val reflect.Value, length int, options *Options) error {
201 if options.Order != nil {
202 order = options.Order
207 typ := f.Type.Resolve(options)
209 case Float32, Float64:
213 n = float64(math.Float32frombits(order.Uint32(buf)))
215 n = math.Float64frombits(order.Uint64(buf))
218 case reflect.Float32, reflect.Float64:
221 return fmt.Errorf("struc: refusing to unpack float into field %s of type %s", f.Name, f.kind.String())
223 case Bool, Int8, Int16, Int32, Int64, Uint8, Uint16, Uint32, Uint64:
226 case Bool, Int8, Uint8:
229 n = uint64(order.Uint16(buf))
231 n = uint64(order.Uint32(buf))
233 n = uint64(order.Uint64(buf))
238 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
244 panic(fmt.Sprintf("no unpack handler for type: %s", typ))
249 func (f *Field) Unpack(buf []byte, val reflect.Value, length int, options *Options) error {
250 typ := f.Type.Resolve(options)
251 if typ == Pad || f.kind == reflect.String {
255 val.SetString(string(buf))
259 if val.Cap() < length {
260 val.Set(reflect.MakeSlice(val.Type(), length, length))
261 } else if val.Len() < length {
262 val.Set(val.Slice(0, length))
264 // special case byte slices for performance
265 if !f.Array && typ == Uint8 && f.defType == Uint8 {
266 copy(val.Bytes(), buf[:length])
271 for i := 0; i < length; i++ {
272 if err := f.unpackVal(buf[pos:pos+size], val.Index(i), 1, options); err != nil {
279 return f.unpackVal(buf, val, length, options)