Compare commits
9 Commits
eb21c85170
...
a745f803b3
| Author | SHA1 | Date | |
|---|---|---|---|
| a745f803b3 | |||
| 1b67000887 | |||
| 04d3e31dbc | |||
| 9f29155d07 | |||
| 021411defa | |||
| ee4d78d2e1 | |||
| 9283c88b4e | |||
| 8d585439bb | |||
| ebf2b08bb1 |
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
|
||||
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
||||
project(PIP)
|
||||
set(PIP_MAJOR 3)
|
||||
set(PIP_MINOR 16)
|
||||
set(PIP_MINOR 17)
|
||||
set(PIP_REVISION 1)
|
||||
set(PIP_SUFFIX )
|
||||
set(PIP_COMPANY SHS)
|
||||
|
||||
@@ -610,7 +610,7 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
struct MapIndex {
|
||||
MapIndex(const Key & k = Key(), size_t i = 0): key(k), index(i) {}
|
||||
MapIndex(Key && k, size_t i = 0): key(std::move(k)), index(i) {}
|
||||
@@ -627,6 +627,10 @@ private:
|
||||
template<typename P, typename Key1, typename T1>
|
||||
friend PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
|
||||
|
||||
PIVector<T> pim_content;
|
||||
PIDeque<MapIndex> pim_index;
|
||||
|
||||
private:
|
||||
inline ssize_t _binarySearch(ssize_t first, ssize_t last, const Key & key, bool & found) const {
|
||||
ssize_t mid = 0;
|
||||
while (first <= last) {
|
||||
@@ -678,10 +682,6 @@ private:
|
||||
inline T & _value(ssize_t index) { return pim_content[pim_index[index].index]; }
|
||||
|
||||
inline const T & _value(ssize_t index) const { return pim_content[pim_index[index].index]; }
|
||||
|
||||
|
||||
PIVector<T> pim_content;
|
||||
PIDeque<MapIndex> pim_index;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -66,6 +66,90 @@ public:
|
||||
_CSet::insert(v3, 0);
|
||||
}
|
||||
|
||||
|
||||
class const_iterator {
|
||||
friend class PISet<T>;
|
||||
|
||||
private:
|
||||
inline const_iterator(const PISet<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PISet<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef T & reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
|
||||
inline const_iterator(): parent(0), pos(0) {}
|
||||
|
||||
inline const T & operator*() const { return parent->pim_index[pos].key; }
|
||||
inline const T & operator->() const { return parent->pim_index[pos].key; }
|
||||
|
||||
inline const_iterator & operator++() {
|
||||
++pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator operator++(int) {
|
||||
const auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
inline const_iterator & operator--() {
|
||||
--pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator operator--(int) {
|
||||
const auto tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline const_iterator & operator+=(const const_iterator & it) {
|
||||
pos += it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator & operator+=(size_t p) {
|
||||
pos += p;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator & operator-=(const const_iterator & it) {
|
||||
pos -= it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator & operator-=(size_t p) {
|
||||
pos -= p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend inline const_iterator operator-(size_t p, const const_iterator & it) { return it - p; }
|
||||
friend inline const_iterator operator-(const const_iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const const_iterator & it1, const const_iterator & it2) { return it1.pos - it2.pos; }
|
||||
|
||||
friend inline const_iterator operator+(size_t p, const const_iterator & it) { return it + p; }
|
||||
friend inline const_iterator operator+(const const_iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp += p;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline bool operator==(const const_iterator & it) const { return (pos == it.pos); }
|
||||
inline bool operator!=(const const_iterator & it) const { return (pos != it.pos); }
|
||||
friend inline bool operator<(const const_iterator & it1, const const_iterator & it2) { return it1.pos < it2.pos; }
|
||||
friend inline bool operator<=(const const_iterator & it1, const const_iterator & it2) { return it1.pos <= it2.pos; }
|
||||
friend inline bool operator>(const const_iterator & it1, const const_iterator & it2) { return it1.pos > it2.pos; }
|
||||
friend inline bool operator>=(const const_iterator & it1, const const_iterator & it2) { return it1.pos >= it2.pos; }
|
||||
};
|
||||
|
||||
|
||||
inline const_iterator begin() const { return const_iterator(this, 0); }
|
||||
inline const_iterator end() const { return const_iterator(this, _CSet::size()); }
|
||||
|
||||
//! Contructs set from vector of elements
|
||||
explicit PISet(const PIVector<T> & values) {
|
||||
if (values.isEmpty()) return;
|
||||
@@ -97,6 +181,10 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Tests if element `key` exists in the set.
|
||||
//! \~russian Проверяет наличие элемента `key` в массиве.
|
||||
inline bool contains(const T & t) const { return _CSet::contains(t); }
|
||||
|
||||
//! Returns if element "t" exists in this set
|
||||
bool operator[](const T & t) const { return _CSet::contains(t); }
|
||||
|
||||
@@ -108,25 +196,21 @@ public:
|
||||
|
||||
//! Unite set with "v"
|
||||
PISet<T> & unite(const PISet<T> & v) {
|
||||
for (typename PIMap<T, uchar>::const_iterator i = v.begin(); i != v.end(); ++i)
|
||||
_CSet::insert(i.key(), 0);
|
||||
for (const auto & i: v)
|
||||
_CSet::insert(i, 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Subtract set with "v"
|
||||
PISet<T> & subtract(const PISet<T> & v) {
|
||||
for (typename PIMap<T, uchar>::const_iterator i = v.begin(); i != v.end(); ++i)
|
||||
_CSet::remove(i.key());
|
||||
for (const auto & i: v)
|
||||
_CSet::remove(i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Intersect set with "v"
|
||||
PISet<T> & intersect(const PISet<T> & v) {
|
||||
for (typename _CSet::iterator i = _CSet::begin(); i != _CSet::end(); ++i)
|
||||
if (!v.contains(i.key())) {
|
||||
_CSet::remove(i.key());
|
||||
--i;
|
||||
}
|
||||
_CSet::removeWhere([&v](const T & k, uchar) { return !v.contains(k); });
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -145,16 +229,16 @@ public:
|
||||
//! Returns content of set as PIVector
|
||||
PIVector<T> toVector() const {
|
||||
PIVector<T> ret;
|
||||
for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i)
|
||||
ret << i.key();
|
||||
for (const auto & i: *this)
|
||||
ret << i;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! Returns content of set as PIDeque
|
||||
PIDeque<T> toDeque() const {
|
||||
PIDeque<T> ret;
|
||||
for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i)
|
||||
ret << i.key();
|
||||
for (const auto & i: *this)
|
||||
ret << i;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
@@ -199,10 +283,10 @@ inline PICout operator<<(PICout s, const PISet<Type> & v) {
|
||||
s.saveAndSetControls(0);
|
||||
s << "{";
|
||||
bool first = true;
|
||||
for (typename PIMap<Type, uchar>::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||
for (const auto & i: v) {
|
||||
if (!first) s << ", ";
|
||||
first = false;
|
||||
s << i.key();
|
||||
s << i;
|
||||
}
|
||||
s << "}";
|
||||
s.restoreControls();
|
||||
|
||||
@@ -668,4 +668,18 @@ private:
|
||||
};
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Inherit from this class to make your class non-trivially copyable.
|
||||
//! \~russian Наследуйтесь от этого класса чтобы сделать свой класс нетривиально копируемым.
|
||||
struct PIP_EXPORT PINonTriviallyCopyable {
|
||||
PINonTriviallyCopyable() noexcept = default;
|
||||
PINonTriviallyCopyable(const PINonTriviallyCopyable &) noexcept = default;
|
||||
PINonTriviallyCopyable(PINonTriviallyCopyable &&) noexcept;
|
||||
PINonTriviallyCopyable & operator=(const PINonTriviallyCopyable &) noexcept = default;
|
||||
PINonTriviallyCopyable & operator=(PINonTriviallyCopyable &&) noexcept = default;
|
||||
~PINonTriviallyCopyable() = default;
|
||||
};
|
||||
inline PINonTriviallyCopyable::PINonTriviallyCopyable(PINonTriviallyCopyable &&) noexcept = default;
|
||||
|
||||
|
||||
#endif // PIBASE_H
|
||||
|
||||
@@ -334,7 +334,7 @@ bool PIConfig::open(const PIString & path, PIIODevice::DeviceMode mode) {
|
||||
bool PIConfig::open(PIString * string, PIIODevice::DeviceMode mode) {
|
||||
_destroy();
|
||||
own_dev = true;
|
||||
dev = new PIIOString(string, mode);
|
||||
dev = new PIIOString(string, PIIODevice::ReadOnly);
|
||||
_setupDev();
|
||||
parse();
|
||||
return true;
|
||||
@@ -365,10 +365,7 @@ void PIConfig::_init() {
|
||||
|
||||
|
||||
void PIConfig::_destroy() {
|
||||
if (stream) {
|
||||
delete stream;
|
||||
stream = nullptr;
|
||||
}
|
||||
piDeleteSafety(stream);
|
||||
if (own_dev && dev) delete dev;
|
||||
dev = nullptr;
|
||||
piForeach(PIConfig * c, inc_devs)
|
||||
@@ -392,6 +389,7 @@ void PIConfig::_clearDev() {
|
||||
}
|
||||
if (PIString(dev->className()) == "PIIOString") {
|
||||
((PIIOString *)dev)->clear();
|
||||
((PIIOString *)dev)->setMode(PIIODevice::WriteOnly);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -419,6 +417,7 @@ void PIConfig::_seekToBeginDev() {
|
||||
}
|
||||
if (PIString(dev->className()) == "PIIOString") {
|
||||
((PIIOString *)dev)->seekToBegin();
|
||||
((PIIOString *)dev)->setMode(PIIODevice::ReadOnly);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,18 @@ PIIOString::PIIOString(const PIString & string) {
|
||||
}
|
||||
|
||||
|
||||
void PIIOString::clear() {
|
||||
if (str) str->clear();
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
|
||||
bool PIIOString::open(PIString * string, PIIODevice::DeviceMode mode) {
|
||||
if (mode == PIIODevice::ReadWrite) {
|
||||
piCoutObj << "Error: ReadWrite mode not supported, use WriteOnly or ReadOnly";
|
||||
str = nullptr;
|
||||
return false;
|
||||
}
|
||||
str = string;
|
||||
return PIIODevice::open(mode);
|
||||
}
|
||||
@@ -53,26 +64,57 @@ bool PIIOString::open(const PIString & string) {
|
||||
}
|
||||
|
||||
|
||||
bool PIIOString::isEnd() const {
|
||||
if (!str) return true;
|
||||
if (mode_ == PIIODevice::WriteOnly)
|
||||
return pos >= str->size_s();
|
||||
else {
|
||||
str->dataUTF8();
|
||||
return pos >= static_cast<ssize_t>(str->lastDataSize());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIIOString::seekToBegin() {
|
||||
if (!str) return;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
|
||||
void PIIOString::seekToEnd() {
|
||||
if (!str) return;
|
||||
if (mode_ == PIIODevice::WriteOnly)
|
||||
pos = str->size_s();
|
||||
else {
|
||||
str->dataUTF8();
|
||||
pos = str->lastDataSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PIString PIIOString::readLine() {
|
||||
if (!canRead() || !str) return PIString();
|
||||
int np = pos;
|
||||
while (++np < str->size_s()) {
|
||||
if ((*str)[np] == '\n') break;
|
||||
auto utf8_data = str->dataUTF8();
|
||||
ssize_t utf8_size = str->lastDataSize();
|
||||
int pp = pos;
|
||||
while (++pp < utf8_size) {
|
||||
if (utf8_data[pp] == '\n') break;
|
||||
}
|
||||
PIString ret = str->mid(pos, np - pos);
|
||||
pos = piMini(np + 1, str->size_s());
|
||||
PIString ret = PIString::fromUTF8(&(utf8_data[pos]), pp - pos);
|
||||
pos = piMini(pp + 1, utf8_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ssize_t PIIOString::readDevice(void * read_to, ssize_t max_size) {
|
||||
if (!canRead() || !str || max_size <= 0) return -1;
|
||||
PIString rs = str->mid(pos, max_size);
|
||||
pos += max_size;
|
||||
if (pos > str->size_s()) pos = str->size_s();
|
||||
const char * cc = rs.data();
|
||||
int ret = strlen(cc);
|
||||
memcpy(read_to, cc, ret);
|
||||
auto utf8_data = str->dataUTF8();
|
||||
ssize_t utf8_size = str->lastDataSize();
|
||||
if (pos >= utf8_size) return 0;
|
||||
int ret = piMini(max_size, utf8_size - pos);
|
||||
if (ret <= 0) return 0;
|
||||
memcpy(read_to, &(utf8_data[pos]), ret);
|
||||
pos += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -98,6 +140,12 @@ int PIIOString::writeString(const PIString & string) {
|
||||
}
|
||||
|
||||
|
||||
ssize_t PIIOString::bytesAvailable() const {
|
||||
if (!str) return 0;
|
||||
return str->size() - pos;
|
||||
}
|
||||
|
||||
|
||||
bool PIIOString::openDevice() {
|
||||
pos = 0;
|
||||
return (str != 0);
|
||||
|
||||
@@ -39,7 +39,7 @@ class PIP_EXPORT PIIOString: public PIIODevice {
|
||||
public:
|
||||
//! \~english Contructs %PIIOString with "string" content and "mode" open mode
|
||||
//! \~russian Создает %PIIOString с содержимым "string" и режимом открытия "mode"
|
||||
explicit PIIOString(PIString * string = 0, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||
explicit PIIOString(PIString * string = 0, PIIODevice::DeviceMode mode = PIIODevice::ReadOnly);
|
||||
|
||||
//! \~english Contructs %PIIOString with "string" content only for read
|
||||
//! \~russian Создает %PIIOString с содержимым "string" только для чтения
|
||||
@@ -51,10 +51,7 @@ public:
|
||||
|
||||
//! \~english Clear content string
|
||||
//! \~russian Очищает содержимое строки
|
||||
void clear() {
|
||||
if (str) str->clear();
|
||||
pos = 0;
|
||||
}
|
||||
void clear();
|
||||
|
||||
//! \~english Open "string" content with "mode" open mode
|
||||
//! \~russian Открывает содержимое "string" с режимом открытия "mode"
|
||||
@@ -66,10 +63,7 @@ public:
|
||||
|
||||
//! \~english Returns if position is at the end of content
|
||||
//! \~russian Возвращает в конце содержимого ли позиция
|
||||
bool isEnd() const {
|
||||
if (!str) return true;
|
||||
return pos >= str->size_s();
|
||||
}
|
||||
bool isEnd() const;
|
||||
|
||||
|
||||
//! \~english Move read/write position to "position"
|
||||
@@ -78,15 +72,11 @@ public:
|
||||
|
||||
//! \~english Move read/write position to the beginning of the string
|
||||
//! \~russian Перемещает позицию чтения/записи на начало строки
|
||||
void seekToBegin() {
|
||||
if (str) pos = 0;
|
||||
}
|
||||
void seekToBegin();
|
||||
|
||||
//! \~english Move read/write position to the end of the string
|
||||
//! \~russian Перемещает позицию чтения/записи на конец строки
|
||||
void seekToEnd() {
|
||||
if (str) pos = str->size_s();
|
||||
}
|
||||
void seekToEnd();
|
||||
|
||||
|
||||
//! \~english Read one text line and return it
|
||||
@@ -97,12 +87,7 @@ public:
|
||||
//! \~russian Вставляет строку "string" в содержимое буфера в текущую позицию
|
||||
int writeString(const PIString & string);
|
||||
|
||||
ssize_t bytesAvailable() const override {
|
||||
if (str)
|
||||
return str->size() - pos;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
ssize_t bytesAvailable() const override;
|
||||
|
||||
protected:
|
||||
bool openDevice() override;
|
||||
|
||||
@@ -707,7 +707,7 @@ bool PISerial::openDevice() {
|
||||
PIString wp = "//./" + p;
|
||||
PRIVATE->hCom = CreateFileA(wp.dataAscii(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
|
||||
if (PRIVATE->hCom == INVALID_HANDLE_VALUE) {
|
||||
piCoutObj << "Unable to open \"" << p << "\"";
|
||||
piCoutObj << "Unable to open \"" << p << "\"" << errorString();
|
||||
fd = -1;
|
||||
return false;
|
||||
}
|
||||
@@ -770,11 +770,12 @@ void PISerial::applySettings() {
|
||||
GetCommMask(PRIVATE->hCom, &PRIVATE->mask);
|
||||
SetCommMask(PRIVATE->hCom, EV_RXCHAR);
|
||||
GetCommState(PRIVATE->hCom, &PRIVATE->sdesc);
|
||||
// piCoutObj << PRIVATE->sdesc.fBinary << PRIVATE->sdesc.fAbortOnError << PRIVATE->sdesc.fDsrSensitivity << PRIVATE->sdesc.fDtrControl
|
||||
//<< PRIVATE->sdesc.fDummy2 << PRIVATE->sdesc.fErrorChar;
|
||||
PRIVATE->desc = PRIVATE->sdesc;
|
||||
PRIVATE->desc.DCBlength = sizeof(PRIVATE->desc);
|
||||
PRIVATE->desc.BaudRate = convertSpeed(outSpeed());
|
||||
// piCoutObj << PRIVATE->sdesc.fBinary << PRIVATE->sdesc.fAbortOnError << PRIVATE->sdesc.fDsrSensitivity << PRIVATE->sdesc.fDtrControl
|
||||
// << PRIVATE->sdesc.fDummy2 << PRIVATE->sdesc.fErrorChar;
|
||||
PRIVATE->desc = PRIVATE->sdesc;
|
||||
PRIVATE->desc.DCBlength = sizeof(PRIVATE->desc);
|
||||
PRIVATE->desc.BaudRate = convertSpeed(outSpeed());
|
||||
PRIVATE->desc.fDtrControl = DTR_CONTROL_ENABLE;
|
||||
if (dataBitsCount() >= 5 && dataBitsCount() <= 8)
|
||||
PRIVATE->desc.ByteSize = dataBitsCount();
|
||||
else
|
||||
@@ -867,6 +868,13 @@ ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) {
|
||||
if (!canRead()) return -1;
|
||||
if (sending) return -1;
|
||||
// piCoutObj << "read ..." << PRIVATE->hCom << max_size;
|
||||
DWORD mask = 0;
|
||||
if (GetCommMask(PRIVATE->hCom, &mask) == FALSE) {
|
||||
piCoutObj << "read error" << errorString();
|
||||
stop();
|
||||
close();
|
||||
return 0;
|
||||
}
|
||||
memset(&(PRIVATE->overlap), 0, sizeof(PRIVATE->overlap));
|
||||
PRIVATE->overlap.hEvent = PRIVATE->event.getEvent();
|
||||
PRIVATE->readed = 0;
|
||||
@@ -884,8 +892,7 @@ ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) {
|
||||
GetOverlappedResult(PRIVATE->hCom, &(PRIVATE->overlap), &(PRIVATE->readed), FALSE);
|
||||
} else
|
||||
return -1;
|
||||
// piCoutObj << "read done" << PRIVATE->readed;
|
||||
// piCoutObj << "read" << (PRIVATE->readed) << errorString();
|
||||
// piCoutObj << "read" << (PRIVATE->readed) << errorString();
|
||||
return PRIVATE->readed;
|
||||
#else
|
||||
if (!canRead()) return -1;
|
||||
|
||||
@@ -292,6 +292,7 @@ bool PIPacketExtractor::threadedRead(const uchar * readed, ssize_t size_) {
|
||||
tmpbuf.append(dev->readForTime(time_));
|
||||
if (tmpbuf.size() > 0) {
|
||||
packetReceived(tmpbuf.data(), tmpbuf.size());
|
||||
tmpbuf.clear();
|
||||
}
|
||||
break;
|
||||
};
|
||||
@@ -305,13 +306,19 @@ PIString PIPacketExtractor::constructFullPathDevice() const {
|
||||
|
||||
|
||||
bool PIPacketExtractor::openDevice() {
|
||||
if (dev) return dev->open();
|
||||
if (dev) {
|
||||
if (!dev->isOpened()) return dev->open();
|
||||
return dev->isOpened();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PIPacketExtractor::closeDevice() {
|
||||
if (dev) return dev->close();
|
||||
if (dev) {
|
||||
if (dev->isOpened()) return dev->close();
|
||||
return !dev->isOpened();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,6 +144,18 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! \~english Returns value of chunk with ID \"id\". You should call \a readAll() before using this function!
|
||||
//! \~russian Возвращает значение чанка с ID \"id\". Необходимо вызвать \a readAll() перед использованием этого метода!
|
||||
template<typename T>
|
||||
T getData(int id) const {
|
||||
T ret{};
|
||||
CacheEntry pos = data_map.value(id);
|
||||
if (pos.start < 0 || pos.length == 0) return ret;
|
||||
PIByteArray ba(data_->data(pos.start), pos.length);
|
||||
if (!ba.isEmpty()) ba >> ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! \~english Place value of last readed chunk into \"v\"
|
||||
//! \~russian Записывает значение последнего прочитанного чанка в \"v\"
|
||||
template<typename T>
|
||||
|
||||
@@ -324,6 +324,7 @@ void PIString::appendFromChars(const char * c, int s, const char * codepage) {
|
||||
ucs2.copy((char16_t *)d.data(old_sz), ucs2.size());
|
||||
# endif
|
||||
#endif
|
||||
changed_ = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -455,6 +456,9 @@ PIString PIString::readableSize(llong bytes) {
|
||||
|
||||
|
||||
void PIString::buildData(const char * cp) const {
|
||||
if (!changed_ && (last_loc_ == cp) && data_) return;
|
||||
last_loc_ = cp;
|
||||
changed_ = false;
|
||||
deleteData();
|
||||
#ifdef PIP_ICU
|
||||
UErrorCode e((UErrorCode)0);
|
||||
@@ -464,7 +468,8 @@ void PIString::buildData(const char * cp) const {
|
||||
data_ = (char *)malloc(len);
|
||||
int sz = ucnv_fromUChars(cc, data_, len, (const UChar *)(d.data()), d.size_s(), &e);
|
||||
ucnv_close(cc);
|
||||
data_[sz] = '\0';
|
||||
data_[sz] = '\0';
|
||||
data_size_ = sz;
|
||||
return;
|
||||
}
|
||||
#else
|
||||
@@ -477,13 +482,15 @@ void PIString::buildData(const char * cp) const {
|
||||
}
|
||||
data_ = (char *)malloc(sz + 1);
|
||||
WideCharToMultiByte((uint)(uintptr_t)cp, 0, (LPCWCH)d.data(), d.size_s(), (LPSTR)data_, sz, NULL, NULL);
|
||||
data_[sz] = '\0';
|
||||
data_[sz] = '\0';
|
||||
data_size_ = sz;
|
||||
return;
|
||||
# else
|
||||
std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> ucs2conv;
|
||||
std::string u8str = ucs2conv.to_bytes((char16_t *)d.data(), (char16_t *)d.data() + d.size());
|
||||
data_ = (char *)malloc(u8str.size() + 1);
|
||||
strcpy(data_, u8str.c_str());
|
||||
data_size_ = u8str.size();
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
@@ -492,7 +499,8 @@ void PIString::buildData(const char * cp) const {
|
||||
void PIString::deleteData() const {
|
||||
if (!data_) return;
|
||||
free(data_);
|
||||
data_ = nullptr;
|
||||
data_ = nullptr;
|
||||
data_size_ = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -594,6 +602,7 @@ PIString & PIString::operator+=(const wchar_t * str) {
|
||||
while (str[++i]) {
|
||||
d.push_back(PIChar(str[i]));
|
||||
}
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -604,12 +613,14 @@ PIString & PIString::operator+=(const char16_t * str) {
|
||||
while (str[++i]) {
|
||||
d.push_back(PIChar(str[i]));
|
||||
}
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::operator+=(const PIString & str) {
|
||||
d.append(str.d);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -622,6 +633,7 @@ PIString & PIString::operator+=(const PIConstChars & str) {
|
||||
d[os + l] = str[l];
|
||||
}
|
||||
}
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -729,6 +741,7 @@ PIString & PIString::cutMid(int start, int len) {
|
||||
if (len > length() - start) len = length() - start;
|
||||
d.remove(start, len);
|
||||
}
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -781,6 +794,7 @@ PIString & PIString::replace(int from, int count, const PIString & with) {
|
||||
d.remove(from, count);
|
||||
d.insert(from, with.d);
|
||||
}
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -837,6 +851,7 @@ PIString & PIString::replaceAll(const PIString & what, const PIString & with) {
|
||||
i += dl;
|
||||
}
|
||||
}
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -863,6 +878,7 @@ PIString & PIString::replaceAll(const PIString & what, const char with) {
|
||||
if (dl > 0) d.remove(i, dl);
|
||||
d[i] = PIChar(with);
|
||||
}
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -879,6 +895,7 @@ PIString & PIString::replaceAll(const char what, const char with) {
|
||||
for (int i = 0; i < l; ++i) {
|
||||
if (at(i) == what) d[i] = with;
|
||||
}
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -898,12 +915,14 @@ PIString & PIString::removeAll(const PIString & str) {
|
||||
d.remove(i, l);
|
||||
i -= l;
|
||||
}
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::insert(int index, const PIString & str) {
|
||||
d.insert(index, str.d);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -920,6 +939,7 @@ PIString & PIString::elide(int size, float pos) {
|
||||
int ls = piRoundf(ns * pos);
|
||||
d.remove(ls, length() - ns);
|
||||
d.insert(ls, s_dotdot.d);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,10 +71,12 @@ public:
|
||||
|
||||
PIString & operator+=(const PIChar & c) {
|
||||
d.push_back(c);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
PIString & operator+=(const char c) {
|
||||
d.push_back(PIChar(c));
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
PIString & operator+=(const char * str);
|
||||
@@ -105,11 +107,17 @@ public:
|
||||
|
||||
//! \~english Contructs a copy of string.
|
||||
//! \~russian Создает копию строки.
|
||||
PIString(const PIString & o) { d = o.d; }
|
||||
PIString(const PIString & o) {
|
||||
d = o.d;
|
||||
changed_ = true;
|
||||
}
|
||||
|
||||
//! \~english Move constructor.
|
||||
//! \~russian Перемещающий конструктор.
|
||||
PIString(PIString && o): d(std::move(o.d)) { piSwap(data_, o.data_); }
|
||||
PIString(PIString && o): d(std::move(o.d)) {
|
||||
piSwap(data_, o.data_);
|
||||
changed_ = true;
|
||||
}
|
||||
|
||||
//! \~english Contructs string with single character "c".
|
||||
//! \~russian Создает строку из одного символа "c".
|
||||
@@ -197,7 +205,8 @@ public:
|
||||
//! \~russian Оператор присваивания.
|
||||
PIString & operator=(const PIString & o) {
|
||||
if (this == &o) return *this;
|
||||
d = o.d;
|
||||
d = o.d;
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -206,6 +215,7 @@ public:
|
||||
PIString & operator=(PIString && o) {
|
||||
d.swap(o.d);
|
||||
piSwap(data_, o.data_);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -367,7 +377,10 @@ public:
|
||||
//! \~russian Индекс элемента считается от `0`.
|
||||
//! Индекс символа должен лежать в пределах от `0` до `size()-1`.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
inline PIChar & operator[](size_t index) { return d[index]; }
|
||||
inline PIChar & operator[](size_t index) {
|
||||
changed_ = true;
|
||||
return d[index];
|
||||
}
|
||||
inline PIChar operator[](size_t index) const { return d[index]; }
|
||||
|
||||
//! \~english Read only access to character by `index`.
|
||||
@@ -383,10 +396,16 @@ public:
|
||||
|
||||
//! \~english Returns the last character of the string.
|
||||
//! \~russian Возвращает последний символ строки.
|
||||
inline PIChar & back() { return d.back(); }
|
||||
inline PIChar & back() {
|
||||
changed_ = true;
|
||||
return d.back();
|
||||
}
|
||||
inline PIChar back() const { return d.back(); }
|
||||
|
||||
inline PIChar & front() { return d.front(); }
|
||||
inline PIChar & front() {
|
||||
changed_ = true;
|
||||
return d.front();
|
||||
}
|
||||
inline PIChar front() const { return d.front(); }
|
||||
|
||||
//! \~english Sets size of the string, new characters are copied from `c`.
|
||||
@@ -402,6 +421,7 @@ public:
|
||||
//! \~\sa \a size(), \a clear()
|
||||
inline PIString & resize(size_t new_size, PIChar c = PIChar()) {
|
||||
d.resize(new_size, c);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -409,6 +429,7 @@ public:
|
||||
//! \~russian Удаляет один символ с конца строки.
|
||||
inline PIString & pop_back() {
|
||||
d.pop_back();
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -416,6 +437,7 @@ public:
|
||||
//! \~russian Удаляет один символ с начала строки.
|
||||
inline PIString & pop_front() {
|
||||
d.pop_front();
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -423,6 +445,7 @@ public:
|
||||
//! \~russian Удаляет символы из строки, начиная с позиции `index` в количестве `count`.
|
||||
inline PIString & remove(size_t index, size_t count = 1) {
|
||||
d.remove(index, count);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -430,6 +453,7 @@ public:
|
||||
//! \~russian Заполняет всю строку символами `c`.
|
||||
inline PIString & fill(PIChar c = PIChar()) {
|
||||
d.fill(c);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -444,6 +468,7 @@ public:
|
||||
//! \~russian Вставляет "str" в начало строки.
|
||||
PIString & prepend(const PIString & str) {
|
||||
d.prepend(str.d);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -451,6 +476,7 @@ public:
|
||||
//! \~russian Вставляет символ `c` в начало строки.
|
||||
PIString & prepend(const PIChar c) {
|
||||
d.prepend(c);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -458,6 +484,7 @@ public:
|
||||
//! \~russian Вставляет символ `c` в начало строки.
|
||||
PIString & prepend(const char c) {
|
||||
d.prepend(PIChar(c));
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -465,6 +492,7 @@ public:
|
||||
//! \~russian Вставляет "str" в начало строки.
|
||||
PIString & push_front(const char * str) {
|
||||
insert(0, str);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -479,6 +507,7 @@ public:
|
||||
//! \~russian Вставляет "str" в начало строки.
|
||||
PIString & push_front(const PIString & str) {
|
||||
d.push_front(str.d);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -486,6 +515,7 @@ public:
|
||||
//! \~russian Вставляет символ `c` в начало строки.
|
||||
PIString & push_front(const PIChar c) {
|
||||
d.push_front(c);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -493,6 +523,7 @@ public:
|
||||
//! \~russian Вставляет символ `c` в начало строки.
|
||||
PIString & push_front(const char c) {
|
||||
d.push_front(PIChar(c));
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -514,6 +545,7 @@ public:
|
||||
//! \~russian Вставляет "str" в конец строки.
|
||||
PIString & append(const PIString & str) {
|
||||
d.append(str.d);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -526,6 +558,7 @@ public:
|
||||
//! \~russian Вставляет символ `c` в конец строки.
|
||||
PIString & append(const PIChar c) {
|
||||
d.append(c);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -533,6 +566,7 @@ public:
|
||||
//! \~russian Вставляет символ `c` в конец строки.
|
||||
PIString & append(const char c) {
|
||||
d.append(PIChar(c));
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -547,6 +581,7 @@ public:
|
||||
//! \~russian Вставляет "str" в конец строки.
|
||||
PIString & push_back(const PIString & str) {
|
||||
d.push_back(str.d);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -559,6 +594,7 @@ public:
|
||||
//! \~russian Вставляет символ `c` в конец строки.
|
||||
PIString & push_back(const PIChar c) {
|
||||
d.push_back(c);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -566,6 +602,7 @@ public:
|
||||
//! \~russian Вставляет символ `c` в конец строки.
|
||||
PIString & push_back(const char c) {
|
||||
d.push_back(PIChar(c));
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -741,6 +778,7 @@ public:
|
||||
//! \~russian Удаляет все найденные символы "what", возвращает эту строку.
|
||||
PIString & removeAll(char c) {
|
||||
d.removeAll(PIChar(c));
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -757,6 +795,7 @@ public:
|
||||
PIString ss(*this);
|
||||
times--;
|
||||
piForTimes(times) * this += ss;
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -784,6 +823,7 @@ public:
|
||||
//! \endcode
|
||||
PIString & insert(const int index, const PIChar c) {
|
||||
d.insert(index, c);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -840,6 +880,7 @@ public:
|
||||
//! \~\sa \a expandLeftTo(), \a expandedRightTo(), \a expandedLeftTo()
|
||||
PIString & expandRightTo(const int len, const PIChar c) {
|
||||
if (len > d.size_s()) d.resize(len, c);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -856,6 +897,7 @@ public:
|
||||
//! \~\sa \a expandRightTo(), \a expandedRightTo(), \a expandedLeftTo()
|
||||
PIString & expandLeftTo(const int len, const PIChar c) {
|
||||
if (len > d.size_s()) insert(0, PIString(len - d.size_s(), c));
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -893,6 +935,7 @@ public:
|
||||
PIString & quote(PIChar c = PIChar('"')) {
|
||||
d.prepend(c);
|
||||
d.append(c);
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -918,6 +961,7 @@ public:
|
||||
//! \~\sa \a reversed()
|
||||
PIString & reverse() {
|
||||
d.reverse();
|
||||
changed_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1051,6 +1095,10 @@ public:
|
||||
//! \~russian Возвращает \c char * представление строки в кодировке ASCII.
|
||||
const char * dataAscii() const;
|
||||
|
||||
//! \~english Returns data size of last data*() call.
|
||||
//! \~russian Возвращает размер данных последнего вызова data*().
|
||||
const size_t lastDataSize() const { return data_size_; }
|
||||
|
||||
//! \~english Returns hash of string
|
||||
//! \~russian Возвращает хэш строки
|
||||
uint hash() const;
|
||||
@@ -1279,7 +1327,10 @@ public:
|
||||
//! \~english Reserved memory will not be released.
|
||||
//! \~russian Зарезервированная память не освободится.
|
||||
//! \~\sa \a resize()
|
||||
void clear() { d.clear(); }
|
||||
void clear() {
|
||||
d.clear();
|
||||
changed_ = true;
|
||||
}
|
||||
|
||||
//! \~english Returns \c true if string equal "true", "yes", "on" or positive not null numeric value.
|
||||
//! \~russian Возвращает \c true если строка равна "true", "yes", "on" или числу > 0.
|
||||
@@ -1804,7 +1855,10 @@ private:
|
||||
void trimsubstr(int & st, int & fn) const;
|
||||
|
||||
PIDeque<PIChar> d;
|
||||
mutable char * data_ = nullptr;
|
||||
mutable bool changed_ = true;
|
||||
mutable const char * last_loc_ = nullptr;
|
||||
mutable char * data_ = nullptr;
|
||||
mutable size_t data_size_ = 0;
|
||||
};
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
@@ -1820,6 +1874,7 @@ BINARY_STREAM_WRITE(PIString) {
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ(PIString) {
|
||||
s >> v.d;
|
||||
v.changed_ = true;
|
||||
if (s.wasReadError()) v.clear();
|
||||
return s;
|
||||
}
|
||||
|
||||
22
main.cpp
22
main.cpp
@@ -5,20 +5,22 @@
|
||||
#include "piliterals_time.h"
|
||||
#include "pimathbase.h"
|
||||
#include "pip.h"
|
||||
#include "pivaluetree.h"
|
||||
#include "pivaluetree_conversions.h"
|
||||
|
||||
using namespace PICoutManipulators;
|
||||
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
// PICodeParser cp;
|
||||
// cp.parseFile("kmm_types.h", false);
|
||||
piCout << (1_Hz * 100).toSystemTime().toSeconds();
|
||||
piCout << (1_Hz * 100);
|
||||
piCout << (1_Hz + 10_GHz);
|
||||
piCout << (100_Hz + 1_KHz - 10_Hz);
|
||||
piCout << PISystemTime::Frequency::fromSystemTime({0, 200000000});
|
||||
piCout << PISystemTime::Frequency::fromSystemTime(25_ms);
|
||||
piCout << PISystemTime::Frequency::fromSystemTime(25_ms).toSystemTime().toMilliseconds();
|
||||
/*PISerial ser;
|
||||
ser.setSpeed(PISerial::S115200);
|
||||
piCout << ser.open("COM15", PIIODevice::ReadWrite);
|
||||
CONNECTL(&ser, threadedReadEvent, ([](const uchar * data, ssize_t size) { piCout << PIByteArray(data, size); }));
|
||||
ser.startThreadedRead();
|
||||
(2_s).sleep();
|
||||
ser.stopAndWait();*/
|
||||
PISet<int> set = {1, 3, 4};
|
||||
set |= PISet<int>{2, 4};
|
||||
set -= PISet<int>{2};
|
||||
piCout << set << (set & PISet<int>{1, 2, 4});
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -285,10 +285,10 @@ int main(int argc, char * argv[]) {
|
||||
ts << "<context>\n";
|
||||
ts << " <name>" << context << "</name>\n";
|
||||
for (const auto & s: strings) {
|
||||
TSMessage m = old.value(s.first);
|
||||
m.filename = locations.value(s.first.hash());
|
||||
writeTSMessage(s.first, m);
|
||||
old.remove(s.first);
|
||||
TSMessage m = old.value(s);
|
||||
m.filename = locations.value(s.hash());
|
||||
writeTSMessage(s, m);
|
||||
old.remove(s);
|
||||
}
|
||||
if (!cli.hasArgument("no-obsolete")) {
|
||||
for (const auto & i: old) {
|
||||
|
||||
Reference in New Issue
Block a user