Diff for /libelwix/src/json.c between versions 1.4 and 1.10

version 1.4, 2018/03/07 12:29:28 version 1.10, 2024/10/28 09:58:51
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004 - 2018Copyright 2004 - 2024
         by Michael Pounov <misho@elwix.org>.  All rights reserved.          by Michael Pounov <misho@elwix.org>.  All rights reserved.
   
 Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
Line 224  json_parse_value(json_t * __restrict json, const char  Line 224  json_parse_value(json_t * __restrict json, const char 
                         case '}':                          case '}':
                                 goto found;                                  goto found;
                 }                  }
                if (jstr[json->h_pos] < 32 || jstr[json->h_pos] > 127) {                if (jstr[json->h_pos] < 32 || (u_char) jstr[json->h_pos] > 127) {
                         json->h_pos = pos;                          json->h_pos = pos;
                         elwix_SetErr(J_ERR_INVAL, "%s", jerrstr[J_ERR_INVAL]);                          elwix_SetErr(J_ERR_INVAL, "%s", jerrstr[J_ERR_INVAL]);
                         return -1;                          return -1;
Line 427  json_token2val(const char *jstr, jtok_t * __restrict t Line 427  json_token2val(const char *jstr, jtok_t * __restrict t
                 return NULL;                  return NULL;
   
         AIT_SET_STRSIZ(v, json_toklen(tok));          AIT_SET_STRSIZ(v, json_toklen(tok));
        strncpy(AIT_GET_STR(v), json_tokstr(jstr, tok), AIT_LEN(v) - 1);        if (AIT_GET_STR(v))
                 strncpy(AIT_GET_STR(v), json_tokstr(jstr, tok), AIT_LEN(v) - 1);
         else
                 ait_freeVar(&v);
   
         return v;          return v;
 }  }
Line 437  json_token2val(const char *jstr, jtok_t * __restrict t Line 440  json_token2val(const char *jstr, jtok_t * __restrict t
  *   *
  * @jstr = JSON string   * @jstr = JSON string
  * @tok = Token for convert   * @tok = Token for convert
 * @return =NULL error or !=NULL allocated str, after use should be e_free() * @return =NULL error or !=NULL allocated str, after use should be json_freestr()|e_free()
  */   */
 char *  char *
 json_token2str(const char *jstr, jtok_t * __restrict tok)  json_token2str(const char *jstr, jtok_t * __restrict tok)
 {  {
        char *str = NULL;        char *s, *s2, *wrk, *str = NULL;
         size_t len;          size_t len;
   
         if (!jstr || !tok)          if (!jstr || !tok)
                 return NULL;                  return NULL;
   
   
         len = json_toklen(tok);          len = json_toklen(tok);
         str = e_malloc(len + 1);          str = e_malloc(len + 1);
         if (!str)          if (!str)
                 return NULL;                  return NULL;
         else {          else {
                strncpy(str, json_tokstr(jstr, tok), len);                memset(str, 0, len + 1);
                str[len] = 0;
                 wrk = e_strdup(json_tokstr(jstr, tok));
                 wrk[len] = 0;
                 for (s = wrk, s2 = str; *s; s++)
                         *s2++ = (*s != '\\') ? *s : *++s;
                 e_free(wrk);
         }          }
   
         return str;          return str;
Line 483  json_token2num(const char *jstr, jtok_t * __restrict t Line 492  json_token2num(const char *jstr, jtok_t * __restrict t
 }  }
   
 /*  /*
 * json_findbykey() - Find data by key * json_token2dbl() - Return token to double
  *   *
  * @jstr = JSON string   * @jstr = JSON string
    * @tok = Token for convert
    * @return number
    */
   double
   json_token2dbl(const char *jstr, jtok_t * __restrict tok)
   {
           double ret = 0;
           char *str;
   
           str = json_token2str(jstr, tok);
           if (!str)
                   return 0;
   
           ret = strtod(str, NULL);
           e_free(str);
           return ret;
   }
   
   /*
    * json_token2bool() - Return token to bool int
    *
    * @jstr = JSON string
    * @tok = Token for convert
    * @return 0 for FALSE and !=0 for TRUE
    */
   int
   json_token2bool(const char *jstr, jtok_t * __restrict tok)
   {
           double ret = 0;
           char *str;
   
           str = json_token2str(jstr, tok);
           if (!str)
                   return 0;
   
           switch (*str) {
                   case 't':
                   case 'T':
                           ret = 1;
                           break;
                   case 'f':
                   case 'F':
                           ret = 0;
                           break;
                   default:
                           ret = (int) strtol(str, NULL, 10);
                           break;
           }
           e_free(str);
           return ret;
   }
   
   /*
    * json_findbykey() - Find token data by key
    *
    * @jstr = JSON string
  * @key = Search key   * @key = Search key
  * @type = Search key for particular token type, if is J_UNDEF this mean any type   * @type = Search key for particular token type, if is J_UNDEF this mean any type
  * @toks = Parsed tokens   * @toks = Parsed tokens
Line 505  json_findbykey(const char *jstr, const char *key, jtyp Line 570  json_findbykey(const char *jstr, const char *key, jtyp
                 klen = strlen(key);                  klen = strlen(key);
   
         for (i = 1; i < toksnum; i++) {          for (i = 1; i < toksnum; i++) {
                if (toks[i].tok_type == J_STRING &&                 if (toks[i].tok_type == J_STRING && toks[i].tok_size == 1 && 
                                 klen == toks[i].tok_end - toks[i].tok_start &&                                   klen == toks[i].tok_end - toks[i].tok_start && 
                                 !strncmp(jstr + toks[i].tok_start, key, klen)) {                                  !strncmp(jstr + toks[i].tok_start, key, klen)) {
                         if (type != J_UNDEF) {                          if (type != J_UNDEF) {
Line 524  json_findbykey(const char *jstr, const char *key, jtyp Line 589  json_findbykey(const char *jstr, const char *key, jtyp
 }  }
   
 /*  /*
    * json_findbypos() - Find token by position on JSON string
    *
    * @pos = Offset from begin of JSON string
    * @toks = Parsed tokens
    * @toksnum = Number of parsed tokens
    * return: =NULL error or !=NULL token found 
    */
   jtok_t *
   json_findbypos(u_long pos, jtok_t * __restrict toks, int toksnum)
   {
           jtok_t *tok = NULL;
           register int i;
   
           if (!toks)
                   return NULL;
   
           for (i = 1; i < toksnum; i++)
                   if (pos <= toks[i].tok_end && pos >= toks[i].tok_start) {
                           tok = toks + i;
                           break;
                   }
   
           return tok;
   }
   
   /*
  * json_token2array() - Convert token to string array   * json_token2array() - Convert token to string array
  *   *
  * @jstr = JSON string   * @jstr = JSON string
Line 535  array_t * Line 626  array_t *
 json_token2array(const char *jstr, jtok_t * __restrict tok)  json_token2array(const char *jstr, jtok_t * __restrict tok)
 {  {
         array_t *arr = NULL;          array_t *arr = NULL;
        register int i;        register int i, j;
         int siz;          int siz;
         ait_val_t *v;          ait_val_t *v;
         jtok_t *t;          jtok_t *t;
Line 554  json_token2array(const char *jstr, jtok_t * __restrict Line 645  json_token2array(const char *jstr, jtok_t * __restrict
         if (tok->tok_type == J_STRING || tok->tok_type == J_VALUE) {          if (tok->tok_type == J_STRING || tok->tok_type == J_VALUE) {
                 v = ait_getVars(&arr, 0);                  v = ait_getVars(&arr, 0);
                 AIT_SET_STRSIZ(v, json_toklen(tok) + 1);                  AIT_SET_STRSIZ(v, json_toklen(tok) + 1);
                json_tokstrcpy(AIT_GET_STR(v), jstr, tok);                if (AIT_GET_STR(v)) {
                         json_tokstrcpy(AIT_GET_STR(v), jstr, tok);
                 } else {
                         ait_freeVar(&v);
                 }
         } else if (tok->tok_type == J_ARRAY) {          } else if (tok->tok_type == J_ARRAY) {
                for (i = 0; i < tok->tok_size; i++) {                for (i = 0, j = 1; i < tok->tok_size; i++) {
                        t = &tok[i + 1];                        t = &tok[i + j];
                         v = ait_getVars(&arr, i);                          v = ait_getVars(&arr, i);
                         AIT_SET_STRSIZ(v, json_toklen(t) + 1);                          AIT_SET_STRSIZ(v, json_toklen(t) + 1);
                        json_tokstrcpy(AIT_GET_STR(v), jstr, t);                        if (AIT_GET_STR(v)) {
                                 json_tokstrcpy(AIT_GET_STR(v), jstr, t);
                         } else {
                                 ait_freeVar(&v);
                         }
 
                         /* if there we have array from objects should parse all object tokens */
                         while (i < tok->tok_size - 1 && tok->tok_idx != tok[i + j + 1].tok_parent)
                                 j++;
                 }                  }
         } else if (tok->tok_type == J_OBJECT) {          } else if (tok->tok_type == J_OBJECT) {
                 for (i = 0; tok->tok_idx <= tok[i + 1].tok_parent; i++) {                  for (i = 0; tok->tok_idx <= tok[i + 1].tok_parent; i++) {
                         t = &tok[i + 1];                          t = &tok[i + 1];
                         v = ait_getVars(&arr, i);                          v = ait_getVars(&arr, i);
                         AIT_SET_STRSIZ(v, json_toklen(t) + 1);                          AIT_SET_STRSIZ(v, json_toklen(t) + 1);
                        json_tokstrcpy(AIT_GET_STR(v), jstr, t);                        if (AIT_GET_STR(v)) {
                                 json_tokstrcpy(AIT_GET_STR(v), jstr, t);
                         } else {
                                 ait_freeVar(&v);
                         }
                 }                  }
         } else {          } else {
                 elwix_SetErr(J_ERR_PARAM, "%s", jerrstr[J_ERR_PARAM]);                  elwix_SetErr(J_ERR_PARAM, "%s", jerrstr[J_ERR_PARAM]);
Line 939  json_add_pair(char * __restrict jstr, int jlen, int ws Line 1046  json_add_pair(char * __restrict jstr, int jlen, int ws
 }  }
   
 /*  /*
    * json_add_pair2() - Adds key/value pair with formated args
    *
    * @jstr = JSON string
    * @jlen = JSON string length
    * @wspace = whitespace include
    * @key = Key string
    * @fmt = Format string for values
    * return: -1 error or !=-1 actual JSON string length
    */
   int
   json_add_pair2(char * __restrict jstr, int jlen, int wspace, const char *key, const char *fmt, ...)
   {
           int len = -1;
           size_t eos;
           va_list lst;
           char szStr[BUFSIZ] = { [0 ... BUFSIZ - 1] = 0 };
   
           if (!jstr || !key || !fmt)
                   return -1;
           else
                   eos = strlen(jstr);
   
           if (json_add_string(jstr, jlen, 0, key) == -1) {
                   jstr[eos] = 0;
                   return -1;
           }
           if (json_add_colon(jstr, jlen, wspace) == -1) {
                   jstr[eos] = 0;
                   return -1;
           }
           va_start(lst, fmt);
           vsnprintf(szStr, sizeof szStr, fmt, lst);
           va_end(lst);
           if ((len = json_add_string(jstr, jlen, 0, szStr)) == -1) {
                   jstr[eos] = 0;
                   return -1;
           }
   
           return len;
   }
   
   /*
  * json_add_array() - Adds array   * json_add_array() - Adds array
  *   *
  * @jstr = JSON string   * @jstr = JSON string
Line 1007  json_dump_yaml(FILE *f, const char *jstr, jtok_t *toks Line 1156  json_dump_yaml(FILE *f, const char *jstr, jtok_t *toks
 {  {
         register int i, j, k;          register int i, j, k;
   
        if (!toksnum)        if (!toksnum || !toks)
                 return 0;                  return 0;
   
         if (toks->tok_type == J_VALUE) {          if (toks->tok_type == J_VALUE) {
Line 1034  json_dump_yaml(FILE *f, const char *jstr, jtok_t *toks Line 1183  json_dump_yaml(FILE *f, const char *jstr, jtok_t *toks
                                 fprintf(f, "  ");                                  fprintf(f, "  ");
                         fprintf(f, "   - ");                          fprintf(f, "   - ");
                         j += json_dump_yaml(f, jstr, toks + j + 1, toksnum - j, indent + 1);                          j += json_dump_yaml(f, jstr, toks + j + 1, toksnum - j, indent + 1);
                           fprintf(f, "\n");
                   }
                   return j + 1;
           }
   
           return 0;
   }
   
   /*
    * json_dump() - Dump parsed JSON string to structure format
    *
    * @f = Output handler
    * @jstr = JSON string
    * @toks = JSON tokens
    * @toksnum = Number of tokens
    * @indent = Start indent spaces
    * return: 0 done and 1 added one more item
    */
   int
   json_dump(FILE *f, const char *jstr, jtok_t *toks, int toksnum, int indent)
   {
           register int i, j, k;
   
           if (!toksnum)
                   return 0;
   
           if (toks->tok_type == J_VALUE) {
                   fprintf(f, "[idx=%ld type=VALUE start=%ld end=%ld size=%ld parent=%ld] = %.*s", 
                                   toks->tok_idx, toks->tok_start, toks->tok_end, toks->tok_size, toks->tok_parent, 
                                   (int) json_toklen(toks), json_tokstr(jstr, toks));
                   return 1;
           } else if (toks->tok_type == J_STRING) {
                   fprintf(f, "[idx=%ld type=STRING start=%ld end=%ld size=%ld parent=%ld] = %.*s", 
                                   toks->tok_idx, toks->tok_start, toks->tok_end, toks->tok_size, toks->tok_parent, 
                                   (int) json_toklen(toks), json_tokstr(jstr, toks));
                   return 1;
           } else if (toks->tok_type == J_OBJECT) {
                   fprintf(f, "\n");
                   fprintf(f, "object:: [idx=%ld type=OBJECT start=%ld end=%ld size=%ld parent=%ld]\n", 
                                   toks->tok_idx, toks->tok_start, toks->tok_end, toks->tok_size, toks->tok_parent);
                   for (j = i = 0; i < json_toksize(toks); i++) {
                           for (k = 0; k < indent; k++)
                                   fprintf(f, "  ");
                           j += json_dump(f, jstr, toks + j + 1, toksnum - j, indent + 1);
                           fprintf(f, ": ");
                           j += json_dump(f, jstr, toks + j + 1, toksnum - j, indent + 1);
                           fprintf(f, "\n");
                   }
                   return j + 1;
           } else if (toks->tok_type == J_ARRAY) {
                   fprintf(f, "\n");
                   fprintf(f, "array[] [idx=%ld type=ARRAY start=%ld end=%ld size=%ld parent=%ld]", 
                                   toks->tok_idx, toks->tok_start, toks->tok_end, toks->tok_size, toks->tok_parent);
                   for (j = i = 0; i < json_toksize(toks); i++) {
                           for (k = 0; k < indent - 1; k++)
                                   fprintf(f, "  ");
                           j += json_dump(f, jstr, toks + j + 1, toksnum - j, indent + 1);
                         fprintf(f, "\n");                          fprintf(f, "\n");
                 }                  }
                 return j + 1;                  return j + 1;

Removed from v.1.4  
changed lines
  Added in v.1.10


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>