DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
MockStream.cpp
Go to the documentation of this file.
1#include "pch.h"
3#include "System/String.h"
5#include <vector>
6
7namespace DotNetDupe {
8 namespace System {
9 namespace IO {
10
11 struct MockStream::Impl {
12 std::vector<char> m_buffer;
13 long m_lPosition;
14 bool m_bCanRead;
15 bool m_bCanWrite;
16 bool m_bCanSeek;
17 bool m_bThrowOnRead;
18 bool m_bThrowOnWrite;
19 bool m_bIsDisposed;
20 };
21
22 MockStream::MockStream(bool bCanRead, bool bCanWrite, bool bCanSeek)
23 : m_pImpl(new Impl()) {
25 m_pImpl->m_lPosition = 0;
26 m_pImpl->m_bCanRead = bCanRead;
27 m_pImpl->m_bCanWrite = bCanWrite;
28 m_pImpl->m_bCanSeek = bCanSeek;
29 m_pImpl->m_bThrowOnRead = false;
30 m_pImpl->m_bThrowOnWrite = false;
31 m_pImpl->m_bIsDisposed = false;
32 }
33
36 delete m_pImpl;
37 }
38
39 void MockStream::SetThrowOnRead(bool bThrow) {
41 m_pImpl->m_bThrowOnRead = bThrow;
42 }
43
44 void MockStream::SetThrowOnWrite(bool bThrow) {
46 m_pImpl->m_bThrowOnWrite = bThrow;
47 }
48
49 void MockStream::SetCanRead(bool bCanRead) {
51 m_pImpl->m_bCanRead = bCanRead;
52 }
53
54 void MockStream::SetCanWrite(bool bCanWrite) {
56 m_pImpl->m_bCanWrite = bCanWrite;
57 }
58
59 void MockStream::SetCanSeek(bool bCanSeek) {
61 m_pImpl->m_bCanSeek = bCanSeek;
62 }
63
66 return m_pImpl->m_bIsDisposed;
67 }
68
69 bool MockStream::CanRead() const {
71 return m_pImpl->m_bCanRead && !m_pImpl->m_bIsDisposed;
72 }
73
74 bool MockStream::CanSeek() const {
76 return m_pImpl->m_bCanSeek && !m_pImpl->m_bIsDisposed;
77 }
78
79 bool MockStream::CanWrite() const {
81 return m_pImpl->m_bCanWrite && !m_pImpl->m_bIsDisposed;
82 }
83
84 long MockStream::GetLength() const {
86 if (m_pImpl->m_bIsDisposed) throw IOException("Stream is closed.");
88 return static_cast<long>(m_pImpl->m_buffer.size());
89 }
90
93 if (m_pImpl->m_bIsDisposed) throw IOException("Stream is closed.");
95 return m_pImpl->m_lPosition;
96 }
97
98 void MockStream::SetPosition(long lValue) {
100 if (m_pImpl->m_bIsDisposed) throw IOException("Stream is closed.");
101 if (!m_pImpl->m_bCanSeek) throw IOException("Stream does not support seeking.");
103 m_pImpl->m_lPosition = lValue;
104 }
105
108 if (m_pImpl->m_bIsDisposed) throw IOException("Stream is closed.");
109 }
110
111 int MockStream::Read(char* pBuffer, int iOffset, int iCount) {
113 if (m_pImpl->m_bIsDisposed) throw IOException("Stream is closed.");
114 if (!m_pImpl->m_bCanRead) throw IOException("Stream does not support reading.");
115 if (m_pImpl->m_bThrowOnRead) throw IOException("Simulated read fault.");
116 if (!pBuffer || iOffset < 0 || iCount < 0) return 0;
117
119 long lAvailable = static_cast<long>(m_pImpl->m_buffer.size()) - m_pImpl->m_lPosition;
120 if (lAvailable <= 0) return 0;
121
123 int iToRead = static_cast<int>(lAvailable < iCount ? lAvailable : iCount);
124 for (int i = 0; i < iToRead; ++i) {
125 pBuffer[iOffset + i] = m_pImpl->m_buffer[m_pImpl->m_lPosition + i];
126 }
127 m_pImpl->m_lPosition += iToRead;
128 return iToRead;
129 }
130
131 long MockStream::Seek(long lOffset, int iOrigin) {
133 if (m_pImpl->m_bIsDisposed) throw IOException("Stream is closed.");
134 if (!m_pImpl->m_bCanSeek) throw IOException("Stream does not support seeking.");
135
137 long lNewPos = m_pImpl->m_lPosition;
138 if (iOrigin == 0) lNewPos = lOffset;
139 else if (iOrigin == 1) lNewPos += lOffset;
140 else if (iOrigin == 2) lNewPos = static_cast<long>(m_pImpl->m_buffer.size()) + lOffset;
141
143 if (lNewPos < 0) lNewPos = 0;
144 m_pImpl->m_lPosition = lNewPos;
145 return m_pImpl->m_lPosition;
146 }
147
148 void MockStream::SetLength(long lValue) {
150 if (m_pImpl->m_bIsDisposed) throw IOException("Stream is closed.");
151 if (!m_pImpl->m_bCanSeek || !m_pImpl->m_bCanWrite) throw IOException("Stream does not support seeking or writing.");
153 m_pImpl->m_buffer.resize(static_cast<size_t>(lValue), 0);
154 }
155
156 void MockStream::Write(const char* pBuffer, int iOffset, int iCount) {
158 if (m_pImpl->m_bIsDisposed) throw IOException("Stream is closed.");
159 if (!m_pImpl->m_bCanWrite) throw IOException("Stream does not support writing.");
160 if (m_pImpl->m_bThrowOnWrite) throw IOException("Simulated write fault.");
161 if (!pBuffer || iOffset < 0 || iCount <= 0) return;
162
164 size_t uRequiredSize = static_cast<size_t>(m_pImpl->m_lPosition + iCount);
165 if (m_pImpl->m_buffer.size() < uRequiredSize) {
166 m_pImpl->m_buffer.resize(uRequiredSize, 0);
167 }
168
170 for (int i = 0; i < iCount; ++i) {
171 m_pImpl->m_buffer[m_pImpl->m_lPosition + i] = pBuffer[iOffset + i];
172 }
173 m_pImpl->m_lPosition += iCount;
174 }
175
178 m_pImpl->m_bIsDisposed = true;
179 }
180
181 }
182 }
183}
The exception that is thrown when an I/O error occurs.
Mock stream implementation for unit testing and diagnostic validation.
High-performance UTF-8 / UTF-16 string manipulation class mirroring .NET System.String.
IOException()
Initializes a new instance of the IOException class with a default message.
Definition Exception.cpp:56
void Flush() override
Clears all buffers for this stream.
int Read(char *pBuffer, int iOffset, int iCount) override
Reads a sequence of bytes from the current stream.
virtual ~MockStream() override
Releases resources used by the MockStream.
long Seek(long lOffset, int iOrigin) override
Sets the position within the current stream.
bool CanSeek() const override
Gets a value indicating whether the current stream supports seeking.
void Dispose() override
Closes and releases all resources associated with the stream.
void Write(const char *pBuffer, int iOffset, int iCount) override
Writes a sequence of bytes to the current stream.
void SetCanSeek(bool bCanSeek)
Sets whether seeking is supported.
void SetCanWrite(bool bCanWrite)
Sets whether write operations are supported.
void SetCanRead(bool bCanRead)
Sets whether read operations are supported.
long GetLength() const override
Gets the length in bytes of the stream.
bool IsDisposed() const
Checks whether the stream has been disposed.
void SetThrowOnRead(bool bThrow)
Configures whether future read operations throw an IOException.
void SetPosition(long lValue) override
Sets the current position within the stream.
void SetThrowOnWrite(bool bThrow)
Configures whether future write operations throw an IOException.
bool CanWrite() const override
Gets a value indicating whether the current stream supports writing.
MockStream(bool bCanRead=true, bool bCanWrite=true, bool bCanSeek=true)
Initializes a new instance of MockStream with configurable capabilities.
bool CanRead() const override
Gets a value indicating whether the current stream supports reading.
void SetLength(long lValue) override
Sets the length of the current stream.
long GetPosition() const override
Gets the current position within the stream.