1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF.  The full HDF copyright notice, including       *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF/releases/.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /* $Id$ */
15 
16 /*****************************************************************************
17  file - vio.c
18 
19  Part of the HDF Vset interface.
20 
21  VDATAs are handled by routines in here.
22  PRIVATE functions manipulate vsdir and are used only within this file.
23  PRIVATE data structures in here pertain to vdatas in vsdir only.
24 
25 
26 LOCAL ROUTINES
27  VSIget_vdata_node      -- allocate a new VDATA record
28  VSIrelease_vdata_node  -- Releases a vdata node
29  VSIget_vsinstance_node -- allocate a new vsinstance_t record
30  VSIrelease_vsinstance_node -- Releases a vsinstance node
31 
32 LIBRARY PRIVATE ROUTINES
33  VSPhshutdown  --  shutdown the Vset interface
34 
35 EXPORTED ROUTINES
36  vinst         -- Looks thru vstab for vsid and return the addr of the vdata
37                    instance where vsid is found.
38  vexistvs      -- Tests if a vdata with id vsid is in the file's vstab.
39  vpackvs       -- Packs a VDATA structure into a compact form suitable for
40                    storing in the HDF file.
41  vunpackvs     -- Convert a packed form(from HDF file) to a VDATA structure.
42                    This routine will also initalize the VDATA structure as
43                    much as it can.
44  vsdestroynode -- Frees B-Tree nodes.
45  VSPgetinfo    -- Read in the "header" information about the Vdata.
46  VSattach      -- Attaches/Creates a new vs in vg depending on "vsid" value.
47  VSdetach      -- Detaches vs from vstab.
48  VSappendable  -- Make it possible to append unlimitedly to an existing VData.
49  VSgetid       -- Returns the id of the next VDATA from the file.
50  VSQuerytag    -- Return the 'otag' of the given Vdata.
51  VSQueryref    -- Return the ref of the given Vdata.
52  vswritelist   -- Return the writelist of a Vdata.
53  VSgetversion  -- Return the version number of a Vdata.
54  VSdelete      -- Remove a Vdata from its file.  This function will both
55                    remove the Vdata from the internal Vset data structures
56                    as well as from the file.
57 
58  NOTE: Another pass needs to made through this file to update some of
59        the comments about certain sections of the code. -GV 9/8/97
60 
61 *************************************************************************/
62 
63 #define VSET_INTERFACE
64 #include "hdf.h"
65 
66 /* Private Function Prototypes */
67 PRIVATE intn vunpackvs
68             (VDATA * vs, uint8 buf[], int32 len);
69 
70 /* Temporary buffer for I/O */
71 PRIVATE uint32 Vhbufsize = 0;
72 PRIVATE uint8 *Vhbuf = NULL;
73 
74 /* Pointers to the VDATA & vsinstance node free lists */
75 static VDATA *vdata_free_list=NULL;
76 static vsinstance_t *vsinstance_free_list=NULL;
77 
78 /* vpackvs is prototyped in vg.h since vconv.c needs to call it */
79 
80 /*******************************************************************************
81  NAME
82     VSIget_vdata_node -- allocate a new VDATA record
83 
84  DESCRIPTION
85     Return an pointer to a new VDATA to use for a new VSID.
86 
87  RETURNS
88     returns VDATA record pointer or NULL if failed.
89 
90 *******************************************************************************/
91 VDATA *
VSIget_vdata_node(void)92 VSIget_vdata_node(void)
93 {
94     VDATA   *ret_value = NULL;
95     CONSTR(FUNC, "VSIget_vdata_node");
96 
97     /* clear error stack */
98     HEclear();
99 
100     /* Grab from free list if possible */
101     if(vdata_free_list != NULL)
102       {
103         ret_value       = vdata_free_list;
104         vdata_free_list = vdata_free_list->next;
105       }
106     else /* allocate a new node */
107       {
108         if((ret_value=(VDATA *)HDmalloc(sizeof(VDATA)))==NULL)
109             HGOTO_ERROR(DFE_NOSPACE, NULL);
110       } /* end else */
111 
112     /* Initialize to zeros */
113     HDmemset(ret_value,0,sizeof(VDATA));
114 
115 done:
116   if(ret_value == NULL)
117     { /* Error condition cleanup */
118 
119     } /* end if */
120 
121   /* Normal function cleanup */
122 
123   return(ret_value);
124 }	/* VSIget_vdata_node */
125 
126 /******************************************************************************
127  NAME
128      VSIrelease_vdata_node -- Releases a vdata node
129 
130  DESCRIPTION
131     Puts an VDATA node into the free list
132 
133  RETURNS
134     No return value
135 
136 *******************************************************************************/
137 void
VSIrelease_vdata_node(VDATA * vs)138 VSIrelease_vdata_node(VDATA *vs /* IN: vdata to release */)
139 {
140 #ifdef LATER
141     CONSTR(FUNC, "VSIrelease_vdata_node");	/* for HERROR */
142 #endif /* LATER */
143 
144     /* Insert the atom at the beginning of the free list */
145     vs->next        = vdata_free_list;
146     vdata_free_list = vs;
147 
148 }   /* end VSIrelease_vdata_node() */
149 
150 /*******************************************************************************
151  NAME
152     VSIget_vsinstance_node -- allocate a new vsinstance_t record
153 
154  DESCRIPTION
155     Return an pointer to a new VDATA to use for a new VSID.
156 
157  RETURNS
158     returns vsinstance_t pointer or NULL if failed.
159 *******************************************************************************/
160 vsinstance_t *
VSIget_vsinstance_node(void)161 VSIget_vsinstance_node(void)
162 {
163     vsinstance_t   *ret_value = NULL;
164     CONSTR(FUNC, "VSIget_vsinstance_node");
165 
166     /* clear error stack */
167     HEclear();
168 
169     /* Grab from free list if possible */
170     if(vsinstance_free_list != NULL)
171       {
172         ret_value            = vsinstance_free_list;
173         vsinstance_free_list = vsinstance_free_list->next;
174       }
175     else /* allocate a new vsinstance record */
176       {
177         if((ret_value=(vsinstance_t *)HDmalloc(sizeof(vsinstance_t)))==NULL)
178             HGOTO_ERROR(DFE_NOSPACE, NULL);
179       } /* end else */
180 
181     /* Initialize to zeros */
182     HDmemset(ret_value,0,sizeof(vsinstance_t));
183 
184 done:
185   if(ret_value == NULL)
186     { /* Error condition cleanup */
187 
188     } /* end if */
189 
190   /* Normal function cleanup */
191 
192   return(ret_value);
193 }	/* VSIget_vsinstance_node */
194 
195 /******************************************************************************
196  NAME
197      VSIrelease_vsinstance_node -- Releases a vsinstance node
198 
199  DESCRIPTION
200     Puts a vsinstance node into the free list
201 
202  RETURNS
203     No return value
204 
205 *******************************************************************************/
206 void
VSIrelease_vsinstance_node(vsinstance_t * vs)207 VSIrelease_vsinstance_node(vsinstance_t *vs /* IN: vinstance node to release */)
208 {
209 #ifdef LATER
210     CONSTR(FUNC, "VSIrelease_vsinstance_node");	/* for HERROR */
211 #endif /* LATER */
212 
213     /* Insert the atom at the beginning of the free list */
214     vs->next             = vsinstance_free_list;
215     vsinstance_free_list = vs;
216 
217 }   /* end VSIrelease_vsinstance_node() */
218 
219 /*******************************************************************************
220  NAME
221     VSPhshutdown  -  shutdown the Vset interface
222 
223  DESCRIPTION
224     For completeness, when the VSet interface is shut-down, free the Vhbuf.
225 
226  RETURNS
227     Returns SUCCEED/FAIL
228 
229  COMMENTS, BUGS, ASSUMPTIONS
230     Should only ever be called by the "atexit" function HDFend
231 *******************************************************************************/
232 intn
VSPhshutdown(void)233 VSPhshutdown(void)
234 {
235     intn  ret_value = SUCCEED;
236     VDATA *v = NULL;
237     vsinstance_t *vs = NULL;
238 
239     /* Release the vdata free-list if it exists */
240     if(vdata_free_list != NULL)
241       {
242         while(vdata_free_list != NULL)
243           {
244             v               = vdata_free_list;
245             vdata_free_list = vdata_free_list->next;
246             v->next = NULL;
247             HDfree(v);
248           } /* end while */
249       } /* end if */
250 
251     /* Release the vsinstance free-list if it exists */
252     if(vsinstance_free_list != NULL)
253       {
254         while(vsinstance_free_list != NULL)
255           {
256             vs                   = vsinstance_free_list;
257             vsinstance_free_list = vsinstance_free_list->next;
258             vs->next = NULL;
259             HDfree(vs);
260           } /* end while */
261       } /* end if */
262 
263     /* free buffer */
264     if(Vhbuf != NULL)
265       {
266           HDfree(Vhbuf);
267           Vhbuf = NULL;
268           Vhbufsize = 0;
269       } /* end if */
270 
271     /* free the parsing buffer */
272     ret_value = VPparse_shutdown();
273 
274   return ret_value;
275 } /* end VSPhshutdown() */
276 
277 /*******************************************************************************
278 NAME
279   vsint
280 
281 DESCRIPTION
282   Looks thru vstab for vsid and return the addr of the vdata instance
283   where vsid is found.
284 
285 RETURNS
286   RETURNS NULL if error or not found.
287   RETURNS vsinstance_t pointer if ok.
288 
289 *******************************************************************************/
290 vsinstance_t *
vsinst(HFILEID f,uint16 vsid)291 vsinst(HFILEID f,  /* IN: File handle */
292        uint16 vsid /* IN: vdata id i.e. ref */)
293 {
294     void *      *t = NULL;
295     vfile_t    *vf = NULL;
296     int32       key;
297     vsinstance_t *ret_value = NULL; /* FAIL */
298     CONSTR(FUNC, "vsinstance");
299 
300     /* clear error stack */
301     HEclear();
302 
303     /* Get Vdata file record? */
304     if (NULL == (vf = Get_vfile(f)))
305         HGOTO_ERROR(DFE_FNF, NULL);
306 
307     /* tbbtdfind returns a pointer to the vsinstance_t pointer */
308     key = (int32)vsid;
309     if (( t = (void * *) tbbtdfind(vf->vstree, &key, NULL))== NULL)
310         HGOTO_ERROR(DFE_NOMATCH,NULL);
311 
312     /* return the actual vsinstance_t ptr */
313     ret_value = ((vsinstance_t *) * t);
314 
315 done:
316   if(ret_value == NULL)
317     { /* Error condition cleanup */
318 
319     } /* end if */
320 
321   /* Normal function cleanup */
322 
323   return ret_value;
324 }   /* vsinst */
325 
326 /*******************************************************************************
327 NAME
328   vexistvs
329 
330 DESCRIPTION
331   Tests if a vdata with id vsid is in the file's vstab.
332 
333 RETURNS
334   returns FAIL if not found,
335   returns TRUE if found.
336 *******************************************************************************/
337 int32
vexistvs(HFILEID f,uint16 vsid)338 vexistvs(HFILEID f,  /* IN: file handle */
339          uint16 vsid /* IN: vdata id i.e. ref */)
340 {
341   return ((NULL==vsinst(f, vsid)) ? FAIL : TRUE);
342 }   /* vexistvs */
343 
344 /* ------------------------------------------------------------------ */
345 /*
346    The following 2 routines, vpackvs and vunpackvs, packs and unpacks
347    a VDATA structure into a compact form suitable for storing in the HDF file.
348  */
349 
350 /****
351 CONTENTS of VS stored in HDF file with tag VSDESCTAG:
352     int16       interlace
353     int32       nvertices
354     uint16       vsize
355     int16       nfields
356 
357     uint16       isize[1..nfields] (internal size of each field)
358     uint16       off[1..nfields] (internal offset of each field)
359     char        fname[1..nfields][FIELDNAMELENMAX]
360     char        vsname[VSNAMELENMAX]
361     char        vsclass[VSNAMELENMAX]
362     uint16      extag, exref
363     uint32      flags (for vset version 4 or higher )
364     int32       nattrs (if bit0 of flags is set)
365     uint16      atags[1..nattrs], arefs[1..nattrs]
366     int16       version, more
367 ****/
368 
369 /* ------------------------------- vpackvs ----------------------------------- */
370 /*
371    The following 2 PRIVATE routines, vpackvs and vunpackvs, packs and unpacks
372    a VDATA structure into a compact form suitable for storing in the HDF file.
373  */
374 
375 /****
376 CONTENTS of VS stored in HDF file with tag DFTAG_VH:
377     int16       interlace
378     int32       nvertices
379     uint16      vsize
380     int16       nfields
381 
382     uint16      isize[1..nfields] (internal size of each field)
383     uint16      off[1..nfields] (internal offset of each field)
384     char        fname[1..nfields][FIELDNAMELENMAX]
385     char        vsname[VSNAMELENMAX]
386     char        vsclass[VSNAMELENMAX]
387 
388 ****/
389 
390 /*******************************************************************************
391 NAME
392   vpackvs
393 
394 DESCRIPTION
395    convert a vs struct to a vspack suitable for storage in a HDF file
396 
397 RETURNS
398    always SUCCEED?
399 
400 *******************************************************************************/
401 intn
vpackvs(VDATA * vs,uint8 buf[],int32 * size)402 vpackvs(VDATA * vs,  /* IN/OUT: */
403         uint8 buf[], /* IN: */
404         int32 *size  /* OUT: */)
405 {
406 #ifdef LATER
407     CONSTR(FUNC, "vpackvg");
408 #endif /* LATER */
409 
410     int32 i;
411     int16 slen;
412     uint8 *bb = NULL;
413     intn  ret_value = SUCCEED;
414 
415     /* clear error stack */
416     HEclear();
417 
418     bb = &buf[0];
419 
420     /* save the interlace */
421     INT16ENCODE(bb, vs->interlace);
422 
423     /* save nvertices */
424     INT32ENCODE(bb, vs->nvertices);
425 
426     /* save ivsize */
427     UINT16ENCODE(bb, vs->wlist.ivsize);
428 
429     /* save nfields */
430     INT16ENCODE(bb, vs->wlist.n);
431 
432     /* Skip over all the "wheel-spinning" for 0-field vdatas */
433     if(vs->wlist.n>0)
434       {
435         for (i = 0; i < vs->wlist.n; i++)   /* save the type */
436             INT16ENCODE(bb, vs->wlist.type[i]);
437 
438         /* save the isize */
439         for (i = 0; i < vs->wlist.n; i++)
440             UINT16ENCODE(bb, vs->wlist.isize[i]);
441 
442         for (i = 0; i < vs->wlist.n; i++)   /* save the offset */
443             UINT16ENCODE(bb, vs->wlist.off[i]);
444 
445         for (i = 0; i < vs->wlist.n; i++)   /* save the order */
446             UINT16ENCODE(bb, vs->wlist.order[i]);
447 
448         /* save each field length and name - omit the null */
449         for (i = 0; i < vs->wlist.n; i++)
450           {
451               slen = HDstrlen(vs->wlist.name[i]);
452               INT16ENCODE(bb, slen);
453 
454               HDstrcpy((char *) bb, vs->wlist.name[i]);
455               bb += slen;
456           }
457       } /* end if */
458 
459     /* save the vsnamelen and vsname - omit the null */
460     slen = HDstrlen(vs->vsname);
461     INT16ENCODE(bb, slen);
462 
463     HDstrcpy((char *) bb, vs->vsname);
464     bb += slen;
465 
466     /* save the vsclasslen and vsclass- omit the null */
467     slen = HDstrlen(vs->vsclass);
468     INT16ENCODE(bb, slen);
469 
470     HDstrcpy((char *) bb, vs->vsclass);
471     bb += slen;
472 
473     /* save the expansion tag/ref pair */
474     UINT16ENCODE(bb, vs->extag);
475     UINT16ENCODE(bb, vs->exref);
476 
477     /* save the version field - to version_3 now if no new feature */
478     INT16ENCODE(bb, vs->version);
479 
480     /* save the 'more' field - NONE now */
481     INT16ENCODE(bb, vs->more);
482 
483     if (vs->flags != 0)
484       {  /* save the flags and update version # */
485        UINT32ENCODE(bb, vs->flags);
486 
487        if (vs->flags & VS_ATTR_SET)
488          { /* save attributes */
489           INT32ENCODE(bb, vs->nattrs);
490 
491           for (i = 0; i < vs->nattrs; i++)
492             {
493               INT32ENCODE(bb, vs->alist[i].findex);
494               UINT16ENCODE(bb, vs->alist[i].atag);
495               UINT16ENCODE(bb, vs->alist[i].aref);
496             }   /* for */
497          }  /* attr set */
498       }     /* flags set */
499 
500    /* duplicate 'version' and 'more' - for new version of libraries */
501    /* see the documentation in vattr.c */
502     INT16ENCODE(bb, vs->version);
503 
504     /* save the 'more' field - NONE now */
505     INT16ENCODE(bb, vs->more);
506 
507     *size = (int32) (bb - buf) + 1;
508     *bb = 0;
509 
510 #ifdef LATER
511 done:
512     if (ret_value == FAIL)
513     { /* Error condition cleanup */
514 
515     } /* end if */
516 #endif /* LATER */
517 
518   /* Normal function cleanup */
519   return ret_value;
520 }   /* vpackvs */
521 
522 /*******************************************************************************
523 NAME
524   vunpackvs
525 
526 DESCRIPTION
527    Convert a packed form(from HDF file)  to a VDATA structure.
528    This routine will also initalize the VDATA structure as much as it can.
529 
530 RETURNS
531    SUCCEED / FAIL
532 
533 *******************************************************************************/
534 PRIVATE     intn
vunpackvs(VDATA * vs,uint8 buf[],int32 len)535 vunpackvs(VDATA * vs, /* IN/OUT: */
536           uint8 buf[],/* IN: */
537           int32 len   /* IN: */)
538 {
539     uint8      *bb = NULL;
540     int32       i;
541     int16       int16var, temp;
542     uint16      uint16var;
543     int32       ret_value = SUCCEED;
544     CONSTR(FUNC, "vunpackvs");
545 
546     /* clear error stack */
547     HEclear();
548 
549     /* '5' is a magic number, the exact amount of space for 2 uint16's */
550     /* the magic number _should_ be '4', but the size of the Vdata */
551     /* information is incorrectly calculated (in vpackvs() above) when the */
552     /* info is written to the file and it's too late to change it now :- ( */
553     /* get version number first -- this is different from version 3
554        vdata interface */
555     bb = &buf[len - 5];
556     UINT16DECODE(bb, uint16var); /* retrieve the vg's version field */
557 
558     vs->version = (int16)uint16var;
559     UINT16DECODE(bb, uint16var);     /* retrieve the vg's more field */
560 
561     vs->more = (int16)uint16var;
562     bb = &buf[0];
563 
564     if (vs->version <= 4)
565       {
566           /* retrieve interlace */
567           INT16DECODE(bb, vs->interlace);
568 
569           /* retrieve nvertices */
570           INT32DECODE(bb, vs->nvertices);
571 
572           /* retrieve tore ivsize */
573           UINT16DECODE(bb, vs->wlist.ivsize);
574 
575           /* retrieve nfields */
576           INT16DECODE(bb, int16var);
577           vs->wlist.n = (intn)int16var;
578 
579           if(vs->wlist.n==0)
580             {   /* Special case for Vdata with 0 fields defined */
581               /* Initialize buffer to NULL & carry over to other arrays */
582               vs->wlist.bptr = NULL;
583               vs->wlist.type = NULL;
584               vs->wlist.off = NULL;
585               vs->wlist.isize = NULL;
586               vs->wlist.order = NULL;
587               vs->wlist.esize = NULL;
588 
589               /* Initialize the array of pointers to field names to NULL also */
590               vs->wlist.name = NULL;
591             } /* end if */
592           else
593             { /* Allocate buffer to hold all the int16/uint16 arrays */
594               if(NULL==(vs->wlist.bptr = HDmalloc(sizeof(uint16)*(size_t)(vs->wlist.n*5))))
595                   HGOTO_ERROR(DFE_NOSPACE, FAIL);
596 
597               /* Use buffer to support the other arrays */
598               vs->wlist.type = (int16 *)vs->wlist.bptr;
599               vs->wlist.off = (uint16 *)vs->wlist.type+vs->wlist.n;
600               vs->wlist.isize = vs->wlist.off+vs->wlist.n;
601               vs->wlist.order = vs->wlist.isize+vs->wlist.n;
602               vs->wlist.esize = vs->wlist.order+vs->wlist.n;
603 
604               for (i = 0; i < vs->wlist.n; i++)   /* retrieve the type */
605                   INT16DECODE(bb, vs->wlist.type[i]);
606 
607               for (i = 0; i < vs->wlist.n; i++)   /* retrieve the isize */
608                   UINT16DECODE(bb, vs->wlist.isize[i]);
609 
610               for (i = 0; i < vs->wlist.n; i++)   /* retrieve the offset */
611                   UINT16DECODE(bb, vs->wlist.off[i]);
612 
613               for (i = 0; i < vs->wlist.n; i++)   /* retrieve the order */
614                   UINT16DECODE(bb, vs->wlist.order[i]);
615 
616               /* retrieve the field names (and each field name's length)  */
617               if(NULL==(vs->wlist.name = HDmalloc(sizeof(char *)*(size_t)vs->wlist.n)))
618                   HGOTO_ERROR(DFE_NOSPACE, FAIL);
619 
620               for (i = 0; i < vs->wlist.n; i++)
621                 {
622                     INT16DECODE(bb, int16var);    /* this gives the length */
623                     if(NULL==(vs->wlist.name[i] = HDmalloc((int16var+1)*sizeof(char))))
624                         HGOTO_ERROR(DFE_NOSPACE, FAIL);
625 
626                     HIstrncpy(vs->wlist.name[i], (char *) bb, int16var + 1);
627 
628                     bb += (size_t)int16var;
629                 }
630             } /* end else */
631 
632           /* retrieve the vsname (and vsnamelen)  */
633           INT16DECODE(bb, int16var);  /* this gives the length */
634 
635           HIstrncpy(vs->vsname, (char *) bb, int16var + 1);
636           bb += (size_t)int16var;
637 
638           /* retrieve the vsclass (and vsclasslen)  */
639           INT16DECODE(bb, int16var);  /* this gives the length */
640 
641           HIstrncpy(vs->vsclass, (char *) bb, int16var + 1);
642           bb += (size_t)int16var;
643 
644           /* retrieve the expansion tag and ref */
645           UINT16DECODE(bb, vs->extag);
646           UINT16DECODE(bb, vs->exref);
647 
648           /* retrieve the middle version field */
649           INT16DECODE(bb, temp);
650           if (temp != vs->version)
651               HGOTO_ERROR(DFE_BADVH, FAIL);
652 
653           /* retrieve the 'more' field */
654           INT16DECODE(bb, temp);
655           if (temp != vs->more)
656               HGOTO_ERROR(DFE_BADVH, FAIL);
657 
658           if (vs->version == VSET_NEW_VERSION)
659             { /* new features exist */
660                 UINT32DECODE(bb, vs->flags);
661                 if (vs->flags & VS_ATTR_SET)
662                   {    /* get attr info */
663                       INT32DECODE(bb, vs->nattrs);
664 
665                       if (NULL == (vs->alist = (vs_attr_t *)HDmalloc(vs->nattrs*sizeof(vs_attr_t))))
666                           HGOTO_ERROR(DFE_NOSPACE, FAIL);
667 
668                       for (i=0; i<vs->nattrs; i++)
669                         {
670                             INT32DECODE(bb, vs->alist[i].findex);
671                             UINT16DECODE(bb, vs->alist[i].atag);
672                             UINT16DECODE(bb, vs->alist[i].aref);
673                         }  /* for */
674                   }     /* attr set */
675             }   /* new version */
676 
677           if (vs->version <= VSET_OLD_TYPES)
678             {
679                 for (i = 0; i < vs->wlist.n; i++)   /* save the type */
680                     vs->wlist.type[i] = map_from_old_types((intn)vs->wlist.type[i]);
681             }
682 
683           /* --- EXTRA --- fill in the machine-dependent size fields */
684           for (i = 0; i < vs->wlist.n; i++)
685             {
686                 vs->wlist.esize[i] = (uint16) (vs->wlist.order[i] *
687                                                DFKNTsize((int32) vs->wlist.type[i] | (int32) DFNT_NATIVE));
688             }
689       }  /* if version <= 4 */
690 
691 done:
692     if (ret_value == FAIL)
693     { /* Error condition cleanup */
694 
695     } /* end if */
696 
697 	  /* Normal function cleanup */
698   return ret_value;
699 }   /* vunpackvs */
700 
701 /*******************************************************************************
702 NAME
703    vsdestroynode
704 
705 DESCRIPTION
706    Frees B-Tree nodes
707 
708    *** Only called by B-tree routines, should _not_ be called externally ***
709    *** unless you know what your are doing                               ***
710 
711 RETURNS
712    Nothing
713 
714 *******************************************************************************/
715 void
vsdestroynode(void * n)716 vsdestroynode(void * n /* IN: Node in TBBT-tree */)
717 {
718     VDATA  *vs = NULL;
719     intn   i;
720 
721     if (n != NULL)
722       {
723           vs = ((vsinstance_t *) n)->vs;
724           if (vs != NULL)
725             {
726                 /* Free the dynamicly allocated VData fields */
727                 for(i=0; i<vs->wlist.n; i++)
728                     HDfree(vs->wlist.name[i]);
729 
730                 HDfree(vs->wlist.name);
731                 HDfree(vs->wlist.bptr);
732 
733                 if(vs->rlist.item != NULL)
734                     HDfree(vs->rlist.item);
735 
736                 if (vs->alist != NULL)
737                     HDfree(vs->alist);
738 
739                 VSIrelease_vdata_node(vs);
740             } /* end if */
741 
742           /* relase this instance to the free list ? */
743           VSIrelease_vsinstance_node((vsinstance_t *)n);
744       } /* end if 'n' */
745 
746 }   /* vsdestroynode */
747 
748 /*******************************************************************************
749  NAME
750     VSPgetinfo -- Read in the "header" information about the Vdata.
751 
752  DESCRIPTION
753     This routine pre-reads the header information for a Vdata into memory
754     so that it can be accessed more quickly by the routines that need it.
755 
756  RETURNS
757     Return a pointer to a VDATA filled with the Vdata information on success,
758     NULL on failure.
759 
760 *******************************************************************************/
761 VDATA *
VSPgetinfo(HFILEID f,uint16 ref)762 VSPgetinfo(HFILEID f, /* IN: file handle */
763            uint16 ref /* IN: ref of the Vdata */)
764 {
765 	VDATA 		*vs = NULL;   /* new vdata to be returned */
766   /* int32       vh_length;   int32 is mismatches Vhbuf's type -- uint32 */
767     size_t vh_length;         /* length of the vdata header */
768     VDATA *ret_value = NULL;  /* FAIL */
769     CONSTR(FUNC, "VSPgetinfo");
770 
771     /* clear error stack */
772     HEclear();
773 
774     /* get a free Vdata node? */
775     if ((vs = VSIget_vdata_node()) == NULL)
776         HGOTO_ERROR(DFE_NOSPACE, NULL);
777 
778     /* need to fetch length of vdata from file */
779     if ((vh_length = Hlength(f,DFTAG_VH,ref)) == FAIL)
780         HGOTO_ERROR(DFE_BADLEN, NULL);
781 
782     if(vh_length > Vhbufsize)
783       {
784         Vhbufsize = vh_length;
785 
786         if (Vhbuf != NULL)
787             HDfree(Vhbuf);
788 
789         if ((Vhbuf = (uint8 *) HDmalloc(Vhbufsize)) == NULL)
790             HGOTO_ERROR(DFE_NOSPACE, NULL);
791       } /* end if */
792 
793     /* get Vdata header from file */
794     if (Hgetelement(f,DFTAG_VH,ref,Vhbuf) == FAIL)
795         HGOTO_ERROR(DFE_NOVS, NULL);
796 
797     /* init all other fields in vdata
798        and then unpack the vdata */
799     vs->otag    = DFTAG_VH;
800     vs->oref    = ref;
801     vs->f       = f;
802     if (FAIL == vunpackvs (vs,Vhbuf, vh_length))
803         HGOTO_ERROR(DFE_INTERNAL, NULL);
804 
805     /* return vdata */
806     ret_value = (vs);
807 
808 done:
809   if(ret_value == NULL)
810     { /* Error condition cleanup */
811 
812     } /* end if */
813 
814   /* Normal function cleanup */
815 
816   return ret_value;
817 } /* end VSPgetinfo() */
818 
819 
820 /*******************************************************************************
821 NAME
822    VSattach
823 
824 DESCRIPTION
825    NEW VSattach:
826    (a)  if vsid == -1
827        if "r" access return error.
828        if "w" access
829        create a new vs in vg and attach it.
830        add to vsdir, set nattach= 1, nvertices = 0.
831 
832    (b)  if (vsid > 0)
833        if "r" access => look in vsdir
834        if not found,
835        fetch  vs from file, add to vsdir,
836        set nattach= 1, nvertices = val from file.
837        if found,
838        check access of found vs
839        if "w" => being written, unstable! forbidden
840        if "r" => ok. incr nattach.
841 
842        if "w" access => new data may be added BUT must be same format
843        as existing vdata.
844        (ie. VSsetfields must match old format exactly!!)
845 
846    Allows for seeks to write.
847 
848    in all cases, set the marked flag to 0.
849    returns NULL if error.
850 
851    OLD VSattach:
852    if vsid == -1, then
853    (a) if vg is "w", create a new vs in vg and attach it.
854    add to vsdir, set nattach= 1, nvertices = 0.
855    (b) if vg is "r", forbidden.
856    if vsid is +ve, then
857    (a) if vg is "w"  => new data may be added BUT must be same format
858    as existing vdata.
859    (ie. VSsetfields must match old format exactly!!)
860 
861    (b) if vg is "r"  => look in vsdir
862    if not found,
863    fetch  vs from file, add to vsdir,
864    set nattach= 1, nvertices = val from file.
865    if found,
866    check access of found vs
867    if "w" => being written, unstable! forbidden
868    if "r" => ok. incr nattach.
869 
870    in all cases, set the marked flag to 0.
871    returns NULL if error.
872 
873 RETURNS
874 
875 
876 *******************************************************************************/
877 int32
VSattach(HFILEID f,int32 vsid,const char * accesstype)878 VSattach(HFILEID f,             /* IN: file handle */
879          int32 vsid,            /* IN: vdata id i.e. ref */
880          const char *accesstype /* IN: access type */)
881 {
882     VDATA        *vs = NULL;    /* new vdata to be returned */
883     vsinstance_t *w = NULL;
884     vfile_t      *vf = NULL;
885     int32        acc_mode;
886     int32      ret_value = FAIL;
887     CONSTR(FUNC, "VSattach");
888 
889     /* clear error stack */
890     HEclear();
891 
892     /* check file and vdata handles */
893     if ((f == FAIL) || (vsid < -1))
894         HGOTO_ERROR(DFE_ARGS, FAIL);
895 
896     /* get vdata file record */
897     if (NULL == (vf = Get_vfile(f)))
898         HGOTO_ERROR(DFE_FNF, FAIL);
899 
900     /* check access type and covert to internal mode? */
901     if (accesstype[0] == 'R' || accesstype[0] == 'r')
902         acc_mode = 'r';
903     else if (accesstype[0] == 'W' || accesstype[0] == 'w')
904         acc_mode = 'w';
905     else
906         HGOTO_ERROR(DFE_BADACC, FAIL);
907 
908     /*      */
909     if (vsid == -1)
910       {  /* ---------- VSID IS -1 -----------------------
911             if "r" access return error.
912             if "w" access
913             create a new vs in vg and attach it.
914             add to vsdir, set nattach= 1, nvertices = 0.
915           */
916           if (acc_mode == 'r')
917               HGOTO_ERROR(DFE_BADACC, FAIL);
918 
919           /* otherwise 'w' */
920           /* allocate space for vs,  & zero it out  */
921           if ((vs = VSIget_vdata_node()) == NULL)
922               HGOTO_ERROR(DFE_NOSPACE, FAIL);
923 
924           vs->otag = DFTAG_VH;
925           vs->oref = Hnewref(f);
926           if (vs->oref == 0)
927             {
928                 VSIrelease_vdata_node(vs);
929                 HGOTO_ERROR(DFE_NOREF, FAIL);
930             }
931 
932           vs->interlace = FULL_INTERLACE;   /* DEFAULT */
933           vs->access = 'w';
934           vs->f = f;
935           vs->version = VSET_VERSION;
936 
937           /* attach new vs to file's vstab */
938           if (NULL == (w = VSIget_vsinstance_node()))
939               HGOTO_ERROR(DFE_NOSPACE, FAIL);
940 
941           vf->vstabn++;
942           w->key = (int32) vs->oref;  /* set the key for the node */
943           w->ref = (uintn) vs->oref;
944           w->vs = vs;
945           w->nattach = 1;
946           w->nvertices = 0;
947 
948           /* insert the vs instance in B-tree */
949           tbbtdins(vf->vstree, w, NULL);
950 
951           vs->instance = w;
952       }     /* end of case where vsid is -1 */
953     else
954       { /*  --------  VSID IS NON_NEGATIVE -------------
955             if "r" access => look in vsdir
956             if not found,
957             fetch  vs from file, add to vsdir,
958             set nattach= 1, nvertices = val from file.
959             if found,
960             check access of found vs
961             if "w" => being written, unstable! forbidden
962             if "r" => ok. incr nattach.
963 
964             if "w" access => new data may be added BUT must be same format
965             as existing vdata.
966             (ie. VSsetfields must match old format exactly!!)
967 
968             Allows for seeks to write.
969 
970             in all cases, set the marked flag to 0.
971             returns NULL if error.
972         */
973 
974         if (NULL == (w = vsinst(f, (uint16) vsid)))
975             HGOTO_ERROR(DFE_VTAB, FAIL);
976 
977         if (acc_mode == 'r')
978           {     /* reading an existing vdata */
979               /* this vdata is already attached for 'r', ok to do so again */
980 	      /* then reset the read position to the beginning of the vdata */
981               if (w->nattach && w->vs->access == 'r')
982 		{
983 		  accrec_t *access_rec;	/* access record */
984 
985                   w->nattach++;
986 
987 		  /* get the access_rec pointer to reset position */
988 		  if ((access_rec = HAatom_object(w->vs->aid)) == NULL)
989 		      HGOTO_ERROR(DFE_ARGS, FAIL);
990 		  access_rec->posn = 0;	/* to fix bugzilla #486 - BMR, Dec, 05 */
991 		}
992               else
993                 {
994                   vs = w->vs;
995 
996                   vs->access = 'r';
997                   vs->aid = Hstartread(vs->f, VSDATATAG, vs->oref);
998                   if (vs->aid == FAIL)
999                     HGOTO_ERROR(DFE_BADAID, FAIL);
1000 
1001                   vs->instance = w;
1002 
1003                   /* attach vs to vsdir  at the vdata instance w */
1004                   w->nattach = 1;
1005                   w->nvertices = vs->nvertices;
1006                 } /* end else */
1007           }		/* end of case where vsid is positive, and "r"  */
1008         else
1009           {		/* writing to an existing vdata */
1010               if (w->nattach)	/* vdata previously attached before */
1011                   HGOTO_ERROR(DFE_BADATTACH, FAIL);
1012 
1013               vs = w->vs;
1014 
1015               vs->access = 'w';
1016               vs->aid = Hstartwrite(vs->f, VSDATATAG, vs->oref, 0);
1017               if (vs->aid == FAIL)
1018                 HGOTO_ERROR(DFE_BADAID, FAIL);
1019 
1020               vs->instance = w;
1021               vs->new_h_sz = 0;
1022 
1023               /* attach vs to vsdir  at the vdata instance w */
1024               w->nattach = 1;
1025               w->nvertices = vs->nvertices;
1026           }		/* end of case where vsid is positive, and "w"  */
1027       } /* end else */
1028 
1029     /* register this vdata with group */
1030     ret_value = HAregister_atom(VSIDGROUP,w);
1031 
1032     /* Make VDatas appendable by default */
1033     if (FAIL == VSappendable(ret_value,VDEFAULTBLKSIZE))
1034         HGOTO_ERROR(DFE_INTERNAL, FAIL);
1035 
1036 done:
1037   if(ret_value == FAIL)
1038     { /* Error condition cleanup */
1039 
1040     } /* end if */
1041 
1042   /* Normal function cleanup */
1043 
1044   return ret_value;
1045 }	/* VSattach */
1046 
1047 /*******************************************************************************
1048 NAME
1049   VSdetach
1050 
1051 DESCRIPTION
1052    Detach vs from vstab.
1053 
1054    if vs has "w" access,   ( <=> only attached ONCE! )
1055    decr nattach.
1056    if (nattach is not  0)  => bad error in code.
1057    if nvertices (in vs) is 0) just free vs from vstab.
1058 
1059    if marked flag is 1
1060    write out vs to file and set marked flag to 0.
1061    free vs from vsdir.
1062 
1063    if vs has "r" access,   ( <=> only attached ONCE! )
1064    decr nattach.
1065    if (nattach is 0)   just free vs from vstab.
1066 
1067 RETURNS
1068    SUCCEED / FAIL
1069 
1070 *******************************************************************************/
1071 int32
VSdetach(int32 vkey)1072 VSdetach(int32 vkey /* IN: vdata key? */)
1073 {
1074     int32       i;
1075     int32       ret;
1076     int32       vspacksize;
1077     vsinstance_t *w = NULL;
1078     VDATA        *vs = NULL;
1079     int32        ret_value = SUCCEED;
1080     CONSTR(FUNC, "VSdetach");
1081 
1082     /* clear error stack */
1083     HEclear();
1084 
1085     /* check if vdata is part of vdata group */
1086     if (HAatom_group(vkey) != VSIDGROUP)
1087         HGOTO_ERROR(DFE_ARGS, FAIL);
1088 
1089     /* get vdata instance */
1090     if (NULL == (w = (vsinstance_t *) HAatom_object(vkey)))
1091         HGOTO_ERROR(DFE_NOVS, FAIL);
1092 
1093     /* get vdata itself and check it */
1094     vs = w->vs;
1095     if ((vs == NULL) || (vs->otag != VSDESCTAG))
1096       HGOTO_ERROR(DFE_ARGS,FAIL);
1097 
1098     w->nattach--; /* detach from vdata */
1099 
1100     /* --- case where access was 'r' --- */
1101     if (vs->access == 'r')
1102       {
1103           if (w->nattach == 0)
1104             { /* end access to vdata */
1105               if (Hendaccess(vs->aid) == FAIL)
1106                   HGOTO_ERROR(DFE_INTERNAL, FAIL);
1107 	      vs->aid = FAIL;
1108 
1109               /* remove from atom list */
1110               if(HAremove_atom(vkey)==NULL)
1111                   HGOTO_ERROR(DFE_INTERNAL, FAIL);
1112             } /* end if */
1113 
1114           /* we are done */
1115           HGOTO_DONE(SUCCEED);
1116       }
1117     else /* must be write */
1118       {
1119           /* --- case where access was 'w' --- */
1120           if (w->nattach != 0)
1121               HGOTO_ERROR(DFE_CANTDETACH, FAIL);
1122 
1123           if (vs->marked)
1124             {	/* if marked , write out vdata's VSDESC to file */
1125                 size_t need;
1126 
1127                 need = sizeof(VWRITELIST) +
1128                        (size_t)vs->nattrs*sizeof(vs_attr_t) + sizeof(VDATA) + 1;
1129 
1130                 if(need > Vhbufsize)
1131                   {
1132                       Vhbufsize = need;
1133                       if (Vhbuf)
1134                           HDfree(Vhbuf);
1135 
1136                       if ((Vhbuf = HDmalloc(Vhbufsize)) == NULL)
1137                           HGOTO_ERROR(DFE_NOSPACE, FAIL);
1138                   } /* end if */
1139 
1140                 if (FAIL == vpackvs(vs, Vhbuf, &vspacksize))
1141                     HGOTO_ERROR(DFE_INTERNAL, FAIL);
1142 
1143                 /* if VH size changed we need to re-use the tag/ref
1144                  * for new header. This will cause the pointer to the
1145                  * original vdata header to be lost but this is okay.  */
1146                 if (vs->new_h_sz)
1147                   {
1148                       /* check if tag/ref exists in DD list already */
1149                       switch(HDcheck_tagref(vs->f, DFTAG_VH, vs->oref))
1150                         {
1151                         case 0: /* not found */
1152                             break;
1153                         case 1: /* found, reuse tag/ref */
1154                             if (HDreuse_tagref(vs->f, DFTAG_VH, vs->oref) == FAIL)
1155                                 HGOTO_ERROR(DFE_INTERNAL, FAIL);
1156                             break;
1157                         case -1: /* error */
1158                             HGOTO_ERROR(DFE_INTERNAL, FAIL);
1159                         default: /* should never get here */
1160                             HGOTO_ERROR(DFE_INTERNAL, FAIL);
1161                         }
1162                   }
1163 
1164                 /* write new one */
1165                 ret = Hputelement(vs->f, VSDESCTAG, vs->oref, Vhbuf, vspacksize);
1166                 if (ret == FAIL)
1167                     HGOTO_ERROR(DFE_WRITEERROR, FAIL);
1168 
1169                 vs->marked = 0;
1170                 vs->new_h_sz = 0;
1171             }
1172 
1173           /* remove all defined symbols */
1174           for (i = 0; i < vs->nusym; i++)
1175               HDfree(vs->usym[i].name);
1176 
1177           if(vs->usym!=NULL)
1178               HDfree(vs->usym);   /* free the actual array */
1179 
1180           vs->nusym = 0;
1181           vs->usym=NULL;
1182 
1183           /* end access to vdata */
1184           if (Hendaccess(vs->aid) == FAIL)
1185               HGOTO_ERROR(DFE_INTERNAL, FAIL);
1186 	  vs->aid = FAIL;
1187 
1188           /* remove vdata from atom list */
1189           if(HAremove_atom(vkey)==NULL)
1190               HGOTO_ERROR(DFE_INTERNAL, FAIL);
1191 
1192       } /* end of 'write' case */
1193 
1194 done:
1195   if(ret_value == FAIL)
1196     { /* Error condition cleanup */
1197 
1198     } /* end if */
1199 
1200   /* Normal function cleanup */
1201   return ret_value;
1202 }	/* VSdetach */
1203 
1204 /*******************************************************************************
1205  NAME
1206    VSappendable
1207 
1208  DESCRIPTION
1209     Make it possible to append unlimitedly to an existing VData
1210 
1211   RETURNS
1212       SUCCEED, or FAIL for error
1213 *******************************************************************************/
1214 int32
VSappendable(int32 vkey,int32 blk)1215 VSappendable(int32 vkey, /* IN: vdata key */
1216              int32 blk   /* IN: */)
1217 {
1218     vsinstance_t *w = NULL;
1219     VDATA        *vs = NULL;
1220     int32      ret_value = SUCCEED;
1221     CONSTR(FUNC, "VSappendable");
1222 
1223     /* clear error stack */
1224     HEclear();
1225 
1226     /* shut compiler up */
1227     blk = blk;
1228 
1229     /* check vdata key is a valid */
1230     if (HAatom_group(vkey) != VSIDGROUP)
1231         HGOTO_ERROR(DFE_ARGS, FAIL);
1232 
1233     /* get vdata instance */
1234     if (NULL == (w = (vsinstance_t *) HAatom_object(vkey)))
1235         HGOTO_ERROR(DFE_NOVS, FAIL);
1236 
1237     /* get Vdata itself and check */
1238     vs = w->vs;
1239     if ((vs == NULL) || (vs->otag != VSDESCTAG))
1240         HGOTO_ERROR(DFE_ARGS, FAIL);
1241 
1242     if(vs->aid == 0)
1243         vs->aid = Hstartaccess(vs->f, VSDATATAG, vs->oref, DFACC_RDWR|DFACC_APPENDABLE);
1244     else
1245         ret_value = Happendable(vs->aid);
1246 
1247 done:
1248   if(ret_value == FAIL)
1249     { /* Error condition cleanup */
1250 
1251     } /* end if */
1252 
1253   /* Normal function cleanup */
1254   return ret_value;
1255 }   /* VSappendable */
1256 
1257 /*******************************************************************************
1258 NAME
1259    VSgetid
1260 
1261 DESCRIPTION
1262    returns the id of the next  VDATA from the file f .
1263    (vsid = -1 gets the 1st vDATA).
1264 
1265 RETURNS
1266    RETURNS -1 on error.
1267    RETURNS vdata id (0 or +ve integer)
1268 
1269 *******************************************************************************/
1270 int32
VSgetid(HFILEID f,int32 vsid)1271 VSgetid(HFILEID f,  /* IN: file handle */
1272         int32 vsid  /* IN: vdata id i.e. ref */)
1273 {
1274     vsinstance_t *w = NULL;
1275     vfile_t      *vf = NULL;
1276     void *        *t = NULL;
1277     int32        key;
1278     int32        ret_value = SUCCEED;
1279     CONSTR(FUNC, "VSgetid");
1280 
1281     /* clear error stack */
1282     HEclear();
1283 
1284     /* check valid vdata id */
1285     if (vsid < -1)
1286         HGOTO_ERROR(DFE_ARGS, FAIL);
1287 
1288     /* get vdata file record */
1289     if (NULL == (vf = Get_vfile(f)))
1290         HGOTO_ERROR(DFE_FNF, FAIL);
1291 
1292     if (vsid == -1)
1293       { /* vsid '-1' case */
1294 
1295         if (vf->vstree==NULL)
1296             HGOTO_DONE(FAIL);
1297 
1298         if ((t = (void **)tbbtfirst((TBBT_NODE *) * (vf->vstree))) == NULL)
1299             HGOTO_DONE(FAIL);
1300 
1301         /* we assume 't' is valid at this point */
1302         w = (vsinstance_t *) * t; /* get actual pointer to the vsinstance_t */
1303         HGOTO_DONE((int32)w->ref);/* rets 1st vdata's ref */
1304       }
1305     else /* vsid >= 0 */
1306       {
1307           /* tbbtdfind returns a pointer to the vsinstance_t pointer */
1308           key = (int32)vsid;
1309           t = (void * *) tbbtdfind(vf->vstree, &key, NULL);
1310 
1311           if (t == NULL)  /* couldn't find the old vsid */
1312               ret_value = (FAIL);
1313           else if (NULL == (t = (void * *) tbbtnext((TBBT_NODE *) t)))  /* get the next node in the tree */
1314               ret_value = (FAIL);
1315           else
1316             {
1317                 w = (vsinstance_t *) * t;   /* get actual pointer to the vsinstance_t */
1318                 ret_value = (int32)w->ref;  /* rets vdata's ref */
1319             }     /* end else */
1320       }
1321 
1322 done:
1323   if(ret_value == FAIL)
1324     { /* Error condition cleanup */
1325 
1326     } /* end if */
1327 
1328   /* Normal function cleanup */
1329   return ret_value;
1330 }   /* VSgetid */
1331 
1332 /*******************************************************************************
1333 NAME
1334    VSQuerytag
1335 
1336 DESCRIPTION
1337    get the 'otag' of the given Vdata
1338 
1339 RETURNS
1340    Return the 'otag' of the given Vdata
1341    Return FAIL on failure
1342 
1343 *******************************************************************************/
1344 int32
VSQuerytag(int32 vkey)1345 VSQuerytag(int32 vkey /* IN: vdata key */)
1346 {
1347     vsinstance_t *w = NULL;
1348     VDATA        *vs = NULL;
1349     int32      ret_value = SUCCEED;
1350     CONSTR(FUNC, "VSQuerytag");
1351 
1352     /* clear error stack */
1353     HEclear();
1354 
1355     /* check vdata key is a valid */
1356     if (HAatom_group(vkey) != VSIDGROUP)
1357       HGOTO_ERROR(DFE_ARGS,FAIL);
1358 
1359     /* get vdata instance */
1360     if (NULL == (w = (vsinstance_t *) HAatom_object(vkey)))
1361       HGOTO_ERROR(DFE_NOVS,FAIL);
1362 
1363     /* get Vdata itself and check */
1364     vs = w->vs;
1365     if ((vs == NULL) || (vs->otag != VSDESCTAG))
1366       HGOTO_ERROR(DFE_ARGS,FAIL);
1367 
1368     /* return otag of vdata */
1369     ret_value = ((int32) vs->otag);
1370 
1371 done:
1372   if(ret_value == FAIL)
1373     { /* Error condition cleanup */
1374 
1375     } /* end if */
1376 
1377   /* Normal function cleanup */
1378 
1379   return ret_value;
1380 }	/* VSQuerytag */
1381 
1382 /*******************************************************************************
1383 NAME
1384   VSQueryref
1385 
1386 DESCRIPTION
1387   get the ref of the the given Vdata
1388 
1389 RETURNS
1390    Return the ref of the given Vdata
1391    Return FAIL on failure
1392 
1393 *******************************************************************************/
1394 int32
VSQueryref(int32 vkey)1395 VSQueryref(int32 vkey /* IN: vdata key */)
1396 {
1397     vsinstance_t *w = NULL;
1398     VDATA        *vs = NULL;
1399     int32      ret_value = SUCCEED;
1400     CONSTR(FUNC, "VSQueryref");
1401 
1402     /* clear error stack */
1403     HEclear();
1404 
1405     /* check vdata key is a valid */
1406     if (HAatom_group(vkey) != VSIDGROUP)
1407       HGOTO_ERROR(DFE_ARGS,FAIL);
1408 
1409     /* get vdata instance */
1410     if (NULL == (w = (vsinstance_t *) HAatom_object(vkey)))
1411       HGOTO_ERROR(DFE_NOVS,FAIL);
1412 
1413     /* get Vdata itself and check */
1414     vs = w->vs;
1415     if ((vs == NULL) || (vs->otag != VSDESCTAG))
1416       HGOTO_ERROR(DFE_ARGS,FAIL);
1417 
1418     /* return ref of vdata */
1419     ret_value = ((int32) vs->oref);
1420 
1421 done:
1422   if(ret_value == FAIL)
1423     { /* Error condition cleanup */
1424 
1425     } /* end if */
1426 
1427   /* Normal function cleanup */
1428 
1429   return ret_value;
1430 }	/* VSQueryref */
1431 
1432 /*******************************************************************************
1433 NAME
1434    vswritelist
1435 
1436 DESCRIPTION
1437    get the 'writelist' of the given vdata
1438 
1439 RETURNS
1440    return the 'writelist' of the vdata if successful else NULL
1441 
1442 *******************************************************************************/
1443 DYN_VWRITELIST *
vswritelist(int32 vkey)1444 vswritelist(int32 vkey /* IN: vdata key */)
1445 {
1446     vsinstance_t *w = NULL;
1447     VDATA        *vs = NULL;
1448     DYN_VWRITELIST *ret_value = NULL; /* Failure */
1449     CONSTR(FUNC, "VSwritelist");
1450 
1451     /* clear error stack */
1452     HEclear();
1453 
1454     /* check vdata key is a valid */
1455     if (HAatom_group(vkey) != VSIDGROUP)
1456         HGOTO_ERROR(DFE_ARGS, NULL);
1457 
1458     /* get vdata instance */
1459     if (NULL == (w = (vsinstance_t *) HAatom_object(vkey)))
1460         HGOTO_ERROR(DFE_NOVS, NULL);
1461 
1462     /* get Vdata itself and check */
1463     vs = w->vs;
1464     if ((vs == NULL) || (vs->otag != VSDESCTAG))
1465         HGOTO_ERROR(DFE_ARGS, NULL);
1466 
1467     /* return 'writelist' */
1468     ret_value = (&(vs->wlist));
1469 
1470 done:
1471   if(ret_value == NULL)
1472     { /* Error condition cleanup */
1473 
1474     } /* end if */
1475 
1476   /* Normal function cleanup */
1477 
1478   return ret_value;
1479 }   /* vswritelist() */
1480 
1481 /*******************************************************************************
1482 NAME
1483   VSgetversion
1484 
1485 DESCRIPTION
1486   get the version nuber of the vdata
1487 
1488 RETURNS
1489   return the version number if successful else '0'.
1490 
1491 *******************************************************************************/
1492 int32
VSgetversion(int32 vkey)1493 VSgetversion(int32 vkey /* IN: vdata key */)
1494 {
1495     vsinstance_t *w = NULL;
1496     VDATA        *vs = NULL;
1497     int32      ret_value = SUCCEED;
1498     CONSTR(FUNC, "VSgetversion");
1499 
1500     /* clear error stack */
1501     HEclear();
1502 
1503     /* check vdata key is a valid */
1504     if (HAatom_group(vkey) != VSIDGROUP)
1505         HGOTO_ERROR(DFE_ARGS, 0);
1506 
1507     /* get vdata instance */
1508     if (NULL == (w = (vsinstance_t *) HAatom_object(vkey)))
1509         HGOTO_ERROR(DFE_NOVS, 0);
1510 
1511     /* get Vdata itself and check */
1512     vs = w->vs;
1513     if ((vs == NULL) || (vs->otag != VSDESCTAG))
1514         HGOTO_ERROR(DFE_ARGS, 0);
1515 
1516     /* return version number */
1517     ret_value = (int32)vs->version;
1518 
1519 done:
1520   if(ret_value == FAIL)
1521     { /* Error condition cleanup */
1522 
1523     } /* end if */
1524 
1525   /* Normal function cleanup */
1526 
1527   return ret_value;
1528 }   /* end VSgetversion() */
1529 
1530 /*******************************************************************************
1531 NAME
1532   VSdelete
1533 
1534 DESCRIPTION
1535    Remove a Vdata from its file.  This function will both remove the Vdata
1536    from the internal Vset data structures as well as from the file.
1537    'vsid' is actually the 'ref' of the vdata.
1538 
1539    (i.e. it calls tbbt_delete() and Hdeldd())
1540 
1541 RETURNS
1542    Return FAIL / SUCCEED
1543 
1544 *******************************************************************************/
1545 int32
VSdelete(int32 f,int32 vsid)1546 VSdelete(int32 f,    /* IN: file handle */
1547          int32 vsid  /* IN: vdata id i.e. ref */)
1548 {
1549     void *       v;
1550     vfile_t    *vf = NULL;
1551     void *      *t = NULL;
1552     int32       key;
1553     int32       ret_value = SUCCEED;
1554     CONSTR(FUNC, "VSdelete");
1555 
1556     /* clear error stack */
1557     HEclear();
1558 
1559     /* check valid vdata id */
1560     if (vsid < -1)
1561         HGOTO_ERROR(DFE_ARGS, FAIL);
1562 
1563     /* get vdata file record */
1564     if (NULL == (vf = Get_vfile(f)))
1565       HGOTO_ERROR(DFE_FNF,FAIL);
1566 
1567     /* find vdata in TBBT using it's ref */
1568     key = vsid;
1569     if (( t = (void * *) tbbtdfind(vf->vstree, &key, NULL))== NULL)
1570         HGOTO_DONE(FAIL);
1571 
1572     /* remove vdata from TBBT */
1573     v = tbbtrem((TBBT_NODE **) vf->vstree, (TBBT_NODE *) t, NULL);
1574 
1575     /* destroy vdata node itself*/
1576     if (v != NULL)
1577         vsdestroynode(v);
1578 
1579     /* delete vdata header and data from file */
1580     if (Hdeldd(f, DFTAG_VS, (uint16) vsid) == FAIL)
1581         HGOTO_ERROR(DFE_INTERNAL, FAIL);
1582 
1583     if (Hdeldd(f, DFTAG_VH, (uint16) vsid) == FAIL)
1584         HGOTO_ERROR(DFE_INTERNAL, FAIL);
1585 
1586 done:
1587   if(ret_value == FAIL)
1588     { /* Error condition cleanup */
1589 
1590     } /* end if */
1591 
1592   /* Normal function cleanup */
1593   return ret_value;
1594 }	/* VSdelete */
1595