DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
BinaryReader.cpp
Go to the documentation of this file.
1#include "pch.h"
8#include <cstring>
9
10namespace DotNetDupe {
11 namespace System {
12 namespace IO {
13
14 BinaryReader::BinaryReader(Stream* pStream, bool bLeaveOpen, bool bIsLittleEndian)
15 : m_pStream(pStream),
16 m_bLeaveOpen(bLeaveOpen),
17 m_bIsLittleEndian(bIsLittleEndian),
18 m_bDisposed(false) {
20 if (m_pStream == nullptr) {
21 throw ArgumentNullException("pStream cannot be null.");
22 }
23 }
24
25 BinaryReader::BinaryReader(SmartPointer<Stream> spStream, bool bLeaveOpen, bool bIsLittleEndian)
26 : m_pStream(spStream.Get()),
27 m_spOwnedStream(spStream),
28 m_bLeaveOpen(bLeaveOpen),
29 m_bIsLittleEndian(bIsLittleEndian),
30 m_bDisposed(false) {
32 if (m_pStream == nullptr) {
33 throw ArgumentNullException("spStream cannot be null.");
34 }
35 }
36
41
42 void BinaryReader::EnsureNotDisposed() const {
44 if (m_bDisposed) {
45 throw InvalidOperationException("BinaryReader is disposed.");
46 }
47 }
48
51 Dispose();
52 }
53
56 if (!m_bDisposed) {
57 m_bDisposed = true;
58 if (!m_bLeaveOpen && m_pStream != nullptr) {
59 m_pStream->Dispose();
60 }
61 }
62 }
63
65 return m_pStream;
66 }
67
69 return m_bIsLittleEndian;
70 }
71
72 void BinaryReader::SetLittleEndian(bool bIsLittleEndian) {
73 m_bIsLittleEndian = bIsLittleEndian;
74 }
75
76 void BinaryReader::FillBuffer(char* pBuffer, int iCount) {
78 EnsureNotDisposed();
79
81 int iTotalRead = 0;
82 while (iTotalRead < iCount) {
83 int iRead = m_pStream->Read(pBuffer + iTotalRead, 0, iCount - iTotalRead);
84 if (iRead <= 0) {
85 throw EndOfStreamException("Unable to read beyond the end of the stream.");
86 }
87 iTotalRead += iRead;
88 }
89 }
90
92 static void ReverseBytes(char* pBuf, int iSize) {
93 for (int i = 0, j = iSize - 1; i < j; ++i, --j) {
94 char chTemp = pBuf[i];
95 pBuf[i] = pBuf[j];
96 pBuf[j] = chTemp;
97 }
98 }
99
101 return ReadByte() != 0;
102 }
103
105 char chBuf = 0;
106 FillBuffer(&chBuf, 1);
107 return static_cast<byte>(chBuf);
108 }
109
111 return static_cast<signed char>(ReadByte());
112 }
113
115 return static_cast<char>(ReadByte());
116 }
117
120 if (iCount < 0) {
121 throw ArgumentOutOfRangeException("iCount must be non-negative.");
122 }
123 EnsureNotDisposed();
124
126 Array<byte> arrBytes(iCount);
127 for (int i = 0; i < iCount; ++i) {
128 arrBytes[i] = ReadByte();
129 }
130 return arrBytes;
131 }
132
133 int BinaryReader::Read(Array<byte>& arrBuffer, int iIndex, int iCount) {
135 EnsureNotDisposed();
136 if (iIndex < 0 || iCount < 0 || (iIndex + iCount) > arrBuffer.GetLength()) {
137 throw ArgumentOutOfRangeException("Invalid index and count bounds.");
138 }
139
141 int iRead = m_pStream->Read(reinterpret_cast<char*>(arrBuffer.GetData()) + iIndex, 0, iCount);
142 return iRead < 0 ? 0 : iRead;
143 }
144
146 char szBuf[2] = { 0 };
147 FillBuffer(szBuf, 2);
148 if (m_bIsLittleEndian != BitConverter::IsLittleEndian) {
149 ReverseBytes(szBuf, 2);
150 }
151 short iVal = 0;
152 std::memcpy(&iVal, szBuf, 2);
153 return iVal;
154 }
155
156 unsigned short BinaryReader::ReadUInt16() {
157 return static_cast<unsigned short>(ReadInt16());
158 }
159
161 char szBuf[4] = { 0 };
162 FillBuffer(szBuf, 4);
163 if (m_bIsLittleEndian != BitConverter::IsLittleEndian) {
164 ReverseBytes(szBuf, 4);
165 }
166 int iVal = 0;
167 std::memcpy(&iVal, szBuf, 4);
168 return iVal;
169 }
170
172 return static_cast<unsigned int>(ReadInt32());
173 }
174
176 char szBuf[8] = { 0 };
177 FillBuffer(szBuf, 8);
178 if (m_bIsLittleEndian != BitConverter::IsLittleEndian) {
179 ReverseBytes(szBuf, 8);
180 }
181 long long llVal = 0;
182 std::memcpy(&llVal, szBuf, 8);
183 return llVal;
184 }
185
186 unsigned long long BinaryReader::ReadUInt64() {
187 return static_cast<unsigned long long>(ReadInt64());
188 }
189
191 char szBuf[4] = { 0 };
192 FillBuffer(szBuf, 4);
193 if (m_bIsLittleEndian != BitConverter::IsLittleEndian) {
194 ReverseBytes(szBuf, 4);
195 }
196 float fVal = 0.0f;
197 std::memcpy(&fVal, szBuf, 4);
198 return fVal;
199 }
200
202 char szBuf[8] = { 0 };
203 FillBuffer(szBuf, 8);
204 if (m_bIsLittleEndian != BitConverter::IsLittleEndian) {
205 ReverseBytes(szBuf, 8);
206 }
207 double dVal = 0.0;
208 std::memcpy(&dVal, szBuf, 8);
209 return dVal;
210 }
211
214 if (iLength < 0) {
215 throw ArgumentOutOfRangeException("iLength must be non-negative.");
216 }
217 if (iLength == 0) {
218 return String("");
219 }
220
222 Array<byte> arrBytes = ReadBytes(iLength);
223 Array<char> arrChars(iLength + 1);
224 for (int i = 0; i < iLength; ++i) {
225 arrChars[i] = static_cast<char>(arrBytes[i]);
226 }
227 arrChars[iLength] = '\0';
228 return String(arrChars.GetData());
229 }
230
231 }
232 }
233}
Defines the exception thrown when a null reference is passed to a method that does not accept it.
Defines the exception thrown when an argument value is outside the acceptable range of values.
Converts base data types to arrays of bytes, and arrays of bytes to base data types.
The exception that is thrown when reading is attempted past the end of a stream.
Defines the exception thrown when a method call is invalid for the object's current state.
ArgumentNullException(const String &sMessage)
Initializes a new instance of the ArgumentNullException class with a specified error message.
ArgumentOutOfRangeException(const String &sMessage)
Initializes a new instance of the ArgumentOutOfRangeException class with a specified error message.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition Array.h:29
int GetLength() const
Gets the total number of elements in all dimensions of the Array.
Definition Array.h:142
T * GetData()
Gets a pointer to the contiguous internal element buffer.
Definition Array.h:146
static const bool IsLittleEndian
Indicates whether this computer architecture is little-endian.
virtual String ReadString(int iLength)
Reads a string of specified byte length from the current stream.
bool IsLittleEndian() const
Gets whether values are decoded in little-endian order.
virtual int Read(Array< byte > &arrBuffer, int iIndex, int iCount)
Reads the specified number of bytes from the stream into an array starting at a specific index.
virtual short ReadInt16()
Reads a 2-byte signed integer from the current stream.
virtual bool ReadBoolean()
Reads a Boolean value from the current stream and advances the current position by one byte.
virtual int ReadInt32()
Reads a 4-byte signed integer from the current stream.
virtual double ReadDouble()
Reads an 8-byte floating point value from the current stream.
virtual signed char ReadSByte()
Reads a signed byte from this stream and advances the current position by one byte.
virtual float ReadSingle()
Reads a 4-byte floating point value from the current stream.
virtual unsigned long long ReadUInt64()
Reads an 8-byte unsigned integer from the current stream.
virtual void Close()
Closes the current reader and the underlying stream if configured.
virtual long long ReadInt64()
Reads an 8-byte signed integer from the current stream.
virtual Array< byte > ReadBytes(int iCount)
Reads the specified number of bytes from the current stream into a byte array.
virtual unsigned short ReadUInt16()
Reads a 2-byte unsigned integer from the current stream.
void Dispose() override
Releases all unmanaged resources used by the BinaryReader.
virtual byte ReadByte()
Reads the next byte from the current stream and advances the current position by one byte.
virtual unsigned int ReadUInt32()
Reads a 4-byte unsigned integer from the current stream.
BinaryReader(Stream *pStream, bool bLeaveOpen=false, bool bIsLittleEndian=true)
Initializes a new instance of the BinaryReader class based on the specified stream and endianness.
Stream * GetBaseStream() const
Exposes access to the underlying stream.
void SetLittleEndian(bool bIsLittleEndian)
Sets the endianness for binary decoding.
virtual char ReadChar()
Reads the next character from the current stream.
virtual ~BinaryReader()
Destructor ensuring deterministic cleanup and closing.
EndOfStreamException(const String &sMessage)
Initializes a new instance of the EndOfStreamException class with a specified error message.
Provides a generic view of a sequence of bytes.
Definition Stream.h:16
virtual int Read(char *buffer, int offset, int count)=0
Reads a sequence of bytes from the current stream and advances the position within the stream by the ...
InvalidOperationException(const String &sMessage)
Initializes a new instance of the InvalidOperationException class with a specified error message.
A unified smart pointer that supports both unique and shared ownership semantics.
Represents text as a sequence of UTF-8 code units with culture-invariant operations.
Definition String.h:74
String()
Initializes a new instance of the String class to an empty string.
Definition String.cpp:64
static void ReverseBytes(char *pBuf, int iSize)
Reverse bytes in place for endian conversion.