A damn mess, but now things work, I think.
[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.4  1995-02-07 17:53:00  quinn
8  * A damn mess, but now things work, I think.
9  *
10  * Revision 1.3  1995/02/07  14:13:46  quinn
11  * Bug fixes.
12  *
13  * Revision 1.2  1995/02/06  16:45:03  quinn
14  * Small mods.
15  *
16  * Revision 1.1  1995/02/02  16:21:54  quinn
17  * First kick.
18  *
19  */
20
21 #include <odr.h>
22
23 int odr_sequence_begin(ODR o, void *p, int size)
24 {
25     char **pp = (char**) p;
26
27     if (o->t_class < 0)
28     {
29         o->t_class = ODR_UNIVERSAL;
30         o->t_tag = ODR_SEQUENCE;
31     }
32
33     if (odr_constructed_begin(o, p, o->t_class, o->t_tag))
34     {
35         if (o->direction == ODR_DECODE && size)
36             *pp = nalloc(o, size);
37         return 1;
38     }
39     else
40         return 0;
41 }
42
43 int odr_sequence_end(ODR o)
44 {
45     return odr_constructed_end(o);    
46 }
47
48 int odr_sequence_more(ODR o)
49 {
50     if (o->stackp < 0)
51         return 0;
52     if (o->stack[o->stackp].len >= 0)
53         return o->bp - o->stack[o->stackp].base < o->stack[o->stackp].len;
54     else
55         return (!(*o->bp == 0 && *(o->bp + 1) == 0));
56 }
57
58 int odr_sequence_of(ODR o, Odr_fun type, void *p, int *num)
59 {
60     char ***pp = (char***) p;  /* for dereferencing */
61     char **tmp;
62     char *dummy;
63     int size = 0, i;
64
65     if (!odr_sequence_begin(o, &dummy, 0))
66         return 0;
67
68     switch (o->direction)
69     {
70         case ODR_DECODE:
71             *num = 0;
72             while (odr_sequence_more(o))
73             {
74                 /* outgrown array? */
75                 if (*num * sizeof(void*) >= size)
76                 {
77                     /* double the buffer size */
78                     tmp = nalloc(o, sizeof(void*) * (size += size ? size :
79                         128));
80                     if (*num)
81                     {
82                         memcpy(tmp, *pp, *num * sizeof(void*));
83                         /*
84                          * For now, we just throw the old *p away, since we use
85                          * nibble memory anyway (disgusting, isn't it?).
86                          */
87                     }
88                     *pp = tmp;
89                 }
90                 if (!(*type)(o, (*pp) + *num, 0))
91                     return 0;
92                 (*num)++;
93             }
94             break;
95         case ODR_ENCODE:
96             for (i = 0; i < *num; i++)
97                 if (!(*type)(o, *pp + i, 0))
98                     return 0;
99             break;
100         case ODR_PRINT: return 1;
101         default: return 0;
102     }
103     return odr_sequence_end(o);
104 }