1
1
mirror of https://github.com/wader/fq.git synced 2024-09-11 12:05:39 +03:00

decode: Move registry package to decode/registry and add a format group type

This commit is contained in:
Mattias Wadman 2021-11-17 16:46:10 +01:00
parent 3cea849101
commit 986d5ecc50
80 changed files with 422 additions and 419 deletions

View File

@ -2,7 +2,7 @@
[./formats_table.jq]: sh-start [./formats_table.jq]: sh-start
|Name |Description |Uses| |Name |Description |Dependencies|
|- |- |-| |- |- |-|
|`aac_frame` |Advanced&nbsp;Audio&nbsp;Coding&nbsp;frame |<sub></sub>| |`aac_frame` |Advanced&nbsp;Audio&nbsp;Coding&nbsp;frame |<sub></sub>|
|`adts` |Audio&nbsp;Data&nbsp;Transport&nbsp;Stream |<sub>`adts_frame`</sub>| |`adts` |Audio&nbsp;Data&nbsp;Transport&nbsp;Stream |<sub>`adts_frame`</sub>|

View File

@ -6,7 +6,7 @@ def nbsp: gsub(" "; "&nbsp;");
[ { [ {
name: "Name", name: "Name",
desc: "Description", desc: "Description",
uses: "Uses" uses: "Dependencies"
}, },
{ {
name: "-", name: "-",

View File

@ -1,4 +1,4 @@
// Package all imports and registers all formats in the default registry // Package all registers all builtin formats with the default registry
//nolint:revive //nolint:revive
package all package all

View File

@ -8,15 +8,15 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var imageFormat []*decode.Format var imageFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.APEV2, Name: format.APEV2,
Description: "APEv2 metadata tag", Description: "APEv2 metadata tag",
DecodeFn: apev2Decode, DecodeFn: apev2Decode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.IMAGE}, Formats: &imageFormat}, {Names: []string{format.IMAGE}, Group: &imageFormat},
}, },
}) })
} }

View File

@ -11,7 +11,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.AV1_CCR, Name: format.AV1_CCR,
Description: "AV1 Codec Configuration Record", Description: "AV1 Codec Configuration Record",
DecodeFn: ccrDecode, DecodeFn: ccrDecode,

View File

@ -10,17 +10,17 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var obuFormat []*decode.Format var obuFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.AV1_FRAME, Name: format.AV1_FRAME,
Description: "AV1 frame", Description: "AV1 frame",
DecodeFn: frameDecode, DecodeFn: frameDecode,
RootArray: true, RootArray: true,
RootName: "frame", RootName: "frame",
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.AV1_OBU}, Formats: &obuFormat}, {Names: []string{format.AV1_OBU}, Group: &obuFormat},
}, },
}) })
} }

View File

@ -7,7 +7,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.AV1_OBU, Name: format.AV1_OBU,
Description: "AV1 Open Bitstream Unit", Description: "AV1 Open Bitstream Unit",
DecodeFn: obuDecode, DecodeFn: obuDecode,

View File

@ -17,16 +17,16 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var probeFormat []*decode.Format var probeGroup decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.BZIP2, Name: format.BZIP2,
Description: "bzip2 compression", Description: "bzip2 compression",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},
DecodeFn: gzDecode, DecodeFn: gzDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.PROBE}, Formats: &probeFormat}, {Names: []string{format.PROBE}, Group: &probeGroup},
}, },
}) })
} }
@ -96,7 +96,7 @@ func gzDecode(d *decode.D, in interface{}) interface{} {
} }
// calculatedCRC32 := crc32W.Sum(nil) // calculatedCRC32 := crc32W.Sum(nil)
uncompressedBB := bitio.NewBufferFromBytes(uncompressed.Bytes(), -1) uncompressedBB := bitio.NewBufferFromBytes(uncompressed.Bytes(), -1)
dv, _, _ := d.FieldTryFormatBitBuf("uncompressed", uncompressedBB, probeFormat, nil) dv, _, _ := d.FieldTryFormatBitBuf("uncompressed", uncompressedBB, probeGroup, nil)
if dv == nil { if dv == nil {
d.FieldRootBitBuf("uncompressed", uncompressedBB) d.FieldRootBitBuf("uncompressed", uncompressedBB)
} }

View File

@ -13,7 +13,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.DNS, Name: format.DNS,
Description: "DNS packet", Description: "DNS packet",
DecodeFn: dnsDecode, DecodeFn: dnsDecode,

View File

@ -15,7 +15,7 @@ import (
// TODO: p_type hi/lo // TODO: p_type hi/lo
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.ELF, Name: format.ELF,
Description: "Executable and Linkable Format", Description: "Executable and Linkable Format",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},

View File

@ -17,18 +17,18 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var flacMetadatablockFormat []*decode.Format var flacMetadatablockFormat decode.Group
var flacFrameFormat []*decode.Format var flacFrameFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.FLAC, Name: format.FLAC,
Description: "Free Lossless Audio Codec file", Description: "Free Lossless Audio Codec file",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},
DecodeFn: flacDecode, DecodeFn: flacDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.FLAC_METADATABLOCKS}, Formats: &flacMetadatablockFormat}, {Names: []string{format.FLAC_METADATABLOCKS}, Group: &flacMetadatablockFormat},
{Names: []string{format.FLAC_FRAME}, Formats: &flacFrameFormat}, {Names: []string{format.FLAC_FRAME}, Group: &flacFrameFormat},
}, },
}) })
} }

View File

@ -12,7 +12,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.FLAC_FRAME, Name: format.FLAC_FRAME,
Description: "FLAC frame", Description: "FLAC frame",
DecodeFn: frameDecode, DecodeFn: frameDecode,

View File

@ -11,19 +11,19 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var flacStreaminfoFormat []*decode.Format var flacStreaminfoFormat decode.Group
var flacPicture []*decode.Format var flacPicture decode.Group
var vorbisCommentFormat []*decode.Format var vorbisCommentFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.FLAC_METADATABLOCK, Name: format.FLAC_METADATABLOCK,
Description: "FLAC metadatablock", Description: "FLAC metadatablock",
DecodeFn: metadatablockDecode, DecodeFn: metadatablockDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.FLAC_STREAMINFO}, Formats: &flacStreaminfoFormat}, {Names: []string{format.FLAC_STREAMINFO}, Group: &flacStreaminfoFormat},
{Names: []string{format.FLAC_PICTURE}, Formats: &flacPicture}, {Names: []string{format.FLAC_PICTURE}, Group: &flacPicture},
{Names: []string{format.VORBIS_COMMENT}, Formats: &vorbisCommentFormat}, {Names: []string{format.VORBIS_COMMENT}, Group: &vorbisCommentFormat},
}, },
}) })
} }

View File

@ -8,17 +8,17 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var flacMetadatablockForamt []*decode.Format var flacMetadatablockForamt decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.FLAC_METADATABLOCKS, Name: format.FLAC_METADATABLOCKS,
Description: "FLAC metadatablocks", Description: "FLAC metadatablocks",
DecodeFn: metadatablocksDecode, DecodeFn: metadatablocksDecode,
RootArray: true, RootArray: true,
RootName: "metadatablocks", RootName: "metadatablocks",
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.FLAC_METADATABLOCK}, Formats: &flacMetadatablockForamt}, {Names: []string{format.FLAC_METADATABLOCK}, Group: &flacMetadatablockForamt},
}, },
}) })
} }

View File

@ -6,7 +6,7 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var images []*decode.Format var images decode.Group
var pictureTypeNames = decode.UToStr{ var pictureTypeNames = decode.UToStr{
0: "Other", 0: "Other",
@ -33,12 +33,12 @@ var pictureTypeNames = decode.UToStr{
} }
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.FLAC_PICTURE, Name: format.FLAC_PICTURE,
Description: "FLAC metadatablock picture", Description: "FLAC metadatablock picture",
DecodeFn: pictureDecode, DecodeFn: pictureDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.IMAGE}, Formats: &images}, {Names: []string{format.IMAGE}, Group: &images},
}, },
}) })
} }

View File

