/
superterminator
/
JsonParse
Обзор
Документация
Войти
/
superterminator
/
JsonParse
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/json_value.c
205 строк
7 KB
superterminator
initial commit
15 сен 2024, 11:40
15 сен 2024, 11:40
f4b359b
Код
Авторство
О чём код?
#include "json_parse.h" #include <string.h> #include <stdlib.h> static char digits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; EXPORT_IMPORT_TOOLS_PREFIX int get_str_int_value(const char* str, int str_length, int* out) { if (!str || !out || str_length <= 0) return ERR_JSON_BAD_PARAMS; *out = 0; if (str_length == 4 && (memcmp(str, "True", 4) == 0 || memcmp(str, "true", 4) == 0)) { *out = 1; return ERR_JSON_SUCCESS; } else if (str_length == 5 && (memcmp(str, "False", 5) == 0 || memcmp(str, "false", 5) == 0)) { *out = 0; return ERR_JSON_SUCCESS; } int sign = 1; for (size_t ch_i = 0; ch_i < str_length; ch_i++) { if (ch_i == 0 && str[0] == '-') { sign = -1; continue; } int not_digit = 1; for (size_t di = 0; di < sizeof(digits) / sizeof(digits[0]); di++) { if (str[ch_i] == digits[di]) { not_digit = 0; break; } } if (not_digit) return ERR_JSON_BAD_VALUE_TYPE; } for (size_t ch_i = 0; ch_i < str_length; ch_i++) { if (sign == -1 && ch_i == 0) continue; *out = *out * 10 + str[ch_i] - '0'; } *out *= sign; return ERR_JSON_SUCCESS; } EXPORT_IMPORT_TOOLS_PREFIX int get_str_float_value(const char* str, int str_length, float* out) { if (!str || !out || str_length <= 0) return ERR_JSON_BAD_PARAMS; *out = 0; int fullstop_cnt = 0; float sign = 1.0; for (size_t ch_i = 0; ch_i < str_length; ch_i++) { if (ch_i == 0 && str[0] == '-') { sign = -1.0; continue; } int not_digit = 1; for (size_t di = 0; di < sizeof(digits) / sizeof(digits[0]); di++) { if (str[ch_i] == digits[di]) { not_digit = 0; break; } if (str[ch_i] == '.') { //one fullstop max if (fullstop_cnt) return ERR_JSON_BAD_VALUE_TYPE; not_digit = 0; fullstop_cnt++; break; } } if (not_digit) return ERR_JSON_BAD_VALUE_TYPE; } fullstop_cnt = 0; float divider = 10.0; for (size_t ch_i = 0; ch_i < str_length; ch_i++) { if (sign == -1.0 && ch_i == 0) continue; if(fullstop_cnt == 0 && str[ch_i] != '.') *out = *out * 10 + str[ch_i] - '0'; else if (str[ch_i] != '.') { *out += (float)(str[ch_i] - '0') / divider; divider *= 10; } else fullstop_cnt++; } *out *= sign; return ERR_JSON_SUCCESS; } static int get_field_int_value(const struct JsonNode* node, int* out) { if (node->type != JsonNodeField || !node->subnodes || !node->subnodes->next || !node->subnodes->next->next) return ERR_JSON_BAD_PARAMS; struct JsonNode* value_node = node->subnodes->next->next; if (value_node->type != JsonNodeValue) return ERR_JSON_BAD_VALUE_TYPE; return get_str_int_value(value_node->token->text, value_node->token->len, out); } static int get_field_float_value(const struct JsonNode* node, float* out) { if (node->type != JsonNodeField || !node->subnodes || !node->subnodes->next || !node->subnodes->next->next) return ERR_JSON_BAD_PARAMS; struct JsonNode* value_node = node->subnodes->next->next; if (value_node->type != JsonNodeValue) return ERR_JSON_BAD_VALUE_TYPE; return get_str_float_value(value_node->token->text, value_node->token->len, out); } static int get_field_str_value(const struct JsonNode* node, char* out, int max_len) { if (node->type != JsonNodeField || !node->subnodes || !node->subnodes->next || !node->subnodes->next->next) return ERR_JSON_BAD_PARAMS; struct JsonNode* value_node = node->subnodes->next->next; if (value_node->type != JsonNodeString) return ERR_JSON_BAD_VALUE_TYPE; if (max_len < value_node->token->len) return ERR_JSON_INSUFFICIENT_BUFFER; //acoount for qoutes memcpy(out, value_node->token->text + 1, value_node->token->len - 2); return ERR_JSON_SUCCESS; } EXPORT_IMPORT_TOOLS_PREFIX int get_subnode_named_int_value(const char* name, const struct JsonNode* parent_node, int* out) { const struct JsonNode* field_node = 0; int err = get_subnode_named(name, parent_node, &field_node); if (err != ERR_JSON_SUCCESS) return err; return get_field_int_value(field_node, out); } EXPORT_IMPORT_TOOLS_PREFIX int get_subnode_named_float_value(const char* name, const struct JsonNode* parent_node, float* out) { const struct JsonNode* field_node = 0; int err = get_subnode_named(name, parent_node, &field_node); if (err != ERR_JSON_SUCCESS) return err; return get_field_float_value(field_node, out); } EXPORT_IMPORT_TOOLS_PREFIX int get_subnode_named_str_value(const char* name, const struct JsonNode* parent_node, char* out, int max_len) { const struct JsonNode* field_node = 0; int err = get_subnode_named(name, parent_node, &field_node); if (err != ERR_JSON_SUCCESS) return err; return get_field_str_value(field_node, out, max_len); } EXPORT_IMPORT_TOOLS_PREFIX int get_subnode_named(const char* name, const struct JsonNode* parent_node, const struct JsonNode** subnode) { if (!subnode || !name || !parent_node) return ERR_JSON_BAD_PARAMS; int search_len = strlen(name); *subnode = 0; struct JsonNode* node = parent_node->subnodes; //named nodes are in JsonNodeCommaNamed node type, search it first, or if parent_node is JsonNodeCommaNamed, then search its childs //there should be no more than one JsonNodeCommaNamed subnode while (node) { if (node->type == JsonNodeCommaNamed) { node = node->subnodes; } else { //only this types are named like "field1":43.58 //JsonTokenString have length with quotes like "val" - 5 if ((node->type == JsonNodeField || node->type == JsonNodeObject || node->type == JsonNodeArray) && node->subnodes->type == JsonNodeString && node->subnodes->token->type == JsonTokenString && node->subnodes->token->len == (search_len + 2) && memcmp(name, node->subnodes->token->text + 1, search_len) == 0 ) { *subnode = node; return ERR_JSON_SUCCESS; } node = node->next; } } return ERR_JSON_NO_FIELD; }