YAZ  5.34.0
odr_oct.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  */
9 #if HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12 
13 #include "odr-priv.h"
14 
15 /*
16  * Top level octet string en/decoder.
17  * Returns 1 on success, 0 on error.
18  */
19 int odr_octetstring(ODR o, Odr_oct **p, int opt, const char *name)
20 {
21  int res, cons = 0;
22 
23  if (o->error)
24  return 0;
25  if (o->op->t_class < 0)
26  {
27  o->op->t_class = ODR_UNIVERSAL;
28  o->op->t_tag = ODR_OCTETSTRING;
29  }
30  res = ber_tag(o, p, o->op->t_class, o->op->t_tag, &cons, opt, name);
31  if (res < 0)
32  return 0;
33  if (!res)
34  return odr_missing(o, opt, name);
35  if (o->direction == ODR_PRINT)
36  {
37  odr_prname(o, name);
38  odr_printf(o, "OCTETSTRING(len=%d) ", (*p)->len);
39 
41  (char*) (*p)->buf, (*p)->len);
42  odr_printf(o, "\n");
43  return 1;
44  }
45  if (o->direction == ODR_DECODE)
46  {
47  *p = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct));
48  (*p)->len = 0;
49  (*p)->buf = 0;
50  }
51  if (ber_octetstring(o, *p, cons))
52  return 1;
53  odr_seterror(o, OOTHER, 43);
54  return 0;
55 }
56 
57 /*
58  * Friendlier interface to octetstring.
59  */
60 int odr_cstring(ODR o, char **p, int opt, const char *name)
61 {
62  int cons = 0, res;
63  Odr_oct *t;
64 
65  if (o->error)
66  return 0;
67  if (o->op->t_class < 0)
68  {
69  o->op->t_class = ODR_UNIVERSAL;
70  o->op->t_tag = ODR_OCTETSTRING;
71  }
72  res = ber_tag(o, p, o->op->t_class, o->op->t_tag, &cons, opt, name);
73  if (res < 0)
74  return 0;
75  if (!res)
76  return odr_missing(o, opt, name);
77  if (o->direction == ODR_PRINT)
78  {
79  odr_prname(o, name);
80  odr_printf(o, "'%s'\n", *p);
81  return 1;
82  }
83  t = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct)); /* wrapper for octstring */
84  if (o->direction == ODR_ENCODE)
85  {
86  t->buf = *p;
87  t->len = strlen(*p);
88  }
89  else
90  {
91  t->len = 0;
92  t->buf = 0;
93  }
94  if (!ber_octetstring(o, t, cons))
95  return 0;
96  if (o->direction == ODR_DECODE)
97  {
98  *p = (char *) t->buf;
99  *(*p + t->len) = '\0'; /* ber_octs reserves space for this */
100  }
101  return 1;
102 }
103 
104 /*
105  * iconv interface to octetstring.
106  */
107 int odr_iconv_string(ODR o, char **p, int opt, const char *name)
108 {
109  int cons = 0, res;
110  Odr_oct *t;
111 
112  if (o->error)
113  return 0;
114  if (o->op->t_class < 0)
115  {
116  o->op->t_class = ODR_UNIVERSAL;
117  o->op->t_tag = ODR_OCTETSTRING;
118  }
119  res = ber_tag(o, p, o->op->t_class, o->op->t_tag, &cons, opt, name);
120  if (res < 0)
121  return 0;
122  if (!res)
123  return odr_missing(o, opt, name);
124  if (o->direction == ODR_PRINT)
125  {
126  odr_prname(o, name);
127  odr_printf(o, "'%s'\n", *p);
128  return 1;
129  }
130  t = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct)); /* wrapper for octstring */
131  if (o->direction == ODR_ENCODE)
132  {
133  t->buf = 0;
134 
135  if (o->op->iconv_handle != 0)
136  {
137  size_t inleft = strlen(*p);
138  char *inbuf = *p;
139  size_t outleft = 4 * inleft + 2;
140  char *outbuf = (char *) odr_malloc (o, outleft);
141  size_t ret;
142 
143  t->buf = outbuf;
144 
145  ret = yaz_iconv(o->op->iconv_handle, &inbuf, &inleft,
146  &outbuf, &outleft);
147  if (ret == (size_t)(-1))
148  {
149  odr_seterror(o, ODATA, 44);
150  return 0;
151  }
152  ret = yaz_iconv(o->op->iconv_handle, 0, 0,
153  &outbuf, &outleft);
154 
155  if (ret == (size_t)(-1))
156  {
157  odr_seterror(o, ODATA, 44);
158  return 0;
159  }
160  t->len = outbuf - (char*) t->buf;
161  }
162  if (!t->buf)
163  {
164  t->buf = *p;
165  t->len = strlen(*p);
166  }
167  }
168  else
169  {
170  t->len = 0;
171  t->buf = 0;
172  }
173  if (!ber_octetstring(o, t, cons))
174  return 0;
175  if (o->direction == ODR_DECODE)
176  {
177  *p = 0;
178 
179  if (o->op->iconv_handle != 0)
180  {
181  size_t inleft = t->len;
182  char *inbuf = (char *) t->buf;
183  size_t outleft = 4 * inleft + 2;
184  char *outbuf = (char *) odr_malloc (o, outleft);
185  size_t ret;
186 
187  *p = outbuf;
188 
189  ret = yaz_iconv (o->op->iconv_handle, &inbuf, &inleft,
190  &outbuf, &outleft);
191  if (ret == (size_t)(-1))
192  {
193  odr_seterror(o, ODATA, 45);
194  return 0;
195  }
196  ret = yaz_iconv(o->op->iconv_handle, 0, 0,
197  &outbuf, &outleft);
198  if (ret == (size_t)(-1))
199  {
200  odr_seterror(o, ODATA, 45);
201  return 0;
202  }
203  inleft = outbuf - (char*) *p;
204 
205  (*p)[inleft] = '\0'; /* null terminate it */
206  }
207  if (!*p)
208  {
209  *p = (char *) t->buf;
210  *(*p + t->len) = '\0'; /* ber_octs reserves space for this */
211  }
212  }
213  return 1;
214 }
215 /*
216  * Local variables:
217  * c-basic-offset: 4
218  * c-file-style: "Stroustrup"
219  * indent-tabs-mode: nil
220  * End:
221  * vim: shiftwidth=4 tabstop=8 expandtab
222  */
223 
int ber_octetstring(ODR o, Odr_oct *p, int cons)
Definition: ber_oct.c:22
int ber_tag(ODR o, void *p, int zclass, int tag, int *constructed, int opt, const char *name)
Encode/decode BER tags.
Definition: ber_tag.c:34
int opt
Definition: initopt.c:19
char * name
Definition: initopt.c:18
Internal ODR definitions.
void odr_seterror(ODR o, int error, int id)
Definition: odr.c:118
void odr_printf(ODR o, const char *fmt,...)
Definition: odr.c:290
#define ODR_DECODE
Definition: odr.h:95
#define ODR_OCTETSTRING
Definition: odr.h:76
#define ODR_UNIVERSAL
Definition: odr.h:65
#define ODR_PRINT
Definition: odr.h:97
#define OOTHER
Definition: odr.h:156
#define ODR_ENCODE
Definition: odr.h:96
#define ODATA
Definition: odr.h:158
void * odr_malloc(ODR o, size_t size)
Definition: odr_mem.c:31
int odr_iconv_string(ODR o, char **p, int opt, const char *name)
Definition: odr_oct.c:107
int odr_octetstring(ODR o, Odr_oct **p, int opt, const char *name)
Definition: odr_oct.c:19
int odr_cstring(ODR o, char **p, int opt, const char *name)
Definition: odr_oct.c:60
void odr_prname(ODR o, const char *name)
Definition: odr_util.c:18
int odr_missing(ODR o, int opt, const char *name)
Definition: odr_util.c:82
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
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
int t_class
Definition: odr-priv.h:107
FILE * print
Definition: odr-priv.h:113
Definition: odr.h:100
int len
Definition: odr.h:102
char * buf
Definition: odr.h:101
Definition: odr.h:125
struct Odr_private * op
Definition: odr.h:132
int error
Definition: odr.h:128
int direction
Definition: odr.h:126