static int object_add_keyval(context_t *ctx, yajl_val obj, char *key, yajl_val value) { const char **tmpk; yajl_val *tmpv; /* We're checking for NULL in "context_add_value" or its callers. */ assert (ctx != NULL); assert (obj != NULL); assert (key != NULL); assert (value != NULL); /* We're assuring that "obj" is an object in "context_add_value". */ assert(YAJL_IS_OBJECT(obj)); tmpk = realloc((void *) obj->u.object.keys, sizeof(*(obj->u.object.keys)) * (obj->u.object.len + 1)); if (tmpk == NULL) RETURN_ERROR(ctx, ENOMEM, "Out of memory"); obj->u.object.keys = tmpk; tmpv = realloc(obj->u.object.values, sizeof (*obj->u.object.values) * (obj->u.object.len + 1)); if (tmpv == NULL) RETURN_ERROR(ctx, ENOMEM, "Out of memory"); obj->u.object.values = tmpv; obj->u.object.keys[obj->u.object.len] = key; obj->u.object.values[obj->u.object.len] = value; obj->u.object.len++; return (0); }
bson* bson_from_json_str(const char* str) { yajl_val root; char* errbuf; bson *b; errbuf = malloc( sizeof(char) * 1024 ); root = yajl_tree_parse( str, errbuf, 1024 ); if( !root ) { puts( "Parse error: " ); if( strlen( errbuf ) ) puts( errbuf ); else puts( "unknown error." ); yajl_tree_free( root ); free( errbuf ); return NULL; } free( errbuf ); assert( YAJL_IS_OBJECT( root ) ); b = malloc( sizeof( bson ) ); bson_init( b ); bson_from_json_object( b, root ); bson_finish( b ); yajl_tree_free( root ); return b; }
/* * Add a value to the value on top of the stack or the "root" member in the * context if the end of the parsing process is reached. */ static int context_add_value (context_t *ctx, yajl_val v) { /* We're checking for NULL values in all the calling functions. */ assert (ctx != NULL); assert (v != NULL); /* * There are three valid states in which this function may be called: * - There is no value on the stack => This is the only value. This is the * last step done when parsing a document. We assign the value to the * "root" member and return. * - The value on the stack is an object. In this case store the key on the * stack or, if the key has already been read, add key and value to the * object. * - The value on the stack is an array. In this case simply add the value * and return. */ if (ctx->stack == NULL) { assert (ctx->root == NULL); ctx->root = v; return (0); } else if (YAJL_IS_OBJECT (ctx->stack->value)) { if (ctx->stack->key == NULL) { if (!YAJL_IS_STRING (v)) RETURN_ERROR (ctx, EINVAL, "context_add_value: " "Object key is not a string (%#04x)", v->type); ctx->stack->key = v->u.string; v->u.string = NULL; free(v); return (0); } else /* if (ctx->key != NULL) */ { char * key; key = ctx->stack->key; ctx->stack->key = NULL; return (object_add_keyval (ctx, ctx->stack->value, key, v)); } } else if (YAJL_IS_ARRAY (ctx->stack->value)) { return (array_add_value (ctx, ctx->stack->value, v)); } else { RETURN_ERROR (ctx, EINVAL, "context_add_value: Cannot add value to " "a value of type %#04x (not a composite type)", ctx->stack->value->type); } }
/* #include "config.h" #include "weapon.h" #include "pic_manager.h" #include "sys_config.h" void AddIntPair(json_t *parent, const char *name, int number) { char buf[32]; sprintf(buf, "%d", number); json_insert_pair_into_object(parent, name, json_new_number(buf)); } void AddBoolPair(json_t *parent, const char *name, int value) { json_insert_pair_into_object(parent, name, json_new_bool(value)); } void AddStringPair(json_t *parent, const char *name, const char *s) { if (!s) { json_insert_pair_into_object(parent, name, json_new_string("")); } else { json_insert_pair_into_object( parent, name, json_new_string(json_escape(s))); } } void AddColorPair(json_t *parent, const char *name, const color_t c) { char buf[8]; ColorStr(buf, c); AddStringPair(parent, name, buf); } */ bool YAJLTryLoadValue(yajl_val *node, const char *name) { if (*node == NULL || !YAJL_IS_OBJECT(*node)) { return false; } const char *path[] = { name, NULL }; *node = yajl_tree_get(*node, path, yajl_t_any); return *node != NULL; }
/* Add YAJL value into YAJL generator handle (JSON object) * * jgen - YAJL generator handle allocated by yajl_gen_alloc() * jval - YAJL value usually returned by yajl_tree_get() */ static yajl_gen_status ovs_yajl_gen_val(yajl_gen jgen, yajl_val jval) { size_t array_len = 0; yajl_val *jvalues = NULL; yajl_val jobj_value = NULL; const char *obj_key = NULL; size_t obj_len = 0; yajl_gen_status yajl_gen_ret = yajl_gen_status_ok; if (jval == NULL) return yajl_gen_generation_complete; if (YAJL_IS_STRING(jval)) OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, YAJL_GET_STRING(jval)); else if (YAJL_IS_DOUBLE(jval)) OVS_YAJL_CALL(yajl_gen_double, jgen, YAJL_GET_DOUBLE(jval)); else if (YAJL_IS_INTEGER(jval)) OVS_YAJL_CALL(yajl_gen_double, jgen, YAJL_GET_INTEGER(jval)); else if (YAJL_IS_TRUE(jval)) OVS_YAJL_CALL(yajl_gen_bool, jgen, 1); else if (YAJL_IS_FALSE(jval)) OVS_YAJL_CALL(yajl_gen_bool, jgen, 0); else if (YAJL_IS_NULL(jval)) OVS_YAJL_CALL(yajl_gen_null, jgen); else if (YAJL_IS_ARRAY(jval)) { /* create new array and add all elements into the array */ array_len = YAJL_GET_ARRAY(jval)->len; jvalues = YAJL_GET_ARRAY(jval)->values; OVS_YAJL_CALL(yajl_gen_array_open, jgen); for (size_t i = 0; i < array_len; i++) OVS_YAJL_CALL(ovs_yajl_gen_val, jgen, jvalues[i]); OVS_YAJL_CALL(yajl_gen_array_close, jgen); } else if (YAJL_IS_OBJECT(jval)) { /* create new object and add all elements into the object */ OVS_YAJL_CALL(yajl_gen_map_open, jgen); obj_len = YAJL_GET_OBJECT(jval)->len; for (size_t i = 0; i < obj_len; i++) { obj_key = YAJL_GET_OBJECT(jval)->keys[i]; jobj_value = YAJL_GET_OBJECT(jval)->values[i]; OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, obj_key); OVS_YAJL_CALL(ovs_yajl_gen_val, jgen, jobj_value); } OVS_YAJL_CALL(yajl_gen_map_close, jgen); } else { OVS_ERROR("%s() unsupported value type %d (skip)", __FUNCTION__, (int)(jval)->type); goto yajl_gen_failure; } return yajl_gen_status_ok; yajl_gen_failure: OVS_ERROR("%s() error to generate value", __FUNCTION__); return yajl_gen_ret; }
void bson_from_json_type(bson *b, yajl_val value, const char* key) { if( YAJL_IS_STRING( value ) ) { char* string = YAJL_GET_STRING( value ); bson_append_string( b, key, string ); } else if( YAJL_IS_NUMBER( value ) ) { char* string = value->u.number.r; size_t len = strlen( string ); // Hack to detect a double, since 'flags' is always set to double. if( memchr( string, '.', len ) || memchr( string, 'e', len ) || memchr( string, 'E', len ) ) { double number = YAJL_GET_DOUBLE( value ); bson_append_double( b, key, number ); } else { uint64_t number = YAJL_GET_INTEGER( value ); if( number <= INT_MIN && number <= INT_MAX) bson_append_int( b, key, (int)number ); else bson_append_long( b, key, number); } } else if ( YAJL_IS_FALSE( value ) ) { bson_append_bool( b, key, 0 ); } else if ( YAJL_IS_TRUE( value ) ) { bson_append_bool( b, key, 1 ); } else if ( YAJL_IS_ARRAY( value ) ) { bson_append_start_array( b, key ); bson_from_json_array( b, value ); bson_append_finish_array( b ); } else if ( YAJL_IS_OBJECT( value ) ) { bson_append_start_object( b, key ); bson_from_json_object( b, value ); bson_append_finish_object( b ); } }
SEXP ParseValue(yajl_val node, int bigint){ if(YAJL_IS_NULL(node)){ return R_NilValue; } if(YAJL_IS_STRING(node)){ SEXP tmp = PROTECT(allocVector(STRSXP, 1)); SET_STRING_ELT(tmp, 0, mkCharCE(YAJL_GET_STRING(node), CE_UTF8)); UNPROTECT(1); return tmp; } if(YAJL_IS_INTEGER(node)){ long long int val = YAJL_GET_INTEGER(node); /* 2^53 is highest int stored as double without loss */ if(bigint && (val > 9007199254740992 || val < -9007199254740992)){ char buf[32]; #ifdef _WIN32 snprintf(buf, 32, "%I64d", val); #else snprintf(buf, 32, "%lld", val); #endif return mkString(buf); /* see .Machine$integer.max in R */ } else if(val > 2147483647 || val < -2147483647){ return ScalarReal(val); } else { return ScalarInteger(val); } } if(YAJL_IS_DOUBLE(node)){ return(ScalarReal(YAJL_GET_DOUBLE(node))); } if(YAJL_IS_NUMBER(node)){ /* A number that is not int or double (very rare) */ /* This seems to correctly round to Inf/0/-Inf */ return(ScalarReal(YAJL_GET_DOUBLE(node))); } if(YAJL_IS_TRUE(node)){ return(ScalarLogical(1)); } if(YAJL_IS_FALSE(node)){ return(ScalarLogical(0)); } if(YAJL_IS_OBJECT(node)){ return(ParseObject(node, bigint)); } if(YAJL_IS_ARRAY(node)){ return(ParseArray(node, bigint)); } error("Invalid YAJL node type."); }
/* Get YAJL value by key from YAJL dictionary * * EXAMPLE: * { * "key_a" : <YAJL return value> * "key_b" : <YAJL return value> * } */ yajl_val ovs_utils_get_value_by_key(yajl_val jval, const char *key) { const char *obj_key = NULL; /* check params */ if (!YAJL_IS_OBJECT(jval) || (key == NULL)) return NULL; /* find a value by key */ for (size_t i = 0; i < YAJL_GET_OBJECT(jval)->len; i++) { obj_key = YAJL_GET_OBJECT(jval)->keys[i]; if (strcmp(obj_key, key) == 0) return YAJL_GET_OBJECT(jval)->values[i]; } return NULL; }
static void yajl_object_free (yajl_val v) { size_t i; if (!YAJL_IS_OBJECT(v)) return; for (i = 0; i < v->u.object.len; i++) { free((char *) v->u.object.keys[i]); v->u.object.keys[i] = NULL; yajl_tree_free (v->u.object.values[i]); v->u.object.values[i] = NULL; } free((void*) v->u.object.keys); free(v->u.object.values); free(v); }
/* * Parsing nested objects and arrays is implemented using a stack. When a new * object or array starts (a curly or a square opening bracket is read), an * appropriate value is pushed on the stack. When the end of the object is * reached (an appropriate closing bracket has been read), the value is popped * off the stack and added to the enclosing object using "context_add_value". */ static int context_push(context_t *ctx, yajl_val v) { stack_elem_t *stack; stack = malloc (sizeof (*stack)); if (stack == NULL) RETURN_ERROR (ctx, ENOMEM, "Out of memory"); memset (stack, 0, sizeof (*stack)); assert ((ctx->stack == NULL) || YAJL_IS_OBJECT (v) || YAJL_IS_ARRAY (v)); stack->value = v; stack->next = ctx->stack; ctx->stack = stack; return (0); }
/* OVS DB table update event handler. * This callback is called by POLL thread if OVS DB * table update callback is received from the DB * server. Once registered callback found, it's called * by this handler. */ static int ovs_db_table_update_cb(ovs_db_t *pdb, yajl_val jnode) { ovs_callback_t *cb = NULL; yajl_val jvalue; yajl_val jparams; yajl_val jtable_updates; const char *params_path[] = {"params", NULL}; const char *id_path[] = {"id", NULL}; /* check & get request attributes */ if ((jparams = yajl_tree_get(jnode, params_path, yajl_t_array)) == NULL || (yajl_tree_get(jnode, id_path, yajl_t_null) == NULL)) { OVS_ERROR("invalid OVS DB request received"); return -1; } /* check array length: [<json-value>, <table-updates>] */ if ((YAJL_GET_ARRAY(jparams) == NULL) || (YAJL_GET_ARRAY(jparams)->len != 2)) { OVS_ERROR("invalid OVS DB request received"); return -1; } jvalue = YAJL_GET_ARRAY(jparams)->values[0]; jtable_updates = YAJL_GET_ARRAY(jparams)->values[1]; if ((!YAJL_IS_OBJECT(jtable_updates)) || (!YAJL_IS_STRING(jvalue))) { OVS_ERROR("invalid OVS DB request id or table update received"); return -1; } /* find registered callback based on <json-value> */ pthread_mutex_lock(&pdb->mutex); cb = ovs_db_table_callback_get(pdb, jvalue); if (cb == NULL || cb->table.call == NULL) { OVS_ERROR("No OVS DB table update callback found"); pthread_mutex_unlock(&pdb->mutex); return -1; } /* call registered callback */ cb->table.call(jtable_updates); pthread_mutex_unlock(&pdb->mutex); return 0; }
void message_json_handler_function(yajl_val j, void *context) { state *s = context; // LLog("[message_json_handler_function] will read value type\n"); // LLog("[message_json_handler_function] value is %d\n", (unsigned int)j); // LLog("[message_json_handler_function] value type is %d\n", j->type); if (!YAJL_IS_OBJECT(j)) { LLog("[message_json_handler_function] value was not an object, bailing out\n"); return; } int num_vals = YAJL_GET_OBJECT(j)->len; for (int i = 0; i < num_vals; i++) { const char *name = YAJL_GET_OBJECT(j)->keys[i]; //LLog("[message_json_handler_function] did get name = %s\n", name); yajl_val value = YAJL_GET_OBJECT(j)->values[i]; if (YAJL_IS_INTEGER(value)) { //LLog("[message_json_handler_function] value is integer\n"); state_set_int(s, name, YAJL_GET_INTEGER(value)); } else if (YAJL_IS_DOUBLE(value)) { //LLog("[message_json_handler_function] value is double\n"); state_set_float(s, name, (float)YAJL_GET_DOUBLE(value)); } else if (YAJL_IS_TRUE(value)) { //LLog("[message_json_handler_function] value is true\n"); state_set_int(s, name, 1); } else if (YAJL_IS_FALSE(value)) { //LLog("[message_json_handler_function] value is false\n"); state_set_int(s, name, 0); } else { //LLog("[message_json_handler_function] value is complex\n"); state_set_json(s, name, value); } } }
static char * parse_json_get_object_string (const char *json, const char *key, int flags, const char *func, const char *cmd) { char *str, *ret; yajl_val tree = NULL, node; size_t i, len; tree = parse_json (json, func); if (tree == NULL) return NULL; if (! YAJL_IS_OBJECT (tree)) goto bad_type; len = YAJL_GET_OBJECT (tree)->len; for (i = 0; i < len; ++i) { if (STREQ (YAJL_GET_OBJECT (tree)->keys[i], key)) { node = YAJL_GET_OBJECT (tree)->values[i]; if ((flags & GET_STRING_NULL_TO_EMPTY) && YAJL_IS_NULL (node)) ret = strdup (""); else { str = YAJL_GET_STRING (node); if (str == NULL) goto bad_type; ret = strdup (str); } if (ret == NULL) reply_with_perror ("strdup"); yajl_tree_free (tree); return ret; } } bad_type: reply_with_error ("output of '%s' was not a JSON object " "containing a key '%s' of type string", cmd, key); yajl_tree_free (tree); return NULL; }
int v1(struct http_request *http_req) { struct jsonrpc_request req; int ret; /* We only allow POST/PUT methods. */ if (http_req->method != HTTP_METHOD_POST && http_req->method != HTTP_METHOD_PUT) { http_response_header(http_req, "allow", "POST, PUT"); http_response(http_req, HTTP_STATUS_METHOD_NOT_ALLOWED, NULL, 0); return (KORE_RESULT_OK); } /* Read JSON-RPC request. */ if ((ret = jsonrpc_read_request(http_req, &req)) != 0) return jsonrpc_error(&req, ret, NULL); /* Echo command takes and gives back params. */ if (strcmp(req.method, "echo") == 0) { if (!YAJL_IS_ARRAY(req.params)) { jsonrpc_log(&req, LOG_ERR, "Echo only accepts positional params"); return jsonrpc_error(&req, JSONRPC_INVALID_PARAMS, NULL); } for (size_t i = 0; i < req.params->u.array.len; i++) { yajl_val v = req.params->u.array.values[i]; if (!YAJL_IS_STRING(v)) { jsonrpc_log(&req, -3, "Echo only accepts strings"); return jsonrpc_error(&req, JSONRPC_INVALID_PARAMS, NULL); } } return jsonrpc_result(&req, write_string_array_params, NULL); } /* Date command displays date and time according to parameters. */ if (strcmp(req.method, "date") == 0) { time_t time_value; struct tm time_info; char timestamp[33]; struct tm *(*gettm)(const time_t *, struct tm *) = localtime_r; if (YAJL_IS_OBJECT(req.params)) { const char *path[] = {"local", NULL}; yajl_val bf; bf = yajl_tree_get(req.params, path, yajl_t_false); if (bf != NULL) gettm = gmtime_r; } else if (req.params != NULL) { jsonrpc_log(&req, LOG_ERR, "Date only accepts named params"); return jsonrpc_error(&req, JSONRPC_INVALID_PARAMS, NULL); } if ((time_value = time(NULL)) == -1) return jsonrpc_error(&req, -2, "Failed to get date time"); if (gettm(&time_value, &time_info) == NULL) return jsonrpc_error(&req, -3, "Failed to get date time info"); memset(timestamp, 0, sizeof(timestamp)); if (strftime_l(timestamp, sizeof(timestamp) - 1, "%c", &time_info, LC_GLOBAL_LOCALE) == 0) return jsonrpc_error(&req, -4, "Failed to get printable date time"); return jsonrpc_result(&req, write_string, timestamp); } return jsonrpc_error(&req, JSONRPC_METHOD_NOT_FOUND, NULL); }