NCBI C Toolkit Cross Reference

C/asnlib/asnlex.c


  1 /*  asnlex.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: asnlex.c
 27 *
 28 * Author:  James Ostell
 29 *
 30 * Version Creation Date: 3/4/91
 31 *
 32 * $Revision: 6.5 $
 33 *
 34 * File Description:
 35 *   Routines for parsing ASN.1 value nototation (text) messages
 36 *
 37 * Modifications:  
 38 * --------------------------------------------------------------------------
 39 * Date     Name        Description of modification
 40 * -------  ----------  -----------------------------------------------------
 41 * 2/11/91  Ostell      AsnTxtReadVal - added check for unresolved base types
 42 * 3/4/91   Kans        Stricter typecasting for GNU C and C++
 43 * 3/4/91   Kans        AsnLexReadBoolean returns Boolean
 44 * 04-20-93 Schuler     LIBCALL calling convention
 45 *
 46 * $Log: asnlex.c,v $
 47 * Revision 6.5  2000/12/12 15:56:12  ostell
 48 * added support BigInt
 49 *
 50 * Revision 6.4  2000/03/10 18:02:05  kans
 51 * increased size of tbuf in AsnLexReadOctets to handle long lines in hand-edited (?) ASN.1 records being submitted
 52 *
 53 * Revision 6.3  1999/12/23 17:25:44  kans
 54 * AsnTxtReadVal checks for NULL atp - same as recent check in AsnBinReadVal
 55 *
 56 * Revision 6.2  1998/06/12 19:27:51  kans
 57 * fixed unix compiler warnings
 58 *
 59 * Revision 6.1  1997/10/29 02:41:31  vakatov
 60 * Type castings to pass through the C++ compiler
 61 *
 62 * Revision 6.0  1997/08/25 18:10:04  madden
 63 * Revision changed to 6.0
 64 *
 65 * Revision 5.3  1997/04/23 23:03:33  ostell
 66 * just added a typecast
 67 *
 68  * Revision 5.2  1997/04/23  21:23:03  ostell
 69  * changed BitHex reading routine to strip internal spaces and allow for linewraps at
 70  * any spacing.
 71  *
 72  * Revision 5.1  1996/12/03  21:43:48  vakatov
 73  * Adopted for 32-bit MS-Windows DLLs
 74  *
 75  * Revision 5.0  1996/05/28  14:00:29  ostell
 76  * Set to revision 5.0
 77  *
 78  * Revision 4.2  1996/02/18  16:45:36  ostell
 79  * changed fix_non_print behavior and added option 3
 80  *
 81  * Revision 4.1  1995/10/28  15:02:06  ostell
 82  * added casts to quiet DOS compile warnings
 83  *
 84  * Revision 4.0  1995/07/26  13:47:38  ostell
 85  * force revision to 4.0
 86  *
 87  * Revision 2.16  1995/05/15  18:38:28  ostell
 88  * added Log line
 89  *
 90 *
 91 * ==========================================================================
 92 */
 93 
 94 /*****************************************************************************
 95 *
 96 *   asnlex.c
 97 *       special text lexxer for asn.1
 98 *
 99 *****************************************************************************/
