diff --git a/CMakeLists.txt b/CMakeLists.txt index c9fe620b..a860867b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) -set(pip_MINOR 98) +set(pip_MINOR 99) set(pip_REVISION 0) set(pip_SUFFIX ) set(pip_COMPANY SHS) diff --git a/libs/main/containers/pimap.h b/libs/main/containers/pimap.h index 9863ffab..6f5e278d 100644 --- a/libs/main/containers/pimap.h +++ b/libs/main/containers/pimap.h @@ -39,11 +39,10 @@ #include "pipair.h" -template -class PIMapIterator; - -template -class PIMapReverseIterator; +template class PIMapIteratorConst; +template class PIMapIteratorConstReverse; +template class PIMapIterator; +template class PIMapIteratorReverse; //! \addtogroup Containers @@ -74,11 +73,13 @@ class PIMapReverseIterator; //! В контейнеры этого типа заносятся элементы вместе с ключами, //! по которым их можно найти, которыми могут выступать значения любого типа. //! \a operator [] позволяет получить доступ к элементу по ключу, -//! и если такого эелемента небыло, то он будет создан. +//! и если такого эелемента не было, то он будет создан. template class PIMap { + template friend class PIMapIteratorConst; + template friend class PIMapIteratorConstReverse; template friend class PIMapIterator; - template friend class PIMapReverseIterator; + template friend class PIMapIteratorReverse; template friend PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIMap & v); template @@ -235,11 +236,17 @@ public: const_reverse_iterator constRend() const {return const_reverse_iterator(this, -1);} - //! \relatesalso PIMapIterator - PIMapIterator makeIterator() const {return PIMapIterator(*this);} + //! \relatesalso PIMapIteratorConst + PIMapIteratorConst makeIterator() const {return PIMapIteratorConst(*this);} - //! \relatesalso PIMapReverseIterator - PIMapReverseIterator makeReverseIterator() const {return PIMapReverseIterator(*this);} + //! \relatesalso PIMapIterator + PIMapIterator makeIterator() {return PIMapIterator(*this);} + + //! \relatesalso PIMapIteratorConstReverse + PIMapIteratorConstReverse makeReverseIterator() const {return PIMapIteratorConstReverse(*this);} + + //! \relatesalso PIMapIteratorReverse + PIMapIteratorReverse makeReverseIterator() {return PIMapIteratorReverse(*this);} size_t size() const {return pim_content.size();} @@ -512,18 +519,18 @@ private: //! \addtogroup Containers //! \{ -//! \class PIMapIterator +//! \class PIMapIteratorConst //! \brief //! \~english Java-style iterator for \a PIMap. //! \~russian Итератор Java стиля для \a PIMap. //! \~\} //! \details //! \~english -//! This class used to easy serial access keys and values in PIMap. -//! You can use constructor to create iterator, or use \a PIMap::makeIterator() +//! This class used to easy serial access keys and values in PIMap with read only permitions. +//! Use constructor to create iterator, or use \a PIMap::makeIterator() //! \~russian -//! Этот класс используется для удобного перебора ключей и значений всего словаря в обратном порядке. -//! Ты можешь использовать конструктор, в который передать словарь, или функцию словаря \a PIMap::makeReverseIterator(). +//! Этот класс используется для удобного перебора ключей и значений всего словаря только для чтения. +//! Можно использовать конструктор, в который передаётся словарь, или функцию словаря \a PIMap::makeIterator(). //! \~ //! \code //! PIMap m; @@ -533,46 +540,42 @@ private: //! auto it = m.makeIterator(); //! while (it.next()) { //! piCout << it.key() << it.value(); +//! } //! // 1 one //! // 2 two //! // 4 four //! \endcode template -class PIMapIterator { +class PIMapIteratorConst { typedef PIMap MapType; public: - PIMapIterator(const PIMap & map, bool reverse = false): m(map), pos(-1) {} + PIMapIteratorConst(const PIMap & map): m(map), pos(-1) {} //! \~english Returns current key. //! \~russian Возвращает ключ текущего элемента. - //! \~\sa \a value(), \a valueRef() + //! \~\sa \a value() const Key & key() const { return m._key(pos); } //! \~english Returns current value. //! \~russian Возвращает значение текущего элемента. - //! \~\sa \a key(), \a valueRef() + //! \~\sa \a key() const T & value() const { return m._value(pos); } - //! \~english Returns current value reference. - //! \~russian Возвращает изменяемую ссылку на значение текущего элемента. - //! \~\sa \a key(), \a value() - T & valueRef() { - return const_cast(m)._value(pos); - } - //! \~english Returns true if iterator can jump to next entry //! \~russian Возвращает true если итератор может перейти к следующему элементу. + //! \~\sa \a next() inline bool hasNext() const { return pos < (m.size_s() - 1); } //! \~english Jump to next entry and return true if new position is valid. //! \~russian Переходит к следующему элементу и возвращает true если он существует. + //! \~\sa \a hasNext(), \a reset() inline bool next() { ++pos; return pos < m.size_s(); @@ -580,6 +583,7 @@ public: //! \~english Reset iterator to initial position. //! \~russian Переходит на начало. + //! \~\sa \a next() inline void reset() { pos = -1; } @@ -591,18 +595,18 @@ private: //! \addtogroup Containers //! \{ -//! \class PIMapReverseIterator +//! \class PIMapIteratorConstReverse //! \brief //! \~english Java-style reverse iterator for \a PIMap. //! \~russian Итератор Java стиля для \a PIMap в обратном порядке. //! \~\} //! \details //! \~english -//! This class used to easy serial reverse access keys and values in PIMap. -//! You can use constructor to create iterator, or use \a PIMap::makeReverseIterator(). +//! This class used to easy serial reverse access keys and values in PIMap with read only permitions. +//! Use constructor to create iterator, or use \a PIMap::makeReverseIterator(). //! \~russian -//! Этот класс используется для удобного перебора ключей и значений всего словаря в обратном порядке. -//! Ты можешь использовать конструктор, в который передать словарь, или функцию словаря \a PIMap::makeReverseIterator(). +//! Этот класс используется для удобного перебора ключей и значений всего словаря в обратном порядке только для чтения. +//! Можно использовать конструктор, в который передаётся словарь, или функцию словаря \a PIMap::makeReverseIterator(). //! \~ //! \code //! PIMap m; @@ -617,54 +621,36 @@ private: //! // 2 two //! // 1 one //! \endcode -//! \~english Write access: -//! \~russian Доступ на запись: -//! \~ -//! \code -//! while (it.next()) { -//! it.valueRef().append("_!"); -//! piCout << it.key() << it.value(); -//! } -//! // 4 four_! -//! // 2 two_! -//! // 1 one_! -//! \endcode template -class PIMapReverseIterator { +class PIMapIteratorConstReverse { typedef PIMap MapType; public: - PIMapReverseIterator(const PIMap & map): m(map), pos(m.size_s()) {} + PIMapIteratorConstReverse(const PIMap & map): m(map), pos(m.size_s()) {} //! \~english Returns current key. //! \~russian Возвращает ключ текущего элемента. - //! \~\sa \a value(), \a valueRef() + //! \~\sa \a value() const Key & key() const { return m._key(pos); } //! \~english Returns current value. //! \~russian Возвращает значение текущего элемента. - //! \~\sa \a key(), \a valueRef() + //! \~\sa \a key() const T & value() const { return m._value(pos); } - - //! \~english Returns current value reference. - //! \~russian Возвращает изменяемую ссылку на значение текущего элемента. - //! \~\sa \a key(), \a value() - T & valueRef() { - return const_cast(m)._value(pos); - } - //! \~english Returns true if iterator can jump to next entry //! \~russian Возвращает true если итератор может перейти к следующему элементу. + //! \~\sa \a next() inline bool hasNext() const { return pos > 0; } //! \~english Jump to next entry and return true if new position is valid. //! \~russian Переходит к следующему элементу и возвращает true если он существует. + //! \~\sa \a hasNext(), \a reset() inline bool next() { --pos; return pos >= 0; @@ -672,6 +658,7 @@ public: //! \~english Reset iterator to initial position. //! \~russian Переходит на начало. + //! \~\sa \a next() inline void reset() { pos = m.size_s(); } @@ -681,6 +668,158 @@ private: }; +//! \addtogroup Containers +//! \{ +//! \class PIMapIterator +//! \brief +//! \~english Java-style iterator for \a PIMap. +//! \~russian Итератор Java стиля для \a PIMap. +//! \~\} +//! \details +//! \~english +//! This class used to easy serial access keys and values in PIMap with write permitions. +//! Use constructor to create iterator, or use \a PIMap::makeIterator() +//! \~russian +//! Этот класс используется для удобного перебора ключей и значений всего словаря с доступом на запись. +//! Можно использовать конструктор, в который передаётся словарь, или функцию словаря \a PIMap::makeIterator(). +//! \~ +//! \code +//! PIMap m; +//! m[1] = "one"; +//! m[2] = "two"; +//! m[4] = "four"; +//! auto it = m.makeIterator(); +//! while (it.next()) { +//! it.value().append("_!"); +//! piCout << it.key() << it.value(); +//! } +//! // 1 one_! +//! // 2 two_! +//! // 4 four_! +//! \endcode +template +class PIMapIterator { + typedef PIMap MapType; +public: + PIMapIterator(PIMap & map): m(map), pos(-1) {} + + //! \~english Returns current key. + //! \~russian Возвращает ключ текущего элемента. + //! \~\sa \a value() + const Key & key() const { + return m._key(pos); + } + + //! \~english Returns current value. + //! \~russian Возвращает значение текущего элемента. + //! \~\sa \a key() + T & value() { + return m._value(pos); + } + + //! \~english Returns true if iterator can jump to next entry + //! \~russian Возвращает true если итератор может перейти к следующему элементу. + //! \~\sa \a next() + inline bool hasNext() const { + return pos < (m.size_s() - 1); + } + + //! \~english Jump to next entry and return true if new position is valid. + //! \~russian Переходит к следующему элементу и возвращает true если он существует. + //! \~\sa \a hasNext(), \a reset() + inline bool next() { + ++pos; + return pos < m.size_s(); + } + + //! \~english Reset iterator to initial position. + //! \~russian Переходит на начало. + //! \~\sa \a next() + inline void reset() { + pos = -1; + } +private: + MapType & m; + ssize_t pos; +}; + + +//! \addtogroup Containers +//! \{ +//! \class PIMapIteratorReverse +//! \brief +//! \~english Java-style reverse iterator for \a PIMap. +//! \~russian Итератор Java стиля для \a PIMap в обратном порядке. +//! \~\} +//! \details +//! \~english +//! This class used to easy serial reverse access keys and values in PIMap with write permitions. +//! Use constructor to create iterator, or use \a PIMap::makeReverseIterator(). +//! \~russian +//! Этот класс используется для удобного перебора ключей и значений всего словаря в обратном порядке с доступом на запись. +//! Можно использовать конструктор, в который передаётся словарь, или функцию словаря \a PIMap::makeReverseIterator(). +//! \~ +//! \code +//! PIMap m; +//! m[1] = "one"; +//! m[2] = "two"; +//! m[4] = "four"; +//! auto it = m.makeReverseIterator(); +//! while (it.next()) { +//! it.value().append("_!"); +//! piCout << it.key() << it.value(); +//! } +//! // 4 four_! +//! // 2 two_! +//! // 1 one_! +//! \endcode +template +class PIMapIteratorReverse { + typedef PIMap MapType; +public: + PIMapIteratorReverse(PIMap & map): m(map), pos(m.size_s()) {} + + //! \~english Returns current key. + //! \~russian Возвращает ключ текущего элемента. + //! \~\sa \a value() + const Key & key() const { + return m._key(pos); + } + + //! \~english Returns current value. + //! \~russian Возвращает значение текущего элемента. + //! \~\sa \a key() + T & value() { + return m._value(pos); + } + + //! \~english Returns true if iterator can jump to next entry + //! \~russian Возвращает true если итератор может перейти к следующему элементу. + //! \~\sa \a next() + inline bool hasNext() const { + return pos > 0; + } + + //! \~english Jump to next entry and return true if new position is valid. + //! \~russian Переходит к следующему элементу и возвращает true если он существует. + //! \~\sa \a hasNext(), \a reset() + inline bool next() { + --pos; + return pos >= 0; + } + + //! \~english Reset iterator to initial position. + //! \~russian Переходит на начало. + //! \~\sa \a next() + inline void reset() { + pos = m.size_s(); + } +private: + MapType & m; + ssize_t pos; +}; + + #ifdef PIP_STD_IOSTREAM //! \~english Output operator to [std::ostream](https://en.cppreference.com/w/cpp/io/basic_ostream). //! \~russian Оператор вывода в [std::ostream](https://ru.cppreference.com/w/cpp/io/basic_ostream). diff --git a/libs/main/core/pichunkstream.cpp b/libs/main/core/pichunkstream.cpp index fa0b1b7f..d9ab18d3 100644 --- a/libs/main/core/pichunkstream.cpp +++ b/libs/main/core/pichunkstream.cpp @@ -125,15 +125,14 @@ int PIChunkStream::read() { } -int PIChunkStream::peekVInt(Version version_, PIByteArray * data_, int pos, PIByteArray & hdr, uint & ret) { +int PIChunkStream::peekVInt(Version version_, uchar * data_, int sz, uint & ret) { switch (version_) { case Version_1: - memcpy(&ret, data_->data(pos), 4); + memcpy(&ret, data_, 4); return 4; case Version_2: { + PIByteArray hdr(data_, piMini(4, sz)); hdr.resize(4); - hdr.fill(uchar(0)); - memcpy(hdr.data(), data_->data(pos), piMini(4, data_->size_s() - pos)); uchar hsz = 0; ret = readVInt(hdr, &hsz); return hsz; @@ -153,13 +152,16 @@ void PIChunkStream::replaceChunk(int id, const PIByteArray & v) { pos.length = v.size_s(); if (size_mod != 0) { auto it = data_map.makeIterator(); - while (it.next()) - if (it.valueRef().start > pos.start) - it.valueRef().start += size_mod; - if (size_mod > 0) + while (it.next()) { + if (it.value().start > pos.start) { + it.value().start += size_mod; + } + } + if (size_mod > 0) { data_->insert(pos.start, PIByteArray(size_mod)); - else + } else { data_->remove(pos.start, -size_mod); + } } memcpy(data_->data(pos.start - pos.size_bytes), nsba.data(), nsba.size()); pos.start += nsba.size_s() - pos.size_bytes; @@ -172,10 +174,9 @@ void PIChunkStream::readAll() { if (!data_) return; int pos = 0, sz = data_->size_s(), hsz = 0; uint csz = 0, cid = 0; - PIByteArray hdr; while (pos < sz) { - pos += peekVInt((Version)version_, data_, pos, hdr, cid); - hsz = peekVInt((Version)version_, data_, pos, hdr, csz); + pos += peekVInt((Version)version_, data_->data(pos), data_->size_s() - pos, cid); + hsz = peekVInt((Version)version_, data_->data(pos), data_->size_s() - pos, csz); pos += hsz; data_map[cid] = CacheEntry(pos, csz, hsz); pos += csz; @@ -193,8 +194,7 @@ bool PIChunkStream::extract(PIByteArray & data, bool read_all) { if (tmp_data.size_s() < 4) return false; data_ = &tmp_data; _init(); - if (read_all) - readAll(); + if (read_all) readAll(); return true; } @@ -208,19 +208,27 @@ void PIChunkStream::_init() { if ((v & 0x80) == 0x80) { v &= 0x7f; switch (v) { - case 2: version_ = (uchar)Version_2; data_->pop_front(); first_byte_taken = true; break; - default: version_ = Version_1; break; + case 2: + version_ = (uchar)Version_2; + data_->pop_front(); + first_byte_taken = true; + break; + default: + version_ = Version_1; + break; } - } else + } else { version_ = Version_1; + } } } uint PIChunkStream::readVInt(PIByteArray & s, uchar * bytes_cnt) { if (s.isEmpty()) return 0; - uchar bytes[4]; s >> bytes[0]; - uchar abc = 0; + uchar bytes[4]; + uchar abc; + s >> bytes[0]; for (abc = 0; abc < 3; ++abc) { uchar mask = (0x80 >> abc); if ((bytes[0] & mask) == mask) { diff --git a/libs/main/core/pichunkstream.h b/libs/main/core/pichunkstream.h index c7039c04..68493586 100644 --- a/libs/main/core/pichunkstream.h +++ b/libs/main/core/pichunkstream.h @@ -165,7 +165,7 @@ private: static uint readVInt(PIByteArray & s, uchar * bytes = 0); static void writeVInt(PIByteArray & s, uint val); - static int peekVInt(Version version_, PIByteArray * data_, int pos, PIByteArray & hdr, uint & ret); + static int peekVInt(Version version_, uchar * data_, int sz, uint & ret); void replaceChunk(int id, const PIByteArray & v); int last_id; diff --git a/libs/main/introspection/piintrospection_server_p.cpp b/libs/main/introspection/piintrospection_server_p.cpp index b32f2de5..9c1b816a 100644 --- a/libs/main/introspection/piintrospection_server_p.cpp +++ b/libs/main/introspection/piintrospection_server_p.cpp @@ -140,8 +140,8 @@ PIByteArray PIIntrospection::packThreads() { PIMap & tm(p->threads); auto it = tm.makeIterator(); while (it.next()) { - it.valueRef().classname = PIStringAscii(it.key()->className()); - it.valueRef().name = it.key()->name(); + it.value().classname = PIStringAscii(it.key()->className()); + it.value().name = it.key()->name(); } ret << tm.values(); p->mutex.unlock(); diff --git a/libs/main/io_utils/piconnection.cpp b/libs/main/io_utils/piconnection.cpp index 45105266..80621c3c 100644 --- a/libs/main/io_utils/piconnection.cpp +++ b/libs/main/io_utils/piconnection.cpp @@ -393,7 +393,7 @@ bool PIConnection::removeDevice(const PIString & full_path) { channels_.remove(dev); auto it = channels_.makeIterator(); while (it.next()) { - it.valueRef().removeAll(dev); + it.value().removeAll(dev); } __device_pool__->lock(); PIDiagnostics * dg = diags_.value(dev, nullptr); @@ -418,7 +418,7 @@ void PIConnection::removeAllDevices() { channels_.remove(d); auto it = channels_.makeIterator(); while (it.next()) { - it.valueRef().removeAll(d); + it.value().removeAll(d); } PIDiagnostics * dg = diags_.value(d, nullptr); if (dg) delete dg; @@ -572,7 +572,7 @@ void PIConnection::removeAllFilters() { channels_.remove(i.value()->extractor); auto it = channels_.makeIterator(); while (it.next()) { - it.valueRef().removeAll(i.value()->extractor); + it.value().removeAll(i.value()->extractor); } if (diags_.value(i.value()->extractor)) { delete diags_.value(i.value()->extractor); @@ -677,7 +677,7 @@ bool PIConnection::removeChannel(const PIString & name0) { channels_.remove(dev0); auto it = channels_.makeIterator(); while (it.next()) { - it.valueRef().removeAll(dev0); + it.value().removeAll(dev0); } return true; } @@ -1234,7 +1234,7 @@ void PIConnection::unboundExtractor(PIPacketExtractor * pe) { channels_.remove(pe); auto it = channels_.makeIterator(); while (it.next()) { - it.valueRef().removeAll(pe); + it.value().removeAll(pe); } bounded_extractors.remove(pe); PIVector k = bounded_extractors.keys(); diff --git a/libs/main/system/pisystemmonitor.cpp b/libs/main/system/pisystemmonitor.cpp index 11e735f9..a3c02d5e 100644 --- a/libs/main/system/pisystemmonitor.cpp +++ b/libs/main/system/pisystemmonitor.cpp @@ -321,7 +321,7 @@ void PISystemMonitor::run() { auto i = cur_tm.makeIterator(); while (i.next()) { if (!last_tm.contains(i.key())) continue; - ThreadStats & ts_new(i.valueRef()); + ThreadStats & ts_new(i.value()); ThreadStats & ts_old(last_tm[i.key()]); ts_new.cpu_load_kernel = calcThreadUsage(ts_new.kernel_time, ts_old.kernel_time); ts_new.cpu_load_user = calcThreadUsage(ts_new.user_time, ts_old.user_time); diff --git a/utils/deploy_tool/main.cpp b/utils/deploy_tool/main.cpp index 87bbee22..28fed863 100644 --- a/utils/deploy_tool/main.cpp +++ b/utils/deploy_tool/main.cpp @@ -663,7 +663,7 @@ int main(int argc, char * argv[]) { auto it = qt_filters.makeIterator(); while (it.next()) - it.valueRef().forEach([](PIString & i){ + it.value().forEach([](PIString & i){ if (!i.startsWith("*")) i.prepend("*"); if (!i.endsWith("*")) i.append("*"); });