1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00

Implementa MemoryStream

This commit is contained in:
Danilo 2024-03-26 10:32:56 -03:00
parent c06de0cf79
commit 3f984fcea2
9 changed files with 272 additions and 1 deletions

View File

@ -3,7 +3,7 @@
#
# Add source to this project's executable.
add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp" "platform/game-dx.cpp" "platform/clock-dx.cpp")
add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp" "platform/game-dx.cpp" "platform/clock-dx.cpp" "csharp/stream.cpp")
if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET xna PROPERTY CXX_STANDARD 20)

View File

@ -0,0 +1,27 @@
#ifndef XNA_CSHARP_BUFFER_HPP
#define XNA_CSHARP_BUFFER_HPP
#include <string>
#include <vector>
namespace xna {
class Buffer {
public:
template <typename T>
static void BlockCopy(
T const* src,
rsize_t srcOffset,
T* dst,
rsize_t dstOffset,
rsize_t byteCount) {
memmove_s(dst + dstOffset, byteCount, src + srcOffset, byteCount);
}
private:
constexpr Buffer() = default;
constexpr Buffer(Buffer&&) = default;
constexpr Buffer(const Buffer&) = default;
};
}
#endif

127
framework/csharp/stream.cpp Normal file
View File

@ -0,0 +1,127 @@
#include "stream.hpp"
#include "buffer.hpp"
namespace xna {
Long MemoryStream::Seek(Long offset, SeekOrigin const& origin, xna_error_ptr_arg) {
Long p = 0;
switch (origin)
{
case SeekOrigin::Begin:
p = _origin + offset;
if (p < _origin) {
xna_error_apply(err, XnaErrorCode::OVERFLOW_OPERATION);
return -1;
}
break;
case SeekOrigin::Current:
p = _position + offset;
if (p < _origin) {
xna_error_apply(err, XnaErrorCode::OVERFLOW_OPERATION);
return -1;
}
break;
case SeekOrigin::End:
p = _length + offset;
if (p < _origin) {
xna_error_apply(err, XnaErrorCode::OVERFLOW_OPERATION);
return -1;
}
break;
default:
xna_error_apply(err, XnaErrorCode::OVERFLOW_OPERATION);
return -1;
}
assertm(_position >= 0, "position >= 0");
_position = static_cast<Int>(p);
return _position;
}
Int MemoryStream::Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) {
if (buffer == nullptr || offset < 0 || count < 0 || bufferLength - offset < count) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return -1;
}
auto off = _length - _position;
if (off > count) off = count;
if (off <= 0 || _closed)
return 0;
if (off <= 8) {
auto byteCount = off;
while (--byteCount >= 0)
buffer[offset + byteCount] = _buffer[_position + static_cast<size_t>(byteCount)];
}
else {
Buffer::BlockCopy<Byte>(_buffer.data(), _position, buffer, offset, off);
}
_position += off;
return off;
}
Int MemoryStream::Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_ptr_arg) {
return Read(buffer.data(), static_cast<Int>(buffer.size()), offset, count, err);
}
Int MemoryStream::ReadByte(xna_error_ptr_arg) {
if (!_closed)
return 0;
if (_position >= _length)
return -1;
return _buffer[_position++];
}
void MemoryStream::Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg){
if (buffer == nullptr || offset < 0 || count < 0 || bufferLength - offset < count) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return;
}
if (_closed)
return;
auto i = _position + count;
if (i < 0 || i > _length) {
xna_error_apply(err, XnaErrorCode::OVERFLOW_OPERATION);
return;
}
if (count <= 8) {
auto byteCount = count;
while (--byteCount >= 0)
_buffer[_position + static_cast<size_t>(byteCount)] = buffer[offset + byteCount];
}
else
Buffer::BlockCopy(buffer, offset, _buffer.data(), _position, count);
_position = i;
}
void MemoryStream::Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_ptr_arg){
Write(buffer.data(), static_cast<Int>(buffer.size()), offset, count, err);
}
void MemoryStream::WriteByte(Byte value, xna_error_ptr_arg) {
if (_closed)
return;
if (_position >= _length) {
xna_error_apply(err, XnaErrorCode::OVERFLOW_OPERATION);
return;
}
_buffer[_position++] = value;
}
}

View File

@ -0,0 +1,65 @@
#ifndef XNA_CSHARP_STREAM_HPP
#define XNA_CSHARP_STREAM_HPP
#include "../types.hpp"
#include "../enums.hpp"
#include "../xnaerror.hpp"
namespace xna {
class Stream {
public:
virtual Int Length() = 0;
virtual Long Position() = 0;
virtual void Close() = 0;
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_nullarg) = 0;
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) = 0;
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_nullarg) = 0;
virtual Int ReadByte(xna_error_nullarg) = 0;
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) = 0;
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_nullarg) = 0;
virtual void WriteByte(Byte value, xna_error_nullarg) = 0;
};
class MemoryStream : public Stream {
public:
constexpr MemoryStream(Int capacity) :
_buffer(static_cast<size_t>(capacity)),
_length(capacity > 0 ? capacity : 0){}
virtual constexpr Int Length() override {
if (_closed)
return 0;
return _length;
}
virtual constexpr Long Position() override {
if (_closed)
return 0;
return _position;
}
virtual constexpr void Close() override {
_closed = true;
_buffer = std::vector<Byte>();
}
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_ptr_arg) override;
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_ptr_arg) override;
virtual Int ReadByte(xna_error_ptr_arg) override;
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_ptr_arg) override;
virtual void WriteByte(Byte value, xna_error_ptr_arg) override;
public:
Int _position{ 0 };
Int _origin{ 0 };
Int _length{ 0 };
std::vector<Byte> _buffer;
bool _closed{ false };
};
}
#endif

View File

@ -1,3 +1,8 @@
/*
TimeSpan in C++
Source code: https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs,865ef7b89f41b632
*/
#ifndef XNA_CSHARP_TIMESPAN_HPP
#define XNA_CSHARP_TIMESPAN_HPP

View File

@ -47,6 +47,12 @@ namespace xna {
Portrait = 4,
};
enum class SeekOrigin {
Begin,
Current,
End,
};
enum class SurfaceFormat {
Color = 0,
Bgr565 = 1,

View File

@ -4,6 +4,16 @@
#include "types.hpp"
namespace xna {
//CShap
struct TimeSpan;
using PTimeSpan = std::shared_ptr<TimeSpan>;
class Stream;
using PStream = std::shared_ptr<Stream>;
class FileStream;
using PFileStream = std::shared_ptr<FileStream>;
class MemoryStream;
using PMemoryStream = std::shared_ptr<MemoryStream>;
//Framework
class BoundingBox;
using PBoundingBox = std::shared_ptr<BoundingBox>;

View File

@ -7,6 +7,7 @@
#include <string>
#include <memory>
#include <utility>
#include <cassert>
namespace xna {
using Sbyte = int8_t;
@ -53,6 +54,9 @@ namespace xna {
}
#define PLATFORM_DEVELOPMENT
//See ref: https://en.cppreference.com/w/cpp/error/assert
#define assertm(exp, msg) assert(((void)msg, exp))
}
#endif

27
framework/xnaerror.hpp Normal file
View File

@ -0,0 +1,27 @@
#ifndef XNA_XNAERROR_HPP
#define XNA_XNAERROR_HPP
namespace xna {
enum class XnaErrorCode {
NONE,
ARGUMENT_OUT_OF_RANGE,
ARGUMENT_IS_NULL,
INVALID_OPERATION,
OVERFLOW_OPERATION,
NULL_CAST,
};
inline void xna_error_apply(XnaErrorCode* source, XnaErrorCode const& value) {
if (source != nullptr)
*source = value;
}
inline bool xna_error_haserros(XnaErrorCode* source) {
return source != nullptr;
}
#define xna_error_nullarg XnaErrorCode* err = nullptr
#define xna_error_ptr_arg XnaErrorCode* err
}
#endif