forked from qt-creator/qt-creator
Utils: Add an offset parameter to the content writing FilePath function
Use QFile::seek to implement locally and a dd seek based poor man's implementation on RL and docker. Change-Id: I241d1c34c00e991845d132ad8edefa1377ba1311 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -586,28 +586,32 @@ void FilePath::asyncFileContents(const Continuation<const std::optional<QByteArr
|
|||||||
cont(fileContents(maxSize, offset));
|
cont(fileContents(maxSize, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilePath::writeFileContents(const QByteArray &data) const
|
bool FilePath::writeFileContents(const QByteArray &data, qint64 offset) const
|
||||||
{
|
{
|
||||||
if (needsDevice()) {
|
if (needsDevice()) {
|
||||||
QTC_ASSERT(s_deviceHooks.writeFileContents, return {});
|
QTC_ASSERT(s_deviceHooks.writeFileContents, return {});
|
||||||
return s_deviceHooks.writeFileContents(*this, data);
|
return s_deviceHooks.writeFileContents(*this, data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile file(path());
|
QFile file(path());
|
||||||
QTC_ASSERT(file.open(QFile::WriteOnly | QFile::Truncate), return false);
|
QTC_ASSERT(file.open(QFile::WriteOnly | QFile::Truncate), return false);
|
||||||
|
if (offset != 0)
|
||||||
|
file.seek(offset);
|
||||||
qint64 res = file.write(data);
|
qint64 res = file.write(data);
|
||||||
return res == data.size();
|
return res == data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilePath::asyncWriteFileContents(const Continuation<bool> &cont, const QByteArray &data) const
|
void FilePath::asyncWriteFileContents(const Continuation<bool> &cont,
|
||||||
|
const QByteArray &data,
|
||||||
|
qint64 offset) const
|
||||||
{
|
{
|
||||||
if (needsDevice()) {
|
if (needsDevice()) {
|
||||||
QTC_ASSERT(s_deviceHooks.asyncWriteFileContents, return);
|
QTC_ASSERT(s_deviceHooks.asyncWriteFileContents, return);
|
||||||
s_deviceHooks.asyncWriteFileContents(cont, *this, data);
|
s_deviceHooks.asyncWriteFileContents(cont, *this, data, offset);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cont(writeFileContents(data));
|
cont(writeFileContents(data, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilePath::needsDevice() const
|
bool FilePath::needsDevice() const
|
||||||
|
@@ -118,7 +118,7 @@ public:
|
|||||||
FilePaths dirEntries(const FileFilter &filter, QDir::SortFlags sort = QDir::NoSort) const;
|
FilePaths dirEntries(const FileFilter &filter, QDir::SortFlags sort = QDir::NoSort) const;
|
||||||
FilePaths dirEntries(QDir::Filters filters) const;
|
FilePaths dirEntries(QDir::Filters filters) const;
|
||||||
std::optional<QByteArray> fileContents(qint64 maxSize = -1, qint64 offset = 0) const;
|
std::optional<QByteArray> fileContents(qint64 maxSize = -1, qint64 offset = 0) const;
|
||||||
bool writeFileContents(const QByteArray &data) const;
|
bool writeFileContents(const QByteArray &data, qint64 offset = 0) const;
|
||||||
|
|
||||||
bool operator==(const FilePath &other) const;
|
bool operator==(const FilePath &other) const;
|
||||||
bool operator!=(const FilePath &other) const;
|
bool operator!=(const FilePath &other) const;
|
||||||
@@ -180,7 +180,9 @@ public:
|
|||||||
void asyncFileContents(const Continuation<const std::optional<QByteArray> &> &cont,
|
void asyncFileContents(const Continuation<const std::optional<QByteArray> &> &cont,
|
||||||
qint64 maxSize = -1,
|
qint64 maxSize = -1,
|
||||||
qint64 offset = 0) const;
|
qint64 offset = 0) const;
|
||||||
void asyncWriteFileContents(const Continuation<bool> &cont, const QByteArray &data) const;
|
void asyncWriteFileContents(const Continuation<bool> &cont,
|
||||||
|
const QByteArray &data,
|
||||||
|
qint64 offset = 0) const;
|
||||||
|
|
||||||
// Prefer not to use
|
// Prefer not to use
|
||||||
// Using needsDevice() in "user" code is likely to result in code that
|
// Using needsDevice() in "user" code is likely to result in code that
|
||||||
@@ -259,7 +261,7 @@ public:
|
|||||||
const std::function<bool(const FilePath &)> &, // Abort on 'false' return.
|
const std::function<bool(const FilePath &)> &, // Abort on 'false' return.
|
||||||
const FileFilter &)> iterateDirectory;
|
const FileFilter &)> iterateDirectory;
|
||||||
std::function<std::optional<QByteArray>(const FilePath &, qint64, qint64)> fileContents;
|
std::function<std::optional<QByteArray>(const FilePath &, qint64, qint64)> fileContents;
|
||||||
std::function<bool(const FilePath &, const QByteArray &)> writeFileContents;
|
std::function<bool(const FilePath &, const QByteArray &, qint64)> writeFileContents;
|
||||||
std::function<QDateTime(const FilePath &)> lastModified;
|
std::function<QDateTime(const FilePath &)> lastModified;
|
||||||
std::function<QFile::Permissions(const FilePath &)> permissions;
|
std::function<QFile::Permissions(const FilePath &)> permissions;
|
||||||
std::function<bool(const FilePath &, QFile::Permissions)> setPermissions;
|
std::function<bool(const FilePath &, QFile::Permissions)> setPermissions;
|
||||||
@@ -276,7 +278,8 @@ public:
|
|||||||
std::function<void(
|
std::function<void(
|
||||||
const Continuation<const std::optional<QByteArray> &> &, const FilePath &, qint64, qint64)>
|
const Continuation<const std::optional<QByteArray> &> &, const FilePath &, qint64, qint64)>
|
||||||
asyncFileContents;
|
asyncFileContents;
|
||||||
std::function<void(const Continuation<bool> &, const FilePath &, const QByteArray &)> asyncWriteFileContents;
|
std::function<void(const Continuation<bool> &, const FilePath &, const QByteArray &, qint64)>
|
||||||
|
asyncWriteFileContents;
|
||||||
std::function<bool(const FilePath &, const FilePath &)> ensureReachable;
|
std::function<bool(const FilePath &, const FilePath &)> ensureReachable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -910,10 +910,17 @@ std::optional<QByteArray> DockerDevice::fileContents(const FilePath &filePath,
|
|||||||
return d->fileContents(filePath, limit, offset);
|
return d->fileContents(filePath, limit, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DockerDevice::writeFileContents(const FilePath &filePath, const QByteArray &data) const
|
bool DockerDevice::writeFileContents(const FilePath &filePath,
|
||||||
|
const QByteArray &data,
|
||||||
|
qint64 offset) const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(handlesFile(filePath), return {});
|
QTC_ASSERT(handlesFile(filePath), return {});
|
||||||
return d->runInShellSuccess({"dd", {"of=" + filePath.path()}}, data);
|
CommandLine cmd({"dd", {"of=" + filePath.path()}});
|
||||||
|
if (offset != 0) {
|
||||||
|
cmd.addArg("bs=1");
|
||||||
|
cmd.addArg(QString("seek=%1").arg(offset));
|
||||||
|
}
|
||||||
|
return d->runInShellSuccess(cmd, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Environment DockerDevice::systemEnvironment() const
|
Environment DockerDevice::systemEnvironment() const
|
||||||
|
@@ -105,7 +105,9 @@ public:
|
|||||||
std::optional<QByteArray> fileContents(const Utils::FilePath &filePath,
|
std::optional<QByteArray> fileContents(const Utils::FilePath &filePath,
|
||||||
qint64 limit,
|
qint64 limit,
|
||||||
qint64 offset) const override;
|
qint64 offset) const override;
|
||||||
bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override;
|
bool writeFileContents(const Utils::FilePath &filePath,
|
||||||
|
const QByteArray &data,
|
||||||
|
qint64 offset) const override;
|
||||||
QDateTime lastModified(const Utils::FilePath &filePath) const override;
|
QDateTime lastModified(const Utils::FilePath &filePath) const override;
|
||||||
qint64 fileSize(const Utils::FilePath &filePath) const override;
|
qint64 fileSize(const Utils::FilePath &filePath) const override;
|
||||||
QFileDevice::Permissions permissions(const Utils::FilePath &filePath) const override;
|
QFileDevice::Permissions permissions(const Utils::FilePath &filePath) const override;
|
||||||
|
@@ -278,10 +278,12 @@ std::optional<QByteArray> DesktopDevice::fileContents(const FilePath &filePath,
|
|||||||
return filePath.fileContents(limit, offset);
|
return filePath.fileContents(limit, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DesktopDevice::writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const
|
bool DesktopDevice::writeFileContents(const FilePath &filePath,
|
||||||
|
const QByteArray &data,
|
||||||
|
qint64 offset) const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(handlesFile(filePath), return {});
|
QTC_ASSERT(handlesFile(filePath), return {});
|
||||||
return filePath.writeFileContents(data);
|
return filePath.writeFileContents(data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
@@ -56,7 +56,9 @@ public:
|
|||||||
std::optional<QByteArray> fileContents(const Utils::FilePath &filePath,
|
std::optional<QByteArray> fileContents(const Utils::FilePath &filePath,
|
||||||
qint64 limit,
|
qint64 limit,
|
||||||
qint64 offset) const override;
|
qint64 offset) const override;
|
||||||
bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override;
|
bool writeFileContents(const Utils::FilePath &filePath,
|
||||||
|
const QByteArray &data,
|
||||||
|
qint64 offset) const override;
|
||||||
qint64 fileSize(const Utils::FilePath &filePath) const override;
|
qint64 fileSize(const Utils::FilePath &filePath) const override;
|
||||||
QFile::Permissions permissions(const Utils::FilePath &filePath) const override;
|
QFile::Permissions permissions(const Utils::FilePath &filePath) const override;
|
||||||
bool setPermissions(const Utils::FilePath &filePath, QFile::Permissions) const override;
|
bool setPermissions(const Utils::FilePath &filePath, QFile::Permissions) const override;
|
||||||
|
@@ -544,10 +544,12 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
|
|||||||
device->asyncFileContents(cont, filePath, maxSize, offset);
|
device->asyncFileContents(cont, filePath, maxSize, offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
deviceHooks.writeFileContents = [](const FilePath &filePath, const QByteArray &data) {
|
deviceHooks.writeFileContents = [](const FilePath &filePath,
|
||||||
|
const QByteArray &data,
|
||||||
|
qint64 offset) {
|
||||||
auto device = DeviceManager::deviceForPath(filePath);
|
auto device = DeviceManager::deviceForPath(filePath);
|
||||||
QTC_ASSERT(device, return false);
|
QTC_ASSERT(device, return false);
|
||||||
return device->writeFileContents(filePath, data);
|
return device->writeFileContents(filePath, data, offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
deviceHooks.lastModified = [](const FilePath &filePath) {
|
deviceHooks.lastModified = [](const FilePath &filePath) {
|
||||||
|
@@ -384,19 +384,21 @@ void IDevice::asyncFileContents(const Continuation<std::optional<QByteArray>> &c
|
|||||||
cont(fileContents(filePath, limit, offset));
|
cont(fileContents(filePath, limit, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IDevice::writeFileContents(const FilePath &filePath, const QByteArray &data) const
|
bool IDevice::writeFileContents(const FilePath &filePath, const QByteArray &data, qint64 offset) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(filePath);
|
Q_UNUSED(filePath);
|
||||||
Q_UNUSED(data);
|
Q_UNUSED(data);
|
||||||
|
Q_UNUSED(offset);
|
||||||
QTC_CHECK(false);
|
QTC_CHECK(false);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void IDevice::asyncWriteFileContents(const Continuation<bool> &cont,
|
void IDevice::asyncWriteFileContents(const Continuation<bool> &cont,
|
||||||
const FilePath &filePath,
|
const FilePath &filePath,
|
||||||
const QByteArray &data) const
|
const QByteArray &data,
|
||||||
|
qint64 offset) const
|
||||||
{
|
{
|
||||||
cont(writeFileContents(filePath, data));
|
cont(writeFileContents(filePath, data, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime IDevice::lastModified(const FilePath &filePath) const
|
QDateTime IDevice::lastModified(const FilePath &filePath) const
|
||||||
|
@@ -243,7 +243,9 @@ public:
|
|||||||
virtual std::optional<QByteArray> fileContents(const Utils::FilePath &filePath,
|
virtual std::optional<QByteArray> fileContents(const Utils::FilePath &filePath,
|
||||||
qint64 limit,
|
qint64 limit,
|
||||||
qint64 offset) const;
|
qint64 offset) const;
|
||||||
virtual bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const;
|
virtual bool writeFileContents(const Utils::FilePath &filePath,
|
||||||
|
const QByteArray &data,
|
||||||
|
qint64 offset) const;
|
||||||
virtual QDateTime lastModified(const Utils::FilePath &filePath) const;
|
virtual QDateTime lastModified(const Utils::FilePath &filePath) const;
|
||||||
virtual QFile::Permissions permissions(const Utils::FilePath &filePath) const;
|
virtual QFile::Permissions permissions(const Utils::FilePath &filePath) const;
|
||||||
virtual bool setPermissions(const Utils::FilePath &filePath, QFile::Permissions) const;
|
virtual bool setPermissions(const Utils::FilePath &filePath, QFile::Permissions) const;
|
||||||
@@ -262,7 +264,8 @@ public:
|
|||||||
qint64 offset) const;
|
qint64 offset) const;
|
||||||
virtual void asyncWriteFileContents(const Continuation<bool> &cont,
|
virtual void asyncWriteFileContents(const Continuation<bool> &cont,
|
||||||
const Utils::FilePath &filePath,
|
const Utils::FilePath &filePath,
|
||||||
const QByteArray &data) const;
|
const QByteArray &data,
|
||||||
|
qint64 offset) const;
|
||||||
|
|
||||||
virtual bool ensureReachable(const Utils::FilePath &other) const;
|
virtual bool ensureReachable(const Utils::FilePath &other) const;
|
||||||
|
|
||||||
|
@@ -1318,10 +1318,17 @@ std::optional<QByteArray> LinuxDevice::fileContents(const FilePath &filePath,
|
|||||||
return result.stdOut;
|
return result.stdOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LinuxDevice::writeFileContents(const FilePath &filePath, const QByteArray &data) const
|
bool LinuxDevice::writeFileContents(const FilePath &filePath,
|
||||||
|
const QByteArray &data,
|
||||||
|
qint64 offset) const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(handlesFile(filePath), return {});
|
QTC_ASSERT(handlesFile(filePath), return {});
|
||||||
return d->runInShellSuccess({"dd", {"of=" + filePath.path()}}, data);
|
CommandLine cmd({"dd", {"of=" + filePath.path()}});
|
||||||
|
if (offset != 0) {
|
||||||
|
cmd.addArg("bs=1");
|
||||||
|
cmd.addArg(QString("seek=%1").arg(offset));
|
||||||
|
}
|
||||||
|
return d->runInShellSuccess(cmd, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FilePaths dirsToCreate(const FilesToTransfer &files)
|
static FilePaths dirsToCreate(const FilesToTransfer &files)
|
||||||
|
@@ -58,7 +58,9 @@ public:
|
|||||||
std::optional<QByteArray> fileContents(const Utils::FilePath &filePath,
|
std::optional<QByteArray> fileContents(const Utils::FilePath &filePath,
|
||||||
qint64 limit,
|
qint64 limit,
|
||||||
qint64 offset) const override;
|
qint64 offset) const override;
|
||||||
bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override;
|
bool writeFileContents(const Utils::FilePath &filePath,
|
||||||
|
const QByteArray &data,
|
||||||
|
qint64 offset) const override;
|
||||||
QDateTime lastModified(const Utils::FilePath &filePath) const override;
|
QDateTime lastModified(const Utils::FilePath &filePath) const override;
|
||||||
Utils::ProcessInterface *createProcessInterface() const override;
|
Utils::ProcessInterface *createProcessInterface() const override;
|
||||||
ProjectExplorer::FileTransferInterface *createFileTransferInterface(
|
ProjectExplorer::FileTransferInterface *createFileTransferInterface(
|
||||||
|
@@ -134,8 +134,10 @@ void tst_fsengine::initTestCase()
|
|||||||
qint64 offset) {
|
qint64 offset) {
|
||||||
return FilePath::fromString(filePath.path()).asyncFileContents(cont, maxSize, offset);
|
return FilePath::fromString(filePath.path()).asyncFileContents(cont, maxSize, offset);
|
||||||
};
|
};
|
||||||
deviceHooks.writeFileContents = [](const FilePath &filePath, const QByteArray &data) {
|
deviceHooks.writeFileContents = [](const FilePath &filePath,
|
||||||
return FilePath::fromString(filePath.path()).writeFileContents(data);
|
const QByteArray &data,
|
||||||
|
qint64 offset) {
|
||||||
|
return FilePath::fromString(filePath.path()).writeFileContents(data, offset);
|
||||||
};
|
};
|
||||||
deviceHooks.lastModified = [](const FilePath &filePath) {
|
deviceHooks.lastModified = [](const FilePath &filePath) {
|
||||||
return FilePath::fromString(filePath.path()).lastModified();
|
return FilePath::fromString(filePath.path()).lastModified();
|
||||||
|
Reference in New Issue
Block a user