Utils: Use QStringDecoder instead of QTextCodec in Process

QTextCodec is in Qt5Compat and may not be part of Qt 7.

Change-Id: I3f7bad6f647f705cbf4ff45979ee32bbcfd671a1
Reviewed-by: David Schulz <david.schulz@qt.io>
Reviewed-by: André Hartmann <aha_1980@gmx.de>
This commit is contained in:
hjk
2025-06-12 10:07:27 +02:00
parent ab9f7e548c
commit c9b8e99058
7 changed files with 48 additions and 50 deletions

View File

@@ -427,16 +427,16 @@ Result<std::unique_ptr<FilePathWatcher>> DeviceFileAccess::watch(const FilePath
return ResultError(Tr::tr("watch is not implemented.")); return ResultError(Tr::tr("watch is not implemented."));
} }
TextCodec DeviceFileAccess::processStdOutCodec(const FilePath &executable) const TextEncoding DeviceFileAccess::processStdOutEncoding(const FilePath &executable) const
{ {
Q_UNUSED(executable) Q_UNUSED(executable)
return TextCodec::utf8(); // Good default nowadays. return TextEncoding::Utf8; // Good default nowadays.
} }
TextCodec DeviceFileAccess::processStdErrCodec(const FilePath &executable) const TextEncoding DeviceFileAccess::processStdErrEncoding(const FilePath &executable) const
{ {
Q_UNUSED(executable) Q_UNUSED(executable)
return TextCodec::utf8(); // Good default nowadays. return TextEncoding::Utf8; // Good default nowadays.
} }
// UnavailableDeviceFileAccess // UnavailableDeviceFileAccess
@@ -1249,16 +1249,16 @@ Result<std::unique_ptr<FilePathWatcher>> DesktopDeviceFileAccess::watch(const Fi
return ResultError(watcher->error()); return ResultError(watcher->error());
} }
TextCodec DesktopDeviceFileAccess::processStdOutCodec(const FilePath &executable) const TextEncoding DesktopDeviceFileAccess::processStdOutEncoding(const FilePath &executable) const
{ {
Q_UNUSED(executable) Q_UNUSED(executable)
return TextCodec::codecForLocale(); return TextCodec::encodingForLocale();
} }
TextCodec DesktopDeviceFileAccess::processStdErrCodec(const FilePath &executable) const TextEncoding DesktopDeviceFileAccess::processStdErrEncoding(const FilePath &executable) const
{ {
Q_UNUSED(executable) Q_UNUSED(executable)
return TextCodec::codecForLocale(); return TextCodec::encodingForLocale();
} }
QDateTime DesktopDeviceFileAccess::lastModified(const FilePath &filePath) const QDateTime DesktopDeviceFileAccess::lastModified(const FilePath &filePath) const

View File

@@ -14,7 +14,7 @@ namespace Utils {
class CommandLine; class CommandLine;
class RunResult; class RunResult;
class TextCodec; class TextEncoding;
// Base class including dummy implementation usable as fallback. // Base class including dummy implementation usable as fallback.
class QTCREATOR_UTILS_EXPORT DeviceFileAccess class QTCREATOR_UTILS_EXPORT DeviceFileAccess
@@ -83,8 +83,8 @@ protected:
virtual Utils::Result<std::unique_ptr<FilePathWatcher>> watch(const FilePath &path) const; virtual Utils::Result<std::unique_ptr<FilePathWatcher>> watch(const FilePath &path) const;
virtual TextCodec processStdOutCodec(const FilePath &executable) const; virtual TextEncoding processStdOutEncoding(const FilePath &executable) const;
virtual TextCodec processStdErrCodec(const FilePath &executable) const; virtual TextEncoding processStdErrEncoding(const FilePath &executable) const;
}; };
class QTCREATOR_UTILS_EXPORT UnavailableDeviceFileAccess : public DeviceFileAccess class QTCREATOR_UTILS_EXPORT UnavailableDeviceFileAccess : public DeviceFileAccess
@@ -209,10 +209,10 @@ protected:
Result<FilePath> createTempFile(const FilePath &filePath) override; Result<FilePath> createTempFile(const FilePath &filePath) override;
Utils::Result<std::unique_ptr<FilePathWatcher>> watch(const FilePath &path) const override; Result<std::unique_ptr<FilePathWatcher>> watch(const FilePath &path) const override;
TextCodec processStdOutCodec(const FilePath &executable) const override; TextEncoding processStdOutEncoding(const FilePath &executable) const override;
TextCodec processStdErrCodec(const FilePath &executable) const override; TextEncoding processStdErrEncoding(const FilePath &executable) const override;
}; };
class QTCREATOR_UTILS_EXPORT UnixDeviceFileAccess : public DeviceFileAccess class QTCREATOR_UTILS_EXPORT UnixDeviceFileAccess : public DeviceFileAccess

View File

