Skip to content

Commit

Permalink
gojqextra,decode: Add generic lazy JQValue
Browse files Browse the repository at this point in the history
  • Loading branch information
wader committed Nov 22, 2021
1 parent 5ad048d commit fdb811e
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 64 deletions.
2 changes: 1 addition & 1 deletion format/mpeg/mp3_frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ func frameDecode(d *decode.D, in interface{}) interface{} {
}

if sampleRate == 0 {
d.Errorf("zero sample rate")
d.Fatalf("zero sample rate")
}

calcFrameBytes := int64(144*bitRate/sampleRate + paddingBytes)
Expand Down
131 changes: 71 additions & 60 deletions internal/gojqextra/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,66 +241,6 @@ func (v String) JQValueToNumber() interface{} { return gojq.NormalizeNumbers(str
func (v String) JQValueToString() interface{} { return string(v) }
func (v String) JQValueToGoJQ() interface{} { return string(v) }

// lazy string

var _ gojq.JQValue = &LazyString{}

type LazyString struct {
Fn func() ([]rune, error)
called bool
rs []rune
}

func (v *LazyString) wrap(fn func(rs []rune) interface{}) interface{} {
if !v.called {
rs, err := v.Fn()
if err != nil {
return err
}
v.called = true
v.rs = rs
}
return fn(v.rs)
}

func (v *LazyString) JQValueLength() interface{} {
return v.wrap(func(rs []rune) interface{} { return len(rs) })
}
func (v *LazyString) JQValueSliceLen() interface{} {
return v.wrap(func(rs []rune) interface{} { return len(rs) })
}
func (v *LazyString) JQValueIndex(index int) interface{} {
// -1 outside after string, -2 outside before string
if index < 0 {
return ""
}
return v.wrap(func(rs []rune) interface{} { return fmt.Sprintf("%c", rs[index]) })
}
func (v *LazyString) JQValueSlice(start int, end int) interface{} {
return v.wrap(func(rs []rune) interface{} { return string(rs[start:end]) })

}
func (v *LazyString) JQValueKey(name string) interface{} { return ExpectedObjectError{Typ: "string"} }
func (v *LazyString) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
return expectedArrayOrObject(key, "string")
}
func (v *LazyString) JQValueEach() interface{} { return IteratorError{Typ: "string"} }
func (v *LazyString) JQValueKeys() interface{} { return FuncTypeNameError{Name: "keys", Typ: "string"} }
func (v *LazyString) JQValueHas(key interface{}) interface{} {
return FuncTypeNameError{Name: "has", Typ: "string"}
}
func (v *LazyString) JQValueType() string { return "string" }
func (v *LazyString) JQValueToNumber() interface{} {
return v.wrap(func(rs []rune) interface{} { return gojq.NormalizeNumbers(string(rs)) })

}
func (v *LazyString) JQValueToString() interface{} {
return v.wrap(func(rs []rune) interface{} { return string(rs) })
}
func (v *LazyString) JQValueToGoJQ() interface{} {
return v.wrap(func(rs []rune) interface{} { return string(rs) })
}

// boolean

var _ gojq.JQValue = Boolean(true)
Expand Down Expand Up @@ -389,3 +329,74 @@ func (v Base) JQValueType() string { return v.Typ }
func (v Base) JQValueToNumber() interface{} { return FuncTypeNameError{Name: "tonumber", Typ: v.Typ} }
func (v Base) JQValueToString() interface{} { return FuncTypeNameError{Name: "tostring", Typ: v.Typ} }
func (v Base) JQValueToGoJQ() interface{} { return nil }

// lazy

var _ gojq.JQValue = &Lazy{}

type Lazy struct {
Fn func() (gojq.JQValue, error)
called bool
err error
jv gojq.JQValue
}

func (v *Lazy) v() (gojq.JQValue, error) {
if !v.called {
v.jv, v.err = v.Fn()
v.called = true
}
return v.jv, v.err
}

func (v *Lazy) f(fn func(jv gojq.JQValue) interface{}) interface{} {
jv, err := v.v()
if err != nil {
return err
}
return fn(jv)
}

func (v *Lazy) JQValueLength() interface{} {
return v.f(func(jv gojq.JQValue) interface{} { return jv.JQValueLength() })
}
func (v *Lazy) JQValueSliceLen() interface{} {
return v.f(func(jv gojq.JQValue) interface{} { return jv.JQValueSliceLen() })
}
func (v *Lazy) JQValueIndex(index int) interface{} {
return v.f(func(jv gojq.JQValue) interface{} { return jv.JQValueIndex(index) })
}
func (v *Lazy) JQValueSlice(start int, end int) interface{} {
return v.f(func(jv gojq.JQValue) interface{} { return jv.JQValueSlice(start, end) })
}
func (v *Lazy) JQValueKey(name string) interface{} {
return v.f(func(jv gojq.JQValue) interface{} { return jv.JQValueKey(name) })
}
func (v *Lazy) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
return v.f(func(jv gojq.JQValue) interface{} { return jv.JQValueUpdate(key, u, delpath) })
}
func (v *Lazy) JQValueEach() interface{} {
return v.f(func(jv gojq.JQValue) interface{} { return jv.JQValueEach() })
}
func (v *Lazy) JQValueKeys() interface{} {
return v.f(func(jv gojq.JQValue) interface{} { return jv.JQValueKeys() })
}
func (v *Lazy) JQValueHas(key interface{}) interface{} {
return v.f(func(jv gojq.JQValue) interface{} { return jv.JQValueHas(key) })
}
func (v *Lazy) JQValueType() string {
jv, err := v.v()
if err != nil {
return "error"
}
return jv.JQValueType()
}
func (v *Lazy) JQValueToNumber() interface{} {
return v.f(func(jv gojq.JQValue) interface{} { return jv.JQValueToNumber() })
}
func (v *Lazy) JQValueToString() interface{} {
return v.f(func(jv gojq.JQValue) interface{} { return jv.JQValueToString() })
}
func (v *Lazy) JQValueToGoJQ() interface{} {
return v.f(func(jv gojq.JQValue) interface{} { return jv.JQValueToGoJQ() })
}
6 changes: 3 additions & 3 deletions pkg/interp/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,13 @@ func makeDecodeValue(dv *decode.Value) interface{} {
// create another buffer we don't have to read and create a string, ex:
// .unknown0 | tobytes[1:] | ...
return decodeValue{
JQValue: &gojqextra.LazyString{
Fn: func() ([]rune, error) {
JQValue: &gojqextra.Lazy{
Fn: func() (gojq.JQValue, error) {
buf := &bytes.Buffer{}
if _, err := io.Copy(buf, vv.Clone()); err != nil {
return nil, err
}
return []rune(buf.String()), nil
return gojqextra.String([]rune(buf.String())), nil
},
},
decodeValueBase: decodeValueBase{dv},
Expand Down

0 comments on commit fdb811e

Please sign in to comment.