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: mfan.c
18 * Author: GeorgeV
19 * Purpose: Multi-file read and write annotations: labels and descriptions
20 * of data items and file
21 * Invokes:
22 * Comments:
23 * Currently the id returned by ANstart() is the same as the
24 * one returned by Hopen().
25 *
26 * Currently as least 4 TBBT trees are created to handle
27 * annotations(1 for file_ann, 1 for file_desc, 1 for data_ann
28 * and 1 for data_desc) for each file which is not pretty but it
29 * does make search/find of annotations much easier.
30 *
31 * NOTE2: Note that any mention of file ID's except in ANStart()
32 * should now refer to annotation interface ID.
33 *
34 * Contents:
35 *
36 * Private Routines:
37 * -----------------
38 * NOTES: TYPE here refers to file/data label/description types
39 * They are AN_FILE_LABEL, AN_FILE_DESC, AN_DATA_LABEL, AN_DATA_DESC
40 * The tag/ref refers to data tag/ref
41 *
42 * ANIinit - Intialize the annotation interface
43 * ANIdestroy - Un-intialize the annotation interface
44 *
45 * ANIanncmp - compare two annotation handles(ann_id's)
46 * (used in annotation TBBTtree)
47 * ANIaddentry: - add entry to corresponding annotation TBBTtree
48 * ANIcreate_ann_tree - create annotation TBBTtree
49 * ANIfind: - return annotation handle(ann_id) if found of given TYPE/ref
50 * ANInumann: - return number of annotations that match TYPE/tag/ref
51 * ANIannlist: - return list of handles(ann_id's) that match TYPE/tag/ref
52 * ANIannlen: - get length of annotation given handle(ann_id)
53 * ANIreadann: - read annotation given handle(ann_id)
54 * ANIwriteann: - write annotation given handle(ann_id)
55 * ANIcreate - create a new file/label annotation
56 * and return a handle(ann_id)
57 *
58 * Public API routines:
59 * --------------------
60 * ANstart - open file for annotation handling, returns an_id
61 * ANfileinfo - get number of file/data annotations in file. Indices returned
62 * are used in ANselect() calls.
63 * ANend - end access to annotation handling on file
64 * ANcreate - create a new data annotation and return a handle(ann_id)
65 * ANcreatef - create a new file annotation and return a handle(ann_id)
66 * ANselect - returns an annotation handle(ann_id) from index for
67 * a particular annotation TYPE. This handle is then used for
68 * calls like ANwriteann(), ANreadann(), ANannlen(),..etc
69 * ANnumann: - return number of annotations that match TYPE/tag/ref
70 * ANannlist: - return list of handles(ann_id's) that match TYPE/tag/ref
71 * ANannlen: - get length of annotation given handle(ann_id)
72 * ANreadann: - read annotation given handle(ann_id)
73 * ANwriteann: - write annotation given handle(ann_id)
74 * ANendaccess - end access to annotation using handle(ann_id)
75 *
76 * Public Miscellaneous API Routines
77 * ---------------------------------
78 * ANget_tagref - get tag/ref pair to annotation type and index
79 * ANid2tagref - get tag/ref pair to annotation ID
80 * ANtagref2id - get annotation id given tag/ref
81 * ANatype2tag - annotation type to corresponding annotation TAG
82 * ANtag2atype - annotation TAG to corresponding annotation type
83 *
84 *---------------------------------------------------------------------------*/
85
86 #ifndef MFAN_MASTER /* define main annotation source file */
87 #define MFAN_MASTER
88
89 #include "mfan.h"
90 #include "atom.h"
91 #include "hfile.h" /* needed for filerec_t */
92
93 /* Whether we've installed the library termination function yet for this
94 interface */
95 PRIVATE intn library_terminate = FALSE;
96
97 /* Function Prototypes for fcns used by TBBT. Can not be PRIVATE. */
98 extern void ANfreedata(void * data);
99 extern void ANfreekey(void * key);
100 extern void dumpentryKey(void *key, void *data);
101 extern intn ANIanncmp(void * i, void * j, intn value);
102
103 /* private initialization routine */
104 PRIVATE intn ANIstart(void);
105
106 /*-----------------------------------------------------------------------------
107 * Internal Routines
108 *---------------------------------------------------------------------------*/
109
110 /* ------------------------ Routines for TBBT ------------------------------*/
111 /* free data - used by tbbt routines */
112 void
ANfreedata(void * data)113 ANfreedata(void * data)
114 {
115 HDfree(data);
116 } /* ANfreekey() */
117
118 /* free key - used by tbbt routines */
119 void
ANfreekey(void * key)120 ANfreekey(void * key)
121 {
122 HDfree(key);
123 } /* ANfreekey() */
124
125 #ifdef AN_DEBUG
126 /* The following routine is used for debugging purposes to dump
127 * key/data pairs from the TBBT trees
128 * eg. tbbt_dump(tree, dumpentryKey, 0)*/
129 void
dumpentryKey(void * key,void * data)130 dumpentryKey(void *key, void *data)
131 {
132 ANentry *node = NULL;
133
134 printf("key = %4.4d, data = ",*(int*)key);
135 if (data != NULL)
136 {
137 node = (ANentry *) data;
138 printf("ann_id=%ld, annref=%d, elmtag=%d, elmref=%d\n",
139 (long)node->ann_id, node->annref, node->elmtag, node->elmref);
140 }
141 else
142 printf("(NULL)\n");
143 return;
144 } /* dumpentryKey() */
145 #endif /* AN_DEBUG */
146
147 /* ------------------------ Private Internal Routines ---------------------*/
148
149 /* ------------------------------- ANIanncmp --------------------------------
150 NAME
151 ANIanncmp -- compare two annotation keys or id's
152
153 DESCRIPTION
154 Compares two annotation keys. Used by tree for annotations
155 Also used to compare annotation id's since also 32 bit value.
156
157 RETURNS
158 Returns 0 if i=j, -1 if i > j and 1 if i < j
159
160 AUTHOR
161 GeorgeV.
162 --------------------------------------------------------------------------- */
163 intn
ANIanncmp(void * i,void * j,intn value)164 ANIanncmp(void * i, /* IN: annotation key(tag,ref) */
165 void * j, /* IN: annotation key(tag,ref) */
166 intn value /* not used */)
167 {
168 /* shut compiler up */
169 value = value;
170
171 if (*(int32 *)i == *(int32 *)j)
172 return 0;
173 if (*(int32 *)i > *(int32 *)j)
174 return -1;
175 else
176 return 1;
177 } /* ANIanncmp */
178
179 /* ------------------------------- ANIdestroy --------------------------------
180 NAME
181 ANIdestroy -- Un-Initialize Annotation Interface
182
183 DESCRIPTION
184 Destroys annotation Atom group ANIDGROUP. This routine is usually
185 registered with the atexit() rouinte.
186
187 RETURNS
188 SUCCEED or FAIL
189
190 AUTHOR
191 GeorgeV.
192
193 --------------------------------------------------------------------------- */
194 intn
ANIdestroy(void)195 ANIdestroy(void)
196 {
197 #ifdef LATER
198 CONSTR(FUNC, "ANIdestroy");
199 #endif /* LATER */
200 int32 ret_value = SUCCEED;
201
202 /* Clear error stack */
203 HEclear();
204
205 /* Destroy the atom groups for annotations */
206 HAdestroy_group(ANIDGROUP);
207
208 return ret_value;
209 } /* ANIdestroy () */
210
211 /*--------------------------------------------------------------------------
212 NAME
213 ANIstart - AN-level initialization routine.
214
215 DESCRIPTION
216 Register the shut-down routine (ANPdestroy) for call with atexit()
217
218 RETURNS
219 Returns SUCCEED/FAIL
220
221 AUTHOR
222 GeorgeV.
223
224 --------------------------------------------------------------------------*/
225 PRIVATE intn
ANIstart(void)226 ANIstart(void)
227 {
228 CONSTR(FUNC, "ANIstart"); /* for HERROR */
229 intn ret_value = SUCCEED;
230
231 /* Don't call this routine again... */
232 library_terminate = TRUE;
233
234 /* Install atexit() library cleanup routine ANIdestroy() */
235 if (HPregister_term_func(&ANIdestroy) != 0)
236 HGOTO_ERROR(DFE_CANTINIT, FAIL);
237
238 done:
239 if(ret_value == FAIL)
240 { /* Error condition cleanup */
241
242 } /* end if */
243
244 /* Normal function cleanup */
245
246 return(ret_value);
247 } /* end ANIstart() */
248
249 /* ------------------------------- ANIinit --------------------------------
250 NAME
251 ANIinit -- Initialize Annotation Interface
252
253 DESCRIPTION
254 Initializes the annotation interface i.e. installs library
255 cleanup routine and creates the Atom group ANIDGROUP for annotations
256 if necessary.
257
258 RETURNS
259 SUCCEED or FAIL
260
261 AUTHOR
262 GeorgeV.
263
264 --------------------------------------------------------------------------- */
265 PRIVATE int32
ANIinit(void)266 ANIinit(void)
267 {
268 CONSTR(FUNC, "ANIinit");
269 int32 ret_value = SUCCEED;
270
271 /* Clear error stack */
272 HEclear();
273
274 /* Perform global, one-time initialization */
275 if (library_terminate == FALSE)
276 {
277 if(ANIstart()==FAIL)
278 HGOTO_ERROR(DFE_CANTINIT, FAIL);
279
280 /* Initialize the atom groups for annotations */
281 HAinit_group(ANIDGROUP,ANATOM_HASH_SIZE);
282 }
283
284 done:
285 if(ret_value == FAIL)
286 { /* Error condition cleanup */
287
288 } /* end if */
289
290 /* Normal function cleanup */
291
292 return ret_value;
293 } /* ANIinit() */
294
295 /*--------------------------------------------------------------------------
296 NAME
297 ANIaddentry -- add entry to corresponding annotation TBBT tree and
298 atom group.
299
300 DESCRIPTION
301 Adds annotation to correct tree and register with atom group
302
303 RETURNS
304 annotation ID if successful and FAIL (-1) otherwise
305
306 AUTHOR
307 GeorgeV.
308
309 -------------------------------------------------------------------------*/
310 PRIVATE int32
ANIaddentry(int32 an_id,ann_type type,uint16 ann_ref,uint16 elmtag,uint16 elmref,intn new_ann)311 ANIaddentry(int32 an_id, /* IN: annotation interface id */
312 ann_type type, /* IN: annotation type
313 AN_DATA_LABEL for data labels,
314 AN_DATA_DESC for data descriptions,
315 AN_FILE_LABEL for file labels,
316 AN_FILE_DESC for file descritpions.*/
317 uint16 ann_ref, /* IN: ref of annotation */
318 uint16 elmtag, /* IN: tag of item of which this is annotation */
319 uint16 elmref, /* IN: ref of item of which this is annotation */
320 intn new_ann /* IN: new annotation flag */)
321 {
322 CONSTR(FUNC, "ANIaddentry");
323 filerec_t *file_rec = NULL; /* file record pointer */
324 uint16 ann_tag = DFTAG_NULL;
325 int32 *ann_key = NULL;
326 ANentry *ann_entry = NULL;
327 ANnode *ann_node = NULL;
328 int32 ret_value = SUCCEED;
329
330 /* Clear error stack */
331 HEclear();
332
333 /* convert an_id i.e. file_id to file rec and check for validity */
334 file_rec = HAatom_object(an_id);
335 if (BADFREC(file_rec))
336 HGOTO_ERROR(DFE_ARGS, FAIL);
337
338 /* Check for empty annotation tree of 'type'? */
339 if (file_rec->an_num[type] == -1)
340 {
341 if ((file_rec->an_tree[type] =
342 (TBBT_TREE *) tbbtdmake(ANIanncmp,sizeof(int32),0)) == NULL)
343 {
344 HE_REPORT_GOTO("failed to create annotation tree", FAIL);
345 }
346
347 file_rec->an_num[type] = 0;
348 }
349
350 /* Which type of annotation file/data label or desc? */
351 switch((ann_type)type)
352 {
353 case AN_DATA_LABEL:
354 ann_tag = DFTAG_DIL;
355 break;
356 case AN_DATA_DESC:
357 ann_tag = DFTAG_DIA;
358 break;
359 case AN_FILE_LABEL:
360 ann_tag = DFTAG_FID;
361 break;
362 case AN_FILE_DESC:
363 ann_tag = DFTAG_FD;
364 break;
365 default:
366 HE_REPORT_GOTO("Bad annotation type for this call",FAIL);
367 }
368
369 /* allocate space for key */
370 if ((ann_key = (int32 *)HDmalloc(sizeof(int32))) == NULL)
371 HGOTO_ERROR(DFE_NOSPACE, FAIL);
372
373 /* Create 32bit key from type/ref
374 * ----------------------------
375 * | type(16bits)| ref(16bits) |
376 * -----------------------------*/
377 *ann_key = AN_CREATE_KEY(type, ann_ref);
378
379 /* Initialize annotation node for insertion in annotation atom group*/
380 if ((ann_node = HDmalloc(sizeof(ANnode))) == NULL)
381 HGOTO_ERROR(DFE_NOSPACE, FAIL);
382
383 ann_node->file_id = an_id;
384 ann_node->ann_key = *ann_key;
385 ann_node->new_ann = new_ann;
386
387 /* Initialize annotation entry for insertion into corresponding TBBT */
388 if ((ann_entry = HDmalloc(sizeof(ANentry))) == NULL)
389 HGOTO_ERROR(DFE_NOSPACE, FAIL);
390
391 /* register annotation with atom group ANIDGROUP */
392 ann_entry->annref = ann_ref;
393 ann_entry->ann_id = HAregister_atom(ANIDGROUP,ann_node);
394 if (FAIL == ann_entry->ann_id)
395 HE_REPORT_GOTO("failed to insert annotation into ANIDGROUP atom group",
396 FAIL);
397
398 if (type == AN_DATA_LABEL || type == AN_DATA_DESC)
399 {
400 ann_entry->elmtag = (uint16) elmtag;
401 ann_entry->elmref = (uint16) elmref;
402 }
403 else
404 {
405 ann_entry->elmtag = ann_tag;
406 ann_entry->elmref = ann_ref;
407 }
408
409 /* Add annotation entry to 'type' tree */
410 if (tbbtdins(file_rec->an_tree[type], ann_entry, ann_key) == NULL)
411 HE_REPORT_GOTO("failed to insert annotation into 'type' tree", FAIL);
412
413 /* increment number of annotatiosn of 'type' */
414 file_rec->an_num[type] += 1;
415
416 /* return annotation id */
417 ret_value = ann_entry->ann_id;
418
419 done:
420 if(ret_value == FAIL)
421 { /* Error condition cleanup */
422 if (ann_key != NULL)
423 HDfree(ann_key);
424 if (ann_entry != NULL)
425 HDfree(ann_entry);
426 if (ann_node != NULL)
427 HDfree(ann_node);
428 } /* end if */
429
430 /* Normal function cleanup */
431
432 return ret_value;
433 } /* ANIaddentry */
434
435 /*--------------------------------------------------------------------------
436 NAME
437 ANIcreate_ann_tree -- create an annotation tree of 'type' for given file
438
439 DESCRIPTION
440 Creates either a label or descritption annotation TBBT tree.
441
442 RETURNS
443 Number of annotations of 'type' in file if successful and
444 FAIL (-1) otherwise
445
446 AUTHOR
447 GeorgeV.
448
449 -------------------------------------------------------------------------*/
450 PRIVATE intn
ANIcreate_ann_tree(int32 an_id,ann_type type)451 ANIcreate_ann_tree(int32 an_id,/* IN: annotation interface id */
452 ann_type type /* IN: AN_DATA_LABEL for data labels,
453 AN_DATA_DESC for data descriptions,
454 AN_FILE_LABEL for file labels,
455 AN_FILE_DESC for file descritpions.*/)
456 {
457 CONSTR(FUNC, "ANIcreate_ann_tree");
458 filerec_t *file_rec = NULL; /* file record pointer */
459 uint8 datadi[4];
460 int32 more_anns;
461 int32 aid = FAIL;
462 int32 nanns;
463 int32 i;
464 int32 *ann_key = NULL;
465 uint16 ann_tag;
466 uint16 ann_ref;
467 uint8 *dptr = NULL;
468 ANentry *ann_entry = NULL;
469 ANnode *ann_node = NULL;
470 intn ret_value = SUCCEED;
471
472 /* Clear error stack */
473 HEclear();
474
475 /* convert an_id i.e. file_id to file rec and check for validity */
476 file_rec = HAatom_object(an_id);
477 if (BADFREC(file_rec))
478 HGOTO_ERROR(DFE_ARGS, FAIL);
479
480 /* Check for empty annotation tree of 'type'? */
481 if (file_rec->an_num[type] == -1)
482 {
483 if ((file_rec->an_tree[type] =
484 (TBBT_TREE *) tbbtdmake(ANIanncmp,sizeof(int32),0)) == NULL)
485 {
486 HE_REPORT_GOTO("failed to create annotation tree", FAIL);
487 }
488 file_rec->an_num[type] = 0; /* initialize to zero entries */
489 }
490 else
491 {
492 ret_value = file_rec->an_num[type]; /* tree already created */
493 goto done; /* we are done */
494 }
495
496 /* Which type of annotation data/file label or desc? */
497 switch((ann_type)type)
498 {
499 case AN_DATA_LABEL:
500 ann_tag = DFTAG_DIL;
501 break;
502 case AN_DATA_DESC:
503 ann_tag = DFTAG_DIA;
504 break;
505 case AN_FILE_LABEL:
506 ann_tag = DFTAG_FID;
507 break;
508 case AN_FILE_DESC:
509 ann_tag = DFTAG_FD;
510 break;
511 default:
512 HE_REPORT_GOTO("Bad annotation type for this call",FAIL);
513 }
514
515 /* Get number of annotations of 'type' in file */
516 if ((nanns = Hnumber(an_id, ann_tag)) == 0)
517 { /* ZERO annotations of 'type' in file */
518 file_rec->an_num[type] = 0;
519 ret_value = file_rec->an_num[type];
520 goto done; /* we are done */
521 }
522
523 /* start read on 'type' annotations in file
524 * note that so far an_id == file_id */
525 if ((aid = Hstartread(an_id, ann_tag, DFREF_WILDCARD)) == FAIL)
526 {
527 HE_REPORT_GOTO("Hstartread failed to read annotation", FAIL);
528 }
529 else
530 more_anns = SUCCEED;
531
532 /* Process annotations of 'type' in file */
533 for (i = 0; (i < nanns) && (more_anns != FAIL); i++)
534 { /* see if annotation is there */
535 if (FAIL == Hinquire(aid, (int32 *) NULL, (uint16 *) NULL, &ann_ref,
536 (int32 *) NULL, (int32 *) NULL, (int32 *) NULL,
537 (int16 *) NULL, (int16 *) NULL))
538 { /* record what we found so far and return */
539 file_rec->an_num[type] = nanns;
540 ret_value = FAIL;
541 goto done; /* we are done */
542 }
543
544 /* if data annotation, read data annotation tag/ref */
545 if(type != AN_FILE_LABEL && type != AN_FILE_DESC)
546 {
547 if ((int32) FAIL == Hread(aid, (int32) 4, datadi))
548 { /* record what we found so far and return */
549 file_rec->an_num[type] = nanns;
550 ret_value = FAIL;
551 goto done; /* we are done */
552 }
553 }
554
555 /* allocate space for key */
556 if ((ann_key = (int32 *)HDmalloc(sizeof(int32))) == NULL)
557 HGOTO_ERROR(DFE_NOSPACE, FAIL);
558
559 /* Create key from tag/ref pair
560 * ----------------------------
561 * | tag(16bits) | ref(16bits) |
562 * -----------------------------*/
563 *ann_key = AN_CREATE_KEY(type, ann_ref);
564
565 /* Initialize annotation node for insertion in annotation atom group*/
566 if ((ann_node = HDmalloc(sizeof(ANnode))) == NULL)
567 HGOTO_ERROR(DFE_NOSPACE, FAIL);
568
569 ann_node->file_id = an_id;
570 ann_node->ann_key = *ann_key;
571 ann_node->new_ann = 0; /* not a newly created annotation */
572
573 /* Initialize annotation entry for insertion into corresponding TBBT */
574 /* and decode data tag/ref */
575 if ((ann_entry = HDmalloc(sizeof(ANentry))) == NULL)
576 HGOTO_ERROR(DFE_NOSPACE, FAIL);
577
578 ann_entry->annref = ann_ref;
579 /* ann_entry->ann_id = *ann_id = num_anns++; */
580 ann_entry->ann_id = HAregister_atom(ANIDGROUP,ann_node);
581 if (FAIL == ann_entry->ann_id)
582 HE_REPORT_GOTO("failed to insert annotation into ann_id Group", FAIL);
583
584 /* Check if data annotation to decode data tag/ref */
585 if(type != AN_FILE_LABEL && type != AN_FILE_DESC)
586 {
587 dptr = (uint8 *) &(datadi[0]);
588 UINT16DECODE(dptr, ann_entry->elmtag);
589 UINT16DECODE(dptr, ann_entry->elmref);
590 }
591 else
592 {
593 ann_entry->elmtag = ann_tag;
594 ann_entry->elmref = ann_ref;
595 }
596
597 /* Add annotation entry to 'type' tree */
598 if (tbbtdins(file_rec->an_tree[type], ann_entry, ann_key) == NULL)
599 HE_REPORT_GOTO("failed to insert annotation into 'type' tree", FAIL);
600
601 /* set read on next annotation */
602 more_anns = Hnextread(aid, ann_tag, DFREF_WILDCARD, DF_CURRENT);
603 } /* end for "more_anns" */
604
605 /* Finish access*/
606 if (FAIL != aid)
607 {
608 if (FAIL == Hendaccess(aid))
609 HGOTO_ERROR(DFE_INTERNAL, FAIL);
610 }
611
612 /* set return value */
613 ret_value = file_rec->an_num[type] = nanns;
614
615 done:
616 if(ret_value == FAIL)
617 { /* Error condition cleanup */
618 if (ann_key != NULL)
619 HDfree(ann_key);
620 if (ann_entry != NULL)
621 HDfree(ann_entry);
622 if (ann_node != NULL)
623 HDfree(ann_node);
624 if (FAIL != aid)
625 Hendaccess(aid);
626 } /* end if */
627
628 /* Normal function cleanup */
629
630 return ret_value;
631 } /* ANIcreate_ann_tree */
632
633 #if NOT_USED_YET
634 /*--------------------------------------------------------------------------
635 NAME
636 ANIfind -- find annotation id for given annotation type and ref number
637
638 DESCRIPTION
639 Find annotation id for the given annotation type and ref number
640
641 RETURNS
642 Annotation id if successful and FAIL (-1) otherwise
643
644 AUTHOR
645 GeorgeV.
646
647 -------------------------------------------------------------------------*/
648 PRIVATE int32
ANIfind(int32 an_id,ann_type type,uint16 ann_ref)649 ANIfind(int32 an_id, /* IN: annotation interface id */
650 ann_type type, /* IN: AN_DATA_LABEL for data labels,
651 AN_DATA_DESC for data descriptions,
652 AN_FILE_LABEL for file labels,
653 AN_FILE_DESC for file descritpions.*/
654 uint16 ann_ref /* IN: ref of annotation */)
655 {
656 CONSTR(FUNC, "ANIfind");
657 filerec_t *file_rec = NULL; /* file record pointer */
658 TBBT_NODE *entry = NULL;
659 ANentry *ann_entry = NULL;
660 int32 ann_key;
661 int32 ret_value = SUCCEED;
662
663 /* Clear error stack */
664 HEclear();
665
666 /* convert an_id i.e. file_id to file rec and check for validity */
667 file_rec = HAatom_object(an_id);
668 if (BADFREC(file_rec))
669 HGOTO_ERROR(DFE_ARGS, FAIL);
670
671 /* Check for empty annotation tree of 'type'? */
672 if (file_rec->an_num[type] == -1)
673 {
674 if ((file_rec->an_tree[type] =
675 (TBBT_TREE *) tbbtdmake(ANIanncmp,sizeof(int32),0)) == NULL)
676 {
677 HE_REPORT_GOTO("failed to create annotation tree", FAIL);
678 }
679
680 file_rec->an_num[type] = 0; /* intialize after allocation */
681 }
682
683 /* Create key from type/ref pair
684 * ----------------------------
685 * | type(16bits) | ref(16bits) |
686 * -----------------------------*/
687 ann_key = AN_CREATE_KEY(type, ann_ref);
688
689 /* See if annotation of 'type' with ref exits */
690 if ((entry = tbbtdfind(file_rec->an_tree[type], &ann_key, NULL)) == NULL)
691 HE_REPORT_GOTO("failed to find annotation of 'type'", FAIL);
692
693 /* get annotation entry from node */
694 ann_entry = (ANentry *) entry->data;
695
696 /* return annotation id */
697 ret_value = ann_entry->ann_id;
698
699 done:
700 if(ret_value == FAIL)
701 { /* Error condition cleanup */
702
703 } /* end if */
704
705 /* Normal function cleanup */
706
707 return ret_value;
708 } /* ANIfind */
709 #endif /* NOT_USED_YET */
710
711 /*--------------------------------------------------------------------------
712 NAME
713 ANInumann -- find number of annotation of 'type' that
714 match the given element tag/ref
715
716 DESCRIPTION
717 Find number of annotation of 'type' for the given element
718 tag/ref pair. Not used for file lables/descs since there
719 can only be one set of them for a file.
720
721 RETURNS
722 Number of annotation found if successful and FAIL (-1) otherwise
723
724 AUTHOR
725 GeorgeV.
726
727 -------------------------------------------------------------------------*/
728 PRIVATE intn
ANInumann(int32 an_id,ann_type type,uint16 elem_tag,uint16 elem_ref)729 ANInumann(int32 an_id, /* IN: annotation interface id */
730 ann_type type, /* IN: AN_DATA_LABEL for data labels,
731 AN_DATA_DESC for data descriptions,
732 AN_FILE_LABEL for file labels,
733 AN_FILE_DESC for file descritpions.*/
734 uint16 elem_tag, /* IN: tag of item of which this is annotation */
735 uint16 elem_ref /* IN: ref of item of which this is annotation */)
736 {
737 CONSTR(FUNC, "ANInumann");
738 filerec_t *file_rec = NULL; /* file record pointer */
739 TBBT_NODE *entry = NULL;
740 ANentry *ann_entry = NULL;
741 intn nanns = 0;
742 intn ret_value = SUCCEED;
743
744 /* Clear error stack */
745 HEclear();
746
747 /* convert an_id i.e. file_id to file rec and check for validity */
748 file_rec = HAatom_object(an_id);
749 if (BADFREC(file_rec))
750 HGOTO_ERROR(DFE_ARGS, FAIL);
751
752 /* Empty annotation tree */
753 if (file_rec->an_num[type] == -1)
754 {
755 if (ANIcreate_ann_tree(an_id, type) == FAIL)
756 HGOTO_ERROR(DFE_BADCALL, FAIL);
757 }
758
759 /* Traverse the list looking for a match */
760 for(entry = tbbtfirst((TBBT_NODE *)*(file_rec->an_tree[type]));
761 entry != NULL; entry = tbbtnext(entry))
762 {
763 ann_entry = (ANentry *) entry->data; /* get annotation entry from node */
764 if ((ann_entry->elmref == elem_ref) && (ann_entry->elmtag == elem_tag))
765 {
766 nanns++; /* increment ref counter if match */
767 }
768 }
769
770 /* return number of annotation references found for tag/ref */
771 ret_value = nanns;
772
773 done:
774 if(ret_value == FAIL)
775 { /* Error condition cleanup */
776
777 } /* end if */
778
779 /* Normal function cleanup */
780
781 return ret_value;
782 } /* ANInumann */
783
784 /*--------------------------------------------------------------------------
785 NAME
786 ANIannlist -- generate list of annotation ids of 'type' that
787 match the given element tag/ref
788
789 DESCRIPTION
790 Find and generate list of annotation ids of 'type' for the given
791 element tag/ref pair
792
793 RETURNS
794 number of annotations ids found if successful and FAIL (-1) otherwise
795
796 AUTHOR
797 GeorgeV.
798
799 ------------------------------------------------------------------------*/
800 PRIVATE intn
ANIannlist(int32 an_id,ann_type type,uint16 elem_tag,uint16 elem_ref,int32 ann_list[])801 ANIannlist(int32 an_id, /* IN: annotation interface id */
802 ann_type type, /* IN: AN_DATA_LABEL for data labels,
803 AN_DATA_DESC for data descriptions,
804 AN_FILE_LABEL for file labels,
805 AN_FILE_DESC for file descritpions.*/
806 uint16 elem_tag, /* IN: tag of item of which this is annotation*/
807 uint16 elem_ref, /* IN: ref of item of which this is annotation */
808 int32 ann_list[]/* OUT: array of ann_id's that match criteria. */)
809 {
810 CONSTR(FUNC, "ANIannlist");
811 filerec_t *file_rec = NULL; /* file record pointer */
812 TBBT_NODE *entry = NULL;
813 ANentry *ann_entry = NULL;
814 intn nanns = 0;
815 intn ret_value = SUCCEED;
816
817 /* Clear error stack */
818 HEclear();
819
820 /* convert an_id i.e. file_id to file rec and check for validity */
821 file_rec = HAatom_object(an_id);
822 if (BADFREC(file_rec))
823 HGOTO_ERROR(DFE_ARGS, FAIL);
824
825 /* Empty annotation tree */
826 if (file_rec->an_num[type] == -1)
827 {
828 if (ANIcreate_ann_tree(an_id, type) == FAIL)
829 HGOTO_ERROR(DFE_BADCALL, FAIL);
830 }
831
832 /* Traverse the list looking for a match */
833 for(entry = tbbtfirst((TBBT_NODE *)*(file_rec->an_tree[type]));
834 entry != NULL; entry = tbbtnext(entry))
835 {
836 ann_entry = (ANentry *) entry->data; /* get annotation entry from node */
837 if ((ann_entry->elmref == elem_ref) && (ann_entry->elmtag == elem_tag))
838 { /* save ref of ann match in list */
839 ann_list[nanns++] = ann_entry->ann_id;
840 }
841 }
842
843 /* return number of annotation id's found for tag/ref */
844 ret_value = nanns;
845
846 done:
847 if(ret_value == FAIL)
848 { /* Error condition cleanup */
849
850 } /* end if */
851
852 /* Normal function cleanup */
853
854 return ret_value;
855 } /* ANIannlist */
856
857 /*--------------------------------------------------------------------------
858 NAME
859 ANIannlen -- get length of annotation givne annotation id
860
861 DESCRIPTION
862 Uses the annotation id to find ann_key & file_id
863
864 RETURNS
865 length of annotation if successful and FAIL (-1) otherwise
866
867 AUTHOR
868 GeorgeV.
869
870 ------------------------------------------------------------------------*/
871 PRIVATE int32
ANIannlen(int32 ann_id)872 ANIannlen(int32 ann_id /* IN: annotation id */)
873 {
874 CONSTR(FUNC, "ANIannlen");
875 ANnode *ann_node = NULL;
876 int32 file_id = FAIL;
877 int32 type;
878 int32 ann_key;
879 uint16 ann_tag;
880 uint16 ann_ref;
881 int32 ann_length =(-1);
882 int32 ret_value = SUCCEED;
883
884 /* Clear error stack */
885 HEclear();
886
887 /* get annotation record */
888 ann_node = HAatom_object(ann_id);
889 if (NULL == ann_node)
890 HGOTO_ERROR(DFE_ARGS, FAIL);
891
892 /* get file id and annotation key */
893 file_id = ann_node->file_id;
894 ann_key = ann_node->ann_key;
895 type = AN_KEY2TYPE(ann_key);
896 ann_ref = AN_KEY2REF(ann_key);
897
898 /* Valid file id */
899 if (file_id == FAIL)
900 HE_REPORT_GOTO("bad file_id", FAIL);
901
902 /* set type annotation tag */
903 switch((int32)type)
904 {
905 case AN_DATA_LABEL:
906 ann_tag = DFTAG_DIL;
907 break;
908 case AN_DATA_DESC:
909 ann_tag = DFTAG_DIA;
910 break;
911 case AN_FILE_LABEL:
912 ann_tag = DFTAG_FID;
913 break;
914 case AN_FILE_DESC:
915 ann_tag = DFTAG_FD;
916 break;
917 default:
918 HE_REPORT_GOTO("Bad annotation type for this call",FAIL);
919 }
920
921 if (ann_tag == DFTAG_DIL || ann_tag == DFTAG_DIA)
922 { /* 4=length of data tag/ref for data label or description */
923 if ((ann_length = Hlength(file_id, ann_tag, ann_ref)) == FAIL)
924 HE_REPORT_GOTO("Failed to find annotation length", FAIL);
925 ann_length -= 4;
926 }
927 else if (ann_tag == DFTAG_FID || ann_tag == DFTAG_FD)
928 { /* not data tag/ref for file label or description */
929 if ((ann_length = Hlength(file_id, ann_tag, ann_ref)) == FAIL)
930 HE_REPORT_GOTO("Failed to find annotation length", FAIL);
931 }
932
933 /* return the length */
934 ret_value = (ann_length);
935
936 done:
937 if(ret_value == FAIL)
938 { /* Error condition cleanup */
939
940 } /* end if */
941
942 /* Normal function cleanup */
943
944 return ret_value;
945 } /* ANIannlen */
946
947 /*--------------------------------------------------------------------------
948 NAME
949 ANIreadann -- read annotation given ann_id
950
951 DESCRIPTION
952 Gets tag and ref of annotation. Finds DD for that annotation.
953 Reads the annotation, taking care of NULL terminator, if necessary.
954
955 RETURNS
956 SUCCEED (0) if successful and FAIL (-1) otherwise
957
958 AUTHOR
959 GeorgeV.
960
961 ------------------------------------------------------------------------*/
962 PRIVATE intn
ANIreadann(int32 ann_id,char * ann,int32 maxlen)963 ANIreadann(int32 ann_id, /* IN: annotation id (handle) */
964 char *ann, /* OUT: space to return annotation in */
965 int32 maxlen /* IN: size of space to return annotation in */)
966 {
967 CONSTR(FUNC, "ANIreadann");
968 ANnode *ann_node = NULL;
969 int32 file_id = FAIL;
970 int32 type;
971 int32 ann_key;
972 int32 aid = FAIL;
973 int32 ann_len;
974 uint16 ann_tag;
975 uint16 ann_ref;
976 uint8 datadi[4] = {0,0,0,0}; /* to read in and discard data/ref! */
977 intn ret_value = SUCCEED;
978
979 /* Clear error stack */
980 HEclear();
981
982 /* get annotation record */
983 ann_node = HAatom_object(ann_id);
984 if (NULL == ann_node)
985 HGOTO_ERROR(DFE_ARGS, FAIL);
986
987 /* get file id and annotation key */
988 file_id = ann_node->file_id;
989 ann_key = ann_node->ann_key;
990 type = AN_KEY2TYPE(ann_key);
991 ann_ref = AN_KEY2REF(ann_key);
992
993 /* Valid file id */
994 if (file_id == FAIL)
995 HE_REPORT_GOTO("bad file_id", FAIL);
996
997 /* set type tag */
998 switch((int32)type)
999 {
1000 case AN_DATA_LABEL:
1001 ann_tag = DFTAG_DIL;
1002 break;
1003 case AN_DATA_DESC:
1004 ann_tag = DFTAG_DIA;
1005 break;
1006 case AN_FILE_LABEL:
1007 ann_tag = DFTAG_FID;
1008 break;
1009 case AN_FILE_DESC:
1010 ann_tag = DFTAG_FD;
1011 break;
1012 default:
1013 HE_REPORT_GOTO("Bad annotation type for this call",FAIL);
1014 }
1015
1016 /* find DD for that annotation using tag/ref */
1017 aid = Hstartread(file_id, ann_tag, ann_ref);
1018 if (aid == FAIL)
1019 HE_REPORT_GOTO("Failed to get access to annotation",FAIL);
1020
1021 if (FAIL == Hinquire(aid, (int32 *) NULL, (uint16 *) NULL, (uint16 *) NULL,
1022 &ann_len, (int32 *) NULL, (int32 *) NULL,
1023 (int16 *) NULL, (int16 *) NULL))
1024 {
1025 HE_REPORT_GOTO("Failed to get annotation",FAIL);
1026 }
1027
1028 /* first four bytes were tag/ref if data annotation, so they don't count */
1029 if (ann_tag == DFTAG_DIL || ann_tag == DFTAG_DIA)
1030 ann_len -= 4;
1031 #ifdef AN_DEBUG
1032 printf("ANIreadann: from Hinquire, ann_len=%d, maxlen=%d\n",
1033 ann_len, maxlen);
1034 #endif
1035 /* Check length of space provided
1036 * if not enough space, truncate annotation
1037 * Labels need space for null terminator, Descriptions don't */
1038 if (ann_tag == DFTAG_FID || ann_tag == DFTAG_DIL)
1039 { /* Labels */
1040 if (ann_len > maxlen - 1)
1041 ann_len = maxlen - 1;
1042 }
1043 else
1044 { /* Descriptions */
1045 if (ann_len > maxlen)
1046 ann_len = maxlen;
1047 }
1048
1049 /* If data label or description need to read past tag/ref */
1050 if (ann_tag == DFTAG_DIL || ann_tag == DFTAG_DIA)
1051 { /* Data label/description */
1052 if ((int32) FAIL == Hread(aid, (int32) 4, datadi))
1053 HE_REPORT_GOTO("Failed to go past tag/ref",FAIL);
1054 }
1055
1056 /* read itslef annotation now..*/
1057 if ((int32) FAIL == Hread(aid, ann_len, ann))
1058 HE_REPORT_GOTO("Failed to read annotation",FAIL);
1059
1060 /* If Label need to NULL terminate string */
1061 if (ann_tag == DFTAG_FID || ann_tag == DFTAG_DIL)
1062 ann[ann_len] = '\0';
1063 #ifdef AN_DEBUG
1064 printf("ANIreadann: ann_len=%d, ann=%s\n", ann_len,ann);
1065 #endif
1066 /* Close access to annotation object */
1067 if (FAIL != aid)
1068 {
1069 if (FAIL == Hendaccess(aid))
1070 HGOTO_ERROR(DFE_INTERNAL, FAIL);
1071 }
1072
1073 done:
1074 if(ret_value == FAIL)
1075 { /* Error condition cleanup */
1076 if (FAIL != aid)
1077 Hendaccess(aid);
1078 } /* end if */
1079
1080 /* Normal function cleanup */
1081
1082 return ret_value;
1083 } /* ANIreadann */
1084
1085 /*--------------------------------------------------------------------------
1086 NAME
1087 ANIwriteann -- write annotation given ann_id
1088
1089 DESCRIPTION
1090 Checks for pre-existence of given annotation, replacing old one if it
1091 exists. Writes out annotation.
1092
1093 RETURNS
1094 SUCCEED (0) if successful and FAIL (-1) otherwise
1095
1096 AUTHOR
1097 GeorgeV.
1098
1099 ------------------------------------------------------------------------*/
1100 PRIVATE intn
ANIwriteann(int32 ann_id,const char * ann,int32 ann_len)1101 ANIwriteann(int32 ann_id, /* IN: annotation id */
1102 const char *ann, /* IN: annotation to write */
1103 int32 ann_len /* IN: length of annotation */)
1104 {
1105 CONSTR(FUNC, "ANIwriteann");
1106 filerec_t *file_rec = NULL; /* file record pointer */
1107 TBBT_NODE *entry = NULL;
1108 ANentry *ann_entry = NULL;
1109 ANnode *ann_node = NULL;
1110 int32 file_id = FAIL;
1111 int32 type;
1112 int32 ann_key;
1113 int32 aid = FAIL;
1114 int newflag = 0;
1115 uint16 ann_tag;
1116 uint16 ann_ref;
1117 uint16 elem_tag;
1118 uint16 elem_ref;
1119 uint8 datadi[4] = {0,0,0,0}; /* to hold data tag/ref for writing */
1120 uint8 *ptr = NULL;
1121 intn ret_value = SUCCEED;
1122
1123 /* Clear error stack */
1124 HEclear();
1125
1126 /* get annotation record */
1127 ann_node = HAatom_object(ann_id);
1128 if (NULL == ann_node)
1129 HGOTO_ERROR(DFE_ARGS, FAIL);
1130
1131 /* get file id and annotation key */
1132 file_id = ann_node->file_id;
1133 ann_key = ann_node->ann_key;
1134 type = AN_KEY2TYPE(ann_key);
1135 ann_ref = AN_KEY2REF(ann_key);
1136
1137 /* convert file_id to file rec and check for validity */
1138 file_rec = HAatom_object(file_id);
1139 if (BADFREC(file_rec))
1140 HGOTO_ERROR(DFE_INTERNAL, FAIL);
1141
1142 /* set type tag */
1143 switch((int32)type)
1144 {
1145 case AN_DATA_LABEL:
1146 ann_tag = DFTAG_DIL;
1147 break;
1148 case AN_DATA_DESC:
1149 ann_tag = DFTAG_DIA;
1150 break;
1151 case AN_FILE_LABEL:
1152 ann_tag = DFTAG_FID;
1153 break;
1154 case AN_FILE_DESC:
1155 ann_tag = DFTAG_FD;
1156 break;
1157 default:
1158 HE_REPORT_GOTO("Bad annotation type for this call",FAIL);
1159 }
1160
1161 /* Get annotation entry so that we can extract tag/ref of element
1162 * Note that for file labels and descriptions the tag/ref contain
1163 * DFTAG_XXX and annotation reference number */
1164 if ((entry = tbbtdfind(file_rec->an_tree[type], &ann_key, NULL)) == NULL)
1165 HE_REPORT_GOTO("failed to retrieve annotation of 'type' tree", FAIL);
1166
1167 ann_entry = (ANentry *) entry->data;
1168
1169 elem_tag = ann_entry->elmtag;
1170 elem_ref = ann_entry->elmref;
1171 newflag = ann_node->new_ann;
1172
1173 /* is this a new annotation */
1174 if (newflag == 1)
1175 {
1176 ann_node->new_ann = 0; /* set new annotation entry to false */
1177 }
1178
1179 /* If annotation exists, re-used the DD and rewrite new annotation
1180 while preserving tag/ref. We assume annotations are not stored
1181 as linked-blocks for now. */
1182 if (newflag == 0)
1183 { /* annotation exists in file, re-writing */
1184 /* Not new, re-used the tag/ref(i.e. DD) for new annotation.
1185 pointer to old annotation is lost. */
1186 if (HDreuse_tagref(file_id, ann_tag, ann_ref) == FAIL)
1187 HE_REPORT_GOTO("Unable to replace old annotation",FAIL);
1188 }
1189
1190 if (ann_tag == DFTAG_DIL || ann_tag == DFTAG_DIA)
1191 { /* Data label/description
1192 * Note: cannot use Hputelement because need to write data tag/ref */
1193 aid = Hstartwrite(file_id, ann_tag, ann_ref, ann_len + 4);
1194 if (aid == FAIL)
1195 HE_REPORT_GOTO("Failed to start write access on annotation",FAIL);
1196
1197 /* Setup up to write annotation tag/ref */
1198 ptr = (uint8 *) &(datadi[0]); /* first, write the object's tag/ref */
1199 UINT16ENCODE(ptr, elem_tag);
1200 UINT16ENCODE(ptr, elem_ref);
1201
1202 /* write annotation tag/ref of element */
1203 if ((int32) FAIL == Hwrite(aid, (int32) 4, datadi))
1204 HE_REPORT_GOTO("Failed to write tag/ref of annotation",FAIL);
1205
1206 #ifdef AN_DEBUG
1207 printf("ANIwriteann: ann_len=%d, ann=%s\n", ann_len,ann);
1208 #endif
1209 /* then write the annotation itself */
1210 if ((int32) FAIL == Hwrite(aid, ann_len, ann))
1211 HE_REPORT_GOTO("Failed to write annotation",FAIL);
1212
1213 /* end access to annotation */
1214 if (FAIL == Hendaccess(aid))
1215 HE_REPORT_GOTO("Failed to end access to annotation",FAIL);
1216 }
1217 else /* file label/description */
1218 {
1219 /* write out file label/description */
1220 if (FAIL == Hputelement(file_id, ann_tag, ann_ref, (const uint8 *)ann, ann_len))
1221 HE_REPORT_GOTO("Failed to write file annotation",FAIL);
1222 #ifdef AN_DEBUG
1223 printf("ANIwriteann: fann_len=%d, fann=%s\n", ann_len,ann);
1224 #endif
1225 }
1226
1227 done:
1228 if(ret_value == FAIL)
1229 { /* Error condition cleanup */
1230 if (FAIL != aid)
1231 Hendaccess(aid);
1232 } /* end if */
1233
1234 /* Normal function cleanup */
1235
1236 return ret_value;
1237 } /* ANIwriteann */
1238
1239 /* ------------------------------- ANIcreate -------------------------------
1240 NAME
1241 ANIcreate - create a new annotation and return a handle(id)
1242
1243 DESCRIPTION
1244 Creates an annotation, returns an 'an_id' to work with the new
1245 annotation which can either be a label or description.
1246
1247 RETURNS
1248 An ID to an annotation which can either be a label or description
1249
1250 AUTHOR
1251 GeorgeV.
1252
1253 --------------------------------------------------------------------------- */
1254 PRIVATE intn
ANIcreate(int32 file_id,uint16 elem_tag,uint16 elem_ref,ann_type type)1255 ANIcreate(int32 file_id, /* IN: file ID */
1256 uint16 elem_tag, /* IN: tag of item to be assigned annotation */
1257 uint16 elem_ref, /* IN: reference number of itme to be assigned ann */
1258 ann_type type /* IN: AN_DATA_LABEL for data labels,
1259 AN_DATA_DESC for data descriptions,
1260 AN_FILE_LABEL for file labels,
1261 AN_FILE_DESC for file descritpions.*/)
1262 {
1263 CONSTR(FUNC, "ANIcreate"); /* for HERROR */
1264 int32 ann_id = FAIL;
1265 uint16 ann_tag;
1266 uint16 ann_ref;
1267 intn ret_value = SUCCEED;
1268
1269 /* Clear error stack */
1270 HEclear();
1271
1272 /* Valid file id */
1273 if (HAatom_group(file_id) != FIDGROUP)
1274 HGOTO_ERROR(DFE_ARGS, FAIL);
1275
1276 /* deal with type */
1277 switch((ann_type)type)
1278 {
1279 case AN_DATA_LABEL:
1280 ann_tag = DFTAG_DIL;
1281 ann_ref = Htagnewref(file_id,ann_tag);
1282 break;
1283 case AN_DATA_DESC:
1284 ann_tag = DFTAG_DIA;
1285 ann_ref = Htagnewref(file_id,ann_tag);
1286 break;
1287 case AN_FILE_LABEL:
1288 /* for file label set elmement tag/ref to ann_tag & ref */
1289 ann_tag = DFTAG_FID;
1290 ann_ref = Htagnewref(file_id,ann_tag);
1291 elem_tag = ann_tag;
1292 elem_ref = ann_ref;
1293 break;
1294 case AN_FILE_DESC:
1295 /* for file desc set elmement tag/ref to ann_tag & ref */
1296 ann_tag = DFTAG_FD;
1297 ann_ref = Htagnewref(file_id,ann_tag);
1298 elem_tag = ann_tag;
1299 elem_ref = ann_ref;
1300 break;
1301 default:
1302 HE_REPORT_GOTO("Bad annotation type for this call",FAIL);
1303 }
1304
1305 /* Check tag and ref */
1306 if (!elem_tag)
1307 HGOTO_ERROR(DFE_BADTAG, FAIL);
1308 if (!elem_ref)
1309 HGOTO_ERROR(DFE_BADREF, FAIL);
1310
1311 /* put new annotation tag/ref into 'type' TBBTtree */
1312 if ((ann_id = ANIaddentry(file_id, type, ann_ref, elem_tag, elem_ref, 1)) == FAIL)
1313 HE_REPORT_GOTO("Failed to add annotation to TBBT tree",FAIL);
1314
1315 ret_value = ann_id;
1316
1317 done:
1318 if(ret_value == FAIL)
1319 { /* Error condition cleanup */
1320
1321 } /* end if */
1322
1323 /* Normal function cleanup */
1324
1325 return ret_value;
1326 } /* ANIcreate() */
1327
1328 /* --------------------- Exported Multi-file Interface ----------------------*/
1329
1330 /* ------------------------------- ANstart --------------------------------
1331 NAME
1332 ANstart -- open file for annotation handling
1333
1334 DESCRIPTION
1335 Start annotation handling on the file return a annotation ID to the file.
1336
1337 RETURNS
1338 A file ID or FAIL. Note that we use 'an_id' which is the same
1339 as the file id.
1340
1341 AUTHOR
1342 GeorgeV.
1343
1344 --------------------------------------------------------------------------- */
1345 EXPORT int32
ANstart(int32 file_id)1346 ANstart(int32 file_id /* IN: file to start annotation access on*/)
1347 {
1348 CONSTR(FUNC, "ANstart");
1349 filerec_t *file_rec = NULL; /* file record pointer */
1350 int32 ret_value = SUCCEED;
1351
1352 /* Clear error stack */
1353 HEclear();
1354
1355 /* convert file id to file rec and check for validity */
1356 file_rec = HAatom_object(file_id);
1357 if (BADFREC(file_rec))
1358 HGOTO_ERROR(DFE_ARGS, FAIL);
1359
1360 /* call ANIinit, should just register termination function once
1361 no matter how many times it is called. */
1362 ANIinit();
1363
1364 ret_value = file_id;
1365
1366 done:
1367 if(ret_value == FAIL)
1368 { /* Error condition cleanup */
1369 } /* end if */
1370
1371 /* Normal function cleanup */
1372 return ret_value;
1373 } /* ANstart() */
1374
1375 /*--------------------------------------------------------------------------
1376 NAME
1377 ANfileinfo - Report high-level information about the ANxxx interface
1378 for a given file.
1379
1380 DESCRIPTION
1381 Reports general information about the number of file and object(i.e. data)
1382 annotations in the file. This routine is generally used to find
1383 the range of acceptable indices for ANselect calls.
1384
1385 RETURNS
1386 SUCCEED/FAIL
1387
1388 AUTHOR
1389 GeorgeV.
1390
1391 --------------------------------------------------------------------------*/
1392 EXPORT intn
ANfileinfo(int32 an_id,int32 * n_file_label,int32 * n_file_desc,int32 * n_obj_label,int32 * n_obj_desc)1393 ANfileinfo(int32 an_id, /* IN: annotation interface id */
1394 int32 *n_file_label, /* OUT: the # of file labels */
1395 int32 *n_file_desc, /* OUT: the # of file descriptions */
1396 int32 *n_obj_label, /* OUT: the # of object labels */
1397 int32 *n_obj_desc /* OUT: the # of object descriptions */)
1398 {
1399 CONSTR(FUNC, "ANfileinfo"); /* for HERROR */
1400 filerec_t *file_rec = NULL; /* file record pointer */
1401 intn ret_value = SUCCEED;
1402
1403 /* Clear error stack */
1404 HEclear();
1405
1406 /* convert an_id i.e. file_id to file rec and check for validity */
1407 file_rec = HAatom_object(an_id);
1408 if (BADFREC(file_rec))
1409 HGOTO_ERROR(DFE_ARGS, FAIL);
1410
1411 /* Empty file label annotation tree? */
1412 if (file_rec->an_num[AN_FILE_LABEL] == -1)
1413 {
1414 if ((*n_file_label = ANIcreate_ann_tree(an_id, AN_FILE_LABEL)) == FAIL)
1415 HE_REPORT_GOTO("failed to create file label annotation TBBTtree", FAIL);
1416 }
1417 else
1418 *n_file_label = file_rec->an_num[AN_FILE_LABEL];
1419
1420 /* Empty file descritpiton annotation tree? */
1421 if (file_rec->an_num[AN_FILE_DESC] == -1)
1422 {
1423 if ((*n_file_desc = ANIcreate_ann_tree(an_id, AN_FILE_DESC)) == FAIL)
1424 HE_REPORT_GOTO("failed to create file desc annotation TBBTtree", FAIL);
1425 }
1426 else
1427 *n_file_desc = file_rec->an_num[AN_FILE_DESC];
1428
1429 /* Empty label annotation tree? */
1430 if (file_rec->an_num[AN_DATA_LABEL] == -1)
1431 {
1432 if ((*n_obj_label = ANIcreate_ann_tree(an_id, AN_DATA_LABEL)) == FAIL)
1433 HE_REPORT_GOTO("failed to create data label annotation TBBTtree", FAIL);
1434 }
1435 else
1436 *n_obj_label = file_rec->an_num[AN_DATA_LABEL];
1437
1438 /* Empty descritpiton annotation tree? */
1439 if (file_rec->an_num[AN_DATA_DESC] == -1)
1440 {
1441 if ((*n_obj_desc = ANIcreate_ann_tree(an_id, AN_DATA_DESC)) == FAIL)
1442 HE_REPORT_GOTO("failed to create data desc annotation TBBTtree", FAIL);
1443 }
1444 else
1445 *n_obj_desc = file_rec->an_num[AN_DATA_DESC];
1446
1447 done:
1448 if(ret_value == FAIL)
1449 { /* Error condition cleanup */
1450
1451 } /* end if */
1452
1453 /* Normal function cleanup */
1454 return ret_value;
1455 } /* ANfileinfo() */
1456
1457 /* -------------------------------- ANend ---------------------------------
1458 NAME
1459 ANend -- End annotation access to file file
1460
1461 DESCRIPTION
1462 End annotation access to file.
1463
1464 RETURNS
1465 SUCCEED / FAIL
1466 --------------------------------------------------------------------------- */
1467 EXPORT int32
ANend(int32 an_id)1468 ANend(int32 an_id /* IN: Annotation ID of file to close */)
1469 {
1470 CONSTR(FUNC,"ANend");
1471 filerec_t *file_rec = NULL; /* file record pointer */
1472 TBBT_NODE *aentry = NULL;
1473 ANentry *ann_entry = NULL;
1474 ANnode *ann_node = NULL;
1475 int32 ret_value = SUCCEED;
1476
1477 /* Clear error stack */
1478 HEclear();
1479
1480 /* convert an_id i.e. file_id to file rec and check for validity */
1481 file_rec = HAatom_object(an_id);
1482 if (BADFREC(file_rec))
1483 HGOTO_ERROR(DFE_ARGS, FAIL);
1484
1485 /* NEED to delete trees of annotations attached to node
1486 * NOTE: This could be written shorter using a for loop....
1487 * or something.... */
1488
1489 /* free file label annotation rb tree */
1490 if (file_rec->an_tree[AN_FILE_LABEL] != NULL)
1491 { /* Traverse tree puling ann_id's to delete from annotation atom group */
1492 for(aentry = tbbtfirst((TBBT_NODE *)*(file_rec->an_tree[AN_FILE_LABEL]));
1493 aentry != NULL;
1494 aentry = tbbtnext(aentry))
1495 { /* get annotation entry from node */
1496 ann_entry = (ANentry *) aentry->data;
1497
1498 /* delete annotation node from annotation group */
1499 if(NULL == (ann_node = HAremove_atom(ann_entry->ann_id)))
1500 HE_REPORT_GOTO("Failed to remove annotation with ann_id", FAIL);
1501
1502 if(ann_node != NULL)
1503 HDfree(ann_node); /* free node */
1504 } /* end for 'entry */
1505 /* finally free tree */
1506 tbbtdfree(file_rec->an_tree[AN_FILE_LABEL], ANfreedata, ANfreekey);
1507 }
1508
1509 /* free file desc annotation rb tree */
1510 if (file_rec->an_tree[AN_FILE_DESC] != NULL)
1511 { /* Traverse tree puling ann_id's to delete from annotation atom group */
1512 for(aentry = tbbtfirst((TBBT_NODE *)*(file_rec->an_tree[AN_FILE_DESC]));
1513 aentry != NULL;
1514 aentry = tbbtnext(aentry))
1515 { /* get annotation entry from node */
1516 ann_entry = (ANentry *) aentry->data;
1517
1518 /* delete annotation node from annotation group */
1519 if(NULL == (ann_node = HAremove_atom(ann_entry->ann_id)))
1520 HE_REPORT_GOTO("Failed to remove annotation with ann_id", FAIL);
1521
1522 if(ann_node != NULL)
1523 HDfree(ann_node); /* free node */
1524
1525 } /* end for 'entry */
1526 /* finally free tree */
1527 tbbtdfree(file_rec->an_tree[AN_FILE_DESC], ANfreedata, ANfreekey);
1528 }
1529
1530 /* free label annotation rb tree */
1531 if (file_rec->an_tree[AN_DATA_LABEL] != NULL)
1532 { /* Traverse tree puling ann_id's to delete from annotation atom group */
1533 for(aentry = tbbtfirst((TBBT_NODE *)*(file_rec->an_tree[AN_DATA_LABEL]));
1534 aentry != NULL;
1535 aentry = tbbtnext(aentry))
1536 { /* get annotation entry from node */
1537 ann_entry = (ANentry *) aentry->data;
1538
1539 /* delete annotation node from annotation group */
1540 if(NULL == (ann_node = HAremove_atom(ann_entry->ann_id)))
1541 HE_REPORT_GOTO("Failed to remove annotation with ann_id", FAIL);
1542
1543 if(ann_node != NULL)
1544 HDfree(ann_node); /* free node */
1545 } /* end for 'entry */
1546 /* finally free tree */
1547 tbbtdfree(file_rec->an_tree[AN_DATA_LABEL], ANfreedata, ANfreekey);
1548 }
1549
1550 /* free desc annotation rb tree */
1551 if (file_rec->an_tree[AN_DATA_DESC] != NULL)
1552 { /* Traverse tree puling ann_id's to delete from annotation atom group */
1553 for(aentry = tbbtfirst((TBBT_NODE *)*(file_rec->an_tree[AN_DATA_DESC]));
1554 aentry != NULL;
1555 aentry = tbbtnext(aentry))
1556 { /* get annotation entry from node */
1557 ann_entry = (ANentry *) aentry->data;
1558
1559 /* delete annotation node from annotation group */
1560 if(NULL == (ann_node = HAremove_atom(ann_entry->ann_id)))
1561 HE_REPORT_GOTO("Failed to remove annotation with ann_id", FAIL);
1562
1563 if(ann_node != NULL)
1564 HDfree(ann_node); /* free node */
1565
1566 } /* end for 'entry */
1567 /* finally free tree */
1568 tbbtdfree(file_rec->an_tree[AN_DATA_DESC], ANfreedata, ANfreekey);
1569 }
1570
1571 /* re-initalize everything in file record for annotations so
1572 the a ANstart() works. */
1573 file_rec->an_tree[AN_DATA_LABEL] = NULL;
1574 file_rec->an_tree[AN_DATA_DESC] = NULL;
1575 file_rec->an_tree[AN_FILE_LABEL] = NULL;
1576 file_rec->an_tree[AN_FILE_DESC] = NULL;
1577 file_rec->an_num[AN_DATA_LABEL] = -1;
1578 file_rec->an_num[AN_DATA_DESC] = -1;
1579 file_rec->an_num[AN_FILE_LABEL] = -1;
1580 file_rec->an_num[AN_FILE_DESC] = -1;
1581
1582 done:
1583 if(ret_value == FAIL)
1584 { /* Error condition cleanup */
1585
1586 } /* end if */
1587
1588 /* Normal function cleanup */
1589 return ret_value;
1590 } /* ANend() */
1591
1592 /* ------------------------------------------------------------------------
1593 NAME
1594 ANcreate - create a new element annotation and return a handle(id)
1595
1596 DESCRIPTION
1597 Creates a data annotation, returns an 'an_id' to work with the new
1598 annotation which can either be a label or description.
1599
1600 RETURNS
1601 An ID to an annotation which can either be a label or description
1602
1603 AUTHOR
1604 GeorgeV.
1605
1606 --------------------------------------------------------------------------- */
1607 EXPORT int32
ANcreate(int32 an_id,uint16 elem_tag,uint16 elem_ref,ann_type type)1608 ANcreate(int32 an_id, /* IN: annotation interface ID */
1609 uint16 elem_tag, /* IN: tag of item to be assigned annotation */
1610 uint16 elem_ref, /* IN: reference number of itme to be assigned ann */
1611 ann_type type /* IN: AN_DATA_LABEL for data labels,
1612 AN_DATA_DESC for data descriptions*/)
1613 {
1614 #ifdef LATER
1615 CONSTR(FUNC, "ANcreate"); /* for HERROR */
1616 #endif /* LATER */
1617 int32 ret_value;
1618
1619 ret_value = (ANIcreate(an_id, elem_tag, elem_ref, type));
1620
1621 return ret_value;
1622 } /* ANcreate() */
1623
1624 /* ------------------------------------------------------------------------
1625 NAME
1626 ANcreatef - create a new file annotation and return a handle(id)
1627
1628 DESCRIPTION
1629 Creates a file annotation, returns an 'an_id' to work with the new
1630 file annotation which can either be a label or description.
1631
1632 RETURNS
1633 An ID to an annotation which can either be a file label or description
1634
1635 AUTHOR
1636 GeorgeV.
1637
1638 --------------------------------------------------------------------------- */
1639 EXPORT int32
ANcreatef(int32 an_id,ann_type type)1640 ANcreatef(int32 an_id,/* IN: annotation interface ID */
1641 ann_type type /* IN: AN_FILE_LABEL for file labels,
1642 AN_FILE_DESC for file descritpions.*/)
1643 {
1644 #ifdef LATER
1645 CONSTR(FUNC, "ANcreatef"); /* for HERROR */
1646 #endif /* LATER */
1647 uint16 ann_tag;
1648 uint16 ann_ref;
1649 int32 ret_value = SUCCEED;
1650
1651 /* deal with type */
1652 switch((ann_type)type)
1653 {
1654 case AN_FILE_LABEL:
1655 ann_tag = DFTAG_FID;
1656 ann_ref = 0; /* initalize with invalid ref,
1657 will be replaced in ANIcreate() */
1658 break;
1659 case AN_FILE_DESC:
1660 ann_tag = DFTAG_FD;
1661 ann_ref = 0; /* initialize with invalid ref,
1662 will be replaced in ANIcreate() */
1663 break;
1664 default:
1665 HE_REPORT_GOTO("Bad annotation type for this call",FAIL);
1666 }
1667
1668 ret_value = ANIcreate(an_id, ann_tag, ann_ref, type);
1669
1670 done:
1671 if(ret_value == FAIL)
1672 { /* Error condition cleanup */
1673
1674 } /* end if */
1675
1676 /* Normal function cleanup */
1677 return ret_value;
1678 } /* ANcreateann() */
1679
1680 /* ------------------------------- ANselect -------------------------------
1681 NAME
1682 ANselect -- get an annotation ID from index of 'type'
1683
1684 DESCRIPTION
1685 The position index is ZERO based
1686
1687 RETURNS
1688 An ID to an annotation type which can either be a label or description
1689
1690 AUTHOR
1691 GeorgeV.
1692
1693 --------------------------------------------------------------------------- */
1694 EXPORT int32
ANselect(int32 an_id,int32 index,ann_type type)1695 ANselect(int32 an_id, /* IN: annotation interface ID */
1696 int32 index, /* IN: index of annottion to get ID for */
1697 ann_type type /* IN: AN_DATA_LABEL for data labels,
1698 AN_DATA_DESC for data descriptions,
1699 AN_FILE_LABEL for file labels,
1700 AN_FILE_DESC for file descritpions.*/)
1701 {
1702 CONSTR(FUNC, "ANselect"); /* for HERROR */
1703 filerec_t *file_rec = NULL; /* file record pointer */
1704 TBBT_NODE *entry = NULL;
1705 ANentry *ann_entry = NULL;
1706 int32 ret_value = SUCCEED;
1707
1708 /* Clear error stack */
1709 HEclear();
1710
1711 /* convert an_id i.e. file_id to file rec and check for validity */
1712 file_rec = HAatom_object(an_id);
1713 if (BADFREC(file_rec))
1714 HGOTO_ERROR(DFE_ARGS, FAIL);
1715
1716 /* Empty annotation tree */
1717 if (file_rec->an_num[type] == -1)
1718 {
1719 if (ANIcreate_ann_tree(an_id, type) == FAIL)
1720 HGOTO_ERROR(DFE_BADCALL, FAIL);
1721 }
1722
1723 /* check index and adjust to 1 based for tbbtindx()*/
1724 if(index >= 0 && index < file_rec->an_num[type])
1725 index++;
1726 else
1727 HE_REPORT_GOTO("bad index", FAIL);
1728
1729 /* find 'index' entry */
1730 if ((entry = tbbtindx((TBBT_NODE *)*(file_rec->an_tree[type]), index)) == NULL)
1731 HE_REPORT_GOTO("failed to find 'index' entry", FAIL);
1732
1733 ann_entry = (ANentry *) entry->data;
1734
1735 /* return ann_id */
1736 ret_value = ann_entry->ann_id;
1737
1738 done:
1739 if(ret_value == FAIL)
1740 { /* Error condition cleanup */
1741
1742 } /* end if */
1743
1744 /* Normal function cleanup */
1745 return ret_value;
1746 } /* ANselect() */
1747
1748 /*--------------------------------------------------------------------------
1749 NAME
1750 ANnumann -- find number of annotation of 'type' that
1751 match the given element tag/ref
1752
1753 DESCRIPTION
1754 Find number of annotation of 'type' for the given element
1755 tag/ref pair. Should not be used for File labels and
1756 descriptions.
1757
1758 RETURNS
1759 Number of annotations found if successful and FAIL (-1) otherwise.
1760
1761 AUTHOR
1762 GeorgeV.
1763
1764 ------------------------------------------------------------------------*/
1765 EXPORT intn
ANnumann(int32 an_id,ann_type type,uint16 elem_tag,uint16 elem_ref)1766 ANnumann(int32 an_id, /* IN: annotation interface id */
1767 ann_type type, /* IN: AN_DATA_LABEL for data labels,
1768 AN_DATA_DESC for data descriptions,
1769 AN_FILE_LABEL for file labels,
1770 AN_FILE_DESC for file descritpions.*/
1771 uint16 elem_tag, /* IN: tag of item of which this is annotation */
1772 uint16 elem_ref /* IN: ref of item of which this is annotation */ )
1773 {
1774 CONSTR(FUNC, "ANnumann");
1775 intn ret_value = SUCCEED;
1776
1777 /* deal with invalid types */
1778 if(type == AN_FILE_LABEL || type == AN_FILE_DESC)
1779 HGOTO_ERROR(DFE_ARGS, FAIL);
1780
1781 ret_value = ANInumann(an_id, type, elem_tag, elem_ref);
1782
1783 done:
1784 if(ret_value == FAIL)
1785 { /* Error condition cleanup */
1786
1787 } /* end if */
1788
1789 /* Normal function cleanup */
1790
1791 return ret_value;
1792 } /* ANnumann() */
1793
1794 /*--------------------------------------------------------------------------
1795 NAME
1796 ANannlist -- generate list of annotation ids of 'type' that
1797 match the given element tag/ref
1798
1799 DESCRIPTION
1800 Find and generate list of annotation ids of 'type' for the given
1801 element tag/ref pair. Should not be used for File labels and
1802 descriptions.
1803
1804 RETURNS
1805 Number of annotations ids found if successful and FAIL (-1) otherwise
1806
1807 AUTHOR
1808 GeorgeV.
1809
1810 ------------------------------------------------------------------------*/
1811 EXPORT intn
ANannlist(int32 an_id,ann_type type,uint16 elem_tag,uint16 elem_ref,int32 ann_list[])1812 ANannlist(int32 an_id, /* IN: annotation interface id */
1813 ann_type type, /* IN: AN_DATA_LABEL for data labels,
1814 AN_DATA_DESC for data descriptions,
1815 AN_FILE_LABEL for file labels,
1816 AN_FILE_DESC for file descritpions.*/
1817 uint16 elem_tag, /* IN: tag of item of which this is annotation */
1818 uint16 elem_ref, /* IN: ref of item of which this is annotation */
1819 int32 ann_list[] /* OUT: array of ann_id's that match criteria. */)
1820 {
1821 CONSTR(FUNC, "ANannlist");
1822 intn ret_value = SUCCEED;
1823
1824 /* deal with invalid types */
1825 if(type == AN_FILE_LABEL || type == AN_FILE_DESC)
1826 HGOTO_ERROR(DFE_ARGS, FAIL);
1827
1828 ret_value = ANIannlist(an_id, type, elem_tag, elem_ref, ann_list);
1829
1830 done:
1831 if(ret_value == FAIL)
1832 { /* Error condition cleanup */
1833
1834 } /* end if */
1835
1836 /* Normal function cleanup */
1837
1838 return ret_value;
1839 } /* ANannlist() */
1840
1841 /*--------------------------------------------------------------------------
1842 NAME
1843 ANannlen -- get length of annotation givne annotation id
1844
1845 DESCRIPTION
1846 Uses the annotation id to find ann_key & file_id
1847
1848 RETURNS
1849 length of annotation if successful and FAIL (-1) otherwise
1850
1851 AUTHOR
1852 GeorgeV.
1853
1854 ------------------------------------------------------------------------*/
1855 EXPORT int32
ANannlen(int32 ann_id)1856 ANannlen(int32 ann_id /* IN: annotation id */)
1857 {
1858 #ifdef LATER
1859 CONSTR(FUNC, "ANannlen");
1860 #endif /* LATER */
1861 int32 ret_value;
1862
1863 ret_value = ANIannlen(ann_id);
1864 return ret_value;
1865 } /* ANannlen() */
1866
1867 /*--------------------------------------------------------------------------
1868 NAME
1869 ANwriteann -- write annotation given ann_id
1870
1871 DESCRIPTION
1872 Checks for pre-existence of given annotation, replacing old one if it
1873 exists. Writes out annotation.
1874
1875 RETURNS
1876 SUCCEED (0) if successful and FAIL (-1) otherwise
1877
1878 AUTHOR
1879 GeorgeV.
1880
1881 ------------------------------------------------------------------------*/
1882 EXPORT int32
ANwriteann(int32 ann_id,const char * ann,int32 annlen)1883 ANwriteann(int32 ann_id, /* IN: annotation id */
1884 const char *ann, /* IN: annotation to write */
1885 int32 annlen /* IN: length of annotation */)
1886 {
1887 #ifdef LATER
1888 CONSTR(FUNC, "ANwriteann"); /* for HERROR */
1889 #endif /* LATER */
1890 int32 ret_value;
1891
1892 ret_value = ANIwriteann(ann_id, ann, annlen);
1893 return ret_value;
1894 } /* ANwriteann() */
1895
1896 /*--------------------------------------------------------------------------
1897 NAME
1898 ANreadann -- read annotation given ann_id
1899
1900 DESCRIPTION
1901 Gets tag and ref of annotation. Finds DD for that annotation.
1902 Reads the annotation, taking care of NULL terminator, if necessary.
1903
1904 RETURNS
1905 SUCCEED (0) if successful and FAIL (-1) otherwise
1906
1907 AUTHOR
1908 GeorgeV.
1909
1910 ------------------------------------------------------------------------*/
1911 EXPORT int32
ANreadann(int32 ann_id,char * ann,int32 maxlen)1912 ANreadann(int32 ann_id, /* IN: annotation id (handle) */
1913 char *ann, /* OUT: space to return annotation in */
1914 int32 maxlen /* IN: size of space to return annotation in */)
1915 {
1916 #ifdef LATER
1917 CONSTR(FUNC, "ANreadann"); /* for HERROR */
1918 #endif /* LATER */
1919 int32 ret_value;
1920
1921 ret_value = ANIreadann(ann_id, ann, maxlen);
1922 return ret_value;
1923 } /* ANreadann() */
1924
1925 /* -----------------------------------------------------------------------
1926 NAME
1927 ANendaccess -- end access to an annotation given it's id
1928
1929 DESCRIPTION
1930 Terminates access to an annotation. For now does nothing
1931
1932 RETURNS
1933 SUCCEED(0) or FAIL(-1)
1934
1935 AUTHOR
1936 GeorgeV.
1937
1938 --------------------------------------------------------------------------- */
1939 EXPORT intn
ANendaccess(int32 ann_id)1940 ANendaccess(int32 ann_id /* IN: annotation id */)
1941 {
1942 #ifdef LATER
1943 CONSTR(FUNC, "ANendaccess"); /* for HERROR */
1944 #endif /* LATER */
1945 intn ret_value = SUCCEED;
1946 /* shut compiler up */
1947 ann_id=ann_id;
1948
1949 return ret_value;
1950 } /* ANendaccess() */
1951
1952 /* -----------------------------------------------------------------------
1953 NAME
1954 ANget_tagref - get tag/ref pair for annotation based on type and index
1955
1956 DESCRIPTION
1957 Get the tag/ref of the annotation based on the type and index of the
1958 annotation. The position index is zero based
1959
1960 RETURNS
1961 A tag/ref pair for an annotation type which can either be a
1962 label or description.
1963
1964 AUTHOR
1965 GeorgeV.
1966
1967 --------------------------------------------------------------------------- */
1968 EXPORT int32
ANget_tagref(int32 an_id,int32 index,ann_type type,uint16 * tag,uint16 * ref)1969 ANget_tagref(int32 an_id, /* IN: annotation interface ID */
1970 int32 index, /* IN: index of annotation to get tag/ref for */
1971 ann_type type, /* IN: AN_DATA_LABEL for data labels,
1972 AN_DATA_DESC for data descriptions,
1973 AN_FILE_LABEL for file labels,
1974 AN_FILE_DESC for file descritpions.*/
1975 uint16 *tag, /* OUT: Tag for annotation */
1976 uint16 *ref /* OUT: ref for annotation */)
1977 {
1978 CONSTR(FUNC, "ANget_tagref"); /* for HERROR */
1979 filerec_t *file_rec = NULL; /* file record pointer */
1980 TBBT_NODE *entry = NULL;
1981 ANentry *ann_entry = NULL;
1982 int32 ret_value = SUCCEED;
1983
1984 /* Clear error stack */
1985 HEclear();
1986
1987 /* convert an_id i.e. file_id to file rec and check for validity */
1988 file_rec = HAatom_object(an_id);
1989 if (BADFREC(file_rec))
1990 HGOTO_ERROR(DFE_ARGS, FAIL);
1991
1992 /* Empty annotation tree */
1993 if (file_rec->an_num[type] == -1)
1994 {
1995 if (ANIcreate_ann_tree(an_id, type) == FAIL)
1996 HGOTO_ERROR(DFE_BADCALL, FAIL);
1997 }
1998
1999 /* check index and adjust to 1 based for tbbtindx()*/
2000 if(index >= 0 && index <= file_rec->an_num[type])
2001 index++;
2002 else
2003 HE_REPORT_GOTO("bad index", FAIL);
2004
2005 /* find 'index' entry */
2006 if ((entry = tbbtindx((TBBT_NODE *)*(file_rec->an_tree[type]), index)) == NULL)
2007 HE_REPORT_GOTO("failed to find 'index' entry", FAIL);
2008
2009 ann_entry = (ANentry *) entry->data;
2010
2011 /* set ref */
2012 *ref = ann_entry->annref;
2013
2014 /* set tag based on type */
2015 switch((int32)type)
2016 {
2017 case AN_DATA_LABEL:
2018 *tag = DFTAG_DIL;
2019 break;
2020 case AN_DATA_DESC:
2021 *tag = DFTAG_DIA;
2022 break;
2023 case AN_FILE_LABEL:
2024 *tag = DFTAG_FID;
2025 break;
2026 case AN_FILE_DESC:
2027 *tag = DFTAG_FD;
2028 break;
2029 default:
2030 HE_REPORT_GOTO("Bad annotation type for this call",FAIL);
2031 }
2032
2033 done:
2034 if(ret_value == FAIL)
2035 { /* Error condition cleanup */
2036
2037 } /* end if */
2038
2039 /* Normal function cleanup */
2040
2041 return ret_value;
2042 } /* ANget_tagref() */
2043
2044 /*--------------------------------------------------------------------------
2045 NAME
2046 ANid2tagref -- get tag/ref given annotation id
2047
2048 DESCRIPTION
2049 Uses the annotation id to find ann_node entry which contains ann_ref
2050
2051 RETURNS
2052 SUCCEED(0) if successful and FAIL (-1) otherwise.
2053
2054 AUTHOR
2055 GeorgeV.
2056
2057 ------------------------------------------------------------------------*/
2058 int32
ANid2tagref(int32 ann_id,uint16 * tag,uint16 * ref)2059 ANid2tagref(int32 ann_id,/* IN: annotation id */
2060 uint16 *tag, /* OUT: Tag for annotation */
2061 uint16 *ref /* OUT: ref for annotation */)
2062 {
2063 CONSTR(FUNC, "ANid2tagref");
2064 ANnode *ann_node = NULL;
2065 int32 file_id = FAIL;
2066 int32 type;
2067 int32 ann_key;
2068 uint16 ann_ref;
2069 int32 ret_value = SUCCEED;
2070
2071 /* Clear error stack */
2072 HEclear();
2073
2074 /* Valid annotation id */
2075 /* get annotation record */
2076 ann_node = HAatom_object(ann_id);
2077 if (NULL == ann_node)
2078 HGOTO_ERROR(DFE_ARGS, FAIL);
2079
2080 /* get file id and annotation key */
2081 file_id = ann_node->file_id;
2082 ann_key = ann_node->ann_key;
2083 type = AN_KEY2TYPE(ann_key);
2084 ann_ref = AN_KEY2REF(ann_key);
2085
2086 /* Valid file id */
2087 if (file_id == FAIL)
2088 HE_REPORT_GOTO("bad file_id", FAIL);
2089
2090 *ref = ann_ref;
2091 /* set type annotation tag */
2092 switch((int32)type)
2093 {
2094 case AN_DATA_LABEL:
2095 *tag = DFTAG_DIL;
2096 break;
2097 case AN_DATA_DESC:
2098 *tag = DFTAG_DIA;
2099 break;
2100 case AN_FILE_LABEL:
2101 *tag = DFTAG_FID;
2102 break;
2103 case AN_FILE_DESC:
2104 *tag = DFTAG_FD;
2105 break;
2106 default:
2107 HE_REPORT_GOTO("Bad annotation type for this call",FAIL);
2108 }
2109
2110 done:
2111 if(ret_value == FAIL)
2112 { /* Error condition cleanup */
2113
2114 } /* end if */
2115
2116 /* Normal function cleanup */
2117
2118 return ret_value;
2119 } /* ANid2tagref */
2120
2121 /*--------------------------------------------------------------------------
2122 NAME
2123 ANtagref2id -- get annotation id given tag/ref
2124
2125 DESCRIPTION
2126 Gets the annotation id of the annotation given the tag/ref of
2127 the annotation itself and the annotation interface id.
2128
2129 RETURNS
2130 Annotation id of annotation if successful and FAIL(-1) otherwise.
2131
2132 AUTHOR
2133 GeorgeV.
2134
2135 ------------------------------------------------------------------------*/
2136 int32
ANtagref2id(int32 an_id,uint16 ann_tag,uint16 ann_ref)2137 ANtagref2id(int32 an_id, /* IN Annotation interface id */
2138 uint16 ann_tag, /* IN: Tag for annotation */
2139 uint16 ann_ref /* IN: ref for annotation */)
2140 {
2141 CONSTR(FUNC, "ANtagref2id");
2142 filerec_t *file_rec = NULL; /* file record pointer */
2143 TBBT_NODE *entry = NULL;
2144 ANentry *ann_entry = NULL;
2145 int32 ann_key;
2146 ann_type type;
2147 int32 ret_value = SUCCEED;
2148
2149 /* Clear error stack */
2150 HEclear();
2151
2152 /* convert an_id i.e. file_id to file rec and check for validity */
2153 file_rec = HAatom_object(an_id);
2154 if (BADFREC(file_rec))
2155 HGOTO_ERROR(DFE_ARGS, FAIL);
2156
2157 /* set type given annotation tag */
2158 switch((uint16)ann_tag)
2159 {
2160 case DFTAG_DIL:
2161 type = AN_DATA_LABEL;
2162 break;
2163 case DFTAG_DIA:
2164 type = AN_DATA_DESC;
2165 break;
2166 case DFTAG_FID:
2167 type = AN_FILE_LABEL;
2168 break;
2169 case DFTAG_FD:
2170 type = AN_FILE_DESC;
2171 break;
2172 default:
2173 HE_REPORT_GOTO("Bad annotation type for this call",FAIL);
2174 }
2175
2176 /* Check for empty annotation tree of 'type'? */
2177 if (file_rec->an_num[type] == -1)
2178 {
2179 if (ANIcreate_ann_tree(an_id, type) == FAIL)
2180 HGOTO_ERROR(DFE_BADCALL, FAIL);
2181 }
2182
2183 /* Create key from type/ref pair
2184 * ----------------------------
2185 * | type(16bits) | ref(16bits) |
2186 * -----------------------------*/
2187 ann_key = AN_CREATE_KEY(type, ann_ref);
2188
2189 /* See if annotation of 'type' with ref exits */
2190 if ((entry = tbbtdfind(file_rec->an_tree[type], &ann_key, NULL)) == NULL)
2191 HE_REPORT_GOTO("failed to find annotation of 'type'", FAIL);
2192
2193 /* get annotation entry from node */
2194 ann_entry = (ANentry *) entry->data;
2195
2196 /* return annotation id */
2197 ret_value = ann_entry->ann_id;
2198
2199 done:
2200 if(ret_value == FAIL)
2201 { /* Error condition cleanup */
2202
2203 } /* end if */
2204
2205 /* Normal function cleanup */
2206
2207 return ret_value;
2208 } /* ANtagref2id */
2209
2210 /*--------------------------------------------------------------------
2211 NAME
2212 ANatype2tag - annotation type to corresponding annotation TAG
2213
2214 DESCRIPTION
2215 Translate annotation type to corresponding TAG
2216
2217 RETURNS
2218 Returns TAG corresponding to annotatin type
2219
2220 AUTHOR
2221 GeorgeV.
2222
2223 --------------------------------------------------------------------*/
2224 EXPORT uint16
ANatype2tag(ann_type atype)2225 ANatype2tag(ann_type atype /* IN: Annotation type */)
2226 { /* Switch on annotation type "atype" */
2227 #ifdef LATER
2228 CONSTR(FUNC, "ANatype2tag"); /* for HERROR */
2229 #endif /* LATER */
2230 uint16 ann_tag;
2231
2232 switch((ann_type)atype)
2233 {
2234 case AN_FILE_LABEL: ann_tag = DFTAG_FID; break;
2235 case AN_FILE_DESC: ann_tag = DFTAG_FD; break;
2236 case AN_DATA_LABEL: ann_tag = DFTAG_DIL; break;
2237 case AN_DATA_DESC: ann_tag = DFTAG_DIA; break;
2238 default: ann_tag = DFTAG_NULL; /*changed from 5 to DFTAG_NULL -BMR*/
2239 } /* switch */
2240 return ann_tag;
2241 } /* ANatype2tag */
2242
2243 /*--------------------------------------------------------------------
2244 NAME
2245 ANtag2atype - annotation TAG to corresponding annotation type
2246
2247 DESCRIPTION
2248 Translate annotation TAG to corresponding atype
2249
2250 RETURNS
2251 Returns type corresponding to annotatin TAG
2252
2253 AUTHOR
2254 GeorgeV.
2255
2256 --------------------------------------------------------------------*/
2257 EXPORT ann_type
ANtag2atype(uint16 atag)2258 ANtag2atype(uint16 atag /* IN: annotation tag */)
2259 { /* Switch on annotation tag */
2260 #ifdef LATER
2261 CONSTR(FUNC, "ANtag2atype"); /* for HERROR */
2262 #endif /* LATER */
2263 ann_type atype;
2264
2265 switch((uint16)atag)
2266 {
2267 case DFTAG_FID: atype = AN_FILE_LABEL; break;
2268 case DFTAG_FD: atype = AN_FILE_DESC; break;
2269 case DFTAG_DIL: atype = AN_DATA_LABEL; break;
2270 case DFTAG_DIA: atype = AN_DATA_DESC; break;
2271 /* This will cause warnings on some compiliers */
2272 default: atype = AN_UNDEF;
2273 } /* switch */
2274 return atype;
2275 } /* ANtag2atype */
2276
2277 #endif /* MFAN_MASTER */
2278