|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/asnlib/asnio.c |
source navigation diff markup identifier search freetext search file search |
1 /* asnio.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: asnio.c
27 *
28 * Author: James Ostell
29 *
30 * Version Creation Date: 3/4/91
31 *
32 * $Revision: 6.12 $
33 *
34 * File Description:
35 * Routines for AsnIo objects. This code has some machine dependencies.
36 * Currently it works for all ncbi supported platforms.
37 *
38 * Modifications:
39 * --------------------------------------------------------------------------
40 * Date Name Description of modification
41 * ------- ---------- -----------------------------------------------------
42 * 3/4/91 Kans Stricter typecasting for GNU C and C++
43 * 4/7/91 Ostell Berkely Socket support, block I/O
44 * 04-20-93 Schuler LIBCALL calling convention
45 * 01-31-94 Schuler Changed ErrGetOpts/ErrSetOpts to ErrSaveOptions/ErrRestoreOptions
46 *
47 * $Log: asnio.c,v $
48 * Revision 6.12 2005/12/01 20:00:13 lavr
49 * AsnIoErrorMsg(): Don't insert extra LFs if there was no typestack dumped
50 *
51 * Revision 6.11 2002/05/20 23:13:39 ivanov
52 * Fixed overburn memory AsnIo buf in the AsnPrint*() -- increased
53 * buffers reserved room
54 *
55 * Revision 6.10 2001/10/11 14:39:08 ostell
56 * added support for XMLModulePrefix
57 *
58 * Revision 6.9 2001/03/13 13:11:46 ostell
59 * made AsnIoBSOpen() and AsnIoMemOpen() XML aware
60 *
61 * Revision 6.8 2001/02/02 22:08:47 shavirin
62 * Fixed case of opening AsnIoPtr in case of XML output for Linux.
63 *
64 * Revision 6.7 2000/05/10 03:12:37 ostell
65 * added support for XML DTD and XML data output
66 *
67 * Revision 6.6 1999/07/30 20:34:25 vakatov
68 * AsnIoGets(): rewritten -- to handle an incremental read
69 *
70 * Revision 6.5 1998/02/27 17:22:21 vakatov
71 * [WIN32 DLL] Declared some functions as NLM_EXTERN(DLL-exportable)
72 *
73 * Revision 6.4 1998/01/09 15:51:03 shavirin
74 * Hash function turned to be external
75 *
76 * Revision 6.3 1998/01/09 15:47:52 shavirin
77 * Added hash calculating functions.
78 *
79 * Revision 6.2 1997/12/04 21:41:14 shavirin
80 * Fixed bug with printing error message
81 *
82 * Revision 6.1 1997/10/29 02:41:13 vakatov
83 * Type castings to pass through the C++ compiler
84 *
85 * Revision 6.0 1997/08/25 18:10:00 madden
86 * Revision changed to 6.0
87 *
88 * Revision 5.4 1997/04/23 15:44:51 ostell
89 * commented out references to g_asnlib which caused unecessary error messages
90 * trying to open asnlib.msg file which does not exist.
91 *
92 * Revision 5.3 1996/12/03 21:43:48 vakatov
93 * Adopted for 32-bit MS-Windows DLLs
94 *
95 * Revision 5.2 1996/10/07 14:37:28 vakatov
96 * AsnIoErrorMsg() rearranged to avoid memory corruption when posting
97 * long (>2048 bytes) error messages
98 *
99 * Revision 5.1 1996/06/18 16:07:46 sad
100 * AsnIoGets errorneously reported that line too long at the end of file, fixed
101 *
102 * Revision 5.0 1996/05/28 14:00:29 ostell
103 * Set to revision 5.0
104 *
105 * Revision 4.6 1996/02/18 18:05:37 kans
106 * severity is an ErrSev variable
107 *
108 * Revision 4.5 1996/02/18 16:45:36 ostell
109 * changed fix_non_print behavior and added option 3
110 *
111 * Revision 4.4 1995/12/21 14:00:51 ostell
112 * added AsnIoFree()
113 *
114 * Revision 4.3 1995/12/18 21:38:00 epstein
115 * add diagnostic values in AsnIoWriteBlock error message
116 *
117 * Revision 4.2 1995/10/28 15:02:06 ostell
118 * added casts to quiet DOS compile warnings
119 *
120 * Revision 4.1 1995/09/14 20:41:02 sirotkin
121 * modification to AsnIoErrMsg to give meaningful error codes
122 *
123 * Revision 4.0 1995/07/26 13:47:38 ostell
124 * force revision to 4.0
125 *
126 * Revision 2.24 1995/05/26 22:14:40 ostell
127 * added spec_version saving to AsnIoReset
128 *
129 * Revision 2.23 1995/05/15 18:38:28 ostell
130 * added Log line
131 *
132 *
133 * ==========================================================================
134 */
135
136 /*****************************************************************************
137 *
138 * asnio.c
139 * routines for AsnIo objects
140 * AsnIoError() uses varargs, so has some portability issues
141 *
142 *****************************************************************************/
143
144 #include "asnbuild.h"
145 #include <tsprintf.h>
146
147 /*
148 NLM_EXTERN char * g_asnlib = "AsnLib";
149 */
150
151 static Int2 bufsize = ASNIO_BUFSIZE; /* current default size of AsnIo buf */
152
153 /*****************************************************************************
154 *
155 * AsnIoPtr AsnIoOpen(file_name, mode)
156 *
157 *****************************************************************************/
158 NLM_EXTERN AsnIoPtr LIBCALL AsnIoOpen (CharPtr file_name, CharPtr mode)
159 {
160 AsnIoPtr aip;
161 Int1 type;
162 FILE *fp;
163
164 if (file_name == NULL)
165 {
166 AsnIoErrorMsg(NULL, 80);
167 return NULL;
168 }
169
170 if (! StringCmp(mode, "r"))
171 type = ASNIO_TEXT_IN;
172 else if (! StringCmp(mode, "w"))
173 type = ASNIO_TEXT_OUT;
174 else if (! StringCmp(mode, "wx"))
175 {
176 type = ASNIO_TEXT_OUT;
177 type |= ASNIO_XML;
178 }
179 else if (! StringCmp(mode, "rb"))
180 type = ASNIO_BIN_IN;
181 else if (! StringCmp(mode, "wb"))
182 type = ASNIO_BIN_OUT;
183 else
184 {
185 AsnIoErrorMsg(NULL, 81, mode);
186 return NULL;
187 }
188
189 if (!StringCmp(mode, "wx")) {
190 fp = FileOpen(file_name, "w");
191 } else {
192 fp = FileOpen(file_name, mode);
193 }
194
195 if (fp == NULL)
196 {
197 /*** Message posted by FileOpen() **
198 AsnIoErrorMsg(NULL, 82, file_name);
199 ***********************************/
200 return NULL;
201 }
202
203 aip = AsnIoNew(type, fp, NULL, NULL, NULL);
204 if (aip != NULL)
205 aip->fname = StringSave(file_name);
206
207 return aip;
208 }
209
210 static CharPtr AsnXMLModuleDefaultPrefix = "\0";
211 static CharPtr AsnXMLModulePrefix = "\0";
212
213 NLM_EXTERN Boolean LIBCALL AsnSetXMLmodulePrefix (CharPtr prefix)
214 {
215 static CharPtr zero = "\0";
216 AsnXMLModulePrefix = prefix;
217 if (prefix == NULL)
218 AsnXMLModulePrefix = zero;
219 return TRUE;
220 }
221 NLM_EXTERN Boolean LIBCALL AsnSetXMLmodulePrefixToDefault (void)
222 {
223 AsnXMLModulePrefix = AsnXMLModuleDefaultPrefix;
224 return TRUE;
225 }
226
227 NLM_EXTERN CharPtr LIBCALL AsnGetXMLmodulePrefix (void)
228 {
229 return AsnXMLModulePrefix;
230 }
231
232 /*****************************************************************************
233 *
234 * AsnIoPtr AsnIoNew(type, fp, iostruct, readfunc, writefunc)
235 * function pointers are optional
236 * if not given, uses file functions
237 *
238 *****************************************************************************/
239 NLM_EXTERN AsnIoPtr LIBCALL AsnIoNew (Int1 type, FILE *fp, Pointer iostruct, IoFuncType readfunc, IoFuncType writefunc)
240 {
241 AsnIoPtr aip;
242
243 aip = (AsnIoPtr) MemNew(sizeof(AsnIo));
244 if (aip == NULL)
245 return NULL;
246
247 aip->bufsize = bufsize;
248 if (! (type & ASNIO_CARRIER)) /* not AsnIoNullOpen() */
249 aip->buf = (BytePtr) MemNew(bufsize);
250 aip->type = type;
251 aip->fp = fp;
252 aip->iostruct = iostruct;
253 aip->readfunc = readfunc;
254 aip->writefunc = writefunc;
255
256 if (type & ASNIO_OUT)
257 aip->bytes = aip->bufsize; /* have a buffer ready to write */
258 aip->linebuf = (CharPtr)aip->buf;
259 aip->tabsize = 2;
260 aip->linelength = 78;
261 aip->max_indent = 10; /* start with 10 indent levels */
262 aip->first = (BoolPtr) MemNew((sizeof(Boolean) * 10));
263 aip->first[0] = TRUE;
264 aip->typestack = (PstackPtr) MemNew((sizeof(Pstack) * 10));
265 aip->max_type = 10;
266 return aip;
267 }
268
269 /*****************************************************************************
270 *
271 * AsnIoPtr AsnIoClose(aip)
272 *
273 *****************************************************************************/
274 NLM_EXTERN AsnIoPtr LIBCALL AsnIoClose (AsnIoPtr aip)
275 {
276 return AsnIoFree (aip, TRUE);
277 }
278
279 /*****************************************************************************
280 *
281 * AsnIoPtr AsnIoFree(aip, close_file)
282 *
283 *****************************************************************************/
284 NLM_EXTERN AsnIoPtr LIBCALL AsnIoFree (AsnIoPtr aip, Boolean close_file)
285 {
286 FILE *fp;
287 int type;
288
289 if (aip == NULL)
290 return aip;
291
292 type = aip->type;
293 fp = aip->fp;
294
295 if (type & ASNIO_OUT)
296 {
297 aip->first[aip->indent_level] = TRUE;
298 if (type & ASNIO_TEXT)
299 AsnPrintNewLine(aip);
300 AsnIoFlush(aip);
301 }
302
303 if (close_file)
304 FileClose(fp);
305
306 MemFree(aip->first);
307 MemFree(aip->typestack);
308 MemFree(aip->buf);
309 if (aip->fname != NULL)
310 MemFree(aip->fname);
311 AsnIoOptionFree(aip, 0, 0);
312 AsnExpOptFree(aip, NULL);
313 MemFree(aip);
314 return NULL;
315 }
316
317 /*****************************************************************************
318 *
319 * AsnOptionPtr AsnIoOptionNew(aip, ao_class, type, data, freefunc)
320 * allocates and adds an option to aip
321 * returns a pointer to it.
322 *
323 *****************************************************************************/
324 NLM_EXTERN AsnOptionPtr LIBCALL AsnIoOptionNew (AsnIoPtr aip, Int2 ao_class, Int2 type, DataVal data, AsnOptFreeFunc freefunc)
325 {
326 if (aip == NULL)
327 return NULL;
328
329 return AsnOptionNew(&aip->aop, ao_class, type, data, freefunc);
330 }
331
332 /*****************************************************************************
333 *
334 * AsnIoOptionFree(aip, ao_class, type)
335 * clears options of ao_class
336 * or if ao_class == 0 clears all options
337 * if type == 0, clears all options of ao_class
338 *
339 *****************************************************************************/
340 NLM_EXTERN void LIBCALL AsnIoOptionFree (AsnIoPtr aip, Int2 ao_class, Int2 type)
341 {
342 AsnOptionFree(&aip->aop, ao_class, type);
343 return;
344 }
345
346 /*****************************************************************************
347 *
348 * AsnOptionPtr AsnIoOptionGet(aip, ao_class, type, last)
349 * gets next option after last
350 * start with last = NULL
351 * if ao_class = 0, match any ao_class
352 * type = 0 match any type
353 *
354 *****************************************************************************/
355 NLM_EXTERN AsnOptionPtr LIBCALL AsnIoOptionGet (AsnIoPtr aip, Int2 ao_class, Int2 type, AsnOptionPtr last)
356 {
357 if (aip == NULL)
358 return NULL;
359
360 return AsnOptionGet(aip->aop, ao_class, type, last);
361 }
362
363 /*****************************************************************************
364 *
365 * AsnOptionPtr AsnOptionNew(aopp, ao_class, type, data, freefunc)
366 * allocates and adds an option to aopp
367 * returns a pointer to it.
368 *
369 *****************************************************************************/
370 NLM_EXTERN AsnOptionPtr LIBCALL AsnOptionNew (AsnOptionPtr PNTR aopp, Int2 ao_class, Int2 type, DataVal data, AsnOptFreeFunc freefunc)
371 {
372 AsnOptionPtr aop, curr;
373
374 aop = (AsnOptionPtr) MemNew(sizeof(AsnOption));
375 if (aop == NULL)
376 return NULL;
377
378 aop->ao_class = ao_class;
379 aop->type = type;
380 aop->data = data;
381 aop->freefunc = freefunc;
382
383 if (aopp != NULL)
384 {
385 curr = *aopp;
386 if (curr == NULL)
387 *aopp = aop;
388 else
389 {
390 while (curr->next != NULL)
391 curr = curr->next;
392 curr->next = aop;
393 }
394 }
395 return aop;
396 }
397
398 /*****************************************************************************
399 *
400 * AsnOptionFree(aopp, ao_class, type)
401 * clears options of ao_class
402 * or if ao_class == 0 clears all options
403 * if type == 0, clears all options of ao_class
404 *
405 *****************************************************************************/
406 NLM_EXTERN void LIBCALL AsnOptionFree (AsnOptionPtr PNTR aopp, Int2 ao_class, Int2 type)
407 {
408 AsnOptionPtr curr, next, prev, first;
409
410 if (aopp == NULL)
411 return;
412
413 curr = *aopp;
414 prev = NULL;
415 first = NULL;
416 while (curr != NULL)
417 {
418 next = curr->next;
419 if (AsnClassTypeMatch (ao_class, type,
420 curr->ao_class, curr->type))
421 {
422 if (curr->freefunc != NULL)
423 (*curr->freefunc)(curr->data.ptrvalue);
424 if (prev != NULL)
425 prev->next = next;
426 MemFree(curr);
427 }
428 else
429 {
430 if (first == NULL)
431 first = curr;
432 prev = curr;
433 }
434 curr = next;
435 }
436
437 *aopp = first;
438 return;
439 }
440
441
442 /*****************************************************************************
443 *
444 * Boolean AsnClassTypeMatch (ao_class, type, this_class, this_type)
445 * checks if ao_class and type match in a way that makes for
446 * clean logic
447 **********************/
448 NLM_EXTERN Boolean LIBCALL AsnClassTypeMatch (Int2 ao_class, Int2 type, Int2 this_class, Int2 this_type)
449 {
450 Boolean retval = FALSE;
451
452 if ((! ao_class) || (ao_class == this_class))
453 {
454 if ((! type) || (type == this_type))
455 {
456 retval = TRUE;
457 }
458 }
459
460 return retval;
461 }
462
463 /*****************************************************************************
464 *
465 * AsnOptionPtr AsnOptionGet(head, ao_class, type, last)
466 * gets next option after last
467 * start with last = NULL
468 * if ao_class = 0, match any ao_class
469 * type = 0 match any type
470 *
471 *****************************************************************************/
472 NLM_EXTERN AsnOptionPtr LIBCALL AsnOptionGet (AsnOptionPtr head, Int2 ao_class, Int2 type, AsnOptionPtr last)
473
474 {
475 AsnOptionPtr aop;
476
477 if (head == NULL)
478 return NULL;
479
480 aop = head;
481
482 if (last != NULL)
483 {
484 while ((aop != NULL) && (aop != last))
485 aop = aop->next;
486 if (aop != NULL)
487 aop = aop->next;
488 }
489
490 while (aop != NULL)
491 {
492 if ((ao_class == 0) || (ao_class == aop->ao_class))
493 {
494 if ((type == 0) || (type == aop->type))
495 return aop;
496 }
497 aop = aop->next;
498 }
499
500 return NULL;
501 }
502
503 /*****************************************************************************
504 *
505 * Boolean AsnIoSetBufsize(aip, size)
506 * replaces current buffer with one of new size
507 * ASSUMES aip has NOT YET been USED
508 * if (aip == NULL)
509 * changes default size of buffer for all new AsnIo
510 *
511 *****************************************************************************/
512 NLM_EXTERN Boolean LIBCALL AsnIoSetBufsize (AsnIoPtr aip, Int2 size)
513 {
514 BytePtr tmp;
515
516 if (aip == NULL)
517 {
518 bufsize = size; /* set default size */
519 return TRUE;
520 }
521 else
522 {
523 tmp = (BytePtr) MemNew(size);
524 if (tmp == NULL)
525 return FALSE;
526 MemFree(aip->buf);
527 aip->buf = tmp;
528 aip->bufsize = size;
529 aip->linebuf = (CharPtr)aip->buf;
530 if (aip->type & ASNIO_OUT)
531 aip->bytes = size;
532 /* have a new sized buffer ready to write */
533 return TRUE;
534 }
535 }
536
537 /*****************************************************************************
538 *
539 * void AsnIoPuts(aip)
540 * put the linebuf
541 *
542 *****************************************************************************/
543 NLM_EXTERN void AsnIoPuts (AsnIoPtr aip)
544 {
545 if (aip->linepos == 0)
546 return;
547
548 if (! aip->no_newline)
549 {
550 aip->linebuf[aip->linepos] = '\n';
551 aip->offset++;
552 }
553
554 aip->linepos = 0;
555
556 if ((aip->bytes - aip->offset) > (aip->linelength + ASNIO_BUFSIZE_RESERVE)) /* room left */
557 aip->linebuf = (CharPtr)aip->buf + aip->offset;
558 else
559 {
560 AsnIoWriteBlock(aip); /* write it out */
561 aip->linebuf = (CharPtr)aip->buf; /* reset line pointer */
562 }
563
564 if (aip->no_newline)
565 aip->no_newline = FALSE;
566
567 return;
568 }
569
570
571 /*****************************************************************************
572 *
573 * CharPtr AsnIoGets(aip)
574 * equivalent of fgets()
575 * only works on TEXT_IN files
576 * increments aip->linenumber
577 *
578 *****************************************************************************/
579 NLM_EXTERN CharPtr AsnIoGets (AsnIoPtr aip)
580 {
581 Int2 offset = aip->offset; /* current end of line */
582 Int2 bytes = aip->bytes - offset; /* unread bytes in buffer */
583 CharPtr str = (CharPtr)aip->buf + offset; /* start of next line */
584 Int2 len = 0; /* # of bytes read in line */
585
586 for (;;) {
587 /* no more data in the buffer? */
588 if (bytes <= 0) {
589 /* check if line is longer than the whole block */
590 if (offset == 0 && len == aip->bufsize) {
591 AsnIoErrorMsg(aip, 74, (int)aip->bufsize, aip->linenumber);
592 return 0;
593 }
594
595 /* move data to the very beginning of the buffer, if necessary */
596 if (offset && aip->bytes == aip->bufsize) {
597 if ( len )
598 MemCopy(aip->buf, aip->buf + offset, (size_t)len);
599 offset = 0;
600 str = (CharPtr)aip->buf + len;
601 }
602
603 /* read to the buffer */
604 aip->offset = offset + len;
605 bytes = AsnIoReadBlock(aip);
606 if ( !bytes ) {
607 if ( !len ) {
608 return 0; /* cant read a thing */
609 } else {
610 *str = '\n';
611 break; /* assume EOF and no last newline */
612 }
613 }
614 continue;
615 }
616
617 /* check for EOL, else forward to the next symbol */
618 len++; /* EOL included */
619 if (*str == '\n' || *str == '\r')
620 break; /* EOL */
621 str++;
622 bytes--;
623 } /* for (;;) */
624
625 aip->offset = offset + len;
626 aip->linenumber++;
627 aip->linebuf = (CharPtr)aip->buf + offset;
628 return aip->linebuf;
629 }
630
631
632 /*****************************************************************************
633 *
634 * Int4 AsnIoTell(aip)
635 * gives seek offset in current file or -1 if error
636 *
637 *****************************************************************************/
638 NLM_EXTERN Int4 LIBCALL AsnIoTell (AsnIoPtr aip)
639 {
640 Int4 offset, bytes;
641
642 if (!(aip->type & ASNIO_FILE))
643 {
644 AsnIoErrorMsg(aip, 75);
645 return 0L;
646 }
647 offset = ftell(aip->fp); /* position after last read */
648 if (aip->type & ASNIO_IN)
649 {
650 bytes = aip->bytes - aip->offset; /* bytes left in buffer */
651 offset -= bytes; /* real position by byte */
652 if (aip->tagsaved) /* binary tags saved? */
653 offset -= aip->used; /* remove that too */
654 }
655 else
656 {
657 offset += aip->offset; /* unflushed stuff in buffer */
658 }
659 return offset;
660 }
661
662
663 /*****************************************************************************
664 *
665 * Int4 AsnIoSeek(aip, pos)
666 * seeks to pos
667 *
668 *****************************************************************************/
669 NLM_EXTERN Int4 LIBCALL AsnIoSeek (AsnIoPtr aip, Int4 pos)
670 {
671 if (! (aip->type & ASNIO_IN))
672 {
673 AsnIoErrorMsg(aip, 76);
674 return 0L;
675 }
676 if (! (aip->type & ASNIO_FILE))
677 {
678 AsnIoErrorMsg(aip, 77);
679 return 0L;
680 }
681 pos = fseek(aip->fp, pos, 0); /* formatted file */
682 AsnIoReset(aip);
683 return pos;
684 }
685
686 /*****************************************************************************
687 *
688 * Int2 AsnIoReadBlock(aip)
689 * returns bytes read
690 *
691 *****************************************************************************/
692 NLM_EXTERN Int2 AsnIoReadBlock (AsnIoPtr aip)
693 {
694 Int2 bytes, offset, retval;
695
696 if (aip->type & ASNIO_TEXT)
697 {
698 offset = aip->offset;
699 bytes = aip->bufsize - offset;
700 }
701 else
702 {
703 bytes = aip->bufsize;
704 offset = 0;
705 }
706
707 if (aip->readfunc == NULL) /* use standard read */
708 {
709 retval = (Int2) FileRead((VoidPtr)(aip->buf + offset), (size_t)1, (size_t) bytes, aip->fp);
710 }
711 else /* use alternative read function */
712 retval = (* aip->readfunc)(aip->iostruct, (CharPtr)(aip->buf + offset), (Uint2)bytes);
713 if (retval > 0)
714 aip->bytes = retval + offset; /* space available to read */
715 else
716 aip->bytes = offset;
717 aip->offset = 0; /* bytes read */
718 if (retval < 0)
719 {
720 AsnIoErrorMsg(aip, 78, retval);
721 retval = 0; /* callers look for 0 as bad return value */
722 }
723 return retval;
724 }
725
726 /*****************************************************************************
727 *
728 * Int2 AsnIoWriteBlock(aip)
729 * does NOT return bytes written
730 * return bytes available in buffer to write on
731 *
732 *****************************************************************************/
733 NLM_EXTERN Int2 AsnIoWriteBlock (AsnIoPtr aip)
734 {
735 Int2 retval, bytes_to_write, offset;
736
737 if (aip->io_failure)
738 return 0;
739 if (aip->used > 2) /* recursion stopper */
740 return 0;
741 aip->used++; /* recursion counter */
742
743 if (aip->type & ASNIO_TEXT)
744 {
745 offset = (Int2)aip->length; /* amount sent on last AsnIoFlush */
746 bytes_to_write = aip->offset - offset;
747 }
748 else
749 {
750 offset = 0;
751 bytes_to_write = aip->offset;
752 }
753
754 if (aip->writefunc == NULL) /* use standard write */
755 {
756 retval = (Int2) FileWrite((VoidPtr)(aip->buf + offset), (size_t)1,
757 (size_t) bytes_to_write, aip->fp);
758 }
759 else /* use alternative write function */
760 retval = (* aip->writefunc)(aip->iostruct, (CharPtr)(aip->buf + offset),
761 (Uint2) bytes_to_write);
762 if (retval != bytes_to_write)
763 {
764 AsnIoErrorMsg(aip, 79, retval, bytes_to_write);
765 aip->io_failure = TRUE;
766 }
767 if (aip->type & ASNIO_TEXT) /* check for full line */
768 {
769 if ((aip->buf[aip->offset - 1] == '\n') || (aip->no_newline))
770 {
771 aip->length = 0;
772 aip->offset = 0; /* write space used */
773 aip->linebuf = (CharPtr)aip->buf;
774 aip->bytes = aip->bufsize; /* free write space */
775 }
776 else
777 {
778 aip->length = aip->offset; /* store flushed section */
779 }
780 }
781 else
782 {
783 aip->bytes = aip->bufsize; /* free write space */
784 aip->offset = 0; /* write space used */
785 }
786 aip->used--; /* warning! each invocation of this function must decrement */
787 return aip->bytes;
788 }
789
790 static char * AsnIoErrStr[107] = {
791 #ifdef WIN16
792
793 "Sorry. Not supported yet",
794 "Cannot start AsnDeBinType() with unknown Type",
795 "tag mismatch on %Fs",
796 "Expected 00 after tag for %Fs",
797 "Tag mismatch on SET/SEQ OF %Fs",
798 "Unable to match element in %Fs.",
799 "element %Fs out of order in SEQUENCE %Fs",
800 "Skipped element %Fs in SEQUENCE %Fs",
801 "AsnDeBinDecr: lenstack[%d] < 0",
802 "type [%Fs]. Unresolved imported type [%Fs]",
803 "type [%Fs]. Unresolved base type [%Fs]",
804 "Unable to read value of %Fs.",
805 "%ld is an invalid value for %Fs.",
806 "Boolean %Fs must be one byte",
807 "Can't allocate %ld bytes for %Fs",
808 "AsnDeBinReal- not encoded as decimal",
809 "NULL value without 0 length for %Fs",
810 "Premature end of file",
811 "End Struct too late in value",
812 "Unable to write value of %Fs.",
813 "AsnEndStruct with nothing on stack.",
814 "AsnEndStruct of %Fs does not match %Fs",
815 "%Fs [%Fs] is not an element of %Fs",
816 "[%Fs] CHOICE may only have one value [%Fs]",
817 "Cannot duplicate element %Fs in SEQ or SET %Fs",
818 "Parent type not struct. %Fs isa=%d",
819 "Input value file must start with Defined Type. line %ld",
820 "Type Reference not found in module. line %ld",
821 "Expected ::= after Type Reference on input. line %ld",
822 "Expected to start with %Fs. line %ld",
823 "Expected comma or } in input value. line %ld",
824 "Expected identifier. line %ld",
825 "Unable to match element in %Fs. line %ld",
826 "element %Fs out of order in SEQUENCE %Fs. line number %ld",
827 "Skipped element %Fs in SEQUENCE %Fs. line %ld",
828 "type [%Fs]. Unresolved imported type [%Fs]. line %ld",
829 "type [%Fs]. Unresolved base type [%Fs]. line %ld",
830 "Expected { line %ld",
831 "Unable to read value of %Fs. line %ld",
832 "Integer value not found for %Fs. line %ld",
833 "Invalid value for %Fs. line %ld",
834 "General defined values not supported yet. %Fs on line %ld",
835 "Invalid value for BOOLEAN %Fs. line %ld",
836 "No \" on string start for %Fs. line %ld",
837 "No \" on string end for %Fs. line %ld",
838 "No \' on OCTET start for %Fs. line %ld",
839 "AsnLexReadOctets on %Fs. line %ld",
840 "No \'H on OCTETs end for %Fs. line %ld",
841 "Uneven number in OCTETS for %Fs. line %ld",
842 "REAL %Fs must start with {. line %ld",
843 "mantissa error on %Fs. line %ld",
844 "comma missing after mantissa on %Fs. line %ld",
845 "base incorrect on %Fs. line %ld",
846 "only base 2 or 10 allowed. %Fs on line %ld",
847 "comma missing after base on %Fs. line %ld",
848 "exponent error on %Fs. line %ld",
849 "no } on %Fs. line %ld",
850 "Expected NULL for %Fs. line %ld",
851 "Can't identify Bit/Hex string line %ld",
852 "Unrecognized token %c. line %ld",
853 "ReadModule: Ref or ident required. line %ld but got %Fs",
854 "No ] on tag. line %ld",
855 "AsnLexTReadType: defined number not supported. line %ld",
856 "No integer tag. line %ld",
857 "Sorry. Subtypes not supported yet. line %ld",
858 "Enumerated type MUST have values. line %ld",
859 "Expected comma around line %ld",
860 "%Fs is an ASN.1 reserved word. line %ld",
861 "object identifier not implemented",
862 "Module: missing %s. line %ld",
863 "Comma out of place. line %ld",
864 "IMPORTS: expected typeref before FROM on line %ld",
865 "IMPORTS: expected Module on line %ld",
866 "Object Indentifier not supported. line %ld",
867 "Input line longer than %d. line %ld",
868 "AsnIoTell on non-FILE",
869 "AsnIoSeek on non-INPUT file",
870 "AsnIoSeek on non-FILE",
871 "Read Error [%d] in AsnIoReadBlock",
872 "AsnIoWriteBlock: too few bytes written [retvalue %d, requested %d]",
873 "No file name given on AsnIoOpen",
874 "Unrecognized AsnIoOpen mode [%Fs]",
875 "Cannot open file [%Fs]",
876 "Cannot open parse tree load file [%Fs]",
877 "[%Fs] should be EXPORTED from module [%Fs]",
878 "Cannot find path to parse tree load files", /* [85] */
879 "Expected identifier for named integer. line %ld",
880 "Missing ( in named integer. line %ld",
881 "Missing ) in named integer. line %ld",
882 "Expected OF on line %ld",
883 "Expected STRING. line %ld",
884 "Invalid token after OF. line %ld",
885 "Syntax error after OBJECT. line %ld",
886 "Sorry. COMPONENTS OF not supported yet. line %ld",
887 "Default for %Fs not supported",
888 "Sorry. Cannot find type def for %Fs to set DEFAULT. line %ld",
889 "IMPORTS: expected Ref line %ld",
890 "EXPORTS line after IMPORTS. line %ld",
891 "%Fs is not a valid Type name. line %ld",
892 "Redefinition of %Fs. line %ld",
893 "Type %Fs was not resolved in module %Fs",
894 "IMPORTED Type %Fs was never referenced in module %Fs",
895 "No IMPORT source for type %Fs in module %Fs",
896 "Did not AsnReadId before AsnReadVal. line %ld" ,
897 "Did not AsnReadVal before AsnReadId. line %ld",
898 "Did not load parse trees for trying to explore them",
899 "Invalid value(s) [%d] in VisibleString [%Fs ...]"
900
901 #else
902
903 "Sorry. Not supported yet",
904 "Cannot start AsnDeBinType() with unknown Type",
905 "tag mismatch on %s",
906 "Expected 00 after tag for %s",
907 "Tag mismatch on SET/SEQ OF %s",
908 "Unable to match element in %s.",
909 "element %s out of order in SEQUENCE %s",
910 "Skipped element %s in SEQUENCE %s",
911 "AsnDeBinDecr: lenstack[%d] < 0",
912 "type [%s]. Unresolved imported type [%s]",
913 "type [%s]. Unresolved base type [%s]",
914 "Unable to read value of %s.",
915 "%ld is an invalid value for %s.",
916 "Boolean %s must be one byte",
917 "Can't allocate %ld bytes for %s",
918 "AsnDeBinReal- not encoded as decimal",
919 "NULL value without 0 length for %s",
920 "Premature end of file",
921 "End Struct too late in value",
922 "Unable to write value of %s.",
923 "AsnEndStruct with nothing on stack.",
924 "AsnEndStruct of %s does not match %s",
925 "%s [%s] is not an element of %s",
926 "[%s] CHOICE may only have one value [%s]",
927 "Cannot duplicate element %s in SEQ or SET %s",
928 "Parent type not struct. %s isa=%d",
929 "Input value file must start with Defined Type. line %ld",
930 "Type Reference not found in module. line %ld",
931 "Expected ::= after Type Reference on input. line %ld",
932 "Expected to start with %s. line %ld",
933 "Expected comma or } in input value. line %ld",
934 "Expected identifier. line %ld",
935 "Unable to match element in %s. line %ld",
936 "element %s out of order in SEQUENCE %s. line number %ld",
937 "Skipped element %s in SEQUENCE %s. line %ld",
938 "type [%s]. Unresolved imported type [%s]. line %ld",
939 "type [%s]. Unresolved base type [%s]. line %ld",
940 "Expected { line %ld",
941 "Unable to read value of %s. line %ld",
942 "Integer value not found for %s. line %ld",
943 "Invalid value for %s. line %ld",
944 "General defined values not supported yet. %s on line %ld",
945 "Invalid value for BOOLEAN %s. line %ld",
946 "No \" on string start for %s. line %ld",
947 "No \" on string end for %s. line %ld",
948 "No \' on OCTET start for %s. line %ld",
949 "AsnLexReadOctets on %s. line %ld",
950 "No \'H on OCTETs end for %s. line %ld",
951 "Uneven number in OCTETS for %s. line %ld",
952 "REAL %s must start with {. line %ld",
953 "mantissa error on %s. line %ld",
954 "comma missing after mantissa on %s. line %ld",
955 "base incorrect on %s. line %ld",
956 "only base 2 or 10 allowed. %s on line %ld",
957 "comma missing after base on %s. line %ld",
958 "exponent error on %s. line %ld",
959 "no } on %s. line %ld",
960 "Expected NULL for %s. line %ld",
961 "Can't identify Bit/Hex string line %ld",
962 "Unrecognized token %c. line %ld",
963 "ReadModule: Ref or ident required. line %ld but got %s",
964 "No ] on tag. line %ld",
965 "AsnLexTReadType: defined number not supported. line %ld",
966 "No integer tag. line %ld",
967 "Sorry. Subtypes not supported yet. line %ld",
968 "Enumerated type MUST have values. line %ld",
969 "Expected comma around line %ld",
970 "%s is an ASN.1 reserved word. line %ld",
971 "object identifier not implemented",
972 "Module: missing %s. line %ld",
973 "Comma out of place. line %ld",
974 "IMPORTS: expected typeref before FROM on line %ld",
975 "IMPORTS: expected Module on line %ld",
976 "Object Indentifier not supported. line %ld",
977 "Input line longer than %d. line %ld",
978 "AsnIoTell on non-FILE",
979 "AsnIoSeek on non-INPUT file",
980 "AsnIoSeek on non-FILE",
981 "Read Error [%d] in AsnIoReadBlock",
982 "AsnIoWriteBlock: too few bytes written [retvalue %d, requested %d]",
983 "No file name given on AsnIoOpen",
984 "Unrecognized AsnIoOpen mode [%s]",
985 "Cannot open file [%s]",
986 "Cannot open parse tree load file [%s]",
987 "[%s] should be EXPORTED from module [%s]",
988 "Cannot find path to parse tree load files", /* [85] */
989 "Expected identifier for named integer. line %ld",
990 "Missing ( in named integer. line %ld",
991 "Missing ) in named integer. line %ld",
992 "Expected OF on line %ld",
993 "Expected STRING. line %ld",
994 "Invalid token after OF. line %ld",
995 "Syntax error after OBJECT. line %ld",
996 "Sorry. COMPONENTS OF not supported yet. line %ld",
997 "Default for %s not supported",
998 "Sorry. Cannot find type def for %s to set DEFAULT. line %ld",
999 "IMPORTS: expected Ref line %ld",
1000 "EXPORTS line after IMPORTS. line %ld",
1001 "%s is not a valid Type name. line %ld",
1002 "Redefinition of %s. line %ld",
1003 "Type %s was not resolved in module %s",
1004 "IMPORTED Type %s was never referenced in module %s",
1005 "No IMPORT source for type %s in module %s",
1006 "Did not AsnReadId before AsnReadVal. line %ld" ,
1007 "Did not AsnReadVal before AsnReadId. line %ld",
1008 "Did not load parse trees for trying to explore them",
1009 "Invalid value(s) [%d] in VisibleString [%s ...]"
1010
1011 #endif
1012 };
1013
1014 /**************************************************************************
1015 *
1016 * AsnErrGetTypeName(name)
1017 *
1018 **************************************************************************/
1019 NLM_EXTERN CharPtr LIBCALL AsnErrGetTypeName (CharPtr name)
1020 {
1021 if (name == NULL)
1022 return ".E";
1023 else
1024 return name;
1025 }
1026
1027 /*****************************************************************************
1028 *
1029 * AsnIoErrorMsg(aip, errcode, args)
1030 *
1031 *****************************************************************************/
1032 #ifdef VAR_ARGS
1033 NLM_EXTERN void CDECL AsnIoErrorMsg(aip, errcode, va_alist)
1034 AsnIoPtr aip;
1035 int errcode;
1036 va_dcl
1037 #else
1038 NLM_EXTERN void CDECL AsnIoErrorMsg(AsnIoPtr aip, int errcode, ...)
1039 #endif
1040 {
1041 CharPtr buf, ptr;
1042 ErrSev severity = SEV_FATAL;
1043 size_t length = 1024; /* estimated maximum of AsnTypeDumpStack() */
1044 CharPtr aip_fname_str = NULL;
1045 CharPtr aip_type_str = NULL;
1046 CharPtr arg_str = NULL;
1047
1048 if (aip != NULL) /* set the error flag for asnlib error */
1049 {
1050 /* non-printing chars in string may not be fatal */
1051 if (errcode == 106 && aip->fix_non_print == 0)
1052 severity = SEV_ERROR;
1053 else
1054 aip->io_failure = TRUE;
1055
1056 if (aip->fname != NULL)
1057 aip_fname_str = aip->fname;
1058
1059 if (aip->type & ASNIO_IN)
1060 aip_type_str = "Input ";
1061 else
1062 {
1063 AsnIoFlush( aip );
1064 aip_type_str = "Output ";
1065 }
1066 }
1067 length += StringLen(aip_fname_str) + StringLen(aip_type_str);
1068
1069 {{
1070 va_list args;
1071 #ifdef VAR_ARGS
1072 va_start(args); /* get the arguments */
1073 #else
1074 va_start(args, errcode);
1075 #endif
1076 arg_str = StringSave( TSPrintfArgs(AsnIoErrStr[errcode], args) );
1077 va_end(args);
1078 }}
1079 length += StringLen(arg_str);
1080
1081 buf = (CharPtr) Malloc(length + 1); *buf = '\0';
1082 StringCat(buf, aip_fname_str);
1083 StringCat(buf, aip_type_str);
1084 ptr = buf + StringLen( buf );
1085
1086 if (aip != NULL)
1087 {
1088 ASSERT (! *ptr);
1089 AsnTypeDumpStack(ptr, aip); /* put in the type stack */
1090 if (ptr[0] && (ptr[0] != ' ' || ptr[1]))
1091 {
1092 ASSERT (ptr[-1] == ' ');
1093 *--ptr = '\n';
1094 while ( *ptr )
1095 ptr++;
1096 *ptr++ = '\n';
1097 *ptr = '\0';
1098 }
1099 }
1100
1101 ASSERT ( StringLen(buf) + StringLen(arg_str) <= length );
1102 StringCpy(ptr, arg_str);
1103 MemFree( arg_str );
1104
1105 if (aip != NULL && aip->error_ret != NULL)
1106 (*aip->error_ret)((Int2)errcode, (CharPtr)buf);
1107 else
1108 ErrPostEx(severity, CTX_NCBIASN1, errcode, "%s", buf);
1109
1110 Free( buf );
1111 return;
1112 }
1113
1114
1115 /*****************************************************************************
1116 *
1117 * void AsnIoSetErrorMsg(aip, ErrorRetType)
1118 * set user error handler
1119 *
1120 *****************************************************************************/
1121 NLM_EXTERN void LIBCALL AsnIoSetErrorMsg (AsnIoPtr aip, AsnErrorFunc error_ret)
1122 {
1123 aip->error_ret = error_ret;
1124 return;
1125 }
1126
1127 /*****************************************************************************
1128 *
1129 * void AsnIoReset(aip)
1130 * resets parse state of aip
1131 * does not reset file or error handler
1132 *
1133 *****************************************************************************/
1134 NLM_EXTERN void LIBCALL AsnIoReset (AsnIoPtr aip)
1135 {
1136 FILE * fp;
1137 Int1 type, max_type, max_indent, linelength, tabsize;
1138 PstackPtr typestack;
1139 BoolPtr first;
1140 ErrorRetType error_ret;
1141 Pointer iostruct;
1142 IoFuncType readfunc, writefunc;
1143 Int2 tbufsize;
1144 BytePtr buf;
1145 CharPtr fname; /* name of file in use */
1146 AsnOptionPtr aop; /* head of options chain */
1147 AsnExpOptPtr aeop; /* exploration options chain */
1148 AsnExpOptStructPtr aeosp;
1149 Uint1 fix_non_print;
1150 Int2 spec_version;
1151
1152 if (aip->type & ASNIO_OUT)
1153 {
1154 if (aip->type & ASNIO_TEXT)
1155 AsnPrintNewLine(aip);
1156 AsnIoFlush(aip); /* clear it */
1157 }
1158
1159 fp = aip->fp; /* things to save */
1160 linelength = aip->linelength;
1161 tabsize = aip->tabsize;
1162 type = aip->type;
1163 max_type = aip->max_type;
1164 max_indent = aip->max_indent;
1165 first = aip->first;
1166 typestack = aip->typestack;
1167 error_ret = aip->error_ret;
1168 iostruct = aip->iostruct;
1169 readfunc = aip->readfunc;
1170 writefunc = aip->writefunc;
1171 tbufsize = aip->bufsize;
1172 buf = aip->buf;
1173 fname = aip->fname;
1174 aop = aip->aop;
1175 aeop = aip->aeop;
1176 aeosp = aip->aeosp;
1177 fix_non_print = aip->fix_non_print;
1178 spec_version = aip->spec_version;
1179
1180 MemFill(aip, '\0', sizeof(AsnIo)); /* clear it */
1181 MemFill(buf, '\0', (size_t)tbufsize);
1182
1183 aip->fp = fp; /* replace saved things */
1184 aip->tabsize = tabsize;
1185 aip->linelength = linelength;
1186 aip->type = type;
1187 aip->max_type = max_type;
1188 aip->max_indent = max_indent;
1189 aip->buf = buf;
1190 aip->linebuf = (CharPtr)aip->buf;
1191 aip->first = first;
1192 aip->typestack = typestack;
1193 aip->error_ret = error_ret;
1194 aip->iostruct = iostruct;
1195 aip->readfunc = readfunc;
1196 aip->writefunc = writefunc;
1197 aip->bufsize = tbufsize;
1198 aip->fname = fname;
1199 aip->aop = aop;
1200 aip->aeop = aeop;
1201 aip->aeosp = aeosp;
1202 aip->fix_non_print = fix_non_print;
1203 aip->spec_version = spec_version;
1204 /* clear stacks and buffers */
1205 MemFill(aip->typestack, '\0', (size_t)(sizeof(Pstack) * aip->max_type));
1206 MemFill(aip->first, '\0', (size_t)(sizeof(Boolean) * aip->max_indent));
1207 aip->first[0] = TRUE;
1208
1209 if (aip->type & ASNIO_OUT)
1210 aip->bytes = aip->bufsize; /* space to write */
1211
1212 return;
1213 }
1214
1215 /*****************************************************************************
1216 *
1217 * void AsnIoFlush(aip)
1218 *
1219 *****************************************************************************/
1220 NLM_EXTERN void LIBCALL AsnIoFlush (AsnIoPtr aip)
1221 {
1222 if (! (aip->type & ASNIO_OUT))
1223 return;
1224
1225 if (aip->offset)
1226 AsnIoWriteBlock(aip);
1227 if (aip->type & ASNIO_FILE) /* not a socket, clear buffers */
1228 fflush(aip->fp);
1229 return;
1230 }
1231
1232 /*****************************************************************************
1233 *
1234 * AsnIoMemOpen(mode, buf, size)
1235 *
1236 *****************************************************************************/
1237
1238 NLM_EXTERN AsnIoMemPtr LIBCALL AsnIoMemOpen (CharPtr mode, BytePtr buf, Int4 size) /* size of buffer, or bytes_to_read */
1239 {
1240 Int1 type;
1241 AsnIoMemPtr aimp;
1242
1243 if (! StringCmp(mode, "r"))
1244 type = (ASNIO_IN | ASNIO_TEXT);
1245 else if (! StringCmp(mode, "rb"))
1246 type = (ASNIO_IN | ASNIO_BIN);
1247 else if (! StringCmp(mode, "w"))
1248 type = (ASNIO_OUT | ASNIO_TEXT);
1249 else if (! StringCmp(mode, "wb"))
1250 type = (ASNIO_OUT | ASNIO_BIN);
1251 else if (! StringCmp(mode, "wx"))
1252 {
1253 type = (ASNIO_OUT | ASNIO_TEXT);
1254 type |= ASNIO_XML;
1255 }
1256 else
1257 {
1258 AsnIoErrorMsg(NULL, 81, mode);
1259 return NULL;
1260 }
1261
1262 aimp =(AsnIoMemPtr) MemNew(sizeof(AsnIoMem));
1263 aimp->size = size;
1264 aimp->buf = buf;
1265 aimp->aip = AsnIoNew(type, NULL, (Pointer)aimp, AsnIoMemRead, AsnIoMemWrite);
1266 return aimp;
1267 }
1268
1269 /*****************************************************************************
1270 *
1271 * AsnIoMemClose(aimp)
1272 *
1273 *****************************************************************************/
1274 NLM_EXTERN AsnIoMemPtr LIBCALL AsnIoMemClose (AsnIoMemPtr aimp)
1275 {
1276 if (aimp == NULL)
1277 return NULL;
1278 AsnIoClose(aimp->aip);
1279 return (AsnIoMemPtr) MemFree(aimp);
1280 }
1281
1282 /*****************************************************************************
1283 *
1284 * AsnIoMemWrite(ptr, buf, count)
1285 *
1286 *****************************************************************************/
1287 NLM_EXTERN Int2 LIBCALL AsnIoMemWrite (Pointer ptr, CharPtr buf, Uint2 count)
1288 {
1289 Int4 bytes;
1290 AsnIoMemPtr aimp;
1291
1292 aimp = (AsnIoMemPtr)ptr;
1293 bytes = MIN((Int4)count, ((aimp->size) - (aimp->count)));
1294 if (! bytes)
1295 return (Int2)(-1);
1296 MemCopy((aimp->buf + aimp->count), buf, (size_t)bytes);
1297 aimp->count += bytes;
1298 return (Int2) bytes;
1299 }
1300
1301 /*****************************************************************************
1302 *
1303 * AsnIoMemRead(ptr, buf, count)
1304 *
1305 *****************************************************************************/
1306 NLM_EXTERN Int2 LIBCALL AsnIoMemRead (Pointer ptr, CharPtr buf, Uint2 count)
1307 {
1308 Int4 bytes;
1309 AsnIoMemPtr aimp;
1310
1311 aimp = (AsnIoMemPtr)ptr;
1312 bytes = MIN((Int4)count, ((aimp->size) - (aimp->count)));
1313 MemCopy(buf, (aimp->buf + aimp->count), (size_t) bytes);
1314 aimp->count += bytes;
1315 return (Int2) bytes;
1316 }
1317
1318 /*****************************************************************************
1319 *
1320 * AsnIoMemReset(aimp, bytes_to_read)
1321 *
1322 *****************************************************************************/
1323 NLM_EXTERN Boolean LIBCALL AsnIoMemReset (AsnIoMemPtr aimp, Int4 bytes_to_read)
1324 {
1325 AsnIoReset(aimp->aip);
1326 aimp->count = 0;
1327 if (aimp->aip->type & ASNIO_IN)
1328 aimp->size = bytes_to_read;
1329 return TRUE;
1330 }
1331
1332 /*****************************************************************************
1333 *
1334 * AsnIoBSOpen(mode, buf, size)
1335 *
1336 *****************************************************************************/
1337 NLM_EXTERN AsnIoBSPtr LIBCALL AsnIoBSOpen (CharPtr mode, ByteStorePtr bsp)
1338 {
1339 Int1 type;
1340 AsnIoBSPtr aibp;
1341
1342 if ((mode == NULL) || (bsp == NULL))
1343 return NULL;
1344
1345 if (! StringCmp(mode, "r"))
1346 type = (ASNIO_IN | ASNIO_TEXT);
1347 else if (! StringCmp(mode, "rb"))
1348 type = (ASNIO_IN | ASNIO_BIN);
1349 else if (! StringCmp(mode, "w"))
1350 type = (ASNIO_OUT | ASNIO_TEXT);
1351 else if (! StringCmp(mode, "wb"))
1352 type = (ASNIO_OUT | ASNIO_BIN);
1353 else if (! StringCmp(mode, "wx"))
1354 {
1355 type = (ASNIO_OUT | ASNIO_TEXT);
1356 type |= ASNIO_XML;
1357 }
1358 else
1359 {
1360 AsnIoErrorMsg(NULL, 81, mode);
1361 return NULL;
1362 }
1363
1364 aibp = (AsnIoBSPtr) MemNew(sizeof(AsnIoBS));
1365 aibp->bsp = bsp;
1366 BSSeek(bsp, 0, SEEK_SET);
1367 aibp->aip = AsnIoNew(type, NULL, (Pointer)aibp, AsnIoBSRead, AsnIoBSWrite);
1368 if (type & ASNIO_OUT)
1369 AsnIoSetBufsize(aibp->aip, 10000); /* big internal buffer for */
1370 /* big ByteStore blocks */
1371 return aibp;
1372 }
1373
1374 /*****************************************************************************
1375 *
1376 * AsnIoBSClose(aibp)
1377 *
1378 *****************************************************************************/
1379 NLM_EXTERN AsnIoBSPtr LIBCALL AsnIoBSClose (AsnIoBSPtr aibp)
1380 {
1381 if (aibp == NULL)
1382 return NULL;
1383 AsnIoClose(aibp->aip);
1384 return (AsnIoBSPtr) MemFree(aibp);
1385 }
1386
1387 /*****************************************************************************
1388 *
1389 * AsnIoBSWrite(ptr, buf, count)
1390 *
1391 *****************************************************************************/
1392 NLM_EXTERN Int2 LIBCALL AsnIoBSWrite (Pointer ptr, CharPtr buf, Uint2 count)
1393 {
1394 Int4 bytes;
1395 AsnIoBSPtr aibp;
1396
1397 aibp = (AsnIoBSPtr)ptr;
1398 bytes = BSWrite(aibp->bsp, (Pointer) buf, (Int4) count);
1399 return (Int2) bytes;
1400 }
1401
1402 /*****************************************************************************
1403 *
1404 * AsnIoBSRead(ptr, buf, count)
1405 *
1406 *****************************************************************************/
1407 NLM_EXTERN Int2 LIBCALL AsnIoBSRead (Pointer ptr, CharPtr buf, Uint2 count)
1408 {
1409 Int4 bytes;
1410 AsnIoBSPtr aibp;
1411
1412 aibp = (AsnIoBSPtr)ptr;
1413 bytes = BSRead(aibp->bsp, (Pointer) buf, (Int4) count);
1414 return (Int2) bytes;
1415 }
1416
1417 /*****************************************************************************
1418 *
1419 * AsnIoCopy(from, fromfunc, tofunc)
1420 * Uses the object loader functions to write "from" to a temporary
1421 * file then read a new object and return a pointer to it
1422 *
1423 *****************************************************************************/
1424 NLM_EXTERN Pointer LIBCALL AsnIoCopy (Pointer from, AsnReadFunc readfunc, AsnWriteFunc writefunc)
1425 {
1426 Pointer res;
1427 AsnIoPtr aip;
1428 CharPtr fname;
1429
1430 if ((from == NULL) || (readfunc == NULL) || (writefunc == NULL))
1431 return NULL;
1432
1433 fname = TmpNam(NULL);
1434 aip = AsnIoOpen(fname, "wb");
1435 if (aip == NULL)
1436 return NULL;
1437
1438 if (! (*writefunc)(from, aip, NULL))
1439 {
1440 AsnIoClose(aip);
1441 return NULL;
1442 }
1443
1444 AsnIoClose(aip);
1445
1446 aip = AsnIoOpen(fname, "rb");
1447 res = (*readfunc)(aip, NULL);
1448
1449 AsnIoClose(aip);
1450 FileRemove(fname);
1451
1452 return res;
1453 }
1454
1455 /*****************************************************************************
1456 *
1457 * AsnIoMemCopy(from, fromfunc, tofunc)
1458 * Uses the object loader functions to write "from" to a ByteStore
1459 * then read a new object and return a pointer to it
1460 *
1461 *****************************************************************************/
1462 NLM_EXTERN Pointer LIBCALL AsnIoMemCopy (Pointer from, AsnReadFunc readfunc, AsnWriteFunc writefunc)
1463 {
1464 Pointer res;
1465 AsnIoBSPtr aibp;
1466 ByteStorePtr bsp;
1467
1468 if ((from == NULL) || (readfunc == NULL) || (writefunc == NULL))
1469 return NULL;
1470
1471 bsp = BSNew(5000);
1472 aibp = AsnIoBSOpen("wb", bsp);
1473 if (aibp == NULL)
1474 return NULL;
1475
1476 if (! (*writefunc)(from, aibp->aip, NULL))
1477 {
1478 AsnIoBSClose(aibp);
1479 BSFree(bsp);
1480 return NULL;
1481 }
1482
1483 AsnIoBSClose(aibp);
1484
1485 aibp = AsnIoBSOpen("rb", bsp);
1486 res = (*readfunc)(aibp->aip, NULL);
1487
1488 AsnIoBSClose(aibp);
1489 BSFree(bsp);
1490
1491 return res;
1492 }
1493
1494 static Int2 LIBCALLBACK AsnIoCompWrite PROTO((Pointer, CharPtr, Uint2));
1495
1496 /*****************************************************************************
1497 *
1498 * AsnIoMemComp(a, b, writefunc)
1499 * Uses the object loader functions to write "a" to a ByteStore
1500 * then does a byte by byte compare with the AsnIo stream from "b"
1501 * Returns TRUE if identical.
1502 *
1503 *****************************************************************************/
1504 NLM_EXTERN Boolean LIBCALL AsnIoMemComp (Pointer a, Pointer b, AsnWriteFunc writefunc)
1505 {
1506 AsnIoBSPtr aibp;
1507 ByteStorePtr bsp;
1508 Boolean retval = FALSE;
1509 ErrOpts opts;
1510
1511 if ((a == NULL) || (b == NULL) || (writefunc == NULL))
1512 return retval;
1513
1514 bsp = BSNew(5000);
1515 aibp = AsnIoBSOpen("wb", bsp);
1516 if (aibp == NULL)
1517 return retval;
1518
1519 retval = (*writefunc)(a, aibp->aip, NULL);
1520
1521 AsnIoBSClose(aibp);
1522
1523 if (! retval)
1524 {
1525 BSFree(bsp);
1526 return FALSE;
1527 }
1528
1529 aibp = (AsnIoBSPtr) MemNew(sizeof(AsnIoBS));
1530 aibp->bsp = bsp;
1531 BSSeek(bsp, 0, SEEK_SET);
1532 aibp->aip = AsnIoNew((Int1)(ASNIO_OUT | ASNIO_BIN), NULL, (Pointer)aibp, NULL, AsnIoCompWrite);
1533
1534 ErrSaveOptions(&opts); /* save state */
1535 ErrSetOpts(ERR_IGNORE, 0); /* set to ignore an error */
1536
1537 retval = (*writefunc)(b, aibp->aip, NULL);
1538
1539 AsnIoFlush(aibp->aip);
1540 if (aibp->aip->io_failure == TRUE)
1541 retval = FALSE;
1542
1543 AsnIoBSClose(aibp);
1544 BSFree(bsp);
1545
1546 ErrRestoreOptions(&opts); /* reset state */
1547
1548 return retval;
1549 }
1550
1551 /*****************************************************************************
1552 *
1553 * AsnIoCompWrite(ptr, buf, count)
1554 *
1555 *****************************************************************************/
1556 static Int2 LIBCALLBACK AsnIoCompWrite (Pointer ptr, CharPtr buf, Uint2 count)
1557 {
1558 Uint2 bytes;
1559 Int2 the_byte;
1560 AsnIoBSPtr aibp;
1561
1562 aibp = (AsnIoBSPtr)ptr;
1563 if (aibp->aip->io_failure)
1564 return (Int2) count;
1565
1566 for (bytes = 0; bytes < count; bytes++, buf++)
1567 {
1568 the_byte = BSGetByte(aibp->bsp);
1569 if ((the_byte == EOF) ||
1570 ((Uint1)(*buf) != (Uint1)the_byte))
1571 {
1572 aibp->aip->io_failure = TRUE;
1573 return (Int2) count;
1574 }
1575 }
1576 return (Int2) bytes;
1577 }
1578 /*****************************************************************************
1579 *
1580 * AsnIoHashWrite(ptr, buf, count)
1581 *
1582 *****************************************************************************/
1583 static Int2 LIBCALL AsnIoHashWrite (Pointer ptr, CharPtr buf, Uint2 count)
1584 {
1585 Uint4Ptr hashPt = (Uint4Ptr) ptr;
1586 Uint4 hash = * hashPt;
1587 Uint2 i;
1588
1589 for (i=0; i < count; i ++){
1590 hash *= (Uint4) 1103515245;
1591 hash += (Uint4) (buf[i]) + (Uint4) 12345;
1592 }
1593 *hashPt = hash;
1594
1595 return (Int2) count;
1596 }
1597 /*****************************************************************************
1598 *
1599 * AsnIoHash(from, tofunc)
1600 * Uses the object loader functions to calculate a hash value
1601 *
1602 *****************************************************************************/
1603 NLM_EXTERN Uint4 LIBCALL AsnIoHash (Pointer from, AsnWriteFunc writefunc)
1604 {
1605 Uint4 retval = 0;
1606 AsnIoPtr aip;
1607
1608 if ((from == NULL) || (writefunc == NULL))
1609 return retval;
1610
1611
1612 aip = AsnIoNew(ASNIO_OUT | ASNIO_BIN, NULL, (Pointer)&retval,
1613 NULL, AsnIoHashWrite);
1614
1615 if (! (*writefunc)(from, aip, NULL))
1616 AsnIoFlush(aip);
1617
1618 AsnIoClose(aip);
1619 return retval;
1620 }
1621 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |