YAZ  5.34.0
odr.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14 
15 #include <assert.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdarg.h>
19 
20 #include <yaz/xmalloc.h>
21 #include <yaz/log.h>
22 #include <yaz/snprintf.h>
23 #include "odr-priv.h"
24 
25 static int log_level = 0;
26 static int log_level_initialized = 0;
27 
28 Odr_null *ODR_NULLVAL = (Odr_null *) "NULL"; /* the presence of a null value */
29 
31 {
32  return ODR_NULLVAL;
33 }
34 
35 char *odr_errlist[] =
36 {
37  "No (unknown) error",
38  "Memory allocation failed",
39  "System error",
40  "No space in buffer",
41  "Required data element missing",
42  "Unexpected tag",
43  "Other error",
44  "Protocol error",
45  "Malformed data",
46  "Stack overflow",
47  "Length of constructed type different from sum of members",
48  "Overflow writing definite length of constructed type",
49  "Bad HTTP Request"
50 };
51 
52 char *odr_errmsg(int n)
53 {
54  return odr_errlist[n];
55 }
56 
57 void odr_perror(ODR o, const char *message)
58 {
59  const char *e = odr_getelement(o);
60  const char **element_path = odr_get_element_path(o);
61  int err, x;
62 
63  err = odr_geterrorx(o, &x);
64  fprintf(stderr, "%s: %s (code %d:%d)", message, odr_errlist[err], err, x);
65  if (e && *e)
66  fprintf(stderr, " element %s", e);
67 
68  fprintf(stderr, "\n");
69  if (element_path)
70  {
71  fprintf(stderr, "Element path:");
72  while (*element_path)
73  fprintf(stderr, " %s", *element_path++);
74  fprintf(stderr, "\n");
75  }
76 }
77 
79 {
80  return o->error;
81 }
82 
83 int odr_geterrorx(ODR o, int *x)
84 {
85  if (x)
86  *x = o->op->error_id;
87  return o->error;
88 }
89 
90 const char *odr_getelement(ODR o)
91 {
92  return o->op->element;
93 }
94 
95 const char **odr_get_element_path(ODR o)
96 {
97  int cur_sz = 0;
98  struct odr_constack *st;
99 
100  for (st = o->op->stack_top; st; st = st->prev)
101  cur_sz++;
102  if (o->op->tmp_names_sz < cur_sz + 1)
103  {
104  o->op->tmp_names_sz = 2 * cur_sz + 5;
105  o->op->tmp_names_buf = (const char **)
106  odr_malloc(o, o->op->tmp_names_sz * sizeof(char*));
107  }
108  o->op->tmp_names_buf[cur_sz] = 0;
109  for (st = o->op->stack_top; st; st = st->prev)
110  {
111  cur_sz--;
112  o->op->tmp_names_buf[cur_sz] = st->name;
113  }
114  assert(cur_sz == 0);
115  return o->op->tmp_names_buf;
116 }
117 
118 void odr_seterror(ODR o, int error, int id)
119 {
120  o->error = error;
121  o->op->error_id = id;
122  o->op->element[0] = '\0';
123 }
124 
125 void odr_setelement(ODR o, const char *element)
126 {
127  if (element)
128  {
129  strncpy(o->op->element, element, sizeof(o->op->element)-1);
130  o->op->element[sizeof(o->op->element)-1] = '\0';
131  }
132 }
133 
134 void odr_FILE_write(ODR o, void *handle, int type,
135  const char *buf, int len)
136 {
137  int i;
138  for (i = 0; i < len; i++)
139  {
140  unsigned c = ((const unsigned char *) buf)[i];
141  if (i == 20000 && len > 31000)
142  {
143  fputs(" ..... ", (FILE*) handle);
144  i = len - 1000;
145  }
146  if (strchr("\r\n\f\t", c) || (c >= ' ' && c <= 126))
147  putc(c, (FILE*) handle);
148  else
149  {
150  char x[5];
151  sprintf(x, "\\X%02X", c);
152  fputs(x, (FILE*) handle);
153  }
154  }
155 }
156 
157 void odr_FILE_close(void *handle)
158 {
159  FILE *f = (FILE *) handle;
160  if (f && f != stderr && f != stdout)
161  fclose(f);
162 }
163 
164 void odr_setprint(ODR o, FILE *file)
165 {
167 }
168 
169 void odr_setprint_noclose(ODR o, FILE *file)
170 {
171  odr_set_stream(o, file, odr_FILE_write, 0);
172 }
173 
174 void odr_set_stream(ODR o, void *handle,
175  void (*stream_write)(ODR o,
176  void *handle, int type,
177  const char *buf, int len),
178  void (*stream_close)(void *handle))
179 {
180  o->op->print = (FILE*) handle;
181  o->op->stream_write = stream_write;
182  o->op->stream_close = stream_close;
183 }
184 
185 int odr_set_charset(ODR o, const char *to, const char *from)
186 {
187  if (o->op->iconv_handle)
189  o->op->iconv_handle = 0;
190  if (to && from)
191  {
192  o->op->iconv_handle = yaz_iconv_open(to, from);
193  if (o->op->iconv_handle == 0)
194  return -1;
195  }
196  return 0;
197 }
198 
199 
200 ODR odr_createmem(int direction)
201 {
202  ODR o;
204  {
207  }
208 
209  if (!(o = (ODR) xmalloc(sizeof(*o))))
210  return 0;
211  o->op = (struct Odr_private *) xmalloc(sizeof(*o->op));
212  o->direction = direction;
213  o->op->buf = 0;
214  o->op->size = o->op->pos = o->op->top = 0;
215  o->op->can_grow = 1;
216  o->mem = nmem_create();
217  o->op->enable_bias = 1;
218  o->op->odr_ber_tag.lclass = -1;
219  o->op->iconv_handle = 0;
220  odr_setprint_noclose(o, stderr);
221  odr_reset(o);
222  yaz_log(log_level, "odr_createmem dir=%d o=%p", direction, o);
223  return o;
224 }
225 
226 void odr_reset(ODR o)
227 {
229  {
232  }
233 
234  odr_seterror(o, ONONE, 0);
235  o->op->bp = o->op->buf;
236  odr_seek(o, ODR_S_SET, 0);
237  o->op->top = 0;
238  o->op->t_class = -1;
239  o->op->t_tag = -1;
240  o->op->indent = 0;
241  o->op->stack_first = 0;
242  o->op->stack_top = 0;
243  o->op->tmp_names_sz = 0;
244  o->op->tmp_names_buf = 0;
245  nmem_reset(o->mem);
246  o->op->choice_bias = -1;
247  o->op->lenlen = 1;
248  if (o->op->iconv_handle != 0)
249  yaz_iconv(o->op->iconv_handle, 0, 0, 0, 0);
250  yaz_log(log_level, "odr_reset o=%p", o);
251 }
252 
254 {
255  nmem_destroy(o->mem);
256  if (o->op->buf && o->op->can_grow)
257  xfree(o->op->buf);
258  if (o->op->stream_close)
259  o->op->stream_close(o->op->print);
260  if (o->op->iconv_handle != 0)
262  xfree(o->op);
263  xfree(o);
264  yaz_log(log_level, "odr_destroy o=%p", o);
265 }
266 
267 void odr_setbuf(ODR o, char *buf, int len, int can_grow)
268 {
269  odr_seterror(o, ONONE, 0);
270  o->op->bp = buf;
271  o->op->buf = buf;
272  o->op->can_grow = can_grow;
273  o->op->top = o->op->pos = 0;
274  o->op->size = len;
275 }
276 
277 char *odr_getbuf(ODR o, int *len, int *size)
278 {
279  *len = o->op->top;
280  if (size)
281  *size = o->op->size;
282  return o->op->buf;
283 }
284 
286 {
287  return o->op->bp - o->op->buf;
288 }
289 
290 void odr_printf(ODR o, const char *fmt, ...)
291 {
292  va_list ap;
293  char buf[4096];
294 
295  va_start(ap, fmt);
296  yaz_vsnprintf(buf, sizeof(buf), fmt, ap);
297  o->op->stream_write(o, o->op->print, ODR_VISIBLESTRING, buf, strlen(buf));
298  va_end(ap);
299 }
300 /*
301  * Local variables:
302  * c-basic-offset: 4
303  * c-file-style: "Stroustrup"
304  * indent-tabs-mode: nil
305  * End:
306  * vim: shiftwidth=4 tabstop=8 expandtab
307  */
308 
enum l_file_type type
Definition: log.c:47
void yaz_log(int level, const char *fmt,...)
Writes log message.
Definition: log.c:487
int yaz_log_module_level(const char *name)
returns level for module
Definition: log.c:586
Logging utility.
void nmem_reset(NMEM n)
releases memory associaged with an NMEM handle
Definition: nmem.c:129
NMEM nmem_create(void)
returns new NMEM handle
Definition: nmem.c:181
void nmem_destroy(NMEM n)
destroys NMEM handle and memory associated with it
Definition: nmem.c:204
Internal ODR definitions.
void odr_perror(ODR o, const char *message)
Definition: odr.c:57
void odr_setprint_noclose(ODR o, FILE *file)
Definition: odr.c:169
const char ** odr_get_element_path(ODR o)
Definition: odr.c:95
void odr_FILE_close(void *handle)
Definition: odr.c:157
void odr_setelement(ODR o, const char *element)
Definition: odr.c:125
Odr_null * ODR_NULLVAL
Definition: odr.c:28
int odr_geterrorx(ODR o, int *x)
Definition: odr.c:83
int odr_geterror(ODR o)
Definition: odr.c:78
int odr_offset(ODR o)
Definition: odr.c:285
void odr_seterror(ODR o, int error, int id)
Definition: odr.c:118
void odr_FILE_write(ODR o, void *handle, int type, const char *buf, int len)
Definition: odr.c:134
ODR odr_createmem(int direction)
Definition: odr.c:200
char * odr_errmsg(int n)
Definition: odr.c:52
int odr_set_charset(ODR o, const char *to, const char *from)
Definition: odr.c:185
void odr_setbuf(ODR o, char *buf, int len, int can_grow)
Definition: odr.c:267
void odr_setprint(ODR o, FILE *file)
Definition: odr.c:164
static int log_level
Definition: odr.c:25
Odr_null * odr_nullval(void)
Definition: odr.c:30
void odr_set_stream(ODR o, void *handle, void(*stream_write)(ODR o, void *handle, int type, const char *buf, int len), void(*stream_close)(void *handle))
Definition: odr.c:174
static int log_level_initialized
Definition: odr.c:26
char * odr_getbuf(ODR o, int *len, int *size)
Definition: odr.c:277
const char * odr_getelement(ODR o)
Definition: odr.c:90
void odr_destroy(ODR o)
Definition: odr.c:253
void odr_reset(ODR o)
Definition: odr.c:226
char * odr_errlist[]
Definition: odr.c:35
void odr_printf(ODR o, const char *fmt,...)
Definition: odr.c:290
#define ODR_VISIBLESTRING
Definition: odr.h:89
#define ODR_S_SET
Definition: odr.h:117
void Odr_null
Definition: odr.h:105
#define ONONE
Definition: odr.h:150
int odr_seek(ODR o, int whence, int offset)
Definition: odr_mem.c:117
void * odr_malloc(ODR o, size_t size)
Definition: odr_mem.c:31
size_t yaz_iconv(yaz_iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
just like iconv(3)
Definition: siconv.c:146
int yaz_iconv_close(yaz_iconv_t cd)
just like iconv_close(3)
Definition: siconv.c:284
yaz_iconv_t yaz_iconv_open(const char *tocode, const char *fromcode)
just like iconv_open(3)
Definition: siconv.c:95
void yaz_vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
Definition: snprintf.c:17
Header for config file reading utilities.
int lclass
Definition: odr-priv.h:41
ODR private data.
Definition: odr-priv.h:83
char * buf
Definition: odr-priv.h:84
int enable_bias
Definition: odr-priv.h:110
struct odr_constack * stack_top
Definition: odr-priv.h:92
int can_grow
Definition: odr-priv.h:106
int indent
Definition: odr-priv.h:114
int lenlen
Definition: odr-priv.h:112
int error_id
Definition: odr-priv.h:100
const char * bp
Definition: odr-priv.h:85
int choice_bias
Definition: odr-priv.h:111
yaz_iconv_t iconv_handle
Definition: odr-priv.h:99
void(* stream_write)(ODR o, void *handle, int type, const char *buf, int len)
Definition: odr-priv.h:102
void(* stream_close)(void *handle)
Definition: odr-priv.h:104
int t_class
Definition: odr-priv.h:107
int tmp_names_sz
Definition: odr-priv.h:95
const char ** tmp_names_buf
Definition: odr-priv.h:94
FILE * print
Definition: odr-priv.h:113
struct odr_constack * stack_first
Definition: odr-priv.h:91
char element[80]
Definition: odr-priv.h:101
int size
Definition: odr-priv.h:88
struct Odr_ber_tag odr_ber_tag
Definition: odr-priv.h:97
stack for BER constructed items
Definition: odr-priv.h:64
struct odr_constack * prev
Definition: odr-priv.h:74
const char * name
Definition: odr-priv.h:72
Definition: odr.h:125
struct Odr_private * op
Definition: odr.h:132
int error
Definition: odr.h:128
int direction
Definition: odr.h:126
NMEM mem
Definition: odr.h:130
Header for memory handling functions.
#define xfree(x)
utility macro which calls xfree_f
Definition: xmalloc.h:53
#define xmalloc(x)
utility macro which calls malloc_f
Definition: xmalloc.h:49