| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtCore module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $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 |
| \inmodule QtCore |
| \reentrant |
| \internal |
| */ |
| |
| #include "qsjiscodec_p.h" |
| #include "qlist.h" |
| |
| QT_BEGIN_NAMESPACE |
| |
| 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 (const 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) { |
| result += QValidChar(ch); |
| } else if (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; |
| } |
| |
| QT_END_NAMESPACE |