diff --git a/.golangci.yml b/.golangci.yml index 2d69a91370..e00d3670be 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -23,6 +23,11 @@ linters: - predeclared - tagliatelle +run: + skip-dirs: + - dev + - doc + linters-settings: misspell: ignore-words: @@ -37,9 +42,3 @@ linters-settings: # allow md5 - G401 - G501 -issues: - exclude-rules: - - path: dev/.*\.go - linters: - # ignore main re-declared errors - - typecheck diff --git a/README.md b/README.md index 568f8b4d7b..b2d2659213 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,11 @@ Basic usage is `fq . file`. For details see [usage.md](doc/usage.md) +## Presentations + +- "fq - jq for binary formats" at [Binary Tools Summit 2022](https://binary-tools.net/summit.html) - (recording soon) - [slides](doc/presentations/bts2022/fq-bts2022-v1.pdf) + + ## Install Use one of the methods listed below or download [release](https://github.com/wader/fq/releases) for your platform. Unarchive it and move the executable to `PATH` etc. diff --git a/doc/presentations/bts2022/README.md b/doc/presentations/bts2022/README.md new file mode 100644 index 0000000000..e65c8defc0 --- /dev/null +++ b/doc/presentations/bts2022/README.md @@ -0,0 +1,21 @@ +fq presentation from Binary Tools Summit 2022 https://binary-tools.net/ + +[fq-bts2022-v1.pdf](fq-bts2022-v1.pdf) + +Will update with link to recording when availabe. + +Was done at the time of ~fq 0.0.5, things might have changed since. + +How to build: + +``` +go install golang.org/x/tools/cmd/present +present -notes -content doc/presentations/bts2022 -base ~/go/pkg/mod/golang.org/x/tools@v0.1.9/cmd/present +``` + +``` +./usage.sh | ansisvg > usage.svg +``` + +Export to PDF via browser. + diff --git a/doc/presentations/bts2022/abstract.txt b/doc/presentations/bts2022/abstract.txt new file mode 100644 index 0000000000..521a308b4f --- /dev/null +++ b/doc/presentations/bts2022/abstract.txt @@ -0,0 +1,15 @@ +fq is inspired by the well known jq tool and language and allows you +to work with binary formats the same way you would using jq. In +addition it can also present data similar to a hex viewer, transform, +slice and concatenate binary data, supports nested formats and has an +interactive REPL with auto-completion. + +It was originally designed to query, inspect and debug codecs and +metadata in media files and containers like mp4, flac, mp3, jpeg. But +has since been extended to support a variety of formats like +executables, packet captures including TCP reassembly and +serialization formats like ASN1 BER, Avro, CBOR, protobuf and a lot +more. + +In summary it aims to be something like jq, hexdump, dd and gdb +combined into one. diff --git a/doc/presentations/bts2022/avc_sps_hdr_params.go b/doc/presentations/bts2022/avc_sps_hdr_params.go new file mode 100644 index 0000000000..0ab6de62e6 --- /dev/null +++ b/doc/presentations/bts2022/avc_sps_hdr_params.go @@ -0,0 +1,18 @@ +func avcHdrParameters(d *decode.D) { + cpbCnt := d.FieldUFn("cpb_cnt", uEV, scalar.UAdd(1)) + d.FieldU4("bit_rate_scale") + d.FieldU4("cpb_size_scale") + d.FieldArray("sched_sels", func(d *decode.D) { + for i := uint64(0); i < cpbCnt; i++ { + d.FieldStruct("sched_sel", func(d *decode.D) { + d.FieldUFn("bit_rate_value", uEV, scalar.UAdd(1)) + d.FieldUFn("cpb_size_value", uEV, scalar.UAdd(1)) + d.FieldBool("cbr_flag") + }) + } + }) + d.FieldU5("initial_cpb_removal_delay_length", scalar.UAdd(1)) + d.FieldU5("cpb_removal_delay_length", scalar.UAdd(1)) + d.FieldU5("dpb_output_delay_length", scalar.UAdd(1)) + d.FieldU5("time_offset_length") +} \ No newline at end of file diff --git a/doc/presentations/bts2022/avc_sps_hdr_params.png b/doc/presentations/bts2022/avc_sps_hdr_params.png new file mode 100644 index 0000000000..431e9bbd86 Binary files /dev/null and b/doc/presentations/bts2022/avc_sps_hdr_params.png differ diff --git a/doc/presentations/bts2022/file.mp3 b/doc/presentations/bts2022/file.mp3 new file mode 100644 index 0000000000..b325d0e3e6 Binary files /dev/null and b/doc/presentations/bts2022/file.mp3 differ diff --git a/doc/presentations/bts2022/file.png b/doc/presentations/bts2022/file.png new file mode 100644 index 0000000000..a6ecff21a4 Binary files /dev/null and b/doc/presentations/bts2022/file.png differ diff --git a/doc/presentations/bts2022/formats.svg b/doc/presentations/bts2022/formats.svg new file mode 100644 index 0000000000..dd809a8907 --- /dev/null +++ b/doc/presentations/bts2022/formats.svg @@ -0,0 +1,1621 @@ + + + + + + +formats + + + +adts + +adts + +adts_frame + + + +adts_frame + +adts_frame + +aac_frame + + + +adts:e->adts_frame:n + + + + + +aac_frame + +aac_frame + + + +adts_frame:e->aac_frame:n + + + + + +apev2 + +apev2 + +image + + + +image + +image + + + +apev2:e->image:n + + + + + +jpeg + +jpeg + +exif + +icc_profile + + + +image->jpeg:n + + + + + +mp4 + +mp4 + +aac_frame + +av1_ccr + +av1_frame + +flac_frame + +flac_metadatablocks + +id3v2 + +image + +jpeg + +mp3_frame + +avc_au + +avc_dcr + +mpeg_es + +hevc_au + +hevc_dcr + +mpeg_pes_packet + +opus_packet + +protobuf_widevine + +pssh_playready + +vorbis_packet + +vp9_frame + +vpx_ccr + + + +image->mp4:n + + + + + +png + +png + +icc_profile + +exif + + + +image->png:n + + + + + +tiff + +tiff + +icc_profile + + + +image->tiff:n + + + + + +webp + +webp + +vp8_frame + + + +image->webp:n + + + + + +gif + +gif + + + +image->gif:n + + + + + +ar + +ar + +probe + + + +probe + +probe + + + +ar:e->probe:n + + + + + +probe->adts:n + + + + + +probe->ar:n + + + + + +bzip2 + +bzip2 + +probe + + + +probe->bzip2:n + + + + + +flac + +flac + +flac_metadatablocks + +flac_frame + + + +probe->flac:n + + + + + +gzip + +gzip + +probe + + + +probe->gzip:n + + + + + +probe->jpeg:n + + + + + +matroska + +matroska + +aac_frame + +av1_ccr + +av1_frame + +avc_au + +avc_dcr + +flac_frame + +flac_metadatablocks + +hevc_au + +hevc_dcr + +image + +mp3_frame + +mpeg_asc + +mpeg_pes_packet + +mpeg_spu + +opus_packet + +vorbis_packet + +vp8_frame + +vp9_cfm + +vp9_frame + + + +probe->matroska:n + + + + + +mp3 + +mp3 + +id3v2 + +id3v1 + +id3v11 + +apev2 + +mp3_frame + + + +probe->mp3:n + + + + + +probe->mp4:n + + + + + +ogg + +ogg + +ogg_page + +vorbis_packet + +opus_packet + +flac_metadatablock + +flac_frame + + + +probe->ogg:n + + + + + +pcap + +pcap + +link_frame + +tcp_stream + +ipv4_packet + + + +probe->pcap:n + + + + + +pcapng + +pcapng + +link_frame + +tcp_stream + +ipv4_packet + + + +probe->pcapng:n + + + + + +probe->png:n + + + + + +tar + +tar + +probe + + + +probe->tar:n + + + + + +probe->tiff:n + + + + + +wav + +wav + +id3v2 + +id3v1 + +id3v11 + + + +probe->wav:n + + + + + +probe->webp:n + + + + + +zip + +zip + +probe + + + +probe->zip:n + + + + + +avro_ocf + +avro_ocf + + + +probe->avro_ocf:n + + + + + +elf + +elf + + + +probe->elf:n + + + + + +probe->gif:n + + + + + +json + +json + + + +probe->json:n + + + + + +mpeg_ts + +mpeg_ts + + + +probe->mpeg_ts:n + + + + + +av1_frame + +av1_frame + +av1_obu + + + +av1_obu + +av1_obu + + + +av1_frame:e->av1_obu:n + + + + + +avc_annexb + +avc_annexb + +avc_nalu + + + +avc_nalu + +avc_nalu + +avc_sps + +avc_pps + +avc_sei + + + +avc_annexb:e->avc_nalu:n + + + + + +avc_sps + +avc_sps + + + +avc_nalu:e->avc_sps:n + + + + + +avc_pps + +avc_pps + + + +avc_nalu:e->avc_pps:n + + + + + +avc_sei + +avc_sei + + + +avc_nalu:e->avc_sei:n + + + + + +avc_au + +avc_au + +avc_nalu + + + +avc_au:e->avc_nalu:n + + + + + +avc_dcr + +avc_dcr + +avc_nalu + + + +avc_dcr:e->avc_nalu:n + + + + + +bsd_loopback_frame + +bsd_loopback_frame + +ipv4_packet + + + +ipv4_packet + +ipv4_packet + +udp_datagram + +tcp_segment + +icmp + + + +bsd_loopback_frame:e->ipv4_packet:n + + + + + +udp_datagram + +udp_datagram + +udp_payload + + + +ipv4_packet:e->udp_datagram:n + + + + + +tcp_segment + +tcp_segment + + + +ipv4_packet:e->tcp_segment:n + + + + + +icmp + +icmp + + + +ipv4_packet:e->icmp:n + + + + + +bzip2:e->probe:n + + + + + +ether8023_frame + +ether8023_frame + +ipv4_packet + + + +ether8023_frame:e->ipv4_packet:n + + + + + +flac_metadatablocks + +flac_metadatablocks + +flac_metadatablock + + + +flac:e->flac_metadatablocks:n + + + + + +flac_frame + +flac_frame + + + +flac:e->flac_frame:n + + + + + +flac_metadatablock + +flac_metadatablock + +flac_streaminfo + +flac_picture + +vorbis_comment + + + +flac_metadatablocks:e->flac_metadatablock:n + + + + + +flac_streaminfo + +flac_streaminfo + + + +flac_metadatablock:e->flac_streaminfo:n + + + + + +flac_picture + +flac_picture + +image + + + +flac_metadatablock:e->flac_picture:n + + + + + +vorbis_comment + +vorbis_comment + +flac_picture + + + +flac_metadatablock:e->vorbis_comment:n + + + + + +flac_picture:e->image:n + + + + + +vorbis_comment:e->flac_picture:n + + + + + +gzip:e->probe:n + + + + + +hevc_annexb + +hevc_annexb + +hevc_nalu + + + +hevc_nalu + +hevc_nalu + + + +hevc_annexb:e->hevc_nalu:n + + + + + +hevc_au + +hevc_au + +hevc_nalu + + + +hevc_au:e->hevc_nalu:n + + + + + +hevc_dcr + +hevc_dcr + +hevc_nalu + + + +hevc_dcr:e->hevc_nalu:n + + + + + +id3v2 + +id3v2 + +image + + + +id3v2:e->image:n + + + + + +udp_payload + +udp_payload + + + +udp_datagram:e->udp_payload:n + + + + + +exif + +exif + + + +jpeg:e->exif:n + + + + + +icc_profile + +icc_profile + + + +jpeg:e->icc_profile:n + + + + + +matroska:e->aac_frame:n + + + + + +matroska:e->image:n + + + + + +matroska:e->av1_frame:n + + + + + +matroska:e->avc_au:n + + + + + +matroska:e->avc_dcr:n + + + + + +matroska:e->flac_metadatablocks:n + + + + + +matroska:e->flac_frame:n + + + + + +matroska:e->hevc_au:n + + + + + +matroska:e->hevc_dcr:n + + + + + +av1_ccr + +av1_ccr + + + +matroska:e->av1_ccr:n + + + + + +mp3_frame + +mp3_frame + +xing + + + +matroska:e->mp3_frame:n + + + + + +mpeg_asc + +mpeg_asc + + + +matroska:e->mpeg_asc:n + + + + + +mpeg_pes_packet + +mpeg_pes_packet + + + +matroska:e->mpeg_pes_packet:n + + + + + +mpeg_spu + +mpeg_spu + + + +matroska:e->mpeg_spu:n + + + + + +opus_packet + +opus_packet + +vorbis_comment + + + +matroska:e->opus_packet:n + + + + + +vorbis_packet + +vorbis_packet + +vorbis_comment + + + +matroska:e->vorbis_packet:n + + + + + +vp8_frame + +vp8_frame + + + +matroska:e->vp8_frame:n + + + + + +vp9_cfm + +vp9_cfm + + + +matroska:e->vp9_cfm:n + + + + + +vp9_frame + +vp9_frame + + + +matroska:e->vp9_frame:n + + + + + +xing + +xing + + + +mp3_frame:e->xing:n + + + + + +opus_packet:e->vorbis_comment:n + + + + + +vorbis_packet:e->vorbis_comment:n + + + + + +mp3:e->apev2:n + + + + + +mp3:e->id3v2:n + + + + + +mp3:e->mp3_frame:n + + + + + +id3v1 + +id3v1 + + + +mp3:e->id3v1:n + + + + + +id3v11 + +id3v11 + + + +mp3:e->id3v11:n + + + + + +mp4:e->aac_frame:n + + + + + +mp4:e->image:n + + + + + +mp4:e->av1_frame:n + + + + + +mp4:e->avc_au:n + + + + + +mp4:e->avc_dcr:n + + + + + +mp4:e->flac_metadatablocks:n + + + + + +mp4:e->flac_frame:n + + + + + +mp4:e->hevc_au:n + + + + + +mp4:e->hevc_dcr:n + + + + + +mp4:e->id3v2:n + + + + + +mp4:e->jpeg:n + + + + + +mp4:e->av1_ccr:n + + + + + +mp4:e->mp3_frame:n + + + + + +mp4:e->mpeg_pes_packet:n + + + + + +mp4:e->opus_packet:n + + + + + +mp4:e->vorbis_packet:n + + + + + +mp4:e->vp9_frame:n + + + + + +mpeg_es + +mpeg_es + +mpeg_asc + +vorbis_packet + + + +mp4:e->mpeg_es:n + + + + + +protobuf_widevine + +protobuf_widevine + +protobuf + + + +mp4:e->protobuf_widevine:n + + + + + +pssh_playready + +pssh_playready + + + +mp4:e->pssh_playready:n + + + + + +vpx_ccr + +vpx_ccr + + + +mp4:e->vpx_ccr:n + + + + + +mpeg_es:e->mpeg_asc:n + + + + + +mpeg_es:e->vorbis_packet:n + + + + + +protobuf + +protobuf + + + +protobuf_widevine:e->protobuf:n + + + + + +mpeg_pes + +mpeg_pes + +mpeg_pes_packet + +mpeg_spu + + + +mpeg_pes:e->mpeg_pes_packet:n + + + + + +mpeg_pes:e->mpeg_spu:n + + + + + +ogg:e->flac_frame:n + + + + + +ogg:e->flac_metadatablock:n + + + + + +ogg:e->opus_packet:n + + + + + +ogg:e->vorbis_packet:n + + + + + +ogg_page + +ogg_page + + + +ogg:e->ogg_page:n + + + + + +pcap:e->ipv4_packet:n + + + + + +link_frame + +link_frame + + + +pcap:e->link_frame:n + + + + + +tcp_stream + +tcp_stream + + + +pcap:e->tcp_stream:n + + + + + +link_frame->bsd_loopback_frame:n + + + + + +link_frame->ether8023_frame:n + + + + + +sll2_packet + +sll2_packet + +ether8023_frame + + + +link_frame->sll2_packet:n + + + + + +sll_packet + +sll_packet + +ether8023_frame + + + +link_frame->sll_packet:n + + + + + +dns + +dns + + + +tcp_stream->dns:n + + + + + +pcapng:e->ipv4_packet:n + + + + + +pcapng:e->link_frame:n + + + + + +pcapng:e->tcp_stream:n + + + + + +png:e->exif:n + + + + + +png:e->icc_profile:n + + + + + +sll2_packet:e->ether8023_frame:n + + + + + +sll_packet:e->ether8023_frame:n + + + + + +tar:e->probe:n + + + + + +tiff:e->icc_profile:n + + + + + +udp_payload->dns:n + + + + + +wav:e->id3v2:n + + + + + +wav:e->id3v1:n + + + + + +wav:e->id3v11:n + + + + + +webp:e->vp8_frame:n + + + + + +zip:e->probe:n + + + + + +asn1_ber + +asn1_ber + + + +bencode + +bencode + + + +bson + +bson + + + +cbor + +cbor + + + +dns_tcp + +dns_tcp + + + +msgpack + +msgpack + + + +raw + +raw + + + diff --git a/doc/presentations/bts2022/fq-bts2022-v1.pdf b/doc/presentations/bts2022/fq-bts2022-v1.pdf new file mode 100644 index 0000000000..d450bf19ad Binary files /dev/null and b/doc/presentations/bts2022/fq-bts2022-v1.pdf differ diff --git a/doc/presentations/bts2022/fq.slide b/doc/presentations/bts2022/fq.slide new file mode 100644 index 0000000000..6e1a52d635 --- /dev/null +++ b/doc/presentations/bts2022/fq.slide @@ -0,0 +1,238 @@ +# fq + +jq for binary formats + +Mattias Wadman +mattias.wadman@gmail.com +https://github.com/wader/fq +@mwader + +## Background + +.html style.html + +- Use various tools to extract data + - ffprobe, gm identify, mp4dump, mediainfo, wireshark, one off programs, ... +- Convert to usable format and do queries + - jq, grep, sqlite, sort, awk, sed, one off programs, ... +- Digging into and slicing binaries + - Hexfiend, hexdump, dd, cat, one off programs, ... + + +## Wishlist + +"Want to see everything about this picture except the picture" + +- A very verbose version of file(1) +- gdb for files +- Select and query things using a language +- Make all parts of a file symbolically addressable +- Nested formats and binaries +- Convenient bit-oriented decoder DSL + + +## Experiments and prototypes + +- Decoder DSL + - TCL, lisp, tengo, Starlark, JavaScript, Go +- Query language + - JSONPath, SQL, jq, JavaScript +- How to use + - IR-JSON: `fq file | jq ... | fq` + - Extend existing project + - Decode and query in same tool + + +## Result + +Go + +- Tests showed fast enough to decode big files +- Found gojq +- Previous good experience +- Good tooling + + +## jq + +"The JSON indenter" + +- JSON in/out +- Syntax kind of a superset of JSON with same types +- Functional language based on generators and backtracking + - Expressions can return or "output" zero, one or more values + - No more outputs backtracks +- Implicit input and output similar to shell pipes +- Extraordinary iteration and combinatorial abilities +- Great for traversing tree structures + + +## Examples + +.code jq1 + +## Examples + +.code jq2 + +## Examples + +.code jq3 + + +## Examples + +.code jq4 + + +## fq + +"The binary indenter" + +- Superset of jq +- Re-implements most of jq's CLI interface +- 83 input formats, 22 supports probe +- Additional standard library functions +- Additional types that act as standard jq types but has special abilities + - _Decode value_ has bit range, actual and symbolic value, description, ... + - _Binary_ has a unit size, bit or bytes, and can be sliced +- Output fancy hexdump, JSON and binary +- Interactive REPL with completion and sub-REPL support + + +## + +.image formats.svg _ 1024 + +## Usage + +- Basic usage + - `fq . file`, `cat file | fq` +- Multiple input files + - `fq 'grep_by(format == "exif")' *.png *.jpeg` +- Hexdump, JSON and binary output + - `fq '.frames[10] | d' file.mp3` + - `fq '[grep_by(format == "dns").questions[].name.value]' file.pcap` + - `fq 'first(grep_by(format == "jpeg")) | tobytes' file > file.jpeg` +- Interactive REPL + - `fq -i . *.png` + + +## + +.background data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAABNJREFUCB1jZGBg+A/EDEwgAgQADigBA//q6GsAAAAASUVORK5CYII%3D +.image usage.svg _ 900 + + +## fq specific functions + +- Standard library + - `streaks`, `count`, `delta`, `chunk`, `diff`, `grep`, `grep_by`, ... + - `toradix`, `fromradix`, `hex`, `base64`, ... +- Decode value + - `display` (alias `d`, `dv`, `da` ...) + - `parent`, `format`, ... + - `tobytes`, `tovalue`, `toactual`, ... + - `torepr`, ... +- Binary + - Regexp functions `test`, `match`, ... + - Decode functions `probe`, `mp3_frame`, ... + + +## Binary and binary array + +- A binary is created using `tobits`, `tobytes`, `tobitsrange` or `tobytesrange`. + - From decode value `.frames[1] | tobytes` + - String or number `"hello" | tobits` + - Binary array `[0xab, ["hello", .name]] | tobytes` +- Can be sliced using normal jq slice syntax. + - `"hello" | tobits[8:8+16]` are the bits for `"el"` +- Can be decoded + - `[tobytes[-10:], 0, 0, 0, 0] | flac_frame` + + +## Example queries + +- Slice and decode + - `tobits[8:8+8000] | mp3_frame | d` + - `match([0xff,0xd8]) as $m | tobytes[$m.offset:] | jpeg` +- ASN1 BER, CBOR, msgpack, BSON, ... has `torepr` support + - `fq -d cbor torepr file.cbor` + - `fq -d msgpack '[torepr.items[].name]' file.msgpack` +- PCAP with TCP reassembly, look for GET requests + - `fq 'grep("GET .*")' file.pcap` +- Parent of scalar value that includes bit 100 + - `grep_by(scalars and in_bits_range(100)) | parent` + + +## Use as script interpreter + +.code fqscript + + +## Use as script interpreter + +.code fqscriptout + + +## Implementation + +- Library of jq function implemented in Go + - Decoders, decode value, binary, bit reader, IO, tty, ... +- CLI and REPL is mostly written in jq + ``` + ( open + | decode + | if $repl then repeat(read as $expr | eval($expr) | print) + else eval($arg) | print + end + ) + ``` +- All current decoders in Go +- Uses a forked version of gojq + - Helped add native functions and iterators support + - JQValue interface, bin/hex/oct literals, reflection, query AST functions, ... + +## Decode API + +SPS HRD parameters from ITU-T H.264 specification + +.code avc_sps_hdr_params.go + +## Decode API + +.image avc_sps_hdr_params.png _ 900 + + +## Decode API + +Formats can use other formats. Simplified version of mp3 decoder: + +.code mp3.go + + +## Future + +- Declarative decoding like kaitai struct, decoder in jq +- Nicer way to handle checksums, encoding, validation etc +- Schemas for ASN1, protobuf, ... +- Better support for modifying data +- More formats like tls, http, http2, grpc, filesystems, ... +- Encoders +- More efficient, lazy decoding, smarter representation +- GUI +- Streaming input, read network traffic `tap("eth0") | select(...)`? +- Hope for more contributors + + +## Thanks and useful tools + +- @itchyny for gojq +- Stephen Dolan and others for jq +- HexFiend +- GNU poke +- Kaitai struct +- Wireshark +- [vscode-jq](https://github.com/wader/vscode-jq) +- [jq-lsp](https://github.com/wader/jq-lsp) + diff --git a/doc/presentations/bts2022/fqscript b/doc/presentations/bts2022/fqscript new file mode 100755 index 0000000000..5b93cd957c --- /dev/null +++ b/doc/presentations/bts2022/fqscript @@ -0,0 +1,22 @@ +#!/usr/bin/env fq -d mp4 -f + +( first(.boxes[] | select(.type == "moov")?) +| first(.boxes[] | select(.type == "mvhd")?) as $mvhd +| { time_scale: $mvhd.time_scale, + duration: ($mvhd.duration / $mvhd.time_scale), + tracks: + [ .boxes[] + | select(.type == "trak") + | [("mdhd", "stsd", "elst") as $t | first(grep_by(.type == $t))] as [$mdhd, $stsd, $elst] + | { data_format: $stsd.boxes[0].type, + media_scale: $mdhd.time_scale, + edit_list: + [ $elst.entries[] + | { track_duration: (.segment_duration / $mvhd.time_scale), + media_time: (.media_time / $mdhd.time_scale) + } + ] + } + ] + } +) \ No newline at end of file diff --git a/doc/presentations/bts2022/fqscriptout b/doc/presentations/bts2022/fqscriptout new file mode 100644 index 0000000000..10fa96b93d --- /dev/null +++ b/doc/presentations/bts2022/fqscriptout @@ -0,0 +1,23 @@ +$ ./editlist file.mp4 +{ + "duration": 60.095, + "time_scale": 600, + "tracks": [ + { + "data_format": "mp4a", + "edit_list": [ + { + "media_time": 0, + "track_duration": 60.095 + } + ], + "media_scale": 22050 + }, + { + "data_format": "avc1", + "edit_list": [ + { + "media_time": 0, + "track_duration": 60.095 + } +... \ No newline at end of file diff --git a/doc/presentations/bts2022/jq1 b/doc/presentations/bts2022/jq1 new file mode 100644 index 0000000000..33e838c211 --- /dev/null +++ b/doc/presentations/bts2022/jq1 @@ -0,0 +1,23 @@ +# Literals +> 123 +123 + +> "abc" +"abc" + +> [1,2,3] +[ + 1, + 2, + 3 +] + +> {a: (1+2+3), b: ["abc", false, null]} +{ + "a": 6, + "b": [ + "abc", + false, + null + ] +} \ No newline at end of file diff --git a/doc/presentations/bts2022/jq2 b/doc/presentations/bts2022/jq2 new file mode 100644 index 0000000000..e99ef7103c --- /dev/null +++ b/doc/presentations/bts2022/jq2 @@ -0,0 +1,20 @@ +# Pipeline using pipe operator "|" and identity function "." for current input +> "hello" | length | . * 2 +10 + +# Multiple outputs using output operator "," +> 1, 2 | . * 2 +2 +4 + +# Index array or object using .[key/index] or just .key for objects +> [1,2,3][1] +2 + +# Collect outputs into array using [...] +> [1,empty,2] +[1,2] + +# Iterate array or object using .[] +> [[1,2,3][]] +[1,2,3] diff --git a/doc/presentations/bts2022/jq3 b/doc/presentations/bts2022/jq3 new file mode 100644 index 0000000000..3632a5b692 --- /dev/null +++ b/doc/presentations/bts2022/jq3 @@ -0,0 +1,22 @@ +# Generators and backtracking +> 1, (2, 3 | . * 2), 4 +1 +4 +6 +4 + +# Conditional, boolean operators and comparsion +> if 1 == 2 and true then "a" else "b" end +"b" + +# Reduce and foreach +> reduce (1,2,3) as $i (0; . + $i) +6 +> foreach (1,2,3) as $i (0; . + $i; .) +1 +3 +6 + +# Bindings (variables) +> 1 as $a | 2 as $b | $a + $b +3 diff --git a/doc/presentations/bts2022/jq4 b/doc/presentations/bts2022/jq4 new file mode 100644 index 0000000000..29342a4d89 --- /dev/null +++ b/doc/presentations/bts2022/jq4 @@ -0,0 +1,20 @@ +# Function using lambda argument. map from standard library: +def map(f): [.[] | f]; +> [1,2,3] | map(. * 2) +[ + 2, + 4, + 6 +] +# select from standard library: +def select(f): if f then . else empty end; +> [1,2,3] | map(select(. % 2 == 0)) +[ + 2 +] + +# Function using argument binding and recursion to output multiple values +def down($n): + if $n >= 0 then $n, down($n-1) + else empty + end; diff --git a/doc/presentations/bts2022/mp3.go b/doc/presentations/bts2022/mp3.go new file mode 100644 index 0000000000..83b421698c --- /dev/null +++ b/doc/presentations/bts2022/mp3.go @@ -0,0 +1,21 @@ +func decode(d *decode.D, in interface{}) interface{} { + d.FieldArray("headers", func(d *decode.D) { + for !d.End() { + d.TryFieldFormat("header", headerGroup) + } + }) + + d.FieldArray("frames", func(d *decode.D) { + for !d.End() { + d.TryFieldFormat("frame", mp3Group) + } + }) + + d.FieldArray("footers", func(d *decode.D) { + for !d.End() { + d.TryFieldFormat("footer", footerGroup) + } + }) + + return nil +} diff --git a/doc/presentations/bts2022/style.html b/doc/presentations/bts2022/style.html new file mode 100644 index 0000000000..bd8799e6f5 --- /dev/null +++ b/doc/presentations/bts2022/style.html @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/doc/presentations/bts2022/usage.sh b/doc/presentations/bts2022/usage.sh new file mode 100755 index 0000000000..9048ebef11 --- /dev/null +++ b/doc/presentations/bts2022/usage.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +c() { + echo -e "\x1b[97m# $1\x1b[0m" +} + +s() { + echo "\$ $1" + sh -c "${1/fq/fq -o line_bytes=16 -o unicode=true -C}" +} + +n() { + sh -c "${1/fq/fq -o line_bytes=16 -o unicode=true -C}" +} + +c "display a decode value" +s "fq . file.mp3" +echo +echo + +c "expression returning a number" +s "fq '.frames | length' file.mp3" +echo +echo + +c "raw bytes" +s "fq 'grep_by(format == \"png\") | tobytes' file.mp3 >file.png" +s "file file.png" +echo +echo + +c "interactve REPL" +echo "\$ fq -i . file.mp3" +echo "mp3> .frames | length" +n "fq '.frames | length' file.mp3" +echo "mp3> .header[0] | repl" +echo "> .headers[0] id3v2> .frames[0].text" +n "fq '.headers[0].frames[0].text' file.mp3" +echo "> .headers[0] id3v2> .frames[0].text | tovalue" +n "fq '.headers[0].frames[0].text | tovalue' file.mp3" +echo "> .headers[0] id3v2> ^D" +echo "mp3> ^D" +echo "$" diff --git a/doc/presentations/bts2022/usage.svg b/doc/presentations/bts2022/usage.svg new file mode 100644 index 0000000000..0a0eb4db5c --- /dev/null +++ b/doc/presentations/bts2022/usage.svg @@ -0,0 +1,911 @@ + + + + # + d + i + s + p + l + a + y + a + d + e + c + o + d + e + v + a + l + u + e + $ + f + q + . + f + i + l + e + . + m + p + 3 + + 0 + 0 + + 0 + 1 + + 0 + 2 + + 0 + 3 + + 0 + 4 + + 0 + 5 + + 0 + 6 + + 0 + 7 + + 0 + 8 + + 0 + 9 + + 0 + a + + 0 + b + + 0 + c + + 0 + d + + 0 + e + + 0 + f + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + a + b + c + d + e + f + + . + { + } + : + f + i + l + e + . + m + p + 3 + ( + m + p + 3 + ) + 0 + x + 0 + 0 + 0 + + 4 + 9 + 4 + 4 + 3 + 3 + 0 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 5 + 3 + 9 + 5 + 4 + 5 + 3 + 5 + 3 + 4 + 5 + 0 + 0 + 0 + 0 + + I + D + 3 + . + . + . + . + . + . + 9 + T + S + S + E + . + . + + h + e + a + d + e + r + s + [ + 0 + : + 1 + ] + : + * + + u + n + t + i + l + 0 + x + a + c + 2 + . + 7 + ( + 2 + 7 + 5 + 5 + ) + + + 0 + x + a + c + 0 + + f + f + f + b + 4 + 0 + c + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + . + . + @ + . + . + . + . + . + . + . + . + . + . + + f + r + a + m + e + s + [ + 0 + : + 3 + ] + : + 0 + x + a + d + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 4 + 9 + 6 + e + 6 + 6 + 6 + f + 0 + 0 + 0 + 0 + 0 + 0 + 0 + f + + . + . + . + . + . + . + . + . + I + n + f + o + . + . + . + . + + * + + u + n + t + i + l + 0 + x + d + 1 + 9 + . + 7 + ( + e + n + d + ) + ( + 5 + 9 + 9 + ) + + + + + + f + o + o + t + e + r + s + [ + 0 + : + 0 + ] + : + # + e + x + p + r + e + s + s + i + o + n + r + e + t + u + r + n + i + n + g + a + n + u + m + b + e + r + $ + f + q + ' + . + f + r + a + m + e + s + | + l + e + n + g + t + h + ' + f + i + l + e + . + m + p + 3 + 3 + # + r + a + w + b + y + t + e + s + $ + f + q + ' + g + r + e + p + _ + b + y + ( + f + o + r + m + a + t + = + = + " + p + n + g + " + ) + | + t + o + b + y + t + e + s + ' + f + i + l + e + . + m + p + 3 + > + f + i + l + e + . + p + n + g + $ + f + i + l + e + f + i + l + e + . + p + n + g + f + i + l + e + . + p + n + g + : + P + N + G + i + m + a + g + e + d + a + t + a + , + 3 + 2 + 0 + x + 2 + 4 + 0 + , + 8 + - + b + i + t + / + c + o + l + o + r + R + G + B + , + n + o + n + - + i + n + t + e + r + l + a + c + e + d + # + i + n + t + e + r + a + c + t + v + e + R + E + P + L + $ + f + q + - + i + . + f + i + l + e + . + m + p + 3 + m + p + 3 + > + . + f + r + a + m + e + s + | + l + e + n + g + t + h + 3 + m + p + 3 + > + . + h + e + a + d + e + r + [ + 0 + ] + | + r + e + p + l + > + . + h + e + a + d + e + r + s + [ + 0 + ] + i + d + 3 + v + 2 + > + . + f + r + a + m + e + s + [ + 0 + ] + . + t + e + x + t + + 0 + 0 + + 0 + 1 + + 0 + 2 + + 0 + 3 + + 0 + 4 + + 0 + 5 + + 0 + 6 + + 0 + 7 + + 0 + 8 + + 0 + 9 + + 0 + a + + 0 + b + + 0 + c + + 0 + d + + 0 + e + + 0 + f + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + a + b + c + d + e + f + + 0 + x + 1 + 0 + + 4 + c + 6 + 1 + 7 + 6 + 6 + 6 + 3 + 5 + 3 + 8 + 2 + e + 3 + 7 + 3 + 6 + 2 + e + 3 + 1 + + L + a + v + f + 5 + 8 + . + 7 + 6 + . + 1 + + . + h + e + a + d + e + r + s + [ + 0 + ] + . + f + r + a + m + e + s + [ + 0 + ] + . + t + e + x + t + : + " + L + a + v + f + 5 + 8 + . + 7 + 6 + . + 1 + 0 + 0 + " + 0 + x + 2 + 0 + + 3 + 0 + 3 + 0 + 0 + 0 + + 0 + 0 + . + + > + . + h + e + a + d + e + r + s + [ + 0 + ] + i + d + 3 + v + 2 + > + . + f + r + a + m + e + s + [ + 0 + ] + . + t + e + x + t + | + t + o + v + a + l + u + e + " + L + a + v + f + 5 + 8 + . + 7 + 6 + . + 1 + 0 + 0 + " + > + . + h + e + a + d + e + r + s + [ + 0 + ] + i + d + 3 + v + 2 + > + ^ + D + m + p + 3 + > + ^ + D + $ +