~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/corelib/codecs/qisciicodec.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the core module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qisciicodec_p.h"
 
30
#include "qlist.h"
 
31
 
 
32
#ifndef QT_NO_CODECS
 
33
 
 
34
/*!
 
35
    \class QIsciiCodec
 
36
    \brief The QIsciiCodec class provides conversion to and from the ISCII encoding.
 
37
 
 
38
    \internal
 
39
*/
 
40
 
 
41
 
 
42
struct Codecs {
 
43
    const char *name;
 
44
    ushort base;
 
45
};
 
46
 
 
47
static const Codecs codecs [] = {
 
48
    { "Iscii-Dev", 0x900 },
 
49
    { "Iscii-Bng", 0x980 },
 
50
    { "Iscii-Pnj", 0xa00 },
 
51
    { "Iscii-Gjr", 0xa80 },
 
52
    { "Iscii-Ori", 0xb00 },
 
53
    { "Iscii-Tml", 0xb80 },
 
54
    { "Iscii-Tlg", 0xc00 },
 
55
    { "Iscii-Knd", 0xc80 },
 
56
    { "Iscii-Mlm", 0xd00 }
 
57
};
 
58
 
 
59
QIsciiCodec::~QIsciiCodec()
 
60
{
 
61
}
 
62
 
 
63
QByteArray QIsciiCodec::name() const
 
64
{
 
65
  return codecs[idx].name;
 
66
}
 
67
 
 
68
int QIsciiCodec::mibEnum() const
 
69
{
 
70
    /* There is no MIBEnum for Iscii */
 
71
    return -3000-idx;
 
72
}
 
73
 
 
74
 
 
75
#define INV 0xff
 
76
 
 
77
/* iscii range from 0xa0 - 0xff */
 
78
static const uchar iscii_to_uni_table[0x60] = {
 
79
    0x00, 0x01, 0x02, 0x03,
 
80
    0x05, 0x06, 0x07, 0x08,
 
81
    0x09, 0x0a, 0x0b, 0x0e,
 
82
    0x0f, 0x20, 0x0d, 0x12,
 
83
 
 
84
    0x13, 0x14, 0x11, 0x15,
 
85
    0x16, 0x17, 0x18, 0x19,
 
86
    0x1a, 0x1b, 0x1c, 0x1d,
 
87
    0x1e, 0x1f, 0x20, 0x21,
 
88
 
 
89
    0x22, 0x23, 0x24, 0x25,
 
90
    0x26, 0x27, 0x28, 0x29,
 
91
    0x2a, 0x2b, 0x2c, 0x2d,
 
92
    0x2e, 0x2f, 0x5f, 0x30,
 
93
 
 
94
    0x31, 0x32, 0x33, 0x34,
 
95
    0x35, 0x36, 0x37, 0x38,
 
96
    0x39,  INV, 0x3e, 0x3f,
 
97
    0x40, 0x41, 0x42, 0x43,
 
98
 
 
99
    0x46, 0x47, 0x48, 0x45,
 
100
    0x4a, 0x4b, 0x4c, 0x49,
 
101
    0x4d, 0x3c, 0x64, 0x00,
 
102
    0x00, 0x00, 0x00, 0x00,
 
103
 
 
104
    0x00, 0x66, 0x67, 0x68,
 
105
    0x69, 0x6a, 0x6b, 0x6c,
 
106
    0x6d, 0x6e, 0x6f, 0x00,
 
107
    0x00, 0x00, 0x00, 0x00
 
108
};
 
109
 
 
110
static const uchar uni_to_iscii_table[0x80] = {
 
111
    0x00, 0xa1, 0xa2, 0xa3,
 
112
    0x00, 0xa4, 0xa5, 0xa6,
 
113
    0xa7, 0xa8, 0xa9, 0xaa,
 
114
    0x00, 0xae, 0xab, 0xac,
 
115
 
 
116
    0xad, 0xb2, 0xaf, 0xb0,
 
117
    0xb1, 0xb3, 0xb4, 0xb5,
 
118
    0xb6, 0xb7, 0xb8, 0xb9,
 
119
    0xba, 0xbb, 0xbc, 0xbd,
 
120
 
 
121
    0xbe, 0xbf, 0xc0, 0xc1,
 
122
    0xc2, 0xc3, 0xc4, 0xc5,
 
123
    0xc6, 0xc7, 0xc8, 0xc9,
 
124
    0xca, 0xcb, 0xcc, 0xcd,
 
125
 
 
126
    0xcf, 0xd0, 0xd1, 0xd2,
 
127
    0xd3, 0xd4, 0xd5, 0xd6,
 
128
    0xd7, 0xd8, 0x00, 0x00,
 
129
    0xe9, 0x00, 0xda, 0xdb,
 
130
 
 
131
    0xdc, 0xdd, 0xde, 0xdf,
 
132
    0x00, 0xe3, 0xe0, 0xe1,
 
133
    0xe2, 0xe7, 0xe4, 0xe5,
 
134
    0xe6, 0xe8, 0x00, 0x00,
 
135
 
 
136
    0x00, 0x00, 0x00, 0x00,
 
137
    0x00, 0x00, 0x00, 0x00,
 
138
    0x01, 0x02, 0x03, 0x04, // decomposable into the uc codes listed here + nukta
 
139
    0x05, 0x06, 0x07, 0xce,
 
140
 
 
141
    0x00, 0x00, 0x00, 0x00,
 
142
    0xea, 0x08, 0xf1, 0xf2,
 
143
    0xf3, 0xf4, 0xf5, 0xf6,
 
144
    0xf7, 0xf8, 0xf9, 0xfa,
 
145
 
 
146
    0x00, 0x00, 0x00, 0x00,
 
147
    0x00, 0x00, 0x00, 0x00,
 
148
    0x00, 0x00, 0x00, 0x00,
 
149
    0x00, 0x00, 0x00, 0x00
 
150
};
 
