Works better now.
[yaz-moved-to-github.git] / odr / odr_seq.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: odr_seq.c,v $
7  * Revision 1.5  1995-02-09 15:51:49  quinn
8  * Works better now.
9  *
10  * Revision 1.4  1995/02/07  17:53:00  quinn
11  * A damn mess, but now things work, I think.
12  *
13  * Revision 1.3  1995/02/07  14:13:46  quinn
14  * Bug fixes.
15  *
16  * Revision 1.2  1995/02/06  16:45:03  quinn
17  * Small mods.
18  *
19  * Revision 1.1  1995/02/02  16:21:54  quinn
20  * First kick.
21  *
22  */
23
24 #include <odr.h>
25 #include <assert.h>
26
27 int odr_sequence_begin(ODR o, void *p, int size)
28 {
29     char **pp = (char**) p;
30
31     if (o->t_class < 0)
32     {
33         o->t_class = ODR_UNIVERSAL;
34         o->t_tag = ODR_SEQUENCE;
35     }
36
37     if (o->direction == ODR_DECODE)
38         *pp = 0;
39     if (odr_constructed_begin(o, p, o->t_class, o->t_tag))
40     {
41         if (o->direction == ODR_DECODE && size)
42             *pp = nalloc(o, size);
43         if (o->direction == ODR_PRINT)
44         {
45             fprintf(o->print, "%s{\n", odr_indent(o));
46             o->indent++;
47         }
48         return 1;
49     }
50     else
51         return 0;
52 }
53
54 int odr_sequence_end(ODR o)
55 {
56     if (o->direction == ODR_PRINT)
57     {
58         assert(o->indent > 0);
59         o->indent--;
60         fprintf(o->print, "%s}\n", odr_indent(o));
61     }
62     return odr_constructed_end(o);    
63 }
64
65 int odr_sequence_more(ODR o)
66 {
67     if (o->stackp < 0)
68         return 0;
69     if (o->stack[o->stackp].len >= 0)
70         return o->bp - o->stack[o->stackp].base < o->stack[o->stackp].len;
71     else
72         return (!(*o->bp == 0 && *(o->bp + 1) == 0));
73 }
74
75 int odr_sequence_of(ODR o, Odr_fun type, void *p, int *num)
76 {
77     char ***pp = (char***) p;  /* for dereferencing */
78     char **tmp;
79     char *dummy = "Nothing";
80     int size = 0, i;
81
82     if (!odr_sequence_begin(o, &dummy, 0))
83         return 0;
84
85     switch (o->direction)
86     {
87         case ODR_DECODE:
88             *num = 0;
89             while (odr_sequence_more(o))
90             {
91                 /* outgrown array? */
92                 if (*num * sizeof(void*) >= size)
93                 {
94                     /* double the buffer size */
95                     tmp = nalloc(o, sizeof(void*) * (size += size ? size :
96                         128));
97                     if (*num)
98                     {
99                         memcpy(tmp, *pp, *num * sizeof(void*));
100                         /*
101                          * For now, we just throw the old *p away, since we use
102                          * nibble memory anyway (disgusting, isn't it?).
103                          */
104                     }
105                     *pp = tmp;
106                 }
107                 if (!(*type)(o, (*pp) + *num, 0))
108                     return 0;
109                 (*num)++;
110             }
111             break;
112         case ODR_ENCODE: case ODR_PRINT:
113             for (i = 0; i < *num; i++)
114                 if (!(*type)(o, *pp + i, 0))
115                     return 0;
116             break;
117         default: return 0;
118     }
119     return odr_sequence_end(o);
120 }