@ -7,7 +7,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.FLAC_STREAMINFO, Name: format.FLAC_STREAMINFO,
Description: "FLAC streaminfo", Description: "FLAC streaminfo",
DecodeFn: streaminfoDecode, DecodeFn: streaminfoDecode,

View File

@ -13,7 +13,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.FLV, Name: format.FLV,
Description: "Flash video", Description: "Flash video",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},

View File

@ -16,7 +16,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.GIF, Name: format.GIF,
Description: "Graphics Interchange Format", Description: "Graphics Interchange Format",
Groups: []string{format.PROBE, format.IMAGE}, Groups: []string{format.PROBE, format.IMAGE},

View File

@ -16,16 +16,16 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var probeFormat []*decode.Format var probeFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.GZIP, Name: format.GZIP,
Description: "gzip compression", Description: "gzip compression",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},
DecodeFn: gzDecode, DecodeFn: gzDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.PROBE}, Formats: &probeFormat}, {Names: []string{format.PROBE}, Group: &probeFormat},
}, },
}) })
} }

View File

@ -11,7 +11,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.ICC_PROFILE, Name: format.ICC_PROFILE,
Description: "International Color Consortium profile", Description: "International Color Consortium profile",
DecodeFn: iccProfileDecode, DecodeFn: iccProfileDecode,

View File

@ -9,7 +9,7 @@ import (
// TODO: comment 28 long, zero byte, track number // TODO: comment 28 long, zero byte, track number
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.ID3V1, Name: format.ID3V1,
Description: "ID3v1 metadata", Description: "ID3v1 metadata",
DecodeFn: id3v1Decode, DecodeFn: id3v1Decode,

View File

@ -7,7 +7,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.ID3V11, Name: format.ID3V11,
Description: "ID3v1.1 metadata", Description: "ID3v1.1 metadata",
DecodeFn: id3v11Decode, DecodeFn: id3v11Decode,

View File

@ -17,15 +17,15 @@ import (
"golang.org/x/text/encoding/unicode" "golang.org/x/text/encoding/unicode"
) )
var imageFormat []*decode.Format var imageFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.ID3V2, Name: format.ID3V2,
Description: "ID3v2 metadata", Description: "ID3v2 metadata",
DecodeFn: id3v2Decode, DecodeFn: id3v2Decode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.IMAGE}, Formats: &imageFormat}, {Names: []string{format.IMAGE}, Group: &imageFormat},
}, },
}) })
} }

View File

@ -13,18 +13,18 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var exifFormat []*decode.Format var exifFormat decode.Group
var iccProfileFormat []*decode.Format var iccProfileFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.JPEG, Name: format.JPEG,
Description: "Joint Photographic Experts Group file", Description: "Joint Photographic Experts Group file",
Groups: []string{format.PROBE, format.IMAGE}, Groups: []string{format.PROBE, format.IMAGE},
DecodeFn: jpegDecode, DecodeFn: jpegDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.EXIF}, Formats: &exifFormat}, {Names: []string{format.EXIF}, Group: &exifFormat},
{Names: []string{format.ICC_PROFILE}, Formats: &iccProfileFormat}, {Names: []string{format.ICC_PROFILE}, Group: &iccProfileFormat},
}, },
}) })
} }

View File

@ -9,7 +9,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.JSON, Name: format.JSON,
Description: "JSON", Description: "JSON",
ProbeOrder: 100, // last ProbeOrder: 100, // last

View File

@ -28,59 +28,59 @@ import (
//go:embed *.jq //go:embed *.jq
var matroskaFS embed.FS var matroskaFS embed.FS
var aacFrameFormat []*decode.Format var aacFrameFormat decode.Group
var av1CCRFormat []*decode.Format var av1CCRFormat decode.Group
var av1FrameFormat []*decode.Format var av1FrameFormat decode.Group
var flacFrameFormat []*decode.Format var flacFrameFormat decode.Group
var flacMetadatablocksFormat []*decode.Format var flacMetadatablocksFormat decode.Group
var imageFormat []*decode.Format var imageFormat decode.Group
var mp3FrameFormat []*decode.Format var mp3FrameFormat decode.Group
var mpegASCFrameFormat []*decode.Format var mpegASCFrameFormat decode.Group
var mpegAVCAUFormat []*decode.Format var mpegAVCAUFormat decode.Group
var mpegAVCDCRFormat []*decode.Format var mpegAVCDCRFormat decode.Group
var mpegHEVCDCRFormat []*decode.Format var mpegHEVCDCRFormat decode.Group
var mpegHEVCSampleFormat []*decode.Format var mpegHEVCSampleFormat decode.Group
var mpegPESPacketSampleFormat []*decode.Format var mpegPESPacketSampleFormat decode.Group
var mpegSPUFrameFormat []*decode.Format var mpegSPUFrameFormat decode.Group
var opusPacketFrameFormat []*decode.Format var opusPacketFrameFormat decode.Group
var vorbisPacketFormat []*decode.Format var vorbisPacketFormat decode.Group
var vp8FrameFormat []*decode.Format var vp8FrameFormat decode.Group
var vp9CFMFormat []*decode.Format var vp9CFMFormat decode.Group
var vp9FrameFormat []*decode.Format var vp9FrameFormat decode.Group
var codecToFormat map[string]*[]*decode.Format var codecToFormat map[string]*decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.MATROSKA, Name: format.MATROSKA,
Description: "Matroska file", Description: "Matroska file",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},
DecodeFn: matroskaDecode, DecodeFn: matroskaDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.AAC_FRAME}, Formats: &aacFrameFormat}, {Names: []string{format.AAC_FRAME}, Group: &aacFrameFormat},
{Names: []string{format.AV1_CCR}, Formats: &av1CCRFormat}, {Names: []string{format.AV1_CCR}, Group: &av1CCRFormat},
{Names: []string{format.AV1_FRAME}, Formats: &av1FrameFormat}, {Names: []string{format.AV1_FRAME}, Group: &av1FrameFormat},
{Names: []string{format.AVC_AU}, Formats: &mpegAVCAUFormat}, {Names: []string{format.AVC_AU}, Group: &mpegAVCAUFormat},
{Names: []string{format.AVC_DCR}, Formats: &mpegAVCDCRFormat}, {Names: []string{format.AVC_DCR}, Group: &mpegAVCDCRFormat},
{Names: []string{format.FLAC_FRAME}, Formats: &flacFrameFormat}, {Names: []string{format.FLAC_FRAME}, Group: &flacFrameFormat},
{Names: []string{format.FLAC_METADATABLOCKS}, Formats: &flacMetadatablocksFormat}, {Names: []string{format.FLAC_METADATABLOCKS}, Group: &flacMetadatablocksFormat},
{Names: []string{format.HEVC_AU}, Formats: &mpegHEVCSampleFormat}, {Names: []string{format.HEVC_AU}, Group: &mpegHEVCSampleFormat},
{Names: []string{format.HEVC_DCR}, Formats: &mpegHEVCDCRFormat}, {Names: []string{format.HEVC_DCR}, Group: &mpegHEVCDCRFormat},
{Names: []string{format.IMAGE}, Formats: &imageFormat}, {Names: []string{format.IMAGE}, Group: &imageFormat},
{Names: []string{format.MP3_FRAME}, Formats: &mp3FrameFormat}, {Names: []string{format.MP3_FRAME}, Group: &mp3FrameFormat},
{Names: []string{format.MPEG_ASC}, Formats: &mpegASCFrameFormat}, {Names: []string{format.MPEG_ASC}, Group: &mpegASCFrameFormat},
{Names: []string{format.MPEG_PES_PACKET}, Formats: &mpegPESPacketSampleFormat}, {Names: []string{format.MPEG_PES_PACKET}, Group: &mpegPESPacketSampleFormat},
{Names: []string{format.MPEG_SPU}, Formats: &mpegSPUFrameFormat}, {Names: []string{format.MPEG_SPU}, Group: &mpegSPUFrameFormat},
{Names: []string{format.OPUS_PACKET}, Formats: &opusPacketFrameFormat}, {Names: []string{format.OPUS_PACKET}, Group: &opusPacketFrameFormat},
{Names: []string{format.VORBIS_PACKET}, Formats: &vorbisPacketFormat}, {Names: []string{format.VORBIS_PACKET}, Group: &vorbisPacketFormat},
{Names: []string{format.VP8_FRAME}, Formats: &vp8FrameFormat}, {Names: []string{format.VP8_FRAME}, Group: &vp8FrameFormat},
{Names: []string{format.VP9_CFM}, Formats: &vp9CFMFormat}, {Names: []string{format.VP9_CFM}, Group: &vp9CFMFormat},
{Names: []string{format.VP9_FRAME}, Formats: &vp9FrameFormat}, {Names: []string{format.VP9_FRAME}, Group: &vp9FrameFormat},
}, },
Files: matroskaFS, Files: matroskaFS,
}) })
codecToFormat = map[string]*[]*decode.Format{ codecToFormat = map[string]*decode.Group{
"A_VORBIS": &vorbisPacketFormat, "A_VORBIS": &vorbisPacketFormat,
"A_MPEG/L3": &mp3FrameFormat, "A_MPEG/L3": &mp3FrameFormat,
"A_FLAC": &flacFrameFormat, "A_FLAC": &flacFrameFormat,

View File

@ -9,25 +9,25 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var headerFormat []*decode.Format var headerFormat decode.Group
var footerFormat []*decode.Format var footerFormat decode.Group
var mp3Frame []*decode.Format var mp3Frame decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.MP3, Name: format.MP3,
ProbeOrder: 20, // after most others (silent samples and jpeg header can look like mp3 sync) ProbeOrder: 20, // after most others (silent samples and jpeg header can look like mp3 sync)
Description: "MP3 file", Description: "MP3 file",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},
DecodeFn: mp3Decode, DecodeFn: mp3Decode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.ID3V2}, Formats: &headerFormat}, {Names: []string{format.ID3V2}, Group: &headerFormat},
{Names: []string{ {Names: []string{
format.ID3V1, format.ID3V1,
format.ID3V11, format.ID3V11,
format.APEV2, format.APEV2,
}, Formats: &footerFormat}, }, Group: &footerFormat},
{Names: []string{format.MP3_FRAME}, Formats: &mp3Frame}, {Names: []string{format.MP3_FRAME}, Group: &mp3Frame},
}, },
}) })
} }

