Qt6: remove or replace QTextCodec

This commit is contained in:
wmayer
2022-09-30 14:52:11 +02:00
parent 31da72fa17
commit 249eb7ff79
7 changed files with 78 additions and 39 deletions

View File

@@ -23,6 +23,15 @@
#include "PreCompiled.h"
#include <qglobal.h>
#if QT_VERSION < 0x060000
#include <QTextCodec>
#else
#include <QByteArray>
#include <QStringDecoder>
#include <QStringEncoder>
#endif
#include "InputSource.h"
#include "XMLTools.h"
@@ -36,11 +45,68 @@ using namespace std;
// ---------------------------------------------------------------------------
// StdInputStream: Constructors and Destructor
// ---------------------------------------------------------------------------
StdInputStream::StdInputStream( std::istream& Stream, XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager* const manager )
: stream(Stream), fMemoryManager(manager)
#if QT_VERSION < 0x060000
struct StdInputStream::TextCodec
{
QTextCodec::ConverterState state;
TextCodec() {
state.flags |= QTextCodec::IgnoreHeader;
state.flags |= QTextCodec::ConvertInvalidToNull;
}
void validateBytes(XMLByte* const toFill, std::streamsize len) {
QTextCodec *textCodec = QTextCodec::codecForName("UTF-8");
if (textCodec) {
const QString text = textCodec->toUnicode(reinterpret_cast<char *>(toFill), static_cast<int>(len), &state);
if (state.invalidChars > 0) {
// In case invalid characters were found decode back to 'utf-8' and replace
// them with '?'
// First, Qt replaces invalid characters with '\0' (see ConvertInvalidToNull)
// but Xerces doesn't like this because it handles this as termination. Thus,
// we have to go through the array and replace '\0' with '?'.
std::streamsize pos = 0;
QByteArray ba = textCodec->fromUnicode(text);
for (int i=0; i<ba.length(); i++, pos++) {
if (pos < len && ba[i] == '\0') {
toFill[i] = '?';
}
}
}
}
}
};
#else
struct StdInputStream::TextCodec
{
void validateBytes(XMLByte* const toFill, std::streamsize len) {
QByteArray encodedString(reinterpret_cast<char *>(toFill), static_cast<int>(len));
auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
QString text = toUtf16(encodedString);
if (toUtf16.hasError()) {
// In case invalid characters were found decode back to 'utf-8' and replace
// them with '?'
// First, Qt replaces invalid characters with '\0'
// but Xerces doesn't like this because it handles this as termination. Thus,
// we have to go through the array and replace '\0' with '?'.
std::streamsize pos = 0;
auto fromUtf16 = QStringEncoder(QStringEncoder::Utf8);
QByteArray ba = fromUtf16(text);
for (int i=0; i<ba.length(); i++, pos++) {
if (pos < len && ba[i] == '\0') {
toFill[i] = '?';
}
}
}
}
};
#endif
StdInputStream::StdInputStream( std::istream& Stream, XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager* const manager )
: stream(Stream)
, fMemoryManager(manager)
, codec(new TextCodec)
{
state.flags |= QTextCodec::IgnoreHeader;
state.flags |= QTextCodec::ConvertInvalidToNull;
}
@@ -65,21 +131,7 @@ XMLSize_t StdInputStream::readBytes(XMLByte* const toFill, const XMLSize_t maxT
stream.read(reinterpret_cast<char *>(toFill), static_cast<std::streamsize>(maxToRead));
std::streamsize len = stream.gcount();
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
const QString text = codec->toUnicode(reinterpret_cast<char *>(toFill), static_cast<int>(len), &state);
if (state.invalidChars > 0) {
// In case invalid characters were found decode back to 'utf-8' and replace
// them with '?'
// First, Qt replaces invalid characters with '\0' (see ConvertInvalidToNull)
// but Xerces doesn't like this because it handles this as termination. Thus,
// we have to go through the array and replace '\0' with '?'.
std::streamsize pos = 0;
QByteArray ba = codec->fromUnicode(text);
for (int i=0; i<ba.length(); i++, pos++) {
if (pos < len && ba[i] == '\0')
toFill[i] = '?';
}
}
codec->validateBytes(toFill, len);
return static_cast<XMLSize_t>(len);
}

View File

@@ -24,10 +24,10 @@
#define BASE_IINPUTSOURCE_H
#include <iosfwd>
#include <memory>
#include <xercesc/util/BinInputStream.hpp>
#include <xercesc/sax/InputSource.hpp>
#include <QTextCodec>
#ifndef FC_GLOBAL_H
#include <FCGlobal.h>
#endif
@@ -70,7 +70,8 @@ private :
// -----------------------------------------------------------------------
std::istream &stream;
XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager* const fMemoryManager;
QTextCodec::ConverterState state;
struct TextCodec;
std::unique_ptr<TextCodec> codec;
};

View File

@@ -37,7 +37,9 @@
# include <QPrintPreviewDialog>
# include <QSpacerItem>
# include <QStyle>
# if QT_VERSION < 0x060000
# include <QTextCodec>
# endif
# include <QTextCursor>
# include <QTextDocument>
# include <QTextStream>
@@ -523,7 +525,9 @@ bool EditorView::saveFile()
if (!file.open(QFile::WriteOnly))
return false;
QTextStream ts(&file);
#if QT_VERSION < 0x060000
ts.setCodec(QTextCodec::codecForName("UTF-8"));
#endif
ts << d->textEdit->document()->toPlainText();
file.close();
d->textEdit->document()->setModified(false);

View File

@@ -45,7 +45,6 @@
#include <QSet>
#include <QSignalMapper>
#include <QTemporaryFile>
#include <qtextcodec.h>
#include <qtextstream.h>
#include <qthread.h>
#include <qthreadpool.h>

View File

@@ -42,7 +42,6 @@
#include <QApplication>
#include <QLocale>
#include <QMessageBox>
#include <QTextCodec>
// FreeCAD header
#include <App/Application.h>
@@ -96,20 +95,6 @@ private:
FILE* file;
};
#if defined (FC_OS_LINUX) || defined(FC_OS_BSD)
QString myDecoderFunc(const QByteArray &localFileName)
{
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
return codec->toUnicode(localFileName);
}
QByteArray myEncoderFunc(const QString &fileName)
{
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
return codec->fromUnicode(fileName);
}
#endif
int main( int argc, char ** argv )
{
#if defined (FC_OS_LINUX) || defined(FC_OS_BSD)

View File

@@ -40,7 +40,6 @@
#include <QTextStream>
#include <QFile>
#include <QLabel>
#include <QTextCodec>
#include <cmath>
#endif

View File

@@ -43,7 +43,6 @@
#include <QTextStream>
#include <QFile>
#include <QLabel>
#include <QTextCodec>
#endif
#include <App/Application.h>