NCBI C Toolkit Cross Reference

C/asnlib/asndebin.c


  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 

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.