Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief UBF library
0003  *   Date type functions. Sizes, put/read data
0004  *   Enduro Execution Library
0005  *
0006  * @file fdatatype.c
0007  */
0008 /* -----------------------------------------------------------------------------
0009  * Enduro/X Middleware Platform for Distributed Transaction Processing
0010  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0011  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0012  * This software is released under one of the following licenses:
0013  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0014  * See LICENSE file for full text.
0015  * -----------------------------------------------------------------------------
0016  * AGPL license:
0017  *
0018  * This program is free software; you can redistribute it and/or modify it under
0019  * the terms of the GNU Affero General Public License, version 3 as published
0020  * by the Free Software Foundation;
0021  *
0022  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0023  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0024  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0025  * for more details.
0026  *
0027  * You should have received a copy of the GNU Affero General Public License along 
0028  * with this program; if not, write to the Free Software Foundation, Inc.,
0029  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0030  *
0031  * -----------------------------------------------------------------------------
0032  * A commercial use license is available from Mavimax, Ltd
0033  * contact@mavimax.com
0034  * -----------------------------------------------------------------------------
0035  */
0036 
0037 /*---------------------------Includes-----------------------------------*/
0038 #include <stdlib.h>
0039 #include <math.h>
0040 #include <errno.h>
0041 #include <ubf.h>
0042 #include <ubf_int.h>
0043 #include <fdatatype.h>
0044 
0045 #include "ndebug.h"
0046 #include "ferror.h"
0047 #include "atmi_tls.h"
0048 #include <ubf_tls.h>
0049 /*---------------------------Externs------------------------------------*/
0050 /*---------------------------Macros-------------------------------------*/
0051 /*---------------------------Enums--------------------------------------*/
0052 /*---------------------------Typedefs-----------------------------------*/
0053 /*---------------------------Globals------------------------------------*/
0054 /*---------------------------Statics------------------------------------*/
0055 /*---------------------------Prototypes---------------------------------*/
0056 /* Get field sizes */
0057 exprivate int get_fb_dftl_size(dtype_str_t *t, char *fb, int *payload_size);
0058 exprivate int get_fb_string_size(dtype_str_t *t, char *fb, int *payload_size);
0059 exprivate int get_fb_carray_size(dtype_str_t *t, char *fb, int *payload_size);
0060 
0061 /* Function for putting data into buffer */
0062 exprivate int put_data_dflt(dtype_str_t *t, char *fb, BFLDID bfldid, char *data, int len);
0063 exprivate int put_data_string(dtype_str_t *t, char *fb, BFLDID bfldid, char *data, int len);
0064 exprivate int put_data_carray(dtype_str_t *t, char *fb, BFLDID bfldid, char *data, int len);
0065 
0066 exprivate int get_d_size_dftl (struct dtype_str *t, char *data, int len, int *payload_size);
0067 exprivate int get_d_size_string (struct dtype_str *t, char *data, int len, int *payload_size);
0068 exprivate int get_d_size_carray (struct dtype_str *t, char *data, int len, int *payload_size);
0069 
0070 exprivate int get_data_dflt (struct dtype_str *t, char *fb, char *buf, int *len);
0071 exprivate int get_data_str (struct dtype_str *t, char *fb, char *buf, int *len);
0072 exprivate int get_data_carr (struct dtype_str *t, char *fb, char *buf, int *len);
0073 
0074 exprivate int g_dflt_empty(struct dtype_ext1* t);
0075 exprivate int g_str_empty(struct dtype_ext1* t);
0076 exprivate int g_carr_empty(struct dtype_ext1* t);
0077 
0078 exprivate int put_empty_dftl(struct dtype_ext1* t, char *fb, BFLDID bfldid);
0079 exprivate int put_empty_str(struct dtype_ext1* t, char *fb, BFLDID bfldid);
0080 exprivate int put_empty_carr(struct dtype_ext1* t, char *fb, BFLDID bfldid);
0081 
0082 exprivate void dump_short (struct dtype_ext1 *t, char *text, char *data, int *len);
0083 exprivate void dump_long (struct dtype_ext1 *t, char *text, char *data, int *len);
0084 exprivate void dump_char (struct dtype_ext1 *t, char *text, char *data, int *len);
0085 exprivate void dump_float (struct dtype_ext1 *t, char *text, char *data, int *len);
0086 exprivate void dump_double (struct dtype_ext1 *t, char *text, char *data, int *len);
0087 exprivate void dump_string (struct dtype_ext1 *t, char *text, char *data, int *len);
0088 exprivate void dump_carray (struct dtype_ext1 *t, char *text, char *data, int *len);
0089 exprivate void dump_int (struct dtype_ext1 *t, char *text, char *data, int *len);
0090 exprivate void dump_ptr (struct dtype_ext1 *t, char *text, char *data, int *len);
0091 
0092 exprivate char *tbuf_short (struct dtype_ext1 *t, int len);
0093 exprivate char *tbuf_long (struct dtype_ext1 *t, int len);
0094 exprivate char *tbuf_char (struct dtype_ext1 *t, int len);
0095 exprivate char *tbuf_float (struct dtype_ext1 *t, int len);
0096 exprivate char *tbuf_double (struct dtype_ext1 *t, int len);
0097 exprivate char *tbuf_string (struct dtype_ext1 *t, int len);
0098 exprivate char *tbuf_carray (struct dtype_ext1 *t, int len);
0099 exprivate char *tbuf_int (struct dtype_ext1 *t, int len);
0100 exprivate char *tbuf_ptr (struct dtype_ext1 *t, int len);
0101 
0102 exprivate char *tallocdlft (struct dtype_ext1 *t, int *len);
0103 
0104 /**
0105  * Functions to compare field values.
0106  */
0107 exprivate int cmp_short (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0108         char *val2, BFLDLEN len2, long mode);
0109 exprivate int cmp_long (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0110         char *val2, BFLDLEN len2, long mode);
0111 exprivate int cmp_int (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0112         char *val2, BFLDLEN len2, long mode);
0113 exprivate int cmp_char (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0114         char *val2, BFLDLEN len2, long mode);
0115 exprivate int cmp_float (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0116         char *val2, BFLDLEN len2, long mode);
0117 exprivate int cmp_double (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0118         char *val2, BFLDLEN len2, long mode);
0119 exprivate int cmp_string (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0120         char *val2, BFLDLEN len2, long mode);
0121 exprivate int cmp_carray (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0122         char *val2, BFLDLEN len2, long mode);
0123 
0124 /**
0125  * We operate with 32 bit align.
0126  */
0127 expublic dtype_str_t G_dtype_str_map[] =
0128 {
0129 /* str type,altnm typeid       default size align elm fb size       put data in fb   get data size   get data from fb */
0130 {"short", NULL, BFLD_SHORT,  BFLD_SHORT_SIZE,  4, get_fb_dftl_size,  put_data_dflt,  get_d_size_dftl, get_data_dflt},     /* 0 */
0131 {"long", NULL,  BFLD_LONG,   BFLD_LONG_SIZE,   8, get_fb_dftl_size,  put_data_dflt,  get_d_size_dftl, get_data_dflt},     /* 1 */
0132 {"char", NULL,  BFLD_CHAR,   BFLD_CHAR_SIZE,   4, get_fb_dftl_size,  put_data_dflt,  get_d_size_dftl, get_data_dflt},     /* 2 */
0133 {"float", NULL, BFLD_FLOAT,  BFLD_FLOAT_SIZE,  4, get_fb_dftl_size,  put_data_dflt,  get_d_size_dftl, get_data_dflt},     /* 3 */
0134 {"double",NULL, BFLD_DOUBLE, BFLD_DOUBLE_SIZE, 8, get_fb_dftl_size,  put_data_dflt,  get_d_size_dftl, get_data_dflt},     /* 4 */
0135 {"string",NULL, BFLD_STRING, BFLD_STRING_SIZE, 4, get_fb_string_size, put_data_string,  get_d_size_string, get_data_str}, /* 5 */
0136 {"carray",NULL, BFLD_CARRAY, BFLD_CARRAY_SIZE, 4, get_fb_carray_size, put_data_carray, get_d_size_carray, get_data_carr}, /* 6 */
0137 {"int",NULL,    BFLD_INT,    BFLD_INT_SIZE,    4, get_fb_dftl_size, put_data_dflt, get_d_size_dftl, get_data_dflt},   /* 7 */
0138 /* TODO - create support functions: */
0139 {"rfu0",NULL,   BFLD_RFU0,   EXFAIL,           4, get_fb_dftl_size, put_data_dflt, get_d_size_dftl, get_data_dflt},   /* 8 */
0140 {"ptr", NULL,   BFLD_PTR,    BFLD_PTR_SIZE,    8, get_fb_dftl_size, put_data_dflt, get_d_size_dftl, get_data_dflt},/* 9 */
0141 {"ubf", "fml32",BFLD_UBF,    BFLD_UBF_SIZE,    8, ndrx_get_fb_ubf_size, ndrx_put_data_ubf, ndrx_get_d_size_ubf, ndrx_get_data_ubf},   /* 10 */
0142 {"view","view32",BFLD_VIEW,  BFLD_VIEW_SIZE,   8, ndrx_get_fb_view_size, ndrx_put_data_view, ndrx_get_d_size_view, ndrx_get_data_view},   /* 11 */
0143 {""}
0144 };
0145 
0146 #define DAO EX_ALIGNMENT_BYTES
0147 #define DAC EX_ALIGNMENT_BYTES+sizeof(BFLDLEN) /**< for string,carray having some extra... */
0148 #define DVW sizeof(UBF_view_t)  /**< full view size */
0149 /**
0150  * We operate with 32 bit align.
0151  */
0152 expublic dtype_ext1_t G_dtype_ext1_map[] =
0153 {
0154 /* type,    get default,  put empty deflt, dump,    datoff, tmpbuf fn, alloc buf, data cmp, prep offset data */
0155 {BFLD_SHORT, g_dflt_empty, put_empty_dftl, dump_short, DAO, tbuf_short, tallocdlft, cmp_short, NULL},     /* 0 */
0156 {BFLD_LONG,  g_dflt_empty, put_empty_dftl, dump_long,  DAO, tbuf_long,  tallocdlft, cmp_long, NULL},      /* 1 */
0157 {BFLD_CHAR,  g_dflt_empty, put_empty_dftl, dump_char,  DAO, tbuf_char,  tallocdlft, cmp_char, NULL},      /* 2 */
0158 {BFLD_FLOAT, g_dflt_empty, put_empty_dftl, dump_float, DAO, tbuf_float, tallocdlft, cmp_float, NULL},     /* 3 */
0159 {BFLD_DOUBLE,g_dflt_empty, put_empty_dftl, dump_double,DAO, tbuf_double,tallocdlft, cmp_double, NULL},    /* 4 */
0160 {BFLD_STRING,g_str_empty,  put_empty_str,  dump_string,DAC, tbuf_string,tallocdlft, cmp_string, NULL},    /* 5 */
0161 {BFLD_CARRAY,g_carr_empty, put_empty_carr, dump_carray,DAC, tbuf_carray,tallocdlft, cmp_carray, NULL},    /* 6 */
0162 {BFLD_INT,  g_dflt_empty, put_empty_dftl,  dump_int,   DAO, tbuf_int,   tallocdlft, cmp_int, NULL},       /* 7 */
0163 /* TODO - create support functions: */
0164 {BFLD_RFU0,  g_dflt_empty, put_empty_dftl,  dump_int,   DAO, tbuf_int,   tallocdlft, cmp_int, NULL},      /* 8 */
0165 {BFLD_PTR,  g_dflt_empty, put_empty_dftl, ndrx_dump_ptr,DAO, tbuf_ptr,   tallocdlft, ndrx_cmp_ptr, NULL},/* 9 */
0166 {BFLD_UBF,  ndrx_g_ubf_empty, ndrx_put_empty_ubf,  ndrx_dump_ubf,   DAO, NULL, tallocdlft, ndrx_cmp_ubf, NULL},/* 10 */
0167 {BFLD_VIEW,  ndrx_g_view_empty, ndrx_put_empty_view,  ndrx_dump_view,   DVW, NULL,ndrx_talloc_view, ndrx_cmp_view, ndrx_prep_viewp}, /* 11 */
0168 
0169 {-1}
0170 };
0171 /*********************** Basic data type operations ***************************/
0172 
0173 /******************************************************************************/
0174 /* Bellow functions returns data block size in UBF buffer. This data includes
0175  * data length it self + service information (BFLDID size, etc..) */
0176 /******************************************************************************/
0177 
0178 /**
0179  * Get element size
0180  * @param t
0181  * @param data
0182  * @return
0183  */
0184 exprivate int get_fb_dftl_size(dtype_str_t *t, char *fb, int *payload_size)
0185 {
0186     if (NULL!=payload_size)
0187         *payload_size = t->size;
0188 
0189     /* e.g. sizeof(BFLDID) + 1 (char) + 4 - ( 4 + 1) % 4 =
0190      * 5 + 4- 5 % 4 = 5 + 4 - 1 = 8*/
0191 /*    return (sizeof(BFLDID) + t->size) + DEFAULT_ALIGN - (sizeof(BFLDID) + t->size) % DEFAULT_ALIGN; */
0192     return ALIGNED_SIZE(t->size);
0193 }
0194 
0195 /**
0196  * Returns the field size used by string
0197  * @param t - record descriptor
0198  * @param data - FB
0199  * @return length in bytes
0200  */
0201 exprivate int get_fb_string_size(dtype_str_t *t, char *fb, int *payload_size)
0202 {
0203     UBF_string_t *str = (UBF_string_t *)fb;
0204     
0205     if (NULL!=payload_size)
0206         *payload_size = str->dlen;
0207     
0208     return ALIGNED_SIZE((sizeof (BFLDLEN) + str->dlen));
0209     
0210 }
0211 /**
0212  * Get data size which are placed into UBF buffer.
0213  * @param t
0214  * @param data
0215  * @return
0216  */
0217 exprivate int get_fb_carray_size(dtype_str_t *t, char *fb, int *payload_size)
0218 {
0219     UBF_carray_t *carr = (UBF_carray_t *)fb;
0220     if (NULL!=payload_size)
0221         *payload_size = carr->dlen;
0222     return ALIGNED_SIZE((sizeof (BFLDLEN) + carr->dlen));
0223 }
0224 
0225 /******************************************************************************/
0226 /* Put data into UBF buffer. This initializes all service information
0227  * and it copies data itself into buffer */
0228 /******************************************************************************/
0229 /**
0230  * Put data into buffer - default function usable for fixed length data types
0231  * NOTE: May require split-up for endiannes.
0232  * @param t data type
0233  * @param fb pointer to UBF buffer
0234  * @param bfldid field ID
0235  * @param data pointer to data
0236  * @param len buffer size???
0237  * @return
0238  */
0239 exprivate int put_data_dflt(dtype_str_t *t, char *fb, BFLDID bfldid, 
0240         char *data, int len)
0241 {
0242     UBF_generic_t *dflt = (void *)fb;
0243     /* int align; */
0244     dflt->bfldid = bfldid;
0245     memcpy(dflt->d, data, t->size);
0246     /* align=t->aligned_size-t->size; */
0247 
0248     /* Reset to 0 aligned memory 
0249      * TODO, do we need this reset?
0250 
0251     if (align > 0)
0252         memset(dflt->d+t->size, 0, align);
0253      */
0254     return EXSUCCEED;
0255 }
0256 
0257 /**
0258  * Put some stuffy string in!
0259  * Return last pointer!?!?
0260  * As from spec, we are not interested in length!
0261  */
0262 exprivate int put_data_string(dtype_str_t *t, char *fb, BFLDID bfldid, 
0263         char *data, int len)
0264 {
0265     UBF_string_t *str = (void *)fb;
0266 
0267     strcpy(str->str, data);
0268     str->dlen = strlen(str->str)+1;
0269     str->bfldid=bfldid;
0270 
0271     return EXSUCCEED;
0272 }
0273 
0274 exprivate int put_data_carray(dtype_str_t *t, char *fb, BFLDID bfldid, 
0275         char *data, int len)
0276 {
0277     UBF_carray_t *carr = (UBF_carray_t *)fb;
0278     /* int align; */
0279     carr->bfldid = bfldid;
0280     carr->dlen = len;
0281 
0282     if (len>0) /* Do not play with memory if length is 0 */
0283     {
0284         /*align = len % DEFAULT_ALIGN;  This assumes that fieldid & dlen is aligned already */
0285         memcpy(carr->carr, data, len);
0286         /*
0287         if (align>0)
0288         {
0289             align=DEFAULT_ALIGN-align;
0290             memset(carr->carr + len, 0, align);
0291         }
0292          * */
0293     }
0294     
0295     return EXSUCCEED;
0296 }
0297 
0298 /******************************************************************************/
0299 /* This function data size including service information, that could cost
0300  * if added to UBF buffer. I.e. this returns target size of the data if put
0301  * into the buffer */
0302 /******************************************************************************/
0303 
0304 /**
0305  * Get data size for elements from table
0306  * @param t
0307  * @param data
0308  * @param len
0309  * @return
0310  */
0311 exprivate int get_d_size_dftl (struct dtype_str *t, char *data, 
0312         int len, int *payload_size)
0313 {
0314     if (NULL!=payload_size)
0315         *payload_size = t->size;
0316     return /* t->aligned_size + sizeof(BFLDID); */ ALIGNED_SIZE(t->size);
0317 }
0318 
0319 /**
0320  * Return the size of new string data
0321  * @param t
0322  * @param data
0323  * @param len
0324  * @return
0325  */
0326 exprivate int get_d_size_string (struct dtype_str *t, char *data, 
0327         int len, int *payload_size)
0328 {
0329     int str_data_len = strlen(data)+1;
0330 
0331     if (NULL!=payload_size)
0332         *payload_size = str_data_len;
0333     
0334     return ALIGNED_SIZE(sizeof(BFLDLEN)+str_data_len);
0335 }
0336 
0337 /**
0338  * Return data size of character array element. 
0339  * @param t
0340  * @param data
0341  * @param len
0342  * @return
0343  */
0344 exprivate int get_d_size_carray (struct dtype_str *t, char *data, 
0345         int len, int *payload_size)
0346 {
0347     /* Counting: BFLDID, DLEN + data len*/
0348     
0349     if (NULL!=payload_size)
0350         *payload_size=len;
0351 
0352     return ALIGNED_SIZE((sizeof(BFLDLEN)+len));
0353 }
0354 
0355 /******************************************************************************/
0356 /* These functions returns the data from UBF buffer. Buffer lenght is
0357  * checked. Functions also return size of data copied into destination buffer */
0358 /******************************************************************************/
0359 
0360 /**
0361  * Read data (default)
0362  * NOTE: May require split-up for endiannes.
0363  * @param t descriptor table
0364  * @param fb address in FB
0365  * @param buf address to output buffer
0366  * @param len field length
0367  * @return
0368  */
0369 exprivate int get_data_dflt (struct dtype_str *t, char *fb, char *buf, int *len)
0370 {
0371     UBF_generic_t *dflt = (void *)fb;
0372     int ret=EXSUCCEED;
0373     
0374     if (NULL!=len && *len < t->size)
0375     {
0376         /* Set error, that string buffer too short */
0377         ndrx_Bset_error_fmt(BNOSPACE, "output buffer too short. Data len %d in buf, "
0378                                 "output: %d", t->size, *len);
0379         EXFAIL_OUT(ret);
0380     }
0381 
0382     memcpy(buf, dflt->d, t->size);
0383 
0384     /* Return the size to caller */
0385     if (NULL!=len)
0386     {
0387         *len = t->size;
0388     }
0389     
0390 out:
0391     return ret;
0392 }
0393 
0394 /**
0395  * Get String data
0396  * @param t
0397  * @param fb
0398  * @param buf
0399  * @param len
0400  * @return
0401  */
0402 exprivate int get_data_str (struct dtype_str *t, char *fb, char *buf, int *len)
0403 {
0404     UBF_string_t *str = (UBF_string_t *)fb;
0405     int ret=EXSUCCEED;
0406 
0407     if (NULL!=len && *len < str->dlen)
0408     {
0409         /* Set error, that string buffer too short */
0410         ndrx_Bset_error_fmt(BNOSPACE, "output buffer too short. Data len %d in buf, "
0411                                 "output: %d", str->dlen, *len);
0412         EXFAIL_OUT(ret);
0413     }
0414     else
0415     {
0416         strcpy(buf, str->str);
0417     }
0418     
0419     /* Return the size to caller */
0420     if (NULL!=len)
0421     {
0422         *len = str->dlen;
0423     }
0424     
0425 out:
0426     return ret;
0427 }
0428 
0429 /**
0430  * Return character array data
0431  * @param t
0432  * @param fb
0433  * @param buf
0434  * @param len
0435  * @return
0436  */
0437 exprivate int get_data_carr (struct dtype_str *t, char *fb, char *buf, int *len)
0438 {
0439     UBF_carray_t *carr = (UBF_carray_t *)fb;
0440     int ret=EXSUCCEED;
0441 
0442     if (NULL!=len && *len>0 && *len < carr->dlen)
0443     {
0444         /* Set error, that string buffer too short */
0445         ndrx_Bset_error_fmt(BNOSPACE, "output buffer too short. Data len %d in buf, "
0446                                 "output: %d", carr->dlen, *len);
0447         EXFAIL_OUT(ret);
0448     }
0449     else
0450     {
0451         /* copy the data */
0452         memcpy(buf, carr->carr, carr->dlen);
0453         /* Bug #495 */
0454         if (NULL!=len)
0455         {
0456             *len=carr->dlen;
0457         }
0458     }
0459 out:
0460     return ret;
0461 }
0462 /*********************** Extended 1 data type operations **********************/
0463 
0464 /******************************************************************************/
0465 /* Bellow functions return empty element data size (including service info)   */
0466 /******************************************************************************/
0467 
0468 /**
0469  * Get default empty element size
0470  * @param t
0471  * @return
0472  */
0473 exprivate int g_dflt_empty(struct dtype_ext1* t)
0474 {
0475     /*
0476     int len = G_dtype_str_map[t->fld_type].aligned_size + sizeof(BFLDID);
0477     return len;
0478     */
0479     return ALIGNED_SIZE(G_dtype_str_map[t->fld_type].size);
0480 }
0481 
0482 /**
0483  * Return empty string size
0484  * @param t
0485  * @return
0486  */
0487 exprivate int g_str_empty(struct dtype_ext1* t)
0488 {
0489     return ALIGNED_SIZE(sizeof(BFLDLEN)+1); /* empty string eos */
0490 }
0491 /**
0492  * Return empty character array size
0493  * @param t
0494  * @return
0495  */
0496 exprivate int g_carr_empty(struct dtype_ext1* t)
0497 {
0498     /*
0499     int len;
0500     len = sizeof(BFLDID)+sizeof(BFLDLEN);  This is already aligned 
0501     return len;
0502      * */
0503     return ALIGNED_SIZE(sizeof(BFLDLEN)); /* empty string eos */
0504 }
0505 
0506 /******************************************************************************/
0507 /* Bellow functions puts empty data into UBF buffer                           */
0508 /******************************************************************************/
0509 
0510 
0511 /**
0512  * Put empty default data type (fill with 0 all element)
0513  * This also applies on chars and doubles (which on some platforms could be wrong)
0514  * This also uses alignment.
0515  * @param t
0516  * @param fb
0517  * @return
0518  */
0519 exprivate int put_empty_dftl(struct dtype_ext1* t, char *fb, BFLDID bfldid)
0520 {
0521     int ret=EXSUCCEED;
0522     int elem_size = G_dtype_str_map[t->fld_type].size;
0523     
0524     UBF_generic_t *fld = (UBF_generic_t *)fb;
0525     fld->bfldid = bfldid;
0526     memset(fld->d, 0, elem_size); /* Set to default 0 */
0527 
0528     return ret;
0529 }
0530 
0531 /**
0532  * Put empty string element
0533  * @param t
0534  * @param fb
0535  * @return
0536  */
0537 exprivate int put_empty_str(struct dtype_ext1* t, char *fb, BFLDID bfldid)
0538 {
0539     int ret=EXSUCCEED;
0540 
0541     UBF_string_t *fld = (UBF_string_t *)fb;
0542     fld->bfldid = bfldid;
0543     /* Uses alignment */
0544     fld->str[0] = EXEOS;
0545     fld->dlen = 1;
0546     /*
0547     memset(fld->str, 0, DEFAULT_ALIGN);
0548     */
0549     return ret;
0550 }
0551 
0552 /**
0553  * Put empty character array element
0554  * Function is already aligned.
0555  * @param t
0556  * @param fb
0557  * @return
0558  */
0559 exprivate int put_empty_carr(struct dtype_ext1* t, char *fb, BFLDID bfldid)
0560 {
0561     int ret=EXSUCCEED;
0562 
0563     UBF_carray_t *fld = (UBF_carray_t *)fb;
0564     fld->bfldid = bfldid;
0565     fld->dlen = 0;
0566     /*fld->carr - intentionally not setting, because there is no data!*/
0567     return ret;
0568 }
0569 
0570 
0571 /******************************************************************************/
0572 /* Bellow functions dump the value depending on it's type                     */
0573 /* this is part of dtype_ext1->p_dump_data                                    */
0574 /******************************************************************************/
0575 
0576 exprivate void dump_short (struct dtype_ext1 *t, char *text, char *data, int *len)
0577 {
0578     if (NULL!=data)
0579     {
0580         short s = (short)*data;
0581         UBF_LOG(log_debug, "%s:\n[%hd]", text, s);
0582     }
0583     else
0584     {
0585         UBF_LOG(log_debug, "%s:\n[null]", text);
0586     }
0587 }
0588 
0589 exprivate void dump_long (struct dtype_ext1 *t, char *text, char *data, int *len)
0590 {
0591     if (NULL!=data)
0592     {
0593         long *l = (long *)data;
0594         UBF_LOG(log_debug, "%s:\n[%ld]", text, *l);
0595     }
0596     else
0597     {
0598         UBF_LOG(log_debug, "%s:\n[null]", text);
0599     }
0600 }
0601 
0602 exprivate void dump_char (struct dtype_ext1 *t, char *text, char *data, int *len)
0603 {
0604     if (NULL!=data)
0605     {
0606         char *c = (char *)data;
0607         UBF_LOG(log_debug, "%s:\n[%c]", text, *c);
0608     }
0609     else
0610     {
0611         UBF_LOG(log_debug, "%s:\n[null]", text);
0612     }
0613 }
0614 
0615 exprivate void dump_float (struct dtype_ext1 *t, char *text, char *data, int *len)
0616 {
0617     if (NULL!=data)
0618     {
0619         float *f = (float *)data;
0620         UBF_LOG(log_debug, "%s:\n[%.6f]", text, *f);
0621     }
0622     else
0623     {
0624         UBF_LOG(log_debug, "%s:\n[null]", text);
0625     }
0626 }
0627 
0628 exprivate void dump_double (struct dtype_ext1 *t, char *text, char *data, int *len)
0629 {
0630     if (NULL!=data)
0631     {
0632         double *d = (double *)data;
0633         UBF_LOG(log_debug, "%s:\n[%.13f]", text, *d);
0634     }
0635     else
0636     {
0637         UBF_LOG(log_debug, "%s:\n[null]", text);
0638     }
0639 }
0640 
0641 exprivate void dump_string (struct dtype_ext1 *t, char *text, char *data, int *len)
0642 {
0643     if (NULL!=data)
0644     {
0645         UBF_LOG(log_debug, "%s:\n[%s]", text, data);
0646     }
0647     else
0648     {
0649         UBF_LOG(log_debug, "%s:\n[null]", text);
0650     }
0651 }
0652 
0653 exprivate void dump_carray (struct dtype_ext1 *t, char *text, char *data, int *len)
0654 {
0655     if (NULL!=data && NULL!=len)
0656     {
0657         UBF_DUMP(log_debug, text, data, *len);
0658     }
0659     else
0660     {
0661         UBF_LOG(log_debug, "%s:\n[null data or len]", text);
0662     }
0663 }
0664 
0665 exprivate void dump_int (struct dtype_ext1 *t, char *text, char *data, int *len)
0666 {
0667     if (NULL!=data)
0668     {
0669         int *l = (int *)data;
0670         UBF_LOG(log_debug, "%s:\n[%d]", text, *l);
0671     }
0672     else
0673     {
0674         UBF_LOG(log_debug, "%s:\n[null]", text);
0675     }
0676 }
0677 
0678 /******************************************************************************/
0679 /* Bellow functions returns temporary buffer space that could be used by      */
0680 /* calls like CBfind.                                                         */
0681 /* this is part of dtype_ext1->p_tbuf                                         */
0682 /******************************************************************************/
0683 
0684 exprivate char *tbuf_short (struct dtype_ext1 *t, int len)
0685 {
0686     UBF_TLS_ENTRY;
0687     return (char *)&G_ubf_tls->tbuf_s;
0688 }
0689 
0690 exprivate char *tbuf_long (struct dtype_ext1 *t, int len)
0691 {
0692     UBF_TLS_ENTRY;
0693     return (char *)&G_ubf_tls->tbuf_l;
0694 }
0695 
0696 exprivate char *tbuf_char (struct dtype_ext1 *t, int len)
0697 {
0698     UBF_TLS_ENTRY;
0699     return (char *)&G_ubf_tls->tbuf_c;
0700 }
0701 
0702 exprivate char *tbuf_float (struct dtype_ext1 *t, int len)
0703 {
0704    UBF_TLS_ENTRY;
0705    return (char *)&G_ubf_tls->tbuf_f;
0706 }
0707 
0708 exprivate char *tbuf_double (struct dtype_ext1 *t, int len)
0709 {
0710    UBF_TLS_ENTRY;
0711    return (char *)&G_ubf_tls->tbuf_d;
0712 }
0713 
0714 /**
0715  * We will re-alloc the buffer each time
0716  * @param t - ptr to ext1 struct
0717  * @param len - potential data size
0718  * @return
0719  */
0720 exprivate char *tbuf_string (struct dtype_ext1 *t, int len)
0721 {
0722     UBF_TLS_ENTRY;
0723 
0724     if (G_ubf_tls->str_dat_len!=len)
0725     {
0726         /* Free up the memory */
0727         if (NULL!=G_ubf_tls->str_buf_ptr)
0728         {
0729             NDRX_FREE(G_ubf_tls->str_buf_ptr);
0730         }
0731 
0732         G_ubf_tls->str_buf_ptr=NDRX_MALLOC(len);
0733 
0734         if (NULL==G_ubf_tls->str_buf_ptr)
0735         {
0736             /* set error */
0737             ndrx_Bset_error_fmt(BMALLOC, "Failed to allocate string tmp "
0738                     "space for %d bytes", len);
0739         }
0740         else
0741         {
0742             UBF_LOG(log_debug, "tbuf_string: allocated %d bytes", len);
0743         }
0744     }
0745     else
0746     {
0747         UBF_LOG(log_debug, "tbuf_string: re-using existing space", len);
0748     }
0749     
0750     return G_ubf_tls->str_buf_ptr;
0751 }
0752 
0753 /**
0754  * We will re-alloc the buffer each time
0755  * @param t - ptr to ext1 struct
0756  * @param len - potential data size
0757  * @return
0758  */
0759 exprivate char *tbuf_carray (struct dtype_ext1 *t, int len)
0760 {
0761     UBF_TLS_ENTRY;
0762 
0763     if (G_ubf_tls->carray_dat_len!=len)
0764     {
0765         /* Free up the memory */
0766         if (NULL!=G_ubf_tls->carray_buf_ptr)
0767         {
0768             NDRX_FREE(G_ubf_tls->carray_buf_ptr);
0769         }
0770         
0771         G_ubf_tls->carray_buf_ptr=NDRX_MALLOC(len);
0772 
0773         if (NULL==G_ubf_tls->carray_buf_ptr)
0774         {
0775             /* set error */
0776             ndrx_Bset_error_fmt(BMALLOC, "Failed to allocate carray tmp space "
0777                     "for %d bytes", len);
0778         }
0779         else
0780         {
0781             UBF_LOG(log_debug, "tbuf_carray: allocated %d bytes", len);
0782         }
0783     }
0784     else
0785     {
0786         UBF_LOG(log_debug, "tbuf_carray: re-using existing space", len);
0787     }
0788 
0789     return G_ubf_tls->carray_buf_ptr;
0790 }
0791 
0792 exprivate char *tbuf_int (struct dtype_ext1 *t, int len)
0793 {
0794     UBF_TLS_ENTRY;
0795     return (char *)&G_ubf_tls->tbuf_i;
0796 }
0797 
0798 exprivate char *tbuf_ptr (struct dtype_ext1 *t, int len)
0799 {
0800    UBF_TLS_ENTRY;
0801    return (char *)&G_ubf_tls->tbuf_p;
0802 }
0803 
0804 /******************************************************************************/
0805 /* Bellow functions are designed for buffer allocation for conversation space.*/
0806 /* User is responsible to free it up                                          */
0807 /******************************************************************************/
0808 
0809 /**
0810  * Function currently common for all data types.
0811  * This basically just allocates the memory. It is caller's responsibility to
0812  * to set correct amount to use. It is suggested that amount should be over
0813  * CF_TEMP_BUF_MAX define.
0814  * @param t
0815  * @param len - buffer length to allocate.
0816  * @return NULL/ptr to allocated mem
0817  */
0818 exprivate char *tallocdlft (struct dtype_ext1 *t, int *len)
0819 {
0820     char *ret=NULL;
0821     int alloc_size = *len;
0822     ret=NDRX_MALLOC(alloc_size);
0823 
0824     if (NULL==ret)
0825     {
0826         ndrx_Bset_error_fmt(BMALLOC, "Failed to allocate %d bytes for user", alloc_size);
0827     }
0828     else
0829     {
0830         *len = alloc_size;
0831     }
0832 
0833     return ret;
0834 }
0835 
0836 /******************************************************************************/
0837 /* Bellow functions are designed to compare two values of the data type       */
0838 /* part of dtype_ext1->p_cmp                                                  */
0839 /******************************************************************************/
0840 
0841 exprivate int cmp_short (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0842         char *val2, BFLDLEN len2,
0843     long mode)
0844 {
0845     short *s1 = (short *)val1;
0846     short *s2 = (short *)val2;
0847     
0848     if (mode & UBF_CMP_MODE_STD)
0849     {
0850         return  *s1 - *s2;
0851     }
0852     else
0853     {
0854         return (*s1==*s2);
0855     }
0856 }
0857 
0858 exprivate int cmp_long (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0859         char *val2, BFLDLEN len2,
0860     long mode)
0861 {
0862     long *l1 = (long *)val1;
0863     long *l2 = (long *)val2;
0864     
0865     if (mode & UBF_CMP_MODE_STD)
0866     {
0867         long lres = *l1 - *l2;
0868         
0869         if (lres > 0)
0870             return 1;
0871         else if (lres < 0)
0872             return -1;
0873         else
0874             return 0;
0875     }
0876     else
0877     {
0878         return (*l1==*l2);
0879     }
0880 }
0881 
0882 exprivate int cmp_int (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0883         char *val2, BFLDLEN len2,
0884     long mode)
0885 {
0886     int *i1 = (int *)val1;
0887     int *i2 = (int *)val2;
0888     
0889     if (mode & UBF_CMP_MODE_STD)
0890     {
0891         return (*i1 - *i2);
0892     }
0893     else
0894     {
0895         return (*i1==*i2);
0896     }
0897 }
0898 
0899 exprivate int cmp_char (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0900         char *val2, BFLDLEN len2, long mode)
0901 {
0902     unsigned char *c1 = (unsigned char *)val1;
0903     unsigned char *c2 = (unsigned char *)val2;
0904     
0905     if (mode & UBF_CMP_MODE_STD)
0906     {
0907         return (*c1 - *c2);
0908     }
0909     else
0910     {
0911         return (*c1==*c2);
0912     }
0913 }
0914 
0915 exprivate int cmp_float (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0916         char *val2, BFLDLEN len2, long mode)
0917 {
0918     float *f1 = (float *)val1;
0919     float *f2 = (float *)val2;
0920     
0921     if (mode & UBF_CMP_MODE_STD)
0922     {
0923         float f = *f1-*f2;
0924         
0925         if (fabs(f) < FLOAT_EQUAL )
0926         {
0927             return 0;
0928         }
0929         else if (f > 0)
0930         {
0931             return 1;
0932         }
0933         else
0934         {
0935             return -1;
0936         }
0937         
0938     }
0939     else
0940     {
0941         return (fabs(*f1-*f2)<FLOAT_EQUAL);
0942     }
0943     
0944 }
0945 
0946 exprivate int cmp_double (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0947         char *val2, BFLDLEN len2, long mode)
0948 {
0949     double *f1 = (double *)val1;
0950     double *f2 = (double *)val2;
0951     
0952     if (mode & UBF_CMP_MODE_STD)
0953     {
0954         double f = *f1-*f2;
0955         
0956         if (fabs(f) < FLOAT_EQUAL )
0957         {
0958             return 0;
0959         }
0960         else if (f > 0)
0961         {
0962             return 1;
0963         }
0964         else
0965         {
0966             return -1;
0967         }
0968         
0969     }
0970     else
0971     {
0972         return (fabs(*f1-*f2)<DOUBLE_EQUAL);
0973     }
0974 }
0975 
0976 /**
0977  * NOTE: val1 - assuming is user API input!
0978  * Last expression is being cached for better performance.
0979  * @param t
0980  * @param val1 
0981  * @param len1 
0982  * @param val2 - user input, may contain regular expression to match on buffer
0983  * @param len2 - if !=0, then using regexp
0984  * @return
0985  */
0986 exprivate int cmp_string (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
0987         char *val2, BFLDLEN len2, long mode)
0988 {
0989     int ret=EXSUCCEED;
0990     char *fn = "cmp_string";
0991 
0992     if (mode & UBF_CMP_MODE_STD)
0993     {
0994         return strcmp(val1, val2);
0995     }
0996     else if (0==len2)
0997     {
0998         ret=(0==strcmp(val1, val2));
0999     }
1000     else
1001     {
1002         static regex_t re;
1003         static char *cashed_string=NULL;
1004         int tmp_len;
1005         char *tmp_regex=NULL;
1006         int err;
1007 
1008         if (NULL==cashed_string || 0!=strcmp(val2, cashed_string))
1009         {
1010             if (NULL!=cashed_string)
1011             {
1012                 UBF_LOG(log_debug, "Freeing-up previously allocated "
1013                                                     "resources");
1014                 NDRX_FREE(cashed_string);
1015                 regfree(&re);
1016             }
1017 
1018             tmp_len= strlen(val2)+1; /* + EOS*/
1019             cashed_string = NDRX_MALLOC(tmp_len); /* +EOS */
1020             tmp_regex = NDRX_MALLOC(tmp_len+2); /* ^$ */
1021 
1022             if (NULL==cashed_string)
1023             {
1024                 ndrx_Bset_error_fmt(BMALLOC, "Failed to allocate %d bytes", tmp_len);
1025                 ret=EXFAIL;
1026             }
1027 
1028             if (NULL==tmp_regex)
1029             {
1030                 ndrx_Bset_error_fmt(BMALLOC, "Failed to allocate %d bytes", tmp_len);
1031                 ret=EXFAIL;
1032             }
1033             else
1034             {
1035                 strcpy(tmp_regex+1, val2);
1036                 tmp_regex[0] = '^';
1037                 tmp_len = strlen(tmp_regex);
1038                 tmp_regex[tmp_len] = '$';
1039                 tmp_regex[tmp_len+1] = '\0'; /* put ending EOS */
1040             }
1041 
1042             if (EXSUCCEED==ret)
1043             {
1044                 UBF_LOG(log_debug, "%s:Compiling regex [%s]", fn, tmp_regex);
1045             }
1046 
1047             if (EXSUCCEED==ret && EXSUCCEED!=(err=regcomp(&re, tmp_regex, 
1048                     REG_EXTENDED | REG_NOSUB)))
1049             {
1050                 ndrx_report_regexp_error("regcomp", err, &re);
1051                 ret=EXFAIL;
1052             }
1053             else if (EXSUCCEED==ret)
1054             {
1055                 strcpy(cashed_string, val2);
1056                 UBF_LOG(log_debug, "%s:REGEX: Compiled OK", fn);
1057             }
1058 
1059             /* Free up allocated cache */
1060             if (EXFAIL==ret)
1061             {
1062                 if (NULL!=cashed_string)
1063                 {
1064                     NDRX_FREE(cashed_string); /* free up cached string for next time */
1065                     cashed_string=NULL;
1066                 }
1067             }
1068 
1069             /* Free up temporary regexp expression */
1070             if (NULL!=tmp_regex)
1071             {
1072                 NDRX_FREE(tmp_regex);
1073             }
1074         }
1075 
1076         if (EXSUCCEED==ret && EXSUCCEED==regexec(&re, val1, (size_t) 0, NULL, 0))
1077         {
1078             UBF_LOG(log_debug, "%s:REGEX: Matched", fn);
1079             ret=EXTRUE;
1080         }
1081         else
1082         {
1083             UBF_LOG(log_debug, "%s:REGEX: NOT Matched", fn);
1084         }   
1085     }
1086 
1087     return ret;
1088 }
1089 
1090 exprivate int cmp_carray (struct dtype_ext1 *t, char *val1, BFLDLEN len1, 
1091         char *val2, BFLDLEN len2, long mode)
1092 {
1093     
1094     if (mode & UBF_CMP_MODE_STD)
1095     {
1096         long ldiff = len1 - len2;
1097         
1098         
1099         if ( ldiff > 0)
1100         {
1101             return 1;
1102         }
1103         else if ( ldiff < 0)
1104         {
1105             return -1;
1106         }
1107         
1108         return memcmp(val1, val2, len1);
1109     }
1110     else
1111     {
1112         if (len1!=len2)
1113             return EXFALSE;
1114         
1115         return (0==memcmp(val1, val2, len1));
1116     }
1117 }
1118 
1119 /* vim: set ts=4 sw=4 et smartindent: */