From 473b2243c9e39698e36c51fc8cf1efdda583fc3d Mon Sep 17 00:00:00 2001 From: Mattias Wadman Date: Thu, 16 Sep 2021 15:29:11 +0200 Subject: [PATCH] decode: Simplify and move format arg into DecodeOptions --- format/ape/apev2.go | 2 +- format/av1/av1_frame.go | 2 +- format/bzip2/bzip2.go | 2 +- format/flac/flac.go | 4 +- format/flac/flac_metadatablock.go | 4 +- format/flac/flac_picture.go | 2 +- format/gzip/gzip.go | 2 +- format/id3/id3v2.go | 8 +- format/jpeg/jpeg.go | 4 +- format/matroska/matroska.go | 33 ++++----- format/mp3/mp3.go | 6 +- format/mp4/boxes.go | 34 ++++----- format/mp4/mp4.go | 32 ++++---- format/mpeg/adts.go | 2 +- format/mpeg/adts_frame.go | 4 +- format/mpeg/annexb.go | 2 +- format/mpeg/avc_au.go | 2 +- format/mpeg/avc_dcr.go | 2 +- format/mpeg/avc_nalu.go | 6 +- format/mpeg/hevc_au.go | 2 +- format/mpeg/hevc_dcr.go | 2 +- format/mpeg/mp3_frame.go | 2 +- format/mpeg/mpeg_es.go | 6 +- format/mpeg/mpeg_pes.go | 4 +- format/ogg/ogg.go | 6 +- format/opus/opus_frame.go | 2 +- format/png/png.go | 2 +- format/protobuf/protobuf_widevine.go | 2 +- format/tar/tar.go | 2 +- format/tiff/tiff.go | 2 +- format/vorbis/vorbis_comment.go | 2 +- format/vorbis/vorbis_packet.go | 2 +- format/wav/wav.go | 4 +- format/webp/webp.go | 2 +- pkg/decode/decode.go | 106 ++++++++++++++------------- 35 files changed, 148 insertions(+), 153 deletions(-) diff --git a/format/ape/apev2.go b/format/ape/apev2.go index 29a7547d..ac3a92ea 100644 --- a/format/ape/apev2.go +++ b/format/ape/apev2.go @@ -55,7 +55,7 @@ func apev2Decode(d *decode.D, in interface{}) interface{} { d.DecodeLenFn(int64(itemSize)*8, func(d *decode.D) { d.FieldStrNullTerminated("filename") // assume image if binary - dv, _, _ := d.FieldTryFormat("value", imageFormat) + dv, _, _ := d.FieldTryFormat("value", imageFormat, nil) if dv == nil { // TODO: framed and unknown instead? d.FieldBitBufLen("value", d.BitsLeft()) diff --git a/format/av1/av1_frame.go b/format/av1/av1_frame.go index 144642fa..dca09902 100644 --- a/format/av1/av1_frame.go +++ b/format/av1/av1_frame.go @@ -26,7 +26,7 @@ func init() { func frameDecode(d *decode.D, in interface{}) interface{} { d.FieldArrayFn("frame", func(d *decode.D) { for d.NotEnd() { - d.FieldFormat("obu", obuFormat) + d.FieldFormat("obu", obuFormat, nil) } }) diff --git a/format/bzip2/bzip2.go b/format/bzip2/bzip2.go index ba0a0e46..89d8d483 100644 --- a/format/bzip2/bzip2.go +++ b/format/bzip2/bzip2.go @@ -96,7 +96,7 @@ func gzDecode(d *decode.D, in interface{}) interface{} { } // calculatedCRC32 := crc32W.Sum(nil) uncompressedBB := bitio.NewBufferFromBytes(uncompressed.Bytes(), -1) - dv, _, _ := d.FieldTryFormatBitBuf("uncompressed", uncompressedBB, probeFormat) + dv, _, _ := d.FieldTryFormatBitBuf("uncompressed", uncompressedBB, probeFormat, nil) if dv == nil { d.FieldRootBitBuf("uncompressed", uncompressedBB) } diff --git a/format/flac/flac.go b/format/flac/flac.go index f0bc97cb..85b8971f 100644 --- a/format/flac/flac.go +++ b/format/flac/flac.go @@ -40,7 +40,7 @@ func flacDecode(d *decode.D, in interface{}) interface{} { d.FieldArrayFn("metadatablocks", func(d *decode.D) { for { - _, v := d.FieldFormat("metadatablock", flacMetadatablockFormat) + _, v := d.FieldFormat("metadatablock", flacMetadatablockFormat, nil) flacMetadatablockOut, ok := v.(format.FlacMetadatablockOut) if !ok { panic(fmt.Sprintf("expected FlacMetadatablockOut got %#+v", v)) @@ -60,7 +60,7 @@ func flacDecode(d *decode.D, in interface{}) interface{} { d.FieldArrayFn("frames", func(d *decode.D) { for d.NotEnd() { // flac frame might need some fields from stream info to decode - _, v := d.FieldFormat("frame", flacFrameFormat, decode.FormatOptions{InArg: flacFrameIn}) + _, v := d.FieldFormat("frame", flacFrameFormat, flacFrameIn) ffo, ok := v.(format.FlacFrameOut) if !ok { panic(fmt.Sprintf("expected FlacFrameOut got %#+v", v)) diff --git a/format/flac/flac_metadatablock.go b/format/flac/flac_metadatablock.go index a72ecd9d..4c1b65a1 100644 --- a/format/flac/flac_metadatablock.go +++ b/format/flac/flac_metadatablock.go @@ -83,9 +83,9 @@ func metadatablockDecode(d *decode.D, in interface{}) interface{} { } mb.HasStreamInfo = true case MetadataBlockVorbisComment: - d.FieldFormatLen("comment", int64(length*8), vorbisCommentFormat) + d.FieldFormatLen("comment", int64(length*8), vorbisCommentFormat, nil) case MetadataBlockPicture: - d.FieldFormatLen("picture", int64(length*8), flacPicture) + d.FieldFormatLen("picture", int64(length*8), flacPicture, nil) case MetadataBlockSeektable: seektableCount := length / 18 d.FieldArrayFn("seekpoints", func(d *decode.D) { diff --git a/format/flac/flac_picture.go b/format/flac/flac_picture.go index a990bd96..ab2ebefc 100644 --- a/format/flac/flac_picture.go +++ b/format/flac/flac_picture.go @@ -32,7 +32,7 @@ func pictureDecode(d *decode.D, in interface{}) interface{} { d.FieldU32("color_depth") d.FieldU32("number_of_index_colors") pictureLen := d.FieldU32("picture_length") - d.FieldFormatLen("picture_data", int64(pictureLen)*8, images) + d.FieldFormatLen("picture_data", int64(pictureLen)*8, images, nil) return nil } diff --git a/format/gzip/gzip.go b/format/gzip/gzip.go index 9fb31e8e..92338d73 100644 --- a/format/gzip/gzip.go +++ b/format/gzip/gzip.go @@ -117,7 +117,7 @@ func gzDecode(d *decode.D, in interface{}) interface{} { } calculatedCRC32 = crc32W.Sum(nil) uncompressedBB := bitio.NewBufferFromBytes(uncompressed.Bytes(), -1) - dv, _, _ := d.FieldTryFormatBitBuf("uncompressed", uncompressedBB, probeFormat) + dv, _, _ := d.FieldTryFormatBitBuf("uncompressed", uncompressedBB, probeFormat, nil) if dv == nil { d.FieldRootBitBuf("uncompressed", uncompressedBB) } diff --git a/format/id3/id3v2.go b/format/id3/id3v2.go index 86940183..de0f2abe 100644 --- a/format/id3/id3v2.go +++ b/format/id3/id3v2.go @@ -454,7 +454,7 @@ func decodeFrame(d *decode.D, version int) uint64 { fieldTextNull(d, "mime_type", encodingUTF8) d.FieldU8("picture_type") // TODO: table fieldTextNull(d, "description", int(encoding)) - dv, _, _ := d.FieldTryFormatLen("picture", d.BitsLeft(), imageFormat) + dv, _, _ := d.FieldTryFormatLen("picture", d.BitsLeft(), imageFormat, nil) if dv == nil { d.FieldBitBufLen("picture", d.BitsLeft()) } @@ -471,9 +471,9 @@ func decodeFrame(d *decode.D, version int) uint64 { fieldTextNull(d, "mime_type", encodingUTF8) fieldTextNull(d, "filename", int(encoding)) fieldTextNull(d, "description", int(encoding)) - dv, _, _ := d.FieldTryFormatLen("picture", d.BitsLeft(), imageFormat) + dv, _, _ := d.FieldTryFormatLen("data", d.BitsLeft(), imageFormat, nil) if dv == nil { - d.FieldBitBufLen("picture", d.BitsLeft()) + d.FieldBitBufLen("data", d.BitsLeft()) } }, @@ -569,7 +569,7 @@ func decodeFrame(d *decode.D, version int) uint64 { } return nil - })) + }), nil) d.FieldBitBufLen("data", int64(dataSize*8)) } else { if fn, ok := frames[idNormalized]; ok { diff --git a/format/jpeg/jpeg.go b/format/jpeg/jpeg.go index 8496233e..432b72f9 100644 --- a/format/jpeg/jpeg.go +++ b/format/jpeg/jpeg.go @@ -296,7 +296,7 @@ func jpegDecode(d *decode.D, in interface{}) interface{} { d.FieldBitBufLen("data", int64(xThumbnail*yThumbnail)*3*8) case markerCode == APP1 && d.TryHasBytes(app1ExifPrefix): d.FieldUTF8("exif_prefix", len(app1ExifPrefix)) - d.FieldFormatLen("exif", d.BitsLeft(), exifFormat) + d.FieldFormatLen("exif", d.BitsLeft(), exifFormat, nil) case markerCode == APP1 && d.TryHasBytes(extendedXMPPrefix): d.FieldStructFn("extended_xmp_chunk", func(d *decode.D) { d.FieldUTF8("signature", len(extendedXMPPrefix)) @@ -316,7 +316,7 @@ func jpegDecode(d *decode.D, in interface{}) interface{} { // TODO: support multimarker? d.FieldU8("cur_marker") d.FieldU8("num_markers") - d.FieldFormatLen("icc_profile", d.BitsLeft(), iccProfileFormat) + d.FieldFormatLen("icc_profile", d.BitsLeft(), iccProfileFormat, nil) case markerCode == APP13 && d.TryHasBytes(app13PhotoshopPrefix): d.FieldUTF8("identifier", len(app13PhotoshopPrefix)) signature := d.FieldUTF8("signature", 4) diff --git a/format/matroska/matroska.go b/format/matroska/matroska.go index b6b17c4e..3a524421 100644 --- a/format/matroska/matroska.go +++ b/format/matroska/matroska.go @@ -133,7 +133,7 @@ type track struct { codec string codecPrivatePos int64 codecPrivateTagSize int64 - decodeOpts []decode.Options + formatInArg interface{} } type block struct { @@ -286,7 +286,7 @@ func decodeMaster(d *decode.D, bitsLimit int64, tag ebml.Tag, dc *decodeContext) } d.SeekRel(int64(tagSize) * 8) case ebml_matroska.FileDataID: - d.FieldFormatLen("value", int64(tagSize)*8, imageFormat) + d.FieldFormatLen("value", int64(tagSize)*8, imageFormat, nil) default: d.FieldBitBufLen("value", int64(tagSize)*8) // if tagID == CRC { @@ -357,29 +357,28 @@ func matroskaDecode(d *decode.D, in interface{}) interface{} { }) d.FieldArrayFn("packets", func(d *decode.D) { for _, l := range packetLengths { - d.FieldFormatLen("packet", l*8, vorbisPacketFormat) + d.FieldFormatLen("packet", l*8, vorbisPacketFormat, nil) } - d.FieldFormatLen("packet", d.BitsLeft(), vorbisPacketFormat) + d.FieldFormatLen("packet", d.BitsLeft(), vorbisPacketFormat, nil) }) }) case "A_AAC": - t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, mpegASCFrameFormat) + t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, mpegASCFrameFormat, nil) case "A_OPUS": - t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, opusPacketFrameFormat) + t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, opusPacketFrameFormat, nil) case "A_FLAC": t.parentD.DecodeRangeFn(t.codecPrivatePos, t.codecPrivateTagSize, func(d *decode.D) { d.FieldStructFn("value", func(d *decode.D) { d.FieldValidateUTF8("magic", "fLaC") d.FieldArrayFn("metadatablocks", func(d *decode.D) { for { - _, v := d.FieldFormat("metadatablock", flacMetadatablockFormat) + _, v := d.FieldFormat("metadatablock", flacMetadatablockFormat, nil) flacMetadatablockOut, ok := v.(format.FlacMetadatablockOut) if !ok { d.Invalid(fmt.Sprintf("expected FlacMetadatablockOut got %#+v", v)) } if flacMetadatablockOut.HasStreamInfo { - t.decodeOpts = append(t.decodeOpts, - decode.FormatOptions{InArg: format.FlacFrameIn{StreamInfo: flacMetadatablockOut.StreamInfo}}) + t.formatInArg = format.FlacFrameIn{StreamInfo: flacMetadatablockOut.StreamInfo} } if flacMetadatablockOut.IsLastBlock { return @@ -389,25 +388,23 @@ func matroskaDecode(d *decode.D, in interface{}) interface{} { }) }) case "V_MPEG4/ISO/AVC": - _, v := t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, mpegAVCDCRFormat) + _, v := t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, mpegAVCDCRFormat, nil) avcDcrOut, ok := v.(format.AvcDcrOut) if !ok { d.Invalid(fmt.Sprintf("expected AvcDcrOut got %#+v", v)) } - t.decodeOpts = append(t.decodeOpts, - decode.FormatOptions{InArg: format.AvcIn{LengthSize: avcDcrOut.LengthSize}}) //nolint:gosimple + t.formatInArg = format.AvcIn{LengthSize: avcDcrOut.LengthSize} //nolint:gosimple case "V_MPEGH/ISO/HEVC": - _, v := t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, mpegHEVCDCRFormat) + _, v := t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, mpegHEVCDCRFormat, nil) hevcDcrOut, ok := v.(format.HevcDcrOut) if !ok { d.Invalid(fmt.Sprintf("expected HevcDcrOut got %#+v", v)) } - t.decodeOpts = append(t.decodeOpts, - decode.FormatOptions{InArg: format.HevcIn{LengthSize: hevcDcrOut.LengthSize}}) //nolint:gosimple + t.formatInArg = format.HevcIn{LengthSize: hevcDcrOut.LengthSize} //nolint:gosimple case "V_AV1": - t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, av1CCRFormat) + t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, av1CCRFormat, nil) case "V_VP9": - t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, vp9CFMFormat) + t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, vp9CFMFormat, nil) default: t.parentD.FieldBitBufRange("value", t.codecPrivatePos, t.codecPrivateTagSize) } @@ -438,7 +435,7 @@ func matroskaDecode(d *decode.D, in interface{}) interface{} { // TODO: fixed/unknown? if t, ok := trackNumberToTrack[int(trackNumber)]; ok { if f, ok := codecToFormat[t.codec]; ok { - d.FieldFormat("packet", *f, t.decodeOpts...) + d.FieldFormat("packet", *f, t.formatInArg) } } diff --git a/format/mp3/mp3.go b/format/mp3/mp3.go index 02ee1a34..cf9b5342 100644 --- a/format/mp3/mp3.go +++ b/format/mp3/mp3.go @@ -36,7 +36,7 @@ func mp3Decode(d *decode.D, in interface{}) interface{} { // there are mp3s files in the wild with multiple headers, two id3v2 tags etc d.FieldArrayFn("headers", func(d *decode.D) { for d.NotEnd() { - if dv, _, _ := d.FieldTryFormat("header", headerFormat); dv == nil { + if dv, _, _ := d.FieldTryFormat("header", headerFormat, nil); dv == nil { return } } @@ -59,7 +59,7 @@ func mp3Decode(d *decode.D, in interface{}) interface{} { d.SeekRel(syncLen) } - if dv, _, _ := d.FieldTryFormat("frame", mp3Frame); dv == nil { + if dv, _, _ := d.FieldTryFormat("frame", mp3Frame, nil); dv == nil { decodeFailures++ d.SeekRel(8) continue @@ -77,7 +77,7 @@ func mp3Decode(d *decode.D, in interface{}) interface{} { d.FieldArrayFn("footers", func(d *decode.D) { for d.NotEnd() { - if dv, _, _ := d.FieldTryFormat("footer", footerFormat); dv == nil { + if dv, _, _ := d.FieldTryFormat("footer", footerFormat, nil); dv == nil { return } } diff --git a/format/mp4/boxes.go b/format/mp4/boxes.go index 36233d74..519d035d 100644 --- a/format/mp4/boxes.go +++ b/format/mp4/boxes.go @@ -432,25 +432,23 @@ func init() { }) }, "avcC": func(ctx *decodeContext, d *decode.D) { - _, v := d.FieldFormat("value", mpegAVCDCRFormat) + _, v := d.FieldFormat("value", mpegAVCDCRFormat, nil) avcDcrOut, ok := v.(format.AvcDcrOut) if !ok { d.Invalid(fmt.Sprintf("expected AvcDcrOut got %#+v", v)) } if ctx.currentTrack != nil { - ctx.currentTrack.decodeOpts = append(ctx.currentTrack.decodeOpts, - decode.FormatOptions{InArg: format.AvcIn{LengthSize: avcDcrOut.LengthSize}}) //nolint:gosimple + ctx.currentTrack.formatInArg = format.AvcIn{LengthSize: avcDcrOut.LengthSize} //nolint:gosimple } }, "hvcC": func(ctx *decodeContext, d *decode.D) { - _, v := d.FieldFormat("value", mpegHEVCDCRFrameFormat) + _, v := d.FieldFormat("value", mpegHEVCDCRFrameFormat, nil) hevcDcrOut, ok := v.(format.HevcDcrOut) if !ok { d.Invalid(fmt.Sprintf("expected HevcDcrOut got %#+v", v)) } if ctx.currentTrack != nil { - ctx.currentTrack.decodeOpts = append(ctx.currentTrack.decodeOpts, - decode.FormatOptions{InArg: format.HevcIn{LengthSize: hevcDcrOut.LengthSize}}) //nolint:gosimple + ctx.currentTrack.formatInArg = format.HevcIn{LengthSize: hevcDcrOut.LengthSize} //nolint:gosimple } }, "dfLa": func(ctx *decodeContext, d *decode.D) { @@ -458,15 +456,14 @@ func init() { d.FieldU24("flags") d.FieldArrayFn("metadatablocks", func(d *decode.D) { for { - _, v := d.FieldFormat("metadatablock", flacMetadatablockFormat) + _, v := d.FieldFormat("metadatablock", flacMetadatablockFormat, nil) flacMetadatablockOut, ok := v.(format.FlacMetadatablockOut) if !ok { d.Invalid(fmt.Sprintf("expected FlacMetadatablockOut got %#+v", v)) } if flacMetadatablockOut.HasStreamInfo { if ctx.currentTrack != nil { - ctx.currentTrack.decodeOpts = append(ctx.currentTrack.decodeOpts, - decode.FormatOptions{InArg: format.FlacFrameIn{StreamInfo: flacMetadatablockOut.StreamInfo}}) + ctx.currentTrack.formatInArg = format.FlacFrameIn{StreamInfo: flacMetadatablockOut.StreamInfo} } } if flacMetadatablockOut.IsLastBlock { @@ -476,20 +473,20 @@ func init() { }) }, "dOps": func(_ *decodeContext, d *decode.D) { - d.FieldFormat("value", opusPacketFrameFormat) + d.FieldFormat("value", opusPacketFrameFormat, nil) }, "av1C": func(_ *decodeContext, d *decode.D) { - d.FieldFormat("value", av1CCRFormat) + d.FieldFormat("value", av1CCRFormat, nil) }, "vpcC": func(_ *decodeContext, d *decode.D) { d.FieldU8("version") d.FieldU24("flags") - d.FieldFormat("value", vpxCCRFormat) + d.FieldFormat("value", vpxCCRFormat, nil) }, "esds": func(ctx *decodeContext, d *decode.D) { d.FieldU32("version") - _, v := d.FieldFormat("es_descriptor", mpegESFormat) + _, v := d.FieldFormat("es_descriptor", mpegESFormat, nil) mpegEsOut, ok := v.(format.MpegEsOut) if !ok { d.Invalid(fmt.Sprintf("expected mpegEsOut got %#+v", v)) @@ -498,8 +495,7 @@ func init() { if ctx.currentTrack != nil && len(mpegEsOut.DecoderConfigs) > 0 { dc := mpegEsOut.DecoderConfigs[0] ctx.currentTrack.objectType = dc.ObjectType - ctx.currentTrack.decodeOpts = append(ctx.currentTrack.decodeOpts, - decode.FormatOptions{InArg: format.AACFrameIn{ObjectType: dc.ASCObjectType}}) + ctx.currentTrack.formatInArg = format.AACFrameIn{ObjectType: dc.ASCObjectType} } }, "stts": func(_ *decodeContext, d *decode.D) { @@ -671,7 +667,7 @@ func init() { d.FieldU24("flags") d.FieldU32("reserved") if isParent(ctx, "covr") { - dv, _, _ := d.FieldTryFormatLen("data", d.BitsLeft(), imageFormat) + dv, _, _ := d.FieldTryFormatLen("data", d.BitsLeft(), imageFormat, nil) if dv == nil { d.FieldBitBufLen("data", d.BitsLeft()) } @@ -938,7 +934,7 @@ func init() { } return s, "" }) - d.FieldFormat("data", id3v2Format) + d.FieldFormat("data", id3v2Format, nil) }, "mehd": func(_ *decodeContext, d *decode.D) { d.FieldU8("version") @@ -978,9 +974,9 @@ func init() { switch { case bytes.Equal(systemID, systemIDWidevine[:]): - d.FieldFormatLen("data", int64(dataLen)*8, protoBufWidevineFormat) + d.FieldFormatLen("data", int64(dataLen)*8, protoBufWidevineFormat, nil) case bytes.Equal(systemID, systemIDPlayReady[:]): - d.FieldFormatLen("data", int64(dataLen)*8, psshPlayreadyFormat) + d.FieldFormatLen("data", int64(dataLen)*8, psshPlayreadyFormat, nil) case systemID == nil: fallthrough default: diff --git a/format/mp4/mp4.go b/format/mp4/mp4.go index 2f1f95c7..69394981 100644 --- a/format/mp4/mp4.go +++ b/format/mp4/mp4.go @@ -107,7 +107,7 @@ type track struct { stco []uint64 // stsc []stsc stsz []uint32 - decodeOpts []decode.Options + formatInArg interface{} objectType int // if data format is "mp4a" moofs []*moof // for fmp4 @@ -156,43 +156,43 @@ func mp4Decode(d *decode.D, in interface{}) interface{} { d.FieldArrayFn("tracks", func(d *decode.D) { for _, t := range sortedTracks { - decodeSampleRange := func(d *decode.D, t *track, dataFormat string, name string, firstBit int64, nBits int64, opts ...decode.Options) { + decodeSampleRange := func(d *decode.D, t *track, dataFormat string, name string, firstBit int64, nBits int64, inArg interface{}) { switch dataFormat { case "fLaC": - d.FieldFormatRange(name, firstBit, nBits, flacFrameFormat, opts...) + d.FieldFormatRange(name, firstBit, nBits, flacFrameFormat, inArg) case "Opus": - d.FieldFormatRange(name, firstBit, nBits, opusPacketFrameFormat, opts...) + d.FieldFormatRange(name, firstBit, nBits, opusPacketFrameFormat, inArg) case "vp09": - d.FieldFormatRange(name, firstBit, nBits, vp9FrameFormat, opts...) + d.FieldFormatRange(name, firstBit, nBits, vp9FrameFormat, inArg) case "avc1": - d.FieldFormatRange(name, firstBit, nBits, mpegAVCAUFormat, opts...) + d.FieldFormatRange(name, firstBit, nBits, mpegAVCAUFormat, inArg) case "hev1", "hvc1": - d.FieldFormatRange(name, firstBit, nBits, mpegHEVCSampleFormat, opts...) + d.FieldFormatRange(name, firstBit, nBits, mpegHEVCSampleFormat, inArg) case "av01": - d.FieldFormatRange(name, firstBit, nBits, av1FrameFormat, opts...) + d.FieldFormatRange(name, firstBit, nBits, av1FrameFormat, inArg) case "mp4a": switch t.objectType { case format.MPEGObjectTypeMP3: - d.FieldFormatRange(name, firstBit, nBits, mp3FrameFormat, opts...) + d.FieldFormatRange(name, firstBit, nBits, mp3FrameFormat, inArg) case format.MPEGObjectTypeAAC: // TODO: MPEGObjectTypeAACLow, Main etc? - d.FieldFormatRange(name, firstBit, nBits, aacFrameFormat, opts...) + d.FieldFormatRange(name, firstBit, nBits, aacFrameFormat, inArg) case format.MPEGObjectTypeVORBIS: - d.FieldFormatRange(name, firstBit, nBits, vorbisPacketFormat, opts...) + d.FieldFormatRange(name, firstBit, nBits, vorbisPacketFormat, inArg) default: d.FieldBitBufRange(name, firstBit, nBits) } case "mp4v": switch t.objectType { case format.MPEGObjectTypeMPEG2VideoMain: - d.FieldFormatRange(name, firstBit, nBits, mpegPESPacketSampleFormat, opts...) + d.FieldFormatRange(name, firstBit, nBits, mpegPESPacketSampleFormat, inArg) case format.MPEGObjectTypeMJPEG: - d.FieldFormatRange(name, firstBit, nBits, jpegFormat, opts...) + d.FieldFormatRange(name, firstBit, nBits, jpegFormat, inArg) default: d.FieldBitBufRange(name, firstBit, nBits) } case "jpeg": - d.FieldFormatRange(name, firstBit, nBits, jpegFormat, opts...) + d.FieldFormatRange(name, firstBit, nBits, jpegFormat, inArg) default: d.FieldBitBufRange(name, firstBit, nBits) } @@ -234,7 +234,7 @@ func mp4Decode(d *decode.D, in interface{}) interface{} { } sampleSize := t.stsz[sampleNr] - decodeSampleRange(d, t, trackSdDataFormat, "sample", int64(sampleOffset)*8, int64(sampleSize)*8, t.decodeOpts...) + decodeSampleRange(d, t, trackSdDataFormat, "sample", int64(sampleOffset)*8, int64(sampleSize)*8, t.formatInArg) // log.Printf("%s %d/%d %d/%d sample=%d/%d chunk=%d size=%d %d-%d\n", // trackSdDataFormat, stscIndex, len(t.stsc), @@ -272,7 +272,7 @@ func mp4Decode(d *decode.D, in interface{}) interface{} { // log.Printf("moof %#+v dataFormat: %#+v\n", m, dataFormat) - decodeSampleRange(d, t, dataFormat, "sample", sampleOffset*8, int64(sz)*8, t.decodeOpts...) + decodeSampleRange(d, t, dataFormat, "sample", sampleOffset*8, int64(sz)*8, t.formatInArg) sampleOffset += int64(sz) } } diff --git a/format/mpeg/adts.go b/format/mpeg/adts.go index 10cf0c94..bd25bc1d 100644 --- a/format/mpeg/adts.go +++ b/format/mpeg/adts.go @@ -24,7 +24,7 @@ func adtsDecoder(d *decode.D, in interface{}) interface{} { validFrames := 0 d.FieldArrayFn("frames", func(d *decode.D) { for !d.End() { - if dv, _, _ := d.FieldTryFormat("frame", adtsFrame); dv == nil { + if dv, _, _ := d.FieldTryFormat("frame", adtsFrame, nil); dv == nil { break } validFrames++ diff --git a/format/mpeg/adts_frame.go b/format/mpeg/adts_frame.go index 2dcd1631..b0f968e0 100644 --- a/format/mpeg/adts_frame.go +++ b/format/mpeg/adts_frame.go @@ -95,9 +95,7 @@ func adtsFrameDecoder(d *decode.D, in interface{}) interface{} { d.FieldArrayFn("raw_data_blocks", func(d *decode.D) { for i := uint64(0); i < numberOfRDBs; i++ { - d.FieldFormatLen("raw_data_block", int64(dataLength)*8, aacFrameFormat, decode.FormatOptions{ - InArg: format.AACFrameIn{ObjectType: int(objectType)}}, - ) + d.FieldFormatLen("raw_data_block", int64(dataLength)*8, aacFrameFormat, format.AACFrameIn{ObjectType: int(objectType)}) } }) diff --git a/format/mpeg/annexb.go b/format/mpeg/annexb.go index 8d818de9..237f2231 100644 --- a/format/mpeg/annexb.go +++ b/format/mpeg/annexb.go @@ -40,7 +40,7 @@ func annexBDecode(d *decode.D, _ interface{}, format []*decode.Format) interface } naluLen := nextOffset - d.FieldFormatLen("nalu", naluLen, format) + d.FieldFormatLen("nalu", naluLen, format, nil) currentPrefixLen = nextPrefixLen } diff --git a/format/mpeg/avc_au.go b/format/mpeg/avc_au.go index 8aac20c6..96fbe28b 100644 --- a/format/mpeg/avc_au.go +++ b/format/mpeg/avc_au.go @@ -31,7 +31,7 @@ func avcAUDecode(d *decode.D, in interface{}) interface{} { for d.NotEnd() { d.FieldStructFn("nalu", func(d *decode.D) { l := d.FieldU("length", int(avcIn.LengthSize)*8) - d.FieldFormatLen("nalu", int64(l)*8, avcNALUFormat) + d.FieldFormatLen("nalu", int64(l)*8, avcNALUFormat, nil) }) } }) diff --git a/format/mpeg/avc_dcr.go b/format/mpeg/avc_dcr.go index e230cab3..04cd2c9c 100644 --- a/format/mpeg/avc_dcr.go +++ b/format/mpeg/avc_dcr.go @@ -110,7 +110,7 @@ func avcDcrParameterSet(d *decode.D, numParamSets uint64) { for i := uint64(0); i < numParamSets; i++ { d.FieldStructFn("set", func(d *decode.D) { paramSetLen := d.FieldU16("length") - d.FieldFormatLen("nal", int64(paramSetLen)*8, avcDCRNALFormat) + d.FieldFormatLen("nal", int64(paramSetLen)*8, avcDCRNALFormat, nil) }) } } diff --git a/format/mpeg/avc_nalu.go b/format/mpeg/avc_nalu.go index 578c3b36..3a10bd24 100644 --- a/format/mpeg/avc_nalu.go +++ b/format/mpeg/avc_nalu.go @@ -129,11 +129,11 @@ func avcNALUDecode(d *decode.D, in interface{}) interface{} { // TODO: if ( separate_colour_plane_flag from SPS ) colour_plane_id; frame_num }) case avcNALSupplementalEnhancementInformation: - d.FieldFormatBitBuf("sei", unescapedBb, avcSEIFormat) + d.FieldFormatBitBuf("sei", unescapedBb, avcSEIFormat, nil) case avcNALSequenceParameterSet: - d.FieldFormatBitBuf("sps", unescapedBb, avcSPSFormat) + d.FieldFormatBitBuf("sps", unescapedBb, avcSPSFormat, nil) case avcNALPictureParameterSet: - d.FieldFormatBitBuf("pps", unescapedBb, avcPPSFormat) + d.FieldFormatBitBuf("pps", unescapedBb, avcPPSFormat, nil) } d.FieldBitBufLen("data", d.BitsLeft()) diff --git a/format/mpeg/hevc_au.go b/format/mpeg/hevc_au.go index a42202bf..d89e2d99 100644 --- a/format/mpeg/hevc_au.go +++ b/format/mpeg/hevc_au.go @@ -29,7 +29,7 @@ func hevcAUDecode(d *decode.D, in interface{}) interface{} { for d.NotEnd() { d.FieldStructFn("nalu", func(d *decode.D) { l := d.FieldU("length", int(hevcIn.LengthSize)*8) - d.FieldFormatLen("nalu", int64(l)*8, hevcAUNALFormat) + d.FieldFormatLen("nalu", int64(l)*8, hevcAUNALFormat, nil) }) } }) diff --git a/format/mpeg/hevc_dcr.go b/format/mpeg/hevc_dcr.go index b5ddcadf..35b7b186 100644 --- a/format/mpeg/hevc_dcr.go +++ b/format/mpeg/hevc_dcr.go @@ -54,7 +54,7 @@ func hevcDcrDecode(d *decode.D, in interface{}) interface{} { for i := uint64(0); i < numNals; i++ { d.FieldStructFn("nal", func(d *decode.D) { nalUnitLength := int64(d.FieldU16("nal_unit_length")) - d.FieldFormatLen("nal", nalUnitLength*8, hevcDCRNALFormat) + d.FieldFormatLen("nal", nalUnitLength*8, hevcDCRNALFormat, nil) }) } }) diff --git a/format/mpeg/mp3_frame.go b/format/mpeg/mp3_frame.go index 43cfe938..42dcd6b9 100644 --- a/format/mpeg/mp3_frame.go +++ b/format/mpeg/mp3_frame.go @@ -321,7 +321,7 @@ func frameDecode(d *decode.D, in interface{}) interface{} { calcFrameBytes := int64(144*bitRate/sampleRate + paddingBytes) dataWithPaddingBytes := calcFrameBytes - headerBytes - crcBytes - sideInfoBytes - if dv, _, _ := d.FieldTryFormat("xing", xingHeader); dv != nil { + if dv, _, _ := d.FieldTryFormat("xing", xingHeader, nil); dv != nil { // TODO: allow shorter? paddingBytes := dataWithPaddingBytes - dv.Range.Len/8 d.FieldBitBufLen("padding", paddingBytes*8) diff --git a/format/mpeg/mpeg_es.go b/format/mpeg/mpeg_es.go index fb430dfd..4a856f30 100644 --- a/format/mpeg/mpeg_es.go +++ b/format/mpeg/mpeg_es.go @@ -238,16 +238,16 @@ func odDecodeTag(d *decode.D, edc *esDecodeContext, expectedTagID int, fn func(d }) d.FieldArrayFn("packets", func(d *decode.D) { for _, l := range packetLengths { - d.FieldFormatLen("packet", l*8, vorbisPacketFormat) + d.FieldFormatLen("packet", l*8, vorbisPacketFormat, nil) } - d.FieldFormatLen("packet", d.BitsLeft(), vorbisPacketFormat) + d.FieldFormatLen("packet", d.BitsLeft(), vorbisPacketFormat, nil) }) }) default: switch format.MpegObjectTypeStreamType[objectType] { case format.MPEGStreamTypeAudio: fieldODDecodeTag(d, edc, "decoder_specific_info", -1, func(d *decode.D) { - _, v := d.FieldFormat("audio_specific_config", mpegASCFormat) + _, v := d.FieldFormat("audio_specific_config", mpegASCFormat, nil) mpegASCout, ok := v.(format.MPEGASCOut) if !ok { panic(fmt.Sprintf("expected MPEGASCOut got %#+v", v)) diff --git a/format/mpeg/mpeg_pes.go b/format/mpeg/mpeg_pes.go index b3acd059..fc67bcf8 100644 --- a/format/mpeg/mpeg_pes.go +++ b/format/mpeg/mpeg_pes.go @@ -47,7 +47,7 @@ func pesDecode(d *decode.D, in interface{}) interface{} { d.FieldArrayFn("packets", func(d *decode.D) { for d.NotEnd() { - dv, v, err := d.FieldTryFormat("packet", pesPacketFormat) + dv, v, err := d.FieldTryFormat("packet", pesPacketFormat, nil) if dv == nil || err != nil { log.Printf("errs[0]: %#+v\n", err) break @@ -70,7 +70,7 @@ func pesDecode(d *decode.D, in interface{}) interface{} { // TODO: is this how spu end is signalled? if s.l == len(s.b) { - spuD.FieldFormatBitBuf("spu", bitio.NewBufferFromBytes(s.b, -1), spuFormat) + spuD.FieldFormatBitBuf("spu", bitio.NewBufferFromBytes(s.b, -1), spuFormat, nil) s.b = nil s.l = 0 } diff --git a/format/ogg/ogg.go b/format/ogg/ogg.go index 5cf46406..2e8b0b93 100644 --- a/format/ogg/ogg.go +++ b/format/ogg/ogg.go @@ -57,7 +57,7 @@ func decodeOgg(d *decode.D, in interface{}) interface{} { d.FieldArrayFn("pages", func(d *decode.D) { for !d.End() { - _, dv, _ := d.FieldTryFormat("page", oggPage) + _, dv, _ := d.FieldTryFormat("page", oggPage, nil) if dv == nil { break } @@ -119,10 +119,10 @@ func decodeOgg(d *decode.D, in interface{}) interface{} { switch s.codec { case codecVorbis: // TODO: err - _, _, _ = s.packetD.FieldTryFormatBitBuf("packet", bb, vorbisPacket) + _, _, _ = s.packetD.FieldTryFormatBitBuf("packet", bb, vorbisPacket, nil) case codecOpus: // TODO: err - _, _, _ = s.packetD.FieldTryFormatBitBuf("packet", bb, opusPacket) + _, _, _ = s.packetD.FieldTryFormatBitBuf("packet", bb, opusPacket, nil) case codecUnknown: s.packetD.FieldBitBuf("packet", bb) } diff --git a/format/opus/opus_frame.go b/format/opus/opus_frame.go index c57a7e26..a398786b 100644 --- a/format/opus/opus_frame.go +++ b/format/opus/opus_frame.go @@ -49,7 +49,7 @@ func opusDecode(d *decode.D, in interface{}) interface{} { case bytes.Equal(prefix, []byte("OpusTags")): d.FieldValueStr("type", "tags", "") d.FieldUTF8("prefix", 8) - d.FieldFormat("comment", vorbisComment) + d.FieldFormat("comment", vorbisComment, nil) default: d.FieldValueStr("type", "audio", "") d.FieldStructFn("toc", func(d *decode.D) { diff --git a/format/png/png.go b/format/png/png.go index 1b6d3194..eaa25fa0 100644 --- a/format/png/png.go +++ b/format/png/png.go @@ -162,7 +162,7 @@ func pngDecode(d *decode.D, in interface{}) interface{} { d.FieldFloatFn("blue_x", df) d.FieldFloatFn("blue_y", df) case "eXIf": - d.FieldFormatLen("exif", int64(chunkLength)*8, exifFormat) + d.FieldFormatLen("exif", int64(chunkLength)*8, exifFormat, nil) case "acTL": d.FieldU32("num_frames") d.FieldU32("num_plays") diff --git a/format/protobuf/protobuf_widevine.go b/format/protobuf/protobuf_widevine.go index 90479673..6a616a43 100644 --- a/format/protobuf/protobuf_widevine.go +++ b/format/protobuf/protobuf_widevine.go @@ -41,7 +41,7 @@ func widevineDecode(d *decode.D, in interface{}) interface{} { }}, } - d.Format(widevineProtoBufFormat, decode.FormatOptions{InArg: format.ProtoBufIn{Message: widewinePb}}) + d.Format(widevineProtoBufFormat, format.ProtoBufIn{Message: widewinePb}) return nil } diff --git a/format/tar/tar.go b/format/tar/tar.go index a1660657..12f01a30 100644 --- a/format/tar/tar.go +++ b/format/tar/tar.go @@ -88,7 +88,7 @@ func tarDecode(d *decode.D, in interface{}) interface{} { fieldStr(d, "prefix", 155) fieldBlockPadding(d, "header_block_padding") if size > 0 { - dv, _, _ := d.FieldTryFormatLen("data", int64(size)*8, probeFormat) + dv, _, _ := d.FieldTryFormatLen("data", int64(size)*8, probeFormat, nil) if dv == nil { d.FieldBitBufLen("data", int64(size)*8) } diff --git a/format/tiff/tiff.go b/format/tiff/tiff.go index 479fe1d7..015aa8f9 100644 --- a/format/tiff/tiff.go +++ b/format/tiff/tiff.go @@ -137,7 +137,7 @@ func decodeIfd(d *decode.D, s *strips, tagNames map[uint64]string) int64 { case typ == UNDEFINED: switch tag { case InterColorProfile: - d.FieldFormatRange("icc", int64(valueByteOffset)*8, int64(valueByteSize)*8, tiffIccProfile) + d.FieldFormatRange("icc", int64(valueByteOffset)*8, int64(valueByteSize)*8, tiffIccProfile, nil) default: // log.Printf("tag: %#+v\n", tag) // log.Printf("valueByteSize: %#+v\n", valueByteSize) diff --git a/format/vorbis/vorbis_comment.go b/format/vorbis/vorbis_comment.go index b646faed..cb769be1 100644 --- a/format/vorbis/vorbis_comment.go +++ b/format/vorbis/vorbis_comment.go @@ -40,7 +40,7 @@ func commentDecode(d *decode.D, in interface{}) interface{} { bs, err := base64.StdEncoding.DecodeString(v) if err == nil { bb := bitio.NewBufferFromBytes(bs, -1) - d.FieldFormatBitBuf("picture", bb, flacPicture) + d.FieldFormatBitBuf("picture", bb, flacPicture, nil) } else { panic(err) } diff --git a/format/vorbis/vorbis_packet.go b/format/vorbis/vorbis_packet.go index 249f9bb7..437cf3ed 100644 --- a/format/vorbis/vorbis_packet.go +++ b/format/vorbis/vorbis_packet.go @@ -119,7 +119,7 @@ func vorbisDecode(d *decode.D, in interface{}) interface{} { // } case packetTypeComment: - d.FieldFormat("comment", vorbisComment) + d.FieldFormat("comment", vorbisComment, nil) // note this uses vorbis bitpacking convention, bits are added LSB first per byte d.FieldValidateZeroPadding("padding0", 7) diff --git a/format/wav/wav.go b/format/wav/wav.go index 2b58022d..4b1cfb17 100644 --- a/format/wav/wav.go +++ b/format/wav/wav.go @@ -196,11 +196,11 @@ func decodeChunks(d *decode.D, stringData bool) { func wavDecode(d *decode.D, in interface{}) interface{} { // there are wav files in the wild with id3v2 header id3v1 footer - _, _, _ = d.FieldTryFormat("header", headerFormat) + _, _, _ = d.FieldTryFormat("header", headerFormat, nil) decodeChunk(d, "RIFF", false) - _, _, _ = d.FieldTryFormat("footer", footerFormat) + _, _, _ = d.FieldTryFormat("footer", footerFormat, nil) return nil } diff --git a/format/webp/webp.go b/format/webp/webp.go index 78a6d629..79e2973c 100644 --- a/format/webp/webp.go +++ b/format/webp/webp.go @@ -57,7 +57,7 @@ func webpDecode(d *decode.D, in interface{}) interface{} { case bytes.Equal(p, []byte("VP8 ")): d.FieldStructFn("image", func(d *decode.D) { decodeChunk(d, "VP8", func(d *decode.D) { - d.Format(vp8Frame) + d.Format(vp8Frame, nil) }) }) case bytes.Equal(p, []byte("VP8L")): diff --git a/pkg/decode/decode.go b/pkg/decode/decode.go index 327a5580..e4c24af6 100644 --- a/pkg/decode/decode.go +++ b/pkg/decode/decode.go @@ -112,47 +112,28 @@ type DecodeOptions struct { func (DecodeOptions) decodeOptions() {} -type FormatOptions struct { - InArg interface{} -} - -func (FormatOptions) decodeOptions() {} - // Decode try decode formats and return first success and all other decoder errors -func Decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts ...Options) (*Value, interface{}, error) { - opts = append(opts, DecodeOptions{IsRoot: true}) +func Decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts DecodeOptions) (*Value, interface{}, error) { + opts.IsRoot = true return decode(ctx, bb, formats, opts) } -func decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts []Options) (*Value, interface{}, error) { +func decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts DecodeOptions) (*Value, interface{}, error) { if formats == nil { panic("formats is nil, failed to register format?") } var forceOne = len(formats) == 1 - var decodeOpts DecodeOptions - var formatOpts FormatOptions - for _, opts := range opts { - switch opt := opts.(type) { - case DecodeOptions: - decodeOpts = opt - case FormatOptions: - formatOpts = opt - default: - panic(fmt.Sprintf("unknown decode option %#+v", opts)) - } - } - decodeErr := DecodeFormatsError{} for _, f := range formats { - d := NewDecoder(ctx, f, bb, decodeOpts) + d := NewDecoder(ctx, f, bb, opts) var decodeV interface{} r, rOk := recoverfn.Run(func() { - decodeV = f.DecodeFn(d, formatOpts.InArg) + decodeV = f.DecodeFn(d, opts.FormatInArg) }) if ctx != nil && ctx.Err() != nil { @@ -187,16 +168,16 @@ func decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts []Opt } maxRange = ranges.MinMax(maxRange, v.Range) - v.Range.Start += decodeOpts.StartOffset + v.Range.Start += opts.StartOffset v.RootBitBuf = d.Value.RootBitBuf return nil }); err != nil { return nil, nil, err } - d.Value.Range = ranges.Range{Start: decodeOpts.StartOffset, Len: maxRange.Len} + d.Value.Range = ranges.Range{Start: opts.StartOffset, Len: maxRange.Len} - if decodeOpts.IsRoot { + if opts.IsRoot { d.FillGaps("unknown") // sort and set ranges for struct and arrays @@ -863,10 +844,14 @@ func (d *D) DecodeRangeFn(firstBit int64, nBits int64, fn func(d *D)) { } } -func (d *D) Format(formats []*Format, opts ...Options) interface{} { +func (d *D) Format(formats []*Format, inArg interface{}) interface{} { bb := d.BitBufRange(d.Pos(), d.BitsLeft()) - opts = append(opts, DecodeOptions{ReadBuf: d.readBuf, IsRoot: false, StartOffset: d.Pos()}) - dv, v, err := decode(d.Ctx, bb, formats, opts) + dv, v, err := decode(d.Ctx, bb, formats, DecodeOptions{ + ReadBuf: d.readBuf, + IsRoot: false, + StartOffset: d.Pos(), + FormatInArg: inArg, + }) if dv == nil || dv.Errors() != nil { panic(err) } @@ -891,10 +876,15 @@ func (d *D) Format(formats []*Format, opts ...Options) interface{} { return v } -func (d *D) FieldTryFormat(name string, formats []*Format, opts ...Options) (*Value, interface{}, error) { +func (d *D) FieldTryFormat(name string, formats []*Format, inArg interface{}) (*Value, interface{}, error) { bb := d.BitBufRange(d.Pos(), d.BitsLeft()) - opts = append(opts, DecodeOptions{Name: name, ReadBuf: d.readBuf, IsRoot: false, StartOffset: d.Pos()}) - dv, v, err := decode(d.Ctx, bb, formats, opts) + dv, v, err := decode(d.Ctx, bb, formats, DecodeOptions{ + Name: name, + ReadBuf: d.readBuf, + IsRoot: false, + StartOffset: d.Pos(), + FormatInArg: inArg, + }) if dv == nil || dv.Errors() != nil { return nil, nil, err } @@ -907,18 +897,23 @@ func (d *D) FieldTryFormat(name string, formats []*Format, opts ...Options) (*Va return dv, v, err } -func (d *D) FieldFormat(name string, formats []*Format, opts ...Options) (*Value, interface{}) { - dv, v, err := d.FieldTryFormat(name, formats, opts...) +func (d *D) FieldFormat(name string, formats []*Format, inArg interface{}) (*Value, interface{}) { + dv, v, err := d.FieldTryFormat(name, formats, inArg) if dv == nil || dv.Errors() != nil { panic(err) } return dv, v } -func (d *D) FieldTryFormatLen(name string, nBits int64, formats []*Format, opts ...Options) (*Value, interface{}, error) { +func (d *D) FieldTryFormatLen(name string, nBits int64, formats []*Format, inArg interface{}) (*Value, interface{}, error) { bb := d.BitBufRange(d.Pos(), nBits) - opts = append(opts, DecodeOptions{Name: name, ReadBuf: d.readBuf, IsRoot: false, StartOffset: d.Pos()}) - dv, v, err := decode(d.Ctx, bb, formats, opts) + dv, v, err := decode(d.Ctx, bb, formats, DecodeOptions{ + Name: name, + ReadBuf: d.readBuf, + IsRoot: false, + StartOffset: d.Pos(), + FormatInArg: inArg, + }) if dv == nil || dv.Errors() != nil { return nil, nil, err } @@ -931,8 +926,8 @@ func (d *D) FieldTryFormatLen(name string, nBits int64, formats []*Format, opts return dv, v, err } -func (d *D) FieldFormatLen(name string, nBits int64, formats []*Format, opts ...Options) (*Value, interface{}) { - dv, v, err := d.FieldTryFormatLen(name, nBits, formats, opts...) +func (d *D) FieldFormatLen(name string, nBits int64, formats []*Format, inArg interface{}) (*Value, interface{}) { + dv, v, err := d.FieldTryFormatLen(name, nBits, formats, inArg) if dv == nil || dv.Errors() != nil { panic(err) } @@ -940,10 +935,15 @@ func (d *D) FieldFormatLen(name string, nBits int64, formats []*Format, opts ... } // TODO: return decooder? -func (d *D) FieldTryFormatRange(name string, firstBit int64, nBits int64, formats []*Format, opts ...Options) (*Value, interface{}, error) { +func (d *D) FieldTryFormatRange(name string, firstBit int64, nBits int64, formats []*Format, inArg interface{}) (*Value, interface{}, error) { bb := d.BitBufRange(firstBit, nBits) - opts = append(opts, DecodeOptions{Name: name, ReadBuf: d.readBuf, IsRoot: false, StartOffset: firstBit}) - dv, v, err := decode(d.Ctx, bb, formats, opts) + dv, v, err := decode(d.Ctx, bb, formats, DecodeOptions{ + Name: name, + ReadBuf: d.readBuf, + IsRoot: false, + StartOffset: firstBit, + FormatInArg: inArg, + }) if dv == nil || dv.Errors() != nil { return nil, nil, err } @@ -953,8 +953,8 @@ func (d *D) FieldTryFormatRange(name string, firstBit int64, nBits int64, format return dv, v, err } -func (d *D) FieldFormatRange(name string, firstBit int64, nBits int64, formats []*Format, opts ...Options) (*Value, interface{}) { - dv, v, err := d.FieldTryFormatRange(name, firstBit, nBits, formats, opts...) +func (d *D) FieldFormatRange(name string, firstBit int64, nBits int64, formats []*Format, inArg interface{}) (*Value, interface{}) { + dv, v, err := d.FieldTryFormatRange(name, firstBit, nBits, formats, inArg) if dv == nil || dv.Errors() != nil { panic(err) } @@ -962,9 +962,13 @@ func (d *D) FieldFormatRange(name string, firstBit int64, nBits int64, formats [ return dv, v } -func (d *D) FieldTryFormatBitBuf(name string, bb *bitio.Buffer, formats []*Format, opts ...Options) (*Value, interface{}, error) { - opts = append(opts, DecodeOptions{Name: name, ReadBuf: d.readBuf, IsRoot: true}) - dv, v, err := decode(d.Ctx, bb, formats, opts) +func (d *D) FieldTryFormatBitBuf(name string, bb *bitio.Buffer, formats []*Format, inArg interface{}) (*Value, interface{}, error) { + dv, v, err := decode(d.Ctx, bb, formats, DecodeOptions{ + Name: name, + ReadBuf: d.readBuf, + IsRoot: true, + FormatInArg: inArg, + }) if dv == nil || dv.Errors() != nil { return nil, nil, err } @@ -974,8 +978,8 @@ func (d *D) FieldTryFormatBitBuf(name string, bb *bitio.Buffer, formats []*Forma return dv, v, err } -func (d *D) FieldFormatBitBuf(name string, bb *bitio.Buffer, formats []*Format, opts ...Options) (*Value, interface{}) { - dv, v, err := d.FieldTryFormatBitBuf(name, bb, formats, opts...) +func (d *D) FieldFormatBitBuf(name string, bb *bitio.Buffer, formats []*Format, inArg interface{}) (*Value, interface{}) { + dv, v, err := d.FieldTryFormatBitBuf(name, bb, formats, inArg) if dv == nil || dv.Errors() != nil { panic(err) } @@ -1036,7 +1040,7 @@ func (d *D) FieldFormatZlibLen(name string, nBits int64, formats []*Format) (*Va } zbb := bitio.NewBufferFromBytes(zd, -1) - return d.FieldFormatBitBuf(name, zbb, formats) + return d.FieldFormatBitBuf(name, zbb, formats, nil) } func (d *D) FieldStrNullTerminated(name string) string {