| From 8a6173c18ad43fa62433e6f67acc541f70336c1b Mon Sep 17 00:00:00 2001 |
| From: Pierre Wielders <pierre@wielders.net> |
| Date: Mon, 21 Jun 2021 14:01:00 +0200 |
| Subject: [PATCH] Increase buffer size of COMRPC messages |
| |
| Cherry-picked from R4 |
| |
| - c1a553eb45bf278b5fb72809bccd0663dabfe8dd |
| |
| [WARNINGS] Warnings from the windows build resolved. (#623) |
| |
| These warnings include uninitialized variables during construction. |
| Potential leaks (and than a crash, due to nullptr access) if the realloc would *not* allocate a new buffer that is big enough.. |
| |
| - 119af9fd2d23ecd61a752c139d201923bbd368b7 |
| [FRAME] Extend the functionality of the Frame template. (#840) |
| |
| * [FRAME] Extend the functionality of the Frame template. |
| Sometimes the ordering in a binary serialzed frame is LSB, sometimes it is MSB. Allow the template to |
| cope with both situations, the default is MSB as that was as it was used sofar. |
| Also sometimes we only need to work with very small frames <255 bytes. using the the uint16_t for maintaining |
| location and size is a bit of overkill. Maybe in the future we would like to enlarge the 64Kb boundary to |
| 4Gb, and the variables than need to be uint32_t :-) |
| Make the variable sizes for creating the buffers a template parameter, again making the default equal to |
| what it was. |
| |
| * [FRAME] Update after review. |
| |
| [WINDOWS] Make new Time compile with less warnings on Windows. |
| |
| Co-authored-by: MFransen69 <39826971+MFransen69@users.noreply.github.com> |
| |
| - 3246752780ea56c98d930e18ebf15ecd55a73e54 |
| |
| [COMRPC] Enlarge the buffer in which we hold the COMRPC message to 32 bits. Now it can grow beyond the 64Kb. (#1116) |
| --- |
| Source/com/Messages.h | 76 ++++----- |
| Source/core/Frame.h | 375 +++++++++++++++++++++++++----------------- |
| 2 files changed, 251 insertions(+), 200 deletions(-) |
| |
| diff --git a/Source/com/Messages.h b/Source/com/Messages.h |
| index 4dacd3fc..4fd79646 100644 |
| --- a/Source/com/Messages.h |
| +++ b/Source/com/Messages.h |
| @@ -17,8 +17,7 @@ |
| * limitations under the License. |
| */ |
| |
| -#ifndef __COM_MESSAGES_H |
| -#define __COM_MESSAGES_H |
| +#pragma once |
| |
| #include "Module.h" |
| |
| @@ -40,25 +39,24 @@ namespace RPC { |
| namespace Data { |
| static const uint16_t IPC_BLOCK_SIZE = 512; |
| |
| - class Frame : public Core::FrameType<IPC_BLOCK_SIZE> { |
| + class Frame : public Core::FrameType<IPC_BLOCK_SIZE, true, uint32_t> { |
| private: |
| + using BaseClass = Core::FrameType < IPC_BLOCK_SIZE, true, uint32_t>; |
| + |
| + public: |
| Frame(Frame&) = delete; |
| Frame& operator=(const Frame&) = delete; |
| |
| - public: |
| - Frame() |
| - { |
| - } |
| - ~Frame() |
| - { |
| + Frame() : BaseClass() { |
| } |
| + ~Frame() = default; |
| |
| public: |
| friend class Input; |
| friend class Output; |
| friend class ObjectInterface; |
| |
| - uint16_t Serialize(const uint16_t offset, uint8_t stream[], const uint16_t maxLength) const |
| + uint16_t Serialize(const uint32_t offset, uint8_t stream[], const uint16_t maxLength) const |
| { |
| uint16_t copiedBytes((Size() - offset) > maxLength ? maxLength : (Size() - offset)); |
| |
| @@ -66,7 +64,7 @@ namespace RPC { |
| |
| return (copiedBytes); |
| } |
| - uint16_t Deserialize(const uint16_t offset, const uint8_t stream[], const uint16_t maxLength) |
| + uint16_t Deserialize(const uint32_t offset, const uint8_t stream[], const uint16_t maxLength) |
| { |
| Size(offset + maxLength); |
| |
| @@ -77,18 +75,13 @@ namespace RPC { |
| }; |
| |
| class Input { |
| - private: |
| + public: |
| Input(const Input&) = delete; |
| Input& operator=(const Input&) = delete; |
| |
| - public: |
| - Input() |
| - : _data() |
| - { |
| - } |
| - ~Input() |
| - { |
| + Input() : _data() { |
| } |
| + ~Input() = default; |
| |
| public: |
| inline void Clear() |
| @@ -139,11 +132,11 @@ namespace RPC { |
| } |
| uint16_t Serialize(uint8_t stream[], const uint16_t maxLength, const uint32_t offset) const |
| { |
| - return (_data.Serialize(static_cast<uint16_t>(offset), stream, maxLength)); |
| + return (_data.Serialize(offset, stream, maxLength)); |
| } |
| uint16_t Deserialize(const uint8_t stream[], const uint16_t maxLength, const uint32_t offset) |
| { |
| - return (_data.Deserialize(static_cast<uint16_t>(offset), stream, maxLength)); |
| + return (_data.Deserialize(offset, stream, maxLength)); |
| } |
| |
| private: |
| @@ -151,18 +144,13 @@ namespace RPC { |
| }; |
| |
| class Output { |
| - private: |
| + public: |
| Output(const Output&) = delete; |
| Output& operator=(const Output&) = delete; |
| |
| - public: |
| - Output() |
| - : _data() |
| - { |
| - } |
| - ~Output() |
| - { |
| + Output() : _data() { |
| } |
| + ~Output() = default; |
| |
| public: |
| inline void Clear() |
| @@ -188,11 +176,11 @@ namespace RPC { |
| } |
| inline uint16_t Serialize(uint8_t stream[], const uint16_t maxLength, const uint32_t offset) const |
| { |
| - return (_data.Serialize(static_cast<uint16_t>(offset), stream, maxLength)); |
| + return (_data.Serialize(offset, stream, maxLength)); |
| } |
| inline uint16_t Deserialize(const uint8_t stream[], const uint16_t maxLength, const uint32_t offset) |
| { |
| - return (_data.Deserialize(static_cast<uint16_t>(offset), stream, maxLength)); |
| + return (_data.Deserialize(offset, stream, maxLength)); |
| } |
| |
| private: |
| @@ -201,8 +189,6 @@ namespace RPC { |
| |
| class Init { |
| private: |
| - Init(const Init&) = delete; |
| - Init& operator=(const Init&) = delete; |
| uint32_t ParentId() const |
| { |
| uint32_t exchangeId = 0; |
| @@ -223,6 +209,9 @@ namespace RPC { |
| }; |
| |
| public: |
| + Init(const Init&) = delete; |
| + Init& operator=(const Init&) = delete; |
| + |
| Init() |
| : _id(0) |
| , _implementation(0) |
| @@ -231,9 +220,7 @@ namespace RPC { |
| , _versionId(0) |
| { |
| } |
| - ~Init() |
| - { |
| - } |
| + ~Init() = default; |
| |
| public: |
| bool IsOffer() const |
| @@ -329,18 +316,13 @@ namespace RPC { |
| }; |
| |
| class Setup { |
| - private: |
| + public: |
| Setup(const Setup&) = delete; |
| Setup& operator=(const Setup&) = delete; |
| |
| - public: |
| - Setup() |
| - : _data() |
| - { |
| - } |
| - ~Setup() |
| - { |
| + Setup() : _data() { |
| } |
| + ~Setup() = default; |
| |
| public: |
| inline void Clear() |
| @@ -401,11 +383,11 @@ namespace RPC { |
| } |
| uint16_t Serialize(uint8_t stream[], const uint16_t maxLength, const uint32_t offset) const |
| { |
| - return (_data.Serialize(static_cast<uint16_t>(offset), stream, maxLength)); |
| + return (_data.Serialize(offset, stream, maxLength)); |
| } |
| uint16_t Deserialize(const uint8_t stream[], const uint16_t maxLength, const uint32_t offset) |
| { |
| - return (_data.Deserialize(static_cast<uint16_t>(offset), stream, maxLength)); |
| + return (_data.Deserialize(offset, stream, maxLength)); |
| } |
| |
| private: |
| @@ -417,5 +399,3 @@ namespace RPC { |
| typedef Core::IPCMessageType<2, Data::Input, Data::Output> InvokeMessage; |
| } |
| } |
| - |
| -#endif // __COM_MESSAGES_H |
| diff --git a/Source/core/Frame.h b/Source/core/Frame.h |
| index 9f945d00..087986c6 100644 |
| --- a/Source/core/Frame.h |
| +++ b/Source/core/Frame.h |
| @@ -17,39 +17,44 @@ |
| * limitations under the License. |
| */ |
| |
| -#ifndef __GENERICS_FRAME_H |
| -#define __GENERICS_FRAME_H |
| +#pragma once |
| |
| #include "Module.h" |
| |
| namespace WPEFramework { |
| namespace Core { |
| |
| - template <const uint16_t BLOCKSIZE> |
| + template <const uint32_t BLOCKSIZE, const bool BIG_ENDIAN_ORDERING = true, typename SIZE_CONTEXT = uint16_t> |
| class FrameType { |
| private: |
| - template <const uint16_t STARTSIZE> |
| + template <const uint32_t STARTSIZE, typename SIZETYPE> |
| class AllocatorType { |
| - private: |
| - AllocatorType<STARTSIZE> operator=(const AllocatorType<STARTSIZE>&) = delete; |
| - |
| public: |
| + AllocatorType<STARTSIZE, SIZETYPE> operator=(const AllocatorType<STARTSIZE, SIZETYPE>&) = delete; |
| + |
| AllocatorType() |
| : _bufferSize(STARTSIZE) |
| , _data(reinterpret_cast<uint8_t*>(::malloc(_bufferSize))) |
| { |
| + // It looks like there is a bug in the windows compiler. It prepares a default/copy constructor |
| + // if if the template being instantiated is not really utilizing it! |
| + #ifndef __WINDOWS__ |
| static_assert(STARTSIZE != 0, "This method can only be called if you specify an initial blocksize"); |
| + #endif |
| } |
| - AllocatorType(const AllocatorType<STARTSIZE>& copy) |
| + AllocatorType(const AllocatorType<STARTSIZE, SIZETYPE>& copy) |
| : _bufferSize(copy._bufferSize) |
| - , _data(STARTSIZE == 0 ? copy._data : reinterpret_cast<uint8_t*>(::malloc(_bufferSize))) |
| + , _data(reinterpret_cast<uint8_t*>(::malloc(_bufferSize))) |
| { |
| + // It looks like there is a bug in the windows compiler. It prepares a default/copy constructor |
| + // if if the template being instantiated is not really utilizing it! |
| + #ifndef __WINDOWS__ |
| + static_assert(STARTSIZE != 0, "This method can only be called if you specify an initial blocksize"); |
| + #endif |
| |
| - if (STARTSIZE != 0) { |
| - ::memcpy(_data, copy._data, _bufferSize); |
| - } |
| + ::memcpy(_data, copy._data, _bufferSize); |
| } |
| - AllocatorType(uint8_t buffer[], const uint32_t length) |
| + AllocatorType(uint8_t buffer[], const SIZETYPE length) |
| : _bufferSize(length) |
| , _data(buffer) |
| { |
| @@ -63,61 +68,62 @@ namespace Core { |
| } |
| |
| public: |
| - inline uint8_t& operator[](const uint16_t index) |
| + inline uint8_t& operator[](const SIZETYPE index) |
| { |
| ASSERT(_data != nullptr); |
| ASSERT(index < _bufferSize); |
| return (_data[index]); |
| } |
| - inline const uint8_t& operator[](const uint16_t index) const |
| + inline const uint8_t& operator[](const SIZETYPE index) const |
| { |
| ASSERT(_data != nullptr); |
| ASSERT(index < _bufferSize); |
| return (_data[index]); |
| } |
| - inline void Allocate(uint32_t requiredSize) |
| + inline void Allocate(SIZETYPE requiredSize) |
| { |
| RealAllocate<STARTSIZE>(requiredSize, TemplateIntToType<STARTSIZE>()); |
| } |
| |
| private: |
| - template <const uint16_t NONZEROSIZE> |
| - inline void RealAllocate(const uint32_t requiredSize, const TemplateIntToType<NONZEROSIZE>& /* For compile time diffrentiation */) |
| + template <const uint32_t NONZEROSIZE> |
| + inline void RealAllocate(const SIZETYPE requiredSize, const TemplateIntToType<NONZEROSIZE>& /* For compile time diffrentiation */) |
| { |
| if (requiredSize > _bufferSize) { |
| ASSERT(_data != nullptr); |
| |
| - _bufferSize = static_cast<uint16_t>(((requiredSize / (STARTSIZE ? STARTSIZE : 1)) + 1) * STARTSIZE); |
| + SIZETYPE bufferSize = static_cast<uint32_t>(((requiredSize / (STARTSIZE ? STARTSIZE : 1)) + 1) * STARTSIZE); |
| |
| // oops we need to "reallocate". |
| - _data = reinterpret_cast<uint8_t*>(::realloc(_data, _bufferSize)); |
| + uint8_t* data = reinterpret_cast<uint8_t*>(::realloc(_data, bufferSize)); |
| + |
| + if (data != nullptr) { |
| + _data = data; |
| + _bufferSize = bufferSize; |
| + } |
| } |
| } |
| - inline void RealAllocate(const uint32_t requiredSize, const TemplateIntToType<0>& /* For compile time diffrentiation */) |
| + inline void RealAllocate(const SIZETYPE requiredSize, const TemplateIntToType<0>& /* For compile time diffrentiation */) |
| { |
| ASSERT(requiredSize <= _bufferSize); |
| } |
| |
| private: |
| - uint16_t _bufferSize; |
| + SIZETYPE _bufferSize; |
| uint8_t* _data; |
| }; |
| |
| - private: |
| - FrameType& operator=(const FrameType&); |
| - |
| public: |
| class Reader { |
| - private: |
| - Reader& operator=(const Reader&); |
| - |
| public: |
| + Reader& operator=(const Reader&) = delete; |
| + |
| Reader() |
| : _offset(0) |
| , _container(nullptr) |
| { |
| } |
| - Reader(const FrameType& data, const uint16_t offset) |
| + Reader(const FrameType& data, const SIZE_CONTEXT offset) |
| : _offset(offset) |
| , _container(&data) |
| { |
| @@ -127,16 +133,14 @@ namespace Core { |
| , _container(copy._container) |
| { |
| } |
| - ~Reader() |
| - { |
| - } |
| + ~Reader() = default; |
| |
| public: |
| inline bool HasData() const |
| { |
| return ((_container != nullptr) && (_offset < _container->Size())); |
| } |
| - inline uint16_t Length() const |
| + inline uint32_t Length() const |
| { |
| return (_container == nullptr ? 0 : _container->Size() - _offset); |
| } |
| @@ -162,7 +166,7 @@ namespace Core { |
| template <typename TYPENAME> |
| TYPENAME Buffer(const TYPENAME maxLength, uint8_t buffer[]) const |
| { |
| - uint16_t result; |
| + uint32_t result; |
| |
| ASSERT(_container != nullptr); |
| |
| @@ -171,7 +175,7 @@ namespace Core { |
| |
| return (static_cast<TYPENAME>(result - sizeof(TYPENAME))); |
| } |
| - void Copy(const uint16_t length, uint8_t buffer[]) const |
| + void Copy(const SIZE_CONTEXT length, uint8_t buffer[]) const |
| { |
| ASSERT(_container != nullptr); |
| |
| @@ -218,6 +222,17 @@ namespace Core { |
| |
| return (result); |
| } |
| + const uint8_t* Data() const { |
| + |
| + ASSERT(_container != nullptr); |
| + |
| + return (&(_container->Data()[_offset])); |
| + } |
| + void Forward (const SIZE_CONTEXT skip) { |
| + ASSERT(skip <= Length()); |
| + _offset += skip; |
| + } |
| + |
| #ifdef __DEBUG__ |
| void Dump() const |
| { |
| @@ -226,21 +241,20 @@ namespace Core { |
| #endif |
| |
| private: |
| - mutable uint16_t _offset; |
| + mutable SIZE_CONTEXT _offset; |
| const FrameType* _container; |
| }; |
| class Writer { |
| - private: |
| - Writer& operator=(const Writer&); |
| - |
| public: |
| + Writer& operator=(const Writer&) = delete; |
| + |
| Writer() |
| : _offset(0) |
| , _container(nullptr) |
| { |
| } |
| // TODO: should we make offset 0 by default? |
| - Writer(FrameType& data, const uint16_t offset) |
| + Writer(FrameType& data, const uint32_t offset) |
| : _offset(offset) |
| , _container(&data) |
| { |
| @@ -250,12 +264,10 @@ namespace Core { |
| , _container(copy._container) |
| { |
| } |
| - ~Writer() |
| - { |
| - } |
| + ~Writer() = default; |
| |
| public: |
| - inline uint16_t Offset() const |
| + inline SIZE_CONTEXT Offset() const |
| { |
| return (_offset); |
| } |
| @@ -266,7 +278,7 @@ namespace Core { |
| |
| _offset += _container->SetBuffer<TYPENAME>(_offset, length, buffer); |
| } |
| - void Copy(const uint16_t length, const uint8_t buffer[]) |
| + void Copy(const SIZE_CONTEXT length, const uint8_t buffer[]) |
| { |
| ASSERT(_container != nullptr); |
| |
| @@ -299,30 +311,46 @@ namespace Core { |
| } |
| |
| private: |
| - uint16_t _offset; |
| + SIZE_CONTEXT _offset; |
| FrameType* _container; |
| }; |
| |
| - public: |
| + public: |
| FrameType() |
| : _size(0) |
| - , _data() |
| - { |
| + , _data() { |
| + // It looks like there is a bug in the windows compiler. It prepares a default/copy constructor |
| + // if if the template being instantiated is not really utilizing it! |
| + #ifndef __WINDOWS__ |
| static_assert(BLOCKSIZE != 0, "This method can only be called if you specify an initial blocksize"); |
| + #endif |
| } |
| - FrameType(const FrameType<BLOCKSIZE>& copy) |
| + FrameType(const FrameType<BLOCKSIZE, BIG_ENDIAN_ORDERING, SIZE_CONTEXT>& copy) |
| : _size(copy._size) |
| , _data(copy._data) |
| { |
| + // It looks like there is a bug in the windows compiler. It prepares a default/copy constructor |
| + // if if the template being instantiated is not really utilizing it! |
| + #ifndef __WINDOWS__ |
| + static_assert(BLOCKSIZE != 0, "This method can only be called if you allocate a new buffer"); |
| + #endif |
| } |
| - FrameType(uint8_t buffer[], const uint32_t length, const uint32_t loadedSize = 0) |
| + FrameType(uint8_t* buffer, const SIZE_CONTEXT length, const SIZE_CONTEXT loadedSize = 0) |
| : _size(loadedSize) |
| , _data(buffer, length) |
| { |
| static_assert(BLOCKSIZE == 0, "This method can only be called if you pass a buffer that can not be extended"); |
| } |
| - ~FrameType() |
| - { |
| + ~FrameType() = default; |
| + |
| + FrameType<BLOCKSIZE, BIG_ENDIAN_ORDERING, SIZE_CONTEXT>& operator=(const FrameType<BLOCKSIZE, BIG_ENDIAN_ORDERING, SIZE_CONTEXT>& rhs) { |
| + if (this != &rhs) { |
| + Size(rhs.Size()); |
| + if (Size() > 0) { |
| + ::memcpy(&(_data[0]), rhs.Data(), Size()); |
| + } |
| + } |
| + return(*this); |
| } |
| |
| public: |
| @@ -330,28 +358,33 @@ namespace Core { |
| { |
| _size = 0; |
| } |
| - inline uint32_t Size() const |
| + inline SIZE_CONTEXT Size() const |
| { |
| return (_size); |
| } |
| - inline uint8_t& operator[](const uint16_t index) |
| + inline const uint8_t* Data() const { |
| + return (&_data[0]); |
| + } |
| + inline uint8_t& operator[](const SIZE_CONTEXT index) |
| { |
| return _data[index]; |
| } |
| - inline const uint8_t& operator[](const uint16_t index) const |
| + inline const uint8_t& operator[](const SIZE_CONTEXT index) const |
| { |
| return _data[index]; |
| } |
| - void Size(uint16_t size) |
| + void Size(SIZE_CONTEXT size) |
| { |
| _data.Allocate(size); |
| |
| _size = size; |
| } |
| template <typename TYPENAME> |
| - uint16_t SetBuffer(const uint16_t offset, const TYPENAME& length, const uint8_t buffer[]) |
| + uint32_t SetBuffer(const SIZE_CONTEXT offset, const TYPENAME& length, const uint8_t buffer[]) |
| { |
| - uint16_t requiredLength(static_cast<uint16_t>(sizeof(TYPENAME) + length)); |
| + SIZE_CONTEXT requiredLength(static_cast<SIZE_CONTEXT>(sizeof(TYPENAME) + length)); |
| + |
| + static_assert(sizeof(TYPENAME) <= sizeof(SIZE_CONTEXT), "Make sure the logic can handle the size (enlarge the SIZE_CONTEXT)"); |
| |
| if ((offset + requiredLength) >= _size) { |
| Size(offset + requiredLength); |
| @@ -367,7 +400,7 @@ namespace Core { |
| return (requiredLength); |
| } |
| |
| - uint16_t Copy(const uint16_t offset, const uint16_t length, uint8_t buffer[]) const |
| + SIZE_CONTEXT Copy(const SIZE_CONTEXT offset, const SIZE_CONTEXT length, uint8_t buffer[]) const |
| { |
| ASSERT(offset + length <= _size); |
| |
| @@ -375,7 +408,7 @@ namespace Core { |
| |
| return (length); |
| } |
| - uint16_t Copy(const uint16_t offset, const uint16_t length, const uint8_t buffer[]) |
| + SIZE_CONTEXT Copy(const SIZE_CONTEXT offset, const SIZE_CONTEXT length, const uint8_t buffer[]) |
| { |
| Size(offset + length); |
| |
| @@ -383,16 +416,17 @@ namespace Core { |
| |
| return (length); |
| } |
| - uint16_t SetText(const uint16_t offset, const string& value) |
| + template <typename TYPENAME = uint16_t> |
| + SIZE_CONTEXT SetText(const SIZE_CONTEXT offset, const string& value) |
| { |
| std::string convertedText(Core::ToString(value)); |
| - return (SetBuffer<uint16_t>(offset, static_cast<uint16_t>(convertedText.length()), reinterpret_cast<const uint8_t*>(convertedText.c_str()))); |
| + return (SetBuffer<TYPENAME>(offset, static_cast<TYPENAME>(convertedText.length()), reinterpret_cast<const uint8_t*>(convertedText.c_str()))); |
| } |
| |
| - uint16_t SetNullTerminatedText(const uint16_t offset, const string& value) |
| + SIZE_CONTEXT SetNullTerminatedText(const SIZE_CONTEXT offset, const string& value) |
| { |
| std::string convertedText(Core::ToString(value)); |
| - uint16_t requiredLength(convertedText.length() + 1); |
| + SIZE_CONTEXT requiredLength(static_cast< SIZE_CONTEXT>(convertedText.length() + 1)); |
| |
| if ((offset + requiredLength) >= _size) { |
| Size(offset + requiredLength); |
| @@ -404,53 +438,56 @@ namespace Core { |
| } |
| |
| template <typename TYPENAME> |
| - uint16_t GetBuffer(const uint16_t offset, const TYPENAME length, uint8_t buffer[]) const |
| + SIZE_CONTEXT GetBuffer(const SIZE_CONTEXT offset, const TYPENAME length, uint8_t buffer[]) const |
| { |
| TYPENAME textLength; |
| |
| ASSERT((offset + sizeof(TYPENAME)) <= _size); |
| + static_assert(sizeof(TYPENAME) <= sizeof(SIZE_CONTEXT), "Make sure the logic can handle the size (enlarge the SIZE_CONTEXT)"); |
| |
| GetNumber<TYPENAME>(offset, textLength); |
| |
| ASSERT((textLength + offset + sizeof(TYPENAME)) <= _size); |
| |
| if ((textLength + offset + sizeof(TYPENAME)) > _size) { |
| - textLength = (_size - (offset + static_cast<uint16_t>(sizeof(TYPENAME)))); |
| + textLength = (_size - (offset + static_cast<uint32_t>(sizeof(TYPENAME)))); |
| } |
| |
| memcpy(buffer, &(_data[offset + sizeof(TYPENAME)]), (textLength > length ? length : textLength)); |
| |
| - return (static_cast<uint16_t>(sizeof(TYPENAME) + textLength)); |
| + return (static_cast<SIZE_CONTEXT>(sizeof(TYPENAME) + textLength)); |
| } |
| |
| - uint16_t GetText(const uint16_t offset, string& result) const |
| + template <typename TYPENAME = uint16_t> |
| + SIZE_CONTEXT GetText(const SIZE_CONTEXT offset, string& result) const |
| { |
| - uint16_t textLength; |
| - ASSERT((offset + sizeof(uint16_t)) <= _size); |
| + TYPENAME textLength; |
| + ASSERT((offset + sizeof(TYPENAME)) <= _size); |
| + static_assert(sizeof(TYPENAME) <= sizeof(SIZE_CONTEXT), "Make sure the logic can handle the size (enlarge the SIZE_CONTEXT)"); |
| |
| - GetNumber<uint16_t>(offset, textLength); |
| + GetNumber<TYPENAME>(offset, textLength); |
| |
| - ASSERT((textLength + offset + sizeof(uint16_t)) <= _size); |
| + ASSERT((textLength + offset + sizeof(TYPENAME)) <= _size); |
| |
| - if (textLength + offset + sizeof(uint16_t) > _size) { |
| - textLength = (_size - (offset + sizeof(uint16_t))); |
| + if (textLength + offset + sizeof(TYPENAME) > _size) { |
| + textLength = (_size - (offset + sizeof(TYPENAME))); |
| } |
| |
| - std::string convertedText(reinterpret_cast<const char*>(&(_data[offset + sizeof(uint16_t)])), textLength); |
| + std::string convertedText(reinterpret_cast<const char*>(&(_data[offset + sizeof(TYPENAME)])), textLength); |
| |
| result = Core::ToString(convertedText); |
| |
| - return (sizeof(uint16_t) + textLength); |
| + return (static_cast<SIZE_CONTEXT>(sizeof(TYPENAME) + textLength)); |
| } |
| |
| - uint16_t GetNullTerminatedText(const uint16_t offset, string& result) const |
| + SIZE_CONTEXT GetNullTerminatedText(const SIZE_CONTEXT offset, string& result) const |
| { |
| const char* text = reinterpret_cast<const char*>(&(_data[offset])); |
| result = text; |
| - return (result.length() + 1); |
| + return (static_cast<SIZE_CONTEXT>(result.length() + 1)); |
| } |
| |
| - uint16_t SetBoolean(const uint16_t offset, const bool value) |
| + SIZE_CONTEXT SetBoolean(const SIZE_CONTEXT offset, const bool value) |
| { |
| if ((offset + 1) >= _size) { |
| Size(offset + 1); |
| @@ -461,7 +498,7 @@ namespace Core { |
| return (1); |
| } |
| |
| - uint16_t GetBoolean(const uint16_t offset, bool& value) const |
| + SIZE_CONTEXT GetBoolean(const SIZE_CONTEXT offset, bool& value) const |
| { |
| ASSERT(offset < _size); |
| |
| @@ -471,23 +508,23 @@ namespace Core { |
| } |
| |
| template <typename TYPENAME> |
| - inline uint16_t SetNumber(const uint16_t offset, const TYPENAME number) |
| + inline SIZE_CONTEXT SetNumber(const SIZE_CONTEXT offset, const TYPENAME number) |
| { |
| return (SetNumber(offset, number, TemplateIntToType<sizeof(TYPENAME) == 1>())); |
| } |
| |
| template <typename TYPENAME> |
| - inline uint16_t GetNumber(const uint16_t offset, TYPENAME& number) const |
| + inline SIZE_CONTEXT GetNumber(const SIZE_CONTEXT offset, TYPENAME& number) const |
| { |
| return (GetNumber(offset, number, TemplateIntToType<sizeof(TYPENAME) == 1>())); |
| } |
| |
| #ifdef __DEBUG__ |
| - void Dump(const unsigned int offset) const |
| + void Dump(const SIZE_CONTEXT offset) const |
| { |
| static const TCHAR character[] = "0123456789ABCDEF"; |
| string info; |
| - uint16_t index = offset; |
| + SIZE_CONTEXT index = offset; |
| |
| while (index < _size) { |
| if (info.empty() == false) { |
| @@ -503,7 +540,7 @@ namespace Core { |
| |
| private: |
| template <typename TYPENAME> |
| - uint16_t SetNumber(const uint16_t offset, const TYPENAME number, const TemplateIntToType<true>&) |
| + SIZE_CONTEXT SetNumber(const SIZE_CONTEXT offset, const TYPENAME number, const TemplateIntToType<true>&) |
| { |
| if ((offset + 1) >= _size) { |
| Size(offset + 1); |
| @@ -515,59 +552,75 @@ namespace Core { |
| } |
| |
| template <typename TYPENAME> |
| - uint16_t SetNumber(const uint16_t offset, const TYPENAME number, const TemplateIntToType<false>&) |
| - { |
| - if ((offset + sizeof(TYPENAME)) >= _size) { |
| - Size(offset + sizeof(TYPENAME)); |
| - } |
| + void SetNumberLittleEndianPlatform(const SIZE_CONTEXT offset, const TYPENAME number) { |
| + const uint8_t* source = reinterpret_cast<const uint8_t*>(&number); |
| + uint8_t* destination = &(_data[offset + sizeof(TYPENAME) - 1]); |
| |
| -#ifdef LITTLE_ENDIAN_PLATFORM |
| - { |
| - const uint8_t* source = reinterpret_cast<const uint8_t*>(&number); |
| - uint8_t* destination = &(_data[offset + sizeof(TYPENAME) - 1]); |
| + *destination-- = *source++; |
| + *destination-- = *source++; |
| |
| + if ((sizeof(TYPENAME) == 4) || (sizeof(TYPENAME) == 8)) { |
| *destination-- = *source++; |
| *destination-- = *source++; |
| |
| - if ((sizeof(TYPENAME) == 4) || (sizeof(TYPENAME) == 8)) { |
| + if (sizeof(TYPENAME) == 8) { |
| + *destination-- = *source++; |
| + *destination-- = *source++; |
| *destination-- = *source++; |
| *destination-- = *source++; |
| - |
| - if (sizeof(TYPENAME) == 8) { |
| - *destination-- = *source++; |
| - *destination-- = *source++; |
| - *destination-- = *source++; |
| - *destination-- = *source++; |
| - } |
| } |
| } |
| -#else |
| - { |
| - const uint8_t* source = reinterpret_cast<const uint8_t*>(&number); |
| - uint8_t* destination = &(_data[offset]); |
| + } |
| + |
| + template <typename TYPENAME> |
| + void SetNumberBigEndianPlatform(const SIZE_CONTEXT offset, const TYPENAME number) { |
| + const uint8_t* source = reinterpret_cast<const uint8_t*>(&number); |
| + uint8_t* destination = &(_data[offset]); |
| + |
| + *destination++ = *source++; |
| + *destination++ = *source++; |
| |
| + if ((sizeof(TYPENAME) == 4) || (sizeof(TYPENAME) == 8)) { |
| *destination++ = *source++; |
| *destination++ = *source++; |
| |
| - if ((sizeof(TYPENAME) == 4) || (sizeof(TYPENAME) == 8)) { |
| + if (sizeof(TYPENAME) == 8) { |
| + *destination++ = *source++; |
| + *destination++ = *source++; |
| *destination++ = *source++; |
| *destination++ = *source++; |
| - |
| - if (sizeof(TYPENAME) == 8) { |
| - *destination++ = *source++; |
| - *destination++ = *source++; |
| - *destination++ = *source++; |
| - *destination++ = *source++; |
| - } |
| } |
| } |
| + } |
| + |
| + |
| + template <typename TYPENAME> |
| + SIZE_CONTEXT SetNumber(const SIZE_CONTEXT offset, const TYPENAME number, const TemplateIntToType<false>&) |
| + { |
| + if ((offset + sizeof(TYPENAME)) >= _size) { |
| + Size(offset + sizeof(TYPENAME)); |
| + } |
| + |
| + if (BIG_ENDIAN_ORDERING == true) { |
| +#ifdef LITTLE_ENDIAN_PLATFORM |
| + SetNumberLittleEndianPlatform(offset, number); |
| +#else |
| + SetNumberBigEndianPlatform(offset, number); |
| +#endif |
| + } |
| + else { |
| +#ifndef LITTLE_ENDIAN_PLATFORM |
| + SetNumberLittleEndianPlatform(offset, number); |
| +#else |
| + SetNumberLittleEndianPlatform(offset, number); |
| #endif |
| + } |
| |
| return (sizeof(TYPENAME)); |
| } |
| |
| template <typename TYPENAME> |
| - uint16_t GetNumber(const uint16_t offset, TYPENAME& number, const TemplateIntToType<true>&) const |
| + SIZE_CONTEXT GetNumber(const SIZE_CONTEXT offset, TYPENAME& number, const TemplateIntToType<true>&) const |
| { |
| // Only on package level allowed to pass the boundaries!!! |
| ASSERT((offset + sizeof(TYPENAME)) <= _size); |
| @@ -578,66 +631,84 @@ namespace Core { |
| } |
| |
| template <typename TYPENAME> |
| - inline uint16_t GetNumber(const uint16_t offset, TYPENAME& value, const TemplateIntToType<false>&) const |
| + inline TYPENAME GetNumberLittleEndianPlatform(const SIZE_CONTEXT offset) const |
| { |
| - TYPENAME result; |
| + TYPENAME result = static_cast<TYPENAME>(0); |
| + const uint8_t* source = &(_data[offset]); |
| + uint8_t* destination = &(reinterpret_cast<uint8_t*>(&result)[sizeof(TYPENAME) - 1]); |
| |
| - if ((offset + sizeof(TYPENAME)) > _size) { |
| - ::memset(&result, 0, sizeof(result)); |
| - } else |
| -#ifdef LITTLE_ENDIAN_PLATFORM |
| - { |
| - const uint8_t* source = &(_data[offset]); |
| - uint8_t* destination = &(reinterpret_cast<uint8_t*>(&result)[sizeof(TYPENAME) - 1]); |
| + *destination-- = *source++; |
| + *destination-- = *source++; |
| |
| + if ((sizeof(TYPENAME) == 4) || (sizeof(TYPENAME) == 8)) { |
| *destination-- = *source++; |
| *destination-- = *source++; |
| |
| - if ((sizeof(TYPENAME) == 4) || (sizeof(TYPENAME) == 8)) { |
| + if (sizeof(TYPENAME) == 8) { |
| + *destination-- = *source++; |
| + *destination-- = *source++; |
| *destination-- = *source++; |
| *destination-- = *source++; |
| - |
| - if (sizeof(TYPENAME) == 8) { |
| - *destination-- = *source++; |
| - *destination-- = *source++; |
| - *destination-- = *source++; |
| - *destination-- = *source++; |
| - } |
| } |
| } |
| -#else |
| - { |
| - // If the sizeof > 1, the alignment could be wrong. Assume the worst, always copy !!! |
| - const uint8_t* source = &(_data[offset]); |
| - uint8_t* destination = reinterpret_cast<uint8_t*>(&result); |
| |
| + return (result); |
| + } |
| + |
| + template <typename TYPENAME> |
| + inline TYPENAME GetNumberBigEndianPlatform(const SIZE_CONTEXT offset) const |
| + { |
| + TYPENAME result = 0; |
| + |
| + // If the sizeof > 1, the alignment could be wrong. Assume the worst, always copy !!! |
| + const uint8_t* source = &(_data[offset]); |
| + uint8_t* destination = reinterpret_cast<uint8_t*>(&result); |
| + |
| + *destination++ = *source++; |
| + *destination++ = *source++; |
| + |
| + if ((sizeof(TYPENAME) == 4) || (sizeof(TYPENAME) == 8)) { |
| *destination++ = *source++; |
| *destination++ = *source++; |
| |
| - if ((sizeof(TYPENAME) == 4) || (sizeof(TYPENAME) == 8)) { |
| + if (sizeof(TYPENAME) == 8) { |
| + *destination++ = *source++; |
| + *destination++ = *source++; |
| *destination++ = *source++; |
| *destination++ = *source++; |
| - |
| - if (sizeof(TYPENAME) == 8) { |
| - *destination++ = *source++; |
| - *destination++ = *source++; |
| - *destination++ = *source++; |
| - *destination++ = *source++; |
| - } |
| } |
| } |
| -#endif |
| |
| - value = result; |
| + return (result); |
| + } |
| + |
| + template <typename TYPENAME> |
| + inline SIZE_CONTEXT GetNumber(const SIZE_CONTEXT offset, TYPENAME& value, const TemplateIntToType<false>&) const |
| + { |
| + if ((offset + sizeof(TYPENAME)) > _size) { |
| + value = static_cast<TYPENAME>(0); |
| + } |
| + else if (BIG_ENDIAN_ORDERING == true) { |
| +#ifdef LITTLE_ENDIAN_PLATFORM |
| + value = GetNumberLittleEndianPlatform<TYPENAME>(offset); |
| +#else |
| + value = GetNumberBigEndianPlatform<TYPENAME>(offset); |
| +#endif |
| + } |
| + else { |
| +#ifndef LITTLE_ENDIAN_PLATFORM |
| + value = GetNumberBigEndianPlatform<TYPENAME>(offset); |
| +#else |
| + value = GetNumberLittleEndianPlatform<TYPENAME>(offset); |
| +#endif |
| + } |
| |
| return (sizeof(TYPENAME)); |
| } |
| |
| private: |
| - mutable uint16_t _size; |
| - AllocatorType<BLOCKSIZE> _data; |
| + mutable SIZE_CONTEXT _size; |
| + AllocatorType<BLOCKSIZE,SIZE_CONTEXT> _data; |
| }; |
| } |
| } |
| - |
| -#endif //__GENERICS_FRAME_H |
| -- |
| 2.25.1 |
| |