Updates to faciliate non-private character set negotiations
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 25 Jul 2002 12:50:16 +0000 (12:50 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 25 Jul 2002 12:50:16 +0000 (12:50 +0000)
include/yaz/charneg.h
zutil/charneg.c

index fb91ef1..2212f0f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: charneg.h,v 1.2 2002-05-19 15:39:54 oleg Exp $
+ * $Id: charneg.h,v 1.3 2002-07-25 12:50:16 adam Exp $
  */
 #ifndef CHARNEG_H
 #define CHARNEG_H
@@ -43,8 +43,10 @@ YAZ_EXPORT Z_External *yaz_set_response_charneg(ODR odr,
 
 
 YAZ_EXPORT void yaz_get_proposal_charneg(NMEM mem,
-       Z_CharSetandLanguageNegotiation *p, char **charsets, int *num_charsets,
-               char **langs, int *num_langs, int *selected);
+       Z_CharSetandLanguageNegotiation *p,
+                                         char ***charsets, int *num_charsets,
+                                         char ***langs, int *num_langs,
+                                         int *selected);
 
 
 YAZ_END_CDECL
index 3cc9b4b..f8a5fd0 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- $ $Id: charneg.c,v 1.3 2002-05-21 08:36:04 adam Exp $
+ $ $Id: charneg.c,v 1.4 2002-07-25 12:50:17 adam Exp $
  * Helper functions for Character Set and Language Negotiation - 3
  */
 
 #include <yaz/charneg.h>
 
 static Z_External* z_ext_record2(ODR o, int oid_class, int oid_value,
-       const char *buf, int len)
+                                 const char *buf, int len)
 {
-       Z_External *p;
-       oident oid;
-               
-       if (!(p = (Z_External *)odr_malloc(o, sizeof(*p)))) return 0;
-       
-       p->descriptor = 0;
-       p->indirect_reference = 0;
-       
-       oid.proto = PROTO_Z3950;
-       oid.oclass = oid_class;
-       oid.value = oid_value;
-       p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
-       
-       p->which = Z_External_octet;
-       if (!(p->u.octet_aligned = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct)))) {
-               return 0;
-       }
-       if (!(p->u.octet_aligned->buf = (unsigned char *)odr_malloc(o, len))) {
-               return 0;
-       }
-       p->u.octet_aligned->len = p->u.octet_aligned->size = len;
-       memcpy(p->u.octet_aligned->buf, buf, len);
+    Z_External *p;
+    oident oid;
+    
+    if (!(p = (Z_External *)odr_malloc(o, sizeof(*p)))) return 0;
+    
+    p->descriptor = 0;
+    p->indirect_reference = 0;
+    
+    oid.proto = PROTO_Z3950;
+    oid.oclass = oid_class;
+    oid.value = oid_value;
+    p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
+    
+    p->which = Z_External_octet;
+    if (!(p->u.octet_aligned = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct)))) {
+        return 0;
+    }
+    if (!(p->u.octet_aligned->buf = (unsigned char *)odr_malloc(o, len))) {
+        return 0;
+    }
+    p->u.octet_aligned->len = p->u.octet_aligned->size = len;
+    memcpy(p->u.octet_aligned->buf, buf, len);
        
-       return p;
+    return p;
+}
+
+static int get_form(const char *charset)
+{
+    int form = -1;
+
+
+    if (!strcmp (charset, "UCS-2"))
+        form = 2;
+    if (!strcmp (charset, "UCS-4"))
+        form = 4;
+    if (!strcmp (charset, "UTF-16"))
+        form = 5;
+    if (!strcmp (charset, "UTF-8"))
+        form = 8;
+
+    return form;
+}
+
+static char *set_form (Odr_oid *encoding)
+{
+    static char *charset = 0;
+    if ( oid_oidlen(encoding) != 6)
+        return 0;
+    if (encoding[5] == 2)
+        charset = "UCS-2";
+    if (encoding[5] == 4)
+        charset = "UCS-4";
+    if (encoding[5] == 5)
+        charset = "UTF-16";
+    if (encoding[5] == 8)
+        charset = "UTF-8";
+    return charset;
 }
