diff --git a/coding/reader.cpp b/coding/reader.cpp index 81cbdcced5..6b94af3bc7 100644 --- a/coding/reader.cpp +++ b/coding/reader.cpp @@ -19,19 +19,3 @@ bool Reader::IsEqual(string const & name1, string const & name2) return (name1 == name2); #endif } - -namespace -{ - bool AssertPosAndSizeImpl(uint64_t pos, uint64_t size, uint64_t readerSize) - { - bool const ret1 = (pos + size <= readerSize); - bool const ret2 = (size <= static_cast(-1)); - ASSERT ( ret1 && ret2, (pos, size, readerSize) ); - return (ret1 && ret2); - } -} - -bool MemReader::AssertPosAndSize(uint64_t pos, uint64_t size) const -{ - return AssertPosAndSizeImpl(pos, size, Size()); -} diff --git a/coding/reader.hpp b/coding/reader.hpp index c96088d0ff..34d2d98ac0 100644 --- a/coding/reader.hpp +++ b/coding/reader.hpp @@ -32,13 +32,12 @@ public: }; // Reader from memory. -class MemReader : public Reader +template +class MemReaderTemplate : public Reader { - bool AssertPosAndSize(uint64_t pos, uint64_t size) const; - public: // Construct from block of memory. - MemReader(void const * pData, size_t size) + MemReaderTemplate(void const * pData, size_t size) : m_pData(static_cast(pData)), m_size(size) { } @@ -50,27 +49,51 @@ public: inline void Read(uint64_t pos, void * p, size_t size) const override { - ASSERT ( AssertPosAndSize(pos, size), () ); + AssertPosAndSize(pos, size); memcpy(p, m_pData + pos, size); } - inline MemReader SubReader(uint64_t pos, uint64_t size) const + inline MemReaderTemplate SubReader(uint64_t pos, uint64_t size) const { - ASSERT ( AssertPosAndSize(pos, size), () ); - return MemReader(m_pData + pos, static_cast(size)); + AssertPosAndSize(pos, size); + return MemReaderTemplate(m_pData + pos, static_cast(size)); } inline unique_ptr CreateSubReader(uint64_t pos, uint64_t size) const override { - ASSERT ( AssertPosAndSize(pos, size), () ); - return make_unique(m_pData + pos, static_cast(size)); + AssertPosAndSize(pos, size); + return make_unique(m_pData + pos, static_cast(size)); } private: + bool GoodPosAndSize(uint64_t pos, uint64_t size) const + { + uint64_t const readerSize = Size(); + bool const ret1 = (pos + size <= readerSize); + bool const ret2 = (size <= static_cast(-1)); + return ret1 && ret2; + } + + void AssertPosAndSize(uint64_t pos, uint64_t size) const + { + if (WithExceptions) + { + if (!GoodPosAndSize(pos, size)) + MYTHROW(Reader::SizeException, (pos, size, Size())); + } + else + { + ASSERT(GoodPosAndSize(pos, size), (pos, size, Size())); + } + } + char const * m_pData; size_t m_size; }; +using MemReader = MemReaderTemplate; +using MemReaderWithExceptions = MemReaderTemplate; + // Reader wrapper to hold the pointer to a polymorfic reader. // Common use: ReaderSource >. // Note! It takes the ownership of Reader.