1
1
mirror of https://github.com/wader/fq.git synced 2024-11-23 18:56:52 +03:00

interp: Make has/1 work for _ext keys

This commit is contained in:
Mattias Wadman 2021-09-27 23:06:46 +02:00
parent 567bc4b342
commit f1fcbe5dfb
2 changed files with 171 additions and 20 deletions

View File

@ -28,3 +28,128 @@ $ fq -d mp3 '.headers[0][]' /test.mp3
0x20|30 30 00 |00. | 0x20|30 30 00 |00. |
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| |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) 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

View File

@ -38,12 +38,22 @@ type valueIf interface {
ToBuffer 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, "_") { if strings.HasPrefix(name, "_") {
return a(name) return a(name)
} }
return b(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 { func makeDecodeValue(dv *decode.Value) valueIf {
switch vv := dv.V.(type) { switch vv := dv.V.(type) {
@ -211,7 +221,10 @@ type decodeValue struct {
} }
func (v decodeValue) JQValueKey(name string) interface{} { 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) // string (*bitio.Buffer)
@ -233,9 +246,11 @@ func NewStringBufferValueObject(dv *decode.Value, bb *bitio.Buffer) BufferDecode
} }
func (v BufferDecodeValue) JQValueKey(name string) interface{} { 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{} { func (v BufferDecodeValue) JQValueLength() interface{} {
return int(v.Buffer.Len()) / 8 return int(v.Buffer.Len()) / 8
} }
@ -302,7 +317,7 @@ func NewArrayDecodeValue(dv *decode.Value, a decode.Array) ArrayDecodeValue {
} }
func (v ArrayDecodeValue) JQValueKey(name string) interface{} { 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) JQValueSliceLen() interface{} { return len(v.Array) }
func (v ArrayDecodeValue) JQValueLength() interface{} { return len(v.Array) } func (v ArrayDecodeValue) JQValueLength() interface{} { return len(v.Array) }
@ -338,11 +353,16 @@ func (v ArrayDecodeValue) JQValueKeys() interface{} {
return vs return vs
} }
func (v ArrayDecodeValue) JQValueHas(key interface{}) interface{} { func (v ArrayDecodeValue) JQValueHas(key interface{}) interface{} {
intKey, ok := key.(int) return valueHas(
if !ok { key,
return gojqextra.HasKeyTypeError{L: "array", R: fmt.Sprintf("%v", key)} v.decodeValueBase.JQValueKey,
} func(key interface{}) interface{} {
return intKey >= 0 && intKey < len(v.Array) 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{} { func (v ArrayDecodeValue) JQValueToGoJQ() interface{} {
vs := make([]interface{}, len(v.Array)) vs := make([]interface{}, len(v.Array))
@ -402,16 +422,22 @@ func (v StructDecodeValue) JQValueKeys() interface{} {
return vs return vs
} }
func (v StructDecodeValue) JQValueHas(key interface{}) interface{} { func (v StructDecodeValue) JQValueHas(key interface{}) interface{} {
stringKey, ok := key.(string) return valueHas(
if !ok { key,
return gojqextra.HasKeyTypeError{L: "object", R: fmt.Sprintf("%v", key)} v.decodeValueBase.JQValueKey,
} func(key interface{}) interface{} {
for _, f := range v.Struct { stringKey, ok := key.(string)
if f.Name == stringKey { if !ok {
return true return gojqextra.HasKeyTypeError{L: "object", R: fmt.Sprintf("%v", key)}
} }
} for _, f := range v.Struct {
return false if f.Name == stringKey {
return true
}
}
return false
},
)
} }
func (v StructDecodeValue) JQValueToGoJQ() interface{} { func (v StructDecodeValue) JQValueToGoJQ() interface{} {
vm := make(map[string]interface{}, len(v.Struct)) vm := make(map[string]interface{}, len(v.Struct))