Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief ATMI tpexport function implementation (Common version)
0003  *
0004  * @file tpexport.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 
0035 /*---------------------------Includes-----------------------------------*/
0036 #include <stdio.h>
0037 #include <stdarg.h>
0038 #include <memory.h>
0039 #include <stdlib.h>
0040 #include <errno.h>
0041 
0042 #include <atmi.h>
0043 #include <userlog.h>
0044 #include <ndebug.h>
0045 #include <tperror.h>
0046 #include <typed_buf.h>
0047 #include <atmi_int.h>
0048 
0049 #include <exparson.h>
0050 #include <view2exjson.h>
0051 #include <exbase64.h>
0052 /*---------------------------Externs------------------------------------*/
0053 /*---------------------------Macros-------------------------------------*/
0054 #define CARR_BUFFSIZE       NDRX_MSGSIZEMAX
0055 #define CARR_BUFFSIZE_B64   (4 * (CARR_BUFFSIZE) / 3)
0056 /* Support #553 fixed */
0057 #define CARR_BUFFSIZE_B64_EOS   (CARR_BUFFSIZE_B64+1)
0058 /*---------------------------Enums--------------------------------------*/
0059 /*---------------------------Typedefs-----------------------------------*/
0060 /*---------------------------Globals------------------------------------*/
0061 /*---------------------------Statics------------------------------------*/
0062 /*---------------------------Prototypes---------------------------------*/
0063 
0064 /**
0065  * Export Any buffer to JSON format
0066  * @param bufctl
0067  * @param ibuf
0068  * @param ilen
0069  * @param ostr
0070  * @param olen
0071  * @param flags
0072  * @param parent_root_object if exporting this as sub-buffer (PTR) in already in progress export
0073  * @return 
0074  */
0075 extern NDRX_API int ndrx_tpexportex(ndrx_expbufctl_t *bufctl, 
0076             char *ibuf, long ilen, char *ostr, long *olen, long flags, 
0077             EXJSON_Object *parent_root_object)
0078 {
0079     int ret=EXSUCCEED;
0080     char buftype[16+1]={EXEOS};
0081     char subtype[XATMI_SUBTYPE_LEN]={EXEOS};
0082     size_t outlen;
0083     char *b64_buf=NULL;
0084     long size_existing=EXFAIL;
0085 
0086     EXJSON_Value *root_value = NULL;
0087     EXJSON_Object *root_object = NULL;
0088     
0089     EXJSON_Value *data_value = NULL;
0090     EXJSON_Object *data_object = NULL;
0091     
0092     char *serialized_string = NULL;
0093 
0094     NDRX_LOG(log_debug, "%s: enter", __func__);
0095     
0096     if ( NULL == parent_root_object )
0097     {
0098         root_value = exjson_value_init_object();
0099         
0100         if (NULL==root_value)
0101         {
0102             ndrx_TPset_error_fmt(TPESYSTEM, "Failed to init json object value - mem issue?");
0103             EXFAIL_OUT(ret);
0104         }
0105         
0106         root_object = exjson_value_get_object(root_value);
0107     }
0108     else
0109     {
0110         root_object = parent_root_object;
0111     }
0112     
0113     b64_buf=NDRX_MALLOC(CARR_BUFFSIZE_B64_EOS);
0114     
0115     if (NULL==b64_buf)
0116     {
0117         NDRX_LOG(log_error, "Failed to malloc %d bytes: %s", 
0118             CARR_BUFFSIZE_B64_EOS, strerror(errno));
0119         EXFAIL_OUT(ret);
0120     }
0121     
0122     /* how about carray ilen? */
0123     if (EXFAIL==(size_existing=ndrx_tptypes(ibuf, buftype, subtype)))
0124     {
0125         NDRX_LOG(log_error, "Cannot determine buffer type");
0126         EXFAIL_OUT(ret);
0127     }
0128 
0129     NDRX_LOG(log_debug, 
0130              "Got buftype=[%s] subtype=[%s] size=[%ld]",
0131              buftype, subtype, size_existing);
0132 
0133     if (EXJSONSuccess!=exjson_object_set_string(root_object, "buftype", buftype))
0134     {
0135         NDRX_LOG(log_error, "Failed to set buftype data");
0136         EXFAIL_OUT(ret);
0137     }
0138 
0139     if ( EXJSONSuccess!=exjson_object_set_number(root_object, "version", TPIMPEXP_VERSION_MAX) ) 
0140     {
0141         NDRX_LOG(log_error, "Failed to set version data");
0142         EXFAIL_OUT(ret);
0143     }
0144     if ( strlen(subtype)>0 )
0145     {
0146         if (EXJSONSuccess!=exjson_object_set_string(root_object, "subtype", subtype))
0147         {
0148             NDRX_LOG(log_error, "Failed to set subtype data");
0149             EXFAIL_OUT(ret);
0150         }
0151     }
0152 
0153     if ( 0==strcmp(BUF_TYPE_STRING_STR, buftype) )
0154     {
0155         if (EXJSONSuccess!=exjson_object_set_string(root_object, "data", ibuf))
0156         {
0157             NDRX_LOG(log_error, "Failed to set string data=[%s]", ibuf);
0158             EXFAIL_OUT(ret);
0159         }
0160     }
0161     else if ( 0 == strcmp(BUF_TYPE_UBF_STR, buftype))
0162     {
0163         if (NULL==(data_value = exjson_value_init_object()))
0164         {
0165             NDRX_LOG(log_error, "Failed to init data_value");
0166             EXFAIL_OUT(ret);
0167         }
0168 
0169         if (NULL==(data_object = exjson_value_get_object(data_value)))
0170         {
0171             NDRX_LOG(log_error, "Failed to init data_object");
0172             EXFAIL_OUT(ret);
0173         }
0174 
0175         if (EXSUCCEED!=ndrx_tpubftojson((UBFH *)ibuf, NULL, 0, data_object))
0176         {
0177             NDRX_LOG(log_error, "Failed to build data object from UBF!!!!");
0178             EXFAIL_OUT(ret);
0179         }
0180         
0181         if (EXJSONSuccess!=exjson_object_set_value(root_object,"data",data_value))
0182         {
0183             /* clean up objects? */
0184             exjson_value_free(data_value);
0185                     
0186             NDRX_LOG(log_error, "Failed to set data object with UBF!!!!");
0187             EXFAIL_OUT(ret);
0188         }
0189     }
0190     else if ( 0 == strcmp(BUF_TYPE_VIEW_STR, buftype))
0191     {
0192         if (NULL==(data_value = exjson_value_init_object()))
0193         {
0194             NDRX_LOG(log_error, "Failed to init data_value");
0195             EXFAIL_OUT(ret);
0196         }
0197 
0198         if (NULL==(data_object = exjson_value_get_object(data_value)))
0199         {
0200             NDRX_LOG(log_error, "Failed to init data_object");
0201             EXFAIL_OUT(ret);
0202         }
0203         if (EXSUCCEED!=ndrx_tpviewtojson((char *)ibuf, subtype, NULL, 0L, 
0204                 BVACCESS_NOTNULL, data_object))
0205         {
0206             NDRX_LOG(log_error, "Failed to build data object from VIEW!!!!");
0207             EXFAIL_OUT(ret);
0208         }
0209         if (EXJSONSuccess!=exjson_object_set_value(root_object,"data",data_value))
0210         {
0211             NDRX_LOG(log_error, "Failed to set data object with VIEW!!!!");
0212             EXFAIL_OUT(ret);
0213         }
0214     }
0215     else if ( 0 == strcmp(BUF_TYPE_CARRAY_STR, buftype))
0216     {
0217         NDRX_LOG(log_debug, "ibuf is binary... convert to b64");
0218         outlen = CARR_BUFFSIZE_B64_EOS;
0219         if (NULL==ndrx_base64_encode((unsigned char *)ibuf, size_existing, 
0220                 &outlen, b64_buf))
0221         {
0222                 NDRX_LOG(log_error, "Failed to convert to b64!");
0223                 EXFAIL_OUT(ret);
0224         }
0225 
0226         /* TODO: Where is EOS??? */
0227         
0228         if (EXJSONSuccess!=exjson_object_set_string(root_object, "data", b64_buf))
0229         {
0230             NDRX_LOG(log_error, "Failed to set carray data=[%s]", b64_buf);
0231             EXFAIL_OUT(ret);
0232         }
0233     }
0234     else if ( 0 == strcmp(BUF_TYPE_JSON_STR, buftype))
0235     {
0236         if (NULL==(data_value = exjson_parse_string(ibuf)))
0237         {
0238             NDRX_LOG(log_error, "Failed to parse ibuf");
0239             EXFAIL_OUT(ret);
0240         }
0241 /*
0242         if (NULL==(data_object = exjson_value_get_object(data_value)))
0243         {
0244             NDRX_LOG(log_error, "Failed to init data_object");
0245             EXFAIL_OUT(ret);
0246         }
0247  */
0248         if (EXJSONSuccess!=exjson_object_set_value(root_object,"data",data_value))
0249         {
0250             NDRX_LOG(log_error, "Failed to set data object with JSON!!!!");
0251             EXFAIL_OUT(ret);
0252         }
0253     }
0254     else
0255     {
0256         EXFAIL_OUT(ret);
0257     }
0258 
0259     if (NULL==parent_root_object)
0260     {
0261         serialized_string = exjson_serialize_to_string(root_value);
0262         if (strlen(serialized_string) < *olen)
0263         {
0264             NDRX_LOG(log_debug, "Return JSON: [%s]", serialized_string);
0265 
0266             if ( TPEX_STRING == flags )
0267             {
0268                 NDRX_LOG(log_debug, "convert to b64");
0269                 outlen = *olen;
0270                 if (NULL==ndrx_base64_encode((unsigned char *)serialized_string, 
0271                             strlen(serialized_string), &outlen, ostr))
0272                 {
0273                     NDRX_LOG(log_error, "Failed to convert to b64!");
0274                     EXFAIL_OUT(ret);
0275                 }
0276             }
0277             else
0278             {
0279                 NDRX_STRCPY_SAFE_DST(ostr, serialized_string, *olen);
0280                 *olen = strlen(ostr)+1;
0281             }
0282         }
0283         else
0284         {
0285             NDRX_LOG(log_error, "olen too short: ostr size: [%d] olen size: [%d]", 
0286                     strlen(serialized_string)+1, *olen);
0287             EXFAIL_OUT(ret);
0288         }
0289     }
0290     else
0291     {
0292         NDRX_LOG(log_debug, "Not serializing as having parent_root_object");
0293     }
0294 
0295 out:
0296 
0297     NDRX_LOG(log_debug, "%s: return %d", __func__, ret);
0298 
0299     if (NULL!=serialized_string)
0300     {
0301         exjson_free_serialized_string(serialized_string);
0302     }
0303 
0304     if (NULL==parent_root_object && NULL!=root_value)
0305     {
0306         exjson_value_free(root_value);
0307     }
0308     
0309     if (NULL!=b64_buf)
0310     {
0311         NDRX_FREE(b64_buf);
0312     }
0313 
0314     return ret;
0315 }
0316 /* vim: set ts=4 sw=4 et smartindent: */