Build packages for Ubuntu Trusty Tahr 14.04 LTS
[yaz-moved-to-github.git] / src / charneg.c
index 302e098..2531346 100644 (file)
@@ -1,49 +1,37 @@
-/*
- * Copyright (c) 2002-2004, Index Data
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) Index Data
  * See the file LICENSE for details.
- *
- * $Id: charneg.c,v 1.2 2004-10-15 00:19:00 adam Exp $
  */
-
-/** 
+/**
  * \file charneg.c
  * \brief Implements Z39.50 Charset negotiation utilities
  *
  * Helper functions for Character Set and Language Negotiation - 3
  */
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
 #include <yaz/otherinfo.h>
 #include <yaz/z-charneg.h>
 #include <yaz/charneg.h>
 #include <yaz/yaz-util.h>
+#include <yaz/oid_db.h>
 
-static Z_External* z_ext_record2(ODR o, int oid_class, int oid_value,
-                                 const char *buf)
+static Z_External* z_ext_record2(ODR o, const char *buf)
 {
     Z_External *p;
-    oident oid;
     int len = strlen(buf);
-    
-    if (!(p = (Z_External *)odr_malloc(o, sizeof(*p)))) return 0;
-    
+
+    if (!(p = (Z_External *)odr_malloc(o, sizeof(*p))))
+        return 0;
     p->descriptor = 0;
     p->indirect_reference = 0;
-    
-    oid.proto = PROTO_Z3950;
-    oid.oclass = (enum oid_class) oid_class;
-    oid.value = (enum oid_value) oid_value;
-    p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
-    
+    p->direct_reference = odr_oiddup(o, yaz_oid_negot_charset_id);
     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);
-       
+    p->u.octet_aligned =
+        odr_create_Odr_oct(o, buf, len);
     return p;
 }
 
@@ -51,7 +39,6 @@ static int get_form(const char *charset)
 {
     int form = -1;
 
-
     if (!yaz_matchstr(charset, "UCS-2"))
         form = 2;
     if (!yaz_matchstr(charset, "UCS-4"))
@@ -64,7 +51,7 @@ static int get_form(const char *charset)
     return form;
 }
 
-static char *set_form (Odr_oid *encoding)
+static char *set_form(Odr_oid *encoding)
 {
     static char *charset = 0;
     if ( oid_oidlen(encoding) != 6)
@@ -82,7 +69,7 @@ static char *set_form (Odr_oid *encoding)
 
 static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
 {
-    int form = get_form (charset);
+    int form = get_form(charset);
     Z_OriginProposal_0 *p0 =
         (Z_OriginProposal_0*)odr_malloc(o, sizeof(*p0));
 
@@ -92,12 +79,12 @@ static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
     {   /* ISO 10646 (UNICODE) */
         char oidname[20];
 
-        Z_Iso10646 *is = (Z_Iso10646 *) odr_malloc (o, sizeof(*is));
+        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);
+        sprintf(oidname, "1.0.10646.1.0.%d", form);
+        is->encodingLevel = odr_getoidbystr(o, oidname);
     }
     else
     {   /* private ones */
@@ -105,13 +92,12 @@ static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
             (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
 
         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_NEGOT, VAL_ID_CHARSET, charset);
+        pc->u.externallySpecified = z_ext_record2(o, charset);
     }
     return p0;
 }
@@ -119,38 +105,34 @@ static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
 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));
-               
+
     memset(p, 0, sizeof(*p));
 
     p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
-    *p->recordsInSelectedCharSets = (selected) ? 1:0;
+    *p->recordsInSelectedCharSets = (selected) ? 1 : 0;
 
-    if (charsets && num_charsets) {            
-       
+    if (charsets && num_charsets)
+    {
         p->num_proposedCharSets = num_charsets;
-        p->proposedCharSets = 
+        p->proposedCharSets =
             (Z_OriginProposal_0**)
             odr_malloc(o, num_charsets*sizeof(Z_OriginProposal_0*));
 
-        for (i = 0; i<num_charsets; i++)
+        for (i = 0; i < num_charsets; i++)
             p->proposedCharSets[i] =
                 z_get_OriginProposal_0(o, charsets[i]);
     }
-    if (langs && num_langs) {
-       
+    if (langs && num_langs)
+    {
         p->num_proposedlanguages = num_langs;
-
-        p->proposedlanguages = 
+        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];
-                       
-        }
     }
     return p;
 }
