NCBI C Toolkit Cross Reference

C/asnlib/asnio.c


  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 

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.