folders
This commit is contained in:
@@ -1,534 +0,0 @@
|
||||
/*! \file pibinarystream.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english Binary serialization interface
|
||||
* \~russian Интерфейс бинарной сериализации
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Binary serialization interface
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIBINARYSTREAM_H
|
||||
#define PIBINARYSTREAM_H
|
||||
|
||||
#include "pimemoryblock.h"
|
||||
#include "pibitarray.h"
|
||||
#include "pimap.h"
|
||||
#include "pivector2d.h"
|
||||
|
||||
#define PIP_BINARY_STREAM
|
||||
|
||||
#define BINARY_STREAM_FRIEND(T) \
|
||||
template<typename P> friend PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const T & v); \
|
||||
template<typename P> friend PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, T & v);
|
||||
#define BINARY_STREAM_WRITE(T) \
|
||||
template<typename P> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const T & v)
|
||||
#define BINARY_STREAM_READ(T) \
|
||||
template<typename P> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, T & v)
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Binary serialization interface.
|
||||
//! \~russian Интерфейс бинарной сериализации.
|
||||
//! \~\details
|
||||
//! \~english In your class you should implement this methods:
|
||||
//! \~russian В производном классе вы должны реализовать следующие методы:
|
||||
//! \~\code
|
||||
//! bool binaryStreamAppendImp (const void * d, size_t s);
|
||||
//! bool binaryStreamTakeImp (void * d, size_t s);
|
||||
//! ssize_t binaryStreamSizeImp () const;
|
||||
//! \endcode
|
||||
//! \~english Function binaryStreamSizeImp should return -1 if size unknown.
|
||||
//! \~russian Функция binaryStreamSizeImp должна возвращать -1 если нет информации о размере.
|
||||
//! \~english See details \ref iostream.
|
||||
//! \~russian Подробнее \ref iostream.
|
||||
template<typename P>
|
||||
class PIBinaryStream {
|
||||
public:
|
||||
//! \~russian Записать данные
|
||||
bool binaryStreamAppend(const void * d, size_t s) {
|
||||
if (!static_cast<P*>(this)->binaryStreamAppendImp(d, s)) {
|
||||
return false;
|
||||
printf("[PIBinaryStream] binaryStreamAppend() error\n");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//! \~russian Прочитать данные
|
||||
bool binaryStreamTake(void * d, size_t s) {
|
||||
if (!static_cast<P*>(this)->binaryStreamTakeImp(d, s)) {
|
||||
return false;
|
||||
printf("[PIBinaryStream] binaryStreamTake() error\n");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//! \~russian Узнать оставшийся размер
|
||||
//!\~\details
|
||||
//!\~russian Возвращает -1 если нет информации о размере
|
||||
ssize_t binaryStreamSize() const {
|
||||
return static_cast<const P*>(this)->binaryStreamSizeImp();
|
||||
}
|
||||
|
||||
//! \~russian Записать данные
|
||||
template<typename T>
|
||||
void binaryStreamAppend(T v) {binaryStreamAppend(&v, sizeof(v));}
|
||||
|
||||
//! \~russian Прочитать int
|
||||
int binaryStreamTakeInt() {
|
||||
int r = 0;
|
||||
binaryStreamTake(&r, sizeof(r));
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// helper class to detect default operators
|
||||
template<typename P>
|
||||
class PIBinaryStreamTrivialRef {
|
||||
public:
|
||||
PIBinaryStreamTrivialRef(PIBinaryStream<P> & s): p(s) {}
|
||||
PIBinaryStream<P> & p;
|
||||
};
|
||||
|
||||
|
||||
template<typename P, typename T> inline PIBinaryStream<P> & operator <<(PIBinaryStreamTrivialRef<P> s, const T & v) {
|
||||
s.p << v;
|
||||
return s.p;
|
||||
}
|
||||
template<typename P, typename T> inline PIBinaryStream<P> & operator >>(PIBinaryStreamTrivialRef<P> s, T & v) {
|
||||
s.p >> v;
|
||||
return s.p;
|
||||
}
|
||||
|
||||
template<typename P> inline PIBinaryStream<P> & operator <<(PIBinaryStreamTrivialRef<P> s, const PIMemoryBlock v) {
|
||||
s.p << v;
|
||||
return s.p;
|
||||
}
|
||||
template<typename P> inline PIBinaryStream<P> & operator >>(PIBinaryStreamTrivialRef<P> s, PIMemoryBlock v) {
|
||||
s.p >> v;
|
||||
return s.p;
|
||||
}
|
||||
|
||||
|
||||
// specify types
|
||||
template<typename P> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const bool v) {
|
||||
s.binaryStreamAppend((uchar)v);
|
||||
return s;
|
||||
}
|
||||
template<typename P> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, bool & v) {
|
||||
uchar c;
|
||||
s.binaryStreamTake(&c, sizeof(c));
|
||||
v = c;
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename P> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIMemoryBlock v) {
|
||||
s.binaryStreamAppend(v.data(), v.size());
|
||||
return s;
|
||||
}
|
||||
template<typename P> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIMemoryBlock v) {
|
||||
s.binaryStreamTake(v.data(), v.size());
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// store simple types
|
||||
|
||||
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const T & v) {
|
||||
//piCout << "<< enum";
|
||||
s.binaryStreamAppend((int)v);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if<!std::is_enum<T>::value, int>::type = 0,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline PIBinaryStreamTrivialRef<P> operator <<(PIBinaryStream<P> & s, const T & v) {
|
||||
s.binaryStreamAppend(&v, sizeof(v));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Store operator for PIVector of any trivial copyable type
|
||||
//! \~russian Оператор сохранения для PIVector тривиальных типов
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector<T> & v) {
|
||||
//piCout << "<< vector trivial default";
|
||||
s.binaryStreamAppend((int)v.size());
|
||||
s.binaryStreamAppend(v.data(), v.size() * sizeof(T));
|
||||
return s;
|
||||
}
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector<T> & v) {
|
||||
//piCout << "<< vector trivial custom";
|
||||
s.binaryStreamAppend((int)v.size());
|
||||
for (size_t i = 0; i < v.size(); ++i) s << v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Store operator for PIDeque of any trivial copyable type
|
||||
//! \~russian Оператор сохранения для PIDeque тривиальных типов
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
|
||||
//piCout << "<< deque trivial default";
|
||||
s.binaryStreamAppend((int)v.size());
|
||||
s.binaryStreamAppend(v.data(), v.size() * sizeof(T));
|
||||
return s;
|
||||
}
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
|
||||
//piCout << "<< deque trivial custom";
|
||||
s.binaryStreamAppend((int)v.size());
|
||||
for (size_t i = 0; i < v.size(); ++i) s << v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Store operator for PIVector2D of any trivial copyable type
|
||||
//! \~russian Оператор сохранения для PIVector2D тривиальных типов
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
|
||||
//piCout << "<< vector2d trivial default";
|
||||
s.binaryStreamAppend((int)v.rows());
|
||||
s.binaryStreamAppend((int)v.cols());
|
||||
s.binaryStreamAppend(v.data(), v.size() * sizeof(T));
|
||||
return s;
|
||||
}
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
|
||||
//piCout << "<< vector2d trivial custom";
|
||||
s.binaryStreamAppend((int)v.rows());
|
||||
s.binaryStreamAppend((int)v.cols());
|
||||
s << v.toPlainVector();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Store operator
|
||||
//! \~russian Оператор сохранения
|
||||
template<typename P>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;}
|
||||
|
||||
|
||||
//! \~english Store operator
|
||||
//! \~russian Оператор сохранения
|
||||
template<typename P, typename Type0, typename Type1>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIPair<Type0, Type1> & v) {s << v.first << v.second; return s;}
|
||||
|
||||
|
||||
|
||||
|
||||
// restore simple types
|
||||
|
||||
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, T & v) {
|
||||
//piCout << ">> enum";
|
||||
v = (T)s.binaryStreamTakeInt();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if<!std::is_enum<T>::value, int>::type = 0,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline PIBinaryStreamTrivialRef<P> operator >>(PIBinaryStream<P> & s, T & v) {
|
||||
if (!s.binaryStreamTake(&v, sizeof(v))) {
|
||||
printf("error with %s\n", __PIP_TYPENAME__(T));
|
||||
assert(false);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Restore operator for PIVector of any trivial copyable type
|
||||
//! \~russian Оператор извлечения для PIVector тривиальных типов
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
|
||||
//piCout << ">> vector trivial default";
|
||||
int sz = s.binaryStreamTakeInt();
|
||||
v._resizeRaw(sz);
|
||||
if (!s.binaryStreamTake(v.data(), sz * sizeof(T))) {
|
||||
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
|
||||
assert(false);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
|
||||
//piCout << ">> vector trivial custom";
|
||||
int sz = s.binaryStreamTakeInt();
|
||||
v._resizeRaw(sz);
|
||||
for (int i = 0; i < sz; ++i) s >> v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Restore operator for PIDeque of any trivial copyable type
|
||||
//! \~russian Оператор извлечения для PIDeque тривиальных типов
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
|
||||
//piCout << ">> deque trivial default";
|
||||
int sz = s.binaryStreamTakeInt();
|
||||
v._resizeRaw(sz);
|
||||
if (!s.binaryStreamTake(v.data(), sz * sizeof(T))) {
|
||||
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
|
||||
assert(false);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
|
||||
//piCout << ">> deque trivial custom";
|
||||
int sz = s.binaryStreamTakeInt();
|
||||
v._resizeRaw(sz);
|
||||
for (int i = 0; i < sz; ++i) s >> v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Restore operator for PIVector2D of any trivial copyable type
|
||||
//! \~russian Оператор извлечения для PIVector2D тривиальных типов
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
|
||||
//piCout << ">> vector2d trivial default";
|
||||
int r, c;
|
||||
r = s.binaryStreamTakeInt();
|
||||
c = s.binaryStreamTakeInt();
|
||||
v._resizeRaw(r, c);
|
||||
if (!s.binaryStreamTake(v.data(), v.size() * sizeof(T))) {
|
||||
printf("error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
|
||||
assert(false);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
template<typename P, typename T,
|
||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
|
||||
//piCout << ">> vector2d trivial custom";
|
||||
int r, c;
|
||||
PIVector<T> tmp;
|
||||
r = s.binaryStreamTakeInt();
|
||||
c = s.binaryStreamTakeInt();
|
||||
s >> tmp;
|
||||
v = PIVector2D<T>(r, c, tmp);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Restore operator
|
||||
//! \~russian Оператор извлечения
|
||||
template<typename P>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIBitArray & v) {s >> v.size_ >> v.data_; return s;}
|
||||
|
||||
|
||||
//! \~english Restore operator
|
||||
//! \~russian Оператор извлечения
|
||||
template<typename P, typename Type0, typename Type1>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIPair<Type0, Type1> & v) {s >> v.first >> v.second; return s;}
|
||||
|
||||
|
||||
|
||||
|
||||
// store complex types
|
||||
|
||||
|
||||
//! \~english Store operator for PIVector of any compound type
|
||||
//! \~russian Оператор сохранения для PIVector сложных типов
|
||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector<T> & v) {
|
||||
//piCout << "<< vector complex";
|
||||
s.binaryStreamAppend(int(v.size_s()));
|
||||
for (size_t i = 0; i < v.size(); ++i) s << v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Store operator for PIDeque of any compound type
|
||||
//! \~russian Оператор сохранения для PIDeque сложных типов
|
||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
|
||||
//piCout << "<< deque complex";
|
||||
s.binaryStreamAppend(int(v.size_s()));
|
||||
for (size_t i = 0; i < v.size(); ++i) s << v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Store operator for PIVector2D of any compound type
|
||||
//! \~russian Оператор сохранения для PIVector2D сложных типов
|
||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
|
||||
//piCout << "<< vector2d complex";
|
||||
s.binaryStreamAppend(int(v.rows()));
|
||||
s.binaryStreamAppend(int(v.cols()));
|
||||
s << v.toPlainVector();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// restore complex types
|
||||
|
||||
|
||||
//! \~english Restore operator for PIVector of any compound type
|
||||
//! \~russian Оператор извлечения для PIVector сложных типов
|
||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
|
||||
//piCout << ">> vector complex";
|
||||
/*if (s.size_s() < 4) {
|
||||
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
|
||||
assert(s.size_s() >= 4);
|
||||
}*/
|
||||
v.resize(s.binaryStreamTakeInt());
|
||||
for (size_t i = 0; i < v.size(); ++i) s >> v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Restore operator for PIDeque of any compound type
|
||||
//! \~russian Оператор извлечения для PIDeque сложных типов
|
||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
|
||||
//piCout << ">> deque complex";
|
||||
/*if (s.size_s() < 4) {
|
||||
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
|
||||
assert(s.size_s() >= 4);
|
||||
}*/
|
||||
v.resize(s.binaryStreamTakeInt());
|
||||
for (size_t i = 0; i < v.size(); ++i) s >> v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Restore operator for PIVector2D of any compound type
|
||||
//! \~russian Оператор извлечения для PIVector2D сложных типов
|
||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
|
||||
//piCout << ">> vector2d complex";
|
||||
/*if (s.size_s() < 8) {
|
||||
printf("error with PIVecto2Dr<%s>\n", __PIP_TYPENAME__(T));
|
||||
assert(s.size_s() >= 8);
|
||||
}*/
|
||||
int r, c;
|
||||
PIVector<T> tmp;
|
||||
r = s.binaryStreamTakeInt();
|
||||
c = s.binaryStreamTakeInt();
|
||||
s >> tmp;
|
||||
v = PIVector2D<T>(r, c, tmp);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// other types
|
||||
|
||||
|
||||
//! \~english Store operator
|
||||
//! \~russian Оператор сохранения
|
||||
template <typename P, typename Key, typename T>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIMap<Key, T> & v) {
|
||||
s.binaryStreamAppend((int)v.pim_index.size_s());
|
||||
for (uint i = 0; i < v.size(); ++i) {
|
||||
s.binaryStreamAppend((int)v.pim_index[i].index);
|
||||
s << v.pim_index[i].key;
|
||||
}
|
||||
s << v.pim_content;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Restore operator
|
||||
//! \~russian Оператор извлечения
|
||||
template <typename P, typename Key, typename T>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIMap<Key, T> & v) {
|
||||
/*if (s.size_s() < 4) {
|
||||
printf("error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
|
||||
assert(s.size_s() >= 4);
|
||||
}*/
|
||||
int sz = s.binaryStreamTakeInt(); v.pim_index.resize(sz);
|
||||
int ind = 0;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
ind = s.binaryStreamTakeInt();
|
||||
s >> v.pim_index[i].key;
|
||||
v.pim_index[i].index = ind;
|
||||
}
|
||||
s >> v.pim_content;
|
||||
if (v.pim_content.size_s() != v.pim_index.size_s()) {
|
||||
piCout << "Warning: loaded invalid PIMap, clear";
|
||||
v.clear();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// non-defined complex types
|
||||
|
||||
|
||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const T & ) {
|
||||
static_assert(std::is_trivially_copyable<T>::value, "[PIBinaryStream] Error: using undeclared operator << for complex type!");
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, T & ) {
|
||||
static_assert(std::is_trivially_copyable<T>::value, "[PIBinaryStream] Error: using undeclared operator >> for complex type!");
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Bit array
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pibitarray.h"
|
||||
#include "picout.h"
|
||||
|
||||
|
||||
PICout operator <<(PICout s, const PIBitArray & ba) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
for (uint i = 0; i < ba.bitSize(); ++i) {
|
||||
s << int(ba[i]);
|
||||
if (i % 8 == 7) s << ' ';
|
||||
}
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef PIP_STD_IOSTREAM
|
||||
std::ostream &operator <<(std::ostream & s, const PIBitArray & ba) {
|
||||
for (uint i = 0; i < ba.bitSize(); ++i) {
|
||||
s << ba[i];
|
||||
if (i % 8 == 7) s << ' ';
|
||||
}
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
/*! \file pibitarray.h
|
||||
* \~\brief
|
||||
* \~english Bit array
|
||||
* \~russian Битовый массив
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Bit array
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIBITARRAY_H
|
||||
#define PIBITARRAY_H
|
||||
|
||||
#include "pivector.h"
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english The %PIBitArray class provides an space-efficient array of bits.
|
||||
//! \~russian Класс %PIBitArray представляет собой компактный массив битов.
|
||||
class PIP_EXPORT PIBitArray {
|
||||
template <typename P>
|
||||
friend PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIBitArray & v);
|
||||
template <typename P>
|
||||
friend PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIBitArray & v);
|
||||
public:
|
||||
|
||||
//! \~english Constructs bit array with "size" size.
|
||||
//! \~russian Создает битовый массив с размером "size".
|
||||
PIBitArray(const int & size = 0) {resize(size);}
|
||||
|
||||
//! \~english Constructs bit array with size 8 and values from "val".
|
||||
//! \~russian Создает битовый массив с размером 8 и значениями из "val".
|
||||
PIBitArray(uchar val) {resize(sizeof(val) * 8); data_[0] = val;}
|
||||
|
||||
//! \~english Constructs bit array with size 16 and values from "val".
|
||||
//! \~russian Создает битовый массив с размером 16 и значениями из "val".
|
||||
PIBitArray(ushort val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
|
||||
|
||||
//! \~english Constructs bit array with size 32 and values from "val".
|
||||
//! \~russian Создает битовый массив с размером 32 и значениями из "val".
|
||||
PIBitArray(uint val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
|
||||
|
||||
//! \~english Constructs bit array with size 64 and values from "val".
|
||||
//! \~russian Создает битовый массив с размером 64 и значениями из "val".
|
||||
PIBitArray(ullong val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
|
||||
|
||||
//! \~english Constructs bit array with size "bytes * 8" and values from "data".
|
||||
//! \~russian Создает битовый массив с размером "bytes * 8" и значениями из "data".
|
||||
PIBitArray(const uchar * data, uint bytes) {resize(bytes * 8); memcpy(this->data(), data, bytes);}
|
||||
|
||||
|
||||
//! \~english Returns a size in bits.
|
||||
//! \~russian Возвращает размер в битах.
|
||||
uint bitSize() const {return size_;}
|
||||
|
||||
//! \~english Returns a size in bytes.
|
||||
//! \~russian Возвращает размер в байтах.
|
||||
uint byteSize() const {return bytesInBits(size_);}
|
||||
|
||||
//! \~english Resize this array to "size" bits.
|
||||
//! \~russian Изменяет размер массива до "size" битов.
|
||||
PIBitArray & resize(const uint & size) {size_ = size; data_.resize(bytesInBits(size_)); return *this;}
|
||||
|
||||
|
||||
//! \~english Set bit with index "index" to 0.
|
||||
//! \~russian Устанавливает бит с индексом "index" в 0.
|
||||
PIBitArray & clearBit(const uint & index) {data_[index / 8] &= ~(1 << (index % 8)); return *this;}
|
||||
|
||||
//! \~english Set bit with index "index" to 1.
|
||||
//! \~russian Устанавливает бит с индексом "index" в 1.
|
||||
PIBitArray & setBit(const uint & index) {data_[index / 8] |= (1 << (index % 8)); return *this;}
|
||||
|
||||
//! \~english Set bit with index "index" to "value".
|
||||
//! \~russian Устанавливает бит с индексом "index" в "value".
|
||||
PIBitArray & writeBit(const uint & index, const bool & value) {if (value) setBit(index); else clearBit(index); return *this;}
|
||||
|
||||
//! \~english Set bit with index "index" to "value".
|
||||
//! \~russian Устанавливает бит с индексом "index" в "value".
|
||||
PIBitArray & writeBit(const uint & index, const uchar & value) {return writeBit(index, value > 0);}
|
||||
|
||||
|
||||
//! \~english Add bit with value "value" to the end of array.
|
||||
//! \~russian Добавляет бит со значением "value" в конец массива.
|
||||
PIBitArray & push_back(const bool & value) {resize(size_ + 1); writeBit(size_ - 1, value); return *this;}
|
||||
|
||||
//! \~english Add bit with value "value" to the end of array.
|
||||
//! \~russian Добавляет бит со значением "value" в конец массива.
|
||||
PIBitArray & push_back(const uchar & value) {return push_back(value > 0);}
|
||||
|
||||
//! \~english Insert bit with value "value" after "index" position.
|
||||
//! \~russian Вставляет бит со значением "value" после положения "index".
|
||||
PIBitArray & insert(const uint & index, const bool & value) {
|
||||
resize(size_ + 1);
|
||||
uint fi = byteSize() - 1, si = index / 8, ti = index % 8;
|
||||
uchar c = data_[si];
|
||||
for (uint i = fi; i > si; --i) {
|
||||
data_[i] <<= 1;
|
||||
if ((0x80 & data_[i - 1]) == 0x80) data_[i] |= 1;
|
||||
else data_[i] &= 0xFE;}
|
||||
data_[si] &= (0xFF >> (7 - ti));
|
||||
data_[si] |= ((c << 1) & (0xFF << (ti)));
|
||||
if (value) data_[si] |= (1 << ti);
|
||||
else data_[si] &= ~(1 << ti);
|
||||
return *this;}
|
||||
|
||||
//! \~english Insert bit with value "value" after "index" position.
|
||||
//! \~russian Вставляет бит со значением "value" после положения "index".
|
||||
PIBitArray & insert(const uint & index, const uchar & value) {return insert(index, value > 0);}
|
||||
|
||||
//! \~english Add bit with value "value" to the beginning of array.
|
||||
//! \~russian Добавляет бит со значением "value" в начало массива.
|
||||
PIBitArray & push_front(const bool & value) {return insert(0, value);}
|
||||
|
||||
//! \~english Add bit with value "value" to the beginning of array.
|
||||
//! \~russian Добавляет бит со значением "value" в начало массива.
|
||||
PIBitArray & push_front(const uchar & value) {return push_front(value > 0);}
|
||||
|
||||
//! \~english Remove one bit from the end of array.
|
||||
//! \~russian Удаляет один бит с конца массива.
|
||||
PIBitArray & pop_back() {return resize(size_ - 1);}
|
||||
|
||||
//! \~english Remove one bit from the beginning of array.
|
||||
//! \~russian Удаляет один бит с начала массива.
|
||||
PIBitArray & pop_front() {
|
||||
if (size_ == 0) return *this;
|
||||
uint fi = byteSize() - 1;
|
||||
for (uint i = 0; i < fi; ++i) {
|
||||
data_[i] >>= 1;
|
||||
if ((1 & data_[i + 1]) == 1) data_[i] |= 0x80;
|
||||
else data_[i] &= 0x7F;}
|
||||
data_[fi] >>= 1;
|
||||
resize(size_ - 1);
|
||||
return *this;}
|
||||
|
||||
//! \~english Add bits "ba" to the end of array.
|
||||
//! \~russian Добавляет биты "ba" в конец массива.
|
||||
PIBitArray & append(const PIBitArray & ba) {for (uint i = 0; i < ba.bitSize(); ++i) push_back(ba[i]); return *this;}
|
||||
|
||||
|
||||
//! \~english Returns pointer to bytes data of array.
|
||||
//! \~russian Возвращает указатель на байтовое содержимое массива.
|
||||
uchar * data() {return data_.data();}
|
||||
|
||||
//! \~english Returns data of array as \b uchar.
|
||||
//! \~russian Возвращает байтовое содержимое массива как \b uchar.
|
||||
uchar toUChar() {if (size_ == 0) return 0; return data_[0];}
|
||||
|
||||
//! \~english Returns data of array as \b ushort.
|
||||
//! \~russian Возвращает байтовое содержимое массива как \b ushort.
|
||||
ushort toUShort() {ushort t = 0; memcpy(&t, data(), piMin<uint>(byteSize(), sizeof(t))); return t;}
|
||||
|
||||
//! \~english Returns data of array as \b uint.
|
||||
//! \~russian Возвращает байтовое содержимое массива как \b uint.
|
||||
uint toUInt() {uint t = 0; memcpy(&t, data(), piMin<uint>(byteSize(), sizeof(t))); return t;}
|
||||
|
||||
//! \~english Returns data of array as \b ullong.
|
||||
//! \~russian Возвращает байтовое содержимое массива как \b ullong.
|
||||
ullong toULLong() {ullong t = 0; memcpy(&t, data(), piMin<uint>(byteSize(), sizeof(t))); return t;}
|
||||
|
||||
|
||||
//! \~english Returns bit value at index "index".
|
||||
//! \~russian Возвращает значение бита с индексом "index".
|
||||
bool at(const uint & index) const {return (1 & (data_[index / 8] >> (index % 8))) == 1 ? true : false;}
|
||||
|
||||
//! \~english Returns bit value at index "index".
|
||||
//! \~russian Возвращает значение бита с индексом "index".
|
||||
bool operator [](const uint & index) const {return at(index);}
|
||||
|
||||
//! \~english Similar to \a append().
|
||||
//! \~russian Аналог \a append().
|
||||
void operator +=(const PIBitArray & ba) {append(ba);}
|
||||
|
||||
//! \~english Returns if two bit arrays are similar.
|
||||
//! \~russian Возвращает равны ли для битовых массива.
|
||||
bool operator ==(const PIBitArray & ba) const {if (bitSize() != ba.bitSize()) return false; for (uint i = 0; i < bitSize(); ++i) if (at(i) != ba[i]) return false; return true;}
|
||||
|
||||
//! \~english Returns if two bit arrays are not similar.
|
||||
//! \~russian Возвращает не равны ли для битовых массива.
|
||||
bool operator !=(const PIBitArray & ba) const {return !(*this == ba);}
|
||||
|
||||
//! \~english Resize and set values from "val".
|
||||
//! \~russian Изменяет размер и устанавливает значения из "val".
|
||||
void operator =(const uchar & val) {resize(sizeof(val) * 8); data_[0] = val;}
|
||||
|
||||
//! \~english Resize and set values from "val".
|
||||
//! \~russian Изменяет размер и устанавливает значения из "val".
|
||||
void operator =(const ushort & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
|
||||
|
||||
//! \~english Resize and set values from "val".
|
||||
//! \~russian Изменяет размер и устанавливает значения из "val".
|
||||
void operator =(const uint & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
|
||||
|
||||
//! \~english Resize and set values from "val".
|
||||
//! \~russian Изменяет размер и устанавливает значения из "val".
|
||||
void operator =(const ullong & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
|
||||
|
||||
private:
|
||||
static uint bytesInBits(const uint & bits) {return (bits + 7) / 8;}
|
||||
|
||||
PIVector<uchar> data_;
|
||||
uint size_;
|
||||
|
||||
};
|
||||
|
||||
#ifdef PIP_STD_IOSTREAM
|
||||
//std::ostream & operator <<(std::ostream & s, const PIBitArray & ba);
|
||||
#endif
|
||||
|
||||
//! \relatesalso PIByteArray
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
PICout operator <<(PICout s, const PIBitArray & ba);
|
||||
|
||||
#endif // PIBITARRAY_H
|
||||
@@ -1,431 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Byte array
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pibytearray.h"
|
||||
#include "pistringlist.h"
|
||||
#include <iostream>
|
||||
#include "picrc.h"
|
||||
|
||||
//! \class PIByteArray pibytearray.h
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! %PIByteArray used to store raw bytes.
|
||||
//! It can be constructed from any data and size.
|
||||
//! You can use %PIByteArray as binary stream
|
||||
//! to serialize/deserialize any objects and data.
|
||||
//! See details \ref iostream.
|
||||
//! This class use PIDeque<uchar> and provide some handle function
|
||||
//! to manipulate it.
|
||||
//! \~russian
|
||||
//! %PIByteArray используется для хранения байтов.
|
||||
//! Он может быть сконструирован из любых даных.
|
||||
//! Можно использовать %PIByteArray как потоковый объект
|
||||
//! для сериализации/десериализации любых типов и данных.
|
||||
//! Подробнее \ref iostream.
|
||||
//! Этот класс использует PIDeque<uchar> и предоставляет набор
|
||||
//! удобных методов для работы с байтами.
|
||||
//!
|
||||
//! \~english \section PIByteArray_sec0 Usage
|
||||
//! \~russian \section PIByteArray_sec0 Использование
|
||||
//! \~english
|
||||
//! %PIByteArray subclass PIBinaryStream and can be used to store custom data and manipulate it.
|
||||
//! Store operators places data at the end of array, restore operators takes data from the beginning
|
||||
//! of array.
|
||||
//! In addition there are Hex and Base64 convertions.
|
||||
//! \~russian
|
||||
//! %PIByteArray наследован от PIBinaryStream и может быть использован для сохранения любых данных и работы с ними.
|
||||
//! Операторы сохранения добавляют данные в конец массива, а операторы извлечения
|
||||
//! берут данные из его начала.
|
||||
//! Также есть методы для преобразования в Hex и Base64.
|
||||
//!
|
||||
//! \~english \section PIByteArray_sec1 Attention
|
||||
//! \~russian \section PIByteArray_sec1 Внимание
|
||||
//! \~english
|
||||
//! Stream operator of %PIByteArray store byte array as vector, not simply append
|
||||
//! content of byte array. This operators useful to transmit custom data as %PIByteArray
|
||||
//! packed into parent byte array, e.g. to form packet from %PIByteArray.
|
||||
//! To append one byte array to another use funtion \a append().
|
||||
//! \~russian
|
||||
//! Потоковый оператор для типа %PIByteArray сохраняет его как контейнер,
|
||||
//! а не просто добавляет его содержимое в конец. Этот оператор полезен для управляемой
|
||||
//! упаковки произвольных данных в виде %PIByteArray.
|
||||
//! Для добавления содержимого одного байтового массива к другому используется
|
||||
//! метод \a append().
|
||||
//! \~\snippet pibytearray.cpp 3
|
||||
//!
|
||||
|
||||
|
||||
static const uchar base64Table[64] = {
|
||||
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
||||
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
|
||||
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
||||
0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
|
||||
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
|
||||
0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33,
|
||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f};
|
||||
|
||||
static const uchar base64InvTable[256] = {
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x3F,
|
||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
|
||||
0x3C, 0x3D, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6,
|
||||
0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE,
|
||||
0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
|
||||
0x17, 0x18, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
|
||||
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
|
||||
0x31, 0x32, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
|
||||
|
||||
|
||||
struct base64HelpStruct {
|
||||
base64HelpStruct() {v = 0;}
|
||||
inline void setBytes(const uchar * r, int size = 3) {
|
||||
v = 0;
|
||||
switch (size) {
|
||||
case 3: v |= r[2];
|
||||
case 2: v |= r[1] << 8;
|
||||
case 1: v |= r[0] << 16;
|
||||
}
|
||||
}
|
||||
inline void getBytes(uchar * r) {
|
||||
r[0] = (v >> 16) & 0xFF;
|
||||
r[1] = (v >> 8) & 0xFF;
|
||||
r[2] = v & 0xFF;
|
||||
}
|
||||
inline void setAscii(const uchar * r, int size = 4) {
|
||||
v = 0;
|
||||
switch (size) {
|
||||
case 4: v |= (base64InvTable[r[3]] & 0x3F);
|
||||
case 3: v |= (base64InvTable[r[2]] & 0x3F) << 6;
|
||||
case 2: v |= (base64InvTable[r[1]] & 0x3F) << 12;
|
||||
case 1: v |= (base64InvTable[r[0]] & 0x3F) << 18;
|
||||
}
|
||||
}
|
||||
inline void getAscii(uchar * r) {
|
||||
r[0] = base64Table[(v >> 18) & 0x3F];
|
||||
r[1] = base64Table[(v >> 12) & 0x3F];
|
||||
r[2] = base64Table[(v >> 6) & 0x3F];
|
||||
r[3] = base64Table[ v & 0x3F];
|
||||
}
|
||||
uint v;
|
||||
};
|
||||
|
||||
|
||||
PIByteArray &PIByteArray::convertToBase64() {
|
||||
return *this = toBase64();
|
||||
}
|
||||
|
||||
|
||||
PIByteArray &PIByteArray::convertFromBase64() {
|
||||
return *this = fromBase64(*this);
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PIByteArray::toBase64() const {
|
||||
if (isEmpty()) return PIByteArray();
|
||||
base64HelpStruct hs;
|
||||
PIByteArray ret;
|
||||
int sz = (size_s() / 3) * 3, ri = -1;
|
||||
uchar t[4];
|
||||
ret.resize(((size_s() - 1) / 3 + 1) * 4);
|
||||
for (int i = 0; i < sz; i += 3) {
|
||||
hs.setBytes(data(i));
|
||||
hs.getAscii(t);
|
||||
ret[++ri] = (t[0]);
|
||||
ret[++ri] = (t[1]);
|
||||
ret[++ri] = (t[2]);
|
||||
ret[++ri] = (t[3]);
|
||||
}
|
||||
int der = size_s() % 3;
|
||||
switch (der) {
|
||||
case 1:
|
||||
hs.setBytes(data(sz), 1);
|
||||
hs.getAscii(t);
|
||||
ret[++ri] = (t[0]);
|
||||
ret[++ri] = (t[1]);
|
||||
ret[++ri] = ('=');
|
||||
ret[++ri] = ('=');
|
||||
break;
|
||||
case 2:
|
||||
hs.setBytes(data(sz), 2);
|
||||
hs.getAscii(t);
|
||||
ret[++ri] = (t[0]);
|
||||
ret[++ri] = (t[1]);
|
||||
ret[++ri] = (t[2]);
|
||||
ret[++ri] = ('=');
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PIByteArray::fromBase64(const PIByteArray & base64) {
|
||||
if (base64.isEmpty()) return PIByteArray();
|
||||
base64HelpStruct hs;
|
||||
PIByteArray ret;
|
||||
int sz = base64.size_s(), ind = -1;
|
||||
uchar t[4];
|
||||
ret.resize(sz / 4 * 3);
|
||||
for (int i = 0; i < sz; i += 4) {
|
||||
hs.setAscii(base64.data(i));
|
||||
hs.getBytes(t);
|
||||
ret[++ind] = (t[0]);
|
||||
ret[++ind] = (t[1]);
|
||||
ret[++ind] = (t[2]);
|
||||
}
|
||||
if (base64.back() == '=') ret.pop_back();
|
||||
if (sz > 1) if (base64[sz - 2] == '=') ret.pop_back();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PIByteArray::fromBase64(const PIString & base64) {
|
||||
return fromBase64(base64.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
PIByteArray & PIByteArray::compressRLE(uchar threshold) {
|
||||
PIByteArray t;
|
||||
uchar fb, clen, mlen = 255 - threshold;
|
||||
for (uint i = 0; i < size();) {
|
||||
fb = at(i);
|
||||
clen = 1;
|
||||
while (at(++i) == fb) {
|
||||
++clen;
|
||||
if (clen == mlen)
|
||||
break;
|
||||
}
|
||||
if (clen > 1) {
|
||||
t.push_back(threshold + clen);
|
||||
t.push_back(fb);
|
||||
continue;
|
||||
}
|
||||
if (fb >= threshold) {
|
||||
t.push_back(threshold + 1);
|
||||
t.push_back(fb);
|
||||
} else
|
||||
t.push_back(fb);
|
||||
}
|
||||
*this = t;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIByteArray & PIByteArray::decompressRLE(uchar threshold) {
|
||||
PIByteArray t;
|
||||
uchar fb, clen;
|
||||
for (uint i = 0; i < size(); ++i) {
|
||||
fb = at(i);
|
||||
if (fb >= threshold) {
|
||||
clen = fb - threshold;
|
||||
fb = at(++i);
|
||||
for (uint j = 0; j < clen; ++j)
|
||||
t.push_back(fb);
|
||||
continue;
|
||||
} else
|
||||
t.push_back(fb);
|
||||
}
|
||||
*this = t;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This is simple sum of all bytes, if "inverse" then add 1 and inverse.
|
||||
//! Pseudocode:
|
||||
//! \~russian
|
||||
//! Это простая сумма всех байтов, если "inverse", то ещё добавляется 1 и инвертируется результат.
|
||||
//! Псевдокод:
|
||||
//! \~\code
|
||||
//! for (i)
|
||||
//! sum += at(i);
|
||||
//! if (inverse) return ~(sum + 1);
|
||||
//! else return sum;
|
||||
//! \endcode
|
||||
uchar PIByteArray::checksumPlain8(bool inverse) const {
|
||||
uchar c = 0;
|
||||
int sz = size_s();
|
||||
for (int i = 0; i < sz; ++i)
|
||||
c += at(i);
|
||||
if (inverse) c = ~(c + 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
uchar PIByteArray::checksumCRC8() const {
|
||||
return standardCRC_8().calculate(data(), size());
|
||||
}
|
||||
|
||||
ushort PIByteArray::checksumCRC16() const {
|
||||
return standardCRC_16().calculate(data(), size());
|
||||
}
|
||||
|
||||
uint PIByteArray::checksumCRC32() const {
|
||||
return standardCRC_32().calculate(data(), size());
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This is sum of all bytes multiplied by index+1, if inverse then add 1 and inverse.
|
||||
//! Pseudocode:
|
||||
//! \~russian
|
||||
//! Это простая сумма всех байтов, умноженных на индекс+1, если "inverse", то ещё добавляется 1 и инвертируется результат.
|
||||
//! Псевдокод:
|
||||
//! \~\code
|
||||
//! for (i)
|
||||
//! sum += at(i) * (i + 1);
|
||||
//! if (inverse) return ~(sum + 1);
|
||||
//! else return sum;
|
||||
//! \endcode
|
||||
uint PIByteArray::checksumPlain32(bool inverse) const {
|
||||
uint c = 0;
|
||||
int sz = size_s();
|
||||
for (int i = 0; i < sz; ++i)
|
||||
c += at(i) * (i + 1);
|
||||
if (inverse) c = ~(c + 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
uint PIByteArray::hash() const {
|
||||
return piHashData(data(), size_s());
|
||||
}
|
||||
|
||||
|
||||
PIString PIByteArray::toString(int base) const {
|
||||
PIString ret;
|
||||
int sz = size_s();
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
if (i > 0) ret += " ";
|
||||
if (base == 2) ret += "b";
|
||||
if (base == 8) ret += "0";
|
||||
if (base == 16) ret += "0x";
|
||||
ret += PIString::fromNumber(at(i), base);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString PIByteArray::toHex() const {
|
||||
PIByteArray hex(size() * 2);
|
||||
uchar *hexData = hex.data();
|
||||
const uchar *d = data();
|
||||
for (int i = 0; i < size_s(); ++i) {
|
||||
int j = (d[i] >> 4) & 0xf;
|
||||
if (j <= 9) hexData[i*2] = (j + '0');
|
||||
else hexData[i*2] = (j + 'a' - 10);
|
||||
j = d[i] & 0xf;
|
||||
if (j <= 9) hexData[i*2+1] = (j + '0');
|
||||
else hexData[i*2+1] = (j + 'a' - 10);
|
||||
}
|
||||
return PIString(hex);
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PIByteArray::fromUserInput(PIString str) {
|
||||
PIByteArray ret;
|
||||
if (str.trim().isEmpty()) return ret;
|
||||
str.replaceAll("\n", " ").replaceAll("\t", " ").replaceAll(" ", " ");
|
||||
PIStringList bl(str.split(" "));
|
||||
bool ok(false);
|
||||
piForeachC (PIString & b, bl) {
|
||||
int bv = b.toInt(-1, &ok);
|
||||
if (ok) ret << uchar(bv);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PIByteArray::fromHex(PIString str) {
|
||||
PIByteArray hexEncoded = str.toByteArray();
|
||||
PIByteArray res((hexEncoded.size() + 1)/ 2);
|
||||
uchar *result = res.data() + res.size();
|
||||
bool odd_digit = true;
|
||||
for (int i = hexEncoded.size() - 1; i >= 0; --i) {
|
||||
int ch = hexEncoded.at(i);
|
||||
int tmp;
|
||||
if (ch >= '0' && ch <= '9') tmp = ch - '0';
|
||||
else if (ch >= 'a' && ch <= 'f') tmp = ch - 'a' + 10;
|
||||
else if (ch >= 'A' && ch <= 'F') tmp = ch - 'A' + 10;
|
||||
else continue;
|
||||
if (odd_digit) {
|
||||
--result;
|
||||
*result = tmp;
|
||||
odd_digit = false;
|
||||
} else {
|
||||
*result |= tmp << 4;
|
||||
odd_digit = true;
|
||||
}
|
||||
}
|
||||
res.remove(0, result - res.data());
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
PICout operator <<(PICout s, const PIByteArray & ba) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
s << "{";
|
||||
for (uint i = 0; i < ba.size(); ++i) {
|
||||
s << ba[i];
|
||||
if (i < ba.size() - 1) s << ", ";
|
||||
}
|
||||
s << "}";
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
#ifdef PIP_STD_IOSTREAM
|
||||
std::ostream &operator <<(std::ostream & s, const PIByteArray & ba) {
|
||||
s << "{";
|
||||
for (uint i = 0; i < ba.size(); ++i) {
|
||||
s << ba[i];
|
||||
if (i < ba.size() - 1) s << ", ";
|
||||
}
|
||||
s << "}";
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
@@ -1,1272 +0,0 @@
|
||||
/*! \file pibytearray.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english Byte array
|
||||
* \~russian Байтовый массив
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Byte array
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIBYTEARRAY_H
|
||||
#define PIBYTEARRAY_H
|
||||
|
||||
#include "pichar.h"
|
||||
#include "pibinarystream.h"
|
||||
#include <stdio.h>
|
||||
|
||||
class PIString;
|
||||
class PIByteArray;
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english The %PIByteArray class provides an array of bytes.
|
||||
//! \~russian Класс %PIByteArray представляет собой массив байтов.
|
||||
class PIP_EXPORT PIByteArray: public PIBinaryStream<PIByteArray>
|
||||
{
|
||||
public:
|
||||
typedef ::PIMemoryBlock RawData DEPRECATEDM("use PIMemoryBlock instead");
|
||||
|
||||
//! \~english Constructs an empty byte array
|
||||
//! \~russian Создает пустой байтовый массив
|
||||
PIByteArray() {}
|
||||
|
||||
//! \~english Constructs copy of byte array "o"
|
||||
//! \~russian Создает копию байтового массива "o"
|
||||
PIByteArray(const PIByteArray & o): d(o.d) {}
|
||||
|
||||
//! \~english Constructs copy of byte array "o"
|
||||
//! \~russian Создает копию байтового массива "o"
|
||||
PIByteArray(const PIDeque<uchar> & o): d(o) {}
|
||||
|
||||
PIByteArray(PIByteArray && o): d(std::move(o.d)) {}
|
||||
|
||||
//! \~english Constructs 0-filled byte array with size "size"
|
||||
//! \~russian Создает заполненный "0" байтовый массив размером "size"
|
||||
PIByteArray(const uint size) {resize(size);}
|
||||
|
||||
//! \~english Constructs byte array from data "data" and size "size"
|
||||
//! \~russian Создает байтовый массив из данных по указателю "data" размером "size"
|
||||
PIByteArray(const void * data, const uint size): d((const uchar*)data, size_t(size)) {}
|
||||
|
||||
//! \~english Constructs byte array with size "size" filled by "t"
|
||||
//! \~russian Создает заполненный "t" байтовый массив размером "size"
|
||||
PIByteArray(const uint size, uchar t): d(size, t) {}
|
||||
|
||||
//! \~english Contructs array from
|
||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~russian Создает массив из
|
||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIByteArray v{1,2,3};
|
||||
//! piCout << v; // {1, 2, 3}
|
||||
//! \endcode
|
||||
PIByteArray(std::initializer_list<uchar> init_list) : d(init_list) {}
|
||||
|
||||
//! \~english Swaps array `v` other with this array.
|
||||
//! \~russian Меняет местами массив `v` с этим массивом.
|
||||
//! \~\details
|
||||
//! \~english This operation is very fast and never fails.
|
||||
//! \~russian Эта операция выполняется мгновенно без копирования памяти и никогда не дает сбоев.
|
||||
inline void swap(PIByteArray & other) {
|
||||
d.swap(other.d);
|
||||
}
|
||||
|
||||
//! \~english Iterator to the first element.
|
||||
//! \~russian Итератор на первый элемент.
|
||||
//! \~\details 
|
||||
//!
|
||||
//! \~english If the array is empty, the returned iterator is equal to \a end().
|
||||
//! \~russian Если массив - пуст, возвращаемый итератор будет равен \a end().
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a end(), \a rbegin(), \a rend()
|
||||
inline PIDeque<uchar>::iterator begin() {return d.begin();}
|
||||
|
||||
//! \~english Iterator to the element following the last element.
|
||||
//! \~russian Итератор на элемент, следующий за последним элементом.
|
||||
//! \~\details 
|
||||
//!
|
||||
//! \~english This element acts as a placeholder;
|
||||
//! attempting to access it results in undefined behavior.
|
||||
//! \~russian Этот элемент существует лишь условно,
|
||||
//! попытка доступа к нему приведёт к выходу за разрешенную память.
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a begin(), \a rbegin(), \a rend()
|
||||
inline PIDeque<uchar>::iterator end() {return d.end();}
|
||||
|
||||
inline PIDeque<uchar>::const_iterator begin() const {return d.begin();}
|
||||
inline PIDeque<uchar>::const_iterator end() const {return d.end();}
|
||||
|
||||
//! \~english Returns a reverse iterator to the first element of the reversed array.
|
||||
//! \~russian Обратный итератор на первый элемент.
|
||||
//! \~\details 
|
||||
//!
|
||||
//! \~english It corresponds to the last element of the non-reversed array.
|
||||
//! If the array is empty, the returned iterator is equal to \a rend().
|
||||
//! \~russian Итератор для прохода массива в обратном порядке.
|
||||
//! Указывает на последний элемент.
|
||||
//! Если массив пустой, то совпадает с итератором \a rend().
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a rend(), \a begin(), \a end()
|
||||
inline PIDeque<uchar>::reverse_iterator rbegin() {return d.rbegin();}
|
||||
|
||||
//! \~english Returns a reverse iterator to the element.
|
||||
//! following the last element of the reversed array.
|
||||
//! \~russian Обратный итератор на элемент, следующий за последним элементом.
|
||||
//! \~\details 
|
||||
//!
|
||||
//! \~english It corresponds to the element preceding the first element of the non-reversed array.
|
||||
//! This element acts as a placeholder, attempting to access it results in undefined behavior.
|
||||
//! \~russian Итератор для прохода массива в обратном порядке.
|
||||
//! Указывает на элемент, предшествующий первому элементу.
|
||||
//! Этот элемент существует лишь условно,
|
||||
//! попытка доступа к нему приведёт к выходу за разрешенную память.
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a rbegin(), \a begin(), \a end()
|
||||
inline PIDeque<uchar>::reverse_iterator rend() {return d.rend();}
|
||||
|
||||
inline PIDeque<uchar>::const_reverse_iterator rbegin() const {return d.rbegin();}
|
||||
inline PIDeque<uchar>::const_reverse_iterator rend() const {return d.rend();}
|
||||
|
||||
//! \~english Number of elements in the container.
|
||||
//! \~russian Количество элементов массива.
|
||||
//! \~\sa \a size_s(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
||||
inline size_t size() const {return d.size();}
|
||||
|
||||
//! \~english Number of elements in the container as signed value.
|
||||
//! \~russian Количество элементов массива в виде знакового числа.
|
||||
//! \~\sa \a size(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
||||
inline ssize_t size_s() const {return d.size_s();}
|
||||
|
||||
//! \~english Same as \a size().
|
||||
//! \~russian Синоним \a size().
|
||||
//! \~\sa \a size(), \a size_s(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
||||
inline size_t length() const {return d.length();}
|
||||
|
||||
//! \~english Number of elements that the container has currently allocated space for.
|
||||
//! \~russian Количество элементов, для которого сейчас выделена память массивом.
|
||||
//! \~\details
|
||||
//! \~english To find out the actual number of items, use the function \a size().
|
||||
//! \~russian Чтобы узнать фактическое количество элементов используйте функцию \a size().
|
||||
//! \~\sa \a reserve(), \a size(), \a size_s()
|
||||
inline size_t capacity() const {return d.capacity();}
|
||||
|
||||
//! \~english Checks if the container has no elements.
|
||||
//! \~russian Проверяет пуст ли массив.
|
||||
//! \~\return
|
||||
//! \~english **true** if the container is empty, **false** otherwise
|
||||
//! \~russian **true** если массив пуст, **false** иначе.
|
||||
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
||||
inline bool isEmpty() const {return d.isEmpty();}
|
||||
|
||||
//! \~english Checks if the container has elements.
|
||||
//! \~russian Проверяет не пуст ли массив.
|
||||
//! \~\return
|
||||
//! \~english **true** if the container is not empty, **false** otherwise
|
||||
//! \~russian **true** если массив не пуст, **false** иначе.
|
||||
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
||||
inline bool isNotEmpty() const {return d.isNotEmpty();}
|
||||
|
||||
//! \~english Tests whether at least one element in the array
|
||||
//! passes the test implemented by the provided function `test`.
|
||||
//! \~russian Проверяет, удовлетворяет ли какой-либо элемент массива условию,
|
||||
//! заданному в передаваемой функции `test`.
|
||||
//! \~\return
|
||||
//! \~english **true** if, in the array,
|
||||
//! it finds an element for which the provided function returns **true**;
|
||||
//! otherwise it returns **false**. Always returns **false** if is empty.
|
||||
//! \~russian **true** если хотя бы для одного элемента
|
||||
//! передаваемая функция возвращает **true**, в остальных случаях **false**.
|
||||
//! Метод возвращает **false** при любом условии для пустого массива.
|
||||
//! \~\details
|
||||
//! \~\sa \a every(), \a contains(), \a entries(), \a forEach()
|
||||
inline bool any(std::function<bool(uchar e)> test) const {
|
||||
return d.any(test);
|
||||
}
|
||||
|
||||
//! \~english Tests whether all elements in the array passes the test
|
||||
//! implemented by the provided function `test`.
|
||||
//! \~russian Проверяет, удовлетворяют ли все элементы массива условию,
|
||||
//! заданному в передаваемой функции `test`.
|
||||
//! \~\return
|
||||
//! \~english **true** if, in the array,
|
||||
//! it finds an element for which the provided function returns **true**;
|
||||
//! otherwise it returns **false**. Always returns **true** if is empty.
|
||||
//! \~russian **true** если для всех элементов передаваемая функция возвращает **true**,
|
||||
//! в остальных случаях **false**.
|
||||
//! Метод возвращает **true** при любом условии для пустого массива.
|
||||
//! \~\details
|
||||
//! \~\sa \a any(), \a contains(), \a entries(), \a forEach()
|
||||
inline bool every(std::function<bool(uchar e)> test) const {
|
||||
return d.every(test);
|
||||
}
|
||||
|
||||
//! \~english Full access to element by `index`.
|
||||
//! \~russian Полный доступ к элементу по индексу `index`.
|
||||
//! \~\details
|
||||
//! \~english Element index starts from `0`.
|
||||
//! Element index must be in range from `0` to `size()-1`.
|
||||
//! Otherwise will be undefined behavior.
|
||||
//! \~russian Индекс элемента считается от `0`.
|
||||
//! Индекс элемента должен лежать в пределах от `0` до `size()-1`.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
//! \~\sa \a at()
|
||||
inline uchar & operator [](size_t index) {return d[index];}
|
||||
inline uchar operator [](size_t index) const {return d[index];}
|
||||
|
||||
//! \~english Read only access to element by `index`.
|
||||
//! \~russian Доступ исключительно на чтение к элементу по индексу `index`.
|
||||
//! \~\details
|
||||
//! \~english Element index starts from `0`.
|
||||
//! Element index must be in range from `0` to `size()-1`.
|
||||
//! Otherwise will be undefined behavior.
|
||||
//! \~russian Индекс элемента считается от `0`.
|
||||
//! Индекс элемента должен лежать в пределах от `0` до `size()-1`.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
inline uchar at(size_t index) const {return d.at(index);}
|
||||
|
||||
//! \~english Last element.
|
||||
//! \~russian Последний элемент массива.
|
||||
//! \~\details
|
||||
//! \~english Returns a reference to the last item in the array.
|
||||
//! This function assumes that the array isn't empty.
|
||||
//! Otherwise will be undefined behavior.
|
||||
//! \~russian Возвращает ссылку на последний элемент в массиве.
|
||||
//! Эта функция предполагает, что массив не пустой.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
inline uchar & back() {return d.back();}
|
||||
inline uchar back() const {return d.back();}
|
||||
|
||||
//! \~english Last element.
|
||||
//! \~russian Первый элемент массива.
|
||||
//! \~\details
|
||||
//! \~english Returns a reference to the last item in the array.
|
||||
//! This function assumes that the array isn't empty.
|
||||
//! Otherwise will be undefined behavior.
|
||||
//! \~russian Возвращает ссылку на пенрвый элемент в массиве.
|
||||
//! Эта функция предполагает, что массив не пустой.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
inline uchar & front() {return d.front();}
|
||||
inline uchar front() const {return d.front();}
|
||||
|
||||
//! \~english Tests if element `e` exists in the array.
|
||||
//! \~russian Проверяет наличие элемента `e` в массиве.
|
||||
//! \~\details
|
||||
//! \~english Optional argument `start` - the position in this array at which to begin searching.
|
||||
//! If the index is greater than or equal to the array's size,
|
||||
//! **false** is returned, which means the array will not be searched.
|
||||
//! If the provided index value is a negative number,
|
||||
//! it is taken as the offset from the end of the array.
|
||||
//! Note: if the provided index is negative,
|
||||
//! the array is still searched from front to back.
|
||||
//! Default: 0 (entire array is searched).
|
||||
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
|
||||
//! Если индекс больше или равен длине массива,
|
||||
//! возвращается **false**, что означает, что массив даже не просматривается.
|
||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
||||
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
|
||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
|
||||
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
|
||||
//! \~\code
|
||||
//! PIByteArray v{1, 2, 3, 4};
|
||||
//! piCout << v.contains(3); // true
|
||||
//! piCout << v.contains(5); // false
|
||||
//! piCout << v.contains(3, 3); // false
|
||||
//! piCout << v.contains(3, -2); // true
|
||||
//! piCout << v.contains(3, -99); // true
|
||||
//! \endcode
|
||||
//! \~\return
|
||||
//! \~english **true** if the array contains an occurrence of element `e`,
|
||||
//! otherwise it returns **false**.
|
||||
//! \~russian **true** если элемент `e` присутствует в массиве,
|
||||
//! в остальных случаях **false**.
|
||||
//! \~\sa \a every(), \a any(), \a entries()
|
||||
inline bool contains(uchar e, ssize_t start = 0) const {
|
||||
return d.contains(e, start);
|
||||
}
|
||||
|
||||
//! \~english Count elements equal `e` in the array.
|
||||
//! \~russian Подсчитывает количество элементов, совпадающих с элементом `e` в массиве.
|
||||
//! \~\details
|
||||
//! \~english Optional argument `start` - the position in this array at which to begin searching.
|
||||
//! If the index is greater than or equal to the array's size,
|
||||
//! 0 is returned, which means the array will not be searched.
|
||||
//! If the provided index value is a negative number,
|
||||
//! it is taken as the offset from the end of the array.
|
||||
//! Note: if the provided index is negative,
|
||||
//! the array is still searched from front to back.
|
||||
//! Default: 0 (entire array is searched).
|
||||
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
|
||||
//! Если индекс больше или равен длине массива,
|
||||
//! возвращается 0, что означает, что массив даже не просматривается.
|
||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
||||
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
|
||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
|
||||
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
|
||||
//! \~\sa \a every(), \a any(), \a contains(), \a indexOf()
|
||||
inline int entries(uchar e, ssize_t start = 0) const {
|
||||
return d.entries(e, start);
|
||||
}
|
||||
|
||||
//! \~english Count elements in the array passes the test implemented by the provided function `test`.
|
||||
//! \~russian Подсчитывает количество элементов в массиве,
|
||||
//! проходящих по условию, заданному в передаваемой функции `test`.
|
||||
//! \~\details
|
||||
//! \~english Overloaded function.
|
||||
//! Optional argument `start` - the position in this array at which to begin searching.
|
||||
//! If the index is greater than or equal to the array's size,
|
||||
//! 0 is returned, which means the array will not be searched.
|
||||
//! If the provided index value is a negative number,
|
||||
//! it is taken as the offset from the end of the array.
|
||||
//! Note: if the provided index is negative,
|
||||
//! the array is still searched from front to back.
|
||||
//! Default: 0 (entire array is searched).
|
||||
//! \~russian Перегруженная функция.
|
||||
//! Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
|
||||
//! Если индекс больше или равен длине массива,
|
||||
//! возвращается 0, что означает, что массив даже не просматривается.
|
||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
||||
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
|
||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
|
||||
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
|
||||
//! \~\sa \a every(), \a any(), \a contains(), \a indexWhere()
|
||||
inline int entries(std::function<bool(uchar e)> test, ssize_t start = 0) const {
|
||||
return d.entries(test, start);
|
||||
}
|
||||
|
||||
//! \~english Returns the first index at which a given element `e`
|
||||
//! can be found in the array, or `-1` if it is not present.
|
||||
//! \~russian Возвращает первый индекс, по которому данный элемент `e`
|
||||
//! может быть найден в массиве или `-1`, если такого индекса нет.
|
||||
//! \~\details
|
||||
//! \~english Optional argument `start` - the position in this array at which to begin searching.
|
||||
//! If the index is greater than or equal to the array's size,
|
||||
//! `-1` is returned, which means the array will not be searched.
|
||||
//! If the provided index value is a negative number,
|
||||
//! it is taken as the offset from the end of the array.
|
||||
//! Note: if the provided index is negative,
|
||||
//! the array is still searched from front to back.
|
||||
//! Default: 0 (entire array is searched).
|
||||
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
|
||||
//! Если индекс больше или равен длине массива,
|
||||
//! возвращается `-1`, что означает, что массив даже не просматривается.
|
||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
||||
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
|
||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
|
||||
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
|
||||
//! \~\code
|
||||
//! PIByteArray v{2, 5, 9};
|
||||
//! piCout << v.indexOf(2); // 0
|
||||
//! piCout << v.indexOf(7); // -1
|
||||
//! piCout << v.indexOf(9, 2); // 2
|
||||
//! piCout << v.indexOf(2, -1); // -1
|
||||
//! piCout << v.indexOf(2, -3); // 0
|
||||
//! \endcode
|
||||
//! \~\sa \a indexWhere(), \a lastIndexOf(), \a lastIndexWhere(), \a contains()
|
||||
inline ssize_t indexOf(const uchar & e, ssize_t start = 0) const {
|
||||
return d.indexOf(e, start);
|
||||
}
|
||||
|
||||
//! \~english Returns the first index passes the test implemented by the provided function `test`,
|
||||
//! or `-1` if it is not present.
|
||||
//! can be found in the array, or `-1` if it is not present.
|
||||
//! \~russian Возвращает первый индекс элемента проходящего по условию,
|
||||
//! заданному в передаваемой функции `test`, или `-1`, если таких элементов нет.
|
||||
//! \~\details
|
||||
//! \~english Optional argument `start` - the position in this array at which to begin searching.
|
||||
//! If the index is greater than or equal to the array's size,
|
||||
//! `-1` is returned, which means the array will not be searched.
|
||||
//! If the provided index value is a negative number,
|
||||
//! it is taken as the offset from the end of the array.
|
||||
//! Note: if the provided index is negative,
|
||||
//! the array is still searched from front to back.
|
||||
//! Default: 0 (entire array is searched).
|
||||
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
|
||||
//! Если индекс больше или равен длине массива,
|
||||
//! возвращается `-1`, что означает, что массив даже не просматривается.
|
||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
||||
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
|
||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
|
||||
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
|
||||
//! \~\code
|
||||
//! PIByteArray v{2, 5, 9};
|
||||
//! piCout << v.indexWhere([](const uchar & s){return s > 3;}); // 1
|
||||
//! piCout << v.indexWhere([](const uchar & s){return s > 3;}, 2); // 2
|
||||
//! piCout << v.indexWhere([](const uchar & s){return s > 10;}); // -1
|
||||
//! \endcode
|
||||
//! \~\sa \a indexOf(), \a lastIndexOf(), \a lastIndexWhere(), \a contains()
|
||||
inline ssize_t indexWhere(std::function<bool(const uchar & e)> test, ssize_t start = 0) const {
|
||||
return d.indexWhere(test, start);
|
||||
}
|
||||
|
||||
//! \~english Returns the last index at which a given element `e`
|
||||
//! can be found in the array, or `-1` if it is not present.
|
||||
//! \~russian Возвращает последний индекс, по которому данный элемент `e`
|
||||
//! может быть найден в массиве или `-1`, если такого индекса нет.
|
||||
//! \~\details
|
||||
//! \~english Optional argument `start` - the position in this array
|
||||
//! at which to start searching backwards.
|
||||
//! If the index is greater than or equal to the array's size,
|
||||
//! causes the whole array to be searched.
|
||||
//! If the provided index value is a negative number,
|
||||
//! it is taken as the offset from the end of the array.
|
||||
//! Therefore, if calculated index less than 0,
|
||||
//! the array is not searched, and the method returns `-1`.
|
||||
//! Note: if the provided index is negative,
|
||||
//! the array is still searched from back to front.
|
||||
//! Default: -1 (entire array is searched).
|
||||
//! \~russian Опциональный аргумент `start` указывает на индекс
|
||||
//! c которого начинать поиск в обратном направлении.
|
||||
//! Если индекс больше или равен длине массива, просматривается весь массив.
|
||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от конца к началу.
|
||||
//! Если рассчитанный индекс оказывается меньше 0, массив даже не просматривается.
|
||||
//! Значение по умолчанию равно `-1`, что равно индексу последнего элемента
|
||||
//! и означает, что просматривается весь массив.
|
||||
//! \~\code
|
||||
//! PIByteArray v{2, 5, 9, 2};
|
||||
//! piCout << v.lastIndexOf(2); // 3
|
||||
//! piCout << v.lastIndexOf(7); // -1
|
||||
//! piCout << v.lastIndexOf(2, 2); // 0
|
||||
//! piCout << v.lastIndexOf(2, -3); // 0
|
||||
//! piCout << v.lastIndexOf(2, -300); // -1
|
||||
//! piCout << v.lastIndexOf(2, 300); // 3
|
||||
//! \endcode
|
||||
//! \~\sa \a indexOf(), \a indexWhere(), \a lastIndexWhere(), \a contains()
|
||||
inline ssize_t lastIndexOf(const uchar & e, ssize_t start = -1) const {
|
||||
return d.lastIndexOf(e, start);
|
||||
}
|
||||
|
||||
//! \~english Returns the last index passes the test implemented by the provided function `test`,
|
||||
//! or `-1` if it is not present.
|
||||
//! \~russian Возвращает последний индекс элемента проходящего по условию,
|
||||
//! заданному в передаваемой функции `test`, или `-1`, если таких элементов нет.
|
||||
//! \~\details
|
||||
//! \~english Optional argument `start` - the position in this array
|
||||
//! at which to start searching backwards.
|
||||
//! If the index is greater than or equal to the array's size,
|
||||
//! causes the whole array to be searched.
|
||||
//! If the provided index value is a negative number,
|
||||
//! it is taken as the offset from the end of the array.
|
||||
//! Therefore, if calculated index less than 0,
|
||||
//! the array is not searched, and the method returns `-1`.
|
||||
//! Note: if the provided index is negative,
|
||||
//! the array is still searched from back to front.
|
||||
//! Default: -1 (entire array is searched).
|
||||
//! \~russian Опциональный аргумент `start` указывает на индекс
|
||||
//! c которого начинать поиск в обратном направлении.
|
||||
//! Если индекс больше или равен длине массива, просматривается весь массив.
|
||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от конца к началу.
|
||||
//! Если рассчитанный индекс оказывается меньше 0, массив даже не просматривается.
|
||||
//! Значение по умолчанию равно `-1`, что равно индексу последнего элемента
|
||||
//! и означает, что просматривается весь массив.
|
||||
//! \~\sa \a indexOf(), \a lastIndexOf(), \a indexWhere(), \a contains()
|
||||
inline ssize_t lastIndexWhere(std::function<bool(const uchar & e)> test, ssize_t start = -1) const {
|
||||
return d.lastIndexWhere(test, start);
|
||||
}
|
||||
|
||||
//! \~english Pointer to array
|
||||
//! \~russian Указатель на память массива
|
||||
//! \~\details
|
||||
//! \~english Optional argument `index` the position in this array,
|
||||
//! where is pointer. Default: start of array.
|
||||
//! \~russian Опциональный аргумент `index` указывает на индекс c которого брать указатель.
|
||||
//! По умолчанию указывает на начало массива.
|
||||
inline uchar * data(size_t index = 0) {return d.data(index);}
|
||||
|
||||
//! \~english Read only pointer to array
|
||||
//! \~russian Указатель на память массива только для чтения.
|
||||
//! \~\details
|
||||
//! \~english The pointer can be used to access and modify the items in the array.
|
||||
//! The pointer remains valid as long as the array isn't reallocated.
|
||||
//! Optional argument `index` the position in this array,
|
||||
//! where is pointer. Default: start of array.
|
||||
//! \~russian Указатель можно использовать для доступа и изменения элементов в массиве.
|
||||
//! Указатель остается действительным только до тех пор, пока массив не будет перераспределен.
|
||||
//! Опциональный аргумент `index` указывает на индекс c которого брать указатель.
|
||||
//! По умолчанию указывает на начало массива.
|
||||
inline const uchar * data(size_t index = 0) const {return d.data(index);}
|
||||
|
||||
//! \~english Clear array, remove all elements.
|
||||
//! \~russian Очищает массив, удаляет все элементы.
|
||||
//! \~\details
|
||||
//! \~\note
|
||||
//! \~english Reserved memory will not be released.
|
||||
//! \~russian Зарезервированная память не освободится.
|
||||
//! \~\sa \a resize()
|
||||
inline PIByteArray & clear() {
|
||||
resize(0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Assigns element 'e' to all items in the array.
|
||||
//! \~russian Заполняет весь массив копиями элемента 'e'.
|
||||
//! \~\details
|
||||
//! \~\sa \a resize()
|
||||
inline PIByteArray & fill(uchar e = 0) {
|
||||
d.fill(e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Assigns result of function 'f(size_t i)' to all items in the array.
|
||||
//! \~russian Заполняет весь массив результатом вызова функции 'f(size_t i)'.
|
||||
//! \~\details
|
||||
//! \~\sa \a resize()
|
||||
inline PIByteArray & fill(std::function<uchar(size_t i)> f) {
|
||||
d.fill(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Same as \a fill().
|
||||
//! \~russian Тоже самое что и \a fill().
|
||||
//! \~\sa \a fill(), \a resize()
|
||||
inline PIByteArray & assign(uchar e = 0) {return fill(e);}
|
||||
|
||||
//! \~english First does `resize(new_size)` then `fill(e)`.
|
||||
//! \~russian Сначала делает `resize(new_size)`, затем `fill(e)`.
|
||||
//! \~\sa \a fill(), \a resize()
|
||||
inline PIByteArray & assign(size_t new_size, uchar e) {
|
||||
resize(new_size);
|
||||
return fill(e);
|
||||
}
|
||||
|
||||
//! \~english Sets size of the array, new elements are copied from `e`.
|
||||
//! \~russian Устанавливает размер массива, новые элементы копируются из `e`.
|
||||
//! \~\details
|
||||
//! \~english If `new_size` is greater than the current \a size(),
|
||||
//! elements are added to the end; the new elements are initialized from `e`.
|
||||
//! If `new_size` is less than the current \a size(), elements are removed from the end.
|
||||
//! \~russian Если `new_size` больше чем текущий размер массива \a size(),
|
||||
//! новые элементы добавляются в конец массива и создаются из `e`.
|
||||
//! Если `new_size` меньше чем текущий размер массива \a size(),
|
||||
//! лишние элементы удаляются с конца массива.
|
||||
//! \~\sa \a size(), \a clear()
|
||||
inline PIByteArray & resize(size_t new_size, uchar e = 0) {
|
||||
d.resize(new_size, e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Sets size of the array, new elements created by function `f(size_t i)`.
|
||||
//! \~russian Устанавливает размер массива, новые элементы создаются функцией `f(size_t i)`.
|
||||
//! \~\details
|
||||
//! \~english If `new_size` is greater than the current \a size(),
|
||||
//! elements are added to the end; the new elements created by function `f(size_t i)`.
|
||||
//! If `new_size` is less than the current \a size(), elements are removed from the end.
|
||||
//! \~russian Если `new_size` больше чем текущий размер массива \a size(),
|
||||
//! новые элементы добавляются в конец массива и функцией `f(size_t i)`.
|
||||
//! Если `new_size` меньше чем текущий размер массива \a size(),
|
||||
//! лишние элементы удаляются с конца массива.
|
||||
//! \~\sa \a size(), \a clear()
|
||||
inline PIByteArray & resize(size_t new_size, std::function<uchar(size_t i)> f) {
|
||||
d.resize(new_size, f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Return resized byte array
|
||||
//! \~russian Возвращает копию байтового массива с измененным размером
|
||||
PIByteArray resized(uint new_size) const {
|
||||
PIByteArray ret(new_size);
|
||||
memcpy(ret.data(), data(), new_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! \~english Attempts to allocate memory for at least `new_size` elements.
|
||||
//! \~russian Резервируется память под как минимум `new_size` элементов.
|
||||
//! \~\details
|
||||
//! \~english If you know in advance how large the array will be,
|
||||
//! you should call this function to prevent reallocations and memory fragmentation.
|
||||
//! If `new_size` is greater than the current \a capacity(),
|
||||
//! new storage is allocated, otherwise the function does nothing.
|
||||
//! This function does not change the \a size() of the array.
|
||||
//! \~russian Если вы заранее знаете, насколько велик будет массив,
|
||||
//! вы можете вызвать эту функцию, чтобы предотвратить перераспределение и фрагментацию памяти.
|
||||
//! Если размер `new_size` больше чем выделенная память \a capacity(),
|
||||
//! то произойдёт выделение новой памяти и перераспределение массива.
|
||||
//! Эта функция не изменяет количество элементов в массиве \a size().
|
||||
//! \~\sa \a size(), \a capacity(), \a resize()
|
||||
inline PIByteArray & reserve(size_t new_size) {
|
||||
d.reserve(new_size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Inserts value `e` at `index` position in the array.
|
||||
//! \~russian Вставляет значение `e` в позицию `index` в массиве.
|
||||
//! \~\details
|
||||
//! \~english The index must be greater than 0 and less than or equal to \a size().
|
||||
//! \~russian Индекс должен быть больше 0 и меньше или равен \a size().
|
||||
//! \~\sa \a append(), \a prepend(), \a remove()
|
||||
inline PIByteArray & insert(size_t index, uchar e = 0) {
|
||||
d.insert(index, e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Inserts array `v` at `index` position in the array.
|
||||
//! \~russian Вставляет массив `v` в позицию `index` в массиве.
|
||||
//! \~\details
|
||||
//! \~english The index must be greater than or equal to 0 and less than or equal to \a size().
|
||||
//! \~russian Индекс должен быть больше или равен 0 и меньше или равен \a size().
|
||||
//! \~\sa \a append(), \a prepend(), \a remove()
|
||||
inline PIByteArray & insert(size_t index, const PIByteArray & v) {
|
||||
d.insert(index, v.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Inserts the given elements at `index` position in the array.
|
||||
//! \~russian Вставляет элементы в позицию `index` в массиве.
|
||||
//! \~\details
|
||||
//! \~english The index must be greater than or equal to 0 and less than or equal to \a size().
|
||||
//! Inserts the given elements from
|
||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~russian Индекс должен быть больше или равен 0 и меньше или равен \a size().
|
||||
//! Вставляет элементы из
|
||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~\sa \a append(), \a prepend(), \a remove()
|
||||
inline PIByteArray & insert(size_t index, std::initializer_list<uchar> init_list) {
|
||||
d.insert(index, init_list);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Removes `count` elements from the middle of the array, starting at `index` position.
|
||||
//! \~russian Удаляет элементы из массива, начиная с позиции `index` в количестве `count`.
|
||||
//! \~\details
|
||||
//! \~\sa \a resize(), \a insert(), \a removeOne(), \a removeAll(), \a removeWhere()
|
||||
inline PIByteArray & remove(size_t index, size_t count = 1) {
|
||||
d.remove(index, count);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Return sub-array starts from "index" and has "count" or less bytes
|
||||
//! \~russian Возвращает подмассив с данными от индекса "index" и размером не более "count"
|
||||
PIByteArray getRange(size_t index, size_t count) const {
|
||||
return d.getRange(index, count);
|
||||
}
|
||||
|
||||
//! \~english Reverses this array.
|
||||
//! \~russian Обращает порядок следования элементов этого массива.
|
||||
//! \~\details
|
||||
//! \~english This method reverses an array [in place](https://en.wikipedia.org/wiki/In-place_algorithm).
|
||||
//! The first array element becomes the last, and the last array element becomes the first.
|
||||
//! The reverse method transposes the elements of the calling array object in place,
|
||||
//! mutating the array, and returning a reference to the array.
|
||||
//! \~russian Метод reverse() на месте переставляет элементы массива,
|
||||
//! на котором он был вызван, изменяет массив и возвращает ссылку на него.
|
||||
//! Первый элемент массива становится последним, а последний — первым.
|
||||
//! \~\sa \a reversed()
|
||||
inline PIByteArray & reverse() {
|
||||
d.reverse();
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Returns reversed array.
|
||||
//! \~russian Возвращает перевернутый массив.
|
||||
//! \~\details
|
||||
//! \~english Returns a copy of the array with elements in reverse order.
|
||||
//! The first array element becomes the last, and the last array element becomes the first.
|
||||
//! \~russian Возвращает копию массива с элементами в обратном порядке.
|
||||
//! Первый элемент массива становится последним, а последний — первым.
|
||||
//! \~\sa \a reverse()
|
||||
inline PIByteArray reversed() const {
|
||||
PIByteArray ret(*this);
|
||||
return ret.reverse();
|
||||
}
|
||||
|
||||
//! \~english Increases or decreases the size of the array by `add_size` elements.
|
||||
//! \~russian Увеличивает или уменьшает размер массива на `add_size` элементов.
|
||||
//! \~\details
|
||||
//! \~english If `add_size > 0` then elements are added to the end of the array.
|
||||
//! If `add_size < 0` then elements are removed from the end of the array.
|
||||
//! If `add_size < 0` and there are fewer elements in the array than specified, then the array becomes empty.
|
||||
//! \~russian Если `add_size > 0`, то в конец массива добавляются элементы.
|
||||
//! Если `add_size < 0`, то с конца массива удаляются элементы.
|
||||
//! Если `add_size < 0` и в массиве меньше элементов чем указано, то массив становится пустым.
|
||||
//! \~\sa \a resize()
|
||||
inline PIByteArray & enlarge(ssize_t add_size, uchar e = 0) {
|
||||
d.enlarge(add_size, e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Remove no more than one element equal `e`.
|
||||
//! \~russian Удаляет первый элемент, который равен элементу `e`.
|
||||
//! \~\details
|
||||
//! \~\sa \a remove(), \a removeAll(), \a removeWhere()
|
||||
inline PIByteArray & removeOne(uchar e) {
|
||||
d.removeOne(e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Remove all elements equal `e`.
|
||||
//! \~russian Удаляет все элементы, равные элементу `e`.
|
||||
//! \~\details
|
||||
//! \~\sa \a remove(), \a removeOne(), \a removeWhere()
|
||||
inline PIByteArray & removeAll(uchar e) {
|
||||
d.removeAll(e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Remove all elements in the array
|
||||
//! passes the test implemented by the provided function `test`.
|
||||
//! \~russian Удаляет все элементы, удовлетворяющие условию,
|
||||
//! заданному в передаваемой функции `test`.
|
||||
//! \~\details
|
||||
//! \~\sa \a remove(), \a removeOne(), \a removeWhere()
|
||||
inline PIByteArray & removeWhere(std::function<bool(uchar e)> test) {
|
||||
d.removeWhere(test);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Appends the given element `e` to the end of the array.
|
||||
//! \~russian Добавляет элемент `e` в конец массива.
|
||||
//! \~\details
|
||||
//! \~english If size() is less than capacity(), which is most often
|
||||
//! then the addition will be very fast.
|
||||
//! In any case, the addition is fast and does not depend on the size of the array.
|
||||
//! If the new size() is greater than capacity()
|
||||
//! then all iterators and references
|
||||
//! (including the past-the-end iterator) are invalidated.
|
||||
//! Otherwise only the past-the-end iterator is invalidated.
|
||||
//! \~russian Если size() меньше capacity(), что часто бывает,
|
||||
//! то добавление будет очень быстрым.
|
||||
//! В любом случае добавление быстрое и не зависит от размера массива.
|
||||
//! Если новый size() больше, чем capacity(),
|
||||
//! то все итераторы и указатели становятся нерабочими.
|
||||
//! В противном случае все, кроме итераторов, указывающих на конец массива,
|
||||
//! остаются в рабочем состоянии.
|
||||
//! \~\sa \a push_front(), \a append(), \a prepend(), \a insert()
|
||||
inline PIByteArray & push_back(uchar e) {
|
||||
d.push_back(e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Appends the given elements to the end of the array.
|
||||
//! \~russian Добавляет элементы в конец массива.
|
||||
//! \~\details
|
||||
//! \~english Overloaded function.
|
||||
//! Appends the given elements from
|
||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~russian Перегруженая функция.
|
||||
//! Добавляет элементы из
|
||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~\sa \a push_back()
|
||||
inline PIByteArray & push_back(std::initializer_list<uchar> init_list) {
|
||||
d.push_back(init_list);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Appends the given array `v` to the end of the array.
|
||||
//! \~russian Добавляет массив `v` в конец массива.
|
||||
//! \~\details
|
||||
//! \~english Overloaded function.
|
||||
//! \~russian Перегруженая функция.
|
||||
//! \~\sa \a push_back()
|
||||
inline PIByteArray & push_back(const PIByteArray & v) {
|
||||
d.push_back(v.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Add to the end data "data" with size "size"
|
||||
//! \~russian Добавляет в конец массива данные по указателю "data" размером "size"
|
||||
PIByteArray & push_back(const void * data_, int size_) {uint ps = size(); enlarge(size_); memcpy(data(ps), data_, size_); return *this;}
|
||||
|
||||
//! \~english Appends the given element `e` to the begin of the array.
|
||||
//! \~russian Добавляет элемент `e` в начало массива.
|
||||
//! \~\details
|
||||
//! \~english If there is free space at the beginning of the array,
|
||||
//! which is most often, then the addition will be very fast.
|
||||
//! In any case, the addition is fast and does not depend on the size of the array.
|
||||
//! If there is no free space at the beginning of the array
|
||||
//! then all iterators and references
|
||||
//! (including the past-the-begin iterator) are invalidated.
|
||||
//! Otherwise only the past-the-begin iterator is invalidated.
|
||||
//! \~russian Если в начале массива имеется свободное место,
|
||||
//! что часто бывает, то добавление будет очень быстрым.
|
||||
//! В любом случае добавление быстрое и не зависит от размера массива.
|
||||
//! Если в начале массива нет свободного места,
|
||||
//! то все итераторы и указатели становятся нерабочими.
|
||||
//! В противном случае все, кроме итераторов указывающих, на начало массива,
|
||||
//! остаются в рабочем состоянии.
|
||||
//! \~\sa \a push_back(), \a append(), \a prepend(), \a insert()
|
||||
inline PIByteArray & push_front(uchar e) {
|
||||
d.push_front(e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Appends the given array `v` to the begin of the array.
|
||||
//! \~russian Добавляет массив `v` в начало массива.
|
||||
//! \~\details
|
||||
//! \~english Overloaded function.
|
||||
//! \~russian Перегруженая функция.
|
||||
//! \~\sa \a push_front()
|
||||
inline PIByteArray & push_front(const PIByteArray & v) {
|
||||
d.push_front(v.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Appends the given elements to the begin of the array.
|
||||
//! \~russian Добавляет элементы в начало массива.
|
||||
//! \~\details
|
||||
//! \~english Overloaded function.
|
||||
//! Appends the given elements from
|
||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~russian Перегруженая функция.
|
||||
//! Добавляет элементы из
|
||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~\sa \a append()
|
||||
inline PIByteArray & push_front(std::initializer_list<uchar> init_list) {
|
||||
d.push_front(init_list);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Appends the given element `e` to the begin of the array.
|
||||
//! \~russian Добавляет элемент `e` в начало массива.
|
||||
//! \~\details
|
||||
//! \~english If there is free space at the beginning of the array,
|
||||
//! which is most often, then the addition will be very fast.
|
||||
//! In any case, the addition is fast and does not depend on the size of the array.
|
||||
//! If there is no free space at the beginning of the array
|
||||
//! then all iterators and references
|
||||
//! (including the past-the-begin iterator) are invalidated.
|
||||
//! Otherwise only the past-the-begin iterator is invalidated.
|
||||
//! \~russian Если в начале массива имеется свободное место,
|
||||
//! что часто бывает, то добавление будет очень быстрым.
|
||||
//! В любом случае добавление быстрое и не зависит от размера массива.
|
||||
//! Если в начале массива нет свободного места,
|
||||
//! то все итераторы и указатели становятся нерабочими.
|
||||
//! В противном случае все, кроме итераторов указывающих, на начало массива,
|
||||
//! остаются в рабочем состоянии.
|
||||
//! \~\sa \a push_back(), \a append(), \a prepend(), \a insert()
|
||||
inline PIByteArray & prepend(uchar e) {
|
||||
d.prepend(e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Appends the given array `v` to the begin of the array.
|
||||
//! \~russian Добавляет массив `v` в начало массива.
|
||||
//! \~\details
|
||||
//! \~english Overloaded function.
|
||||
//! \~russian Перегруженая функция.
|
||||
//! \~\sa \a prepend()
|
||||
inline PIByteArray & prepend(const PIByteArray & v) {
|
||||
d.prepend(v.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Appends the given elements to the begin of the array.
|
||||
//! \~russian Добавляет элементы в начало массива.
|
||||
//! \~\details
|
||||
//! \~english Overloaded function.
|
||||
//! Appends the given elements from
|
||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~russian Перегруженая функция.
|
||||
//! Добавляет элементы из
|
||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~\sa \a append()
|
||||
inline PIByteArray & prepend(std::initializer_list<uchar> init_list) {
|
||||
d.prepend(init_list);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Remove one element from the end of the array.
|
||||
//! \~russian Удаляет один элемент с конца массива.
|
||||
//! \~\details
|
||||
//! \~english Deleting an element from the end is very fast
|
||||
//! and does not depend on the size of the array.
|
||||
//! \~russian Удаление элемента с конца выполняется очень быстро
|
||||
//! и не зависит от размера массива.
|
||||
//! \~\sa \a pop_front(), \a take_back(), \a take_front()
|
||||
inline PIByteArray & pop_back() {
|
||||
d.pop_back();
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Remove one element from the begining of the array.
|
||||
//! \~russian Удаляет один элемент с начала массива.
|
||||
//! \~\details
|
||||
//! \~english Removing an element from the beginning takes longer than from the end.
|
||||
//! This time is directly proportional to the size of the array.
|
||||
//! All iterators and references are invalidated.
|
||||
//! \~russian Удаление элемента с начала выполняется дольше, чем с конца.
|
||||
//! Это время прямопропорционально размеру массива.
|
||||
//! При удалении элемента все итераторы и указатели становятся нерабочими.
|
||||
//! \~\sa \a pop_back(), \a take_back(), \a take_front()
|
||||
inline PIByteArray & pop_front() {
|
||||
d.pop_front();
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Remove one element from the end of the array and return it.
|
||||
//! \~russian Удаляет один элемент с начала массива и возвращает его.
|
||||
//! \~\details
|
||||
//! \~\sa \a take_front(), \a pop_back(), \a pop_front()
|
||||
inline uchar take_back() {
|
||||
return d.take_back();
|
||||
}
|
||||
|
||||
//! \~english Remove one element from the begining of the array and return it.
|
||||
//! \~russian Удаляет один элемент с конца массива и возвращает его.
|
||||
//! \~\details
|
||||
//! \~\sa \a take_front(), \a pop_back(), \a pop_front()
|
||||
inline uchar take_front() {
|
||||
return d.take_front();
|
||||
}
|
||||
|
||||
//! \~english Returns a new array with all elements
|
||||
//! that pass the test implemented by the provided function `test`.
|
||||
//! \~russian Возвращает новый массив со всеми элементами,
|
||||
//! прошедшими проверку, задаваемую в передаваемой функции `test`.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIByteArray v{3, 2, 5, 2, 7};
|
||||
//! PIByteArray v2 = v.filter([](const uchar & i){return i > 2;});
|
||||
//! piCout << v2; // {3, 5, 7}
|
||||
//! \endcode
|
||||
//! \~\sa \a map(), \a any(), \a every()
|
||||
inline PIByteArray filter(std::function<bool(const uchar & e)> test) const {
|
||||
return PIByteArray(d.filter(test));
|
||||
}
|
||||
|
||||
//! \~english Execute function `void f(const uchar & e)` for every element in array.
|
||||
//! \~russian Выполняет функцию `void f(const uchar & e)` для каждого элемента массива.
|
||||
//! \~\details
|
||||
//! \~russian Не позволяет изменять элементы массива.
|
||||
//! Для редактирования элементов используйте функцию вида `void f(uchar & e)`.
|
||||
//! \~english Does not allow changing array elements.
|
||||
//! To edit elements, use the function like `void f(T & e)`
|
||||
//! \~\code
|
||||
//! PIByteArray v{1, 2, 3, 4, 5};
|
||||
//! int s = 0;
|
||||
//! v.forEach([&s](const uchar & e){s += e;});
|
||||
//! piCout << s; // 15
|
||||
//! \endcode
|
||||
//! \~\sa \a filter(), \a map(), \a reduce(), \a any(), \a every()
|
||||
inline void forEach(std::function<void(const uchar & e)> f) const {
|
||||
d.forEach(f);
|
||||
}
|
||||
|
||||
//! \~english Execute function `void f(uchar & e)` for every element in array.
|
||||
//! \~russian Выполняет функцию `void f(uchar & e)` для каждого элемента массива.
|
||||
//! \~\details
|
||||
//! \~english Overloaded function.
|
||||
//! Allows you to change the elements of the array.
|
||||
//! \~russian Перегруженая функция.
|
||||
//! Позволяет изменять элементы массива.
|
||||
//! \~\code
|
||||
//! PIByteArray v{1, 2, 3, 4, 5};
|
||||
//! v.forEach([](uchar & e){e++;});
|
||||
//! piCout << v; // {2, 3, 4, 5, 6}
|
||||
//! \endcode
|
||||
//! \~\sa \a filter(), \a map(), \a reduce(), \a any(), \a every()
|
||||
inline PIByteArray & forEach(std::function<void(uchar & e)> f) {
|
||||
d.forEach(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Сreates a new array populated with the results
|
||||
//! of calling a provided function `ST f(const uchar & e)` on every element in the calling array.
|
||||
//! \~russian Создаёт новый массив с результатом вызова указанной функции
|
||||
//! `ST f(const T & e)` для каждого элемента массива.
|
||||
//! \~\details
|
||||
//! \~english Calls a provided function`ST f(const uchar & e)`
|
||||
//! once for each element in an array, in order,
|
||||
//! and constructs a new array from the results.
|
||||
//! \~russian Метод `map` вызывает переданную функцию `ST f(const uchar & e)`
|
||||
//! один раз для каждого элемента в порядке их появления
|
||||
//! и конструирует новый массив из результатов её вызова.
|
||||
//! \~\code
|
||||
//! PIByteArray v{0x31, 0x0A, 0xFF};
|
||||
//! PIStringList sl = v.map<PIString>([](const uchar & i){return PIString::fromNumber(i, 16);});
|
||||
//! piCout << sl; {"31", "A", "FF"}
|
||||
//! \endcode
|
||||
//! \~\sa \a forEach(), \a reduce()
|
||||
template <typename ST>
|
||||
inline PIDeque<ST> map(std::function<ST(const uchar & e)> f) const {
|
||||
return d.map<ST>(f);
|
||||
}
|
||||
|
||||
//! \~english Applies the function `ST f(const uchar & e, const ST & acc)`
|
||||
//! to each element of the array (from left to right), returns one value.
|
||||
//! \~russian Применяет функцию `ST f(const uchar & e, const ST & acc)`
|
||||
//! к каждому элементу массива (слева-направо), возвращает одно значение.
|
||||
//! \~\details
|
||||
//! \~english The reduce() method performs the `f` function
|
||||
//! once for each element in the array.
|
||||
//! If the `initial` argument is passed when calling reduce(),
|
||||
//! then when the function `f` is called for the first time,
|
||||
//! the value of `acc` will be assigned to `initial`.
|
||||
//! If the array is empty, the value `initial` will be returned.
|
||||
//! \param f is a function like `ST f(const uchar & e, const ST & acc)`,
|
||||
//! executed for each element of the array. It takes two arguments:
|
||||
//! * **e** - current element of the array
|
||||
//! * **acc** - accumulator accumulating the value
|
||||
//! which this function returns after visiting the next element
|
||||
//!
|
||||
//! \param initial _optional_ Object used as the second argument
|
||||
//! when the `f` function is first called.
|
||||
//! \~russian Метод reduce() выполняет функцию `f`
|
||||
//! один раз для каждого элемента, присутствующего в массиве.
|
||||
//! Если при вызове reduce() передан аргумент `initial`,
|
||||
//! то при первом вызове функции `f` значение `acc`
|
||||
//! будет равным значению `initial`.
|
||||
//! Если массив пустой то будет возвращено значение `initial`.
|
||||
//! \param f Функция, вида `ST f(const uchar & e, const ST & acc)`,
|
||||
//! выполняющаяся для каждого элемента массива.
|
||||
//! Она принимает два аргумента:
|
||||
//! * **e** - текущий элемент массива
|
||||
//! * **acc** - аккумулятор, аккумулирующий значение
|
||||
//! которое возвращает эта функция после посещения очередного элемента
|
||||
//!
|
||||
//! \param initial _опциональный_ Объект,
|
||||
//! используемый в качестве второго аргумента при первом вызове функции `f`.
|
||||
//!
|
||||
//! \~\code
|
||||
//! PIByteArray v{1, 2, 3, 4, 5};
|
||||
//! PIString s = v.reduce<PIString>([](const uchar & e, const PIString & acc){return acc + PIString::fromNumber(e);});
|
||||
//! piCout << s; // "12345"
|
||||
//! \endcode
|
||||
//! \~\sa \a forEach(), \a map()
|
||||
template <typename ST>
|
||||
inline ST reduce(std::function<ST(const uchar & e, const ST & acc)> f, const ST & initial = ST()) const {
|
||||
return d.reduce<ST>(f, initial);
|
||||
}
|
||||
|
||||
//! \~english Convert data to Base 64 and return this byte array
|
||||
//! \~russian Преобразует данные в Base 64 и возвращает текущий массив
|
||||
PIByteArray & convertToBase64();
|
||||
|
||||
//! \~english Convert data from Base 64 and return this byte array
|
||||
//! \~russian Преобразует данные из Base 64 и возвращает текущий массив
|
||||
PIByteArray & convertFromBase64();
|
||||
|
||||
//! \~english Return converted to Base 64 data
|
||||
//! \~russian Возвращает копию байтового массива, преобразованного в Base 64
|
||||
PIByteArray toBase64() const;
|
||||
|
||||
PIByteArray & compressRLE(uchar threshold = 192);
|
||||
PIByteArray & decompressRLE(uchar threshold = 192);
|
||||
PIByteArray compressedRLE(uchar threshold = 192) {PIByteArray ba(*this); ba.compressRLE(threshold); return ba;}
|
||||
PIByteArray decompressedRLE(uchar threshold = 192) {PIByteArray ba(*this); ba.decompressRLE(threshold); return ba;}
|
||||
|
||||
//! \~english Return string representation of data, each byte in "base" base, separated by spaces
|
||||
//! \~russian Возвращает текстовое представление байтового массива, каждый байт в "base" системе, с пробелами
|
||||
PIString toString(int base = 16) const;
|
||||
|
||||
//! \~english
|
||||
//! Returns a hex encoded copy of the byte array, without spaces.
|
||||
//! The hex encoding uses the numbers 0-9 and the letters a-f.
|
||||
//! \~russian
|
||||
//! Возвращает шестнадцатеричное представление массива, без пробелов.
|
||||
//! Оно использует цифры 0-9 и буквы a-f.
|
||||
PIString toHex() const;
|
||||
|
||||
//! \~english Add to the end data "data" with size "size"
|
||||
//! \~russian Добавляет в конец массива данные по указателю "data" размером "size"
|
||||
PIByteArray & append(const void * data_, int size_) {uint ps = size(); enlarge(size_); memcpy(data(ps), data_, size_); return *this;}
|
||||
|
||||
//! \~english Add to the end byte array "data"
|
||||
//! \~russian Добавляет в конец массива содержимое массива "data"
|
||||
PIByteArray & append(const PIByteArray & data_) {uint ps = size(); enlarge(data_.size_s()); memcpy(data(ps), data_.data(), data_.size()); return *this;}
|
||||
|
||||
//! \~english Add to the end "t"
|
||||
//! \~russian Добавляет в конец массива байт "t"
|
||||
PIByteArray & append(uchar t) {push_back(t); return *this;}
|
||||
|
||||
//! \~english Appends the given elements to the end of the array.
|
||||
//! \~russian Добавляет элементы в конец массива.
|
||||
//! \~\details
|
||||
//! \~english Overloaded function.
|
||||
//! Appends the given elements from
|
||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~russian Перегруженая функция.
|
||||
//! Добавляет элементы из
|
||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~\sa \a push_back()
|
||||
inline PIByteArray & append(std::initializer_list<uchar> init_list) {
|
||||
d.append(init_list);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Returns 8-bit checksum
|
||||
//! \~russian Возвращает 8-битную контрольную сумму
|
||||
uchar checksumPlain8(bool inverse = true) const;
|
||||
|
||||
//! \~english Returns 32-bit checksum
|
||||
//! \~russian Возвращает 32-битную контрольную сумму
|
||||
uint checksumPlain32(bool inverse = true) const;
|
||||
|
||||
//! \~english Returns 8-bit checksum CRC-8
|
||||
//! \~russian Возвращает 8-битную контрольную сумму CRC-8
|
||||
uchar checksumCRC8() const;
|
||||
|
||||
//! \~english Returns 16-bit checksum CRC-16
|
||||
//! \~russian Возвращает 16-битную контрольную сумму CRC-16
|
||||
ushort checksumCRC16() const;
|
||||
|
||||
//! \~english Returns 32-bit checksum CRC-32
|
||||
//! \~russian Возвращает 32-битную контрольную сумму CRC-32
|
||||
uint checksumCRC32() const;
|
||||
|
||||
//! \~english Returns hash of content
|
||||
//! \~russian Возвращает хэш содержимого
|
||||
uint hash() const;
|
||||
|
||||
void operator =(const PIDeque<uchar> & o) {resize(o.size()); memcpy(data(), o.data(), o.size());}
|
||||
|
||||
PIByteArray & operator =(const PIByteArray & o) {if (this == &o) return *this; clear(); append(o); return *this;}
|
||||
|
||||
PIByteArray & operator =(PIByteArray && o) {swap(o); return *this;}
|
||||
|
||||
static PIByteArray fromUserInput(PIString str);
|
||||
|
||||
static PIByteArray fromHex(PIString str);
|
||||
|
||||
//! \~english Return converted from Base 64 data
|
||||
//! \~russian Возвращает массив из Base 64 представления
|
||||
static PIByteArray fromBase64(const PIByteArray & base64);
|
||||
static PIByteArray fromBase64(const PIString & base64);
|
||||
|
||||
|
||||
bool binaryStreamAppendImp(const void * d_, size_t s) {
|
||||
append(d_, s);
|
||||
return true;
|
||||
}
|
||||
bool binaryStreamTakeImp(void * d_, size_t s) {
|
||||
size_t rs = size();
|
||||
if (rs > s) rs = s;
|
||||
memcpy(d_, data(), rs);
|
||||
remove(0, rs);
|
||||
return rs == s;
|
||||
}
|
||||
|
||||
ssize_t binaryStreamSizeImp() const {return size();}
|
||||
|
||||
private:
|
||||
PIDeque<uchar> d;
|
||||
|
||||
};
|
||||
|
||||
//! \relatesalso PIByteArray
|
||||
//! \~english Byte arrays compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator <(const PIByteArray & v0, const PIByteArray & v1) {
|
||||
if (v0.size() == v1.size()) {
|
||||
if (v0.isEmpty()) return false;
|
||||
return memcmp(v0.data(), v1.data(), v0.size()) < 0;
|
||||
}
|
||||
return v0.size() < v1.size();
|
||||
}
|
||||
|
||||
//! \relatesalso PIByteArray
|
||||
//! \~english Byte arrays compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator >(const PIByteArray & v0, const PIByteArray & v1) {
|
||||
if (v0.size() == v1.size()) {
|
||||
if (v0.isEmpty()) return false;
|
||||
return memcmp(v0.data(), v1.data(), v0.size()) > 0;
|
||||
}
|
||||
return v0.size() > v1.size();
|
||||
}
|
||||
|
||||
//! \relatesalso PIByteArray
|
||||
//! \~english Byte arrays compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator ==(const PIByteArray & v0, const PIByteArray & v1) {
|
||||
if (v0.size() == v1.size()) {
|
||||
if (v0.isEmpty()) return true;
|
||||
return memcmp(v0.data(), v1.data(), v0.size()) == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//! \relatesalso PIByteArray
|
||||
//! \~english Byte arrays compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator !=(const PIByteArray & v0, const PIByteArray & v1) {
|
||||
if (v0.size() == v1.size()) {
|
||||
if (v0.isEmpty()) return false;
|
||||
return memcmp(v0.data(), v1.data(), v0.size()) != 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef PIP_STD_IOSTREAM
|
||||
//! \relatesalso PIByteArray \brief Output to std::ostream operator
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba);
|
||||
#endif
|
||||
|
||||
//! \relatesalso PIByteArray
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
PIP_EXPORT PICout operator <<(PICout s, const PIByteArray & ba);
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIByteArray) {
|
||||
s.binaryStreamAppend((int)v.size_s());
|
||||
s.binaryStreamAppend(v.data(), v.size());
|
||||
return s;
|
||||
}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ(PIByteArray) {
|
||||
v.resize(s.binaryStreamTakeInt());
|
||||
s.binaryStreamTake(v.data(), v.size());
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PIByteArray
|
||||
//! \~english Returns PIByteArray::hash() of "ba"
|
||||
//! \~russian Возвращает PIByteArray::hash() от "ba"
|
||||
template<> inline uint piHash(const PIByteArray & ba) {return ba.hash();}
|
||||
|
||||
//! \relatesalso PIByteArray
|
||||
//! \~english Swap contents betwee "f" and "s"
|
||||
//! \~russian Меняет содержимое массивов "f" и "s"
|
||||
template<> inline void piSwap(PIByteArray & f, PIByteArray & s) {f.swap(s);}
|
||||
|
||||
|
||||
//! \relatesalso PIByteArray
|
||||
//! \~english Store "value" to bytearray and returns it
|
||||
//! \~russian Сохраняет "value" в байтовый массив и возвращает его
|
||||
template <typename T> PIByteArray piSerialize(const T & value) {
|
||||
PIByteArray ret;
|
||||
ret << value;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! \relatesalso PIByteArray
|
||||
//! \~english Restore type "T" from bytearray "data" and returns it
|
||||
//! \~russian Извлекает тип "T" из байтового массива "data" и возвращает его
|
||||
template <typename T> T piDeserialize(const PIByteArray & data) {
|
||||
T ret;
|
||||
if (!data.isEmpty()) {
|
||||
PIByteArray ba(data);
|
||||
ba >> ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif // PIBYTEARRAY_H
|
||||
@@ -1,385 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Unicode char
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "pistring.h"
|
||||
#ifdef PIP_ICU
|
||||
# define U_NOEXCEPT
|
||||
# include "unicode/ucnv.h"
|
||||
# include "unicode/ustring.h"
|
||||
#endif
|
||||
#ifdef WINDOWS
|
||||
# include <stringapiset.h>
|
||||
# include <winnls.h>
|
||||
#endif
|
||||
char * __syslocname__ = 0;
|
||||
char * __sysoemname__ = 0;
|
||||
char * __utf8name__ = 0;
|
||||
#ifdef BLACKBERRY
|
||||
# include <ctype.h>
|
||||
#endif
|
||||
#include <wchar.h>
|
||||
|
||||
//! \class PIChar pichar.h
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This class is wrapper around UTF16.
|
||||
//! There are many contructors and information functions
|
||||
//!
|
||||
//! \~russian
|
||||
//! %PIChar хранит один сивол в UTF16. Имеет много контрукторов, геттеров в различные
|
||||
//! кодировки (системную, консольную, UTF8) и информационных функций.
|
||||
//!
|
||||
|
||||
|
||||
ushort charFromCodepage(const char * c, int size, const char * codepage, int * taken = 0) {
|
||||
if (!c || size <= 0) return 0;
|
||||
if (uchar(c[0]) < 0x80) return c[0];
|
||||
int ret;
|
||||
#ifdef PIP_ICU
|
||||
UErrorCode e((UErrorCode)0);
|
||||
UConverter * cc = ucnv_open(codepage, &e);
|
||||
if (cc) {
|
||||
UChar uc(0);
|
||||
e = (UErrorCode)0;
|
||||
ret = ucnv_toUChars(cc, &uc, 1, c, size, &e);
|
||||
//printf("PIChar %d -> %d\n", c[0], uc);
|
||||
if (taken) *taken = ret;
|
||||
ucnv_close(cc);
|
||||
return ushort(uc);
|
||||
}
|
||||
#else
|
||||
# ifdef WINDOWS
|
||||
wchar_t buffer;
|
||||
ret = MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, size, &buffer, 1);
|
||||
if (ret <= 0) return 0;
|
||||
if (taken) *taken = ret;
|
||||
return buffer;
|
||||
# else
|
||||
mbstate_t state;
|
||||
memset(&state, 0, sizeof(state));
|
||||
wchar_t wc;
|
||||
ret = mbrtowc(&wc, c, size, &state);
|
||||
//printf("mbtowc = %d\n", ret);
|
||||
//piCout << errorString();
|
||||
if (ret < 1) return 0;
|
||||
return ushort(wc);
|
||||
# endif
|
||||
#endif
|
||||
return ushort(c[0]);
|
||||
}
|
||||
|
||||
|
||||
int charCompare(const PIChar & f, const PIChar & s) {
|
||||
if (f.isAscii() && s.isAscii())
|
||||
return strncmp(f.toCharPtr(), s.toCharPtr(), 1);
|
||||
return
|
||||
#ifdef PIP_ICU
|
||||
u_strCompare((const UChar*)f.toWCharPtr(), 1, (const UChar*)s.toWCharPtr(), 1, FALSE);
|
||||
#else
|
||||
# ifdef WINDOWS
|
||||
CompareStringW(LOCALE_USER_DEFAULT, 0, (PCNZWCH)f.toWCharPtr(), 1, (PCNZWCH)s.toWCharPtr(), 1) - 2;
|
||||
# else
|
||||
wcsncmp((const wchar_t *)f.toWCharPtr(), (const wchar_t *)s.toWCharPtr(), 1);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool winIsCharType(const ushort * ch, int type) {
|
||||
#ifdef WINDOWS
|
||||
WORD attr = 0;
|
||||
if (GetStringTypeW(CT_CTYPE1, (LPCWCH)ch, 1, &attr) == 0) return false;
|
||||
return ((attr & type) == type);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PIChar::PIChar(const char * c, int * bytes) {
|
||||
ch = charFromCodepage(c, 4, __syslocname__, bytes);
|
||||
}
|
||||
|
||||
|
||||
PIChar PIChar::fromConsole(char c) {
|
||||
PIChar ret;
|
||||
ret.ch = charFromCodepage(&c, 1, __sysoemname__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIChar PIChar::fromSystem(char c) {
|
||||
PIChar ret;
|
||||
ret.ch = charFromCodepage(&c, 1, __syslocname__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIChar PIChar::fromUTF8(const char * c) {
|
||||
PIChar ret;
|
||||
int l = 0;
|
||||
while (c[l] != '\0') ++l;
|
||||
ret.ch = charFromCodepage(c, l, __utf8name__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::operator ==(const PIChar & o) const {
|
||||
return ch == o.ch;
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::operator >(const PIChar & o) const {
|
||||
return charCompare(*this, o) > 0;
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::operator <(const PIChar & o) const {
|
||||
return charCompare(*this, o) < 0;
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::operator >=(const PIChar & o) const {
|
||||
return charCompare(*this, o) >= 0;
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::operator <=(const PIChar & o) const {
|
||||
return charCompare(*this, o) <= 0;
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::isDigit() const {
|
||||
if (isAscii()) return isdigit(ch) != 0;
|
||||
#ifdef WINDOWS
|
||||
return winIsCharType(&ch, C1_DIGIT);
|
||||
#else
|
||||
return iswdigit(ch) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::isHex() const {
|
||||
if (isAscii()) return isxdigit(ch) != 0;
|
||||
#ifdef WINDOWS
|
||||
return winIsCharType(&ch, C1_XDIGIT);
|
||||
#else
|
||||
return iswxdigit(ch) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::isGraphical() const {
|
||||
if (isAscii()) return isgraph(ch) != 0;
|
||||
#ifdef WINDOWS
|
||||
return !winIsCharType(&ch, C1_CNTRL);
|
||||
#else
|
||||
return iswgraph(ch) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::isControl() const {
|
||||
if (isAscii()) return iscntrl(ch) != 0;
|
||||
#ifdef WINDOWS
|
||||
return winIsCharType(&ch, C1_CNTRL);
|
||||
#else
|
||||
return iswcntrl(ch) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::isLower() const {
|
||||
if (isAscii()) return islower(ch) != 0;
|
||||
#ifdef WINDOWS
|
||||
return winIsCharType(&ch, C1_LOWER);
|
||||
#else
|
||||
return iswlower(ch) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::isUpper() const {
|
||||
if (isAscii()) return isupper(ch) != 0;
|
||||
#ifdef WINDOWS
|
||||
return winIsCharType(&ch, C1_UPPER);
|
||||
#else
|
||||
return iswupper(ch) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::isPrint() const {
|
||||
if (isAscii()) return isprint(ch) != 0;
|
||||
#ifdef WINDOWS
|
||||
return !winIsCharType(&ch, C1_CNTRL);
|
||||
#else
|
||||
return iswprint(ch) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::isSpace() const {
|
||||
if (isAscii()) return isspace(ch) != 0;
|
||||
#ifdef WINDOWS
|
||||
return winIsCharType(&ch, C1_SPACE);
|
||||
#else
|
||||
return iswspace(ch) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::isAlpha() const {
|
||||
if (isAscii()) return isalpha(ch) != 0;
|
||||
#ifdef WINDOWS
|
||||
return winIsCharType(&ch, C1_ALPHA);
|
||||
#else
|
||||
return iswalpha(ch) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIChar::isAscii() const {
|
||||
return isascii(ch) != 0;
|
||||
}
|
||||
|
||||
|
||||
const wchar_t * PIChar::toWCharPtr() const {
|
||||
return reinterpret_cast<const wchar_t * >(&ch);
|
||||
}
|
||||
|
||||
|
||||
const char * PIChar::toCharPtr() const {
|
||||
return reinterpret_cast<const char * >(&ch);
|
||||
}
|
||||
|
||||
|
||||
wchar_t PIChar::toWChar() const {
|
||||
return wchar_t(ch);
|
||||
}
|
||||
|
||||
|
||||
char PIChar::toConsole1Byte() const {
|
||||
if (ch < 0x80) return ch;
|
||||
#ifdef PIP_ICU
|
||||
UErrorCode e((UErrorCode)0);
|
||||
UConverter * cc = ucnv_open(__sysoemname__, &e);
|
||||
if (cc) {
|
||||
char uc[8];
|
||||
e = (UErrorCode)0;
|
||||
ucnv_fromUChars(cc, uc, 8, (const UChar*)(&ch), 1, &e);
|
||||
ucnv_close(cc);
|
||||
return uc[0];
|
||||
}
|
||||
#endif
|
||||
#ifdef WINDOWS
|
||||
char ret[4] = {0,0,0,0};
|
||||
WideCharToMultiByte(CP_OEMCP, 0, (LPCWCH)&ch, 1, ret, 4, NULL, NULL);
|
||||
return ret[0];
|
||||
#endif
|
||||
return toAscii();
|
||||
}
|
||||
|
||||
|
||||
char PIChar::toSystem() const {
|
||||
if (ch < 0x80) return ch;
|
||||
#ifdef PIP_ICU
|
||||
UErrorCode e((UErrorCode)0);
|
||||
UConverter * cc = ucnv_open(__syslocname__, &e);
|
||||
if (cc) {
|
||||
char uc[8];
|
||||
e = (UErrorCode)0;
|
||||
ucnv_fromUChars(cc, uc, 8, (const UChar*)(&ch), 1, &e);
|
||||
ucnv_close(cc);
|
||||
return uc[0];
|
||||
}
|
||||
#endif
|
||||
#ifdef WINDOWS
|
||||
char ret[4] = {0,0,0,0};
|
||||
WideCharToMultiByte(CP_ACP, 0, (LPCWCH)&ch, 1, ret, 4, NULL, NULL);
|
||||
return ret[0];
|
||||
#endif
|
||||
return toAscii();
|
||||
}
|
||||
|
||||
|
||||
PIChar PIChar::toUpper() const {
|
||||
if (isAscii()) return PIChar((ushort)toupper(ch));
|
||||
#ifdef PIP_ICU
|
||||
UChar c(0);
|
||||
UErrorCode e((UErrorCode)0);
|
||||
u_strToUpper(&c, 1, (const UChar*)(&ch), 1, 0, &e);
|
||||
return PIChar((ushort)c);
|
||||
#else
|
||||
# ifdef WINDOWS
|
||||
ushort wc = 0;
|
||||
if (LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE, (LPCWSTR)&ch, 1, (LPWSTR)&wc, 1) == 1)
|
||||
return PIChar(wc);
|
||||
# endif
|
||||
#endif
|
||||
return PIChar((ushort)towupper(ch));
|
||||
}
|
||||
|
||||
|
||||
PIChar PIChar::toLower() const {
|
||||
if (isAscii()) return PIChar((ushort)tolower(ch));
|
||||
#ifdef PIP_ICU
|
||||
UChar c(0);
|
||||
UErrorCode e((UErrorCode)0);
|
||||
u_strToLower(&c, 1, (const UChar*)(&ch), 1, 0, &e);
|
||||
return PIChar((ushort)c);
|
||||
#else
|
||||
# ifdef WINDOWS
|
||||
ushort wc = 0;
|
||||
if (LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE, (LPCWSTR)&ch, 1, (LPWSTR)&wc, 1) == 1)
|
||||
return PIChar(wc);
|
||||
# endif
|
||||
#endif
|
||||
return PIChar((ushort)towlower(ch));
|
||||
}
|
||||
|
||||
|
||||
PICout operator <<(PICout s, const PIChar & v) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
if (v.isAscii()) s << char(v.ch);
|
||||
else {
|
||||
#ifdef PIP_ICU
|
||||
UErrorCode e((UErrorCode)0);
|
||||
UConverter * cc = ucnv_open(__syslocname__, &e);
|
||||
if (cc) {
|
||||
char uc[8];
|
||||
memset(uc, 0, 8);
|
||||
e = (UErrorCode)0;
|
||||
ucnv_fromUChars(cc, uc, 8, (const UChar*)(&v.ch), 1, &e);
|
||||
ucnv_close(cc);
|
||||
s << uc;
|
||||
} else
|
||||
#endif
|
||||
#ifdef WINDOWS
|
||||
s << v.toSystem();
|
||||
#else
|
||||
s << PIString(v);
|
||||
#endif
|
||||
}
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
@@ -1,265 +0,0 @@
|
||||
/*! \file pichar.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english Single string character
|
||||
* \~russian Один символ строки
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Unicode char
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PICHAR_H
|
||||
#define PICHAR_H
|
||||
|
||||
#include "piincludes.h"
|
||||
|
||||
extern PIP_EXPORT char * __syslocname__;
|
||||
extern PIP_EXPORT char * __sysoemname__;
|
||||
extern PIP_EXPORT char * __utf8name__;
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english %PIChar represents a single character.
|
||||
//! \~russian %PIChar представляет собой один символ строки.
|
||||
class PIP_EXPORT PIChar
|
||||
{
|
||||
friend class PIString;
|
||||
friend PICout operator <<(PICout s, const PIChar & v);
|
||||
public:
|
||||
//! \~english Contructs Ascii symbol
|
||||
//! \~russian Создает символ Ascii
|
||||
PIChar(char c) {ch = c;}
|
||||
|
||||
//! \~english Contructs ascii symbol
|
||||
//! \~russian Создает символ Ascii
|
||||
PIChar(uchar c) {ch = c;}
|
||||
|
||||
//! \~english Contructs 2-bytes symbol
|
||||
//! \~russian Создает 2-байтный символ
|
||||
PIChar(ushort c = 0) {ch = c;}
|
||||
|
||||
//! \~english Contructs 2-bytes symbol from `wchar_t`
|
||||
//! \~russian Создает 2-байтный символ из `wchar_t`
|
||||
PIChar(wchar_t c) {ch = c;}
|
||||
|
||||
//! \~english Contructs symbol from system locale and no more than 4 bytes of string
|
||||
//! \~russian Создает символ из системной локали не более 4 байт длины
|
||||
PIChar(const char * c, int * bytes = 0);
|
||||
|
||||
//! \~english Copy operator
|
||||
//! \~russian Оператор присваивания
|
||||
PIChar & operator =(const char v) {ch = v; return *this;}
|
||||
|
||||
//! \~english Copy operator
|
||||
//! \~russian Оператор присваивания
|
||||
PIChar & operator =(const wchar_t v) {ch = v; return *this;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator ==(const PIChar & o) const;
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator !=(const PIChar & o) const {return !(o == *this);}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator >(const PIChar & o) const;
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator <(const PIChar & o) const;
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator >=(const PIChar & o) const;
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator <=(const PIChar & o) const;
|
||||
|
||||
//! \~english Returns \b true if symbol is digit ('0' to '9')
|
||||
//! \~russian Возвращает \b true если символ является
|
||||
bool isDigit() const;
|
||||
|
||||
//! \~english Returns \b true if symbol is HEX digit ('0' to '9', 'a' to 'f', 'A' to 'F')
|
||||
//! \~russian Возвращает \b true если символ является HEX цифрой ('0' до '9', 'a' до 'f', 'A' до 'F')
|
||||
bool isHex() const;
|
||||
|
||||
//! \~english Returns \b true if symbol is drawable (without space)
|
||||
//! \~russian Возвращает \b true если символ является графическим (исключая пробельные)
|
||||
bool isGraphical() const;
|
||||
|
||||
//! \~english Returns \b true if symbol is control byte (< 32 or 127)
|
||||
//! \~russian Возвращает \b true если символ является контрольным (< 32 or 127)
|
||||
bool isControl() const;
|
||||
|
||||
//! \~english Returns \b true if symbol is in lower case
|
||||
//! \~russian Возвращает \b true если символ в нижнем регистре
|
||||
bool isLower() const;
|
||||
|
||||
//! \~english Returns \b true if symbol is in upper case
|
||||
//! \~russian Возвращает \b true если символ в верхнем регистре
|
||||
bool isUpper() const;
|
||||
|
||||
//! \~english Returns \b true if symbol is printable (with space)
|
||||
//! \~russian Возвращает \b true если символ является печатным (включая пробельные)
|
||||
bool isPrint() const;
|
||||
|
||||
//! \~english Returns \b true if symbol is space or tab
|
||||
//! \~russian Возвращает \b true если символ является пробельным или табуляцией
|
||||
bool isSpace() const;
|
||||
|
||||
//! \~english Returns \b true if symbol is alphabetical letter
|
||||
//! \~russian Возвращает \b true если символ является алфавитной буквой
|
||||
bool isAlpha() const;
|
||||
|
||||
//! \~english Returns \b true if symbol is Ascii (< 128)
|
||||
//! \~russian Возвращает \b true если символ является Ascii (< 128)
|
||||
bool isAscii() const;
|
||||
|
||||
const wchar_t * toWCharPtr() const;
|
||||
|
||||
//! \~english Returns as `char *` string
|
||||
//! \~russian Возвращает символ как указатель на `char *`
|
||||
const char * toCharPtr() const;
|
||||
|
||||
wchar_t toWChar() const;
|
||||
|
||||
//! \~english Returns symbol as Ascii
|
||||
//! \~russian Возвращает символ в Ascii
|
||||
char toAscii() const {return ch % 256;}
|
||||
|
||||
//! \~english Returns symbol as console codepage
|
||||
//! \~russian Возвращает символ в консольной кодировке
|
||||
char toConsole1Byte() const;
|
||||
|
||||
//! \~english Returns symbol as system codepage
|
||||
//! \~russian Возвращает символ в системной кодировке
|
||||
char toSystem() const;
|
||||
|
||||
ushort unicode16Code() const {return ch;}
|
||||
|
||||
//! \~english Returns symbol in upper case
|
||||
//! \~russian Возвращает символ в нижнем регистре
|
||||
PIChar toUpper() const;
|
||||
|
||||
//! \~english Returns symbol in lower case
|
||||
//! \~russian Возвращает символ в верхнем регистре
|
||||
PIChar toLower() const;
|
||||
|
||||
//! \~english Returns symbol from console codepage
|
||||
//! \~russian Возвращает символ из консольной кодировки
|
||||
static PIChar fromConsole(char c);
|
||||
|
||||
//! \~english Returns symbol from system codepage
|
||||
//! \~russian Возвращает символ из системной кодировки
|
||||
static PIChar fromSystem(char c);
|
||||
|
||||
//! \~english Returns symbol from UTF8 codepage
|
||||
//! \~russian Возвращает символ из UTF8 кодировки
|
||||
static PIChar fromUTF8(const char * c);
|
||||
|
||||
private:
|
||||
ushort ch;
|
||||
|
||||
};
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
PIP_EXPORT PICout operator <<(PICout s, const PIChar & v);
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);}
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator >(const char v, const PIChar & c) {return (PIChar(v) > c);}
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator <(const char v, const PIChar & c) {return (PIChar(v) < c);}
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator >=(const char v, const PIChar & c) {return (PIChar(v) >= c);}
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator <=(const char v, const PIChar & c) {return (PIChar(v) <= c);}
|
||||
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator ==(const char * v, const PIChar & c) {return (PIChar(v) == c);}
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator >(const char * v, const PIChar & c) {return (PIChar(v) > c);}
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator <(const char * v, const PIChar & c) {return (PIChar(v) < c);}
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator >=(const char * v, const PIChar & c) {return (PIChar(v) >= c);}
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator <=(const char * v, const PIChar & c) {return (PIChar(v) <= c);}
|
||||
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator ==(const int v, const PIChar & c) {return (PIChar((ushort)v) == c);}
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator >(const int v, const PIChar & c) {return (PIChar((ushort)v) > c);}
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator <(const int v, const PIChar & c) {return (PIChar((ushort)v) < c);}
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator >=(const int v, const PIChar & c) {return (PIChar((ushort)v) >= c);}
|
||||
|
||||
//! \relatesalso PIChar
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator <=(const int v, const PIChar & c) {return (PIChar((ushort)v) <= c);}
|
||||
|
||||
#endif // PICHAR_H
|
||||
@@ -1,263 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Binary markup serializator
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pichunkstream.h"
|
||||
|
||||
//! \class PIChunkStream pichunkstream.h
|
||||
//! \details
|
||||
//! \~english \section PIChunkStream_sec0 Synopsis
|
||||
//! \~russian \section PIChunkStream_sec0 Краткий обзор
|
||||
//! \~english
|
||||
//! This class provides very handly mechanism to store and restore values to and from
|
||||
//! \a PIByteArray. The main advantage of using this class is that your binary data
|
||||
//! become independent from order and collection of your values.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Этот класс предоставляет очень удобный механизм для сохранения и извлечения значений
|
||||
//! в/из \a PIByteArray. Главным плюсом является то, что данные не будут зависеть от порядка
|
||||
//! и наличия значений.
|
||||
//!
|
||||
//! \~english \section PIChunkStream_sec1 Mechanism
|
||||
//! \~russian \section PIChunkStream_sec1 Механизм
|
||||
//! \~english
|
||||
//! %PIChunkStream works with items called "chunk". Chunk is an ID, size and any value that
|
||||
//! can be stored and restored to/from %PIChunkStream with stream operators << and >>.
|
||||
//!
|
||||
//! To construct %PIChunkStream for writing data use any non-default constructor. Empty constructor
|
||||
//! creates internal buffer that can be accessed by function \a data().
|
||||
//! Non-empty constructor works with given byte array.
|
||||
//!
|
||||
//! To read chunks from byte array use function \a read() that returns ID of
|
||||
//! readed chunk. Then you can get value of this chunk with functions \a getData() or \a get(),
|
||||
//! but you should definitely know type of this value. You can read from byte array
|
||||
//! while \a atEnd() if false.
|
||||
//!
|
||||
//! \~russian
|
||||
//! %PIChunkStream работает с элементами под названием "чанк". Чанк имеет ID, размер и значение,
|
||||
//! и может быть записан или прочитан в/из %PIChunkStream с помощью операторов << и >>.
|
||||
//!
|
||||
//! Для создания потока на запись используется любой не-умолчальный конструктор. Пустой конструктор
|
||||
//! создает внутренний буфер, который можно получить с помощью метода \a data().
|
||||
//! Непустой конструктор работает с переданным байтовым массивом.
|
||||
//!
|
||||
//! Для чтения чанков из байтового массива используется метод \a read(), который возвращает
|
||||
//! ID прочитанного чанка. Получить значение этого чанка далее можно с помощью методов \a getData() или get(),
|
||||
//! но тип значения должен быть известен. Читать из потока можно пока метод \a atEnd() возвращает ложь.
|
||||
//!
|
||||
//! \~english \section PIChunkStream_sec2 Examples
|
||||
//! \~russian \section PIChunkStream_sec2 Пример
|
||||
//!
|
||||
//! \~english Using simple operator and cascade serialization:
|
||||
//! \~russian Использование простого оператора и каскадная сериализация:
|
||||
//!
|
||||
//! \~english Prepare your structs to work with %PIChunkStream:
|
||||
//! \~russian Подготовка своей структуры для работы с %PIChunkStream:
|
||||
//! \~\snippet pichunkstream.cpp struct
|
||||
//! \~english Old-style writing to %PIChunkStream:
|
||||
//! \~russian Старый стиль использования %PIChunkStream:
|
||||
//! \~\snippet pichunkstream.cpp write
|
||||
//! \~english Fastest reading from %PIChunkStream:
|
||||
//! \~russian Самое быстрое чтение из %PIChunkStream:
|
||||
//! \~\snippet pichunkstream.cpp read
|
||||
//!
|
||||
//! \~english And next code show how to serialize your struct with %PIChunkStream:
|
||||
//! \~russian Следующий код показывает, как сериализовать свою структуру в %PIChunkStream:
|
||||
//! \~\snippet pichunkstream.cpp write_new
|
||||
//!
|
||||
//! \~english ... and deserialize:
|
||||
//! \~russian ... и десериализовать:
|
||||
//! \~\snippet pichunkstream.cpp read_new
|
||||
//!
|
||||
|
||||
|
||||
void PIChunkStream::setSource(const PIByteArray & data) {
|
||||
data_ = const_cast<PIByteArray*>(&data);
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
void PIChunkStream::setSource(PIByteArray * data) {
|
||||
data_ = (data ? data : &tmp_data);
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PIChunkStream::data() const {
|
||||
if (first_byte_taken) {
|
||||
PIByteArray ret(*data_);
|
||||
ret.prepend((uchar)(0x80 | version_));
|
||||
return ret;
|
||||
}
|
||||
return *data_;
|
||||
}
|
||||
|
||||
|
||||
int PIChunkStream::read() {
|
||||
switch (version_) {
|
||||
case Version_1:
|
||||
(*data_) >> last_id >> last_data;
|
||||
break;
|
||||
case Version_2:
|
||||
last_id = readVInt(*data_);
|
||||
last_data.resize(readVInt(*data_));
|
||||
//piCout << last_id << last_data.size();
|
||||
(*data_) >> PIMemoryBlock(last_data.data(), last_data.size_s());
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return last_id;
|
||||
}
|
||||
|
||||
|
||||
int PIChunkStream::peekVInt(Version version_, uchar * data_, int sz, uint & ret) {
|
||||
switch (version_) {
|
||||
case Version_1:
|
||||
memcpy(&ret, data_, 4);
|
||||
return 4;
|
||||
case Version_2: {
|
||||
PIByteArray hdr(data_, piMini(4, sz));
|
||||
hdr.resize(4);
|
||||
uchar hsz = 0;
|
||||
ret = readVInt(hdr, &hsz);
|
||||
return hsz;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PIChunkStream::replaceChunk(int id, const PIByteArray & v) {
|
||||
if (!data_map.contains(id)) return;
|
||||
auto & pos(data_map[id]);
|
||||
PIByteArray nsba;
|
||||
writeVInt(nsba, v.size());
|
||||
int size_mod = (v.size_s() + nsba.size_s()) - (pos.length + pos.size_bytes);
|
||||
pos.length = v.size_s();
|
||||
if (size_mod != 0) {
|
||||
auto it = data_map.makeIterator();
|
||||
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 {
|
||||
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;
|
||||
memcpy(data_->data(pos.start), v.data(), pos.length);
|
||||
}
|
||||
|
||||
|
||||
void PIChunkStream::readAll() {
|
||||
data_map.clear();
|
||||
if (!data_) return;
|
||||
int pos = 0, sz = data_->size_s(), hsz = 0;
|
||||
uint csz = 0, cid = 0;
|
||||
while (pos < sz) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PIChunkStream::~PIChunkStream() {
|
||||
}
|
||||
|
||||
|
||||
bool PIChunkStream::extract(PIByteArray & data, bool read_all) {
|
||||
if (data.size_s() < 4) return false;
|
||||
data >> tmp_data;
|
||||
if (tmp_data.size_s() < 4) return false;
|
||||
data_ = &tmp_data;
|
||||
_init();
|
||||
if (read_all) readAll();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PIChunkStream::_init() {
|
||||
first_byte_taken = false;
|
||||
last_id = -1;
|
||||
last_data.clear();
|
||||
if (!data_->isEmpty()) {
|
||||
uchar v = data_->at(0);
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
version_ = Version_1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint PIChunkStream::readVInt(PIByteArray & s, uchar * bytes_cnt) {
|
||||
if (s.isEmpty()) return 0;
|
||||
uchar bytes[4];
|
||||
uchar abc;
|
||||
s >> bytes[0];
|
||||
for (abc = 0; abc < 3; ++abc) {
|
||||
uchar mask = (0x80 >> abc);
|
||||
if ((bytes[0] & mask) == mask) {
|
||||
bytes[0] &= (mask - 1);
|
||||
s >> bytes[abc + 1];
|
||||
} else break;
|
||||
}
|
||||
if (bytes_cnt) *bytes_cnt = (abc + 1);
|
||||
uint ret = 0;
|
||||
for (int i = 0; i <= abc; ++i) {
|
||||
ret += (bytes[i] << (8 * ((int)abc - i)));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void PIChunkStream::writeVInt(PIByteArray & s, uint val) {
|
||||
if (val > 0xfffffff) return;
|
||||
if (val <= 0x7f) {
|
||||
s << uchar(val);
|
||||
return;
|
||||
}
|
||||
if (val <= 0x3fff) {
|
||||
s << uchar((val >> 8) | 0x80) << uchar(val & 0xff);
|
||||
return;
|
||||
}
|
||||
if (val <= 0x1fffff) {
|
||||
s << uchar((val >> 16) | 0xc0) << uchar((val >> 8) & 0xff) << uchar(val & 0xff);
|
||||
return;
|
||||
}
|
||||
s << uchar((val >> 24) | 0xe0) << uchar((val >> 16) & 0xff) << uchar((val >> 8) & 0xff) << uchar(val & 0xff);
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
/*! \file pichunkstream.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english Binary markup de/serializator stream
|
||||
* \~russian Бинарный поток для де/сериализации с разметкой
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Binary markup serializator
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PICHUNKSTREAM_H
|
||||
#define PICHUNKSTREAM_H
|
||||
|
||||
#include "pibytearray.h"
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Class for binary de/serialization.
|
||||
//! \~russian Класс для бинарной де/сериализации.
|
||||
class PIP_EXPORT PIChunkStream
|
||||
{
|
||||
public:
|
||||
|
||||
//! \~english
|
||||
//! Version of data packing. Read-access %PIChunkStream automatic detect version, but write-access
|
||||
//! %PIChunkStream by default write in new version, be careful!
|
||||
//! \~russian
|
||||
//! Версия хранения данных. %PIChunkStream на чтение автоматически определяет версию, но для записи
|
||||
//! использует по умолчанию новую, осторожно!
|
||||
enum Version {
|
||||
Version_1 /*! \~english First, old version \~russian Первая, старая версия */,
|
||||
Version_2 /*! \~english Second, more optimized version \~russian Вторая, более оптимизированная версия */ = 2,
|
||||
};
|
||||
|
||||
//! \~english Contructs stream for read from "data"
|
||||
//! \~russian Создает поток на чтение из "data"
|
||||
PIChunkStream(const PIByteArray & data): version_(Version_2) {setSource(data);}
|
||||
|
||||
//! \~english Contructs stream for read or write to/from "data", or empty stream for write if "data" = 0
|
||||
//! \~russian Создает поток на чтение или запись из/в "data", или пустой поток на запись если "data" = 0
|
||||
PIChunkStream(PIByteArray * data = 0, Version v = Version_2): version_(v) {setSource(data);}
|
||||
|
||||
//! \~english Contructs empty stream for write with version \"v\"
|
||||
//! \~russian Создает пустой поток на запись с версией \"v\"
|
||||
PIChunkStream(Version v): version_(v) {setSource(0);}
|
||||
|
||||
~PIChunkStream();
|
||||
|
||||
template <typename T>
|
||||
struct Chunk {
|
||||
Chunk(int i, const T & d): id(i), data(d) {}
|
||||
int id;
|
||||
T data;
|
||||
};
|
||||
template <typename T>
|
||||
struct ChunkConst {
|
||||
ChunkConst(int i, const T & d): id(i), data(d) {}
|
||||
int id;
|
||||
const T & data;
|
||||
};
|
||||
|
||||
//! \~english Returns chunk with ID "id" and value "data" for write to stream
|
||||
//! \~russian Возвращает чанк с ID "id" и значением "data" для записи в поток
|
||||
template <typename T> static ChunkConst<T> chunk(int id, const T & data) {return ChunkConst<T>(id, data);}
|
||||
|
||||
//! \~english Add to this stream chunk with ID "id" and value "data"
|
||||
//! \~russian Добавляет в этот поток чанк с ID "id" и значением "data"
|
||||
template <typename T> PIChunkStream & add(int id, const T & data) {*this << ChunkConst<T>(id, data); return *this;}
|
||||
|
||||
//! \~english
|
||||
//! Extract %PIByteArray from "data" and set it current stream.
|
||||
//! If "read_all" then call \a readAll() after extract.
|
||||
//! Returns if has data to read.
|
||||
//! \~russian
|
||||
//! Извлекает %PIByteArray из "data" и инициализирует им поток.
|
||||
//! Если указан "read_all", то вызывает \a readAll() после инициализации.
|
||||
//! Возвращает если ли данные для чтения.
|
||||
bool extract(PIByteArray & data, bool read_all = false);
|
||||
|
||||
void setSource(const PIByteArray & data);
|
||||
void setSource(PIByteArray * data);
|
||||
|
||||
//! \~english Returns internal buffer with written data
|
||||
//! \~russian Возвращает внутренний буфер с записанными данными
|
||||
PIByteArray data() const;
|
||||
|
||||
//! \~english Returns if there is end of stream
|
||||
//! \~russian Возвращает достигнут ли конец потока
|
||||
bool atEnd() const {return data_->size_s() <= 1;}
|
||||
|
||||
//! \~english Returns stream version
|
||||
//! \~russian Возвращает версию потока
|
||||
Version version() const {return (Version)version_;}
|
||||
|
||||
|
||||
//! \~english Read one chunk from stream and returns its ID
|
||||
//! \~russian Читает один чанк из потока и возвращает его ID
|
||||
int read();
|
||||
|
||||
//! \~english Read all chunks from stream. This function just index input data
|
||||
//! \~russian Читает все чанки из потока. Данный метод лишь индексирует данные
|
||||
void readAll();
|
||||
|
||||
//! \~english Returns last readed chunk ID
|
||||
//! \~russian Возвращает ID последнего прочитанного чанка
|
||||
int getID() {return last_id;}
|
||||
|
||||
//! \~english Returns value of last readed chunk
|
||||
//! \~russian Возвращает значение последнего прочитанного чанка
|
||||
template <typename T>
|
||||
T getData() const {T ret{}; PIByteArray s(last_data); s >> ret; return ret;}
|
||||
|
||||
//! \~english Place value of last readed chunk into \"v\"
|
||||
//! \~russian Записывает значение последнего прочитанного чанка в \"v\"
|
||||
template <typename T>
|
||||
void get(T & v) const {v = getData<T>();}
|
||||
|
||||
//! \~english Place value of chunk with ID \"id\" into \"v\". You should call \a readAll() before using this function!
|
||||
//! \~russian Записывает значение чанка с ID \"id\" в \"v\". Необходимо вызвать \a readAll() перед использованием этого метода!
|
||||
template <typename T>
|
||||
const PIChunkStream & get(int id, T & v) const {
|
||||
CacheEntry pos = data_map.value(id);
|
||||
if (pos.start < 0 || pos.length == 0) return *this;
|
||||
PIByteArray ba(data_->data(pos.start), pos.length);
|
||||
if (!ba.isEmpty())
|
||||
ba >> v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Replace value of chunk with ID \"id\" to \"v\". You should call \a readAll() before using this function!
|
||||
//! \~russian Заменяет значение чанка с ID \"id\" на \"v\". Необходимо вызвать \a readAll() перед использованием этого метода!
|
||||
template <typename T>
|
||||
PIChunkStream & set(int id, const T & v) {
|
||||
PIByteArray ba;
|
||||
ba << v;
|
||||
replaceChunk(id, ba);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
void _init();
|
||||
|
||||
struct CacheEntry {
|
||||
CacheEntry(int s = 0, int l = 0, int b = 0): start(s), length(l), size_bytes(b) {}
|
||||
int start;
|
||||
int length;
|
||||
int size_bytes;
|
||||
};
|
||||
|
||||
static uint readVInt(PIByteArray & s, uchar * bytes = 0);
|
||||
static void writeVInt(PIByteArray & s, uint val);
|
||||
static int peekVInt(Version version_, uchar * data_, int sz, uint & ret);
|
||||
void replaceChunk(int id, const PIByteArray & v);
|
||||
|
||||
int last_id;
|
||||
uchar version_;
|
||||
mutable PIByteArray * data_, last_data, tmp_data;
|
||||
PIMap<int, CacheEntry> data_map;
|
||||
bool first_byte_taken;
|
||||
|
||||
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c);
|
||||
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::ChunkConst<T> & c);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c) {
|
||||
PIByteArray ba;
|
||||
ba << c.data;
|
||||
switch (s.version_) {
|
||||
case PIChunkStream::Version_1:
|
||||
(*(s.data_)) << c.id << ba;
|
||||
break;
|
||||
case PIChunkStream::Version_2:
|
||||
if (s.data_->isEmpty())
|
||||
(*(s.data_)) << uchar(uchar(s.version_) | 0x80);
|
||||
PIChunkStream::writeVInt(*(s.data_), c.id);
|
||||
PIChunkStream::writeVInt(*(s.data_), ba.size());
|
||||
s.data_->append(ba);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
template <typename T>
|
||||
PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::ChunkConst<T> & c) {
|
||||
PIByteArray ba;
|
||||
ba << c.data;
|
||||
switch (s.version_) {
|
||||
case PIChunkStream::Version_1:
|
||||
(*(s.data_)) << c.id << ba;
|
||||
break;
|
||||
case PIChunkStream::Version_2:
|
||||
if (s.data_->isEmpty())
|
||||
(*(s.data_)) << uchar(uchar(s.version_) | 0x80);
|
||||
PIChunkStream::writeVInt(*(s.data_), c.id);
|
||||
PIChunkStream::writeVInt(*(s.data_), ba.size());
|
||||
s.data_->append(ba);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif // PICHUNKSTREAM_H
|
||||
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
C-String class
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "piconstchars.h"
|
||||
#include "pistring.h"
|
||||
|
||||
|
||||
//! \~\class PIConstChars piconstchars.h
|
||||
//! \~\details
|
||||
//! \~english \section PIConstChars_sec0 Synopsis
|
||||
//! \~russian \section PIConstChars_sec0 Краткий обзор
|
||||
//! \~english
|
||||
//! This is wrapper around \c const char * string. %PIConstChars doesn`t
|
||||
//! copy string, just save pointer and size.
|
||||
//!
|
||||
//! Provides API similar to string, with information and compare methods.
|
||||
//!
|
||||
//! Used to more handly works with ordinary C-strings.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Это обертка вокруг \c const char * строки. %PIConstChars не скопирует
|
||||
//! строку, а хранит только указатель и размер.
|
||||
//!
|
||||
//! Предоставляет API схожий с обычной строкой, с методами сравнения и информационными.
|
||||
//!
|
||||
//! Используется для более удобной работы с обычными C-строками.
|
||||
//!
|
||||
|
||||
|
||||
bool PIConstChars::contains(char c) const {
|
||||
for (int i = 0; i < (int)len; ++i)
|
||||
if (str[i] == c) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PIConstChars::startsWith(const PIConstChars & str) const {
|
||||
if (size() < str.size()) return false;
|
||||
return str == left(str.size());
|
||||
}
|
||||
|
||||
|
||||
bool PIConstChars::startsWith(const char c) const {
|
||||
if (size() < 1) return false;
|
||||
return str[0] == c;
|
||||
}
|
||||
|
||||
|
||||
bool PIConstChars::endsWith(const PIConstChars & str) const {
|
||||
if (size() < str.size()) return false;
|
||||
return str == right(str.size());
|
||||
}
|
||||
|
||||
|
||||
bool PIConstChars::endsWith(const char c) const {
|
||||
if (size() < 1) return false;
|
||||
return str[len - 1] == c;
|
||||
}
|
||||
|
||||
|
||||
PIConstChars PIConstChars::mid(const int start, const int len) const {
|
||||
int s = start, l = len;
|
||||
if (l == 0 || s >= (int)size() || isEmpty()) return PIConstChars("");
|
||||
if (s < 0) {
|
||||
l += s;
|
||||
s = 0;
|
||||
}
|
||||
if (l < 0) {
|
||||
return PIConstChars(str + s, (int)size() - s);
|
||||
} else {
|
||||
if (l > (int)size() - s)
|
||||
l = (int)size() - s;
|
||||
return PIConstChars(str + s, l);
|
||||
}
|
||||
return PIConstChars("");
|
||||
}
|
||||
|
||||
|
||||
PIConstChars PIConstChars::left(const int l) const {
|
||||
if (l <= 0) return PIConstChars("");
|
||||
return mid(0, l);
|
||||
}
|
||||
|
||||
|
||||
PIConstChars PIConstChars::right(const int l) const {
|
||||
if (l <= 0) return PIConstChars("");
|
||||
return mid((int)size() - l, l);
|
||||
}
|
||||
|
||||
|
||||
PIConstChars & PIConstChars::cutLeft(const int l) {
|
||||
if (l <= 0) return *this;
|
||||
if (l >= (int)size())
|
||||
*this = PIConstChars("");
|
||||
else {
|
||||
str += l;
|
||||
len -= l;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIConstChars & PIConstChars::cutRight(const int l) {
|
||||
if (l <= 0) return *this;
|
||||
if (l >= (int)size())
|
||||
*this = PIConstChars("");
|
||||
else {
|
||||
len -= l;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIConstChars PIConstChars::takeLeft(const int len) {
|
||||
PIConstChars ret(left(len));
|
||||
cutLeft(len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIConstChars PIConstChars::takeRight(const int len) {
|
||||
PIConstChars ret(right(len));
|
||||
cutRight(len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIConstChars & PIConstChars::trim() {
|
||||
if (isEmpty()) return *this;
|
||||
int st = -1, fn = 0;
|
||||
for (int i = 0; i < (int)len; ++i) {
|
||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12) && at(i) != uchar(0)) {
|
||||
st = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (st < 0) {
|
||||
*this = PIConstChars("");
|
||||
return *this;
|
||||
}
|
||||
for (int i = (int)len - 1; i >= 0; --i) {
|
||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12) && at(i) != uchar(0)) {
|
||||
fn = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fn < (int)len - 1) cutRight((int)len - fn - 1);
|
||||
if (st > 0) cutLeft(st);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString PIConstChars::toString() const {
|
||||
if (isEmpty()) return PIString();
|
||||
return PIString::fromAscii(str, len);
|
||||
}
|
||||
@@ -1,266 +0,0 @@
|
||||
/*! \file piconstchars.h
|
||||
* \ingroup Core
|
||||
* \brief
|
||||
* \~english C-String class
|
||||
* \~russian Класс C-строки
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
C-String class
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PICONSTCHARS_H
|
||||
#define PICONSTCHARS_H
|
||||
|
||||
#include "picout.h"
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english C-String class.
|
||||
//! \~russian Класс C-строки.
|
||||
class PIP_EXPORT PIConstChars {
|
||||
public:
|
||||
|
||||
//! \~english Contructs an null string.
|
||||
//! \~russian Создает нулевую строку.
|
||||
PIConstChars() {}
|
||||
|
||||
//! \~english Contructs string from C-string "string".
|
||||
//! \~russian Создает строку из C-строки "string".
|
||||
PIConstChars(const char * string) {
|
||||
str = string;
|
||||
len = strlen(string);
|
||||
}
|
||||
|
||||
//! \~english Contructs string from "size" characters of buffer "data".
|
||||
//! \~russian Создает строку из "size" символов массива "data".
|
||||
PIConstChars(const char * data, size_t size) {
|
||||
str = data;
|
||||
len = size;
|
||||
}
|
||||
|
||||
//! \~english Contructs a copy of string.
|
||||
//! \~russian Создает копию строки.
|
||||
PIConstChars(const PIConstChars & o) {
|
||||
str = o.str;
|
||||
len = o.len;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Read-only access to character by `index`.
|
||||
//! \~russian Доступ на чтение к символу по индексу `index`.
|
||||
inline char operator [](size_t index) const {return str[index];}
|
||||
|
||||
//! \~english Read-only access to character by `index`.
|
||||
//! \~russian Доступ на чтение к символу по индексу `index`.
|
||||
inline char at(size_t index) const {return str[index];}
|
||||
|
||||
//! \~english Returns \c char * string pointer.
|
||||
//! \~russian Возвращает \c char * указатель строки.
|
||||
inline const char * data() const {return str;}
|
||||
|
||||
//! \~english Returns \c true if string doesn`t have any data.
|
||||
//! \~russian Возвращает \c true если строка не имеет данных.
|
||||
inline bool isNull() const {return !str;}
|
||||
|
||||
//! \~english Returns \c true if string is empty, i.e. length = 0, or null.
|
||||
//! \~russian Возвращает \c true если строка пустая, т.е. длина = 0, или нулевая.
|
||||
inline bool isEmpty() const {return len == 0;}
|
||||
|
||||
//! \~english Returns \c true if string is not empty, i.e. length > 0.
|
||||
//! \~russian Возвращает \c true если строка непустая, т.е. длина > 0.
|
||||
inline bool isNotEmpty() const {return len > 0;}
|
||||
|
||||
//! \~english Returns \c true if string contains character "c".
|
||||
//! \~russian Возвращает \c true если строка содержит символ "c".
|
||||
bool contains(char c) const;
|
||||
|
||||
//! \~english Returns characters length of string.
|
||||
//! \~russian Возвращает длину строки в символах.
|
||||
inline size_t length() const {return len;}
|
||||
|
||||
//! \~english Returns characters length of string.
|
||||
//! \~russian Возвращает длину строки в символах.
|
||||
inline size_t size() const {return len;}
|
||||
|
||||
//! \~english Returns characters length of string.
|
||||
//! \~russian Возвращает длину строки в символах.
|
||||
inline ssize_t size_s() const {return len;}
|
||||
|
||||
//! \~english Returns if string starts with "str".
|
||||
//! \~russian Возвращает начинается ли строка со "str".
|
||||
bool startsWith(const PIConstChars & str) const;
|
||||
|
||||
//! \~english Returns if string starts with "c".
|
||||
//! \~russian Возвращает начинается ли строка с "c".
|
||||
bool startsWith(const char c) const;
|
||||
|
||||
//! \~english Returns if string ends with "str".
|
||||
//! \~russian Возвращает оканчивается ли строка на "str".
|
||||
bool endsWith(const PIConstChars & str) const;
|
||||
|
||||
//! \~english Returns if string ends with "c".
|
||||
//! \~russian Возвращает оканчивается ли строка "c".
|
||||
bool endsWith(const char c) const;
|
||||
|
||||
//! \~english Returns part of string from character at index "start" and maximum length "len".
|
||||
//! \~russian Возвращает подстроку от символа "start" и максимальной длиной "len".
|
||||
//! \~\sa \a left(), \a right()
|
||||
PIConstChars mid(const int start, const int len = -1) const;
|
||||
|
||||
//! \~english Returns part of string from start and maximum length "len".
|
||||
//! \~russian Возвращает подстроку от начала и максимальной длиной "len".
|
||||
//! \~\sa \a mid(), \a right()
|
||||
PIConstChars left(const int len) const;
|
||||
|
||||
//! \~english Returns part of string at end and maximum length "len".
|
||||
//! \~russian Возвращает подстроку максимальной длиной "len" и до конца.
|
||||
//! \~\sa \a mid(), \a left()
|
||||
PIConstChars right(const int len) const;
|
||||
|
||||
//! \~english Remove part of string from start and maximum length "len" and return this string.
|
||||
//! \~russian Удаляет часть строки от начала и максимальной длины "len", возвращает эту строку.
|
||||
//! \~\sa \a cutRight()
|
||||
PIConstChars & cutLeft(const int len);
|
||||
|
||||
//! \~english Remove part of string at end and maximum length "len" and return this string.
|
||||
//! \~russian Удаляет часть строки максимальной длины "len" от конца, возвращает эту строку.
|
||||
//! \~\sa \a cutLeft()
|
||||
PIConstChars & cutRight(const int len);
|
||||
|
||||
//! \~english Take a part from the begin of string with maximum length "len" and return it.
|
||||
//! \~russian Извлекает часть строки от начала максимальной длины "len" и возвращает её.
|
||||
//! \~\sa \a takeRight()
|
||||
PIConstChars takeLeft(const int len);
|
||||
|
||||
//! \~english Take a part from the end of string with maximum length "len" and return it.
|
||||
//! \~russian Извлекает часть строки с конца максимальной длины "len" и возвращает её.
|
||||
//! \~\sa \a takeLeft()
|
||||
PIConstChars takeRight(const int len);
|
||||
|
||||
//! \~english Remove spaces at the start and at the end of string and return this string.
|
||||
//! \~russian Удаляет пробельные символы с начала и конца строки и возвращает эту строку.
|
||||
//! \~\sa \a trimmed()
|
||||
PIConstChars & trim();
|
||||
|
||||
//! \~english Returns copy of this string without spaces at the start and at the end.
|
||||
//! \~russian Возвращает копию этой строки без пробельных символов с начала и конца.
|
||||
//! \~\sa \a trim()
|
||||
PIConstChars trimmed() const {return PIConstChars(*this).trim();}
|
||||
|
||||
//! \~english Returns as PIString.
|
||||
//! \~russian Возвращает как PIString.
|
||||
PIString toString() const;
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
inline PIConstChars & operator =(const PIConstChars & s) {
|
||||
if (this == &s) return *this;
|
||||
len = s.len;
|
||||
str = s.str;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Assign move operator.
|
||||
//! \~russian Оператор перемещающего присваивания.
|
||||
inline PIConstChars & operator =(PIConstChars && s) {
|
||||
swap(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
inline PIConstChars & operator =(const char * s) {
|
||||
str = s;
|
||||
len = strlen(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
inline bool operator ==(const PIConstChars & s) const {
|
||||
if (isNull() && s.isNull()) return true;
|
||||
if (isNull() xor s.isNull()) return false;
|
||||
if (size() != s.size()) return false;
|
||||
return strcmp(str, s.str) == 0;
|
||||
}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
inline bool operator !=(const PIConstChars & s) const {return !(*this == s);}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
inline bool operator <(const PIConstChars & s) const {
|
||||
if ( isNull() && s.isNull()) return false;
|
||||
if ( isNull() && !s.isNull()) return true ;
|
||||
if (!isNull() && s.isNull()) return false;
|
||||
if (size() == s.size())
|
||||
return strcmp(str, s.str) < 0;
|
||||
return size() < s.size();
|
||||
}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
inline bool operator >(const PIConstChars & s) const {
|
||||
if ( isNull() && s.isNull()) return false;
|
||||
if ( isNull() && !s.isNull()) return false;
|
||||
if (!isNull() && s.isNull()) return true ;
|
||||
if (size() == s.size())
|
||||
return strcmp(str, s.str) > 0;
|
||||
return size() > s.size();
|
||||
}
|
||||
|
||||
//! \~english Returns hash of string content.
|
||||
//! \~russian Возвращает хэш содержимого строки.
|
||||
inline uint hash() const {
|
||||
if (isEmpty()) return 0;
|
||||
return piHashData((const uchar *)str, len);
|
||||
}
|
||||
|
||||
inline void swap(PIConstChars& v) {
|
||||
piSwap<const char *>(str, v.str);
|
||||
piSwap<size_t>(len, v.len);
|
||||
}
|
||||
|
||||
private:
|
||||
const char * str = nullptr;
|
||||
size_t len = 0;
|
||||
};
|
||||
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english Output operator to \a PICout.
|
||||
//! \~russian Оператор вывода в \a PICout.
|
||||
inline PICout operator <<(PICout s, const PIConstChars & v) {
|
||||
s.space();
|
||||
if (v.isNull())
|
||||
s.write("(null)");
|
||||
else {
|
||||
s.quote();
|
||||
s.write(v.data(), v.size());
|
||||
s.quote();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
template<> inline uint piHash(const PIConstChars & s) {return s.hash();}
|
||||
|
||||
|
||||
#endif // PICONSTCHARS_H
|
||||
@@ -1,350 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Timer
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "pidatetime.h"
|
||||
#include <ctime>
|
||||
#ifdef ARDUINO
|
||||
# include <Arduino.h>
|
||||
#endif
|
||||
#ifdef MAC_OS
|
||||
//# include <mach/mach_traps.h>
|
||||
//# include <mach/mach.h>
|
||||
# include <mach/clock.h>
|
||||
//# include <crt_externs.h>
|
||||
#endif
|
||||
#ifdef MICRO_PIP
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
//! \addtogroup Core
|
||||
//! \{
|
||||
//!
|
||||
//! \~\class PITime pidatetime.h
|
||||
//!
|
||||
//! \~\class PIDate pidatetime.h
|
||||
//!
|
||||
//! \~\class PIDateTime pidatetime.h
|
||||
//!
|
||||
//! \}
|
||||
|
||||
|
||||
|
||||
|
||||
bool operator ==(const PITime & t0, const PITime & t1) {
|
||||
return (t0.hours == t1.hours && t0.minutes == t1.minutes && t0.seconds == t1.seconds);
|
||||
}
|
||||
|
||||
|
||||
bool operator <(const PITime & t0, const PITime & t1) {
|
||||
if (t0.hours == t1.hours) {
|
||||
if (t0.minutes == t1.minutes) {
|
||||
return t0.seconds < t1.seconds;
|
||||
} else return t0.minutes < t1.minutes;
|
||||
} else return t0.hours < t1.hours;
|
||||
}
|
||||
|
||||
|
||||
bool operator >(const PITime & t0, const PITime & t1) {
|
||||
if (t0.hours == t1.hours) {
|
||||
if (t0.minutes == t1.minutes) {
|
||||
return t0.seconds > t1.seconds;
|
||||
} else return t0.minutes > t1.minutes;
|
||||
} else return t0.hours > t1.hours;
|
||||
}
|
||||
|
||||
bool operator ==(const PIDate & t0, const PIDate & t1) {
|
||||
return (t0.year == t1.year && t0.month == t1.month && t0.day == t1.day);
|
||||
}
|
||||
|
||||
|
||||
bool operator <(const PIDate & t0, const PIDate & t1) {
|
||||
if (t0.year == t1.year) {
|
||||
if (t0.month == t1.month) {
|
||||
return t0.day < t1.day;
|
||||
} else return t0.month < t1.month;
|
||||
} else return t0.year < t1.year;
|
||||
}
|
||||
|
||||
|
||||
bool operator >(const PIDate & t0, const PIDate & t1) {
|
||||
if (t0.year == t1.year) {
|
||||
if (t0.month == t1.month) {
|
||||
return t0.day > t1.day;
|
||||
} else return t0.month > t1.month;
|
||||
} else return t0.year > t1.year;
|
||||
}
|
||||
|
||||
bool operator ==(const PIDateTime & t0, const PIDateTime & t1) {
|
||||
return (t0.year == t1.year && t0.month == t1.month && t0.day == t1.day &&
|
||||
t0.hours == t1.hours && t0.minutes == t1.minutes && t0.seconds == t1.seconds);
|
||||
}
|
||||
|
||||
|
||||
bool operator <(const PIDateTime & t0, const PIDateTime & t1) {
|
||||
if (t0.year == t1.year) {
|
||||
if (t0.month == t1.month) {
|
||||
if (t0.day == t1.day) {
|
||||
if (t0.hours == t1.hours) {
|
||||
if (t0.minutes == t1.minutes) {
|
||||
return t0.seconds < t1.seconds;
|
||||
} else return t0.minutes < t1.minutes;
|
||||
} else return t0.hours < t1.hours;
|
||||
} else return t0.day < t1.day;
|
||||
} else return t0.month < t1.month;
|
||||
} else return t0.year < t1.year;
|
||||
}
|
||||
|
||||
|
||||
bool operator >(const PIDateTime & t0, const PIDateTime & t1) {
|
||||
if (t0.year == t1.year) {
|
||||
if (t0.month == t1.month) {
|
||||
if (t0.day == t1.day) {
|
||||
if (t0.hours == t1.hours) {
|
||||
if (t0.minutes == t1.minutes) {
|
||||
return t0.seconds > t1.seconds;
|
||||
} else return t0.minutes > t1.minutes;
|
||||
} else return t0.hours > t1.hours;
|
||||
} else return t0.day > t1.day;
|
||||
} else return t0.month > t1.month;
|
||||
} else return t0.year > t1.year;
|
||||
}
|
||||
|
||||
|
||||
PISystemTime PITime::toSystemTime() const {
|
||||
return PISystemTime((hours * 60. + minutes) * 60. + seconds, milliseconds * 1000.);
|
||||
}
|
||||
|
||||
|
||||
PITime PITime::current() {
|
||||
time_t rt = ::time(0);
|
||||
tm * pt = localtime(&rt);
|
||||
PITime t;
|
||||
t.seconds = pt->tm_sec;
|
||||
t.minutes = pt->tm_min;
|
||||
t.hours = pt->tm_hour;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
PITime PITime::fromSystemTime(const PISystemTime & st) {
|
||||
double s = st.toSeconds();
|
||||
int v = s;
|
||||
PITime ret;
|
||||
ret.milliseconds = (s - v) * 1000;
|
||||
ret.seconds = v % 60; v = (v - ret.seconds) / 60;
|
||||
ret.minutes = v % 60; v = (v - ret.minutes) / 60;
|
||||
ret.hours = v;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIDate PIDate::current() {
|
||||
time_t rt = ::time(0);
|
||||
tm * pt = localtime(&rt);
|
||||
PIDate d;
|
||||
d.day = pt->tm_mday;
|
||||
d.month = pt->tm_mon + 1;
|
||||
d.year = pt->tm_year + 1900;
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
PIDateTime PIDateTime::current() {
|
||||
time_t rt = ::time(0);
|
||||
tm * pt = localtime(&rt);
|
||||
PIDateTime dt;
|
||||
dt.milliseconds = 0;
|
||||
dt.seconds = pt->tm_sec;
|
||||
dt.minutes = pt->tm_min;
|
||||
dt.hours = pt->tm_hour;
|
||||
dt.day = pt->tm_mday;
|
||||
dt.month = pt->tm_mon + 1;
|
||||
dt.year = pt->tm_year + 1900;
|
||||
return dt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PIString PITime::toString(const PIString & format) const {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
||||
ts.replace("h", PIString::fromNumber(hours));
|
||||
ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(minutes));
|
||||
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
||||
ts.replace("s", PIString::fromNumber(seconds));
|
||||
ts.replace("zzz", PIString::fromNumber(milliseconds).expandLeftTo(3, '0'));
|
||||
ts.replace("zz", PIString::fromNumber(milliseconds).expandLeftTo(2, '0'));
|
||||
ts.replace("z", PIString::fromNumber(milliseconds));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
PIString PIDate::toString(const PIString & format) const {
|
||||
PIString ts = format;
|
||||
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(year).right(2));
|
||||
ts.replace("y", PIString::fromNumber(year).right(1));
|
||||
ts.replace("MM", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
||||
ts.replace("M", PIString::fromNumber(month));
|
||||
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(day));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
PIString PIDateTime::toString(const PIString & format) const {
|
||||
PIString ts = format;
|
||||
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(year).right(2));
|
||||
ts.replace("y", PIString::fromNumber(year).right(1));
|
||||
ts.replace("MM", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
||||
ts.replace("M", PIString::fromNumber(month));
|
||||
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(day));
|
||||
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
||||
ts.replace("h", PIString::fromNumber(hours));
|
||||
ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(minutes));
|
||||
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
||||
ts.replace("s", PIString::fromNumber(seconds));
|
||||
ts.replace("zzz", PIString::fromNumber(milliseconds).expandLeftTo(3, '0'));
|
||||
ts.replace("zz", PIString::fromNumber(milliseconds).expandLeftTo(2, '0'));
|
||||
ts.replace("z", PIString::fromNumber(milliseconds));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
time_t PIDateTime::toSecondSinceEpoch() const {
|
||||
tm pt;
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.tm_sec = seconds;
|
||||
pt.tm_min = minutes;
|
||||
pt.tm_hour = hours;
|
||||
pt.tm_mday = day;
|
||||
pt.tm_mon = month - 1;
|
||||
#ifdef WINDOWS
|
||||
pt.tm_year = piMaxi(year - 1900, 70);
|
||||
#else
|
||||
pt.tm_year = piMaxi(year - 1900, 0);
|
||||
#endif
|
||||
return mktime(&pt);
|
||||
}
|
||||
|
||||
|
||||
PIDateTime PIDateTime::fromSecondSinceEpoch(const time_t sec) {
|
||||
tm * pt = localtime(&sec);
|
||||
PIDateTime dt;
|
||||
dt.seconds = pt->tm_sec;
|
||||
dt.minutes = pt->tm_min;
|
||||
dt.hours = pt->tm_hour;
|
||||
dt.day = pt->tm_mday;
|
||||
dt.month = pt->tm_mon + 1;
|
||||
dt.year = pt->tm_year + 1900;
|
||||
return dt;
|
||||
|
||||
}
|
||||
|
||||
|
||||
PIString time2string(const PITime & time, const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(time.hours).expandLeftTo(2, '0'));
|
||||
ts.replace("h", PIString::fromNumber(time.hours));
|
||||
ts.replace("mm", PIString::fromNumber(time.minutes).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(time.minutes));
|
||||
ts.replace("ss", PIString::fromNumber(time.seconds).expandLeftTo(2, '0'));
|
||||
ts.replace("s", PIString::fromNumber(time.seconds));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
PIString date2string(const PIDate & date, const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(date.year).right(2));
|
||||
ts.replace("y", PIString::fromNumber(date.year).right(1));
|
||||
ts.replace("MM", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
||||
ts.replace("M", PIString::fromNumber(date.month));
|
||||
ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(date.day));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
PIString datetime2string(const PIDateTime & date, const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(date.hours).expandLeftTo(2, '0'));
|
||||
ts.replace("h", PIString::fromNumber(date.hours));
|
||||
ts.replace("mm", PIString::fromNumber(date.minutes).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(date.minutes));
|
||||
ts.replace("ss", PIString::fromNumber(date.seconds).expandLeftTo(2, '0'));
|
||||
ts.replace("s", PIString::fromNumber(date.seconds));
|
||||
ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(date.year).right(2));
|
||||
ts.replace("y", PIString::fromNumber(date.year).right(1));
|
||||
ts.replace("MM", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
||||
ts.replace("M", PIString::fromNumber(date.month));
|
||||
ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(date.day));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PICout operator <<(PICout s, const PITime & v) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
s << "PITime(" << v.hours << ":";
|
||||
s << PIString::fromNumber(v.minutes).expandLeftTo(2, '0') << ":";
|
||||
s << PIString::fromNumber(v.seconds).expandLeftTo(2, '0') << ":";
|
||||
s << PIString::fromNumber(v.milliseconds).expandLeftTo(3, '0') << ")";
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
PICout operator <<(PICout s, const PIDate & v) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
s << "PIDate(" << v.day << "-";
|
||||
s << PIString::fromNumber(v.month).expandLeftTo(2, '0') << "-";
|
||||
s << v.year << ")";
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
PICout operator <<(PICout s, const PIDateTime & v) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
s << "PIDateTime(";
|
||||
s << v.day << "-";
|
||||
s << PIString::fromNumber(v.month).expandLeftTo(2, '0') << "-";
|
||||
s << v.year << " ";
|
||||
s << v.hours << ":";
|
||||
s << PIString::fromNumber(v.minutes).expandLeftTo(2, '0') << ":";
|
||||
s << PIString::fromNumber(v.seconds).expandLeftTo(2, '0') << ":";
|
||||
s << PIString::fromNumber(v.milliseconds).expandLeftTo(3, '0') << ")";
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -1,320 +0,0 @@
|
||||
/*! \file pidatetime.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english Time and date structs
|
||||
* \~russian Типы времени и даты
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Time and date structs
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIDATETIME_H
|
||||
#define PIDATETIME_H
|
||||
|
||||
|
||||
#include "pisystemtime.h"
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Calendar time.
|
||||
//! \~russian Календарное время.
|
||||
class PIP_EXPORT PITime {
|
||||
public:
|
||||
//! \~english Construct %PITime from hours, minutes, seconds and milliseconds
|
||||
//! \~russian Создает %PITime из часов, минут, секунд и миллисекунд
|
||||
PITime(int hours_ = 0, int minutes_ = 0, int seconds_ = 0, int milliseconds_ = 0): hours(hours_), minutes(minutes_), seconds(seconds_), milliseconds(milliseconds_) {;}
|
||||
|
||||
//! \~english Returns string representation
|
||||
//! \~russian Возвращает строковое представление
|
||||
PIString toString(const PIString & format = "h:mm:ss") const;
|
||||
|
||||
//! \~english Returns time as %PISystemTime
|
||||
//! \~russian Возвращает время как %PISystemTime
|
||||
PISystemTime toSystemTime() const;
|
||||
|
||||
//! \~english Returns current time
|
||||
//! \~russian Возвращает текущее время
|
||||
static PITime current();
|
||||
|
||||
//! \~english Construct %PITime from %PISystemTime
|
||||
//! \~russian Создает %PITime из %PISystemTime
|
||||
static PITime fromSystemTime(const PISystemTime & st);
|
||||
|
||||
|
||||
//! \~english Hour, 0-23
|
||||
//! \~russian Час, 0-23
|
||||
int hours;
|
||||
|
||||
//! \~english Minutes, 0-59
|
||||
//! \~russian Минуты, 0-59
|
||||
int minutes;
|
||||
|
||||
//! \~english Seconds, 0-59
|
||||
//! \~russian Секунды, 0-59
|
||||
int seconds;
|
||||
|
||||
//! \~english Milliseconds, 0-999
|
||||
//! \~russian Миллисекунды, 0-999
|
||||
int milliseconds;
|
||||
};
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
PIP_EXPORT bool operator ==(const PITime & t0, const PITime & t1);
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
PIP_EXPORT bool operator <(const PITime & t0, const PITime & t1);
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
PIP_EXPORT bool operator >(const PITime & t0, const PITime & t1);
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator !=(const PITime & t0, const PITime & t1) {return !(t0 == t1);}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator <=(const PITime & t0, const PITime & t1) {return !(t0 > t1);}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator >=(const PITime & t0, const PITime & t1) {return !(t0 < t1);}
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english \brief Output operator to PICout
|
||||
//! \~russian \brief Оператор вывода в PICout
|
||||
PIP_EXPORT PICout operator <<(PICout s, const PITime & v);
|
||||
|
||||
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Calendar date.
|
||||
//! \~russian Календарная дата.
|
||||
class PIP_EXPORT PIDate {
|
||||
public:
|
||||
//! \~english Construct %PIDate from year, month and day
|
||||
//! \~russian Создает %PIDate из года, месяца и дня
|
||||
PIDate(int year_ = 0, int month_ = 0, int day_ = 0): year(year_), month(month_), day(day_) {;}
|
||||
|
||||
//! \~english Returns string representation
|
||||
//! \~russian Возвращает строковое представление
|
||||
PIString toString(const PIString & format = "d.MM.yyyy") const;
|
||||
|
||||
//! \~english Returns current date
|
||||
//! \~russian Возвращает текущую дату
|
||||
static PIDate current();
|
||||
|
||||
|
||||
//! \~english Year
|
||||
//! \~russian Год
|
||||
int year;
|
||||
|
||||
//! \~english Month, 1-12
|
||||
//! \~russian Месяц, 1-12
|
||||
int month;
|
||||
|
||||
//! \~english Day, 1-31
|
||||
//! \~russian День, 1-31
|
||||
int day;
|
||||
};
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
PIP_EXPORT bool operator ==(const PIDate & t0, const PIDate & t1);
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
PIP_EXPORT bool operator <(const PIDate & t0, const PIDate & t1);
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
PIP_EXPORT bool operator >(const PIDate & t0, const PIDate & t1);
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator !=(const PIDate & t0, const PIDate & t1) {return !(t0 == t1);}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator <=(const PIDate & t0, const PIDate & t1) {return !(t0 > t1);}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator >=(const PIDate & t0, const PIDate & t1) {return !(t0 < t1);}
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english \brief Output operator to PICout
|
||||
//! \~russian \brief Оператор вывода в PICout
|
||||
PIP_EXPORT PICout operator <<(PICout s, const PIDate & v);
|
||||
|
||||
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Calendar date and time.
|
||||
//! \~russian Календарное дата и время.
|
||||
class PIP_EXPORT PIDateTime {
|
||||
public:
|
||||
//! \~english Construct null %PIDateTime
|
||||
//! \~russian Создает нулевой %PIDateTime
|
||||
PIDateTime() {year = month = day = hours = minutes = seconds = milliseconds = 0;}
|
||||
|
||||
//! \~english Construct %PIDateTime from %PITime and null %PIDate
|
||||
//! \~russian Создает %PIDateTime из %PITime и нулевого %PIDate
|
||||
PIDateTime(const PITime & time) {year = month = day = 0; hours = time.hours; minutes = time.minutes; seconds = time.seconds; milliseconds = time.milliseconds;}
|
||||
|
||||
//! \~english Construct %PIDateTime from %PIDate and null %PITime
|
||||
//! \~russian Создает %PIDateTime из %PIDate и нулевого %PITime
|
||||
PIDateTime(const PIDate & date) {year = date.year; month = date.month; day = date.day; hours = minutes = seconds = milliseconds = 0;}
|
||||
|
||||
//! \~english Construct %PIDateTime from %PIDate and %PITime
|
||||
//! \~russian Создает %PIDateTime из %PIDate и %PITime
|
||||
PIDateTime(const PIDate & date, const PITime & time) {year = date.year; month = date.month; day = date.day; hours = time.hours; minutes = time.minutes; seconds = time.seconds; milliseconds = time.milliseconds;}
|
||||
|
||||
|
||||
//! \~english Returns normalized %PIDateTime
|
||||
//! \~russian Возвращает нормализованный %PIDateTime
|
||||
PIDateTime normalized() const {return PIDateTime::fromSecondSinceEpoch(toSecondSinceEpoch());}
|
||||
|
||||
//! \~english Normalize all fields
|
||||
//! \~russian Нормализует все поля
|
||||
void normalize() {*this = normalized();}
|
||||
|
||||
//! \~english Returns string representation
|
||||
//! \~russian Возвращает строковое представление
|
||||
PIString toString(const PIString & format = "h:mm:ss d.MM.yyyy") const;
|
||||
|
||||
//! \~english Returns seconds since 1 Jan 1970
|
||||
//! \~russian Возвращает секунды от 1 Янв 1970
|
||||
time_t toSecondSinceEpoch() const;
|
||||
|
||||
//! \~english Returns time as %PISystemTime
|
||||
//! \~russian Возвращает время как %PISystemTime
|
||||
PISystemTime toSystemTime() const {return PISystemTime(int(toSecondSinceEpoch()), milliseconds * 1000000);}
|
||||
|
||||
//! \~english Returns date part
|
||||
//! \~russian Возвращает дату
|
||||
PIDate date() const {return PIDate(year, month, day);}
|
||||
|
||||
//! \~english Returns time part
|
||||
//! \~russian Возвращает время
|
||||
PITime time() const {return PITime(hours, minutes, seconds, milliseconds);}
|
||||
|
||||
//! \~english Set date part
|
||||
//! \~russian Устанавливает дату
|
||||
void setDate(const PIDate & d) {year = d.year; month = d.month; day = d.day;}
|
||||
|
||||
//! \~english Set time part
|
||||
//! \~russian Устанавливает время
|
||||
void setTime(const PITime & t) {hours = t.hours; minutes = t.minutes; seconds = t.seconds; milliseconds = t.milliseconds;}
|
||||
|
||||
//! \~english Sum operator
|
||||
//! \~russian Оператор сложения
|
||||
void operator +=(const PIDateTime & d1) {year += d1.year; month += d1.month; day += d1.day; hours += d1.hours; minutes += d1.minutes; seconds += d1.seconds; normalize();}
|
||||
|
||||
//! \~english Subtract operator
|
||||
//! \~russian Оператор вычитания
|
||||
void operator -=(const PIDateTime & d1) {year -= d1.year; month -= d1.month; day -= d1.day; hours -= d1.hours; minutes -= d1.minutes; seconds -= d1.seconds; normalize();}
|
||||
|
||||
//! \~english Construct %PIDateTime from seconds since 1 Jan 1970
|
||||
//! \~russian Создает %PIDateTime из секунд от 1 Янв 1970
|
||||
static PIDateTime fromSecondSinceEpoch(const time_t sec);
|
||||
|
||||
//! \~english Construct %PIDateTime from %PISystemTime
|
||||
//! \~russian Создает %PIDateTime из %PISystemTime
|
||||
static PIDateTime fromSystemTime(const PISystemTime & st) {PIDateTime dt = fromSecondSinceEpoch(st.seconds); dt.milliseconds = piClampi(st.nanoseconds / 1000000, 0, 999); return dt;}
|
||||
|
||||
//! \~english Returns current date and time
|
||||
//! \~russian Возвращает текущую дату и время
|
||||
static PIDateTime current();
|
||||
|
||||
|
||||
//! \~english Year
|
||||
//! \~russian Год
|
||||
int year;
|
||||
|
||||
//! \~english Month, 1-12
|
||||
//! \~russian Месяц, 1-12
|
||||
int month;
|
||||
|
||||
//! \~english Day, 1-31
|
||||
//! \~russian День, 1-31
|
||||
int day;
|
||||
|
||||
//! \~english Hour, 0-23
|
||||
//! \~russian Час, 0-23
|
||||
int hours;
|
||||
|
||||
//! \~english Minutes, 0-59
|
||||
//! \~russian Минуты, 0-59
|
||||
int minutes;
|
||||
|
||||
//! \~english Seconds, 0-59
|
||||
//! \~russian Секунды, 0-59
|
||||
int seconds;
|
||||
|
||||
//! \~english Milliseconds, 0-999
|
||||
//! \~russian Миллисекунды, 0-999
|
||||
int milliseconds;
|
||||
};
|
||||
|
||||
//! \~english Sum operator
|
||||
//! \~russian Оператор сложения
|
||||
inline PIDateTime operator +(const PIDateTime & d0, const PIDateTime & d1) {PIDateTime td = d0; td += d1; return td.normalized();}
|
||||
|
||||
//! \~english Subtract operator
|
||||
//! \~russian Оператор вычитания
|
||||
inline PIDateTime operator -(const PIDateTime & d0, const PIDateTime & d1) {PIDateTime td = d0; td -= d1; return td.normalized();}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
PIP_EXPORT bool operator ==(const PIDateTime & t0, const PIDateTime & t1);
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
PIP_EXPORT bool operator <(const PIDateTime & t0, const PIDateTime & t1);
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
PIP_EXPORT bool operator >(const PIDateTime & t0, const PIDateTime & t1);
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator !=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 == t1);}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator <=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 > t1);}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
inline bool operator >=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 < t1);}
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english \brief Output operator to PICout
|
||||
//! \~russian \brief Оператор вывода в PICout
|
||||
PIP_EXPORT PICout operator <<(PICout s, const PIDateTime & v);
|
||||
|
||||
|
||||
#endif // PIDATETIME_H
|
||||
@@ -1,247 +0,0 @@
|
||||
/*! \file piflags.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english General flags class
|
||||
* \~russian Универсальные флаги
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
General flags class
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIFLAGS_H
|
||||
#define PIFLAGS_H
|
||||
|
||||
#include "pip_export.h"
|
||||
|
||||
//! \addtogroup Core
|
||||
//! \{
|
||||
//! \~\class PIFlags piflags.h
|
||||
//! \~\brief
|
||||
//! \~english Container for bit flags
|
||||
//! \~russian Контейнер для битовых полей (флагов)
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! %PIFlags is wrapper around \c "int". One can use it as native \c "int".
|
||||
//! There are manybit-wise operators,
|
||||
//! native conversion to "int" and function
|
||||
//! to test flag. \n Example:
|
||||
//!
|
||||
//! \~russian
|
||||
//! %PIFlags по сути обертка вокруг \c "int". Можно использовать его как обычный \c "int".
|
||||
//! Имеет много битовых операторов,
|
||||
//! неявное преобразование в "int" и методы для проверки
|
||||
//! флагов. \n Пример:
|
||||
//!
|
||||
//! \~\snippet piincludes.cpp flags
|
||||
//!
|
||||
//! \}
|
||||
template<typename Enum>
|
||||
class PIFlags {
|
||||
public:
|
||||
|
||||
//! \~english Constructor with flags = 0
|
||||
//! \~russian Создает нулевые флаги
|
||||
PIFlags(): flags(0) {;}
|
||||
|
||||
//! \~english Constructor with flags = Enum "e"
|
||||
//! \~russian Создает флаги со значением = Enum "e"
|
||||
PIFlags(Enum e): flags(e) {;}
|
||||
|
||||
//! \~english Constructor with flags = int "i"
|
||||
//! \~russian Создает флаги со значением = int "i"
|
||||
PIFlags(const int i): flags(i) {;}
|
||||
|
||||
//! \~english Set flags on positions "f" to value "on"
|
||||
//! \~russian Устанавливает флаги по позициям "f" в "on"
|
||||
PIFlags & setFlag(const PIFlags & f, bool on = true) {if (on) flags |= f.flags; else flags &= ~f.flags; return *this;}
|
||||
|
||||
//! \~english Set flag "e" to value "on"
|
||||
//! \~russian Устанавливает флаг "e" в "on"
|
||||
PIFlags & setFlag(const Enum & e, bool on = true) {if (on) flags |= e; else flags &= ~e; return *this;}
|
||||
|
||||
//! \~english Set flag "i" to value "on"
|
||||
//! \~russian Устанавливает флаг "i" в "on"
|
||||
PIFlags & setFlag(const int & i, bool on = true) {if (on) flags |= i; else flags &= ~i; return *this;}
|
||||
|
||||
//! \~english Assign operator
|
||||
//! \~russian Оператор присваивания
|
||||
void operator =(const Enum & e) {flags = e;}
|
||||
|
||||
//! \~english Assign operator
|
||||
//! \~russian Оператор присваивания
|
||||
void operator =(const int & i) {flags = i;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator ==(const PIFlags & f) {return flags == f.flags;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator ==(const Enum & e) {return flags == e;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator ==(const int i) {return flags == i;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator !=(const PIFlags & f) {return flags != f.flags;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator !=(const Enum & e) {return flags != e;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator !=(const int i) {return flags != i;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator >(const PIFlags & f) {return flags > f.flags;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator >(const Enum & e) {return flags > e;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator >(const int i) {return flags > i;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator <(const PIFlags & f) {return flags < f.flags;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator <(const Enum & e) {return flags < e;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator <(const int i) {return flags < i;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator >=(const PIFlags & f) {return flags >= f.flags;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator >=(const Enum & e) {return flags >= e;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator >=(const int i) {return flags >= i;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator <=(const PIFlags & f) {return flags <= f.flags;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator <=(const Enum & e) {return flags <= e;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator <=(const int i) {return flags <= i;}
|
||||
|
||||
//! \~english Bit-wise AND operator
|
||||
//! \~russian Оператор побитового И
|
||||
void operator &=(const PIFlags & f) {flags &= f.flags;}
|
||||
|
||||
//! \~english Bit-wise AND operator
|
||||
//! \~russian Оператор побитового И
|
||||
void operator &=(const Enum & e) {flags &= e;}
|
||||
|
||||
//! \~english Bit-wise AND operator
|
||||
//! \~russian Оператор побитового И
|
||||
void operator &=(const int i) {flags &= i;}
|
||||
|
||||
//! \~english Bit-wise OR operator
|
||||
//! \~russian Оператор побитового ИЛИ
|
||||
void operator |=(const PIFlags & f) {flags |= f.flags;}
|
||||
|
||||
//! \~english Bit-wise OR operator
|
||||
//! \~russian Оператор побитового ИЛИ
|
||||
void operator |=(const Enum & e) {flags |= e;}
|
||||
|
||||
//! \~english Bit-wise OR operator
|
||||
//! \~russian Оператор побитового ИЛИ
|
||||
void operator |=(const int i) {flags |= i;}
|
||||
|
||||
//! \~english Bit-wise XOR operator
|
||||
//! \~russian Оператор побитового исключающего ИЛИ
|
||||
void operator ^=(const PIFlags & f) {flags ^= f.flags;}
|
||||
|
||||
//! \~english Bit-wise XOR operator
|
||||
//! \~russian Оператор побитового исключающего ИЛИ
|
||||
void operator ^=(const Enum & e) {flags ^= e;}
|
||||
|
||||
//! \~english Bit-wise XOR operator
|
||||
//! \~russian Оператор побитового исключающего ИЛИ
|
||||
void operator ^=(const int i) {flags ^= i;}
|
||||
|
||||
//! \~english Bit-wise AND operator
|
||||
//! \~russian Оператор побитового И
|
||||
PIFlags operator &(PIFlags f) const {PIFlags tf(flags & f.flags); return tf;}
|
||||
|
||||
//! \~english Bit-wise AND operator
|
||||
//! \~russian Оператор побитового И
|
||||
PIFlags operator &(Enum e) const {PIFlags tf(flags & e); return tf;}
|
||||
|
||||
//! \~english Bit-wise AND operator
|
||||
//! \~russian Оператор побитового И
|
||||
PIFlags operator &(int i) const {PIFlags tf(flags & i); return tf;}
|
||||
|
||||
//! \~english Bit-wise OR operator
|
||||
//! \~russian Оператор побитового ИЛИ
|
||||
PIFlags operator |(PIFlags f) const {PIFlags tf(flags | f.flags); return tf;}
|
||||
|
||||
//! \~english Bit-wise OR operator
|
||||
//! \~russian Оператор побитового ИЛИ
|
||||
PIFlags operator |(Enum e) const {PIFlags tf(flags | e); return tf;}
|
||||
|
||||
//! \~english Bit-wise OR operator
|
||||
//! \~russian Оператор побитового ИЛИ
|
||||
PIFlags operator |(int i) const {PIFlags tf(flags | i); return tf;}
|
||||
|
||||
//! \~english Bit-wise XOR operator
|
||||
//! \~russian Оператор побитового исключающего ИЛИ
|
||||
PIFlags operator ^(PIFlags f) const {PIFlags tf(flags ^ f.flags); return tf;}
|
||||
|
||||
//! \~english Bit-wise XOR operator
|
||||
//! \~russian Оператор побитового исключающего ИЛИ
|
||||
PIFlags operator ^(Enum e) const {PIFlags tf(flags ^ e); return tf;}
|
||||
|
||||
//! \~english Bit-wise XOR operator
|
||||
//! \~russian Оператор побитового исключающего ИЛИ
|
||||
PIFlags operator ^(int i) const {PIFlags tf(flags ^ i); return tf;}
|
||||
|
||||
//! \~english Test flag operator
|
||||
//! \~russian Оператор проверки флага
|
||||
bool operator [](Enum e) const {return (flags & e) == e;}
|
||||
|
||||
//! \~english Implicity conversion to \c int
|
||||
//! \~russian Оператор неявного преобразования в \c int
|
||||
operator int() const {return flags;}
|
||||
|
||||
private:
|
||||
int flags;
|
||||
|
||||
};
|
||||
|
||||
#endif // PIFLAGS_H
|
||||
@@ -1,567 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
JSON class
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "pijson.h"
|
||||
|
||||
|
||||
//! \~\class PIJSON pijson.h
|
||||
//! \~\details
|
||||
//! \~english \section PIJSON_sec0 Synopsis
|
||||
//! \~russian \section PIJSON_sec0 Краткий обзор
|
||||
//! \~english
|
||||
//!
|
||||
//! \~russian
|
||||
//! JSON - это древовидная структура, каждый элемент которой может быть либо
|
||||
//! парой имя:значение, либо массивом, либо объектом, т.е. именованным
|
||||
//! списком элементов. Корневой элемент JSON может быть либо массивом,
|
||||
//! либо объектом.
|
||||
//!
|
||||
//! Массивы заключены в квадратные скобки [], их элементы не имеют имени
|
||||
//! и разделяются запятыми.
|
||||
//!
|
||||
//! Объекты заключены в фигурные скобки {}, их элементы имеют имя
|
||||
//! и разделяются запятыми.
|
||||
//!
|
||||
//!
|
||||
//! \~english \section PIJSON_sec1 PIJSON tree
|
||||
//! \~russian \section PIJSON_sec1 Дерево PIJSON
|
||||
//! \~english
|
||||
//!
|
||||
//! \~russian
|
||||
//! %PIJSON представляет собой элемент дерева JSON. Каждый элемент имеет тип (\a type())
|
||||
//! и может иметь имя (\a name()). Если это конечный элемент,то он будет иметь значение,
|
||||
//! доступное через \a value(), \a toBool(), \a toInt(), \a toDouble() или \a toString().
|
||||
//!
|
||||
//! Если элемент преставляет собой массив, то его размер доступен через \a size(),
|
||||
//! а элементы массива через целочисленный оператор []. Весь массив доступен через \a array().
|
||||
//!
|
||||
//! Если элемент преставляет собой объект, то его размер доступен через \a size(),
|
||||
//! а элементы объекта через строковый оператор []. Проверить наличие элемента по имени можно
|
||||
//! с помощью \a contains(). Весь объект доступен через \a object().
|
||||
//!
|
||||
//! Создать дерево из текстового представления JSON можно с помощью \a fromJSON(), а
|
||||
//! преобразовать в текст с помощью \a toJSON().
|
||||
//!
|
||||
//!
|
||||
//! \~english \section PIJSON_sec2 PIJSON creation
|
||||
//! \~russian \section PIJSON_sec2 Создание PIJSON
|
||||
//! \~english
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для создания нового дерева необходимо лишь создать пустой корневой PIJSON и заполнить его
|
||||
//! значениями, массивами или объектами с помощью целочисленного или строкового оператора [].
|
||||
//! В зависимости от типа аргумента элемент преобразуется либо в массив, либо в объект.
|
||||
//!
|
||||
//! При приравнивании PIJSON к какому-либо значению, его тип автоматически установится в нужный.
|
||||
//! При обращении на запись целочисленным оператором [] размер массива автоматически увеличится
|
||||
//! при необходимости.
|
||||
//!
|
||||
//!
|
||||
//! \~english \section PIJSON_sec3 Mask/unmask
|
||||
//! \~russian \section PIJSON_sec3 Маскирование/размаскирование
|
||||
//! \~english
|
||||
//!
|
||||
//! \~russian
|
||||
//! Строковые значения в стандарте JSON могут иметь в явном виде только печатные символы,
|
||||
//! спецсимволы и юникод должны быть преобразованы маскированием, т.е., например, вместо
|
||||
//! символа новой строки должно быть "\n", а не-ASCII символы должны быть в виде "\uXXXX".
|
||||
//!
|
||||
//! Оператор вывода в PICout не выполняет маскирования строк.
|
||||
//!
|
||||
//! Методы \a toJSON() и \a fromJSON() маскируют и размаскируют строковые поля.
|
||||
//!
|
||||
//!
|
||||
//! \~english \section PIJSON_sec4 Examples
|
||||
//! \~russian \section PIJSON_sec4 Примеры
|
||||
//! \~english
|
||||
//!
|
||||
//! \~russian
|
||||
//! Чтение:
|
||||
//! \~\code
|
||||
//! PIJSON json = PIJSON::fromJSON(
|
||||
//! "["
|
||||
//! " true,"
|
||||
//! " 10,"
|
||||
//! " {"
|
||||
//! " \"num\":1.E-2,"
|
||||
//! " \"str\":\"text\""
|
||||
//! " },"
|
||||
//! "]");
|
||||
//! piCout << json;
|
||||
//! piCout << json.toJSON();
|
||||
//! \endcode
|
||||
//! \~\code
|
||||
//! [
|
||||
//! true,
|
||||
//! 10,
|
||||
//! {
|
||||
//! "num": 1.e-2,
|
||||
//! "str": "text"
|
||||
//! }
|
||||
//! ]
|
||||
//!
|
||||
//! [true,10,{"num":1.e-2,"str":"text"}]
|
||||
//! \endcode
|
||||
//! Разбор:
|
||||
//! \~\code
|
||||
//! PIJSON json = PIJSON::fromJSON(
|
||||
//! "["
|
||||
//! " true,"
|
||||
//! " 10,"
|
||||
//! " {"
|
||||
//! " \"num\":1.E-2,"
|
||||
//! " \"str\":\"text\""
|
||||
//! " },"
|
||||
//! "]");
|
||||
//! piCout << "top-level:";
|
||||
//! for (const auto & i: json.array())
|
||||
//! piCout << i.value();
|
||||
//! piCout << "[2][\"str\"]:";
|
||||
//! piCout << json[2]["str"].toString();
|
||||
//! \endcode
|
||||
//! \~\code
|
||||
//! top-level:
|
||||
//! PIVariant(Bool, 1)
|
||||
//! PIVariant(String, 10)
|
||||
//! PIVariant(Invalid)
|
||||
//! [2]["str"]:
|
||||
//! text
|
||||
//! \endcode
|
||||
//!
|
||||
//! Создание:\n
|
||||
//! Простой массив
|
||||
//! \~\code
|
||||
//! PIJSON json;
|
||||
//! json[0] = -1;
|
||||
//! json[1] = "text";
|
||||
//! json[3] = false;
|
||||
//! piCout << json.toJSON();
|
||||
//! \endcode
|
||||
//! \~\code
|
||||
//! [-1,"text","",false]
|
||||
//! \endcode
|
||||
//!
|
||||
//! Массив объектов
|
||||
//! \~\code
|
||||
//! struct {
|
||||
//! PIString name;
|
||||
//! PIString surname;
|
||||
//! PIString email;
|
||||
//! } persons[] = {
|
||||
//! {"Ivan", "Ivanov", "ivan@pip.ru"},
|
||||
//! {"Igor", "Igorevich", "igor@pip.ru"},
|
||||
//! {"Andrey", "Andreevich", "andrey@pip.ru"}
|
||||
//! };
|
||||
//! PIJSON obj;
|
||||
//! PIJSON json;
|
||||
//! int index = 0;
|
||||
//! for (const auto & p: persons) {
|
||||
//! obj["index"] = index++;
|
||||
//! obj["name"] = p.name;
|
||||
//! obj["surname"] = p.surname;
|
||||
//! obj["email"] = p.email;
|
||||
//! json << obj;
|
||||
//! }
|
||||
//! piCout << json;
|
||||
//! \endcode
|
||||
//! \~\code
|
||||
//! [
|
||||
//! {
|
||||
//! "name": "Ivan",
|
||||
//! "email": "ivan@pip.ru",
|
||||
//! "index": 0,
|
||||
//! "surname": "Ivanov"
|
||||
//! },
|
||||
//! {
|
||||
//! "name": "Igor",
|
||||
//! "email": "igor@pip.ru",
|
||||
//! "index": 1,
|
||||
//! "surname": "Igorevich"
|
||||
//! },
|
||||
//! {
|
||||
//! "name": "Andrey",
|
||||
//! "email": "andrey@pip.ru",
|
||||
//! "index": 2,
|
||||
//! "surname": "Andreevich"
|
||||
//! }
|
||||
//! ]
|
||||
//! \endcode
|
||||
//!
|
||||
|
||||
|
||||
PIJSON PIJSON::newObject() {
|
||||
PIJSON ret;
|
||||
ret.c_type = Object;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIJSON PIJSON::newArray() {
|
||||
PIJSON ret;
|
||||
ret.c_type = Array;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIJSON PIJSON::newString(const PIString & v) {
|
||||
PIJSON ret;
|
||||
ret = v;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const PIVector<PIJSON> & PIJSON::array() const {
|
||||
if (!isArray()) {
|
||||
return nullEntry().c_array;
|
||||
} else {
|
||||
return c_array;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const PIMap<PIString, PIJSON> & PIJSON::object() const {
|
||||
if (!isObject()) {
|
||||
return nullEntry().c_object;
|
||||
} else {
|
||||
return c_object;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! \details
|
||||
//! \~english
|
||||
//! If "v" type is boolean set type to \a PIJSON::Boolean.\n
|
||||
//! If "v" type is any numeric set type to \a PIJSON::Number.\n
|
||||
//! If "v" type is string set type to \a PIJSON::String.\n
|
||||
//! In case of any other type set element type to \a PIJSON::Invalid.
|
||||
//! \~russian
|
||||
//! Если тип "v" логический, то устанавливает тип в \a PIJSON::Boolean.\n
|
||||
//! Если тип "v" любой численный, то устанавливает тип в \a PIJSON::Number.\n
|
||||
//! Если тип "v" строковый, то устанавливает тип в \a PIJSON::String.\n
|
||||
//! Если тип "v" любой другой, то устанавливает тип в \a PIJSON::Invalid.
|
||||
void PIJSON::setValue(const PIVariant & v) {
|
||||
c_value = v;
|
||||
switch (v.type()) {
|
||||
case PIVariant::pivBool: c_type = Boolean; break;
|
||||
case PIVariant::pivUChar:
|
||||
case PIVariant::pivShort:
|
||||
case PIVariant::pivUShort:
|
||||
case PIVariant::pivInt:
|
||||
case PIVariant::pivUInt:
|
||||
case PIVariant::pivLLong:
|
||||
case PIVariant::pivULLong:
|
||||
case PIVariant::pivFloat:
|
||||
case PIVariant::pivDouble:
|
||||
case PIVariant::pivLDouble: c_type = Number; break;
|
||||
case PIVariant::pivString: c_type = String; break;
|
||||
default: c_type = Invalid; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIJSON::clear() {
|
||||
c_type = Invalid;
|
||||
c_value = PIVariant();
|
||||
c_name.clear();
|
||||
c_object.clear();
|
||||
c_array.clear();
|
||||
}
|
||||
|
||||
|
||||
int PIJSON::size() const {
|
||||
if (isArray()) return c_array.size_s();
|
||||
if (isObject()) return c_object.size_s();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool PIJSON::contains(const PIString & key) const {
|
||||
if (!isObject()) return false;
|
||||
return c_object.contains(key);
|
||||
}
|
||||
|
||||
|
||||
void PIJSON::resize(int new_size) {
|
||||
c_type = Array;
|
||||
c_array.resize(new_size, newString());
|
||||
}
|
||||
|
||||
|
||||
const PIJSON & PIJSON::operator[](int index) const {
|
||||
if (!isArray()) return nullEntry();
|
||||
return c_array[index];
|
||||
}
|
||||
|
||||
|
||||
PIJSON & PIJSON::operator[](int index) {
|
||||
c_type = Array;
|
||||
if (index >= c_array.size_s()) {
|
||||
c_array.resize(index + 1, newString());
|
||||
}
|
||||
PIJSON & ret(c_array[index]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIJSON & PIJSON::operator<<(const PIJSON & element) {
|
||||
c_type = Array;
|
||||
c_array << element;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIJSON & PIJSON::operator=(const PIJSON & v) {
|
||||
c_type = v.c_type;
|
||||
c_value = v.c_value;
|
||||
c_object = v.c_object;
|
||||
c_array = v.c_array;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIJSON PIJSON::operator[](const PIString & key) const {
|
||||
if (!isObject()) return nullEntry();
|
||||
if (!c_object.contains(key)) return nullEntry();
|
||||
return c_object.value(key);
|
||||
}
|
||||
|
||||
|
||||
PIJSON & PIJSON::operator[](const PIString & key) {
|
||||
c_type = Object;
|
||||
PIJSON & ret(c_object[key]);
|
||||
ret.c_name = key;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString PIJSON::toJSON(PrintType print_type) const {
|
||||
PIString ret;
|
||||
print(ret, *this, "", print_type == Tree, true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIJSON PIJSON::fromJSON(PIString str) {
|
||||
return parseValue(str);
|
||||
}
|
||||
|
||||
|
||||
PIJSON & PIJSON::nullEntry() {
|
||||
static PIJSON ret;
|
||||
ret.clear();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString PIJSON::parseName(PIString & s) {
|
||||
//piCout << "\n\n\n parseName" << s;
|
||||
PIString ret;
|
||||
ret = s.takeRange('"', '"');
|
||||
s.trim();
|
||||
if (s.isEmpty()) return PIString();
|
||||
if (s[0] != ':') return PIString();
|
||||
s.remove(0).trim();
|
||||
return PIJSON::stringUnmask(ret);
|
||||
}
|
||||
|
||||
|
||||
PIJSON PIJSON::parseValue(PIString & s) {
|
||||
PIJSON ret;
|
||||
//piCout << "\n\n\n parseValue" << s;
|
||||
s.trim();
|
||||
if (s.isEmpty()) return ret;
|
||||
if (s[0] == '{') {
|
||||
ret = parseObject(s.takeRange('{', '}'));
|
||||
} else if (s[0] == '[') {
|
||||
ret = parseArray(s.takeRange('[', ']'));
|
||||
} else {
|
||||
s.trim();
|
||||
if (s.startsWith('"')) {
|
||||
ret.c_type = PIJSON::String;
|
||||
ret.c_value = PIJSON::stringUnmask(s.takeRange('"', '"'));
|
||||
} else {
|
||||
PIString value;
|
||||
int ind = s.find(',');
|
||||
if (ind >= 0) {
|
||||
value = s.takeLeft(ind).trim().toLowerCase();
|
||||
} else {
|
||||
value = s;
|
||||
s.clear();
|
||||
}
|
||||
//piCout << "\n\n\n parseValue value = \"" << value << "\"";
|
||||
if (value == "null") {
|
||||
ret.c_type = PIJSON::Null;
|
||||
} else if (value == "true") {
|
||||
ret.c_type = PIJSON::Boolean;
|
||||
ret.c_value = true;
|
||||
} else if (value == "false") {
|
||||
ret.c_type = PIJSON::Boolean;
|
||||
ret.c_value = false;
|
||||
} else {
|
||||
ret.c_type = PIJSON::Number;
|
||||
ret.c_value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIJSON PIJSON::parseObject(PIString s) {
|
||||
//piCout << "\n\n\n parseObject" << s;
|
||||
PIJSON ret;
|
||||
ret.c_type = PIJSON::Object;
|
||||
while (s.isNotEmpty()) {
|
||||
PIString name = PIJSON::stringUnmask(parseName(s));
|
||||
PIJSON value = parseValue(s);
|
||||
auto & child(ret.c_object[name]);
|
||||
child = value;
|
||||
child.c_name = name;
|
||||
s.trim();
|
||||
if (s.isEmpty()) break;
|
||||
if (s[0] != ',') break;
|
||||
s.remove(0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIJSON PIJSON::parseArray(PIString s) {
|
||||
//piCout << "\n\n\n parseArray" << s;
|
||||
PIJSON ret;
|
||||
ret.c_type = PIJSON::Array;
|
||||
while (s.isNotEmpty()) {
|
||||
PIJSON value = parseValue(s);
|
||||
ret.c_array << value;
|
||||
s.trim();
|
||||
if (s.isEmpty()) break;
|
||||
if (s[0] != ',') break;
|
||||
s.remove(0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString PIJSON::stringMask(const PIString & s) {
|
||||
PIString ret;
|
||||
for (auto c: s) {
|
||||
if (!c.isAscii()) {
|
||||
ret += "\\u" + PIString::fromNumber(c.unicode16Code(), 16).expandLeftTo(4, '0');
|
||||
} else {
|
||||
char ca = c.toAscii();
|
||||
switch (ca) {
|
||||
case '"' : ret += "\\\""; break;
|
||||
case '\\': ret += "\\\\"; break;
|
||||
case '/' : ret += "\\/" ; break;
|
||||
case '\b': ret += "\\b" ; break;
|
||||
case '\f': ret += "\\f" ; break;
|
||||
case '\n': ret += "\\n" ; break;
|
||||
case '\r': ret += "\\r" ; break;
|
||||
case '\t': ret += "\\t" ; break;
|
||||
default: ret += ca;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString PIJSON::stringUnmask(const PIString & s) {
|
||||
PIString ret;
|
||||
for (int i = 0; i < s.size_s(); ++i) {
|
||||
char ca = s[i].toAscii();
|
||||
if (ca == '\\') {
|
||||
if (i == s.size_s() - 1) continue;
|
||||
++i;
|
||||
char na = s[i].toAscii();
|
||||
switch (na) {
|
||||
case '"' : ret += '\"'; break;
|
||||
case '\\': ret += '\\'; break;
|
||||
case '/' : ret += '/' ; break;
|
||||
case 'b' : ret += '\b'; break;
|
||||
case 'f' : ret += '\f'; break;
|
||||
case 'n' : ret += '\n'; break;
|
||||
case 'r' : ret += '\r'; break;
|
||||
case 't' : ret += '\t'; break;
|
||||
case 'u' :
|
||||
ret += PIChar(s.mid(i + 1, 4).toUShort(16));
|
||||
i += 4;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
} else {
|
||||
ret += s[i];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void PIJSON::print(PIString & s, const PIJSON & v, PIString tab, bool spaces, bool transform, bool comma) {
|
||||
if (spaces) s += tab;
|
||||
/*
|
||||
switch (v.c_type) {
|
||||
case JSONEntry::Invalid: s << "(Invalid)"; break;
|
||||
case JSONEntry::Null: s << "(Null)"; break;
|
||||
case JSONEntry::Boolean: s << "(Boolean)"; break;
|
||||
case JSONEntry::Number: s << "(Number)"; break;
|
||||
case JSONEntry::String: s << "(String)"; break;
|
||||
case JSONEntry::Object: s << "(Object)"; break;
|
||||
case JSONEntry::Array: s << "(Array)"; break;
|
||||
}
|
||||
*/
|
||||
if (v.name().isNotEmpty()) {
|
||||
s += '"' + (transform ? stringMask(v.name()) : v.name()) + "\":";
|
||||
if (spaces) s += ' ';
|
||||
}
|
||||
switch (v.c_type) {
|
||||
case PIJSON::Invalid: break;
|
||||
case PIJSON::Null: s += "null"; break;
|
||||
case PIJSON::Boolean: s += PIString::fromBool(v.c_value.toBool()); break;
|
||||
case PIJSON::Number: s += v.c_value.toString(); break;
|
||||
case PIJSON::String: s += '"' + (transform ? stringMask(v.c_value.toString()) : v.c_value.toString()) + '"'; break;
|
||||
case PIJSON::Object:
|
||||
s += "{";
|
||||
if (spaces) s += '\n';
|
||||
{
|
||||
PIString ntab = tab + " ";
|
||||
auto it = v.c_object.makeIterator();
|
||||
int cnt = 0;
|
||||
while (it.next()) {
|
||||
print(s, it.value(), ntab, spaces, transform, ++cnt < v.c_object.size_s());
|
||||
}
|
||||
}
|
||||
if (spaces) s += tab;
|
||||
s += "}";
|
||||
break;
|
||||
case PIJSON::Array:
|
||||
s += "[";
|
||||
if (spaces) s += '\n';
|
||||
{
|
||||
PIString ntab = tab + " ";
|
||||
for (int i = 0; i < v.c_array.size_s(); ++i) {
|
||||
print(s, v.c_array[i], ntab, spaces, transform, i < v.c_array.size_s() - 1);
|
||||
}
|
||||
}
|
||||
if (spaces) s += tab;
|
||||
s += "]";
|
||||
break;
|
||||
}
|
||||
if (comma) s += ',';
|
||||
if (spaces) s += "\n";
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
/*! \file pijson.h
|
||||
* \ingroup Core
|
||||
* \brief
|
||||
* \~english JSON class
|
||||
* \~russian Класс JSON
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
JSON class
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIJSON_H
|
||||
#define PIJSON_H
|
||||
|
||||
#include "pivariant.h"
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english JSON class.
|
||||
//! \~russian Класс JSON.
|
||||
class PIP_EXPORT PIJSON {
|
||||
friend PICout operator <<(PICout s, const PIJSON & v);
|
||||
public:
|
||||
|
||||
//! \~english
|
||||
//! Type of JSON tree element
|
||||
//! \~russian
|
||||
//! Тип элемента дерева JSON
|
||||
enum Type {
|
||||
Invalid /*! \~english Invalid type \~russian Недействительный тип */,
|
||||
Null /*! \~english Without value, null \~russian Без значения, null */,
|
||||
Boolean /*! \~english Boolean, /b true or /b false \~russian Логическое, /b true или /b false */,
|
||||
Number /*! \~english Integer or floating-point number \~russian Целое либо число с плавающей точкой */,
|
||||
String /*! \~english Text \~russian Текст */,
|
||||
Object /*! \~english Object, {} \~russian Объект, {} */,
|
||||
Array /*! \~english Array, [] \~russian Массив, [] */
|
||||
};
|
||||
|
||||
//! \~english
|
||||
//! Generate JSON variant
|
||||
//! \~russian
|
||||
//! Вариант генерации JSON
|
||||
enum PrintType {
|
||||
Compact /*! \~english Without spaces, minimum size \~russian Без пробелов, минимальный размер */,
|
||||
Tree /*! \~english With spaces and new-lines, human-readable \~russian С пробелами и новыми строками, читаемый человеком */
|
||||
};
|
||||
|
||||
//! \~english Contructs invalid %PIJSON.
|
||||
//! \~russian Создает недействительный %PIJSON.
|
||||
PIJSON() {}
|
||||
PIJSON(const PIJSON & o) = default;
|
||||
|
||||
//! \~english Returns name of element, or empty string if it doesn`t have name.
|
||||
//! \~russian Возвращает имя элемента, либо пустую строку, если имени нет.
|
||||
const PIString & name() const {return c_name;}
|
||||
|
||||
//! \~english Returns elements array of this element, or empty array if element is not \a PIJSON::Array.
|
||||
//! \~russian Возвращает массив элементов этого элемента, либо пустой массив, если тип элемента не \a PIJSON::Array.
|
||||
const PIVector<PIJSON> & array() const;
|
||||
|
||||
//! \~english Returns elements map of this element, or empty map if element is not \a PIJSON::Object.
|
||||
//! \~russian Возвращает словарь элементов этого элемента, либо пустой словарь, если тип элемента не \a PIJSON::Object.
|
||||
const PIMap<PIString, PIJSON> & object() const;
|
||||
|
||||
//! \~english Returns element value.
|
||||
//! \~russian Возвращает значение элемента.
|
||||
const PIVariant & value() const {return c_value;}
|
||||
|
||||
//! \~english Returns element value as bool.
|
||||
//! \~russian Возвращает значение элемента как логическое.
|
||||
bool toBool() const {return c_value.toBool();}
|
||||
|
||||
//! \~english Returns element value as integer number.
|
||||
//! \~russian Возвращает значение элемента как целое число.
|
||||
int toInt() const {return c_value.toInt();}
|
||||
|
||||
//! \~english Returns element value as floating-point number.
|
||||
//! \~russian Возвращает значение элемента как число с плавающей точкой.
|
||||
double toDouble() const {return c_value.toDouble();}
|
||||
|
||||
//! \~english Returns element value as string, valid for all types.
|
||||
//! \~russian Возвращает значение элемента как строка, действительно для всех типов.
|
||||
PIString toString() const {return c_value.toString();}
|
||||
|
||||
|
||||
//! \~english Returns element type.
|
||||
//! \~russian Возвращает тип элемента.
|
||||
Type type() const {return c_type;}
|
||||
|
||||
//! \~english Returns if element is valid.
|
||||
//! \~russian Возвращает действителен ли элемент.
|
||||
bool isValid() const {return c_type != Invalid;}
|
||||
|
||||
//! \~english Returns if element is \a PIJSON::Object.
|
||||
//! \~russian Возвращает является ли элемент \a PIJSON::Object.
|
||||
bool isObject() const {return c_type == Object;}
|
||||
|
||||
//! \~english Returns if element is \a PIJSON::Array.
|
||||
//! \~russian Возвращает является ли элемент \a PIJSON::Array.
|
||||
bool isArray() const {return c_type == Array;}
|
||||
|
||||
//! \~english Set value and type of element from "v".
|
||||
//! \~russian Устанавливает значение и тип элемента из "v".
|
||||
void setValue(const PIVariant & v);
|
||||
|
||||
//! \~english Clear element and set it to \a PIJSON::Invalid.
|
||||
//! \~russian Очищает элемент и устанавливает его в \a PIJSON::Invalid.
|
||||
void clear();
|
||||
|
||||
//! \~english Returns size of elements array if type is \a PIJSON::Array, size of elements map if type is \a PIJSON::Object, otherwise returns 0.
|
||||
//! \~russian Возвращает размер массива элементов если тип \a PIJSON::Array, размер словаря элементов если тип \a PIJSON::Object, иначе возвращает 0.
|
||||
int size() const;
|
||||
|
||||
//! \~english Returns if elements map contains key "key" if type is \a PIJSON::Object, otherwise returns \b false.
|
||||
//! \~russian Возвращает содержит ли словарь элементов ключ "key" если тип \a PIJSON::Object, иначе возвращает \b false.
|
||||
bool contains(const PIString & key) const;
|
||||
|
||||
//! \~english Set element type to \a PIJSON::Array and resize elements array to "new_size".
|
||||
//! \~russian Устанавливает тип элемента в \a PIJSON::Array и изменяет размер массива элементов на "new_size".
|
||||
void resize(int new_size);
|
||||
|
||||
|
||||
//! \~english Synonim of \a setValue().
|
||||
//! \~russian Аналог \a setValue().
|
||||
PIJSON & operator=(const PIVariant & v) {setValue(v); return *this;}
|
||||
|
||||
PIJSON & operator=(const PIJSON & v);
|
||||
|
||||
|
||||
//! \~english Returns element from array with index "index" if type is \a PIJSON::Array, otherwise returns invalid %PIJSON.
|
||||
//! \~russian Возвращает элемент из массива по индексу "index" если тип \a PIJSON::Array, иначе возвращает недействительный %PIJSON.
|
||||
const PIJSON & operator[](int index) const;
|
||||
|
||||
//! \~english Set element type to \a PIJSON::Array, resize if necessary and returns element from array with index "index".
|
||||
//! \~russian Устанавливает тип элемента в \a PIJSON::Array, изменяет размер массива при неоходимости и возвращает элемент из массива по индексу "index".
|
||||
PIJSON & operator[](int index);
|
||||
|
||||
//! \~english Set element type to \a PIJSON::Array and add element to the end of array.
|
||||
//! \~russian Устанавливает тип элемента в \a PIJSON::Array и добавляет элемент в массив.
|
||||
PIJSON & operator <<(const PIJSON & element);
|
||||
|
||||
|
||||
//! \~english Returns element from map with key "key" if type is \a PIJSON::Object, otherwise returns invalid %PIJSON.
|
||||
//! \~russian Возвращает элемент из словаря по ключу "key" если тип \a PIJSON::Object, иначе возвращает недействительный %PIJSON.
|
||||
PIJSON operator[](const PIString & key) const;
|
||||
|
||||
//! \~english Set element type to \a PIJSON::Object and returns element from map with key "key". If element with this key doesn`t exists, it will be created.
|
||||
//! \~russian Устанавливает тип элемента в \a PIJSON::Object и возвращает элемент из словаря по ключу "key". Если элемента с таким ключом не существует, он будет создан.
|
||||
PIJSON & operator[](const PIString & key);
|
||||
|
||||
PIJSON operator[](const char * key) const {return (*this)[PIString::fromUTF8(key)];}
|
||||
PIJSON & operator[](const char * key) {return (*this)[PIString::fromUTF8(key)];}
|
||||
|
||||
|
||||
//! \~english Returns text representation of JSON tree.
|
||||
//! \~russian Возвращает текстовое представление дерева JSON.
|
||||
PIString toJSON(PrintType print_type = Compact) const;
|
||||
|
||||
//! \~english Parse text representation of JSON "str" and returns it root element.
|
||||
//! \~russian Разбирает текстовое представление JSON "str" и возвращает его корневой элемент.
|
||||
static PIJSON fromJSON(PIString str);
|
||||
|
||||
static PIJSON newObject();
|
||||
static PIJSON newArray();
|
||||
static PIJSON newString(const PIString & v = PIString());
|
||||
|
||||
private:
|
||||
static PIJSON & nullEntry();
|
||||
static PIString parseName(PIString & s);
|
||||
static PIJSON parseValue(PIString & s);
|
||||
static PIJSON parseObject(PIString s);
|
||||
static PIJSON parseArray(PIString s);
|
||||
static PIString stringMask(const PIString & s);
|
||||
static PIString stringUnmask(const PIString & s);
|
||||
static void print(PIString & s, const PIJSON & v, PIString tab, bool spaces, bool transform = false, bool comma = false);
|
||||
|
||||
PIString c_name;
|
||||
PIVariant c_value;
|
||||
PIVector<PIJSON> c_array;
|
||||
PIMap<PIString, PIJSON> c_object;
|
||||
Type c_type = Invalid;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english Output operator to \a PICout.
|
||||
//! \~russian Оператор вывода в \a PICout.
|
||||
inline PICout operator <<(PICout s, const PIJSON & v) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
PIString str;
|
||||
PIJSON::print(str, v, "", true);
|
||||
s << str;
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
#endif // PICONSTCHARS_H
|
||||
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Storage of properties for GUI usage
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pipropertystorage.h"
|
||||
|
||||
|
||||
//! \~\class PIPropertyStorage pipropertystorage.h
|
||||
//! \~\details
|
||||
//! \~english \section PIPropertyStorage_sec0 Synopsis
|
||||
//! \~russian \section PIPropertyStorage_sec0 Краткий обзор
|
||||
//!
|
||||
//! \~english
|
||||
//! Key-value storage, based on PIVector with PIPropertyStorage::Property elements. Each element in vector
|
||||
//! contains unique name. You can access property by name with \a propertyValueByName() or \a propertyByName().
|
||||
//! You can add or replace property by \a addProperty(const Property&) or \a addProperty(const PIString&, const PIVariant&, const PIString&, int).
|
||||
//!
|
||||
//! \~russian
|
||||
//! Хранилище свойств ключ-значние, основанный на PIVector с элементами PIPropertyStorage::Property.
|
||||
//! Каждый элемент имеет уникальное имя. Доступ к свойствам через \a propertyValueByName() или \a propertyByName().
|
||||
//! Добавление и перезапись свойств через \a addProperty(const Property&) или \a addProperty(const PIString&, const PIVariant&, const PIString&, int).
|
||||
//!
|
||||
//! \~english Example:
|
||||
//! \~russian Пример:
|
||||
//! \~\code{.cpp}
|
||||
//! \endcode
|
||||
//!
|
||||
|
||||
|
||||
//! \~\class PIPropertyStorage::Property pipropertystorage.h
|
||||
//! \~\details
|
||||
//!
|
||||
|
||||
|
||||
bool PIPropertyStorage::isPropertyExists(const PIString & _name) const {
|
||||
for (uint i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == _name)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//! \details
|
||||
//! \~english Returns "true" if new property added, else if update existing property return "false"
|
||||
//! \~russian Возвращает истину если новое свойство добавлено, в случае обновления "ложь"
|
||||
bool PIPropertyStorage::addProperty(const PIPropertyStorage::Property & p) {
|
||||
for (uint i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == p.name) {
|
||||
props[i] = p;
|
||||
return false;
|
||||
}
|
||||
props << p;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIPropertyStorage::addProperty(PIPropertyStorage::Property && p) {
|
||||
for (uint i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == p.name) {
|
||||
props[i] = std::move(p);
|
||||
return false;
|
||||
}
|
||||
props << std::move(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//! \details
|
||||
//! \~english Returns "true" if new property added, else if update existing property return "false"
|
||||
//! \~russian Возвращает истину если новое свойство добавлено, в случае обновления "ложь"
|
||||
bool PIPropertyStorage::addProperty(const PIString & _name, const PIVariant & _def_value, const PIString & _comment, int _flags) {
|
||||
return addProperty(Property(_name, _comment, _def_value, _flags));
|
||||
}
|
||||
|
||||
|
||||
bool PIPropertyStorage::removeProperty(const PIString & _name) {
|
||||
for (uint i = 0; i < props.size(); ++i) {
|
||||
if (props[i].name == _name) {
|
||||
props.remove(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//! \details
|
||||
//! \~english "flag" checked as bitfield
|
||||
//! \~russian "flag" проверяется как битовое поле
|
||||
int PIPropertyStorage::removePropertiesByFlag(int flag) {
|
||||
int ret = 0;
|
||||
for (int i = 0; i < props.size_s(); ++i) {
|
||||
if ((props[i].flags & flag) == flag) {
|
||||
props.remove(i);
|
||||
--i;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! \details
|
||||
//! \~english "flag_ignore" is bitfield to ignore property in merge process
|
||||
//! \~russian "flag_ignore" - битовое поле для исключения свойств из процесса слияния
|
||||
void PIPropertyStorage::updateProperties(const PIVector<PIPropertyStorage::Property> & properties_, int flag_ignore) {
|
||||
PIMap<PIString, PIVariant> values;
|
||||
piForeachC(Property & p, props)
|
||||
if (((p.flags & flag_ignore) != flag_ignore) || (flag_ignore == 0))
|
||||
values[p.name] = p.value;
|
||||
props = properties_;
|
||||
for (uint i = 0; i < props.size(); ++i) {
|
||||
Property & p(props[i]);
|
||||
if (values.contains(p.name)) {
|
||||
PIVariant pv = values[p.name];
|
||||
if (pv.type() == p.value.type())
|
||||
p.value = pv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PIPropertyStorage::Property PIPropertyStorage::propertyByName(const PIString & name) const {
|
||||
piForeachC(Property & p, props)
|
||||
if (p.name == name)
|
||||
return p;
|
||||
return Property();
|
||||
}
|
||||
|
||||
|
||||
PIVariant PIPropertyStorage::propertyValueByName(const PIString & name) const {
|
||||
piForeachC(Property & p, props)
|
||||
if (p.name == name)
|
||||
return p.value;
|
||||
return PIVariant();
|
||||
}
|
||||
|
||||
|
||||
bool PIPropertyStorage::setPropertyValue(const PIString & name, const PIVariant & value) {
|
||||
for (uint i = 0; i < props.size(); ++i) {
|
||||
if (props[i].name == name) {
|
||||
props[i].value = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PIPropertyStorage::setPropertyComment(const PIString & name, const PIString & comment) {
|
||||
for (uint i = 0; i < props.size(); ++i) {
|
||||
if (props[i].name == name) {
|
||||
props[i].comment = comment;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PIPropertyStorage::setPropertyFlags(const PIString & name, int flags) {
|
||||
for (uint i = 0; i < props.size(); ++i) {
|
||||
if (props[i].name == name) {
|
||||
props[i].flags = flags;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
PIPropertyStorage::Property & PIPropertyStorage::operator[](const PIString & name) {
|
||||
piForeach (Property & p, props)
|
||||
if (p.name == name)
|
||||
return p;
|
||||
addProperty(name, "");
|
||||
return props.back();
|
||||
}
|
||||
|
||||
|
||||
const PIPropertyStorage::Property PIPropertyStorage::operator[](const PIString & name) const {
|
||||
piForeachC (Property & p, props)
|
||||
if (p.name == name)
|
||||
return p;
|
||||
return Property();
|
||||
}
|
||||
@@ -1,296 +0,0 @@
|
||||
/*! \file pipropertystorage.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english Properties array
|
||||
* \~russian Массив свойств
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Storage of properties for GUI usage
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIPROPERTYSTORAGE_H
|
||||
#define PIPROPERTYSTORAGE_H
|
||||
|
||||
#include "pivariant.h"
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english This class provides key-value properties storage.
|
||||
//! \~russian Этот класс предоставляет ключ-значение хранение свойств.
|
||||
class PIP_EXPORT PIPropertyStorage {
|
||||
public:
|
||||
|
||||
//! \~english Contructs an empty %PIPropertyStorage
|
||||
//! \~russian Создает пустой %PIPropertyStorage
|
||||
PIPropertyStorage() {}
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english PIPropertyStorage element.
|
||||
//! \~russian Элемент PIPropertyStorage.
|
||||
struct PIP_EXPORT Property {
|
||||
|
||||
//! \~english Contructs %PIPropertyStorage::Property with name "n", comment "c", value "v" and flags "f"
|
||||
//! \~russian Создает %PIPropertyStorage::Property с именем "n", комментарием "c", значением "v" и флагами "f"
|
||||
Property(const PIString & n = PIString(), const PIString & c = PIString(), const PIVariant & v = PIVariant(), int f = 0): name(n), comment(c), value(v), flags(f) {}
|
||||
|
||||
//! \~english Contructs copy of another %PIPropertyStorage::Property "o"
|
||||
//! \~russian Создает копию %PIPropertyStorage::Property "o"
|
||||
Property(const Property & o): name(o.name), comment(o.comment), value(o.value), flags(o.flags) {}
|
||||
|
||||
Property(Property && o) {swap(o);}
|
||||
|
||||
//! \~english Assign operator
|
||||
//! \~russian Оператор присваивания
|
||||
Property & operator =(const Property & v) {
|
||||
name = v.name;
|
||||
comment = v.comment;
|
||||
value = v.value;
|
||||
flags = v.flags;
|
||||
return *this;
|
||||
}
|
||||
Property & operator =(Property && v) {swap(v); return *this;}
|
||||
|
||||
|
||||
//! \~english Returns value as boolean
|
||||
//! \~russian Возвращает значение как логическое
|
||||
bool toBool() const {return value.toBool();}
|
||||
|
||||
//! \~english Returns value as integer
|
||||
//! \~russian Возвращает значение как целое
|
||||
int toInt() const {return value.toInt();}
|
||||
|
||||
//! \~english Returns value as float
|
||||
//! \~russian Возвращает значение как float
|
||||
float toFloat() const {return value.toFloat();}
|
||||
|
||||
//! \~english Returns value as double
|
||||
//! \~russian Возвращает значение как double
|
||||
double toDouble() const {return value.toDouble();}
|
||||
|
||||
//! \~english Returns value as string
|
||||
//! \~russian Возвращает значение как строку
|
||||
PIString toString() const {return value.toString();}
|
||||
|
||||
void swap(Property & o) {
|
||||
name.swap(o.name);
|
||||
comment.swap(o.comment);
|
||||
value.swap(o.value);
|
||||
piSwap(flags, o.flags);
|
||||
}
|
||||
|
||||
//! \~english Property name (uniqueue for %PIPropertyStorage)
|
||||
//! \~russian Имя свойства (уникальное для %PIPropertyStorage)
|
||||
PIString name;
|
||||
|
||||
//! \~english Optional description of property
|
||||
//! \~russian Опциональный комментарий свойства
|
||||
PIString comment;
|
||||
|
||||
//! \~english Property value
|
||||
//! \~russian Значение свойства
|
||||
PIVariant value;
|
||||
|
||||
//! \~english Abstract flags which may be used for user needs
|
||||
//! \~russian Абстрактные флаги, могут быть использованы для своих нужд
|
||||
int flags;
|
||||
};
|
||||
|
||||
//! \~english Contructs %PIPropertyStorage with "pl" properties
|
||||
//! \~russian Создает %PIPropertyStorage со свойствами "pl"
|
||||
PIPropertyStorage(const PIVector<Property> & pl) {props = pl;}
|
||||
|
||||
//! \~english Contructs %PIPropertyStorage from another "o"
|
||||
//! \~russian Создает %PIPropertyStorage из другого "o"
|
||||
PIPropertyStorage(PIVector<Property> && o): props(std::move(o)) {}
|
||||
|
||||
typedef PIVector<Property>::const_iterator const_iterator;
|
||||
typedef PIVector<Property>::iterator iterator;
|
||||
typedef Property value_type;
|
||||
|
||||
iterator begin() {return props.begin();}
|
||||
const_iterator begin() const {return props.begin();}
|
||||
iterator end() {return props.end();}
|
||||
const_iterator end() const {return props.end();}
|
||||
|
||||
//! \~english Returns properties count
|
||||
//! \~russian Возвращает количество свойств
|
||||
int length() const {return props.length();}
|
||||
|
||||
//! \~english Returns properties count
|
||||
//! \~russian Возвращает количество свойств
|
||||
int size() const {return props.size();}
|
||||
|
||||
//! \~english Returns if no properties
|
||||
//! \~russian Возвращает нет ли свойств
|
||||
bool isEmpty() const {return props.isEmpty();}
|
||||
|
||||
//! \~english Returns if properties
|
||||
//! \~russian Возвращает есть ли свойства
|
||||
bool isNotEmpty() const {return props.isNotEmpty();}
|
||||
|
||||
//! \~english Returns first property
|
||||
//! \~russian Возвращает первое свойство
|
||||
Property & front() {return props.front();}
|
||||
|
||||
//! \~english Returns first property as const
|
||||
//! \~russian Возвращает первое свойство как константу
|
||||
const Property & front() const {return props.front();}
|
||||
|
||||
//! \~english Returns last property
|
||||
//! \~russian Возвращает последнее свойство
|
||||
Property & back() {return props.back();}
|
||||
|
||||
//! \~english Returns last property as const
|
||||
//! \~russian Возвращает последнее свойство как константу
|
||||
const Property & back() const {return props.back();}
|
||||
|
||||
//! \~english Remove property at index "i"
|
||||
//! \~russian Удаляет свойство по индексу "i"
|
||||
void removeAt(int i) {props.remove(i);}
|
||||
|
||||
//! \~english Remove all properties
|
||||
//! \~russian Удаляет все свойства
|
||||
void clear() {props.clear();}
|
||||
|
||||
|
||||
//! \~english Returns copy of this %PIPropertyStorage
|
||||
//! \~russian Возвращает копию этого %PIPropertyStorage
|
||||
PIPropertyStorage copy() const {return PIPropertyStorage(*this);}
|
||||
|
||||
//! \~english Returns properties count
|
||||
//! \~russian Возвращает количество свойств
|
||||
int propertiesCount() const {return props.size();}
|
||||
|
||||
//! \~english Returns properties as PIVector
|
||||
//! \~russian Возвращает свойства как PIVector
|
||||
PIVector<Property> & properties() {return props;}
|
||||
|
||||
//! \~english Returns properties as const PIVector
|
||||
//! \~russian Возвращает свойства как константный PIVector
|
||||
const PIVector<Property> & properties() const {return props;}
|
||||
|
||||
const PIPropertyStorage & propertyStorage() const {return *this;}
|
||||
|
||||
//! \~english Returns if properties with name "name" exists
|
||||
//! \~russian Возвращает присутствует ли свойство с именем "name"
|
||||
bool isPropertyExists(const PIString & name) const;
|
||||
|
||||
//! \~english Remove all properties
|
||||
//! \~russian Удаляет все свойства
|
||||
void clearProperties() {props.clear();}
|
||||
|
||||
//! \~english Add property if name isn't present in storage, otherwrise update existing property with same name
|
||||
//! \~russian Добавляет новое свойство, если его имени не было в контейнере, иначе обновляет существующее свойство с этим именем
|
||||
bool addProperty(const Property & p);
|
||||
bool addProperty(Property && p);
|
||||
|
||||
//! \~english Add property if name isn't present in storage, otherwrise update existing property with same name
|
||||
//! \~russian Добавляет новое свойство, если его имени не было в контейнере, иначе обновляет существующее свойство с этим именем
|
||||
bool addProperty(const PIString & _name, const PIVariant & _def_value, const PIString & _comment = PIString(), int _flags = 0);
|
||||
|
||||
//! \~english Remove property with name "name", returns if property removed
|
||||
//! \~russian Удаляет свойство с именем "name", возвращает было ли оно удалено
|
||||
bool removeProperty(const PIString & name);
|
||||
|
||||
//! \~english Remove all properties with flag "flag" set, returns removed properties count
|
||||
//! \~russian Удаляет все свойства с флагом "flag", возвращает количество удаленных свойств
|
||||
int removePropertiesByFlag(int flag);
|
||||
|
||||
//! \~english Merge other "properties" into this
|
||||
//! \~russian Объединяет "properties" с текущим контейнером
|
||||
void updateProperties(const PIVector<Property> & properties, int flag_ignore = 0);
|
||||
|
||||
//! \~english Returns property with name "name" or default-constructed %PIPropertyStorage::Property
|
||||
//! \~russian Возвращает свойство с именем "name" или пустое %PIPropertyStorage::Property
|
||||
Property propertyByName(const PIString & name) const;
|
||||
|
||||
//! \~english Returns property value with name "name" or invalid %PIVariant
|
||||
//! \~russian Возвращает значение свойства с именем "name" или недействительный %PIVariant
|
||||
PIVariant propertyValueByName(const PIString & name) const;
|
||||
|
||||
//! \~english Set value of property with name "name" to "value", returns if property exists
|
||||
//! \~russian Устанавливает значение "value" свойству с именем "name", возвращает существует ли такое свойство
|
||||
bool setPropertyValue(const PIString & name, const PIVariant & value);
|
||||
|
||||
//! \~english Set comment of property with name "name" to "comment", returns if property exists
|
||||
//! \~russian Устанавливает комментарий "comment" свойству с именем "name", возвращает существует ли такое свойство
|
||||
bool setPropertyComment(const PIString & name, const PIString & comment);
|
||||
|
||||
//! \~english Set flags of property with name "name" to "flags", returns if property exists
|
||||
//! \~russian Устанавливает флаги "flags" свойству с именем "name", возвращает существует ли такое свойство
|
||||
bool setPropertyFlags(const PIString & name, int flags);
|
||||
|
||||
//! \~english Add property "p"
|
||||
//! \~russian Добавляет свойство "p"
|
||||
PIPropertyStorage & operator <<(const PIPropertyStorage::Property & p) {props << p; return *this;}
|
||||
|
||||
//! \~english Add properties "p"
|
||||
//! \~russian Добавляет свойства "p"
|
||||
PIPropertyStorage & operator <<(const PIVector<Property> & p) {props << p; return *this;}
|
||||
|
||||
//! \~english Add properties "p"
|
||||
//! \~russian Добавляет свойства "p"
|
||||
PIPropertyStorage & operator <<(const PIPropertyStorage & p) {props << p.props; return *this;}
|
||||
|
||||
//! \~english Returns property with index "i"
|
||||
//! \~russian Возвращает свойство по индексу "i"
|
||||
Property & operator[](int i) {return props[i];}
|
||||
|
||||
//! \~english Returns property with index "i" as const
|
||||
//! \~russian Возвращает свойство по индексу "i" как константу
|
||||
const Property & operator[](int i) const {return props[i];}
|
||||
|
||||
//! \~english Returns property with name "name"
|
||||
//! \~russian Возвращает свойство с именем "name"
|
||||
Property & operator[](const PIString & name);
|
||||
|
||||
//! \~english Returns property with name "name" as const
|
||||
//! \~russian Возвращает свойство с именем "name" как константу
|
||||
const Property operator[](const PIString & name) const;
|
||||
|
||||
protected:
|
||||
PIVector<Property> props;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIPropertyStorage::Property) {s << v.name << v.value << v.comment << v.flags; return s;}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ (PIPropertyStorage::Property) {s >> v.name >> v.value >> v.comment >> v.flags; return s;}
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIPropertyStorage) {s << v.properties(); return s;}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ (PIPropertyStorage) {s >> v.properties(); return s;}
|
||||
|
||||
|
||||
#endif // PIPROPERTYSTORAGE_H
|
||||
@@ -1,1799 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
String
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "pistring.h"
|
||||
#include "pistringlist.h"
|
||||
#include "pimathbase.h"
|
||||
#ifdef PIP_ICU
|
||||
# define U_NOEXCEPT
|
||||
# include "unicode/ucnv.h"
|
||||
#endif
|
||||
#ifdef WINDOWS
|
||||
# include <stringapiset.h>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
||||
//! \class PIString pistring.h
|
||||
//! \~\details
|
||||
//! \~english \section PIString_sec0 Synopsis
|
||||
//! \~russian \section PIString_sec0 Краткий обзор
|
||||
//!
|
||||
//! \~english
|
||||
//! String is a sequence of \a PIChar. Real memory size of string is symbols count * 2.
|
||||
//! String can be constucted from many types of data and can be converted
|
||||
//! to many types. There are many operators and handly functions to use
|
||||
//! string as you wish.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Строка состоит из последовательности \a PIChar. Реальный объем памяти,
|
||||
//! занимаемый строкой, равен количеству символов * 2. Строка может быть
|
||||
//! создана из множества типов и преобразована в несколько типов.
|
||||
//! Имеет множество методов для манипуляций.
|
||||
//!
|
||||
|
||||
|
||||
|
||||
|
||||
const char PIString::toBaseN[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||
'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^'};
|
||||
const char PIString::fromBaseN[] = {(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
|
||||
(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
|
||||
(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
|
||||
(char) 0, (char) 1, (char) 2, (char) 3, (char) 4, (char) 5, (char) 6, (char) 7, (char) 8, (char) 9, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
|
||||
(char)-1, (char)10, (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20, (char)21, (char)22, (char)23, (char)24,
|
||||
(char)25, (char)26, (char)27, (char)28, (char)29, (char)30, (char)31, (char)32, (char)33, (char)34, (char)35, (char)36, (char)37, (char)38, (char)39, (char)-1,
|
||||
(char)-1, (char)10, (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20, (char)21, (char)22, (char)23, (char)24,
|
||||
(char)25, (char)26, (char)27, (char)28, (char)29, (char)30, (char)31, (char)32, (char)33, (char)34, (char)35, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
|
||||
(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
|
||||
(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
|
||||
(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
|
||||
(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
|
||||
(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
|
||||
(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
|
||||
(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
|
||||
(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1};
|
||||
|
||||
const float PIString::ElideLeft = 0.f;
|
||||
const float PIString::ElideCenter = .5f;
|
||||
const float PIString::ElideRight = 1.f;
|
||||
|
||||
|
||||
template <typename T>
|
||||
T toDecimal(const PIString & s) {
|
||||
int part = 0, exp = 0;
|
||||
bool negative = false, negative_exp = false, err = false, has_digit = false;
|
||||
T ret = 0., frac = 0., frac_delim = 1.;
|
||||
for (const PIChar pc: s) {
|
||||
char c = pc.toAscii();
|
||||
switch (part) {
|
||||
case 0: // sign
|
||||
if (pc.isSpace()) continue;
|
||||
if (c >= '0' && c <= '9') {
|
||||
has_digit = true;
|
||||
ret = c - '0';
|
||||
part = 1;
|
||||
continue;
|
||||
}
|
||||
if (c == '+') {
|
||||
part = 1;
|
||||
continue;
|
||||
}
|
||||
if (c == '-') {
|
||||
negative = true;
|
||||
part = 1;
|
||||
continue;
|
||||
}
|
||||
if (c == '.' || c == ',') {
|
||||
part = 2;
|
||||
continue;
|
||||
}
|
||||
err = true;
|
||||
break;
|
||||
case 1: // integer
|
||||
if (c >= '0' && c <= '9') {
|
||||
has_digit = true;
|
||||
ret = ret * 10 + (c - '0');
|
||||
continue;
|
||||
}
|
||||
if (c == '.' || c == ',') {
|
||||
part = 2;
|
||||
continue;
|
||||
}
|
||||
if ((c == 'e' || c == 'E') && has_digit) {
|
||||
part = 3;
|
||||
continue;
|
||||
}
|
||||
err = true;
|
||||
break;
|
||||
case 2: // fractional
|
||||
if (c >= '0' && c <= '9') {
|
||||
has_digit = true;
|
||||
frac = frac * 10 + (c - '0');
|
||||
frac_delim *= 10.;
|
||||
continue;
|
||||
}
|
||||
if ((c == 'e' || c == 'E') && has_digit) {
|
||||
part = 3;
|
||||
continue;
|
||||
}
|
||||
err = true;
|
||||
break;
|
||||
case 3: // exponent with sign
|
||||
if (c == '+') {
|
||||
part = 4;
|
||||
continue;
|
||||
}
|
||||
if (c == '-') {
|
||||
negative_exp = true;
|
||||
part = 4;
|
||||
continue;
|
||||
}
|
||||
case 4: // exponent
|
||||
if (c >= '0' && c <= '9') {
|
||||
exp = (exp * 10) + (c - '0');
|
||||
continue;
|
||||
}
|
||||
err = true;
|
||||
break;
|
||||
}
|
||||
if (err) break;
|
||||
}
|
||||
frac /= frac_delim;
|
||||
ret += frac;
|
||||
if (negative && has_digit) ret = -ret;
|
||||
if (exp > 0) {
|
||||
if (negative_exp) ret /= pow10((T)exp);
|
||||
else ret *= pow10((T)exp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#define pisprintf(f, v) char ch[256]; memset(ch, 0, 256); snprintf(ch, 256, f, v); return PIStringAscii(ch);
|
||||
|
||||
PIString PIString::itos(const int num) {pisprintf("%d", num);}
|
||||
PIString PIString::ltos(const long num) {pisprintf("%ld", num);}
|
||||
PIString PIString::lltos(const llong num) {pisprintf("%lld", num);}
|
||||
PIString PIString::uitos(const uint num) {pisprintf("%u", num);}
|
||||
PIString PIString::ultos(const ulong num) {pisprintf("%lu", num);}
|
||||
PIString PIString::ulltos(const ullong num) {pisprintf("%llu", num);}
|
||||
PIString PIString::dtos(const double num, char format, int precision) {
|
||||
char f[8] = "%.";
|
||||
int wr = snprintf(&(f[2]), 4, "%d", precision);
|
||||
if (wr > 4) wr = 4;
|
||||
f[2 + wr] = format;
|
||||
f[3 + wr] = 0;
|
||||
pisprintf(f, num);
|
||||
}
|
||||
#undef pisprintf
|
||||
|
||||
|
||||
|
||||
PIString PIString::fromNumberBaseS(const llong value, int base, bool * ok) {
|
||||
if (value == 0LL) return PIString('0');
|
||||
if ((base < 2) || (base > 40)) {
|
||||
if (ok != 0) *ok = false;
|
||||
return PIString();
|
||||
}
|
||||
if (ok != 0) *ok = true;
|
||||
if (base == 10) return lltos(value);
|
||||
PIString ret;
|
||||
llong v = value < 0 ? -value : value, cn;
|
||||
int b = base;
|
||||
while (v >= llong(base)) {
|
||||
cn = v % b;
|
||||
v /= b;
|
||||
//cout << int(cn) << ", " << int(v) << endl;
|
||||
ret.push_front(PIChar(toBaseN[cn]));
|
||||
}
|
||||
if (v > 0) ret.push_front(PIChar(toBaseN[v]));
|
||||
if (value < 0) ret.push_front('-');
|
||||
return ret;
|
||||
}
|
||||
|
||||
PIString PIString::fromNumberBaseU(const ullong value, int base, bool * ok) {
|
||||
if (value == 0ULL) return PIString('0');
|
||||
if ((base < 2) || (base > 40)) {
|
||||
if (ok != 0) *ok = false;
|
||||
return PIString();
|
||||
}
|
||||
if (ok != 0) *ok = true;
|
||||
if (base == 10) return ulltos(value);
|
||||
PIString ret;
|
||||
ullong v = value, cn;
|
||||
int b = base;
|
||||
while (v >= ullong(base)) {
|
||||
cn = v % b;
|
||||
v /= b;
|
||||
//cout << int(cn) << ", " << int(v) << endl;
|
||||
ret.push_front(PIChar(toBaseN[cn]));
|
||||
}
|
||||
if (v > 0) ret.push_front(PIChar(toBaseN[v]));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
llong PIString::toNumberBase(const PIString & value, int base, bool * ok) {
|
||||
static const PIString s_0x = PIStringAscii("0x");
|
||||
PIString v = value.trimmed();
|
||||
if (base < 0) {
|
||||
int ind = v.find(s_0x);
|
||||
if (ind == 0 || ind == 1) {
|
||||
v.remove(ind, 2);
|
||||
base = 16;
|
||||
} else {
|
||||
base = 10;
|
||||
}
|
||||
} else if ((base < 2) || (base > 40)) {
|
||||
if (ok != 0) *ok = false;
|
||||
return 0;
|
||||
}
|
||||
if (ok) *ok = true;
|
||||
PIVector<int> digits;
|
||||
llong ret = 0, m = 1;
|
||||
bool neg = false;
|
||||
char cs;
|
||||
for (int i = 0; i < v.size_s(); ++i) {
|
||||
if (v[i] == PIChar('-')) {
|
||||
neg = !neg;
|
||||
continue;
|
||||
}
|
||||
cs = fromBaseN[int(v[i].toAscii())];
|
||||
if (cs < 0 || cs >= base) {
|
||||
if (ok) *ok = false;
|
||||
break;
|
||||
}
|
||||
digits << cs;
|
||||
}
|
||||
for (int i = digits.size_s() - 1; i >= 0; --i) {
|
||||
ret += digits[i] * m;
|
||||
m *= base;
|
||||
}
|
||||
if (neg) ret = -ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void PIString::appendFromChars(const char * c, int s, const char * codepage) {
|
||||
// piCout << "appendFromChars";
|
||||
if (s == 0) return;
|
||||
int old_sz = size_s();
|
||||
if (s == -1) s = strlen(c);
|
||||
#ifdef PIP_ICU
|
||||
UErrorCode e((UErrorCode)0);
|
||||
UConverter * cc = ucnv_open(codepage, &e);
|
||||
if (cc) {
|
||||
d.enlarge(s);
|
||||
e = (UErrorCode)0;
|
||||
int sz = ucnv_toUChars(cc, (UChar*)(d.data(old_sz)), s, c, s, &e);
|
||||
d.resize(old_sz+sz);
|
||||
ucnv_close(cc);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
# ifdef WINDOWS
|
||||
int sz = MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, s, 0, 0);
|
||||
if (sz <= 0) return;
|
||||
d.enlarge(sz);
|
||||
MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, s, (LPWSTR)d.data(old_sz), sz);
|
||||
# else
|
||||
std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> ucs2conv;
|
||||
std::u16string ucs2 = ucs2conv.from_bytes(c, c+s);
|
||||
d.enlarge(ucs2.size());
|
||||
ucs2.copy((char16_t *)d.data(old_sz), ucs2.size());
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::fromConsole(const PIByteArray & ba) {
|
||||
PIString ret;
|
||||
if (ba.isNotEmpty()) ret.appendFromChars((const char*)ba.data(), ba.size(), __sysoemname__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::fromConsole(const char * s) {
|
||||
PIString ret;
|
||||
if (!s) return ret;
|
||||
if (s[0] != '\0') ret.appendFromChars(s, -1, __sysoemname__);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::fromSystem(const PIByteArray & ba) {
|
||||
PIString ret;
|
||||
if (ba.isNotEmpty()) ret.appendFromChars((const char*)ba.data(), ba.size(), __syslocname__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::fromSystem(const char * s) {
|
||||
PIString ret;
|
||||
if (!s) return ret;
|
||||
if (s[0] != '\0') ret.appendFromChars(s, -1, __syslocname__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::fromUTF8(const char * s) {
|
||||
PIString ret;
|
||||
if (!s) return ret;
|
||||
if (s[0] != '\0') {
|
||||
if ((uchar)s[0] == 0xEF && (uchar)s[1] == 0xBB && (uchar)s[2] == 0xBF) {
|
||||
s += 3;
|
||||
if (s[0] == '\0') return ret;
|
||||
}
|
||||
ret.appendFromChars(s, -1, __utf8name__);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::fromUTF8(const PIByteArray & ba) {
|
||||
PIString ret;
|
||||
if (ba.isNotEmpty()) {
|
||||
const char * data = (const char*)ba.data();
|
||||
int size = ba.size();
|
||||
if (ba.size() >= 3) {
|
||||
if (ba[0] == 0xEF && ba[1] == 0xBB && ba[2] == 0xBF) {
|
||||
data += 3;
|
||||
size -= 3;
|
||||
if (size == 0) return ret;
|
||||
}
|
||||
}
|
||||
ret.appendFromChars(data, size, __utf8name__);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::fromAscii(const char * s) {
|
||||
return fromAscii(s, strlen(s));
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::fromAscii(const char * s, int len) {
|
||||
PIString ret;
|
||||
ret.resize(len);
|
||||
for (int l = 0; l < len; ++l) {
|
||||
ret[l] = s[l];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::fromCodepage(const char * s, const char * c) {
|
||||
PIString ret;
|
||||
if (s[0] > '\0') ret.appendFromChars(s, -1
|
||||
#ifdef PIP_ICU
|
||||
, c
|
||||
#else
|
||||
# ifdef WINDOWS
|
||||
, __utf8name__
|
||||
# endif
|
||||
#endif
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Example:
|
||||
//! \~russian
|
||||
//! Пример:
|
||||
//! \~\code
|
||||
//! piCout << PIString::readableSize(512); // 512 B
|
||||
//! piCout << PIString::readableSize(5120); // 5.0 kB
|
||||
//! piCout << PIString::readableSize(512000); // 500.0 kB
|
||||
//! piCout << PIString::readableSize(5120000); // 4.8 MB
|
||||
//! piCout << PIString::readableSize(512000000); // 488.2 MB
|
||||
//! piCout << PIString::readableSize(51200000000); // 47.6 GB
|
||||
//! \endcode
|
||||
PIString PIString::readableSize(llong bytes) {
|
||||
PIString s;
|
||||
s.setReadableSize(bytes);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void PIString::buildData(const char * cp) const {
|
||||
deleteData();
|
||||
#ifdef PIP_ICU
|
||||
UErrorCode e((UErrorCode)0);
|
||||
UConverter * cc = ucnv_open(cp, &e);
|
||||
if (cc) {
|
||||
const size_t len = MB_CUR_MAX*size()+1;
|
||||
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';
|
||||
return;
|
||||
}
|
||||
#else
|
||||
# ifdef WINDOWS
|
||||
int sz = WideCharToMultiByte((uint)(uintptr_t)cp, 0, (LPCWCH)d.data(), d.size_s(), 0, 0, NULL, NULL);
|
||||
if (sz <= 0) {
|
||||
data_ = (char *)malloc(1);
|
||||
data_[0] = '\0';
|
||||
return;
|
||||
}
|
||||
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';
|
||||
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());
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PIString::deleteData() const {
|
||||
if (!data_) return;
|
||||
free(data_);
|
||||
data_ = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void PIString::trimsubstr(int &st, int &fn) const {
|
||||
for (int i = 0; i < d.size_s(); ++i) {
|
||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12) && at(i) != uchar(0)) {
|
||||
st = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (st < 0) return;
|
||||
for (int i = d.size_s() - 1; i >= 0; --i) {
|
||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12) && at(i) != uchar(0)) {
|
||||
fn = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint PIString::hash() const {
|
||||
return piHashData((const uchar*)d.data(), d.size() * sizeof(PIChar));
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PIString::toSystem() const {
|
||||
if (isEmpty()) return PIByteArray();
|
||||
buildData(__syslocname__);
|
||||
return PIByteArray(data_, strlen(data_));
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PIString::toUTF8() const {
|
||||
if (isEmpty()) return PIByteArray();
|
||||
buildData(__utf8name__);
|
||||
return PIByteArray(data_, strlen(data_));
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PIString::toCharset(const char * c) const {
|
||||
if (isEmpty()) return PIByteArray();
|
||||
buildData(
|
||||
#ifdef PIP_ICU
|
||||
c
|
||||
#else
|
||||
# ifdef WINDOWS
|
||||
__utf8name__
|
||||
# endif
|
||||
#endif
|
||||
);
|
||||
return PIByteArray(data_, strlen(data_));
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::simplified() const {
|
||||
PIString ret(*this);
|
||||
for (int i = 0; i < ret.size_s(); ++i)
|
||||
if (!ret[i].isAscii())
|
||||
ret[i] = '?';
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::operator +=(const char * str) {
|
||||
if (!str) return *this;
|
||||
appendFromChars(str, -1, __syslocname__);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::operator +=(const PIByteArray & ba) {
|
||||
appendFromChars((const char * )ba.data(), ba.size_s(), __utf8name__);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString::~PIString() {
|
||||
deleteData();
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::operator +=(const wchar_t * str) {
|
||||
if (!str) return *this;
|
||||
int i = -1;
|
||||
while (str[++i]) {
|
||||
d.push_back(PIChar(str[i]));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::operator +=(const PIString & str) {
|
||||
d.append(str.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::operator +=(const PIConstChars & str) {
|
||||
if (!str.isEmpty()) {
|
||||
size_t os = d.size();
|
||||
d.enlarge(str.size());
|
||||
for (size_t l = 0; l < d.size(); ++l) {
|
||||
d[os + l] = str[l];
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool PIString::operator ==(const PIString & str) const {
|
||||
return d == str.d;
|
||||
}
|
||||
|
||||
|
||||
bool PIString::operator !=(const PIString & str) const {
|
||||
return d != str.d;
|
||||
}
|
||||
|
||||
|
||||
bool PIString::operator <(const PIString & str) const {
|
||||
size_t l = str.size();
|
||||
if (size() < l) return true;
|
||||
if (size() > l) return false;
|
||||
for (size_t i = 0; i < l; ++i) {
|
||||
if (at(i) == str.at(i)) continue;
|
||||
if (at(i) < str.at(i)) return true;
|
||||
else return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PIString::operator >(const PIString & str) const {
|
||||
size_t l = str.size();
|
||||
if (size() < l) return false;
|
||||
if (size() > l) return true;
|
||||
for (size_t i = 0; i < l; ++i) {
|
||||
if (at(i) == str.at(i)) continue;
|
||||
if (at(i) < str.at(i)) return false;
|
||||
else return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! If "len" < 0 then returns substring from symbol "start" to end.
|
||||
//! "start" should be >= 0.
|
||||
//! \~russian
|
||||
//! Если "len" < 0 тогда возвращается подстрока от символа "start" и до конца.
|
||||
//! "start" должен быть >= 0.
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! piCout << s.mid(0, -1); // s = "0123456789"
|
||||
//! piCout << s.mid(0, 2); // s = "01"
|
||||
//! piCout << s.mid(3); // s = "3456789"
|
||||
//! piCout << s.mid(3, 4); // s = "3456"
|
||||
//! piCout << s.mid(7, 1); // s = "7"
|
||||
//! piCout << s.mid(7, 4); // s = "789"
|
||||
//! piCout << s.mid(-1); // s = ""
|
||||
//! \endcode
|
||||
//! \~\sa \a left(), \a right()
|
||||
PIString PIString::mid(int start, int len) const {
|
||||
if (len == 0 || start >= length()) return PIString();
|
||||
if (start < 0) {
|
||||
return PIString();
|
||||
}
|
||||
if (len < 0) {
|
||||
return PIString(d.data(start), size_s() - start);
|
||||
} else {
|
||||
if (len > length() - start) len = length() - start;
|
||||
return PIString(d.data(start), len);
|
||||
}
|
||||
return PIString();
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! If "len" < 0 then remove substring from symbol "start" to end.
|
||||
//! "start" should be >= 0.
|
||||
//! \~russian
|
||||
//! Если "len" < 0 тогда удаляется подстрока от символа "start" и до конца.
|
||||
//! "start" должен быть >= 0.
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! s.cutMid(1, 3);
|
||||
//! piCout << s; // s = "0456789"
|
||||
//! s.cutMid(0, 2);
|
||||
//! piCout << s; // s = "56789"
|
||||
//! s.cutMid(3, -1);
|
||||
//! piCout << s; // s = "567"
|
||||
//! s.cutMid(-1, -1);
|
||||
//! piCout << s; // s = "567"
|
||||
//! \endcode
|
||||
//! \~\sa \a cutLeft(), \a cutRight()
|
||||
PIString & PIString::cutMid(int start, int len) {
|
||||
if (len == 0) return *this;
|
||||
if (start < 0) {
|
||||
return *this;
|
||||
}
|
||||
if (len < 0) {
|
||||
d.remove(start, size() - start);
|
||||
} else {
|
||||
if (len > length() - start) len = length() - start;
|
||||
d.remove(start, len);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english Remove spaces, tabulations, line feeds and null symbols:
|
||||
//! \~russian Удаляет пробелы, табуляцию, переводы строк и нулевые символы:
|
||||
//! \~ ' ', '\\n', '\\r', '\\t', '\\0'
|
||||
//! \~\code
|
||||
//! PIString s(" \t string \n");
|
||||
//! s.trim();
|
||||
//! piCout << s; // s = "string"
|
||||
//! \endcode
|
||||
//! \~\sa \a trimmed()
|
||||
PIString & PIString::trim() {
|
||||
int st = -1, fn = 0;
|
||||
trimsubstr(st, fn);
|
||||
if (st < 0) {
|
||||
clear();
|
||||
return *this;
|
||||
}
|
||||
if (fn < size_s() - 1) cutRight(size_s() - fn - 1);
|
||||
if (st > 0) cutLeft(st);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::trimmed() const {
|
||||
int st = -1, fn = 0;
|
||||
trimsubstr(st, fn);
|
||||
if (st < 0) return PIString();
|
||||
return mid(st, fn - st + 1);
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! s.replace(2, 3, "_cut_");
|
||||
//! piCout << s; // s = "01_cut_56789"
|
||||
//! s.replace(0, 1, "one_");
|
||||
//! piCout << s; // s = "one_1_cut_56789"
|
||||
//! \endcode
|
||||
//! \~\sa \a replaced(), \a replaceAll()
|
||||
PIString & PIString::replace(int from, int count, const PIString & with) {
|
||||
count = piMini(count, length() - from);
|
||||
if (count == with.size_s()) {
|
||||
memcpy(d.data(from), with.d.data(), count * sizeof(PIChar));
|
||||
} else {
|
||||
d.remove(from, count);
|
||||
d.insert(from, with.d);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english If "ok" is not null, it set to "true" if something was replaced
|
||||
//! \~russian Если "ok" не null, то устанавливает в "true" если замена произведена
|
||||
//! \~\code
|
||||
//! PIString s("pip string");
|
||||
//! bool ok;
|
||||
//! s.replace("string", "conf", &ok);
|
||||
//! piCout << s << ok; // s = "pip conf", true
|
||||
//! s.replace("PIP", "PlInPr", &ok);
|
||||
//! piCout << s << ok; // s = "pip conf", false
|
||||
//! \endcode
|
||||
//! \~\sa \a replaced(), \a replaceAll()
|
||||
PIString & PIString::replace(const PIString & what, const PIString & with, bool * ok) {
|
||||
if (what.isEmpty()) {
|
||||
if (ok != 0) *ok = false;
|
||||
return *this;
|
||||
}
|
||||
int s = find(what);
|
||||
if (s >= 0) replace(s, what.length(), with);
|
||||
if (ok != 0) *ok = (s >= 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("substrings");
|
||||
//! s.replaceAll("s", "_");
|
||||
//! piCout << s; // s = "_ub_tring_"
|
||||
//! \endcode
|
||||
//! \~\sa \a replace(), \a replaced(), \a replacedAll()
|
||||
PIString & PIString::replaceAll(const PIString & what, const PIString & with) {
|
||||
if (what.isEmpty() || what == with) return *this;
|
||||
if (with.isEmpty()) {
|
||||
removeAll(what);
|
||||
} else {
|
||||
int l = what.length(), dl = with.length() - what.length();
|
||||
for (int i = 0; i < length() - l + 1; ++i) {
|
||||
bool match = true;
|
||||
for (int j = 0; j < l; ++j) {
|
||||
if (at(j + i) != what[j]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match) continue;
|
||||
if (dl > 0) d.insert(i, PIDeque<PIChar>((size_t)dl));
|
||||
if (dl < 0) d.remove(i, -dl);
|
||||
memcpy(d.data(i), with.d.data(), with.size() * sizeof(PIChar));
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("substrings");
|
||||
//! s.replaceAll("s", '_');
|
||||
//! piCout << s; // s = "_ub_tring_"
|
||||
//! \endcode
|
||||
//! \~\sa \a replace(), \a replaced(), \a replacedAll()
|
||||
PIString & PIString::replaceAll(const PIString & what, const char with) {
|
||||
if (what.isEmpty()) return *this;
|
||||
int l = what.length(), dl = what.length() - 1;
|
||||
for (int i = 0; i < length() - l + 1; ++i) {
|
||||
bool match = true;
|
||||
for (int j = 0; j < l; ++j) {
|
||||
if (at(j + i) != what[j]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match) continue;
|
||||
if (dl > 0) d.remove(i, dl);
|
||||
d[i] = PIChar(with);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("substrings");
|
||||
//! s.replaceAll('s', '_');
|
||||
//! piCout << s; // s = "_ub_tring_"
|
||||
//! \endcode
|
||||
//! \~\sa \a replace(), \a replaced(), \a replacedAll()
|
||||
PIString & PIString::replaceAll(const char what, const char with) {
|
||||
int l = length();
|
||||
for (int i = 0; i < l; ++i) {
|
||||
if (at(i) == what) d[i] = with;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::removeAll(const PIString & str) {
|
||||
if (str.isEmpty()) return *this;
|
||||
int l = str.length();
|
||||
for (int i = 0; i < length() - l + 1; ++i) {
|
||||
bool match = true;
|
||||
for (int j = 0; j < l; ++j) {
|
||||
if (d.at(j + i) != str.at(j)) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match) continue;
|
||||
d.remove(i, l);
|
||||
i -= l;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::insert(int index, const PIString & str) {
|
||||
d.insert(index, str.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::elide(int size, float pos) {
|
||||
static const PIString s_dotdot = PIStringAscii("..");
|
||||
if (length() <= size) return *this;
|
||||
if (length() <= 2) {
|
||||
fill('.');
|
||||
return *this;
|
||||
}
|
||||
pos = piClampf(pos, 0.f, 1.f);
|
||||
int ns = size - 2;
|
||||
int ls = piRoundf(ns * pos);
|
||||
d.remove(ls, length() - ns);
|
||||
d.insert(ls, s_dotdot.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIStringList PIString::split(const PIString & delim) const {
|
||||
PIStringList sl;
|
||||
if (isEmpty() || delim.isEmpty()) return sl;
|
||||
PIString ts(*this);
|
||||
int ci = ts.find(delim);
|
||||
while (ci >= 0) {
|
||||
sl << ts.left(ci);
|
||||
ts.cutLeft(ci + delim.length());
|
||||
ci = ts.find(delim);
|
||||
}
|
||||
if (ts.length() > 0) sl << ts;
|
||||
return sl;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("012345012345");
|
||||
//! piCout << s.find('-'); // -1
|
||||
//! piCout << s.find('3'); // 3
|
||||
//! piCout << s.find('3', 4); // 9
|
||||
//! piCout << s.find('3', 10); // -1
|
||||
//! \endcode
|
||||
//! \~\sa \a findAny(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
|
||||
int PIString::find(const char c, const int start) const {
|
||||
for (int i = start; i < length(); ++i) {
|
||||
if (at(i) == c) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("012345012345");
|
||||
//! piCout << s.find("-"); // -1
|
||||
//! piCout << s.find("34"); // 3
|
||||
//! piCout << s.find("3", 4); // 9
|
||||
//! piCout << s.find("3", 10); // -1
|
||||
//! \endcode
|
||||
//! \~\sa \a findAny(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
|
||||
int PIString::find(const PIString & str, const int start) const {
|
||||
int l = str.length();
|
||||
for (int i = start; i < length() - l + 1; ++i) {
|
||||
if (mid(i, l) == str) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString("1.str").findAny(".,:"); // 1
|
||||
//! piCout << PIString("1,str").findAny(".,:"); // 1
|
||||
//! piCout << PIString("1:str").findAny(".,:"); // 1
|
||||
//! \endcode
|
||||
//! \~\sa \a find(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
|
||||
int PIString::findAny(const PIString & str, const int start) const {
|
||||
for (int i = start; i < length(); ++i) {
|
||||
if (str.contains(at(i))) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("012345012345");
|
||||
//! piCout << s.findLast('-'); // -1
|
||||
//! piCout << s.findLast('3'); // 9
|
||||
//! piCout << s.findLast('3', 4); // 9
|
||||
//! piCout << s.findLast('3', 10); // -1
|
||||
//! \endcode
|
||||
//! \~\sa \a find(), \a findAny(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
|
||||
int PIString::findLast(const char c, const int start) const {
|
||||
for (int i = length() - 1; i >= start; --i) {
|
||||
if (at(i) == c) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int PIString::findLast(PIChar c, const int start) const
|
||||
{
|
||||
for (int i = length() - 1; i >= start; --i) {
|
||||
if (at(i) == c) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("012345012345");
|
||||
//! piCout << s.findLast("-"); // -1
|
||||
//! piCout << s.findLast("34"); // 9
|
||||
//! piCout << s.findLast("3", 4); // 9
|
||||
//! piCout << s.findLast("3", 10); // -1
|
||||
//! \endcode
|
||||
//! \~\sa \a find(), \a findAny(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
|
||||
int PIString::findLast(const PIString & str, const int start) const {
|
||||
int l = str.length();
|
||||
for (int i = length() - l; i >= start; --i) {
|
||||
if (mid(i, l) == str) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString(".str.0").findAnyLast(".,:"); // 4
|
||||
//! piCout << PIString(".str,0").findAnyLast(".,:"); // 4
|
||||
//! piCout << PIString(".str:0").findAnyLast(".,:"); // 4
|
||||
//! \endcode
|
||||
//! \~\sa \a find(), \a findAny(), \a findLast(), \a findWord(), \a findCWord(), \a findRange()
|
||||
int PIString::findAnyLast(const PIString & str, const int start) const {
|
||||
for (int i = length() - 1; i >= start; --i) {
|
||||
if (str.contains(at(i))) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("this is <PIP>");
|
||||
//! piCout << s.findWord("this"); // 0
|
||||
//! piCout << s.findWord("is"); // 5
|
||||
//! piCout << s.findWord("PIP", 4); // -1
|
||||
//! piCout << s.findWord("<PIP>", 4); // 8
|
||||
//! \endcode
|
||||
//! \~\sa \a find(), \a findAny(), \a findLast(), \a findAnyLast(), \a findCWord(), \a findRange()
|
||||
int PIString::findWord(const PIString & word, const int start) const {
|
||||
int f = start - 1, tl = length(), wl = word.length();
|
||||
while ((f = find(word, f + 1)) >= 0) {
|
||||
bool ok = true;
|
||||
PIChar c;
|
||||
if (f > 0) {
|
||||
c = at(f - 1);
|
||||
if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) {
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (f + wl < tl) {
|
||||
c = at(f + wl);
|
||||
if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) {
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (ok) return f;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("this::is <PIP>");
|
||||
//! piCout << s.findCWord("this"); // 0
|
||||
//! piCout << s.findCWord("is"); // 6
|
||||
//! piCout << s.findCWord("PIP", 4); // 10
|
||||
//! piCout << s.findCWord("<PIP>", 4); // 9
|
||||
//! \endcode
|
||||
//! \~\sa \a find(), \a findAny(), \a findLast(), \a findAnyLast(), \a findWord(), \a findRange()
|
||||
int PIString::findCWord(const PIString & word, const int start) const {
|
||||
int f = start - 1, tl = length(), wl = word.length();
|
||||
while ((f = find(word, f + 1)) >= 0) {
|
||||
bool ok = true;
|
||||
PIChar c;
|
||||
if (f > 0) {
|
||||
c = at(f - 1);
|
||||
if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r' || (c != '_' && !c.isAlpha() && !c.isDigit()))) {
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (f + wl < tl) {
|
||||
c = at(f + wl);
|
||||
if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r' || (c != '_' && !c.isAlpha() && !c.isDigit()))) {
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (ok) return f;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s(" {figures{inside}}");
|
||||
//! int len = -1;
|
||||
//! piCout << s.findRange('{', '}', '\\', 0, &len) << len << s.mid(2, len); // 2 15 figures{inside}
|
||||
//! s = "\"text\\\"shielded\" next";
|
||||
//! piCout << s.findRange('"', '"', '\\', 0, &len) << len << s.mid(1, len); // 1 14 text\"shielded
|
||||
//! \endcode
|
||||
//! \~\sa \a find(), \a findAny(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord()
|
||||
int PIString::findRange(const PIChar start, const PIChar end, const PIChar shield, const int start_index, int * len) const {
|
||||
if (len) *len = 0;
|
||||
bool trim_ = (start != ' ' && start != '\t' && start != '\n' && start != '\r'), eq = (start == end);
|
||||
int sz = size_s(), ls = -1, le = -1, cnt = 0;
|
||||
for (int i = start_index; i < sz; ++i) {
|
||||
PIChar c = at(i);
|
||||
if (c == shield) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (trim_) {
|
||||
if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
|
||||
continue;
|
||||
trim_ = false;
|
||||
}
|
||||
if (eq) {
|
||||
if (c == start) {
|
||||
if (cnt == 0) ls = i;
|
||||
else {le = i; cnt = 0; break;}
|
||||
cnt++;
|
||||
}
|
||||
} else {
|
||||
if (c == start) {
|
||||
if (cnt == 0) ls = i;
|
||||
cnt++;
|
||||
}
|
||||
if (c == end) {
|
||||
cnt--;
|
||||
if (cnt == 0) le = i;
|
||||
}
|
||||
}
|
||||
if (cnt <= 0) break;
|
||||
}
|
||||
//piCout << ls << le << cnt;
|
||||
if (le < ls || ls < 0 || le < 0 || cnt != 0) return -1;
|
||||
if (len) *len = le - ls - 1;
|
||||
return ls + 1;
|
||||
}
|
||||
|
||||
|
||||
int PIString::entries(const PIChar c) const {
|
||||
int sz = size_s(), ret = 0;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
if (at(i) == c) ++ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool PIString::startsWith(const PIString & str) const {
|
||||
if (size() < str.size()) return false;
|
||||
return str == left(str.size());
|
||||
}
|
||||
|
||||
|
||||
bool PIString::endsWith(const PIString & str) const {
|
||||
if (size() < str.size()) return false;
|
||||
return str == right(str.size());
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString("true").toBool(); // true
|
||||
//! piCout << PIString("Yes").toBool(); // true
|
||||
//! piCout << PIString(" TRUE ").toBool(); // true
|
||||
//! piCout << PIString(" 1 ").toBool(); // true
|
||||
//! piCout << PIString("0").toBool(); // false
|
||||
//! piCout << PIString("0.1").toBool(); // true
|
||||
//! piCout << PIString("-1").toBool(); // false
|
||||
//! piCout << PIString("").toBool(); // false
|
||||
//! \endcode
|
||||
bool PIString::toBool() const {
|
||||
static const PIString s_true = PIStringAscii("true");
|
||||
static const PIString s_yes = PIStringAscii("yes" );
|
||||
static const PIString s_on = PIStringAscii("on" );
|
||||
static const PIString s_ok = PIStringAscii("ok" );
|
||||
PIString s(*this);
|
||||
s = s.trimmed().toLowerCase();
|
||||
if (s == s_true || s == s_yes || s == s_on || s == s_ok) return true;
|
||||
if (toDouble() > 0.) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("\t ! word");
|
||||
//! piCout << s.takeSymbol(); // "!"
|
||||
//! piCout << s.takeSymbol(); // "w"
|
||||
//! piCout << s.takeSymbol(); // "o"
|
||||
//! piCout << s; // "rd"
|
||||
//! \endcode
|
||||
//! \~\sa \a takeWord(), \a takeCWord(), \a takeLine(), \a takeNumber(), \a takeRange()
|
||||
PIString PIString::takeSymbol() {
|
||||
PIString ret;
|
||||
int sz = size_s(), ss = -1;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
PIChar c = at(i);
|
||||
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue;
|
||||
ss = i;
|
||||
break;
|
||||
}
|
||||
if (ss < 0) return ret;
|
||||
ret = mid(ss, 1);
|
||||
cutLeft(ss + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("some words\nnew line ");
|
||||
//! piCout << s.takeWord(); // "some"
|
||||
//! piCout << s.takeWord(); // "words"
|
||||
//! piCout << s.takeWord(); // "new"
|
||||
//! piCout << s; // " line "
|
||||
//! \endcode
|
||||
//! \~\sa \a takeSymbol(), \a takeCWord(), \a takeLine(), \a takeNumber(), \a takeRange()
|
||||
PIString PIString::takeWord() {
|
||||
int sz = size_s(), ws = -1, we = -1;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
PIChar c = at(i);
|
||||
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
|
||||
if (we < 0 && ws >= 0) {
|
||||
we = i;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (ws < 0) ws = i;
|
||||
if (we >= 0) break;
|
||||
}
|
||||
}
|
||||
PIString ret = mid(ws, we - ws);
|
||||
cutLeft(we < 0 ? sz : we);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! \endcode
|
||||
//! \~\sa \a takeSymbol(), \a takeWord(), \a takeLine(), \a takeNumber(), \a takeRange()
|
||||
PIString PIString::takeCWord() {
|
||||
PIString ret;
|
||||
int sz = size_s(), ws = -1, we = -1;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
PIChar c = at(i);
|
||||
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
|
||||
if (we < 0 && ws >= 0) {
|
||||
we = i;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (ws < 0) {
|
||||
if (c.isAlpha() || c == '_') {
|
||||
ws = i;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
if (!c.isAlpha() && !c.isDigit() && c != '_') {
|
||||
we = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (we >= 0) break;
|
||||
}
|
||||
}
|
||||
ret = mid(ws, we - ws);
|
||||
cutLeft(we < 0 ? sz : we);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("some words\nnew line \n\nend");
|
||||
//! piCout << s.takeLine(); // "some words"
|
||||
//! piCout << s.takeLine(); // "new line "
|
||||
//! piCout << s.takeLine(); // ""
|
||||
//! piCout << s; // "end"
|
||||
//! \endcode
|
||||
//! \~\sa \a takeSymbol(), \a takeWord(), \a takeCWord(), \a takeNumber(), \a takeRange()
|
||||
PIString PIString::takeLine() {
|
||||
int sz = size_s(), le = -1;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
PIChar c = at(i);
|
||||
if (c == '\n') {
|
||||
le = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PIString ret = left(le);
|
||||
if (!ret.isEmpty()) {
|
||||
if (ret.back() == '\r') {
|
||||
ret.cutRight(1);
|
||||
}
|
||||
}
|
||||
cutLeft(le < 0 ? sz : le + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s(" 0xFF -99 1.2E+5f 1000L");
|
||||
//! piCout << s.takeNumber(); // "0xFF"
|
||||
//! piCout << s.takeNumber(); // "-99"
|
||||
//! piCout << s.takeNumber(); // "1.2E+5f"
|
||||
//! piCout << s.takeNumber(); // "1000L"
|
||||
//! piCout << s; // ""
|
||||
//! \endcode
|
||||
//! \~\sa \a takeSymbol(), \a takeWord(), \a takeCWord(), \a takeLine(), \a takeRange()
|
||||
PIString PIString::takeNumber() {
|
||||
PIString ret;
|
||||
int sz = size_s(), ls = -1, le = -1, phase = 0;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
if (phase > 7) break;
|
||||
PIChar c = at(i);
|
||||
//piCout << "char " << c << "phase" << phase;
|
||||
switch (phase) {
|
||||
case 0: // trim
|
||||
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
|
||||
continue;
|
||||
}
|
||||
phase = 7;
|
||||
case 7: // sign
|
||||
if (c == '-' || c == '+') {
|
||||
ls = i;
|
||||
phase = 1;
|
||||
break;
|
||||
}
|
||||
case 1: // search start
|
||||
if ((c >= '0' && c <= '9') || c == '.') {
|
||||
le = i;
|
||||
if (ls < 0) ls = i;
|
||||
if (c == '.') phase = 3;
|
||||
else phase = 2;
|
||||
break;
|
||||
}
|
||||
phase = 9;
|
||||
break;
|
||||
case 2: // integer
|
||||
if (c == '.') {
|
||||
le = i;
|
||||
phase = 3;
|
||||
break;
|
||||
}
|
||||
if (c == 'e' || c == 'E') {
|
||||
le = i;
|
||||
phase = 4;
|
||||
break;
|
||||
}
|
||||
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || c == 'x') {
|
||||
le = i;
|
||||
break;
|
||||
}
|
||||
phase = 6;
|
||||
break;
|
||||
case 3: // point
|
||||
if (c == 'e' || c == 'E') {
|
||||
le = i;
|
||||
phase = 4;
|
||||
break;
|
||||
}
|
||||
if (c >= '0' && c <= '9') {
|
||||
le = i;
|
||||
break;
|
||||
}
|
||||
phase = 6;
|
||||
break;
|
||||
case 4: // exp
|
||||
if ((c >= '0' && c <= '9') || c == '-' || c == '+') {
|
||||
le = i;
|
||||
phase = 5;
|
||||
break;
|
||||
}
|
||||
phase = 6;
|
||||
break;
|
||||
case 5: // power
|
||||
if (c >= '0' && c <= '9') {
|
||||
le = i;
|
||||
break;
|
||||
}
|
||||
phase = 6;
|
||||
break;
|
||||
case 6: // suffix
|
||||
if (c == 'f' || c == 's' || c == 'u' || c == 'l' || c == 'L') {
|
||||
le = i;
|
||||
break;
|
||||
}
|
||||
phase = 9;
|
||||
break;
|
||||
}
|
||||
if (phase == 6) {
|
||||
if (c == 'f' || c == 's' || c == 'u' || c == 'l' || c == 'L') le = i;
|
||||
else phase = 9;
|
||||
}
|
||||
}
|
||||
//piCout << ls << le;
|
||||
if (le < ls) return ret;
|
||||
ret = mid(ls, le - ls + 1);
|
||||
cutLeft(le + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english "shield" symbol prevent analysis of the next symbol
|
||||
//! \~russian Символ "shield" экранирует следующий символ
|
||||
//! \~\code
|
||||
//! PIString s(" {figures{inside}}");
|
||||
//! piCout << s.takeRange('{', '}'); // "figures{inside}"
|
||||
//! piCout << s; // ""
|
||||
//! s = "\"text\\\"shielded\" next";
|
||||
//! piCout << s.takeRange('"', '"'); // "text\"shielded"
|
||||
//! piCout << s; // " next"
|
||||
//! \endcode
|
||||
//! \~\sa \a takeSymbol(), \a takeWord(), \a takeLine(), \a takeNumber()
|
||||
PIString PIString::takeRange(const PIChar start, const PIChar end, const PIChar shield) {
|
||||
PIString ret;
|
||||
bool trim_ = (start != ' ' && start != '\t' && start != '\n' && start != '\r'), eq = (start == end);
|
||||
int sz = size_s(), ls = -1, le = -1, cnt = 0;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
PIChar c = at(i);
|
||||
if (c == shield) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (trim_) {
|
||||
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
|
||||
continue;
|
||||
}
|
||||
trim_ = false;
|
||||
}
|
||||
if (eq) {
|
||||
if (c == start) {
|
||||
if (cnt == 0) {
|
||||
ls = i;
|
||||
} else {
|
||||
le = i;
|
||||
cnt = 0;
|
||||
break;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
} else {
|
||||
if (c == start) {
|
||||
if (cnt == 0) ls = i;
|
||||
cnt++;
|
||||
}
|
||||
if (c == end) {
|
||||
cnt--;
|
||||
if (cnt == 0) le = i;
|
||||
}
|
||||
}
|
||||
if (cnt <= 0) break;
|
||||
}
|
||||
//piCout << ls << le << cnt;
|
||||
if (le < ls || ls < 0 || le < 0 || cnt != 0) return ret;
|
||||
ret = mid(ls + 1, le - ls - 1);
|
||||
cutLeft(le + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("a(b(c)d)e");
|
||||
//! piCout << s.inBrackets('(', ')'); // "b(c)d"
|
||||
//! piCout << s; // s = "a(b(c)d)e"
|
||||
//! \endcode
|
||||
PIString PIString::inBrackets(const PIChar start, const PIChar end) const {
|
||||
int slen = length();
|
||||
int st = -1, bcnt = 0;
|
||||
PIChar cc;
|
||||
for (int i = 0; i < slen; i++) {
|
||||
cc = at(i);
|
||||
if (cc == start) {
|
||||
if (bcnt == 0) st = i;
|
||||
bcnt++;
|
||||
}
|
||||
if (cc == end && st >= 0) {
|
||||
bcnt--;
|
||||
if (bcnt == 0) return mid(st+1, i-st-1);
|
||||
}
|
||||
}
|
||||
return PIString();
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This function fill internal buffer by sequence of chars.
|
||||
//! Length of this buffer is count of symbols + end byte '\0'.
|
||||
//! Returned pointer is valid until next execution of this function.
|
||||
//! \~russian
|
||||
//! Этот метод заполняет внутренный байтовый буфер. Размер
|
||||
//! этого буфера равен количеству символов строки + завершающий байт '\0'.
|
||||
//! Возвращаемый указатель действителен до следующего вызова этого метода.
|
||||
//! \~\code
|
||||
//! piCout << PIString("0123456789").data(); // 0123456789
|
||||
//! piCout << PIString("№1").data(); // №1
|
||||
//! \endcode
|
||||
//! \~\sa \a dataConsole(), \a dataUTF8()
|
||||
const char * PIString::data() const {
|
||||
if (isEmpty()) return "";
|
||||
buildData(__syslocname__);
|
||||
return data_;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This function fill internal buffer by sequence of chars.
|
||||
//! Length of this buffer is count of symbols + end byte '\0'.
|
||||
//! Returned pointer is valid until next execution of this function.
|
||||
//! \~russian
|
||||
//! Этот метод заполняет внутренный байтовый буфер. Размер
|
||||
//! этого буфера равен количеству символов строки + завершающий байт '\0'.
|
||||
//! Возвращаемый указатель действителен до следующего вызова этого метода.
|
||||
//! \~\sa \a data(), \a dataUTF8()
|
||||
const char * PIString::dataConsole() const {
|
||||
if (isEmpty()) return "";
|
||||
buildData(__sysoemname__ );
|
||||
return data_;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This function fill internal buffer by sequence of chars.
|
||||
//! Length of this buffer is count of symbols + end byte '\0'.
|
||||
//! Returned pointer is valid until next execution of this function.
|
||||
//! \~russian
|
||||
//! Этот метод заполняет внутренный байтовый буфер. Размер
|
||||
//! этого буфера равен количеству символов строки + завершающий байт '\0'.
|
||||
//! Возвращаемый указатель действителен до следующего вызова этого метода.
|
||||
//! \~\sa \a data(), \a dataConsole()
|
||||
const char * PIString::dataUTF8() const {
|
||||
if (isEmpty()) return "";
|
||||
buildData(__utf8name__);
|
||||
return data_;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This function fill internal buffer by sequence of chars.
|
||||
//! Length of this buffer is count of symbols + end byte '\0'.
|
||||
//! Returned pointer is valid until next execution of this function.
|
||||
//! \~russian
|
||||
//! Этот метод заполняет внутренный байтовый буфер. Размер
|
||||
//! этого буфера равен количеству символов строки + завершающий байт '\0'.
|
||||
//! Возвращаемый указатель действителен до следующего вызова этого метода.
|
||||
//! \~\sa \a dataConsole(), \a dataUTF8()
|
||||
const char * PIString::dataAscii() const {
|
||||
if (isEmpty()) return "";
|
||||
deleteData();
|
||||
data_ = (char*)malloc(size()+1);
|
||||
for (int i = 0; i < size_s(); ++i) {
|
||||
data_[i] = uchar(at(i).ch);
|
||||
}
|
||||
data_[size()] = '\0';
|
||||
return data_;
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::toUpperCase() const {
|
||||
PIString str(*this);
|
||||
int l = str.size();
|
||||
for (int i = 0; i < l; ++i) {
|
||||
str.d[i] = str.d[i].toUpper();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::toLowerCase() const {
|
||||
PIString str(*this);
|
||||
int l = str.size();
|
||||
for (int i = 0; i < l; ++i) {
|
||||
str.d[i] = str.d[i].toLower();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
char PIString::toChar() const {
|
||||
char v;
|
||||
sscanf(dataAscii(), "%c", &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
float PIString::toFloat() const {
|
||||
return toDecimal<float>(*this);
|
||||
}
|
||||
|
||||
|
||||
double PIString::toDouble() const {
|
||||
return toDecimal<double>(*this);
|
||||
}
|
||||
|
||||
|
||||
ldouble PIString::toLDouble() const {
|
||||
return toDecimal<ldouble>(*this);
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Example:
|
||||
//! \~russian
|
||||
//! Пример:
|
||||
//! \~\code
|
||||
//! PIString s;
|
||||
//! s.setReadableSize(512);
|
||||
//! piCout << s; // 512 B
|
||||
//! s.setReadableSize(5120);
|
||||
//! piCout << s; // 5.0 kB
|
||||
//! s.setReadableSize(512000);
|
||||
//! piCout << s; // 500.0 kB
|
||||
//! s.setReadableSize(5120000);
|
||||
//! piCout << s; // 4.8 MB
|
||||
//! s.setReadableSize(512000000);
|
||||
//! piCout << s; // 488.2 MB
|
||||
//! s.setReadableSize(51200000000);
|
||||
//! piCout << s; // 47.6 GB
|
||||
//! \endcode
|
||||
PIString & PIString::setReadableSize(llong bytes) {
|
||||
clear();
|
||||
if (bytes < 1024) {
|
||||
*this += (PIString::fromNumber(bytes) + PIStringAscii(" B"));
|
||||
return *this;
|
||||
}
|
||||
double fres = bytes / 1024.;
|
||||
llong res = bytes / 1024;
|
||||
fres -= res;
|
||||
if (res < 1024) {
|
||||
*this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" kB"));
|
||||
return *this;
|
||||
}
|
||||
fres = res / 1024.;
|
||||
res /= 1024;
|
||||
fres -= res;
|
||||
if (res < 1024) {
|
||||
*this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" MB"));
|
||||
return *this;
|
||||
}
|
||||
fres = res / 1024.;
|
||||
res /= 1024;
|
||||
fres -= res;
|
||||
if (res < 1024) {
|
||||
*this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" GB"));
|
||||
return *this;
|
||||
}
|
||||
fres = res / 1024.;
|
||||
res /= 1024;
|
||||
fres -= res;
|
||||
if (res < 1024) {
|
||||
*this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" TB"));
|
||||
return *this;
|
||||
}
|
||||
fres = res / 1024.;
|
||||
res /= 1024;
|
||||
fres -= res;
|
||||
*this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" PB"));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
const static PIString _versionDelims_ = PIStringAscii("._-+");
|
||||
|
||||
|
||||
void parseVersion(PIString s, PIVector<int> & codes, PIStringList & strs) {
|
||||
s.trim();
|
||||
if (s.isEmpty()) {
|
||||
codes.resize(3, 0);
|
||||
return;
|
||||
}
|
||||
int mccnt = 2 - s.entries('.');
|
||||
if (mccnt > 0) {
|
||||
int ind = s.findLast('.') + 1;
|
||||
while (!_versionDelims_.contains(s[ind])) {
|
||||
++ind;
|
||||
if (ind > s.size_s() - 1) break;
|
||||
}
|
||||
for (int i = 0; i < mccnt; ++i) {
|
||||
s.insert(ind, PIStringAscii(".0"));
|
||||
}
|
||||
}
|
||||
PIStringList comps;
|
||||
while (!s.isEmpty()) {
|
||||
int ind = s.findAny(_versionDelims_);
|
||||
if (ind >= 0) {
|
||||
comps << s.takeLeft(ind);
|
||||
s.cutLeft(1).trim();
|
||||
} else {
|
||||
comps << s;
|
||||
s.clear();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < comps.size_s(); ++i) {
|
||||
if (comps[i].isEmpty()) comps[i] = '0';
|
||||
bool ok = false;
|
||||
int val = comps[i].toInt(-1, &ok);
|
||||
if (ok) {
|
||||
codes << val;
|
||||
} else {
|
||||
strs << comps[i];
|
||||
}
|
||||
}
|
||||
//piCout << codes << strs;
|
||||
}
|
||||
|
||||
|
||||
int versionLabelValue(PIString s) {
|
||||
int ret = -10000;
|
||||
if (s.isEmpty()) return 0;
|
||||
if (s.startsWith(PIStringAscii("pre"))) {
|
||||
s.cutLeft(3);
|
||||
ret -= 1;
|
||||
}
|
||||
if (s.startsWith(PIStringAscii("rc"))) {
|
||||
s.cutLeft(2);
|
||||
ret += s.toInt();
|
||||
}
|
||||
if (s.startsWith(PIStringAscii("r"))) {
|
||||
s.cutLeft(1);
|
||||
ret += 10000 + s.toInt();
|
||||
}
|
||||
if (s == PIStringAscii("alpha")) ret -= 4;
|
||||
if (s == PIStringAscii("beta" )) ret -= 2;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PIString
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This function parse version to number codes and labels. Then it
|
||||
//! compare no more than "components" codes. If there is no difference, compare
|
||||
//! labels. Each label has corresponding integer value, so
|
||||
//! "prealpha" < "alpha" < "prebeta" < "beta" < "rc[N]" < "" < "r[N]".
|
||||
//! Example:
|
||||
//! \~russian
|
||||
//! Этот метод разбирает версии на числовые части и метку. Затем сравнивает
|
||||
//! не более чем "components" частей. Если различий нет, то сравниваются
|
||||
//! метки. Каждой метке соответствует своё значение так, что
|
||||
//! "prealpha" < "alpha" < "prebeta" < "beta" < "rc[N]" < "" < "r[N]".
|
||||
//! Пример:
|
||||
//! \~\code
|
||||
//! piCout << versionCompare("1.0.0_rc2-999", "1.0.1_rc2-999"); // -1, <
|
||||
//! piCout << versionCompare("1.0.0", "0.9.2"); // 1, >
|
||||
//! piCout << versionCompare("1.0.0_r1", "1.0.0"); // 1, >
|
||||
//! piCout << versionCompare("1.0.0_r1", "1.0.0", 3); // 0, =
|
||||
//! piCout << versionCompare("1.0.0_r2", "1.0.0", 3); // 0, =
|
||||
//! piCout << versionCompare(".2-alpha", "0.2_alpha"); // 0, =
|
||||
//! piCout << versionCompare("1_prebeta", "1.0_alpha"); // 1, >
|
||||
//! \endcode
|
||||
//! \~\return
|
||||
//! \~english
|
||||
//! * 0 - equal
|
||||
//! * 1 - v0 > v1
|
||||
//! * -1 - v0 < v1
|
||||
//! \~russian
|
||||
//! * 0 - равны
|
||||
//! * 1 - v0 > v1
|
||||
//! * -1 - v0 < v1
|
||||
int versionCompare(const PIString & v0, const PIString & v1, int components) {
|
||||
PIStringList strs[2]; PIVector<int> codes[2];
|
||||
parseVersion(v0.toLowerCase(), codes[0], strs[0]);
|
||||
parseVersion(v1.toLowerCase(), codes[1], strs[1]);
|
||||
//piCout << codes[0] << strs[0];
|
||||
int mc = piMaxi(codes[0].size_s(), codes[1].size_s());
|
||||
if (codes[0].size_s() < mc) codes[0].resize(mc, 0);
|
||||
if (codes[1].size_s() < mc) codes[1].resize(mc, 0);
|
||||
mc = piMaxi(strs[0].size_s(), strs[1].size_s());
|
||||
if (strs[0].size_s() < mc) strs[0].resize(mc, "");
|
||||
if (strs[1].size_s() < mc) strs[1].resize(mc, "");
|
||||
int comps = piMini(components, codes[0].size_s(), codes[1].size_s());
|
||||
if (comps < 1) return (v0 == v1 ? 0 : (v0 > v1 ? 1 : -1));
|
||||
for (int c = 0; c < comps; ++c) {
|
||||
if (codes[0][c] > codes[1][c]) return 1;
|
||||
if (codes[0][c] < codes[1][c]) return -1;
|
||||
}
|
||||
mc = piClampi(mc, 0, components - comps);
|
||||
for (int c = 0; c < mc; ++c) {
|
||||
int lv0 = versionLabelValue(strs[0][c]);
|
||||
int lv1 = versionLabelValue(strs[1][c]);
|
||||
if (lv0 > lv1) return 1;
|
||||
if (lv0 < lv1) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PIString
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Parse version as described in \a versionCompare() and returns
|
||||
//! classic view of codes and labels: major.minor.revision[-build][_label].
|
||||
//! Example:
|
||||
//! \~russian
|
||||
//! Разбирает версию по описанию \a versionCompare() и возвращает
|
||||
//! классическое представление версии и метки: major.minor.revision[-build][_label].
|
||||
//! Пример:
|
||||
//! \~\code
|
||||
//! piCout << versionNormalize(""); // 0.0.0
|
||||
//! piCout << versionNormalize("1"); // 1.0.0
|
||||
//! piCout << versionNormalize("1.2"); // 1.2.0
|
||||
//! piCout << versionNormalize("1.2.3"); // 1.2.3
|
||||
//! piCout << versionNormalize("1.2+rc1.99"); // 1.2.99_rc1
|
||||
//! piCout << versionNormalize("1.2-alpha"); // 1.2.0_alpha
|
||||
//! piCout << versionNormalize("1..4_rc2-999"); // 1.0.4-999_rc2
|
||||
//! \endcode
|
||||
PIString versionNormalize(const PIString & v) {
|
||||
PIStringList strs; PIVector<int> codes;
|
||||
parseVersion(v.toLowerCase(), codes, strs);
|
||||
PIString ret;
|
||||
for (int i = 0; i < codes.size_s(); ++i) {
|
||||
if (i > 0) {
|
||||
if (i < 3) ret += '.';
|
||||
else ret += '-';
|
||||
}
|
||||
ret += PIString::fromNumber(codes[i]);
|
||||
}
|
||||
for (int i = 0; i < strs.size_s(); ++i) {
|
||||
ret += '_';
|
||||
ret += strs[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,1570 +0,0 @@
|
||||
/*! \file pistring.h
|
||||
* \ingroup Core
|
||||
* \brief
|
||||
* \~english String class
|
||||
* \~russian Класс строки
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
String
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PISTRING_H
|
||||
#define PISTRING_H
|
||||
|
||||
#include "pibytearray.h"
|
||||
#include "piconstchars.h"
|
||||
|
||||
#define PIStringAscii PIString::fromAscii
|
||||
|
||||
|
||||
class PIStringList;
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english String class.
|
||||
//! \~russian Класс строки.
|
||||
class PIP_EXPORT PIString
|
||||
{
|
||||
BINARY_STREAM_FRIEND(PIString);
|
||||
public:
|
||||
typedef PIDeque<PIChar>::iterator iterator;
|
||||
typedef PIDeque<PIChar>::const_iterator const_iterator;
|
||||
typedef PIDeque<PIChar>::reverse_iterator reverse_iterator;
|
||||
typedef PIDeque<PIChar>::const_reverse_iterator const_reverse_iterator;
|
||||
typedef PIChar value_type;
|
||||
typedef PIChar* pointer;
|
||||
typedef const PIChar* const_pointer;
|
||||
typedef PIChar& reference;
|
||||
typedef const PIChar& const_reference;
|
||||
typedef size_t size_type;
|
||||
|
||||
//! \~english Contructs an empty string.
|
||||
//! \~russian Создает пустую строку.
|
||||
PIString() {}
|
||||
|
||||
//! \~english Value for elide at left.
|
||||
//! \~russian Значение для пропуска слева.
|
||||
static const float ElideLeft ;
|
||||
|
||||
//! \~english Value for elide at center.
|
||||
//! \~russian Значение для пропуска в середине.
|
||||
static const float ElideCenter;
|
||||
|
||||
//! \~english Value for elide at right.
|
||||
//! \~russian Значение для пропуска справа.
|
||||
static const float ElideRight ;
|
||||
|
||||
PIString & operator +=(const PIChar & c) {d.push_back(c); return *this;}
|
||||
PIString & operator +=(const char c) {d.push_back(PIChar(c)); return *this;}
|
||||
PIString & operator +=(const char * str);
|
||||
PIString & operator +=(const wchar_t * str);
|
||||
PIString & operator +=(const PIByteArray & ba);
|
||||
PIString & operator +=(const PIString & str);
|
||||
PIString & operator +=(const PIConstChars & str);
|
||||
|
||||
PIString(uchar ) = delete;
|
||||
PIString( short) = delete;
|
||||
PIString(ushort) = delete;
|
||||
PIString( int ) = delete;
|
||||
PIString(uint ) = delete;
|
||||
PIString( long ) = delete;
|
||||
PIString(ulong ) = delete;
|
||||
PIString( llong) = delete;
|
||||
PIString(ullong) = delete;
|
||||
|
||||
PIString & operator +=(uchar ) = delete;
|
||||
PIString & operator +=( short) = delete;
|
||||
PIString & operator +=(ushort) = delete;
|
||||
PIString & operator +=( int ) = delete;
|
||||
PIString & operator +=(uint ) = delete;
|
||||
PIString & operator +=( long ) = delete;
|
||||
PIString & operator +=(ulong ) = delete;
|
||||
PIString & operator +=( llong) = delete;
|
||||
PIString & operator +=(ullong) = delete;
|
||||
|
||||
//! \~english Contructs a copy of string.
|
||||
//! \~russian Создает копию строки.
|
||||
PIString(const PIString & o) {d = o.d;}
|
||||
|
||||
//! \~english Move constructor.
|
||||
//! \~russian Перемещающий конструктор.
|
||||
PIString(PIString && o): d(std::move(o.d)) {piSwap(data_, o.data_);}
|
||||
|
||||
//! \~english Contructs string with single character "c".
|
||||
//! \~russian Создает строку из одного символа "c".
|
||||
PIString(const PIChar c) {d.push_back(c);}
|
||||
|
||||
//! \~english Contructs string with single character "c".
|
||||
//! \~russian Создает строку из одного символа "c".
|
||||
PIString(const char c) {d.push_back(PIChar(c));}
|
||||
|
||||
//! \~english Contructs string from C-string "str" (system codepage).
|
||||
//! \~russian Создает строку из C-строки "str" (кодировка системы).
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! "str" should be null-terminated\n
|
||||
//! \~russian
|
||||
//! "str" должна заканчиваться нулевым байтом\n
|
||||
//! \~\code
|
||||
//! PIString s("string");
|
||||
//! \endcode
|
||||
PIString(const char * str) {*this += str;}
|
||||
|
||||
//! \~english Contructs string from \c wchar_t C-string "str".
|
||||
//! \~russian Создает строку из \c wchar_t C-строки "str".
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! "str" should be null-terminated
|
||||
//! \~russian
|
||||
//! "str" должна заканчиваться нулевым \c wchar_t
|
||||
//! \~\code
|
||||
//! PIString s(L"string");
|
||||
//! \endcode
|
||||
PIString(const wchar_t * str) {*this += str;}
|
||||
|
||||
//! \~english Contructs string from byte array "ba" (as UTF-8).
|
||||
//! \~russian Создает строку из байтового массива "ba" (как UTF-8).
|
||||
PIString(const PIByteArray & ba) {*this += ba;}
|
||||
|
||||
//! \~english Contructs string from "len" characters of buffer "str".
|
||||
//! \~russian Создает строку из "len" символов массива "str".
|
||||
PIString(const PIChar * str, const int len): d(str, size_t(len)) {}
|
||||
|
||||
//! \~english Contructs string from "len" characters of buffer "str" (system codepage).
|
||||
//! \~russian Создает строку из "len" символов массива "str" (кодировка системы).
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("string", 3); // s = "str"
|
||||
//! \endcode
|
||||
PIString(const char * str, const int len) {appendFromChars(str, len);}
|
||||
|
||||
//! \~english Contructs string as sequence of characters "c" of buffer with length "len".
|
||||
//! \~russian Создает строку как последовательность длиной "len" символа "c".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s(5, 'p'); // s = "ppppp"
|
||||
//! \endcode
|
||||
PIString(const int len, const char c) {for (int i = 0; i < len; ++i) d.push_back(PIChar(c));}
|
||||
|
||||
//! \~english Contructs string as sequence of characters "c" of buffer with length "len".
|
||||
//! \~russian Создает строку как последовательность длиной "len" символа "c".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s(5, "№"); // s = "№№№№№"
|
||||
//! \endcode
|
||||
PIString(const int len, const PIChar c) {for (int i = 0; i < len; ++i) d.push_back(c);}
|
||||
|
||||
PIString(const PIConstChars & c) {*this += c;}
|
||||
|
||||
~PIString();
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIString & operator =(const PIString & o) {if (this == &o) return *this; d = o.d; return *this;}
|
||||
|
||||
//! \~english Assign move operator.
|
||||
//! \~russian Оператор перемещающего присваивания.
|
||||
PIString & operator =(PIString && o) {d.swap(o.d); piSwap(data_, o.data_); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIString & operator =(const PIConstChars & o) {d.clear(); *this += o; return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIString & operator =(const char * o) {d.clear(); *this += o; return *this;}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator ==(const PIString & str) const;
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator ==(const PIChar c) const {if (d.size() != 1) return false; return d.at(0) == c;}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator ==(const char * str) const {return *this == PIString(str);}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator !=(const PIString & str) const;
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator !=(const PIChar c) const {if (d.size() != 1) return true; return d.at(0) != c;}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator !=(const char * str) const {return *this != PIString(str);}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator <(const PIString & str) const;
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator <(const PIChar c) const {if (d.size() != 1) return d.size() < 1; return d.at(0) < c;}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator <(const char * str) const {return *this < PIString(str);}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator >(const PIString & str) const;
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator >(const PIChar c) const {if (d.size() != 1) return d.size() > 1; return d.at(0) > c;}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator >(const char * str) const {return *this > PIString(str);}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator <=(const PIString & str) const {return !(*this > str);}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator <=(const PIChar c) const {return !(*this > c);}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator <=(const char * str) const {return *this <= PIString(str);}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator >=(const PIString & str) const {return !(*this < str);}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator >=(const PIChar c) const {return !(*this < c);}
|
||||
|
||||
//! \~english Compare operator.
|
||||
//! \~russian Оператор сравнения.
|
||||
bool operator >=(const char * str) const {return *this >= PIString(str);}
|
||||
|
||||
//! \~english Iterator to the first element.
|
||||
//! \~russian Итератор на первый элемент.
|
||||
//! \~\details
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a end(), \a rbegin(), \a rend()
|
||||
inline iterator begin() {return d.begin();}
|
||||
|
||||
//! \~english Iterator to the element following the last element.
|
||||
//! \~russian Итератор на элемент, следующий за последним элементом.
|
||||
//! \~\details
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a begin(), \a rbegin(), \a rend()
|
||||
inline iterator end() {return d.end();}
|
||||
|
||||
inline const_iterator begin() const {return d.begin();}
|
||||
inline const_iterator end() const {return d.end();}
|
||||
|
||||
//! \~english Returns a reverse iterator to the first element of the reversed array.
|
||||
//! \~russian Обратный итератор на первый элемент.
|
||||
//! \~\details
|
||||
//! \~english It corresponds to the last element of the non-reversed array.
|
||||
//! \~russian Итератор для прохода массива в обратном порядке.
|
||||
//! Указывает на последний элемент.
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a rend(), \a begin(), \a end()
|
||||
inline reverse_iterator rbegin() {return d.rbegin();}
|
||||
|
||||
//! \~english Returns a reverse iterator to the element.
|
||||
//! following the last element of the reversed array.
|
||||
//! \~russian Обратный итератор на элемент, следующий за последним элементом.
|
||||
//! \~\details
|
||||
//! \~english It corresponds to the element preceding the first element of the non-reversed array.
|
||||
//! \~russian Итератор для прохода массива в обратном порядке.
|
||||
//! Указывает на элемент, предшествующий первому элементу.
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a rbegin(), \a begin(), \a end()
|
||||
inline reverse_iterator rend() {return d.rend();}
|
||||
|
||||
inline const_reverse_iterator rbegin() const {return d.rbegin();}
|
||||
inline const_reverse_iterator rend() const {return d.rend();}
|
||||
|
||||
//! \~english Full access to character by `index`.
|
||||
//! \~russian Полный доступ к символу по индексу `index`.
|
||||
//! \~\details
|
||||
//! \~english Сharacter index starts from `0`.
|
||||
//! Сharacter index must be in range from `0` to `size()-1`.
|
||||
//! Otherwise will be undefined behavior.
|
||||
//! \~russian Индекс элемента считается от `0`.
|
||||
//! Индекс символа должен лежать в пределах от `0` до `size()-1`.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
inline PIChar & operator [](size_t index) {return d[index];}
|
||||
inline PIChar operator [](size_t index) const {return d[index];}
|
||||
|
||||
//! \~english Read only access to character by `index`.
|
||||
//! \~russian Доступ исключительно на чтение к символу по индексу `index`.
|
||||
//! \~\details
|
||||
//! \~english Сharacter index starts from `0`.
|
||||
//! Сharacter index must be in range from `0` to `size()-1`.
|
||||
//! Otherwise will be undefined behavior.
|
||||
//! \~russian Индекс символа считается от `0`.
|
||||
//! Индекс символа должен лежать в пределах от `0` до `size()-1`.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
inline const PIChar at(size_t index) const {return d.at(index);}
|
||||
|
||||
//! \~english Returns the last character of the string.
|
||||
//! \~russian Возвращает последний символ строки.
|
||||
inline PIChar & back() {return d.back();}
|
||||
inline PIChar back() const {return d.back();}
|
||||
|
||||
inline PIChar & front() {return d.front();}
|
||||
inline PIChar front() const {return d.front();}
|
||||
|
||||
//! \~english Sets size of the string, new characters are copied from `c`.
|
||||
//! \~russian Устанавливает размер строки, новые символы копируются из `c`.
|
||||
//! \~\details
|
||||
//! \~english If `new_size` is greater than the current \a size(),
|
||||
//! characters are added to the end; the new characters are initialized from `c`.
|
||||
//! If `new_size` is less than the current \a size(), characters are removed from the end.
|
||||
//! \~russian Если `new_size` больше чем текущий размер строки \a size(),
|
||||
//! новые символы добавляются в конец строки и создаются из `с`.
|
||||
//! Если `new_size` меньше чем текущий размер строки \a size(),
|
||||
//! лишние символы удаляются с конца строки.
|
||||
//! \~\sa \a size(), \a clear()
|
||||
inline PIString & resize(size_t new_size, PIChar c = PIChar()) {d.resize(new_size, c); return *this;}
|
||||
|
||||
//! \~english Delete one character at the end of string.
|
||||
//! \~russian Удаляет один символ с конца строки.
|
||||
inline PIString & pop_back() {d.pop_back(); return *this;}
|
||||
|
||||
//! \~english Delete one character at the benig of string.
|
||||
//! \~russian Удаляет один символ с начала строки.
|
||||
inline PIString & pop_front() {d.pop_front(); return *this;}
|
||||
|
||||
//! \~english Removes `count` characters from the string, starting at `index` position.
|
||||
//! \~russian Удаляет символы из строки, начиная с позиции `index` в количестве `count`.
|
||||
inline PIString & remove(size_t index, size_t count = 1) {d.remove(index, count); return *this;}
|
||||
|
||||
//! \~english Assigns character 'c' to all string characters.
|
||||
//! \~russian Заполняет всю строку символами `c`.
|
||||
inline PIString & fill(PIChar c = PIChar()) {d.fill(c); return *this;}
|
||||
|
||||
//! \~english Insert string "str" at the begin of string.
|
||||
//! \~russian Вставляет "str" в начало строки.
|
||||
PIString & prepend(const char * str) {insert(0, str); return *this;}
|
||||
|
||||
//! \~english Insert string "str" at the begin of string.
|
||||
//! \~russian Вставляет "str" в начало строки.
|
||||
PIString & prepend(const PIString & str) {d.prepend(str.d); return *this;}
|
||||
|
||||
//! \~english Insert character `c` at the begin of string.
|
||||
//! \~russian Вставляет символ `c` в начало строки.
|
||||
PIString & prepend(const PIChar c) {d.prepend(c); return *this;}
|
||||
|
||||
//! \~english Insert character `c` at the begin of string.
|
||||
//! \~russian Вставляет символ `c` в начало строки.
|
||||
PIString & prepend(const char c) {d.prepend(PIChar(c)); return *this;}
|
||||
|
||||
//! \~english Insert string "str" at the begin of string.
|
||||
//! \~russian Вставляет "str" в начало строки.
|
||||
PIString & push_front(const char * str) {insert(0, str); return *this;}
|
||||
|
||||
//! \~english Insert string "str" at the begin of string.
|
||||
//! \~russian Вставляет "str" в начало строки.
|
||||
PIString & push_front(const PIString & str) {d.push_front(str.d); return *this;}
|
||||
|
||||
//! \~english Insert character `c` at the begin of string.
|
||||
//! \~russian Вставляет символ `c` в начало строки.
|
||||
PIString & push_front(const PIChar c) {d.push_front(c); return *this;}
|
||||
|
||||
//! \~english Insert character `c` at the begin of string.
|
||||
//! \~russian Вставляет символ `c` в начало строки.
|
||||
PIString & push_front(const char c) {d.push_front(PIChar(c)); return *this;}
|
||||
|
||||
//! \~english Insert string "str" at the end of string.
|
||||
//! \~russian Вставляет "str" в конец строки.
|
||||
PIString & append(const char * str) {*this += str; return *this;}
|
||||
|
||||
//! \~english Insert string "str" at the end of string.
|
||||
//! \~russian Вставляет "str" в конец строки.
|
||||
PIString & append(const PIString & str) {d.append(str.d); return *this;}
|
||||
|
||||
PIString & append(const PIConstChars & str) {*this += str; return *this;}
|
||||
|
||||
//! \~english Insert character `c` at the end of string.
|
||||
//! \~russian Вставляет символ `c` в конец строки.
|
||||
PIString & append(const PIChar c) {d.append(c); return *this;}
|
||||
|
||||
//! \~english Insert character `c` at the end of string.
|
||||
//! \~russian Вставляет символ `c` в конец строки.
|
||||
PIString & append(const char c) {d.append(PIChar(c)); return *this;}
|
||||
|
||||
//! \~english Insert string "str" at the end of string.
|
||||
//! \~russian Вставляет "str" в конец строки.
|
||||
PIString & push_back(const char * str) {*this += str; return *this;}
|
||||
|
||||
//! \~english Insert string "str" at the end of string.
|
||||
//! \~russian Вставляет "str" в конец строки.
|
||||
PIString & push_back(const PIString & str) {d.push_back(str.d); return *this;}
|
||||
|
||||
PIString & push_back(const PIConstChars & str) {*this += str; return *this;}
|
||||
|
||||
//! \~english Insert character `c` at the end of string.
|
||||
//! \~russian Вставляет символ `c` в конец строки.
|
||||
PIString & push_back(const PIChar c) {d.push_back(c); return *this;}
|
||||
|
||||
//! \~english Insert character `c` at the end of string.
|
||||
//! \~russian Вставляет символ `c` в конец строки.
|
||||
PIString & push_back(const char c) {d.push_back(PIChar(c)); return *this;}
|
||||
|
||||
|
||||
//! \~english Returns part of string from character at index "start" and maximum length "len".
|
||||
//! \~russian Возвращает подстроку от символа "start" и максимальной длиной "len".
|
||||
PIString mid(int start, int len = -1) const;
|
||||
|
||||
//! \~english Synonym of \a mid().
|
||||
//! \~russian Аналог \a mid().
|
||||
PIString subString(int start, int len = -1) const {return mid(start, len);}
|
||||
|
||||
//! \~english Returns part of string from start and maximum length "len".
|
||||
//! \~russian Возвращает подстроку от начала и максимальной длиной "len".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! piCout << s.left(-1); // s = ""
|
||||
//! piCout << s.left(1); // s = "0"
|
||||
//! piCout << s.left(5); // s = "01234"
|
||||
//! piCout << s.left(15); // s = "0123456789"
|
||||
//! \endcode
|
||||
//! \~\sa \a mid(), \a right()
|
||||
PIString left(int len) const {return len <= 0 ? PIString() : mid(0, len);}
|
||||
|
||||
//! \~english Returns part of string at end and maximum length "len".
|
||||
//! \~russian Возвращает подстроку максимальной длиной "len" и до конца.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! piCout << s.right(-1); // s = ""
|
||||
//! piCout << s.right(1); // s = "9"
|
||||
//! piCout << s.right(5); // s = "56789"
|
||||
//! piCout << s.right(15); // s = "0123456789"
|
||||
//! \endcode
|
||||
//! \~\sa \a mid(), \a left()
|
||||
PIString right(int len) const {return len <= 0 ? PIString() : mid(size() - len, len);}
|
||||
|
||||
//! \~english Remove part of string from character as index "start" and maximum length "len" and return this string.
|
||||
//! \~russian Удаляет часть строки от символа "start" и максимальной длины "len", возвращает эту строку.
|
||||
PIString & cutMid(int start, int len);
|
||||
|
||||
//! \~english Remove part of string from start and maximum length "len" and return this string.
|
||||
//! \~russian Удаляет часть строки от начала и максимальной длины "len", возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! s.cutLeft(1);
|
||||
//! piCout << s; // s = "123456789"
|
||||
//! s.cutLeft(3);
|
||||
//! piCout << s; // s = "456789"
|
||||
//! s.cutLeft(30);
|
||||
//! piCout << s; // s = ""
|
||||
//! \endcode
|
||||
//! \~\sa \a cutMid(), \a cutRight()
|
||||
PIString & cutLeft(int len) {return len <= 0 ? *this : cutMid(0, len);}
|
||||
|
||||
//! \~english Remove part of string at end and maximum length "len" and return this string.
|
||||
//! \~russian Удаляет часть строки максимальной длины "len" от конца, возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! s.cutRight(1);
|
||||
//! piCout << s; // s = "012345678"
|
||||
//! s.cutRight(3);
|
||||
//! piCout << s; // s = "012345"
|
||||
//! s.cutRight(30);
|
||||
//! piCout << s; // s = ""
|
||||
//! \endcode
|
||||
//! \~\sa \a cutMid(), \a cutLeft()
|
||||
PIString & cutRight(int len) {return len <= 0 ? *this : cutMid(size() - len, len);}
|
||||
|
||||
//! \~english Remove spaces at the start and at the end of string and return this string.
|
||||
//! \~russian Удаляет пробельные символы с начала и конца строки и возвращает эту строку.
|
||||
PIString & trim();
|
||||
|
||||
//! \~english Returns copy of this string without spaces at the start and at the end.
|
||||
//! \~russian Возвращает копию этой строки без пробельных символов с начала и конца.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s(" \t string \n");
|
||||
//! piCout << s.trimmed(); // s = "string"
|
||||
//! piCout << s; // s = " string "
|
||||
//! \endcode
|
||||
//! \~\sa \a trim()
|
||||
PIString trimmed() const;
|
||||
|
||||
//! \~english Replace part of string from index "from" and maximum length "len" with string "with" and return this string.
|
||||
//! \~russian Заменяет часть строки от символа "from" и максимальной длины "len" строкой "with", возвращает эту строку.
|
||||
PIString & replace(const int from, const int count, const PIString & with);
|
||||
|
||||
//! \~english Replace part copy of this string from index "from" and maximum length "len" with string "with".
|
||||
//! \~russian Заменяет часть копии этой строки от символа "from" и максимальной длины "len" строкой "with".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! piCout << s.replaced(2, 3, "_cut_"); // s = "01_cut_56789"
|
||||
//! piCout << s.replaced(0, 1, "one_"); // s = "one_123456789"
|
||||
//! \endcode
|
||||
//! \~\sa \a replace(), \a replaceAll()
|
||||
PIString replaced(const int from, const int count, const PIString & with) const {PIString str(*this); str.replace(from, count, with); return str;}
|
||||
|
||||
//! \~english Replace first founded substring "what" with string "with" and return this string.
|
||||
//! \~russian Заменяет первую найденную подстроку "what" строкой "with", возвращает эту строку.
|
||||
PIString & replace(const PIString & what, const PIString & with, bool * ok = 0);
|
||||
|
||||
//! \~english Replace in string copy first founded substring "what" with string "with".
|
||||
//! \~russian Заменяет в копии строки первую найденную подстроку "what" строкой "with".
|
||||
//! \~\details
|
||||
//! \~english If "ok" is not null, it set to "true" if something was replaced.
|
||||
//! \~russian Если "ok" не null, то устанавливает в "true" если замена произведена.
|
||||
//! \~\code
|
||||
//! PIString s("pip string");
|
||||
//! bool ok;
|
||||
//! piCout << s.replace("string", "conf", &ok); // s = "pip conf", true
|
||||
//! piCout << s.replace("PIP", "PlInPr", &ok); // s = "pip string", false
|
||||
//! \endcode
|
||||
//! \~\sa \a replaced(), \a replaceAll()
|
||||
PIString replaced(const PIString & what, const PIString & with, bool * ok = 0) const {PIString str(*this); str.replace(what, with, ok); return str;}
|
||||
|
||||
//! \~english Replace all founded substrings "what" with strings "with" and return this string.
|
||||
//! \~russian Заменяет все найденные подстроки "what" строками "with", возвращает эту строку.
|
||||
PIString & replaceAll(const PIString & what, const PIString & with);
|
||||
|
||||
//! \~english Replace all founded substrings "what" with characters "with" and return this string.
|
||||
//! \~russian Заменяет все найденные подстроки "what" символами "with", возвращает эту строку.
|
||||
PIString & replaceAll(const PIString & what, const char with);
|
||||
|
||||
//! \~english Replace all founded characters "what" with characters "with" and return this string.
|
||||
//! \~russian Заменяет все найденные символы "what" символами "with", возвращает эту строку.
|
||||
PIString & replaceAll(const char what, const char with);
|
||||
|
||||
//! \~english Replace all founded substrings "what" with strings "with" in string copy.
|
||||
//! \~russian Заменяет в копии строки все найденные подстроки "what" строками "with".
|
||||
//! \~\sa \a replaceAll()
|
||||
PIString replacedAll(const PIString & what, const PIString & with) const {PIString str(*this); str.replaceAll(what, with); return str;}
|
||||
|
||||
//! \~english Replace all founded substrings "what" with characters "with" in string copy.
|
||||
//! \~russian Заменяет в копии строки все найденные подстроки "what" символами "with".
|
||||
//! \~\sa \a replaceAll()
|
||||
PIString replacedAll(const PIString & what, const char with) const {PIString str(*this); str.replaceAll(what, with); return str;}
|
||||
|
||||
//! \~english Replace all founded characters "what" with characters "with" in string copy.
|
||||
//! \~russian Заменяет в копии строки все найденные символы "what" символами "with".
|
||||
//! \~\sa \a replaceAll()
|
||||
PIString replacedAll(const char what, const char with) const {PIString str(*this); str.replaceAll(what, with); return str;}
|
||||
|
||||
//! \~english Remove all founded substrings "what" and return this string.
|
||||
//! \~russian Удаляет все найденные подстроки "what", возвращает эту строку.
|
||||
PIString & removeAll(const PIString & str);
|
||||
|
||||
//! \~english Remove all founded characters "what" and return this string.
|
||||
//! \~russian Удаляет все найденные символы "what", возвращает эту строку.
|
||||
PIString & removeAll(char c) {d.removeAll(PIChar(c)); return *this;}
|
||||
|
||||
//! \~english Repeat content of string "times" times and return this string.
|
||||
//! \~russian Повторяет содержимое строки "times" раз и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s(" :-) ");
|
||||
//! s.repeat(3);
|
||||
//! piCout << s; // :-) :-) :-)
|
||||
//! \endcode
|
||||
//! \~\sa \a repeated()
|
||||
PIString & repeat(int times) {PIString ss(*this); times--; piForTimes (times) *this += ss; return *this;}
|
||||
|
||||
//! \~english Returns repeated "times" times string.
|
||||
//! \~russian Возвращает повторённую "times" раз строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s(" :-) ");
|
||||
//! piCout << s.repeated(3); // :-) :-) :-)
|
||||
//! piCout << s; // :-)
|
||||
//! \endcode
|
||||
//! \~\sa \a repeat()
|
||||
PIString repeated(int times) const {PIString ss(*this); return ss.repeat(times);}
|
||||
|
||||
//! \~english Insert character "c" after index "index" and return this string.
|
||||
//! \~russian Вставляет символ "c" после позиции "index" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("pp");
|
||||
//! s.insert(1, "i");
|
||||
//! piCout << s; // s = "pip"
|
||||
//! \endcode
|
||||
PIString & insert(const int index, const PIChar c) {d.insert(index, c); return *this;}
|
||||
|
||||
//! \~english Insert character "c" after index "index" and return this string.
|
||||
//! \~russian Вставляет символ "c" после позиции "index" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("pp");
|
||||
//! s.insert(1, 'i');
|
||||
//! piCout << s; // s = "pip"
|
||||
//! \endcode
|
||||
PIString & insert(const int index, const char c) {return insert(index, PIChar(c));}
|
||||
|
||||
//! \~english Insert string "str" after index "index" and return this string.
|
||||
//! \~russian Вставляет строку "str" после позиции "index" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("stg");
|
||||
//! s.insert(2, "rin");
|
||||
//! piCout << s; // s = "string"
|
||||
//! \endcode
|
||||
PIString & insert(const int index, const PIString & str);
|
||||
|
||||
//! \~english Insert string "str" after index "index" and return this string.
|
||||
//! \~russian Вставляет строку "str" после позиции "index" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("stg");
|
||||
//! s.insert(2, "rin");
|
||||
//! piCout << s; // s = "string"
|
||||
//! \endcode
|
||||
PIString & insert(const int index, const char * c) {return insert(index, PIString(c));}
|
||||
|
||||
//! \~english Enlarge string to length "len" by addition characters "c" at the end, and return this string.
|
||||
//! \~russian Увеличивает длину строки до "len" добавлением символов "c" в конец и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("str");
|
||||
//! s.expandRightTo(2, "_");
|
||||
//! piCout << s; // s = "str"
|
||||
//! s.expandRightTo(6, "_");
|
||||
//! piCout << s; // s = "str___"
|
||||
//! \endcode
|
||||
//! \~\sa \a expandLeftTo(), \a expandedRightTo(), \a expandedLeftTo()
|
||||
PIString & expandRightTo(const int len, const PIChar c) {if (len > d.size_s()) d.resize(len, c); return *this;}
|
||||
|
||||
//! \~english Enlarge string to length "len" by addition characters "c" at the begin, and return this string.
|
||||
//! \~russian Увеличивает длину строки до "len" добавлением символов "c" в начало и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("str");
|
||||
//! s.expandLeftTo(2, "_");
|
||||
//! piCout << s; // s = "str"
|
||||
//! s.expandLeftTo(6, "_");
|
||||
//! piCout << s; // s = "___str"
|
||||
//! \endcode
|
||||
//! \~\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)); return *this;}
|
||||
|
||||
//! \~english Enlarge copy of this string to length "len" by addition characters "c" at the end.
|
||||
//! \~russian Увеличивает длину копии этой строки до "len" добавлением символов "c" в конец.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("str");
|
||||
//! piCouy << s.expandedRightTo(5, "_"); // s = "str__"
|
||||
//! piCout << s; // s = "str"
|
||||
//! \endcode
|
||||
//! \~\sa \a expandRightTo(), \a expandLeftTo(), \a expandedLeftTo()
|
||||
PIString expandedRightTo(const int len, const PIChar c) const {return PIString(*this).expandRightTo(len, c);}
|
||||
|
||||
//! \~english Enlarge copy of this string to length "len" by addition characters "c" at the begin.
|
||||
//! \~russian Увеличивает длину копии этой строки до "len" добавлением символов "c" в начало.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("str");
|
||||
//! piCouy << s.expandedLeftTo(5, "_"); // s = "__str"
|
||||
//! piCout << s; // s = "str"
|
||||
//! \endcode
|
||||
//! \~\sa \a expandRightTo(), \a expandLeftTo(), \a expandedRightTo()
|
||||
PIString expandedLeftTo(const int len, const PIChar c) const {return PIString(*this).expandLeftTo(len, c);}
|
||||
|
||||
//! \~english Add "c" characters at the beginning and end, and return this string.
|
||||
//! \~russian Добавляет символ "c" в начало и конец и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("str");
|
||||
//! s.quote();
|
||||
//! piCout << s; // s = ""str""
|
||||
//! \endcode
|
||||
//! \~\sa \a quoted()
|
||||
PIString & quote(PIChar c = PIChar('"')) {d.prepend(c); d.append(c); return *this;}
|
||||
|
||||
//! \~english Returns quoted copy of this string.
|
||||
//! \~russian Возвращает копию строки с добавленным в начало и конец символом "c".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("str");
|
||||
//! piCout << s.quoted(); // s = ""str""
|
||||
//! piCout << s; // s = "str"
|
||||
//! \endcode
|
||||
//! \~\sa \a quote()
|
||||
PIString quoted(PIChar c = PIChar('"')) {return PIString(*this).quote(c);}
|
||||
|
||||
//! \~english Reverse string and return this string.
|
||||
//! \~russian Разворачивает и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! s.reverse();
|
||||
//! piCout << s; // s = "9876543210"
|
||||
//! \endcode
|
||||
//! \~\sa \a reversed()
|
||||
PIString & reverse() {d.reverse(); return *this;}
|
||||
|
||||
//! \~english Reverse copy of this string.
|
||||
//! \~russian Разворачивает копию этой строки.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! piCout << s.reversed(); // s = "9876543210"
|
||||
//! piCout << s; // s = "0123456789"
|
||||
//! \endcode
|
||||
//! \~\sa \a reverse()
|
||||
PIString reversed() const {PIString ret(*this); return ret.reverse();}
|
||||
|
||||
//! \~english Fit string to maximum size "size" by inserting ".." at position "pos" and return this string.
|
||||
//! \~russian Уменьшает строку до размера "size", вставляя ".." в положение "pos" и возвращает эту строку.
|
||||
//! \~\sa \a elided()
|
||||
PIString & elide(int size, float pos = ElideCenter);
|
||||
|
||||
//! \~english Fit copy of this string to maximum size "size" by inserting ".." at position "pos".
|
||||
//! \~russian Уменьшает копию этой строки до размера "size", вставляя ".." в положение "pos".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString("123456789ABCDEF").elided(8, PIString::ElideLeft); // ..ABCDEF
|
||||
//! piCout << PIString("123456789ABCDEF").elided(8, PIString::ElideCenter); // 123..DEF
|
||||
//! piCout << PIString("123456789ABCDEF").elided(8, PIString::ElideRight); // 123456..
|
||||
//! piCout << PIString("123456789ABCDEF").elided(8, 0.25); // 12..CDEF
|
||||
//! \endcode
|
||||
//! \~\sa \a elide()
|
||||
PIString elided(int size, float pos = ElideCenter) const {PIString str(*this); str.elide(size, pos); return str;}
|
||||
|
||||
|
||||
//! \~english Take a part of string from character at index "start" and maximum length "len" and return it.
|
||||
//! \~russian Извлекает часть строки от символа "start" максимальной длины "len" и возвращает её.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! piCout << s.takeMid(1, 3); // "123"
|
||||
//! piCout << s; // s = "0456789"
|
||||
//! \endcode
|
||||
//! \~\sa \a takeLeft, \a takeRight()
|
||||
PIString takeMid(const int start, const int len = -1) {PIString ret(mid(start, len)); cutMid(start, len); return ret;}
|
||||
|
||||
//! \~english Take a part from the begin of string with maximum length "len" and return it.
|
||||
//! \~russian Извлекает часть строки от начала максимальной длины "len" и возвращает её.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! piCout << s.takeLeft(3); // "012"
|
||||
//! piCout << s; // s = "3456789"
|
||||
//! \endcode
|
||||
//! \~\sa \a takeMid(), \a takeRight()
|
||||
PIString takeLeft(const int len) {PIString ret(left(len)); cutLeft(len); return ret;}
|
||||
|
||||
//! \~english Take a part from the end of string with maximum length "len" and return it.
|
||||
//! \~russian Извлекает часть строки с конца максимальной длины "len" и возвращает её.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("0123456789");
|
||||
//! piCout << s.takeRight(3); // "789"
|
||||
//! piCout << s; // s = "0123456"
|
||||
//! \endcode
|
||||
//! \~\sa \a takeMid(), \a takeLeft()
|
||||
PIString takeRight(const int len) {PIString ret(right(len)); cutRight(len); return ret;}
|
||||
|
||||
//! \~english Take a character from the begin of this string and return it.
|
||||
//! \~russian Извлекает символ с начала строки и возвращает его как строку.
|
||||
PIString takeSymbol();
|
||||
|
||||
//! \~english Take a word from the begin of this string and return it.
|
||||
//! \~russian Извлекает слово с начала строки и возвращает его.
|
||||
PIString takeWord();
|
||||
|
||||
//! \~english Take a word with letters, numbers and '_' characters from the begin of this string and return it.
|
||||
//! \~russian Извлекает слово из букв, цифр и симолов '_' с начала строки и возвращает его.
|
||||
PIString takeCWord();
|
||||
|
||||
//! \~english Take a line from the begin of this string and return it.
|
||||
//! \~russian Извлекает строку текста (до новой строки) с начала строки и возвращает её.
|
||||
PIString takeLine();
|
||||
|
||||
//! \~english Take a number with C-format from the begin of this string and return it.
|
||||
//! \~russian Извлекает число в C-формате с начала строки и возвращает его как строку.
|
||||
PIString takeNumber();
|
||||
|
||||
//! \~english Take a range between "start" and "end" characters from the begin of this string and return it.
|
||||
//! \~russian Извлекает диапазон между символами "start" и "end" с начала строки и возвращает его.
|
||||
PIString takeRange(const PIChar start, const PIChar end, const PIChar shield = '\\');
|
||||
|
||||
|
||||
//! \~english Returns string in brackets "start" and "end" characters from the beginning.
|
||||
//! \~russian Возвращает строку между символами "start" и "end" с начала строки.
|
||||
PIString inBrackets(const PIChar start, const PIChar end) const;
|
||||
|
||||
//! \~english Returns \c char * representation of this string in system codepage.
|
||||
//! \~russian Возвращает \c char * представление строки в системной кодировке.
|
||||
const char * data() const;
|
||||
|
||||
//! \~english Returns \c char * representation of this string in terminal codepage.
|
||||
//! \~russian Возвращает \c char * представление строки в кодировке консоли.
|
||||
const char * dataConsole() const;
|
||||
|
||||
//! \~english Returns \c char * representation of this string in UTF-8.
|
||||
//! \~russian Возвращает \c char * представление строки в кодировке UTF-8.
|
||||
const char * dataUTF8() const;
|
||||
|
||||
//! \~english Returns \c char * representation of this string in ASCII.
|
||||
//! \~russian Возвращает \c char * представление строки в кодировке ASCII.
|
||||
const char * dataAscii() const;
|
||||
|
||||
//! \~english Returns hash of string
|
||||
//! \~russian Возвращает хэш строки
|
||||
uint hash() const;
|
||||
|
||||
//! \~english Same as \a toUTF8().
|
||||
//! \~russian Тоже самое, что \a toUTF8().
|
||||
PIByteArray toByteArray() const {return toUTF8();}
|
||||
|
||||
//! \~english Returns \a PIByteArray contains \a data() of this string without terminating null-char.
|
||||
//! \~russian Возвращает \a PIByteArray содержащий \a data() строки без завершающего нулевого байта.
|
||||
PIByteArray toSystem() const;
|
||||
|
||||
//! \~english Returns \a PIByteArray contains \a dataUTF8() of this string without terminating null-char.
|
||||
//! \~russian Возвращает \a PIByteArray содержащий \a dataUTF8() строки без завершающего нулевого байта.
|
||||
PIByteArray toUTF8() const;
|
||||
|
||||
//! \~english Returns \a PIByteArray contains custom charset representation of this string without terminating null-char.
|
||||
//! \~russian Возвращает \a PIByteArray содержащий строку в указанной кодировке без завершающего нулевого байта.
|
||||
PIByteArray toCharset(const char * c) const;
|
||||
|
||||
//! \~english Returns \a PIString with non-ASCII symbols replaced with '?'.
|
||||
//! \~russian Возвращает \a PIString с заменёнными '?' не-ASCII символами.
|
||||
PIString simplified() const;
|
||||
|
||||
//! \~english Split string with delimiter "delim" to \a PIStringList.
|
||||
//! \~russian Разделяет строку в \a PIStringList через разделитель "delim".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("1 2 3");
|
||||
//! piCout << s.split(" "); // {"1", "2", "3"}
|
||||
//! \endcode
|
||||
PIStringList split(const PIString & delim) const;
|
||||
|
||||
|
||||
//! \~english Convert each character in copied string to upper case.
|
||||
//! \~russian Преобразует каждый символ в скопированной строке в верхний регистр.
|
||||
PIString toUpperCase() const;
|
||||
|
||||
//! \~english Convert each character in copied string to lower case.
|
||||
//! \~russian Преобразует каждый символ в скопированной строке в нижний регистр.
|
||||
PIString toLowerCase() const;
|
||||
|
||||
|
||||
//! \~english Returns if string contains character "c".
|
||||
//! \~russian Возвращает содержит ли строка символ "c".
|
||||
bool contains(const char c) const {return d.contains(PIChar(c));}
|
||||
|
||||
//! \~english Returns if string contains substring "str".
|
||||
//! \~russian Возвращает содержит ли строка подстроку "str".
|
||||
bool contains(const char * str) const {return contains(PIString(str));}
|
||||
|
||||
//! \~english Returns if string contains substring "str".
|
||||
//! \~russian Возвращает содержит ли строка подстроку "str".
|
||||
bool contains(const PIString & str) const {return find(str) >= 0;}
|
||||
|
||||
|
||||
//! \~english Search character "c" from character at index "start" and return first occur position.
|
||||
//! \~russian Ищет символ "c" от символа "start" и возвращает первое вхождение.
|
||||
int find(const char c, const int start = 0) const;
|
||||
|
||||
//! \~english Search character "c" from character at index "start" and return first occur position.
|
||||
//! \~russian Ищет символ "c" от символа "start" и возвращает первое вхождение.
|
||||
int find(PIChar c, const int start = 0) const {return d.indexOf(c, start);}
|
||||
|
||||
//! \~english Search substring "str" from character at index "start" and return first occur position.
|
||||
//! \~russian Ищет подстроку "str" от символа "start" и возвращает первое вхождение.
|
||||
int find(const PIString & str, const int start = 0) const;
|
||||
|
||||
//! \~english Search substring "str" from character at index "start" and return first occur position.
|
||||
//! \~russian Ищет подстроку "str" от символа "start" и возвращает первое вхождение.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("012345012345");
|
||||
//! piCout << s.find("-"); // -1
|
||||
//! piCout << s.find("34"); // 3
|
||||
//! piCout << s.find("3", 4); // 9
|
||||
//! piCout << s.find("3", 10); // -1
|
||||
//! \endcode
|
||||
//! \~\sa \a findAny(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
|
||||
int find(const char * str, const int start = 0) const {return find(PIString(str), start);}
|
||||
|
||||
//! \~english Search any character of "str" from character at index "start" and return first occur position.
|
||||
//! \~russian Ищет любой символ строки "str" от симола "start" и возвращает первое вхождение.
|
||||
int findAny(const PIString & str, const int start = 0) const;
|
||||
|
||||
//! \~english Search any character of "str" from character at index "start" and return first occur position.
|
||||
//! \~russian Ищет любой символ строки "str" от симола "start" и возвращает первое вхождение.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString("1.str").findAny(".,:"); // 1
|
||||
//! piCout << PIString("1,str").findAny(".,:"); // 1
|
||||
//! piCout << PIString("1:str").findAny(".,:"); // 1
|
||||
//! \endcode
|
||||
//! \~\sa \a find(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
|
||||
int findAny(const char * str, const int start = 0) const {return findAny(PIString(str), start);}
|
||||
|
||||
//! \~english Search character "c" from character at index "start" and return last occur position.
|
||||
//! \~russian Ищет символ "c" от символа "start" и возвращает последнее вхождение.
|
||||
int findLast(const char c, const int start = 0) const;
|
||||
|
||||
//! \~english Search character "c" from character at index "start" and return last occur position.
|
||||
//! \~russian Ищет символ "c" от символа "start" и возвращает последнее вхождение.
|
||||
int findLast(PIChar c, const int start = 0) const;
|
||||
|
||||
//! \~english Search substring "str" from character at index "start" and return last occur position.
|
||||
//! \~russian Ищет подстроку "str" от символа "start" и возвращает последнее вхождение.
|
||||
int findLast(const PIString & str, const int start = 0) const;
|
||||
|
||||
//! \~english Search substring "str" from character at index "start" and return last occur position.
|
||||
//! \~russian Ищет подстроку "str" от символа "start" и возвращает последнее вхождение.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("012345012345");
|
||||
//! piCout << s.findLast("-"); // -1
|
||||
//! piCout << s.findLast("34"); // 9
|
||||
//! piCout << s.findLast("3", 4); // 9
|
||||
//! piCout << s.findLast("3", 10); // -1
|
||||
//! \endcode
|
||||
//! \~\sa \a find(), \a findAny(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
|
||||
int findLast(const char * str, const int start = 0) const {return findLast(PIString(str), start);}
|
||||
|
||||
//! \~english Search any character of "str" from character at index "start" and return last occur position.
|
||||
//! \~russian Ищет любой символ строки "str" от символа "start" и возвращает последнее вхождение.
|
||||
int findAnyLast(const PIString & str, const int start = 0) const;
|
||||
|
||||
//! \~english Search any character of "str" from character at index "start" and return last occur position.
|
||||
//! \~russian Ищет любой символ строки "str" от символа "start" и возвращает последнее вхождение.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString(".str.0").findAnyLast(".,:"); // 4
|
||||
//! piCout << PIString(".str,0").findAnyLast(".,:"); // 4
|
||||
//! piCout << PIString(".str:0").findAnyLast(".,:"); // 4
|
||||
//! \endcode
|
||||
//! \~\sa \a find(), \a findAny(), \a findLast(), \a findWord(), \a findCWord(), \a findRange()
|
||||
int findAnyLast(const char * str, const int start = 0) const {return findAnyLast(PIString(str), start);}
|
||||
|
||||
//! \~english Search word "word" from character at index "start" and return first occur position.
|
||||
//! \~russian Ищет слово "word" от симола "start" и возвращает первое вхождение.
|
||||
int findWord(const PIString & word, const int start = 0) const;
|
||||
|
||||
//! \~english Search C-word "word" from character at index "start" and return first occur position.
|
||||
//! \~russian Ищет C-слово "word" от симола "start" и возвращает первое вхождение.
|
||||
int findCWord(const PIString & word, const int start = 0) const;
|
||||
|
||||
//! \~english Search range start between "start" and "end" characters at index "start_index" and return first occur position.
|
||||
//! \~russian Ищет начало диапазона между символами "start" и "end" от симола "start" и возвращает первое вхождение.
|
||||
int findRange(const PIChar start, const PIChar end, const PIChar shield = '\\', const int start_index = 0, int * len = 0) const;
|
||||
|
||||
//! \~english Returns number of occurrences of character "c".
|
||||
//! \~russian Возвращает число вхождений символа "c".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString(".str.0").entries("."); // 2
|
||||
//! piCout << PIString(".str.0").entries("0"); // 1
|
||||
//! \endcode
|
||||
int entries(const PIChar c) const;
|
||||
|
||||
//! \~english Returns number of occurrences of character "c".
|
||||
//! \~russian Возвращает число вхождений символа "c".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString(".str.0").entries('.'); // 2
|
||||
//! piCout << PIString(".str.0").entries('0'); // 1
|
||||
//! \endcode
|
||||
int entries(char c) const {return entries(PIChar(c));}
|
||||
|
||||
//! \~english Returns if string starts with "str".
|
||||
//! \~russian Возвращает начинается ли строка со "str".
|
||||
bool startsWith(const PIString & str) const;
|
||||
|
||||
//! \~english Returns if string ends with "str".
|
||||
//! \~russian Возвращает оканчивается ли строка на "str".
|
||||
bool endsWith(const PIString & str) const;
|
||||
|
||||
//! \~english Returns characters length of string.
|
||||
//! \~russian Возвращает длину строки в символах.
|
||||
int length() const {return d.size_s();}
|
||||
|
||||
//! \~english Returns characters length of string.
|
||||
//! \~russian Возвращает длину строки в символах.
|
||||
size_t size() const {return d.size();}
|
||||
|
||||
//! \~english Returns characters length of string.
|
||||
//! \~russian Возвращает длину строки в символах.
|
||||
ssize_t size_s() const {return d.size_s();}
|
||||
|
||||
//! \~english Returns \c true if string is empty, i.e. length = 0.
|
||||
//! \~russian Возвращает \c true если строка пустая, т.е. длина = 0.
|
||||
bool isEmpty() const {if (d.isEmpty()) return true; if (d.at(0) == PIChar()) return true; return false;}
|
||||
|
||||
//! \~english Returns \c true if string is not empty, i.e. length > 0.
|
||||
//! \~russian Возвращает \c true если строка непустая, т.е. длина > 0.
|
||||
bool isNotEmpty() const {return !isEmpty();}
|
||||
|
||||
//! \~english Clear string, will be empty string.
|
||||
//! \~russian Очищает строку, строка становится пустой.
|
||||
//! \~\details
|
||||
//! \~\note
|
||||
//! \~english Reserved memory will not be released.
|
||||
//! \~russian Зарезервированная память не освободится.
|
||||
//! \~\sa \a resize()
|
||||
void clear() {d.clear();}
|
||||
|
||||
//! \~english Returns \c true if string equal "true", "yes", "on" or positive not null numeric value.
|
||||
//! \~russian Возвращает \c true если строка равна "true", "yes", "on" или числу > 0.
|
||||
bool toBool() const;
|
||||
|
||||
//! \~english Returns \c char numeric value of string.
|
||||
//! \~russian Возвращает \c char числовое значение строки.
|
||||
char toChar() const;
|
||||
|
||||
//! \~english Returns \c short numeric value of string in base "base".
|
||||
//! \~russian Возвращает \c short числовое значение строки по основанию "base".
|
||||
//! \~\details
|
||||
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
|
||||
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
|
||||
//! \~\code
|
||||
//! piCout << PIString("123").toShort(); // 123
|
||||
//! piCout << PIString("123").toShort(16); // 291
|
||||
//! piCout << PIString("0x123").toShort(); // 291
|
||||
//! piCout << PIString("1001").toShort(2); // 9
|
||||
//! \endcode
|
||||
short toShort(int base = -1, bool * ok = 0) const {return short(toNumberBase(*this, base, ok));}
|
||||
|
||||
//! \~english Returns \c ushort numeric value of string in base "base".
|
||||
//! \~russian Возвращает \c ushort числовое значение строки по основанию "base".
|
||||
//! \~\details
|
||||
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
|
||||
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
|
||||
//! \~\code
|
||||
//! piCout << PIString("123").toUShort(); // 123
|
||||
//! piCout << PIString("123").toUShort(16); // 291
|
||||
//! piCout << PIString("0x123").toUShort(); // 291
|
||||
//! piCout << PIString("1001").toUShort(2); // 9
|
||||
//! \endcode
|
||||
ushort toUShort(int base = -1, bool * ok = 0) const {return ushort(toNumberBase(*this, base, ok));}
|
||||
|
||||
//! \~english Returns \c int numeric value of string in base "base".
|
||||
//! \~russian Возвращает \c int числовое значение строки по основанию "base".
|
||||
//! \~\details
|
||||
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
|
||||
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
|
||||
//! \~\code
|
||||
//! piCout << PIString("123").toInt(); // 123
|
||||
//! piCout << PIString("123").toInt(16); // 291
|
||||
//! piCout << PIString("0x123").toInt(); // 291
|
||||
//! piCout << PIString("1001").toInt(2); // 9
|
||||
//! \endcode
|
||||
int toInt(int base = -1, bool * ok = 0) const {return int(toNumberBase(*this, base, ok));}
|
||||
|
||||
//! \~english Returns \c uint numeric value of string in base "base".
|
||||
//! \~russian Возвращает \c uint числовое значение строки по основанию "base".
|
||||
//! \~\details
|
||||
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
|
||||
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
|
||||
//! \~\code
|
||||
//! piCout << PIString("123").toUInt(); // 123
|
||||
//! piCout << PIString("123").toUInt(16); // 291
|
||||
//! piCout << PIString("0x123").toUInt(); // 291
|
||||
//! piCout << PIString("1001").toUInt(2); // 9
|
||||
//! \endcode
|
||||
uint toUInt(int base = -1, bool * ok = 0) const {return uint(toNumberBase(*this, base, ok));}
|
||||
|
||||
//! \~english Returns \c long numeric value of string in base "base".
|
||||
//! \~russian Возвращает \c long числовое значение строки по основанию "base".
|
||||
//! \~\details
|
||||
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
|
||||
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
|
||||
//! \~\code
|
||||
//! piCout << PIString("123").toLong(); // 123
|
||||
//! piCout << PIString("123").toLong(16); // 291
|
||||
//! piCout << PIString("0x123").toLong(); // 291
|
||||
//! piCout << PIString("1001").toLong(2); // 9
|
||||
//! \endcode
|
||||
long toLong(int base = -1, bool * ok = 0) const {return long(toNumberBase(*this, base, ok));}
|
||||
|
||||
//! \~english Returns \c ulong numeric value of string in base "base".
|
||||
//! \~russian Возвращает \c ulong числовое значение строки по основанию "base".
|
||||
//! \~\details
|
||||
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
|
||||
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
|
||||
//! \~\code
|
||||
//! piCout << PIString("123").toULong(); // 123
|
||||
//! piCout << PIString("123").toULong(16); // 291
|
||||
//! piCout << PIString("0x123").toULong(); // 291
|
||||
//! piCout << PIString("1001").toULong(2); // 9
|
||||
//! \endcode
|
||||
ulong toULong(int base = -1, bool * ok = 0) const {return ulong(toNumberBase(*this, base, ok));}
|
||||
|
||||
//! \~english Returns \c llong numeric value of string in base "base".
|
||||
//! \~russian Возвращает \c llong числовое значение строки по основанию "base".
|
||||
//! \~\details
|
||||
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
|
||||
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
|
||||
//! \~\code
|
||||
//! piCout << PIString("123").toLLong(); // 123
|
||||
//! piCout << PIString("123").toLLong(16); // 291
|
||||
//! piCout << PIString("0x123").toLLong(); // 291
|
||||
//! piCout << PIString("1001").toLLong(2); // 9
|
||||
//! \endcode
|
||||
llong toLLong(int base = -1, bool * ok = 0) const {return toNumberBase(*this, base, ok);}
|
||||
|
||||
//! \~english Returns \c ullong numeric value of string in base "base".
|
||||
//! \~russian Возвращает \c ullong числовое значение строки по основанию "base".
|
||||
//! \~\details
|
||||
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
|
||||
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
|
||||
//! \~\code
|
||||
//! piCout << PIString("123").toULLong(); // 123
|
||||
//! piCout << PIString("123").toULLong(16); // 291
|
||||
//! piCout << PIString("0x123").toULLong(); // 291
|
||||
//! piCout << PIString("1001").toULLong(2); // 9
|
||||
//! \endcode
|
||||
ullong toULLong(int base = -1, bool * ok = 0) const {return ullong(toNumberBase(*this, base, ok));}
|
||||
|
||||
//! \~english Returns \c float numeric value of string.
|
||||
//! \~russian Возвращает \c float числовое значение строки.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString("123").toFloat(); // 123
|
||||
//! piCout << PIString("1.2E+2").toFloat(); // 120
|
||||
//! piCout << PIString("0.01").toFloat(); // 0.01
|
||||
//! \endcode
|
||||
float toFloat() const;
|
||||
|
||||
//! \~english Returns \c double numeric value of string.
|
||||
//! \~russian Возвращает \c double числовое значение строки.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString("123").toDouble(); // 123
|
||||
//! piCout << PIString("1.2E+2").toDouble(); // 120
|
||||
//! piCout << PIString("0.01").toDouble(); // 0.01
|
||||
//! \endcode
|
||||
double toDouble() const;
|
||||
|
||||
//! \~english Returns \c ldouble numeric value of string.
|
||||
//! \~russian Возвращает \c ldouble числовое значение строки.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString("123").toLDouble(); // 123
|
||||
//! piCout << PIString("1.2E+2").toLDouble(); // 120
|
||||
//! piCout << PIString("0.01").toLDouble(); // 0.01
|
||||
//! \endcode
|
||||
ldouble toLDouble() const;
|
||||
|
||||
//! \~english Set string content to text representation of "value" in base "base" and return this string.
|
||||
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s;
|
||||
//! s.setNumber(123);
|
||||
//! piCout << s; // 123
|
||||
//! s.setNumber(123, 16);
|
||||
//! piCout << s; // 7B
|
||||
//! \endcode
|
||||
PIString & setNumber(const short value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
|
||||
|
||||
//! \~english Set string content to text representation of "value" in base "base" and return this string.
|
||||
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s;
|
||||
//! s.setNumber(123);
|
||||
//! piCout << s; // 123
|
||||
//! s.setNumber(123, 16);
|
||||
//! piCout << s; // 7B
|
||||
//! \endcode
|
||||
PIString & setNumber(const ushort value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
|
||||
|
||||
//! \~english Set string content to text representation of "value" in base "base" and return this string.
|
||||
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s;
|
||||
//! s.setNumber(123);
|
||||
//! piCout << s; // 123
|
||||
//! s.setNumber(123, 16);
|
||||
//! piCout << s; // 7B
|
||||
//! \endcode
|
||||
PIString & setNumber(const int value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
|
||||
|
||||
//! \~english Set string content to text representation of "value" in base "base" and return this string.
|
||||
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s;
|
||||
//! s.setNumber(123);
|
||||
//! piCout << s; // 123
|
||||
//! s.setNumber(123, 16);
|
||||
//! piCout << s; // 7B
|
||||
//! \endcode
|
||||
PIString & setNumber(const uint value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
|
||||
|
||||
//! \~english Set string content to text representation of "value" in base "base" and return this string.
|
||||
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s;
|
||||
//! s.setNumber(123);
|
||||
//! piCout << s; // 123
|
||||
//! s.setNumber(123, 16);
|
||||
//! piCout << s; // 7B
|
||||
//! \endcode
|
||||
PIString & setNumber(const long value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
|
||||
|
||||
//! \~english Set string content to text representation of "value" in base "base" and return this string.
|
||||
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s;
|
||||
//! s.setNumber(123);
|
||||
//! piCout << s; // 123
|
||||
//! s.setNumber(123, 16);
|
||||
//! piCout << s; // 7B
|
||||
//! \endcode
|
||||
PIString & setNumber(const ulong value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
|
||||
|
||||
//! \~english Set string content to text representation of "value" in base "base" and return this string.
|
||||
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s;
|
||||
//! s.setNumber(123);
|
||||
//! piCout << s; // 123
|
||||
//! s.setNumber(123, 16);
|
||||
//! piCout << s; // 7B
|
||||
//! \endcode
|
||||
PIString & setNumber(const llong & value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
|
||||
|
||||
//! \~english Set string content to text representation of "value" in base "base" and return this string.
|
||||
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s;
|
||||
//! s.setNumber(123);
|
||||
//! piCout << s; // 123
|
||||
//! s.setNumber(123, 16);
|
||||
//! piCout << s; // 7B
|
||||
//! \endcode
|
||||
PIString & setNumber(const ullong & value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
|
||||
|
||||
//! \~english Set string content to text representation of "value" with format "format" and precision "precision" and return this string.
|
||||
//! \~russian Устанавливает содержимое строки в текстовое представление "value" в формате "format" и точностью "precision" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s;
|
||||
//! s.setNumber(12.3);
|
||||
//! piCout << s; // 12.30000000
|
||||
//! s.setNumber(12.3, 'f', 3);
|
||||
//! piCout << s; // 12.300
|
||||
//! s.setNumber(12.123456, 'f', 3);
|
||||
//! piCout << s; // 12.123
|
||||
//! s.setNumber(123456789., 'g', 2);
|
||||
//! piCout << s; // 1.2e+08
|
||||
//! s.setNumber(123456789., 'f', 0);
|
||||
//! piCout << s; // 123456789
|
||||
//! \endcode
|
||||
PIString & setNumber(const float value, char format = 'f', int precision = 8) {*this = PIString::fromNumber(value, format, precision); return *this;}
|
||||
|
||||
//! \~english Set string content to text representation of "value" with format "format" and precision "precision" and return this string.
|
||||
//! \~russian Устанавливает содержимое строки в текстовое представление "value" в формате "format" и точностью "precision" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s;
|
||||
//! s.setNumber(12.3);
|
||||
//! piCout << s; // 12.30000000
|
||||
//! s.setNumber(12.3, 'f', 3);
|
||||
//! piCout << s; // 12.300
|
||||
//! s.setNumber(12.123456, 'f', 3);
|
||||
//! piCout << s; // 12.123
|
||||
//! s.setNumber(123456789., 'g', 2);
|
||||
//! piCout << s; // 1.2e+08
|
||||
//! s.setNumber(123456789., 'f', 0);
|
||||
//! piCout << s; // 123456789
|
||||
//! \endcode
|
||||
PIString & setNumber(const double & value, char format = 'f', int precision = 8) {*this = PIString::fromNumber(value, format, precision); return *this;}
|
||||
|
||||
//! \~english Set string content to text representation of "value" with format "format" and precision "precision" and return this string.
|
||||
//! \~russian Устанавливает содержимое строки в текстовое представление "value" в формате "format" и точностью "precision" и возвращает эту строку.
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s;
|
||||
//! s.setNumber(12.3);
|
||||
//! piCout << s; // 12.30000000
|
||||
//! s.setNumber(12.3, 'f', 3);
|
||||
//! piCout << s; // 12.300
|
||||
//! s.setNumber(12.123456, 'f', 3);
|
||||
//! piCout << s; // 12.123
|
||||
//! s.setNumber(123456789., 'g', 2);
|
||||
//! piCout << s; // 1.2e+08
|
||||
//! s.setNumber(123456789., 'f', 0);
|
||||
//! piCout << s; // 123456789
|
||||
//! \endcode
|
||||
PIString & setNumber(const ldouble & value, char format = 'f', int precision = 8) {*this = PIString::fromNumber(value, format, precision); return *this;}
|
||||
|
||||
//! \~english Set string content to human readable size in B/kB/MB/GB/TB/PB.
|
||||
//! \~russian Устанавливает содержимое в строку с читаемым размером B/kB/MB/GB/TB/PB.
|
||||
//! \~\sa PIString::readableSize()
|
||||
PIString & setReadableSize(llong bytes);
|
||||
|
||||
//! \~english Returns string contains numeric representation of "value" in base "base".
|
||||
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString::fromNumber(123); // 123
|
||||
//! piCout << PIString::fromNumber(123, 16); // 7B
|
||||
//! \endcode
|
||||
static PIString fromNumber(const short value, int base = 10, bool * ok = 0) {return fromNumberBaseS(llong(value), base, ok);}
|
||||
|
||||
//! \~english Returns string contains numeric representation of "value" in base "base".
|
||||
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString::fromNumber(123); // 123
|
||||
//! piCout << PIString::fromNumber(123, 16); // 7B
|
||||
//! \endcode
|
||||
static PIString fromNumber(const ushort value, int base = 10, bool * ok = 0) {return fromNumberBaseU(ullong(value), base, ok);}
|
||||
|
||||
//! \~english Returns string contains numeric representation of "value" in base "base".
|
||||
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString::fromNumber(123); // 123
|
||||
//! piCout << PIString::fromNumber(123, 16); // 7B
|
||||
//! \endcode
|
||||
static PIString fromNumber(const int value, int base = 10, bool * ok = 0) {return fromNumberBaseS(llong(value), base, ok);}
|
||||
|
||||
//! \~english Returns string contains numeric representation of "value" in base "base".
|
||||
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString::fromNumber(123); // 123
|
||||
//! piCout << PIString::fromNumber(123, 16); // 7B
|
||||
//! \endcode
|
||||
static PIString fromNumber(const uint value, int base = 10, bool * ok = 0) {return fromNumberBaseU(ullong(value), base, ok);}
|
||||
|
||||
//! \~english Returns string contains numeric representation of "value" in base "base".
|
||||
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString::fromNumber(123); // 123
|
||||
//! piCout << PIString::fromNumber(123, 16); // 7B
|
||||
//! \endcode
|
||||
static PIString fromNumber(const long value, int base = 10, bool * ok = 0) {return fromNumberBaseS(llong(value), base, ok);}
|
||||
|
||||
//! \~english Returns string contains numeric representation of "value" in base "base".
|
||||
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString::fromNumber(123); // 123
|
||||
//! piCout << PIString::fromNumber(123, 16); // 7B
|
||||
//! \endcode
|
||||
static PIString fromNumber(const ulong value, int base = 10, bool * ok = 0) {return fromNumberBaseU(ullong(value), base, ok);}
|
||||
|
||||
//! \~english Returns string contains numeric representation of "value" in base "base".
|
||||
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString::fromNumber(123); // 123
|
||||
//! piCout << PIString::fromNumber(123, 16); // 7B
|
||||
//! \endcode
|
||||
static PIString fromNumber(const llong & value, int base = 10, bool * ok = 0) {return fromNumberBaseS(value, base, ok);}
|
||||
|
||||
//! \~english Returns string contains numeric representation of "value" in base "base".
|
||||
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString::fromNumber(123); // 123
|
||||
//! piCout << PIString::fromNumber(123, 16); // 7B
|
||||
//! \endcode
|
||||
static PIString fromNumber(const ullong & value, int base = 10, bool * ok = 0) {return fromNumberBaseU(value, base, ok);}
|
||||
|
||||
//! \~english Returns string contains numeric representation of "value" with format "format" and precision "precision".
|
||||
//! \~russian Возвращает строковое представление числа "value" в формате "format" и точностью "precision".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString::fromNumber(12.3); // 12.30000000
|
||||
//! piCout << PIString::fromNumber(12.3, 'f', 3); // 12.300
|
||||
//! piCout << PIString::fromNumber(12.123456, 'f', 3); // 12.123
|
||||
//! piCout << PIString::fromNumber(123456789., 'g', 2); // 1.2e+08
|
||||
//! piCout << PIString::fromNumber(123456789., 'f', 0); // 123456789
|
||||
//! \endcode
|
||||
static PIString fromNumber(const float value, char format = 'f', int precision = 8) {return dtos(value, format, precision);}
|
||||
|
||||
//! \~english Returns string contains numeric representation of "value" with format "format" and precision "precision".
|
||||
//! \~russian Возвращает строковое представление числа "value" в формате "format" и точностью "precision".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString::fromNumber(12.3); // 12.30000000
|
||||
//! piCout << PIString::fromNumber(12.3, 'f', 3); // 12.300
|
||||
//! piCout << PIString::fromNumber(12.123456, 'f', 3); // 12.123
|
||||
//! piCout << PIString::fromNumber(123456789., 'g', 2); // 1.2e+08
|
||||
//! piCout << PIString::fromNumber(123456789., 'f', 0); // 123456789
|
||||
//! \endcode
|
||||
static PIString fromNumber(const double & value, char format = 'f', int precision = 8) {return dtos(value, format, precision);}
|
||||
|
||||
//! \~english Returns string contains numeric representation of "value" with format "format" and precision "precision".
|
||||
//! \~russian Возвращает строковое представление числа "value" в формате "format" и точностью "precision".
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString::fromNumber(12.3); // 12.30000000
|
||||
//! piCout << PIString::fromNumber(12.3, 'f', 3); // 12.300
|
||||
//! piCout << PIString::fromNumber(12.123456, 'f', 3); // 12.123
|
||||
//! piCout << PIString::fromNumber(123456789., 'g', 2); // 1.2e+08
|
||||
//! piCout << PIString::fromNumber(123456789., 'f', 0); // 123456789
|
||||
//! \endcode
|
||||
static PIString fromNumber(const ldouble & value, char format = 'f', int precision = 8) {return dtos(value, format, precision);}
|
||||
|
||||
//! \~english Returns "true" or "false"
|
||||
//! \~russian Возвращает "true" или "false"
|
||||
static PIString fromBool(const bool value) {return PIString(value ? PIStringAscii("true") : PIStringAscii("false"));}
|
||||
|
||||
//! \~english Returns string constructed from terminal codepage.
|
||||
//! \~russian Возвращает строку созданную из кодировки консоли.
|
||||
static PIString fromConsole(const PIByteArray & s);
|
||||
|
||||
//! \~english Returns string constructed from terminal codepage.
|
||||
//! \~russian Возвращает строку созданную из кодировки консоли.
|
||||
static PIString fromConsole(const char * s);
|
||||
|
||||
//! \~english Returns string constructed from system codepage.
|
||||
//! \~russian Возвращает строку созданную из кодировки системы.
|
||||
static PIString fromSystem(const PIByteArray & s);
|
||||
|
||||
//! \~english Returns string constructed from system codepage.
|
||||
//! \~russian Возвращает строку созданную из кодировки системы.
|
||||
static PIString fromSystem(const char * s);
|
||||
|
||||
//! \~english Returns string constructed from UTF-8.
|
||||
//! \~russian Возвращает строку созданную из UTF-8.
|
||||
static PIString fromUTF8(const char * s);
|
||||
|
||||
//! \~english Returns string constructed from UTF-8.
|
||||
//! \~russian Возвращает строку созданную из UTF-8.
|
||||
static PIString fromUTF8(const PIByteArray & utf);
|
||||
|
||||
//! \~english Returns string constructed from ASCII.
|
||||
//! \~russian Возвращает строку созданную из ASCII.
|
||||
static PIString fromAscii(const char * s);
|
||||
|
||||
//! \~english Returns string constructed from "len" chars ASCII.
|
||||
//! \~russian Возвращает строку созданную из "len" символов ASCII.
|
||||
static PIString fromAscii(const char * s, int len);
|
||||
|
||||
//! \~english Returns string constructed from "cp" codepage.
|
||||
//! \~russian Возвращает строку созданную из кодировки "cp".
|
||||
static PIString fromCodepage(const char * s, const char * cp);
|
||||
|
||||
//! \~english Returns string contains human readable size in B/kB/MB/GB/TB/PB.
|
||||
//! \~russian Возвращает строку с читаемым размером B/kB/MB/GB/TB/PB.
|
||||
//! \~\sa PIString::setReadableSize()
|
||||
static PIString readableSize(llong bytes);
|
||||
|
||||
//! \~english Swaps string `str` other with this string.
|
||||
//! \~russian Меняет строку `str` с этой строкой.
|
||||
//! \~\details
|
||||
//! \~english This operation is very fast and never fails.
|
||||
//! \~russian Эта операция выполняется мгновенно без копирования памяти и никогда не дает сбоев.
|
||||
void swap(PIString & str) {
|
||||
d.swap(str.d);
|
||||
piSwap(data_, str.data_);
|
||||
}
|
||||
|
||||
private:
|
||||
static const char toBaseN[];
|
||||
static const char fromBaseN[];
|
||||
|
||||
static PIString itos(const int num);
|
||||
static PIString ltos(const long num);
|
||||
static PIString lltos(const llong num);
|
||||
static PIString uitos(const uint num);
|
||||
static PIString ultos(const ulong num);
|
||||
static PIString ulltos(const ullong num);
|
||||
static PIString dtos(const double num, char format = 'f', int precision = 8);
|
||||
static PIString fromNumberBaseS(const llong value, int base = 10, bool * ok = 0);
|
||||
static PIString fromNumberBaseU(const ullong value, int base = 10, bool * ok = 0);
|
||||
static llong toNumberBase(const PIString & value, int base = -1, bool * ok = 0);
|
||||
void appendFromChars(const char * c, int s, const char * cp = __syslocname__);
|
||||
void buildData(const char * cp = __syslocname__) const;
|
||||
void deleteData() const;
|
||||
void trimsubstr(int &st, int &fn) const;
|
||||
|
||||
PIDeque<PIChar> d;
|
||||
mutable char * data_ = nullptr;
|
||||
};
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIString) {s << v.d; return s;}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ(PIString) {s >> v.d; return s;}
|
||||
|
||||
|
||||
//! \~english Returns concatenated string.
|
||||
//! \~russian Возвращает соединение строк.
|
||||
inline PIString operator +(const PIString & str, const PIString & f) {PIString s(str); s += f; return s;}
|
||||
|
||||
//! \~english Returns concatenated string.
|
||||
//! \~russian Возвращает соединение строк.
|
||||
inline PIString operator +(const PIString & f, const char * str) {PIString s(f); s += str; return s;}
|
||||
|
||||
//! \~english Returns concatenated string.
|
||||
//! \~russian Возвращает соединение строк.
|
||||
inline PIString operator +(const char * str, const PIString & f) {return PIString(str) + f;}
|
||||
|
||||
//! \~english Returns concatenated string.
|
||||
//! \~russian Возвращает соединение строк.
|
||||
inline PIString operator +(const char c, const PIString & f) {return PIString(c) + f;}
|
||||
|
||||
//! \~english Returns concatenated string.
|
||||
//! \~russian Возвращает соединение строк.
|
||||
inline PIString operator +(const PIString & f, const char c) {PIString s(f); s.push_back(c); return s;}
|
||||
|
||||
|
||||
//! \relatesalso PIString
|
||||
//! \~english Compare two version strings in free notation and returns 0, -1 or 1.
|
||||
//! \~russian Сравнивает две строки с версиями в произвольной форме и возвращает 0, -1 или 1.
|
||||
int PIP_EXPORT versionCompare(const PIString & v0, const PIString & v1, int components = 6);
|
||||
|
||||
//! \relatesalso PIString
|
||||
//! \~english Converts version string in free notation to classic view.
|
||||
//! \~russian Преобразует строку с версией в произвольной форме к классическому виду.
|
||||
PIString PIP_EXPORT versionNormalize(const PIString & v);
|
||||
|
||||
|
||||
template<> inline uint piHash(const PIString & s) {return s.hash();}
|
||||
|
||||
template<> inline void piSwap(PIString & f, PIString & s) {
|
||||
f.swap(s);
|
||||
}
|
||||
|
||||
#endif // PISTRING_H
|
||||
@@ -1,131 +0,0 @@
|
||||
/*! \file pistring_std.h
|
||||
* \ingroup Core
|
||||
* \brief
|
||||
* \~english STD convertions for PIString
|
||||
* \~russian Преобразования в/из STD для строки
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
STD for PIString
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PISTRING_STD_H
|
||||
#define PISTRING_STD_H
|
||||
|
||||
|
||||
#include <string>
|
||||
#ifdef QNX
|
||||
typedef std::basic_string<wchar_t> wstring;
|
||||
#endif
|
||||
#include "pistringlist.h"
|
||||
|
||||
|
||||
inline std::string PIString2StdString(const PIString & v) {
|
||||
std::string s;
|
||||
ushort wc;
|
||||
uchar tc;
|
||||
if (v.size() > 0) {
|
||||
for (int i = 0; i < v.length(); ++i) {
|
||||
wc = v[i].unicode16Code();
|
||||
while (tc = wc & 0xFF, tc) {
|
||||
s.push_back(tc);
|
||||
wc >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
inline PIString StdString2PIString(const std::string & v) {
|
||||
return PIString(v.c_str(), v.length());
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAS_LOCALE
|
||||
inline std::wstring PIString2StdWString(const PIString & v) {
|
||||
std::wstring s;
|
||||
for (int i = 0; i < v.length(); ++i) {
|
||||
s.push_back(v[i].toWChar());
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
inline PIString StdWString2PIString(const std::wstring & v) {
|
||||
PIString s;
|
||||
uint l = v.size();
|
||||
for (uint i = 0; i < l; ++i) {
|
||||
s.push_back(PIChar(v[i]));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//! \relatesalso PIChar \brief Output operator to \c std::ostream
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIChar & v) {
|
||||
s << v.toCharPtr();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PIString \brief Return concatenated string
|
||||
inline PIString operator +(const PIString & f, const std::string & str) {
|
||||
PIString s(f);
|
||||
s += StdString2PIString(str);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PIString \brief Return concatenated string
|
||||
inline PIString operator +(const std::string & str, const PIString & f) {
|
||||
return StdString2PIString(str) + f;
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PIString \brief Output operator to std::ostream (cout)
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIString & v) {
|
||||
for (int i = 0; i < v.length(); ++i) {
|
||||
s << v[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PIString \brief Input operator from std::istream (cin)
|
||||
inline std::istream & operator >>(std::istream & s, PIString & v) {
|
||||
std::string ss;
|
||||
s >> ss;
|
||||
v = StdString2PIString(ss);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PIStringList \brief Output operator to std::ostream (cout)
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIStringList & v) {
|
||||
s << PIChar("{");
|
||||
for (uint i = 0; i < v.size(); ++i) {
|
||||
s << PIChar("\"") << v[i] << PIChar("\"");
|
||||
if (i < v.size() - 1) s << PIStringAscii(", ");
|
||||
}
|
||||
s << PIChar("}");
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
#endif // PISTRING_STD_H
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Strings array class
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pistringlist.h"
|
||||
|
||||
|
||||
//! \~\class PIStringList pistringlist.h
|
||||
//! \~\details
|
||||
//!
|
||||
|
||||
|
||||
//! \details
|
||||
//! \~english Example:
|
||||
//! \~russian Пример:
|
||||
//! \~\code
|
||||
//! PIStringList sl("1", "2");
|
||||
//! sl << "3";
|
||||
//! piCout << sl.join(" < "); // 1 < 2 < 3
|
||||
//! \endcode
|
||||
PIString PIStringList::join(const PIString & delim) const {
|
||||
PIString s;
|
||||
for (uint i = 0; i < size(); ++i) {
|
||||
s += at(i);
|
||||
if (i < size() - 1)
|
||||
s += delim;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \details
|
||||
//! \~english Example:
|
||||
//! \~russian Пример:
|
||||
//! \~\code
|
||||
//! PIStringList sl("1", "2");
|
||||
//! sl << "1" << "2" << "3";
|
||||
//! piCout << sl; // {"1", "2", "1", "2", "3"}
|
||||
//! piCout << sl.removeStrings("1"); // {"2", "2", "3"}
|
||||
//! \endcode
|
||||
PIStringList & PIStringList::removeStrings(const PIString & value) {
|
||||
for (uint i = 0; i < size(); ++i) {
|
||||
if (at(i) == value) {
|
||||
remove(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! \details
|
||||
//! \~english Example:
|
||||
//! \~russian Пример:
|
||||
//! \~\code
|
||||
//! PIStringList sl("1", "2");
|
||||
//! sl << "1" << "2" << "3";
|
||||
//! piCout << sl; // {"1", "2", "1", "2", "3"}
|
||||
//! piCout << sl.removeDuplicates(); // {"1", "2", "3"}
|
||||
//! \endcode
|
||||
PIStringList& PIStringList::removeDuplicates() {
|
||||
PIStringList l;
|
||||
PIString s;
|
||||
bool ae;
|
||||
for (int i = 0; i < size_s(); ++i) {
|
||||
ae = false;
|
||||
s = at(i);
|
||||
for (int j = 0; j < l.size_s(); ++j) {
|
||||
if (s != l[j]) continue;
|
||||
ae = true; break;
|
||||
}
|
||||
if (!ae) {
|
||||
l << s;
|
||||
continue;
|
||||
}
|
||||
remove(i);
|
||||
--i;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! \details
|
||||
//! \~english Example:
|
||||
//! \~russian Пример:
|
||||
//! \~\code
|
||||
//! PIStringList sl(" 1 ", "\t2", " 3\n");
|
||||
//! piCout << sl; // {" 1 ", " 2", " 3\n"}
|
||||
//! piCout << sl.trim(); // {"1", "2", "3"}
|
||||
//! \endcode
|
||||
PIStringList & PIStringList::trim() {
|
||||
for (uint i = 0; i < size(); ++i)
|
||||
(*this)[i].trim();
|
||||
return *this;
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
/*! \file pistringlist.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english Based on \a PIDeque<PIString> strings list
|
||||
* \~russian Основанный на \a PIDeque<PIString> массив строк
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Strings array class
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PISTRINGLIST_H
|
||||
#define PISTRINGLIST_H
|
||||
|
||||
#include "pistring.h"
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Based on \a PIDeque<PIString> strings list.
|
||||
//! \~russian Основанный на \a PIDeque<PIString> массив строк.
|
||||
class PIP_EXPORT PIStringList: public PIDeque<PIString>
|
||||
{
|
||||
public:
|
||||
|
||||
//! \~english Contructs an empty strings list
|
||||
//! \~russian Создает пустой список строк
|
||||
PIStringList() {;}
|
||||
|
||||
//! \~english Contructs strings list with one string "str"
|
||||
//! \~russian Создает список строк с одной строкой "str"
|
||||
PIStringList(const PIString & str) {push_back(str);}
|
||||
PIStringList(PIString && str) {push_back(std::move(str));}
|
||||
|
||||
//! \~english Contructs strings list with strings "s0" and "s1"
|
||||
//! \~russian Создает список строк со строками "s0" и "s1"
|
||||
PIStringList(const PIString & s0, const PIString & s1) {push_back(s0); push_back(s1);}
|
||||
PIStringList(PIString && s0, PIString && s1) {push_back(std::move(s0)); push_back(std::move(s1));}
|
||||
|
||||
//! \~english Contructs strings list with strings "s0", "s1" and "s2"
|
||||
//! \~russian Создает список строк со строками "s0", "s1" и "s2"
|
||||
PIStringList(const PIString & s0, const PIString & s1, const PIString & s2) {push_back(s0); push_back(s1); push_back(s2);}
|
||||
PIStringList(PIString && s0, PIString && s1, PIString && s2) {push_back(std::move(s0)); push_back(std::move(s1)); push_back(std::move(s2));}
|
||||
|
||||
//! \~english Contructs strings list with strings "s0", "s1", "s2" and "s3"
|
||||
//! \~russian Создает список строк со строками "s0", "s1", "s2" и "s3"
|
||||
PIStringList(const PIString & s0, const PIString & s1, const PIString & s2, const PIString & s3) {push_back(s0); push_back(s1); push_back(s2); push_back(s3);}
|
||||
PIStringList(PIString && s0, PIString && s1, PIString && s2, PIString && s3) {push_back(std::move(s0)); push_back(std::move(s1)); push_back(std::move(s2)); push_back(std::move(s3));}
|
||||
|
||||
//! \~english Contructs strings list with strings "o"
|
||||
//! \~russian Создает список строк со строками "o"
|
||||
PIStringList(const PIStringList & o): PIDeque<PIString>(o) {}
|
||||
PIStringList(PIStringList && o): PIDeque<PIString>(std::move(o)) {}
|
||||
|
||||
//! \~english Contructs strings list with strings "o"
|
||||
//! \~russian Создает список строк со строками "o"
|
||||
PIStringList(const PIVector<PIString> & o): PIDeque<PIString>() {resize(o.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = o[i];}
|
||||
|
||||
//! \~english Contructs strings list with strings "o"
|
||||
//! \~russian Создает список строк со строками "o"
|
||||
PIStringList(const PIDeque<PIString> & o): PIDeque<PIString>() {resize(o.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = o[i];}
|
||||
|
||||
//! \~english Contructs strings list with strings "init_list" in std::initializer_list format
|
||||
//! \~russian Создает список строк со строками "init_list" в формате std::initializer_list
|
||||
PIStringList(std::initializer_list<PIString> init_list): PIDeque<PIString>(init_list) {}
|
||||
|
||||
|
||||
//! \~english Join all strings in one with delimiter "delim" and returns it
|
||||
//! \~russian Соединяет все строки в одну через разделитель "delim" и возвращает её
|
||||
PIString join(const PIString & delim) const;
|
||||
|
||||
//! \~english Remove all strings equal "value" and returns reference to this
|
||||
//! \~russian Удаляет все строки равные "value" и возвращает ссылку на этот список строк
|
||||
PIStringList & removeStrings(const PIString & value);
|
||||
|
||||
PIStringList & remove(uint num) {PIDeque<PIString>::remove(num); return *this;}
|
||||
PIStringList & remove(uint num, uint count) {PIDeque<PIString>::remove(num, count); return *this;}
|
||||
|
||||
//! \~english Remove duplicated strings and returns reference to this
|
||||
//! \~russian Удаляет все дублированные строки и возвращает ссылку на этот список строк
|
||||
PIStringList & removeDuplicates();
|
||||
|
||||
//! \~english Trim all strings and returns reference to this
|
||||
//! \~russian Подчищает у всех строк пробельные символы в начале и в конце и возвращает ссылку на этот список строк
|
||||
PIStringList & trim();
|
||||
|
||||
//! \~english Returns sum of lengths of all strings
|
||||
//! \~russian Возвращает сумму длин всех строк
|
||||
uint contentSize() {uint s = 0; for (uint i = 0; i < size(); ++i) s += at(i).size(); return s;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator ==(const PIStringList & o) const {if (size() != o.size()) return false; for (size_t i = 0; i < size(); ++i) if (o[i] != (*this)[i]) return false; return true;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator !=(const PIStringList & o) const {return !(o == (*this));}
|
||||
|
||||
//! \~english Assign operator
|
||||
//! \~russian Оператор присваивания
|
||||
PIStringList & operator =(const PIStringList & o) {PIDeque<PIString>::operator=(o); return *this;}
|
||||
|
||||
//! \~english Append string "str"
|
||||
//! \~russian Добавляет строку "str"
|
||||
PIStringList & operator <<(const PIString & str) {append(str); return *this;}
|
||||
PIStringList & operator <<(PIString && str) {append(std::move(str)); return *this;}
|
||||
|
||||
//! \~english Append strings list "sl"
|
||||
//! \~russian Добавляет список строк "sl"
|
||||
PIStringList & operator <<(const PIStringList & sl) {append(sl); return *this;}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIStringList) {
|
||||
s << static_cast<const PIDeque<PIString> &>(v);
|
||||
return s;
|
||||
}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ(PIStringList) {
|
||||
s >> static_cast<PIDeque<PIString> &>(v);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
inline PICout operator <<(PICout s, const PIStringList & v) {s.space(); s.saveAndSetControls(0); s << "{"; for (uint i = 0; i < v.size(); ++i) {s << "\"" << v[i] << "\""; if (i < v.size() - 1) s << ", ";} s << "}"; s.restoreControls(); return s;}
|
||||
|
||||
#endif // PISTRINGLIST_H
|
||||
@@ -1,219 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Unix time
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "pisystemtime.h"
|
||||
#include "pitime.h"
|
||||
#include <ctime>
|
||||
#ifdef QNX
|
||||
# include <time.h>
|
||||
#endif
|
||||
#ifndef MICRO_PIP
|
||||
# include "pisystemtests.h"
|
||||
#elif defined(ARDUINO)
|
||||
# include <Arduino.h>
|
||||
#endif
|
||||
#ifdef WINDOWS
|
||||
extern FILETIME __pi_ftjan1970;
|
||||
long long __PIQueryPerformanceCounter() {LARGE_INTEGER li; QueryPerformanceCounter(&li); return li.QuadPart;}
|
||||
#endif
|
||||
#ifdef MAC_OS
|
||||
//# include <mach/mach_traps.h>
|
||||
//# include <mach/mach.h>
|
||||
# include <mach/clock.h>
|
||||
//# include <crt_externs.h>
|
||||
extern clock_serv_t __pi_mac_clock;
|
||||
#endif
|
||||
#ifdef MICRO_PIP
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
||||
//! \class PISystemTime pisystemtime.h
|
||||
//! \details
|
||||
//! \~english \section PISystemTime_sec0 Synopsis
|
||||
//! \~russian \section PISystemTime_sec0 Краткий обзор
|
||||
//! \~english
|
||||
//! This class provide arithmetic functions for POSIX system time.
|
||||
//! This time represents as seconds and nanosecons in integer formats.
|
||||
//! You can take current system time with function \a PISystemTime::current(),
|
||||
//! compare times, sum or subtract two times, convert time to/from
|
||||
//! seconds, milliseconds, microseconds or nanoseconds.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Этот класс предоставляет арифметику для системного времени в формате POSIX.
|
||||
//! Это время представлено в виде целочисленных секунд и наносекунд.
|
||||
//! Можно взять текущее время с помощью метода \a PISystemTime::current(),
|
||||
//! сравнивать, суммировать и вычитать времена, преобразовывать в/из
|
||||
//! секунд, миллисекунд, микросекунд и наносекунд.
|
||||
//!
|
||||
//! \~english \section PISystemTime_sec1 Example
|
||||
//! \~russian \section PISystemTime_sec1 Пример
|
||||
//! \~\snippet pitimer.cpp system_time
|
||||
//!
|
||||
|
||||
|
||||
//! \class PITimeMeasurer pisystemtime.h
|
||||
//! \details
|
||||
//! \~english \section PITimeMeasurer_sec0 Usage
|
||||
//! \~russian \section PITimeMeasurer_sec0 Использование
|
||||
//! \~english
|
||||
//! Function \a reset() set time mark to current
|
||||
//! system time, then functions "double elapsed_*()" returns time elapsed from this mark.
|
||||
//! These functions can returns nano-, micro-, milli- and seconds with suffixes "n", "u", "m"
|
||||
//! and "s"
|
||||
//!
|
||||
//! \~russian
|
||||
//! Метод \a reset() устанавливает текущую метку системного времени. Далее методы
|
||||
//! "double elapsed_*()" возвращают время, прошедшее от установленной метки.
|
||||
//! Эти методы возвращают нано, микро, милли и секунды с приставками
|
||||
//! "n", "u", "m" и "s".
|
||||
//!
|
||||
|
||||
|
||||
|
||||
|
||||
//! \details
|
||||
//! \warning
|
||||
//! \~english
|
||||
//! Use this function to sleep for difference of system times or constructs system time.
|
||||
//! If you call this function on system time returned with \a PISystemTime::current() thread will be sleep almost forever
|
||||
//! \~russian
|
||||
//! Используйте этот метод для ожидания разниц системных времен или своего времени.
|
||||
//! Если метод будет вызван для системного времени \a PISystemTime::current(), то
|
||||
//! ожидание будет почти бесконечным
|
||||
void PISystemTime::sleep() {
|
||||
piUSleep(piFloord(toMicroseconds()));
|
||||
}
|
||||
|
||||
|
||||
void PISystemTime::toTimespec(void * ts) {
|
||||
#ifndef WINDOWS
|
||||
((timespec*)ts)->tv_sec = seconds;
|
||||
((timespec*)ts)->tv_nsec = nanoseconds;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PISystemTime PISystemTime::abs() const {
|
||||
if (seconds < 0)
|
||||
return PISystemTime(piAbsl(seconds) - 1, 1000000000l - piAbsl(nanoseconds));
|
||||
else
|
||||
return PISystemTime(piAbsl(seconds), piAbsl(nanoseconds));
|
||||
}
|
||||
|
||||
|
||||
PISystemTime PISystemTime::current(bool precise_but_not_system) {
|
||||
#ifdef WINDOWS
|
||||
if (precise_but_not_system) {
|
||||
llong qpc(0);
|
||||
if (__pi_perf_freq > 0) {
|
||||
qpc = __PIQueryPerformanceCounter();
|
||||
return PISystemTime::fromSeconds(qpc / double(__pi_perf_freq));
|
||||
}
|
||||
return PISystemTime();
|
||||
} else {
|
||||
FILETIME ft, sft;
|
||||
# if (_WIN32_WINNT >= 0x0602)
|
||||
GetSystemTimePreciseAsFileTime(&ft);
|
||||
# else
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
# endif
|
||||
sft.dwHighDateTime = ft.dwHighDateTime - __pi_ftjan1970.dwHighDateTime;
|
||||
if (ft.dwLowDateTime < __pi_ftjan1970.dwLowDateTime) {
|
||||
sft.dwLowDateTime = ft.dwLowDateTime + (0xFFFFFFFF - __pi_ftjan1970.dwLowDateTime);
|
||||
sft.dwHighDateTime--;
|
||||
} else
|
||||
sft.dwLowDateTime = ft.dwLowDateTime - __pi_ftjan1970.dwLowDateTime;
|
||||
ullong lt = ullong(sft.dwHighDateTime) * 0x100000000U + ullong(sft.dwLowDateTime);
|
||||
return PISystemTime(lt / 10000000U, (lt % 10000000U) * 100U);
|
||||
}
|
||||
#elif defined(MAC_OS)
|
||||
mach_timespec_t t_cur;
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
#elif defined(MICRO_PIP)
|
||||
timespec t_cur;
|
||||
# ifdef ARDUINO
|
||||
static const uint32_t offSetSinceEpoch_s = 1581897605UL;
|
||||
uint32_t mt = millis();
|
||||
t_cur.tv_sec = offSetSinceEpoch_s + (mt / 1000);
|
||||
t_cur.tv_nsec = (mt - (mt / 1000)) * 1000000UL;
|
||||
# else
|
||||
timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
gettimeofday(&tv, NULL);
|
||||
t_cur.tv_sec = tv.tv_sec;
|
||||
t_cur.tv_nsec = tv.tv_usec * 1000;
|
||||
# endif
|
||||
#else
|
||||
timespec t_cur;
|
||||
clock_gettime(precise_but_not_system ? CLOCK_MONOTONIC : 0, &t_cur);
|
||||
#endif
|
||||
#ifndef WINDOWS
|
||||
return PISystemTime(t_cur.tv_sec, t_cur.tv_nsec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
PITimeMeasurer::PITimeMeasurer() {
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
double PITimeMeasurer::elapsed_n() const {
|
||||
return (PISystemTime::current(true) - t_st).toNanoseconds()
|
||||
#ifndef MICRO_PIP
|
||||
- PISystemTests::time_elapsed_ns
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
double PITimeMeasurer::elapsed_u() const {
|
||||
return (PISystemTime::current(true) - t_st).toMicroseconds()
|
||||
#ifndef MICRO_PIP
|
||||
- PISystemTests::time_elapsed_ns / 1.E+3
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
double PITimeMeasurer::elapsed_m() const {
|
||||
return (PISystemTime::current(true) - t_st).toMilliseconds()
|
||||
#ifndef MICRO_PIP
|
||||
- PISystemTests::time_elapsed_ns / 1.E+6
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
double PITimeMeasurer::elapsed_s() const {
|
||||
return (PISystemTime::current(true) - t_st).toSeconds()
|
||||
#ifndef MICRO_PIP
|
||||
- PISystemTests::time_elapsed_ns / 1.E+9
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
PISystemTime PITimeMeasurer::elapsed() const {
|
||||
return (PISystemTime::current(true) - t_st);
|
||||
}
|
||||
@@ -1,253 +0,0 @@
|
||||
/*! \file pisystemtime.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english System time structs and methods
|
||||
* \~russian Типы и методы системного времени
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Time structs
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PISYSTEMTIME_H
|
||||
#define PISYSTEMTIME_H
|
||||
|
||||
|
||||
#include "pistring.h"
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english System time with nanosecond precision.
|
||||
//! \~russian Системное время с точностью до наносекунд.
|
||||
class PIP_EXPORT PISystemTime {
|
||||
public:
|
||||
|
||||
//! \~english Contructs time with seconds and nanoseconds = 0
|
||||
//! \~russian Создает время с секундами и наносекундами = 0
|
||||
PISystemTime() {seconds = nanoseconds = 0;}
|
||||
|
||||
//! \~english Contructs time with "s" seconds and "ns" nanoseconds
|
||||
//! \~russian Создает время с секундами "s" и наносекундами "ns"
|
||||
PISystemTime(int s, int ns) {seconds = s; nanoseconds = ns; checkOverflows();}
|
||||
|
||||
|
||||
//! \~english Returns time value in seconds
|
||||
//! \~russian Возвращает значение времени в секундах
|
||||
double toSeconds() const {return double(seconds) + nanoseconds / 1.e+9;}
|
||||
|
||||
//! \~english Returns time value in milliseconds
|
||||
//! \~russian Возвращает значение времени в миллисекундах
|
||||
double toMilliseconds() const {return seconds * 1.e+3 + nanoseconds / 1.e+6;}
|
||||
|
||||
//! \~english Returns time value in microseconds
|
||||
//! \~russian Возвращает значение времени в микросекундах
|
||||
double toMicroseconds() const {return seconds * 1.e+6 + nanoseconds / 1.e+3;}
|
||||
|
||||
//! \~english Returns time value in nanoseconds
|
||||
//! \~russian Возвращает значение времени в наносекундах
|
||||
double toNanoseconds() const {return seconds * 1.e+9 + double(nanoseconds);}
|
||||
|
||||
|
||||
//! \~english Add to time "v" seconds
|
||||
//! \~russian Добавляет ко времени "v" секунд
|
||||
PISystemTime & addSeconds(double v) {*this += fromSeconds(v); return *this;}
|
||||
|
||||
//! \~english Add to time "v" milliseconds
|
||||
//! \~russian Добавляет ко времени "v" миллисекунд
|
||||
PISystemTime & addMilliseconds(double v) {*this += fromMilliseconds(v); return *this;}
|
||||
|
||||
//! \~english Add to time "v" microseconds
|
||||
//! \~russian Добавляет ко времени "v" микросекунд
|
||||
PISystemTime & addMicroseconds(double v) {*this += fromMicroseconds(v); return *this;}
|
||||
|
||||
//! \~english Add to time "v" nanoseconds
|
||||
//! \~russian Добавляет ко времени "v" наносекунд
|
||||
PISystemTime & addNanoseconds(double v) {*this += fromNanoseconds(v); return *this;}
|
||||
|
||||
|
||||
//! \~english Sleep for this time
|
||||
//! \~russian Ожидать это время
|
||||
void sleep();
|
||||
|
||||
//! \~english On *nix system assign current value to timespec struct
|
||||
//! \~russian На *nix системах присваивает время к timespec структуре
|
||||
void toTimespec(void * ts);
|
||||
|
||||
//! \~english Returns copy of this time with absolutely values of s and ns
|
||||
//! \~russian Возвращает копию времени с модулем значения
|
||||
PISystemTime abs() const;
|
||||
|
||||
//! \~english Returns sum of this time with "t"
|
||||
//! \~russian Возвращает сумму этого времени с "t"
|
||||
PISystemTime operator +(const PISystemTime & t) const {PISystemTime tt(*this); tt.seconds += t.seconds; tt.nanoseconds += t.nanoseconds; tt.checkOverflows(); return tt;}
|
||||
|
||||
//! \~english Returns difference between this time and "t"
|
||||
//! \~russian Возвращает разницу между этим временем и "t"
|
||||
PISystemTime operator -(const PISystemTime & t) const {PISystemTime tt(*this); tt.seconds -= t.seconds; tt.nanoseconds -= t.nanoseconds; tt.checkOverflows(); return tt;}
|
||||
|
||||
//! \~english Returns multiplication between this time and "t"
|
||||
//! \~russian Возвращает это временя умноженное на "t"
|
||||
PISystemTime operator *(const double & v) const {return fromMilliseconds(toMilliseconds() * v);}
|
||||
|
||||
//! \~english Returns division between this time and "t"
|
||||
//! \~russian Возвращает это временя поделённое на "t"
|
||||
PISystemTime operator /(const double & v) const {return fromMilliseconds(toMilliseconds() / v);}
|
||||
|
||||
//! \~english Add to time "t"
|
||||
//! \~russian Добавляет ко времени "t"
|
||||
PISystemTime & operator +=(const PISystemTime & t) {seconds += t.seconds; nanoseconds += t.nanoseconds; checkOverflows(); return *this;}
|
||||
|
||||
//! \~english Subtract from time "t"
|
||||
//! \~russian Вычитает из времени "t"
|
||||
PISystemTime & operator -=(const PISystemTime & t) {seconds -= t.seconds; nanoseconds -= t.nanoseconds; checkOverflows(); return *this;}
|
||||
|
||||
//! \~english Multiply time by "v"
|
||||
//! \~russian Умножает время на "v"
|
||||
PISystemTime & operator *=(const double & v) {*this = fromMilliseconds(toMilliseconds() * v); return *this;}
|
||||
|
||||
//! \~english Divide time by "v"
|
||||
//! \~russian Делит время на "v"
|
||||
PISystemTime & operator /=(const double & v) {*this = fromMilliseconds(toMilliseconds() / v); return *this;}
|
||||
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator ==(const PISystemTime & t) const {return ((seconds == t.seconds) && (nanoseconds == t.nanoseconds));}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator !=(const PISystemTime & t) const {return ((seconds != t.seconds) || (nanoseconds != t.nanoseconds));}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator >(const PISystemTime & t) const {if (seconds == t.seconds) return nanoseconds > t.nanoseconds; return seconds > t.seconds;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator <(const PISystemTime & t) const {if (seconds == t.seconds) return nanoseconds < t.nanoseconds; return seconds < t.seconds;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator >=(const PISystemTime & t) const {if (seconds == t.seconds) return nanoseconds >= t.nanoseconds; return seconds >= t.seconds;}
|
||||
|
||||
//! \~english Compare operator
|
||||
//! \~russian Оператор сравнения
|
||||
bool operator <=(const PISystemTime & t) const {if (seconds == t.seconds) return nanoseconds <= t.nanoseconds; return seconds <= t.seconds;}
|
||||
|
||||
|
||||
//! \~english Contructs time from seconds "v"
|
||||
//! \~russian Создает время из "v" секунд
|
||||
static PISystemTime fromSeconds(double v) {int s = piFloord(v); return PISystemTime(s, int((v - s) * 1000000000.));}
|
||||
|
||||
//! \~english Contructs time from milliseconds "v"
|
||||
//! \~russian Создает время из "v" миллисекунд
|
||||
static PISystemTime fromMilliseconds(double v) {int s = piFloord(v / 1000.); return PISystemTime(s, int((v / 1000. - s) * 1000000000.));}
|
||||
|
||||
//! \~english Contructs time from microseconds "v"
|
||||
//! \~russian Создает время из "v" микросекунд
|
||||
static PISystemTime fromMicroseconds(double v) {int s = piFloord(v / 1000000.); return PISystemTime(s, int((v / 1000000. - s) * 1000000000.));}
|
||||
|
||||
//! \~english Contructs time from nanoseconds "v"
|
||||
//! \~russian Создает время из "v" наносекунд
|
||||
static PISystemTime fromNanoseconds(double v) {int s = piFloord(v / 1000000000.); return PISystemTime(s, int((v / 1000000000. - s) * 1000000000.));}
|
||||
|
||||
//! \~english Returns current system time
|
||||
//! \~russian Возвращает текущее системное время
|
||||
static PISystemTime current(bool precise_but_not_system = false);
|
||||
|
||||
//! \~english Seconds time part
|
||||
//! \~russian Секунды времени
|
||||
int seconds;
|
||||
|
||||
//! \~english Nanoseconds time part
|
||||
//! \~russian Наносекунды времени
|
||||
int nanoseconds;
|
||||
|
||||
private:
|
||||
void checkOverflows() {while (nanoseconds >= 1000000000) {nanoseconds -= 1000000000; seconds++;} while (nanoseconds < 0) {nanoseconds += 1000000000; seconds--;}}
|
||||
|
||||
};
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english \brief Output operator to PICout
|
||||
//! \~russian \brief Оператор вывода в PICout
|
||||
inline PICout operator <<(PICout s, const PISystemTime & v) {s.space(); s.saveAndSetControls(0); s << "(" << v.seconds << " s, " << v.nanoseconds << " ns)"; s.restoreControls(); return s;}
|
||||
|
||||
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Time measurements.
|
||||
//! \~russian Измерение времени.
|
||||
class PIP_EXPORT PITimeMeasurer {
|
||||
public:
|
||||
PITimeMeasurer();
|
||||
|
||||
/** \brief Set internal time mark to current system time
|
||||
* \details This function used for set start time mark. Later
|
||||
* you can find out elapsed time from this time mark to any
|
||||
* moment of time with \a elapsed_s(), \a elapsed_m(),
|
||||
* \a elapsed_u() or \a elapsed_n() functions.
|
||||
* \sa \a elapsed_s(), \a elapsed_m(), \a elapsed_u(), \a elapsed_n() */
|
||||
void reset() {t_st = PISystemTime::current(true);}
|
||||
|
||||
//! \brief Returns nanoseconds elapsed from last \a reset() execution or from timer measurer creation.
|
||||
double elapsed_n() const;
|
||||
|
||||
//! \brief Returns microseconds elapsed from last \a reset() execution or from timer measurer creation.
|
||||
double elapsed_u() const;
|
||||
|
||||
//! \brief Returns milliseconds elapsed from last \a reset() execution or from timer measurer creation.
|
||||
double elapsed_m() const;
|
||||
|
||||
//! \brief Returns seconds elapsed from last \a reset() execution or from timer measurer creation.
|
||||
double elapsed_s() const;
|
||||
|
||||
//! \brief Returns PISystemTime elapsed from last \a reset() execution or from timer measurer creation.
|
||||
PISystemTime elapsed() const;
|
||||
|
||||
double reset_time_n() const {return t_st.toNanoseconds();}
|
||||
double reset_time_u() const {return t_st.toMicroseconds();}
|
||||
double reset_time_m() const {return t_st.toMilliseconds();}
|
||||
double reset_time_s() const {return t_st.toSeconds();}
|
||||
|
||||
//! \brief Returns time mark of last \a reset() execution or timer measurer creation.
|
||||
PISystemTime reset_time() {return t_st;}
|
||||
|
||||
//! \brief Returns nanoseconds representation of current system time.
|
||||
static double elapsed_system_n() {return PISystemTime::current(true).toNanoseconds();}
|
||||
|
||||
//! \brief Returns microseconds representation of current system time.
|
||||
static double elapsed_system_u() {return PISystemTime::current(true).toMicroseconds();}
|
||||
|
||||
//! \brief Returns milliseconds representation of current system time.
|
||||
static double elapsed_system_m() {return PISystemTime::current(true).toMilliseconds();}
|
||||
|
||||
//! \brief Returns seconds representation of current system time.
|
||||
static double elapsed_system_s() {return PISystemTime::current(true).toSeconds();}
|
||||
|
||||
//! \brief Returns time mark of current system time.
|
||||
static PISystemTime elapsed_system() {return PISystemTime::current(true);}
|
||||
|
||||
private:
|
||||
PISystemTime t_st, t_cur;
|
||||
|
||||
};
|
||||
|
||||
#endif // PITIME_H
|
||||
@@ -1,341 +0,0 @@
|
||||
/*! \file pitextstream.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english Text serialization functionality over PIBinaryStream
|
||||
* \~russian Функциональность текстовой сериализации поверх PIBinaryStream
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Text serialization functionality over PIBinaryStream
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PITEXTSTREAM_H
|
||||
#define PITEXTSTREAM_H
|
||||
|
||||
#include "pistring.h"
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Text serialization functionality over PIBinaryStream.
|
||||
//! \~russian Функциональность текстовой сериализации поверх PIBinaryStream.
|
||||
template<typename P>
|
||||
class PITextStream {
|
||||
public:
|
||||
|
||||
//! \~english Floating-point numbers write format
|
||||
//! \~russian Формат записи чисел с плавающей точкой
|
||||
enum FloatFormat {
|
||||
DecimalFormat /** \~english Decimal format, "*.*" \~russian Десятичный формат, "*.*" */ = 'f',
|
||||
ExponentFormat /** \~english Exponential format, "*e+-<E>" \~russian Экспонентный формат, "*e+-<E>" */ = 'e'
|
||||
};
|
||||
|
||||
//! \~english String encoding
|
||||
//! \~russian Кодировка строк
|
||||
enum Encoding {
|
||||
System /** \~english System encoding \~russian Системная кодировка */,
|
||||
UTF8 /** \~english UTF-8 encoding \~russian Кодировка UTF-8 */,
|
||||
};
|
||||
|
||||
//! \~english Construct text stream binded to "stream_"
|
||||
//! \~russian Возвращает привязанный к "stream_" текстовый поток
|
||||
PITextStream(PIBinaryStream<P> * stream_) {setStream(stream_);}
|
||||
|
||||
//! \~english Returns binded PIBinaryStream
|
||||
//! \~russian Возвращает привязанный PIBinaryStream
|
||||
PIBinaryStream<P> * stream() const {return s;}
|
||||
void setStream(PIBinaryStream<P> * stream_) {
|
||||
s = stream_;
|
||||
is_end = false;
|
||||
}
|
||||
|
||||
//! \~english Returns if end of stream reached
|
||||
//! \~russian Возвращает достигнут ли конец потока
|
||||
bool isEnd() const {return is_end;}
|
||||
|
||||
//! \~english Returns read/write encoding
|
||||
//! \~russian Возвращает кодировку чтения/записи
|
||||
Encoding encoding() const {return enc;}
|
||||
|
||||
//! \~english Set read/write encoding, default UTF8
|
||||
//! \~russian Устанавливает кодировку чтения/записи, по умолчанию UTF8
|
||||
void setEncoding(Encoding e) {enc = e;}
|
||||
|
||||
//! \~english Returns float numbers write format
|
||||
//! \~russian Возвращает формат записи чисел с плавающей точкой
|
||||
FloatFormat floatFormat() const {return format_;}
|
||||
|
||||
//! \~english Set float numbers write format, default DecimalFormat
|
||||
//! \~russian Устанавливает формат записи чисел с плавающей точкой, по умолчанию DecimalFormat
|
||||
void setFloatFormat(FloatFormat format) {format_ = format;}
|
||||
|
||||
//! \~english Returns float numbers write precision
|
||||
//! \~russian Возвращает точность записи чисел с плавающей точкой
|
||||
int floatPrecision() const {return prec_;}
|
||||
|
||||
//! \~english Set float numbers write precision to "prec_" digits, default 5
|
||||
//! \~russian Устанавливает точность записи чисел с плавающей точкой, по умолчанию 5
|
||||
void setFloatPrecision(int prec) {prec_ = prec;}
|
||||
|
||||
//! \~english Append space
|
||||
//! \~russian Добавляет пробел
|
||||
PITextStream<P> & space() {s->binaryStreamAppend(' '); return *this;}
|
||||
|
||||
//! \~english Append new line
|
||||
//! \~russian Добавляет новую строку
|
||||
PITextStream<P> & newLine() {s->binaryStreamAppend('\n'); return *this;}
|
||||
|
||||
//! \~english Append "v" string
|
||||
//! \~russian Добавляет строку "v"
|
||||
void append(const PIString & v) {
|
||||
if (v.isEmpty()) return;
|
||||
PIByteArray d;
|
||||
switch (enc) {
|
||||
case System: d = v.toSystem(); break;
|
||||
case UTF8 : d = v.toUTF8(); break;
|
||||
}
|
||||
s->binaryStreamAppend(d.data(), d.size());
|
||||
}
|
||||
|
||||
//! \~english Append "v" as ASCII
|
||||
//! \~russian Добавляет "v" как ASCII
|
||||
void append(const PIConstChars & v) {if (!v.isEmpty()) s->binaryStreamAppend(v.data(), v.size());}
|
||||
|
||||
//! \~english Append "v" char as character
|
||||
//! \~russian Добавляет "v" как символ
|
||||
void append(char v) {s->binaryStreamAppend(v);}
|
||||
|
||||
//! \~english Append "v" as ASCII
|
||||
//! \~russian Добавляет "v" как ASCII
|
||||
void append(const char * v) {append(PIConstChars(v));}
|
||||
|
||||
//! \~english Append boolean, "true" of "false"
|
||||
//! \~russian Добавляет логическое, "true" of "false"
|
||||
void append(bool v) {append(v ? "true" : "false");}
|
||||
|
||||
//! \~english Append integer
|
||||
//! \~russian Добавляет целое
|
||||
void append(int v) {append(PIString::fromNumber(v));}
|
||||
|
||||
//! \~english Append integer
|
||||
//! \~russian Добавляет целое
|
||||
void append(llong v) {append(PIString::fromNumber(v));}
|
||||
|
||||
//! \~english Append floating-point number, using \a floatFormat() and \a floatPrecision()
|
||||
//! \~russian Добавляет число с плавающей точкой, используя \a floatFormat() и \a floatPrecision()
|
||||
void append(float v) {append(PIString::fromNumber(v, (char)format_, prec_));}
|
||||
|
||||
//! \~english Append floating-point number, using \a floatFormat() and \a floatPrecision()
|
||||
//! \~russian Добавляет число с плавающей точкой, используя \a floatFormat() и \a floatPrecision()
|
||||
void append(double v) {append(PIString::fromNumber(v, (char)format_, prec_));}
|
||||
|
||||
|
||||
//! \~english Read character
|
||||
//! \~russian Читает символ
|
||||
char readChar(bool * rok) {
|
||||
char ret;
|
||||
bool ok = s->binaryStreamTake(&ret, sizeof(ret));
|
||||
if (!ok) is_end = true;
|
||||
if (rok) *rok = ok;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! \~english Read line
|
||||
//! \~russian Читает строку
|
||||
PIString readLine() {
|
||||
PIByteArray ret;
|
||||
bool ok = true;
|
||||
for (;;) {
|
||||
char b = readChar(&ok);
|
||||
if (!ok || b == '\n') break;
|
||||
if (b != '\r')
|
||||
ret.append((uchar)b);
|
||||
}
|
||||
return fromBytes(ret);
|
||||
}
|
||||
|
||||
//! \~english Read word, skip leading whitespaces, until next whitespace
|
||||
//! \~russian Читает слово, пропуская начальные пробельные символы, до следующего пробельного символа
|
||||
PIString readWord() {
|
||||
static PIConstChars spaces(" \t\n\r");
|
||||
return readUntil(spaces);
|
||||
}
|
||||
|
||||
//! \~english Read C-word, skip leading and until non C-identifier
|
||||
//! \~russian Читает C-слово, пропуская начальные и до следующих символов, не являющихся C-идентификаторами
|
||||
PIString readCWord() {
|
||||
static PIConstChars chars(" \t\n\r:;%$&#@!?~/*-+=.,\\\"'`[](){}<>");
|
||||
return readUntil(chars);
|
||||
}
|
||||
|
||||
private:
|
||||
PIString fromBytes(const PIByteArray & ba) {
|
||||
switch (enc) {
|
||||
case System: return PIString::fromSystem(ba);
|
||||
case UTF8 : return PIString::fromUTF8(ba);
|
||||
}
|
||||
return PIString();
|
||||
}
|
||||
PIString readUntil(const PIConstChars & chars) {
|
||||
//static PIConstChars spaces(" \t\n\r");
|
||||
bool ok = true;
|
||||
char c = skipWhile(chars, &ok);
|
||||
if (!ok) return PIString();
|
||||
PIByteArray ret;
|
||||
ret.append((uchar)c);
|
||||
for (;;) {
|
||||
c = readChar(&ok);
|
||||
if (!ok || chars.contains(c)) break;
|
||||
ret.append((uchar)c);
|
||||
}
|
||||
return fromBytes(ret);
|
||||
}
|
||||
// returns first non-"chars" char
|
||||
char skipWhile(const PIConstChars & chars, bool * rok) {
|
||||
bool ok = true;
|
||||
char c = 0;
|
||||
for (;;) {
|
||||
c = readChar(&ok);
|
||||
if (!ok || !chars.contains(c)) break;
|
||||
}
|
||||
if (rok) *rok = ok;
|
||||
return c;
|
||||
}
|
||||
|
||||
PIBinaryStream<P> * s;
|
||||
Encoding enc = UTF8;
|
||||
FloatFormat format_ = DecimalFormat;
|
||||
bool is_end = false;
|
||||
int prec_ = 5;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//! \~english Returns PITextStream for binary stream "stream"
|
||||
//! \~russian Возвращает PITextStream для бинарного потока "stream"
|
||||
template<typename P>
|
||||
inline PITextStream<P> createPITextStream(PIBinaryStream<P> * stream) {return PITextStream<P>(stream);}
|
||||
|
||||
|
||||
//! \~english Append boolean
|
||||
//! \~russian Добавляет логическое
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, bool v) {s.append(v); return s;}
|
||||
|
||||
//! \~english Append character
|
||||
//! \~russian Добавляет символ
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, char v) {s.append(v); return s;}
|
||||
|
||||
//! \~english Append integer
|
||||
//! \~russian Добавляет целое
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, uchar v) {s.append((int)v); return s;}
|
||||
|
||||
//! \~english Append integer
|
||||
//! \~russian Добавляет целое
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, short v) {s.append((int)v); return s;}
|
||||
|
||||
//! \~english Append integer
|
||||
//! \~russian Добавляет целое
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, ushort v) {s.append((int)v); return s;}
|
||||
|
||||
//! \~english Append integer
|
||||
//! \~russian Добавляет целое
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, int v) {s.append((int)v); return s;}
|
||||
|
||||
//! \~english Append integer
|
||||
//! \~russian Добавляет целое
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, uint v) {s.append((int)v); return s;}
|
||||
|
||||
//! \~english Append integer
|
||||
//! \~russian Добавляет целое
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, llong v) {s.append((llong)v); return s;}
|
||||
|
||||
//! \~english Append integer
|
||||
//! \~russian Добавляет целое
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, ullong v) {s.append((llong)v); return s;}
|
||||
|
||||
//! \~english Append floating-point number
|
||||
//! \~russian Добавляет число с плавающей точкой
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, float v) {s.append(v); return s;}
|
||||
|
||||
//! \~english Append floating-point number
|
||||
//! \~russian Добавляет число с плавающей точкой
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, double v) {s.append(v); return s;}
|
||||
|
||||
|
||||
//! \~english Append string
|
||||
//! \~russian Добавляет строку
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, const char * v) {s.append(v); return s;}
|
||||
|
||||
//! \~english Append string
|
||||
//! \~russian Добавляет строку
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, const PIConstChars & v) {s.append(v); return s;}
|
||||
|
||||
//! \~english Append string
|
||||
//! \~russian Добавляет строку
|
||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, const PIString & v) {s.append(v); return s;}
|
||||
|
||||
|
||||
//! \~english Read word as bool
|
||||
//! \~russian Читает слово как логическое
|
||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, bool & v) {v = s.readWord().toBool(); return s;}
|
||||
|
||||
//! \~english Read character
|
||||
//! \~russian Читает символ
|
||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, char & v) {v = s.readChar(); return s;}
|
||||
|
||||
//! \~english Read word as integer
|
||||
//! \~russian Читает слово как целое
|
||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, uchar & v) {v = s.readWord().toUInt(); return s;}
|
||||
|
||||
//! \~english Read word as integer
|
||||
//! \~russian Читает слово как целое
|
||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, short & v) {v = s.readWord().toInt(); return s;}
|
||||
|
||||
//! \~english Read word as integer
|
||||
//! \~russian Читает слово как целое
|
||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, ushort & v) {v = s.readWord().toUInt(); return s;}
|
||||
|
||||
//! \~english Read word as integer
|
||||
//! \~russian Читает слово как целое
|
||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, int & v) {v = s.readWord().toInt(); return s;}
|
||||
|
||||
//! \~english Read word as integer
|
||||
//! \~russian Читает слово как целое
|
||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, uint & v) {v = s.readWord().toUInt(); return s;}
|
||||
|
||||
//! \~english Read word as integer
|
||||
//! \~russian Читает слово как целое
|
||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, llong & v) {v = s.readWord().toLLong(); return s;}
|
||||
|
||||
//! \~english Read word as integer
|
||||
//! \~russian Читает слово как целое
|
||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, ullong & v) {v = s.readWord().toULLong(); return s;}
|
||||
|
||||
//! \~english Read word as floating-point number
|
||||
//! \~russian Читает слово как число с плавающей точкой
|
||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, float & v) {v = s.readWord().toFloat(); return s;}
|
||||
|
||||
//! \~english Read word as floating-point number
|
||||
//! \~russian Читает слово как число с плавающей точкой
|
||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, double & v) {v = s.readWord().toDouble(); return s;}
|
||||
|
||||
|
||||
//! \~english Read word
|
||||
//! \~russian Читает слово
|
||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, PIString & v) {v = s.readWord(); return s;}
|
||||
|
||||
#endif
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "pitime.h"
|
||||
#ifdef QNX
|
||||
# include <time.h>
|
||||
#endif
|
||||
#ifndef MICRO_PIP
|
||||
# include "pisystemtests.h"
|
||||
#elif defined(ARDUINO)
|
||||
# include <Arduino.h>
|
||||
#endif
|
||||
#ifdef MICRO_PIP
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
||||
//! \details
|
||||
//! \~english
|
||||
//! This function consider \c "usleep" offset
|
||||
//! on QNX/Linux/Mac, which is calculated with
|
||||
//! \a pip_sys_test program. If this is correct
|
||||
//! offset value in system config, this function
|
||||
//! wait \b exactly "usecs" microseconds.
|
||||
//! \~russian
|
||||
//! Этот метод учитывает смещение \c "usleep"
|
||||
//! на QNX/Linux/Mac, которое расчитывается с помощью
|
||||
//! утилиты \a pip_sys_test. Если это значение в системном
|
||||
//! конфиге действительно, то этот метод будет ожидать
|
||||
//! \b точно "usecs" микросекунд.
|
||||
void piUSleep(int usecs) {
|
||||
if (usecs <= 0) return;
|
||||
#ifdef WINDOWS
|
||||
//printf("Sleep %d\n", usecs / 1000);
|
||||
if (usecs > 0) Sleep(usecs / 1000);
|
||||
//printf("Sleep end");
|
||||
#else
|
||||
# ifdef FREERTOS
|
||||
vTaskDelay(usecs / 1000 / portTICK_PERIOD_MS);
|
||||
# else
|
||||
usecs -= PISystemTests::usleep_offset_us;
|
||||
if (usecs > 0) usleep(usecs);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*! \file pitime.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english System time, time and date
|
||||
* \~russian Системное время, время и дата
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PITIME_H
|
||||
#define PITIME_H
|
||||
|
||||
#include "pidatetime.h"
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~english Precise sleep for "usecs" microseconds
|
||||
//! \~russian Точно ожидает "usecs" микросекунд
|
||||
PIP_EXPORT void piUSleep(int usecs); // on !Windows consider constant "usleep" offset
|
||||
|
||||
//! \ingroup Core
|
||||
//! \brief
|
||||
//! \~english Precise sleep for "msecs" milliseconds
|
||||
//! \~russian Точно ожидает "msecs" миллисекунд
|
||||
//! \~\details
|
||||
//! \~english This function exec \a piUSleep (msecs * 1000)
|
||||
//! \~russian Этот метод вызывает \a piUSleep (msecs * 1000)
|
||||
inline void piMSleep(double msecs) {piUSleep(int(msecs * 1000.));} // on !Windows consider constant "usleep" offset
|
||||
|
||||
//! \ingroup Core
|
||||
//! \brief
|
||||
//! \~english Precise sleep for "secs" seconds
|
||||
//! \~russian Точно ожидает "secs" секунд
|
||||
//! \~\details
|
||||
//! \~english This function exec \a piUSleep (msecs * 1000000)
|
||||
//! \~russian Этот метод вызывает \a piUSleep (msecs * 1000000)
|
||||
inline void piSleep(double secs) {piUSleep(int(secs * 1000000.));} // on !Windows consider constant "usleep" offset
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~english Shortest available on current system sleep
|
||||
//! \~russian Наименее возможное для данной системы по длительности ожидание
|
||||
inline void piMinSleep() {piMSleep(PIP_MIN_MSLEEP);}
|
||||
|
||||
#endif // PITIME_H
|
||||
@@ -1,88 +0,0 @@
|
||||
/*! \file pitime_win.h
|
||||
* \ingroup Core
|
||||
* \brief
|
||||
* \~english PITime conversions for Windows
|
||||
* \~russian Преобразования PITime для Windows
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
PITime conversions for Windows
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PITIME_WIN_H
|
||||
#define PITIME_WIN_H
|
||||
|
||||
#include "pibase.h"
|
||||
#ifdef WINDOWS
|
||||
|
||||
#include "pitime.h"
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
inline PISystemTime FILETIME2PISystemTime(const FILETIME &t) {
|
||||
PISystemTime st;
|
||||
ullong lt = ullong(t.dwHighDateTime) * 0x100000000U + ullong(t.dwLowDateTime);
|
||||
st.seconds = lt / 10000000U;
|
||||
st.nanoseconds = (lt % 10000000U) * 100U;
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline PIDateTime SYSTEMTIME2PIDateTime(const SYSTEMTIME &t) {
|
||||
PIDateTime dt;
|
||||
dt.year = t.wYear;
|
||||
dt.month = t.wMonth;
|
||||
dt.day = t.wDay;
|
||||
dt.hours = t.wHour;
|
||||
dt.minutes = t.wMinute;
|
||||
dt.seconds = t.wSecond;
|
||||
dt.milliseconds = t.wMilliseconds;
|
||||
return dt;
|
||||
}
|
||||
|
||||
inline PIDateTime FILETIME2PIDateTime(const FILETIME &t) {
|
||||
FILETIME lt;
|
||||
SYSTEMTIME st;
|
||||
FileTimeToLocalFileTime(&t, <);
|
||||
FileTimeToSystemTime(<, &st);
|
||||
return SYSTEMTIME2PIDateTime(st);
|
||||
}
|
||||
|
||||
inline SYSTEMTIME PIDateTime2SYSTEMTIME(const PIDateTime &dt) {
|
||||
SYSTEMTIME st;
|
||||
st.wYear = dt.year;
|
||||
st.wMonth = dt.month;
|
||||
st.wDay = dt.day;
|
||||
st.wHour = dt.hours;
|
||||
st.wMinute = dt.minutes;
|
||||
st.wSecond = dt.seconds;
|
||||
st.wMilliseconds = dt.milliseconds;
|
||||
return st;
|
||||
}
|
||||
|
||||
inline FILETIME PIDateTime2FILETIME(const PIDateTime &dt) {
|
||||
FILETIME lt, ret;
|
||||
SYSTEMTIME st = PIDateTime2SYSTEMTIME(dt);
|
||||
SystemTimeToFileTime(&st, <);
|
||||
LocalFileTimeToFileTime(<, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // WINDOWS
|
||||
#endif // PITIME_WIN_H
|
||||
@@ -1,939 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Variant type
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pivariant.h"
|
||||
|
||||
|
||||
//! \class PIVariant pivariant.h
|
||||
//! \details
|
||||
//! \~english \section PIVariant_sec0 Synopsis
|
||||
//! \~russian \section PIVariant_sec0 Краткий обзор
|
||||
//! \~english
|
||||
//! This class provides general type that can contains all standard types, some
|
||||
//! PIP types or custom type. In case of standard types this class also provides
|
||||
//! convertions between them.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Этот класс предоставляет некий общий тип, который может содержать все стандартные тип,
|
||||
//! некоторые типы PIP, а также любой свой тип. В случае стандартных типов предоставляется
|
||||
//! автоматическое преобразование между ними.
|
||||
//!
|
||||
//! \~english \section PIVariant_sec1 Usage
|
||||
//! \~russian \section PIVariant_sec1 Использование
|
||||
//! \~english
|
||||
//! %PIVariant useful if you want pass many variables with different types in
|
||||
//! single array, or type may vary from case to case, e.g.:
|
||||
//!
|
||||
//! \~russian
|
||||
//! %PIVariant полезен когда надо передать несколько разнотипных значений
|
||||
//! одним массивом, или тип заранее неизвестен, например:
|
||||
//!
|
||||
//! \~\code{cpp}
|
||||
//! PIVector<PIVariant> array;
|
||||
//! array << PIVariant(10) << PIVariant(1.61) << PIVariant(true) << PIVariant("0xFF");
|
||||
//! piCout << array;
|
||||
//! for (auto i: array)
|
||||
//! piCout << i.toInt();
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english Result:
|
||||
//! \~russian Результат:
|
||||
//! \~\code{cpp}
|
||||
//! {PIVariant(Int, 10), PIVariant(Double, 1,61), PIVariant(Bool, true), PIVariant(String, 0xFF)}
|
||||
//! 10
|
||||
//! 1
|
||||
//! 1
|
||||
//! 255
|
||||
//! \endcode
|
||||
//!
|
||||
|
||||
|
||||
#ifdef CUSTOM_PIVARIANT
|
||||
PIMap<PIString, __PIVariantInfo__ * > * __PIVariantInfoStorage__::map = 0;
|
||||
#endif
|
||||
|
||||
|
||||
PIVariant::PIVariant() {
|
||||
_type = PIVariant::pivInvalid;
|
||||
_info = 0;
|
||||
}
|
||||
|
||||
|
||||
PIVariant::PIVariant(const PIVariant & v) {
|
||||
_type = v._type;
|
||||
_content = v._content;
|
||||
#ifdef CUSTOM_PIVARIANT
|
||||
_info = v._info;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PIVariant::PIVariant(PIVariant && v) {
|
||||
swap(v);
|
||||
}
|
||||
|
||||
|
||||
void PIVariant::setValueFromString(const PIString & v) {
|
||||
switch (_type) {
|
||||
case PIVariant::pivBool: {setValue(v.toBool());} break;
|
||||
case PIVariant::pivChar: {setValue(v.toChar());} break;
|
||||
case PIVariant::pivUChar: {setValue((uchar)v.toChar());} break;
|
||||
case PIVariant::pivShort: {setValue(v.toShort());} break;
|
||||
case PIVariant::pivUShort: {setValue(v.toUShort());} break;
|
||||
case PIVariant::pivInt: {setValue(v.toInt());} break;
|
||||
case PIVariant::pivUInt: {setValue(v.toUInt());} break;
|
||||
case PIVariant::pivLLong: {setValue(v.toLLong());} break;
|
||||
case PIVariant::pivULLong: {setValue(v.toULLong());} break;
|
||||
case PIVariant::pivFloat: {setValue(v.toFloat());} break;
|
||||
case PIVariant::pivDouble: {setValue(v.toDouble());} break;
|
||||
case PIVariant::pivLDouble: {setValue(v.toLDouble());} break;
|
||||
case PIVariant::pivTime: {} break; // TODO
|
||||
case PIVariant::pivDate: {} break; // TODO
|
||||
case PIVariant::pivDateTime: {} break; // TODO
|
||||
case PIVariant::pivString: {setValue(v);} break;
|
||||
case PIVariant::pivStringList: {setValue(v.split("%|%"));} break;
|
||||
case PIVariant::pivEnum: {PIVariantTypes::Enum r = toEnum(); r.selectName(v); setValue(r);} break;
|
||||
case PIVariant::pivFile: {PIVariantTypes::File r = toFile(); r.file = v; setValue(r);} break;
|
||||
case PIVariant::pivDir: {PIVariantTypes::Dir r = toDir(); r.dir = v; setValue(r);} break;
|
||||
case PIVariant::pivColor: {setValue(PIVariantTypes::Color(v.mid(1).toUInt(16)));} break;
|
||||
case PIVariant::pivIODevice: {setValue(PIVariantTypes::IODevice());} break; // TODO
|
||||
case PIVariant::pivCustom: {} break; // TODO;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PIVariant & PIVariant::operator =(const PIVariant & v) {
|
||||
_type = v._type;
|
||||
_content = v._content;
|
||||
#ifdef CUSTOM_PIVARIANT
|
||||
_info = v._info;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIVariant & PIVariant::operator =(PIVariant && v) {
|
||||
swap(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool PIVariant::operator ==(const PIVariant & v) const {
|
||||
return (_type == v._type) && (_content == v._content);
|
||||
}
|
||||
|
||||
|
||||
PIVariant::Type PIVariant::typeFromName(const PIString & tname) {
|
||||
PIString s = tname.trimmed().toLowerCase().replaceAll(" ", "");
|
||||
if (s == "bool" || s == "boolean") return PIVariant::pivBool;
|
||||
if (s == "char" || s == "sbyte") return PIVariant::pivChar;
|
||||
if (s == "short" || s == "shortint" || s == "signedshort" || s == "signedshortint" || s == "sword") return PIVariant::pivShort;
|
||||
if (s == "int" || s == "signed" || s == "signedint") return PIVariant::pivInt;
|
||||
if (s == "long" || s == "longint" || s == "signedlong" || s == "signedlongint" || s == "sdword") return PIVariant::pivInt;
|
||||
if (s == "llong" || s == "longlong" || s == "longlongint" || s == "signedlonglong" || s == "signedlonglongint" || s == "sqword") return PIVariant::pivLLong;
|
||||
if (s == "uchar" || s == "byte") return PIVariant::pivUChar;
|
||||
if (s == "ushort" || s == "unsignedshort" || s == "unsignedshortint" || s == "word") return PIVariant::pivUShort;
|
||||
if (s == "uint" || s == "unsigned" || s == "unsignedint") return PIVariant::pivUInt;
|
||||
if (s == "ulong" || s == "unsignedlong" || s == "unsignedlongint" || s == "dword") return PIVariant::pivUInt;
|
||||
if (s == "ullong" || s == "unsignedlonglong" || s == "unsignedlonglongint" || s == "qword") return PIVariant::pivULLong;
|
||||
if (s == "float") return PIVariant::pivFloat;
|
||||
if (s == "double" || s == "real") return PIVariant::pivDouble;
|
||||
if (s == "ldouble" || s == "longdouble") return PIVariant::pivLDouble;
|
||||
if (s == "complexd" || s == "complex<double>") return PIVariant::pivComplexd;
|
||||
if (s == "complexld" || s == "complex<ldouble>" || s == "complex<longdouble>") return PIVariant::pivComplexld;
|
||||
if (s == "pibitarray" || s == "bitarray") return PIVariant::pivBitArray;
|
||||
if (s == "pibytearray" || s == "bytearray" || s == "vector<uchar>" || s == "pivector<uchar>" || s == "vector<unsignedchar>" || s == "pivector<unsignedchar>" ||
|
||||
s == "vector<char>" || s == "pivector<char>") return PIVariant::pivByteArray;
|
||||
if (s == "pistring" || s == "string") return PIVariant::pivString;
|
||||
if (s == "pistringlist" || s == "stringlist" || s == "vector<string>" || s == "vector<pistring>" || s == "pivector<string>" || s == "pivector<pistring>") return PIVariant::pivStringList;
|
||||
if (s == "pitime" || s == "time") return PIVariant::pivTime;
|
||||
if (s == "pidate" || s == "date") return PIVariant::pivDate;
|
||||
if (s == "pidatetime" || s == "datetime") return PIVariant::pivDateTime;
|
||||
if (s == "pisystemtime" || s == "systemtime") return PIVariant::pivSystemTime;
|
||||
if (s == "enum") return PIVariant::pivEnum;
|
||||
if (s == "file" || s == "path") return PIVariant::pivFile;
|
||||
if (s == "dir" || s == "directory") return PIVariant::pivDir;
|
||||
if (s == "color") return PIVariant::pivColor;
|
||||
if (s == "point") return PIVariant::pivPoint;
|
||||
if (s == "rect") return PIVariant::pivRect;
|
||||
if (s == "vector") return PIVariant::pivMathVector;
|
||||
if (s == "matrix") return PIVariant::pivMathMatrix;
|
||||
if (s == "line") return PIVariant::pivLine;
|
||||
if (s == "device" || s == "iodevice") return PIVariant::pivIODevice;
|
||||
return PIVariant::pivInvalid;
|
||||
}
|
||||
|
||||
|
||||
PIString PIVariant::typeName() const {
|
||||
#ifdef CUSTOM_PIVARIANT
|
||||
if ((_type == pivCustom) && _info)
|
||||
return _info->typeName;
|
||||
#endif
|
||||
return typeName(_type);
|
||||
}
|
||||
|
||||
|
||||
void PIVariant::swap(PIVariant & v) {
|
||||
piSwap(_type, v._type);
|
||||
_content.swap(v._content);
|
||||
#ifdef CUSTOM_PIVARIANT
|
||||
piSwap(_info, v._info);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PIString PIVariant::typeName(PIVariant::Type type) {
|
||||
switch (type) {
|
||||
case PIVariant::pivBool: return "Bool";
|
||||
case PIVariant::pivChar: return "Char";
|
||||
case PIVariant::pivUChar: return "UChar";
|
||||
case PIVariant::pivShort: return "Short";
|
||||
case PIVariant::pivUShort: return "UShort";
|
||||
case PIVariant::pivInt: return "Int";
|
||||
case PIVariant::pivUInt: return "UInt";
|
||||
case PIVariant::pivLLong: return "LLong";
|
||||
case PIVariant::pivULLong: return "ULLong";
|
||||
case PIVariant::pivFloat: return "Float";
|
||||
case PIVariant::pivDouble: return "Double";
|
||||
case PIVariant::pivLDouble: return "LDouble";
|
||||
case PIVariant::pivComplexd: return "Complexd";
|
||||
case PIVariant::pivComplexld: return "Complexld";
|
||||
case PIVariant::pivBitArray: return "BitArray";
|
||||
case PIVariant::pivByteArray: return "ByteArray";
|
||||
case PIVariant::pivString: return "String";
|
||||
case PIVariant::pivStringList: return "StringList";
|
||||
case PIVariant::pivTime: return "Time";
|
||||
case PIVariant::pivDate: return "Date";
|
||||
case PIVariant::pivDateTime: return "DateTime";
|
||||
case PIVariant::pivSystemTime: return "SystemTime";
|
||||
case PIVariant::pivEnum: return "Enum";
|
||||
case PIVariant::pivFile: return "File";
|
||||
case PIVariant::pivDir: return "Dir";
|
||||
case PIVariant::pivColor: return "Color";
|
||||
case PIVariant::pivPoint: return "Point";
|
||||
case PIVariant::pivRect: return "Rect";
|
||||
case PIVariant::pivMathVector: return "Vector";
|
||||
case PIVariant::pivMathMatrix: return "Matrix";
|
||||
case PIVariant::pivCustom: return "Custom";
|
||||
default: break;
|
||||
}
|
||||
return "Invalid";
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as boolean
|
||||
//! \~russian Возвращает содержимое как boolean
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of numeric types returns \b true if value != 0. \n
|
||||
//! In case of String type returns \a PIString::toBool(). \n
|
||||
//! In case of StringList type returns \b false if string list is empty,
|
||||
//! otherwise returns \a PIString::toBool() of first string. \n
|
||||
//! In case of other types returns \b false.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для численных типов возвращает \b true если значение != 0. \n
|
||||
//! Для типа String возвращает \a PIString::toBool(). \n
|
||||
//! Для типа StringList возвращает \b false если массив пустой, \n
|
||||
//! иначе возвращает \a PIString::toBool() первой строки. \n
|
||||
//! Для остальных типов возвращает \b false.
|
||||
//!
|
||||
bool PIVariant::toBool() const {
|
||||
PIByteArray ba(_content);
|
||||
switch (_type) {
|
||||
case PIVariant::pivBool: {bool r; ba >> r; return r;}
|
||||
case PIVariant::pivChar: {char r; ba >> r; return r != 0;}
|
||||
case PIVariant::pivUChar: {uchar r; ba >> r; return r != 0;}
|
||||
case PIVariant::pivShort: {short r; ba >> r; return r != 0;}
|
||||
case PIVariant::pivUShort: {ushort r; ba >> r; return r != 0;}
|
||||
case PIVariant::pivInt: {int r; ba >> r; return r != 0;}
|
||||
case PIVariant::pivUInt: {uint r; ba >> r; return r != 0;}
|
||||
case PIVariant::pivLLong: {llong r; ba >> r; return r != 0;}
|
||||
case PIVariant::pivULLong: {ullong r; ba >> r; return r != 0;}
|
||||
case PIVariant::pivFloat: {float r; ba >> r; return r > 0.f;}
|
||||
case PIVariant::pivDouble: {double r; ba >> r; return r > 0.;}
|
||||
case PIVariant::pivLDouble: {ldouble r; ba >> r; return r > 0.;}
|
||||
case PIVariant::pivString: {PIString r; ba >> r; return r.toBool();}
|
||||
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return false; return r.front().toBool();}
|
||||
case PIVariant::pivCustom: return getAsValue<bool>(*this);
|
||||
default: break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as int
|
||||
//! \~russian Возвращает содержимое как int
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of numeric types returns integer value. \n
|
||||
//! In case of String type returns \a PIString::toInt(). \n
|
||||
//! In case of StringList type returns \b 0 if string list is empty,
|
||||
//! otherwise returns \a PIString::toInt() of first string. \n
|
||||
//! In case of other types returns \b 0.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для численных типов возвращает целочисленное значение. \n
|
||||
//! Для типа String возвращает \a PIString::toInt(). \n
|
||||
//! Для типа StringList возвращает \b 0 если массив пустой, \n
|
||||
//! иначе возвращает \a PIString::toInt() первой строки. \n
|
||||
//! Для остальных типов возвращает \b 0.
|
||||
//!
|
||||
int PIVariant::toInt() const {
|
||||
PIByteArray ba(_content);
|
||||
switch (_type) {
|
||||
case PIVariant::pivBool: {bool r; ba >> r; return r;}
|
||||
case PIVariant::pivChar: {char r; ba >> r; return r;}
|
||||
case PIVariant::pivUChar: {uchar r; ba >> r; return r;}
|
||||
case PIVariant::pivShort: {short r; ba >> r; return r;}
|
||||
case PIVariant::pivUShort: {ushort r; ba >> r; return r;}
|
||||
case PIVariant::pivInt: {int r; ba >> r; return r;}
|
||||
case PIVariant::pivUInt: {uint r; ba >> r; return r;}
|
||||
case PIVariant::pivLLong: {llong r; ba >> r; return r;}
|
||||
case PIVariant::pivULLong: {ullong r; ba >> r; return r;}
|
||||
case PIVariant::pivFloat: {float r; ba >> r; return r;}
|
||||
case PIVariant::pivDouble: {double r; ba >> r; return r;}
|
||||
case PIVariant::pivLDouble: {ldouble r; ba >> r; return r;}
|
||||
case PIVariant::pivString: {PIString r; ba >> r; return r.toInt();}
|
||||
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0; return r.front().toInt();}
|
||||
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return r.selectedValue();}
|
||||
case PIVariant::pivColor: {PIVariantTypes::Color r; ba >> r; return (int)r.rgba;}
|
||||
case PIVariant::pivCustom: return getAsValue<int>(*this);
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as long long
|
||||
//! \~russian Возвращает содержимое как long long
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of numeric types returns integer value. \n
|
||||
//! In case of String type returns \a PIString::toLLong(). \n
|
||||
//! In case of StringList type returns \b 0L if string list is empty,
|
||||
//! otherwise returns \a PIString::toLLong() of first string. \n
|
||||
//! In case of other types returns \b 0L.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для численных типов возвращает целочисленное значение. \n
|
||||
//! Для типа String возвращает \a PIString::toLLong(). \n
|
||||
//! Для типа StringList возвращает \b 0L если массив пустой, \n
|
||||
//! иначе возвращает \a PIString::toLLong() первой строки. \n
|
||||
//! Для остальных типов возвращает \b 0L.
|
||||
//!
|
||||
llong PIVariant::toLLong() const {
|
||||
PIByteArray ba(_content);
|
||||
switch (_type) {
|
||||
case PIVariant::pivBool: {bool r; ba >> r; return r;}
|
||||
case PIVariant::pivChar: {char r; ba >> r; return r;}
|
||||
case PIVariant::pivUChar: {uchar r; ba >> r; return r;}
|
||||
case PIVariant::pivShort: {short r; ba >> r; return r;}
|
||||
case PIVariant::pivUShort: {ushort r; ba >> r; return r;}
|
||||
case PIVariant::pivInt: {int r; ba >> r; return r;}
|
||||
case PIVariant::pivUInt: {uint r; ba >> r; return r;}
|
||||
case PIVariant::pivLLong: {llong r; ba >> r; return r;}
|
||||
case PIVariant::pivULLong: {ullong r; ba >> r; return r;}
|
||||
case PIVariant::pivFloat: {float r; ba >> r; return r;}
|
||||
case PIVariant::pivDouble: {double r; ba >> r; return r;}
|
||||
case PIVariant::pivLDouble: {ldouble r; ba >> r; return r;}
|
||||
case PIVariant::pivString: {PIString r; ba >> r; return r.toLLong();}
|
||||
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0L; return r.front().toLLong();}
|
||||
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return llong(r.selectedValue());}
|
||||
case PIVariant::pivCustom: return getAsValue<llong>(*this);
|
||||
default: break;
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as float
|
||||
//! \~russian Возвращает содержимое как float
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of numeric types returns float value. \n
|
||||
//! In case of String type returns \a PIString::toFloat(). \n
|
||||
//! In case of StringList type returns \b 0.f if string list is empty,
|
||||
//! otherwise returns \a PIString::toFloat() of first string. \n
|
||||
//! In case of other types returns \b 0.f .
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для численных типов возвращает вещественное значение. \n
|
||||
//! Для типа String возвращает \a PIString::toFloat(). \n
|
||||
//! Для типа StringList возвращает \b 0.f если массив пустой, \n
|
||||
//! иначе возвращает \a PIString::toFloat() первой строки. \n
|
||||
//! Для остальных типов возвращает \b 0.f .
|
||||
//!
|
||||
float PIVariant::toFloat() const {
|
||||
PIByteArray ba(_content);
|
||||
switch (_type) {
|
||||
case PIVariant::pivBool: {bool r; ba >> r; return r;}
|
||||
case PIVariant::pivChar: {char r; ba >> r; return r;}
|
||||
case PIVariant::pivUChar: {uchar r; ba >> r; return r;}
|
||||
case PIVariant::pivShort: {short r; ba >> r; return r;}
|
||||
case PIVariant::pivUShort: {ushort r; ba >> r; return r;}
|
||||
case PIVariant::pivInt: {int r; ba >> r; return r;}
|
||||
case PIVariant::pivUInt: {uint r; ba >> r; return r;}
|
||||
case PIVariant::pivLLong: {llong r; ba >> r; return r;}
|
||||
case PIVariant::pivULLong: {ullong r; ba >> r; return r;}
|
||||
case PIVariant::pivFloat: {float r; ba >> r; return r;}
|
||||
case PIVariant::pivDouble: {double r; ba >> r; return r;}
|
||||
case PIVariant::pivLDouble: {ldouble r; ba >> r; return r;}
|
||||
case PIVariant::pivString: {PIString r; ba >> r; return r.toFloat();}
|
||||
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0.f; return r.front().toFloat();}
|
||||
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return float(r.selectedValue());}
|
||||
case PIVariant::pivCustom: return getAsValue<float>(*this);
|
||||
default: break;
|
||||
}
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as double
|
||||
//! \~russian Возвращает содержимое как double
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of numeric types returns double value. \n
|
||||
//! In case of String type returns \a PIString::toDouble(). \n
|
||||
//! In case of StringList type returns \b 0. if string list is empty,
|
||||
//! otherwise returns \a PIString::toDouble() of first string. \n
|
||||
//! In case of other types returns \b 0. .
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для численных типов возвращает вещественное значение. \n
|
||||
//! Для типа String возвращает \a PIString::toDouble(). \n
|
||||
//! Для типа StringList возвращает \b 0. если массив пустой, \n
|
||||
//! иначе возвращает \a PIString::toDouble() первой строки. \n
|
||||
//! Для остальных типов возвращает \b 0. .
|
||||
//!
|
||||
double PIVariant::toDouble() const {
|
||||
PIByteArray ba(_content);
|
||||
switch (_type) {
|
||||
case PIVariant::pivBool: {bool r; ba >> r; return r;}
|
||||
case PIVariant::pivChar: {char r; ba >> r; return r;}
|
||||
case PIVariant::pivUChar: {uchar r; ba >> r; return r;}
|
||||
case PIVariant::pivShort: {short r; ba >> r; return r;}
|
||||
case PIVariant::pivUShort: {ushort r; ba >> r; return r;}
|
||||
case PIVariant::pivInt: {int r; ba >> r; return r;}
|
||||
case PIVariant::pivUInt: {uint r; ba >> r; return r;}
|
||||
case PIVariant::pivLLong: {llong r; ba >> r; return r;}
|
||||
case PIVariant::pivULLong: {ullong r; ba >> r; return r;}
|
||||
case PIVariant::pivFloat: {float r; ba >> r; return r;}
|
||||
case PIVariant::pivDouble: {double r; ba >> r; return r;}
|
||||
case PIVariant::pivLDouble: {ldouble r; ba >> r; return r;}
|
||||
case PIVariant::pivString: {PIString r; ba >> r; return r.toDouble();}
|
||||
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0.; return r.front().toDouble();}
|
||||
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return double(r.selectedValue());}
|
||||
case PIVariant::pivCustom: return getAsValue<double>(*this);
|
||||
default: break;
|
||||
}
|
||||
return 0.;
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as long double
|
||||
//! \~russian Возвращает содержимое как long double
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of numeric types returns long double value. \n
|
||||
//! In case of String type returns \a PIString::toLDouble(). \n
|
||||
//! In case of StringList type returns \b 0. if string list is empty,
|
||||
//! otherwise returns \a PIString::toLDouble() of first string. \n
|
||||
//! In case of other types returns \b 0. .
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для численных типов возвращает вещественное значение. \n
|
||||
//! Для типа String возвращает \a PIString::toLDouble(). \n
|
||||
//! Для типа StringList возвращает \b 0. если массив пустой, \n
|
||||
//! иначе возвращает \a PIString::toLDouble() первой строки. \n
|
||||
//! Для остальных типов возвращает \b 0. .
|
||||
//!
|
||||
ldouble PIVariant::toLDouble() const {
|
||||
PIByteArray ba(_content);
|
||||
switch (_type) {
|
||||
case PIVariant::pivBool: {bool r; ba >> r; return r;}
|
||||
case PIVariant::pivChar: {char r; ba >> r; return r;}
|
||||
case PIVariant::pivUChar: {uchar r; ba >> r; return r;}
|
||||
case PIVariant::pivShort: {short r; ba >> r; return r;}
|
||||
case PIVariant::pivUShort: {ushort r; ba >> r; return r;}
|
||||
case PIVariant::pivInt: {int r; ba >> r; return r;}
|
||||
case PIVariant::pivUInt: {uint r; ba >> r; return r;}
|
||||
case PIVariant::pivLLong: {llong r; ba >> r; return r;}
|
||||
case PIVariant::pivULLong: {ullong r; ba >> r; return r;}
|
||||
case PIVariant::pivFloat: {float r; ba >> r; return r;}
|
||||
case PIVariant::pivDouble: {double r; ba >> r; return r;}
|
||||
case PIVariant::pivLDouble: {ldouble r; ba >> r; return r;}
|
||||
case PIVariant::pivString: {PIString r; ba >> r; return r.toLDouble();}
|
||||
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0.; return r.front().toLDouble();}
|
||||
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return ldouble(r.selectedValue());}
|
||||
case PIVariant::pivCustom: return getAsValue<float>(*this);
|
||||
default: break;
|
||||
}
|
||||
return 0.;
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as time
|
||||
//! \~russian Возвращает содержимое как время
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of Time type returns time value. \n
|
||||
//! In case of DateTime type returns time part of value. \n
|
||||
//! In case of other types returns \a PITime().
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа Time возвращает время. \n
|
||||
//! Для типа DateTime возвращает часть времени. \n
|
||||
//! Для остальных типов возвращает \a PITime().
|
||||
//!
|
||||
PITime PIVariant::toTime() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivTime) {PITime r; ba >> r; return r;}
|
||||
if (_type == PIVariant::pivDateTime) {PIDateTime r; ba >> r; return r.time();}
|
||||
if (_type == PIVariant::pivCustom) {return getAsValue<PITime>(*this);}
|
||||
return PITime();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as date
|
||||
//! \~russian Возвращает содержимое как дата
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of Date type returns date value. \n
|
||||
//! In case of DateTime type returns date part of value. \n
|
||||
//! In case of other types returns \a PIDate().
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа Date возвращает дату. \n
|
||||
//! Для типа DateTime возвращает часть даты. \n
|
||||
//! Для остальных типов возвращает \a PIDate().
|
||||
//!
|
||||
PIDate PIVariant::toDate() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivDate) {PIDate r; ba >> r; return r;}
|
||||
if (_type == PIVariant::pivDateTime) {PIDateTime r; ba >> r; return r.date();}
|
||||
if (_type == PIVariant::pivCustom) {return getAsValue<PIDate>(*this);}
|
||||
return PIDate();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as date and time
|
||||
//! \~russian Возвращает содержимое как дата и время
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of Time type returns time value with null date. \n
|
||||
//! In case of Date type returns date value with null time. \n
|
||||
//! In case of DateTime type returns date and time. \n
|
||||
//! In case of other types returns \a PIDateTime().
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа Time возвращает время без даты. \n
|
||||
//! Для типа Date возвращает дату без времени. \n
|
||||
//! Для типа DateTime возвращает время и дату. \n
|
||||
//! Для остальных типов возвращает \a PIDateTime().
|
||||
//!
|
||||
PIDateTime PIVariant::toDateTime() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivTime) {PITime r; ba >> r; return PIDateTime(r);}
|
||||
if (_type == PIVariant::pivDate) {PIDate r; ba >> r; return PIDateTime(r);}
|
||||
if (_type == PIVariant::pivDateTime) {PIDateTime r; ba >> r; return r;}
|
||||
if (_type == PIVariant::pivCustom) {return getAsValue<PIDateTime>(*this);}
|
||||
return PIDateTime();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as system time
|
||||
//! \~russian Возвращает содержимое как системное время
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of SystemTime type returns system time. \n
|
||||
//! In case of other types returns \a PISystemTime::fromSeconds() from \a toDouble().
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа SystemTime возвращает системное время. \n
|
||||
//! Для остальных типов возвращает \a PISystemTime::fromSeconds() от \a toDouble().
|
||||
//!
|
||||
PISystemTime PIVariant::toSystemTime() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivSystemTime) {PISystemTime r; ba >> r; return r;}
|
||||
if (_type == PIVariant::pivCustom) {return getAsValue<PISystemTime>(*this);}
|
||||
return PISystemTime::fromSeconds(toDouble());
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as string
|
||||
//! \~russian Возвращает содержимое как строка
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of numeric types returns \a PIString::fromNumber(). \n
|
||||
//! In case of String type returns string value. \n
|
||||
//! In case of StringList type returns joined string ("(" + PIStringList::join("; ") + ")"). \n
|
||||
//! In case of BitArray or ByteArray types returns number of bits/bytes. \n
|
||||
//! In case of Time, Date or DateTime types returns toString() of this values. \n
|
||||
//! In case of SystemTime types returns second and nanoseconds of time
|
||||
//! ("(PISystemTime::seconds s, PISystemTime::nanoseconds ns)"). \n
|
||||
//! In case of other types returns \b "".
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для численных типов возвращает \a PIString::fromNumber(). \n
|
||||
//! Для типа String возвращает строку. \n
|
||||
//! Для типа StringList возвращает объединенную строку ("(" + PIStringList::join("; ") + ")"). \n
|
||||
//! Для типов BitArray или ByteArray возвращает количество бит/байт. \n
|
||||
//! Для типов Time, Date или DateTime возвращает toString(). \n
|
||||
//! Для типов SystemTime возвращает секунды и наносекунды в формате "(s, ns)".
|
||||
//! Для остальных типов возвращает \b "".
|
||||
//!
|
||||
PIString PIVariant::toString() const {
|
||||
PIByteArray ba(_content);
|
||||
switch (_type) {
|
||||
case PIVariant::pivBool: {bool r; ba >> r; return PIString::fromNumber(r);}
|
||||
case PIVariant::pivChar: {char r; ba >> r; return PIString::fromNumber(r);}
|
||||
case PIVariant::pivUChar: {uchar r; ba >> r; return PIString::fromNumber(r);}
|
||||
case PIVariant::pivShort: {short r; ba >> r; return PIString::fromNumber(r);}
|
||||
case PIVariant::pivUShort: {ushort r; ba >> r; return PIString::fromNumber(r);}
|
||||
case PIVariant::pivInt: {int r; ba >> r; return PIString::fromNumber(r);}
|
||||
case PIVariant::pivUInt: {uint r; ba >> r; return PIString::fromNumber(r);}
|
||||
case PIVariant::pivLLong: {llong r; ba >> r; return PIString::fromNumber(r);}
|
||||
case PIVariant::pivULLong: {ullong r; ba >> r; return PIString::fromNumber(r);}
|
||||
case PIVariant::pivFloat: {float r; ba >> r; return PIString::fromNumber(r);}
|
||||
case PIVariant::pivDouble: {double r; ba >> r; return PIString::fromNumber(r);}
|
||||
case PIVariant::pivLDouble: {ldouble r; ba >> r; return PIString::fromNumber(r);}
|
||||
case PIVariant::pivTime: {PITime r; ba >> r; return r.toString();}
|
||||
case PIVariant::pivDate: {PIDate r; ba >> r; return r.toString();}
|
||||
case PIVariant::pivDateTime: {PIDateTime r; ba >> r; return r.toString();}
|
||||
case PIVariant::pivString: {PIString r; ba >> r; return r;}
|
||||
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return PIString(); return r.join(";");}
|
||||
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return r.selectedName();}
|
||||
case PIVariant::pivFile: {PIVariantTypes::File r; ba >> r; return r.file;}
|
||||
case PIVariant::pivDir: {PIVariantTypes::Dir r; ba >> r; return r.dir;}
|
||||
case PIVariant::pivColor: {PIVariantTypes::Color r; ba >> r; return "#" + PIString::fromNumber(r.rgba, 16);}
|
||||
case PIVariant::pivIODevice: {PIVariantTypes::IODevice r; ba >> r; return "IODevice";} // TODO
|
||||
case PIVariant::pivCustom: return getAsValue<PIString>(*this);
|
||||
default: break;
|
||||
}
|
||||
return PIString();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as strings list
|
||||
//! \~russian Возвращает содержимое как массив строк
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of StringList type returns strings list value. \n
|
||||
//! In case of other types returns \a PIStringList with one string \a toString().
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа StringList возвращает массив строк. \n
|
||||
//! Для остальных типов возвращает \a PIStringList с одной строкой \a toString().
|
||||
//!
|
||||
PIStringList PIVariant::toStringList() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivStringList) {PIStringList r; ba >> r; return r;}
|
||||
if (_type == PIVariant::pivEnum) {PIVariantTypes::Enum r; ba >> r; return r.names();}
|
||||
if (_type == PIVariant::pivCustom) {return getAsValue<PIStringList>(*this);}
|
||||
return PIStringList(toString());
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as bit array
|
||||
//! \~russian Возвращает содержимое как массив битов
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of BitArray type returns bit array value. \n
|
||||
//! In case of other types returns \a PIBitArray from \a toLLong() value.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа BitArray возвращает массив битов. \n
|
||||
//! Для остальных типов возвращает \a PIBitArray от значения \a toLLong().
|
||||
//!
|
||||
PIBitArray PIVariant::toBitArray() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivBitArray) {PIBitArray r; ba >> r; return r;}
|
||||
if (_type == PIVariant::pivCustom) {return getAsValue<PIBitArray>(*this);}
|
||||
return PIBitArray(ullong(toLLong()));
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as byte array
|
||||
//! \~russian Возвращает содержимое как массив байтов
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of ByteArray type returns byte array value. \n
|
||||
//! In case of other types returns empty \a PIByteArray.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа ByteArray возвращает массив байтов. \n
|
||||
//! Для остальных типов возвращает пустой \a PIByteArray.
|
||||
//!
|
||||
PIByteArray PIVariant::toByteArray() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivByteArray) {PIByteArray r; ba >> r; return r;}
|
||||
if (_type == PIVariant::pivCustom) {return getAsValue<PIByteArray>(*this);}
|
||||
return PIByteArray();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as enum
|
||||
//! \~russian Возвращает содержимое как перечисление
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of Enum type returns enum value. \n
|
||||
//! In case of String returns Enum with one member. \n
|
||||
//! In case of StringList returns Enum with corresponding members. \n
|
||||
//! In case of other types returns empty Enum.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа Enum возвращает перечисление. \n
|
||||
//! Для типа String возвращает Enum с одним членом. \n
|
||||
//! Для типа StringList возвращает Enum с членами по строкам. \n
|
||||
//! Для остальных типов возвращает пустой Enum.
|
||||
//!
|
||||
PIVariantTypes::Enum PIVariant::toEnum() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivEnum) {PIVariantTypes::Enum r; ba >> r; return r;}
|
||||
if (_type == PIVariant::pivString) {PIString v; ba >> v; PIVariantTypes::Enum r; r << v; return r;}
|
||||
if (_type == PIVariant::pivStringList) {PIStringList v; ba >> v; PIVariantTypes::Enum r; r << v; return r;}
|
||||
if (_type == PIVariant::pivCustom) {return getAsValue<PIVariantTypes::Enum>(*this);}
|
||||
return PIVariantTypes::Enum();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as file
|
||||
//! \~russian Возвращает содержимое как файл
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of File type returns file value. \n
|
||||
//! In case of String returns File with string value path. \n
|
||||
//! In case of other types returns empty File.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа File возвращает файл. \n
|
||||
//! Для типа String возвращает File с путем значения строки. \n
|
||||
//! Для остальных типов возвращает пустой File.
|
||||
//!
|
||||
PIVariantTypes::File PIVariant::toFile() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivFile) {PIVariantTypes::File r; ba >> r; return r;}
|
||||
if (_type == PIVariant::pivString) {PIString v; ba >> v; PIVariantTypes::File r; r.file = v; return r;}
|
||||
if (_type == PIVariant::pivCustom) {return getAsValue<PIVariantTypes::File>(*this);}
|
||||
return PIVariantTypes::File();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as dir
|
||||
//! \~russian Возвращает содержимое как директория
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of Dir type returns dir value. \n
|
||||
//! In case of String returns Dir with string value path. \n
|
||||
//! In case of other types returns empty Dir.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа Dir возвращает директорию. \n
|
||||
//! Для типа String возвращает Dir с путем значения строки. \n
|
||||
//! Для остальных типов возвращает пустой Dir.
|
||||
//!
|
||||
PIVariantTypes::Dir PIVariant::toDir() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivDir) {PIVariantTypes::Dir r; ba >> r; return r;}
|
||||
if (_type == PIVariant::pivString) {PIString v; ba >> v; PIVariantTypes::Dir r; r.dir = v; return r;}
|
||||
if (_type == PIVariant::pivCustom) {return getAsValue<PIVariantTypes::Dir>(*this);}
|
||||
return PIVariantTypes::Dir();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as color
|
||||
//! \~russian Возвращает содержимое как цвет
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of Color type returns color value. \n
|
||||
//! In case of Int returns color with int value. \n
|
||||
//! In case of other types returns empty Color.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа Color возвращает цвет. \n
|
||||
//! Для типа Int возвращает цвет с целочисленным значением. \n
|
||||
//! Для остальных типов возвращает пустой Color.
|
||||
//!
|
||||
PIVariantTypes::Color PIVariant::toColor() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivColor) {PIVariantTypes::Color r; ba >> r; return r;}
|
||||
if (_type == PIVariant::pivInt) {int v; ba >> v; return PIVariantTypes::Color(v);}
|
||||
if (_type == PIVariant::pivCustom) {return getAsValue<PIVariantTypes::Color>(*this);}
|
||||
return PIVariantTypes::Color();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as IODevice
|
||||
//! \~russian Возвращает содержимое как IODevice
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of IODevice type returns IODevice value. \n
|
||||
//! In case of other types returns empty IODevice.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа IODevice возвращает IODevice. \n
|
||||
//! Для остальных типов возвращает пустой IODevice.
|
||||
//!
|
||||
PIVariantTypes::IODevice PIVariant::toIODevice() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivIODevice) {PIVariantTypes::IODevice r; ba >> r; return r;}
|
||||
return PIVariantTypes::IODevice();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as point
|
||||
//! \~russian Возвращает содержимое как точка
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of Point type returns point value. \n
|
||||
//! In case of other types returns empty PIPointd.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа Point возвращает точку. \n
|
||||
//! Для остальных типов возвращает пустую PIPointd.
|
||||
//!
|
||||
PIPointd PIVariant::toPoint() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivPoint) {PIPointd r; ba >> r; return r;}
|
||||
return PIPointd();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as rect
|
||||
//! \~russian Возвращает содержимое как прямоугольник
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of Rect type returns rect value. \n
|
||||
//! In case of other types returns empty PIRectd.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа Rect возвращает прямоугольник. \n
|
||||
//! Для остальных типов возвращает пустой PIRectd.
|
||||
//!
|
||||
PIRectd PIVariant::toRect() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivRect) {PIRectd r; ba >> r; return r;}
|
||||
return PIRectd();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as line
|
||||
//! \~russian Возвращает содержимое как линия
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of Line type returns line value. \n
|
||||
//! In case of other types returns empty PILined.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа Line возвращает линию. \n
|
||||
//! Для остальных типов возвращает пустую PILined.
|
||||
//!
|
||||
PILined PIVariant::toLine() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivLine) {PILined r; ba >> r; return r;}
|
||||
return PILined();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as math vector
|
||||
//! \~russian Возвращает содержимое как вектор
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of MathVector type returns rect value. \n
|
||||
//! In case of other types returns empty PIMathVectord.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа MathVector возвращает вектор. \n
|
||||
//! Для остальных типов возвращает пустой PIMathVectord.
|
||||
//!
|
||||
PIMathVectord PIVariant::toMathVector() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivMathVector) {PIMathVectord r; ba >> r; return r;}
|
||||
return PIMathVectord();
|
||||
}
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as math matrix
|
||||
//! \~russian Возвращает содержимое как матрица
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of MathMatrix type returns rect value. \n
|
||||
//! In case of other types returns empty PIMathMatrixd.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Для типа MathMatrix возвращает матрицу. \n
|
||||
//! Для остальных типов возвращает пустую PIMathMatrixd.
|
||||
//!
|
||||
PIMathMatrixd PIVariant::toMathMatrix() const {
|
||||
PIByteArray ba(_content);
|
||||
if (_type == PIVariant::pivMathMatrix) {PIMathMatrixd r; ba >> r; return r;}
|
||||
return PIMathMatrixd();
|
||||
}
|
||||
|
||||
@@ -1,1001 +0,0 @@
|
||||
/*! \file pivariant.h
|
||||
* \ingroup Core
|
||||
* \brief
|
||||
* \~english Variant type
|
||||
* \~russian Вариативный тип
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Variant type
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIVARIANT_H
|
||||
#define PIVARIANT_H
|
||||
|
||||
#include "pivarianttypes.h"
|
||||
#include "piconstchars.h"
|
||||
#include "pitime.h"
|
||||
#include "pigeometry.h"
|
||||
#include "pimathmatrix.h"
|
||||
|
||||
|
||||
#ifdef DOXYGEN
|
||||
|
||||
//! \relatesalso PIVariant
|
||||
//! \~\brief
|
||||
//! \~english Macro to register type for using in %PIVariant
|
||||
//! \~russian Макрос для регистрации типа для использования в %PIVariant
|
||||
# define REGISTER_VARIANT(Typename)
|
||||
|
||||
//! \relatesalso PIVariant
|
||||
//! \~\brief
|
||||
//! \~english Macro to register type with namespace for using in %PIVariant
|
||||
//! \~russian Макрос для регистрации типа с пространством имен для использования в %PIVariant
|
||||
# define REGISTER_NS_VARIANT(Namespace, Typename)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef QNX
|
||||
# define CUSTOM_PIVARIANT
|
||||
#endif
|
||||
|
||||
#ifdef CUSTOM_PIVARIANT
|
||||
|
||||
|
||||
template<typename T>
|
||||
class __PIVariantFunctions__ {
|
||||
public:
|
||||
static PIString typeNameHelper() {return PIStringAscii("");}
|
||||
|
||||
static bool isSimpleHelper() {return false;}
|
||||
template<typename C> static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();}
|
||||
template<typename C> static C castVariant(const T & v) {return C();}
|
||||
};
|
||||
|
||||
struct PIP_EXPORT __PIVariantInfo__ {
|
||||
__PIVariantInfo__() {
|
||||
simple = false;
|
||||
}
|
||||
typedef PIByteArray(*castHelperFunc)(PIByteArray);
|
||||
PIMap<PIString, castHelperFunc> cast;
|
||||
PIString typeName;
|
||||
bool simple;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct __PIVariantTypeInfo__ {
|
||||
typedef T PureType;
|
||||
typedef const T ConstPureType;
|
||||
typedef T * PointerType;
|
||||
typedef const T * ConstPointerType;
|
||||
typedef T & ReferenceType;
|
||||
typedef const T & ConstReferenceType;
|
||||
};
|
||||
|
||||
#define __TYPEINFO_SINGLE(PT, T) \
|
||||
template<> struct __PIVariantTypeInfo__<T> { \
|
||||
typedef PT PureType; \
|
||||
typedef const PT ConstPureType; \
|
||||
typedef PT * PointerType; \
|
||||
typedef const PT * ConstPointerType; \
|
||||
typedef PT & ReferenceType; \
|
||||
typedef const PT & ConstReferenceType; \
|
||||
};
|
||||
|
||||
#define REGISTER_VARIANT_TYPEINFO(T) \
|
||||
__TYPEINFO_SINGLE(T, T &) \
|
||||
__TYPEINFO_SINGLE(T, const T) \
|
||||
__TYPEINFO_SINGLE(T, const T &)
|
||||
|
||||
|
||||
class PIP_EXPORT __PIVariantInfoStorage__ {
|
||||
public:
|
||||
__PIVariantInfoStorage__() {if (!map) map = new PIMap<PIString, __PIVariantInfo__ * >();}
|
||||
static __PIVariantInfoStorage__ * get() {static __PIVariantInfoStorage__ * r = new __PIVariantInfoStorage__(); return r;}
|
||||
static PIMap<PIString, __PIVariantInfo__ * > * map;
|
||||
};
|
||||
|
||||
|
||||
#define REGISTER_VARIANT_H(classname) \
|
||||
template<> inline PIString __PIVariantFunctions__< classname >::typeNameHelper() {static PIString tn = PIStringAscii(#classname); return tn;} \
|
||||
REGISTER_VARIANT_TYPEINFO(classname)
|
||||
|
||||
#define REGISTER_NS_VARIANT_H(ns, classname) \
|
||||
template<> inline PIString __PIVariantFunctions__< ns::classname >::typeNameHelper() {static PIString tn = PIStringAscii(#ns"::"#classname); return tn;} \
|
||||
REGISTER_VARIANT_TYPEINFO(ns::classname)
|
||||
|
||||
#define REGISTER_VARIANT_CPP(classname) \
|
||||
template <typename T> \
|
||||
class __##classname##_PIVariantInitializer__ { \
|
||||
public: \
|
||||
__##classname##_PIVariantInitializer__(const PIString & name) { \
|
||||
if (__PIVariantInfoStorage__::get()->map->contains(name)) \
|
||||
return; \
|
||||
__PIVariantInfo__ * vi = new __PIVariantInfo__(); \
|
||||
vi->typeName = name; \
|
||||
(*(__PIVariantInfoStorage__::get()->map))[name] = vi; \
|
||||
} \
|
||||
};
|
||||
|
||||
#define REGISTER_NS_VARIANT_CPP(ns, classname) \
|
||||
template <typename T> \
|
||||
class __##ns##classname##_PIVariantInitializer__ { \
|
||||
public: \
|
||||
__##ns##classname##_PIVariantInitializer__(const PIString & name) { \
|
||||
if (__PIVariantInfoStorage__::get()->map->contains(name)) \
|
||||
return; \
|
||||
__PIVariantInfo__ * vi = new __PIVariantInfo__(); \
|
||||
vi->typeName = name; \
|
||||
(*(__PIVariantInfoStorage__::get()->map))[name] = vi; \
|
||||
} \
|
||||
};
|
||||
|
||||
#define INIT_VARIANT(classname) \
|
||||
__##classname##_PIVariantInitializer__< classname > __##classname##_pivariant_initializer__(#classname);
|
||||
|
||||
#define INIT_NS_VARIANT(ns, classname) \
|
||||
__##ns##classname##_PIVariantInitializer__< ns::classname > __##ns##classname##_pivariant_initializer__(#ns"::"#classname);
|
||||
|
||||
#define REGISTER_VARIANT(classname) \
|
||||
REGISTER_VARIANT_H(classname) \
|
||||
REGISTER_VARIANT_CPP(classname) \
|
||||
static INIT_VARIANT(classname)
|
||||
|
||||
#define REGISTER_NS_VARIANT(ns, classname) \
|
||||
REGISTER_NS_VARIANT_H(ns, classname) \
|
||||
REGISTER_NS_VARIANT_CPP(ns, classname) \
|
||||
static INIT_NS_VARIANT(ns, classname)
|
||||
|
||||
|
||||
#define REGISTER_VARIANT_CAST_H(classname_from, classname_to) \
|
||||
template<> template<> inline \
|
||||
classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(const classname_from & v);
|
||||
|
||||
#define REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) \
|
||||
template<> template<> inline \
|
||||
PIByteArray __PIVariantFunctions__<classname_from>::castHelper<classname_to>(PIByteArray v) { \
|
||||
classname_from f; v >> f; \
|
||||
classname_to t = __PIVariantFunctions__<classname_from>::castVariant<classname_to>(f); \
|
||||
PIByteArray ret; ret << t; \
|
||||
return ret;} \
|
||||
template <typename T, typename C> \
|
||||
class __##classname_from##_##classname_to##_PIVariantCastInitializer__ { \
|
||||
public: \
|
||||
__##classname_from##_##classname_to##_PIVariantCastInitializer__(const PIString & name, const PIString & cname) { \
|
||||
__PIVariantInfo__ * vi(__PIVariantInfoStorage__::get()->map->value(name, 0)); \
|
||||
if (!vi) { \
|
||||
piCout << "Warning! Using REGISTER_VARIANT_CAST("#classname_from", "#classname_to") before REGISTER_VARIANT("#classname_from"), ignore."; \
|
||||
return; \
|
||||
} \
|
||||
vi->cast[cname] = __PIVariantFunctions__<classname_from>::castHelper<classname_to>; \
|
||||
} \
|
||||
}; \
|
||||
static __##classname_from##_##classname_to##_PIVariantCastInitializer__< classname_from, classname_to > __##classname_from##_##classname_to##_pivariant_cast_initializer__(#classname_from, #classname_to); \
|
||||
template<> template<> \
|
||||
classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(const classname_from & v)
|
||||
|
||||
#define REGISTER_VARIANT_CAST(classname_from, classname_to) \
|
||||
REGISTER_VARIANT_CAST_H(classname_from, classname_to) \
|
||||
REGISTER_VARIANT_CAST_CPP(classname_from, classname_to)
|
||||
|
||||
|
||||
#define REGISTER_VARIANT_CAST_SIMPLE(classname_from, classname_to) REGISTER_VARIANT_CAST(classname_from, classname_to) {return classname_to(v);}
|
||||
#define REGISTER_VARIANT_CAST_SIMPLE_H(classname_from, classname_to) REGISTER_VARIANT_CAST_H(classname_from, classname_to)
|
||||
#define REGISTER_VARIANT_CAST_SIMPLE_CPP(classname_from, classname_to) REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) {return classname_to(v);}
|
||||
|
||||
#else
|
||||
|
||||
#define REGISTER_VARIANT_TYPEINFO(classname)
|
||||
#define REGISTER_VARIANT_H(classname)
|
||||
#define REGISTER_VARIANT_CPP(classname)
|
||||
#define INIT_VARIANT(classname)
|
||||
#define REGISTER_VARIANT(classname)
|
||||
#define REGISTER_NS_VARIANT_H(ns, classname)
|
||||
#define REGISTER_NS_VARIANT_CPP(ns, classname)
|
||||
#define INIT_NS_VARIANT(ns, classname)
|
||||
#define REGISTER_NS_VARIANT(ns, classname)
|
||||
#define REGISTER_VARIANT_CAST_H(classname_from, classname_to)
|
||||
#define REGISTER_VARIANT_CAST_CPP(classname_from, classname_to)
|
||||
#define REGISTER_VARIANT_CAST(classname_from, classname_to)
|
||||
#define REGISTER_VARIANT_CAST_SIMPLE(classname_from, classname_to)
|
||||
#define REGISTER_VARIANT_CAST_SIMPLE_H(classname_from, classname_to)
|
||||
#define REGISTER_VARIANT_CAST_SIMPLE_CPP(classname_from, classname_to)
|
||||
|
||||
#endif
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Variant type.
|
||||
//! \~russian Вариантный тип.
|
||||
class PIP_EXPORT PIVariant {
|
||||
friend PICout operator <<(PICout s, const PIVariant & v);
|
||||
BINARY_STREAM_FRIEND(PIVariant);
|
||||
public:
|
||||
|
||||
//! \~english Type of %PIVariant content
|
||||
//! \~russian Тип содержимого %PIVariant
|
||||
enum Type {
|
||||
pivInvalid /** \~english Invalid type, default type of empty contructor \~russian Недействительный тип, также конструированный по умолчанию */ = 0 ,
|
||||
pivBool /** bool */ ,
|
||||
pivChar /** char */ ,
|
||||
pivUChar /** uchar */ ,
|
||||
pivShort /** short */ ,
|
||||
pivUShort /** ushort */ ,
|
||||
pivInt /** int */ ,
|
||||
pivUInt /** uint */ ,
|
||||
pivLLong /** llong */ ,
|
||||
pivULLong /** ullong */ ,
|
||||
pivFloat /** float */ ,
|
||||
pivDouble /** double */ ,
|
||||
pivLDouble /** ldouble */ ,
|
||||
pivComplexd /** complexd */ ,
|
||||
pivComplexld /** complexld */ ,
|
||||
pivBitArray /** PIBitArray */ ,
|
||||
pivByteArray /** PIByteArray */ ,
|
||||
pivString /** PIString */ ,
|
||||
pivStringList /** PIStringList */ ,
|
||||
pivTime /** PITime */ ,
|
||||
pivDate /** PIDate */ ,
|
||||
pivDateTime /** PIDateTime */ ,
|
||||
pivSystemTime /** PISystemTime */ ,
|
||||
pivEnum /** PIVariantTypes::Enum */ ,
|
||||
pivFile /** PIVariantTypes::File */ ,
|
||||
pivDir /** PIVariantTypes::Dir */ ,
|
||||
pivColor /** PIVariantTypes::Color */ ,
|
||||
pivPoint /** PIPoint<double> */ ,
|
||||
pivRect /** PIRect<double> */ ,
|
||||
pivIODevice /** PIVariantTypes::IODevice */ ,
|
||||
pivMathVector /** PIMathVector<double> */ ,
|
||||
pivMathMatrix /** PIMathMatrix<double> */ ,
|
||||
pivLine /** PILine<double> */ ,
|
||||
pivCustom /** \~english Custom \~russian Свой тип */ = 0xFF
|
||||
};
|
||||
|
||||
//! \~english Construct \a pivInvalid %PIVariant
|
||||
//! \~russian Создает \a pivInvalid %PIVariant
|
||||
PIVariant();
|
||||
|
||||
//! \~english Contructs a copy of %PIVariant.
|
||||
//! \~russian Создает копию %PIVariant.
|
||||
PIVariant(const PIVariant & v);
|
||||
|
||||
//! \~english Move constructor.
|
||||
//! \~russian Перемещающий конструктор.
|
||||
PIVariant(PIVariant && v);
|
||||
|
||||
//! \~english Constructs %PIVariant from string
|
||||
//! \~russian Создает %PIVariant из строки.
|
||||
PIVariant(const char * v) {initType(PIString(v));}
|
||||
|
||||
//! \~english Constructs %PIVariant from boolean
|
||||
//! \~russian Создает %PIVariant из логического значения.
|
||||
PIVariant(const bool v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from char
|
||||
//! \~russian Создает %PIVariant из символа.
|
||||
PIVariant(const char v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from integer
|
||||
//! \~russian Создает %PIVariant из целого числа.
|
||||
PIVariant(const uchar v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from integer
|
||||
//! \~russian Создает %PIVariant из целого числа.
|
||||
PIVariant(const short v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from integer
|
||||
//! \~russian Создает %PIVariant из целого числа.
|
||||
PIVariant(const ushort v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from integer
|
||||
//! \~russian Создает %PIVariant из целого числа.
|
||||
PIVariant(const int & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from integer
|
||||
//! \~russian Создает %PIVariant из целого числа.
|
||||
PIVariant(const uint & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from integer
|
||||
//! \~russian Создает %PIVariant из целого числа.
|
||||
PIVariant(const llong & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from integer
|
||||
//! \~russian Создает %PIVariant из целого числа.
|
||||
PIVariant(const ullong & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from float
|
||||
//! \~russian Создает %PIVariant из вещественного числа.
|
||||
PIVariant(const float & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from double
|
||||
//! \~russian Создает %PIVariant из вещественного числа.
|
||||
PIVariant(const double & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from long double
|
||||
//! \~russian Создает %PIVariant из вещественного числа.
|
||||
PIVariant(const ldouble & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from bit array
|
||||
//! \~russian Создает %PIVariant из массива битов.
|
||||
PIVariant(const PIBitArray & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from byte array
|
||||
//! \~russian Создает %PIVariant из массива байтов.
|
||||
PIVariant(const PIByteArray & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from string
|
||||
//! \~russian Создает %PIVariant из строки.
|
||||
PIVariant(const PIString & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from strings list
|
||||
//! \~russian Создает %PIVariant из массива строк.
|
||||
PIVariant(const PIStringList & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from time
|
||||
//! \~russian Создает %PIVariant из времени.
|
||||
PIVariant(const PITime & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from date
|
||||
//! \~russian Создает %PIVariant из даты.
|
||||
PIVariant(const PIDate & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from date and time
|
||||
//! \~russian Создает %PIVariant из даты и времени.
|
||||
PIVariant(const PIDateTime & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from system time
|
||||
//! \~russian Создает %PIVariant из системного времени.
|
||||
PIVariant(const PISystemTime & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from enum
|
||||
//! \~russian Создает %PIVariant из перечисления.
|
||||
PIVariant(const PIVariantTypes::Enum & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from file
|
||||
//! \~russian Создает %PIVariant из файла.
|
||||
PIVariant(const PIVariantTypes::File & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from dir
|
||||
//! \~russian Создает %PIVariant из директории.
|
||||
PIVariant(const PIVariantTypes::Dir & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from color
|
||||
//! \~russian Создает %PIVariant из цвета.
|
||||
PIVariant(const PIVariantTypes::Color & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from IODevice
|
||||
//! \~russian Создает %PIVariant из IODevice.
|
||||
PIVariant(const PIVariantTypes::IODevice & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from point
|
||||
//! \~russian Создает %PIVariant из точки.
|
||||
PIVariant(const PIPointd & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from rect
|
||||
//! \~russian Создает %PIVariant из прямоугольника.
|
||||
PIVariant(const PIRectd & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from line
|
||||
//! \~russian Создает %PIVariant из линии.
|
||||
PIVariant(const PILined & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from MathVector
|
||||
//! \~russian Создает %PIVariant из MathVector.
|
||||
PIVariant(const PIMathVectord & v) {initType(v);}
|
||||
|
||||
//! \~english Constructs %PIVariant from MathMatrix
|
||||
//! \~russian Создает %PIVariant из MathMatrix.
|
||||
PIVariant(const PIMathMatrixd & v) {initType(v);}
|
||||
|
||||
|
||||
//! \~english Set variant content and type to string
|
||||
//! \~russian Устанавливает значение и тип из строки
|
||||
void setValue(const char * v) {setValue(PIString(v));}
|
||||
|
||||
//! \~english Set variant content and type to boolean
|
||||
//! \~russian Устанавливает значение и тип из
|
||||
void setValue(const bool v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to char
|
||||
//! \~russian Устанавливает значение и тип из символа
|
||||
void setValue(const char v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to integer
|
||||
//! \~russian Устанавливает значение и тип из целого числа
|
||||
void setValue(const uchar v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to integer
|
||||
//! \~russian Устанавливает значение и тип из целого числа
|
||||
void setValue(const short v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to integer
|
||||
//! \~russian Устанавливает значение и тип из целого числа
|
||||
void setValue(const ushort v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to integer
|
||||
//! \~russian Устанавливает значение и тип из целого числа
|
||||
void setValue(const int & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to integer
|
||||
//! \~russian Устанавливает значение и тип из целого числа
|
||||
void setValue(const uint & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to integer
|
||||
//! \~russian Устанавливает значение и тип из целого числа
|
||||
void setValue(const llong & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to integer
|
||||
//! \~russian Устанавливает значение и тип из целого числа
|
||||
void setValue(const ullong & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to float
|
||||
//! \~russian Устанавливает значение и тип из вещественного числа
|
||||
void setValue(const float & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to double
|
||||
//! \~russian Устанавливает значение и тип из вещественного числа
|
||||
void setValue(const double & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to long double
|
||||
//! \~russian Устанавливает значение и тип из вещественного числа
|
||||
void setValue(const ldouble & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to bit array
|
||||
//! \~russian Устанавливает значение и тип из массива битов
|
||||
void setValue(const PIBitArray & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to byte array
|
||||
//! \~russian Устанавливает значение и тип из массива байтов
|
||||
void setValue(const PIByteArray & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to string
|
||||
//! \~russian Устанавливает значение и тип из строки
|
||||
void setValue(const PIString & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to strings list
|
||||
//! \~russian Устанавливает значение и тип из массива строк
|
||||
void setValue(const PIStringList & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to time
|
||||
//! \~russian Устанавливает значение и тип из времени
|
||||
void setValue(const PITime & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to date
|
||||
//! \~russian Устанавливает значение и тип из даты
|
||||
void setValue(const PIDate & v) {initType(v);}
|
||||
|
||||
//!
|
||||
//! \~english Set variant content and type to date and time
|
||||
//! \~russian Устанавливает значение и тип из даты и времени
|
||||
void setValue(const PIDateTime & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to system time
|
||||
//! \~russian Устанавливает значение и тип из системного времени
|
||||
void setValue(const PISystemTime & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to enum
|
||||
//! \~russian Устанавливает значение и тип из перечисления
|
||||
void setValue(const PIVariantTypes::Enum & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to file
|
||||
//! \~russian Устанавливает значение и тип из файла
|
||||
void setValue(const PIVariantTypes::File & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to dir
|
||||
//! \~russian Устанавливает значение и тип из директории
|
||||
void setValue(const PIVariantTypes::Dir & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to color
|
||||
//! \~russian Устанавливает значение и тип из цвета
|
||||
void setValue(const PIVariantTypes::Color & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to IODevice
|
||||
//! \~russian Устанавливает значение и тип из IODevice
|
||||
void setValue(const PIVariantTypes::IODevice & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to point
|
||||
//! \~russian Устанавливает значение и тип из точки
|
||||
void setValue(const PIPointd & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to rect
|
||||
//! \~russian Устанавливает значение и тип из прямоугольника
|
||||
void setValue(const PIRectd & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to line
|
||||
//! \~russian Устанавливает значение и тип из линии
|
||||
void setValue(const PILined & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to math vector
|
||||
//! \~russian Устанавливает значение и тип из вектора
|
||||
void setValue(const PIMathVectord & v) {initType(v);}
|
||||
|
||||
//! \~english Set variant content and type to math matrix
|
||||
//! \~russian Устанавливает значение и тип из матрицы
|
||||
void setValue(const PIMathMatrixd & v) {initType(v);}
|
||||
|
||||
|
||||
//! \~english Set current value from string without change type
|
||||
//! \~russian Устанавливает текущее значение из строки без изменения типа
|
||||
void setValueFromString(const PIString & v);
|
||||
|
||||
|
||||
bool toBool() const;
|
||||
int toInt() const;
|
||||
llong toLLong() const;
|
||||
float toFloat() const;
|
||||
double toDouble() const;
|
||||
ldouble toLDouble() const;
|
||||
PITime toTime() const;
|
||||
PIDate toDate() const;
|
||||
PIDateTime toDateTime() const;
|
||||
PISystemTime toSystemTime() const;
|
||||
PIString toString() const;
|
||||
PIStringList toStringList() const;
|
||||
PIBitArray toBitArray() const;
|
||||
PIByteArray toByteArray() const;
|
||||
PIVariantTypes::Enum toEnum() const;
|
||||
PIVariantTypes::File toFile() const;
|
||||
PIVariantTypes::Dir toDir() const;
|
||||
PIVariantTypes::Color toColor() const;
|
||||
PIVariantTypes::IODevice toIODevice() const;
|
||||
PIPointd toPoint() const;
|
||||
PIRectd toRect() const;
|
||||
PILined toLine() const;
|
||||
PIMathVectord toMathVector() const;
|
||||
PIMathMatrixd toMathMatrix() const;
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns variant content as custom type
|
||||
//! \~russian Возвращает содержимое в качестве своего типа
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of known types this function equivalent \a to<Type> function. \n
|
||||
//! Otherwise returns content as type T only if this type was set earlier.
|
||||
//! \~russian
|
||||
//! Для стандартных типов эквиваленстно методу \a to<Type>. \n
|
||||
//! Для других возвращает тип T только если он был установлен ранее.
|
||||
template<typename T>
|
||||
T value() const {return getAsValue<T>(*this);}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIVariant & v);
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(PIVariant && v);
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const char * v) {setValue(PIString(v)); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const bool v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const char v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const uchar v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const short v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const ushort v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const int & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const uint & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const llong & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const ullong & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const float & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const double & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const ldouble & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIBitArray & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIByteArray & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIString & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIStringList & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PITime & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIDate & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIDateTime & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PISystemTime & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIVariantTypes::Enum & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIVariantTypes::File & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIVariantTypes::Dir & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIVariantTypes::Color & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIVariantTypes::IODevice & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIPointd & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIRectd & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PILined & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIMathVectord & v) {setValue(v); return *this;}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariant & operator =(const PIMathMatrixd & v) {setValue(v); return *this;}
|
||||
|
||||
|
||||
//! \~english Compare operator. Check type and content.
|
||||
//! \~russian Оператор сравнения. Сравнивает тип и содержимое.
|
||||
bool operator ==(const PIVariant & v) const;
|
||||
|
||||
//! \~english Compare operator. Check type and content.
|
||||
//! \~russian Оператор сравнения. Сравнивает тип и содержимое.
|
||||
bool operator !=(const PIVariant & v) const {return !(*this == v);}
|
||||
|
||||
|
||||
//! \~english Returns type of variant content.
|
||||
//! \~russian Возвращает тип значения.
|
||||
PIVariant::Type type() const {return _type;}
|
||||
|
||||
//! \~english Returns type name of variant content.
|
||||
//! \~russian Возвращает имя типа значения.
|
||||
PIString typeName() const;
|
||||
|
||||
|
||||
//! \~english Returns if type is not \a pivInvalid.
|
||||
//! \~russian Возвращает не является ли тип \a pivInvalid.
|
||||
bool isValid() const {return _type != PIVariant::pivInvalid;}
|
||||
|
||||
//! \~english Swaps with other %PIVariant.
|
||||
//! \~russian Меняет с другим %PIVariant.
|
||||
void swap(PIVariant & v);
|
||||
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns new %PIVariant from custom type value.
|
||||
//! \~russian Возвращает новый %PIVariant из значения своего типа.
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In case of known types this function equivalent \a PIVariant() constructors. \n
|
||||
//! Otherwise returns variant with content "v" and type \a pivCustom.
|
||||
//! \~russian
|
||||
//! Для стандартных типов эквиваленстно конструктору \a PIVariant(). \n
|
||||
//! Для других устанавливает содержимое из "v" и тип \a pivCustom.
|
||||
template <typename T>
|
||||
static PIVariant fromValue(const T & v) {
|
||||
PIVariant ret;
|
||||
ret.initType<T>(v);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PIVariant fromValue(const PIByteArray & c, const PIString & type) {
|
||||
PIVariant ret;
|
||||
PIVariant::Type t = typeFromName(type);
|
||||
if (t == pivInvalid) {
|
||||
#ifdef CUSTOM_PIVARIANT
|
||||
ret._info = __PIVariantInfoStorage__::get()->map->value(type, 0);
|
||||
if (ret._info) {
|
||||
t = pivCustom;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
piCout << "Can`t initialize PIVariant from unregistered type \"" << type << "\"!";
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret._type = t;
|
||||
ret._content = c;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Returns type from its name.
|
||||
//! \~russian Возвращает тип из его названия.
|
||||
static PIVariant::Type typeFromName(const PIString & tname);
|
||||
|
||||
//! \~english Returns type name.
|
||||
//! \~russian Возвращает имя типа.
|
||||
static PIString typeName(PIVariant::Type type);
|
||||
|
||||
private:
|
||||
void destroy() {_content.clear();}
|
||||
template <typename T> inline static Type getType() {return pivCustom;}
|
||||
template <typename T> inline void initType(const T & v) {
|
||||
_content.clear();
|
||||
_content << v;
|
||||
_type = getType<T>();
|
||||
#ifdef CUSTOM_PIVARIANT
|
||||
if (_type == pivCustom) {
|
||||
_info = __PIVariantInfoStorage__::get()->map->value(__PIVariantFunctions__<T>::typeNameHelper(), 0);
|
||||
if (!_info)
|
||||
piCout << "Can`t initialize PIVariant from unregistered type!";
|
||||
} else
|
||||
_info = 0;
|
||||
#endif
|
||||
}
|
||||
template<typename T> inline static T getAsValue(const PIVariant & v) {
|
||||
#ifdef CUSTOM_PIVARIANT
|
||||
if (v._content.isEmpty() || !v._info) return T();
|
||||
PIString cn = __PIVariantFunctions__<T>::typeNameHelper();
|
||||
//piCout << "gav" << cn;
|
||||
PIByteArray ba;
|
||||
if (cn == v._info->typeName) {
|
||||
ba = v._content;
|
||||
} else {
|
||||
__PIVariantInfo__::castHelperFunc cf = v._info->cast.value(cn);
|
||||
//piCout << "gav cast" << cf;
|
||||
if (!cf) return T();
|
||||
ba = cf(v._content);
|
||||
}
|
||||
T ret; ba >> ret;
|
||||
return ret;
|
||||
#else
|
||||
return T();
|
||||
#endif
|
||||
}
|
||||
|
||||
PIByteArray _content;
|
||||
PIVariant::Type _type;
|
||||
#ifdef CUSTOM_PIVARIANT
|
||||
__PIVariantInfo__ * _info;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
template<> inline bool PIVariant::value() const {return toBool();}
|
||||
template<> inline char PIVariant::value() const {return (char)toInt();}
|
||||
template<> inline uchar PIVariant::value() const {return (uchar)toInt();}
|
||||
template<> inline short PIVariant::value() const {return (short)toInt();}
|
||||
template<> inline ushort PIVariant::value() const {return (ushort)toInt();}
|
||||
template<> inline int PIVariant::value() const {return toInt();}
|
||||
template<> inline uint PIVariant::value() const {return (uint)toInt();}
|
||||
template<> inline llong PIVariant::value() const {return toLLong();}
|
||||
template<> inline ullong PIVariant::value() const {return (ullong)toLLong();}
|
||||
template<> inline float PIVariant::value() const {return toFloat();}
|
||||
template<> inline double PIVariant::value() const {return toDouble();}
|
||||
template<> inline ldouble PIVariant::value() const {return toLDouble();}
|
||||
template<> inline void* PIVariant::value() const {return (void*)toLLong();}
|
||||
template<> inline const char* PIVariant::value() const {return toString().data();}
|
||||
template<> inline PITime PIVariant::value() const {return toTime();}
|
||||
template<> inline PIDate PIVariant::value() const {return toDate();}
|
||||
template<> inline PIDateTime PIVariant::value() const {return toDateTime();}
|
||||
template<> inline PIString PIVariant::value() const {return toString();}
|
||||
template<> inline PIStringList PIVariant::value() const {return toStringList();}
|
||||
template<> inline PIBitArray PIVariant::value() const {return toBitArray();}
|
||||
template<> inline PIByteArray PIVariant::value() const {return toByteArray();}
|
||||
template<> inline PIVariantTypes::Enum PIVariant::value() const {return toEnum();}
|
||||
template<> inline PIVariantTypes::File PIVariant::value() const {return toFile();}
|
||||
template<> inline PIVariantTypes::Dir PIVariant::value() const {return toDir();}
|
||||
template<> inline PIVariantTypes::Color PIVariant::value() const {return toColor();}
|
||||
template<> inline PIVariantTypes::IODevice PIVariant::value() const {return toIODevice();}
|
||||
template<> inline PIPointd PIVariant::value() const {return toPoint();}
|
||||
template<> inline PIRectd PIVariant::value() const {return toRect();}
|
||||
template<> inline PILined PIVariant::value() const {return toLine();}
|
||||
template<> inline PIVariant PIVariant::value() const {return *this;}
|
||||
|
||||
template<> inline PIVariant PIVariant::fromValue(const bool & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const char & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const uchar & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const short & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const ushort & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const int & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const uint & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const llong & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const ullong & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const float & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const double & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const ldouble & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIBitArray & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIByteArray & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIString & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIStringList & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PITime & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIDate & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIDateTime & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PISystemTime & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::Enum & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::File & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::Dir & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::Color & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::IODevice & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIPointd & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIRectd & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PILined & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIMathVectord & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIMathMatrixd & v) {return PIVariant(v);}
|
||||
template<> inline PIVariant PIVariant::fromValue(const PIVariant & v) {return PIVariant(v);}
|
||||
|
||||
template<> inline PIVariant::Type PIVariant::getType<bool>() {return PIVariant::pivBool;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<char>() {return PIVariant::pivChar;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<uchar>() {return PIVariant::pivUChar;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<short>() {return PIVariant::pivShort;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<ushort>() {return PIVariant::pivUShort;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<int>() {return PIVariant::pivInt;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<uint>() {return PIVariant::pivUInt;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<llong>() {return PIVariant::pivLLong;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<ullong>() {return PIVariant::pivULLong;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<float>() {return PIVariant::pivFloat;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<double>() {return PIVariant::pivDouble;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<ldouble>() {return PIVariant::pivLDouble;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIBitArray>() {return PIVariant::pivBitArray;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIByteArray>() {return PIVariant::pivByteArray;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIString>() {return PIVariant::pivString;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIStringList>() {return PIVariant::pivStringList;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PITime>() {return PIVariant::pivTime;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIDate>() {return PIVariant::pivDate;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIDateTime>() {return PIVariant::pivDateTime;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PISystemTime>() {return PIVariant::pivSystemTime;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::Enum>() {return PIVariant::pivEnum;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::File>() {return PIVariant::pivFile;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::Dir>() {return PIVariant::pivDir;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::Color>() {return PIVariant::pivColor;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::IODevice>() {return PIVariant::pivIODevice;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIPointd>() {return PIVariant::pivPoint;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIRectd>() {return PIVariant::pivRect;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PILined>() {return PIVariant::pivLine;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIMathVectord>() {return PIVariant::pivMathVector;}
|
||||
template<> inline PIVariant::Type PIVariant::getType<PIMathMatrixd>() {return PIVariant::pivMathMatrix;}
|
||||
|
||||
REGISTER_VARIANT(bool)
|
||||
REGISTER_VARIANT(char)
|
||||
REGISTER_VARIANT(uchar)
|
||||
REGISTER_VARIANT(short)
|
||||
REGISTER_VARIANT(ushort)
|
||||
REGISTER_VARIANT(int)
|
||||
REGISTER_VARIANT(uint)
|
||||
REGISTER_VARIANT(llong)
|
||||
REGISTER_VARIANT(ullong)
|
||||
REGISTER_VARIANT(float)
|
||||
REGISTER_VARIANT(double)
|
||||
REGISTER_VARIANT(ldouble)
|
||||
REGISTER_VARIANT(PIBitArray)
|
||||
REGISTER_VARIANT(PIByteArray)
|
||||
REGISTER_VARIANT(PIString)
|
||||
REGISTER_VARIANT(PIStringList)
|
||||
REGISTER_VARIANT(PITime)
|
||||
REGISTER_VARIANT(PIDate)
|
||||
REGISTER_VARIANT(PIDateTime)
|
||||
REGISTER_VARIANT(PISystemTime)
|
||||
REGISTER_NS_VARIANT(PIVariantTypes, Enum)
|
||||
REGISTER_NS_VARIANT(PIVariantTypes, File)
|
||||
REGISTER_NS_VARIANT(PIVariantTypes, Dir)
|
||||
REGISTER_NS_VARIANT(PIVariantTypes, Color)
|
||||
REGISTER_NS_VARIANT(PIVariantTypes, IODevice)
|
||||
REGISTER_VARIANT(PIPointd)
|
||||
REGISTER_VARIANT(PIRectd)
|
||||
REGISTER_VARIANT(PILined)
|
||||
REGISTER_VARIANT(PIMathVectord)
|
||||
REGISTER_VARIANT(PIMathMatrixd)
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIVariant) {
|
||||
s << v._content << v._type;
|
||||
if (v._type == PIVariant::pivCustom) {
|
||||
#ifdef CUSTOM_PIVARIANT
|
||||
if (v._info) {
|
||||
s << v._info->typeName;
|
||||
} else {
|
||||
s << PIStringAscii("");
|
||||
}
|
||||
#else
|
||||
s << PIStringAscii("");
|
||||
#endif
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ(PIVariant) {
|
||||
s >> v._content >> v._type;
|
||||
if (v._type == PIVariant::pivCustom) {
|
||||
PIString tn;
|
||||
s >> tn;
|
||||
#ifdef CUSTOM_PIVARIANT
|
||||
PIByteArray vc = v._content;
|
||||
v = PIVariant::fromValue(vc, tn);
|
||||
#endif
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
inline PICout operator <<(PICout s, const PIVariant & v) {
|
||||
s.space(); s.saveAndSetControls(0);
|
||||
s << "PIVariant(" << v.typeName();
|
||||
if (v.isValid())
|
||||
s << ", " << v.toString();
|
||||
s << ")";
|
||||
s.restoreControls(); return s;
|
||||
}
|
||||
|
||||
|
||||
#endif // PIVARIANT_H
|
||||
@@ -1,186 +0,0 @@
|
||||
/*! \file pivariantsimple.h
|
||||
* \ingroup Core
|
||||
* \brief
|
||||
* \~english Simple variant type
|
||||
* \~russian Простой вариативный тип
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Variant simple type
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIVARIANTSIMPLE_H
|
||||
#define PIVARIANTSIMPLE_H
|
||||
|
||||
#include "pistring.h"
|
||||
#include <typeinfo>
|
||||
#ifdef MICRO_PIP
|
||||
#include "pivariant.h"
|
||||
#endif
|
||||
|
||||
|
||||
class __VariantFunctionsBase__ {
|
||||
public:
|
||||
virtual __VariantFunctionsBase__ * instance() {return 0;}
|
||||
virtual PIString typeName() const {return PIString();}
|
||||
virtual uint hash() const {return 0;}
|
||||
virtual void newT(void *& ptr, const void * value) {;}
|
||||
virtual void newNullT(void *& ptr) {;}
|
||||
virtual void assignT(void *& ptr, const void * value) {;}
|
||||
virtual void deleteT(void *& ptr) {;}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class __VariantFunctions__: public __VariantFunctionsBase__ {
|
||||
public:
|
||||
__VariantFunctionsBase__ * instance() final {static __VariantFunctions__<T> ret; return &ret;}
|
||||
#ifdef MICRO_PIP
|
||||
PIString typeName() const final {static PIString ret(PIVariant(T()).typeName()); return ret;}
|
||||
#else
|
||||
PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;}
|
||||
#endif
|
||||
uint hash() const final {static uint ret = typeName().hash(); return ret;}
|
||||
void newT(void *& ptr, const void * value) final {ptr = (void*)(new T(*(const T*)value));}
|
||||
void newNullT(void *& ptr) final {ptr = (void*)(new T());}
|
||||
void assignT(void *& ptr, const void * value) final {*(T*)ptr = *(const T*)value;}
|
||||
void deleteT(void *& ptr) final {delete (T*)(ptr);}
|
||||
};
|
||||
|
||||
|
||||
//! \addtogroup Core
|
||||
//! \{
|
||||
//! \~\class PIVariantSimple pivariantsimple.h
|
||||
//! \~\brief
|
||||
//! \~english Simple variant type.
|
||||
//! \~russian Простой вариативный тип.
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//!
|
||||
//! \~russian
|
||||
//!
|
||||
//! \}
|
||||
class PIVariantSimple {
|
||||
public:
|
||||
|
||||
//! \~english Construct null %PIVariantSimple
|
||||
//! \~russian Создает пустой %PIVariantSimple
|
||||
PIVariantSimple() {ptr = 0; f = 0;}
|
||||
|
||||
//! \~english Contructs a copy of %PIVariantSimple.
|
||||
//! \~russian Создает копию %PIVariantSimple.
|
||||
PIVariantSimple(const PIVariantSimple & v) {
|
||||
ptr = 0;
|
||||
f = v.f;
|
||||
if (f && v.ptr)
|
||||
f->newT(ptr, v.ptr);
|
||||
}
|
||||
~PIVariantSimple() {destroy();}
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
PIVariantSimple & operator=(const PIVariantSimple & v) {
|
||||
destroy();
|
||||
f = v.f;
|
||||
if (f && v.ptr)
|
||||
f->newT(ptr, v.ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Set value to "v".
|
||||
//! \~russian Устанавливает значение в "v".
|
||||
template <typename T>
|
||||
void setValue(const T & v) {
|
||||
if (f) {
|
||||
if (isMyType<T>()) {
|
||||
f->assignT(ptr, (const void *)&v);
|
||||
return;
|
||||
}
|
||||
}
|
||||
destroy();
|
||||
f = __VariantFunctions__<T>().instance();
|
||||
f->newT(ptr, (const void *)&v);
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Returns value as type "T".
|
||||
//! \~russian Возвращает значение как тип "T".
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In contrast of PIVariant this class has strong check of type.
|
||||
//! Returns value only if this type was set before.
|
||||
//!
|
||||
//! \~russian
|
||||
//! В отличии от PIVariant этот класс строго проверяет типы.
|
||||
//! Возвращает значение только если этот же тип был установлен ранее.
|
||||
//!
|
||||
template <typename T>
|
||||
T value() const {
|
||||
if (!f) return T();
|
||||
if (!isMyType<T>())
|
||||
return T();
|
||||
return *(T*)(ptr);
|
||||
}
|
||||
|
||||
//! \~english Returns %PIVariantSimple with value "v".
|
||||
//! \~russian Возвращает %PIVariantSimple со значением "v".
|
||||
template <typename T>
|
||||
static PIVariantSimple fromValue(const T & v) {
|
||||
PIVariantSimple ret;
|
||||
ret.setValue(v);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
bool isMyType() const {
|
||||
if (!f) return false;
|
||||
uint mh = f->hash(), th = __VariantFunctions__<T>().instance()->hash();
|
||||
if (mh == 0 || th == 0) return false;
|
||||
return mh == th;
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
if (ptr && f)
|
||||
f->deleteT(ptr);
|
||||
ptr = 0;
|
||||
f = 0;
|
||||
}
|
||||
|
||||
void * ptr;
|
||||
__VariantFunctionsBase__ * f;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define REGISTER_PIVARIANTSIMPLE(Type) \
|
||||
template<> \
|
||||
class __VariantFunctions__<Type>: public __VariantFunctionsBase__ { \
|
||||
public: \
|
||||
__VariantFunctionsBase__ * instance() final {static __VariantFunctions__<Type> ret; return &ret;} \
|
||||
PIString typeName() const final {static PIString ret(#Type); return ret;} \
|
||||
uint hash() const final {static uint ret = typeName().hash(); return ret;} \
|
||||
void newT(void *& ptr, const void * value) final {ptr = (void*)(new Type(*(const Type *)value));} \
|
||||
void newNullT(void *& ptr) final {ptr = (void*)(new Type());} \
|
||||
void assignT(void *& ptr, const void * value) final {*(Type *)ptr = *(const Type *)value;} \
|
||||
void deleteT(void *& ptr) final {delete (Type *)(ptr);} \
|
||||
};
|
||||
|
||||
REGISTER_PIVARIANTSIMPLE(std::function<void(void*)>)
|
||||
|
||||
#endif // PIVARIANTSIMPLE_H
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Variant types
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pivarianttypes.h"
|
||||
#include "pipropertystorage.h"
|
||||
#ifndef MICRO_PIP
|
||||
# include "piiodevice.h"
|
||||
#endif
|
||||
|
||||
|
||||
int PIVariantTypes::Enum::selectedValue() const {
|
||||
for (const auto & e: enum_list)
|
||||
if (e.name == selected)
|
||||
return e.value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool PIVariantTypes::Enum::selectValue(int v) {
|
||||
for (const auto & e: enum_list)
|
||||
if (e.value == v) {
|
||||
selected = e.name;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PIVariantTypes::Enum::selectName(const PIString & n) {
|
||||
for (const auto & e: enum_list)
|
||||
if (e.name == n) {
|
||||
selected = e.name;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int PIVariantTypes::Enum::value(const PIString & n) const {
|
||||
for (const auto & e: enum_list)
|
||||
if (e.name == n)
|
||||
return e.value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
PIString PIVariantTypes::Enum::name(int v) const {
|
||||
for (const auto & e: enum_list)
|
||||
if (e.value == v)
|
||||
return e.name;
|
||||
return PIString();
|
||||
}
|
||||
|
||||
|
||||
PIVector<int> PIVariantTypes::Enum::values() const {
|
||||
PIVector<int> ret;
|
||||
for (const auto & e: enum_list)
|
||||
ret << e.value;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIStringList PIVariantTypes::Enum::names() const {
|
||||
PIStringList ret;
|
||||
for (const auto & e: enum_list)
|
||||
ret << e.name;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PIVariantTypes::IODevice::IODevice() {
|
||||
#ifndef MICRO_PIP
|
||||
mode = PIIODevice::ReadWrite;
|
||||
#else
|
||||
mode = 0; // TODO: PIIODevice for MICRO PIP
|
||||
#endif // MICRO_PIP
|
||||
options = 0;
|
||||
}
|
||||
|
||||
|
||||
void PIVariantTypes::IODevice::set(const PIPropertyStorage & ps) {
|
||||
props.clear();
|
||||
props << ps;
|
||||
}
|
||||
|
||||
|
||||
PIPropertyStorage PIVariantTypes::IODevice::get() const {
|
||||
PIPropertyStorage ret;
|
||||
PIByteArray ba = props;
|
||||
if (!ba.isEmpty()) ba >> ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIString PIVariantTypes::IODevice::toPICout() const {
|
||||
PIString s;
|
||||
s += "IODevice(" + prefix + ", mode=";
|
||||
int rwc = 0;
|
||||
if (mode & 1) {s += "r"; ++rwc;}
|
||||
if (mode & 2) {s += "w"; ++rwc;}
|
||||
if (rwc == 1) s += "o";
|
||||
s += ", flags=";
|
||||
#ifndef MICRO_PIP // TODO: PIIODevice for MICRO PIP
|
||||
if (options != 0) {
|
||||
if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingRead])
|
||||
s += " br";
|
||||
if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingWrite])
|
||||
s += " bw";
|
||||
}
|
||||
#endif // MICRO_PIP
|
||||
PIPropertyStorage ps = get();
|
||||
piForeachC (PIPropertyStorage::Property & p, ps) {
|
||||
s += ", " + p.name + "=\"" + p.value.toString() + "\"";
|
||||
}
|
||||
s += ")";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PIVariantTypes::Enum & PIVariantTypes::Enum::operator <<(const PIVariantTypes::Enumerator & v) {
|
||||
enum_list << v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIVariantTypes::Enum & PIVariantTypes::Enum::operator <<(const PIString & v) {
|
||||
if (enum_list.isEmpty()) {
|
||||
enum_list << Enumerator(0, v);
|
||||
} else {
|
||||
enum_list << Enumerator(enum_list.back().value + 1, v);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIVariantTypes::Enum & PIVariantTypes::Enum::operator <<(const PIStringList & v) {
|
||||
for (const auto & s: v)
|
||||
(*this) << s;
|
||||
return *this;
|
||||
}
|
||||
@@ -1,379 +0,0 @@
|
||||
/*! \file pivarianttypes.h
|
||||
* \ingroup Core
|
||||
* \brief
|
||||
* \~english Types for PIVariant
|
||||
* \~russian Типы для PIVariant
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Variant types
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIVARIANTYPES_H
|
||||
#define PIVARIANTYPES_H
|
||||
|
||||
#include "pistringlist.h"
|
||||
|
||||
|
||||
class PIPropertyStorage;
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \relatesalso PIVariant
|
||||
//! \~english Namespace contains several types for PIVariant
|
||||
//! \~russian Пространство имен содержит некоторые типы для PIVariant
|
||||
namespace PIVariantTypes {
|
||||
|
||||
|
||||
//! \addtogroup Core
|
||||
//! \{
|
||||
//! \~\struct Enumerator pivarianttypes.h
|
||||
//! \~\brief
|
||||
//! \~english Name-value pair.
|
||||
//! \~russian Пара имя-значение.
|
||||
//! \}
|
||||
struct PIP_EXPORT Enumerator {
|
||||
Enumerator(int v = 0, const PIString & n = PIString()): value(v), name(n) {}
|
||||
|
||||
//! \~english Value.
|
||||
//! \~russian Значение.
|
||||
int value;
|
||||
|
||||
//! \~english Name.
|
||||
//! \~russian Имя.
|
||||
PIString name;
|
||||
};
|
||||
|
||||
|
||||
//! \addtogroup Core
|
||||
//! \{
|
||||
//! \~\struct Enum pivarianttypes.h
|
||||
//! \~\brief
|
||||
//! \~english Collection of PIVariantTypes::Enumerator.
|
||||
//! \~russian Набор PIVariantTypes::Enumerator.
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This class represents classic c-style enum.
|
||||
//! Contains elements with unique names and not uniqueue values, also
|
||||
//! name of enum and selected member.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Этот класс представляет классический c-style enum.
|
||||
//! Содержит элементы с уникальными именами и неуникальными значениями,
|
||||
//! а также имя перечисления и выбранного элемента.
|
||||
//!
|
||||
//! \}
|
||||
struct PIP_EXPORT Enum {
|
||||
Enum(const PIString & n = PIString()): enum_name(n) {}
|
||||
|
||||
//! \~english Returns selected value, or 0 if there is no name in members.
|
||||
//! \~russian Возвращает выбранное значение, или 0, если выбранного имени нет в элементах.
|
||||
int selectedValue() const;
|
||||
|
||||
//! \~english Returns selected name.
|
||||
//! \~russian Возвращает выбранное имя.
|
||||
PIString selectedName() const {return selected;}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Select value if exists in Enum.
|
||||
//! \~russian Выбирает значение, если оно существует в Enum.
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! If Enum contains several PIVariantTypes::Enumerator with same values,
|
||||
//! first PIVariantTypes::Enumerator will selected.
|
||||
//! Returns if value exists in Enum.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Если Enum содержит несколько PIVariantTypes::Enumerator с этим значением,
|
||||
//! то будет выбран первый.
|
||||
//! Возвращает существовал ли такой Enum.
|
||||
//!
|
||||
bool selectValue(int v);
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Select name if exists in Enum.
|
||||
//! \~russian Выбирает имя, если оно существует в Enum.
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Returns if name exists in Enum.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Возвращает существовал ли такой Enum.
|
||||
//!
|
||||
bool selectName(const PIString & n);
|
||||
|
||||
//! \~english Find PIVariantTypes::Enumerator with name "n" and return it value, otherwise 0.
|
||||
//! \~russian Ищет PIVariantTypes::Enumerator с именем "n" и возвращает его значение, иначе 0.
|
||||
int value(const PIString & n) const;
|
||||
|
||||
//! \~english Find PIVariantTypes::Enumerator with value "v" and return it name, otherwise empty string.
|
||||
//! \~russian Ищет PIVariantTypes::Enumerator со значением "v" и возвращает его имя, иначе пустую строку.
|
||||
PIString name(int v) const;
|
||||
|
||||
//! \~english Returns all members values.
|
||||
//! \~russian Возвращает все значения членов.
|
||||
PIVector<int> values() const;
|
||||
|
||||
//! \~english Returns all members names.
|
||||
//! \~russian Возвращает все имена членов.
|
||||
PIStringList names() const;
|
||||
|
||||
//! \~english Add PIVariantTypes::Enumerator to Enum.
|
||||
//! \~russian Добавляет в Enum PIVariantTypes::Enumerator.
|
||||
Enum & operator <<(const Enumerator & v);
|
||||
|
||||
//! \~english Add PIVariantTypes::Enumerator with name "v" and value of last element + 1, otherwise 0.
|
||||
//! \~russian Добавляет PIVariantTypes::Enumerator с именем "v" и значением последнего элемента + 1, иначе 0.
|
||||
Enum & operator <<(const PIString & v);
|
||||
|
||||
//! \~english Add PIVariantTypes::Enumerator element for each name of vector.
|
||||
//! \~russian Добавляет PIVariantTypes::Enumerator для каждой строки из массива.
|
||||
Enum & operator <<(const PIStringList & v);
|
||||
|
||||
//! \~english Returns if Enum is empty.
|
||||
//! \~russian Возвращает пустой ли Enum.
|
||||
bool isEmpty() const {return enum_list.isEmpty();}
|
||||
|
||||
|
||||
//! \~english Name of Enum.
|
||||
//! \~russian Имя Enum.
|
||||
PIString enum_name;
|
||||
|
||||
//! \~english Name of selected element.
|
||||
//! \~russian Имя выбранного элемента.
|
||||
PIString selected;
|
||||
|
||||
//! \~english Members.
|
||||
//! \~russian Элементы.
|
||||
PIVector<Enumerator> enum_list;
|
||||
};
|
||||
|
||||
|
||||
//! \addtogroup Core
|
||||
//! \{
|
||||
//! \~\struct File pivarianttypes.h
|
||||
//! \~\brief
|
||||
//! \~english File location description.
|
||||
//! \~russian Описание положения файла.
|
||||
//! \}
|
||||
struct PIP_EXPORT File {
|
||||
File(const PIString & p = PIString(), const PIString & f = PIString(), bool abs = false, bool save_mode = false):
|
||||
file(p), filter(f), is_abs(abs), is_save(save_mode) {}
|
||||
|
||||
//! \~english Returns path.
|
||||
//! \~russian Возвращает путь.
|
||||
PIString toString() const {return file;}
|
||||
|
||||
//! \~english Path.
|
||||
//! \~russian Путь.
|
||||
PIString file;
|
||||
|
||||
//! \~english Name filter.
|
||||
//! \~russian Фильтр имени.
|
||||
PIString filter;
|
||||
|
||||
//! \~english If path is absolute.
|
||||
//! \~russian Абсолютный ли путь.
|
||||
bool is_abs;
|
||||
|
||||
//! \~english If save is available.
|
||||
//! \~russian Доступно ли сохранение.
|
||||
bool is_save;
|
||||
};
|
||||
|
||||
|
||||
//! \addtogroup Core
|
||||
//! \{
|
||||
//! \~\struct Dir pivarianttypes.h
|
||||
//! \~\brief
|
||||
//! \~english Directory description.
|
||||
//! \~russian Описание директории.
|
||||
//! \}
|
||||
struct PIP_EXPORT Dir {
|
||||
Dir(const PIString & d = PIString(), bool abs = false):
|
||||
dir(d), is_abs(abs) {}
|
||||
|
||||
//! \~english Returns path.
|
||||
//! \~russian Возвращает путь.
|
||||
PIString toString() const {return dir;}
|
||||
|
||||
//! \~english Path.
|
||||
//! \~russian Путь.
|
||||
PIString dir;
|
||||
|
||||
//! \~english If path is absolute.
|
||||
//! \~russian Абсолютный ли путь.
|
||||
bool is_abs;
|
||||
};
|
||||
|
||||
|
||||
//! \addtogroup Core
|
||||
//! \{
|
||||
//! \~\struct Color pivarianttypes.h
|
||||
//! \~\brief
|
||||
//! \~english 32-bits color.
|
||||
//! \~russian 32-битный цвет.
|
||||
//! \}
|
||||
struct PIP_EXPORT Color {
|
||||
Color(uint v = 0) {rgba = v;}
|
||||
|
||||
//! \~english Integer color.
|
||||
//! \~russian Целочисленный цвет.
|
||||
uint rgba;
|
||||
};
|
||||
|
||||
|
||||
//! \addtogroup Core
|
||||
//! \{
|
||||
//! \~\struct IODevice pivarianttypes.h
|
||||
//! \~\brief
|
||||
//! \~english Input/output device description.
|
||||
//! \~russian Описание устройства ввода/вывода.
|
||||
//! \}
|
||||
struct PIP_EXPORT IODevice {
|
||||
IODevice();
|
||||
|
||||
//! \~english Serialize "ps" and set it to "props".
|
||||
//! \~russian Сериализует "ps" и устанавливает "props".
|
||||
void set(const PIPropertyStorage & ps);
|
||||
|
||||
//! \~english Deserialize "props" and returns it.
|
||||
//! \~russian Десериализует "props" и возвращает свойства.
|
||||
PIPropertyStorage get() const;
|
||||
|
||||
//! \~english Returns string for PICout.
|
||||
//! \~russian Возвращает строку для PICout.
|
||||
PIString toPICout() const;
|
||||
|
||||
//! \~english PIIODevice prefix, see \ref PIIODevice_sec7.
|
||||
//! \~russian Префикс PIIODevice, см. \ref PIIODevice_sec7.
|
||||
PIString prefix;
|
||||
|
||||
//! PIIODevice::DeviceMode.
|
||||
int mode;
|
||||
|
||||
//! PIIODevice::DeviceOptions.
|
||||
int options;
|
||||
|
||||
//! \~english Serialized properties.
|
||||
//! \~russian Сериализованные свойства.
|
||||
PIByteArray props;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
inline PICout operator <<(PICout s, const PIVariantTypes::Enumerator & v) {s << v.name << "(" << v.value << ")"; return s;}
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
inline PICout operator <<(PICout s, const PIVariantTypes::Enum & v) {s << "Enum(" << v.selectedValue() << "=" << v.selectedName() << ")"; return s;}
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
inline PICout operator <<(PICout s, const PIVariantTypes::File & v) {s << "File(\"" << v.file << "\")"; return s;}
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
inline PICout operator <<(PICout s, const PIVariantTypes::Dir & v) {s << "Dir(\"" << v.dir << "\")"; return s;}
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
inline PICout operator <<(PICout s, const PIVariantTypes::Color & v) {s.saveControls(); s << PICoutManipulators::Hex << "Color(#" << v.rgba << ")"; s.restoreControls(); return s;}
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
inline PICout operator <<(PICout s, const PIVariantTypes::IODevice & v) {s << v.toPICout(); return s;}
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIVariantTypes::Enumerator) {s << v.value << v.name; return s;}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ (PIVariantTypes::Enumerator) {s >> v.value >> v.name; return s;}
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIVariantTypes::Enum) {s << v.enum_name << v.selected << v.enum_list; return s;}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ (PIVariantTypes::Enum) {s >> v.enum_name >> v.selected >> v.enum_list; return s;}
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIVariantTypes::File) {s << v.file << v.filter << uchar((v.is_abs ? 1 : 0) + (v.is_save ? 2 : 0)); return s;}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ (PIVariantTypes::File) {uchar f(0); s >> v.file >> v.filter >> f; v.is_abs = ((f & 1) == 1); v.is_save = ((f & 2) == 2); return s;}
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIVariantTypes::Dir) {s << v.dir << v.is_abs; return s;}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ (PIVariantTypes::Dir) {s >> v.dir >> v.is_abs; return s;}
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIVariantTypes::Color) {s << v.rgba; return s;}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ (PIVariantTypes::Color) {s >> v.rgba; return s;}
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIVariantTypes::IODevice) {s << v.prefix << v.mode << v.options << v.props; return s;}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ (PIVariantTypes::IODevice) {s >> v.prefix >> v.mode >> v.options >> v.props; return s;}
|
||||
|
||||
|
||||
#endif // PIVARIANTYPES_H
|
||||
Reference in New Issue
Block a user