Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Protocol view support
0003  *
0004  * @file pview.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 <sys/socket.h>
0037 #include <sys/time.h>
0038 #include <sys/types.h>
0039 #include <arpa/inet.h>
0040 #include <netinet/in.h>
0041 #include <errno.h>
0042 #include <fcntl.h>
0043 #include <netdb.h>
0044 #include <string.h>
0045 #include <unistd.h>
0046 #include <atmi.h>
0047 
0048 #include <stdio.h>
0049 #include <stdlib.h>
0050 
0051 #include <exnet.h>
0052 #include <ndrstandard.h>
0053 #include <ndebug.h>
0054 #include <ndrxdcmn.h>
0055 
0056 #include <utlist.h>
0057 #include <ubf_int.h>            /* FLOAT_RESOLUTION, DOUBLE_RESOLUTION */
0058 
0059 #include <typed_buf.h>
0060 #include <ubfutil.h>
0061 #include <math.h>
0062 #include <xatmi.h>
0063 #include <userlog.h>
0064 
0065 #include "fdatatype.h"
0066 #include <multibuf.h>
0067 #include "exnetproto.h"
0068 #include <ubfview.h>
0069 /*---------------------------Externs------------------------------------*/
0070 /*---------------------------Macros-------------------------------------*/
0071 /*---------------------------Enums--------------------------------------*/
0072 /*---------------------------Typedefs-----------------------------------*/
0073 /*---------------------------Statics------------------------------------*/
0074 /*---------------------------Prototypes---------------------------------*/
0075 
0076 /**
0077  * Resolve view by name, version with init
0078  * @param vname view name
0079  * @return  NULL or ptr to view object
0080  */
0081 expublic ndrx_typedview_t * ndrx_view_get_init(char *vname)
0082 {
0083     ndrx_typedview_t *ret=NULL;
0084     
0085     /* check that we have init in place */
0086     if (EXSUCCEED!=ndrx_view_init())
0087     {
0088         NDRX_LOG(log_error, "Failed to init view sub-system");
0089         goto out;
0090     }
0091     
0092     EXHASH_FIND_STR(ndrx_G_view_hash, vname, ret);
0093 out:
0094     return ret;
0095 }
0096 
0097 /**
0098  * Convert view XATMI buffer to protocol
0099  * Loop over the view, read the non null fields
0100  * NOTE: In case if this MBUF, then view data is encapsulated 
0101  * in ndrx_view_header 
0102  * If view comes from UBF then it is BVIEWFLD
0103  * @param fld Current proto field
0104  * @param level recursion level
0105  * @param offset offset in C struct (not to the field)
0106  * @param ex_buf start of the C struct ptr
0107  * @param ex_len C len
0108  * @param proto_buf output buffer
0109  * @param proto_buf_offset current offset at output buf
0110  * @param p_ub_data not used
0111  * @param proto_bufsz output buffer size
0112  * @return EXSUCCEED/EXFAIL
0113  */
0114 expublic int exproto_build_ex2proto_view(cproto_t *fld, int level, long offset,
0115         char *ex_buf, long ex_len, char *proto_buf, long *proto_buf_offset,
0116         long proto_bufsz)
0117 {
0118     int ret = EXSUCCEED;
0119     BFLDID bfldid;
0120     BFLDOCC occ;
0121     char *p;
0122     /* Indicators.. */
0123     BFLDOCC realocc;
0124     unsigned short *L_length; /* will transfer as long */
0125     ndrx_typedview_t *v;
0126     ndrx_typedview_field_t *vf;
0127     char *cstruct;
0128     char f_data_buf[sizeof(proto_ufb_fld_t)+sizeof(char *)]; /* just store ptr */
0129     ssize_t f_data_buf_len;
0130     proto_ufb_fld_t *fldata = (proto_ufb_fld_t*)f_data_buf;
0131     short accept_tags[] = {VIEW_TAG_CNAME, 0, EXFAIL};
0132     xmsg_t tmp_cv;
0133     BVIEWFLD vheader;
0134     long dim_size;
0135                     
0136     NDRX_LOG(log_debug, "%s enter at level %d", __func__, level);
0137     
0138     if (XATMIBUFPTR==XTYPE(fld->type))
0139     {
0140         BVIEWFLD *vdata = (BVIEWFLD *)ex_buf;
0141             
0142         NDRX_STRCPY_SAFE(vheader.vname, vdata->vname);
0143         vheader.vflags = vdata->vflags;
0144         cstruct = vdata->data;
0145     }
0146     else
0147     {
0148         ndrx_view_header *p_hdr = (ndrx_view_header *)ex_buf;
0149         
0150         /* Resolve view descriptor */
0151         NDRX_STRCPY_SAFE(vheader.vname, p_hdr->vname);
0152         vheader.vflags = p_hdr->vflags;
0153         cstruct = p_hdr->data;
0154     }
0155     
0156     /* write off header... */
0157     tmp_cv.descr = "VIEWHDR";
0158     tmp_cv.tab[0] = ndrx_G_view;
0159     tmp_cv.tabcnt=1;
0160     tmp_cv.command = 0; /* not used... */
0161     
0162     if (EXSUCCEED!=exproto_build_ex2proto(&tmp_cv, 0, 0,(char *)&vheader, 
0163         sizeof(vheader), proto_buf, proto_buf_offset,  
0164         NULL, fldata, proto_bufsz))
0165     {
0166         NDRX_LOG(log_error, "Failed to emit view[%s] header", vheader.vname);
0167         EXFAIL_OUT(ret);
0168     }
0169     
0170     if (EXEOS==vheader.vname[0])
0171     {
0172         NDRX_LOG(log_debug, "Empty view - no data conv");
0173         goto out;
0174     }
0175 
0176     if (NULL==(v = ndrx_view_get_init(vheader.vname)))
0177     {
0178         NDRX_LOG(log_error, "View [%s] not found!", vheader.vname);
0179         EXFAIL_OUT(ret);
0180     }
0181     
0182     tmp_cv.descr = "VIEWLFLD";
0183     tmp_cv.tab[0] = ndrx_G_view_field;
0184     tmp_cv.tabcnt=1;
0185     tmp_cv.command = 0; /* not used... */
0186         
0187     DL_FOREACH(v->fields, vf)
0188     {        
0189         NDRX_STRCPY_SAFE(fldata->cname, vf->cname);
0190            
0191         /* send only up till last non null field.. */
0192         if (EXFAIL==ndrx_Bvoccur_int(cstruct, v, 
0193                 vf, NULL, &realocc, 
0194                 &dim_size, NULL))
0195         {
0196             /* currently error is not returned... */
0197             NDRX_LOG(log_error, "Bvoccur() failed: %s", Bstrerror(Berror));
0198             EXFAIL_OUT(ret);
0199         }
0200         
0201         if (realocc > vf->count)
0202         {
0203             NDRX_LOG(log_error, "Invalid count for field %s.%s in "
0204                     "view %hd, specified: %hd", v->vname, vf->cname, 
0205                     vf->count, realocc);
0206             EXFAIL_OUT(ret);
0207         }
0208 
0209         for (occ=0; occ<realocc; occ++)
0210         {
0211             p = cstruct+vf->offset+occ*dim_size;
0212             
0213             /* just increment the field id for view.. */
0214             bfldid++;
0215             
0216             /* get the carray length  */
0217             if (vf->flags & NDRX_VIEW_FLAG_LEN_INDICATOR_L)
0218             {
0219                 L_length = (unsigned short *)(cstruct+vf->length_fld_offset+
0220                             occ*sizeof(unsigned short));
0221                 fldata->bfldlen= (BFLDLEN)*L_length;
0222             }
0223             else
0224             {
0225                 fldata->bfldlen=dim_size;
0226             }
0227             
0228             /* Optimize out the length field for fixed
0229              * data types.
0230              */
0231             accept_tags[1] = ndrx_G_view_proto_tag_map[vf->typecode_full];
0232             
0233             /* put the pointer value there */
0234             memcpy(fldata->buf, &p, sizeof(char *));
0235             
0236             f_data_buf_len = sizeof(f_data_buf);
0237             
0238             /* lets drive our structure? */
0239             ret = exproto_build_ex2proto(&tmp_cv, 0, 0,(char *)fldata, 
0240                     f_data_buf_len, proto_buf, proto_buf_offset,  
0241                     accept_tags, fldata, proto_bufsz);
0242 
0243             if (EXSUCCEED!=ret)
0244             {
0245                 NDRX_LOG(log_error, "Failed to convert sub/tag %x: view: [%s] "
0246                         "cname: [%s] occ: %d"
0247                     "at offset %ld", fld->tag, v->vname, vf->cname, occ);
0248                 EXFAIL_OUT(ret);
0249             }
0250         }
0251     }
0252     
0253 out:
0254             
0255     return ret;
0256 }
0257 
0258 
0259 /* vim: set ts=4 sw=4 et smartindent: */