@@ -2189,14 +2189,14 @@ QChar FilePath::pathListSeparator() const
return osType() == OsTypeWindows ? u';' : u':'; return osType() == OsTypeWindows ? u';' : u':';
} }
TextCodec FilePath::processStdOutCodec() const TextEncoding FilePath::processStdOutEncoding() const
{ {
return fileAccess()->processStdOutCodec(*this); return fileAccess()->processStdOutEncoding(*this);
} }
TextCodec FilePath::processStdErrCodec() const TextEncoding FilePath::processStdErrEncoding() const
{ {
return fileAccess()->processStdErrCodec(*this); return fileAccess()->processStdErrEncoding(*this);
} }
/*! /*!

View File

@@ -34,7 +34,7 @@ namespace Utils {
class DeviceFileAccess; class DeviceFileAccess;
class Environment; class Environment;
enum class FileStreamHandle; enum class FileStreamHandle;
class TextCodec; class TextEncoding;
template <class ...Args> using Continuation = std::function<void(Args...)>; template <class ...Args> using Continuation = std::function<void(Args...)>;
using CopyContinuation = Continuation<const Result<> &>; using CopyContinuation = Continuation<const Result<> &>;
@@ -199,8 +199,8 @@ public:
QChar pathComponentSeparator() const; QChar pathComponentSeparator() const;
QChar pathListSeparator() const; QChar pathListSeparator() const;
TextCodec processStdOutCodec() const; TextEncoding processStdOutEncoding() const;
TextCodec processStdErrCodec() const; TextEncoding processStdErrEncoding() const;
void clear(); void clear();
bool isEmpty() const; bool isEmpty() const;

View File

@@ -198,15 +198,14 @@ public:
QString readAllData() QString readAllData()
{ {
QString msg = codec.toUnicode(rawData.data(), rawData.size(), &codecState); QString msg = decoder.decode(rawData);
rawData.clear(); rawData.clear();
return msg; return msg;
} }
QByteArray rawData; QByteArray rawData;
QString incompleteLineBuffer; // lines not yet signaled QString incompleteLineBuffer; // lines not yet signaled
TextCodec codec; QStringDecoder decoder;
TextCodec::ConverterState codecState;
std::function<void(const QString &lines)> outputCallback; std::function<void(const QString &lines)> outputCallback;
TextChannelMode m_textChannelMode = TextChannelMode::Off; TextChannelMode m_textChannelMode = TextChannelMode::Off;
@@ -732,8 +731,8 @@ public:
qint64 m_applicationMainThreadId = 0; qint64 m_applicationMainThreadId = 0;
ProcessResultData m_resultData; ProcessResultData m_resultData;
TextCodec m_stdOutCodec; std::optional<TextEncoding> m_stdOutEncoding;
TextCodec m_stdErrCodec; std::optional<TextEncoding> m_stdErrEncoding;
ProcessResult m_result = ProcessResult::StartFailed; ProcessResult m_result = ProcessResult::StartFailed;
ChannelBuffer m_stdOut; ChannelBuffer m_stdOut;
@@ -992,15 +991,15 @@ void ProcessPrivate::sendControlSignal(ControlSignal controlSignal)
void ProcessPrivate::clearForRun() void ProcessPrivate::clearForRun()
{ {
if (!m_stdOutCodec.isValid()) if (!m_stdOutEncoding)
m_stdOutCodec = m_setup.m_commandLine.executable().processStdOutCodec(); m_stdOutEncoding = m_setup.m_commandLine.executable().processStdOutEncoding();
m_stdOut.clearForRun(); m_stdOut.clearForRun();
m_stdOut.codec = m_stdOutCodec; m_stdOut.decoder = QStringDecoder(m_stdOutEncoding->name());
if (!m_stdErrCodec.isValid()) if (!m_stdErrEncoding)
m_stdErrCodec = m_setup.m_commandLine.executable().processStdErrCodec(); m_stdErrEncoding = m_setup.m_commandLine.executable().processStdErrEncoding();
m_stdErr.clearForRun(); m_stdErr.clearForRun();
m_stdErr.codec = m_stdErrCodec; m_stdErr.decoder = QStringDecoder(m_stdErrEncoding->name());
m_result = ProcessResult::StartFailed; m_result = ProcessResult::StartFailed;
m_startTimestamp = {}; m_startTimestamp = {};
@@ -1673,15 +1672,15 @@ QByteArray Process::rawStdErr() const
QString Process::stdOut() const QString Process::stdOut() const
{ {
QTC_CHECK(d->m_stdOut.keepRawData); QTC_CHECK(d->m_stdOut.keepRawData);
QTC_ASSERT(d->m_stdOutCodec.isValid(), return {}); // Process was not started QTC_ASSERT(d->m_stdOutEncoding, return {}); // Process was not started
return d->m_stdOutCodec.toUnicode(d->m_stdOut.rawData); return d->m_stdOut.decoder.decode(d->m_stdOut.rawData);
} }
QString Process::stdErr() const QString Process::stdErr() const
{ {
QTC_CHECK(d->m_stdErr.keepRawData); QTC_CHECK(d->m_stdErr.keepRawData);
QTC_ASSERT(d->m_stdErrCodec.isValid(), return {}); // Process was not started QTC_ASSERT(d->m_stdOutEncoding, return {}); // Process was not started
return d->m_stdErrCodec.toUnicode(d->m_stdErr.rawData); return d->m_stdOut.decoder.decode(d->m_stdErr.rawData);
} }
QString Process::cleanedStdOut() const QString Process::cleanedStdOut() const
@@ -1726,7 +1725,6 @@ QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug str, const Process &r)
void ChannelBuffer::clearForRun() void ChannelBuffer::clearForRun()
{ {
rawData.clear(); rawData.clear();
codecState.reset();
incompleteLineBuffer.clear(); incompleteLineBuffer.clear();
} }
@@ -1745,7 +1743,7 @@ void ChannelBuffer::append(const QByteArray &text)
return; return;
// Convert and append the new input to the buffer of incomplete lines // Convert and append the new input to the buffer of incomplete lines
incompleteLineBuffer.append(codec.toUnicode(text.constData(), text.size(), &codecState)); incompleteLineBuffer.append(decoder.decode(text));
QStringView bufferView(incompleteLineBuffer); QStringView bufferView(incompleteLineBuffer);
@@ -1796,27 +1794,21 @@ void ChannelBuffer::handleRest()
} }
} }
void Process::setCodec(const TextCodec &codec)
{
QTC_ASSERT(codec.isValid(), return);
d->m_stdOutCodec = codec;
d->m_stdErrCodec = codec;
}
void Process::setEncoding(const TextEncoding &encoding) void Process::setEncoding(const TextEncoding &encoding)
{ {
setCodec(TextCodec::codecForName(encoding)); d->m_stdOutEncoding = encoding;
d->m_stdErrEncoding = encoding;
} }
void Process::setUtf8Codec() void Process::setUtf8Codec()
{ {
d->m_stdOutCodec = TextCodec::utf8(); d->m_stdOutEncoding = QStringDecoder::Utf8;
d->m_stdErrCodec = TextCodec::utf8(); d->m_stdErrEncoding = QStringDecoder::Utf8;
} }
void Process::setUtf8StdOutCodec() void Process::setUtf8StdOutCodec()
{ {
d->m_stdOutCodec = TextCodec::utf8(); d->m_stdOutEncoding = QStringDecoder::Utf8;
} }
void Process::setTimeOutMessageBoxEnabled(bool v) void Process::setTimeOutMessageBoxEnabled(bool v)

View File

@@ -28,6 +28,7 @@ class ProcessInterface;
class ProcessResultData; class ProcessResultData;
class ProcessRunData; class ProcessRunData;
class TextEncoding; class TextEncoding;
class TextCodec;
class QTCREATOR_UTILS_EXPORT Process final : public QObject class QTCREATOR_UTILS_EXPORT Process final : public QObject
{ {
@@ -144,7 +145,6 @@ public:
void runBlocking(std::chrono::seconds timeout = std::chrono::seconds(10), void runBlocking(std::chrono::seconds timeout = std::chrono::seconds(10),
EventLoopMode eventLoopMode = EventLoopMode::Off); EventLoopMode eventLoopMode = EventLoopMode::Off);
void setCodec(const TextCodec &codec); // for stdOut and stdErr
void setEncoding(const TextEncoding &encoding); // for stdOut and stdErr void setEncoding(const TextEncoding &encoding); // for stdOut and stdErr
void setUtf8Codec(); // for stdOut and stdErr void setUtf8Codec(); // for stdOut and stdErr
void setUtf8StdOutCodec(); // for stdOut, stdErr uses executable.processStdErrCodec() void setUtf8StdOutCodec(); // for stdOut, stdErr uses executable.processStdErrCodec()

View File

@@ -21,6 +21,12 @@ public:
TextEncoding(const QByteArray &name); TextEncoding(const QByteArray &name);
TextEncoding(QStringEncoder::Encoding encoding); TextEncoding(QStringEncoder::Encoding encoding);
static const QStringConverter::Encoding Utf8 = QStringConverter::Encoding::Utf8;
static const QStringConverter::Encoding Utf16 = QStringConverter::Encoding::Utf16;
static const QStringConverter::Encoding Utf32 = QStringConverter::Encoding::Utf32;
static const QStringConverter::Encoding Latin1 = QStringConverter::Encoding::Latin1;
static const QStringConverter::Encoding System = QStringConverter::Encoding::System;
operator QByteArray() const { return m_name; } operator QByteArray() const { return m_name; }
QByteArray name() const { return m_name; } QByteArray name() const { return m_name; }