1package decode
2
3import (
4	"bytes"
5	"context"
6	"fmt"
7	"io"
8	"io/ioutil"
9
10	"github.com/wader/fq/internal/recoverfn"
11	"github.com/wader/fq/pkg/bitio"
12	"github.com/wader/fq/pkg/ranges"
13	"github.com/wader/fq/pkg/scalar"
14)
15
16//go:generate sh -c "cat decode_gen.go.tmpl | go run ../../dev/tmpl.go types.json | gofmt > decode_gen.go"
17
18type Endian int
19
20const (
21	// BigEndian byte order
22	BigEndian = iota
23	// LittleEndian byte order
24	LittleEndian
25)
26
27type Options struct {
28	Name          string
29	Description   string
30	Force         bool
31	FillGaps      bool
32	IsRoot        bool
33	Range         ranges.Range // if zero use whole buffer
34	FormatOptions map[string]interface{}
35	FormatInArg   interface{}
36	ReadBuf       *[]byte
37}
38
39// Decode try decode group and return first success and all other decoder errors
40func Decode(ctx context.Context, bb *bitio.Buffer, group Group, opts Options) (*Value, interface{}, error) {
41	return decode(ctx, bb, group, opts)
42}
43
44func decode(ctx context.Context, bb *bitio.Buffer, group Group, opts Options) (*Value, interface{}, error) {
45	decodeRange := opts.Range
46	if decodeRange.IsZero() {
47		decodeRange = ranges.Range{Len: bb.Len()}
48	}
49
50	if group == nil {
51		panic("group is nil, failed to register format?")
52	}
53
54	formatsErr := FormatsError{}
55
56	for _, g := range group {
57		cbb, err := bb.BitBufRange(decodeRange.Start, decodeRange.Len)
58		if err != nil {
59			return nil, nil, IOError{Err: err, Op: "BitBufRange", ReadSize: decodeRange.Len, Pos: decodeRange.Start}
60		}
61
62		d := newDecoder(ctx, g, cbb, opts)
63
64		var decodeV interface{}
65		r, rOk := recoverfn.Run(func() {
66			decodeV = g.DecodeFn(d, opts.FormatInArg)
67		})
68
69		if ctx != nil && ctx.Err() != nil {
70			return nil, nil, ctx.Err()
71		}
72
73		if !rOk {
74			if re, ok := r.RecoverV.(RecoverableErrorer); ok && re.IsRecoverableError() {
75				panicErr, _ := re.(error)
76				formatErr := FormatError{
77					Err:        panicErr,
78					Format:     g,
79					Stacktrace: r,
80				}
81				formatsErr.Errs = append(formatsErr.Errs, formatErr)
82
83				switch vv := d.Value.V.(type) {
84				case *Compound:
85					// TODO: hack, changes V
86					vv.Err = formatErr
87					d.Value.V = vv
88				}
89
90				if len(group) != 1 {
91					continue
92				}
93			} else {
94				r.RePanic()
95			}
96		}
97
98		// TODO: maybe move to Format* funcs?
99		if opts.FillGaps {
100			d.FillGaps(ranges.Range{Start: 0, Len: decodeRange.Len}, "unknown")
101		}
102
103		var minMaxRange ranges.Range
104		if err := d.Value.WalkRootPreOrder(func(v *Value, rootV *Value, depth int, rootDepth int) error {
105			minMaxRange = ranges.MinMax(minMaxRange, v.Range)
106			v.Range.Start += decodeRange.Start
107			v.RootBitBuf = bb
108			return nil
109		}); err != nil {
110			return nil, nil, err
111		}
112
113		d.Value.Range = ranges.Range{Start: decodeRange.Start, Len: minMaxRange.Len}
114
115		if opts.IsRoot {
116			d.Value.postProcess()
117		}
118
119		if len(formatsErr.Errs) > 0 {
120			return d.Value, decodeV, formatsErr
121		}
122
123		return d.Value, decodeV, nil
124	}
125
126	return nil, nil, formatsErr
127}
128
129type D struct {
130	Ctx     context.Context
131	Endian  Endian
132	Value   *Value
133	Options Options
134
135	bitBuf *bitio.Buffer
136
137	readBuf *[]byte
138}
139
140// TODO: new struct decoder?
141// note bb is assumed to be a non-shared buffer
142func newDecoder(ctx context.Context, format Format, bb *bitio.Buffer, opts Options) *D {
143	name := format.RootName
144	if opts.Name != "" {
145		name = opts.Name
146	}
147	rootV := &Compound{
148		IsArray:     format.RootArray,
149		Children:    nil,
150		Description: opts.Description,
151		Format:      &format,
152	}
153
154	return &D{
155		Ctx:    ctx,
156		Endian: BigEndian,
157		Value: &Value{
158			Name:       name,
159			V:          rootV,
160			RootBitBuf: bb,
161			Range:      ranges.Range{Start: 0, Len: 0},
162			IsRoot:     opts.IsRoot,
163		},
164		Options: opts,
165
166		bitBuf:  bb,
167		readBuf: opts.ReadBuf,
168	}
169}
170
171func (d *D) FieldDecoder(name string, bitBuf *bitio.Buffer, v interface{}) *D {
172	return &D{
173		Ctx:    d.Ctx,
174		Endian: d.Endian,
175		Value: &Value{
176			Name:       name,
177			V:          v,
178			Range:      ranges.Range{Start: d.Pos(), Len: 0},
179			RootBitBuf: bitBuf,
180		},
181		Options: d.Options,
182
183		bitBuf:  bitBuf,
184		readBuf: d.readBuf,
185	}
186}
187
188func (d *D) Copy(r io.Writer, w io.Reader) (int64, error) {
189	// TODO: what size? now same as io.Copy
190	buf := d.SharedReadBuf(32 * 1024)
191	return io.CopyBuffer(r, w, buf)
192}
193
194func (d *D) MustCopy(r io.Writer, w io.Reader) int64 {
195	n, err := d.Copy(r, w)
196	if err != nil {
197		d.IOPanic(err, "MustCopy: Copy")
198	}
199	return n
200}
201
202func (d *D) MustNewBitBufFromReader(r io.Reader) *bitio.Buffer {
203	b := &bytes.Buffer{}
204	d.MustCopy(b, r)
205	return bitio.NewBufferFromBytes(b.Bytes(), -1)
206}
207
208func (d *D) SharedReadBuf(n int) []byte {
209	if d.readBuf == nil {
210		d.readBuf = new([]byte)
211	}
212	if len(*d.readBuf) < n {
213		*d.readBuf = make([]byte, n)
214	}
215	return *d.readBuf
216}
217
218func (d *D) FillGaps(r ranges.Range, namePrefix string) {
219	makeWalkFn := func(fn func(iv *Value)) func(iv *Value, rootV *Value, depth int, rootDepth int) error {
220		return func(iv *Value, rootV *Value, depth int, rootDepth int) error {
221			switch iv.V.(type) {
222			case *Compound:
223			default:
224				fn(iv)
225			}
226			return nil
227		}
228	}
229
230	// TODO: redo this, tries to get rid of slice grow
231	// TODO: pre-sorted somehow?
232	n := 0
233	_ = d.Value.WalkRootPreOrder(makeWalkFn(func(iv *Value) { n++ }))
234	valueRanges := make([]ranges.Range, n)
235	i := 0
236	_ = d.Value.WalkRootPreOrder(makeWalkFn(func(iv *Value) {
237		valueRanges[i] = iv.Range
238		i++
239	}))
240
241	gaps := ranges.Gaps(r, valueRanges)
242	for i, gap := range gaps {
243		bb, err := d.bitBuf.BitBufRange(gap.Start, gap.Len)
244		if err != nil {
245			d.IOPanic(err, "FillGaps: BitBufRange")
246		}
247
248		v := &Value{
249			Name: fmt.Sprintf("%s%d", namePrefix, i),
250			V: &scalar.S{
251				Actual:  bb,
252				Unknown: true,
253			},
254			RootBitBuf: d.bitBuf,
255			Range:      gap,
256		}
257
258		d.AddChild(v)
259	}
260}
261
262// Errorf stops decode with a reason unless forced
263func (d *D) Errorf(format string, a ...interface{}) {
264	if !d.Options.Force {
265		panic(DecoderError{Reason: fmt.Sprintf(format, a...), Pos: d.Pos()})
266	}
267}
268
269// Fatalf stops decode with a reason regardless of forced
270func (d *D) Fatalf(format string, a ...interface{}) {
271	panic(DecoderError{Reason: fmt.Sprintf(format, a...), Pos: d.Pos()})
272}
273
274func (d *D) IOPanic(err error, op string) {
275	panic(IOError{Err: err, Pos: d.Pos(), Op: op})
276}
277
278// Bits reads nBits bits from buffer
279func (d *D) bits(nBits int) (uint64, error) {
280	if nBits < 0 || nBits > 64 {
281		return 0, fmt.Errorf("nBits must be 0-64 (%d)", nBits)
282	}
283	// 64 bits max, 9 byte worse case if not byte aligned
284	buf := d.SharedReadBuf(9)
285	_, err := bitio.ReadFull(d.bitBuf, buf, nBits)
286	if err != nil {
287		return 0, err
288	}
289
290	return bitio.Read64(buf[:], 0, nBits), nil
291}
292
293// Bits reads nBits bits from buffer
294func (d *D) Bits(nBits int) (uint64, error) {
295	n, err := d.bits(nBits)
296	if err != nil {
297		return 0, err
298	}
299	return n, nil
300}
301
302func (d *D) PeekBits(nBits int) uint64 {
303	n, err := d.TryPeekBits(nBits)
304	if err != nil {
305		panic(IOError{Err: err, Op: "PeekBits", ReadSize: int64(nBits), Pos: d.Pos()})
306	}
307	return n
308}
309
310func (d *D) PeekBytes(nBytes int) []byte {
311	bs, err := d.bitBuf.PeekBytes(nBytes)
312	if err != nil {
313		panic(IOError{Err: err, Op: "PeekBytes", ReadSize: int64(nBytes) * 8, Pos: d.Pos()})
314	}
315	return bs
316}
317
318func (d *D) PeekFind(nBits int, seekBits int64, fn func(v uint64) bool, maxLen int64) (int64, uint64) {
319	peekBits, v, err := d.TryPeekFind(nBits, seekBits, maxLen, fn)
320	if err != nil {
321		d.IOPanic(err, "PeekFind: TryPeekFind")
322	}
323	if peekBits == -1 {
324		d.Errorf("peek not found")
325	}
326	return peekBits, v
327}
328
329func (d *D) TryHasBytes(hb []byte) bool {
330	lenHb := len(hb)
331	if d.BitsLeft() < int64(lenHb*8) {
332		return false
333	}
334	bs := d.PeekBytes(lenHb)
335	return bytes.Equal(hb, bs)
336}
337
338// PeekFindByte number of bytes to next v
339func (d *D) PeekFindByte(findV uint8, maxLen int64) int64 {
340	peekBits, _, err := d.TryPeekFind(8, 8, maxLen*8, func(v uint64) bool {
341		return uint64(findV) == v
342	})
343	if err != nil {
344		panic(IOError{Err: err, Op: "PeekFindByte", ReadSize: 0, Pos: d.Pos()})
345
346	}
347	return peekBits / 8
348}
349
350// PeekBits peek nBits bits from buffer
351// TODO: share code?
352func (d *D) TryPeekBits(nBits int) (uint64, error) {
353	start, err := d.bitBuf.SeekBits(0, io.SeekCurrent)
354	if err != nil {
355		return 0, err
356	}
357	n, err := d.bits(nBits)
358	if _, err := d.bitBuf.SeekBits(start, io.SeekStart); err != nil {
359		return 0, err
360	}
361	return n, err
362}
363
364func (d *D) TryPeekFind(nBits int, seekBits int64, maxLen int64, fn func(v uint64) bool) (int64, uint64, error) {
365	start, err := d.bitBuf.SeekBits(0, io.SeekCurrent)
366	if err != nil {
367		return 0, 0, err
368	}
369
370	var count int64
371
372	if seekBits < 0 {
373		count = int64(-nBits)
374		if _, err := d.bitBuf.SeekBits(start+count, io.SeekStart); err != nil {
375			return 0, 0, err
376		}
377	}
378
379	found := false
380	var v uint64
381	for {
382		if (seekBits > 0 && maxLen > 0 && count >= maxLen) || (seekBits < 0 && maxLen > 0 && count < -maxLen) {
383			break
384		}
385		v, err = d.TryU(nBits)
386		if err != nil {
387			if _, err := d.bitBuf.SeekBits(start, io.SeekStart); err != nil {
388				return 0, 0, err
389			}
390			return 0, 0, err
391		}
392		if fn(v) {
393			found = true
394			break
395		}
396		count += seekBits
397		if _, err := d.bitBuf.SeekBits(start+count, io.SeekStart); err != nil {
398			return 0, 0, err
399		}
400	}
401	if _, err := d.bitBuf.SeekBits(start, io.SeekStart); err != nil {
402		return 0, 0, err
403	}
404
405	if !found {
406		return -1, 0, nil
407	}
408
409	return count, v, nil
410}
411
412func (d *D) BytesRange(firstBit int64, nBytes int) []byte {
413	bs, err := d.bitBuf.BytesRange(firstBit, nBytes)
414	if err != nil {
415		panic(IOError{Err: err, Op: "BytesRange", ReadSize: int64(nBytes) * 8, Pos: firstBit})
416	}
417	return bs
418}
419
420func (d *D) BytesLen(nBytes int) []byte {
421	bs, err := d.bitBuf.BytesLen(nBytes)
422	if err != nil {
423		panic(IOError{Err: err, Op: "BytesLen", ReadSize: int64(nBytes) * 8, Pos: d.Pos()})
424	}
425	return bs
426}
427
428// TODO: rename/remove BitBuf name?
429func (d *D) BitBufRange(firstBit int64, nBits int64) *bitio.Buffer {
430	bb, err := d.bitBuf.BitBufRange(firstBit, nBits)
431	if err != nil {
432		panic(IOError{Err: err, Op: "BitBufRange", ReadSize: nBits, Pos: firstBit})
433	}
434	return bb
435}
436
437func (d *D) Pos() int64 {
438	bPos, err := d.bitBuf.Pos()
439	if err != nil {
440		panic(IOError{Err: err, Op: "Pos", ReadSize: 0, Pos: bPos})
441	}
442	return bPos
443}
444
445func (d *D) Len() int64 {
446	return d.bitBuf.Len()
447}
448
449func (d *D) End() bool {
450	bEnd, err := d.bitBuf.End()
451	if err != nil {
452		panic(IOError{Err: err, Op: "Len", ReadSize: 0, Pos: d.Pos()})
453	}
454	return bEnd
455}
456
457func (d *D) NotEnd() bool { return !d.End() }
458
459func (d *D) BitsLeft() int64 {
460	bBitsLeft, err := d.bitBuf.BitsLeft()
461	if err != nil {
462		panic(IOError{Err: err, Op: "BitsLeft", ReadSize: 0, Pos: d.Pos()})
463	}
464	return bBitsLeft
465}
466
467func (d *D) AlignBits(nBits int) int {
468	bByteAlignBits, err := d.bitBuf.AlignBits(nBits)
469	if err != nil {
470		panic(IOError{Err: err, Op: "AlignBits", ReadSize: 0, Pos: d.Pos()})
471	}
472	return bByteAlignBits
473}
474
475func (d *D) ByteAlignBits() int {
476	bByteAlignBits, err := d.bitBuf.ByteAlignBits()
477	if err != nil {
478		panic(IOError{Err: err, Op: "ByteAlignBits", ReadSize: 0, Pos: d.Pos()})
479	}
480	return bByteAlignBits
481}
482
483func (d *D) BytePos() int64 {
484	bBytePos, err := d.bitBuf.BytePos()
485	if err != nil {
486		panic(IOError{Err: err, Op: "BytePos", ReadSize: 0, Pos: d.Pos()})
487	}
488	return bBytePos
489}
490
491func (d *D) SeekRel(deltaBits int64) int64 {
492	pos, err := d.bitBuf.SeekRel(deltaBits)
493	if err != nil {
494		panic(IOError{Err: err, Op: "SeekRel", SeekPos: deltaBits, Pos: d.Pos()})
495	}
496	return pos
497}
498
499func (d *D) SeekAbs(pos int64) int64 {
500	pos, err := d.bitBuf.SeekAbs(pos)
501	if err != nil {
502		panic(IOError{Err: err, Op: "SeekAbs", SeekPos: pos, Pos: d.Pos()})
503	}
504	return pos
505}
506
507func (d *D) AddChild(v *Value) {
508	v.Parent = d.Value
509
510	switch fv := d.Value.V.(type) {
511	case *Compound:
512		if !fv.IsArray {
513			for _, ff := range fv.Children {
514				if ff.Name == v.Name {
515					d.Fatalf("%q already exist in struct %s", v.Name, d.Value.Name)
516				}
517			}
518		}
519		fv.Children = append(fv.Children, v)
520	}
521}
522
523func (d *D) FieldGet(name string) *Value {
524	switch fv := d.Value.V.(type) {
525	case *Compound:
526		for _, ff := range fv.Children {
527			if ff.Name == name {
528				return ff
529			}
530		}
531	default:
532		panic(fmt.Sprintf("%s is not a struct", d.Value.Name))
533	}
534	return nil
535}
536
537func (d *D) FieldMustGet(name string) *Value {
538	if v := d.FieldGet(name); v != nil {
539		return v
540	}
541	panic(fmt.Sprintf("%s not found in struct %s", name, d.Value.Name))
542}
543
544func (d *D) FieldArray(name string, fn func(d *D), sms ...scalar.Mapper) *D {
545	cd := d.FieldDecoder(name, d.bitBuf, &Compound{IsArray: true})
546	d.AddChild(cd.Value)
547	fn(cd)
548	return cd
549}
550
551func (d *D) FieldArrayValue(name string) *D {
552	return d.FieldArray(name, func(d *D) {})
553}
554
555func (d *D) FieldStruct(name string, fn func(d *D)) *D {
556	cd := d.FieldDecoder(name, d.bitBuf, &Compound{})
557	d.AddChild(cd.Value)
558	fn(cd)
559	return cd
560}
561
562func (d *D) FieldStructValue(name string) *D {
563	return d.FieldStruct(name, func(d *D) {})
564}
565
566func (d *D) FieldStructArrayLoop(name string, structName string, condFn func() bool, fn func(d *D)) *D {
567	return d.FieldArray(name, func(d *D) {
568		for condFn() {
569			d.FieldStruct(structName, fn)
570		}
571	})
572}
573
574func (d *D) FieldArrayLoop(name string, condFn func() bool, fn func(d *D)) *D {
575	return d.FieldArray(name, func(d *D) {
576		for condFn() {
577			fn(d)
578		}
579	})
580}
581
582func (d *D) FieldRangeFn(name string, firstBit int64, nBits int64, fn func() *Value) *Value {
583	v := fn()
584	v.Name = name
585	v.RootBitBuf = d.bitBuf
586	v.Range = ranges.Range{Start: firstBit, Len: nBits}
587	d.AddChild(v)
588
589	return v
590}
591
592func (d *D) AssertAtLeastBitsLeft(nBits int64) {
593	if d.Options.Force {
594		return
595	}
596	bl := d.BitsLeft()
597	if bl < nBits {
598		// TODO:
599		panic(DecoderError{Reason: fmt.Sprintf("expected bits left %d, found %d", nBits, bl), Pos: d.Pos()})
600	}
601}
602
603func (d *D) AssertLeastBytesLeft(nBytes int64) {
604	if d.Options.Force {
605		return
606	}
607	bl := d.BitsLeft()
608	if bl < nBytes*8 {
609		// TODO:
610		panic(DecoderError{Reason: fmt.Sprintf("expected bytes left %d, found %d bits", nBytes, bl), Pos: d.Pos()})
611	}
612}
613
614// TODO: rethink
615func (d *D) FieldValueU(name string, a uint64, sms ...scalar.Mapper) {
616	d.FieldScalarFn(name, func(_ scalar.S) (scalar.S, error) { return scalar.S{Actual: a}, nil }, sms...)
617}
618
619func (d *D) FieldValueS(name string, a int64, sms ...scalar.Mapper) {
620	d.FieldScalarFn(name, func(_ scalar.S) (scalar.S, error) { return scalar.S{Actual: a}, nil }, sms...)
621}
622
623func (d *D) FieldValueBool(name string, a bool, sms ...scalar.Mapper) {
624	d.FieldScalarFn(name, func(_ scalar.S) (scalar.S, error) { return scalar.S{Actual: a}, nil }, sms...)
625}
626
627func (d *D) FieldValueFloat(name string, a float64, sms ...scalar.Mapper) {
628	d.FieldScalarFn(name, func(_ scalar.S) (scalar.S, error) { return scalar.S{Actual: a}, nil }, sms...)
629}
630
631func (d *D) FieldValueStr(name string, a string, sms ...scalar.Mapper) {
632	d.FieldScalarFn(name, func(_ scalar.S) (scalar.S, error) { return scalar.S{Actual: a}, nil }, sms...)
633}
634
635func (d *D) FieldValueRaw(name string, a []byte, sms ...scalar.Mapper) {
636	d.FieldScalarFn(name, func(_ scalar.S) (scalar.S, error) {
637		return scalar.S{Actual: bitio.NewBufferFromBytes(a, -1)}, nil
638	}, sms...)
639}
640
641func (d *D) LenFn(nBits int64, fn func(d *D)) {
642	d.RangeFn(d.Pos(), nBits, fn)
643	d.SeekRel(nBits)
644}
645
646func (d *D) RangeFn(firstBit int64, nBits int64, fn func(d *D)) {
647	var subV interface{}
648	switch vv := d.Value.V.(type) {
649	case *Compound:
650		subV = &Compound{IsArray: vv.IsArray}
651	default:
652		panic("unreachable")
653	}
654
655	// TODO: do some kind of DecodeLimitedLen/RangeFn?
656	bb := d.BitBufRange(0, firstBit+nBits)
657	if _, err := bb.SeekAbs(firstBit); err != nil {
658		d.IOPanic(err, "RangeFn: SeekAbs")
659	}
660	sd := d.FieldDecoder("", bb, subV)
661
662	fn(sd)
663
664	// TODO: refactor, similar to decode()
665	if err := sd.Value.WalkRootPreOrder(func(v *Value, rootV *Value, depth int, rootDepth int) error {
666		//v.Range.Start += firstBit
667		v.RootBitBuf = d.Value.RootBitBuf
668
669		return nil
670	}); err != nil {
671		panic(err)
672	}
673
674	switch vv := sd.Value.V.(type) {
675	case *Compound:
676		for _, f := range vv.Children {
677			d.AddChild(f)
678		}
679	default:
680		panic("unreachable")
681	}
682}
683
684func (d *D) Format(group Group, inArg interface{}) interface{} {
685	dv, v, err := decode(d.Ctx, d.bitBuf, group, Options{
686		Force:       d.Options.Force,
687		FillGaps:    false,
688		IsRoot:      false,
689		Range:       ranges.Range{Start: d.Pos(), Len: d.BitsLeft()},
690		FormatInArg: inArg,
691		ReadBuf:     d.readBuf,
692	})
693	if dv == nil || dv.Errors() != nil {
694		d.IOPanic(err, "Format: decode")
695	}
696
697	switch vv := dv.V.(type) {
698	case *Compound:
699		for _, f := range vv.Children {
700			d.AddChild(f)
701		}
702	default:
703		panic("unreachable")
704	}
705
706	if _, err := d.bitBuf.SeekRel(dv.Range.Len); err != nil {
707		d.IOPanic(err, "Format: SeekRel")
708	}
709
710	return v
711}
712
713func (d *D) TryFieldFormat(name string, group Group, inArg interface{}) (*Value, interface{}, error) {
714	dv, v, err := decode(d.Ctx, d.bitBuf, group, Options{
715		Name:        name,
716		Force:       d.Options.Force,
717		FillGaps:    false,
718		IsRoot:      false,
719		Range:       ranges.Range{Start: d.Pos(), Len: d.BitsLeft()},
720		FormatInArg: inArg,
721		ReadBuf:     d.readBuf,
722	})
723	if dv == nil || dv.Errors() != nil {
724		return nil, nil, err
725	}
726
727	d.AddChild(dv)
728	if _, err := d.bitBuf.SeekRel(dv.Range.Len); err != nil {
729		d.IOPanic(err, "TryFieldFormat: SeekRel")
730	}
731
732	return dv, v, err
733}
734
735func (d *D) FieldFormat(name string, group Group, inArg interface{}) (*Value, interface{}) {
736	dv, v, err := d.TryFieldFormat(name, group, inArg)
737	if dv == nil || dv.Errors() != nil {
738		d.IOPanic(err, "FieldFormat: TryFieldFormat")
739	}
740	return dv, v
741}
742
743func (d *D) TryFieldFormatLen(name string, nBits int64, group Group, inArg interface{}) (*Value, interface{}, error) {
744	dv, v, err := decode(d.Ctx, d.bitBuf, group, Options{
745		Name:        name,
746		Force:       d.Options.Force,
747		FillGaps:    true,
748		IsRoot:      false,
749		Range:       ranges.Range{Start: d.Pos(), Len: nBits},
750		FormatInArg: inArg,
751		ReadBuf:     d.readBuf,
752	})
753	if dv == nil || dv.Errors() != nil {
754		return nil, nil, err
755	}
756
757	d.AddChild(dv)
758	if _, err := d.bitBuf.SeekRel(nBits); err != nil {
759		d.IOPanic(err, "TryFieldFormatLen: SeekRel")
760	}
761
762	return dv, v, err
763}
764
765func (d *D) FieldFormatLen(name string, nBits int64, group Group, inArg interface{}) (*Value, interface{}) {
766	dv, v, err := d.TryFieldFormatLen(name, nBits, group, inArg)
767	if dv == nil || dv.Errors() != nil {
768		d.IOPanic(err, "FieldFormatLen: TryFieldFormatLen")
769	}
770	return dv, v
771}
772
773// TODO: return decooder?
774func (d *D) TryFieldFormatRange(name string, firstBit int64, nBits int64, group Group, inArg interface{}) (*Value, interface{}, error) {
775	dv, v, err := decode(d.Ctx, d.bitBuf, group, Options{
776		Name:        name,
777		Force:       d.Options.Force,
778		FillGaps:    true,
779		IsRoot:      false,
780		Range:       ranges.Range{Start: firstBit, Len: nBits},
781		FormatInArg: inArg,
782		ReadBuf:     d.readBuf,
783	})
784	if dv == nil || dv.Errors() != nil {
785		return nil, nil, err
786	}
787
788	d.AddChild(dv)
789
790	return dv, v, err
791}
792
793func (d *D) FieldFormatRange(name string, firstBit int64, nBits int64, group Group, inArg interface{}) (*Value, interface{}) {
794	dv, v, err := d.TryFieldFormatRange(name, firstBit, nBits, group, inArg)
795	if dv == nil || dv.Errors() != nil {
796		d.IOPanic(err, "FieldFormatRange: TryFieldFormatRange")
797	}
798
799	return dv, v
800}
801
802func (d *D) TryFieldFormatBitBuf(name string, bb *bitio.Buffer, group Group, inArg interface{}) (*Value, interface{}, error) {
803	dv, v, err := decode(d.Ctx, bb, group, Options{
804		Name:        name,
805		Force:       d.Options.Force,
806		FillGaps:    true,
807		IsRoot:      true,
808		FormatInArg: inArg,
809		ReadBuf:     d.readBuf,
810	})
811	if dv == nil || dv.Errors() != nil {
812		return nil, nil, err
813	}
814
815	dv.Range.Start = d.Pos()
816
817	d.AddChild(dv)
818
819	return dv, v, err
820}
821
822func (d *D) FieldFormatBitBuf(name string, bb *bitio.Buffer, group Group, inArg interface{}) (*Value, interface{}) {
823	dv, v, err := d.TryFieldFormatBitBuf(name, bb, group, inArg)
824	if dv == nil || dv.Errors() != nil {
825		d.IOPanic(err, "FieldFormatBitBuf: TryFieldFormatBitBuf")
826	}
827
828	return dv, v
829}
830
831// TODO: rethink this
832func (d *D) FieldRootBitBuf(name string, bb *bitio.Buffer) *Value {
833	v := &Value{}
834	v.V = &scalar.S{Actual: bb}
835	v.Name = name
836	v.RootBitBuf = bb
837	v.IsRoot = true
838	v.Range = ranges.Range{Start: d.Pos(), Len: bb.Len()}
839	d.AddChild(v)
840
841	return v
842}
843
844func (d *D) FieldStructRootBitBufFn(name string, bb *bitio.Buffer, fn func(d *D)) *Value {
845	cd := d.FieldDecoder(name, bb, &Compound{})
846	cd.Value.IsRoot = true
847	d.AddChild(cd.Value)
848	fn(cd)
849
850	cd.Value.postProcess()
851
852	return cd.Value
853}
854
855// TODO: range?
856func (d *D) FieldFormatReaderLen(name string, nBits int64, fn func(r io.Reader) (io.ReadCloser, error), group Group) (*Value, interface{}) {
857	bb, err := d.bitBuf.BitBufLen(nBits)
858	if err != nil {
859		d.IOPanic(err, "FieldFormatReaderLen: BitBufLen")
860	}
861	zr, err := fn(bb)
862	if err != nil {
863		d.IOPanic(err, "FieldFormatReaderLen: fn")
864	}
865	zd, err := ioutil.ReadAll(zr)
866	if err != nil {
867		d.IOPanic(err, "FieldFormatReaderLen: ReadAll")
868	}
869	zbb := bitio.NewBufferFromBytes(zd, -1)
870
871	return d.FieldFormatBitBuf(name, zbb, group, nil)
872}
873
874// TODO: too mant return values
875func (d *D) TryFieldReaderRangeFormat(name string, startBit int64, nBits int64, fn func(r io.Reader) io.Reader, group Group, inArg interface{}) (int64, *bitio.Buffer, *Value, interface{}, error) {
876	bitLen := nBits
877	if bitLen == -1 {
878		bitLen = d.BitsLeft()
879	}
880	bb, err := d.bitBuf.BitBufRange(startBit, bitLen)
881	if err != nil {
882		return 0, nil, nil, nil, err
883	}
884	r := fn(bb)
885	// TODO: check if io.Closer?
886	rb, err := ioutil.ReadAll(r)
887	if err != nil {
888		return 0, nil, nil, nil, err
889	}
890	cz, err := bb.Pos()
891	rbb := bitio.NewBufferFromBytes(rb, -1)
892	if err != nil {
893		return 0, nil, nil, nil, err
894	}
895	dv, v, err := d.TryFieldFormatBitBuf(name, rbb, group, inArg)
896
897	return cz, rbb, dv, v, err
898}
899
900func (d *D) FieldReaderRangeFormat(name string, startBit int64, nBits int64, fn func(r io.Reader) io.Reader, group Group, inArg interface{}) (int64, *bitio.Buffer, *Value, interface{}) {
901	cz, rbb, dv, v, err := d.TryFieldReaderRangeFormat(name, startBit, nBits, fn, group, inArg)
902	if err != nil {
903		d.IOPanic(err, "TryFieldReaderRangeFormat")
904	}
905	return cz, rbb, dv, v
906}
907
908func (d *D) TryFieldValue(name string, fn func() (*Value, error)) (*Value, error) {
909	start := d.Pos()
910	v, err := fn()
911	stop := d.Pos()
912	v.Name = name
913	v.RootBitBuf = d.bitBuf
914	v.Range = ranges.Range{Start: start, Len: stop - start}
915	if err != nil {
916		return nil, err
917	}
918	d.AddChild(v)
919
920	return v, err
921}
922
923func (d *D) FieldValue(name string, fn func() *Value) *Value {
924	v, err := d.TryFieldValue(name, func() (*Value, error) { return fn(), nil })
925	if err != nil {
926		d.IOPanic(err, "FieldValue: TryFieldValue")
927	}
928	return v
929}
930
931// looks a bit weird to force at least one ScalarFn arg
932func (d *D) TryFieldScalarFn(name string, sfn scalar.Fn, sms ...scalar.Mapper) (*scalar.S, error) {
933	v, err := d.TryFieldValue(name, func() (*Value, error) {
934		s, err := sfn(scalar.S{})
935		if err != nil {
936			return &Value{V: &s}, err
937		}
938		for _, sm := range sms {
939			s, err = sm.MapScalar(s)
940			if err != nil {
941				return &Value{V: &s}, err
942			}
943		}
944		return &Value{V: &s}, nil
945	})
946	if err != nil {
947		return &scalar.S{}, err
948	}
949	return v.V.(*scalar.S), nil
950}
951
952func (d *D) FieldScalarFn(name string, sfn scalar.Fn, sms ...scalar.Mapper) *scalar.S {
953	v, err := d.TryFieldScalarFn(name, sfn, sms...)
954	if err != nil {
955		d.IOPanic(err, "FieldScalarFn: TryFieldScalarFn")
956	}
957	return v
958}
959
960func (v *Value) TryScalarFn(sms ...scalar.Mapper) error {
961	var err error
962	sr, ok := v.V.(*scalar.S)
963	if !ok {
964		panic("not a scalar value")
965	}
966	s := *sr
967	for _, sm := range sms {
968		s, err = sm.MapScalar(s)
969		if err != nil {
970			break
971		}
972	}
973	v.V = &s
974	return err
975}
976