static int _bson_json_read_null (void *_ctx) { BASIC_YAJL_CB_PREAMBLE; BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL ("null"); bson_append_null (STACK_BSON_CHILD, key, (int)len); return 1; }
static int _bson_json_read_double (void *_ctx, /* IN */ double val) /* IN */ { BASIC_YAJL_CB_PREAMBLE; BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL ("double"); bson_append_double (STACK_BSON_CHILD, key, (int)len, val); return 1; }
static int _bson_json_read_boolean (void *_ctx, /* IN */ int val) /* IN */ { BASIC_YAJL_CB_PREAMBLE; if (bson->read_state == BSON_JSON_IN_BSON_TYPE && bson->bson_state == BSON_JSON_LF_UNDEFINED) { bson->bson_type_data.undefined.has_undefined = true; return 1; } BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL ("boolean"); bson_append_bool (STACK_BSON_CHILD, key, (int)len, val); return 1; }
static int _bson_json_read_string (void *_ctx, /* IN */ const unsigned char *val, /* IN */ size_t vlen) /* IN */ { bson_json_read_state_t rs; bson_json_read_bson_state_t bs; BASIC_YAJL_CB_PREAMBLE; rs = bson->read_state; bs = bson->bson_state; if (rs == BSON_JSON_REGULAR) { BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL ("string"); bson_append_utf8 (STACK_BSON_CHILD, key, (int)len, (const char *)val, (int)vlen); } else if (rs == BSON_JSON_IN_BSON_TYPE || rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES || rs == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) { const char *val_w_null; _bson_json_buf_set (&bson->bson_type_buf[2], val, vlen, true); val_w_null = (const char *)bson->bson_type_buf[2].buf; switch (bs) { case BSON_JSON_LF_REGEX: bson->bson_type_data.regex.has_regex = true; _bson_json_buf_set (&bson->bson_type_buf[0], val, vlen, true); break; case BSON_JSON_LF_OPTIONS: bson->bson_type_data.regex.has_options = true; _bson_json_buf_set (&bson->bson_type_buf[1], val, vlen, true); break; case BSON_JSON_LF_OID: if (vlen != 24) { goto BAD_PARSE; } bson->bson_type_data.oid.has_oid = true; bson_oid_init_from_string (&bson->bson_type_data.oid.oid, val_w_null); break; case BSON_JSON_LF_TYPE: bson->bson_type_data.binary.has_subtype = true; #ifdef _MSC_VER # define SSCANF sscanf_s #else # define SSCANF sscanf #endif if (SSCANF (val_w_null, "%02x", &bson->bson_type_data.binary.type) != 1) { goto BAD_PARSE; } #undef SSCANF break; case BSON_JSON_LF_BINARY: { /* TODO: error handling for pton */ int binary_len; bson->bson_type_data.binary.has_binary = true; binary_len = b64_pton (val_w_null, NULL, 0); _bson_json_buf_ensure (&bson->bson_type_buf[0], binary_len + 1); b64_pton ((char *)bson->bson_type_buf[2].buf, bson->bson_type_buf[0].buf, binary_len + 1); bson->bson_type_buf[0].len = binary_len; break; } case BSON_JSON_LF_REF: bson->bson_type_data.ref.has_ref = true; _bson_json_buf_set (&bson->bson_type_buf[0], val, vlen, true); break; case BSON_JSON_LF_ID: if (vlen != 24) { goto BAD_PARSE; } bson->bson_type_data.ref.has_id = true; bson_oid_init_from_string (&bson->bson_type_data.ref.id, val_w_null); break; case BSON_JSON_LF_INT64: { int64_t v64; char *endptr = NULL; errno = 0; v64 = bson_ascii_strtoll ((const char *)val, &endptr, 10); if (((v64 == INT64_MIN) || (v64 == INT64_MAX)) && (errno == ERANGE)) { goto BAD_PARSE; } if (endptr != ((const char *)val + vlen)) { goto BAD_PARSE; } if (bson->read_state == BSON_JSON_IN_BSON_TYPE) { bson->bson_type_data.v_int64.value = v64; } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) { bson->bson_type_data.date.has_date = true; bson->bson_type_data.date.date = v64; } else { goto BAD_PARSE; } } break; case BSON_JSON_LF_DATE: { int64_t v64; if (!_bson_iso8601_date_parse ((char *)val, (int)vlen, &v64)) { _bson_json_read_set_error (reader, "Could not parse \"%s\" as a date", val_w_null); return 0; } else { bson->bson_type_data.date.has_date = true; bson->bson_type_data.date.date = v64; } } break; case BSON_JSON_LF_TIMESTAMP_T: case BSON_JSON_LF_TIMESTAMP_I: case BSON_JSON_LF_UNDEFINED: case BSON_JSON_LF_MINKEY: case BSON_JSON_LF_MAXKEY: default: goto BAD_PARSE; } return 1; BAD_PARSE: _bson_json_read_set_error (reader, "Invalid input string %s, looking for %d", val_w_null, bs); return 0; } else { _bson_json_read_set_error (reader, "Invalid state to look for string %d", rs); return 0; } return 1; }
static int _bson_json_read_integer (void *_ctx, /* IN */ int64_t val) /* IN */ { bson_json_read_state_t rs; bson_json_read_bson_state_t bs; BASIC_YAJL_CB_PREAMBLE; rs = bson->read_state; bs = bson->bson_state; if (rs == BSON_JSON_REGULAR) { BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL ("integer"); if (val <= INT32_MAX) { bson_append_int32 (STACK_BSON_CHILD, key, (int)len, (int)val); } else { bson_append_int64 (STACK_BSON_CHILD, key, (int)len, val); } } else if (rs == BSON_JSON_IN_BSON_TYPE || rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) { switch (bs) { case BSON_JSON_LF_DATE: bson->bson_type_data.date.has_date = true; bson->bson_type_data.date.date = val; break; case BSON_JSON_LF_TIMESTAMP_T: bson->bson_type_data.timestamp.has_t = true; bson->bson_type_data.timestamp.t = (uint32_t)val; break; case BSON_JSON_LF_TIMESTAMP_I: bson->bson_type_data.timestamp.has_i = true; bson->bson_type_data.timestamp.i = (uint32_t)val; break; case BSON_JSON_LF_MINKEY: bson->bson_type_data.minkey.has_minkey = true; break; case BSON_JSON_LF_MAXKEY: bson->bson_type_data.maxkey.has_maxkey = true; break; case BSON_JSON_LF_REGEX: case BSON_JSON_LF_OPTIONS: case BSON_JSON_LF_OID: case BSON_JSON_LF_BINARY: case BSON_JSON_LF_TYPE: case BSON_JSON_LF_REF: case BSON_JSON_LF_ID: case BSON_JSON_LF_UNDEFINED: case BSON_JSON_LF_INT64: default: _bson_json_read_set_error (reader, "Invalid special type for integer read %d", bs); return 0; } } else { _bson_json_read_set_error (reader, "Invalid state for integer read %d", rs); return 0; } return 1; }