100 
101 #include "asnbuild.h"
102 
103 
104 /*****************************************************************************
105 *
106 *   Int2 AsnLexScan(aip, name)
107 *     scans until name ::= to start reading asn.1 past garbage
108 *
109 *****************************************************************************/
110 static Int2 AsnLexScan PROTO((AsnIoPtr aip, CharPtr name));
111 
112 /*****************************************************************************
113 *
114 *   AsnTypePtr AsnTxtReadId(aip, amp, atp)
115 *       reads identifier for next value
116 *
117 *****************************************************************************/
118 NLM_EXTERN AsnTypePtr LIBCALL  AsnTxtReadId (AsnIoPtr aip, AsnModulePtr amp, AsnTypePtr atp)
119 {
120         Int2 token, isa;
121         AsnTypePtr atp2, atp3, atp4;
122     PstackPtr currpsp, prevpsp;
123         Boolean is_ref;
124 
125         if (! aip->type_indent)    /* just starting reading */
126         {
127                 if (atp == NULL)       /* starting an unknown item */
128                 {
129                         token = AsnLexWord(aip);
130                         if (token == EOF_TOKEN)
131                                 return NULL;
132 
133                         if (token != REF)
134                         {
135                                 AsnIoErrorMsg(aip, 26, aip->linenumber);
136                                 return NULL;
137                         }
138         
139                         atp = AsnLexFindType(aip, amp);
140                         if (atp == NULL)
141                         {
142                                 AsnIoErrorMsg(aip, 27, aip->linenumber);
143                                 return NULL;
144                         }
145 
146                         token = AsnLexWord(aip);
147                         if (token != ISDEF)
148                         {
149                                 AsnIoErrorMsg(aip, 28, aip->linenumber);
150                                 return NULL;
151                         }
152                 }
153                 else               /* reading a known, possibly internal value */
154                 {
155                         if ((atp->name != NULL) &&    /* do we need to read a type ref? */
156                                 (IS_UPPER(*atp->name)))
157                                 is_ref = TRUE;
158                         else
159                                 is_ref = FALSE;
160 
161                         if ((is_ref) && (aip->scan_for_start))
162                         {
163                                 token = AsnLexScan(aip, atp->name);  /* scan to start */
164                                 if (token == EOF_TOKEN)
165                                         return NULL;
166                                 if (token != ISDEF)
167                                 {
168                                         AsnIoErrorMsg(aip, 28, aip->linenumber);
169                                         return NULL;
170                                 }
171                         }
172                         else if ((is_ref) || (aip->bytes))   /* reading an internal value */
173                         {
174                                 token = AsnLexWord(aip);
175                                 if (token == EOF_TOKEN)
176                                         return NULL;
177 
178                                 if (! StrMatch(atp->name, aip->word, aip->wordlen))
179                                 {
180                                         AsnIoErrorMsg(aip, 29,AsnErrGetTypeName(atp->name), aip->linenumber);
181                                         return NULL;
182                                 }
183                                 if (token == REF)        /* read of a non-internal value */
184                                 {
185                                         token = AsnLexWord(aip);
186                                         if (token != ISDEF)
187                                         {
188                                                 AsnIoErrorMsg(aip, 28, aip->linenumber);
189                                                 return NULL;
190                                         }
191                                 }
192                         }
193                         
194                 }
195 
196                 aip->typestack[0].type = atp;         /* load first type */
197                 aip->typestack[0].resolved = FALSE;
198         
199                 return atp;
200         }
201 
202     currpsp = & aip->typestack[aip->type_indent];
203     prevpsp = currpsp - 1;
204 
205         if (currpsp->type != NULL)   /* reading in a struct */
206         {
207                 token = AsnLexWord(aip);
208                 switch (token)
209                 {
210                         case COMMA:
211                                 break;
212                         case END_STRUCT:
213                                 return prevpsp->type;
214 
215                         default:
216                                 AsnIoErrorMsg(aip, 30, aip->linenumber);
217                                 return NULL;
218                 }
219         }
220 
221             /* check for SEQOF and SETOF */
222         
223         atp = prevpsp->type;
224         atp2 = AsnFindBaseType(atp);
225         isa = atp2->type->isa;
226         if ((isa == SEQOF_TYPE) || (isa == SETOF_TYPE))
227         {
228                 token = AsnLexWord(aip);
229         if (token == END_STRUCT)    /* empty set */
230             return prevpsp->type;
231         aip->tagsaved = TRUE;       /* not empty, note not read */
232                 atp = (AsnTypePtr) atp2->branch;   /* set of what type? */
233                 currpsp->type = atp;
234                 currpsp->resolved = FALSE;
235                 return atp;   /* no type identifier */
236         }
237         
238 
239         token = AsnLexWord(aip);
240 
241         if (token == EOF_TOKEN)
242         {
243                 AsnIoErrorMsg(aip, 17 );
244                 return NULL;
245         }
246 
247     if ((token == END_STRUCT) && ((isa == SEQ_TYPE) || (isa == SET_TYPE)))
248         return prevpsp->type;   /* empty SET/SEQ */
249 
250         if (token != IDENT)
251         {
252                 AsnIoErrorMsg(aip, 31, aip->linenumber);
253                 return NULL;
254         }
255 
256         atp = AsnLexFindElement(aip, (AsnTypePtr) atp2->branch);
257         if (atp == NULL)
258         {
259                 AsnIoErrorMsg(aip, 32, AsnErrGetTypeName(prevpsp->type->name), aip->linenumber);
260                 return NULL;
261         }
262 
263         if (atp2->type->isa == SEQ_TYPE)      /* check sequence order */
264         {
265                 atp3 = currpsp->type;
266                 if (atp3 != NULL)
267                 {
268                         atp4 = (AsnTypePtr) atp2->branch;
269                         atp3 = atp3->next;
270                         while (atp4 != atp3)
271                         {
272                                 if (atp == atp4)
273                                 {
274                                         AsnIoErrorMsg(aip, 33,AsnErrGetTypeName(atp->name), AsnErrGetTypeName(atp2->name), aip->linenumber);
275                                         return NULL;
276                                 }
277                                 atp4 = atp4->next;
278                         }
279                 }
280                 else
281                         atp3 = (AsnTypePtr) atp2->branch;
282 
283                 while ((atp3 != NULL) && (atp3 != atp))
284                 {
285                         if (! (atp3->optional || atp3->hasdefault))
286                         {
287                                 AsnIoErrorMsg(aip, 34,AsnErrGetTypeName(atp3->name), AsnErrGetTypeName(atp2->name), aip->linenumber);
288                                 return NULL;
289                         }
290                         atp3 = atp3->next;
291                 }
292         }
293 
294         currpsp->type = atp;
295         currpsp->resolved = FALSE;    /* mark first use */
296         return atp;
297 }
298 
299 /*****************************************************************************
300 *
301 *   Int2 AsnTxtReadVal(aip, atp, valueptr)
302 *       read the value pointed at by atp
303 *       returns START_STRUCT
304 *               END_STRUCT
305 *                       or 1 if ok
306 *                       0 if an error
307 *       if (valueptr == NULL)
308 *               just checks that value is of proper type
309 *
310 *****************************************************************************/
311 NLM_EXTERN Int2 LIBCALL  AsnTxtReadVal (AsnIoPtr aip, AsnTypePtr atp, DataValPtr valueptr)
312 {
313         Int2 isa, token, retval;
314         Boolean terminalvalue;      /* set if read a terminal value */
315         AsnTypePtr atp2;
316         Boolean read_value;
317         DataVal fake_value;
318         AsnTypePtr base_type, curr_type;
319     PstackPtr currpsp;
320 
321         retval = 1;  /* assume success */
322     currpsp = & aip->typestack[aip->type_indent];
323         curr_type = currpsp->type;
324 
325         if (atp == NULL)
326                 return 0;
327 
328         base_type = AsnFindBaseType(atp);     
329     if (base_type == NULL)     /* not found */
330     {
331         base_type = atp;   
332         while (base_type->type != NULL)
333             base_type = base_type->type;
334         if (base_type->imported)
335                 {
336             AsnIoErrorMsg(aip,35, AsnErrGetTypeName(atp->name), base_type->name, aip->linenumber);
337                         return 0;
338                 }
339        else
340                 {
341             AsnIoErrorMsg(aip,36, AsnErrGetTypeName(atp->name), base_type->name, aip->linenumber);
342                         return 0;
343                 }
344     }
345         isa = base_type->type->isa;
346 
347         if (valueptr == NULL)       /* just check the value */
348         {
349                 read_value = FALSE;
350                 valueptr = &fake_value;
351         }
352         else
353                 read_value = TRUE;
354 
355         terminalvalue = TRUE;    /* most values are terminal values */
356 
357         if (ISA_STRINGTYPE(isa))
358                 isa = GENERALSTRING_TYPE;
359 
360         switch (isa)
361         {
362                 case SEQ_TYPE:
363                 case SET_TYPE:
364                 case SETOF_TYPE:
365                 case SEQOF_TYPE:
366                         terminalvalue = FALSE;  /* handled by AsnTypeSetIndent() */
367                         if (aip->token != END_STRUCT)   /* should be open brace */
368                         {
369                                 token = AsnLexWord(aip);    /* read open brace */
370                                 if (token != START_STRUCT)
371                                 {
372                                         AsnIoErrorMsg(aip, 37, aip->linenumber);
373                                         return 0;
374                                 }
375                                 AsnTypeSetIndent(TRUE, aip, atp);  
376                                 retval = START_STRUCT;
377                                 valueptr->intvalue = START_STRUCT;
378                                 terminalvalue = FALSE;
379                         }
380                         else
381                         {                          /* close brace already read in AsnTxtReadId */
382                                 switch (isa)
383                                 {
384                                         case SEQOF_TYPE:
385                                         case SETOF_TYPE:
386                                                 break;
387                                         case SEQ_TYPE:       /* check that no more waiting */
388                                         if (curr_type != NULL)   /* check next one */
389                                                 atp2 = curr_type->next;
390                                         else                     /* empty sequence written */
391                                                 atp2 = (AsnTypePtr)base_type->branch;
392                                                 while (atp2 != NULL)
393                                                 {
394                                                         if (! (atp2->optional || atp2->hasdefault))
395                                                         {
396 
397                                                                 AsnIoErrorMsg(aip, 34, AsnErrGetTypeName(atp2->name), base_type->name, aip->linenumber);
398                                                                 return 0;
399                                                         }
400                                                         atp2 = atp2->next;
401                                                 }
402                                                 break;
403                                         default:
404                                                 break;
405                                 }
406                                 AsnTypeSetIndent(FALSE, aip, atp);  
407                                 retval = END_STRUCT;
408                                 valueptr->intvalue = END_STRUCT;
409                         }
410                         break;
411                 case CHOICE_TYPE:
412                         AsnTypeSetIndent(TRUE, aip, atp);  /* nest down to type */
413                         terminalvalue = FALSE;
414                         break;
415                 case BOOLEAN_TYPE:
416                         valueptr->boolvalue = AsnLexReadBoolean(aip, atp);
417                         break;
418                 case INTEGER_TYPE:
419                 case ENUM_TYPE:
420                         valueptr->intvalue = AsnLexReadInteger(aip, atp);
421                         break;
422                 case BIGINT_TYPE:
423                         valueptr->bigintvalue = AsnLexReadBigInt(aip, atp);
424                         break;
425                 case REAL_TYPE:
426                         valueptr->realvalue = AsnLexReadReal(aip, atp);
427                         break;
428                 case GENERALSTRING_TYPE:
429                         if (read_value)
430                         {
431                                 valueptr->ptrvalue = AsnLexReadString(aip, atp);
432                                 if (valueptr->ptrvalue == NULL)
433                                         return 0;
434                         }
435                         else
436                         {
437                                 if (! AsnLexSkipString(aip, atp))
438                                         return 0;
439                         }
440                         break;
441                 case NULL_TYPE:
442                         AsnLexReadNull(aip, atp);
443                         break;
444                 case OCTETS_TYPE:
445                         if (read_value)
446                         {
447                                 valueptr->ptrvalue = AsnLexReadOctets(aip, atp);
448                                 if (valueptr->ptrvalue == NULL) return 0;
449                         }
450                         else
451                                 AsnLexSkipOctets(aip, atp);
452                         break;
453                 case STRSTORE_TYPE:
454                         if (read_value)
455                         {
456                                 valueptr->ptrvalue = (ByteStorePtr) AsnLexReadString(aip, atp);
457                                 if (valueptr->ptrvalue == NULL)
458                                         return 0;
459                         }
460                         else
461                         {
462                                 if (! AsnLexSkipString(aip, atp))
463                                         return 0;
464                         }
465                         break;
466                 default:
467                         AsnIoErrorMsg(aip, 38,  AsnErrGetTypeName(atp->name),aip->linenumber);
468                         return 0;
469         }
470 
471         if (terminalvalue)       /* pop out of any CHOICE nests */
472         {
473                 while ((aip->type_indent) &&
474                         (AsnFindBaseIsa(aip->typestack[aip->type_indent - 1].type) == CHOICE_TYPE))
475                         AsnTypeSetIndent(FALSE, aip, atp);
476         }
477 
478         return retval;
479 }
480 
481 /*****************************************************************************
482 *
483 *   AsnTypePtr AsnLexFindType(aip, amp)
484 *       returns pointer to type definition in amp
485 *       or NULL if not found
486 *
487 *****************************************************************************/
488 NLM_EXTERN AsnTypePtr AsnLexFindType (AsnIoPtr aip, AsnModulePtr amp)
489 {
490         AsnTypePtr atp;
491         
492         while (amp != NULL)
493         {
494                 atp = AsnLexFindElement(aip, amp->types);
495                 if (atp != NULL)
496                         return atp;
497 
498                 amp = amp->next;
499         }
500         return NULL;
501 }                               
502 
503 /*****************************************************************************
504 *
505 *   AsnTypePtr AsnLexFindElement(aip, atp)
506 *       finds an element in a list of elements
507 *       (elements of SEQ, SET, CHOICE)
508 *
509 *****************************************************************************/
510 NLM_EXTERN AsnTypePtr AsnLexFindElement (AsnIoPtr aip, AsnTypePtr atp)
511 {
512         while (atp != NULL)
513         {
514                 if (StrMatch(atp->name, aip->word, aip->wordlen))   /* it matches */
515                         return atp;
516                 else
517                         atp = atp->next;
518         }
519         return NULL;
520 }
521 
522 
523 /*****************************************************************************
524 *
525 *   Int4 AsnLexReadInteger(aip, atp)
526 *       expects an INTEGER or ENUMERATED next
527 *       assumes none of it has already been read
528 *       does not advance to next token
529 *       atp points to the definition of this integer for named values
530 *
531 *****************************************************************************/
532 NLM_EXTERN Int4 AsnLexReadInteger (AsnIoPtr aip, AsnTypePtr atp)
533 {
534         Int2 token;
535         AsnValxNodePtr avnp;
536         AsnTypePtr atp2;
537 
538         token = AsnLexWord(aip);      /* read the integer */
539 
540         if (token == NUMBER)    /* just a number */
541         {
542                 return AsnLexInteger(aip);
543         }
544 
545         if (token != IDENT)    /* not number or named value */
546         {
547                 AsnIoErrorMsg(aip, 39, AsnErrGetTypeName(atp->name), aip->linenumber);
548                 return 0;
549         }
550 
551                         /******************** read a named integer value *********/
552         atp2 = AsnFindBaseType(atp);
553         if (atp2->branch != NULL)       /* named values */
554         {
555                 avnp = (AsnValxNodePtr) atp2->branch;
556                 while (avnp != NULL)
557                 {
558                         if (StrMatch(avnp->name, aip->word, aip->wordlen))
559                                 return avnp->intvalue;
560                         avnp = avnp->next;
561                 }
562         }
563 
564         if (atp2->type->isa == ENUM_TYPE)   /* enumerated MUST match named value */
565         {
566                 AsnIoErrorMsg(aip, 40, AsnErrGetTypeName(atp->name), aip->linenumber);
567                 return 0;
568         }
569 
570                    /******************* could it be a previously defined value? ***/
571 
572         AsnIoErrorMsg(aip, 41, AsnErrGetTypeName(atp->name), aip->linenumber);
573 
574         return 0;
575 }
576 
577 /*****************************************************************************
578 *
579 *   Int8 AsnLexReadBigInt(aip, atp)
580 *       expects an INTEGER next
581 *       assumes none of it has already been read
582 *       does not advance to next token
583 *       atp points to the definition of this integer for named values
584 *
585 *****************************************************************************/
586 NLM_EXTERN Int8 AsnLexReadBigInt (AsnIoPtr aip, AsnTypePtr atp)
587 {
588         Int2 token;
589 
590         token = AsnLexWord(aip);      /* read the integer */
591 
592         if (token == NUMBER)    /* just a number */
593         {
594                 return AsnLexBigInt(aip);
595         }
596 
597         if (token != IDENT)    /* not number or named value */
598         {
599                 AsnIoErrorMsg(aip, 39, AsnErrGetTypeName(atp->name), aip->linenumber);
600                 return 0;
601         }
602 
603                         /******************** read a named integer value *********/
604                         /**** not supported for bigint *****/
605 
606                    /******************* could it be a previously defined value? ***/
607 
608         AsnIoErrorMsg(aip, 41, AsnErrGetTypeName(atp->name), aip->linenumber);
609 
610         return (Int8)0;
611 }
612 
613 /*****************************************************************************
614 *
615 *   Boolean AsnLexReadBoolean(aip, atp)
616 *       expects a BOOLEAN next
617 *       assumes none of it has already been read
618 *       does not advance to next token
619 *       atp points to the definition of this BOOLEN
620 *
621 *****************************************************************************/
622 NLM_EXTERN Boolean AsnLexReadBoolean (AsnIoPtr aip, AsnTypePtr atp)
623 {
624         AsnLexWord(aip);      /* read the boolean */
625 
626         if (StrMatch("TRUE", aip->word, aip->wordlen))
627                 return TRUE;
628         else if (StrMatch("FALSE", aip->word, aip->wordlen))
629                 return FALSE;
630 
631         AsnIoErrorMsg(aip, 42, AsnErrGetTypeName(atp->name), aip->linenumber);
632 
633         return FALSE;      /* just for lint */
634 }
635 
636 /*****************************************************************************
637 *
638 *   Int4 AsnLexReadString(aip, atp)
639 *       expects any String type next
640 *       assumes none of it has already been read
641 *       does not advance to next token
642 *       atp points to the definition of this String
643 *       if atp->type->isa == a string type
644 *               packs String to single value, if segmented on input
645 *       otherwise returns the stringstoreptr itself
646 *
647 *****************************************************************************/
648 NLM_EXTERN Pointer AsnLexReadString (AsnIoPtr aip, AsnTypePtr atp)
649 {
650         Int2 token;
651         ByteStorePtr ssp;
652         CharPtr result=NULL;
653         Int4 bytes;
654 
655         token = AsnLexWord(aip);      /* read the start */
656         if (token != START_STRING)
657         {
658                 AsnIoErrorMsg(aip, 43, AsnErrGetTypeName(atp->name), aip->linenumber);
659                 return NULL;
660         }
661 
662         ssp = BSNew(0);
663         if (ssp == NULL) return result;
664         token = AsnLexWord(aip);   /* read the string(s) */
665         while (token == IN_STRING)
666         {
667                 bytes = BSWrite(ssp, aip->word, (Int4)aip->wordlen);
668                 if (bytes != (Int4)(aip->wordlen))
669                 {
670                         BSFree(ssp);
671                         return result;
672                 }
673                 token = AsnLexWord(aip);
674         }
675 
676         if (token == ERROR_TOKEN) return NULL;
677 
678         if (token != END_STRING)
679         {
680                 AsnIoErrorMsg(aip, 44, AsnErrGetTypeName(atp->name), aip->linenumber);
681                 return NULL;
682         }
683         if (AsnFindBaseIsa(atp) == STRSTORE_TYPE)    /* string store */
684                 return ssp;
685 
686         result = (CharPtr) BSMerge(ssp, NULL);
687         BSFree(ssp);
688 
689         return result;
690 }
691 
692 /*****************************************************************************
693 *
694 *   void AsnLexSkipString(aip, atp)
695 *       expects any String type next
696 *       assumes none of it has already been read
697 *       does not advance to next token
698 *       atp points to the definition of this String
699 *       just reads past end of string
700 *
701 *****************************************************************************/
702 NLM_EXTERN Boolean AsnLexSkipString (AsnIoPtr aip, AsnTypePtr atp)
703 {
704         Int2 token;
705 
706         token = AsnLexWord(aip);      /* read the start */
707         if (token != START_STRING)
708         {
709                 AsnIoErrorMsg(aip, 43, AsnErrGetTypeName(atp->name), aip->linenumber);
710                 return FALSE;
711         }
712 
713         token = AsnLexWord(aip);   /* read the string(s) */
714         while (token == IN_STRING)
715                 token = AsnLexWord(aip);
716 
717         if (token == ERROR_TOKEN) return FALSE;
718 
719         if (token != END_STRING)
720                 AsnIoErrorMsg(aip, 44, AsnErrGetTypeName(atp->name), aip->linenumber);
721 
722         return TRUE;
723 }
724 
725 /*****************************************************************************
726 *
727 *   ByteStorePtr AsnLexReadOctets(aip, atp)
728 *       expects Octets type next
729 *       assumes none of it has already been read
730 *       does not advance to next token
731 *       atp points to the definition of this OCTET STRING
732 *
733 *****************************************************************************/
734 NLM_EXTERN ByteStorePtr AsnLexReadOctets (AsnIoPtr aip, AsnTypePtr atp)
735 {
736         Int2 token, len;
737         ByteStorePtr ssp = NULL;
738         Byte tbuf[256]; /* was 101 - changed to handle occasional hand-edited ASN.1? */
739         Int4 bytes, left, added;
740 
741         token = AsnLexWord(aip);      /* read the start */
742         if (token != START_BITHEX)
743         {
744                 AsnIoErrorMsg(aip, 45, AsnErrGetTypeName(atp->name), aip->linenumber);
745                 return NULL;
746         }
747         ssp = BSNew(0);
748         if (ssp == NULL) return ssp;
749         token = AsnLexWord(aip);   /* read the octet(s) */
750         left = 0;
751         while (token == IN_BITHEX)
752         {
753                 len = (Int2)(aip->wordlen + left);
754                 MemCopy((tbuf + left), aip->word, (len - left));
755                 tbuf[len] = '\0';
756                 added = AsnTypeStringToHex(tbuf, len, tbuf, &left);
757                 if (added < 0)
758                 {
759                         AsnIoErrorMsg(aip, 46, AsnErrGetTypeName(atp->name), aip->linenumber);
760                         return NULL;
761                 }
762                 if (added)
763                 {
764                         bytes = BSWrite(ssp, tbuf, added);
765                         if (bytes != added)
766                         {
767                                 ssp = BSFree(ssp);
768                                 return ssp;
769                         }
770                 }
771                 if (left)   /* left a char */
772                 {
773                         MemCopy(tbuf, ((aip->word)+(aip->wordlen - left)),left);
774                 }
775 
776                 token = AsnLexWord(aip);
777         }
778         
779         if (token != OCTETS)
780         {
781                 AsnIoErrorMsg(aip, 47, AsnErrGetTypeName(atp->name), aip->linenumber);
782                 return NULL;
783         }
784 
785         return ssp;
786 }
787 
788 /*****************************************************************************
789 *
790 *   void AsnLexSkipOctets(aip, atp)
791 *       expects Octets type next
792 *       assumes none of it has already been read
793 *       does not advance to next token
794 *       atp points to the definition of this OCTET STRING
795 *
796 *****************************************************************************/
797 NLM_EXTERN void AsnLexSkipOctets (AsnIoPtr aip, AsnTypePtr atp)
798 {
799         Int2 token, left, len;
800     Int4 line;
801 
802         token = AsnLexWord(aip);      /* read the start */
803         if (token != START_BITHEX)
804         {
805                 AsnIoErrorMsg(aip, 45, AsnErrGetTypeName(atp->name), aip->linenumber);
806                 return;
807         }
808 
809     line = aip->linenumber;
810         token = AsnLexWord(aip);   /* read the octet(s) */
811     left = 0;
812         while (token == IN_BITHEX)
813         {
814         len = aip->wordlen + left;
815         left = len % 2;
816                 token = AsnLexWord(aip);
817         }
818 
819     if (left)
820         {
821         AsnIoErrorMsg(aip, 48, AsnErrGetTypeName(atp->name), line);
822                 return;
823         }
824         
825         if (token != OCTETS)
826                 AsnIoErrorMsg(aip, 47, AsnErrGetTypeName(atp->name), aip->linenumber);
827 
828         return;
829 }
830 
831 /*****************************************************************************
832 *
833 *   FloatHi AsnLexReadReal(aip, atp)
834 *       expects a REAL next
835 *       assumes none of it has already been read
836 *       does not advance to next token
837 *       atp points to the definition of this REAL
838 *
839 *****************************************************************************/
840 NLM_EXTERN FloatHi AsnLexReadReal (AsnIoPtr aip, AsnTypePtr atp)
841 {
842         Int2 token;
843         double mantissa, result;
844         int     base, exponent;
845         char buf[15];
846 
847         result = 0.0;
848         token = AsnLexWord(aip);      /* read the { */
849         if (token != START_STRUCT)
850         {
851                 AsnIoErrorMsg(aip, 49, AsnErrGetTypeName(atp->name), aip->linenumber);
852                 return (FloatHi)result;
853         }
854 
855         token = AsnLexWord(aip);      /* read mantissa */
856         if (token != NUMBER)
857         {
858                 AsnIoErrorMsg(aip, 50, AsnErrGetTypeName(atp->name), aip->linenumber);
859                 return (FloatHi)result;
860         }
861         MemCopy(buf, aip->word, (size_t)aip->wordlen);
862         buf[aip->wordlen] = '\0';
863         mantissa = atof(buf);
864 
865         token = AsnLexWord(aip);      /* read comma */
866         if (token != COMMA)
867         {
868                 AsnIoErrorMsg(aip, 51, AsnErrGetTypeName(atp->name), aip->linenumber);
869                 return (FloatHi)result;
870         }
871 
872         token = AsnLexWord(aip);      /* read base */
873         if (token != NUMBER)
874         {
875                 AsnIoErrorMsg(aip, 52, AsnErrGetTypeName(atp->name), aip->linenumber);
876                 return (FloatHi)result;
877         }
878         MemCopy(buf, aip->word, (size_t)aip->wordlen);
879         buf[aip->wordlen] = '\0';
880         base = atoi(buf);
881         if ((base != 2) && (base != 10))
882         {
883                 AsnIoErrorMsg(aip, 53, AsnErrGetTypeName(atp->name), aip->linenumber);
884                 return (FloatHi)result;
885         }
886 
887         token = AsnLexWord(aip);
888         if (token != COMMA)
889         {
890                 AsnIoErrorMsg(aip, 54, AsnErrGetTypeName(atp->name), aip->linenumber);
891                 return (FloatHi)result;
892         }
893 
894         token = AsnLexWord(aip);
895         if (token != NUMBER)
896         {
897                 AsnIoErrorMsg(aip, 55, AsnErrGetTypeName(atp->name), aip->linenumber);
898                 return (FloatHi)result;
899         }
900         MemCopy(buf, aip->word, (size_t)aip->wordlen);
901         buf[aip->wordlen] = '\0';
902         exponent = atoi(buf);
903 
904         token = AsnLexWord(aip);
905         if (token != END_STRUCT)
906         {
907                 AsnIoErrorMsg(aip, 56, AsnErrGetTypeName(atp->name), aip->linenumber);
908                 return (FloatHi)result;
909         }
910     
911     if (base == 10)      /* range checking only on base 10, for doubles */
912     {
913         if (exponent > DBL_MAX_10_EXP)   /* exponent too big */
914                 return  (FloatHi)DBL_MAX;
915         else if (exponent < DBL_MIN_10_EXP)  /* exponent too small */
916                 return (FloatHi)result;
917     }
918         
919         result = mantissa * Nlm_Powi((double)base, exponent);
920 
921         return (FloatHi)result;
922 }
923 
924 /*****************************************************************************
925 *
926 *   void AsnLexReadNull(aip, atp)
927 *
928 *****************************************************************************/
929 NLM_EXTERN void AsnLexReadNull (AsnIoPtr aip, AsnTypePtr atp)
930 {
931         AsnLexWord(aip);
932         if (! StrMatch("NULL", aip->word, aip->wordlen))
933         {
934                 AsnIoErrorMsg(aip, 57, AsnErrGetTypeName(atp->name), aip->linenumber);
935                 return;
936         }
937         return;
938 }
939 
940 /*****************************************************************************
941 *
942 *   CharPtr AsnLexSaveWord(aip)
943 *       create a new null terminated string from
944 *       a non null terminated string (word) of length (len)
945 *
946 *****************************************************************************/
947 NLM_EXTERN CharPtr AsnLexSaveWord (AsnIoPtr aip)
948 {
949         CharPtr ptr;
950 
951         ptr = (CharPtr) MemNew((size_t)(aip->wordlen + 1));
952         MemCopy(ptr, aip->word, (size_t)aip->wordlen);
953         return ptr;
954 }
955 
956 /*****************************************************************************
957 *
958 *   void AsnLexSkipStruct(aip)
959 *       skips current structure and all substructures
960 *       Does NOT read following element
961 *
962 *****************************************************************************/
963 NLM_EXTERN void AsnLexSkipStruct (AsnIoPtr aip)
964 {
965         int type_indent = 1;
966         Int2 token;
967 
968         while (type_indent)
969         {
970                 token = AsnLexWord(aip);
971                 switch (token)
972                 {
973                         case START_STRUCT:       /* another substructure */
974                                 type_indent++;
975                                 break;
976                         case END_STRUCT:                /* a close brace */
977                                 type_indent--;
978                                 break;
979                         case EOF_TOKEN:
980                                 AsnIoErrorMsg(aip, 17);
981                                 return;
982                         default:
983                                 break;
984                 }
985         }
986 
987         return;
988 }
989 
990 /*****************************************************************************
991 *
992 *   Int4 AsnLexInteger(aip)
993 *
994 *****************************************************************************/
995 NLM_EXTERN Int4 AsnLexInteger (AsnIoPtr aip)
996 {
997         char tbuf[11];
998         Int4 value;
999 
1000         MemCopy(tbuf, aip->word, (size_t)aip->wordlen);
1001         tbuf[aip->wordlen] = '\0';
1002         value = atol(tbuf);
1003         return value;
1004 }
1005 
1006 /*****************************************************************************
1007 *
1008 *   Int8 AsnLexBigInt(aip)
1009 *
1010 *****************************************************************************/
1011 NLM_EXTERN Int8 AsnLexBigInt (AsnIoPtr aip)
1012 {
1013         char tbuf[40];
1014         Int8 value;
1015         const char * result;
1016 
1017         MemCopy(tbuf, aip->word, (size_t)aip->wordlen);
1018         tbuf[aip->wordlen] = '\0';
1019         value = Nlm_StringToInt8 (tbuf, &result);
1020         return value;
1021 }
1022 
1023 /*****************************************************************************
1024 *
1025 *   Int2 AsnLexWord(aip)
1026 *       reads words, punctuation
1027 *       returns tokens defined in asntypes.h
1028 *       does not return ASN reserved words - use AsnLexWord() for that
1029 *
1030 *****************************************************************************/
1031 
1032 NLM_EXTERN Int2 AsnLexWord (AsnIoPtr aip)
1033 {
1034         register CharPtr pos;
1035         Int1 state;
1036         Int2 token;
1037         register int linepos, len;
1038         int done;
1039 
1040     if (aip->tagsaved)     /* had to read ahead */
1041     {
1042         aip->tagsaved = FALSE;
1043         return aip->token;
1044     }
1045 
1046     if (! aip->bytes)        /* no data loaded */
1047                 AsnIoGets(aip);
1048                 
1049         linepos = aip->linepos;
1050         pos = aip->linebuf + linepos;
1051         state = aip->state;
1052         len = 0;
1053 
1054         while (*pos == '\n' || *pos == '\r')    /* skip empty lines */
1055         {
1056                 pos = AsnIoGets(aip);   /* get a line */
1057 
1058                 if (pos == NULL)
1059                         return EOF_TOKEN;
1060         }
1061         
1062         if (state == IN_STRING_STATE)
1063         {
1064                 aip->word = pos;
1065                 if ((* pos == '\"') && (*(pos + 1) != '\"'))    /* end of string */
1066                 {
1067                         token = END_STRING;
1068                         pos++;
1069                         state = 0;        /* reset state */
1070                 }
1071                 else
1072                 {
1073                         token = IN_STRING;
1074                         while ((* pos != '\"') && (* pos != '\n') && (* pos != '\r'))
1075                         {
1076                                 if ((aip->fix_non_print != 2) && ((*pos < ' ') || (*pos > '~')))
1077                                 {
1078                                         done = (int)(*pos);
1079                                         *pos = '\0';
1080                                         if ((aip->fix_non_print == 0) || (aip->fix_non_print == 3))
1081                                         {
1082                                                 AsnIoErrorMsg(aip, 106, done, aip->word);
1083                                         }
1084                                         done = 0;
1085                                         *pos = '#';   /* replace with # */
1086                                 }
1087                                 pos++; len++;
1088                         }
1089 
1090                         if ((*pos != '\n') && (*pos != '\r') && (* (pos + 1) == '\"')) /* internal quote */
1091                         {
1092                                 len++;        /* include in previous string */
1093                                 pos += 2;     /* point to rest of string */
1094                         }
1095                 }
1096         }
1097         else if (state == IN_BITHEX_STATE)
1098         {
1099                 aip->word = pos;
1100                 if (*pos == '\'')                         /* end of binhex */
1101                 {
1102                         state = 0;              /* set to normal */
1103                         pos++;                       /* move past quote */
1104                         while (IS_WHITESP(*pos))
1105                         {
1106                                 if (*pos == '\n' || *pos == '\r')    /* skip empty lines */
1107                                 {
1108                                         pos = AsnIoGets(aip);   /* get a line */
1109                                         
1110                                         if (pos == NULL)
1111                                         return EOF_TOKEN;
1112                                 }
1113                                 else
1114                                         pos++;
1115                         }
1116                         if (* pos == 'H')
1117                                 token = OCTETS;
1118                         else if (* pos == 'B')
1119                                 token = ASNBITS;
1120                         else
1121                         {
1122                                 AsnIoErrorMsg(aip, 58, aip->linenumber);
1123                                 token = ERROR_TOKEN;
1124                         }
1125                         pos++;         /* move past H or B */
1126                 }
1127                 else
1128                 {
1129                         token = IN_BITHEX;
1130                         while ((* pos != '\'') && (* pos != '\n') && (* pos != '\r'))
1131                         {
1132                                 pos++; len++;
1133                         }
1134                 }   
1135         }
1136         else              /* normal scanning */
1137         {
1138                 while ((* pos <= ' ') || ((*pos == '-') && (*(pos+1) == '-')))     /* skip leading white space */
1139                 {
1140                         if (*pos == '\n' || *pos == '\r')
1141                         {
1142                                 pos = AsnIoGets(aip);
1143 
1144                                 if (pos == NULL)
1145                                         return EOF_TOKEN;
1146                         }
1147                         else if ((*pos == '-') && (*(pos+1) == '-'))   /* skip comments */
1148                         {
1149                                 pos += 2;
1150                                 done = 0;
1151                                 while (! done)
1152                                 {
1153                                         if ((*pos == '-') && (*(pos +1) == '-'))
1154                                         {
1155                                                 pos += 2;
1156                                                 done = 1;
1157                                         }
1158                                         else if (*pos == '\n' || *pos == '\r')
1159                                                 done = 1;
1160                                         else
1161                                                 pos++;
1162                                 }
1163                         }
1164                         else
1165                                 pos++;
1166                         
1167                 }
1168 
1169                 aip->word = pos;
1170                 if (* pos == '\"')
1171                 {
1172                         token = START_STRING;
1173                         state = IN_STRING_STATE;
1174                 }
1175                 else if (* pos == '\'')
1176                 {
1177                         token = START_BITHEX;
1178                         state = IN_BITHEX_STATE;
1179                 }
1180                 else if (* pos == ',')
1181                         token = COMMA;
1182                 else if (* pos == '{')
1183                         token = START_STRUCT;
1184                 else if (* pos == '}')
1185                         token = END_STRUCT;
1186                 else if (* pos == '[')
1187                         token = START_TAG;
1188                 else if (* pos == ']')
1189                         token = END_TAG;
1190                 else if (* pos == '(')
1191                         token = OPEN_PAREN;
1192                 else if (* pos == ')')
1193                         token = CLOSE_PAREN;
1194                 else if (* pos == ';')
1195                         token = SEMI_COLON;
1196                 else if (* pos == ':')
1197                 {
1198                         if ((*(pos + 1) == ':') && (*(pos + 2) == '='))
1199                         {
1200                                 token = ISDEF;
1201                                 pos += 2;
1202                                 len = 3;
1203                         }
1204                         else
1205                         {
1206                                 AsnIoErrorMsg(aip, 59, *pos, aip->linenumber);
1207                                 token = ERROR_TOKEN;
1208                         }
1209                 }
1210                 else if (IS_UPPER(*pos))  /* a reference or keyword */
1211                 {
1212                         token = REF;
1213                         while ((IS_ALPHANUM(*pos)) || (*pos == '-'))
1214                         {
1215                                 pos++; len++;
1216                         }
1217                         pos--;    /* move back for increment at end */
1218                         len--;
1219                 }
1220                 else if (IS_LOWER(*pos))  /* an identifier or valuereference */
1221                 {
1222                         token = IDENT;
1223                         while ((IS_ALPHANUM(*pos)) || (*pos == '-'))
1224                         {
1225                                 pos++; len++;
1226                         }
1227                         pos--;            /* move back for increment at end */
1228                         len--;
1229                 }
1230                 else if ((IS_DIGIT(*pos)) || ((*pos == '-') && (IS_DIGIT(*(pos+1)))))
1231                 {
1232                         token = NUMBER;
1233                         if (*pos == '-')
1234                         {
1235                                 pos++; len++;
1236                         }
1237 
1238                         while (IS_DIGIT(*pos))
1239                         {
1240                                 pos++; len++;
1241                         }
1242                         pos--;    /* move back for increment at end */
1243                         len--;
1244                 }
1245                 else
1246                 {
1247                         AsnIoErrorMsg(aip, 59, *pos, aip->linenumber);
1248                         token = ERROR_TOKEN;
1249                 }
1250                 len++; pos++;     /* move over last symbol */
1251         }
1252 
1253         aip->linepos = pos - aip->linebuf;
1254 /******************** check on MSWIN
1255         linepos = 0;
1256         while (pos != linebuf)
1257         {
1258                 linepos++;
1259                 pos++;
1260         }
1261         aip->linepos = linepos;
1262 **********************/
1263         aip->state = state;
1264         aip->wordlen = len;
1265         aip->token = token;
1266         return token;
1267 }
1268 
1269 /*****************************************************************************
1270 *
1271 *   Boolean StrMatch(a, b, len)
1272 *       returns TRUE if a matches b for EXACTLY len
1273 *       and a has a '\0' after that
1274 *
1275 *****************************************************************************/
1276 NLM_EXTERN Boolean StrMatch (CharPtr a, CharPtr b, Int2 len)
1277 {
1278         if ((a == NULL) || (b == NULL))
1279                 return FALSE;
1280                 
1281         while (len)
1282         {
1283                 if (*a != *b)
1284                         return FALSE;
1285                 a++; b++; len--;
1286         }
1287         if (*a != '\0')
1288                 return FALSE;
1289         return TRUE;
1290 }
1291 
1292 
1293 /*****************************************************************************
1294 *
1295 *   Int2 AsnLexScan(aip, name)
1296 *     scans until name ::= to start reading asn.1 past garbage
1297 *
1298 *****************************************************************************/
1299 static Int2 AsnLexScan (AsnIoPtr aip, CharPtr name)
1300 {
1301         register CharPtr pos;
1302         Int2 token = 0;
1303         register int linepos, len;
1304         int done;
1305         Boolean started = FALSE, matched_ref = FALSE;
1306 
1307         if (aip->type_indent)   /* only for start */
1308                 return ERROR_TOKEN;
1309 
1310    if (! aip->bytes)        /* no data loaded */
1311                 AsnIoGets(aip);
1312                 
1313         linepos = aip->linepos;
1314         pos = aip->linebuf + linepos;
1315         len = 0;
1316 
1317         while (*pos == '\n' || *pos == '\r')    /* skip empty lines */
1318         {
1319                 pos = AsnIoGets(aip);   /* get a line */
1320 
1321                 if (pos == NULL)
1322                         return EOF_TOKEN;
1323         }
1324 
1325         while (! started)
1326         {
1327                 while ((* pos <= ' ') || ((*pos == '-') && (*(pos+1) == '-')))     /* skip leading white space */
1328                 {
1329                         if (*pos == '\n' || *pos == '\r')
1330                         {
1331                                 pos = AsnIoGets(aip);
1332 
1333                                 if (pos == NULL)
1334                                         return EOF_TOKEN;
1335                         }
1336                         else if ((*pos == '-') && (*(pos+1) == '-'))   /* skip comments */
1337                         {
1338                                 pos += 2;
1339                                 done = 0;
1340                                 while (! done)
1341                                 {
1342                                         if ((*pos == '-') && (*(pos +1) == '-'))
1343                                         {
1344                                                 pos += 2;
1345                                                 done = 1;
1346                                         }
1347                                         else if (*pos == '\n' || *pos == '\r')
1348                                                 done = 1;
1349                                         else
1350                                                 pos++;
1351                                 }
1352                         }
1353                         else
1354                                 pos++;
1355                         
1356                 }
1357 
1358                 aip->word = pos;
1359                 len = 0;
1360                 if (* pos == ':')
1361                 {
1362                         if ((*(pos + 1) == ':') && (*(pos + 2) == '='))
1363                         {
1364                                 token = ISDEF;
1365                                 pos += 2;
1366                                 len = 3;
1367                                 if (matched_ref)
1368                                         started = TRUE;
1369                                 else
1370                                 {
1371                                         AsnIoErrorMsg(aip, 59, *pos, aip->linenumber);
1372                                         return ERROR_TOKEN;
1373                                 }
1374                         }
1375                         else
1376                                 matched_ref = FALSE;
1377                 }
1378                 else if (IS_UPPER(*pos))  /* a reference or keyword */
1379                 {
1380                         token = REF;
1381                         while ((IS_ALPHANUM(*pos)) || (*pos == '-'))
1382                         {
1383                                 pos++; len++;
1384                         }
1385                         pos--;    /* move back for increment at end */
1386                         aip->wordlen = len;
1387          if (StrMatch(name, aip->word, (Int2)len))
1388                                 matched_ref = TRUE;
1389                         else
1390                                 matched_ref = FALSE;
1391                 }
1392                 else
1393                         matched_ref = FALSE;
1394                 pos++;     /* move over last symbol */
1395         }
1396 
1397                           /* found it , do normal return after ::= */
1398 
1399         aip->linepos = pos - aip->linebuf;
1400         aip->wordlen = len;
1401         aip->token = token;
1402         return token;
1403 }
1404 
1405 
1406 

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.