151
 
 
152
static const uchar uni_to_iscii_pairs[] = {
 
153
    0x00, 0x00,
 
154
    0x15, 0x3c, // 0x958
 
155
    0x16, 0x3c, // 0x959
 
156
    0x17, 0x3c, // 0x95a
 
157
    0x1c, 0x3c, // 0x95b
 
158
    0x21, 0x3c, // 0x95c
 
159
    0x22, 0x3c, // 0x95d
 
160
    0x2b, 0x3c, // 0x95e
 
161
    0x64, 0x64  // 0x965
 
162
};
 
163
 
 
164
 
 
165
QByteArray QIsciiCodec::convertFromUnicode(const QChar *uc, int len, ConverterState *state) const
 
166
{
 
167
    char replacement = '?';
 
168
    bool halant = false;
 
169
    if (state) {
 
170
        if (state->flags & ConvertInvalidToNull)
 
171
            replacement = 0;
 
172
        halant = state->state_data[0];
 
173
    }
 
174
    int invalid = 0;
 
175
 
 
176
    QByteArray result;
 
177
    result.resize(2*len); //worst case
 
178
 
 
179
    uchar *ch = (uchar *)result.data();
 
180
 
 
181
    int base = codecs[idx].base;
 
182
 
 
183
    for (int i =0; i < len; ++i) {
 
184
        int pos = uc[i].unicode() - base;
 
185
        if (pos > 0 && pos < 0x80) {
 
186
            uchar iscii = uni_to_iscii_table[pos];
 
187
            if (iscii > 0x80) {
 
188
                *ch++ = iscii;
 
189
            } else if (iscii) {
 
190
                const uchar *pair = uni_to_iscii_pairs + 2*iscii;
 
191
                *ch++ = *pair++;
 
192
                *ch++ = *pair++;
 
193
            } else {
 
194
                *ch++ = replacement;
 
195
                ++invalid;
 
196
            }
 
197
        } else {
 
198
            if (uc[i].unicode() == 0x200c) { // ZWNJ
 
199
                if (halant)
 
200
                    // Consonant Halant ZWNJ -> Consonant Halant Halant
 
201
                    *ch++ = 0xe8;
 
202
            } else if (uc[i].unicode() == 0x200d) { // ZWJ
 
203
                if (halant)
 
204
                    // Consonant Halant ZWJ -> Consonant Halant Nukta
 
205
                    *ch++ = 0xe9;
 
206
            } else {
 
207
                *ch++ = replacement;
 
208
                ++invalid;
 
209
            }
 
210
        }
 
211
        halant = (pos == 0x4d);
 
212
    }
 
213
    result.truncate(ch - (uchar *)result.data());
 
214
 
 
215
    if (state) {
 
216
        state->invalidChars += invalid;
 
217
        state->state_data[0] = halant;
 
218
    }
 
219
    return result;
 
220
}
 
221
 
 
222
QString QIsciiCodec::convertToUnicode(const char* chars, int len, ConverterState *state) const
 
223
{
 
224
    bool halant = false;
 
225
    if (state) {
 
226
        halant = state->state_data[0];
 
227
    }
 
228
 
 
229
    QString result;
 
230
    result.resize(len);
 
231
    QChar *uc = (QChar *)result.unicode();
 
232
 
 
233
    int base = codecs[idx].base;
 
234
 
 
235
    for (int i = 0; i < len; ++i) {
 
236
        ushort ch = (uchar) chars[i];
 
237
        if (ch < 0xa0)
 
238
            *uc++ = ch;
 
239
        else {
 
240
            ushort c = iscii_to_uni_table[ch - 0xa0];
 
241
            if (halant && (c == INV || c == 0xe9)) {
 
242
                // Consonant Halant INV -> Consonant Halant ZWJ
 
243
                // Consonant Halant Nukta -> Consonant Halant ZWJ
 
244
                *uc++ = QChar(0x200d);
 
245
            } else if (halant && c == 0xe8) {
 
246
                // Consonant Halant Halant -> Consonant Halant ZWNJ
 
247
                *uc++ = QChar(0x200c);
 
248
            } else {
 
249
                *uc++ = QChar(c+base);
 
250
            }
 
251
        }
 
252
        halant = ((uchar)chars[i] == 0xe8);
 
253
    }
 
254
    result.resize(uc - result.unicode());
 
255
 
 
256
    if (state) {
 
257
        state->state_data[0] = halant;
 
258
    }
 
259
    return result;
 
260
}
 
261
#endif // QT_NO_CODECS