Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Dynamic VIEW access functions
0003  *
0004  * @file view_access.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 <limits.h>
0041 
0042 #include <ndrstandard.h>
0043 #include <ubfview.h>
0044 #include <ndebug.h>
0045 
0046 #include <userlog.h>
0047 #include <view_cmn.h>
0048 #include <atmi_tls.h>
0049 #include <cf.h>
0050 #include "Exfields.h"
0051 /*---------------------------Externs------------------------------------*/
0052 /*---------------------------Macros-------------------------------------*/
0053 /*---------------------------Enums--------------------------------------*/
0054 /*---------------------------Typedefs-----------------------------------*/
0055 /*---------------------------Globals------------------------------------*/
0056 /*---------------------------Statics------------------------------------*/
0057 /*---------------------------Prototypes---------------------------------*/
0058 
0059 /**
0060  * Find field occurrence and field length
0061  * @param cstruct c structure onto which operate
0062  * @param v resolved view
0063  * @param f resolved field
0064  * @param occ occurrence to seek
0065  * @param p_len data len
0066  * @return ptr to value or NULL on error (Berror loaded)
0067  */
0068 expublic char * ndrx_Bvfind_int(char *cstruct, ndrx_typedview_t *v,
0069     ndrx_typedview_field_t *f, BFLDOCC occ, BFLDLEN *p_len)
0070 {
0071     int ret = EXSUCCEED;
0072     int dim_size = f->fldsize/f->count;
0073     char *fld_offs = cstruct+f->offset+occ*dim_size;
0074     char *cvn_buf;
0075     short *C_count;
0076     short C_count_stor;
0077     unsigned short *L_length;
0078     unsigned short L_length_stor;
0079 
0080     UBF_LOG(log_debug, "%s enter, get %s.%s occ=%d", __func__,
0081             v->vname, f->cname, occ);
0082     
0083     if (occ > f->count-1 || occ<0)
0084     {
0085         ndrx_Bset_error_fmt(BEINVAL, "Invalid occurrence requested for field "
0086                 "%s.%s, count=%d occ=%d (zero base)",
0087                 v->vname, f->cname, f->count, occ);
0088         fld_offs=NULL;
0089         goto out;
0090     }
0091     
0092     NDRX_VIEW_COUNT_SETUP;
0093     
0094     /* Will request type convert now */
0095     NDRX_VIEW_LEN_SETUP(occ, dim_size);
0096     
0097     *p_len = (BFLDLEN)*L_length;
0098 out:
0099     return fld_offs;
0100 }
0101 
0102 /**
0103  * Return the VIEW field according to user type
0104  * In case of NULL value, we do not return the given occurrence.
0105  * If the C_count is less than given occurrence and BVACCESS_NOTNULL is set, then
0106  * field not found will be returned.
0107  * 
0108  * @param cstruct instance of the view object
0109  * @param view view name
0110  * @param cname field name in view
0111  * @param occ array occurrence of the field (if count > 0)
0112  * @param buf user buffer to install data to
0113  * @param len on input user buffer len, on output bytes written to (for carray only)
0114  * on input for string too.
0115  * @param usrtype of buf see BFLD_* types
0116  * @param mode alloc mode do alloc in case if CB_MODE_ALLOC
0117  * @param extralen shall we alloc more?
0118  * @return ptr to data or NULL in case of error
0119  * 
0120  * The following errors possible:
0121  * - BBADVIEW view not found
0122  * - BNOCNAME field not found
0123  * - BNOTPRES field is NULL
0124  * - BEINVAL cstruct/view/cname/buf is NULL
0125  * - BEINVAL - invalid usrtype
0126  * - BEINVAL - invalid occurrence
0127  * - BNOSPACE - no space in buffer (the data is larger than user buf specified)
0128  */
0129 expublic char * ndrx_CBvget_int(char *cstruct, ndrx_typedview_t *v,
0130     ndrx_typedview_field_t *f, BFLDOCC occ, char *buf, BFLDLEN *len, 
0131                  int usrtype, long flags,
0132                              int mode, int *extralen)
0133 {
0134     int ret = EXSUCCEED;
0135     int dim_size = f->fldsize/f->count;
0136     char *fld_offs = cstruct+f->offset+occ*dim_size;
0137     char *cvn_buf;
0138     short *C_count;
0139     short C_count_stor;
0140     unsigned short *L_length;
0141     unsigned short L_length_stor;
0142     char *allocbuf = NULL;
0143     BFLDLEN allocbuflen = 0;
0144 
0145     UBF_LOG(log_debug, "%s enter, get %s.%s occ=%d", __func__,
0146             v->vname, f->cname, occ);
0147 
0148     NDRX_VIEW_COUNT_SETUP;
0149 
0150     if (flags & BVACCESS_NOTNULL)
0151     {
0152         if (ndrx_Bvnull_int(v, f, occ, cstruct))
0153         {
0154             UBF_LOG(log_debug, "Field is NULL");
0155             ndrx_Bset_error_fmt(BNOTPRES, "%s.%s occ=%d is NULL", 
0156                              v->vname, f->cname, occ);
0157             EXFAIL_OUT(ret);
0158         }
0159 
0160         if (*C_count<occ+1)
0161         {
0162             UBF_LOG(log_debug, "%s.%s count field is set to %hu, "
0163                     "but requesting occ=%d (zero based) - NOT PRES",
0164                      v->vname, f->cname, *C_count, occ);
0165             ndrx_Bset_error_fmt(BNOTPRES, "%s.%s count field is set to %hu, "
0166                     "but requesting occ=%d (zero based) - NOT PRES",
0167                      v->vname, f->cname, *C_count, occ);
0168             EXFAIL_OUT(ret);
0169         }
0170     }
0171 
0172     /* Will request type convert now */
0173     NDRX_VIEW_LEN_SETUP(occ, dim_size);
0174     
0175     if (CB_MODE_ALLOC==mode)
0176     {
0177         /* in this case we re-write the output buffer */
0178         if (NULL==(cvn_buf=ndrx_ubf_get_cbuf(f->typecode_full, usrtype,
0179                         NULL, fld_offs, *L_length,
0180                         &allocbuf,
0181                         &allocbuflen,
0182                         mode,
0183                         (NULL!=extralen?*extralen:0))))
0184         {
0185             UBF_LOG(log_error, "%s: get_cbuf failed!", __func__);
0186             /* probably error is already set: */
0187             ndrx_Bset_error_fmt(BMALLOC, "%s: get_cbuf failed!", __func__);
0188             /* Error should be already set */
0189             return NULL; /* <<<< RETURN!!!! */
0190         }
0191         
0192         buf = allocbuf;
0193         len = &allocbuflen;
0194     }
0195 
0196     cvn_buf = ndrx_ubf_convert(f->typecode_full, CNV_DIR_OUT, fld_offs, *L_length,
0197                                 usrtype, buf, len);
0198     if (NULL==cvn_buf)
0199     {
0200         UBF_LOG(log_error, "%s: failed to convert data!", __func__);
0201         /* Error should be provided by conversation function */
0202         EXFAIL_OUT(ret);
0203     }
0204     
0205     if (NULL!=len && NULL!=extralen)
0206     {
0207         *extralen=*len;
0208     }
0209      
0210 out:
0211     UBF_LOG(log_debug, "%s return %d %p", __func__, ret, buf);
0212 
0213     if (EXSUCCEED!=ret)
0214     {
0215         if (NULL!=allocbuf)
0216         {
0217             NDRX_FREE(allocbuf);
0218         }
0219         
0220         return NULL;
0221     }
0222 
0223     return buf;
0224 }
0225 
0226 /**
0227  * Wrapper for function for ndrx_CBvget_int, just to resolve the objects
0228  * @param cstruct c struct 
0229  * @param view view name
0230  * @param cname field name
0231  * @param occ occurrence
0232  * @param buf buffer to where unload data
0233  * @param len data len (optional)
0234  * @param usrtype user type to convert to
0235  * @return EXSUCCEED/EXFAIL
0236  */
0237 expublic int ndrx_CBvget(char *cstruct, char *view, char *cname, BFLDOCC occ, 
0238              char *buf, BFLDLEN *len, int usrtype, long flags)
0239 {
0240     int ret = EXFALSE;
0241     ndrx_typedview_t *v = NULL;
0242     ndrx_typedview_field_t *f = NULL;
0243 
0244     /* resolve view & field, call ndrx_Bvnull_int */
0245 
0246     if (NULL==(v = ndrx_view_get_view(view)))
0247     {
0248         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0249         EXFAIL_OUT(ret);
0250     }
0251 
0252     if (NULL==(f = ndrx_view_get_field(v, cname)))
0253     {
0254         ndrx_Bset_error_fmt(BNOCNAME, "Field [%s] of view [%s] not found!", 
0255                 cname, v->vname);
0256         EXFAIL_OUT(ret);
0257     }
0258 
0259     if (occ > f->count-1 || occ<0)
0260     {
0261         ndrx_Bset_error_fmt(BEINVAL, "Invalid occurrence requested for field "
0262                 "%s.%s, count=%d occ=%d (zero base)",
0263                 v->vname, f->cname, f->count, occ);
0264         EXFAIL_OUT(ret);
0265     }
0266 
0267     if (NULL==ndrx_CBvget_int(cstruct, v, f, occ, buf, len, 
0268                                      usrtype, flags, CB_MODE_DEFAULT, NULL))
0269     {
0270         /* error must be set */
0271         UBF_LOG(log_error, "ndrx_CBvget_int failed");
0272         EXFAIL_OUT(ret);
0273     }
0274     
0275 out:
0276     
0277     return ret;
0278 }
0279 /**
0280  * Wrapper for function for ndrx_CBvget_int, just to resolve the objects
0281  * @param cstruct c struct 
0282  * @param view view name
0283  * @param cname field name
0284  * @param occ occurrence
0285  * @param buf buffer to where unload data
0286  * @param len data len (optional)
0287  * @param usrtype user type to convert to
0288  * @param extralen optional len to allocate
0289  * @return allocated buffer or NULL
0290  */
0291 expublic char *ndrx_CBvgetalloc(char *cstruct, char *view, char *cname, BFLDOCC occ, 
0292             int usrtype, long flags, BFLDLEN *extralen)
0293 {
0294     char *ret = NULL;
0295     ndrx_typedview_t *v = NULL;
0296     ndrx_typedview_field_t *f = NULL;
0297 
0298     /* resolve view & field, call ndrx_Bvnull_int */
0299 
0300     if (NULL==(v = ndrx_view_get_view(view)))
0301     {
0302         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0303         goto out;
0304     }
0305 
0306     if (NULL==(f = ndrx_view_get_field(v, cname)))
0307     {
0308         ndrx_Bset_error_fmt(BNOCNAME, "Field [%s] of view [%s] not found!", 
0309                 cname, v->vname);
0310         goto out;
0311     }
0312 
0313     if (occ > f->count-1 || occ<0)
0314     {
0315         ndrx_Bset_error_fmt(BEINVAL, "Invalid occurrence requested for field "
0316                 "%s.%s, count=%d occ=%d (zero base)",
0317                 v->vname, f->cname, f->count, occ);
0318         goto out;
0319     }
0320 
0321     if (NULL==(ret=ndrx_CBvget_int(cstruct, v, f, occ, NULL, 0, usrtype, 
0322             flags, CB_MODE_ALLOC, extralen)))
0323     {
0324         /* error must be set */
0325         UBF_LOG(log_error, "ndrx_CBvget_int failed");
0326         goto out;
0327     }
0328     
0329 out:
0330     
0331     return ret;
0332 }
0333 
0334 
0335 
0336 /**
0337  * Return the VIEW field according to user type
0338  * If "C" (count flag) was used, and is less than occ+1, then C_<field> is incremented
0339  * to occ+1.
0340  * 
0341  * In case if "L" (length) was present and this is carray buffer, then L flag will
0342  * be set
0343  * 
0344  * @param cstruct instance of the view object
0345  * @param view view name
0346  * @param cname field name in view
0347  * @param occ array occurrence of the field (if count > 0)
0348  * @param buf data to set
0349  * @param len used only for carray, to indicate the length of the data
0350  * @param usrtype of buf see BFLD_* types
0351  * @return 0 on success, or -1 on fail. 
0352  * 
0353  * The following errors possible:
0354  * - BBADVIEW view not found
0355  * - BNOCNAME field not found
0356  * - BNOTPRES field not present (invalid occ)
0357  * - BEINVAL cstruct/view/cname/buf is NULL
0358  * - BEINVAL invalid usrtype
0359  * - BNOSPACE the view field is shorter than data received
0360  */
0361 expublic int ndrx_CBvchg_int(char *cstruct, ndrx_typedview_t *v, 
0362         ndrx_typedview_field_t *f, BFLDOCC occ, char *buf, 
0363                  BFLDLEN len, int usrtype)
0364 {
0365     int ret = EXSUCCEED;
0366     int dim_size = f->fldsize/f->count;
0367     char *fld_offs = cstruct+f->offset+occ*dim_size;
0368     char *cvn_buf;
0369     short *C_count;
0370     short C_count_stor;
0371     unsigned short *L_length;
0372     unsigned short L_length_stor;
0373 
0374     BFLDLEN setlen;
0375     UBF_LOG(log_debug, "%s enter, get %s.%s occ=%d", __func__,
0376             v->vname, f->cname, occ);
0377 
0378     NDRX_VIEW_COUNT_SETUP;
0379 
0380     /* Length output buffer */
0381     NDRX_VIEW_LEN_SETUP(occ, dim_size);
0382 
0383     setlen = dim_size;
0384 
0385     cvn_buf = ndrx_ubf_convert(usrtype, CNV_DIR_OUT, buf, len,
0386                                 f->typecode_full, fld_offs, &setlen);
0387 
0388     if (NULL==cvn_buf)
0389     {
0390         UBF_LOG(log_error, "%s: failed to convert data!", __func__);
0391         /* Error should be provided by conversation function */
0392         EXFAIL_OUT(ret);
0393     }
0394 
0395     if (occ+1 > *C_count)
0396     {
0397         *C_count = occ+1;
0398     }
0399 
0400     *L_length = setlen;
0401     
0402 out:    
0403     UBF_LOG(log_debug, "%s return %d", __func__, ret);
0404 
0405     return ret;
0406 }
0407 
0408 /**
0409  * Set the field wrapper for internal method above.
0410  * @param cstruct
0411  * @param view
0412  * @param cname
0413  * @param occ
0414  * @param buf
0415  * @param len
0416  * @param usrtype
0417  * @return 
0418  */
0419 expublic int ndrx_CBvchg(char *cstruct, char *view, char *cname, BFLDOCC occ, 
0420              char *buf, BFLDLEN len, int usrtype)
0421 {
0422     int ret = EXFALSE;
0423     ndrx_typedview_t *v = NULL;
0424     ndrx_typedview_field_t *f = NULL;
0425 
0426     /* resolve view & field, call ndrx_Bvnull_int */
0427 
0428     if (NULL==(v = ndrx_view_get_view(view)))
0429     {
0430         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0431         EXFAIL_OUT(ret);
0432     }
0433 
0434     if (NULL==(f = ndrx_view_get_field(v, cname)))
0435     {
0436         ndrx_Bset_error_fmt(BNOCNAME, "Field [%s] of view [%s] not found!", 
0437                 cname, v->vname);
0438         EXFAIL_OUT(ret);
0439     }
0440 
0441     if (occ > f->count-1 || occ<0)
0442     {
0443         ndrx_Bset_error_fmt(BEINVAL, "Invalid occurrence requested for field "
0444                 "%s.%s, count=%d occ=%d (zero base)",
0445                 v->vname, f->cname, f->count, occ);
0446         EXFAIL_OUT(ret);
0447     }
0448 
0449     if (EXFAIL==(ret=ndrx_CBvchg_int(cstruct, v, f, occ, buf, len, usrtype)))
0450     {
0451         /* error must be set */
0452        UBF_LOG(log_error, "ndrx_CBvchg_int failed");
0453         EXFAIL_OUT(ret);
0454     }
0455     
0456 out:
0457     return ret;
0458 }
0459 
0460 /**
0461  * Return size of the given view in bytes
0462  * @param view view name
0463  * @return >=0 on success, -1 on FAIL.
0464  * Errors:
0465  * BBADVIEW view not found
0466  * BEINVAL view field is NULL
0467  */
0468 expublic long ndrx_Bvsizeof(char *view)
0469 {
0470     long ret;
0471 
0472     ndrx_typedview_t *v = NULL;
0473 
0474     if (NULL==(v = ndrx_view_get_view(view)))
0475     {
0476         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0477         EXFAIL_OUT(ret);
0478     }
0479 
0480     ret = v->ssize;
0481     
0482 out:
0483     return ret;
0484 }
0485 
0486 /**
0487  * Copy view data from one view to another. Views must be the same
0488  * and the buffer size on both sides must be at least in size view
0489  * @param cstruct_dst destination buffer
0490  * @param cstruct_src source buffer
0491  * @param view view name (must be common between two views)
0492  * @return bytes copied or -1 on failure
0493  */
0494 expublic long ndrx_Bvcpy(char *cstruct_dst, char *cstruct_src, char *view)
0495 {
0496     long ret;
0497 
0498     ndrx_typedview_t *v = NULL;
0499 
0500     if (NULL==(v = ndrx_view_get_view(view)))
0501     {
0502         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0503         EXFAIL_OUT(ret);
0504     }
0505 
0506     ret = v->ssize;
0507     
0508     memcpy(cstruct_dst, cstruct_src, ret);
0509     
0510 out:
0511     return ret;
0512 }
0513 
0514 /**
0515  * Return the occurrences set in buffer. This will either return C_ count field
0516  * set, or will return max array size, this does not test field against NULL or not.
0517  * anything, 
0518  * @param cstruct instance of the view object
0519  * @param view view name
0520  * @param cname field name in view
0521  * @param maxocc number of occurrences for view filed
0522  * @param realoccs by using set the count set in variable, it tests the array
0523  * until the end. And it detects the last array element which is not NULL and 
0524  * from start till last used (even in the middle there is NULL) is assumed as
0525  * it is real occs. (optional), set if not NULL
0526  * @param fldtype field type code
0527  * @return occurrences (1 based)
0528  *  The following errors possible:
0529  * - BBADVIEW view not found
0530  * - BNOCNAME field not found
0531  * - BEINVAL cstruct/view/cname/buf is NULL
0532  * 
0533  */
0534 expublic BFLDOCC ndrx_Bvoccur_int(char *cstruct, ndrx_typedview_t *v, 
0535         ndrx_typedview_field_t *f, BFLDOCC *maxocc, BFLDOCC *realocc, 
0536                 long *dim_size, int *fldtype)
0537 {
0538     BFLDOCC ret;
0539     short *C_count;
0540     short C_count_stor;
0541     int i;
0542         
0543     NDRX_VIEW_COUNT_SETUP;
0544 
0545     if (NULL!=maxocc)
0546     {
0547         *maxocc=f->count;
0548     }
0549 
0550     ret = *C_count;
0551     
0552     if (NULL!=realocc)
0553     {
0554         /* scan from the end until we reach first non NULL */
0555         for (i=ret-1; i>=0; i--)
0556         {
0557             if (!ndrx_Bvnull_int(v, f, i, cstruct))
0558             {
0559                 break;
0560             }
0561         }
0562         *realocc = i+1;
0563     }
0564     
0565     
0566     if (NULL!=dim_size)
0567     {
0568         *dim_size = f->fldsize/f->count;
0569     }
0570     
0571     if (NULL!=fldtype)
0572     {
0573         *fldtype = f->typecode_full;
0574     }
0575     
0576 out:
0577     UBF_LOG(log_debug, "%s returns %d maxocc=%d dim_size=%d realocc=%d", __func__, 
0578          ret, maxocc?*maxocc:-1, dim_size?*dim_size:-1, realocc?*realocc:-1);
0579     return ret;
0580 }
0581 
0582 /**
0583  * Wrapper for ndrx_Bvoccur_int
0584  * @param cstruct
0585  * @param view
0586  * @param cname
0587  * @param maxocc
0588  * @param realocc
0589  * @param dimsz
0590  * @return 
0591  */
0592 expublic BFLDOCC ndrx_Bvoccur(char *cstruct, char *view, char *cname, 
0593         BFLDOCC *maxocc, BFLDOCC *realocc, long *dim_size, int *fldtype)
0594 {
0595     BFLDOCC ret = EXSUCCEED;
0596     ndrx_typedview_t *v = NULL;
0597     ndrx_typedview_field_t *f = NULL;
0598 
0599     if (NULL==(v = ndrx_view_get_view(view)))
0600     {
0601         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0602         EXFAIL_OUT(ret);
0603     }
0604 
0605     if (NULL==(f = ndrx_view_get_field(v, cname)))
0606     {
0607         ndrx_Bset_error_fmt(BNOCNAME, "Field [%s] of view [%s] not found!", 
0608                 cname, v->vname);
0609         EXFAIL_OUT(ret);
0610     }
0611     
0612     if (EXFAIL==(ret = ndrx_Bvoccur_int(cstruct, v, f, maxocc, realocc, 
0613             dim_size, fldtype)))
0614     {
0615         UBF_LOG(log_error, "ndrx_Bvoccur_int failed");
0616     }
0617     
0618 out:
0619     return ret;    
0620 }
0621 
0622 /**
0623  * Set C_ occurrence indicator field, if "C" flag was set
0624  * If flag is not present, function succeeds and does not return error, but
0625  * data also is not changed.
0626  * @param cstruct instance of the view object
0627  * @param view view name
0628  * @param cname field name in view
0629  * @param occ occurrences (non zero based)
0630  * @return 0 on success or -1 on failure
0631  *  The following errors possible:
0632  * - BBADVIEW view not found
0633  * - BNOCNAME field not found
0634  * - BEINVAL cstruct/view/cname/buf is NULL
0635  * - BNOTPRES occ out of bounds
0636  */
0637 expublic int ndrx_Bvsetoccur(char *cstruct, char *view, char *cname, BFLDOCC occ)
0638 {   
0639     int ret = EXSUCCEED;
0640     ndrx_typedview_t *v = NULL;
0641     ndrx_typedview_field_t *f = NULL;
0642     short *C_count;
0643     short C_count_stor;
0644 
0645     if (NULL==(v = ndrx_view_get_view(view)))
0646     {
0647         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0648         EXFAIL_OUT(ret);
0649     }
0650 
0651     if (NULL==(f = ndrx_view_get_field(v, cname)))
0652     {
0653         ndrx_Bset_error_fmt(BNOCNAME, "Field [%s] of view [%s] not found!", 
0654                 cname, v->vname);
0655         EXFAIL_OUT(ret);
0656     }
0657 
0658     if (occ>f->count || occ<0)
0659     {
0660         ndrx_Bset_error_fmt(BEINVAL, "%s: invalid occ %d max: %d, min: 0",
0661                          __func__, occ, occ>f->count);
0662         EXFAIL_OUT(ret);
0663     }
0664 
0665     NDRX_VIEW_COUNT_SETUP;
0666 
0667     *C_count = occ;
0668     
0669 out:
0670     return ret;
0671 }
0672 
0673 /**
0674  * Iterate over the structure, this will only return list of fields used for
0675  * by structure.
0676  * @param state Save state for scanning. Save is initialized when view is not NULL
0677  * @param cstruct instance of the view object
0678  * @param view view name if not NULL, then start scan
0679  * @param cname output cname field, must be NDRX_VIEW_CNAME_LEN + 1 in size.
0680  * @param fldtype return the type of the field
0681  * @return On success 1 is returned, on EOF 0, on failure -1
0682  */
0683 expublic int ndrx_Bvnext (Bvnext_state_t *state, char *view, char *cname, 
0684               int *fldtype, BFLDOCC *maxocc, long *dim_size)
0685 {
0686     int ret = EXSUCCEED;
0687     ndrx_typedview_t *v;
0688     ndrx_typedview_field_t *f;
0689     
0690     v = (ndrx_typedview_t *) state->v;
0691     f = (ndrx_typedview_field_t *) state->vel;
0692     
0693     /* find first */
0694     if (NULL!=view)
0695     {
0696         UBF_LOG(log_debug, "Starting to scan view: %s", view);
0697         memset(state, 0, sizeof(Bvnext_state_t));
0698 
0699         /* Resolve the view */
0700         if (NULL==(v = ndrx_view_get_view(view)))
0701         {
0702             ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
0703             EXFAIL_OUT(ret);
0704         }
0705 
0706         f = v->fields;
0707         
0708         if (NULL==f)
0709         {
0710             UBF_LOG(log_debug, "View scan EOF");
0711             ret = 0;
0712             goto out;
0713         }
0714 
0715     }
0716     else
0717     {
0718         /* find next */
0719         f = f->next;
0720         
0721         if (NULL==f)
0722         {
0723             UBF_LOG(log_debug, "View scan EOF");
0724             ret = 0;
0725             goto out;
0726         }
0727 
0728     }
0729     
0730     NDRX_STRCPY_SAFE_DST(cname, f->cname, (NDRX_VIEW_CNAME_LEN+1));
0731     
0732     if (NULL!=fldtype)
0733     {
0734         *fldtype = f->typecode_full;
0735     }
0736     
0737     ret = 1;
0738     
0739     if (NULL!=dim_size)
0740     {
0741         *dim_size = f->fldsize/f->count;
0742     }
0743     
0744     if (NULL!=maxocc)
0745     {
0746         *maxocc = f->count;
0747     }
0748     
0749 out:
0750     /* fill up the state: */
0751 
0752     state->v = v;
0753     state->vel = f;
0754     
0755     if (ret > 0)
0756     {
0757         UBF_LOG(log_debug, "%s returns %d (%s.%s %d)", __func__, 
0758                 ret, v->vname, cname, fldtype?*fldtype:-1);
0759     }
0760     else
0761     {
0762         UBF_LOG(log_debug, "%s returns %d",  __func__, ret);
0763     }
0764     
0765     return ret;
0766 }
0767 
0768 /* vim: set ts=4 sw=4 et smartindent: */