View File

@ -9,7 +9,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.XING, Name: format.XING,
Description: "Xing header", Description: "Xing header",
DecodeFn: xingDecode, DecodeFn: xingDecode,

View File

@ -27,30 +27,30 @@ import (
//go:embed *.jq //go:embed *.jq
var mp4FS embed.FS var mp4FS embed.FS
var aacFrameFormat []*decode.Format var aacFrameFormat decode.Group
var av1CCRFormat []*decode.Format var av1CCRFormat decode.Group
var av1FrameFormat []*decode.Format var av1FrameFormat decode.Group
var flacFrameFormat []*decode.Format var flacFrameFormat decode.Group
var flacMetadatablocksFormat []*decode.Format var flacMetadatablocksFormat decode.Group
var id3v2Format []*decode.Format var id3v2Format decode.Group
var imageFormat []*decode.Format var imageFormat decode.Group
var jpegFormat []*decode.Format var jpegFormat decode.Group
var mp3FrameFormat []*decode.Format var mp3FrameFormat decode.Group
var mpegAVCAUFormat []*decode.Format var mpegAVCAUFormat decode.Group
var mpegAVCDCRFormat []*decode.Format var mpegAVCDCRFormat decode.Group
var mpegESFormat []*decode.Format var mpegESFormat decode.Group
var mpegHEVCDCRFrameFormat []*decode.Format var mpegHEVCDCRFrameFormat decode.Group
var mpegHEVCSampleFormat []*decode.Format var mpegHEVCSampleFormat decode.Group
var mpegPESPacketSampleFormat []*decode.Format var mpegPESPacketSampleFormat decode.Group
var opusPacketFrameFormat []*decode.Format var opusPacketFrameFormat decode.Group
var protoBufWidevineFormat []*decode.Format var protoBufWidevineFormat decode.Group
var psshPlayreadyFormat []*decode.Format var psshPlayreadyFormat decode.Group
var vorbisPacketFormat []*decode.Format var vorbisPacketFormat decode.Group
var vp9FrameFormat []*decode.Format var vp9FrameFormat decode.Group
var vpxCCRFormat []*decode.Format var vpxCCRFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.MP4, Name: format.MP4,
Description: "MPEG-4 file and similar", Description: "MPEG-4 file and similar",
Groups: []string{ Groups: []string{
@ -59,27 +59,27 @@ func init() {
}, },
DecodeFn: mp4Decode, DecodeFn: mp4Decode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.AAC_FRAME}, Formats: &aacFrameFormat}, {Names: []string{format.AAC_FRAME}, Group: &aacFrameFormat},
{Names: []string{format.AV1_CCR}, Formats: &av1CCRFormat}, {Names: []string{format.AV1_CCR}, Group: &av1CCRFormat},
{Names: []string{format.AV1_FRAME}, Formats: &av1FrameFormat}, {Names: []string{format.AV1_FRAME}, Group: &av1FrameFormat},
{Names: []string{format.FLAC_FRAME}, Formats: &flacFrameFormat}, {Names: []string{format.FLAC_FRAME}, Group: &flacFrameFormat},
{Names: []string{format.FLAC_METADATABLOCKS}, Formats: &flacMetadatablocksFormat}, {Names: []string{format.FLAC_METADATABLOCKS}, Group: &flacMetadatablocksFormat},
{Names: []string{format.ID3V2}, Formats: &id3v2Format}, {Names: []string{format.ID3V2}, Group: &id3v2Format},
{Names: []string{format.IMAGE}, Formats: &imageFormat}, {Names: []string{format.IMAGE}, Group: &imageFormat},
{Names: []string{format.JPEG}, Formats: &jpegFormat}, {Names: []string{format.JPEG}, Group: &jpegFormat},
{Names: []string{format.MP3_FRAME}, Formats: &mp3FrameFormat}, {Names: []string{format.MP3_FRAME}, Group: &mp3FrameFormat},
{Names: []string{format.AVC_AU}, Formats: &mpegAVCAUFormat}, {Names: []string{format.AVC_AU}, Group: &mpegAVCAUFormat},
{Names: []string{format.AVC_DCR}, Formats: &mpegAVCDCRFormat}, {Names: []string{format.AVC_DCR}, Group: &mpegAVCDCRFormat},
{Names: []string{format.MPEG_ES}, Formats: &mpegESFormat}, {Names: []string{format.MPEG_ES}, Group: &mpegESFormat},
{Names: []string{format.HEVC_AU}, Formats: &mpegHEVCSampleFormat}, {Names: []string{format.HEVC_AU}, Group: &mpegHEVCSampleFormat},
{Names: []string{format.HEVC_DCR}, Formats: &mpegHEVCDCRFrameFormat}, {Names: []string{format.HEVC_DCR}, Group: &mpegHEVCDCRFrameFormat},
{Names: []string{format.MPEG_PES_PACKET}, Formats: &mpegPESPacketSampleFormat}, {Names: []string{format.MPEG_PES_PACKET}, Group: &mpegPESPacketSampleFormat},
{Names: []string{format.OPUS_PACKET}, Formats: &opusPacketFrameFormat}, {Names: []string{format.OPUS_PACKET}, Group: &opusPacketFrameFormat},
{Names: []string{format.PROTOBUF_WIDEVINE}, Formats: &protoBufWidevineFormat}, {Names: []string{format.PROTOBUF_WIDEVINE}, Group: &protoBufWidevineFormat},
{Names: []string{format.PSSH_PLAYREADY}, Formats: &psshPlayreadyFormat}, {Names: []string{format.PSSH_PLAYREADY}, Group: &psshPlayreadyFormat},
{Names: []string{format.VORBIS_PACKET}, Formats: &vorbisPacketFormat}, {Names: []string{format.VORBIS_PACKET}, Group: &vorbisPacketFormat},
{Names: []string{format.VP9_FRAME}, Formats: &vp9FrameFormat}, {Names: []string{format.VP9_FRAME}, Group: &vp9FrameFormat},
{Names: []string{format.VPX_CCR}, Formats: &vpxCCRFormat}, {Names: []string{format.VPX_CCR}, Group: &vpxCCRFormat},
}, },
Files: mp4FS, Files: mp4FS,
}) })

