00001
00002
00003
00004
00005
00012 #include <stdio.h>
00013 #include <yaz/otherinfo.h>
00014 #include <yaz/z-charneg.h>
00015 #include <yaz/charneg.h>
00016 #include <yaz/yaz-util.h>
00017 #include <yaz/oid_db.h>
00018
00019 static Z_External* z_ext_record2(ODR o, const char *buf)
00020 {
00021 Z_External *p;
00022 int len = strlen(buf);
00023
00024 if (!(p = (Z_External *)odr_malloc(o, sizeof(*p)))) return 0;
00025
00026 p->descriptor = 0;
00027 p->indirect_reference = 0;
00028
00029 p->direct_reference = odr_oiddup(o, yaz_oid_negot_charset_id);
00030
00031 p->which = Z_External_octet;
00032 if (!(p->u.octet_aligned = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct)))) {
00033 return 0;
00034 }
00035 if (!(p->u.octet_aligned->buf = (unsigned char *)odr_malloc(o, len))) {
00036 return 0;
00037 }
00038 p->u.octet_aligned->len = p->u.octet_aligned->size = len;
00039 memcpy(p->u.octet_aligned->buf, buf, len);
00040
00041 return p;
00042 }
00043
00044 static int get_form(const char *charset)
00045 {
00046 int form = -1;
00047
00048
00049 if (!yaz_matchstr(charset, "UCS-2"))
00050 form = 2;
00051 if (!yaz_matchstr(charset, "UCS-4"))
00052 form = 4;
00053 if (!yaz_matchstr(charset, "UTF-16"))
00054 form = 5;
00055 if (!yaz_matchstr(charset, "UTF-8"))
00056 form = 8;
00057
00058 return form;
00059 }
00060
00061 static char *set_form (Odr_oid *encoding)
00062 {
00063 static char *charset = 0;
00064 if ( oid_oidlen(encoding) != 6)
00065 return 0;
00066 if (encoding[5] == 2)
00067 charset = "UCS-2";
00068 if (encoding[5] == 4)
00069 charset = "UCS-4";
00070 if (encoding[5] == 5)
00071 charset = "UTF-16";
00072 if (encoding[5] == 8)
00073 charset = "UTF-8";
00074 return charset;
00075 }
00076
00077 static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
00078 {
00079 int form = get_form (charset);
00080 Z_OriginProposal_0 *p0 =
00081 (Z_OriginProposal_0*)odr_malloc(o, sizeof(*p0));
00082
00083 memset(p0, 0, sizeof(*p0));
00084
00085 if (form > 0)
00086 {
00087 char oidname[20];
00088
00089 Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
00090 p0->which = Z_OriginProposal_0_iso10646;
00091 p0->u.iso10646 = is;
00092 is->collections = 0;
00093 sprintf (oidname, "1.0.10646.1.0.%d", form);
00094 is->encodingLevel = odr_getoidbystr (o, oidname);
00095 }
00096 else
00097 {
00098 Z_PrivateCharacterSet *pc =
00099 (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
00100
00101 memset(pc, 0, sizeof(*pc));
00102
00103 p0->which = Z_OriginProposal_0_private;
00104 p0->u.zprivate = pc;
00105
00106 pc->which = Z_PrivateCharacterSet_externallySpecified;
00107 pc->u.externallySpecified = z_ext_record2(o, charset);
00108 }
00109 return p0;
00110 }
00111
00112 static Z_OriginProposal *z_get_OriginProposal(
00113 ODR o, const char **charsets, int num_charsets,
00114 const char **langs, int num_langs, int selected)
00115 {
00116 int i;
00117 Z_OriginProposal *p = (Z_OriginProposal *) odr_malloc(o, sizeof(*p));
00118
00119 memset(p, 0, sizeof(*p));
00120
00121 p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
00122 *p->recordsInSelectedCharSets = (selected) ? 1:0;
00123
00124 if (charsets && num_charsets) {
00125
00126 p->num_proposedCharSets = num_charsets;
00127 p->proposedCharSets =
00128 (Z_OriginProposal_0**)
00129 odr_malloc(o, num_charsets*sizeof(Z_OriginProposal_0*));
00130
00131 for (i = 0; i<num_charsets; i++)
00132 p->proposedCharSets[i] =
00133 z_get_OriginProposal_0(o, charsets[i]);
00134 }
00135 if (langs && num_langs) {
00136
00137 p->num_proposedlanguages = num_langs;
00138
00139 p->proposedlanguages =
00140 (char **) odr_malloc(o, num_langs*sizeof(char *));
00141
00142 for (i = 0; i<num_langs; i++) {
00143
00144 p->proposedlanguages[i] = (char *)langs[i];
00145
00146 }
00147 }
00148 return p;
00149 }
00150
00151 static Z_CharSetandLanguageNegotiation *z_get_CharSetandLanguageNegotiation(
00152 ODR o)
00153 {
00154 Z_CharSetandLanguageNegotiation *p =
00155 (Z_CharSetandLanguageNegotiation *) odr_malloc(o, sizeof(*p));
00156
00157 memset(p, 0, sizeof(*p));
00158
00159 return p;
00160 }
00161
00162
00163 Z_External *yaz_set_proposal_charneg(ODR o,
00164 const char **charsets, int num_charsets,
00165 const char **langs, int num_langs,
00166 int selected)
00167 {
00168 Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
00169
00170 p->descriptor = 0;
00171 p->indirect_reference = 0;
00172
00173 p->direct_reference = odr_oiddup(o, yaz_oid_negot_charset_3);
00174
00175 p->which = Z_External_charSetandLanguageNegotiation;
00176 p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
00177 p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_proposal;
00178 p->u.charNeg3->u.proposal =
00179 z_get_OriginProposal(o, charsets, num_charsets,
00180 langs, num_langs, selected);
00181
00182 return p;
00183 }
00184
00185 Z_External *yaz_set_proposal_charneg_list(ODR o,
00186 const char *delim,
00187 const char *charset_list,
00188 const char *lang_list,
00189 int selected)
00190 {
00191 char **charsets_addresses = 0;
00192 char **langs_addresses = 0;
00193 int charsets_count = 0;
00194 int langs_count = 0;
00195
00196 if (charset_list)
00197 nmem_strsplit(odr_getmem(o), delim, charset_list,
00198 &charsets_addresses, &charsets_count);
00199 if (lang_list)
00200 nmem_strsplit(odr_getmem(o), delim, lang_list,
00201 &langs_addresses, &langs_count);
00202 return yaz_set_proposal_charneg(o,
00203 (const char **) charsets_addresses,
00204 charsets_count,
00205 (const char **) langs_addresses,
00206 langs_count,
00207 selected);
00208 }
00209
00210
00211
00212 static Z_TargetResponse *z_get_TargetResponse(ODR o, const char *charset,
00213 const char *lang, int selected)
00214 {
00215 Z_TargetResponse *p = (Z_TargetResponse *) odr_malloc(o, sizeof(*p));
00216 int form = get_form(charset);
00217
00218 memset(p, 0, sizeof(*p));
00219
00220 if (form > 0)
00221 {
00222 char oidname[20];
00223
00224 Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
00225 p->which = Z_TargetResponse_iso10646;
00226 p->u.iso10646 = is;
00227 is->collections = 0;
00228 sprintf (oidname, "1.0.10646.1.0.%d", form);
00229 is->encodingLevel = odr_getoidbystr (o, oidname);
00230 }
00231 else
00232 {
00233 Z_PrivateCharacterSet *pc =
00234 (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
00235
00236 memset(pc, 0, sizeof(*pc));
00237
00238 p->which = Z_TargetResponse_private;
00239 p->u.zprivate = pc;
00240
00241 pc->which = Z_PrivateCharacterSet_externallySpecified;
00242 pc->u.externallySpecified =
00243 z_ext_record2(o, charset);
00244 }
00245 p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
00246 *p->recordsInSelectedCharSets = (selected) ? 1:0;
00247
00248 p->selectedLanguage = lang ? (char *)odr_strdup(o, lang) : 0;
00249 return p;
00250 }
00251
00252
00253 Z_External *yaz_set_response_charneg(ODR o, const char *charset,
00254 const char *lang, int selected)
00255 {
00256 Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
00257
00258 p->descriptor = 0;
00259 p->indirect_reference = 0;
00260
00261 p->direct_reference = odr_oiddup(o, yaz_oid_negot_charset_3);
00262
00263 p->which = Z_External_charSetandLanguageNegotiation;
00264 p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
00265 p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_response;
00266 p->u.charNeg3->u.response = z_get_TargetResponse(o, charset, lang, selected);
00267
00268 return p;
00269 }
00270
00271
00272 Z_CharSetandLanguageNegotiation *yaz_get_charneg_record(Z_OtherInformation *p)
00273 {
00274 int i;
00275
00276 if (!p)
00277 return 0;
00278
00279 for (i = 0; i < p->num_elements; i++) {
00280 Z_External *pext;
00281 if ((p->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
00282 (pext = p->list[i]->information.externallyDefinedInfo)) {
00283
00284 if (!oid_oidcmp(pext->direct_reference, yaz_oid_negot_charset_3)
00285 && pext->which == Z_External_charSetandLanguageNegotiation)
00286 {
00287 return pext->u.charNeg3;
00288 }
00289 }
00290 }
00291 return 0;
00292 }
00293
00294
00295 int yaz_del_charneg_record(Z_OtherInformation **p)
00296 {
00297 int i;
00298
00299 if (!*p)
00300 return 0;
00301
00302 for (i = 0; i < (*p)->num_elements; i++) {
00303 Z_External *pext;
00304 if (((*p)->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
00305 (pext = (*p)->list[i]->information.externallyDefinedInfo))
00306 {
00307 if (!oid_oidcmp(pext->direct_reference, yaz_oid_negot_charset_3)
00308 && pext->which == Z_External_charSetandLanguageNegotiation)
00309 {
00310 if ((*p)->num_elements <= 1)
00311 *p = 0;
00312 else
00313 {
00314 --((*p)->num_elements);
00315 for(; i < (*p)->num_elements; i++)
00316 (*p)->list[i] = (*p)->list[i+1];
00317 }
00318 return 1;
00319 }
00320 }
00321 }
00322 return 0;
00323 }
00324
00325
00326
00327 void yaz_get_proposal_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
00328 char ***charsets, int *num_charsets,
00329 char ***langs, int *num_langs, int *selected)
00330 {
00331 int i;
00332 Z_OriginProposal *pro = p->u.proposal;
00333
00334 if (num_charsets && charsets)
00335 {
00336 if (pro->num_proposedCharSets)
00337 {
00338 *num_charsets = pro->num_proposedCharSets;
00339
00340 (*charsets) = (char **)
00341 nmem_malloc(mem, pro->num_proposedCharSets * sizeof(char *));
00342
00343 for (i=0; i<pro->num_proposedCharSets; i++)
00344 {
00345 (*charsets)[i] = 0;
00346
00347 if (pro->proposedCharSets[i]->which ==
00348 Z_OriginProposal_0_private &&
00349 pro->proposedCharSets[i]->u.zprivate->which ==
00350 Z_PrivateCharacterSet_externallySpecified) {
00351
00352 Z_External *pext =
00353 pro->proposedCharSets[i]->u.zprivate->u.externallySpecified;
00354
00355 if (pext->which == Z_External_octet) {
00356
00357 (*charsets)[i] = (char *)
00358 nmem_malloc(mem, (1+pext->u.octet_aligned->len) *
00359 sizeof(char));
00360
00361 memcpy ((*charsets)[i], pext->u.octet_aligned->buf,
00362 pext->u.octet_aligned->len);
00363 (*charsets)[i][pext->u.octet_aligned->len] = 0;
00364
00365 }
00366 }
00367 else if (pro->proposedCharSets[i]->which ==
00368 Z_OriginProposal_0_iso10646)
00369 (*charsets)[i] = set_form (
00370 pro->proposedCharSets[i]->u.iso10646->encodingLevel);
00371 }
00372 }
00373 else
00374 *num_charsets = 0;
00375 }
00376
00377 if (langs && num_langs)
00378 {
00379 if (pro->num_proposedlanguages)
00380 {
00381 *num_langs = pro->num_proposedlanguages;
00382
00383 (*langs) = (char **)
00384 nmem_malloc(mem, pro->num_proposedlanguages * sizeof(char *));
00385
00386 for (i=0; i<pro->num_proposedlanguages; i++)
00387 (*langs)[i] = nmem_strdup(mem, pro->proposedlanguages[i]);
00388 }
00389 else
00390 *num_langs = 0;
00391 }
00392
00393 if(pro->recordsInSelectedCharSets && selected)
00394 *selected = *pro->recordsInSelectedCharSets;
00395 }
00396
00397
00398 void yaz_get_response_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
00399 char **charset, char **lang, int *selected)
00400 {
00401 Z_TargetResponse *res = p->u.response;
00402
00403 if (charset && res->which == Z_TargetResponse_private &&
00404 res->u.zprivate->which == Z_PrivateCharacterSet_externallySpecified) {
00405
00406 Z_External *pext = res->u.zprivate->u.externallySpecified;
00407
00408 if (pext->which == Z_External_octet) {
00409
00410 *charset = (char *)
00411 nmem_malloc(mem, (1+pext->u.octet_aligned->len)*sizeof(char));
00412 memcpy (*charset, pext->u.octet_aligned->buf,
00413 pext->u.octet_aligned->len);
00414 (*charset)[pext->u.octet_aligned->len] = 0;
00415 }
00416 }
00417 if (charset && res->which == Z_TargetResponse_iso10646)
00418 *charset = set_form (res->u.iso10646->encodingLevel);
00419 if (lang && res->selectedLanguage)
00420 *lang = nmem_strdup (mem, res->selectedLanguage);
00421
00422 if(selected && res->recordsInSelectedCharSets)
00423 *selected = *res->recordsInSelectedCharSets;
00424 }
00425
00426
00427
00428
00429
00430
00431
00432