summaryrefslogtreecommitdiff
path: root/loragw_pkt_logger/src/parson.c
diff options
context:
space:
mode:
Diffstat (limited to 'loragw_pkt_logger/src/parson.c')
-rw-r--r--loragw_pkt_logger/src/parson.c649
1 files changed, 0 insertions, 649 deletions
diff --git a/loragw_pkt_logger/src/parson.c b/loragw_pkt_logger/src/parson.c
deleted file mode 100644
index b273ba1..0000000
--- a/loragw_pkt_logger/src/parson.c
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- Parson ( http://kgabis.github.com/parson/ )
- Copyright (c) 2012 Krzysztof Gabis
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*/
-
-#include "parson.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#define ERROR 0
-#define SUCCESS 1
-#define STARTING_CAPACITY 15
-#define ARRAY_MAX_CAPACITY 122880 /* 15*(2^13) */
-#define OBJECT_MAX_CAPACITY 960 /* 15*(2^6) */
-#define MAX_NESTING 19
-#define sizeof_token(a) (sizeof(a) - 1)
-#define skip_char(str) ((*str)++)
-#define skip_whitespaces(str) while (isspace(**str)) { skip_char(str); }
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-
-#define parson_malloc(a) malloc(a)
-#define parson_free(a) free((void*)a)
-#define parson_realloc(a, b) realloc(a, b)
-
-/* Type definitions */
-typedef union json_value_value {
- const char *string;
- double number;
- JSON_Object *object;
- JSON_Array *array;
- int boolean;
- int null;
-} JSON_Value_Value;
-
-struct json_value_t {
- JSON_Value_Type type;
- JSON_Value_Value value;
-};
-
-struct json_object_t {
- const char **names;
- JSON_Value **values;
- size_t count;
- size_t capacity;
-};
-
-struct json_array_t {
- JSON_Value **items;
- size_t count;
- size_t capacity;
-};
-
-/* Various */
-static int try_realloc(void **ptr, size_t new_size);
-static char * parson_strndup(const char *string, size_t n);
-static int is_utf(const unsigned char *string);
-static int is_decimal(const char *string, size_t length);
-
-/* JSON Object */
-static JSON_Object * json_object_init(void);
-static int json_object_add(JSON_Object *object, const char *name, JSON_Value *value);
-static int json_object_resize(JSON_Object *object, size_t capacity);
-static JSON_Value * json_object_nget_value(const JSON_Object *object, const char *name, size_t n);
-static void json_object_free(JSON_Object *object);
-
-/* JSON Array */
-static JSON_Array * json_array_init(void);
-static int json_array_add(JSON_Array *array, JSON_Value *value);
-static int json_array_resize(JSON_Array *array, size_t capacity);
-static void json_array_free(JSON_Array *array);
-
-/* JSON Value */
-static JSON_Value * json_value_init_object(void);
-static JSON_Value * json_value_init_array(void);
-static JSON_Value * json_value_init_string(const char *string);
-static JSON_Value * json_value_init_number(double number);
-static JSON_Value * json_value_init_boolean(int boolean);
-static JSON_Value * json_value_init_null(void);
-
-/* Parser */
-static void skip_quotes(const char **string);
-static const char * get_processed_string(const char **string);
-static JSON_Value * parse_object_value(const char **string, size_t nesting);
-static JSON_Value * parse_array_value(const char **string, size_t nesting);
-static JSON_Value * parse_string_value(const char **string);
-static JSON_Value * parse_boolean_value(const char **string);
-static JSON_Value * parse_number_value(const char **string);
-static JSON_Value * parse_null_value(const char **string);
-static JSON_Value * parse_value(const char **string, size_t nesting);
-
-/* Various */
-static int try_realloc(void **ptr, size_t new_size) {
- void *reallocated_ptr = parson_realloc(*ptr, new_size);
- if (!reallocated_ptr) { return ERROR; }
- *ptr = reallocated_ptr;
- return SUCCESS;
-}
-
-static char * parson_strndup(const char *string, size_t n) {
- char *output_string = (char*)parson_malloc(n + 1);
- if (!output_string) { return NULL; }
- output_string[n] = '\0';
- strncpy(output_string, string, n);
- return output_string;
-}
-
-static int is_utf(const unsigned char *s) {
- return isxdigit(s[0]) && isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]);
-}
-
-static int is_decimal(const char *string, size_t length) {
- if (length > 1 && string[0] == '0' && string[1] != '.') { return 0; }
- if (length > 2 && !strncmp(string, "-0", 2) && string[2] != '.') { return 0; }
- while (length--) { if (strchr("xX", string[length])) { return 0; } }
- return 1;
-}
-
-/* JSON Object */
-static JSON_Object * json_object_init(void) {
- JSON_Object *new_obj = (JSON_Object*)parson_malloc(sizeof(JSON_Object));
- if (!new_obj) { return NULL; }
- new_obj->names = (const char**)NULL;
- new_obj->values = (JSON_Value**)NULL;
- new_obj->capacity = 0;
- new_obj->count = 0;
- return new_obj;
-}
-
-static int json_object_add(JSON_Object *object, const char *name, JSON_Value *value) {
- size_t index;
- if (object->count >= object->capacity) {
- size_t new_capacity = MAX(object->capacity * 2, STARTING_CAPACITY);
- if (new_capacity > OBJECT_MAX_CAPACITY) { return ERROR; }
- if (json_object_resize(object, new_capacity) == ERROR) { return ERROR; }
- }
- if (json_object_get_value(object, name) != NULL) { return ERROR; }
- index = object->count;
- object->names[index] = parson_strndup(name, strlen(name));
- if (!object->names[index]) { return ERROR; }
- object->values[index] = value;
- object->count++;
- return SUCCESS;
-}
-
-static int json_object_resize(JSON_Object *object, size_t capacity) {
- if (try_realloc((void**)&object->names, capacity * sizeof(char*)) == ERROR) { return ERROR; }
- if (try_realloc((void**)&object->values, capacity * sizeof(JSON_Value*)) == ERROR) { return ERROR; }
- object->capacity = capacity;
- return SUCCESS;
-}
-
-static JSON_Value * json_object_nget_value(const JSON_Object *object, const char *name, size_t n) {
- size_t i, name_length;
- for (i = 0; i < json_object_get_count(object); i++) {
- name_length = strlen(object->names[i]);
- if (name_length != n) { continue; }
- if (strncmp(object->names[i], name, n) == 0) { return object->values[i]; }
- }
- return NULL;
-}
-
-static void json_object_free(JSON_Object *object) {
- while(object->count--) {
- parson_free(object->names[object->count]);
- json_value_free(object->values[object->count]);
- }
- parson_free(object->names);
- parson_free(object->values);
- parson_free(object);
-}
-
-/* JSON Array */
-static JSON_Array * json_array_init(void) {
- JSON_Array *new_array = (JSON_Array*)parson_malloc(sizeof(JSON_Array));
- if (!new_array) { return NULL; }
- new_array->items = (JSON_Value**)NULL;
- new_array->capacity = 0;
- new_array->count = 0;
- return new_array;
-}
-
-static int json_array_add(JSON_Array *array, JSON_Value *value) {
- if (array->count >= array->capacity) {
- size_t new_capacity = MAX(array->capacity * 2, STARTING_CAPACITY);
- if (new_capacity > ARRAY_MAX_CAPACITY) { return ERROR; }
- if (!json_array_resize(array, new_capacity)) { return ERROR; }
- }
- array->items[array->count] = value;
- array->count++;
- return SUCCESS;
-}
-
-static int json_array_resize(JSON_Array *array, size_t capacity) {
- if (try_realloc((void**)&array->items, capacity * sizeof(JSON_Value*)) == ERROR) { return ERROR; }
- array->capacity = capacity;
- return SUCCESS;
-}
-
-static void json_array_free(JSON_Array *array) {
- while (array->count--) { json_value_free(array->items[array->count]); }
- parson_free(array->items);
- parson_free(array);
-}
-
-/* JSON Value */
-static JSON_Value * json_value_init_object(void) {
- JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
- if (!new_value) { return NULL; }
- new_value->type = JSONObject;
- new_value->value.object = json_object_init();
- if (!new_value->value.object) { parson_free(new_value); return NULL; }
- return new_value;
-}
-
-static JSON_Value * json_value_init_array(void) {
- JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
- if (!new_value) { return NULL; }
- new_value->type = JSONArray;
- new_value->value.array = json_array_init();
- if (!new_value->value.array) { parson_free(new_value); return NULL; }
- return new_value;
-}
-
-static JSON_Value * json_value_init_string(const char *string) {
- JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
- if (!new_value) { return NULL; }
- new_value->type = JSONString;
- new_value->value.string = string;
- return new_value;
-}
-
-static JSON_Value * json_value_init_number(double number) {
- JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
- if (!new_value) { return NULL; }
- new_value->type = JSONNumber;
- new_value->value.number = number;
- return new_value;
-}
-
-static JSON_Value * json_value_init_boolean(int boolean) {
- JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
- if (!new_value) { return NULL; }
- new_value->type = JSONBoolean;
- new_value->value.boolean = boolean;
- return new_value;
-}
-
-static JSON_Value * json_value_init_null(void) {
- JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
- if (!new_value) { return NULL; }
- new_value->type = JSONNull;
- return new_value;
-}
-
-/* Parser */
-static void skip_quotes(const char **string) {
- skip_char(string);
- while (**string != '\"') {
- if (**string == '\0') { return; }
- if (**string == '\\') { skip_char(string); if (**string == '\0') { return; }}
- skip_char(string);
- }
- skip_char(string);
-}
-
-/* Returns contents of a string inside double quotes and parses escaped
- characters inside.
- Example: "\u006Corem ipsum" -> lorem ipsum */
-static const char * get_processed_string(const char **string) {
- const char *string_start = *string;
- char *output, *processed_ptr, *unprocessed_ptr, current_char;
- unsigned int utf_val;
- skip_quotes(string);
- if (**string == '\0') { return NULL; }
- output = parson_strndup(string_start + 1, *string - string_start - 2);
- if (!output) { return NULL; }
- processed_ptr = unprocessed_ptr = output;
- while (*unprocessed_ptr) {
- current_char = *unprocessed_ptr;
- if (current_char == '\\') {
- unprocessed_ptr++;
- current_char = *unprocessed_ptr;
- switch (current_char) {
- case '\"': case '\\': case '/': break;
- case 'b': current_char = '\b'; break;
- case 'f': current_char = '\f'; break;
- case 'n': current_char = '\n'; break;
- case 'r': current_char = '\r'; break;
- case 't': current_char = '\t'; break;
- case 'u':
- unprocessed_ptr++;
- if (!is_utf((const unsigned char*)unprocessed_ptr) ||
- sscanf(unprocessed_ptr, "%4x", &utf_val) == EOF) {
- parson_free(output); return NULL;
- }
- if (utf_val < 0x80) {
- current_char = utf_val;
- } else if (utf_val < 0x800) {
- *processed_ptr++ = (utf_val >> 6) | 0xC0;
- current_char = ((utf_val | 0x80) & 0xBF);
- } else {
- *processed_ptr++ = (utf_val >> 12) | 0xE0;
- *processed_ptr++ = (((utf_val >> 6) | 0x80) & 0xBF);
- current_char = ((utf_val | 0x80) & 0xBF);
- }
- unprocessed_ptr += 3;
- break;
- default:
- parson_free(output);
- return NULL;
- break;
- }
- } else if ((unsigned char)current_char < 0x20) { /* 0x00-0x19 are invalid characters for json string (http://www.ietf.org/rfc/rfc4627.txt) */
- parson_free(output);
- return NULL;
- }
- *processed_ptr = current_char;
- processed_ptr++;
- unprocessed_ptr++;
- }
- *processed_ptr = '\0';
- if (try_realloc((void**)&output, strlen(output) + 1) == ERROR) { return NULL; }
- return output;
-}
-
-static JSON_Value * parse_value(const char **string, size_t nesting) {
- if (nesting > MAX_NESTING) { return NULL; }
- skip_whitespaces(string);
- switch (**string) {
- case '{':
- return parse_object_value(string, nesting + 1);
- case '[':
- return parse_array_value(string, nesting + 1);
- case '\"':
- return parse_string_value(string);
- case 'f': case 't':
- return parse_boolean_value(string);
- case '-':
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- return parse_number_value(string);
- case 'n':
- return parse_null_value(string);
- default:
- return NULL;
- }
-}
-
-static JSON_Value * parse_object_value(const char **string, size_t nesting) {
- JSON_Value *output_value = json_value_init_object(), *new_value = NULL;
- JSON_Object *output_object = json_value_get_object(output_value);
- const char *new_key = NULL;
- if (!output_value) { return NULL; }
- skip_char(string);
- skip_whitespaces(string);
- if (**string == '}') { skip_char(string); return output_value; } /* empty object */
- while (**string != '\0') {
- new_key = get_processed_string(string);
- skip_whitespaces(string);
- if (!new_key || **string != ':') {
- json_value_free(output_value);
- return NULL;
- }
- skip_char(string);
- new_value = parse_value(string, nesting);
- if (!new_value) {
- parson_free(new_key);
- json_value_free(output_value);
- return NULL;
- }
- if(!json_object_add(output_object, new_key, new_value)) {
- parson_free(new_key);
- parson_free(new_value);
- json_value_free(output_value);
- return NULL;
- }
- parson_free(new_key);
- skip_whitespaces(string);
- if (**string != ',') { break; }
- skip_char(string);
- skip_whitespaces(string);
- }
- skip_whitespaces(string);
- if (**string != '}' || /* Trim object after parsing is over */
- json_object_resize(output_object, json_object_get_count(output_object)) == ERROR) {
- json_value_free(output_value);
- return NULL;
- }
- skip_char(string);
- return output_value;
-}
-
-static JSON_Value * parse_array_value(const char **string, size_t nesting) {
- JSON_Value *output_value = json_value_init_array(), *new_array_value = NULL;
- JSON_Array *output_array = json_value_get_array(output_value);
- if (!output_value) { return NULL; }
- skip_char(string);
- skip_whitespaces(string);
- if (**string == ']') { /* empty array */
- skip_char(string);
- return output_value;
- }
- while (**string != '\0') {
- new_array_value = parse_value(string, nesting);
- if (!new_array_value) {
- json_value_free(output_value);
- return NULL;
- }
- if(json_array_add(output_array, new_array_value) == ERROR) {
- parson_free(new_array_value);
- json_value_free(output_value);
- return NULL;
- }
- skip_whitespaces(string);
- if (**string != ',') { break; }
- skip_char(string);
- skip_whitespaces(string);
- }
- skip_whitespaces(string);
- if (**string != ']' || /* Trim array after parsing is over */
- json_array_resize(output_array, json_array_get_count(output_array)) == ERROR) {
- json_value_free(output_value);
- return NULL;
- }
- skip_char(string);
- return output_value;
-}
-
-static JSON_Value * parse_string_value(const char **string) {
- const char *new_string = get_processed_string(string);
- if (!new_string) { return NULL; }
- return json_value_init_string(new_string);
-}
-
-static JSON_Value * parse_boolean_value(const char **string) {
- size_t true_token_size = sizeof_token("true");
- size_t false_token_size = sizeof_token("false");
- if (strncmp("true", *string, true_token_size) == 0) {
- *string += true_token_size;
- return json_value_init_boolean(1);
- } else if (strncmp("false", *string, false_token_size) == 0) {
- *string += false_token_size;
- return json_value_init_boolean(0);
- }
- return NULL;
-}
-
-static JSON_Value * parse_number_value(const char **string) {
- char *end;
- double number = strtod(*string, &end);
- JSON_Value *output_value;
- if (is_decimal(*string, end - *string)) {
- *string = end;
- output_value = json_value_init_number(number);
- } else {
- output_value = NULL;
- }
- return output_value;
-}
-
-static JSON_Value * parse_null_value(const char **string) {
- size_t token_size = sizeof_token("null");
- if (strncmp("null", *string, token_size) == 0) {
- *string += token_size;
- return json_value_init_null();
- }
- return NULL;
-}
-
-/* Parser API */
-JSON_Value * json_parse_file(const char *filename) {
- FILE *fp = fopen(filename, "r");
- size_t file_size;
- char *file_contents;
- JSON_Value *output_value;
- if (!fp) { return NULL; }
- fseek(fp, 0L, SEEK_END);
- file_size = ftell(fp);
- rewind(fp);
- file_contents = (char*)parson_malloc(sizeof(char) * (file_size + 1));
- if (!file_contents) { fclose(fp); return NULL; }
- if (fread(file_contents, file_size, 1, fp) < 1) {
- if (ferror(fp)) { fclose(fp); return NULL; }
- }
- fclose(fp);
- file_contents[file_size] = '\0';
- output_value = json_parse_string(file_contents);
- parson_free(file_contents);
- return output_value;
-}
-
-JSON_Value * json_parse_string(const char *string) {
- if (!string || (*string != '{' && *string != '[')) { return NULL; }
- return parse_value((const char**)&string, 0);
-}
-
-/* JSON Object API */
-JSON_Value * json_object_get_value(const JSON_Object *object, const char *name) {
- return json_object_nget_value(object, name, strlen(name));
-}
-
-const char * json_object_get_string(const JSON_Object *object, const char *name) {
- return json_value_get_string(json_object_get_value(object, name));
-}
-
-double json_object_get_number(const JSON_Object *object, const char *name) {
- return json_value_get_number(json_object_get_value(object, name));
-}
-
-JSON_Object * json_object_get_object(const JSON_Object *object, const char *name) {
- return json_value_get_object(json_object_get_value(object, name));
-}
-
-JSON_Array * json_object_get_array(const JSON_Object *object, const char *name) {
- return json_value_get_array(json_object_get_value(object, name));
-}
-
-int json_object_get_boolean(const JSON_Object *object, const char *name) {
- return json_value_get_boolean(json_object_get_value(object, name));
-}
-
-JSON_Value * json_object_dotget_value(const JSON_Object *object, const char *name) {
- const char *dot_position = strchr(name, '.');
- if (!dot_position) { return json_object_get_value(object, name); }
- object = json_value_get_object(json_object_nget_value(object, name, dot_position - name));
- return json_object_dotget_value(object, dot_position + 1);
-}
-
-const char * json_object_dotget_string(const JSON_Object *object, const char *name) {
- return json_value_get_string(json_object_dotget_value(object, name));
-}
-
-double json_object_dotget_number(const JSON_Object *object, const char *name) {
- return json_value_get_number(json_object_dotget_value(object, name));
-}
-
-JSON_Object * json_object_dotget_object(const JSON_Object *object, const char *name) {
- return json_value_get_object(json_object_dotget_value(object, name));
-}
-
-JSON_Array * json_object_dotget_array(const JSON_Object *object, const char *name) {
- return json_value_get_array(json_object_dotget_value(object, name));
-}
-
-int json_object_dotget_boolean(const JSON_Object *object, const char *name) {
- return json_value_get_boolean(json_object_dotget_value(object, name));
-}
-
-size_t json_object_get_count(const JSON_Object *object) {
- return object ? object->count : 0;
-}
-
-const char * json_object_get_name(const JSON_Object *object, size_t index) {
- if (index >= json_object_get_count(object)) { return NULL; }
- return object->names[index];
-}
-
-/* JSON Array API */
-JSON_Value * json_array_get_value(const JSON_Array *array, size_t index) {
- if (index >= json_array_get_count(array)) { return NULL; }
- return array->items[index];
-}
-
-const char * json_array_get_string(const JSON_Array *array, size_t index) {
- return json_value_get_string(json_array_get_value(array, index));
-}
-
-double json_array_get_number(const JSON_Array *array, size_t index) {
- return json_value_get_number(json_array_get_value(array, index));
-}
-
-JSON_Object * json_array_get_object(const JSON_Array *array, size_t index) {
- return json_value_get_object(json_array_get_value(array, index));
-}
-
-JSON_Array * json_array_get_array(const JSON_Array *array, size_t index) {
- return json_value_get_array(json_array_get_value(array, index));
-}
-
-int json_array_get_boolean(const JSON_Array *array, size_t index) {
- return json_value_get_boolean(json_array_get_value(array, index));
-}
-
-size_t json_array_get_count(const JSON_Array *array) {
- return array ? array->count : 0;
-}
-
-/* JSON Value API */
-JSON_Value_Type json_value_get_type(const JSON_Value *value) {
- return value ? value->type : JSONError;
-}
-
-JSON_Object * json_value_get_object(const JSON_Value *value) {
- return json_value_get_type(value) == JSONObject ? value->value.object : NULL;
-}
-
-JSON_Array * json_value_get_array(const JSON_Value *value) {
- return json_value_get_type(value) == JSONArray ? value->value.array : NULL;
-}
-
-const char * json_value_get_string(const JSON_Value *value) {
- return json_value_get_type(value) == JSONString ? value->value.string : NULL;
-}
-
-double json_value_get_number(const JSON_Value *value) {
- return json_value_get_type(value) == JSONNumber ? value->value.number : 0;
-}
-
-int json_value_get_boolean(const JSON_Value *value) {
- return json_value_get_type(value) == JSONBoolean ? value->value.boolean : -1;
-}
-
-void json_value_free(JSON_Value *value) {
- switch (json_value_get_type(value)) {
- case JSONObject:
- json_object_free(value->value.object);
- break;
- case JSONString:
- if (value->value.string) { parson_free(value->value.string); }
- break;
- case JSONArray:
- json_array_free(value->value.array);
- break;
- default:
- break;
- }
- parson_free(value);
-}