View File

@ -7,7 +7,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.PSSH_PLAYREADY, Name: format.PSSH_PLAYREADY,
Description: "PlayReady PSSH", Description: "PlayReady PSSH",
DecodeFn: playreadyPsshDecode, DecodeFn: playreadyPsshDecode,

View File

@ -12,7 +12,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.AAC_FRAME, Name: format.AAC_FRAME,
Description: "Advanced Audio Coding frame", Description: "Advanced Audio Coding frame",
DecodeFn: aacDecode, DecodeFn: aacDecode,

View File

@ -6,10 +6,10 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var adtsFrame []*decode.Format var adtsFrame decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.ADTS, Name: format.ADTS,
Description: "Audio Data Transport Stream", Description: "Audio Data Transport Stream",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},
@ -17,7 +17,7 @@ func init() {
RootArray: true, RootArray: true,
RootName: "frames", RootName: "frames",
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.ADTS_FRAME}, Formats: &adtsFrame}, {Names: []string{format.ADTS_FRAME}, Group: &adtsFrame},
}, },
}) })
} }

View File

@ -10,15 +10,15 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var aacFrameFormat []*decode.Format var aacFrameFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.ADTS_FRAME, Name: format.ADTS_FRAME,
Description: "Audio Data Transport Stream frame", Description: "Audio Data Transport Stream frame",
DecodeFn: adtsFrameDecoder, DecodeFn: adtsFrameDecoder,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.AAC_FRAME}, Formats: &aacFrameFormat}, {Names: []string{format.AAC_FRAME}, Group: &aacFrameFormat},
}, },
}) })
} }

View File

@ -22,7 +22,7 @@ func annexBDecodeStartCodeLen(v uint64) int64 {
} }
} }
func annexBDecode(d *decode.D, _ interface{}, format []*decode.Format) interface{} { func annexBDecode(d *decode.D, _ interface{}, format decode.Group) interface{} {
currentOffset, currentPrefixLen, err := annexBFindStartCode(d) currentOffset, currentPrefixLen, err := annexBFindStartCode(d)
// TODO: really restrict to 0? // TODO: really restrict to 0?
if err != nil || currentOffset != 0 { if err != nil || currentOffset != 0 {

View File

@ -6,10 +6,10 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var annexBAVCNALUFormat []*decode.Format var annexBAVCNALUFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.AVC_ANNEXB, Name: format.AVC_ANNEXB,
Description: "H.264/AVC Annex B", Description: "H.264/AVC Annex B",
DecodeFn: func(d *decode.D, in interface{}) interface{} { DecodeFn: func(d *decode.D, in interface{}) interface{} {
@ -18,7 +18,7 @@ func init() {
RootArray: true, RootArray: true,
RootName: "stream", RootName: "stream",
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.AVC_NALU}, Formats: &annexBAVCNALUFormat}, {Names: []string{format.AVC_NALU}, Group: &annexBAVCNALUFormat},
}, },
}) })
} }

View File

@ -8,17 +8,17 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var avcNALUFormat []*decode.Format var avcNALUFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.AVC_AU, Name: format.AVC_AU,
Description: "H.264/AVC Access Unit", Description: "H.264/AVC Access Unit",
DecodeFn: avcAUDecode, DecodeFn: avcAUDecode,
RootArray: true, RootArray: true,
RootName: "access_unit", RootName: "access_unit",
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.AVC_NALU}, Formats: &avcNALUFormat}, {Names: []string{format.AVC_NALU}, Group: &avcNALUFormat},
}, },
}) })
} }

View File

@ -11,15 +11,15 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var avcDCRNALFormat []*decode.Format var avcDCRNALFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.AVC_DCR, Name: format.AVC_DCR,
Description: "H.264/AVC Decoder Configuration Record", Description: "H.264/AVC Decoder Configuration Record",
DecodeFn: avcDcrDecode, DecodeFn: avcDcrDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.AVC_NALU}, Formats: &avcDCRNALFormat}, {Names: []string{format.AVC_NALU}, Group: &avcDCRNALFormat},
}, },
}) })
} }

View File

@ -9,19 +9,19 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var avcSPSFormat []*decode.Format var avcSPSFormat decode.Group
var avcPPSFormat []*decode.Format var avcPPSFormat decode.Group
var avcSEIFormat []*decode.Format var avcSEIFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.AVC_NALU, Name: format.AVC_NALU,
Description: "H.264/AVC Network Access Layer Unit", Description: "H.264/AVC Network Access Layer Unit",
DecodeFn: avcNALUDecode, DecodeFn: avcNALUDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.AVC_SPS}, Formats: &avcSPSFormat}, {Names: []string{format.AVC_SPS}, Group: &avcSPSFormat},
{Names: []string{format.AVC_PPS}, Formats: &avcPPSFormat}, {Names: []string{format.AVC_PPS}, Group: &avcPPSFormat},
{Names: []string{format.AVC_SEI}, Formats: &avcSEIFormat}, {Names: []string{format.AVC_SEI}, Group: &avcSEIFormat},
}, },
}) })
} }

View File

@ -7,7 +7,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.AVC_PPS, Name: format.AVC_PPS,
Description: "H.264/AVC Picture Parameter Set", Description: "H.264/AVC Picture Parameter Set",
DecodeFn: avcPPSDecode, DecodeFn: avcPPSDecode,

View File

@ -7,7 +7,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.AVC_SEI, Name: format.AVC_SEI,
Description: "H.264/AVC Supplemental Enhancement Information", Description: "H.264/AVC Supplemental Enhancement Information",
DecodeFn: avcSEIDecode, DecodeFn: avcSEIDecode,

View File

@ -7,7 +7,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.AVC_SPS, Name: format.AVC_SPS,
Description: "H.264/AVC Sequence Parameter Set", Description: "H.264/AVC Sequence Parameter Set",
DecodeFn: avcSPSDecode, DecodeFn: avcSPSDecode,

View File

@ -6,10 +6,10 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var annexBHEVCNALUFormat []*decode.Format var annexBHEVCNALUFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.HEVC_ANNEXB, Name: format.HEVC_ANNEXB,
Description: "H.265/HEVC Annex B", Description: "H.265/HEVC Annex B",
DecodeFn: func(d *decode.D, in interface{}) interface{} { DecodeFn: func(d *decode.D, in interface{}) interface{} {
@ -18,7 +18,7 @@ func init() {
RootArray: true, RootArray: true,
RootName: "stream", RootName: "stream",
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.HEVC_NALU}, Formats: &annexBHEVCNALUFormat}, {Names: []string{format.HEVC_NALU}, Group: &annexBHEVCNALUFormat},
}, },
}) })
} }

View File

@ -6,17 +6,17 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var hevcAUNALFormat []*decode.Format var hevcAUNALFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.HEVC_AU, Name: format.HEVC_AU,
Description: "H.265/HEVC Access Unit", Description: "H.265/HEVC Access Unit",
DecodeFn: hevcAUDecode, DecodeFn: hevcAUDecode,
RootArray: true, RootArray: true,
RootName: "access_unit", RootName: "access_unit",
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.HEVC_NALU}, Formats: &hevcAUNALFormat}, {Names: []string{format.HEVC_NALU}, Group: &hevcAUNALFormat},
}, },
}) })
} }

View File

@ -6,15 +6,15 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var hevcDCRNALFormat []*decode.Format var hevcDCRNALFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.HEVC_DCR, Name: format.HEVC_DCR,
Description: "H.265/HEVC Decoder Configuration Record", Description: "H.265/HEVC Decoder Configuration Record",
DecodeFn: hevcDcrDecode, DecodeFn: hevcDcrDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.HEVC_NALU}, Formats: &hevcDCRNALFormat}, {Names: []string{format.HEVC_NALU}, Group: &hevcDCRNALFormat},
}, },
}) })
} }

