Expanded tabs in all source files. Added vim/emacs local variables
[yaz-moved-to-github.git] / src / odr_seq.c
1 /*
2  * Copyright (C) 1995-2005, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: odr_seq.c,v 1.4 2005-06-25 15:46:04 adam Exp $
6  */
7 /**
8  * \file odr_seq.c
9  * \brief Implements ODR SEQUENCE codec
10  */
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14
15 #include "odr-priv.h"
16
17 int odr_sequence_begin(ODR o, void *p, int size, const char *name)
18 {
19     char **pp = (char**) p;
20
21     if (o->error)
22         return 0;
23     if (o->t_class < 0)
24     {
25         o->t_class = ODR_UNIVERSAL;
26         o->t_tag = ODR_SEQUENCE;
27     }
28     if (o->direction == ODR_DECODE)
29         *pp = 0;
30     if (odr_constructed_begin(o, p, o->t_class, o->t_tag, name))
31     {
32         if (o->direction == ODR_DECODE && size)
33             *pp = (char *)odr_malloc(o, size);
34         return 1;
35     }
36     else
37         return 0;
38 }
39
40 int odr_set_begin(ODR o, void *p, int size, const char *name)
41 {
42     char **pp = (char**) p;
43
44     if (o->error)
45         return 0;
46     if (o->t_class < 0)
47     {
48         o->t_class = ODR_UNIVERSAL;
49         o->t_tag = ODR_SET;
50     }
51     if (o->direction == ODR_DECODE)
52         *pp = 0;
53     if (odr_constructed_begin(o, p, o->t_class, o->t_tag, name))
54     {
55         if (o->direction == ODR_DECODE && size)
56             *pp = (char *)odr_malloc(o, size);
57         return 1;
58     }
59     else
60         return 0;
61 }
62
63 int odr_sequence_end(ODR o)
64 {
65     return odr_constructed_end(o);    
66 }
67
68 int odr_set_end(ODR o)
69 {
70     return odr_constructed_end(o);    
71 }
72
73 static int odr_sequence_more(ODR o)
74 {
75     return odr_constructed_more(o);
76 }
77
78 static int odr_sequence_x (ODR o, Odr_fun type, void *p, int *num)
79 {
80     char ***pp = (char***) p;  /* for dereferencing */
81     char **tmp = 0;
82     int size = 0, i;
83
84     switch (o->direction)
85     {
86         case ODR_DECODE:
87             *num = 0;
88             *pp = (char **)odr_nullval();
89             while (odr_sequence_more(o))
90             {
91                 /* outgrown array? */
92                 if (*num * (int) sizeof(void*) >= size)
93                 {
94                     /* double the buffer size */
95                     tmp = (char **)odr_malloc(o, sizeof(void*) *
96                                               (size += size ? size : 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, 0))
108                     return 0;
109                 (*num)++;
110             }
111             break;
112         case ODR_ENCODE: case ODR_PRINT:
113 #ifdef ODR_DEBUG
114             fprintf(stderr, "[seqof: num=%d]", *num);
115 #endif
116             for (i = 0; i < *num; i++)
117             {
118 #ifdef ODR_DEBUG
119                 fprintf(stderr, "[seqof: elem #%d]", i);
120 #endif
121                 if (!(*type)(o, *pp + i, 0, 0))
122                     return 0;
123             }
124             break;
125         default:
126             odr_seterror(o, OOTHER, 47);
127             return 0;
128     }
129     return odr_sequence_end(o);
130 }
131
132 int odr_set_of(ODR o, Odr_fun type, void *p, int *num, const char *name)
133 {
134     if (!odr_set_begin(o, p, 0, name)) {
135         if (o->direction == ODR_DECODE)
136             *num = 0;
137         return 0;
138     }
139     return odr_sequence_x (o, type, p, num);
140 }
141
142 int odr_sequence_of(ODR o, Odr_fun type, void *p, int *num,
143                     const char *name)
144 {
145     if (!odr_sequence_begin(o, p, 0, name)) {
146         if (o->direction == ODR_DECODE)
147             *num = 0;
148         return 0;
149     }
150     return odr_sequence_x (o, type, p, num);
151 }
152
153 /*
154  * Local variables:
155  * c-basic-offset: 4
156  * indent-tabs-mode: nil
157  * End:
158  * vim: shiftwidth=4 tabstop=8 expandtab
159  */
160