summaryrefslogtreecommitdiffstats
path: root/src/OSSupport
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@outlook.com>2021-01-11 17:39:43 +0100
committerGitHub <noreply@github.com>2021-01-11 17:39:43 +0100
commiteeb63b8901a9c049f1bb594abb9ce9b4a9c47620 (patch)
treeb07daae788f918b83eeb0bdbd51e49292f1c8d88 /src/OSSupport
parentFixed switch-ups regarding some slab and stair recipes (#5099) (diff)
downloadcuberite-eeb63b8901a9c049f1bb594abb9ce9b4a9c47620.tar
cuberite-eeb63b8901a9c049f1bb594abb9ce9b4a9c47620.tar.gz
cuberite-eeb63b8901a9c049f1bb594abb9ce9b4a9c47620.tar.bz2
cuberite-eeb63b8901a9c049f1bb594abb9ce9b4a9c47620.tar.lz
cuberite-eeb63b8901a9c049f1bb594abb9ce9b4a9c47620.tar.xz
cuberite-eeb63b8901a9c049f1bb594abb9ce9b4a9c47620.tar.zst
cuberite-eeb63b8901a9c049f1bb594abb9ce9b4a9c47620.zip
Diffstat (limited to 'src/OSSupport')
-rw-r--r--src/OSSupport/File.cpp67
-rw-r--r--src/OSSupport/File.h27
-rw-r--r--src/OSSupport/GZipFile.cpp96
-rw-r--r--src/OSSupport/GZipFile.h41
4 files changed, 88 insertions, 143 deletions
diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp
index 8c5eb92a4..618463bd6 100644
--- a/src/OSSupport/File.cpp
+++ b/src/OSSupport/File.cpp
@@ -157,19 +157,18 @@ int cFile::Read (void * a_Buffer, size_t a_NumBytes)
-AString cFile::Read(size_t a_NumBytes)
+ContiguousByteBuffer cFile::Read(size_t a_NumBytes)
{
ASSERT(IsOpen());
if (!IsOpen())
{
- return AString();
+ return {};
}
- // HACK: This depends on the knowledge that AString::data() returns the internal buffer, rather than a copy of it.
- AString res;
- res.resize(a_NumBytes);
- auto newSize = fread(const_cast<char *>(res.data()), 1, a_NumBytes, m_File);
+ ContiguousByteBuffer res;
+ res.resize(a_NumBytes); // TODO: investigate if worth hacking around std::string internals to avoid initialisation
+ auto newSize = fread(res.data(), sizeof(std::byte), a_NumBytes, m_File);
res.resize(newSize);
return res;
}
@@ -284,9 +283,8 @@ int cFile::ReadRestOfFile(AString & a_Contents)
auto DataSize = static_cast<size_t>(TotalSize - Position);
- // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly
- a_Contents.assign(DataSize, '\0');
- return Read(static_cast<void *>(const_cast<char *>(a_Contents.data())), DataSize);
+ a_Contents.resize(DataSize); // TODO: investigate if worth hacking around std::string internals to avoid initialisation
+ return Read(a_Contents.data(), DataSize);
}
@@ -709,3 +707,54 @@ void cFile::Flush(void)
{
fflush(m_File);
}
+
+
+
+
+
+template <class StreamType>
+FileStream<StreamType>::FileStream(const std::string & Path)
+{
+ // Except on failbit, which is what open sets on failure:
+ FileStream::exceptions(FileStream::failbit | FileStream::badbit);
+
+ // Open the file:
+ FileStream::open(Path);
+
+ // Only subsequently except on serious errors, and not on conditions like EOF or malformed input:
+ FileStream::exceptions(FileStream::badbit);
+}
+
+
+
+
+
+template <class StreamType>
+FileStream<StreamType>::FileStream(const std::string & Path, const typename FileStream::openmode Mode)
+{
+ // Except on failbit, which is what open sets on failure:
+ FileStream::exceptions(FileStream::failbit | FileStream::badbit);
+
+ // Open the file:
+ FileStream::open(Path, Mode);
+
+ // Only subsequently except on serious errors, and not on conditions like EOF or malformed input:
+ FileStream::exceptions(FileStream::badbit);
+}
+
+
+
+
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-template-vtables" // http://bugs.llvm.org/show_bug.cgi?id=18733
+#endif
+
+// Instantiate the templated wrapper for input and output:
+template class FileStream<std::ifstream>;
+template class FileStream<std::ofstream>;
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h
index 59f3a5558..7a3333483 100644
--- a/src/OSSupport/File.h
+++ b/src/OSSupport/File.h
@@ -75,7 +75,7 @@ public:
int Read(void * a_Buffer, size_t a_NumBytes);
/** Reads up to a_NumBytes bytes, returns the bytes actually read, or empty string on failure; asserts if not open */
- AString Read(size_t a_NumBytes);
+ std::basic_string<std::byte> Read(size_t a_NumBytes);
/** Writes up to a_NumBytes bytes from a_Buffer, returns the number of bytes actually written, or -1 on failure; asserts if not open */
int Write(const void * a_Buffer, size_t a_NumBytes);
@@ -192,17 +192,8 @@ class FileStream final : public StreamType
{
public:
- FileStream(const std::string & Path)
- {
- // Except on failbit, which is what open sets on failure:
- FileStream::exceptions(FileStream::failbit | FileStream::badbit);
-
- // Open the file:
- FileStream::open(Path);
-
- // Only subsequently except on serious errors, and not on conditions like EOF or malformed input:
- FileStream::exceptions(FileStream::badbit);
- }
+ FileStream(const std::string & Path);
+ FileStream(const std::string & Path, const typename FileStream::openmode Mode);
};
@@ -211,3 +202,15 @@ public:
using InputFileStream = FileStream<std::ifstream>;
using OutputFileStream = FileStream<std::ofstream>;
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-template-vtables" // http://bugs.llvm.org/show_bug.cgi?id=18733
+#endif
+
+extern template class FileStream<std::ifstream>;
+extern template class FileStream<std::ofstream>;
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
diff --git a/src/OSSupport/GZipFile.cpp b/src/OSSupport/GZipFile.cpp
index e83d42583..0bf26dfed 100644
--- a/src/OSSupport/GZipFile.cpp
+++ b/src/OSSupport/GZipFile.cpp
@@ -4,107 +4,27 @@
// Implements the cGZipFile class representing a RAII wrapper over zlib's GZip file routines
#include "Globals.h"
+#include "File.h"
#include "GZipFile.h"
-cGZipFile::cGZipFile(void) :
- m_File(nullptr), m_Mode(fmRead)
+Compression::Result GZipFile::ReadRestOfFile(const std::string & a_FileName)
{
-}
-
-
-
-
-
-cGZipFile::~cGZipFile()
-{
- Close();
-}
-
+ InputFileStream File(a_FileName, InputFileStream::binary);
+ const std::string Input{ std::istreambuf_iterator<char>(File), std::istreambuf_iterator<char>() };
+ const ContiguousByteBufferView Data{ reinterpret_cast<const std::byte *>(Input.data()), Input.size() };
-
-
-
-bool cGZipFile::Open(const AString & a_FileName, eMode a_Mode)
-{
- if (m_File != nullptr)
- {
- ASSERT(!"A file is already open in this object");
- return false;
- }
- m_File = gzopen(a_FileName.c_str(), (a_Mode == fmRead) ? "r" : "w");
- m_Mode = a_Mode;
- return (m_File != nullptr);
+ return Compression::Extractor().ExtractGZip(Data);
}
-void cGZipFile::Close(void)
+void GZipFile::Write(const std::string & a_FileName, ContiguousByteBufferView a_Contents)
{
- if (m_File != nullptr)
- {
- gzclose(m_File);
- m_File = nullptr;
- }
+ OutputFileStream(a_FileName, OutputFileStream::binary) << Compression::Compressor().CompressGZip(a_Contents).GetStringView();
}
-
-
-
-
-
-int cGZipFile::ReadRestOfFile(AString & a_Contents)
-{
- if (m_File == nullptr)
- {
- ASSERT(!"No file has been opened");
- return -1;
- }
-
- if (m_Mode != fmRead)
- {
- ASSERT(!"Bad file mode, cannot read");
- return -1;
- }
-
- // Since the gzip format doesn't really support getting the uncompressed length, we need to read incrementally. Yuck!
- int NumBytesRead = 0;
- int TotalBytes = 0;
- char Buffer[64 KiB];
- while ((NumBytesRead = gzread(m_File, Buffer, sizeof(Buffer))) > 0)
- {
- TotalBytes += NumBytesRead;
- a_Contents.append(Buffer, static_cast<size_t>(NumBytesRead));
- }
- // NumBytesRead is < 0 on error
- return (NumBytesRead >= 0) ? TotalBytes : NumBytesRead;
-}
-
-
-
-
-
-bool cGZipFile::Write(const char * a_Contents, int a_Size)
-{
- if (m_File == nullptr)
- {
- ASSERT(!"No file has been opened");
- return false;
- }
-
- if (m_Mode != fmWrite)
- {
- ASSERT(!"Bad file mode, cannot write");
- return false;
- }
-
- return (gzwrite(m_File, a_Contents, static_cast<unsigned int>(a_Size)) != 0);
-}
-
-
-
-
diff --git a/src/OSSupport/GZipFile.h b/src/OSSupport/GZipFile.h
index 00a2fd717..dd4999339 100644
--- a/src/OSSupport/GZipFile.h
+++ b/src/OSSupport/GZipFile.h
@@ -1,7 +1,7 @@
// GZipFile.h
-// Declares the cGZipFile class representing a RAII wrapper over zlib's GZip file routines
+// Declares the GZipFile namespace representing a wrapper over a file stream that can read and write to GZip'd files
@@ -9,44 +9,17 @@
#pragma once
-#include "zlib/zlib.h"
+#include "StringCompression.h"
-class cGZipFile
+namespace GZipFile
{
-public:
- enum eMode
- {
- fmRead, // Read-only. If the file doesn't exist, object will not be valid
- fmWrite, // Write-only. If the file already exists, it will be overwritten
- } ;
+ /** Reads the rest of the file and returns the decompressed contents. */
+ Compression::Result ReadRestOfFile(const std::string & a_FileName);
- cGZipFile(void);
- ~cGZipFile();
-
- /** Opens the file. Returns true if successful. Fails if a file has already been opened through this object. */
- bool Open(const AString & a_FileName, eMode a_Mode);
-
- /** Closes the file, flushing all buffers. This object may be then reused for a different file and / or mode */
- void Close(void);
-
- /** Reads the rest of the file and decompresses it into a_Contents. Returns the number of decompressed bytes, <0 for error */
- int ReadRestOfFile(AString & a_Contents);
-
- /** Writes a_Contents into file, compressing it along the way. Returns true if successful. Multiple writes are supported. */
- bool Write(const AString & a_Contents) { return Write(a_Contents.data(), static_cast<int>(a_Contents.size())); }
-
- bool Write(const char * a_Data, int a_Size);
-
-protected:
- gzFile m_File;
- eMode m_Mode;
+ /** Writes a_Contents into file, compressing it along the way. */
+ void Write(const std::string & a_FileName, ContiguousByteBufferView a_Contents);
} ;
-
-
-
-
-