2 $ $Id: charneg.c,v 1.1 2003-10-27 12:21:30 adam Exp $
3 * Helper functions for Character Set and Language Negotiation - 3
7 #include <yaz/otherinfo.h>
8 #include <yaz/z-charneg.h>
9 #include <yaz/charneg.h>
10 #include <yaz/yaz-util.h>
12 static Z_External* z_ext_record2(ODR o, int oid_class, int oid_value,
17 int len = strlen(buf);
19 if (!(p = (Z_External *)odr_malloc(o, sizeof(*p)))) return 0;
22 p->indirect_reference = 0;
24 oid.proto = PROTO_Z3950;
25 oid.oclass = (enum oid_class) oid_class;
26 oid.value = (enum oid_value) oid_value;
27 p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
29 p->which = Z_External_octet;
30 if (!(p->u.octet_aligned = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct)))) {
33 if (!(p->u.octet_aligned->buf = (unsigned char *)odr_malloc(o, len))) {
36 p->u.octet_aligned->len = p->u.octet_aligned->size = len;
37 memcpy(p->u.octet_aligned->buf, buf, len);
42 static int get_form(const char *charset)
47 if (!yaz_matchstr(charset, "UCS-2"))
49 if (!yaz_matchstr(charset, "UCS-4"))
51 if (!yaz_matchstr(charset, "UTF-16"))
53 if (!yaz_matchstr(charset, "UTF-8"))
59 static char *set_form (Odr_oid *encoding)
61 static char *charset = 0;
62 if ( oid_oidlen(encoding) != 6)
75 static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
77 int form = get_form (charset);
78 Z_OriginProposal_0 *p0 =
79 (Z_OriginProposal_0*)odr_malloc(o, sizeof(*p0));
81 memset(p0, 0, sizeof(*p0));
84 { /* ISO 10646 (UNICODE) */
87 Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
88 p0->which = Z_OriginProposal_0_iso10646;
91 sprintf (oidname, "1.0.10646.1.0.%d", form);
92 is->encodingLevel = odr_getoidbystr (o, oidname);
96 Z_PrivateCharacterSet *pc =
97 (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
99 memset(pc, 0, sizeof(*pc));
101 p0->which = Z_OriginProposal_0_private;
104 pc->which = Z_PrivateCharacterSet_externallySpecified;
105 pc->u.externallySpecified =
106 z_ext_record2(o, CLASS_NEGOT, VAL_ID_CHARSET, charset);
111 static Z_OriginProposal *z_get_OriginProposal(
112 ODR o, const char **charsets, int num_charsets,
113 const char **langs, int num_langs, int selected)
116 Z_OriginProposal *p = (Z_OriginProposal *) odr_malloc(o, sizeof(*p));
118 memset(p, 0, sizeof(*p));
120 p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
121 *p->recordsInSelectedCharSets = (selected) ? 1:0;
123 if (charsets && num_charsets) {
125 p->num_proposedCharSets = num_charsets;
126 p->proposedCharSets =
127 (Z_OriginProposal_0**)
128 odr_malloc(o, num_charsets*sizeof(Z_OriginProposal_0*));
130 for (i = 0; i<num_charsets; i++)
131 p->proposedCharSets[i] =
132 z_get_OriginProposal_0(o, charsets[i]);
134 if (langs && num_langs) {
136 p->num_proposedlanguages = num_langs;
138 p->proposedlanguages =
139 (char **) odr_malloc(o, num_langs*sizeof(char *));
141 for (i = 0; i<num_langs; i++) {
143 p->proposedlanguages[i] = (char *)langs[i];
150 static Z_CharSetandLanguageNegotiation *z_get_CharSetandLanguageNegotiation(
153 Z_CharSetandLanguageNegotiation *p =
154 (Z_CharSetandLanguageNegotiation *) odr_malloc(o, sizeof(*p));
156 memset(p, 0, sizeof(*p));
161 /* Create EXTERNAL for negotation proposal. Client side */
162 Z_External *yaz_set_proposal_charneg(ODR o,
163 const char **charsets, int num_charsets,
164 const char **langs, int num_langs,
167 Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
171 p->indirect_reference = 0;
173 oid.proto = PROTO_Z3950;
174 oid.oclass = CLASS_NEGOT;
175 oid.value = VAL_CHARNEG3;
176 p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
178 p->which = Z_External_charSetandLanguageNegotiation;
179 p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
180 p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_proposal;
181 p->u.charNeg3->u.proposal =
182 z_get_OriginProposal(o, charsets, num_charsets,
183 langs, num_langs, selected);
188 /* used by yaz_set_response_charneg */
189 static Z_TargetResponse *z_get_TargetResponse(ODR o, const char *charset,
190 const char *lang, int selected)
192 Z_TargetResponse *p = (Z_TargetResponse *) odr_malloc(o, sizeof(*p));
193 int form = get_form(charset);
195 memset(p, 0, sizeof(*p));
201 Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
202 p->which = Z_TargetResponse_iso10646;
205 sprintf (oidname, "1.0.10646.1.0.%d", form);
206 is->encodingLevel = odr_getoidbystr (o, oidname);
210 Z_PrivateCharacterSet *pc =
211 (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
213 memset(pc, 0, sizeof(*pc));
215 p->which = Z_TargetResponse_private;
218 pc->which = Z_PrivateCharacterSet_externallySpecified;
219 pc->u.externallySpecified =
220 z_ext_record2(o, CLASS_NEGOT, VAL_ID_CHARSET, charset);
222 p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
223 *p->recordsInSelectedCharSets = (selected) ? 1:0;
225 p->selectedLanguage = lang ? (char *)odr_strdup(o, lang) : 0;
229 /* Create charset response. Server side */
230 Z_External *yaz_set_response_charneg(ODR o, const char *charset,
231 const char *lang, int selected)
233 Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
237 p->indirect_reference = 0;
239 oid.proto = PROTO_Z3950;
240 oid.oclass = CLASS_NEGOT;
241 oid.value = VAL_CHARNEG3;
242 p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
244 p->which = Z_External_charSetandLanguageNegotiation;
245 p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
246 p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_response;
247 p->u.charNeg3->u.response = z_get_TargetResponse(o, charset, lang, selected);
252 /* Get negotiation from OtherInformation. Client&Server side */
253 Z_CharSetandLanguageNegotiation *yaz_get_charneg_record(Z_OtherInformation *p)
261 for (i=0; i<p->num_elements; i++) {
263 if ((p->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
264 (pext = p->list[i]->information.externallyDefinedInfo)) {
266 oident *ent = oid_getentbyoid(pext->direct_reference);
268 if (ent && ent->value == VAL_CHARNEG3 && ent->oclass == CLASS_NEGOT &&
269 pext->which == Z_External_charSetandLanguageNegotiation) {
271 return pext->u.charNeg3;
278 /* Get charsets, langs, selected from negotiation.. Server side */
279 void yaz_get_proposal_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
280 char ***charsets, int *num_charsets,
281 char ***langs, int *num_langs, int *selected)
284 Z_OriginProposal *pro = p->u.proposal;
286 if (num_charsets && charsets)
288 if (pro->num_proposedCharSets)
290 *num_charsets = pro->num_proposedCharSets;
292 (*charsets) = (char **)
293 nmem_malloc(mem, pro->num_proposedCharSets * sizeof(char *));
295 for (i=0; i<pro->num_proposedCharSets; i++)
299 if (pro->proposedCharSets[i]->which ==
300 Z_OriginProposal_0_private &&
301 pro->proposedCharSets[i]->u.zprivate->which ==
302 Z_PrivateCharacterSet_externallySpecified) {
305 pro->proposedCharSets[i]->u.zprivate->u.externallySpecified;
307 if (pext->which == Z_External_octet) {
309 (*charsets)[i] = (char *)
310 nmem_malloc(mem, (1+pext->u.octet_aligned->len) *
313 memcpy ((*charsets)[i], pext->u.octet_aligned->buf,
314 pext->u.octet_aligned->len);
315 (*charsets)[i][pext->u.octet_aligned->len] = 0;
319 else if (pro->proposedCharSets[i]->which ==
320 Z_OriginProposal_0_iso10646)
321 (*charsets)[i] = set_form (
322 pro->proposedCharSets[i]->u.iso10646->encodingLevel);
329 if (langs && num_langs)
331 if (pro->num_proposedlanguages)
333 *num_langs = pro->num_proposedlanguages;
336 nmem_malloc(mem, pro->num_proposedlanguages * sizeof(char *));
338 for (i=0; i<pro->num_proposedlanguages; i++)
339 (*langs)[i] = nmem_strdup(mem, pro->proposedlanguages[i]);
345 if(pro->recordsInSelectedCharSets && selected)
346 *selected = *pro->recordsInSelectedCharSets;
349 /* Return charset, lang, selected from negotiation.. Client side */
350 void yaz_get_response_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
351 char **charset, char **lang, int *selected)
353 Z_TargetResponse *res = p->u.response;
355 if (charset && res->which == Z_TargetResponse_private &&
356 res->u.zprivate->which == Z_PrivateCharacterSet_externallySpecified) {
358 Z_External *pext = res->u.zprivate->u.externallySpecified;
360 if (pext->which == Z_External_octet) {
363 nmem_malloc(mem, (1+pext->u.octet_aligned->len)*sizeof(char));
364 memcpy (*charset, pext->u.octet_aligned->buf,
365 pext->u.octet_aligned->len);
366 (*charset)[pext->u.octet_aligned->len] = 0;
369 if (charset && res->which == Z_TargetResponse_iso10646)
370 *charset = set_form (res->u.iso10646->encodingLevel);
371 if (lang && res->selectedLanguage)
372 *lang = nmem_strdup (mem, res->selectedLanguage);
374 if(selected && res->recordsInSelectedCharSets)
375 *selected = *res->recordsInSelectedCharSets;