YAZ  5.23.1
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 
void yaz_vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
Definition: snprintf.c:17
void odr_seterror(ODR o, int error, int id)
Definition: odr.c:118
int t_class
Definition: odr-priv.h:107
const char * odr_getelement(ODR o)
Definition: odr.c:90
int odr_geterrorx(ODR o, int *x)
Definition: odr.c:83
struct odr_constack * stack_top
Definition: odr-priv.h:92
void odr_FILE_close(void *handle)
Definition: odr.c:157
int odr_offset(ODR o)
Definition: odr.c:285
int choice_bias
Definition: odr-priv.h:111
stack for BER constructed items
Definition: odr-priv.h:63
void odr_perror(ODR o, const char *message)
Definition: odr.c:57
char * odr_getbuf(ODR o, int *len, int *size)
Definition: odr.c:277
FILE * print
Definition: odr-priv.h:113
void nmem_destroy(NMEM n)
destroys NMEM handle and memory associated with it
Definition: nmem.c:204
int error
Definition: odr.h:128
int odr_seek(ODR o, int whence, int offset)
Definition: odr_mem.c:117
yaz_iconv_t yaz_iconv_open(const char *tocode, const char *fromcode)
just like iconv_open(3)
Definition: siconv.c:95
void nmem_reset(NMEM n)
releases memory associaged with an NMEM handle
Definition: nmem.c:129
int can_grow
Definition: odr-priv.h:106
struct Odr_ber_tag odr_ber_tag
Definition: odr-priv.h:97
void odr_setprint(ODR o, FILE *file)
Definition: odr.c:164
void odr_setprint_noclose(ODR o, FILE *file)
Definition: odr.c:169
void * odr_malloc(ODR o, size_t size)
Definition: odr_mem.c:31
void odr_setelement(ODR o, const char *element)
Definition: odr.c:125
#define ODR_S_SET
Definition: odr.h:117
Internal ODR definitions.
void(* stream_write)(ODR o, void *handle, int type, const char *buf, int len)
Definition: odr-priv.h:102
const char ** odr_get_element_path(ODR o)
Definition: odr.c:95
const char ** tmp_names_buf
Definition: odr-priv.h:94
#define ODR_VISIBLESTRING
Definition: odr.h:89
int yaz_iconv_close(yaz_iconv_t cd)
just like iconv_close(3)
Definition: siconv.c:284
char element[80]
Definition: odr-priv.h:101
int error_id
Definition: odr-priv.h:100
int direction
Definition: odr.h:126
int odr_geterror(ODR o)
Definition: odr.c:78
#define ONONE
Definition: odr.h:150
Odr_null * odr_nullval(void)
Definition: odr.c:30
void odr_setbuf(ODR o, char *buf, int len, int can_grow)
Definition: odr.c:267
void odr_reset(ODR o)
Definition: odr.c:226
void(* stream_close)(void *handle)
Definition: odr-priv.h:104
#define xfree(x)
utility macro which calls xfree_f
Definition: xmalloc.h:53
enum l_file_type type
Definition: log.c:45
int indent
Definition: odr-priv.h:114
static int log_level
Definition: odr.c:25
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
struct Odr_private * op
Definition: odr.h:132
int size
Definition: odr-priv.h:88
NMEM mem
Definition: odr.h:130
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
char * odr_errmsg(int n)
Definition: odr.c:52
yaz_iconv_t iconv_handle
Definition: odr-priv.h:99
const char * bp
Definition: odr-priv.h:85
void odr_destroy(ODR o)
Definition: odr.c:253
struct odr_constack * prev
Definition: odr-priv.h:74
Definition: odr.h:124
const char * name
Definition: odr-priv.h:72
int odr_set_charset(ODR o, const char *to, const char *from)
Definition: odr.c:185
void odr_FILE_write(ODR o, void *handle, int type, const char *buf, int len)
Definition: odr.c:134
static int log_level_initialized
Definition: odr.c:26
#define xmalloc(x)
utility macro which calls malloc_f
Definition: xmalloc.h:49
int lclass
Definition: odr-priv.h:41
char * buf
Definition: odr-priv.h:84
Header for memory handling functions.
NMEM nmem_create(void)
returns new NMEM handle
Definition: nmem.c:181
int lenlen
Definition: odr-priv.h:112
void yaz_log(int level, const char *fmt,...)
Writes log message.
Definition: log.c:485
int yaz_log_module_level(const char *name)
returns level for module
Definition: log.c:584
ODR odr_createmem(int direction)
Definition: odr.c:200
struct odr_constack * stack_first
Definition: odr-priv.h:91
int enable_bias
Definition: odr-priv.h:110
ODR private data.
Definition: odr-priv.h:83
char * odr_errlist[]
Definition: odr.c:35
Logging utility.
int tmp_names_sz
Definition: odr-priv.h:95
Header for config file reading utilities.
Odr_null * ODR_NULLVAL
Definition: odr.c:28
void odr_printf(ODR o, const char *fmt,...)
Definition: odr.c:290
void Odr_null
Definition: odr.h:105