| /**************************************************************************** |
| ** |
| ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). |
| ** All rights reserved. |
| ** Contact: Nokia Corporation (qt-info@nokia.com) |
| ** |
| ** This file is part of the plugins of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** GNU Lesser General Public License Usage |
| ** This file may be used under the terms of the GNU Lesser General Public |
| ** License version 2.1 as published by the Free Software Foundation and |
| ** appearing in the file LICENSE.LGPL included in the packaging of this |
| ** file. Please review the following information to ensure the GNU Lesser |
| ** General Public License version 2.1 requirements will be met: |
| ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
| ** |
| ** In addition, as a special exception, Nokia gives you certain additional |
| ** rights. These rights are described in the Nokia Qt LGPL Exception |
| ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU General |
| ** Public License version 3.0 as published by the Free Software Foundation |
| ** and appearing in the file LICENSE.GPL included in the packaging of this |
| ** file. Please review the following information to ensure the GNU General |
| ** Public License version 3.0 requirements will be met: |
| ** http://www.gnu.org/copyleft/gpl.html. |
| ** |
| ** Other Usage |
| ** Alternatively, this file may be used in accordance with the terms and |
| ** conditions contained in a signed written agreement between you and Nokia. |
| ** |
| ** |
| ** |
| ** |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| // Most of the code here was originally written by Serika Kurusugawa |
| // a.k.a. Junji Takagi, and is included in Qt with the author's permission, |
| // and the grateful thanks of the Qt team. |
| |
| /*! \class QSjisCodec |
| \reentrant |
| \internal |
| */ |
| |
| #include "qsjiscodec.h" |
| #include "qlist.h" |
| |
| QT_BEGIN_NAMESPACE |
| |
| #ifndef QT_NO_TEXTCODEC |
| enum { |
| Esc = 0x1b |
| }; |
| |
| #define IsKana(c) (((c) >= 0xa1) && ((c) <= 0xdf)) |
| #define IsSjisChar1(c) ((((c) >= 0x81) && ((c) <= 0x9f)) || \ |
| (((c) >= 0xe0) && ((c) <= 0xfc))) |
| #define IsSjisChar2(c) (((c) >= 0x40) && ((c) != 0x7f) && ((c) <= 0xfc)) |
| #define IsUserDefinedChar1(c) (((c) >= 0xf0) && ((c) <= 0xfc)) |
| |
| #define QValidChar(u) ((u) ? QChar((ushort)(u)) : QChar(QChar::ReplacementCharacter)) |
| |
| /*! |
| Creates a Shift-JIS codec. Note that this is done automatically by |
| the QApplication, you do not need construct your own. |
| */ |
| QSjisCodec::QSjisCodec() : conv(QJpUnicodeConv::newConverter(QJpUnicodeConv::Default)) |
| { |
| } |
| |
| |
| /*! |
| Destroys the Shift-JIS codec. |
| */ |
| QSjisCodec::~QSjisCodec() |
| { |
| delete (QJpUnicodeConv*)conv; |
| conv = 0; |
| } |
| |
| |
| QByteArray QSjisCodec::convertFromUnicode(const QChar *uc, int len, ConverterState *state) const |
| { |
| char replacement = '?'; |
| if (state) { |
| if (state->flags & ConvertInvalidToNull) |
| replacement = 0; |
| } |
| int invalid = 0; |
| |
| int rlen = 2*len + 1; |
| QByteArray rstr; |
| rstr.resize(rlen); |
| uchar* cursor = (uchar*)rstr.data(); |
| for (int i = 0; i < len; i++) { |
| QChar ch = uc[i]; |
| uint j; |
| if (ch.row() == 0x00 && ch.cell() < 0x80) { |
| // ASCII |
| *cursor++ = ch.cell(); |
| } else if ((j = conv->unicodeToJisx0201(ch.row(), ch.cell())) != 0) { |
| // JIS X 0201 Latin or JIS X 0201 Kana |
| *cursor++ = j; |
| } else if ((j = conv->unicodeToSjis(ch.row(), ch.cell())) != 0) { |
| // JIS X 0208 |
| *cursor++ = (j >> 8); |
| *cursor++ = (j & 0xff); |
| } else if ((j = conv->unicodeToSjisibmvdc(ch.row(), ch.cell())) != 0) { |
| // JIS X 0208 IBM VDC |
| *cursor++ = (j >> 8); |
| *cursor++ = (j & 0xff); |
| } else if ((j = conv->unicodeToCp932(ch.row(), ch.cell())) != 0) { |
| // CP932 (for lead bytes 87, ee & ed) |
| *cursor++ = (j >> 8); |
| *cursor++ = (j & 0xff); |
| } else if ((j = conv->unicodeToJisx0212(ch.row(), ch.cell())) != 0) { |
| // JIS X 0212 (can't be encoded in ShiftJIS !) |
| *cursor++ = 0x81; // white square |
| *cursor++ = 0xa0; // white square |
| } else { |
| // Error |
| *cursor++ = replacement; |
| ++invalid; |
| } |
| } |
| rstr.resize(cursor - (const uchar*)rstr.constData()); |
| |
| if (state) { |
| state->invalidChars += invalid; |
| } |
| return rstr; |
| } |
| |
| QString QSjisCodec::convertToUnicode(const char* chars, int len, ConverterState *state) const |
| { |
| uchar buf[1] = {0}; |
| int nbuf = 0; |
| QChar replacement = QChar::ReplacementCharacter; |
| if (state) { |
| if (state->flags & ConvertInvalidToNull) |
| replacement = QChar::Null; |
| nbuf = state->remainingChars; |
| buf[0] = state->state_data[0]; |
| } |
| int invalid = 0; |
| uint u= 0; |
| QString result; |
| for (int i=0; i<len; i++) { |
| uchar ch = chars[i]; |
| switch (nbuf) { |
| case 0: |
| if (ch < 0x80 || IsKana(ch)) { |
| // JIS X 0201 Latin or JIS X 0201 Kana |
| u = conv->jisx0201ToUnicode(ch); |
| result += QValidChar(u); |
| } else if (IsSjisChar1(ch)) { |
| // JIS X 0208 |
| buf[0] = ch; |
| nbuf = 1; |
| } else { |
| // Invalid |
| result += replacement; |
| ++invalid; |
| } |
| break; |
| case 1: |
| // JIS X 0208 |
| if (IsSjisChar2(ch)) { |
| if ((u = conv->sjisibmvdcToUnicode(buf[0], ch))) { |
| result += QValidChar(u); |
| } else if ((u = conv->cp932ToUnicode(buf[0], ch))) { |
| result += QValidChar(u); |
| } |
| else if (IsUserDefinedChar1(buf[0])) { |
| result += QChar::ReplacementCharacter; |
| } else { |
| u = conv->sjisToUnicode(buf[0], ch); |
| result += QValidChar(u); |
| } |
| } else { |
| // Invalid |
| result += replacement; |
| ++invalid; |
| } |
| nbuf = 0; |
| break; |
| } |
| } |
| |
| if (state) { |
| state->remainingChars = nbuf; |
| state->state_data[0] = buf[0]; |
| state->invalidChars += invalid; |
| } |
| return result; |
| } |
| |
| |
| int QSjisCodec::_mibEnum() |
| { |
| return 17; |
| } |
| |
| QByteArray QSjisCodec::_name() |
| { |
| return "Shift_JIS"; |
| } |
| |
| /*! |
| Returns the codec's mime name. |
| */ |
| QList<QByteArray> QSjisCodec::_aliases() |
| { |
| QList<QByteArray> list; |
| list << "SJIS" // Qt 3 compat |
| << "MS_Kanji"; |
| return list; |
| } |
| #endif // QT_NO_TEXTCODEC |
| |
| QT_END_NAMESPACE |