Fix for UBSan build
[platform/upstream/doxygen.git] / qtools / qutfcodec.cpp
1 /****************************************************************************
2 ** $Id: qt/src/tools/qutfcodec.cpp   2.3.2   edited 2001-01-26 $
3 **
4 ** Implementation of QEucCodec class
5 **
6 ** Created : 981015
7 **
8 ** Copyright (C)1998-2000 Trolltech AS.  All rights reserved.
9 **
10 ** This file is part of the tools module of the Qt GUI Toolkit.
11 **
12 ** This file may be distributed under the terms of the Q Public License
13 ** as defined by Trolltech AS of Norway and appearing in the file
14 ** LICENSE.QPL included in the packaging of this file.
15 **
16 ** This file may be distributed and/or modified under the terms of the
17 ** GNU General Public License version 2 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.GPL included in the
19 ** packaging of this file.
20 **
21 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22 ** licenses may use this file in accordance with the Qt Commercial License
23 ** Agreement provided with the Software.
24 **
25 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27 **
28 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29 **   information about Qt Commercial License Agreements.
30 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
31 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
32 **
33 ** Contact info@trolltech.com if any conditions of this licensing are
34 ** not clear to you.
35 **
36 **********************************************************************/
37
38 #include "qutfcodec.h"
39
40 #ifndef QT_NO_TEXTCODEC
41
42 int QUtf8Codec::mibEnum() const
43 {
44     return 106;
45 }
46
47 QCString QUtf8Codec::fromUnicode(const QString& uc, int& len_in_out) const
48 {
49     int l = QMIN((int)uc.length(),len_in_out);
50     int rlen = l*3+1;
51     QCString rstr(rlen);
52     uchar* cursor = (uchar*)rstr.data();
53     for (int i=0; i<l; i++) {
54         QChar ch = uc[i];
55         if ( !ch.row() && ch.cell() < 0x80 ) {
56             *cursor++ = ch.cell();
57         } else {
58             uchar b = (ch.row() << 2) | (ch.cell() >> 6);
59             if ( ch.row() < 0x08 ) {
60                 *cursor++ = 0xc0 | b;
61             } else {
62                 *cursor++ = 0xe0 | (ch.row() >> 4);
63                 *cursor++ = 0x80 | (b&0x3f);
64             }
65             *cursor++ = 0x80 | (ch.cell()&0x3f);
66         }
67     }
68     len_in_out = cursor - (uchar*)rstr.data();
69     rstr.truncate(len_in_out);
70     return rstr;
71 }
72
73 const char* QUtf8Codec::name() const
74 {
75     return "UTF-8";
76 }
77
78 int QUtf8Codec::heuristicContentMatch(const char* chars, int len) const
79 {
80     int score = 0;
81     for (int i=0; i<len; i++) {
82         uchar ch = chars[i];
83         // No nulls allowed.
84         if ( !ch )
85             return -1;
86         if ( ch < 128 ) {
87             // Inconclusive
88             score++;
89         } else if ( (ch&0xe0) == 0xc0 ) {
90             if ( i < len-1 ) {
91                 uchar c2 = chars[++i];
92                 if ( (c2&0xc0) != 0x80 )
93                     return -1;
94                 score+=3;
95             }
96         } else if ( (ch&0xf0) == 0xe0 ) {
97             if ( i < len-1 ) {
98                 uchar c2 = chars[++i];
99                 if ( (c2&0xc0) != 0x80 ) {
100                     return -1;
101 #if 0
102                     if ( i < len-1 ) {
103                         uchar c3 = chars[++i];
104                         if ( (c3&0xc0) != 0x80 )
105                             return -1;
106                         score+=3;
107                     }
108 #endif
109                 }
110                 score+=2;
111             }
112         }
113     }
114     return score;
115 }
116
117
118
119
120 class QUtf8Decoder : public QTextDecoder {
121     ushort uc;
122     int need;
123 public:
124     QUtf8Decoder() : need(0)
125     {
126     }
127
128     QString toUnicode(const char* chars, int len)
129     {
130         QString result;
131         for (int i=0; i<len; i++) {
132             uchar ch = chars[i];
133             if (need) {
134                 if ( (ch&0xc0) == 0x80 ) {
135                     uc = (uc << 6) | (ch & 0x3f);
136                     need--;
137                     if ( !need ) {
138                         result += QChar(uc);
139                     }
140                 } else {
141                     // error
142                     result += QChar::replacement;
143                     need = 0;
144                 }
145             } else {
146                 if ( ch < 128 ) {
147                     result += QChar(ch);
148                 } else if ( (ch&0xe0) == 0xc0 ) {
149                     uc = ch &0x1f;
150                     need = 1;
151                 } else if ( (ch&0xf0) == 0xe0 ) {
152                     uc = ch &0x0f;
153                     need = 2;
154                 }
155             }
156         }
157         return result;
158     }
159 };
160
161 QTextDecoder* QUtf8Codec::makeDecoder() const
162 {
163     return new QUtf8Decoder;
164 }
165
166
167
168
169
170
171 int QUtf16Codec::mibEnum() const
172 {
173     return 1000;
174 }
175
176 const char* QUtf16Codec::name() const
177 {
178     return "ISO-10646-UCS-2";
179 }
180
181 int QUtf16Codec::heuristicContentMatch(const char* chars, int len) const
182 {
183     uchar* uchars = (uchar*)chars;
184     if ( len >= 2 && ((uchars[0] == 0xff && uchars[1] == 0xfe) ||
185                       (uchars[1] == 0xff && uchars[0] == 0xfe)) )
186         return len;
187     else
188         return 0;
189 }
190
191
192
193
194 class QUtf16Encoder : public QTextEncoder {
195     bool headerdone;
196 public:
197     QUtf16Encoder() : headerdone(FALSE)
198     {
199     }
200
201     QCString fromUnicode(const QString& uc, int& len_in_out)
202     {
203         if ( headerdone ) {
204             len_in_out = uc.length()*sizeof(QChar);
205             QCString d(len_in_out);
206             memcpy(d.data(),uc.unicode(),len_in_out);
207             return d;
208         } else {
209             headerdone = TRUE;
210             len_in_out = (1+uc.length())*sizeof(QChar);
211             QCString d(len_in_out);
212             memcpy(d.data(),&QChar::byteOrderMark,sizeof(QChar));
213             memcpy(d.data()+sizeof(QChar),uc.unicode(),uc.length()*sizeof(QChar));
214             return d;
215         }
216     }
217 };
218
219 class QUtf16Decoder : public QTextDecoder {
220     uchar buf;
221     bool half;
222     bool swap;
223     bool headerdone;
224
225 public:
226     QUtf16Decoder() : half(FALSE), swap(FALSE), headerdone(FALSE)
227     {
228     }
229
230     QString toUnicode(const char* chars, int len)
231     {
232         QString r;
233
234         while ( len-- ) {
235             if ( half ) {
236                 QChar ch;
237                 if ( swap ) {
238                     ch.row() = *chars++;
239                     ch.cell() = buf;
240                 } else {
241                     ch.row() = buf;
242                     ch.cell() = *chars++;
243                 }
244                 if ( !headerdone ) {
245                     if ( ch == QChar::byteOrderSwapped ) {
246                         swap = !swap;
247                     } else if ( ch == QChar::byteOrderMark ) {
248                         // Ignore ZWNBSP
249                     } else {
250                         r += ch;
251                     }
252                     headerdone = TRUE;
253                 } else
254                     r += ch;
255                 half = FALSE;
256             } else {
257                 buf = *chars++;
258                 half = TRUE;
259             }
260         }
261
262         return r;
263     }
264 };
265
266 QTextDecoder* QUtf16Codec::makeDecoder() const
267 {
268     return new QUtf16Decoder;
269 }
270
271 QTextEncoder* QUtf16Codec::makeEncoder() const
272 {
273     return new QUtf16Encoder;
274 }
275
276 #endif // QT_NO_TEXTCODEC