Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief VIEW UBF operations (UBF->C struct, C struct->UBF)
0003  *
0004  * @file view_ubf.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 <string.h>
0035 #include <stdio.h>
0036 #include <stdlib.h>
0037 #include <memory.h>
0038 #include <errno.h>
0039 #include <dirent.h>
0040 #include <limits.h>
0041 
0042 #include <ndrstandard.h>
0043 #include <ubfview.h>
0044 #include <ndebug.h>
0045 
0046 #include <userlog.h>
0047 #include <view_cmn.h>
0048 #include <ferror.h>
0049 #include <ubfutil.h>
0050 
0051 #include "Exfields.h"
0052 /*---------------------------Externs------------------------------------*/
0053 /*---------------------------Macros-------------------------------------*/
0054 /*---------------------------Enums--------------------------------------*/
0055 /*---------------------------Typedefs-----------------------------------*/
0056 /*---------------------------Globals------------------------------------*/
0057 /*---------------------------Statics------------------------------------*/
0058 /*---------------------------Prototypes---------------------------------*/
0059 
0060 /**
0061  * Fill the C structure with UBF data
0062  * @param p_ub ptr to UBF buffer
0063  * @param v resolved view
0064  * @param cstruct ptr to memory block where view instance lives
0065  * @return EXSUCCEED/EXFAIL
0066  */
0067 expublic int ndrx_Bvftos_int(UBFH *p_ub, ndrx_typedview_t *v, char *cstruct)
0068 {
0069     int ret = EXSUCCEED;
0070     int occ;
0071     int dim_size;
0072     char *fld_offs;
0073     BFLDLEN len;
0074     short *C_count;
0075     short C_count_stor;
0076     unsigned short *L_length;
0077     unsigned short L_length_stor;
0078     long l;
0079     ndrx_typedview_field_t *f;
0080     
0081     UBF_LOG(log_info, "Into %s", __func__);
0082     
0083     /* Go over the c struct  */
0084     DL_FOREACH(v->fields, f)
0085     {
0086         if (f->flags & NDRX_VIEW_FLAG_1WAYMAP_UBF2C_S)
0087         {
0088             dim_size = f->fldsize/f->count;
0089             
0090             if (f->flags & NDRX_VIEW_FLAG_ELEMCNT_IND_C)
0091             {
0092                 C_count = (short *)(cstruct+f->count_fld_offset);
0093             }
0094             else
0095             {
0096                 C_count = &C_count_stor;
0097             }
0098             
0099             *C_count = 0;
0100             for (occ=0; occ<f->count; occ++)
0101             {
0102                 fld_offs = cstruct+f->offset+occ*dim_size;
0103                 
0104                 if (f->flags & NDRX_VIEW_FLAG_LEN_INDICATOR_L)
0105                 {
0106                     L_length = (unsigned short *)(cstruct+f->length_fld_offset+
0107                             occ*sizeof(unsigned short));
0108                 }
0109                 else
0110                 {
0111                     L_length = &L_length_stor;
0112                 }
0113                 
0114                 *L_length = 0;
0115                 len = dim_size;
0116 
0117                 if (
0118                         (
0119                             BFLD_INT==f->typecode_full && 
0120                             EXSUCCEED!=CBget(p_ub, f->ubfid, occ, (char *)&l, 0L, BFLD_LONG)
0121                          )
0122                          ||
0123 
0124                         (
0125                             BFLD_INT!=f->typecode_full && 
0126                             EXSUCCEED!=CBget(p_ub, f->ubfid, occ, fld_offs, &len, f->typecode_full)
0127                         )
0128                     )
0129                 {
0130                     UBF_LOG(log_info, "Failed to get %d field: %s",
0131                             f->ubfid, Bstrerror(Berror));
0132 
0133                     if (BNOTPRES!=Berror)
0134                     {
0135                         UBF_LOG(log_error, "Error getting field: %s", 
0136                                 Bstrerror(Berror));
0137                         /* error already set */
0138                         EXFAIL_OUT(ret);
0139 
0140                     }
0141                     else
0142                     {
0143                         /* unset UBF error */
0144                         ndrx_Bunset_error();
0145 
0146                         /* Setup NULL at given occ, but we need to do this for occ! */
0147                         if (EXSUCCEED!=ndrx_Bvselinit_int(v, f, occ, cstruct))
0148                         {
0149                             ndrx_Bset_error_fmt(BBADVIEW, "Failed to set NULL to %s.%s",
0150                                     v->vname, f->cname);
0151                             EXFAIL_OUT(ret);
0152                         }
0153 
0154                     }
0155                 }
0156                 else
0157                 {
0158                     if (BFLD_INT==f->typecode_full)
0159                     {
0160                         int *vi = (int *)fld_offs;
0161                         *vi = (int)l;
0162                     }
0163                     
0164                     *C_count = (*C_count) + 1;
0165                     
0166                     if (BFLD_STRING==f->typecode_full || 
0167                             BFLD_CARRAY==f->typecode_full)
0168                     {
0169                         *L_length = (unsigned short)len;
0170                     }
0171                     else
0172                     {
0173                         /* not used for others.. */
0174                         *L_length = 0;
0175                     }
0176                 }
0177             } /* for occ */
0178         } /* if UBF->C flag */
0179         else
0180         {
0181             UBF_LOG(log_debug, "Defaulting to NULL %s.%s", 
0182                     v->vname, f->cname);
0183             if (EXSUCCEED!=ndrx_Bvselinit_int(v, f, EXFAIL, cstruct))
0184             {
0185                 ndrx_Bset_error_fmt(BBADVIEW, "Failed to set NULL to %s.%s",
0186                         v->vname, f->cname);
0187                 EXFAIL_OUT(ret);
0188             }
0189         }
0190     } /* for fields in v */
0191     
0192 out:
0193     return ret;
0194 }
0195 
0196 /**
0197  * Fill the C struct from UBF
0198  * @param p_ub UBF buffer to fill
0199  * @param cstruct memptr of the struct
0200  * @param view view name
0201  * @return EXSUCCEED/EXFAIL
0202  */
0203 expublic int ndrx_Bvftos(UBFH *p_ub, char *cstruct, char *view)
0204 {
0205     int ret = EXSUCCEED;
0206     ndrx_typedview_t *v = NULL;
0207     /* Resolve view */
0208     
0209     if (NULL==(v = ndrx_view_get_view(view)))
0210     {
0211         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0212         EXFAIL_OUT(ret);
0213     }
0214     
0215     if (EXSUCCEED!=ndrx_Bvftos_int(p_ub, v, cstruct))
0216     {
0217         UBF_LOG(log_error, "ndrx_Bvftos_int failed");
0218         EXFAIL_OUT(ret);
0219     }
0220     
0221 out:
0222     return ret;
0223 }
0224 
0225 /**
0226  * Copy C struct data to UBF buffer
0227  * @param p_ub UBF buffer
0228  * @param v resolved view
0229  * @param cstruct ptr c struct to update
0230  * @param mode BUPDATE, BOJOIN, BJOIN, BCONCAT
0231  * @return EXSUCCEED/EXFAIL
0232  */
0233 expublic int ndrx_Bvstof_int(UBFH *p_ub, ndrx_typedview_t *v, char *cstruct, int mode)
0234 {
0235     int ret=EXSUCCEED;
0236     ndrx_typedview_field_t *f;
0237     UBFH *temp_ub = NULL;
0238     long bsize = v->ssize*3+1024;
0239     short *C_count;
0240     short C_count_stor;
0241     char *fld_offs;
0242     unsigned short *L_length; /* will transfer as long */
0243     unsigned short L_length_stor;
0244     
0245     int dim_size;
0246     
0247     int *int_fix_ptr;
0248     long int_fix_l;
0249     int occ;
0250     BFLDLEN len;
0251     
0252     temp_ub = (UBFH *)NDRX_MALLOC(bsize);
0253 
0254     if (NULL==temp_ub)
0255     {
0256         int err = errno;
0257         UBF_LOG(log_error, "Failed to allocate %ld bytes in temporary UBF buffer: %s", 
0258                 bsize, strerror(errno));
0259         ndrx_Bset_error_fmt(BMALLOC, "Failed to allocate %ld bytes in temporary UBF buffer: %s", 
0260                 bsize, strerror(errno));
0261         EXFAIL_OUT(ret);
0262     }
0263     
0264     if (EXSUCCEED!=Binit(temp_ub, bsize))
0265     {
0266         UBF_LOG(log_error, "Failed to init UBF buffer: %s", Bstrerror(Berror));
0267         EXFAIL_OUT(ret);
0268     }
0269     
0270     /*
0271      * - Build new UBF buffer from v. Loop over the v, add data to FB, realloc if needed.
0272      * - call the BUPDATE, (BOJOIN - RFU), (BJOIN - RFU), BCONCAT
0273      */
0274     DL_FOREACH(v->fields, f)
0275     {
0276         dim_size = f->fldsize/f->count;
0277         
0278         if (f->flags & NDRX_VIEW_FLAG_1WAYMAP_C2UBF_F)
0279         {
0280             UBF_LOG(log_debug, "Processing field: [%s] ubf [%s]", 
0281                     f->cname, f->fbname);
0282 
0283             /* Check do we have length indicator? */
0284             if (f->flags & NDRX_VIEW_FLAG_ELEMCNT_IND_C)
0285             {
0286                 C_count = (short *)(cstruct+f->count_fld_offset);
0287 
0288                 UBF_LOG(log_dump, "%s.C_%s=%hd", 
0289                         v->vname, f->cname, *C_count);
0290             }
0291             else
0292             {
0293                 C_count_stor=f->count; 
0294                 C_count = &C_count_stor;
0295             }
0296 
0297             if (*C_count > f->count)
0298             {
0299                 UBF_LOG(log_error, "Invalid count for field %s.%s in "
0300                         "view %hd, specified: %hd", v->vname, f->cname, 
0301                         f->count, *C_count);
0302                 ndrx_Bset_error_fmt(BEINVAL, "Invalid count for field %s.%s in "
0303                         "view %hd, specified: %hd", v->vname, f->cname, 
0304                         f->count, *C_count);
0305                 EXFAIL_OUT(ret);
0306             }
0307 
0308             for (occ=0; occ<*C_count; occ++)
0309             {
0310              
0311                 fld_offs = cstruct+f->offset+occ*dim_size;
0312                 
0313                 if (f->flags & NDRX_VIEW_FLAG_LEN_INDICATOR_L)
0314                 {
0315                     L_length = (unsigned short *)(cstruct+f->length_fld_offset+
0316                             occ*sizeof(unsigned short));
0317                 }
0318                 else
0319                 {
0320                     L_length_stor = dim_size;
0321                     L_length = &L_length_stor;
0322                 }
0323                 
0324                 if (BFLD_CARRAY==f->typecode_full && *L_length > dim_size)
0325                 {
0326                     UBF_LOG(log_error, "Invalid length for field %s.%s in "
0327                             "view dim size %d, occ %d specified: %hu", v->vname, 
0328                             f->cname,  dim_size, occ, *L_length);
0329                     ndrx_Bset_error_fmt(BEINVAL, "Invalid length for field %s.%s in "
0330                             "view dim size %d, occ %d specified: %hu", v->vname, 
0331                             f->cname, dim_size, occ, *L_length);
0332                     EXFAIL_OUT(ret);
0333                 }
0334                 
0335                 len = *L_length;
0336                 
0337                 /* If field is not NULL 
0338                  * BUPDATE does not make NULL appear in target UBF
0339                  */
0340                 if (BUPDATE != mode || !ndrx_Bvnull_int(v, f, occ, cstruct))
0341                 {
0342                     if (BFLD_INT==f->typecode_full)
0343                     {
0344                         int_fix_ptr = (int *)fld_offs;
0345                         int_fix_l = (long)*int_fix_ptr;
0346     
0347                         if (EXSUCCEED!=CBchg(temp_ub, f->ubfid, occ, 
0348                                 (char *)&int_fix_l, 0L, BFLD_LONG))
0349                         {
0350                             UBF_LOG(log_error, "Failed to add field [%s]/%d as long!", 
0351                                     f->fbname, f->ubfid);
0352                             /* error will be set already */
0353                             EXFAIL_OUT(ret);
0354                         }
0355                     }
0356                     else
0357                     {
0358                         if (EXSUCCEED!=CBchg(temp_ub, f->ubfid, occ, 
0359                                 fld_offs, len, f->typecode_full))
0360                         {
0361                             UBF_LOG(log_error, "Failed to add field [%s]/%d as long!", 
0362                                     f->fbname, f->ubfid);
0363                             
0364                             /* error will be set already */
0365                             EXFAIL_OUT(ret);
0366                         }
0367                         
0368                         if (BFLD_STRING == f->typecode_full)
0369                         {
0370                             /* provide length back, nr transfered +1 for EOS*/
0371                             *L_length = strlen(fld_offs)+1;
0372                         }
0373                     }
0374                 }
0375                 else
0376                 {
0377                     /* Not interested in any more occurrences 
0378                      * cause it will cause NULL occurrances...
0379                      */
0380                     break; 
0381                 }
0382             }
0383         }
0384     }
0385     
0386     /* Temporary buffer built ok... now merge. */
0387     
0388     ndrx_debug_dump_UBF_ubflogger(log_info, "Temporary buffer built", 
0389             temp_ub);
0390     
0391     ndrx_debug_dump_UBF_ubflogger(log_info, "Output buffer before merge",
0392             p_ub);
0393     
0394     switch (mode)
0395     {
0396         case BUPDATE:
0397             UBF_LOG(log_info, "About to run Bupdate");
0398             if (EXSUCCEED!=Bupdate(p_ub, temp_ub))
0399             {
0400                 UBF_LOG(log_error, "Failed to Bupdate(): %s", Bstrerror(Berror));
0401                 EXFAIL_OUT(ret);
0402             }
0403             break;
0404         case BJOIN:
0405             UBF_LOG(log_info, "About to run Bjoin");
0406             if (EXSUCCEED!=Bjoin(p_ub, temp_ub))
0407             {
0408                 UBF_LOG(log_error, "Failed to Bjoin(): %s", Bstrerror(Berror));
0409                 EXFAIL_OUT(ret);
0410             }
0411             break;
0412         case BOJOIN:
0413             UBF_LOG(log_info, "About to run Bojoin");
0414             if (EXSUCCEED!=Bojoin(p_ub, temp_ub))
0415             {
0416                 UBF_LOG(log_error, "Failed to Bojoin(): %s", Bstrerror(Berror));
0417                 EXFAIL_OUT(ret);
0418             }
0419             break;
0420         case BCONCAT:
0421             UBF_LOG(log_info, "About to run Bconcat");
0422             if (EXSUCCEED!=Bconcat(p_ub, temp_ub))
0423             {
0424                 UBF_LOG(log_error, "Failed to Bconcat(): %s", Bstrerror(Berror));
0425                 EXFAIL_OUT(ret);
0426             }
0427             break;
0428         default:
0429             ndrx_Bset_error_fmt(BEINVAL, "Invalid %s option: %d", __func__, mode);
0430             EXFAIL_OUT(ret);
0431             break;
0432     }
0433     
0434     ndrx_debug_dump_UBF_ubflogger(log_info, "Output buffer after merge",
0435             p_ub);
0436     
0437 out:
0438     if (NULL!=temp_ub)
0439     {
0440         NDRX_FREE(temp_ub);
0441     }
0442 
0443     return ret;
0444 }
0445 
0446 /**
0447  * Copy data from C struct to UBF
0448  * @param p_ub ptr to UBF buffer
0449  * @param cstruct ptr to memroy block
0450  * @param mode BUPDATE, BOJOIN, BJOIN, BCONCAT
0451  * @param view view name of th ec struct
0452  * @return EXSUCCEED/EXFAIL
0453  */
0454 expublic int ndrx_Bvstof(UBFH *p_ub, char *cstruct, int mode, char *view)
0455 {
0456     int ret = EXSUCCEED;
0457     ndrx_typedview_t *v = NULL;
0458     
0459     /* Resolve view */
0460     
0461     if (NULL==(v = ndrx_view_get_view(view)))
0462     {
0463         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0464         EXFAIL_OUT(ret);
0465     }
0466     
0467     if (EXSUCCEED!=ndrx_Bvstof_int(p_ub, v, cstruct, mode))
0468     {
0469         UBF_LOG(log_error, "ndrx_Bvstof_int failed");
0470         EXFAIL_OUT(ret);
0471     }
0472     
0473 out:
0474     return ret;
0475 }
0476 
0477 /* vim: set ts=4 sw=4 et smartindent: */