Added map() function for creating a mapping iterator. Added mijin::pipe types for map() and join().
		
			
				
	
	
		
			186 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			186 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
 | |
| #pragma once
 | |
| 
 | |
| #if !defined(MIJIN_IO_STREAM_HPP_INCLUDED)
 | |
| #define MIJIN_IO_STREAM_HPP_INCLUDED 1
 | |
| 
 | |
| #include <cassert>
 | |
| #include <cstdint>
 | |
| #include <optional>
 | |
| #include <span>
 | |
| #include <string>
 | |
| 
 | |
| namespace mijin
 | |
| {
 | |
| 
 | |
| //
 | |
| // public defines
 | |
| //
 | |
| 
 | |
| //
 | |
| // public constants
 | |
| //
 | |
| 
 | |
| //
 | |
| // public types
 | |
| //
 | |
| 
 | |
| enum class SeekMode
 | |
| {
 | |
|     ABSOLUTE,
 | |
|     RELATIVE,
 | |
|     RELATIVE_TO_END
 | |
| };
 | |
| 
 | |
| struct StreamFeatures
 | |
| {
 | |
|     bool read  : 1 = false;
 | |
|     bool write : 1 = false;
 | |
|     bool tell  : 1 = false;
 | |
|     bool seek  : 1 = false;
 | |
| };
 | |
| 
 | |
| enum class FileOpenMode
 | |
| {
 | |
|     READ,
 | |
|     WRITE,
 | |
|     APPEND,
 | |
|     READ_WRITE
 | |
| };
 | |
| 
 | |
| enum class [[nodiscard]] StreamError
 | |
| {
 | |
|     SUCCESS,
 | |
|     IO_ERROR,
 | |
|     NOT_SUPPORTED,
 | |
|     UNKNOWN_ERROR
 | |
| };
 | |
| 
 | |
| class Stream
 | |
| {
 | |
| public:
 | |
|     virtual ~Stream() = default;
 | |
|     
 | |
| public:
 | |
|     virtual StreamError readRaw(std::span<std::uint8_t> buffer, bool partial = false, std::size_t* outBytesRead = nullptr) = 0;
 | |
|     virtual StreamError writeRaw(std::span<const std::uint8_t> buffer) = 0;
 | |
|     virtual std::size_t tell() = 0;
 | |
|     virtual StreamError seek(std::intptr_t pos, SeekMode seekMode = SeekMode::ABSOLUTE) = 0;
 | |
|     virtual void flush();
 | |
|     virtual bool isAtEnd() = 0;
 | |
|     virtual StreamFeatures getFeatures() = 0;
 | |
| 
 | |
|     inline StreamError readRaw(void* outData, std::size_t bytes, bool partial = false, std::size_t* outBytesRead = nullptr)
 | |
|     {
 | |
|         std::uint8_t* ptr = static_cast<std::uint8_t*>(outData);
 | |
|         return readRaw(std::span(ptr, ptr + bytes), partial, outBytesRead);
 | |
|     }
 | |
| 
 | |
|     inline StreamError writeRaw(const void* data, std::size_t bytes)
 | |
|     {
 | |
|         const std::uint8_t* ptr = static_cast<const std::uint8_t*>(data);
 | |
|         return writeRaw(std::span(ptr, ptr + bytes));
 | |
|     }
 | |
| 
 | |
|     template<typename T>
 | |
|     inline StreamError read(T& value)
 | |
|     {
 | |
|         return readRaw(&value, sizeof(T));
 | |
|     }
 | |
| 
 | |
|     template<typename T>
 | |
|     inline StreamError readSpan(T& values)
 | |
|     {
 | |
|         auto asSpan = std::span(values);
 | |
|         return readRaw(asSpan.data(), asSpan.size_bytes());
 | |
|     }
 | |
| 
 | |
|     template<typename TItBegin, typename TItEnd>
 | |
|     inline StreamError readSpan(TItBegin&& begin, TItEnd&& end)
 | |
|     {
 | |
|         auto asSpan = std::span(std::forward<TItBegin>(begin), std::forward<TItEnd>(end));
 | |
|         return readRaw(asSpan.data(), asSpan.size_bytes());
 | |
|     }
 | |
| 
 | |
|     template<typename T>
 | |
|     inline StreamError write(const T& value)
 | |
|     {
 | |
|         return writeRaw(&value, sizeof(T));
 | |
|     }
 | |
| 
 | |
|     template<typename T>
 | |
|     inline StreamError writeSpan(const T& values)
 | |
|     {
 | |
|         auto asSpan = std::span(values);
 | |
|         return writeRaw(asSpan.data(), asSpan.size_bytes());
 | |
|     }
 | |
| 
 | |
|     template<typename TItBegin, typename TItEnd>
 | |
|     inline StreamError writeSpan(TItBegin&& begin, TItEnd&& end)
 | |
|     {
 | |
|         return writeSpan(std::span(std::forward<TItBegin>(begin), std::forward<TItEnd>(end)));
 | |
|     }
 | |
| 
 | |
|     StreamError readString(std::string& outString);
 | |
|     StreamError writeString(std::string_view str);
 | |
| };
 | |
| 
 | |
| class FileStream : public Stream
 | |
| {
 | |
| private:
 | |
|     std::FILE* handle = nullptr; // TODO: wrap in gsl::owner<>
 | |
|     FileOpenMode mode;
 | |
|     std::size_t length = 0;
 | |
| public:
 | |
|     ~FileStream() override;
 | |
| 
 | |
|     StreamError open(const char* path, FileOpenMode mode_);
 | |
|     inline StreamError open(const std::string& path, FileOpenMode mode_) {
 | |
|         return open(path.c_str(), mode_);
 | |
|     }
 | |
|     void close();
 | |
|     [[nodiscard]] inline bool isOpen() const { return handle != nullptr; }
 | |
| 
 | |
|     // Stream overrides
 | |
|     StreamError readRaw(std::span<std::uint8_t> buffer, bool partial = false, std::size_t* outBytesRead = nullptr) override;
 | |
|     StreamError writeRaw(std::span<const std::uint8_t> buffer) override;
 | |
|     std::size_t tell() override;
 | |
|     StreamError seek(std::intptr_t pos, SeekMode seekMode = SeekMode::ABSOLUTE) override;
 | |
|     void flush() override;
 | |
|     bool isAtEnd() override;
 | |
|     StreamFeatures getFeatures() override;
 | |
| };
 | |
| 
 | |
| class MemoryStream : public Stream
 | |
| {
 | |
| private:
 | |
|     std::span<std::uint8_t> data_;
 | |
|     std::size_t pos_ = 0;
 | |
|     bool canWrite_ = false;
 | |
| public:
 | |
|     void openRW(std::span<std::uint8_t> data);
 | |
|     void openRO(std::span<const std::uint8_t> data);
 | |
|     void close();
 | |
|     [[nodiscard]] inline bool isOpen() const { return data_.data() != nullptr; }
 | |
|     [[nodiscard]] inline std::size_t availableBytes() const {
 | |
|         assert(isOpen());
 | |
|         return data_.size() - pos_;
 | |
|     }
 | |
| 
 | |
|     // Stream overrides
 | |
|     StreamError readRaw(std::span<std::uint8_t> buffer, bool partial = false, std::size_t* outBytesRead = nullptr) override;
 | |
|     StreamError writeRaw(std::span<const std::uint8_t> buffer) override;
 | |
|     std::size_t tell() override;
 | |
|     StreamError seek(std::intptr_t pos, SeekMode seekMode = SeekMode::ABSOLUTE) override;
 | |
|     bool isAtEnd() override;
 | |
|     StreamFeatures getFeatures() override;
 | |
| };
 | |
| 
 | |
| //
 | |
| // public functions
 | |
| //
 | |
| 
 | |
| } // namespace mijin
 | |
| 
 | |
| #endif // !defined(MIJIN_IO_STREAM_HPP_INCLUDED)
 |