func dumpArray(buf *bytes.Buffer, x C.jv) { ct := C.jv_array_length(C.jv_copy(x)) buf.WriteRune('[') defer buf.WriteRune(']') for i := C.int(0); i < ct; i++ { val := C.jv_array_get(C.jv_copy(x), i) if i > 0 { buf.WriteRune(',') } dumpValue(buf, val) C.jv_free(val) } }
func dumpObject(buf *bytes.Buffer, x C.jv) { keys := C.jv_keys(C.jv_copy(x)) defer C.jv_free(keys) ct := C.jv_array_length(C.jv_copy(keys)) buf.WriteRune('{') defer buf.WriteRune('}') for i := C.int(0); i < ct; i++ { key := C.jv_array_get(C.jv_copy(keys), i) if i > 0 { buf.WriteRune(',') } dumpString(buf, key) buf.WriteRune(':') val := C.jv_object_get(C.jv_copy(x), key) dumpValue(buf, val) C.jv_free(val) } }
func jvToGo(value C.jv) interface{} { switch C.jv_get_kind(value) { case C.JV_KIND_INVALID: return errors.New("invalid") case C.JV_KIND_NULL: return nil case C.JV_KIND_FALSE: return false case C.JV_KIND_TRUE: return true case C.JV_KIND_NUMBER: number := C.jv_number_value(value) if C.jv_is_integer(value) == 0 { return float64(number) } else { return int(number) } case C.JV_KIND_STRING: return C.GoString(C.jv_string_value(value)) case C.JV_KIND_ARRAY: length := C.jv_array_length(C.jv_copy(value)) arr := make([]interface{}, length) for i := range arr { arr[i] = jvToGo(C.jv_array_get(C.jv_copy(value), C.int(i))) } return arr case C.JV_KIND_OBJECT: result := make(map[string]interface{}) var k, v C.jv for jv_i := C.jv_object_iter(value); C.jv_object_iter_valid(value, jv_i) != 0; jv_i = C.jv_object_iter_next(value, jv_i) { k = C.jv_object_iter_key(value, jv_i) v = C.jv_object_iter_value(value, jv_i) result[C.GoString(C.jv_string_value(k))] = jvToGo(v) } return result default: return errors.New("unknown type") } }
// ArrayLength returns the number of elements in the array. // // Consumes the invocant func (jv *Jv) ArrayLength() int { return int(C.jv_array_length(jv.jv)) }