int dom_null(JSAXContextRef ctxt) { DomInfo *data = getDOMContext(ctxt); // no handle to the context CHECK_CONDITION_RETURN_VALUE(data == NULL, 0, "null encountered without any context"); // no parent node CHECK_CONDITION_RETURN_VALUE(data->m_prev == NULL, 0, "unexpected state - how is this possible?"); SANITY_CHECK_POINTER(ctxt); SANITY_CHECK_POINTER(data->m_prev); if (data->m_value == NULL) { CHECK_CONDITION_RETURN_VALUE(!jis_array(data->m_prev->m_value), 0, "Improper place for null"); jarray_append(data->m_prev->m_value, jnull()); } else if (jis_string(data->m_value)) { CHECK_CONDITION_RETURN_VALUE(!jis_object(data->m_prev->m_value), 0, "Improper place for null"); jobject_put(data->m_prev->m_value, data->m_value, jnull()); data->m_value = NULL; } else { PJ_LOG_ERR("PBNJSON_NULL_VALUE_WO_KEY", 0, "value portion of key-value pair without a key"); return 0; } return 1; }
static bool jobject_to_string_append (jvalue_ref jref, JStreamRef generating) { SANITY_CHECK_POINTER(jref); if (UNLIKELY(!generating->o_begin (generating))) { PJ_LOG_ERR("Schema validation error, objects are not allowed."); return false; } if (!jis_object (jref)) { const char *asStr = jvalue_tostring_internal_layer2 (jref, NULL, false); generating->string (generating, J_CSTR_TO_BUF("Internal error - not an object")); generating->string (generating, j_cstr_to_buffer(asStr)); // create invalid JSON on purpose return false; } jobject_iter it; jobject_iter_init(&it, jref); jobject_key_value key_value; while (jobject_iter_next(&it, &key_value)) { assert(jis_string(key_value.key)); if(UNLIKELY(!key_value_to_string_append(key_value, generating))) { return false; } } if (UNLIKELY(!generating->o_end (generating))) { PJ_LOG_ERR("Schema validation error, object did not validate against schema"); return false; } return true; }
int dom_string(JSAXContextRef ctxt, const char *string, size_t stringLen) { DomInfo *data = getDOMContext(ctxt); CHECK_CONDITION_RETURN_VALUE(data == NULL, 0, "string encountered without any context"); CHECK_CONDITION_RETURN_VALUE(data->m_prev == NULL, 0, "unexpected state - how is this possible?"); jvalue_ref jstr = createOptimalString(data->m_optInformation, string, stringLen); if (data->m_value == NULL) { if (UNLIKELY(!jis_array(data->m_prev->m_value))) { PJ_LOG_ERR("PBNJSON_ARR_MISPLACED_STR", 1, PMLOGKS("STRING", string), "Improper place for string"); j_release(&jstr); return 0; } jarray_append(data->m_prev->m_value, jstr); } else if (jis_string(data->m_value)) { if (UNLIKELY(!jis_object(data->m_prev->m_value))) { PJ_LOG_ERR("PBNJSON_OBJ_MISPLACED_STR", 1, PMLOGKS("STRING", string), "Improper place for string"); j_release(&jstr); return 0; } jobject_put(data->m_prev->m_value, data->m_value, jstr); data->m_value = NULL; } else { PJ_LOG_ERR("PBNJSON_STR_VALUE_WO_KEY", 1, PMLOGKS("STRING", string), "value portion of key-value pair without a key"); return 0; } return 1; }
int dom_number(JSAXContextRef ctxt, const char *number, size_t numberLen) { DomInfo *data = getDOMContext(ctxt); jvalue_ref jnum; CHECK_CONDITION_RETURN_VALUE(data == NULL, 0, "number encountered without any context"); CHECK_CONDITION_RETURN_VALUE(data->m_prev == NULL, 0, "unexpected state - how is this possible?"); CHECK_POINTER_RETURN_VALUE(number, 0); CHECK_CONDITION_RETURN_VALUE(numberLen == 0, 0, "unexpected - numeric string doesn't actually contain a number"); jnum = createOptimalNumber(data->m_optInformation, number, numberLen); if (data->m_value == NULL) { if (UNLIKELY(!jis_array(data->m_prev->m_value))) { PJ_LOG_ERR("PBNJSON_ARR_MISPLACED_NUM", 1, PMLOGKS("NUM", number), "Improper place for number"); j_release(&jnum); return 0; } jarray_append(data->m_prev->m_value, jnum); } else if (jis_string(data->m_value)) { if (UNLIKELY(!jis_object(data->m_prev->m_value))) { PJ_LOG_ERR("PBNJSON_OBJ_MISPLACED_NUM", 1, PMLOGKS("NUM", number), "Improper place for number"); j_release(&jnum); return 0; } jobject_put(data->m_prev->m_value, data->m_value, jnum); data->m_value = NULL; } else { PJ_LOG_ERR("PBNJSON_NUM_VALUE_WO_KEY", 1, PMLOGKS("NUM", number), "value portion of key-value pair without a key"); return 0; } return 1; }
bool jsax_parse_inject(JSAXContextRef ctxt, jvalue_ref key, jvalue_ref value) { assert (jis_string(key)); assert (jis_object(value)); return jsax_parse_inject_internal(ctxt, key, value); }
static int dom_object_start(JSAXContextRef ctxt) { DomInfo *data = getDOMContext(ctxt); jvalue_ref newParent; DomInfo *newChild; CHECK_CONDITION_RETURN_VALUE(data == NULL, 0, "object encountered without any context"); newParent = jobject_create(); newChild = calloc(1, sizeof(DomInfo)); if (UNLIKELY(newChild == NULL || jis_null(newParent))) { PJ_LOG_ERR("Failed to allocate space for new object"); j_release(&newParent); free(newChild); return 0; } newChild->m_prev = data; newChild->m_optInformation = data->m_optInformation; changeDOMContext(ctxt, newChild); if (data->m_prev != NULL) { if (jis_array(data->m_prev->m_value)) { assert(data->m_value == NULL); jarray_append(data->m_prev->m_value, newParent); } else { assert(jis_object(data->m_prev->m_value)); CHECK_CONDITION_RETURN_VALUE(!jis_string(data->m_value), 0, "improper place for a child object"); jobject_put(data->m_prev->m_value, data->m_value, newParent); } } // not using reference counting here on purpose data->m_value = newParent; return 1; }
static int dom_object_end(JSAXContextRef ctxt) { DomInfo *data = getDOMContext(ctxt); CHECK_CONDITION_RETURN_VALUE(data == NULL, 0, "object end encountered without any context"); CHECK_CONDITION_RETURN_VALUE(data->m_value != NULL, 0, "mismatch between key/value count"); CHECK_CONDITION_RETURN_VALUE(!jis_object(data->m_prev->m_value), 0, "object end encountered, but not in an object"); assert(data->m_prev != NULL); changeDOMContext(ctxt, data->m_prev); if (data->m_prev->m_prev != NULL) data->m_prev->m_value = NULL; free(data); return 1; }
int dom_object_key(JSAXContextRef ctxt, const char *key, size_t keyLen) { DomInfo *data = getDOMContext(ctxt); CHECK_CONDITION_RETURN_VALUE(data == NULL, 0, "object key encountered without any context"); CHECK_CONDITION_RETURN_VALUE(data->m_value != NULL, 0, "Improper place for an object key"); CHECK_CONDITION_RETURN_VALUE(data->m_prev == NULL, 0, "object key encountered without any parent object"); CHECK_CONDITION_RETURN_VALUE(!jis_object(data->m_prev->m_value), 0, "object key encountered without any parent object"); // Need to be careful here - typically, m_value isn't reference counted // thus if parsing fails and m_value hasn't been inserted into a bigger object that is // tracked, we will leak. // The alternate behaviour is to insert into the parent value with a null value. // Then when inserting the value of the key/value pair into an object, we first remove the key & re-insert // a key/value pair (we don't currently have a replace mechanism). data->m_value = createOptimalString(data->m_optInformation, key, keyLen); return 1; }
int dom_object_end(JSAXContextRef ctxt) { DomInfo *data = getDOMContext(ctxt); CHECK_CONDITION_RETURN_VALUE(data == NULL, 0, "object end encountered without any context"); CHECK_CONDITION_RETURN_VALUE(data->m_value != NULL, 0, "mismatch between key/value count"); CHECK_CONDITION_RETURN_VALUE(!jis_object(data->m_prev->m_value), 0, "object end encountered, but not in an object"); assert(data->m_prev != NULL); changeDOMContext(ctxt, data->m_prev); if (data->m_prev->m_prev != NULL) { j_release(&data->m_prev->m_value); // 0xdeadbeef may be written in debug mode, which fools the code data->m_prev->m_value = NULL; } free(data); return 1; }
int dom_boolean(JSAXContextRef ctxt, bool value) { DomInfo *data = getDOMContext(ctxt); CHECK_CONDITION_RETURN_VALUE(data == NULL, 0, "boolean encountered without any context"); CHECK_CONDITION_RETURN_VALUE(data->m_prev == NULL, 0, "unexpected state - how is this possible?"); if (data->m_value == NULL) { CHECK_CONDITION_RETURN_VALUE(!jis_array(data->m_prev->m_value), 0, "Improper place for boolean"); jarray_append(data->m_prev->m_value, jboolean_create(value)); } else if (jis_string(data->m_value)) { CHECK_CONDITION_RETURN_VALUE(!jis_object(data->m_prev->m_value), 0, "Improper place for boolean"); jobject_put(data->m_prev->m_value, data->m_value, jboolean_create(value)); data->m_value = NULL; } else { PJ_LOG_ERR("PBNJSON_BOOL_VALUE_WO_KEY", 0, "value portion of key-value pair without a key"); return 0; } return 1; }
int dom_object_start(JSAXContextRef ctxt) { DomInfo *data = getDOMContext(ctxt); jvalue_ref newParent; DomInfo *newChild; CHECK_CONDITION_RETURN_VALUE(data == NULL, 0, "object encountered without any context"); newParent = jobject_create(); newChild = calloc(1, sizeof(DomInfo)); if (UNLIKELY(newChild == NULL || !jis_valid(newParent))) { PJ_LOG_ERR("PBNJSON_OBJ_CALLOC_ERR", 0, "Failed to allocate space for new object"); j_release(&newParent); free(newChild); return 0; } newChild->m_prev = data; newChild->m_optInformation = data->m_optInformation; changeDOMContext(ctxt, newChild); if (data->m_prev != NULL) { if (jis_array(data->m_prev->m_value)) { assert(data->m_value == NULL); jarray_append(data->m_prev->m_value, jvalue_copy(newParent)); } else { assert(jis_object(data->m_prev->m_value)); if (UNLIKELY(!jis_string(data->m_value))) { PJ_LOG_ERR("PBNJSON_OBJ_MISPLACED_CHILD", 0, "improper place for a child object"); j_release(&newParent); return 0; } jobject_put(data->m_prev->m_value, data->m_value, jvalue_copy(newParent)); } } data->m_value = newParent; return 1; }
bool JValue::isObject() const { return jis_object(m_jval); }