@@ -160,9 +142,9 @@ static Z_CharSetandLanguageNegotiation *z_get_CharSetandLanguageNegotiation(
 {
     Z_CharSetandLanguageNegotiation *p =
         (Z_CharSetandLanguageNegotiation *) odr_malloc(o, sizeof(*p));
-    
+
     memset(p, 0, sizeof(*p));
-       
+
     return p;
 }
 
@@ -173,15 +155,11 @@ Z_External *yaz_set_proposal_charneg(ODR o,
                                      int selected)
 {
     Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
-    oident oid;
-       
+
     p->descriptor = 0;
-    p->indirect_reference = 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->direct_reference = odr_oiddup(o, yaz_oid_negot_charset_3);
 
     p->which = Z_External_charSetandLanguageNegotiation;
     p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
@@ -193,15 +171,40 @@ Z_External *yaz_set_proposal_charneg(ODR o,
     return p;
 }
 
+Z_External *yaz_set_proposal_charneg_list(ODR o,
+                                          const char *delim,
+                                          const char *charset_list,
+                                          const char *lang_list,
+                                          int selected)
+{
+    char **charsets_addresses = 0;
+    char **langs_addresses = 0;
+    int charsets_count = 0;
+    int langs_count = 0;
+
+    if (charset_list)
+        nmem_strsplit(odr_getmem(o), delim, charset_list,
+                      &charsets_addresses, &charsets_count);
+    if (lang_list)
+        nmem_strsplit(odr_getmem(o), delim, lang_list,
+                      &langs_addresses, &langs_count);
+    return yaz_set_proposal_charneg(o,
+                                    (const char **) charsets_addresses,
+                                    charsets_count,
+                                    (const char **) langs_addresses,
+                                    langs_count,
+                                    selected);
+}
+
+
 /* used by yaz_set_response_charneg */
 static Z_TargetResponse *z_get_TargetResponse(ODR o, const char *charset,
                                               const char *lang, int selected)
-{      
+{
     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];
@@ -210,27 +213,27 @@ static Z_TargetResponse *z_get_TargetResponse(ODR o, const char *charset,
         p->which = Z_TargetResponse_iso10646;
         p->u.iso10646 = is;
         is->collections = 0;
-        sprintf (oidname, "1.0.10646.1.0.%d", form);
+        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;
-       
+
         pc->which = Z_PrivateCharacterSet_externallySpecified;
         pc->u.externallySpecified =
-           z_ext_record2(o, CLASS_NEGOT, VAL_ID_CHARSET, charset);
+            z_ext_record2(o, 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;
+    *p->recordsInSelectedCharSets = (selected) ? 1 : 0;
+
+    p->selectedLanguage = lang ? (char *) odr_strdup(o, lang) : 0;
     return p;
 }
 
@@ -239,15 +242,11 @@ Z_External *yaz_set_response_charneg(ODR o, const char *charset,
                                      const char *lang, int selected)
 {
     Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
-    oident oid;
-       
+
     p->descriptor = 0;
-    p->indirect_reference = 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->direct_reference = odr_oiddup(o, yaz_oid_negot_charset_3);
 
     p->which = Z_External_charSetandLanguageNegotiation;
     p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
@@ -260,22 +259,20 @@ Z_External *yaz_set_response_charneg(ODR o, const char *charset,
 /* Get negotiation from OtherInformation. Client&Server side */
 Z_CharSetandLanguageNegotiation *yaz_get_charneg_record(Z_OtherInformation *p)
 {
-    Z_External *pext;
     int i;
-       
-    if(!p)
+
+    if (!p)
         return 0;
-       
-    for (i=0; i<p->num_elements; i++) {
-       
+
+    for (i = 0; i < p->num_elements; i++)
+    {
+        Z_External *pext;
         if ((p->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
-            (pext = p->list[i]->information.externallyDefinedInfo)) {
-                                       
-            oident *ent = oid_getentbyoid(pext->direct_reference);
-                       
-            if (ent && ent->value == VAL_CHARNEG3 && ent->oclass == CLASS_NEGOT &&
-                pext->which == Z_External_charSetandLanguageNegotiation) {
-                               
+            (pext = p->list[i]->information.externallyDefinedInfo))
+        {
+            if (!oid_oidcmp(pext->direct_reference, yaz_oid_negot_charset_3)
+                && pext->which == Z_External_charSetandLanguageNegotiation)
+            {
                 return pext->u.charNeg3;
             }
         }
@@ -283,6 +280,39 @@ Z_CharSetandLanguageNegotiation *yaz_get_charneg_record(Z_OtherInformation *p)
     return 0;
 }
 
+/* Delete negotiation from OtherInformation. Client&Server side */
+int yaz_del_charneg_record(Z_OtherInformation **p)
+{
+    int i;
+
+    if (!*p)
+        return 0;
+
+    for (i = 0; i < (*p)->num_elements; i++)
+    {
+        Z_External *pext;
+        if (((*p)->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
+            (pext = (*p)->list[i]->information.externallyDefinedInfo))
+        {
+            if (!oid_oidcmp(pext->direct_reference, yaz_oid_negot_charset_3)
+                && pext->which == Z_External_charSetandLanguageNegotiation)
+            {
+                if ((*p)->num_elements <= 1)
+                    *p = 0;
+                else
+                {
+                    --((*p)->num_elements);
+                    for (; i < (*p)->num_elements; i++)
+                        (*p)->list[i] = (*p)->list[i+1];
+                }
+                return 1;
+            }
+        }
+    }
+    return 0;
+}
+
+
 /* Get charsets, langs, selected from negotiation.. Server side */
 void yaz_get_proposal_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
                               char ***charsets, int *num_charsets,
@@ -290,67 +320,66 @@ void yaz_get_proposal_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
 {
     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++) 
+
+            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_PrivateCharacterSet_externallySpecified)
+                {
                     Z_External *pext =
                         pro->proposedCharSets[i]->u.zprivate->u.externallySpecified;
-                    
-                    if (pext->which == Z_External_octet) {
-                        
+
+                    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);
+
+                        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 (
+                    (*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++)
+
+            for (i = 0; i < pro->num_proposedlanguages; i++)
                 (*langs)[i] = nmem_strdup(mem, pro->proposedlanguages[i]);
         }
         else
             *num_langs = 0;
     }
-    
-    if(pro->recordsInSelectedCharSets && selected)
+
+    if (pro->recordsInSelectedCharSets && selected)
         *selected = *pro->recordsInSelectedCharSets;
 }
 
@@ -359,26 +388,35 @@ void yaz_get_response_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
                               char **charset, char **lang, int *selected)
 {
     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) {
-            
+
+        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);
+            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);
+        *charset = set_form(res->u.iso10646->encodingLevel);
     if (lang && res->selectedLanguage)
-        *lang = nmem_strdup (mem, res->selectedLanguage);
+        *lang = nmem_strdup(mem, res->selectedLanguage);
 
-    if(selected && res->recordsInSelectedCharSets)
+    if (selected && res->recordsInSelectedCharSets)
         *selected = *res->recordsInSelectedCharSets;
 }
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+