mirror of
https://github.com/wader/fq.git
synced 2024-12-23 13:22:58 +03:00
Add to/bytes/bits[range]
This commit is contained in:
parent
a050adca49
commit
7f36f703dd
1
LICENSE
1
LICENSE
@ -1,4 +1,5 @@
|
|||||||
Copyright (c) 2021 Mattias Wadman
|
Copyright (c) 2021 Mattias Wadman
|
||||||
|
colorjson fork and various code in gojqextra package Copyright (c) 2019-2021 itchyny
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
14
doc/usage.md
14
doc/usage.md
@ -142,16 +142,22 @@ notable is support for arbitrary-precision integers.
|
|||||||
- `format_root/0` return root value of format for value
|
- `format_root/0` return root value of format for value
|
||||||
- `parent/0` return parent value
|
- `parent/0` return parent value
|
||||||
- `parents/0` output parents of value
|
- `parents/0` output parents of value
|
||||||
- `find` and `grep` all take 1 or 2 arguments. First is a scalar to match, where a string is
|
- All `find` and `grep` functions take 1 or 2 arguments. First is a scalar to match, where a string is
|
||||||
treated as a regexp. A buffer will be matches exact bytes. Second argument is regexp
|
treated as a regexp. A buffer scalar will be matches exact bytes. Second argument are regexp
|
||||||
flags with addition to "b" which will treat each byte in the input buffer as a rune, this
|
flags with addition that "b" will treat each byte in the input buffer as a code point, this
|
||||||
makes it possible to match exact bytes, ex: `find("\u00ff"; b")` will match the byte `0xff` and not
|
makes it possible to match exact bytes, ex: `find("\u00ff"; b")` will match the byte `0xff` and not
|
||||||
the UTF-8 codepoint `0xff`.
|
the UTF-8 encoded codepoint for 255.
|
||||||
- `find/1`, `find/2` match in buffer and output match buffers
|
- `find/1`, `find/2` match in buffer and output match buffers
|
||||||
- `grep/1`, `grep/2` recursively match value and buffer
|
- `grep/1`, `grep/2` recursively match value and buffer
|
||||||
- `vgrep/1`, `vgrep/2` recursively match value
|
- `vgrep/1`, `vgrep/2` recursively match value
|
||||||
- `bgrep/1`, `bgrep/2` recursively match buffer
|
- `bgrep/1`, `bgrep/2` recursively match buffer
|
||||||
- `fgrep/1`, `fgrep/2` recursively match field name
|
- `fgrep/1`, `fgrep/2` recursively match field name
|
||||||
|
- Buffers:
|
||||||
|
- `tobits` - Transform input into a bits buffer not preserving source range, will start at zero.
|
||||||
|
- `tobitsrange` - Transform input into a bits buffer preserving source range if possible.
|
||||||
|
- `tobytes` - Transform input into a bytes buffer not preserving source range, will start at zero.
|
||||||
|
- `tobytesrange` - Transform input into a byte buffer preserving source range if possible.
|
||||||
|
- `buffer[start:end]`, `buffer[:end]`, `buffer[start:]` - Create a sub buffer from start to end in buffer units preserving source range.
|
||||||
- `open` open file for reading
|
- `open` open file for reading
|
||||||
- `probe` or `decode` probe format and decode
|
- `probe` or `decode` probe format and decode
|
||||||
- `mp3`, `matroska`, ..., `<name>`, `decode([name])` force decode as format
|
- `mp3`, `matroska`, ..., `<name>`, `decode([name])` force decode as format
|
||||||
|
@ -1,17 +1,40 @@
|
|||||||
package gojqextra
|
package gojqextra
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
// many of these based on errors form gojq
|
"github.com/wader/gojq"
|
||||||
|
)
|
||||||
|
|
||||||
|
// many of these based on errors from gojq
|
||||||
// TODO: refactor to use errors from gojq?
|
// TODO: refactor to use errors from gojq?
|
||||||
// TODO: preview from gojq?
|
// TODO: preview from gojq?
|
||||||
|
|
||||||
|
type NonUpdatableTypeError struct {
|
||||||
|
Typ string
|
||||||
|
Key string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err NonUpdatableTypeError) Error() string {
|
||||||
|
return fmt.Sprintf("update key %v cannot be applied to: %s", err.Key, err.Typ)
|
||||||
|
}
|
||||||
|
|
||||||
type FuncTypeError struct {
|
type FuncTypeError struct {
|
||||||
|
Name string
|
||||||
|
V interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err FuncTypeError) Error() string { return err.Name + " cannot be applied to: " + typeof(err.V) }
|
||||||
|
|
||||||
|
type FuncTypeNameError struct {
|
||||||
Name string
|
Name string
|
||||||
Typ string
|
Typ string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (err FuncTypeError) Error() string { return err.Name + " cannot be applied to: " + err.Typ }
|
func (err FuncTypeNameError) Error() string {
|
||||||
|
return err.Name + " cannot be applied to: " + err.Typ
|
||||||
|
}
|
||||||
|
|
||||||
type ExpectedObjectError struct {
|
type ExpectedObjectError struct {
|
||||||
Typ string
|
Typ string
|
||||||
@ -70,3 +93,24 @@ type ArrayIndexTooLargeError struct {
|
|||||||
func (err *ArrayIndexTooLargeError) Error() string {
|
func (err *ArrayIndexTooLargeError) Error() string {
|
||||||
return fmt.Sprintf("array index too large: %v", err.V)
|
return fmt.Sprintf("array index too large: %v", err.V)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func typeof(v interface{}) string {
|
||||||
|
switch v := v.(type) {
|
||||||
|
case nil:
|
||||||
|
return "null"
|
||||||
|
case bool:
|
||||||
|
return "boolean"
|
||||||
|
case int, float64, *big.Int:
|
||||||
|
return "number"
|
||||||
|
case string:
|
||||||
|
return "string"
|
||||||
|
case []interface{}:
|
||||||
|
return "array"
|
||||||
|
case map[string]interface{}:
|
||||||
|
return "object"
|
||||||
|
case gojq.JQValue:
|
||||||
|
return fmt.Sprintf("JQValue(%s)", v.JQValueType())
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("invalid value: %v", v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
12
internal/gojqextra/math.go
Normal file
12
internal/gojqextra/math.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// from gojq
|
||||||
|
// The MIT License (MIT)
|
||||||
|
// Copyright (c) 2019-2021 itchyny
|
||||||
|
|
||||||
|
package gojqextra
|
||||||
|
|
||||||
|
import "math/bits"
|
||||||
|
|
||||||
|
const (
|
||||||
|
maxInt = 1<<(bits.UintSize-1) - 1 // math.MaxInt64 or math.MaxInt32
|
||||||
|
minInt = -maxInt - 1 // math.MinInt64 or math.MinInt32
|
||||||
|
)
|
127
internal/gojqextra/totype.go
Normal file
127
internal/gojqextra/totype.go
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
// Some of these functions are based on gojq func.go functions
|
||||||
|
// TODO: maybe should be exported from gojq fq branch instead?
|
||||||
|
// The MIT License (MIT)
|
||||||
|
// Copyright (c) 2019-2021 itchyny
|
||||||
|
|
||||||
|
package gojqextra
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"math/big"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/wader/gojq"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ToString(x interface{}) (string, bool) {
|
||||||
|
switch x := x.(type) {
|
||||||
|
case string:
|
||||||
|
return x, true
|
||||||
|
case gojq.JQValue:
|
||||||
|
return ToString(x.JQValueToGoJQ())
|
||||||
|
default:
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToObject(x interface{}) (map[string]interface{}, bool) {
|
||||||
|
switch x := x.(type) {
|
||||||
|
case map[string]interface{}:
|
||||||
|
return x, true
|
||||||
|
case gojq.JQValue:
|
||||||
|
return ToObject(x.JQValueToGoJQ())
|
||||||
|
default:
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToArray(x interface{}) ([]interface{}, bool) {
|
||||||
|
switch x := x.(type) {
|
||||||
|
case []interface{}:
|
||||||
|
return x, true
|
||||||
|
case gojq.JQValue:
|
||||||
|
return ToArray(x.JQValueToGoJQ())
|
||||||
|
default:
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToBoolean(x interface{}) (bool, bool) {
|
||||||
|
switch x := x.(type) {
|
||||||
|
case bool:
|
||||||
|
return x, true
|
||||||
|
case gojq.JQValue:
|
||||||
|
return ToBoolean(x.JQValueToGoJQ())
|
||||||
|
default:
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsNull(x interface{}) bool {
|
||||||
|
switch x := x.(type) {
|
||||||
|
case nil:
|
||||||
|
return true
|
||||||
|
case gojq.JQValue:
|
||||||
|
return IsNull(x.JQValueToGoJQ())
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToInt(x interface{}) (int, bool) {
|
||||||
|
switch x := x.(type) {
|
||||||
|
case int:
|
||||||
|
return x, true
|
||||||
|
case float64:
|
||||||
|
return floatToInt(x), true
|
||||||
|
case *big.Int:
|
||||||
|
if x.IsInt64() {
|
||||||
|
if i := x.Int64(); minInt <= i && i <= maxInt {
|
||||||
|
return int(i), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if x.Sign() > 0 {
|
||||||
|
return maxInt, true
|
||||||
|
}
|
||||||
|
return minInt, true
|
||||||
|
case gojq.JQValue:
|
||||||
|
return ToInt(x.JQValueToGoJQ())
|
||||||
|
default:
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func floatToInt(x float64) int {
|
||||||
|
if minInt <= x && x <= maxInt {
|
||||||
|
return int(x)
|
||||||
|
}
|
||||||
|
if x > 0 {
|
||||||
|
return maxInt
|
||||||
|
}
|
||||||
|
return minInt
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToFloat(x interface{}) (float64, bool) {
|
||||||
|
switch x := x.(type) {
|
||||||
|
case int:
|
||||||
|
return float64(x), true
|
||||||
|
case float64:
|
||||||
|
return x, true
|
||||||
|
case *big.Int:
|
||||||
|
return bigToFloat(x), true
|
||||||
|
case gojq.JQValue:
|
||||||
|
return ToFloat(x.JQValueToGoJQ())
|
||||||
|
default:
|
||||||
|
return 0.0, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func bigToFloat(x *big.Int) float64 {
|
||||||
|
if x.IsInt64() {
|
||||||
|
return float64(x.Int64())
|
||||||
|
}
|
||||||
|
if f, err := strconv.ParseFloat(x.String(), 64); err == nil {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
return math.Inf(x.Sign())
|
||||||
|
}
|
@ -23,15 +23,6 @@ func expectedArrayOrObject(key interface{}, typ string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type NonUpdatableTypeError struct {
|
|
||||||
Typ string
|
|
||||||
Key string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (err NonUpdatableTypeError) Error() string {
|
|
||||||
return fmt.Sprintf("update key %v cannot be applied to: %s", err.Key, err.Typ)
|
|
||||||
}
|
|
||||||
|
|
||||||
// array
|
// array
|
||||||
|
|
||||||
var _ gojq.JQValue = Array{}
|
var _ gojq.JQValue = Array{}
|
||||||
@ -86,7 +77,8 @@ func (v Array) JQValueUpdate(key interface{}, u interface{}, delpath bool) inter
|
|||||||
if delpath {
|
if delpath {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return FuncTypeError{Name: "setpath", Typ: "number"}
|
// TODO: wrong error?
|
||||||
|
return FuncTypeNameError{Name: "setpath", Typ: "number"}
|
||||||
} else if intKey < 0 {
|
} else if intKey < 0 {
|
||||||
intKey += len(v)
|
intKey += len(v)
|
||||||
}
|
}
|
||||||
@ -111,10 +103,10 @@ func (v Array) JQValueHas(key interface{}) interface{} {
|
|||||||
}
|
}
|
||||||
func (v Array) JQValueType() string { return "array" }
|
func (v Array) JQValueType() string { return "array" }
|
||||||
func (v Array) JQValueToNumber() interface{} {
|
func (v Array) JQValueToNumber() interface{} {
|
||||||
return FuncTypeError{Name: "tonumber", Typ: "array"}
|
return FuncTypeNameError{Name: "tonumber", Typ: "array"}
|
||||||
}
|
}
|
||||||
func (v Array) JQValueToString() interface{} {
|
func (v Array) JQValueToString() interface{} {
|
||||||
return FuncTypeError{Name: "tostring", Typ: "array"}
|
return FuncTypeNameError{Name: "tostring", Typ: "array"}
|
||||||
}
|
}
|
||||||
func (v Array) JQValueToGoJQ() interface{} { return []interface{}(v) }
|
func (v Array) JQValueToGoJQ() interface{} { return []interface{}(v) }
|
||||||
|
|
||||||
@ -177,10 +169,10 @@ func (v Object) JQValueHas(key interface{}) interface{} {
|
|||||||
}
|
}
|
||||||
func (v Object) JQValueType() string { return "object" }
|
func (v Object) JQValueType() string { return "object" }
|
||||||
func (v Object) JQValueToNumber() interface{} {
|
func (v Object) JQValueToNumber() interface{} {
|
||||||
return FuncTypeError{Name: "tonumber", Typ: "object"}
|
return FuncTypeNameError{Name: "tonumber", Typ: "object"}
|
||||||
}
|
}
|
||||||
func (v Object) JQValueToString() interface{} {
|
func (v Object) JQValueToString() interface{} {
|
||||||
return FuncTypeError{Name: "tostring", Typ: "object"}
|
return FuncTypeNameError{Name: "tostring", Typ: "object"}
|
||||||
}
|
}
|
||||||
func (v Object) JQValueToGoJQ() interface{} { return map[string]interface{}(v) }
|
func (v Object) JQValueToGoJQ() interface{} { return map[string]interface{}(v) }
|
||||||
|
|
||||||
@ -203,9 +195,9 @@ func (v Number) JQValueUpdate(key interface{}, u interface{}, delpath bool) inte
|
|||||||
return expectedArrayOrObject(key, "number")
|
return expectedArrayOrObject(key, "number")
|
||||||
}
|
}
|
||||||
func (v Number) JQValueEach() interface{} { return IteratorError{Typ: "number"} }
|
func (v Number) JQValueEach() interface{} { return IteratorError{Typ: "number"} }
|
||||||
func (v Number) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: "number"} }
|
func (v Number) JQValueKeys() interface{} { return FuncTypeNameError{Name: "keys", Typ: "number"} }
|
||||||
func (v Number) JQValueHas(key interface{}) interface{} {
|
func (v Number) JQValueHas(key interface{}) interface{} {
|
||||||
return FuncTypeError{Name: "has", Typ: "number"}
|
return FuncTypeNameError{Name: "has", Typ: "number"}
|
||||||
}
|
}
|
||||||
func (v Number) JQValueType() string { return "number" }
|
func (v Number) JQValueType() string { return "number" }
|
||||||
func (v Number) JQValueToNumber() interface{} { return v.V }
|
func (v Number) JQValueToNumber() interface{} { return v.V }
|
||||||
@ -240,9 +232,9 @@ func (v String) JQValueUpdate(key interface{}, u interface{}, delpath bool) inte
|
|||||||
return expectedArrayOrObject(key, "string")
|
return expectedArrayOrObject(key, "string")
|
||||||
}
|
}
|
||||||
func (v String) JQValueEach() interface{} { return IteratorError{Typ: "string"} }
|
func (v String) JQValueEach() interface{} { return IteratorError{Typ: "string"} }
|
||||||
func (v String) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: "string"} }
|
func (v String) JQValueKeys() interface{} { return FuncTypeNameError{Name: "keys", Typ: "string"} }
|
||||||
func (v String) JQValueHas(key interface{}) interface{} {
|
func (v String) JQValueHas(key interface{}) interface{} {
|
||||||
return FuncTypeError{Name: "has", Typ: "string"}
|
return FuncTypeNameError{Name: "has", Typ: "string"}
|
||||||
}
|
}
|
||||||
func (v String) JQValueType() string { return "string" }
|
func (v String) JQValueType() string { return "string" }
|
||||||
func (v String) JQValueToNumber() interface{} { return gojq.NormalizeNumbers(string(v)) }
|
func (v String) JQValueToNumber() interface{} { return gojq.NormalizeNumbers(string(v)) }
|
||||||
@ -255,7 +247,9 @@ var _ gojq.JQValue = Boolean(true)
|
|||||||
|
|
||||||
type Boolean bool
|
type Boolean bool
|
||||||
|
|
||||||
func (v Boolean) JQValueLength() interface{} { return FuncTypeError{Name: "length", Typ: "boolean"} }
|
func (v Boolean) JQValueLength() interface{} {
|
||||||
|
return FuncTypeNameError{Name: "length", Typ: "boolean"}
|
||||||
|
}
|
||||||
func (v Boolean) JQValueSliceLen() interface{} { return ExpectedArrayError{Typ: "boolean"} }
|
func (v Boolean) JQValueSliceLen() interface{} { return ExpectedArrayError{Typ: "boolean"} }
|
||||||
func (v Boolean) JQValueIndex(index int) interface{} { return ExpectedArrayError{Typ: "boolean"} }
|
func (v Boolean) JQValueIndex(index int) interface{} { return ExpectedArrayError{Typ: "boolean"} }
|
||||||
func (v Boolean) JQValueSlice(start int, end int) interface{} {
|
func (v Boolean) JQValueSlice(start int, end int) interface{} {
|
||||||
@ -266,13 +260,13 @@ func (v Boolean) JQValueUpdate(key interface{}, u interface{}, delpath bool) int
|
|||||||
return expectedArrayOrObject(key, "boolean")
|
return expectedArrayOrObject(key, "boolean")
|
||||||
}
|
}
|
||||||
func (v Boolean) JQValueEach() interface{} { return IteratorError{Typ: "boolean"} }
|
func (v Boolean) JQValueEach() interface{} { return IteratorError{Typ: "boolean"} }
|
||||||
func (v Boolean) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: "boolean"} }
|
func (v Boolean) JQValueKeys() interface{} { return FuncTypeNameError{Name: "keys", Typ: "boolean"} }
|
||||||
func (v Boolean) JQValueHas(key interface{}) interface{} {
|
func (v Boolean) JQValueHas(key interface{}) interface{} {
|
||||||
return FuncTypeError{Name: "has", Typ: "boolean"}
|
return FuncTypeNameError{Name: "has", Typ: "boolean"}
|
||||||
}
|
}
|
||||||
func (v Boolean) JQValueType() string { return "boolean" }
|
func (v Boolean) JQValueType() string { return "boolean" }
|
||||||
func (v Boolean) JQValueToNumber() interface{} {
|
func (v Boolean) JQValueToNumber() interface{} {
|
||||||
return FuncTypeError{Name: "tonumber", Typ: "boolean"}
|
return FuncTypeNameError{Name: "tonumber", Typ: "boolean"}
|
||||||
}
|
}
|
||||||
func (v Boolean) JQValueToString() interface{} {
|
func (v Boolean) JQValueToString() interface{} {
|
||||||
if v {
|
if v {
|
||||||
@ -297,10 +291,12 @@ func (v Null) JQValueUpdate(key interface{}, u interface{}, delpath bool) interf
|
|||||||
return expectedArrayOrObject(key, "null")
|
return expectedArrayOrObject(key, "null")
|
||||||
}
|
}
|
||||||
func (v Null) JQValueEach() interface{} { return IteratorError{Typ: "null"} }
|
func (v Null) JQValueEach() interface{} { return IteratorError{Typ: "null"} }
|
||||||
func (v Null) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: "null"} }
|
func (v Null) JQValueKeys() interface{} { return FuncTypeNameError{Name: "keys", Typ: "null"} }
|
||||||
func (v Null) JQValueHas(key interface{}) interface{} { return FuncTypeError{Name: "has", Typ: "null"} }
|
func (v Null) JQValueHas(key interface{}) interface{} {
|
||||||
|
return FuncTypeNameError{Name: "has", Typ: "null"}
|
||||||
|
}
|
||||||
func (v Null) JQValueType() string { return "null" }
|
func (v Null) JQValueType() string { return "null" }
|
||||||
func (v Null) JQValueToNumber() interface{} { return FuncTypeError{Name: "tonumber", Typ: "null"} }
|
func (v Null) JQValueToNumber() interface{} { return FuncTypeNameError{Name: "tonumber", Typ: "null"} }
|
||||||
func (v Null) JQValueToString() interface{} { return "null" }
|
func (v Null) JQValueToString() interface{} { return "null" }
|
||||||
func (v Null) JQValueToGoJQ() interface{} { return nil }
|
func (v Null) JQValueToGoJQ() interface{} { return nil }
|
||||||
|
|
||||||
@ -325,11 +321,11 @@ func (v Base) JQValueUpdate(key interface{}, u interface{}, delpath bool) interf
|
|||||||
return expectedArrayOrObject(key, v.Typ)
|
return expectedArrayOrObject(key, v.Typ)
|
||||||
}
|
}
|
||||||
func (v Base) JQValueEach() interface{} { return IteratorError{Typ: v.Typ} }
|
func (v Base) JQValueEach() interface{} { return IteratorError{Typ: v.Typ} }
|
||||||
func (v Base) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: v.Typ} }
|
func (v Base) JQValueKeys() interface{} { return FuncTypeNameError{Name: "keys", Typ: v.Typ} }
|
||||||
func (v Base) JQValueHas(key interface{}) interface{} {
|
func (v Base) JQValueHas(key interface{}) interface{} {
|
||||||
return HasKeyTypeError{L: "array", R: fmt.Sprintf("%v", key)}
|
return HasKeyTypeError{L: "array", R: fmt.Sprintf("%v", key)}
|
||||||
}
|
}
|
||||||
func (v Base) JQValueType() string { return v.Typ }
|
func (v Base) JQValueType() string { return v.Typ }
|
||||||
func (v Base) JQValueToNumber() interface{} { return FuncTypeError{Name: "tonumber", Typ: v.Typ} }
|
func (v Base) JQValueToNumber() interface{} { return FuncTypeNameError{Name: "tonumber", Typ: v.Typ} }
|
||||||
func (v Base) JQValueToString() interface{} { return FuncTypeError{Name: "tostring", Typ: v.Typ} }
|
func (v Base) JQValueToString() interface{} { return FuncTypeNameError{Name: "tostring", Typ: v.Typ} }
|
||||||
func (v Base) JQValueToGoJQ() interface{} { return nil }
|
func (v Base) JQValueToGoJQ() interface{} { return nil }
|
@ -116,7 +116,7 @@ func (bv BufferView) JQValueType() string {
|
|||||||
return "buffer"
|
return "buffer"
|
||||||
}
|
}
|
||||||
func (bv BufferView) JQValueKeys() interface{} {
|
func (bv BufferView) JQValueKeys() interface{} {
|
||||||
return gojqextra.FuncTypeError{Name: "keys", Typ: "buffer"}
|
return gojqextra.FuncTypeNameError{Name: "keys", Typ: "buffer"}
|
||||||
}
|
}
|
||||||
func (bv BufferView) JQValueHas(key interface{}) interface{} {
|
func (bv BufferView) JQValueHas(key interface{}) interface{} {
|
||||||
return gojqextra.HasKeyTypeError{L: "buffer", R: fmt.Sprintf("%v", key)}
|
return gojqextra.HasKeyTypeError{L: "buffer", R: fmt.Sprintf("%v", key)}
|
||||||
|
@ -60,8 +60,8 @@ func (i *Interp) makeFunctions() []Function {
|
|||||||
{[]string{"_display"}, 1, 1, nil, i._display},
|
{[]string{"_display"}, 1, 1, nil, i._display},
|
||||||
{[]string{"_hexdump"}, 1, 1, nil, i._hexdump},
|
{[]string{"_hexdump"}, 1, 1, nil, i._hexdump},
|
||||||
|
|
||||||
{[]string{"tobytes"}, 0, 0, i.toBytes, nil},
|
{[]string{"_tobitsrange"}, 0, 2, i._toBitsRange, nil},
|
||||||
{[]string{"tobits"}, 0, 0, i.toBits, nil},
|
|
||||||
{[]string{"tovalue"}, 0, 1, i.toValue, nil},
|
{[]string{"tovalue"}, 0, 1, i.toValue, nil},
|
||||||
|
|
||||||
{[]string{"hex"}, 0, 0, makeStringBitBufTransformFn(
|
{[]string{"hex"}, 0, 0, makeStringBitBufTransformFn(
|
||||||
@ -700,20 +700,44 @@ func (i *Interp) _display(c interface{}, a []interface{}) gojq.Iter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) toBytes(c interface{}, a []interface{}) interface{} {
|
// note is used to implement tobytes*/0 also
|
||||||
bb, err := toBuffer(c)
|
func (i *Interp) _toBitsRange(c interface{}, a []interface{}) interface{} {
|
||||||
if err != nil {
|
var unit int
|
||||||
return err
|
var r bool
|
||||||
}
|
var ok bool
|
||||||
return bufferViewFromBuffer(bb, 8)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *Interp) toBits(c interface{}, a []interface{}) interface{} {
|
if len(a) >= 1 {
|
||||||
bb, err := toBuffer(c)
|
unit, ok = gojqextra.ToInt(a[0])
|
||||||
|
if !ok {
|
||||||
|
return gojqextra.FuncTypeError{Name: "_tobitsrange", V: a[0]}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unit = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(a) >= 2 {
|
||||||
|
r, ok = gojqextra.ToBoolean(a[1])
|
||||||
|
if !ok {
|
||||||
|
return gojqextra.FuncTypeError{Name: "_tobitsrange", V: a[1]}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: unit > 8?
|
||||||
|
|
||||||
|
bv, err := toBufferView(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return bufferViewFromBuffer(bb, 1)
|
bv.unit = unit
|
||||||
|
|
||||||
|
if !r {
|
||||||
|
bb, _ := bv.toBuffer()
|
||||||
|
return bufferViewFromBuffer(bb, unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
return bv
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) toValue(c interface{}, a []interface{}) interface{} {
|
func (i *Interp) toValue(c interface{}, a []interface{}) interface{} {
|
||||||
@ -838,7 +862,7 @@ func (i *Interp) find(c interface{}, a []interface{}) gojq.Iter {
|
|||||||
if len(a) > 1 {
|
if len(a) > 1 {
|
||||||
flags, ok = a[1].(string)
|
flags, ok = a[1].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return gojq.NewIter(gojqextra.FuncTypeError{Name: "find", Typ: "string"})
|
return gojq.NewIter(gojqextra.FuncTypeNameError{Name: "find", Typ: "string"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,11 @@ def parents:
|
|||||||
end
|
end
|
||||||
);
|
);
|
||||||
|
|
||||||
|
def tobitsrange: _tobitsrange;
|
||||||
|
def tobytesrange: _tobitsrange(8);
|
||||||
|
def tobits: _tobitsrange(1; false);
|
||||||
|
def tobytes: _tobitsrange(8; false);
|
||||||
|
|
||||||
def formats:
|
def formats:
|
||||||
_registry.formats;
|
_registry.formats;
|
||||||
|
|
||||||
|
182
pkg/interp/testdata/buffer.fqtest
vendored
182
pkg/interp/testdata/buffer.fqtest
vendored
@ -55,3 +55,185 @@ error: buffer byte list must be bytes (0-255) got -1
|
|||||||
mp3> [256] | tobytes
|
mp3> [256] | tobytes
|
||||||
error: buffer byte list must be bytes (0-255) got 256
|
error: buffer byte list must be bytes (0-255) got 256
|
||||||
mp3> ^D
|
mp3> ^D
|
||||||
|
$ fq -d mp3 -i . /test.mp3
|
||||||
|
mp3> .frames[1] | tobits | ., .start, .stop, .size, .[4:17], (tobits, tobytes, tobitsrange, tobytesrange | ., .start, .stop, .size, .[4:17])
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
1664
|
||||||
|
1664
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0|ff fb 50 |..P |.: none 0x0.4-0x2 (1.5)
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
1664
|
||||||
|
1664
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0|ff fb 50 |..P |.: none 0x0.4-0x2 (1.5)
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
208
|
||||||
|
208
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00| 00 00 0a 2c 43 2e 55 94 80 01 80 93| ...,C.U.....|.: none 0x4-0x10.7 (13)
|
||||||
|
0x10|6b |k |
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
1664
|
||||||
|
1664
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0|ff fb 50 |..P |.: none 0x0.4-0x2 (1.5)
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
208
|
||||||
|
208
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00| 00 00 0a 2c 43 2e 55 94 80 01 80 93| ...,C.U.....|.: none 0x4-0x10.7 (13)
|
||||||
|
0x10|6b |k |
|
||||||
|
mp3> .frames[1] | tobytes | ., .start, .stop, .size, .[4:17], (tobits, tobytes, tobitsrange, tobytesrange | ., .start, .stop, .size, .[4:17])
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
208
|
||||||
|
208
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00| 00 00 0a 2c 43 2e 55 94 80 01 80 93| ...,C.U.....|.: none 0x4-0x10.7 (13)
|
||||||
|
0x10|6b |k |
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
1664
|
||||||
|
1664
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0|ff fb 50 |..P |.: none 0x0.4-0x2 (1.5)
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
208
|
||||||
|
208
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00| 00 00 0a 2c 43 2e 55 94 80 01 80 93| ...,C.U.....|.: none 0x4-0x10.7 (13)
|
||||||
|
0x10|6b |k |
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
1664
|
||||||
|
1664
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0|ff fb 50 |..P |.: none 0x0.4-0x2 (1.5)
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
208
|
||||||
|
208
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00| 00 00 0a 2c 43 2e 55 94 80 01 80 93| ...,C.U.....|.: none 0x4-0x10.7 (13)
|
||||||
|
0x10|6b |k |
|
||||||
|
mp3> .frames[1] | tobitsrange | ., .start, .stop, .size, .[4:17], (tobits, tobytes, tobitsrange, tobytesrange | ., .start, .stop, .size, .[4:17])
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0e0| ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80| ..P....,C.U..|.: none 0xe3-0x1b2.7 (208)
|
||||||
|
0x0f0|01 80 93 6b 27 30 80 00 07 aa c3 8e 33 85 d3 64|...k'0......3..d|
|
||||||
|
* |until 0x1b2.7 (208) | |
|
||||||
|
1816
|
||||||
|
3480
|
||||||
|
1664
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0xe0| ff fb 50 | ..P |.: none 0xe3.4-0xe5 (1.5)
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
1664
|
||||||
|
1664
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0|ff fb 50 |..P |.: none 0x0.4-0x2 (1.5)
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
208
|
||||||
|
208
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00| 00 00 0a 2c 43 2e 55 94 80 01 80 93| ...,C.U.....|.: none 0x4-0x10.7 (13)
|
||||||
|
0x10|6b |k |
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0e0| ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80| ..P....,C.U..|.: none 0xe3-0x1b2.7 (208)
|
||||||
|
0x0f0|01 80 93 6b 27 30 80 00 07 aa c3 8e 33 85 d3 64|...k'0......3..d|
|
||||||
|
* |until 0x1b2.7 (208) | |
|
||||||
|
1816
|
||||||
|
3480
|
||||||
|
1664
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0xe0| ff fb 50 | ..P |.: none 0xe3.4-0xe5 (1.5)
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0e0| ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80| ..P....,C.U..|.: none 0xe3-0x1b2.7 (208)
|
||||||
|
0x0f0|01 80 93 6b 27 30 80 00 07 aa c3 8e 33 85 d3 64|...k'0......3..d|
|
||||||
|
* |until 0x1b2.7 (208) | |
|
||||||
|
227
|
||||||
|
435
|
||||||
|
208
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0xe0| 00 00 0a 2c 43 2e 55 94 80| ...,C.U..|.: none 0xe7-0xf3.7 (13)
|
||||||
|
0xf0|01 80 93 6b |...k |
|
||||||
|
mp3> .frames[1] | tobytesrange | ., .start, .stop, .size, .[4:17], (tobits, tobytes, tobitsrange, tobytesrange | ., .start, .stop, .size, .[4:17])
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0e0| ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80| ..P....,C.U..|.: none 0xe3-0x1b2.7 (208)
|
||||||
|
0x0f0|01 80 93 6b 27 30 80 00 07 aa c3 8e 33 85 d3 64|...k'0......3..d|
|
||||||
|
* |until 0x1b2.7 (208) | |
|
||||||
|
227
|
||||||
|
435
|
||||||
|
208
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0xe0| 00 00 0a 2c 43 2e 55 94 80| ...,C.U..|.: none 0xe7-0xf3.7 (13)
|
||||||
|
0xf0|01 80 93 6b |...k |
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
1664
|
||||||
|
1664
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0|ff fb 50 |..P |.: none 0x0.4-0x2 (1.5)
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00|ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80 01 80 93|..P....,C.U.....|.: none 0x0-0xcf.7 (208)
|
||||||
|
* |until 0xcf.7 (end) (208) | |
|
||||||
|
0
|
||||||
|
208
|
||||||
|
208
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x00| 00 00 0a 2c 43 2e 55 94 80 01 80 93| ...,C.U.....|.: none 0x4-0x10.7 (13)
|
||||||
|
0x10|6b |k |
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0e0| ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80| ..P....,C.U..|.: none 0xe3-0x1b2.7 (208)
|
||||||
|
0x0f0|01 80 93 6b 27 30 80 00 07 aa c3 8e 33 85 d3 64|...k'0......3..d|
|
||||||
|
* |until 0x1b2.7 (208) | |
|
||||||
|
1816
|
||||||
|
3480
|
||||||
|
1664
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0xe0| ff fb 50 | ..P |.: none 0xe3.4-0xe5 (1.5)
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0x0e0| ff fb 50 c4 00 00 0a 2c 43 2e 55 94 80| ..P....,C.U..|.: none 0xe3-0x1b2.7 (208)
|
||||||
|
0x0f0|01 80 93 6b 27 30 80 00 07 aa c3 8e 33 85 d3 64|...k'0......3..d|
|
||||||
|
* |until 0x1b2.7 (208) | |
|
||||||
|
227
|
||||||
|
435
|
||||||
|
208
|
||||||
|
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
|
||||||
|
0xe0| 00 00 0a 2c 43 2e 55 94 80| ...,C.U..|.: none 0xe7-0xf3.7 (13)
|
||||||
|
0xf0|01 80 93 6b |...k |
|
||||||
|
mp3> ^D
|
||||||
|
Loading…
Reference in New Issue
Block a user