|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/asnlib/asnlex.c |
source navigation diff markup identifier search freetext search file search |
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 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |