mirror of
https://github.com/borgesdan/xn65
synced 2024-12-29 21:54:47 +01:00
Correnções em BinaryReader
This commit is contained in:
parent
75d5dd5011
commit
764184341a
@ -231,8 +231,8 @@ namespace csharp {
|
|||||||
HRresult = HResults::HR_E_POINTER;
|
HRresult = HResults::HR_E_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ThrowIfNull(void* argument, OptionalString const& paramName, std::source_location const& source = std::source_location::current()) {
|
static void ThrowIfNull(void const* argument, OptionalString const& paramName, std::source_location const& source = std::source_location::current()) {
|
||||||
if (!argument)
|
if (argument == nullptr)
|
||||||
{
|
{
|
||||||
throw ArgumentNullException(paramName, source);
|
throw ArgumentNullException(paramName, source);
|
||||||
}
|
}
|
||||||
@ -245,17 +245,23 @@ namespace csharp {
|
|||||||
ArgumentOutOfRangeException(OptionalString const& message = std::nullopt, std::source_location const& source = std::source_location::current())
|
ArgumentOutOfRangeException(OptionalString const& message = std::nullopt, std::source_location const& source = std::source_location::current())
|
||||||
: ArgumentOutOfRangeException(message, std::nullopt, nullptr, source) { }
|
: ArgumentOutOfRangeException(message, std::nullopt, nullptr, source) { }
|
||||||
|
|
||||||
ArgumentOutOfRangeException(OptionalString const& message, OptionalString const& paramName, std::source_location const& source = std::source_location::current())
|
ArgumentOutOfRangeException(OptionalString const& paramName, OptionalString const& message, std::source_location const& source = std::source_location::current())
|
||||||
: ArgumentOutOfRangeException(message, paramName, nullptr, source) { }
|
: ArgumentOutOfRangeException(paramName, message, nullptr, source) { }
|
||||||
|
|
||||||
ArgumentOutOfRangeException(OptionalString const& message, std::shared_ptr<Exception> const& innerException, std::source_location const& source = std::source_location::current())
|
ArgumentOutOfRangeException(OptionalString const& message, std::shared_ptr<Exception> const& innerException, std::source_location const& source = std::source_location::current())
|
||||||
: ArgumentOutOfRangeException(message, std::nullopt, innerException, source) { }
|
: ArgumentOutOfRangeException(message, std::nullopt, innerException, source) { }
|
||||||
|
|
||||||
ArgumentOutOfRangeException(OptionalString const& message, OptionalString const& paramName, std::shared_ptr<Exception> const& innerException, std::source_location const& source = std::source_location::current())
|
ArgumentOutOfRangeException(OptionalString const& paramName, OptionalString const& message, std::shared_ptr<Exception> const& innerException, std::source_location const& source = std::source_location::current())
|
||||||
: ArgumentException(message.value_or(SR::Arg_ArgumentOutOfRangeException), paramName, innerException, source)
|
: ArgumentException(paramName, message.value_or(SR::Arg_ArgumentOutOfRangeException), innerException, source)
|
||||||
{
|
{
|
||||||
HRresult = HResults::HR_E_POINTER;
|
HRresult = HResults::HR_E_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void ThrowIfNegative(T& value, OptionalString const& paramName, std::source_location const& source = std::source_location::current()) {
|
||||||
|
if (value < 0)
|
||||||
|
throw ArgumentOutOfRangeException(paramName, source);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SystemException : public Exception {
|
class SystemException : public Exception {
|
||||||
|
@ -4,25 +4,135 @@
|
|||||||
#include "stream.hpp"
|
#include "stream.hpp"
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace csharp {
|
namespace csharp {
|
||||||
|
/*
|
||||||
|
* The BinaryReader class uses byte encodings, by default UTF8.
|
||||||
|
* This was not implemented, but we tried to follow the same standard.
|
||||||
|
* Also the reading of primitives was modified.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//The BinaryReader class uses byte encodings, by default UTF8
|
||||||
class BinaryReader {
|
class BinaryReader {
|
||||||
public:
|
public:
|
||||||
BinaryReader(std::shared_ptr<Stream> input, bool leaveOpen = false)
|
BinaryReader(std::shared_ptr<Stream> const& input, bool leaveOpen = false)
|
||||||
: _stream(input), _leaveOpen(leaveOpen)
|
: _stream(input), _leaveOpen(leaveOpen)
|
||||||
{
|
{
|
||||||
if (input == nullptr)
|
ArgumentNullException::ThrowIfNull(input.get(), "input");
|
||||||
throw csharp::ArgumentNullException(std::nullopt, "input");
|
|
||||||
|
if (!input->CanRead())
|
||||||
|
throw ArgumentException(SR::Argument_StreamNotReadable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::shared_ptr<Stream> BaseStream() const { return _stream; }
|
||||||
|
|
||||||
virtual void Close() {
|
virtual void Close() {
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!_leaveOpen)
|
if (!_leaveOpen)
|
||||||
_stream->Close();
|
_stream->Close();
|
||||||
|
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int32_t PeekChar();
|
||||||
|
virtual int32_t Read();
|
||||||
|
|
||||||
|
virtual uint8_t ReadByte() {
|
||||||
|
return InternalReadByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual inline int8_t ReadSByte() {
|
||||||
|
return static_cast<int8_t>(InternalReadByte());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual inline bool ReadBoolean() {
|
||||||
|
return InternalReadByte() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual char ReadChar();
|
||||||
|
|
||||||
|
virtual int16_t ReadInt16() {
|
||||||
|
return ReadNumeric<int16_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uint16_t ReadUInt16() {
|
||||||
|
return ReadNumeric<uint16_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int32_t ReadInt32() {
|
||||||
|
return ReadNumeric<int32_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uint32_t ReadUInt32() {
|
||||||
|
return ReadNumeric<uint32_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int64_t ReadInt64() {
|
||||||
|
return ReadNumeric<int64_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uint64_t ReadUInt64() {
|
||||||
|
return ReadNumeric<uint64_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual float ReadSingle() {
|
||||||
|
return ReadNumeric<float>();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual double ReadDouble() {
|
||||||
|
return ReadNumeric<double>();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::string ReadString();
|
||||||
|
|
||||||
|
virtual int32_t Read(char* buffer, int32_t bufferLength, int32_t index, int32_t count);
|
||||||
|
|
||||||
|
virtual int32_t Read(char* buffer, int32_t bufferLength);
|
||||||
|
|
||||||
|
virtual std::vector<char> ReadChars(int32_t count);
|
||||||
|
|
||||||
|
virtual int32_t Read(uint8_t* buffer, int32_t bufferLength, int32_t index, int32_t count);
|
||||||
|
|
||||||
|
virtual int32_t Read(uint8_t* buffer, int32_t bufferLength);
|
||||||
|
|
||||||
|
virtual std::vector<uint8_t> ReadBytes(int32_t count);
|
||||||
|
|
||||||
|
virtual void ReadExactly(uint8_t* buffer, int32_t bufferLength);
|
||||||
|
|
||||||
|
int32_t Read7BitEncodedInt();
|
||||||
|
int64_t Read7BitEncodedInt64();
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t InternalReadByte();
|
||||||
|
void InternalRead(std::vector<uint8_t>& buffer);
|
||||||
|
int32_t InternalReadChars(char* buffer, int32_t bufferLength);
|
||||||
|
|
||||||
|
template<class TNUMERIC>
|
||||||
|
TNUMERIC ReadNumeric() {
|
||||||
|
const auto numericSize = sizeof(TNUMERIC);
|
||||||
|
|
||||||
|
if (_auxBuffer.size() != numericSize)
|
||||||
|
_auxBuffer.resize(numericSize);
|
||||||
|
|
||||||
|
InternalRead(_auxBuffer);
|
||||||
|
|
||||||
|
const auto ptr = reinterpret_cast<TNUMERIC*>(_auxBuffer.data());
|
||||||
|
const auto value = *ptr;
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr int MaxCharBytesSize = 128;
|
||||||
|
|
||||||
std::shared_ptr<Stream> _stream;
|
std::shared_ptr<Stream> _stream;
|
||||||
bool _leaveOpen;
|
bool _leaveOpen;
|
||||||
|
bool _disposed{false};
|
||||||
|
bool _2BytesPerChar{ false };
|
||||||
|
|
||||||
|
std::vector<uint8_t> _auxBuffer;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,13 +60,21 @@ namespace csharp {
|
|||||||
virtual int32_t Read(uint8_t* buffer, int32_t bufferLength);
|
virtual int32_t Read(uint8_t* buffer, int32_t bufferLength);
|
||||||
virtual int32_t ReadByte();
|
virtual int32_t ReadByte();
|
||||||
|
|
||||||
virtual int32_t ReadExactly(uint8_t* buffer, int32_t bufferLength, int32_t offset, int32_t count) {
|
void ReadExactly(uint8_t* buffer, int32_t bufferLength) {
|
||||||
return ReadAtLeastCore(buffer, bufferLength, bufferLength, true);
|
ReadAtLeastCore(buffer, bufferLength, bufferLength, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ReadExactly(uint8_t* buffer, int32_t offset, int32_t count) {
|
||||||
|
ReadAtLeastCore(buffer + offset, count, count, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ReadAtLeast(uint8_t* buffer, int32_t bufferLength, int32_t minimumBytes, bool throwOnEndOfStream = true) {
|
||||||
|
return ReadAtLeastCore(buffer, bufferLength, minimumBytes, throwOnEndOfStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Write(uint8_t const* buffer, int32_t bufferLength, int32_t offset, int32_t count) = 0;
|
virtual void Write(uint8_t const* buffer, int32_t bufferLength, int32_t offset, int32_t count) = 0;
|
||||||
virtual void Write(uint8_t const* buffer, int32_t bufferLength);
|
virtual void Write(uint8_t const* buffer, int32_t bufferLength);
|
||||||
virtual void WriteByte(uint8_t value);
|
virtual void WriteByte(uint8_t value) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ValidateBuffer(uint8_t const* buffer, int32_t bufferLength);
|
void ValidateBuffer(uint8_t const* buffer, int32_t bufferLength);
|
||||||
|
@ -50,7 +50,13 @@ namespace csharp {
|
|||||||
inline static const std::string ArgumentOutOfRange_StreamLength
|
inline static const std::string ArgumentOutOfRange_StreamLength
|
||||||
= "Stream length must be non-negative and less than 2^31 - 1 - origin.";
|
= "Stream length must be non-negative and less than 2^31 - 1 - origin.";
|
||||||
inline static const std::string net_uri_NotAbsolute
|
inline static const std::string net_uri_NotAbsolute
|
||||||
= "This operation is not supported for a relative URI.";
|
= "This operation is not supported for a relative URI.";
|
||||||
|
inline static const std::string Argument_StreamNotReadable
|
||||||
|
= "Stream was not readable.";
|
||||||
|
inline static const std::string Format_Bad7BitInt
|
||||||
|
= "Too many bytes in what should have been a 7-bit encoded integer.";
|
||||||
|
inline static const std::string IO_InvalidStringLen_Len
|
||||||
|
= "BinaryReader encountered an invalid string length.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,4 +10,4 @@ if (CMAKE_VERSION VERSION_GREATER 3.12)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# TODO: Add tests and install targets if needed.
|
# TODO: Add tests and install targets if needed.
|
||||||
target_link_libraries(BlankApp Xn65DX)
|
target_link_libraries(BlankApp Xn65DX CSharp++)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "xna-dx/framework.hpp"
|
#include "xna-dx/framework.hpp"
|
||||||
|
#include "csharp/io/binary.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace xna;
|
using namespace xna;
|
||||||
@ -11,6 +12,21 @@ namespace xna {
|
|||||||
public:
|
public:
|
||||||
Game1() : Game() {
|
Game1() : Game() {
|
||||||
Content()->RootDirectory("Content");
|
Content()->RootDirectory("Content");
|
||||||
|
|
||||||
|
auto stream = std::make_shared<csharp::FileStream>("D:/file.bin", csharp::FileMode::Open);
|
||||||
|
auto reader = csharp::BinaryReader(stream);
|
||||||
|
auto bo = reader.ReadBoolean(); //reader.ReadChar()
|
||||||
|
auto sb = reader.ReadSByte(); //127
|
||||||
|
auto by = reader.ReadByte(); //255
|
||||||
|
auto ch = reader.ReadChar(); //x
|
||||||
|
auto i16 = reader.ReadInt16(); //32767
|
||||||
|
auto ui16 = reader.ReadUInt16();//65535
|
||||||
|
auto i32 = reader.ReadInt32(); //2147483647
|
||||||
|
auto ui32 = reader.ReadUInt32(); //4294967295
|
||||||
|
auto i64 = reader.ReadInt64(); //9223372036854775807
|
||||||
|
auto ui64 = reader.ReadUInt64(); //18446744073709551615
|
||||||
|
auto str = reader.ReadString(); //The string in stream.
|
||||||
|
auto str2 = reader.ReadString(); //Ç de cedilha e ñ com til mas sem ¨ trema.
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize() override {
|
void Initialize() override {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
# Add source to this project's executable.
|
# Add source to this project's executable.
|
||||||
add_library (CSharp++ STATIC
|
add_library (CSharp++ STATIC
|
||||||
"exception.cpp"
|
"exception.cpp"
|
||||||
"io/stream.cpp")
|
"io/stream.cpp" "io/binary.cpp")
|
||||||
|
|
||||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||||
set_property(TARGET CSharp++ PROPERTY CXX_STANDARD 20)
|
set_property(TARGET CSharp++ PROPERTY CXX_STANDARD 20)
|
||||||
|
345
sources/csharp/io/binary.cpp
Normal file
345
sources/csharp/io/binary.cpp
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
#include "csharp/io/binary.hpp"
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace csharp {
|
||||||
|
int32_t BinaryReader::PeekChar() {
|
||||||
|
if (_disposed)
|
||||||
|
throw InvalidOperationException();
|
||||||
|
|
||||||
|
if (!_stream->CanSeek())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto origPos = _stream->Position();
|
||||||
|
const auto ch = Read();
|
||||||
|
|
||||||
|
_stream->Position(origPos);
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BinaryReader::Read() {
|
||||||
|
if (_disposed)
|
||||||
|
throw InvalidOperationException();
|
||||||
|
|
||||||
|
int32_t charsRead = 0;
|
||||||
|
int32_t numBytes;
|
||||||
|
int64_t posSav = 0;
|
||||||
|
|
||||||
|
if (_stream->CanSeek())
|
||||||
|
{
|
||||||
|
posSav = _stream->Position();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto charBytes = std::vector<uint8_t>(MaxCharBytesSize);
|
||||||
|
char singleChar = '\0';
|
||||||
|
|
||||||
|
while (charsRead == 0) {
|
||||||
|
numBytes = _2BytesPerChar ? 2 : 1;
|
||||||
|
|
||||||
|
auto r = _stream->ReadByte();
|
||||||
|
charBytes[0] = static_cast<uint8_t>(r);
|
||||||
|
|
||||||
|
if (r == -1)
|
||||||
|
{
|
||||||
|
numBytes = 0;
|
||||||
|
}
|
||||||
|
if (numBytes == 2)
|
||||||
|
{
|
||||||
|
r = _stream->ReadByte();
|
||||||
|
charBytes[1] = static_cast<uint8_t>(r);
|
||||||
|
|
||||||
|
if (r == -1)
|
||||||
|
{
|
||||||
|
numBytes = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numBytes == 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto chars = reinterpret_cast<char*>(charBytes.data());
|
||||||
|
const auto decoder = std::string(chars);
|
||||||
|
charsRead = decoder.size();
|
||||||
|
singleChar = decoder[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return singleChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BinaryReader::InternalReadByte() {
|
||||||
|
if (_disposed)
|
||||||
|
throw InvalidOperationException();
|
||||||
|
|
||||||
|
const auto b = _stream->ReadByte();
|
||||||
|
if (b == -1)
|
||||||
|
{
|
||||||
|
throw EndOfStreamException(SR::IO_EOF_ReadBeyondEOF);
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<uint8_t>(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
char BinaryReader::ReadChar() {
|
||||||
|
const auto value = Read();
|
||||||
|
|
||||||
|
if (value == -1)
|
||||||
|
{
|
||||||
|
throw EndOfStreamException(SR::IO_EOF_ReadBeyondEOF);
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<char>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryReader::InternalRead(std::vector<uint8_t>& buffer) {
|
||||||
|
if (_disposed)
|
||||||
|
throw InvalidOperationException();
|
||||||
|
|
||||||
|
_stream->ReadExactly(buffer.data(), buffer.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string BinaryReader::ReadString() {
|
||||||
|
if (_disposed)
|
||||||
|
throw InvalidOperationException();
|
||||||
|
|
||||||
|
const auto stringLength = Read7BitEncodedInt();
|
||||||
|
if (stringLength < 0)
|
||||||
|
{
|
||||||
|
throw IOException(SR::IO_InvalidStringLen_Len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stringLength == 0)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto charBytes = std::vector<uint8_t>(MaxCharBytesSize);
|
||||||
|
int32_t currPos = 0;
|
||||||
|
|
||||||
|
std::string sb;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
const auto readLength = std::min(MaxCharBytesSize, stringLength - currPos);
|
||||||
|
const auto n = _stream->Read(charBytes.data(), readLength);
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
throw EndOfStreamException(SR::IO_EOF_ReadBeyondEOF);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto chars = reinterpret_cast<char*>(charBytes.data());
|
||||||
|
|
||||||
|
if (currPos == 0 && n == stringLength)
|
||||||
|
{
|
||||||
|
return std::string(chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(chars);
|
||||||
|
|
||||||
|
currPos += n;
|
||||||
|
|
||||||
|
} while (currPos < stringLength);
|
||||||
|
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BinaryReader::Read(char* buffer, int32_t bufferLength, int32_t index, int32_t count) {
|
||||||
|
ArgumentNullException::ThrowIfNull(buffer, "buffer");
|
||||||
|
|
||||||
|
if (index < 0)
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
if (count < 0)
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
if (bufferLength - index < count) {
|
||||||
|
throw ArgumentException(SR::Argument_InvalidOffLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_disposed)
|
||||||
|
throw InvalidOperationException();
|
||||||
|
|
||||||
|
return InternalReadChars(buffer + index, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BinaryReader::Read(char* buffer, int32_t bufferLength) {
|
||||||
|
if (_disposed)
|
||||||
|
throw InvalidOperationException();
|
||||||
|
|
||||||
|
return InternalReadChars(buffer, bufferLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BinaryReader::InternalReadChars(char* buffer, int32_t bufferLength) {
|
||||||
|
int totalCharsRead = 0;
|
||||||
|
auto charBytes = std::vector<uint8_t>(MaxCharBytesSize);
|
||||||
|
|
||||||
|
auto numBytes = bufferLength;
|
||||||
|
|
||||||
|
while (bufferLength > 0)
|
||||||
|
{
|
||||||
|
auto numBytes = bufferLength;
|
||||||
|
|
||||||
|
if (_2BytesPerChar)
|
||||||
|
{
|
||||||
|
numBytes <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> byteBuffer;
|
||||||
|
|
||||||
|
if (numBytes > MaxCharBytesSize)
|
||||||
|
{
|
||||||
|
numBytes = MaxCharBytesSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
numBytes = _stream->Read(charBytes.data(), numBytes);
|
||||||
|
byteBuffer = std::vector<uint8_t>(charBytes.begin(), charBytes.begin() + numBytes);
|
||||||
|
|
||||||
|
if (byteBuffer.empty())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto chars = reinterpret_cast<char*>(byteBuffer.data());
|
||||||
|
auto charsRead = std::string(chars);
|
||||||
|
|
||||||
|
bufferLength = charsRead.length();
|
||||||
|
totalCharsRead += charsRead.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
// we may have read fewer than the number of characters requested if end of stream reached
|
||||||
|
// or if the encoding makes the char count too big for the buffer (e.g. fallback sequence)
|
||||||
|
return totalCharsRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> BinaryReader::ReadChars(int32_t count) {
|
||||||
|
if (count < 0)
|
||||||
|
throw ArgumentOutOfRangeException();
|
||||||
|
|
||||||
|
if (_disposed)
|
||||||
|
throw InvalidOperationException();
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
return std::vector<char>();
|
||||||
|
|
||||||
|
auto chars = std::vector<char>(count);
|
||||||
|
const auto n = InternalReadChars(chars.data(), chars.size());
|
||||||
|
|
||||||
|
if (n != count) {
|
||||||
|
chars = std::vector<char>(chars.begin(), chars.begin() + count);
|
||||||
|
}
|
||||||
|
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BinaryReader::Read(uint8_t* buffer, int32_t bufferLength, int32_t index, int32_t count) {
|
||||||
|
ArgumentNullException::ThrowIfNull(buffer, "buffer");
|
||||||
|
ArgumentOutOfRangeException::ThrowIfNegative(index, "index");
|
||||||
|
ArgumentOutOfRangeException::ThrowIfNegative(count, "count");
|
||||||
|
|
||||||
|
if (bufferLength - index < count) {
|
||||||
|
throw ArgumentException(SR::Argument_InvalidOffLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_disposed)
|
||||||
|
throw InvalidOperationException();
|
||||||
|
|
||||||
|
return _stream->Read(buffer, bufferLength, index, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BinaryReader::Read(uint8_t* buffer, int32_t bufferLength) {
|
||||||
|
if (_disposed)
|
||||||
|
throw InvalidOperationException();
|
||||||
|
|
||||||
|
return _stream->Read(buffer, bufferLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> BinaryReader::ReadBytes(int32_t count) {
|
||||||
|
ArgumentOutOfRangeException::ThrowIfNegative(count, "count");
|
||||||
|
|
||||||
|
if (_disposed)
|
||||||
|
throw InvalidOperationException();
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
return std::vector<uint8_t>();
|
||||||
|
|
||||||
|
auto result = std::vector<uint8_t>(count);
|
||||||
|
const auto numRead = _stream->ReadAtLeast(result.data(), result.size(), result.size(), false);
|
||||||
|
|
||||||
|
if (numRead != result.size())
|
||||||
|
{
|
||||||
|
result = std::vector<uint8_t>(result.begin(), result.begin() + numRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryReader::ReadExactly(uint8_t* buffer, int32_t bufferLength) {
|
||||||
|
if (_disposed)
|
||||||
|
throw InvalidOperationException();
|
||||||
|
|
||||||
|
_stream->ReadExactly(buffer, bufferLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BinaryReader::Read7BitEncodedInt() {
|
||||||
|
uint32_t result = 0;
|
||||||
|
uint8_t byteReadJustNow;
|
||||||
|
|
||||||
|
constexpr int32_t MaxBytesWithoutOverflow = 4;
|
||||||
|
|
||||||
|
for (int32_t shift = 0; shift < MaxBytesWithoutOverflow * 7; shift += 7)
|
||||||
|
{
|
||||||
|
byteReadJustNow = ReadByte();
|
||||||
|
result |= (byteReadJustNow & 0x7Fu) << shift;
|
||||||
|
|
||||||
|
if (byteReadJustNow <= 0x7Fu)
|
||||||
|
{
|
||||||
|
return static_cast<int32_t>(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byteReadJustNow = ReadByte();
|
||||||
|
|
||||||
|
if (byteReadJustNow > 15u)
|
||||||
|
{
|
||||||
|
//FormatException
|
||||||
|
throw InvalidOperationException(SR::Format_Bad7BitInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
result |= static_cast<uint32_t>(byteReadJustNow) << (MaxBytesWithoutOverflow * 7);
|
||||||
|
return static_cast<int32_t>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t BinaryReader::Read7BitEncodedInt64() {
|
||||||
|
uint64_t result = 0;
|
||||||
|
uint8_t byteReadJustNow;
|
||||||
|
|
||||||
|
constexpr int32_t MaxBytesWithoutOverflow = 9;
|
||||||
|
|
||||||
|
for (int32_t shift = 0; shift < MaxBytesWithoutOverflow * 7; shift += 7)
|
||||||
|
{
|
||||||
|
byteReadJustNow = ReadByte();
|
||||||
|
result |= (byteReadJustNow & 0x7Ful) << shift;
|
||||||
|
|
||||||
|
if (byteReadJustNow <= 0x7Fu)
|
||||||
|
{
|
||||||
|
return static_cast<int64_t>(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byteReadJustNow = ReadByte();
|
||||||
|
|
||||||
|
if (byteReadJustNow > 1u)
|
||||||
|
{
|
||||||
|
//FormatException
|
||||||
|
throw InvalidOperationException(SR::Format_Bad7BitInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
result |= static_cast<int64_t>(byteReadJustNow) << (MaxBytesWithoutOverflow * 7);
|
||||||
|
return static_cast<int64_t>(result);
|
||||||
|
}
|
||||||
|
}
|
@ -684,7 +684,8 @@ namespace csharp {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto result = static_cast<int32_t>(c);
|
const auto uchar = static_cast<unsigned char>(c);
|
||||||
|
const auto result = static_cast<int32_t>(uchar);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user