YAZ  4.2.57
charneg.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2013 Index Data
3  * See the file LICENSE for details.
4  */
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14 
15 #include <stdio.h>
16 #include <yaz/otherinfo.h>
17 #include <yaz/z-charneg.h>
18 #include <yaz/charneg.h>
19 #include <yaz/yaz-util.h>
20 #include <yaz/oid_db.h>
21 
22 static Z_External* z_ext_record2(ODR o, const char *buf)
23 {
24  Z_External *p;
25  int len = strlen(buf);
26 
27  if (!(p = (Z_External *)odr_malloc(o, sizeof(*p))))
28  return 0;
29  p->descriptor = 0;
30  p->indirect_reference = 0;
31 
33 
35  if (!(p->u.octet_aligned = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct))))
36  return 0;
37  if (!(p->u.octet_aligned->buf = (unsigned char *)odr_malloc(o, len)))
38  return 0;
39  p->u.octet_aligned->len = p->u.octet_aligned->size = len;
40  memcpy(p->u.octet_aligned->buf, buf, len);
41 
42  return p;
43 }
44 
45 static int get_form(const char *charset)
46 {
47  int form = -1;
48 
49  if (!yaz_matchstr(charset, "UCS-2"))
50  form = 2;
51  if (!yaz_matchstr(charset, "UCS-4"))
52  form = 4;
53  if (!yaz_matchstr(charset, "UTF-16"))
54  form = 5;
55  if (!yaz_matchstr(charset, "UTF-8"))
56  form = 8;
57 
58  return form;
59 }
60 
61 static char *set_form(Odr_oid *encoding)
62 {
63  static char *charset = 0;
64  if ( oid_oidlen(encoding) != 6)
65  return 0;
66  if (encoding[5] == 2)
67  charset = "UCS-2";
68  if (encoding[5] == 4)
69  charset = "UCS-4";
70  if (encoding[5] == 5)
71  charset = "UTF-16";
72  if (encoding[5] == 8)
73  charset = "UTF-8";
74  return charset;
75 }
76 
77 static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
78 {
79  int form = get_form(charset);
80  Z_OriginProposal_0 *p0 =
81  (Z_OriginProposal_0*)odr_malloc(o, sizeof(*p0));
82 
83  memset(p0, 0, sizeof(*p0));
84 
85  if (form > 0)
86  { /* ISO 10646 (UNICODE) */
87  char oidname[20];
88 
89  Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc(o, sizeof(*is));
91  p0->u.iso10646 = is;
92  is->collections = 0;
93  sprintf(oidname, "1.0.10646.1.0.%d", form);
94  is->encodingLevel = odr_getoidbystr(o, oidname);
95  }
96  else
97  { /* private ones */
99  (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
100 
101  memset(pc, 0, sizeof(*pc));
102 
104  p0->u.zprivate = pc;
105 
107  pc->u.externallySpecified = z_ext_record2(o, charset);
108  }
109  return p0;
110 }
111 
113  ODR o, const char **charsets, int num_charsets,
114  const char **langs, int num_langs, int selected)
115 {
116  int i;
117  Z_OriginProposal *p = (Z_OriginProposal *) odr_malloc(o, sizeof(*p));
118 
119  memset(p, 0, sizeof(*p));
120 
122  *p->recordsInSelectedCharSets = (selected) ? 1 : 0;
123 
124  if (charsets && num_charsets)
125  {
126  p->num_proposedCharSets = num_charsets;
127  p->proposedCharSets =
129  odr_malloc(o, num_charsets*sizeof(Z_OriginProposal_0*));
130 
131  for (i = 0; i < num_charsets; i++)
132  p->proposedCharSets[i] =
133  z_get_OriginProposal_0(o, charsets[i]);
134  }
135  if (langs && num_langs)
136  {
137  p->num_proposedlanguages = num_langs;
138  p->proposedlanguages =
139  (char **) odr_malloc(o, num_langs*sizeof(char *));
140 
141  for (i = 0; i < num_langs; i++)
142  p->proposedlanguages[i] = (char *)langs[i];
143  }
144  return p;
145 }
146 
148  ODR o)
149 {
151  (Z_CharSetandLanguageNegotiation *) odr_malloc(o, sizeof(*p));
152 
153  memset(p, 0, sizeof(*p));
154 
155  return p;
156 }
157 
158 /* Create EXTERNAL for negotation proposal. Client side */
160  const char **charsets, int num_charsets,
161  const char **langs, int num_langs,
162  int selected)
163 {
164  Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
165 
166  p->descriptor = 0;
167  p->indirect_reference = 0;
168 
170 
174  p->u.charNeg3->u.proposal =
175  z_get_OriginProposal(o, charsets, num_charsets,
176  langs, num_langs, selected);
177 
178  return p;
179 }
180 
182  const char *delim,
183  const char *charset_list,
184  const char *lang_list,
185  int selected)
186 {
187  char **charsets_addresses = 0;
188  char **langs_addresses = 0;
189  int charsets_count = 0;
190  int langs_count = 0;
191 
192  if (charset_list)
193  nmem_strsplit(odr_getmem(o), delim, charset_list,
194  &charsets_addresses, &charsets_count);
195  if (lang_list)
196  nmem_strsplit(odr_getmem(o), delim, lang_list,
197  &langs_addresses, &langs_count);
198  return yaz_set_proposal_charneg(o,
199  (const char **) charsets_addresses,
200  charsets_count,
201  (const char **) langs_addresses,
202  langs_count,
203  selected);
204 }
205 
206 
207 /* used by yaz_set_response_charneg */
208 static Z_TargetResponse *z_get_TargetResponse(ODR o, const char *charset,
209  const char *lang, int selected)
210 {
211  Z_TargetResponse *p = (Z_TargetResponse *) odr_malloc(o, sizeof(*p));
212  int form = get_form(charset);
213 
214  memset(p, 0, sizeof(*p));
215  if (form > 0)
216  {
217  char oidname[20];
218 
219  Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
221  p->u.iso10646 = is;
222  is->collections = 0;
223  sprintf(oidname, "1.0.10646.1.0.%d", form);
224  is->encodingLevel = odr_getoidbystr (o, oidname);
225  }
226  else
227  {
229  (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
230 
231  memset(pc, 0, sizeof(*pc));
232 
234  p->u.zprivate = pc;
235 
237  pc->u.externallySpecified =
238  z_ext_record2(o, charset);
239  }
241  *p->recordsInSelectedCharSets = (selected) ? 1 : 0;
242 
243  p->selectedLanguage = lang ? (char *) odr_strdup(o, lang) : 0;
244  return p;
245 }
246 
247 /* Create charset response. Server side */
248 Z_External *yaz_set_response_charneg(ODR o, const char *charset,
249  const char *lang, int selected)
250 {
251  Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
252 
253  p->descriptor = 0;
254  p->indirect_reference = 0;
255 
257 
261  p->u.charNeg3->u.response = z_get_TargetResponse(o, charset, lang, selected);
262 
263  return p;
264 }
265 
266 /* Get negotiation from OtherInformation. Client&Server side */
268 {
269  int i;
270 
271  if (!p)
272  return 0;
273 
274  for (i = 0; i < p->num_elements; i++)
275  {
276  Z_External *pext;
277  if ((p->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
278  (pext = p->list[i]->information.externallyDefinedInfo))
279  {
282  {
283  return pext->u.charNeg3;
284  }
285  }
286  }
287  return 0;
288 }
289 
290 /* Delete negotiation from OtherInformation. Client&Server side */
292 {
293  int i;
294 
295  if (!*p)
296  return 0;
297 
298  for (i = 0; i < (*p)->num_elements; i++)
299  {
300  Z_External *pext;
301  if (((*p)->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
302  (pext = (*p)->list[i]->information.externallyDefinedInfo))
303  {
306  {
307  if ((*p)->num_elements <= 1)
308  *p = 0;
309  else
310  {
311  --((*p)->num_elements);
312  for (; i < (*p)->num_elements; i++)
313  (*p)->list[i] = (*p)->list[i+1];
314  }
315  return 1;
316  }
317  }
318  }
319  return 0;
320 }
321 
322 
323 /* Get charsets, langs, selected from negotiation.. Server side */
325  char ***charsets, int *num_charsets,
326  char ***langs, int *num_langs, int *selected)
327 {
328  int i;
329  Z_OriginProposal *pro = p->u.proposal;
330 
331  if (num_charsets && charsets)
332  {
333  if (pro->num_proposedCharSets)
334  {
335  *num_charsets = pro->num_proposedCharSets;
336 
337  (*charsets) = (char **)
338  nmem_malloc(mem, pro->num_proposedCharSets * sizeof(char *));
339 
340  for (i = 0; i < pro->num_proposedCharSets; i++)
341  {
342  (*charsets)[i] = 0;
343 
344  if (pro->proposedCharSets[i]->which ==
346  pro->proposedCharSets[i]->u.zprivate->which ==
348  {
349  Z_External *pext =
351 
352  if (pext->which == Z_External_octet)
353  {
354  (*charsets)[i] = (char *)
355  nmem_malloc(mem, (1+pext->u.octet_aligned->len) *
356  sizeof(char));
357 
358  memcpy((*charsets)[i], pext->u.octet_aligned->buf,
359  pext->u.octet_aligned->len);
360  (*charsets)[i][pext->u.octet_aligned->len] = 0;
361  }
362  }
363  else if (pro->proposedCharSets[i]->which ==
365  (*charsets)[i] = set_form(
367  }
368  }
369  else
370  *num_charsets = 0;
371  }
372 
373  if (langs && num_langs)
374  {
375  if (pro->num_proposedlanguages)
376  {
377  *num_langs = pro->num_proposedlanguages;
378 
379  (*langs) = (char **)
380  nmem_malloc(mem, pro->num_proposedlanguages * sizeof(char *));
381 
382  for (i = 0; i < pro->num_proposedlanguages; i++)
383  (*langs)[i] = nmem_strdup(mem, pro->proposedlanguages[i]);
384  }
385  else
386  *num_langs = 0;
387  }
388 
389  if (pro->recordsInSelectedCharSets && selected)
390  *selected = *pro->recordsInSelectedCharSets;
391 }
392 
393 /* Return charset, lang, selected from negotiation.. Client side */
395  char **charset, char **lang, int *selected)
396 {
397  Z_TargetResponse *res = p->u.response;
398 
399  if (charset && res->which == Z_TargetResponse_private &&
401  {
402  Z_External *pext = res->u.zprivate->u.externallySpecified;
403 
404  if (pext->which == Z_External_octet)
405  {
406  *charset = (char *)
407  nmem_malloc(mem, (1+pext->u.octet_aligned->len)*sizeof(char));
408  memcpy(*charset, pext->u.octet_aligned->buf,
409  pext->u.octet_aligned->len);
410  (*charset)[pext->u.octet_aligned->len] = 0;
411  }
412  }
413  if (charset && res->which == Z_TargetResponse_iso10646)
414  *charset = set_form(res->u.iso10646->encodingLevel);
415  if (lang && res->selectedLanguage)
416  *lang = nmem_strdup(mem, res->selectedLanguage);
417 
418  if (selected && res->recordsInSelectedCharSets)
419  *selected = *res->recordsInSelectedCharSets;
420 }
421 /*
422  * Local variables:
423  * c-basic-offset: 4
424  * c-file-style: "Stroustrup"
425  * indent-tabs-mode: nil
426  * End:
427  * vim: shiftwidth=4 tabstop=8 expandtab
428  */
429