|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/asnlib/asndebin.c |
source navigation diff markup identifier search freetext search file search |
1 /* asndebin.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: asndebin.c
27 *
28 * Author: James Ostell
29 *
30 * Version Creation Date: 3/4/91
31 *
32 * $Revision: 6.7 $
33 *
34 * File Description:
35 * Special binary form (BER) decoder for ASN.1
36 *
37 * Modifications:
38 * --------------------------------------------------------------------------
39 * Date Name Description of modification
40 * ------- ---------- -----------------------------------------------------
41 * 2/11/91 Ostell AsnBinReadVal - added check for unresolved base types
42 * 3/4/91 Kans Stricter typecasting for GNU C and C++
43 * 3/4/91 Kans AsnDeBinReadBoolean returns Boolean
44 * 04-20-93 Schuler LIBCALL calling convention
45 * 08-01-93 Gish AsnDeBinReadString calls MemGet instead of MemNew
46 *
47 * $Log: asndebin.c,v $
48 * Revision 6.7 2004/04/01 13:43:05 lavr
49 * Spell "occurred", "occurrence", and "occurring"
50 *
51 * Revision 6.6 2003/12/10 15:41:19 sirotkin
52 * As per toolkit RT request 15030485 and Jim Ostell, afety checks after ato2=AsnFindBaseIsa(atp) were added.
53 *
54 * Revision 6.5 2002/10/09 19:16:31 ivanov
55 * Fixed buffer overrun in the AsnDeBinReadReal()
56 *
57 * Revision 6.4 2000/12/12 15:56:10 ostell
58 * added support BigInt
59 *
60 * Revision 6.3 1999/12/23 14:18:06 beloslyu
61 * fix the AsnBinReadVal function if the atp is NULL
62 *
63 * Revision 6.2 1998/01/22 20:46:24 volodya
64 * fix endless loop
65 *
66 * Revision 6.1 1997/10/29 02:40:21 vakatov
67 * Type castings to pass through the C++ compiler
68 *
69 * Revision 6.0 1997/08/25 18:09:46 madden
70 * Revision changed to 6.0
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/12/21 22:03:20 epstein
82 * per Kevin Kendall, IBI; avoid infinite loop caused by uninformative return value in AsnDeBinDecr()
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 #include "asnbuild.h"
95
96 #define ASNDEBIN_EOF -2
97
98 /*****************************************************************************
99 *
100 * AsnTypePtr AsnBinReadId(aip, atp)
101 * reads identifier for next value
102 *
103 *****************************************************************************/
104 NLM_EXTERN AsnTypePtr LIBCALL AsnBinReadId (AsnIoPtr aip, AsnTypePtr atp)
105 {
106 Int4 used;
107
108 Int2 isa;
109 AsnTypePtr atp2, atp3, atp4;
110 Boolean found;
111 PstackPtr psp, prevpsp, currpsp;
112
113 used = 0;
114
115 if (! aip->type_indent) /* just starting or ending reading */
116 {
117 if (atp == NULL) /* starting an unknown item */
118 {
119 AsnIoErrorMsg(aip, 1);
120 return NULL;
121 }
122
123 used = AsnDeBinScanTag(aip); /* read the tag */
124
125 if (used == ASNDEBIN_EOF) /* end of file */
126 return NULL;
127 /* see RT toolbox ticket 15030485 for the below fix */
128
129 atp2 = AsnFindBaseType(atp); /* find the base type */
130 if (atp2 == NULL)
131 return atp2;
132 if (atp2->type == NULL)
133 return atp2->type;
134 isa = atp2->type->isa;
135
136
137 if (atp2->type->isa != CHOICE_TYPE)
138 {
139 atp2 = atp2->type; /* will be primitive tag */
140 if ((aip->tagclass != atp2->tagclass) ||
141 (aip->tagnumber != atp2->tagnumber))
142 found = FALSE;
143 else
144 found = TRUE;
145 }
146 else
147 {
148 atp2 = (AsnTypePtr) atp->branch; /* look for a match among choices */
149 found = FALSE;
150 while ((atp2 != NULL) && (! found))
151 {
152 if ((aip->tagclass == atp2->tagclass) &&
153 (aip->tagnumber == atp2->tagnumber))
154 found = TRUE;
155 else
156 atp2 = atp2->next;
157 }
158 aip->tagsaved = TRUE; /* will need tag for which CHOICE next round */
159 }
160
161 if (! found)
162 {
163 AsnIoErrorMsg(aip, 2, AsnErrGetTypeName(atp->name));
164 return NULL;
165 }
166
167 psp = & aip->typestack[0];
168 psp->len = aip->length;
169 psp->type = atp;
170 psp->resolved = FALSE;
171 psp->tag_indef = FALSE;
172
173 return atp;
174 }
175
176 prevpsp = & aip->typestack[aip->type_indent - 1]; /* previous level */
177 currpsp = prevpsp + 1; /* current level */
178
179 /** end of definate length struct ****/
180 if (prevpsp->len == 0)
181 {
182 prevpsp->resolved = TRUE;
183 return prevpsp->type;
184 }
185
186 if (currpsp->type != NULL) /* reading a struct */
187 {
188 if (! aip->tagsaved) /* already read it? */
189 {
190 used = AsnDeBinScanTag(aip); /* read the tag */
191 if (! AsnDeBinDecr(used, aip)) /* decrement length counter */
192 return NULL;
193 }
194
195 if ((aip->length == 0) && (aip->tagclass == 0) &&
196 (aip->tagnumber == 0)) /* length 0, could be end of contents */
197 {
198 if (prevpsp->len == INDEFINATE)
199 {
200 prevpsp->resolved = TRUE;
201 aip->tagsaved = FALSE;
202 if (prevpsp->tag_indef) /* indefinate user tag? */
203 {
204 used = AsnDeBinScanTag(aip); /* should be 00 for tag */
205 if (! AsnDeBinDecr(used, aip))
206 return NULL;
207 if ((aip->length == 0) && (aip->tagclass == 0) &&
208 (aip->tagnumber == 0))
209 prevpsp->tag_indef = FALSE;
210 else
211 {
212 AsnIoErrorMsg(aip, 3, AsnErrGetTypeName(prevpsp->type->name));
213 return NULL;
214 }
215 }
216 return prevpsp->type;
217 }
218 }
219 else
220 aip->tagsaved = TRUE;
221 }
222
223
224 if (aip->type_indent) /* check for SEQOF and SETOF */
225 {
226 atp = prevpsp->type;
227 atp2 = AsnFindBaseType(atp);
228 isa = atp2->type->isa;
229 if ((isa == SEQOF_TYPE) || (isa == SETOF_TYPE))
230 {
231 atp = (AsnTypePtr) atp2->branch; /* set of what type? */
232 currpsp->type = atp;
233 currpsp->len = INDEFINATE;
234 currpsp->resolved = FALSE;
235 currpsp->tag_indef = FALSE;
236 atp2 = AsnFindBaseType(atp);
237 isa = atp2->type->isa;
238 atp2 = atp2->type; /* get universal type */
239 used = AsnDeBinScanTag(aip); /* read the tag */
240 if (! AsnDeBinDecr(used, aip))
241 return NULL;
242 if ((aip->tagclass != atp2->tagclass) ||
243 (aip->tagnumber != atp2->tagnumber))
244 {
245 if ((aip->length == 0) && (aip->tagclass == 0) &&
246 (aip->tagnumber == 0)) /* length 0, could be end of contents */
247 { /* this handles an empty SEQ OF/SET OF ***/
248 if (prevpsp->len == INDEFINATE)
249 {
250 prevpsp->resolved = TRUE;
251 aip->tagsaved = FALSE;
252 if (prevpsp->tag_indef) /* indefinate user tag? */
253 {
254 used = AsnDeBinScanTag(aip); /* should be 00 for tag */
255 if (! AsnDeBinDecr(used, aip))
256 return NULL;
257 if ((aip->length == 0) && (aip->tagclass == 0) &&
258 (aip->tagnumber == 0))
259 prevpsp->tag_indef = FALSE;
260 else
261 {
262 AsnIoErrorMsg(aip, 3, AsnErrGetTypeName(prevpsp->type->name));
263 return NULL;
264 }
265 }
266 return prevpsp->type;
267 }
268 }
269 else if (isa == CHOICE_TYPE) /* no tag */
270 {
271 aip->tagsaved = TRUE;
272 }
273 else
274 {
275 AsnIoErrorMsg(aip, 4, AsnErrGetTypeName(atp->name));
276 return NULL;
277 }
278 }
279 currpsp->len = aip->length;
280 return atp; /* no type identifier */
281 }
282 }
283
284 used = AsnDeBinScanTag(aip); /* read the tag */
285 if (! AsnDeBinDecr(used, aip)) /* decrement length counter */
286 return NULL;
287
288 if ((aip->length == 0) && (aip->tagclass == 0) &&
289 (aip->tagnumber == 0)) /* length 0, could be end of contents */
290 {
291 if (prevpsp->len == INDEFINATE)
292 {
293 prevpsp->resolved = TRUE;
294 aip->tagsaved = FALSE;
295 if (prevpsp->tag_indef) /* indefinate user tag? */
296 {
297 used = AsnDeBinScanTag(aip); /* should be 00 for tag */
298 if (! AsnDeBinDecr(used, aip))
299 return NULL;
300 if ((aip->length == 0) && (aip->tagclass == 0) &&
301 (aip->tagnumber == 0))
302 prevpsp->tag_indef = FALSE;
303 else
304 {
305 AsnIoErrorMsg(aip, 3, AsnErrGetTypeName(prevpsp->type->name));
306 return NULL;
307 }
308 }
309 return prevpsp->type;
310 }
311 }
312
313 atp2 = AsnFindBaseType(prevpsp->type);
314 atp = AsnDeBinFindElement(aip, (AsnTypePtr) atp2->branch);
315 if (atp == NULL)
316 {
317 AsnIoErrorMsg(aip, 5, AsnErrGetTypeName(prevpsp->type->name));
318 return NULL;
319 }
320
321 if (atp2->type->isa == SEQ_TYPE) /* check sequence order */
322 {
323 atp3 = currpsp->type;
324 if (atp3 != NULL)
325 {
326 atp4 = (AsnTypePtr) atp2->branch;
327 atp3 = atp3->next;
328 while (atp4 != atp3)
329 {
330 if (atp == atp4)
331 {
332 AsnIoErrorMsg(aip, 6, AsnErrGetTypeName(atp->name), AsnErrGetTypeName(atp2->name));
333 return NULL;
334 }
335 atp4 = atp4->next;
336 }
337 }
338 else
339 atp3 = (AsnTypePtr) atp2->branch;
340
341 while ((atp3 != NULL) && (atp3 != atp))
342 {
343 if (! (atp3->optional || atp3->hasdefault))
344 {
345 AsnIoErrorMsg(aip, 7, AsnErrGetTypeName(atp3->name), AsnErrGetTypeName(atp2->name));
346 return NULL;
347 }
348 atp3 = atp3->next;
349 }
350 }
351
352 currpsp->type = atp;
353 currpsp->len = aip->length;
354 currpsp->resolved = FALSE; /* mark first use */
355 if ((atp->tagclass != TAG_UNIVERSAL) && (atp->tagclass != TAG_NONE)
356 && (aip->length == INDEFINATE))
357 currpsp->tag_indef = TRUE;
358 return atp;
359 }
360
361 /*****************************************************************************
362 *
363 * Boolean AsnDeBinDecr(used, aip)
364 * decrement all levels above level with used bytes
365 *
366 *****************************************************************************/
367 NLM_EXTERN Boolean AsnDeBinDecr (Int4 used, AsnIoPtr aip)
368 {
369 PstackPtr psp, psp0;
370
371 if (used == ASNDEBIN_EOF) return FALSE; /* avoid infinite loop in higher levels */
372
373 if (used <= 0) /* tag saved or INDEFINATE */
374 return TRUE;
375
376 psp = (psp0 = aip->typestack) + aip->type_indent;
377 while (psp > psp0) {
378 --psp;
379 if (psp->len == INDEFINATE) /* if one INDEFINATE, assume all are */
380 return TRUE;
381 if ((psp->len -= used) < 0) {
382 AsnIoErrorMsg(aip, 8, (int)(psp - psp0) /* level */);
383 return FALSE;
384 }
385 }
386 return TRUE;
387 }
388
389 /**** old version ***********************
390 NLM_EXTERN Boolean AsnDeBinDecr (Int4 used, AsnIoPtr aip)
391 {
392 Int2 level;
393
394 if (used == INDEFINATE)
395 return TRUE;
396
397 level = aip->type_indent;
398 while (level)
399 {
400 level--;
401 if (aip->typestack[level].len != INDEFINATE)
402 {
403 aip->typestack[level].len -= used;
404 if (aip->typestack[level].len < 0)
405 {
406 AsnIoErrorMsg(aip, 8, level);
407 return FALSE;
408 }
409 }
410 }
411 return TRUE;
412 }
413 *****************************************/
414 /*****************************************************************************
415 *
416 * Int4 AsnDeBinScanTag(aip)
417 * scan the next tag-length element
418 * return bytes used from input
419 *
420 *****************************************************************************/
421 NLM_EXTERN Int4 AsnDeBinScanTag (AsnIoPtr aip)
422 {
423 Int4 used;
424 Uint4 number;
425 Int2 bytes, lenbytes;
426 BytePtr bp;
427 Byte octet, bit8_7, bit5_1;
428 Boolean bit6;
429
430 used = 0; /* no bytes read yet */
431 if (aip->tagsaved) /* return currently saved tag */
432 {
433 aip->tagsaved = FALSE;
434 return used; /* no additional bytes read */
435 }
436
437 bytes = aip->bytes - aip->offset; /* current location in buffer */
438 if (! bytes)
439 {
440 bytes = AsnIoReadBlock(aip);
441 if (bytes == 0)
442 return ASNDEBIN_EOF;
443 }
444 bp = aip->buf + aip->offset;
445
446 /*** read first octet of tag-id ******/
447 octet = *bp;
448 bp++; bytes--; used++;
449
450 bit5_1 = octet & (Byte)0x1f; /* short form tag number */
451 bit6 = (Byte)((octet >> 5) & 0x01); /* constructed? */
452 bit8_7 = (Byte)((octet >> 6) & 0x03); /* tag class */
453
454 switch (bit8_7) /* get tag class */
455 {
456 case 0x0:
457 aip->tagclass = TAG_UNIVERSAL;
458 break;
459 case 0x1:
460 aip->tagclass = TAG_APPLICATION;
461 break;
462 case 0x2:
463 aip->tagclass = TAG_CONTEXT;
464 break;
465 case 0x3:
466 aip->tagclass = TAG_PRIVATE;
467 break;
468 }
469
470 aip->constructed = bit6; /* constructed? */
471
472 /*** get the tag-id ****/
473 if (bit5_1 != 0x1f) /* short form */
474 {
475 aip->tagnumber = bit5_1; /* that's it */
476 }
477 else /* long form */
478 {
479 number = 0; /* have to build it up */
480 do
481 {
482 if (! bytes)
483 {
484 bytes = AsnIoReadBlock(aip);
485 if (! bytes)
486 {AsnIoErrorMsg(aip, 17); return 0;}
487 bp = aip->buf;
488 }
489 octet = *bp;
490 bp++; bytes--; used++;
491 number = (number << 7) + (octet & 0x7f);
492 }
493 while ((octet & 0x80) != 0);
494 aip->tagnumber = (Int2) number;
495 }
496
497 /*** scan the length, if present */
498 if (! bytes)
499 {
500 bytes = AsnIoReadBlock(aip);
501 if (! bytes)
502 {AsnIoErrorMsg(aip, 17); return 0;}
503 bp = aip->buf;
504 }
505
506 octet = *bp;
507 bp++; bytes--; used++;
508
509 if (! (octet & 0x80)) /* short form used */
510 aip->length = octet & 0x7f;
511 else if ((octet & 0x7f) == 0x00) /* indefinate form used */
512 aip->length = INDEFINATE;
513 else /* long form used */
514 {
515 number = 0;
516 for (lenbytes = (Int2)(octet & 0x7f); lenbytes > 0; lenbytes--)
517 {
518 if (! bytes)
519 {
520 bytes = AsnIoReadBlock(aip);
521 if (! bytes)
522 {AsnIoErrorMsg(aip, 17); return 0;}
523 bp = aip->buf;
524 }
525 octet = *bp;
526 bp++; bytes--; used++;
527 number = (number << 8) + octet;
528 }
529 aip->length = number;
530 }
531
532 aip->offset = aip->bytes - bytes;
533 aip->used = used;
534 return used;
535 }
536
537 /*****************************************************************************
538 *
539 * Int2 AsnBinReadVal(aip, atp, valueptr)
540 * read the value pointed at by atp
541 * this should be the same as aip->typestack[aip->type_indent].type
542 * returns START_STRUCT
543 * END_STRUCT
544 * 1 if ok
545 * 0 if an error occurred
546 * if (valueptr == NULL)
547 * just checks that value is of proper type
548 *
549 *****************************************************************************/
550 NLM_EXTERN Int2 LIBCALL AsnBinReadVal (AsnIoPtr aip, AsnTypePtr atp, DataValPtr valueptr)
551 {
552 Int4 used;
553 Int2 isa, retval;
554 Boolean terminalvalue; /* set if read a terminal value */
555 AsnTypePtr atp2;
556 Boolean read_value;
557 DataVal fake_value;
558 AsnTypePtr base_type, curr_type;
559 int next_type;
560 PstackPtr currpsp, prevpsp;
561
562 currpsp = & aip->typestack[aip->type_indent];
563 curr_type = currpsp->type;
564 if (aip->type_indent)
565 prevpsp = currpsp - 1;
566 else
567 prevpsp = NULL;
568
569 if (atp == NULL)
570 return 0;
571
572 base_type = AsnFindBaseType(atp);
573 if (base_type == NULL) /* not found */
574 {
575 base_type = atp;
576 while (base_type->type != NULL)
577 base_type = base_type->type;
578 if (base_type->imported)
579 {
580 AsnIoErrorMsg(aip,9, AsnErrGetTypeName(atp->name), AsnErrGetTypeName(base_type->name));
581 return 0;
582 }
583 else
584 {
585 AsnIoErrorMsg(aip,10, AsnErrGetTypeName(atp->name), AsnErrGetTypeName(base_type->name));
586 return 0;
587 }
588 }
589 isa = base_type->type->isa;
590
591 if (valueptr == NULL) /* just check the value */
592 {
593 read_value = FALSE;
594 valueptr = &fake_value;
595 }
596 else
597 read_value = TRUE;
598
599 retval = 1; /* normal return */
600 terminalvalue = TRUE; /* most values are terminal values */
601
602 if (ISA_STRINGTYPE(isa))
603 isa = GENERALSTRING_TYPE;
604
605 switch (isa)
606 {
607 case SEQ_TYPE:
608 case SET_TYPE:
609 case SETOF_TYPE:
610 case SEQOF_TYPE:
611 terminalvalue = FALSE; /* handled by AsnTypeSetIndent() */
612 if ((prevpsp == NULL) || (! prevpsp->resolved)) /* open brace */
613 {
614 AsnTypeSetIndent(TRUE, aip, atp);
615 while (aip->tagclass != TAG_UNIVERSAL) /* read to struct */
616 {
617 used = AsnDeBinScanTag(aip);
618 if (! AsnDeBinDecr(used, aip))
619 return 0;
620 }
621 retval = START_STRUCT;
622 valueptr->intvalue = START_STRUCT;
623 terminalvalue = FALSE;
624 }
625 else
626 { /* close brace already read in AsnBinReadId */
627 switch (isa)
628 {
629 case SEQOF_TYPE:
630 case SETOF_TYPE:
631 break;
632 case SEQ_TYPE: /* check that no more waiting */
633 if (curr_type != NULL) /* check next one */
634 atp2 = curr_type->next;
635 else /* empty sequence written */
636 atp2 = (AsnTypePtr) base_type->branch;
637 while (atp2 != NULL)
638 {
639 if (! (atp2->optional || atp2->hasdefault))
640 {
641 AsnIoErrorMsg(aip, 7, AsnErrGetTypeName(atp2->name), AsnErrGetTypeName(atp->name));
642 return 0;
643 }
644 atp2 = atp2->next;
645 }
646 break;
647 default:
648 break;
649 }
650 next_type = aip->type_indent - 2; /* end any choices */
651 while ((next_type >= 0) &&
652 (AsnFindBaseIsa(aip->typestack[next_type].type) == CHOICE_TYPE))
653 {
654 currpsp = & aip->typestack[next_type];
655 atp2 = currpsp->type;
656 if ((atp2->tagclass != TAG_NONE) &&
657 (currpsp->tag_indef))
658 {
659 used = AsnDeBinScanTag(aip); /* should be 00 for tag */
660 if (! AsnDeBinDecr(used, aip))
661 return 0;
662 if ((aip->length == 0) && (aip->tagclass == 0) &&
663 (aip->tagnumber == 0))
664 currpsp->tag_indef = FALSE;
665 else
666 {
667 AsnIoErrorMsg(aip, 3, AsnErrGetTypeName(atp2->name));
668 return 0;
669 }
670 }
671 next_type--;
672 }
673 AsnTypeSetIndent(FALSE, aip, curr_type);
674 retval = END_STRUCT;
675 valueptr->intvalue = END_STRUCT;
676 }
677 break;
678 case CHOICE_TYPE:
679 AsnTypeSetIndent(TRUE, aip, atp); /* nest down to type */
680 terminalvalue = FALSE;
681 break;
682 default: /* set up for primitive type */
683 base_type = AsnFindBaseType(atp);
684 base_type = base_type->type; /* point at the type itself */
685
686 while ((aip->tagclass != base_type->tagclass) ||
687 (aip->tagnumber != base_type->tagnumber))/* read to element */
688 {
689 used = AsnDeBinScanTag(aip);
690 if (! AsnDeBinDecr(used, aip))
691 return 0;
692 }
693
694 if ((aip->bytes - aip->offset) == 0)
695 {
696 if (! AsnIoReadBlock(aip))
697 {AsnIoErrorMsg(aip, 17); return 0;}
698 }
699 switch (isa)
700 {
701 case BOOLEAN_TYPE:
702 valueptr->boolvalue = AsnDeBinReadBoolean(aip, atp);
703 break;
704 case INTEGER_TYPE:
705 case ENUM_TYPE:
706 valueptr->intvalue = AsnDeBinReadInteger(aip, atp);
707 break;
708 case BIGINT_TYPE:
709 valueptr->bigintvalue = AsnDeBinReadBigInt(aip, atp);
710 break;
711 case REAL_TYPE:
712 valueptr->realvalue = AsnDeBinReadReal(aip);
713 break;
714 case GENERALSTRING_TYPE:
715 if (read_value)
716 {
717 valueptr->ptrvalue = AsnDeBinReadString(aip, atp);
718 if (valueptr->ptrvalue == NULL)
719 return 0;
720 }
721 else
722 AsnDeBinSkipString(aip);
723 break;
724 case NULL_TYPE:
725 AsnDeBinReadNull(aip, atp);
726 break;
727 case OCTETS_TYPE:
728 case STRSTORE_TYPE:
729 if (read_value)
730 {
731 valueptr->ptrvalue = AsnDeBinReadOctets(aip);
732 if (valueptr->ptrvalue == NULL) return 0;
733 }
734 else
735 AsnDeBinSkipOctets(aip);
736 break;
737 default:
738 AsnIoErrorMsg(aip, 11, AsnErrGetTypeName(atp->name));
739 return 0;
740 }
741 if (currpsp->tag_indef) /* indefinate user tag */
742 {
743 used = AsnDeBinScanTag(aip); /* should be 00 for tag */
744 if (! AsnDeBinDecr(used, aip))
745 return 0;
746 if ((aip->length == 0) && (aip->tagclass == 0) &&
747 (aip->tagnumber == 0))
748 currpsp->tag_indef = FALSE;
749 else
750 {
751 AsnIoErrorMsg(aip, 3, AsnErrGetTypeName(atp->name));
752 return 0;
753 }
754 }
755 }
756
757 if (terminalvalue) /* pop out of any CHOICE nests */
758 {
759 next_type = aip->type_indent - 1; /* end any choices */
760 if ((next_type >= 0) &&
761 (AsnFindBaseIsa(aip->typestack[next_type].type) == CHOICE_TYPE))
762 {
763 while ((next_type >= 0) &&
764 (AsnFindBaseIsa(aip->typestack[next_type].type) == CHOICE_TYPE))
765 {
766 currpsp = & aip->typestack[next_type];
767 atp2 = currpsp->type;
768 if ((curr_type->tagclass != TAG_NONE) &&
769 (currpsp->tag_indef))
770 {
771 used = AsnDeBinScanTag(aip); /* should be 00 for tag */
772 if (! AsnDeBinDecr(used, aip))
773 return 0;
774 if ((aip->length == 0) && (aip->tagclass == 0) &&
775 (aip->tagnumber == 0))
776 currpsp->tag_indef = FALSE;
777 else
778 {
779 AsnIoErrorMsg(aip, 3, AsnErrGetTypeName(atp2->name));
780 return 0;
781 }
782 }
783 next_type--;
784 }
785 AsnTypeSetIndent(FALSE, aip, curr_type);
786 }
787 }
788
789 return retval;
790 }
791
792 /*****************************************************************************
793 *
794 * AsnTypePtr AsnDeBinFindType(aip, amp)
795 * returns pointer to type definition in amp
796 * or NULL if not found
797 *
798 *****************************************************************************/
799 NLM_EXTERN AsnTypePtr AsnDeBinFindType (AsnIoPtr aip, AsnModulePtr amp)
800 {
801 AsnTypePtr atp;
802
803 while (amp != NULL)
804 {
805 atp = AsnDeBinFindElement(aip, amp->types);
806 if (atp != NULL)
807 return atp;
808
809 amp = amp->next;
810 }
811 return NULL;
812 }
813
814 /*****************************************************************************
815 *
816 * AsnTypePtr AsnDeBinFindElement(aip, atp)
817 * finds an element in a list of elements
818 * (elements of SEQ, SET, CHOICE)
819 *
820 *****************************************************************************/
821 NLM_EXTERN AsnTypePtr AsnDeBinFindElement (AsnIoPtr aip, AsnTypePtr atp)
822 {
823 while (atp != NULL)
824 {
825 if ((aip->tagclass == atp->tagclass) &&
826 (aip->tagnumber == atp->tagnumber))
827 return atp;
828 else
829 atp = atp->next;
830 }
831 return NULL;
832 }
833
834
835 /*****************************************************************************
836 *
837 * Int4 AsnDeBinReadInteger(aip, atp)
838 * expects an INTEGER or ENUMERATED next
839 * assumes none of it has already been read
840 * does not advance to next token
841 * atp points to the definition of this integer for named values
842 *
843 *****************************************************************************/
844 NLM_EXTERN Int4 AsnDeBinReadInteger (AsnIoPtr aip, AsnTypePtr atp)
845 {
846 Int2 bytes, len;
847 Uint4 number;
848 BytePtr bp;
849 AsnValxNodePtr avnp;
850 Int4 value;
851 AsnTypePtr atp2;
852
853 bytes = aip->bytes - aip->offset;
854 bp = aip->buf + aip->offset;
855 len = (Int2) aip->length;
856 aip->tagsaved = FALSE;
857
858 if ((*bp & 0x80) != 0) /* negative number */
859 number = (Uint4)(-1);
860 else
861 number = 0;
862
863 while (len)
864 {
865 number = (number << 8) | (*bp & 0xff);
866 bp++; bytes--; len--;
867 if (! bytes)
868 {
869 bytes = AsnIoReadBlock(aip);
870 if (! bytes)
871 {AsnIoErrorMsg(aip, 17); return 0;}
872 bp = aip->buf;
873 }
874 }
875
876 value = (Int4) number;
877
878 if (! AsnDeBinDecr(aip->length, aip))
879 return 0;
880 aip->offset = aip->bytes - bytes;
881
882 if (AsnFindBaseIsa(atp) != ENUM_TYPE)
883 return value;
884
885 /******************** read a named integer value *********/
886
887 atp2 = AsnFindBaseType(atp);
888 if (atp2->branch != NULL) /* named values */
889 {
890 avnp = (AsnValxNodePtr) atp2->branch;
891 while (avnp != NULL)
892 {
893 if (avnp->intvalue == value)
894 return value;
895 avnp = avnp->next;
896 }
897 }
898
899 AsnIoErrorMsg(aip, 12, value, AsnErrGetTypeName(atp->name));
900
901 return 0;
902 }
903
904 /*****************************************************************************
905 *
906 * Int8 AsnDeBinReadBigInt(aip, atp)
907 * expects an INTEGER next
908 * assumes none of it has already been read
909 * does not advance to next token
910 * atp points to the definition of this integer for named values
911 *
912 *****************************************************************************/
913 NLM_EXTERN Int8 AsnDeBinReadBigInt (AsnIoPtr aip, AsnTypePtr atp)
914 {
915 Int2 bytes, len;
916 Uint8 number;
917 BytePtr bp;
918 Int8 value;
919
920 bytes = aip->bytes - aip->offset;
921 bp = aip->buf + aip->offset;
922 len = (Int2) aip->length;
923 aip->tagsaved = FALSE;
924
925 if ((*bp & 0x80) != 0) /* negative number */
926 number = (Uint8)(-1);
927 else
928 number = 0;
929
930 while (len)
931 {
932 number = (number << 8) | (*bp & 0xff);
933 bp++; bytes--; len--;
934 if (! bytes)
935 {
936 bytes = AsnIoReadBlock(aip);
937 if (! bytes)
938 {AsnIoErrorMsg(aip, 17); return 0;}
939 bp = aip->buf;
940 }
941 }
942
943 value = (Int8) number;
944
945 if (! AsnDeBinDecr(aip->length, aip))
946 return 0;
947 aip->offset = aip->bytes - bytes;
948
949 if (AsnFindBaseIsa(atp) != ENUM_TYPE)
950 return value;
951
952 /******************** read a named integer value *********/
953
954 /* named value not supported for BigInt ****/
955
956
957 AsnIoErrorMsg(aip, 12, value, AsnErrGetTypeName(atp->name));
958
959 return (Int8)0;
960 }
961
962 /*****************************************************************************
963 *
964 * Boolean AsnDeBinReadBoolean(aip, atp)
965 * expects a BOOLEAN next
966 * assumes none of it has already been read
967 * does not advance to next token
968 * atp points to the definition of this BOOLEN
969 *
970 *****************************************************************************/
971 NLM_EXTERN Boolean AsnDeBinReadBoolean (AsnIoPtr aip, AsnTypePtr atp)
972 {
973 BytePtr bp;
974 Byte octet;
975 Boolean result = TRUE;
976
977 aip->tagsaved = FALSE;
978 if (aip->length != 1)
979 {
980 AsnIoErrorMsg(aip, 13, AsnErrGetTypeName(atp->name));
981 return FALSE;
982 }
983
984 bp = aip->buf + aip->offset;
985 octet = *bp;
986
987 if (octet == 0)
988 result = FALSE;
989 else
990 result = TRUE;
991
992 aip->offset++;
993 AsnDeBinDecr((Int4)1, aip);
994
995 return result;
996 }
997
998 /*****************************************************************************
999 *
1000 * Int4 AsnDeBinReadString(aip, atp)
1001 * expects any String type next
1002 * assumes none of it has already been read
1003 * does not advance to next token
1004 * atp points to the definition of this String
1005 * packs String to single value, if segmented on input
1006 *
1007 *****************************************************************************/
1008 NLM_EXTERN CharPtr AsnDeBinReadString (AsnIoPtr aip, AsnTypePtr atp)
1009 {
1010 Int4 len;
1011 register int bytes, amount;
1012 register BytePtr bp;
1013 register CharPtr tmp;
1014 CharPtr result;
1015
1016 aip->tagsaved = FALSE;
1017 len = aip->length;
1018 AsnDeBinDecr(len, aip);
1019 result = (CharPtr) MemGet((size_t)(len + 1), FALSE);
1020 if (result == NULL)
1021 {
1022 AsnIoErrorMsg(aip, 14, len, AsnErrGetTypeName(atp->name));
1023 return NULL;
1024 }
1025 result[len] = '\0';
1026
1027 bp = aip->buf + aip->offset;
1028 bytes = (int)(aip->bytes - aip->offset);
1029 tmp = result;
1030
1031 while (len)
1032 {
1033 if ((Int4)bytes >= len)
1034 amount = (int) len;
1035 else
1036 amount = bytes;
1037 bytes -= amount;
1038 len -= (Int4)amount;
1039 while (amount)
1040 {
1041 if ((aip->fix_non_print != 2) && ((* bp < ' ') || (*bp > '~')))
1042 {
1043 *tmp = '\0';
1044 if ((aip->fix_non_print == 0) || (aip->fix_non_print == 3))
1045 {
1046 AsnIoErrorMsg(aip, 106, (int)(*bp), result);
1047 }
1048 *bp = '#'; /* repair string with # */
1049 }
1050 *tmp = *bp;
1051 tmp++; bp++; amount--;
1052 }
1053 if (! bytes)
1054 {
1055 bytes = (int) AsnIoReadBlock(aip);
1056 if (! bytes)
1057 {AsnIoErrorMsg(aip, 17); return NULL;}
1058 bp = aip->buf;
1059 }
1060 }
1061 aip->offset = aip->bytes - (Int2) bytes;
1062 return result;
1063 }
1064
1065 /*****************************************************************************
1066 *
1067 * void AsnDeBinSkipString(aip)
1068 * expects any String type next
1069 * assumes none of it has already been read
1070 * does not advance to next token
1071 * just reads past end of string
1072 *
1073 *****************************************************************************/
1074 NLM_EXTERN void AsnDeBinSkipString (AsnIoPtr aip)
1075 {
1076 Int4 len;
1077 register int bytes, amount;
1078 register BytePtr bp, tmp;
1079 int bad;
1080
1081 aip->tagsaved = FALSE;
1082 len = aip->length;
1083 AsnDeBinDecr(len, aip);
1084
1085 bp = aip->buf + aip->offset;
1086 tmp = bp;
1087 bytes = (int)(aip->bytes - aip->offset);
1088
1089 while (len)
1090 {
1091 if ((Int4)bytes >= len)
1092 amount = (int) len;
1093 else
1094 amount = bytes;
1095 bytes -= amount;
1096 len -= (Int4)amount;
1097 while (amount)
1098 {
1099 if ((* bp < ' ') || (*bp > '~'))
1100 {
1101 bad = (int)(*bp);
1102 *bp = '\0';
1103 AsnIoErrorMsg(aip, 106, bad, (CharPtr)tmp);
1104 aip->io_failure = TRUE;
1105 }
1106 bp++; amount--;
1107 }
1108 if (! bytes)
1109 {
1110 bytes = (int) AsnIoReadBlock(aip);
1111 if (! bytes)
1112 {AsnIoErrorMsg(aip, 17); return;}
1113 bp = aip->buf;
1114 tmp = bp;
1115 }
1116 }
1117 aip->offset = aip->bytes - (Int2) bytes;
1118 return;
1119 }
1120
1121 /*****************************************************************************
1122 *
1123 * AsnDeBinReadOctets(aip)
1124 * expects any OCTETS type next
1125 * assumes none of it has already been read
1126 * does not advance to next token
1127 *
1128 *****************************************************************************/
1129 NLM_EXTERN ByteStorePtr AsnDeBinReadOctets (AsnIoPtr aip)
1130 {
1131 Int4 len;
1132 Int2 bytes, amount;
1133 BytePtr bp;
1134 ByteStorePtr bsp;
1135
1136 aip->tagsaved = FALSE;
1137 len = aip->length;
1138 AsnDeBinDecr(len, aip);
1139 bsp = BSNew((Uint4)len);
1140 if (bsp == NULL) return bsp;
1141
1142 bp = aip->buf + aip->offset;
1143 bytes = aip->bytes - aip->offset;
1144
1145 while (len)
1146 {
1147 if ((Int4)bytes >= len)
1148 amount = (Int2) len;
1149 else
1150 amount = bytes;
1151 BSWrite(bsp, bp, amount);
1152 len -= amount;
1153 bytes -= amount;
1154 if (! bytes)
1155 {
1156 bytes = AsnIoReadBlock(aip);
1157 if (! bytes)
1158 {AsnIoErrorMsg(aip, 17); return NULL;}
1159 bp = aip->buf;
1160 }
1161 }
1162 aip->offset = aip->bytes - bytes;
1163 return bsp;
1164 }
1165
1166 /*****************************************************************************
1167 *
1168 * AsnDeBinSkipOctets(aip)
1169 * expects any OCTETS type next
1170 * assumes none of it has already been read
1171 * does not advance to next token
1172 *
1173 *****************************************************************************/
1174 NLM_EXTERN void AsnDeBinSkipOctets (AsnIoPtr aip)
1175 {
1176 Int4 len;
1177 Int2 bytes, amount;
1178
1179 aip->tagsaved = FALSE;
1180 len = aip->length;
1181 AsnDeBinDecr(len, aip);
1182
1183 bytes = aip->bytes - aip->offset;
1184
1185 while (len)
1186 {
1187 if ((Int4)bytes >= len)
1188 amount = (Int2) len;
1189 else
1190 amount = bytes;
1191 len -= amount;
1192 bytes -= amount;
1193 if (! bytes)
1194 {
1195 bytes = AsnIoReadBlock(aip);
1196 if (! bytes)
1197 {AsnIoErrorMsg(aip, 17); return ;}
1198 }
1199 }
1200 aip->offset = aip->bytes - bytes;
1201 return;
1202 }
1203
1204 /*****************************************************************************
1205 *
1206 * FloatHi AsnDeBinReadReal(aip)
1207 * expects a REAL next
1208 * assumes none of it has already been read
1209 * does not advance to next token
1210 *
1211 *****************************************************************************/
1212 NLM_EXTERN FloatHi AsnDeBinReadReal (AsnIoPtr aip)
1213 {
1214 double result = 0.0;
1215 Int4 len;
1216 Int2 bytes, amount;
1217 BytePtr bp;
1218 char buf[200], *tmp;
1219
1220 aip->tagsaved = FALSE;
1221 len = aip->length;
1222 AsnDeBinDecr(len, aip);
1223
1224 bp = aip->buf + aip->offset;
1225 bytes = aip->bytes - aip->offset;
1226 tmp = buf;
1227
1228 while (len)
1229 {
1230 if ((Int4)bytes >= len)
1231 amount = (Int2) len;
1232 else
1233 amount = bytes;
1234 MemCopy(tmp, bp, (size_t)amount);
1235 tmp += amount;
1236 len -= amount;
1237 bytes -= amount;
1238 if (! bytes)
1239 {
1240 bytes = AsnIoReadBlock(aip);
1241 if (! bytes)
1242 {AsnIoErrorMsg(aip, 17); return (FloatHi)result;}
1243 bp = aip->buf;
1244 }
1245 }
1246 aip->offset = aip->bytes - bytes;
1247
1248 if (buf[0] != '\0') /* not decimal encoding */
1249 {
1250 AsnIoErrorMsg(aip, 15);
1251 return (FloatHi)result;
1252 }
1253
1254 *tmp = '\0';
1255 /* range check base 10 exponents assuming doubles */
1256
1257 if ((tmp = StringStr((buf+1), "e")) != NULL)
1258 {
1259 int n = atoi(tmp + 1);
1260 if (n < DBL_MIN_10_EXP) /** too small, return 0.0 **/
1261 return (FloatHi)result;
1262 else if (n > DBL_MAX_10_EXP) /** too big, return the max */
1263 return (FloatHi)DBL_MAX;
1264 }
1265
1266 if (sscanf((buf + 1), "%lf", &result) != 1) {
1267 result = 0.0;
1268 }
1269 return (FloatHi)result;
1270 }
1271
1272 /*****************************************************************************
1273 *
1274 * void AsnDeBinReadNull(aip, atp)
1275 *
1276 *****************************************************************************/
1277 NLM_EXTERN void AsnDeBinReadNull (AsnIoPtr aip, AsnTypePtr atp)
1278 {
1279 aip->tagsaved = FALSE;
1280 if (aip->length != 0)
1281 AsnIoErrorMsg(aip, 16, AsnErrGetTypeName(atp->name));
1282
1283 return;
1284 }
1285
1286 /*****************************************************************************
1287 *
1288 * void AsnDeBinSkipStruct(aip)
1289 * skips current structure and all substructures
1290 * Does NOT read following element
1291 *
1292 *****************************************************************************/
1293 NLM_EXTERN void AsnDeBinSkipStruct (AsnIoPtr aip)
1294 {
1295 aip->tagsaved = FALSE;
1296 AsnIoErrorMsg(aip, 0);
1297 return;
1298 }
1299
1300 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |