Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions examples/example-04.c
Original file line number Diff line number Diff line change
@@ -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;
}

17 changes: 10 additions & 7 deletions examples/makefile
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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

Expand All @@ -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) >$@
95 changes: 95 additions & 0 deletions tiny-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ typedef struct jsonStaticPool_s {

/* Search a property by its name in a JSON object. */
json_t const* json_getProperty( json_t const* obj, char const* property ) {
if ( !obj || !property || json_getType( obj )==JSON_NULL ) {
return 0;
}
if ( obj->name && !strcmp( obj->name, property ) ) {
return obj;
}
json_t const* sibling;
for( sibling = obj->u.c.child; sibling; sibling = sibling->sibling )
if ( sibling->name && !strcmp( sibling->name, property ) )
Expand Down Expand Up @@ -459,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
24 changes: 24 additions & 0 deletions tiny-json.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down