Merge remote-tracking branch 'upstream/tags/v4.8.0-rc1' into experimental
[qt:android-lighthouse.git] / src / corelib / codecs / qtextcodec.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qplatformdefs.h"
43 #include "qtextcodec.h"
44 #include "qtextcodec_p.h"
45
46 #ifndef QT_NO_TEXTCODEC
47
48 #include "qlist.h"
49 #include "qfile.h"
50 #ifndef QT_NO_LIBRARY
51 # include "qcoreapplication.h"
52 # include "qtextcodecplugin.h"
53 # include "private/qfactoryloader_p.h"
54 #endif
55 #include "qstringlist.h"
56
57 #ifdef Q_OS_UNIX
58 #  include "qiconvcodec_p.h"
59 #endif
60
61 #include "qutfcodec_p.h"
62 #include "qsimplecodec_p.h"
63 #include "qlatincodec_p.h"
64 #ifndef QT_NO_CODECS
65 #  include "qtsciicodec_p.h"
66 #  include "qisciicodec_p.h"
67 #if !defined(Q_OS_SYMBIAN) && !defined(Q_OS_INTEGRITY)
68 #  if defined(QT_NO_ICONV) && !defined(QT_BOOTSTRAPPED)
69 // no iconv(3) support, must build all codecs into the library
70 #    include "../../plugins/codecs/cn/qgb18030codec.h"
71 #    include "../../plugins/codecs/jp/qeucjpcodec.h"
72 #    include "../../plugins/codecs/jp/qjiscodec.h"
73 #    include "../../plugins/codecs/jp/qsjiscodec.h"
74 #    include "../../plugins/codecs/kr/qeuckrcodec.h"
75 #    include "../../plugins/codecs/tw/qbig5codec.h"
76 #  endif // QT_NO_ICONV
77 #  if defined(Q_WS_X11) && !defined(QT_BOOTSTRAPPED)
78 #    include "qfontlaocodec_p.h"
79 #    include "../../plugins/codecs/jp/qfontjpcodec.h"
80 #  endif
81 #endif // QT_NO_SYMBIAN
82 #endif // QT_NO_CODECS
83 #include "qlocale.h"
84 #include "qmutex.h"
85 #include "qhash.h"
86
87 #include <stdlib.h>
88 #include <ctype.h>
89 #include <locale.h>
90 #if defined (_XOPEN_UNIX) && !defined(Q_OS_QNX) && !defined(Q_OS_OSF) && !defined(Q_OS_ANDROID)
91 #include <langinfo.h>
92 #endif
93
94 #if defined(Q_OS_WINCE)
95 #  define QT_NO_SETLOCALE
96 #endif
97
98 #ifdef Q_OS_SYMBIAN
99 #include "qtextcodec_symbian.cpp"
100 #endif
101
102
103 // enabling this is not exception safe!
104 // #define Q_DEBUG_TEXTCODEC
105
106 QT_BEGIN_NAMESPACE
107
108 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_TEXTCODECPLUGIN)
109 Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
110     (QTextCodecFactoryInterface_iid, QLatin1String("/codecs")))
111 #endif
112
113 //Cache for QTextCodec::codecForName and codecForMib.
114 typedef QHash<QByteArray, QTextCodec *> QTextCodecCache;
115 Q_GLOBAL_STATIC(QTextCodecCache, qTextCodecCache)
116
117
118 static char qtolower(register char c)
119 { if (c >= 'A' && c <= 'Z') return c + 0x20; return c; }
120 static bool qisalnum(register char c)
121 { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'z'); }
122
123 static bool nameMatch(const QByteArray &name, const QByteArray &test)
124 {
125     // if they're the same, return a perfect score
126     if (qstricmp(name, test) == 0)
127         return true;
128
129     const char *n = name.constData();
130     const char *h = test.constData();
131
132     // if the letters and numbers are the same, we have a match
133     while (*n != '\0') {
134         if (qisalnum(*n)) {
135             for (;;) {
136                 if (*h == '\0')
137                     return false;
138                 if (qisalnum(*h))
139                     break;
140                 ++h;
141             }
142             if (qtolower(*n) != qtolower(*h))
143                 return false;
144             ++h;
145         }
146         ++n;
147     }
148     while (*h && !qisalnum(*h))
149            ++h;
150     return (*h == '\0');
151 }
152
153
154 static QTextCodec *createForName(const QByteArray &name)
155 {
156 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_TEXTCODECPLUGIN)
157     QFactoryLoader *l = loader();
158     QStringList keys = l->keys();
159     for (int i = 0; i < keys.size(); ++i) {
160         if (nameMatch(name, keys.at(i).toLatin1())) {
161             QString realName = keys.at(i);
162             if (QTextCodecFactoryInterface *factory
163                 = qobject_cast<QTextCodecFactoryInterface*>(l->instance(realName))) {
164                 return factory->create(realName);
165             }
166         }
167     }
168 #else
169     Q_UNUSED(name);
170 #endif
171     return 0;
172 }
173
174 static QTextCodec *createForMib(int mib)
175 {
176 #ifndef QT_NO_TEXTCODECPLUGIN
177     QString name = QLatin1String("MIB: ") + QString::number(mib);
178     if (QTextCodecFactoryInterface *factory
179         = qobject_cast<QTextCodecFactoryInterface*>(loader()->instance(name)))
180         return factory->create(name);
181 #else
182     Q_UNUSED(mib);
183 #endif
184     return 0;
185 }
186
187 static QList<QTextCodec*> *all = 0;
188 #ifdef Q_DEBUG_TEXTCODEC
189 static bool destroying_is_ok = false;
190 #endif
191
192 static QTextCodec *localeMapper = 0;
193 QTextCodec *QTextCodec::cftr = 0;
194
195
196 class QTextCodecCleanup
197 {
198 public:
199     ~QTextCodecCleanup();
200 };
201
202 /*
203     Deletes all the created codecs. This destructor is called just
204     before exiting to delete any QTextCodec objects that may be lying
205     around.
206 */
207 QTextCodecCleanup::~QTextCodecCleanup()
208 {
209     if (!all)
210         return;
211
212 #ifdef Q_DEBUG_TEXTCODEC
213     destroying_is_ok = true;
214 #endif
215
216     QList<QTextCodec *> *myAll = all;
217     all = 0; // Otherwise the d'tor destroys the iterator
218     for (QList<QTextCodec *>::const_iterator it = myAll->constBegin()
219             ; it != myAll->constEnd(); ++it) {
220         delete *it;
221     }
222     delete myAll;
223     localeMapper = 0;
224
225 #ifdef Q_DEBUG_TEXTCODEC
226     destroying_is_ok = false;
227 #endif
228 }
229
230 Q_GLOBAL_STATIC(QTextCodecCleanup, createQTextCodecCleanup)
231
232 bool QTextCodec::validCodecs()
233 {
234 #ifdef Q_OS_SYMBIAN
235     // If we don't have a trap handler, we're outside of the main() function,
236     // ie. in global constructors or destructors. Don't use codecs in this
237     // case as it would lead to crashes because we don't have a cleanup stack on Symbian
238     return (User::TrapHandler() != NULL);
239 #else
240     return true;
241 #endif
242 }
243
244
245 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
246 class QWindowsLocalCodec: public QTextCodec
247 {
248 public:
249     QWindowsLocalCodec();
250     ~QWindowsLocalCodec();
251
252     QString convertToUnicode(const char *, int, ConverterState *) const;
253     QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
254     QString convertToUnicodeCharByChar(const char *chars, int length, ConverterState *state) const;
255
256     QByteArray name() const;
257     int mibEnum() const;
258
259 };
260
261 QWindowsLocalCodec::QWindowsLocalCodec()
262 {
263 }
264
265 QWindowsLocalCodec::~QWindowsLocalCodec()
266 {
267 }
268
269 QString QWindowsLocalCodec::convertToUnicode(const char *chars, int length, ConverterState *state) const
270 {
271     const char *mb = chars;
272     int mblen = length;
273
274     if (!mb || !mblen)
275         return QString();
276
277     const int wclen_auto = 4096;
278     wchar_t wc_auto[wclen_auto];
279     int wclen = wclen_auto;
280     wchar_t *wc = wc_auto;
281     int len;
282     QString sp;
283     bool prepend = false;
284     char state_data = 0;
285     int remainingChars = 0;
286
287     //save the current state information
288     if (state) {
289         state_data = (char)state->state_data[0];
290         remainingChars = state->remainingChars;
291     }
292
293     //convert the pending charcter (if available)
294     if (state && remainingChars) {
295         char prev[3] = {0};
296         prev[0] = state_data;
297         prev[1] = mb[0];
298         remainingChars = 0;
299         len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
300                                     prev, 2, wc, wclen);
301         if (len) {
302             prepend = true;
303             sp.append(QChar(wc[0]));
304             mb++;
305             mblen--;
306             wc[0] = 0;
307         }
308     }
309
310     while (!(len=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
311                 mb, mblen, wc, wclen))) {
312         int r = GetLastError();
313         if (r == ERROR_INSUFFICIENT_BUFFER) {
314             if (wc != wc_auto) {
315                 qWarning("MultiByteToWideChar: Size changed");
316                 break;
317             } else {
318                 wclen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
319                                     mb, mblen, 0, 0);
320                 wc = new wchar_t[wclen];
321                 // and try again...
322             }
323         } else if (r == ERROR_NO_UNICODE_TRANSLATION) {
324             //find the last non NULL character
325             while (mblen > 1  && !(mb[mblen-1]))
326                 mblen--;
327             //check whether,  we hit an invalid character in the middle
328             if ((mblen <= 1) || (remainingChars && state_data))
329                 return convertToUnicodeCharByChar(chars, length, state);
330             //Remove the last character and try again...
331             state_data = mb[mblen-1];
332             remainingChars = 1;
333             mblen--;
334         } else {
335             // Fail.
336             qWarning("MultiByteToWideChar: Cannot convert multibyte text");
337             break;
338         }
339     }
340     if (len <= 0)
341         return QString();
342     if (wc[len-1] == 0) // len - 1: we don't want terminator
343         --len;
344
345     //save the new state information
346     if (state) {
347         state->state_data[0] = (char)state_data;
348         state->remainingChars = remainingChars;
349     }
350     QString s((QChar*)wc, len);
351     if (wc != wc_auto)
352         delete [] wc;
353     if (prepend) {
354         return sp+s;
355     }
356     return s;
357 }
358
359 QString QWindowsLocalCodec::convertToUnicodeCharByChar(const char *chars, int length, ConverterState *state) const
360 {
361     if (!chars || !length)
362         return QString();
363
364     int copyLocation = 0;
365     int extra = 2;
366     if (state && state->remainingChars) {
367         copyLocation = state->remainingChars;
368         extra += copyLocation;
369     }
370     int newLength = length + extra;
371     char *mbcs = new char[newLength];
372     //ensure that we have a NULL terminated string
373     mbcs[newLength-1] = 0;
374     mbcs[newLength-2] = 0;
375     memcpy(&(mbcs[copyLocation]), chars, length);
376     if (copyLocation) {
377         //copy the last character from the state
378         mbcs[0] = (char)state->state_data[0];
379         state->remainingChars = 0;
380     }
381     const char *mb = mbcs;
382 #ifndef Q_OS_WINCE
383     const char *next = 0;
384     QString s;
385     while((next = CharNextExA(CP_ACP, mb, 0)) != mb) {
386         wchar_t wc[2] ={0};
387         int charlength = next - mb;
388         int len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, mb, charlength, wc, 2);
389         if (len>0) {
390             s.append(QChar(wc[0]));
391         } else {
392             int r = GetLastError();
393             //check if the character being dropped is the last character
394             if (r == ERROR_NO_UNICODE_TRANSLATION && mb == (mbcs+newLength -3) && state) {
395                 state->remainingChars = 1;
396                 state->state_data[0] = (char)*mb;
397             }
398         }
399         mb = next;
400     }
401 #else
402     QString s;
403     int size = mbstowcs(NULL, mb, length);
404     if (size < 0) {
405         Q_ASSERT("Error in CE TextCodec");
406         return QString();
407     }
408     wchar_t* ws = new wchar_t[size + 2];
409     ws[size +1] = 0;
410     ws[size] = 0;
411     size = mbstowcs(ws, mb, length);
412     for (int i=0; i< size; i++)
413         s.append(QChar(ws[i]));
414     delete [] ws;
415 #endif
416     delete mbcs;
417     return s;
418 }
419
420 QByteArray QWindowsLocalCodec::convertFromUnicode(const QChar *ch, int uclen, ConverterState *) const
421 {
422     if (!ch)
423         return QByteArray();
424     if (uclen == 0)
425         return QByteArray("");
426     BOOL used_def;
427     QByteArray mb(4096, 0);
428     int len;
429     while (!(len=WideCharToMultiByte(CP_ACP, 0, (const wchar_t*)ch, uclen,
430                 mb.data(), mb.size()-1, 0, &used_def)))
431     {
432         int r = GetLastError();
433         if (r == ERROR_INSUFFICIENT_BUFFER) {
434             mb.resize(1+WideCharToMultiByte(CP_ACP, 0,
435                                 (const wchar_t*)ch, uclen,
436                                 0, 0, 0, &used_def));
437                 // and try again...
438         } else {
439 #ifndef QT_NO_DEBUG
440             // Fail.
441             qWarning("WideCharToMultiByte: Cannot convert multibyte text (error %d): %s (UTF-8)",
442                 r, QString(ch, uclen).toLocal8Bit().data());
443 #endif
444             break;
445         }
446     }
447     mb.resize(len);
448     return mb;
449 }
450
451
452 QByteArray QWindowsLocalCodec::name() const
453 {
454     return "System";
455 }
456
457 int QWindowsLocalCodec::mibEnum() const
458 {
459     return 0;
460 }
461
462 #else
463
464 /* locale names mostly copied from XFree86 */
465 static const char * const iso8859_2locales[] = {
466     "croatian", "cs", "cs_CS", "cs_CZ","cz", "cz_CZ", "czech", "hr",
467     "hr_HR", "hu", "hu_HU", "hungarian", "pl", "pl_PL", "polish", "ro",
468     "ro_RO", "rumanian", "serbocroatian", "sh", "sh_SP", "sh_YU", "sk",
469     "sk_SK", "sl", "sl_CS", "sl_SI", "slovak", "slovene", "sr_SP", 0 };
470
471 static const char * const iso8859_3locales[] = {
472     "eo", 0 };
473
474 static const char * const iso8859_4locales[] = {
475     "ee", "ee_EE", 0 };
476
477 static const char * const iso8859_5locales[] = {
478     "mk", "mk_MK", "sp", "sp_YU", 0 };
479
480 static const char * const cp_1251locales[] = {
481     "be", "be_BY", "bg", "bg_BG", "bulgarian", 0 };
482
483 static const char * const pt_154locales[] = {
484     "ba_RU", "ky", "ky_KG", "kk", "kk_KZ", 0 };
485
486 static const char * const iso8859_6locales[] = {
487     "ar_AA", "ar_SA", "arabic", 0 };
488
489 static const char * const iso8859_7locales[] = {
490     "el", "el_GR", "greek", 0 };
491
492 static const char * const iso8859_8locales[] = {
493     "hebrew", "he", "he_IL", "iw", "iw_IL", 0 };
494
495 static const char * const iso8859_9locales[] = {
496     "tr", "tr_TR", "turkish", 0 };
497
498 static const char * const iso8859_13locales[] = {
499     "lt", "lt_LT", "lv", "lv_LV", 0 };
500
501 static const char * const iso8859_15locales[] = {
502     "et", "et_EE",
503     // Euro countries
504     "br_FR", "ca_ES", "de", "de_AT", "de_BE", "de_DE", "de_LU", "en_IE",
505     "es", "es_ES", "eu_ES", "fi", "fi_FI", "finnish", "fr", "fr_FR",
506     "fr_BE", "fr_LU", "french", "ga_IE", "gl_ES", "it", "it_IT", "oc_FR",
507     "nl", "nl_BE", "nl_NL", "pt", "pt_PT", "sv_FI", "wa_BE",
508     0 };
509
510 static const char * const koi8_ulocales[] = {
511     "uk", "uk_UA", "ru_UA", "ukrainian", 0 };
512
513 static const char * const tis_620locales[] = {
514     "th", "th_TH", "thai", 0 };
515
516 // static const char * const tcvnlocales[] = {
517 //     "vi", "vi_VN", 0 };
518
519 static bool try_locale_list(const char * const locale[], const QByteArray &lang)
520 {
521     int i;
522     for(i=0; locale[i] && lang != locale[i]; i++)
523         ;
524     return locale[i] != 0;
525 }
526
527 // For the probably_koi8_locales we have to look. the standard says
528 // these are 8859-5, but almost all Russian users use KOI8-R and
529 // incorrectly set $LANG to ru_RU. We'll check tolower() to see what
530 // it thinks ru_RU means.
531
532 // If you read the history, it seems that many Russians blame ISO and
533 // Perestroika for the confusion.
534 //
535 // The real bug is that some programs break if the user specifies
536 // ru_RU.KOI8-R.
537
538 static const char * const probably_koi8_rlocales[] = {
539     "ru", "ru_SU", "ru_RU", "russian", 0 };
540
541 static QTextCodec * ru_RU_hack(const char * i) {
542     QTextCodec * ru_RU_codec = 0;
543
544 #if !defined(QT_NO_SETLOCALE)
545     QByteArray origlocale(setlocale(LC_CTYPE, i));
546 #else
547     QByteArray origlocale(i);
548 #endif
549     // unicode   koi8r   latin5   name
550     // 0x044E    0xC0    0xEE     CYRILLIC SMALL LETTER YU
551     // 0x042E    0xE0    0xCE     CYRILLIC CAPITAL LETTER YU
552     int latin5 = tolower(0xCE);
553     int koi8r = tolower(0xE0);
554     if (koi8r == 0xC0 && latin5 != 0xEE) {
555         ru_RU_codec = QTextCodec::codecForName("KOI8-R");
556     } else if (koi8r != 0xC0 && latin5 == 0xEE) {
557         ru_RU_codec = QTextCodec::codecForName("ISO 8859-5");
558     } else {
559         // something else again... let's assume... *throws dice*
560         ru_RU_codec = QTextCodec::codecForName("KOI8-R");
561         qWarning("QTextCodec: Using KOI8-R, probe failed (%02x %02x %s)",
562                   koi8r, latin5, i);
563     }
564 #if !defined(QT_NO_SETLOCALE)
565     setlocale(LC_CTYPE, origlocale);
566 #endif
567
568     return ru_RU_codec;
569 }
570
571 #endif
572
573 #if !defined(Q_OS_WIN32) && !defined(Q_OS_WINCE)
574 static QTextCodec *checkForCodec(const QByteArray &name) {
575     QTextCodec *c = QTextCodec::codecForName(name);
576     if (!c) {
577         const int index = name.indexOf('@');
578         if (index != -1) {
579             c = QTextCodec::codecForName(name.left(index));
580         }
581     }
582     return c;
583 }
584 #endif
585
586 /* the next two functions are implicitely thread safe,
587    as they are only called by setup() which uses a mutex.
588 */
589 static void setupLocaleMapper()
590 {
591 #ifdef Q_OS_SYMBIAN
592     localeMapper = QSymbianTextCodec::localeMapper;
593     if (localeMapper)
594         return;
595 #endif
596
597 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
598     localeMapper = QTextCodec::codecForName("System");
599 #else
600
601 #ifndef QT_NO_ICONV
602     localeMapper = QTextCodec::codecForName("System");
603 #endif
604
605 #if defined (_XOPEN_UNIX) && !defined(Q_OS_QNX) && !defined(Q_OS_OSF) && !defined(Q_OS_ANDROID)
606     if (!localeMapper) {
607         char *charset = nl_langinfo (CODESET);
608         if (charset)
609             localeMapper = QTextCodec::codecForName(charset);
610     }
611 #endif
612
613     if (!localeMapper) {
614         // Very poorly defined and followed standards causes lots of
615         // code to try to get all the cases... This logic is
616         // duplicated in QIconvCodec, so if you change it here, change
617         // it there too.
618
619         // Try to determine locale codeset from locale name assigned to
620         // LC_CTYPE category.
621
622         // First part is getting that locale name.  First try setlocale() which
623         // definitely knows it, but since we cannot fully trust it, get ready
624         // to fall back to environment variables.
625 #if !defined(QT_NO_SETLOCALE)
626         const QByteArray ctype = setlocale(LC_CTYPE, 0);
627 #else
628         const QByteArray ctype;
629 #endif
630
631         // Get the first nonempty value from $LC_ALL, $LC_CTYPE, and $LANG
632         // environment variables.
633         QByteArray lang = qgetenv("LC_ALL");
634         if (lang.isEmpty() || lang == "C") {
635             lang = qgetenv("LC_CTYPE");
636         }
637         if (lang.isEmpty() || lang == "C") {
638             lang = qgetenv("LANG");
639         }
640
641         // Now try these in order:
642         // 1. CODESET from ctype if it contains a .CODESET part (e.g. en_US.ISO8859-15)
643         // 2. CODESET from lang if it contains a .CODESET part
644         // 3. ctype (maybe the locale is named "ISO-8859-1" or something)
645         // 4. locale (ditto)
646         // 5. check for "@euro"
647         // 6. guess locale from ctype unless ctype is "C"
648         // 7. guess locale from lang
649
650         // 1. CODESET from ctype if it contains a .CODESET part (e.g. en_US.ISO8859-15)
651         int indexOfDot = ctype.indexOf('.');
652         if (indexOfDot != -1)
653             localeMapper = checkForCodec( ctype.mid(indexOfDot + 1) );
654
655         // 2. CODESET from lang if it contains a .CODESET part
656         if (!localeMapper) {
657             indexOfDot = lang.indexOf('.');
658             if (indexOfDot != -1)
659                 localeMapper = checkForCodec( lang.mid(indexOfDot + 1) );
660         }
661
662         // 3. ctype (maybe the locale is named "ISO-8859-1" or something)
663         if (!localeMapper && !ctype.isEmpty() && ctype != "C")
664             localeMapper = checkForCodec(ctype);
665
666         // 4. locale (ditto)
667         if (!localeMapper && !lang.isEmpty())
668             localeMapper = checkForCodec(lang);
669
670         // 5. "@euro"
671         if ((!localeMapper && ctype.contains("@euro")) || lang.contains("@euro"))
672             localeMapper = checkForCodec("ISO 8859-15");
673
674         // 6. guess locale from ctype unless ctype is "C"
675         // 7. guess locale from lang
676         const QByteArray &try_by_name = (!ctype.isEmpty() && ctype != "C") ? lang : ctype;
677
678         // Now do the guessing.
679         if (!lang.isEmpty() && !localeMapper && !try_by_name.isEmpty()) {
680             if (try_locale_list(iso8859_15locales, lang))
681                 localeMapper = QTextCodec::codecForName("ISO 8859-15");
682             else if (try_locale_list(iso8859_2locales, lang))
683                 localeMapper = QTextCodec::codecForName("ISO 8859-2");
684             else if (try_locale_list(iso8859_3locales, lang))
685                 localeMapper = QTextCodec::codecForName("ISO 8859-3");
686             else if (try_locale_list(iso8859_4locales, lang))
687                 localeMapper = QTextCodec::codecForName("ISO 8859-4");
688             else if (try_locale_list(iso8859_5locales, lang))
689                 localeMapper = QTextCodec::codecForName("ISO 8859-5");
690             else if (try_locale_list(iso8859_6locales, lang))
691                 localeMapper = QTextCodec::codecForName("ISO 8859-6");
692             else if (try_locale_list(iso8859_7locales, lang))
693                 localeMapper = QTextCodec::codecForName("ISO 8859-7");
694             else if (try_locale_list(iso8859_8locales, lang))
695                 localeMapper = QTextCodec::codecForName("ISO 8859-8-I");
696             else if (try_locale_list(iso8859_9locales, lang))
697                 localeMapper = QTextCodec::codecForName("ISO 8859-9");
698             else if (try_locale_list(iso8859_13locales, lang))
699                 localeMapper = QTextCodec::codecForName("ISO 8859-13");
700             else if (try_locale_list(tis_620locales, lang))
701                 localeMapper = QTextCodec::codecForName("ISO 8859-11");
702             else if (try_locale_list(koi8_ulocales, lang))
703                 localeMapper = QTextCodec::codecForName("KOI8-U");
704             else if (try_locale_list(cp_1251locales, lang))
705                 localeMapper = QTextCodec::codecForName("CP 1251");
706             else if (try_locale_list(pt_154locales, lang))
707                 localeMapper = QTextCodec::codecForName("PT 154");
708             else if (try_locale_list(probably_koi8_rlocales, lang))
709                 localeMapper = ru_RU_hack(lang);
710         }
711
712     }
713
714     // If everything failed, we default to 8859-1
715     // We could perhaps default to 8859-15.
716     if (!localeMapper)
717         localeMapper = QTextCodec::codecForName("ISO 8859-1");
718 #endif
719 }
720
721 #ifndef QT_NO_THREAD
722 Q_GLOBAL_STATIC_WITH_ARGS(QMutex, textCodecsMutex, (QMutex::Recursive));
723 #endif
724
725 // textCodecsMutex need to be locked to enter this function
726 static void setup()
727 {
728     if (all)
729         return;
730
731 #ifdef Q_OS_SYMBIAN
732     // If we don't have a trap handler, we're outside of the main() function,
733     // ie. in global constructors or destructors. Don't create codecs in this
734     // case as it would lead to crashes because of a missing cleanup stack on Symbian
735     if (User::TrapHandler() == NULL)
736         return;
737 #endif
738
739 #ifdef Q_DEBUG_TEXTCODEC
740     if (destroying_is_ok)
741         qWarning("QTextCodec: Creating new codec during codec cleanup");
742 #endif
743     all = new QList<QTextCodec*>;
744     // create the cleanup object to cleanup all codecs on exit
745     (void) createQTextCodecCleanup();
746
747 #ifndef QT_NO_CODECS
748     (void)new QTsciiCodec;
749     for (int i = 0; i < 9; ++i)
750         (void)new QIsciiCodec(i);
751
752     for (int i = 0; i < QSimpleTextCodec::numSimpleCodecs; ++i)
753         (void)new QSimpleTextCodec(i);
754
755 #ifdef Q_OS_SYMBIAN
756     localeMapper = QSymbianTextCodec::init();
757 #endif
758
759 #  if defined(Q_WS_X11) && !defined(QT_BOOTSTRAPPED)
760     // no font codecs when bootstrapping
761     (void)new QFontLaoCodec;
762 #    if defined(QT_NO_ICONV)
763     // no iconv(3) support, must build all codecs into the library
764     (void)new QFontGb2312Codec;
765     (void)new QFontGbkCodec;
766     (void)new QFontGb18030_0Codec;
767     (void)new QFontJis0208Codec;
768     (void)new QFontJis0201Codec;
769     (void)new QFontKsc5601Codec;
770     (void)new QFontBig5hkscsCodec;
771     (void)new QFontBig5Codec;
772 #    endif // QT_NO_ICONV && !QT_BOOTSTRAPPED
773 #  endif // Q_WS_X11
774
775
776 #if !defined(Q_OS_SYMBIAN) && !defined(Q_OS_INTEGRITY)
777 #  if defined(QT_NO_ICONV) && !defined(QT_BOOTSTRAPPED)
778     // no asian codecs when bootstrapping, sorry
779     (void)new QGb18030Codec;
780     (void)new QGbkCodec;
781     (void)new QGb2312Codec;
782     (void)new QEucJpCodec;
783     (void)new QJisCodec;
784     (void)new QSjisCodec;
785     (void)new QEucKrCodec;
786     (void)new QCP949Codec;
787     (void)new QBig5Codec;
788     (void)new QBig5hkscsCodec;
789 #  endif // QT_NO_ICONV && !QT_BOOTSTRAPPED
790 #endif //Q_OS_SYMBIAN
791 #endif // QT_NO_CODECS
792
793 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
794     (void) new QWindowsLocalCodec;
795 #endif // Q_OS_WIN32
796
797     (void)new QUtf16Codec;
798     (void)new QUtf16BECodec;
799     (void)new QUtf16LECodec;
800     (void)new QUtf32Codec;
801     (void)new QUtf32BECodec;
802     (void)new QUtf32LECodec;
803 #ifndef Q_OS_SYMBIAN
804     (void)new QLatin15Codec;
805 #endif
806     (void)new QLatin1Codec;
807     (void)new QUtf8Codec;
808
809 #if !defined(Q_OS_SYMBIAN) && !defined(Q_OS_INTEGRITY)
810 #if defined(Q_OS_UNIX) && !defined(QT_NO_ICONV) && !defined(QT_BOOTSTRAPPED)
811     // QIconvCodec depends on the UTF-16 codec, so it needs to be created last
812     (void) new QIconvCodec();
813 #endif
814 #endif
815
816     if (!localeMapper)
817         setupLocaleMapper();
818 }
819
820 /*!
821     \enum QTextCodec::ConversionFlag
822
823     \value DefaultConversion  No flag is set.
824     \value ConvertInvalidToNull  If this flag is set, each invalid input
825                                  character is output as a null character.
826     \value IgnoreHeader  Ignore any Unicode byte-order mark and don't generate any.
827
828     \omitvalue FreeFunction
829 */
830
831 /*!
832     \fn QTextCodec::ConverterState::ConverterState(ConversionFlags flags)
833
834     Constructs a ConverterState object initialized with the given \a flags.
835 */
836
837 /*!
838     Destroys the ConverterState object.
839 */
840 QTextCodec::ConverterState::~ConverterState()
841 {
842     if (flags & FreeFunction)
843         (QTextCodecUnalignedPointer::decode(state_data))(this);
844     else if (d)
845         qFree(d);
846 }
847
848 /*!
849     \class QTextCodec
850     \brief The QTextCodec class provides conversions between text encodings.
851     \reentrant
852     \ingroup i18n
853
854     Qt uses Unicode to store, draw and manipulate strings. In many
855     situations you may wish to deal with data that uses a different
856     encoding. For example, most Japanese documents are still stored
857     in Shift-JIS or ISO 2022-JP, while Russian users often have their
858     documents in KOI8-R or Windows-1251.
859
860     Qt provides a set of QTextCodec classes to help with converting
861     non-Unicode formats to and from Unicode. You can also create your
862     own codec classes.
863
864     The supported encodings are:
865
866     \list
867     \o Apple Roman
868     \o \l{Big5 Text Codec}{Big5}
869     \o \l{Big5-HKSCS Text Codec}{Big5-HKSCS}
870     \o CP949
871     \o \l{EUC-JP Text Codec}{EUC-JP}
872     \o \l{EUC-KR Text Codec}{EUC-KR}
873     \o \l{GBK Text Codec}{GB18030-0}
874     \o IBM 850
875     \o IBM 866
876     \o IBM 874
877     \o \l{ISO 2022-JP (JIS) Text Codec}{ISO 2022-JP}
878     \o ISO 8859-1 to 10
879     \o ISO 8859-13 to 16
880     \o Iscii-Bng, Dev, Gjr, Knd, Mlm, Ori, Pnj, Tlg, and Tml
881     \o JIS X 0201
882     \o JIS X 0208
883     \o KOI8-R
884     \o KOI8-U
885     \o MuleLao-1
886     \o ROMAN8
887     \o \l{Shift-JIS Text Codec}{Shift-JIS}
888     \o TIS-620
889     \o \l{TSCII Text Codec}{TSCII}
890     \o UTF-8
891     \o UTF-16
892     \o UTF-16BE
893     \o UTF-16LE
894     \o UTF-32
895     \o UTF-32BE
896     \o UTF-32LE
897     \o Windows-1250 to 1258
898     \o WINSAMI2
899     \endlist
900
901     QTextCodecs can be used as follows to convert some locally encoded
902     string to Unicode. Suppose you have some string encoded in Russian
903     KOI8-R encoding, and want to convert it to Unicode. The simple way
904     to do it is like this:
905
906     \snippet doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp 0
907
908     After this, \c string holds the text converted to Unicode.
909     Converting a string from Unicode to the local encoding is just as
910     easy:
911
912     \snippet doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp 1
913
914     To read or write files in various encodings, use QTextStream and
915     its \l{QTextStream::setCodec()}{setCodec()} function. See the
916     \l{tools/codecs}{Codecs} example for an application of QTextCodec
917     to file I/O.
918
919     Some care must be taken when trying to convert the data in chunks,
920     for example, when receiving it over a network. In such cases it is
921     possible that a multi-byte character will be split over two
922     chunks. At best this might result in the loss of a character and
923     at worst cause the entire conversion to fail.
924
925     The approach to use in these situations is to create a QTextDecoder
926     object for the codec and use this QTextDecoder for the whole
927     decoding process, as shown below:
928
929     \snippet doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp 2
930
931     The QTextDecoder object maintains state between chunks and therefore
932     works correctly even if a multi-byte character is split between
933     chunks.
934
935     \section1 Creating Your Own Codec Class
936
937     Support for new text encodings can be added to Qt by creating
938     QTextCodec subclasses.
939
940     The pure virtual functions describe the encoder to the system and
941     the coder is used as required in the different text file formats
942     supported by QTextStream, and under X11, for the locale-specific
943     character input and output.
944
945     To add support for another encoding to Qt, make a subclass of
946     QTextCodec and implement the functions listed in the table below.
947
948     \table
949     \header \o Function \o Description
950
951     \row \o name()
952          \o Returns the official name for the encoding. If the
953             encoding is listed in the
954             \l{IANA character-sets encoding file}, the name
955             should be the preferred MIME name for the encoding.
956
957     \row \o aliases()
958          \o Returns a list of alternative names for the encoding.
959             QTextCodec provides a default implementation that returns
960             an empty list. For example, "ISO-8859-1" has "latin1",
961             "CP819", "IBM819", and "iso-ir-100" as aliases.
962
963     \row \o mibEnum()
964          \o Return the MIB enum for the encoding if it is listed in
965             the \l{IANA character-sets encoding file}.
966
967     \row \o convertToUnicode()
968          \o Converts an 8-bit character string to Unicode.
969
970     \row \o convertFromUnicode()
971          \o Converts a Unicode string to an 8-bit character string.
972     \endtable
973
974     You may find it more convenient to make your codec class
975     available as a plugin; see \l{How to Create Qt Plugins} for
976     details.
977
978     \sa QTextStream, QTextDecoder, QTextEncoder, {Codecs Example}
979 */
980
981 /*!
982     Constructs a QTextCodec, and gives it the highest precedence. The
983     QTextCodec should always be constructed on the heap (i.e. with \c
984     new). Qt takes ownership and will delete it when the application
985     terminates.
986 */
987 QTextCodec::QTextCodec()
988 {
989 #ifndef QT_NO_THREAD
990     QMutexLocker locker(textCodecsMutex());
991 #endif
992     setup();
993     all->prepend(this);
994 }
995
996
997 /*!
998     \nonreentrant
999
1000     Destroys the QTextCodec. Note that you should not delete codecs
1001     yourself: once created they become Qt's responsibility.
1002 */
1003 QTextCodec::~QTextCodec()
1004 {
1005 #ifdef Q_DEBUG_TEXTCODEC
1006     if (!destroying_is_ok)
1007         qWarning("QTextCodec::~QTextCodec: Called by application");
1008 #endif
1009     if (all) {
1010 #ifndef QT_NO_THREAD
1011         QMutexLocker locker(textCodecsMutex());
1012 #endif
1013         all->removeAll(this);
1014         QTextCodecCache *cache = qTextCodecCache();
1015         if (cache)
1016             cache->clear();
1017     }
1018 }
1019
1020 /*!
1021     \fn QTextCodec *QTextCodec::codecForName(const char *name)
1022
1023     Searches all installed QTextCodec objects and returns the one
1024     which best matches \a name; the match is case-insensitive. Returns
1025     0 if no codec matching the name \a name could be found.
1026 */
1027
1028 /*!
1029     Searches all installed QTextCodec objects and returns the one
1030     which best matches \a name; the match is case-insensitive. Returns
1031     0 if no codec matching the name \a name could be found.
1032 */
1033 QTextCodec *QTextCodec::codecForName(const QByteArray &name)
1034 {
1035     if (name.isEmpty())
1036         return 0;
1037
1038 #ifndef QT_NO_THREAD
1039     QMutexLocker locker(textCodecsMutex());
1040 #endif
1041     setup();
1042
1043     if (!validCodecs())
1044         return 0;
1045
1046     QTextCodecCache *cache = qTextCodecCache();
1047     QTextCodec *codec;
1048     if (cache) {
1049         codec = cache->value(name);
1050         if (codec)
1051             return codec;
1052     }
1053
1054     for (int i = 0; i < all->size(); ++i) {
1055         QTextCodec *cursor = all->at(i);
1056         if (nameMatch(cursor->name(), name)) {
1057             if (cache)
1058                 cache->insert(name, cursor);
1059             return cursor;
1060         }
1061         QList<QByteArray> aliases = cursor->aliases();
1062         for (int y = 0; y < aliases.size(); ++y)
1063             if (nameMatch(aliases.at(y), name)) {
1064                 if (cache)
1065                     cache->insert(name, cursor);
1066                 return cursor;
1067             }
1068     }
1069
1070     codec = createForName(name);
1071     if (codec && cache)
1072         cache->insert(name, codec);
1073     return codec;
1074 }
1075
1076
1077 /*!
1078     Returns the QTextCodec which matches the \link
1079     QTextCodec::mibEnum() MIBenum\endlink \a mib.
1080 */
1081 QTextCodec* QTextCodec::codecForMib(int mib)
1082 {
1083 #ifndef QT_NO_THREAD
1084     QMutexLocker locker(textCodecsMutex());
1085 #endif
1086     setup();
1087
1088     if (!validCodecs())
1089         return 0;
1090
1091     QByteArray key = "MIB: " + QByteArray::number(mib);
1092     QTextCodecCache *cache = qTextCodecCache();
1093     QTextCodec *codec;
1094     if (cache) {
1095         codec = cache->value(key);
1096         if (codec)
1097             return codec;
1098     }
1099
1100     QList<QTextCodec*>::ConstIterator i;
1101     for (int i = 0; i < all->size(); ++i) {
1102         QTextCodec *cursor = all->at(i);
1103         if (cursor->mibEnum() == mib) {
1104             if (cache)
1105                 cache->insert(key, cursor);
1106             return cursor;
1107         }
1108     }
1109
1110     codec = createForMib(mib);
1111
1112     // Qt 3 used 1000 (mib for UCS2) as its identifier for the utf16 codec. Map
1113     // this correctly for compatibility.
1114     if (!codec && mib == 1000)
1115         return codecForMib(1015);
1116
1117     if (codec && cache)
1118         cache->insert(key, codec);
1119     return codec;
1120 }
1121
1122 /*!
1123     Returns the list of all available codecs, by name. Call
1124     QTextCodec::codecForName() to obtain the QTextCodec for the name.
1125
1126     The list may contain many mentions of the same codec
1127     if the codec has aliases.
1128
1129     \sa availableMibs(), name(), aliases()
1130 */
1131 QList<QByteArray> QTextCodec::availableCodecs()
1132 {
1133 #ifndef QT_NO_THREAD
1134     QMutexLocker locker(textCodecsMutex());
1135 #endif
1136     setup();
1137
1138     QList<QByteArray> codecs;
1139
1140     if (!validCodecs())
1141         return codecs;
1142
1143     for (int i = 0; i < all->size(); ++i) {
1144         codecs += all->at(i)->name();
1145         codecs += all->at(i)->aliases();
1146     }
1147
1148 #ifndef QT_NO_THREAD
1149     locker.unlock();
1150 #endif
1151
1152 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_TEXTCODECPLUGIN)
1153     QFactoryLoader *l = loader();
1154     QStringList keys = l->keys();
1155     for (int i = 0; i < keys.size(); ++i) {
1156         if (!keys.at(i).startsWith(QLatin1String("MIB: "))) {
1157             QByteArray name = keys.at(i).toLatin1();
1158             if (!codecs.contains(name))
1159                 codecs += name;
1160         }
1161     }
1162 #endif
1163
1164     return codecs;
1165 }
1166
1167 /*!
1168     Returns the list of MIBs for all available codecs. Call
1169     QTextCodec::codecForMib() to obtain the QTextCodec for the MIB.
1170
1171     \sa availableCodecs(), mibEnum()
1172 */
1173 QList<int> QTextCodec::availableMibs()
1174 {
1175 #ifndef QT_NO_THREAD
1176     QMutexLocker locker(textCodecsMutex());
1177 #endif
1178     setup();
1179
1180     QList<int> codecs;
1181
1182     if (!validCodecs())
1183         return codecs;
1184
1185     for (int i = 0; i < all->size(); ++i)
1186         codecs += all->at(i)->mibEnum();
1187
1188 #ifndef QT_NO_THREAD
1189     locker.unlock();
1190 #endif
1191
1192 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_TEXTCODECPLUGIN)
1193     QFactoryLoader *l = loader();
1194     QStringList keys = l->keys();
1195     for (int i = 0; i < keys.size(); ++i) {
1196         if (keys.at(i).startsWith(QLatin1String("MIB: "))) {
1197             int mib = keys.at(i).mid(5).toInt();
1198             if (!codecs.contains(mib))
1199                 codecs += mib;
1200         }
1201     }
1202 #endif
1203
1204     return codecs;
1205 }
1206
1207 /*!
1208     Set the codec to \a c; this will be returned by
1209     codecForLocale(). If \a c is a null pointer, the codec is reset to
1210     the default.
1211
1212     This might be needed for some applications that want to use their
1213     own mechanism for setting the locale.
1214
1215     \sa codecForLocale()
1216 */
1217 void QTextCodec::setCodecForLocale(QTextCodec *c)
1218 {
1219 #ifndef QT_NO_THREAD
1220     QMutexLocker locker(textCodecsMutex());
1221 #endif
1222     localeMapper = c;
1223     if (!localeMapper)
1224         setupLocaleMapper();
1225 }
1226
1227 /*!
1228     Returns a pointer to the codec most suitable for this locale.
1229
1230     On Windows, the codec will be based on a system locale. On Unix
1231     systems, starting with Qt 4.2, the codec will be using the \e
1232     iconv library. Note that in both cases the codec's name will be
1233     "System".
1234 */
1235
1236 QTextCodec* QTextCodec::codecForLocale()
1237 {
1238     if (!validCodecs())
1239         return 0;
1240
1241     if (localeMapper)
1242         return localeMapper;
1243
1244 #ifndef QT_NO_THREAD
1245     QMutexLocker locker(textCodecsMutex());
1246 #endif
1247     setup();
1248
1249     return localeMapper;
1250 }
1251
1252
1253 /*!
1254     \fn QByteArray QTextCodec::name() const
1255
1256     QTextCodec subclasses must reimplement this function. It returns
1257     the name of the encoding supported by the subclass.
1258
1259     If the codec is registered as a character set in the
1260     \l{IANA character-sets encoding file} this method should
1261     return the preferred mime name for the codec if defined,
1262     otherwise its name.
1263 */
1264
1265 /*!
1266     \fn int QTextCodec::mibEnum() const
1267
1268     Subclasses of QTextCodec must reimplement this function. It
1269     returns the MIBenum (see \l{IANA character-sets encoding file}
1270     for more information). It is important that each QTextCodec
1271     subclass returns the correct unique value for this function.
1272 */
1273
1274 /*!
1275   Subclasses can return a number of aliases for the codec in question.
1276
1277   Standard aliases for codecs can be found in the
1278   \l{IANA character-sets encoding file}.
1279 */
1280 QList<QByteArray> QTextCodec::aliases() const
1281 {
1282     return QList<QByteArray>();
1283 }
1284
1285 /*!
1286     \fn QString QTextCodec::convertToUnicode(const char *chars, int len,
1287                                              ConverterState *state) const
1288
1289     QTextCodec subclasses must reimplement this function.
1290
1291     Converts the first \a len characters of \a chars from the
1292     encoding of the subclass to Unicode, and returns the result in a
1293     QString.
1294
1295     \a state can be 0, in which case the conversion is stateless and
1296     default conversion rules should be used. If state is not 0, the
1297     codec should save the state after the conversion in \a state, and
1298     adjust the remainingChars and invalidChars members of the struct.
1299 */
1300
1301 /*!
1302     \fn QByteArray QTextCodec::convertFromUnicode(const QChar *input, int number,
1303                                                   ConverterState *state) const
1304
1305     QTextCodec subclasses must reimplement this function.
1306
1307     Converts the first \a number of characters from the \a input array
1308     from Unicode to the encoding of the subclass, and returns the result
1309     in a QByteArray.
1310
1311     \a state can be 0 in which case the conversion is stateless and
1312     default conversion rules should be used. If state is not 0, the
1313     codec should save the state after the conversion in \a state, and
1314     adjust the remainingChars and invalidChars members of the struct.
1315 */
1316
1317 /*!
1318     Creates a QTextDecoder which stores enough state to decode chunks
1319     of \c{char *} data to create chunks of Unicode data.
1320
1321     The caller is responsible for deleting the returned object.
1322 */
1323 QTextDecoder* QTextCodec::makeDecoder() const
1324 {
1325     return new QTextDecoder(this);
1326 }
1327
1328 /*!
1329     Creates a QTextDecoder with a specified \a flags to decode chunks
1330     of \c{char *} data to create chunks of Unicode data.
1331
1332     The caller is responsible for deleting the returned object.
1333
1334     \since 4.7
1335 */
1336 QTextDecoder* QTextCodec::makeDecoder(QTextCodec::ConversionFlags flags) const
1337 {
1338     return new QTextDecoder(this, flags);
1339 }
1340
1341
1342 /*!
1343     Creates a QTextEncoder which stores enough state to encode chunks
1344     of Unicode data as \c{char *} data.
1345
1346     The caller is responsible for deleting the returned object.
1347 */
1348 QTextEncoder* QTextCodec::makeEncoder() const
1349 {
1350     return new QTextEncoder(this);
1351 }
1352
1353 /*!
1354     Creates a QTextEncoder with a specified \a flags to encode chunks
1355     of Unicode data as \c{char *} data.
1356
1357     The caller is responsible for deleting the returned object.
1358
1359     \since 4.7
1360 */
1361 QTextEncoder* QTextCodec::makeEncoder(QTextCodec::ConversionFlags flags) const
1362 {
1363     return new QTextEncoder(this, flags);
1364 }
1365
1366 /*!
1367     \fn QByteArray QTextCodec::fromUnicode(const QChar *input, int number,
1368                                            ConverterState *state) const
1369
1370     Converts the first \a number of characters from the \a input array
1371     from Unicode to the encoding of this codec, and returns the result
1372     in a QByteArray.
1373
1374     The \a state of the convertor used is updated.
1375 */
1376
1377 /*!
1378     Converts \a str from Unicode to the encoding of this codec, and
1379     returns the result in a QByteArray.
1380 */
1381 QByteArray QTextCodec::fromUnicode(const QString& str) const
1382 {
1383     return convertFromUnicode(str.constData(), str.length(), 0);
1384 }
1385
1386 /*!
1387     \fn QString QTextCodec::toUnicode(const char *input, int size,
1388                                       ConverterState *state) const
1389
1390     Converts the first \a size characters from the \a input from the
1391     encoding of this codec to Unicode, and returns the result in a
1392     QString.
1393
1394     The \a state of the convertor used is updated.
1395 */
1396
1397 /*!
1398     Converts \a a from the encoding of this codec to Unicode, and
1399     returns the result in a QString.
1400 */
1401 QString QTextCodec::toUnicode(const QByteArray& a) const
1402 {
1403     return convertToUnicode(a.constData(), a.length(), 0);
1404 }
1405
1406 /*!
1407     Returns true if the Unicode character \a ch can be fully encoded
1408     with this codec; otherwise returns false.
1409 */
1410 bool QTextCodec::canEncode(QChar ch) const
1411 {
1412     ConverterState state;
1413     state.flags = ConvertInvalidToNull;
1414     convertFromUnicode(&ch, 1, &state);
1415     return (state.invalidChars == 0);
1416 }
1417
1418 /*!
1419     \overload
1420
1421     \a s contains the string being tested for encode-ability.
1422 */
1423 bool QTextCodec::canEncode(const QString& s) const
1424 {
1425     ConverterState state;
1426     state.flags = ConvertInvalidToNull;
1427     convertFromUnicode(s.constData(), s.length(), &state);
1428     return (state.invalidChars == 0);
1429 }
1430
1431 #ifdef QT3_SUPPORT
1432 /*!
1433     Returns a string representing the current language and
1434     sublanguage, e.g. "pt" for Portuguese, or "pt_br" for Portuguese/Brazil.
1435
1436     \sa QLocale
1437 */
1438 const char *QTextCodec::locale()
1439 {
1440     static char locale[6];
1441     QByteArray l = QLocale::system().name().toLatin1();
1442     int len = qMin(l.length(), 5);
1443     memcpy(locale, l.constData(), len);
1444     locale[len] = '\0';
1445
1446     return locale;
1447 }
1448
1449 /*!
1450     \overload
1451 */
1452
1453 QByteArray QTextCodec::fromUnicode(const QString& uc, int& lenInOut) const
1454 {
1455     QByteArray result = convertFromUnicode(uc.constData(), lenInOut, 0);
1456     lenInOut = result.length();
1457     return result;
1458 }
1459
1460 /*!
1461     \overload
1462
1463     \a a contains the source characters; \a len contains the number of
1464     characters in \a a to use.
1465 */
1466 QString QTextCodec::toUnicode(const QByteArray& a, int len) const
1467 {
1468     len = qMin(a.size(), len);
1469     return convertToUnicode(a.constData(), len, 0);
1470 }
1471 #endif
1472
1473 /*!
1474     \overload
1475
1476     \a chars contains the source characters.
1477 */
1478 QString QTextCodec::toUnicode(const char *chars) const
1479 {
1480     int len = qstrlen(chars);
1481     return convertToUnicode(chars, len, 0);
1482 }
1483
1484
1485 /*!
1486     \class QTextEncoder
1487     \brief The QTextEncoder class provides a state-based encoder.
1488     \reentrant
1489     \ingroup i18n
1490
1491     A text encoder converts text from Unicode into an encoded text format
1492     using a specific codec.
1493
1494     The encoder converts Unicode into another format, remembering any
1495     state that is required between calls.
1496
1497     \sa QTextCodec::makeEncoder(), QTextDecoder
1498 */
1499
1500 /*!
1501     \fn QTextEncoder::QTextEncoder(const QTextCodec *codec)
1502
1503     Constructs a text encoder for the given \a codec.
1504 */
1505
1506 /*!
1507     Constructs a text encoder for the given \a codec and conversion \a flags.
1508
1509     \since 4.7
1510 */
1511 QTextEncoder::QTextEncoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags)
1512     : c(codec), state()
1513 {
1514     state.flags = flags;
1515 }
1516
1517 /*!
1518     Destroys the encoder.
1519 */
1520 QTextEncoder::~QTextEncoder()
1521 {
1522 }
1523
1524 /*! \internal
1525     \since 4.5
1526     Determines whether the eecoder encountered a failure while decoding the input. If
1527     an error was encountered, the produced result is undefined, and gets converted as according
1528     to the conversion flags.
1529  */
1530 bool QTextEncoder::hasFailure() const
1531 {
1532     return state.invalidChars != 0;
1533 }
1534
1535 /*!
1536     Converts the Unicode string \a str into an encoded QByteArray.
1537 */
1538 QByteArray QTextEncoder::fromUnicode(const QString& str)
1539 {
1540     QByteArray result = c->fromUnicode(str.constData(), str.length(), &state);
1541     return result;
1542 }
1543
1544 /*!
1545     \overload
1546
1547     Converts \a len characters (not bytes) from \a uc, and returns the
1548     result in a QByteArray.
1549 */
1550 QByteArray QTextEncoder::fromUnicode(const QChar *uc, int len)
1551 {
1552     QByteArray result = c->fromUnicode(uc, len, &state);
1553     return result;
1554 }
1555
1556 #ifdef QT3_SUPPORT
1557 /*!
1558   \overload
1559
1560   Converts \a lenInOut characters (not bytes) from \a uc, and returns the
1561   result in a QByteArray. The number of characters read is returned in
1562   the \a lenInOut parameter.
1563 */
1564 QByteArray QTextEncoder::fromUnicode(const QString& uc, int& lenInOut)
1565 {
1566     QByteArray result = c->fromUnicode(uc.constData(), lenInOut, &state);
1567     lenInOut = result.length();
1568     return result;
1569 }
1570 #endif
1571
1572 /*!
1573     \class QTextDecoder
1574     \brief The QTextDecoder class provides a state-based decoder.
1575     \reentrant
1576     \ingroup i18n
1577
1578     A text decoder converts text from an encoded text format into Unicode
1579     using a specific codec.
1580
1581     The decoder converts text in this format into Unicode, remembering any
1582     state that is required between calls.
1583
1584     \sa QTextCodec::makeDecoder(), QTextEncoder
1585 */
1586
1587 /*!
1588     \fn QTextDecoder::QTextDecoder(const QTextCodec *codec)
1589
1590     Constructs a text decoder for the given \a codec.
1591 */
1592
1593 /*!
1594     Constructs a text decoder for the given \a codec and conversion \a flags.
1595
1596     \since 4.7
1597 */
1598
1599 QTextDecoder::QTextDecoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags)
1600     : c(codec), state()
1601 {
1602     state.flags = flags;
1603 }
1604
1605 /*!
1606     Destroys the decoder.
1607 */
1608 QTextDecoder::~QTextDecoder()
1609 {
1610 }
1611
1612 /*!
1613     \fn QString QTextDecoder::toUnicode(const char *chars, int len)
1614
1615     Converts the first \a len bytes in \a chars to Unicode, returning
1616     the result.
1617
1618     If not all characters are used (e.g. if only part of a multi-byte
1619     encoding is at the end of the characters), the decoder remembers
1620     enough state to continue with the next call to this function.
1621 */
1622 QString QTextDecoder::toUnicode(const char *chars, int len)
1623 {
1624     return c->toUnicode(chars, len, &state);
1625 }
1626
1627
1628 /*! \overload
1629
1630     The converted string is returned in \a target.
1631  */
1632 void QTextDecoder::toUnicode(QString *target, const char *chars, int len)
1633 {
1634     Q_ASSERT(target);
1635     switch (c->mibEnum()) {
1636     case 106: // utf8
1637         static_cast<const QUtf8Codec*>(c)->convertToUnicode(target, chars, len, &state);
1638         break;
1639     case 4: { // latin1
1640         target->resize(len);
1641         ushort *data = (ushort*)target->data();
1642         for (int i = len; i >=0; --i)
1643             data[i] = (uchar) chars[i];
1644     } break;
1645     default:
1646         *target = c->toUnicode(chars, len, &state);
1647     }
1648 }
1649
1650
1651 /*!
1652     \overload
1653
1654     Converts the bytes in the byte array specified by \a ba to Unicode
1655     and returns the result.
1656 */
1657 QString QTextDecoder::toUnicode(const QByteArray &ba)
1658 {
1659     return c->toUnicode(ba.constData(), ba.length(), &state);
1660 }
1661
1662
1663 /*!
1664     \fn QTextCodec* QTextCodec::codecForTr()
1665
1666     Returns the codec used by QObject::tr() on its argument. If this
1667     function returns 0 (the default), tr() assumes Latin-1.
1668
1669     \sa setCodecForTr()
1670 */
1671
1672 /*!
1673     \fn void QTextCodec::setCodecForTr(QTextCodec *c)
1674     \nonreentrant
1675
1676     Sets the codec used by QObject::tr() on its argument to \a c. If
1677     \a c is 0 (the default), tr() assumes Latin-1.
1678
1679     If the literal quoted text in the program is not in the Latin-1
1680     encoding, this function can be used to set the appropriate
1681     encoding. For example, software developed by Korean programmers
1682     might use eucKR for all the text in the program, in which case the
1683     main() function might look like this:
1684
1685     \snippet doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp 3
1686
1687     Note that this is not the way to select the encoding that the \e
1688     user has chosen. For example, to convert an application containing
1689     literal English strings to Korean, all that is needed is for the
1690     English strings to be passed through tr() and for translation
1691     files to be loaded. For details of internationalization, see
1692     \l{Internationalization with Qt}.
1693
1694     \sa codecForTr(), setCodecForCStrings()
1695 */
1696
1697
1698 /*!
1699     \fn QTextCodec* QTextCodec::codecForCStrings()
1700
1701     Returns the codec used by QString to convert to and from \c{const
1702     char *} and QByteArrays. If this function returns 0 (the default),
1703     QString assumes Latin-1.
1704
1705     \sa setCodecForCStrings()
1706 */
1707
1708 /*!
1709     \fn void QTextCodec::setCodecForCStrings(QTextCodec *codec)
1710     \nonreentrant
1711
1712     Sets the codec used by QString to convert to and from \c{const
1713     char *} and QByteArrays. If the \a codec is 0 (the default),
1714     QString assumes Latin-1.
1715
1716     \warning Some codecs do not preserve the characters in the ASCII
1717     range (0x00 to 0x7F). For example, the Japanese Shift-JIS
1718     encoding maps the backslash character (0x5A) to the Yen
1719     character. To avoid undesirable side-effects, we recommend
1720     avoiding such codecs with setCodecsForCString().
1721
1722     \sa codecForCStrings(), setCodecForTr()
1723 */
1724
1725 /*!
1726     \since 4.4
1727
1728     Tries to detect the encoding of the provided snippet of HTML in
1729     the given byte array, \a ba, by checking the BOM (Byte Order Mark)
1730     and the content-type meta header and returns a QTextCodec instance
1731     that is capable of decoding the html to unicode.  If the codec
1732     cannot be detected from the content provided, \a defaultCodec is
1733     returned.
1734
1735     \sa codecForUtfText()
1736 */
1737 QTextCodec *QTextCodec::codecForHtml(const QByteArray &ba, QTextCodec *defaultCodec)
1738 {
1739     // determine charset
1740     int pos;
1741     QTextCodec *c = 0;
1742
1743     c = QTextCodec::codecForUtfText(ba, c);
1744     if (!c) {
1745         QByteArray header = ba.left(512).toLower();
1746         if ((pos = header.indexOf("http-equiv=")) != -1) {
1747             if ((pos = header.lastIndexOf("meta ", pos)) != -1) {
1748                 pos = header.indexOf("charset=", pos) + int(strlen("charset="));
1749                 if (pos != -1) {
1750                     int pos2 = header.indexOf('\"', pos+1);
1751                     QByteArray cs = header.mid(pos, pos2-pos);
1752                     //            qDebug("found charset: %s", cs.data());
1753                     c = QTextCodec::codecForName(cs);
1754                 }
1755             }
1756         }
1757     }
1758     if (!c)
1759         c = defaultCodec;
1760
1761     return c;
1762 }
1763
1764 /*!
1765     \overload
1766
1767     Tries to detect the encoding of the provided snippet of HTML in
1768     the given byte array, \a ba, by checking the BOM (Byte Order Mark)
1769     and the content-type meta header and returns a QTextCodec instance
1770     that is capable of decoding the html to unicode. If the codec cannot
1771     be detected, this overload returns a Latin-1 QTextCodec.
1772 */
1773 QTextCodec *QTextCodec::codecForHtml(const QByteArray &ba)
1774 {
1775     return codecForHtml(ba, QTextCodec::codecForMib(/*Latin 1*/ 4));
1776 }
1777
1778 /*!
1779     \since 4.6
1780
1781     Tries to detect the encoding of the provided snippet \a ba by
1782     using the BOM (Byte Order Mark) and returns a QTextCodec instance
1783     that is capable of decoding the text to unicode. If the codec
1784     cannot be detected from the content provided, \a defaultCodec is
1785     returned.
1786
1787     \sa codecForHtml()
1788 */
1789 QTextCodec *QTextCodec::codecForUtfText(const QByteArray &ba, QTextCodec *defaultCodec)
1790 {
1791     const int arraySize = ba.size();
1792
1793     if (arraySize > 3) {
1794         if ((uchar)ba[0] == 0x00
1795             && (uchar)ba[1] == 0x00
1796             && (uchar)ba[2] == 0xFE
1797             && (uchar)ba[3] == 0xFF)
1798             return QTextCodec::codecForMib(1018); // utf-32 be
1799         else if ((uchar)ba[0] == 0xFF
1800                  && (uchar)ba[1] == 0xFE
1801                  && (uchar)ba[2] == 0x00
1802                  && (uchar)ba[3] == 0x00)
1803             return QTextCodec::codecForMib(1019); // utf-32 le
1804     }
1805
1806     if (arraySize < 2)
1807         return defaultCodec;
1808     if ((uchar)ba[0] == 0xfe && (uchar)ba[1] == 0xff)
1809         return QTextCodec::codecForMib(1013); // utf16 be
1810     else if ((uchar)ba[0] == 0xff && (uchar)ba[1] == 0xfe)
1811         return QTextCodec::codecForMib(1014); // utf16 le
1812
1813     if (arraySize < 3)
1814         return defaultCodec;
1815     if ((uchar)ba[0] == 0xef
1816         && (uchar)ba[1] == 0xbb
1817         && (uchar)ba[2] == 0xbf)
1818         return QTextCodec::codecForMib(106); // utf-8
1819
1820     return defaultCodec;
1821 }
1822
1823 /*!
1824     \overload
1825
1826     Tries to detect the encoding of the provided snippet \a ba by
1827     using the BOM (Byte Order Mark) and returns a QTextCodec instance
1828     that is capable of decoding the text to unicode. If the codec
1829     cannot be detected, this overload returns a Latin-1 QTextCodec.
1830
1831     \sa codecForHtml()
1832 */
1833 QTextCodec *QTextCodec::codecForUtfText(const QByteArray &ba)
1834 {
1835     return codecForUtfText(ba, QTextCodec::codecForMib(/*Latin 1*/ 4));
1836 }
1837
1838
1839 /*! \internal
1840     \since 4.3
1841     Determines whether the decoder encountered a failure while decoding the input. If
1842     an error was encountered, the produced result is undefined, and gets converted as according
1843     to the conversion flags.
1844  */
1845 bool QTextDecoder::hasFailure() const
1846 {
1847     return state.invalidChars != 0;
1848 }
1849
1850 /*!
1851     \fn QTextCodec *QTextCodec::codecForContent(const char *str, int size)
1852
1853     This functionality is no longer provided by Qt. This
1854     compatibility function always returns a null pointer.
1855 */
1856
1857 /*!
1858     \fn QTextCodec *QTextCodec::codecForName(const char *hint, int accuracy)
1859
1860     Use the codecForName(const QByteArray &) overload instead.
1861 */
1862
1863 /*!
1864     \fn QTextCodec *QTextCodec::codecForIndex(int i)
1865
1866     Use availableCodecs() or availableMibs() instead and iterate
1867     through the resulting list.
1868 */
1869
1870
1871 /*!
1872     \fn QByteArray QTextCodec::mimeName() const
1873
1874     Use name() instead.
1875 */
1876
1877 QT_END_NAMESPACE
1878
1879 #endif // QT_NO_TEXTCODEC