NCBI C Toolkit Cross Reference

C/asnlib/asntypes.c


  1 /* asntypes.c
  2 * ===========================================================================
  3 *
  4 *                            PUBLIC DOMAIN NOTICE                          
  5 *               National Center for Biotechnology Information
  6 *                                                                          
  7 *  This software/database is a "United States Government Work" under the   
  8 *  terms of the United States Copyright Act.  It was written as part of    
  9 *  the author's official duties as a United States Government employee and 
 10 *  thus cannot be copyrighted.  This software/database is freely available 
 11 *  to the public for use. The National Library of Medicine and the U.S.    
 12 *  Government have not placed any restriction on its use or reproduction.  
 13 *                                                                          
 14 *  Although all reasonable efforts have been taken to ensure the accuracy  
 15 *  and reliability of the software and data, the NLM and the U.S.          
 16 *  Government do not and cannot warrant the performance or results that    
 17 *  may be obtained by using this software or data. The NLM and the U.S.    
 18 *  Government disclaim all warranties, express or implied, including       
 19 *  warranties of performance, merchantability or fitness for any particular
 20 *  purpose.                                                                
 21 *                                                                          
 22 *  Please cite the author in any work or product based on this material.   
 23 *
 24 * ===========================================================================
 25 *
 26 * File Name: asntypes.c
 27 *
 28 * Author:  James Ostell
 29 *
 30 * Version Creation Date: 3/4/91
 31 *
 32 * $Revision: 6.9 $
 33 *
 34 * File Description:
 35 *   Routines to deal with internal operations on AsnType objects.
 36 *
 37 * Modifications:  
 38 * --------------------------------------------------------------------------
 39 * Date     Name        Description of modification
 40 * -------  ----------  -----------------------------------------------------
 41 * 3/4/91   Kans        Stricter typecasting for GNU C and C++
 42 * 04-20-93 Schuler     LIBCALL calling convention
 43 * 02-24-94 Schuler     Make AsnTypeStringToHex LIBCALL too
 44 *
 45 * $Log: asntypes.c,v $
 46 * Revision 6.9  2003/12/03 19:31:09  gouriano
 47 * Corrected DTD generation (a different approach)
 48 *
 49 * Revision 6.8  2003/12/02 21:40:17  gouriano
 50 * Revert back to rev 6.6
 51 *
 52 * Revision 6.7  2003/12/02 19:52:49  gouriano
 53 * Corrected DTD generation
 54 *
 55 * Revision 6.6  2000/07/25 20:30:58  ostell
 56 * added support for printing multiple ASN.1 modules as multiple XML DTD and .mod files
 57 *
 58 * Revision 6.5  2000/05/26 14:51:23  ostell
 59 * fixed uninitialized variable
 60 *
 61 * Revision 6.4  2000/05/10 03:12:37  ostell
 62 * added support for XML DTD and XML data output
 63 *
 64 * Revision 6.2  1998/06/12 19:27:56  kans
 65 * fixed unix compiler warnings
 66 *
 67 * Revision 6.1  1997/10/29 02:42:10  vakatov
 68 * Type castings to pass through the C++ compiler
 69 *
 70 * Revision 6.0  1997/08/25 18:10:25  madden
 71 * Revision changed to 6.0
 72 *
 73 * Revision 5.3  1997/04/24 12:47:49  ostell
 74 * in AsnTypeStringToHex, allowed argument "left" to be NULL
 75 *
 76  * Revision 5.2  1997/04/23  21:23:03  ostell
 77  * changed BitHex reading routine to strip internal spaces and allow for linewraps at
 78  * any spacing.
 79  *
 80  * Revision 5.1  1996/12/03  21:43:48  vakatov
 81  * Adopted for 32-bit MS-Windows DLLs
 82  *
 83  * Revision 5.0  1996/05/28  14:00:29  ostell
 84  * Set to revision 5.0
 85  *
 86  * Revision 4.0  1995/07/26  13:47:38  ostell
 87  * force revision to 4.0
 88  *
 89  * Revision 2.19  1995/05/20  17:05:26  ostell
 90  * added ASNTYPE_RUNTIME_LINK
 91  * if defined enables oldstyle runtime link of AsnLinkType().
 92  * default is disabled, which assumes all linking of asn.1 parse trees
 93  * via calls to AsnLoad() functions is done before any AsnREAD or AsnWrite
 94  *
 95  * Revision 2.18  1995/05/15  18:38:28  ostell
 96  * added Log line
 97  *
 98 *
 99 * ==========================================================================
100 */
101 
102 /*****************************************************************************
103 *
104 *   asntypes.c
105 *       basic routines for processing asn1 types
106 *       does not support lexxing of type definitions - those are in
107 *               asnlext.c
108 *
109 *****************************************************************************/
110 
111 #include "asnbuild.h"
112 
113 /*****************************************************************************
114 *
115 *   This stores all loaded parse trees and links them together
116 *
117 *****************************************************************************/
118 static ValNodePtr
119     amps ,                /* the AsnModulePtr blocks */
120     names ;               /* the load file names */
121 
122 /*****************************************************************************
123 *
124 *   CharPtr AsnFindPrimName(atp)
125 *       returns the string name of an ASN.1 primitive type
126 *
127 *****************************************************************************/
128 NLM_EXTERN CharPtr LIBCALL  AsnFindPrimName (AsnTypePtr atp)
129 {
130         AsnTypePtr atp2;
131 
132         atp2 = AsnFindBaseType(atp);
133         if (atp2 == NULL)
134                 return NULL;
135 
136         return atp2->type->name;
137 }
138 
139 /*****************************************************************************
140 *
141 *   CharPtr AsnFindBaseName(atp)
142 *       returns the string name of an ASN.1 basic entity
143 *       returns NULL if not resolved
144 *       returns NULL if resolves to a primitive type (use AsnFindPrimName)
145 *
146 *****************************************************************************/
147 NLM_EXTERN CharPtr LIBCALL  AsnFindBaseName (AsnTypePtr atp)
148 {
149         AsnTypePtr atp2;
150 
151         atp2 = AsnFindBaseType(atp);
152         if (atp2 == NULL)
153                 return NULL;
154 
155         if (atp2->name == NULL)
156                 return NULL;
157         else if (IS_UPPER(*atp2->name))
158                 return atp2->name;
159         else
160                 return NULL;
161 }
162 
163 /*****************************************************************************
164 *
165 *   void AsnKillValue(atp, dvp)
166 *       eliminates stored values such as strings
167 *
168 *****************************************************************************/
169 NLM_EXTERN void LIBCALL  AsnKillValue (AsnTypePtr atp, DataValPtr dvp)
170 {
171         Int2 isa;
172 
173         isa = AsnFindBaseIsa(atp);
174         if (ISA_STRINGTYPE(isa))
175                 MemFree(dvp->ptrvalue);
176         else if ((isa == OCTETS_TYPE) || (isa == STRSTORE_TYPE))
177                 BSFree((ByteStorePtr) dvp->ptrvalue);
178         return;
179 }
180 
181 /*****************************************************************************
182 *
183 *   void AsnTypeSetIndent(increase, aip, atp)
184 *       set the typestack type_indent
185 *
186 *****************************************************************************/
187 NLM_EXTERN void AsnTypeSetIndent (Boolean increase, AsnIoPtr aip, AsnTypePtr atp)
188 {
189         Int1 curr_indent;
190         PstackPtr tmptype;
191         
192 
193         if (increase)
194         {
195                 aip->typestack[aip->type_indent].type = atp;     /* save type */
196                 aip->type_indent++;
197                 curr_indent = aip->type_indent;
198                 if (curr_indent == aip->max_type)   /* expand indent levels */
199                 {
200                         tmptype = aip->typestack;
201                         aip->typestack = (PstackPtr) MemNew((sizeof(Pstack) * (aip->max_type + 10)));
202                         MemCopy(aip->typestack, tmptype, (size_t)(sizeof(Pstack) * aip->max_type));
203                         MemFree(tmptype);
204                         aip->max_type += 10;
205                 }
206                 aip->typestack[curr_indent].type = NULL;     /* set to first time */
207         }
208         else
209         {
210                 do
211                 {
212                         aip->typestack[aip->type_indent].type = NULL;
213                         if (aip->type_indent)
214                                 aip->type_indent--;
215                 } while ((aip->type_indent) &&
216                         (AsnFindBaseIsa(aip->typestack[aip->type_indent-1].type) == CHOICE_TYPE)
217                          && (aip->token != ISMODULE_TOKEN) && (!(aip->type & ASNIO_XML)));
218                 /* this is to pop out of choice nests */
219                 /* XML popping is formatted at ends */
220         }
221         return;
222 }
223 
224 /*****************************************************************************
225 *
226 *   AsnTypePtr AsnFindBaseType(atp)
227 *       find the primitive type for atp
228 *
229 *****************************************************************************/
230 NLM_EXTERN AsnTypePtr LIBCALL AsnFindBaseType (AsnTypePtr atp)
231 {
232         if (atp == NULL) return NULL;
233 
234         if (atp->type == NULL) return NULL;
235 
236         while (! ISA_BASETYPE(atp->type->isa))
237         {
238                 atp = atp->type;
239                 if (atp->type == NULL)   /* not found */
240                         return NULL;
241         }
242         return atp;
243 }
244 
245 NLM_EXTERN AsnTypePtr LIBCALL AsnFindBaseTypeDTD (AsnTypePtr atp)
246 {
247         if (atp == NULL) return NULL;
248 
249         if (atp->type == NULL) return NULL;
250 
251         if (! ISA_BASETYPE(atp->type->isa))
252         {
253                 atp = atp->type;
254                 if (atp->type == NULL)   /* not found */
255                         return atp;
256         }
257         return atp;
258 }
259 
260 /*****************************************************************************
261 *
262 *   Int2 AsnFindBaseIsa(atp)
263 *       find the primitive type for atp
264 *
265 *****************************************************************************/
266 NLM_EXTERN Int2 LIBCALL AsnFindBaseIsa (AsnTypePtr atp)
267 {
268         if (atp == NULL)
269                 return -1;
270 
271         if (ISA_BASETYPE(atp->isa))
272                 return atp->isa;
273 
274         if (atp->type == NULL)
275                 return -1;
276 
277         while (! ISA_BASETYPE(atp->type->isa))
278         {
279                 atp = atp->type;
280                 if (atp->type == NULL)
281                         return -1;
282         }
283         return atp->type->isa;
284 }
285 
286 /*****************************************************************************
287 *
288 *   Boolean AsnTypeValidateOut(aip, atp, dvp)
289 *       if not open or closing a SET, SEQ, SETOF, SEQOF, will
290 *               put atp in aip->typestack if it validates.
291 *
292 *   KNOWN DEFECT:  SET should check for 1 of each non-optional element
293 *       It does not right now, it only checks that an element is a valid
294 *       member of the SET.
295 *
296 *****************************************************************************/
297 NLM_EXTERN Boolean AsnTypeValidateOut (AsnIoPtr aip, AsnTypePtr atp, DataValPtr dvp)
298 {
299         Int2 isa;
300         AsnTypePtr atp2, parent_type, base_type, curr_type;
301         Boolean foundit;
302         AsnValxNodePtr avnp;
303 
304         if ((aip == NULL) || (atp == NULL))
305                 return FALSE;
306                 
307         curr_type = aip->typestack[aip->type_indent].type;
308         base_type = AsnFindBaseType(atp);
309         if (base_type == NULL)
310         {
311                 AsnIoErrorMsg(aip, 10, AsnErrGetTypeName(atp->name), "AsnTypeValidateOut");
312                 return FALSE;
313         }
314                 
315         isa = base_type->type->isa;
316 
317         if (((isa == SEQ_TYPE) || (isa == SET_TYPE) ||
318                  (isa == SEQOF_TYPE) || (isa == SETOF_TYPE))
319                  && (dvp->intvalue == END_STRUCT))
320         {
321                 switch (isa)
322                 {
323                         case SEQOF_TYPE:
324                         case SETOF_TYPE:
325                                 break;
326                         case SEQ_TYPE:       /* check that no more waiting */
327                                 if (curr_type != NULL)   /* check next one */
328                                         atp2 = curr_type->next;
329                                 else                     /* empty sequence written */
330                                         atp2 = (AsnTypePtr) base_type->branch;
331                                 while (atp2 != NULL)
332                                 {
333                                         if (! (atp2->optional || atp2->hasdefault))
334                                         {
335                                                 AsnIoErrorMsg(aip, 7, AsnErrGetTypeName(atp2->name), AsnErrGetTypeName(atp->name));
336                                                 return FALSE;
337                                         }
338                                         atp2 = atp2->next;
339                                 }
340                                 break;
341                         default:
342                                 break;
343                 }
344                 return TRUE;
345         }
346 
347         if (aip->type_indent)       /* part of a larger struct */
348         {
349                 foundit = FALSE;
350                 if (aip->type_indent < 1)
351                         return FALSE;
352                         
353                 parent_type = aip->typestack[aip->type_indent - 1].type;
354                 base_type = AsnFindBaseType(parent_type);
355                 if (base_type == NULL)
356                         return FALSE;
357                 isa = base_type->type->isa;
358                 atp2 = (AsnTypePtr) base_type->branch;
359                 while (atp2 != NULL)
360                 {
361                         if (atp2 == atp)
362                         {
363                                 foundit = TRUE;
364                                 break;
365                         }
366                         atp2 = atp2->next;
367                 }
368                 if (! foundit)
369                 {
370                         atp2 = AsnFindBaseType(atp);
371                         AsnIoErrorMsg(aip, 22, AsnErrGetTypeName(atp->name),
372                                 AsnErrGetTypeName(atp2->name), AsnErrGetTypeName(parent_type->name));
373                         return FALSE;
374                 }
375                 switch (isa)
376                 {
377                         case SETOF_TYPE:       /* just has to be right type */
378                         case SEQOF_TYPE:
379                                 break;
380                         case CHOICE_TYPE:      /* can only have one value */
381                                 if (curr_type != NULL)
382                                 {
383                                         AsnIoErrorMsg(aip, 23, AsnErrGetTypeName(parent_type->name),
384                                                 AsnErrGetTypeName(atp->name));
385                                         return FALSE;
386                                 }
387                                 break;
388                         case SET_TYPE:         /* SET should check for 1 of each */
389                                                    /* non-optional element, but doesn't */
390                                 if (curr_type == atp)
391                                 {
392                                         AsnIoErrorMsg(aip, 24, AsnErrGetTypeName(atp->name),
393                                                 AsnErrGetTypeName(parent_type->name));
394                                         return FALSE;
395                                 }
396                                 break;
397                         case SEQ_TYPE:
398                                 if (curr_type == atp)
399                                 {
400                                         AsnIoErrorMsg(aip, 24, AsnErrGetTypeName(atp->name),
401                                                 AsnErrGetTypeName(parent_type->name));
402                                         return FALSE;
403                                 }
404                                                                  /* check preceeding elements */
405                                 if (curr_type != NULL)
406                                 {
407                                         atp2 = (AsnTypePtr) base_type->branch;
408                                         while (atp2 != curr_type->next)
409                                         {
410                                                 if (atp == atp2)
411                                                 {
412                                                         AsnIoErrorMsg(aip, 6, AsnErrGetTypeName(atp->name),
413                                                                 AsnErrGetTypeName(parent_type->name));
414                                                         return FALSE;
415                                                 }
416                                                 atp2 = atp2->next;
417                                         }
418                                 }
419                                 else
420                                         atp2 = (AsnTypePtr) base_type->branch;
421                                 while ((atp2 != NULL) && (atp != atp2))
422                                 {
423                                         if (! (atp2->optional || atp2->hasdefault))
424                                         {                                       /* skipped a non-optional element */
425                                                 AsnIoErrorMsg(aip, 7, AsnErrGetTypeName(atp2->name),
426                                                         AsnErrGetTypeName(parent_type->name));
427                                                 return FALSE;
428                                         }
429                                         atp2 = atp2->next;
430                                 }
431                                 if (atp2 == NULL)  /* element out of order */
432                                 {
433                                         AsnIoErrorMsg(aip, 6, AsnErrGetTypeName(atp->name),
434                                                 AsnErrGetTypeName(parent_type->name));
435                                         return FALSE;
436                                 }
437                                 break;
438                         default:
439                                 AsnIoErrorMsg(aip, 25, AsnErrGetTypeName(parent_type->name),
440                                         parent_type->isa);
441                                 return FALSE;
442                 }
443                 base_type = AsnFindBaseType(atp);
444                 isa = base_type->type->isa;
445         }
446 
447         if (ISA_STRINGTYPE(isa))
448                 isa = GENERALSTRING_TYPE;
449 
450                                 /******************* maintain typestack ****************/
451         switch (isa)          /* set aip->typestack for non-struct types */
452         {                                         /* this is done for them in AsnTypeSetIndent() */
453                 case SEQ_TYPE:
454                 case SET_TYPE:
455                 case SEQOF_TYPE:
456                 case SETOF_TYPE:
457                 case CHOICE_TYPE:
458                 default:                                   /* terminal value */
459                         aip->typestack[aip->type_indent].type = atp;
460                         break;
461         }
462 
463         switch (isa)          /* check ranges and values */
464         {
465                 case ENUM_TYPE:
466                         avnp = (AsnValxNodePtr) base_type->branch;
467                         while (avnp != NULL)
468                         {
469                                 if (avnp->intvalue == dvp->intvalue)
470                                         return TRUE;
471                                 avnp = avnp->next;
472                         }
473                         AsnIoErrorMsg(aip, 12, dvp->intvalue, AsnErrGetTypeName(atp->name));
474                         return FALSE;
475                 default :
476                         break;
477         }
478         return TRUE;    
479 }
480 
481 /*****************************************************************************
482 *
483 *   AsnTypePathFind(amp, str, countptr)
484 *       like AsnTypeFind() but allocates an array of AsnTypePtr and fills
485 *       it in with the proper path.  Sets countptr to sizeof array.
486 *       Returns array or NULL on failure
487 *
488 *****************************************************************************/
489 NLM_EXTERN AsnTypePtr PNTR LIBCALL  AsnTypePathFind (AsnModulePtr amp, CharPtr str, Int2Ptr countptr)
490 {
491         AsnModulePtr amp2;
492         AsnTypePtr atp;
493         Int2 count;
494         AsnTypePtr PNTR typeptr;
495         CharPtr ptr;
496 
497         *countptr = 0;
498         count = 1;
499         ptr = str;
500         while (*ptr != '\0')
501         {
502                 if (*ptr == '.')
503                         count++;
504                 ptr++;
505         }
506         typeptr = (AsnTypePtr*) MemNew(sizeof(AsnTypePtr) * count);
507 
508     if (amp == NULL)
509         {
510                 if (amps == NULL)
511                 {
512                         AsnIoErrorMsg(NULL, (Int2)105);
513                         return NULL;
514                 }
515         amp = (AsnModulePtr) amps->data.ptrvalue;
516         }
517 
518         amp2 = amp;
519         atp = NULL;
520 
521         while (amp2 != NULL)
522         {
523                 atp = AsnTypeFindType(amp2->types, str, typeptr, count, FALSE);
524                 if (atp != NULL)
525                 {
526                         *countptr = count;
527                         return typeptr;
528                 }
529                 else
530                         amp2 = amp2->next;
531         }
532 
533         MemFree(typeptr);
534         return NULL;       /* not found */
535 }
536 
537 
538 /*****************************************************************************
539 *
540 *   AsnTypePtr AsnTypeFind(amp, str)
541 *       finds a type in a module or set of modules
542 *       str is a path with dot separation.
543 *       E is used to indicate an element of SEQOF or SETOF
544 *       looks for partial paths as well
545 *
546 *   if called with amp == NULL
547 *       searches all loaded modules
548 *   returns a single node at the end of the path
549 *
550 *****************************************************************************/
551 NLM_EXTERN AsnTypePtr LIBCALL  AsnTypeFind (AsnModulePtr amp, CharPtr str)
552 {
553         AsnModulePtr amp2;
554         AsnTypePtr atp;
555 
556     if (amp == NULL)
557         {
558                 if (amps == NULL)
559                 {
560                         AsnIoErrorMsg(NULL, (Int2)105);
561                         return NULL;
562                 }
563         amp = (AsnModulePtr) amps->data.ptrvalue;
564         }
565 
566         amp2 = amp;
567         atp = NULL;
568 
569         while (amp2 != NULL)
570         {
571                 atp = AsnTypeFindType(amp2->types, str, NULL, 0, FALSE);
572                 if (atp != NULL)
573                         return atp;
574                 else
575                         amp2 = amp2->next;
576         }
577 
578         return atp;       /* not found */
579 }
580 
581 /*****************************************************************************
582 *
583 *   AsnTypePtr AsnTypeFindType(atp, str, typeptr, count, in_it)
584 *
585 *****************************************************************************/
586 NLM_EXTERN AsnTypePtr AsnTypeFindType (AsnTypePtr atp, CharPtr str, AsnTypePtr PNTR typeptr, Int2 count, Boolean in_it)
587 {
588         AsnTypePtr curr, next;
589         CharPtr beg;
590         Int2 len, isa;
591         Boolean is_element,       /* (unamed) element of setof seqof */
592                 is_type,              /* if a type, must find the original def */
593                 got_it;
594         AsnTypePtr PNTR typenext;
595         Int2 newcount;
596 
597         if (count < 0)      /* off array ... error condition */
598                 return NULL;
599 
600         beg = str;
601         len = 0;
602         if (typeptr == NULL)
603         {
604                 typenext = NULL;
605                 newcount = 0;
606         }
607         else
608         {
609                 newcount = count - 1;
610                 if (newcount >= 0)
611                         typenext = typeptr + 1;
612                 else
613                         typenext = NULL;
614         }
615         is_element = FALSE;
616         is_type = FALSE;
617         while ((*beg != '.') && (*beg != '\0'))
618         {
619                 beg++; len++;
620         }
621 
622         if ((*str == 'E') && (len == 1))
623                 is_element = TRUE;
624         else if (IS_UPPER(*str))
625                 is_type = TRUE;
626 
627         curr = atp;                             /* look at this level */
628         while (curr != NULL)
629         {
630                 got_it = FALSE;
631                 if (is_element)
632                         got_it = TRUE;
633                 else if (StrMatch(curr->name, str, len))   /* found it */
634                 {
635                         if (! is_type)
636                                 got_it = TRUE;
637                         else                    /* check that this is the real def */
638                         {
639                                 if (! curr->imported)
640                                         got_it = TRUE;
641                         }
642                 }
643 
644                 if (got_it)
645                 {
646                         if (typeptr != NULL)
647                                 *typeptr = curr;
648 
649                         if (*beg == '\0')    /* that's it */
650                                 return curr;
651                         else                 /* go down the path */
652                         {
653                                 next = AsnFindBaseType(curr);
654                                 isa = next->type->isa;
655                                 if ((next->branch != NULL)   /* go further */
656                                         && (isa != INTEGER_TYPE)
657                                         && (isa != ENUM_TYPE))
658                                 {
659                                         next = AsnTypeFindType((AsnTypePtr) next->branch, (beg + 1), typenext, newcount, TRUE);
660                                         if (next != NULL)
661                                                 return next;
662                                 }
663                         }
664                 }
665                 curr = curr->next;
666         }
667         
668         if (in_it)     /* processing a path and can't find next node here */
669                 return NULL;
670 
671         curr = atp;           /* start down a level */
672         while (curr != NULL)
673         {
674                 if (curr->branch != NULL)
675                 {
676                         next = AsnFindBaseType(curr);
677                         
678                         if ((next != NULL) && (next->type != NULL))
679                         {
680                                 isa = next->type->isa;
681                                 if ((next->branch != NULL)   /* go further */
682                                         && (isa != INTEGER_TYPE)
683                                         && (isa != ENUM_TYPE))
684                                 {
685                                         next = AsnTypeFindType((AsnTypePtr) next->branch, str, typenext, newcount, FALSE);
686                                         if (next != NULL)
687                                         {
688                                                 if (typeptr != NULL)
689                                                         *typeptr = curr;
690                                                 return next;
691                                         }
692                                 }
693                         }
694                         /** else, an error has occurred, unresolved branch **/
695                 }
696                 curr = curr->next;
697         }
698         return NULL;
699 }
700 
701 /*****************************************************************************
702 *
703 *   CharPtr AsnTypeDumpStack(str, aip)
704 *       dump a typestack into str
705 *       returns a pointer to the '\0' at the end of the str
706 *
707 *****************************************************************************/
708 NLM_EXTERN CharPtr LIBCALL  AsnTypeDumpStack (CharPtr str, AsnIoPtr aip)
709 {
710     Int2 level, isa, lastnochoice;
711 
712     lastnochoice = -1;
713     *str = '\0';
714 
715         for(level = 0; level <= aip->type_indent; level++)
716         {
717                 if (level == aip->type_indent)
718                 {
719                         if ((aip->type & ASNIO_OUT) ||
720                                 ((aip->type & ASNIO_IN) && (aip->read_id == FALSE)))
721                                 str = StringMove(str, "<");
722                 }
723                 if (aip->typestack[level].type == NULL)
724                         str = StringMove(str, " ");
725                 else
726                 {
727                         isa = AsnFindBaseIsa(aip->typestack[level].type);
728             if (aip->typestack[level].type->name != NULL)
729                 str = StringMove(str, aip->typestack[level].type->name);
730             else if ((lastnochoice == SEQOF_TYPE) ||
731                         (lastnochoice == SETOF_TYPE))
732                 str = StringMove(str, "E");
733             else
734                 str = StringMove(str, "?");
735             if (isa != CHOICE_TYPE)
736                 lastnochoice = isa;
737                 }
738         if (level != aip->type_indent)
739             str = StringMove(str, ".");
740                 else
741                 {
742                         if ((aip->type & ASNIO_OUT) ||
743                                 ((aip->type & ASNIO_IN) && (aip->read_id == FALSE)))
744                                 str = StringMove(str, ">");
745                 }
746         }
747         return str;
748 }
749 
750 /*****************************************************************************
751 *
752 *   Int4 AsnTypeStringToHex(from, len, to, left)
753 *       converts an octet string to binary
754 *       returns number of hex digits created if all ok
755 *       *left is chars left at the end of the buffer including first letter of
756 *          a remaining digit (from does not have an even number of letters)
757 *          since this could include white space, could be more than 1
758 *       returns a negative number on an error
759 *       skips over internal or trailing white space
760 *       left can be NULL in which case it is ignored
761 *
762 *****************************************************************************/
763 NLM_EXTERN Int4 LIBCALL AsnTypeStringToHex (Pointer from, Int4 len, Pointer to, Int4Ptr left)
764 {
765         BytePtr f, t;
766         Byte octet = 0, value;
767         int i;
768         Int4 added = 0;
769 
770         f = (BytePtr) from;
771         t = (BytePtr) to;
772         if (left != NULL)
773                 *left = 0;
774         i = 16;
775 
776         while (len)
777         {
778              if (! IS_WHITESP(*f))  /* skip spaces */
779              {
780                 if (i == 16)       /* first letter of pair */
781                 {
782                         octet = 0;
783                         if (left != NULL)
784                                 *left = len; /* point at it in case one letter left */
785                 }
786 
787                 value = TO_UPPER(*f);
788                 if ((value >= 'A') && (value <= 'F'))
789                         octet += (((value - 'A') + 10) * i);
790                 else if ((value >= '0') && (value <= '9'))
791                         octet += ((value - '0') * i);
792                 else
793                         return (Int4)(-1);
794 
795                 if (i == 16)     /* first letter of pair */
796                         i = 1;   /* goto second letter */
797                 else             /* letter pair was read */
798                 {
799                         i = 16;  /* reset for first letter */
800                         if (left != NULL)
801                                 *left = 0;  /* nothing left so far */
802                         *t = octet;  /* record the hex digit */
803                         t++; added++;
804                 }
805 
806              }
807              len--;
808              f++;
809         }
810         return added;
811 }
812 
813 #ifdef ASNTYPE_RUNTIME_LINK
814 static Int2 tstack_max;
815 static AsnTypePtr PNTR tstack;
816 static Int2Ptr prev;
817 #endif
818 
819 /*****************************************************************************
820 *
821 *   AsnLinkType(type, localtype)
822 *      provides for linkage of imported types
823 *      if (type != NULL)
824 *         it's an element of type localtype
825 *         so, set type->type to localtype
826 *      else
827 *         it's localtype itself
828 *         so, return localtype
829 *      return pointer to correct type
830 *
831 *      ifdef'd OUT NOW THAT LINKING IS DONE AT LOAD TIME
832 *
833 *****************************************************************************/
834 NLM_EXTERN AsnTypePtr LIBCALL  AsnLinkType (AsnTypePtr type, AsnTypePtr localtype)
835 {
836 
837         if (type == NULL)
838                 return localtype;
839         else
840 #ifndef ASNTYPE_RUNTIME_LINK
841                 return type;        /* assume has been linked at tree load time */
842 #else
843         {
844     Int2 i, j;
845     Int2Ptr oldprev;
846     AsnTypePtr PNTR oldtstack;
847 
848         for (i = 0; i < tstack_max; i++)
849                 {
850                 if (tstack[i] == NULL)
851                 break;
852                 }
853 
854         if (i >= tstack_max)   /* increase stack size */
855         {
856             oldtstack = tstack;
857             oldprev = prev;
858             tstack = MemNew(((tstack_max + 20) * sizeof(AsnTypePtr)));
859             prev = MemNew(((tstack_max + 20) * sizeof(Int2)));
860             MemCopy(tstack, oldtstack, (size_t)(tstack_max * sizeof(AsnTypePtr)));
861             MemCopy(prev, oldprev, (size_t)(tstack_max * sizeof(Int2)));
862             MemFree(oldtstack);
863             MemFree(oldprev);
864             tstack_max += 20;
865         }
866 
867         j = type->tmp;
868         if (j)    /* previous type linked */
869             prev[i] = j;
870         tstack[i] = type->type;
871         type->tmp =  (i + 1);
872                 if (type != localtype)   /* don't link to itself */
873                         type->type = localtype;
874                 return type;
875         }
876 #endif
877 }
878 
879 /*****************************************************************************
880 *
881 *   AsnUnlinkType(type)
882 *     disconnects local tree.
883 *
884 *****************************************************************************/
885 NLM_EXTERN void LIBCALL  AsnUnlinkType (AsnTypePtr type)
886 {
887 #ifdef ASNTYPE_RUNTIME_LINK
888     Int2 j;
889 
890         if (type != NULL)
891         {
892         j = type->tmp;
893         j--;
894                 type->type = tstack[j];
895         if (prev[j])
896             type->tmp = prev[j];
897         else
898                 type->tmp = 0;
899         tstack[j] = NULL;
900         prev[j] = 0;
901         }
902 #endif
903         return;
904 }
905 
906 static void AddXMLname(AsnTypePtr atp, AsnTypePtr PNTR typestack, Int2 stackptr)
907 {
908         Char buf[80];
909         AsnTypePtr atp2;
910         Boolean found=FALSE, getparent=TRUE, doitem = FALSE, done = FALSE;
911         CharPtr tmp;
912         Int2 i, isa;
913 
914         if (atp->XMLname == NULL)   /* only do it once */
915         {
916                 tmp = buf; *tmp = '\0';
917                 if (atp->name == NULL)
918                 {
919                         doitem = TRUE;
920                 }
921                 else if (IS_UPPER(*(atp->name)))
922                 {
923                         getparent = FALSE;
924                         tmp = StringMove(tmp, atp->name);
925                 }
926 
927                 if ((getparent) && (stackptr))
928                 {
929                         atp2 = typestack[stackptr - 1];
930                         isa = AsnFindBaseIsa(atp2);
931                         if ((doitem) && ((isa == SEQOF_TYPE) || (isa == SETOF_TYPE)))
932                         {
933                                 atp2 = AsnFindBaseTypeDTD(atp);
934                                 if (atp2 != NULL)
935                                 {
936                                 if (atp2->name == NULL)
937                                 {
938                                         atp2 = typestack[stackptr - 1];
939                                         if (atp->type != NULL)
940                                         {
941                                                 if (ISA_BASETYPE(atp->type->isa))
942                                                 {
943                                                         if (atp2->XMLname != NULL)
944                                                         {
945                                                                 tmp = StringMove(tmp, atp2->XMLname);
946                                                                 getparent = FALSE;
947                                                                 found = TRUE;
948                                                         }
949                                                 }
950                                         }
951                                 }
952                                 else
953                                 {
954                                         if (atp2->XMLname != NULL)
955                                                 tmp = StringMove(tmp, atp2->XMLname);
956                                         else if (atp2->name != NULL)
957                                                 tmp = StringMove(tmp, atp2->name);
958                                         if (*buf != '\0')
959                                         {
960                                                 doitem = FALSE;
961                                                 getparent = FALSE;
962                                                 done = TRUE;
963                                                 found = TRUE;
964                                         }
965                                 }
966                                 }
967                         }
968 
969                         atp2 = typestack[stackptr - 1];
970                         if ((getparent) && (atp2->XMLname != NULL))  /* already nested */
971                         {
972                                 tmp = StringMove(tmp, atp2->XMLname);
973                                 tmp = StringMove(tmp, "_");
974                                 getparent = FALSE;
975                                 found = TRUE;
976                         }
977 
978                         if ((stackptr) && (getparent))
979                         {
980                                 found = FALSE;
981 
982                                 for (i = (stackptr - 1); (i >= 0) && (! found); i--)
983                                 {
984                                         atp2 = AsnFindBaseTypeDTD(typestack[i]);
985                                         if ((atp2 != NULL) && (atp2->name != NULL) && (IS_UPPER(*(atp2->name))))
986                                         {
987                                                 while (i < stackptr)
988                                                 {
989                                                         atp2 = AsnFindBaseTypeDTD(typestack[i]);
990                                                         if (atp2->name == NULL)
991                                                                 tmp = StringMove(tmp, "E");
992                                                         else
993                                                                 tmp = StringMove(tmp, atp2->name);
994                                                         tmp = StringMove(tmp, "_");
995                                                         i++;
996                                                 }
997                                                 found = TRUE;
998                                         }
999                                 }
1000                         }
1001 
1002                         if ((! done) && found)
1003                         {
1004                                 if (doitem)
1005                                         tmp = StringMove(tmp, "_E");
1006                                 else
1007                                         tmp = StringMove(tmp, atp->name);
1008                         }
1009                 }
1010 
1011 
1012                 if (*buf != '\0')
1013                 {
1014                         atp->XMLname = StringSave(buf);
1015                 }
1016         }
1017 
1018         atp2 = AsnFindBaseTypeDTD(atp);
1019         if ((! atp->imported) && (atp2 != NULL) && (atp2->type != NULL))
1020         {
1021                 isa = atp2->type->isa;
1022                 if ((isa == SEQ_TYPE) || (isa == SET_TYPE))
1023                 {
1024                         typestack[stackptr] = atp;
1025                         for (atp2 = atp->branch; atp2 != NULL; atp2 = atp2->next)
1026                                 AddXMLname(atp2, typestack, (Int2)(stackptr + 1));
1027                 }
1028                 else if ((isa == SEQOF_TYPE) || (isa == SETOF_TYPE))
1029                 {
1030                         typestack[stackptr] = atp;
1031                         for (atp2 = atp->branch; atp2 != NULL; atp2 = atp2->next)
1032                                 AddXMLname(atp2, typestack, (Int2)(stackptr + 1));
1033                 }                       
1034                 else if (isa == CHOICE_TYPE)
1035                 {
1036                         typestack[stackptr] = atp;
1037                         for (atp2 = atp->branch; atp2 != NULL; atp2 = atp2->next)
1038                                 AddXMLname(atp2, typestack, (Int2)(stackptr + 1));
1039                 }
1040         }
1041 
1042         return;
1043 
1044 }
1045 /*****************************************************************************
1046 *
1047 *   void AsnModuleLink(amp)
1048 *       links IMPORT types with EXPORTS from other modules
1049 *       if cannot link an IMPORT, no errors are generated
1050 *
1051 *****************************************************************************/
1052 NLM_EXTERN void LIBCALL  AsnModuleLink (AsnModulePtr amp)
1053 {
1054         AsnTypePtr atp, atp2, typestack[10];
1055         AsnModulePtr currmod, mod;
1056         Boolean found;
1057 
1058         currmod = amp;
1059         while (currmod != NULL)
1060         {
1061                 atp = currmod->types;
1062                 while (atp != NULL)
1063                 {
1064                         if ((atp->imported) && (atp->type == NULL)) /* link imported types */
1065                         {
1066                                 mod = amp;
1067                                 if (mod == currmod)
1068                                         mod = mod->next;
1069                                 found = FALSE;
1070                                 while ((mod != NULL) && (! found))
1071                                 {
1072                                         atp2 = mod->types;
1073                                         while ((atp2 != NULL) && (! found))
1074                                         {
1075                                                 if ((! atp2->imported) &&
1076                                 (! StringCmp(atp2->name, atp->name)))
1077                                                 {
1078                                                         if (atp2->exported)
1079                                                         {
1080                                                                 atp->type = atp2;
1081                                                                 found = TRUE;
1082                                                         }
1083                                                         else
1084                                                         {
1085                                                                 AsnIoErrorMsg(NULL, 84, AsnErrGetTypeName(atp2->name),
1086                                                                         mod->modulename);
1087                                                                 atp2 = atp2->next;
1088                                                         }
1089                                                 }
1090                                                 else
1091                                                         atp2 = atp2->next;
1092                                         }
1093                                         mod = mod->next;
1094                                         if (mod == currmod)
1095                                                 mod = mod->next;
1096                                 }
1097                         }
1098                         atp = atp->next;
1099                 }
1100                 currmod = currmod->next;
1101         }
1102 
1103         /*** Fill in the XML names *********/
1104 
1105         currmod = amp;
1106         while (currmod != NULL)
1107         {
1108                 atp = currmod->types;
1109                 while (atp != NULL)
1110                 {
1111                         AddXMLname(atp, typestack, (Int2)0);
1112                         atp = atp->next;
1113                 }
1114                 currmod = currmod->next;
1115         }
1116 
1117 
1118         return;
1119 }
1120 
1121 /*****************************************************************************
1122 *
1123 *   AsnStoreTree(file, amp)
1124 *
1125 *****************************************************************************/
1126 NLM_EXTERN void LIBCALL AsnStoreTree (CharPtr file, AsnModulePtr amp)
1127 {
1128     ValNodePtr anp, last;
1129     AsnModulePtr tamp, tamp2, newamp;
1130     Int2 numamp;
1131 
1132                     /* check to see if we already have it (could happen) */
1133 
1134     anp = names;
1135     last = NULL;
1136     while (anp != NULL)
1137     {
1138         if (! StringCmp((CharPtr)anp->data.ptrvalue, file))
1139             return;   /* have it */
1140         last = anp;
1141         anp = anp->next;
1142     }
1143 
1144                     /* add the name */
1145     anp = ValNodeNew(last);
1146     if (last == NULL)
1147         names = anp;
1148     anp->data.ptrvalue = (Pointer) StringSave(file);
1149 
1150     last = NULL;
1151     anp = amps;
1152     while (anp != NULL)
1153     {
1154         last = anp;
1155         anp = anp->next;
1156     }
1157     anp = ValNodeNew(last);
1158     if (last == NULL)
1159         amps = anp;
1160 
1161     tamp = amp;
1162     numamp = 0;
1163     while (tamp != NULL)
1164     {
1165         numamp++;
1166         tamp = tamp->next;
1167     }
1168     newamp = (AsnModulePtr) MemNew(numamp * sizeof(AsnModule));
1169     anp->data.ptrvalue = (Pointer) newamp;
1170     tamp = amp;
1171     tamp2 = newamp;
1172     while (numamp)
1173     {
1174         MemCopy(tamp2, tamp, sizeof(AsnModule));
1175         tamp2++; tamp++; numamp--;
1176     }
1177     if (last != NULL)
1178     {
1179         tamp = (AsnModulePtr)last->data.ptrvalue;
1180         while (tamp->next != NULL)
1181             tamp = tamp->next;
1182         tamp->next = newamp;    /* link it in to list copy */
1183     }
1184 
1185     tamp = (AsnModulePtr) amps->data.ptrvalue;
1186     AsnModuleLink(tamp);              /* connect the tree */
1187     return;
1188 }
1189 
1190 
1191 /*****************************************************************************
1192 *
1193 *   Pointer PointerDecode(index, avn, at)
1194 *
1195 *****************************************************************************/
1196 static Pointer PointerDecode (Int2 index, AsnValxNodePtr avn, AsnTypePtr at)
1197 {
1198     if (index == -32000)
1199         return NULL;
1200     if (index == -32001)
1201         return (Pointer) avn;
1202     if (index < 0)
1203     {
1204         index *= -1;
1205         return (Pointer) &avn[index];
1206     }
1207     return (Pointer) &at[index];
1208 }
1209 
1210 /*****************************************************************************
1211 *
1212 *   AsnTreeLoad(file, &avn, &at, &amp)
1213 *
1214 *****************************************************************************/
1215 NLM_EXTERN Boolean LIBCALL  AsnTreeLoad (char *file, AsnValxNodePtr *avnptr, AsnTypePtr *atptr, AsnModulePtr *ampptr)
1216 {
1217     AsnValxNodePtr avn = NULL, avncurr;
1218     AsnTypePtr at = NULL, atcurr;
1219     AsnModulePtr amp = NULL, ampcurr;
1220     ValNodePtr anp, ampanp;
1221     int numval, numtype, nummod, i;
1222     FILE * fp;
1223     int isa, next;
1224     long intvalue;
1225     double realvalue;
1226     char name[PATH_MAX], fname[60];
1227     CharPtr ptr;
1228     int bools[5], tagclass, tagnumber, defaultvalue, type, branch;
1229 
1230                     /* check to see if we already have it (could happen) */
1231 
1232     anp = names;
1233     ampanp = amps;
1234     while (anp != NULL)
1235     {
1236         if (! StringCmp((CharPtr)anp->data.ptrvalue, file))
1237         {                               /* have it */
1238             if (* ampptr == NULL)       /* fill dynamic load */
1239             {
1240                 * ampptr = (AsnModulePtr) ampanp->data.ptrvalue;
1241                 * atptr = (* ampptr)->types;
1242                      /* don't really need avnptr filled in */
1243             }
1244             return TRUE;
1245         }
1246         ampanp = ampanp->next;
1247         anp = anp->next;
1248     }
1249 
1250         if (! ProgMon("Load ASN.1 Trees"))
1251                 return FALSE;
1252 
1253     if (* ampptr != NULL)      /* static load, add to list */
1254     {
1255         AsnStoreTree(file, (* ampptr));
1256         return TRUE;        /* already loaded */
1257     }
1258 
1259     if (! FindPath("ncbi", "ncbi", "asnload", name, sizeof (name)))
1260         {
1261                 AsnIoErrorMsg(NULL, 85);
1262         return FALSE;
1263         }
1264 
1265     FileBuildPath (name, NULL, file);/* add file to path */
1266 
1267     fp = FileOpen(name, "r");
1268     if (fp == NULL)
1269     {
1270         AsnIoErrorMsg(NULL, 83, (CharPtr) name);
1271         return FALSE;
1272     }
1273 
1274     fscanf(fp, "%d %d %d", &numval, &numtype, &nummod);
1275 
1276     if (numval)
1277         avn = (AsnValxNodePtr) MemNew(numval * sizeof(AsnValxNode));
1278     at  = (AsnTypePtr)   MemNew(numtype * sizeof(AsnType));
1279     amp = (AsnModulePtr) MemNew(nummod  * sizeof(AsnModule));
1280 
1281     *avnptr = avn;
1282     *atptr = at;
1283     *ampptr = amp;
1284 
1285     avncurr = avn;
1286     for (i = 0; i < numval; i++)
1287     {
1288         fscanf(fp, "%d %s %ld %lf %d", &isa, name, &intvalue, &realvalue, &next);
1289         avncurr->valueisa = isa;
1290         if (*name != '-')
1291             avncurr->name = StringSave(name);
1292         avncurr->intvalue = (Int4)intvalue;
1293         avncurr->realvalue = (FloatHi)realvalue;
1294         avncurr->next = (AsnValxNodePtr) PointerDecode((Int2)next, avn, at);
1295         avncurr++;
1296     }
1297 
1298     atcurr = at;
1299     for (i = 0; i < numtype; i++)
1300     {
1301         fscanf(fp, "%d %s %d %d %d %d %d %d %d %d %d %d %d",
1302             &isa, name, &tagclass, &tagnumber, bools, bools+1, bools+2,
1303             bools+3, bools+4, &defaultvalue, &type, &branch, &next);
1304         atcurr->isa = isa;
1305         if (*name != '-')
1306         {
1307             atcurr->name = StringSave(name);
1308             ptr = atcurr->name;
1309             while (*ptr != '\0')
1310             {
1311                 if (*ptr == '!')
1312                     *ptr = ' ';
1313                 ptr++;
1314             }
1315         }
1316         atcurr->tagclass = (Uint1)tagclass;
1317         atcurr->tagnumber = tagnumber;
1318         atcurr->implicit = (Boolean)bools[0];
1319         atcurr->optional = (Boolean)bools[1];
1320         atcurr->hasdefault = (Boolean)bools[2];
1321         atcurr->exported = (Boolean)bools[3];
1322         atcurr->imported = (Boolean)bools[4];
1323         atcurr->defaultvalue = (AsnValxNodePtr)PointerDecode((Int2)defaultvalue, avn, at);
1324         atcurr->type = (AsnTypePtr)PointerDecode((Int2)type, avn, at);
1325         atcurr->branch = PointerDecode((Int2)branch, avn, at);
1326         atcurr->next = (AsnTypePtr)PointerDecode((Int2)next, avn,at);
1327         atcurr++;
1328     }
1329 
1330     ampcurr = amp;
1331     for (i = 0; i < nummod; i++)
1332     {
1333         fscanf(fp, "%s %s %d %d", name, fname, &type, &next);
1334         if (*name != '-')
1335             ampcurr->modulename = StringSave(name);
1336                 if (*fname != '-')
1337                         ampcurr->filename = StringSave(fname);
1338         ampcurr->types = (AsnTypePtr)PointerDecode((Int2)type, avn, at);
1339         if (next != -32000)
1340             ampcurr->next = &amp[next];
1341         ampcurr++;
1342     }
1343 
1344     FileClose(fp);
1345                                   /* store it in list */
1346     AsnStoreTree(file, (* ampptr));
1347 
1348     return TRUE;
1349 }
1350 
1351 /*****************************************************************************
1352 *
1353 *   AsnEnumStr(type, val)
1354 *
1355 *****************************************************************************/
1356 NLM_EXTERN CharPtr LIBCALL  AsnEnumStr (CharPtr type, Int2 val)
1357 {
1358     AsnTypePtr atp;
1359 
1360         if (amps == NULL)
1361         {
1362                 AsnIoErrorMsg(NULL, (Int2)105);
1363                 return NULL;
1364         }
1365     atp = AsnTypeFind((AsnModulePtr)amps->data.ptrvalue, type);
1366     return AsnEnumTypeStr(atp, val);
1367 }
1368 
1369 /*****************************************************************************
1370 *
1371 *   AsnEnumTypeStr(atp, val)
1372 *       returns string for ennumerated type val or a named integer
1373 *
1374 *****************************************************************************/
1375 NLM_EXTERN CharPtr LIBCALL  AsnEnumTypeStr (AsnTypePtr atp, Int2 val)
1376 {
1377     AsnValxNodePtr avnp;
1378 
1379     atp = AsnFindBaseType(atp);
1380     if (atp == NULL)
1381         return NULL;
1382 
1383     if ((atp->type->isa != ENUM_TYPE) && (atp->type->isa != INTEGER_TYPE))
1384         return NULL;
1385 
1386         avnp = (AsnValxNodePtr) atp->branch;
1387         while (avnp != NULL)
1388         {
1389                 if (val == (Int2) avnp->intvalue)
1390             return avnp->name;
1391                 else
1392                         avnp = avnp->next;
1393         }
1394     return NULL;
1395 }
1396 
1397 /*****************************************************************************
1398 *
1399 *   AsnAllModPtr()
1400 *      returns a pointer to the start of all modules in memory
1401 *
1402 *****************************************************************************/
1403 NLM_EXTERN AsnModulePtr LIBCALL  AsnAllModPtr (void)
1404 {
1405     if (amps == NULL)
1406         return NULL;
1407     return (AsnModulePtr)amps->data.ptrvalue;
1408 }
1409 
1410 
1411 
1412 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.