diff --git a/doc/demo.svg b/doc/demo.svg index eee01e80..729ebf6d 100644 --- a/doc/demo.svg +++ b/doc/demo.svg @@ -1,4 +1,4 @@ - + diff --git a/doc/demo.svg.sh b/doc/demo.svg.sh index 6297d0ed..213885fa 100755 --- a/doc/demo.svg.sh +++ b/doc/demo.svg.sh @@ -14,8 +14,8 @@ s() { c "Overview of mp3 file" s "fq . file.mp3" echo -c "Show ID3v2 tag inside mp3 file" -s "fq '.headers[0]' file.mp3" +c "Show header of first ID3v2 tag inside mp3 file" +s "fq '.headers[0].header' file.mp3" echo c "Show encoder software used" s "fq -r '.frames[0].tag.encoder | tovalue' file.mp3" diff --git a/format/id3/id3v2.go b/format/id3/id3v2.go index eab5562f..286a68c8 100644 --- a/format/id3/id3v2.go +++ b/format/id3/id3v2.go @@ -433,6 +433,7 @@ func decodeFrame(d *decode.D, version int) uint64 { d.FieldStrFn("entry", textNullFn(encodingUTF8)) } }) + decodeFrames(d, version, uint64(d.BitsLeft()/8)) }, // id3v2.0 @@ -607,23 +608,23 @@ func decodeFrames(d *decode.D, version int, size uint64) { } func id3v2Decode(d *decode.D) any { - d.AssertAtLeastBitsLeft(4 * 8) - d.FieldUTF8("magic", 3, d.StrAssert("ID3")) - version := int(d.FieldU8("version")) - versionValid := version == 2 || version == 3 || version == 4 - if !versionValid { - d.Fatalf("unsupported version %d", version) - } - - d.FieldU8("revision") + var version uint64 var extendedHeader bool - d.FieldStruct("flags", func(d *decode.D) { - d.FieldBool("unsynchronisation") - extendedHeader = d.FieldBool("extended_header") - d.FieldBool("experimental_indicator") - d.FieldU5("unused") + var size uint64 + + d.AssertAtLeastBitsLeft(4 * 8) + d.FieldStruct("header", func(d *decode.D) { + d.FieldUTF8("magic", 3, d.StrAssert("ID3")) + version = d.FieldU8("version", d.UintAssert(2, 3, 4)) + d.FieldU8("revision") + d.FieldStruct("flags", func(d *decode.D) { + d.FieldBool("unsynchronisation") + extendedHeader = d.FieldBool("extended_header") + d.FieldBool("experimental_indicator") + d.FieldU5("unused") + }) + size = d.FieldUintFn("size", decodeSyncSafeU32) }) - size := d.FieldUintFn("size", decodeSyncSafeU32) var extHeaderSize uint64 if extendedHeader { @@ -640,7 +641,7 @@ func id3v2Decode(d *decode.D) any { }) } - decodeFrames(d, version, size) + decodeFrames(d, int(version), size) return nil } diff --git a/format/id3/testdata/apic.fqtest b/format/id3/testdata/apic.fqtest index 15f05684..4fe5fecb 100644 --- a/format/id3/testdata/apic.fqtest +++ b/format/id3/testdata/apic.fqtest @@ -2,15 +2,16 @@ # fq test.mp3 '.. | select(format == "id3v2")._bytes' > apic $ fq -d id3v2 dv apic |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: apic (id3v2) 0x0-0xb3.7 (180) -0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) -0x00| 04 | . | version: 4 0x3-0x3.7 (1) -0x00| 00 | . | revision: 0 0x4-0x4.7 (1) - | | | flags{}: 0x5-0x5.7 (1) -0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) -0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) -0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) -0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) -0x00| 00 00 01 2a | ...* | size: 170 0x6-0x9.7 (4) + | | | header{}: 0x0-0x9.7 (10) +0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) +0x00| 04 | . | version: 4 (valid) 0x3-0x3.7 (1) +0x00| 00 | . | revision: 0 0x4-0x4.7 (1) + | | | flags{}: 0x5-0x5.7 (1) +0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) +0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) +0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) +0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) +0x00| 00 00 01 2a | ...* | size: 170 0x6-0x9.7 (4) | | | frames[0:2]: 0xa-0xa9.7 (160) | | | [0]{}: frame 0xa-0x22.7 (25) 0x00| 54 53 53 45 | TSSE | id: "TSSE" (Software/Hardware and settings used for encoding) 0xa-0xd.7 (4) diff --git a/format/id3/testdata/ctoc b/format/id3/testdata/ctoc new file mode 100644 index 00000000..247d357c Binary files /dev/null and b/format/id3/testdata/ctoc differ diff --git a/format/id3/testdata/ctoc.fqtest b/format/id3/testdata/ctoc.fqtest new file mode 100644 index 00000000..06acaaba --- /dev/null +++ b/format/id3/testdata/ctoc.fqtest @@ -0,0 +1,71 @@ +$ fq -d id3v2 dv ctoc + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: ctoc (id3v2) 0x0-0x9e.7 (159) + | | | header{}: 0x0-0x9.7 (10) +0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) +0x00| 03 | . | version: 3 (valid) 0x3-0x3.7 (1) +0x00| 00 | . | revision: 0 0x4-0x4.7 (1) + | | | flags{}: 0x5-0x5.7 (1) +0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) +0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) +0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) +0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) +0x00| 00 00 01 95 | .... | size: 149 0x6-0x9.7 (4) + | | | frames[0:1]: 0xa-0x9e.7 (149) + | | | [0]{}: frame 0xa-0x9e.7 (149) +0x00| 43 54 4f 43 | CTOC | id: "CTOC" (Table of contents) 0xa-0xd.7 (4) +0x00| 00 00| ..| size: 139 0xe-0x11.7 (4) +0x10|00 8b |.. | + | | | flags{}: 0x12-0x13.7 (2) +0x10| 00 | . | tag_alter_preservation: false 0x12-0x12 (0.1) +0x10| 00 | . | file_alter_preservation: false 0x12.1-0x12.1 (0.1) +0x10| 00 | . | read_only: false 0x12.2-0x12.2 (0.1) +0x10| 00 | . | unused0: 0 0x12.3-0x12.7 (0.5) +0x10| 00 | . | compression: false 0x13-0x13 (0.1) +0x10| 00 | . | encryption: false 0x13.1-0x13.1 (0.1) +0x10| 00 | . | grouping_identity: false 0x13.2-0x13.2 (0.1) +0x10| 00 | . | unused1: 0 0x13.3-0x13.7 (0.5) +0x10| 54 4f 43 4d 00 | TOCM. | element_id: "TOCM" 0x14-0x18.7 (5) +0x10| 03 | . | ctoc_flags: 3 0x19-0x19.7 (1) +0x10| 13 | . | entry_count: 19 0x1a-0x1a.7 (1) + | | | entries[0:19]: 0x1b-0x6f.7 (85) +0x10| 63 68 30 00 | ch0. | [0]: "ch0" entry 0x1b-0x1e.7 (4) +0x10| 63| c| [1]: "ch1" entry 0x1f-0x22.7 (4) +0x20|68 31 00 |h1. | +0x20| 63 68 32 00 | ch2. | [2]: "ch2" entry 0x23-0x26.7 (4) +0x20| 63 68 33 00 | ch3. | [3]: "ch3" entry 0x27-0x2a.7 (4) +0x20| 63 68 34 00 | ch4. | [4]: "ch4" entry 0x2b-0x2e.7 (4) +0x20| 63| c| [5]: "ch5" entry 0x2f-0x32.7 (4) +0x30|68 35 00 |h5. | +0x30| 63 68 36 00 | ch6. | [6]: "ch6" entry 0x33-0x36.7 (4) +0x30| 63 68 37 00 | ch7. | [7]: "ch7" entry 0x37-0x3a.7 (4) +0x30| 63 68 38 00 | ch8. | [8]: "ch8" entry 0x3b-0x3e.7 (4) +0x30| 63| c| [9]: "ch9" entry 0x3f-0x42.7 (4) +0x40|68 39 00 |h9. | +0x40| 63 68 31 30 00 | ch10. | [10]: "ch10" entry 0x43-0x47.7 (5) +0x40| 63 68 31 31 00 | ch11. | [11]: "ch11" entry 0x48-0x4c.7 (5) +0x40| 63 68 31| ch1| [12]: "ch12" entry 0x4d-0x51.7 (5) +0x50|32 00 |2. | +0x50| 63 68 31 33 00 | ch13. | [13]: "ch13" entry 0x52-0x56.7 (5) +0x50| 63 68 31 34 00 | ch14. | [14]: "ch14" entry 0x57-0x5b.7 (5) +0x50| 63 68 31 35| ch15| [15]: "ch15" entry 0x5c-0x60.7 (5) +0x60|00 |. | +0x60| 63 68 31 36 00 | ch16. | [16]: "ch16" entry 0x61-0x65.7 (5) +0x60| 63 68 31 37 00 | ch17. | [17]: "ch17" entry 0x66-0x6a.7 (5) +0x60| 63 68 31 38 00| ch18.| [18]: "ch18" entry 0x6b-0x6f.7 (5) + | | | frames[0:1]: 0x70-0x9e.7 (47) + | | | [0]{}: frame 0x70-0x9e.7 (47) +0x70|54 49 54 32 |TIT2 | id: "TIT2" (Title/songname/content description) 0x70-0x73.7 (4) +0x70| 00 00 00 25 | ...% | size: 37 0x74-0x77.7 (4) + | | | flags{}: 0x78-0x79.7 (2) +0x70| 00 | . | tag_alter_preservation: false 0x78-0x78 (0.1) +0x70| 00 | . | file_alter_preservation: false 0x78.1-0x78.1 (0.1) +0x70| 00 | . | read_only: false 0x78.2-0x78.2 (0.1) +0x70| 00 | . | unused0: 0 0x78.3-0x78.7 (0.5) +0x70| 00 | . | compression: false 0x79-0x79 (0.1) +0x70| 00 | . | encryption: false 0x79.1-0x79.1 (0.1) +0x70| 00 | . | grouping_identity: false 0x79.2-0x79.2 (0.1) +0x70| 00 | . | unused1: 0 0x79.3-0x79.7 (0.5) +0x70| 01 | . | text_encoding: "utf16" (1) 0x7a-0x7a.7 (1) +0x70| ff fe 54 00 61| ..T.a| text: "Table of contents" 0x7b-0x9e.7 (36) +0x80|00 62 00 6c 00 65 00 20 00 6f 00 66 00 20 00 63|.b.l.e. .o.f. .c| +0x90|00 6f 00 6e 00 74 00 65 00 6e 00 74 00 73 00| |.o.n.t.e.n.t.s.|| diff --git a/format/id3/testdata/id3v23.fqtest b/format/id3/testdata/id3v23.fqtest index eb7aca4d..94563f51 100644 --- a/format/id3/testdata/id3v23.fqtest +++ b/format/id3/testdata/id3v23.fqtest @@ -1,15 +1,16 @@ # ffmpeg -f lavfi -i sine -t 0s -id3v2_version 3 -f mp3 pipe:1 > id3v23 $ fq -d id3v2 dv id3v23 |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: id3v23 (id3v2) 0x0-0x2c.7 (45) -0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) -0x00| 03 | . | version: 3 0x3-0x3.7 (1) -0x00| 00 | . | revision: 0 0x4-0x4.7 (1) - | | | flags{}: 0x5-0x5.7 (1) -0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) -0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) -0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) -0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) -0x00| 00 00 00 23 | ...# | size: 35 0x6-0x9.7 (4) + | | | header{}: 0x0-0x9.7 (10) +0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) +0x00| 03 | . | version: 3 (valid) 0x3-0x3.7 (1) +0x00| 00 | . | revision: 0 0x4-0x4.7 (1) + | | | flags{}: 0x5-0x5.7 (1) +0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) +0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) +0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) +0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) +0x00| 00 00 00 23 | ...# | size: 35 0x6-0x9.7 (4) | | | frames[0:1]: 0xa-0x22.7 (25) | | | [0]{}: frame 0xa-0x22.7 (25) 0x00| 54 53 53 45 | TSSE | id: "TSSE" (Software/Hardware and settings used for encoding) 0xa-0xd.7 (4) diff --git a/format/id3/testdata/id3v24.fqtest b/format/id3/testdata/id3v24.fqtest index 8791e122..b9189ed0 100644 --- a/format/id3/testdata/id3v24.fqtest +++ b/format/id3/testdata/id3v24.fqtest @@ -1,15 +1,16 @@ # ffmpeg -f lavfi -i sine -t 0s -id3v2_version 4 -f mp3 pipe:1 > id3v24 $ fq -d id3v2 dv id3v24 |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: id3v24 (id3v2) 0x0-0x2c.7 (45) -0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) -0x00| 04 | . | version: 4 0x3-0x3.7 (1) -0x00| 00 | . | revision: 0 0x4-0x4.7 (1) - | | | flags{}: 0x5-0x5.7 (1) -0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) -0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) -0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) -0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) -0x00| 00 00 00 23 | ...# | size: 35 0x6-0x9.7 (4) + | | | header{}: 0x0-0x9.7 (10) +0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) +0x00| 04 | . | version: 4 (valid) 0x3-0x3.7 (1) +0x00| 00 | . | revision: 0 0x4-0x4.7 (1) + | | | flags{}: 0x5-0x5.7 (1) +0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) +0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) +0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) +0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) +0x00| 00 00 00 23 | ...# | size: 35 0x6-0x9.7 (4) | | | frames[0:1]: 0xa-0x22.7 (25) | | | [0]{}: frame 0xa-0x22.7 (25) 0x00| 54 53 53 45 | TSSE | id: "TSSE" (Software/Hardware and settings used for encoding) 0xa-0xd.7 (4) diff --git a/format/id3/testdata/txxx-nonullterm.fqtest b/format/id3/testdata/txxx-nonullterm.fqtest index f12bc2b9..c65fa682 100644 --- a/format/id3/testdata/txxx-nonullterm.fqtest +++ b/format/id3/testdata/txxx-nonullterm.fqtest @@ -1,14 +1,15 @@ $ fq -d id3v2 dv txxx-nonullterm |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: txxx-nonullterm (id3v2) 0x0-0x26.7 (39) -0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) -0x00| 03 | . | version: 3 0x3-0x3.7 (1) -0x00| 00 | . | revision: 0 0x4-0x4.7 (1) - | | | flags{}: 0x5-0x5.7 (1) -0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) -0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) -0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) -0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) -0x00| 00 00 00 1d | .... | size: 29 0x6-0x9.7 (4) + | | | header{}: 0x0-0x9.7 (10) +0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) +0x00| 03 | . | version: 3 (valid) 0x3-0x3.7 (1) +0x00| 00 | . | revision: 0 0x4-0x4.7 (1) + | | | flags{}: 0x5-0x5.7 (1) +0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) +0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) +0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) +0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) +0x00| 00 00 00 1d | .... | size: 29 0x6-0x9.7 (4) | | | frames[0:1]: 0xa-0x26.7 (29) | | | [0]{}: frame 0xa-0x26.7 (29) 0x00| 54 58 58 58 | TXXX | id: "TXXX" (User defined text information frame) 0xa-0xd.7 (4) diff --git a/format/id3/testdata/utf16-apic.fqtest b/format/id3/testdata/utf16-apic.fqtest index 87529581..ef4ec800 100644 --- a/format/id3/testdata/utf16-apic.fqtest +++ b/format/id3/testdata/utf16-apic.fqtest @@ -4,15 +4,16 @@ # fq test.mp3 .headers[0]._bits > utf16-apic $ fq -d id3v2 dv utf16-apic |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: utf16-apic (id3v2) 0x0-0x255.7 (598) -0x000|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) -0x000| 04 | . | version: 4 0x3-0x3.7 (1) -0x000| 00 | . | revision: 0 0x4-0x4.7 (1) - | | | flags{}: 0x5-0x5.7 (1) -0x000| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) -0x000| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) -0x000| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) -0x000| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) -0x000| 00 00 04 4c | ...L | size: 588 0x6-0x9.7 (4) + | | | header{}: 0x0-0x9.7 (10) +0x000|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) +0x000| 04 | . | version: 4 (valid) 0x3-0x3.7 (1) +0x000| 00 | . | revision: 0 0x4-0x4.7 (1) + | | | flags{}: 0x5-0x5.7 (1) +0x000| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) +0x000| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) +0x000| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) +0x000| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) +0x000| 00 00 04 4c | ...L | size: 588 0x6-0x9.7 (4) | | | frames[0:2]: 0xa-0x155.7 (332) | | | [0]{}: frame 0xa-0x12e.7 (293) 0x000| 41 50 49 43 | APIC | id: "APIC" (Attached picture) 0xa-0xd.7 (4) diff --git a/format/mp3/testdata/header-zeros-frames.fqtest b/format/mp3/testdata/header-zeros-frames.fqtest index 645e5de5..90dadf67 100644 --- a/format/mp3/testdata/header-zeros-frames.fqtest +++ b/format/mp3/testdata/header-zeros-frames.fqtest @@ -3,15 +3,16 @@ $ fq -d mp3 dv header-zeros-frames.mp3 |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: header-zeros-frames.mp3 (mp3) 0x0-0xff.7 (256) | | | headers[0:1]: 0x0-0x2c.7 (45) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| [0]{}: header (id3v2) 0x0-0x2c.7 (45) -0x000|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) -0x000| 04 | . | version: 4 0x3-0x3.7 (1) -0x000| 00 | . | revision: 0 0x4-0x4.7 (1) - | | | flags{}: 0x5-0x5.7 (1) -0x000| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) -0x000| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) -0x000| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) -0x000| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) -0x000| 00 00 00 23 | ...# | size: 35 0x6-0x9.7 (4) + | | | header{}: 0x0-0x9.7 (10) +0x000|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) +0x000| 04 | . | version: 4 (valid) 0x3-0x3.7 (1) +0x000| 00 | . | revision: 0 0x4-0x4.7 (1) + | | | flags{}: 0x5-0x5.7 (1) +0x000| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) +0x000| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) +0x000| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) +0x000| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) +0x000| 00 00 00 23 | ...# | size: 35 0x6-0x9.7 (4) | | | frames[0:1]: 0xa-0x22.7 (25) | | | [0]{}: frame 0xa-0x22.7 (25) 0x000| 54 53 53 45 | TSSE | id: "TSSE" (Software/Hardware and settings used for encoding) 0xa-0xd.7 (4) diff --git a/format/mp3/testdata/headerfooter.fqtest b/format/mp3/testdata/headerfooter.fqtest index 36a99c96..3d6bde9d 100644 --- a/format/mp3/testdata/headerfooter.fqtest +++ b/format/mp3/testdata/headerfooter.fqtest @@ -3,15 +3,16 @@ $ fq -d mp3 dv headerfooter.mp3 |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: headerfooter.mp3 (mp3) 0x0-0x25d.7 (606) | | | headers[0:1]: 0x0-0x3c.7 (61) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| [0]{}: header (id3v2) 0x0-0x3c.7 (61) -0x000|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) -0x000| 04 | . | version: 4 0x3-0x3.7 (1) -0x000| 00 | . | revision: 0 0x4-0x4.7 (1) - | | | flags{}: 0x5-0x5.7 (1) -0x000| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) -0x000| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) -0x000| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) -0x000| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) -0x000| 00 00 00 33 | ...3 | size: 51 0x6-0x9.7 (4) + | | | header{}: 0x0-0x9.7 (10) +0x000|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3) +0x000| 04 | . | version: 4 (valid) 0x3-0x3.7 (1) +0x000| 00 | . | revision: 0 0x4-0x4.7 (1) + | | | flags{}: 0x5-0x5.7 (1) +0x000| 00 | . | unsynchronisation: false 0x5-0x5 (0.1) +0x000| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1) +0x000| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1) +0x000| 00 | . | unused: 0 0x5.3-0x5.7 (0.5) +0x000| 00 00 00 33 | ...3 | size: 51 0x6-0x9.7 (4) | | | frames[0:2]: 0xa-0x32.7 (41) | | | [0]{}: frame 0xa-0x19.7 (16) 0x000| 54 49 54 32 | TIT2 | id: "TIT2" (Title/songname/content description) 0xa-0xd.7 (4) diff --git a/format/mp4/testdata/dash.fqtest b/format/mp4/testdata/dash.fqtest index c144e821..7b6ccff0 100644 --- a/format/mp4/testdata/dash.fqtest +++ b/format/mp4/testdata/dash.fqtest @@ -72,16 +72,17 @@ $ fq -d mp4 dv dash_audio_init.mp4 0x0c0| 15 | . | pad: 0 0xcc-0xcc (0.1) 0x0c0| 15 c7 | .. | language: "eng" 0xcc.1-0xcd.7 (1.7) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| data{}: (id3v2) 0xce-0x11a.7 (77) -0x0c0| 49 44| ID| magic: "ID3" (valid) 0xce-0xd0.7 (3) + | | | header{}: 0xce-0xd7.7 (10) +0x0c0| 49 44| ID| magic: "ID3" (valid) 0xce-0xd0.7 (3) 0x0d0|33 |3 | -0x0d0| 04 | . | version: 4 0xd1-0xd1.7 (1) -0x0d0| 00 | . | revision: 0 0xd2-0xd2.7 (1) - | | | flags{}: 0xd3-0xd3.7 (1) -0x0d0| 00 | . | unsynchronisation: false 0xd3-0xd3 (0.1) -0x0d0| 00 | . | extended_header: false 0xd3.1-0xd3.1 (0.1) -0x0d0| 00 | . | experimental_indicator: false 0xd3.2-0xd3.2 (0.1) -0x0d0| 00 | . | unused: 0 0xd3.3-0xd3.7 (0.5) -0x0d0| 00 00 00 43 | ...C | size: 67 0xd4-0xd7.7 (4) +0x0d0| 04 | . | version: 4 (valid) 0xd1-0xd1.7 (1) +0x0d0| 00 | . | revision: 0 0xd2-0xd2.7 (1) + | | | flags{}: 0xd3-0xd3.7 (1) +0x0d0| 00 | . | unsynchronisation: false 0xd3-0xd3 (0.1) +0x0d0| 00 | . | extended_header: false 0xd3.1-0xd3.1 (0.1) +0x0d0| 00 | . | experimental_indicator: false 0xd3.2-0xd3.2 (0.1) +0x0d0| 00 | . | unused: 0 0xd3.3-0xd3.7 (0.5) +0x0d0| 00 00 00 43 | ...C | size: 67 0xd4-0xd7.7 (4) | | | frames[0:1]: 0xd8-0x11a.7 (67) | | | [0]{}: frame 0xd8-0x11a.7 (67) 0x0d0| 50 52 49 56 | PRIV | id: "PRIV" (Private frame) 0xd8-0xdb.7 (4) @@ -578,15 +579,16 @@ $ fq -d mp4 dv dash_video_init.mp4 0x00d0|15 |. | pad: 0 0xd0-0xd0 (0.1) 0x00d0|15 c7 |.. | language: "eng" 0xd0.1-0xd1.7 (1.7) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| data{}: (id3v2) 0xd2-0x11e.7 (77) -0x00d0| 49 44 33 | ID3 | magic: "ID3" (valid) 0xd2-0xd4.7 (3) -0x00d0| 04 | . | version: 4 0xd5-0xd5.7 (1) -0x00d0| 00 | . | revision: 0 0xd6-0xd6.7 (1) - | | | flags{}: 0xd7-0xd7.7 (1) -0x00d0| 00 | . | unsynchronisation: false 0xd7-0xd7 (0.1) -0x00d0| 00 | . | extended_header: false 0xd7.1-0xd7.1 (0.1) -0x00d0| 00 | . | experimental_indicator: false 0xd7.2-0xd7.2 (0.1) -0x00d0| 00 | . | unused: 0 0xd7.3-0xd7.7 (0.5) -0x00d0| 00 00 00 43 | ...C | size: 67 0xd8-0xdb.7 (4) + | | | header{}: 0xd2-0xdb.7 (10) +0x00d0| 49 44 33 | ID3 | magic: "ID3" (valid) 0xd2-0xd4.7 (3) +0x00d0| 04 | . | version: 4 (valid) 0xd5-0xd5.7 (1) +0x00d0| 00 | . | revision: 0 0xd6-0xd6.7 (1) + | | | flags{}: 0xd7-0xd7.7 (1) +0x00d0| 00 | . | unsynchronisation: false 0xd7-0xd7 (0.1) +0x00d0| 00 | . | extended_header: false 0xd7.1-0xd7.1 (0.1) +0x00d0| 00 | . | experimental_indicator: false 0xd7.2-0xd7.2 (0.1) +0x00d0| 00 | . | unused: 0 0xd7.3-0xd7.7 (0.5) +0x00d0| 00 00 00 43 | ...C | size: 67 0xd8-0xdb.7 (4) | | | frames[0:1]: 0xdc-0x11e.7 (67) | | | [0]{}: frame 0xdc-0x11e.7 (67) 0x00d0| 50 52 49 56| PRIV| id: "PRIV" (Private frame) 0xdc-0xdf.7 (4) diff --git a/pkg/interp/testdata/basic.fqtest b/pkg/interp/testdata/basic.fqtest index 74009adb..b3c371d6 100644 --- a/pkg/interp/testdata/basic.fqtest +++ b/pkg/interp/testdata/basic.fqtest @@ -1,12 +1,12 @@ # ffmpeg -f lavfi -i sine -t 10ms test.mp3 $ fq -i . test.mp3 -mp3> .headers[0].magic == "ID3" +mp3> .headers[0].header.magic == "ID3" true -mp3> .headers[0].version == 4 +mp3> .headers[0].header.version == 4 true mp3> .frames[0].header.protection == true false -mp3> .headers[0].flags + {} +mp3> .headers[0].header.flags + {} { "experimental_indicator": false, "extended_header": false, @@ -17,11 +17,11 @@ mp3> ._gap false mp3> format "mp3" -mp3> .headers[0].magic | format +mp3> .headers[0].header.magic | format null mp3> ._format "mp3" -mp3> .headers[0].magic._format +mp3> .headers[0].header.magic._format null mp3> ^D # TODO: use test format diff --git a/pkg/interp/testdata/binary.fqtest b/pkg/interp/testdata/binary.fqtest index be458c82..f5302c00 100644 --- a/pkg/interp/testdata/binary.fqtest +++ b/pkg/interp/testdata/binary.fqtest @@ -1,13 +1,13 @@ -$ fq -d mp3 '.headers[0].magic._bits[8:16] | hd' test.mp3 +$ fq -d mp3 '.headers[0].header.magic._bits[8:16] | hd' test.mp3 |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0| 44 | D |.: raw bits 0x1-0x1.7 (1) -$ fq -d mp3 '.headers[0].magic._bits | [.[8:16], .[0:8]] | hd' test.mp3 +$ fq -d mp3 '.headers[0].header.magic._bits | [.[8:16], .[0:8]] | hd' test.mp3 |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0|44 49| |DI| |.: raw bits 0x0-0x1.7 (2) -$ fq -d mp3 '.headers[0].magic._bits | [.[8:16], .[0:8]] | tobits | hd' test.mp3 +$ fq -d mp3 '.headers[0].header.magic._bits | [.[8:16], .[0:8]] | tobits | hd' test.mp3 |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0|44 49| |DI| |.: raw bits 0x0-0x1.7 (2) -$ fq -d mp3 '.headers[0].magic._bits | [.[8:16], .[0:8]] | tobytes | hd' test.mp3 +$ fq -d mp3 '.headers[0].header.magic._bits | [.[8:16], .[0:8]] | tobytes | hd' test.mp3 |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0|44 49| |DI| |.: raw bits 0x0-0x1.7 (2) $ fq -n '"12" | tobytes | hd' @@ -33,7 +33,7 @@ $ fq -d mp3 '.frames[]._bits[0:12] | tonumber' test.mp3 4095 4095 4095 -$ fq -d mp3 '.headers[0].magic._bits[0:24] | tostring' test.mp3 +$ fq -d mp3 '.headers[0].header.magic._bits[0:24] | tostring' test.mp3 "ID3" $ fq -d mp3 '.frames[0].audio_data | ("", "md5", "base64", "snippet") as $f | tovalue({bits_format: $f})' test.mp3 "<5>AAAAAAA=" @@ -47,7 +47,7 @@ mp3> [1, 2, 3] | tobytes mp3> [1, 2, 3, [1, 2, 3]] | tobytes |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0|01 02 03 01 02 03| |......| |.: raw bits 0x0-0x5.7 (6) -mp3> [1, 2, 3, [1, 2, 3], .headers[0].magic] | tobytes +mp3> [1, 2, 3, [1, 2, 3], .headers[0].header.magic] | tobytes |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0|01 02 03 01 02 03 49 44 33| |......ID3| |.: raw bits 0x0-0x8.7 (9) mp3> [-1] | tobytes diff --git a/pkg/interp/testdata/decode.fqtest b/pkg/interp/testdata/decode.fqtest index 649f6abf..f9b40504 100644 --- a/pkg/interp/testdata/decode.fqtest +++ b/pkg/interp/testdata/decode.fqtest @@ -59,7 +59,7 @@ mp3> .[] = 1 "frames": 1, "headers": 1 } -mp3> walk(tovalue) | .headers[0].magic +mp3> walk(tovalue) | .headers[0].header.magic "ID3" mp3> ^D $ fq -d bytes 'png | d' test.mp3 diff --git a/pkg/interp/testdata/exprfile.fqtest b/pkg/interp/testdata/exprfile.fqtest index fc1e8f95..6a0fbdde 100644 --- a/pkg/interp/testdata/exprfile.fqtest +++ b/pkg/interp/testdata/exprfile.fqtest @@ -1,7 +1,7 @@ /test.jq: 123 /test2.jq: -.headers[0].magic | tovalue +.headers[0].header.magic | tovalue /err.jq: asdad) $ fq -n -f test.jq diff --git a/pkg/interp/testdata/gojq.fqtest b/pkg/interp/testdata/gojq.fqtest index c8aac5cb..bea77d07 100644 --- a/pkg/interp/testdata/gojq.fqtest +++ b/pkg/interp/testdata/gojq.fqtest @@ -24,11 +24,11 @@ $ fq -n '{a:1, b: 2} | tostream' "b" ] ] -$ fq -d mp3 '{(.headers[0].magic): 123}' test.mp3 +$ fq -d mp3 '{(.headers[0].header.magic): 123}' test.mp3 { "ID3": 123 } -$ fq -d mp3 '{(.headers[0].magic): 123}' test.mp3 +$ fq -d mp3 '{(.headers[0].header.magic): 123}' test.mp3 { "ID3": 123 } @@ -257,12 +257,6 @@ $ fq -d mp3 '.frames[0] | to_entries[].key' test.mp3 # TODO: move this test as it depends on xml $ fq -r '.headers[0] | to_xml({indent: 2})' test.mp3 - - false - false - false - 0 - false @@ -282,11 +276,19 @@ $ fq -r '.headers[0] | to_xml({indent: 2})' test.mp3 Lavf58.45.100 utf8 - ID3 +
+ + false + false + false + 0 + + ID3 + 0 + 35 + 4 +
���������� - 0 - 35 - 4
$ fq -i null> 0b0_1 @@ -309,5 +311,5 @@ null> 0x012_3456789abcdefx ^ unexpected token "x" null> ^D # test JQValue in assign/update path -$ fq -c -d mp3 '.headers[0].version as $i | [] | .[$i] = 1 | .[$i] += 2' test.mp3 +$ fq -c -d mp3 '.headers[0].header.version as $i | [] | .[$i] = 1 | .[$i] += 2' test.mp3 [null,null,null,null,3] diff --git a/pkg/interp/testdata/grep.fqtest b/pkg/interp/testdata/grep.fqtest index 32aa26ce..5a2c1ede 100644 --- a/pkg/interp/testdata/grep.fqtest +++ b/pkg/interp/testdata/grep.fqtest @@ -11,15 +11,15 @@ mp3> grep(44100, "ID", "^ID3$", "^ID.?$", "Info", "magic", "\u00ff", [0x49, 0x44 0x1d0|20 d4 29 52 98 c8 c8 f9 13 80 40 24 bc 91 23 42| .)R......@$..#B| * |until 0x283.7 (end) (188) | | |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x40| 49 6e 66 6f | Info |.frames[0].tag.header: "Info" (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) mp3> vgrep(44100, "ID", "^ID3$", "^ID.?$", "Info", "magic", "\u00ff", [0x49, 0x44]) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x20| 40| @|.frames[0].header.sample_rate: 44100 (0) @@ -28,31 +28,31 @@ mp3> vgrep(44100, "ID", "^ID3$", "^ID.?$", "Info", "magic", "\u00ff", [0x49, 0x4 |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x1b0| 52 | R |.frames[2].header.sample_rate: 44100 (0) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x40| 49 6e 66 6f | Info |.frames[0].tag.header: "Info" (valid) mp3> fgrep(44100, "ID", "^ID3$", "^ID.?$", "Info", "magic", "\u00ff", [0x49, 0x44]) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) mp3> bgrep(44100, "ID", "^ID3$", "^ID.?$", "Info", "magic", "\u00ff", [0x49, 0x44]) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x1c0| 11 4b 36 4a 08 83 58 c9| .K6J..X.|.frames[2].audio_data: raw bits 0x1d0|20 d4 29 52 98 c8 c8 f9 13 80 40 24 bc 91 23 42| .)R......@$..#B| * |until 0x283.7 (end) (188) | | |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x40| 49 6e 66 6f | Info |.frames[0].tag.header: "Info" (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) mp3> "64ff65ff66" | fromhex | bgrep("\u00ff"; "b") |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0|64 ff 65 ff 66| |d.e.f| |.: raw bits 0x0-0x4.7 (5) @@ -65,11 +65,7 @@ mp3> grep_by(. == 44100) 0x1b0| 52 | R |.frames[2].header.sample_rate: 44100 (0) mp3> grep_by(format == "id3v2") |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0]{}: header (id3v2) -0x00|49 44 33 |ID3 | magic: "ID3" (valid) -0x00| 04 | . | version: 4 -0x00| 00 | . | revision: 0 -0x00| 00 | . | flags{}: -0x00| 00 00 00 23 | ...# | size: 35 +0x00|49 44 33 04 00 00 00 00 00 23 |ID3......# | header{}: 0x00| 54 53 53 45 00 00| TSSE..| frames[0:1]: 0x10|00 0f 00 00 03 4c 61 76 66 35 38 2e 34 35 2e 31|.....Lavf58.45.1| 0x20|30 30 00 |00. | diff --git a/pkg/interp/testdata/value.fqtest b/pkg/interp/testdata/value.fqtest index b59bff59..eb5b4975 100644 --- a/pkg/interp/testdata/value.fqtest +++ b/pkg/interp/testdata/value.fqtest @@ -7,26 +7,20 @@ $ fq -d mp3 '.headers[].frames[0].size // 123' test.mp3 0x00| 00 00| ..|.headers[0].frames[0].size: 15 0x10|00 0f |.. | # test each in decoded order -$ fq -d mp3 '.headers[0][]' test.mp3 +$ fq -d mp3 '.headers[0].header[]' test.mp3 |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0| 04 | . |.headers[0].version: 4 +0x0| 04 | . |.headers[0].header.version: 4 (valid) |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0| 00 | . |.headers[0].revision: 0 - |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0].flags{}: +0x0| 00 | . |.headers[0].header.revision: 0 + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0].header.flags{}: 0x0| 00 | . | unsynchronisation: false 0x0| 00 | . | extended_header: false 0x0| 00 | . | experimental_indicator: false 0x0| 00 | . | unused: 0 |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0| 00 00 00 23 | ...# |.headers[0].size: 35 - |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0].frames[0:1]: -0x00| 54 53 53 45 00 00| TSSE..| [0]{}: frame -0x10|00 0f 00 00 03 4c 61 76 66 35 38 2e 34 35 2e 31|.....Lavf58.45.1| -0x20|30 30 00 |00. | - |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x20| 00 00 00 00 00 00 00 00 00 00 | .......... |.headers[0].padding: raw bits (all zero) +0x0| 00 00 00 23 | ...# |.headers[0].header.size: 35 # TODO: proper buffer_root test $ fq -d mp3 -i . test.mp3 mp3> .frames[0].header.mpeg_version | (topath | path_to_expr), tovalue, toactual, tosym, todescription @@ -47,12 +41,13 @@ mp3> . | (root, buffer_root, format_root, parent | try (topath | path_to_expr) c "." "expected decode value but got: null (null)" [] -mp3> .headers[0].magic | (root, buffer_root, format_root, parent | topath | path_to_expr), [parents | topath | path_to_expr] +mp3> .headers[0].header.magic | (root, buffer_root, format_root, parent | topath | path_to_expr), [parents | topath | path_to_expr] "." "." ".headers[0]" -".headers[0]" +".headers[0].header" [ + ".headers[0].header", ".headers[0]", ".headers", "." @@ -93,7 +88,7 @@ mp3> .headers as $c | (0, "abc") as $n | $n, try ($c | has($n)) catch . true "abc" "cannot check whether array has a key: abc" -mp3> .headers[0].magic as $c | (0, "abc") as $n | $n, try ($c | has($n)) catch . +mp3> .headers[0].header.magic as $c | (0, "abc") as $n | $n, try ($c | has($n)) catch . 0 "has cannot be applied to: string" "abc" @@ -168,7 +163,7 @@ true true "_abc" "expected a extkey but got: _abc" -mp3> .headers[0].magic as $c | ("_start", "_stop", "_len", "_name", "_root", "_buffer_root", "_format_root", "_parent", "_sym", "_description", "_path", "_bits", "_bytes", "_error", "_gap", "_format", "_abc") as $n | $n, try ($c | has($n)) catch . +mp3> .headers[0].header.magic as $c | ("_start", "_stop", "_len", "_name", "_root", "_buffer_root", "_format_root", "_parent", "_sym", "_description", "_path", "_bits", "_bytes", "_error", "_gap", "_format", "_abc") as $n | $n, try ($c | has($n)) catch . "_start" true "_stop" diff --git a/pkg/interp/testdata/value_array.fqtest b/pkg/interp/testdata/value_array.fqtest index 48ff91fc..b7e068bb 100644 --- a/pkg/interp/testdata/value_array.fqtest +++ b/pkg/interp/testdata/value_array.fqtest @@ -6,12 +6,6 @@ mp3> .headers | ., tovalue, toactual, tosym, type, length? * |until 0x2c.7 (45) | | [ { - "flags": { - "experimental_indicator": false, - "extended_header": false, - "unsynchronisation": false, - "unused": 0 - }, "frames": [ { "flags": { @@ -33,11 +27,19 @@ mp3> .headers | ., tovalue, toactual, tosym, type, length? "text_encoding": "utf8" } ], - "magic": "ID3", - "padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", - "revision": 0, - "size": 35, - "version": 4 + "header": { + "flags": { + "experimental_indicator": false, + "extended_header": false, + "unsynchronisation": false, + "unused": 0 + }, + "magic": "ID3", + "revision": 0, + "size": 35, + "version": 4 + }, + "padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" } ] null @@ -46,17 +48,13 @@ null 1 mp3> .headers[0] | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0]{}: header (id3v2) -0x00|49 44 33 |ID3 | magic: "ID3" (valid) -0x00| 04 | . | version: 4 -0x00| 00 | . | revision: 0 -0x00| 00 | . | flags{}: -0x00| 00 00 00 23 | ...# | size: 35 +0x00|49 44 33 04 00 00 00 00 00 23 |ID3......# | header{}: 0x00| 54 53 53 45 00 00| TSSE..| frames[0:1]: 0x10|00 0f 00 00 03 4c 61 76 66 35 38 2e 34 35 2e 31|.....Lavf58.45.1| 0x20|30 30 00 |00. | 0x20| 00 00 00 00 00 00 00 00 00 00 | .......... | padding: raw bits (all zero) "object" -7 +3 mp3> .headers[-1000] | ., type, length? null "null" @@ -76,12 +74,6 @@ mp3> .headers[0:-1] | ., type, length? mp3> .headers[-1000:2000] | ., type, length? [ { - "flags": { - "experimental_indicator": false, - "extended_header": false, - "unsynchronisation": false, - "unused": 0 - }, "frames": [ { "flags": { @@ -103,11 +95,19 @@ mp3> .headers[-1000:2000] | ., type, length? "text_encoding": "utf8" } ], - "magic": "ID3", - "padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", - "revision": 0, - "size": 35, - "version": 4 + "header": { + "flags": { + "experimental_indicator": false, + "extended_header": false, + "unsynchronisation": false, + "unused": 0 + }, + "magic": "ID3", + "revision": 0, + "size": 35, + "version": 4 + }, + "padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" } ] "array" @@ -130,11 +130,11 @@ mp3> .headers | type mp3> .headers | tonumber error: tonumber cannot be applied to: array mp3> .headers | tostring -"[{\"flags\":{\"experimental_indicator\":false,\"extended_header\":false,\"unsynchronisation\":false,\"unused\":0},\"frames\":[{\"flags\":{\"compression\":false,\"data_length_indicator\":false,\"encryption\":false,\"file_alter_preservation\":false,\"grouping_identity\":false,\"read_only\":false,\"tag_alter_preservation\":false,\"unsync\":false,\"unused0\":0,\"unused1\":0,\"unused2\":0},\"id\":\"TSSE\",\"size\":15,\"text\":\"Lavf58.45.100\",\"text_encoding\":\"utf8\"}],\"magic\":\"ID3\",\"padding\":\"\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\",\"revision\":0,\"size\":35,\"version\":4}]" +"[{\"frames\":[{\"flags\":{\"compression\":false,\"data_length_indicator\":false,\"encryption\":false,\"file_alter_preservation\":false,\"grouping_identity\":false,\"read_only\":false,\"tag_alter_preservation\":false,\"unsync\":false,\"unused0\":0,\"unused1\":0,\"unused2\":0},\"id\":\"TSSE\",\"size\":15,\"text\":\"Lavf58.45.100\",\"text_encoding\":\"utf8\"}],\"header\":{\"flags\":{\"experimental_indicator\":false,\"extended_header\":false,\"unsynchronisation\":false,\"unused\":0},\"magic\":\"ID3\",\"revision\":0,\"size\":35,\"version\":4},\"padding\":\"\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\"}]" mp3> .headers + "" -error: cannot add: array ([{"flags":{"experimental_ ...]) and string ("") +error: cannot add: array ([{"frames":[{"flags":{"co ...]) and string ("") mp3> .headers + 1 -error: cannot add: array ([{"flags":{"experimental_ ...]) and number (1) +error: cannot add: array ([{"frames":[{"flags":{"co ...]) and number (1) mp3> .headers._start | ., type, length? 0 "number" @@ -189,7 +189,7 @@ mp3> .headers._gap | ., type, length? false "boolean" mp3> .headers.a = 1 -error: expected an object but got: array ([{"flags":{"experimental_ ...]) +error: expected an object but got: array ([{"frames":[{"flags":{"co ...]) mp3> .headers[0] = 1 { "footers": [], @@ -853,13 +853,13 @@ mp3> .headers[0] |= empty "headers": [] } mp3> .headers | setpath(["a"]; 1) -error: expected an object but got: array ([{"flags":{"experimental_ ...]) +error: expected an object but got: array ([{"frames":[{"flags":{"co ...]) mp3> .headers | setpath([0]; 1) [ 1 ] mp3> .headers | delpaths([["a"]]) -error: expected an object but got: array ([{"flags":{"experimental_ ...]) +error: expected an object but got: array ([{"frames":[{"flags":{"co ...]) mp3> .headers | delpaths([[0]]) [] mp3> ^D diff --git a/pkg/interp/testdata/value_boolean.fqtest b/pkg/interp/testdata/value_boolean.fqtest index 23edd7ac..2b212e85 100644 --- a/pkg/interp/testdata/value_boolean.fqtest +++ b/pkg/interp/testdata/value_boolean.fqtest @@ -1,112 +1,113 @@ $ fq -i -d mp3 . test.mp3 -mp3> .headers[0].flags.unsynchronisation | ., tovalue, toactual, tosym, type, length? +mp3> .headers[0].header.flags.unsynchronisation | ., tovalue, toactual, tosym, type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0| 00 | . |.headers[0].flags.unsynchronisation: false +0x0| 00 | . |.headers[0].header.flags.unsynchronisation: false false false null "boolean" -mp3> .headers[0].flags.unsynchronisation[0] | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation[0] | ., type, length? error: expected an array but got: boolean -mp3> .headers[0].flags.unsynchronisation[-1000] | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation[-1000] | ., type, length? error: expected an array but got: boolean -mp3> .headers[0].flags.unsynchronisation[1000] | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation[1000] | ., type, length? error: expected an array but got: boolean -mp3> .headers[0].flags.unsynchronisation[1:3] | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation[1:3] | ., type, length? error: expected an array but got: boolean -mp3> .headers[0].flags.unsynchronisation[0:-1] | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation[0:-1] | ., type, length? error: expected an array but got: boolean -mp3> .headers[0].flags.unsynchronisation[-1000:2000] | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation[-1000:2000] | ., type, length? error: expected an array but got: boolean -mp3> .headers[0].flags.unsynchronisation["test"] | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation["test"] | ., type, length? error: expected an object but got: boolean -mp3> [.headers[0].flags.unsynchronisation[]] | type, length? +mp3> [.headers[0].header.flags.unsynchronisation[]] | type, length? error: cannot iterate over: boolean -mp3> .headers[0].flags.unsynchronisation | keys +mp3> .headers[0].header.flags.unsynchronisation | keys error: keys cannot be applied to: boolean -mp3> .headers[0].flags.unsynchronisation | has("a") +mp3> .headers[0].header.flags.unsynchronisation | has("a") error: has cannot be applied to: boolean -mp3> .headers[0].flags.unsynchronisation | has(0) +mp3> .headers[0].header.flags.unsynchronisation | has(0) error: has cannot be applied to: boolean -mp3> .headers[0].flags.unsynchronisation | type +mp3> .headers[0].header.flags.unsynchronisation | type "boolean" -mp3> .headers[0].flags.unsynchronisation | tonumber +mp3> .headers[0].header.flags.unsynchronisation | tonumber error: tonumber cannot be applied to: boolean -mp3> .headers[0].flags.unsynchronisation | tostring +mp3> .headers[0].header.flags.unsynchronisation | tostring "false" -mp3> .headers[0].flags.unsynchronisation + "" +mp3> .headers[0].header.flags.unsynchronisation + "" error: cannot add: boolean (false) and string ("") -mp3> .headers[0].flags.unsynchronisation + 1 +mp3> .headers[0].header.flags.unsynchronisation + 1 error: cannot add: boolean (false) and number (1) -mp3> .headers[0].flags.unsynchronisation._start | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation._start | ., type, length? 40 "number" 40 -mp3> .headers[0].flags.unsynchronisation._stop | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation._stop | ., type, length? 41 "number" 41 -mp3> .headers[0].flags.unsynchronisation._len | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation._len | ., type, length? 1 "number" 1 -mp3> .headers[0].flags.unsynchronisation._name | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation._name | ., type, length? "unsynchronisation" "string" 17 -mp3> .headers[0].flags.unsynchronisation._actual | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation._actual | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0| 00 | . |.headers[0].flags.unsynchronisation: false +0x0| 00 | . |.headers[0].header.flags.unsynchronisation: false "boolean" -mp3> .headers[0].flags.unsynchronisation._sym | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation._sym | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0| 00 | . |.headers[0].flags.unsynchronisation: false +0x0| 00 | . |.headers[0].header.flags.unsynchronisation: false "null" 0 -mp3> .headers[0].flags.unsynchronisation._description | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation._description | ., type, length? null "null" 0 -mp3> .headers[0].flags.unsynchronisation._path | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation._path | ., type, length? [ "headers", 0, + "header", "flags", "unsynchronisation" ] "array" -4 -mp3> .headers[0].flags.unsynchronisation._bits | ., type, length? +5 +mp3> .headers[0].header.flags.unsynchronisation._bits | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0| 00 | . |.: raw bits 0x5-0x5 (0.1) "string" 1 -mp3> .headers[0].flags.unsynchronisation._bytes | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation._bytes | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0| 00 | . |.: raw bits 0x5-0x5 (0.1) "string" 0 -mp3> .headers[0].flags.unsynchronisation._error | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation._error | ., type, length? null "null" 0 -mp3> .headers[0].flags.unsynchronisation._gap | ., type, length? +mp3> .headers[0].header.flags.unsynchronisation._gap | ., type, length? false "boolean" -mp3> .headers[0].flags.unsynchronisation.a = 1 +mp3> .headers[0].header.flags.unsynchronisation.a = 1 error: expected an object but got: boolean (false) -mp3> .headers[0].flags.unsynchronisation[0] = 1 +mp3> .headers[0].header.flags.unsynchronisation[0] = 1 error: expected an array but got: boolean (false) -mp3> .headers[0].flags.unsynchronisation.a |= empty +mp3> .headers[0].header.flags.unsynchronisation.a |= empty error: expected an object but got: boolean -mp3> .headers[0].flags.unsynchronisation[0] |= empty +mp3> .headers[0].header.flags.unsynchronisation[0] |= empty error: expected an array but got: boolean -mp3> .headers[0].flags.unsynchronisation | setpath(["a"]; 1) +mp3> .headers[0].header.flags.unsynchronisation | setpath(["a"]; 1) error: expected an object but got: boolean (false) -mp3> .headers[0].flags.unsynchronisation | setpath([0]; 1) +mp3> .headers[0].header.flags.unsynchronisation | setpath([0]; 1) error: expected an array but got: boolean (false) -mp3> .headers[0].flags.unsynchronisation | delpaths([["a"]]) +mp3> .headers[0].header.flags.unsynchronisation | delpaths([["a"]]) error: expected an object but got: boolean (false) -mp3> .headers[0].flags.unsynchronisation | delpaths([[0]]) +mp3> .headers[0].header.flags.unsynchronisation | delpaths([[0]]) error: expected an array but got: boolean (false) mp3> ^D diff --git a/pkg/interp/testdata/value_number.fqtest b/pkg/interp/testdata/value_number.fqtest index 2d95c095..dd2f99df 100644 --- a/pkg/interp/testdata/value_number.fqtest +++ b/pkg/interp/testdata/value_number.fqtest @@ -1,113 +1,114 @@ $ fq -i -d mp3 . test.mp3 -mp3> .headers[0].version | ., tovalue, toactual, tosym, type, length? +mp3> .headers[0].header.version | ., tovalue, toactual, tosym, type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0| 04 | . |.headers[0].version: 4 +0x0| 04 | . |.headers[0].header.version: 4 (valid) 4 4 null "number" 4 -mp3> .headers[0].version[0] | ., type, length? +mp3> .headers[0].header.version[0] | ., type, length? error: expected an array but got: number -mp3> .headers[0].version[-1000] | ., type, length? +mp3> .headers[0].header.version[-1000] | ., type, length? error: expected an array but got: number -mp3> .headers[0].version[1000] | ., type, length? +mp3> .headers[0].header.version[1000] | ., type, length? error: expected an array but got: number -mp3> .headers[0].version[1:3] | ., type, length? +mp3> .headers[0].header.version[1:3] | ., type, length? error: expected an array but got: number -mp3> .headers[0].version[0:-1] | ., type, length? +mp3> .headers[0].header.version[0:-1] | ., type, length? error: expected an array but got: number -mp3> .headers[0].version[-1000:2000] | ., type, length? +mp3> .headers[0].header.version[-1000:2000] | ., type, length? error: expected an array but got: number -mp3> .headers[0].version["test"] | ., type, length? +mp3> .headers[0].header.version["test"] | ., type, length? error: expected an object but got: number -mp3> [.headers[0].version[]] | type, length? +mp3> [.headers[0].header.version[]] | type, length? error: cannot iterate over: number -mp3> .headers[0].version | keys +mp3> .headers[0].header.version | keys error: keys cannot be applied to: number -mp3> .headers[0].version | has("a") +mp3> .headers[0].header.version | has("a") error: has cannot be applied to: number -mp3> .headers[0].version | has(0) +mp3> .headers[0].header.version | has(0) error: has cannot be applied to: number -mp3> .headers[0].version | type +mp3> .headers[0].header.version | type "number" -mp3> .headers[0].version | tonumber +mp3> .headers[0].header.version | tonumber 4 -mp3> .headers[0].version | tostring +mp3> .headers[0].header.version | tostring "4" -mp3> .headers[0].version + "" +mp3> .headers[0].header.version + "" error: cannot add: number (4) and string ("") -mp3> .headers[0].version + 1 +mp3> .headers[0].header.version + 1 5 -mp3> .headers[0].version._start | ., type, length? +mp3> .headers[0].header.version._start | ., type, length? 24 "number" 24 -mp3> .headers[0].version._stop | ., type, length? +mp3> .headers[0].header.version._stop | ., type, length? 32 "number" 32 -mp3> .headers[0].version._len | ., type, length? +mp3> .headers[0].header.version._len | ., type, length? 8 "number" 8 -mp3> .headers[0].version._name | ., type, length? +mp3> .headers[0].header.version._name | ., type, length? "version" "string" 7 -mp3> .headers[0].version._actual | ., type, length? +mp3> .headers[0].header.version._actual | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0| 04 | . |.headers[0].version: 4 +0x0| 04 | . |.headers[0].header.version: 4 (valid) "number" 4 -mp3> .headers[0].version._sym | ., type, length? +mp3> .headers[0].header.version._sym | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0| 04 | . |.headers[0].version: 4 +0x0| 04 | . |.headers[0].header.version: 4 (valid) "null" 0 -mp3> .headers[0].version._description | ., type, length? -null -"null" -0 -mp3> .headers[0].version._path | ., type, length? +mp3> .headers[0].header.version._description | ., type, length? +"valid" +"string" +5 +mp3> .headers[0].header.version._path | ., type, length? [ "headers", 0, + "header", "version" ] "array" -3 -mp3> .headers[0].version._bits | ., type, length? +4 +mp3> .headers[0].header.version._bits | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0| 04 | . |.: raw bits 0x3-0x3.7 (1) "string" 8 -mp3> .headers[0].version._bytes | ., type, length? +mp3> .headers[0].header.version._bytes | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0| 04 | . |.: raw bits 0x3-0x3.7 (1) "string" 1 -mp3> .headers[0].version._error | ., type, length? +mp3> .headers[0].header.version._error | ., type, length? null "null" 0 -mp3> .headers[0].version._gap | ., type, length? +mp3> .headers[0].header.version._gap | ., type, length? false "boolean" -mp3> .headers[0].version.a = 1 +mp3> .headers[0].header.version.a = 1 error: expected an object but got: number (4) -mp3> .headers[0].version[0] = 1 +mp3> .headers[0].header.version[0] = 1 error: expected an array but got: number (4) -mp3> .headers[0].version.a |= empty +mp3> .headers[0].header.version.a |= empty error: expected an object but got: number -mp3> .headers[0].version[0] |= empty +mp3> .headers[0].header.version[0] |= empty error: expected an array but got: number -mp3> .headers[0].version | setpath(["a"]; 1) +mp3> .headers[0].header.version | setpath(["a"]; 1) error: expected an object but got: number (4) -mp3> .headers[0].version | setpath([0]; 1) +mp3> .headers[0].header.version | setpath([0]; 1) error: expected an array but got: number (4) -mp3> .headers[0].version | delpaths([["a"]]) +mp3> .headers[0].header.version | delpaths([["a"]]) error: expected an object but got: number (4) -mp3> .headers[0].version | delpaths([[0]]) +mp3> .headers[0].header.version | delpaths([[0]]) error: expected an array but got: number (4) mp3> ^D diff --git a/pkg/interp/testdata/value_object.fqtest b/pkg/interp/testdata/value_object.fqtest index 4531b367..6cc0271c 100644 --- a/pkg/interp/testdata/value_object.fqtest +++ b/pkg/interp/testdata/value_object.fqtest @@ -1,6 +1,6 @@ $ fq -i -d mp3 . test.mp3 -mp3> .headers[0].flags | ., tovalue, toactual, tosym, type, length? - |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0].flags{}: +mp3> .headers[0].header.flags | ., tovalue, toactual, tosym, type, length? + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0].header.flags{}: 0x0| 00 | . | unsynchronisation: false 0x0| 00 | . | extended_header: false 0x0| 00 | . | experimental_indicator: false @@ -15,100 +15,101 @@ null null "object" 4 -mp3> .headers[0].flags[0] | ., type, length? +mp3> .headers[0].header.flags[0] | ., type, length? error: expected an array with index 0 but got: object -mp3> .headers[0].flags[-1000] | ., type, length? +mp3> .headers[0].header.flags[-1000] | ., type, length? error: expected an array with index -2 but got: object -mp3> .headers[0].flags[1000] | ., type, length? +mp3> .headers[0].header.flags[1000] | ., type, length? error: expected an array with index -1 but got: object -mp3> .headers[0].flags[1:3] | ., type, length? +mp3> .headers[0].header.flags[1:3] | ., type, length? error: expected an array but got: object -mp3> .headers[0].flags[0:-1] | ., type, length? +mp3> .headers[0].header.flags[0:-1] | ., type, length? error: expected an array but got: object -mp3> .headers[0].flags[-1000:2000] | ., type, length? +mp3> .headers[0].header.flags[-1000:2000] | ., type, length? error: expected an array but got: object -mp3> .headers[0].flags["test"] | ., type, length? +mp3> .headers[0].header.flags["test"] | ., type, length? null "null" 0 -mp3> [.headers[0].flags[]] | type, length? +mp3> [.headers[0].header.flags[]] | type, length? "array" 4 -mp3> .headers[0].flags | keys +mp3> .headers[0].header.flags | keys [ "unsynchronisation", "extended_header", "experimental_indicator", "unused" ] -mp3> .headers[0].flags | has("a") +mp3> .headers[0].header.flags | has("a") false -mp3> .headers[0].flags | has(0) +mp3> .headers[0].header.flags | has(0) error: cannot check whether object has a key: 0 -mp3> .headers[0].flags | type +mp3> .headers[0].header.flags | type "object" -mp3> .headers[0].flags | tonumber +mp3> .headers[0].header.flags | tonumber error: tonumber cannot be applied to: object -mp3> .headers[0].flags | tostring +mp3> .headers[0].header.flags | tostring "{\"experimental_indicator\":false,\"extended_header\":false,\"unsynchronisation\":false,\"unused\":0}" -mp3> .headers[0].flags + "" +mp3> .headers[0].header.flags + "" error: cannot add: object ({"experimental_indicator" ...}) and string ("") -mp3> .headers[0].flags + 1 +mp3> .headers[0].header.flags + 1 error: cannot add: object ({"experimental_indicator" ...}) and number (1) -mp3> .headers[0].flags._start | ., type, length? +mp3> .headers[0].header.flags._start | ., type, length? 40 "number" 40 -mp3> .headers[0].flags._stop | ., type, length? +mp3> .headers[0].header.flags._stop | ., type, length? 48 "number" 48 -mp3> .headers[0].flags._len | ., type, length? +mp3> .headers[0].header.flags._len | ., type, length? 8 "number" 8 -mp3> .headers[0].flags._name | ., type, length? +mp3> .headers[0].header.flags._name | ., type, length? "flags" "string" 5 -mp3> .headers[0].flags._actual | ., type, length? +mp3> .headers[0].header.flags._actual | ., type, length? null "null" 0 -mp3> .headers[0].flags._sym | ., type, length? +mp3> .headers[0].header.flags._sym | ., type, length? null "null" 0 -mp3> .headers[0].flags._description | ., type, length? +mp3> .headers[0].header.flags._description | ., type, length? null "null" 0 -mp3> .headers[0].flags._path | ., type, length? +mp3> .headers[0].header.flags._path | ., type, length? [ "headers", 0, + "header", "flags" ] "array" -3 -mp3> .headers[0].flags._bits | ., type, length? +4 +mp3> .headers[0].header.flags._bits | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0| 00 | . |.: raw bits 0x5-0x5.7 (1) "string" 8 -mp3> .headers[0].flags._bytes | ., type, length? +mp3> .headers[0].header.flags._bytes | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0| 00 | . |.: raw bits 0x5-0x5.7 (1) "string" 1 -mp3> .headers[0].flags._error | ., type, length? +mp3> .headers[0].header.flags._error | ., type, length? null "null" 0 -mp3> .headers[0].flags._gap | ., type, length? +mp3> .headers[0].header.flags._gap | ., type, length? false "boolean" -mp3> .headers[0].flags.a = 1 +mp3> .headers[0].header.flags.a = 1 { "footers": [], "frames": [ @@ -437,13 +438,6 @@ mp3> .headers[0].flags.a = 1 ], "headers": [ { - "flags": { - "a": 1, - "experimental_indicator": false, - "extended_header": false, - "unsynchronisation": false, - "unused": 0 - }, "frames": [ { "flags": { @@ -465,17 +459,26 @@ mp3> .headers[0].flags.a = 1 "text_encoding": "utf8" } ], - "magic": "ID3", - "padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", - "revision": 0, - "size": 35, - "version": 4 + "header": { + "flags": { + "a": 1, + "experimental_indicator": false, + "extended_header": false, + "unsynchronisation": false, + "unused": 0 + }, + "magic": "ID3", + "revision": 0, + "size": 35, + "version": 4 + }, + "padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" } ] } -mp3> .headers[0].flags[0] = 1 +mp3> .headers[0].header.flags[0] = 1 error: expected an array but got: object ({"experimental_indicator" ...}) -mp3> .headers[0].flags.a |= empty +mp3> .headers[0].header.flags.a |= empty { "footers": [], "frames": [ @@ -804,12 +807,6 @@ mp3> .headers[0].flags.a |= empty ], "headers": [ { - "flags": { - "experimental_indicator": false, - "extended_header": false, - "unsynchronisation": false, - "unused": 0 - }, "frames": [ { "flags": { @@ -831,17 +828,25 @@ mp3> .headers[0].flags.a |= empty "text_encoding": "utf8" } ], - "magic": "ID3", - "padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", - "revision": 0, - "size": 35, - "version": 4 + "header": { + "flags": { + "experimental_indicator": false, + "extended_header": false, + "unsynchronisation": false, + "unused": 0 + }, + "magic": "ID3", + "revision": 0, + "size": 35, + "version": 4 + }, + "padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" } ] } -mp3> .headers[0].flags[0] |= empty +mp3> .headers[0].header.flags[0] |= empty error: expected an array with index 0 but got: object -mp3> .headers[0].flags | setpath(["a"]; 1) +mp3> .headers[0].header.flags | setpath(["a"]; 1) { "a": 1, "experimental_indicator": false, @@ -849,15 +854,15 @@ mp3> .headers[0].flags | setpath(["a"]; 1) "unsynchronisation": false, "unused": 0 } -mp3> .headers[0].flags | setpath([0]; 1) +mp3> .headers[0].header.flags | setpath([0]; 1) error: expected an array but got: object ({"experimental_indicator" ...}) -mp3> .headers[0].flags | delpaths([["a"]]) +mp3> .headers[0].header.flags | delpaths([["a"]]) { "experimental_indicator": false, "extended_header": false, "unsynchronisation": false, "unused": 0 } -mp3> .headers[0].flags | delpaths([[0]]) +mp3> .headers[0].header.flags | delpaths([[0]]) error: expected an array but got: object ({"experimental_indicator" ...}) mp3> ^D diff --git a/pkg/interp/testdata/value_string.fqtest b/pkg/interp/testdata/value_string.fqtest index 13f42ab1..913e83e7 100644 --- a/pkg/interp/testdata/value_string.fqtest +++ b/pkg/interp/testdata/value_string.fqtest @@ -1,125 +1,126 @@ $ fq -i -d mp3 . test.mp3 -mp3> .headers[0].magic | ., tovalue, toactual, tosym, type, length? +mp3> .headers[0].header.magic | ., tovalue, toactual, tosym, type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) "ID3" "ID3" null "string" 3 -mp3> .headers[0].magic[0] | ., type, length? +mp3> .headers[0].header.magic[0] | ., type, length? "I" "string" 1 -mp3> .headers[0].magic[-1000] | ., type, length? +mp3> .headers[0].header.magic[-1000] | ., type, length? "" "string" 0 -mp3> .headers[0].magic[1000] | ., type, length? +mp3> .headers[0].header.magic[1000] | ., type, length? "" "string" 0 -mp3> .headers[0].magic[1:3] | ., type, length? +mp3> .headers[0].header.magic[1:3] | ., type, length? "D3" "string" 2 -mp3> .headers[0].magic[0:-1] | ., type, length? +mp3> .headers[0].header.magic[0:-1] | ., type, length? "ID" "string" 2 -mp3> .headers[0].magic[-1000:2000] | ., type, length? +mp3> .headers[0].header.magic[-1000:2000] | ., type, length? "ID3" "string" 3 -mp3> .headers[0].magic["test"] | ., type, length? +mp3> .headers[0].header.magic["test"] | ., type, length? error: expected an object but got: string -mp3> [.headers[0].magic[]] | type, length? +mp3> [.headers[0].header.magic[]] | type, length? error: cannot iterate over: string -mp3> .headers[0].magic | keys +mp3> .headers[0].header.magic | keys error: keys cannot be applied to: string -mp3> .headers[0].magic | has("a") +mp3> .headers[0].header.magic | has("a") error: has cannot be applied to: string -mp3> .headers[0].magic | has(0) +mp3> .headers[0].header.magic | has(0) error: has cannot be applied to: string -mp3> .headers[0].magic | type +mp3> .headers[0].header.magic | type "string" -mp3> .headers[0].magic | tonumber +mp3> .headers[0].header.magic | tonumber error: invalid number: "ID3" -mp3> .headers[0].magic | tostring +mp3> .headers[0].header.magic | tostring "ID3" -mp3> .headers[0].magic + "" +mp3> .headers[0].header.magic + "" "ID3" -mp3> .headers[0].magic + 1 +mp3> .headers[0].header.magic + 1 error: cannot add: string ("ID3") and number (1) -mp3> .headers[0].magic._start | ., type, length? +mp3> .headers[0].header.magic._start | ., type, length? 0 "number" 0 -mp3> .headers[0].magic._stop | ., type, length? +mp3> .headers[0].header.magic._stop | ., type, length? 24 "number" 24 -mp3> .headers[0].magic._len | ., type, length? +mp3> .headers[0].header.magic._len | ., type, length? 24 "number" 24 -mp3> .headers[0].magic._name | ., type, length? +mp3> .headers[0].header.magic._name | ., type, length? "magic" "string" 5 -mp3> .headers[0].magic._actual | ., type, length? +mp3> .headers[0].header.magic._actual | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) "string" 3 -mp3> .headers[0].magic._sym | ., type, length? +mp3> .headers[0].header.magic._sym | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| -0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid) +0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid) "null" 0 -mp3> .headers[0].magic._description | ., type, length? +mp3> .headers[0].header.magic._description | ., type, length? "valid" "string" 5 -mp3> .headers[0].magic._path | ., type, length? +mp3> .headers[0].header.magic._path | ., type, length? [ "headers", 0, + "header", "magic" ] "array" -3 -mp3> .headers[0].magic._bits | ., type, length? +4 +mp3> .headers[0].header.magic._bits | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0|49 44 33 |ID3 |.: raw bits 0x0-0x2.7 (3) "string" 24 -mp3> .headers[0].magic._bytes | ., type, length? +mp3> .headers[0].header.magic._bytes | ., type, length? |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0|49 44 33 |ID3 |.: raw bits 0x0-0x2.7 (3) "string" 3 -mp3> .headers[0].magic._error | ., type, length? +mp3> .headers[0].header.magic._error | ., type, length? null "null" 0 -mp3> .headers[0].magic._gap | ., type, length? +mp3> .headers[0].header.magic._gap | ., type, length? false "boolean" -mp3> .headers[0].magic.a = 1 +mp3> .headers[0].header.magic.a = 1 error: expected an object but got: string ("ID3") -mp3> .headers[0].magic[0] = 1 +mp3> .headers[0].header.magic[0] = 1 error: expected an array but got: string ("ID3") -mp3> .headers[0].magic.a |= empty +mp3> .headers[0].header.magic.a |= empty error: expected an object but got: string -mp3> .headers[0].magic[0] |= empty +mp3> .headers[0].header.magic[0] |= empty error: expected an array but got: string ("ID3") -mp3> .headers[0].magic | setpath(["a"]; 1) +mp3> .headers[0].header.magic | setpath(["a"]; 1) error: expected an object but got: string ("ID3") -mp3> .headers[0].magic | setpath([0]; 1) +mp3> .headers[0].header.magic | setpath([0]; 1) error: expected an array but got: string ("ID3") -mp3> .headers[0].magic | delpaths([["a"]]) +mp3> .headers[0].header.magic | delpaths([["a"]]) error: expected an object but got: string ("ID3") -mp3> .headers[0].magic | delpaths([[0]]) +mp3> .headers[0].header.magic | delpaths([[0]]) error: expected an array but got: string ("ID3") mp3> ^D diff --git a/pkg/interp/testdata/value_t.fqtest.tmpl.sh b/pkg/interp/testdata/value_t.fqtest.tmpl.sh index 22503aae..f726b312 100644 --- a/pkg/interp/testdata/value_t.fqtest.tmpl.sh +++ b/pkg/interp/testdata/value_t.fqtest.tmpl.sh @@ -1,10 +1,10 @@ #!/bin/sh sed 's/CMD/fq -i -d mp3 . test.mp3/g' value_array.fqtest -sed 's/CMD/fq -i -d mp3 . test.mp3/g' value_boolean.fqtest +sed 's/CMD/fq -i -d mp3 . test.mp3/g' value_boolean.fqtest sed 's/CMD/fq -i -d mp3 . test.mp3/g' value_null.fqtest -sed 's/CMD/fq -i -d mp3 . test.mp3/g' value_number.fqtest -sed 's/CMD/fq -i -d mp3 . test.mp3/g' value_object.fqtest -sed 's/CMD/fq -i -d mp3 . test.mp3/g' value_string.fqtest +sed 's/CMD/fq -i -d mp3 . test.mp3/g' value_number.fqtest +sed 's/CMD/fq -i -d mp3 . test.mp3/g' value_object.fqtest +sed 's/CMD/fq -i -d mp3 . test.mp3/g' value_string.fqtest sed "s/CMD/fq -i -n '\"[]\" | json'/g" value_json_array.fqtest sed "s/CMD/fq -i -n '\"{}\" | json'/g" value_json_object.fqtest