diff --git a/src/ogfx/gui/widgets/TreeView.hpp b/src/ogfx/gui/widgets/TreeView.hpp index 8cf42d4..1bad706 100644 --- a/src/ogfx/gui/widgets/TreeView.hpp +++ b/src/ogfx/gui/widgets/TreeView.hpp @@ -32,7 +32,7 @@ namespace ogfx { class TreeView : public ScrollableWidget { - public: class Item : public ostd::__i_stringeable + public: class Item : public ostd::I_stringeable { public: inline Item(TreeView& parent) { m_treeView = &parent; } diff --git a/src/ostd/data/AnimationData.hpp b/src/ostd/data/AnimationData.hpp index 6ca5092..29ccb82 100644 --- a/src/ostd/data/AnimationData.hpp +++ b/src/ostd/data/AnimationData.hpp @@ -25,7 +25,7 @@ namespace ostd { - struct AnimationData : public ostd::__i_stringeable { + struct AnimationData : public ostd::I_stringeable { i32 frameCount { 1 }; i32 stillFrame { 0 }; f64 fps { 60.0 }; diff --git a/src/ostd/data/BaseObject.hpp b/src/ostd/data/BaseObject.hpp index 550a8c6..92a7c07 100755 --- a/src/ostd/data/BaseObject.hpp +++ b/src/ostd/data/BaseObject.hpp @@ -27,7 +27,7 @@ namespace ostd { class OutputHandlerBase; struct Signal; - class BaseObject : public __i_stringeable, public __i_serializable + class BaseObject : public I_stringeable, public I_serializable { public: using SignalCallback = std::function; public: diff --git a/src/ostd/io/Serial.cpp b/src/ostd/io/Serial.cpp index 44123a9..08e3165 100755 --- a/src/ostd/io/Serial.cpp +++ b/src/ostd/io/Serial.cpp @@ -3,189 +3,209 @@ namespace ostd { - bool Serial::isValidAddress(u64 addr, u32 size) + bool Serial::construct(u64 size, Serial::Endianness endianness, bool preInitialize, i8 initialValue) { - if (addr == 0) return false; - if (size == 0) return false; - if (addr > u64Range::max() - size) return false; // u64 overflow check - return (addr + size - 1) < s_openStream.size(); + m_address = 1; + return m_data.construct(size, endianness, preInitialize, initialValue); } - Serial::ReadResult Serial::read::int8(u64 addr) + bool Serial::resetAddress(u64 newAddr) { - if (!isStreamAttached()) return { 0, true }; - managed_address_check(addr); + if (newAddr == 0) + newAddr = 1; // Managed Address should never be 0, if the intent is to reset the managed address to the start of the Stream it will be set to 1 + if (!isValidAddress(newAddr)) + return false; + m_address = newAddr; + return true; + } + + bool Serial::isValidAddress(u64 addr, u32 size) const + { + if (addr == 0) return false; // addr == 0 is managed mode and should never reach this point + if (size == 0) return false; + if (addr > u64Range::max() - size) return false; // u64 overflow check + return (addr + size - 1) < m_data.size(); + } + + + + + + Serial::ReadResult Serial::Reader::int8(u64 _addr) + { + if (isInvalid()) return { 0, true }; + u64& addr = resolve_address(_addr); if (!isValidAddress(addr, tTypeSize::INT8)) return { 0, true }; - i8 val = s_openStream[addr]; - s_addr += tTypeSize::INT8; + i8 val = data[addr]; + addr += tTypeSize::INT8; return { val, false }; } - Serial::ReadResult Serial::read::uint8(u64 addr) + Serial::ReadResult Serial::Reader::uint8(u64 _addr) { - auto res = int8(addr); + auto res = int8(_addr); return { cast(res.value), res.error }; } - Serial::ReadResult Serial::read::int16(u64 addr) + Serial::ReadResult Serial::Reader::int16(u64 _addr) { - if (!isStreamAttached()) return { 0, true }; - managed_address_check(addr); + if (isInvalid()) return { 0, true }; + u64& addr = resolve_address(_addr); if (!isValidAddress(addr, tTypeSize::INT16)) return { 0, true }; i16 val = 0; if (isLittleEndian()) { - val = ((s_openStream[addr + 0] ) & 0x00FFU) - | ((s_openStream[addr + 1] << 8) & 0xFF00U); + val = ((data[addr + 0] ) & 0x00FFU) + | ((data[addr + 1] << 8) & 0xFF00U); } - else if (isBigEndian()) + else if (parent.isBigEndian()) { - val = ((s_openStream[addr + 0] << 8) & 0xFF00U) - | ( s_openStream[addr + 1] & 0x00FFU); + val = ((data[addr + 0] << 8) & 0xFF00U) + | ( data[addr + 1] & 0x00FFU); } else return { 0, true }; - s_addr += tTypeSize::INT16; + addr += tTypeSize::INT16; return { val, false }; } - Serial::ReadResult Serial::read::uint16(u64 addr) + Serial::ReadResult Serial::Reader::uint16(u64 _addr) { - auto res = int16(addr); + auto res = int16(_addr); return { cast(res.value), res.error }; } - Serial::ReadResult Serial::read::int32(u64 addr) + Serial::ReadResult Serial::Reader::int32(u64 _addr) { - if (!isStreamAttached()) return { 0, true }; - managed_address_check(addr); + if (isInvalid()) return { 0, true }; + u64& addr = resolve_address(_addr); if (!isValidAddress(addr, tTypeSize::INT32)) return { 0, true }; i32 val = 0; if (isLittleEndian()) { - val = ((s_openStream[addr + 0] ) & 0x000000FF) - | ((s_openStream[addr + 1] << 8) & 0x0000FF00) - | ((s_openStream[addr + 2] << 16) & 0x00FF0000) - | ((s_openStream[addr + 3] << 24) & 0xFF000000); + val = ((data[addr + 0] ) & 0x000000FF) + | ((data[addr + 1] << 8) & 0x0000FF00) + | ((data[addr + 2] << 16) & 0x00FF0000) + | ((data[addr + 3] << 24) & 0xFF000000); } else if (isBigEndian()) { - val = ((s_openStream[addr + 0] << 24) & 0xFF000000U) - | ((s_openStream[addr + 1] << 16) & 0x00FF0000U) - | ((s_openStream[addr + 2] << 8) & 0x0000FF00U) - | ( s_openStream[addr + 3] & 0x000000FFU); + val = ((data[addr + 0] << 24) & 0xFF000000U) + | ((data[addr + 1] << 16) & 0x00FF0000U) + | ((data[addr + 2] << 8) & 0x0000FF00U) + | ( data[addr + 3] & 0x000000FFU); } else return { 0, true }; - s_addr += tTypeSize::INT32; + addr += tTypeSize::INT32; return { val, false }; } - Serial::ReadResult Serial::read::uint32(u64 addr) + Serial::ReadResult Serial::Reader::uint32(u64 _addr) { - auto res = int32(addr); + auto res = int32(_addr); return { cast(res.value), res.error }; } - Serial::ReadResult Serial::read::int64(u64 addr) + Serial::ReadResult Serial::Reader::int64(u64 _addr) { - if (!isStreamAttached()) return { 0, true }; - managed_address_check(addr); + if (isInvalid()) return { 0, true }; + u64& addr = resolve_address(_addr); if (!isValidAddress(addr, tTypeSize::INT64)) return { 0, true }; i64 val = 0; if (isLittleEndian()) { - val = ( s_openStream[addr + 7] & 0x00000000000000FFU) - | (( s_openStream[addr + 6] << 8) & 0x000000000000FF00U) - | (( s_openStream[addr + 5] << 16) & 0x0000000000FF0000U) - | (( s_openStream[addr + 4] << 24) & 0x00000000FF000000U) - | (((i64)s_openStream[addr + 3] << 32) & 0x000000FF00000000U) - | (((i64)s_openStream[addr + 2] << 40) & 0x0000FF0000000000U) - | (((i64)s_openStream[addr + 1] << 48) & 0x00FF000000000000U) - | (((i64)s_openStream[addr + 0] << 56) & 0xFF00000000000000U); + val = ( data[addr + 7] & 0x00000000000000FFU) + | (( data[addr + 6] << 8) & 0x000000000000FF00U) + | (( data[addr + 5] << 16) & 0x0000000000FF0000U) + | (( data[addr + 4] << 24) & 0x00000000FF000000U) + | (((i64)data[addr + 3] << 32) & 0x000000FF00000000U) + | (((i64)data[addr + 2] << 40) & 0x0000FF0000000000U) + | (((i64)data[addr + 1] << 48) & 0x00FF000000000000U) + | (((i64)data[addr + 0] << 56) & 0xFF00000000000000U); } else if (isBigEndian()) { - val = (((i64)s_openStream[addr + 0] << 56) & 0xFF00000000000000U) - | (((i64)s_openStream[addr + 1] << 48) & 0x00FF000000000000U) - | (((i64)s_openStream[addr + 2] << 40) & 0x0000FF0000000000U) - | (((i64)s_openStream[addr + 3] << 32) & 0x000000FF00000000U) - | (( s_openStream[addr + 4] << 24) & 0x00000000FF000000U) - | (( s_openStream[addr + 5] << 16) & 0x0000000000FF0000U) - | (( s_openStream[addr + 6] << 8) & 0x000000000000FF00U) - | ( s_openStream[addr + 7] & 0x00000000000000FFU); + val = (((i64)data[addr + 0] << 56) & 0xFF00000000000000U) + | (((i64)data[addr + 1] << 48) & 0x00FF000000000000U) + | (((i64)data[addr + 2] << 40) & 0x0000FF0000000000U) + | (((i64)data[addr + 3] << 32) & 0x000000FF00000000U) + | (( data[addr + 4] << 24) & 0x00000000FF000000U) + | (( data[addr + 5] << 16) & 0x0000000000FF0000U) + | (( data[addr + 6] << 8) & 0x000000000000FF00U) + | ( data[addr + 7] & 0x00000000000000FFU); } else return { 0, true }; - s_addr += tTypeSize::INT64; + addr += tTypeSize::INT64; return { val, false }; } - Serial::ReadResult Serial::read::uint64(u64 addr) + Serial::ReadResult Serial::Reader::uint64(u64 _addr) { - auto res = int64(addr); + auto res = int64(_addr); return { cast(res.value), res.error }; } - Serial::ReadResult Serial::read::float32(u64 addr) + Serial::ReadResult Serial::Reader::float32(u64 _addr) { - if (!isStreamAttached()) return { 0, true }; - managed_address_check(addr); + if (isInvalid()) return { 0, true }; + u64& addr = resolve_address(_addr); if (!isValidAddress(addr, tTypeSize::FLOAT32)) return { 0, true }; __float_parser fp; if (isLittleEndian()) { - fp.data[3] = s_openStream[addr + 0]; - fp.data[2] = s_openStream[addr + 1]; - fp.data[1] = s_openStream[addr + 2]; - fp.data[0] = s_openStream[addr + 3]; + fp.data[3] = data[addr + 0]; + fp.data[2] = data[addr + 1]; + fp.data[1] = data[addr + 2]; + fp.data[0] = data[addr + 3]; } else if (isBigEndian()) { - fp.data[0] = s_openStream[addr + 0]; - fp.data[1] = s_openStream[addr + 1]; - fp.data[2] = s_openStream[addr + 2]; - fp.data[3] = s_openStream[addr + 3]; + fp.data[0] = data[addr + 0]; + fp.data[1] = data[addr + 1]; + fp.data[2] = data[addr + 2]; + fp.data[3] = data[addr + 3]; } else return { 0, true }; - s_addr += tTypeSize::FLOAT32; + addr += tTypeSize::FLOAT32; return { fp.val, false }; } - Serial::ReadResult Serial::read::float64(u64 addr) + Serial::ReadResult Serial::Reader::float64(u64 _addr) { - if (!isStreamAttached()) return { 0, true }; - managed_address_check(addr); + if (isInvalid()) return { 0, true }; + u64& addr = resolve_address(_addr); if (!isValidAddress(addr, tTypeSize::FLOAT64)) return { 0, true }; __double_parser dp; if (isLittleEndian()) { - dp.data[7] = s_openStream[addr++]; - dp.data[6] = s_openStream[addr++]; - dp.data[5] = s_openStream[addr++]; - dp.data[4] = s_openStream[addr++]; - dp.data[3] = s_openStream[addr++]; - dp.data[2] = s_openStream[addr++]; - dp.data[1] = s_openStream[addr++]; - dp.data[0] = s_openStream[addr ]; + dp.data[7] = data[addr++]; + dp.data[6] = data[addr++]; + dp.data[5] = data[addr++]; + dp.data[4] = data[addr++]; + dp.data[3] = data[addr++]; + dp.data[2] = data[addr++]; + dp.data[1] = data[addr++]; + dp.data[0] = data[addr ]; } else if (isBigEndian()) { - dp.data[0] = s_openStream[addr++]; - dp.data[1] = s_openStream[addr++]; - dp.data[2] = s_openStream[addr++]; - dp.data[3] = s_openStream[addr++]; - dp.data[4] = s_openStream[addr++]; - dp.data[5] = s_openStream[addr++]; - dp.data[6] = s_openStream[addr++]; - dp.data[7] = s_openStream[addr ]; + dp.data[0] = data[addr++]; + dp.data[1] = data[addr++]; + dp.data[2] = data[addr++]; + dp.data[3] = data[addr++]; + dp.data[4] = data[addr++]; + dp.data[5] = data[addr++]; + dp.data[6] = data[addr++]; + dp.data[7] = data[addr ]; } else return { 0, true }; - s_addr += tTypeSize::FLOAT64; + addr += tTypeSize::FLOAT64; return { dp.val, false }; } - bool Serial::read::stream(Stream& outStream, u64 addr, bool sizeStored, u32 size_if_not_stored) + bool Serial::Reader::stream(u64 _addr, Stream& outStream, bool sizeStored, u32 size_if_not_stored) { - if (!isStreamAttached()) return false; - managed_address_check(addr); + if (isInvalid()) return false; + u64& addr = resolve_address(_addr); if (!sizeStored && size_if_not_stored < 1) return false; u32 size = size_if_not_stored; if (sizeStored) @@ -207,18 +227,18 @@ namespace ostd else return false; } if (!isValidAddress(addr, size)) return false; - Serial::Stream data = { size, endianness }; - StreamEdit edit = data.data(); - std::copy_n(s_openStream.begin() + addr, size, edit.begin()); - outStream = std::move(data); - s_addr = addr + size; + Serial::Stream _data = { size, endianness }; + StreamEdit edit = _data.data(); + std::copy_n(data.begin() + addr, size, edit.begin()); + outStream = std::move(_data); + addr += size; return true; } - bool Serial::read::string(String& outString, u64 addr, bool sizeStored, u32 size_if_not_stored, bool null_terminated) + bool Serial::Reader::string(u64 _addr, String& outString, bool sizeStored, u32 size_if_not_stored, bool null_terminated) { - if (!isStreamAttached()) return false; - managed_address_check(addr); + if (isInvalid()) return false; + u64& addr = resolve_address(_addr); if (!null_terminated || sizeStored) // I want null_terminated to have the lowest priority { if (!sizeStored && size_if_not_stored < 1) return false; @@ -233,9 +253,9 @@ namespace ostd if (!isValidAddress(addr, size)) return false; for (u64 i = addr; i < (addr + size); i++) { - outString += cast(s_openStream[i]); + outString += cast(data[i]); } - s_addr = addr + size; + addr += size; return true; } else @@ -252,12 +272,11 @@ namespace ostd addr += tTypeSize::INT8; } outString = out; - s_addr = addr; return true; } } - bool Serial::read::object(__i_serializable& outObject, u64 addr) + bool Serial::Reader::object(I_serializable& outObject, u64 addr) { Serial::Stream objData(0); if (!stream(objData, addr, true, 0)) @@ -267,7 +286,7 @@ namespace ostd - bool Serial::write::int8(u64 addr, i8 value) + bool Serial::Writer::int8(u64 addr, i8 value) { if (!isStreamAttached()) return false; managed_address_check(addr); @@ -277,12 +296,12 @@ namespace ostd return true; } - bool Serial::write::uint8(u64 addr, u8 value) + bool Serial::Writer::uint8(u64 addr, u8 value) { return int8(addr, cast(value)); } - bool Serial::write::int16(u64 addr, i16 value) + bool Serial::Writer::int16(u64 addr, i16 value) { if (!isStreamAttached()) return false; managed_address_check(addr); @@ -302,12 +321,12 @@ namespace ostd return true; } - bool Serial::write::uint16(u64 addr, u16 value) + bool Serial::Writer::uint16(u64 addr, u16 value) { return int16(addr, cast(value)); } - bool Serial::write::int32(u64 addr, i32 value) + bool Serial::Writer::int32(u64 addr, i32 value) { if (!isStreamAttached()) return false; managed_address_check(addr); @@ -331,12 +350,12 @@ namespace ostd return true; } - bool Serial::write::uint32(u64 addr, u32 value) + bool Serial::Writer::uint32(u64 addr, u32 value) { return int32(addr, cast(value)); } - bool Serial::write::int64(u64 addr, i64 value) + bool Serial::Writer::int64(u64 addr, i64 value) { if (!isStreamAttached()) return false; managed_address_check(addr); @@ -368,14 +387,12 @@ namespace ostd return true; } - bool Serial::write::uint64(u64 addr, u64 value) + bool Serial::Writer::uint64(u64 addr, u64 value) { - if (!isStreamAttached()) return false; - if (!isValidAddress(addr, tTypeSize::UINT64)) return false; return int64(addr, cast(value)); } - bool Serial::write::float32(u64 addr, f32 value) + bool Serial::Writer::float32(u64 addr, f32 value) { if (!isStreamAttached()) return false; managed_address_check(addr); @@ -401,7 +418,7 @@ namespace ostd return true; } - bool Serial::write::float64(u64 addr, f64 value) + bool Serial::Writer::float64(u64 addr, f64 value) { if (!isStreamAttached()) return false; managed_address_check(addr); @@ -435,7 +452,7 @@ namespace ostd return true; } - bool Serial::write::stream(u64 addr, const Stream& value, bool storeSize) + bool Serial::Writer::stream(u64 addr, const Stream& value, bool storeSize) { if (!isStreamAttached()) return false; managed_address_check(addr); @@ -454,7 +471,7 @@ namespace ostd return true; } - bool Serial::write::string(u64 addr, const String& value, bool storeSize, bool null_terminated) + bool Serial::Writer::string(u64 addr, const String& value, bool storeSize, bool null_terminated) { if (!isStreamAttached()) return false; managed_address_check(addr); @@ -480,7 +497,7 @@ namespace ostd return true; } - bool Serial::write::object(u64 addr, const __i_serializable& value) + bool Serial::Writer::object(u64 addr, const I_serializable& value) { if (!isStreamAttached()) return false; const Serial::Stream data = value.serialize(); diff --git a/src/ostd/io/Serial.hpp b/src/ostd/io/Serial.hpp index 0348ba5..2b37a98 100755 --- a/src/ostd/io/Serial.hpp +++ b/src/ostd/io/Serial.hpp @@ -25,7 +25,7 @@ namespace ostd { - class __i_serializable; + class I_serializable; class Serial { public: template struct ReadResult { T value; bool error { false }; }; @@ -37,26 +37,13 @@ namespace ostd public: Stream(const Stream&) = delete; Stream& operator=(const Stream&) = delete; + inline Stream(void) { } // Uninitialized Stream inline Stream(u64 size, Endianness endianness = Endianness::LittleEndian, bool preInitialize = false, i8 initialValue = 0) { - if (size < 1) return; - if constexpr (sizeof(size_t) < sizeof(uint64_t)) - { - if (size > std::numeric_limits::max()) - throw "Serial::Stream size can't excede UINT32_MAX on a 32bit system."; - } - m_data = new i8[size]; - m_size = size; - m_endianness = endianness; - if (preInitialize) - { - for (u64 i = 0; i < size; i++) - m_data[i] = initialValue; - } + construct(size, endianness, preInitialize, initialValue); } - inline Stream(Stream&& other) noexcept : m_data(other.m_data), m_size(other.m_size) { + inline Stream(Stream&& other) noexcept : m_data(other.m_data), m_size(other.m_size), m_endianness(other.m_endianness) { other.m_data = nullptr; other.m_size = 0; - m_endianness = other.m_endianness; } inline Stream& operator=(Stream&& other) noexcept { if (this != &other) { @@ -73,11 +60,30 @@ namespace ostd delete[] m_data; m_data = nullptr; } + inline bool construct(u64 size, Endianness endianness = Endianness::LittleEndian, bool preInitialize = false, i8 initialValue = 0) { + if (isValid()) return false; + if (size < 1) return false; + if constexpr (sizeof(size_t) < sizeof(uint64_t)) + { + if (size > std::numeric_limits::max()) + throw std::runtime_error("Serial::Stream size can't excede UINT32_MAX on a 32bit system."); + } + m_data = new i8[size]; + m_size = size; + m_endianness = endianness; + if (preInitialize) + { + for (u64 i = 0; i < size; i++) + m_data[i] = initialValue; + } + return true; + } inline bool isValid(void) const { return m_size > 0 && m_data != nullptr; } inline u64 size(void) const { return isValid() ? m_size : 0; } inline bool isLittleEndian(void) const { return m_endianness == Endianness::LittleEndian; } inline bool isBigEndian(void) const { return m_endianness == Endianness::BigEndian; } inline Endianness getEndianness(void) const { return m_endianness; } + inline void setEndianness(Endianness endianness) { m_endianness = endianness; } inline StreamEdit data() { if (isValid()) return { m_data, cast(m_size) }; @@ -94,104 +100,131 @@ namespace ostd u64 m_size { 0 }; Endianness m_endianness { Endianness::LittleEndian }; }; + private: struct Reader + { + inline Reader(Serial& _parent) : parent(_parent) { data = parent.m_data.data(); } + + ReadResult int8(u64 addr); + inline ReadResult int8(void) { return int8(0); } + ReadResult uint8(u64 addr); + inline ReadResult uint8(void) { return uint8(0); } + + ReadResult int16(u64 addr); + inline ReadResult int16(void) { return int16(0); } + ReadResult uint16(u64 addr); + inline ReadResult uint16(void) { return uint16(0); } + + ReadResult int32(u64 addr); + inline ReadResult int32(void) { return int32(0); } + ReadResult uint32(u64 addr); + inline ReadResult uint32(void) { return uint32(0); } + + ReadResult int64(u64 addr); + inline ReadResult int64(void) { return int64(0); } + ReadResult uint64(u64 addr); + inline ReadResult uint64(void) { return uint64(0); } + + ReadResult float32(u64 addr); + inline ReadResult float32(void) { return float32(0); } + ReadResult float64(u64 addr); + inline ReadResult float64(void) { return float64(0); } + + bool stream(u64 addr, Stream& outStream, bool sizeStored = true, u32 size_if_not_stored = 0); + inline bool stream(Stream& outStream, bool sizeStored = true, u32 size_if_not_stored = 0) { return stream(0, outStream, sizeStored, size_if_not_stored); } + bool string(u64 addr, String& outString, bool sizeStored = true, u32 size_if_not_stored = 0, bool null_terminated = false); + inline bool string(String& outString, bool sizeStored = true, u32 size_if_not_stored = 0, bool null_terminated = false) { return string(0, outString, sizeStored, size_if_not_stored, null_terminated); } + bool object(u64 addr, I_serializable& outObject); + inline bool object(I_serializable& outObject) { return object(0, outObject); } + + private: // Convenience wrappers + inline bool isValid(void) const { return parent.isValid(); } + inline bool isInvalid(void) const { return parent.isInvalid(); } + inline bool isLittleEndian(void) const { return parent.isLittleEndian(); } + inline bool isBigEndian(void) const { return parent.isBigEndian(); } + inline u64& resolve_address(u64& addr) { return parent.resolve_address(addr); } + inline bool isValidAddress(u64 addr, u32 size = 1) const { return parent.isValidAddress(addr); } + + private: + Serial& parent; + StreamView data; + }; + private: struct Writer + { + inline Writer(Serial& _parent) : parent(_parent) { data = parent.m_data.data(); } + + bool int8(u64 addr, i8 value); + inline bool int8(i8 value) { return int8(0, value); } + bool uint8(u64 addr, u8 value); + inline bool uint8(u8 value) { return uint8(0, value); } + + bool int16(u64 addr, i16 value); + inline bool int16(i16 value) { return int16(0, value); } + bool uint16(u64 addr, u16 value); + inline bool uint16(u16 value) { return uint16(0, value); } + + bool int32(u64 addr, i32 value); + inline bool int32(i32 value) { return int32(0, value); } + bool uint32(u64 addr, u32 value); + inline bool uint32(u32 value) { return uint32(0, value); } + + bool int64(u64 addr, i64 value); + inline bool int64(i64 value) { return int64(0, value); } + bool uint64(u64 addr, u64 value); + inline bool uint64(u64 value) { return uint64(0, value); } + + bool float32(u64 addr, f32 value); + inline bool float32(f32 value) { return float32(0, value); } + bool float64(u64 addr, f64 value); + inline bool float64(f64 value) { return float64(0, value); } + + bool stream(u64 addr, const Stream& value, bool storeSize = true); + inline bool stream(const Stream& value, bool storeSize = true) { return stream(0, value, storeSize); } + bool string(u64 addr, const String& value, bool storeSize = true, bool null_terminated = false); // if sizeStored, null_terminated will be ignored + inline bool string(const String& value, bool storeSize = true, bool null_terminated = false) { return string(0, value, storeSize, null_terminated); } + bool object(u64 addr, const I_serializable& value); + inline bool object(const I_serializable& value) { return object(0, value); } + + private: // Convenience wrappers + inline bool isValid(void) const { return parent.isValid(); } + inline bool isInvalid(void) const { return parent.isInvalid(); } + inline bool isLittleEndian(void) const { return parent.isLittleEndian(); } + inline bool isBigEndian(void) const { return parent.isBigEndian(); } + inline u64& resolve_address(u64& addr) { return parent.resolve_address(addr); } + inline bool isValidAddress(u64 addr, u32 size = 1) const { return parent.isValidAddress(addr); } + + private: + Serial& parent; + StreamEdit data; + }; public: - inline static void attachStream(Stream& stream) { s_openStream = stream.data(); s_endianness = stream.getEndianness(); disableManagedAddress(); } - inline static void detachStrean(void) { s_openStream = {}; } - inline static bool setManagedAddress(u64 addr) { if (!isManagedAddressEnabled() || !isValidAddress(addr)) return false; s_addr = addr; return true; } - inline static bool isManagedAddressEnabled(void) { return s_managedAddress; } - inline static void enableManagedAddress(bool enable = true) { s_managedAddress = enable; s_addr = 0; } - inline static void disableManagedAddress(void) { enableManagedAddress(false); } - inline static bool isStreamAttached(void) { return !s_openStream.empty(); } - inline static bool isLittleEndian(void) { return s_endianness == Endianness::LittleEndian; } - inline static bool isBigEndian(void) { return s_endianness == Endianness::BigEndian; } - static bool isValidAddress(u64 addr, u32 size = 1); + inline Serial(void) : read(*this), write(*this) { } + inline Serial(u64 size, Endianness endianness = Endianness::LittleEndian, bool preInitialize = false, i8 initialValue = 0) : read(*this), write(*this) { construct(size, endianness, preInitialize, initialValue); } + bool construct(u64 size, Endianness endianness = Endianness::LittleEndian, bool preInitialize = false, i8 initialValue = 0); + bool resetAddress(u64 newAddr); + bool isValidAddress(u64 addr, u32 size = 1) const; - public: struct read - { - ReadResult int8(u64 addr = 0); - inline i8 int8d(u64 addr = 0, bool* outError = nullptr) { auto val = int8(addr); if (outError) *outError = val.error; return val.value; } - ReadResult uint8(u64 addr = 0); - inline u8 uint8d(u64 addr = 0, bool* outError = nullptr) { auto val = uint8(addr); if (outError) *outError = val.error; return val.value; } - - ReadResult int16(u64 addr = 0); - inline i16 int16d(u64 addr = 0, bool* outError = nullptr) { auto val = int16(addr); if (outError) *outError = val.error; return val.value; } - ReadResult uint16(u64 addr = 0); - inline u16 uint16d(u64 addr = 0, bool* outError = nullptr) { auto val = uint16(addr); if (outError) *outError = val.error; return val.value; } - - ReadResult int32(u64 addr = 0); - inline i32 int32d(u64 addr = 0, bool* outError = nullptr) { auto val = int32(addr); if (outError) *outError = val.error; return val.value; } - ReadResult uint32(u64 addr = 0); - inline u32 uint32d(u64 addr = 0, bool* outError = nullptr) { auto val = uint32(addr); if (outError) *outError = val.error; return val.value; } - - ReadResult int64(u64 addr = 0); - inline i64 int64d(u64 addr = 0, bool* outError = nullptr) { auto val = int64(addr); if (outError) *outError = val.error; return val.value; } - ReadResult uint64(u64 addr = 0); - inline u64 uint64d(u64 addr = 0, bool* outError = nullptr) { auto val = uint64(addr); if (outError) *outError = val.error; return val.value; } - - ReadResult float32(u64 addr = 0); - inline f32 float32d(u64 addr = 0, bool* outError = nullptr) { auto val = float32(addr); if (outError) *outError = val.error; return val.value; } - ReadResult float64(u64 addr = 0); - inline f64 float64d(u64 addr = 0, bool* outError = nullptr) { auto val = float64(addr); if (outError) *outError = val.error; return val.value; } - - bool stream(Stream& outStream, u64 addr = 0, bool sizeStored = true, u32 size_if_not_stored = 0); - bool string(String& outString, u64 addr = 0, bool sizeStored = true, u32 size_if_not_stored = 0, bool null_terminated = false); - bool object(__i_serializable& outObject, u64 addr = 0); - - private: - read(void) = default; - }; - - public: struct write - { - bool int8(u64 addr, i8 value); - inline bool int8(i8 value) { return int8(0, value); } - bool uint8(u64 addr, u8 value); - inline bool uint8(i8 value) { return uint8(0, value); } - - bool int16(u64 addr, i16 value); - inline bool int16(i8 value) { return int16(0, value); } - bool uint16(u64 addr, u16 value); - inline bool uint16(i8 value) { return uint16(0, value); } - - bool int32(u64 addr, i32 value); - inline bool int32(i8 value) { return int32(0, value); } - bool uint32(u64 addr, u32 value); - inline bool uint32(i8 value) { return uint32(0, value); } - - bool int64(u64 addr, i64 value); - inline bool int64(i8 value) { return int64(0, value); } - bool uint64(u64 addr, u64 value); - inline bool uint64(i8 value) { return uint64(0, value); } - - bool float32(u64 addr, f32 value); - inline bool float32(i8 value) { return float32(0, value); } - bool float64(u64 addr, f64 value); - inline bool float64(i8 value) { return float64(0, value); } - - bool stream(u64 addr, const Stream& value, bool storeSize = true); - inline bool stream(const Stream& value, bool storeSize = true) { return stream(0, value, storeSize); } - bool string(u64 addr, const String& value, bool storeSize = true, bool null_terminated = false); // if sizeStored, null_terminated will be ignored - inline bool string(const String& value, bool storeSize = true, bool null_terminated = false) { return string(0, value, storeSize, null_terminated); } - bool object(u64 addr, const __i_serializable& value); - inline bool object(const __i_serializable& value) { return object(0, value); } - - private: - write(void) = default; - }; + inline bool isValid(void) const { return m_data.isValid(); } + inline bool isInvalid(void) const { return !isValid(); } + inline bool isLittleEndian(void) const { return m_data.isLittleEndian(); } + inline bool isBigEndian(void) const { return m_data.isBigEndian(); } + inline Endianness getEndianness(void) const { return m_data.getEndianness(); } private: - Serial(void) = default; - inline static void managed_address_check(u64& addr) { if (isManagedAddressEnabled()) addr = s_addr; } + inline u64& resolve_address(u64& addr) { if (addr == 0) return m_address; return addr; } + inline bool restore_address(void) { resetAddress(m_backupAddress); return false; } // Always returns false so it can be used as false on error in return statements private: - inline static StreamEdit s_openStream { }; - inline static Endianness s_endianness { Endianness::LittleEndian }; + Stream m_data; + u64 m_address { 0 }; + u64 m_backupAddress { 0 }; + bool m_backupStored { false }; - inline static u64 s_addr { 0 }; - inline static bool s_managedAddress { false }; + public: + Writer write; + Reader read; }; - class __i_serializable + class I_serializable { public: virtual Serial::Stream serialize(void) const = 0; diff --git a/src/ostd/math/Geometry.hpp b/src/ostd/math/Geometry.hpp index af0b37b..b4d5e8d 100755 --- a/src/ostd/math/Geometry.hpp +++ b/src/ostd/math/Geometry.hpp @@ -44,7 +44,7 @@ namespace ostd { - struct Vec2 : public __i_stringeable + struct Vec2 : public I_stringeable { //======================== Data ======================== f32 x { 0.0f }; @@ -139,7 +139,7 @@ namespace ostd }; template - class Point : public __i_stringeable + class Point : public I_stringeable { public: T x; @@ -194,7 +194,7 @@ namespace ostd typedef Point I16Point; typedef Point I8Point; - struct Vec3 : public __i_stringeable + struct Vec3 : public I_stringeable { inline Vec3(f32 xx = 0, f32 yy = 0, f32 zz = 0) { @@ -216,7 +216,7 @@ namespace ostd f32 z; }; - struct Vec4 : public __i_stringeable + struct Vec4 : public I_stringeable { inline Vec4(f32 xx = 0, f32 yy = 0, f32 zz = 0, f32 ww = 0) { @@ -240,7 +240,7 @@ namespace ostd f32 w; }; - struct Triangle : public __i_stringeable + struct Triangle : public I_stringeable { Vec2 vA; Vec2 vB; @@ -284,7 +284,7 @@ namespace ostd } }; - class Rectangle : public __i_stringeable + class Rectangle : public I_stringeable { public: inline Rectangle(void) : x(0), y(0), w(0), h(0) {} @@ -431,7 +431,7 @@ namespace ostd }; template - class Rect : public __i_stringeable + class Rect : public I_stringeable { public: Rect(void) = default; @@ -457,7 +457,7 @@ namespace ostd typedef Rect I8Rect; template - class Line : public __i_stringeable + class Line : public I_stringeable { public: Line(void) = default; diff --git a/src/ostd/string/String.hpp b/src/ostd/string/String.hpp index 92f60ef..95fc03b 100644 --- a/src/ostd/string/String.hpp +++ b/src/ostd/string/String.hpp @@ -210,15 +210,15 @@ namespace ostd ostd::cpp_string m_data; }; - struct __i_stringeable + struct I_stringeable { virtual String toString(void) const = 0; - friend std::ostream& operator<<(std::ostream& out, const __i_stringeable& val); + friend std::ostream& operator<<(std::ostream& out, const I_stringeable& val); inline operator String() const { return toString(); } inline operator std::string() const { return toString(); } }; - inline std::ostream& operator<<(std::ostream& out, const __i_stringeable& val) + inline std::ostream& operator<<(std::ostream& out, const I_stringeable& val) { out << val.toString(); return out;