Skip to content

Commit

Permalink
interp: Make has/1 work for _ext keys
Browse files Browse the repository at this point in the history
  • Loading branch information
wader committed Sep 27, 2021
1 parent 567bc4b commit f1fcbe5
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 20 deletions.
125 changes: 125 additions & 0 deletions pkg/interp/testdata/value.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,128 @@ $ fq -d mp3 '.headers[0][]' /test.mp3
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: Correct (none) (zero padding)
# TODO: proper buffer_root test
$ fq -d mp3 -i . /test.mp3
mp3> . | (root, buffer_root, format_root, parent | ._path | path_to_expr), [parents | ._path | path_to_expr]
"."
"."
"."
"."
[]
mp3> .frames[0].side_info.granules[1] | (root, buffer_root, format_root, parent | ._path | path_to_expr), [parents | ._path | path_to_expr]
"."
"."
".frames[0]"
".frames[0].side_info.granules"
[
".frames[0].side_info.granules",
".frames[0].side_info",
".frames[0]",
".frames",
"."
]
mp3> 123 | root
error: expected a decode value but got: number (123)
mp3> 123 | buffer_root
error: expected a decode value but got: number (123)
mp3> 123 | format_root
error: expected a decode value but got: number (123)
mp3> 123 | parent
error: expected a decode value but got: number (123)
mp3> 123 | parents
error: expected a decode value but got: number (123)
mp3> ^D
$ fq -d mp3 -i . /test.mp3
mp3> has("_start")
true
mp3> has("_stop")
true
mp3> has("_len")
true
mp3> has("_name")
true
mp3> has("_root")
true
mp3> has("_buffer_root")
true
mp3> has("_format_root")
true
mp3> has("_parent")
true
mp3> has("_symbol")
true
mp3> has("_description")
true
mp3> has("_path")
true
mp3> has("_bits")
true
mp3> has("_bytes")
true
mp3> has("_error")
true
mp3> has("_unknown")
true
mp3> has("_format")
true
mp3> has("_abc")
error: expected a extkey but got: _abc
mp3> ^D
$ fq -d mp3 -i . /test.mp3
mp3> ._start
0
mp3> ._stop
5152
mp3> ._len
5152
mp3> ._name
""
mp3> ._root
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.: {} /test.mp3 (mp3)
0x000|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..| headers: [1]
* |until 0x2c.7 (45) | |
0x020| ff fb 40| ..@| frames: [3]
0x030|c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
* |until 0x283.7 (end) (599) | |
| | | footers: [0]
mp3> ._buffer_root
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.: {} /test.mp3 (mp3)
0x000|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..| headers: [1]
* |until 0x2c.7 (45) | |
0x020| ff fb 40| ..@| frames: [3]
0x030|c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
* |until 0x283.7 (end) (599) | |
| | | footers: [0]
mp3> ._format_root
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.: {} /test.mp3 (mp3)
0x000|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..| headers: [1]
* |until 0x2c.7 (45) | |
0x020| ff fb 40| ..@| frames: [3]
0x030|c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
* |until 0x283.7 (end) (599) | |
| | | footers: [0]
mp3> ._parent
null
mp3> ._symbol
""
mp3> ._description
"/test.mp3"
mp3> ._path
[]
mp3> ._bits
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x000|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..|.: none (5152 bits)
* |until 0x283.7 (end) (644) | |
mp3> ._bytes
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x000|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..|.: none (644 bytes)
* |until 0x283.7 (end) (644) | |
mp3> ._error
null
mp3> ._unknown
false
mp3> ._format
"mp3"
mp3> ._abc
error: expected a extkey but got: _abc
mp3> ^D
66 changes: 46 additions & 20 deletions pkg/interp/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,22 @@ type valueIf interface {
ToBuffer
}

