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