2 $ $Id: charneg.c,v 1.7 2002-10-04 19:06:25 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,
13 const char *buf, int len)
18 if (!(p = (Z_External *)odr_malloc(o, sizeof(*p)))) return 0;
21 p->indirect_reference = 0;
23 oid.proto = PROTO_Z3950;
24 oid.oclass = (enum oid_class) oid_class;
25 oid.value = (enum oid_value) oid_value;
26 p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
28 p->which = Z_External_octet;
29 if (!(p->u.octet_aligned = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct)))) {
32 if (!(p->u.octet_aligned->buf = (unsigned char *)odr_malloc(o, len))) {
35 p->u.octet_aligned->len = p->u.octet_aligned->size = len;
36 memcpy(p->u.octet_aligned->buf, buf, len);
41 static int get_form(const char *charset)
46 if (!yaz_matchstr(charset, "UCS-2"))
48 if (!yaz_matchstr(charset, "UCS-4"))
50 if (!yaz_matchstr(charset, "UTF-16"))
52 if (!yaz_matchstr(charset, "UTF-8"))
58 static char *set_form (Odr_oid *encoding)
60 static char *charset = 0;
61 if ( oid_oidlen(encoding) != 6)
74 static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
76 int form = get_form (charset);
77 Z_OriginProposal_0 *p0 =
78 (Z_OriginProposal_0*)odr_malloc(o, sizeof(*p0));
80 memset(p0, 0, sizeof(*p0));
83 { /* ISO 10646 (UNICODE) */
86 Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
87 p0->which = Z_OriginProposal_0_iso10646;
90 sprintf (oidname, "1.0.10646.1.0.%d", form);
91 is->encodingLevel = odr_getoidbystr (o, oidname);
95 Z_PrivateCharacterSet *pc =
96 (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_RECSYN, VAL_NOP, charset, strlen(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 Z_External *yaz_set_proposal_charneg(ODR o,
162 const char **charsets, int num_charsets,
163 const char **langs, int num_langs,
166 Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
170 p->indirect_reference = 0;
172 oid.proto = PROTO_Z3950;
173 oid.oclass = CLASS_NEGOT;
174 oid.value = VAL_CHARNEG3;
175 p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
177 p->which = Z_External_charSetandLanguageNegotiation;
178 p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
179 p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_proposal;
180 p->u.charNeg3->u.proposal =
181 z_get_OriginProposal(o, charsets, num_charsets,
182 langs, num_langs, selected);
187 static Z_TargetResponse *z_get_TargetResponse(ODR o, const char *charset,
188 const char *lang, int selected)
190 Z_TargetResponse *p = (Z_TargetResponse *) odr_malloc(o, sizeof(*p));
191 int form = get_form(charset);
193 memset(p, 0, sizeof(*p));
199 Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
200 p->which = Z_TargetResponse_iso10646;
203 sprintf (oidname, "1.0.10646.1.0.%d", form);
204 is->encodingLevel = odr_getoidbystr (o, oidname);
208 Z_PrivateCharacterSet *pc =
209 (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
211 memset(pc, 0, sizeof(*pc));
213 p->which = Z_TargetResponse_private;
216 pc->which = Z_PrivateCharacterSet_externallySpecified;
217 pc->u.externallySpecified =
218 z_ext_record2(o, CLASS_RECSYN, VAL_NOP, charset, strlen(charset));
220 p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
221 *p->recordsInSelectedCharSets = (selected) ? 1:0;
223 p->selectedLanguage = lang ? (char *)odr_strdup(o, lang) : 0;
227 Z_External *yaz_set_response_charneg(ODR o, const char *charset,
228 const char *lang, int selected)
230 Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
234 p->indirect_reference = 0;
236 oid.proto = PROTO_Z3950;
237 oid.oclass = CLASS_NEGOT;
238 oid.value = VAL_CHARNEG3;
239 p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
241 p->which = Z_External_charSetandLanguageNegotiation;
242 p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
243 p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_response;
244 p->u.charNeg3->u.response = z_get_TargetResponse(o, charset, lang, selected);
249 Z_CharSetandLanguageNegotiation *yaz_get_charneg_record(Z_OtherInformation *p)
257 for (i=0; i<p->num_elements; i++) {
259 if ((p->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
260 (pext = p->list[i]->information.externallyDefinedInfo)) {
262 oident *ent = oid_getentbyoid(pext->direct_reference);
264 if (ent && ent->value == VAL_CHARNEG3 && ent->oclass == CLASS_NEGOT &&
265 pext->which == Z_External_charSetandLanguageNegotiation) {
267 return pext->u.charNeg3;
275 void yaz_get_proposal_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
276 char ***charsets, int *num_charsets,
277 char ***langs, int *num_langs, int *selected)
280 Z_OriginProposal *pro = p->u.proposal;
282 if (num_charsets && charsets)
284 if (pro->num_proposedCharSets)
286 *num_charsets = pro->num_proposedCharSets;
288 (*charsets) = (char **)
289 nmem_malloc(mem, pro->num_proposedCharSets * sizeof(char *));
291 for (i=0; i<pro->num_proposedCharSets; i++)
295 if (pro->proposedCharSets[i]->which ==
296 Z_OriginProposal_0_private &&
297 pro->proposedCharSets[i]->u.zprivate->which ==
298 Z_PrivateCharacterSet_externallySpecified) {
301 pro->proposedCharSets[i]->u.zprivate->u.externallySpecified;
303 if (pext->which == Z_External_octet) {
305 (*charsets)[i] = (char *)
306 nmem_malloc(mem, (1+pext->u.octet_aligned->len) *
309 memcpy ((*charsets)[i], pext->u.octet_aligned->buf,
310 pext->u.octet_aligned->len);
311 (*charsets)[i][pext->u.octet_aligned->len] = 0;
315 else if (pro->proposedCharSets[i]->which ==
316 Z_OriginProposal_0_iso10646)
317 (*charsets)[i] = set_form (
318 pro->proposedCharSets[i]->u.iso10646->encodingLevel);
325 if (langs && num_langs)
327 if (pro->num_proposedlanguages)
329 *num_langs = pro->num_proposedlanguages;
332 nmem_malloc(mem, pro->num_proposedlanguages * sizeof(char *));
334 for (i=0; i<pro->num_proposedlanguages; i++)
335 (*langs)[i] = nmem_strdup(mem, pro->proposedlanguages[i]);
341 if(pro->recordsInSelectedCharSets && selected)
342 *selected = *pro->recordsInSelectedCharSets;
345 void yaz_get_response_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
346 char **charset, char **lang, int *selected)
348 Z_TargetResponse *res = p->u.response;
350 if (charset && res->which == Z_TargetResponse_private &&
351 res->u.zprivate->which == Z_PrivateCharacterSet_externallySpecified) {
353 Z_External *pext = res->u.zprivate->u.externallySpecified;
355 if (pext->which == Z_External_octet) {
358 nmem_malloc(mem, (1+pext->u.octet_aligned->len)*sizeof(char));
359 memcpy (*charset, pext->u.octet_aligned->buf,
360 pext->u.octet_aligned->len);
361 (*charset)[pext->u.octet_aligned->len] = 0;
364 if (charset && res->which == Z_TargetResponse_iso10646)
365 *charset = set_form (res->u.iso10646->encodingLevel);
366 if (lang && res->selectedLanguage)
367 *lang = nmem_strdup (mem, res->selectedLanguage);
369 if(selected && res->recordsInSelectedCharSets)
370 *selected = *res->recordsInSelectedCharSets;