32 #include <kprotocolinfo.h> 43 #include <tqstringlist.h> 45 #include <tqstylesheet.h> 47 #include <tqtextcodec.h> 51 # define KURL_ROOTDIR_PATH "C:/" 53 # define KURL_ROOTDIR_PATH "/" 56 static const TQString fileProt =
"file";
58 static TQTextCodec * codecForHint(
int encoding_hint )
60 return TQTextCodec::codecForMib( encoding_hint );
67 static TQString encode(
const TQString& segment,
int encoding_offset,
int encoding_hint,
bool isRawURI =
false )
69 const char *encode_string =
"/@<>#\"&?={}|^~[]\'`\\:+%";
70 encode_string += encoding_offset;
74 local = segment.local8Bit();
77 TQTextCodec * textCodec = codecForHint( encoding_hint );
79 local = segment.local8Bit();
81 local = textCodec->fromUnicode( segment );
84 int old_length = isRawURI ? local.size() - 1 : local.length();
87 return segment.isNull() ? TQString::null : TQString(
"");
90 TQChar *new_segment =
new TQChar[ old_length * 3 + 1 ];
93 for (
int i = 0; i < old_length; i++ )
99 unsigned char character = local[i];
100 if ( (character <= 32) || (character >= 127) ||
101 strchr(encode_string, character) )
103 new_segment[ new_length++ ] =
'%';
105 unsigned int c = character / 16;
106 c += (c > 9) ? (
'A' - 10) :
'0';
107 new_segment[ new_length++ ] = c;
110 c += (c > 9) ? (
'A' - 10) :
'0';
111 new_segment[ new_length++ ] = c;
115 new_segment[ new_length++ ] = (QChar)local[i];
118 TQString result = TQString(new_segment, new_length);
119 delete [] new_segment;
123 static TQString encodeHost(
const TQString& segment,
bool encode_slash,
int encoding_hint )
130 Q_UNUSED( encode_slash );
131 Q_UNUSED( encoding_hint );
132 TQString host = KIDNA::toAscii(segment);
137 return encode(segment, encode_slash ? 0 : 1, encoding_hint);
141 static int hex2int(
unsigned int _char )
143 if ( _char >=
'A' && _char <=
'F')
144 return _char -
'A' + 10;
145 if ( _char >=
'a' && _char <=
'f')
146 return _char -
'a' + 10;
147 if ( _char >=
'0' && _char <=
'9')
162 static TQString lazy_encode(
const TQString& segment,
bool encodeAt=
true )
164 int old_length = segment.length();
167 return TQString::null;
170 TQChar *new_segment =
new TQChar[ old_length * 3 + 1 ];
173 for (
int i = 0; i < old_length; i++ )
175 unsigned int character = segment[i].unicode();
178 if ((character < 32) ||
179 ((character ==
'%') &&
180 (i+2 < old_length) &&
181 (hex2int(segment[i+1].unicode())!= -1) &&
182 (hex2int(segment[i+2].unicode())!= -1)) ||
183 (character ==
'?') ||
184 ((character ==
'@') && encodeAt) ||
185 (character ==
'#') ||
186 ((character == 32) && (i+1 == old_length || segment[i+1] == (QChar)
' ')))
188 new_segment[ new_length++ ] =
'%';
190 unsigned int c = character / 16;
191 c += (c > 9) ? (
'A' - 10) :
'0';
192 new_segment[ new_length++ ] = c;
195 c += (c > 9) ? (
'A' - 10) :
'0';
196 new_segment[ new_length++ ] = c;
199 new_segment[ new_length++ ] = segment[i];
202 TQString result = TQString(new_segment, new_length);
203 delete [] new_segment;
207 static void decode(
const TQString& segment, TQString &decoded, TQString &encoded,
int encoding_hint=0,
bool updateDecoded =
true,
bool isRawURI =
false )
209 decoded = TQString::null;
212 int old_length = segment.length();
216 TQTextCodec *textCodec = 0;
218 textCodec = codecForHint( encoding_hint );
221 textCodec = TQTextCodec::codecForLocale();
223 TQCString csegment = textCodec->fromUnicode(segment);
225 if (textCodec->toUnicode(csegment) != segment)
228 textCodec = codecForHint( 106 );
229 csegment = textCodec->fromUnicode(segment);
231 old_length = csegment.length();
237 char *new_segment =
new char[ old_length + 1 ];
238 TQChar *new_usegment =
new TQChar[ old_length * 3 + 1 ];
241 while( i < old_length )
243 bool bReencode =
false;
244 unsigned char character = csegment[ i++ ];
245 if ((character <=
' ') || (character > 127))
248 new_usegment [ new_length2++ ] = character;
249 if (character ==
'%' )
251 int a = i+1 < old_length ? hex2int( csegment[i] ) : -1;
252 int b = i+1 < old_length ? hex2int( csegment[i+1] ) : -1;
253 if ((a == -1) || (b == -1))
261 character = a * 16 + b;
262 if (!isRawURI && !character && updateDecoded)
265 new_usegment [ new_length2++ ] = (
unsigned char) csegment[i++];
266 new_usegment [ new_length2++ ] = (
unsigned char) csegment[i++];
272 new_usegment [ new_length2++ ] =
'%';
274 unsigned int c = character / 16;
275 c += (c > 9) ? (
'A' - 10) :
'0';
276 new_usegment[ new_length2++ ] = c;
279 c += (c > 9) ? (
'A' - 10) :
'0';
280 new_usegment[ new_length2++ ] = c;
283 new_segment [ new_length++ ] = character;
285 new_segment [ new_length ] = 0;
287 encoded = TQString( new_usegment, new_length2);
292 decoded = textCodec->toUnicode( new_segment );
294 int length = tqstrlen( new_segment );
295 while ( length < new_length ) {
296 decoded += TQChar::null;
298 decoded += textCodec->toUnicode( new_segment + length );
299 length += tqstrlen( new_segment + length );
303 TQCString validate = textCodec->fromUnicode(decoded);
305 if (strcmp(validate.data(), new_segment) != 0)
307 decoded = TQString::fromLocal8Bit(new_segment, new_length);
311 delete [] new_segment;
312 delete [] new_usegment;
315 static TQString decode(
const TQString &segment,
int encoding_hint = 0,
bool isRawURI =
false)
319 decode(segment, result, tmp, encoding_hint,
true, isRawURI);
323 static TQString cleanpath(
const TQString &_path,
bool cleanDirSeparator,
bool decodeDots)
325 if (_path.isEmpty())
return TQString::null;
327 if (TQDir::isRelativePath(_path))
330 TQString path = _path;
332 int len = path.length();
339 TQString encodedDot(
"%2e");
341 if (path.find(encodedDot, 0,
false) != -1)
346 TQString encodedDOT(
"%2E");
348 path.replace(encodedDot,
".");
349 path.replace(encodedDOT,
".");
354 bool slash = (len && path[len-1] ==
'/') ||
355 (len > 1 && path[len-2] ==
'/' && path[len-1] ==
'.');
364 int cdUp, orig_pos, pos;
367 pos = orig_pos = len;
368 while ( pos && (pos = path.findRev(
'/',--pos)) != -1 )
370 len = orig_pos - pos - 1;
371 if ( len == 2 && path[pos+1] ==
'.' && path[pos+2] ==
'.' )
377 if ( (len || !cleanDirSeparator) &&
378 (len != 1 || path[pos+1] !=
'.' ) )
381 result.prepend(path.mid(pos, len+1));
389 #ifdef Q_WS_WIN // prepend drive letter if exists (js) 390 if (orig_pos >= 2 && isalpha(path[0].latin1()) && path[1]==
':') {
391 result.prepend(TQString(path[0])+
":");
395 if ( result.isEmpty() )
396 result = KURL_ROOTDIR_PATH;
397 else if ( slash && result[result.length()-1] !=
'/' )
405 int len = _url.length();
406 if (!len)
return true;
407 const TQChar *str = _url.unicode();
410 if (!isalpha(str[0].latin1()))
413 for(
int i = 1; i < len; i++)
415 char c = str[i].latin1();
420 if (!isalpha(c) && !isdigit(c) && (c !=
'+') && (c !=
'-'))
434 for (TQStringList::ConstIterator it = list.begin();
445 for( KURL::List::ConstIterator it = begin();
449 lst.append( (*it).url() );
468 parse( url, encoding_hint );
474 parse( TQString::fromLatin1(url), encoding_hint );
480 parse( TQString::fromLatin1(url), encoding_hint );
488 TQDataStream & operator<< (TQDataStream & s,
const KURL & a)
490 TQString QueryForWire=a.m_strQuery_encoded;
491 if (!a.m_strQuery_encoded.isNull())
492 QueryForWire.prepend(
"?");
494 s << a.m_strProtocol << a.m_strUser << a.m_strPass << a.m_strHost
495 << a.m_strPath << a.m_strPath_encoded << QueryForWire << a.m_strRef_encoded
496 << TQ_INT8(a.m_bIsMalformed ? 1 : 0) << a.m_iPort;
500 TQDataStream & operator>> (TQDataStream & s,
KURL & a)
503 TQString QueryFromWire;
504 s >> a.m_strProtocol >> a.m_strUser >> a.m_strPass >> a.m_strHost
505 >> a.m_strPath >> a.m_strPath_encoded >> QueryFromWire >> a.m_strRef_encoded
506 >> malf >> a.m_iPort;
507 a.m_bIsMalformed = (malf != 0);
509 if ( QueryFromWire.isNull() )
510 a.m_strQuery_encoded = TQString::null;
511 else if ( QueryFromWire.length() == 1 )
512 a.m_strQuery_encoded =
"";
514 a.m_strQuery_encoded = QueryFromWire.mid(1);
521 #ifndef QT_NO_NETWORKPROTOCOL 533 KURL u(lst.last(), _rel_url, encoding_hint);
534 lst.remove( lst.last() );
542 TQString rUrl = _rel_url;
543 int len = _u.m_strProtocol.length();
544 if ( !_u.m_strHost.isEmpty() && !rUrl.isEmpty() &&
545 rUrl.find( _u.m_strProtocol, 0,
false ) == 0 &&
546 rUrl[len] ==
':' && (rUrl[len+1] !=
'/' ||
547 (rUrl[len+1] ==
'/' && rUrl[len+2] !=
'/')) )
549 rUrl.remove( 0, rUrl.find(
':' ) + 1 );
552 if ( rUrl.isEmpty() )
556 else if ( rUrl[0] ==
'#' )
559 m_strRef_encoded = rUrl.mid(1);
560 if ( m_strRef_encoded.isNull() )
561 m_strRef_encoded =
"";
566 m_strQuery_encoded = TQString::null;
567 m_strRef_encoded = TQString::null;
570 if ((rUrl.length() > 1) && (rUrl[1] ==
'/'))
572 m_strHost = TQString::null;
574 if (_u.m_strProtocol == fileProt)
577 m_strPath = TQString::null;
578 m_strPath_encoded = TQString::null;
580 else if ( rUrl[0] !=
'?' )
582 int pos = m_strPath.findRev(
'/' );
584 m_strPath.truncate(pos);
586 if (!m_strPath_encoded.isEmpty())
588 pos = m_strPath_encoded.findRev(
'/' );
590 m_strPath_encoded.truncate(pos);
591 m_strPath_encoded +=
'/';
596 if ( m_strPath.isEmpty() )
599 KURL tmp(
url() + rUrl, encoding_hint);
605 KURL tmp( rUrl, encoding_hint);
608 if (!_u.m_strUser.isEmpty() && m_strUser.isEmpty() && (_u.m_strHost == m_strHost) && (_u.m_strProtocol == m_strProtocol))
610 m_strUser = _u.m_strUser;
611 m_strPass = _u.m_strPass;
619 m_strProtocol = TQString::null;
620 m_strUser = TQString::null;
621 m_strPass = TQString::null;
622 m_strHost = TQString::null;
623 m_strPath = TQString::null;
624 m_strPath_encoded = TQString::null;
625 m_strQuery_encoded = TQString::null;
626 m_strRef_encoded = TQString::null;
627 m_bIsMalformed =
true;
634 return (m_strPath.isEmpty() && m_strProtocol.isEmpty());
639 if ( _url.isEmpty() || m_iUriMode ==
Invalid )
641 m_strProtocol = _url;
646 const TQChar* buf = _url.unicode();
647 const TQChar* orig = buf;
648 uint len = _url.length();
652 TQChar x = buf[pos++];
655 const bool alpha = isalpha((
int)x);
658 if (alpha && buf[pos]==
':' && (len==2 || (len>2 && (buf[pos+1]==
'/' || buf[pos+1]==
'\\'))))
660 if ( x == (QChar)
'/' )
665 m_strProtocol = fileProt;
669 if ( !isalpha( (
int)x ) )
675 while( pos < len && (isalpha((
int)buf[pos]) || isdigit((
int)buf[pos]) ||
676 buf[pos] == (QChar)
'+' || buf[pos] == (QChar)
'-')) pos++;
678 if (pos < len && buf[pos] == (QChar)
':' )
680 m_strProtocol = TQString( orig, pos ).lower();
681 if ( m_iUriMode ==
Auto )
684 switch ( m_iUriMode )
703 m_strProtocol = _url;
709 uint len = _url.length();
710 const TQChar* buf = _url.unicode();
717 while( pos < len && (isalpha((
int)buf[pos]) || isdigit((
int)buf[pos]) ||
718 buf[pos] == (QChar)
'+' || buf[pos] == (QChar)
'-')) pos++;
721 if (pos < len && buf[pos] == (QChar)
':' )
725 m_strProtocol = _url;
731 m_strPath = TQString::null;
733 m_strPath = decode( TQString( buf + pos, len - pos ), encoding_hint,
true );
735 m_bIsMalformed =
false;
743 if ( m_bIsMalformed )
745 TQRegExp mailre(
"(.+@)(.+)");
746 if ( mailre.exactMatch( m_strPath ) )
749 TQString host = KIDNA::toUnicode( mailre.cap( 2 ) );
751 host = TQString(mailre.cap( 2 )).lower();
753 TQString host = TQString(mailre.cap( 2 )).lower();
755 m_strPath = mailre.cap( 1 ) +
host;
762 bool badHostName =
false;
764 uint len = _url.length();
765 const TQChar* buf = _url.unicode();
773 TQChar x = buf[pos++];
776 const bool alpha = isalpha((
int)x);
779 if (alpha && buf[pos]==(QChar)
':' && (len==2 || (len>2 && (buf[pos+1]==(QChar)
'/' || buf[pos+1]==(QChar)
'\\'))))
781 if ( x == (QChar)
'/' )
784 if ( !isalpha( (
int)x ) )
790 while( pos < len && (isalpha((
int)buf[pos]) || isdigit((
int)buf[pos]) ||
791 buf[pos] == (QChar)
'+' || buf[pos] == (QChar)
'-')) pos++;
794 if ( pos+2 < len && buf[pos] == (QChar)
':' && buf[pos+1] == (QChar)
'/' && buf[pos+2] == (QChar)
'/' )
798 else if (pos+1 < len && buf[pos] == (QChar)
':' )
813 if (buf[pos] == (QChar)
'[')
817 while( (x != (QChar)
':') && (x != (QChar)
'@') && (x != (QChar)
'/') && (x != (QChar)
'?') && (x != (QChar)
'#') )
819 if ((x == (QChar)
'\"') || (x == (QChar)
';') || (x == (QChar)
'<'))
830 setHost(decode(TQString( buf + start, pos - start ), encoding_hint));
833 if ( x == (QChar)
'@' )
835 m_strUser = decode(TQString( buf + start, pos - start ), encoding_hint);
839 else if ( (x == (QChar)
'/') || (x == (QChar)
'?') || (x == (QChar)
'#'))
844 setHost(decode(TQString( buf + start, pos - start ), encoding_hint));
848 else if ( x != (QChar)
':' )
850 m_strUser = decode(TQString( buf + start, pos - start ), encoding_hint);
859 while( (pos < len) &&
860 (buf[pos] != (QChar)
'@') &&
861 (buf[pos] != (QChar)
'/') &&
862 (buf[pos] != (QChar)
'?') &&
863 (buf[pos] != (QChar)
'#')) pos++;
866 if ( (pos == len) || (buf[pos] != (QChar)
'@') )
872 m_strUser = TQString::null;
873 TQString tmp( buf + start, pos - start );
875 m_iPort = (
unsigned short int)strtol(tmp.ascii(), &endptr, 10);
876 if ((pos == len) && (strlen(endptr) == 0))
879 pos -= strlen(endptr);
880 if ((buf[pos] != (QChar)
'@') &&
881 (buf[pos] != (QChar)
'/') &&
882 (buf[pos] != (QChar)
'?') &&
883 (buf[pos] != (QChar)
'#'))
889 m_strPass = decode(TQString( buf + start, pos - start), encoding_hint);
898 if (buf[pos] == (QChar)
'[')
911 while( (x != (QChar)
']') )
913 if ((x == (QChar)
'\"') || (x == (QChar)
';') || (x == (QChar)
'<'))
924 setHost(decode(TQString( buf + start, pos - start ), encoding_hint));
925 if (pos < len) pos++;
937 while( (x != (QChar)
':') && (x != (QChar)
'@') && (x != (QChar)
'/') && (x != (QChar)
'?') && (x != (QChar)
'#') )
939 if ((x == (QChar)
'\"') || (x == (QChar)
';') || (x == (QChar)
'<'))
949 setHost(decode(TQString( buf + start, pos - start ), encoding_hint));
952 setHost(decode(TQString( buf + start, pos - start ), encoding_hint));
955 if ( x == (QChar)
'/' || x == (QChar)
'#' || x == (QChar)
'?' )
960 else if ( x != (QChar)
':' )
968 if ( !isdigit( buf[pos++] ) )
972 while( pos < len && isdigit( buf[pos] ) ) pos++;
973 port = TQString( buf + start, pos - start );
974 m_iPort = port.toUShort();
981 while( pos < len && buf[pos] != (QChar)
'#' && buf[pos]!=(QChar)
'?' ) pos++;
983 tmp = TQString( buf + start, pos - start );
991 delim = (buf[pos++]==(QChar)
'#'?(QChar)
'?':(QChar)
'#');
995 while(pos < len && buf[pos]!=delim ) pos++;
997 tmp = TQString(buf + start, pos - start);
998 if (delim==(QChar)
'#')
999 _setQuery(tmp, encoding_hint);
1001 m_strRef_encoded = tmp;
1007 tmp = TQString( buf + pos + 1, len - pos - 1);
1008 if (delim == (QChar)
'#')
1009 m_strRef_encoded = tmp;
1011 _setQuery(tmp, encoding_hint);
1015 m_bIsMalformed =
false;
1018 if (m_strProtocol.isEmpty())
1021 m_strProtocol = fileProt;
1028 m_strProtocol = _url;
1043 parse( TQString::fromLatin1(_url) );
1048 #ifndef QT_NO_NETWORKPROTOCOL 1051 m_strProtocol = u.protocol();
1053 m_strUser = u.user();
1054 m_strPass = u.password();
1055 m_strHost = u.host();
1056 m_strPath = u.path(
false );
1057 m_strPath_encoded = TQString::null;
1058 m_strQuery_encoded = u.query();
1059 m_strRef_encoded = u.ref();
1060 m_bIsMalformed = !u.isValid();
1069 m_strProtocol = _u.m_strProtocol;
1070 m_strUser = _u.m_strUser;
1071 m_strPass = _u.m_strPass;
1072 m_strHost = _u.m_strHost;
1073 m_strPath = _u.m_strPath;
1074 m_strPath_encoded = _u.m_strPath_encoded;
1075 m_strQuery_encoded = _u.m_strQuery_encoded;
1076 m_strRef_encoded = _u.m_strRef_encoded;
1077 m_bIsMalformed = _u.m_bIsMalformed;
1078 m_iPort = _u.m_iPort;
1079 m_iUriMode = _u.m_iUriMode;
1091 i = m_strProtocol.compare(_u.m_strProtocol);
1099 i = m_strProtocol.compare(_u.m_strProtocol);
1100 if (i)
return (i < 0);
1102 i = m_strHost.compare(_u.m_strHost);
1103 if (i)
return (i < 0);
1105 if (m_iPort != _u.m_iPort)
return (m_iPort < _u.m_iPort);
1107 i = m_strPath.compare(_u.m_strPath);
1108 if (i)
return (i < 0);
1110 i = m_strQuery_encoded.compare(_u.m_strQuery_encoded);
1111 if (i)
return (i < 0);
1113 i = m_strRef_encoded.compare(_u.m_strRef_encoded);
1114 if (i)
return (i < 0);
1116 i = m_strUser.compare(_u.m_strUser);
1117 if (i)
return (i < 0);
1119 i = m_strPass.compare(_u.m_strPass);
1120 if (i)
return (i < 0);
1130 if ( m_strProtocol == _u.m_strProtocol &&
1131 m_strUser == _u.m_strUser &&
1132 m_strPass == _u.m_strPass &&
1133 m_strHost == _u.m_strHost &&
1134 m_strPath == _u.m_strPath &&
1136 ( m_strPath_encoded.isNull() || _u.m_strPath_encoded.isNull() ||
1137 m_strPath_encoded == _u.m_strPath_encoded ) &&
1138 m_strQuery_encoded == _u.m_strQuery_encoded &&
1139 m_strRef_encoded == _u.m_strRef_encoded &&
1140 m_iPort == _u.m_iPort )
1151 return ( *
this == u );
1156 return equals( u, ignore_trailing );
1164 if ( ignore_trailing )
1166 TQString path1 =
path(1);
1167 TQString path2 = _u.
path(1);
1168 if ( path1 != path2 )
1171 if ( m_strProtocol == _u.m_strProtocol &&
1172 m_strUser == _u.m_strUser &&
1173 m_strPass == _u.m_strPass &&
1174 m_strHost == _u.m_strHost &&
1175 m_strQuery_encoded == _u.m_strQuery_encoded &&
1176 m_strRef_encoded == _u.m_strRef_encoded &&
1177 m_iPort == _u.m_iPort )
1183 return ( *
this == _u );
1191 if ( m_strProtocol == _u.m_strProtocol &&
1192 m_strUser == _u.m_strUser &&
1193 m_strPass == _u.m_strPass &&
1194 m_strHost == _u.m_strHost &&
1195 m_strQuery_encoded == _u.m_strQuery_encoded &&
1196 m_strRef_encoded == _u.m_strRef_encoded &&
1197 m_iPort == _u.m_iPort )
1199 if (
path().isEmpty() || _u.
path().isEmpty() )
1202 TQString p1( cleanpath(
path(),
true,
false ) );
1203 if ( p1[p1.length()-1] !=
'/' )
1205 TQString p2( cleanpath( _u.
path(),
true, false ) );
1206 if ( p2[p2.length()-1] !=
'/' )
1213 return p2.startsWith( p1 );
1220 m_strRef_encoded = TQString::null;
1222 while( _txt[i] == (QChar)
'/' ) ++i;
1225 tmp = _txt.mid( i );
1229 TQString path = m_strPath_encoded.isEmpty() ? m_strPath : m_strPath_encoded;
1230 if ( path.isEmpty() )
1234 int lastSlash = path.findRev(
'/' );
1235 if ( lastSlash == -1)
1241 else if ( path.right(1) !=
"/" )
1242 path.truncate( lastSlash+1 );
1244 if (m_strPath_encoded.isEmpty())
1259 if (m_iUriMode !=
URL)
return;
1260 m_strPath = cleanpath(m_strPath, cleanDirSeparator,
false);
1262 m_strPath_encoded = cleanpath(m_strPath_encoded, cleanDirSeparator,
true);
1265 static TQString trailingSlash(
int _trailing,
const TQString &path )
1267 TQString result =
path;
1269 if ( _trailing == 0 )
1271 else if ( _trailing == 1 )
1273 int len = result.length();
1274 if ( (len == 0) || (result[ len - 1 ] != (QChar)
'/') )
1278 else if ( _trailing == -1 )
1280 if ( result ==
"/" )
1282 int len = result.length();
1283 while (len > 1 && result[ len - 1 ] == (QChar)
'/')
1287 result.truncate( len );
1292 return TQString::null;
1298 if (!m_strPath_encoded.isEmpty())
1300 m_strPath_encoded = trailingSlash( _trailing, m_strPath_encoded );
1302 m_strPath = trailingSlash( _trailing, m_strPath );
1309 if (!m_strPath_encoded.isEmpty() && encoding_hint == 0)
1311 tmp = trailingSlash( _trailing, m_strPath_encoded );
1315 tmp =
path( _trailing );
1316 if ( _no_empty_path && tmp.isEmpty() )
1318 if (m_iUriMode ==
Mailto)
1320 tmp = encode( tmp, 2, encoding_hint );
1324 tmp = encode( tmp, 1, encoding_hint );
1329 if (!m_strQuery_encoded.isNull())
1330 tmp +=
'?' + m_strQuery_encoded;
1336 m_strPath_encoded = _txt;
1338 decode( m_strPath_encoded, m_strPath, m_strPath_encoded, encoding_hint );
1340 if (m_strProtocol == fileProt)
1341 m_strPath_encoded = TQString::null;
1343 if ( m_iUriMode ==
Auto )
1350 int pos = _txt.find(
'?' );
1354 m_strQuery_encoded = TQString::null;
1359 _setQuery(_txt.right(_txt.length() - pos - 1), encoding_hint);
1365 return trailingSlash( _trailing,
path() );
1370 if ( (m_strProtocol != fileProt ) ||
hasSubURL() )
1373 if (m_strHost.isEmpty() || (m_strHost ==
"localhost"))
1376 char hostname[ 256 ];
1377 hostname[ 0 ] =
'\0';
1378 if (!gethostname( hostname, 255 ))
1379 hostname[
sizeof(hostname)-1] =
'\0';
1381 for(
char *p = hostname; *p; p++)
1384 return (m_strHost == hostname);
1392 TQString q =
query();
1394 if (!q.isEmpty() && (q[0] ==
'?'))
1397 TQStringList args = TQStringList::split(
'&', q);
1398 for(TQStringList::Iterator it = args.begin();
1402 if (s.startsWith(
"charset="))
1403 it = args.erase(it);
1407 if (!encoding.isEmpty())
1408 args.append(
"charset="+encode_string(encoding));
1411 _setQuery(TQString::null);
1413 _setQuery(args.join(
"&"));
1419 return TQString::null;
1421 TQString q =
query();
1424 return TQString::null;
1429 TQStringList args = TQStringList::split(
'&', q);
1430 for(TQStringList::ConstIterator it = args.begin();
1435 if (s.startsWith(
"charset="))
1438 return TQString::null;
1443 if ( m_strProtocol.isEmpty() || m_bIsMalformed )
1445 if (m_strRef_encoded.isEmpty())
1447 if (m_strRef_encoded.startsWith(
"gzip:"))
1449 if (m_strRef_encoded.startsWith(
"bzip:"))
1451 if (m_strRef_encoded.startsWith(
"bzip2:"))
1453 if (m_strRef_encoded.startsWith(
"tar:"))
1455 if (m_strRef_encoded.startsWith(
"ar:"))
1457 if (m_strRef_encoded.startsWith(
"zip:"))
1459 if (m_strRef_encoded.startsWith(
"lzma:"))
1461 if (m_strRef_encoded.startsWith(
"xz:"))
1463 if ( m_strProtocol ==
"error" )
1468 TQString
KURL::url(
int _trailing,
int encoding_hint )
const 1470 if( m_bIsMalformed )
1475 return m_strProtocol;
1478 TQString u = m_strProtocol;
1482 if (
hasHost() || (m_strProtocol == fileProt) )
1487 u += encode(m_strUser, 0, encoding_hint);
1491 u += encode(m_strPass, 0, encoding_hint);
1495 if ( m_iUriMode ==
URL )
1497 bool IPv6 = (m_strHost.find(
':') != -1);
1499 u +=
'[' + m_strHost +
']';
1501 u += encodeHost(m_strHost,
true, encoding_hint);
1502 if ( m_iPort != 0 ) {
1504 buffer.sprintf(
":%u", m_iPort );
1514 if ( m_iUriMode ==
URL || m_iUriMode ==
Mailto )
1517 u += encode( m_strPath, 21, encoding_hint,
true );
1522 u += m_strRef_encoded;
1530 if( m_bIsMalformed )
1535 return m_strProtocol;
1538 TQString u = m_strProtocol;
1542 if (
hasHost() || (m_strProtocol == fileProt) )
1547 u += encode(m_strUser, 0, 0);
1551 if ( m_iUriMode ==
URL )
1553 bool IPv6 = (m_strHost.find(
':') != -1);
1556 u +=
'[' + m_strHost +
']';
1560 u += lazy_encode(m_strHost);
1565 u += lazy_encode(m_strHost);
1567 if ( m_iPort != 0 ) {
1569 buffer.sprintf(
":%u", m_iPort );
1574 if (m_iUriMode ==
Mailto)
1576 u += lazy_encode( m_strPath,
false );
1580 u += trailingSlash( _trailing, lazy_encode( m_strPath ) );
1583 if (!m_strQuery_encoded.isNull())
1584 u +=
'?' + m_strQuery_encoded;
1589 u += m_strRef_encoded;
1601 return TQDir::convertSeparators(u);
1609 if (
isLocalFile() && m_strRef_encoded.isNull() && m_strQuery_encoded.isNull() ) {
1618 return TQStyleSheet::escape(
prettyURL());
1630 u.m_strRef_encoded = TQString::null;
1634 url =
KURL(url.m_strRef_encoded);
1638 ref = url.m_strRef_encoded;
1644 KURL::List::Iterator it;
1645 for( it = lst.begin() ; it != lst.end(); ++it )
1647 (*it).m_strRef_encoded =
ref;
1660 if (lst.isEmpty())
return KURL();
1663 KURL::List::ConstIterator first = lst.fromLast();
1664 for( KURL::List::ConstIterator it = first; it != lst.end(); --it )
1669 if (!u.m_strRef_encoded) u.m_strRef_encoded = tmp.
url();
1670 else u.m_strRef_encoded +=
"#" + tmp.
url();
1683 KURL::List::Iterator it = list.fromLast();
1684 return (*it).fileName(_strip_trailing_slash);
1686 const TQString &path = m_strPath;
1688 int len = path.length();
1692 if ( _strip_trailing_slash )
1694 while ( len >= 1 && path[ len - 1 ] == TQChar(
'/') )
1697 else if ( path[ len - 1 ] == TQChar(
'/') )
1701 if ( len == 1 && path[ 0 ] == TQChar(
'/') )
1706 if (!m_strPath_encoded.isEmpty())
1711 int i = m_strPath_encoded.findRev( TQChar(
'/'), len - 1 );
1712 TQString fileName_encoded = m_strPath_encoded.mid(i+1);
1713 n += fileName_encoded.contains(
"%2f",
false);
1717 i = path.findRev( TQChar(
'/'), i - 1 );
1719 while (--n && (i > 0));
1724 if ( len == (
int)path.length() )
1728 fname = path.left( len );
1732 fname = path.mid( i + 1, len - i - 1 );
1742 KURL &u = lst.last();
1744 *
this =
join( lst );
1748 m_strPath_encoded = TQString::null;
1750 if ( _txt.isEmpty() )
1754 int len = m_strPath.length();
1756 if ( _txt[0] != (QChar)
'/' && ( len == 0 || m_strPath[ len - 1 ] != (QChar)
'/' ) )
1761 if ( len != 0 && m_strPath[ len - 1 ] == (QChar)
'/' )
1763 while( _txt[i] == (QChar)
'/' )
1767 m_strPath += _txt.mid( i );
1771 bool _ignore_trailing_slash_in_path )
const 1773 TQString result = m_strPath_encoded.isEmpty() ? m_strPath : m_strPath_encoded;
1774 if ( _ignore_trailing_slash_in_path )
1775 result = trailingSlash( -1, result );
1777 if ( result.isEmpty() || result ==
"/" )
1780 int i = result.findRev(
"/" );
1784 return TQString::null;
1792 if ( _strip_trailing_slash_from_result )
1793 result = result.left( i );
1795 result = result.left( i + 1 );
1797 if (!m_strPath_encoded.isEmpty())
1798 result = decode(result);
1806 if ( _dir.isEmpty() || m_bIsMalformed )
1812 KURL &u = lst.last();
1814 *
this =
join( lst );
1819 if ( _dir[0] == (QChar)
'/' )
1821 m_strPath_encoded = TQString::null;
1824 m_strQuery_encoded = TQString::null;
1829 if ( ( _dir[0] == (QChar)
'~' ) && ( m_strProtocol == fileProt ))
1831 m_strPath_encoded = TQString::null;
1832 m_strPath = TQDir::homeDirPath();
1834 m_strPath += _dir.right(m_strPath.length() - 1);
1836 m_strQuery_encoded = TQString::null;
1845 TQString p =
path(1);
1847 p = cleanpath( p,
true,
false );
1851 m_strQuery_encoded = TQString::null;
1861 u._setQuery(TQString::null);
1880 KURL &u = lst.last();
1881 TQString old = u.
path();
1883 if (u.
path() != old)
1885 if (lst.count() == 1)
1887 lst.remove(lst.fromLast());
1896 return decode(
ref() );
1900 return decode( (*lst.begin()).
ref() );
1911 return (*lst.begin()).
ref();
1918 m_strRef_encoded = encode( _ref, 0, 0 );
1924 (*lst.begin()).
setRef( encode( _ref, 0, 0 ) );
1926 *
this =
join( lst );
1937 return (*lst.begin()).
hasRef();
1943 m_strProtocol = _txt;
1945 m_bIsMalformed =
false;
1951 if ( _txt.isEmpty() )
1952 m_strUser = TQString::null;
1960 if ( _txt.isEmpty() )
1961 m_strPass = TQString::null;
1969 if ( m_iUriMode ==
Auto )
1971 switch ( m_iUriMode )
1975 m_strHost = KIDNA::toUnicode(_txt);
1976 if (m_strHost.isEmpty())
1977 m_strHost = _txt.lower();
1979 m_strHost = _txt.lower();
1997 m_bIsMalformed =
false;
1998 if (m_strProtocol.isEmpty())
2000 m_strProtocol = fileProt;
2003 m_strPath_encoded = TQString::null;
2004 if ( m_iUriMode ==
Auto )
2010 if ( dir.endsWith(
"/"))
2018 if (_txt[0] == (QChar)
'?')
2019 _setQuery( _txt.length() > 1 ? _txt.mid(1) :
"" , encoding_hint );
2021 _setQuery( _txt, encoding_hint );
2025 void KURL::_setQuery(
const TQString &_txt,
int encoding_hint)
2027 m_strQuery_encoded = _txt;
2031 int l = m_strQuery_encoded.length();
2041 char c = m_strQuery_encoded[i].latin1();
2042 if ((c ==
'&') || (c ==
':') || (c ==
';') ||
2043 (c ==
'=') || (c ==
'/') || (c ==
'?'))
2049 TQString tmp = m_strQuery_encoded.mid(s, i-s);
2051 decode( tmp, newTmp, tmp, encoding_hint,
false );
2056 result += m_strQuery_encoded[i];
2060 m_strQuery_encoded = result;
2065 if (m_strQuery_encoded.isNull())
2066 return TQString::null;
2067 return '?'+m_strQuery_encoded;
2072 return decode(str, encoding_hint);
2077 return encode(str, 1, encoding_hint);
2082 return encode(str, 0, encoding_hint);
2085 bool urlcmp(
const TQString& _url1,
const TQString& _url2 )
2088 if ( _url1.isEmpty() && _url2.isEmpty() )
2091 if ( _url1.isEmpty() || _url2.isEmpty() )
2098 if ( list1.isEmpty() || list2.isEmpty() )
2101 return ( list1 == list2 );
2104 bool urlcmp(
const TQString& _url1,
const TQString& _url2,
bool _ignore_trailing,
bool _ignore_ref )
2107 if ( _url1.isEmpty() && _url2.isEmpty() )
2110 if ( _url1.isEmpty() || _url2.isEmpty() )
2117 if ( list1.isEmpty() || list2.isEmpty() )
2120 unsigned int size = list1.count();
2121 if ( list2.count() != size )
2126 (*list1.begin()).
setRef(TQString::null);
2127 (*list2.begin()).
setRef(TQString::null);
2130 KURL::List::Iterator it1 = list1.begin();
2131 KURL::List::Iterator it2 = list2.begin();
2132 for( ; it1 != list1.end() ; ++it1, ++it2 )
2133 if ( !(*it1).equals( *it2, _ignore_trailing ) )
2139 TQMap< TQString, TQString > KURL::queryItems(
int options )
const {
2140 return queryItems(options, 0);
2143 TQMap< TQString, TQString > KURL::queryItems(
int options,
int encoding_hint )
const {
2144 if ( m_strQuery_encoded.isEmpty() )
2145 return TQMap<TQString,TQString>();
2147 TQMap< TQString, TQString > result;
2148 TQStringList items = TQStringList::split(
'&', m_strQuery_encoded );
2149 for ( TQStringList::const_iterator it = items.begin() ; it != items.end() ; ++it ) {
2150 int equal_pos = (*it).find(
'=' );
2151 if ( equal_pos > 0 ) {
2152 TQString name = (*it).left( equal_pos );
2154 name = name.lower();
2155 TQString value = (*it).mid( equal_pos + 1 );
2156 if ( value.isEmpty() )
2157 result.insert( name, TQString::fromLatin1(
"") );
2160 value.replace(
'+',
' ' );
2161 result.insert( name,
decode_string( value, encoding_hint ) );
2163 }
else if ( equal_pos < 0 ) {
2164 TQString name = (*it);
2166 name = name.lower();
2167 result.insert( name, TQString::null );
2181 TQString item = _item +
'=';
2182 if ( m_strQuery_encoded.length() <= 1 )
2183 return TQString::null;
2185 TQStringList items = TQStringList::split(
'&', m_strQuery_encoded );
2186 unsigned int _len = item.length();
2187 for ( TQStringList::ConstIterator it = items.begin(); it != items.end(); ++it )
2189 if ( (*it).startsWith( item ) )
2191 if ( (*it).length() > _len )
2193 TQString str = (*it).mid( _len );
2194 str.replace(
'+',
' ' );
2198 return TQString::fromLatin1(
"");
2202 return TQString::null;
2207 TQString item = _item +
'=';
2208 if ( m_strQuery_encoded.length() <= 1 )
2211 TQStringList items = TQStringList::split(
'&', m_strQuery_encoded );
2212 for ( TQStringList::Iterator it = items.begin(); it != items.end(); )
2214 if ( (*it).startsWith( item ) || (*it == _item) )
2216 TQStringList::Iterator deleteIt = it;
2218 items.remove(deleteIt);
2225 m_strQuery_encoded = items.join(
"&" );
2230 TQString item = _item +
'=';
2231 TQString value = encode( _value, 0, encoding_hint );
2233 if (!m_strQuery_encoded.isEmpty())
2234 m_strQuery_encoded +=
'&';
2235 m_strQuery_encoded += item + value;
2241 if ( text.isEmpty() )
2245 if (!TQDir::isRelativePath(text))
2253 static TQString _relativePath(
const TQString &base_dir,
const TQString &path,
bool &isParent)
2255 TQString _base_dir(TQDir::cleanDirPath(base_dir));
2256 TQString _path(TQDir::cleanDirPath(path.isEmpty() || (path[0] != (QChar)
'/') ? _base_dir+
"/"+path :
path));
2258 if (_base_dir.isEmpty())
2261 if (_base_dir[_base_dir.length()-1] !=
'/')
2262 _base_dir.append(
'/');
2264 TQStringList list1 = TQStringList::split(
'/', _base_dir);
2265 TQStringList list2 = TQStringList::split(
'/', _path);
2269 uint maxLevel = QMIN(list1.count(), list2.count());
2270 while((level < maxLevel) && (list1[level] == list2[level])) level++;
2274 for(uint i = level; i < list1.count(); i++)
2275 result.append(
"../");
2278 for(uint i = level; i < list2.count(); i++)
2279 result.append(list2[i]).append(
"/");
2281 if ((level < list2.count()) && (path[path.length()-1] != (QChar)
'/'))
2282 result.truncate(result.length()-1);
2284 isParent = (level == list1.count());
2291 bool parent =
false;
2292 TQString result = _relativePath(base_dir, path, parent);
2294 result.prepend(
"./");
2311 return url.
url(0, encoding_hint);
2319 TQString basePath = base_url.
directory(
false,
false);
2320 relURL = encode( _relativePath(basePath, url.
path(), dummy), 1, encoding_hint);
2321 relURL += url.
query();
2327 relURL += url.
ref();
2330 if ( relURL.isEmpty() )
2345 if (protocol == fileProt)
2347 if (KGlobal::_instance)
2348 mode = KProtocolInfo::uriParseMode(protocol);
2349 if (mode ==
Auto ) {
2353 if ( protocol ==
"ed2k" || protocol ==
"sig2dat" || protocol ==
"slsk" || protocol ==
"data" ) mode =
RawURI;
2354 else if ( protocol ==
"mailto" ) mode =
Mailto;
void setQuery(const TQString &_txt, int encoding_hint=0)
Sets the encoded query of the URL.
Represents and parses a URL.
void setRef(const TQString &_txt)
Sets the encoded reference part (everything after '#')
bool equals(const KURL &u, bool ignore_trailing=false) const
Compares this URL with another one.
void parse(const TQString &_url, int encoding_hint=0)
Parses the given string and fills the URL's values on success.
bool hasRef() const
Tests if the URL has a reference part.
bool hasSubURL() const
Tests if the URL has any sub URLs.
KURL & operator=(const KURL &_u)
Copies the values of the given URL into this one.
static URIMode uriModeForProtocol(const TQString &protocol)
Determines which URI mode is suitable for processing URIs of a given protocol.
void adjustPath(int _trailing)
Adds or removes a trailing slash to/from the path.
TQString ref() const
Returns the encoded reference of the URL.
void addQueryItem(const TQString &_item, const TQString &_value, int encoding_hint=0)
Adds an additional query item.
URIMode
Defines the type of URI we are processing.
static bool isRelativeURL(const TQString &_url)
Tests if a given URL is a relative as opposed to an absolute URL.
TQString query() const
Returns the encoded query of the URL.
static const TQString & staticQString(const char *str)
Creates a static TQString.
TQString protocol() const
Returns the protocol for the URL.
TQString fileName(bool _ignore_trailing_slash_in_path=true) const
Returns the filename of the path.
bool hasPass() const
Tests if this URL has a password included in it.
void setEncodedPathAndQuery(const TQString &_txt, int encoding_hint=0)
Sets both path and query of the URL in their encoded form.
void parseRawURI(const TQString &_url, int encoding_hint=0)
Parses the given string and fills the URL's values on success.
unsigned short int port() const
Returns the port number included in the URL.
TQString pathOrURL() const
Returns the URL as a string depending if it is a local file.
TQString queryItem(const TQString &item) const
Returns the value of a certain query item.
void setUser(const TQString &_txt)
Sets the user name (login, user id, etc) to include in the URL.
bool isEmpty() const
Tests if the KURL is empty.
static List split(const TQString &_url)
Splits nested URLs into a list of URLs.
bool hasHost() const
Tests if this URL has a hostname included in it.
AdjustementFlags
Flags to choose how file: URLs are treated when creating their QString representation with prettyURL(...
static TQString relativeURL(const KURL &base_url, const KURL &url, int encoding_hint=0)
Creates an URL relative to a base URL for a given input URL.
TQString host() const
Returns the decoded hostname included in the URL.
TQString user() const
Returns the decoded user name (login, user id, etc) included in the URL.
void setFileName(const TQString &_txt)
Sets the filename of the path.
void setPass(const TQString &_txt)
Sets the password (corresponding to user()) to include in the URL.
bool isParentOf(const KURL &u) const
Tests if the given URL is parent of this URL.
KURL upURL() const
Returns the URL that is the best possible candidate for on level higher in the path hierachy...
bool isLocalFile() const
Tests if the file is local.
void removeQueryItem(const TQString &_item)
Removea an item from the query.
void setPath(const TQString &path)
Sets the decoded path of the URL.
void cleanPath(bool cleanDirSeparator=true)
Resolves "." and ".." components in path.
void parseURL(const TQString &_url, int encoding_hint=0)
Parses the given string and fills the URL's values on success.
int uriMode() const
Returns the URI processing mode for the URL.
TQString directory(bool _strip_trailing_slash_from_result=true, bool _ignore_trailing_slash_in_path=true) const
Returns the directory of the path.
bool operator<(const KURL &_u) const
Tests if this URL is less than the given URL.
TQStringList toStringList() const
Converts the URLs of this list to a list of strings.
void setHost(const TQString &_txt)
Sets the hostname to include in the URL.
static TQString encode_string_no_slash(const TQString &str, int encoding_hint=0)
Encodes a string for use in URLs.
bool hasUser() const
Tests if this URL has a user name included in it.
TQString encodedPathAndQuery(int _trailing=0, bool _no_empty_path=false, int encoding_hint=0) const
Returns the encoded path and the query.
Strip the file: protocol from the string, i.e.
static TQString encode_string(const TQString &str, int encoding_hint=0)
Encodes a string for use in URLs.
KURL()
Constructs an empty URL.
bool urlcmp(const TQString &_url1, const TQString &_url2)
bool hasHTMLRef() const
Tests if there is an HTML-style reference.
bool cd(const TQString &_dir)
Changes the directory by descending into the given directory.
bool cmp(const KURL &u, bool ignore_trailing=false) const KDE_DEPRECATED
Compares this URL with another one.
~KURL()
Destructs the KURL object.
TQString htmlURL() const
Returns the URL as string, escaped for HTML.
void setDirectory(const TQString &dir)
Sets the directory of the path, leaving the filename empty.
static TQString decode_string(const TQString &str, int encoding_hint=0)
Decodes a string as used in URLs.
void addPath(const TQString &txt)
Adds to the current path.
void setHTMLRef(const TQString &_ref)
Sets the decoded HTML-style reference.
TQString url(int _trailing=0, int encoding_hint=0) const
Returns the URL as string, with all escape sequences intact, encoded in a given charset.
TQString path() const
Returns the current decoded path.
static TQString relativePath(const TQString &base_dir, const TQString &path, bool *isParent=0)
Creates a path relative to a base path for a given input path.
TQString encodedHtmlRef() const
Returns the encoded HTML-style reference (the part of the URL after '#')
void setEncodedPath(const TQString &_txt, int encoding_hint=0)
Sets the (already encoded) path of the URL.
void parseMailto(const TQString &_url, int encoding_hint=0)
Parses the given string and fills the URL's values on success.
void setPort(unsigned short int _p)
Sets the port number to include in the URL.
Normalize query keys to lowercase.
bool operator==(const KURL &_u) const
Tests if this URL is equal to the given one.
void setFileEncoding(const TQString &encoding)
Adds file encoding information.
void reset()
Resets the members to their "null" state.
KURL::List is a TQValueList that contains KURLs with a few convenience methods.
TQString fileEncoding() const
Returns encoding information of the URL.
static KURL join(const List &_list)
Joins a list of URLs into a single URL with sub URLs.
List()
Creates an empty List.
TQString pass() const
Returns the decoded password (corresponding to user()) included in the URL.
bool isValid() const
Tests if the URL is well formed.
TQString prettyURL(int _trailing=0) const
Returns the URL as string in human-friendly format.
TQString htmlRef() const
Returns decoded the HTML-style reference (the part of the URL after '#')
void setProtocol(const TQString &_txt)
Sets the protocol for the URL.
static KURL fromPathOrURL(const TQString &text)
Creates a KURL object from a TQString representing either an absolute path or a real URL...