Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief view<->json conversion lib
0003  *
0004  * @file view2exjson.c
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 #include <stdlib.h>
0035 #include <string.h>
0036 #include <memory.h>
0037 #include <ctype.h>
0038 #include <errno.h>
0039 
0040 #include <userlog.h>
0041 
0042 #include <ndrstandard.h>
0043 #include <ndebug.h>
0044 
0045 #include <exparson.h>
0046 #include <view2exjson.h>
0047 #include <ubf.h>
0048 #include <atmi_int.h>
0049 #include <typed_buf.h>
0050 #include <exbase64.h>
0051 
0052 #include "tperror.h"
0053 
0054 
0055 /*------------------------------Externs---------------------------------------*/
0056 /*------------------------------Macros----------------------------------------*/
0057 #define IS_INT(X) (BFLD_SHORT == X || BFLD_LONG == X || BFLD_INT == X)
0058 #define IS_NUM(X) (BFLD_FLOAT == X || BFLD_DOUBLE == X)
0059 #define IS_BIN(X) (BFLD_CARRAY == X)
0060 
0061 /* TODO: Fix atmi buffer size to match size of ATMI buffer size. */
0062 #define CARR_BUFFSIZE       NDRX_MSGSIZEMAX
0063 #define CARR_BUFFSIZE_B64   (4 * (CARR_BUFFSIZE) / 3)
0064 /*------------------------------Enums-----------------------------------------*/
0065 /*------------------------------Typedefs--------------------------------------*/
0066 /*------------------------------Globals---------------------------------------*/
0067 /*------------------------------Statics---------------------------------------*/
0068 /*------------------------------Prototypes------------------------------------*/
0069 
0070 
0071 exprivate long round_long( double r ) {
0072     return (r > 0.0) ? (r + 0.5) : (r - 0.5); 
0073 }
0074 
0075 /**
0076  * Convert JSON text buffer to UBF
0077  * @param view - Extracted view name
0078  * @param buffer - json text to parse
0079  * @param p_null_view_ind is set to EXTRUE in case if view is empty.
0080  *  optional param.
0081  * @return NULL on failure (or p_null_view_ind indicated that view is empty)
0082  */
0083 expublic char* ndrx_tpjsontoview(char *view, char *buffer, EXJSON_Object *data_object, int * p_null_view_ind)
0084 {
0085     int ret = EXSUCCEED;
0086     EXJSON_Value *root_value=NULL;
0087     EXJSON_Object *root_object=data_object;
0088     EXJSON_Object *view_object;
0089     EXJSON_Array *array;
0090     size_t i, cnt, j, arr_cnt;
0091     int type;
0092     char *name;
0093     char    *str_val;
0094     double d_val;
0095     int f_type;
0096     short   bool_val;
0097     char    *bin_buf=NULL;
0098     size_t bin_buf_len;
0099     char    *s_ptr;
0100     long vsize;
0101     int cnametyp;
0102     char *cstruct = NULL;
0103 
0104     bin_buf_len=CARR_BUFFSIZE+1;
0105     NDRX_MALLOC_OUT(bin_buf, bin_buf_len, char);
0106     
0107     if ( NULL != buffer )
0108     {
0109         NDRX_LOG(log_debug, "Parsing buffer: [%s]", buffer);
0110 
0111         root_value = exjson_parse_string_with_comments(buffer);
0112         type = exjson_value_get_type(root_value);
0113         NDRX_LOG(log_debug, "Type is %d", type);
0114 
0115         if (exjson_value_get_type(root_value) != EXJSONObject)
0116         {
0117             NDRX_LOG(log_debug, "Failed to parse root element");
0118             ndrx_TPset_error_fmt(TPEINVAL, "exjson: Failed to parse root element");
0119             EXFAIL_OUT(ret);
0120         }
0121         root_object = exjson_value_get_object(root_value);
0122     }
0123     else
0124     {
0125         NDRX_LOG(log_debug, "Parsing from data_object");
0126     }
0127 
0128     cnt = exjson_object_get_count(root_object);
0129     NDRX_LOG(log_debug, "cnt = %d", cnt);
0130     
0131     
0132     if (NULL==(name = (char *)exjson_object_get_name(root_object, 0)))
0133     {
0134         NDRX_LOG(log_error, "exjson: Invalid json no root VIEW object");
0135         ndrx_TPset_error_msg(TPEINVAL, "exjson: Invalid json no root VIEW object");
0136         EXFAIL_OUT(ret);
0137     }
0138     
0139     /* have some safe copy, assume buffer size */
0140     NDRX_STRCPY_SAFE_DST(view, name, NDRX_VIEW_NAME_LEN+1);
0141     
0142     /* It is normal to have empty view / due to embedded, thus
0143      * have an indicator to return that view actually is NULL / empty
0144      * (in certain cases)
0145      */
0146     if (NULL!=p_null_view_ind && EXEOS==name[0])
0147     {
0148         NDRX_LOG(log_info, "Importing NULL (empty) view");
0149         *p_null_view_ind=EXTRUE;
0150         goto out;
0151     }
0152         
0153     vsize = Bvsizeof(name);
0154     
0155     if (vsize < 0)
0156     {
0157         NDRX_LOG(log_error, "Failed to get view [%s] size: %s", 
0158                 name, Bstrerror(Berror));
0159         
0160         ndrx_TPset_error_fmt(TPEINVAL, "Failed to get view [%s] size: %s", 
0161                 name, Bstrerror(Berror));
0162         
0163         EXFAIL_OUT(ret);
0164     }
0165     
0166     NDRX_LOG(log_debug, "Allocating view [%s]: %ld", name, vsize);
0167     
0168     cstruct = tpalloc("VIEW", name, vsize);
0169     
0170     if (NULL==cstruct)
0171     {
0172         NDRX_LOG(log_error, "Failed to allocate view: %s", tpstrerror(tperrno));
0173         /* error must be set already! */
0174         EXFAIL_OUT(ret);
0175     }
0176     
0177     view_object = exjson_object_get_object(root_object, name);
0178     
0179     if (NULL==view_object)
0180     {
0181         NDRX_LOG(log_error, "exjson: Failed to get view object");
0182         ndrx_TPset_error_msg(TPESYSTEM, "exjson: Failed to get view object");
0183         EXFAIL_OUT(ret);
0184     }
0185 
0186     cnt = exjson_object_get_count(view_object);
0187     NDRX_LOG(log_debug, "cnt = %d", cnt);
0188     
0189     for (i =0; i< cnt; i++)
0190     {
0191         name = (char *)exjson_object_get_name(view_object, i);
0192 
0193         NDRX_LOG(log_debug, "came: [%s]", name);
0194         
0195         if (EXFAIL==Bvoccur(cstruct, view, name, NULL, NULL, NULL, &cnametyp))
0196         {
0197             NDRX_LOG(log_error, "Error getting field %s.%s infos: %s",
0198                     view, name, Bstrerror(Berror));
0199             
0200             if (BNOCNAME==Berror)
0201             {
0202                 NDRX_LOG(log_debug, "%s.%s not found in view -> ignore",
0203                         view, name);
0204                 continue;
0205             }
0206             else
0207             {
0208                 ndrx_TPset_error_fmt(TPESYSTEM, "Failed to get %s.%s infos: %s",
0209                         view, name, Bstrerror(Berror));
0210                 EXFAIL_OUT(ret);
0211             }
0212         }
0213 
0214         switch ((f_type=exjson_value_get_type(exjson_object_get_value_at(view_object, i))))
0215         {
0216             case EXJSONString:
0217             {
0218                 BFLDLEN str_len;
0219                 s_ptr = str_val = (char *)exjson_object_get_string(view_object, name);
0220                 NDRX_LOG(log_debug, "Str Value: [%s]", str_val);
0221 
0222                 /* If it is carray - parse hex... */
0223                 if (IS_BIN(cnametyp))
0224                 {
0225                     size_t st_len = bin_buf_len;
0226                     NDRX_LOG(log_debug, "Field is binary..."
0227                             " convert from b64...");
0228 
0229                     if (NULL==ndrx_base64_decode(str_val,
0230                             strlen(str_val),
0231                             &st_len,
0232                             bin_buf))
0233                     {
0234                         NDRX_LOG(log_debug, "Failed to "
0235                                 "decode base64!");
0236                         
0237                         ndrx_TPset_error_fmt(TPEINVAL, "Failed to "
0238                                 "decode base64: %s", name);
0239                         
0240                         EXFAIL_OUT(ret);
0241                     }
0242                     str_len = st_len;
0243                     s_ptr = bin_buf;
0244                     NDRX_LOG(log_debug, "got binary len [%d]", str_len);
0245                 }
0246                 else
0247                 {
0248                     str_len = strlen(s_ptr);
0249                 }
0250 
0251                 if (EXSUCCEED!=CBvchg(cstruct, view, name, 0, s_ptr, 
0252                         str_len, BFLD_CARRAY))
0253                 {
0254                     NDRX_LOG(log_error, "Failed to set view field %s.%s: %s",
0255                             view, name, Bstrerror(Berror));
0256                     ndrx_TPset_error_fmt(TPESYSTEM, "Failed to set view field %s.%s: %s",
0257                             view, name, Bstrerror(Berror));
0258                     EXFAIL_OUT(ret);
0259                 }
0260                 
0261                 break;
0262             }
0263             case EXJSONNumber:
0264             {
0265                 long l;
0266 
0267                 if (IS_INT(cnametyp))
0268                 {
0269                     l = exjson_object_get_intnumber(view_object, name);
0270                     NDRX_LOG(log_debug, "Integer Value: [%ld]", l);
0271 
0272                     if (EXSUCCEED!=CBvchg(cstruct, view, name, 0, 
0273                             (char *)&l, 0L, BFLD_LONG))
0274                     {
0275                         NDRX_LOG(log_error, "Failed to set [%s] to [%ld]!", 
0276                             name, l);
0277                         
0278                         ndrx_TPset_error_fmt(TPESYSTEM, "Failed to set [%s] to [%ld]!", 
0279                             name, l);
0280                         
0281                         EXFAIL_OUT(ret);
0282                     }
0283                 }
0284                 else
0285                 {
0286                     d_val = exjson_object_get_number(view_object, name);
0287                     NDRX_LOG(log_debug, "Double Value: [%lf]", d_val);
0288 
0289                     if (EXSUCCEED!=CBvchg(cstruct, view, name, 0, 
0290                             (char *)&d_val, 0L, BFLD_DOUBLE))
0291                     {
0292                         NDRX_LOG(log_error, "Failed to set [%s] to [%lf]: %s", 
0293                                 name, d_val, Bstrerror(Berror));
0294                         
0295                         ndrx_TPset_error_fmt(TPESYSTEM, "Failed to set [%s] to [%lf]: %s", 
0296                                 name, d_val, Bstrerror(Berror));
0297                         
0298                         EXFAIL_OUT(ret);
0299                     }
0300                 }
0301             }
0302                     break;
0303             case EXJSONBoolean:
0304             {
0305                 bool_val = (short)exjson_object_get_boolean(view_object, name);
0306                 NDRX_LOG(log_debug, "Bool Value: [%hd]", bool_val);
0307                 if (EXSUCCEED!=CBvchg(cstruct, view, name, 0, 
0308                         (char *)&bool_val, 0L, BFLD_SHORT))
0309                 {
0310                     NDRX_LOG(log_error, "Failed to set [%s] to [%hd]: %s", 
0311                             name, bool_val, Bstrerror(Berror));
0312                     
0313                     ndrx_TPset_error_fmt(TPESYSTEM, "Failed to set [%s] to [%hd]: %s", 
0314                             name, bool_val, Bstrerror(Berror));
0315                     
0316                     EXFAIL_OUT(ret);
0317                 }
0318             }
0319             break;
0320             /* Fielded buffer fields with more than one occurrance will go to array: 
0321              * Stuff here is almost identicial to above!
0322              */
0323             case EXJSONArray:
0324             {
0325                 if (NULL==(array = exjson_object_get_array(view_object, name)))
0326                 {
0327                     NDRX_LOG(log_error, "Failed to get array object!");
0328                     ndrx_TPset_error_fmt(TPESYSTEM, "Failed to get array object!");
0329                     EXFAIL_OUT(ret);
0330                 }
0331                 arr_cnt = exjson_array_get_count(array);
0332 
0333                 for (j = 0; j<arr_cnt; j++ )
0334                 {
0335                     switch (f_type = exjson_value_get_type(
0336                             exjson_array_get_value(array, j)))
0337                     {
0338                         case EXJSONString:
0339                         {
0340                             BFLDLEN str_len;
0341                             s_ptr = str_val = (char *)exjson_array_get_string(array, j);
0342                             NDRX_LOG(log_debug, 
0343                                         "Array j=%d, Str Value: [%s]", j, str_val);
0344 
0345                             /* If it is carray - parse hex... */
0346                             if (IS_BIN(cnametyp))
0347                             {
0348                                 size_t st_len = bin_buf_len;
0349                                 if (NULL==ndrx_base64_decode(str_val,
0350                                         strlen(str_val),
0351                                         &st_len,
0352                                         bin_buf))
0353                                 {
0354                                     NDRX_LOG(log_debug, "Failed to "
0355                                             "decode base64!");
0356                                     
0357                                     ndrx_TPset_error_fmt(TPEINVAL, "Failed to "
0358                                             "decode base64!");
0359                                     
0360                                     EXFAIL_OUT(ret);
0361                                 }
0362                                 str_len = st_len;
0363                                 s_ptr = bin_buf;
0364                                 NDRX_LOG(log_debug, "got binary len [%d]", str_len);
0365                             }
0366                             else
0367                             {
0368                                 str_len = strlen(s_ptr);
0369                             }
0370 
0371                             if (EXSUCCEED!=CBvchg(cstruct, view, name, j, 
0372                                     s_ptr, str_len, BFLD_CARRAY))
0373                             {
0374                                 NDRX_LOG(log_error, "Failed to set [%s] to [%s]: %s", 
0375                                         name, str_val, Bstrerror(Berror));
0376                                 ndrx_TPset_error_fmt(TPESYSTEM, "Failed to set [%s] "
0377                                         "to [%s]: %s", 
0378                                         name, str_val, Bstrerror(Berror));
0379                                 
0380                                 EXFAIL_OUT(ret);
0381                             }
0382                         }
0383                         break;
0384                         case EXJSONNumber:
0385                         {
0386                             long l;
0387        
0388                             if (IS_INT(cnametyp))
0389                             {
0390                                 l = exjson_array_get_intnumber(array, j);
0391                                 NDRX_LOG(log_debug, "Array j=%d, Integer Value: [%ld]", j, l);
0392 
0393                                 if (EXSUCCEED!=CBvchg(cstruct, view, name, j, 
0394                                         (char *)&l, 0L, BFLD_LONG))
0395                                 {
0396                                         NDRX_LOG(log_error, "Failed to set [%s] to [%ld]: %s", 
0397                                                 name, l, Bstrerror(Berror));
0398                                         
0399                                         ndrx_TPset_error_fmt(TPESYSTEM, 
0400                                                 "Failed to set [%s] to [%ld]: %s", 
0401                                                 name, l, Bstrerror(Berror));
0402                                         
0403                                         EXFAIL_OUT(ret);
0404                                 }
0405                             }
0406                             else
0407                             {
0408                                 d_val = exjson_array_get_number(array, j);
0409                                 NDRX_LOG(log_debug, "Array j=%d, Double Value: [%lf]", j, d_val);
0410 
0411                                 if (EXSUCCEED!=CBvchg(cstruct, view, name, j, 
0412                                         (char *)&d_val, 0L, BFLD_DOUBLE))
0413                                 {
0414                                     NDRX_LOG(log_error, "Failed to set [%s] to [%lf]: %s", 
0415                                             name, d_val, Bstrerror(Berror));
0416                                     
0417                                     ndrx_TPset_error_fmt(TPESYSTEM,"Failed to set "
0418                                             "[%s] to [%lf]: %s", 
0419                                             name, d_val, Bstrerror(Berror));
0420                                     
0421                                     EXFAIL_OUT(ret);
0422                                 }
0423                             }
0424                         }
0425                         break;
0426                         case EXJSONBoolean:
0427                         {
0428                             bool_val = (short)exjson_array_get_boolean(array, j);
0429                             NDRX_LOG(log_debug, "Array j=%d, Bool Value: [%hd]", j, bool_val);
0430                             if (EXSUCCEED!=CBvchg(cstruct, view, name, j, 
0431                                     (char *)&bool_val, 0L, BFLD_SHORT))
0432                             {
0433                                 NDRX_LOG(log_error, "Failed to set [%s] to [%hd]: %s", 
0434                                         name, bool_val, Bstrerror(Berror));
0435                                 
0436                                 ndrx_TPset_error_fmt(TPESYSTEM,"Failed to set "
0437                                         "[%s] to [%hd]: %s", 
0438                                         name, bool_val, Bstrerror(Berror));
0439                                 
0440                                 EXFAIL_OUT(ret);
0441                             }
0442                         }
0443                         default:
0444                             NDRX_LOG(log_error, 
0445                                         "Unsupported array elem "
0446                                         "type: %d", f_type);                            
0447                         break;
0448                     }
0449                 }
0450 
0451             }
0452             break;
0453             default:
0454             {
0455                 NDRX_LOG(log_error, "Unsupported type: %d", f_type);
0456             }
0457             break;
0458 
0459         }
0460     }
0461     
0462 out:
0463     /* cleanup code */
0464     if (NULL != root_value)
0465     {
0466         exjson_value_free(root_value);
0467     }
0468 
0469     if (EXSUCCEED!=ret && NULL!=cstruct)
0470     {
0471         tpfree(cstruct);
0472         cstruct = NULL;
0473     }
0474 
0475     if (NULL!=bin_buf)
0476     {
0477         NDRX_FREE(bin_buf);
0478     }
0479     
0480     
0481     return cstruct;
0482 }
0483 
0484 
0485 /**
0486  * Build json text from UBF buffer
0487  * @param p_ub  JSON buffer
0488  * @param buffer output json buffer
0489  * @param bufsize       output buffer size
0490  * @param flags BVACCESS_NOTNULL -> return only non NULL values, if not set,
0491  * return all
0492  * @return SUCCEED/FAIL 
0493  */
0494 expublic int ndrx_tpviewtojson(char *cstruct, char *view, char *buffer, 
0495         int bufsize, long flags, EXJSON_Object *data_object)
0496 {
0497     int ret = EXSUCCEED;
0498     int occs;
0499     int is_array;
0500     double d_val;
0501     long l_val;
0502     size_t strval_len = CARR_BUFFSIZE+1;
0503     char *strval=NULL; 
0504     
0505     size_t b64_buf_len =CARR_BUFFSIZE_B64+1;
0506     char *b64_buf=NULL;
0507     int is_num, is_int;
0508     char *s_ptr;
0509     BFLDLEN flen;
0510     
0511     Bvnext_state_t state;
0512     char cname[NDRX_VIEW_CNAME_LEN+1];
0513     int fldtype;
0514     BFLDOCC maxocc;
0515     long dim_size;
0516     
0517     EXJSON_Value *root_value = NULL;
0518     EXJSON_Object *root_object = data_object;
0519     EXJSON_Value *view_value = NULL;
0520     EXJSON_Object *view_object = NULL;
0521     
0522     char *serialized_string = NULL;
0523     BFLDOCC oc;
0524     EXJSON_Array *jarr=NULL;
0525     
0526     NDRX_MALLOC_OUT(strval, strval_len, char);
0527     NDRX_MALLOC_OUT(b64_buf, b64_buf_len, char);
0528 
0529     if (NULL == data_object)
0530     {
0531         root_value = exjson_value_init_object();
0532         root_object = exjson_value_get_object(root_value);
0533     }
0534     
0535     view_value = exjson_value_init_object();
0536     view_object = exjson_value_get_object(view_value);
0537     
0538     if( EXJSONSuccess != exjson_object_set_value(root_object, view, view_value) )
0539     {   
0540         
0541         if (NULL!=view_value)
0542         {
0543             exjson_value_free(view_value);
0544         }
0545 
0546         
0547         NDRX_LOG(log_error, "exjson: Failed to set root value");
0548         ndrx_TPset_error_msg(TPESYSTEM, "exjson: Failed to set root value");
0549         EXFAIL_OUT(ret);
0550     }
0551     
0552     if (EXEOS!=view[0] && EXFAIL==(ret=Bvnext(&state, view, cname, 
0553             &fldtype, &maxocc, &dim_size)))
0554     {
0555         NDRX_LOG(log_error, "Failed to iterate VIEW: %s", Bstrerror(Berror));
0556         ndrx_TPset_error_fmt(TPESYSTEM, "Failed to iterate VIEW: %s",  
0557                 Bstrerror(Berror));
0558         EXFAIL_OUT(ret);
0559     }
0560     
0561     while (ret && EXEOS!=cname[0])
0562     {
0563         int fulloccs;
0564         int realoccs;
0565         /* Get real occurrences */
0566         if (EXFAIL==(fulloccs=Bvoccur(cstruct, view, cname, NULL, &realoccs, NULL, NULL)))
0567         {
0568             NDRX_LOG(log_error, "Failed to get view field %s.%s infos: %s", 
0569                     view, cname, Bstrerror(Berror));
0570             ndrx_TPset_error_fmt(TPESYSTEM, "Failed to get view field %s.%s infos: %s", 
0571                     view, cname, Bstrerror(Berror));
0572             EXFAIL_OUT(ret);
0573         }
0574         
0575         if (flags & BVACCESS_NOTNULL)
0576         {
0577             occs = realoccs;
0578             NDRX_LOG(log_dump, "Using REAL (non null) occs: %s", occs);
0579         }
0580         else
0581         {
0582             occs = fulloccs;
0583             NDRX_LOG(log_dump, "Using set occs: %s", occs);
0584         }
0585         
0586         for (oc=0; oc<occs; oc++)
0587         {
0588             NDRX_LOG(log_debug, "Field: [%s] occ %d", cname, oc);
0589             if (0==oc)
0590             {
0591                 if (occs>1)
0592                 {
0593                     /* create array */
0594                     is_array = EXTRUE;
0595                     /* add array to document... */
0596                     if (EXJSONSuccess!=exjson_object_set_value(view_object, cname, 
0597                             exjson_value_init_array()))
0598                     {
0599                         NDRX_LOG(log_error, "exjson: Failed to add Array to root object!!");
0600                         ndrx_TPset_error_msg(TPESYSTEM, "exjson: Failed to add "
0601                                 "Array to root object!!");
0602                         EXFAIL_OUT(ret);
0603                     }
0604                     if (NULL == (jarr=exjson_object_get_array(view_object, cname)))
0605                     {
0606                         NDRX_LOG(log_error, "Failed to initialize array!!");
0607 
0608                         ndrx_TPset_error_msg(TPESYSTEM, "Failed to initialize array");
0609                         EXFAIL_OUT(ret);                    
0610                     }
0611                 }
0612                 else
0613                 {
0614                     is_array = EXFALSE;
0615                 }
0616             }
0617             else
0618             {
0619                 is_array = EXTRUE;
0620             }
0621 
0622             is_num = EXFALSE;
0623             is_int = EXFALSE;
0624 
0625             if (IS_INT(fldtype))
0626             {
0627                 if (EXSUCCEED!=CBvget(cstruct, view, cname, oc, 
0628                         (char *)&l_val, 0L, BFLD_LONG, 0))
0629                 {
0630                     NDRX_LOG(log_error, "Failed to get (long): %s.%s/%d: %s",
0631                                                     view, cname, oc, Bstrerror(Berror));
0632 
0633                     ndrx_TPset_error_fmt(TPESYSTEM, "Failed to get (long): %s.%s/%d: %s",
0634                                                     view, cname, oc, Bstrerror(Berror));
0635                     EXFAIL_OUT(ret);
0636                 }
0637                 is_int = EXTRUE;
0638                 NDRX_LOG(log_debug, "Numeric integer: %ld", l_val);
0639             }
0640             else if (IS_NUM(fldtype))
0641             {
0642                 if (EXSUCCEED!=CBvget(cstruct, view, cname, oc, 
0643                         (char *)&d_val, 0L, BFLD_DOUBLE, 0))
0644                 {
0645                     NDRX_LOG(log_error, "Failed to get (double): %s.%s/%d: %s",
0646                                                     view, cname, oc, Bstrerror(Berror));
0647 
0648                     ndrx_TPset_error_fmt(TPESYSTEM, "Failed to get (double): %s.%s/%d: %s",
0649                                                     view, cname, oc, Bstrerror(Berror));
0650                     EXFAIL_OUT(ret);
0651                 }
0652                 is_num = EXTRUE;
0653                 NDRX_LOG(log_debug, "Numeric double: %lf", d_val);
0654             }
0655             else
0656             {
0657                 flen = strval_len;
0658                 if (EXSUCCEED!=CBvget(cstruct, view, cname, oc, 
0659                         strval, &flen, BFLD_CARRAY, 0))
0660                 {
0661                     NDRX_LOG(log_error, "Failed to get (string): %s.%s/%d: %s",
0662                                             view, cname, oc, Bstrerror(Berror));
0663 
0664                     ndrx_TPset_error_fmt(TPESYSTEM, "Failed to get (string): %s.%s/%d: %s",
0665                                             view, cname, oc, Bstrerror(Berror));
0666 
0667                     EXFAIL_OUT(ret);
0668                 }
0669 
0670                 /* If it is carray, then convert to hex... */
0671                 if (IS_BIN(fldtype))
0672                 {
0673                     size_t outlen = b64_buf_len;
0674                     NDRX_LOG(log_debug, "Field is binary... convert to b64");
0675 
0676                     if (NULL==ndrx_base64_encode((unsigned char *)strval, flen, 
0677                                 &outlen, b64_buf))
0678                     {
0679                         NDRX_LOG(log_error, "Failed to convert to b64!");
0680 
0681                         ndrx_TPset_error_fmt(TPESYSTEM, "Failed to convert to b64!");
0682 
0683                         EXFAIL_OUT(ret);
0684                     }
0685                     /* b64_buf[outlen] = EXEOS; */
0686                     s_ptr = b64_buf;
0687 
0688                 }
0689                 else
0690                 {
0691                     strval[flen] = EXEOS;
0692                     s_ptr = strval;
0693                 }
0694 
0695                 NDRX_LOG(log_debug, "String value: [%s]", s_ptr);
0696             }
0697 
0698             if (is_array)
0699             {
0700                 /* Add array element 
0701                 exjson_object_set_value */
0702 
0703                 /* Add normal element */
0704                 if (is_int)
0705                 {
0706                     if (EXJSONSuccess!=exjson_array_append_intnumber(jarr, l_val))
0707                     {
0708                         NDRX_LOG(log_error, "Failed to set array elem to [%ld]!",
0709                                 l_val);
0710 
0711                         ndrx_TPset_error_fmt(TPESYSTEM, "exjson: Failed to set array "
0712                                 "elem to [%ld]!", l_val);
0713 
0714                         EXFAIL_OUT(ret);
0715                     }
0716                 }
0717                 else if (is_num)
0718                 {
0719                     if (EXJSONSuccess!=exjson_array_append_number(jarr, d_val))
0720                     {
0721                         NDRX_LOG(log_error, "Failed to set array elem to [%lf]!",
0722                                 d_val);
0723 
0724                         ndrx_TPset_error_fmt(TPESYSTEM, "exjson: Failed to set array "
0725                                 "elem to [%lf]!", d_val);
0726 
0727                         EXFAIL_OUT(ret);
0728                     }
0729                 }
0730                 else
0731                 {
0732                     if (EXJSONSuccess!=exjson_array_append_string(jarr, s_ptr))
0733                     {
0734                         NDRX_LOG(log_error, "Failed to set array elem to [%s]!", 
0735                                 s_ptr);
0736 
0737                         ndrx_TPset_error_fmt(TPESYSTEM, "exjson: Failed to set array "
0738                                 "elem to [%s]!", s_ptr);
0739 
0740                         EXFAIL_OUT(ret);
0741                     }
0742                 }
0743             }
0744             else
0745             {
0746                 /* Add normal element */
0747                 if (is_int)
0748                 {
0749                     if (EXJSONSuccess!=exjson_object_set_intnumber(view_object, cname, l_val))
0750                     {
0751                         NDRX_LOG(log_error, "Failed to set [%s] value to [%ld]!",
0752                                             cname, l_val);
0753 
0754                         ndrx_TPset_error_fmt(TPESYSTEM, "exjson: Failed to set [%s] "
0755                                 "value to [%ld]!", cname, l_val);
0756 
0757                         EXFAIL_OUT(ret);
0758                     }
0759                 }
0760                 else if (is_num)
0761                 {
0762                     if (EXJSONSuccess!=exjson_object_set_number(view_object, cname, d_val))
0763                     {
0764                         NDRX_LOG(log_error, "Failed to set [%s] value to [%lf]!",
0765                                             cname, d_val);
0766 
0767                         ndrx_TPset_error_fmt(TPESYSTEM, "exjson: Failed to set [%s] "
0768                                 "value to [%lf]!", cname, d_val);
0769 
0770                         EXFAIL_OUT(ret);
0771                     }
0772                 }
0773                 else
0774                 {
0775                     if (EXJSONSuccess!=exjson_object_set_string(view_object, cname, s_ptr))
0776                     {
0777                         NDRX_LOG(log_error, "Failed to set [%s] value to [%s]!",
0778                                         cname, s_ptr);
0779 
0780                         ndrx_TPset_error_fmt(TPESYSTEM, "exjson: Failed to set [%s] "
0781                                 "value to [%s]!", cname, s_ptr);
0782 
0783                         EXFAIL_OUT(ret);
0784                     }
0785                 }
0786             }
0787         } /* for occ */
0788     
0789     if (EXFAIL==(ret=Bvnext(&state, NULL, cname, &fldtype, &maxocc, &dim_size)))
0790     {
0791         NDRX_LOG(log_error, "Failed to iterate VIEW: %s", Bstrerror(Berror));
0792         ndrx_TPset_error_fmt(TPESYSTEM, "Failed to iterate VIEW: %s",  
0793             Bstrerror(Berror));
0794         EXFAIL_OUT(ret);
0795     }
0796 
0797     } /* while ret */ 
0798 
0799     if (NULL != buffer)
0800     {
0801         serialized_string = exjson_serialize_to_string(root_value);
0802 
0803         if (strlen(serialized_string) < bufsize ) /* have space for EOS */
0804         {
0805 
0806             NDRX_STRCPY_SAFE_DST(buffer, serialized_string, bufsize);
0807             NDRX_LOG(log_debug, "Got JSON: [%s]", buffer);
0808         }
0809         else
0810         {
0811             NDRX_LOG(log_error, "Buffer too short: Got json size: [%d] buffer size: [%d]", 
0812                     strlen(serialized_string)+1, bufsize);
0813 
0814             ndrx_TPset_error_fmt(TPEOS, "Buffer too short: Got json size: "
0815                     "[%d] buffer size: [%d]",  strlen(serialized_string)+1, bufsize);
0816 
0817             EXFAIL_OUT(ret);
0818         }
0819     }
0820 out:
0821 
0822     if (NULL!=serialized_string)
0823     {
0824         exjson_free_serialized_string(serialized_string);
0825     }
0826 
0827     if (NULL==data_object && NULL!=root_value)
0828     {
0829         exjson_value_free(root_value);
0830     }
0831 
0832     if (NULL!=strval)
0833     {
0834         NDRX_FREE(strval);
0835     }
0836     
0837     
0838     if (NULL!=b64_buf)
0839     {
0840         NDRX_FREE(b64_buf);
0841     }
0842 
0843     /* At iter end, ret normally becomes 0, thus fine here as SUCCEED */
0844     return ret;
0845 }
0846 
0847 /**
0848  * auto-buffer convert func. view->ubf
0849  * @param buffer
0850  * @return 
0851  */
0852 expublic int typed_xcvt_json2view(buffer_obj_t **buffer)
0853 {
0854     int ret = EXSUCCEED;
0855     buffer_obj_t *tmp_b;
0856     /* Allocate the max UBF buffer */
0857     char * tmp = NULL;
0858     char view[NDRX_VIEW_NAME_LEN+1];
0859     
0860     /* Do the convert */
0861     ndrx_TPunset_error();
0862     if (NULL==(tmp=ndrx_tpjsontoview(view, (*buffer)->buf, NULL, NULL)))
0863     {
0864         NDRX_LOG(log_error, "Failed to convert JSON->VIEW: %s", 
0865                 tpstrerror(tperrno));
0866         EXFAIL_OUT(ret);
0867     }
0868 
0869     tmp_b=ndrx_find_buffer((char *)tmp);
0870     tmp_b->autoalloc = (*buffer)->autoalloc;
0871 
0872     /* finally return the buffer */
0873     NDRX_LOG(log_info, "Returning new buffer %p", tmp_b);
0874     *buffer = tmp_b;
0875 out:
0876     return ret;
0877 }
0878 
0879 
0880 /**
0881  * auto-buffer convert func. view->json
0882  * @param buffer
0883  * @param flags - conversion mode 0 (incl NULL0, BVACCESS_NOTNULL - not null
0884  * @return 
0885  */
0886 expublic int typed_xcvt_view2json(buffer_obj_t **buffer, long flags)
0887 {
0888     int ret = EXSUCCEED;
0889     buffer_obj_t *tmp_b;
0890     char type[XATMI_SUBTYPE_LEN+1];
0891     char subtype[XATMI_TYPE_LEN+1]={EXEOS};
0892     char * tmp = NULL;
0893     char * newbuf_out = NULL; /* real output buffer */
0894 
0895     if (NULL==(tmp = tpalloc("JSON", NULL, NDRX_MSGSIZEMAX)))
0896     {
0897         NDRX_LOG(log_error, "failed to convert UBF->JSON. JSON buffer alloc fail!: %s",
0898                 tpstrerror(tperrno));
0899         EXFAIL_OUT(ret);
0900     }
0901     
0902     /* Get view name... */
0903     
0904     if (EXFAIL==tptypes((*buffer)->buf, type, subtype))
0905     {
0906          NDRX_LOG(log_error, "Failed to get view infos: %s",
0907                 tpstrerror(tperrno));
0908         EXFAIL_OUT(ret);
0909     }
0910     
0911     NDRX_LOG(log_debug, "Got types %s/%s", type, subtype);
0912 
0913     /* Do the convert */
0914     ndrx_TPunset_error();
0915     if (EXSUCCEED!=ndrx_tpviewtojson((*buffer)->buf, 
0916             subtype, tmp, NDRX_MSGSIZEMAX, flags, NULL))
0917     {
0918         tpfree((char *)tmp);
0919         NDRX_LOG(log_error, "Failed to convert VIEW->JSON: %s", 
0920                 tpstrerror(tperrno));
0921         EXFAIL_OUT(ret);
0922     }
0923 
0924     /* Shrink the buffer (by reallocating) new! 
0925      * we will do the shrink because, msg Q might not have settings set for
0926      * max buffer size...
0927      */
0928     if (NULL==(newbuf_out = tpalloc("JSON", NULL, strlen(tmp)+1)))
0929     {
0930         tpfree((char *)tmp);
0931         NDRX_LOG(log_error, "Failed to alloc output JSON %ld: %s", strlen(tmp)+1, 
0932                 tpstrerror(tperrno));
0933         EXFAIL_OUT(ret);
0934     }
0935 
0936     strcpy(newbuf_out, tmp);
0937 
0938     tmp_b=ndrx_find_buffer((char *)newbuf_out);
0939     tmp_b->autoalloc = (*buffer)->autoalloc;
0940 
0941     /* Kill the buffers */
0942     tpfree((*buffer)->buf);
0943     tpfree((char *)tmp);
0944 
0945     /* finally return the buffer */
0946     NDRX_LOG(log_info, "Returning new buffer %p", tmp_b->buf);
0947     
0948     *buffer = tmp_b;
0949 out:
0950     return ret;
0951 }
0952 
0953 /* vim: set ts=4 sw=4 et smartindent: */