From 4b5586ffed4616ca937452d6725899050e94f15f Mon Sep 17 00:00:00 2001 From: rexy712 Date: Fri, 21 Dec 2018 12:44:47 -0800 Subject: [PATCH] Reorganized file structure --- CMakeLists.txt | 2 +- include/rjp.h | 12 ++- include/rjp_internal.h | 19 +++-- include/strings.h | 32 +++++++ src/input.c | 187 +++++------------------------------------ src/memory.c | 70 +++++++++++++-- src/output.c | 96 +-------------------- src/rjp.c | 155 ++++++++++++++++++++++++++++++++++ src/strings.c | 17 +++- 9 files changed, 309 insertions(+), 281 deletions(-) create mode 100644 include/strings.h create mode 100644 src/rjp.c diff --git a/CMakeLists.txt b/CMakeLists.txt index a3b2c38..88d9335 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ include_directories("${INCLUDE_PATH}") option(ENABLE_DIAGNOSTICS "Print diagnostic messages when parsing json to help identify issues" ON) option(ENABLE_SHARED "Build shared library" OFF) -set(SOURCE_LIST "src/input.c" "src/output.c" "src/strings.c" "src/memory.c") +set(SOURCE_LIST "src/input.c" "src/output.c" "src/strings.c" "src/memory.c" "src/rjp.c") if(ENABLE_SHARED) add_library(rjp SHARED ${SOURCE_LIST}) else() diff --git a/include/rjp.h b/include/rjp.h index fa9a7a8..55fabda 100644 --- a/include/rjp.h +++ b/include/rjp.h @@ -75,17 +75,17 @@ typedef struct RJP_value{ enum RJP_type type; //flag to determine active member of union }RJP_value; -//Convert C string consisting of json data into RJP's format + //Convert C string consisting of json data into RJP's format RJP_value* rjp_parse(const char* str); - -//Free an RJP_value and all members/elements -void rjp_free_value(RJP_value* root); - //Initialize a root RJP_value to NULL RJP_value* rjp_init_json(void); //Initialize a root RJP_value to copy of value RJP_value* rjp_init_json_as(RJP_value value); +//Free an RJP_value and all members/elements +void rjp_free_value(RJP_value* root); +//Deep copy RJP_value +void rjp_copy_value(RJP_value* dest, const RJP_value* src); //Allocate heap space for rjp to use. Use if the memory is to be freed by rjp @@ -95,8 +95,6 @@ void* rjp_calloc(size_t num, size_t nbytes); //Free memory allocated by rjp_alloc or rjp_calloc void rjp_free(void* dest); -//Deep copy an RJP_value -void rjp_copy_value(RJP_value* dest, const RJP_value* src); //add a member to a json object, allocating a copy of the key RJP_value* rjp_add_member(RJP_value* dest, const char* key, size_t keylen, RJP_value value); //add a member to a json object without allocation. key must be allocated using rjp_alloc/rjp_calloc diff --git a/include/rjp_internal.h b/include/rjp_internal.h index dfaa984..90fa45e 100644 --- a/include/rjp_internal.h +++ b/include/rjp_internal.h @@ -21,6 +21,19 @@ #include "rjp.h" +#ifdef __GNUC__ +#define MAYBE_UNUSED __attribute__((unused)) +#else +#define MAYBE_UNUSED +#endif + +#ifdef RJP_DIAGNOSTICS +#include +#define DIAG_PRINT(...) fprintf(__VA_ARGS__) +#else +#define DIAG_PRINT(...) +#endif + // typedef struct RJP_array_element{ struct RJP_value value; @@ -33,12 +46,8 @@ typedef struct RJP_object_member{ struct RJP_object_member* next; }RJP_object_member; -char* _rjp__parse_string(RJP_value* root, const char* str, int* len, int* row, int* column); -size_t _rjp__object_strlen(RJP_value* root); +void _rjp__add_element(RJP_array* j); void _rjp__add_member(RJP_object* j, const char* str, size_t len); void _rjp__add_member_no_alloc(RJP_object* j, char* str, size_t len); -void _rjp__add_element(RJP_array* j); -size_t _rjp__object_strlen(RJP_value* root); -size_t _rjp__value_strlen(RJP_value* root); #endif diff --git a/include/strings.h b/include/strings.h new file mode 100644 index 0000000..bea1299 --- /dev/null +++ b/include/strings.h @@ -0,0 +1,32 @@ +/** + rjp + Copyright (C) 2018 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef STRINGS_H +#define STRINGS_H + +#include "rjp.h" +#include //size_t + +int _rjp__is_whitespace(char c); +char* _rjp__parse_string(RJP_value* root, const char* str, int* len, int* row, int* column); +size_t _rjp__array_strlen(RJP_value* arr); +size_t _rjp__object_strlen(RJP_value* root); +size_t _rjp__value_strlen(RJP_value* root); +void _rjp__strcpy(RJP_string* dest, const RJP_string* src); + +#endif diff --git a/src/input.c b/src/input.c index b7b3462..565fb4e 100644 --- a/src/input.c +++ b/src/input.c @@ -20,22 +20,11 @@ #include "rjp.h" #include "rjp_internal.h" -#include //strncpy -#include //malloc, calloc, free +#include "strings.h" +#include "memory.h" +#include //strtod, strtol #include //fprintf, stderr -#ifdef __GNUC__ -#define MAYBE_UNUSED __attribute__((unused)) -#else -#define MAYBE_UNUSED -#endif - -#ifdef RJP_DIAGNOSTICS -#define DIAG_PRINT(...) fprintf(__VA_ARGS__) -#else -#define DIAG_PRINT(...) -#endif - //types of searches in the text typedef enum json_search_target{ json_key, @@ -45,151 +34,21 @@ typedef enum json_search_target{ json_none }json_search_target; -//Determine if the character is valid whitespace -static int _rjp__is_whitespace(char c){ - return c == ' ' || c == '\n' || c == '\r' || c == '\t'; -} -//add an element to an array -void _rjp__add_element(RJP_array* j){ - ++j->num_elements; - if(!j->elements){ - j->elements = rjp_calloc(1, sizeof(RJP_array_element)); - j->last = j->elements; - }else{ - j->last->next = rjp_calloc(1, sizeof(RJP_array_element)); - j->last = j->last->next; - } -} -//create member of the object as a linked list member and assign a name with name allocation -void _rjp__add_member(RJP_object* j, const char* str, size_t len){ - ++j->num_members; - if(!j->members){ - j->members = rjp_calloc(1, sizeof(RJP_object_member)); - j->last = j->members; - }else{ - j->last->next = rjp_calloc(1, sizeof(RJP_object_member)); - j->last = j->last->next; - } - j->last->name.value = rjp_alloc(len + 1); - strncpy(j->last->name.value, str, len); - j->last->name.value[len] = 0; - j->last->name.length = len; -} -void _rjp__add_member_no_alloc(RJP_object* j, char* str, size_t len){ - ++j->num_members; - if(!j->members){ - j->members = rjp_calloc(1, sizeof(RJP_object_member)); - j->last = j->members; - }else{ - j->last->next = rjp_calloc(1, sizeof(RJP_object_member)); - j->last = j->last->next; - } - j->last->name.value = str; - j->last->name.length = len; -} - -static RJP_value* _rjp__add_value(RJP_value* curr, RJP_value* new_val){ +static RJP_value* _rjp__add_value(RJP_value* curr, RJP_value new_val){ + new_val.parent = curr; if(!curr){ curr = rjp_calloc(1, sizeof(RJP_value)); - *curr = *new_val; + *curr = new_val; return curr; } if(curr->type == json_array){ _rjp__add_element(&curr->array); - curr->array.last->value = *new_val; + curr->array.last->value = new_val; return &curr->array.last->value; } - curr->object.last->value = *new_val; + curr->object.last->value = new_val; return &curr->object.last->value; } -//Assign object characteristics to previously allocated RJP_value -static RJP_value* _rjp__add_object(RJP_value* curr){ - RJP_value new_object = {.type = json_object, .integer = 0, .parent = curr}; - return _rjp__add_value(curr, &new_object); -} -//Assign array characteristics to previously allocated RJP_value -static RJP_value* _rjp__add_array(RJP_value* curr){ - RJP_value new_array = {.type = json_array, .array = {.num_elements = 0, .elements = NULL}, .parent = curr}; - return _rjp__add_value(curr, &new_array); -} -//Assign string characteristics to previously allocated RJP_value with no string allocation -static RJP_value* _rjp__add_string_no_alloc(RJP_value* curr, char* str, int len){ - RJP_value new_string = {.type = json_string, .string = {.value = str, .length = len}, .parent = curr}; - return _rjp__add_value(curr, &new_string); -} -//Assign double characteristics to previously allocated RJP_value -static RJP_value* _rjp__add_dfloat(RJP_value* curr, double value){ - RJP_value new_double = {.type = json_dfloat, .dfloat = value, .parent = curr}; - return _rjp__add_value(curr, &new_double); -} -//Assign integer characteristics to previously allocated RJP_value -static RJP_value* _rjp__add_integer(RJP_value* curr, long value){ - RJP_value new_integer = {.type = json_integer, .integer = value, .parent = curr}; - return _rjp__add_value(curr, &new_integer); -} -static RJP_value* _rjp__add_boolean(RJP_value* curr, int value){ - RJP_value new_boolean = {.type = json_boolean, .boolean = value, .parent = curr}; - return _rjp__add_value(curr, &new_boolean); -} -static RJP_value* _rjp__add_null(RJP_value* curr){ - RJP_value new_null = {.type = json_null, .integer = 0, .parent = curr}; - return _rjp__add_value(curr, &new_null); -} - -static void _rjp__free_object_recurse(RJP_value* root); - -static void _rjp__free_array(RJP_value* root){ - RJP_array_element* arr = root->array.elements; - for(RJP_array_element* i = arr;i != NULL;i = arr){ - arr = arr->next; - if(i->value.type == json_object){ - _rjp__free_object_recurse(&i->value); - }else if(i->value.type == json_array){ - _rjp__free_array(&i->value); - }else if(i->value.type == json_string){ - free(i->value.string.value); - } - free(i); - } -} -//Recursively free JSON objects -static void _rjp__free_object_recurse(RJP_value* root){ - RJP_object_member* next; - for(RJP_object_member* m = root->object.members;m;m = next){ - next = m->next; - if(m->value.type == json_object) - _rjp__free_object_recurse(&m->value); - else if(m->value.type == json_string) - free(m->value.string.value); - else if(m->value.type == json_array) - _rjp__free_array(&m->value); - if(m->name.value) - free(m->name.value); - free(m); - } -} -void rjp_free_value_json(char* json){ - free(json); -} -//Same as recurse but also frees root node -void rjp_free_value(RJP_value* root){ - if(!root) - return; - - if((root->type) == json_object) - _rjp__free_object_recurse(root); - else if((root->type) == json_array) - _rjp__free_array(root); - - free(root); -} - -MAYBE_UNUSED static int _rjp__is_array_empty(RJP_value* curr){ - if(curr->object.members->value.type != json_array) - return 0; - return curr->object.members->value.array.num_elements == 0; -} - #define syntax_error(msg, row, column)\ do{DIAG_PRINT(stderr, "Syntax error! %s (%i:%i)\n", msg, row, column);rjp_free_value(root);return NULL;}while(0) @@ -299,11 +158,11 @@ RJP_value* rjp_parse(const char* str){ //object if(c == '{'){ if(!root){ - root = _rjp__add_object(NULL); + root = _rjp__add_value(NULL, rjp_object()); curr = root; *top = json_key; }else{ - curr = _rjp__add_object(curr); + curr = _rjp__add_value(curr, rjp_object()); *top = json_comma; ++top; *top = json_key; @@ -311,11 +170,11 @@ RJP_value* rjp_parse(const char* str){ } else if(c == '['){ if(!root){ - root = _rjp__add_array(NULL); + root = _rjp__add_value(NULL, rjp_array()); curr = root; }else{ - curr = _rjp__add_array(curr); + curr = _rjp__add_value(curr, rjp_array()); } } else if(c == ']' && curr->type == json_array){ //empty array @@ -334,7 +193,7 @@ RJP_value* rjp_parse(const char* str){ return NULL; } } - _rjp__add_string_no_alloc(curr, new_string, vallen); + _rjp__add_value(curr, rjp_string(new_string, vallen)); str += vallen; *top = json_comma; } @@ -363,15 +222,15 @@ RJP_value* rjp_parse(const char* str){ } if(floating){ if(!root){ - root = curr = _rjp__add_dfloat(NULL, strtod(str, NULL)); + root = curr = _rjp__add_value(NULL, rjp_dfloat(strtod(str, NULL))); }else{ - _rjp__add_dfloat(curr, strtod(str, NULL)); + _rjp__add_value(curr, rjp_dfloat(strtod(str, NULL))); } }else{ if(!root){ - root = curr = _rjp__add_integer(NULL, strtol(str, NULL, 10)); + root = curr = _rjp__add_value(NULL, rjp_integer(strtol(str, NULL, 10))); }else{ - _rjp__add_integer(curr, strtol(str, NULL, 10)); + _rjp__add_value(curr, rjp_integer(strtol(str, NULL, 10))); } } str += (numlen-1); @@ -381,28 +240,28 @@ RJP_value* rjp_parse(const char* str){ else if(!strncmp(str, "true", 4)){ if(!curr){ *top = json_none; - root = curr = _rjp__add_boolean(curr, 1); + root = curr = _rjp__add_value(curr, rjp_boolean(1)); }else{ *top = json_comma; - _rjp__add_boolean(curr, 1); + _rjp__add_value(curr, rjp_boolean(1)); } str += 3;column += 3; }else if(!strncmp(str, "false", 5)){ if(!curr){ *top = json_none; - root = curr = _rjp__add_boolean(curr, 0); + root = curr = _rjp__add_value(curr, rjp_boolean(0)); }else{ *top = json_comma; - _rjp__add_boolean(curr, 0); + _rjp__add_value(curr, rjp_boolean(0)); } str += 4;column += 4; }else if(!strncmp(str, "null", 4)){ if(!curr){ *top = json_none; - root = curr = _rjp__add_null(curr); + root = curr = _rjp__add_value(curr, rjp_null()); }else{ *top = json_comma; - _rjp__add_null(curr); + _rjp__add_value(curr, rjp_null()); } str += 3;column += 3; } diff --git a/src/memory.c b/src/memory.c index 145ba9a..d71f3ec 100644 --- a/src/memory.c +++ b/src/memory.c @@ -1,3 +1,21 @@ +/** + rjp + Copyright (C) 2018 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + #include "rjp_internal.h" #include @@ -13,13 +31,6 @@ void rjp_free(void* data){ free(data); } -void _rjp__strcpy(RJP_string* dest, const RJP_string* src){ - dest->value = rjp_alloc(src->length + 1); - strcpy(dest->value, src->value); - dest->value[src->length] = 0; - dest->length = src->length; -} - static void _rjp__copy_object(RJP_value* dest, const RJP_value* src){ dest->object.members = dest->object.last = 0; for(RJP_value* curr = rjp_get_member(src);curr;curr = rjp_next_member(curr)){ @@ -63,3 +74,48 @@ void rjp_copy_value(RJP_value* dest, const RJP_value* src){ break; }; } + +static void _rjp__free_object_recurse(RJP_value* root); +static void _rjp__free_array(RJP_value* root){ + RJP_array_element* arr = root->array.elements; + for(RJP_array_element* i = arr;i != NULL;i = arr){ + arr = arr->next; + if(i->value.type == json_object){ + _rjp__free_object_recurse(&i->value); + }else if(i->value.type == json_array){ + _rjp__free_array(&i->value); + }else if(i->value.type == json_string){ + free(i->value.string.value); + } + free(i); + } +} +//Recursively free JSON objects +static void _rjp__free_object_recurse(RJP_value* root){ + RJP_object_member* next; + for(RJP_object_member* m = root->object.members;m;m = next){ + next = m->next; + if(m->value.type == json_object) + _rjp__free_object_recurse(&m->value); + else if(m->value.type == json_string) + free(m->value.string.value); + else if(m->value.type == json_array) + _rjp__free_array(&m->value); + if(m->name.value) + free(m->name.value); + free(m); + } +} + +//Same as recurse but also frees root node +void rjp_free_value(RJP_value* root){ + if(!root) + return; + + if((root->type) == json_object) + _rjp__free_object_recurse(root); + else if((root->type) == json_array) + _rjp__free_array(root); + + free(root); +} diff --git a/src/output.c b/src/output.c index b82e2cd..c2ee530 100644 --- a/src/output.c +++ b/src/output.c @@ -18,9 +18,9 @@ #include "rjp.h" #include "rjp_internal.h" +#include "memory.h" #include //strlen -#include //malloc, calloc, free #include //sprintf RJP_value* rjp_init_json(void){ @@ -32,100 +32,6 @@ RJP_value* rjp_init_json_as(RJP_value value){ *ret = value; return ret; } -RJP_value* rjp_add_member(RJP_value* dest, const char* key, size_t keylen, RJP_value value){ - if(!keylen) - keylen = strlen(key); - _rjp__add_member(&dest->object, key, keylen); - dest->object.last->value = value; - dest->object.last->value.parent = dest; - return &dest->object.last->value; -} -RJP_value* rjp_add_member_no_alloc(RJP_value* dest, char* key, size_t keylen, RJP_value value){ - if(!keylen) - keylen = strlen(key); - _rjp__add_member_no_alloc(&dest->object, key, keylen); - dest->object.last->value = value; - dest->object.last->value.parent = dest; - return &dest->object.last->value; -} -RJP_value* rjp_add_element(RJP_value* dest, RJP_value value){ - _rjp__add_element(&dest->array); - dest->array.last->value = value; - dest->array.last->value.parent = dest; - return &dest->array.last->value; -} -void rjp_set_value(RJP_value* dest, RJP_value value){ - struct RJP_value* p = dest->parent; - *dest = value; - dest->parent = p; -} -RJP_value rjp_integer(long i){ - return (RJP_value){.integer = i, .type = json_integer}; -} -RJP_value rjp_boolean(char b){ - return (RJP_value){.boolean = b, .type = json_boolean}; -} -RJP_value rjp_dfloat(double d){ - return (RJP_value){.dfloat = d, .type = json_dfloat}; -} -RJP_value rjp_string(char* c, size_t len){ - return (RJP_value){.string = {.value = c, .length = len}, .type = json_string}; -} -RJP_value rjp_null(void){ - return (RJP_value){.integer = 0, .type = json_null}; -} -RJP_value rjp_object(void){ - return (RJP_value){.object = {0}, .type = json_object}; -} -RJP_value rjp_array(void){ - return (RJP_value){.array = {0}, .type = json_array}; -} - - - -RJP_value* rjp_get_member(const RJP_value* object){ - return &object->object.members->value; -} -RJP_value* rjp_next_member(const RJP_value* member){ - //polymorphism - return (RJP_value*)(((RJP_object_member*)member)->next); -} -RJP_value* rjp_get_element(const RJP_value* array){ - return &array->array.elements->value; -} -RJP_value* rjp_next_element(const RJP_value* element){ - return (RJP_value*)(((RJP_array_element*)element)->next); -} - -char* rjp_member_name(const RJP_value* member){ - return ((RJP_object_member*)member)->name.value; -} -size_t rjp_member_name_length(RJP_value* member){ - return ((RJP_object_member*)member)->name.length; -} - -RJP_value* rjp_value_parent(RJP_value* value){ - return value->parent; -} -RJP_type rjp_value_type(RJP_value* value){ - return value->type; -} -double rjp_value_dfloat(RJP_value* value){ - return value->dfloat; -} -int rjp_value_integer(RJP_value* value){ - return value->integer; -} -char rjp_value_boolean(RJP_value* value){ - return value->boolean; -} -char* rjp_value_string(RJP_value* value){ - return value->string.value; -} -size_t rjp_value_string_length(RJP_value* value){ - return value->string.length; -} - static size_t _rjp__write_value(char* dest, RJP_value* val){ size_t ret; diff --git a/src/rjp.c b/src/rjp.c new file mode 100644 index 0000000..594b6cb --- /dev/null +++ b/src/rjp.c @@ -0,0 +1,155 @@ +/** + rjp + Copyright (C) 2018 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "rjp_internal.h" + +#include //strncpy, strlen + +void _rjp__add_element(RJP_array* j){ + ++j->num_elements; + if(!j->elements){ + j->elements = rjp_calloc(1, sizeof(RJP_array_element)); + j->last = j->elements; + }else{ + j->last->next = rjp_calloc(1, sizeof(RJP_array_element)); + j->last = j->last->next; + } +} +//create member of the object as a linked list member and assign a name with name allocation +void _rjp__add_member(RJP_object* j, const char* str, size_t len){ + ++j->num_members; + if(!j->members){ + j->members = rjp_calloc(1, sizeof(RJP_object_member)); + j->last = j->members; + }else{ + j->last->next = rjp_calloc(1, sizeof(RJP_object_member)); + j->last = j->last->next; + } + j->last->name.value = rjp_alloc(len + 1); + strncpy(j->last->name.value, str, len); + j->last->name.value[len] = 0; + j->last->name.length = len; +} +void _rjp__add_member_no_alloc(RJP_object* j, char* str, size_t len){ + ++j->num_members; + if(!j->members){ + j->members = rjp_calloc(1, sizeof(RJP_object_member)); + j->last = j->members; + }else{ + j->last->next = rjp_calloc(1, sizeof(RJP_object_member)); + j->last = j->last->next; + } + j->last->name.value = str; + j->last->name.length = len; +} + +RJP_value* rjp_add_member(RJP_value* dest, const char* key, size_t keylen, RJP_value value){ + if(!keylen) + keylen = strlen(key); + _rjp__add_member(&dest->object, key, keylen); + dest->object.last->value = value; + dest->object.last->value.parent = dest; + return &dest->object.last->value; +} +RJP_value* rjp_add_member_no_alloc(RJP_value* dest, char* key, size_t keylen, RJP_value value){ + if(!keylen) + keylen = strlen(key); + _rjp__add_member_no_alloc(&dest->object, key, keylen); + dest->object.last->value = value; + dest->object.last->value.parent = dest; + return &dest->object.last->value; +} +RJP_value* rjp_add_element(RJP_value* dest, RJP_value value){ + _rjp__add_element(&dest->array); + dest->array.last->value = value; + dest->array.last->value.parent = dest; + return &dest->array.last->value; +} +void rjp_set_value(RJP_value* dest, RJP_value value){ + struct RJP_value* p = dest->parent; + *dest = value; + dest->parent = p; +} +RJP_value rjp_integer(long i){ + return (RJP_value){.integer = i, .type = json_integer}; +} +RJP_value rjp_boolean(char b){ + return (RJP_value){.boolean = b, .type = json_boolean}; +} +RJP_value rjp_dfloat(double d){ + return (RJP_value){.dfloat = d, .type = json_dfloat}; +} +RJP_value rjp_string(char* c, size_t len){ + return (RJP_value){.string = {.value = c, .length = len}, .type = json_string}; +} +RJP_value rjp_null(void){ + return (RJP_value){.integer = 0, .type = json_null}; +} +RJP_value rjp_object(void){ + return (RJP_value){.object = {0}, .type = json_object}; +} +RJP_value rjp_array(void){ + return (RJP_value){.array = {0}, .type = json_array}; +} + + + +RJP_value* rjp_get_member(const RJP_value* object){ + return &object->object.members->value; +} +RJP_value* rjp_next_member(const RJP_value* member){ + //polymorphism + return (RJP_value*)(((RJP_object_member*)member)->next); +} +RJP_value* rjp_get_element(const RJP_value* array){ + return &array->array.elements->value; +} +RJP_value* rjp_next_element(const RJP_value* element){ + return (RJP_value*)(((RJP_array_element*)element)->next); +} + +char* rjp_member_name(const RJP_value* member){ + return ((RJP_object_member*)member)->name.value; +} +size_t rjp_member_name_length(RJP_value* member){ + return ((RJP_object_member*)member)->name.length; +} + +RJP_value* rjp_value_parent(RJP_value* value){ + return value->parent; +} +RJP_type rjp_value_type(RJP_value* value){ + return value->type; +} +double rjp_value_dfloat(RJP_value* value){ + return value->dfloat; +} +int rjp_value_integer(RJP_value* value){ + return value->integer; +} +char rjp_value_boolean(RJP_value* value){ + return value->boolean; +} +char* rjp_value_string(RJP_value* value){ + return value->string.value; +} +size_t rjp_value_string_length(RJP_value* value){ + return value->string.length; +} + + diff --git a/src/strings.c b/src/strings.c index 630dfa9..c9c9a21 100644 --- a/src/strings.c +++ b/src/strings.c @@ -16,12 +16,18 @@ along with this program. If not, see . */ -#include "rjp.h" +#include "strings.h" #include "rjp_internal.h" #include //fprintf #include //malloc, free -#include +#include //uintN_t +#include //strcpy + +//Determine if the character is valid whitespace +int _rjp__is_whitespace(char c){ + return c == ' ' || c == '\n' || c == '\r' || c == '\t'; +} static uint32_t utf_strtol_4(const char* c){ uint32_t ret = 0; @@ -261,6 +267,13 @@ size_t rjp_escape_strcpy(char* dest, const char* src){ dest[j] = 0; return j; } +void _rjp__strcpy(RJP_string* dest, const RJP_string* src){ + dest->value = rjp_alloc(src->length + 1); + strcpy(dest->value, src->value); + dest->value[src->length] = 0; + dest->length = src->length; +} + size_t rjp_escape_strlen(const char* str){ size_t count = 0; for(size_t i = 0;str[i];++i){