View File

@ -7,7 +7,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.HEVC_NALU, Name: format.HEVC_NALU,
Description: "H.265/HEVC Network Access Layer Unit", Description: "H.265/HEVC Network Access Layer Unit",
DecodeFn: hevcNALUDecode, DecodeFn: hevcNALUDecode,

View File

@ -19,15 +19,15 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var xingHeader []*decode.Format var xingHeader decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.MP3_FRAME, Name: format.MP3_FRAME,
Description: "MPEG audio layer 3 frame", Description: "MPEG audio layer 3 frame",
DecodeFn: frameDecode, DecodeFn: frameDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.XING}, Formats: &xingHeader}, {Names: []string{format.XING}, Group: &xingHeader},
}, },
}) })
} }

View File

@ -9,7 +9,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.MPEG_ASC, Name: format.MPEG_ASC,
Description: "MPEG-4 Audio Specific Config", Description: "MPEG-4 Audio Specific Config",
DecodeFn: ascDecoder, DecodeFn: ascDecoder,

View File

@ -9,17 +9,17 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var mpegASCFormat []*decode.Format var mpegASCFormat decode.Group
var vorbisPacketFormat []*decode.Format var vorbisPacketFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.MPEG_ES, Name: format.MPEG_ES,
Description: "MPEG Elementary Stream", Description: "MPEG Elementary Stream",
DecodeFn: esDecode, DecodeFn: esDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.MPEG_ASC}, Formats: &mpegASCFormat}, {Names: []string{format.MPEG_ASC}, Group: &mpegASCFormat},
{Names: []string{format.VORBIS_PACKET}, Formats: &vorbisPacketFormat}, {Names: []string{format.VORBIS_PACKET}, Group: &vorbisPacketFormat},
}, },
}) })
} }

View File

@ -13,19 +13,19 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var pesPacketFormat []*decode.Format var pesPacketFormat decode.Group
var spuFormat []*decode.Format var spuFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.MPEG_PES, Name: format.MPEG_PES,
Description: "MPEG Packetized elementary stream", Description: "MPEG Packetized elementary stream",
DecodeFn: pesDecode, DecodeFn: pesDecode,
RootArray: true, RootArray: true,
RootName: "packets", RootName: "packets",
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.MPEG_PES_PACKET}, Formats: &pesPacketFormat}, {Names: []string{format.MPEG_PES_PACKET}, Group: &pesPacketFormat},
{Names: []string{format.MPEG_SPU}, Formats: &spuFormat}, {Names: []string{format.MPEG_SPU}, Group: &spuFormat},
}, },
}) })
} }

View File

@ -11,7 +11,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.MPEG_PES_PACKET, Name: format.MPEG_PES_PACKET,
Description: "MPEG Packetized elementary stream packet", Description: "MPEG Packetized elementary stream packet",
DecodeFn: pesPacketDecode, DecodeFn: pesPacketDecode,

View File

@ -14,7 +14,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.MPEG_SPU, Name: format.MPEG_SPU,
Description: "Sub Picture Unit (DVD subtitle)", Description: "Sub Picture Unit (DVD subtitle)",
DecodeFn: spuDecode, DecodeFn: spuDecode,

View File

@ -7,7 +7,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.MPEG_TS, Name: format.MPEG_TS,
ProbeOrder: 10, // make sure to be after gif, both start with 0x47 ProbeOrder: 10, // make sure to be after gif, both start with 0x47
Description: "MPEG Transport Stream", Description: "MPEG Transport Stream",

View File

@ -12,26 +12,26 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var oggPageFormat []*decode.Format var oggPageFormat decode.Group
var vorbisPacketFormat []*decode.Format var vorbisPacketFormat decode.Group
var vorbisCommentFormat []*decode.Format var vorbisCommentFormat decode.Group
var opusPacketFormat []*decode.Format var opusPacketFormat decode.Group
var flacMetadatablockFormat []*decode.Format var flacMetadatablockFormat decode.Group
var flacFrameFormat []*decode.Format var flacFrameFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.OGG, Name: format.OGG,
Description: "OGG file", Description: "OGG file",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},
DecodeFn: decodeOgg, DecodeFn: decodeOgg,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.OGG_PAGE}, Formats: &oggPageFormat}, {Names: []string{format.OGG_PAGE}, Group: &oggPageFormat},
{Names: []string{format.VORBIS_PACKET}, Formats: &vorbisPacketFormat}, {Names: []string{format.VORBIS_PACKET}, Group: &vorbisPacketFormat},
{Names: []string{format.VORBIS_COMMENT}, Formats: &vorbisCommentFormat}, {Names: []string{format.VORBIS_COMMENT}, Group: &vorbisCommentFormat},
{Names: []string{format.OPUS_PACKET}, Formats: &opusPacketFormat}, {Names: []string{format.OPUS_PACKET}, Group: &opusPacketFormat},
{Names: []string{format.FLAC_METADATABLOCK}, Formats: &flacMetadatablockFormat}, {Names: []string{format.FLAC_METADATABLOCK}, Group: &flacMetadatablockFormat},
{Names: []string{format.FLAC_FRAME}, Formats: &flacFrameFormat}, {Names: []string{format.FLAC_FRAME}, Group: &flacFrameFormat},
}, },
}) })
} }

View File

@ -11,7 +11,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.OGG_PAGE, Name: format.OGG_PAGE,
Description: "OGG page", Description: "OGG page",
DecodeFn: pageDecode, DecodeFn: pageDecode,

View File

@ -10,15 +10,15 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var vorbisComment []*decode.Format var vorbisComment decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.OPUS_PACKET, Name: format.OPUS_PACKET,
Description: "Opus packet", Description: "Opus packet",
DecodeFn: opusDecode, DecodeFn: opusDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.VORBIS_COMMENT}, Formats: &vorbisComment}, {Names: []string{format.VORBIS_COMMENT}, Group: &vorbisComment},
}, },
}) })
} }

View File

@ -15,18 +15,18 @@ import (
"github.com/wader/fq/pkg/ranges" "github.com/wader/fq/pkg/ranges"
) )
var iccProfileFormat []*decode.Format var iccProfileFormat decode.Group
var exifFormat []*decode.Format var exifFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.PNG, Name: format.PNG,
Description: "Portable Network Graphics file", Description: "Portable Network Graphics file",
Groups: []string{format.PROBE, format.IMAGE}, Groups: []string{format.PROBE, format.IMAGE},
DecodeFn: pngDecode, DecodeFn: pngDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.ICC_PROFILE}, Formats: &iccProfileFormat}, {Names: []string{format.ICC_PROFILE}, Group: &iccProfileFormat},
{Names: []string{format.EXIF}, Formats: &exifFormat}, {Names: []string{format.EXIF}, Group: &exifFormat},
}, },
}) })
} }

View File

@ -8,7 +8,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.PROTOBUF, Name: format.PROTOBUF,
Description: "Protobuf", Description: "Protobuf",
DecodeFn: protobufDecode, DecodeFn: protobufDecode,

View File

@ -8,15 +8,15 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var widevineProtoBufFormat []*decode.Format var widevineProtoBufFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.PROTOBUF_WIDEVINE, Name: format.PROTOBUF_WIDEVINE,
Description: "Widevine protobuf", Description: "Widevine protobuf",
DecodeFn: widevineDecode, DecodeFn: widevineDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.PROTOBUF}, Formats: &widevineProtoBufFormat}, {Names: []string{format.PROTOBUF}, Group: &widevineProtoBufFormat},
}, },
}) })
} }

View File

@ -7,7 +7,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.RAW, Name: format.RAW,
Description: "Raw bits", Description: "Raw bits",
DecodeFn: func(d *decode.D, in interface{}) interface{} { return nil }, DecodeFn: func(d *decode.D, in interface{}) interface{} { return nil },

View File

