Utils: Make TextFileFormat::ReadResult a class

... containing the previous enum plus an error string, remove the
*errorString out-parameter from the static functions and adjust
all callers.

Change-Id: I9eab8b40cd28492906a1336fc6bab55cf1ae1122
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2025-04-16 17:23:11 +02:00
parent 66421d2950
commit 0c7d7b4cda
19 changed files with 149 additions and 178 deletions

View File

@@ -198,7 +198,7 @@ bool TextFileFormat::decode(const QByteArray &data, QStringList *target) const
// Read text file contents to string or stringlist. // Read text file contents to string or stringlist.
template <class Target> template <class Target>
TextFileFormat::ReadResult readTextFile(const FilePath &filePath, const QTextCodec *defaultCodec, TextFileFormat::ReadResult readTextFile(const FilePath &filePath, const QTextCodec *defaultCodec,
Target *target, TextFileFormat *format, QString *errorString, Target *target, TextFileFormat *format,
QByteArray *decodingErrorSampleIn = nullptr) QByteArray *decodingErrorSampleIn = nullptr)
{ {
if (decodingErrorSampleIn) if (decodingErrorSampleIn)
@@ -207,15 +207,11 @@ TextFileFormat::ReadResult readTextFile(const FilePath &filePath, const QTextCod
QByteArray data; QByteArray data;
try { try {
FileReader reader; FileReader reader;
if (!reader.fetch(filePath, errorString)) if (const Result<> res = reader.fetch(filePath); !res)
return TextFileFormat::ReadIOError; return {TextFileFormat::ReadIOError, res.error()};
data = reader.data(); data = reader.data();
} catch (const std::bad_alloc &) { } catch (const std::bad_alloc &) {
if (errorString) return {TextFileFormat::ReadMemoryAllocationError, Tr::tr("Out of memory.")};
*errorString = Tr::tr("Out of memory.");
else
qWarning() << Q_FUNC_INFO << "Out of memory in" << filePath;
return TextFileFormat::ReadMemoryAllocationError;
} }
if (!data.isEmpty()) if (!data.isEmpty())
@@ -225,13 +221,9 @@ TextFileFormat::ReadResult readTextFile(const FilePath &filePath, const QTextCod
format->setCodec(defaultCodec ? defaultCodec : QTextCodec::codecForLocale()); format->setCodec(defaultCodec ? defaultCodec : QTextCodec::codecForLocale());
if (!format->decode(data, target)) { if (!format->decode(data, target)) {
if (errorString)
*errorString = Tr::tr("An encoding error was encountered.");
else
qWarning() << Q_FUNC_INFO << "An encoding error was encountered in" << filePath;
if (decodingErrorSampleIn) if (decodingErrorSampleIn)
*decodingErrorSampleIn = TextFileFormat::decodingErrorSample(data); *decodingErrorSampleIn = TextFileFormat::decodingErrorSample(data);
return TextFileFormat::ReadEncodingError; return {TextFileFormat::ReadEncodingError, Tr::tr("An encoding error was encountered.")};
} }
return TextFileFormat::ReadSuccess; return TextFileFormat::ReadSuccess;
} }
@@ -247,15 +239,14 @@ TextFileFormat::ReadResult readTextFile(const FilePath &filePath, const QTextCod
TextFileFormat::ReadResult TextFileFormat::ReadResult
TextFileFormat::readFile(const FilePath &filePath, const QTextCodec *defaultCodec, TextFileFormat::readFile(const FilePath &filePath, const QTextCodec *defaultCodec,
QStringList *plainTextList, TextFileFormat *format, QString *errorString, QStringList *plainTextList, TextFileFormat *format,
QByteArray *decodingErrorSample /* = 0 */) QByteArray *decodingErrorSample /* = 0 */)
{ {
const TextFileFormat::ReadResult result = const TextFileFormat::ReadResult result =
readTextFile(filePath, defaultCodec, readTextFile(filePath, defaultCodec, plainTextList, format, decodingErrorSample);
plainTextList, format, errorString, decodingErrorSample);
if (debug) if (debug)
qDebug().nospace() << Q_FUNC_INFO << filePath << ' ' << *format qDebug().nospace() << Q_FUNC_INFO << filePath << ' ' << *format
<< " returns " << result << '/' << plainTextList->size() << " chunks"; << " returns " << result.code << '/' << plainTextList->size() << " chunks";
return result; return result;
} }
@@ -270,31 +261,30 @@ TextFileFormat::ReadResult
TextFileFormat::ReadResult TextFileFormat::ReadResult
TextFileFormat::readFile(const FilePath &filePath, const QTextCodec *defaultCodec, TextFileFormat::readFile(const FilePath &filePath, const QTextCodec *defaultCodec,
QString *plainText, TextFileFormat *format, QString *errorString, QString *plainText, TextFileFormat *format,
QByteArray *decodingErrorSample /* = 0 */) QByteArray *decodingErrorSample /* = 0 */)
{ {
const TextFileFormat::ReadResult result = const TextFileFormat::ReadResult result =
readTextFile(filePath, defaultCodec, readTextFile(filePath, defaultCodec,
plainText, format, errorString, decodingErrorSample); plainText, format, decodingErrorSample);
if (debug) if (debug)
qDebug().nospace() << Q_FUNC_INFO << filePath << ' ' << *format qDebug().nospace() << Q_FUNC_INFO << filePath << ' ' << *format
<< " returns " << result << '/' << plainText->size() << " characters"; << " returns " << result.code << '/' << plainText->size() << " characters";
return result; return result;
} }
TextFileFormat::ReadResult TextFileFormat::readFileUTF8(const FilePath &filePath, TextFileFormat::ReadResult TextFileFormat::readFileUTF8(const FilePath &filePath,
const QTextCodec *defaultCodec, const QTextCodec *defaultCodec,
QByteArray *plainText, QString *errorString) QByteArray *plainText)
{ {
QByteArray data; QByteArray data;
try { try {
FileReader reader; FileReader reader;
if (!reader.fetch(filePath, errorString)) if (const Result<> res = reader.fetch(filePath); !res)
return TextFileFormat::ReadIOError; return {TextFileFormat::ReadIOError, res.error()};
data = reader.data(); data = reader.data();
} catch (const std::bad_alloc &) { } catch (const std::bad_alloc &) {
*errorString = Tr::tr("Out of memory."); return {TextFileFormat::ReadMemoryAllocationError, Tr::tr("Out of memory.")};
return TextFileFormat::ReadMemoryAllocationError;
} }
TextFileFormat format = TextFileFormat::detect(data); TextFileFormat format = TextFileFormat::detect(data);
@@ -313,16 +303,15 @@ TextFileFormat::ReadResult TextFileFormat::readFileUTF8(const FilePath &filePath
return TextFileFormat::ReadSuccess; return TextFileFormat::ReadSuccess;
} }
tl::expected<QString, std::pair<TextFileFormat::ReadResult, QString>> tl::expected<QString, TextFileFormat::ReadResult>
TextFileFormat::readFile(const FilePath &filePath, const QTextCodec *defaultCodec) TextFileFormat::readFile(const FilePath &filePath, const QTextCodec *defaultCodec)
{ {
QString plainText; QString plainText;
TextFileFormat format; TextFileFormat format;
QString errorString;
const TextFileFormat::ReadResult result = const TextFileFormat::ReadResult result =
readTextFile(filePath, defaultCodec, &plainText, &format, &errorString, nullptr); readTextFile(filePath, defaultCodec, &plainText, &format, nullptr);
if (result != TextFileFormat::ReadSuccess) if (result.code != TextFileFormat::ReadSuccess)
return tl::unexpected(std::make_pair(result, errorString)); return tl::unexpected(result);
return plainText; return plainText;
} }

View File

@@ -8,8 +8,6 @@
#include <QStringList> #include <QStringList>
#include <utility>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QTextCodec; class QTextCodec;
class QByteArray; class QByteArray;
@@ -34,14 +32,24 @@ public:
#endif #endif
}; };
enum ReadResult enum ReadResultCode {
{
ReadSuccess, ReadSuccess,
ReadEncodingError, ReadEncodingError,
ReadMemoryAllocationError, ReadMemoryAllocationError,
ReadIOError ReadIOError
}; };
class QTCREATOR_UTILS_EXPORT ReadResult
{
public:
ReadResult() = default;
ReadResult(ReadResultCode code) : code(code) {}
ReadResult(ReadResultCode code, const QString &error) : code(code), error(error) {}
ReadResultCode code;
QString error;
};
TextFileFormat(); TextFileFormat();
static TextFileFormat detect(const QByteArray &data); static TextFileFormat detect(const QByteArray &data);
@@ -50,15 +58,16 @@ public:
bool decode(const QByteArray &data, QStringList *target) const; bool decode(const QByteArray &data, QStringList *target) const;
static ReadResult readFile(const FilePath &filePath, const QTextCodec *defaultCodec, static ReadResult readFile(const FilePath &filePath, const QTextCodec *defaultCodec,
QStringList *plainText, TextFileFormat *format, QString *errorString, QStringList *plainText, TextFileFormat *format,
QByteArray *decodingErrorSample = nullptr); QByteArray *decodingErrorSample = nullptr);
static ReadResult readFile(const FilePath &filePath, const QTextCodec *defaultCodec, static ReadResult readFile(const FilePath &filePath, const QTextCodec *defaultCodec,
QString *plainText, TextFileFormat *format, QString *errorString, QString *plainText, TextFileFormat *format,
QByteArray *decodingErrorSample = nullptr); QByteArray *decodingErrorSample = nullptr);
static ReadResult readFileUTF8(const FilePath &filePath, const QTextCodec *defaultCodec, static ReadResult readFileUTF8(const FilePath &filePath, const QTextCodec *defaultCodec,
QByteArray *plainText, QString *errorString); QByteArray *plainText);
static tl::expected<QString, std::pair<ReadResult, QString>>
readFile(const FilePath &filePath, const QTextCodec *defaultCodec); static tl::expected<QString, ReadResult> readFile(const FilePath &filePath,
const QTextCodec *defaultCodec);
Utils::Result<> writeFile(const FilePath &filePath, QString plainText) const; Utils::Result<> writeFile(const FilePath &filePath, QString plainText) const;

View File

@@ -47,12 +47,11 @@ QByteArray CppParser::getFileContent(const FilePath &filePath) const
if (const auto source = m_workingCopy.source(filePath)) { if (const auto source = m_workingCopy.source(filePath)) {
fileContent = *source; fileContent = *source;
} else { } else {
QString error;
const QTextCodec *codec = Core::EditorManager::defaultTextCodec(); const QTextCodec *codec = Core::EditorManager::defaultTextCodec();
if (TextFileFormat::readFileUTF8(filePath, codec, &fileContent, &error) const TextFileFormat::ReadResult result =
!= TextFileFormat::ReadSuccess) { TextFileFormat::readFileUTF8(filePath, codec, &fileContent);
qDebug() << "Failed to read file" << filePath << ":" << error; if (result.code != TextFileFormat::ReadSuccess)
} qDebug() << "Failed to read file" << filePath << ":" << result.error;
} }
fileContent.replace("\r\n", "\n"); fileContent.replace("\r\n", "\n");
return fileContent; return fileContent;

View File

@@ -140,16 +140,14 @@ QTextDocument *FixitsRefactoringFile::document(const FilePath &filePath) const
if (m_documents.find(filePath) == m_documents.end()) { if (m_documents.find(filePath) == m_documents.end()) {
QString fileContents; QString fileContents;
if (!filePath.isEmpty()) { if (!filePath.isEmpty()) {
QString error;
QTextCodec *defaultCodec = Core::EditorManager::defaultTextCodec(); QTextCodec *defaultCodec = Core::EditorManager::defaultTextCodec();
TextFileFormat::ReadResult result = TextFileFormat::readFile(filePath, TextFileFormat::ReadResult result = TextFileFormat::readFile(filePath,
defaultCodec, defaultCodec,
&fileContents, &fileContents,
&m_textFileFormat, &m_textFileFormat);
&error); if (result.code != TextFileFormat::ReadSuccess) {
if (result != TextFileFormat::ReadSuccess) {
qCDebug(fixitsLog) qCDebug(fixitsLog)
<< "ERROR: Could not read " << filePath.toUserOutput() << ":" << error; << "ERROR: Could not read " << filePath.toUserOutput() << ":" << result.error;
m_textFileFormat.setCodec(nullptr); m_textFileFormat.setCodec(nullptr);
} }
} }

View File

@@ -55,7 +55,7 @@ BaseTextDocument::~BaseTextDocument()
bool BaseTextDocument::hasDecodingError() const bool BaseTextDocument::hasDecodingError() const
{ {
return d->m_readResult == TextFileFormat::ReadEncodingError; return d->m_readResult.code == TextFileFormat::ReadEncodingError;
} }
QByteArray BaseTextDocument::decodingErrorSample() const QByteArray BaseTextDocument::decodingErrorSample() const
@@ -129,16 +129,14 @@ bool BaseTextDocument::isUtf8Codec(const QByteArray &name)
Returns whether the operation was successful. Returns whether the operation was successful.
*/ */
BaseTextDocument::ReadResult BaseTextDocument::read(const Utils::FilePath &filePath, BaseTextDocument::ReadResult BaseTextDocument::read(const FilePath &filePath,
QStringList *plainTextList, QStringList *plainTextList)
QString *errorString)
{ {
d->m_readResult = Utils::TextFileFormat::readFile(filePath, d->m_readResult = TextFileFormat::readFile(filePath,
codec(), codec(),
plainTextList, plainTextList,
&d->m_format, &d->m_format,
errorString, &d->m_decodingErrorSample);
&d->m_decodingErrorSample);
return d->m_readResult; return d->m_readResult;
} }
@@ -152,16 +150,14 @@ BaseTextDocument::ReadResult BaseTextDocument::read(const Utils::FilePath &fileP
Returns whether the operation was successful. Returns whether the operation was successful.
*/ */
BaseTextDocument::ReadResult BaseTextDocument::read(const Utils::FilePath &filePath, BaseTextDocument::ReadResult BaseTextDocument::read(const FilePath &filePath,
QString *plainText, QString *plainText)
QString *errorString)
{ {
d->m_readResult = Utils::TextFileFormat::readFile(filePath, d->m_readResult = TextFileFormat::readFile(filePath,
codec(), codec(),
plainText, plainText,
&d->m_format, &d->m_format,
errorString, &d->m_decodingErrorSample);
&d->m_decodingErrorSample);
return d->m_readResult; return d->m_readResult;
} }

View File

@@ -31,8 +31,8 @@ public:
bool supportsUtf8Bom() const; bool supportsUtf8Bom() const;
Utils::TextFileFormat::LineTerminationMode lineTerminationMode() const; Utils::TextFileFormat::LineTerminationMode lineTerminationMode() const;
ReadResult read(const Utils::FilePath &filePath, QStringList *plainTextList, QString *errorString); ReadResult read(const Utils::FilePath &filePath, QStringList *plainTextList);
ReadResult read(const Utils::FilePath &filePath, QString *plainText, QString *errorString); ReadResult read(const Utils::FilePath &filePath, QString *plainText);
bool hasDecodingError() const; bool hasDecodingError() const;
QByteArray decodingErrorSample() const; QByteArray decodingErrorSample() const;

View File

@@ -101,24 +101,21 @@ void CppSearchResultFilter::setValue(bool &member, bool value)
namespace Internal { namespace Internal {
static QByteArray getSource(const FilePath &fileName, const WorkingCopy &workingCopy)
static QByteArray getSource(const Utils::FilePath &fileName,
const WorkingCopy &workingCopy)
{ {
if (const auto source = workingCopy.source(fileName)) { if (const auto source = workingCopy.source(fileName))
return *source; return *source;
} else {
QString fileContents;
Utils::TextFileFormat format;
QString error;
QTextCodec *defaultCodec = EditorManager::defaultTextCodec();
Utils::TextFileFormat::ReadResult result = Utils::TextFileFormat::readFile(
fileName, defaultCodec, &fileContents, &format, &error);
if (result != Utils::TextFileFormat::ReadSuccess)
qWarning() << "Could not read " << fileName << ". Error: " << error;
return fileContents.toUtf8(); QString fileContents;
} TextFileFormat format;
QString error;
QTextCodec *defaultCodec = EditorManager::defaultTextCodec();
TextFileFormat::ReadResult result = TextFileFormat::readFile(
fileName, defaultCodec, &fileContents, &format);
if (result.code != TextFileFormat::ReadSuccess)
qWarning() << "Could not read " << fileName << ". Error: " << result.error;
return fileContents.toUtf8();
} }
static QByteArray typeId(CPlusPlus::Symbol *symbol) static QByteArray typeId(CPlusPlus::Symbol *symbol)

View File

@@ -192,14 +192,11 @@ bool CppSourceProcessor::getFileContents(const FilePath &absoluteFilePath,
// Get from file // Get from file
*revision = 0; *revision = 0;
QString error; const TextFileFormat::ReadResult result =
if (Utils::TextFileFormat::readFileUTF8(absoluteFilePath, TextFileFormat::readFileUTF8(absoluteFilePath, m_defaultCodec, contents);
m_defaultCodec, if (result.code != TextFileFormat::ReadSuccess) {
contents,
&error)
!= Utils::TextFileFormat::ReadSuccess) {
qWarning("Error reading file \"%s\": \"%s\".", qPrintable(absoluteFilePath.toUrlishString()), qWarning("Error reading file \"%s\": \"%s\".", qPrintable(absoluteFilePath.toUrlishString()),
qPrintable(error)); qPrintable(result.error));
return false; return false;
} }
contents->replace("\r\n", "\n"); contents->replace("\r\n", "\n");

View File

@@ -55,20 +55,18 @@ Result<> FormWindowFile::open(const FilePath &filePath, const FilePath &realFile
return ResultError("File name is empty"); // FIXME: Use something better return ResultError("File name is empty"); // FIXME: Use something better
QString contents; QString contents;
QString errorString; TextFileFormat::ReadResult readResult = read(filePath.absoluteFilePath(), &contents);
TextFileFormat::ReadResult readResult = read(filePath.absoluteFilePath(), if (readResult.code == TextFileFormat::ReadEncodingError)
&contents, return ResultError(readResult.error);
&errorString); if (readResult.code != TextFileFormat::ReadSuccess)
if (readResult == TextFileFormat::ReadEncodingError) return ResultError(readResult.error);
return ResultError(errorString);
if (readResult != TextFileFormat::ReadSuccess)
return ResultError(errorString);
form->setFileName(filePath.absoluteFilePath().toUrlishString()); form->setFileName(filePath.absoluteFilePath().toUrlishString());
const QByteArray contentsBA = contents.toUtf8(); const QByteArray contentsBA = contents.toUtf8();
QBuffer str; QBuffer str;
str.setData(contentsBA); str.setData(contentsBA);
str.open(QIODevice::ReadOnly); str.open(QIODevice::ReadOnly);
QString errorString;
if (!form->setContents(&str, &errorString)) if (!form->setContents(&str, &errorString))
return ResultError(errorString); return ResultError(errorString);
form->setDirty(filePath != realFilePath); form->setDirty(filePath != realFilePath);

View File

@@ -270,18 +270,17 @@ Result<> DiffEditorDocument::open(const FilePath &filePath, const FilePath &real
QTC_CHECK(filePath == realFilePath); // does not support autosave QTC_CHECK(filePath == realFilePath); // does not support autosave
beginReload(); beginReload();
QString patch; QString patch;
QString errorString; ReadResult readResult = read(filePath, &patch);
ReadResult readResult = read(filePath, &patch, &errorString); if (readResult.code == TextFileFormat::ReadIOError
if (readResult == TextFileFormat::ReadIOError || readResult.code == TextFileFormat::ReadMemoryAllocationError) {
|| readResult == TextFileFormat::ReadMemoryAllocationError) { return ResultError(readResult.error);
return ResultError(errorString);
} }
const std::optional<QList<FileData>> fileDataList = DiffUtils::readPatch(patch); const std::optional<QList<FileData>> fileDataList = DiffUtils::readPatch(patch);
bool ok = fileDataList.has_value(); bool ok = fileDataList.has_value();
if (!ok) { if (!ok) {
errorString = Tr::tr("Could not parse patch file \"%1\". " readResult.error = Tr::tr("Could not parse patch file \"%1\". "
"The content is not of unified diff format.") "The content is not of unified diff format.")
.arg(filePath.toUserOutput()); .arg(filePath.toUserOutput());
} else { } else {
setTemporary(false); setTemporary(false);
@@ -291,10 +290,10 @@ Result<> DiffEditorDocument::open(const FilePath &filePath, const FilePath &real
setDiffFiles(*fileDataList); setDiffFiles(*fileDataList);
} }
endReload(ok); endReload(ok);
if (!ok && readResult == TextFileFormat::ReadEncodingError) if (!ok && readResult.code == TextFileFormat::ReadEncodingError)
ok = selectEncoding(); ok = selectEncoding();
if (!ok) if (!ok)
return ResultError(errorString); return ResultError(readResult.error);
return ResultOk; return ResultOk;
} }

View File

@@ -176,12 +176,11 @@ QList<ReloadInput> DiffCurrentFileController::reloadInputList() const
DocumentModel::documentForFilePath(FilePath::fromString(m_fileName))); DocumentModel::documentForFilePath(FilePath::fromString(m_fileName)));
if (textDocument && textDocument->isModified()) { if (textDocument && textDocument->isModified()) {
QString errorString;
TextFileFormat format = textDocument->format(); TextFileFormat format = textDocument->format();
QString leftText; QString leftText;
const TextFileFormat::ReadResult leftResult = TextFileFormat::readFile( const TextFileFormat::ReadResult leftResult = TextFileFormat::readFile(
FilePath::fromString(m_fileName), format.codec(), &leftText, &format, &errorString); FilePath::fromString(m_fileName), format.codec(), &leftText, &format);
const QString rightText = textDocument->plainText(); const QString rightText = textDocument->plainText();
@@ -190,9 +189,9 @@ QList<ReloadInput> DiffCurrentFileController::reloadInputList() const
reloadInput.fileInfo = {DiffFileInfo(m_fileName, Tr::tr("Saved")), reloadInput.fileInfo = {DiffFileInfo(m_fileName, Tr::tr("Saved")),
DiffFileInfo(m_fileName, Tr::tr("Modified"))}; DiffFileInfo(m_fileName, Tr::tr("Modified"))};
reloadInput.fileInfo[RightSide].patchBehaviour = DiffFileInfo::PatchEditor; reloadInput.fileInfo[RightSide].patchBehaviour = DiffFileInfo::PatchEditor;
reloadInput.binaryFiles = (leftResult == TextFileFormat::ReadEncodingError); reloadInput.binaryFiles = (leftResult.code == TextFileFormat::ReadEncodingError);
if (leftResult == TextFileFormat::ReadIOError) if (leftResult.code == TextFileFormat::ReadIOError)
reloadInput.fileOperation = FileData::NewFile; reloadInput.fileOperation = FileData::NewFile;
result << reloadInput; result << reloadInput;
@@ -229,7 +228,7 @@ QList<ReloadInput> DiffOpenFilesController::reloadInputList() const
QString leftText; QString leftText;
const QString fileName = textDocument->filePath().toUrlishString(); const QString fileName = textDocument->filePath().toUrlishString();
const TextFileFormat::ReadResult leftResult = TextFileFormat::readFile( const TextFileFormat::ReadResult leftResult = TextFileFormat::readFile(
FilePath::fromString(fileName), format.codec(), &leftText, &format, &errorString); FilePath::fromString(fileName), format.codec(), &leftText, &format);
const QString rightText = textDocument->plainText(); const QString rightText = textDocument->plainText();
@@ -238,9 +237,9 @@ QList<ReloadInput> DiffOpenFilesController::reloadInputList() const
reloadInput.fileInfo = {DiffFileInfo(fileName, Tr::tr("Saved")), reloadInput.fileInfo = {DiffFileInfo(fileName, Tr::tr("Saved")),
DiffFileInfo(fileName, Tr::tr("Modified"))}; DiffFileInfo(fileName, Tr::tr("Modified"))};
reloadInput.fileInfo[RightSide].patchBehaviour = DiffFileInfo::PatchEditor; reloadInput.fileInfo[RightSide].patchBehaviour = DiffFileInfo::PatchEditor;
reloadInput.binaryFiles = (leftResult == TextFileFormat::ReadEncodingError); reloadInput.binaryFiles = (leftResult.code == TextFileFormat::ReadEncodingError);
if (leftResult == TextFileFormat::ReadIOError) if (leftResult.code == TextFileFormat::ReadIOError)
reloadInput.fileOperation = FileData::NewFile; reloadInput.fileOperation = FileData::NewFile;
result << reloadInput; result << reloadInput;
@@ -281,7 +280,7 @@ QList<ReloadInput> DiffModifiedFilesController::reloadInputList() const
QString leftText; QString leftText;
const QString fileName = textDocument->filePath().toUrlishString(); const QString fileName = textDocument->filePath().toUrlishString();
const TextFileFormat::ReadResult leftResult = TextFileFormat::readFile( const TextFileFormat::ReadResult leftResult = TextFileFormat::readFile(
FilePath::fromString(fileName), format.codec(), &leftText, &format, &errorString); FilePath::fromString(fileName), format.codec(), &leftText, &format);
const QString rightText = textDocument->plainText(); const QString rightText = textDocument->plainText();
@@ -290,9 +289,9 @@ QList<ReloadInput> DiffModifiedFilesController::reloadInputList() const
reloadInput.fileInfo = {DiffFileInfo(fileName, Tr::tr("Saved")), reloadInput.fileInfo = {DiffFileInfo(fileName, Tr::tr("Saved")),
DiffFileInfo(fileName, Tr::tr("Modified"))}; DiffFileInfo(fileName, Tr::tr("Modified"))};
reloadInput.fileInfo[RightSide].patchBehaviour = DiffFileInfo::PatchEditor; reloadInput.fileInfo[RightSide].patchBehaviour = DiffFileInfo::PatchEditor;
reloadInput.binaryFiles = (leftResult == TextFileFormat::ReadEncodingError); reloadInput.binaryFiles = (leftResult.code == TextFileFormat::ReadEncodingError);
if (leftResult == TextFileFormat::ReadIOError) if (leftResult.code == TextFileFormat::ReadIOError)
reloadInput.fileOperation = FileData::NewFile; reloadInput.fileOperation = FileData::NewFile;
result << reloadInput; result << reloadInput;
@@ -332,19 +331,19 @@ QList<ReloadInput> DiffExternalFilesController::reloadInputList() const
QString rightText; QString rightText;
const TextFileFormat::ReadResult leftResult = TextFileFormat::readFile( const TextFileFormat::ReadResult leftResult = TextFileFormat::readFile(
m_leftFilePath, format.codec(), &leftText, &format, &errorString); m_leftFilePath, format.codec(), &leftText, &format);
const TextFileFormat::ReadResult rightResult = TextFileFormat::readFile( const TextFileFormat::ReadResult rightResult = TextFileFormat::readFile(
m_rightFilePath, format.codec(), &rightText, &format, &errorString); m_rightFilePath, format.codec(), &rightText, &format);
ReloadInput reloadInput; ReloadInput reloadInput;
reloadInput.text = {leftText, rightText}; reloadInput.text = {leftText, rightText};
reloadInput.fileInfo[LeftSide].fileName = m_leftFilePath.toUrlishString(); reloadInput.fileInfo[LeftSide].fileName = m_leftFilePath.toUrlishString();
reloadInput.fileInfo[RightSide].fileName = m_rightFilePath.toUrlishString(); reloadInput.fileInfo[RightSide].fileName = m_rightFilePath.toUrlishString();
reloadInput.binaryFiles = (leftResult == TextFileFormat::ReadEncodingError reloadInput.binaryFiles = leftResult.code == TextFileFormat::ReadEncodingError
|| rightResult == TextFileFormat::ReadEncodingError); || rightResult.code == TextFileFormat::ReadEncodingError;
const bool leftFileExists = (leftResult != TextFileFormat::ReadIOError); const bool leftFileExists = leftResult.code != TextFileFormat::ReadIOError;
const bool rightFileExists = (rightResult != TextFileFormat::ReadIOError); const bool rightFileExists = rightResult.code != TextFileFormat::ReadIOError;
if (!leftFileExists && rightFileExists) if (!leftFileExists && rightFileExists)
reloadInput.fileOperation = FileData::NewFile; reloadInput.fileOperation = FileData::NewFile;
else if (leftFileExists && !rightFileExists) else if (leftFileExists && !rightFileExists)

View File

@@ -3865,11 +3865,8 @@ IEditor *GitClient::openShowEditor(const FilePath &workingDirectory, const QStri
if (content.isEmpty()) if (content.isEmpty())
return nullptr; return nullptr;
QByteArray fileContent; QByteArray fileContent;
if (TextFileFormat::readFileUTF8(path, if (TextFileFormat::readFileUTF8(path, nullptr, &fileContent).code
nullptr, == TextFileFormat::ReadSuccess) {
&fileContent,
nullptr)
== TextFileFormat::ReadSuccess) {
if (fileContent == content) if (fileContent == content)
return nullptr; // open the file for read/write return nullptr; // open the file for read/write
} }

View File

@@ -26,6 +26,7 @@
#include <QLabel> #include <QLabel>
using namespace LanguageServerProtocol; using namespace LanguageServerProtocol;
using namespace Utils;
namespace LanguageClient { namespace LanguageClient {
@@ -277,20 +278,20 @@ bool operator==(const ItemData &id1, const ItemData &id2)
return id1.range == id2.range && id1.userData == id2.userData; return id1.range == id2.range && id1.userData == id2.userData;
} }
QStringList SymbolSupport::getFileContents(const Utils::FilePath &filePath) QStringList SymbolSupport::getFileContents(const FilePath &filePath)
{ {
QString fileContent; QString fileContent;
if (TextEditor::TextDocument *document = TextEditor::TextDocument::textDocumentForFilePath( if (TextEditor::TextDocument *document = TextEditor::TextDocument::textDocumentForFilePath(
filePath)) { filePath)) {
fileContent = document->plainText(); fileContent = document->plainText();
} else { } else {
Utils::TextFileFormat format; TextFileFormat format;
format.lineTerminationMode = Utils::TextFileFormat::LFLineTerminator; format.lineTerminationMode = TextFileFormat::LFLineTerminator;
QString error;
const QTextCodec *codec = Core::EditorManager::defaultTextCodec(); const QTextCodec *codec = Core::EditorManager::defaultTextCodec();
if (Utils::TextFileFormat::readFile(filePath, codec, &fileContent, &format, &error) const TextFileFormat::ReadResult result =
!= Utils::TextFileFormat::ReadSuccess) { TextFileFormat::readFile(filePath, codec, &fileContent, &format);
qDebug() << "Failed to read file" << filePath << ":" << error; if (result.code != TextFileFormat::ReadSuccess) {
qDebug() << "Failed to read file" << filePath << ":" << result.error;
} }
} }
return fileContent.split("\n"); return fileContent.split("\n");

View File

@@ -236,10 +236,9 @@ bool PythonBuildSystem::save()
if (filePath.fileName() == "pyproject.toml") { if (filePath.fileName() == "pyproject.toml") {
Core::BaseTextDocument projectFile; Core::BaseTextDocument projectFile;
QString pyProjectTomlContent; QString pyProjectTomlContent;
QString readingError; const BaseTextDocument::ReadResult result = projectFile.read(filePath, &pyProjectTomlContent);
auto result = projectFile.read(filePath, &pyProjectTomlContent, &readingError); if (result.code != TextFileFormat::ReadSuccess) {
if (result != TextFileFormat::ReadSuccess) { MessageManager::writeDisrupting(result.error);
MessageManager::writeDisrupting(readingError);
return false; return false;
} }
auto newPyProjectToml = updatePyProjectTomlContent(pyProjectTomlContent, projectFiles); auto newPyProjectToml = updatePyProjectTomlContent(pyProjectTomlContent, projectFiles);

View File

@@ -12,6 +12,8 @@
#include <utils/filepath.h> #include <utils/filepath.h>
using namespace Utils;
namespace Python::Internal { namespace Python::Internal {
/* /*
@@ -19,15 +21,14 @@ namespace Python::Internal {
\param relativeFilePath The relative path to the file from the testfiles folder \param relativeFilePath The relative path to the file from the testfiles folder
\returns The contents of the file \returns The contents of the file
*/ */
static Utils::Result<QString> readTestFile(const QString &relativeFilePath) static Result<QString> readTestFile(const QString &relativeFilePath)
{ {
const auto filePath = Utils::FilePath::fromUserInput(":/unittests/Python/" + relativeFilePath); const auto filePath = FilePath::fromUserInput(":/unittests/Python/" + relativeFilePath);
Core::BaseTextDocument projectFile; Core::BaseTextDocument projectFile;
QString fileContent; QString fileContent;
QString readingError; const Core::BaseTextDocument::ReadResult result = projectFile.read(filePath, &fileContent);
auto result = projectFile.read(filePath, &fileContent, &readingError); if (result.code != TextFileFormat::ReadSuccess)
if (result != Utils::TextFileFormat::ReadSuccess) return ResultError(result.error);
return Utils::make_unexpected(readingError);
return fileContent; return fileContent;
} }

View File

@@ -743,14 +743,13 @@ QPair<ProFile *, QStringList> QmakePriFile::readProFile()
{ {
QString contents; QString contents;
{ {
QString errorMsg; const TextFileFormat::ReadResult result =
if (TextFileFormat::readFile(filePath(), TextFileFormat::readFile(filePath(),
Core::EditorManager::defaultTextCodec(), Core::EditorManager::defaultTextCodec(),
&contents, &contents,
&m_textFormat, &m_textFormat);
&errorMsg) if (result.code != TextFileFormat::ReadSuccess) {
!= TextFileFormat::ReadSuccess) { QmakeBuildSystem::proFileParseError(result.error, filePath());
QmakeBuildSystem::proFileParseError(errorMsg, filePath());
return {includeFile, lines}; return {includeFile, lines};
} }
lines = contents.split('\n'); lines = contents.split('\n');

View File

@@ -322,17 +322,14 @@ bool QmlBuildSystem::setFileSettingInProjectFile(const QString &setting,
} }
QString fileContent; QString fileContent;
QString error; TextFileFormat textFileFormat;
Utils::TextFileFormat textFileFormat;
const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8 const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
Utils::TextFileFormat::ReadResult readResult = Utils::TextFileFormat::readFile(qmlProjectFilePath, TextFileFormat::ReadResult readResult = TextFileFormat::readFile(qmlProjectFilePath,
codec, codec,
&fileContent, &fileContent,
&textFileFormat, &textFileFormat);
&error); if (readResult.code != TextFileFormat::ReadSuccess)
if (readResult != Utils::TextFileFormat::ReadSuccess) { qWarning() << "Failed to read file" << qmlProjectFilePath << ":" << readResult.error;
qWarning() << "Failed to read file" << qmlProjectFilePath << ":" << error;
}
const QString settingQmlCode = setting + ":"; const QString settingQmlCode = setting + ":";
@@ -489,13 +486,12 @@ bool QmlBuildSystem::setMainUiFileInMainFile(const Utils::FilePath &newMainUiFil
} }
QString fileContent; QString fileContent;
QString error; TextFileFormat textFileFormat;
Utils::TextFileFormat textFileFormat;
const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8 const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
if (Utils::TextFileFormat::readFile(mainFilePath(), codec, &fileContent, &textFileFormat, &error) const TextFileFormat::ReadResult res =
!= Utils::TextFileFormat::ReadSuccess) { TextFileFormat::readFile(mainFilePath(), codec, &fileContent, &textFileFormat);
qWarning() << "Failed to read file" << mainFilePath() << ":" << error; if (res.code != TextFileFormat::ReadSuccess)
} qWarning() << "Failed to read file" << mainFilePath() << ":" << res.error;
const QString currentMain = QString("%1 {").arg(mainUiFilePath().baseName()); const QString currentMain = QString("%1 {").arg(mainUiFilePath().baseName());
const QString newMain = QString("%1 {").arg(newMainUiFilePath.baseName()); const QString newMain = QString("%1 {").arg(newMainUiFilePath.baseName());

View File

@@ -111,15 +111,13 @@ QTextDocument *RefactoringFile::mutableDocument() const
if (!m_document) { if (!m_document) {
QString fileContents; QString fileContents;
if (!m_filePath.isEmpty()) { if (!m_filePath.isEmpty()) {
QString error;
QTextCodec *defaultCodec = EditorManager::defaultTextCodec(); QTextCodec *defaultCodec = EditorManager::defaultTextCodec();
TextFileFormat::ReadResult result = TextFileFormat::readFile(m_filePath, TextFileFormat::ReadResult result = TextFileFormat::readFile(m_filePath,
defaultCodec, defaultCodec,
&fileContents, &fileContents,
&m_textFileFormat, &m_textFileFormat);
&error); if (result.code != TextFileFormat::ReadSuccess) {
if (result != TextFileFormat::ReadSuccess) { qWarning() << "Could not read " << m_filePath << ". Error: " << result.error;
qWarning() << "Could not read " << m_filePath << ". Error: " << error;
m_textFileFormat.setCodec(nullptr); m_textFileFormat.setCodec(nullptr);
} }
} }

View File

@@ -771,12 +771,11 @@ Result<> TextDocument::openImpl(const FilePath &filePath,
bool reload) bool reload)
{ {
QStringList content; QStringList content;
QString errorString;
ReadResult readResult = TextFileFormat::ReadIOError; ReadResult readResult = TextFileFormat::ReadIOError;
if (!filePath.isEmpty()) { if (!filePath.isEmpty()) {
readResult = read(realFilePath, &content, &errorString); readResult = read(realFilePath, &content);
const int chunks = content.size(); const int chunks = content.size();
// Don't call setUndoRedoEnabled(true) when reload is true and filenames are different, // Don't call setUndoRedoEnabled(true) when reload is true and filenames are different,
@@ -826,8 +825,8 @@ Result<> TextDocument::openImpl(const FilePath &filePath,
d->m_document.setModified(filePath != realFilePath); d->m_document.setModified(filePath != realFilePath);
setFilePath(filePath); setFilePath(filePath);
} }
if (readResult == TextFileFormat::ReadIOError) if (readResult.code == TextFileFormat::ReadIOError)
return ResultError(errorString); return ResultError(readResult.error);
return ResultOk; return ResultOk;
} }