1
1
mirror of https://github.com/wader/fq.git synced 2024-10-04 15:38:17 +03:00
fq/doc/dev.md

147 lines
4.6 KiB
Markdown
Raw Normal View History

2020-06-08 03:29:51 +03:00
# Implementation details
- fq uses a gojq fork that can be found at https://github.com/wader/gojq/tree/fq (the "fq" branch)
2021-12-31 19:13:16 +03:00
- fq uses a readline fork that can be found at https://github.com/wader/readline/tree/fq (the "fq" branch)
2020-06-08 03:29:51 +03:00
- cli readline uses raw mode so blocks ctrl-c to become a SIGINT
## Implement a decoder
### Steps to add new decoder
- Create a directory `format/<name>`
- Copy some similar decoder, `format/format/bson.go` is quite small, to `format/<name>/<name>.go`
- Cleanup and fill in the register struct, rename `format.BSON` and don't forget to change the string constant.
- Add an import to `format/all/all.go`
## Things to think about
2020-06-08 03:29:51 +03:00
- Main goal in the end is to produce a tree that is user-friendly and easy to work with.
Prefer a nice and easy to use tree over nice decoder implementation.
- Use same names, symbols, constant number base etc as in specification. But prefer lowercase to jq/JSON-ish.
- Decode only ranges you know what they are. If possible let "parent" decide what to do with unknown
bits by using `*Decode*Len/Range/Limit` functions. fq will automatically add "unknown" fields.
- Try to no decode too much as one value.
A length encoded int could be two fields, but maybe a length prefixed string should be one.
Flags can be struct with bit-fields.
- Map as many value as possible to more usage symbolic values.
- Endian is inherited inside one format decoder, defaults to big endian for new format decoder
- Make sure zero length or no frames etc found fails decoding
- If in the probe group make sure to validate input to make it non-ambiguous with other decoders
- Try keep decoder code as declarative as possible
- Split into multiple sub formats if possible. Makes it possible to use them separately.
- Validate/Assert
- Error/Fatal/panic
2021-12-31 19:13:16 +03:00
- Is format probeable or not
- Can new formats be added to other formats
2021-12-31 19:13:16 +03:00
- Does the new format include existing formats
2022-01-01 13:45:03 +03:00
Run `make doc` generate some of the documentation (requires [FFmpeg](https://github.com/FFmpeg/FFmpeg) and [Graphviz](https://gitlab.com/graphviz/graphviz)).
2021-12-31 19:13:16 +03:00
Run `make lint` to lint source code.
TODO: `make fuzz`
2020-06-08 03:29:51 +03:00
## Tests
2020-06-08 03:29:51 +03:00
```sh
2021-12-31 19:13:16 +03:00
# run all tests for one format
go test -run TestFQTests/mp4 ./format/
# write all actual outputs
make actual
# write for specific tests
WRITE_ACTUAL=1 go run -run ...
```
2020-06-08 03:29:51 +03:00
2021-08-27 10:47:43 +03:00
## Debug
Split debug and normal output even when using repl:
Write `log` package output and stderr to a file that can be `tail -f`:ed in another terminal:
2021-08-27 10:47:43 +03:00
```sh
2021-12-03 12:35:52 +03:00
LOGFILE=/tmp/log go run fq.go ... 2>>/tmp/log
2021-08-27 10:47:43 +03:00
```
gojq execution debug:
```sh
2021-12-03 12:35:52 +03:00
GOJQ_DEBUG=1 go run -tags debug fq.go ...
2021-08-27 10:47:43 +03:00
```
Memory and CPU profile (will open a browser):
```sh
make memprof ARGS=". file"
make cpuprof ARGS=". test.mp3"
```
## From start to decoded value
```
main:main()
cli.Main(default registry)
interp.New(registry, std os interp implementation)
interp.(*Interp).Main()
interp.jq _main/0:
args.jq _args_parse/2
populate filenames for input/0
interp.jq inputs/0
foreach valid input/0 output
interp.jq open
funcs.go _open
interp.jq decode
funcs.go _decode
decode.go Decode(...)
...
interp.jq eval expr
funcs.go _eval
interp.jq display
funcs.go _display
for interp.(decodeValueBase).Display()
dump.go
print tree
empty output
```
2021-11-21 23:55:53 +03:00
## bitio and other io packages
```
*os.File, *bytes.Buffer
^
ctxreadseeker.Reader defers blocking io operations to a goroutine to make them cancellable
^
progressreadseeker.Reader approximates how much of a file has been read
^
aheadreadseeker.Reader does readahead caching
^
| (io.ReadSeeker interface)
|
bitio.Reader (implements bitio.Bit* interfaces)
^
| (bitio.Bit* interfaces)
|
bitio.Buffer convenience wrapper to read bytes from bit reader, create section readers etc
SectionBitReader
MultiBitReader
```
## jq oddities
```
jq -n '[1,2,3,4] | .[null:], .[null:2], .[2:null], .[:null]'
```
## Setup docker desktop with golang windows container
```sh
git clone https://github.com/StefanScherer/windows-docker-machine.git
cd windows-docker-machine
vagrant up 2016-box
cd ../fq
docker --context 2016-box run --rm -ti -v "C:${PWD//\//\\}:C:${PWD//\//\\}" -w "$PWD" golang:1.17.5-windowsservercore-ltsc2016
2022-01-06 11:57:47 +03:00
```
## Release process
Run and follow instructions:
```
make release=1.2.3
```