YAZ  5.23.1
charneg.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  */
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;
33  p->u.octet_aligned =
34  odr_create_Odr_oct(o, buf, len);
35  return p;
36 }
37 
38 static int get_form(const char *charset)
39 {
40  int form = -1;
41 
42  if (!yaz_matchstr(charset, "UCS-2"))
43  form = 2;
44  if (!yaz_matchstr(charset, "UCS-4"))
45  form = 4;
46  if (!yaz_matchstr(charset, "UTF-16"))
47  form = 5;
48  if (!yaz_matchstr(charset, "UTF-8"))
49  form = 8;
50 
51  return form;
52 }
53 
54 static char *set_form(Odr_oid *encoding)
55 {
56  static char *charset = 0;
57  if ( oid_oidlen(encoding) != 6)
58  return 0;
59  if (encoding[5] == 2)
60  charset = "UCS-2";
61  if (encoding[5] == 4)
62  charset = "UCS-4";
63  if (encoding[5] == 5)
64  charset = "UTF-16";
65  if (encoding[5] == 8)
66  charset = "UTF-8";
67  return charset;
68 }
69 
70 static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
71 {
72  int form = get_form(charset);
73  Z_OriginProposal_0 *p0 =
74  (Z_OriginProposal_0*)odr_malloc(o, sizeof(*p0));
75 
76  memset(p0, 0, sizeof(*p0));
77 
78  if (form > 0)
79  { /* ISO 10646 (UNICODE) */
80  char oidname[20];
81 
82  Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc(o, sizeof(*is));
84  p0->u.iso10646 = is;
85  is->collections = 0;
86  sprintf(oidname, "1.0.10646.1.0.%d", form);
87  is->encodingLevel = odr_getoidbystr(o, oidname);
88  }
89  else
90  { /* private ones */
92  (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
93 
94  memset(pc, 0, sizeof(*pc));
95 
97  p0->u.zprivate = pc;
98 
100  pc->u.externallySpecified = z_ext_record2(o, charset);
101  }
102  return p0;
103 }
104 
106  ODR o, const char **charsets, int num_charsets,
107  const char **langs, int num_langs, int selected)
108 {
109  int i;
110  Z_OriginProposal *p = (Z_OriginProposal *) odr_malloc(o, sizeof(*p));
111 
112  memset(p, 0, sizeof(*p));
113 
115  *p->recordsInSelectedCharSets = (selected) ? 1 : 0;
116 
117  if (charsets && num_charsets)
118  {
119  p->num_proposedCharSets = num_charsets;
120  p->proposedCharSets =
122  odr_malloc(o, num_charsets*sizeof(Z_OriginProposal_0*));
123 
124  for (i = 0; i < num_charsets; i++)
125  p->proposedCharSets[i] =
126  z_get_OriginProposal_0(o, charsets[i]);
127  }
128  if (langs && num_langs)
129  {
130  p->num_proposedlanguages = num_langs;
131  p->proposedlanguages =
132  (char **) odr_malloc(o, num_langs*sizeof(char *));
133 
134  for (i = 0; i < num_langs; i++)
135  p->proposedlanguages[i] = (char *)langs[i];
136  }
137  return p;
138 }
139 
141  ODR o)
142 {
144  (Z_CharSetandLanguageNegotiation *) odr_malloc(o, sizeof(*p));
145 
146  memset(p, 0, sizeof(*p));
147 
148  return p;
149 }
150 
151 /* Create EXTERNAL for negotation proposal. Client side */
153  const char **charsets, int num_charsets,
154  const char **langs, int num_langs,
155  int selected)
156 {
157  Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
158 
159  p->descriptor = 0;
160  p->indirect_reference = 0;
161 
163 
167  p->u.charNeg3->u.proposal =
168  z_get_OriginProposal(o, charsets, num_charsets,
169  langs, num_langs, selected);
170 
171  return p;
172 }
173 
175  const char *delim,
176  const char *charset_list,
177  const char *lang_list,
178  int selected)
179 {
180  char **charsets_addresses = 0;
181  char **langs_addresses = 0;
182  int charsets_count = 0;
183  int langs_count = 0;
184 
185  if (charset_list)
186  nmem_strsplit(odr_getmem(o), delim, charset_list,
187  &charsets_addresses, &charsets_count);
188  if (lang_list)
189  nmem_strsplit(odr_getmem(o), delim, lang_list,
190  &langs_addresses, &langs_count);
191  return yaz_set_proposal_charneg(o,
192  (const char **) charsets_addresses,
193  charsets_count,
194  (const char **) langs_addresses,
195  langs_count,
196  selected);
197 }
198 
199 
200 /* used by yaz_set_response_charneg */
201 static Z_TargetResponse *z_get_TargetResponse(ODR o, const char *charset,
202  const char *lang, int selected)
203 {
204  Z_TargetResponse *p = (Z_TargetResponse *) odr_malloc(o, sizeof(*p));
205  int form = get_form(charset);
206 
207  memset(p, 0, sizeof(*p));
208  if (form > 0)
209  {
210  char oidname[20];
211 
212  Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
214  p->u.iso10646 = is;
215  is->collections = 0;
216  sprintf(oidname, "1.0.10646.1.0.%d", form);
217  is->encodingLevel = odr_getoidbystr (o, oidname);
218  }
219  else
220  {
222  (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
223 
224  memset(pc, 0, sizeof(*pc));
225 
227  p->u.zprivate = pc;
228 
230  pc->u.externallySpecified =
231  z_ext_record2(o, charset);
232  }
234  *p->recordsInSelectedCharSets = (selected) ? 1 : 0;
235 
236  p->selectedLanguage = lang ? (char *) odr_strdup(o, lang) : 0;
237  return p;
238 }
239 
240 /* Create charset response. Server side */
241 Z_External *yaz_set_response_charneg(ODR o, const char *charset,
242  const char *lang, int selected)
243 {
244  Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
245 
246  p->descriptor = 0;
247  p->indirect_reference = 0;
248 
250 
254  p->u.charNeg3->u.response = z_get_TargetResponse(o, charset, lang, selected);
255 
256  return p;
257 }
258 
259 /* Get negotiation from OtherInformation. Client&Server side */
261 {
262  int i;
263 
264  if (!p)
265  return 0;
266 
267  for (i = 0; i < p->num_elements; i++)
268  {
269  Z_External *pext;
270  if ((p->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
271  (pext = p->list[i]->information.externallyDefinedInfo))
272  {
275  {
276  return pext->u.charNeg3;
277  }
278  }
279  }
280  return 0;
281 }
282 
283 /* Delete negotiation from OtherInformation. Client&Server side */
285 {
286  int i;
287 
288  if (!*p)
289  return 0;
290 
291  for (i = 0; i < (*p)->num_elements; i++)
292  {
293  Z_External *pext;
294  if (((*p)->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
295  (pext = (*p)->list[i]->information.externallyDefinedInfo))
296  {
299  {
300  if ((*p)->num_elements <= 1)
301  *p = 0;
302  else
303  {
304  --((*p)->num_elements);
305  for (; i < (*p)->num_elements; i++)
306  (*p)->list[i] = (*p)->list[i+1];
307  }
308  return 1;
309  }
310  }
311  }
312  return 0;
313 }
314 
315 
316 /* Get charsets, langs, selected from negotiation.. Server side */
318  char ***charsets, int *num_charsets,
319  char ***langs, int *num_langs, int *selected)
320 {
321  int i;
322  Z_OriginProposal *pro = p->u.proposal;
323 
324  if (num_charsets && charsets)
325  {
326  if (pro->num_proposedCharSets)
327  {
328  *num_charsets = pro->num_proposedCharSets;
329 
330  (*charsets) = (char **)
331  nmem_malloc(mem, pro->num_proposedCharSets * sizeof(char *));
332 
333  for (i = 0; i < pro->num_proposedCharSets; i++)
334  {
335  (*charsets)[i] = 0;
336 
337  if (pro->proposedCharSets[i]->which ==
339  pro->proposedCharSets[i]->u.zprivate->which ==
341  {
342  Z_External *pext =
344 
345  if (pext->which == Z_External_octet)
346  {
347  (*charsets)[i] = (char *)
348  nmem_malloc(mem, (1+pext->u.octet_aligned->len) *
349  sizeof(char));
350 
351  memcpy((*charsets)[i], pext->u.octet_aligned->buf,
352  pext->u.octet_aligned->len);
353  (*charsets)[i][pext->u.octet_aligned->len] = 0;
354  }
355  }
356  else if (pro->proposedCharSets[i]->which ==
358  (*charsets)[i] = set_form(
360  }
361  }
362  else
363  *num_charsets = 0;
364  }
365 
366  if (langs && num_langs)
367  {
368  if (pro->num_proposedlanguages)
369  {
370  *num_langs = pro->num_proposedlanguages;
371 
372  (*langs) = (char **)
373  nmem_malloc(mem, pro->num_proposedlanguages * sizeof(char *));
374 
375  for (i = 0; i < pro->num_proposedlanguages; i++)
376  (*langs)[i] = nmem_strdup(mem, pro->proposedlanguages[i]);
377  }
378  else
379  *num_langs = 0;
380  }
381 
382  if (pro->recordsInSelectedCharSets && selected)
383  *selected = *pro->recordsInSelectedCharSets;
384 }
385 
386 /* Return charset, lang, selected from negotiation.. Client side */
388  char **charset, char **lang, int *selected)
389 {
390  Z_TargetResponse *res = p->u.response;
391 
392  if (charset && res->which == Z_TargetResponse_private &&
394  {
395  Z_External *pext = res->u.zprivate->u.externallySpecified;
396 
397  if (pext->which == Z_External_octet)
398  {
399  *charset = (char *)
400  nmem_malloc(mem, (1+pext->u.octet_aligned->len)*sizeof(char));
401  memcpy(*charset, pext->u.octet_aligned->buf,
402  pext->u.octet_aligned->len);
403  (*charset)[pext->u.octet_aligned->len] = 0;
404  }
405  }
406  if (charset && res->which == Z_TargetResponse_iso10646)
407  *charset = set_form(res->u.iso10646->encodingLevel);
408  if (lang && res->selectedLanguage)
409  *lang = nmem_strdup(mem, res->selectedLanguage);
410 
411  if (selected && res->recordsInSelectedCharSets)
412  *selected = *res->recordsInSelectedCharSets;
413 }
414 /*
415  * Local variables:
416  * c-basic-offset: 4
417  * c-file-style: "Stroustrup"
418  * indent-tabs-mode: nil
419  * End:
420  * vim: shiftwidth=4 tabstop=8 expandtab
421  */
422 
static int get_form(const char *charset)
Definition: charneg.c:38
Odr_oid * collections
Definition: z-charneg.h:182
void nmem_strsplit(NMEM nmem, const char *delim, const char *dstr, char ***darray, int *num)
allocates sub strings out of string using certain delimitors
Definition: nmemsdup.c:61
Odr_bool * recordsInSelectedCharSets
Definition: z-charneg.h:87
char * buf
Definition: odr.h:101
Z_External * yaz_set_proposal_charneg(ODR o, const char **charsets, int num_charsets, const char **langs, int num_langs, int selected)
Definition: charneg.c:152
#define Z_PrivateCharacterSet_externallySpecified
Definition: z-charneg.h:118
Z_Iso10646 * iso10646
Definition: z-charneg.h:94
char * odr_strdup(ODR o, const char *str)
Definition: odr_mem.c:36
#define Z_OriginProposal_0_iso10646
Definition: z-charneg.h:77
union Z_TargetResponse::@42 u
static Z_OriginProposal * z_get_OriginProposal(ODR o, const char **charsets, int num_charsets, const char **langs, int num_langs, int selected)
Definition: charneg.c:105
#define Z_CharSetandLanguageNegotiation_proposal
Definition: z-charneg.h:65
Odr_oid * direct_reference
Definition: prt-ext.h:60
int oid_oidcmp(const Odr_oid *o1, const Odr_oid *o2)
compares OIDs
Definition: oid_util.c:34
void yaz_get_response_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p, char **charset, char **lang, int *selected)
Definition: charneg.c:387
Header for common YAZ utilities.
#define Z_CharSetandLanguageNegotiation_response
Definition: z-charneg.h:66
static Z_CharSetandLanguageNegotiation * z_get_CharSetandLanguageNegotiation(ODR o)
Definition: charneg.c:140
short Odr_oid
Definition: oid_util.h:42
void * nmem_malloc(NMEM n, size_t size)
allocates memory block on NMEM handle
Definition: nmem.c:145
void * odr_malloc(ODR o, size_t size)
Definition: odr_mem.c:31
const Odr_oid yaz_oid_negot_charset_3[]
Definition: oid_std.c:140
Z_TargetResponse * response
Definition: z-charneg.h:64
Header for OID database.
union Z_External::@30 u
int which
Definition: prt-ext.h:63
Z_External * yaz_set_proposal_charneg_list(ODR o, const char *delim, const char *charset_list, const char *lang_list, int selected)
Definition: charneg.c:174
Z_External * externallySpecified
Definition: z-charneg.h:115
Header for Z39.50 OtherInfo utilities.
int num_proposedCharSets
Definition: z-charneg.h:83
Odr_oid * odr_getoidbystr(ODR o, const char *str)
Definition: odr_util.c:77
int yaz_del_charneg_record(Z_OtherInformation **p)
Definition: charneg.c:284
union Z_OriginProposal_0::@41 u
union Z_CharSetandLanguageNegotiation::@40 u
Z_External * externallyDefinedInfo
Definition: z-core.h:1285
char * descriptor
Definition: prt-ext.h:62
Z_PrivateCharacterSet * zprivate
Definition: z-charneg.h:95
char * nmem_strdup(NMEM mem, const char *src)
allocates string on NMEM handle (similar strdup)
Definition: nmemsdup.c:18
Odr_bool * recordsInSelectedCharSets
Definition: z-charneg.h:103
const Odr_oid yaz_oid_negot_charset_id[]
Definition: oid_std.c:142
Odr_int * indirect_reference
Definition: prt-ext.h:61
ASN.1 Module NegotiationRecordDefinition-charSetandLanguageNegotiation-3.
static Z_External * z_ext_record2(ODR o, const char *buf)
Definition: charneg.c:22
Z_OriginProposal * proposal
Definition: z-charneg.h:63
#define Z_TargetResponse_private
Definition: z-charneg.h:99
Definition: odr.h:124
int num_proposedlanguages
Definition: z-charneg.h:85
Z_LanguageCode ** proposedlanguages
Definition: z-charneg.h:86
int yaz_matchstr(const char *s1, const char *s2)
match strings - independent of case and &#39;-&#39;
Definition: matchstr.c:42
#define Z_External_charSetandLanguageNegotiation
Definition: prt-ext.h:88
Z_External * yaz_set_response_charneg(ODR o, const char *charset, const char *lang, int selected)
Definition: charneg.c:241
static Z_TargetResponse * z_get_TargetResponse(ODR o, const char *charset, const char *lang, int selected)
Definition: charneg.c:201
Z_OriginProposal_0 ** proposedCharSets
Definition: z-charneg.h:84
Odr_oid * odr_oiddup(ODR odr, const Odr_oid *o)
Definition: odr_util.c:60
int oid_oidlen(const Odr_oid *o)
returns length of OIDs
Definition: oid_util.c:49
#define Z_External_octet
Definition: prt-ext.h:66
Z_CharSetandLanguageNegotiation * charNeg3
Definition: prt-ext.h:132
union Z_OtherInformationUnit::@74 information
structure for all known EXTERNALs
Definition: prt-ext.h:58
#define odr_getmem(o)
Definition: odr.h:216
#define Z_OtherInfo_externallyDefinedInfo
Definition: z-core.h:1289
static char * set_form(Odr_oid *encoding)
Definition: charneg.c:54
Z_Iso10646 * iso10646
Definition: z-charneg.h:74
void yaz_get_proposal_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p, char ***charsets, int *num_charsets, char ***langs, int *num_langs, int *selected)
Definition: charneg.c:317
#define Z_OriginProposal_0_private
Definition: z-charneg.h:78
Z_LanguageCode * selectedLanguage
Definition: z-charneg.h:102
#define bool_t
Definition: odr.h:52
#define Z_TargetResponse_iso10646
Definition: z-charneg.h:98
Z_CharSetandLanguageNegotiation * yaz_get_charneg_record(Z_OtherInformation *p)
Definition: charneg.c:260
union Z_PrivateCharacterSet::@43 u
Odr_oid * encodingLevel
Definition: z-charneg.h:183
Z_PrivateCharacterSet * zprivate
Definition: z-charneg.h:75
Z_OtherInformationUnit ** list
Definition: z-core.h:1296
static Z_OriginProposal_0 * z_get_OriginProposal_0(ODR o, const char *charset)
Definition: charneg.c:70
Header for Z39.50 Charset negotiation utilities.
Odr_oct * odr_create_Odr_oct(ODR o, const char *buf, int sz)
Definition: odr_mem.c:66
Odr_oct * octet_aligned
Definition: prt-ext.h:105
int len
Definition: odr.h:102