mirror of
https://github.com/rafagafe/tiny-json.git
synced 2025-03-13 03:35:31 +00:00
Merge 277ca31477
into 025cdde5f2
This commit is contained in:
commit
6c6b490f94
71
examples/example-04.c
Normal file
71
examples/example-04.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
CC = gcc
|
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)
|
||||||
src += $(wildcard ../*.c)
|
src += $(wildcard ../*.c)
|
||||||
@ -9,7 +9,7 @@ dep = $(obj:.o=.d)
|
|||||||
|
|
||||||
.PHONY: build all clean
|
.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
|
all: clean build
|
||||||
|
|
||||||
@ -19,13 +19,16 @@ clean::
|
|||||||
rm -rf *.exe
|
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 $@ $^
|
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 $@ $^
|
gcc $(CFLAGS) -o $@ $^
|
||||||
|
|
||||||
example-03.exe: example-03.o ../tiny-json.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 $@ $^
|
gcc $(CFLAGS) -o $@ $^
|
||||||
|
|
||||||
-include $(dep)
|
-include $(dep)
|
||||||
|
95
tiny-json.c
95
tiny-json.c
@ -41,6 +41,12 @@ typedef struct jsonStaticPool_s {
|
|||||||
|
|
||||||
/* Search a property by its name in a JSON object. */
|
/* Search a property by its name in a JSON object. */
|
||||||
json_t const* json_getProperty( json_t const* obj, char const* property ) {
|
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;
|
json_t const* sibling;
|
||||||
for( sibling = obj->u.c.child; sibling; sibling = sibling->sibling )
|
for( sibling = obj->u.c.child; sibling; sibling = sibling->sibling )
|
||||||
if ( sibling->name && !strcmp( sibling->name, property ) )
|
if ( sibling->name && !strcmp( sibling->name, property ) )
|
||||||
@ -459,3 +465,92 @@ static char* setToNull( char* ch ) {
|
|||||||
static bool isEndOfPrimitive( char ch ) {
|
static bool isEndOfPrimitive( char ch ) {
|
||||||
return ch == ',' || isOneOfThem( ch, blank ) || isOneOfThem( ch, endofblock );
|
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
tiny-json.h
24
tiny-json.h
@ -167,6 +167,30 @@ struct jsonPool_s {
|
|||||||
* This property is always unnamed and its type is JSON_OBJ. */
|
* This property is always unnamed and its type is JSON_OBJ. */
|
||||||
json_t const* json_createWithPool( char* str, jsonPool_t* pool );
|
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
|
#ifdef __cplusplus
|
||||||
|
Loading…
Reference in New Issue
Block a user