Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief BFLD_VIEW type support
0003  *
0004  * @file fld_view.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 <regex.h>
0041 #include <ubf.h>
0042 #include <ubf_int.h>
0043 #include <ndebug.h>
0044 #include <ferror.h>
0045 #include <errno.h>
0046 #include <ubf_tls.h>
0047 #include <ubfutil.h>
0048 
0049 #include "ubfview.h"
0050 /*---------------------------Externs------------------------------------*/
0051 /*---------------------------Macros-------------------------------------*/
0052 #define VIEW_SIZE_OVERHEAD   (sizeof(BFLDLEN)+NDRX_VIEW_NAME_LEN+1)
0053 /*---------------------------Enums--------------------------------------*/
0054 /*---------------------------Typedefs-----------------------------------*/
0055 /*---------------------------Globals------------------------------------*/
0056 /*---------------------------Statics------------------------------------*/
0057 /*---------------------------Prototypes---------------------------------*/
0058 
0059 /**
0060  * Get total size of the view
0061  * @param t type descriptor
0062  * @param fb data in fb
0063  * @param payload_size return view size
0064  * @return total size in bytes, aligned
0065  */
0066 expublic int ndrx_get_fb_view_size(dtype_str_t *t, char *fb, int *payload_size)
0067 {
0068     UBF_view_t *view = (UBF_view_t *)fb;
0069     
0070     if (NULL!=payload_size)
0071     {
0072         /* what size? */
0073         *payload_size = view->dlen;
0074     }
0075     
0076     return ALIGNED_SIZE_T(UBF_view_t, view->dlen);
0077 }
0078 
0079 /**
0080  * Put the buffer data.
0081  * If we cannot extract the data length from the view, we shall generate
0082  * error: BBADVIEW
0083  * @param t type descriptor
0084  * @param fb UBF buffer position for field
0085  * @param bfldid field id
0086  * @param data must be UBF type buffer
0087  * @param len not used, we take datak
0088  * @return status (BBADVIEW if view not found...)
0089  */
0090 expublic int ndrx_put_data_view(dtype_str_t *t, char *fb, BFLDID bfldid, 
0091         char *data, int len)
0092 {
0093     int ret = EXSUCCEED;
0094     UBF_view_t *viewfb = (UBF_view_t *)fb;
0095     BVIEWFLD *vdata = (BVIEWFLD *)data;
0096     ndrx_typedview_t * vdef;
0097     long vsize;
0098     VIEW_ENTRY;
0099     
0100     /* find the view */
0101     
0102     if (EXEOS!=vdata->vname[0])
0103     {
0104         vdef = ndrx_view_get_view(vdata->vname);
0105 
0106         if (NULL==vdef)
0107         {
0108             ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not loaded, check VIEWFILES env");
0109             EXFAIL_OUT(ret);
0110         }
0111         
0112         vsize=vdef->ssize;
0113     }
0114     else
0115     {
0116         /* for empty fields */
0117         vsize=0;
0118     }
0119     
0120     /* int align; */
0121     viewfb->bfldid = bfldid;
0122     viewfb->vflags = vdata->vflags;
0123     viewfb->dlen=vsize;
0124     
0125     NDRX_STRCPY_SAFE(viewfb->vname, vdata->vname);
0126     
0127     if (vsize>0)
0128     {
0129         memcpy(viewfb->data, vdata->data, vsize);
0130     }
0131     
0132 out:
0133     return ret;
0134 }
0135 
0136 /**
0137  * Return estimated required data size
0138  * This size is used for calculation of data adding, not for retrieval
0139  * the real data used by view.
0140  * @param t type descr
0141  * @param data data
0142  * @param len passed len, not used
0143  * @return bytes needed. 
0144  */
0145 expublic int ndrx_get_d_size_view (struct dtype_str *t, char *data, 
0146         int len, int *payload_size)
0147 {
0148     int ret;
0149     BVIEWFLD *vdata = (BVIEWFLD *)data;
0150     ndrx_typedview_t * vdef;
0151     long vsize;
0152     VIEW_ENTRY;
0153     
0154     /* find the view */
0155     
0156     if (EXEOS!=vdata->vname[0])
0157     {
0158         vdef = ndrx_view_get_view(vdata->vname);
0159 
0160         if (NULL==vdef)
0161         {
0162             ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not loaded, check VIEWFILES env", 
0163                     vdata->vname);
0164             EXFAIL_OUT(ret);
0165         }
0166         vsize=vdef->ssize;
0167     }
0168     else
0169     {
0170         vsize=0;
0171     }
0172     
0173     if (NULL!=payload_size)
0174         *payload_size=vsize;
0175 
0176     ret=ALIGNED_SIZE_T(UBF_view_t, vsize);
0177     
0178 out:
0179     return ret;
0180 }
0181 
0182 /**
0183  * Get data, data is unloaded to BVIEWFLD. It is expected that BVIEWFLD.data
0184  * has enough space to hold the buffer.
0185  * @param t data type descr
0186  * @param fb field position in UBF buffer
0187  * @param buf output buffer
0188  * @param len output buffer len. 
0189  * @return EXSUCCEED/EXFAIL
0190  */
0191 expublic int ndrx_get_data_view (struct dtype_str *t, char *fb, char *buf, int *len)
0192 {
0193     int ret=EXSUCCEED;
0194     UBF_view_t *viewfb = (UBF_view_t *)fb;
0195     BVIEWFLD *vdata = (BVIEWFLD *)buf;
0196 
0197     UBF_LOG(log_debug, "viewfb->dlen=%d len=%p (%d)",
0198             viewfb->dlen, len, len?*len:0);
0199     
0200     if (NULL!=len && *len>0 && *len < viewfb->dlen)
0201     {
0202         /* Set error, that string buffer too short */
0203         ndrx_Bset_error_fmt(BNOSPACE, "output buffer too short. Data len %d in buf, "
0204                                 "output: %d", viewfb->dlen, *len);
0205         EXFAIL_OUT(ret);
0206     }
0207     
0208     /* copy the data */
0209     NDRX_STRCPY_SAFE(vdata->vname, viewfb->vname);
0210     vdata->vflags = (unsigned int )viewfb->vflags;
0211     memcpy(vdata->data, viewfb->data, viewfb->dlen);
0212 
0213     if (NULL!=len)
0214     {
0215         *len=viewfb->dlen;
0216     }
0217 
0218 out:
0219     return ret;
0220 }
0221 
0222 /**
0223  * Return aligned empty view size
0224  * @param t data type
0225  * @return 
0226  */
0227 expublic int ndrx_g_view_empty(struct dtype_ext1* t)
0228 {
0229     return ALIGNED_SIZE_T(UBF_view_t, 0);
0230 }
0231 
0232 /**
0233  * Put empty UBF buffer in UBF buffer
0234  * @param t type descr
0235  * @param fb UBF buffer where to install the data
0236  * @param bfldid field id to set
0237  * @return EXSUCCEED/EXFAIL
0238  */
0239 expublic int ndrx_put_empty_view(struct dtype_ext1* t, char *fb, BFLDID bfldid)
0240 {
0241     int ret=EXSUCCEED;
0242     UBF_view_t *viewfb = (UBF_view_t *)fb;
0243     
0244     memset(viewfb, 0, sizeof(UBF_view_t));    
0245     viewfb->bfldid = bfldid;
0246 
0247     return ret;
0248 }
0249 
0250 /**
0251  * Print the buffer to log
0252  * Field must match the buffer format of UBF_view_t
0253  * @param t type descr
0254  * @param text extra debug msg
0255  * @param data ptr to UBF_view_t
0256  * @param len not used..
0257  */
0258 expublic void ndrx_dump_view(struct dtype_ext1 *t, char *text, char *data, int *len)
0259 {
0260     UBF_view_t *viewfb = (UBF_view_t *)data;
0261     
0262     if (NULL!=data)
0263     {
0264         UBF_LOG(log_debug, "%s: View [%s] vflags [%ld]", text, 
0265                 viewfb->vname, viewfb->vflags);
0266         ndrx_debug_dump_VIEW_ubflogger(log_debug, text, viewfb->data, viewfb->vname);
0267     }
0268     else
0269     {
0270         UBF_LOG(log_debug, "%s:\n[null data]", text);
0271     }
0272 }
0273 
0274 /**
0275  * Compare two views
0276  * This shall point to BVIEWFLD. So that later any finds and next ops
0277  * would return the same BVIEWFLD and could be used in existing places where
0278  * data is compared by value, and not by headers.
0279  * @param t data type
0280  * @param val1 ptr in buffer
0281  * @param len1 not used
0282  * @param val2 ptr in buffer
0283  * @param len2 not used
0284  * @param mode UBF_CMP_MODE_STD? 
0285  * @return EXTRUE/EXFALSE, or -1,0,1,-2 on error
0286  */
0287 expublic int ndrx_cmp_view (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0288         char *val2, BFLDLEN len2, long mode)
0289 {
0290     int ret = 0;
0291     
0292     BVIEWFLD *vdata1 = (BVIEWFLD *)val1;
0293     BVIEWFLD *vdata2 = (BVIEWFLD *)val2;
0294     
0295     if (mode & UBF_CMP_MODE_STD)
0296     {
0297         ret = Bvcmp(vdata1->data, vdata1->vname, 
0298                 vdata2->data, vdata2->vname);
0299         goto out;
0300     }
0301     else
0302     {
0303         ret = Bvcmp(vdata1->data, vdata1->vname, 
0304                 vdata2->data, vdata2->vname);
0305         
0306         if (-2==ret)
0307         {
0308             goto out;
0309         }
0310         
0311         if (0==ret)
0312         {
0313             ret=EXTRUE;
0314         }
0315         else
0316         {
0317             ret=EXFALSE;
0318         }
0319     }
0320     
0321 out:
0322     return ret;
0323 }
0324 
0325 /**
0326  * Allocate buffer for view (in case of Bgetalloc()).
0327  * Also prepare internal structures -> calculate data pointer.
0328  * We return real size + extra if requested.
0329  * @param t
0330  * @param len - buffer length to allocate.
0331  * @return NULL/ptr to allocated mem
0332  */
0333 expublic char *ndrx_talloc_view (struct dtype_ext1 *t, int *len)
0334 {
0335     char *ret=NULL;
0336     int alloc_size = *len;
0337     BVIEWFLD *ptr;
0338     
0339     ret= NDRX_MALLOC(sizeof(BVIEWFLD) + alloc_size);
0340     
0341     ptr = (BVIEWFLD *)ret;
0342     
0343     if (NULL==ret)
0344     {
0345         ndrx_Bset_error_fmt(BMALLOC, "Failed to allocate %d bytes (with hdr) for user", 
0346                 sizeof(BVIEWFLD) + alloc_size);
0347     }
0348     else
0349     {
0350         *len = alloc_size;
0351         /* this is the trick, we alloc one block with data to self offset */
0352         ptr->data = ret + sizeof(BVIEWFLD);
0353     }
0354 
0355     return ret;
0356 }
0357 
0358 /**
0359  * Prepare view data for presenting to user.
0360  * This will setup BVIEWFLD and return the pointer to it
0361  * @param t type descriptor
0362  * @param storage where to store the returned data ptr
0363  * @param data start in UBF buffer
0364  * @return ptr to data block of BVIEWFLD
0365  */
0366 expublic char* ndrx_prep_viewp (struct dtype_ext1 *t, 
0367         ndrx_ubf_tls_bufval_t *storage, char *data)
0368 {
0369     UBF_view_t *viewfb = (UBF_view_t *)data;
0370 
0371     NDRX_STRCPY_SAFE(storage->vdata.vname, viewfb->vname);
0372     storage->vdata.vflags = (unsigned int)viewfb->vflags;
0373     storage->vdata.data=viewfb->data;
0374 
0375     UBF_LOG(log_debug, "Into ndrx_prep_viewp - preparing view BVIEWFLD");
0376     
0377     return (char *)&storage->vdata;
0378 }
0379 
0380 /* vim: set ts=4 sw=4 et smartindent: */