// starts JQ with a value, and visits each result; the value must be freeJv'd by the visitor. func processJq(jq *C.jq_state, input C.jv, visit func(val C.jv)) error { var jv C.jv C.jq_start(jq, input, 0) for { jv = C.jq_next(jq) if !isValid(jv) { break } visit(jv) } defer freeJv(jv) return jvError(jv) }
// Process a single input and send the results on `out` func (jq *Jq) _Execute(jv *Jv, out chan<- *Jv, err chan<- error) { flags := C.int(0) C.jq_start(jq._state, jv.jv, flags) result := &Jv{C.jq_next(jq._state)} for result.IsValid() { out <- result result = &Jv{C.jq_next(jq._state)} } msg, ok := result.GetInvalidMessageAsString() if ok { // Uncaught jq exception // TODO: get file:line position in input somehow. err <- errors.New(msg) } }
func (j *jqExecutor) execute(input ...string) []string { jsons := strings.Join(input, "") parser := C.jv_parser_new(0) defer C.jv_parser_free(parser) // Make a simple input then convert to CString. cjsons := C.CString(jsons) defer C.free(unsafe.Pointer(cjsons)) C.jv_parser_set_buf(parser, cjsons, C.int(len(jsons)), 0) var response []string // Check if v is valid. for v := C.jv_parser_next(parser); C.jv_is_valid(v) == 1; v = C.jv_parser_next(parser) { C.jq_start(j.state, v, 0) // Check if res is valid. for res := C.jq_next(j.state); C.jv_is_valid(res) == 1; res = C.jq_next(j.state) { response = append(response, toString(res)) } } return response }
func (jq *JQ) start(jv C.jv) { C.jq_start(jq.state, jv, 0) }