support for json_ObjectsToJSON (reverse action of json_createWithPool)

This commit is contained in:
Jeff Mathews 2023-02-10 15:25:56 -07:00
parent be4772ea70
commit 277ca31477
4 changed files with 194 additions and 7 deletions

71
examples/example-04.c Normal file
View File

@ -0,0 +1,71 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "tiny-json.h"
#include "../json-maker/json-maker.h"
int main( void ) {
printf("tiny-json objects to json...\n");
{
// convert a static string to a tiny-json objects
const char* original = "{\"ts\":\"2023-02-09T23:18:27Z\",\"dev\":true,\"info\":{\"r1\":16807,\"ra\":[282475249,1622650073,984943658,1144108930],\"r2\":470211272},\"r3\":44}";
char *data = malloc( strlen(original)+1 );
strcpy(data, original);
json_t pool[16] = {0,};
json_t const *e = json_create( data, pool, sizeof(pool)/sizeof(pool[0]) );
assert( e );
// test something in those tiny-json objects
json_t const *e1 = json_getProperty( e, "dev" );
const char* key = json_getName(e1);
bool value = json_getBoolean(e1);
assert( strcmp( key, "dev" ) == 0 );
assert( value == true );
// convert tiny-json objects back into json string
size_t sz = 2048;
char *json = calloc( 1, sz );
assert(json);
// just convert back, don't change anything
json_ObjectsToJSON( json, &sz, e );
assert( strcmp( json, original ) == 0 );
// convert while replacing a key
json_replaceInteger( json, &sz, e, "r1", 22 );
assert( strstr( json, "\"ts\":\"2023-02-09T23:18:27Z\"") ); // no change
assert( strstr( json, "\"r1\":22") ); // <- changed
assert( strstr( json, "\"dev\":true") ); // no change
// retain last change by reseting json input & storing tiny-objects
strcpy(data, json);
e = json_create( data, pool, sizeof(pool)/sizeof(pool[0]) );
// convert while replacing a key
json_replaceBoolean( json, &sz, e, "dev", false );
assert( strstr( json, "\"ts\":\"2023-02-09T23:18:27Z\"") ); // no change
assert( strstr( json, "\"r1\":22") ); // still changed
assert( strstr( json, "\"dev\":false") ); // <- changed
// retain last change by reseting json input & storing tiny-objects
strcpy(data, json);
e = json_create( data, pool, sizeof(pool)/sizeof(pool[0]) );
// convert while replacing a key
json_replaceString( json, &sz, e, "ts", "ABCDEF" );
assert( strstr( json, "\"ts\":\"ABCDEF\"") ); // <- changed
assert( strstr( json, "\"r1\":22") ); // still changed
assert( strstr( json, "\"dev\":false") ); // still changed
free(data);
free(json);
}
printf("pass\n");
return 0;
}

View File

