Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Compare view buffer values
0003  *
0004  * @file view_cmp.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 #define NUM_COMP(A, B) \
0054         do \
0055         {\
0056             if ((A) > (B)) \
0057             {\
0058                 ret=1;\
0059                 UBF_LOG(log_debug, "NUM_COMP non eq cname=[%s] occ=%d (A=%ld > B=%ld)", f->cname, occ, (long)(A), (long)(B));\
0060                 goto out;\
0061             }\
0062             else if ((A) < (B)) \
0063             {\
0064                 ret=-1;\
0065                 UBF_LOG(log_debug, "NUM_COMP non eq cname=[%s] occ=%d (A=%ld< B=%ld)", f->cname, occ, (long)(A), (long)(B));\
0066                 goto out;\
0067             }\
0068     } while (0)\
0069 
0070 #define FLOAT_COMP(A, B) \
0071     do \
0072     {\
0073         if (fabs((A)-(B)) > FLOAT_EQUAL)\
0074         {\
0075             if ((A) > (B))\
0076             {\
0077                 ret=1;\
0078                 UBF_LOG(log_debug, "FLOAT_COMP non eq cname=[%s] occ=%d (A=%f > B=%f)", f->cname, occ, (float)(A), (float)(B));\
0079                 goto out;\
0080             }\
0081             else\
0082             {\
0083                 ret=-1;\
0084                 UBF_LOG(log_debug, "FLOAT_COMP non eq cname=[%s] occ=%d (A=%f < B=%f)", f->cname, occ, (float)(A), (float)(B));\
0085                 goto out;\
0086             }\
0087         }\
0088     } while (0)
0089 
0090 #define DOUBLE_COMP(A, B) \
0091     do \
0092     {\
0093         if (fabs((A)-(B)) > DOUBLE_EQUAL) \
0094         {\
0095             if ((A) > (B)) \
0096             {\
0097                 ret=1;\
0098                 UBF_LOG(log_debug, "DOUBLE_COMP non eq cname=[%s] occ=%d (A=%lf > B=%lf)", f->cname, occ, (double)(A), (double)(B));\
0099                 goto out;\
0100             } \
0101             else \
0102             {\
0103                 ret=-1;\
0104                 UBF_LOG(log_debug, "DOUBLE_COMP non eq cname=[%s] occ=%d (A=%lf < B=%lf)", f->cname, occ, (double)(A), (double)(B));\
0105                 goto out;\
0106             }\
0107         }\
0108      } while (0)
0109 /*---------------------------Enums--------------------------------------*/
0110 /*---------------------------Typedefs-----------------------------------*/
0111 /*---------------------------Globals------------------------------------*/
0112 /*---------------------------Statics------------------------------------*/
0113 /*---------------------------Prototypes---------------------------------*/
0114 
0115 /**
0116  * Compare to views
0117  * @param cstruct1 view structure 1 ptr
0118  * @param view1 view name 1
0119  * @param cstruct2 view structure 2 ptr
0120  * @param view2 view name 2
0121  * @return  0 - view name/data are equal
0122  *  -1 - first view field is less than view2/cstruct
0123  *  1 - first view is greater than view2
0124  *  -2 - there is error (view not found)
0125  */
0126 expublic int ndrx_Bvcmp(char *cstruct1, char *view1, char *cstruct2, char *view2)
0127 {
0128     int ret = 0;
0129     ndrx_typedview_t *v = NULL;
0130     ndrx_typedview_field_t *f;
0131     short *C_count1, *C_count2;
0132     short C_count_stor1, C_count_stor2;
0133     unsigned short *L_length1, *L_length2;
0134     BFLDOCC occ;
0135     short *sv1, *sv2;
0136     int *iv1, *iv2;
0137     long *lv1, *lv2;
0138     float *fv1, *fv2;
0139     double *dv1, *dv2;
0140     int len_cmp;
0141     
0142     UBF_LOG(log_debug, "Compare views by data %p [%s] %p [%s]", 
0143             cstruct1, view1, cstruct2, view2);
0144 
0145     if (EXEOS==view1[0] && EXEOS==view2[0])
0146     {
0147         UBF_LOG(log_debug, "Both empty views - assume equals");
0148         goto out;
0149     }
0150     
0151     if (0!=(ret=strcmp(view1, view2)))
0152     {
0153         UBF_LOG(log_debug, "Name differs [%s] vs [%s]", view1, view2);
0154         
0155         /* normalize values */
0156         if (ret<-1)
0157         {
0158             ret=-1;
0159         }
0160         else if (ret>1)
0161         {
0162             ret=1;
0163         }
0164         
0165         goto out;
0166     }
0167     
0168     /* find the descriptor, only one needed, as matches*/
0169     if (NULL==(v = ndrx_view_get_view(view1)))
0170     {
0171         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view1);
0172         ret=-2;
0173         goto out;
0174     }
0175     
0176     DL_FOREACH(v->fields, f)
0177     {        
0178         UBF_LOG(log_dump, "Processing field: [%s]", f->cname);
0179         /* Check do we have length indicator? */
0180         if (f->flags & NDRX_VIEW_FLAG_ELEMCNT_IND_C)
0181         {
0182             C_count1 = (short *)(cstruct1+f->count_fld_offset);
0183             C_count2 = (short *)(cstruct2+f->count_fld_offset);
0184         }
0185         else
0186         {
0187             C_count_stor1=f->count; 
0188             C_count1 = &C_count_stor1;
0189             
0190             C_count_stor2=f->count; 
0191             C_count2 = &C_count_stor2;
0192         }
0193         
0194         NUM_COMP(*C_count1, *C_count2);
0195         
0196         /* well we must support arrays too...! of any types
0197          * Arrays we will load into occurrences of the same buffer
0198          */
0199         /* loop over the occurrences 
0200          * we might want to send less count then max struct size..*/
0201         for (occ=0; occ<*C_count1; occ++)
0202         {
0203             int dim_size = f->fldsize/f->count;
0204             /* OK we need to understand following:
0205              * size (data len) of each of the array elements..
0206              * the header plotter needs to support occurrences of the
0207              * length elements for the arrays...
0208              * 
0209              * For outgoing if there is only one occurrence for field
0210              * then we can can detect the field to be NULL,
0211              * if NULL, then we do not send empty fields over..
0212             */ 
0213             char *fld_offs1 = cstruct1+f->offset+occ*dim_size;
0214             char *fld_offs2 = cstruct2+f->offset+occ*dim_size;
0215             
0216             
0217             /* check if both are NULL, then structures matches... and
0218              * we do not continue. This might apply to un-init strings
0219              * and carrays.
0220              */
0221             if (ndrx_Bvnull_int(v, f, occ, cstruct1) &&
0222                     ndrx_Bvnull_int(v, f, occ, cstruct2))
0223             {
0224                 continue;
0225             }
0226             
0227             switch(f->typecode_full)
0228             {
0229                 case BFLD_SHORT:
0230                     sv1 = (short *)fld_offs1;
0231                     sv2 = (short *)fld_offs2;
0232 
0233                     NUM_COMP(*sv1, *sv2);
0234                     
0235                     break;
0236                 case BFLD_INT:
0237                     iv1 = (int *)fld_offs1;
0238                     iv2 = (int *)fld_offs2;
0239 
0240                     NUM_COMP(*iv1, *iv2);
0241                     
0242                     break;
0243                 case BFLD_LONG:
0244                     lv1 = (long *)fld_offs1;
0245                     lv2 = (long *)fld_offs2;
0246 
0247                     NUM_COMP(*lv1, *lv2);
0248                     
0249                     break;
0250                 case BFLD_CHAR:
0251                     
0252                     NUM_COMP(*fld_offs1, *fld_offs2);
0253 
0254                     break;
0255                 case BFLD_FLOAT:
0256                     fv1 = (float *)fld_offs1;
0257                     fv2 = (float *)fld_offs2;
0258                     FLOAT_COMP(*fv1, *fv2);
0259                     break;
0260                 case BFLD_DOUBLE:
0261                     dv1 = (double *)fld_offs1;
0262                     dv2 = (double *)fld_offs2;
0263 
0264                     DOUBLE_COMP(*dv1, *dv2);
0265                     break;
0266                 case BFLD_STRING:
0267 
0268                     if (0!=(ret=strcmp(fld_offs1, fld_offs2)))
0269                     {
0270                         UBF_LOG(log_debug, "STRING COMP cname=[%s] occ=%d (A=[%s] <> B=[%s])", 
0271                             f->cname, occ, fld_offs1, fld_offs2);
0272                         if (ret<-1)
0273                         {
0274                             ret=-1;
0275                         }
0276                         else if (ret>1)
0277                         {
0278                             ret=1;
0279                         }
0280 
0281                         goto out;
0282                     }
0283                     
0284                     break;
0285                 case BFLD_CARRAY:
0286 
0287                     if (f->flags & NDRX_VIEW_FLAG_LEN_INDICATOR_L)
0288                     {
0289 
0290                         L_length1 = (unsigned short *)(cstruct1+f->length_fld_offset+
0291                                 occ*sizeof(unsigned short));
0292                         
0293                         L_length2 = (unsigned short *)(cstruct2+f->length_fld_offset+
0294                                 occ*sizeof(unsigned short));
0295                         
0296                         NUM_COMP(*L_length1, *L_length2);
0297                         
0298                         len_cmp = *L_length1;
0299                     }
0300                     else
0301                     {
0302                         len_cmp = dim_size;
0303                     }
0304                     
0305                     if (0!=(ret=memcmp(fld_offs1, fld_offs2, len_cmp)))
0306                     {
0307 
0308                         UBF_LOG(log_debug, "CARRAY COMP cname=[%s] occ=%d (A <> B)", 
0309                             f->cname, occ);
0310 
0311                         if (ret<-1)
0312                         {
0313                             ret=-1;
0314                         }
0315                         else if (ret>1)
0316                         {
0317                             ret=1;
0318                         }
0319                         goto out;
0320                     }
0321                     
0322                     break;
0323             }
0324         } /* for occ */
0325     }
0326     
0327 out:
0328     
0329     UBF_LOG(log_debug, "Result %d", ret);
0330     return ret;
0331 
0332 }
0333 
0334 /* vim: set ts=4 sw=4 et smartindent: */