@ -1,12 +0,0 @@
package registry
import (
"github.com/wader/fq/pkg/decode"
)
// Default global registry that all standard formats register with
var Default = New()
func MustRegister(format *decode.Format) *decode.Format {
return Default.MustRegister(format)
}

View File

@ -1,115 +1,13 @@
package registry package registry
import ( import (
"errors"
"fmt"
"sort"
"sync"
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/decode/registry"
) )
type Registry struct { // Default global registry that all builtin formats register with
Groups map[string][]*decode.Format var Default = registry.New()
resolveOnce sync.Once
resolved bool func MustRegister(format decode.Format) {
} Default.MustRegister(format)
func New() *Registry {
return &Registry{
Groups: map[string][]*decode.Format{},
resolveOnce: sync.Once{},
}
}
func (r *Registry) register(groupName string, format *decode.Format, single bool) *decode.Format { //nolint:unparam
if r.resolved {
// for now can't change after resolved
panic("registry already resolved")
}
formats, ok := r.Groups[groupName]
if ok {
if !single {
panic(fmt.Sprintf("%s: format already registered", groupName))
}
} else {
formats = []*decode.Format{}
}
r.Groups[groupName] = append(formats, format)
return format
}
func (r *Registry) MustRegister(format *decode.Format) *decode.Format {
r.register(format.Name, format, false)
for _, g := range format.Groups {
r.register(g, format, true)
}
r.register("all", format, true)
return format
}
func sortFormats(fs []*decode.Format) {
sort.Slice(fs, func(i, j int) bool {
if fs[i].ProbeOrder == fs[j].ProbeOrder {
return fs[i].Name < fs[j].Name
}
return fs[i].ProbeOrder < fs[j].ProbeOrder
})
}
func (r *Registry) resolve() error {
for _, fs := range r.Groups {
for _, f := range fs {
for _, d := range f.Dependencies {
var formats []*decode.Format
for _, dName := range d.Names {
df, ok := r.Groups[dName]
if !ok {
return fmt.Errorf("%s: can't find format dependency %s", f.Name, dName)
}
formats = append(formats, df...)
}
sortFormats(formats)
*d.Formats = formats
}
}
}
for _, fs := range r.Groups {
sortFormats(fs)
}
r.resolved = true
return nil
}
func (r *Registry) Group(name string) ([]*decode.Format, error) {
r.resolveOnce.Do(func() {
if err := r.resolve(); err != nil {
panic(err)
}
})
if g, ok := r.Groups[name]; ok {
return g, nil
}
return nil, errors.New("format group not found")
}
func (r *Registry) MustGroup(name string) []*decode.Format {
g, err := r.Group(name)
if err == nil {
return g
}
panic(err)
}
func (r *Registry) MustAll() []*decode.Format {
return r.MustGroup("all")
} }

View File

@ -13,16 +13,16 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var probeFormat []*decode.Format var probeFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.TAR, Name: format.TAR,
Description: "Tar archive", Description: "Tar archive",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},
DecodeFn: tarDecode, DecodeFn: tarDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.PROBE}, Formats: &probeFormat}, {Names: []string{format.PROBE}, Group: &probeFormat},
}, },
}) })
} }

View File

@ -12,7 +12,7 @@ import (
// currently just a alias for tiff // currently just a alias for tiff
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.EXIF, Name: format.EXIF,
Description: "Exchangeable Image File Format", Description: "Exchangeable Image File Format",
Groups: []string{}, Groups: []string{},

View File

@ -8,16 +8,16 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var tiffIccProfile []*decode.Format var tiffIccProfile decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.TIFF, Name: format.TIFF,
Description: "Tag Image File Format", Description: "Tag Image File Format",
Groups: []string{format.PROBE, format.IMAGE}, Groups: []string{format.PROBE, format.IMAGE},
DecodeFn: tiffDecode, DecodeFn: tiffDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.ICC_PROFILE}, Formats: &tiffIccProfile}, {Names: []string{format.ICC_PROFILE}, Group: &tiffIccProfile},
}, },
}) })
} }

View File

@ -10,15 +10,15 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var flacPicture []*decode.Format var flacPicture decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.VORBIS_COMMENT, Name: format.VORBIS_COMMENT,
Description: "Vorbis comment", Description: "Vorbis comment",
DecodeFn: commentDecode, DecodeFn: commentDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.FLAC_PICTURE}, Formats: &flacPicture}, {Names: []string{format.FLAC_PICTURE}, Group: &flacPicture},
}, },
}) })
} }

View File

@ -10,15 +10,15 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var vorbisComment []*decode.Format var vorbisComment decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.VORBIS_PACKET, Name: format.VORBIS_PACKET,
Description: "Vorbis packet", Description: "Vorbis packet",
DecodeFn: vorbisDecode, DecodeFn: vorbisDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.VORBIS_COMMENT}, Formats: &vorbisComment}, {Names: []string{format.VORBIS_COMMENT}, Group: &vorbisComment},
}, },
}) })
} }

View File

@ -11,7 +11,7 @@ import (
// TODO: vpx frame? // TODO: vpx frame?
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.VP8_FRAME, Name: format.VP8_FRAME,
Description: "VP8 frame", Description: "VP8 frame",
DecodeFn: vp8Decode, DecodeFn: vp8Decode,

View File

@ -9,7 +9,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.VP9_CFM, Name: format.VP9_CFM,
Description: "VP9 Codec Feature Metadata", Description: "VP9 Codec Feature Metadata",
DecodeFn: vp9CFMDecode, DecodeFn: vp9CFMDecode,

View File

@ -48,7 +48,7 @@ var vp9ColorSpaceNames = decode.UToStr{
} }
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.VP9_FRAME, Name: format.VP9_FRAME,
Description: "VP9 frame", Description: "VP9 frame",
DecodeFn: vp9Decode, DecodeFn: vp9Decode,

View File

@ -9,7 +9,7 @@ import (
) )
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.VPX_CCR, Name: format.VPX_CCR,
Description: "VPX Codec Configuration Record", Description: "VPX Codec Configuration Record",
DecodeFn: vpxCCRDecode, DecodeFn: vpxCCRDecode,

View File

@ -16,19 +16,19 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var headerFormat []*decode.Format var headerFormat decode.Group
var footerFormat []*decode.Format var footerFormat decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.WAV, Name: format.WAV,
ProbeOrder: 10, // after most others (overlap some with webp) ProbeOrder: 10, // after most others (overlap some with webp)
Description: "WAV file", Description: "WAV file",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},
DecodeFn: wavDecode, DecodeFn: wavDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.ID3V2}, Formats: &headerFormat}, {Names: []string{format.ID3V2}, Group: &headerFormat},
{Names: []string{format.ID3V1, format.ID3V11}, Formats: &footerFormat}, {Names: []string{format.ID3V1, format.ID3V11}, Group: &footerFormat},
}, },
}) })
} }

View File

@ -10,16 +10,16 @@ import (
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
) )
var vp8Frame []*decode.Format var vp8Frame decode.Group
func init() { func init() {
registry.MustRegister(&decode.Format{ registry.MustRegister(decode.Format{
Name: format.WEBP, Name: format.WEBP,
Description: "WebP image", Description: "WebP image",
Groups: []string{format.PROBE, format.IMAGE}, Groups: []string{format.PROBE, format.IMAGE},
DecodeFn: webpDecode, DecodeFn: webpDecode,
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.VP8_FRAME}, Formats: &vp8Frame}, {Names: []string{format.VP8_FRAME}, Group: &vp8Frame},
}, },
}) })
} }

View File

