2 * Copyright (c) 1995-2004, Index Data
3 * See the file LICENSE for details.
5 * $Id: odr.c,v 1.8 2004-10-15 00:19:00 adam Exp $
11 * \brief Implements fundamental ODR functionality
22 #include <yaz/xmalloc.h>
25 Odr_null *ODR_NULLVAL = (Odr_null *) "NULL"; /* the presence of a null value */
27 Odr_null *odr_nullval (void)
35 "Memory allocation failed",
38 "Required data element missing",
44 "Length of constructed type different from sum of members",
45 "Overflow writing definite length of constructed type",
49 char *odr_errmsg(int n)
51 return odr_errlist[n];
54 void odr_perror(ODR o, const char *message)
56 const char *e = odr_getelement(o);
59 err = odr_geterrorx(o, &x);
60 fprintf(stderr, "%s: %s (code %d:%d)", message, odr_errlist[err], err, x);
62 fprintf (stderr, " element %s", e);
63 fprintf(stderr, "\n");
66 int odr_geterror(ODR o)
71 int odr_geterrorx(ODR o, int *x)
78 const char *odr_getelement(ODR o)
80 return o->op->element;
83 const char **odr_get_element_path(ODR o)
85 return o->op->stack_names;
88 void odr_seterror(ODR o, int error, int id)
92 o->op->element[0] = '\0';
95 void odr_setelement(ODR o, const char *element)
99 strncpy(o->op->element, element, sizeof(o->op->element)-1);
100 o->op->element[sizeof(o->op->element)-1] = '\0';
104 void odr_FILE_write(ODR o, void *handle, int type,
105 const char *buf, int len)
109 if (type == ODR_OCTETSTRING)
111 const char **stack_names = odr_get_element_path(o);
112 for (i = 0; stack_names[i]; i++)
113 fprintf((FILE*) handle, "[%s]", stack_names[i]);
114 fputs("\n", (FILE*) handle);
117 for (i = 0; i<len; i++)
119 unsigned c = ((const unsigned char *) buf)[i];
120 if (i == 2000 && len > 3100)
122 fputs(" ..... ", (FILE*) handle);
125 if (strchr("\r\n\f\t", c) || (c >= ' ' && c <= 126))
126 putc(c, (FILE*) handle);
130 sprintf(x, "\\X%02X", c);
131 fputs(x, (FILE*) handle);
136 void odr_FILE_close(void *handle)
138 FILE *f = (FILE *) handle;
139 if (f && f != stderr && f != stdout)
143 void odr_setprint(ODR o, FILE *file)
145 odr_set_stream(o, file, odr_FILE_write, odr_FILE_close);
148 void odr_set_stream(ODR o, void *handle,
149 void (*stream_write)(ODR o,
150 void *handle, int type,
151 const char *buf, int len),
152 void (*stream_close)(void *handle))
154 o->print = (FILE*) handle;
155 o->op->stream_write = stream_write;
156 o->op->stream_close = stream_close;
159 int odr_set_charset(ODR o, const char *to, const char *from)
161 if (o->op->iconv_handle)
162 yaz_iconv_close (o->op->iconv_handle);
163 o->op->iconv_handle = 0;
166 o->op->iconv_handle = yaz_iconv_open (to, from);
167 if (o->op->iconv_handle == 0)
175 ODR odr_createmem(int direction)
179 if (!(o = (ODR)xmalloc(sizeof(*o))))
181 o->direction = direction;
183 o->size = o->pos = o->top = 0;
185 o->mem = nmem_create();
187 o->op = (struct Odr_private *) xmalloc (sizeof(*o->op));
188 o->op->odr_ber_tag.lclass = -1;
189 o->op->iconv_handle = 0;
190 odr_setprint(o, stderr);
192 yaz_log (LOG_DEBUG, "odr_createmem dir=%d o=%p", direction, o);
196 void odr_reset(ODR o)
198 odr_seterror(o, ONONE, 0);
200 odr_seek(o, ODR_S_SET, 0);
209 if (o->op->iconv_handle != 0)
210 yaz_iconv(o->op->iconv_handle, 0, 0, 0, 0);
211 yaz_log (LOG_DEBUG, "odr_reset o=%p", o);
214 void odr_destroy(ODR o)
216 nmem_destroy(o->mem);
217 if (o->buf && o->can_grow)
219 if (o->op->stream_close)
220 o->op->stream_close(o->print);
221 if (o->op->iconv_handle != 0)
222 yaz_iconv_close (o->op->iconv_handle);
225 yaz_log (LOG_DEBUG, "odr_destroy o=%p", o);
228 void odr_setbuf(ODR o, char *buf, int len, int can_grow)
230 odr_seterror(o, ONONE, 0);
231 o->bp = (unsigned char *) buf;
233 o->buf = (unsigned char *) buf;
234 o->can_grow = can_grow;
239 char *odr_getbuf(ODR o, int *len, int *size)
244 return (char*) o->buf;
247 void odr_printf(ODR o, const char *fmt, ...)
254 _vsnprintf(buf, sizeof(buf)-1, fmt, ap);
257 vsnprintf(buf, sizeof(buf), fmt, ap);
259 vsprintf(buf, fmt, ap);
262 o->op->stream_write(o, o->print, ODR_VISIBLESTRING, buf, strlen(buf));