2 $ $Id: charneg.c,v 1.4 2002-07-25 12:50:17 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>
11 static Z_External* z_ext_record2(ODR o, int oid_class, int oid_value,
12 const char *buf, int len)
17 if (!(p = (Z_External *)odr_malloc(o, sizeof(*p)))) return 0;
20 p->indirect_reference = 0;
22 oid.proto = PROTO_Z3950;
23 oid.oclass = oid_class;
24 oid.value = oid_value;
25 p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
27 p->which = Z_External_octet;
28 if (!(p->u.octet_aligned = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct)))) {
31 if (!(p->u.octet_aligned->buf = (unsigned char *)odr_malloc(o, len))) {
34 p->u.octet_aligned->len = p->u.octet_aligned->size = len;
35 memcpy(p->u.octet_aligned->buf, buf, len);
40 static int get_form(const char *charset)
45 if (!strcmp (charset, "UCS-2"))
47 if (!strcmp (charset, "UCS-4"))
49 if (!strcmp (charset, "UTF-16"))
51 if (!strcmp (charset, "UTF-8"))
57 static char *set_form (Odr_oid *encoding)
59 static char *charset = 0;
60 if ( oid_oidlen(encoding) != 6)
73 static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
75 int form = get_form (charset);
76 Z_OriginProposal_0 *p0 =
77 (Z_OriginProposal_0*)odr_malloc(o, sizeof(*p0));
79 memset(p0, 0, sizeof(*p0));
82 { /* ISO 10646 (UNICODE) */
85 Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
86 p0->which = Z_OriginProposal_0_iso10646;
89 sprintf (oidname, "1.0.10646.1.0.%d", form);
90 is->encodingLevel = odr_getoidbystr (o, oidname);
94 Z_PrivateCharacterSet *pc =
95 (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
98 memset(pc, 0, sizeof(*pc));
100 p0->which = Z_OriginProposal_0_private;
103 pc->which = Z_PrivateCharacterSet_externallySpecified;
104 pc->u.externallySpecified =
105 z_ext_record2(o, CLASS_RECSYN, VAL_NOP, charset, strlen(charset));
110 static Z_OriginProposal *z_get_OriginProposal(
111 ODR o, const char **charsets, int num_charsets,
112 const char **langs, int num_langs, int selected)
115 Z_OriginProposal *p = (Z_OriginProposal *) odr_malloc(o, sizeof(*p));
117 memset(p, 0, sizeof(*p));
119 p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
120 *p->recordsInSelectedCharSets = (selected) ? 1:0;
122 if (charsets && num_charsets) {
124 p->num_proposedCharSets = num_charsets;
125 p->proposedCharSets =
126 (Z_OriginProposal_0**)
127 odr_malloc(o, num_charsets*sizeof(Z_OriginProposal_0*));
129 for (i = 0; i<num_charsets; i++)
130 p->proposedCharSets[i] =
131 z_get_OriginProposal_0(o, charsets[i]);
133 if (langs && num_langs) {
135 p->num_proposedlanguages = num_langs;
137 p->proposedlanguages =
138 (char **) odr_malloc(o, num_langs*sizeof(char *));
140 for (i = 0; i<num_langs; i++) {
142 p->proposedlanguages[i] = (char *)langs[i];
149 static Z_CharSetandLanguageNegotiation *z_get_CharSetandLanguageNegotiation(
152 Z_CharSetandLanguageNegotiation *p =
153 (Z_CharSetandLanguageNegotiation *) odr_malloc(o, sizeof(*p));
155 memset(p, 0, sizeof(*p));
160 Z_External *yaz_set_proposal_charneg(ODR o,
161 const char **charsets, int num_charsets,
162 const char **langs, int num_langs,
165 Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
169 p->indirect_reference = 0;
171 oid.proto = PROTO_Z3950;
172 oid.oclass = CLASS_NEGOT;
173 oid.value = VAL_CHARNEG3;
174 p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
176 p->which = Z_External_charSetandLanguageNegotiation;
177 p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
178 p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_proposal;
179 p->u.charNeg3->u.proposal =
180 z_get_OriginProposal(o, charsets, num_charsets,
181 langs, num_langs, selected);
186 static Z_TargetResponse *z_get_TargetResponse(ODR o, const char *charset,
187 const char *lang, int selected)
189 Z_TargetResponse *p = (Z_TargetResponse *) odr_malloc(o, sizeof(*p));
190 int form = get_form(charset);
192 memset(p, 0, sizeof(*p));
198 Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
199 p->which = Z_TargetResponse_iso10646;
202 sprintf (oidname, "1.0.10646.1.0.%d", form);
203 is->encodingLevel = odr_getoidbystr (o, oidname);
207 Z_PrivateCharacterSet *pc =
208 (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
210 memset(pc, 0, sizeof(*pc));
212 p->which = Z_TargetResponse_private;
215 pc->which = Z_PrivateCharacterSet_externallySpecified;
216 pc->u.externallySpecified =
217 z_ext_record2(o, CLASS_RECSYN, VAL_NOP, charset, strlen(charset));
219 p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
220 *p->recordsInSelectedCharSets = (selected) ? 1:0;
222 p->selectedLanguage = lang ? (char *)odr_strdup(o, lang) : 0;
226 Z_External *yaz_set_response_charneg(ODR o, const char *charset,
227 const char *lang, int selected)
229 Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
233 p->indirect_reference = 0;
235 oid.proto = PROTO_Z3950;
236 oid.oclass = CLASS_NEGOT;
237 oid.value = VAL_CHARNEG3;
238 p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
240 p->which = Z_External_charSetandLanguageNegotiation;
241 p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
242 p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_response;
243 p->u.charNeg3->u.response = z_get_TargetResponse(o, charset, lang, selected);
248 Z_CharSetandLanguageNegotiation *yaz_get_charneg_record(Z_OtherInformation *p)
256 for (i=0; i<p->num_elements; i++) {
258 if ((p->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
259 (pext = p->list[i]->information.externallyDefinedInfo)) {
261 oident *ent = oid_getentbyoid(pext->direct_reference);
263 if (ent && ent->value == VAL_CHARNEG3 && ent->oclass == CLASS_NEGOT &&
264 pext->which == Z_External_charSetandLanguageNegotiation) {
266 return pext->u.charNeg3;
274 void yaz_get_proposal_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
275 char ***charsets, int *num_charsets,
276 char ***langs, int *num_langs, int *selected)
279 Z_OriginProposal *pro = p->u.proposal;
281 if (num_charsets && charsets)
283 if (pro->num_proposedCharSets)
285 *num_charsets = pro->num_proposedCharSets;
287 (*charsets) = (char **)
288 nmem_malloc(mem, pro->num_proposedCharSets * sizeof(char *));
290 for (i=0; i<pro->num_proposedCharSets; i++)
294 if (pro->proposedCharSets[i]->which ==
295 Z_OriginProposal_0_private &&
296 pro->proposedCharSets[i]->u.zprivate->which ==
297 Z_PrivateCharacterSet_externallySpecified) {
300 pro->proposedCharSets[i]->u.zprivate->u.externallySpecified;
302 if (pext->which == Z_External_octet) {
304 (*charsets)[i] = (char *)
305 nmem_malloc(mem, (1+pext->u.octet_aligned->len) *
308 memcpy ((*charsets)[i], pext->u.octet_aligned->buf,
309 pext->u.octet_aligned->len);
310 (*charsets)[i][pext->u.octet_aligned->len] = 0;
314 else if (pro->proposedCharSets[i]->which ==
315 Z_OriginProposal_0_iso10646)
316 (*charsets)[i] = set_form (
317 pro->proposedCharSets[i]->u.iso10646->encodingLevel);
324 if (langs && num_langs)
326 if (pro->num_proposedlanguages)
328 *num_langs = pro->num_proposedlanguages;
331 nmem_malloc(mem, pro->num_proposedlanguages * sizeof(char *));
333 for (i=0; i<pro->num_proposedlanguages; i++)
334 (*langs)[i] = nmem_strdup(mem, pro->proposedlanguages[i]);
340 if(pro->recordsInSelectedCharSets && selected)
341 *selected = *pro->recordsInSelectedCharSets;
344 void yaz_get_response_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
345 char **charset, char **lang, int *selected)
347 Z_TargetResponse *res = p->u.response;
349 if (charset && res->which == Z_TargetResponse_private &&
350 res->u.zprivate->which == Z_PrivateCharacterSet_externallySpecified) {
352 Z_External *pext = res->u.zprivate->u.externallySpecified;
354 if (pext->which == Z_External_octet) {
357 nmem_malloc(mem, (1+pext->u.octet_aligned->len)*sizeof(char));
358 memcpy (*charset, pext->u.octet_aligned->buf,
359 pext->u.octet_aligned->len);
360 (*charset)[pext->u.octet_aligned->len] = 0;
363 if (charset && res->which == Z_TargetResponse_iso10646)
364 *charset = set_form (res->u.iso10646->encodingLevel);
365 if (lang && res->selectedLanguage)
366 *lang = nmem_strdup (mem, res->selectedLanguage);
368 if(selected && res->recordsInSelectedCharSets)
369 *selected = *res->recordsInSelectedCharSets;