"Fossies" - the Fresh Open Source Software Archive

Member "opensips-3.0.1/modules/cachedb_mongodb/cachedb_mongodb_json.c" (1 Aug 2019, 8506 Bytes) of package /linux/misc/opensips-3.0.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cachedb_mongodb_json.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.0.0_vs_3.0.1.

    1 /*
    2  * Copyright (C) 2011-2017 OpenSIPS Project
    3  *
    4  * This file is part of opensips, a free SIP server.
    5  *
    6  * opensips is free software; you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License as published by
    8  * the Free Software Foundation; either version 2 of the License, or
    9  * (at your option) any later version.
   10  *
   11  * opensips is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with this program; if not, write to the Free Software
   18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   19  */
   20 
   21 #include "../../dprint.h"
   22 #include "../../ut.h"
   23 #include "cachedb_mongodb_json.h"
   24 #include "cachedb_mongodb_dbase.h"
   25 
   26 int json_to_bson_append_element(bson_t *doc, const char *k, struct json_object *v);
   27 
   28 int json_to_bson_append_array(bson_t *doc, struct json_object *a)
   29 {
   30     int i, al_len;
   31     char *al;
   32     json_object *it;
   33 
   34     for (i = 0; i < json_object_array_length(a); i++) {
   35         al = int2str(i, &al_len);
   36         if (!al) {
   37             LM_ERR("Failed to convert %d to str\n", i);
   38             return -1;
   39         }
   40 
   41         al[al_len] = '\0';
   42         it = json_object_array_get_idx(a, i);
   43         if (!it) {
   44             LM_ERR("Failed to get JSON idx\n");
   45             return -1;
   46         }
   47 
   48         if (json_to_bson_append_element(doc, al, it) < 0) {
   49             LM_ERR("Failed to append element to BSON\n");
   50             return -1;
   51         }
   52     }
   53 
   54     return 0;
   55 }
   56 
   57 # define json_object_object_iterator(obj,key,val) \
   58     char *key; struct json_object *val; struct lh_entry *entry; \
   59     for(entry = json_object_get_object(obj)->head; \
   60         (entry ? (key = (char*)entry->k, \
   61         val = (struct json_object*)entry->v, entry) : 0); \
   62         entry = entry->next)
   63 
   64 int json_to_bson_append(bson_t *doc, struct json_object *o)
   65 {
   66     json_object_object_iterator(o, key, val) {
   67         if (json_to_bson_append_element(doc, key, val) < 0) {
   68             LM_ERR("Failed to append new element\n");
   69             return -1;
   70         }
   71     }
   72 
   73     return 0;
   74 }
   75 
   76 int json_to_bson_append_element(bson_t *doc, const char *k, struct json_object *v)
   77 {
   78     bson_t child;
   79 
   80     if (!v) {
   81         bson_append_null(doc, k, -1);
   82         return 0;
   83     }
   84 
   85     switch (json_object_get_type(v)) {
   86         case json_type_int:
   87             if (!bson_append_int32(doc, k, -1, json_object_get_int(v))) {
   88                 LM_ERR("Failed to append int\n");
   89                 return -1;
   90             }
   91             break;
   92         case json_type_boolean:
   93             if (!bson_append_bool(doc, k, -1, json_object_get_boolean(v))) {
   94                 LM_ERR("Failed to append boolean\n");
   95                 return -1;
   96             }
   97             break;
   98         case json_type_double:
   99             if (!bson_append_double(doc, k, -1, json_object_get_double(v))) {
  100                 LM_ERR("Failed to append double\n");
  101                 return -1;
  102             }
  103             break;
  104         case json_type_string:
  105             if (!bson_append_utf8(doc, k, -1, json_object_get_string(v), -1)) {
  106                 LM_ERR("Failed to append string\n");
  107                 return -1;
  108             }
  109             break;
  110         case json_type_object:
  111             BSON_APPEND_DOCUMENT_BEGIN(doc, k, &child);
  112             if (json_to_bson_append(&child, v) < 0) {
  113                 LM_ERR("Failed to append to bson_t\n");
  114                 return -1;
  115             }
  116             bson_append_document_end(doc, &child);
  117             break;
  118         case json_type_array:
  119             BSON_APPEND_ARRAY_BEGIN(doc, k, &child);
  120             if (json_to_bson_append_array(&child, v) < 0) {
  121                 LM_ERR("Failed to append array to bson_t\n");
  122                 return -1;
  123             }
  124             bson_append_array_end(doc, &child);
  125             break;
  126         default:
  127             LM_ERR("Can't handle type for : %s\n", json_object_to_json_string(v));
  128             return -1;
  129     }
  130 
  131     return 0;
  132 }
  133 
  134 int json_to_bson(char *json, bson_t *doc)
  135 {
  136     struct json_object *obj;
  137 
  138     LM_DBG("Trying to convert [%s]\n", json);
  139 
  140     obj = json_tokener_parse(json);
  141     if (!obj) {
  142         LM_ERR("Failed to parse JSON: %s\n", json);
  143         return -2;
  144     }
  145 
  146     if (!json_object_is_type(obj, json_type_object)) {
  147         LM_ERR("Inconsistent JSON type\n");
  148         goto error;
  149     }
  150 
  151     bson_init(doc);
  152     if (json_to_bson_append(doc, obj) < 0) {
  153         LM_ERR("Failed to convert json to bson_t\n");
  154         bson_destroy(doc);
  155         goto error;
  156     }
  157 
  158     json_object_put(obj);
  159     return 0;
  160 
  161 error:
  162     if (obj)
  163         json_object_put(obj);
  164     return -1;
  165 }
  166 
  167 void bson_to_json_generic(struct json_object *obj, bson_iter_t *it,
  168                           bson_type_t type)
  169 {
  170     const char *curr_key;
  171     char *s, oid[25];
  172     const unsigned char *bin;
  173     int len;
  174     struct json_object *obj2 = NULL;
  175     unsigned int ts, ulen, _;
  176     bson_iter_t it2;
  177     bson_subtype_t subtype;
  178 
  179     while (bson_iter_next(it)) {
  180         curr_key = bson_iter_key(it);
  181         switch (bson_iter_type(it) ) {
  182                 case BSON_TYPE_INT32:
  183                     LM_DBG("Found key %s with type int\n", curr_key);
  184                     if (type == BSON_TYPE_DOCUMENT) {
  185                         json_object_object_add(obj,curr_key,
  186                                    json_object_new_int(bson_iter_int32(it)));
  187                     } else if (type == BSON_TYPE_ARRAY) {
  188                         json_object_array_add(obj,
  189                              json_object_new_int(bson_iter_int32(it)));
  190                     }
  191                     break;
  192                 case BSON_TYPE_INT64:
  193                     LM_DBG("Found key %s with type long\n", curr_key);
  194                     /* no intrinsic support in OpenSIPS for 64bit integers -
  195                      * converting to string */
  196                     s = int2str(bson_iter_int64(it), &len);
  197                     s[len]=0;
  198                     if (type == BSON_TYPE_DOCUMENT) {
  199                         json_object_object_add(obj,curr_key,json_object_new_string(s));
  200                     } else if (type == BSON_TYPE_ARRAY) {
  201                         json_object_array_add(obj,json_object_new_string(s));
  202                     }
  203                     break;
  204                 case BSON_TYPE_DOUBLE:
  205                     /* no intrinsic support in OpenSIPS for floating point numbers
  206                      * converting to int */
  207                     LM_DBG("Found key %s with type double\n",curr_key);
  208                     if (type == BSON_TYPE_DOCUMENT)
  209                         json_object_object_add(obj,curr_key,
  210                                 json_object_new_int((int)bson_iter_double(it)));
  211                     else if (type == BSON_TYPE_ARRAY)
  212                         json_object_array_add(obj,
  213                                json_object_new_int((int)bson_iter_double(it)));
  214                     break;
  215                 case BSON_TYPE_UTF8:
  216                     LM_DBG("Found key %s with type string\n",curr_key);
  217                     if (type == BSON_TYPE_DOCUMENT)
  218                         json_object_object_add(obj,curr_key,
  219                                 json_object_new_string(bson_iter_utf8(it, NULL)));
  220                     else if (type == BSON_TYPE_ARRAY)
  221                         json_object_array_add(obj,json_object_new_string(bson_iter_utf8(it, NULL)));
  222                     break;
  223                 case BSON_TYPE_BOOL:
  224                     LM_DBG("Found key %s with type bool\n",curr_key);
  225                     if (type == BSON_TYPE_DOCUMENT)
  226                         json_object_object_add(obj,curr_key,
  227                                 json_object_new_int((int)bson_iter_bool(it)));
  228                     else if (type == BSON_TYPE_ARRAY)
  229                         json_object_array_add(obj,json_object_new_int((int)bson_iter_bool(it)));
  230                     break;
  231                 case BSON_TYPE_DATE_TIME:
  232                     LM_DBG("Found key %s with type date\n",curr_key);
  233                     if (type == BSON_TYPE_DOCUMENT)
  234                         json_object_object_add(obj,curr_key,
  235                                 json_object_new_int((int)(bson_iter_date_time(it)/1000)));
  236                     else if (type == BSON_TYPE_ARRAY)
  237                         json_object_array_add(obj,json_object_new_int((int)(bson_iter_date_time(it)/1000)));
  238                     break;
  239                 case BSON_TYPE_ARRAY:
  240                     LM_DBG("Found key %s with type array\n",curr_key);
  241                     obj2 = json_object_new_array();
  242                     bson_iter_recurse(it, &it2);
  243                     bson_to_json_generic(obj2,&it2,BSON_TYPE_ARRAY);
  244                     if (type == BSON_TYPE_DOCUMENT)
  245                         json_object_object_add(obj,curr_key,obj2);
  246                     else if (type == BSON_TYPE_ARRAY)
  247                         json_object_array_add(obj,obj2);
  248                     break;
  249                 case BSON_TYPE_DOCUMENT:
  250                     LM_DBG("Found key %s with type object\n",curr_key);
  251                     obj2 = json_object_new_object();
  252                     bson_iter_recurse(it, &it2);
  253                     bson_to_json_generic(obj2,&it2,BSON_TYPE_DOCUMENT);
  254                     if (type == BSON_TYPE_DOCUMENT)
  255                         json_object_object_add(obj,curr_key,obj2);
  256                     else if (type == BSON_TYPE_ARRAY)
  257                         json_object_array_add(obj,obj2);
  258                     break;
  259                 case BSON_TYPE_OID:
  260                     memset(oid, 0, sizeof oid);
  261                     bson_oid_to_string(bson_iter_oid(it), oid);
  262                     json_object_object_add(obj,curr_key,
  263                             json_object_new_string(oid));
  264                     LM_DBG(" Found type %d for key %s \n",
  265                             bson_iter_type(it),curr_key);
  266                     break;
  267                 case BSON_TYPE_NULL:
  268                     json_object_object_add(obj,curr_key,NULL);
  269                     break;
  270                 case BSON_TYPE_TIMESTAMP:
  271                     bson_iter_timestamp(it, &ts, &_);
  272                     json_object_object_add(obj, curr_key,
  273                                            json_object_new_int(ts));
  274                     break;
  275                 case BSON_TYPE_BINARY:
  276                     bson_iter_binary(it, &subtype, &ulen, &bin);
  277                     json_object_object_add(obj, curr_key,
  278                                            json_object_new_string((const char *)bin));
  279                     break;
  280                 default:
  281                     LM_WARN("Unsupported type %d for key %s - skipping\n",
  282                             bson_iter_type(it),curr_key);
  283         }
  284     }
  285 }