2 * Copyright (c) 1995-2004, Index Data
3 * See the file LICENSE for details.
5 * $Id: odr.c,v 1.10 2004-12-13 14:21:55 heikki Exp $
11 * \brief Implements fundamental ODR functionality
22 #include <yaz/xmalloc.h>
26 static int log_level=0;
27 static int log_level_initialized=0;
29 Odr_null *ODR_NULLVAL = (Odr_null *) "NULL"; /* the presence of a null value */
31 Odr_null *odr_nullval (void)
39 "Memory allocation failed",
42 "Required data element missing",
48 "Length of constructed type different from sum of members",
49 "Overflow writing definite length of constructed type",
53 char *odr_errmsg(int n)
55 return odr_errlist[n];
58 void odr_perror(ODR o, const char *message)
60 const char *e = odr_getelement(o);
63 err = odr_geterrorx(o, &x);
64 fprintf(stderr, "%s: %s (code %d:%d)", message, odr_errlist[err], err, x);
66 fprintf (stderr, " element %s", e);
67 fprintf(stderr, "\n");
70 int odr_geterror(ODR o)
75 int odr_geterrorx(ODR o, int *x)
82 const char *odr_getelement(ODR o)
84 return o->op->element;
87 const char **odr_get_element_path(ODR o)
89 return o->op->stack_names;
92 void odr_seterror(ODR o, int error, int id)
96 o->op->element[0] = '\0';
99 void odr_setelement(ODR o, const char *element)
103 strncpy(o->op->element, element, sizeof(o->op->element)-1);
104 o->op->element[sizeof(o->op->element)-1] = '\0';
108 void odr_FILE_write(ODR o, void *handle, int type,
109 const char *buf, int len)
113 if (type == ODR_OCTETSTRING)
115 const char **stack_names = odr_get_element_path(o);
116 for (i = 0; stack_names[i]; i++)
117 fprintf((FILE*) handle, "[%s]", stack_names[i]);
118 fputs("\n", (FILE*) handle);
121 for (i = 0; i<len; i++)
123 unsigned c = ((const unsigned char *) buf)[i];
124 if (i == 2000 && len > 3100)
126 fputs(" ..... ", (FILE*) handle);
129 if (strchr("\r\n\f\t", c) || (c >= ' ' && c <= 126))
130 putc(c, (FILE*) handle);
134 sprintf(x, "\\X%02X", c);
135 fputs(x, (FILE*) handle);
140 void odr_FILE_close(void *handle)
142 FILE *f = (FILE *) handle;
143 if (f && f != stderr && f != stdout)
147 void odr_setprint(ODR o, FILE *file)
149 odr_set_stream(o, file, odr_FILE_write, odr_FILE_close);
152 void odr_set_stream(ODR o, void *handle,
153 void (*stream_write)(ODR o,
154 void *handle, int type,
155 const char *buf, int len),
156 void (*stream_close)(void *handle))
158 o->print = (FILE*) handle;
159 o->op->stream_write = stream_write;
160 o->op->stream_close = stream_close;
163 int odr_set_charset(ODR o, const char *to, const char *from)
165 if (o->op->iconv_handle)
166 yaz_iconv_close (o->op->iconv_handle);
167 o->op->iconv_handle = 0;
170 o->op->iconv_handle = yaz_iconv_open (to, from);
171 if (o->op->iconv_handle == 0)
178 ODR odr_createmem(int direction)
181 if (!log_level_initialized)
183 log_level=yaz_log_module_level("odr");
184 log_level_initialized=1;
187 if (!(o = (ODR)xmalloc(sizeof(*o))))
189 o->direction = direction;
191 o->size = o->pos = o->top = 0;
193 o->mem = nmem_create();
195 o->op = (struct Odr_private *) xmalloc (sizeof(*o->op));
196 o->op->odr_ber_tag.lclass = -1;
197 o->op->iconv_handle = 0;
198 odr_setprint(o, stderr);
200 yaz_log (log_level, "odr_createmem dir=%d o=%p", direction, o);
204 void odr_reset(ODR o)
206 if (!log_level_initialized)
208 log_level=yaz_log_module_level("odr");
209 log_level_initialized=1;
212 odr_seterror(o, ONONE, 0);
214 odr_seek(o, ODR_S_SET, 0);
223 if (o->op->iconv_handle != 0)
224 yaz_iconv(o->op->iconv_handle, 0, 0, 0, 0);
225 yaz_log (log_level, "odr_reset o=%p", o);
228 void odr_destroy(ODR o)
230 nmem_destroy(o->mem);
231 if (o->buf && o->can_grow)
233 if (o->op->stream_close)
234 o->op->stream_close(o->print);
235 if (o->op->iconv_handle != 0)
236 yaz_iconv_close (o->op->iconv_handle);
239 yaz_log (log_level, "odr_destroy o=%p", o);
242 void odr_setbuf(ODR o, char *buf, int len, int can_grow)
244 odr_seterror(o, ONONE, 0);
245 o->bp = (unsigned char *) buf;
247 o->buf = (unsigned char *) buf;
248 o->can_grow = can_grow;
253 char *odr_getbuf(ODR o, int *len, int *size)
258 return (char*) o->buf;
261 void odr_printf(ODR o, const char *fmt, ...)
268 _vsnprintf(buf, sizeof(buf)-1, fmt, ap);
271 vsnprintf(buf, sizeof(buf), fmt, ap);
273 vsprintf(buf, fmt, ap);
276 o->op->stream_write(o, o->print, ODR_VISIBLESTRING, buf, strlen(buf));