|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/asnlib/asnenbin.c |
source navigation diff markup identifier search freetext search file search |
1 /* asnenbin.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: asnenbin.c
27 *
28 * Author: James Ostell
29 *
30 * Version Creation Date: 3/4/91
31 *
32 * $Revision: 6.6 $
33 *
34 * File Description:
35 * Special binary (BER) encoder for ASN.1
36 *
37 * Modifications:
38 * --------------------------------------------------------------------------
39 * Date Name Description of modification
40 * ------- ---------- -----------------------------------------------------
41 * 3/4/91 Kans Stricter typecasting for GNU C and C++
42 * 04-20-93 Schuler LIBCALL calling convention
43 *
44 * $Log: asnenbin.c,v $
45 * Revision 6.6 2003/11/07 20:57:02 beloslyu
46 * fix the c++ style comments to a C ones
47 *
48 * Revision 6.5 2003/08/01 16:55:24 gouriano
49 * workaround MSVC++.NET optimization bug
50 *
51 * Revision 6.4 2000/12/12 15:56:11 ostell
52 * added support BigInt
53 *
54 * Revision 6.3 1998/06/12 19:27:49 kans
55 * fixed unix compiler warnings
56 *
57 * Revision 6.2 1998/05/02 18:54:25 kans
58 * for Mac, use %LG instead of %lg, which is not legal C, and not supported by CodeWarrior
59 *
60 * Revision 6.1 1998/05/01 23:35:18 kans
61 * use %lf on Mac, %lg elsewhere, sprintf bug reported
62 *
63 * Revision 6.0 1997/08/25 18:09:50 madden
64 * Revision changed to 6.0
65 *
66 * Revision 5.1 1996/12/03 21:43:48 vakatov
67 * Adopted for 32-bit MS-Windows DLLs
68 *
69 * Revision 5.0 1996/05/28 14:00:29 ostell
70 * Set to revision 5.0
71 *
72 * Revision 4.1 1996/02/18 16:45:36 ostell
73 * changed fix_non_print behavior and added option 3
74 *
75 * Revision 4.0 1995/07/26 13:47:38 ostell
76 * force revision to 4.0
77 *
78 * Revision 2.9 1995/05/15 18:38:28 ostell
79 * added Log line
80 *
81 *
82 * ==========================================================================
83 */
84
85 #include "asnbuild.h"
86
87 /*****************************************************************************
88 *
89 * Boolean AsnBinWrite(aip, atp, valueptr)
90 *
91 *****************************************************************************/
92 NLM_EXTERN Boolean LIBCALL AsnBinWrite (AsnIoPtr aip, AsnTypePtr atp, DataValPtr dvp)
93 {
94 Int2 isa;
95 AsnTypePtr atp2;
96 Boolean terminalvalue;
97 int next_type;
98
99 terminalvalue = TRUE; /* most are terminal values */
100
101 if (! AsnTypeValidateOut(aip, atp, dvp))
102 return FALSE;
103
104 atp2 = AsnFindBaseType(atp);
105 isa = atp2->type->isa;
106 if (ISA_STRINGTYPE(isa))
107 isa = GENERALSTRING_TYPE;
108
109 if (((isa == SEQ_TYPE) || (isa == SET_TYPE) ||
110 (isa == SEQOF_TYPE) || (isa == SETOF_TYPE))
111 && (dvp->intvalue == END_STRUCT))
112 {
113 AsnEnBinCloseStruct(aip, atp);
114 return TRUE;
115 }
116
117 AsnEnBinTags(atp, aip); /* put in the tags */
118
119 if (isa == CHOICE_TYPE) /* show nothing */
120 {
121 AsnTypeSetIndent(TRUE, aip, atp);
122 return TRUE;
123 }
124
125 switch (isa)
126 {
127 case SEQ_TYPE:
128 case SET_TYPE:
129 case SEQOF_TYPE:
130 case SETOF_TYPE:
131 if (dvp->intvalue == START_STRUCT) /* open brace */
132 AsnEnBinOpenStruct(aip, atp);
133 else
134 {
135 AsnIoErrorMsg(aip, 18 );
136 return FALSE;
137 }
138 terminalvalue = FALSE;
139 break;
140 case BOOLEAN_TYPE:
141 AsnEnBinBoolean(dvp->boolvalue, aip, atp);
142 break;
143 case INTEGER_TYPE:
144 case ENUM_TYPE:
145 AsnEnBinInteger(dvp->intvalue, aip, atp);
146 break;
147 case BIGINT_TYPE:
148 AsnEnBinBigInt(dvp->bigintvalue, aip, atp);
149 break;
150 case REAL_TYPE:
151 AsnEnBinReal(dvp->realvalue, aip, atp);
152 break;
153 case GENERALSTRING_TYPE:
154 if (! AsnEnBinString((CharPtr) dvp->ptrvalue, aip, atp))
155 return FALSE;
156 break;
157 case NULL_TYPE:
158 AsnEnBinNull(aip, atp);
159 break;
160 case OCTETS_TYPE:
161 case STRSTORE_TYPE:
162 AsnEnBinOctets((ByteStorePtr) dvp->ptrvalue, aip, atp);
163 break;
164 default:
165 AsnIoErrorMsg(aip, 19, AsnErrGetTypeName(atp->name));
166 return FALSE;
167 }
168
169 if (terminalvalue) /* pop out of choice nests */
170 {
171 if (atp->tagclass != TAG_NONE)
172 AsnEnBinEndIndef(aip); /* put indefinate encoding */
173 next_type = aip->type_indent - 1; /* end any choices */
174 while ((next_type >= 0) &&
175 (AsnFindBaseIsa(aip->typestack[next_type].type) == CHOICE_TYPE))
176 {
177 if (aip->typestack[next_type].type->tagclass != TAG_NONE)
178 AsnEnBinEndIndef(aip);
179 next_type--;
180 }
181 if (AsnFindBaseIsa(aip->typestack[aip->type_indent - 1].type) == CHOICE_TYPE)
182 AsnTypeSetIndent(FALSE, aip, atp);
183 }
184 return TRUE;
185 }
186
187 /*****************************************************************************
188 *
189 * void AsnEnBinTags(atp, aip)
190 * encode tags for atp
191 *
192 *****************************************************************************/
193 NLM_EXTERN void AsnEnBinTags (AsnTypePtr atp, AsnIoPtr aip)
194 {
195 int isa, len;
196 Int4 tagnumber;
197 Byte octets[6], bit87, bit6, bit5_1;
198
199 if (atp->tagclass == TAG_NONE) /* encode tag, if any */
200 return;
201
202 isa = AsnFindBaseIsa(atp);
203 if ((isa == SEQ_TYPE) || (isa == SEQOF_TYPE) ||
204 (isa == SET_TYPE) || (isa == SETOF_TYPE) ||
205 (atp->tagclass == TAG_CONTEXT))
206 bit6 = 32; /* constructed bit set */
207 else
208 bit6 = 0;
209
210 bit87 = atp->tagclass; /* map directly */
211
212 tagnumber = atp->tagnumber;
213
214 if (tagnumber <= 30) /* only need one octet */
215 {
216 bit5_1 = (Byte)(tagnumber) & (Byte)0x0ff;
217 octets[0] = bit87 + bit6 + bit5_1;
218 AsnEnBinBytes(octets, (Uint4)1, aip);
219 }
220 else
221 {
222 bit5_1 = 31; /* extended tag */
223
224 octets[0] = bit87 + bit6 + bit5_1;
225
226 if (tagnumber <= 0x07f)
227 {
228 octets[1] = (Byte)tagnumber;
229 len = 2;
230 }
231 else if (tagnumber <= 0x03fff)
232 {
233 octets[1] = (Byte)(128 + ((tagnumber >> 7) & 0x07f));
234 octets[2] = (Byte)(tagnumber & 0x07f);
235 len = 3;
236 }
237 else if (tagnumber <= 0x01fffff)
238 {
239 octets[1] = (Byte)(128 + ((tagnumber >> 14) & 0x07f));
240 octets[2] = (Byte)(128 + ((tagnumber >> 7) & 0x07f));
241 octets[3] = (Byte)(tagnumber & 0x07f);
242 len = 4;
243 }
244 else if (tagnumber <= 0x0fffffff)
245 {
246 octets[1] = (Byte)(128 + ((tagnumber >> 21) & 0x07f));
247 octets[2] = (Byte)(128 + ((tagnumber >> 14) & 0x07f));
248 octets[3] = (Byte)(128 + ((tagnumber >> 7) & 0x07f));
249 octets[4] = (Byte)(tagnumber & 0x07f);
250 len = 5;
251 }
252 else
253 {
254 octets[1] = (Byte)(128 + ((tagnumber >> 28) & 0x07f));
255 octets[2] = (Byte)(128 + ((tagnumber >> 21) & 0x07f));
256 octets[3] = (Byte)(128 + ((tagnumber >> 14) & 0x07f));
257 octets[4] = (Byte)(128 + ((tagnumber >> 7) & 0x07f));
258 octets[5] = (Byte)(tagnumber & 0x07f);
259 len = 6;
260 }
261
262 AsnEnBinBytes(octets, (Uint4)len, aip);
263 }
264
265 if (atp->tagclass == TAG_CONTEXT) /* indefinate length on user tags */
266 AsnEnBinStartIndef(aip);
267
268 return;
269 }
270
271 /*****************************************************************************
272 *
273 * void AsnEnBinNull(aip, atp)
274 *
275 *****************************************************************************/
276 NLM_EXTERN void AsnEnBinNull (AsnIoPtr aip, AsnTypePtr atp)
277 {
278 AsnTypePtr atp2;
279
280 atp2 = AsnFindBaseType(atp);
281 atp2 = atp2->type;
282 AsnEnBinTags(atp2, aip);
283
284 AsnEnBinLen((Uint4)0, aip);
285 return;
286 }
287
288
289 /*****************************************************************************
290 *
291 * void AsnEnBinReal(realvalue, aip)
292 *
293 *****************************************************************************/
294 NLM_EXTERN void AsnEnBinReal (FloatHi realvalue, AsnIoPtr aip, AsnTypePtr atp)
295 {
296 AsnTypePtr atp2;
297 Byte buf[32];
298 Uint4 len;
299
300 atp2 = AsnFindBaseType(atp);
301 atp2 = atp2->type;
302 AsnEnBinTags(atp2, aip);
303 buf[0] = 0; /* use decimal encoding */
304 #ifdef OS_MAC
305 /* sprintf((char *)(buf + 1), "%lf", realvalue); */
306 sprintf((char *)(buf + 1), "%LG", realvalue);
307 #else
308 sprintf((char *)(buf + 1), "%lg", realvalue);
309 #endif
310 len = StringLen((char *)(buf+1)) + 1;
311 AsnEnBinLen(len, aip);
312 AsnEnBinBytes(buf, len, aip);
313
314 return;
315 }
316
317 /*****************************************************************************
318 *
319 * void AsnEnBinInteger(theInt, aip)
320 *
321 *****************************************************************************/
322 NLM_EXTERN void AsnEnBinInteger (Int4 theInt, AsnIoPtr aip, AsnTypePtr atp)
323 {
324 AsnTypePtr atp2;
325 Byte octets[4];
326 int msb, len, i;
327 Int4 cint;
328
329 atp2 = AsnFindBaseType(atp);
330 atp2 = atp2->type;
331 AsnEnBinTags(atp2, aip);
332
333 len = 0;
334 /**** split integer into bytes *****/
335 cint = theInt;
336 for (i = 3; i >= 0; i--)
337 {
338 octets[i] = (Byte)(cint & 0x0ff);
339 cint >>= 8;
340 }
341
342 /***** find most significant byte ****/
343 msb = 0;
344 if (theInt >= 0)
345 {
346 while (msb < 3 && octets[msb] == 0 &&
347 ((octets[msb+1] & 0x080) == 0))
348 msb++;
349 }
350 else
351 {
352 while (msb < 3 && octets[msb] == 0x0ff &&
353 ((octets[msb+1] & 0x080) == 0x080))
354 msb++;
355 }
356
357 len = 4 - msb;
358
359 AsnEnBinLen((Uint4)len, aip);
360
361 /** shift left to eliminate unnecessary bytes */
362 for ( ; msb > 0; msb--)
363 {
364 for (i = 0; i < 3; i++)
365 octets[i] = octets[i+1];
366 /* dirty workaround of an optimization bug of MSVC++.NET compiler */
367 #if defined(_MSC_VER)
368 # if _MSC_VER < 1300
369 octets[3] = 0;
370 # endif
371 #else
372 octets[3] = 0;
373 #endif
374 }
375
376 AsnEnBinBytes(octets, (Uint4)len, aip);
377
378 return;
379 }
380
381 /*****************************************************************************
382 *
383 * void AsnEnBinBigInt(theInt, aip)
384 *
385 *****************************************************************************/
386 NLM_EXTERN void AsnEnBinBigInt (Int8 theInt, AsnIoPtr aip, AsnTypePtr atp)
387 {
388 AsnTypePtr atp2;
389 Byte octets[8];
390 int msb, len, i;
391 Int8 cint;
392
393 atp2 = AsnFindBaseType(atp);
394 atp2 = atp2->type;
395 AsnEnBinTags(atp2, aip);
396
397 len = 0;
398 /**** split integer into bytes *****/
399 cint = theInt;
400 for (i = 7; i >= 0; i--)
401 {
402 octets[i] = (Byte)(cint & 0x0ff);
403 cint >>= 8;
404 }
405
406 /***** find most significant byte ****/
407 msb = 0;
408 if (theInt >= 0)
409 {
410 while (msb < 7 && octets[msb] == 0 &&
411 ((octets[msb+1] & 0x080) == 0))
412 msb++;
413 }
414 else
415 {
416 while (msb < 7 && octets[msb] == 0x0ff &&
417 ((octets[msb+1] & 0x080) == 0x080))
418 msb++;
419 }
420
421 len = 8 - msb;
422
423 AsnEnBinLen((Uint4)len, aip);
424
425 /** shift left to eliminate unnecessary bytes */
426 for ( ; msb > 0; msb--)
427 {
428 for (i = 0; i < 7; i++)
429 octets[i] = octets[i+1];
430 /* dirty workaround of an optimization bug of MSVC++.NET compiler */
431 #if defined(_MSC_VER)
432 # if _MSC_VER < 1300
433 octets[7] = 0;
434 # endif
435 #else
436 octets[7] = 0;
437 #endif
438 }
439
440 AsnEnBinBytes(octets, (Uint4)len, aip);
441
442 return;
443 }
444
445 /*****************************************************************************
446 *
447 * void AsnEnBinBoolean(value, aip)
448 *
449 *****************************************************************************/
450 NLM_EXTERN void AsnEnBinBoolean (Boolean value, AsnIoPtr aip, AsnTypePtr atp)
451 {
452 AsnTypePtr atp2;
453 Byte octets[1];
454
455 atp2 = AsnFindBaseType(atp);
456 atp2 = atp2->type;
457 AsnEnBinTags(atp2, aip);
458
459 AsnEnBinLen((Uint4)1, aip);
460
461 if (value)
462 octets[0] = 1;
463 else
464 octets[0] = 0;
465 AsnEnBinBytes(octets, (Uint4)1, aip);
466 return;
467 }
468 /*****************************************************************************
469 *
470 * Boolean AsnEnBinString(str, aip)
471 *
472 *****************************************************************************/
473 NLM_EXTERN Boolean AsnEnBinString (CharPtr str, AsnIoPtr aip, AsnTypePtr atp)
474 {
475 Uint4 stringlen;
476 AsnTypePtr atp2;
477
478 atp2 = AsnFindBaseType(atp);
479 atp2 = atp2->type;
480 AsnEnBinTags(atp2, aip);
481
482 stringlen = StringLen(str);
483 AsnEnBinLen(stringlen, aip);
484 if (! AsnEnBinTheBytes(str, stringlen, aip, TRUE))
485 return FALSE;
486 return TRUE;
487 }
488
489 /*****************************************************************************
490 *
491 * AsnEnBinOctets(bsp, aip, atp)
492 *
493 *****************************************************************************/
494 NLM_EXTERN void AsnEnBinOctets (ByteStorePtr bsp, AsnIoPtr aip, AsnTypePtr atp)
495 {
496 Uint4 totlen, tlen;
497 AsnTypePtr atp2;
498 Byte buf[100];
499
500 atp2 = AsnFindBaseType(atp);
501 atp2 = atp2->type;
502 AsnEnBinTags(atp2, aip);
503
504 totlen = BSLen(bsp);
505 AsnEnBinLen(totlen, aip);
506
507 BSSeek(bsp, 0, SEEK_SET);
508
509 while (totlen)
510 {
511 if (totlen < 100)
512 tlen = totlen;
513 else
514 tlen = 100;
515
516 BSRead(bsp, buf, tlen);
517 AsnEnBinBytes(buf, tlen, aip);
518 totlen -= tlen;
519 }
520 return;
521 }
522
523 /*****************************************************************************
524 *
525 * AsnEnBinOpenStruct(aip, atp)
526 *
527 *****************************************************************************/
528 NLM_EXTERN void AsnEnBinOpenStruct (AsnIoPtr aip, AsnTypePtr atp)
529 {
530 AsnTypePtr atp2;
531
532 atp2 = AsnFindBaseType(atp);
533 atp2 = atp2->type;
534 AsnEnBinTags(atp2, aip);
535 AsnEnBinStartIndef(aip);
536 AsnTypeSetIndent(TRUE, aip, atp);
537 return;
538 }
539
540 /*****************************************************************************
541 *
542 * AsnEnBinCloseStruct(aip, atp)
543 *
544 *****************************************************************************/
545 NLM_EXTERN void AsnEnBinCloseStruct (AsnIoPtr aip, AsnTypePtr atp)
546 {
547 int next_type, tagclass;
548
549 AsnEnBinEndIndef(aip); /* end the primitive struct */
550 tagclass = aip->typestack[aip->type_indent - 1].type->tagclass;
551 if (tagclass == TAG_CONTEXT)
552 AsnEnBinEndIndef(aip); /* end for user tags */
553 next_type = aip->type_indent - 2; /* end any choices */
554 while ((next_type >= 0) &&
555 (AsnFindBaseIsa(aip->typestack[next_type].type) == CHOICE_TYPE))
556 {
557 if (aip->typestack[next_type].type->tagclass != TAG_NONE)
558 AsnEnBinEndIndef(aip);
559 next_type--;
560 }
561 AsnTypeSetIndent(FALSE, aip, atp);
562 return;
563 }
564
565
566 /*****************************************************************************
567 *
568 * AsnEnBinStartIndef(aip)
569 *
570 *****************************************************************************/
571 NLM_EXTERN void AsnEnBinStartIndef (AsnIoPtr aip)
572 {
573 Byte octets[1];
574
575 octets[0] = 128; /* indefinate length encoding */
576 AsnEnBinBytes(octets, (Uint4)1, aip);
577 return;
578 }
579
580 /*****************************************************************************
581 *
582 * AsnEnBinEndIndef(aip)
583 *
584 *****************************************************************************/
585 NLM_EXTERN void AsnEnBinEndIndef (AsnIoPtr aip)
586 {
587 Byte nulls[2];
588
589 nulls[0] = 0;
590 nulls[1] = 0;
591 AsnEnBinBytes(nulls, (Uint4)2, aip);
592 return;
593 }
594
595
596 /*****************************************************************************
597 *
598 * void AsnEnBinTheBytes(ptr, len, aip, is_string)
599 * write bytes to asnio output
600 *
601 *****************************************************************************/
602 NLM_EXTERN Boolean LIBCALL AsnEnBinTheBytes (Pointer ptr, Uint4 len, AsnIoPtr aip, Boolean is_string)
603 {
604 register BytePtr from, to;
605 register int bytes, amount, bad_char = 0, bad_char_ctr = 0;
606
607 bytes = (int)(aip->bytes - aip->offset);
608 if (! bytes)
609 bytes = (int)AsnIoWriteBlock(aip);
610 to = aip->buf + aip->offset;
611 from = (BytePtr) ptr;
612
613 while (len)
614 {
615 if (aip->io_failure) /* physical device write failure */
616 return FALSE;
617
618 if (len <= (Uint4)bytes)
619 amount = (int)len;
620 else
621 amount = bytes;
622 bytes -= amount;
623 len -= (Uint4)amount;
624 while (amount)
625 {
626 *to = *from;
627 if (is_string)
628 {
629 if ((aip->fix_non_print != 2) && ((*from < ' ') || (*from > '~')))
630 {
631 if (! bad_char_ctr)
632 bad_char = (int)(*from);
633 bad_char_ctr++;
634 *from = '#';
635 *to = '#'; /* replace with # */
636 }
637 }
638 from++; to++; amount--;
639 }
640 if (! bytes)
641 {
642 aip->offset = aip->bytes; /* set to write whole block */
643 bytes = (int)AsnIoWriteBlock(aip);
644 to = aip->buf;
645 }
646 }
647 aip->offset = (Int2) (aip->bytes - (Int2) bytes);
648 if ((bad_char_ctr) && ((aip->fix_non_print == 0) || (aip->fix_non_print == 3)))
649 AsnIoErrorMsg(aip, 106, bad_char, (CharPtr)ptr);
650 return TRUE;
651 }
652
653 /*****************************************************************************
654 *
655 * void AsnBinLen(len, aip)
656 * encode a definate length
657 *
658 *****************************************************************************/
659 NLM_EXTERN void AsnEnBinLen (Uint4 len, AsnIoPtr aip)
660 {
661 Byte octets[5];
662 int octnum, i;
663
664 for (octnum = 0; octnum < 5; octnum++)
665 octets[octnum] = 0;
666
667 if (len <= 127) /* use short form */
668 {
669 octets[0] = (Byte)(len & 0x0ffff);
670 AsnEnBinBytes(octets, (Uint4)1, aip);
671 return;
672 }
673
674 if (len <= 0x0ff) /* use long form */
675 octnum = 1;
676 else if (len <= 0x0ffff)
677 octnum = 2;
678 else if (len <= 0x0ffffff)
679 octnum = 3;
680 else
681 octnum = 4;
682
683 octets[0] = (Byte)(0x080 | (octnum & 0x07f));
684
685 for (i = 1; i <= octnum; i++)
686 octets[i] = (Byte)((len >> ((octnum - i) * 8)) & 0x0ff);
687
688 octnum++;
689 AsnEnBinBytes(octets, (Uint4)octnum, aip);
690 return;
691 }
692
693 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |