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