mirror of
https://github.com/sigmasternchen/libargo
synced 2025-03-15 05:08:54 +00:00
added documentation for marshaller
This commit is contained in:
parent
a1cf81a8ee
commit
cc311dbcdf
1 changed files with 204 additions and 11 deletions
215
README.md
215
README.md
|
@ -1,17 +1,27 @@
|
|||
# Cson
|
||||
## JSON Library for C
|
||||
|
||||
[](https://github.com/overflowerror/Cson/actions/workflows/test-suite.yml)
|
||||
|
||||
## JSON Library for C
|
||||
|
||||
The purpose of this project is to provide a convinient way to interact with JSON data in C.
|
||||
|
||||
Functions for constructing, interacting, encoding and decoding of JSON data can be accessed through the `json.h` header. Additionally this projects includes a marshaller generater that takes a struct definitions and generates functions to encode or decoded these structs.
|
||||
|
||||
### Disclaimer
|
||||
|
||||
This library was originaly just a finger exercise to see if I could build a JSON lib from scratch. That also means that I can't guarantee for anything - treat it as highly unstable.
|
||||
|
||||
Nevertheless you are welcome to use or modify the code as you like. I also appriciate pull requests.
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
For the base functionallity there are no dependencies.
|
||||
|
||||
The `Makefile` is build for `gcc` but did not use any GNU-specific functionality so `clang` - or any other C-compiler for that matter - would probably work as well.
|
||||
The marshaller generator needs `lex` and `yacc`. The `Makefile` uses `flex` and `bison` but I think I only used `lex` and `yacc` functionality respectively.
|
||||
Also a `gcc` compatible compiler (or a compiler that supports GCC function attributes) is need. So `clang` should work too.
|
||||
|
||||
The `Makefile` is build for `gcc`
|
||||
|
||||
## Build
|
||||
|
||||
|
@ -21,17 +31,26 @@ Static lib:
|
|||
Shared lib:
|
||||
`make libcson.so`
|
||||
|
||||
Demo program:
|
||||
`make demo`
|
||||
Base Demo program:
|
||||
`make json-demo`
|
||||
|
||||
Test program:
|
||||
`make test`
|
||||
Base Test program:
|
||||
`make json-test`
|
||||
|
||||
Marshaller program:
|
||||
`make marshaller-gen`
|
||||
|
||||
Marshaller Demo program:
|
||||
`make marshaller-demo`
|
||||
|
||||
Marshaller Test program:
|
||||
`make marshaller-test`
|
||||
|
||||
### Test
|
||||
|
||||
To run the test suit just build the test program (see above) and run `./test`
|
||||
To run the test suit just run `make tests`
|
||||
|
||||
## Usage
|
||||
## Usage (Base Functionallity)
|
||||
|
||||
### General
|
||||
|
||||
|
@ -150,7 +169,181 @@ The string will be stored on the heap and has to be freed manually.
|
|||
|
||||
The function `json_print(jsonValue_t*)` will display the structure and types of the value in the terminal (stdout).
|
||||
|
||||
## Demo
|
||||
`json_free(jsonValue_t*)` is used to recursively free a JSON value.
|
||||
|
||||
The file src/demo.c provides a few examples on how the library could be used.
|
||||
### Demo
|
||||
|
||||
The file demo/json.c provides a few examples on how the library could be used.
|
||||
|
||||
To build the demo just use `make json-demo`
|
||||
|
||||
## Usage (Marshaller)
|
||||
|
||||
### Build
|
||||
|
||||
To build to marshaller generator use the following command:
|
||||
|
||||
`make marshaller-gen`
|
||||
|
||||
### Marshaller-Gen Synopsis
|
||||
|
||||
```
|
||||
./marshaller-gen [-o OUTPUT_FILE] {INPUT_FILE}
|
||||
```
|
||||
|
||||
The marshaller generator takes any number of `INPUT_FILE`S (C header files) that contain the struct definitions. If no input file is given `stdin` is used.
|
||||
|
||||
Using the `-o` option the `OUTPUT_FILE` for the generated C code can be specified. If no OUTPUT_FILE is given `stdout` is used.
|
||||
|
||||
### Input Specification
|
||||
|
||||
Although the `INPUT_FILE`s are just normal C header files the syntax is quite restricted. It is recommended to only put the struct definitions in the input files. Typedefs can be used as long as the struct definition is part of the typedef.
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
// this is okay
|
||||
struct name {};
|
||||
```
|
||||
|
||||
```
|
||||
// this is okay
|
||||
typedef struct name {} name_t;
|
||||
```
|
||||
|
||||
```
|
||||
// this is okay
|
||||
typedef struct {} name_t;
|
||||
```
|
||||
|
||||
```
|
||||
// this is not
|
||||
struct name {};
|
||||
typedef struct name name_t;
|
||||
|
||||
```
|
||||
For this library a typedef is considered an alias of the struct type.
|
||||
|
||||
|
||||
Comments and preprocessor statements will be ignored. Using other language constructs will cause a syntax error.
|
||||
|
||||
#### Supported Types
|
||||
|
||||
integer types: `char`, `short`, `int`, `long`, `long long`
|
||||
|
||||
float types: `float`, `double`
|
||||
|
||||
string types: `char*`, `const char*`
|
||||
|
||||
(While supported using `const` does not make sense since all data is stored on the heap.)
|
||||
|
||||
struct types: any struct or typedef struct type that has a marshaller
|
||||
|
||||
array types: any of the types above; see Lists for details
|
||||
|
||||
pointer types: only single pointers to types that are not lists are allowed (`struct s*` is okay, `int***` is not)
|
||||
|
||||
### Compiling The Output File
|
||||
|
||||
The marshaller generator assumes that `json.h` as well as all input files are in the include path. So make sure to compile the `OUTPUT_FILE` with the correct `-I` options.
|
||||
|
||||
The result has to be linked with `libcson.a` or `libcson.so`.
|
||||
|
||||
### Marshalling
|
||||
|
||||
To encode a struct as JSON just use the `json_marshall()` function (declared in `marshaller.h`). This function takes 2 arguments and returns the marshalled struct as a string.
|
||||
|
||||
The argument is the type of the struct. The second argument is a pointer to the struct.
|
||||
|
||||
Example:
|
||||
|
||||
Let's assume the struct looks like this:
|
||||
```
|
||||
struct s {
|
||||
int i;
|
||||
char* s;
|
||||
};
|
||||
```
|
||||
|
||||
Then the call to `json_marshall()` looks something like this:
|
||||
```
|
||||
// obj is the struct to be marshalled
|
||||
struct s obj = { .i = 42, .s = "hello World" };
|
||||
|
||||
char* result = json_marshall(struct s, &obj);
|
||||
|
||||
free(result);
|
||||
```
|
||||
|
||||
This also works if there is a typedef for the struct.
|
||||
|
||||
### Unmarshalling
|
||||
|
||||
To decode a JSON string into a struct the `json_unmarshall()` function is used.
|
||||
|
||||
It works similar to `json_marshall()`. The difference is that here the second parameter is the input string and the result is a struct pointer.
|
||||
|
||||
Example (using the same struct definition as above):
|
||||
|
||||
```
|
||||
struct s* obj = json_unmarshall(struct s, "{\"i\":1337,\"s\":\"foobar\"}");
|
||||
|
||||
json_free_struct(struct s, obj);
|
||||
```
|
||||
|
||||
The function `json_free_struct()` is used to recursively free the resouses used in the struct.
|
||||
|
||||
### Lists
|
||||
|
||||
The marshaller can also deal with arrays (lists) - either as struct members or for marshalling/unmarshalling collections.
|
||||
|
||||
Note: To use lists as struct members they have to be declared as a double pointer of the type of the list member. For example: If it is an integer list the struct member has to be declared as `int**`.
|
||||
|
||||
Lists are represented as an array of pointers. Similar to `envoiron` the length of the list is given implicitly: The pointer after the last element is NULL.
|
||||
|
||||
Example:
|
||||
```
|
||||
const char* array[3];
|
||||
array[0] = "foo";
|
||||
array[1] = "bar";
|
||||
array[2] = NULL;
|
||||
```
|
||||
|
||||
To iterate over such a list use a for loop similar to this one:
|
||||
```
|
||||
for (size_t i = 0; array[i] != NULL; i++) {
|
||||
printf("%s\n", array[i]);
|
||||
}
|
||||
```
|
||||
|
||||
#### Marshalling
|
||||
|
||||
To encode a list use the `json_marshall_array()` function that works similar to `json_marshall()`. If a list is part of a struct the marshalling is handled by the struct marshaller.
|
||||
|
||||
#### Unmarshalling
|
||||
|
||||
To decode a list use the `json_unmarshall_array()` function that works similar to `json_unmarshall()`. If a list is part of a struct the unmarshalling is handled by the struct marshaller.
|
||||
|
||||
To free a decoded list use the `json_free_array()` function that works similar to `json_free_struct()`. If a list is part of a struct the freeing is handled by the struct marshaller.
|
||||
|
||||
If the list has a primitive type (i.e. not a struct, not a list; Note: For this strings are also considered primitive) use the `json_free_prim_array()` function. It only has the list as an argument.
|
||||
|
||||
### Demo
|
||||
|
||||
The file demo/marshaller.c provides an example on how the marshaller could be used.
|
||||
|
||||
To build the demo just use `make marshaller-demo`
|
||||
|
||||
### Error Messages
|
||||
|
||||
Message | Meaning
|
||||
-----------------
|
||||
`file limit reached` | By default marshaller-gen only accepts 10 input files. This can be changed in the constant `MAX_FILES` in codegen.c.
|
||||
`lexical error in line` | The marshaller generator only supports a very limited syntax for the header file. Make sure only have structs or typedefs in the input files. For more details see Input Specification.
|
||||
`syntax error` | See `lexical error in line`.
|
||||
`... not yet supported` | The respective feature or type is not yet implemented.
|
||||
`... not supported` | The respective feature or type is not supported and probably won't ever be.
|
||||
`const char* struct members are discouraged` | The use of `const char*` doesn't make sense because all the data will be on the heap anyway. `const` would just confuse.
|
||||
`double pointer type; assuming dynamic array` | Not an error. Just a hint that double pointer types will be assumed to be dynamic arrays - which may not be but the user intended.
|
||||
`unknown type` | The marshaller for the given type is not present (not linked).
|
||||
`marshaller for name already present` | The type has multiple marshallers.
|
||||
|
|
Loading…
Reference in a new issue