Browse Source

Init commit in new repo

Joachim M. Giæver 7 years ago
parent
commit
b7f86921bb
7 changed files with 2015 additions and 2 deletions
  1. 19 0
      Makefile
  2. 13 2
      README.md
  3. 17 0
      common.c
  4. 6 0
      common.h
  5. BIN
      json-test
  6. 1502 0
      json.c
  7. 458 0
      json.h

+ 19 - 0
Makefile

@@ -0,0 +1,19 @@
+# MAKEFILE
+
+CC=gcc
+CCOPTS=-Wall -g
+CCL=-lpthread -lm 
+
+JSON_SRC=json.c
+JSON_HEADERS=json.h
+
+COMMON_SRC=common.c
+COMMON_HEADER=common.h
+
+all: json-test
+
+json-test: $(JSON_SRC) $(COMMON_SRC) $(JSON_HEADERS) $(COMMON_HEADER) Makefile
+	$(CC) $(CCOPTS) $(JSON_SRC) $(COMMON_SRC) -o $@ -D_DEBUG_JSON=1 -include $(JSON_HEADERS) $(COMMON_HEADER) $(CCL)
+
+clean:
+	rm -f *~ *.o *.exe *.stackdump sql-* json-* *.dot* *.txt

+ 13 - 2
README.md

@@ -1,3 +1,14 @@
-# JSON-creator
+JSON creator 
+====
+This is a C implemention to create JSON-objects in C.
 
-This is a C implemention to create JSON-objects in C.
+More to come. Stay tuned. 
+
+Easy to use. Try it out:
+
+```
+make
+$ ./sql-test
+```
+
+Enjoy.

+ 17 - 0
common.c

@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+void errandend( const char *format, ... ) {
+
+	va_list vargs;
+
+	va_start( vargs, format );
+	
+	printf( " | " );
+    printf( format, vargs );
+    
+    va_end( vargs );
+
+    exit( EXIT_FAILURE );
+}

+ 6 - 0
common.h

@@ -0,0 +1,6 @@
+#ifndef _COMMON_H
+#define _COMMON_H
+
+void errandend( const char *format, ... );
+
+#endif

BIN
json-test


+ 1502 - 0
json.c

