void t12_dict_in_dict(){ INIT_LOCAL(); onion_dict *A=onion_dict_new(); onion_dict *B=onion_dict_new(); onion_dict *C=onion_dict_new(); onion_dict *D=onion_dict_new(); int i; for (i=0;i<16;i++){ char tmp[9]; sprintf(tmp,"%08X",rand()); onion_dict_add(A, tmp, tmp, OD_DUP_ALL); sprintf(tmp,"%08X",rand()); onion_dict_add(B, tmp, tmp, OD_DUP_ALL); sprintf(tmp,"%08X",rand()); onion_dict_add(C, tmp, tmp, OD_DUP_ALL); sprintf(tmp,"%08X",rand()); onion_dict_add(D, tmp, tmp, OD_DUP_ALL); } onion_dict_add(A, "B", B, OD_DICT|OD_FREE_VALUE); onion_dict_add(A, "C", C, OD_DICT|OD_FREE_VALUE); onion_dict_add(A, "D", D, OD_DICT|OD_FREE_VALUE); FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get(A, "B"), NULL); FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get(A, "C"), NULL); FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get(A, "D"), NULL); FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get_dict(A, "B"), B); FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get_dict(A, "C"), C); FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get_dict(A, "D"), D); { onion_block *tmpA=onion_dict_to_json(A); onion_block *tmpB=onion_dict_to_json(B); onion_block *tmpC=onion_dict_to_json(C); onion_block *tmpD=onion_dict_to_json(D); /* ONION_DEBUG("Json is: %s",tmpA); ONION_DEBUG("Json is: %s",tmpB); ONION_DEBUG("Json is: %s",tmpC); ONION_DEBUG("Json is: %s",tmpD); */ FAIL_IF_EQUAL( strstr(onion_block_data(tmpA), onion_block_data(tmpB)), NULL); FAIL_IF_EQUAL( strstr(onion_block_data(tmpA), onion_block_data(tmpC)), NULL); FAIL_IF_EQUAL( strstr(onion_block_data(tmpA), onion_block_data(tmpD)), NULL); onion_block_free(tmpA); onion_block_free(tmpB); onion_block_free(tmpC); onion_block_free(tmpD); } B=onion_dict_hard_dup(A); onion_dict_free(A); onion_dict_free(B); END_LOCAL(); }
void t18_json_escape_codes(){ INIT_LOCAL(); onion_dict *d=onion_dict_from_json("{ \"hello\": \"Hello\\nworld\", \"second\":\"second\" }"); FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "Hello\nworld"); FAIL_IF_NOT_STRSTR(onion_dict_get(d, "second"), "second"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\\uD83D\\uDE02\" }"); FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "😂"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\\uD83D\\uDE03\" }"); // Another code point FAIL_IF_STRSTR(onion_dict_get(d, "hello"), "😂"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\\u007b\" }"); // simple unicode FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "{"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\\\"Quote\" }"); // Escape quote FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "\"Quote"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\"Quote\" }"); // Must fail FAIL_IF_NOT_EQUAL(d, NULL); d=onion_dict_new(); onion_dict_add(d, "hello", "Hello\nWorld\\", 0); onion_dict_add(d, "second", "123", 0); onion_block *b=onion_dict_to_json(d); FAIL_IF_NOT_EQUAL_STR(onion_block_data(b),"{\"hello\":\"Hello\\nWorld\\\\\", \"second\":\"123\"}"); onion_block_free(b); onion_dict_free(d); d=onion_dict_new(); onion_dict_add(d, "hello", "😂\t\n😂", 0); b=onion_dict_to_json(d); FAIL_IF_NOT_EQUAL_STR(onion_block_data(b),"{\"hello\":\"😂\\t\\n😂\"}"); onion_block_free(b); onion_dict_free(d); d=onion_dict_new(); onion_dict_add(d, "hello", "\02\03\x7f", 0); b=onion_dict_to_json(d); FAIL_IF_NOT_EQUAL_STR(onion_block_data(b),"{\"hello\":\"\\u0002\\u0003\\u007F\"}"); onion_block_free(b); onion_dict_free(d); END_LOCAL(); }
/** * @short Helps to prepare each pair. */ static void onion_dict_json_preorder(onion_block *block, const char *key, const void *value, int flags){ if (!onion_block_size(block)) // Error somewhere. return; char *s; s=onion_c_quote_new(key); if (s==NULL){ onion_block_clear(block); return; } onion_block_add_str(block, s); free(s); onion_block_add_char(block, ':'); if (flags&OD_DICT){ onion_block *tmp; tmp=onion_dict_to_json((onion_dict*)value); if (!tmp){ onion_block_clear(block); return; } onion_block_add_block(block, tmp); onion_block_free(tmp); } else{ s=onion_c_quote_new(value); if (s==NULL){ onion_block_clear(block); return; } onion_block_add_str(block, s); free(s); } onion_block_add_data(block, ", ",2); }
/** * @short Shortcut to answer some json data * * It converts to json the passed dict and returns it. The dict is freed before returning. */ onion_connection_status onion_shortcut_response_json(onion_dict *d, onion_request *req, onion_response *res){ onion_response_set_header(res, "Content-Type", "application/json"); onion_block *bl=onion_dict_to_json(d); onion_dict_free(d); char tmp[16]; snprintf(tmp,sizeof(tmp),"%ld",(long)onion_block_size(bl)); int ret=onion_shortcut_response_extra_headers(onion_block_data(bl), HTTP_OK, req, res, "Content-Length", tmp, NULL); onion_block_free(bl); return ret; }
void onion_sessions_redis_save(onion_sessions *sessions, const char *session_id, onion_dict* data) { onion_block *bl = onion_dict_to_json(data); ONION_DEBUG0("Save session %s: %s", session_id, onion_block_data(bl)); onion_session_redis *p = sessions->data; #ifdef HAVE_PTHREADS pthread_mutex_lock(&p->mutex); #endif if(p == NULL) { redisReply* reply = redisCommand(p->context, "HDEL SESSIONS %b", session_id, strlen(session_id)); if(reply->type != REDIS_REPLY_INTEGER) { ONION_ERROR("Error removing session"); } freeReplyObject(reply); } else { const char* json = onion_block_data(bl); redisReply* reply = redisCommand(p->context, "HSET SESSIONS %b %b", session_id, strlen(session_id), json, strlen(json)); if(reply->type != REDIS_REPLY_INTEGER) { ONION_ERROR("Error saving session"); } freeReplyObject(reply); onion_block_free(bl); } #ifdef HAVE_PTHREADS pthread_mutex_unlock(&p->mutex); #endif return; }
/** * @short Helps to prepare each pair. */ static void onion_dict_json_preorder(onion_block *block, const char *key, const void *value, int flags){ if (!onion_block_size(block)) // Error somewhere. return; onion_block_add_char(block,'\"'); onion_json_quote_add(block, key); onion_block_add_data(block,"\":",2); if (flags&OD_DICT){ onion_block *tmp; tmp=onion_dict_to_json((onion_dict*)value); if (!tmp){ onion_block_clear(block); return; } onion_block_add_block(block, tmp); onion_block_free(tmp); } else{ onion_block_add_char(block,'\"'); onion_json_quote_add(block, value); onion_block_add_char(block,'\"'); } onion_block_add_data(block, ", ",2); }
void onion_sessions_sqlite3_save(onion_sessions *sessions, const char *session_id, onion_dict *data){ onion_block *bl=onion_dict_to_json(data); ONION_DEBUG0("Save session %s: %s", session_id, onion_block_data(bl)); const char *json=onion_block_data(bl); int rc; onion_session_sqlite3 *p=sessions->data; #ifdef HAVE_PTHREADS pthread_mutex_lock(&p->mutex); #endif sqlite3_reset(p->save); rc=sqlite3_bind_text(p->save, 1, session_id, -1, SQLITE_STATIC); if( rc!=SQLITE_OK ){ ONION_ERROR("Error binding session_id"); goto error; } rc=sqlite3_bind_text(p->save, 2, json, -1, SQLITE_STATIC); if( rc!=SQLITE_OK ){ ONION_ERROR("Error binding json data"); goto error; } rc=sqlite3_step(p->save); if( rc!=SQLITE_DONE ){ ONION_ERROR("Error saving session (%d)", rc); goto error; } ONION_DEBUG0("Session saved"); error: onion_block_free(bl); #ifdef HAVE_PTHREADS pthread_mutex_unlock(&p->mutex); #endif return; }
void t10_tojson(){ INIT_LOCAL(); onion_dict *d=onion_dict_new(); const char *tmp; int s; onion_block *b; b=onion_dict_to_json(d); tmp=onion_block_data(b); ONION_DEBUG("Json returned is '%s'", tmp); FAIL_IF_NOT_EQUAL_STR(tmp,"{}"); onion_block_free(b); onion_dict_add(d, "test", "json", 0); b=onion_dict_to_json(d); tmp=onion_block_data(b); s=onion_block_size(b); ONION_DEBUG("Json returned is '%s'", tmp); FAIL_IF(s<=0); FAIL_IF_EQUAL(strstr(tmp,"{"), NULL); FAIL_IF_EQUAL(strstr(tmp,"}"), NULL); FAIL_IF_EQUAL(strstr(tmp,"\"test\""), NULL); FAIL_IF_EQUAL(strstr(tmp,"\"json\""), NULL); FAIL_IF_NOT_EQUAL(strstr(tmp,","), NULL); onion_block_free(b); onion_dict_add(d, "other", "data", 0); b=onion_dict_to_json(d); tmp=onion_block_data(b); s=onion_block_size(b); ONION_DEBUG("Json returned is '%s'", tmp); FAIL_IF(s<=0); FAIL_IF_EQUAL(strstr(tmp,"{"), NULL); FAIL_IF_EQUAL(strstr(tmp,"}"), NULL); FAIL_IF_EQUAL(strstr(tmp,"\"test\""), NULL); FAIL_IF_EQUAL(strstr(tmp,"\"json\""), NULL); FAIL_IF_EQUAL(strstr(tmp,","), NULL); FAIL_IF_EQUAL(strstr(tmp,"\"other\""), NULL); FAIL_IF_EQUAL(strstr(tmp,"\"data\""), NULL); onion_block_free(b); onion_dict_add(d, "with\"", "data\n", 0); b=onion_dict_to_json(d); tmp=onion_block_data(b); s=onion_block_size(b); ONION_DEBUG("Json returned is '%s'", tmp); FAIL_IF(s<=0); FAIL_IF_EQUAL(strstr(tmp,"\\n"), NULL); FAIL_IF_EQUAL(strstr(tmp,"\\\""), NULL); onion_block_free(b); onion_dict_free(d); END_LOCAL(); }
/** * @short Converts the dictionary to a JSON string. */ std::string toJSON() const{ onion_block *bl=onion_dict_to_json(ptr); std::string str=onion_block_data(bl); onion_block_free(bl); return str; }