+
 static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
 {
-       Z_OriginProposal_0 *p0 =
-                               (Z_OriginProposal_0*)odr_malloc(o, sizeof(*p0));
-       Z_PrivateCharacterSet *pc =
-                               (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
+    int form = get_form (charset);
+    Z_OriginProposal_0 *p0 =
+        (Z_OriginProposal_0*)odr_malloc(o, sizeof(*p0));
 
-       memset(p0, 0, sizeof(*p0));
-       memset(pc, 0, sizeof(*pc));
-                       
-       p0->which = Z_OriginProposal_0_private;
-       p0->u.zprivate = pc;
-       
-       pc->which = Z_PrivateCharacterSet_externallySpecified;
-       pc->u.externallySpecified =
-                       z_ext_record2(o, CLASS_RECSYN, VAL_NOP, charset, (strlen(charset)+1));
+    memset(p0, 0, sizeof(*p0));
+
+    if (form > 0)
+    {   /* ISO 10646 (UNICODE) */
+        char oidname[20];
+
+        Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
+        p0->which = Z_OriginProposal_0_iso10646;
+        p0->u.iso10646 = is;
+        is->collections = 0;
+        sprintf (oidname, "1.0.10646.1.0.%d", form);
+        is->encodingLevel = odr_getoidbystr (o, oidname);
+    }
+    else
+    {   /* private ones */
+        Z_PrivateCharacterSet *pc =
+            (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
+
+        
+        memset(pc, 0, sizeof(*pc));
+        
+        p0->which = Z_OriginProposal_0_private;
+        p0->u.zprivate = pc;
        
-       return p0;
+        pc->which = Z_PrivateCharacterSet_externallySpecified;
+        pc->u.externallySpecified =
+            z_ext_record2(o, CLASS_RECSYN, VAL_NOP, charset, strlen(charset));
+    }
+    return p0;
 }
-static Z_OriginProposal *z_get_OriginProposal(ODR o, const char **charsets,
-       int num_charsets, const char **langs, int num_langs, int selected)
+
+static Z_OriginProposal *z_get_OriginProposal(
+    ODR o, const char **charsets, int num_charsets,
+    const char **langs, int num_langs, int selected)
 {      
-       int i;
-       Z_OriginProposal *p = (Z_OriginProposal *) odr_malloc(o, sizeof(*p));
+    int i;
+    Z_OriginProposal *p = (Z_OriginProposal *) odr_malloc(o, sizeof(*p));
                
-       memset(p, 0, sizeof(*p));
+    memset(p, 0, sizeof(*p));
 
-       p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
-       *p->recordsInSelectedCharSets = (selected) ? 1:0;
+    p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
+    *p->recordsInSelectedCharSets = (selected) ? 1:0;
 
-       if (charsets && num_charsets) {         
+    if (charsets && num_charsets) {            
        
-               p->num_proposedCharSets = num_charsets;
-               p->proposedCharSets = 
-                       (Z_OriginProposal_0**) odr_malloc(o,
-                               num_charsets*sizeof(Z_OriginProposal_0*));
+        p->num_proposedCharSets = num_charsets;
+        p->proposedCharSets = 
+            (Z_OriginProposal_0**)
+            odr_malloc(o, num_charsets*sizeof(Z_OriginProposal_0*));
 
-               for (i = 0; i<num_charsets; i++) {
-
-                       p->proposedCharSets[i] =
-                               z_get_OriginProposal_0(o, charsets[i]);
-                       
-               }
-       }
-       if (langs && num_langs) {
+        for (i = 0; i<num_charsets; i++)
+            p->proposedCharSets[i] =
+                z_get_OriginProposal_0(o, charsets[i]);
+    }
+    if (langs && num_langs) {
        
-               p->num_proposedlanguages = num_langs;
+        p->num_proposedlanguages = num_langs;
 
-               p->proposedlanguages = 
-                       (char **) odr_malloc(o, num_langs*sizeof(char *));
+        p->proposedlanguages = 
+            (char **) odr_malloc(o, num_langs*sizeof(char *));
 
-               for (i = 0; i<num_langs; i++) {
+        for (i = 0; i<num_langs; i++) {
 
-                       p->proposedlanguages[i] = (char *)langs[i];
+            p->proposedlanguages[i] = (char *)langs[i];
                        
-               }
-       }
-       return p;
+        }
+    }
+    return p;
 }
-static Z_CharSetandLanguageNegotiation *z_get_CharSetandLanguageNegotiation(ODR o)
+
+static Z_CharSetandLanguageNegotiation *z_get_CharSetandLanguageNegotiation(
+    ODR o)
 {
-       Z_CharSetandLanguageNegotiation *p =
-               (Z_CharSetandLanguageNegotiation *) odr_malloc(o, sizeof(*p));
-       
-       memset(p, 0, sizeof(*p));
+    Z_CharSetandLanguageNegotiation *p =
+        (Z_CharSetandLanguageNegotiation *) odr_malloc(o, sizeof(*p));
+    
+    memset(p, 0, sizeof(*p));
        
-       return p;
+    return p;
 }
-Z_External *yaz_set_proposal_charneg(ODR o, const char **charsets, int num_charsets,
-       const char **langs, int num_langs, int selected)
+
+Z_External *yaz_set_proposal_charneg(ODR o,
+                                     const char **charsets, int num_charsets,
+                                     const char **langs, int num_langs,
+                                     int selected)
 {
-       Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
-       oident oid;
+    Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
+    oident oid;
        
-       p->descriptor = 0;
-       p->indirect_reference = 0;      
-
-       oid.proto = PROTO_Z3950;
-       oid.oclass = CLASS_NEGOT;
-       oid.value = VAL_CHARNEG3;
-       p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
-
-       p->which = Z_External_charSetandLanguageNegotiation;
-       p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
-       p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_proposal;
-       p->u.charNeg3->u.proposal =
-               z_get_OriginProposal(o, charsets, num_charsets,
-                       langs, num_langs, selected);
-
-       return p;
+    p->descriptor = 0;
+    p->indirect_reference = 0; 
+
+    oid.proto = PROTO_Z3950;
+    oid.oclass = CLASS_NEGOT;
+    oid.value = VAL_CHARNEG3;
+    p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
+
+    p->which = Z_External_charSetandLanguageNegotiation;
+    p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
+    p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_proposal;
+    p->u.charNeg3->u.proposal =
+        z_get_OriginProposal(o, charsets, num_charsets,
+                             langs, num_langs, selected);
+
+    return p;
 }
+
 static Z_TargetResponse *z_get_TargetResponse(ODR o, const char *charset,
-       const char *lang, int selected)
+                                              const char *lang, int selected)
 {      
-       Z_TargetResponse *p = (Z_TargetResponse *) odr_malloc(o, sizeof(*p));
-       Z_PrivateCharacterSet *pc =
-                               (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
-               
-       memset(p, 0, sizeof(*p));
-       memset(pc, 0, sizeof(*pc));
-       
-       p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
-       *p->recordsInSelectedCharSets = (selected) ? 1:0;
-       p->selectedLanguage = (char *)odr_strdup(o, lang);
+    Z_TargetResponse *p = (Z_TargetResponse *) odr_malloc(o, sizeof(*p));
+    int form = get_form(charset);
+
+    memset(p, 0, sizeof(*p));
+
+    if (form > 0)
+    {
+        char oidname[20];
+
+        Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
+        p->which = Z_TargetResponse_iso10646;
+        p->u.iso10646 = is;
+        is->collections = 0;
+        sprintf (oidname, "1.0.10646.1.0.%d", form);
+        is->encodingLevel = odr_getoidbystr (o, oidname);
+    }
+    else
+    {
+        Z_PrivateCharacterSet *pc =
+            (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
+        
+        memset(pc, 0, sizeof(*pc));
        
-       p->which = Z_TargetResponse_private;
-       p->u.zprivate = pc;
+        p->which = Z_TargetResponse_private;
+        p->u.zprivate = pc;
        
-       pc->which = Z_PrivateCharacterSet_externallySpecified;
-       pc->u.externallySpecified =
-                       z_ext_record2(o, CLASS_RECSYN, VAL_NOP, charset, (strlen(charset)+1));
-       return p;
+        pc->which = Z_PrivateCharacterSet_externallySpecified;
+        pc->u.externallySpecified =
+        z_ext_record2(o, CLASS_RECSYN, VAL_NOP, charset, strlen(charset));
+    }
+    p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
+    *p->recordsInSelectedCharSets = (selected) ? 1:0;
+    
+    p->selectedLanguage = lang ? (char *)odr_strdup(o, lang) : 0;
+    return p;
 }
+
 Z_External *yaz_set_response_charneg(ODR o, const char *charset,
-       const char *lang, int selected)
+                                     const char *lang, int selected)
 {
-       Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
-       oident oid;
+    Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
+    oident oid;
        
-       p->descriptor = 0;
-       p->indirect_reference = 0;      
+    p->descriptor = 0;
+    p->indirect_reference = 0; 
 
-       oid.proto = PROTO_Z3950;
-       oid.oclass = CLASS_NEGOT;
-       oid.value = VAL_CHARNEG3;
-       p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
+    oid.proto = PROTO_Z3950;
+    oid.oclass = CLASS_NEGOT;
+    oid.value = VAL_CHARNEG3;
+    p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
 
-       p->which = Z_External_charSetandLanguageNegotiation;
-       p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
-       p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_response;
-       p->u.charNeg3->u.response = z_get_TargetResponse(o, charset, lang, selected);
+    p->which = Z_External_charSetandLanguageNegotiation;
+    p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
+    p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_response;
+    p->u.charNeg3->u.response = z_get_TargetResponse(o, charset, lang, selected);
 
-       return p;
+    return p;
 }
+
 Z_CharSetandLanguageNegotiation *yaz_get_charneg_record(Z_OtherInformation *p)
 {
-       Z_External *pext;
-       int i;
+    Z_External *pext;
+    int i;
        
-       if(!p)
-               return 0;
+    if(!p)
+        return 0;
        
-       for (i=0; i<p->num_elements; i++) {
+    for (i=0; i<p->num_elements; i++) {
        
-               if ((p->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
-                                       (pext = p->list[i]->information.externallyDefinedInfo)) {
+        if ((p->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
+            (pext = p->list[i]->information.externallyDefinedInfo)) {
                                        
-                       oident *ent = oid_getentbyoid(pext->direct_reference);
+            oident *ent = oid_getentbyoid(pext->direct_reference);
                        
-                       if (ent && ent->value == VAL_CHARNEG3 && ent->oclass == CLASS_NEGOT &&
-                               pext->which == Z_External_charSetandLanguageNegotiation) {
+            if (ent && ent->value == VAL_CHARNEG3 && ent->oclass == CLASS_NEGOT &&
+                pext->which == Z_External_charSetandLanguageNegotiation) {
                                
-                               return pext->u.charNeg3;
-                       }
-               }
-       }
+                return pext->u.charNeg3;
+            }
+        }
+    }
        
-       return 0;
+    return 0;
 }
-void yaz_get_proposal_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p, char **charsets,
-       int *num_charsets, char **langs, int *num_langs, int *selected)
-{
-       int i;
-       Z_OriginProposal *pro = p->u.proposal;
-       
-       if (pro->num_proposedCharSets && charsets && num_charsets) {
-       
-               *num_charsets = pro->num_proposedCharSets;
-       
-               charsets = (char **)nmem_malloc(mem, pro->num_proposedCharSets * sizeof(char *));
-               
-               for (i=0; i<pro->num_proposedCharSets; i++) {
-               
-                       if (pro->proposedCharSets[i]->which == Z_OriginProposal_0_private &&
-                               pro->proposedCharSets[i]->u.zprivate->which == Z_PrivateCharacterSet_externallySpecified) {
-                                       
-                               Z_External *pext =
-                                       pro->proposedCharSets[i]->u.zprivate->u.externallySpecified;
-                               
-                               if (pext->which == Z_External_octet) {
-                       
-                                       charsets[i] = (char *)nmem_malloc(mem, pext->u.octet_aligned->len * sizeof(char));
-                                       
-                                       memcpy (charsets[i], pext->u.octet_aligned->buf, pext->u.octet_aligned->len);
-                                       
-                               }
-                       }
-               }
-       }
-
-       if (pro->num_proposedlanguages && langs && num_langs) {
 
-               *num_langs = pro->num_proposedlanguages;
-       
-               langs = (char **)nmem_malloc(mem, pro->num_proposedlanguages * sizeof(char *));
-               
-               for (i=0; i<pro->num_proposedlanguages; i++) {
-
-                       langs[i] = (char *)nmem_malloc(mem, strlen(pro->proposedlanguages[i])+1);
-                       memcpy (langs[i], pro->proposedlanguages[i], strlen(pro->proposedlanguages[i])+1);              
-               }
-       }
-       
-       if(pro->recordsInSelectedCharSets && selected) {
-       
-               *selected = *pro->recordsInSelectedCharSets;
-               
-       }
+void yaz_get_proposal_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
+                              char ***charsets, int *num_charsets,
+                              char ***langs, int *num_langs, int *selected)
+{
+    int i;
+    Z_OriginProposal *pro = p->u.proposal;
+    
+    if (num_charsets && charsets)
+    {
+        if (pro->num_proposedCharSets)
+        {
+            *num_charsets = pro->num_proposedCharSets;
+            
+            (*charsets) = (char **)
+                nmem_malloc(mem, pro->num_proposedCharSets * sizeof(char *));
+            
+            for (i=0; i<pro->num_proposedCharSets; i++) 
+            {
+                (*charsets)[i] = 0;
+                
+                if (pro->proposedCharSets[i]->which ==
+                    Z_OriginProposal_0_private &&
+                    pro->proposedCharSets[i]->u.zprivate->which ==
+                    Z_PrivateCharacterSet_externallySpecified) {
+                    
+                    Z_External *pext =
+                        pro->proposedCharSets[i]->u.zprivate->u.externallySpecified;
+                    
+                    if (pext->which == Z_External_octet) {
+                        
+                        (*charsets)[i] = (char *)
+                            nmem_malloc(mem, (1+pext->u.octet_aligned->len) *
+                                        sizeof(char));
+                        
+                        memcpy ((*charsets)[i], pext->u.octet_aligned->buf,
+                                pext->u.octet_aligned->len);
+                        (*charsets)[i][pext->u.octet_aligned->len] = 0;
+                        
+                    }
+                }
+                else if (pro->proposedCharSets[i]->which ==
+                         Z_OriginProposal_0_iso10646)
+                    (*charsets)[i] = set_form (
+                        pro->proposedCharSets[i]->u.iso10646->encodingLevel);
+            }
+        }
+        else
+            *num_charsets = 0;
+    }
+    
+    if (langs && num_langs)
+    {
+        if (pro->num_proposedlanguages)
+        {
+            *num_langs = pro->num_proposedlanguages;
+            
+            (*langs) = (char **)
+                nmem_malloc(mem, pro->num_proposedlanguages * sizeof(char *));
+            
+            for (i=0; i<pro->num_proposedlanguages; i++)
+                (*langs)[i] = nmem_strdup(mem, pro->proposedlanguages[i]);
+        }
+        else
+            *num_langs = 0;
+    }
+    
+    if(pro->recordsInSelectedCharSets && selected)
+        *selected = *pro->recordsInSelectedCharSets;
 }
+
 void yaz_get_response_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
-       char **charset, char **lang, int *selected)
+                              char **charset, char **lang, int *selected)
 {
-       Z_TargetResponse *res = p->u.response;
+    Z_TargetResponse *res = p->u.response;
        
-       if (charset && res->which == Z_TargetResponse_private &&
-               res->u.zprivate->which == Z_PrivateCharacterSet_externallySpecified) {
+    if (charset && res->which == Z_TargetResponse_private &&
+        res->u.zprivate->which == Z_PrivateCharacterSet_externallySpecified) {
 
-               Z_External *pext = res->u.zprivate->u.externallySpecified;
-                               
-               if (pext->which == Z_External_octet) {
-                       
-                       *charset = (char *)nmem_malloc(mem, pext->u.octet_aligned->len * sizeof(char));
-                       memcpy (*charset, pext->u.octet_aligned->buf, pext->u.octet_aligned->len);
-               }       
-       }
-
-       if (lang && res->selectedLanguage) {
-       
-               *lang = (char *)nmem_malloc(mem, strlen(res->selectedLanguage)+1);
-               memcpy (*lang, res->selectedLanguage, strlen(res->selectedLanguage)+1);
-       
-       }
-
-       if(selected && res->recordsInSelectedCharSets) {
-       
-               *selected = *res->recordsInSelectedCharSets;
+        Z_External *pext = res->u.zprivate->u.externallySpecified;
+        
+        if (pext->which == Z_External_octet) {
+            
+            *charset = (char *)
+                nmem_malloc(mem, (1+pext->u.octet_aligned->len)*sizeof(char));
+            memcpy (*charset, pext->u.octet_aligned->buf,
+                    pext->u.octet_aligned->len);
+            (*charset)[pext->u.octet_aligned->len] = 0;
+        }      
+    }
+    if (charset && res->which == Z_TargetResponse_iso10646)
+        *charset = set_form (res->u.iso10646->encodingLevel);
+    if (lang && res->selectedLanguage)
+        *lang = nmem_strdup (mem, res->selectedLanguage);
 
-       }
+    if(selected && res->recordsInSelectedCharSets)
+        *selected = *res->recordsInSelectedCharSets;
 }