@@ -0,0 +1,1502 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include "common.h"
+#include "json.h"
+
+/**
+ * TODO: 1.	Redo the json_obj structure to be able to hold several.
+ * 			Now only hols several members and pairs. Can hold several.
+ *		 2. Save to file
+ *		 3. Encoding of values; e.g unicode values and special chars.
+ *		 4. json_from_file; parser?
+ **/
+
+/**
+ * Structure: json_type
+ * Typedef: json_type_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type: 		Type of an JSON-entry.
+ *
+ * Description:
+ * 	Holds the type of an JSON-entry.
+ **/
+struct json_type {
+	json_types_t type;
+};
+
+/**
+ * JSON-entry types
+ **/
+
+/**
+ * Structure: 
+ * Typedef: 
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type:		Entry type (MUST BE FIRST)
+ *	json_mem_t *members:	JSON-meners entries.
+ *	print_type_t ptype:		Print type, eg Pretty print.
+ *	int code:				Status code.
+ *
+ * Description:
+ * 	Defines an JSON-object.
+ **/
+struct json_obj {
+	json_types_t type;
+	json_mem_t *members;
+	print_type_t ptype;
+	json_printf_t *pfunc;
+	FILE *jfile;
+	int code;
+};
+
+/**
+ * Structure: json_mem
+ * Typedef: json_mem_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type:		Entry type (MUST BE FIRST)
+ *	void *entry:			Containing entry. Either pair or new member
+ *	void *next:				Simblings; other members or pairs in parent.
+ *
+ * Description:
+ * 	Defines an JSON-member entry
+ **/
+struct json_mem {
+	json_types_t type;
+	void *entry;
+	void *next;
+};
+
+/**
+ * Structure: json_elem
+ * Typedef: json_elem_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type:		Entry type (MUST BE FIRST).
+ *	void *entry:			Containing entry. Either value or new element.
+ *	void *next:				Simblings; other elements in parent.
+ *
+ * Description:
+ *  Defines an JSON-element entry.
+ **/
+struct json_elem {
+	json_types_t type;
+	void *entry;
+	void *next;
+};
+
+/**
+ * Structure: json_pair
+ * Typedef: json_pair_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type:		Entry type (MUST BE FIRST).
+ *	char *str:				String specifier.
+ *	json_val_t *value;		Containing entry, only value.
+ *	void *next:				Simblings; other members or pairs in parent.
+ *
+ * Description:
+ * 
+ **/
+struct json_pair {
+	json_types_t type; 
+	char *str;
+	json_val_t *value;
+	void *next;
+};
+
+/**
+ * Structure: json_arr
+ * Typedef: json_arr_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type: 		Entry type (MUST BE FIRST).
+ *	void *entry:			Containing entry, only elements.
+ *
+ * Description:
+ *  Defines a JSON-array entry.
+ **/
+struct json_arr {
+	json_types_t type;
+	json_elem_t *entry; 
+};
+
+/**
+ * Structure: json_val
+ * Typedef: json_val_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type:		Entry type (MUST BE FIRST).
+ * 	json_types_t sub_type:	Type of the sub entry, eg JSON_INT, _CHAR etc
+ * 	void *value:			The actual entry
+ *
+ * Description:
+ * 
+ **/
+struct json_val {
+	json_types_t type;
+	json_types_t sub_type;
+	void *value;
+};
+
+/**
+ * Function: json_ptype
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - print_type_t ptype: 	Print type
+ *
+ * Description:
+ * Validates and sets the print type, e.g
+ * Pretty Print, Print etc. (File save not implemented)
+ *
+ * Returns: int, the print type value
+ **/
+static int json_ptype( print_type_t ptype );
+
+/**
+ * Function: json_set_code
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:	JSON-object to set status for
+ * - int code: 			The status code to set
+ *
+ * Description:
+ * Sets the status code of the last event
+ * of types related to the JSON-object.
+ *
+ * Returns: int, the newly set code
+ **/
+static int json_set_code( json_obj_t *jobj, int code );
+
+/**
+ * Function: json_get_type
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - void *entry: 		The JSON-entry to read type of
+ *
+ * Description:
+ * Returns the type of the JSON-entry.
+ *
+ * Returns: json_types_t, the type
+ **/
+static json_types_t json_get_type( void *entry );
+
+/**
+ * Function: json_is_type
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - void *entry: 		The JSON-entry to check
+ * - json_types_t:		The JSON-type compare against
+ *
+ * Description:
+ * Checks the equality of the type of the entry
+ * agains the given type.
+ *
+ * Returns: int, 1 on success, 0 on failure
+ **/
+static int json_is_type( void *entry, json_types_t jtype );
+
+/**
+ * Function: json_uninit_obj
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj: 	The JSON-object (parent of obj)
+ * - void *obj:			Any kind of object within parent
+ *
+ * Description:
+ * Checks if the JSON-object is uninitialized. Checks
+ * both the root (jobj) and sub obj.
+ *
+ * Returns: int, 1 on failure, 0 on success
+ **/
+static int json_uninit_obj( json_obj_t *jobj, void *obj );
+
+/**
+ * Function: json_val_vtype
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		Parent JSON-object
+ * - json_types_t *vtype:	The value type
+ *
+ * Description:
+ * Checks if the given type is valid as a value, for
+ * the value entry.
+ *
+ * Returns: int, 1 on success, 0 on failure
+ **/
+static int json_val_vtype( json_obj_t *jobj, json_types_t vtype );
+
+/**
+ * Function: json_insert
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		Parent JSON-obj
+ * - void *root:			Root-entry, an JSON-entry
+ * - void *entry:			New entry, valid for root-entry
+ *
+ * Description:
+ * Inserts an entry into the root, which is related 
+ * to the parent JSON-obj. Insertion method and possibilities
+ * depends on the root-entry.
+ *
+ * Returns: void *, address to newly inserte entry
+ **/
+static void *json_insert( json_obj_t *jobj, void *root, void *entry );
+
+/** Recursice functions to print the tree **/
+static void _json_out( json_obj_t *jobj, int height );
+static void _print_( json_obj_t *jobj, ... );
+static void _print_mem( json_obj_t *jobj, json_mem_t *jmem, int height );
+static void _print_pair( json_obj_t *jobj, json_pair_t *jpair, int height );
+static void _print_arr( json_obj_t *jobj, json_arr_t *jarr, int height );
+static void _print_elem( json_obj_t *jobj, json_elem_t *jelem, int height );
+static void _print_value( json_obj_t *jobj, json_val_t *jval, int height );
+static char *_print_set_newline( json_obj_t *jobj );
+static void _print_tabs_release( char *tabs );
+static char *_print_tabs( json_obj_t *jobj, int height );
+/** Silence in comments is like nothing was here */
+
+/**
+ * Function: json_create
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - char *fname:			The filename; on saving
+ 							and possible parsing - in the future.
+ * - print_type_t ptype:	Store/print type
+ *
+ * Description:
+ * Creates the main root of the JSON-structure.
+ *
+ * Returns: json_obj_t *, the mother root
+ **/
+json_obj_t *json_create( char *fname, print_type_t ptype ) {
+
+	json_obj_t *jobj = ( json_obj_t *) malloc( sizeof( json_obj_t ) );
+
+	if ( jobj == NULL )
+		errandend( "Could not allocate memory for JSON object" );
+
+	jobj->type = JSON_OBJ;
+	jobj->members = NULL;
+	jobj->ptype = json_ptype( ptype );
+
+	if ( (jobj->ptype & JSON_SAVE_FILE) == JSON_SAVE_FILE ) {
+		jobj->jfile = fopen( fname, "w+" );
+
+		if ( jobj->jfile == NULL ) {
+			printf("%s\n", fname );
+			errandend( "Could not open file for reading/writing." );
+		}
+
+		jobj->pfunc = (json_printf_t *)fprintf;
+
+	} else {
+
+		jobj->jfile = NULL;
+		jobj->pfunc = (json_printf_t *)printf;
+
+	}
+
+	json_set_code( jobj, jobj->ptype );
+
+	return jobj;
+
+}
+
+/**
+ * Function: json_destroy
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object to destroy
+ *
+ * Description:
+ * Destroys any kind of JSON-objects
+ *
+ * Returns: void
+ **/
+void json_destroy( json_obj_t *jobj ) {
+
+	if ( jobj == NULL )
+		return;
+
+	if ( jobj->members != NULL )
+		json_destroy_mem( jobj->members );
+
+	if ( jobj->jfile != NULL )
+		fclose( jobj->jfile );
+
+	free( jobj );
+
+}
+
+/**
+ * Function: json_create_obj
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ * - json_val_t *jval:		JSON-value to insert to
+ *
+ * Description:
+ * Creates a new JSON-object to insert into the 
+ * JSON-structure (only into JSON-value.).
+ *
+ * Works recursivly on children.
+ *
+ * Returns: json_obj_t *, JSON-object
+ **/
+json_obj_t *json_create_obj( json_obj_t *jobj, json_val_t *jval ) {
+
+	json_obj_t *jcobj;
+
+	if ( json_uninit_obj( jobj, jval ) ) 
+		return NULL;
+
+	jcobj = json_create( "", jobj->ptype );
+
+	if ( json_insert( jobj, jval, jobj ) != NULL )
+		return jcobj;
+
+	json_destroy( jcobj );
+
+	return NULL;
+
+}
+
+/**
+ * Function: json_create_mem
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object to insert to
+ *
+ * Description:
+ * Creates a new JSON-member and inserts it into the 
+ * JSON-object. May be any kind of JSON-object, both
+ * root or children.
+ *
+ * Returns: json_mem_t *, JSON-member
+ **/
+json_mem_t *json_create_mem( json_obj_t *jobj ) {
+
+	json_mem_t *jmem;
+
+	if ( json_has_err( jobj ) ) 
+		return NULL;
+
+	jmem = ( json_mem_t *) malloc( sizeof( json_mem_t ) );
+
+	if ( jmem == NULL ) {
+		json_set_code( jobj, JSON_NOMEM );
+		return NULL;
+	}
+
+	jmem->type = JSON_MEM;
+	jmem->entry = NULL;
+	jmem->next = NULL;
+
+	if ( json_insert( jobj, jobj, jmem ) != NULL )
+		return jmem;
+	
+	json_destroy_mem( jmem );
+
+	return NULL;
+
+}
+
+/**
+ * Function: json_destroy_mem
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_mem_t *jmem:		JSON-member to destroy
+ *
+ * Description:
+ * Destroy a JSON-member, works recursively on both simblings
+ * and children.
+ *
+ * Returns: void
+ **/
+void json_destroy_mem( json_mem_t *jmem ) {
+
+	if ( jmem == NULL )
+		return;
+
+	if ( jmem->entry != NULL ) {
+		if ( json_is_type( jmem->entry, JSON_PAIR ) )
+			json_destroy_pair( jmem->entry );
+		else
+			json_destroy_mem( jmem->entry );
+	}
+
+	if ( jmem->next != NULL ) {
+		if ( json_is_type( jmem->next, JSON_PAIR ) )
+			json_destroy_pair( jmem->next );
+		else
+			json_destroy_mem( jmem->next );
+	}
+
+	free( jmem );
+
+}
+
+/**
+ * Function: json_create_pair
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ * - json_mem_t *jmem:		JSON-member to insert to
+ *
+ * Description:
+ * Creates a new JSON-pair and inserts it into a JSON-member.
+ *
+ * Returns: json_pair_t *, JSON-pair
+ **/
+json_pair_t *json_create_pair( json_obj_t *jobj, json_mem_t *jmem, char *str ) {
+
+	json_pair_t *jpair;
+
+	if ( json_uninit_obj( jobj, jmem ) ) 
+		return NULL;
+
+	jpair = ( json_pair_t *) malloc( sizeof( json_pair_t ) );
+
+	if ( jpair == NULL ) {
+		json_set_code( jobj, JSON_NOMEM );
+		return NULL;
+	}
+
+	jpair->type = JSON_PAIR;
+	jpair->str = strdup( str );
+	jpair->value = NULL;
+	jpair->next = NULL;
+
+	if ( json_insert( jobj, jmem, jpair ) != NULL )
+		return jpair;
+		
+	json_destroy_pair( jpair );
+
+	return NULL;
+
+}
+
+/**
+ * Function: json_destroy_pair
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_pair_t *jpair:	JSON-pair to destroy
+ *
+ * Description:
+ * Destroys a JSON-pair. Works recursively on both the simblings
+ * and children.
+ *
+ * Returns: void
+ **/	
+void json_destroy_pair( json_pair_t *jpair ) {
+
+	if ( jpair == NULL )
+		return;
+
+	if ( jpair->value != NULL )
+		json_destroy_value( jpair->value );
+
+	if ( jpair->next != NULL ) {
+		if ( json_is_type( jpair->next, JSON_PAIR ) )
+			json_destroy_pair( jpair->next );
+		else
+			json_destroy_mem( jpair->next );
+	}
+
+	free( jpair->str );
+	free( jpair );
+
+}
+
+/**
+ * Function: json_create_arr
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ * - json_val_t *jval:		JSON-value to insert to
+ *
+ * Description:
+ * Creates a new JSON-array and inserts it into JSON-value.
+ *
+ * Returns: json_arr_t *, JSON-array
+ **/
+json_arr_t *json_create_arr( json_obj_t *jobj, json_val_t *jval ) {
+
+	json_arr_t *jarr;
+
+	if ( json_uninit_obj( jobj, jval ) )
+		return NULL;
+
+	jarr = ( json_arr_t *) malloc( sizeof( json_arr_t ) );
+
+	if ( jarr == NULL ) {
+		json_set_code( jobj, JSON_NOMEM );
+		return NULL;
+	}
+
+	jarr->type = JSON_ARR;
+	jarr->entry = NULL;
+
+	if ( json_insert( jobj, jval, jarr ) != NULL )
+		return jarr;
+
+	json_destroy_arr( jarr );
+
+	return NULL;
+
+}
+
+/**
+ * Function: json_destroy_arr
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_arr_t *jarr: 		JSON-array to destroy
+ *
+ * Description:
+ * Destroys a JSON-array. Works recursively on the children.
+ *
+ * Returns: void
+ **/
+void json_destroy_arr( json_arr_t *jarr ) {
+
+	if ( jarr == NULL )
+		return;
+
+	if ( jarr->entry != NULL )
+		json_destroy_elem( jarr->entry );
+
+	free( jarr );
+
+}
+
+/**
+ * Function: json_create_elem
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ * - json_arr_t *jarr: 		JSON-array to insert into
+ *
+ * Description:
+ * Creates a JSON-element and inserts it int an JSON-array.
+ *
+ * Returns: json_elem_t *, JSON-element
+ **/
+json_elem_t *json_create_elem( json_obj_t *jobj, json_arr_t *jarr ) {
+
+	json_elem_t *jelem;
+
+	if ( json_uninit_obj( jobj, jarr ) ) 
+		return NULL;
+
+	jelem = ( json_elem_t *) malloc( sizeof( json_elem_t ) );
+
+	if ( jelem == NULL ) {
+		json_set_code( jobj, JSON_NOMEM );
+		return NULL;
+	}
+
+	jelem->type = JSON_ELEM;
+	jelem->entry = NULL;
+	jelem->next = NULL;
+
+	if ( json_insert( jobj, jarr, jelem ) != NULL )
+		return jelem;
+	
+	json_destroy_elem( jelem );
+
+	return NULL;
+
+}
+
+/**
+ * Function: json_destroy_elem
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_elem_t *jelem:	JSON-element to destroy
+ *
+ * Description:
+ * Destroys a JSON-element. Works recursively on both simblings
+ * and children.
+ *
+ * Returns: void
+ **/
+void json_destroy_elem( json_elem_t *jelem ) {
+
+	if ( jelem == NULL )
+		return;
+
+	if ( jelem->entry != NULL )
+		json_destroy_value( jelem->entry );
+
+	if ( jelem->next != NULL )
+		json_destroy_elem( jelem->next );
+
+	free( jelem );
+
+}
+
+/**
+ * Function: json_insert_value
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ * - void *ins_obj:			Object or element to insert into
+ * - json_types_t vtype:	Type of the held element in value
+ * - void *entry:			Entry to store in value
+ *
+ * Description:
+ * Creates a new JSON-value and inserts it into a JSON-element or
+ * a JSON-pair. The value must also be specified. JSON-object and 
+ * JSON-array can be insert upon creation by setting entry as NULL.
+ * 
+ * Ex:
+ *
+ * // Insert this value into a JSON-pair, will contain an JSON-array
+ * json_val_t *jvalue = json_insert_value( jobj, jpair, JSON_ARR, NULL );
+ *
+ * // Create the JSON-array and insert it into the above value
+ * json_arr_t *jarr = json_create_arr( jobj, jval );
+ *
+ * Returns: json_val_t *, JSON-value
+ **/
+json_val_t *json_insert_value( json_obj_t *jobj, void *ins_obj, json_types_t vtype, void *entry ) {
+
+	json_val_t *jval;
+
+	if  ( vtype != JSON_NULL && ( ( vtype != JSON_OBJ && vtype != JSON_ARR && json_uninit_obj( jobj, entry ) ) || json_val_vtype( jobj, vtype ) < 0 ) )
+		return NULL;
+
+	jval = ( json_val_t *) malloc( sizeof( json_val_t ) );
+
+	if ( jval == NULL ) {
+		json_set_code( jobj, JSON_NOMEM );
+		return NULL;
+	}
+
+	jval->type = JSON_VAL;
+	jval->sub_type = vtype;
+
+	if ( vtype == JSON_OBJ || vtype == JSON_ARR ) {
+		/* By now; nothing to do */
+	} else {
+
+		switch( vtype ) {
+			case JSON_CHAR:
+				jval->value = strdup( (char *)entry );
+				break;
+			case JSON_INT:
+				jval->value = (int *) malloc( sizeof( int ) );
+				memcpy( jval->value, ((const void *)entry), sizeof( int ) );
+				break;
+			case JSON_FLOAT:
+				jval->value = (float *) malloc( sizeof( int ) );
+				memcpy( jval->value, ((const void *)entry), sizeof( float ) );
+				break;
+			case JSON_BOOL:
+				jval->value = strdup( *((bool *)entry) == true ? "true" : "false" );
+				break;
+			case JSON_NULL:
+				jval->value = strdup( entry == NULL ? "null" : "" );
+				break;
+			default:
+				json_set_code( jobj, JSON_INVALID_VAL_TYPE );
+				break;
+		}
+
+		json_set_code( jobj, JSON_INS_VAL_VAL );
+
+	}
+
+	if ( json_insert( jobj, ins_obj, jval ) != NULL )
+		return jval;
+
+	json_destroy_value( jval );
+
+	return NULL;
+
+}
+
+/**
+ * Function: json_destroy_value
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_val_t *jval:		JSON-value to destroy
+ *
+ * Description:
+ * Destroys a JSON-value. Works recursively on children.
+ *
+ * Returns: void
+ **/
+void json_destroy_value( json_val_t *jval ) {
+
+	if ( jval == NULL )
+		return;
+
+	switch( jval->sub_type ) {
+
+		case JSON_OBJ:
+			json_destroy( jval->value );;
+			break;
+
+		case JSON_ARR:
+			json_destroy_arr( jval->value );
+			break;
+
+		case JSON_CHAR:
+		case JSON_INT:
+		case JSON_FLOAT:
+		case JSON_BOOL:
+		case JSON_NULL:
+			free( jval->value );
+			break;
+
+		default:
+			break;
+
+	}
+
+	free( jval );
+
+}
+
+/**
+ * Function: json_has_err
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ *
+ * Description:
+ * Returns whether or not there was an error present on last event.
+ *
+ * Returns: int 0 on non errors 1 on errors
+ **/
+int json_has_err( json_obj_t *jobj ) {
+
+	if ( jobj == NULL )
+		return JSON_UNINITALIZED_OJB;
+
+	return ( jobj->code >= 0 ? 0 : 1 );
+
+}
+
+/**
+ * Function: json_last_err
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ *
+ * Description:
+ * Returns the last error code present.
+ *
+ * Returns: int, >= 0 on non errors <= 0 on errors
+ **/
+int json_last_err( json_obj_t *jobj ) {
+
+	if ( jobj == NULL )
+		return JSON_UNINITALIZED_OJB;
+
+	return jobj->code;
+
+}
+
+/**
+ * Function: json_last_errmsg
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ *
+ * Description:
+ * Returns the error message related to the error code
+ * stored in the JSON-object (remember to check for errors; json_has_err).
+ *
+ * Returns: char *, error message
+ **/
+const char *json_last_errmsg( json_obj_t *jobj ) {
+
+	char *errmsg;
+	int errcode = json_last_err( jobj );
+
+	switch( errcode ) {
+
+		case JSON_NO_REPORT:
+			errmsg = "Not an error";
+			break;
+
+		case JSON_UNKNOWN_PTYPE:
+			errmsg = "Unknown print type";
+			break;
+
+		case JSON_UNINITALIZED_OJB:
+			errmsg = "Un-initialized JSON object";
+			break;
+
+		case JSON_NOMEM:
+			errmsg = "Out of memory";
+			break;
+
+		case JSON_INVALID_VAL_TYPE:
+			errmsg = "Invalid type to insert within value object";
+			break;
+
+		case JSON_INVALID_ROOT_ENT:
+		case JSON_INVALID_OBJ_ENT:
+		case JSON_INVALID_MEM_ENT:
+		case JSON_INVALID_PAIR_ENT:
+		case JSON_INVALID_ELE_MENT:
+		case JSON_INVALID_VAL_ENT:
+		case JSON_INVALID_ELEM_ENT:
+		case JSON_INVALID_ARR_ENT:
+			errmsg = "Invalid object to insert within parent object";
+			break;
+
+		case JSON_MIXED_VAL_AND_TYPE:
+			errmsg = "Mixed value and type.";
+			break;
+
+		default:
+			errmsg = "Error code unknown or not implemented";
+			break;
+
+	}
+
+	return (const char *)errmsg;
+
+}
+
+/**
+ * Function: json_out
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ *
+ * Description:
+ * Recursively prints the JSON-object.
+ *
+ * Returns: void
+ **/
+void json_out( json_obj_t *jobj ) {
+
+	int height = 1;
+
+	_print_( jobj, "[%s", _print_set_newline(jobj) );
+	_json_out( jobj, height );
+	_print_( jobj, "]%s", _print_set_newline(jobj) );
+
+}
+
+/**
+ * Function: json_ptype
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - print_type_t ptype: 	Print type
+ *
+ * Description:
+ * Validates and sets the print type, e.g
+ * Pretty Print, Print etc. (File save not implemented)
+ *
+ * Returns: int, the print type value
+ **/
+static int json_ptype( print_type_t ptype ) {
+	return ( ptype > JSON_SAVE_FILE - 1 && ptype < JSON_TYPE ? ptype : JSON_UNKNOWN_PTYPE );
+}
+
+/**
+ * Function: json_set_code
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:	JSON-object to set status for
+ * - int code: 			The status code to set
+ *
+ * Description:
+ * Sets the status code of the last event
+ * of types related to the JSON-object.
+ *
+ * Returns: int, the newly set code
+ **/
+static int json_set_code( json_obj_t *jobj, int code ) {
+
+	if ( jobj == NULL )
+		return jobj->code = JSON_UNINITALIZED_OJB;
+
+	return jobj->code = code;
+}
+
+/**
+ * Function: json_get_type
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - void *entry: 		The JSON-entry to read type of
+ *
+ * Description:
+ * Returns the type of the JSON-entry.
+ *
+ * Returns: json_types_t, the type
+ **/
+static json_types_t json_get_type( void *entry ) {
+
+	json_type_t *type = (json_type_t *)entry;
+
+	return type->type;
+
+}
+
+/**
+ * Function: json_is_type
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - void *entry: 		The JSON-entry to check
+ * - json_types_t:		The JSON-type compare against
+ *
+ * Description:
+ * Checks the equality of the type of the entry
+ * agains the given type.
+ *
+ * Returns: int, 1 on success, 0 on failure
+ **/
+static int json_is_type( void *entry, json_types_t jtype ) {
+	return json_get_type( entry ) == jtype;
+}
+
+/**
+ * Function: json_uninit_obj
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj: 	The JSON-object (parent of obj)
+ * - void *obj:			Any kind of object within parent
+ *
+ * Description:
+ * Checks if the JSON-object is uninitialized. Checks
+ * both the root (jobj) and sub obj.
+ *
+ * Returns: int, 1 on failure, 0 on success
+ **/
+static int json_uninit_obj( json_obj_t *jobj, void *obj ) {
+
+	if ( json_has_err( jobj ) )
+		return 0;
+
+	if ( obj == NULL ) {
+		json_set_code( jobj, JSON_UNINITALIZED_OJB );
+		return 1;
+	}
+
+	return 0;
+
+}
+
+/**
+ * Function: json_val_vtype
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		Parent JSON-object
+ * - json_types_t *vtype:	The value type
+ *
+ * Description:
+ * Checks if the given type is valid as a value, for
+ * the value entry.
+ *
+ * Returns: int, 1 on success, 0 on failure
+ **/
+static int json_val_vtype( json_obj_t *jobj, json_types_t vtype ) {
+
+	int i;
+	json_types_t val_types[7] = {
+		JSON_OBJ, JSON_ARR, JSON_CHAR, JSON_INT, JSON_FLOAT, JSON_BOOL, JSON_NULL
+	};
+
+	for ( i = 0; i < sizeof( val_types ); i++ ) {
+		if ( vtype == val_types[ i ] )
+			return ( jobj == NULL ? JSON_INS_TYPE_VAL : json_set_code( jobj, JSON_INS_TYPE_VAL ) );
+	}
+
+	return ( jobj == NULL ? JSON_INVALID_VAL_TYPE : json_set_code( jobj, JSON_INVALID_VAL_TYPE ) );
+
+}
+
+/**
+ * Function: json_insert
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		Parent JSON-obj
+ * - void *root:			Root-entry, an JSON-entry
+ * - void *entry:			New entry, valid for root-entry
+ *
+ * Description:
+ * Inserts an entry into the root, which is related 
+ * to the parent JSON-obj. Insertion method and possibilities
+ * depends on the root-entry.
+ *
+ * Returns: void *, address to newly inserte entry
+ **/
+static void *json_insert( json_obj_t *jobj, void *root, void *entry ) {
+
+	void *tmp;
+
+	if ( json_has_err( jobj ) )
+		return NULL;
+
+	switch( json_get_type( root ) ) {
+
+		case JSON_OBJ:
+
+			if ( !json_is_type( entry, JSON_MEM ) ) {
+				json_set_code( jobj, JSON_INVALID_OBJ_ENT );
+				return NULL;
+			}
+
+			tmp = ((json_obj_t *)root)->members;
+
+			while( tmp != NULL && ((json_mem_t *)tmp)->next != NULL )
+				tmp =  ((json_mem_t *)tmp)->next;
+
+			if ( tmp == NULL )
+				((json_obj_t *)root)->members = (json_mem_t *)entry;
+			else
+				 ((json_mem_t *)tmp)->next = (json_mem_t *)entry;
+
+			json_set_code( jobj, JSON_INS_MEM_OBJ );
+
+			break;
+
+		case JSON_MEM:
+			
+			switch( json_get_type( entry ) ) {
+
+				case JSON_PAIR:
+				case JSON_MEM:
+
+					tmp = ((json_mem_t *)root)->entry;
+
+					if ( tmp == NULL )
+						((json_mem_t *)root)->entry = entry;
+
+					while( tmp != NULL && ( ( json_is_type( entry, JSON_MEM ) && ((json_mem_t *)tmp)->next != NULL ) || ( json_is_type( entry, JSON_PAIR ) && ((json_pair_t *)tmp)->next != NULL ) ) ) {
+						tmp = ( json_is_type( entry, JSON_MEM ) ? ((json_mem_t *)tmp)->next : ((json_pair_t *)tmp)->next );
+					}
+
+					if ( tmp != NULL ) {
+						if ( json_is_type( entry, JSON_MEM ) )
+							((json_mem_t *)tmp)->next = entry;
+						else
+							((json_pair_t *)tmp)->next = entry;
+					}
+
+					json_set_code( jobj, JSON_INS_PAIR_MEM );
+					break;
+
+				default:
+					json_set_code( jobj, JSON_INVALID_MEM_ENT );
+					break;
+			}
+
+			break;
+
+		case JSON_PAIR:
+
+			if ( !json_is_type( entry, JSON_VAL ) ) {
+				json_set_code( jobj, JSON_INVALID_PAIR_ENT );
+				return NULL;
+			}
+
+			((json_pair_t *)root)->value = entry;
+			json_set_code( jobj, JSON_INS_VAL_PAIR );
+
+			break;
+
+		case JSON_ELEM:
+			
+			if ( !json_is_type( entry, JSON_VAL ) ) {
+				json_set_code( jobj, JSON_INVALID_ELEM_ENT );
+				break;
+			}
+
+			tmp = ((json_elem_t *)root)->entry;
+
+			if ( tmp != NULL )
+				json_destroy_value( tmp );
+
+			((json_elem_t *)root)->entry = entry;
+
+			json_set_code( jobj, JSON_INS_VAL_ELEM );
+
+			break;
+
+		case JSON_ARR:
+
+			if ( !json_is_type( entry, JSON_ELEM ) ) {
+				json_set_code( jobj, JSON_INVALID_ARR_ENT );
+				return NULL;
+			}
+
+			tmp = ((json_arr_t *)root)->entry;
+
+			if ( tmp == NULL )
+				((json_arr_t *)root)->entry = entry;
+			else {
+				
+				while( tmp != NULL && ((json_elem_t *)tmp)->next != NULL )
+					tmp = ((json_elem_t *)tmp)->next;
+
+				((json_elem_t *)tmp)->next = entry;
+
+			}
+
+			json_set_code( jobj, JSON_INS_ELEM_ARR );
+
+			break;
+
+		case JSON_VAL:
+			
+			switch( json_get_type( entry ) ) {
+
+				case JSON_OBJ:
+				case JSON_ARR:
+
+					((json_val_t *)root)->value = entry;
+
+					json_set_code( jobj, JSON_INS_VAL_VAL );
+
+					break;
+
+				default:
+					json_set_code( jobj, JSON_INVALID_VAL_ENT );
+					return NULL;
+			}
+
+			break;
+
+		default:
+			json_set_code( jobj, JSON_INVALID_ROOT_ENT );
+			return NULL;
+
+	}
+
+	return entry;
+}
+
+/** Recursice functions to print the tree **/
+static void _json_out( json_obj_t *jobj, int height ) {
+
+	if ( jobj == NULL )
+		return;
+
+	_print_mem( jobj, jobj->members, height );
+
+}
+
+static void _print_( json_obj_t *jobj, ... ) {
+
+	va_list vargs;
+	char *format;
+
+	va_start( vargs, jobj );
+
+	if ( jobj->jfile == NULL || (jobj->ptype & JSON_PRINT) == JSON_PRINT ) {
+
+		format = va_arg( vargs, char * );
+		vprintf( format, vargs );
+
+	}
+
+	va_end( vargs );
+
+}
+
+static void _print_mem( json_obj_t *jobj, json_mem_t *jmem, int height ) {
+
+	char *tabs;
+
+	if ( jmem == NULL )
+		return;
+
+	tabs = _print_tabs( jobj, height );
+
+	_print_( jobj, "%s{%s", tabs, _print_set_newline( jobj ) );
+
+	if ( json_is_type( jmem->entry, JSON_PAIR ) )
+		_print_pair( jobj, jmem->entry, height + 1 );
+	else
+		_print_mem( jobj, jmem->entry, height + 1 );
+
+	_print_( jobj, "%s}%s%s", tabs, ( jmem->next != NULL ? "," : "" ), _print_set_newline( jobj )  );
+
+	_print_tabs_release( tabs );
+
+	_print_mem( jobj, jmem->next, height );
+
+}
+
+static void _print_pair( json_obj_t *jobj, json_pair_t *jpair, int height ) {
+
+	char *tabs;
+
+	if ( jpair == NULL )
+		return;
+
+	tabs = _print_tabs( jobj, height );
+
+	_print_( jobj, "%s\"%s\":", tabs, jpair->str );
+	_print_value( jobj, jpair->value, height + 1 );
+	_print_( jobj, "%s%s", ( jpair->next != NULL ? "," : "" ), _print_set_newline( jobj ) );
+
+	_print_tabs_release( tabs );
+
+	if ( jpair->next != NULL ) {
+
+		if ( json_is_type( jpair->next, JSON_PAIR ) )
+			_print_pair( jobj, jpair->next, height );
+		else if ( json_is_type( jpair->next, JSON_MEM ) )
+			_print_mem( jobj, jpair->next, height );
+	}
+
+}
+
+static void _print_arr( json_obj_t *jobj, json_arr_t *jarr, int height ) {
+
+	char *tabs;
+
+	if ( jarr == NULL )
+		return;
+
+	tabs = _print_tabs( jobj, height - 1 );
+
+	_print_( jobj, "[%s", _print_set_newline( jobj ) );
+	_print_elem( jobj, jarr->entry, height );
+	_print_( jobj, "%s]", tabs );
+
+	_print_tabs_release( tabs );
+
+}
+
+static void _print_elem( json_obj_t *jobj, json_elem_t *jelem, int height ) {
+
+	char *tabs;
+
+	if ( jelem == NULL )
+		return;
+
+	tabs = _print_tabs( jobj, height );
+
+	_print_( jobj, "%s", tabs );
+	_print_value( jobj, jelem->entry, height );
+	_print_( jobj, "%s%s", ( jelem->next != NULL ? "," : "" ), _print_set_newline( jobj ) );
+
+	_print_elem( jobj, jelem->next, height );
+
+	_print_tabs_release( tabs );
+
+}
+
+static void _print_value( json_obj_t *jobj, json_val_t *jval, int height ) {
+
+	char *tabs;
+
+	if ( jval == NULL ) {
+		_print_( jobj, "\"\"" );
+		return;
+	}
+
+	tabs = _print_tabs( jobj, height + 1 );
+
+	switch( jval->sub_type ) {
+
+		case JSON_OBJ:
+			_json_out( jval->value, height );
+			break;
+
+		case JSON_ARR:
+			_print_arr( jobj, jval->value, height );
+			break;
+		case JSON_CHAR:
+		case JSON_BOOL:
+		case JSON_NULL:
+			_print_( jobj, "\"%s\"", (char *)jval->value );
+			break;
+
+		case JSON_INT:
+			_print_( jobj, "%d", *(int *)jval->value );
+			break;
+
+		case JSON_FLOAT:
+			_print_( jobj, "%f", *(float *)jval->value );
+			break;
+		default:
+			_print_( jobj, "\"\"");
+			break;
+
+	}
+
+	_print_tabs_release( tabs ); 
+
+}
+
+static char *_print_set_newline( json_obj_t *jobj ) {
+	return (jobj->ptype & JSON_PPRINT) == JSON_PPRINT ? "\n": "";
+}
+
+static void _print_tabs_release( char *tabs ) {
+
+	if ( tabs == NULL )
+		return;
+
+	free( tabs );
+}
+
+static char *_print_tabs( json_obj_t *jobj, int height ) {
+
+	int i;
+	char *tabs;
+
+	if ( (jobj->ptype & JSON_PPRINT) == JSON_PPRINT ) {
+		tabs = ( char *) malloc( sizeof( char * ) );
+		tabs[0] = 0;
+		return tabs;
+	}
+
+	tabs = ( char *) malloc( sizeof( char * ) * height );
+
+	for ( i = 0; i < height; i++ )
+		tabs[ i ] = '\t';
+
+	tabs[i] = 0;
+
+	return tabs;
+
+}
+/** Silence in comments is like nothing was here */
+
+/*** 
+ * THIS IS FOR DEBUGGING OF THE JSON-IMPLEMENTATION;
+ * To run this make project as:
+ * $ make json-test
+ * and run by
+ * $ ./json-test
+ **/
+
+#ifdef _DEBUG_JSON
+
+int main(int argc, char const *argv[]) {
+
+	int i = 18848;
+	float f = 154.4848;
+	bool b = true;
+
+	json_obj_t *jobj = json_create( "", JSON_PRINT | JSON_PPRINT );
+
+	if ( json_has_err( jobj ) )
+		printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
+
+	json_mem_t *jmem = json_create_mem( jobj );
+
+	if ( json_has_err( jobj ) )
+		printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
+
+	json_pair_t *jpair = json_create_pair( jobj, jmem, "Test" );
+
+	if ( json_has_err( jobj ) )
+		printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
+
+	json_pair_t *jpair2 = json_create_pair( jobj, jmem, "Test" );
+
+	if ( json_has_err( jobj ) )
+		printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
+
+	json_pair_t *jpair3 = json_create_pair( jobj, jmem, "Test" );
+
+	if ( json_has_err( jobj ) )
+		printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
+
+	json_val_t *jval = json_insert_value( jobj, jpair, JSON_CHAR, "Litt text" );
+	jval = json_insert_value( jobj, jpair2, JSON_CHAR, "Litt mer test" );
+	jval = json_insert_value( jobj, jpair3, JSON_CHAR, "Litt test" );
+
+	if ( json_has_err( jobj ) )
+		printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
+
+	json_mem_t *jmem2 = json_create_mem( jobj );
+
+	if ( json_has_err( jobj ) )
+		printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
+
+	jpair2 = json_create_pair( jobj, jmem2, "array" );
+
+	if ( json_has_err( jobj ) )
+		printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
+
+	json_val_t *jval2 = json_insert_value( jobj, jpair2, JSON_ARR, NULL );
+
+	if ( json_has_err( jobj ) )
+		printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
+
+	json_arr_t *jarr = json_create_arr( jobj, jval2 );
+
+	if ( json_has_err( jobj ) )
+		printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
+
+	json_elem_t *elem = json_create_elem( jobj, jarr );
+
+	json_val_t *val = json_insert_value( jobj, elem, JSON_INT, &i );
+
+	elem = json_create_elem( jobj, jarr );
+	val = json_insert_value( jobj, elem, JSON_BOOL, &b );
+
+	elem = json_create_elem( jobj, jarr );
+	val = json_insert_value( jobj, elem, JSON_CHAR, "FUCK YOU" );
+
+	elem = json_create_elem( jobj, jarr );
+	val = json_insert_value( jobj, elem, JSON_FLOAT, &f );
+
+	elem = json_create_elem( jobj, jarr );
+	val = json_insert_value( jobj, elem, JSON_NULL, NULL );
+
+	json_out( jobj );
+
+	json_destroy( jobj );
+
+	return EXIT_SUCCESS;
+}
+
+#endif

