1 // 2 // memory_stream.hpp 3 // 4 // Copyright © 2024 Apple Inc. All rights reserved. 5 // 6 // Please refer to the license found in the LICENSE file in the root directory of the source tree. 7 8 #pragma once 9 10 #include <istream> 11 #include <ostream> 12 13 #include "memory_buffer.hpp" 14 15 namespace inmemoryfs { 16 17 /// A class representing an in-memory stream buffer. 18 class MemoryStreamBuf: public std::streambuf { 19 public: 20 ~MemoryStreamBuf() = default; 21 22 /// Constructs a `MemoryStreamBuf` from a `MemoryBuffer`. 23 /// 24 /// @param buffer The memory buffer. 25 explicit MemoryStreamBuf(const std::shared_ptr<MemoryBuffer>& buffer) noexcept; 26 27 protected: 28 /// Called by `seekof` if the `openmode` is input. 29 /// 30 /// @param offset The offset value relative to the `dir`. 31 /// @param dir The seek direction. 32 /// @retval The stream position. 33 pos_type iseekoff(off_type offset, std::ios_base::seekdir dir); 34 35 /// Called by `seekof` if the `openmode` is output. 36 /// 37 /// @param offset The offset value relative to the `dir`. 38 /// @param dir The seek direction. 39 /// @retval The stream position. 40 pos_type oseekoff(off_type offset, std::ios_base::seekdir dir); 41 42 /// Called by other member functions to alter the stream position of the controlled input sequence. 43 /// 44 /// @param which The open mode. 45 /// @retval The stream position. 46 pos_type seekpos(pos_type pos, std::ios_base::openmode which) override; 47 48 /// Called by the public member function `pubseekoff` to alter the stream position. 49 /// 50 /// @param offset The offset value relative to the `dir`. 51 /// @param dir The seek direction. 52 /// @param which The open mode. 53 /// @retval The stream position. 54 std::streambuf::pos_type seekoff(std::streambuf::off_type offset, 55 std::ios_base::seekdir dir, 56 std::ios_base::openmode which) override; 57 58 /// Called by other member functions to get an estimate on the number of characters available in controlled input sequence. 59 /// 60 /// Returns number of characters available in controlled input sequence. 61 std::streamsize showmanyc() override; 62 63 /// Called by other member functions to put a character back into the controlled input sequence and decrease the position indicator. 64 /// 65 /// Returns the value of the character put back, converted to a value of type int. 66 int_type pbackfail(int_type ch) override; 67 68 /// Called by other member functions to get the current character in the controlled input sequence without changing the current position. 69 /// 70 /// Returns the value of the current character, converted to a value of type int. 71 std::streambuf::int_type underflow() override; 72 73 /// Called by other member functions to get the current character in the controlled input sequence and advances the current position. 74 /// 75 /// Returns the value of the current character, converted to a value of type int. 76 std::streambuf::int_type uflow() override; 77 78 /// Called by other member functions to put a character into the controlled output sequence. 79 /// 80 /// Returns the value of the character that's put into the stream, converted to a value of type int. 81 int_type overflow(int_type ch) override; 82 83 /// Retrieves characters from the controlled input sequence and stores them in the array pointed by s, 84 /// until either n characters have been extracted or the end of the sequence is reached. 85 /// 86 /// Returns the number of characters copied. 87 std::streamsize xsgetn(char *s, std::streamsize n) override; 88 89 /// Writes characters from the array pointed to by s into the controlled output sequence, 90 /// until either n characters have been written or the end of the output sequence is reached. 91 /// 92 /// Returns the number of characters that's written. 93 std::streamsize xsputn(const char *s, std::streamsize n) override; 94 95 private: 96 /// Reads the character at the specified position. 97 std::streambuf::int_type read(char *pos); 98 99 const std::shared_ptr<MemoryBuffer> buffer_; 100 }; 101 102 /// A class representing an in-memory input stream. 103 class MemoryIStream final : public std::istream { 104 public: 105 MemoryIStream(const std::shared_ptr<MemoryBuffer>& buffer) noexcept; 106 107 ~MemoryIStream() = default; 108 109 private: 110 MemoryStreamBuf streambuf; 111 }; 112 113 /// A class representing an in-memory output stream. 114 class MemoryOStream final : public std::ostream { 115 public: 116 MemoryOStream(const std::shared_ptr<MemoryBuffer>& buffer) noexcept; 117 118 ~MemoryOStream() = default; 119 120 private: 121 MemoryStreamBuf streambuf; 122 }; 123 124 } 125