@ -12,7 +12,7 @@ import (
"os/signal" "os/signal"
"path/filepath" "path/filepath"
"github.com/wader/fq/format/registry" "github.com/wader/fq/pkg/decode/registry"
"github.com/wader/fq/pkg/interp" "github.com/wader/fq/pkg/interp"
"github.com/wader/readline" "github.com/wader/readline"

View File

@ -33,34 +33,34 @@ type Options struct {
ReadBuf *[]byte ReadBuf *[]byte
} }
// Decode try decode formats and return first success and all other decoder errors // Decode try decode group and return first success and all other decoder errors
func Decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts Options) (*Value, interface{}, error) { func Decode(ctx context.Context, bb *bitio.Buffer, group Group, opts Options) (*Value, interface{}, error) {
return decode(ctx, bb, formats, opts) return decode(ctx, bb, group, opts)
} }
func decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts Options) (*Value, interface{}, error) { func decode(ctx context.Context, bb *bitio.Buffer, group Group, opts Options) (*Value, interface{}, error) {
decodeRange := opts.Range decodeRange := opts.Range
if decodeRange.IsZero() { if decodeRange.IsZero() {
decodeRange = ranges.Range{Len: bb.Len()} decodeRange = ranges.Range{Len: bb.Len()}
} }
if formats == nil { if group == nil {
panic("formats is nil, failed to register format?") panic("group is nil, failed to register format?")
} }
decodeErr := FormatsError{} formatsErr := FormatsError{}
for _, f := range formats { for _, g := range group {
cbb, err := bb.BitBufRange(decodeRange.Start, decodeRange.Len) cbb, err := bb.BitBufRange(decodeRange.Start, decodeRange.Len)
if err != nil { if err != nil {
return nil, nil, IOError{Err: err, Op: "BitBufRange", ReadSize: decodeRange.Len, Pos: decodeRange.Start} return nil, nil, IOError{Err: err, Op: "BitBufRange", ReadSize: decodeRange.Len, Pos: decodeRange.Start}
} }
d := newDecoder(ctx, f, cbb, opts) d := newDecoder(ctx, g, cbb, opts)
var decodeV interface{} var decodeV interface{}
r, rOk := recoverfn.Run(func() { r, rOk := recoverfn.Run(func() {
decodeV = f.DecodeFn(d, opts.FormatInArg) decodeV = g.DecodeFn(d, opts.FormatInArg)
}) })
if ctx != nil && ctx.Err() != nil { if ctx != nil && ctx.Err() != nil {
@ -72,10 +72,10 @@ func decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts Optio
panicErr, _ := re.(error) panicErr, _ := re.(error)
formatErr := FormatError{ formatErr := FormatError{
Err: panicErr, Err: panicErr,
Format: f, Format: g,
Stacktrace: r, Stacktrace: r,
} }
decodeErr.Errs = append(decodeErr.Errs, formatErr) formatsErr.Errs = append(formatsErr.Errs, formatErr)
switch vv := d.Value.V.(type) { switch vv := d.Value.V.(type) {
case Compound: case Compound:
@ -84,7 +84,7 @@ func decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts Optio
d.Value.V = vv d.Value.V = vv
} }
if len(formats) != 1 { if len(group) != 1 {
continue continue
} }
} else { } else {
@ -113,10 +113,10 @@ func decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts Optio
d.Value.postProcess() d.Value.postProcess()
} }
return d.Value, decodeV, decodeErr return d.Value, decodeV, formatsErr
} }
return nil, nil, decodeErr return nil, nil, formatsErr
} }
type D struct { type D struct {
@ -132,7 +132,7 @@ type D struct {
// TODO: new struct decoder? // TODO: new struct decoder?
// note bb is assumed to be a non-shared buffer // note bb is assumed to be a non-shared buffer
func newDecoder(ctx context.Context, format *Format, bb *bitio.Buffer, opts Options) *D { func newDecoder(ctx context.Context, format Format, bb *bitio.Buffer, opts Options) *D {
name := format.RootName name := format.RootName
if opts.Name != "" { if opts.Name != "" {
name = opts.Name name = opts.Name
@ -141,7 +141,7 @@ func newDecoder(ctx context.Context, format *Format, bb *bitio.Buffer, opts Opti
IsArray: format.RootArray, IsArray: format.RootArray,
Children: new([]*Value), Children: new([]*Value),
Description: opts.Description, Description: opts.Description,
Format: format, Format: &format,
} }
return &D{ return &D{
@ -652,8 +652,8 @@ func (d *D) RangeFn(firstBit int64, nBits int64, fn func(d *D)) {
} }
} }
func (d *D) Format(formats []*Format, inArg interface{}) interface{} { func (d *D) Format(group Group, inArg interface{}) interface{} {
dv, v, err := decode(d.Ctx, d.bitBuf, formats, Options{ dv, v, err := decode(d.Ctx, d.bitBuf, group, Options{
Force: d.Options.Force, Force: d.Options.Force,
FillGaps: false, FillGaps: false,
IsRoot: false, IsRoot: false,
@ -681,8 +681,8 @@ func (d *D) Format(formats []*Format, inArg interface{}) interface{} {
return v return v
} }
func (d *D) FieldTryFormat(name string, formats []*Format, inArg interface{}) (*Value, interface{}, error) { func (d *D) FieldTryFormat(name string, group Group, inArg interface{}) (*Value, interface{}, error) {
dv, v, err := decode(d.Ctx, d.bitBuf, formats, Options{ dv, v, err := decode(d.Ctx, d.bitBuf, group, Options{
Name: name, Name: name,
Force: d.Options.Force, Force: d.Options.Force,
FillGaps: false, FillGaps: false,
@ -703,16 +703,16 @@ func (d *D) FieldTryFormat(name string, formats []*Format, inArg interface{}) (*
return dv, v, err return dv, v, err
} }
func (d *D) FieldFormat(name string, formats []*Format, inArg interface{}) (*Value, interface{}) { func (d *D) FieldFormat(name string, group Group, inArg interface{}) (*Value, interface{}) {
dv, v, err := d.FieldTryFormat(name, formats, inArg) dv, v, err := d.FieldTryFormat(name, group, inArg)
if dv == nil || dv.Errors() != nil { if dv == nil || dv.Errors() != nil {
panic(err) panic(err)
} }
return dv, v return dv, v
} }
func (d *D) FieldTryFormatLen(name string, nBits int64, formats []*Format, inArg interface{}) (*Value, interface{}, error) { func (d *D) FieldTryFormatLen(name string, nBits int64, group Group, inArg interface{}) (*Value, interface{}, error) {
dv, v, err := decode(d.Ctx, d.bitBuf, formats, Options{ dv, v, err := decode(d.Ctx, d.bitBuf, group, Options{
Name: name, Name: name,
Force: d.Options.Force, Force: d.Options.Force,
FillGaps: true, FillGaps: true,
@ -733,8 +733,8 @@ func (d *D) FieldTryFormatLen(name string, nBits int64, formats []*Format, inArg
return dv, v, err return dv, v, err
} }
func (d *D) FieldFormatLen(name string, nBits int64, formats []*Format, inArg interface{}) (*Value, interface{}) { func (d *D) FieldFormatLen(name string, nBits int64, group Group, inArg interface{}) (*Value, interface{}) {
dv, v, err := d.FieldTryFormatLen(name, nBits, formats, inArg) dv, v, err := d.FieldTryFormatLen(name, nBits, group, inArg)
if dv == nil || dv.Errors() != nil { if dv == nil || dv.Errors() != nil {
panic(err) panic(err)
} }
@ -742,8 +742,8 @@ func (d *D) FieldFormatLen(name string, nBits int64, formats []*Format, inArg in
} }
// TODO: return decooder? // TODO: return decooder?
func (d *D) FieldTryFormatRange(name string, firstBit int64, nBits int64, formats []*Format, inArg interface{}) (*Value, interface{}, error) { func (d *D) FieldTryFormatRange(name string, firstBit int64, nBits int64, group Group, inArg interface{}) (*Value, interface{}, error) {
dv, v, err := decode(d.Ctx, d.bitBuf, formats, Options{ dv, v, err := decode(d.Ctx, d.bitBuf, group, Options{
Name: name, Name: name,
Force: d.Options.Force, Force: d.Options.Force,
FillGaps: true, FillGaps: true,
@ -761,8 +761,8 @@ func (d *D) FieldTryFormatRange(name string, firstBit int64, nBits int64, format
return dv, v, err return dv, v, err
} }
func (d *D) FieldFormatRange(name string, firstBit int64, nBits int64, formats []*Format, inArg interface{}) (*Value, interface{}) { func (d *D) FieldFormatRange(name string, firstBit int64, nBits int64, group Group, inArg interface{}) (*Value, interface{}) {
dv, v, err := d.FieldTryFormatRange(name, firstBit, nBits, formats, inArg) dv, v, err := d.FieldTryFormatRange(name, firstBit, nBits, group, inArg)
if dv == nil || dv.Errors() != nil { if dv == nil || dv.Errors() != nil {
panic(err) panic(err)
} }
@ -770,8 +770,8 @@ func (d *D) FieldFormatRange(name string, firstBit int64, nBits int64, formats [
return dv, v return dv, v
} }
func (d *D) FieldTryFormatBitBuf(name string, bb *bitio.Buffer, formats []*Format, inArg interface{}) (*Value, interface{}, error) { func (d *D) FieldTryFormatBitBuf(name string, bb *bitio.Buffer, group Group, inArg interface{}) (*Value, interface{}, error) {
dv, v, err := decode(d.Ctx, bb, formats, Options{ dv, v, err := decode(d.Ctx, bb, group, Options{
Name: name, Name: name,
Force: d.Options.Force, Force: d.Options.Force,
FillGaps: true, FillGaps: true,
@ -788,8 +788,8 @@ func (d *D) FieldTryFormatBitBuf(name string, bb *bitio.Buffer, formats []*Forma
return dv, v, err return dv, v, err
} }
func (d *D) FieldFormatBitBuf(name string, bb *bitio.Buffer, formats []*Format, inArg interface{}) (*Value, interface{}) { func (d *D) FieldFormatBitBuf(name string, bb *bitio.Buffer, group Group, inArg interface{}) (*Value, interface{}) {
dv, v, err := d.FieldTryFormatBitBuf(name, bb, formats, inArg) dv, v, err := d.FieldTryFormatBitBuf(name, bb, group, inArg)
if dv == nil || dv.Errors() != nil { if dv == nil || dv.Errors() != nil {
panic(err) panic(err)
} }
@ -819,7 +819,7 @@ func (d *D) FieldStructRootBitBufFn(name string, bb *bitio.Buffer, fn func(d *D)
} }
// TODO: range? // TODO: range?
func (d *D) FieldFormatReaderLen(name string, nBits int64, fn func(r io.Reader) (io.ReadCloser, error), formats []*Format) (*Value, interface{}) { func (d *D) FieldFormatReaderLen(name string, nBits int64, fn func(r io.Reader) (io.ReadCloser, error), group Group) (*Value, interface{}) {
bb, err := d.bitBuf.BitBufLen(nBits) bb, err := d.bitBuf.BitBufLen(nBits)
if err != nil { if err != nil {
panic(err) panic(err)
@ -834,5 +834,5 @@ func (d *D) FieldFormatReaderLen(name string, nBits int64, fn func(r io.Reader)
} }
zbb := bitio.NewBufferFromBytes(zd, -1) zbb := bitio.NewBufferFromBytes(zd, -1)
return d.FieldFormatBitBuf(name, zbb, formats, nil) return d.FieldFormatBitBuf(name, zbb, group, nil)
} }

View File

@ -14,7 +14,7 @@ type RecoverableErrorer interface {
type FormatError struct { type FormatError struct {
Err error Err error
Format *Format Format Format
Stacktrace recoverfn.Raw Stacktrace recoverfn.Raw
} }

View File

@ -2,9 +2,11 @@ package decode
import "io/fs" import "io/fs"
type Group []Format
type Dependency struct { type Dependency struct {
Names []string Names []string
Formats *[]*Format // TODO: rename to outFormats to make it clear it's used to assign? Group *Group
} }
type Format struct { type Format struct {
@ -19,8 +21,8 @@ type Format struct {
Files fs.ReadDirFS Files fs.ReadDirFS
} }
func FormatFn(d func(d *D, in interface{}) interface{}) []*Format { func FormatFn(d func(d *D, in interface{}) interface{}) Group {
return []*Format{{ return Group{{
DecodeFn: d, DecodeFn: d,
}} }}
} }

View File

@ -0,0 +1,115 @@
package registry
import (
"errors"
"fmt"
"sort"
"sync"
"github.com/wader/fq/pkg/decode"
)
type Registry struct {
Groups map[string]decode.Group
resolveOnce sync.Once
resolved bool
}
func New() *Registry {
return &Registry{
Groups: map[string]decode.Group{},
resolveOnce: sync.Once{},
}
}
func (r *Registry) register(groupName string, format decode.Format, single bool) decode.Format { //nolint:unparam
if r.resolved {
// for now can't change after resolved
panic("registry already resolved")
}
group, ok := r.Groups[groupName]
if ok {
if !single {
panic(fmt.Sprintf("%s: format already registered", groupName))
}
} else {
group = decode.Group{}
}
r.Groups[groupName] = append(group, format)
return format
}
func (r *Registry) MustRegister(format decode.Format) decode.Format {
r.register(format.Name, format, false)
for _, g := range format.Groups {
r.register(g, format, true)
}
r.register("all", format, true)
return format
}
func sortFormats(g decode.Group) {
sort.Slice(g, func(i, j int) bool {
if g[i].ProbeOrder == g[j].ProbeOrder {
return g[i].Name < g[j].Name
}
return g[i].ProbeOrder < g[j].ProbeOrder
})
}
func (r *Registry) resolve() error {
for _, fs := range r.Groups {
for _, f := range fs {
for _, d := range f.Dependencies {
var group decode.Group
for _, dName := range d.Names {
df, ok := r.Groups[dName]
if !ok {
return fmt.Errorf("%s: can't find format dependency %s", f.Name, dName)
}
group = append(group, df...)
}
sortFormats(group)
*d.Group = group
}
}
}
for _, fs := range r.Groups {
sortFormats(fs)
}
r.resolved = true
return nil
}
func (r *Registry) Group(name string) (decode.Group, error) {
r.resolveOnce.Do(func() {
if err := r.resolve(); err != nil {
panic(err)
}
})
if g, ok := r.Groups[name]; ok {
return g, nil
}
return nil, errors.New("format group not found")
}
func (r *Registry) MustGroup(name string) decode.Group {
g, err := r.Group(name)
if err == nil {
return g
}
panic(err)
}
func (r *Registry) MustAll() decode.Group {
return r.MustGroup("all")
}

View File

@ -7,9 +7,9 @@ import (
"strconv" "strconv"
"testing" "testing"
"github.com/wader/fq/format/registry"
"github.com/wader/fq/internal/difftest" "github.com/wader/fq/internal/difftest"
"github.com/wader/fq/internal/script" "github.com/wader/fq/internal/script"
"github.com/wader/fq/pkg/decode/registry"
"github.com/wader/fq/pkg/interp" "github.com/wader/fq/pkg/interp"
) )

View File

@ -155,7 +155,7 @@ func makeHashFn(fn func() (hash.Hash, error)) func(c interface{}, a []interface{
} }
func (i *Interp) _registry(c interface{}, a []interface{}) interface{} { func (i *Interp) _registry(c interface{}, a []interface{}) interface{} {
uniqueFormats := map[string]*decode.Format{} uniqueFormats := map[string]decode.Format{}
groups := map[string]interface{}{} groups := map[string]interface{}{}
formats := map[string]interface{}{} formats := map[string]interface{}{}

View File

@ -18,7 +18,6 @@ import (
"time" "time"
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"
"github.com/wader/fq/format/registry"
"github.com/wader/fq/internal/ansi" "github.com/wader/fq/internal/ansi"
"github.com/wader/fq/internal/colorjson" "github.com/wader/fq/internal/colorjson"
"github.com/wader/fq/internal/ctxstack" "github.com/wader/fq/internal/ctxstack"
@ -27,6 +26,7 @@ import (
"github.com/wader/fq/internal/pos" "github.com/wader/fq/internal/pos"
"github.com/wader/fq/pkg/bitio" "github.com/wader/fq/pkg/bitio"
"github.com/wader/fq/pkg/decode" "github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/decode/registry"
"github.com/wader/gojq" "github.com/wader/gojq"
) )