Skip to content

Commit cd3e5fa

Browse files
committed
xtd::io::memeory_stream implements xtd::io::stream
1 parent 3f8aea0 commit cd3e5fa

File tree

2 files changed

+95
-323
lines changed

2 files changed

+95
-323
lines changed

src/xtd.core/include/xtd/io/memory_stream.hpp

Lines changed: 32 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,31 @@
22
/// @brief Contains xtd::io::memory_stream class.
33
/// @copyright Copyright (c) 2025 Gammasoft. All rights reserved.
44
#pragma once
5-
#include "seek_origin.hpp"
6-
#include "../core_export.hpp"
7-
#include "../array.hpp"
8-
#include "../object.hpp"
9-
#include "../string.hpp"
10-
#include <cstdio>
11-
#include <sstream>
5+
#include "stream.hpp"
6+
#include "../collections/generic/list.hpp"
7+
#include "../new_ptr.hpp"
128

139
/// @brief The xtd namespace contains all fundamental classes to access Hardware, Os, System, and more.
1410
namespace xtd {
1511
/// @brief The xtd::io namespace contains types that allow reading and writing to files and data streams, and types that provide basic file and directory support.
1612
namespace io {
17-
/// @cond
1813
/// @brief Creates a stream whose backing store is memory.
1914
/// ```cpp
20-
/// class core_export_ memory_stream : public xtd::object, public std::stringstream
15+
/// class core_export_ memory_stream : public xtd::io::stream
2116
/// ```
2217
/// @par Inheritance
2318
/// xtd::object → xtd::io::text_writer
2419
/// @par Header
2520
/// ```cpp
26-
/// #include <xtd/io/text_writer>
21+
/// #include <xtd/io/memory_stream>
2722
/// ```
2823
/// @par Namespace
2924
/// xtd::io
3025
/// @par Library
3126
/// xtd.core
3227
/// @ingroup xtd_core io
33-
class core_export_ memory_stream : public xtd::object, public std::stringstream {
28+
class core_export_ memory_stream : public xtd::io::stream {
3429
public:
35-
/// @name Public Aliases
36-
37-
/// @{
38-
/// @brief Represents the underlying memory buffer type.
39-
using memory_buffer = std::stringbuf;
40-
/// @}
41-
4230
/// @name Public constructors
4331

4432
/// @{
@@ -60,60 +48,43 @@ namespace xtd {
6048
/// @{
6149
/// @brief Gets a value indicating whether the current stream supports reading.
6250
/// @return `true` if the stream supports reading; otherwise, `false`.
63-
bool can_read() const noexcept;
51+
bool can_read() const noexcept override;
6452

6553
/// @brief Gets a value indicating whether the current stream supports seeking.
6654
/// @return `true` if the stream supports seeking; otherwise, `false`.
67-
bool can_seek() const noexcept;
55+
bool can_seek() const noexcept override;
6856

6957
/// @brief Gets a value indicating whether the current stream supports writing.
7058
/// @return `true` if the stream supports writing; otherwise, `false`.
71-
bool can_write() const noexcept;
59+
bool can_write() const noexcept override;
7260

7361
/// @brief Gets the number of bytes allocated for this stream.
7462
/// @return The length of the usable portion of the buffer for the stream.
7563
/// @exception xtd::argument_out_of_range_exception A capacity is less than the current length of the stream.
7664
/// @remarks `capacity` is the buffer length for system-provided byte arrays. `capacity` cannot be set to a value less than the current length of the stream.
77-
xtd::size capacity() const noexcept;
65+
xtd::size capacity() const;
7866
/// @brief Sets the number of bytes allocated for this stream.
7967
/// @param value The length of the usable portion of the buffer for the stream.
80-
/// @return This current instance.
8168
/// @exception xtd::argument_out_of_range_exception A capacity is less than the current length of the stream.
8269
/// @remarks `capacity` is the buffer length for system-provided byte arrays. `capacity` cannot be set to a value less than the current length of the stream.
83-
memory_stream& capacity(xtd::size value);
70+
void capacity(xtd::size value);
8471

8572
/// @brief Gets the length of the stream in bytes.
8673
/// @return The length of the stream in bytes.
87-
xtd::size length() const noexcept;
74+
xtd::size length() const override;
8875

8976
/// @brief Gets the current position within the stream.
9077
/// @return The current position within the stream.
91-
xtd::size position() const noexcept;
78+
xtd::size position() const override;
9279
/// @brief Sets the current position within the stream.
9380
/// @param value The current position within the stream.
94-
/// @return This current instance.
95-
memory_stream& position(xtd::size value);
81+
void position(xtd::size value) override;
9682
/// @}
9783

9884
/// @name Public Methods
9985

10086
/// @{
101-
/// @brief Reads the bytes from the current memory stream and writes them to another stream, using a specified buffer size.
102-
/// @param destination The stream to which the contents of the current memory stream will be copied.
103-
/// @param buffer_size The size of the buffer. This value must be greater than zero. The default size is 81920.
104-
void copy_to(std::ostream& destination, xtd::size buffer_size) const;
105-
106-
/// @brief Returns the array of unsigned bytes from which this stream was created.
107-
/// @return The byte array from which this stream was created, or the underlying array if a byte array was not provided to the xtd::memory_stream::memory_stream constructor during construction of the current instance.
108-
/// @remarks Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the xtd::memory_stream object, the length of the buffer returned from xtd::memory_stream::get_buffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the xtd::memory_stream::to_array method; however, xtd::memory_stream::to_array creates a copy of the data in memory.
109-
/// @remarks To create a xtd::memory_stream instance with a publicly visible buffer, use xtd::memory_stream::memory_stream, xtd::memory_stream::memory_stream (const array<byte>&, xtd::zize, xtd::size, bool, bool), or xtd::memory_stream::memory_stream (xtd::size). If the current stream is resizable, two calls to this method do not return the same array if the underlying byte array is resized between calls. For additional information, see xtd::memory_stream::capacity.
110-
const memory_buffer& get_buffer() const;
111-
112-
using std::stringstream::read;
113-
/// @brief Reads a sequence of bytes from the current memory stream and advances the position within the memory stream by the number of bytes read.
114-
/// @param buffer A region of memory. When this method returns, the contents of this span are replaced by the bytes read from the current memory stream source.
115-
/// @return The total number of bytes read into the buffer. This can be less than the number of bytes allocated in the buffer if that many bytes are not currently available, or zero (0) if the end of the memory stream has been reached.
116-
xtd::size read(xtd::array<xtd::byte>& buffer);
87+
using xtd::io::stream::read;
11788
/// @brief Reads a block of bytes from the current stream and writes the data to a buffer.
11889
/// @param buffer When this method returns, contains the specified byte array with the values between `offset` and (`offset` + `count` - 1) replaced by the characters read from the current stream.
11990
/// @param offset The zero-based byte offset in buffer at which to begin storing data from the current stream.
@@ -123,20 +94,7 @@ namespace xtd {
12394
/// @remarks If the read operation is successful, the current position within the stream advances by the number of bytes read. If an exception occurs, the current position within the stream remains unchanged.
12495
/// @remarks The `read` method will return zero only if the end of the stream is reached. In all other cases, `read` always reads at least one byte from the stream before returning. By definition, if no data is available from the stream upon a call to `read`, the `read` method returns zero (the end of the stream is reached automatically). An implementation is free to return fewer bytes than requested even if the end of the stream has not been reached.
12596
/// @remarks Use xtd::io::binary_reader for reading primitive data types.
126-
xtd::size read(xtd::array<xtd::byte>& buffer, size offset, size count);
127-
128-
/// @brief Reads a byte from the current stream.
129-
/// @return The byte cast to a xtd::int32, or -1 if the end of the stream has been reached.
130-
/// @remarks If the read operation is successful, the current position within the stream is advanced by one byte. If an exception occurs, the current position within the stream is unchanged.
131-
/// @par Examples
132-
/// This code example is part of a larger example provided for the xtd::io::memory_stream class.
133-
/// ```cpp
134-
/// // Read the remaining bytes, byte by byte.
135-
/// while(count < mem_stream.length()) {
136-
/// byte_array[count++] = as<byte>(mem_stream.read_byte());
137-
/// }
138-
/// ```
139-
xtd::int32 read_byte();
97+
xtd::size read(xtd::array<xtd::byte>& buffer, size offset, size count) override;
14098

14199
/// @brief Sets the position within the current stream to the specified value.
142100
/// @param offset The new position within the stream. This is relative to the loc parameter, and can be positive or negative.
@@ -147,20 +105,17 @@ namespace xtd {
147105
/// @brief Sets the length of the current stream to the specified value.
148106
/// @param value The value at which to set the length.
149107
/// @remarks If the specified value is less than the current length of the stream, the stream is truncated. If after the truncation the current position within the stream is past the end of the stream, the xtd::io::memery_stream::read_byte method returns -1, the xtd::io::memery_stream::read method reads zero bytes into the provided byte array, and xtd::io::memery_stream::write and xtd::io::memery_stream::write_byte methods append specified bytes at the end of the stream, increasing its length. If the specified value is larger than the current capacity and the stream is resizable, the capacity is increased, and the current position within the stream is unchanged. If the length is increased, the contents of the stream between the old and the new length are initialized to zeros.
150-
void set_length(xtd::size value);
108+
void set_length(xtd::size value) override;
151109

152110
/// @brief Writes the stream contents to a byte array, regardless of the Position property.
153111
/// @return A new byte array.
154112
/// @remarks This method omits unused bytes in xtd::io::memory_stream from the array. To get the entire buffer, use the xtd::io::memory_stream::get_buffer method.
155113
/// @remarks This method returns a copy of the contents of the xtd::io::memory_stream as a byte array. If the current instance was constructed on a provided byte array, a copy of the section of the array to which this instance has access is returned. See the xtd::io::memory_stream constructor for details.
156114
xtd::array<xtd::byte> to_array() const;
157115

158-
using std::stringstream::write;
159-
/// @brief Writes the sequence of bytes contained in `source` into the current memory stream and advances the current position within this memory stream by the number of bytes written.
160-
/// @param bytes A region of memory. This method copies the contents of this region to the current memory stream.
161-
void write(const xtd::array<xtd::byte>& bytes);
116+
using xtd::io::stream::write;
162117
/// @brief Writes a block of bytes to the current stream using data read from a buffer.
163-
/// @param bytes The buffer to write data from.
118+
/// @param buffer The buffer to write data from.
164119
/// @param offset The zero-based byte offset in buffer at which to begin copying bytes to the current stream.
165120
/// @param count The maximum number of bytes to write.
166121
/// @par Examples
@@ -171,27 +126,25 @@ namespace xtd {
171126
/// ```
172127
/// @remarks The `offset` parameter gives the offset of the first byte in `buffer` to write from, and the `count` parameter gives the number of bytes to write. If the write operation is successful, the current position within the stream is advanced by the number of bytes written. If an exception occurs, the current position within the stream is unchanged.
173128
/// @remarks Except for a `memory_stream` constructed with a byte[] parameter, write operations at the end of a `memory_stream` expand the `memory_stream`.
174-
void write(const xtd::array<xtd::byte>& bytes, size offset, size count);
175-
/// @brief Writes a byte to the current stream at the current position.
176-
/// @param value The byte to write.
177-
/// @par Examples
178-
/// This code example is part of a larger example provided for the MemoryStream class.
179-
/// ```cpp
180-
/// // Write the second string to the stream, byte by byte.
181-
/// count = 0;
182-
/// while(count < second_string.Length) {
183-
/// memStream.write_byte(second_string[count++]);
184-
/// }
185-
/// ```
186-
/// @remarks Except for a `memory_stream` constructed with a byte[] parameter, write operations at the end of a `memory_stream` expand the `memory_stream`.
187-
void write_byte(xtd::byte value);
129+
void write(const xtd::array<xtd::byte>& buffer, size offset, size count) override;
188130

189131
/// @brief Writes the entire contents of this memory stream to another stream.
190132
/// @param stream The stream to write this memory stream to.
191133
/// @exception xtd::bject_closed_exception The current or target stream is closed.
192134
/// @remarks When the current stream is open, this method is equivalent to calling [std::ostream::write](https://en.cppreference.com/w/cpp/io/basic_ostream/write) on the underlying buffer of this stream.
193-
void write_to(std::ostream& stream) const;
135+
void write_to(std::ostream& stream);
194136
/// @}
137+
private:
138+
xtd::byte abstract_read_byte_unchecked();
139+
void abstract_write_byte_unchecked(xtd::byte b);
140+
141+
struct data {
142+
xtd::array<byte>* static_buffer = null;
143+
xtd::collections::generic::list<byte> dynamic_buffer;
144+
xtd::size position = 0;
145+
bool writable = true;
146+
};
147+
ptr<data> data_ = new_ptr<data>();
195148
};
196149
}
197150
}

0 commit comments

Comments
 (0)