You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

204 lines
5.9 KiB

/**
* (C) 2007-22 - ntop.org and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not see see <http://www.gnu.org/licenses/>
*
*/
// taken from (and modified)
// https://github.com/Logan007/C-Simple-JSON-Parser
// which is declared license-free code by the author according to
// https://github.com/forkachild/C-Simple-JSON-Parser/issues/3#issuecomment-1073520808
#include <stdlib.h> // for malloc, free, NULL, atof, realloc
#include <string.h> // for memcpy
#include "json.h"
static int json_str_next_occurence (char *str, char ch);
static int json_str_next_non_numeral (char *str);
static json_object_t *_json_parse (char *str, int *offset);
json_object_t *json_parse (char *str) {
int offset = 0;
json_object_t *temp_obj = _json_parse(str, &offset);
return temp_obj;
}
void json_free (json_object_t *obj) {
int i;
if(obj == NULL)
return;
if(obj->pairs == NULL) {
free(obj);
return;
}
for(i = 0; i < obj->count; i++) {
if(obj->pairs[i].key != NULL)
free(obj->pairs[i].key);
if(obj->pairs[i].value != NULL) {
switch(obj->pairs[i].type) {
case JSON_STRING:
free(obj->pairs[i].value->string_value);
break;
case JSON_DOUBLE:
break;
case JSON_OBJECT:
json_free(obj->pairs[i].value->json_object);
}
free(obj->pairs[i].value);
}
}
}
static int json_str_next_occurence (char *str, char ch) {
int pos = 0;
if(str == NULL)
return -1;
while(*str != ch && *str != '\0') {
str++;
pos++;
}
return (*str == '\0') ? -1 : pos;
}
static int json_str_next_non_numeral (char *str) {
int pos = 0;
if(str == NULL)
return -1;
while((json_str_is_numeral(*str)) && (*str != '\0')) {
str++;
pos++;
}
return (*str == '\0') ? -1 : pos;
}
static json_object_t *_json_parse (char *str, int *offset) {
int _offset = 0;
json_object_t *obj = (json_object_t*)malloc(sizeof(json_object_t));
obj->count = 1;
obj->pairs = (json_pair_t*)malloc(sizeof(json_pair_t));
while(*str != '\0') {
json_str_remove_whitespace_calc_offset(str, _offset);
if(*str == '{') {
str++;
_offset++;
} else if(*str == '"') {
int i = json_str_next_occurence(++str, '"');
if(i <= 0) {
json_free(obj);
return NULL;
}
json_pair_t tempPtr = obj->pairs[obj->count - 1];
tempPtr.key = (char*)malloc((i + 1) * sizeof(char));
memcpy(tempPtr.key, str, i * sizeof(char));
tempPtr.key[i] = '\0';
str += i + 1;
_offset += i + 2;
i = json_str_next_occurence(str, ':');
if(i == -1)
return NULL;
str += i + 1;
_offset += i + 1;
json_str_remove_whitespace_calc_offset(str, _offset);
if(*str == '{') {
int _offsetBeforeParsingChildObject = _offset;
int _sizeOfChildObject;
tempPtr.value = (json_value_t*)malloc(sizeof(json_value_t));
tempPtr.type = JSON_OBJECT;
tempPtr.value->json_object = _json_parse(str, &_offset);
if(tempPtr.value->json_object == NULL) {
json_free(obj);
return NULL;
}
// Advance the string pointer by the size of the processed child object
_sizeOfChildObject = _offset - _offsetBeforeParsingChildObject;
str += _sizeOfChildObject;
} else if(*str == '"') {
i = json_str_next_occurence(++str, '"');
if(i == -1) {
json_free(obj);
return NULL;
}
tempPtr.value = (json_value_t*)malloc(sizeof(json_value_t));
tempPtr.type = JSON_STRING;
tempPtr.value->string_value = (char*)malloc((i + 1) * sizeof(char));
memcpy(tempPtr.value->string_value, str, i * sizeof(char));
tempPtr.value->string_value[i] = '\0';
str += i + 1;
_offset += i + 2;
} else if(json_str_is_numeral(*str)) {
i = json_str_next_non_numeral(str);
if(i == -1) {
json_free(obj);
return NULL;
}
char *tempStr = (char*)malloc((i + 1) * sizeof(char));
memcpy(tempStr, str, i * sizeof(char));
tempStr[i] = '\0';
tempPtr.value = (json_value_t*)malloc(sizeof(json_value_t));
tempPtr.type = JSON_DOUBLE;
tempPtr.value->double_value = atof(tempStr);
free(tempStr);
str += i;
_offset += i + 1;
}
obj->pairs[obj->count - 1] = tempPtr;
} else if (*str == ',') {
obj->count++;
obj->pairs = (json_pair_t*)realloc(obj->pairs, obj->count * sizeof(json_pair_t));
str++;
_offset++;
} else if (*str == '}') {
(*offset) += _offset + 1;
return obj;
}
}
return obj;
}