summaryrefslogtreecommitdiffabout
path: root/microkde/kurl.cpp
authorMichael Krelin <hacker@klever.net>2007-07-04 11:23:42 (UTC)
committer Michael Krelin <hacker@klever.net>2007-07-04 11:23:42 (UTC)
commita08aff328d4393031d5ba7d622c2b05705a89d73 (patch) (side-by-side diff)
tree8ee90d686081c52e7c69b5ce946e9b1a7d690001 /microkde/kurl.cpp
parent11edc920afe4f274c0964436633aa632c8288a40 (diff)
downloadkdepimpi-a08aff328d4393031d5ba7d622c2b05705a89d73.zip
kdepimpi-a08aff328d4393031d5ba7d622c2b05705a89d73.tar.gz
kdepimpi-a08aff328d4393031d5ba7d622c2b05705a89d73.tar.bz2
initial public commit of qt4 portp1
Diffstat (limited to 'microkde/kurl.cpp') (more/less context) (show whitespace changes)
-rw-r--r--microkde/kurl.cpp30
1 files changed, 16 insertions, 14 deletions
diff --git a/microkde/kurl.cpp b/microkde/kurl.cpp
index 2574e25..122ad71 100644
--- a/microkde/kurl.cpp
+++ b/microkde/kurl.cpp
@@ -5,131 +5,133 @@
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "kurl.h"
#ifndef KDE_QT_ONLY
#include <kdebug.h>
#include <kglobal.h>
//US#include <kidna.h>
#endif
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#ifdef _WIN32_
#else
#include <unistd.h>
#endif
-#include <qurl.h>
+#include <q3url.h>
#include <qdir.h>
#include <qstringlist.h>
#include <qregexp.h>
//US#include <qstylesheet.h>
#include <qmap.h>
#include <qtextcodec.h>
+//Added by qt3to4:
+#include <Q3CString>
static const QString fileProt = "file";
static QTextCodec * codecForHint( int encoding_hint /* not 0 ! */ )
{
return QTextCodec::codecForMib( encoding_hint );
}
static QString encode( const QString& segment, bool encode_slash, int encoding_hint )
{
const char *encode_string;
if (encode_slash)
encode_string = "<>#@\"&%?={}|^~[]\'`\\:+/";
else
encode_string = "<>#@\"&%?={}|^~[]\'`\\:+";
- QCString local;
+ Q3CString local;
if (encoding_hint==0)
local = segment.local8Bit();
else
{
QTextCodec * textCodec = codecForHint( encoding_hint );
if (!textCodec)
local = segment.local8Bit();
else
local = textCodec->fromUnicode( segment );
}
int old_length = local.length();
if ( !old_length )
return segment.isNull() ? QString::null : QString(""); // differenciate null and empty
// a worst case approximation
QChar *new_segment = new QChar[ old_length * 3 + 1 ];
int new_length = 0;
for ( int i = 0; i < old_length; i++ )
{
// 'unsave' and 'reserved' characters
// according to RFC 1738,
// 2.2. URL Character Encoding Issues (pp. 3-4)
// WABA: Added non-ascii
unsigned char character = local[i];
if ( (character <= 32) || (character >= 127) ||
strchr(encode_string, character) )
{
new_segment[ new_length++ ] = '%';
unsigned int c = character / 16;
c += (c > 9) ? ('A' - 10) : '0';
new_segment[ new_length++ ] = c;
c = character % 16;
c += (c > 9) ? ('A' - 10) : '0';
new_segment[ new_length++ ] = c;
}
else
- new_segment[ new_length++ ] = local[i];
+ new_segment[ new_length++ ] = character;
}
QString result = QString(new_segment, new_length);
delete [] new_segment;
return result;
}
static QString encodeHost( const QString& segment, bool encode_slash, int encoding_hint )
{
// Hostnames are encoded differently
// we use the IDNA transformation instead
// Note: when merging qt-addon, use QResolver::domainToAscii here
#ifndef KDE_QT_ONLY
Q_UNUSED( encode_slash );
Q_UNUSED( encoding_hint );
return KIDNA::toAscii(segment);
#else
return encode(segment, encode_slash, encoding_hint);
#endif
}
static int hex2int( unsigned int _char )
{
if ( _char >= 'A' && _char <='F')
return _char - 'A' + 10;
if ( _char >= 'a' && _char <='f')
return _char - 'a' + 10;
if ( _char >= '0' && _char <='9')
return _char - '0';
return -1;
}
@@ -176,65 +178,65 @@ static QString lazy_encode( const QString& segment )
c += (c > 9) ? ('A' - 10) : '0';
new_segment[ new_length++ ] = c;
c = character % 16;
c += (c > 9) ? ('A' - 10) : '0';
new_segment[ new_length++ ] = c;
}
else
new_segment[ new_length++ ] = segment[i];
}
QString result = QString(new_segment, new_length);
delete [] new_segment;
return result;
}
static void decode( const QString& segment, QString &decoded, QString &encoded, int encoding_hint=0, bool updateDecoded = true )
{
decoded = QString::null;
encoded = segment;
int old_length = segment.length();
if ( !old_length )
return;
QTextCodec *textCodec = 0;
if (encoding_hint)
textCodec = codecForHint( encoding_hint );
if (!textCodec)
textCodec = QTextCodec::codecForLocale();
- QCString csegment = textCodec->fromUnicode(segment);
+ Q3CString csegment = textCodec->fromUnicode(segment);
// Check if everything went ok
if (textCodec->toUnicode(csegment) != segment)
{
// Uh oh
textCodec = codecForHint( 106 ); // Fall back to utf-8
csegment = textCodec->fromUnicode(segment);
}
old_length = csegment.length();
int new_length = 0;
int new_length2 = 0;
// make a copy of the old one
char *new_segment = new char[ old_length + 1 ];
QChar *new_usegment = new QChar[ old_length * 3 + 1 ];
int i = 0;
while( i < old_length )
{
bool bReencode = false;
unsigned char character = csegment[ i++ ];
if ((character <= ' ') || (character > 127))
bReencode = true;
new_usegment [ new_length2++ ] = character;
if (character == '%' )
{
int a = i+1 < old_length ? hex2int( csegment[i] ) : -1;
int b = i+1 < old_length ? hex2int( csegment[i+1] ) : -1;
if ((a == -1) || (b == -1)) // Only replace if sequence is valid
{
// Contains stray %, make sure to re-encode!
@@ -249,65 +251,65 @@ static void decode( const QString& segment, QString &decoded, QString &encoded,
new_usegment [ new_length2++ ] = (unsigned char) csegment[i++];
new_usegment [ new_length2++ ] = (unsigned char) csegment[i++];
}
}
if (bReencode)
{
new_length2--;
new_usegment [ new_length2++ ] = '%';
unsigned int c = character / 16;
c += (c > 9) ? ('A' - 10) : '0';
new_usegment[ new_length2++ ] = c;
c = character % 16;
c += (c > 9) ? ('A' - 10) : '0';
new_usegment[ new_length2++ ] = c;
}
new_segment [ new_length++ ] = character;
}
new_segment [ new_length ] = 0;
encoded = QString( new_usegment, new_length2);
// Encoding specified
if (updateDecoded)
{
QByteArray array;
array.setRawData(new_segment, new_length);
decoded = textCodec->toUnicode( array, new_length );
array.resetRawData(new_segment, new_length);
- QCString validate = textCodec->fromUnicode(decoded);
+ Q3CString validate = textCodec->fromUnicode(decoded);
if (strcmp(validate.data(), new_segment) != 0)
{
decoded = QString::fromLocal8Bit(new_segment, new_length);
}
}
delete [] new_segment;
delete [] new_usegment;
}
static QString decode(const QString &segment, int encoding_hint = 0)
{
QString result;
QString tmp;
decode(segment, result, tmp, encoding_hint);
return result;
}
static QString cleanpath(const QString &path, bool cleanDirSeparator=true)
{
if (path.isEmpty()) return QString::null;
int len = path.length();
bool slash = (len && path[len-1] == '/') ||
(len > 1 && path[len-2] == '/' && path[len-1] == '.');
// The following code cleans up directory path much like
// QDir::cleanDirPath() except it can be made to ignore multiple
// directory separators by setting the flag to false. That fixes
// bug# 15044, mail.altavista.com and other similar brain-dead server
// implementations that do not follow what has been specified in
// RFC 2396!! (dA)
@@ -390,106 +392,106 @@ QStringList KURL::List::toStringList() const
for( KURL::List::ConstIterator it = begin();
it != end();
it++)
{
lst.append( (*it).url() );
}
return lst;
}
KURL::KURL()
{
reset();
}
KURL::~KURL()
{
}
KURL::KURL( const QString &url, int encoding_hint )
{
reset();
parse( url, encoding_hint );
}
KURL::KURL( const char * url, int encoding_hint )
{
reset();
parse( QString::fromLatin1(url), encoding_hint );
}
-KURL::KURL( const QCString& url, int encoding_hint )
+KURL::KURL( const Q3CString& url, int encoding_hint )
{
reset();
parse( QString::fromLatin1(url), encoding_hint );
}
KURL::KURL( const KURL& _u )
{
*this = _u;
}
QDataStream & operator<< (QDataStream & s, const KURL & a)
{
QString QueryForWire=a.m_strQuery_encoded;
if (!a.m_strQuery_encoded.isNull())
QueryForWire.prepend("?");
s << a.m_strProtocol << a.m_strUser << a.m_strPass << a.m_strHost
<< a.m_strPath << a.m_strPath_encoded << QueryForWire << a.m_strRef_encoded
<< Q_INT8(a.m_bIsMalformed ? 1 : 0) << a.m_iPort;
return s;
}
QDataStream & operator>> (QDataStream & s, KURL & a)
{
Q_INT8 malf;
QString QueryFromWire;
s >> a.m_strProtocol >> a.m_strUser >> a.m_strPass >> a.m_strHost
>> a.m_strPath >> a.m_strPath_encoded >> QueryFromWire >> a.m_strRef_encoded
>> malf >> a.m_iPort;
a.m_bIsMalformed = (malf != 0);
if ( QueryFromWire.isEmpty() )
a.m_strQuery_encoded = QString::null;
else
a.m_strQuery_encoded = QueryFromWire.mid(1);
return s;
}
#ifndef QT_NO_NETWORKPROTOCOL
-KURL::KURL( const QUrl &u )
+KURL::KURL( const Q3Url &u )
{
*this = u;
}
#endif
KURL::KURL( const KURL& _u, const QString& _rel_url, int encoding_hint )
{
// WORKAROUND THE RFC 1606 LOOPHOLE THAT ALLOWS
// http:/index.html AS A VALID SYNTAX FOR RELATIVE
// URLS. ( RFC 2396 section 5.2 item # 3 )
QString rUrl = _rel_url;
int len = _u.m_strProtocol.length();
if ( !_u.m_strHost.isEmpty() && !rUrl.isEmpty() &&
rUrl.find( _u.m_strProtocol, 0, false ) == 0 &&
rUrl[len] == ':' && (rUrl[len+1] != '/' ||
(rUrl[len+1] == '/' && rUrl[len+2] != '/')) )
{
rUrl.remove( 0, rUrl.find( ':' ) + 1 );
}
if ( rUrl.isEmpty() )
{
*this = _u;
}
else if ( rUrl[0] == '#' )
{
*this = _u;
QString ref = decode(rUrl.mid(1), encoding_hint);
if ( ref.isNull() )
ref = ""; // we know there was an (empty) html ref, we saw the '#'
setHTMLRef( ref );
}
@@ -560,71 +562,71 @@ void KURL::reset()
bool KURL::isEmpty() const
{
return (m_strPath.isEmpty() && m_strProtocol.isEmpty());
}
void KURL::parse( const QString& _url, int encoding_hint )
{
//kdDebug(126) << "parse " << _url << endl;
// Return immediately whenever the given url
// is empty or null.
if ( _url.isEmpty() )
{
m_strProtocol = _url;
return;
}
QString port;
bool badHostName = false;
int start = 0;
uint len = _url.length();
const QChar* buf = _url.unicode();
const QChar* orig = buf;
QChar delim;
QString tmp;
uint pos = 0;
// Node 1: Accept alpha or slash
QChar x = buf[pos++];
if ( x == '/' )
goto Node9;
- if ( !isalpha( (int)x ) )
+ if ( !x.isLetter() )
goto NodeErr;
// Node 2: Accept any amount of (alpha|digit|'+'|'-')
// '.' is not currently accepted, because current KURL may be confused.
// Proceed with :// :/ or :
- while( pos < len && (isalpha((int)buf[pos]) || isdigit((int)buf[pos]) ||
+ while( pos < len && ( buf[pos].isLetter() || buf[pos].isDigit() ||
buf[pos] == '+' || buf[pos] == '-')) pos++;
if ( pos+2 < len && buf[pos] == ':' && buf[pos+1] == '/' && buf[pos+2] == '/' )
{
m_strProtocol = QString( orig, pos ).lower();
pos += 3;
}
else if (pos+1 < len && buf[pos] == ':' ) // Need to always compare length()-1 otherwise KURL passes "http:" as legal!!
{
m_strProtocol = QString( orig, pos ).lower();
//kdDebug(126)<<"setting protocol to "<<m_strProtocol<<endl;
pos++;
start = pos;
goto Node9;
}
else
goto NodeErr;
//Node 3: We need at least one character here
if ( pos == len )
goto NodeErr;
start = pos;
// Node 4: Accept any amount of characters.
if (buf[pos] == '[') // An IPv6 host follows.
goto Node8;
// Terminate on / or @ or ? or # or " or ; or <
x = buf[pos];
while( (x != ':') && (x != '@') && (x != '/') && (x != '?') && (x != '#') )
{
if ((x == '\"') || (x == ';') || (x == '<'))
badHostName = true;
@@ -740,69 +742,69 @@ void KURL::parse( const QString& _url, int encoding_hint )
x = buf[pos];
while( (x != ':') && (x != '@') && (x != '/') && (x != '?') && (x != '#') )
{
if ((x == '\"') || (x == ';') || (x == '<'))
badHostName = true;
if (++pos == len)
break;
x = buf[pos];
}
if (badHostName)
goto NodeErr;
if ( pos == len )
{
setHost(decode(QString( buf + start, pos - start ), encoding_hint));
goto NodeOk;
}
setHost(decode(QString( buf + start, pos - start ), encoding_hint));
}
x = buf[pos];
if ( x == '/' )
{
start = pos++;
goto Node9;
}
else if ( x != ':' )
goto NodeErr;
pos++;
// Node 8a: Accept at least one digit
if ( pos == len )
goto NodeErr;
start = pos;
- if ( !isdigit( buf[pos++] ) )
+ if ( !buf[pos++].isDigit() )
goto NodeErr;
// Node 8b: Accept any amount of digits
- while( pos < len && isdigit( buf[pos] ) ) pos++;
+ while( pos < len && buf[pos].isDigit() ) pos++;
port = QString( buf + start, pos - start );
m_iPort = port.toUShort();
if ( pos == len )
goto NodeOk;
start = pos++;
Node9: // parse path until query or reference reached
while( pos < len && buf[pos] != '#' && buf[pos]!='?' ) pos++;
tmp = QString( buf + start, pos - start );
//kdDebug(126)<<" setting encoded path&query to:"<<tmp<<endl;
setEncodedPath( tmp, encoding_hint );
if ( pos == len )
goto NodeOk;
//Node10: // parse query or reference depending on what comes first
delim = (buf[pos++]=='#'?'?':'#');
start = pos;
while(pos < len && buf[pos]!=delim ) pos++;
tmp = QString(buf + start, pos - start);
if (delim=='#')
setQuery(tmp, encoding_hint);
else
m_strRef_encoded = tmp;
if (pos == len)
goto NodeOk;
@@ -819,65 +821,65 @@ void KURL::parse( const QString& _url, int encoding_hint )
m_bIsMalformed = false; // Valid URL
//kdDebug()<<"Prot="<<m_strProtocol<<"\nUser="<<m_strUser<<"\nPass="<<m_strPass<<"\nHost="<<m_strHost<<"\nPath="<<m_strPath<<"\nQuery="<<m_strQuery_encoded<<"\nRef="<<m_strRef_encoded<<"\nPort="<<m_iPort<<endl;
if (m_strProtocol.isEmpty())
{
m_strProtocol = fileProt;
}
return;
NodeErr:
// kdDebug(126) << "KURL couldn't parse URL \"" << _url << "\"" << endl;
reset();
m_strProtocol = _url;
}
KURL& KURL::operator=( const QString& _url )
{
reset();
parse( _url );
return *this;
}
KURL& KURL::operator=( const char * _url )
{
reset();
parse( QString::fromLatin1(_url) );
return *this;
}
#ifndef QT_NO_NETWORKPROTOCOL
-KURL& KURL::operator=( const QUrl & u )
+KURL& KURL::operator=( const Q3Url & u )
{
m_strProtocol = u.protocol();
m_strUser = u.user();
m_strPass = u.password();
m_strHost = u.host();
m_strPath = u.path( FALSE );
m_strPath_encoded = QString::null;
m_strQuery_encoded = u.query();
m_strRef_encoded = u.ref();
m_bIsMalformed = !u.isValid();
m_iPort = u.port();
return *this;
}
#endif
KURL& KURL::operator=( const KURL& _u )
{
m_strProtocol = _u.m_strProtocol;
m_strUser = _u.m_strUser;
m_strPass = _u.m_strPass;
m_strHost = _u.m_strHost;
m_strPath = _u.m_strPath;
m_strPath_encoded = _u.m_strPath_encoded;
m_strQuery_encoded = _u.m_strQuery_encoded;
m_strRef_encoded = _u.m_strRef_encoded;
m_bIsMalformed = _u.m_bIsMalformed;
m_iPort = _u.m_iPort;
return *this;
}
@@ -1345,109 +1347,109 @@ KURL::List KURL::split( const KURL& _url )
{
ref = url.m_strRef_encoded;
break;
}
}
// Set HTML ref in all URLs.
KURL::List::Iterator it;
for( it = lst.begin() ; it != lst.end(); ++it )
{
(*it).m_strRef_encoded = ref;
}
return lst;
}
KURL::List KURL::split( const QString& _url )
{
return split(KURL(_url));
}
KURL KURL::join( const KURL::List & lst )
{
if (lst.isEmpty()) return KURL();
KURL tmp;
KURL::List::ConstIterator first = lst.fromLast();
for( KURL::List::ConstIterator it = first; it != lst.end(); --it )
{
KURL u(*it);
if (it != first)
{
- if (!u.m_strRef_encoded) u.m_strRef_encoded = tmp.url();
+ if (u.m_strRef_encoded.isEmpty()) u.m_strRef_encoded = tmp.url();
else u.m_strRef_encoded += "#" + tmp.url(); // Support more than one suburl thingy
}
tmp = u;
}
return tmp;
}
QString KURL::fileName( bool _strip_trailing_slash ) const
{
QString fname;
if (hasSubURL()) { // If we have a suburl, then return the filename from there
KURL::List list = KURL::split(*this);
KURL::List::Iterator it = list.fromLast();
return (*it).fileName(_strip_trailing_slash);
}
const QString &path = m_strPath;
int len = path.length();
if ( len == 0 )
return fname;
if ( _strip_trailing_slash )
{
while ( len >= 1 && path[ len - 1 ] == '/' )
len--;
}
else if ( path[ len - 1 ] == '/' )
return fname;
// Does the path only consist of '/' characters ?
if ( len == 1 && path[ 0 ] == '/' )
return fname;
// Skip last n slashes
int n = 1;
if (!m_strPath_encoded.isEmpty())
{
// This is hairy, we need the last unencoded slash.
// Count in the encoded string how many encoded slashes follow the last
// unencoded one.
int i = m_strPath_encoded.findRev( '/', len - 1 );
QString fileName_encoded = m_strPath_encoded.mid(i+1);
- n += fileName_encoded.contains("%2f", false);
+ n += fileName_encoded.count("%2f", Qt::CaseInsensitive);
}
int i = len;
do {
i = path.findRev( '/', i - 1 );
}
while (--n && (i > 0));
// If ( i == -1 ) => the first character is not a '/'
// So it's some URL like file:blah.tgz, return the whole path
if ( i == -1 ) {
if ( len == (int)path.length() )
fname = path;
else
// Might get here if _strip_trailing_slash is true
fname = path.left( len );
}
else
{
fname = path.mid( i + 1, len - i - 1 ); // TO CHECK
}
return fname;
}
void KURL::addPath( const QString& _txt )
{
if (hasSubURL())
{
KURL::List lst = split( *this );
KURL &u = lst.last();
u.addPath(_txt);
*this = join( lst );
return;