From 102491a7435835ff349573712d7bba902eaf0836 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Sun, 3 May 2020 14:09:42 -0300 Subject: [PATCH] Refactoring/reimplementation of MXP support (#3625) Refactoring/reimplementation of MXP protocol Extracts MXP support from TBuffer Separates input parsing from protocol processing: input is parsed into MxpTag objects by the MxpNodeBuilder and are passed to be handled by the MxpTagProcessor Class hierarchy of MxpTagHandler for implementing support for each tag: allows for a clear separation of the implementation of each tag and makes it easier for adding support for new tags Defines a clear interface (MxpClient) separating the MXP implementation from other parts of the code Solves some limitations of previous implementation such as supporting element definitions not only for tags, interpolating named and positional attributes and interpolating &text; placeholder by tag content Includes support for COLOR tag Handles FONT, U, I, B, VAR and !ENTITY tags, but so far no defined behavior (can be implemented in MxpMudlet) Attributes that hold MXP state are now in the Host class to avoid needless copies when TBuffer is copied around Introduces QtTests for some of the classes Other refactorings intended to simplify TBuffer class, extracting responbilities that aren't directly related to the buffer mgmt Extracted TEncodingTable from TBuffer, this class is responsible for mapping encoding names to tables. It also removes some bloat from TBuffer. TLinkStore to manage links and associated hints to be displayed. TEntityResolver to map character entities, such as > to their associated string values; supports interpolating strings replacing the entity placeholders by their values --- CMakeLists.txt | 1 + src/CMakeLists.txt | 52 ++ src/Host.cpp | 3 + src/Host.h | 6 + src/MxpTag.cpp | 126 +++ src/MxpTag.h | 157 ++++ src/TBuffer.cpp | 1239 +------------------------- src/TBuffer.h | 89 +- src/TConsole.cpp | 7 +- src/TConsole.h | 1 + src/TEncodingTable.cpp | 698 +++++++++++++++ src/TEncodingTable.h | 54 ++ src/TEntityHandler.cpp | 64 ++ src/TEntityHandler.h | 47 + src/TEntityResolver.cpp | 169 ++++ src/TEntityResolver.h | 55 ++ src/TLinkStore.cpp | 56 ++ src/TLinkStore.h | 56 ++ src/TMxpBRTagHandler.cpp | 24 + src/TMxpBRTagHandler.h | 32 + src/TMxpClient.h | 71 ++ src/TMxpColorTagHandler.cpp | 39 + src/TMxpColorTagHandler.h | 36 + src/TMxpContext.h | 46 + src/TMxpCustomElementTagHandler.cpp | 161 ++++ src/TMxpCustomElementTagHandler.h | 47 + src/TMxpElementDefinitionHandler.cpp | 69 ++ src/TMxpElementDefinitionHandler.h | 35 + src/TMxpElementRegistry.cpp | 37 + src/TMxpElementRegistry.h | 59 ++ src/TMxpEntityTagHandler.cpp | 52 ++ src/TMxpEntityTagHandler.h | 39 + src/TMxpEvent.h | 35 + src/TMxpFontTagHandler.cpp | 41 + src/TMxpFontTagHandler.h | 35 + src/TMxpFormattingTagsHandler.cpp | 49 + src/TMxpFormattingTagsHandler.h | 37 + src/TMxpLinkTagHandler.cpp | 75 ++ src/TMxpLinkTagHandler.h | 41 + src/TMxpMudlet.cpp | 98 ++ src/TMxpMudlet.h | 101 +++ src/TMxpNodeBuilder.cpp | 210 +++++ src/TMxpNodeBuilder.h | 109 +++ src/TMxpProcessor.cpp | 161 ++++ src/TMxpProcessor.h | 71 ++ src/TMxpSendTagHandler.cpp | 131 +++ src/TMxpSendTagHandler.h | 52 ++ src/TMxpSupportTagHandler.cpp | 95 ++ src/TMxpSupportTagHandler.h | 35 + src/TMxpTagHandler.cpp | 30 + src/TMxpTagHandler.h | 64 ++ src/TMxpTagHandlerResult.h | 25 + src/TMxpTagParser.cpp | 175 ++++ src/TMxpTagParser.h | 50 ++ src/TMxpTagProcessor.cpp | 122 +++ src/TMxpTagProcessor.h | 67 ++ src/TMxpVarTagHandler.cpp | 53 ++ src/TMxpVarTagHandler.h | 41 + src/TMxpVersionTagHandler.cpp | 32 + src/TMxpVersionTagHandler.h | 33 + src/TStringUtils.cpp | 85 ++ src/TStringUtils.h | 61 ++ src/TTextEdit.cpp | 8 +- src/ctelnet.cpp | 2 +- src/mudlet.pro | 58 +- test/CMakeLists.txt | 53 ++ test/TEntityHandlerTest.cpp | 85 ++ test/TEntityResolverTest.cpp | 128 +++ test/TLinkStoreTest.cpp | 81 ++ test/TMxpSendTagHandlerTest.cpp | 112 +++ test/TMxpStubClient.h | 129 +++ test/TMxpTagParserTest.cpp | 287 ++++++ 72 files changed, 5491 insertions(+), 1293 deletions(-) create mode 100644 src/MxpTag.cpp create mode 100644 src/MxpTag.h create mode 100644 src/TEncodingTable.cpp create mode 100644 src/TEncodingTable.h create mode 100644 src/TEntityHandler.cpp create mode 100644 src/TEntityHandler.h create mode 100644 src/TEntityResolver.cpp create mode 100644 src/TEntityResolver.h create mode 100644 src/TLinkStore.cpp create mode 100644 src/TLinkStore.h create mode 100644 src/TMxpBRTagHandler.cpp create mode 100644 src/TMxpBRTagHandler.h create mode 100644 src/TMxpClient.h create mode 100644 src/TMxpColorTagHandler.cpp create mode 100644 src/TMxpColorTagHandler.h create mode 100644 src/TMxpContext.h create mode 100644 src/TMxpCustomElementTagHandler.cpp create mode 100644 src/TMxpCustomElementTagHandler.h create mode 100644 src/TMxpElementDefinitionHandler.cpp create mode 100644 src/TMxpElementDefinitionHandler.h create mode 100644 src/TMxpElementRegistry.cpp create mode 100644 src/TMxpElementRegistry.h create mode 100644 src/TMxpEntityTagHandler.cpp create mode 100644 src/TMxpEntityTagHandler.h create mode 100644 src/TMxpEvent.h create mode 100644 src/TMxpFontTagHandler.cpp create mode 100644 src/TMxpFontTagHandler.h create mode 100644 src/TMxpFormattingTagsHandler.cpp create mode 100644 src/TMxpFormattingTagsHandler.h create mode 100644 src/TMxpLinkTagHandler.cpp create mode 100644 src/TMxpLinkTagHandler.h create mode 100644 src/TMxpMudlet.cpp create mode 100644 src/TMxpMudlet.h create mode 100644 src/TMxpNodeBuilder.cpp create mode 100644 src/TMxpNodeBuilder.h create mode 100644 src/TMxpProcessor.cpp create mode 100644 src/TMxpProcessor.h create mode 100644 src/TMxpSendTagHandler.cpp create mode 100644 src/TMxpSendTagHandler.h create mode 100644 src/TMxpSupportTagHandler.cpp create mode 100644 src/TMxpSupportTagHandler.h create mode 100644 src/TMxpTagHandler.cpp create mode 100644 src/TMxpTagHandler.h create mode 100644 src/TMxpTagHandlerResult.h create mode 100644 src/TMxpTagParser.cpp create mode 100644 src/TMxpTagParser.h create mode 100644 src/TMxpTagProcessor.cpp create mode 100644 src/TMxpTagProcessor.h create mode 100644 src/TMxpVarTagHandler.cpp create mode 100644 src/TMxpVarTagHandler.h create mode 100644 src/TMxpVersionTagHandler.cpp create mode 100644 src/TMxpVersionTagHandler.h create mode 100644 src/TStringUtils.cpp create mode 100644 src/TStringUtils.h create mode 100644 test/CMakeLists.txt create mode 100644 test/TEntityHandlerTest.cpp create mode 100644 test/TEntityResolverTest.cpp create mode 100644 test/TLinkStoreTest.cpp create mode 100644 test/TMxpSendTagHandlerTest.cpp create mode 100644 test/TMxpStubClient.h create mode 100644 test/TMxpTagParserTest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a52a5b4933..3a22b6ef1df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,6 +164,7 @@ add_subdirectory(3rdparty/edbee-lib/edbee-lib) add_subdirectory(3rdparty/communi) add_subdirectory(translations/translated) add_subdirectory(src) +add_subdirectory(test) if(USE_UPDATER) add_subdirectory(3rdparty/dblsqd) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 20b7e326596..db7f8794ff6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -81,20 +81,45 @@ set(mudlet_SRCS TDebug.cpp TDockWidget.cpp TEasyButtonBar.cpp + TEncodingTable.cpp + TEntityHandler.cpp + TEntityResolver.cpp TFlipButton.cpp TForkedProcess.cpp TimerUnit.cpp TKey.cpp TLabel.cpp + TLinkStore.cpp TLuaInterpreter.cpp TMap.cpp TMedia.cpp + TMxpElementDefinitionHandler.cpp + TMxpElementRegistry.cpp + TMxpFormattingTagsHandler.cpp + TMxpBRTagHandler.cpp + TMxpColorTagHandler.cpp + TMxpCustomElementTagHandler.cpp + TMxpEntityTagHandler.cpp + TMxpFontTagHandler.cpp + TMxpLinkTagHandler.cpp + TMxpNodeBuilder.cpp + TMxpMudlet.cpp + TMxpProcessor.cpp + TMxpSendTagHandler.cpp + TMxpSupportTagHandler.cpp + MxpTag.cpp + TMxpTagHandler.cpp + TMxpTagParser.cpp + TMxpTagProcessor.cpp + TMxpVarTagHandler.cpp + TMxpVersionTagHandler.cpp TriggerUnit.cpp TRoom.cpp TRoomDB.cpp TScript.cpp TSplitter.cpp TSplitterHandle.cpp + TStringUtils.cpp TTabBar.cpp TTextCodec.cpp TTextEdit.cpp @@ -183,6 +208,9 @@ set(mudlet_HDRS TDebug.h TDockWidget.h TEasyButtonBar.h + TEncodingTable.h + TEntityHandler.h + TEntityResolver.h testdbg.h TEvent.h TForkedProcess.h @@ -190,10 +218,33 @@ set(mudlet_HDRS TimerUnit.h TKey.h TLabel.h + TLinkStore.h TLuaInterpreter.h TMap.h TMatchState.h TMedia.h + TMxpBRTagHandler.h + TMxpClient.h + TMxpColorTagHandler.h + TMxpCustomElementTagHandler.h + TMxpEntityTagHandler.h + TMxpFontTagHandler.h + TMxpLinkTagHandler.h + TMxpElementDefinitionHandler.h + TMxpElementRegistry.h + TMxpContext.h + TMxpFormattingTagsHandler.h + TMxpMudlet.h + TMxpNodeBuilder.h + TMxpProcessor.h + TMxpSendTagHandler.h + MxpTag.h + TMxpTagHandler.h + TMxpTagParser.h + TMxpTagProcessor.h + TMxpSupportTagHandler.cpp + TMxpVarTagHandler.h + TMxpVersionTagHandler.h Tree.h TriggerUnit.h TRoom.h @@ -201,6 +252,7 @@ set(mudlet_HDRS TScript.h TSplitter.h TSplitterHandle.h + TStringUtils.h TTabBar.h TTextCodec.h TTextEdit.h diff --git a/src/Host.cpp b/src/Host.cpp index b8f61369574..37d9898d738 100644 --- a/src/Host.cpp +++ b/src/Host.cpp @@ -37,6 +37,7 @@ #include "dlgMapper.h" #include "mudlet.h" + #include "pre_guard.h" #include #include @@ -205,6 +206,8 @@ Host::Host(int port, const QString& hostname, const QString& login, const QStrin , mEnableMSP(true) , mEnableMSDP(false) , mServerMXPenabled(true) +, mMxpClient(this) +, mMxpProcessor(&mMxpClient) , mMediaLocationGMCP(QString()) , mMediaLocationMSP(QString()) , mFORCE_GA_OFF(false) diff --git a/src/Host.h b/src/Host.h index d1e986455b5..d92b6f600d9 100644 --- a/src/Host.h +++ b/src/Host.h @@ -44,6 +44,9 @@ #include #include "post_guard.h" +#include "TMxpMudlet.h" +#include "TMxpProcessor.h" + class QDialog; class QDockWidget; class QPushButton; @@ -356,6 +359,9 @@ class Host : public QObject bool mEnableMSP; bool mEnableMSDP; bool mServerMXPenabled; + + TMxpMudlet mMxpClient; + TMxpProcessor mMxpProcessor; QString mMediaLocationGMCP; QString mMediaLocationMSP; QTextStream mErrorLogStream; diff --git a/src/MxpTag.cpp b/src/MxpTag.cpp new file mode 100644 index 00000000000..94bb0f7bad4 --- /dev/null +++ b/src/MxpTag.cpp @@ -0,0 +1,126 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "MxpTag.h" +#include "TMxpTagParser.h" + +const MxpTagAttribute& MxpStartTag::getAttribute(int attrIndex) const +{ + return getAttribute(mAttrsNames[attrIndex]); +} + +const MxpTagAttribute& MxpStartTag::getAttribute(const QString& attrName) const +{ + const auto ptr = mAttrsMap.find(attrName.toUpper()); + return *ptr; +} + +const QString& MxpStartTag::getAttributeValue(int attrIndex) const +{ + return getAttribute(attrIndex).getValue(); +} + +const QString& MxpStartTag::getAttributeValue(const QString& attrName) const +{ + return getAttribute(attrName).getValue(); +} + +bool MxpStartTag::hasAttribute(const QString& attrName) const +{ + return mAttrsMap.contains(attrName.toUpper()); +} + +bool MxpStartTag::isAttributeAt(const char* attrName, int attrIndex) +{ + return mAttrsNames[attrIndex].compare(attrName, Qt::CaseInsensitive) == 0; +} + +bool MxpTag::isNamed(const QString& tagName) const +{ + return name.compare(tagName, Qt::CaseInsensitive) == 0; +} + +QString MxpEndTag::toString() const +{ + QString result; + result.append(""); + return result; +} + +QString MxpStartTag::toString() const +{ + QString result; + result.append('<'); + result.append(name); + for (const auto& attrName : mAttrsNames) { + result.append(' '); + if (attrName.contains(" ") || attrName.contains("<")) { + result.append('"'); + result.append(attrName); + result.append('"'); + } else { + result.append(attrName); + } + + const auto& attr = getAttribute(attrName); + if (attr.hasValue()) { + result.append('='); + + const auto& val = attr.getValue(); + result.append('"'); + result.append(val); + result.append('"'); + } + } + + if (mIsEmpty) { + result.append(" /"); + } + + result.append('>'); + + return result; +} + +MxpStartTag MxpStartTag::transform(const MxpTagAttribute::Transformation& transformation) const +{ + QList newAttrs; + for (const auto& attr : mAttrsNames) { + newAttrs.append(transformation(mAttrsMap[attr.toUpper()])); + } + + return MxpStartTag(name, newAttrs, mIsEmpty); +} + +const QString& MxpStartTag::getAttributeByNameOrIndex(const QString& attrName, int attrIndex, const QString& defaultValue) const +{ + if (hasAttribute(attrName)) + return getAttributeValue(attrName); + if (getAttributesCount() > attrIndex && !getAttribute(attrIndex).hasValue()) + return getAttribute(attrIndex).getName(); + + return defaultValue; +} + +const QString& MxpStartTag::getAttrName(int attrIndex) const +{ + return mAttrsNames[attrIndex]; +} diff --git a/src/MxpTag.h b/src/MxpTag.h new file mode 100644 index 00000000000..668f99821b1 --- /dev/null +++ b/src/MxpTag.h @@ -0,0 +1,157 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_MXPTAG_H +#define MUDLET_MXPTAG_H + +#include +#include +#include +#include +#include + +class MxpTagAttribute : public QPair +{ +public: + typedef std::function Transformation; + + MxpTagAttribute(const QString& name, const QString& value) : QPair(name, value) {} + + explicit MxpTagAttribute(const QString& name) : MxpTagAttribute(name, QString::fromLatin1("")) {} + + MxpTagAttribute() : QPair() {} + + virtual const QString& getName() const { return first; } + + inline const QString& getValue() const { return second; } + + inline bool hasValue() const { return !second.isEmpty(); } + + inline bool isNamed(const QString& name) const { return name.compare(first, Qt::CaseInsensitive) == 0; } +}; + +class MxpStartTag; +class MxpEndTag; +class MxpTextNode; + +class MxpNode +{ +public: + enum Type { MXP_NODE_TYPE_TEXT, MXP_NODE_TYPE_START_TAG, MXP_NODE_TYPE_END_TAG }; + + explicit MxpNode(MxpNode::Type type) : mType(type) {} + + MxpNode::Type getType() const { return mType; } + + MxpStartTag* asStartTag() const { return mType == MXP_NODE_TYPE_START_TAG ? (MxpStartTag*)this : nullptr; } + + MxpEndTag* asEndTag() const { return mType == MXP_NODE_TYPE_END_TAG ? (MxpEndTag*)this : nullptr; } + + MxpTextNode* asText() const { return mType == MXP_NODE_TYPE_TEXT ? (MxpTextNode*)this : nullptr; } + + virtual QString toString() const = 0; + + bool isTag() { return mType != MXP_NODE_TYPE_TEXT; } + + bool isEndTag() { return mType == MXP_NODE_TYPE_END_TAG; } + + bool isStartTag() { return mType == MXP_NODE_TYPE_START_TAG; } + +protected: + MxpNode::Type mType; +}; + +class MxpTextNode : public MxpNode +{ + QString mContent; + +public: + explicit MxpTextNode(const QString& content) : MxpNode(MXP_NODE_TYPE_TEXT), mContent(QString(content)) {} + + inline const QString& getContent() const { return mContent; } + + virtual QString toString() const { return mContent; } +}; + +class MxpTag : public MxpNode +{ + friend class TMxpTagParser; + +protected: + QString name; + + explicit MxpTag(MxpNode::Type type, const QString& name) : MxpNode(type), name(name) {} + +public: + inline const QString& getName() const { return name; } + + inline bool isStartTag() const { return mType == MXP_NODE_TYPE_START_TAG; } + + inline bool isEndTag() const { return mType == MXP_NODE_TYPE_END_TAG; } + + bool isNamed(const QString& tagName) const; +}; + +class MxpEndTag : public MxpTag +{ +public: + explicit MxpEndTag(const QString& name) : MxpTag(MXP_NODE_TYPE_END_TAG, name) {} + QString toString() const override; +}; + +class MxpStartTag : public MxpTag +{ + QMap mAttrsMap; + QStringList mAttrsNames; + bool mIsEmpty; + +public: + explicit MxpStartTag(const QString& name) : MxpStartTag(name, QList(), false) {} + + MxpStartTag(const QString& name, const QList& attributes, bool isEmpty) : MxpTag(MXP_NODE_TYPE_START_TAG, QString(name)), mIsEmpty(isEmpty) + { + for (const auto& attr : attributes) { + mAttrsNames.append(attr.getName()); + mAttrsMap[attr.first.toUpper()] = attr; + } + } + + MxpStartTag transform(const MxpTagAttribute::Transformation& transformation) const; + + inline const QStringList& getAttributesNames() const { return mAttrsNames; } + + inline int getAttributesCount() const { return mAttrsNames.size(); } + + bool hasAttribute(const QString& attrName) const; + + const MxpTagAttribute& getAttribute(int attrIndex) const; + + const MxpTagAttribute& getAttribute(const QString& attrName) const; + + const QString& getAttributeValue(int attrIndex) const; + const QString& getAttributeValue(const QString& attrName) const; + const QString& getAttributeByNameOrIndex(const QString& attrName, int attrIndex, const QString& defaultValue = QString()) const; + bool isAttributeAt(const char* attrName, int attrIndex); + inline bool isEmpty() const { return mIsEmpty; } + + QString toString() const override; + const QString& getAttrName(int attrIndex) const; +}; + +#endif //MUDLET_MXPTAG_H diff --git a/src/TBuffer.cpp b/src/TBuffer.cpp index d94a1f95f4b..0da189e885c 100644 --- a/src/TBuffer.cpp +++ b/src/TBuffer.cpp @@ -24,6 +24,7 @@ #include "mudlet.h" #include "TConsole.h" +#include "TStringUtils.h" #include "pre_guard.h" #include @@ -50,631 +51,6 @@ //#define DEBUG_MXP_PROCESSING -// These tables have been regenerated from examination of the Qt source code -// particularly from: -// https://gitorious.org/qt/qt?p=qt:qt.git;a=blob;f=src/corelib/codecs/qsimplecodec.cpp;h=cb52ce35f369f7fbe5b04ff2c2cf1600bd794f4e;hb=HEAD -// It represents the Unicode codepoints that are to be used to represent -// extended ASCII characters with the MS Bit set. The name is one that will -// be recognized as a valid encoding name to supply to: -// QTextCodec::codecForName(...) -// "ISO 885901" is not included here as it is inherent in Qt and has a straight -// one for one mapping of characters in the range 128 to 255 to the -// corresponding Unicode codepoint. -// Note that the codepoint 0xFFFD is the Unicode replacement character and -// is reserved to show, amongst other things, where a UTF-8 sequence of bytes -// is not a known character or, in these tables, the fact that no character was -// defined at that Extended ASCII character code. - -// a map of computer-friendly encoding names as keys -// values are a pair of human-friendly name + encoding data - -// clang-format off -// Do not let code reformatting tool mess this around! -// PLACEMARKER: Extended ASCII decoder Unicode codepoint lookup tables -const QMap> TBuffer::csmEncodingTable = { - {"ISO 8859-2", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0x0104), QChar(0x02D8), QChar(0x0141), QChar(0x00A4), QChar(0x013D), QChar(0x015A), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x0160), QChar(0x015E), QChar(0x0164), QChar(0x0179), QChar(0x00AD), QChar(0x017D), QChar(0x017B), // A8-AF - QChar(0x00B0), QChar(0x0105), QChar(0x02DB), QChar(0x0142), QChar(0x00B4), QChar(0x013E), QChar(0x015B), QChar(0x02C7), // B0-B7 - QChar(0x00B8), QChar(0x0161), QChar(0x015F), QChar(0x0165), QChar(0x017A), QChar(0x02DD), QChar(0x017E), QChar(0x017C), // B8-BF - QChar(0x0154), QChar(0x00C1), QChar(0x00C2), QChar(0x0102), QChar(0x00C4), QChar(0x0139), QChar(0x0106), QChar(0x00C7), // C0-C7 - QChar(0x010C), QChar(0x00C9), QChar(0x0118), QChar(0x00CB), QChar(0x011A), QChar(0x00CD), QChar(0x00CE), QChar(0x010E), // C8-CF - QChar(0x0110), QChar(0x0143), QChar(0x0147), QChar(0x00D3), QChar(0x00D4), QChar(0x0150), QChar(0x00D6), QChar(0x00D7), // D0-D7 - QChar(0x0158), QChar(0x016E), QChar(0x00DA), QChar(0x0170), QChar(0x00DC), QChar(0x00DD), QChar(0x0162), QChar(0x00DF), // D8-DF - QChar(0x0155), QChar(0x00E1), QChar(0x00E2), QChar(0x0103), QChar(0x00E4), QChar(0x013A), QChar(0x0107), QChar(0x00E7), // E0-E7 - QChar(0x010D), QChar(0x00E9), QChar(0x0119), QChar(0x00EB), QChar(0x011B), QChar(0x00ED), QChar(0x00EE), QChar(0x010F), // E8-EF - QChar(0x0111), QChar(0x0144), QChar(0x0148), QChar(0x00F3), QChar(0x00F4), QChar(0x0151), QChar(0x00F6), QChar(0x00F7), // F0=F7 - QChar(0x0159), QChar(0x016F), QChar(0x00FA), QChar(0x0171), QChar(0x00FC), QChar(0x00FD), QChar(0x0163), QChar(0x02D9)}}, // F8-FF - {"ISO 8859-3", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0x0126), QChar(0x02D8), QChar(0x00A3), QChar(0x00A4), QChar(0xFFFD), QChar(0x0124), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x0130), QChar(0x015E), QChar(0x011E), QChar(0x0134), QChar(0x00AD), QChar(0xFFFD), QChar(0x017B), // A8-AF - QChar(0x00B0), QChar(0x0127), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x0125), QChar(0x00B7), // B0-B7 - QChar(0x00B8), QChar(0x0131), QChar(0x015F), QChar(0x011F), QChar(0x0135), QChar(0x00BD), QChar(0xFFFD), QChar(0x017C), // B8-BF - QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0xFFFD), QChar(0x00C4), QChar(0x010A), QChar(0x0108), QChar(0x00C7), // C0-C7 - QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF - QChar(0xFFFD), QChar(0x00D1), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x0120), QChar(0x00D6), QChar(0x00D7), // D0-D7 - QChar(0x011C), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x016C), QChar(0x015C), QChar(0x00DF), // D8-DF - QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0xFFFD), QChar(0x00E4), QChar(0x010B), QChar(0x0109), QChar(0x00E7), // E0-E7 - QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF - QChar(0xFFFD), QChar(0x00F1), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x0121), QChar(0x00F6), QChar(0x00F7), // F0=F7 - QChar(0x011D), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x016D), QChar(0x015D), QChar(0x02D9)}},// F8-FF - {"ISO 8859-4", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0x0104), QChar(0x0138), QChar(0x0156), QChar(0x00A4), QChar(0x0128), QChar(0x013B), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x0160), QChar(0x0112), QChar(0x0122), QChar(0x0166), QChar(0x00AD), QChar(0x017D), QChar(0x00AF), // A8-AF - QChar(0x00B0), QChar(0x0105), QChar(0x02DB), QChar(0x0157), QChar(0x00B4), QChar(0x0129), QChar(0x013C), QChar(0x02C7), // B0-B7 - QChar(0x00B8), QChar(0x0161), QChar(0x0113), QChar(0x0123), QChar(0x0167), QChar(0x014A), QChar(0x017E), QChar(0x014B), // B8-BF - QChar(0x0100), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x012E), // C0-C7 - QChar(0x010C), QChar(0x00C9), QChar(0x0118), QChar(0x00CB), QChar(0x0116), QChar(0x00CD), QChar(0x00CE), QChar(0x012A), // C8-CF - QChar(0x0110), QChar(0x0145), QChar(0x014C), QChar(0x0136), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 - QChar(0x00D8), QChar(0x0172), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x0168), QChar(0x016A), QChar(0x00DF), // D8-DF - QChar(0x0101), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x012F), // E0-E7 - QChar(0x010D), QChar(0x00E9), QChar(0x0119), QChar(0x00EB), QChar(0x0117), QChar(0x00ED), QChar(0x00EE), QChar(0x012B), // E8-EF - QChar(0x0111), QChar(0x0146), QChar(0x014D), QChar(0x0137), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 - QChar(0x00F8), QChar(0x0173), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x0169), QChar(0x016B), QChar(0x02D9)}},// F8-FF - {"ISO 8859-5", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0x0401), QChar(0x0402), QChar(0x0403), QChar(0x0404), QChar(0x0405), QChar(0x0406), QChar(0x0407), // A0-A7 - QChar(0x0408), QChar(0x0409), QChar(0x040A), QChar(0x040B), QChar(0x040C), QChar(0x00AD), QChar(0x040E), QChar(0x040F), // A8-AF - QChar(0x0410), QChar(0x0411), QChar(0x0412), QChar(0x0413), QChar(0x0414), QChar(0x0415), QChar(0x0416), QChar(0x0417), // B0-B7 - QChar(0x0418), QChar(0x0419), QChar(0x041A), QChar(0x041B), QChar(0x041C), QChar(0x041D), QChar(0x041E), QChar(0x041F), // B8-BF - QChar(0x0420), QChar(0x0421), QChar(0x0422), QChar(0x0423), QChar(0x0424), QChar(0x0425), QChar(0x0426), QChar(0x0427), // C0-C7 - QChar(0x0428), QChar(0x0429), QChar(0x042A), QChar(0x042B), QChar(0x042C), QChar(0x042D), QChar(0x042E), QChar(0x042F), // C8-CF - QChar(0x0430), QChar(0x0431), QChar(0x0432), QChar(0x0433), QChar(0x0434), QChar(0x0435), QChar(0x0436), QChar(0x0437), // D0-D7 - QChar(0x0438), QChar(0x0439), QChar(0x043A), QChar(0x043B), QChar(0x043C), QChar(0x043D), QChar(0x043E), QChar(0x043F), // D8-DF - QChar(0x0440), QChar(0x0441), QChar(0x0442), QChar(0x0443), QChar(0x0444), QChar(0x0445), QChar(0x0446), QChar(0x0447), // E0-E7 - QChar(0x0448), QChar(0x0449), QChar(0x044A), QChar(0x044B), QChar(0x044C), QChar(0x044D), QChar(0x044E), QChar(0x044F), // E8-EF - QChar(0x2116), QChar(0x0451), QChar(0x0452), QChar(0x0453), QChar(0x0454), QChar(0x0455), QChar(0x0456), QChar(0x0457), // F0=F7 - QChar(0x0458), QChar(0x0459), QChar(0x045A), QChar(0x045B), QChar(0x045C), QChar(0x00A7), QChar(0x045E), QChar(0x045F)}},// F8-FF - {"ISO 8859-6", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x00A4), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // A0-A7 - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x060C), QChar(0x00AD), QChar(0xFFFD), QChar(0xFFFD), // A8-AF - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // B0-B7 - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x061B), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x061F), // B8-BF - QChar(0xFFFD), QChar(0x0621), QChar(0x0622), QChar(0x0623), QChar(0x0624), QChar(0x0625), QChar(0x0626), QChar(0x0627), // C0-C7 - QChar(0x0628), QChar(0x0629), QChar(0x062A), QChar(0x062B), QChar(0x062C), QChar(0x062D), QChar(0x062E), QChar(0x062F), // C8-CF - QChar(0x0630), QChar(0x0631), QChar(0x0632), QChar(0x0633), QChar(0x0634), QChar(0x0635), QChar(0x0636), QChar(0x0637), // D0-D7 - QChar(0x0638), QChar(0x0639), QChar(0x063A), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // D8-DF - QChar(0x0640), QChar(0x0641), QChar(0x0642), QChar(0x0643), QChar(0x0644), QChar(0x0645), QChar(0x0646), QChar(0x0647), // E0-E7 - QChar(0x0648), QChar(0x0649), QChar(0x064A), QChar(0x064B), QChar(0x064C), QChar(0x064D), QChar(0x064E), QChar(0x064F), // E8-EF - QChar(0x0650), QChar(0x0651), QChar(0x0652), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // F0=F7 - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD)}},// F8-FF - {"ISO 8859-7", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0x2018), QChar(0x2019), QChar(0x00A3), QChar(0xFFFD), QChar(0xFFFD), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x00A9), QChar(0xFFFD), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0xFFFD), QChar(0x2015), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x0384), QChar(0x0385), QChar(0x0386), QChar(0x00B7), // B0-B7 - QChar(0x0388), QChar(0x0389), QChar(0x038A), QChar(0x00BB), QChar(0x038C), QChar(0x00BD), QChar(0x038E), QChar(0x038F), // B8-BF - QChar(0x0390), QChar(0x0391), QChar(0x0392), QChar(0x0393), QChar(0x0394), QChar(0x0395), QChar(0x0396), QChar(0x0397), // C0-C7 - QChar(0x0398), QChar(0x0399), QChar(0x039A), QChar(0x039B), QChar(0x039C), QChar(0x039D), QChar(0x039E), QChar(0x039F), // C8-CF - QChar(0x03A0), QChar(0x03A1), QChar(0xFFFD), QChar(0x03A3), QChar(0x03A4), QChar(0x03A5), QChar(0x03A6), QChar(0x03A7), // D0-D7 - QChar(0x03A8), QChar(0x03A9), QChar(0x03AA), QChar(0x03AB), QChar(0x03AC), QChar(0x03AD), QChar(0x03AE), QChar(0x03AF), // D8-DF - QChar(0x03B0), QChar(0x03B1), QChar(0x03B2), QChar(0x03B3), QChar(0x03B4), QChar(0x03B5), QChar(0x03B6), QChar(0x03B7), // E0-E7 - QChar(0x03B8), QChar(0x03B9), QChar(0x03BA), QChar(0x03BB), QChar(0x03BC), QChar(0x03BD), QChar(0x03BE), QChar(0x03BF), // E8-EF - QChar(0x03C0), QChar(0x03C1), QChar(0x03C2), QChar(0x03C3), QChar(0x03C4), QChar(0x03C5), QChar(0x03C6), QChar(0x03C7), // F0=F7 - QChar(0x03C8), QChar(0x03C9), QChar(0x03CA), QChar(0x03CB), QChar(0x03CC), QChar(0x03CD), QChar(0x03CE), QChar(0xFFFD)}},// F8-FF - {"ISO 8859-8", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0xFFFD), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x00A9), QChar(0x00D7), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x203E), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x00B8), QChar(0x00B9), QChar(0x00F7), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0xFFFD), // B8-BF - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // C0-C7 - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // C8-CF - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // D0-D7 - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x2017), // D8-DF - QChar(0x05D0), QChar(0x05D1), QChar(0x05D2), QChar(0x05D3), QChar(0x05D4), QChar(0x05D5), QChar(0x05D6), QChar(0x05D7), // E0-E7 - QChar(0x05D8), QChar(0x05D9), QChar(0x05DA), QChar(0x05DB), QChar(0x05DC), QChar(0x05DD), QChar(0x05DE), QChar(0x05DF), // E8-EF - QChar(0x05E0), QChar(0x05E1), QChar(0x05E2), QChar(0x05E3), QChar(0x05E4), QChar(0x05E5), QChar(0x05E6), QChar(0x05E7), // F0=F7 - QChar(0x05E8), QChar(0x05E9), QChar(0x05EA), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD)}},// F8-FF - {"ISO 8859-9", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0x00A1), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x00A9), QChar(0x00AA), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x00B8), QChar(0x00B9), QChar(0x00BA), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00BF), // B8-BF - QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x00C7), // C0-C7 - QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF - QChar(0x011E), QChar(0x00D1), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 - QChar(0x00D8), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x0130), QChar(0x015E), QChar(0x00DF), // D8-DF - QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x00E7), // E0-E7 - QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF - QChar(0x011F), QChar(0x00F1), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 - QChar(0x00F8), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x0131), QChar(0x015F), QChar(0x00FF)}},// F8-FF - {"ISO 8859-10", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0x0104), QChar(0x0112), QChar(0x0122), QChar(0x012A), QChar(0x0128), QChar(0x0136), QChar(0x00A7), // A0-A7 - QChar(0x013B), QChar(0x0110), QChar(0x0160), QChar(0x0166), QChar(0x017D), QChar(0x00AD), QChar(0x016A), QChar(0x014A), // A8-AF - QChar(0x00B0), QChar(0x0105), QChar(0x0113), QChar(0x0123), QChar(0x012B), QChar(0x0129), QChar(0x0137), QChar(0x00B7), // B0-B7 - QChar(0x013C), QChar(0x0111), QChar(0x0161), QChar(0x0167), QChar(0x017E), QChar(0x2015), QChar(0x016B), QChar(0x014B), // B8-BF - QChar(0x0100), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x012E), // C0-C7 - QChar(0x010C), QChar(0x00C9), QChar(0x0118), QChar(0x00CB), QChar(0x0116), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF - QChar(0x00D0), QChar(0x0145), QChar(0x014C), QChar(0x00D3), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x0168), // D0-D7 - QChar(0x00D8), QChar(0x0172), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x00DD), QChar(0x00DE), QChar(0x00DF), // D8-DF - QChar(0x0101), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x012F), // E0-E7 - QChar(0x010D), QChar(0x00E9), QChar(0x0119), QChar(0x00EB), QChar(0x0117), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF - QChar(0x00F0), QChar(0x0146), QChar(0x014D), QChar(0x00F3), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x0169), // F0=F7 - QChar(0x00F8), QChar(0x0173), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x00FD), QChar(0x00FE), QChar(0x0138)}},// F8-FF - {"ISO 8859-11", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 80-87 - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 88-8F - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 90-97 - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 98-9F - QChar(0x00A0), QChar(0x0E01), QChar(0x0E02), QChar(0x0E03), QChar(0x0E04), QChar(0x0E05), QChar(0x0E06), QChar(0x0E07), // A0-A7 - QChar(0x0E08), QChar(0x0E09), QChar(0x0E0A), QChar(0x0E0B), QChar(0x0E0C), QChar(0x0E0D), QChar(0x0E0E), QChar(0x0E0F), // A8-AF - QChar(0x0E10), QChar(0x0E11), QChar(0x0E12), QChar(0x0E13), QChar(0x0E14), QChar(0x0E15), QChar(0x0E16), QChar(0x0E17), // B0-B7 - QChar(0x0E18), QChar(0x0E19), QChar(0x0E1A), QChar(0x0E1B), QChar(0x0E1C), QChar(0x0E1D), QChar(0x0E1E), QChar(0x0E1F), // B8-BF - QChar(0x0E20), QChar(0x0E21), QChar(0x0E22), QChar(0x0E23), QChar(0x0E24), QChar(0x0E25), QChar(0x0E26), QChar(0x0E27), // C0-C7 - QChar(0x0E28), QChar(0x0E29), QChar(0x0E2A), QChar(0x0E2B), QChar(0x0E2C), QChar(0x0E2D), QChar(0x0E2E), QChar(0x0E2F), // C8-CF - QChar(0x0E30), QChar(0x0E31), QChar(0x0E32), QChar(0x0E33), QChar(0x0E34), QChar(0x0E35), QChar(0x0E36), QChar(0x0E37), // D0-D7 - QChar(0x0E38), QChar(0x0E39), QChar(0x0E3A), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x0E3F), // D8-DF - QChar(0x0E40), QChar(0x0E41), QChar(0x0E42), QChar(0x0E43), QChar(0x0E44), QChar(0x0E45), QChar(0x0E46), QChar(0x0E47), // E0-E7 - QChar(0x0E48), QChar(0x0E49), QChar(0x0E4A), QChar(0x0E4B), QChar(0x0E4C), QChar(0x0E4D), QChar(0x0E4E), QChar(0x0E4F), // E8-EF - QChar(0x0E50), QChar(0x0E51), QChar(0x0E52), QChar(0x0E53), QChar(0x0E54), QChar(0x0E55), QChar(0x0E56), QChar(0x0E57), // F0=F7 - QChar(0x0E58), QChar(0x0E59), QChar(0x0E5A), QChar(0x0E5B), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD)}},// F8-FF - {"ISO 8859-13", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0x201D), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x201E), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x00D8), QChar(0x00A9), QChar(0x0156), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00C6), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x201C), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x00F8), QChar(0x00B9), QChar(0x0157), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00E6), // B8-BF - QChar(0x0104), QChar(0x012E), QChar(0x0100), QChar(0x0106), QChar(0x00C4), QChar(0x00C5), QChar(0x0118), QChar(0x0112), // C0-C7 - QChar(0x010C), QChar(0x00C9), QChar(0x0179), QChar(0x0116), QChar(0x0122), QChar(0x0136), QChar(0x012A), QChar(0x013B), // C8-CF - QChar(0x0160), QChar(0x0143), QChar(0x0145), QChar(0x00D3), QChar(0x014C), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 - QChar(0x0172), QChar(0x0141), QChar(0x015A), QChar(0x016A), QChar(0x00DC), QChar(0x017B), QChar(0x017D), QChar(0x00DF), // D8-DF - QChar(0x0105), QChar(0x012F), QChar(0x0101), QChar(0x0107), QChar(0x00E4), QChar(0x00E5), QChar(0x0119), QChar(0x0113), // E0-E7 - QChar(0x010D), QChar(0x00E9), QChar(0x017A), QChar(0x0117), QChar(0x0123), QChar(0x0137), QChar(0x012B), QChar(0x013C), // E8-EF - QChar(0x0161), QChar(0x0144), QChar(0x0146), QChar(0x00F3), QChar(0x014D), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 - QChar(0x0173), QChar(0x0142), QChar(0x015B), QChar(0x016B), QChar(0x00FC), QChar(0x017C), QChar(0x017E), QChar(0x2019)}},// F8-FF - {"ISO 8859-14", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0x1E02), QChar(0x1E03), QChar(0x00A3), QChar(0x010A), QChar(0x010B), QChar(0x1E0A), QChar(0x00A7), // A0-A7 - QChar(0x1E80), QChar(0x00A9), QChar(0x1E82), QChar(0x1E0B), QChar(0x1EF2), QChar(0x00AD), QChar(0x00AE), QChar(0x0178), // A8-AF - QChar(0x1E1E), QChar(0x1E1F), QChar(0x0120), QChar(0x0121), QChar(0x1E40), QChar(0x1E41), QChar(0x00B6), QChar(0x1E56), // B0-B7 - QChar(0x1E81), QChar(0x1E57), QChar(0x1E83), QChar(0x1E60), QChar(0x1EF3), QChar(0x1E84), QChar(0x1E85), QChar(0x1E61), // B8-BF - QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x00C7), // C0-C7 - QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF - QChar(0x0174), QChar(0x00D1), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x1E6A), // D0-D7 - QChar(0x00D8), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x00DD), QChar(0x0176), QChar(0x00DF), // D8-DF - QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x00E7), // E0-E7 - QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF - QChar(0x0175), QChar(0x00F1), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x1E6B), // F0=F7 - QChar(0x00F8), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x00FD), QChar(0x0177), QChar(0x00FF)}},// F8-FF - {"ISO 8859-15", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0x00A1), QChar(0x00A2), QChar(0x00A3), QChar(0x20AC), QChar(0x00A5), QChar(0x0160), QChar(0x00A7), // A0-A7 - QChar(0x0161), QChar(0x00A9), QChar(0x00AA), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x017D), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x017E), QChar(0x00B9), QChar(0x00BA), QChar(0x00BB), QChar(0x0152), QChar(0x0153), QChar(0x0178), QChar(0x00BF), // B8-BF - QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x00C7), // C0-C7 - QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF - QChar(0x00D0), QChar(0x00D1), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 - QChar(0x00D8), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x00DD), QChar(0x00DE), QChar(0x00DF), // D8-DF - QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x00E7), // E0-E7 - QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF - QChar(0x00F0), QChar(0x00F1), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 - QChar(0x00F8), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x00FD), QChar(0x00FE), QChar(0x00FF)}},// F8-FF - {"ISO 8859-16", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 - QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F - QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 - QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F - QChar(0x00A0), QChar(0x0104), QChar(0x0105), QChar(0x0141), QChar(0x20AC), QChar(0x201E), QChar(0x0160), QChar(0x00A7), // A0-A7 - QChar(0x0161), QChar(0x00A9), QChar(0x0218), QChar(0x00AB), QChar(0x0179), QChar(0x00AD), QChar(0x017A), QChar(0x017B), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x010C), QChar(0x0142), QChar(0x017D), QChar(0x201D), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x017E), QChar(0x010D), QChar(0x0219), QChar(0x00BB), QChar(0x0152), QChar(0x0153), QChar(0x0178), QChar(0x017C), // B8-BF - QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x0102), QChar(0x00C4), QChar(0x0106), QChar(0x00C6), QChar(0x00C7), // C0-C7 - QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF - QChar(0x0110), QChar(0x0143), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x0150), QChar(0x00D6), QChar(0x015A), // D0-D7 - QChar(0x0170), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x0118), QChar(0x021A), QChar(0x00DF), // D8-DF - QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x0103), QChar(0x00E4), QChar(0x0107), QChar(0x00E6), QChar(0x00E7), // E0-E7 - QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF - QChar(0x0111), QChar(0x0144), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x0151), QChar(0x00F6), QChar(0x015B), // F0=F7 - QChar(0x0171), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x0119), QChar(0x021B), QChar(0x00FF)}},// F8-FF - {"CP437", // Our alternative is M_CP437 - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x00C7), QChar(0x00FC), QChar(0x00E9), QChar(0x00E2), QChar(0x00E4), QChar(0x00E0), QChar(0x00E5), QChar(0x00E7), // 80-87 - QChar(0x00EA), QChar(0x00EB), QChar(0x00E8), QChar(0x00EF), QChar(0x00EE), QChar(0x00EC), QChar(0x00C4), QChar(0x00C5), // 88-8F - QChar(0x00C9), QChar(0x00E6), QChar(0x00C6), QChar(0x00F4), QChar(0x00F6), QChar(0x00F2), QChar(0x00FB), QChar(0x00F9), // 90-97 - QChar(0x00FF), QChar(0x00D6), QChar(0x00DC), QChar(0x00A2), QChar(0x00A3), QChar(0x00A5), QChar(0x20A7), QChar(0x0192), // 98-9F - QChar(0x00E1), QChar(0x00ED), QChar(0x00F3), QChar(0x00FA), QChar(0x00F1), QChar(0x00D1), QChar(0x00AA), QChar(0x00BA), // A0-A7 - QChar(0x00BF), QChar(0x2310), QChar(0x00AC), QChar(0x00BD), QChar(0x00BC), QChar(0x00A1), QChar(0x00AB), QChar(0x00BB), // A8-AF - QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2502), QChar(0x2524), QChar(0x2561), QChar(0x2562), QChar(0x2556), // B0-B7 - QChar(0x2555), QChar(0x2563), QChar(0x2551), QChar(0x2557), QChar(0x255D), QChar(0x255C), QChar(0x255B), QChar(0x2510), // B8-BF - QChar(0x2514), QChar(0x2534), QChar(0x252C), QChar(0x251C), QChar(0x2500), QChar(0x253C), QChar(0x255E), QChar(0x255F), // C0-C7 - QChar(0x255A), QChar(0x2554), QChar(0x2569), QChar(0x2566), QChar(0x2560), QChar(0x2550), QChar(0x256C), QChar(0x2567), // C8-CF - QChar(0x2568), QChar(0x2564), QChar(0x2565), QChar(0x2559), QChar(0x2558), QChar(0x2552), QChar(0x2553), QChar(0x256B), // D0-D7 - QChar(0x256A), QChar(0x2518), QChar(0x250C), QChar(0x2588), QChar(0x2584), QChar(0x258C), QChar(0x2590), QChar(0x2580), // D8-DF - QChar(0x03B1), QChar(0x00DF), QChar(0x0393), QChar(0x03C0), QChar(0x03A3), QChar(0x03C3), QChar(0x00B5), QChar(0x03C4), // E0-E7 - QChar(0x03A6), QChar(0x0398), QChar(0x03A9), QChar(0x03B4), QChar(0x221E), QChar(0x03C6), QChar(0x03B5), QChar(0x2229), // E8-EF - QChar(0x2261), QChar(0x00B1), QChar(0x2265), QChar(0x2264), QChar(0x2320), QChar(0x2321), QChar(0x00F7), QChar(0x2248), // F0=F7 - QChar(0x00B0), QChar(0x2219), QChar(0x00B7), QChar(0x221A), QChar(0x207F), QChar(0x00B2), QChar(0x25A0), QChar(0x00A0)}},// F8-FF - {"CP667", // Our alternative is M_CP667 - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x00C7), QChar(0x00FC), QChar(0x00E9), QChar(0x00E2), QChar(0x00E4), QChar(0x00E0), QChar(0x0105), QChar(0x00E7), // 80-87 - QChar(0x00EA), QChar(0x00EB), QChar(0x00E8), QChar(0x00EF), QChar(0x00EE), QChar(0x0107), QChar(0x00C4), QChar(0x0104), // 88-8F - QChar(0x0118), QChar(0x0119), QChar(0x0142), QChar(0x00F4), QChar(0x00F6), QChar(0x0106), QChar(0x00FB), QChar(0x00F9), // 90-97 - QChar(0x015A), QChar(0x00D6), QChar(0x00DC), QChar(0x00A2), QChar(0x0141), QChar(0x00A5), QChar(0x015B), QChar(0x0192), // 98-9F - QChar(0x0179), QChar(0x017B), QChar(0x00F3), QChar(0x0144), QChar(0x0143), QChar(0x017A), QChar(0x017C), QChar(0x00BA), // A0-A7 - QChar(0x00BF), QChar(0x2310), QChar(0x00AC), QChar(0x00BD), QChar(0x00BC), QChar(0x00A1), QChar(0x00AB), QChar(0x00BB), // A8-AF - QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2502), QChar(0x2524), QChar(0x2561), QChar(0x2562), QChar(0x2556), // B0-B7 - QChar(0x2555), QChar(0x2563), QChar(0x2551), QChar(0x2557), QChar(0x255D), QChar(0x255C), QChar(0x255B), QChar(0x2510), // B8-BF - QChar(0x2514), QChar(0x2534), QChar(0x252C), QChar(0x251C), QChar(0x2500), QChar(0x253C), QChar(0x255E), QChar(0x255F), // C0-C7 - QChar(0x255A), QChar(0x2554), QChar(0x2569), QChar(0x2566), QChar(0x2560), QChar(0x2550), QChar(0x256C), QChar(0x2567), // C8-CF - QChar(0x2568), QChar(0x2564), QChar(0x2565), QChar(0x2559), QChar(0x2558), QChar(0x2552), QChar(0x2553), QChar(0x256B), // D0-D7 - QChar(0x256A), QChar(0x2518), QChar(0x250C), QChar(0x2588), QChar(0x2584), QChar(0x258C), QChar(0x2590), QChar(0x2580), // D8-DF - QChar(0x03B1), QChar(0x00DF), QChar(0x0393), QChar(0x03C0), QChar(0x03A3), QChar(0x03C3), QChar(0x00B5), QChar(0x03C4), // E0-E7 - QChar(0x03A6), QChar(0x0398), QChar(0x03A9), QChar(0x03B4), QChar(0x221E), QChar(0x03C6), QChar(0x03B5), QChar(0x2229), // E8-EF - QChar(0x2261), QChar(0x00B1), QChar(0x2265), QChar(0x2264), QChar(0x2320), QChar(0x2321), QChar(0x00F7), QChar(0x2248), // F0=F7 - QChar(0x00B0), QChar(0x2219), QChar(0x00B7), QChar(0x221A), QChar(0x207F), QChar(0x00B2), QChar(0x25A0), QChar(0x00A0)}},// F8-FF - {"CP737", // Our alternative is M_CP737 - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0391), QChar(0x0392), QChar(0x0393), QChar(0x0394), QChar(0x0395), QChar(0x0396), QChar(0x0397), QChar(0x0398), // 80-87 - QChar(0x0399), QChar(0x039A), QChar(0x039B), QChar(0x039C), QChar(0x039D), QChar(0x039E), QChar(0x039F), QChar(0x03A0), // 88-8F - QChar(0x03A1), QChar(0x03A3), QChar(0x03A4), QChar(0x03A5), QChar(0x03A6), QChar(0x03A7), QChar(0x03A8), QChar(0x03A9), // 90-97 - QChar(0x00FF), QChar(0x00D6), QChar(0x00DC), QChar(0x00A2), QChar(0x00A3), QChar(0x00A5), QChar(0x20A7), QChar(0x0192), // 98-9F - QChar(0x00E1), QChar(0x00ED), QChar(0x00F3), QChar(0x00FA), QChar(0x00F1), QChar(0x00D1), QChar(0x00AA), QChar(0x00BA), // A0-A7 - QChar(0x00BF), QChar(0x2310), QChar(0x00AC), QChar(0x00BD), QChar(0x00BC), QChar(0x00A1), QChar(0x00AB), QChar(0x00BB), // A8-AF - QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2502), QChar(0x2524), QChar(0x2561), QChar(0x2562), QChar(0x2556), // B0-B7 - QChar(0x2555), QChar(0x2563), QChar(0x2551), QChar(0x2557), QChar(0x255D), QChar(0x255C), QChar(0x255B), QChar(0x2510), // B8-BF - QChar(0x2514), QChar(0x2534), QChar(0x252C), QChar(0x251C), QChar(0x2500), QChar(0x253C), QChar(0x255E), QChar(0x255F), // C0-C7 - QChar(0x255A), QChar(0x2554), QChar(0x2569), QChar(0x2566), QChar(0x2560), QChar(0x2550), QChar(0x256C), QChar(0x2567), // C8-CF - QChar(0x2568), QChar(0x2564), QChar(0x2565), QChar(0x2559), QChar(0x2558), QChar(0x2552), QChar(0x2553), QChar(0x256B), // D0-D7 - QChar(0x256A), QChar(0x2518), QChar(0x250C), QChar(0x2588), QChar(0x2584), QChar(0x258C), QChar(0x2590), QChar(0x2580), // D8-DF - QChar(0x03C9), QChar(0x03AC), QChar(0x03AD), QChar(0x03AE), QChar(0x03CA), QChar(0x03AF), QChar(0x03CC), QChar(0x03CD), // E0-E7 - QChar(0x03CB), QChar(0x03CE), QChar(0x0386), QChar(0x0388), QChar(0x0389), QChar(0x038A), QChar(0x038C), QChar(0x038E), // E8-EF - QChar(0x03C9), QChar(0x00B1), QChar(0x2265), QChar(0x2264), QChar(0x03AA), QChar(0x03AB), QChar(0x00F7), QChar(0x2248), // F0=F7 - QChar(0x00B0), QChar(0x2219), QChar(0x00B7), QChar(0x221A), QChar(0x207F), QChar(0x00B2), QChar(0x25A0), QChar(0x00A0)}},// F8-FF - {"CP850", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x00C7), QChar(0x00FC), QChar(0x00E9), QChar(0x00E2), QChar(0x00E4), QChar(0x00E0), QChar(0x00E5), QChar(0x00E7), // 80-87 - QChar(0x00EA), QChar(0x00EB), QChar(0x00E8), QChar(0x00EF), QChar(0x00EE), QChar(0x00EC), QChar(0x00C4), QChar(0x00C5), // 88-8F - QChar(0x00C9), QChar(0x00E6), QChar(0x00C6), QChar(0x00F4), QChar(0x00F6), QChar(0x00F2), QChar(0x00FB), QChar(0x00F9), // 90-97 - QChar(0x00FF), QChar(0x00D6), QChar(0x00DC), QChar(0x00F8), QChar(0x00A3), QChar(0x00D8), QChar(0x00D7), QChar(0x0192), // 98-9F - QChar(0x00E1), QChar(0x00ED), QChar(0x00F3), QChar(0x00FA), QChar(0x00F1), QChar(0x00D1), QChar(0x00AA), QChar(0x00BA), // A0-A7 - QChar(0x00BF), QChar(0x00AE), QChar(0x00AC), QChar(0x00BD), QChar(0x00BC), QChar(0x00A1), QChar(0x00AB), QChar(0x00BB), // A8-AF - QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2502), QChar(0x2524), QChar(0x00C1), QChar(0x00C2), QChar(0x00C0), // B0-B7 - QChar(0x00A9), QChar(0x2563), QChar(0x2551), QChar(0x2557), QChar(0x255D), QChar(0x00A2), QChar(0x00A5), QChar(0x2510), // B8-BF - QChar(0x2514), QChar(0x2534), QChar(0x252C), QChar(0x251C), QChar(0x2500), QChar(0x253C), QChar(0x00E3), QChar(0x00C3), // C0-C7 - QChar(0x255A), QChar(0x2554), QChar(0x2569), QChar(0x2566), QChar(0x2560), QChar(0x2550), QChar(0x256C), QChar(0x00A4), // C8-CF - QChar(0x00F0), QChar(0x00D0), QChar(0x00CA), QChar(0x00CB), QChar(0x00C8), QChar(0x0131), QChar(0x00CD), QChar(0x00CE), // D0-D7 - QChar(0x00CF), QChar(0x2518), QChar(0x250C), QChar(0x2588), QChar(0x2584), QChar(0x00A6), QChar(0x00CC), QChar(0x2580), // D8-DF - QChar(0x00D3), QChar(0x00DF), QChar(0x00D4), QChar(0x00D2), QChar(0x00F5), QChar(0x00D5), QChar(0x00B5), QChar(0x00FE), // E0-E7 - QChar(0x00DE), QChar(0x00DA), QChar(0x00DB), QChar(0x00D9), QChar(0x00FD), QChar(0x00DD), QChar(0x00AF), QChar(0x00B4), // E8-EF - QChar(0x00AD), QChar(0x00B1), QChar(0x2017), QChar(0x00BE), QChar(0x00B6), QChar(0x00A7), QChar(0x00F7), QChar(0x00B8), // F0=F7 - QChar(0x00B0), QChar(0x00A8), QChar(0x00B7), QChar(0x00B9), QChar(0x00B3), QChar(0x00B2), QChar(0x25A0), QChar(0x00A0)}},// F8-FF - {"CP866", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0410), QChar(0x0411), QChar(0x0412), QChar(0x0413), QChar(0x0414), QChar(0x0415), QChar(0x0416), QChar(0x0417), // 80-87 - QChar(0x0418), QChar(0x0419), QChar(0x041A), QChar(0x041B), QChar(0x041C), QChar(0x041D), QChar(0x041E), QChar(0x041F), // 88-8F - QChar(0x0420), QChar(0x0421), QChar(0x0422), QChar(0x0423), QChar(0x0424), QChar(0x0425), QChar(0x0426), QChar(0x0427), // 90-97 - QChar(0x0428), QChar(0x0429), QChar(0x042A), QChar(0x042B), QChar(0x042C), QChar(0x042D), QChar(0x042E), QChar(0x042F), // 98-9F - QChar(0x0430), QChar(0x0431), QChar(0x0432), QChar(0x0433), QChar(0x0434), QChar(0x0435), QChar(0x0436), QChar(0x0437), // A0-A7 - QChar(0x0438), QChar(0x0439), QChar(0x043A), QChar(0x043B), QChar(0x043C), QChar(0x043D), QChar(0x043E), QChar(0x043F), // A8-AF - QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2502), QChar(0x2524), QChar(0x2561), QChar(0x2562), QChar(0x2556), // B0-B7 - QChar(0x2555), QChar(0x2563), QChar(0x2551), QChar(0x2557), QChar(0x255D), QChar(0x255C), QChar(0x255B), QChar(0x2510), // B8-BF - QChar(0x2514), QChar(0x2534), QChar(0x252C), QChar(0x251C), QChar(0x2500), QChar(0x253C), QChar(0x255E), QChar(0x255F), // C0-C7 - QChar(0x255A), QChar(0x2554), QChar(0x2569), QChar(0x2566), QChar(0x2560), QChar(0x2550), QChar(0x256C), QChar(0x2567), // C8-CF - QChar(0x2568), QChar(0x2564), QChar(0x2565), QChar(0x2559), QChar(0x2558), QChar(0x2552), QChar(0x2553), QChar(0x256B), // D0-D7 - QChar(0x256A), QChar(0x2518), QChar(0x250C), QChar(0x2588), QChar(0x2584), QChar(0x258C), QChar(0x2590), QChar(0x2580), // D8-DF - QChar(0x0440), QChar(0x0441), QChar(0x0442), QChar(0x0443), QChar(0x0444), QChar(0x0445), QChar(0x0446), QChar(0x0447), // E0-E7 - QChar(0x0448), QChar(0x0449), QChar(0x044A), QChar(0x044B), QChar(0x044C), QChar(0x044D), QChar(0x044E), QChar(0x044F), // E8-EF - QChar(0x0401), QChar(0x0451), QChar(0x0404), QChar(0x0454), QChar(0x0407), QChar(0x0457), QChar(0x040E), QChar(0x045E), // F0=F7 - QChar(0x00B0), QChar(0x2219), QChar(0x00B7), QChar(0x221A), QChar(0x2116), QChar(0x00A4), QChar(0x25A0), QChar(0x00A0)}},// F8-FF - {"CP869", // Our alternative is M_CP869 - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x0386), QChar(0x20AC), // 80-87 - QChar(0x00B7), QChar(0x00AC), QChar(0x00A6), QChar(0x2018), QChar(0x2019), QChar(0x0388), QChar(0x2015), QChar(0x0389), // 88-8F - QChar(0x038A), QChar(0x03AA), QChar(0x038C), QChar(0xFFFD), QChar(0xFFFD), QChar(0x038E), QChar(0x03A8), QChar(0x00A9), // 90-97 - QChar(0x038F), QChar(0x00B2), QChar(0x00B3), QChar(0x03AC), QChar(0x00A3), QChar(0x03AD), QChar(0x03AE), QChar(0x03AF), // 98-9F - QChar(0x03CA), QChar(0x0390), QChar(0x03CC), QChar(0x03CD), QChar(0x0391), QChar(0x0392), QChar(0x0393), QChar(0x0394), // A0-A7 - QChar(0x0395), QChar(0x0396), QChar(0x0397), QChar(0x00BD), QChar(0x0398), QChar(0x0399), QChar(0x00AB), QChar(0x00BB), // A8-AF - QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2502), QChar(0x2524), QChar(0x039A), QChar(0x039B), QChar(0x039C), // B0-B7 - QChar(0x039D), QChar(0x2563), QChar(0x2551), QChar(0x2557), QChar(0x255D), QChar(0x039E), QChar(0x039F), QChar(0x2510), // B8-BF - QChar(0x2514), QChar(0x2534), QChar(0x252C), QChar(0x251C), QChar(0x2500), QChar(0x253C), QChar(0x03A0), QChar(0x03A1), // C0-C7 - QChar(0x255A), QChar(0x2554), QChar(0x2569), QChar(0x2566), QChar(0x2560), QChar(0x2550), QChar(0x256C), QChar(0x03A3), // C8-CF - QChar(0x03A4), QChar(0x03A5), QChar(0x03A6), QChar(0x03A7), QChar(0x03A8), QChar(0x03A9), QChar(0x03B1), QChar(0x03B2), // D0-D7 - QChar(0x03B3), QChar(0x2518), QChar(0x250C), QChar(0x2588), QChar(0x2584), QChar(0x03B4), QChar(0x03B5), QChar(0x2580), // D8-DF - QChar(0x03B6), QChar(0x03B7), QChar(0x03B8), QChar(0x03B9), QChar(0x03BA), QChar(0x03BB), QChar(0x03BC), QChar(0x03BD), // E0-E7 - QChar(0x03BE), QChar(0x03BF), QChar(0x03C0), QChar(0x03C1), QChar(0x03C3), QChar(0x03C2), QChar(0x03C4), QChar(0x0384), // E8-EF - QChar(0x00AD), QChar(0x00B1), QChar(0x03C5), QChar(0x03C6), QChar(0x03C7), QChar(0x00A7), QChar(0x03C8), QChar(0x0385), // F0=F7 - QChar(0x00B0), QChar(0x00A8), QChar(0x03C9), QChar(0x03CB), QChar(0x03B0), QChar(0x03CE), QChar(0x25A0), QChar(0x00A0)}},// F8-FF - {"CP1161", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x20AC), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x2026), QChar(0xFFFD), QChar(0xFFFD), // 80-87 - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 88-8F - QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 - QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 98-9F - QChar(0x00A0), QChar(0x0E01), QChar(0x0E02), QChar(0x0E03), QChar(0x0E04), QChar(0x0E05), QChar(0x0E06), QChar(0x0E07), // A0-A7 - QChar(0x0E08), QChar(0x0E09), QChar(0x0E0A), QChar(0x0E0B), QChar(0x0E0C), QChar(0x0E0D), QChar(0x0E0E), QChar(0x0E0F), // A8-AF - QChar(0x0E10), QChar(0x0E11), QChar(0x0E12), QChar(0x0E13), QChar(0x0E14), QChar(0x0E15), QChar(0x0E16), QChar(0x0E17), // B0-B7 - QChar(0x0E18), QChar(0x0E19), QChar(0x0E1A), QChar(0x0E1B), QChar(0x0E1C), QChar(0x0E1D), QChar(0x0E1E), QChar(0x0E1F), // B8-BF - QChar(0x0E20), QChar(0x0E21), QChar(0x0E22), QChar(0x0E23), QChar(0x0E24), QChar(0x0E25), QChar(0x0E26), QChar(0x0E27), // C0-C7 - QChar(0x0E28), QChar(0x0E29), QChar(0x0E2A), QChar(0x0E2B), QChar(0x0E2C), QChar(0x0E2D), QChar(0x0E2E), QChar(0x0E2F), // C8-CF - QChar(0x0E30), QChar(0x0E31), QChar(0x0E32), QChar(0x0E33), QChar(0x0E34), QChar(0x0E35), QChar(0x0E36), QChar(0x0E37), // D0-D7 - QChar(0x0E38), QChar(0x0E39), QChar(0x0E3A), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x0E3F), // D8-DF - QChar(0x0E40), QChar(0x0E41), QChar(0x0E42), QChar(0x0E43), QChar(0x0E44), QChar(0x0E45), QChar(0x0E46), QChar(0x0E47), // E0-E7 - QChar(0x0E48), QChar(0x0E49), QChar(0x0E4A), QChar(0x0E4B), QChar(0x0E4C), QChar(0x0E4D), QChar(0x0E4E), QChar(0x0E4F), // E8-EF - QChar(0x0E50), QChar(0x0E51), QChar(0x0E52), QChar(0x0E53), QChar(0x0E54), QChar(0x0E55), QChar(0x0E56), QChar(0x0E57), // F0=F7 - QChar(0x0E58), QChar(0x0E59), QChar(0x0E5A), QChar(0x0E5B), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD)}},// F8-FF - {"KOI8-R", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x2500), QChar(0x2502), QChar(0x250C), QChar(0x2510), QChar(0x2514), QChar(0x2518), QChar(0x251C), QChar(0x2524), // 80-87 - QChar(0x252C), QChar(0x2534), QChar(0x253C), QChar(0x2580), QChar(0x2584), QChar(0x2588), QChar(0x258C), QChar(0x2590), // 88-8F - QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2320), QChar(0x25A0), QChar(0x2219), QChar(0x221A), QChar(0x2248), // 90-97 - QChar(0x2264), QChar(0x2265), QChar(0x00A0), QChar(0x2321), QChar(0x00B0), QChar(0x00B2), QChar(0x00B7), QChar(0x00F7), // 98-9F - QChar(0x2550), QChar(0x2551), QChar(0x2552), QChar(0x0451), QChar(0x2553), QChar(0x2554), QChar(0x2555), QChar(0x2556), // A0-A7 - QChar(0x2557), QChar(0x2558), QChar(0x2559), QChar(0x255A), QChar(0x255B), QChar(0x255C), QChar(0x255D), QChar(0x255E), // A8-AF - QChar(0x255F), QChar(0x2560), QChar(0x2561), QChar(0x0401), QChar(0x2562), QChar(0x2563), QChar(0x2564), QChar(0x2565), // B0-B7 - QChar(0x2566), QChar(0x2567), QChar(0x2568), QChar(0x2569), QChar(0x256A), QChar(0x256B), QChar(0x256C), QChar(0x00A9), // B8-BF - QChar(0x044E), QChar(0x0430), QChar(0x0431), QChar(0x0446), QChar(0x0434), QChar(0x0435), QChar(0x0444), QChar(0x0433), // C0-C7 - QChar(0x0445), QChar(0x0438), QChar(0x0439), QChar(0x043A), QChar(0x043B), QChar(0x043C), QChar(0x043D), QChar(0x043E), // C8-CF - QChar(0x043F), QChar(0x044F), QChar(0x0440), QChar(0x0441), QChar(0x0442), QChar(0x0443), QChar(0x0436), QChar(0x0432), // D0-D7 - QChar(0x044C), QChar(0x044B), QChar(0x0437), QChar(0x0448), QChar(0x044D), QChar(0x0449), QChar(0x0447), QChar(0x044A), // D8-DF - QChar(0x042E), QChar(0x0410), QChar(0x0411), QChar(0x0426), QChar(0x0414), QChar(0x0415), QChar(0x0424), QChar(0x0413), // E0-E7 - QChar(0x0425), QChar(0x0418), QChar(0x0419), QChar(0x041A), QChar(0x041B), QChar(0x041C), QChar(0x041D), QChar(0x041E), // E8-EF - QChar(0x041F), QChar(0x042F), QChar(0x0420), QChar(0x0421), QChar(0x0422), QChar(0x0423), QChar(0x0416), QChar(0x0412), // F0=F7 - QChar(0x042C), QChar(0x042B), QChar(0x0417), QChar(0x0428), QChar(0x042D), QChar(0x0429), QChar(0x0427), QChar(0x042A)}},// F8-FF - {"KOI8-U", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x2500), QChar(0x2502), QChar(0x250C), QChar(0x2510), QChar(0x2514), QChar(0x2518), QChar(0x251C), QChar(0x2524), // 80-87 - QChar(0x252C), QChar(0x2534), QChar(0x253C), QChar(0x2580), QChar(0x2584), QChar(0x2588), QChar(0x258C), QChar(0x2590), // 88-8F - QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2320), QChar(0x25A0), QChar(0x2219), QChar(0x221A), QChar(0x2248), // 90-97 - QChar(0x2264), QChar(0x2265), QChar(0x00A0), QChar(0x2321), QChar(0x00B0), QChar(0x00B2), QChar(0x00B7), QChar(0x00F7), // 98-9F - QChar(0x2550), QChar(0x2551), QChar(0x2552), QChar(0x0451), QChar(0x0454), QChar(0x2554), QChar(0x0456), QChar(0x0457), // A0-A7 - QChar(0x2557), QChar(0x2558), QChar(0x2559), QChar(0x255A), QChar(0x255B), QChar(0x0491), QChar(0x255D), QChar(0x255E), // A8-AF - QChar(0x255F), QChar(0x2560), QChar(0x2561), QChar(0x0401), QChar(0x0404), QChar(0x2563), QChar(0x0406), QChar(0x0407), // B0-B7 - QChar(0x2566), QChar(0x2567), QChar(0x2568), QChar(0x2569), QChar(0x256A), QChar(0x0490), QChar(0x256C), QChar(0x00A9), // B8-BF - QChar(0x044E), QChar(0x0430), QChar(0x0431), QChar(0x0446), QChar(0x0434), QChar(0x0435), QChar(0x0444), QChar(0x0433), // C0-C7 - QChar(0x0445), QChar(0x0438), QChar(0x0439), QChar(0x043A), QChar(0x043B), QChar(0x043C), QChar(0x043D), QChar(0x043E), // C8-CF - QChar(0x043F), QChar(0x044F), QChar(0x0440), QChar(0x0441), QChar(0x0442), QChar(0x0443), QChar(0x0436), QChar(0x0432), // D0-D7 - QChar(0x044C), QChar(0x044B), QChar(0x0437), QChar(0x0448), QChar(0x044D), QChar(0x0449), QChar(0x0447), QChar(0x044A), // D8-DF - QChar(0x042E), QChar(0x0410), QChar(0x0411), QChar(0x0426), QChar(0x0414), QChar(0x0415), QChar(0x0424), QChar(0x0413), // E0-E7 - QChar(0x0425), QChar(0x0418), QChar(0x0419), QChar(0x041A), QChar(0x041B), QChar(0x041C), QChar(0x041D), QChar(0x041E), // E8-EF - QChar(0x041F), QChar(0x042F), QChar(0x0420), QChar(0x0421), QChar(0x0422), QChar(0x0423), QChar(0x0416), QChar(0x0412), // F0=F7 - QChar(0x042C), QChar(0x042B), QChar(0x0417), QChar(0x0428), QChar(0x042D), QChar(0x0429), QChar(0x0427), QChar(0x042A)}},// F8-FF - {"MACINTOSH", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x00C4), QChar(0x00C5), QChar(0x00C7), QChar(0x00C9), QChar(0x00D1), QChar(0x00D6), QChar(0x00DC), QChar(0x00E1), // 80-87 - QChar(0x00E0), QChar(0x00E2), QChar(0x00E4), QChar(0x00E3), QChar(0x00E5), QChar(0x00E7), QChar(0x00E9), QChar(0x00E8), // 88-8F - QChar(0x00EA), QChar(0x00EB), QChar(0x00ED), QChar(0x00EC), QChar(0x00EE), QChar(0x00EF), QChar(0x00F1), QChar(0x00F3), // 90-97 - QChar(0x00F2), QChar(0x00F4), QChar(0x00F6), QChar(0x00F5), QChar(0x00FA), QChar(0x00F9), QChar(0x00FB), QChar(0x00FC), // 98-9F - QChar(0x2020), QChar(0x00B0), QChar(0x00A2), QChar(0x00A3), QChar(0x00A7), QChar(0x2022), QChar(0x00B6), QChar(0x00DF), // A0-A7 - QChar(0x00AE), QChar(0x00A9), QChar(0x2122), QChar(0x00B4), QChar(0x00A8), QChar(0x2260), QChar(0x00C6), QChar(0x00D8), // A8-AF - QChar(0x221E), QChar(0x00B1), QChar(0x2264), QChar(0x2265), QChar(0x00A5), QChar(0x00B5), QChar(0x2202), QChar(0x2211), // B0-B7 - QChar(0x220F), QChar(0x03C0), QChar(0x222B), QChar(0x00AA), QChar(0x00BA), QChar(0x03A9), QChar(0x00E6), QChar(0x00F8), // B8-BF - QChar(0x00BF), QChar(0x00A1), QChar(0x00AC), QChar(0x221A), QChar(0x0192), QChar(0x2248), QChar(0x2206), QChar(0x00AB), // C0-C7 - QChar(0x00BB), QChar(0x2026), QChar(0x00A0), QChar(0x00C0), QChar(0x00C3), QChar(0x00D5), QChar(0x0152), QChar(0x0153), // C8-CF - QChar(0x2013), QChar(0x2014), QChar(0x201C), QChar(0x201D), QChar(0x2018), QChar(0x2019), QChar(0x00F7), QChar(0x25CA), // D0-D7 - QChar(0x00FF), QChar(0x0178), QChar(0x2044), QChar(0x20AC), QChar(0x2039), QChar(0x203A), QChar(0xFB01), QChar(0xFB02), // D8-DF - QChar(0x2021), QChar(0x00B7), QChar(0x201A), QChar(0x201E), QChar(0x2030), QChar(0x00C2), QChar(0x00CA), QChar(0x00C1), // E0-E7 - QChar(0x00CB), QChar(0x00C8), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), QChar(0x00CC), QChar(0x00D3), QChar(0x00D4), // E8-EF - QChar(0xF8FF), QChar(0x00D2), QChar(0x00DA), QChar(0x00DB), QChar(0x00D9), QChar(0x0131), QChar(0x02C6), QChar(0x02DC), // F0=F7 - QChar(0x00AF), QChar(0x02D8), QChar(0x02D9), QChar(0x02DA), QChar(0x00B8), QChar(0x02DD), QChar(0x02DB), QChar(0x02C7)}},// F8-FF - {"WINDOWS-1250", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0xFFFD), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 - QChar(0xFFFD), QChar(0x2030), QChar(0x0160), QChar(0x2039), QChar(0x015A), QChar(0x0164), QChar(0x017D), QChar(0x0179), // 88-8F - QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 - QChar(0xFFFD), QChar(0x2122), QChar(0x0161), QChar(0x203A), QChar(0x015B), QChar(0x0165), QChar(0x017E), QChar(0x017A), // 98-9F - QChar(0x00A0), QChar(0x02C7), QChar(0x02D8), QChar(0x0141), QChar(0x00A4), QChar(0x0104), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x00A9), QChar(0x015E), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x017B), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x02DB), QChar(0x0142), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x00B8), QChar(0x0105), QChar(0x015F), QChar(0x00BB), QChar(0x013D), QChar(0x02DD), QChar(0x013E), QChar(0x017C), // B8-BF - QChar(0x0154), QChar(0x00C1), QChar(0x00C2), QChar(0x0102), QChar(0x00C4), QChar(0x0139), QChar(0x0106), QChar(0x00C7), // C0-C7 - QChar(0x010C), QChar(0x00C9), QChar(0x0118), QChar(0x00CB), QChar(0x011A), QChar(0x00CD), QChar(0x00CE), QChar(0x010E), // C8-CF - QChar(0x0110), QChar(0x0143), QChar(0x0147), QChar(0x00D3), QChar(0x00D4), QChar(0x0150), QChar(0x00D6), QChar(0x00D7), // D0-D7 - QChar(0x0158), QChar(0x016E), QChar(0x00DA), QChar(0x0170), QChar(0x00DC), QChar(0x00DD), QChar(0x0162), QChar(0x00DF), // D8-DF - QChar(0x0155), QChar(0x00E1), QChar(0x00E2), QChar(0x0103), QChar(0x00E4), QChar(0x013A), QChar(0x0107), QChar(0x00E7), // E0-E7 - QChar(0x010D), QChar(0x00E9), QChar(0x0119), QChar(0x00EB), QChar(0x011B), QChar(0x00ED), QChar(0x00EE), QChar(0x010F), // E8-EF - QChar(0x0111), QChar(0x0144), QChar(0x0148), QChar(0x00F3), QChar(0x00F4), QChar(0x0151), QChar(0x00F6), QChar(0x00F7), // F0=F7 - QChar(0x0159), QChar(0x016F), QChar(0x00FA), QChar(0x0171), QChar(0x00FC), QChar(0x00FD), QChar(0x0163), QChar(0x02D9)}},// F8-FF - {"WINDOWS-1251", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x0402), QChar(0x0403), QChar(0x201A), QChar(0x0453), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 - QChar(0x20AC), QChar(0x2030), QChar(0x0409), QChar(0x2039), QChar(0x040A), QChar(0x040C), QChar(0x040B), QChar(0x040F), // 88-8F - QChar(0x0452), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 - QChar(0xFFFD), QChar(0x2122), QChar(0x0459), QChar(0x203A), QChar(0x045A), QChar(0x045C), QChar(0x045B), QChar(0x045F), // 98-9F - QChar(0x00A0), QChar(0x040E), QChar(0x045E), QChar(0x0408), QChar(0x00A4), QChar(0x0490), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x0401), QChar(0x00A9), QChar(0x0404), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x0407), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x0406), QChar(0x0456), QChar(0x0491), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x0451), QChar(0x2116), QChar(0x0454), QChar(0x00BB), QChar(0x0458), QChar(0x0405), QChar(0x0455), QChar(0x0457), // B8-BF - QChar(0x0410), QChar(0x0411), QChar(0x0412), QChar(0x0413), QChar(0x0414), QChar(0x0415), QChar(0x0416), QChar(0x0417), // C0-C7 - QChar(0x0418), QChar(0x0419), QChar(0x041A), QChar(0x041B), QChar(0x041C), QChar(0x041D), QChar(0x041E), QChar(0x041F), // C8-CF - QChar(0x0420), QChar(0x0421), QChar(0x0422), QChar(0x0423), QChar(0x0424), QChar(0x0425), QChar(0x0426), QChar(0x0427), // D0-D7 - QChar(0x0428), QChar(0x0429), QChar(0x042A), QChar(0x042B), QChar(0x042C), QChar(0x042D), QChar(0x042E), QChar(0x042F), // D8-DF - QChar(0x0430), QChar(0x0431), QChar(0x0432), QChar(0x0433), QChar(0x0434), QChar(0x0435), QChar(0x0436), QChar(0x0437), // E0-E7 - QChar(0x0438), QChar(0x0439), QChar(0x043A), QChar(0x043B), QChar(0x043C), QChar(0x043D), QChar(0x043E), QChar(0x043F), // E8-EF - QChar(0x0440), QChar(0x0441), QChar(0x0442), QChar(0x0443), QChar(0x0444), QChar(0x0445), QChar(0x0446), QChar(0x0447), // F0=F7 - QChar(0x0448), QChar(0x0449), QChar(0x044A), QChar(0x044B), QChar(0x044C), QChar(0x044D), QChar(0x044E), QChar(0x044F)}},// F8-FF - {"WINDOWS-1252", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0x0192), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 - QChar(0x02C6), QChar(0x2030), QChar(0x0160), QChar(0x2039), QChar(0x0152), QChar(0xFFFD), QChar(0x017D), QChar(0xFFFD), // 88-8F - QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 - QChar(0x02DC), QChar(0x2122), QChar(0x0161), QChar(0x203A), QChar(0x0153), QChar(0xFFFD), QChar(0x017E), QChar(0x0178), // 98-9F - QChar(0x00A0), QChar(0x00A1), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x00A9), QChar(0x00AA), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x00B8), QChar(0x00B9), QChar(0x00BA), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00BF), // B8-BF - QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x00C7), // C0-C7 - QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF - QChar(0x00D0), QChar(0x00D1), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 - QChar(0x00D8), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x00DD), QChar(0x00DE), QChar(0x00DF), // D8-DF - QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x00E7), // E0-E7 - QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF - QChar(0x00F0), QChar(0x00F1), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 - QChar(0x00F8), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x00FD), QChar(0x00FE), QChar(0x00FF)}},// F8-FF - {"WINDOWS-1253", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0x0192), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 - QChar(0xFFFD), QChar(0x2030), QChar(0xFFFD), QChar(0x2039), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 88-8F - QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 - QChar(0xFFFD), QChar(0x2122), QChar(0xFFFD), QChar(0x203A), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 98-9F - QChar(0x00A0), QChar(0x0385), QChar(0x0386), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x00A9), QChar(0xFFFD), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x2015), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x0384), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x0388), QChar(0x0389), QChar(0x038A), QChar(0x00BB), QChar(0x038C), QChar(0x00BD), QChar(0x038E), QChar(0x038F), // B8-BF - QChar(0x0390), QChar(0x0391), QChar(0x0392), QChar(0x0393), QChar(0x0394), QChar(0x0395), QChar(0x0396), QChar(0x0397), // C0-C7 - QChar(0x0398), QChar(0x0399), QChar(0x039A), QChar(0x039B), QChar(0x039C), QChar(0x039D), QChar(0x039E), QChar(0x039F), // C8-CF - QChar(0x03A0), QChar(0x03A1), QChar(0xFFFD), QChar(0x03A3), QChar(0x03A4), QChar(0x03A5), QChar(0x03A6), QChar(0x03A7), // D0-D7 - QChar(0x03A8), QChar(0x03A9), QChar(0x03AA), QChar(0x03AB), QChar(0x03AC), QChar(0x03AD), QChar(0x03AE), QChar(0x03AF), // D8-DF - QChar(0x03B0), QChar(0x03B1), QChar(0x03B2), QChar(0x03B3), QChar(0x03B4), QChar(0x03B5), QChar(0x03B6), QChar(0x03B7), // E0-E7 - QChar(0x03B8), QChar(0x03B9), QChar(0x03BA), QChar(0x03BB), QChar(0x03BC), QChar(0x03BD), QChar(0x03BE), QChar(0x03BF), // E8-EF - QChar(0x03C0), QChar(0x03C1), QChar(0x03C2), QChar(0x03C3), QChar(0x03C4), QChar(0x03C5), QChar(0x03C6), QChar(0x03C7), // F0=F7 - QChar(0x03C8), QChar(0x03C9), QChar(0x03CA), QChar(0x03CB), QChar(0x03CC), QChar(0x03CD), QChar(0x03CE), QChar(0xFFFD)}},// F8-FF - {"WINDOWS-1254", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0x0192), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 - QChar(0x02C6), QChar(0x2030), QChar(0x0160), QChar(0x2039), QChar(0x0152), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 88-8F - QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 - QChar(0x02DC), QChar(0x2122), QChar(0x0161), QChar(0x203A), QChar(0x0153), QChar(0xFFFD), QChar(0xFFFD), QChar(0x0178), // 98-9F - QChar(0x00A0), QChar(0x00A1), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x00A9), QChar(0x00AA), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x00B8), QChar(0x00B9), QChar(0x00BA), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00BF), // B8-BF - QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x00C7), // C0-C7 - QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF - QChar(0x011E), QChar(0x00D1), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 - QChar(0x00D8), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x0130), QChar(0x015E), QChar(0x00DF), // D8-DF - QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x00E7), // E0-E7 - QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF - QChar(0x011F), QChar(0x00F1), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 - QChar(0x00F8), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x0131), QChar(0x015F), QChar(0x00FF)}},// F8-FF - {"WINDOWS-1255", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0x0192), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 - QChar(0x02C6), QChar(0x2030), QChar(0xFFFD), QChar(0x2039), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 88-8F - QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 - QChar(0x02DC), QChar(0x2122), QChar(0xFFFD), QChar(0x203A), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 98-9F - QChar(0x00A0), QChar(0x00A1), QChar(0x00A2), QChar(0x00A3), QChar(0x20AA), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x00A9), QChar(0x00D7), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x00B8), QChar(0x00B9), QChar(0x00F7), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00BF), // B8-BF - QChar(0x05B0), QChar(0x05B1), QChar(0x05B2), QChar(0x05B3), QChar(0x05B4), QChar(0x05B5), QChar(0x05B6), QChar(0x05B7), // C0-C7 - QChar(0x05B8), QChar(0x05B9), QChar(0xFFFD), QChar(0x05BB), QChar(0x05BC), QChar(0x05BD), QChar(0x05BE), QChar(0x05BF), // C8-CF - QChar(0x05C0), QChar(0x05C1), QChar(0x05C2), QChar(0x05C3), QChar(0x05F0), QChar(0x05F1), QChar(0x05F2), QChar(0x05F3), // D0-D7 - QChar(0x05F4), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // D8-DF - QChar(0x05D0), QChar(0x05D1), QChar(0x05D2), QChar(0x05D3), QChar(0x05D4), QChar(0x05D5), QChar(0x05D6), QChar(0x05D7), // E0-E7 - QChar(0x05D8), QChar(0x05D9), QChar(0x05DA), QChar(0x05DB), QChar(0x05DC), QChar(0x05DD), QChar(0x05DE), QChar(0x05DF), // E8-EF - QChar(0x05E0), QChar(0x05E1), QChar(0x05E2), QChar(0x05E3), QChar(0x05E4), QChar(0x05E5), QChar(0x05E6), QChar(0x05E7), // F0=F7 - QChar(0x05E8), QChar(0x05E9), QChar(0x05EA), QChar(0xFFFD), QChar(0xFFFD), QChar(0x200E), QChar(0x200F), QChar(0xFFFD)}},// F8-FF - {"WINDOWS-1256", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x20AC), QChar(0x067E), QChar(0x201A), QChar(0x0192), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 - QChar(0x02C6), QChar(0x2030), QChar(0x0679), QChar(0x2039), QChar(0x0152), QChar(0x0686), QChar(0x0698), QChar(0x0688), // 88-8F - QChar(0x06AF), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 - QChar(0x06A9), QChar(0x2122), QChar(0x0691), QChar(0x203A), QChar(0x0153), QChar(0x200C), QChar(0x200D), QChar(0x06BA), // 98-9F - QChar(0x00A0), QChar(0x060C), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x00A9), QChar(0x06BE), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x00B8), QChar(0x00B9), QChar(0x061B), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x061F), // B8-BF - QChar(0x06C1), QChar(0x0621), QChar(0x0622), QChar(0x0623), QChar(0x0624), QChar(0x0625), QChar(0x0626), QChar(0x0627), // C0-C7 - QChar(0x0628), QChar(0x0629), QChar(0x062A), QChar(0x062B), QChar(0x062C), QChar(0x062D), QChar(0x062E), QChar(0x062F), // C8-CF - QChar(0x0630), QChar(0x0631), QChar(0x0632), QChar(0x0633), QChar(0x0634), QChar(0x0635), QChar(0x0636), QChar(0x00D7), // D0-D7 - QChar(0x0637), QChar(0x0638), QChar(0x0639), QChar(0x063A), QChar(0x0640), QChar(0x0641), QChar(0x0642), QChar(0x0643), // D8-DF - QChar(0x00E0), QChar(0x0644), QChar(0x00E2), QChar(0x0645), QChar(0x0646), QChar(0x0647), QChar(0x0648), QChar(0x00E7), // E0-E7 - QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x0649), QChar(0x064A), QChar(0x00EE), QChar(0x00EF), // E8-EF - QChar(0x064B), QChar(0x064C), QChar(0x064D), QChar(0x064E), QChar(0x00F4), QChar(0x064F), QChar(0x0650), QChar(0x00F7), // F0=F7 - QChar(0x0651), QChar(0x00F9), QChar(0x0652), QChar(0x00FB), QChar(0x00FC), QChar(0x200E), QChar(0x200F), QChar(0x06D2)}},// F8-FF - {"WINDOWS-1257", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0xFFFD), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 - QChar(0xFFFD), QChar(0x2030), QChar(0xFFFD), QChar(0x2039), QChar(0xFFFD), QChar(0x00A8), QChar(0x02C7), QChar(0x00B8), // 88-8F - QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 - QChar(0xFFFD), QChar(0x2122), QChar(0xFFFD), QChar(0x203A), QChar(0xFFFD), QChar(0x00AF), QChar(0x02DB), QChar(0xFFFD), // 98-9F - QChar(0x00A0), QChar(0xFFFD), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0xFFFD), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x00D8), QChar(0x00A9), QChar(0x0156), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00C6), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x00F8), QChar(0x00B9), QChar(0x0157), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00E6), // B8-BF - QChar(0x0104), QChar(0x012E), QChar(0x0100), QChar(0x0106), QChar(0x00C4), QChar(0x00C5), QChar(0x0118), QChar(0x0112), // C0-C7 - QChar(0x010C), QChar(0x00C9), QChar(0x0179), QChar(0x0116), QChar(0x0122), QChar(0x0136), QChar(0x012A), QChar(0x013B), // C8-CF - QChar(0x0160), QChar(0x0143), QChar(0x0145), QChar(0x00D3), QChar(0x014C), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 - QChar(0x0172), QChar(0x0141), QChar(0x015A), QChar(0x016A), QChar(0x00DC), QChar(0x017B), QChar(0x017D), QChar(0x00DF), // D8-DF - QChar(0x0105), QChar(0x012F), QChar(0x0101), QChar(0x0107), QChar(0x00E4), QChar(0x00E5), QChar(0x0119), QChar(0x0113), // E0-E7 - QChar(0x010D), QChar(0x00E9), QChar(0x017A), QChar(0x0117), QChar(0x0123), QChar(0x0137), QChar(0x012B), QChar(0x013C), // E8-EF - QChar(0x0161), QChar(0x0144), QChar(0x0146), QChar(0x00F3), QChar(0x014D), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 - QChar(0x0173), QChar(0x0142), QChar(0x015B), QChar(0x016B), QChar(0x00FC), QChar(0x017C), QChar(0x017E), QChar(0x02D9)}},// F8-FF - {"WINDOWS-1258", - // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF - {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0x0192), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 - QChar(0x02C6), QChar(0x2030), QChar(0xFFFD), QChar(0x2039), QChar(0x0152), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 88-8F - QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 - QChar(0x02DC), QChar(0x2122), QChar(0xFFFD), QChar(0x203A), QChar(0x0153), QChar(0xFFFD), QChar(0xFFFD), QChar(0x0178), // 98-9F - QChar(0x00A0), QChar(0x00A1), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 - QChar(0x00A8), QChar(0x00A9), QChar(0x00AA), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF - QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 - QChar(0x00B8), QChar(0x00B9), QChar(0x00BA), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00BF), // B8-BF - QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x0102), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x00C7), // C0-C7 - QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x0300), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF - QChar(0x0110), QChar(0x00D1), QChar(0x0309), QChar(0x00D3), QChar(0x00D4), QChar(0x01A0), QChar(0x00D6), QChar(0x00D7), // D0-D7 - QChar(0x00D8), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x01AF), QChar(0x0303), QChar(0x00DF), // D8-DF - QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x0103), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x00E7), // E0-E7 - QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x0301), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF - QChar(0x0111), QChar(0x00F1), QChar(0x0323), QChar(0x00F3), QChar(0x00F4), QChar(0x01A1), QChar(0x00F6), QChar(0x00F7), // F0=F7 - QChar(0x00F8), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x01B0), QChar(0x20AB), QChar(0x00FF)}}};// F8-FF -// clang-format on - -// a map of supported MXP elements and attributes -const QMap> TBuffer::mSupportedMxpElements = { - {QStringLiteral("send"), {"href", "hint", "prompt"}}, - {QStringLiteral("br"), {}}, - {QStringLiteral("a"), {"href", "hint"}} -}; - // Default constructor: TChar::TChar() : mFgColor(Qt::white) @@ -744,23 +120,11 @@ const QString timeStampFormat = QStringLiteral("hh:mm:ss.zzz "); const QString blankTimeStamp = QStringLiteral("------------ "); TBuffer::TBuffer(Host* pH) -: mLinkID(0) -, mLinesLimit(10000) +: mLinesLimit(10000) , mBatchDeleteSize(1000) , mWrapAt(99999999) , mWrapIndent(0) , mCursorY(0) -, mMXP(false) -, mMXP_MODE(MXP_MODE_OPEN) -, mMXP_DEFAULT(MXP_MODE_OPEN) -, mAssemblingToken(false) -, openT(0) -, closeT(0) -, mMXP_LINK_MODE(false) -, mIgnoreTag(false) -, mParsingVar(false) -, mOpenMainQuote() -, mMXP_SEND_NO_REF_MODE(false) , mEchoingText(false) , mGotESC(false) , mGotCSI(false) @@ -800,22 +164,10 @@ TBuffer::TBuffer(Host* pH) { clear(); - TMxpElement _element; - _element.name = "SEND"; - _element.href = ""; - _element.hint = ""; - mMXP_Elements["SEND"] = _element; - - TMxpElement _aURL; - _aURL.name = "A"; - _aURL.href = ""; - _aURL.hint = ""; - mMXP_Elements["A"] = _aURL; - #ifdef QT_DEBUG // Validate the encoding tables in case there has been an edit which breaks // things: - for (auto table : csmEncodingTable) { + for (auto table : csmEncodingTable.getEncodings()) { Q_ASSERT_X(table.size() == 128, "TBuffer", "Mis-sized encoding look-up table."); } #endif @@ -919,15 +271,12 @@ int TBuffer::getLastLineNumber() void TBuffer::addLink(bool trigMode, const QString& text, QStringList& command, QStringList& hint, TChar format) { - if (++mLinkID > scmMaxLinks) { - mLinkID = 1; - } - mLinkStore[mLinkID] = command; - mHintStore[mLinkID] = hint; + int id = mLinkStore.addLinks(command, hint); + if (!trigMode) { - append(text, 0, text.length(), format.mFgColor, format.mBgColor, format.mFlags, mLinkID); + append(text, 0, text.length(), format.mFgColor, format.mBgColor, format.mFlags, id); } else { - appendLine(text, 0, text.length(), format.mFgColor, format.mBgColor, format.mFlags, mLinkID); + appendLine(text, 0, text.length(), format.mFgColor, format.mBgColor, format.mFlags, id); } } @@ -1073,7 +422,7 @@ void TBuffer::translateToPlainText(std::string& incoming, const bool isFromServe encodingTableToUse = "CP869"; } - const QVector encodingLookupTable = csmEncodingTable.value(encodingTableToUse); + const QVector encodingLookupTable = csmEncodingTable.getLookupTable(encodingTableToUse); // If the encoding is "ASCII", "ISO 8859-1", "UTF-8", "GBK", "GB18030", // "BIG5" or "BIG5-HKSCS" (which are not in the table) encodingLookupTable // will be empty otherwise the 128 values in the returned table will be used @@ -1206,51 +555,8 @@ void TBuffer::translateToPlainText(std::string& incoming, const bool isFromServe if (!mpHost->mFORCE_MXP_NEGOTIATION_OFF && mpHost->mServerMXPenabled && isFromServer) { mGotCSI = false; - bool isOk = false; QString code = QString(localBuffer.substr(localBufferPosition, spanEnd - spanStart).c_str()); - int modeCode = code.toInt(&isOk); - if (isOk) { - // we really do not handle these well... - // MXP line modes - comments are from http://www.zuggsoft.com/zmud/mxp.htm#MXP%20Line%20Tags - mMXP = true; // some servers don't negotiate, they assume! - - switch (modeCode) { - case 0: // open line - only MXP commands in the "open" category are allowed. When a newline is received from the MUD, the mode reverts back to the Default mode. OPEN MODE starts as the Default mode until changes with one of the "lock mode" tags listed below. - mMXP_MODE = MXP_MODE_OPEN; - break; - case 1: // secure line (until next newline) all tags and commands in MXP are allowed within the line. When a newline is received from the MUD, the mode reverts back to the Default mode. - mMXP_MODE = MXP_MODE_SECURE; - break; - case 2: // locked line (until next newline) no MXP or HTML commands are allowed in the line. The line is not parsed for any tags at all. This is useful for "verbatim" text output from the MUD. When a newline is received from the MUD, the mode reverts back to the Default mode. - mMXP_MODE = MXP_MODE_LOCKED; - break; - case 3: // reset (MXP 0.4 or later) - close all open tags. Set mode to Open. Set text color and properties to default. - closeT = 0; - openT = 0; - mAssemblingToken = false; - mMXP_MODE = mMXP_DEFAULT; - currentToken.clear(); - mParsingVar = false; - break; - case 4: // temp secure mode (MXP 0.4 or later) - set secure mode for the next tag only. Must be immediately followed by a < character to start a tag. Remember to set secure mode when closing the tag also. - mMXP_MODE = MXP_MODE_TEMP_SECURE; - break; - case 5: // lock open mode (MXP 0.4 or later) - set open mode. Mode remains in effect until changed. OPEN mode becomes the new default mode. - mMXP_DEFAULT = mMXP_MODE = MXP_MODE_OPEN; - break; - case 6: // lock secure mode (MXP 0.4 or later) - set secure mode. Mode remains in effect until changed. Secure mode becomes the new default mode. - mMXP_DEFAULT = mMXP_MODE = MXP_MODE_SECURE; - break; - case 7: // lock locked mode (MXP 0.4 or later) - set locked mode. Mode remains in effect until changed. Locked mode becomes the new default mode. - mMXP_DEFAULT = mMXP_MODE = MXP_MODE_LOCKED; - break; - default: - qDebug().noquote().nospace() << "TBuffer::translateToPlainText(...) INFO - Unhandled MXP control sequence CSI " << code << " z received, Mudlet will ignore it."; - } - } else { - // isOk is false here as toInt(...) failed - qDebug().noquote().nospace() << "TBuffer::translateToPlainText(...) INFO - Non-numeric MXP control sequence CSI " << code << " z received, Mudlet will ignore it."; - } + mpHost->mMxpProcessor.setMode(code); } // end of if (!mpHost->mFORCE_MXP_NEGOTIATION_OFF) // We have manually disabled MXP negotiation @@ -1375,396 +681,32 @@ void TBuffer::translateToPlainText(std::string& incoming, const bool isFromServe // We are outside of a CSI or OSC sequence if we get to here: - if (mMXP && mpHost->mServerMXPenabled && (mMXP_MODE != MXP_MODE_LOCKED)) { - - // ignore < and > inside of parameter strings - if (openT == 1) { - if (ch == '\'' || ch == '\"') { - if (!mParsingVar) { - mOpenMainQuote = ch; - mParsingVar = true; - } else { - if (ch == mOpenMainQuote) { - mParsingVar = false; - } - } - } - } - - if (ch == '<') { - if (!mParsingVar) { - ++openT; - if (!currentToken.empty()) { - currentToken += ch; - } - mAssemblingToken = true; - ++localBufferPosition; - continue; - } - } - - if (ch == '>') { - if (!mParsingVar) { - ++closeT; - } - - // sanity check - if (closeT > openT) { - closeT = 0; - openT = 0; - mAssemblingToken = false; - currentToken.clear(); - mParsingVar = false; - } - - if ((openT > 0) && (closeT == openT)) { - mAssemblingToken = false; - // If we were in temp secure mode, then we switch back to default after the next tag - if (mMXP_MODE == MXP_MODE_TEMP_SECURE) { - mMXP_MODE = mMXP_DEFAULT; - } - std::string::size_type _pfs = currentToken.find_first_of(' '); - QString _tn; - if (_pfs == std::string::npos) { - _tn = currentToken.c_str(); - } else { - _tn = currentToken.substr(0, _pfs).c_str(); - } - _tn = _tn.toUpper(); - if (_tn == "VERSION") { - QString payload = QStringLiteral("\n\x1b[1z\n").arg(APP_VERSION, APP_BUILD); - mpHost->mTelnet.sendData(payload); - } else if (_tn == QLatin1String("SUPPORT")) { - auto response = processSupportsRequest(currentToken.c_str()); - QString payload = QStringLiteral("\n\x1b[1z\n").arg(response); - mpHost->mTelnet.sendData(payload); - } - if (_tn == "BR") { - // a
is a newline, but doesn't reset the MXP mode - ch = '\n'; - openT = 0; - closeT = 0; - currentToken.clear(); - goto COMMIT_LINE; // jump ahead of the part that resets MXP mode on newline - } - if (_tn.startsWith("!EL")) { - QString _tp = currentToken.substr(currentToken.find_first_of(' ')).c_str(); - _tn = _tp.section(' ', 1, 1).toUpper(); - _tp = _tp.section(' ', 2).toUpper(); - if ((_tp.indexOf(" pRef3)) || (_got_ref)) { - _ref = _t2.mid(pRef, pRef2 - pRef); - } - } else if (_ref.startsWith('\"')) { - int pRef3 = _t2.indexOf('\"', _t2.indexOf('\"', pRef) + 1); - int pRef4 = _t2.indexOf('='); - if (((pRef4 == -1) || (pRef4 != 0 && pRef4 > pRef3)) || (_got_ref)) { - _ref = _t2.mid(pRef, pRef2 - pRef); - } - } else if (_ref.startsWith('&')) { - _ref = _t2.mid(pRef, _t2.indexOf(' ', pRef + 1) - pRef); - } else { - _ref = ""; - } - _ref = _ref.replace(';', ""); - _ref = _ref.replace(""", ""); - _ref = _ref.replace("&", "&"); - _ref = _ref.replace('\'', ""); //NEU - _ref = _ref.replace('\"', ""); //NEU - _ref = _ref.replace(""", R"(")"); - - pRef = _t2.indexOf("HINT="); - QString _hint; - if (pRef != -1) { - pRef += 5; - int pRef2 = _t2.indexOf(' ', pRef); - _hint = _t2.mid(pRef, pRef2 - pRef); - if (_hint.startsWith('\'') || pRef2 < 0) { - pRef2 = _t2.indexOf('\'', _t2.indexOf('\'', pRef) + 1); - _hint = _t2.mid(pRef, pRef2 - pRef); - } else if (_hint.startsWith('\"') || pRef2 < 0) { - pRef2 = _t2.indexOf('\"', _t2.indexOf('\"', pRef) + 1); - _hint = _t2.mid(pRef, pRef2 - pRef); - } - _hint = _hint.replace(';', ""); - _hint = _hint.replace(""", ""); - _hint = _hint.replace("&", "&"); - _hint = _hint.replace('\'', ""); //NEU - _hint = _hint.replace('\"', ""); //NEU - _hint = _hint.replace(""", R"(")"); - } - TMxpElement _element; - _element.name = _tn; - _element.href = _ref; - _element.hint = _hint; - mMXP_Elements[_tn] = _element; - } - openT = 0; - closeT = 0; - currentToken.clear(); - ++localBufferPosition; + if (mpHost->mMxpProcessor.isEnabled()) { + if (mpHost->mServerMXPenabled) { + if (mpHost->mMxpProcessor.mode() != MXP_MODE_LOCKED) { + TMxpProcessingResult result = mpHost->mMxpProcessor.processMxpInput(ch); + if (result == HANDLER_NEXT_CHAR) { + localBufferPosition++; continue; + } else if (result == HANDLER_COMMIT_LINE) { // BR tag + ch = '\n'; + goto COMMIT_LINE; + } else { //HANDLER_FALL_THROUGH -> do nothing + assert(localBuffer[localBufferPosition] == ch); } - - - if (mMXP_LINK_MODE) { - if (_tn.indexOf('/') != -1) { - mMXP_LINK_MODE = false; - } - } - - if (mMXP_SEND_NO_REF_MODE) { - if (_tn.indexOf('/') != -1) { - mMXP_SEND_NO_REF_MODE = false; - if (mLinkStore[mLinkID].front() == "send([[]])") { - QString _t_ref = "send([["; - _t_ref.append(mAssembleRef.c_str()); - _t_ref.append("]])"); - QStringList _t_ref_list; - _t_ref_list << _t_ref; - mLinkStore[mLinkID] = _t_ref_list; - } else { - mLinkStore[mLinkID].replaceInStrings("&TEXT", mAssembleRef.c_str()); - } - mAssembleRef.clear(); - } - } else if (mMXP_Elements.contains(_tn)) { - QString _tp; - std::string::size_type _fs = currentToken.find_first_of(' '); - if (_fs != std::string::npos) { - _tp = currentToken.substr(_fs).c_str(); - } - QString _t1 = _tp.toUpper(); - const TMxpElement& _element = mMXP_Elements[_tn]; - QString _t2 = _element.href; - QString _t3 = _element.hint; - bool _userTag = true; - if (_t2.size() < 1) { - _userTag = false; - } - QRegularExpression _rex; - QStringList _rl1, _rl2; - int _ki1 = _tp.indexOf('\''); - int _ki2 = _tp.indexOf('\"'); - int _ki3 = _tp.indexOf('='); - // is the first parameter to send given in the form - // send "what" hint="bla" or send href="what" hint="bla" - - // handle the first case without a variable assignment - if ((_ki3 == -1) // no = whatsoever - || ((_ki3 != -1) && ((_ki2 < _ki3) || (_ki1 < _ki3)))) // first parameter is given without = - { - if ((_ki1 < _ki2 && _ki1 != -1) || (_ki2 == -1 && _ki1 != -1)) { - if (_ki1 < _ki3 || _ki3 == -1) { - _rl1 << "HREF"; - int _cki1 = _tp.indexOf('\'', _ki1 + 1); - if (_cki1 > -1) { - _rl2 << _tp.mid(_ki1 + 1, _cki1 - (_ki1 + 1)); - } - } - } else if ((_ki2 < _ki1 && _ki2 != -1) || (_ki1 == -1 && _ki2 != -1)) { - if (_ki2 < _ki3 || _ki3 == -1) { - _rl1 << "HREF"; - int _cki2 = _tp.indexOf('\"', _ki2 + 1); - if (_cki2 > -1) { - _rl2 << _tp.mid(_ki2 + 1, _cki2 - (_ki2 + 1)); - } - } - } - } - // parse parameters in the form var="val" or var='val' where val can be given in the form "foo'b'ar" or 'foo"b"ar' - if (_tp.contains(QStringLiteral(R"(=')"))) { - _rex = QRegularExpression(QStringLiteral(R"(\b(\w+)=\'([^\']*) ?)")); - } else { - _rex = QRegularExpression(QStringLiteral(R"(\b(\w+)=\"([^\"]*) ?)")); - } - - int _rpos = 0; - QRegularExpressionMatch match = _rex.match(_tp, _rpos); - while ((_rpos = match.capturedStart()) != -1) { - _rl1 << match.captured(1).toUpper(); - _rl2 << match.captured(2); - _rpos += match.capturedLength(); - - match = _rex.match(_tp, _rpos); - } - - QMap mxp_attrs; - if ((_rl1.size() == _rl2.size()) && (!_rl1.empty())) { - for (int i = 0; i < _rl1.size(); i++) { - QString _var = _rl1[i]; - mxp_attrs[_var] = _rl2[i]; - _var.prepend('&'); - if (_userTag || _t2.indexOf(_var) != -1) { - _t2 = _t2.replace(_var, _rl2[i]); - _t3 = _t3.replace(_var, _rl2[i]); - } else { - if (_rl1[i] == QStringLiteral("HREF")) { - _t2 = _rl2[i]; - } - if (_rl1[i] == QStringLiteral("HINT")) { - _t3 = _rl2[i]; - } - } - } - } - - // handle print to prompt feature PROMPT - bool _send_to_command_line = false; - if (_t1.endsWith("PROMPT")) { - _send_to_command_line = true; - } - - - mMXP_LINK_MODE = true; - if (_t2.isEmpty() || _t2.contains("&TEXT")) { - mMXP_SEND_NO_REF_MODE = true; - } - mLinkID++; - if (mLinkID > scmMaxLinks) { - mLinkID = 1; - } - QStringList _tl = _t2.split('|'); - for (int i = 0, total = _tl.size(); i < total; ++i) { - _tl[i].replace("|", ""); - if (_element.name == "A") { - _tl[i] = "openUrl([[" + _tl[i] + "]])"; - } else if (!_send_to_command_line) { - _tl[i] = "send([[" + _tl[i] + "]])"; - } else { - _tl[i] = "printCmdLine([[" + _tl[i] + "]])"; - } - } - - mMxpEvents.enqueue(MxpEvent(_element.name, mxp_attrs, _tl)); - - mLinkStore[mLinkID] = _tl; - - _t3 = _t3.replace(""", R"(")"); - _t3 = _t3.replace("&", "&"); - _t3 = _t3.replace("'", "'"); - _t3 = _t3.replace(""", R"(")"); - - QStringList _tl2 = _t3.split('|'); - _tl2.replaceInStrings("|", ""); - if (_tl2.size() >= _tl.size() + 1) { - _tl2.pop_front(); - } - mHintStore[mLinkID] = _tl2; - } - openT = 0; - closeT = 0; - currentToken.clear(); - } - ++localBufferPosition; - continue; - } - - if (mAssemblingToken) { - if (ch == '\n') { - closeT = 0; - openT = 0; - mAssemblingToken = false; - currentToken.clear(); - mParsingVar = false; } else { - currentToken += ch; - ++localBufferPosition; - continue; + mpHost->mMxpProcessor.processRawInput(ch); } } - if (ch == '&' || mIgnoreTag) { - if ((localBufferPosition + 4 < localBufferLength) && (mSkip.empty())) { - if (localBuffer.substr(localBufferPosition, 4) == ">") { - localBufferPosition += 3; - ch = '>'; - mIgnoreTag = false; - } else if (localBuffer.substr(localBufferPosition, 4) == "<") { - localBufferPosition += 3; - ch = '<'; - mIgnoreTag = false; - } else if (localBuffer.substr(localBufferPosition, 5) == "&") { - mIgnoreTag = false; - localBufferPosition += 4; - ch = '&'; - } else if (localBuffer.substr(localBufferPosition, 6) == """) { - localBufferPosition += 5; - mIgnoreTag = false; - mSkip.clear(); - ch = '"'; - } - } else if (mSkip == ">" && ch == ';') { // if the content is split across package borders - mIgnoreTag = false; - mSkip.clear(); - ch = '>'; - } else if (mSkip == "<" && ch == ';') { - mIgnoreTag = false; - mSkip.clear(); - ch = '<'; - } else if (mSkip == "&" && ch == ';') { - mIgnoreTag = false; - mSkip.clear(); - ch = '&'; - } else if (mSkip == """ && ch == ';') { - mIgnoreTag = false; - mSkip.clear(); - ch = '"'; - } else { - mIgnoreTag = true; - mSkip += ch; - // sanity check - if (mSkip.size() > 7) { - mIgnoreTag = false; - mSkip.clear(); - } - ++localBufferPosition; - continue; - } + if (CHAR_IS_COMMIT_CHAR(ch)) { + // after a newline (but not a
) return to default mode + mpHost->mMxpProcessor.resetToDefaultMode(); } } - - if (mMXP_SEND_NO_REF_MODE) { - mAssembleRef += ch; - } - - if (mMXP && ((ch == '\n') || (ch == '\xff') || (ch == '\r'))) { - // after a newline (but not a
) return to default mode - mMXP_MODE = mMXP_DEFAULT; - } - COMMIT_LINE: - if ((ch == '\n') || (ch == '\xff') || (ch == '\r')) { + if (CHAR_IS_COMMIT_CHAR(ch)) { // DE: MUD Zeilen werden immer am Zeilenanfang geschrieben // EN: MUD lines are always written at the beginning of the line @@ -1899,11 +841,19 @@ void TBuffer::translateToPlainText(std::string& incoming, const bool isFromServe TChar c((!mIsDefaultColor && mBold) ? mForeGroundColorLight : mForeGroundColor, mBackGroundColor, attributeFlags); - if (mMXP_LINK_MODE) { - c.mLinkIndex = mLinkID; + if (mpHost->mMxpClient.isInLinkMode()) { + c.mLinkIndex = mLinkStore.getCurrentLinkID(); c.mFlags |= TChar::Underline; } + if (mpHost->mMxpClient.hasFgColor()) { + c.mFgColor = mpHost->mMxpClient.getFgColor(); + } + + if (mpHost->mMxpClient.hasBgColor()) { + c.mBgColor = mpHost->mMxpClient.getBgColor(); + } + if (isTwoTCharsNeeded) { // CHECK: Do we need to duplicate stuff for mMXP_LINK_MODE - yes I think we do: mMudBuffer.push_back(c); @@ -4054,13 +3004,7 @@ bool TBuffer::applyLink(const QPoint& P_begin, const QPoint& P_end, const QStrin } if (!incLinkID) { incLinkID = true; - mLinkID++; - linkID = mLinkID; - if (mLinkID > scmMaxLinks) { - mLinkID = 1; - } - mLinkStore[mLinkID] = linkFunction; - mHintStore[mLinkID] = linkHint; + mLinkStore.addLinks(linkFunction, linkHint); } buffer.at(y).at(x++).mLinkIndex = linkID; } @@ -5166,74 +4110,6 @@ void TBuffer::encodingChanged(const QByteArray& newEncoding) } } -QString TBuffer::processSupportsRequest(const QString& elements) -{ - // strip initial SUPPORT and tokenize all of the requested elements - auto elementsList = elements.trimmed().remove(0, 7).split(QStringLiteral(" "), QString::SkipEmptyParts); - QStringList result; - - auto reportEntireElement = [](auto element, auto& result) { - result.append("+" + element); - - for (const auto& attribute : mSupportedMxpElements.value(element)) { - result.append("+" + element + QStringLiteral(".") + attribute); - } - - return result; - }; - - auto reportAllElements = [reportEntireElement](auto& result) { - auto elementsIterator = mSupportedMxpElements.constBegin(); - while (elementsIterator != mSupportedMxpElements.constEnd()) { - result = reportEntireElement(elementsIterator.key(), result); - ++elementsIterator; - } - - return result; - }; - - // empty - report all known elements - if (elementsList.isEmpty()) { - result = reportAllElements(result); - } else { - // otherwise it's - for (auto& element : elementsList) { - // prune any enclosing quotes - if (element.startsWith(QChar('"'))) { - element = element.remove(0, 1); - } - if (element.endsWith(QChar('"'))) { - element.chop(1); - } - - if (!element.contains(QChar('.'))) { - if (mSupportedMxpElements.contains(element)) { - result = reportEntireElement(element, result); - } else { - result.append("-" + element); - } - } else { - auto elementName = element.section(QChar('.'), 0, 0); - auto attributeName = element.section(QChar('.'), 1, 1); - - if (!mSupportedMxpElements.contains(elementName)) { - result.append("-" + element); - } else if (attributeName == QLatin1String("*")) { - result = reportEntireElement(elementName, result); - } else { - if (mSupportedMxpElements.value(elementName).contains(attributeName)) { - result.append("+" + element + "." + attributeName); - } else { - result.append("-" + element + "." + attributeName); - } - } - } - } - } - - return result.join(QLatin1String(" ")); -} - // Count the graphemes in a QString - returning its length in terms of those: int TBuffer::lengthInGraphemes(const QString& text) { @@ -5253,46 +4129,5 @@ int TBuffer::lengthInGraphemes(const QString& text) const QList TBuffer::getEncodingNames() { - static QByteArrayList results; - if (results.isEmpty()) { - // First call, list is empty - so work them out, just this once: - results = QByteArrayList{csmEncodingTable.keys()}; - - QMutableByteArrayListIterator itEncoding(results); - while (itEncoding.hasNext()) { - QByteArray encoding{itEncoding.next()}; - QTextCodec* pEncoding = QTextCodec::codecForName(encoding); - if (!pEncoding) { - // We do not have that encoder available after all - itEncoding.remove(); - if (encoding == "CP437") { - // Okay to insert our replacement TTextCodex_XXXX into the - // system we must instantiate them once: - auto* pTTextCodec_437 = new TTextCodec_437(); - // Now that it has been instantiated, the system knows about - // it - indeed it takes possession of it and we must NOT - // delete it ourselves! - if (pTTextCodec_437) { - itEncoding.insert(pTTextCodec_437->name()); - } - } else if (encoding == "CP667") { - auto* pTTextCodec_667 = new TTextCodec_667(); - if (pTTextCodec_667) { - itEncoding.insert(pTTextCodec_667->name()); - } - } else if (encoding == "CP737") { - auto* pTTextCodec_737 = new TTextCodec_737(); - if (pTTextCodec_737) { - itEncoding.insert(pTTextCodec_737->name()); - } - } else if (encoding == "CP869") { - auto* pTTextCodec_869 = new TTextCodec_869(); - if (pTTextCodec_869) { - itEncoding.insert(pTTextCodec_869->name()); - } - } - } - } - } - return results; + return csmEncodingTable.getEncodingNames(); } diff --git a/src/TBuffer.h b/src/TBuffer.h index 687d2a68e73..c87ec2b705a 100644 --- a/src/TBuffer.h +++ b/src/TBuffer.h @@ -41,6 +41,10 @@ #include #include #include "post_guard.h" +#include "TEncodingTable.h" +#include "TLinkStore.h" +#include "TMxpMudlet.h" +#include "TMxpProcessor.h" #include #include @@ -117,38 +121,12 @@ class TChar }; Q_DECLARE_OPERATORS_FOR_FLAGS(TChar::AttributeFlags) -struct TMxpElement -{ - QString name; - QString href; - QString hint; -}; - -enum TMXPMode -{ - MXP_MODE_OPEN, - MXP_MODE_SECURE, - MXP_MODE_LOCKED, - MXP_MODE_TEMP_SECURE -}; - -struct MxpEvent { - QString name; - QMap attrs; - QStringList actions; - MxpEvent(QString name, QMap attrs, QStringList actions) - : name(name), attrs(attrs), actions(actions) - {} -}; -class TBuffer { - // private - a map of computer-friendly encoding names as keys, - // value is the encoding data. - // Look to mudlet::mEncodingNameTable for the GUI "human" names for the keys: - static const QMap> csmEncodingTable; - static const QMap> mSupportedMxpElements; +class TBuffer +{ + inline static const TEncodingTable &csmEncodingTable = TEncodingTable::csmDefaultInstance; inline static const int TCHAR_IN_BYTES = sizeof(TChar); @@ -205,16 +183,13 @@ class TBuffer { void encodingChanged(const QByteArray &); static int lengthInGraphemes(const QString& text); - QQueue mMxpEvents; std::deque bufferLine; std::deque> buffer; QStringList timeBuffer; QStringList lineBuffer; QList promptBuffer; - QMap mLinkStore; - QMap mHintStore; - int mLinkID; + TLinkStore mLinkStore; int mLinesLimit; int mBatchDeleteSize; int mWrapAt; @@ -222,54 +197,8 @@ class TBuffer { int mCursorY; - /* - * The documentation at https://www.zuggsoft.com/zmud/mxp.htm says: " - * * 0 - OPEN LINE - initial default mode: only MXP commands in the 'open' - * category are allowed. When a newline is received from the MUD, the - * mode reverts back to the Default mode. OPEN mode starts as the - * default mode until changes with one of the 'lock mode' tags listed - * below. - * * 1 - SECURE LINE (until next newline) all tags and commands in MXP are - * allowed within the line. When a newline is received from the MUD, - * the mode reverts back to the Default mode. - * * 2 - LOCKED LINE (until next newline) no MXP or HTML commands are - * allowed in the line. The line is not parsed for any tags at all. - * This is useful for "verbatim" text output from the MUD. When a - * newline is received from the MUD, the mode reverts back to the - * Default mode. - * The following additional modes were added to the v0.4 MXP spec: - * * 3 - RESET close all open tags. Set mode to Open. Set text color and - * properties to default. - * * 4 - TEMP SECURE MODE set secure mode for the next tag only. Must be - * immediately followed by a < character to start a tag. Remember to - * set secure mode when closing the tag also. - * * 5 - LOCK OPEN MODE set open mode. Mode remains in effect until - * changed. OPEN mode becomes the new default mode. - * * 6 - LOCK SECURE MODE set secure mode. Mode remains in effect until - * changed. Secure mode becomes the new default mode. - * * 7 - LOCK LOCKED MODE set locked mode. Mode remains in effect until - * changed. Locked mode becomes the new default mode." - */ // State of MXP systen: - bool mMXP; - TMXPMode mMXP_MODE; - TMXPMode mMXP_DEFAULT; - - bool mAssemblingToken; - std::string currentToken; - int openT; - int closeT; - - QMap mMXP_Elements; - - bool mMXP_LINK_MODE; - bool mIgnoreTag; - std::string mSkip; - bool mParsingVar; - char mOpenMainQuote; - bool mMXP_SEND_NO_REF_MODE; - std::string mAssembleRef; bool mEchoingText; @@ -280,14 +209,12 @@ class TBuffer { bool processUtf8Sequence(const std::string&, bool, size_t, size_t&, bool&); bool processGBSequence(const std::string&, bool, bool, size_t, size_t&, bool&); bool processBig5Sequence(const std::string&, bool, size_t, size_t&, bool&); - QString processSupportsRequest(const QString& attributes); void decodeSGR(const QString&); void decodeSGR38(const QStringList&, bool isColonSeparated = true); void decodeSGR48(const QStringList&, bool isColonSeparated = true); void decodeOSC(const QString&); void resetColors(); - static const int scmMaxLinks = 2000; // First stage in decoding SGR/OCS sequences - set true when we see the // ASCII ESC character: diff --git a/src/TConsole.cpp b/src/TConsole.cpp index 228d118022e..c1d0b533394 100644 --- a/src/TConsole.cpp +++ b/src/TConsole.cpp @@ -1245,8 +1245,11 @@ void TConsole::printOnDisplay(std::string& incomingSocketData, const bool isFrom buffer.translateToPlainText(incomingSocketData, isFromServer); mTriggerEngineMode = false; - while (!buffer.mMxpEvents.isEmpty()) { - const MxpEvent &event = buffer.mMxpEvents.dequeue(); + // dequeues MXP events and raise them through the LuaInterpreter + // TODO: move this somewhere else more appropriate + auto &mxpEventQueue = mpHost->mMxpClient.mMxpEvents; + while (!mxpEventQueue.isEmpty()) { + const auto& event = mxpEventQueue.dequeue(); mpHost->mLuaInterpreter.signalMXPEvent(event.name, event.attrs, event.actions); } diff --git a/src/TConsole.h b/src/TConsole.h index 8903dfb8363..b5abe23e7dc 100644 --- a/src/TConsole.h +++ b/src/TConsole.h @@ -122,6 +122,7 @@ class TConsole : public QWidget buffer.setWrapIndent(count); } + TLinkStore &getLinkStore() { return buffer.mLinkStore; } void echo(const QString&); bool moveCursor(int x, int y); int select(const QString&, int numOfMatch = 1); diff --git a/src/TEncodingTable.cpp b/src/TEncodingTable.cpp new file mode 100644 index 00000000000..cf2520aed31 --- /dev/null +++ b/src/TEncodingTable.cpp @@ -0,0 +1,698 @@ +/*************************************************************************** + * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * + * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * + * Copyright (C) 2014-2018 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +#include "TEncodingTable.h" +#include "TTextCodec.h" + +const TEncodingTable TEncodingTable::csmDefaultInstance = TEncodingTable(csmEncodings); + +QList TEncodingTable::getEncodingNames() const +{ + static QByteArrayList results; + if (results.isEmpty()) { + // First call, list is empty - so work them out, just this once: + results = QByteArrayList{mEncodingMap.keys()}; + + QMutableByteArrayListIterator itEncoding(results); + while (itEncoding.hasNext()) { + QByteArray encoding{itEncoding.next()}; + QTextCodec* pEncoding = QTextCodec::codecForName(encoding); + if (!pEncoding) { + // We do not have that encoder available after all + itEncoding.remove(); + if (encoding == "CP437") { + // Okay to insert our replacement TTextCodex_XXXX into the + // system we must instantiate them once: + auto* pTTextCodec_437 = new TTextCodec_437(); + // Now that it has been instantiated, the system knows about + // it - indeed it takes possession of it and we must NOT + // delete it ourselves! + if (pTTextCodec_437) { + itEncoding.insert(pTTextCodec_437->name()); + } + } else if (encoding == "CP667") { + auto* pTTextCodec_667 = new TTextCodec_667(); + if (pTTextCodec_667) { + itEncoding.insert(pTTextCodec_667->name()); + } + } else if (encoding == "CP737") { + auto* pTTextCodec_737 = new TTextCodec_737(); + if (pTTextCodec_737) { + itEncoding.insert(pTTextCodec_737->name()); + } + } else if (encoding == "CP869") { + auto* pTTextCodec_869 = new TTextCodec_869(); + if (pTTextCodec_869) { + itEncoding.insert(pTTextCodec_869->name()); + } + } + } + } + } + return results; +} + +const QVector& TEncodingTable::getLookupTable(const QByteArray& encoding) const +{ + const auto ptr = mEncodingMap.find(encoding); + return ptr != mEncodingMap.end() ? ptr.value() : csmEmptyLookupTable; +} + + +// These tables have been regenerated from examination of the Qt source code +// particularly from: +// https://gitorious.org/qt/qt?p=qt:qt.git;a=blob;f=src/corelib/codecs/qsimplecodec.cpp;h=cb52ce35f369f7fbe5b04ff2c2cf1600bd794f4e;hb=HEAD +// It represents the Unicode codepoints that are to be used to represent +// extended ASCII characters with the MS Bit set. The name is one that will +// be recognized as a valid encoding name to supply to: +// QTextCodec::codecForName(...) +// "ISO 885901" is not included here as it is inherent in Qt and has a straight +// one for one mapping of characters in the range 128 to 255 to the +// corresponding Unicode codepoint. +// Note that the codepoint 0xFFFD is the Unicode replacement character and +// is reserved to show, amongst other things, where a UTF-8 sequence of bytes +// is not a known character or, in these tables, the fact that no character was +// defined at that Extended ASCII character code. + +// a map of computer-friendly encoding names as keys +// values are a pair of human-friendly name + encoding data + +// clang-format off +// Do not let code reformatting tool mess this around! +// PLACEMARKER: Extended ASCII decoder Unicode codepoint lookup tables +const QMap> TEncodingTable::csmEncodings = { + {"ISO 8859-2", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0x0104), QChar(0x02D8), QChar(0x0141), QChar(0x00A4), QChar(0x013D), QChar(0x015A), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x0160), QChar(0x015E), QChar(0x0164), QChar(0x0179), QChar(0x00AD), QChar(0x017D), QChar(0x017B), // A8-AF + QChar(0x00B0), QChar(0x0105), QChar(0x02DB), QChar(0x0142), QChar(0x00B4), QChar(0x013E), QChar(0x015B), QChar(0x02C7), // B0-B7 + QChar(0x00B8), QChar(0x0161), QChar(0x015F), QChar(0x0165), QChar(0x017A), QChar(0x02DD), QChar(0x017E), QChar(0x017C), // B8-BF + QChar(0x0154), QChar(0x00C1), QChar(0x00C2), QChar(0x0102), QChar(0x00C4), QChar(0x0139), QChar(0x0106), QChar(0x00C7), // C0-C7 + QChar(0x010C), QChar(0x00C9), QChar(0x0118), QChar(0x00CB), QChar(0x011A), QChar(0x00CD), QChar(0x00CE), QChar(0x010E), // C8-CF + QChar(0x0110), QChar(0x0143), QChar(0x0147), QChar(0x00D3), QChar(0x00D4), QChar(0x0150), QChar(0x00D6), QChar(0x00D7), // D0-D7 + QChar(0x0158), QChar(0x016E), QChar(0x00DA), QChar(0x0170), QChar(0x00DC), QChar(0x00DD), QChar(0x0162), QChar(0x00DF), // D8-DF + QChar(0x0155), QChar(0x00E1), QChar(0x00E2), QChar(0x0103), QChar(0x00E4), QChar(0x013A), QChar(0x0107), QChar(0x00E7), // E0-E7 + QChar(0x010D), QChar(0x00E9), QChar(0x0119), QChar(0x00EB), QChar(0x011B), QChar(0x00ED), QChar(0x00EE), QChar(0x010F), // E8-EF + QChar(0x0111), QChar(0x0144), QChar(0x0148), QChar(0x00F3), QChar(0x00F4), QChar(0x0151), QChar(0x00F6), QChar(0x00F7), // F0=F7 + QChar(0x0159), QChar(0x016F), QChar(0x00FA), QChar(0x0171), QChar(0x00FC), QChar(0x00FD), QChar(0x0163), QChar(0x02D9)}}, // F8-FF + {"ISO 8859-3", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0x0126), QChar(0x02D8), QChar(0x00A3), QChar(0x00A4), QChar(0xFFFD), QChar(0x0124), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x0130), QChar(0x015E), QChar(0x011E), QChar(0x0134), QChar(0x00AD), QChar(0xFFFD), QChar(0x017B), // A8-AF + QChar(0x00B0), QChar(0x0127), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x0125), QChar(0x00B7), // B0-B7 + QChar(0x00B8), QChar(0x0131), QChar(0x015F), QChar(0x011F), QChar(0x0135), QChar(0x00BD), QChar(0xFFFD), QChar(0x017C), // B8-BF + QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0xFFFD), QChar(0x00C4), QChar(0x010A), QChar(0x0108), QChar(0x00C7), // C0-C7 + QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF + QChar(0xFFFD), QChar(0x00D1), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x0120), QChar(0x00D6), QChar(0x00D7), // D0-D7 + QChar(0x011C), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x016C), QChar(0x015C), QChar(0x00DF), // D8-DF + QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0xFFFD), QChar(0x00E4), QChar(0x010B), QChar(0x0109), QChar(0x00E7), // E0-E7 + QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF + QChar(0xFFFD), QChar(0x00F1), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x0121), QChar(0x00F6), QChar(0x00F7), // F0=F7 + QChar(0x011D), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x016D), QChar(0x015D), QChar(0x02D9)}},// F8-FF + {"ISO 8859-4", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0x0104), QChar(0x0138), QChar(0x0156), QChar(0x00A4), QChar(0x0128), QChar(0x013B), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x0160), QChar(0x0112), QChar(0x0122), QChar(0x0166), QChar(0x00AD), QChar(0x017D), QChar(0x00AF), // A8-AF + QChar(0x00B0), QChar(0x0105), QChar(0x02DB), QChar(0x0157), QChar(0x00B4), QChar(0x0129), QChar(0x013C), QChar(0x02C7), // B0-B7 + QChar(0x00B8), QChar(0x0161), QChar(0x0113), QChar(0x0123), QChar(0x0167), QChar(0x014A), QChar(0x017E), QChar(0x014B), // B8-BF + QChar(0x0100), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x012E), // C0-C7 + QChar(0x010C), QChar(0x00C9), QChar(0x0118), QChar(0x00CB), QChar(0x0116), QChar(0x00CD), QChar(0x00CE), QChar(0x012A), // C8-CF + QChar(0x0110), QChar(0x0145), QChar(0x014C), QChar(0x0136), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 + QChar(0x00D8), QChar(0x0172), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x0168), QChar(0x016A), QChar(0x00DF), // D8-DF + QChar(0x0101), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x012F), // E0-E7 + QChar(0x010D), QChar(0x00E9), QChar(0x0119), QChar(0x00EB), QChar(0x0117), QChar(0x00ED), QChar(0x00EE), QChar(0x012B), // E8-EF + QChar(0x0111), QChar(0x0146), QChar(0x014D), QChar(0x0137), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 + QChar(0x00F8), QChar(0x0173), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x0169), QChar(0x016B), QChar(0x02D9)}},// F8-FF + {"ISO 8859-5", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0x0401), QChar(0x0402), QChar(0x0403), QChar(0x0404), QChar(0x0405), QChar(0x0406), QChar(0x0407), // A0-A7 + QChar(0x0408), QChar(0x0409), QChar(0x040A), QChar(0x040B), QChar(0x040C), QChar(0x00AD), QChar(0x040E), QChar(0x040F), // A8-AF + QChar(0x0410), QChar(0x0411), QChar(0x0412), QChar(0x0413), QChar(0x0414), QChar(0x0415), QChar(0x0416), QChar(0x0417), // B0-B7 + QChar(0x0418), QChar(0x0419), QChar(0x041A), QChar(0x041B), QChar(0x041C), QChar(0x041D), QChar(0x041E), QChar(0x041F), // B8-BF + QChar(0x0420), QChar(0x0421), QChar(0x0422), QChar(0x0423), QChar(0x0424), QChar(0x0425), QChar(0x0426), QChar(0x0427), // C0-C7 + QChar(0x0428), QChar(0x0429), QChar(0x042A), QChar(0x042B), QChar(0x042C), QChar(0x042D), QChar(0x042E), QChar(0x042F), // C8-CF + QChar(0x0430), QChar(0x0431), QChar(0x0432), QChar(0x0433), QChar(0x0434), QChar(0x0435), QChar(0x0436), QChar(0x0437), // D0-D7 + QChar(0x0438), QChar(0x0439), QChar(0x043A), QChar(0x043B), QChar(0x043C), QChar(0x043D), QChar(0x043E), QChar(0x043F), // D8-DF + QChar(0x0440), QChar(0x0441), QChar(0x0442), QChar(0x0443), QChar(0x0444), QChar(0x0445), QChar(0x0446), QChar(0x0447), // E0-E7 + QChar(0x0448), QChar(0x0449), QChar(0x044A), QChar(0x044B), QChar(0x044C), QChar(0x044D), QChar(0x044E), QChar(0x044F), // E8-EF + QChar(0x2116), QChar(0x0451), QChar(0x0452), QChar(0x0453), QChar(0x0454), QChar(0x0455), QChar(0x0456), QChar(0x0457), // F0=F7 + QChar(0x0458), QChar(0x0459), QChar(0x045A), QChar(0x045B), QChar(0x045C), QChar(0x00A7), QChar(0x045E), QChar(0x045F)}},// F8-FF + {"ISO 8859-6", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x00A4), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // A0-A7 + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x060C), QChar(0x00AD), QChar(0xFFFD), QChar(0xFFFD), // A8-AF + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // B0-B7 + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x061B), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x061F), // B8-BF + QChar(0xFFFD), QChar(0x0621), QChar(0x0622), QChar(0x0623), QChar(0x0624), QChar(0x0625), QChar(0x0626), QChar(0x0627), // C0-C7 + QChar(0x0628), QChar(0x0629), QChar(0x062A), QChar(0x062B), QChar(0x062C), QChar(0x062D), QChar(0x062E), QChar(0x062F), // C8-CF + QChar(0x0630), QChar(0x0631), QChar(0x0632), QChar(0x0633), QChar(0x0634), QChar(0x0635), QChar(0x0636), QChar(0x0637), // D0-D7 + QChar(0x0638), QChar(0x0639), QChar(0x063A), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // D8-DF + QChar(0x0640), QChar(0x0641), QChar(0x0642), QChar(0x0643), QChar(0x0644), QChar(0x0645), QChar(0x0646), QChar(0x0647), // E0-E7 + QChar(0x0648), QChar(0x0649), QChar(0x064A), QChar(0x064B), QChar(0x064C), QChar(0x064D), QChar(0x064E), QChar(0x064F), // E8-EF + QChar(0x0650), QChar(0x0651), QChar(0x0652), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // F0=F7 + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD)}},// F8-FF + {"ISO 8859-7", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0x2018), QChar(0x2019), QChar(0x00A3), QChar(0xFFFD), QChar(0xFFFD), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x00A9), QChar(0xFFFD), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0xFFFD), QChar(0x2015), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x0384), QChar(0x0385), QChar(0x0386), QChar(0x00B7), // B0-B7 + QChar(0x0388), QChar(0x0389), QChar(0x038A), QChar(0x00BB), QChar(0x038C), QChar(0x00BD), QChar(0x038E), QChar(0x038F), // B8-BF + QChar(0x0390), QChar(0x0391), QChar(0x0392), QChar(0x0393), QChar(0x0394), QChar(0x0395), QChar(0x0396), QChar(0x0397), // C0-C7 + QChar(0x0398), QChar(0x0399), QChar(0x039A), QChar(0x039B), QChar(0x039C), QChar(0x039D), QChar(0x039E), QChar(0x039F), // C8-CF + QChar(0x03A0), QChar(0x03A1), QChar(0xFFFD), QChar(0x03A3), QChar(0x03A4), QChar(0x03A5), QChar(0x03A6), QChar(0x03A7), // D0-D7 + QChar(0x03A8), QChar(0x03A9), QChar(0x03AA), QChar(0x03AB), QChar(0x03AC), QChar(0x03AD), QChar(0x03AE), QChar(0x03AF), // D8-DF + QChar(0x03B0), QChar(0x03B1), QChar(0x03B2), QChar(0x03B3), QChar(0x03B4), QChar(0x03B5), QChar(0x03B6), QChar(0x03B7), // E0-E7 + QChar(0x03B8), QChar(0x03B9), QChar(0x03BA), QChar(0x03BB), QChar(0x03BC), QChar(0x03BD), QChar(0x03BE), QChar(0x03BF), // E8-EF + QChar(0x03C0), QChar(0x03C1), QChar(0x03C2), QChar(0x03C3), QChar(0x03C4), QChar(0x03C5), QChar(0x03C6), QChar(0x03C7), // F0=F7 + QChar(0x03C8), QChar(0x03C9), QChar(0x03CA), QChar(0x03CB), QChar(0x03CC), QChar(0x03CD), QChar(0x03CE), QChar(0xFFFD)}},// F8-FF + {"ISO 8859-8", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0xFFFD), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x00A9), QChar(0x00D7), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x203E), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x00B8), QChar(0x00B9), QChar(0x00F7), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0xFFFD), // B8-BF + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // C0-C7 + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // C8-CF + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // D0-D7 + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x2017), // D8-DF + QChar(0x05D0), QChar(0x05D1), QChar(0x05D2), QChar(0x05D3), QChar(0x05D4), QChar(0x05D5), QChar(0x05D6), QChar(0x05D7), // E0-E7 + QChar(0x05D8), QChar(0x05D9), QChar(0x05DA), QChar(0x05DB), QChar(0x05DC), QChar(0x05DD), QChar(0x05DE), QChar(0x05DF), // E8-EF + QChar(0x05E0), QChar(0x05E1), QChar(0x05E2), QChar(0x05E3), QChar(0x05E4), QChar(0x05E5), QChar(0x05E6), QChar(0x05E7), // F0=F7 + QChar(0x05E8), QChar(0x05E9), QChar(0x05EA), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD)}},// F8-FF + {"ISO 8859-9", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0x00A1), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x00A9), QChar(0x00AA), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x00B8), QChar(0x00B9), QChar(0x00BA), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00BF), // B8-BF + QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x00C7), // C0-C7 + QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF + QChar(0x011E), QChar(0x00D1), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 + QChar(0x00D8), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x0130), QChar(0x015E), QChar(0x00DF), // D8-DF + QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x00E7), // E0-E7 + QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF + QChar(0x011F), QChar(0x00F1), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 + QChar(0x00F8), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x0131), QChar(0x015F), QChar(0x00FF)}},// F8-FF + {"ISO 8859-10", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0x0104), QChar(0x0112), QChar(0x0122), QChar(0x012A), QChar(0x0128), QChar(0x0136), QChar(0x00A7), // A0-A7 + QChar(0x013B), QChar(0x0110), QChar(0x0160), QChar(0x0166), QChar(0x017D), QChar(0x00AD), QChar(0x016A), QChar(0x014A), // A8-AF + QChar(0x00B0), QChar(0x0105), QChar(0x0113), QChar(0x0123), QChar(0x012B), QChar(0x0129), QChar(0x0137), QChar(0x00B7), // B0-B7 + QChar(0x013C), QChar(0x0111), QChar(0x0161), QChar(0x0167), QChar(0x017E), QChar(0x2015), QChar(0x016B), QChar(0x014B), // B8-BF + QChar(0x0100), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x012E), // C0-C7 + QChar(0x010C), QChar(0x00C9), QChar(0x0118), QChar(0x00CB), QChar(0x0116), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF + QChar(0x00D0), QChar(0x0145), QChar(0x014C), QChar(0x00D3), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x0168), // D0-D7 + QChar(0x00D8), QChar(0x0172), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x00DD), QChar(0x00DE), QChar(0x00DF), // D8-DF + QChar(0x0101), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x012F), // E0-E7 + QChar(0x010D), QChar(0x00E9), QChar(0x0119), QChar(0x00EB), QChar(0x0117), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF + QChar(0x00F0), QChar(0x0146), QChar(0x014D), QChar(0x00F3), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x0169), // F0=F7 + QChar(0x00F8), QChar(0x0173), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x00FD), QChar(0x00FE), QChar(0x0138)}},// F8-FF + {"ISO 8859-11", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 80-87 + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 88-8F + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 90-97 + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 98-9F + QChar(0x00A0), QChar(0x0E01), QChar(0x0E02), QChar(0x0E03), QChar(0x0E04), QChar(0x0E05), QChar(0x0E06), QChar(0x0E07), // A0-A7 + QChar(0x0E08), QChar(0x0E09), QChar(0x0E0A), QChar(0x0E0B), QChar(0x0E0C), QChar(0x0E0D), QChar(0x0E0E), QChar(0x0E0F), // A8-AF + QChar(0x0E10), QChar(0x0E11), QChar(0x0E12), QChar(0x0E13), QChar(0x0E14), QChar(0x0E15), QChar(0x0E16), QChar(0x0E17), // B0-B7 + QChar(0x0E18), QChar(0x0E19), QChar(0x0E1A), QChar(0x0E1B), QChar(0x0E1C), QChar(0x0E1D), QChar(0x0E1E), QChar(0x0E1F), // B8-BF + QChar(0x0E20), QChar(0x0E21), QChar(0x0E22), QChar(0x0E23), QChar(0x0E24), QChar(0x0E25), QChar(0x0E26), QChar(0x0E27), // C0-C7 + QChar(0x0E28), QChar(0x0E29), QChar(0x0E2A), QChar(0x0E2B), QChar(0x0E2C), QChar(0x0E2D), QChar(0x0E2E), QChar(0x0E2F), // C8-CF + QChar(0x0E30), QChar(0x0E31), QChar(0x0E32), QChar(0x0E33), QChar(0x0E34), QChar(0x0E35), QChar(0x0E36), QChar(0x0E37), // D0-D7 + QChar(0x0E38), QChar(0x0E39), QChar(0x0E3A), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x0E3F), // D8-DF + QChar(0x0E40), QChar(0x0E41), QChar(0x0E42), QChar(0x0E43), QChar(0x0E44), QChar(0x0E45), QChar(0x0E46), QChar(0x0E47), // E0-E7 + QChar(0x0E48), QChar(0x0E49), QChar(0x0E4A), QChar(0x0E4B), QChar(0x0E4C), QChar(0x0E4D), QChar(0x0E4E), QChar(0x0E4F), // E8-EF + QChar(0x0E50), QChar(0x0E51), QChar(0x0E52), QChar(0x0E53), QChar(0x0E54), QChar(0x0E55), QChar(0x0E56), QChar(0x0E57), // F0=F7 + QChar(0x0E58), QChar(0x0E59), QChar(0x0E5A), QChar(0x0E5B), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD)}},// F8-FF + {"ISO 8859-13", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0x201D), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x201E), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x00D8), QChar(0x00A9), QChar(0x0156), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00C6), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x201C), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x00F8), QChar(0x00B9), QChar(0x0157), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00E6), // B8-BF + QChar(0x0104), QChar(0x012E), QChar(0x0100), QChar(0x0106), QChar(0x00C4), QChar(0x00C5), QChar(0x0118), QChar(0x0112), // C0-C7 + QChar(0x010C), QChar(0x00C9), QChar(0x0179), QChar(0x0116), QChar(0x0122), QChar(0x0136), QChar(0x012A), QChar(0x013B), // C8-CF + QChar(0x0160), QChar(0x0143), QChar(0x0145), QChar(0x00D3), QChar(0x014C), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 + QChar(0x0172), QChar(0x0141), QChar(0x015A), QChar(0x016A), QChar(0x00DC), QChar(0x017B), QChar(0x017D), QChar(0x00DF), // D8-DF + QChar(0x0105), QChar(0x012F), QChar(0x0101), QChar(0x0107), QChar(0x00E4), QChar(0x00E5), QChar(0x0119), QChar(0x0113), // E0-E7 + QChar(0x010D), QChar(0x00E9), QChar(0x017A), QChar(0x0117), QChar(0x0123), QChar(0x0137), QChar(0x012B), QChar(0x013C), // E8-EF + QChar(0x0161), QChar(0x0144), QChar(0x0146), QChar(0x00F3), QChar(0x014D), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 + QChar(0x0173), QChar(0x0142), QChar(0x015B), QChar(0x016B), QChar(0x00FC), QChar(0x017C), QChar(0x017E), QChar(0x2019)}},// F8-FF + {"ISO 8859-14", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0x1E02), QChar(0x1E03), QChar(0x00A3), QChar(0x010A), QChar(0x010B), QChar(0x1E0A), QChar(0x00A7), // A0-A7 + QChar(0x1E80), QChar(0x00A9), QChar(0x1E82), QChar(0x1E0B), QChar(0x1EF2), QChar(0x00AD), QChar(0x00AE), QChar(0x0178), // A8-AF + QChar(0x1E1E), QChar(0x1E1F), QChar(0x0120), QChar(0x0121), QChar(0x1E40), QChar(0x1E41), QChar(0x00B6), QChar(0x1E56), // B0-B7 + QChar(0x1E81), QChar(0x1E57), QChar(0x1E83), QChar(0x1E60), QChar(0x1EF3), QChar(0x1E84), QChar(0x1E85), QChar(0x1E61), // B8-BF + QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x00C7), // C0-C7 + QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF + QChar(0x0174), QChar(0x00D1), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x1E6A), // D0-D7 + QChar(0x00D8), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x00DD), QChar(0x0176), QChar(0x00DF), // D8-DF + QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x00E7), // E0-E7 + QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF + QChar(0x0175), QChar(0x00F1), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x1E6B), // F0=F7 + QChar(0x00F8), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x00FD), QChar(0x0177), QChar(0x00FF)}},// F8-FF + {"ISO 8859-15", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0x00A1), QChar(0x00A2), QChar(0x00A3), QChar(0x20AC), QChar(0x00A5), QChar(0x0160), QChar(0x00A7), // A0-A7 + QChar(0x0161), QChar(0x00A9), QChar(0x00AA), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x017D), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x017E), QChar(0x00B9), QChar(0x00BA), QChar(0x00BB), QChar(0x0152), QChar(0x0153), QChar(0x0178), QChar(0x00BF), // B8-BF + QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x00C7), // C0-C7 + QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF + QChar(0x00D0), QChar(0x00D1), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 + QChar(0x00D8), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x00DD), QChar(0x00DE), QChar(0x00DF), // D8-DF + QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x00E7), // E0-E7 + QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF + QChar(0x00F0), QChar(0x00F1), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 + QChar(0x00F8), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x00FD), QChar(0x00FE), QChar(0x00FF)}},// F8-FF + {"ISO 8859-16", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0080), QChar(0x0081), QChar(0x0082), QChar(0x0083), QChar(0x0084), QChar(0x0085), QChar(0x0086), QChar(0x0087), // 80-87 + QChar(0x0088), QChar(0x0089), QChar(0x008A), QChar(0x008B), QChar(0x008C), QChar(0x008D), QChar(0x008E), QChar(0x008F), // 88-8F + QChar(0x0090), QChar(0x0091), QChar(0x0092), QChar(0x0093), QChar(0x0094), QChar(0x0095), QChar(0x0096), QChar(0x0097), // 90-97 + QChar(0x0098), QChar(0x0099), QChar(0x009A), QChar(0x009B), QChar(0x009C), QChar(0x009D), QChar(0x009E), QChar(0x009F), // 98-9F + QChar(0x00A0), QChar(0x0104), QChar(0x0105), QChar(0x0141), QChar(0x20AC), QChar(0x201E), QChar(0x0160), QChar(0x00A7), // A0-A7 + QChar(0x0161), QChar(0x00A9), QChar(0x0218), QChar(0x00AB), QChar(0x0179), QChar(0x00AD), QChar(0x017A), QChar(0x017B), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x010C), QChar(0x0142), QChar(0x017D), QChar(0x201D), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x017E), QChar(0x010D), QChar(0x0219), QChar(0x00BB), QChar(0x0152), QChar(0x0153), QChar(0x0178), QChar(0x017C), // B8-BF + QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x0102), QChar(0x00C4), QChar(0x0106), QChar(0x00C6), QChar(0x00C7), // C0-C7 + QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF + QChar(0x0110), QChar(0x0143), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x0150), QChar(0x00D6), QChar(0x015A), // D0-D7 + QChar(0x0170), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x0118), QChar(0x021A), QChar(0x00DF), // D8-DF + QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x0103), QChar(0x00E4), QChar(0x0107), QChar(0x00E6), QChar(0x00E7), // E0-E7 + QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF + QChar(0x0111), QChar(0x0144), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x0151), QChar(0x00F6), QChar(0x015B), // F0=F7 + QChar(0x0171), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x0119), QChar(0x021B), QChar(0x00FF)}},// F8-FF + {"CP437", // Our alternative is M_CP437 + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x00C7), QChar(0x00FC), QChar(0x00E9), QChar(0x00E2), QChar(0x00E4), QChar(0x00E0), QChar(0x00E5), QChar(0x00E7), // 80-87 + QChar(0x00EA), QChar(0x00EB), QChar(0x00E8), QChar(0x00EF), QChar(0x00EE), QChar(0x00EC), QChar(0x00C4), QChar(0x00C5), // 88-8F + QChar(0x00C9), QChar(0x00E6), QChar(0x00C6), QChar(0x00F4), QChar(0x00F6), QChar(0x00F2), QChar(0x00FB), QChar(0x00F9), // 90-97 + QChar(0x00FF), QChar(0x00D6), QChar(0x00DC), QChar(0x00A2), QChar(0x00A3), QChar(0x00A5), QChar(0x20A7), QChar(0x0192), // 98-9F + QChar(0x00E1), QChar(0x00ED), QChar(0x00F3), QChar(0x00FA), QChar(0x00F1), QChar(0x00D1), QChar(0x00AA), QChar(0x00BA), // A0-A7 + QChar(0x00BF), QChar(0x2310), QChar(0x00AC), QChar(0x00BD), QChar(0x00BC), QChar(0x00A1), QChar(0x00AB), QChar(0x00BB), // A8-AF + QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2502), QChar(0x2524), QChar(0x2561), QChar(0x2562), QChar(0x2556), // B0-B7 + QChar(0x2555), QChar(0x2563), QChar(0x2551), QChar(0x2557), QChar(0x255D), QChar(0x255C), QChar(0x255B), QChar(0x2510), // B8-BF + QChar(0x2514), QChar(0x2534), QChar(0x252C), QChar(0x251C), QChar(0x2500), QChar(0x253C), QChar(0x255E), QChar(0x255F), // C0-C7 + QChar(0x255A), QChar(0x2554), QChar(0x2569), QChar(0x2566), QChar(0x2560), QChar(0x2550), QChar(0x256C), QChar(0x2567), // C8-CF + QChar(0x2568), QChar(0x2564), QChar(0x2565), QChar(0x2559), QChar(0x2558), QChar(0x2552), QChar(0x2553), QChar(0x256B), // D0-D7 + QChar(0x256A), QChar(0x2518), QChar(0x250C), QChar(0x2588), QChar(0x2584), QChar(0x258C), QChar(0x2590), QChar(0x2580), // D8-DF + QChar(0x03B1), QChar(0x00DF), QChar(0x0393), QChar(0x03C0), QChar(0x03A3), QChar(0x03C3), QChar(0x00B5), QChar(0x03C4), // E0-E7 + QChar(0x03A6), QChar(0x0398), QChar(0x03A9), QChar(0x03B4), QChar(0x221E), QChar(0x03C6), QChar(0x03B5), QChar(0x2229), // E8-EF + QChar(0x2261), QChar(0x00B1), QChar(0x2265), QChar(0x2264), QChar(0x2320), QChar(0x2321), QChar(0x00F7), QChar(0x2248), // F0=F7 + QChar(0x00B0), QChar(0x2219), QChar(0x00B7), QChar(0x221A), QChar(0x207F), QChar(0x00B2), QChar(0x25A0), QChar(0x00A0)}},// F8-FF + {"CP667", // Our alternative is M_CP667 + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x00C7), QChar(0x00FC), QChar(0x00E9), QChar(0x00E2), QChar(0x00E4), QChar(0x00E0), QChar(0x0105), QChar(0x00E7), // 80-87 + QChar(0x00EA), QChar(0x00EB), QChar(0x00E8), QChar(0x00EF), QChar(0x00EE), QChar(0x0107), QChar(0x00C4), QChar(0x0104), // 88-8F + QChar(0x0118), QChar(0x0119), QChar(0x0142), QChar(0x00F4), QChar(0x00F6), QChar(0x0106), QChar(0x00FB), QChar(0x00F9), // 90-97 + QChar(0x015A), QChar(0x00D6), QChar(0x00DC), QChar(0x00A2), QChar(0x0141), QChar(0x00A5), QChar(0x015B), QChar(0x0192), // 98-9F + QChar(0x0179), QChar(0x017B), QChar(0x00F3), QChar(0x0144), QChar(0x0143), QChar(0x017A), QChar(0x017C), QChar(0x00BA), // A0-A7 + QChar(0x00BF), QChar(0x2310), QChar(0x00AC), QChar(0x00BD), QChar(0x00BC), QChar(0x00A1), QChar(0x00AB), QChar(0x00BB), // A8-AF + QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2502), QChar(0x2524), QChar(0x2561), QChar(0x2562), QChar(0x2556), // B0-B7 + QChar(0x2555), QChar(0x2563), QChar(0x2551), QChar(0x2557), QChar(0x255D), QChar(0x255C), QChar(0x255B), QChar(0x2510), // B8-BF + QChar(0x2514), QChar(0x2534), QChar(0x252C), QChar(0x251C), QChar(0x2500), QChar(0x253C), QChar(0x255E), QChar(0x255F), // C0-C7 + QChar(0x255A), QChar(0x2554), QChar(0x2569), QChar(0x2566), QChar(0x2560), QChar(0x2550), QChar(0x256C), QChar(0x2567), // C8-CF + QChar(0x2568), QChar(0x2564), QChar(0x2565), QChar(0x2559), QChar(0x2558), QChar(0x2552), QChar(0x2553), QChar(0x256B), // D0-D7 + QChar(0x256A), QChar(0x2518), QChar(0x250C), QChar(0x2588), QChar(0x2584), QChar(0x258C), QChar(0x2590), QChar(0x2580), // D8-DF + QChar(0x03B1), QChar(0x00DF), QChar(0x0393), QChar(0x03C0), QChar(0x03A3), QChar(0x03C3), QChar(0x00B5), QChar(0x03C4), // E0-E7 + QChar(0x03A6), QChar(0x0398), QChar(0x03A9), QChar(0x03B4), QChar(0x221E), QChar(0x03C6), QChar(0x03B5), QChar(0x2229), // E8-EF + QChar(0x2261), QChar(0x00B1), QChar(0x2265), QChar(0x2264), QChar(0x2320), QChar(0x2321), QChar(0x00F7), QChar(0x2248), // F0=F7 + QChar(0x00B0), QChar(0x2219), QChar(0x00B7), QChar(0x221A), QChar(0x207F), QChar(0x00B2), QChar(0x25A0), QChar(0x00A0)}},// F8-FF + {"CP737", // Our alternative is M_CP737 + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0391), QChar(0x0392), QChar(0x0393), QChar(0x0394), QChar(0x0395), QChar(0x0396), QChar(0x0397), QChar(0x0398), // 80-87 + QChar(0x0399), QChar(0x039A), QChar(0x039B), QChar(0x039C), QChar(0x039D), QChar(0x039E), QChar(0x039F), QChar(0x03A0), // 88-8F + QChar(0x03A1), QChar(0x03A3), QChar(0x03A4), QChar(0x03A5), QChar(0x03A6), QChar(0x03A7), QChar(0x03A8), QChar(0x03A9), // 90-97 + QChar(0x00FF), QChar(0x00D6), QChar(0x00DC), QChar(0x00A2), QChar(0x00A3), QChar(0x00A5), QChar(0x20A7), QChar(0x0192), // 98-9F + QChar(0x00E1), QChar(0x00ED), QChar(0x00F3), QChar(0x00FA), QChar(0x00F1), QChar(0x00D1), QChar(0x00AA), QChar(0x00BA), // A0-A7 + QChar(0x00BF), QChar(0x2310), QChar(0x00AC), QChar(0x00BD), QChar(0x00BC), QChar(0x00A1), QChar(0x00AB), QChar(0x00BB), // A8-AF + QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2502), QChar(0x2524), QChar(0x2561), QChar(0x2562), QChar(0x2556), // B0-B7 + QChar(0x2555), QChar(0x2563), QChar(0x2551), QChar(0x2557), QChar(0x255D), QChar(0x255C), QChar(0x255B), QChar(0x2510), // B8-BF + QChar(0x2514), QChar(0x2534), QChar(0x252C), QChar(0x251C), QChar(0x2500), QChar(0x253C), QChar(0x255E), QChar(0x255F), // C0-C7 + QChar(0x255A), QChar(0x2554), QChar(0x2569), QChar(0x2566), QChar(0x2560), QChar(0x2550), QChar(0x256C), QChar(0x2567), // C8-CF + QChar(0x2568), QChar(0x2564), QChar(0x2565), QChar(0x2559), QChar(0x2558), QChar(0x2552), QChar(0x2553), QChar(0x256B), // D0-D7 + QChar(0x256A), QChar(0x2518), QChar(0x250C), QChar(0x2588), QChar(0x2584), QChar(0x258C), QChar(0x2590), QChar(0x2580), // D8-DF + QChar(0x03C9), QChar(0x03AC), QChar(0x03AD), QChar(0x03AE), QChar(0x03CA), QChar(0x03AF), QChar(0x03CC), QChar(0x03CD), // E0-E7 + QChar(0x03CB), QChar(0x03CE), QChar(0x0386), QChar(0x0388), QChar(0x0389), QChar(0x038A), QChar(0x038C), QChar(0x038E), // E8-EF + QChar(0x03C9), QChar(0x00B1), QChar(0x2265), QChar(0x2264), QChar(0x03AA), QChar(0x03AB), QChar(0x00F7), QChar(0x2248), // F0=F7 + QChar(0x00B0), QChar(0x2219), QChar(0x00B7), QChar(0x221A), QChar(0x207F), QChar(0x00B2), QChar(0x25A0), QChar(0x00A0)}},// F8-FF + {"CP850", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x00C7), QChar(0x00FC), QChar(0x00E9), QChar(0x00E2), QChar(0x00E4), QChar(0x00E0), QChar(0x00E5), QChar(0x00E7), // 80-87 + QChar(0x00EA), QChar(0x00EB), QChar(0x00E8), QChar(0x00EF), QChar(0x00EE), QChar(0x00EC), QChar(0x00C4), QChar(0x00C5), // 88-8F + QChar(0x00C9), QChar(0x00E6), QChar(0x00C6), QChar(0x00F4), QChar(0x00F6), QChar(0x00F2), QChar(0x00FB), QChar(0x00F9), // 90-97 + QChar(0x00FF), QChar(0x00D6), QChar(0x00DC), QChar(0x00F8), QChar(0x00A3), QChar(0x00D8), QChar(0x00D7), QChar(0x0192), // 98-9F + QChar(0x00E1), QChar(0x00ED), QChar(0x00F3), QChar(0x00FA), QChar(0x00F1), QChar(0x00D1), QChar(0x00AA), QChar(0x00BA), // A0-A7 + QChar(0x00BF), QChar(0x00AE), QChar(0x00AC), QChar(0x00BD), QChar(0x00BC), QChar(0x00A1), QChar(0x00AB), QChar(0x00BB), // A8-AF + QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2502), QChar(0x2524), QChar(0x00C1), QChar(0x00C2), QChar(0x00C0), // B0-B7 + QChar(0x00A9), QChar(0x2563), QChar(0x2551), QChar(0x2557), QChar(0x255D), QChar(0x00A2), QChar(0x00A5), QChar(0x2510), // B8-BF + QChar(0x2514), QChar(0x2534), QChar(0x252C), QChar(0x251C), QChar(0x2500), QChar(0x253C), QChar(0x00E3), QChar(0x00C3), // C0-C7 + QChar(0x255A), QChar(0x2554), QChar(0x2569), QChar(0x2566), QChar(0x2560), QChar(0x2550), QChar(0x256C), QChar(0x00A4), // C8-CF + QChar(0x00F0), QChar(0x00D0), QChar(0x00CA), QChar(0x00CB), QChar(0x00C8), QChar(0x0131), QChar(0x00CD), QChar(0x00CE), // D0-D7 + QChar(0x00CF), QChar(0x2518), QChar(0x250C), QChar(0x2588), QChar(0x2584), QChar(0x00A6), QChar(0x00CC), QChar(0x2580), // D8-DF + QChar(0x00D3), QChar(0x00DF), QChar(0x00D4), QChar(0x00D2), QChar(0x00F5), QChar(0x00D5), QChar(0x00B5), QChar(0x00FE), // E0-E7 + QChar(0x00DE), QChar(0x00DA), QChar(0x00DB), QChar(0x00D9), QChar(0x00FD), QChar(0x00DD), QChar(0x00AF), QChar(0x00B4), // E8-EF + QChar(0x00AD), QChar(0x00B1), QChar(0x2017), QChar(0x00BE), QChar(0x00B6), QChar(0x00A7), QChar(0x00F7), QChar(0x00B8), // F0=F7 + QChar(0x00B0), QChar(0x00A8), QChar(0x00B7), QChar(0x00B9), QChar(0x00B3), QChar(0x00B2), QChar(0x25A0), QChar(0x00A0)}},// F8-FF + {"CP866", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0410), QChar(0x0411), QChar(0x0412), QChar(0x0413), QChar(0x0414), QChar(0x0415), QChar(0x0416), QChar(0x0417), // 80-87 + QChar(0x0418), QChar(0x0419), QChar(0x041A), QChar(0x041B), QChar(0x041C), QChar(0x041D), QChar(0x041E), QChar(0x041F), // 88-8F + QChar(0x0420), QChar(0x0421), QChar(0x0422), QChar(0x0423), QChar(0x0424), QChar(0x0425), QChar(0x0426), QChar(0x0427), // 90-97 + QChar(0x0428), QChar(0x0429), QChar(0x042A), QChar(0x042B), QChar(0x042C), QChar(0x042D), QChar(0x042E), QChar(0x042F), // 98-9F + QChar(0x0430), QChar(0x0431), QChar(0x0432), QChar(0x0433), QChar(0x0434), QChar(0x0435), QChar(0x0436), QChar(0x0437), // A0-A7 + QChar(0x0438), QChar(0x0439), QChar(0x043A), QChar(0x043B), QChar(0x043C), QChar(0x043D), QChar(0x043E), QChar(0x043F), // A8-AF + QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2502), QChar(0x2524), QChar(0x2561), QChar(0x2562), QChar(0x2556), // B0-B7 + QChar(0x2555), QChar(0x2563), QChar(0x2551), QChar(0x2557), QChar(0x255D), QChar(0x255C), QChar(0x255B), QChar(0x2510), // B8-BF + QChar(0x2514), QChar(0x2534), QChar(0x252C), QChar(0x251C), QChar(0x2500), QChar(0x253C), QChar(0x255E), QChar(0x255F), // C0-C7 + QChar(0x255A), QChar(0x2554), QChar(0x2569), QChar(0x2566), QChar(0x2560), QChar(0x2550), QChar(0x256C), QChar(0x2567), // C8-CF + QChar(0x2568), QChar(0x2564), QChar(0x2565), QChar(0x2559), QChar(0x2558), QChar(0x2552), QChar(0x2553), QChar(0x256B), // D0-D7 + QChar(0x256A), QChar(0x2518), QChar(0x250C), QChar(0x2588), QChar(0x2584), QChar(0x258C), QChar(0x2590), QChar(0x2580), // D8-DF + QChar(0x0440), QChar(0x0441), QChar(0x0442), QChar(0x0443), QChar(0x0444), QChar(0x0445), QChar(0x0446), QChar(0x0447), // E0-E7 + QChar(0x0448), QChar(0x0449), QChar(0x044A), QChar(0x044B), QChar(0x044C), QChar(0x044D), QChar(0x044E), QChar(0x044F), // E8-EF + QChar(0x0401), QChar(0x0451), QChar(0x0404), QChar(0x0454), QChar(0x0407), QChar(0x0457), QChar(0x040E), QChar(0x045E), // F0=F7 + QChar(0x00B0), QChar(0x2219), QChar(0x00B7), QChar(0x221A), QChar(0x2116), QChar(0x00A4), QChar(0x25A0), QChar(0x00A0)}},// F8-FF + {"CP869", // Our alternative is M_CP869 + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x0386), QChar(0x20AC), // 80-87 + QChar(0x00B7), QChar(0x00AC), QChar(0x00A6), QChar(0x2018), QChar(0x2019), QChar(0x0388), QChar(0x2015), QChar(0x0389), // 88-8F + QChar(0x038A), QChar(0x03AA), QChar(0x038C), QChar(0xFFFD), QChar(0xFFFD), QChar(0x038E), QChar(0x03A8), QChar(0x00A9), // 90-97 + QChar(0x038F), QChar(0x00B2), QChar(0x00B3), QChar(0x03AC), QChar(0x00A3), QChar(0x03AD), QChar(0x03AE), QChar(0x03AF), // 98-9F + QChar(0x03CA), QChar(0x0390), QChar(0x03CC), QChar(0x03CD), QChar(0x0391), QChar(0x0392), QChar(0x0393), QChar(0x0394), // A0-A7 + QChar(0x0395), QChar(0x0396), QChar(0x0397), QChar(0x00BD), QChar(0x0398), QChar(0x0399), QChar(0x00AB), QChar(0x00BB), // A8-AF + QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2502), QChar(0x2524), QChar(0x039A), QChar(0x039B), QChar(0x039C), // B0-B7 + QChar(0x039D), QChar(0x2563), QChar(0x2551), QChar(0x2557), QChar(0x255D), QChar(0x039E), QChar(0x039F), QChar(0x2510), // B8-BF + QChar(0x2514), QChar(0x2534), QChar(0x252C), QChar(0x251C), QChar(0x2500), QChar(0x253C), QChar(0x03A0), QChar(0x03A1), // C0-C7 + QChar(0x255A), QChar(0x2554), QChar(0x2569), QChar(0x2566), QChar(0x2560), QChar(0x2550), QChar(0x256C), QChar(0x03A3), // C8-CF + QChar(0x03A4), QChar(0x03A5), QChar(0x03A6), QChar(0x03A7), QChar(0x03A8), QChar(0x03A9), QChar(0x03B1), QChar(0x03B2), // D0-D7 + QChar(0x03B3), QChar(0x2518), QChar(0x250C), QChar(0x2588), QChar(0x2584), QChar(0x03B4), QChar(0x03B5), QChar(0x2580), // D8-DF + QChar(0x03B6), QChar(0x03B7), QChar(0x03B8), QChar(0x03B9), QChar(0x03BA), QChar(0x03BB), QChar(0x03BC), QChar(0x03BD), // E0-E7 + QChar(0x03BE), QChar(0x03BF), QChar(0x03C0), QChar(0x03C1), QChar(0x03C3), QChar(0x03C2), QChar(0x03C4), QChar(0x0384), // E8-EF + QChar(0x00AD), QChar(0x00B1), QChar(0x03C5), QChar(0x03C6), QChar(0x03C7), QChar(0x00A7), QChar(0x03C8), QChar(0x0385), // F0=F7 + QChar(0x00B0), QChar(0x00A8), QChar(0x03C9), QChar(0x03CB), QChar(0x03B0), QChar(0x03CE), QChar(0x25A0), QChar(0x00A0)}},// F8-FF + {"CP1161", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x20AC), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x2026), QChar(0xFFFD), QChar(0xFFFD), // 80-87 + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 88-8F + QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 + QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 98-9F + QChar(0x00A0), QChar(0x0E01), QChar(0x0E02), QChar(0x0E03), QChar(0x0E04), QChar(0x0E05), QChar(0x0E06), QChar(0x0E07), // A0-A7 + QChar(0x0E08), QChar(0x0E09), QChar(0x0E0A), QChar(0x0E0B), QChar(0x0E0C), QChar(0x0E0D), QChar(0x0E0E), QChar(0x0E0F), // A8-AF + QChar(0x0E10), QChar(0x0E11), QChar(0x0E12), QChar(0x0E13), QChar(0x0E14), QChar(0x0E15), QChar(0x0E16), QChar(0x0E17), // B0-B7 + QChar(0x0E18), QChar(0x0E19), QChar(0x0E1A), QChar(0x0E1B), QChar(0x0E1C), QChar(0x0E1D), QChar(0x0E1E), QChar(0x0E1F), // B8-BF + QChar(0x0E20), QChar(0x0E21), QChar(0x0E22), QChar(0x0E23), QChar(0x0E24), QChar(0x0E25), QChar(0x0E26), QChar(0x0E27), // C0-C7 + QChar(0x0E28), QChar(0x0E29), QChar(0x0E2A), QChar(0x0E2B), QChar(0x0E2C), QChar(0x0E2D), QChar(0x0E2E), QChar(0x0E2F), // C8-CF + QChar(0x0E30), QChar(0x0E31), QChar(0x0E32), QChar(0x0E33), QChar(0x0E34), QChar(0x0E35), QChar(0x0E36), QChar(0x0E37), // D0-D7 + QChar(0x0E38), QChar(0x0E39), QChar(0x0E3A), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0x0E3F), // D8-DF + QChar(0x0E40), QChar(0x0E41), QChar(0x0E42), QChar(0x0E43), QChar(0x0E44), QChar(0x0E45), QChar(0x0E46), QChar(0x0E47), // E0-E7 + QChar(0x0E48), QChar(0x0E49), QChar(0x0E4A), QChar(0x0E4B), QChar(0x0E4C), QChar(0x0E4D), QChar(0x0E4E), QChar(0x0E4F), // E8-EF + QChar(0x0E50), QChar(0x0E51), QChar(0x0E52), QChar(0x0E53), QChar(0x0E54), QChar(0x0E55), QChar(0x0E56), QChar(0x0E57), // F0=F7 + QChar(0x0E58), QChar(0x0E59), QChar(0x0E5A), QChar(0x0E5B), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD)}},// F8-FF + {"KOI8-R", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x2500), QChar(0x2502), QChar(0x250C), QChar(0x2510), QChar(0x2514), QChar(0x2518), QChar(0x251C), QChar(0x2524), // 80-87 + QChar(0x252C), QChar(0x2534), QChar(0x253C), QChar(0x2580), QChar(0x2584), QChar(0x2588), QChar(0x258C), QChar(0x2590), // 88-8F + QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2320), QChar(0x25A0), QChar(0x2219), QChar(0x221A), QChar(0x2248), // 90-97 + QChar(0x2264), QChar(0x2265), QChar(0x00A0), QChar(0x2321), QChar(0x00B0), QChar(0x00B2), QChar(0x00B7), QChar(0x00F7), // 98-9F + QChar(0x2550), QChar(0x2551), QChar(0x2552), QChar(0x0451), QChar(0x2553), QChar(0x2554), QChar(0x2555), QChar(0x2556), // A0-A7 + QChar(0x2557), QChar(0x2558), QChar(0x2559), QChar(0x255A), QChar(0x255B), QChar(0x255C), QChar(0x255D), QChar(0x255E), // A8-AF + QChar(0x255F), QChar(0x2560), QChar(0x2561), QChar(0x0401), QChar(0x2562), QChar(0x2563), QChar(0x2564), QChar(0x2565), // B0-B7 + QChar(0x2566), QChar(0x2567), QChar(0x2568), QChar(0x2569), QChar(0x256A), QChar(0x256B), QChar(0x256C), QChar(0x00A9), // B8-BF + QChar(0x044E), QChar(0x0430), QChar(0x0431), QChar(0x0446), QChar(0x0434), QChar(0x0435), QChar(0x0444), QChar(0x0433), // C0-C7 + QChar(0x0445), QChar(0x0438), QChar(0x0439), QChar(0x043A), QChar(0x043B), QChar(0x043C), QChar(0x043D), QChar(0x043E), // C8-CF + QChar(0x043F), QChar(0x044F), QChar(0x0440), QChar(0x0441), QChar(0x0442), QChar(0x0443), QChar(0x0436), QChar(0x0432), // D0-D7 + QChar(0x044C), QChar(0x044B), QChar(0x0437), QChar(0x0448), QChar(0x044D), QChar(0x0449), QChar(0x0447), QChar(0x044A), // D8-DF + QChar(0x042E), QChar(0x0410), QChar(0x0411), QChar(0x0426), QChar(0x0414), QChar(0x0415), QChar(0x0424), QChar(0x0413), // E0-E7 + QChar(0x0425), QChar(0x0418), QChar(0x0419), QChar(0x041A), QChar(0x041B), QChar(0x041C), QChar(0x041D), QChar(0x041E), // E8-EF + QChar(0x041F), QChar(0x042F), QChar(0x0420), QChar(0x0421), QChar(0x0422), QChar(0x0423), QChar(0x0416), QChar(0x0412), // F0=F7 + QChar(0x042C), QChar(0x042B), QChar(0x0417), QChar(0x0428), QChar(0x042D), QChar(0x0429), QChar(0x0427), QChar(0x042A)}},// F8-FF + {"KOI8-U", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x2500), QChar(0x2502), QChar(0x250C), QChar(0x2510), QChar(0x2514), QChar(0x2518), QChar(0x251C), QChar(0x2524), // 80-87 + QChar(0x252C), QChar(0x2534), QChar(0x253C), QChar(0x2580), QChar(0x2584), QChar(0x2588), QChar(0x258C), QChar(0x2590), // 88-8F + QChar(0x2591), QChar(0x2592), QChar(0x2593), QChar(0x2320), QChar(0x25A0), QChar(0x2219), QChar(0x221A), QChar(0x2248), // 90-97 + QChar(0x2264), QChar(0x2265), QChar(0x00A0), QChar(0x2321), QChar(0x00B0), QChar(0x00B2), QChar(0x00B7), QChar(0x00F7), // 98-9F + QChar(0x2550), QChar(0x2551), QChar(0x2552), QChar(0x0451), QChar(0x0454), QChar(0x2554), QChar(0x0456), QChar(0x0457), // A0-A7 + QChar(0x2557), QChar(0x2558), QChar(0x2559), QChar(0x255A), QChar(0x255B), QChar(0x0491), QChar(0x255D), QChar(0x255E), // A8-AF + QChar(0x255F), QChar(0x2560), QChar(0x2561), QChar(0x0401), QChar(0x0404), QChar(0x2563), QChar(0x0406), QChar(0x0407), // B0-B7 + QChar(0x2566), QChar(0x2567), QChar(0x2568), QChar(0x2569), QChar(0x256A), QChar(0x0490), QChar(0x256C), QChar(0x00A9), // B8-BF + QChar(0x044E), QChar(0x0430), QChar(0x0431), QChar(0x0446), QChar(0x0434), QChar(0x0435), QChar(0x0444), QChar(0x0433), // C0-C7 + QChar(0x0445), QChar(0x0438), QChar(0x0439), QChar(0x043A), QChar(0x043B), QChar(0x043C), QChar(0x043D), QChar(0x043E), // C8-CF + QChar(0x043F), QChar(0x044F), QChar(0x0440), QChar(0x0441), QChar(0x0442), QChar(0x0443), QChar(0x0436), QChar(0x0432), // D0-D7 + QChar(0x044C), QChar(0x044B), QChar(0x0437), QChar(0x0448), QChar(0x044D), QChar(0x0449), QChar(0x0447), QChar(0x044A), // D8-DF + QChar(0x042E), QChar(0x0410), QChar(0x0411), QChar(0x0426), QChar(0x0414), QChar(0x0415), QChar(0x0424), QChar(0x0413), // E0-E7 + QChar(0x0425), QChar(0x0418), QChar(0x0419), QChar(0x041A), QChar(0x041B), QChar(0x041C), QChar(0x041D), QChar(0x041E), // E8-EF + QChar(0x041F), QChar(0x042F), QChar(0x0420), QChar(0x0421), QChar(0x0422), QChar(0x0423), QChar(0x0416), QChar(0x0412), // F0=F7 + QChar(0x042C), QChar(0x042B), QChar(0x0417), QChar(0x0428), QChar(0x042D), QChar(0x0429), QChar(0x0427), QChar(0x042A)}},// F8-FF + {"MACINTOSH", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x00C4), QChar(0x00C5), QChar(0x00C7), QChar(0x00C9), QChar(0x00D1), QChar(0x00D6), QChar(0x00DC), QChar(0x00E1), // 80-87 + QChar(0x00E0), QChar(0x00E2), QChar(0x00E4), QChar(0x00E3), QChar(0x00E5), QChar(0x00E7), QChar(0x00E9), QChar(0x00E8), // 88-8F + QChar(0x00EA), QChar(0x00EB), QChar(0x00ED), QChar(0x00EC), QChar(0x00EE), QChar(0x00EF), QChar(0x00F1), QChar(0x00F3), // 90-97 + QChar(0x00F2), QChar(0x00F4), QChar(0x00F6), QChar(0x00F5), QChar(0x00FA), QChar(0x00F9), QChar(0x00FB), QChar(0x00FC), // 98-9F + QChar(0x2020), QChar(0x00B0), QChar(0x00A2), QChar(0x00A3), QChar(0x00A7), QChar(0x2022), QChar(0x00B6), QChar(0x00DF), // A0-A7 + QChar(0x00AE), QChar(0x00A9), QChar(0x2122), QChar(0x00B4), QChar(0x00A8), QChar(0x2260), QChar(0x00C6), QChar(0x00D8), // A8-AF + QChar(0x221E), QChar(0x00B1), QChar(0x2264), QChar(0x2265), QChar(0x00A5), QChar(0x00B5), QChar(0x2202), QChar(0x2211), // B0-B7 + QChar(0x220F), QChar(0x03C0), QChar(0x222B), QChar(0x00AA), QChar(0x00BA), QChar(0x03A9), QChar(0x00E6), QChar(0x00F8), // B8-BF + QChar(0x00BF), QChar(0x00A1), QChar(0x00AC), QChar(0x221A), QChar(0x0192), QChar(0x2248), QChar(0x2206), QChar(0x00AB), // C0-C7 + QChar(0x00BB), QChar(0x2026), QChar(0x00A0), QChar(0x00C0), QChar(0x00C3), QChar(0x00D5), QChar(0x0152), QChar(0x0153), // C8-CF + QChar(0x2013), QChar(0x2014), QChar(0x201C), QChar(0x201D), QChar(0x2018), QChar(0x2019), QChar(0x00F7), QChar(0x25CA), // D0-D7 + QChar(0x00FF), QChar(0x0178), QChar(0x2044), QChar(0x20AC), QChar(0x2039), QChar(0x203A), QChar(0xFB01), QChar(0xFB02), // D8-DF + QChar(0x2021), QChar(0x00B7), QChar(0x201A), QChar(0x201E), QChar(0x2030), QChar(0x00C2), QChar(0x00CA), QChar(0x00C1), // E0-E7 + QChar(0x00CB), QChar(0x00C8), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), QChar(0x00CC), QChar(0x00D3), QChar(0x00D4), // E8-EF + QChar(0xF8FF), QChar(0x00D2), QChar(0x00DA), QChar(0x00DB), QChar(0x00D9), QChar(0x0131), QChar(0x02C6), QChar(0x02DC), // F0=F7 + QChar(0x00AF), QChar(0x02D8), QChar(0x02D9), QChar(0x02DA), QChar(0x00B8), QChar(0x02DD), QChar(0x02DB), QChar(0x02C7)}},// F8-FF + {"WINDOWS-1250", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0xFFFD), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 + QChar(0xFFFD), QChar(0x2030), QChar(0x0160), QChar(0x2039), QChar(0x015A), QChar(0x0164), QChar(0x017D), QChar(0x0179), // 88-8F + QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 + QChar(0xFFFD), QChar(0x2122), QChar(0x0161), QChar(0x203A), QChar(0x015B), QChar(0x0165), QChar(0x017E), QChar(0x017A), // 98-9F + QChar(0x00A0), QChar(0x02C7), QChar(0x02D8), QChar(0x0141), QChar(0x00A4), QChar(0x0104), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x00A9), QChar(0x015E), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x017B), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x02DB), QChar(0x0142), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x00B8), QChar(0x0105), QChar(0x015F), QChar(0x00BB), QChar(0x013D), QChar(0x02DD), QChar(0x013E), QChar(0x017C), // B8-BF + QChar(0x0154), QChar(0x00C1), QChar(0x00C2), QChar(0x0102), QChar(0x00C4), QChar(0x0139), QChar(0x0106), QChar(0x00C7), // C0-C7 + QChar(0x010C), QChar(0x00C9), QChar(0x0118), QChar(0x00CB), QChar(0x011A), QChar(0x00CD), QChar(0x00CE), QChar(0x010E), // C8-CF + QChar(0x0110), QChar(0x0143), QChar(0x0147), QChar(0x00D3), QChar(0x00D4), QChar(0x0150), QChar(0x00D6), QChar(0x00D7), // D0-D7 + QChar(0x0158), QChar(0x016E), QChar(0x00DA), QChar(0x0170), QChar(0x00DC), QChar(0x00DD), QChar(0x0162), QChar(0x00DF), // D8-DF + QChar(0x0155), QChar(0x00E1), QChar(0x00E2), QChar(0x0103), QChar(0x00E4), QChar(0x013A), QChar(0x0107), QChar(0x00E7), // E0-E7 + QChar(0x010D), QChar(0x00E9), QChar(0x0119), QChar(0x00EB), QChar(0x011B), QChar(0x00ED), QChar(0x00EE), QChar(0x010F), // E8-EF + QChar(0x0111), QChar(0x0144), QChar(0x0148), QChar(0x00F3), QChar(0x00F4), QChar(0x0151), QChar(0x00F6), QChar(0x00F7), // F0=F7 + QChar(0x0159), QChar(0x016F), QChar(0x00FA), QChar(0x0171), QChar(0x00FC), QChar(0x00FD), QChar(0x0163), QChar(0x02D9)}},// F8-FF + {"WINDOWS-1251", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x0402), QChar(0x0403), QChar(0x201A), QChar(0x0453), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 + QChar(0x20AC), QChar(0x2030), QChar(0x0409), QChar(0x2039), QChar(0x040A), QChar(0x040C), QChar(0x040B), QChar(0x040F), // 88-8F + QChar(0x0452), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 + QChar(0xFFFD), QChar(0x2122), QChar(0x0459), QChar(0x203A), QChar(0x045A), QChar(0x045C), QChar(0x045B), QChar(0x045F), // 98-9F + QChar(0x00A0), QChar(0x040E), QChar(0x045E), QChar(0x0408), QChar(0x00A4), QChar(0x0490), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x0401), QChar(0x00A9), QChar(0x0404), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x0407), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x0406), QChar(0x0456), QChar(0x0491), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x0451), QChar(0x2116), QChar(0x0454), QChar(0x00BB), QChar(0x0458), QChar(0x0405), QChar(0x0455), QChar(0x0457), // B8-BF + QChar(0x0410), QChar(0x0411), QChar(0x0412), QChar(0x0413), QChar(0x0414), QChar(0x0415), QChar(0x0416), QChar(0x0417), // C0-C7 + QChar(0x0418), QChar(0x0419), QChar(0x041A), QChar(0x041B), QChar(0x041C), QChar(0x041D), QChar(0x041E), QChar(0x041F), // C8-CF + QChar(0x0420), QChar(0x0421), QChar(0x0422), QChar(0x0423), QChar(0x0424), QChar(0x0425), QChar(0x0426), QChar(0x0427), // D0-D7 + QChar(0x0428), QChar(0x0429), QChar(0x042A), QChar(0x042B), QChar(0x042C), QChar(0x042D), QChar(0x042E), QChar(0x042F), // D8-DF + QChar(0x0430), QChar(0x0431), QChar(0x0432), QChar(0x0433), QChar(0x0434), QChar(0x0435), QChar(0x0436), QChar(0x0437), // E0-E7 + QChar(0x0438), QChar(0x0439), QChar(0x043A), QChar(0x043B), QChar(0x043C), QChar(0x043D), QChar(0x043E), QChar(0x043F), // E8-EF + QChar(0x0440), QChar(0x0441), QChar(0x0442), QChar(0x0443), QChar(0x0444), QChar(0x0445), QChar(0x0446), QChar(0x0447), // F0=F7 + QChar(0x0448), QChar(0x0449), QChar(0x044A), QChar(0x044B), QChar(0x044C), QChar(0x044D), QChar(0x044E), QChar(0x044F)}},// F8-FF + {"WINDOWS-1252", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0x0192), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 + QChar(0x02C6), QChar(0x2030), QChar(0x0160), QChar(0x2039), QChar(0x0152), QChar(0xFFFD), QChar(0x017D), QChar(0xFFFD), // 88-8F + QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 + QChar(0x02DC), QChar(0x2122), QChar(0x0161), QChar(0x203A), QChar(0x0153), QChar(0xFFFD), QChar(0x017E), QChar(0x0178), // 98-9F + QChar(0x00A0), QChar(0x00A1), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x00A9), QChar(0x00AA), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x00B8), QChar(0x00B9), QChar(0x00BA), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00BF), // B8-BF + QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x00C7), // C0-C7 + QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF + QChar(0x00D0), QChar(0x00D1), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 + QChar(0x00D8), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x00DD), QChar(0x00DE), QChar(0x00DF), // D8-DF + QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x00E7), // E0-E7 + QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF + QChar(0x00F0), QChar(0x00F1), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 + QChar(0x00F8), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x00FD), QChar(0x00FE), QChar(0x00FF)}},// F8-FF + {"WINDOWS-1253", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0x0192), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 + QChar(0xFFFD), QChar(0x2030), QChar(0xFFFD), QChar(0x2039), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 88-8F + QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 + QChar(0xFFFD), QChar(0x2122), QChar(0xFFFD), QChar(0x203A), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 98-9F + QChar(0x00A0), QChar(0x0385), QChar(0x0386), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x00A9), QChar(0xFFFD), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x2015), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x0384), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x0388), QChar(0x0389), QChar(0x038A), QChar(0x00BB), QChar(0x038C), QChar(0x00BD), QChar(0x038E), QChar(0x038F), // B8-BF + QChar(0x0390), QChar(0x0391), QChar(0x0392), QChar(0x0393), QChar(0x0394), QChar(0x0395), QChar(0x0396), QChar(0x0397), // C0-C7 + QChar(0x0398), QChar(0x0399), QChar(0x039A), QChar(0x039B), QChar(0x039C), QChar(0x039D), QChar(0x039E), QChar(0x039F), // C8-CF + QChar(0x03A0), QChar(0x03A1), QChar(0xFFFD), QChar(0x03A3), QChar(0x03A4), QChar(0x03A5), QChar(0x03A6), QChar(0x03A7), // D0-D7 + QChar(0x03A8), QChar(0x03A9), QChar(0x03AA), QChar(0x03AB), QChar(0x03AC), QChar(0x03AD), QChar(0x03AE), QChar(0x03AF), // D8-DF + QChar(0x03B0), QChar(0x03B1), QChar(0x03B2), QChar(0x03B3), QChar(0x03B4), QChar(0x03B5), QChar(0x03B6), QChar(0x03B7), // E0-E7 + QChar(0x03B8), QChar(0x03B9), QChar(0x03BA), QChar(0x03BB), QChar(0x03BC), QChar(0x03BD), QChar(0x03BE), QChar(0x03BF), // E8-EF + QChar(0x03C0), QChar(0x03C1), QChar(0x03C2), QChar(0x03C3), QChar(0x03C4), QChar(0x03C5), QChar(0x03C6), QChar(0x03C7), // F0=F7 + QChar(0x03C8), QChar(0x03C9), QChar(0x03CA), QChar(0x03CB), QChar(0x03CC), QChar(0x03CD), QChar(0x03CE), QChar(0xFFFD)}},// F8-FF + {"WINDOWS-1254", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0x0192), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 + QChar(0x02C6), QChar(0x2030), QChar(0x0160), QChar(0x2039), QChar(0x0152), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 88-8F + QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 + QChar(0x02DC), QChar(0x2122), QChar(0x0161), QChar(0x203A), QChar(0x0153), QChar(0xFFFD), QChar(0xFFFD), QChar(0x0178), // 98-9F + QChar(0x00A0), QChar(0x00A1), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x00A9), QChar(0x00AA), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x00B8), QChar(0x00B9), QChar(0x00BA), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00BF), // B8-BF + QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x00C3), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x00C7), // C0-C7 + QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x00CC), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF + QChar(0x011E), QChar(0x00D1), QChar(0x00D2), QChar(0x00D3), QChar(0x00D4), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 + QChar(0x00D8), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x0130), QChar(0x015E), QChar(0x00DF), // D8-DF + QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x00E3), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x00E7), // E0-E7 + QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x00EC), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF + QChar(0x011F), QChar(0x00F1), QChar(0x00F2), QChar(0x00F3), QChar(0x00F4), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 + QChar(0x00F8), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x0131), QChar(0x015F), QChar(0x00FF)}},// F8-FF + {"WINDOWS-1255", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0x0192), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 + QChar(0x02C6), QChar(0x2030), QChar(0xFFFD), QChar(0x2039), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 88-8F + QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 + QChar(0x02DC), QChar(0x2122), QChar(0xFFFD), QChar(0x203A), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 98-9F + QChar(0x00A0), QChar(0x00A1), QChar(0x00A2), QChar(0x00A3), QChar(0x20AA), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x00A9), QChar(0x00D7), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x00B8), QChar(0x00B9), QChar(0x00F7), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00BF), // B8-BF + QChar(0x05B0), QChar(0x05B1), QChar(0x05B2), QChar(0x05B3), QChar(0x05B4), QChar(0x05B5), QChar(0x05B6), QChar(0x05B7), // C0-C7 + QChar(0x05B8), QChar(0x05B9), QChar(0xFFFD), QChar(0x05BB), QChar(0x05BC), QChar(0x05BD), QChar(0x05BE), QChar(0x05BF), // C8-CF + QChar(0x05C0), QChar(0x05C1), QChar(0x05C2), QChar(0x05C3), QChar(0x05F0), QChar(0x05F1), QChar(0x05F2), QChar(0x05F3), // D0-D7 + QChar(0x05F4), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // D8-DF + QChar(0x05D0), QChar(0x05D1), QChar(0x05D2), QChar(0x05D3), QChar(0x05D4), QChar(0x05D5), QChar(0x05D6), QChar(0x05D7), // E0-E7 + QChar(0x05D8), QChar(0x05D9), QChar(0x05DA), QChar(0x05DB), QChar(0x05DC), QChar(0x05DD), QChar(0x05DE), QChar(0x05DF), // E8-EF + QChar(0x05E0), QChar(0x05E1), QChar(0x05E2), QChar(0x05E3), QChar(0x05E4), QChar(0x05E5), QChar(0x05E6), QChar(0x05E7), // F0=F7 + QChar(0x05E8), QChar(0x05E9), QChar(0x05EA), QChar(0xFFFD), QChar(0xFFFD), QChar(0x200E), QChar(0x200F), QChar(0xFFFD)}},// F8-FF + {"WINDOWS-1256", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x20AC), QChar(0x067E), QChar(0x201A), QChar(0x0192), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 + QChar(0x02C6), QChar(0x2030), QChar(0x0679), QChar(0x2039), QChar(0x0152), QChar(0x0686), QChar(0x0698), QChar(0x0688), // 88-8F + QChar(0x06AF), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 + QChar(0x06A9), QChar(0x2122), QChar(0x0691), QChar(0x203A), QChar(0x0153), QChar(0x200C), QChar(0x200D), QChar(0x06BA), // 98-9F + QChar(0x00A0), QChar(0x060C), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x00A9), QChar(0x06BE), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x00B8), QChar(0x00B9), QChar(0x061B), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x061F), // B8-BF + QChar(0x06C1), QChar(0x0621), QChar(0x0622), QChar(0x0623), QChar(0x0624), QChar(0x0625), QChar(0x0626), QChar(0x0627), // C0-C7 + QChar(0x0628), QChar(0x0629), QChar(0x062A), QChar(0x062B), QChar(0x062C), QChar(0x062D), QChar(0x062E), QChar(0x062F), // C8-CF + QChar(0x0630), QChar(0x0631), QChar(0x0632), QChar(0x0633), QChar(0x0634), QChar(0x0635), QChar(0x0636), QChar(0x00D7), // D0-D7 + QChar(0x0637), QChar(0x0638), QChar(0x0639), QChar(0x063A), QChar(0x0640), QChar(0x0641), QChar(0x0642), QChar(0x0643), // D8-DF + QChar(0x00E0), QChar(0x0644), QChar(0x00E2), QChar(0x0645), QChar(0x0646), QChar(0x0647), QChar(0x0648), QChar(0x00E7), // E0-E7 + QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x0649), QChar(0x064A), QChar(0x00EE), QChar(0x00EF), // E8-EF + QChar(0x064B), QChar(0x064C), QChar(0x064D), QChar(0x064E), QChar(0x00F4), QChar(0x064F), QChar(0x0650), QChar(0x00F7), // F0=F7 + QChar(0x0651), QChar(0x00F9), QChar(0x0652), QChar(0x00FB), QChar(0x00FC), QChar(0x200E), QChar(0x200F), QChar(0x06D2)}},// F8-FF + {"WINDOWS-1257", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0xFFFD), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 + QChar(0xFFFD), QChar(0x2030), QChar(0xFFFD), QChar(0x2039), QChar(0xFFFD), QChar(0x00A8), QChar(0x02C7), QChar(0x00B8), // 88-8F + QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 + QChar(0xFFFD), QChar(0x2122), QChar(0xFFFD), QChar(0x203A), QChar(0xFFFD), QChar(0x00AF), QChar(0x02DB), QChar(0xFFFD), // 98-9F + QChar(0x00A0), QChar(0xFFFD), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0xFFFD), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x00D8), QChar(0x00A9), QChar(0x0156), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00C6), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x00F8), QChar(0x00B9), QChar(0x0157), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00E6), // B8-BF + QChar(0x0104), QChar(0x012E), QChar(0x0100), QChar(0x0106), QChar(0x00C4), QChar(0x00C5), QChar(0x0118), QChar(0x0112), // C0-C7 + QChar(0x010C), QChar(0x00C9), QChar(0x0179), QChar(0x0116), QChar(0x0122), QChar(0x0136), QChar(0x012A), QChar(0x013B), // C8-CF + QChar(0x0160), QChar(0x0143), QChar(0x0145), QChar(0x00D3), QChar(0x014C), QChar(0x00D5), QChar(0x00D6), QChar(0x00D7), // D0-D7 + QChar(0x0172), QChar(0x0141), QChar(0x015A), QChar(0x016A), QChar(0x00DC), QChar(0x017B), QChar(0x017D), QChar(0x00DF), // D8-DF + QChar(0x0105), QChar(0x012F), QChar(0x0101), QChar(0x0107), QChar(0x00E4), QChar(0x00E5), QChar(0x0119), QChar(0x0113), // E0-E7 + QChar(0x010D), QChar(0x00E9), QChar(0x017A), QChar(0x0117), QChar(0x0123), QChar(0x0137), QChar(0x012B), QChar(0x013C), // E8-EF + QChar(0x0161), QChar(0x0144), QChar(0x0146), QChar(0x00F3), QChar(0x014D), QChar(0x00F5), QChar(0x00F6), QChar(0x00F7), // F0=F7 + QChar(0x0173), QChar(0x0142), QChar(0x015B), QChar(0x016B), QChar(0x00FC), QChar(0x017C), QChar(0x017E), QChar(0x02D9)}},// F8-FF + {"WINDOWS-1258", + // x0/x8 x1/x9 x2/xA x3/xB x4/xC x5/xD x6/xE x7/xF + {QChar(0x20AC), QChar(0xFFFD), QChar(0x201A), QChar(0x0192), QChar(0x201E), QChar(0x2026), QChar(0x2020), QChar(0x2021), // 80-87 + QChar(0x02C6), QChar(0x2030), QChar(0xFFFD), QChar(0x2039), QChar(0x0152), QChar(0xFFFD), QChar(0xFFFD), QChar(0xFFFD), // 88-8F + QChar(0xFFFD), QChar(0x2018), QChar(0x2019), QChar(0x201C), QChar(0x201D), QChar(0x2022), QChar(0x2013), QChar(0x2014), // 90-97 + QChar(0x02DC), QChar(0x2122), QChar(0xFFFD), QChar(0x203A), QChar(0x0153), QChar(0xFFFD), QChar(0xFFFD), QChar(0x0178), // 98-9F + QChar(0x00A0), QChar(0x00A1), QChar(0x00A2), QChar(0x00A3), QChar(0x00A4), QChar(0x00A5), QChar(0x00A6), QChar(0x00A7), // A0-A7 + QChar(0x00A8), QChar(0x00A9), QChar(0x00AA), QChar(0x00AB), QChar(0x00AC), QChar(0x00AD), QChar(0x00AE), QChar(0x00AF), // A8-AF + QChar(0x00B0), QChar(0x00B1), QChar(0x00B2), QChar(0x00B3), QChar(0x00B4), QChar(0x00B5), QChar(0x00B6), QChar(0x00B7), // B0-B7 + QChar(0x00B8), QChar(0x00B9), QChar(0x00BA), QChar(0x00BB), QChar(0x00BC), QChar(0x00BD), QChar(0x00BE), QChar(0x00BF), // B8-BF + QChar(0x00C0), QChar(0x00C1), QChar(0x00C2), QChar(0x0102), QChar(0x00C4), QChar(0x00C5), QChar(0x00C6), QChar(0x00C7), // C0-C7 + QChar(0x00C8), QChar(0x00C9), QChar(0x00CA), QChar(0x00CB), QChar(0x0300), QChar(0x00CD), QChar(0x00CE), QChar(0x00CF), // C8-CF + QChar(0x0110), QChar(0x00D1), QChar(0x0309), QChar(0x00D3), QChar(0x00D4), QChar(0x01A0), QChar(0x00D6), QChar(0x00D7), // D0-D7 + QChar(0x00D8), QChar(0x00D9), QChar(0x00DA), QChar(0x00DB), QChar(0x00DC), QChar(0x01AF), QChar(0x0303), QChar(0x00DF), // D8-DF + QChar(0x00E0), QChar(0x00E1), QChar(0x00E2), QChar(0x0103), QChar(0x00E4), QChar(0x00E5), QChar(0x00E6), QChar(0x00E7), // E0-E7 + QChar(0x00E8), QChar(0x00E9), QChar(0x00EA), QChar(0x00EB), QChar(0x0301), QChar(0x00ED), QChar(0x00EE), QChar(0x00EF), // E8-EF + QChar(0x0111), QChar(0x00F1), QChar(0x0323), QChar(0x00F3), QChar(0x00F4), QChar(0x01A1), QChar(0x00F6), QChar(0x00F7), // F0=F7 + QChar(0x00F8), QChar(0x00F9), QChar(0x00FA), QChar(0x00FB), QChar(0x00FC), QChar(0x01B0), QChar(0x20AB), QChar(0x00FF)}}};// F8-FF +// clang-format on \ No newline at end of file diff --git a/src/TEncodingTable.h b/src/TEncodingTable.h new file mode 100644 index 00000000000..0425ce1c395 --- /dev/null +++ b/src/TEncodingTable.h @@ -0,0 +1,54 @@ +#ifndef MUDLET_TENCODINGTABLE_H +#define MUDLET_TENCODINGTABLE_H +/*************************************************************************** + * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * + * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * + * Copyright (C) 2014-2018 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "pre_guard.h" +#include +#include +#include +#include +#include +#include +#include +#include "post_guard.h" + +// a map of encoding names to encodings +class TEncodingTable +{ + static const QMap> csmEncodings; + inline static const QVector csmEmptyLookupTable = {}; + + const QMap>& mEncodingMap; + +public: + static const TEncodingTable csmDefaultInstance; + + explicit TEncodingTable(const QMap>& encodings) : mEncodingMap(encodings) {} + + const QMap> getEncodings() const { return mEncodingMap; } + QList getEncodingNames() const; + + const QVector& getLookupTable(const QByteArray& encoding) const; +}; + +#endif //MUDLET_TENCODINGTABLE_H diff --git a/src/TEntityHandler.cpp b/src/TEntityHandler.cpp new file mode 100644 index 00000000000..62cb69e56fd --- /dev/null +++ b/src/TEntityHandler.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * + * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * + * Copyright (C) 2014-2018 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TEntityHandler.h" + +// returns true if the char is handled by the EntityHandler (i.e. it is part of an entity) +bool TEntityHandler::handle(char ch) +{ + if (ch == ';' && !mCurrentEntity.isEmpty()) { // END OF ENTITY + mCurrentEntity.append(ch); + + QString resolved = mpEntityResolver.getResolution(mCurrentEntity); + // we only get the last character, current implementation of TBuffer loop is based on one char at a time + // TODO: it could be interesting to have a way to send longer sequences to the buffer + mResult = resolved.back().toLatin1(); + + mIsResolved = true; + mCurrentEntity.clear(); + return true; + } else if (ch == '&' || !mCurrentEntity.isEmpty()) { // START OR MIDDLE OF ENTITY + mIsResolved = false; + mCurrentEntity.append(ch); + return true; + } else if (mCurrentEntity.length() > 7) { // LONG ENTITY? MAYBE INVALID... IGNORE IT + reset(); + return false; + } else { + return false; + } +} +bool TEntityHandler::isEntityResolved() const +{ + return mIsResolved; +} + +void TEntityHandler::reset() +{ + mCurrentEntity.clear(); + mIsResolved = false; +} +char TEntityHandler::getResultAndReset() +{ + reset(); + return mResult; +} diff --git a/src/TEntityHandler.h b/src/TEntityHandler.h new file mode 100644 index 00000000000..fa662e303dc --- /dev/null +++ b/src/TEntityHandler.h @@ -0,0 +1,47 @@ +#ifndef MUDLET_TENTITYHANDLER_H +#define MUDLET_TENTITYHANDLER_H +/*************************************************************************** + * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * + * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * + * Copyright (C) 2014-2018 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TEntityResolver.h" +// Handles entity processing state and conversion of simple standard entities such as > < & and " +class TEntityHandler +{ +private: + const TEntityResolver& mpEntityResolver; + + QString mCurrentEntity; + bool mIsResolved; + char mResult; + +public: + TEntityHandler() : TEntityHandler(TEntityResolver::scmDefaultResolver) {} + explicit TEntityHandler(const TEntityResolver& pResolver) : mpEntityResolver(pResolver), mIsResolved(false), mResult(0) {} + + bool handle(char ch); + void reset(); + + bool isEntityResolved() const; + char getResultAndReset(); +}; + +#endif //MUDLET_TENTITYHANDLER_H diff --git a/src/TEntityResolver.cpp b/src/TEntityResolver.cpp new file mode 100644 index 00000000000..a5dbf8054c7 --- /dev/null +++ b/src/TEntityResolver.cpp @@ -0,0 +1,169 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TEntityResolver.h" + +QString TEntityResolver::getResolution(const QString& entity) const +{ + if (entity.front() != '&' || entity.back() != ';') { + return entity; + } + + auto ptr = mEntititesMap.find(entity.toLower()); + if (ptr != mEntititesMap.end()) { + return *ptr; + } + + auto stdPtr = scmStandardEntites.find(entity.toLower()); + if (stdPtr != scmStandardEntites.end()) { + return *stdPtr; + } + + + return entity[1] == '#' ? resolveCode(entity.mid(2, entity.size() - 3)) : entity; +} + +bool TEntityResolver::registerEntity(const QString& entity, const QString& str) +{ + if (entity.front() != '&' || entity.back() != ';') { + return false; + } + + + mEntititesMap[entity.toLower()] = str; + return true; +} + +bool TEntityResolver::unregisterEntity(const QString & entity){ + return mEntititesMap.remove(entity) > 0; +} + +QString TEntityResolver::resolveCode(const QString& entityValue) +{ + return entityValue.front() == 'x' ? resolveCode(entityValue.mid(1), 16) : resolveCode(entityValue, 10); +} + +QString TEntityResolver::resolveCode(const QString& entityValue, int base) +{ + bool isNum = false; + ushort code = entityValue.toUShort(&isNum, base); + return isNum ? resolveCode(code) : entityValue; +} + +QString TEntityResolver::resolveCode(ushort val) +{ + return QString(QChar(val)); +} + +QString TEntityResolver::interpolate(const QString& input, std::function resolver) +{ + QString output; + QString entity; + + for (const auto& ch : input) { + if (ch == ';' && !entity.isEmpty()) { + entity.append(ch); + output.append(resolver(entity)); + entity.clear(); + } else if (ch == '&' || !entity.isEmpty()) { + entity.append(ch); + } else { + output.append(ch); + } + } + + output.append(entity); + return output; +} + +QString TEntityResolver::interpolate(const QString& input) const +{ + return interpolate(input, [this](const QString& it) { return getResolution(it); }); +} + +const TEntityResolver TEntityResolver::scmDefaultResolver = TEntityResolver(); + +// clang-format off +const QHash TEntityResolver::scmStandardEntites = { + {QStringLiteral("&tab;"), QStringLiteral("\t")}, + {QStringLiteral("&newline;"), QStringLiteral("\n")}, + {QStringLiteral("!"), QStringLiteral("!")}, + {QStringLiteral("""), QStringLiteral("\"")}, + {QStringLiteral("#"), QStringLiteral("#")}, + {QStringLiteral("$"), QStringLiteral("$")}, + {QStringLiteral("%"), QStringLiteral("%")}, + {QStringLiteral("&"), QStringLiteral("&")}, + {QStringLiteral("'"), QStringLiteral("'")}, + {QStringLiteral("("), QStringLiteral("(")}, + {QStringLiteral(")"), QStringLiteral(")")}, + {QStringLiteral("*"), QStringLiteral("*")}, + {QStringLiteral("+"), QStringLiteral("+")}, + {QStringLiteral(","), QStringLiteral(",")}, + {QStringLiteral("."), QStringLiteral(".")}, + {QStringLiteral("/"), QStringLiteral("/")}, + {QStringLiteral(":"), QStringLiteral(":")}, + {QStringLiteral(";"), QStringLiteral(";")}, + {QStringLiteral("<"), QStringLiteral("<")}, + {QStringLiteral("="), QStringLiteral("=")}, + {QStringLiteral(">"), QStringLiteral(">")}, + {QStringLiteral("?"), QStringLiteral("?")}, + {QStringLiteral("@"), QStringLiteral("@")}, + {QStringLiteral("["), QStringLiteral("[")}, + {QStringLiteral("\"), QStringLiteral("\\")}, + {QStringLiteral("]"), QStringLiteral("]")}, + {QStringLiteral("&hat;"), QStringLiteral("^")}, + {QStringLiteral("_"), QStringLiteral("_")}, + {QStringLiteral("`"), QStringLiteral("`")}, + {QStringLiteral("{"), QStringLiteral("{")}, + {QStringLiteral("|"), QStringLiteral("|")}, + {QStringLiteral("}"), QStringLiteral("}")}, + {QStringLiteral(" "), QStringLiteral(" ")}, + {QStringLiteral("¡"), QStringLiteral("¡")}, + {QStringLiteral("¢"), QStringLiteral("¢")}, + {QStringLiteral("£"), QStringLiteral("£")}, + {QStringLiteral("¤"), QStringLiteral("¤")}, + {QStringLiteral("¥"), QStringLiteral("Â¥")}, + {QStringLiteral("¦"), QStringLiteral("¦")}, + {QStringLiteral("§"), QStringLiteral("§")}, + {QStringLiteral("˙"), QStringLiteral("¨")}, + {QStringLiteral("©"), QStringLiteral("©")}, + {QStringLiteral("ª"), QStringLiteral("ª")}, + {QStringLiteral("«"), QStringLiteral("«")}, + {QStringLiteral("¬"), QStringLiteral("¬")}, + {QStringLiteral("­"), QStringLiteral("­")}, + {QStringLiteral("®"), QStringLiteral("®")}, + {QStringLiteral("¯"), QStringLiteral("¯")}, + {QStringLiteral("°"), QStringLiteral("°")}, + {QStringLiteral("±"), QStringLiteral("±")}, + {QStringLiteral("²"), QStringLiteral("²")}, + {QStringLiteral("³"), QStringLiteral("³")}, + {QStringLiteral("´"), QStringLiteral("´")}, + {QStringLiteral("µ"), QStringLiteral("µ")}, + {QStringLiteral("¶"), QStringLiteral("¶")}, + {QStringLiteral("·"), QStringLiteral("·")}, + {QStringLiteral("¸"), QStringLiteral("¸")}, + {QStringLiteral("¹"), QStringLiteral("¹")}, + {QStringLiteral("º"), QStringLiteral("º")}, + {QStringLiteral("»"), QStringLiteral("»")}, + {QStringLiteral("¼"), QStringLiteral("¼")}, + {QStringLiteral("½"), QStringLiteral("½")}, + {QStringLiteral("¾"), QStringLiteral("¾")}, + {QStringLiteral("¿"), QStringLiteral("¿")} +}; +// clang-format on diff --git a/src/TEntityResolver.h b/src/TEntityResolver.h new file mode 100644 index 00000000000..0e5c8bfc493 --- /dev/null +++ b/src/TEntityResolver.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_MXPENTITYRESOLVER_H +#define MUDLET_MXPENTITYRESOLVER_H + +#include "pre_guard.h" +#include +#include +#include "post_guard.h" +#include + +class TEntityResolver +{ + QHash mEntititesMap; + +public: + static const QHash scmStandardEntites; + static const TEntityResolver scmDefaultResolver; + + + inline bool registerEntity(const QString& entity, const QChar ch) { return registerEntity(entity, QString(ch)); } + + inline bool registerEntity(const QString& entity, const char ch) { return registerEntity(entity, QChar::fromLatin1(ch)); } + + bool registerEntity(const QString& entity, const QString& str); + bool unregisterEntity(const QString& entity); + + QString getResolution(const QString& entityValue) const; + + static QString resolveCode(ushort val); + static QString resolveCode(const QString& entityValue); + static QString resolveCode(const QString& entityValue, int base); + static QString interpolate(const QString& input, std::function resolver); + + QString interpolate(const QString& input) const; +}; + +#endif //MUDLET_MXPENTITYRESOLVER_H diff --git a/src/TLinkStore.cpp b/src/TLinkStore.cpp new file mode 100644 index 00000000000..79800962970 --- /dev/null +++ b/src/TLinkStore.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TLinkStore.h" + +int TLinkStore::addLinks(const QStringList& links, const QStringList& hints) +{ + if (++mLinkID > maxLinks) { + mLinkID = 1; + } + mLinkStore[mLinkID] = links; + mHintStore[mLinkID] = hints; + + return mLinkID; +} + +QStringList TLinkStore::getCurrentLinks() const +{ + return mLinkStore[mLinkID]; +} + +void TLinkStore::setCurrentLinks(const QStringList& links) +{ + mLinkStore[mLinkID] = links; +} + +QStringList& TLinkStore::getLinks(int id) +{ + return mLinkStore[id]; +} + +QStringList& TLinkStore::getHints(int id) +{ + return mHintStore[id]; +} + +int TLinkStore::getCurrentLinkID() const +{ + return mLinkID; +} diff --git a/src/TLinkStore.h b/src/TLinkStore.h new file mode 100644 index 00000000000..f4706cda7ca --- /dev/null +++ b/src/TLinkStore.h @@ -0,0 +1,56 @@ +#ifndef MUDLET_TLINKSTORE_H +#define MUDLET_TLINKSTORE_H + +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "pre_guard.h" +#include +#include +#include "post_guard.h" + +// Keep together lists of links and hints associated +class TLinkStore { + inline static const int scmMaxLinks = 2000; + + QMap mLinkStore; + QMap mHintStore; + + int mLinkID; + + int maxLinks; +public: + TLinkStore() : TLinkStore(scmMaxLinks) + {}; + + explicit TLinkStore(int maxLinks) : maxLinks(maxLinks), mLinkID(0) + {} + + int addLinks(const QStringList& links, const QStringList& hints); + + QStringList& getLinks(int id); + QStringList& getHints(int id); + + int getCurrentLinkID() const; + + QStringList getCurrentLinks() const; + void setCurrentLinks(const QStringList& links); +}; + +#endif //MUDLET_TLINKSTORE_H diff --git a/src/TMxpBRTagHandler.cpp b/src/TMxpBRTagHandler.cpp new file mode 100644 index 00000000000..39af4461e9d --- /dev/null +++ b/src/TMxpBRTagHandler.cpp @@ -0,0 +1,24 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TMxpBRTagHandler.h" +TMxpTagHandlerResult TMxpBRTagHandler::handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) +{ + return MXP_TAG_COMMIT_LINE; +} diff --git a/src/TMxpBRTagHandler.h b/src/TMxpBRTagHandler.h new file mode 100644 index 00000000000..a791f0f6610 --- /dev/null +++ b/src/TMxpBRTagHandler.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPBRTAGHANDLER_H +#define MUDLET_TMXPBRTAGHANDLER_H +#include "TMxpTagHandler.h" + +class TMxpBRTagHandler : public TMxpSingleTagHandler +{ +public: + TMxpBRTagHandler() : TMxpSingleTagHandler("BR") {} + + TMxpTagHandlerResult handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) override; +}; +#include "TMxpTagHandler.h" +#endif //MUDLET_TMXPBRTAGHANDLER_H diff --git a/src/TMxpClient.h b/src/TMxpClient.h new file mode 100644 index 00000000000..c85be4afc07 --- /dev/null +++ b/src/TMxpClient.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPCLIENT_H +#define MUDLET_TMXPCLIENT_H + +#include "MxpTag.h" +#include "TMxpContext.h" +#include "TMxpTagHandlerResult.h" + +class TMxpClient +{ +protected: + TMxpContext* mpContext; + +public: + TMxpClient() : mpContext(nullptr) {} + + virtual void initialize(TMxpContext* context) { mpContext = context; } + + virtual QString getVersion() = 0; + + virtual void sendToServer(QString& str) = 0; + + virtual void setLinkMode(bool val) = 0; + + virtual void setFlag(const QString& elementName, const QMap& params, const QString& content) = 0; + + virtual void publishEntity(const QString& name, const QString& value) = 0; + + virtual void setVariable(const QString& name, const QString& value) = 0; + + virtual void pushColor(const QString& fgColor, const QString& bgColor) = 0; + virtual void popColor() = 0; + + virtual void pushFont(const QString& fontFace, const QString& fontSize) = 0; + virtual void popFont() = 0; + + virtual void setBold(bool val) = 0; + virtual void setItalic(bool val) = 0; + virtual void setUnderline(bool val) = 0; + + virtual int setLink(const QStringList& hrefs, const QStringList& hints) = 0; + virtual bool getLink(int id, QStringList** hrefs, QStringList** hints) = 0; + + virtual bool tagReceived(MxpTag* tag) { return tag->isStartTag() ? startTagReceived(tag->asStartTag()) : endTagReceived(tag->asEndTag()); } + + virtual bool startTagReceived(MxpStartTag* startTag) { return true; } + + virtual bool endTagReceived(MxpEndTag* startTag) { return true; } + + virtual TMxpTagHandlerResult tagHandled(MxpTag* tag, TMxpTagHandlerResult result) { return result; } +}; + +#endif //MUDLET_TMXPCLIENT_H diff --git a/src/TMxpColorTagHandler.cpp b/src/TMxpColorTagHandler.cpp new file mode 100644 index 00000000000..cfeb04ff6d5 --- /dev/null +++ b/src/TMxpColorTagHandler.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TMxpColorTagHandler.h" +#include "TMxpClient.h" +bool TMxpColorTagHandler::supports(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) +{ + return tag->isNamed("COLOR") || tag->isNamed("C"); +} +TMxpTagHandlerResult TMxpColorTagHandler::handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) +{ + QString fg = tag->getAttributeByNameOrIndex("FORE", 0); + QString bg = tag->getAttributeByNameOrIndex("BACK", 1); + + client.pushColor(fg, bg); + + return MXP_TAG_HANDLED; +} +TMxpTagHandlerResult TMxpColorTagHandler::handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) +{ + client.popColor(); + return MXP_TAG_HANDLED; +} diff --git a/src/TMxpColorTagHandler.h b/src/TMxpColorTagHandler.h new file mode 100644 index 00000000000..c0cc1c6c620 --- /dev/null +++ b/src/TMxpColorTagHandler.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPCOLORTAGHANDLER_H +#define MUDLET_TMXPCOLORTAGHANDLER_H + +#include "TMxpTagHandler.h" + +// +class TMxpColorTagHandler : public TMxpTagHandler +{ +public: + TMxpColorTagHandler() = default; + bool supports(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) override; + + TMxpTagHandlerResult handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) override; + TMxpTagHandlerResult handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) override; +}; +#include "TMxpTagHandler.h" +#endif //MUDLET_TMXPCOLORTAGHANDLER_H diff --git a/src/TMxpContext.h b/src/TMxpContext.h new file mode 100644 index 00000000000..f59664c9697 --- /dev/null +++ b/src/TMxpContext.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +#ifndef MUDLET_TMXPCONTEXT_H +#define MUDLET_TMXPCONTEXT_H + +#include "TEntityResolver.h" +#include "TMxpElementRegistry.h" +#include "TMxpTagHandler.h" + +#include "pre_guard.h" +#include +#include +#include +#include "post_guard.h" + +class TMxpClient; + +class TMxpContext : public TMxpTagHandler +{ +public: + virtual TMxpElementRegistry& getElementRegistry() = 0; + virtual QMap>& getSupportedElements() = 0; + virtual TEntityResolver& getEntityResolver() = 0; + + virtual TMxpTagHandler& getMainHandler() = 0; +}; + +#endif //MUDLET_TMXPCONTEXT_H diff --git a/src/TMxpCustomElementTagHandler.cpp b/src/TMxpCustomElementTagHandler.cpp new file mode 100644 index 00000000000..6db17e0f2f1 --- /dev/null +++ b/src/TMxpCustomElementTagHandler.cpp @@ -0,0 +1,161 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TMxpCustomElementTagHandler.h" +#include "TEntityResolver.h" +#include "TMxpClient.h" +#include "TMxpTagParser.h" + + +TMxpTagHandlerResult TMxpCustomElementTagHandler::handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) +{ + TMxpElement el = ctx.getElementRegistry().getElement(tag->getName()); + if (!el.flags.isEmpty()) { + mCurrentFlagAttributes = parseFlagAttributes(tag, el); + if (el.empty || tag->isEmpty()) { + setFlag(client, tag, el); + } else { + configFlag(client, tag, el); + } + } + + if (!el.definition.isEmpty()) { + for (const QSharedPointer& ptr : el.parsedDefinition) { + if (!ptr->isTag()) { + ctx.handleContent(ptr->asText()->getContent()); + } else { + // transform the custom tag to the given in the definition + MxpStartTag newTag = resolveElementDefinition(el, ptr->asStartTag(), tag); + ctx.handleTag(ctx, client, &newTag); + } + } + } + + return MXP_TAG_HANDLED; +} + +TMxpTagHandlerResult TMxpCustomElementTagHandler::handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) +{ + TMxpElement el = ctx.getElementRegistry().getElement(tag->getName()); + + if (!el.flags.isEmpty() && !mCurrentFlagName.isEmpty()) { // is closing a custom tag with flag + client.setFlag(mCurrentFlagName, mCurrentFlagAttributes, mCurrentFlagContent); + mCurrentFlagName.clear(); + } + + if (el.definition.isEmpty()) + return MXP_TAG_HANDLED; //NO DEFINITION + + + // generates closing tags in the reverse order + // in the example: ' ATT='col=red'> + // will generate + for (int i = el.parsedDefinition.size(); i > 0; i--) { + MxpNode* node = el.parsedDefinition[i - 1].get(); + if (node->isTag()) { + MxpEndTag endTag(node->asStartTag()->getName()); + ctx.handleTag(ctx, client, &endTag); + } + } + + return MXP_TAG_HANDLED; +} + +// Receives and element definition such as: +// " ATT='desc'> +// and a custom tag such as: +// 1024 +// and returns a new tag interpolating the definition with the custom tag values: +// +MxpStartTag TMxpCustomElementTagHandler::resolveElementDefinition(const TMxpElement& element, MxpStartTag* definitionTag, MxpStartTag* customTag) const +{ + auto mapping = [this, customTag, element](const MxpTagAttribute& attr) { + if (!attr.hasValue()) { + return MxpTagAttribute(mapAttributes(element, attr.getName(), customTag)); + } else { + if (attr.isNamed("hint")) { // not needed according to the spec, but kept to avoid changes for the user interface + return MxpTagAttribute(attr.getName(), mapAttributes(element, attr.getValue().toUpper(), customTag)); + } else { + return MxpTagAttribute(attr.getName(), mapAttributes(element, attr.getValue(), customTag)); + } + } + }; + + return definitionTag->transform(mapping); +} + +QString TMxpCustomElementTagHandler::mapAttributes(const TMxpElement& element, const QString& input, MxpStartTag* tag) +{ + auto mapEntityNameToTagAttributeValue = [element, tag](const QString& input) { + QString attrName = input.mid(1, input.size() - 2); + // get attribute value by NAME + // " ATT='desc'> + // 1024 + if (tag->hasAttribute(attrName)) { + return tag->getAttributeValue(attrName); + } + + // get attribute value by INDEX + // ' att='id'> + // A trash can + int attrIndex = element.attrs.indexOf(attrName.toLower()); + if (attrIndex != -1 && tag->getAttributesCount() > attrIndex) { + return tag->getAttribute(attrIndex).getName(); + } + + return input; + }; + + return TEntityResolver::interpolate(input, mapEntityNameToTagAttributeValue); +} +void TMxpCustomElementTagHandler::configFlag(TMxpClient& client, MxpStartTag* tag, const TMxpElement& el) +{ + mCurrentFlagName = el.name; + parseFlagAttributes(tag, el); + mCurrentFlagContent.clear(); +} + +void TMxpCustomElementTagHandler::setFlag(TMxpClient& ctx, const MxpStartTag* tag, const TMxpElement& el) +{ + ctx.setFlag(el.name, parseFlagAttributes(tag, el), ""); +} + +const QMap& TMxpCustomElementTagHandler::parseFlagAttributes(const MxpStartTag* tag, const TMxpElement& el) +{ + QMap& values = mCurrentFlagAttributes; + + values.clear(); + for (int i = 0; i < el.attrs.size(); i++) { + const QString& attrName = el.attrs[i]; + + if (tag->hasAttribute(attrName)) { + values[attrName] = tag->getAttributeValue(attrName); + } else if (tag->getAttributesCount() > i) { + values[attrName] = tag->getAttribute(i).getName(); + } + } + return values; +} + +void TMxpCustomElementTagHandler::handleContent(char ch) +{ + if (!mCurrentFlagName.isEmpty()) { + mCurrentFlagContent.append(ch); + } +} diff --git a/src/TMxpCustomElementTagHandler.h b/src/TMxpCustomElementTagHandler.h new file mode 100644 index 00000000000..7ca4190b8a7 --- /dev/null +++ b/src/TMxpCustomElementTagHandler.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPCUSTOMELEMENTTAGHANDLER_H +#define MUDLET_TMXPCUSTOMELEMENTTAGHANDLER_H + +#include "TMxpContext.h" +#include "TMxpElementRegistry.h" +#include "TMxpTagHandler.h" + +class TMxpCustomElementTagHandler : public TMxpTagHandler +{ + QString mCurrentFlagName; + QString mCurrentFlagContent; + QMap mCurrentFlagAttributes; + + MxpStartTag resolveElementDefinition(const TMxpElement& element, MxpStartTag* definitionTag, MxpStartTag* customTag) const; + static QString mapAttributes(const TMxpElement& element, const QString& input, MxpStartTag* tag); + void setFlag(TMxpClient& ctx, const MxpStartTag* tag, const TMxpElement& el); + void configFlag(TMxpClient& client, MxpStartTag* tag, const TMxpElement& el); + const QMap& parseFlagAttributes(const MxpStartTag* tag, const TMxpElement& el); + +public: + bool supports(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) override { return ctx.getElementRegistry().containsElement(tag->getName()); } + + TMxpTagHandlerResult handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) override; + TMxpTagHandlerResult handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) override; + void handleContent(char ch) override; +}; +#include "TMxpTagHandler.h" +#endif //MUDLET_TMXPCUSTOMELEMENTTAGHANDLER_H diff --git a/src/TMxpElementDefinitionHandler.cpp b/src/TMxpElementDefinitionHandler.cpp new file mode 100644 index 00000000000..3d934b4cf4f --- /dev/null +++ b/src/TMxpElementDefinitionHandler.cpp @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "TMxpElementDefinitionHandler.h" +#include "TMxpContext.h" +#include "TMxpTagParser.h" + +// +TMxpTagHandlerResult TMxpElementDefinitionHandler::handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) +{ + if (tag->getAttributesCount() < 2) { // UNEXPECTED: element without definition nor attributes + return MXP_TAG_NOT_HANDLED; + } + + TMxpElement el; + el.name = tag->getAttrName(0); // element-name + + if (tag->hasAttribute("DELETE")) { + ctx.getElementRegistry().unregisterElement(el.name); + return MXP_TAG_HANDLED; + } + + static const QStringList boolAttrs({"OPEN", "DELETE", "EMPTY"}); + if (!tag->getAttribute(1).hasValue()) { + const QString& secondAttr = tag->getAttrName(1); + if (!boolAttrs.contains(secondAttr, Qt::CaseInsensitive)) { // it is a definition and not {OPEN, DELETE, EMPTY} + el.definition = secondAttr; + } + } + + if (tag->hasAttribute("ATT")) { + el.attrs = tag->getAttributeValue("ATT").toLower().split(' ', QString::SkipEmptyParts); + } + + if (tag->hasAttribute("TAG")) { + el.tag = tag->getAttributeValue("TAG"); + } + + if (tag->hasAttribute("FLAG")) { + el.flags = tag->getAttributeValue("FLAG"); + } + + el.open = tag->hasAttribute("OPEN"); + el.empty = tag->hasAttribute("EMPTY"); + + if (!el.definition.isEmpty()) { + TMxpTagParser parser; + el.parsedDefinition = parser.parseToMxpNodeList(el.definition); + } + + ctx.getElementRegistry().registerElement(el); + + return MXP_TAG_HANDLED; +} diff --git a/src/TMxpElementDefinitionHandler.h b/src/TMxpElementDefinitionHandler.h new file mode 100644 index 00000000000..a9a3ff11f78 --- /dev/null +++ b/src/TMxpElementDefinitionHandler.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPELEMENTDEFINITIONHANDLER_H +#define MUDLET_TMXPELEMENTDEFINITIONHANDLER_H +#include "TMxpElementRegistry.h" +#include "TMxpTagHandler.h" + +// https://www.zuggsoft.com/zmud/mxp.htm#ELEMENT +// +class TMxpElementDefinitionHandler : public TMxpTagHandler +{ +public: + bool supports(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) override { return tag->isNamed("!EL") || tag->isNamed(("!ELEMENT")); } + + TMxpTagHandlerResult handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) override; +}; +#include "TMxpTagHandler.h" +#endif //MUDLET_TMXPELEMENTDEFINITIONHANDLER_H diff --git a/src/TMxpElementRegistry.cpp b/src/TMxpElementRegistry.cpp new file mode 100644 index 00000000000..c4a000f3216 --- /dev/null +++ b/src/TMxpElementRegistry.cpp @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TMxpElementRegistry.h" +void TMxpElementRegistry::registerElement(const TMxpElement& element) +{ + mMXP_Elements[element.name.toUpper()] = element; +} +bool TMxpElementRegistry::containsElement(const QString& name) const +{ + return mMXP_Elements.contains(name.toUpper()); +} + +TMxpElement TMxpElementRegistry::getElement(const QString& name) const +{ + return mMXP_Elements[name.toUpper()]; +} +void TMxpElementRegistry::unregisterElement(const QString& name) +{ + mMXP_Elements.remove(name.toUpper()); +} diff --git a/src/TMxpElementRegistry.h b/src/TMxpElementRegistry.h new file mode 100644 index 00000000000..ebf9a4a707f --- /dev/null +++ b/src/TMxpElementRegistry.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPELEMENTREGISTRY_H +#define MUDLET_TMXPELEMENTREGISTRY_H + +#include "MxpTag.h" +#include "pre_guard.h" +#include +#include +#include +#include +#include "post_guard.h" + +struct TMxpElement +{ + QString name; + QString definition; + QStringList attrs; + QString tag; + QString flags; + bool open; + bool empty; + + QString href; + QString hint; + + QList> parsedDefinition; +}; + +class TMxpElementRegistry +{ + QMap mMXP_Elements; + +public: + void registerElement(const TMxpElement& element); + void unregisterElement(const QString& name); + + bool containsElement(const QString& name) const; + TMxpElement getElement(const QString& name) const; +}; + +#endif //MUDLET_TMXPELEMENTREGISTRY_H diff --git a/src/TMxpEntityTagHandler.cpp b/src/TMxpEntityTagHandler.cpp new file mode 100644 index 00000000000..dbb3a74d1db --- /dev/null +++ b/src/TMxpEntityTagHandler.cpp @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "TMxpEntityTagHandler.h" +TMxpTagHandlerResult TMxpEntityTagHandler::handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) +{ + if (tag->getAttributesCount() < 2) { + return MXP_TAG_NOT_HANDLED; + } + + static const QStringList boolOptions({"PRIVATE", "PUBLISH", "DELETE", "ADD", "REMOVE"}); + TEntityResolver& resolver = ctx.getEntityResolver(); + + const QString& name = tag->getAttrName(1); + + if (tag->hasAttribute("DELETE")) { + resolver.unregisterEntity(name); + } else if (!boolOptions.contains(tag->getAttribute(1).getName(), Qt::CaseInsensitive)) { // 2nd attribute is actually the value + const QString& value = tag->getAttrName(1); + if (tag->hasAttribute("ADD")) { + QString newDefinition = resolver.getResolution(name); + newDefinition.append("|"); + newDefinition.append(value); + + resolver.registerEntity(name, newDefinition); + } else if (tag->hasAttribute("REMOVE")) { + QString currentValue = resolver.getResolution(name); + QString toDelete = currentValue.contains("|") ? "|" + value : value; + resolver.registerEntity(name, currentValue.replace(toDelete, "")); + } else { // PUBLISH + resolver.registerEntity(name, value); + client.publishEntity(name, value); + } + } + + return MXP_TAG_HANDLED; +} diff --git a/src/TMxpEntityTagHandler.h b/src/TMxpEntityTagHandler.h new file mode 100644 index 00000000000..9f66907fa20 --- /dev/null +++ b/src/TMxpEntityTagHandler.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef MUDLET_TENTITYTAGHANDLER_H +#define MUDLET_TENTITYTAGHANDLER_H + + +#include "TMxpClient.h" +#include "TMxpContext.h" +#include "TMxpTagHandler.h" + +// +class TMxpEntityTagHandler : public TMxpTagHandler +{ +public: + bool supports(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) override { + return tag->isNamed("!ENTITY") || tag->isNamed("!EN"); + } + + TMxpTagHandlerResult handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) override; +}; + + +#endif //MUDLET_TENTITYTAGHANDLER_H diff --git a/src/TMxpEvent.h b/src/TMxpEvent.h new file mode 100644 index 00000000000..8c71ae10cac --- /dev/null +++ b/src/TMxpEvent.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPEVENT_H +#define MUDLET_TMXPEVENT_H + +#include "pre_guard.h" +#include +#include +#include "post_guard.h" + +struct TMxpEvent +{ + QString name; + QMap attrs; + QStringList actions; +}; + +#endif //MUDLET_TMXPEVENT_H diff --git a/src/TMxpFontTagHandler.cpp b/src/TMxpFontTagHandler.cpp new file mode 100644 index 00000000000..5633eea79a3 --- /dev/null +++ b/src/TMxpFontTagHandler.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TMxpFontTagHandler.h" +#include "TMxpClient.h" + +TMxpTagHandlerResult TMxpFontTagHandler::handleStartTag(TMxpContext& context, TMxpClient& client, MxpStartTag* tag) +{ + QString fontFace = tag->getAttributeByNameOrIndex("FACE", 0); + QString fontSize = tag->getAttributeByNameOrIndex("SIZE", 1); + client.pushFont(fontFace, fontSize); + + QString fgColor = tag->getAttributeByNameOrIndex("COLOR", 2); + QString bgColor = tag->getAttributeByNameOrIndex("BACK", 3); + client.pushColor(fgColor, bgColor); + + return MXP_TAG_HANDLED; +} +TMxpTagHandlerResult TMxpFontTagHandler::handleEndTag(TMxpContext& context, TMxpClient& client, MxpEndTag* tag) +{ + client.popFont(); + client.popColor(); + + return MXP_TAG_HANDLED; +} diff --git a/src/TMxpFontTagHandler.h b/src/TMxpFontTagHandler.h new file mode 100644 index 00000000000..d9f234cbd6c --- /dev/null +++ b/src/TMxpFontTagHandler.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPFONTTAGHANDLER_H +#define MUDLET_TMXPFONTTAGHANDLER_H +#include "TMxpTagHandler.h" + +// +class TMxpFontTagHandler : public TMxpSingleTagHandler +{ +public: + TMxpFontTagHandler() : TMxpSingleTagHandler("FONT") {} + + TMxpTagHandlerResult handleStartTag(TMxpContext &context, TMxpClient& client, MxpStartTag* tag) override; + + TMxpTagHandlerResult handleEndTag(TMxpContext &context, TMxpClient& client, MxpEndTag* tag) override; +}; +#include "TMxpTagHandler.h" +#endif //MUDLET_TMXPFONTTAGHANDLER_H diff --git a/src/TMxpFormattingTagsHandler.cpp b/src/TMxpFormattingTagsHandler.cpp new file mode 100644 index 00000000000..0b9a52613bc --- /dev/null +++ b/src/TMxpFormattingTagsHandler.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "TMxpFormattingTagsHandler.h" +#include "TMxpClient.h" + +bool TMxpFormattingTagsHandler::supports(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) +{ + return tag->isNamed("B") || tag->isNamed("I") || tag->isNamed("U"); +} +TMxpTagHandlerResult TMxpFormattingTagsHandler::handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) +{ + setAttribute(client, tag, true); + + return MXP_TAG_HANDLED; +} +TMxpTagHandlerResult TMxpFormattingTagsHandler::handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) +{ + setAttribute(client, tag, false); + + return MXP_TAG_HANDLED; +} +void TMxpFormattingTagsHandler::setAttribute(TMxpClient& client, MxpTag* tag, bool value) const +{ + if (tag->isNamed("B")) { + client.setBold(value); + } else if (tag->isNamed("I")) { + client.setItalic(value); + } else if (tag->isNamed("U")) { + client.setUnderline(value); + } else { + // do nothing + } +} diff --git a/src/TMxpFormattingTagsHandler.h b/src/TMxpFormattingTagsHandler.h new file mode 100644 index 00000000000..7ac79e1e819 --- /dev/null +++ b/src/TMxpFormattingTagsHandler.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPFORMATTINGTAGSHANDLER_H +#define MUDLET_TMXPFORMATTINGTAGSHANDLER_H + +#include "TMxpTagHandler.h" + +class TMxpFormattingTagsHandler : public TMxpTagHandler +{ +public: + bool supports(TMxpContext& ctx, TMxpClient& client, MxpTag* tag); + + TMxpTagHandlerResult handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) override; + + TMxpTagHandlerResult handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) override; + + void setAttribute(TMxpClient& client, MxpTag* tag, bool value) const; +}; + +#endif //MUDLET_TMXPFORMATTINGTAGSHANDLER_H diff --git a/src/TMxpLinkTagHandler.cpp b/src/TMxpLinkTagHandler.cpp new file mode 100644 index 00000000000..a30d0487b35 --- /dev/null +++ b/src/TMxpLinkTagHandler.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "TMxpLinkTagHandler.h" +#include "TMxpClient.h" + +// +TMxpTagHandlerResult TMxpLinkTagHandler::handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) +{ + if (tag->hasAttribute("EXPIRE")) { + return MXP_TAG_NOT_HANDLED; + } + + QString href = getHref(tag); + if (href.isEmpty()) { + return MXP_TAG_NOT_HANDLED; + } + + QString hint = tag->hasAttribute("hint") ? tag->getAttributeValue("hint") : href; + + href = QStringLiteral("openUrl([[%1]])").arg(href); + + mLinkId = client.setLink(QStringList(href), QStringList(hint)); + client.setLinkMode(true); + return MXP_TAG_HANDLED; +} +TMxpTagHandlerResult TMxpLinkTagHandler::handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) +{ + QStringList *links, *hints; + if (!client.getLink(mLinkId, &links, &hints)) { + return MXP_TAG_NOT_HANDLED; + } + + if (links != nullptr) { + links->replaceInStrings("&text;", mCurrentTagContent, Qt::CaseInsensitive); + } + + client.setLinkMode(false); + return MXP_TAG_HANDLED; +} +QString TMxpLinkTagHandler::getHref(const MxpStartTag* tag) +{ + if (tag->getAttributesCount() == 0) { + // http://someurl.com/ + mIsHrefInContent = true; + return "&text;"; + } else if (tag->hasAttribute("href")) { + return tag->getAttributeValue("href"); + } else if (!tag->getAttribute(0).hasValue()) { + return tag->getAttribute(0).getName(); + } else { + return ""; + } +} +void TMxpLinkTagHandler::handleContent(char ch) +{ + if (mIsHrefInContent) { + mCurrentTagContent.append(ch); + } +} diff --git a/src/TMxpLinkTagHandler.h b/src/TMxpLinkTagHandler.h new file mode 100644 index 00000000000..c6db4f98a6f --- /dev/null +++ b/src/TMxpLinkTagHandler.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef MUDLET_TMXPLINKTAGHANDLER_H +#define MUDLET_TMXPLINKTAGHANDLER_H +#include "TMxpTagHandler.h" + +// +class TMxpLinkTagHandler : public TMxpSingleTagHandler +{ + bool mIsHrefInContent; + QString mCurrentTagContent; + int mLinkId; + + QString getHref(const MxpStartTag* tag); + +public: + TMxpLinkTagHandler() : TMxpSingleTagHandler("A"), mIsHrefInContent(false), mLinkId(0) {} + + TMxpTagHandlerResult handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) override; + TMxpTagHandlerResult handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) override; + + void handleContent(char ch) override; +}; +#include "TMxpTagHandler.h" +#endif //MUDLET_TMXPLINKTAGHANDLER_H diff --git a/src/TMxpMudlet.cpp b/src/TMxpMudlet.cpp new file mode 100644 index 00000000000..2a89232507d --- /dev/null +++ b/src/TMxpMudlet.cpp @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TMxpMudlet.h" +#include "Host.h" +#include "TConsole.h" +#include "TLinkStore.h" + + +TMxpMudlet::TMxpMudlet(Host* pHost) : mpHost(pHost), mLinkMode(false) {} + +QString TMxpMudlet::getVersion() +{ + return scmVersion; +} +void TMxpMudlet::sendToServer(QString& str) +{ + mpHost->mTelnet.sendData(str); +} +void TMxpMudlet::pushColor(const QString& fgColor, const QString& bgColor) +{ + pushColor(fgColors, fgColor); + pushColor(bgColors, bgColor); +} +void TMxpMudlet::popColor() +{ + popColor(fgColors); + popColor(bgColors); +} +void TMxpMudlet::pushColor(QList& stack, const QString& color) +{ + if (color.isEmpty()) { + if (!stack.isEmpty()) { + stack.push_back(stack.last()); + } + } else { + stack.push_back(QColor(color)); + } +} +void TMxpMudlet::popColor(QList& stack) +{ + if (!stack.isEmpty()) { + stack.pop_back(); + } +} +int TMxpMudlet::setLink(const QStringList& links, const QStringList& hints) +{ + return getLinkStore().addLinks(links, hints); +} +bool TMxpMudlet::getLink(int id, QStringList** links, QStringList** hints) +{ + *links = &getLinkStore().getLinks(id); + *hints = &getLinkStore().getHints(id); + + return true; +} +TMxpTagHandlerResult TMxpMudlet::tagHandled(MxpTag* tag, TMxpTagHandlerResult result) +{ + if (tag->isStartTag()) { + if (mpContext->getElementRegistry().containsElement(tag->getName())) { + enqueueMxpEvent(tag->asStartTag()); + } else if (tag->isNamed("SEND")) { + enqueueMxpEvent(tag->asStartTag()); + } + } + + return result; +} +void TMxpMudlet::enqueueMxpEvent(MxpStartTag* tag) +{ + TMxpEvent ev; + ev.name = tag->getName(); + for (const auto& attrName : tag->getAttributesNames()) { + ev.attrs[attrName] = tag->getAttributeValue(attrName); + } + ev.actions = getLinkStore().getCurrentLinks(); + mMxpEvents.enqueue(ev); +} +TLinkStore& TMxpMudlet::getLinkStore() +{ + return mpHost->mpConsole->getLinkStore(); +} diff --git a/src/TMxpMudlet.h b/src/TMxpMudlet.h new file mode 100644 index 00000000000..cf84383085f --- /dev/null +++ b/src/TMxpMudlet.h @@ -0,0 +1,101 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef MUDLET_TMXPMUDLET_H +#define MUDLET_TMXPMUDLET_H + +#include "TEntityResolver.h" +#include "TLinkStore.h" +#include "TMxpClient.h" +#include "TMxpEvent.h" + +#include "pre_guard.h" +#include +#include +#include "post_guard.h" + +class Host; + +class TMxpMudlet : public TMxpClient +{ + inline static const QString scmVersion = QStringLiteral("%1%2").arg(QString::fromLatin1(APP_VERSION), QString::fromLatin1(APP_BUILD)); + + Host* mpHost; + + bool mLinkMode; + +public: + // Shouldn't be here, look for a better solution + QQueue mMxpEvents; + + TMxpMudlet(Host* pHost); + + QString getVersion() override; + + void sendToServer(QString& str) override; + + void setLinkMode(bool val) override { mLinkMode = val; } + + bool isInLinkMode() const { return mLinkMode; } + + QList fgColors, bgColors; + void pushColor(const QString& fgColor, const QString& bgColor) override; + + void popColor() override; + + void pushColor(QList& stack, const QString& color); + + void popColor(QList& stack); + + bool hasFgColor() const { return !fgColors.isEmpty(); } + const QColor& getFgColor() { return fgColors.last(); } + + bool hasBgColor() const { return !bgColors.isEmpty(); } + + const QColor& getBgColor() { return bgColors.last(); } + + // TODO: implement support for fonts? + void pushFont(const QString& fontFace, const QString& fontSize) override {} + void popFont() override {} + + int setLink(const QStringList& links, const QStringList& hints) override; + + bool getLink(int id, QStringList** links, QStringList** hints) override; + + bool isBold, isItalic, isUnderline; + + void setBold(bool bold) override { isBold = bold; } + void setItalic(bool italic) override { isItalic = italic; } + void setUnderline(bool underline) override { isUnderline = underline; } + + void setFlag(const QString& elementName, const QMap& values, const QString& content) override + { + // TODO: raise mxp event + } + + void publishEntity(const QString& name, const QString& value) override {} + + void setVariable(const QString& name, const QString& value) override {} + + TMxpTagHandlerResult tagHandled(MxpTag* tag, TMxpTagHandlerResult result) override; + + void enqueueMxpEvent(MxpStartTag* tag); + TLinkStore& getLinkStore(); +}; + +#endif //MUDLET_TMXPMUDLET_H diff --git a/src/TMxpNodeBuilder.cpp b/src/TMxpNodeBuilder.cpp new file mode 100644 index 00000000000..30e0d73efff --- /dev/null +++ b/src/TMxpNodeBuilder.cpp @@ -0,0 +1,210 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "TMxpNodeBuilder.h" +#include "TMxpTagParser.h" +#include "TStringUtils.h" + +bool TMxpNodeBuilder::accept(char ch) +{ + if (mIsInsideTag) { // inside tag + mCurrentText.clear(); + mIsText = false; + + if (!acceptTag(ch)) { + return false; + } else { + mIsInsideTag = false; + return true; + } + } else if (ch == '<') { // start tag + if (mIsInsideText) { + mIsInsideText = false; + mIsText = true; + mHasNode = true; + return true; + } else { // second call + mHasNode = false; //mIsText = false + return acceptTag(ch); + } + } else if (!mOptionIgnoreText) { // text + mIsInsideText = true; + mCurrentText.append(ch); + return false; + } + + return false; +} +bool TMxpNodeBuilder::acceptTag(char ch) +{ + if (mHasNode) { + mHasNode = false; + return true; + } + + if (mIsInsideAttr) { + if (!acceptAttribute(ch)) { + return false; + } else { + if (!mCurrentAttrName.isEmpty()) { + processAttribute(); + } + resetCurrentAttribute(); + } + } + + if (QChar(ch).isSpace()) + return false; + + if (ch == '<') { // reset + resetCurrentTag(); + mIsInsideTag = true; + return false; + } + + if (ch == '/') { + mIsEndTag = mCurrentTagName.isEmpty(); + mIsEmptyTag = !mIsEndTag; + return false; + } + + if (ch == '>') { + processAttribute(); + mHasNode = true; + return false; + } + + if (!acceptAttribute(ch)) + return false; + + return false; +} +void TMxpNodeBuilder::processAttribute() +{ + if (mCurrentTagName.isEmpty()) { + mCurrentTagName = mCurrentAttrName; + } else if (!mCurrentAttrName.isEmpty()) { + mCurrentTagAttrs.append(MxpTagAttribute(mCurrentAttrName, mCurrentAttrValue)); + } +} +void TMxpNodeBuilder::resetCurrentTag() +{ + mHasNode = false; + mIsEndTag = false; + mIsEmptyTag = false; + mIsInsideTag = false; + mCurrentTagName.clear(); + mCurrentTagAttrs.clear(); + + resetCurrentAttribute(); +} +bool TMxpNodeBuilder::acceptAttribute(char ch) +{ + mIsInsideAttr = true; + + QString& buffer = mReadingAttrValue ? mCurrentAttrValue : mCurrentAttrName; + if (!acceptSequence(ch, buffer)) { + return false; + } + + resetCurrentSequence(); + + if (ch == '=') { + mReadingAttrValue = true; + return false; + } else { + return true; + } +} +void TMxpNodeBuilder::resetCurrentAttribute() +{ + mCurrentAttrName.clear(); + mCurrentAttrValue.clear(); + + mReadingAttrValue = false; + + mIsInsideAttr = false; + resetCurrentSequence(); +} +bool TMxpNodeBuilder::acceptSequence(char ch, QString& buffer) +{ + if (mHasSequence) { + mHasSequence = false; + return true; + } + + if (TStringUtils::isQuote(ch)) { + if (!mIsInsideSequence) { + mIsInsideSequence = true; + mIsQuotedSequence = true; + mOpeningQuote = ch; + return false; + } else if (mIsQuotedSequence && ch == mOpeningQuote) { + mHasSequence = true; + return false; + } + } + + if (!mIsQuotedSequence) { + if (QChar(ch).isSpace()) { + mHasSequence = true; + return false; + } else if (ch == '>' || ch == '/' || ch == '=') { + return true; + } + } + + if (mIsQuotedSequence && !mSequenceHasSpaces && ch == '=') { + return true; + } + + if (!mIsInsideSequence) { + mIsInsideSequence = true; + } + + mSequenceHasSpaces = mSequenceHasSpaces || QChar(ch).isSpace(); + + buffer.append(ch); + return false; +} +void TMxpNodeBuilder::resetCurrentSequence() +{ + mSequenceHasSpaces = false; + mIsQuotedSequence = false; + mIsInsideSequence = false; + mHasSequence = false; +} +MxpTag* TMxpNodeBuilder::buildTag() +{ + MxpTag* result = mIsEndTag ? static_cast(new MxpEndTag(mCurrentTagName)) : static_cast(new MxpStartTag(mCurrentTagName, mCurrentTagAttrs, mIsEmptyTag)); + resetCurrentTag(); + + return result; +} +MxpNode* TMxpNodeBuilder::buildNode() +{ + MxpNode* node = mIsText ? static_cast(new MxpTextNode(mCurrentText)) : static_cast(buildTag()); + mCurrentText.clear(); + mHasNode = false; + return node; +} +void TMxpNodeBuilder::reset() +{ + resetCurrentTag(); + mCurrentText.clear(); +} diff --git a/src/TMxpNodeBuilder.h b/src/TMxpNodeBuilder.h new file mode 100644 index 00000000000..ec96ae218f6 --- /dev/null +++ b/src/TMxpNodeBuilder.h @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef MUDLET_TMXPNODEBUILDER_H +#define MUDLET_TMXPNODEBUILDER_H + +#include "MxpTag.h" +#include "TStringUtils.h" + +#include "pre_guard.h" +#include +#include "post_guard.h" + +class TMxpNodeBuilder +{ + bool mOptionIgnoreText; + + // current tag attrs + QString mCurrentTagName; + QList mCurrentTagAttrs; + bool mIsEndTag; + bool mIsEmptyTag; + // parsing tag state + bool mIsInsideTag; + + // current attr + QString mCurrentAttrName; + QString mCurrentAttrValue; + // parsing attr state + bool mIsInsideAttr; + bool mReadingAttrValue; + + // text sequence state + bool mIsInsideSequence; + bool mIsQuotedSequence; + char mOpeningQuote; + bool mSequenceHasSpaces; + bool mHasSequence; + + // current text node + QString mCurrentText; + + // text node parsing state + bool mIsInsideText; + + // overall processing state + bool mHasNode; // a node is ready to be consumed + bool mIsText; // the current node is a text node + + bool acceptTag(char ch); + void resetCurrentTag(); + + bool acceptAttribute(char ch); + void resetCurrentAttribute(); + + bool acceptSequence(char ch, QString& buffer); + void resetCurrentSequence(); + void processAttribute(); + +public: + explicit TMxpNodeBuilder(bool ignoreText = false) + : mOptionIgnoreText(ignoreText) + , mIsInsideTag(false) + , mHasNode(false) + , mIsInsideAttr(false) + , mIsInsideSequence(false) + , mHasSequence(false) + , mIsQuotedSequence(false) + , mIsText(false) + , mIsInsideText(false) + { + } + + // returns true when a node (text/tag start/tag end) is available + // the same char has to be input again when a match is found as it may be a boundary + // and the class keeps no buffer of it + bool accept(char ch); + + MxpNode* buildNode(); + MxpTag* buildTag(); + + void reset(); + + inline bool hasTag() const { return isTag() && hasNode(); } + + inline bool hasNode() const { return mHasNode; } + + inline bool isInsideTag() const { return mIsInsideTag; } + + inline bool isTag() const { return !mIsText; } + + inline bool isText() const { return mIsText; } +}; +#endif //MUDLET_TMXPNODEBUILDER_H diff --git a/src/TMxpProcessor.cpp b/src/TMxpProcessor.cpp new file mode 100644 index 00000000000..b6e07c60a7c --- /dev/null +++ b/src/TMxpProcessor.cpp @@ -0,0 +1,161 @@ +/*************************************************************************** + * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * + * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * + * Copyright (C) 2014-2018 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TMxpProcessor.h" +#include "pre_guard.h" +#include +#include "post_guard.h" + +bool TMxpProcessor::setMode(const QString& code) +{ + bool isOk = false; + int modeCode = code.toInt(&isOk); + if (isOk) { + return setMode(modeCode); + } else { + // isOk is false here as toInt(...) failed + qDebug().noquote().nospace() << "TMxpProcessor::setMode(...) INFO - Non-numeric MXP control sequence CSI " << code << " z received, Mudlet will ignore it."; + return false; + } +} + +/* + * The documentation at https://www.zuggsoft.com/zmud/mxp.htm says: " + * * 0 - OPEN LINE - initial default mode: only MXP commands in the 'open' + * category are allowed. When a newline is received from the MUD, the + * mode reverts back to the Default mode. OPEN mode starts as the + * default mode until changes with one of the 'lock mode' tags listed + * below. + * * 1 - SECURE LINE (until next newline) all tags and commands in MXP are + * allowed within the line. When a newline is received from the MUD, + * the mode reverts back to the Default mode. + * * 2 - LOCKED LINE (until next newline) no MXP or HTML commands are + * allowed in the line. The line is not parsed for any tags at all. + * This is useful for "verbatim" text output from the MUD. When a + * newline is received from the MUD, the mode reverts back to the + * Default mode. + * The following additional modes were added to the v0.4 MXP spec: + * * 3 - RESET close all open tags. Set mode to Open. Set text color and + * properties to default. + * * 4 - TEMP SECURE MODE set secure mode for the next tag only. Must be + * immediately followed by a < character to start a tag. Remember to + * set secure mode when closing the tag also. + * * 5 - LOCK OPEN MODE set open mode. Mode remains in effect until + * changed. OPEN mode becomes the new default mode. + * * 6 - LOCK SECURE MODE set secure mode. Mode remains in effect until + * changed. Secure mode becomes the new default mode. + * * 7 - LOCK LOCKED MODE set locked mode. Mode remains in effect until + * changed. Locked mode becomes the new default mode." + */ +bool TMxpProcessor::setMode(int modeCode) +{ + // we really do not handle these well... + // MXP line modes - comments are from http://www.zuggsoft.com/zmud/mxp.htm#MXP%20Line%20TagsmMXP = true; // some servers don't negotiate, they assume! + + mMXP = true; + switch (modeCode) { + case 0: // open line - only MXP commands in the "open" category are allowed. When a newline is received from the MUD, the mode reverts back to the Default mode. OPEN MODE starts as the Default mode until changes with one of the "lock mode" tags listed below. + mMXP_MODE = MXP_MODE_OPEN; + break; + case 1: // secure line (until next newline) all tags and commands in MXP are allowed within the line. When a newline is received from the MUD, the mode reverts back to the Default mode. + mMXP_MODE = MXP_MODE_SECURE; + break; + case 2: // locked line (until next newline) no MXP or HTML commands are allowed in the line. The line is not parsed for any tags at all. This is useful for "verbatim" text output from the MUD. When a newline is received from the MUD, the mode reverts back to the Default mode. + mMXP_MODE = MXP_MODE_LOCKED; + break; + case 3: // reset (MXP 0.4 or later) - close all open tags. Set mode to Open. Set text color and properties to default. + mMxpTagBuilder.reset(); + mMXP_MODE = mMXP_DEFAULT; + break; + case 4: // temp secure mode (MXP 0.4 or later) - set secure mode for the next tag only. Must be immediately followed by a < character to start a tag. Remember to set secure mode when closing the tag also. + mMXP_MODE = MXP_MODE_TEMP_SECURE; + break; + case 5: // lock open mode (MXP 0.4 or later) - set open mode. Mode remains in effect until changed. OPEN mode becomes the new default mode. + mMXP_DEFAULT = mMXP_MODE = MXP_MODE_OPEN; + break; + case 6: // lock secure mode (MXP 0.4 or later) - set secure mode. Mode remains in effect until changed. Secure mode becomes the new default mode. + mMXP_DEFAULT = mMXP_MODE = MXP_MODE_SECURE; + break; + case 7: // lock locked mode (MXP 0.4 or later) - set locked mode. Mode remains in effect until changed. Locked mode becomes the new default mode. + mMXP_DEFAULT = mMXP_MODE = MXP_MODE_LOCKED; + break; + default: + qDebug().noquote().nospace() << "TMxpProcessor::setMode(...) INFO - Unhandled MXP control sequence CSI " << QString::number(modeCode) << " z received, Mudlet will ignore it."; + return false; + } + + return true; +} +TMXPMode TMxpProcessor::mode() const +{ + return mMXP_MODE; +} +bool TMxpProcessor::isEnabled() const +{ + return mMXP; +} + +void TMxpProcessor::resetToDefaultMode() +{ + mMXP_MODE = mMXP_DEFAULT; +} + +void TMxpProcessor::enable() +{ + mMXP = true; +} + +TMxpProcessingResult TMxpProcessor::processMxpInput(char& ch) +{ + if (!mMxpTagBuilder.accept(ch) && mMxpTagBuilder.isInsideTag() && !mMxpTagBuilder.hasTag()) { + return HANDLER_NEXT_CHAR; + } + + if (mMxpTagBuilder.hasTag()) { + QScopedPointer tag(mMxpTagBuilder.buildTag()); + + // qDebug() << "TAG RECEIVED: " << tag->asString(); + if (mMXP_MODE == MXP_MODE_TEMP_SECURE) { + mMXP_MODE = mMXP_DEFAULT; + } + + TMxpTagHandlerResult result = mMxpTagProcessor.handleTag(mMxpTagProcessor, *mpMxpClient, tag.get()); + return result == MXP_TAG_COMMIT_LINE ? HANDLER_COMMIT_LINE : HANDLER_NEXT_CHAR; + } + + if (mEntityHandler.handle(ch)) { // ch is part of an entity + if (mEntityHandler.isEntityResolved()) { // entity has been mapped (i.e. ch == ';') + ch = mEntityHandler.getResultAndReset(); + } else { // ask for the next char + return HANDLER_NEXT_CHAR; + } + } + + mMxpTagProcessor.handleContent(ch); + + return HANDLER_FALL_THROUGH; +} + +void TMxpProcessor::processRawInput(char ch) +{ + mMxpTagProcessor.handleContent(ch); +} diff --git a/src/TMxpProcessor.h b/src/TMxpProcessor.h new file mode 100644 index 00000000000..904c3ae32fd --- /dev/null +++ b/src/TMxpProcessor.h @@ -0,0 +1,71 @@ +#ifndef MUDLET_TMXPPROCESSOR_H +#define MUDLET_TMXPPROCESSOR_H + +/*************************************************************************** + * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * + * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * + * Copyright (C) 2014-2018 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TEntityHandler.h" +#include "TMxpNodeBuilder.h" +#include "TMxpTagProcessor.h" + +class Host; + +enum TMXPMode { MXP_MODE_OPEN, MXP_MODE_SECURE, MXP_MODE_LOCKED, MXP_MODE_TEMP_SECURE }; +enum TMxpProcessingResult { HANDLER_FALL_THROUGH, HANDLER_NEXT_CHAR, HANDLER_COMMIT_LINE }; + +// handles the MXP protocol +class TMxpProcessor +{ + // State of MXP system: + bool mMXP; + TMXPMode mMXP_MODE; + TMXPMode mMXP_DEFAULT; + + // MXP delegated handlers + TMxpNodeBuilder mMxpTagBuilder; + TMxpTagProcessor mMxpTagProcessor; + TEntityHandler mEntityHandler; + + TMxpClient* mpMxpClient; + +public: + explicit TMxpProcessor(TMxpClient* pMxpClient) + : mMXP(false) + , mMXP_MODE(MXP_MODE_OPEN), mMXP_DEFAULT(MXP_MODE_OPEN) + , mMxpTagBuilder(true), mEntityHandler(mMxpTagProcessor.getEntityResolver()), mpMxpClient(pMxpClient) + { + mpMxpClient->initialize(&mMxpTagProcessor); + } + + bool setMode(const QString& code); + bool setMode(int modeCode); + TMXPMode mode() const; + + void enable(); + bool isEnabled() const; + void resetToDefaultMode(); + + TMxpProcessingResult processMxpInput(char& ch); + void processRawInput(char ch); +}; + +#endif //MUDLET_TMXPPROCESSOR_H diff --git a/src/TMxpSendTagHandler.cpp b/src/TMxpSendTagHandler.cpp new file mode 100644 index 00000000000..1d85b424452 --- /dev/null +++ b/src/TMxpSendTagHandler.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "TMxpSendTagHandler.h" +#include "TMxpClient.h" +#include "TStringUtils.h" + +TMxpSendTagHandler::TMxpSendTagHandler() : TMxpSingleTagHandler("SEND"), mLinkId(0), mIsHrefInContent(false) {} +TMxpTagHandlerResult TMxpSendTagHandler::handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) +{ + // if (tag->hasAttr("EXPIRE") && tag->getAttr(0).isNamed("EXPIRE")) + // return MXP_TAG_NOT_HANDLED; + + QString href = extractHref(tag); + QString hint = extractHint(tag); + + if (href.contains(TAG_CONTENT_PLACEHOLDER, Qt::CaseInsensitive) || hint.contains(TAG_CONTENT_PLACEHOLDER, Qt::CaseInsensitive)) { + mIsHrefInContent = true; + } + + QStringList hrefs = href.split('|'); + QStringList hints = hint.isEmpty() ? hrefs : hint.split('|'); + + while (hints.size() > hrefs.size()) { + hints.removeFirst(); + } + + // handle print to prompt feature PROMPT + // Zugg + QString command = tag->hasAttribute(ATTR_PROMPT) ? QStringLiteral("printCmdLine") : QStringLiteral("send"); + + for (int i = 0; i < hrefs.size(); i++) { + hrefs[i] = ctx.getEntityResolver().interpolate(hrefs[i]); + hrefs[i] = QStringLiteral("%1([[%2]])").arg(command, hrefs[i]); + + hints[i] = ctx.getEntityResolver().interpolate(hints[i]); + } + + mLinkId = client.setLink(hrefs, hints); + + client.setLinkMode(true); + + return MXP_TAG_HANDLED; +} +QString TMxpSendTagHandler::extractHref(MxpStartTag* tag) +{ + if (tag->getAttributesCount() == 0) { + // buy bread + return TAG_CONTENT_PLACEHOLDER; + } + + if (tag->hasAttribute(ATTR_HREF)) { + // '> + // bread + // + // A shining sword of Lewshire + return tag->getAttributeValue(ATTR_HREF); + } + + if (!tag->getAttribute(0).isNamed(ATTR_PROMPT) && !tag->getAttribute(0).isNamed(ATTR_HINT) && !tag->getAttribute(0).isNamed(ATTR_EXPIRE)) { + // has one attribute, but not called href + // Zugg + // fountain + return tag->getAttrName(0); + } + + return TAG_CONTENT_PLACEHOLDER; +} + +QString TMxpSendTagHandler::extractHint(MxpStartTag* tag) +{ + if (tag->hasAttribute(ATTR_HINT)) { + return tag->getAttributeValue(ATTR_HINT); + } else if (tag->getAttributesCount() > 1 && !tag->getAttribute(1).isNamed(ATTR_PROMPT) && !tag->getAttribute(1).isNamed(ATTR_EXPIRE)) { + return tag->getAttrName(1); + } + + return QString(); +} + +TMxpTagHandlerResult TMxpSendTagHandler::handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) +{ + if (mIsHrefInContent) { + updateHrefInLinks(client); + } + + resetCurrentTagContent(client); + return MXP_TAG_HANDLED; +} + +void TMxpSendTagHandler::resetCurrentTagContent(TMxpClient& client) +{ + mIsHrefInContent = false; + mCurrentTagContent.clear(); + client.setLinkMode(false); +} + +void TMxpSendTagHandler::updateHrefInLinks(TMxpClient& client) const +{ + QStringList *hrefs, *hints; + if (client.getLink(mLinkId, &hrefs, &hints)) { + if (hrefs != nullptr) { + hrefs->replaceInStrings(TAG_CONTENT_PLACEHOLDER, mCurrentTagContent, Qt::CaseInsensitive); + } + + if (hints != nullptr) { + hints->replaceInStrings(TAG_CONTENT_PLACEHOLDER, mCurrentTagContent, Qt::CaseInsensitive); + } + } +} +void TMxpSendTagHandler::handleContent(char ch) +{ + if (mIsHrefInContent) { + mCurrentTagContent.append(ch); + } +} diff --git a/src/TMxpSendTagHandler.h b/src/TMxpSendTagHandler.h new file mode 100644 index 00000000000..e4a7b12a8d5 --- /dev/null +++ b/src/TMxpSendTagHandler.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPSENDTAGHANDLER_H +#define MUDLET_TMXPSENDTAGHANDLER_H +#include "TEntityResolver.h" +#include "TMxpTagHandler.h" + +// +class TMxpSendTagHandler : public TMxpSingleTagHandler +{ + inline static const QString ATTR_HREF = QStringLiteral("href"); + inline static const QString ATTR_HINT = QStringLiteral("hint"); + inline static const QString ATTR_PROMPT = QStringLiteral("prompt"); + inline static const QString ATTR_EXPIRE = QStringLiteral("expire"); + inline static const QString TAG_CONTENT_PLACEHOLDER = QStringLiteral("&text;"); + + bool mIsHrefInContent; + QString mCurrentTagContent; + int mLinkId; + + void updateHrefInLinks(TMxpClient& client) const; + void resetCurrentTagContent(TMxpClient& client); +public: + static QString extractHref(MxpStartTag* tag); + static QString extractHint(MxpStartTag* tag); + + TMxpSendTagHandler(); + TMxpTagHandlerResult handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) override; + TMxpTagHandlerResult handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) override; + + void handleContent(char ch) override; + +}; +#include "TMxpTagHandler.h" +#endif //MUDLET_TMXPSENDTAGHANDLER_H diff --git a/src/TMxpSupportTagHandler.cpp b/src/TMxpSupportTagHandler.cpp new file mode 100644 index 00000000000..193889a3a31 --- /dev/null +++ b/src/TMxpSupportTagHandler.cpp @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * + * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * + * Copyright (C) 2014-2018 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +#include "TMxpSupportTagHandler.h" +#include "TMxpClient.h" +#include "TMxpContext.h" + +TMxpTagHandlerResult TMxpSupportTagHandler::handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) +{ + const QString& supportOptions = processSupportsRequest(ctx, tag); + + QString payload = QStringLiteral("\n\x1b[1z\n").arg(supportOptions); + client.sendToServer(payload); + + return MXP_TAG_HANDLED; +} +QString TMxpSupportTagHandler::processSupportsRequest(TMxpContext& ctx, MxpStartTag* tag) +{ + const auto& supportedMxpElements = ctx.getSupportedElements(); + // strip initial SUPPORT and tokenize all of the requested elements + QStringList result; + + auto reportEntireElement = [](auto element, auto& result, auto& mSupportedMxpElements) { + result.append("+" + element); + + for (const auto& attribute : mSupportedMxpElements.value(element)) { + result.append("+" + element + QStringLiteral(".") + attribute); + } + + return result; + }; + + auto reportAllElements = [reportEntireElement](auto& result, auto& mSupportedMxpElements) { + auto elementsIterator = mSupportedMxpElements.constBegin(); + while (elementsIterator != mSupportedMxpElements.constEnd()) { + result = reportEntireElement(elementsIterator.key(), result, mSupportedMxpElements); + ++elementsIterator; + } + + return result; + }; + + // empty - report all known elements + if (tag->getAttributesCount() == 0) { + result = reportAllElements(result, supportedMxpElements); + } else { + // otherwise it's + for (auto& element : tag->getAttributesNames()) { + if (!element.contains(QChar('.'))) { + if (supportedMxpElements.contains(element)) { + result = reportEntireElement(element, result, supportedMxpElements); + } else { + result.append("-" + element); + } + } else { + auto elementName = element.section(QChar('.'), 0, 0); + auto attributeName = element.section(QChar('.'), 1, 1); + + if (!supportedMxpElements.contains(elementName)) { + result.append("-" + element); + } else if (attributeName == QLatin1String("*")) { + result = reportEntireElement(elementName, result, supportedMxpElements); + } else { + if (supportedMxpElements.value(elementName).contains(attributeName)) { + result.append("+" + elementName + "." + attributeName); + } else { + result.append("-" + elementName + "." + attributeName); + } + } + } + } + } + + return result.join(QLatin1String(" ")); +} diff --git a/src/TMxpSupportTagHandler.h b/src/TMxpSupportTagHandler.h new file mode 100644 index 00000000000..a9b6db8d3f8 --- /dev/null +++ b/src/TMxpSupportTagHandler.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +#ifndef MUDLET_TMXPSUPPORTTAGHANDLER_H +#define MUDLET_TMXPSUPPORTTAGHANDLER_H + +#include "TMxpTagHandler.h" + +class TMxpSupportTagHandler : public TMxpSingleTagHandler +{ +public: + QString processSupportsRequest(TMxpContext& ctx, MxpStartTag* tag); + + explicit TMxpSupportTagHandler() : TMxpSingleTagHandler("SUPPORT") {} + + TMxpTagHandlerResult handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) override; +}; +#endif //MUDLET_TMXPSUPPORTTAGHANDLER_H diff --git a/src/TMxpTagHandler.cpp b/src/TMxpTagHandler.cpp new file mode 100644 index 00000000000..d5b01c785ee --- /dev/null +++ b/src/TMxpTagHandler.cpp @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TMxpTagHandler.h" +#include "TMxpClient.h" + +TMxpTagHandlerResult TMxpTagHandler::handleTag(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) +{ + if (!supports(ctx, client, tag)) { + return MXP_TAG_NOT_HANDLED; + } + + return tag->isStartTag() ? handleStartTag(ctx, client, tag->asStartTag()) : handleEndTag(ctx, client, tag->asEndTag()); +} diff --git a/src/TMxpTagHandler.h b/src/TMxpTagHandler.h new file mode 100644 index 00000000000..bbe23d8277c --- /dev/null +++ b/src/TMxpTagHandler.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPTAGHANDLER_H +#define MUDLET_TMXPTAGHANDLER_H + +#include "MxpTag.h" +#include "TMxpTagHandlerResult.h" + +#include "pre_guard.h" +#include +#include "post_guard.h" + +class TMxpClient; +class TMxpContext; + +class TMxpTagHandler +{ +public: + virtual TMxpTagHandlerResult handleTag(TMxpContext& ctx, TMxpClient& client, MxpTag* tag); + + virtual void handleContent(char ch) {} + + void handleContent(const QString& text) + { + for (auto& ch : text) { + handleContent(ch.toLatin1()); + } + } + + virtual bool supports(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) { return true; } + + virtual TMxpTagHandlerResult handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) { return MXP_TAG_NOT_HANDLED; } + + virtual TMxpTagHandlerResult handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) { return MXP_TAG_NOT_HANDLED; } +}; + +class TMxpSingleTagHandler : public TMxpTagHandler +{ + QString tagName; + +public: + explicit TMxpSingleTagHandler(QString tagName) : tagName(std::move(tagName)) {} + + virtual bool supports(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) { return tag->isNamed(tagName); } +}; + +#endif //MUDLET_TMXPTAGHANDLER_H diff --git a/src/TMxpTagHandlerResult.h b/src/TMxpTagHandlerResult.h new file mode 100644 index 00000000000..f090f7e5d86 --- /dev/null +++ b/src/TMxpTagHandlerResult.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPTAGHANDLERRESULT_H +#define MUDLET_TMXPTAGHANDLERRESULT_H + +enum TMxpTagHandlerResult { MXP_TAG_NOT_HANDLED, MXP_TAG_HANDLED, MXP_TAG_COMMIT_LINE }; + +#endif //MUDLET_TMXPTAGHANDLERRESULT_H diff --git a/src/TMxpTagParser.cpp b/src/TMxpTagParser.cpp new file mode 100644 index 00000000000..2bec1ffb317 --- /dev/null +++ b/src/TMxpTagParser.cpp @@ -0,0 +1,175 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "TMxpTagParser.h" +#include "TMxpNodeBuilder.h" +#include "TStringUtils.h" +#include + +static QStringRef stripTagAndTrim(const QString& tagText) +{ + return TStringUtils::trimmedRef(TStringUtils::stripRef(tagText, '<', '>')); +} + +static bool isEndTag(const QString& tagText) +{ + return stripTagAndTrim(tagText).startsWith("/"); +} + +static bool isTag(const QString& tagString) +{ + return TStringUtils::isBetween(TStringUtils::trimmedRef(tagString), '<', '>'); +} + +QList> TMxpTagParser::parseToMxpNodeList(const QString& tagText, bool ignoreText) const +{ + TMxpNodeBuilder nodeBuilder(ignoreText); + + QList> result; + for (int i = 0; i < tagText.length(); i++) { + if (nodeBuilder.accept(tagText[i].toLatin1())) { + result.append(QSharedPointer(nodeBuilder.buildNode())); + i--; + } + } + + if (nodeBuilder.hasNode()) { + result.append(QSharedPointer(nodeBuilder.buildNode())); + } + + return result; +} + +MxpTag* TMxpTagParser::parseTag(const QString& tagText) const +{ + return isEndTag(tagText) ? static_cast(parseEndTag(tagText)) : static_cast(parseStartTag(tagText)); +} + +MxpEndTag* TMxpTagParser::parseEndTag(const QString& tagText) const +{ + QStringRef tagContent = TStringUtils::trimmedRef(stripTagAndTrim(tagText)).mid(1); + const QStringList& parts = parseToList(tagContent); + + if (parts.size() > 1) { + qDebug() << "WARN: end tag " << tagText << " has attributes"; + } + + return new MxpEndTag(parts.first()); +} + +MxpStartTag* TMxpTagParser::parseStartTag(const QString& tagText) const +{ + QStringRef tagContent = TStringUtils::stripRef(tagText, '<', '>'); + + const QStringList& parts = parseToList(tagContent); + + const QString& name = parts.first(); + + bool isClosed = parts.back() == "/"; + size_t attrsEndIndex = isClosed ? parts.size() - 1 : parts.size(); + + QList attrs; + for (int i = 1; i < attrsEndIndex; i++) { + attrs.append(parseAttribute(parts[i])); + } + + return new MxpStartTag(name, attrs, isClosed); +} + +MxpTagAttribute TMxpTagParser::parseAttribute(const QString& attr) const +{ + if (isTag(attr)) { + return MxpTagAttribute(attr, QString()); + } + + int sepIdx = attr.indexOf('='); + if (sepIdx == -1) { + return MxpTagAttribute(attr, QString()); + } + + const QString& name = attr.left(sepIdx); + const QString& value = TStringUtils::unquoteRef(attr.midRef(sepIdx + 1)).toString(); + + return MxpTagAttribute(name, value); +} +QStringList TMxpTagParser::parseToList(const QString& tagText) +{ + return parseToList(QStringRef(&tagText)); +} + +QStringList TMxpTagParser::parseToList(const QStringRef& tagText) +{ + QStringList result; + + int start = 0; + + while (start < tagText.length()) { + if (TStringUtils::isQuote(tagText[start])) { + auto end = readTextBlock(tagText, start + 1, tagText.length(), tagText[start]); + if (start != end) { + result.append(tagText.mid(start + 1, end - start - 1).toString()); + } + + start = end + 1; + continue; + } + + if (!tagText[start].isSpace()) { + auto end = readTextBlock(tagText, start, tagText.length(), ' '); + if (start != end) { + result.append(tagText.mid(start, end - start).toString()); + } + + start = end; + continue; + } + + start++; + } + + return result; +} + +int TMxpTagParser::readTextBlock(const QStringRef& str, int start, int end, QChar terminatingChar) +{ + bool inQuote = false; + QChar curQuote = 0; + + int pos = start; + while (pos < end) { + if (!inQuote && str[pos] == terminatingChar) { + break; + } + + if (TStringUtils::isQuote(str[pos])) { + if (!inQuote) { + inQuote = true; + curQuote = str[pos]; + } else { + if (str[pos] == curQuote) { + inQuote = false; + } + } + } + + pos++; + } + + return pos; +} diff --git a/src/TMxpTagParser.h b/src/TMxpTagParser.h new file mode 100644 index 00000000000..e2b5eefe1fd --- /dev/null +++ b/src/TMxpTagParser.h @@ -0,0 +1,50 @@ + +#ifndef MUDLET_MXPSUPPORT_CPP_TMXPTAGPARSER_H +#define MUDLET_MXPSUPPORT_CPP_TMXPTAGPARSER_H + +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +#include "MxpTag.h" + +#include "pre_guard.h" +#include +#include +#include +#include "post_guard.h" + +class TMxpTagParser +{ + static int readTextBlock(const QStringRef& str, int start, int end, QChar terminatingChar); + +public: + static QStringList parseToList(const QStringRef& tagText); + static QStringList parseToList(const QString& tagText); + + QList> parseToMxpNodeList(const QString& tagText, bool ignoreText = false) const; + + MxpTag* parseTag(const QString& tagText) const; + MxpStartTag* parseStartTag(const QString& tagText) const; + MxpEndTag* parseEndTag(const QString& tagText) const; + + MxpTagAttribute parseAttribute(const QString& attr) const; +}; + +#endif //MUDLET_MXPSUPPORT_CPP_TMXPTAGPARSER_H diff --git a/src/TMxpTagProcessor.cpp b/src/TMxpTagProcessor.cpp new file mode 100644 index 00000000000..0dc98eebc75 --- /dev/null +++ b/src/TMxpTagProcessor.cpp @@ -0,0 +1,122 @@ +/*************************************************************************** + * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * + * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * + * Copyright (C) 2014-2018 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +#include "TMxpTagProcessor.h" +#include "TMxpBRTagHandler.h" +#include "TMxpColorTagHandler.h" +#include "TMxpCustomElementTagHandler.h" +#include "TMxpElementDefinitionHandler.h" +#include "TMxpEntityTagHandler.h" +#include "TMxpFontTagHandler.h" +#include "TMxpFormattingTagsHandler.h" +#include "TMxpLinkTagHandler.h" +#include "TMxpSendTagHandler.h" +#include "TMxpSupportTagHandler.h" +#include "TMxpTagHandlerResult.h" +#include "TMxpTagParser.h" +#include "TMxpVarTagHandler.h" +#include "TMxpVersionTagHandler.h" + +TMxpTagHandlerResult TMxpTagProcessor::process(TMxpContext& ctx, TMxpClient& client, const std::string& currentToken) +{ + TMxpTagParser parser; + QScopedPointer tag(parser.parseTag(currentToken.c_str())); + + return handleTag(ctx, client, tag.get()); +} + +TMxpTagHandlerResult TMxpTagProcessor::handleTag(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) +{ + if (!client.tagReceived(tag)) { + return MXP_TAG_NOT_HANDLED; + } + + for (const auto& handler : mRegisteredHandlers) { + TMxpTagHandlerResult result = handler->handleTag(ctx, client, tag); + + if (result != MXP_TAG_NOT_HANDLED) { + result = client.tagHandled(tag, result); + if (result != MXP_TAG_NOT_HANDLED) { + return result; + } + } + } + + return MXP_TAG_NOT_HANDLED; +} + +void TMxpTagProcessor::handleContent(char ch) +{ + for (const auto& handler : mRegisteredHandlers) { + handler->handleContent(ch); + } +} + +TMxpTagProcessor::TMxpTagProcessor() +{ + registerHandler(new TMxpVersionTagHandler()); + registerHandler(new TMxpSupportTagHandler()); + + registerHandler(TMxpFeatureOptions({"var", {"publish"}}), new TMxpVarTagHandler()); + registerHandler(TMxpFeatureOptions({"br", {}}), new TMxpBRTagHandler()); + registerHandler(TMxpFeatureOptions({"send", {"href", "hint", "prompt"}}), new TMxpSendTagHandler()); + registerHandler(TMxpFeatureOptions({"a", {"href", "hint"}}), new TMxpLinkTagHandler()); + registerHandler(TMxpFeatureOptions({"color", {"fore", "back"}}), new TMxpColorTagHandler()); + registerHandler(TMxpFeatureOptions({"font", {"color", "back"}}), new TMxpFontTagHandler()); + + mSupportedMxpElements["b"] = QVector(); + mSupportedMxpElements["i"] = QVector(); + mSupportedMxpElements["u"] = QVector(); + mRegisteredHandlers.append(QSharedPointer(new TMxpFormattingTagsHandler())); + + registerHandler(new TMxpEntityTagHandler()); + registerHandler(new TMxpElementDefinitionHandler()); + registerHandler(new TMxpCustomElementTagHandler()); +} + +void TMxpTagProcessor::registerHandler(const TMxpFeatureOptions& supports, TMxpTagHandler* handler) +{ + mSupportedMxpElements[supports.first].append(supports.second); + mRegisteredHandlers.append(QSharedPointer(handler)); +} + +void TMxpTagProcessor::registerHandler(TMxpTagHandler* handler) +{ + mRegisteredHandlers.append(QSharedPointer(handler)); +} +TMxpElementRegistry& TMxpTagProcessor::getElementRegistry() +{ + return mMxpElementRegistry; +} +QMap>& TMxpTagProcessor::getSupportedElements() +{ + return mSupportedMxpElements; +} +TMxpTagHandler& TMxpTagProcessor::getMainHandler() +{ + return *this; +} +TEntityResolver& TMxpTagProcessor::getEntityResolver() +{ + return mEntityResolver; +} diff --git a/src/TMxpTagProcessor.h b/src/TMxpTagProcessor.h new file mode 100644 index 00000000000..075dc1dcdc3 --- /dev/null +++ b/src/TMxpTagProcessor.h @@ -0,0 +1,67 @@ +#ifndef MUDLET_TMXPTAGPROCESSOR_H +#define MUDLET_TMXPTAGPROCESSOR_H + +/*************************************************************************** + * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * + * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * + * Copyright (C) 2014-2018 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "pre_guard.h" +#include +#include +#include +#include "post_guard.h" + +#include "MxpTag.h" +#include "TEntityResolver.h" +#include "TMxpClient.h" +#include "TMxpContext.h" +#include "TMxpElementRegistry.h" +#include "TMxpTagHandler.h" +#include "TMxpTagHandlerResult.h" + +typedef QPair> TMxpFeatureOptions; + +class TMxpTagProcessor : public TMxpContext +{ + QMap> mSupportedMxpElements; + QList> mRegisteredHandlers; + + TMxpElementRegistry mMxpElementRegistry; + TEntityResolver mEntityResolver; + +public: + TMxpTagProcessor(); + TMxpTagHandlerResult process(TMxpContext& ctx, TMxpClient& client, const std::string& currentToken); + + TMxpTagHandlerResult handleTag(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) override; + void handleContent(char ch) override; + + void registerHandler(const TMxpFeatureOptions& supports, TMxpTagHandler* handler); + void registerHandler(TMxpTagHandler* handler); + + TMxpElementRegistry& getElementRegistry() override; + QMap>& getSupportedElements() override; + TMxpTagHandler& getMainHandler() override; + + TEntityResolver& getEntityResolver() override; +}; + +#endif //MUDLET_TMXPTAGPROCESSOR_H diff --git a/src/TMxpVarTagHandler.cpp b/src/TMxpVarTagHandler.cpp new file mode 100644 index 00000000000..1befaeec7f6 --- /dev/null +++ b/src/TMxpVarTagHandler.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * + * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * + * Copyright (C) 2014-2018 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "TMxpVarTagHandler.h" +#include "TMxpClient.h" +bool TMxpVarTagHandler::supports(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) +{ + return tag->isNamed("VAR") || tag->isNamed("V"); +} + + +TMxpTagHandlerResult TMxpVarTagHandler::handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) +{ + mCurrentStartTag = *tag; + mCurrentVarContent.clear(); + return MXP_TAG_HANDLED; +} + +// +//Value +TMxpTagHandlerResult TMxpVarTagHandler::handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) +{ + const QString& name = mCurrentStartTag.getAttrName(0); + const QString& value = mCurrentVarContent; + + if (mCurrentStartTag.hasAttribute("PUBLISH") || !mCurrentStartTag.hasAttribute("DELETE")) { + client.setVariable(name, value); + } + + return MXP_TAG_HANDLED; +} +void TMxpVarTagHandler::handleContent(char ch) +{ + mCurrentVarContent.append(ch); +} diff --git a/src/TMxpVarTagHandler.h b/src/TMxpVarTagHandler.h new file mode 100644 index 00000000000..f08c3518c8f --- /dev/null +++ b/src/TMxpVarTagHandler.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * + * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * + * Copyright (C) 2014-2018 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET__TMXPVARTAGHANDLER_H +#define MUDLET__TMXPVARTAGHANDLER_H + +// +//Value +#include "TMxpTagHandler.h" +class TMxpVarTagHandler : public TMxpTagHandler { + MxpStartTag mCurrentStartTag; + QString mCurrentVarContent; +public: + TMxpVarTagHandler() : mCurrentStartTag(MxpStartTag("VAR")) {} + bool supports(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) override; + TMxpTagHandlerResult handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) override; + TMxpTagHandlerResult handleEndTag(TMxpContext& ctx, TMxpClient& client, MxpEndTag* tag) override; + + void handleContent(char ch) override; +}; + +#endif//MUDLET__TMXPVARTAGHANDLER_H diff --git a/src/TMxpVersionTagHandler.cpp b/src/TMxpVersionTagHandler.cpp new file mode 100644 index 00000000000..328a2f6efaf --- /dev/null +++ b/src/TMxpVersionTagHandler.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +#include "TMxpVersionTagHandler.h" +#include "TMxpClient.h" + +TMxpTagHandlerResult TMxpVersionTagHandler::handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) +{ + const QString& version = client.getVersion(); + + QString payload = scmVersionString.arg(version); + client.sendToServer(payload); + + return MXP_TAG_HANDLED; +} diff --git a/src/TMxpVersionTagHandler.h b/src/TMxpVersionTagHandler.h new file mode 100644 index 00000000000..09982c2f829 --- /dev/null +++ b/src/TMxpVersionTagHandler.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TMXPVERSIONTAGHANDLER_H +#define MUDLET_TMXPVERSIONTAGHANDLER_H +#include "TMxpTagHandler.h" + +class TMxpVersionTagHandler : public TMxpSingleTagHandler +{ +public: + TMxpVersionTagHandler() : TMxpSingleTagHandler("VERSION") {} + inline static const QString scmVersionString = QStringLiteral("\n\x1b[1z\n"); + + TMxpTagHandlerResult handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag) override; +}; +#include "TMxpTagHandler.h" +#endif //MUDLET_TMXPVERSIONTAGHANDLER_H diff --git a/src/TStringUtils.cpp b/src/TStringUtils.cpp new file mode 100644 index 00000000000..f88ae38e7d1 --- /dev/null +++ b/src/TStringUtils.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "TStringUtils.h" + +QStringRef TStringUtils::trimmedRef(const QStringRef& ref) +{ + int start = 0; + int end = ref.length(); + + while (start < end && ref[start].isSpace()) { + start++; + } + + while (end > start && ref[end - 1].isSpace()) { + end--; + } + + return QStringRef(ref.string(), ref.position() + start, end - start); +} + +QStringRef TStringUtils::trimmedRef(const QString& str) +{ + return trimmedRef(QStringRef(&str)); +} + +QStringRef TStringUtils::stripRef(const QString& str, QChar start, QChar end) +{ + int len = str.length(); + if (len > 1 && str.front() == start && str.back() == end) { + return str.midRef(1, len - 2); + } + + return QStringRef(&str); +} + +bool TStringUtils::isQuote(QChar ch) +{ + return isOneOf(ch, QStringLiteral("\'\"")); +} + +bool TStringUtils::isOneOf(QChar ch, const QString& chars) +{ + for (const auto& o : chars) { + if (o == ch) { + return true; + } + } + + return false; +} + +bool TStringUtils::isQuoted(const QStringRef& ref) +{ + return TStringUtils::isQuote(ref.front()) && ref.front() == ref.back(); +} + +QStringRef TStringUtils::unquoteRef(const QStringRef& ref) +{ + return isQuoted(ref) ? ref.mid(1, ref.size() - 2) : ref; +} +bool TStringUtils::isBetween(const QString& str, char first, char last) +{ + return isBetween(QStringRef(&str), first, last); +} + +bool TStringUtils::isBetween(const QStringRef& str, char first, char last) +{ + return str.front() == first && str.back() == last; +} diff --git a/src/TStringUtils.h b/src/TStringUtils.h new file mode 100644 index 00000000000..9ae7fa1da5e --- /dev/null +++ b/src/TStringUtils.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2020 by Gustavo Sousa - gustavocms@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MUDLET_TSTRINGUTILS_H +#define MUDLET_TSTRINGUTILS_H + +#include "pre_guard.h" +#include +#include +#include "post_guard.h" +#include + +#define CHAR_NEW_LINE '\n' +#define CHAR_CARRIAGE_RETURN '\r' +#define CHAR_END_OF_FILE '\xff' +#define CHAR_END_OF_TEXT '\004' +#define CHAR_ESC '\033' + +#define CHAR_IS_COMMIT_CHAR(ch) ((ch) == CHAR_NEW_LINE || (ch) == CHAR_CARRIAGE_RETURN || (ch) == CHAR_END_OF_FILE || (ch) == CHAR_END_OF_TEXT) + + +class TStringUtils +{ +public: + static bool isQuote(QChar ch); + static bool isOneOf(QChar ch, const QString &chars); + + static QStringRef trimmedRef(const QStringRef& ref); + static QStringRef stripRef(const QString& str, QChar start, QChar end); + + static QStringRef unquoteRef(const QStringRef& ref); + static bool isBetween(const QString& str, char first, char last); + static bool isBetween(const QStringRef& str, char first, char last); + static QStringRef trimmedRef(const QString& str); + static bool isQuoted(const QStringRef& ref); + + static void apply(QStringList& strList, const std::function& func) + { + for (auto& ptr : strList) { + func(ptr); + } + } +}; + +#endif //MUDLET_TSTRINGUTILS_H diff --git a/src/TTextEdit.cpp b/src/TTextEdit.cpp index e99ecce4dd9..e7236e5168d 100644 --- a/src/TTextEdit.cpp +++ b/src/TTextEdit.cpp @@ -818,7 +818,7 @@ void TTextEdit::updateTextCursor(const QMouseEvent* event, int lineIndex, int tC if (tCharIndex < static_cast(mpBuffer->buffer[lineIndex].size())) { if (mpBuffer->buffer.at(lineIndex).at(tCharIndex).linkIndex()) { setCursor(Qt::PointingHandCursor); - QStringList tooltip = mpBuffer->mHintStore[mpBuffer->buffer.at(lineIndex).at(tCharIndex).linkIndex()]; + QStringList tooltip = mpHost->mpConsole->getLinkStore().getHints(mpBuffer->buffer.at(lineIndex).at(tCharIndex).linkIndex()); QToolTip::showText(event->globalPos(), tooltip.join("\n")); } else { setCursor(Qt::IBeamCursor); @@ -1005,7 +1005,7 @@ void TTextEdit::mousePressEvent(QMouseEvent* event) if (y < static_cast(mpBuffer->buffer.size())) { if (x < static_cast(mpBuffer->buffer[y].size())) { if (mpBuffer->buffer.at(y).at(x).linkIndex()) { - QStringList command = mpBuffer->mLinkStore[mpBuffer->buffer.at(y).at(x).linkIndex()]; + QStringList command = mpHost->mpConsole->getLinkStore().getLinks(mpBuffer->buffer.at(y).at(x).linkIndex()); QString func; if (!command.empty()) { func = command.at(0); @@ -1083,8 +1083,8 @@ void TTextEdit::mousePressEvent(QMouseEvent* event) if (y < static_cast(mpBuffer->buffer.size())) { if (x < static_cast(mpBuffer->buffer[y].size())) { if (mpBuffer->buffer.at(y).at(x).linkIndex()) { - QStringList command = mpBuffer->mLinkStore[mpBuffer->buffer.at(y).at(x).linkIndex()]; - QStringList hint = mpBuffer->mHintStore[mpBuffer->buffer.at(y).at(x).linkIndex()]; + QStringList command = mpHost->mpConsole->getLinkStore().getLinks(mpBuffer->buffer.at(y).at(x).linkIndex()); + QStringList hint = mpHost->mpConsole->getLinkStore().getHints(mpBuffer->buffer.at(y).at(x).linkIndex()); if (command.size() > 1) { auto popup = new QMenu(this); for (int i = 0, total = command.size(); i < total; ++i) { diff --git a/src/ctelnet.cpp b/src/ctelnet.cpp index b44a4a6ce35..95803c9cafb 100644 --- a/src/ctelnet.cpp +++ b/src/ctelnet.cpp @@ -1122,7 +1122,7 @@ void cTelnet::processTelnetCommand(const std::string& command) if (!mpHost->mFORCE_MXP_NEGOTIATION_OFF) { sendTelnetOption(TN_DO, OPT_MXP); mpHost->mServerMXPenabled = true; - mpHost->mpConsole->buffer.mMXP = true; + mpHost->mMxpProcessor.enable(); raiseProtocolEvent("sysProtocolEnabled", "MXP"); break; } diff --git a/src/mudlet.pro b/src/mudlet.pro index bfbd816d742..a25f958917c 100644 --- a/src/mudlet.pro +++ b/src/mudlet.pro @@ -517,14 +517,38 @@ SOURCES += \ TDebug.cpp \ TDockWidget.cpp \ TEasyButtonBar.cpp \ + TEncodingTable.cpp \ + TEntityHandler.cpp \ + TEntityResolver.cpp \ TFlipButton.cpp \ TForkedProcess.cpp \ TimerUnit.cpp \ TKey.cpp \ TLabel.cpp \ + TLinkStore.cpp \ TLuaInterpreter.cpp \ TMap.cpp \ TMedia.cpp \ + TMxpElementDefinitionHandler.cpp \ + TMxpElementRegistry.cpp \ + TMxpEntityTagHandler.cpp \ + TMxpFormattingTagsHandler.cpp \ + TMxpBRTagHandler.cpp \ + TMxpColorTagHandler.cpp \ + TMxpCustomElementTagHandler.cpp \ + TMxpFontTagHandler.cpp \ + TMxpLinkTagHandler.cpp \ + TMxpMudlet.cpp \ + TMxpNodeBuilder.cpp \ + TMxpProcessor.cpp \ + TMxpSendTagHandler.cpp \ + TMxpSupportTagHandler.cpp \ + MxpTag.cpp \ + TMxpTagHandler.cpp \ + TMxpTagParser.cpp \ + TMxpTagProcessor.cpp \ + TMxpVarTagHandler.cpp \ + TMxpVersionTagHandler.cpp \ TriggerUnit.cpp \ TRoom.cpp \ TRoomDB.cpp \ @@ -540,7 +564,8 @@ SOURCES += \ TVar.cpp \ VarUnit.cpp \ XMLexport.cpp \ - XMLimport.cpp + XMLimport.cpp \ + TStringUtils.cpp HEADERS += \ ActionUnit.h \ @@ -592,6 +617,9 @@ HEADERS += \ TDebug.h \ TDockWidget.h \ TEasyButtonBar.h \ + TEncodingTable.h \ + TEntityHandler.h \ + TEntityResolver.h \ testdbg.h \ TEvent.h \ TFlipButton.h \ @@ -599,10 +627,33 @@ HEADERS += \ TimerUnit.h \ TKey.h \ TLabel.h \ + TLinkStore.h \ TLuaInterpreter.h \ TMap.h \ - TMedia.h \ TMatchState.h \ + TMedia.h \ + TMxpBRTagHandler.h \ + TMxpClient.h \ + TMxpColorTagHandler.h \ + TMxpCustomElementTagHandler.h \ + TMxpFontTagHandler.h \ + TMxpLinkTagHandler.h \ + TMxpElementDefinitionHandler.h \ + TMxpElementRegistry.h \ + TMxpEntityTagHandler.h \ + TMxpContext.h \ + TMxpFormattingTagsHandler.h \ + TMxpMudlet.h \ + TMxpNodeBuilder.h \ + TMxpProcessor.h \ + TMxpSendTagHandler.h \ + MxpTag.h \ + TMxpTagHandler.h \ + TMxpTagParser.h \ + TMxpTagProcessor.h \ + TMxpSupportTagHandler.cpp \ + TMxpVarTagHandler.h \ + TMxpVersionTagHandler.h \ Tree.h \ TriggerUnit.h \ TRoom.h \ @@ -622,7 +673,8 @@ HEADERS += \ XMLimport.h \ widechar_width.h \ ../3rdparty/discord/rpc/include/discord_register.h \ - ../3rdparty/discord/rpc/include/discord_rpc.h + ../3rdparty/discord/rpc/include/discord_rpc.h \ + TStringUtils.h # This is for compiled UI files, not those used at runtime through the resource file. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000000..f51cac945cd --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,53 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.1) + +SET(CMAKE_AUTOMOC ON) +SET(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 17) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + + +PROJECT(mudlet-tests + LANGUAGES CXX) + +ENABLE_TESTING() + +find_package(Qt5Test REQUIRED) +find_package(Qt5 REQUIRED + COMPONENTS Core + Multimedia + Network + OpenGL + UiTools + Widgets + Concurrent) + +link_libraries( + Qt5::Test + Qt5::Concurrent + Qt5::Core + Qt5::Network + Qt5::Multimedia + Qt5::UiTools + Qt5::Widgets) + + +include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../src") + +add_executable(TEntityResolverTest TEntityResolverTest.cpp ../src/TEntityResolver.cpp) +add_test(NAME TEntityResolverTest COMMAND TEntityResolverTest) + +add_executable(TEntityHandlerTest TEntityHandlerTest.cpp ../src/TEntityHandler.cpp ../src/TEntityResolver.cpp) +add_test(NAME TEntityHandlerTest COMMAND TEntityHandlerTest) + +add_executable(TLinkStoreTest TLinkStoreTest.cpp ../src/TLinkStore.cpp ../src/TEntityResolver.cpp) +add_test(NAME TLinkStoreTest COMMAND TLinkStoreTest) + + +file(GLOB MXP_SOURCE ../src/TMxp*.cpp ../src/MxpTag.cpp ../src/TEntityHandler.cpp ../src/TEntityResolver.cpp ../src/TStringUtils.cpp) +list(FILTER MXP_SOURCE EXCLUDE REGEX ".*/src/TMxpMudlet.cpp") + +add_executable(TMxpTagParserTest TMxpTagParserTest.cpp ../src/TMxpTagParser.cpp ../src/TMxpNodeBuilder.cpp ../src/MxpTag.cpp ../src/TStringUtils.cpp) +add_test(NAME TMxpTagParserTest COMMAND TMxpTagParserTest) + +add_executable(TMxpSendTagHandlerTest TMxpSendTagHandlerTest.cpp ${MXP_SOURCE} ../src/TMxpSendTagHandler.cpp ../src/TMxpTagParser.cpp ../src/TMxpNodeBuilder.cpp) +add_test(NAME TMxpSendTagHandlerTest COMMAND TMxpSendTagHandlerTest) diff --git a/test/TEntityHandlerTest.cpp b/test/TEntityHandlerTest.cpp new file mode 100644 index 00000000000..3c8258f0195 --- /dev/null +++ b/test/TEntityHandlerTest.cpp @@ -0,0 +1,85 @@ +#include +#include + +class TEntityHandlerTest : public QObject { +Q_OBJECT + +private: + +private slots: + + void initTestCase() + { + } + + void testHandleSimpleString() + { + TEntityHandler handler; + + std::string str = "Someone says "Hello""; + std::string result = processString(handler, str); + + QCOMPARE(result.c_str(), "Someone says \"Hello\""); + } + + void testHandleUnfinishedString() + { + TEntityHandler handler; + + std::string str = "Someone says "Hello&qu"; + std::string result = processString(handler, str); + + QCOMPARE(result.c_str(), "Someone says \"Hello"); + } + + void testLongSequence() + { + TEntityHandler handler; + + std::string str = "Long sequence: &01234567; asdf"; + std::string result = processString(handler, str); + + QCOMPARE(result.c_str(), "Long sequence: ; asdf"); + } + + void testHandleSplitInTwoParts() + { + TEntityHandler handler; + + std::string part1 = "Someone says "Hello&qu"; + std::string result1 = processString(handler, part1); + QCOMPARE(result1.c_str(), "Someone says \"Hello"); + + std::string part2 = "ot; to you"; + std::string result2 = processString(handler, part2); + QCOMPARE(result2.c_str(), "\" to you"); + + std::string result = result1 + result2; + + qDebug() << result1.c_str(); + qDebug() << result2.c_str(); + qDebug() << result.c_str(); + + QCOMPARE(result.c_str(), "Someone says \"Hello\" to you"); + } + + inline static std::string processString(TEntityHandler& handler, std::string& str) + { + size_t len = str.length(); + std::string result; + for (size_t i = 0; i < len; i++) { + if (!handler.handle(str[i])) { + result += str[i]; + } else if (handler.isEntityResolved()) { + result += handler.getResultAndReset(); + } + } + return result; + } + + void cleanupTestCase() + { + } +}; +#include "TEntityHandlerTest.moc" +QTEST_MAIN(TEntityHandlerTest) diff --git a/test/TEntityResolverTest.cpp b/test/TEntityResolverTest.cpp new file mode 100644 index 00000000000..72b29d72486 --- /dev/null +++ b/test/TEntityResolverTest.cpp @@ -0,0 +1,128 @@ + +#include +#include +#include + +class TEntityResolverTest : public QObject { +Q_OBJECT + +private: + +private slots: + + void initTestCase() + { + } + + void testStandardEntities() + { + TEntityResolver resolver; + + QCOMPARE(resolver.getResolution(" "), " "); + QCOMPARE(resolver.getResolution(">"), ">"); + QCOMPARE(resolver.getResolution("<"), "<"); + QCOMPARE(resolver.getResolution("&"), "&"); + QCOMPARE(resolver.getResolution("""), "\""); + } + + void testStandardEntitiesCaseInsensitive() + { + TEntityResolver resolver; + + QCOMPARE(resolver.getResolution(">"), ">"); + QCOMPARE(resolver.getResolution("≪"), "<"); + QCOMPARE(resolver.getResolution("&AmP;"), "&"); + QCOMPARE(resolver.getResolution("""), "\""); + } + + void testDecimalCode() + { + TEntityResolver resolver; + + QCOMPARE(resolver.getResolution(" "), "\n"); + QCOMPARE(resolver.getResolution("%"), "%"); + QCOMPARE(resolver.getResolution(" "), " "); + } + + void testHexCode() + { + TEntityResolver resolver; + + QCOMPARE(resolver.getResolution(" "), " "); + QCOMPARE(resolver.getResolution("&"), "&"); + QCOMPARE(resolver.getResolution("+"), "+"); + + } + + void testRegisteredEntities() + { + TEntityResolver resolver; + + // Examples from MXP specification https://www.zuggsoft.com/zmud/mxp.htm#ENTITY + resolver.registerEntity("&Version;", "6.15"); + resolver.registerEntity("&Start;", ""); + resolver.registerEntity("&End;", ""); + + QCOMPARE(resolver.getResolution("&VERSION;"), "6.15"); + QCOMPARE(resolver.getResolution("&Start;"), ""); + QCOMPARE(resolver.getResolution("&end;"), ""); + } + + void testRegisterEntityAsChar() + { + TEntityResolver resolver; + + resolver.registerEntity("&symbol;", '@'); + + QCOMPARE(resolver.getResolution("&symbol;"), "@"); + } + + void testInvalidRegister() + { + TEntityResolver resolver; + + QVERIFY(!resolver.registerEntity("&symbol", '@')); + QVERIFY(!resolver.registerEntity("symbol", '@')); + + QVERIFY(resolver.registerEntity("&symbol;", '@')); + } + + void testResolveNonExistentEntity() + { + TEntityResolver resolver; + + QCOMPARE(resolver.getResolution("&symbol;"), "&symbol;"); + } + + void testInterpolation() + { + TEntityResolver resolver; + + QCOMPARE(resolver.interpolate("2 < 4"), "2 < 4"); + QCOMPARE(resolver.interpolate("2 ≪ 4"), "2 < 4"); + QCOMPARE(resolver.interpolate("You say "Hello World""), "You say \"Hello World\""); + } + + void testCustomInterpolation() + { + const QMap attributes = { + {QStringLiteral("&name;"), QStringLiteral("drunk sailor")}, + {QStringLiteral("&desc;"), QStringLiteral("A drunk sailor is lying here")} + }; + + auto mapping = [attributes](auto& attr) { + auto ptr = attributes.find(attr); + return ptr != attributes.end() ? *ptr : attr; + }; + + QCOMPARE(TEntityResolver::interpolate("attack '&name;'|look '&name;'", mapping), "attack 'drunk sailor'|look 'drunk sailor'"); + QCOMPARE(TEntityResolver::interpolate("desc: '&desc;'", mapping), "desc: 'A drunk sailor is lying here'"); + } + + void cleanupTestCase() + { + } +}; + +#include "TEntityResolverTest.moc" +QTEST_MAIN(TEntityResolverTest) diff --git a/test/TLinkStoreTest.cpp b/test/TLinkStoreTest.cpp new file mode 100644 index 00000000000..973029a7a24 --- /dev/null +++ b/test/TLinkStoreTest.cpp @@ -0,0 +1,81 @@ +#include +#include + +class TLinkStoreTest : public QObject { +Q_OBJECT + +private: + +private slots: + + void initTestCase() + { + } + + void testAddAndGet() + { + TLinkStore store(3); + + QStringList links; + links.append("GET &href;"); + links.append("LOOK &href;"); + + QStringList hints; + hints.append("Get &href;"); + hints.append("Look at &href;"); + + int id = store.addLinks(links, hints); + + QStringList links2 = store.getLinks(id); + QCOMPARE(links2, links); + QCOMPARE(links2[1], "LOOK &href;"); + + QStringList hints2 = store.getHints(id); + QCOMPARE(hints2, hints); + QCOMPARE(hints2[1], "Look at &href;"); + } + + void testNewGeneratedID() + { + TLinkStore store(3); + + QStringList links; + + store.addLinks(links, links); + QCOMPARE(store.getCurrentLinkID(), 1); + + store.addLinks(links, links); + QCOMPARE(store.getCurrentLinkID(), 2); + + store.addLinks(links, links); + QCOMPARE(store.getCurrentLinkID(), 3); + + store.addLinks(links, links); + QCOMPARE(store.getCurrentLinkID(), 1); + + store.addLinks(links, links); + QCOMPARE(store.getCurrentLinkID(), 2); + } + + void testMaxId() + { + TLinkStore store(3); + + QStringList links; + links.append("GET &href;"); + + store.addLinks(links, links); + store.addLinks(links, links); + store.addLinks(links, links); + + QCOMPARE(store.getCurrentLinkID(), 3); + QCOMPARE(store.getLinks(3), links); + } + + void cleanupTestCase() + { + } +}; + +#include "TLinkStoreTest.moc" +QTEST_MAIN(TLinkStoreTest) diff --git a/test/TMxpSendTagHandlerTest.cpp b/test/TMxpSendTagHandlerTest.cpp new file mode 100644 index 00000000000..62dbc1b4bb3 --- /dev/null +++ b/test/TMxpSendTagHandlerTest.cpp @@ -0,0 +1,112 @@ + +#include +#include +#include "TMxpStubClient.h" +#include "TMxpSendTagHandler.h" + +class TMxpSendTagHandlerTest : public QObject { +Q_OBJECT + +private: + +private slots: + + void testStaticText() + { + // Zugg + TMxpStubContext ctx; + TMxpStubClient stub; + + TMxpTagParser parser; + MxpStartTag* startTag = parser.parseStartTag(""); + MxpEndTag* endTag = parser.parseEndTag(""); + + TMxpSendTagHandler sendTagHandler; + TMxpTagHandler& tagHandler = sendTagHandler; + tagHandler.handleTag(ctx, stub, startTag); + tagHandler.handleContent("Zugg"); + tagHandler.handleTag(ctx, stub, endTag); + + QCOMPARE(stub.mHrefs.size(), 1); + QCOMPARE(stub.mHrefs[0], "printCmdLine([[tell Zugg ]])"); + + QCOMPARE(stub.mHints.size(), 1); + QCOMPARE(stub.mHints[0], "tell Zugg "); + } + + void testSimpleSend() + { + // north + TMxpStubContext ctx; + TMxpStubClient stub; + + MxpStartTag startTag("SEND"); + MxpEndTag endTag("SEND"); + + TMxpSendTagHandler sendTagHandler; + TMxpTagHandler& tagHandler = sendTagHandler; + + tagHandler.handleTag(ctx, stub, &startTag); + tagHandler.handleContent("north"); + tagHandler.handleTag(ctx, stub, &endTag); + + QCOMPARE(stub.mHrefs.size(), 1); + QCOMPARE(stub.mHrefs[0], "send([[north]])"); + + QCOMPARE(stub.mHints.size(), 1); + QCOMPARE(stub.mHints[0], "north"); + } + + void testSendPrompt() + { + // north + TMxpStubContext ctx; + TMxpStubClient stub; + + TMxpTagParser parser; + MxpStartTag* startTag = parser.parseStartTag(""); + MxpEndTag* endTag = parser.parseEndTag(""); + + TMxpSendTagHandler sendTagHandler; + TMxpTagHandler& tagHandler = sendTagHandler; + tagHandler.handleTag(ctx, stub, startTag); + tagHandler.handleContent("north"); + tagHandler.handleTag(ctx, stub, endTag); + + QCOMPARE(stub.mHrefs.size(), 1); + QCOMPARE(stub.mHrefs[0], "printCmdLine([[north]])"); + + QCOMPARE(stub.mHints.size(), 1); + QCOMPARE(stub.mHints[0], "north"); + } + + void testResolvingEntity() + { + // north + TMxpStubContext ctx; + TMxpStubClient stub; + + ctx.getEntityResolver().registerEntity("&charName;", "Gandalf"); + + TMxpTagParser parser; + MxpStartTag* startTag = parser.parseStartTag(""); + MxpEndTag* endTag = parser.parseEndTag(""); + + TMxpSendTagHandler sendTagHandler; + TMxpTagHandler& tagHandler = sendTagHandler; + tagHandler.handleTag(ctx, stub, startTag); + tagHandler.handleContent("TAG CONTENT"); + tagHandler.handleTag(ctx, stub, endTag); + + QCOMPARE(stub.mHrefs.size(), 1); + QCOMPARE(stub.mHrefs[0], "send([[say I am Gandalf]])"); + + QCOMPARE(stub.mHints.size(), 1); + QCOMPARE(stub.mHints[0], "say I am Gandalf"); + } + +}; + +#include "TMxpSendTagHandlerTest.moc" +QTEST_MAIN(TMxpSendTagHandlerTest) + diff --git a/test/TMxpStubClient.h b/test/TMxpStubClient.h new file mode 100644 index 00000000000..ef62e6dfd00 --- /dev/null +++ b/test/TMxpStubClient.h @@ -0,0 +1,129 @@ +// +// Created by gustavo on 19/04/2020. +// + +#ifndef MUDLET_TEST_TMXPSTUBCLIENT_H +#define MUDLET_TEST_TMXPSTUBCLIENT_H + +#include "TMxpContext.h" +#include "TMxpClient.h" + +class TMxpStubContext : public TMxpContext { +public: + TMxpElementRegistry mElementRegistry; + QMap> mSupportedElements; + TEntityResolver mEntityResolver; + + TMxpElementRegistry& getElementRegistry() override + { + return mElementRegistry; + } + QMap>& getSupportedElements() override + { + return mSupportedElements; + } + + virtual TMxpTagHandlerResult handleTag(TMxpContext& ctx, TMxpClient& client, MxpTag* tag) + { + return MXP_TAG_HANDLED; + } + + virtual void handleContent(char ch) + { + + } + + TMxpTagHandler& getMainHandler() override + { + return *this; + } + + TEntityResolver& getEntityResolver() override + { + return mEntityResolver; + } +}; + +class TMxpStubClient : public TMxpClient { +public: + QString version; + bool linkMode; + + QString sentToServer; + + QString fgColor, bgColor; + + QStringList mHrefs, mHints; + + QString getVersion() override + { + return version; + } + + void sendToServer(QString& str) override + { + sentToServer.append(str); + } + void setLinkMode(bool val) override + { + this->linkMode = val; + } + void setFlag(const QString& elementName, const QMap& params, const QString& content) override + { + + } + void pushColor(const QString& fgColor, const QString& bgColor) override + { + this->fgColor = fgColor; + this->bgColor = bgColor; + } + void popColor() override + { + fgColor.clear(); + bgColor.clear(); + } + void pushFont(const QString& fontFace, const QString& fontSize) override + { + + } + void popFont() override + { + + } + + bool isBold, isItalic, isUnderline; + + void setBold(bool bold) override + { + isBold = bold; + } + void setItalic(bool italic) override + { + isItalic = italic; + } + void setUnderline(bool underline) override + { + isUnderline = underline; + } + + int setLink(const QStringList& hrefs, const QStringList& hints) override + { + qDebug() << QString("setLink([%1], [%2])").arg(hrefs.join(", ")).arg(hints.join(", ")); + mHrefs = hrefs; + mHints = hints; + + return 1; + } + bool getLink(int id, QStringList** href, QStringList** hint) override + { + *href = &mHrefs; + *hint = &mHints; + + return true; + } + void publishEntity(const QString& name, const QString& value) override {} + + void setVariable(const QString& name, const QString& value) override {} +}; + +#endif //MUDLET_TEST_TMXPSTUBCLIENT_H diff --git a/test/TMxpTagParserTest.cpp b/test/TMxpTagParserTest.cpp new file mode 100644 index 00000000000..c6e6499b472 --- /dev/null +++ b/test/TMxpTagParserTest.cpp @@ -0,0 +1,287 @@ +#include +#include +#include "TMxpTagParser.h" + +class TMxpTagParserTest : public QObject { +Q_OBJECT + +private: + +private slots: + + void initTestCase() + {} + + + void testParseWithQuotes() + { + TMxpTagParser parser; + QList> list = parser.parseToMxpNodeList(" ", true); + + QCOMPARE(list.size(), 1); + QCOMPARE(list[0]->asStartTag()->getName(), "!EN"); + QCOMPARE(list[0]->asStartTag()->getAttrName(0), "quot"); + QCOMPARE(list[0]->asStartTag()->getAttrName(1), "\""); + } + + void testParseToNodes() + { + TMxpTagParser parser; + QList> list = parser.parseToMxpNodeList(""); + + QCOMPARE(list.size(), 2); + QVERIFY(list[0].get()->isTag()); + QCOMPARE(list[0]->asStartTag()->getName(), "COLOR"); + QCOMPARE(list[0]->asStartTag()->getAttributeValue("FORE"), "red"); + QCOMPARE(list[1]->asStartTag()->getName(), "B"); + } + + void testParseToNodesWithText() + { + TMxpTagParser parser; + QList> list = parser.parseToMxpNodeList("north"); + + QCOMPARE(list.size(), 3); + QVERIFY(list[0].get()->isTag()); + QCOMPARE(list[0]->asStartTag()->getName(), "SEND"); + + QVERIFY(!list[1]->isTag()); + QCOMPARE(list[1]->asText()->getContent(), "north"); + QCOMPARE(list[2]->asEndTag()->getName(), "SEND"); + } + + void testParseToNodesIgnoreText() + { + TMxpTagParser parser; + QList> list = parser.parseToMxpNodeList(" asafsdfasdf", true); + + QCOMPARE(list.size(), 2); + QVERIFY(list[0].get()->isTag()); + QCOMPARE(list[0]->asStartTag()->getName(), "COLOR"); + QCOMPARE(list[0]->asStartTag()->getAttributeValue("FORE"), "red"); + QCOMPARE(list[1]->asStartTag()->getName(), "B"); + } + + void testParseToNodesWithClosedAndEndTag() + { + TMxpTagParser parser; + QList> list = parser.parseToMxpNodeList("text"); + + QCOMPARE(list.size(), 4); + QVERIFY(list[0].get()->isTag()); + QVERIFY(list[0].get()->asStartTag()->isEmpty()); + QCOMPARE(list[0].get()->asStartTag()->getAttrName(0), "2"); + + QVERIFY(list[3].get()->isEndTag()); + QCOMPARE(list[3].get()->asEndTag()->getName(), "SEND"); + + } + + void testParseToNodesWithTextAndSpaces() + { + TMxpTagParser parser; + QList> list = parser.parseToMxpNodeList(" go north... "); + + QCOMPARE(list.size(), 3); + QVERIFY(list[0].get()->isTag()); + QCOMPARE(list[0]->asStartTag()->getName(), "SEND"); + QCOMPARE(list[0]->asStartTag()->getAttributeValue("href"), "&text;"); + + QVERIFY(!list[1]->isTag()); + QCOMPARE(list[1]->asText()->getContent(), " go north... "); + QCOMPARE(list[2]->asEndTag()->getName(), "SEND"); + } + + void testComplexElementDefinitionToTag() + { + QString tagLine = + "\" ATT='name desc'>"; + TMxpTagParser parser; + + MxpStartTag tag = *parser.parseStartTag(tagLine); + + QCOMPARE(tag.getName(), "!EL"); + QCOMPARE(tag.getAttributesCount(), 3); + + QCOMPARE(tag.getAttribute(0).getName(), "get"); + QCOMPARE(tag.getAttribute(0).getValue(), ""); + + QCOMPARE(tag.getAttribute(1).getName(), + ""); + QCOMPARE(tag.getAttributeValue("ATT"), "name desc"); + + MxpStartTag sendTag = *parser.parseStartTag(tag.getAttribute(1).getName()); + QCOMPARE(sendTag.getName(), "send"); + } + + void testMxpTagParser() + { + TMxpTagParser parser; + MxpStartTag tag = *parser.parseStartTag(""); + + QCOMPARE(tag.getName(), "!EL"); + + QVERIFY(tag.hasAttribute("RExit")); + QCOMPARE(tag.getAttributeValue("RExit"), ""); + QCOMPARE(tag.getAttribute(0).getName(), "RExit"); + QCOMPARE(tag.getAttribute(0).getValue(), ""); + + QVERIFY(tag.hasAttribute("FLAG")); + QCOMPARE(tag.getAttributeValue("FLAG"), "RoomExit"); + } + + void testComplexElementDefinitionToList() + { + QString tagLine = + "!EL get \"\" ATT='name desc'"; + + QStringList list = TMxpTagParser::parseToList(tagLine); + QCOMPARE(list.size(), 4); + QCOMPARE(list[0], "!EL"); + QCOMPARE(list[1], "get"); + QCOMPARE(list[2], + ""); + QCOMPARE(list[3], "ATT='name desc'"); + } + + void testAttrDefinition() + { + QString tagLine = R"()"; + TMxpTagParser::parseToList(tagLine); + + } + + void testSimpleElementDefition() + { + TMxpTagParser parser; + + QString tagLine = "!EL RExit FLAG=RoomExit"; + QStringList list = TMxpTagParser::parseToList(tagLine); + QCOMPARE(list.size(), 3); + QCOMPARE(list[0], "!EL"); + QCOMPARE(list[1], "RExit"); + QCOMPARE(list[2], "FLAG=RoomExit"); + } + + void testSimpleQuotedElementDefition() + { + TMxpTagParser parser; + + QString tagLine = "!EL RExit 'FLAG=RoomExit'"; + QStringList list = TMxpTagParser::parseToList(tagLine); + QCOMPARE(list[0], "!EL"); + QCOMPARE(list[1], "RExit"); + QCOMPARE(list[2], "FLAG=RoomExit"); + } + + void testElementDefitionWithExtraSpaces() + { + TMxpTagParser parser; + + QString tagLine = "!EL RExit FLAG=RoomExit"; + QStringList list = TMxpTagParser::parseToList(tagLine); + QCOMPARE(list[0], "!EL"); + QCOMPARE(list[1], "RExit"); + QCOMPARE(list[2], "FLAG=RoomExit"); + } + + void testDoubleQuotedElementDefition() + { + TMxpTagParser parser; + + QString tagLine = R"(!EL RExit "FLAG=RoomExit")"; + QStringList list = TMxpTagParser::parseToList(tagLine); + QCOMPARE(list[0], "!EL"); + QCOMPARE(list[1], "RExit"); + QCOMPARE(list[2], "FLAG=RoomExit"); + } + + void testElementDefitionQuotedAttributeSpaces() + { + TMxpTagParser parser; + + QString tagLine = "!EL sHp FLAG='Set Hp'"; + QStringList list = TMxpTagParser::parseToList(tagLine); + QCOMPARE(list[0], "!EL"); + QCOMPARE(list[1], "sHp"); + QCOMPARE(list[2], "FLAG='Set Hp'"); + } + + void testAccessAttrCaseInsensitive() + { + TMxpTagParser parser; + QString tagLine = ""; + + MxpStartTag tag = *parser.parseStartTag(tagLine); + + QVERIFY(tag.hasAttribute("sHp")); + QVERIFY(tag.hasAttribute("shp")); + QVERIFY(tag.hasAttribute("shP")); + + } + + void testElementDefitionQuotesInQuotes() + { + TMxpTagParser parser; + + QString tagLine = "!EL x FLAG='Quote \" ex'"; + QStringList list = TMxpTagParser::parseToList(tagLine); + QCOMPARE(list[0], "!EL"); + QCOMPARE(list[1], "x"); + QCOMPARE(list[2], "FLAG='Quote \" ex'"); + } + + void testElementComplet1() + { + TMxpTagParser parser; + + QString tagLine = R"(FRAME Name="Map" Left="-20c" Top="0" Width="20c" Height="20c")"; + QStringList list = TMxpTagParser::parseToList(tagLine); + + QCOMPARE(list[0], "FRAME"); + QCOMPARE(list[1], "Name=\"Map\""); + QCOMPARE(list[2], "Left=\"-20c\""); + QCOMPARE(list[3], "Top=\"0\""); + QCOMPARE(list[4], "Width=\"20c\""); + QCOMPARE(list[5], "Height=\"20c\""); + } + + void testEndTag() + { + TMxpTagParser parser; + + MxpEndTag* endTag = parser.parseEndTag(""); + QCOMPARE(endTag->getName(), "V"); + QVERIFY(endTag->isEndTag()); + QCOMPARE(endTag->asStartTag(), nullptr); + } + + void testParseEndTag() + { + TMxpTagParser parser; + + MxpTag* tag = parser.parseTag(""); + QCOMPARE(tag->getName(), "V"); + QVERIFY(tag->isEndTag()); + QVERIFY(tag->asEndTag()); + QVERIFY(!tag->asStartTag()); + } + + void testStartTagClosed() + { + TMxpTagParser parser; + MxpTag* tag = parser.parseTag(""); + + QVERIFY(tag->isStartTag()); + QVERIFY(tag->asStartTag()->isEmpty()); + QCOMPARE(tag->getName(), "RNum"); + QCOMPARE(tag->asStartTag()->getAttribute(0).getName(), "212"); + QCOMPARE(tag->asStartTag()->getAttributesCount(), 1); + } + + void cleanupTestCase() + {} +}; + +#include "TMxpTagParserTest.moc" +QTEST_MAIN(TMxpTagParserTest)