Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarFile.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/core/StarFile.cpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/core/StarFile.cpp')
-rw-r--r--source/core/StarFile.cpp240
1 files changed, 240 insertions, 0 deletions
diff --git a/source/core/StarFile.cpp b/source/core/StarFile.cpp
new file mode 100644
index 0000000..738a088
--- /dev/null
+++ b/source/core/StarFile.cpp
@@ -0,0 +1,240 @@
+#include "StarFile.hpp"
+#include "StarFormat.hpp"
+
+#include <fstream>
+
+namespace Star {
+
+void File::makeDirectoryRecursive(String const& fileName) {
+ auto parent = dirName(fileName);
+ if (!isDirectory(parent))
+ makeDirectoryRecursive(parent);
+ if (!isDirectory(fileName))
+ makeDirectory(fileName);
+}
+
+void File::removeDirectoryRecursive(String const& fileName) {
+ {
+ String fileInDir;
+ bool isDir;
+
+ for (auto const& p : dirList(fileName)) {
+ std::tie(fileInDir, isDir) = p;
+
+ fileInDir = relativeTo(fileName, fileInDir);
+
+ if (isDir)
+ removeDirectoryRecursive(fileInDir);
+ else
+ remove(fileInDir);
+ }
+ }
+
+ remove(fileName);
+}
+
+void File::copy(String const& source, String const& target) {
+ auto sourceFile = File::open(source, IOMode::Read);
+ auto targetFile = File::open(target, IOMode::ReadWrite);
+
+ targetFile->resize(0);
+
+ char buf[1024];
+ while (!sourceFile->atEnd()) {
+ size_t r = sourceFile->read(buf, 1024);
+ targetFile->writeFull(buf, r);
+ }
+}
+
+FilePtr File::open(const String& filename, IOMode mode) {
+ auto file = make_shared<File>(filename);
+ file->open(mode);
+ return file;
+}
+
+ByteArray File::readFile(String const& filename) {
+ FilePtr file = File::open(filename, IOMode::Read);
+ ByteArray bytes;
+ while (!file->atEnd()) {
+ char buffer[1024];
+ size_t r = file->read(buffer, 1024);
+ bytes.append(buffer, r);
+ }
+
+ return bytes;
+}
+
+String File::readFileString(String const& filename) {
+ FilePtr file = File::open(filename, IOMode::Read);
+ std::string str;
+ while (!file->atEnd()) {
+ char buffer[1024];
+ size_t r = file->read(buffer, 1024);
+ for (size_t i = 0; i < r; ++i)
+ str.push_back(buffer[i]);
+ }
+
+ return str;
+}
+
+StreamOffset File::fileSize(String const& filename) {
+ return File::open(filename, IOMode::Read)->size();
+}
+
+void File::writeFile(char const* data, size_t len, String const& filename) {
+ FilePtr file = File::open(filename, IOMode::Write | IOMode::Truncate);
+ file->writeFull(data, len);
+}
+
+void File::writeFile(ByteArray const& data, String const& filename) {
+ writeFile(data.ptr(), data.size(), filename);
+}
+
+void File::writeFile(String const& data, String const& filename) {
+ writeFile(data.utf8Ptr(), data.utf8Size(), filename);
+}
+
+void File::overwriteFileWithRename(ByteArray const& data, String const& filename, String const& newSuffix) {
+ overwriteFileWithRename(data.ptr(), data.size(), filename, newSuffix);
+}
+
+void File::overwriteFileWithRename(String const& data, String const& filename, String const& newSuffix) {
+ overwriteFileWithRename(data.utf8Ptr(), data.utf8Size(), filename, newSuffix);
+}
+
+void File::backupFileInSequence(String const& targetFile, unsigned maximumBackups, String const& backupExtensionPrefix) {
+ for (unsigned i = maximumBackups; i > 0; --i) {
+ String curExtension = i == 1 ? "" : strf("%s%s", backupExtensionPrefix, i - 1);
+ String nextExtension = strf("%s%s", backupExtensionPrefix, i);
+
+ if (File::isFile(targetFile + curExtension))
+ File::copy(targetFile + curExtension, targetFile + nextExtension);
+ }
+}
+
+File::File()
+ : IODevice(IOMode::Closed) {
+ m_file = 0;
+}
+
+File::File(String filename)
+ : IODevice(IOMode::Closed), m_filename(move(filename)), m_file(0) {}
+
+File::~File() {
+ close();
+}
+
+StreamOffset File::pos() {
+ if (!m_file)
+ throw IOException("pos called on closed File");
+
+ return ftell(m_file);
+}
+
+void File::seek(StreamOffset offset, IOSeek seekMode) {
+ if (!m_file)
+ throw IOException("seek called on closed File");
+
+ fseek(m_file, offset, seekMode);
+}
+
+StreamOffset File::size() {
+ return fsize(m_file);
+}
+
+bool File::atEnd() {
+ if (!m_file)
+ throw IOException("eof called on closed File");
+
+ return ftell(m_file) >= fsize(m_file);
+}
+
+size_t File::read(char* data, size_t len) {
+ if (!m_file)
+ throw IOException("read called on closed File");
+
+ if (!isReadable())
+ throw IOException("read called on non-readable File");
+
+ return fread(m_file, data, len);
+}
+
+size_t File::write(const char* data, size_t len) {
+ if (!m_file)
+ throw IOException("write called on closed File");
+
+ if (!isWritable())
+ throw IOException("write called on non-writable File");
+
+ return fwrite(m_file, data, len);
+}
+
+size_t File::readAbsolute(StreamOffset readPosition, char* data, size_t len) {
+ return pread(m_file, data, len, readPosition);
+}
+
+size_t File::writeAbsolute(StreamOffset writePosition, char const* data, size_t len) {
+ return pwrite(m_file, data, len, writePosition);
+}
+
+String File::fileName() const {
+ return m_filename;
+}
+
+void File::setFilename(String filename) {
+ if (isOpen())
+ throw IOException("Cannot call setFilename while File is open");
+ m_filename = move(filename);
+}
+
+void File::remove() {
+ close();
+ if (m_filename.empty())
+ throw IOException("Cannot remove file, no filename set");
+ remove(m_filename);
+}
+
+void File::resize(StreamOffset s) {
+ bool tempOpen = false;
+ if (!isOpen()) {
+ tempOpen = true;
+ open(mode());
+ }
+
+ File::resize(m_file, s);
+
+ if (tempOpen)
+ close();
+}
+
+void File::sync() {
+ if (!m_file)
+ throw IOException("sync called on closed File");
+
+ fsync(m_file);
+}
+
+void File::open(IOMode m) {
+ close();
+ if (m_filename.empty())
+ throw IOException("Cannot open file, no filename set");
+
+ m_file = fopen(m_filename.utf8Ptr(), m);
+ setMode(m);
+}
+
+void File::close() {
+ if (m_file)
+ fclose(m_file);
+ m_file = 0;
+ setMode(IOMode::Closed);
+}
+
+String File::deviceName() const {
+ if (m_filename.empty())
+ return "<unnamed temp file>";
+ else
+ return m_filename;
+}
+
+}