Compare commits
No commits in common. "ce7a7b15c72bcc33ab8fe2afae4a4b7bd8ca2427" and "60707421c85e343cbf3d06844e85c05b24e9031d" have entirely different histories.
ce7a7b15c7
...
60707421c8
@ -63,60 +63,6 @@ StreamError Stream::writeString(std::string_view str)
|
|||||||
return writeSpan(str.begin(), str.end());
|
return writeSpan(str.begin(), str.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamError Stream::getTotalLength(std::size_t& outLength)
|
|
||||||
{
|
|
||||||
const StreamFeatures features = getFeatures();
|
|
||||||
if (!features.tell || !features.seek) {
|
|
||||||
return StreamError::NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
const std::size_t origPos = tell();
|
|
||||||
if (StreamError error = seek(0, SeekMode::RELATIVE_TO_END); error != StreamError::SUCCESS)
|
|
||||||
{
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
outLength = tell();
|
|
||||||
if (StreamError error = seek(static_cast<std::intptr_t>(origPos)); error != StreamError::SUCCESS)
|
|
||||||
{
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
return StreamError::SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
StreamError Stream::readRest(TypelessBuffer& outBuffer)
|
|
||||||
{
|
|
||||||
// first try to allocate everything at once
|
|
||||||
std::size_t length = 0;
|
|
||||||
if (StreamError lengthError = getTotalLength(length); lengthError == StreamError::SUCCESS)
|
|
||||||
{
|
|
||||||
MIJIN_ASSERT(getFeatures().tell, "How did you find the length if you cannot tell()?");
|
|
||||||
length -= tell();
|
|
||||||
outBuffer.resize(length);
|
|
||||||
if (StreamError error = readRaw(outBuffer.data(), length); error != StreamError::SUCCESS)
|
|
||||||
{
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
return StreamError::SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// could not determine the size, read chunk-wise
|
|
||||||
static constexpr std::size_t CHUNK_SIZE = 4096;
|
|
||||||
std::array<std::byte, CHUNK_SIZE> chunk = {};
|
|
||||||
|
|
||||||
while (!isAtEnd())
|
|
||||||
{
|
|
||||||
std::size_t bytesRead = 0;
|
|
||||||
if (StreamError error = readRaw(chunk, true, &bytesRead); error != StreamError::SUCCESS)
|
|
||||||
{
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
outBuffer.resize(outBuffer.byteSize() + bytesRead);
|
|
||||||
std::span<std::byte> bufferBytes = outBuffer.makeSpan<std::byte>();
|
|
||||||
std::copy_n(chunk.begin(), bytesRead, bufferBytes.end() - static_cast<long>(bytesRead));
|
|
||||||
}
|
|
||||||
return StreamError::SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileStream::~FileStream()
|
FileStream::~FileStream()
|
||||||
{
|
{
|
||||||
if (handle) {
|
if (handle) {
|
||||||
|
|||||||
@ -7,10 +7,8 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <ranges>
|
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../container/typeless_buffer.hpp"
|
|
||||||
|
|
||||||
namespace mijin
|
namespace mijin
|
||||||
{
|
{
|
||||||
@ -78,26 +76,12 @@ public:
|
|||||||
return readRaw(std::span(ptr, ptr + bytes), partial, outBytesRead);
|
return readRaw(std::span(ptr, ptr + bytes), partial, outBytesRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::ranges::contiguous_range TRange>
|
|
||||||
inline StreamError readRaw(TRange& range, bool partial = false, std::size_t* outBytesRead = nullptr)
|
|
||||||
{
|
|
||||||
const std::size_t bytes = std::distance(range.begin(), range.end()) * sizeof(std::ranges::range_value_t<TRange>);
|
|
||||||
return readRaw(&*range.begin(), bytes, partial, outBytesRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline StreamError writeRaw(const void* data, std::size_t bytes)
|
inline StreamError writeRaw(const void* data, std::size_t bytes)
|
||||||
{
|
{
|
||||||
const std::uint8_t* ptr = static_cast<const std::uint8_t*>(data);
|
const std::uint8_t* ptr = static_cast<const std::uint8_t*>(data);
|
||||||
return writeRaw(std::span(ptr, ptr + bytes));
|
return writeRaw(std::span(ptr, ptr + bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::ranges::contiguous_range TRange>
|
|
||||||
inline StreamError writeRaw(const TRange& range)
|
|
||||||
{
|
|
||||||
const std::size_t bytes = std::distance(range.begin(), range.end()) * sizeof(std::ranges::range_value_t<TRange>);
|
|
||||||
return writeRaw(&*range.begin(), bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline StreamError read(T& value)
|
inline StreamError read(T& value)
|
||||||
{
|
{
|
||||||
@ -139,12 +123,6 @@ public:
|
|||||||
|
|
||||||
StreamError readString(std::string& outString);
|
StreamError readString(std::string& outString);
|
||||||
StreamError writeString(std::string_view str);
|
StreamError writeString(std::string_view str);
|
||||||
|
|
||||||
StreamError getTotalLength(std::size_t& outLength);
|
|
||||||
StreamError readRest(TypelessBuffer& outBuffer);
|
|
||||||
|
|
||||||
template<typename TChar = char>
|
|
||||||
StreamError readAsString(std::basic_string<TChar>& outString);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileStream : public Stream
|
class FileStream : public Stream
|
||||||
@ -202,42 +180,6 @@ public:
|
|||||||
// public functions
|
// public functions
|
||||||
//
|
//
|
||||||
|
|
||||||
template<typename TChar>
|
|
||||||
StreamError Stream::readAsString(std::basic_string<TChar>& outString)
|
|
||||||
{
|
|
||||||
static_assert(sizeof(TChar) == 1, "Can only read to 8-bit character types (char, unsigned char or char8_t");
|
|
||||||
|
|
||||||
// first try to allocate everything at once
|
|
||||||
std::size_t length = 0;
|
|
||||||
if (StreamError lengthError = getTotalLength(length); lengthError == StreamError::SUCCESS)
|
|
||||||
{
|
|
||||||
MIJIN_ASSERT(getFeatures().tell, "How did you find the length if you cannot tell()?");
|
|
||||||
length -= tell();
|
|
||||||
outString.resize(length);
|
|
||||||
if (StreamError error = readRaw(outString.data(), length); error != StreamError::SUCCESS)
|
|
||||||
{
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
return StreamError::SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// could not determine the size, read chunk-wise
|
|
||||||
static constexpr std::size_t CHUNK_SIZE = 4096;
|
|
||||||
std::array<TChar, CHUNK_SIZE> chunk;
|
|
||||||
|
|
||||||
outString.clear();
|
|
||||||
while (!isAtEnd())
|
|
||||||
{
|
|
||||||
std::size_t bytesRead = 0;
|
|
||||||
if (StreamError error = readRaw(chunk, true, &bytesRead); error != StreamError::SUCCESS)
|
|
||||||
{
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
outString.append(chunk.data(), chunk.data() + bytesRead);
|
|
||||||
}
|
|
||||||
return StreamError::SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace mijin
|
} // namespace mijin
|
||||||
|
|
||||||
#endif // !defined(MIJIN_IO_STREAM_HPP_INCLUDED)
|
#endif // !defined(MIJIN_IO_STREAM_HPP_INCLUDED)
|
||||||
|
|||||||
@ -40,21 +40,6 @@ struct FileInfo
|
|||||||
bool isHidden : 1 = false;
|
bool isHidden : 1 = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// basically just a thin wrapper around adapter + path, for utility
|
|
||||||
class PathReference
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
class FileSystemAdapter* adapter_;
|
|
||||||
fs::path path_;
|
|
||||||
public:
|
|
||||||
PathReference(class FileSystemAdapter* adapter, fs::path path) noexcept : adapter_(adapter), path_(std::move(path)) {}
|
|
||||||
|
|
||||||
[[nodiscard]] class FileSystemAdapter* getAdapter() const noexcept { return adapter_; }
|
|
||||||
[[nodiscard]] const fs::path& getPath() const noexcept { return path_; }
|
|
||||||
[[nodiscard]] inline FileInfo getInfo() const;
|
|
||||||
[[nodiscard]] inline StreamError open(FileOpenMode mode, std::unique_ptr<Stream>& outStream) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FileSystemAdapter
|
class FileSystemAdapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -65,8 +50,6 @@ public:
|
|||||||
[[nodiscard]] virtual std::vector<FileInfo> listFiles(const fs::path& folder) = 0;
|
[[nodiscard]] virtual std::vector<FileInfo> listFiles(const fs::path& folder) = 0;
|
||||||
[[nodiscard]] virtual FileInfo getFileInfo(const fs::path& file) = 0;
|
[[nodiscard]] virtual FileInfo getFileInfo(const fs::path& file) = 0;
|
||||||
[[nodiscard]] virtual StreamError open(const fs::path& path, FileOpenMode mode, std::unique_ptr<Stream>& outStream) = 0;
|
[[nodiscard]] virtual StreamError open(const fs::path& path, FileOpenMode mode, std::unique_ptr<Stream>& outStream) = 0;
|
||||||
|
|
||||||
[[nodiscard]] PathReference getPath(fs::path path) noexcept { return PathReference(this, std::move(path)); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class OSFileSystemAdapter : public FileSystemAdapter
|
class OSFileSystemAdapter : public FileSystemAdapter
|
||||||
@ -85,16 +68,6 @@ public:
|
|||||||
// public functions
|
// public functions
|
||||||
//
|
//
|
||||||
|
|
||||||
inline FileInfo PathReference::getInfo() const
|
|
||||||
{
|
|
||||||
return adapter_->getFileInfo(path_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline StreamError PathReference::open(FileOpenMode mode, std::unique_ptr<Stream>& outStream) const
|
|
||||||
{
|
|
||||||
return adapter_->open(path_, mode, outStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string formatFileType(const FileInfo& info)
|
inline std::string formatFileType(const FileInfo& info)
|
||||||
{
|
{
|
||||||
if (info.isFolder) {
|
if (info.isFolder) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user