Qt 4.8
qurl.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
200 #include "qplatformdefs.h"
201 #include "qurl.h"
202 #include "qatomic.h"
203 #include "qbytearray.h"
204 #include "qdir.h"
205 #include "qfile.h"
206 #include "qlist.h"
207 #ifndef QT_NO_REGEXP
208 #include "qregexp.h"
209 #endif
210 #include "qstring.h"
211 #include "qstringlist.h"
212 #include "qstack.h"
213 #include "qvarlengtharray.h"
214 #include "qdebug.h"
215 #if defined QT3_SUPPORT
216 #include "qfileinfo.h"
217 #endif
218 #ifndef QT_BOOTSTRAPPED
219 #include "qtldurl_p.h"
220 #endif
221 #if defined(Q_OS_WINCE_WM)
222 #pragma optimize("g", off)
223 #endif
224 #include "qmutex.h"
225 #include "private/qorderedmutexlocker_p.h"
226 
228 
229 extern void q_normalizePercentEncoding(QByteArray *ba, const char *exclude);
230 extern void q_toPercentEncoding(QByteArray *ba, const char *exclude, const char *include = 0);
231 extern void q_fromPercentEncoding(QByteArray *ba);
232 
233 static QByteArray toPercentEncodingHelper(const QString &s, const char *exclude, const char *include = 0)
234 {
235  if (s.isNull())
236  return QByteArray(); // null
237  QByteArray ba = s.toUtf8();
238  q_toPercentEncoding(&ba, exclude, include);
239  return ba;
240 }
241 
243 {
244  if (ba.isNull())
245  return QString(); // null
246  QByteArray copy = ba;
247  q_fromPercentEncoding(&copy);
248  return QString::fromUtf8(copy.constData(), copy.length());
249 }
250 
252 {
253  if (ba->isNull())
254  return QString(); // null
256  return QString::fromUtf8(ba->constData(), ba->length());
257 }
258 
259 // ### Qt 5: Consider accepting empty strings as valid. See task 144227.
260 
261 //#define QURL_DEBUG
262 
263 // implemented in qvsnprintf.cpp
264 Q_CORE_EXPORT int qsnprintf(char *str, size_t n, const char *fmt, ...);
265 
266 // needed by the punycode encoder/decoder
267 #define Q_MAXINT ((uint)((uint)(-1)>>1))
268 static const uint base = 36;
269 static const uint tmin = 1;
270 static const uint tmax = 26;
271 static const uint skew = 38;
272 static const uint damp = 700;
273 static const uint initial_bias = 72;
274 static const uint initial_n = 128;
275 
276 #define QURL_SETFLAG(a, b) { (a) |= (b); }
277 #define QURL_UNSETFLAG(a, b) { (a) &= ~(b); }
278 #define QURL_HASFLAG(a, b) (((a) & (b)) == (b))
279 
281  inline QUrlErrorInfo() : _source(0), _message(0), _expected(0), _found(0)
282  { }
283 
284  const char *_source;
285  const char *_message;
286  char _expected;
287  char _found;
288 
289  inline void setParams(const char *source, const char *message, char expected, char found)
290  {
291  _source = source;
292  _message = message;
293  _expected = expected;
294  _found = found;
295  }
296 };
297 
299 {
300  const char *scheme;
302 
303  const char *userInfo;
306 
307  const char *host;
309  int port;
310 
311  const char *path;
313  const char *query;
315  const char *fragment;
317 };
318 
319 
321 {
322 public:
323  QUrlPrivate();
324  QUrlPrivate(const QUrlPrivate &other);
325 
326  bool setUrl(const QString &url);
327 
328  QString canonicalHost() const;
329  void ensureEncodedParts() const;
330  QString authority(QUrl::FormattingOptions options = QUrl::None) const;
331  void setAuthority(const QString &auth);
332  void setUserInfo(const QString &userInfo);
333  QString userInfo(QUrl::FormattingOptions options = QUrl::None) const;
334  void setEncodedAuthority(const QByteArray &authority);
335  void setEncodedUserInfo(const QUrlParseData *parseData);
336  void setEncodedUrl(const QByteArray &encodedUrl, QUrl::ParsingMode parsingMode);
337  QString fragmentImpl() const;
338 
339  QByteArray mergePaths(const QByteArray &relativePath) const;
340 
341  void queryItem(int pos, int *value, int *end);
342 
345  ParseOnly
346  };
347 
348  void validate() const;
349  void parse(ParseOptions parseOptions = ParseAndSet) const;
350  void clear();
351 
352  QByteArray toEncoded(QUrl::FormattingOptions options = QUrl::None) const;
353 
355 
363 
369 
370  int port;
372 
373  bool hasQuery;
375  bool isValid;
377 
380 
381  enum State {
382  Parsed = 0x1,
383  Validated = 0x2,
384  Normalized = 0x4,
385  HostCanonicalized = 0x8
386  };
388 
389  // This mutex protects stateFlags, errorInfo, host,
390  // hasQuery, hasFragment, isValid, isHostValid,
391  // encodedNormalized and all other encoded* variables above.
392  // This also protects all other variables when set by parse,
393  // but not when set by setters.
394  mutable QMutex mutex;
395 
397  const QByteArray & normalized() const;
398 
400  QString createErrorString();
401 };
402 
403 
404 static bool QT_FASTCALL _HEXDIG(const char **ptr)
405 {
406  char ch = **ptr;
407  if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
408  ++(*ptr);
409  return true;
410  }
411 
412  return false;
413 }
414 
415 // pct-encoded = "%" HEXDIG HEXDIG
416 static bool QT_FASTCALL _pctEncoded(const char **ptr)
417 {
418  const char *ptrBackup = *ptr;
419 
420  if (**ptr != '%')
421  return false;
422  ++(*ptr);
423 
424  if (!_HEXDIG(ptr)) {
425  *ptr = ptrBackup;
426  return false;
427  }
428  if (!_HEXDIG(ptr)) {
429  *ptr = ptrBackup;
430  return false;
431  }
432 
433  return true;
434 }
435 
436 #if 0
437 // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
438 static bool QT_FASTCALL _genDelims(const char **ptr, char *c)
439 {
440  char ch = **ptr;
441  switch (ch) {
442  case ':': case '/': case '?': case '#':
443  case '[': case ']': case '@':
444  *c = ch;
445  ++(*ptr);
446  return true;
447  default:
448  return false;
449  }
450 }
451 #endif
452 
453 // sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
454 // / "*" / "+" / "," / ";" / "="
455 static bool QT_FASTCALL _subDelims(const char **ptr)
456 {
457  char ch = **ptr;
458  switch (ch) {
459  case '!': case '$': case '&': case '\'':
460  case '(': case ')': case '*': case '+':
461  case ',': case ';': case '=':
462  ++(*ptr);
463  return true;
464  default:
465  return false;
466  }
467 }
468 
469 // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
470 static bool QT_FASTCALL _unreserved(const char **ptr)
471 {
472  char ch = **ptr;
473  if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
474  || (ch >= '0' && ch <= '9')
475  || ch == '-' || ch == '.' || ch == '_' || ch == '~') {
476  ++(*ptr);
477  return true;
478  }
479  return false;
480 }
481 
482 // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
483 static bool QT_FASTCALL _scheme(const char **ptr, QUrlParseData *parseData)
484 {
485  bool first = true;
486  bool isSchemeValid = true;
487 
488  parseData->scheme = *ptr;
489  for (;;) {
490  char ch = **ptr;
491  if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
492  ;
493  } else if ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.') {
494  if (first)
495  isSchemeValid = false;
496  } else {
497  break;
498  }
499 
500  ++(*ptr);
501  first = false;
502  }
503 
504  if (**ptr != ':') {
505  isSchemeValid = true;
506  *ptr = parseData->scheme;
507  } else {
508  parseData->schemeLength = *ptr - parseData->scheme;
509  ++(*ptr); // skip ':'
510  }
511 
512  return isSchemeValid;
513 }
514 
515 // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
516 static bool QT_FASTCALL _IPvFuture(const char **ptr)
517 {
518  if (**ptr != 'v')
519  return false;
520 
521  const char *ptrBackup = *ptr;
522  ++(*ptr);
523 
524  if (!_HEXDIG(ptr)) {
525  *ptr = ptrBackup;
526  return false;
527  }
528 
529  while (_HEXDIG(ptr))
530  ;
531 
532  if (**ptr != '.') {
533  *ptr = ptrBackup;
534  return false;
535  }
536  ++(*ptr);
537 
538  if (!_unreserved(ptr) && !_subDelims(ptr) && *((*ptr)++) != ':') {
539  *ptr = ptrBackup;
540  return false;
541  }
542 
543 
544  while (_unreserved(ptr) || _subDelims(ptr) || *((*ptr)++) == ':')
545  ;
546 
547  return true;
548 }
549 
550 // h16 = 1*4HEXDIG
551 // ; 16 bits of address represented in hexadecimal
552 static bool QT_FASTCALL _h16(const char **ptr)
553 {
554  int i = 0;
555  for (; i < 4; ++i) {
556  if (!_HEXDIG(ptr))
557  break;
558  }
559  return (i != 0);
560 }
561 
562 // dec-octet = DIGIT ; 0-9
563 // / %x31-39 DIGIT ; 10-99
564 // / "1" 2DIGIT ; 100-199
565 // / "2" %x30-34 DIGIT ; 200-249
566 // / "25" %x30-35 ; 250-255
567 static bool QT_FASTCALL _decOctet(const char **ptr)
568 {
569  const char *ptrBackup = *ptr;
570  char c1 = **ptr;
571 
572  if (c1 < '0' || c1 > '9')
573  return false;
574 
575  ++(*ptr);
576 
577  if (c1 == '0')
578  return true;
579 
580  char c2 = **ptr;
581 
582  if (c2 < '0' || c2 > '9')
583  return true;
584 
585  ++(*ptr);
586 
587  char c3 = **ptr;
588  if (c3 < '0' || c3 > '9')
589  return true;
590 
591  // If there is a three digit number larger than 255, reject the
592  // whole token.
593  if (c1 >= '2' && c2 >= '5' && c3 > '5') {
594  *ptr = ptrBackup;
595  return false;
596  }
597 
598  ++(*ptr);
599 
600  return true;
601 }
602 
603 // IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
604 static bool QT_FASTCALL _IPv4Address(const char **ptr)
605 {
606  const char *ptrBackup = *ptr;
607 
608  if (!_decOctet(ptr)) {
609  *ptr = ptrBackup;
610  return false;
611  }
612 
613  for (int i = 0; i < 3; ++i) {
614  char ch = *((*ptr)++);
615  if (ch != '.') {
616  *ptr = ptrBackup;
617  return false;
618  }
619 
620  if (!_decOctet(ptr)) {
621  *ptr = ptrBackup;
622  return false;
623  }
624  }
625 
626  return true;
627 }
628 
629 // ls32 = ( h16 ":" h16 ) / IPv4address
630 // ; least-significant 32 bits of address
631 static bool QT_FASTCALL _ls32(const char **ptr)
632 {
633  const char *ptrBackup = *ptr;
634  if (_h16(ptr) && *((*ptr)++) == ':' && _h16(ptr))
635  return true;
636 
637  *ptr = ptrBackup;
638  return _IPv4Address(ptr);
639 }
640 
641 // IPv6address = 6( h16 ":" ) ls32 // case 1
642 // / "::" 5( h16 ":" ) ls32 // case 2
643 // / [ h16 ] "::" 4( h16 ":" ) ls32 // case 3
644 // / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 // case 4
645 // / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 // case 5
646 // / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 // case 6
647 // / [ *4( h16 ":" ) h16 ] "::" ls32 // case 7
648 // / [ *5( h16 ":" ) h16 ] "::" h16 // case 8
649 // / [ *6( h16 ":" ) h16 ] "::" // case 9
650 static bool QT_FASTCALL _IPv6Address(const char **ptr)
651 {
652  const char *ptrBackup = *ptr;
653 
654  // count of (h16 ":") to the left of and including ::
655  int leftHexColons = 0;
656  // count of (h16 ":") to the right of ::
657  int rightHexColons = 0;
658 
659  // first count the number of (h16 ":") on the left of ::
660  while (_h16(ptr)) {
661 
662  // an h16 not followed by a colon is considered an
663  // error.
664  if (**ptr != ':') {
665  *ptr = ptrBackup;
666  return false;
667  }
668  ++(*ptr);
669  ++leftHexColons;
670 
671  // check for case 1, the only time when there can be no ::
672  if (leftHexColons == 6 && _ls32(ptr)) {
673  return true;
674  }
675  }
676 
677  // check for case 2 where the address starts with a :
678  if (leftHexColons == 0 && *((*ptr)++) != ':') {
679  *ptr = ptrBackup;
680  return false;
681  }
682 
683  // check for the second colon in ::
684  if (*((*ptr)++) != ':') {
685  *ptr = ptrBackup;
686  return false;
687  }
688 
689  int canBeCase = -1;
690  bool ls32WasRead = false;
691 
692  const char *tmpBackup = *ptr;
693 
694  // count the number of (h16 ":") on the right of ::
695  for (;;) {
696  tmpBackup = *ptr;
697  if (!_h16(ptr)) {
698  if (!_ls32(ptr)) {
699  if (rightHexColons != 0) {
700  *ptr = ptrBackup;
701  return false;
702  }
703 
704  // the address ended with :: (case 9)
705  // only valid if 1 <= leftHexColons <= 7
706  canBeCase = 9;
707  } else {
708  ls32WasRead = true;
709  }
710  break;
711  }
712  ++rightHexColons;
713  if (**ptr != ':') {
714  // no colon could mean that what was read as an h16
715  // was in fact the first part of an ls32. we backtrack
716  // and retry.
717  const char *pb = *ptr;
718  *ptr = tmpBackup;
719  if (_ls32(ptr)) {
720  ls32WasRead = true;
721  --rightHexColons;
722  } else {
723  *ptr = pb;
724  // address ends with only 1 h16 after :: (case 8)
725  if (rightHexColons == 1)
726  canBeCase = 8;
727  }
728  break;
729  }
730  ++(*ptr);
731  }
732 
733  // determine which case it is based on the number of rightHexColons
734  if (canBeCase == -1) {
735 
736  // check if a ls32 was read. If it wasn't and rightHexColons >= 2 then the
737  // last 2 HexColons are in fact a ls32
738  if (!ls32WasRead && rightHexColons >= 2)
739  rightHexColons -= 2;
740 
741  canBeCase = 7 - rightHexColons;
742  }
743 
744  // based on the case we need to check that the number of leftHexColons is valid
745  if (leftHexColons > (canBeCase - 2)) {
746  *ptr = ptrBackup;
747  return false;
748  }
749 
750  return true;
751 }
752 
753 // IP-literal = "[" ( IPv6address / IPvFuture ) "]"
754 static bool QT_FASTCALL _IPLiteral(const char **ptr)
755 {
756  const char *ptrBackup = *ptr;
757  if (**ptr != '[')
758  return false;
759  ++(*ptr);
760 
761  if (!_IPv6Address(ptr) && !_IPvFuture(ptr)) {
762  *ptr = ptrBackup;
763  return false;
764  }
765 
766  if (**ptr != ']') {
767  *ptr = ptrBackup;
768  return false;
769  }
770  ++(*ptr);
771 
772  return true;
773 }
774 
775 // reg-name = *( unreserved / pct-encoded / sub-delims )
776 static void QT_FASTCALL _regName(const char **ptr)
777 {
778  for (;;) {
779  if (!_unreserved(ptr) && !_subDelims(ptr)) {
780  if (!_pctEncoded(ptr))
781  break;
782  }
783  }
784 }
785 
786 // host = IP-literal / IPv4address / reg-name
787 static void QT_FASTCALL _host(const char **ptr, QUrlParseData *parseData)
788 {
789  parseData->host = *ptr;
790  if (!_IPLiteral(ptr)) {
791  if (_IPv4Address(ptr)) {
792  char ch = **ptr;
793  if (ch && ch != ':' && ch != '/') {
794  // reset
795  *ptr = parseData->host;
796  _regName(ptr);
797  }
798  } else {
799  _regName(ptr);
800  }
801  }
802  parseData->hostLength = *ptr - parseData->host;
803 }
804 
805 // userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
806 static void QT_FASTCALL _userInfo(const char **ptr, QUrlParseData *parseData)
807 {
808  parseData->userInfo = *ptr;
809  for (;;) {
810  if (_unreserved(ptr) || _subDelims(ptr)) {
811  ;
812  } else {
813  if (_pctEncoded(ptr)) {
814  ;
815  } else if (**ptr == ':') {
816  parseData->userInfoDelimIndex = *ptr - parseData->userInfo;
817  ++(*ptr);
818  } else {
819  break;
820  }
821  }
822  }
823  if (**ptr != '@') {
824  *ptr = parseData->userInfo;
825  parseData->userInfoDelimIndex = -1;
826  return;
827  }
828  parseData->userInfoLength = *ptr - parseData->userInfo;
829  ++(*ptr);
830 }
831 
832 // port = *DIGIT
833 static void QT_FASTCALL _port(const char **ptr, int *port)
834 {
835  bool first = true;
836 
837  for (;;) {
838  const char *ptrBackup = *ptr;
839  char ch = *((*ptr)++);
840  if (ch < '0' || ch > '9') {
841  *ptr = ptrBackup;
842  break;
843  }
844 
845  if (first) {
846  first = false;
847  *port = 0;
848  }
849 
850  *port *= 10;
851  *port += ch - '0';
852  }
853 }
854 
855 // authority = [ userinfo "@" ] host [ ":" port ]
856 static void QT_FASTCALL _authority(const char **ptr, QUrlParseData *parseData)
857 {
858  _userInfo(ptr, parseData);
859  _host(ptr, parseData);
860 
861  if (**ptr != ':')
862  return;
863 
864  ++(*ptr);
865  _port(ptr, &parseData->port);
866 }
867 
868 // pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
869 static bool QT_FASTCALL _pchar(const char **ptr)
870 {
871  char c = *(*ptr);
872 
873  switch (c) {
874  case '!': case '$': case '&': case '\'': case '(': case ')': case '*':
875  case '+': case ',': case ';': case '=': case ':': case '@':
876  case '-': case '.': case '_': case '~':
877  ++(*ptr);
878  return true;
879  default:
880  break;
881  };
882 
883  if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {
884  ++(*ptr);
885  return true;
886  }
887 
888  if (_pctEncoded(ptr))
889  return true;
890 
891  return false;
892 }
893 
894 // segment = *pchar
895 static bool QT_FASTCALL _segmentNZ(const char **ptr)
896 {
897  if (!_pchar(ptr))
898  return false;
899 
900  while(_pchar(ptr))
901  ;
902 
903  return true;
904 }
905 
906 // path-abempty = *( "/" segment )
907 static void QT_FASTCALL _pathAbEmpty(const char **ptr)
908 {
909  for (;;) {
910  if (**ptr != '/')
911  break;
912  ++(*ptr);
913 
914  while (_pchar(ptr))
915  ;
916  }
917 }
918 
919 // path-abs = "/" [ segment-nz *( "/" segment ) ]
920 static bool QT_FASTCALL _pathAbs(const char **ptr)
921 {
922  // **ptr == '/' already checked in caller
923  ++(*ptr);
924 
925  // we might be able to unnest this to gain some performance.
926  if (!_segmentNZ(ptr))
927  return true;
928 
929  _pathAbEmpty(ptr);
930 
931  return true;
932 }
933 
934 // path-rootless = segment-nz *( "/" segment )
935 static bool QT_FASTCALL _pathRootless(const char **ptr)
936 {
937  // we might be able to unnest this to gain some performance.
938  if (!_segmentNZ(ptr))
939  return false;
940 
941  _pathAbEmpty(ptr);
942 
943  return true;
944 }
945 
946 
947 // hier-part = "//" authority path-abempty
948 // / path-abs
949 // / path-rootless
950 // / path-empty
951 static void QT_FASTCALL _hierPart(const char **ptr, QUrlParseData *parseData)
952 {
953  const char *ptrBackup = *ptr;
954  const char *pathStart = 0;
955  if (*((*ptr)++) == '/' && *((*ptr)++) == '/') {
956  _authority(ptr, parseData);
957  pathStart = *ptr;
958  _pathAbEmpty(ptr);
959  } else {
960  *ptr = ptrBackup;
961  pathStart = *ptr;
962  if (**ptr == '/')
963  _pathAbs(ptr);
964  else
965  _pathRootless(ptr);
966  }
967  parseData->path = pathStart;
968  parseData->pathLength = *ptr - pathStart;
969 }
970 
971 // query = *( pchar / "/" / "?" )
972 static void QT_FASTCALL _query(const char **ptr, QUrlParseData *parseData)
973 {
974  parseData->query = *ptr;
975  for (;;) {
976  if (_pchar(ptr)) {
977  ;
978  } else if (**ptr == '/' || **ptr == '?') {
979  ++(*ptr);
980  } else {
981  break;
982  }
983  }
984  parseData->queryLength = *ptr - parseData->query;
985 }
986 
987 // fragment = *( pchar / "/" / "?" )
988 static void QT_FASTCALL _fragment(const char **ptr, QUrlParseData *parseData)
989 {
990  parseData->fragment = *ptr;
991  for (;;) {
992  if (_pchar(ptr)) {
993  ;
994  } else if (**ptr == '/' || **ptr == '?' || **ptr == '#') {
995  ++(*ptr);
996  } else {
997  break;
998  }
999  }
1000  parseData->fragmentLength = *ptr - parseData->fragment;
1001 }
1002 
1006 };
1007 
1008 inline bool operator<(uint one, const NameprepCaseFoldingEntry &other)
1009 { return one < other.uc; }
1010 
1011 inline bool operator<(const NameprepCaseFoldingEntry &one, uint other)
1012 { return one.uc < other; }
1013 
1015 /* { 0x0041, { 0x0061, 0x0000, 0x0000, 0x0000 } },
1016  { 0x0042, { 0x0062, 0x0000, 0x0000, 0x0000 } },
1017  { 0x0043, { 0x0063, 0x0000, 0x0000, 0x0000 } },
1018  { 0x0044, { 0x0064, 0x0000, 0x0000, 0x0000 } },
1019  { 0x0045, { 0x0065, 0x0000, 0x0000, 0x0000 } },
1020  { 0x0046, { 0x0066, 0x0000, 0x0000, 0x0000 } },
1021  { 0x0047, { 0x0067, 0x0000, 0x0000, 0x0000 } },
1022  { 0x0048, { 0x0068, 0x0000, 0x0000, 0x0000 } },
1023  { 0x0049, { 0x0069, 0x0000, 0x0000, 0x0000 } },
1024  { 0x004A, { 0x006A, 0x0000, 0x0000, 0x0000 } },
1025  { 0x004B, { 0x006B, 0x0000, 0x0000, 0x0000 } },
1026  { 0x004C, { 0x006C, 0x0000, 0x0000, 0x0000 } },
1027  { 0x004D, { 0x006D, 0x0000, 0x0000, 0x0000 } },
1028  { 0x004E, { 0x006E, 0x0000, 0x0000, 0x0000 } },
1029  { 0x004F, { 0x006F, 0x0000, 0x0000, 0x0000 } },
1030  { 0x0050, { 0x0070, 0x0000, 0x0000, 0x0000 } },
1031  { 0x0051, { 0x0071, 0x0000, 0x0000, 0x0000 } },
1032  { 0x0052, { 0x0072, 0x0000, 0x0000, 0x0000 } },
1033  { 0x0053, { 0x0073, 0x0000, 0x0000, 0x0000 } },
1034  { 0x0054, { 0x0074, 0x0000, 0x0000, 0x0000 } },
1035  { 0x0055, { 0x0075, 0x0000, 0x0000, 0x0000 } },
1036  { 0x0056, { 0x0076, 0x0000, 0x0000, 0x0000 } },
1037  { 0x0057, { 0x0077, 0x0000, 0x0000, 0x0000 } },
1038  { 0x0058, { 0x0078, 0x0000, 0x0000, 0x0000 } },
1039  { 0x0059, { 0x0079, 0x0000, 0x0000, 0x0000 } },
1040  { 0x005A, { 0x007A, 0x0000, 0x0000, 0x0000 } },*/
1041  { 0x00B5, { 0x03BC, 0x0000, 0x0000, 0x0000 } },
1042  { 0x00C0, { 0x00E0, 0x0000, 0x0000, 0x0000 } },
1043  { 0x00C1, { 0x00E1, 0x0000, 0x0000, 0x0000 } },
1044  { 0x00C2, { 0x00E2, 0x0000, 0x0000, 0x0000 } },
1045  { 0x00C3, { 0x00E3, 0x0000, 0x0000, 0x0000 } },
1046  { 0x00C4, { 0x00E4, 0x0000, 0x0000, 0x0000 } },
1047  { 0x00C5, { 0x00E5, 0x0000, 0x0000, 0x0000 } },
1048  { 0x00C6, { 0x00E6, 0x0000, 0x0000, 0x0000 } },
1049  { 0x00C7, { 0x00E7, 0x0000, 0x0000, 0x0000 } },
1050  { 0x00C8, { 0x00E8, 0x0000, 0x0000, 0x0000 } },
1051  { 0x00C9, { 0x00E9, 0x0000, 0x0000, 0x0000 } },
1052  { 0x00CA, { 0x00EA, 0x0000, 0x0000, 0x0000 } },
1053  { 0x00CB, { 0x00EB, 0x0000, 0x0000, 0x0000 } },
1054  { 0x00CC, { 0x00EC, 0x0000, 0x0000, 0x0000 } },
1055  { 0x00CD, { 0x00ED, 0x0000, 0x0000, 0x0000 } },
1056  { 0x00CE, { 0x00EE, 0x0000, 0x0000, 0x0000 } },
1057  { 0x00CF, { 0x00EF, 0x0000, 0x0000, 0x0000 } },
1058  { 0x00D0, { 0x00F0, 0x0000, 0x0000, 0x0000 } },
1059  { 0x00D1, { 0x00F1, 0x0000, 0x0000, 0x0000 } },
1060  { 0x00D2, { 0x00F2, 0x0000, 0x0000, 0x0000 } },
1061  { 0x00D3, { 0x00F3, 0x0000, 0x0000, 0x0000 } },
1062  { 0x00D4, { 0x00F4, 0x0000, 0x0000, 0x0000 } },
1063  { 0x00D5, { 0x00F5, 0x0000, 0x0000, 0x0000 } },
1064  { 0x00D6, { 0x00F6, 0x0000, 0x0000, 0x0000 } },
1065  { 0x00D8, { 0x00F8, 0x0000, 0x0000, 0x0000 } },
1066  { 0x00D9, { 0x00F9, 0x0000, 0x0000, 0x0000 } },
1067  { 0x00DA, { 0x00FA, 0x0000, 0x0000, 0x0000 } },
1068  { 0x00DB, { 0x00FB, 0x0000, 0x0000, 0x0000 } },
1069  { 0x00DC, { 0x00FC, 0x0000, 0x0000, 0x0000 } },
1070  { 0x00DD, { 0x00FD, 0x0000, 0x0000, 0x0000 } },
1071  { 0x00DE, { 0x00FE, 0x0000, 0x0000, 0x0000 } },
1072  { 0x00DF, { 0x0073, 0x0073, 0x0000, 0x0000 } },
1073  { 0x0100, { 0x0101, 0x0000, 0x0000, 0x0000 } },
1074  { 0x0102, { 0x0103, 0x0000, 0x0000, 0x0000 } },
1075  { 0x0104, { 0x0105, 0x0000, 0x0000, 0x0000 } },
1076  { 0x0106, { 0x0107, 0x0000, 0x0000, 0x0000 } },
1077  { 0x0108, { 0x0109, 0x0000, 0x0000, 0x0000 } },
1078  { 0x010A, { 0x010B, 0x0000, 0x0000, 0x0000 } },
1079  { 0x010C, { 0x010D, 0x0000, 0x0000, 0x0000 } },
1080  { 0x010E, { 0x010F, 0x0000, 0x0000, 0x0000 } },
1081  { 0x0110, { 0x0111, 0x0000, 0x0000, 0x0000 } },
1082  { 0x0112, { 0x0113, 0x0000, 0x0000, 0x0000 } },
1083  { 0x0114, { 0x0115, 0x0000, 0x0000, 0x0000 } },
1084  { 0x0116, { 0x0117, 0x0000, 0x0000, 0x0000 } },
1085  { 0x0118, { 0x0119, 0x0000, 0x0000, 0x0000 } },
1086  { 0x011A, { 0x011B, 0x0000, 0x0000, 0x0000 } },
1087  { 0x011C, { 0x011D, 0x0000, 0x0000, 0x0000 } },
1088  { 0x011E, { 0x011F, 0x0000, 0x0000, 0x0000 } },
1089  { 0x0120, { 0x0121, 0x0000, 0x0000, 0x0000 } },
1090  { 0x0122, { 0x0123, 0x0000, 0x0000, 0x0000 } },
1091  { 0x0124, { 0x0125, 0x0000, 0x0000, 0x0000 } },
1092  { 0x0126, { 0x0127, 0x0000, 0x0000, 0x0000 } },
1093  { 0x0128, { 0x0129, 0x0000, 0x0000, 0x0000 } },
1094  { 0x012A, { 0x012B, 0x0000, 0x0000, 0x0000 } },
1095  { 0x012C, { 0x012D, 0x0000, 0x0000, 0x0000 } },
1096  { 0x012E, { 0x012F, 0x0000, 0x0000, 0x0000 } },
1097  { 0x0130, { 0x0069, 0x0307, 0x0000, 0x0000 } },
1098  { 0x0132, { 0x0133, 0x0000, 0x0000, 0x0000 } },
1099  { 0x0134, { 0x0135, 0x0000, 0x0000, 0x0000 } },
1100  { 0x0136, { 0x0137, 0x0000, 0x0000, 0x0000 } },
1101  { 0x0139, { 0x013A, 0x0000, 0x0000, 0x0000 } },
1102  { 0x013B, { 0x013C, 0x0000, 0x0000, 0x0000 } },
1103  { 0x013D, { 0x013E, 0x0000, 0x0000, 0x0000 } },
1104  { 0x013F, { 0x0140, 0x0000, 0x0000, 0x0000 } },
1105  { 0x0141, { 0x0142, 0x0000, 0x0000, 0x0000 } },
1106  { 0x0143, { 0x0144, 0x0000, 0x0000, 0x0000 } },
1107  { 0x0145, { 0x0146, 0x0000, 0x0000, 0x0000 } },
1108  { 0x0147, { 0x0148, 0x0000, 0x0000, 0x0000 } },
1109  { 0x0149, { 0x02BC, 0x006E, 0x0000, 0x0000 } },
1110  { 0x014A, { 0x014B, 0x0000, 0x0000, 0x0000 } },
1111  { 0x014C, { 0x014D, 0x0000, 0x0000, 0x0000 } },
1112  { 0x014E, { 0x014F, 0x0000, 0x0000, 0x0000 } },
1113  { 0x0150, { 0x0151, 0x0000, 0x0000, 0x0000 } },
1114  { 0x0152, { 0x0153, 0x0000, 0x0000, 0x0000 } },
1115  { 0x0154, { 0x0155, 0x0000, 0x0000, 0x0000 } },
1116  { 0x0156, { 0x0157, 0x0000, 0x0000, 0x0000 } },
1117  { 0x0158, { 0x0159, 0x0000, 0x0000, 0x0000 } },
1118  { 0x015A, { 0x015B, 0x0000, 0x0000, 0x0000 } },
1119  { 0x015C, { 0x015D, 0x0000, 0x0000, 0x0000 } },
1120  { 0x015E, { 0x015F, 0x0000, 0x0000, 0x0000 } },
1121  { 0x0160, { 0x0161, 0x0000, 0x0000, 0x0000 } },
1122  { 0x0162, { 0x0163, 0x0000, 0x0000, 0x0000 } },
1123  { 0x0164, { 0x0165, 0x0000, 0x0000, 0x0000 } },
1124  { 0x0166, { 0x0167, 0x0000, 0x0000, 0x0000 } },
1125  { 0x0168, { 0x0169, 0x0000, 0x0000, 0x0000 } },
1126  { 0x016A, { 0x016B, 0x0000, 0x0000, 0x0000 } },
1127  { 0x016C, { 0x016D, 0x0000, 0x0000, 0x0000 } },
1128  { 0x016E, { 0x016F, 0x0000, 0x0000, 0x0000 } },
1129  { 0x0170, { 0x0171, 0x0000, 0x0000, 0x0000 } },
1130  { 0x0172, { 0x0173, 0x0000, 0x0000, 0x0000 } },
1131  { 0x0174, { 0x0175, 0x0000, 0x0000, 0x0000 } },
1132  { 0x0176, { 0x0177, 0x0000, 0x0000, 0x0000 } },
1133  { 0x0178, { 0x00FF, 0x0000, 0x0000, 0x0000 } },
1134  { 0x0179, { 0x017A, 0x0000, 0x0000, 0x0000 } },
1135  { 0x017B, { 0x017C, 0x0000, 0x0000, 0x0000 } },
1136  { 0x017D, { 0x017E, 0x0000, 0x0000, 0x0000 } },
1137  { 0x017F, { 0x0073, 0x0000, 0x0000, 0x0000 } },
1138  { 0x0181, { 0x0253, 0x0000, 0x0000, 0x0000 } },
1139  { 0x0182, { 0x0183, 0x0000, 0x0000, 0x0000 } },
1140  { 0x0184, { 0x0185, 0x0000, 0x0000, 0x0000 } },
1141  { 0x0186, { 0x0254, 0x0000, 0x0000, 0x0000 } },
1142  { 0x0187, { 0x0188, 0x0000, 0x0000, 0x0000 } },
1143  { 0x0189, { 0x0256, 0x0000, 0x0000, 0x0000 } },
1144  { 0x018A, { 0x0257, 0x0000, 0x0000, 0x0000 } },
1145  { 0x018B, { 0x018C, 0x0000, 0x0000, 0x0000 } },
1146  { 0x018E, { 0x01DD, 0x0000, 0x0000, 0x0000 } },
1147  { 0x018F, { 0x0259, 0x0000, 0x0000, 0x0000 } },
1148  { 0x0190, { 0x025B, 0x0000, 0x0000, 0x0000 } },
1149  { 0x0191, { 0x0192, 0x0000, 0x0000, 0x0000 } },
1150  { 0x0193, { 0x0260, 0x0000, 0x0000, 0x0000 } },
1151  { 0x0194, { 0x0263, 0x0000, 0x0000, 0x0000 } },
1152  { 0x0196, { 0x0269, 0x0000, 0x0000, 0x0000 } },
1153  { 0x0197, { 0x0268, 0x0000, 0x0000, 0x0000 } },
1154  { 0x0198, { 0x0199, 0x0000, 0x0000, 0x0000 } },
1155  { 0x019C, { 0x026F, 0x0000, 0x0000, 0x0000 } },
1156  { 0x019D, { 0x0272, 0x0000, 0x0000, 0x0000 } },
1157  { 0x019F, { 0x0275, 0x0000, 0x0000, 0x0000 } },
1158  { 0x01A0, { 0x01A1, 0x0000, 0x0000, 0x0000 } },
1159  { 0x01A2, { 0x01A3, 0x0000, 0x0000, 0x0000 } },
1160  { 0x01A4, { 0x01A5, 0x0000, 0x0000, 0x0000 } },
1161  { 0x01A6, { 0x0280, 0x0000, 0x0000, 0x0000 } },
1162  { 0x01A7, { 0x01A8, 0x0000, 0x0000, 0x0000 } },
1163  { 0x01A9, { 0x0283, 0x0000, 0x0000, 0x0000 } },
1164  { 0x01AC, { 0x01AD, 0x0000, 0x0000, 0x0000 } },
1165  { 0x01AE, { 0x0288, 0x0000, 0x0000, 0x0000 } },
1166  { 0x01AF, { 0x01B0, 0x0000, 0x0000, 0x0000 } },
1167  { 0x01B1, { 0x028A, 0x0000, 0x0000, 0x0000 } },
1168  { 0x01B2, { 0x028B, 0x0000, 0x0000, 0x0000 } },
1169  { 0x01B3, { 0x01B4, 0x0000, 0x0000, 0x0000 } },
1170  { 0x01B5, { 0x01B6, 0x0000, 0x0000, 0x0000 } },
1171  { 0x01B7, { 0x0292, 0x0000, 0x0000, 0x0000 } },
1172  { 0x01B8, { 0x01B9, 0x0000, 0x0000, 0x0000 } },
1173  { 0x01BC, { 0x01BD, 0x0000, 0x0000, 0x0000 } },
1174  { 0x01C4, { 0x01C6, 0x0000, 0x0000, 0x0000 } },
1175  { 0x01C5, { 0x01C6, 0x0000, 0x0000, 0x0000 } },
1176  { 0x01C7, { 0x01C9, 0x0000, 0x0000, 0x0000 } },
1177  { 0x01C8, { 0x01C9, 0x0000, 0x0000, 0x0000 } },
1178  { 0x01CA, { 0x01CC, 0x0000, 0x0000, 0x0000 } },
1179  { 0x01CB, { 0x01CC, 0x0000, 0x0000, 0x0000 } },
1180  { 0x01CD, { 0x01CE, 0x0000, 0x0000, 0x0000 } },
1181  { 0x01CF, { 0x01D0, 0x0000, 0x0000, 0x0000 } },
1182  { 0x01D1, { 0x01D2, 0x0000, 0x0000, 0x0000 } },
1183  { 0x01D3, { 0x01D4, 0x0000, 0x0000, 0x0000 } },
1184  { 0x01D5, { 0x01D6, 0x0000, 0x0000, 0x0000 } },
1185  { 0x01D7, { 0x01D8, 0x0000, 0x0000, 0x0000 } },
1186  { 0x01D9, { 0x01DA, 0x0000, 0x0000, 0x0000 } },
1187  { 0x01DB, { 0x01DC, 0x0000, 0x0000, 0x0000 } },
1188  { 0x01DE, { 0x01DF, 0x0000, 0x0000, 0x0000 } },
1189  { 0x01E0, { 0x01E1, 0x0000, 0x0000, 0x0000 } },
1190  { 0x01E2, { 0x01E3, 0x0000, 0x0000, 0x0000 } },
1191  { 0x01E4, { 0x01E5, 0x0000, 0x0000, 0x0000 } },
1192  { 0x01E6, { 0x01E7, 0x0000, 0x0000, 0x0000 } },
1193  { 0x01E8, { 0x01E9, 0x0000, 0x0000, 0x0000 } },
1194  { 0x01EA, { 0x01EB, 0x0000, 0x0000, 0x0000 } },
1195  { 0x01EC, { 0x01ED, 0x0000, 0x0000, 0x0000 } },
1196  { 0x01EE, { 0x01EF, 0x0000, 0x0000, 0x0000 } },
1197  { 0x01F0, { 0x006A, 0x030C, 0x0000, 0x0000 } },
1198  { 0x01F1, { 0x01F3, 0x0000, 0x0000, 0x0000 } },
1199  { 0x01F2, { 0x01F3, 0x0000, 0x0000, 0x0000 } },
1200  { 0x01F4, { 0x01F5, 0x0000, 0x0000, 0x0000 } },
1201  { 0x01F6, { 0x0195, 0x0000, 0x0000, 0x0000 } },
1202  { 0x01F7, { 0x01BF, 0x0000, 0x0000, 0x0000 } },
1203  { 0x01F8, { 0x01F9, 0x0000, 0x0000, 0x0000 } },
1204  { 0x01FA, { 0x01FB, 0x0000, 0x0000, 0x0000 } },
1205  { 0x01FC, { 0x01FD, 0x0000, 0x0000, 0x0000 } },
1206  { 0x01FE, { 0x01FF, 0x0000, 0x0000, 0x0000 } },
1207  { 0x0200, { 0x0201, 0x0000, 0x0000, 0x0000 } },
1208  { 0x0202, { 0x0203, 0x0000, 0x0000, 0x0000 } },
1209  { 0x0204, { 0x0205, 0x0000, 0x0000, 0x0000 } },
1210  { 0x0206, { 0x0207, 0x0000, 0x0000, 0x0000 } },
1211  { 0x0208, { 0x0209, 0x0000, 0x0000, 0x0000 } },
1212  { 0x020A, { 0x020B, 0x0000, 0x0000, 0x0000 } },
1213  { 0x020C, { 0x020D, 0x0000, 0x0000, 0x0000 } },
1214  { 0x020E, { 0x020F, 0x0000, 0x0000, 0x0000 } },
1215  { 0x0210, { 0x0211, 0x0000, 0x0000, 0x0000 } },
1216  { 0x0212, { 0x0213, 0x0000, 0x0000, 0x0000 } },
1217  { 0x0214, { 0x0215, 0x0000, 0x0000, 0x0000 } },
1218  { 0x0216, { 0x0217, 0x0000, 0x0000, 0x0000 } },
1219  { 0x0218, { 0x0219, 0x0000, 0x0000, 0x0000 } },
1220  { 0x021A, { 0x021B, 0x0000, 0x0000, 0x0000 } },
1221  { 0x021C, { 0x021D, 0x0000, 0x0000, 0x0000 } },
1222  { 0x021E, { 0x021F, 0x0000, 0x0000, 0x0000 } },
1223  { 0x0220, { 0x019E, 0x0000, 0x0000, 0x0000 } },
1224  { 0x0222, { 0x0223, 0x0000, 0x0000, 0x0000 } },
1225  { 0x0224, { 0x0225, 0x0000, 0x0000, 0x0000 } },
1226  { 0x0226, { 0x0227, 0x0000, 0x0000, 0x0000 } },
1227  { 0x0228, { 0x0229, 0x0000, 0x0000, 0x0000 } },
1228  { 0x022A, { 0x022B, 0x0000, 0x0000, 0x0000 } },
1229  { 0x022C, { 0x022D, 0x0000, 0x0000, 0x0000 } },
1230  { 0x022E, { 0x022F, 0x0000, 0x0000, 0x0000 } },
1231  { 0x0230, { 0x0231, 0x0000, 0x0000, 0x0000 } },
1232  { 0x0232, { 0x0233, 0x0000, 0x0000, 0x0000 } },
1233  { 0x0345, { 0x03B9, 0x0000, 0x0000, 0x0000 } },
1234  { 0x037A, { 0x0020, 0x03B9, 0x0000, 0x0000 } },
1235  { 0x0386, { 0x03AC, 0x0000, 0x0000, 0x0000 } },
1236  { 0x0388, { 0x03AD, 0x0000, 0x0000, 0x0000 } },
1237  { 0x0389, { 0x03AE, 0x0000, 0x0000, 0x0000 } },
1238  { 0x038A, { 0x03AF, 0x0000, 0x0000, 0x0000 } },
1239  { 0x038C, { 0x03CC, 0x0000, 0x0000, 0x0000 } },
1240  { 0x038E, { 0x03CD, 0x0000, 0x0000, 0x0000 } },
1241  { 0x038F, { 0x03CE, 0x0000, 0x0000, 0x0000 } },
1242  { 0x0390, { 0x03B9, 0x0308, 0x0301, 0x0000 } },
1243  { 0x0391, { 0x03B1, 0x0000, 0x0000, 0x0000 } },
1244  { 0x0392, { 0x03B2, 0x0000, 0x0000, 0x0000 } },
1245  { 0x0393, { 0x03B3, 0x0000, 0x0000, 0x0000 } },
1246  { 0x0394, { 0x03B4, 0x0000, 0x0000, 0x0000 } },
1247  { 0x0395, { 0x03B5, 0x0000, 0x0000, 0x0000 } },
1248  { 0x0396, { 0x03B6, 0x0000, 0x0000, 0x0000 } },
1249  { 0x0397, { 0x03B7, 0x0000, 0x0000, 0x0000 } },
1250  { 0x0398, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
1251  { 0x0399, { 0x03B9, 0x0000, 0x0000, 0x0000 } },
1252  { 0x039A, { 0x03BA, 0x0000, 0x0000, 0x0000 } },
1253  { 0x039B, { 0x03BB, 0x0000, 0x0000, 0x0000 } },
1254  { 0x039C, { 0x03BC, 0x0000, 0x0000, 0x0000 } },
1255  { 0x039D, { 0x03BD, 0x0000, 0x0000, 0x0000 } },
1256  { 0x039E, { 0x03BE, 0x0000, 0x0000, 0x0000 } },
1257  { 0x039F, { 0x03BF, 0x0000, 0x0000, 0x0000 } },
1258  { 0x03A0, { 0x03C0, 0x0000, 0x0000, 0x0000 } },
1259  { 0x03A1, { 0x03C1, 0x0000, 0x0000, 0x0000 } },
1260  { 0x03A3, { 0x03C3, 0x0000, 0x0000, 0x0000 } },
1261  { 0x03A4, { 0x03C4, 0x0000, 0x0000, 0x0000 } },
1262  { 0x03A5, { 0x03C5, 0x0000, 0x0000, 0x0000 } },
1263  { 0x03A6, { 0x03C6, 0x0000, 0x0000, 0x0000 } },
1264  { 0x03A7, { 0x03C7, 0x0000, 0x0000, 0x0000 } },
1265  { 0x03A8, { 0x03C8, 0x0000, 0x0000, 0x0000 } },
1266  { 0x03A9, { 0x03C9, 0x0000, 0x0000, 0x0000 } },
1267  { 0x03AA, { 0x03CA, 0x0000, 0x0000, 0x0000 } },
1268  { 0x03AB, { 0x03CB, 0x0000, 0x0000, 0x0000 } },
1269  { 0x03B0, { 0x03C5, 0x0308, 0x0301, 0x0000 } },
1270  { 0x03C2, { 0x03C3, 0x0000, 0x0000, 0x0000 } },
1271  { 0x03D0, { 0x03B2, 0x0000, 0x0000, 0x0000 } },
1272  { 0x03D1, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
1273  { 0x03D2, { 0x03C5, 0x0000, 0x0000, 0x0000 } },
1274  { 0x03D3, { 0x03CD, 0x0000, 0x0000, 0x0000 } },
1275  { 0x03D4, { 0x03CB, 0x0000, 0x0000, 0x0000 } },
1276  { 0x03D5, { 0x03C6, 0x0000, 0x0000, 0x0000 } },
1277  { 0x03D6, { 0x03C0, 0x0000, 0x0000, 0x0000 } },
1278  { 0x03D8, { 0x03D9, 0x0000, 0x0000, 0x0000 } },
1279  { 0x03DA, { 0x03DB, 0x0000, 0x0000, 0x0000 } },
1280  { 0x03DC, { 0x03DD, 0x0000, 0x0000, 0x0000 } },
1281  { 0x03DE, { 0x03DF, 0x0000, 0x0000, 0x0000 } },
1282  { 0x03E0, { 0x03E1, 0x0000, 0x0000, 0x0000 } },
1283  { 0x03E2, { 0x03E3, 0x0000, 0x0000, 0x0000 } },
1284  { 0x03E4, { 0x03E5, 0x0000, 0x0000, 0x0000 } },
1285  { 0x03E6, { 0x03E7, 0x0000, 0x0000, 0x0000 } },
1286  { 0x03E8, { 0x03E9, 0x0000, 0x0000, 0x0000 } },
1287  { 0x03EA, { 0x03EB, 0x0000, 0x0000, 0x0000 } },
1288  { 0x03EC, { 0x03ED, 0x0000, 0x0000, 0x0000 } },
1289  { 0x03EE, { 0x03EF, 0x0000, 0x0000, 0x0000 } },
1290  { 0x03F0, { 0x03BA, 0x0000, 0x0000, 0x0000 } },
1291  { 0x03F1, { 0x03C1, 0x0000, 0x0000, 0x0000 } },
1292  { 0x03F2, { 0x03C3, 0x0000, 0x0000, 0x0000 } },
1293  { 0x03F4, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
1294  { 0x03F5, { 0x03B5, 0x0000, 0x0000, 0x0000 } },
1295  { 0x0400, { 0x0450, 0x0000, 0x0000, 0x0000 } },
1296  { 0x0401, { 0x0451, 0x0000, 0x0000, 0x0000 } },
1297  { 0x0402, { 0x0452, 0x0000, 0x0000, 0x0000 } },
1298  { 0x0403, { 0x0453, 0x0000, 0x0000, 0x0000 } },
1299  { 0x0404, { 0x0454, 0x0000, 0x0000, 0x0000 } },
1300  { 0x0405, { 0x0455, 0x0000, 0x0000, 0x0000 } },
1301  { 0x0406, { 0x0456, 0x0000, 0x0000, 0x0000 } },
1302  { 0x0407, { 0x0457, 0x0000, 0x0000, 0x0000 } },
1303  { 0x0408, { 0x0458, 0x0000, 0x0000, 0x0000 } },
1304  { 0x0409, { 0x0459, 0x0000, 0x0000, 0x0000 } },
1305  { 0x040A, { 0x045A, 0x0000, 0x0000, 0x0000 } },
1306  { 0x040B, { 0x045B, 0x0000, 0x0000, 0x0000 } },
1307  { 0x040C, { 0x045C, 0x0000, 0x0000, 0x0000 } },
1308  { 0x040D, { 0x045D, 0x0000, 0x0000, 0x0000 } },
1309  { 0x040E, { 0x045E, 0x0000, 0x0000, 0x0000 } },
1310  { 0x040F, { 0x045F, 0x0000, 0x0000, 0x0000 } },
1311  { 0x0410, { 0x0430, 0x0000, 0x0000, 0x0000 } },
1312  { 0x0411, { 0x0431, 0x0000, 0x0000, 0x0000 } },
1313  { 0x0412, { 0x0432, 0x0000, 0x0000, 0x0000 } },
1314  { 0x0413, { 0x0433, 0x0000, 0x0000, 0x0000 } },
1315  { 0x0414, { 0x0434, 0x0000, 0x0000, 0x0000 } },
1316  { 0x0415, { 0x0435, 0x0000, 0x0000, 0x0000 } },
1317  { 0x0416, { 0x0436, 0x0000, 0x0000, 0x0000 } },
1318  { 0x0417, { 0x0437, 0x0000, 0x0000, 0x0000 } },
1319  { 0x0418, { 0x0438, 0x0000, 0x0000, 0x0000 } },
1320  { 0x0419, { 0x0439, 0x0000, 0x0000, 0x0000 } },
1321  { 0x041A, { 0x043A, 0x0000, 0x0000, 0x0000 } },
1322  { 0x041B, { 0x043B, 0x0000, 0x0000, 0x0000 } },
1323  { 0x041C, { 0x043C, 0x0000, 0x0000, 0x0000 } },
1324  { 0x041D, { 0x043D, 0x0000, 0x0000, 0x0000 } },
1325  { 0x041E, { 0x043E, 0x0000, 0x0000, 0x0000 } },
1326  { 0x041F, { 0x043F, 0x0000, 0x0000, 0x0000 } },
1327  { 0x0420, { 0x0440, 0x0000, 0x0000, 0x0000 } },
1328  { 0x0421, { 0x0441, 0x0000, 0x0000, 0x0000 } },
1329  { 0x0422, { 0x0442, 0x0000, 0x0000, 0x0000 } },
1330  { 0x0423, { 0x0443, 0x0000, 0x0000, 0x0000 } },
1331  { 0x0424, { 0x0444, 0x0000, 0x0000, 0x0000 } },
1332  { 0x0425, { 0x0445, 0x0000, 0x0000, 0x0000 } },
1333  { 0x0426, { 0x0446, 0x0000, 0x0000, 0x0000 } },
1334  { 0x0427, { 0x0447, 0x0000, 0x0000, 0x0000 } },
1335  { 0x0428, { 0x0448, 0x0000, 0x0000, 0x0000 } },
1336  { 0x0429, { 0x0449, 0x0000, 0x0000, 0x0000 } },
1337  { 0x042A, { 0x044A, 0x0000, 0x0000, 0x0000 } },
1338  { 0x042B, { 0x044B, 0x0000, 0x0000, 0x0000 } },
1339  { 0x042C, { 0x044C, 0x0000, 0x0000, 0x0000 } },
1340  { 0x042D, { 0x044D, 0x0000, 0x0000, 0x0000 } },
1341  { 0x042E, { 0x044E, 0x0000, 0x0000, 0x0000 } },
1342  { 0x042F, { 0x044F, 0x0000, 0x0000, 0x0000 } },
1343  { 0x0460, { 0x0461, 0x0000, 0x0000, 0x0000 } },
1344  { 0x0462, { 0x0463, 0x0000, 0x0000, 0x0000 } },
1345  { 0x0464, { 0x0465, 0x0000, 0x0000, 0x0000 } },
1346  { 0x0466, { 0x0467, 0x0000, 0x0000, 0x0000 } },
1347  { 0x0468, { 0x0469, 0x0000, 0x0000, 0x0000 } },
1348  { 0x046A, { 0x046B, 0x0000, 0x0000, 0x0000 } },
1349  { 0x046C, { 0x046D, 0x0000, 0x0000, 0x0000 } },
1350  { 0x046E, { 0x046F, 0x0000, 0x0000, 0x0000 } },
1351  { 0x0470, { 0x0471, 0x0000, 0x0000, 0x0000 } },
1352  { 0x0472, { 0x0473, 0x0000, 0x0000, 0x0000 } },
1353  { 0x0474, { 0x0475, 0x0000, 0x0000, 0x0000 } },
1354  { 0x0476, { 0x0477, 0x0000, 0x0000, 0x0000 } },
1355  { 0x0478, { 0x0479, 0x0000, 0x0000, 0x0000 } },
1356  { 0x047A, { 0x047B, 0x0000, 0x0000, 0x0000 } },
1357  { 0x047C, { 0x047D, 0x0000, 0x0000, 0x0000 } },
1358  { 0x047E, { 0x047F, 0x0000, 0x0000, 0x0000 } },
1359  { 0x0480, { 0x0481, 0x0000, 0x0000, 0x0000 } },
1360  { 0x048A, { 0x048B, 0x0000, 0x0000, 0x0000 } },
1361  { 0x048C, { 0x048D, 0x0000, 0x0000, 0x0000 } },
1362  { 0x048E, { 0x048F, 0x0000, 0x0000, 0x0000 } },
1363  { 0x0490, { 0x0491, 0x0000, 0x0000, 0x0000 } },
1364  { 0x0492, { 0x0493, 0x0000, 0x0000, 0x0000 } },
1365  { 0x0494, { 0x0495, 0x0000, 0x0000, 0x0000 } },
1366  { 0x0496, { 0x0497, 0x0000, 0x0000, 0x0000 } },
1367  { 0x0498, { 0x0499, 0x0000, 0x0000, 0x0000 } },
1368  { 0x049A, { 0x049B, 0x0000, 0x0000, 0x0000 } },
1369  { 0x049C, { 0x049D, 0x0000, 0x0000, 0x0000 } },
1370  { 0x049E, { 0x049F, 0x0000, 0x0000, 0x0000 } },
1371  { 0x04A0, { 0x04A1, 0x0000, 0x0000, 0x0000 } },
1372  { 0x04A2, { 0x04A3, 0x0000, 0x0000, 0x0000 } },
1373  { 0x04A4, { 0x04A5, 0x0000, 0x0000, 0x0000 } },
1374  { 0x04A6, { 0x04A7, 0x0000, 0x0000, 0x0000 } },
1375  { 0x04A8, { 0x04A9, 0x0000, 0x0000, 0x0000 } },
1376  { 0x04AA, { 0x04AB, 0x0000, 0x0000, 0x0000 } },
1377  { 0x04AC, { 0x04AD, 0x0000, 0x0000, 0x0000 } },
1378  { 0x04AE, { 0x04AF, 0x0000, 0x0000, 0x0000 } },
1379  { 0x04B0, { 0x04B1, 0x0000, 0x0000, 0x0000 } },
1380  { 0x04B2, { 0x04B3, 0x0000, 0x0000, 0x0000 } },
1381  { 0x04B4, { 0x04B5, 0x0000, 0x0000, 0x0000 } },
1382  { 0x04B6, { 0x04B7, 0x0000, 0x0000, 0x0000 } },
1383  { 0x04B8, { 0x04B9, 0x0000, 0x0000, 0x0000 } },
1384  { 0x04BA, { 0x04BB, 0x0000, 0x0000, 0x0000 } },
1385  { 0x04BC, { 0x04BD, 0x0000, 0x0000, 0x0000 } },
1386  { 0x04BE, { 0x04BF, 0x0000, 0x0000, 0x0000 } },
1387  { 0x04C1, { 0x04C2, 0x0000, 0x0000, 0x0000 } },
1388  { 0x04C3, { 0x04C4, 0x0000, 0x0000, 0x0000 } },
1389  { 0x04C5, { 0x04C6, 0x0000, 0x0000, 0x0000 } },
1390  { 0x04C7, { 0x04C8, 0x0000, 0x0000, 0x0000 } },
1391  { 0x04C9, { 0x04CA, 0x0000, 0x0000, 0x0000 } },
1392  { 0x04CB, { 0x04CC, 0x0000, 0x0000, 0x0000 } },
1393  { 0x04CD, { 0x04CE, 0x0000, 0x0000, 0x0000 } },
1394  { 0x04D0, { 0x04D1, 0x0000, 0x0000, 0x0000 } },
1395  { 0x04D2, { 0x04D3, 0x0000, 0x0000, 0x0000 } },
1396  { 0x04D4, { 0x04D5, 0x0000, 0x0000, 0x0000 } },
1397  { 0x04D6, { 0x04D7, 0x0000, 0x0000, 0x0000 } },
1398  { 0x04D8, { 0x04D9, 0x0000, 0x0000, 0x0000 } },
1399  { 0x04DA, { 0x04DB, 0x0000, 0x0000, 0x0000 } },
1400  { 0x04DC, { 0x04DD, 0x0000, 0x0000, 0x0000 } },
1401  { 0x04DE, { 0x04DF, 0x0000, 0x0000, 0x0000 } },
1402  { 0x04E0, { 0x04E1, 0x0000, 0x0000, 0x0000 } },
1403  { 0x04E2, { 0x04E3, 0x0000, 0x0000, 0x0000 } },
1404  { 0x04E4, { 0x04E5, 0x0000, 0x0000, 0x0000 } },
1405  { 0x04E6, { 0x04E7, 0x0000, 0x0000, 0x0000 } },
1406  { 0x04E8, { 0x04E9, 0x0000, 0x0000, 0x0000 } },
1407  { 0x04EA, { 0x04EB, 0x0000, 0x0000, 0x0000 } },
1408  { 0x04EC, { 0x04ED, 0x0000, 0x0000, 0x0000 } },
1409  { 0x04EE, { 0x04EF, 0x0000, 0x0000, 0x0000 } },
1410  { 0x04F0, { 0x04F1, 0x0000, 0x0000, 0x0000 } },
1411  { 0x04F2, { 0x04F3, 0x0000, 0x0000, 0x0000 } },
1412  { 0x04F4, { 0x04F5, 0x0000, 0x0000, 0x0000 } },
1413  { 0x04F8, { 0x04F9, 0x0000, 0x0000, 0x0000 } },
1414  { 0x0500, { 0x0501, 0x0000, 0x0000, 0x0000 } },
1415  { 0x0502, { 0x0503, 0x0000, 0x0000, 0x0000 } },
1416  { 0x0504, { 0x0505, 0x0000, 0x0000, 0x0000 } },
1417  { 0x0506, { 0x0507, 0x0000, 0x0000, 0x0000 } },
1418  { 0x0508, { 0x0509, 0x0000, 0x0000, 0x0000 } },
1419  { 0x050A, { 0x050B, 0x0000, 0x0000, 0x0000 } },
1420  { 0x050C, { 0x050D, 0x0000, 0x0000, 0x0000 } },
1421  { 0x050E, { 0x050F, 0x0000, 0x0000, 0x0000 } },
1422  { 0x0531, { 0x0561, 0x0000, 0x0000, 0x0000 } },
1423  { 0x0532, { 0x0562, 0x0000, 0x0000, 0x0000 } },
1424  { 0x0533, { 0x0563, 0x0000, 0x0000, 0x0000 } },
1425  { 0x0534, { 0x0564, 0x0000, 0x0000, 0x0000 } },
1426  { 0x0535, { 0x0565, 0x0000, 0x0000, 0x0000 } },
1427  { 0x0536, { 0x0566, 0x0000, 0x0000, 0x0000 } },
1428  { 0x0537, { 0x0567, 0x0000, 0x0000, 0x0000 } },
1429  { 0x0538, { 0x0568, 0x0000, 0x0000, 0x0000 } },
1430  { 0x0539, { 0x0569, 0x0000, 0x0000, 0x0000 } },
1431  { 0x053A, { 0x056A, 0x0000, 0x0000, 0x0000 } },
1432  { 0x053B, { 0x056B, 0x0000, 0x0000, 0x0000 } },
1433  { 0x053C, { 0x056C, 0x0000, 0x0000, 0x0000 } },
1434  { 0x053D, { 0x056D, 0x0000, 0x0000, 0x0000 } },
1435  { 0x053E, { 0x056E, 0x0000, 0x0000, 0x0000 } },
1436  { 0x053F, { 0x056F, 0x0000, 0x0000, 0x0000 } },
1437  { 0x0540, { 0x0570, 0x0000, 0x0000, 0x0000 } },
1438  { 0x0541, { 0x0571, 0x0000, 0x0000, 0x0000 } },
1439  { 0x0542, { 0x0572, 0x0000, 0x0000, 0x0000 } },
1440  { 0x0543, { 0x0573, 0x0000, 0x0000, 0x0000 } },
1441  { 0x0544, { 0x0574, 0x0000, 0x0000, 0x0000 } },
1442  { 0x0545, { 0x0575, 0x0000, 0x0000, 0x0000 } },
1443  { 0x0546, { 0x0576, 0x0000, 0x0000, 0x0000 } },
1444  { 0x0547, { 0x0577, 0x0000, 0x0000, 0x0000 } },
1445  { 0x0548, { 0x0578, 0x0000, 0x0000, 0x0000 } },
1446  { 0x0549, { 0x0579, 0x0000, 0x0000, 0x0000 } },
1447  { 0x054A, { 0x057A, 0x0000, 0x0000, 0x0000 } },
1448  { 0x054B, { 0x057B, 0x0000, 0x0000, 0x0000 } },
1449  { 0x054C, { 0x057C, 0x0000, 0x0000, 0x0000 } },
1450  { 0x054D, { 0x057D, 0x0000, 0x0000, 0x0000 } },
1451  { 0x054E, { 0x057E, 0x0000, 0x0000, 0x0000 } },
1452  { 0x054F, { 0x057F, 0x0000, 0x0000, 0x0000 } },
1453  { 0x0550, { 0x0580, 0x0000, 0x0000, 0x0000 } },
1454  { 0x0551, { 0x0581, 0x0000, 0x0000, 0x0000 } },
1455  { 0x0552, { 0x0582, 0x0000, 0x0000, 0x0000 } },
1456  { 0x0553, { 0x0583, 0x0000, 0x0000, 0x0000 } },
1457  { 0x0554, { 0x0584, 0x0000, 0x0000, 0x0000 } },
1458  { 0x0555, { 0x0585, 0x0000, 0x0000, 0x0000 } },
1459  { 0x0556, { 0x0586, 0x0000, 0x0000, 0x0000 } },
1460  { 0x0587, { 0x0565, 0x0582, 0x0000, 0x0000 } },
1461  { 0x1E00, { 0x1E01, 0x0000, 0x0000, 0x0000 } },
1462  { 0x1E02, { 0x1E03, 0x0000, 0x0000, 0x0000 } },
1463  { 0x1E04, { 0x1E05, 0x0000, 0x0000, 0x0000 } },
1464  { 0x1E06, { 0x1E07, 0x0000, 0x0000, 0x0000 } },
1465  { 0x1E08, { 0x1E09, 0x0000, 0x0000, 0x0000 } },
1466  { 0x1E0A, { 0x1E0B, 0x0000, 0x0000, 0x0000 } },
1467  { 0x1E0C, { 0x1E0D, 0x0000, 0x0000, 0x0000 } },
1468  { 0x1E0E, { 0x1E0F, 0x0000, 0x0000, 0x0000 } },
1469  { 0x1E10, { 0x1E11, 0x0000, 0x0000, 0x0000 } },
1470  { 0x1E12, { 0x1E13, 0x0000, 0x0000, 0x0000 } },
1471  { 0x1E14, { 0x1E15, 0x0000, 0x0000, 0x0000 } },
1472  { 0x1E16, { 0x1E17, 0x0000, 0x0000, 0x0000 } },
1473  { 0x1E18, { 0x1E19, 0x0000, 0x0000, 0x0000 } },
1474  { 0x1E1A, { 0x1E1B, 0x0000, 0x0000, 0x0000 } },
1475  { 0x1E1C, { 0x1E1D, 0x0000, 0x0000, 0x0000 } },
1476  { 0x1E1E, { 0x1E1F, 0x0000, 0x0000, 0x0000 } },
1477  { 0x1E20, { 0x1E21, 0x0000, 0x0000, 0x0000 } },
1478  { 0x1E22, { 0x1E23, 0x0000, 0x0000, 0x0000 } },
1479  { 0x1E24, { 0x1E25, 0x0000, 0x0000, 0x0000 } },
1480  { 0x1E26, { 0x1E27, 0x0000, 0x0000, 0x0000 } },
1481  { 0x1E28, { 0x1E29, 0x0000, 0x0000, 0x0000 } },
1482  { 0x1E2A, { 0x1E2B, 0x0000, 0x0000, 0x0000 } },
1483  { 0x1E2C, { 0x1E2D, 0x0000, 0x0000, 0x0000 } },
1484  { 0x1E2E, { 0x1E2F, 0x0000, 0x0000, 0x0000 } },
1485  { 0x1E30, { 0x1E31, 0x0000, 0x0000, 0x0000 } },
1486  { 0x1E32, { 0x1E33, 0x0000, 0x0000, 0x0000 } },
1487  { 0x1E34, { 0x1E35, 0x0000, 0x0000, 0x0000 } },
1488  { 0x1E36, { 0x1E37, 0x0000, 0x0000, 0x0000 } },
1489  { 0x1E38, { 0x1E39, 0x0000, 0x0000, 0x0000 } },
1490  { 0x1E3A, { 0x1E3B, 0x0000, 0x0000, 0x0000 } },
1491  { 0x1E3C, { 0x1E3D, 0x0000, 0x0000, 0x0000 } },
1492  { 0x1E3E, { 0x1E3F, 0x0000, 0x0000, 0x0000 } },
1493  { 0x1E40, { 0x1E41, 0x0000, 0x0000, 0x0000 } },
1494  { 0x1E42, { 0x1E43, 0x0000, 0x0000, 0x0000 } },
1495  { 0x1E44, { 0x1E45, 0x0000, 0x0000, 0x0000 } },
1496  { 0x1E46, { 0x1E47, 0x0000, 0x0000, 0x0000 } },
1497  { 0x1E48, { 0x1E49, 0x0000, 0x0000, 0x0000 } },
1498  { 0x1E4A, { 0x1E4B, 0x0000, 0x0000, 0x0000 } },
1499  { 0x1E4C, { 0x1E4D, 0x0000, 0x0000, 0x0000 } },
1500  { 0x1E4E, { 0x1E4F, 0x0000, 0x0000, 0x0000 } },
1501  { 0x1E50, { 0x1E51, 0x0000, 0x0000, 0x0000 } },
1502  { 0x1E52, { 0x1E53, 0x0000, 0x0000, 0x0000 } },
1503  { 0x1E54, { 0x1E55, 0x0000, 0x0000, 0x0000 } },
1504  { 0x1E56, { 0x1E57, 0x0000, 0x0000, 0x0000 } },
1505  { 0x1E58, { 0x1E59, 0x0000, 0x0000, 0x0000 } },
1506  { 0x1E5A, { 0x1E5B, 0x0000, 0x0000, 0x0000 } },
1507  { 0x1E5C, { 0x1E5D, 0x0000, 0x0000, 0x0000 } },
1508  { 0x1E5E, { 0x1E5F, 0x0000, 0x0000, 0x0000 } },
1509  { 0x1E60, { 0x1E61, 0x0000, 0x0000, 0x0000 } },
1510  { 0x1E62, { 0x1E63, 0x0000, 0x0000, 0x0000 } },
1511  { 0x1E64, { 0x1E65, 0x0000, 0x0000, 0x0000 } },
1512  { 0x1E66, { 0x1E67, 0x0000, 0x0000, 0x0000 } },
1513  { 0x1E68, { 0x1E69, 0x0000, 0x0000, 0x0000 } },
1514  { 0x1E6A, { 0x1E6B, 0x0000, 0x0000, 0x0000 } },
1515  { 0x1E6C, { 0x1E6D, 0x0000, 0x0000, 0x0000 } },
1516  { 0x1E6E, { 0x1E6F, 0x0000, 0x0000, 0x0000 } },
1517  { 0x1E70, { 0x1E71, 0x0000, 0x0000, 0x0000 } },
1518  { 0x1E72, { 0x1E73, 0x0000, 0x0000, 0x0000 } },
1519  { 0x1E74, { 0x1E75, 0x0000, 0x0000, 0x0000 } },
1520  { 0x1E76, { 0x1E77, 0x0000, 0x0000, 0x0000 } },
1521  { 0x1E78, { 0x1E79, 0x0000, 0x0000, 0x0000 } },
1522  { 0x1E7A, { 0x1E7B, 0x0000, 0x0000, 0x0000 } },
1523  { 0x1E7C, { 0x1E7D, 0x0000, 0x0000, 0x0000 } },
1524  { 0x1E7E, { 0x1E7F, 0x0000, 0x0000, 0x0000 } },
1525  { 0x1E80, { 0x1E81, 0x0000, 0x0000, 0x0000 } },
1526  { 0x1E82, { 0x1E83, 0x0000, 0x0000, 0x0000 } },
1527  { 0x1E84, { 0x1E85, 0x0000, 0x0000, 0x0000 } },
1528  { 0x1E86, { 0x1E87, 0x0000, 0x0000, 0x0000 } },
1529  { 0x1E88, { 0x1E89, 0x0000, 0x0000, 0x0000 } },
1530  { 0x1E8A, { 0x1E8B, 0x0000, 0x0000, 0x0000 } },
1531  { 0x1E8C, { 0x1E8D, 0x0000, 0x0000, 0x0000 } },
1532  { 0x1E8E, { 0x1E8F, 0x0000, 0x0000, 0x0000 } },
1533  { 0x1E90, { 0x1E91, 0x0000, 0x0000, 0x0000 } },
1534  { 0x1E92, { 0x1E93, 0x0000, 0x0000, 0x0000 } },
1535  { 0x1E94, { 0x1E95, 0x0000, 0x0000, 0x0000 } },
1536  { 0x1E96, { 0x0068, 0x0331, 0x0000, 0x0000 } },
1537  { 0x1E97, { 0x0074, 0x0308, 0x0000, 0x0000 } },
1538  { 0x1E98, { 0x0077, 0x030A, 0x0000, 0x0000 } },
1539  { 0x1E99, { 0x0079, 0x030A, 0x0000, 0x0000 } },
1540  { 0x1E9A, { 0x0061, 0x02BE, 0x0000, 0x0000 } },
1541  { 0x1E9B, { 0x1E61, 0x0000, 0x0000, 0x0000 } },
1542  { 0x1EA0, { 0x1EA1, 0x0000, 0x0000, 0x0000 } },
1543  { 0x1EA2, { 0x1EA3, 0x0000, 0x0000, 0x0000 } },
1544  { 0x1EA4, { 0x1EA5, 0x0000, 0x0000, 0x0000 } },
1545  { 0x1EA6, { 0x1EA7, 0x0000, 0x0000, 0x0000 } },
1546  { 0x1EA8, { 0x1EA9, 0x0000, 0x0000, 0x0000 } },
1547  { 0x1EAA, { 0x1EAB, 0x0000, 0x0000, 0x0000 } },
1548  { 0x1EAC, { 0x1EAD, 0x0000, 0x0000, 0x0000 } },
1549  { 0x1EAE, { 0x1EAF, 0x0000, 0x0000, 0x0000 } },
1550  { 0x1EB0, { 0x1EB1, 0x0000, 0x0000, 0x0000 } },
1551  { 0x1EB2, { 0x1EB3, 0x0000, 0x0000, 0x0000 } },
1552  { 0x1EB4, { 0x1EB5, 0x0000, 0x0000, 0x0000 } },
1553  { 0x1EB6, { 0x1EB7, 0x0000, 0x0000, 0x0000 } },
1554  { 0x1EB8, { 0x1EB9, 0x0000, 0x0000, 0x0000 } },
1555  { 0x1EBA, { 0x1EBB, 0x0000, 0x0000, 0x0000 } },
1556  { 0x1EBC, { 0x1EBD, 0x0000, 0x0000, 0x0000 } },
1557  { 0x1EBE, { 0x1EBF, 0x0000, 0x0000, 0x0000 } },
1558  { 0x1EC0, { 0x1EC1, 0x0000, 0x0000, 0x0000 } },
1559  { 0x1EC2, { 0x1EC3, 0x0000, 0x0000, 0x0000 } },
1560  { 0x1EC4, { 0x1EC5, 0x0000, 0x0000, 0x0000 } },
1561  { 0x1EC6, { 0x1EC7, 0x0000, 0x0000, 0x0000 } },
1562  { 0x1EC8, { 0x1EC9, 0x0000, 0x0000, 0x0000 } },
1563  { 0x1ECA, { 0x1ECB, 0x0000, 0x0000, 0x0000 } },
1564  { 0x1ECC, { 0x1ECD, 0x0000, 0x0000, 0x0000 } },
1565  { 0x1ECE, { 0x1ECF, 0x0000, 0x0000, 0x0000 } },
1566  { 0x1ED0, { 0x1ED1, 0x0000, 0x0000, 0x0000 } },
1567  { 0x1ED2, { 0x1ED3, 0x0000, 0x0000, 0x0000 } },
1568  { 0x1ED4, { 0x1ED5, 0x0000, 0x0000, 0x0000 } },
1569  { 0x1ED6, { 0x1ED7, 0x0000, 0x0000, 0x0000 } },
1570  { 0x1ED8, { 0x1ED9, 0x0000, 0x0000, 0x0000 } },
1571  { 0x1EDA, { 0x1EDB, 0x0000, 0x0000, 0x0000 } },
1572  { 0x1EDC, { 0x1EDD, 0x0000, 0x0000, 0x0000 } },
1573  { 0x1EDE, { 0x1EDF, 0x0000, 0x0000, 0x0000 } },
1574  { 0x1EE0, { 0x1EE1, 0x0000, 0x0000, 0x0000 } },
1575  { 0x1EE2, { 0x1EE3, 0x0000, 0x0000, 0x0000 } },
1576  { 0x1EE4, { 0x1EE5, 0x0000, 0x0000, 0x0000 } },
1577  { 0x1EE6, { 0x1EE7, 0x0000, 0x0000, 0x0000 } },
1578  { 0x1EE8, { 0x1EE9, 0x0000, 0x0000, 0x0000 } },
1579  { 0x1EEA, { 0x1EEB, 0x0000, 0x0000, 0x0000 } },
1580  { 0x1EEC, { 0x1EED, 0x0000, 0x0000, 0x0000 } },
1581  { 0x1EEE, { 0x1EEF, 0x0000, 0x0000, 0x0000 } },
1582  { 0x1EF0, { 0x1EF1, 0x0000, 0x0000, 0x0000 } },
1583  { 0x1EF2, { 0x1EF3, 0x0000, 0x0000, 0x0000 } },
1584  { 0x1EF4, { 0x1EF5, 0x0000, 0x0000, 0x0000 } },
1585  { 0x1EF6, { 0x1EF7, 0x0000, 0x0000, 0x0000 } },
1586  { 0x1EF8, { 0x1EF9, 0x0000, 0x0000, 0x0000 } },
1587  { 0x1F08, { 0x1F00, 0x0000, 0x0000, 0x0000 } },
1588  { 0x1F09, { 0x1F01, 0x0000, 0x0000, 0x0000 } },
1589  { 0x1F0A, { 0x1F02, 0x0000, 0x0000, 0x0000 } },
1590  { 0x1F0B, { 0x1F03, 0x0000, 0x0000, 0x0000 } },
1591  { 0x1F0C, { 0x1F04, 0x0000, 0x0000, 0x0000 } },
1592  { 0x1F0D, { 0x1F05, 0x0000, 0x0000, 0x0000 } },
1593  { 0x1F0E, { 0x1F06, 0x0000, 0x0000, 0x0000 } },
1594  { 0x1F0F, { 0x1F07, 0x0000, 0x0000, 0x0000 } },
1595  { 0x1F18, { 0x1F10, 0x0000, 0x0000, 0x0000 } },
1596  { 0x1F19, { 0x1F11, 0x0000, 0x0000, 0x0000 } },
1597  { 0x1F1A, { 0x1F12, 0x0000, 0x0000, 0x0000 } },
1598  { 0x1F1B, { 0x1F13, 0x0000, 0x0000, 0x0000 } },
1599  { 0x1F1C, { 0x1F14, 0x0000, 0x0000, 0x0000 } },
1600  { 0x1F1D, { 0x1F15, 0x0000, 0x0000, 0x0000 } },
1601  { 0x1F28, { 0x1F20, 0x0000, 0x0000, 0x0000 } },
1602  { 0x1F29, { 0x1F21, 0x0000, 0x0000, 0x0000 } },
1603  { 0x1F2A, { 0x1F22, 0x0000, 0x0000, 0x0000 } },
1604  { 0x1F2B, { 0x1F23, 0x0000, 0x0000, 0x0000 } },
1605  { 0x1F2C, { 0x1F24, 0x0000, 0x0000, 0x0000 } },
1606  { 0x1F2D, { 0x1F25, 0x0000, 0x0000, 0x0000 } },
1607  { 0x1F2E, { 0x1F26, 0x0000, 0x0000, 0x0000 } },
1608  { 0x1F2F, { 0x1F27, 0x0000, 0x0000, 0x0000 } },
1609  { 0x1F38, { 0x1F30, 0x0000, 0x0000, 0x0000 } },
1610  { 0x1F39, { 0x1F31, 0x0000, 0x0000, 0x0000 } },
1611  { 0x1F3A, { 0x1F32, 0x0000, 0x0000, 0x0000 } },
1612  { 0x1F3B, { 0x1F33, 0x0000, 0x0000, 0x0000 } },
1613  { 0x1F3C, { 0x1F34, 0x0000, 0x0000, 0x0000 } },
1614  { 0x1F3D, { 0x1F35, 0x0000, 0x0000, 0x0000 } },
1615  { 0x1F3E, { 0x1F36, 0x0000, 0x0000, 0x0000 } },
1616  { 0x1F3F, { 0x1F37, 0x0000, 0x0000, 0x0000 } },
1617  { 0x1F48, { 0x1F40, 0x0000, 0x0000, 0x0000 } },
1618  { 0x1F49, { 0x1F41, 0x0000, 0x0000, 0x0000 } },
1619  { 0x1F4A, { 0x1F42, 0x0000, 0x0000, 0x0000 } },
1620  { 0x1F4B, { 0x1F43, 0x0000, 0x0000, 0x0000 } },
1621  { 0x1F4C, { 0x1F44, 0x0000, 0x0000, 0x0000 } },
1622  { 0x1F4D, { 0x1F45, 0x0000, 0x0000, 0x0000 } },
1623  { 0x1F50, { 0x03C5, 0x0313, 0x0000, 0x0000 } },
1624  { 0x1F52, { 0x03C5, 0x0313, 0x0300, 0x0000 } },
1625  { 0x1F54, { 0x03C5, 0x0313, 0x0301, 0x0000 } },
1626  { 0x1F56, { 0x03C5, 0x0313, 0x0342, 0x0000 } },
1627  { 0x1F59, { 0x1F51, 0x0000, 0x0000, 0x0000 } },
1628  { 0x1F5B, { 0x1F53, 0x0000, 0x0000, 0x0000 } },
1629  { 0x1F5D, { 0x1F55, 0x0000, 0x0000, 0x0000 } },
1630  { 0x1F5F, { 0x1F57, 0x0000, 0x0000, 0x0000 } },
1631  { 0x1F68, { 0x1F60, 0x0000, 0x0000, 0x0000 } },
1632  { 0x1F69, { 0x1F61, 0x0000, 0x0000, 0x0000 } },
1633  { 0x1F6A, { 0x1F62, 0x0000, 0x0000, 0x0000 } },
1634  { 0x1F6B, { 0x1F63, 0x0000, 0x0000, 0x0000 } },
1635  { 0x1F6C, { 0x1F64, 0x0000, 0x0000, 0x0000 } },
1636  { 0x1F6D, { 0x1F65, 0x0000, 0x0000, 0x0000 } },
1637  { 0x1F6E, { 0x1F66, 0x0000, 0x0000, 0x0000 } },
1638  { 0x1F6F, { 0x1F67, 0x0000, 0x0000, 0x0000 } },
1639  { 0x1F80, { 0x1F00, 0x03B9, 0x0000, 0x0000 } },
1640  { 0x1F81, { 0x1F01, 0x03B9, 0x0000, 0x0000 } },
1641  { 0x1F82, { 0x1F02, 0x03B9, 0x0000, 0x0000 } },
1642  { 0x1F83, { 0x1F03, 0x03B9, 0x0000, 0x0000 } },
1643  { 0x1F84, { 0x1F04, 0x03B9, 0x0000, 0x0000 } },
1644  { 0x1F85, { 0x1F05, 0x03B9, 0x0000, 0x0000 } },
1645  { 0x1F86, { 0x1F06, 0x03B9, 0x0000, 0x0000 } },
1646  { 0x1F87, { 0x1F07, 0x03B9, 0x0000, 0x0000 } },
1647  { 0x1F88, { 0x1F00, 0x03B9, 0x0000, 0x0000 } },
1648  { 0x1F89, { 0x1F01, 0x03B9, 0x0000, 0x0000 } },
1649  { 0x1F8A, { 0x1F02, 0x03B9, 0x0000, 0x0000 } },
1650  { 0x1F8B, { 0x1F03, 0x03B9, 0x0000, 0x0000 } },
1651  { 0x1F8C, { 0x1F04, 0x03B9, 0x0000, 0x0000 } },
1652  { 0x1F8D, { 0x1F05, 0x03B9, 0x0000, 0x0000 } },
1653  { 0x1F8E, { 0x1F06, 0x03B9, 0x0000, 0x0000 } },
1654  { 0x1F8F, { 0x1F07, 0x03B9, 0x0000, 0x0000 } },
1655  { 0x1F90, { 0x1F20, 0x03B9, 0x0000, 0x0000 } },
1656  { 0x1F91, { 0x1F21, 0x03B9, 0x0000, 0x0000 } },
1657  { 0x1F92, { 0x1F22, 0x03B9, 0x0000, 0x0000 } },
1658  { 0x1F93, { 0x1F23, 0x03B9, 0x0000, 0x0000 } },
1659  { 0x1F94, { 0x1F24, 0x03B9, 0x0000, 0x0000 } },
1660  { 0x1F95, { 0x1F25, 0x03B9, 0x0000, 0x0000 } },
1661  { 0x1F96, { 0x1F26, 0x03B9, 0x0000, 0x0000 } },
1662  { 0x1F97, { 0x1F27, 0x03B9, 0x0000, 0x0000 } },
1663  { 0x1F98, { 0x1F20, 0x03B9, 0x0000, 0x0000 } },
1664  { 0x1F99, { 0x1F21, 0x03B9, 0x0000, 0x0000 } },
1665  { 0x1F9A, { 0x1F22, 0x03B9, 0x0000, 0x0000 } },
1666  { 0x1F9B, { 0x1F23, 0x03B9, 0x0000, 0x0000 } },
1667  { 0x1F9C, { 0x1F24, 0x03B9, 0x0000, 0x0000 } },
1668  { 0x1F9D, { 0x1F25, 0x03B9, 0x0000, 0x0000 } },
1669  { 0x1F9E, { 0x1F26, 0x03B9, 0x0000, 0x0000 } },
1670  { 0x1F9F, { 0x1F27, 0x03B9, 0x0000, 0x0000 } },
1671  { 0x1FA0, { 0x1F60, 0x03B9, 0x0000, 0x0000 } },
1672  { 0x1FA1, { 0x1F61, 0x03B9, 0x0000, 0x0000 } },
1673  { 0x1FA2, { 0x1F62, 0x03B9, 0x0000, 0x0000 } },
1674  { 0x1FA3, { 0x1F63, 0x03B9, 0x0000, 0x0000 } },
1675  { 0x1FA4, { 0x1F64, 0x03B9, 0x0000, 0x0000 } },
1676  { 0x1FA5, { 0x1F65, 0x03B9, 0x0000, 0x0000 } },
1677  { 0x1FA6, { 0x1F66, 0x03B9, 0x0000, 0x0000 } },
1678  { 0x1FA7, { 0x1F67, 0x03B9, 0x0000, 0x0000 } },
1679  { 0x1FA8, { 0x1F60, 0x03B9, 0x0000, 0x0000 } },
1680  { 0x1FA9, { 0x1F61, 0x03B9, 0x0000, 0x0000 } },
1681  { 0x1FAA, { 0x1F62, 0x03B9, 0x0000, 0x0000 } },
1682  { 0x1FAB, { 0x1F63, 0x03B9, 0x0000, 0x0000 } },
1683  { 0x1FAC, { 0x1F64, 0x03B9, 0x0000, 0x0000 } },
1684  { 0x1FAD, { 0x1F65, 0x03B9, 0x0000, 0x0000 } },
1685  { 0x1FAE, { 0x1F66, 0x03B9, 0x0000, 0x0000 } },
1686  { 0x1FAF, { 0x1F67, 0x03B9, 0x0000, 0x0000 } },
1687  { 0x1FB2, { 0x1F70, 0x03B9, 0x0000, 0x0000 } },
1688  { 0x1FB3, { 0x03B1, 0x03B9, 0x0000, 0x0000 } },
1689  { 0x1FB4, { 0x03AC, 0x03B9, 0x0000, 0x0000 } },
1690  { 0x1FB6, { 0x03B1, 0x0342, 0x0000, 0x0000 } },
1691  { 0x1FB7, { 0x03B1, 0x0342, 0x03B9, 0x0000 } },
1692  { 0x1FB8, { 0x1FB0, 0x0000, 0x0000, 0x0000 } },
1693  { 0x1FB9, { 0x1FB1, 0x0000, 0x0000, 0x0000 } },
1694  { 0x1FBA, { 0x1F70, 0x0000, 0x0000, 0x0000 } },
1695  { 0x1FBB, { 0x1F71, 0x0000, 0x0000, 0x0000 } },
1696  { 0x1FBC, { 0x03B1, 0x03B9, 0x0000, 0x0000 } },
1697  { 0x1FBE, { 0x03B9, 0x0000, 0x0000, 0x0000 } },
1698  { 0x1FC2, { 0x1F74, 0x03B9, 0x0000, 0x0000 } },
1699  { 0x1FC3, { 0x03B7, 0x03B9, 0x0000, 0x0000 } },
1700  { 0x1FC4, { 0x03AE, 0x03B9, 0x0000, 0x0000 } },
1701  { 0x1FC6, { 0x03B7, 0x0342, 0x0000, 0x0000 } },
1702  { 0x1FC7, { 0x03B7, 0x0342, 0x03B9, 0x0000 } },
1703  { 0x1FC8, { 0x1F72, 0x0000, 0x0000, 0x0000 } },
1704  { 0x1FC9, { 0x1F73, 0x0000, 0x0000, 0x0000 } },
1705  { 0x1FCA, { 0x1F74, 0x0000, 0x0000, 0x0000 } },
1706  { 0x1FCB, { 0x1F75, 0x0000, 0x0000, 0x0000 } },
1707  { 0x1FCC, { 0x03B7, 0x03B9, 0x0000, 0x0000 } },
1708  { 0x1FD2, { 0x03B9, 0x0308, 0x0300, 0x0000 } },
1709  { 0x1FD3, { 0x03B9, 0x0308, 0x0301, 0x0000 } },
1710  { 0x1FD6, { 0x03B9, 0x0342, 0x0000, 0x0000 } },
1711  { 0x1FD7, { 0x03B9, 0x0308, 0x0342, 0x0000 } },
1712  { 0x1FD8, { 0x1FD0, 0x0000, 0x0000, 0x0000 } },
1713  { 0x1FD9, { 0x1FD1, 0x0000, 0x0000, 0x0000 } },
1714  { 0x1FDA, { 0x1F76, 0x0000, 0x0000, 0x0000 } },
1715  { 0x1FDB, { 0x1F77, 0x0000, 0x0000, 0x0000 } },
1716  { 0x1FE2, { 0x03C5, 0x0308, 0x0300, 0x0000 } },
1717  { 0x1FE3, { 0x03C5, 0x0308, 0x0301, 0x0000 } },
1718  { 0x1FE4, { 0x03C1, 0x0313, 0x0000, 0x0000 } },
1719  { 0x1FE6, { 0x03C5, 0x0342, 0x0000, 0x0000 } },
1720  { 0x1FE7, { 0x03C5, 0x0308, 0x0342, 0x0000 } },
1721  { 0x1FE8, { 0x1FE0, 0x0000, 0x0000, 0x0000 } },
1722  { 0x1FE9, { 0x1FE1, 0x0000, 0x0000, 0x0000 } },
1723  { 0x1FEA, { 0x1F7A, 0x0000, 0x0000, 0x0000 } },
1724  { 0x1FEB, { 0x1F7B, 0x0000, 0x0000, 0x0000 } },
1725  { 0x1FEC, { 0x1FE5, 0x0000, 0x0000, 0x0000 } },
1726  { 0x1FF2, { 0x1F7C, 0x03B9, 0x0000, 0x0000 } },
1727  { 0x1FF3, { 0x03C9, 0x03B9, 0x0000, 0x0000 } },
1728  { 0x1FF4, { 0x03CE, 0x03B9, 0x0000, 0x0000 } },
1729  { 0x1FF6, { 0x03C9, 0x0342, 0x0000, 0x0000 } },
1730  { 0x1FF7, { 0x03C9, 0x0342, 0x03B9, 0x0000 } },
1731  { 0x1FF8, { 0x1F78, 0x0000, 0x0000, 0x0000 } },
1732  { 0x1FF9, { 0x1F79, 0x0000, 0x0000, 0x0000 } },
1733  { 0x1FFA, { 0x1F7C, 0x0000, 0x0000, 0x0000 } },
1734  { 0x1FFB, { 0x1F7D, 0x0000, 0x0000, 0x0000 } },
1735  { 0x1FFC, { 0x03C9, 0x03B9, 0x0000, 0x0000 } },
1736  { 0x20A8, { 0x0072, 0x0073, 0x0000, 0x0000 } },
1737  { 0x2102, { 0x0063, 0x0000, 0x0000, 0x0000 } },
1738  { 0x2103, { 0x00B0, 0x0063, 0x0000, 0x0000 } },
1739  { 0x2107, { 0x025B, 0x0000, 0x0000, 0x0000 } },
1740  { 0x2109, { 0x00B0, 0x0066, 0x0000, 0x0000 } },
1741  { 0x210B, { 0x0068, 0x0000, 0x0000, 0x0000 } },
1742  { 0x210C, { 0x0068, 0x0000, 0x0000, 0x0000 } },
1743  { 0x210D, { 0x0068, 0x0000, 0x0000, 0x0000 } },
1744  { 0x2110, { 0x0069, 0x0000, 0x0000, 0x0000 } },
1745  { 0x2111, { 0x0069, 0x0000, 0x0000, 0x0000 } },
1746  { 0x2112, { 0x006C, 0x0000, 0x0000, 0x0000 } },
1747  { 0x2115, { 0x006E, 0x0000, 0x0000, 0x0000 } },
1748  { 0x2116, { 0x006E, 0x006F, 0x0000, 0x0000 } },
1749  { 0x2119, { 0x0070, 0x0000, 0x0000, 0x0000 } },
1750  { 0x211A, { 0x0071, 0x0000, 0x0000, 0x0000 } },
1751  { 0x211B, { 0x0072, 0x0000, 0x0000, 0x0000 } },
1752  { 0x211C, { 0x0072, 0x0000, 0x0000, 0x0000 } },
1753  { 0x211D, { 0x0072, 0x0000, 0x0000, 0x0000 } },
1754  { 0x2120, { 0x0073, 0x006D, 0x0000, 0x0000 } },
1755  { 0x2121, { 0x0074, 0x0065, 0x006C, 0x0000 } },
1756  { 0x2122, { 0x0074, 0x006D, 0x0000, 0x0000 } },
1757  { 0x2124, { 0x007A, 0x0000, 0x0000, 0x0000 } },
1758  { 0x2126, { 0x03C9, 0x0000, 0x0000, 0x0000 } },
1759  { 0x2128, { 0x007A, 0x0000, 0x0000, 0x0000 } },
1760  { 0x212A, { 0x006B, 0x0000, 0x0000, 0x0000 } },
1761  { 0x212B, { 0x00E5, 0x0000, 0x0000, 0x0000 } },
1762  { 0x212C, { 0x0062, 0x0000, 0x0000, 0x0000 } },
1763  { 0x212D, { 0x0063, 0x0000, 0x0000, 0x0000 } },
1764  { 0x2130, { 0x0065, 0x0000, 0x0000, 0x0000 } },
1765  { 0x2131, { 0x0066, 0x0000, 0x0000, 0x0000 } },
1766  { 0x2133, { 0x006D, 0x0000, 0x0000, 0x0000 } },
1767  { 0x213E, { 0x03B3, 0x0000, 0x0000, 0x0000 } },
1768  { 0x213F, { 0x03C0, 0x0000, 0x0000, 0x0000 } },
1769  { 0x2145, { 0x0064, 0x0000, 0x0000, 0x0000 } },
1770  { 0x2160, { 0x2170, 0x0000, 0x0000, 0x0000 } },
1771  { 0x2161, { 0x2171, 0x0000, 0x0000, 0x0000 } },
1772  { 0x2162, { 0x2172, 0x0000, 0x0000, 0x0000 } },
1773  { 0x2163, { 0x2173, 0x0000, 0x0000, 0x0000 } },
1774  { 0x2164, { 0x2174, 0x0000, 0x0000, 0x0000 } },
1775  { 0x2165, { 0x2175, 0x0000, 0x0000, 0x0000 } },
1776  { 0x2166, { 0x2176, 0x0000, 0x0000, 0x0000 } },
1777  { 0x2167, { 0x2177, 0x0000, 0x0000, 0x0000 } },
1778  { 0x2168, { 0x2178, 0x0000, 0x0000, 0x0000 } },
1779  { 0x2169, { 0x2179, 0x0000, 0x0000, 0x0000 } },
1780  { 0x216A, { 0x217A, 0x0000, 0x0000, 0x0000 } },
1781  { 0x216B, { 0x217B, 0x0000, 0x0000, 0x0000 } },
1782  { 0x216C, { 0x217C, 0x0000, 0x0000, 0x0000 } },
1783  { 0x216D, { 0x217D, 0x0000, 0x0000, 0x0000 } },
1784  { 0x216E, { 0x217E, 0x0000, 0x0000, 0x0000 } },
1785  { 0x216F, { 0x217F, 0x0000, 0x0000, 0x0000 } },
1786  { 0x24B6, { 0x24D0, 0x0000, 0x0000, 0x0000 } },
1787  { 0x24B7, { 0x24D1, 0x0000, 0x0000, 0x0000 } },
1788  { 0x24B8, { 0x24D2, 0x0000, 0x0000, 0x0000 } },
1789  { 0x24B9, { 0x24D3, 0x0000, 0x0000, 0x0000 } },
1790  { 0x24BA, { 0x24D4, 0x0000, 0x0000, 0x0000 } },
1791  { 0x24BB, { 0x24D5, 0x0000, 0x0000, 0x0000 } },
1792  { 0x24BC, { 0x24D6, 0x0000, 0x0000, 0x0000 } },
1793  { 0x24BD, { 0x24D7, 0x0000, 0x0000, 0x0000 } },
1794  { 0x24BE, { 0x24D8, 0x0000, 0x0000, 0x0000 } },
1795  { 0x24BF, { 0x24D9, 0x0000, 0x0000, 0x0000 } },
1796  { 0x24C0, { 0x24DA, 0x0000, 0x0000, 0x0000 } },
1797  { 0x24C1, { 0x24DB, 0x0000, 0x0000, 0x0000 } },
1798  { 0x24C2, { 0x24DC, 0x0000, 0x0000, 0x0000 } },
1799  { 0x24C3, { 0x24DD, 0x0000, 0x0000, 0x0000 } },
1800  { 0x24C4, { 0x24DE, 0x0000, 0x0000, 0x0000 } },
1801  { 0x24C5, { 0x24DF, 0x0000, 0x0000, 0x0000 } },
1802  { 0x24C6, { 0x24E0, 0x0000, 0x0000, 0x0000 } },
1803  { 0x24C7, { 0x24E1, 0x0000, 0x0000, 0x0000 } },
1804  { 0x24C8, { 0x24E2, 0x0000, 0x0000, 0x0000 } },
1805  { 0x24C9, { 0x24E3, 0x0000, 0x0000, 0x0000 } },
1806  { 0x24CA, { 0x24E4, 0x0000, 0x0000, 0x0000 } },
1807  { 0x24CB, { 0x24E5, 0x0000, 0x0000, 0x0000 } },
1808  { 0x24CC, { 0x24E6, 0x0000, 0x0000, 0x0000 } },
1809  { 0x24CD, { 0x24E7, 0x0000, 0x0000, 0x0000 } },
1810  { 0x24CE, { 0x24E8, 0x0000, 0x0000, 0x0000 } },
1811  { 0x24CF, { 0x24E9, 0x0000, 0x0000, 0x0000 } },
1812  { 0x3371, { 0x0068, 0x0070, 0x0061, 0x0000 } },
1813  { 0x3373, { 0x0061, 0x0075, 0x0000, 0x0000 } },
1814  { 0x3375, { 0x006F, 0x0076, 0x0000, 0x0000 } },
1815  { 0x3380, { 0x0070, 0x0061, 0x0000, 0x0000 } },
1816  { 0x3381, { 0x006E, 0x0061, 0x0000, 0x0000 } },
1817  { 0x3382, { 0x03BC, 0x0061, 0x0000, 0x0000 } },
1818  { 0x3383, { 0x006D, 0x0061, 0x0000, 0x0000 } },
1819  { 0x3384, { 0x006B, 0x0061, 0x0000, 0x0000 } },
1820  { 0x3385, { 0x006B, 0x0062, 0x0000, 0x0000 } },
1821  { 0x3386, { 0x006D, 0x0062, 0x0000, 0x0000 } },
1822  { 0x3387, { 0x0067, 0x0062, 0x0000, 0x0000 } },
1823  { 0x338A, { 0x0070, 0x0066, 0x0000, 0x0000 } },
1824  { 0x338B, { 0x006E, 0x0066, 0x0000, 0x0000 } },
1825  { 0x338C, { 0x03BC, 0x0066, 0x0000, 0x0000 } },
1826  { 0x3390, { 0x0068, 0x007A, 0x0000, 0x0000 } },
1827  { 0x3391, { 0x006B, 0x0068, 0x007A, 0x0000 } },
1828  { 0x3392, { 0x006D, 0x0068, 0x007A, 0x0000 } },
1829  { 0x3393, { 0x0067, 0x0068, 0x007A, 0x0000 } },
1830  { 0x3394, { 0x0074, 0x0068, 0x007A, 0x0000 } },
1831  { 0x33A9, { 0x0070, 0x0061, 0x0000, 0x0000 } },
1832  { 0x33AA, { 0x006B, 0x0070, 0x0061, 0x0000 } },
1833  { 0x33AB, { 0x006D, 0x0070, 0x0061, 0x0000 } },
1834  { 0x33AC, { 0x0067, 0x0070, 0x0061, 0x0000 } },
1835  { 0x33B4, { 0x0070, 0x0076, 0x0000, 0x0000 } },
1836  { 0x33B5, { 0x006E, 0x0076, 0x0000, 0x0000 } },
1837  { 0x33B6, { 0x03BC, 0x0076, 0x0000, 0x0000 } },
1838  { 0x33B7, { 0x006D, 0x0076, 0x0000, 0x0000 } },
1839  { 0x33B8, { 0x006B, 0x0076, 0x0000, 0x0000 } },
1840  { 0x33B9, { 0x006D, 0x0076, 0x0000, 0x0000 } },
1841  { 0x33BA, { 0x0070, 0x0077, 0x0000, 0x0000 } },
1842  { 0x33BB, { 0x006E, 0x0077, 0x0000, 0x0000 } },
1843  { 0x33BC, { 0x03BC, 0x0077, 0x0000, 0x0000 } },
1844  { 0x33BD, { 0x006D, 0x0077, 0x0000, 0x0000 } },
1845  { 0x33BE, { 0x006B, 0x0077, 0x0000, 0x0000 } },
1846  { 0x33BF, { 0x006D, 0x0077, 0x0000, 0x0000 } },
1847  { 0x33C0, { 0x006B, 0x03C9, 0x0000, 0x0000 } },
1848  { 0x33C1, { 0x006D, 0x03C9, 0x0000, 0x0000 } },
1849  { 0x33C3, { 0x0062, 0x0071, 0x0000, 0x0000 } },
1850  { 0x33C6, { 0x0063, 0x2215, 0x006B, 0x0067 } },
1851  { 0x33C7, { 0x0063, 0x006F, 0x002E, 0x0000 } },
1852  { 0x33C8, { 0x0064, 0x0062, 0x0000, 0x0000 } },
1853  { 0x33C9, { 0x0067, 0x0079, 0x0000, 0x0000 } },
1854  { 0x33CB, { 0x0068, 0x0070, 0x0000, 0x0000 } },
1855  { 0x33CD, { 0x006B, 0x006B, 0x0000, 0x0000 } },
1856  { 0x33CE, { 0x006B, 0x006D, 0x0000, 0x0000 } },
1857  { 0x33D7, { 0x0070, 0x0068, 0x0000, 0x0000 } },
1858  { 0x33D9, { 0x0070, 0x0070, 0x006D, 0x0000 } },
1859  { 0x33DA, { 0x0070, 0x0072, 0x0000, 0x0000 } },
1860  { 0x33DC, { 0x0073, 0x0076, 0x0000, 0x0000 } },
1861  { 0x33DD, { 0x0077, 0x0062, 0x0000, 0x0000 } },
1862  { 0xFB00, { 0x0066, 0x0066, 0x0000, 0x0000 } },
1863  { 0xFB01, { 0x0066, 0x0069, 0x0000, 0x0000 } },
1864  { 0xFB02, { 0x0066, 0x006C, 0x0000, 0x0000 } },
1865  { 0xFB03, { 0x0066, 0x0066, 0x0069, 0x0000 } },
1866  { 0xFB04, { 0x0066, 0x0066, 0x006C, 0x0000 } },
1867  { 0xFB05, { 0x0073, 0x0074, 0x0000, 0x0000 } },
1868  { 0xFB06, { 0x0073, 0x0074, 0x0000, 0x0000 } },
1869  { 0xFB13, { 0x0574, 0x0576, 0x0000, 0x0000 } },
1870  { 0xFB14, { 0x0574, 0x0565, 0x0000, 0x0000 } },
1871  { 0xFB15, { 0x0574, 0x056B, 0x0000, 0x0000 } },
1872  { 0xFB16, { 0x057E, 0x0576, 0x0000, 0x0000 } },
1873  { 0xFB17, { 0x0574, 0x056D, 0x0000, 0x0000 } },
1874  { 0xFF21, { 0xFF41, 0x0000, 0x0000, 0x0000 } },
1875  { 0xFF22, { 0xFF42, 0x0000, 0x0000, 0x0000 } },
1876  { 0xFF23, { 0xFF43, 0x0000, 0x0000, 0x0000 } },
1877  { 0xFF24, { 0xFF44, 0x0000, 0x0000, 0x0000 } },
1878  { 0xFF25, { 0xFF45, 0x0000, 0x0000, 0x0000 } },
1879  { 0xFF26, { 0xFF46, 0x0000, 0x0000, 0x0000 } },
1880  { 0xFF27, { 0xFF47, 0x0000, 0x0000, 0x0000 } },
1881  { 0xFF28, { 0xFF48, 0x0000, 0x0000, 0x0000 } },
1882  { 0xFF29, { 0xFF49, 0x0000, 0x0000, 0x0000 } },
1883  { 0xFF2A, { 0xFF4A, 0x0000, 0x0000, 0x0000 } },
1884  { 0xFF2B, { 0xFF4B, 0x0000, 0x0000, 0x0000 } },
1885  { 0xFF2C, { 0xFF4C, 0x0000, 0x0000, 0x0000 } },
1886  { 0xFF2D, { 0xFF4D, 0x0000, 0x0000, 0x0000 } },
1887  { 0xFF2E, { 0xFF4E, 0x0000, 0x0000, 0x0000 } },
1888  { 0xFF2F, { 0xFF4F, 0x0000, 0x0000, 0x0000 } },
1889  { 0xFF30, { 0xFF50, 0x0000, 0x0000, 0x0000 } },
1890  { 0xFF31, { 0xFF51, 0x0000, 0x0000, 0x0000 } },
1891  { 0xFF32, { 0xFF52, 0x0000, 0x0000, 0x0000 } },
1892  { 0xFF33, { 0xFF53, 0x0000, 0x0000, 0x0000 } },
1893  { 0xFF34, { 0xFF54, 0x0000, 0x0000, 0x0000 } },
1894  { 0xFF35, { 0xFF55, 0x0000, 0x0000, 0x0000 } },
1895  { 0xFF36, { 0xFF56, 0x0000, 0x0000, 0x0000 } },
1896  { 0xFF37, { 0xFF57, 0x0000, 0x0000, 0x0000 } },
1897  { 0xFF38, { 0xFF58, 0x0000, 0x0000, 0x0000 } },
1898  { 0xFF39, { 0xFF59, 0x0000, 0x0000, 0x0000 } },
1899  { 0xFF3A, { 0xFF5A, 0x0000, 0x0000, 0x0000 } },
1900  { 0x10400, { 0xd801, 0xdc28, 0x0000, 0x0000 } },
1901  { 0x10401, { 0xd801, 0xdc29, 0x0000, 0x0000 } },
1902  { 0x10402, { 0xd801, 0xdc2A, 0x0000, 0x0000 } },
1903  { 0x10403, { 0xd801, 0xdc2B, 0x0000, 0x0000 } },
1904  { 0x10404, { 0xd801, 0xdc2C, 0x0000, 0x0000 } },
1905  { 0x10405, { 0xd801, 0xdc2D, 0x0000, 0x0000 } },
1906  { 0x10406, { 0xd801, 0xdc2E, 0x0000, 0x0000 } },
1907  { 0x10407, { 0xd801, 0xdc2F, 0x0000, 0x0000 } },
1908  { 0x10408, { 0xd801, 0xdc30, 0x0000, 0x0000 } },
1909  { 0x10409, { 0xd801, 0xdc31, 0x0000, 0x0000 } },
1910  { 0x1040A, { 0xd801, 0xdc32, 0x0000, 0x0000 } },
1911  { 0x1040B, { 0xd801, 0xdc33, 0x0000, 0x0000 } },
1912  { 0x1040C, { 0xd801, 0xdc34, 0x0000, 0x0000 } },
1913  { 0x1040D, { 0xd801, 0xdc35, 0x0000, 0x0000 } },
1914  { 0x1040E, { 0xd801, 0xdc36, 0x0000, 0x0000 } },
1915  { 0x1040F, { 0xd801, 0xdc37, 0x0000, 0x0000 } },
1916  { 0x10410, { 0xd801, 0xdc38, 0x0000, 0x0000 } },
1917  { 0x10411, { 0xd801, 0xdc39, 0x0000, 0x0000 } },
1918  { 0x10412, { 0xd801, 0xdc3A, 0x0000, 0x0000 } },
1919  { 0x10413, { 0xd801, 0xdc3B, 0x0000, 0x0000 } },
1920  { 0x10414, { 0xd801, 0xdc3C, 0x0000, 0x0000 } },
1921  { 0x10415, { 0xd801, 0xdc3D, 0x0000, 0x0000 } },
1922  { 0x10416, { 0xd801, 0xdc3E, 0x0000, 0x0000 } },
1923  { 0x10417, { 0xd801, 0xdc3F, 0x0000, 0x0000 } },
1924  { 0x10418, { 0xd801, 0xdc40, 0x0000, 0x0000 } },
1925  { 0x10419, { 0xd801, 0xdc41, 0x0000, 0x0000 } },
1926  { 0x1041A, { 0xd801, 0xdc42, 0x0000, 0x0000 } },
1927  { 0x1041B, { 0xd801, 0xdc43, 0x0000, 0x0000 } },
1928  { 0x1041C, { 0xd801, 0xdc44, 0x0000, 0x0000 } },
1929  { 0x1041D, { 0xd801, 0xdc45, 0x0000, 0x0000 } },
1930  { 0x1041E, { 0xd801, 0xdc46, 0x0000, 0x0000 } },
1931  { 0x1041F, { 0xd801, 0xdc47, 0x0000, 0x0000 } },
1932  { 0x10420, { 0xd801, 0xdc48, 0x0000, 0x0000 } },
1933  { 0x10421, { 0xd801, 0xdc49, 0x0000, 0x0000 } },
1934  { 0x10422, { 0xd801, 0xdc4A, 0x0000, 0x0000 } },
1935  { 0x10423, { 0xd801, 0xdc4B, 0x0000, 0x0000 } },
1936  { 0x10424, { 0xd801, 0xdc4C, 0x0000, 0x0000 } },
1937  { 0x10425, { 0xd801, 0xdc4D, 0x0000, 0x0000 } },
1938  { 0x1D400, { 0x0061, 0x0000, 0x0000, 0x0000 } },
1939  { 0x1D401, { 0x0062, 0x0000, 0x0000, 0x0000 } },
1940  { 0x1D402, { 0x0063, 0x0000, 0x0000, 0x0000 } },
1941  { 0x1D403, { 0x0064, 0x0000, 0x0000, 0x0000 } },
1942  { 0x1D404, { 0x0065, 0x0000, 0x0000, 0x0000 } },
1943  { 0x1D405, { 0x0066, 0x0000, 0x0000, 0x0000 } },
1944  { 0x1D406, { 0x0067, 0x0000, 0x0000, 0x0000 } },
1945  { 0x1D407, { 0x0068, 0x0000, 0x0000, 0x0000 } },
1946  { 0x1D408, { 0x0069, 0x0000, 0x0000, 0x0000 } },
1947  { 0x1D409, { 0x006A, 0x0000, 0x0000, 0x0000 } },
1948  { 0x1D40A, { 0x006B, 0x0000, 0x0000, 0x0000 } },
1949  { 0x1D40B, { 0x006C, 0x0000, 0x0000, 0x0000 } },
1950  { 0x1D40C, { 0x006D, 0x0000, 0x0000, 0x0000 } },
1951  { 0x1D40D, { 0x006E, 0x0000, 0x0000, 0x0000 } },
1952  { 0x1D40E, { 0x006F, 0x0000, 0x0000, 0x0000 } },
1953  { 0x1D40F, { 0x0070, 0x0000, 0x0000, 0x0000 } },
1954  { 0x1D410, { 0x0071, 0x0000, 0x0000, 0x0000 } },
1955  { 0x1D411, { 0x0072, 0x0000, 0x0000, 0x0000 } },
1956  { 0x1D412, { 0x0073, 0x0000, 0x0000, 0x0000 } },
1957  { 0x1D413, { 0x0074, 0x0000, 0x0000, 0x0000 } },
1958  { 0x1D414, { 0x0075, 0x0000, 0x0000, 0x0000 } },
1959  { 0x1D415, { 0x0076, 0x0000, 0x0000, 0x0000 } },
1960  { 0x1D416, { 0x0077, 0x0000, 0x0000, 0x0000 } },
1961  { 0x1D417, { 0x0078, 0x0000, 0x0000, 0x0000 } },
1962  { 0x1D418, { 0x0079, 0x0000, 0x0000, 0x0000 } },
1963  { 0x1D419, { 0x007A, 0x0000, 0x0000, 0x0000 } },
1964  { 0x1D434, { 0x0061, 0x0000, 0x0000, 0x0000 } },
1965  { 0x1D435, { 0x0062, 0x0000, 0x0000, 0x0000 } },
1966  { 0x1D436, { 0x0063, 0x0000, 0x0000, 0x0000 } },
1967  { 0x1D437, { 0x0064, 0x0000, 0x0000, 0x0000 } },
1968  { 0x1D438, { 0x0065, 0x0000, 0x0000, 0x0000 } },
1969  { 0x1D439, { 0x0066, 0x0000, 0x0000, 0x0000 } },
1970  { 0x1D43A, { 0x0067, 0x0000, 0x0000, 0x0000 } },
1971  { 0x1D43B, { 0x0068, 0x0000, 0x0000, 0x0000 } },
1972  { 0x1D43C, { 0x0069, 0x0000, 0x0000, 0x0000 } },
1973  { 0x1D43D, { 0x006A, 0x0000, 0x0000, 0x0000 } },
1974  { 0x1D43E, { 0x006B, 0x0000, 0x0000, 0x0000 } },
1975  { 0x1D43F, { 0x006C, 0x0000, 0x0000, 0x0000 } },
1976  { 0x1D440, { 0x006D, 0x0000, 0x0000, 0x0000 } },
1977  { 0x1D441, { 0x006E, 0x0000, 0x0000, 0x0000 } },
1978  { 0x1D442, { 0x006F, 0x0000, 0x0000, 0x0000 } },
1979  { 0x1D443, { 0x0070, 0x0000, 0x0000, 0x0000 } },
1980  { 0x1D444, { 0x0071, 0x0000, 0x0000, 0x0000 } },
1981  { 0x1D445, { 0x0072, 0x0000, 0x0000, 0x0000 } },
1982  { 0x1D446, { 0x0073, 0x0000, 0x0000, 0x0000 } },
1983  { 0x1D447, { 0x0074, 0x0000, 0x0000, 0x0000 } },
1984  { 0x1D448, { 0x0075, 0x0000, 0x0000, 0x0000 } },
1985  { 0x1D449, { 0x0076, 0x0000, 0x0000, 0x0000 } },
1986  { 0x1D44A, { 0x0077, 0x0000, 0x0000, 0x0000 } },
1987  { 0x1D44B, { 0x0078, 0x0000, 0x0000, 0x0000 } },
1988  { 0x1D44C, { 0x0079, 0x0000, 0x0000, 0x0000 } },
1989  { 0x1D44D, { 0x007A, 0x0000, 0x0000, 0x0000 } },
1990  { 0x1D468, { 0x0061, 0x0000, 0x0000, 0x0000 } },
1991  { 0x1D469, { 0x0062, 0x0000, 0x0000, 0x0000 } },
1992  { 0x1D46A, { 0x0063, 0x0000, 0x0000, 0x0000 } },
1993  { 0x1D46B, { 0x0064, 0x0000, 0x0000, 0x0000 } },
1994  { 0x1D46C, { 0x0065, 0x0000, 0x0000, 0x0000 } },
1995  { 0x1D46D, { 0x0066, 0x0000, 0x0000, 0x0000 } },
1996  { 0x1D46E, { 0x0067, 0x0000, 0x0000, 0x0000 } },
1997  { 0x1D46F, { 0x0068, 0x0000, 0x0000, 0x0000 } },
1998  { 0x1D470, { 0x0069, 0x0000, 0x0000, 0x0000 } },
1999  { 0x1D471, { 0x006A, 0x0000, 0x0000, 0x0000 } },
2000  { 0x1D472, { 0x006B, 0x0000, 0x0000, 0x0000 } },
2001  { 0x1D473, { 0x006C, 0x0000, 0x0000, 0x0000 } },
2002  { 0x1D474, { 0x006D, 0x0000, 0x0000, 0x0000 } },
2003  { 0x1D475, { 0x006E, 0x0000, 0x0000, 0x0000 } },
2004  { 0x1D476, { 0x006F, 0x0000, 0x0000, 0x0000 } },
2005  { 0x1D477, { 0x0070, 0x0000, 0x0000, 0x0000 } },
2006  { 0x1D478, { 0x0071, 0x0000, 0x0000, 0x0000 } },
2007  { 0x1D479, { 0x0072, 0x0000, 0x0000, 0x0000 } },
2008  { 0x1D47A, { 0x0073, 0x0000, 0x0000, 0x0000 } },
2009  { 0x1D47B, { 0x0074, 0x0000, 0x0000, 0x0000 } },
2010  { 0x1D47C, { 0x0075, 0x0000, 0x0000, 0x0000 } },
2011  { 0x1D47D, { 0x0076, 0x0000, 0x0000, 0x0000 } },
2012  { 0x1D47E, { 0x0077, 0x0000, 0x0000, 0x0000 } },
2013  { 0x1D47F, { 0x0078, 0x0000, 0x0000, 0x0000 } },
2014  { 0x1D480, { 0x0079, 0x0000, 0x0000, 0x0000 } },
2015  { 0x1D481, { 0x007A, 0x0000, 0x0000, 0x0000 } },
2016  { 0x1D49C, { 0x0061, 0x0000, 0x0000, 0x0000 } },
2017  { 0x1D49E, { 0x0063, 0x0000, 0x0000, 0x0000 } },
2018  { 0x1D49F, { 0x0064, 0x0000, 0x0000, 0x0000 } },
2019  { 0x1D4A2, { 0x0067, 0x0000, 0x0000, 0x0000 } },
2020  { 0x1D4A5, { 0x006A, 0x0000, 0x0000, 0x0000 } },
2021  { 0x1D4A6, { 0x006B, 0x0000, 0x0000, 0x0000 } },
2022  { 0x1D4A9, { 0x006E, 0x0000, 0x0000, 0x0000 } },
2023  { 0x1D4AA, { 0x006F, 0x0000, 0x0000, 0x0000 } },
2024  { 0x1D4AB, { 0x0070, 0x0000, 0x0000, 0x0000 } },
2025  { 0x1D4AC, { 0x0071, 0x0000, 0x0000, 0x0000 } },
2026  { 0x1D4AE, { 0x0073, 0x0000, 0x0000, 0x0000 } },
2027  { 0x1D4AF, { 0x0074, 0x0000, 0x0000, 0x0000 } },
2028  { 0x1D4B0, { 0x0075, 0x0000, 0x0000, 0x0000 } },
2029  { 0x1D4B1, { 0x0076, 0x0000, 0x0000, 0x0000 } },
2030  { 0x1D4B2, { 0x0077, 0x0000, 0x0000, 0x0000 } },
2031  { 0x1D4B3, { 0x0078, 0x0000, 0x0000, 0x0000 } },
2032  { 0x1D4B4, { 0x0079, 0x0000, 0x0000, 0x0000 } },
2033  { 0x1D4B5, { 0x007A, 0x0000, 0x0000, 0x0000 } },
2034  { 0x1D4D0, { 0x0061, 0x0000, 0x0000, 0x0000 } },
2035  { 0x1D4D1, { 0x0062, 0x0000, 0x0000, 0x0000 } },
2036  { 0x1D4D2, { 0x0063, 0x0000, 0x0000, 0x0000 } },
2037  { 0x1D4D3, { 0x0064, 0x0000, 0x0000, 0x0000 } },
2038  { 0x1D4D4, { 0x0065, 0x0000, 0x0000, 0x0000 } },
2039  { 0x1D4D5, { 0x0066, 0x0000, 0x0000, 0x0000 } },
2040  { 0x1D4D6, { 0x0067, 0x0000, 0x0000, 0x0000 } },
2041  { 0x1D4D7, { 0x0068, 0x0000, 0x0000, 0x0000 } },
2042  { 0x1D4D8, { 0x0069, 0x0000, 0x0000, 0x0000 } },
2043  { 0x1D4D9, { 0x006A, 0x0000, 0x0000, 0x0000 } },
2044  { 0x1D4DA, { 0x006B, 0x0000, 0x0000, 0x0000 } },
2045  { 0x1D4DB, { 0x006C, 0x0000, 0x0000, 0x0000 } },
2046  { 0x1D4DC, { 0x006D, 0x0000, 0x0000, 0x0000 } },
2047  { 0x1D4DD, { 0x006E, 0x0000, 0x0000, 0x0000 } },
2048  { 0x1D4DE, { 0x006F, 0x0000, 0x0000, 0x0000 } },
2049  { 0x1D4DF, { 0x0070, 0x0000, 0x0000, 0x0000 } },
2050  { 0x1D4E0, { 0x0071, 0x0000, 0x0000, 0x0000 } },
2051  { 0x1D4E1, { 0x0072, 0x0000, 0x0000, 0x0000 } },
2052  { 0x1D4E2, { 0x0073, 0x0000, 0x0000, 0x0000 } },
2053  { 0x1D4E3, { 0x0074, 0x0000, 0x0000, 0x0000 } },
2054  { 0x1D4E4, { 0x0075, 0x0000, 0x0000, 0x0000 } },
2055  { 0x1D4E5, { 0x0076, 0x0000, 0x0000, 0x0000 } },
2056  { 0x1D4E6, { 0x0077, 0x0000, 0x0000, 0x0000 } },
2057  { 0x1D4E7, { 0x0078, 0x0000, 0x0000, 0x0000 } },
2058  { 0x1D4E8, { 0x0079, 0x0000, 0x0000, 0x0000 } },
2059  { 0x1D4E9, { 0x007A, 0x0000, 0x0000, 0x0000 } },
2060  { 0x1D504, { 0x0061, 0x0000, 0x0000, 0x0000 } },
2061  { 0x1D505, { 0x0062, 0x0000, 0x0000, 0x0000 } },
2062  { 0x1D507, { 0x0064, 0x0000, 0x0000, 0x0000 } },
2063  { 0x1D508, { 0x0065, 0x0000, 0x0000, 0x0000 } },
2064  { 0x1D509, { 0x0066, 0x0000, 0x0000, 0x0000 } },
2065  { 0x1D50A, { 0x0067, 0x0000, 0x0000, 0x0000 } },
2066  { 0x1D50D, { 0x006A, 0x0000, 0x0000, 0x0000 } },
2067  { 0x1D50E, { 0x006B, 0x0000, 0x0000, 0x0000 } },
2068  { 0x1D50F, { 0x006C, 0x0000, 0x0000, 0x0000 } },
2069  { 0x1D510, { 0x006D, 0x0000, 0x0000, 0x0000 } },
2070  { 0x1D511, { 0x006E, 0x0000, 0x0000, 0x0000 } },
2071  { 0x1D512, { 0x006F, 0x0000, 0x0000, 0x0000 } },
2072  { 0x1D513, { 0x0070, 0x0000, 0x0000, 0x0000 } },
2073  { 0x1D514, { 0x0071, 0x0000, 0x0000, 0x0000 } },
2074  { 0x1D516, { 0x0073, 0x0000, 0x0000, 0x0000 } },
2075  { 0x1D517, { 0x0074, 0x0000, 0x0000, 0x0000 } },
2076  { 0x1D518, { 0x0075, 0x0000, 0x0000, 0x0000 } },
2077  { 0x1D519, { 0x0076, 0x0000, 0x0000, 0x0000 } },
2078  { 0x1D51A, { 0x0077, 0x0000, 0x0000, 0x0000 } },
2079  { 0x1D51B, { 0x0078, 0x0000, 0x0000, 0x0000 } },
2080  { 0x1D51C, { 0x0079, 0x0000, 0x0000, 0x0000 } },
2081  { 0x1D538, { 0x0061, 0x0000, 0x0000, 0x0000 } },
2082  { 0x1D539, { 0x0062, 0x0000, 0x0000, 0x0000 } },
2083  { 0x1D53B, { 0x0064, 0x0000, 0x0000, 0x0000 } },
2084  { 0x1D53C, { 0x0065, 0x0000, 0x0000, 0x0000 } },
2085  { 0x1D53D, { 0x0066, 0x0000, 0x0000, 0x0000 } },
2086  { 0x1D53E, { 0x0067, 0x0000, 0x0000, 0x0000 } },
2087  { 0x1D540, { 0x0069, 0x0000, 0x0000, 0x0000 } },
2088  { 0x1D541, { 0x006A, 0x0000, 0x0000, 0x0000 } },
2089  { 0x1D542, { 0x006B, 0x0000, 0x0000, 0x0000 } },
2090  { 0x1D543, { 0x006C, 0x0000, 0x0000, 0x0000 } },
2091  { 0x1D544, { 0x006D, 0x0000, 0x0000, 0x0000 } },
2092  { 0x1D546, { 0x006F, 0x0000, 0x0000, 0x0000 } },
2093  { 0x1D54A, { 0x0073, 0x0000, 0x0000, 0x0000 } },
2094  { 0x1D54B, { 0x0074, 0x0000, 0x0000, 0x0000 } },
2095  { 0x1D54C, { 0x0075, 0x0000, 0x0000, 0x0000 } },
2096  { 0x1D54D, { 0x0076, 0x0000, 0x0000, 0x0000 } },
2097  { 0x1D54E, { 0x0077, 0x0000, 0x0000, 0x0000 } },
2098  { 0x1D54F, { 0x0078, 0x0000, 0x0000, 0x0000 } },
2099  { 0x1D550, { 0x0079, 0x0000, 0x0000, 0x0000 } },
2100  { 0x1D56C, { 0x0061, 0x0000, 0x0000, 0x0000 } },
2101  { 0x1D56D, { 0x0062, 0x0000, 0x0000, 0x0000 } },
2102  { 0x1D56E, { 0x0063, 0x0000, 0x0000, 0x0000 } },
2103  { 0x1D56F, { 0x0064, 0x0000, 0x0000, 0x0000 } },
2104  { 0x1D570, { 0x0065, 0x0000, 0x0000, 0x0000 } },
2105  { 0x1D571, { 0x0066, 0x0000, 0x0000, 0x0000 } },
2106  { 0x1D572, { 0x0067, 0x0000, 0x0000, 0x0000 } },
2107  { 0x1D573, { 0x0068, 0x0000, 0x0000, 0x0000 } },
2108  { 0x1D574, { 0x0069, 0x0000, 0x0000, 0x0000 } },
2109  { 0x1D575, { 0x006A, 0x0000, 0x0000, 0x0000 } },
2110  { 0x1D576, { 0x006B, 0x0000, 0x0000, 0x0000 } },
2111  { 0x1D577, { 0x006C, 0x0000, 0x0000, 0x0000 } },
2112  { 0x1D578, { 0x006D, 0x0000, 0x0000, 0x0000 } },
2113  { 0x1D579, { 0x006E, 0x0000, 0x0000, 0x0000 } },
2114  { 0x1D57A, { 0x006F, 0x0000, 0x0000, 0x0000 } },
2115  { 0x1D57B, { 0x0070, 0x0000, 0x0000, 0x0000 } },
2116  { 0x1D57C, { 0x0071, 0x0000, 0x0000, 0x0000 } },
2117  { 0x1D57D, { 0x0072, 0x0000, 0x0000, 0x0000 } },
2118  { 0x1D57E, { 0x0073, 0x0000, 0x0000, 0x0000 } },
2119  { 0x1D57F, { 0x0074, 0x0000, 0x0000, 0x0000 } },
2120  { 0x1D580, { 0x0075, 0x0000, 0x0000, 0x0000 } },
2121  { 0x1D581, { 0x0076, 0x0000, 0x0000, 0x0000 } },
2122  { 0x1D582, { 0x0077, 0x0000, 0x0000, 0x0000 } },
2123  { 0x1D583, { 0x0078, 0x0000, 0x0000, 0x0000 } },
2124  { 0x1D584, { 0x0079, 0x0000, 0x0000, 0x0000 } },
2125  { 0x1D585, { 0x007A, 0x0000, 0x0000, 0x0000 } },
2126  { 0x1D5A0, { 0x0061, 0x0000, 0x0000, 0x0000 } },
2127  { 0x1D5A1, { 0x0062, 0x0000, 0x0000, 0x0000 } },
2128  { 0x1D5A2, { 0x0063, 0x0000, 0x0000, 0x0000 } },
2129  { 0x1D5A3, { 0x0064, 0x0000, 0x0000, 0x0000 } },
2130  { 0x1D5A4, { 0x0065, 0x0000, 0x0000, 0x0000 } },
2131  { 0x1D5A5, { 0x0066, 0x0000, 0x0000, 0x0000 } },
2132  { 0x1D5A6, { 0x0067, 0x0000, 0x0000, 0x0000 } },
2133  { 0x1D5A7, { 0x0068, 0x0000, 0x0000, 0x0000 } },
2134  { 0x1D5A8, { 0x0069, 0x0000, 0x0000, 0x0000 } },
2135  { 0x1D5A9, { 0x006A, 0x0000, 0x0000, 0x0000 } },
2136  { 0x1D5AA, { 0x006B, 0x0000, 0x0000, 0x0000 } },
2137  { 0x1D5AB, { 0x006C, 0x0000, 0x0000, 0x0000 } },
2138  { 0x1D5AC, { 0x006D, 0x0000, 0x0000, 0x0000 } },
2139  { 0x1D5AD, { 0x006E, 0x0000, 0x0000, 0x0000 } },
2140  { 0x1D5AE, { 0x006F, 0x0000, 0x0000, 0x0000 } },
2141  { 0x1D5AF, { 0x0070, 0x0000, 0x0000, 0x0000 } },
2142  { 0x1D5B0, { 0x0071, 0x0000, 0x0000, 0x0000 } },
2143  { 0x1D5B1, { 0x0072, 0x0000, 0x0000, 0x0000 } },
2144  { 0x1D5B2, { 0x0073, 0x0000, 0x0000, 0x0000 } },
2145  { 0x1D5B3, { 0x0074, 0x0000, 0x0000, 0x0000 } },
2146  { 0x1D5B4, { 0x0075, 0x0000, 0x0000, 0x0000 } },
2147  { 0x1D5B5, { 0x0076, 0x0000, 0x0000, 0x0000 } },
2148  { 0x1D5B6, { 0x0077, 0x0000, 0x0000, 0x0000 } },
2149  { 0x1D5B7, { 0x0078, 0x0000, 0x0000, 0x0000 } },
2150  { 0x1D5B8, { 0x0079, 0x0000, 0x0000, 0x0000 } },
2151  { 0x1D5B9, { 0x007A, 0x0000, 0x0000, 0x0000 } },
2152  { 0x1D5D4, { 0x0061, 0x0000, 0x0000, 0x0000 } },
2153  { 0x1D5D5, { 0x0062, 0x0000, 0x0000, 0x0000 } },
2154  { 0x1D5D6, { 0x0063, 0x0000, 0x0000, 0x0000 } },
2155  { 0x1D5D7, { 0x0064, 0x0000, 0x0000, 0x0000 } },
2156  { 0x1D5D8, { 0x0065, 0x0000, 0x0000, 0x0000 } },
2157  { 0x1D5D9, { 0x0066, 0x0000, 0x0000, 0x0000 } },
2158  { 0x1D5DA, { 0x0067, 0x0000, 0x0000, 0x0000 } },
2159  { 0x1D5DB, { 0x0068, 0x0000, 0x0000, 0x0000 } },
2160  { 0x1D5DC, { 0x0069, 0x0000, 0x0000, 0x0000 } },
2161  { 0x1D5DD, { 0x006A, 0x0000, 0x0000, 0x0000 } },
2162  { 0x1D5DE, { 0x006B, 0x0000, 0x0000, 0x0000 } },
2163  { 0x1D5DF, { 0x006C, 0x0000, 0x0000, 0x0000 } },
2164  { 0x1D5E0, { 0x006D, 0x0000, 0x0000, 0x0000 } },
2165  { 0x1D5E1, { 0x006E, 0x0000, 0x0000, 0x0000 } },
2166  { 0x1D5E2, { 0x006F, 0x0000, 0x0000, 0x0000 } },
2167  { 0x1D5E3, { 0x0070, 0x0000, 0x0000, 0x0000 } },
2168  { 0x1D5E4, { 0x0071, 0x0000, 0x0000, 0x0000 } },
2169  { 0x1D5E5, { 0x0072, 0x0000, 0x0000, 0x0000 } },
2170  { 0x1D5E6, { 0x0073, 0x0000, 0x0000, 0x0000 } },
2171  { 0x1D5E7, { 0x0074, 0x0000, 0x0000, 0x0000 } },
2172  { 0x1D5E8, { 0x0075, 0x0000, 0x0000, 0x0000 } },
2173  { 0x1D5E9, { 0x0076, 0x0000, 0x0000, 0x0000 } },
2174  { 0x1D5EA, { 0x0077, 0x0000, 0x0000, 0x0000 } },
2175  { 0x1D5EB, { 0x0078, 0x0000, 0x0000, 0x0000 } },
2176  { 0x1D5EC, { 0x0079, 0x0000, 0x0000, 0x0000 } },
2177  { 0x1D5ED, { 0x007A, 0x0000, 0x0000, 0x0000 } },
2178  { 0x1D608, { 0x0061, 0x0000, 0x0000, 0x0000 } },
2179  { 0x1D609, { 0x0062, 0x0000, 0x0000, 0x0000 } },
2180  { 0x1D60A, { 0x0063, 0x0000, 0x0000, 0x0000 } },
2181  { 0x1D60B, { 0x0064, 0x0000, 0x0000, 0x0000 } },
2182  { 0x1D60C, { 0x0065, 0x0000, 0x0000, 0x0000 } },
2183  { 0x1D60D, { 0x0066, 0x0000, 0x0000, 0x0000 } },
2184  { 0x1D60E, { 0x0067, 0x0000, 0x0000, 0x0000 } },
2185  { 0x1D60F, { 0x0068, 0x0000, 0x0000, 0x0000 } },
2186  { 0x1D610, { 0x0069, 0x0000, 0x0000, 0x0000 } },
2187  { 0x1D611, { 0x006A, 0x0000, 0x0000, 0x0000 } },
2188  { 0x1D612, { 0x006B, 0x0000, 0x0000, 0x0000 } },
2189  { 0x1D613, { 0x006C, 0x0000, 0x0000, 0x0000 } },
2190  { 0x1D614, { 0x006D, 0x0000, 0x0000, 0x0000 } },
2191  { 0x1D615, { 0x006E, 0x0000, 0x0000, 0x0000 } },
2192  { 0x1D616, { 0x006F, 0x0000, 0x0000, 0x0000 } },
2193  { 0x1D617, { 0x0070, 0x0000, 0x0000, 0x0000 } },
2194  { 0x1D618, { 0x0071, 0x0000, 0x0000, 0x0000 } },
2195  { 0x1D619, { 0x0072, 0x0000, 0x0000, 0x0000 } },
2196  { 0x1D61A, { 0x0073, 0x0000, 0x0000, 0x0000 } },
2197  { 0x1D61B, { 0x0074, 0x0000, 0x0000, 0x0000 } },
2198  { 0x1D61C, { 0x0075, 0x0000, 0x0000, 0x0000 } },
2199  { 0x1D61D, { 0x0076, 0x0000, 0x0000, 0x0000 } },
2200  { 0x1D61E, { 0x0077, 0x0000, 0x0000, 0x0000 } },
2201  { 0x1D61F, { 0x0078, 0x0000, 0x0000, 0x0000 } },
2202  { 0x1D620, { 0x0079, 0x0000, 0x0000, 0x0000 } },
2203  { 0x1D621, { 0x007A, 0x0000, 0x0000, 0x0000 } },
2204  { 0x1D63C, { 0x0061, 0x0000, 0x0000, 0x0000 } },
2205  { 0x1D63D, { 0x0062, 0x0000, 0x0000, 0x0000 } },
2206  { 0x1D63E, { 0x0063, 0x0000, 0x0000, 0x0000 } },
2207  { 0x1D63F, { 0x0064, 0x0000, 0x0000, 0x0000 } },
2208  { 0x1D640, { 0x0065, 0x0000, 0x0000, 0x0000 } },
2209  { 0x1D641, { 0x0066, 0x0000, 0x0000, 0x0000 } },
2210  { 0x1D642, { 0x0067, 0x0000, 0x0000, 0x0000 } },
2211  { 0x1D643, { 0x0068, 0x0000, 0x0000, 0x0000 } },
2212  { 0x1D644, { 0x0069, 0x0000, 0x0000, 0x0000 } },
2213  { 0x1D645, { 0x006A, 0x0000, 0x0000, 0x0000 } },
2214  { 0x1D646, { 0x006B, 0x0000, 0x0000, 0x0000 } },
2215  { 0x1D647, { 0x006C, 0x0000, 0x0000, 0x0000 } },
2216  { 0x1D648, { 0x006D, 0x0000, 0x0000, 0x0000 } },
2217  { 0x1D649, { 0x006E, 0x0000, 0x0000, 0x0000 } },
2218  { 0x1D64A, { 0x006F, 0x0000, 0x0000, 0x0000 } },
2219  { 0x1D64B, { 0x0070, 0x0000, 0x0000, 0x0000 } },
2220  { 0x1D64C, { 0x0071, 0x0000, 0x0000, 0x0000 } },
2221  { 0x1D64D, { 0x0072, 0x0000, 0x0000, 0x0000 } },
2222  { 0x1D64E, { 0x0073, 0x0000, 0x0000, 0x0000 } },
2223  { 0x1D64F, { 0x0074, 0x0000, 0x0000, 0x0000 } },
2224  { 0x1D650, { 0x0075, 0x0000, 0x0000, 0x0000 } },
2225  { 0x1D651, { 0x0076, 0x0000, 0x0000, 0x0000 } },
2226  { 0x1D652, { 0x0077, 0x0000, 0x0000, 0x0000 } },
2227  { 0x1D653, { 0x0078, 0x0000, 0x0000, 0x0000 } },
2228  { 0x1D654, { 0x0079, 0x0000, 0x0000, 0x0000 } },
2229  { 0x1D655, { 0x007A, 0x0000, 0x0000, 0x0000 } },
2230  { 0x1D670, { 0x0061, 0x0000, 0x0000, 0x0000 } },
2231  { 0x1D671, { 0x0062, 0x0000, 0x0000, 0x0000 } },
2232  { 0x1D672, { 0x0063, 0x0000, 0x0000, 0x0000 } },
2233  { 0x1D673, { 0x0064, 0x0000, 0x0000, 0x0000 } },
2234  { 0x1D674, { 0x0065, 0x0000, 0x0000, 0x0000 } },
2235  { 0x1D675, { 0x0066, 0x0000, 0x0000, 0x0000 } },
2236  { 0x1D676, { 0x0067, 0x0000, 0x0000, 0x0000 } },
2237  { 0x1D677, { 0x0068, 0x0000, 0x0000, 0x0000 } },
2238  { 0x1D678, { 0x0069, 0x0000, 0x0000, 0x0000 } },
2239  { 0x1D679, { 0x006A, 0x0000, 0x0000, 0x0000 } },
2240  { 0x1D67A, { 0x006B, 0x0000, 0x0000, 0x0000 } },
2241  { 0x1D67B, { 0x006C, 0x0000, 0x0000, 0x0000 } },
2242  { 0x1D67C, { 0x006D, 0x0000, 0x0000, 0x0000 } },
2243  { 0x1D67D, { 0x006E, 0x0000, 0x0000, 0x0000 } },
2244  { 0x1D67E, { 0x006F, 0x0000, 0x0000, 0x0000 } },
2245  { 0x1D67F, { 0x0070, 0x0000, 0x0000, 0x0000 } },
2246  { 0x1D680, { 0x0071, 0x0000, 0x0000, 0x0000 } },
2247  { 0x1D681, { 0x0072, 0x0000, 0x0000, 0x0000 } },
2248  { 0x1D682, { 0x0073, 0x0000, 0x0000, 0x0000 } },
2249  { 0x1D683, { 0x0074, 0x0000, 0x0000, 0x0000 } },
2250  { 0x1D684, { 0x0075, 0x0000, 0x0000, 0x0000 } },
2251  { 0x1D685, { 0x0076, 0x0000, 0x0000, 0x0000 } },
2252  { 0x1D686, { 0x0077, 0x0000, 0x0000, 0x0000 } },
2253  { 0x1D687, { 0x0078, 0x0000, 0x0000, 0x0000 } },
2254  { 0x1D688, { 0x0079, 0x0000, 0x0000, 0x0000 } },
2255  { 0x1D689, { 0x007A, 0x0000, 0x0000, 0x0000 } },
2256  { 0x1D6A8, { 0x03B1, 0x0000, 0x0000, 0x0000 } },
2257  { 0x1D6A9, { 0x03B2, 0x0000, 0x0000, 0x0000 } },
2258  { 0x1D6AA, { 0x03B3, 0x0000, 0x0000, 0x0000 } },
2259  { 0x1D6AB, { 0x03B4, 0x0000, 0x0000, 0x0000 } },
2260  { 0x1D6AC, { 0x03B5, 0x0000, 0x0000, 0x0000 } },
2261  { 0x1D6AD, { 0x03B6, 0x0000, 0x0000, 0x0000 } },
2262  { 0x1D6AE, { 0x03B7, 0x0000, 0x0000, 0x0000 } },
2263  { 0x1D6AF, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
2264  { 0x1D6B0, { 0x03B9, 0x0000, 0x0000, 0x0000 } },
2265  { 0x1D6B1, { 0x03BA, 0x0000, 0x0000, 0x0000 } },
2266  { 0x1D6B2, { 0x03BB, 0x0000, 0x0000, 0x0000 } },
2267  { 0x1D6B3, { 0x03BC, 0x0000, 0x0000, 0x0000 } },
2268  { 0x1D6B4, { 0x03BD, 0x0000, 0x0000, 0x0000 } },
2269  { 0x1D6B5, { 0x03BE, 0x0000, 0x0000, 0x0000 } },
2270  { 0x1D6B6, { 0x03BF, 0x0000, 0x0000, 0x0000 } },
2271  { 0x1D6B7, { 0x03C0, 0x0000, 0x0000, 0x0000 } },
2272  { 0x1D6B8, { 0x03C1, 0x0000, 0x0000, 0x0000 } },
2273  { 0x1D6B9, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
2274  { 0x1D6BA, { 0x03C3, 0x0000, 0x0000, 0x0000 } },
2275  { 0x1D6BB, { 0x03C4, 0x0000, 0x0000, 0x0000 } },
2276  { 0x1D6BC, { 0x03C5, 0x0000, 0x0000, 0x0000 } },
2277  { 0x1D6BD, { 0x03C6, 0x0000, 0x0000, 0x0000 } },
2278  { 0x1D6BE, { 0x03C7, 0x0000, 0x0000, 0x0000 } },
2279  { 0x1D6BF, { 0x03C8, 0x0000, 0x0000, 0x0000 } },
2280  { 0x1D6C0, { 0x03C9, 0x0000, 0x0000, 0x0000 } },
2281  { 0x1D6D3, { 0x03C3, 0x0000, 0x0000, 0x0000 } },
2282  { 0x1D6E2, { 0x03B1, 0x0000, 0x0000, 0x0000 } },
2283  { 0x1D6E3, { 0x03B2, 0x0000, 0x0000, 0x0000 } },
2284  { 0x1D6E4, { 0x03B3, 0x0000, 0x0000, 0x0000 } },
2285  { 0x1D6E5, { 0x03B4, 0x0000, 0x0000, 0x0000 } },
2286  { 0x1D6E6, { 0x03B5, 0x0000, 0x0000, 0x0000 } },
2287  { 0x1D6E7, { 0x03B6, 0x0000, 0x0000, 0x0000 } },
2288  { 0x1D6E8, { 0x03B7, 0x0000, 0x0000, 0x0000 } },
2289  { 0x1D6E9, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
2290  { 0x1D6EA, { 0x03B9, 0x0000, 0x0000, 0x0000 } },
2291  { 0x1D6EB, { 0x03BA, 0x0000, 0x0000, 0x0000 } },
2292  { 0x1D6EC, { 0x03BB, 0x0000, 0x0000, 0x0000 } },
2293  { 0x1D6ED, { 0x03BC, 0x0000, 0x0000, 0x0000 } },
2294  { 0x1D6EE, { 0x03BD, 0x0000, 0x0000, 0x0000 } },
2295  { 0x1D6EF, { 0x03BE, 0x0000, 0x0000, 0x0000 } },
2296  { 0x1D6F0, { 0x03BF, 0x0000, 0x0000, 0x0000 } },
2297  { 0x1D6F1, { 0x03C0, 0x0000, 0x0000, 0x0000 } },
2298  { 0x1D6F2, { 0x03C1, 0x0000, 0x0000, 0x0000 } },
2299  { 0x1D6F3, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
2300  { 0x1D6F4, { 0x03C3, 0x0000, 0x0000, 0x0000 } },
2301  { 0x1D6F5, { 0x03C4, 0x0000, 0x0000, 0x0000 } },
2302  { 0x1D6F6, { 0x03C5, 0x0000, 0x0000, 0x0000 } },
2303  { 0x1D6F7, { 0x03C6, 0x0000, 0x0000, 0x0000 } },
2304  { 0x1D6F8, { 0x03C7, 0x0000, 0x0000, 0x0000 } },
2305  { 0x1D6F9, { 0x03C8, 0x0000, 0x0000, 0x0000 } },
2306  { 0x1D6FA, { 0x03C9, 0x0000, 0x0000, 0x0000 } },
2307  { 0x1D70D, { 0x03C3, 0x0000, 0x0000, 0x0000 } },
2308  { 0x1D71C, { 0x03B1, 0x0000, 0x0000, 0x0000 } },
2309  { 0x1D71D, { 0x03B2, 0x0000, 0x0000, 0x0000 } },
2310  { 0x1D71E, { 0x03B3, 0x0000, 0x0000, 0x0000 } },
2311  { 0x1D71F, { 0x03B4, 0x0000, 0x0000, 0x0000 } },
2312  { 0x1D720, { 0x03B5, 0x0000, 0x0000, 0x0000 } },
2313  { 0x1D721, { 0x03B6, 0x0000, 0x0000, 0x0000 } },
2314  { 0x1D722, { 0x03B7, 0x0000, 0x0000, 0x0000 } },
2315  { 0x1D723, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
2316  { 0x1D724, { 0x03B9, 0x0000, 0x0000, 0x0000 } },
2317  { 0x1D725, { 0x03BA, 0x0000, 0x0000, 0x0000 } },
2318  { 0x1D726, { 0x03BB, 0x0000, 0x0000, 0x0000 } },
2319  { 0x1D727, { 0x03BC, 0x0000, 0x0000, 0x0000 } },
2320  { 0x1D728, { 0x03BD, 0x0000, 0x0000, 0x0000 } },
2321  { 0x1D729, { 0x03BE, 0x0000, 0x0000, 0x0000 } },
2322  { 0x1D72A, { 0x03BF, 0x0000, 0x0000, 0x0000 } },
2323  { 0x1D72B, { 0x03C0, 0x0000, 0x0000, 0x0000 } },
2324  { 0x1D72C, { 0x03C1, 0x0000, 0x0000, 0x0000 } },
2325  { 0x1D72D, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
2326  { 0x1D72E, { 0x03C3, 0x0000, 0x0000, 0x0000 } },
2327  { 0x1D72F, { 0x03C4, 0x0000, 0x0000, 0x0000 } },
2328  { 0x1D730, { 0x03C5, 0x0000, 0x0000, 0x0000 } },
2329  { 0x1D731, { 0x03C6, 0x0000, 0x0000, 0x0000 } },
2330  { 0x1D732, { 0x03C7, 0x0000, 0x0000, 0x0000 } },
2331  { 0x1D733, { 0x03C8, 0x0000, 0x0000, 0x0000 } },
2332  { 0x1D734, { 0x03C9, 0x0000, 0x0000, 0x0000 } },
2333  { 0x1D747, { 0x03C3, 0x0000, 0x0000, 0x0000 } },
2334  { 0x1D756, { 0x03B1, 0x0000, 0x0000, 0x0000 } },
2335  { 0x1D757, { 0x03B2, 0x0000, 0x0000, 0x0000 } },
2336  { 0x1D758, { 0x03B3, 0x0000, 0x0000, 0x0000 } },
2337  { 0x1D759, { 0x03B4, 0x0000, 0x0000, 0x0000 } },
2338  { 0x1D75A, { 0x03B5, 0x0000, 0x0000, 0x0000 } },
2339  { 0x1D75B, { 0x03B6, 0x0000, 0x0000, 0x0000 } },
2340  { 0x1D75C, { 0x03B7, 0x0000, 0x0000, 0x0000 } },
2341  { 0x1D75D, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
2342  { 0x1D75E, { 0x03B9, 0x0000, 0x0000, 0x0000 } },
2343  { 0x1D75F, { 0x03BA, 0x0000, 0x0000, 0x0000 } },
2344  { 0x1D760, { 0x03BB, 0x0000, 0x0000, 0x0000 } },
2345  { 0x1D761, { 0x03BC, 0x0000, 0x0000, 0x0000 } },
2346  { 0x1D762, { 0x03BD, 0x0000, 0x0000, 0x0000 } },
2347  { 0x1D763, { 0x03BE, 0x0000, 0x0000, 0x0000 } },
2348  { 0x1D764, { 0x03BF, 0x0000, 0x0000, 0x0000 } },
2349  { 0x1D765, { 0x03C0, 0x0000, 0x0000, 0x0000 } },
2350  { 0x1D766, { 0x03C1, 0x0000, 0x0000, 0x0000 } },
2351  { 0x1D767, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
2352  { 0x1D768, { 0x03C3, 0x0000, 0x0000, 0x0000 } },
2353  { 0x1D769, { 0x03C4, 0x0000, 0x0000, 0x0000 } },
2354  { 0x1D76A, { 0x03C5, 0x0000, 0x0000, 0x0000 } },
2355  { 0x1D76B, { 0x03C6, 0x0000, 0x0000, 0x0000 } },
2356  { 0x1D76C, { 0x03C7, 0x0000, 0x0000, 0x0000 } },
2357  { 0x1D76D, { 0x03C8, 0x0000, 0x0000, 0x0000 } },
2358  { 0x1D76E, { 0x03C9, 0x0000, 0x0000, 0x0000 } },
2359  { 0x1D781, { 0x03C3, 0x0000, 0x0000, 0x0000 } },
2360  { 0x1D790, { 0x03B1, 0x0000, 0x0000, 0x0000 } },
2361  { 0x1D791, { 0x03B2, 0x0000, 0x0000, 0x0000 } },
2362  { 0x1D792, { 0x03B3, 0x0000, 0x0000, 0x0000 } },
2363  { 0x1D793, { 0x03B4, 0x0000, 0x0000, 0x0000 } },
2364  { 0x1D794, { 0x03B5, 0x0000, 0x0000, 0x0000 } },
2365  { 0x1D795, { 0x03B6, 0x0000, 0x0000, 0x0000 } },
2366  { 0x1D796, { 0x03B7, 0x0000, 0x0000, 0x0000 } },
2367  { 0x1D797, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
2368  { 0x1D798, { 0x03B9, 0x0000, 0x0000, 0x0000 } },
2369  { 0x1D799, { 0x03BA, 0x0000, 0x0000, 0x0000 } },
2370  { 0x1D79A, { 0x03BB, 0x0000, 0x0000, 0x0000 } },
2371  { 0x1D79B, { 0x03BC, 0x0000, 0x0000, 0x0000 } },
2372  { 0x1D79C, { 0x03BD, 0x0000, 0x0000, 0x0000 } },
2373  { 0x1D79D, { 0x03BE, 0x0000, 0x0000, 0x0000 } },
2374  { 0x1D79E, { 0x03BF, 0x0000, 0x0000, 0x0000 } },
2375  { 0x1D79F, { 0x03C0, 0x0000, 0x0000, 0x0000 } },
2376  { 0x1D7A0, { 0x03C1, 0x0000, 0x0000, 0x0000 } },
2377  { 0x1D7A1, { 0x03B8, 0x0000, 0x0000, 0x0000 } },
2378  { 0x1D7A2, { 0x03C3, 0x0000, 0x0000, 0x0000 } },
2379  { 0x1D7A3, { 0x03C4, 0x0000, 0x0000, 0x0000 } },
2380  { 0x1D7A4, { 0x03C5, 0x0000, 0x0000, 0x0000 } },
2381  { 0x1D7A5, { 0x03C6, 0x0000, 0x0000, 0x0000 } },
2382  { 0x1D7A6, { 0x03C7, 0x0000, 0x0000, 0x0000 } },
2383  { 0x1D7A7, { 0x03C8, 0x0000, 0x0000, 0x0000 } },
2384  { 0x1D7A8, { 0x03C9, 0x0000, 0x0000, 0x0000 } },
2385  { 0x1D7BB, { 0x03C3, 0x0000, 0x0000, 0x0000 } }
2386 };
2387 
2388 static void mapToLowerCase(QString *str, int from)
2389 {
2390  int N = sizeof(NameprepCaseFolding) / sizeof(NameprepCaseFolding[0]);
2391 
2392  ushort *d = 0;
2393  for (int i = from; i < str->size(); ++i) {
2394  uint uc = str->at(i).unicode();
2395  if (uc < 0x80) {
2396  if (uc <= 'Z' && uc >= 'A') {
2397  if (!d)
2398  d = reinterpret_cast<ushort *>(str->data());
2399  d[i] = (uc | 0x20);
2400  }
2401  } else {
2402  if (QChar(uc).isHighSurrogate() && i < str->size() - 1) {
2403  ushort low = str->at(i + 1).unicode();
2404  if (QChar(low).isLowSurrogate()) {
2405  uc = QChar::surrogateToUcs4(uc, low);
2406  ++i;
2407  }
2408  }
2409  const NameprepCaseFoldingEntry *entry = qBinaryFind(NameprepCaseFolding,
2410  NameprepCaseFolding + N,
2411  uc);
2412  if ((entry - NameprepCaseFolding) != N) {
2413  int l = 1;
2414  while (l < 4 && entry->mapping[l])
2415  ++l;
2416  if (l > 1 || uc > 0xffff) {
2417  if (uc <= 0xffff)
2418  str->replace(i, 1, reinterpret_cast<const QChar *>(&entry->mapping[0]), l);
2419  else
2420  str->replace(--i, 2, reinterpret_cast<const QChar *>(&entry->mapping[0]), l);
2421  i += l - 1;
2422  d = 0;
2423  } else {
2424  if (!d)
2425  d = reinterpret_cast<ushort *>(str->data());
2426  d[i] = entry->mapping[0];
2427  }
2428  }
2429  }
2430  }
2431 }
2432 
2433 static bool isMappedToNothing(uint uc)
2434 {
2435  if (uc < 0xad)
2436  return false;
2437  switch (uc) {
2438  case 0x00AD: case 0x034F: case 0x1806: case 0x180B: case 0x180C: case 0x180D:
2439  case 0x200B: case 0x200C: case 0x200D: case 0x2060: case 0xFE00: case 0xFE01:
2440  case 0xFE02: case 0xFE03: case 0xFE04: case 0xFE05: case 0xFE06: case 0xFE07:
2441  case 0xFE08: case 0xFE09: case 0xFE0A: case 0xFE0B: case 0xFE0C: case 0xFE0D:
2442  case 0xFE0E: case 0xFE0F: case 0xFEFF:
2443  return true;
2444  default:
2445  return false;
2446  }
2447 }
2448 
2449 
2450 static bool containsProhibitedOuptut(const QString *str, int from)
2451 {
2452  const ushort *in = reinterpret_cast<const ushort *>(str->begin() + from);
2453  const ushort *end = (ushort *)str->data() + str->size();
2454  for ( ; in < end; ++in) {
2455  uint uc = *in;
2456  if (QChar(uc).isHighSurrogate() && in < end - 1) {
2457  ushort low = *(in + 1);
2458  if (QChar(low).isLowSurrogate()) {
2459  ++in;
2460  uc = QChar::surrogateToUcs4(uc, low);
2461  } else {
2462  // unpaired surrogates are prohibited
2463  return true;
2464  }
2465  }
2466  if (uc <= 0xFFFF) {
2467  if (uc < 0x80 ||
2468  !(uc <= 0x009F
2469  || uc == 0x00A0
2470  || uc == 0x0340
2471  || uc == 0x0341
2472  || uc == 0x06DD
2473  || uc == 0x070F
2474  || uc == 0x1680
2475  || uc == 0x180E
2476  || (uc >= 0x2000 && uc <= 0x200F)
2477  || (uc >= 0x2028 && uc <= 0x202F)
2478  || uc == 0x205F
2479  || (uc >= 0x2060 && uc <= 0x2063)
2480  || (uc >= 0x206A && uc <= 0x206F)
2481  || (uc >= 0x2FF0 && uc <= 0x2FFB)
2482  || uc == 0x3000
2483  || (uc >= 0xD800 && uc <= 0xDFFF)
2484  || (uc >= 0xE000 && uc <= 0xF8FF)
2485  || (uc >= 0xFDD0 && uc <= 0xFDEF)
2486  || uc == 0xFEFF
2487  || (uc >= 0xFFF9 && uc <= 0xFFFF))) {
2488  continue;
2489  }
2490  } else {
2491  if (!((uc >= 0x1D173 && uc <= 0x1D17A)
2492  || (uc >= 0x1FFFE && uc <= 0x1FFFF)
2493  || (uc >= 0x2FFFE && uc <= 0x2FFFF)
2494  || (uc >= 0x3FFFE && uc <= 0x3FFFF)
2495  || (uc >= 0x4FFFE && uc <= 0x4FFFF)
2496  || (uc >= 0x5FFFE && uc <= 0x5FFFF)
2497  || (uc >= 0x6FFFE && uc <= 0x6FFFF)
2498  || (uc >= 0x7FFFE && uc <= 0x7FFFF)
2499  || (uc >= 0x8FFFE && uc <= 0x8FFFF)
2500  || (uc >= 0x9FFFE && uc <= 0x9FFFF)
2501  || (uc >= 0xAFFFE && uc <= 0xAFFFF)
2502  || (uc >= 0xBFFFE && uc <= 0xBFFFF)
2503  || (uc >= 0xCFFFE && uc <= 0xCFFFF)
2504  || (uc >= 0xDFFFE && uc <= 0xDFFFF)
2505  || uc == 0xE0001
2506  || (uc >= 0xE0020 && uc <= 0xE007F)
2507  || (uc >= 0xEFFFE && uc <= 0xEFFFF)
2508  || (uc >= 0xF0000 && uc <= 0xFFFFD)
2509  || (uc >= 0xFFFFE && uc <= 0xFFFFF)
2510  || (uc >= 0x100000 && uc <= 0x10FFFD)
2511  || (uc >= 0x10FFFE && uc <= 0x10FFFF))) {
2512  continue;
2513  }
2514  }
2515  return true;
2516  }
2517  return false;
2518 }
2519 
2521 {
2522  if (uc < 0x5b0)
2523  return false;
2524  return uc == 0x05BE
2525  || uc == 0x05C0
2526  || uc == 0x05C3
2527  || (uc >= 0x05D0 && uc <= 0x05EA)
2528  || (uc >= 0x05F0 && uc <= 0x05F4)
2529  || uc == 0x061B
2530  || uc == 0x061F
2531  || (uc >= 0x0621 && uc <= 0x063A)
2532  || (uc >= 0x0640 && uc <= 0x064A)
2533  || (uc >= 0x066D && uc <= 0x066F)
2534  || (uc >= 0x0671 && uc <= 0x06D5)
2535  || uc == 0x06DD
2536  || (uc >= 0x06E5 && uc <= 0x06E6)
2537  || (uc >= 0x06FA && uc <= 0x06FE)
2538  || (uc >= 0x0700 && uc <= 0x070D)
2539  || uc == 0x0710
2540  || (uc >= 0x0712 && uc <= 0x072C)
2541  || (uc >= 0x0780 && uc <= 0x07A5)
2542  || uc == 0x07B1
2543  || uc == 0x200F
2544  || uc == 0xFB1D
2545  || (uc >= 0xFB1F && uc <= 0xFB28)
2546  || (uc >= 0xFB2A && uc <= 0xFB36)
2547  || (uc >= 0xFB38 && uc <= 0xFB3C)
2548  || uc == 0xFB3E
2549  || (uc >= 0xFB40 && uc <= 0xFB41)
2550  || (uc >= 0xFB43 && uc <= 0xFB44)
2551  || (uc >= 0xFB46 && uc <= 0xFBB1)
2552  || (uc >= 0xFBD3 && uc <= 0xFD3D)
2553  || (uc >= 0xFD50 && uc <= 0xFD8F)
2554  || (uc >= 0xFD92 && uc <= 0xFDC7)
2555  || (uc >= 0xFDF0 && uc <= 0xFDFC)
2556  || (uc >= 0xFE70 && uc <= 0xFE74)
2557  || (uc >= 0xFE76 && uc <= 0xFEFC);
2558 }
2559 
2560 static bool isBidirectionalL(uint uc)
2561 {
2562  if (uc < 0xaa)
2563  return (uc >= 0x0041 && uc <= 0x005A)
2564  || (uc >= 0x0061 && uc <= 0x007A);
2565 
2566  if (uc == 0x00AA
2567  || uc == 0x00B5
2568  || uc == 0x00BA
2569  || (uc >= 0x00C0 && uc <= 0x00D6)
2570  || (uc >= 0x00D8 && uc <= 0x00F6)
2571  || (uc >= 0x00F8 && uc <= 0x0220)
2572  || (uc >= 0x0222 && uc <= 0x0233)
2573  || (uc >= 0x0250 && uc <= 0x02AD)
2574  || (uc >= 0x02B0 && uc <= 0x02B8)
2575  || (uc >= 0x02BB && uc <= 0x02C1)
2576  || (uc >= 0x02D0 && uc <= 0x02D1)
2577  || (uc >= 0x02E0 && uc <= 0x02E4)
2578  || uc == 0x02EE
2579  || uc == 0x037A
2580  || uc == 0x0386
2581  || (uc >= 0x0388 && uc <= 0x038A)) {
2582  return true;
2583  }
2584 
2585  if (uc == 0x038C
2586  || (uc >= 0x038E && uc <= 0x03A1)
2587  || (uc >= 0x03A3 && uc <= 0x03CE)
2588  || (uc >= 0x03D0 && uc <= 0x03F5)
2589  || (uc >= 0x0400 && uc <= 0x0482)
2590  || (uc >= 0x048A && uc <= 0x04CE)
2591  || (uc >= 0x04D0 && uc <= 0x04F5)
2592  || (uc >= 0x04F8 && uc <= 0x04F9)
2593  || (uc >= 0x0500 && uc <= 0x050F)
2594  || (uc >= 0x0531 && uc <= 0x0556)
2595  || (uc >= 0x0559 && uc <= 0x055F)
2596  || (uc >= 0x0561 && uc <= 0x0587)
2597  || uc == 0x0589
2598  || uc == 0x0903
2599  || (uc >= 0x0905 && uc <= 0x0939)
2600  || (uc >= 0x093D && uc <= 0x0940)
2601  || (uc >= 0x0949 && uc <= 0x094C)
2602  || uc == 0x0950) {
2603  return true;
2604  }
2605 
2606  if ((uc >= 0x0958 && uc <= 0x0961)
2607  || (uc >= 0x0964 && uc <= 0x0970)
2608  || (uc >= 0x0982 && uc <= 0x0983)
2609  || (uc >= 0x0985 && uc <= 0x098C)
2610  || (uc >= 0x098F && uc <= 0x0990)
2611  || (uc >= 0x0993 && uc <= 0x09A8)
2612  || (uc >= 0x09AA && uc <= 0x09B0)
2613  || uc == 0x09B2
2614  || (uc >= 0x09B6 && uc <= 0x09B9)
2615  || (uc >= 0x09BE && uc <= 0x09C0)
2616  || (uc >= 0x09C7 && uc <= 0x09C8)
2617  || (uc >= 0x09CB && uc <= 0x09CC)
2618  || uc == 0x09D7
2619  || (uc >= 0x09DC && uc <= 0x09DD)
2620  || (uc >= 0x09DF && uc <= 0x09E1)
2621  || (uc >= 0x09E6 && uc <= 0x09F1)
2622  || (uc >= 0x09F4 && uc <= 0x09FA)
2623  || (uc >= 0x0A05 && uc <= 0x0A0A)
2624  || (uc >= 0x0A0F && uc <= 0x0A10)
2625  || (uc >= 0x0A13 && uc <= 0x0A28)
2626  || (uc >= 0x0A2A && uc <= 0x0A30)
2627  || (uc >= 0x0A32 && uc <= 0x0A33)) {
2628  return true;
2629  }
2630 
2631  if ((uc >= 0x0A35 && uc <= 0x0A36)
2632  || (uc >= 0x0A38 && uc <= 0x0A39)
2633  || (uc >= 0x0A3E && uc <= 0x0A40)
2634  || (uc >= 0x0A59 && uc <= 0x0A5C)
2635  || uc == 0x0A5E
2636  || (uc >= 0x0A66 && uc <= 0x0A6F)
2637  || (uc >= 0x0A72 && uc <= 0x0A74)
2638  || uc == 0x0A83
2639  || (uc >= 0x0A85 && uc <= 0x0A8B)
2640  || uc == 0x0A8D
2641  || (uc >= 0x0A8F && uc <= 0x0A91)
2642  || (uc >= 0x0A93 && uc <= 0x0AA8)
2643  || (uc >= 0x0AAA && uc <= 0x0AB0)
2644  || (uc >= 0x0AB2 && uc <= 0x0AB3)
2645  || (uc >= 0x0AB5 && uc <= 0x0AB9)
2646  || (uc >= 0x0ABD && uc <= 0x0AC0)
2647  || uc == 0x0AC9
2648  || (uc >= 0x0ACB && uc <= 0x0ACC)
2649  || uc == 0x0AD0
2650  || uc == 0x0AE0
2651  || (uc >= 0x0AE6 && uc <= 0x0AEF)
2652  || (uc >= 0x0B02 && uc <= 0x0B03)
2653  || (uc >= 0x0B05 && uc <= 0x0B0C)
2654  || (uc >= 0x0B0F && uc <= 0x0B10)
2655  || (uc >= 0x0B13 && uc <= 0x0B28)
2656  || (uc >= 0x0B2A && uc <= 0x0B30)) {
2657  return true;
2658  }
2659 
2660  if ((uc >= 0x0B32 && uc <= 0x0B33)
2661  || (uc >= 0x0B36 && uc <= 0x0B39)
2662  || (uc >= 0x0B3D && uc <= 0x0B3E)
2663  || uc == 0x0B40
2664  || (uc >= 0x0B47 && uc <= 0x0B48)
2665  || (uc >= 0x0B4B && uc <= 0x0B4C)
2666  || uc == 0x0B57
2667  || (uc >= 0x0B5C && uc <= 0x0B5D)
2668  || (uc >= 0x0B5F && uc <= 0x0B61)
2669  || (uc >= 0x0B66 && uc <= 0x0B70)
2670  || uc == 0x0B83
2671  || (uc >= 0x0B85 && uc <= 0x0B8A)
2672  || (uc >= 0x0B8E && uc <= 0x0B90)
2673  || (uc >= 0x0B92 && uc <= 0x0B95)
2674  || (uc >= 0x0B99 && uc <= 0x0B9A)
2675  || uc == 0x0B9C
2676  || (uc >= 0x0B9E && uc <= 0x0B9F)
2677  || (uc >= 0x0BA3 && uc <= 0x0BA4)
2678  || (uc >= 0x0BA8 && uc <= 0x0BAA)
2679  || (uc >= 0x0BAE && uc <= 0x0BB5)
2680  || (uc >= 0x0BB7 && uc <= 0x0BB9)
2681  || (uc >= 0x0BBE && uc <= 0x0BBF)
2682  || (uc >= 0x0BC1 && uc <= 0x0BC2)
2683  || (uc >= 0x0BC6 && uc <= 0x0BC8)
2684  || (uc >= 0x0BCA && uc <= 0x0BCC)
2685  || uc == 0x0BD7
2686  || (uc >= 0x0BE7 && uc <= 0x0BF2)
2687  || (uc >= 0x0C01 && uc <= 0x0C03)
2688  || (uc >= 0x0C05 && uc <= 0x0C0C)
2689  || (uc >= 0x0C0E && uc <= 0x0C10)
2690  || (uc >= 0x0C12 && uc <= 0x0C28)
2691  || (uc >= 0x0C2A && uc <= 0x0C33)
2692  || (uc >= 0x0C35 && uc <= 0x0C39)) {
2693  return true;
2694  }
2695  if ((uc >= 0x0C41 && uc <= 0x0C44)
2696  || (uc >= 0x0C60 && uc <= 0x0C61)
2697  || (uc >= 0x0C66 && uc <= 0x0C6F)
2698  || (uc >= 0x0C82 && uc <= 0x0C83)
2699  || (uc >= 0x0C85 && uc <= 0x0C8C)
2700  || (uc >= 0x0C8E && uc <= 0x0C90)
2701  || (uc >= 0x0C92 && uc <= 0x0CA8)
2702  || (uc >= 0x0CAA && uc <= 0x0CB3)
2703  || (uc >= 0x0CB5 && uc <= 0x0CB9)
2704  || uc == 0x0CBE
2705  || (uc >= 0x0CC0 && uc <= 0x0CC4)
2706  || (uc >= 0x0CC7 && uc <= 0x0CC8)
2707  || (uc >= 0x0CCA && uc <= 0x0CCB)
2708  || (uc >= 0x0CD5 && uc <= 0x0CD6)
2709  || uc == 0x0CDE
2710  || (uc >= 0x0CE0 && uc <= 0x0CE1)
2711  || (uc >= 0x0CE6 && uc <= 0x0CEF)
2712  || (uc >= 0x0D02 && uc <= 0x0D03)
2713  || (uc >= 0x0D05 && uc <= 0x0D0C)
2714  || (uc >= 0x0D0E && uc <= 0x0D10)
2715  || (uc >= 0x0D12 && uc <= 0x0D28)
2716  || (uc >= 0x0D2A && uc <= 0x0D39)
2717  || (uc >= 0x0D3E && uc <= 0x0D40)
2718  || (uc >= 0x0D46 && uc <= 0x0D48)
2719  || (uc >= 0x0D4A && uc <= 0x0D4C)
2720  || uc == 0x0D57
2721  || (uc >= 0x0D60 && uc <= 0x0D61)
2722  || (uc >= 0x0D66 && uc <= 0x0D6F)
2723  || (uc >= 0x0D82 && uc <= 0x0D83)
2724  || (uc >= 0x0D85 && uc <= 0x0D96)
2725  || (uc >= 0x0D9A && uc <= 0x0DB1)
2726  || (uc >= 0x0DB3 && uc <= 0x0DBB)
2727  || uc == 0x0DBD) {
2728  return true;
2729  }
2730  if ((uc >= 0x0DC0 && uc <= 0x0DC6)
2731  || (uc >= 0x0DCF && uc <= 0x0DD1)
2732  || (uc >= 0x0DD8 && uc <= 0x0DDF)
2733  || (uc >= 0x0DF2 && uc <= 0x0DF4)
2734  || (uc >= 0x0E01 && uc <= 0x0E30)
2735  || (uc >= 0x0E32 && uc <= 0x0E33)
2736  || (uc >= 0x0E40 && uc <= 0x0E46)
2737  || (uc >= 0x0E4F && uc <= 0x0E5B)
2738  || (uc >= 0x0E81 && uc <= 0x0E82)
2739  || uc == 0x0E84
2740  || (uc >= 0x0E87 && uc <= 0x0E88)
2741  || uc == 0x0E8A
2742  || uc == 0x0E8D
2743  || (uc >= 0x0E94 && uc <= 0x0E97)
2744  || (uc >= 0x0E99 && uc <= 0x0E9F)
2745  || (uc >= 0x0EA1 && uc <= 0x0EA3)
2746  || uc == 0x0EA5
2747  || uc == 0x0EA7
2748  || (uc >= 0x0EAA && uc <= 0x0EAB)
2749  || (uc >= 0x0EAD && uc <= 0x0EB0)
2750  || (uc >= 0x0EB2 && uc <= 0x0EB3)
2751  || uc == 0x0EBD
2752  || (uc >= 0x0EC0 && uc <= 0x0EC4)
2753  || uc == 0x0EC6
2754  || (uc >= 0x0ED0 && uc <= 0x0ED9)
2755  || (uc >= 0x0EDC && uc <= 0x0EDD)
2756  || (uc >= 0x0F00 && uc <= 0x0F17)
2757  || (uc >= 0x0F1A && uc <= 0x0F34)
2758  || uc == 0x0F36
2759  || uc == 0x0F38
2760  || (uc >= 0x0F3E && uc <= 0x0F47)
2761  || (uc >= 0x0F49 && uc <= 0x0F6A)
2762  || uc == 0x0F7F
2763  || uc == 0x0F85
2764  || (uc >= 0x0F88 && uc <= 0x0F8B)
2765  || (uc >= 0x0FBE && uc <= 0x0FC5)
2766  || (uc >= 0x0FC7 && uc <= 0x0FCC)
2767  || uc == 0x0FCF) {
2768  return true;
2769  }
2770 
2771  if ((uc >= 0x1000 && uc <= 0x1021)
2772  || (uc >= 0x1023 && uc <= 0x1027)
2773  || (uc >= 0x1029 && uc <= 0x102A)
2774  || uc == 0x102C
2775  || uc == 0x1031
2776  || uc == 0x1038
2777  || (uc >= 0x1040 && uc <= 0x1057)
2778  || (uc >= 0x10A0 && uc <= 0x10C5)
2779  || (uc >= 0x10D0 && uc <= 0x10F8)
2780  || uc == 0x10FB
2781  || (uc >= 0x1100 && uc <= 0x1159)
2782  || (uc >= 0x115F && uc <= 0x11A2)
2783  || (uc >= 0x11A8 && uc <= 0x11F9)
2784  || (uc >= 0x1200 && uc <= 0x1206)
2785  || (uc >= 0x1208 && uc <= 0x1246)
2786  || uc == 0x1248
2787  || (uc >= 0x124A && uc <= 0x124D)
2788  || (uc >= 0x1250 && uc <= 0x1256)
2789  || uc == 0x1258
2790  || (uc >= 0x125A && uc <= 0x125D)
2791  || (uc >= 0x1260 && uc <= 0x1286)
2792  || uc == 0x1288
2793  || (uc >= 0x128A && uc <= 0x128D)
2794  || (uc >= 0x1290 && uc <= 0x12AE)
2795  || uc == 0x12B0
2796  || (uc >= 0x12B2 && uc <= 0x12B5)
2797  || (uc >= 0x12B8 && uc <= 0x12BE)
2798  || uc == 0x12C0
2799  || (uc >= 0x12C2 && uc <= 0x12C5)
2800  || (uc >= 0x12C8 && uc <= 0x12CE)
2801  || (uc >= 0x12D0 && uc <= 0x12D6)
2802  || (uc >= 0x12D8 && uc <= 0x12EE)
2803  || (uc >= 0x12F0 && uc <= 0x130E)
2804  || uc == 0x1310) {
2805  return true;
2806  }
2807 
2808  if ((uc >= 0x1312 && uc <= 0x1315)
2809  || (uc >= 0x1318 && uc <= 0x131E)
2810  || (uc >= 0x1320 && uc <= 0x1346)
2811  || (uc >= 0x1348 && uc <= 0x135A)
2812  || (uc >= 0x1361 && uc <= 0x137C)
2813  || (uc >= 0x13A0 && uc <= 0x13F4)
2814  || (uc >= 0x1401 && uc <= 0x1676)
2815  || (uc >= 0x1681 && uc <= 0x169A)
2816  || (uc >= 0x16A0 && uc <= 0x16F0)
2817  || (uc >= 0x1700 && uc <= 0x170C)
2818  || (uc >= 0x170E && uc <= 0x1711)
2819  || (uc >= 0x1720 && uc <= 0x1731)
2820  || (uc >= 0x1735 && uc <= 0x1736)
2821  || (uc >= 0x1740 && uc <= 0x1751)
2822  || (uc >= 0x1760 && uc <= 0x176C)
2823  || (uc >= 0x176E && uc <= 0x1770)
2824  || (uc >= 0x1780 && uc <= 0x17B6)
2825  || (uc >= 0x17BE && uc <= 0x17C5)
2826  || (uc >= 0x17C7 && uc <= 0x17C8)
2827  || (uc >= 0x17D4 && uc <= 0x17DA)
2828  || uc == 0x17DC
2829  || (uc >= 0x17E0 && uc <= 0x17E9)
2830  || (uc >= 0x1810 && uc <= 0x1819)
2831  || (uc >= 0x1820 && uc <= 0x1877)
2832  || (uc >= 0x1880 && uc <= 0x18A8)
2833  || (uc >= 0x1E00 && uc <= 0x1E9B)
2834  || (uc >= 0x1EA0 && uc <= 0x1EF9)
2835  || (uc >= 0x1F00 && uc <= 0x1F15)
2836  || (uc >= 0x1F18 && uc <= 0x1F1D)
2837  || (uc >= 0x1F20 && uc <= 0x1F45)
2838  || (uc >= 0x1F48 && uc <= 0x1F4D)
2839  || (uc >= 0x1F50 && uc <= 0x1F57)
2840  || uc == 0x1F59
2841  || uc == 0x1F5B
2842  || uc == 0x1F5D) {
2843  return true;
2844  }
2845 
2846  if ((uc >= 0x1F5F && uc <= 0x1F7D)
2847  || (uc >= 0x1F80 && uc <= 0x1FB4)
2848  || (uc >= 0x1FB6 && uc <= 0x1FBC)
2849  || uc == 0x1FBE
2850  || (uc >= 0x1FC2 && uc <= 0x1FC4)
2851  || (uc >= 0x1FC6 && uc <= 0x1FCC)
2852  || (uc >= 0x1FD0 && uc <= 0x1FD3)
2853  || (uc >= 0x1FD6 && uc <= 0x1FDB)
2854  || (uc >= 0x1FE0 && uc <= 0x1FEC)
2855  || (uc >= 0x1FF2 && uc <= 0x1FF4)
2856  || (uc >= 0x1FF6 && uc <= 0x1FFC)
2857  || uc == 0x200E
2858  || uc == 0x2071
2859  || uc == 0x207F
2860  || uc == 0x2102
2861  || uc == 0x2107
2862  || (uc >= 0x210A && uc <= 0x2113)
2863  || uc == 0x2115
2864  || (uc >= 0x2119 && uc <= 0x211D)) {
2865  return true;
2866  }
2867 
2868  if (uc == 0x2124
2869  || uc == 0x2126
2870  || uc == 0x2128
2871  || (uc >= 0x212A && uc <= 0x212D)
2872  || (uc >= 0x212F && uc <= 0x2131)
2873  || (uc >= 0x2133 && uc <= 0x2139)
2874  || (uc >= 0x213D && uc <= 0x213F)
2875  || (uc >= 0x2145 && uc <= 0x2149)
2876  || (uc >= 0x2160 && uc <= 0x2183)
2877  || (uc >= 0x2336 && uc <= 0x237A)
2878  || uc == 0x2395
2879  || (uc >= 0x249C && uc <= 0x24E9)
2880  || (uc >= 0x3005 && uc <= 0x3007)
2881  || (uc >= 0x3021 && uc <= 0x3029)
2882  || (uc >= 0x3031 && uc <= 0x3035)
2883  || (uc >= 0x3038 && uc <= 0x303C)
2884  || (uc >= 0x3041 && uc <= 0x3096)
2885  || (uc >= 0x309D && uc <= 0x309F)
2886  || (uc >= 0x30A1 && uc <= 0x30FA)) {
2887  return true;
2888  }
2889 
2890  if ((uc >= 0x30FC && uc <= 0x30FF)
2891  || (uc >= 0x3105 && uc <= 0x312C)
2892  || (uc >= 0x3131 && uc <= 0x318E)
2893  || (uc >= 0x3190 && uc <= 0x31B7)
2894  || (uc >= 0x31F0 && uc <= 0x321C)
2895  || (uc >= 0x3220 && uc <= 0x3243)) {
2896  return true;
2897  }
2898 
2899  if ((uc >= 0x3260 && uc <= 0x327B)
2900  || (uc >= 0x327F && uc <= 0x32B0)
2901  || (uc >= 0x32C0 && uc <= 0x32CB)
2902  || (uc >= 0x32D0 && uc <= 0x32FE)
2903  || (uc >= 0x3300 && uc <= 0x3376)
2904  || (uc >= 0x337B && uc <= 0x33DD)) {
2905  return true;
2906  }
2907  if ((uc >= 0x33E0 && uc <= 0x33FE)
2908  || (uc >= 0x3400 && uc <= 0x4DB5)
2909  || (uc >= 0x4E00 && uc <= 0x9FA5)
2910  || (uc >= 0xA000 && uc <= 0xA48C)
2911  || (uc >= 0xAC00 && uc <= 0xD7A3)
2912  || (uc >= 0xD800 && uc <= 0xFA2D)
2913  || (uc >= 0xFA30 && uc <= 0xFA6A)
2914  || (uc >= 0xFB00 && uc <= 0xFB06)
2915  || (uc >= 0xFB13 && uc <= 0xFB17)
2916  || (uc >= 0xFF21 && uc <= 0xFF3A)
2917  || (uc >= 0xFF41 && uc <= 0xFF5A)
2918  || (uc >= 0xFF66 && uc <= 0xFFBE)
2919  || (uc >= 0xFFC2 && uc <= 0xFFC7)
2920  || (uc >= 0xFFCA && uc <= 0xFFCF)
2921  || (uc >= 0xFFD2 && uc <= 0xFFD7)
2922  || (uc >= 0xFFDA && uc <= 0xFFDC)) {
2923  return true;
2924  }
2925 
2926  if ((uc >= 0x10300 && uc <= 0x1031E)
2927  || (uc >= 0x10320 && uc <= 0x10323)
2928  || (uc >= 0x10330 && uc <= 0x1034A)
2929  || (uc >= 0x10400 && uc <= 0x10425)
2930  || (uc >= 0x10428 && uc <= 0x1044D)
2931  || (uc >= 0x1D000 && uc <= 0x1D0F5)
2932  || (uc >= 0x1D100 && uc <= 0x1D126)
2933  || (uc >= 0x1D12A && uc <= 0x1D166)
2934  || (uc >= 0x1D16A && uc <= 0x1D172)
2935  || (uc >= 0x1D183 && uc <= 0x1D184)
2936  || (uc >= 0x1D18C && uc <= 0x1D1A9)
2937  || (uc >= 0x1D1AE && uc <= 0x1D1DD)
2938  || (uc >= 0x1D400 && uc <= 0x1D454)
2939  || (uc >= 0x1D456 && uc <= 0x1D49C)
2940  || (uc >= 0x1D49E && uc <= 0x1D49F)
2941  || uc == 0x1D4A2
2942  || (uc >= 0x1D4A5 && uc <= 0x1D4A6)
2943  || (uc >= 0x1D4A9 && uc <= 0x1D4AC)
2944  || (uc >= 0x1D4AE && uc <= 0x1D4B9)
2945  || uc == 0x1D4BB
2946  || (uc >= 0x1D4BD && uc <= 0x1D4C0)
2947  || (uc >= 0x1D4C2 && uc <= 0x1D4C3)
2948  || (uc >= 0x1D4C5 && uc <= 0x1D505)
2949  || (uc >= 0x1D507 && uc <= 0x1D50A)
2950  || (uc >= 0x1D50D && uc <= 0x1D514)
2951  || (uc >= 0x1D516 && uc <= 0x1D51C)
2952  || (uc >= 0x1D51E && uc <= 0x1D539)
2953  || (uc >= 0x1D53B && uc <= 0x1D53E)
2954  || (uc >= 0x1D540 && uc <= 0x1D544)
2955  || uc == 0x1D546
2956  || (uc >= 0x1D54A && uc <= 0x1D550)
2957  || (uc >= 0x1D552 && uc <= 0x1D6A3)
2958  || (uc >= 0x1D6A8 && uc <= 0x1D7C9)
2959  || (uc >= 0x20000 && uc <= 0x2A6D6)
2960  || (uc >= 0x2F800 && uc <= 0x2FA1D)
2961  || (uc >= 0xF0000 && uc <= 0xFFFFD)
2962  || (uc >= 0x100000 && uc <= 0x10FFFD)) {
2963  return true;
2964  }
2965 
2966  return false;
2967 }
2968 
2969 #ifdef QT_BUILD_INTERNAL
2970 // export for tst_qurl.cpp
2971 Q_AUTOTEST_EXPORT void qt_nameprep(QString *source, int from);
2972 Q_AUTOTEST_EXPORT bool qt_check_std3rules(const QChar *uc, int len);
2973 #else
2974 // non-test build, keep the symbols for ourselves
2975 static void qt_nameprep(QString *source, int from);
2976 static bool qt_check_std3rules(const QChar *uc, int len);
2977 #endif
2978 
2979 void qt_nameprep(QString *source, int from)
2980 {
2981  QChar *src = source->data(); // causes a detach, so we're sure the only one using it
2982  QChar *out = src + from;
2983  const QChar *e = src + source->size();
2984 
2985  for ( ; out < e; ++out) {
2986  register ushort uc = out->unicode();
2987  if (uc >= 0x80) {
2988  break;
2989  } else if (uc >= 'A' && uc <= 'Z') {
2990  *out = QChar(uc | 0x20);
2991  }
2992  }
2993  if (out == e)
2994  return; // everything was mapped easily (lowercased, actually)
2995  int firstNonAscii = out - src;
2996 
2997  // Characters unassigned in Unicode 3.2 are not allowed in "stored string" scheme
2998  // but allowed in "query" scheme
2999  // (Table A.1)
3000  const bool isUnassignedAllowed = false; // ###
3001  // Characters commonly mapped to nothing are simply removed
3002  // (Table B.1)
3003  const QChar *in = out;
3004  for ( ; in < e; ++in) {
3005  uint uc = in->unicode();
3006  if (QChar(uc).isHighSurrogate() && in < e - 1) {
3007  ushort low = in[1].unicode();
3008  if (QChar(low).isLowSurrogate()) {
3009  ++in;
3010  uc = QChar::surrogateToUcs4(uc, low);
3011  }
3012  }
3013  if (!isUnassignedAllowed) {
3015  if (version == QChar::Unicode_Unassigned || version > QChar::Unicode_3_2) {
3016  source->resize(from); // not allowed, clear the label
3017  return;
3018  }
3019  }
3020  if (!isMappedToNothing(uc)) {
3021  if (uc <= 0xFFFF) {
3022  *out++ = *in;
3023  } else {
3024  *out++ = in[-1];
3025  *out++ = in[0];
3026  }
3027  }
3028  }
3029  if (out != in)
3030  source->truncate(out - src);
3031 
3032  // Map to lowercase (Table B.2)
3033  mapToLowerCase(source, firstNonAscii);
3034 
3035  // Normalize to Unicode 3.2 form KC
3037  QChar::UnicodeVersion version, int from);
3039  firstNonAscii > from ? firstNonAscii - 1 : from);
3040 
3041  // Strip prohibited output
3042  if (containsProhibitedOuptut(source, firstNonAscii)) {
3043  source->resize(from);
3044  return;
3045  }
3046 
3047  // Check for valid bidirectional characters
3048  bool containsLCat = false;
3049  bool containsRandALCat = false;
3050  src = source->data();
3051  e = src + source->size();
3052  for (in = src + from; in < e && (!containsLCat || !containsRandALCat); ++in) {
3053  uint uc = in->unicode();
3054  if (QChar(uc).isHighSurrogate() && in < e - 1) {
3055  ushort low = in[1].unicode();
3056  if (QChar(low).isLowSurrogate()) {
3057  ++in;
3058  uc = QChar::surrogateToUcs4(uc, low);
3059  }
3060  }
3061  if (isBidirectionalL(uc))
3062  containsLCat = true;
3063  else if (isBidirectionalRorAL(uc))
3064  containsRandALCat = true;
3065  }
3066  if (containsRandALCat) {
3067  if (containsLCat || (!isBidirectionalRorAL(src[from].unicode())
3068  || !isBidirectionalRorAL(e[-1].unicode())))
3069  source->resize(from); // not allowed, clear the label
3070  }
3071 }
3072 
3073 bool qt_check_std3rules(const QChar *uc, int len)
3074 {
3075  if (len > 63)
3076  return false;
3077 
3078  for (int i = 0; i < len; ++i) {
3079  register ushort c = uc[i].unicode();
3080  if (c == '-' && (i == 0 || i == len - 1))
3081  return false;
3082 
3083  // verifying the absence of LDH is the same as verifying that
3084  // only LDH is present
3085  if (c == '-' || (c >= '0' && c <= '9')
3086  || (c >= 'A' && c <= 'Z')
3087  || (c >= 'a' && c <= 'z')
3088  //underscore is not supposed to be allowed, but other browser accept it (QTBUG-7434)
3089  || c == '_')
3090  continue;
3091 
3092  return false;
3093  }
3094 
3095  return true;
3096 }
3097 
3098 
3099 static inline uint encodeDigit(uint digit)
3100 {
3101  return digit + 22 + 75 * (digit < 26);
3102 }
3103 
3104 static inline uint adapt(uint delta, uint numpoints, bool firsttime)
3105 {
3106  delta /= (firsttime ? damp : 2);
3107  delta += (delta / numpoints);
3108 
3109  uint k = 0;
3110  for (; delta > ((base - tmin) * tmax) / 2; k += base)
3111  delta /= (base - tmin);
3112 
3113  return k + (((base - tmin + 1) * delta) / (delta + skew));
3114 }
3115 
3116 static inline void appendEncode(QString* output, uint& delta, uint& bias, uint& b, uint& h)
3117 {
3118  uint qq;
3119  uint k;
3120  uint t;
3121 
3122  // insert the variable length delta integer; fail on
3123  // overflow.
3124  for (qq = delta, k = base;; k += base) {
3125  // stop generating digits when the threshold is
3126  // detected.
3127  t = (k <= bias) ? tmin : (k >= bias + tmax) ? tmax : k - bias;
3128  if (qq < t) break;
3129 
3130  *output += QChar(encodeDigit(t + (qq - t) % (base - t)));
3131  qq = (qq - t) / (base - t);
3132  }
3133 
3134  *output += QChar(encodeDigit(qq));
3135  bias = adapt(delta, h + 1, h == b);
3136  delta = 0;
3137  ++h;
3138 }
3139 
3140 static void toPunycodeHelper(const QChar *s, int ucLength, QString *output)
3141 {
3142  uint n = initial_n;
3143  uint delta = 0;
3144  uint bias = initial_bias;
3145 
3146  int outLen = output->length();
3147  output->resize(outLen + ucLength);
3148 
3149  QChar *d = output->data() + outLen;
3150  bool skipped = false;
3151  // copy all basic code points verbatim to output.
3152  for (uint j = 0; j < (uint) ucLength; ++j) {
3153  ushort js = s[j].unicode();
3154  if (js < 0x80)
3155  *d++ = js;
3156  else
3157  skipped = true;
3158  }
3159 
3160  // if there were only basic code points, just return them
3161  // directly; don't do any encoding.
3162  if (!skipped)
3163  return;
3164 
3165  output->truncate(d - output->constData());
3166  int copied = output->size() - outLen;
3167 
3168  // h and b now contain the number of basic code points in input.
3169  uint b = copied;
3170  uint h = copied;
3171 
3172  // if basic code points were copied, add the delimiter character.
3173  if (h > 0)
3174  *output += QChar(0x2d);
3175 
3176  // while there are still unprocessed non-basic code points left in
3177  // the input string...
3178  while (h < (uint) ucLength) {
3179  // find the character in the input string with the lowest
3180  // unicode value.
3181  uint m = Q_MAXINT;
3182  uint j;
3183  for (j = 0; j < (uint) ucLength; ++j) {
3184  if (s[j].unicode() >= n && s[j].unicode() < m)
3185  m = (uint) s[j].unicode();
3186  }
3187 
3188  // reject out-of-bounds unicode characters
3189  if (m - n > (Q_MAXINT - delta) / (h + 1)) {
3190  output->truncate(outLen);
3191  return; // punycode_overflow
3192  }
3193 
3194  delta += (m - n) * (h + 1);
3195  n = m;
3196 
3197  // for each code point in the input string
3198  for (j = 0; j < (uint) ucLength; ++j) {
3199 
3200  // increase delta until we reach the character with the
3201  // lowest unicode code. fail if delta overflows.
3202  if (s[j].unicode() < n) {
3203  ++delta;
3204  if (!delta) {
3205  output->truncate(outLen);
3206  return; // punycode_overflow
3207  }
3208  }
3209 
3210  // if j is the index of the character with the lowest
3211  // unicode code...
3212  if (s[j].unicode() == n) {
3213  appendEncode(output, delta, bias, b, h);
3214  }
3215  }
3216 
3217  ++delta;
3218  ++n;
3219  }
3220 
3221  // prepend ACE prefix
3222  output->insert(outLen, QLatin1String("xn--"));
3223  return;
3224 }
3225 
3226 
3227 static const char * const idn_whitelist[] = {
3228  "ac", "ar", "at",
3229  "biz", "br",
3230  "cat", "ch", "cl", "cn",
3231  "de", "dk",
3232  "es",
3233  "fi",
3234  "gr",
3235  "hu",
3236  "info", "io", "is",
3237  "jp",
3238  "kr",
3239  "li", "lt",
3240  "museum",
3241  "no",
3242  "org",
3243  "se", "sh",
3244  "th", "tm", "tw",
3245  "vn",
3246  "xn--mgbaam7a8h", // UAE
3247  "xn--mgberp4a5d4ar", // Saudi Arabia
3248  "xn--wgbh1c" // Egypt
3249 };
3250 
3252 
3253 static bool lessThan(const QChar *a, int l, const char *c)
3254 {
3255  const ushort *uc = (const ushort *)a;
3256  const ushort *e = uc + l;
3257 
3258  if (!c || *c == 0)
3259  return false;
3260 
3261  while (*c) {
3262  if (uc == e || *uc != *c)
3263  break;
3264  ++uc;
3265  ++c;
3266  }
3267  return (uc == e ? *c : *uc < *c);
3268 }
3269 
3270 static bool equal(const QChar *a, int l, const char *b)
3271 {
3272  while (l && a->unicode() && *b) {
3273  if (*a != QLatin1Char(*b))
3274  return false;
3275  ++a;
3276  ++b;
3277  --l;
3278  }
3279  return l == 0;
3280 }
3281 
3282 static bool qt_is_idn_enabled(const QString &domain)
3283 {
3284  int idx = domain.lastIndexOf(QLatin1Char('.'));
3285  if (idx == -1)
3286  return false;
3287 
3288  int len = domain.size() - idx - 1;
3289  QString tldString(domain.constData() + idx + 1, len);
3290  qt_nameprep(&tldString, 0);
3291 
3292  const QChar *tld = tldString.constData();
3293 
3294  if (user_idn_whitelist)
3295  return user_idn_whitelist->contains(tldString);
3296 
3297  int l = 0;
3298  int r = sizeof(idn_whitelist)/sizeof(const char *) - 1;
3299  int i = (l + r + 1) / 2;
3300 
3301  while (r != l) {
3302  if (lessThan(tld, len, idn_whitelist[i]))
3303  r = i - 1;
3304  else
3305  l = i;
3306  i = (l + r + 1) / 2;
3307  }
3308  return equal(tld, len, idn_whitelist[i]);
3309 }
3310 
3311 static inline bool isDotDelimiter(ushort uc)
3312 {
3313  // IDNA / rfc3490 describes these four delimiters used for
3314  // separating labels in unicode international domain
3315  // names.
3316  return uc == 0x2e || uc == 0x3002 || uc == 0xff0e || uc == 0xff61;
3317 }
3318 
3319 static int nextDotDelimiter(const QString &domain, int from = 0)
3320 {
3321  const QChar *b = domain.unicode();
3322  const QChar *ch = b + from;
3323  const QChar *e = b + domain.length();
3324  while (ch < e) {
3325  if (isDotDelimiter(ch->unicode()))
3326  break;
3327  else
3328  ++ch;
3329  }
3330  return ch - b;
3331 }
3332 
3334 static QString qt_ACE_do(const QString &domain, AceOperation op)
3335 {
3336  if (domain.isEmpty())
3337  return domain;
3338 
3339  QString result;
3340  result.reserve(domain.length());
3341 
3342  const bool isIdnEnabled = op == NormalizeAce ? qt_is_idn_enabled(domain) : false;
3343  int lastIdx = 0;
3344  QString aceForm; // this variable is here for caching
3345 
3346  while (1) {
3347  int idx = nextDotDelimiter(domain, lastIdx);
3348  int labelLength = idx - lastIdx;
3349  if (labelLength == 0) {
3350  if (idx == domain.length())
3351  break;
3352  return QString(); // two delimiters in a row -- empty label not allowed
3353  }
3354 
3355  // RFC 3490 says, about the ToASCII operation:
3356  // 3. If the UseSTD3ASCIIRules flag is set, then perform these checks:
3357  //
3358  // (a) Verify the absence of non-LDH ASCII code points; that is, the
3359  // absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F.
3360  //
3361  // (b) Verify the absence of leading and trailing hyphen-minus; that
3362  // is, the absence of U+002D at the beginning and end of the
3363  // sequence.
3364  // and:
3365  // 8. Verify that the number of code points is in the range 1 to 63
3366  // inclusive.
3367 
3368  // copy the label to the destination, which also serves as our scratch area, lowercasing it
3369  int prevLen = result.size();
3370  bool simple = true;
3371  result.resize(prevLen + labelLength);
3372  {
3373  QChar *out = result.data() + prevLen;
3374  const QChar *in = domain.constData() + lastIdx;
3375  const QChar *e = in + labelLength;
3376  for (; in < e; ++in, ++out) {
3377  register ushort uc = in->unicode();
3378  if (uc > 0x7f)
3379  simple = false;
3380  if (uc >= 'A' && uc <= 'Z')
3381  *out = QChar(uc | 0x20);
3382  else
3383  *out = *in;
3384  }
3385  }
3386 
3387  if (simple && labelLength > 6) {
3388  // ACE form domains contain only ASCII characters, but we can't consider them simple
3389  // is this an ACE form?
3390  // the shortest valid ACE domain is 6 characters long (U+0080 would be 1, but it's not allowed)
3391  static const ushort acePrefixUtf16[] = { 'x', 'n', '-', '-' };
3392  if (memcmp(result.constData() + prevLen, acePrefixUtf16, sizeof acePrefixUtf16) == 0)
3393  simple = false;
3394  }
3395 
3396  if (simple) {
3397  // fastest case: this is the common case (non IDN-domains)
3398  // so we're done
3399  if (!qt_check_std3rules(result.constData() + prevLen, labelLength))
3400  return QString();
3401  } else {
3402  // Punycode encoding and decoding cannot be done in-place
3403  // That means we need one or two temporaries
3404  qt_nameprep(&result, prevLen);
3405  labelLength = result.length() - prevLen;
3406  register int toReserve = labelLength + 4 + 6; // "xn--" plus some extra bytes
3407  aceForm.resize(0);
3408  if (toReserve > aceForm.capacity())
3409  aceForm.reserve(toReserve);
3410  toPunycodeHelper(result.constData() + prevLen, result.size() - prevLen, &aceForm);
3411 
3412  // We use resize()+memcpy() here because we're overwriting the data we've copied
3413  if (isIdnEnabled) {
3414  QString tmp = QUrl::fromPunycode(aceForm.toLatin1());
3415  if (tmp.isEmpty())
3416  return QString(); // shouldn't happen, since we've just punycode-encoded it
3417  result.resize(prevLen + tmp.size());
3418  memcpy(result.data() + prevLen, tmp.constData(), tmp.size() * sizeof(QChar));
3419  } else {
3420  result.resize(prevLen + aceForm.size());
3421  memcpy(result.data() + prevLen, aceForm.constData(), aceForm.size() * sizeof(QChar));
3422  }
3423 
3424  if (!qt_check_std3rules(aceForm.constData(), aceForm.size()))
3425  return QString();
3426  }
3427 
3428 
3429  lastIdx = idx + 1;
3430  if (lastIdx < domain.size() + 1)
3431  result += QLatin1Char('.');
3432  else
3433  break;
3434  }
3435  return result;
3436 }
3437 
3438 
3440 {
3441  ref = 1;
3442  port = -1;
3443  isValid = false;
3444  isHostValid = true;
3445  parsingMode = QUrl::TolerantMode;
3446  valueDelimiter = '=';
3447  pairDelimiter = '&';
3448  stateFlags = 0;
3449  hasFragment = false;
3450  hasQuery = false;
3451 }
3452 
3453 // Called by normalized() and detach(). Must hold copy.mutex.
3455  : scheme(copy.scheme),
3456  userName(copy.userName),
3457  password(copy.password),
3458  host(copy.host),
3459  path(copy.path),
3460  query(copy.query),
3461  fragment(copy.fragment),
3462  encodedOriginal(copy.encodedOriginal),
3463  encodedUserName(copy.encodedUserName),
3464  encodedPassword(copy.encodedPassword),
3465  encodedPath(copy.encodedPath),
3466  encodedFragment(copy.encodedFragment),
3467  port(copy.port),
3468  parsingMode(copy.parsingMode),
3469  hasQuery(copy.hasQuery),
3470  hasFragment(copy.hasFragment),
3471  isValid(copy.isValid),
3472  isHostValid(copy.isHostValid),
3473  valueDelimiter(copy.valueDelimiter),
3474  pairDelimiter(copy.pairDelimiter),
3475  stateFlags(copy.stateFlags),
3476  encodedNormalized(copy.encodedNormalized)
3477 { ref = 1; }
3478 
3480 {
3481  // Caller must lock mutex first
3483  return host;
3484 
3485  QUrlPrivate *that = const_cast<QUrlPrivate *>(this);
3487  if (host.contains(QLatin1Char(':'))) {
3488  // This is an IP Literal, use _IPLiteral to validate
3489  QByteArray ba = host.toLatin1();
3490  bool needsBraces = false;
3491  if (!ba.startsWith('[')) {
3492  // surround the IP Literal with [ ] if it's not already done so
3493  ba.reserve(ba.length() + 2);
3494  ba.prepend('[');
3495  ba.append(']');
3496  needsBraces = true;
3497  }
3498 
3499  const char *ptr = ba.constData();
3500  if (!_IPLiteral(&ptr))
3501  that->host.clear();
3502  else if (needsBraces)
3503  that->host = QString::fromLatin1(ba.toLower());
3504  else
3505  that->host = host.toLower();
3506  } else {
3507  that->host = qt_ACE_do(host, NormalizeAce);
3508  }
3509  that->isHostValid = !that->host.isNull();
3510  return that->host;
3511 }
3512 
3513 // From RFC 3896, Appendix A Collected ABNF for URI
3514 // authority = [ userinfo "@" ] host [ ":" port ]
3515 // userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
3516 // host = IP-literal / IPv4address / reg-name
3517 // port = *DIGIT
3518 //[...]
3519 // pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
3520 //
3521 // query = *( pchar / "/" / "?" )
3522 //
3523 // fragment = *( pchar / "/" / "?" )
3524 //
3525 // pct-encoded = "%" HEXDIG HEXDIG
3526 //
3527 // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
3528 // reserved = gen-delims / sub-delims
3529 // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
3530 // sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
3531 // / "*" / "+" / "," / ";" / "="
3532 
3533 // use defines for concatenation:
3534 #define ABNF_sub_delims "!$&'()*+,;="
3535 #define ABNF_gen_delims ":/?#[]@"
3536 #define ABNF_pchar ABNF_sub_delims ":@"
3537 #define ABNF_reserved ABNF_sub_delims ABNF_gen_delims
3538 
3539 // list the characters that don't have to be converted according to the list above.
3540 // "unreserved" is already automatically not encoded, so we don't have to list it.
3541 // the path component has a complex ABNF that basically boils down to
3542 // slash-separated segments of "pchar"
3543 
3545 static const char passwordExcludeChars[] = ABNF_sub_delims ":";
3546 static const char pathExcludeChars[] = ABNF_pchar "/";
3547 static const char queryExcludeChars[] = ABNF_pchar "/?";
3548 static const char fragmentExcludeChars[] = ABNF_pchar "/?";
3549 
3551 {
3552  QUrlPrivate *that = const_cast<QUrlPrivate *>(this);
3553 
3554  if (encodedUserName.isNull())
3555  // userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
3557  if (encodedPassword.isNull())
3558  // userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
3560  if (encodedPath.isNull())
3561  // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" ... also "/"
3563  if (encodedFragment.isNull())
3564  // fragment = *( pchar / "/" / "?" )
3566 }
3567 
3568 QString QUrlPrivate::authority(QUrl::FormattingOptions options) const
3569 {
3570  // Caller must lock mutex first
3571 
3572  if ((options & QUrl::RemoveAuthority) == QUrl::RemoveAuthority)
3573  return QString();
3574 
3575  QString tmp = userInfo(options);
3576  if (!tmp.isEmpty())
3577  tmp += QLatin1Char('@');
3578  tmp += canonicalHost();
3579  if (!(options & QUrl::RemovePort) && port != -1)
3580  tmp += QLatin1Char(':') + QString::number(port);
3581 
3582  return tmp;
3583 }
3584 
3586 {
3587  isHostValid = true;
3588  if (auth.isEmpty()) {
3589  setUserInfo(QString());
3590  if (auth.isNull())
3591  host.clear();
3592  else
3593  host = QLatin1String("");
3594  port = -1;
3595  return;
3596  }
3597 
3598  // find the port section of the authority by searching from the
3599  // end towards the beginning for numbers until a ':' is reached.
3600  int portIndex = auth.length() - 1;
3601  if (portIndex == 0) {
3602  portIndex = -1;
3603  } else {
3604  short c = auth.at(portIndex--).unicode();
3605  if (c < '0' || c > '9') {
3606  portIndex = -1;
3607  } else while (portIndex >= 0) {
3608  c = auth.at(portIndex).unicode();
3609  if (c == ':') {
3610  break;
3611  } else if (c == '.') {
3612  portIndex = -1;
3613  break;
3614  }
3615  --portIndex;
3616  }
3617  }
3618 
3619  if (portIndex != -1) {
3620  port = 0;
3621  for (int i = portIndex + 1; i < auth.length(); ++i)
3622  port = (port * 10) + (auth.at(i).unicode() - '0');
3623  } else {
3624  port = -1;
3625  }
3626 
3627  int userInfoIndex = auth.indexOf(QLatin1Char('@'));
3628  if (userInfoIndex != -1 && (portIndex == -1 || userInfoIndex < portIndex))
3629  setUserInfo(auth.left(userInfoIndex));
3630 
3631  int hostIndex = 0;
3632  if (userInfoIndex != -1)
3633  hostIndex = userInfoIndex + 1;
3634  int hostLength = auth.length() - hostIndex;
3635  if (portIndex != -1)
3636  hostLength -= (auth.length() - portIndex);
3637 
3638  host = auth.mid(hostIndex, hostLength).trimmed();
3639 }
3640 
3642 {
3645 
3646  int delimIndex = userInfo.indexOf(QLatin1Char(':'));
3647  if (delimIndex == -1) {
3648  userName = userInfo;
3649  password.clear();
3650  return;
3651  }
3652  userName = userInfo.left(delimIndex);
3653  password = userInfo.right(userInfo.length() - delimIndex - 1);
3654 }
3655 
3657 {
3658  userName.clear();
3659  password.clear();
3660  if (!parseData->userInfoLength) {
3663  } else if (parseData->userInfoDelimIndex == -1) {
3664  encodedUserName = QByteArray(parseData->userInfo, parseData->userInfoLength);
3666  } else {
3667  encodedUserName = QByteArray(parseData->userInfo, parseData->userInfoDelimIndex);
3668  encodedPassword = QByteArray(parseData->userInfo + parseData->userInfoDelimIndex + 1,
3669  parseData->userInfoLength - parseData->userInfoDelimIndex - 1);
3670  }
3671 }
3672 
3673 QString QUrlPrivate::userInfo(QUrl::FormattingOptions options) const
3674 {
3675  if ((options & QUrl::RemoveUserInfo) == QUrl::RemoveUserInfo)
3676  return QString();
3677 
3678  QUrlPrivate *that = const_cast<QUrlPrivate *>(this);
3679  if (userName.isNull())
3681  if (password.isNull())
3683 
3684  QString tmp = userName;
3685 
3686  if (!(options & QUrl::RemovePassword) && !password.isEmpty()) {
3687  tmp += QLatin1Char(':');
3688  tmp += password;
3689  }
3690 
3691  return tmp;
3692 }
3693 
3694 /*
3695  From http://www.ietf.org/rfc/rfc3986.txt, 5.2.3: Merge paths
3696 
3697  Returns a merge of the current path with the relative path passed
3698  as argument.
3699 */
3701 {
3702  // Caller must lock mutex first
3703 
3704  if (encodedPath.isNull())
3706 
3707  // If the base URI has a defined authority component and an empty
3708  // path, then return a string consisting of "/" concatenated with
3709  // the reference's path; otherwise,
3710  if (!authority().isEmpty() && encodedPath.isEmpty())
3711  return '/' + relativePath;
3712 
3713  // Return a string consisting of the reference's path component
3714  // appended to all but the last segment of the base URI's path
3715  // (i.e., excluding any characters after the right-most "/" in the
3716  // base URI path, or excluding the entire base URI path if it does
3717  // not contain any "/" characters).
3718  QByteArray newPath;
3719  if (!encodedPath.contains('/'))
3720  newPath = relativePath;
3721  else
3722  newPath = encodedPath.left(encodedPath.lastIndexOf('/') + 1) + relativePath;
3723 
3724  return newPath;
3725 }
3726 
3727 void QUrlPrivate::queryItem(int pos, int *value, int *end)
3728 {
3729  *end = query.indexOf(pairDelimiter, pos);
3730  if (*end == -1)
3731  *end = query.size();
3732  *value = pos;
3733  while (*value < *end) {
3734  if (query[*value] == valueDelimiter)
3735  break;
3736  ++*value;
3737  }
3738 }
3739 
3740 /*
3741  From http://www.ietf.org/rfc/rfc3986.txt, 5.2.4: Remove dot segments
3742 
3743  Removes unnecessary ../ and ./ from the path. Used for normalizing
3744  the URL.
3745 */
3747 {
3748  // The input buffer is initialized with the now-appended path
3749  // components and the output buffer is initialized to the empty
3750  // string.
3751  char *out = path->data();
3752  const char *in = out;
3753  const char *end = out + path->size();
3754 
3755  // If the input buffer consists only of
3756  // "." or "..", then remove that from the input
3757  // buffer;
3758  if (path->size() == 1 && in[0] == '.')
3759  ++in;
3760  else if (path->size() == 2 && in[0] == '.' && in[1] == '.')
3761  in += 2;
3762  // While the input buffer is not empty, loop:
3763  while (in < end) {
3764 
3765  // otherwise, if the input buffer begins with a prefix of "../" or "./",
3766  // then remove that prefix from the input buffer;
3767  if (path->size() >= 2 && in[0] == '.' && in[1] == '/')
3768  in += 2;
3769  else if (path->size() >= 3 && in[0] == '.' && in[1] == '.' && in[2] == '/')
3770  in += 3;
3771 
3772  // otherwise, if the input buffer begins with a prefix of
3773  // "/./" or "/.", where "." is a complete path segment,
3774  // then replace that prefix with "/" in the input buffer;
3775  if (in <= end - 3 && in[0] == '/' && in[1] == '.' && in[2] == '/') {
3776  in += 2;
3777  continue;
3778  } else if (in == end - 2 && in[0] == '/' && in[1] == '.') {
3779  *out++ = '/';
3780  in += 2;
3781  break;
3782  }
3783 
3784  // otherwise, if the input buffer begins with a prefix
3785  // of "/../" or "/..", where ".." is a complete path
3786  // segment, then replace that prefix with "/" in the
3787  // input buffer and remove the last //segment and its
3788  // preceding "/" (if any) from the output buffer;
3789  if (in <= end - 4 && in[0] == '/' && in[1] == '.' && in[2] == '.' && in[3] == '/') {
3790  while (out > path->constData() && *(--out) != '/')
3791  ;
3792  if (out == path->constData() && *out != '/')
3793  ++in;
3794  in += 3;
3795  continue;
3796  } else if (in == end - 3 && in[0] == '/' && in[1] == '.' && in[2] == '.') {
3797  while (out > path->constData() && *(--out) != '/')
3798  ;
3799  if (*out == '/')
3800  ++out;
3801  in += 3;
3802  break;
3803  }
3804 
3805  // otherwise move the first path segment in
3806  // the input buffer to the end of the output
3807  // buffer, including the initial "/" character
3808  // (if any) and any subsequent characters up
3809  // to, but not including, the next "/"
3810  // character or the end of the input buffer.
3811  *out++ = *in++;
3812  while (in < end && *in != '/')
3813  *out++ = *in++;
3814  }
3815  path->truncate(out - path->constData());
3816 }
3817 
3819 {
3820  // Caller must lock mutex first
3821  QUrlPrivate *that = const_cast<QUrlPrivate *>(this);
3822  that->encodedOriginal = that->toEncoded(); // may detach
3823  parse(ParseOnly);
3824 
3826 
3827  if (!isValid)
3828  return;
3829 
3830  QString auth = authority(); // causes the non-encoded forms to be valid
3831 
3832  // authority() calls canonicalHost() which sets this
3833  if (!isHostValid)
3834  return;
3835 
3836  if (scheme == QLatin1String("mailto")) {
3837  if (!host.isEmpty() || port != -1 || !userName.isEmpty() || !password.isEmpty()) {
3838  that->isValid = false;
3839  that->errorInfo.setParams(0, QT_TRANSLATE_NOOP(QUrl, "expected empty host, username,"
3840  "port and password"),
3841  0, 0);
3842  }
3843  } else if (scheme == QLatin1String("ftp") || scheme == QLatin1String("http")) {
3844  if (host.isEmpty() && !(path.isEmpty() && encodedPath.isEmpty())) {
3845  that->isValid = false;
3846  that->errorInfo.setParams(0, QT_TRANSLATE_NOOP(QUrl, "the host is empty, but not the path"),
3847  0, 0);
3848  }
3849  }
3850 }
3851 
3852 void QUrlPrivate::parse(ParseOptions parseOptions) const
3853 {
3854  // Caller must lock mutex first
3855  QUrlPrivate *that = const_cast<QUrlPrivate *>(this);
3856  that->errorInfo.setParams(0, 0, 0, 0);
3857  if (encodedOriginal.isEmpty()) {
3858  that->isValid = false;
3859  that->errorInfo.setParams(0, QT_TRANSLATE_NOOP(QUrl, "empty"),
3860  0, 0);
3862  return;
3863  }
3864 
3865 
3866  QUrlParseData parseData;
3867  memset(&parseData, 0, sizeof(parseData));
3868  parseData.userInfoDelimIndex = -1;
3869  parseData.port = -1;
3870 
3871  const char *pptr = (char *) encodedOriginal.constData();
3872  const char **ptr = &pptr;
3873 
3874 #if defined (QURL_DEBUG)
3875  qDebug("QUrlPrivate::parse(), parsing \"%s\"", pptr);
3876 #endif
3877 
3878  // optional scheme
3879  bool isSchemeValid = _scheme(ptr, &parseData);
3880 
3881  if (isSchemeValid == false) {
3882  that->isValid = false;
3883  char ch = *((*ptr)++);
3884  that->errorInfo.setParams(*ptr, QT_TRANSLATE_NOOP(QUrl, "unexpected URL scheme"),
3885  0, ch);
3887 #if defined (QURL_DEBUG)
3888  qDebug("QUrlPrivate::parse(), unrecognized: %c%s", ch, *ptr);
3889 #endif
3890  return;
3891  }
3892 
3893  // hierpart
3894  _hierPart(ptr, &parseData);
3895 
3896  // optional query
3897  char ch = *((*ptr)++);
3898  if (ch == '?') {
3899  that->hasQuery = true;
3900  _query(ptr, &parseData);
3901  ch = *((*ptr)++);
3902  }
3903 
3904  // optional fragment
3905  if (ch == '#') {
3906  that->hasFragment = true;
3907  _fragment(ptr, &parseData);
3908  } else if (ch != '\0') {
3909  that->isValid = false;
3910  that->errorInfo.setParams(*ptr, QT_TRANSLATE_NOOP(QUrl, "expected end of URL"),
3911  0, ch);
3913 #if defined (QURL_DEBUG)
3914  qDebug("QUrlPrivate::parse(), unrecognized: %c%s", ch, *ptr);
3915 #endif
3916  return;
3917  }
3918 
3919  // when doing lazy validation, this function is called after
3920  // encodedOriginal has been constructed from the individual parts,
3921  // only to see if the constructed URL can be parsed. in that case,
3922  // parse() is called in ParseOnly mode; we don't want to set all
3923  // the members over again.
3924  if (parseOptions == ParseAndSet) {
3926 
3927  if (parseData.scheme) {
3928  QByteArray s(parseData.scheme, parseData.schemeLength);
3929  that->scheme = fromPercentEncodingMutable(&s);
3930  }
3931 
3932  that->setEncodedUserInfo(&parseData);
3933 
3934  QByteArray h(parseData.host, parseData.hostLength);
3935  that->host = fromPercentEncodingMutable(&h);
3936  that->port = uint(parseData.port) <= 0xffffU ? parseData.port : -1;
3937 
3938  that->path.clear();
3939  that->encodedPath = QByteArray(parseData.path, parseData.pathLength);
3940 
3941  if (that->hasQuery)
3942  that->query = QByteArray(parseData.query, parseData.queryLength);
3943  else
3944  that->query.clear();
3945 
3946  that->fragment.clear();
3947  if (that->hasFragment) {
3948  that->encodedFragment = QByteArray(parseData.fragment, parseData.fragmentLength);
3949  } else {
3950  that->encodedFragment.clear();
3951  }
3952  }
3953 
3954  that->isValid = true;
3955  QURL_SETFLAG(that->stateFlags, Parsed);
3956 
3957 #if defined (QURL_DEBUG)
3958  qDebug("QUrl::setUrl(), scheme = %s", that->scheme.toLatin1().constData());
3959  qDebug("QUrl::setUrl(), userInfo = %s", that->userInfo.toLatin1().constData());
3960  qDebug("QUrl::setUrl(), host = %s", that->host.toLatin1().constData());
3961  qDebug("QUrl::setUrl(), port = %i", that->port);
3962  qDebug("QUrl::setUrl(), path = %s", fromPercentEncodingHelper(__path).toLatin1().constData());
3963  qDebug("QUrl::setUrl(), query = %s", __query.constData());
3964  qDebug("QUrl::setUrl(), fragment = %s", fromPercentEncodingHelper(__fragment).toLatin1().constData());
3965 #endif
3966 }
3967 
3969 {
3970  scheme.clear();
3971  userName.clear();
3972  password.clear();
3973  host.clear();
3974  port = -1;
3975  path.clear();
3976  query.clear();
3977  fragment.clear();
3978 
3982  encodedPath.clear();
3985 
3986  isValid = false;
3987  hasQuery = false;
3988  hasFragment = false;
3989 
3990  valueDelimiter = '=';
3991  pairDelimiter = '&';
3992 
3994 }
3995 
3996 QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const
3997 {
3998  // Caller must lock mutex first
3999  if (!QURL_HASFLAG(stateFlags, Parsed)) parse();
4000  else ensureEncodedParts();
4001 
4002  if (options==0x100) // private - see qHash(QUrl)
4003  return normalized();
4004 
4005  QByteArray url;
4006 
4007  if (!(options & QUrl::RemoveScheme) && !scheme.isEmpty()) {
4008  url += scheme.toLatin1();
4009  url += ':';
4010  }
4011  QString savedHost = host; // pre-validation, may be invalid!
4012  QString auth = authority();
4013  bool doFileScheme = scheme == QLatin1String("file") && encodedPath.startsWith('/');
4014  if ((options & QUrl::RemoveAuthority) != QUrl::RemoveAuthority && (!auth.isNull() || doFileScheme || !savedHost.isEmpty())) {
4015  if (doFileScheme && !encodedPath.startsWith('/'))
4016  url += '/';
4017  url += "//";
4018 
4019  if ((options & QUrl::RemoveUserInfo) != QUrl::RemoveUserInfo) {
4020  bool hasUserOrPass = false;
4021  if (!userName.isEmpty()) {
4022  url += encodedUserName;
4023  hasUserOrPass = true;
4024  }
4025  if (!(options & QUrl::RemovePassword) && !password.isEmpty()) {
4026  url += ':';
4027  url += encodedPassword;
4028  hasUserOrPass = true;
4029  }
4030  if (hasUserOrPass)
4031  url += '@';
4032  }
4033 
4034  if (host.startsWith(QLatin1Char('['))) {
4035  url += host.toLatin1();
4036  } else if (host.contains(QLatin1Char(':'))) {
4037  url += '[';
4038  url += host.toLatin1();
4039  url += ']';
4040  } else if (host.isEmpty() && !savedHost.isEmpty()) {
4041  // this case is only possible with an invalid URL
4042  // it's here only so that we can keep the original, invalid hostname
4043  // in encodedOriginal.
4044  // QUrl::isValid() will return false, so toEncoded() can be anything (it's not valid)
4045  url += savedHost.toUtf8();
4046  } else {
4047  url += QUrl::toAce(host);
4048  }
4049  if (!(options & QUrl::RemovePort) && port != -1) {
4050  url += ':';
4051  url += QString::number(port).toAscii();
4052  }
4053  }
4054 
4055  if (!(options & QUrl::RemovePath)) {
4056  // check if we need to insert a slash
4057  if (!encodedPath.isEmpty() && !auth.isEmpty()) {
4058  if (!encodedPath.startsWith('/'))
4059  url += '/';
4060  }
4061  url += encodedPath;
4062 
4063  // check if we need to remove trailing slashes
4064  while ((options & QUrl::StripTrailingSlash) && url.endsWith('/'))
4065  url.chop(1);
4066  }
4067 
4068  if (!(options & QUrl::RemoveQuery) && hasQuery) {
4069  url += '?';
4070  url += query;
4071  }
4072  if (!(options & QUrl::RemoveFragment) && hasFragment) {
4073  url += '#';
4074  url += encodedFragment;
4075  }
4076 
4077  return url;
4078 }
4079 
4080 #define qToLower(ch) (((ch|32) >= 'a' && (ch|32) <= 'z') ? (ch|32) : ch)
4081 
4083 {
4084  // Caller must lock mutex first
4086  return encodedNormalized;
4087 
4088  QUrlPrivate *that = const_cast<QUrlPrivate *>(this);
4090 
4091  QUrlPrivate tmp = *this;
4092  tmp.scheme = tmp.scheme.toLower();
4093  tmp.host = tmp.canonicalHost();
4094 
4095  // ensure the encoded and normalized parts of the URL
4096  tmp.ensureEncodedParts();
4097  if (tmp.encodedUserName.contains('%'))
4099  if (tmp.encodedPassword.contains('%'))
4101  if (tmp.encodedFragment.contains('%'))
4103 
4104  if (tmp.encodedPath.contains('%')) {
4105  // the path is a bit special:
4106  // the slashes shouldn't be encoded or decoded.
4107  // They should remain exactly like they are right now
4108  //
4109  // treat the path as a slash-separated sequence of pchar
4110  QByteArray result;
4111  result.reserve(tmp.encodedPath.length());
4112  if (tmp.encodedPath.startsWith('/'))
4113  result.append('/');
4114 
4115  const char *data = tmp.encodedPath.constData();
4116  int lastSlash = 0;
4117  int nextSlash;
4118  do {
4119  ++lastSlash;
4120  nextSlash = tmp.encodedPath.indexOf('/', lastSlash);
4121  int len;
4122  if (nextSlash == -1)
4123  len = tmp.encodedPath.length() - lastSlash;
4124  else
4125  len = nextSlash - lastSlash;
4126 
4127  if (memchr(data + lastSlash, '%', len)) {
4128  // there's at least one percent before the next slash
4129  QByteArray block = QByteArray(data + lastSlash, len);
4131  result.append(block);
4132  } else {
4133  // no percents in this path segment, append wholesale
4134  result.append(data + lastSlash, len);
4135  }
4136 
4137  // append the slash too, if it's there
4138  if (nextSlash != -1)
4139  result.append('/');
4140 
4141  lastSlash = nextSlash;
4142  } while (lastSlash != -1);
4143 
4144  tmp.encodedPath = result;
4145  }
4146 
4147  if (!tmp.scheme.isEmpty()) // relative test
4149 
4150  int qLen = tmp.query.length();
4151  for (int i = 0; i < qLen; i++) {
4152  if (qLen - i > 2 && tmp.query.at(i) == '%') {
4153  ++i;
4154  tmp.query[i] = qToLower(tmp.query.at(i));
4155  ++i;
4156  tmp.query[i] = qToLower(tmp.query.at(i));
4157  }
4158  }
4159  encodedNormalized = tmp.toEncoded();
4160 
4161  return encodedNormalized;
4162 }
4163 
4165 {
4166  if (isValid && isHostValid)
4167  return QString();
4168 
4170  errorString += QLatin1String(encodedOriginal.constData());
4171  errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, "\""));
4172 
4173  if (errorInfo._source) {
4175  if (position > 0) {
4176  errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, ": error at position "));
4177  errorString += QString::number(position);
4178  } else {
4179  errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, ": "));
4180  errorString += QLatin1String(errorInfo._source);
4181  }
4182  }
4183 
4184  if (errorInfo._expected) {
4185  errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, ": expected \'"));
4186  errorString += QLatin1Char(errorInfo._expected);
4187  errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, "\'"));
4188  } else {
4189  errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, ": "));
4190  if (isHostValid)
4191  errorString += QLatin1String(errorInfo._message);
4192  else
4193  errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, "invalid hostname"));
4194  }
4195  if (errorInfo._found) {
4196  errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, ", but found \'"));
4197  errorString += QLatin1Char(errorInfo._found);
4198  errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, "\'"));
4199  }
4200  return errorString;
4201 }
4202 
4242 QUrl::QUrl(const QString &url) : d(0)
4243 {
4244  if (!url.isEmpty())
4245  setUrl(url);
4246 }
4247 
4259 QUrl::QUrl(const QString &url, ParsingMode parsingMode) : d(0)
4260 {
4261  if (!url.isEmpty())
4262  setUrl(url, parsingMode);
4263  else {
4264  d = new QUrlPrivate;
4265  d->parsingMode = parsingMode;
4266  }
4267 }
4268 
4273 {
4274 }
4275 
4279 QUrl::QUrl(const QUrl &other) : d(other.d)
4280 {
4281  if (d)
4282  d->ref.ref();
4283 }
4284 
4289 {
4290  if (d && !d->ref.deref())
4291  delete d;
4292 }
4293 
4303 bool QUrl::isValid() const
4304 {
4305  if (!d) return false;
4306 
4307  QMutexLocker lock(&d->mutex);
4310 
4311  return d->isValid && d->isHostValid;
4312 }
4313 
4317 bool QUrl::isEmpty() const
4318 {
4319  if (!d) return true;
4320 
4321  QMutexLocker lock(&d->mutex);
4323  return d->encodedOriginal.isEmpty();
4324  else
4325  return d->scheme.isEmpty() // no encodedScheme
4328  && d->host.isEmpty() // no encodedHost
4329  && d->port == -1
4330  && d->path.isEmpty() && d->encodedPath.isEmpty()
4331  && d->query.isEmpty()
4332  && d->fragment.isEmpty() && d->encodedFragment.isEmpty();
4333 }
4334 
4341 {
4342  if (d && !d->ref.deref())
4343  delete d;
4344  d = 0;
4345 }
4346 
4358 void QUrl::setUrl(const QString &url)
4359 {
4360  setUrl(url, TolerantMode);
4361 }
4362 
4373 void QUrl::setUrl(const QString &url, ParsingMode parsingMode)
4374 {
4375  if (!d) d = new QUrlPrivate;
4376  QMutexLocker lock(&d->mutex);
4377  detach(lock);
4378  d->clear();
4379 
4380  // escape all reserved characters and delimiters
4381  // reserved = gen-delims / sub-delims
4382  if (parsingMode != TolerantMode) {
4384  return;
4385  }
4386 
4387  // Tolerant preprocessing
4388  QString tmp = url;
4389 
4390  // Allow %20 in the QString variant
4391  tmp.replace(QLatin1String("%20"), QLatin1String(" "));
4392 
4393  // Percent-encode unsafe ASCII characters after host part
4394  int start = tmp.indexOf(QLatin1String("//"));
4395  if (start != -1) {
4396  // Has host part, find delimiter
4397  start += 2; // skip "//"
4398  const char delims[] = "/#?";
4399  const char *d = delims;
4400  int hostEnd = -1;
4401  while (*d && (hostEnd = tmp.indexOf(QLatin1Char(*d), start)) == -1)
4402  ++d;
4403  start = (hostEnd == -1) ? -1 : hostEnd + 1;
4404  } else {
4405  start = 0; // Has no host part
4406  }
4407  QByteArray encodedUrl;
4408  if (start != -1) {
4409  QString hostPart = tmp.left(start);
4410  QString otherPart = tmp.mid(start);
4411  encodedUrl = toPercentEncodingHelper(hostPart, ":/?#[]@!$&'()*+,;=")
4412  + toPercentEncodingHelper(otherPart, ":/?#@!$&'()*+,;=");
4413  } else {
4414  encodedUrl = toPercentEncodingHelper(tmp, ABNF_reserved);
4415  }
4416  d->setEncodedUrl(encodedUrl, StrictMode);
4417 }
4418 
4429 void QUrl::setEncodedUrl(const QByteArray &encodedUrl)
4430 {
4431  setEncodedUrl(encodedUrl, TolerantMode);
4432 }
4433 
4434 inline static bool isHex(char c)
4435 {
4436  c |= 0x20;
4437  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
4438 }
4439 
4440 static inline char toHex(quint8 c)
4441 {
4442  return c > 9 ? c - 10 + 'A' : c + '0';
4443 }
4444 
4449 void QUrl::setEncodedUrl(const QByteArray &encodedUrl, ParsingMode parsingMode)
4450 {
4451  if (!d) d = new QUrlPrivate;
4452  QMutexLocker lock(&d->mutex);
4453  detach(lock);
4454  d->clear();
4455  d->setEncodedUrl(encodedUrl, parsingMode);
4456 }
4457 
4458 void QUrlPrivate::setEncodedUrl(const QByteArray &encodedUrl, QUrl::ParsingMode parsingMode)
4459 {
4460  // Caller must lock mutex first
4461  QByteArray tmp = encodedUrl;
4462  if ((this->parsingMode = parsingMode) == QUrl::TolerantMode) {
4463  // Replace stray % with %25
4464  QByteArray copy = tmp;
4465  for (int i = 0, j = 0; i < copy.size(); ++i, ++j) {
4466  if (copy.at(i) == '%') {
4467  if (i + 2 >= copy.size() || !isHex(copy.at(i + 1)) || !isHex(copy.at(i + 2))) {
4468  tmp.replace(j, 1, "%25");
4469  j += 2;
4470  }
4471  }
4472  }
4473 
4474  // Find the host part
4475  int hostStart = tmp.indexOf("//");
4476  int hostEnd = -1;
4477  if (hostStart != -1) {
4478  // Has host part, find delimiter
4479  hostStart += 2; // skip "//"
4480  hostEnd = tmp.indexOf('/', hostStart);
4481  if (hostEnd == -1)
4482  hostEnd = tmp.indexOf('#', hostStart);
4483  if (hostEnd == -1)
4484  hostEnd = tmp.indexOf('?');
4485  if (hostEnd == -1)
4486  hostEnd = tmp.length() - 1;
4487  }
4488 
4489  // Reserved and unreserved characters are fine
4490 // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
4491 // reserved = gen-delims / sub-delims
4492 // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
4493 // sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
4494 // / "*" / "+" / "," / ";" / "="
4495  // Replace everything else with percent encoding
4496  static const char doEncode[] = " \"<>[\\]^`{|}";
4497  static const char doEncodeHost[] = " \"<>\\^`{|}";
4498  for (int i = 0; i < tmp.size(); ++i) {
4499  quint8 c = quint8(tmp.at(i));
4500  if (c < 32 || c > 127 ||
4501  strchr(hostStart <= i && i <= hostEnd ? doEncodeHost : doEncode, c)) {
4502  char buf[4];
4503  buf[0] = '%';
4504  buf[1] = toHex(c >> 4);
4505  buf[2] = toHex(c & 0xf);
4506  buf[3] = '\0';
4507  tmp.replace(i, 1, buf);
4508  i += 2;
4509  }
4510  }
4511  }
4512 
4513  encodedOriginal = tmp;
4514 }
4515 
4534 {
4535  if (!d) d = new QUrlPrivate;
4536  QMutexLocker lock(&d->mutex);
4538  detach(lock);
4540 
4541  d->scheme = scheme;
4542 }
4543 
4551 {
4552  if (!d) return QString();
4553  QMutexLocker lock(&d->mutex);
4555 
4556  return d->scheme;
4557 }
4558 
4576 {
4577  if (!d) d = new QUrlPrivate;
4578 
4579  QMutexLocker lock(&d->mutex);
4581  detach(lock);
4583  d->setAuthority(authority);
4584 }
4585 
4593 {
4594  if (!d) return QString();
4595 
4596  QMutexLocker lock(&d->mutex);
4598 
4599  return d->authority();
4600 }
4601 
4616 {
4617  if (!d) d = new QUrlPrivate;
4618 
4619  QMutexLocker lock(&d->mutex);
4621  detach(lock);
4623 
4624  d->setUserInfo(userInfo.trimmed());
4625 }
4626 
4632 {
4633  if (!d) return QString();
4634 
4635  QMutexLocker lock(&d->mutex);
4637 
4638  return d->userInfo();
4639 }
4640 
4649 {
4650  if (!d) d = new QUrlPrivate;
4651 
4652  QMutexLocker lock(&d->mutex);
4654  detach(lock);
4656 
4657  d->userName = userName;
4658  d->encodedUserName.clear();
4659 }
4660 
4668 {
4669  if (!d) return QString();
4670 
4671  QMutexLocker lock(&d->mutex);
4673 
4674  d->userInfo(); // causes the unencoded form to be set
4675  return d->userName;
4676 }
4677 
4695 {
4696  if (!d) d = new QUrlPrivate;
4697  QMutexLocker lock(&d->mutex);
4699  detach(lock);
4701 
4703  d->userName.clear();
4704 }
4705 
4720 {
4721  if (!d) return QByteArray();
4722  QMutexLocker lock(&d->mutex);
4724 
4725  d->ensureEncodedParts();
4726  return d->encodedUserName;
4727 }
4728 
4737 {
4738  if (!d) d = new QUrlPrivate;
4739  QMutexLocker lock(&d->mutex);
4741  detach(lock);
4743 
4744  d->password = password;
4745  d->encodedPassword.clear();
4746 }
4747 
4755 {
4756  if (!d) return QString();
4757  QMutexLocker lock(&d->mutex);
4759 
4760  d->userInfo(); // causes the unencoded form to be set
4761  return d->password;
4762 }
4763 
4781 {
4782  if (!d) d = new QUrlPrivate;
4783  QMutexLocker lock(&d->mutex);
4785  detach(lock);
4787 
4789  d->password.clear();
4790 }
4791 
4806 {
4807  if (!d) return QByteArray();
4808  QMutexLocker lock(&d->mutex);
4810 
4811  d->ensureEncodedParts();
4812  return d->encodedPassword;
4813 }
4814 
4822 {
4823  if (!d) d = new QUrlPrivate;
4824  QMutexLocker lock(&d->mutex);
4826  detach(lock);
4827  d->isHostValid = true;
4829 
4830  d->host = host;
4831 }
4832 
4838 {
4839  if (!d) return QString();
4840  QMutexLocker lock(&d->mutex);
4842 
4843  QString result = d->canonicalHost();
4844  if (result.startsWith(QLatin1Char('[')))
4845  return result.mid(1, result.length() - 2);
4846  return result;
4847 }
4848 
4862 {
4864 }
4865 
4885 {
4886  // should we cache this in d->encodedHost?
4887  return QUrl::toAce(host());
4888 }
4889 
4898 {
4899  if (!d) d = new QUrlPrivate;
4900  QMutexLocker lock(&d->mutex);
4902  detach(lock);
4904 
4905  if (port < -1 || port > 65535) {
4906  qWarning("QUrl::setPort: Out of range");
4907  port = -1;
4908  }
4909 
4910  d->port = port;
4911 }
4912 
4916 int QUrl::port() const
4917 {
4918  if (!d) return -1;
4919  QMutexLocker lock(&d->mutex);
4922  return d->port;
4923 }
4924 
4939 int QUrl::port(int defaultPort) const
4940 {
4941  if (!d) return defaultPort;
4942  QMutexLocker lock(&d->mutex);
4944  return d->port == -1 ? defaultPort : d->port;
4945 }
4946 
4961 {
4962  if (!d) d = new QUrlPrivate;
4963  QMutexLocker lock(&d->mutex);
4965  detach(lock);
4967 
4968  d->path = path;
4969  d->encodedPath.clear();
4970 }
4971 
4978 {
4979  if (!d) return QString();
4980  QMutexLocker lock(&d->mutex);
4982 
4983  if (d->path.isNull()) {
4984  QUrlPrivate *that = const_cast<QUrlPrivate *>(d);
4986  }
4987  return d->path;
4988 }
4989 
5014 {
5015  if (!d) d = new QUrlPrivate;
5016  QMutexLocker lock(&d->mutex);
5018  detach(lock);
5020 
5021  d->encodedPath = path;
5022  d->path.clear();
5023 }
5024 
5039 {
5040  if (!d) return QByteArray();
5041  QMutexLocker lock(&d->mutex);
5043 
5044  d->ensureEncodedParts();
5045  return d->encodedPath;
5046 }
5047 
5058 bool QUrl::hasQuery() const
5059 {
5060  if (!d) return false;
5061  QMutexLocker lock(&d->mutex);
5063 
5064  return d->hasQuery;
5065 }
5066 
5089 void QUrl::setQueryDelimiters(char valueDelimiter, char pairDelimiter)
5090 {
5091  if (!d) d = new QUrlPrivate;
5092  QMutexLocker lock(&d->mutex);
5093  detach(lock);
5094 
5095  d->valueDelimiter = valueDelimiter;
5096  d->pairDelimiter = pairDelimiter;
5097 }
5098 
5104 {
5105  if (!d) return '&';
5106  return d->pairDelimiter;
5107 }
5108 
5114 {
5115  if (!d) return '=';
5116  return d->valueDelimiter;
5117 }
5118 
5137 {
5138  if (!d) d = new QUrlPrivate;
5139  QMutexLocker lock(&d->mutex);
5141  detach(lock);
5143 
5144  d->query = query;
5145  d->hasQuery = !query.isNull();
5146 }
5147 
5162 {
5163  if (!d) d = new QUrlPrivate;
5164  QMutexLocker lock(&d->mutex);
5166  detach(lock);
5167 
5168  char alsoEncode[3];
5169  alsoEncode[0] = d->valueDelimiter;
5170  alsoEncode[1] = d->pairDelimiter;
5171  alsoEncode[2] = 0;
5172 
5173  QByteArray queryTmp;
5174  for (int i = 0; i < query.size(); i++) {
5175  if (i) queryTmp += d->pairDelimiter;
5176  // query = *( pchar / "/" / "?" )
5177  queryTmp += toPercentEncodingHelper(query.at(i).first, queryExcludeChars, alsoEncode);
5178  queryTmp += d->valueDelimiter;
5179  // query = *( pchar / "/" / "?" )
5180  queryTmp += toPercentEncodingHelper(query.at(i).second, queryExcludeChars, alsoEncode);
5181  }
5182 
5183  d->query = queryTmp;
5184  d->hasQuery = !query.isEmpty();
5185 }
5186 
5206 {
5207  if (!d) d = new QUrlPrivate;
5208  QMutexLocker lock(&d->mutex);
5210  detach(lock);
5211 
5212  QByteArray queryTmp;
5213  for (int i = 0; i < query.size(); i++) {
5214  if (i) queryTmp += d->pairDelimiter;
5215  queryTmp += query.at(i).first;
5216  queryTmp += d->valueDelimiter;
5217  queryTmp += query.at(i).second;
5218  }
5219 
5220  d->query = queryTmp;
5221  d->hasQuery = !query.isEmpty();
5222 }
5223 
5240 void QUrl::addQueryItem(const QString &key, const QString &value)
5241 {
5242  if (!d) d = new QUrlPrivate;
5243  QMutexLocker lock(&d->mutex);
5245  detach(lock);
5246 
5247  char alsoEncode[3];
5248  alsoEncode[0] = d->valueDelimiter;
5249  alsoEncode[1] = d->pairDelimiter;
5250  alsoEncode[2] = 0;
5251 
5252  if (!d->query.isEmpty())
5253  d->query += d->pairDelimiter;
5254 
5255  // query = *( pchar / "/" / "?" )
5256  d->query += toPercentEncodingHelper(key, queryExcludeChars, alsoEncode);
5257  d->query += d->valueDelimiter;
5258  // query = *( pchar / "/" / "?" )
5259  d->query += toPercentEncodingHelper(value, queryExcludeChars, alsoEncode);
5260 
5261  d->hasQuery = !d->query.isEmpty();
5262 }
5263 
5280 {
5281  if (!d) d = new QUrlPrivate;
5282  QMutexLocker lock(&d->mutex);
5284  detach(lock);
5285 
5286  if (!d->query.isEmpty())
5287  d->query += d->pairDelimiter;
5288 
5289  d->query += key;
5290  d->query += d->valueDelimiter;
5291  d->query += value;
5292 
5293  d->hasQuery = !d->query.isEmpty();
5294 }
5295 
5306 {
5307  if (!d) return QList<QPair<QString, QString> >();
5308  QMutexLocker lock(&d->mutex);
5310 
5312 
5313  int pos = 0;
5314  const char *query = d->query.constData();
5315  while (pos < d->query.size()) {
5316  int valuedelim, end;
5317  d->queryItem(pos, &valuedelim, &end);
5318  QByteArray q(query + pos, valuedelim - pos);
5319  if (valuedelim < end) {
5320  QByteArray v(query + valuedelim + 1, end - valuedelim - 1);
5321  itemMap += qMakePair(fromPercentEncodingMutable(&q),
5323  } else {
5324  itemMap += qMakePair(fromPercentEncodingMutable(&q), QString());
5325  }
5326  pos = end + 1;
5327  }
5328 
5329  return itemMap;
5330 }
5331 
5343 {
5344  if (!d) return QList<QPair<QByteArray, QByteArray> >();
5345  QMutexLocker lock(&d->mutex);
5347 
5349 
5350  int pos = 0;
5351  const char *query = d->query.constData();
5352  while (pos < d->query.size()) {
5353  int valuedelim, end;
5354  d->queryItem(pos, &valuedelim, &end);
5355  if (valuedelim < end)
5356  itemMap += qMakePair(QByteArray(query + pos, valuedelim - pos),
5357  QByteArray(query + valuedelim + 1, end - valuedelim - 1));
5358  else
5359  itemMap += qMakePair(QByteArray(query + pos, valuedelim - pos), QByteArray());
5360  pos = end + 1;
5361  }
5362 
5363  return itemMap;
5364 }
5365 
5372 bool QUrl::hasQueryItem(const QString &key) const
5373 {
5374  if (!d) return false;
5376 }
5377 
5395 {
5396  if (!d) return false;
5397  QMutexLocker lock(&d->mutex);
5399 
5400  int pos = 0;
5401  const char *query = d->query.constData();
5402  while (pos < d->query.size()) {
5403  int valuedelim, end;
5404  d->queryItem(pos, &valuedelim, &end);
5405  if (key == QByteArray::fromRawData(query + pos, valuedelim - pos))
5406  return true;
5407  pos = end + 1;
5408  }
5409  return false;
5410 }
5411 
5423 {
5424  if (!d) return QString();
5426  return fromPercentEncodingMutable(&tmp);
5427 }
5428 
5446 {
5447  if (!d) return QByteArray();
5448  QMutexLocker lock(&d->mutex);
5450 
5451  int pos = 0;
5452  const char *query = d->query.constData();
5453  while (pos < d->query.size()) {
5454  int valuedelim, end;
5455  d->queryItem(pos, &valuedelim, &end);
5456  if (key == QByteArray::fromRawData(query + pos, valuedelim - pos))
5457  return valuedelim < end ?
5458  QByteArray(query + valuedelim + 1, end - valuedelim - 1) : QByteArray();
5459  pos = end + 1;
5460  }
5461  return QByteArray();
5462 }
5463 
5475 {
5476  if (!d) return QStringList();
5477  QMutexLocker lock(&d->mutex);
5479 
5480  QByteArray encodedKey = toPercentEncoding(key, queryExcludeChars);
5482 
5483  int pos = 0;
5484  const char *query = d->query.constData();
5485  while (pos < d->query.size()) {
5486  int valuedelim, end;
5487  d->queryItem(pos, &valuedelim, &end);
5488  if (encodedKey == QByteArray::fromRawData(query + pos, valuedelim - pos)) {
5489  QByteArray v(query + valuedelim + 1, end - valuedelim - 1);
5490  values += valuedelim < end ?
5492  : QString();
5493  }
5494  pos = end + 1;
5495  }
5496 
5497  return values;
5498 }
5499 
5517 {
5518  if (!d) return QList<QByteArray>();
5519  QMutexLocker lock(&d->mutex);
5521 
5523 
5524  int pos = 0;
5525  const char *query = d->query.constData();
5526  while (pos < d->query.size()) {
5527  int valuedelim, end;
5528  d->queryItem(pos, &valuedelim, &end);
5529  if (key == QByteArray::fromRawData(query + pos, valuedelim - pos))
5530  values += valuedelim < end ?
5531  QByteArray(query + valuedelim + 1, end - valuedelim - 1)
5532  : QByteArray();
5533  pos = end + 1;
5534  }
5535 
5536  return values;
5537 }
5538 
5546 {
5547  if (!d) return;
5549 }
5550 
5568 {
5569  if (!d) return;
5570  QMutexLocker lock(&d->mutex);
5572  detach(lock);
5573 
5574  int pos = 0;
5575  const char *query = d->query.constData();
5576  while (pos < d->query.size()) {
5577  int valuedelim, end;
5578  d->queryItem(pos, &valuedelim, &end);
5579  if (key == QByteArray::fromRawData(query + pos, valuedelim - pos)) {
5580  if (end < d->query.size())
5581  ++end; // remove additional '%'
5582  d->query.remove(pos, end - pos);
5583  return;
5584  }
5585  pos = end + 1;
5586  }
5587 }
5588 
5596 {
5597  if (!d) return;
5599 }
5600 
5618 {
5619  if (!d) return;
5620  QMutexLocker lock(&d->mutex);
5622  detach(lock);
5623 
5624  int pos = 0;
5625  const char *query = d->query.constData();
5626  while (pos < d->query.size()) {
5627  int valuedelim, end;
5628  d->queryItem(pos, &valuedelim, &end);
5629  if (key == QByteArray::fromRawData(query + pos, valuedelim - pos)) {
5630  if (end < d->query.size())
5631  ++end; // remove additional '%'
5632  d->query.remove(pos, end - pos);
5633  query = d->query.constData(); //required if remove detach;
5634  } else {
5635  pos = end + 1;
5636  }
5637  }
5638 }
5639 
5644 {
5645  if (!d) return QByteArray();
5646  QMutexLocker lock(&d->mutex);
5648 
5649  return d->query;
5650 }
5651 
5670 {
5671  if (!d) d = new QUrlPrivate;
5672  QMutexLocker lock(&d->mutex);
5674  detach(lock);
5676 
5677  d->fragment = fragment;
5678  d->hasFragment = !fragment.isNull();
5679  d->encodedFragment.clear();
5680 }
5681 
5688 {
5689  if (!d) return QString();
5690  QMutexLocker lock(&d->mutex);
5692 
5693  return d->fragmentImpl();
5694 }
5695 
5697 {
5698  if (fragment.isNull() && !encodedFragment.isNull()) {
5699  QUrlPrivate *that = const_cast<QUrlPrivate *>(this);
5701  }
5702  return fragment;
5703 }
5704 
5728 {
5729  if (!d) d = new QUrlPrivate;
5730  QMutexLocker lock(&d->mutex);
5732  detach(lock);
5734 
5736  d->hasFragment = !fragment.isNull();
5737  d->fragment.clear();
5738 }
5739 
5754 {
5755  if (!d) return QByteArray();
5756  QMutexLocker lock(&d->mutex);
5758 
5759  d->ensureEncodedParts();
5760  return d->encodedFragment;
5761 }
5762 
5773 bool QUrl::hasFragment() const
5774 {
5775  if (!d) return false;
5776  QMutexLocker lock(&d->mutex);
5778 
5779  return d->hasFragment;
5780 }
5781 
5793 #ifndef QT_BOOTSTRAPPED
5795 {
5796  return qTopLevelDomain(host());
5797 }
5798 #endif
5799 
5819 QUrl QUrl::resolved(const QUrl &relative) const
5820 {
5821  if (!d) return relative;
5822  if (!relative.d) return *this;
5823 
5824  QOrderedMutexLocker locker(&d->mutex, &relative.d->mutex);
5825 
5827  if (!QURL_HASFLAG(relative.d->stateFlags, QUrlPrivate::Parsed))
5828  relative.d->parse();
5829 
5830  d->ensureEncodedParts();
5831  relative.d->ensureEncodedParts();
5832 
5833  QUrl t;
5834  // be non strict and allow scheme in relative url
5835  if (!relative.d->scheme.isEmpty() && relative.d->scheme != d->scheme) {
5836  t = relative;
5837  // t.detach(locker) would unlock, so bypass it
5838  qAtomicDetach(t.d);
5839  } else {
5840  if (!relative.d->authority().isEmpty()) {
5841  t = relative;
5842  qAtomicDetach(t.d);
5843  } else {
5844  t.d = new QUrlPrivate;
5845  if (relative.d->encodedPath.isEmpty()) {
5846  t.d->encodedPath = d->encodedPath;
5847  t.d->query = relative.d->hasQuery ? relative.d->query : d->query;
5848  } else {
5849  t.d->encodedPath = relative.d->encodedPath.at(0) == '/'
5850  ? relative.d->encodedPath
5851  : d->mergePaths(relative.d->encodedPath);
5852  t.d->query = relative.d->query;
5853  }
5854  t.d->hasQuery = !t.d->query.isNull();
5857  t.d->host = d->host;
5858  t.d->port = d->port;
5859  }
5860  t.setScheme(d->scheme);
5861  }
5862  t.setFragment(relative.d->fragmentImpl());
5864  t.d->path.clear();
5865 
5866 #if defined(QURL_DEBUG)
5867  qDebug("QUrl(\"%s\").resolved(\"%s\") = \"%s\"",
5868  d->toEncoded().constData(),
5869  relative.d->toEncoded().constData(),
5870  t.toEncoded().constData());
5871 #endif
5872  return t;
5873 }
5874 
5880 bool QUrl::isRelative() const
5881 {
5882  if (!d) return true;
5883  QMutexLocker lock(&d->mutex);
5885 
5886  return d->scheme.isEmpty();
5887 }
5888 
5896 QString QUrl::toString(FormattingOptions options) const
5897 {
5898  if (!d) return QString();
5899  QString ourPath = path();
5900  QMutexLocker lock(&d->mutex);
5902 
5903  QString url;
5904 
5905  if (!(options & QUrl::RemoveScheme) && !d->scheme.isEmpty())
5906  url += d->scheme + QLatin1Char(':');
5907  if ((options & QUrl::RemoveAuthority) != QUrl::RemoveAuthority) {
5908  bool doFileScheme = d->scheme == QLatin1String("file") && ourPath.startsWith(QLatin1Char('/'));
5909  QString tmp = d->authority(options);
5910  if (!tmp.isNull() || doFileScheme) {
5911  if (doFileScheme && !ourPath.startsWith(QLatin1Char('/')))
5912  url += QLatin1Char('/');
5913  url += QLatin1String("//");
5914  url += tmp;
5915  }
5916  }
5917  if (!(options & QUrl::RemovePath)) {
5918  // check if we need to insert a slash
5919  if ((options & QUrl::RemoveAuthority) != QUrl::RemoveAuthority
5920  && !d->authority(options).isEmpty() && !ourPath.isEmpty() && ourPath.at(0) != QLatin1Char('/'))
5921  url += QLatin1Char('/');
5922  url += ourPath;
5923  // check if we need to remove trailing slashes
5924  while ((options & StripTrailingSlash) && url.endsWith(QLatin1Char('/')))
5925  url.chop(1);
5926  }
5927 
5928  if (!(options & QUrl::RemoveQuery) && d->hasQuery) {
5929  url += QLatin1Char('?');
5930  url += fromPercentEncoding(d->query);
5931  }
5932  if (!(options & QUrl::RemoveFragment) && d->hasFragment) {
5933  url += QLatin1Char('#');
5934  url += d->fragmentImpl();
5935  }
5936 
5937  return url;
5938 }
5939 
5949 QByteArray QUrl::toEncoded(FormattingOptions options) const
5950 {
5951  if (!d) return QByteArray();
5952  QMutexLocker lock(&d->mutex);
5953  return d->toEncoded(options);
5954 }
5955 
5965 {
5966  QUrl tmp;
5967  tmp.setEncodedUrl(input, TolerantMode);
5968  return tmp;
5969 }
5970 
5981 QUrl QUrl::fromEncoded(const QByteArray &input, ParsingMode parsingMode)
5982 {
5983  QUrl tmp;
5984  tmp.setEncodedUrl(input, parsingMode);
5985  return tmp;
5986 }
5987 
5993 {
5994  return fromPercentEncodingHelper(input);
5995 }
5996 
6009 QByteArray QUrl::toPercentEncoding(const QString &input, const QByteArray &exclude, const QByteArray &include)
6010 {
6011  return toPercentEncodingHelper(input, exclude.constData(), include.constData());
6012 }
6013 
6026 {
6027  QString output;
6028  toPunycodeHelper(uc.constData(), uc.size(), &output);
6029  return output.toLatin1();
6030 }
6031 
6045 {
6046  uint n = initial_n;
6047  uint i = 0;
6048  uint bias = initial_bias;
6049 
6050  // strip any ACE prefix
6051  int start = pc.startsWith("xn--") ? 4 : 0;
6052  if (!start)
6053  return QString::fromLatin1(pc);
6054 
6055  // find the last delimiter character '-' in the input array. copy
6056  // all data before this delimiter directly to the output array.
6057  int delimiterPos = pc.lastIndexOf(0x2d);
6058  QString output = delimiterPos < 4 ?
6059  QString() : QString::fromLatin1(pc.constData() + start, delimiterPos - start);
6060 
6061  // if a delimiter was found, skip to the position after it;
6062  // otherwise start at the front of the input string. everything
6063  // before the delimiter is assumed to be basic code points.
6064  uint cnt = delimiterPos + 1;
6065 
6066  // loop through the rest of the input string, inserting non-basic
6067  // characters into output as we go.
6068  while (cnt < (uint) pc.size()) {
6069  uint oldi = i;
6070  uint w = 1;
6071 
6072  // find the next index for inserting a non-basic character.
6073  for (uint k = base; cnt < (uint) pc.size(); k += base) {
6074  // grab a character from the punycode input and find its
6075  // delta digit (each digit code is part of the
6076  // variable-length integer delta)
6077  uint digit = pc.at(cnt++);
6078  if (digit - 48 < 10) digit -= 22;
6079  else if (digit - 65 < 26) digit -= 65;
6080  else if (digit - 97 < 26) digit -= 97;
6081  else digit = base;
6082 
6083  // reject out of range digits
6084  if (digit >= base || digit > (Q_MAXINT - i) / w)
6085  return QLatin1String("");
6086 
6087  i += (digit * w);
6088 
6089  // detect threshold to stop reading delta digits
6090  uint t;
6091  if (k <= bias) t = tmin;
6092  else if (k >= bias + tmax) t = tmax;
6093  else t = k - bias;
6094  if (digit < t) break;
6095 
6096  w *= (base - t);
6097  }
6098 
6099  // find new bias and calculate the next non-basic code
6100  // character.
6101  bias = adapt(i - oldi, output.length() + 1, oldi == 0);
6102  n += i / (output.length() + 1);
6103 
6104  // allow the deltas to wrap around
6105  i %= (output.length() + 1);
6106 
6107  // insert the character n at position i
6108  output.insert((uint) i, QChar((ushort) n));
6109  ++i;
6110  }
6111 
6112  return output;
6113 }
6114 
6135 {
6136  return qt_ACE_do(QString::fromLatin1(domain), NormalizeAce);
6137 }
6138 
6159 {
6160  QString result = qt_ACE_do(domain, ToAceOnly);
6161  return result.toLatin1();
6162 }
6163 
6176 {
6177  if (user_idn_whitelist)
6178  return *user_idn_whitelist;
6179  QStringList list;
6180  unsigned int i = 0;
6181  while (i < sizeof(idn_whitelist)/sizeof(const char *)) {
6182  list << QLatin1String(idn_whitelist[i]);
6183  ++i;
6184  }
6185  return list;
6186 }
6187 
6213 {
6214  if (!user_idn_whitelist)
6215  user_idn_whitelist = new QStringList;
6216  *user_idn_whitelist = list;
6217 }
6218 
6228 bool QUrl::operator <(const QUrl &url) const
6229 {
6230  QOrderedMutexLocker(d ? &d->mutex : 0, url.d ? &url.d->mutex : 0);
6231  if (!d) return url.d ? QByteArray() < url.d->normalized() : false;
6233  if (!url.d) return d->normalized() < QByteArray();
6234  if (!QURL_HASFLAG(url.d->stateFlags, QUrlPrivate::Parsed)) url.d->parse();
6235  return d->normalized() < url.d->normalized();
6236 }
6237 
6242 bool QUrl::operator ==(const QUrl &url) const
6243 {
6244  if (!d) return url.isEmpty();
6245  if (!url.d) return isEmpty();
6246  QOrderedMutexLocker(&d->mutex, &url.d->mutex);
6248  if (!QURL_HASFLAG(url.d->stateFlags, QUrlPrivate::Parsed)) url.d->parse();
6249  return d->normalized() == url.d->normalized();
6250 }
6251 
6256 bool QUrl::operator !=(const QUrl &url) const
6257 {
6258  return !(*this == url);
6259 }
6260 
6265 {
6266  if (!d) {
6267  if (url.d) {
6268  url.d->ref.ref();
6269  d = url.d;
6270  }
6271  } else {
6272  if (url.d)
6273  qAtomicAssign(d, url.d);
6274  else
6275  clear();
6276  }
6277  return *this;
6278 }
6279 
6284 {
6285  if (url.isEmpty()) {
6286  clear();
6287  } else {
6288  QUrl tmp(url);
6289  if (!d) d = new QUrlPrivate;
6290  qAtomicAssign(d, tmp.d);
6291  }
6292  return *this;
6293 }
6294 
6314 {
6315  if (!d) {
6316  d = new QUrlPrivate;
6317  } else {
6318  // Public method, so it must lock first.
6319  QMutexLocker lock(&d->mutex);
6320  detach(lock);
6321  }
6322 }
6323 
6324 
6337 {
6338  Q_ASSERT(d); // we have a locker, so we have a d pointer
6339  // Ensure that we hold the mutex until after making our private copy,
6340  // so that another thread cannot deref + delete d meanwhile.
6341  // So this is a modified version of qAtomicDetach(d)
6342  if (d->ref == 1) {
6343  locker.unlock();
6344  return;
6345  }
6346  QUrlPrivate * x = d;
6347  d = new QUrlPrivate(*x);
6348  locker.unlock();
6349  if (!x->ref.deref())
6350  delete x;
6351 }
6352 
6356 bool QUrl::isDetached() const
6357 {
6358  return !d || d->ref == 1;
6359 }
6360 
6361 
6375 {
6376  QUrl url;
6377  url.setScheme(QLatin1String("file"));
6378  QString deslashified = QDir::fromNativeSeparators(localFile);
6379 
6380  // magic for drives on windows
6381  if (deslashified.length() > 1 && deslashified.at(1) == QLatin1Char(':') && deslashified.at(0) != QLatin1Char('/')) {
6382  url.setPath(QLatin1Char('/') + deslashified);
6383  // magic for shared drive on windows
6384  } else if (deslashified.startsWith(QLatin1String("//"))) {
6385  int indexOfPath = deslashified.indexOf(QLatin1Char('/'), 2);
6386  url.setHost(deslashified.mid(2, indexOfPath - 2));
6387  if (indexOfPath > 2)
6388  url.setPath(deslashified.right(deslashified.length() - indexOfPath));
6389  } else {
6390  url.setPath(deslashified);
6391  }
6392 
6393  return url;
6394 }
6395 
6413 {
6414  if (!d) return QString();
6415 
6416  // the call to isLocalFile() also ensures that we're parsed
6417  if (!isLocalFile() && !scheme().isEmpty())
6418  return QString();
6419 
6420  QString tmp;
6421  QString ourPath = path();
6422 
6423  QMutexLocker lock(&d->mutex); // for d->host
6424 
6425  // magic for shared drive on windows
6426  if (!d->host.isEmpty()) {
6427  tmp = QLatin1String("//") + d->host + (ourPath.length() > 0 && ourPath.at(0) != QLatin1Char('/')
6428  ? QLatin1Char('/') + ourPath : ourPath);
6429  } else {
6430  tmp = ourPath;
6431  // magic for drives on windows
6432  if (ourPath.length() > 2 && ourPath.at(0) == QLatin1Char('/') && ourPath.at(2) == QLatin1Char(':'))
6433  tmp.remove(0, 1);
6434  }
6435 
6436  return tmp;
6437 }
6438 
6453 bool QUrl::isLocalFile() const
6454 {
6455  if (!d) return false;
6456  QMutexLocker lock(&d->mutex);
6458 
6459  if (d->scheme.compare(QLatin1String("file"), Qt::CaseInsensitive) != 0)
6460  return false; // not file
6461  return true;
6462 }
6463 
6469 bool QUrl::isParentOf(const QUrl &childUrl) const
6470 {
6471  QString childPath = childUrl.path();
6472 
6473  if (!d)
6474  return ((childUrl.scheme().isEmpty())
6475  && (childUrl.authority().isEmpty())
6476  && childPath.length() > 0 && childPath.at(0) == QLatin1Char('/'));
6477 
6478  QMutexLocker lock(&d->mutex);
6480  lock.unlock();
6481 
6482  QString ourPath = path();
6483 
6484  return ((childUrl.scheme().isEmpty() || scheme() == childUrl.scheme())
6485  && (childUrl.authority().isEmpty() || authority() == childUrl.authority())
6486  && childPath.startsWith(ourPath)
6487  && ((ourPath.endsWith(QLatin1Char('/')) && childPath.length() > ourPath.length())
6488  || (!ourPath.endsWith(QLatin1Char('/'))
6489  && childPath.length() > ourPath.length() && childPath.at(ourPath.length()) == QLatin1Char('/'))));
6490 }
6491 
6716 #ifdef QT3_SUPPORT
6717 void QUrl::setFileName(const QString &txt)
6718 {
6719  QFileInfo fileInfo(path());
6720  fileInfo.setFile(txt);
6721  setPath(fileInfo.filePath());
6722 }
6723 
6724 QString QUrl::fileName() const
6725 {
6726  QFileInfo fileInfo(path());
6727  return fileInfo.fileName();
6728 }
6729 
6730 QString QUrl::dirPath() const
6731 {
6732  QFileInfo fileInfo(path());
6733  if (fileInfo.isAbsolute()) {
6734  QString absPath = fileInfo.absolutePath();
6735 #ifdef Q_OS_WIN
6736  if (absPath.size() > 1 && absPath.at(1) == QLatin1Char(':'))
6737  absPath = absPath.mid(2);
6738 #endif
6739  return absPath;
6740  }
6741  return fileInfo.path();
6742 }
6743 #endif
6744 
6745 
6746 #ifndef QT_NO_DATASTREAM
6747 
6758 {
6759  QByteArray u = url.toEncoded();
6760  out << u;
6761  return out;
6762 }
6763 
6775 {
6776  QByteArray u;
6777  in >> u;
6778  url = QUrl::fromEncoded(u);
6779  return in;
6780 }
6781 #endif // QT_NO_DATASTREAM
6782 
6783 #ifndef QT_NO_DEBUG_STREAM
6785 {
6786  d.maybeSpace() << "QUrl(" << url.toString() << ')';
6787  return d.space();
6788 }
6789 #endif
6790 
6801 {
6802  if (!d)
6803  return QLatin1String(QT_TRANSLATE_NOOP(QUrl, "Invalid URL \"\": ")); // XXX not a good message, but the one an empty URL produces
6804  QMutexLocker lock(&d->mutex);
6805  return d->createErrorString();
6806 }
6807 
6818 // The following code has the following copyright:
6819 /*
6820  Copyright (C) Research In Motion Limited 2009. All rights reserved.
6821 
6822 Redistribution and use in source and binary forms, with or without
6823 modification, are permitted provided that the following conditions are met:
6824  * Redistributions of source code must retain the above copyright
6825  notice, this list of conditions and the following disclaimer.
6826  * Redistributions in binary form must reproduce the above copyright
6827  notice, this list of conditions and the following disclaimer in the
6828  documentation and/or other materials provided with the distribution.
6829  * Neither the name of Research In Motion Limited nor the
6830  names of its contributors may be used to endorse or promote products
6831  derived from this software without specific prior written permission.
6832 
6833 THIS SOFTWARE IS PROVIDED BY Research In Motion Limited ''AS IS'' AND ANY
6834 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6835 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6836 DISCLAIMED. IN NO EVENT SHALL Research In Motion Limited BE LIABLE FOR ANY
6837 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6838 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6839 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6840 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6841 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6842 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6843 
6844 */
6845 
6846 
6879 {
6880  QString trimmedString = userInput.trimmed();
6881 
6882  // Check first for files, since on Windows drive letters can be interpretted as schemes
6883  if (QDir::isAbsolutePath(trimmedString))
6884  return QUrl::fromLocalFile(trimmedString);
6885 
6886  QUrl url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode);
6887  QUrl urlPrepended = QUrl::fromEncoded("http://" + trimmedString.toUtf8(), QUrl::TolerantMode);
6888 
6889  // Check the most common case of a valid url with a scheme
6890  // We check if the port would be valid by adding the scheme to handle the case host:port
6891  // where the host would be interpretted as the scheme
6892  if (url.isValid()
6893  && !url.scheme().isEmpty()
6894  && urlPrepended.port() == -1)
6895  return url;
6896 
6897  // Else, try the prepended one and adjust the scheme from the host name
6898  if (urlPrepended.isValid() && (!urlPrepended.host().isEmpty() || !urlPrepended.path().isEmpty()))
6899  {
6900  int dotIndex = trimmedString.indexOf(QLatin1Char('.'));
6901  const QString hostscheme = trimmedString.left(dotIndex).toLower();
6902  if (hostscheme == QLatin1String("ftp"))
6903  urlPrepended.setScheme(QLatin1String("ftp"));
6904  return urlPrepended;
6905  }
6906 
6907  return QUrl();
6908 }
6909 // end of BSD code
6910 
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
static bool QT_FASTCALL _IPv4Address(const char **ptr)
Definition: qurl.cpp:604
static const uint skew
Definition: qurl.cpp:271
static void toPunycodeHelper(const QChar *s, int ucLength, QString *output)
Definition: qurl.cpp:3140
QBool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.h:904
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:62
double d
Definition: qnumeric_p.h:62
int fragmentLength
Definition: qurl.cpp:316
QString topLevelDomain() const
Returns the TLD (Top-Level Domain) of the URL, (e.
Definition: qurl.cpp:5794
void setEncodedPath(const QByteArray &path)
Sets the URL&#39;s path to the percent-encoded path.
Definition: qurl.cpp:5013
void qAtomicDetach(T *&d)
This is a helper for the detach method of implicitly shared classes.
Definition: qatomic.h:214
void setUserInfo(const QString &userInfo)
Sets the user info of the URL to userInfo.
Definition: qurl.cpp:4615
void chop(int n)
Removes n bytes from the end of the byte array.
void parse(ParseOptions parseOptions=ParseAndSet) const
Definition: qurl.cpp:3852
QUrlPrivate()
Definition: qurl.cpp:3439
QStringList allQueryItemValues(const QString &key) const
Returns the a list of query string values whose key is equal to key from the URL. ...
Definition: qurl.cpp:5474
void setQueryDelimiters(char valueDelimiter, char pairDelimiter)
Sets the characters used for delimiting between keys and values, and between key-value pairs in the U...
Definition: qurl.cpp:5089
static QString fromPercentEncoding(const QByteArray &)
Returns a decoded copy of input.
Definition: qurl.cpp:5992
void truncate(int pos)
Truncates the byte array at index position pos.
bool isValid() const
Returns true if the URL is valid; otherwise returns false.
Definition: qurl.cpp:4303
static QByteArray toPercentEncoding(const QString &, const QByteArray &exclude=QByteArray(), const QByteArray &include=QByteArray())
Returns an encoded copy of input.
Definition: qurl.cpp:6009
unsigned char c[8]
Definition: qnumeric_p.h:62
static void appendEncode(QString *output, uint &delta, uint &bias, uint &b, uint &h)
Definition: qurl.cpp:3116
#define ABNF_sub_delims
Definition: qurl.cpp:3534
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void setParams(const char *source, const char *message, char expected, char found)
Definition: qurl.cpp:289
#define Q_MAXINT
Definition: qurl.cpp:267
QString path
Definition: qurl.cpp:360
The QMutex class provides access serialization between threads.
Definition: qmutex.h:60
void validate() const
Definition: qurl.cpp:3818
NormalizationForm
This enum describes the various normalized forms of Unicode text.
Definition: qstring.h:309
static const uint damp
Definition: qurl.cpp:272
void addEncodedQueryItem(const QByteArray &key, const QByteArray &value)
Inserts the pair key = value into the query string of the URL.
Definition: qurl.cpp:5279
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
void setAuthority(const QString &authority)
Sets the authority of the URL to authority.
Definition: qurl.cpp:4575
QByteArray encodedPath
Definition: qurl.cpp:367
static QByteArray toPercentEncodingHelper(const QString &s, const char *exclude, const char *include=0)
Definition: qurl.cpp:233
static const NameprepCaseFoldingEntry NameprepCaseFolding[]
Definition: qurl.cpp:1014
static bool isAbsolutePath(const QString &path)
Returns true if path is absolute; returns false if it is relative.
Definition: qdir.h:192
QString toString(FormattingOptions options=None) const
Returns the human-displayable string representation of the URL.
Definition: qurl.cpp:5896
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
static const char fragmentExcludeChars[]
Definition: qurl.cpp:3548
QByteArray encodedUserName
Definition: qurl.cpp:365
The QAtomicInt class provides platform-independent atomic operations on integers. ...
Definition: qatomic.h:55
bool isAbsolute() const
Returns true if the file path name is absolute, otherwise returns false if the path is relative...
Definition: qfileinfo.h:111
QByteArray encodedQueryItemValue(const QByteArray &key) const
Returns the first query string value whose key is equal to key from the URL.
Definition: qurl.cpp:5445
QByteArray & append(char c)
Appends the character ch to this byte array.
QByteArray encodedHost() const
Returns the host part of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:4884
static bool QT_FASTCALL _IPLiteral(const char **ptr)
Definition: qurl.cpp:754
void setEncodedPassword(const QByteArray &password)
Sets the URL&#39;s password to the percent-encoded password.
Definition: qurl.cpp:4780
static bool QT_FASTCALL _subDelims(const char **ptr)
Definition: qurl.cpp:455
static void QT_FASTCALL _query(const char **ptr, QUrlParseData *parseData)
Definition: qurl.cpp:972
bool hasFragment
Definition: qurl.cpp:374
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
const char * path
Definition: qurl.cpp:311
static QString fromPercentEncodingHelper(const QByteArray &ba)
Definition: qurl.cpp:242
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
bool isParentOf(const QUrl &url) const
Returns true if this URL is a parent of childUrl.
Definition: qurl.cpp:6469
void chop(int n)
Removes n characters from the end of the string.
Definition: qstring.cpp:4623
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
Definition: qurl.cpp:4317
static const uint initial_n
Definition: qurl.cpp:274
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QByteArray encodedNormalized
Definition: qurl.cpp:396
QByteArray encodedPassword() const
Returns the password of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:4805
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
QString fileName() const
Returns the name of the file, excluding the path.
Definition: qfileinfo.cpp:726
static bool isBidirectionalRorAL(uint uc)
Definition: qurl.cpp:2520
bool isDetached() const
Definition: qurl.cpp:6356
void unlock()
Unlocks this mutex locker.
Definition: qmutex.h:117
static void clear(QVariant::Private *d)
Definition: qvariant.cpp:197
bool isLowSurrogate() const
Returns true if the QChar is the low part of a utf16 surrogate (ie.
Definition: qchar.h:279
static bool QT_FASTCALL _pctEncoded(const char **ptr)
Definition: qurl.cpp:416
const char * userInfo
Definition: qurl.cpp:303
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
static bool QT_FASTCALL _pathAbs(const char **ptr)
Definition: qurl.cpp:920
bool operator<(const QUrl &url) const
Returns true if this URL is "less than" the given url.
Definition: qurl.cpp:6228
const char * _message
Definition: qurl.cpp:285
void setPath(const QString &path)
Sets the path of the URL to path.
Definition: qurl.cpp:4960
QByteArray toLower() const
Returns a lowercase copy of the byte array.
#define QT_TRANSLATE_NOOP(scope, x)
Marks the string literal sourceText for dynamic translation in the given context; i...
Definition: qglobal.h:2487
#define QURL_HASFLAG(a, b)
Definition: qurl.cpp:278
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
#define QURL_SETFLAG(a, b)
Definition: qurl.cpp:276
quint16 u
Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
Definition: qalgorithms.h:295
static const uint tmin
Definition: qurl.cpp:269
long ASN1_INTEGER_get ASN1_INTEGER * a
QString fragment
Definition: qurl.cpp:362
void setQueryItems(const QList< QPair< QString, QString > > &query)
Sets the query string of the URL to an encoded version of query.
Definition: qurl.cpp:5161
unsigned char quint8
Definition: qglobal.h:934
bool ref()
Atomically increments the value of this QAtomicInt.
QByteArray & prepend(char c)
Prepends the character ch to this byte array.
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
char _expected
Definition: qurl.cpp:286
The QString class provides a Unicode character string.
Definition: qstring.h:83
void setUserInfo(const QString &userInfo)
Definition: qurl.cpp:3641
QString host() const
Returns the host of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:4837
static bool qt_check_std3rules(const QChar *uc, int len)
Definition: qurl.cpp:3073
QUrlErrorInfo()
Definition: qurl.cpp:281
char queryValueDelimiter() const
Returns the character used to delimit between keys and values in the query string of the URL...
Definition: qurl.cpp:5113
bool isHighSurrogate() const
Returns true if the QChar is the high part of a utf16 surrogate (ie.
Definition: qchar.h:276
static const char passwordExcludeChars[]
Definition: qurl.cpp:3545
QString password
Definition: qurl.cpp:358
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
bool startsWith(const QByteArray &a) const
Returns true if this byte array starts with byte array ba; otherwise returns false.
void setHost(const QString &host)
Sets the host of the URL to host.
Definition: qurl.cpp:4821
QString fragment() const
Returns the fragment of the URL.
Definition: qurl.cpp:5687
static const uint base
Definition: qurl.cpp:268
Q_CORE_EXPORT QString qTopLevelDomain(const QString &domain)
Return the top-level-domain per Qt&#39;s copy of the Mozilla public suffix list of domain.
Definition: qtldurl.cpp:73
#define QT_FASTCALL
Definition: qglobal.h:1161
static void removeDotsFromPath(QByteArray *path)
Definition: qurl.cpp:3746
bool isRelative() const
Returns true if the URL is relative; otherwise returns false.
Definition: qurl.cpp:5880
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QChar * data()
Returns a pointer to the data stored in the QString.
Definition: qstring.h:710
QByteArray encodedPassword
Definition: qurl.cpp:366
static QUrl fromUserInput(const QString &userInput)
Returns a valid URL from a user supplied userInput string if one can be deducted. ...
Definition: qurl.cpp:6878
QString fragmentImpl() const
Definition: qurl.cpp:5696
QList< QPair< QString, QString > > queryItems() const
Returns the query string of the URL, as a map of keys and values.
Definition: qurl.cpp:5305
bool hasQuery() const
Returns true if this URL contains a Query (i.
Definition: qurl.cpp:5058
int queryLength
Definition: qurl.cpp:314
~QUrl()
Destructor; called immediately before the object is deleted.
Definition: qurl.cpp:4288
int stateFlags
Definition: qurl.cpp:387
void clear()
Definition: qurl.cpp:3968
static bool isMappedToNothing(uint uc)
Definition: qurl.cpp:2433
QString path() const
Returns the path of the URL.
Definition: qurl.cpp:4977
#define ABNF_reserved
Definition: qurl.cpp:3537
QString errorString() const
Returns a text string that explains why an URL is invalid in the case being; otherwise returns an emp...
Definition: qurl.cpp:6800
QAtomicInt ref
Definition: qurl.cpp:354
QString userInfo(QUrl::FormattingOptions options=QUrl::None) const
Definition: qurl.cpp:3673
void setEncodedFragment(const QByteArray &fragment)
Sets the URL&#39;s fragment to the percent-encoded fragment.
Definition: qurl.cpp:5727
bool isLocalFile() const
Returns true if this URL is pointing to a local file path.
Definition: qurl.cpp:6453
QByteArray encodedUserName() const
Returns the user name of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:4719
Q_GUI_EXPORT QString errorString(EGLint code=eglGetError())
Definition: qegl.cpp:743
UnicodeVersion unicodeVersion() const
Returns the Unicode version that introduced this character.
Definition: qchar.cpp:1189
int userInfoLength
Definition: qurl.cpp:305
void clear()
Resets the content of the QUrl.
Definition: qurl.cpp:4340
Q_CORE_EXPORT void qDebug(const char *,...)
int port() const
Returns the port of the URL, or -1 if the port is unspecified.
Definition: qurl.cpp:4916
void reserve(int size)
Attempts to allocate memory for at least size characters.
Definition: qstring.h:881
static bool isDotDelimiter(ushort uc)
Definition: qurl.cpp:3311
static char toHex(quint8 c)
Definition: qurl.cpp:4440
static void QT_FASTCALL _fragment(const char **ptr, QUrlParseData *parseData)
Definition: qurl.cpp:988
static void QT_FASTCALL _port(const char **ptr, int *port)
Definition: qurl.cpp:833
QString createErrorString()
Definition: qurl.cpp:4164
static QByteArray toAce(const QString &)
Returns the ASCII Compatible Encoding of the given domain name domain.
Definition: qurl.cpp:6158
static QString qt_ACE_do(const QString &domain, AceOperation op)
Definition: qurl.cpp:3334
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static bool QT_FASTCALL _h16(const char **ptr)
Definition: qurl.cpp:552
int lastIndexOf(char c, int from=-1) const
Returns the index position of the last occurrence of character ch in the byte array, searching backward from index position from.
QList< QPair< QByteArray, QByteArray > > encodedQueryItems() const
Returns the query string of the URL, as a map of encoded keys and values.
Definition: qurl.cpp:5342
const char * scheme
Definition: qurl.cpp:300
void truncate(int pos)
Truncates the string at the given position index.
Definition: qstring.cpp:4603
static bool lessThan(const QChar *a, int l, const char *c)
Definition: qurl.cpp:3253
#define QURL_UNSETFLAG(a, b)
Definition: qurl.cpp:277
void detach()
Forces a detach.
Definition: qurl.cpp:6313
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
static QString fromPercentEncodingMutable(QByteArray *ba)
Definition: qurl.cpp:251
static const char pathExcludeChars[]
Definition: qurl.cpp:3546
QString trimmed() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end.
Definition: qstring.cpp:4506
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
const QChar * unicode() const
Returns a &#39;\0&#39;-terminated Unicode representation of the string.
Definition: qstring.h:706
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
static const char *const idn_whitelist[]
Definition: qurl.cpp:3227
QUrl::ParsingMode parsingMode
Definition: qurl.cpp:371
static bool QT_FASTCALL _HEXDIG(const char **ptr)
Definition: qurl.cpp:404
QString authority() const
Returns the authority of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:4592
static const uint tmax
Definition: qurl.cpp:270
static bool QT_FASTCALL _scheme(const char **ptr, QUrlParseData *parseData)
Definition: qurl.cpp:483
void setUrl(const QString &url)
Constructs a URL by parsing the contents of url.
Definition: qurl.cpp:4358
bool deref()
Atomically decrements the value of this QAtomicInt.
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
static QByteArray fromRawData(const char *, int size)
Constructs a QByteArray that uses the first size bytes of the data array.
static QString fromPunycode(const QByteArray &)
Returns the Punycode decoded representation of pc.
Definition: qurl.cpp:6044
void setFile(const QString &file)
Sets the file that the QFileInfo provides information about to file.
Definition: qfileinfo.cpp:468
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
void q_fromPercentEncoding(QByteArray *ba)
static const char queryExcludeChars[]
Definition: qurl.cpp:3547
QString userInfo() const
Returns the user info of the URL, or an empty string if the user info is undefined.
Definition: qurl.cpp:4631
Q_CORE_EXPORT void qWarning(const char *,...)
#define ABNF_pchar
Definition: qurl.cpp:3536
static QStringList idnWhitelist()
Returns the current whitelist of top-level domains that are allowed to have non-ASCII characters in t...
Definition: qurl.cpp:6175
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
int userInfoDelimIndex
Definition: qurl.cpp:304
void setEncodedHost(const QByteArray &host)
Sets the URL&#39;s host to the ACE- or percent-encoded host.
Definition: qurl.cpp:4861
QByteArray encodedPath() const
Returns the path of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:5038
void queryItem(int pos, int *value, int *end)
Definition: qurl.cpp:3727
static bool QT_FASTCALL _IPvFuture(const char **ptr)
Definition: qurl.cpp:516
QBool contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the list contains the string str; otherwise returns false.
Definition: qstringlist.h:172
void removeAllQueryItems(const QString &key)
Removes all the query string pairs whose key is equal to key from the URL.
Definition: qurl.cpp:5595
static void qt_nameprep(QString *source, int from)
Definition: qurl.cpp:2979
QString right(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n rightmost characters of the string.
Definition: qstring.cpp:3682
const char * fragment
Definition: qurl.cpp:315
const T * ptr(const T &t)
QDebug & maybeSpace()
Writes a space character to the debug stream, depending on the last character sent to the stream...
Definition: qdebug.h:93
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
QByteArray toEncoded(QUrl::FormattingOptions options=QUrl::None) const
Definition: qurl.cpp:3996
QByteArray query
Definition: qurl.cpp:361
QByteArray left(int len) const
Returns a byte array that contains the leftmost len bytes of this byte array.
The State element defines configurations of objects and properties.
quint16 values[128]
void setAuthority(const QString &auth)
Definition: qurl.cpp:3585
bool isNull() const
Returns true if this byte array is null; otherwise returns false.
static void QT_FASTCALL _host(const char **ptr, QUrlParseData *parseData)
Definition: qurl.cpp:787
QUrlPrivate * d
Definition: qurl.h:279
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
Definition: qurl.cpp:6412
int indexOf(char c, int from=0) const
Returns the index position of the first occurrence of the character ch in the byte array...
static const char userNameExcludeChars[]
Definition: qurl.cpp:3544
void q_normalizePercentEncoding(QByteArray *ba, const char *exclude)
UnicodeVersion
Specifies which version of the [Unicode standard](http://www.
Definition: qchar.h:212
static QByteArray toPunycode(const QString &)
Returns a uc in Punycode encoding.
Definition: qurl.cpp:6025
void setFragment(const QString &fragment)
Sets the fragment of the URL to fragment.
Definition: qurl.cpp:5669
static QString fromAce(const QByteArray &)
Returns the Unicode form of the given domain name domain, which is encoded in the ASCII Compatible En...
Definition: qurl.cpp:6134
const char * host
Definition: qurl.cpp:307
int schemeLength
Definition: qurl.cpp:301
int pathLength
Definition: qurl.cpp:312
static void QT_FASTCALL _authority(const char **ptr, QUrlParseData *parseData)
Definition: qurl.cpp:856
int length() const
Same as size().
Definition: qbytearray.h:356
QByteArray toEncoded(FormattingOptions options=None) const
Returns the encoded representation of the URL if it&#39;s valid; otherwise an empty QByteArray is returne...
Definition: qurl.cpp:5949
void resize(int size)
Sets the size of the string to size characters.
Definition: qstring.cpp:1353
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition: qstring.h:505
char _found
Definition: qurl.cpp:287
bool hasQuery
Definition: qurl.cpp:373
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
QString userName() const
Returns the user name of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:4667
QString scheme() const
Returns the scheme of the URL.
Definition: qurl.cpp:4550
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
int compare(const QString &s) const
Definition: qstring.cpp:5037
static void mapToLowerCase(QString *str, int from)
Definition: qurl.cpp:2388
void setPort(int port)
Sets the port of the URL to port.
Definition: qurl.cpp:4897
static bool QT_FASTCALL _decOctet(const char **ptr)
Definition: qurl.cpp:567
bool hasQueryItem(const QString &key) const
Returns true if there is a query string pair whose key is equal to key from the URL.
Definition: qurl.cpp:5372
QUrl & operator=(const QUrl &copy)
Assigns the specified url to this object.
Definition: qurl.cpp:6264
#define Q_CORE_EXPORT
Definition: qglobal.h:1449
bool operator<(uint one, const NameprepCaseFoldingEntry &other)
Definition: qurl.cpp:1008
bool operator!=(const QUrl &url) const
Returns true if this URL and the given url are not equal; otherwise returns false.
Definition: qurl.cpp:6256
QByteArray encodedOriginal
Definition: qurl.cpp:364
int capacity() const
Returns the maximum number of characters that can be stored in the string without forcing a reallocat...
Definition: qstring.h:727
const QByteArray & normalized() const
Definition: qurl.cpp:4082
void clear()
Clears the contents of the string and makes it empty.
Definition: qstring.h:723
unsigned short ushort
Definition: qglobal.h:995
int lastIndexOf(QChar c, int from=-1, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:3000
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
static void QT_FASTCALL _hierPart(const char **ptr, QUrlParseData *parseData)
Definition: qurl.cpp:951
static bool containsProhibitedOuptut(const QString *str, int from)
Definition: qurl.cpp:2450
static QMap< QByteArray, int > mapping
Definition: qaxserver.cpp:577
Q_OUTOFLINE_TEMPLATE QPair< T1, T2 > qMakePair(const T1 &x, const T2 &y)
Definition: qpair.h:102
int key
QString toLower() const Q_REQUIRED_RESULT
Returns a lowercase copy of the string.
Definition: qstring.cpp:5389
static uint encodeDigit(uint digit)
Definition: qurl.cpp:3099
QString scheme
Definition: qurl.cpp:356
iterator begin()
Returns an STL-style iterator pointing to the first character in the string.
Definition: qstring.h:888
QByteArray toAscii() const Q_REQUIRED_RESULT
Returns an 8-bit representation of the string as a QByteArray.
Definition: qstring.cpp:4014
void setEncodedUrl(const QByteArray &url)
Constructs a URL by parsing the contents of encodedUrl.
Definition: qurl.cpp:4429
static QReadWriteLock lock
Definition: proxyconf.cpp:399
bool hasFragment() const
Returns true if this URL contains a fragment (i.
Definition: qurl.cpp:5773
static void QT_FASTCALL _pathAbEmpty(const char **ptr)
Definition: qurl.cpp:907
#define Q_AUTOTEST_EXPORT
Definition: qglobal.h:1510
QByteArray mergePaths(const QByteArray &relativePath) const
Definition: qurl.cpp:3700
QFactoryLoader * l
QString queryItemValue(const QString &key) const
Returns the first query string value whose key is equal to key from the URL.
Definition: qurl.cpp:5422
QMutex mutex
Definition: qurl.cpp:394
QString authority(QUrl::FormattingOptions options=QUrl::None) const
Definition: qurl.cpp:3568
static void QT_FASTCALL _regName(const char **ptr)
Definition: qurl.cpp:776
void qAtomicAssign(T *&d, T *x)
This is a helper for the assignment operators of implicitly shared classes.
Definition: qatomic.h:195
QString host
Definition: qurl.cpp:359
void q_toPercentEncoding(QByteArray *ba, const char *exclude, const char *include=0)
QByteArray encodedFragment() const
Returns the fragment of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:5753
int qsnprintf(char *str, size_t n, const char *fmt,...)
A portable snprintf() function, calls qvsnprintf.
Definition: qvsnprintf.cpp:128
QString canonicalHost() const
Definition: qurl.cpp:3479
static uint surrogateToUcs4(ushort high, ushort low)
Converts a UTF16 surrogate pair with the given high and low values to its UCS-4 code point...
Definition: qchar.h:297
int hostLength
Definition: qurl.cpp:308
static bool QT_FASTCALL _IPv6Address(const char **ptr)
Definition: qurl.cpp:650
QByteArray encodedFragment
Definition: qurl.cpp:368
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
const char * _source
Definition: qurl.cpp:284
void setScheme(const QString &scheme)
Sets the scheme of the URL to scheme.
Definition: qurl.cpp:4533
bool hasEncodedQueryItem(const QByteArray &key) const
Returns true if there is a query string pair whose key is equal to key from the URL.
Definition: qurl.cpp:5394
static bool QT_FASTCALL _segmentNZ(const char **ptr)
Definition: qurl.cpp:895
void ensureEncodedParts() const
Definition: qurl.cpp:3550
static uint adapt(uint delta, uint numpoints, bool firsttime)
Definition: qurl.cpp:3104
void addQueryItem(const QString &key, const QString &value)
Inserts the pair key = value into the query string of the URL.
Definition: qurl.cpp:5240
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
Definition: qurl.cpp:6374
static bool qt_is_idn_enabled(const QString &domain)
Definition: qurl.cpp:3282
QByteArray & replace(int index, int len, const char *s)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static bool QT_FASTCALL _pchar(const char **ptr)
Definition: qurl.cpp:869
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
static bool isHex(char c)
Definition: qurl.cpp:4434
#define qToLower(ch)
Definition: qurl.cpp:4080
void setEncodedUserInfo(const QUrlParseData *parseData)
Definition: qurl.cpp:3656
int port
Definition: qurl.cpp:370
static QStringList * user_idn_whitelist
Definition: qurl.cpp:3251
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71
static bool QT_FASTCALL _pathRootless(const char **ptr)
Definition: qurl.cpp:935
void removeQueryItem(const QString &key)
Removes the first query string pair whose key is equal to key from the URL.
Definition: qurl.cpp:5545
char queryPairDelimiter() const
Returns the character used to delimit between key-value pairs in the query string of the URL...
Definition: qurl.cpp:5103
ParsingMode
The parsing mode controls the way QUrl parses strings.
Definition: qurl.h:64
static QString fromNativeSeparators(const QString &pathName)
Returns pathName using &#39;/&#39; as file separator.
Definition: qdir.cpp:848
QString userName
Definition: qurl.cpp:357
static bool isBidirectionalL(uint uc)
Definition: qurl.cpp:2560
char valueDelimiter
Definition: qurl.cpp:378
static const uint initial_bias
Definition: qurl.cpp:273
const char * query
Definition: qurl.cpp:313
static QUrl fromEncoded(const QByteArray &url)
Parses input and returns the corresponding QUrl.
Definition: qurl.cpp:5964
QString path() const
Returns the file&#39;s path.
Definition: qfileinfo.cpp:615
AceOperation
Definition: qurl.cpp:3333
QString & remove(int i, int len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition: qstring.cpp:1867
static void setIdnWhitelist(const QStringList &)
Sets the whitelist of Top-Level Domains (TLDs) that are allowed to have non-ASCII characters in domai...
Definition: qurl.cpp:6212
char at(int i) const
Returns the character at index position i in the byte array.
Definition: qbytearray.h:413
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition: qstring.cpp:3796
QUrl resolved(const QUrl &relative) const
Returns the result of the merge of this URL with relative.
Definition: qurl.cpp:5819
bool isValid
Definition: qurl.cpp:375
The QFileInfo class provides system-independent file information.
Definition: qfileinfo.h:60
void setEncodedQueryItems(const QList< QPair< QByteArray, QByteArray > > &query)
Sets the query string of the URL to the encoded version of query.
Definition: qurl.cpp:5205
void reserve(int size)
Attempts to allocate memory for at least size bytes.
Definition: qbytearray.h:449
void removeAllEncodedQueryItems(const QByteArray &key)
Removes all the query string pairs whose key is equal to key from the URL.
Definition: qurl.cpp:5617
static const KeyPair *const end
static bool QT_FASTCALL _ls32(const char **ptr)
Definition: qurl.cpp:631
QString filePath() const
Returns the file name, including the path (which may be absolute or relative).
Definition: qfileinfo.cpp:707
static void QT_FASTCALL _userInfo(const char **ptr, QUrlParseData *parseData)
Definition: qurl.cpp:806
QDebug & space()
Writes a space character to the debug stream and returns a reference to the stream.
Definition: qdebug.h:91
void setUserName(const QString &userName)
Sets the URL&#39;s user name to userName.
Definition: qurl.cpp:4648
QList< QByteArray > allEncodedQueryItemValues(const QByteArray &key) const
Returns the a list of query string values whose key is equal to key from the URL. ...
Definition: qurl.cpp:5516
QString & insert(int i, QChar c)
Definition: qstring.cpp:1671
QDataStream & operator<<(QDataStream &out, const QUrl &url)
Writes url url to the stream out and returns a reference to the stream.
Definition: qurl.cpp:6757
bool operator==(const QUrl &url) const
Returns true if this URL and the given url are equal; otherwise returns false.
Definition: qurl.cpp:6242
static QString fileName(const QString &fileUrl)
void setEncodedUserName(const QByteArray &userName)
Sets the URL&#39;s user name to the percent-encoded userName.
Definition: qurl.cpp:4694
QString absolutePath() const
Returns a file&#39;s path absolute path.
Definition: qfileinfo.cpp:577
QUrl()
Constructs an empty QUrl object.
Definition: qurl.cpp:4272
QString password() const
Returns the password of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:4754
static bool QT_FASTCALL _unreserved(const char **ptr)
Definition: qurl.cpp:470
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
void setPassword(const QString &password)
Sets the URL&#39;s password to password.
Definition: qurl.cpp:4736
char pairDelimiter
Definition: qurl.cpp:379
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition: qstring.h:712
QByteArray & remove(int index, int len)
Removes len bytes from the array, starting at index position pos, and returns a reference to the arra...
void clear()
Clears the contents of the byte array and makes it empty.
void qt_string_normalize(QString *data, QString::NormalizationForm mode, QChar::UnicodeVersion version, int from)
Definition: qstring.cpp:6710
static int nextDotDelimiter(const QString &domain, int from=0)
Definition: qurl.cpp:3319
bool isHostValid
Definition: qurl.cpp:376
QByteArray encodedQuery() const
Returns the query string of the URL in percent encoded form.
Definition: qurl.cpp:5643
static bool equal(const QChar *a, int l, const char *b)
Definition: qurl.cpp:3270
QUrlErrorInfo errorInfo
Definition: qurl.cpp:399
bool endsWith(const QByteArray &a) const
Returns true if this byte array ends with byte array ba; otherwise returns false. ...
void removeEncodedQueryItem(const QByteArray &key)
Removes the first query string pair whose key is equal to key from the URL.
Definition: qurl.cpp:5567
QBool contains(char c) const
Returns true if the byte array contains the character ch; otherwise returns false.
Definition: qbytearray.h:525
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
void setEncodedQuery(const QByteArray &query)
Sets the query string of the URL to query.
Definition: qurl.cpp:5136
void setEncodedUrl(const QByteArray &encodedUrl, QUrl::ParsingMode parsingMode)
Definition: qurl.cpp:4458
QDataStream & operator>>(QDataStream &in, QUrl &url)
Reads a url into url from the stream in and returns a reference to the stream.
Definition: qurl.cpp:6774