static char * copy_and_remove_whitespaces(const char *string) { char *output_string = (char*)parson_malloc(strlen(string) + 1); char *output_string_ptr = output_string; const char *string_ptr = string; const char *skipped_string = NULL; void *reallocated_ptr; char current_char; if (!output_string) { return NULL; } while (*string_ptr) { current_char = *string_ptr; switch (current_char) { case ' ': case '\r': case '\n': case '\t': string_ptr++; break; case '\"': skipped_string = skip_string(string_ptr); if (!skipped_string) { parson_free(output_string); return NULL; } strncpy(output_string_ptr, string_ptr, skipped_string - string_ptr); output_string_ptr = output_string_ptr + (skipped_string - string_ptr); string_ptr = skipped_string; break; default: *output_string_ptr = current_char; string_ptr++; output_string_ptr++; break; } } *output_string_ptr = '\0'; reallocated_ptr = parson_realloc(output_string, strlen(output_string) + 1); if (!reallocated_ptr) { parson_free(output_string); return NULL; } output_string = (char*)reallocated_ptr; return output_string; }
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); }
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); }
static void json_object_free(JSON_Object *object) { size_t i; for (i = 0; i < object->count; i++) { parson_free(object->names[i]); json_value_free(object->values[i]); } parson_free(object->names); parson_free(object->values); parson_free(object); }
/* 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**)parson_malloc(sizeof(char*) * STARTING_CAPACITY); if (!new_obj->names) { parson_free(new_obj); return NULL; } new_obj->values = (JSON_Value**)parson_malloc(sizeof(JSON_Value*) * STARTING_CAPACITY); if (!new_obj->values) { parson_free(new_obj->names); parson_free(new_obj); return NULL; } new_obj->capacity = STARTING_CAPACITY; new_obj->count = 0; return new_obj; }
static char * read_file(const char * filename) { FILE *fp = fopen(filename, "r"); size_t file_size; char *file_contents; 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); parson_free(file_contents); return NULL; } } fclose(fp); file_contents[file_size] = '\0'; return file_contents; }
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; }
/* 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; }
/* 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**)parson_malloc(STARTING_CAPACITY * sizeof(JSON_Value*)); if (!new_array->items) { parson_free(new_array); return NULL; } new_array->capacity = STARTING_CAPACITY; new_array->count = 0; return new_array; }
/* 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; }
static const char * parse_escaped_characters(const char *string) { char *output_string = (char*)parson_malloc(strlen(string) + 1); char *output_string_ptr = output_string; const char *string_ptr = string; char current_char; unsigned int utf_val; void *reallocated_ptr; if (!output_string) { return NULL; } while (*string_ptr) { current_char = *string_ptr; if (current_char == '\\') { string_ptr++; current_char = *string_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': string_ptr++; if (!is_utf(string_ptr) || sscanf(string_ptr, "%4x", &utf_val) == EOF) { parson_free(output_string); return NULL; } if (utf_val < 0x80) { current_char = utf_val; } else if (utf_val < 0x800) { *output_string_ptr++ = (utf_val >> 6) | 0xC0; current_char = ((utf_val | 0x80) & 0xBF); } else { *output_string_ptr++ = (utf_val >> 12) | 0xE0; *output_string_ptr++ = (((utf_val >> 6) | 0x80) & 0xBF); current_char = ((utf_val | 0x80) & 0xBF); } string_ptr += 3; break; default: parson_free(output_string); return NULL; break; }
static void json_array_free(JSON_Array *array) { size_t i; for (i = 0; i < array->count; i++) { json_value_free(array->items[i]); } parson_free(array->items); parson_free(array); }