Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief UBF library
0003  *   The emulator of UBF library
0004  *   Enduro Execution Library
0005  *   Implementation of projection functions.
0006  *
0007  * @file fproj_impl.c
0008  */
0009 /* -----------------------------------------------------------------------------
0010  * Enduro/X Middleware Platform for Distributed Transaction Processing
0011  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0012  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0013  * This software is released under one of the following licenses:
0014  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0015  * See LICENSE file for full text.
0016  * -----------------------------------------------------------------------------
0017  * AGPL license:
0018  *
0019  * This program is free software; you can redistribute it and/or modify it under
0020  * the terms of the GNU Affero General Public License, version 3 as published
0021  * by the Free Software Foundation;
0022  *
0023  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0024  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0025  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0026  * for more details.
0027  *
0028  * You should have received a copy of the GNU Affero General Public License along 
0029  * with this program; if not, write to the Free Software Foundation, Inc.,
0030  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0031  *
0032  * -----------------------------------------------------------------------------
0033  * A commercial use license is available from Mavimax, Ltd
0034  * contact@mavimax.com
0035  * -----------------------------------------------------------------------------
0036  */
0037 
0038 /*---------------------------Includes-----------------------------------*/
0039 #include <string.h>
0040 #include <stdio.h>
0041 #include <stdlib.h>
0042 #include <memory.h>
0043 
0044 #include <ubf.h>
0045 #include <ubf_int.h>    /* Internal headers for UBF... */
0046 #include <fdatatype.h>
0047 #include <ferror.h>
0048 #include <fieldtable.h>
0049 #include <ndrstandard.h>
0050 #include <ndebug.h>
0051 #include <cf.h>
0052 /*---------------------------Externs------------------------------------*/
0053 /*---------------------------Macros-------------------------------------*/
0054 /* #define UBF_API_DEBUG */
0055 /*---------------------------Enums--------------------------------------*/
0056 /*---------------------------Typedefs-----------------------------------*/
0057 /*---------------------------Globals------------------------------------*/
0058 /*---------------------------Statics------------------------------------*/
0059 /*---------------------------Prototypes---------------------------------*/
0060 
0061 /**
0062  * Compare two integers
0063  * @param a
0064  * @param b
0065  * @return
0066  */
0067 int compare (const void * a, const void * b)
0068 {
0069     return ( *(int*)a - *(int*)b );
0070 }
0071 
0072 /**
0073  * Performs binary search on passed in list
0074  * @param array - array it selft
0075  * @param left - min value
0076  * @param right - max value
0077  * @param number - number to search for
0078  * @return TRUE(found)/FALSE(not found)
0079  */
0080 int is_fld_pres (BFLDID * array, BFLDID left, BFLDID right, BFLDID number)
0081 {
0082     int middle = 0;
0083     int bsearch = EXFALSE;
0084 
0085     while(bsearch == EXFALSE && left <= right)
0086     {
0087         middle = (left + right) / 2;
0088 
0089         if(number == array[middle])
0090         {
0091             bsearch = EXTRUE;
0092         }
0093         else
0094         {
0095                 if(number < array[middle]) right = middle - 1;
0096                 if(number > array[middle]) left = middle + 1;
0097         }
0098     }
0099     
0100     UBF_LOG(log_debug, "is_fld_pres: [%p/%s] in%s list",
0101                                         number, ndrx_Bfname_int(number), bsearch?"":" NOT");
0102 
0103     return bsearch;
0104 }
0105 
0106 /**
0107  * Delete & clean up the buffer.
0108  * @param hdr - ptr header
0109  * @param del_start - ptr to start of removal
0110  * @param del_stop - ptr to end of the removal
0111  */
0112 exprivate void delete_buffer_data(UBFH *p_ub, char *del_start, char *del_stop,
0113                                 BFLDID **p_nextfld)
0114 {
0115     char *last;
0116     int remove_size;
0117     int move_size;
0118     UBF_header_t *hdr = (UBF_header_t *)p_ub;
0119     char fn[] = "delete_buffer_data";
0120     char *p;
0121 /***************************************** DEBUG *******************************/
0122 #ifdef UBF_API_DEBUG
0123     /* Real debug stuff!! */
0124     UBF_header_t *__p_ub_copy;
0125     int *__dbg_fldptr_org;
0126     int *__dbg_fldptr_new;
0127     char *__dbg_p_org;
0128     char *__dbg_p_new;
0129     int __dbg_newuse;
0130     int __dbg_olduse;
0131 #endif
0132 /*******************************************************************************/
0133 /***************************************** DEBUG *******************************/
0134 #ifdef UBF_API_DEBUG
0135     __p_ub_copy = NDRX_MALLOC(hdr->buf_len);
0136     memcpy(__p_ub_copy, p_ub, hdr->buf_len);
0137 
0138     UBF_LOG(log_debug, "%s: entry\n"
0139                                     "FBbuflen=%d FBused=%d FBfree=%d ",fn,
0140                                     hdr->buf_len, hdr->bytes_used,
0141                                     (hdr->buf_len - hdr->bytes_used));
0142 #endif
0143 /*******************************************************************************/
0144     /* We should remove here stuff out of the buffer
0145      * In range from del_bfldid_start..p_bfldid
0146      * and update the pointers
0147      */
0148 
0149     remove_size = del_stop-del_start;
0150 
0151     UBF_LOG(log_debug, "About to delete from buffer: %d bytes",
0152             remove_size);
0153 
0154     last = (char *)hdr;
0155     last+=(hdr->bytes_used-1);
0156 
0157     /* Remove the data */
0158     move_size = (last-del_start+1) - remove_size;
0159 
0160     UBF_LOG(log_debug, "delete_buffer_data: to %p, from %p size: %d",
0161                     del_start, del_start+remove_size, move_size);
0162 
0163     memmove(del_start, del_start+remove_size, move_size);
0164     hdr->bytes_used-=remove_size;
0165 
0166     /* Now reset the tail to zeros */
0167     last = (char *)hdr;
0168     last+=(hdr->bytes_used-1);
0169 
0170     /* Ensure that we reset last elements... So that we do not get
0171      * used elements
0172      */
0173     UBF_LOG(log_debug, "resetting: %p to 0 - %d bytes",
0174                     last+1, remove_size);
0175     memset(last+1, 0, remove_size);
0176 
0177     /* Update the pointer to next */
0178     p = (char *)*p_nextfld;
0179     p-=remove_size;
0180     *p_nextfld= (BFLDID *)p;
0181 /***************************************** DEBUG *******************************/
0182 #ifdef UBF_API_DEBUG
0183     __dbg_olduse = __p_ub_copy->bytes_used;
0184     __dbg_newuse = hdr->bytes_used;
0185 
0186     /* Do bellow to print out end element (last) of the array - should be bbadfldid */
0187     __dbg_p_org = (char *)__p_ub_copy;
0188     __dbg_p_org+= (__p_ub_copy->bytes_used - FF_USED_BYTES);
0189 
0190     __dbg_p_new = (char *)hdr;
0191     __dbg_p_new+= (hdr->bytes_used - FF_USED_BYTES);
0192 
0193     __dbg_fldptr_org = (int *)__dbg_p_org;
0194     __dbg_fldptr_new = (int *)__dbg_p_new;
0195 
0196     UBF_LOG(log_debug, "%s: org_used=%d new_used=%d diff=%d "
0197                                 "org_start=%d/%p new_start=%d/%p\n"
0198                                 "old_finish=%d/%p, new_finish=%d/%p",
0199                                 fn,
0200                                 __dbg_olduse,
0201                                 __dbg_newuse,
0202                                 (__dbg_olduse - __dbg_newuse),
0203                                 __p_ub_copy->bfldid, __p_ub_copy->bfldid,
0204                                 hdr->bfldid, hdr->bfldid,
0205                                 *__dbg_fldptr_org, *__dbg_fldptr_org,
0206                                 *__dbg_fldptr_new, *__dbg_fldptr_new);
0207     /* Check the last four bytes before the end */
0208     __dbg_p_org-= FF_USED_BYTES;
0209     __dbg_p_new-= FF_USED_BYTES;
0210     __dbg_fldptr_org = (int *)__dbg_p_org;
0211     __dbg_fldptr_new = (int *)__dbg_p_new;
0212     UBF_LOG(log_debug, "%s: last %d bytes of data\n org=%p new %p",
0213                           fn, FF_USED_BYTES, *__dbg_fldptr_org, *__dbg_fldptr_new);
0214     UBF_DUMP_DIFF(log_always, "After _Bproj", __p_ub_copy, p_ub, hdr->buf_len);
0215     UBF_DUMP(log_always, "Used buffer dump after delete_buffer_data: ",
0216                                 p_ub, hdr->bytes_used);
0217     NDRX_FREE(__p_ub_copy);
0218 #endif
0219 /*******************************************************************************/
0220 }
0221 
0222 /**
0223  * Function leaves only required fields into the buffer
0224  * This version will also serve as core for Bdelete and Bdeleteall
0225  * @param p_ub
0226  * @param fldlist - list of fields to be kept into buffer. If NULL or just BBADFLDID,
0227  *                  then buffer is reinitialized.
0228  * @param mode  - operating mode, see PROJ_MODE_*
0229  * @param processed - ptr to int, which will return the count of chunks processed
0230  * @return SUCCEED/FAIL
0231  */
0232 expublic int ndrx_Bproj (UBFH * p_ub, BFLDID * fldlist,
0233                                     int mode, int *processed)
0234 {
0235     UBF_header_t *hdr = (UBF_header_t *)p_ub;
0236     int ret=EXSUCCEED;
0237     BFLDID   *p_bfldid = &hdr->bfldid;
0238     char *p = (char *)&hdr->bfldid;
0239     BFLDID *del_bfldid_start = NULL; /* Mark the point when we should delete the field */
0240 
0241     dtype_str_t *dtype=NULL;
0242     int fld_count = 0;
0243     BFLDID *f_p=fldlist;
0244     int step;
0245     char fn[] = "_Bproj";
0246     int type;
0247     int mark;
0248 /***************************************** DEBUG *******************************/
0249 #ifdef UBF_API_DEBUG
0250     /* Real debug stuff!! */
0251     UBF_header_t *__p_ub_copy;
0252     int *__dbg_fldptr_org;
0253     int *__dbg_fldptr_new;
0254     char *__dbg_p_org;
0255     char *__dbg_p_new;
0256     int __dbg_newuse;
0257     int __dbg_olduse;
0258     dtype_str_t *__dbg_dtype;
0259 #endif
0260 /*******************************************************************************/
0261 
0262 /***************************************** DEBUG *******************************/
0263 #ifdef UBF_API_DEBUG
0264     __p_ub_copy = NDRX_MALLOC(hdr->buf_len);
0265     memcpy(__p_ub_copy, p_ub, hdr->buf_len);
0266 
0267     UBF_LOG(log_debug, "%s: entry\n FBbuflen=%d FBused=%d FBfree=%d ",fn,
0268                                     hdr->buf_len, hdr->bytes_used,
0269                                     (hdr->buf_len - hdr->bytes_used));
0270     
0271 #endif
0272 /*******************************************************************************/
0273     *processed=0;
0274     /* In this case we delete all items - run the init */
0275     if (NULL==fldlist || BBADFLDID==*fldlist)
0276     {
0277         ret=Binit (p_ub, hdr->buf_len);
0278     }
0279     else
0280     {
0281         /* Get the count */
0282         if (PROJ_MODE_DELALL!=mode)
0283         {
0284             while(BBADFLDID!=*f_p)
0285             {
0286                 fld_count++;
0287                 f_p++;
0288             }
0289         }
0290         else
0291         {
0292             /* In this case we have only one field */
0293             fld_count=1;
0294         }
0295 
0296         /* In all other cases
0297          * 1. Sort the incoming array
0298          * 2. Loop through the buffer, and delete all un-needed items.
0299          */
0300         qsort (fldlist, fld_count, sizeof(int), compare);
0301 
0302         /* OK stuff is sorted */
0303         /* Do not count in bad field by it self. It is not needed for us! */
0304         while(!UBF_EOF(hdr, p_bfldid))
0305         {
0306             /* Should we start removal? */
0307             if (PROJ_MODE_PROJ==mode)
0308             {
0309                 /* if not in list then about to delete. */
0310                 mark = !is_fld_pres(fldlist, 0, fld_count-1, *p_bfldid);
0311             }
0312             else if (PROJ_MODE_DELETE==mode)
0313             {
0314                 mark = is_fld_pres(fldlist, 0, fld_count-1, *p_bfldid);
0315             }
0316             else if (PROJ_MODE_DELALL==mode)
0317             {
0318                 /* single field mode, if in list then about to delete*/
0319                 mark = *fldlist==*p_bfldid;
0320             }
0321             else
0322             {
0323                 UBF_LOG(log_error, "Unknown proj mode %d", mode);
0324                 return EXFAIL; /* <<< RETURN! */
0325             }
0326             
0327             /* if (NULL!=del_bfldid_start && *del_bfldid_start != *p_bfldid && !pres)*/
0328             if (NULL!=del_bfldid_start && !mark)
0329             {
0330                 UBF_LOG(log_debug, "Current BFLDID before removal: %p",
0331                                                     *p_bfldid);
0332 
0333                 delete_buffer_data(p_ub, (char *)del_bfldid_start, 
0334                         (char *)p_bfldid, &p_bfldid);
0335 
0336                 UBF_LOG(log_debug, "Current BFLDID after  removal: %p",
0337                                                     *p_bfldid);
0338                 /* Mark that we have all done! */
0339                 del_bfldid_start=NULL; /* Mark that we have finished with this. */
0340                 *processed=*processed+1;
0341             }
0342 
0343             if (mark && NULL==del_bfldid_start)
0344             {
0345                 del_bfldid_start = p_bfldid;
0346                 UBF_LOG(log_debug, "Marking field %p for deletion at %p",
0347                                         *del_bfldid_start, del_bfldid_start);
0348             }
0349             /* Get type descriptor */
0350             type = *p_bfldid>>EFFECTIVE_BITS;
0351 
0352             if (IS_TYPE_INVALID(type))
0353             {
0354                 ret=EXFAIL;
0355                 ndrx_Bset_error_fmt(BALIGNERR, "%s: Unknown data type found in "
0356                                         "buffer: %d", fn, type);
0357                 break; /* <<< BREAK; */
0358             }
0359 
0360             /* Check type alignity */
0361             dtype = &G_dtype_str_map[type];
0362             p = (char *)p_bfldid;
0363             /* Get the step */
0364             step = dtype->p_next(dtype, p, NULL);
0365 
0366             /* Move us forward. */
0367             p+=step;
0368             /* Align error */
0369             if (CHECK_ALIGN(p, p_ub, hdr))
0370             {
0371                 ret=EXFAIL;
0372                 ndrx_Bset_error_fmt(BALIGNERR, "%s: Pointing to non UBF area: %p",
0373                                             fn, p);
0374                 break; /* <<< BREAK; */
0375             }
0376             p_bfldid = (BFLDID *)p;
0377 
0378         }
0379 
0380         /* If last field was Bad field, then still we need to delete the stuff out! */
0381         if (EXSUCCEED==ret && NULL!=del_bfldid_start && *del_bfldid_start != *p_bfldid)
0382         {
0383 
0384             delete_buffer_data(p_ub, (char *)del_bfldid_start,
0385                                 (char *)p_bfldid, &p_bfldid);
0386             /* Mark that we have all done! */
0387             del_bfldid_start=NULL; /* Mark that we have finished with this. */
0388             *processed=*processed+1;
0389         }
0390     } /* Else  of use of Binit */
0391     
0392     if (EXSUCCEED!=ubf_cache_update(p_ub))
0393     {
0394         ndrx_Bset_error_fmt(BALIGNERR, "%s: Failed to update cache!");
0395         EXFAIL_OUT(ret);
0396     }
0397     
0398 out:
0399 /***************************************** DEBUG *******************************/
0400 #ifdef UBF_API_DEBUG
0401     __dbg_olduse = __p_ub_copy->bytes_used;
0402     __dbg_newuse = hdr->bytes_used;
0403 
0404     /* Do bellow to print out end element (last) of the array - should be bbadfldid */
0405     __dbg_p_org = (char *)__p_ub_copy;
0406     __dbg_p_org+= (__p_ub_copy->bytes_used - FF_USED_BYTES);
0407 
0408     __dbg_p_new = (char *)hdr;
0409     __dbg_p_new+= (hdr->bytes_used - FF_USED_BYTES);
0410 
0411     __dbg_fldptr_org = (int *)__dbg_p_org;
0412     __dbg_fldptr_new = (int *)__dbg_p_new;
0413 
0414     UBF_LOG(log_debug, "%s: returns=%d\norg_used=%d new_used=%d diff=%d "
0415                                 "org_start=%d/%p new_start=%d/%p\n"
0416                                 "old_finish=%d/%p, new_finish=%d/%p",
0417                                 fn,
0418                                 ret,
0419                                 __dbg_olduse,
0420                                 __dbg_newuse,
0421                                 (__dbg_olduse - __dbg_newuse),
0422                                 __p_ub_copy->bfldid, __p_ub_copy->bfldid,
0423                                 hdr->bfldid, hdr->bfldid,
0424                                 *__dbg_fldptr_org, *__dbg_fldptr_org,
0425                                 *__dbg_fldptr_new, *__dbg_fldptr_new);
0426     /* Check the last four bytes before the end */
0427     __dbg_p_org-= FF_USED_BYTES;
0428     __dbg_p_new-= FF_USED_BYTES;
0429     __dbg_fldptr_org = (int *)__dbg_p_org;
0430     __dbg_fldptr_new = (int *)__dbg_p_new;
0431     UBF_LOG(log_debug, "%s: last %d bytes of data\n org=%p new %p",
0432                           fn, FF_USED_BYTES, *__dbg_fldptr_org, *__dbg_fldptr_new);
0433     UBF_DUMP_DIFF(log_always, "After _Bproj", __p_ub_copy, p_ub, hdr->buf_len);
0434     UBF_DUMP(log_always, "Used buffer dump after _Bproj: ",p_ub, hdr->bytes_used);
0435     NDRX_FREE(__p_ub_copy);
0436 #endif
0437 /*******************************************************************************/
0438 
0439     return ret;     
0440 }
0441 
0442 
0443 /**
0444  * Copy buffer from one to another
0445  * @param hdr - ptr header
0446  * @param del_start 
0447  * @param del_stop 
0448  */
0449 exprivate int copy_buffer_data(UBFH *p_ub_dst,
0450                         char *cpy_start, char *cpy_stop, BFLDID **p_nextfld_dst)
0451 {
0452     int ret=EXSUCCEED;
0453     int cpy_size;
0454     UBF_header_t *hdr_dst = (UBF_header_t *)p_ub_dst;
0455 
0456     char fn[] = "delete_buffer_data";
0457     char *p;
0458 /***************************************** DEBUG *******************************/
0459 #ifdef UBF_API_DEBUG
0460     /* Real debug stuff!! */
0461     UBF_header_t *__p_ub_copy;
0462     int *__dbg_fldptr_org;
0463     int *__dbg_fldptr_new;
0464     char *__dbg_p_org;
0465     char *__dbg_p_new;
0466     int __dbg_newuse;
0467     int __dbg_olduse;
0468     dtype_str_t *__dbg_dtype;
0469 #endif
0470 /*******************************************************************************/
0471 /***************************************** DEBUG *******************************/
0472 #ifdef UBF_API_DEBUG
0473     __p_ub_copy = NDRX_MALLOC(hdr_dst->buf_len);
0474     memcpy(__p_ub_copy, p_ub_dst, hdr_dst->buf_len);
0475 
0476     UBF_LOG(log_debug, "%s: entry\n"
0477                                     "FBbuflen=%d FBused=%d FBfree=%d ",fn,
0478                                     hdr_dst->buf_len, hdr_dst->bytes_used,
0479                                     (hdr_dst->buf_len - hdr_dst->bytes_used));
0480 #endif
0481 /*******************************************************************************/
0482         /* We should remove here stuff out of the buffer
0483          * In range from del_bfldid_start..p_bfldid
0484          * and update the pointers
0485          */
0486 
0487         cpy_size = cpy_stop-cpy_start;
0488 
0489         UBF_LOG(log_debug, "About to copy from buffer: %d bytes",
0490                 cpy_size);
0491         /*
0492          * Check dest buffer length.
0493          */
0494         if (hdr_dst->bytes_used+cpy_size > hdr_dst->buf_len)
0495         {
0496             ndrx_Bset_error_fmt(BNOSPACE, "No space in dest buffer, free: "
0497                                       "%d bytes required: %d bytes",
0498                                 (hdr_dst->buf_len - hdr_dst->bytes_used), cpy_size);
0499             ret=EXFAIL;
0500         }
0501         else
0502         {                  
0503             memcpy(*p_nextfld_dst, cpy_start, cpy_size);
0504 
0505             /* Update dest pointer */
0506             p = (char *)*p_nextfld_dst;
0507             p+=cpy_size;
0508             *p_nextfld_dst = (BFLDID *)p;
0509             hdr_dst->bytes_used+=cpy_size;
0510             
0511         }
0512 /***************************************** DEBUG *******************************/
0513 #ifdef UBF_API_DEBUG
0514     __dbg_olduse = __p_ub_copy->bytes_used;
0515     __dbg_newuse = hdr_dst->bytes_used;
0516 
0517     /* Do bellow to print out end element (last) of the array - should be bbadfldid */
0518     __dbg_p_org = (char *)__p_ub_copy;
0519     __dbg_p_org+= (__p_ub_copy->bytes_used - FF_USED_BYTES);
0520 
0521     __dbg_p_new = (char *)hdr_dst;
0522     __dbg_p_new+= (hdr_dst->bytes_used - FF_USED_BYTES);
0523 
0524     __dbg_fldptr_org = (int *)__dbg_p_org;
0525     __dbg_fldptr_new = (int *)__dbg_p_new;
0526 
0527     UBF_LOG(log_debug, "%s: org_used=%d new_used=%d diff=%d "
0528                                 "org_start=%d/%p new_start=%d/%p\n"
0529                                 "old_finish=%d/%p, new_finish=%d/%p",
0530                                 fn,
0531                                 __dbg_olduse,
0532                                 __dbg_newuse,
0533                                 (__dbg_olduse - __dbg_newuse),
0534                                 __p_ub_copy->bfldid, __p_ub_copy->bfldid,
0535                                 hdr_dst->bfldid, hdr_dst->bfldid,
0536                                 *__dbg_fldptr_org, *__dbg_fldptr_org,
0537                                 *__dbg_fldptr_new, *__dbg_fldptr_new);
0538     /* Check the last four bytes before the end */
0539     __dbg_p_org-= FF_USED_BYTES;
0540     __dbg_p_new-= FF_USED_BYTES;
0541     __dbg_fldptr_org = (int *)__dbg_p_org;
0542     __dbg_fldptr_new = (int *)__dbg_p_new;
0543     UBF_LOG(log_debug, "%s: last %d bytes of data\n org=%p new %p",
0544                           fn, FF_USED_BYTES, *__dbg_fldptr_org, *__dbg_fldptr_new);
0545     UBF_DUMP_DIFF(log_always, "After _Bproj", __p_ub_copy, p_ub_dst, hdr_dst->buf_len);
0546     UBF_DUMP(log_always, "Used buffer dump after delete_buffer_data: ",
0547                                 p_ub_dst, hdr_dst->bytes_used);
0548     NDRX_FREE(__p_ub_copy);
0549 #endif
0550 /*******************************************************************************/
0551     return ret;
0552 }
0553 
0554 /**
0555  * Projection copy from one buffer to another buffer
0556  * @param p_ub_dst - dst buffer (being modified)
0557  * @param p_ub_src - src buffer (not modified)
0558  * @param fldlist - list of fields to be kept into buffer. If NULL or just BBADFLDID,
0559  *                  then buffer is reinitialized.
0560  * @return SUCCEED/FAIL
0561  */
0562 expublic int ndrx_Bprojcpy (UBFH * p_ub_dst, UBFH * p_ub_src,
0563                                     BFLDID * fldlist)
0564 {
0565     int ret=EXSUCCEED;
0566 
0567     UBF_header_t *hdr_src = (UBF_header_t *)p_ub_src;
0568     BFLDID   *p_bfldid_src = &hdr_src->bfldid;
0569     char *p = (char *)&hdr_src->bfldid;
0570     BFLDID *cpy_bfldid_start = NULL; /* Mark the point when we should delete the field */
0571     
0572     
0573     UBF_header_t *hdr_dst = (UBF_header_t *)p_ub_dst;
0574     BFLDID   *p_bfldid_dst = &hdr_dst->bfldid;
0575 
0576 
0577     dtype_str_t *dtype=NULL;
0578     int fld_count = 0;
0579     BFLDID *f_p=fldlist;
0580     int step;
0581     char fn[] = "_Bprojcpy";
0582     int type;
0583     int mark;
0584 /***************************************** DEBUG *******************************/
0585 #ifdef UBF_API_DEBUG
0586     /* Real debug stuff!! */
0587     UBF_header_t *__p_ub_copy;
0588     int *__dbg_fldptr_org;
0589     int *__dbg_fldptr_new;
0590     char *__dbg_p_org;
0591     char *__dbg_p_new;
0592     int __dbg_newuse;
0593     int __dbg_olduse;
0594 #endif
0595 /*******************************************************************************/
0596 
0597 /***************************************** DEBUG *******************************/
0598 #ifdef UBF_API_DEBUG
0599     __p_ub_copy = NDRX_MALLOC(hdr_dst->buf_len);
0600     memcpy(__p_ub_copy, p_ub_dst, hdr_dst->buf_len);
0601 
0602     UBF_LOG(log_debug, "%s: dst buf: entry\n FBbuflen=%d FBused=%d FBfree=%d ",fn,
0603                                     hdr_dst->buf_len, hdr_dst->bytes_used,
0604                                     (hdr_dst->buf_len - hdr_dst->bytes_used));
0605 
0606 #endif
0607 /*******************************************************************************/
0608     /* In this case we delete all items - run the init */
0609     
0610     if (EXSUCCEED!=Binit (p_ub_dst, hdr_dst->buf_len))
0611     {
0612         EXFAIL_OUT(ret);
0613     }
0614 
0615     if ((NULL==fldlist || BBADFLDID==*fldlist))
0616     {
0617         UBF_LOG(log_debug, "Copy list empty - nothing to do!");
0618     }
0619     else
0620     {
0621 
0622         /* Get the count */
0623         while(BBADFLDID!=*f_p)
0624         {
0625             fld_count++;
0626             f_p++;
0627         }
0628 
0629         /* In all other cases
0630          * 1. Sort the incoming array
0631          * 2. Loop throught the buffer, and delete all un-needed items.
0632          */
0633         qsort (fldlist, fld_count, sizeof(int), compare);
0634 
0635         /* OK stuff is sorted */
0636         /* Do not count in bad field by it self. It is not needed for us! */
0637         while(EXSUCCEED==ret && !UBF_EOF(hdr_src, p_bfldid_src))
0638         {
0639             mark = is_fld_pres(fldlist, 0, fld_count-1, *p_bfldid_src);
0640             
0641             if (NULL!=cpy_bfldid_start && !mark)
0642             {
0643                 if (EXSUCCEED!=copy_buffer_data(p_ub_dst,
0644                             (char *)cpy_bfldid_start,
0645                             (char *)p_bfldid_src, &p_bfldid_dst))
0646                 {
0647                     EXFAIL_OUT(ret);
0648                 }
0649                 /* Mark that we have all done! */
0650                 cpy_bfldid_start=NULL; /* Mark that we have finished with this. */
0651                 
0652             }
0653 
0654             /* Should we start removal? */
0655             if (mark &&
0656                     NULL==cpy_bfldid_start)
0657             {
0658                 cpy_bfldid_start = p_bfldid_src;
0659                 UBF_LOG(log_debug, "Marking field %p for copy at %p",
0660                                         *cpy_bfldid_start, cpy_bfldid_start);
0661             }
0662             /* Get type descriptor */
0663             type = *p_bfldid_src>>EFFECTIVE_BITS;
0664 
0665             if (IS_TYPE_INVALID(type))
0666             {
0667                 ndrx_Bset_error_fmt(BALIGNERR, "%s: Unknown data type found in "
0668                                         "buffer: %d", fn, type);
0669                 EXFAIL_OUT(ret);
0670             }
0671 
0672             /* Check type alignity */
0673             dtype = &G_dtype_str_map[type];
0674             p = (char *)p_bfldid_src;
0675             /* Get the step */
0676             step = dtype->p_next(dtype, p, NULL);
0677 
0678             /* Move us forward. */
0679             p+=step;
0680             /* Align error */
0681             if (CHECK_ALIGN(p, p_ub_src, hdr_src))
0682             {
0683                 ndrx_Bset_error_fmt(BALIGNERR, "%s: Pointing to non UBF area: %p",
0684                                             fn, p);
0685                 EXFAIL_OUT(ret);
0686             }
0687             p_bfldid_src = (BFLDID *)p;
0688 
0689         }
0690 
0691         /* If last field was Bad field, then still we need to delete the stuff out! */
0692         /* fix for un-init memory usage... */
0693         if (NULL!=cpy_bfldid_start && (UBF_EOF(hdr_src, p_bfldid_src) || *cpy_bfldid_start != *p_bfldid_src))
0694         {
0695 
0696             ret=copy_buffer_data(p_ub_dst,
0697                             (char *)cpy_bfldid_start,
0698                             (char *)p_bfldid_src, &p_bfldid_dst);
0699             /* Mark that we have all done! */
0700             cpy_bfldid_start=NULL; /* Mark that we have finished with this. */
0701             
0702             if (EXSUCCEED!=ret)
0703             {
0704                 EXFAIL_OUT(ret);
0705             }
0706         }
0707     } /* Else  of use of Binit */
0708 
0709     if (EXSUCCEED!=ubf_cache_update(p_ub_dst))
0710     {
0711         ndrx_Bset_error_fmt(BALIGNERR, "%s: Failed to update cache!");
0712         EXFAIL_OUT(ret);
0713     }
0714 
0715 out:
0716 /***************************************** DEBUG *******************************/
0717 #ifdef UBF_API_DEBUG
0718     __dbg_olduse = __p_ub_copy->bytes_used;
0719     __dbg_newuse = hdr_dst->bytes_used;
0720 
0721     /* Do bellow to print out end element (last) of the array - should be bbadfldid */
0722     __dbg_p_org = (char *)__p_ub_copy;
0723     __dbg_p_org+= (__p_ub_copy->bytes_used - FF_USED_BYTES);
0724 
0725     __dbg_p_new = (char *)hdr_dst;
0726     __dbg_p_new+= (hdr_dst->bytes_used - FF_USED_BYTES);
0727 
0728     __dbg_fldptr_org = (int *)__dbg_p_org;
0729     __dbg_fldptr_new = (int *)__dbg_p_new;
0730 
0731     UBF_LOG(log_debug, "%s: dst returns=%d\norg_used=%d new_used=%d diff=%d "
0732                                 "org_start=%d/%p new_start=%d/%p\n"
0733                                 "old_finish=%d/%p, new_finish=%d/%p",
0734                                 fn,
0735                                 ret,
0736                                 __dbg_olduse,
0737                                 __dbg_newuse,
0738                                 (__dbg_olduse - __dbg_newuse),
0739                                 __p_ub_copy->bfldid, __p_ub_copy->bfldid,
0740                                 hdr_dst->bfldid, hdr_dst->bfldid,
0741                                 *__dbg_fldptr_org, *__dbg_fldptr_org,
0742                                 *__dbg_fldptr_new, *__dbg_fldptr_new);
0743     /* Check the last four bytes before the end */
0744     __dbg_p_org-= FF_USED_BYTES;
0745     __dbg_p_new-= FF_USED_BYTES;
0746     __dbg_fldptr_org = (int *)__dbg_p_org;
0747     __dbg_fldptr_new = (int *)__dbg_p_new;
0748     UBF_LOG(log_debug, "%s: last %d bytes of dst data\n org=%p new %p",
0749                           fn, FF_USED_BYTES, *__dbg_fldptr_org, *__dbg_fldptr_new);
0750     UBF_DUMP_DIFF(log_always, "After _Bproj", __p_ub_copy, p_ub_dst, hdr_dst->buf_len);
0751     UBF_DUMP(log_always, "Used buffer dump after _Bprojcpy: ",p_ub_dst,
0752                                                         hdr_dst->bytes_used);
0753     NDRX_FREE(__p_ub_copy);
0754 #endif
0755 /*******************************************************************************/
0756 
0757     return ret;
0758 }
0759 
0760 /* vim: set ts=4 sw=4 et smartindent: */