2 * Copyright (C) 1995-2005, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: odr.c,v 1.13 2005-08-11 14:21:55 adam Exp $
11 * \brief Implements fundamental ODR functionality
23 #include <yaz/xmalloc.h>
27 static int log_level=0;
28 static int log_level_initialized=0;
30 Odr_null *ODR_NULLVAL = (Odr_null *) "NULL"; /* the presence of a null value */
32 Odr_null *odr_nullval (void)
40 "Memory allocation failed",
43 "Required data element missing",
49 "Length of constructed type different from sum of members",
50 "Overflow writing definite length of constructed type",
54 char *odr_errmsg(int n)
56 return odr_errlist[n];
59 void odr_perror(ODR o, const char *message)
61 const char *e = odr_getelement(o);
62 const char **element_path = odr_get_element_path(o);
65 err = odr_geterrorx(o, &x);
66 fprintf(stderr, "%s: %s (code %d:%d)", message, odr_errlist[err], err, x);
68 fprintf(stderr, " element %s", e);
70 fprintf(stderr, "\n");
73 fprintf(stderr, "Element path:");
75 fprintf(stderr, " %s", *element_path++);
76 fprintf(stderr, "\n");
80 int odr_geterror(ODR o)
85 int odr_geterrorx(ODR o, int *x)
92 const char *odr_getelement(ODR o)
94 return o->op->element;
97 const char **odr_get_element_path(ODR o)
100 struct odr_constack *st;
102 for (st = o->op->stack_top; st; st = st->prev)
104 if (o->op->tmp_names_sz < cur_sz + 1)
106 o->op->tmp_names_sz = 2 * cur_sz + 5;
107 o->op->tmp_names_buf = (const char **)
108 odr_malloc(o, o->op->tmp_names_sz * sizeof(char*));
110 o->op->tmp_names_buf[cur_sz] = 0;
111 for (st = o->op->stack_top; st; st = st->prev)
114 o->op->tmp_names_buf[cur_sz] = st->name;
117 return o->op->tmp_names_buf;
120 void odr_seterror(ODR o, int error, int id)
123 o->op->error_id = id;
124 o->op->element[0] = '\0';
127 void odr_setelement(ODR o, const char *element)
131 strncpy(o->op->element, element, sizeof(o->op->element)-1);
132 o->op->element[sizeof(o->op->element)-1] = '\0';
136 void odr_FILE_write(ODR o, void *handle, int type,
137 const char *buf, int len)
141 if (type == ODR_OCTETSTRING)
143 const char **stack_names = odr_get_element_path(o);
144 for (i = 0; stack_names[i]; i++)
145 fprintf((FILE*) handle, "[%s]", stack_names[i]);
146 fputs("\n", (FILE*) handle);
149 for (i = 0; i<len; i++)
151 unsigned c = ((const unsigned char *) buf)[i];
152 if (i == 2000 && len > 3100)
154 fputs(" ..... ", (FILE*) handle);
157 if (strchr("\r\n\f\t", c) || (c >= ' ' && c <= 126))
158 putc(c, (FILE*) handle);
162 sprintf(x, "\\X%02X", c);
163 fputs(x, (FILE*) handle);
168 void odr_FILE_close(void *handle)
170 FILE *f = (FILE *) handle;
171 if (f && f != stderr && f != stdout)
175 void odr_setprint(ODR o, FILE *file)
177 odr_set_stream(o, file, odr_FILE_write, odr_FILE_close);
180 void odr_set_stream(ODR o, void *handle,
181 void (*stream_write)(ODR o,
182 void *handle, int type,
183 const char *buf, int len),
184 void (*stream_close)(void *handle))
186 o->print = (FILE*) handle;
187 o->op->stream_write = stream_write;
188 o->op->stream_close = stream_close;
191 int odr_set_charset(ODR o, const char *to, const char *from)
193 if (o->op->iconv_handle)
194 yaz_iconv_close (o->op->iconv_handle);
195 o->op->iconv_handle = 0;
198 o->op->iconv_handle = yaz_iconv_open (to, from);
199 if (o->op->iconv_handle == 0)
206 ODR odr_createmem(int direction)
209 if (!log_level_initialized)
211 log_level=yaz_log_module_level("odr");
212 log_level_initialized=1;
215 if (!(o = (ODR)xmalloc(sizeof(*o))))
217 o->direction = direction;
219 o->size = o->pos = o->top = 0;
221 o->mem = nmem_create();
223 o->op = (struct Odr_private *) xmalloc (sizeof(*o->op));
224 o->op->odr_ber_tag.lclass = -1;
225 o->op->iconv_handle = 0;
226 odr_setprint(o, stderr);
228 yaz_log (log_level, "odr_createmem dir=%d o=%p", direction, o);
232 void odr_reset(ODR o)
234 if (!log_level_initialized)
236 log_level=yaz_log_module_level("odr");
237 log_level_initialized=1;
240 odr_seterror(o, ONONE, 0);
242 odr_seek(o, ODR_S_SET, 0);
247 o->op->stack_first = 0;
248 o->op->stack_top = 0;
249 o->op->tmp_names_sz = 0;
250 o->op->tmp_names_buf = 0;
254 if (o->op->iconv_handle != 0)
255 yaz_iconv(o->op->iconv_handle, 0, 0, 0, 0);
256 yaz_log (log_level, "odr_reset o=%p", o);
259 void odr_destroy(ODR o)
261 nmem_destroy(o->mem);
262 if (o->buf && o->can_grow)
264 if (o->op->stream_close)
265 o->op->stream_close(o->print);
266 if (o->op->iconv_handle != 0)
267 yaz_iconv_close (o->op->iconv_handle);
270 yaz_log (log_level, "odr_destroy o=%p", o);
273 void odr_setbuf(ODR o, char *buf, int len, int can_grow)
275 odr_seterror(o, ONONE, 0);
276 o->bp = (unsigned char *) buf;
278 o->buf = (unsigned char *) buf;
279 o->can_grow = can_grow;
284 char *odr_getbuf(ODR o, int *len, int *size)
289 return (char*) o->buf;
292 void odr_printf(ODR o, const char *fmt, ...)
299 _vsnprintf(buf, sizeof(buf)-1, fmt, ap);
302 vsnprintf(buf, sizeof(buf), fmt, ap);
304 vsprintf(buf, fmt, ap);
307 o->op->stream_write(o, o->print, ODR_VISIBLESTRING, buf, strlen(buf));
313 * indent-tabs-mode: nil
315 * vim: shiftwidth=4 tabstop=8 expandtab