kdecore Library API Documentation

kidna.cpp

00001 /*
00002     This file is part of the KDE libraries
00003 
00004     Copyright (c) 2003 Waldo Bastian <bastian@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019     Boston, MA 02111-1307, USA.
00020 */
00021 
00022 #include "kidna.h"
00023 
00024 #include <qstringlist.h>
00025 #include <kdebug.h>
00026 
00027 #include "ltdl.h"
00028 #include <stdlib.h>
00029 
00030 #define IDNA_SUCCESS 0
00031 
00032 static lt_dlhandle KIDNA_lib; // = 0
00033 static bool KIDNA_lib_load_failed; // = false
00034 
00035 typedef int (*KIDNA_utf8_to_ace_t)(const char *, char **, int);
00036 typedef int (*KIDNA_utf8ace_to_utf8_t)(const char *, char **, int);
00037 
00038 static KIDNA_utf8_to_ace_t KIDNA_utf8_to_ace; // = 0
00039 static KIDNA_utf8ace_to_utf8_t KIDNA_utf8ace_to_utf8; // = 0
00040 
00041 static void KIDNA_load_lib()
00042 {
00043    KIDNA_lib_load_failed = true; // Unless proven otherwise
00044    KIDNA_lib = lt_dlopen("/usr/local/lib/libidn.la");
00045    if (!KIDNA_lib) 
00046    {
00047       KIDNA_lib = lt_dlopen("/usr/lib/libidn.la");
00048    }
00049    
00050    if (!KIDNA_lib) 
00051       return; // Error
00052 
00053    KIDNA_utf8_to_ace = (KIDNA_utf8_to_ace_t) lt_dlsym(KIDNA_lib, "idna_to_ascii_8z");
00054    if (!KIDNA_utf8_to_ace)
00055    {
00056       kdWarning() << "Symbol idna_utf8_to_ace not found." << endl;   
00057       return; // Error
00058    }
00059          
00060    KIDNA_utf8ace_to_utf8 = (KIDNA_utf8ace_to_utf8_t) lt_dlsym(KIDNA_lib, "idna_to_unicode_8z8z");
00061    if (!KIDNA_utf8ace_to_utf8)
00062    {
00063       kdWarning() << "Symbol idna_utf8ace_to_utf8 not found." << endl;   
00064       return; // Error
00065    }
00066    KIDNA_lib_load_failed = false; // Succes
00067 }
00068 
00069 static QStringList *KIDNA_idnDomains = 0;
00070 
00071 static bool idnSupportForHost(const QString &host)
00072 {
00073    if (!KIDNA_idnDomains)
00074    {
00075       const char *kde_use_idn = getenv("KDE_USE_IDN");
00076       if (!kde_use_idn)
00077          kde_use_idn = "at:ch:cn:de:dk:kr:jp:li:no:se:tw";
00078       KIDNA_idnDomains = new QStringList(QStringList::split(':', QString::fromLatin1(kde_use_idn).lower()));
00079    }
00080    
00081    QString tld = host.mid(host.findRev('.')+1).lower();
00082    return KIDNA_idnDomains->contains(tld);
00083 }
00084 
00085 QCString KIDNA::toAsciiCString(const QString &idna)
00086 {
00087    int l = idna.length();
00088    const QChar *u = idna.unicode();
00089    bool needConversion = false;
00090    for(;l--;)
00091    {
00092       if ((*u++).unicode() > 127)
00093       {
00094           needConversion = true;
00095           break;
00096       }
00097    }
00098    if (!needConversion)
00099       return idna.lower().latin1();
00100 
00101    if (!KIDNA_lib && !KIDNA_lib_load_failed)
00102    {
00103       KIDNA_load_lib();
00104    }
00105 
00106    if (KIDNA_lib_load_failed || !idnSupportForHost(idna))
00107    {
00108       return 0; // Can't convert
00109    }
00110    else 
00111    {
00112       // Also handle names that start with "." even though libidn
00113       // doesn't like those
00114       bool bStartsWithDot = (idna[0] == '.');
00115       char *pOutput;
00116       if ((*KIDNA_utf8_to_ace)(idna.utf8().data()+(bStartsWithDot ? 1: 0), &pOutput, 0) == IDNA_SUCCESS)
00117       {
00118          QCString result = pOutput;
00119          free(pOutput);
00120          if (bStartsWithDot)
00121             return "."+result;
00122          return result;
00123       }
00124       else
00125       {
00126          return 0; // Can't convert
00127       }
00128    }
00129 }
00130 
00131 QString KIDNA::toAscii(const QString &idna)
00132 {
00133    int l = idna.length();
00134    const QChar *u = idna.unicode();
00135    bool needConversion = false;
00136    for(;l--;)
00137    {
00138       if ((*u++).unicode() > 127)
00139       {
00140           needConversion = true;
00141           break;
00142       }
00143    }
00144    if (!needConversion)
00145       return idna.lower();
00146 
00147    if (!KIDNA_lib && !KIDNA_lib_load_failed)
00148    {
00149       KIDNA_load_lib();
00150    }
00151 
00152    if (KIDNA_lib_load_failed || !idnSupportForHost(idna))
00153    {
00154       return QString::null; // Can't convert
00155    }
00156    else 
00157    {
00158       // Also handle names that start with "." even though libidn
00159       // doesn't like those
00160       bool bStartsWithDot = (idna[0] == '.');
00161       char *pOutput;
00162       if ((*KIDNA_utf8_to_ace)(idna.utf8().data()+(bStartsWithDot ? 1: 0), &pOutput, 0) == IDNA_SUCCESS)
00163       {
00164          QString result(pOutput);
00165          free(pOutput);
00166          if (bStartsWithDot)
00167             return "."+result;
00168          return result;
00169       }
00170       else
00171       {
00172          return QString::null; // Can't convert
00173       }
00174    }
00175 }
00176 
00177 QString KIDNA::toUnicode(const QString &idna)
00178 {
00179    if (!KIDNA_lib && !KIDNA_lib_load_failed)
00180    {
00181       KIDNA_load_lib();
00182    }
00183 
00184    if (KIDNA_lib_load_failed || !idnSupportForHost(idna))
00185    {
00186       return idna.lower(); // Return as is
00187    }
00188    else 
00189    {
00190       char *pOutput;
00191       if ((*KIDNA_utf8ace_to_utf8)(idna.utf8(), &pOutput, 0) == IDNA_SUCCESS)
00192       {
00193          QString result = QString::fromUtf8(pOutput);
00194          free(pOutput);
00195          return result;
00196       }
00197       else
00198       {
00199          return idna.lower(); // Return as is.
00200       }
00201    }
00202 }
KDE Logo
This file is part of the documentation for kdecore Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 14 09:16:06 2006 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003