NCBI C Toolkit Cross Reference

C/asnlib/asngen.c


  1 /*  asngen.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: asngen.c
 27 *
 28 * Author:  James Ostell
 29 *
 30 * Version Creation Date: 3/4/91
 31 *
 32 * $Revision: 6.3 $
 33 *
 34 * File Description:
 35 *   General application interface routines for ASNlib
 36 *      using these has the advantage that your routine will read binary
 37 *        and print value messages with no changes
 38 *      it has the disadvantage that you link both binary and text routines
 39 *        whether you use them or not
 40 *
 41 * Modifications:  
 42 * --------------------------------------------------------------------------
 43 * Date     Name        Description of modification
 44 * -------  ----------  -----------------------------------------------------
 45 * 3/4/91   Kans        Stricter typecasting for GNU C and C++
 46 * 04-20-93 Schuler     LIBCALL calling convention
 47 *
 48 * $Log: asngen.c,v $
 49 * Revision 6.3  2003/09/15 16:16:33  kans
 50 * added AsnWriteEx, AsnTxtWriteEx, and AsnPrintStream
 51 *
 52 * Revision 6.2  1997/10/29 02:40:40  vakatov
 53 * Type castings to pass through the C++ compiler
 54 *
 55 * Revision 6.1  1997/10/28 15:13:00  epstein
 56 *  add AsnFindNthPieceOfObject
 57 *
 58 * Revision 6.0  1997/08/25 18:09:55  madden
 59 * Revision changed to 6.0
 60 *
 61 * Revision 5.1  1996/12/03 21:43:48  vakatov
 62 * Adopted for 32-bit MS-Windows DLLs
 63 *
 64  * Revision 5.0  1996/05/28  14:00:29  ostell
 65  * Set to revision 5.0
 66  *
 67  * Revision 4.1  1996/01/03  22:59:49  ostell
 68  * added ExpOptCheck on AsnReadVal()
 69  *
 70  * Revision 4.0  1995/07/26  13:47:38  ostell
 71  * force revision to 4.0
 72  *
 73  * Revision 2.8  1995/05/15  18:38:28  ostell
 74  * added Log line
 75  *
 76 *
 77 * ==========================================================================
 78 */
 79 
 80 #include "asnbuild.h"
 81 
 82 /*****************************************************************************
 83 *
 84 *   AsnReadId()
 85 *       generalized read ident
 86 *
 87 *****************************************************************************/
 88 NLM_EXTERN AsnTypePtr LIBCALL  AsnReadId (AsnIoPtr aip, AsnModulePtr amp, AsnTypePtr atp)
 89 
 90 {
 91         if (aip->read_id)
 92                 AsnIoErrorMsg(aip, 104, aip->linenumber);
 93         aip->read_id = TRUE;
 94         
 95     if (aip->type & ASNIO_TEXT)
 96                 return AsnTxtReadId(aip, amp, atp);
 97     else if (aip->type & ASNIO_BIN)
 98                 return AsnBinReadId(aip, atp);
 99 
100         return NULL;
101 }
102 
103 /*****************************************************************************
104 *
105 *   AsnReadVal()
106 *       generalized readvalue
107 *
108 *****************************************************************************/
109 NLM_EXTERN Int2 LIBCALL AsnReadVal (AsnIoPtr aip, AsnTypePtr atp, DataValPtr vp)
110 
111 {
112         Int2 retval = -1;
113 
114         if (! aip->read_id)
115                 AsnIoErrorMsg(aip, 103, aip->linenumber);
116         aip->read_id = FALSE;
117         
118         if (aip->type & ASNIO_TEXT)
119                 retval = AsnTxtReadVal(aip, atp, vp);
120         else if (aip->type & ASNIO_BIN)
121                 retval = AsnBinReadVal(aip, atp, vp);
122 
123         if (aip->aeop != NULL)    /* exploring nodes */
124                 AsnCheckExpOpt(aip, atp, vp);
125 
126         return retval;
127 }
128 
129 /*****************************************************************************
130 *
131 *   AsnWrite()
132 *       generalized write value
133 *
134 *****************************************************************************/
135 NLM_EXTERN Boolean LIBCALL AsnWrite (AsnIoPtr aip, AsnTypePtr atp, DataValPtr dvp)
136 
137 {
138         Boolean retval = FALSE;
139         
140         if (aip->aeop != NULL)    /* exploring nodes */
141                 AsnCheckExpOpt(aip, atp, dvp);
142 
143         if (aip->type & ASNIO_TEXT)
144                 retval = AsnTxtWrite(aip, atp, dvp);
145         else if (aip->type & ASNIO_BIN)
146                 retval = AsnBinWrite(aip, atp, dvp);
147 
148         if (aip->io_failure)
149                 return FALSE;
150         return retval;
151 }
152 
153 /*****************************************************************************
154 *
155 *   AsnWriteEx()
156 *       specialized write value
157 *
158 *****************************************************************************/
159 NLM_EXTERN Boolean LIBCALL AsnWriteEx (AsnIoPtr aip, AsnTypePtr atp, DataValPtr dvp, AsnStreamStringFunc stream)
160 
161 {
162         Boolean retval = FALSE;
163 
164         if (aip->aeop != NULL)
165                 AsnCheckExpOpt(aip, atp, dvp);
166 
167         if (aip->type & ASNIO_TEXT)
168                 retval = AsnTxtWriteEx(aip, atp, dvp, stream);
169         else if (aip->type & ASNIO_BIN)
170                 return FALSE;
171 
172         if (aip->io_failure)
173                 return FALSE;
174         return retval;
175 }
176 
177 /*****************************************************************************
178 *
179 *   AsnSkipValue(aip, atp)
180 *       Assumes that a read id has just been done
181 *       Assumes all values to be encountered are linked to atp
182 *       will skip values until it returns to the former level
183 *       returns TRUE if no errors
184 *       ends with a ReadVal()
185 *
186 *****************************************************************************/
187 NLM_EXTERN Boolean LIBCALL AsnSkipValue (AsnIoPtr aip, AsnTypePtr atp)
188 
189 {
190         Int2 level;
191 
192         level = AsnGetLevel(aip);
193         if (! AsnReadVal(aip, atp, NULL))
194                 return FALSE;
195 
196         while (level < AsnGetLevel(aip))
197         {
198                 if ((atp = AsnReadId(aip, NULL, atp)) == NULL)
199                         return FALSE;
200                 if (! AsnReadVal(aip, atp, NULL))
201                         return FALSE;
202         }
203         return TRUE;
204 }
205 
206 /*****************************************************************************
207 *
208 *   AsnOpenStruct(aip, atp, ptr)
209 *      write atp as a START_STRUCT
210 *
211 *****************************************************************************/
212 NLM_EXTERN Boolean LIBCALL AsnOpenStruct (AsnIoPtr aip, AsnTypePtr atp, Pointer ptr)
213 
214 {
215         DataVal av;
216         Boolean retval;
217 
218         av.intvalue = START_STRUCT;
219         if(aip->aeosp != NULL)
220                 aip->aeosp->the_struct = ptr;
221         retval = AsnWrite(aip, atp, &av);
222         if(aip->aeosp != NULL)
223                 aip->aeosp->the_struct = NULL;
224         return retval;
225 }
226 
227 /*****************************************************************************
228 *
229 *   AsnCloseStruct(aip, atp, ptr)
230 *      writes an END_STRUCT for atp
231 *
232 *****************************************************************************/
233 NLM_EXTERN Boolean LIBCALL AsnCloseStruct (AsnIoPtr aip, AsnTypePtr atp, Pointer ptr)
234 
235 {
236         DataVal av;
237     Int2 i;
238         Boolean retval;
239 
240     i = aip->type_indent;
241     if (! i)
242         {
243         AsnIoErrorMsg(aip, 20 );
244                 return FALSE;
245         }
246 
247     i--;
248     while ((i) &&
249         (AsnFindBaseIsa(aip->typestack[i].type) == CHOICE_TYPE))
250         i--;
251     if (aip->typestack[i].type != atp)
252         {
253         AsnIoErrorMsg(aip, 21, AsnErrGetTypeName(atp->name),
254                         AsnErrGetTypeName(aip->typestack[i].type->name));
255                 return FALSE;
256         }
257 
258         av.intvalue = END_STRUCT;
259         if(aip->aeosp != NULL)
260                 aip->aeosp->the_struct = ptr;
261         retval = AsnWrite(aip, atp, &av);
262         if(aip->aeosp != NULL)
263                 aip->aeosp->the_struct = NULL;
264         return retval;
265 }
266 
267 /*****************************************************************************
268 *
269 *   AsnWriteChoice(aip, atp, the_choice, the_value)
270 *
271 *****************************************************************************/
272 NLM_EXTERN Boolean LIBCALL AsnWriteChoice (AsnIoPtr aip, AsnTypePtr atp, Int2 the_choice, DataValPtr the_value)
273 
274 {
275         Boolean retval;
276         DataVal av;
277 
278         if (the_value == NULL)
279         {
280                 av.ptrvalue = NULL;
281                 the_value = &av;
282         }
283         if(aip->aeosp != NULL)
284                 aip->aeosp->the_choice = the_choice;
285         retval = AsnWrite(aip, atp, the_value);
286         if(aip->aeosp != NULL)
287                 aip->aeosp->the_choice = NO_CHOICE_SET;
288         return retval;
289 }
290 
291 /*****************************************************************************
292 *
293 *   Int2 AsnGetLevel(aip)
294 *       returns current level in parse stack
295 *       to traverse a struct (SEQUENCE, SET, SET OF, SEQUENCE OF)
296 *       atp = AsnReadId(aip, ...)    id for struct
297 *       level = AsnGetLevel(aip);    record level
298 *       AsnReadVal(aip, ...)         read open bracket to indent a level
299 *       while (AsnGetLevel(aip) != level)
300 *       {
301 *           AsnReadId()
302 *           AsnReadVal()
303 *       }
304 *       At this point you have read the close bracket for the struct
305 *   
306 *****************************************************************************/
307 NLM_EXTERN Int2 LIBCALL AsnGetLevel (AsnIoPtr aip)
308 
309 {
310     return (Int2)aip->type_indent;
311 }
312 
313 /*****************************************************************************
314 *
315 *   AsnCheckExpOpt(aip, atp, dvp)
316 *       see if atp is a node we are looking for
317 *       call user callback if it is
318 *
319 *****************************************************************************/
320 NLM_EXTERN void LIBCALL AsnCheckExpOpt (AsnIoPtr aip, AsnTypePtr atp, DataValPtr dvp)
321 
322 {
323         AsnExpOptPtr aeop;
324         AsnTypePtr base;
325         Boolean got_one;
326         Int2 i, j, isa, isa_end_struct;
327 
328         aeop = aip->aeop;
329         base = AsnFindBaseType(atp);
330         while (aeop != NULL)
331         {
332                 got_one = FALSE;
333                 if (aeop->numtypes == 1)    /* checking one type */
334                 {
335                         if ((aeop->types[0] == atp) ||
336                                 (aeop->types[0] == base))
337                         {
338                                 got_one = TRUE;
339                         }
340                 }
341                 else if (aeop->numtypes == 0)   /* checking all types */
342                         got_one = TRUE;
343                 else
344                 {
345                         if (aeop->types[aeop->numtypes - 1] == atp)
346                         {
347                                 isa = base->type->isa;
348 
349                                 isa_end_struct = 0;
350                                 if ((isa == SEQ_TYPE) || (isa == SET_TYPE) ||
351                                          (isa == SEQOF_TYPE) || (isa == SETOF_TYPE))
352                                 {
353                                          if (dvp->intvalue != START_STRUCT)
354                                                 isa_end_struct = 1;
355                                 }
356 
357                                 if ((Int2)aip->type_indent >= (aeop->numtypes - 1 - isa_end_struct))
358                                 {
359                                         if (isa_end_struct)
360                                                 i = aip->type_indent - 2;
361                                         else
362                                                 i = aip->type_indent - 1;
363                                         j = aeop->numtypes - 2;
364                                         while ((j > 0) && (i > 0))
365                                         {
366                                                 if (aip->typestack[i].type == aeop->types[j])
367                                                 {
368                                                         j--; i--;
369                                                 }
370                                                 else
371                                                         break;
372                                         }
373                                         if (! j)    /* got through it all */
374                                         {
375                                                 if ((aip->typestack[i].type == aeop->types[0]) ||
376                                                         (AsnFindBaseType(aip->typestack[i].type) ==
377                                                                 aeop->types[0]))
378                                                                 got_one = TRUE;
379                                         }
380                                 }
381                         }
382                 }
383 
384                 if (got_one)   /* found it */
385                 {
386                         aip->aeosp->atp = atp;
387                         aip->aeosp->dvp = dvp;
388                         aip->aeosp->data = aeop->user_data;
389                         (* aeop->user_callback)(aip->aeosp);
390                 }
391                 aeop = aeop->next;
392         }
393         return;
394 }
395 
396 /*****************************************************************************
397 *
398 *   AsnExpOptNew(aip, path, ptr, func)
399 *
400 *****************************************************************************/
401 NLM_EXTERN AsnExpOptPtr LIBCALL AsnExpOptNew (AsnIoPtr aip, CharPtr path, Pointer ptr, AsnExpOptFunc func)   /* user supplied callback */
402 
403 {
404         AsnExpOptPtr curr, prev;
405         AsnTypePtr PNTR typeptr = NULL;
406         Int2 typecount = 0;
407 
408         if (path != NULL)     /* get type array */
409         {
410                 typeptr = AsnTypePathFind(NULL, path, &typecount);
411                 if (typeptr == NULL)    /* path not found */
412                         return NULL;
413         }
414         curr = (AsnExpOptPtr) MemNew(sizeof(AsnExpOpt));
415         curr->user_data = ptr;
416         curr->user_callback = func;
417         curr->types = typeptr;
418         curr->numtypes = typecount;
419         if (aip->aeop == NULL)   /* first one */
420         {
421                 aip->aeop = curr;
422                 aip->aeosp = (AsnExpOptStructPtr) MemNew(sizeof(AsnExpOptStruct));
423                 aip->aeosp->aip = aip;
424                 aip->aeosp->the_choice = NO_CHOICE_SET;
425         }
426         else
427         {
428                 prev = aip->aeop;
429                 while (prev->next != NULL)
430                         prev = prev->next;
431                 prev->next = curr;
432         }
433         return curr;
434 }
435 
436 /*****************************************************************************
437 *
438 *   AsnExpOptFree(aip, aeop)
439 *       if aeop == NULL, free them all
440 *
441 *****************************************************************************/
442 NLM_EXTERN AsnExpOptPtr LIBCALL AsnExpOptFree (AsnIoPtr aip, AsnExpOptPtr aeop)
443 
444 {
445         AsnExpOptPtr curr, next, prev;
446 
447         curr = aip->aeop;
448         prev = NULL;
449         while (curr != NULL)
450         {
451                 if ((aeop == NULL) || (aeop == curr))
452                 {
453                         next = curr->next;
454                         if (prev != NULL)
455                                 prev->next = next;
456                         else
457                                 aip->aeop = next;
458                         MemFree(curr->types);
459                         MemFree(curr);
460                         curr = next;
461                 }
462                 else
463                 {
464                         prev = curr;
465                         curr = curr->next;
466                 }
467         }
468         if (prev == NULL)    /* nothing left */
469                 aip->aeosp = (AsnExpOptStructPtr) MemFree(aip->aeosp);   /* free the AsnExpOptStruct */
470         return NULL;
471 }
472 
473 /*****************************************************************************
474 *
475 *   AsnNullValueMsg(aip, node)
476 *       posts an error message when a NULL value is passed to the object
477 *   loaders for node.
478 *
479 *****************************************************************************/
480 NLM_EXTERN void LIBCALL AsnNullValueMsg (AsnIoPtr aip, AsnTypePtr node)
481 
482 {
483         char * tmpbuf;
484         CharPtr str;
485 
486         tmpbuf = (char*) malloc(512);   /* temp. local buffer for mswindows */
487         str = StringMove(tmpbuf, "NULL value passed to object loader for ");
488         str = AsnTypeDumpStack(str, aip);
489         if (node != NULL)
490         {
491                 if (*(str - 1) == '>')    /* already read or written */
492                 {
493                         while (*str != '<')
494                                 str--;
495                 }
496                 else
497                 {               
498                         *str = '.';
499                         str++;
500                 }
501                 StringMove(str, node->name);
502         }
503         ErrPost(CTX_NCBIOBJ, 1, tmpbuf);
504         free(tmpbuf);
505         return;
506 }
507 
508 
509 
510 typedef struct {
511     Int4 count;
512     Pointer val;
513 } StructInfo;
514 
515 static void LIBCALLBACK GetNth(AsnExpOptStructPtr aeosp)
516 {
517         StructInfo *sp;
518 
519         if (aeosp->dvp->intvalue != START_STRUCT) return;
520         sp = (StructInfo *) aeosp->data;
521         if (sp->count-- == 1)
522             sp->val = (Pointer) aeosp->the_struct;
523 }
524 
525 /* Finds the Nth occurrence of any low-level ASN.1 object within a higher
526    level object for which an ASN.1 Write function exists.  The string
527    parameter must identify the low-level object for which the search is
528    being performed.
529 
530    Note that this function can be used to obtain pieces of an object in an
531    object-oriented "method", rather than using the native method of
532    traversing pointers to fetch the desired piece.  However, note that
533    this technique is very inefficient since the entire structure must be
534    traversed to obtain each component. */
535 NLM_EXTERN VoidPtr LIBCALL
536 AsnFindNthPieceOfObject(AsnWriteFunc wfunc, Pointer datum, CharPtr string, Int4 n)
537 {
538   AsnIoPtr aip;
539   StructInfo si;
540   AsnExpOptPtr aeop;
541 
542   aip = AsnIoNullOpen();
543   si.count = n;
544   si.val = NULL;
545   aeop = AsnExpOptNew(aip, string, (Pointer)&si, GetNth);
546   wfunc(datum, aip, NULL);
547   AsnIoClose(aip);
548   return si.val;
549 }
550 
551 

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.