YAZ 5.35.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
22static 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
38static 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
54static 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
70static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
71{
72 int form = get_form(charset);
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[28];
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;
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;
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{
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);
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 */
201static 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[28];
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
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 */
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;
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 {
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
static Z_External * z_ext_record2(ODR o, const char *buf)
Definition charneg.c:22
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
static Z_TargetResponse * z_get_TargetResponse(ODR o, const char *charset, const char *lang, int selected)
Definition charneg.c:201
static Z_CharSetandLanguageNegotiation * z_get_CharSetandLanguageNegotiation(ODR o)
Definition charneg.c:140
static Z_OriginProposal_0 * z_get_OriginProposal_0(ODR o, const char *charset)
Definition charneg.c:70
static char * set_form(Odr_oid *encoding)
Definition charneg.c:54
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
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
Z_External * yaz_set_response_charneg(ODR o, const char *charset, const char *lang, int selected)
Definition charneg.c:241
void yaz_get_response_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p, char **charset, char **lang, int *selected)
Definition charneg.c:387
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
Z_CharSetandLanguageNegotiation * yaz_get_charneg_record(Z_OtherInformation *p)
Definition charneg.c:260
int yaz_del_charneg_record(Z_OtherInformation **p)
Definition charneg.c:284
Header for Z39.50 Charset negotiation utilities.
int yaz_matchstr(const char *s1, const char *s2)
match strings - independent of case and '-'
Definition matchstr.c:42
void * nmem_malloc(NMEM n, size_t size)
allocates memory block on NMEM handle
Definition nmem.c:145
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
char * nmem_strdup(NMEM mem, const char *src)
allocates string on NMEM handle (similar strdup)
Definition nmemsdup.c:18
#define odr_getmem(o)
Definition odr.h:216
#define bool_t
Definition odr.h:52
Odr_oct * odr_create_Odr_oct(ODR o, const char *buf, int sz)
Definition odr_mem.c:66
void * odr_malloc(ODR o, size_t size)
Definition odr_mem.c:31
char * odr_strdup(ODR o, const char *str)
Definition odr_mem.c:36
Odr_oid * odr_oiddup(ODR odr, const Odr_oid *o)
Definition odr_util.c:60
Odr_oid * odr_getoidbystr(ODR o, const char *str)
Definition odr_util.c:77
Header for OID database.
const Odr_oid yaz_oid_negot_charset_3[]
Definition oid_std.c:140
const Odr_oid yaz_oid_negot_charset_id[]
Definition oid_std.c:142
int oid_oidcmp(const Odr_oid *o1, const Odr_oid *o2)
compares OIDs
Definition oid_util.c:34
int oid_oidlen(const Odr_oid *o)
returns length of OIDs
Definition oid_util.c:49
short Odr_oid
Definition oid_util.h:42
Header for Z39.50 OtherInfo utilities.
#define Z_External_octet
Definition prt-ext.h:66
#define Z_External_charSetandLanguageNegotiation
Definition prt-ext.h:88
union Z_CharSetandLanguageNegotiation::@37 u
Z_TargetResponse * response
Definition z-charneg.h:64
Z_OriginProposal * proposal
Definition z-charneg.h:63
structure for all known EXTERNALs
Definition prt-ext.h:59
Z_CharSetandLanguageNegotiation * charNeg3
Definition prt-ext.h:132
Odr_int * indirect_reference
Definition prt-ext.h:61
int which
Definition prt-ext.h:63
union Z_External::@27 u
Odr_oid * direct_reference
Definition prt-ext.h:60
Odr_oct * octet_aligned
Definition prt-ext.h:105
char * descriptor
Definition prt-ext.h:62
Odr_oid * encodingLevel
Definition z-charneg.h:183
Odr_oid * collections
Definition z-charneg.h:182
Z_PrivateCharacterSet * zprivate
Definition z-charneg.h:75
Z_Iso10646 * iso10646
Definition z-charneg.h:74
union Z_OriginProposal_0::@38 u
Z_LanguageCode ** proposedlanguages
Definition z-charneg.h:86
int num_proposedlanguages
Definition z-charneg.h:85
Z_OriginProposal_0 ** proposedCharSets
Definition z-charneg.h:84
int num_proposedCharSets
Definition z-charneg.h:83
Odr_bool * recordsInSelectedCharSets
Definition z-charneg.h:87
Z_External * externallyDefinedInfo
Definition z-core.h:1285
union Z_OtherInformationUnit::@71 information
Z_OtherInformationUnit ** list
Definition z-core.h:1296
Z_External * externallySpecified
Definition z-charneg.h:115
union Z_PrivateCharacterSet::@40 u
Z_PrivateCharacterSet * zprivate
Definition z-charneg.h:95
Odr_bool * recordsInSelectedCharSets
Definition z-charneg.h:103
Z_Iso10646 * iso10646
Definition z-charneg.h:94
union Z_TargetResponse::@39 u
Z_LanguageCode * selectedLanguage
Definition z-charneg.h:102
int len
Definition odr.h:102
char * buf
Definition odr.h:101
Definition odr.h:125
Header for common YAZ utilities.
ASN.1 Module NegotiationRecordDefinition-charSetandLanguageNegotiation-3.
#define Z_CharSetandLanguageNegotiation_proposal
Definition z-charneg.h:65
#define Z_OriginProposal_0_private
Definition z-charneg.h:78
#define Z_PrivateCharacterSet_externallySpecified
Definition z-charneg.h:118
#define Z_CharSetandLanguageNegotiation_response
Definition z-charneg.h:66
#define Z_OriginProposal_0_iso10646
Definition z-charneg.h:77
#define Z_TargetResponse_private
Definition z-charneg.h:99
#define Z_TargetResponse_iso10646
Definition z-charneg.h:98
#define Z_OtherInfo_externallyDefinedInfo
Definition z-core.h:1289