Skip to content

Commit

Permalink
interp: Cleanup, use BufferRange for _open, progress for all decode
Browse files Browse the repository at this point in the history
  • Loading branch information
wader committed Oct 29, 2021
1 parent 0814206 commit 67898cb
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 97 deletions.
3 changes: 0 additions & 3 deletions format/flac/flac_metadatablocks.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package flac

// TODO: 24 bit picture length truncate warning
// TODO: Cuesheet

import (
"fmt"

Expand Down
2 changes: 1 addition & 1 deletion pkg/interp/bufferrange.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type BufferRange struct {
unit int
}

func bufferViewFromBuffer(bb *bitio.Buffer, unit int) BufferRange {
func newBufferRangeFromBuffer(bb *bitio.Buffer, unit int) BufferRange {
return BufferRange{
bb: bb,
r: ranges.Range{Start: 0, Len: bb.Len()},
Expand Down
4 changes: 2 additions & 2 deletions pkg/interp/formats.jq
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
| to_entries[]
# TODO: nicer way to skip "all" which also would override builtin all/*
| select(.key != "all")
| "def \(.key)($opts): _decode(\(.key | tojson); $opts);"
, "def \(.key): _decode(\(.key | tojson); {});"
| "def \(.key)($opts): decode(\(.key | tojson); $opts);"
, "def \(.key): decode(\(.key | tojson); {});"
)
, ( _registry.formats[]
| select(.files)
Expand Down
32 changes: 14 additions & 18 deletions pkg/interp/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func makeStringBitBufTransformFn(
}
outBB := bitio.NewBufferFromBytes(buf.Bytes(), -1)

return bufferViewFromBuffer(outBB, 8)
return newBufferRangeFromBuffer(outBB, 8)
default:
bb, err := toBuffer(c)
if err != nil {
Expand Down Expand Up @@ -170,7 +170,7 @@ func makeBitBufTransformFn(fn func(r io.Reader) (io.Reader, error)) func(c inter

outBB := bitio.NewBufferFromBytes(outBuf.Bytes(), -1)

return bufferViewFromBuffer(outBB, 8)
return newBufferRangeFromBuffer(outBB, 8)
}
}

Expand All @@ -192,7 +192,7 @@ func makeHashFn(fn func() (hash.Hash, error)) func(c interface{}, a []interface{

outBB := bitio.NewBufferFromBytes(h.Sum(nil), -1)

return bufferViewFromBuffer(outBB, 8)
return newBufferRangeFromBuffer(outBB, 8)
}
}

Expand Down Expand Up @@ -473,24 +473,21 @@ func (i *Interp) history(c interface{}, a []interface{}) interface{} {
return vs
}

type bitBufFile struct {
gojq.JQValue

bb *bitio.Buffer
filename string

type openFile struct {
BufferRange
filename string
progressFn progressreadseeker.ProgressFn
}

var _ ToBufferView = (*bitBufFile)(nil)
var _ ToBufferView = (*openFile)(nil)

func (bbf *bitBufFile) Display(w io.Writer, opts Options) error {
_, err := fmt.Fprintln(w, bbf.JQValue.JQValueToString())
func (of *openFile) Display(w io.Writer, opts Options) error {
_, err := fmt.Fprintf(w, "<openFile %q>\n", of.filename)
return err
}

func (bbf *bitBufFile) ToBufferView() (BufferRange, error) {
return bufferViewFromBuffer(bbf.bb, 8), nil
func (of *openFile) ToBufferView() (BufferRange, error) {
return newBufferRangeFromBuffer(of.bb, 8), nil
}

// def open: #:: string| => buffer
Expand Down Expand Up @@ -541,8 +538,7 @@ func (i *Interp) _open(c interface{}, a []interface{}) interface{} {
bEnd = int64(len(buf))
}

bbf := &bitBufFile{
JQValue: gojqextra.String(fmt.Sprintf("<bitBufFile %s>", path)),
bbf := &openFile{
filename: path,
}

Expand Down Expand Up @@ -581,7 +577,7 @@ func (i *Interp) _decode(c interface{}, a []interface{}) interface{} {
// would be nice to move all progress code into decode but it might be
// tricky to keep track of absolute positions in the underlaying readers
// when it uses BitBuf slices, maybe only in Pos()?
if bbf, ok := c.(*bitBufFile); ok {
if bbf, ok := c.(*openFile); ok {
opts.Filename = bbf.filename

if opts.Progress != "" {
Expand Down Expand Up @@ -732,7 +728,7 @@ func (i *Interp) _toBitsRange(c interface{}, a []interface{}) interface{} {

if !r {
bb, _ := bv.toBuffer()
return bufferViewFromBuffer(bb, unit)
return newBufferRangeFromBuffer(bb, unit)
}

return bv
Expand Down
68 changes: 40 additions & 28 deletions pkg/interp/funcs.jq
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,45 @@ def help:
, "^D Exit REPL"
) | println;

# null input means done, otherwise {approx_read_bytes: 123, total_size: 123}
# TODO: decode provide even more detailed progress, post-process sort etc?
def _decode_progress:
# _input_filenames is remaning files to read
( (_input_filenames | length) as $inputs_len
| ( options.filenames | length) as $filenames_len
| _ansi.clear_line
, "\r"
, if . != null then
( if $filenames_len > 1 then
"\($filenames_len - $inputs_len)/\($filenames_len) \(_input_filename) "
else empty
end
, "\((.approx_read_bytes / .total_size * 100 | _numbertostring(1)))%"
)
else empty
end
| stderr
);

def decode($name; $opts):
( options as $opts
| (null | stdout) as $stdout
| _decode(
$name;
$opts + {
_progress: (
if $opts.decode_progress and $opts.repl and $stdout.is_terminal then
"_decode_progress"
else null
end
)
}
)
);
def decode($name): decode($name; {});
def decode: decode(options.decode_format; {});


def display($opts): _display($opts);
def display: _display({});
def d($opts): _display($opts);
Expand Down Expand Up @@ -66,34 +105,7 @@ def match($regex; $flags): if _is_buffer then _bits_match($regex; $flags) else _
def formats:
_registry.formats;

# integer division
# inspried by https://github.com/itchyny/gojq/issues/63#issuecomment-765066351
def intdiv($a; $b):
( ($a | _to_int) as $a
| ($b | _to_int) as $b
| ($a - ($a % $b)) / $b
);

def _esc: "\u001b";
def _ansi:
{
clear_line: "\(_esc)[2K",
};

# valid jq identifier, start with alpha or underscore then zero or more alpha, num or underscore
def _is_ident: type == "string" and test("^[a-zA-Z_][a-zA-Z_0-9]*$");
# escape " and \
def _escape_ident: gsub("(?<g>[\\\\\"])"; "\\\(.g)");

# format number with fixed number of decimals
def _numbertostring($decimals):
( . as $n
| [ (. % (. + 1)) # truncate to integer
, "."
, foreach range($decimals) as $_ (1; . * 10; ($n * .) % 10)
]
| join("")
);
def intdiv(a; b): _intdiv(a; b);

# TODO: escape for safe key names
# path ["a", 1, "b"] -> "a[1].b"
Expand Down
29 changes: 29 additions & 0 deletions pkg/interp/internal.jq
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,35 @@ def _finally(f; fin):
# TODO: figure out a saner way to force int
def _to_int: (. % (. + 1));

# integer division
# inspried by https://github.com/itchyny/gojq/issues/63#issuecomment-765066351
def _intdiv($a; $b):
( ($a | _to_int) as $a
| ($b | _to_int) as $b
| ($a - ($a % $b)) / $b
);

def _esc: "\u001b";
def _ansi:
{
clear_line: "\(_esc)[2K",
};

# valid jq identifier, start with alpha or underscore then zero or more alpha, num or underscore
def _is_ident: type == "string" and test("^[a-zA-Z_][a-zA-Z_0-9]*$");
# escape " and \
def _escape_ident: gsub("(?<g>[\\\\\"])"; "\\\(.g)");

# format number with fixed number of decimals
def _numbertostring($decimals):
( . as $n
| [ (. % (. + 1)) # truncate to integer
, "."
, foreach range($decimals) as $_ (1; . * 10; ($n * .) % 10)
]
| join("")
);

def _repeat_break(f):
try repeat(f)
catch
Expand Down
3 changes: 1 addition & 2 deletions pkg/interp/interp.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ func toBufferView(v interface{}) (BufferRange, error) {
if err != nil {
return BufferRange{}, err
}
return bufferViewFromBuffer(bb, 8), nil
return newBufferRangeFromBuffer(bb, 8), nil
}
}

Expand Down Expand Up @@ -546,7 +546,6 @@ func (i *Interp) Eval(ctx context.Context, c interface{}, src string, srcFilenam
return []*gojq.Query{i.initFqQuery}, nil
},
load: func(name string) (*gojq.Query, error) {
// log.Printf("name: %#+v\n", name)
if err := ctx.Err(); err != nil {
return nil, err
}
Expand Down
41 changes: 1 addition & 40 deletions pkg/interp/interp.jq
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
include "internal";
include "options";
include "funcs";
include "grep";
include "options";
include "args";
include "repl";
# generated decode functions per format and format helpers
Expand All @@ -24,45 +24,6 @@ def _exit_code_compile_error: 3;
def _exit_code_input_decode_error: 4;
def _exit_code_expr_error: 5;


# null input means done, otherwise {approx_read_bytes: 123, total_size: 123}
# TODO: decode provide even more detailed progress, post-process sort etc?
def _decode_progress:
# _input_filenames is remaning files to read
( (_input_filenames | length) as $inputs_len
| ( options.filenames | length) as $filenames_len
| _ansi.clear_line
, "\r"
, if . != null then
( if $filenames_len > 1 then
"\($filenames_len - $inputs_len)/\($filenames_len) \(_input_filename) "
else empty
end
, "\((.approx_read_bytes / .total_size * 100 | _numbertostring(1)))%"
)
else empty
end
| stderr
);

def decode($name; $opts):
( options as $opts
| (null | stdout) as $stdout
| _decode(
$name;
$opts + {
_progress: (
if $opts.decode_progress and $opts.repl and $stdout.is_terminal then
"_decode_progress"
else null
end
)
}
)
);
def decode($name): decode($name; {});
def decode: decode(options.decode_format; {});

# next valid input
def input:
def _input($opts; f):
Expand Down
4 changes: 2 additions & 2 deletions pkg/interp/options.jq
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ def _build_default_dynamic_options:
( (null | stdout) as $stdout
| {
# TODO: intdiv 2 * 2 to get even number, nice or maybe not needed?
display_bytes: (if $stdout.is_terminal then [intdiv(intdiv($stdout.width; 8); 2) * 2, 4] | max else 16 end),
line_bytes: (if $stdout.is_terminal then [intdiv(intdiv($stdout.width; 8); 2) * 2, 4] | max else 16 end),
display_bytes: (if $stdout.is_terminal then [_intdiv(_intdiv($stdout.width; 8); 2) * 2, 4] | max else 16 end),
line_bytes: (if $stdout.is_terminal then [_intdiv(_intdiv($stdout.width; 8); 2) * 2, 4] | max else 16 end),
}
);

Expand Down
2 changes: 1 addition & 1 deletion pkg/interp/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func makeDecodeValue(dv *decode.Value) interface{} {
case []byte:
// TODO: not sure about this
// TODO: only synthentic value without range?
return bufferViewFromBuffer(bitio.NewBufferFromBytes(vv, -1), 8)
return newBufferRangeFromBuffer(bitio.NewBufferFromBytes(vv, -1), 8)
case []interface{}:
return decodeValue{
JQValue: gojqextra.Array(vv),
Expand Down

0 comments on commit 67898cb

Please sign in to comment.