Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief NULL Value handling in views
0003  *
0004  * @file view_null.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 <math.h>
0041 #include <ndrstandard.h>
0042 #include <typed_buf.h>
0043 #include <ndebug.h>
0044 
0045 #include <userlog.h>
0046 #include <typed_view.h>
0047 #include <view_cmn.h>
0048 #include <atmi_tls.h>
0049 
0050 #include "Exfields.h"
0051 /*---------------------------Externs------------------------------------*/
0052 /*---------------------------Macros-------------------------------------*/
0053 /*---------------------------Enums--------------------------------------*/
0054 /*---------------------------Typedefs-----------------------------------*/
0055 /*---------------------------Globals------------------------------------*/
0056 /*---------------------------Statics------------------------------------*/
0057 /*---------------------------Prototypes---------------------------------*/
0058 
0059 /**
0060  * Test is given field empty in "memory"
0061  * @param v resolved view object
0062  * @param f resolved view field object
0063  * @param occ occurrence of the field
0064  * @param view user data memory block to analyze
0065  * @return EXFALSE/EXTRUE/EXFAIL
0066  */
0067 expublic int ndrx_Bvnull_int(ndrx_typedview_t *v, ndrx_typedview_field_t *f, 
0068         BFLDOCC occ, char *cstruct)
0069 {
0070     int ret = EXFALSE;
0071     int dim_size = f->fldsize/f->count;
0072     char *fld_offs = cstruct+f->offset+occ*dim_size;
0073     short *sv;
0074     int *iv;
0075     long *lv;
0076     float *fv;
0077     double *dv;
0078     int i, j;
0079     int len;
0080     short *C_count;
0081 
0082     
0083     if (f->nullval_none)
0084     {
0085         UBF_LOG(log_debug, "field set to NONE, no NULL value...");
0086         ret=EXFALSE;
0087         goto out;
0088     }
0089     
0090     /* if counter is available and occ is > than counter, then field is NULL */
0091     if (f->flags & NDRX_VIEW_FLAG_ELEMCNT_IND_C)
0092     {
0093         C_count = (short *)(cstruct+f->count_fld_offset);
0094 
0095         if (occ >= *C_count)
0096         {
0097             UBF_LOG(log_debug, "test occ=%d max count=%hd - false",
0098                 occ, *C_count);
0099             ret=EXTRUE;
0100             goto out;
0101         }
0102     }
0103 
0104     switch(f->typecode_full)
0105     {
0106         case BFLD_SHORT:
0107             sv = (short *)fld_offs;
0108             
0109             if (*sv==f->nullval_short)
0110             {
0111                 ret=EXTRUE;
0112                 goto out;
0113             }
0114             break;
0115         case BFLD_INT:
0116             iv = (int *)fld_offs;
0117             
0118             if (*iv==f->nullval_int)
0119             {
0120                 ret=EXTRUE;
0121                 goto out;
0122             }
0123             break;
0124         case BFLD_LONG:
0125             lv = (long *)fld_offs;
0126             
0127             if (*lv==f->nullval_long)
0128             {
0129                 ret=EXTRUE;
0130                 goto out;
0131             }
0132             break;
0133         case BFLD_CHAR:
0134             if (*fld_offs == f->nullval_bin[0])
0135             {
0136                 ret=EXTRUE;
0137                 goto out;
0138             }
0139             
0140             break;
0141         case BFLD_FLOAT:
0142             fv = (float *)fld_offs;
0143             
0144             if (fabs( *fv - f->nullval_float)<FLOAT_EQUAL)
0145             {
0146                 ret=EXTRUE;
0147                 goto out;
0148             }
0149             break;
0150         case BFLD_DOUBLE:
0151             dv = (double *)fld_offs;
0152             
0153             if (fabs( *dv - f->nullval_double)<DOUBLE_EQUAL)
0154             {
0155                 ret=EXTRUE;
0156                 goto out;
0157             }
0158             break;
0159         case BFLD_STRING:
0160             
0161             /* nullval_bin EOS is set by CALLOC at the parser.. */
0162             len = dim_size-1; /* EOS do not count in */
0163             
0164             /*
0165              * Well we somehow need to check the length 
0166              * of the default and the data.
0167              * For filler the first part must match (length at-least)
0168              * For non-filler it must be full match
0169              */
0170             if (f->flags & NDRX_VIEW_FLAG_NULLFILLER_P)
0171             {
0172                 /* test the filler */
0173                 ret=EXTRUE;
0174                 
0175                 if (len < f->nullval_bin_len)
0176                 {
0177                     /* No match , it is shorter.. */
0178                     ret=EXFALSE;
0179                     goto out;
0180                 }
0181                 
0182                 for (i=0; i<f->nullval_bin_len; i++)
0183                 {
0184                     if (i>=len)
0185                     {
0186                         ret=EXFALSE;
0187                         goto out;
0188                     }
0189                     else if (i==f->nullval_bin_len-1)
0190                     {
0191                         /* compare last bits... */
0192                         for (j=i; j<len; j++)
0193                         {
0194                             if (fld_offs[j]!=f->nullval_bin[i])
0195                             {
0196                                 ret=EXFALSE;
0197                                 goto out;
0198                             }
0199                         }
0200                     }
0201                     else if (fld_offs[i]!=f->nullval_bin[i])
0202                     {
0203                         ret=EXFALSE;
0204                         goto out;
0205                     }
0206                     
0207                 }
0208             }
0209             else
0210             {
0211                 /* EOS will be set there by calloc... */
0212                 UBF_LOG(log_dump, "STR_CMP: data: [%s] vs obj: [%s]",
0213                         fld_offs, f->nullval_bin);
0214                 if (0==strcmp(fld_offs, f->nullval_bin))
0215                 {
0216                     ret=EXTRUE;
0217                     goto out;
0218                 }
0219             }
0220             
0221             break;
0222         case BFLD_CARRAY:
0223             
0224             len = dim_size;
0225             
0226             if (!(f->flags & NDRX_VIEW_FLAG_NULLFILLER_P))
0227             {
0228                 if (len < f->nullval_bin_len)
0229                 {
0230                     ret=EXFALSE;
0231                     goto out;
0232                 }
0233             }
0234             
0235             /* test the filler */
0236             ret=EXTRUE;
0237             
0238             for (i=0; i<f->nullval_bin_len; i++)
0239             {
0240                 if (i>=len)
0241                 {
0242                     ret=EXFALSE;
0243                     goto out;
0244                 }
0245                 else if (f->flags & NDRX_VIEW_FLAG_NULLFILLER_P && 
0246                         i==f->nullval_bin_len-1)
0247                 {
0248                     /* compare last bits... */
0249                     for (j=i; j<len; j++)
0250                     {
0251                         if (fld_offs[j]!=f->nullval_bin[i])
0252                         {
0253                             ret=EXFALSE;
0254                             goto out;
0255                         }
0256                     }
0257                 }
0258                 else if (fld_offs[i]!=f->nullval_bin[i])
0259                 {
0260                     ret=EXFALSE;
0261                     goto out;
0262                 }
0263                 
0264             }
0265             
0266             break;
0267     }
0268     
0269 out:
0270     UBF_LOG(log_debug, "%s: %s.%s presence %d", __func__, v->vname, f->cname, ret);
0271     return ret;
0272        
0273 }
0274 
0275 /**
0276  * Test is field null or not 
0277  * @param cstruct
0278  * @param cname
0279  * @param occ
0280  * @param view
0281  * @return EXFAIL(-1)/EXFALSE(0)/EXTRUE(1)
0282  */
0283 expublic int ndrx_Bvnull(char *cstruct, char *cname, BFLDOCC occ, char *view)
0284 {
0285     int ret = EXFALSE;
0286     ndrx_typedview_t *v = NULL;
0287     ndrx_typedview_field_t *f = NULL;
0288     
0289     /* resolve view & field, call ndrx_Bvnull_int */
0290     
0291     if (NULL==(v = ndrx_view_get_view(view)))
0292     {
0293         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0294         EXFAIL_OUT(ret);
0295     }
0296     
0297     if (NULL==(f = ndrx_view_get_field(v, cname)))
0298     {
0299         ndrx_Bset_error_fmt(BNOCNAME, "Field [%s] of view [%s] not found!", 
0300                 cname, v->vname);
0301         EXFAIL_OUT(ret);
0302     }
0303     
0304     if (occ > f->count-1 || occ<0)
0305     {
0306         ndrx_Bset_error_fmt(BEINVAL, "Invalid occurrence requested for field "
0307                 "%s.%s, count=%d occ=%d (zero base)",
0308                 v->vname, f->cname, f->count, occ);
0309         EXFAIL_OUT(ret);
0310     }
0311     
0312     if (EXFAIL==(ret=ndrx_Bvnull_int(v, f, occ, cstruct)))
0313     {
0314         /* should not get here.. */
0315         ndrx_Bset_error_fmt(BBADVIEW, "System error occurred.");
0316         goto out;
0317     }
0318     
0319 out:
0320     return ret;
0321 }
0322 
0323 /**
0324  * Initialize single structure element to NULL
0325  * @param v view object
0326  * @param f field object
0327  * @param cstruct c structure
0328  * @return 
0329  */
0330 expublic int ndrx_Bvselinit_int(ndrx_typedview_t *v, ndrx_typedview_field_t *f,  
0331         BFLDLEN single_occ, char *cstruct)
0332 {
0333     int ret = EXSUCCEED;
0334     int dim_size;
0335     char *fld_offs;
0336     short *sv;
0337     int *iv;
0338     long *lv;
0339     float *fv;
0340     double *dv;
0341     int i, j;
0342     int len;
0343     int occ;
0344     short *C_count;
0345     unsigned short *L_length;
0346     int start_occ;
0347     int stop_occ;
0348     
0349     if (f->nullval_none)
0350     {
0351         UBF_LOG(log_debug, "field set to NONE, no NULL value...");
0352         goto out;
0353     } 
0354     
0355     if (EXFAIL!=single_occ)
0356     {
0357         start_occ = single_occ;
0358         stop_occ = single_occ+1;
0359     }
0360     else
0361     {
0362         start_occ = 0;
0363         stop_occ = f->count;
0364     }
0365     
0366     for (occ=start_occ; occ<stop_occ; occ++)
0367     {   
0368      
0369         if (f->flags & NDRX_VIEW_FLAG_ELEMCNT_IND_C)
0370         {
0371             C_count = (short *)(cstruct+f->count_fld_offset);
0372             
0373             /* Reset only if full NULLing */
0374             if (EXFAIL==single_occ)
0375             {
0376                 *C_count = 0;
0377             }
0378         }
0379         
0380         dim_size = f->fldsize/f->count;
0381         fld_offs = cstruct+f->offset+occ*dim_size;   
0382         
0383         switch(f->typecode_full)
0384         {
0385             case BFLD_SHORT:
0386                 sv = (short *)fld_offs;
0387                 *sv=f->nullval_short;
0388                 
0389                 break;
0390             case BFLD_INT:
0391                 iv = (int *)fld_offs;
0392                 *iv=f->nullval_int;
0393                 break;
0394             case BFLD_LONG:
0395                 lv = (long *)fld_offs;
0396                 *lv=f->nullval_long;
0397                 break;
0398             case BFLD_CHAR:
0399                 *fld_offs = f->nullval_bin[0];
0400                 break;
0401             case BFLD_FLOAT:
0402                 fv = (float *)fld_offs;
0403                 *fv = f->nullval_float;
0404                 break;
0405             case BFLD_DOUBLE:
0406                 dv = (double *)fld_offs;
0407                 *dv = f->nullval_double;
0408                 break;
0409             case BFLD_STRING:
0410                 
0411                 /* nullval_bin EOS is set by CALLOC at the parser.. */
0412                 if (f->flags & NDRX_VIEW_FLAG_LEN_INDICATOR_L)
0413                 {
0414                     
0415                     L_length = (unsigned short *)(cstruct+f->length_fld_offset+
0416                                 occ*sizeof(unsigned short));
0417                     *L_length = 0;
0418                 }
0419                 
0420                 if (f->flags & NDRX_VIEW_FLAG_NULLFILLER_P)
0421                 {
0422                     for (i=0; i<f->nullval_bin_len; i++)
0423                     {
0424                         if (i>=dim_size-1)
0425                         {
0426                             /* Put EOS */
0427                             fld_offs[i] = EXEOS;
0428                             break;
0429                         } /* if we are at the end... */
0430                         else if (i==f->nullval_bin_len-1)
0431                         {
0432                             /* Transfer last char as multiple copies.. */
0433                             for (j=i; j<dim_size-1; j++)
0434                             {
0435                                 fld_offs[j]=f->nullval_bin[i];
0436                             }
0437                             
0438                             fld_offs[dim_size-1] = EXEOS;
0439                             break;
0440                         }
0441                         else
0442                         {
0443                             /* transfer the value.. */
0444                             fld_offs[i]=f->nullval_bin[i];
0445                         }
0446                     }
0447                 }
0448                 else
0449                 {   
0450                     len = f->nullval_bin_len;
0451                     
0452                     if (len>dim_size)
0453                     {
0454                         len = dim_size-1; /* Place for eos */
0455                     }
0456                     
0457                     NDRX_STRNCPY(fld_offs, f->nullval_bin, len);
0458                     
0459                     fld_offs[len] = EXEOS;                    
0460                 }
0461                 
0462                 break;
0463             case BFLD_CARRAY:
0464 
0465                 /* nullval_bin EOS is set by CALLOC at the parser.. */
0466                 if (f->flags & NDRX_VIEW_FLAG_LEN_INDICATOR_L)
0467                 {
0468                      L_length = (unsigned short *)(cstruct+f->length_fld_offset+
0469                                 occ*sizeof(unsigned short));
0470                     *L_length = 0;
0471                 }
0472                 
0473                 len = dim_size;
0474 
0475                 /* test the filler */
0476                 for (i=0; i<f->nullval_bin_len; i++)
0477                 {
0478                     if (i>=len)
0479                     {
0480                         break;
0481                     }
0482                     else if (f->flags & NDRX_VIEW_FLAG_NULLFILLER_P && 
0483                             i==f->nullval_bin_len-1 && i<len)
0484                     {
0485                         /* compare last bits... */
0486                         for (j=i; j<len; j++)
0487                         {
0488                             fld_offs[j]=f->nullval_bin[i];
0489                         }
0490                     }
0491                     else
0492                     {
0493                         fld_offs[i]=f->nullval_bin[i];
0494                     }
0495                 }
0496                 break;
0497         } /* switch typecode */
0498     } /* for occ */
0499     
0500 out:
0501     
0502     return ret;
0503        
0504 }
0505 
0506 /**
0507  * Init VIEW element to zero
0508  * @param cstruct c struct
0509  * @param cname field name
0510  * @param view view name
0511  * @return  EXSUCCEED/EXFAIL
0512  */
0513 expublic int ndrx_Bvselinit(char *cstruct, char *cname, char *view) 
0514 {
0515     int ret = EXSUCCEED;
0516     ndrx_typedview_t *v = NULL;
0517     ndrx_typedview_field_t *f = NULL;
0518     
0519     if (NULL==(v = ndrx_view_get_view(view)))
0520     {
0521         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0522         EXFAIL_OUT(ret);
0523     }
0524     
0525     if (NULL==(f = ndrx_view_get_field(v, cname)))
0526     {
0527         ndrx_Bset_error_fmt(BNOCNAME, "Field [%s] of view [%s] not found!", 
0528                 cname, v->vname);
0529         EXFAIL_OUT(ret);
0530     }
0531         
0532     if (EXFAIL==ndrx_Bvselinit_int(v, f, EXFAIL, cstruct))
0533     {
0534         /* should not get here.. */
0535         ndrx_Bset_error_fmt(BBADVIEW, "System error occurred.");
0536         EXFAIL_OUT(ret);
0537     }
0538     
0539 out:
0540     return ret;
0541 }
0542 
0543 /* Next todo: Fvsinit */
0544 
0545 /**
0546  * Initialize view to default values.
0547  * @param v resolved view object
0548  * @param cstruct memory bloc to initialize
0549  * @return EXSUCCEED/EXFAIL
0550  */
0551 expublic int ndrx_Bvsinit_int(ndrx_typedview_t *v, char *cstruct)
0552 {
0553     int ret =EXSUCCEED;
0554     ndrx_typedview_field_t *f;
0555     
0556     /* Go over the c struct  */
0557     DL_FOREACH(v->fields, f)
0558     {
0559         if (EXSUCCEED!=ndrx_Bvselinit_int(v, f, EXFAIL, cstruct))
0560         {
0561             ndrx_Bset_error_fmt(BBADVIEW, "System error occurred.");
0562             goto out;
0563         }
0564     }
0565     
0566 out:
0567     return ret;
0568 }
0569 
0570 /**
0571  * Initialize full structure by given view
0572  * @param cstruct memory addr
0573  * @param view view name
0574  * @return  EXSUCCEED/EXFAIL
0575  */
0576 expublic int ndrx_Bvsinit(char *cstruct, char *view)
0577 {
0578     int ret = EXSUCCEED;
0579     ndrx_typedview_t *v = NULL;
0580     
0581     if (NULL==(v = ndrx_view_get_view(view)))
0582     {
0583         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0584         EXFAIL_OUT(ret);
0585     }
0586     
0587     if (EXSUCCEED!=ndrx_Bvsinit_int(v, cstruct))
0588     {
0589         UBF_LOG(log_error, "ndrx_Bvsinit_int failed!");
0590         EXFAIL_OUT(ret);
0591     }
0592     
0593 out:
0594                 
0595     return ret;
0596 }
0597 
0598 
0599 /* vim: set ts=4 sw=4 et smartindent: */