@ -1,6 +1,6 @@
CC = gcc
CFLAGS = -std=c99 -Wall -pedantic
CFLAGS = -std=c99 -Wall -pedantic -I. -I.. -I../../json-maker -DJSON_REVERSER
src = $(wildcard *.c)
src += $(wildcard ../*.c)
@ -9,7 +9,7 @@ dep = $(obj:.o=.d)
.PHONY: build all clean
build: example-01.exe example-02.exe example-03.exe
build: example-01.exe example-02.exe example-03.exe example-04.exe
all: clean build
@ -19,16 +19,19 @@ clean::
rm -rf *.exe
example-01.exe: example-01.o ../tiny-json.o
example-01.exe: example-01.o ../tiny-json.o ../../json-maker/json-maker.o
gcc $(CFLAGS) -o $@ $^
example-02.exe: example-02.o ../tiny-json.o
example-02.exe: example-02.o ../tiny-json.o ../../json-maker/json-maker.o
gcc $(CFLAGS) -o $@ $^
example-03.exe: example-03.o ../tiny-json.o
gcc $(CFLAGS) -o $@ $^
example-03.exe: example-03.o ../tiny-json.o ../../json-maker/json-maker.o
gcc $(CFLAGS) -o $@ $^
example-04.exe: example-04.o ../tiny-json.o ../../json-maker/json-maker.o
gcc $(CFLAGS) -o $@ $^
-include $(dep)
%.d: %.c
$(CC) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@
$(CC) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@

View File

@ -465,3 +465,92 @@ static char* setToNull( char* ch ) {
static bool isEndOfPrimitive( char ch ) {
return ch == ',' || isOneOfThem( ch, blank ) || isOneOfThem( ch, endofblock );
}
#ifdef JSON_REVERSER
#include <assert.h>
#include "json-maker.h"
static char* objectToJSON(char* o, size_t* sz, const json_t* e, const char* property, const char* newString, const int newInteger) {
for( e = json_getChild(e); e!=0; e = json_getSibling(e) ) {
const char *key = json_getName(e);
switch( json_getType( e ) ) {
case JSON_OBJ: {
o = json_objOpen( o, key, sz );
o = objectToJSON(o, sz, e, property, newString, newInteger);
o = json_objClose( o, sz );
break; }
case JSON_TEXT: {
const char *value = json_getValue(e);
if ( key && property && !strcmp( key, property ) ) {
value = newString;
}
o = json_str( o, key, value, sz );
break; }
case JSON_INTEGER: {
int value = json_getInteger(e);
if ( key && property && !strcmp( key, property ) ) {
value = newInteger;
}
o = json_int( o, key, value, sz );
break; }
case JSON_ARRAY: {
o = json_arrOpen( o, key, sz);
o = objectToJSON(o, sz, e, property, newString, newInteger);
o = json_arrClose( o, sz );
break; }
case JSON_BOOLEAN: {
bool value = json_getBoolean(e);
if ( key && property && !strcmp( key, property ) ) {
value = newInteger;
}
o = json_bool( o, key, value, sz );
break; }
case JSON_REAL:
case JSON_NULL:
default:
assert(0); // not supported
break;
}
}
return o;
}
char* json_ObjectsToJSON(char* json, size_t* sz, const json_t* e) {
char *o = json;
o = json_objOpen( o, NULL, sz );
o = objectToJSON( o, sz, e, 0, 0, 0 );
o = json_objClose( o, sz );
o = json_end( o, sz );
return json;
}
char* json_replaceString(char* json, size_t* sz, const json_t* e, const char* key, const char* value) {
char *o = json;
o = json_objOpen( o, NULL, sz );
o = objectToJSON( o, sz, e, key, value, 0 );
o = json_objClose( o, sz );
o = json_end( o, sz );
return json;
}
char* json_replaceInteger(char* json, size_t* sz, const json_t* e, const char* key, const int value) {
char *o = json;
o = json_objOpen( o, NULL, sz );
o = objectToJSON( o, sz, e, key, 0, value );
o = json_objClose( o, sz );
o = json_end( o, sz );
return json;
}
char* json_replaceBoolean(char* json, size_t* sz, const json_t* e, const char* key, const int value) {
char *o = json;
o = json_objOpen( o, NULL, sz );
o = objectToJSON( o, sz, e, key, 0, value );
o = json_objClose( o, sz );
o = json_end( o, sz );
return json;
}
#endif

View File

@ -167,6 +167,30 @@ struct jsonPool_s {
* This property is always unnamed and its type is JSON_OBJ. */
json_t const* json_createWithPool( char* str, jsonPool_t* pool );
#ifdef JSON_REVERSER
#include <assert.h>
#include "json-maker.h"
/** reverse the action of json_createWithPool.
* i.e. convert all the json_t* tiny json objects back into a string
* caller must allocate json string large enough to thold the string and set sz accordingly.
* returns pointer to json string */
char* json_ObjectsToJSON(char* json, size_t* sz, const json_t* e);
/** json_ObjectsToJSON but also finds the property matching *key and replaces it with value.
* if caller intends on calling more than one property, then they should
* retain the change by reseting json input & storing tiny-objects via
strcpy(data, json);
e = json_create( data, pool, sizeof(pool)/sizeof(pool[0]) );
and then calling the json_replace api again. */
char* json_replaceString(char* json, size_t* sz, const json_t* e, const char* key, const char* value);
char* json_replaceInteger(char* json, size_t* sz, const json_t* e, const char* key, const int value);
char* json_replaceBoolean(char* json, size_t* sz, const json_t* e, const char* key, const int value);
#endif
/** @ } */
#ifdef __cplusplus