mirror of
https://github.com/kgabis/parson.git
synced 2025-01-14 06:12:54 +08:00
Merged changes from parson-devel (serialization, copying, comparing, validation, creating values).
This commit is contained in:
parent
55856a2eab
commit
638190d6a0
76
README.md
Normal file → Executable file
76
README.md
Normal file → Executable file
@ -1,6 +1,5 @@
|
||||
##About
|
||||
Parson is a lighweight [json](http://json.org) parser and reader written in C.
|
||||
If you need serialization and json value building in code, use [parson-devel](https://github.com/kgabis/parson-devel), which has extended API, but may change in future.
|
||||
Parson is a lighweight [json](http://json.org) library written in C.
|
||||
|
||||
##Features
|
||||
* Full JSON support
|
||||
@ -11,7 +10,7 @@ If you need serialization and json value building in code, use [parson-devel](ht
|
||||
* Test suites
|
||||
|
||||
##Installation
|
||||
Run the following code:
|
||||
Run:
|
||||
```
|
||||
git clone https://github.com/kgabis/parson.git
|
||||
```
|
||||
@ -19,8 +18,9 @@ and copy parson.h and parson.c to you source code tree.
|
||||
|
||||
Run ```make test``` to compile and run tests.
|
||||
|
||||
##Example
|
||||
Here is a function, which prints basic commit info (date, sha and author) from a github repository. It's also included in tests.c file, you can just uncomment and run it.
|
||||
##Examples
|
||||
###Parsing JSON
|
||||
Here is a function, which prints basic commit info (date, sha and author) from a github repository.
|
||||
```c
|
||||
void print_commits_info(const char *username, const char *repo) {
|
||||
JSON_Value *root_value;
|
||||
@ -75,5 +75,71 @@ Date SHA Author
|
||||
...
|
||||
```
|
||||
|
||||
###Persistence
|
||||
In this example I'm using parson to save user information to a file and then load it and validate later.
|
||||
```c
|
||||
void persistence_example(void) {
|
||||
JSON_Value *schema = json_parse_string("{\"name\":\"\"}");
|
||||
JSON_Value *user_data = json_parse_file("user_data.json");
|
||||
char buf[256];
|
||||
const char *name = NULL;
|
||||
if (!user_data || !json_validate(schema, user_data) == JSONSuccess) {
|
||||
puts("Enter your name:");
|
||||
scanf("%s", buf);
|
||||
user_data = json_value_init_object();
|
||||
json_object_set_string(json_object(user_data), "name", buf);
|
||||
json_serialize_to_file(user_data, "user_data.json");
|
||||
}
|
||||
name = json_object_get_string(json_object(user_data), "name");
|
||||
printf("Hello, %s.", name);
|
||||
json_value_free(schema);
|
||||
json_value_free(user_data);
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
###Serialization
|
||||
Creating JSON values is very simple thanks to the dot notation.
|
||||
Object hierarchy is automatically created when addressing specific fields.
|
||||
In the following example I create a simple JSON value containing basic information about a person.
|
||||
```c
|
||||
void serialization_example(void) {
|
||||
JSON_Value *root_value = json_value_init_object();
|
||||
JSON_Object *root_object = json_value_get_object(root_value);
|
||||
char *serialized_string = NULL;
|
||||
json_object_set_string(root_object, "name", "John Smith");
|
||||
json_object_set_number(root_object, "age", 25);
|
||||
json_object_dotset_string(root_object, "address.city", "Cupertino");
|
||||
json_object_dotset_value(root_object, "contact.emails", json_parse_string("[\"email@example.com\",\"email2@example.com\"]"));
|
||||
serialized_string = json_serialize_to_string(root_value);
|
||||
puts(serialized_string);
|
||||
json_free_serialized_string(serialized_string);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Created value (after formatting outside parson):
|
||||
```
|
||||
{
|
||||
"name":"John Smith",
|
||||
"age":25,
|
||||
"address":{
|
||||
"city":"Cupertino"
|
||||
},
|
||||
"contact":{
|
||||
"emails":[
|
||||
"email@example.com",
|
||||
"email2@example.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##Contributing
|
||||
|
||||
I will always merge *working* bug fixes. However, if you want to add something to the API,
|
||||
I *won't* merge it without prior discussion.
|
||||
Remember to follow parson's code style and write appropriate tests.
|
||||
|
||||
##License
|
||||
[The MIT License (MIT)](http://opensource.org/licenses/mit-license.php)
|
131
parson.h
Normal file → Executable file
131
parson.h
Normal file → Executable file
@ -36,38 +36,68 @@ typedef struct json_object_t JSON_Object;
|
||||
typedef struct json_array_t JSON_Array;
|
||||
typedef struct json_value_t JSON_Value;
|
||||
|
||||
typedef enum json_value_type {
|
||||
JSONError = 0,
|
||||
enum json_value_type {
|
||||
JSONError = -1,
|
||||
JSONNull = 1,
|
||||
JSONString = 2,
|
||||
JSONNumber = 3,
|
||||
JSONObject = 4,
|
||||
JSONArray = 5,
|
||||
JSONBoolean = 6
|
||||
} JSON_Value_Type;
|
||||
|
||||
};
|
||||
typedef int JSON_Value_Type;
|
||||
|
||||
enum json_result_t {
|
||||
JSONSuccess = 0,
|
||||
JSONFailure = -1
|
||||
};
|
||||
typedef int JSON_Status;
|
||||
|
||||
/* Parses first JSON value in a file, returns NULL in case of error */
|
||||
JSON_Value * json_parse_file(const char *filename);
|
||||
JSON_Value * json_parse_file(const char *filename);
|
||||
|
||||
/* Parses first JSON value in a file and ignores comments (/ * * / and //),
|
||||
returns NULL in case of error */
|
||||
JSON_Value * json_parse_file_with_comments(const char *filename);
|
||||
JSON_Value * json_parse_file_with_comments(const char *filename);
|
||||
|
||||
/* Parses first JSON value in a string, returns NULL in case of error */
|
||||
JSON_Value * json_parse_string(const char *string);
|
||||
JSON_Value * json_parse_string(const char *string);
|
||||
|
||||
/* Parses first JSON value in a string and ignores comments (/ * * / and //),
|
||||
returns NULL in case of error */
|
||||
JSON_Value * json_parse_string_with_comments(const char *string);
|
||||
JSON_Value * json_parse_string_with_comments(const char *string);
|
||||
|
||||
/* JSON Object */
|
||||
/* Serialization */
|
||||
size_t json_serialization_size(const JSON_Value *value);
|
||||
JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes);
|
||||
JSON_Status json_serialize_to_file(const JSON_Value *value, const char *filename);
|
||||
char * json_serialize_to_string(const JSON_Value *value);
|
||||
void json_free_serialized_string(char *string); /* frees string from json_serialize_to_string */
|
||||
|
||||
/* Comparing */
|
||||
int json_value_equals(const JSON_Value *a, const JSON_Value *b);
|
||||
|
||||
/* Validation
|
||||
This is *NOT* JSON Schema. It validates json by checking if object have identically
|
||||
named fields with matching types.
|
||||
For example schema {"name":"", "age":0} will validate
|
||||
{"name":"Joe", "age":25} and {"name":"Joe", "age":25, "gender":"m"},
|
||||
but not {"name":"Joe"} or {"name":"Joe", "age":"Cucumber"}.
|
||||
In case of arrays, only first value in schema is checked against all values in tested array.
|
||||
Empty objects ({}) validate all objects, empty arrays ([]) validate all arrays,
|
||||
null validates values of every type.
|
||||
*/
|
||||
JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value);
|
||||
|
||||
/*
|
||||
* JSON Object
|
||||
*/
|
||||
JSON_Value * json_object_get_value (const JSON_Object *object, const char *name);
|
||||
const char * json_object_get_string (const JSON_Object *object, const char *name);
|
||||
JSON_Object * json_object_get_object (const JSON_Object *object, const char *name);
|
||||
JSON_Array * json_object_get_array (const JSON_Object *object, const char *name);
|
||||
double json_object_get_number (const JSON_Object *object, const char *name);
|
||||
int json_object_get_boolean(const JSON_Object *object, const char *name);
|
||||
double json_object_get_number (const JSON_Object *object, const char *name); /* returns 0 on fail */
|
||||
int json_object_get_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
|
||||
|
||||
/* dotget functions enable addressing values with dot notation in nested objects,
|
||||
just like in structs or c++/java/c# objects (e.g. objectA.objectB.value).
|
||||
@ -77,30 +107,95 @@ JSON_Value * json_object_dotget_value (const JSON_Object *object, const char *
|
||||
const char * json_object_dotget_string (const JSON_Object *object, const char *name);
|
||||
JSON_Object * json_object_dotget_object (const JSON_Object *object, const char *name);
|
||||
JSON_Array * json_object_dotget_array (const JSON_Object *object, const char *name);
|
||||
double json_object_dotget_number (const JSON_Object *object, const char *name);
|
||||
int json_object_dotget_boolean(const JSON_Object *object, const char *name);
|
||||
double json_object_dotget_number (const JSON_Object *object, const char *name); /* returns 0 on fail */
|
||||
int json_object_dotget_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
|
||||
|
||||
/* Functions to get available names */
|
||||
size_t json_object_get_count(const JSON_Object *object);
|
||||
const char * json_object_get_name (const JSON_Object *object, size_t index);
|
||||
|
||||
/* JSON Array */
|
||||
/* Creates new name-value pair or frees and replaces old value with new one. */
|
||||
JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value);
|
||||
JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string);
|
||||
JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number);
|
||||
JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean);
|
||||
JSON_Status json_object_set_null(JSON_Object *object, const char *name);
|
||||
|
||||
/* Works like dotget functions, but creates whole hierarchy if necessary. */
|
||||
JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value);
|
||||
JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, const char *string);
|
||||
JSON_Status json_object_dotset_number(JSON_Object *object, const char *name, double number);
|
||||
JSON_Status json_object_dotset_boolean(JSON_Object *object, const char *name, int boolean);
|
||||
JSON_Status json_object_dotset_null(JSON_Object *object, const char *name);
|
||||
|
||||
/* Frees and removes name-value pair */
|
||||
JSON_Status json_object_remove(JSON_Object *object, const char *name);
|
||||
|
||||
/* Works like dotget function, but removes name-value pair only on exact match. */
|
||||
JSON_Status json_object_dotremove(JSON_Object *object, const char *key);
|
||||
|
||||
/* Removes all name-value pairs in object */
|
||||
JSON_Status json_object_clear(JSON_Object *object);
|
||||
|
||||
/*
|
||||
*JSON Array
|
||||
*/
|
||||
JSON_Value * json_array_get_value (const JSON_Array *array, size_t index);
|
||||
const char * json_array_get_string (const JSON_Array *array, size_t index);
|
||||
JSON_Object * json_array_get_object (const JSON_Array *array, size_t index);
|
||||
JSON_Array * json_array_get_array (const JSON_Array *array, size_t index);
|
||||
double json_array_get_number (const JSON_Array *array, size_t index);
|
||||
int json_array_get_boolean(const JSON_Array *array, size_t index);
|
||||
double json_array_get_number (const JSON_Array *array, size_t index); /* returns 0 on fail */
|
||||
int json_array_get_boolean(const JSON_Array *array, size_t index); /* returns -1 on fail */
|
||||
size_t json_array_get_count (const JSON_Array *array);
|
||||
|
||||
/* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist.
|
||||
* Order of values in array may change during execution. */
|
||||
JSON_Status json_array_remove(JSON_Array *array, size_t i);
|
||||
|
||||
/* Frees and removes from array value at given index and replaces it with given one.
|
||||
* Does nothing and returns JSONFailure if index doesn't exist. */
|
||||
JSON_Status json_array_replace_value(JSON_Array *array, size_t i, JSON_Value *value);
|
||||
JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char* string);
|
||||
JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number);
|
||||
JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean);
|
||||
JSON_Status json_array_replace_null(JSON_Array *array, size_t i);
|
||||
|
||||
/* Frees and removes all values from array */
|
||||
JSON_Status json_array_clear(JSON_Array *array);
|
||||
|
||||
/* Appends new value at the end of array. */
|
||||
JSON_Status json_array_append_value(JSON_Array *array, JSON_Value *value);
|
||||
JSON_Status json_array_append_string(JSON_Array *array, const char *string);
|
||||
JSON_Status json_array_append_number(JSON_Array *array, double number);
|
||||
JSON_Status json_array_append_boolean(JSON_Array *array, int boolean);
|
||||
JSON_Status json_array_append_null(JSON_Array *array);
|
||||
|
||||
/*
|
||||
*JSON Value
|
||||
*/
|
||||
JSON_Value * json_value_init_object (void);
|
||||
JSON_Value * json_value_init_array (void);
|
||||
JSON_Value * json_value_init_string (const char *string); /* copies passed string */
|
||||
JSON_Value * json_value_init_number (double number);
|
||||
JSON_Value * json_value_init_boolean(int boolean);
|
||||
JSON_Value * json_value_init_null (void);
|
||||
JSON_Value * json_value_deep_copy (const JSON_Value *value);
|
||||
void json_value_free (JSON_Value *value);
|
||||
|
||||
/* JSON Value */
|
||||
JSON_Value_Type json_value_get_type (const JSON_Value *value);
|
||||
JSON_Object * json_value_get_object (const JSON_Value *value);
|
||||
JSON_Array * json_value_get_array (const JSON_Value *value);
|
||||
const char * json_value_get_string (const JSON_Value *value);
|
||||
double json_value_get_number (const JSON_Value *value);
|
||||
int json_value_get_boolean(const JSON_Value *value);
|
||||
void json_value_free (JSON_Value *value);
|
||||
|
||||
/* Same as above, but shorter */
|
||||
JSON_Value_Type json_type (const JSON_Value *value);
|
||||
JSON_Object * json_object (const JSON_Value *value);
|
||||
JSON_Array * json_array (const JSON_Value *value);
|
||||
const char * json_string (const JSON_Value *value);
|
||||
double json_number (const JSON_Value *value);
|
||||
int json_boolean(const JSON_Value *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
154
tests.c
Normal file → Executable file
154
tests.c
Normal file → Executable file
@ -20,6 +20,9 @@
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "parson.h"
|
||||
|
||||
@ -30,53 +33,68 @@
|
||||
#define TEST(A) printf("%-72s-",#A); \
|
||||
if(A){puts(" OK");tests_passed++;} \
|
||||
else{puts(" FAIL");tests_failed++;}
|
||||
#define STREQ(A, B) (A && B ? strcmp(A, B) == 0 : 0)
|
||||
#define STREQ(A, B) ((A) && (B) ? strcmp((A), (B)) == 0 : 0)
|
||||
|
||||
|
||||
void test_suite_1(void);
|
||||
void test_suite_2(JSON_Value *value);
|
||||
void test_suite_1(void); /* Test 3 files from json.org + serialization*/
|
||||
void test_suite_2(JSON_Value *value); /* Test correctness of parsed values */
|
||||
void test_suite_2_no_comments(void);
|
||||
void test_suite_2_with_comments(void);
|
||||
void test_suite_3(void);
|
||||
void test_suite_3(void); /* Test incorrect values */
|
||||
void test_suite_4(void); /* Test deep copy funtion */
|
||||
void test_suite_5(void); /* Test building json values from scratch */
|
||||
void test_suite_6(void); /* Test value comparing verification */
|
||||
void test_suite_7(void); /* Test schema validation */
|
||||
void test_suite_8(void); /* Test serialization to file */
|
||||
|
||||
char *read_file(const char *filename);
|
||||
void print_commits_info(const char *username, const char *repo);
|
||||
void persistence_example(void);
|
||||
void serialization_example(void);
|
||||
|
||||
static int tests_passed;
|
||||
static int tests_failed;
|
||||
|
||||
int main() {
|
||||
/* Example function from readme file: */
|
||||
/* Example functions from readme file: */
|
||||
/* print_commits_info("torvalds", "linux"); */
|
||||
/* serialization_example(); */
|
||||
/* persistence_example(); */
|
||||
test_suite_1();
|
||||
test_suite_2_no_comments();
|
||||
test_suite_2_with_comments();
|
||||
test_suite_3();
|
||||
test_suite_4();
|
||||
test_suite_5();
|
||||
test_suite_6();
|
||||
test_suite_7();
|
||||
test_suite_8();
|
||||
printf("Tests failed: %d\n", tests_failed);
|
||||
printf("Tests passed: %d\n", tests_passed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 3 test files from json.org */
|
||||
void test_suite_1(void) {
|
||||
JSON_Value *val;
|
||||
TEST((val = json_parse_file("tests/test_1_1.txt")) != NULL);
|
||||
TEST(json_value_equals(json_parse_string(json_serialize_to_string(val)), val));
|
||||
if (val) { json_value_free(val); }
|
||||
TEST((val = json_parse_file("tests/test_1_2.txt")) != NULL);
|
||||
TEST(json_value_equals(json_parse_string(json_serialize_to_string(val)), val));
|
||||
if (val) { json_value_free(val); }
|
||||
TEST((val = json_parse_file("tests/test_1_3.txt")) != NULL);
|
||||
TEST(json_value_equals(json_parse_string(json_serialize_to_string(val)), val));
|
||||
if (val) { json_value_free(val); }
|
||||
|
||||
TEST((val = json_parse_file_with_comments("tests/test_1_1.txt")) != NULL);
|
||||
TEST(json_value_equals(json_parse_string(json_serialize_to_string(val)), val));
|
||||
if (val) { json_value_free(val); }
|
||||
TEST((val = json_parse_file_with_comments("tests/test_1_2.txt")) != NULL);
|
||||
TEST(json_value_equals(json_parse_string(json_serialize_to_string(val)), val));
|
||||
if (val) { json_value_free(val); }
|
||||
TEST((val = json_parse_file_with_comments("tests/test_1_3.txt")) != NULL);
|
||||
TEST(json_value_equals(json_parse_string(json_serialize_to_string(val)), val));
|
||||
if (val) { json_value_free(val); }
|
||||
|
||||
}
|
||||
|
||||
/* Testing correctness of parsed values */
|
||||
void test_suite_2(JSON_Value *root_value) {
|
||||
JSON_Object *root_object;
|
||||
JSON_Array *array;
|
||||
@ -125,11 +143,11 @@ void test_suite_2(JSON_Value *root_value) {
|
||||
TEST(json_object_dotget_value(root_object, "") == NULL);
|
||||
|
||||
array = json_object_dotget_array(root_object, "object.nested array");
|
||||
TEST(array != NULL);
|
||||
TEST(json_array_get_count(array) > 1);
|
||||
if (array != NULL && json_array_get_count(array) > 1) {
|
||||
TEST(STREQ(json_array_get_string(array, 0), "lorem"));
|
||||
TEST(STREQ(json_array_get_string(array, 1), "ipsum"));
|
||||
} else {
|
||||
tests_failed++;
|
||||
}
|
||||
TEST(json_object_dotget_boolean(root_object, "nested true"));
|
||||
|
||||
@ -142,22 +160,21 @@ void test_suite_2(JSON_Value *root_value) {
|
||||
void test_suite_2_no_comments(void) {
|
||||
const char *filename = "tests/test_2.txt";
|
||||
JSON_Value *root_value = NULL;
|
||||
printf("Testing %s:\n", filename);
|
||||
root_value = json_parse_file(filename);
|
||||
test_suite_2(root_value);
|
||||
TEST(json_value_equals(root_value, json_parse_string(json_serialize_to_string(root_value))));
|
||||
json_value_free(root_value);
|
||||
}
|
||||
|
||||
void test_suite_2_with_comments(void) {
|
||||
const char *filename = "tests/test_2_comments.txt";
|
||||
JSON_Value *root_value = NULL;
|
||||
printf("Testing %s:\n", filename);
|
||||
root_value = json_parse_file_with_comments(filename);
|
||||
test_suite_2(root_value);
|
||||
TEST(json_value_equals(root_value, json_parse_string(json_serialize_to_string(root_value))));
|
||||
json_value_free(root_value);
|
||||
}
|
||||
|
||||
/* Testing values, on which parsing should fail */
|
||||
void test_suite_3(void) {
|
||||
char nested_20x[] = "[[[[[[[[[[[[[[[[[[[[\"hi\"]]]]]]]]]]]]]]]]]]]]";
|
||||
puts("Testing invalid strings:");
|
||||
@ -205,6 +222,80 @@ void test_suite_3(void) {
|
||||
TEST(json_parse_string("[\"\\uDF67\\uD834\"]") == NULL); /* wrong order surrogate pair */
|
||||
}
|
||||
|
||||
void test_suite_4() {
|
||||
const char *filename = "tests/test_2.txt";
|
||||
JSON_Value *a = NULL, *a_copy = NULL;
|
||||
printf("Testing %s:\n", filename);
|
||||
a = json_parse_file(filename);
|
||||
TEST(json_value_equals(a, a)); /* test equality test */
|
||||
a_copy = json_value_deep_copy(a);
|
||||
TEST(a_copy != NULL);
|
||||
TEST(json_value_equals(a, a_copy));
|
||||
}
|
||||
|
||||
void test_suite_5(void) {
|
||||
JSON_Value *val_from_file = json_parse_file("tests/test_5.txt");
|
||||
|
||||
JSON_Value *val = json_value_init_object();
|
||||
JSON_Object *obj = json_value_get_object(val);
|
||||
TEST(json_object_set_string(obj, "first", "John") == JSONSuccess);
|
||||
TEST(json_object_set_string(obj, "last", "Doe") == JSONSuccess);
|
||||
TEST(json_object_set_number(obj, "age", 25) == JSONSuccess);
|
||||
TEST(json_object_set_boolean(obj, "registered", 1) == JSONSuccess);
|
||||
TEST(json_object_set_value(obj, "interests", json_value_init_array()) == JSONSuccess);
|
||||
TEST(json_array_append_string(json_object_get_array(obj, "interests"), "Writing") == JSONSuccess);
|
||||
TEST(json_array_append_string(json_object_get_array(obj, "interests"), "Mountain Biking") == JSONSuccess);
|
||||
TEST(json_array_replace_string(json_object_get_array(obj, "interests"), 0, "Reading") == JSONSuccess);
|
||||
TEST(json_object_dotset_string(obj, "favorites.color", "blue") == JSONSuccess);
|
||||
TEST(json_object_dotset_string(obj, "favorites.sport", "running") == JSONSuccess);
|
||||
TEST(json_object_dotset_string(obj, "favorites.fruit", "apple") == JSONSuccess);
|
||||
TEST(json_object_dotremove(obj, "favorites.fruit") == JSONSuccess);
|
||||
TEST(json_object_set_string(obj, "utf string", "\\u006corem\\u0020ipsum") == JSONSuccess);
|
||||
TEST(json_object_set_string(obj, "utf-8 string", "あいうえお") == JSONSuccess);
|
||||
TEST(json_object_set_string(obj, "surrogate string", "lorem\\uD834\\uDD1Eipsum\\uD834\\uDF67lorem") == JSONSuccess);
|
||||
TEST(json_value_equals(val_from_file, val));
|
||||
}
|
||||
|
||||
void test_suite_6(void) {
|
||||
const char *filename = "tests/test_2.txt";
|
||||
JSON_Value *a = NULL;
|
||||
JSON_Value *b = NULL;
|
||||
a = json_parse_file(filename);
|
||||
b = json_parse_file(filename);
|
||||
TEST(json_value_equals(a, b));
|
||||
json_object_set_string(json_object(a), "string", "eki");
|
||||
TEST(!json_value_equals(a, b));
|
||||
a = json_value_deep_copy(b);
|
||||
TEST(json_value_equals(a, b));
|
||||
json_array_append_number(json_object_get_array(json_object(b), "string array"), 1337);
|
||||
TEST(!json_value_equals(a, b));
|
||||
}
|
||||
|
||||
void test_suite_7(void) {
|
||||
JSON_Value *val_from_file = json_parse_file("tests/test_5.txt");
|
||||
JSON_Value *schema = json_value_init_object();
|
||||
JSON_Object *schema_obj = json_value_get_object(schema);
|
||||
json_object_set_string(schema_obj, "first", "");
|
||||
json_object_set_string(schema_obj, "last", "");
|
||||
json_object_set_number(schema_obj, "age", 0);
|
||||
json_object_set_null(schema_obj, "favorites");
|
||||
TEST(json_validate(schema, val_from_file) == JSONSuccess);
|
||||
json_object_set_string(schema_obj, "age", "");
|
||||
TEST(json_validate(schema, val_from_file) == JSONFailure);
|
||||
}
|
||||
|
||||
void test_suite_8(void) {
|
||||
const char *filename = "tests/test_2.txt";
|
||||
const char *temp_filename = "tests/test_2_serialized.txt";
|
||||
JSON_Value *a = NULL;
|
||||
JSON_Value *b = NULL;
|
||||
a = json_parse_file(filename);
|
||||
TEST(json_serialize_to_file(a, temp_filename) == JSONSuccess);
|
||||
b = json_parse_file(temp_filename);
|
||||
TEST(json_value_equals(a, b));
|
||||
remove(temp_filename);
|
||||
}
|
||||
|
||||
void print_commits_info(const char *username, const char *repo) {
|
||||
JSON_Value *root_value;
|
||||
JSON_Array *commits;
|
||||
@ -244,3 +335,36 @@ void print_commits_info(const char *username, const char *repo) {
|
||||
json_value_free(root_value);
|
||||
system(cleanup_command);
|
||||
}
|
||||
|
||||
void persistence_example(void) {
|
||||
JSON_Value *schema = json_parse_string("{\"name\":\"\"}");
|
||||
JSON_Value *user_data = json_parse_file("user_data.json");
|
||||
char buf[256];
|
||||
const char *name = NULL;
|
||||
if (!user_data || json_validate(schema, user_data) == JSONSuccess) {
|
||||
puts("Enter your name:");
|
||||
scanf("%s", buf);
|
||||
user_data = json_value_init_object();
|
||||
json_object_set_string(json_object(user_data), "name", buf);
|
||||
json_serialize_to_file(user_data, "user_data.json");
|
||||
}
|
||||
name = json_object_get_string(json_object(user_data), "name");
|
||||
printf("Hello, %s.", name);
|
||||
json_value_free(schema);
|
||||
json_value_free(user_data);
|
||||
return;
|
||||
}
|
||||
|
||||
void serialization_example(void) {
|
||||
JSON_Value *root_value = json_value_init_object();
|
||||
JSON_Object *root_object = json_value_get_object(root_value);
|
||||
char *serialized_string = NULL;
|
||||
json_object_set_string(root_object, "name", "John Smith");
|
||||
json_object_set_number(root_object, "age", 25);
|
||||
json_object_dotset_string(root_object, "address.city", "Cupertino");
|
||||
json_object_dotset_value(root_object, "contact.emails",
|
||||
json_parse_string("[\"email@example.com\", \"email2@example.com\"]"));
|
||||
serialized_string = json_serialize_to_string(root_value);
|
||||
puts(serialized_string);
|
||||
json_free_serialized_string(serialized_string);
|
||||
}
|
||||
|
0
tests/test_1_1.txt
Normal file → Executable file
0
tests/test_1_1.txt
Normal file → Executable file
0
tests/test_1_2.txt
Normal file → Executable file
0
tests/test_1_2.txt
Normal file → Executable file
0
tests/test_1_3.txt
Normal file → Executable file
0
tests/test_1_3.txt
Normal file → Executable file
0
tests/test_2.txt
Normal file → Executable file
0
tests/test_2.txt
Normal file → Executable file
0
tests/test_2_comments.txt
Normal file → Executable file
0
tests/test_2_comments.txt
Normal file → Executable file
14
tests/test_5.txt
Normal file
14
tests/test_5.txt
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"first": "John",
|
||||
"last": "Doe",
|
||||
"age": 25,
|
||||
"registered": true,
|
||||
"interests": [ "Reading", "Mountain Biking" ],
|
||||
"favorites": {
|
||||
"color": "blue",
|
||||
"sport": "running"
|
||||
},
|
||||
"utf string" : "\u006corem\u0020ipsum",
|
||||
"utf-8 string": "あいうえお",
|
||||
"surrogate string": "lorem\uD834\uDD1Eipsum\uD834\uDF67lorem"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user