+ 458 - 0
json.h

@@ -0,0 +1,458 @@
+#ifndef _JSON_H
+#define _JSON_H
+
+#include <stdbool.h>
+
+/**
+ * Structure: print_type_t
+ * Typedef: print_type_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	JSON_SAVE_FILE,
+ *	JSON_PRINT,
+ *	JSON_PPRINT,
+ *	JSON_TYPE
+ *
+ * Description:
+ *  Representation of JSON after processing.
+ **/
+typedef enum {
+	JSON_SAVE_FILE = 0x32f,
+	JSON_PRINT = JSON_SAVE_FILE << 1,
+	JSON_PPRINT = JSON_PRINT << 1,
+	JSON_TYPE
+} print_type_t;
+
+/**
+ * Enum: json_type_t
+ * Typedef: json_type_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ * - describes itself
+ *
+ * Description:
+ * Defines entries in JSON
+ **/
+typedef enum {
+	__JSON__	= 0x1,
+	JSON_OBJ 	= __JSON__ << 1,
+	JSON_MEM 	= JSON_OBJ << 1,
+	JSON_ELEM 	= JSON_MEM << 1,
+	JSON_PAIR 	= JSON_ELEM << 1,
+	JSON_ARR 	= JSON_PAIR << 1,
+	JSON_VAL 	= JSON_ARR << 1,
+	JSON_CHAR 	= JSON_VAL << 1,
+	JSON_INT 	= JSON_CHAR << 1,
+	JSON_FLOAT 	= JSON_INT << 1,
+	JSON_BOOL 	= JSON_FLOAT << 1,
+	JSON_NULL 	= JSON_BOOL << 1,
+	JSON_TYPE_NOTSET
+} json_types_t;
+
+/**
+ * Structure: json_type
+ * Typedef: json_type_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type: 		Type of an JSON-entry.
+ *
+ * Description:
+ * 	Holds the type of an JSON-entry.
+ **/
+typedef struct json_type json_type_t;
+
+/**
+ * JSON-entry types
+ **/
+
+/**
+ * Structure: 
+ * Typedef: 
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type:		Entry type (MUST BE FIRST)
+ *	json_mem_t *members:	JSON-meners entries.
+ *	print_type_t ptype:		Print type, eg Pretty print.
+ *	int code:				Status code.
+ *
+ * Description:
+ * 	Defines an JSON-object.
+ **/
+typedef struct json_obj json_obj_t;
+
+/**
+ * Structure: json_mem
+ * Typedef: json_mem_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type:		Entry type (MUST BE FIRST)
+ *	void *entry:			Containing entry. Either pair or new member
+ *	void *next:				Simblings; other members or pairs in parent.
+ *
+ * Description:
+ * 	Defines an JSON-member entry
+ **/
+typedef struct json_mem json_mem_t;
+
+/**
+ * Structure: json_elem
+ * Typedef: json_elem_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type:		Entry type (MUST BE FIRST).
+ *	void *entry:			Containing entry. Either value or new element.
+ *	void *next:				Simblings; other elements in parent.
+ *
+ * Description:
+ *  Defines an JSON-element entry.
+ **/
+typedef struct json_elem json_elem_t;
+
+/**
+ * Structure: json_pair
+ * Typedef: json_pair_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type:		Entry type (MUST BE FIRST).
+ *	char *str:				String specifier.
+ *	json_val_t *value;		Containing entry, only value.
+ *	void *next:				Simblings; other members or pairs in parent.
+ *
+ * Description:
+ * 
+ **/
+typedef struct json_pair json_pair_t;
+
+/**
+ * Structure: json_arr
+ * Typedef: json_arr_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type: 		Entry type (MUST BE FIRST).
+ *	void *entry:			Containing entry, only elements.
+ *
+ * Description:
+ *  Defines a JSON-array entry.
+ **/
+typedef struct json_arr json_arr_t;
+
+/**
+ * Structure: json_val
+ * Typedef: json_val_t
+ * Author: Joachim M. Giæver
+ * 
+ * Sections:
+ *	json_types_t type:		Entry type (MUST BE FIRST).
+ * 	json_types_t sub_type:	Type of the sub entry, eg JSON_INT, _CHAR etc
+ * 	void *value:			The actual entry
+ *
+ * Description:
+ * 
+ **/
+typedef struct json_val json_val_t;
+
+typedef void json_printf_t (void *, ...);
+
+/**
+ * Result codes; OK = 0 =< resultcode > 0 = Failure
+ **/
+#define JSON_INS_ELEM_ARR 		11
+#define JSON_INS_VAL_ELEM		9
+#define JSON_INS_VAL_VAL		8
+#define JSON_INS_TYPE_VAL		7
+#define JSON_INS_VAL_PAIR		6
+#define JSON_INS_PAIR_MEM		5
+#define JSON_INS_MEM_OBJ		3
+#define JSON_INS_CORRECTLY		2
+#define JSON_OK 				1
+#define JSON_NO_REPORT			0
+#define JSON_UNKNOWN_PTYPE		-1
+#define JSON_UNINITALIZED_OJB	-2
+#define JSON_NOMEM 				-3
+#define JSON_INVALID_ROOT_ENT	-4
+#define JSON_INVALID_OBJ_ENT	-5
+#define JSON_INVALID_MEM_ENT	-6
+#define JSON_INVALID_PAIR_ENT	-7
+#define JSON_INVALID_ELE_MENT	-8
+#define JSON_INVALID_VAL_TYPE	-9
+#define JSON_INVALID_VAL_ENT	-10
+#define JSON_INVALID_ELEM_ENT 	-11
+#define JSON_INVALID_ARR_ENT	-12
+#define JSON_MIXED_VAL_AND_TYPE	-13
+#define JSON_INVALID_STRUCTURE	-100
+
+/**
+ * Function: json_create
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - char *fname:			The filename; on saving
+ 							and possible parsing - in the future.
+ * - print_type_t ptype:	Store/print type
+ *
+ * Description:
+ * Creates the main root of the JSON-structure.
+ *
+ * Returns: json_obj_t *, the mother root
+ **/
+json_obj_t *json_create( char *fname, print_type_t ptype );
+
+/**
+ * Function: json_destroy
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object to destroy
+ *
+ * Description:
+ * Destroys any kind of JSON-objects
+ *
+ * Returns: void
+ **/
+void json_destroy( json_obj_t *jobj );
+
+/**
+ * Function: json_create_obj
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ * - json_val_t *jval:		JSON-value to insert to
+ *
+ * Description:
+ * Creates a new JSON-object to insert into the 
+ * JSON-structure (only into JSON-value.).
+ *
+ * Works recursivly on children.
+ *
+ * Returns: json_obj_t *, JSON-object
+ **/
+json_obj_t *json_create_obj( json_obj_t *jobj, json_val_t *jval );
+
+/**
+ * Function: json_create_mem
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object to insert to
+ *
+ * Description:
+ * Creates a new JSON-member and inserts it into the 
+ * JSON-object. May be any kind of JSON-object, both
+ * root or children.
+ *
+ * Returns: json_mem_t *, JSON-member
+ **/
+json_mem_t *json_create_mem( json_obj_t *jobj );
+
+/**
+ * Function: json_destroy_mem
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_mem_t *jmem:		JSON-member to destroy
+ *
+ * Description:
+ * Destroy a JSON-member, works recursively on both simblings
+ * and children.
+ *
+ * Returns: void
+ **/
+void json_destroy_mem( json_mem_t *jmem );
+
+/**
+ * Function: json_create_pair
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ * - json_mem_t *jmem:		JSON-member to insert to
+ *
+ * Description:
+ * Creates a new JSON-pair and inserts it into a JSON-member.
+ *
+ * Returns: json_pair_t *, JSON-pair
+ **/
+json_pair_t *json_create_pair( json_obj_t *jobj, json_mem_t *jmem, char *str );
+
+/**
+ * Function: json_destroy_pair
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_pair_t *jpair:	JSON-pair to destroy
+ *
+ * Description:
+ * Destroys a JSON-pair. Works recursively on both the simblings
+ * and children.
+ *
+ * Returns: void
+ **/	
+void json_destroy_pair( json_pair_t *jpair );
+
+/**
+ * Function: json_create_arr
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ * - json_val_t *jval:		JSON-value to insert to
+ *
+ * Description:
+ * Creates a new JSON-array and inserts it into JSON-value.
+ *
+ * Returns: json_arr_t *, JSON-array
+ **/
+json_arr_t *json_create_arr( json_obj_t *jobj, json_val_t *jval );
+
+/**
+ * Function: json_destroy_arr
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_arr_t *jarr: 		JSON-array to destroy
+ *
+ * Description:
+ * Destroys a JSON-array. Works recursively on the children.
+ *
+ * Returns: void
+ **/
+void json_destroy_arr( json_arr_t *jarr );
+
+/**
+ * Function: json_create_elem
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ * - json_arr_t *jarr: 		JSON-array to insert into
+ *
+ * Description:
+ * Creates a JSON-element and inserts it int an JSON-array.
+ *
+ * Returns: json_elem_t *, JSON-element
+ **/
+json_elem_t *json_create_elem( json_obj_t *jobj, json_arr_t *jarr );
+
+/**
+ * Function: json_destroy_elem
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_elem_t *jelem:	JSON-element to destroy
+ *
+ * Description:
+ * Destroys a JSON-element. Works recursively on both simblings
+ * and children.
+ *
+ * Returns: void
+ **/
+void json_destroy_elem( json_elem_t *jelem );
+
+/**
+ * Function: json_insert_value
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ * - void *ins_obj:			Object or element to insert into
+ * - json_types_t vtype:	Type of the held element in value
+ * - void *entry:			Entry to store in value
+ *
+ * Description:
+ * Creates a new JSON-value and inserts it into a JSON-element or
+ * a JSON-pair. The value must also be specified. JSON-object and 
+ * JSON-array can be insert upon creation by setting entry as NULL.
+ * 
+ * Ex:
+ *
+ * // Insert this value into a JSON-pair, will contain an JSON-array
+ * json_val_t *jvalue = json_insert_value( jobj, jpair, JSON_ARR, NULL );
+ *
+ * // Create the JSON-array and insert it into the above value
+ * json_arr_t *jarr = json_create_arr( jobj, jval );
+ *
+ * Returns: json_val_t *, JSON-value
+ **/
+json_val_t *json_insert_value( json_obj_t *jobj, void *ins_obj, json_types_t vtype, void *entry );
+
+/**
+ * Function: json_destroy_value
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_val_t *jval:		JSON-value to destroy
+ *
+ * Description:
+ * Destroys a JSON-value. Works recursively on children.
+ *
+ * Returns: void
+ **/
+void json_destroy_value( json_val_t *jval );
+
+/**
+ * Function: json_has_err
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ *
+ * Description:
+ * Returns whether or not there was an error present on last event.
+ *
+ * Returns: int 0 on non errors 1 on errors
+ **/
+int json_has_err( json_obj_t *jobj );
+
+/**
+ * Function: json_last_err
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ *
+ * Description:
+ * Returns the last error code present.
+ *
+ * Returns: int, >= 0 on non errors <= 0 on errors
+ **/
+int json_last_err( json_obj_t *jobj );
+
+/**
+ * Function: json_last_errmsg
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ *
+ * Description:
+ * Returns the error message related to the error code
+ * stored in the JSON-object (remember to check for errors; json_has_err).
+ *
+ * Returns: char *, error message
+ **/
+const char *json_last_errmsg( json_obj_t *jobj );
+
+/**
+ * Function: 
+ * Author: Joachim M. Giæver
+ * 
+ * Parameters:
+ * - json_obj_t *jobj:		JSON-object which is the main-root
+ *
+ * Description:
+ * Recursively prints the JSON-object.
+ *
+ * Returns: void
+ **/
+void json_print( json_obj_t *jobj );
+
+#endif