Implement reading/writing extra fields in layout and storing in json_value structure, fix bug reading arrays and objects (uninitialized json_value)

master
teknomunk 1 year ago
parent 2e01bfd30d
commit 95ced0973d

@ -568,6 +568,7 @@ bool json_pull_parser_read_value( struct json_pull_parser* jpp, struct json_valu
}
while(( s = json_pull_parser_read_object_key(jpp) )) {
struct json_value v;
memset(&v,0,sizeof(v));
if( !json_pull_parser_read_value(jpp, value ? &v : NULL ) ) {
if( value ) {
json_value_free_composite(&v);
@ -598,6 +599,7 @@ bool json_pull_parser_read_value( struct json_pull_parser* jpp, struct json_valu
}
struct json_value v;
memset(&v,0,sizeof(v));
if( !json_pull_parser_read_value(jpp, value ? &v :NULL) ) {
//printf( "failed to read value. state=%d\n", jpp->curr_state );

@ -16,36 +16,6 @@
#define DEBUG_fflush(...)
#endif
bool inline_layout_writer( struct json_writer* jw, const char* field_name, void* data, struct json_object_field* layout_field_data )
{
bool result = false;
DEBUG_printf( "begin inline_layout_writer()\n" );
struct json_object_field* layout = layout_field_data->sublayout;
for( int i = 0; layout[i].key; ++i ) {
void* field_data = &((char*)(data))[ layout[i].offset ];
DEBUG_printf( "layout[%d] = { .key = %s, .offset = %d, .required = %c, ... }, field_data=%p\n",
i,
layout[i].key,
layout[i].offset,
layout[i].required ? 'T' : 'F',
field_data
);
if( layout[i].type->writer( jw, layout[i].key, field_data, &layout[i] ) ) {
jw->need_comma = true;
result = true;
}
}
DEBUG_printf( "end inline_layout_writer()\n" );
return result;
}
struct json_field_type json_field_inline_sublayout = {
.writer = inline_layout_writer,
};
static int count_required_fields( struct json_object_field* layout )
{
int count = 0;
@ -70,6 +40,20 @@ static bool handle_layout_field( struct json_pull_parser* jpp, const char* key,
return true;
}
DEBUG_printf( "no match\n" );
} else if( layout[i].type == &json_field_extra ) {
DEBUG_printf( "extra layout\n" );
layout[i].key = key;
DEBUG_printf( "layout_data = { .key = %s, .offset = %d, .required = %c, ... }, field_data=%p\n",
layout[i].key,
layout[i].offset,
layout[i].required ? 'T' : 'F',
field_data
);
if( layout[i].type->reader( jpp, field_data, &layout[i] ) ) {
return true;
}
} else if( 0 == strcmp( key, layout[i].key ) ) {
DEBUG_printf( "layout_data = { .key = %s, .offset = %d, .required = %c, ... }, field_data=%p\n",

@ -37,8 +37,10 @@ struct json_field_type
};
#endif
extern struct json_field_type json_field_integer;
extern struct json_field_type json_field_inline_sublayout;
extern struct json_field_type json_field_extra;
extern struct json_field_type json_field_integer;
// layout/bool.c
extern struct json_field_type json_field_bool;

@ -0,0 +1,131 @@
#include "../layout.h"
#include "json/json.h"
#include "json/value.h"
#include "collections/array.h"
#include <string.h>
//#define DEBUG
#ifdef DEBUG
#define DEBUG_printf printf
#define DEBUG_fflush fflush
#else
#define DEBUG_printf(...)
#define DEBUG_fflush(...)
#endif
static bool extra_reader( struct json_pull_parser* jpp, void* field_data, struct json_object_field* layout_field_data )
{
printf( "extra_reader key=%s\n", layout_field_data->key );
struct json_value* extra = field_data;
struct json_object_pair pair = {
.key = strdup(layout_field_data->key),
.value = {
.type = jvt_null
},
};
if( !json_pull_parser_read_value( jpp, &pair.value ) ) {
return false;
}
if( extra->type != jvt_object ) {
json_value_free_composite(extra);
}
extra->type = jvt_object;
array_append( &extra->o, sizeof(pair), &pair );
return true;
}
static bool json_value_writer( struct json_writer* jw, const char* field_name, void* data, struct json_object_field* layout_field_data )
{
struct json_value* value = data;
// Discard layout data
layout_field_data = NULL;
switch( value->type ) {
case jvt_null:
return false;
case jvt_number:
json_write_field_name( jw, field_name );
fprintf( jw->f, "%g", value->n );
return true;
case jvt_string:
json_write_field_name( jw, field_name );
json_write_string( jw->f, value->s );
return true;
case jvt_array:
json_write_field_name( jw, field_name );
{
fprintf( jw->f, "[" );
for( int i = 0; i < value->a.count; ++i ) {
if( i > 0 ) {
fprintf( jw->f, "," );
}
if( value->a.items[i].type == jvt_null ) {
fprintf( jw->f, "null" );
} else {
json_value_writer( jw, NULL, &value->a.items[i], NULL );
}
}
fprintf( jw->f, "]" );
}
return true;
case jvt_object:
json_write_field_name( jw, field_name );
{
fprintf( jw->f, "{" ); jw->indent += 1;
for( int i = 0; i < value->o.count; ++i ) {
if( i > 0 ) {
fprintf( jw->f, ",\n" );
}
json_write_indention(jw);
json_write_string( jw->f, value->o.items[i].key );
fprintf( jw->f, ":" );
if( value->o.items[i].value.type == jvt_null ) {
fprintf( jw->f, "null" );
} else {
json_value_writer( jw, NULL, &value->o.items[i].value, NULL );
}
}
fprintf( jw->f, "}" ); jw->indent -= 1;
}
return true;
};
return false;
}
static bool extra_writer( struct json_writer* jw, const char* field_name, void* data, struct json_object_field* layout_field_data )
{
struct json_value* value = data;
if( value->type != jvt_object ) { return false; }
for( int i = 0; i < value->o.count; ++i ) {
json_write_indention(jw);
json_write_string( jw->f, value->o.items[i].key );
fprintf( jw->f, ":" );
if( value->o.items[i].value.type == jvt_null ) {
fprintf( jw->f, "null" );
} else {
json_value_writer( jw, NULL, &value->o.items[i].value, NULL );
}
jw->need_comma = true;
}
jw->need_comma = true;
return value->o.count > 0;
}
struct json_field_type json_field_extra = {
.reader = extra_reader,
.writer = extra_writer,
};

@ -1,6 +1,16 @@
#include "../json.h"
#include "../layout.h"
//#define DEBUG
#ifdef DEBUG
#define DEBUG_printf printf
#define DEBUG_fflush fflush
#else
#define DEBUG_printf(...)
#define DEBUG_fflush(...)
#endif
bool json_field_object_type_reader( struct json_pull_parser* jpp, void* field_data, struct json_object_field* layout_field_data )
{
struct json_field_type* ft = layout_field_data->type;
@ -91,3 +101,34 @@ struct json_field_type json_field_fixed_null = {
.size = sizeof(int),
};
bool inline_layout_writer( struct json_writer* jw, const char* field_name, void* data, struct json_object_field* layout_field_data )
{
bool result = false;
DEBUG_printf( "begin inline_layout_writer()\n" );
struct json_object_field* layout = layout_field_data->sublayout;
for( int i = 0; layout[i].key; ++i ) {
void* field_data = &((char*)(data))[ layout[i].offset ];
DEBUG_printf( "layout[%d] = { .key = %s, .offset = %d, .required = %c, ... }, field_data=%p\n",
i,
layout[i].key,
layout[i].offset,
layout[i].required ? 'T' : 'F',
field_data
);
if( layout[i].type->writer( jw, layout[i].key, field_data, &layout[i] ) ) {
jw->need_comma = true;
result = true;
}
}
DEBUG_printf( "end inline_layout_writer()\n" );
return result;
}
struct json_field_type json_field_inline_sublayout = {
.writer = inline_layout_writer,
};

Loading…
Cancel
Save