func valueUnderscoreKey(name string, a, b func(name string) interface{}) interface{} {
func valueKey(name string, a, b func(name string) interface{}) interface{} {
if strings.HasPrefix(name, "_") {
return a(name)
}
return b(name)
}
func valueHas(key interface{}, a func(name string) interface{}, b func(key interface{}) interface{}) interface{} {
stringKey, ok := key.(string)
if ok && strings.HasPrefix(stringKey, "_") {
if err, ok := a(stringKey).(error); ok {
return err
}
return true
}
return b(key)
}

func makeDecodeValue(dv *decode.Value) valueIf {
switch vv := dv.V.(type) {
Expand Down Expand Up @@ -211,7 +221,10 @@ type decodeValue struct {
}

func (v decodeValue) JQValueKey(name string) interface{} {
return valueUnderscoreKey(name, v.decodeValueBase.JQValueKey, v.JQValue.JQValueKey)
return valueKey(name, v.decodeValueBase.JQValueKey, v.JQValue.JQValueKey)
}
func (v decodeValue) JQValueHas(key interface{}) interface{} {
return valueHas(key, v.decodeValueBase.JQValueKey, v.JQValue.JQValueHas)
}

// string (*bitio.Buffer)
Expand All @@ -233,9 +246,11 @@ func NewStringBufferValueObject(dv *decode.Value, bb *bitio.Buffer) BufferDecode
}

func (v BufferDecodeValue) JQValueKey(name string) interface{} {
return valueUnderscoreKey(name, v.decodeValueBase.JQValueKey, v.Base.JQValueKey)
return valueKey(name, v.decodeValueBase.JQValueKey, v.Base.JQValueKey)
}
func (v BufferDecodeValue) JQValueHas(key interface{}) interface{} {
return valueHas(key, v.decodeValueBase.JQValueKey, v.Base.JQValueHas)
}

func (v BufferDecodeValue) JQValueLength() interface{} {
return int(v.Buffer.Len()) / 8
}
Expand Down Expand Up @@ -302,7 +317,7 @@ func NewArrayDecodeValue(dv *decode.Value, a decode.Array) ArrayDecodeValue {
}

func (v ArrayDecodeValue) JQValueKey(name string) interface{} {
return valueUnderscoreKey(name, v.decodeValueBase.JQValueKey, v.Base.JQValueKey)
return valueKey(name, v.decodeValueBase.JQValueKey, v.Base.JQValueKey)
}
func (v ArrayDecodeValue) JQValueSliceLen() interface{} { return len(v.Array) }
func (v ArrayDecodeValue) JQValueLength() interface{} { return len(v.Array) }
Expand Down Expand Up @@ -338,11 +353,16 @@ func (v ArrayDecodeValue) JQValueKeys() interface{} {
return vs
}
func (v ArrayDecodeValue) JQValueHas(key interface{}) interface{} {
intKey, ok := key.(int)
if !ok {
return gojqextra.HasKeyTypeError{L: "array", R: fmt.Sprintf("%v", key)}
}
return intKey >= 0 && intKey < len(v.Array)
return valueHas(
key,
v.decodeValueBase.JQValueKey,
func(key interface{}) interface{} {
intKey, ok := key.(int)
if !ok {
return gojqextra.HasKeyTypeError{L: "array", R: fmt.Sprintf("%v", key)}
}
return intKey >= 0 && intKey < len(v.Array)
})
}
func (v ArrayDecodeValue) JQValueToGoJQ() interface{} {
vs := make([]interface{}, len(v.Array))
Expand Down Expand Up @@ -402,16 +422,22 @@ func (v StructDecodeValue) JQValueKeys() interface{} {
return vs
}
func (v StructDecodeValue) JQValueHas(key interface{}) interface{} {
stringKey, ok := key.(string)
if !ok {
return gojqextra.HasKeyTypeError{L: "object", R: fmt.Sprintf("%v", key)}
}
for _, f := range v.Struct {
if f.Name == stringKey {
return true
}
}
return false
return valueHas(
key,
v.decodeValueBase.JQValueKey,
func(key interface{}) interface{} {
stringKey, ok := key.(string)
if !ok {
return gojqextra.HasKeyTypeError{L: "object", R: fmt.Sprintf("%v", key)}
}
for _, f := range v.Struct {
if f.Name == stringKey {
return true
}
}
return false
},
)
}
func (v StructDecodeValue) JQValueToGoJQ() interface{} {
vm := make(map[string]interface{}, len(v.Struct))
Expand Down

0 comments on commit f1fcbe5

Please sign in to comment.