diff --git a/3rd/lua/lapi.c b/3rd/lua/lapi.c index 02b7fab7..ec4bdddd 100644 --- a/3rd/lua/lapi.c +++ b/3rd/lua/lapi.c @@ -5,7 +5,7 @@ */ #define lapi_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lcode.c b/3rd/lua/lcode.c index 12619f54..7f32d33c 100644 --- a/3rd/lua/lcode.c +++ b/3rd/lua/lcode.c @@ -5,7 +5,7 @@ */ #define lcode_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lctype.c b/3rd/lua/lctype.c index f8ad7a2e..7d8123d2 100644 --- a/3rd/lua/lctype.c +++ b/3rd/lua/lctype.c @@ -5,7 +5,7 @@ */ #define lctype_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/ldebug.c b/3rd/lua/ldebug.c index e1389296..110146c9 100644 --- a/3rd/lua/ldebug.c +++ b/3rd/lua/ldebug.c @@ -5,7 +5,7 @@ */ #define ldebug_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/ldo.c b/3rd/lua/ldo.c index 316e45c8..36e7d26d 100644 --- a/3rd/lua/ldo.c +++ b/3rd/lua/ldo.c @@ -5,7 +5,7 @@ */ #define ldo_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/ldump.c b/3rd/lua/ldump.c index f025acac..222b372d 100644 --- a/3rd/lua/ldump.c +++ b/3rd/lua/ldump.c @@ -5,7 +5,7 @@ */ #define ldump_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lfunc.c b/3rd/lua/lfunc.c index ccafbb8a..897526c4 100644 --- a/3rd/lua/lfunc.c +++ b/3rd/lua/lfunc.c @@ -5,7 +5,7 @@ */ #define lfunc_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lgc.c b/3rd/lua/lgc.c index db4df829..6fe4a808 100644 --- a/3rd/lua/lgc.c +++ b/3rd/lua/lgc.c @@ -5,7 +5,7 @@ */ #define lgc_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/llex.c b/3rd/lua/llex.c index 66fd411b..42f0f247 100644 --- a/3rd/lua/llex.c +++ b/3rd/lua/llex.c @@ -5,7 +5,7 @@ */ #define llex_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lmem.c b/3rd/lua/lmem.c index 0241cc3b..bf081c28 100644 --- a/3rd/lua/lmem.c +++ b/3rd/lua/lmem.c @@ -5,7 +5,7 @@ */ #define lmem_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lobject.c b/3rd/lua/lobject.c index 2218c8cd..25547694 100644 --- a/3rd/lua/lobject.c +++ b/3rd/lua/lobject.c @@ -5,7 +5,7 @@ */ #define lobject_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lopcodes.c b/3rd/lua/lopcodes.c index 5ca3eb26..744bda77 100644 --- a/3rd/lua/lopcodes.c +++ b/3rd/lua/lopcodes.c @@ -5,7 +5,7 @@ */ #define lopcodes_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lparser.c b/3rd/lua/lparser.c index cc54de43..23ebf10a 100644 --- a/3rd/lua/lparser.c +++ b/3rd/lua/lparser.c @@ -5,7 +5,7 @@ */ #define lparser_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lstate.c b/3rd/lua/lstate.c index c1a76643..fa96483f 100644 --- a/3rd/lua/lstate.c +++ b/3rd/lua/lstate.c @@ -5,7 +5,7 @@ */ #define lstate_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lstring.c b/3rd/lua/lstring.c index 6257f211..14103e22 100644 --- a/3rd/lua/lstring.c +++ b/3rd/lua/lstring.c @@ -5,7 +5,7 @@ */ #define lstring_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/ltable.c b/3rd/lua/ltable.c index ea4fe7fc..ae9145f1 100644 --- a/3rd/lua/ltable.c +++ b/3rd/lua/ltable.c @@ -5,7 +5,7 @@ */ #define ltable_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/ltm.c b/3rd/lua/ltm.c index 0e7c7132..aa61c87d 100644 --- a/3rd/lua/ltm.c +++ b/3rd/lua/ltm.c @@ -5,7 +5,7 @@ */ #define ltm_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lundump.c b/3rd/lua/lundump.c index 7a67d75a..b3e79253 100644 --- a/3rd/lua/lundump.c +++ b/3rd/lua/lundump.c @@ -5,7 +5,7 @@ */ #define lundump_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lvm.c b/3rd/lua/lvm.c index cc43d871..da27d5e9 100644 --- a/3rd/lua/lvm.c +++ b/3rd/lua/lvm.c @@ -5,7 +5,7 @@ */ #define lvm_c -#define LUA_CORE + #include "lprefix.h" diff --git a/3rd/lua/lzio.c b/3rd/lua/lzio.c index 6f790944..b2ef5c4c 100644 --- a/3rd/lua/lzio.c +++ b/3rd/lua/lzio.c @@ -5,7 +5,7 @@ */ #define lzio_c -#define LUA_CORE + #include "lprefix.h" diff --git a/CMakeLists.txt b/CMakeLists.txt index eaa103d9..8b5e0fcb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) -set(pip_MINOR 39) +set(pip_MINOR 94) set(pip_REVISION 0) set(pip_SUFFIX ) set(pip_COMPANY SHS) diff --git a/libs/cloud/picloudtcp.cpp b/libs/cloud/picloudtcp.cpp index 178560fe..a5ff2a6c 100644 --- a/libs/cloud/picloudtcp.cpp +++ b/libs/cloud/picloudtcp.cpp @@ -168,14 +168,14 @@ PIByteArray PICloud::TCP::parseConnect_d(PIByteArray & ba) { uint PICloud::TCP::parseConnect(PIByteArray & ba) { - uint ret; + uint ret = 0; ba >> ret; return ret; } uint PICloud::TCP::parseDisconnect(PIByteArray & ba) { - uint ret; + uint ret = 0; ba >> ret; return ret; } diff --git a/libs/compress/picompress.cpp b/libs/compress/picompress.cpp index 6fc21a30..3e450960 100644 --- a/libs/compress/picompress.cpp +++ b/libs/compress/picompress.cpp @@ -53,7 +53,7 @@ PIByteArray piCompress(const PIByteArray & ba, int level) { PIByteArray piDecompress(const PIByteArray & zba) { #ifdef PIP_COMPRESS - ullong sz; + ullong sz = 0; if (zba.size() < sizeof(ullong)) { piCout << "[PICompress]" << "Error: invalid input"; return zba; diff --git a/libs/console/piscreen.cpp b/libs/console/piscreen.cpp index 6ee52ebe..fa8388a2 100644 --- a/libs/console/piscreen.cpp +++ b/libs/console/piscreen.cpp @@ -51,6 +51,18 @@ PRIVATE_DEFINITION_END(PIScreen::SystemConsole) PIScreen::SystemConsole::SystemConsole() { width = height = pwidth = pheight = 0; mouse_x = mouse_y = -1; +} + + +PIScreen::SystemConsole::~SystemConsole() { +#ifdef WINDOWS + SetConsoleMode(PRIVATE->hOut, PRIVATE->smode); + SetConsoleTextAttribute(PRIVATE->hOut, PRIVATE->dattr); +#endif +} + + +void PIScreen::SystemConsole::begin() { int w, h; #ifdef WINDOWS PRIVATE->ulcoord.X = 0; @@ -74,18 +86,6 @@ PIScreen::SystemConsole::SystemConsole() { # endif #endif resize(w, h); -} - - -PIScreen::SystemConsole::~SystemConsole() { -#ifdef WINDOWS - SetConsoleMode(PRIVATE->hOut, PRIVATE->smode); - SetConsoleTextAttribute(PRIVATE->hOut, PRIVATE->dattr); -#endif -} - - -void PIScreen::SystemConsole::begin() { #ifdef WINDOWS SetConsoleMode(PRIVATE->hOut, ENABLE_WRAP_AT_EOL_OUTPUT); GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi); @@ -93,6 +93,7 @@ void PIScreen::SystemConsole::begin() { PRIVATE->bc.Y = 0; #endif clear(); + clearScreen(); hideCursor(); } diff --git a/libs/main/code/picodeparser.cpp b/libs/main/code/picodeparser.cpp index 81e86bbd..92947f25 100644 --- a/libs/main/code/picodeparser.cpp +++ b/libs/main/code/picodeparser.cpp @@ -1050,7 +1050,7 @@ PIString PICodeParser::procMacros(PIString fc) { if (ifcnt > 0) ifcnt--; else { //piCout << "main endif" << skip << grab; - if (grab) pfc << procMacros(nfc); + if (grab) pfc += procMacros(nfc); skip = grab = false; continue; } @@ -1059,7 +1059,7 @@ PIString PICodeParser::procMacros(PIString fc) { //piCout << "main elif" << skip << grab << cond_ok; if (cond_ok) { if (grab) { - pfc << procMacros(nfc); + pfc += procMacros(nfc); skip = true; grab = false; } continue; @@ -1075,12 +1075,12 @@ PIString PICodeParser::procMacros(PIString fc) { } if (mif.left(4) == s_else && ifcnt == 0) { //piCout << "main else" << skip << grab; - if (grab) pfc << procMacros(nfc); + if (grab) pfc += procMacros(nfc); if (skip && !cond_ok) {skip = false; grab = true;} else {skip = true; grab = false;} continue; } - if (grab) nfc << line << '\n'; + if (grab) nfc += line + '\n'; continue; } if (mif.left(2) == s_if) { @@ -1095,8 +1095,8 @@ PIString PICodeParser::procMacros(PIString fc) { //return false; /// WARNING: now skip errors } } else { - if (grab) nfc << line << '\n'; - else if (!skip) pfc << line << '\n'; + if (grab) nfc += line + '\n'; + else if (!skip) pfc += line + '\n'; } } return pfc; diff --git a/libs/main/console/pikbdlistener.h b/libs/main/console/pikbdlistener.h index 9ce0373f..0488be55 100644 --- a/libs/main/console/pikbdlistener.h +++ b/libs/main/console/pikbdlistener.h @@ -247,13 +247,11 @@ private: }; -inline PIByteArray & operator <<(PIByteArray & s, const PIKbdListener::KeyEvent & v) {s << v.key << v.modifiers; return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIKbdListener::MouseEvent & v) {s << v.x << v.y << (int)v.action << v.buttons << v.modifiers; return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIKbdListener::WheelEvent & v) {s << (*(PIKbdListener::MouseEvent*)&v) << (uchar)v.direction; return s;} +BINARY_STREAM_WRITE(PIKbdListener::MouseEvent) {s << v.x << v.y << v.action << v.buttons << v.modifiers; return s;} +BINARY_STREAM_READ (PIKbdListener::MouseEvent) {s >> v.x >> v.y >> v.action >> v.buttons >> v.modifiers; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::KeyEvent & v) {s >> v.key >> v.modifiers; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::MouseEvent & v) {int a(0); s >> v.x >> v.y >> a >> v.buttons >> v.modifiers; v.action = (PIKbdListener::MouseAction)a; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::WheelEvent & v) {uchar d(0); s >> (*(PIKbdListener::MouseEvent*)&v) >> d; v.direction = d; return s;} +BINARY_STREAM_WRITE(PIKbdListener::WheelEvent) {s << (*(PIKbdListener::MouseEvent*)&v) << v.direction; return s;} +BINARY_STREAM_READ (PIKbdListener::WheelEvent) {s >> (*(PIKbdListener::MouseEvent*)&v) >> v.direction; return s;} REGISTER_PIVARIANTSIMPLE(PIKbdListener::KeyEvent) REGISTER_PIVARIANTSIMPLE(PIKbdListener::MouseEvent) diff --git a/libs/main/console/piscreentypes.h b/libs/main/console/piscreentypes.h index 6a6b4288..328ea87f 100644 --- a/libs/main/console/piscreentypes.h +++ b/libs/main/console/piscreentypes.h @@ -143,11 +143,14 @@ namespace PIScreenTypes { } -inline PIByteArray & operator <<(PIByteArray & s, const PIScreenTypes::Cell & v) {s << v.format.raw_format << v.symbol; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIScreenTypes::Cell & v) {s >> v.format.raw_format >> v.symbol; return s;} +//inline PIByteArray & operator <<(PIByteArray & s, const PIScreenTypes::Cell & v) {s << v.format.raw_format << v.symbol; return s;} +//inline PIByteArray & operator >>(PIByteArray & s, PIScreenTypes::Cell & v) {s >> v.format.raw_format >> v.symbol; return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIScreenTypes::TileEvent & v) {s << v.type << v.data; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIScreenTypes::TileEvent & v) {s >> v.type >> v.data; return s;} +BINARY_STREAM_WRITE(PIScreenTypes::Cell) {s << v.format.raw_format << v.symbol; return s;} +BINARY_STREAM_READ (PIScreenTypes::Cell) {s >> v.format.raw_format >> v.symbol; return s;} + +BINARY_STREAM_WRITE(PIScreenTypes::TileEvent) {s << v.type << v.data; return s;} +BINARY_STREAM_READ (PIScreenTypes::TileEvent) {s >> v.type >> v.data; return s;} REGISTER_PIVARIANTSIMPLE(PIScreenTypes::TileEvent) diff --git a/libs/main/containers/pimap.h b/libs/main/containers/pimap.h index 14640065..bfe94175 100644 --- a/libs/main/containers/pimap.h +++ b/libs/main/containers/pimap.h @@ -71,9 +71,11 @@ class PIMapIterator; template class PIMap { - template friend PIByteArray & operator >>(PIByteArray & s, PIMap & v); - template friend PIByteArray & operator <<(PIByteArray & s, const PIMap & v); template friend class PIMapIterator; + template + friend PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIMap & v); + template + friend PIBinaryStream

& operator >>(PIBinaryStream

& s, PIMap & v); public: PIMap() {;} PIMap(const PIMap & other) {*this = other;} @@ -295,8 +297,10 @@ protected: bool operator <(const MapIndex & s) const {return key < s.key;} bool operator >(const MapIndex & s) const {return key > s.key;} }; - template friend PIByteArray & operator >>(PIByteArray & s, PIDeque::MapIndex> & v); - template friend PIByteArray & operator <<(PIByteArray & s, const PIDeque::MapIndex> & v); + template + friend PIBinaryStream

& operator >>(PIBinaryStream

& s, PIDeque::MapIndex> & v); + template + friend PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIDeque::MapIndex> & v); ssize_t binarySearch(ssize_t first, ssize_t last, const Key & key, bool & found) const { ssize_t mid; diff --git a/libs/main/containers/pipair.h b/libs/main/containers/pipair.h index 40999910..d373e276 100644 --- a/libs/main/containers/pipair.h +++ b/libs/main/containers/pipair.h @@ -132,6 +132,10 @@ template< class T1, class T2 > PIPair createPIPair(const T1 & f, const T2 & s) { return PIPair(f, s); } +template< class T1, class T2 > +PIPair makePIPair(const T1 & f, const T2 & s) { + return PIPair(f, s); +} //! \~english Creates \a PIPair object, deducing the target type from the types of arguments. //! \~russian Создает \a PIPair выводя типы из аргументов. @@ -140,5 +144,9 @@ template< class T1, class T2 > PIPair createPIPair(T1 && f, T2 && s) { return PIPair(std::move(f), std::move(s)); } +template< class T1, class T2 > +PIPair makePIPair(T1 && f, T2 && s) { + return PIPair(std::move(f), std::move(s)); +} #endif // PIPAIR_H diff --git a/libs/main/core/pibase.h b/libs/main/core/pibase.h index 0a44cf74..832ea872 100644 --- a/libs/main/core/pibase.h +++ b/libs/main/core/pibase.h @@ -265,13 +265,15 @@ #ifdef CC_GCC # undef DEPRECATED +# undef DEPRECATEDM # define DEPRECATED __attribute__((deprecated)) +# define DEPRECATEDM(msg) __attribute__((deprecated(msg))) # if CC_GCC_VERSION > 0x025F // > 2.95 +# pragma GCC diagnostic warning "-Wdeprecated-declarations" # ifdef LINUX # define HAS_LOCALE # endif # ifdef MAC_OS -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" # pragma GCC diagnostic ignored "-Wundefined-bool-conversion" # pragma GCC diagnostic ignored "-Wc++11-extensions" # endif @@ -287,7 +289,9 @@ #ifdef CC_VC # undef DEPRECATED -# define DEPRECATED +# undef DEPRECATEDM +# define DEPRECATED __declspec(deprecated) +# define DEPRECATEDM(msg) __declspec(deprecated(msg)) # pragma warning(disable: 4018) # pragma warning(disable: 4061) # pragma warning(disable: 4100) @@ -312,7 +316,9 @@ #ifdef CC_OTHER # undef DEPRECATED +# undef DEPRECATEDM # define DEPRECATED +# define DEPRECATEDM(msg) #endif #endif //DOXYGEN diff --git a/libs/main/core/pibinarystream.h b/libs/main/core/pibinarystream.h new file mode 100644 index 00000000..c58a53f9 --- /dev/null +++ b/libs/main/core/pibinarystream.h @@ -0,0 +1,504 @@ +/*! \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 . +*/ + +#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 friend PIBinaryStream

& operator <<(PIBinaryStream

& s, const T & v); \ + template friend PIBinaryStream

& operator >>(PIBinaryStream

& s, T & v); +#define BINARY_STREAM_WRITE(T) \ + template inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const T & v) +#define BINARY_STREAM_READ(T) \ + template inline PIBinaryStream

& operator >>(PIBinaryStream

& s, T & v) + + +//! \ingroup Core +//! \~\brief +//! \~english Binary serialization interface. +//! \~russian Интерфейс бинарной сериализации. +template +class PIBinaryStream { +public: + // one should implement next methods: + // + // bool binaryStreamAppendImp(const void * d, size_t s); + // bool binaryStreamTakeImp ( void * d, size_t s); + + bool binaryStreamAppend(const void * d, size_t s) { + if (!static_cast(this)->binaryStreamAppendImp(d, s)) { + return false; + printf("[PIBinaryStream] binaryStreamAppend() error\n"); + } + return true; + } + bool binaryStreamTake(void * d, size_t s) { + if (!static_cast(this)->binaryStreamTakeImp(d, s)) { + return false; + printf("[PIBinaryStream] binaryStreamTake() error\n"); + } + return true; + } + template + void binaryStreamAppend(T v) {binaryStreamAppend(&v, sizeof(v));} + uchar binaryStreamTakeByte(bool * ok = nullptr) { + uchar r = 0; + if (binaryStreamTake(&r, sizeof(r))) { + if (ok) *ok = true; + } else { + if (ok) *ok = false; + } + return r; + } + int binaryStreamTakeInt(bool * ok = nullptr) { + int r = 0; + if (binaryStreamTake(&r, sizeof(r))) { + if (ok) *ok = true; + } else { + if (ok) *ok = false; + } + return r; + } +}; + + +// helper class to detect default operators +template +class PIBinaryStreamTrivialRef { +public: + PIBinaryStreamTrivialRef(PIBinaryStream

& s): p(s) {} + PIBinaryStream

& p; +}; + + +template inline PIBinaryStream

& operator <<(PIBinaryStreamTrivialRef

s, const T & v) {s.p << v; return s.p;} +template inline PIBinaryStream

& operator >>(PIBinaryStreamTrivialRef

s, T & v) {s.p >> v; return s.p;} + + +// specify types +template inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const bool v) {s.binaryStreamAppend((uchar)v); return s;} +template inline PIBinaryStream

& operator >>(PIBinaryStream

& s, bool & v) {v = s.binaryStreamTakeByte(); return s;} + +template inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIMemoryBlock v) { + s.binaryStreamAppend(v.data(), v.size()); + return s; +} +template inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIMemoryBlock v) { + s.binaryStreamTake(v.data(), v.size()); + return s; +} + + + + +// store simple types + + +template::value, int>::type = 0> +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const T & v) { + //piCout << "<< enum"; + s.binaryStreamAppend((int)v); + return s; +} + + +template::value, int>::type = 0, +typename std::enable_if< std::is_trivially_copyable::value, int>::type = 0> +inline PIBinaryStreamTrivialRef

operator <<(PIBinaryStream

& s, const T & v) { + s.binaryStreamAppend(&v, sizeof(v)); + return s; +} + + +//! \~english Store operator for PIVector of any trivial copyable type +//! \~russian Оператор сохранения для PIVector тривиальных типов +template::value, int>::type = 0, +typename std::enable_if< std::is_same&>() << std::declval()), PIBinaryStreamTrivialRef

>::value, int>::type = 0> +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIVector & v) { + //piCout << "<< vector trivial default"; + s.binaryStreamAppend((int)v.size()); + s.binaryStreamAppend(v.data(), v.size() * sizeof(T)); + return s; +} +template::value, int>::type = 0, +typename std::enable_if&>() << std::declval()), PIBinaryStreamTrivialRef

>::value, int>::type = 0> +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIVector & 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::value, int>::type = 0, +typename std::enable_if< std::is_same&>() << std::declval()), PIBinaryStreamTrivialRef

>::value, int>::type = 0> +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIDeque & v) { + //piCout << "<< deque trivial default"; + s.binaryStreamAppend((int)v.size()); + s.binaryStreamAppend(v.data(), v.size() * sizeof(T)); + return s; +} +template::value, int>::type = 0, +typename std::enable_if&>() << std::declval()), PIBinaryStreamTrivialRef

>::value, int>::type = 0> +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIDeque & 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::value, int>::type = 0, +typename std::enable_if< std::is_same&>() << std::declval()), PIBinaryStreamTrivialRef

>::value, int>::type = 0> +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIVector2D & 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::value, int>::type = 0, +typename std::enable_if&>() << std::declval()), PIBinaryStreamTrivialRef

>::value, int>::type = 0> +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIVector2D & 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 +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIBitArray & v) {s << v.size_ << v.data_; return s;} + + +//! \~english Store operator +//! \~russian Оператор сохранения +template +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIPair & v) {s << v.first << v.second; return s;} + + + + +// restore simple types + + +template::value, int>::type = 0> +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, T & v) { + //piCout << ">> enum"; + v = (T)s.binaryStreamTakeInt(); + return s; +} + + +template::value, int>::type = 0, +typename std::enable_if< std::is_trivially_copyable::value, int>::type = 0> +inline PIBinaryStreamTrivialRef

operator >>(PIBinaryStream

& 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::value, int>::type = 0, +typename std::enable_if< std::is_same&>() >> std::declval()), PIBinaryStreamTrivialRef

>::value, int>::type = 0> +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIVector & 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::value, int>::type = 0, +typename std::enable_if&>() >> std::declval()), PIBinaryStreamTrivialRef

>::value, int>::type = 0> +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIVector & 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::value, int>::type = 0, +typename std::enable_if< std::is_same&>() >> std::declval()), PIBinaryStreamTrivialRef

>::value, int>::type = 0> +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIDeque & 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::value, int>::type = 0, +typename std::enable_if&>() >> std::declval()), PIBinaryStreamTrivialRef

>::value, int>::type = 0> +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIDeque & 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::value, int>::type = 0, +typename std::enable_if< std::is_same&>() >> std::declval()), PIBinaryStreamTrivialRef

>::value, int>::type = 0> +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIVector2D & 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::value, int>::type = 0, +typename std::enable_if&>() >> std::declval()), PIBinaryStreamTrivialRef

>::value, int>::type = 0> +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIVector2D & v) { + //piCout << ">> vector2d trivial custom"; + int r, c; + PIVector tmp; + r = s.binaryStreamTakeInt(); + c = s.binaryStreamTakeInt(); + s >> tmp; + v = PIVector2D(r, c, tmp); + return s; +} + + +//! \~english Restore operator +//! \~russian Оператор извлечения +template +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIBitArray & v) {s >> v.size_ >> v.data_; return s;} + + +//! \~english Restore operator +//! \~russian Оператор извлечения +template +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIPair & v) {s >> v.first >> v.second; return s;} + + + + +// store complex types + + +//! \~english Store operator for PIVector of any compound type +//! \~russian Оператор сохранения для PIVector сложных типов +template::value, int>::type = 0> +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIVector & 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::value, int>::type = 0> +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIDeque & 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::value, int>::type = 0> +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIVector2D & 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::value, int>::type = 0> +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIVector & 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::value, int>::type = 0> +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIDeque & 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::value, int>::type = 0> +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIVector2D & 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 tmp; + r = s.binaryStreamTakeInt(); + c = s.binaryStreamTakeInt(); + s >> tmp; + v = PIVector2D(r, c, tmp); + return s; +} + + + + +// other types + + +//! \~english Store operator +//! \~russian Оператор сохранения +template +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIMap & 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 +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIMap & 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::value, int>::type = 0> +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const T & ) { + static_assert(std::is_trivially_copyable::value, "[PIBinaryStream] Error: using undeclared operator << for complex type!"); + return s; +} + +template::value, int>::type = 0> +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, T & ) { + static_assert(std::is_trivially_copyable::value, "[PIBinaryStream] Error: using undeclared operator >> for complex type!"); + return s; +} + + + + +#endif diff --git a/libs/main/core/pibitarray.h b/libs/main/core/pibitarray.h index c9eae0e9..65574b51 100644 --- a/libs/main/core/pibitarray.h +++ b/libs/main/core/pibitarray.h @@ -28,8 +28,10 @@ #include "pivector.h" class PIP_EXPORT PIBitArray { - friend PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v); - friend PIByteArray & operator >>(PIByteArray & s, PIBitArray & v); + template + friend PIBinaryStream

& operator >>(PIBinaryStream

& s, PIBitArray & v); + template + friend PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIBitArray & v); public: PIBitArray(const int & size = 0) {resize(size);} PIBitArray(uchar val) {resize(sizeof(val) * 8); data_[0] = val;} diff --git a/libs/main/core/pibytearray.cpp b/libs/main/core/pibytearray.cpp index bdc33f1c..c589e584 100644 --- a/libs/main/core/pibytearray.cpp +++ b/libs/main/core/pibytearray.cpp @@ -438,38 +438,3 @@ std::ostream &operator <<(std::ostream & s, const PIByteArray & ba) { return s; } #endif - - -PIByteArray & operator >>(PIByteArray & s, PIByteArray & v) { - if (s.size_s() < 4) { - s.clear(); - v.clear(); - return s; - } - assert(s.size_s() >= 4); - int sz = 0; - s >> sz; - if (sz > s.size_s()) { - piCout << "[PIByteArray] Warning: operator >> wants too much data, discard!" << sz << s.size_s(); - s.clear(); - v.clear(); - return s; - } - v.resize(sz); - if (sz > 0) { - memcpy(v.data(), s.data(), sz); - s.remove(0, sz); - } - return s; -} - - -PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v) { - s << int(v.size_s()); - int os = s.size_s(); - if (v.size_s() > 0) { - s.enlarge(v.size_s()); - memcpy(s.data(os), v.data(), v.size()); - } - return s; -} diff --git a/libs/main/core/pibytearray.h b/libs/main/core/pibytearray.h index da738b30..9a4aed33 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -27,9 +27,7 @@ #define PIBYTEARRAY_H #include "pichar.h" -#include "pibitarray.h" -#include "pimap.h" -#include "pivector2d.h" +#include "pibinarystream.h" #include class PIString; @@ -40,9 +38,10 @@ class PIByteArray; //! \~\brief //! \~english The %PIByteArray class provides an array of bytes. //! \~russian Класс %PIByteArray представляет собой массив байтов. -class PIP_EXPORT PIByteArray: public PIDeque +class PIP_EXPORT PIByteArray: public PIDeque, public PIBinaryStream { public: + typedef ::PIMemoryBlock RawData DEPRECATEDM("use PIMemoryBlock instead"); //! \~english Constructs an empty byte array //! \~russian Создает пустой байтовый массив @@ -71,25 +70,6 @@ public: PIByteArray(const uint size, uchar t): PIDeque(size, t) {} - //! \~english Help struct to store/restore custom blocks of data to/from PIByteArray - //! \~russian Вспомогательная структура для сохранения/извлечения произвольного блока данных в/из байтового массива - struct RawData { - friend PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v); - friend PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v); - public: - //! \~english Constructs data block - //! \~russian Создает блок данных - RawData(void * data = 0, int size = 0) {d = data; s = size;} - RawData(const RawData & o) {d = o.d; s = o.s;} - //! \~english Constructs data block - //! \~russian Создает блок данных - RawData(const void * data, const int size) {d = const_cast(data); s = size;} - RawData & operator =(const RawData & o) {d = o.d; s = o.s; return *this;} - private: - void * d; - int s; - }; - //! \~english Return resized byte array //! \~russian Возвращает копию байтового массива с измененным размером PIByteArray resized(uint new_size) const {PIByteArray ret(new_size); memcpy(ret.data(), data(), new_size); return ret;} @@ -170,13 +150,17 @@ public: static PIByteArray fromBase64(const PIString & base64); - class StreamRef { - public: - StreamRef(PIByteArray & s): ba(s) {} - operator PIByteArray&() {return ba;} - private: - PIByteArray & ba; - }; + bool binaryStreamAppendImp(const void * d, size_t s) { + append(d, s); + return true; + } + bool binaryStreamTakeImp(void * d, size_t s) { + if (size() < s) + return false; + memcpy(d, data(), s); + remove(0, s); + return true; + } }; @@ -235,443 +219,14 @@ inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba); PIP_EXPORT PICout operator <<(PICout s, const PIByteArray & ba); - - -// store operators for basic types - - -//! \relatesalso PIByteArray -//! \~english Store operator -//! \~russian Оператор сохранения -inline PIByteArray & operator <<(PIByteArray & s, const bool v) {s.push_back(v); return s;} - -//! \relatesalso PIByteArray -//! \~english Store operator -//! \~russian Оператор сохранения -inline PIByteArray & operator <<(PIByteArray & s, const char v) {s.push_back(v); return s;} - -//! \relatesalso PIByteArray -//! \~english Store operator -//! \~russian Оператор сохранения -inline PIByteArray & operator <<(PIByteArray & s, const uchar v) {s.push_back(v); return s;} - -//! \relatesalso PIByteArray -//! \~english Store operator for any trivial copyable type -//! \~russian Оператор сохранения для тривиальных типов -template::value, int>::type = 0> -inline PIByteArray::StreamRef operator <<(PIByteArray & s, const T & v) { - int os = s.size_s(); - s.enlarge(sizeof(v)); - memcpy(s.data(os), &v, sizeof(v)); +BINARY_STREAM_WRITE(PIByteArray) { + s.binaryStreamAppend((int)v.size_s()); + s.binaryStreamAppend(v.data(), v.size()); return s; } - -//! \relatesalso PIByteArray -//! \~english Store operator, see \ref PIByteArray_sec1 for details -//! \~russian Оператор сохранения, подробнее в \ref PIByteArray_sec1 -PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v); - -//! \relatesalso PIByteArray -//! \~english Store operator -//! \~russian Оператор сохранения -inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v) { - int os = s.size_s(); - if (v.s > 0) { - s.enlarge(v.s); - memcpy(s.data(os), v.d, v.s); - } - return s; -} - -//! \relatesalso PIByteArray -//! \~english Store operator for PIVector of any trivial copyable type -//! \~russian Оператор сохранения для PIVector тривиальных типов -template::value, int>::type = 0, - typename std::enable_if< std::is_same() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { - s << int(v.size_s()); - int os = s.size_s(); - if (v.size_s() > 0) { - s.enlarge(v.size_s()*sizeof(T)); - memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); - } - return s; -} -template::value, int>::type = 0, - typename std::enable_if() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { - s << int(v.size_s()); - for (uint i = 0; i < v.size(); ++i) s << v[i]; - return s; -} - -//! \relatesalso PIByteArray -//! \~english Store operator for PIDeque of any trivial copyable type -//! \~russian Оператор сохранения для PIDeque тривиальных типов -template::value, int>::type = 0, - typename std::enable_if< std::is_same() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { - s << int(v.size_s()); - int os = s.size_s(); - if (v.size_s() > 0) { - s.enlarge(v.size_s()*sizeof(T)); - memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); - } - return s; -} -template::value, int>::type = 0, - typename std::enable_if() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { - s << int(v.size_s()); - for (uint i = 0; i < v.size(); ++i) s << v[i]; - return s; -} - -//! \relatesalso PIByteArray -//! \~english Store operator for PIVector2D of any trivial copyable type -//! \~russian Оператор сохранения для PIVector2D тривиальных типов -template::value, int>::type = 0, - typename std::enable_if< std::is_same() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { - s << int(v.rows()) << int(v.cols()); - int os = s.size_s(); - if (v.size_s() > 0) { - s.enlarge(v.size_s()*sizeof(T)); - memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); - } - return s; -} -template::value, int>::type = 0, - typename std::enable_if() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { - s << int(v.rows()) << int(v.cols()) << v.toPlainVector(); - return s; -} - -//! \relatesalso PIByteArray -//! \~english Store operator -//! \~russian Оператор сохранения -inline PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;} - -//! \relatesalso PIPair -//! \~english Store operator -//! \~russian Оператор сохранения -template -inline PIByteArray & operator <<(PIByteArray & s, const PIPair & v) {s << v.first << v.second; return s;} - - - - -// restore operators for basic types - - -//! \relatesalso PIByteArray -//! \~english Restore operator -//! \~russian Оператор извлечения -inline PIByteArray & operator >>(PIByteArray & s, bool & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} - -//! \relatesalso PIByteArray -//! \~english Restore operator -//! \~russian Оператор извлечения -inline PIByteArray & operator >>(PIByteArray & s, char & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} - -//! \relatesalso PIByteArray -//! \~english Restore operator -//! \~russian Оператор извлечения -inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} - -//! \relatesalso PIByteArray -//! \~english Restore operator for any trivial copyable type -//! \~russian Оператор извлечения для тривиальных типов -template::value, int>::type = 0> -inline PIByteArray::StreamRef operator >>(PIByteArray & s, T & v) { - if (s.size() < sizeof(v)) { - printf("error with %s\n", __PIP_TYPENAME__(T)); - assert(s.size() >= sizeof(v)); - } - memcpy((void*)(&v), s.data(), sizeof(v)); - s.remove(0, sizeof(v)); - return s; -} - -//! \relatesalso PIByteArray -//! \~english Restore operator, see \ref PIByteArray_sec1 for details -//! \~russian Оператор извлечения, подробнее в \ref PIByteArray_sec1 -PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIByteArray & v); - -//! \relatesalso PIByteArray -//! \~english Restore operator -//! \~russian Оператор извлечения -inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) { - if (s.size_s() < v.s) { - printf("error with RawData %d < %d\n", (int)s.size_s(), v.s); - assert(s.size_s() >= v.s); - } - if (v.s > 0) { - memcpy((void*)(v.d), s.data(), v.s); - s.remove(0, v.s); - } - return s; -} - -//! \relatesalso PIByteArray -//! \~english Restore operator for PIVector of any trivial copyable type -//! \~russian Оператор извлечения для PIVector тривиальных типов -template::value, int>::type = 0, - typename std::enable_if< std::is_same() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { - if (s.size_s() < 4) { - printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T)); - assert(s.size_s() >= 4); - } - int sz; s >> sz; - v._resizeRaw(sz); - if (sz > 0) { - memcpy(v.data(), s.data(), sz*sizeof(T)); - s.remove(0, sz*sizeof(T)); - } - return s; -} -template::value, int>::type = 0, - typename std::enable_if() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { - if (s.size_s() < 4) { - printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T)); - assert(s.size_s() >= 4); - } - int sz; s >> sz; - v.resize(sz); - for (int i = 0; i < sz; ++i) s >> v[i]; - return s; -} - -//! \relatesalso PIByteArray -//! \~english Restore operator for PIDeque of any trivial copyable type -//! \~russian Оператор извлечения для PIDeque тривиальных типов -template::value, int>::type = 0, - typename std::enable_if< std::is_same() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { - if (s.size_s() < 4) { - printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T)); - assert(s.size_s() >= 4); - } - int sz; s >> sz; - v._resizeRaw(sz); - if (sz > 0) { - memcpy(v.data(), s.data(), sz*sizeof(T)); - s.remove(0, sz*sizeof(T)); - } - return s; -} -template::value, int>::type = 0, - typename std::enable_if() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { - if (s.size_s() < 4) { - printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T)); - assert(s.size_s() >= 4); - } - int sz; s >> sz; - v.resize(sz); - for (int i = 0; i < sz; ++i) s >> v[i]; - return s; -} - -//! \relatesalso PIByteArray -//! \~english Restore operator for PIVector2D of any trivial copyable type -//! \~russian Оператор извлечения для PIVector2D тривиальных типов -template::value, int>::type = 0, - typename std::enable_if< std::is_same() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { - if (s.size_s() < 8) { - printf("error with PIVecto2Dr<%s>\n", __PIP_TYPENAME__(T)); - assert(s.size_s() >= 8); - } - int r, c; s >> r >> c; - v._resizeRaw(r, c); - int sz = r*c; - if (sz > 0) { - memcpy(v.data(), s.data(), sz*sizeof(T)); - s.remove(0, sz*sizeof(T)); - } - return s; -} -template::value, int>::type = 0, - typename std::enable_if() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { - if (s.size_s() < 8) { - printf("error with PIVecto2Dr<%s>\n", __PIP_TYPENAME__(T)); - assert(s.size_s() >= 8); - } - int r,c; - PIVector tmp; - s >> r >> c >> tmp; - v = PIVector2D(r, c, tmp); - return s; -} - -//! \relatesalso PIByteArray -//! \~english Restore operator -//! \~russian Оператор извлечения -inline PIByteArray & operator >>(PIByteArray & s, PIBitArray & v) {assert(s.size_s() >= 8); s >> v.size_ >> v.data_; return s;} - -//! \relatesalso PIPair -//! \~english Restore operator -//! \~russian Оператор извлечения -template -inline PIByteArray & operator >>(PIByteArray & s, PIPair & v) {s >> v.first >> v.second; return s;} - - - - -// store operators for complex types - - -//! \relatesalso PIByteArray -//! \~english Store operator for PIVector of any compound type -//! \~russian Оператор сохранения для PIVector сложных типов -template::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { - s << int(v.size_s()); - for (uint i = 0; i < v.size(); ++i) s << v[i]; - return s; -} - -//! \relatesalso PIByteArray -//! \~english Store operator for PIDeque of any compound type -//! \~russian Оператор сохранения для PIDeque сложных типов -template::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { - s << int(v.size_s()); - for (uint i = 0; i < v.size(); ++i) s << v[i]; - return s; -} - -//! \relatesalso PIByteArray -//! \~english Store operator for PIVector2D of any compound type -//! \~russian Оператор сохранения для PIVector2D сложных типов -template::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { - s << int(v.rows()) << int(v.cols()) << v.toPlainVector(); - return s; -} - - - - -// restore operators for complex types - - -//! \relatesalso PIByteArray -//! \~english Restore operator for PIVector of any compound type -//! \~russian Оператор извлечения для PIVector сложных типов -template::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { - if (s.size_s() < 4) { - printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T)); - assert(s.size_s() >= 4); - } - int sz; s >> sz; - v.resize(sz); - for (int i = 0; i < sz; ++i) s >> v[i]; - return s; -} - -//! \relatesalso PIByteArray -//! \~english Restore operator for PIDeque of any compound type -//! \~russian Оператор извлечения для PIDeque сложных типов -template::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { - if (s.size_s() < 4) { - printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T)); - assert(s.size_s() >= 4); - } - int sz; s >> sz; - v.resize(sz); - for (int i = 0; i < sz; ++i) s >> v[i]; - return s; -} - -//! \relatesalso PIByteArray -//! \~english Restore operator for PIVector2D of any compound type -//! \~russian Оператор извлечения для PIVector2D сложных типов -template::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { - if (s.size_s() < 8) { - printf("error with PIVecto2Dr<%s>\n", __PIP_TYPENAME__(T)); - assert(s.size_s() >= 8); - } - int r,c; - PIVector tmp; - s >> r >> c >> tmp; - v = PIVector2D(r, c, tmp); - return s; -} - - - - -// other types - - -//! \relatesalso PIByteArray -//! \~english Store operator -//! \~russian Оператор сохранения -template -inline PIByteArray & operator <<(PIByteArray & s, const PIMap & v) { - s << int(v.pim_index.size_s()); - for (uint i = 0; i < v.size(); ++i) - s << int(v.pim_index[i].index) << v.pim_index[i].key; - s << v.pim_content; - return s; -} - - -//! \relatesalso PIByteArray -//! \~english Restore operator -//! \~russian Оператор извлечения -template -inline PIByteArray & operator >>(PIByteArray & s, PIMap & 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 >> sz; v.pim_index.resize(sz); - int ind = 0; - for (int i = 0; i < sz; ++i) { - s >> ind >> 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; -} - - - -template::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const T & ) { - static_assert(std::is_trivially_copyable::value, "[PIByteArray] Error: using undeclared operator << for complex type!"); - return s; -} - -template::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, T & ) { - static_assert(std::is_trivially_copyable::value, "[PIByteArray] Error: using undeclared operator >> for complex type!"); +BINARY_STREAM_READ(PIByteArray) { + v.resize(s.binaryStreamTakeInt()); + s.binaryStreamTake(v.data(), v.size()); return s; } diff --git a/libs/main/core/pichunkstream.cpp b/libs/main/core/pichunkstream.cpp index 6255c955..fa0b1b7f 100644 --- a/libs/main/core/pichunkstream.cpp +++ b/libs/main/core/pichunkstream.cpp @@ -117,7 +117,7 @@ int PIChunkStream::read() { last_id = readVInt(*data_); last_data.resize(readVInt(*data_)); //piCout << last_id << last_data.size(); - (*data_) >> PIByteArray::RawData(last_data.data(), last_data.size_s()); + (*data_) >> PIMemoryBlock(last_data.data(), last_data.size_s()); break; default: break; } diff --git a/libs/main/core/pichunkstream.h b/libs/main/core/pichunkstream.h index a0456541..c7039c04 100644 --- a/libs/main/core/pichunkstream.h +++ b/libs/main/core/pichunkstream.h @@ -124,7 +124,7 @@ public: //! \~english Returns value of last readed chunk //! \~russian Возвращает значение последнего прочитанного чанка template - T getData() const {T ret; PIByteArray s(last_data); s >> ret; return ret;} + T getData() const {T ret{}; PIByteArray s(last_data); s >> ret; return ret;} //! \~english Place value of last readed chunk into \"v\" //! \~russian Записывает значение последнего прочитанного чанка в \"v\" diff --git a/libs/main/core/piconstchars.cpp b/libs/main/core/piconstchars.cpp index 90d057eb..bc978a2a 100644 --- a/libs/main/core/piconstchars.cpp +++ b/libs/main/core/piconstchars.cpp @@ -42,6 +42,13 @@ //! +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()); diff --git a/libs/main/core/piconstchars.h b/libs/main/core/piconstchars.h index 3f6ec6d1..1a00bfd6 100644 --- a/libs/main/core/piconstchars.h +++ b/libs/main/core/piconstchars.h @@ -86,6 +86,10 @@ public: //! \~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;} diff --git a/libs/main/core/picout.cpp b/libs/main/core/picout.cpp index 6ed35e67..551bd064 100644 --- a/libs/main/core/picout.cpp +++ b/libs/main/core/picout.cpp @@ -320,10 +320,10 @@ PICout PICout::operator <<(const PIFlags & v) #define PICOUTTOTARGET(v) { \ if (buffer_) {\ - (*buffer_) << (v);\ + (*buffer_) += (v);\ } else {\ if (PICout::isOutputDeviceActive(PICout::StdOut)) std::cout << (v);\ - if (PICout::isOutputDeviceActive(PICout::Buffer)) PICout::__string__() << (v);\ + if (PICout::isOutputDeviceActive(PICout::Buffer)) PICout::__string__() += (v);\ }\ } @@ -386,52 +386,52 @@ PICout PICout::operator <<(const PICoutSpecialChar v) { switch (v) { case Null: if (buffer_) { - (*buffer_) << PIChar(); + (*buffer_) += PIChar(); } else { if (isOutputDeviceActive(StdOut)) std::cout << char(0); - if (isOutputDeviceActive(Buffer)) PICout::__string__() << PIChar(); + if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIChar(); } break; case NewLine: if (buffer_) { - (*buffer_) << "\n"; + (*buffer_) += "\n"; } else { if (isOutputDeviceActive(StdOut)) std::cout << '\n'; - if (isOutputDeviceActive(Buffer)) PICout::__string__() << "\n"; + if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\n"; } fo_ = true; break; case Tab: if (buffer_) { - (*buffer_) << "\t"; + (*buffer_) += "\t"; } else { if (isOutputDeviceActive(StdOut)) std::cout << '\t'; - if (isOutputDeviceActive(Buffer)) PICout::__string__() << "\t"; + if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\t"; } break; case Esc: #ifdef CC_VC if (buffer_) { - (*buffer_) << PIChar(27); + (*buffer_) += PIChar(27); } else { if (isOutputDeviceActive(StdOut)) std::cout << char(27); - if (isOutputDeviceActive(Buffer)) PICout::__string__() << PIChar(27); + if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIChar(27); } #else if (buffer_) { - (*buffer_) << "\e"; + (*buffer_) += "\e"; } else { if (isOutputDeviceActive(StdOut)) std::cout << '\e'; - if (isOutputDeviceActive(Buffer)) PICout::__string__() << "\e"; + if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\e"; } #endif break; case Quote: if (buffer_) { - (*buffer_) << "\""; + (*buffer_) += "\""; } else { if (isOutputDeviceActive(StdOut)) std::cout << '"'; - if (isOutputDeviceActive(Buffer)) PICout::__string__() << "\""; + if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\""; } break; }; @@ -469,10 +469,10 @@ PICout & PICout::space() { if (!act_) return *this; if (!fo_ && co_[AddSpaces]) { if (buffer_) { - (*buffer_) << " "; + (*buffer_) += " "; } else { if (isOutputDeviceActive(StdOut)) std::cout << ' '; - if (isOutputDeviceActive(Buffer)) PICout::__string__() << " "; + if (isOutputDeviceActive(Buffer)) PICout::__string__() += " "; } } fo_ = false; @@ -489,10 +489,10 @@ PICout & PICout::quote() { if (!act_) return *this; if (co_[AddQuotes]) { if (buffer_) { - (*buffer_) << "\""; + (*buffer_) += "\""; } else { if (isOutputDeviceActive(StdOut)) std::cout << '"'; - if (isOutputDeviceActive(Buffer)) PICout::__string__() << "\""; + if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\""; } } fo_ = false; @@ -509,10 +509,10 @@ PICout & PICout::newLine() { if (!act_) return *this; if (co_[AddNewLine]) { if (buffer_) { - (*buffer_) << "\n"; + (*buffer_) += "\n"; } else { if (isOutputDeviceActive(StdOut)) std::cout << std::endl; - if (isOutputDeviceActive(Buffer)) PICout::__string__() << "\n"; + if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\n"; } } fo_ = false; diff --git a/libs/main/core/pidatetime.h b/libs/main/core/pidatetime.h index 9b009613..c5da3208 100644 --- a/libs/main/core/pidatetime.h +++ b/libs/main/core/pidatetime.h @@ -311,16 +311,6 @@ inline bool operator <=(const PIDateTime & t0, const PIDateTime & t1) {return !( //! \~russian Оператор сравнения inline bool operator >=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 < t1);} -//! \relatesalso PIByteArray -//! \~english Store operator -//! \~russian Оператор сохранения -inline PIByteArray & operator <<(PIByteArray & s, const PIDateTime & v) {s << v.year << v.month << v.day << v.hours << v.minutes << v.seconds << v.milliseconds; return s;} - -//! \relatesalso PIByteArray -//! \~english Restore operator -//! \~russian Оператор извлечения -inline PIByteArray & operator >>(PIByteArray & s, PIDateTime & v) {s >> v.year >> v.month >> v.day >> v.hours >> v.minutes >> v.seconds >> v.milliseconds; return s;} - //! \relatesalso PICout //! \~english \brief Output operator to PICout //! \~russian \brief Оператор вывода в PICout diff --git a/libs/main/core/piincludes.h b/libs/main/core/piincludes.h index 71902e27..e867a756 100644 --- a/libs/main/core/piincludes.h +++ b/libs/main/core/piincludes.h @@ -38,6 +38,7 @@ class PIMutexLocker; class PIObject; class PIString; class PIByteArray; +template class PIBinaryStream; #ifndef MICRO_PIP class PIInit; #endif diff --git a/libs/main/core/pimemoryblock.h b/libs/main/core/pimemoryblock.h new file mode 100644 index 00000000..133d6ae0 --- /dev/null +++ b/libs/main/core/pimemoryblock.h @@ -0,0 +1,63 @@ +/*! \file pimemoryblock.h + * \ingroup Core + * \~\brief + * \~english Base types and functions + * \~russian Базовые типы и методы +*/ +/* + PIP - Platform Independent Primitives + Base types and functions + 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 . +*/ + +#ifndef PIMEMORYBLOCK_H +#define PIMEMORYBLOCK_H + + +//! \ingroup Core +//! \include pimemoryblock.h +//! \brief +//! \~english Help struct to store/restore custom blocks of data to/from PIBinaryStream +//! \~russian Вспомогательная структура для сохранения/извлечения произвольного блока данных в/из PIBinaryStream +struct PIMemoryBlock { +public: + + //! \~english Constructs data block + //! \~russian Создает блок данных + PIMemoryBlock(void * data_ = 0, int size_ = 0) {d = data_; s = size_;} + + //! \~english Constructs data block + //! \~russian Создает блок данных + PIMemoryBlock(const void * data_, const int size_) {d = const_cast(data_); s = size_;} + + PIMemoryBlock(const PIMemoryBlock & o) {d = o.d; s = o.s;} + + PIMemoryBlock & operator =(const PIMemoryBlock & o) {d = o.d; s = o.s; return *this;} + + void * data() {return d;} + const void * data() const {return d;} + int size() const {return s;} + +private: + void * d; + int s; + +}; + +template +PIMemoryBlock createMemoryBlock(const T * ptr) {return PIMemoryBlock(ptr, sizeof(T));} + +#endif // PIMEMORYBLOCK_H diff --git a/libs/main/core/piobject.cpp b/libs/main/core/piobject.cpp index c764e5d8..f857dbf3 100644 --- a/libs/main/core/piobject.cpp +++ b/libs/main/core/piobject.cpp @@ -23,6 +23,7 @@ #ifndef MICRO_PIP # include "pisysteminfo.h" # include "pifile.h" +# include "piiostream.h" #endif @@ -753,7 +754,8 @@ bool dumpApplicationToFile(const PIString & path, bool with_objects) { bool ba = PICout::isBufferActive(); PICout::setBufferActive(true, true); dumpApplication(with_objects); - f << PICout::buffer(); + PIIOTextStream ts(&f); + ts << PICout::buffer(); f.close(); PICout::setBufferActive(ba, true); PIFile::rename(path + "_tmp", path); diff --git a/libs/main/core/pipropertystorage.h b/libs/main/core/pipropertystorage.h index d695e197..fefb3fa3 100644 --- a/libs/main/core/pipropertystorage.h +++ b/libs/main/core/pipropertystorage.h @@ -271,10 +271,11 @@ protected: }; -inline PIByteArray & operator <<(PIByteArray & s, const PIPropertyStorage::Property & v) {s << v.name << v.value << v.comment << v.flags; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIPropertyStorage::Property & v) {s >> v.name >> v.value >> v.comment >> v.flags; return s;} +BINARY_STREAM_WRITE(PIPropertyStorage::Property) {s << v.name << v.value << v.comment << v.flags; return s;} +BINARY_STREAM_READ (PIPropertyStorage::Property) {s >> v.name >> v.value >> v.comment >> v.flags; return s;} + +BINARY_STREAM_WRITE(PIPropertyStorage) {s << v.properties(); return s;} +BINARY_STREAM_READ (PIPropertyStorage) {s >> v.properties(); return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIPropertyStorage & v) {s << v.properties(); return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIPropertyStorage & v) {s >> v.properties(); return s;} #endif // PIPROPERTYSTORAGE_H diff --git a/libs/main/core/pistring.cpp b/libs/main/core/pistring.cpp index 66488590..34fd1a26 100644 --- a/libs/main/core/pistring.cpp +++ b/libs/main/core/pistring.cpp @@ -215,6 +215,13 @@ void PIString::appendFromChars(const char * c, int s, const char * codepage) { } +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; @@ -224,6 +231,13 @@ PIString PIString::fromConsole(const char * s) { } +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; @@ -361,6 +375,13 @@ uint PIString::hash() const { } +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__); diff --git a/libs/main/core/pistring.h b/libs/main/core/pistring.h index c4f2940a..513794cc 100644 --- a/libs/main/core/pistring.h +++ b/libs/main/core/pistring.h @@ -40,8 +40,7 @@ class PIStringList; //! \~russian Класс строки. class PIP_EXPORT PIString { - friend PIByteArray & operator >>(PIByteArray & s, PIString & v); - friend PIByteArray & operator <<(PIByteArray & s, const PIString & v); + BINARY_STREAM_FRIEND(PIString); public: typedef PIDeque::iterator iterator; typedef PIDeque::const_iterator const_iterator; @@ -242,94 +241,6 @@ public: //! \~russian Оператор сравнения. bool operator >=(const char * str) const {return *this >= PIString(str);} - //! \~english Append string "str" at the end of string. - //! \~russian Добавляет в конец строку "str". - //! \~\details - //! \~\code - //! PIString s("this"), s1(" is"), s2(" string"); - //! s << s1 << s2; // s = "this is string" - //! \endcode - PIString & operator <<(const PIString & str) {*this += str; return *this;} - - //! \~english Append character "c" at the end of string. - //! \~russian Добавляет в конец символ "c". - //! \~\details - //! \~\code - //! PIString s("stri"); - //! s << PIChar('n') << PIChar('g'); // s = "string" - //! \endcode - PIString & operator <<(const PIChar c) {d.append(c); return *this;} - - //! \~english Append character `c` at the end of string. - //! \~russian Добавляет в конец символ `c`. - //! \~\details - //! \~\code - //! PIString s("stri"); - //! s << 'n' << 'g'; // s = "string" - //! \endcode - PIString & operator <<(const char c) {d.append(PIChar(c)); return *this;} - - //! \~english Append С-string "str" at the end of string. - //! \~russian Добавляет в конец C-строку "str". - //! \~\details - //! \~\code - //! PIString s("this"); - //! s << " is" << " string"; // s = "this is string" - //! \endcode - PIString & operator <<(const char * str) {*this += str; return *this;} - - //! \~english Append \c wchar_t C-string "str" at the end of string. - //! \~russian Добавляет в конец \c wchar_t C-строку "str". - //! \~\details - //! \~\code - //! PIString s; - //! s << L"№ -" << " number"; // s = "№ - number" - //! \endcode - PIString & operator <<(const wchar_t * str) {*this += str; return *this;} - - PIString & operator <<(const PIConstChars & str) {*this += str; return *this;} - - //! \~english Append string representation of "num" at the end of string. - //! \~russian Добавляет в конец строковое представление "num". - //! \~\details - //! \~\code - //! PIString s("ten - "); - //! s << 10; // s = "ten - 10" - //! \endcode - PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;} - PIString & operator <<(const uint & num) {*this += PIString::fromNumber(num); return *this;} - - //! \~english Append string representation of "num" at the end of string. - //! \~russian Добавляет в конец строковое представление "num". - //! \~\details - //! \~\code - //! PIString s("ten - "); - //! s << 10; // s = "ten - 10" - //! \endcode - PIString & operator <<(const long & num) {*this += PIString::fromNumber(num); return *this;} - PIString & operator <<(const ulong & num) {*this += PIString::fromNumber(num); return *this;} - - PIString & operator <<(const llong & num) {*this += PIString::fromNumber(num); return *this;} - PIString & operator <<(const ullong & num) {*this += PIString::fromNumber(num); return *this;} - - //! \~english Append string representation of "num" at the end of string. - //! \~russian Добавляет в конец строковое представление "num". - //! \~\details - //! \~\code - //! PIString s("1/10 - "); - //! s << 0.1; // s = "1/10 - 0.1" - //! \endcode - PIString & operator <<(const float & num) {*this += PIString::fromNumber(num); return *this;} - - //! \~english Append string representation of "num" at the end of string. - //! \~russian Добавляет в конец строковое представление "num". - //! \~\details - //! \~\code - //! PIString s("1/10 - "); - //! s << 0.1; // s = "1/10 - 0.1" - //! \endcode - PIString & operator <<(const double & num) {*this += PIString::fromNumber(num); return *this;} - //! \~english Iterator to the first element. //! \~russian Итератор на первый элемент. //! \~\details @@ -909,6 +820,10 @@ public: //! \~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; @@ -1507,10 +1422,18 @@ public: //! \~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 Возвращает строку созданную из кодировки системы. @@ -1583,12 +1506,12 @@ PIP_EXPORT PICout operator <<(PICout s, const PIString & v); //! \relatesalso PIByteArray //! \~english Store operator. //! \~russian Оператор сохранения. -inline PIByteArray & operator <<(PIByteArray & s, const PIString & v) {s << v.d; return s;} +BINARY_STREAM_WRITE(PIString) {s << v.d; return s;} //! \relatesalso PIByteArray //! \~english Restore operator. //! \~russian Оператор извлечения. -inline PIByteArray & operator >>(PIByteArray & s, PIString & v) {v.d.clear(); s >> v.d; return s;} +BINARY_STREAM_READ(PIString) {v.d.clear(); s >> v.d; return s;} //! \~english Returns concatenated string. diff --git a/libs/main/core/pistringlist.h b/libs/main/core/pistringlist.h index 0e6fc2a3..66d4a047 100644 --- a/libs/main/core/pistringlist.h +++ b/libs/main/core/pistringlist.h @@ -126,15 +126,19 @@ public: }; -//! \relatesalso PIByteArray -//! \~english Store operator -//! \~russian Оператор сохранения -inline PIByteArray & operator <<(PIByteArray & s, const PIStringList & v) {s << int(v.size_s()); for (int i = 0; i < v.size_s(); ++i) s << v[i]; return s;} +BINARY_STREAM_WRITE(PIStringList) { + s.binaryStreamAppend(v.size()); + for (int i = 0; i < v.size_s(); ++i) + s << v[i]; + return s; +} +BINARY_STREAM_READ(PIStringList) { + v.resize(s.binaryStreamTakeInt()); + for (int i = 0; i < v.size_s(); ++i) + s >> v[i]; + return s; +} -//! \relatesalso PIByteArray -//! \~english Restore operator -//! \~russian Оператор извлечения -inline PIByteArray & operator >>(PIByteArray & s, PIStringList & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;} //! \relatesalso PICout //! \~english Output operator to \a PICout diff --git a/libs/main/core/pitextstream.h b/libs/main/core/pitextstream.h new file mode 100644 index 00000000..4a8ab8cc --- /dev/null +++ b/libs/main/core/pitextstream.h @@ -0,0 +1,341 @@ +/*! \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 . +*/ + +#ifndef PITEXTSTREAM_H +#define PITEXTSTREAM_H + +#include "pistring.h" + + +//! \ingroup Core +//! \~\brief +//! \~english Text serialization functionality over PIBinaryStream. +//! \~russian Функциональность текстовой сериализации поверх PIBinaryStream. +template +class PITextStream { +public: + + //! \~english Floating-point numbers write format + //! \~russian Формат записи чисел с плавающей точкой + enum FloatFormat { + DecimalFormat /** \~english Decimal format, "*.*" \~russian Десятичный формат, "*.*" */ = 'f', + ExponentFormat /** \~english Exponential format, "*e+-" \~russian Экспонентный формат, "*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

* stream_) {setStream(stream_);} + + //! \~english Returns binded PIBinaryStream + //! \~russian Возвращает привязанный PIBinaryStream + PIBinaryStream

* stream() const {return s;} + void setStream(PIBinaryStream

* 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

& space() {s->binaryStreamAppend(' '); return *this;} + + //! \~english Append new line + //! \~russian Добавляет новую строку + PITextStream

& 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 takeChar(bool * rok) { + bool ok = true; + char ret = (char)s->binaryStreamTakeByte(&ok); + if (!ok) is_end = true; + if (rok) *rok = ok; + return ret; + } + + //! \~english Read line + //! \~russian Читает строку + PIString takeLine() { + PIByteArray ret; + bool ok = true; + for (;;) { + char b = takeChar(&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 takeWord() { + static PIConstChars spaces(" \t\n\r"); + return takeUntil(spaces); + } + + //! \~english + //! \~russian + PIString takeCWord() { + static PIConstChars chars(" \t\n\r:;%$&#@!?~/*-+=.,\\\"'`[](){}<>"); + return takeUntil(chars); + } + +private: + PIString fromBytes(const PIByteArray & ba) { + switch (enc) { + case System: return PIString::fromSystem(ba); + case UTF8 : return PIString::fromUTF8(ba); + } + return PIString(); + } + PIString takeUntil(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 = takeChar(&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 = takeChar(&ok); + if (!ok || !chars.contains(c)) break; + } + if (rok) *rok = ok; + return c; + } + + PIBinaryStream

* 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 +inline PITextStream

createPITextStream(PIBinaryStream

* stream) {return PITextStream

(stream);} + + +//! \~english Append boolean +//! \~russian Добавляет логическое +template inline PITextStream

& operator <<(PITextStream

& s, bool v) {s.append(v); return s;} + +//! \~english Append character +//! \~russian Добавляет символ +template inline PITextStream

& operator <<(PITextStream

& s, char v) {s.append(v); return s;} + +//! \~english Append integer +//! \~russian Добавляет целое +template inline PITextStream

& operator <<(PITextStream

& s, uchar v) {s.append((int)v); return s;} + +//! \~english Append integer +//! \~russian Добавляет целое +template inline PITextStream

& operator <<(PITextStream

& s, short v) {s.append((int)v); return s;} + +//! \~english Append integer +//! \~russian Добавляет целое +template inline PITextStream

& operator <<(PITextStream

& s, ushort v) {s.append((int)v); return s;} + +//! \~english Append integer +//! \~russian Добавляет целое +template inline PITextStream

& operator <<(PITextStream

& s, int v) {s.append((int)v); return s;} + +//! \~english Append integer +//! \~russian Добавляет целое +template inline PITextStream

& operator <<(PITextStream

& s, uint v) {s.append((int)v); return s;} + +//! \~english Append integer +//! \~russian Добавляет целое +template inline PITextStream

& operator <<(PITextStream

& s, llong v) {s.append((llong)v); return s;} + +//! \~english Append integer +//! \~russian Добавляет целое +template inline PITextStream

& operator <<(PITextStream

& s, ullong v) {s.append((llong)v); return s;} + +//! \~english Append floating-point number +//! \~russian Добавляет число с плавающей точкой +template inline PITextStream

& operator <<(PITextStream

& s, float v) {s.append(v); return s;} + +//! \~english Append floating-point number +//! \~russian Добавляет число с плавающей точкой +template inline PITextStream

& operator <<(PITextStream

& s, double v) {s.append(v); return s;} + + +//! \~english Append string +//! \~russian Добавляет строку +template inline PITextStream

& operator <<(PITextStream

& s, const char * v) {s.append(v); return s;} + +//! \~english Append string +//! \~russian Добавляет строку +template inline PITextStream

& operator <<(PITextStream

& s, const PIConstChars & v) {s.append(v); return s;} + +//! \~english Append string +//! \~russian Добавляет строку +template inline PITextStream

& operator <<(PITextStream

& s, const PIString & v) {s.append(v); return s;} + + +//! \~english Read word as bool +//! \~russian Читает слово как логическое +template inline PITextStream

& operator >>(PITextStream

& s, bool & v) {v = s.takeWord().toBool(); return s;} + +//! \~english Read character +//! \~russian Читает символ +template inline PITextStream

& operator >>(PITextStream

& s, char & v) {v = s.takeChar(); return s;} + +//! \~english Read word as integer +//! \~russian Читает слово как целое +template inline PITextStream

& operator >>(PITextStream

& s, uchar & v) {v = s.takeWord().toUInt(); return s;} + +//! \~english Read word as integer +//! \~russian Читает слово как целое +template inline PITextStream

& operator >>(PITextStream

& s, short & v) {v = s.takeWord().toInt(); return s;} + +//! \~english Read word as integer +//! \~russian Читает слово как целое +template inline PITextStream

& operator >>(PITextStream

& s, ushort & v) {v = s.takeWord().toUInt(); return s;} + +//! \~english Read word as integer +//! \~russian Читает слово как целое +template inline PITextStream

& operator >>(PITextStream

& s, int & v) {v = s.takeWord().toInt(); return s;} + +//! \~english Read word as integer +//! \~russian Читает слово как целое +template inline PITextStream

& operator >>(PITextStream

& s, uint & v) {v = s.takeWord().toUInt(); return s;} + +//! \~english Read word as integer +//! \~russian Читает слово как целое +template inline PITextStream

& operator >>(PITextStream

& s, llong & v) {v = s.takeWord().toLLong(); return s;} + +//! \~english Read word as integer +//! \~russian Читает слово как целое +template inline PITextStream

& operator >>(PITextStream

& s, ullong & v) {v = s.takeWord().toULLong(); return s;} + +//! \~english Read word as floating-point number +//! \~russian Читает слово как число с плавающей точкой +template inline PITextStream

& operator >>(PITextStream

& s, float & v) {v = s.takeWord().toFloat(); return s;} + +//! \~english Read word as floating-point number +//! \~russian Читает слово как число с плавающей точкой +template inline PITextStream

& operator >>(PITextStream

& s, double & v) {v = s.takeWord().toDouble(); return s;} + + +//! \~english Read word +//! \~russian Читает слово +template inline PITextStream

& operator >>(PITextStream

& s, PIString & v) {v = s.takeWord(); return s;} + +#endif diff --git a/libs/main/core/pivariant.h b/libs/main/core/pivariant.h index 94afc609..5a33a0c1 100644 --- a/libs/main/core/pivariant.h +++ b/libs/main/core/pivariant.h @@ -206,8 +206,7 @@ classname_to __PIVariantFunctions__::castVariant(c //! \~english Variant type. class PIP_EXPORT PIVariant { friend PICout operator <<(PICout s, const PIVariant & v); - friend PIByteArray & operator <<(PIByteArray & s, const PIVariant & v); - friend PIByteArray & operator >>(PIByteArray & s, PIVariant & v); + BINARY_STREAM_FRIEND(PIVariant); public: //! Type of %PIVariant content @@ -773,8 +772,9 @@ REGISTER_VARIANT(PILined) REGISTER_VARIANT(PIMathVectord) REGISTER_VARIANT(PIMathMatrixd) -inline PIByteArray & operator <<(PIByteArray & s, const PIVariant & v) { - s << v._content << int(v._type); + +BINARY_STREAM_WRITE(PIVariant) { + s << v._content << v._type; if (v._type == PIVariant::pivCustom) { #ifdef CUSTOM_PIVARIANT if (v._info) { @@ -788,10 +788,8 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIVariant & v) { } return s; } -inline PIByteArray & operator >>(PIByteArray & s, PIVariant & v) { - int t(0); - s >> v._content >> t; - v._type = (PIVariant::Type)t; +BINARY_STREAM_READ(PIVariant) { + s >> v._content >> v._type; if (v._type == PIVariant::pivCustom) { PIString tn; s >> tn; diff --git a/libs/main/core/pivarianttypes.cpp b/libs/main/core/pivarianttypes.cpp index 6eb609cb..cd823373 100644 --- a/libs/main/core/pivarianttypes.cpp +++ b/libs/main/core/pivarianttypes.cpp @@ -110,25 +110,25 @@ PIPropertyStorage PIVariantTypes::IODevice::get() const { PIString PIVariantTypes::IODevice::toPICout() const { PIString s; - s << "IODevice(" << prefix << ", mode="; + 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="; + 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"; + s += " br"; if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingWrite]) - s << " bw"; + s += " bw"; } #endif // MICRO_PIP PIPropertyStorage ps = get(); piForeachC (PIPropertyStorage::Property & p, ps) { - s << ", " << p.name << "=\"" << p.value.toString() << "\""; + s += ", " + p.name + "=\"" + p.value.toString() + "\""; } - s << ")"; + s += ")"; return s; } diff --git a/libs/main/core/pivarianttypes.h b/libs/main/core/pivarianttypes.h index 00342f31..17b0546b 100644 --- a/libs/main/core/pivarianttypes.h +++ b/libs/main/core/pivarianttypes.h @@ -164,28 +164,34 @@ struct PIP_EXPORT IODevice { } -inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Enumerator & v) {s << v.value << v.name; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Enumerator & v) {s >> v.value >> v.name; return s;} inline PICout operator <<(PICout s, const PIVariantTypes::Enumerator & v) {s << v.name << "(" << v.value << ")"; return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Enum & v) {s << v.enum_name << v.selected << v.enum_list; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Enum & v) {s >> v.enum_name >> v.selected >> v.enum_list; return s;} inline PICout operator <<(PICout s, const PIVariantTypes::Enum & v) {s << "Enum(" << v.selectedValue() << "=" << v.selectedName() << ")"; return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::File & v) {s << v.file << v.filter << uchar((v.is_abs ? 1 : 0) + (v.is_save ? 2 : 0)); return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::File & v) {uchar f(0); s >> v.file >> v.filter >> f; v.is_abs = ((f & 1) == 1); v.is_save = ((f & 2) == 2); return s;} inline PICout operator <<(PICout s, const PIVariantTypes::File & v) {s << "File(\"" << v.file << "\")"; return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Dir & v) {s << v.dir << v.is_abs; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Dir & v) {s >> v.dir >> v.is_abs; return s;} inline PICout operator <<(PICout s, const PIVariantTypes::Dir & v) {s << "Dir(\"" << v.dir << "\")"; return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Color & v) {s << v.rgba; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Color & v) {s >> v.rgba; return s;} inline PICout operator <<(PICout s, const PIVariantTypes::Color & v) {s.saveControl(); s << PICoutManipulators::Hex << "Color(#" << v.rgba << ")"; s.restoreControl(); return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::IODevice & v) {s << v.prefix << v.mode << v.options << v.props; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::IODevice & v) {s >> v.prefix >> v.mode >> v.options >> v.props; return s;} inline PICout operator <<(PICout s, const PIVariantTypes::IODevice & v) {s << v.toPICout(); return s;} +BINARY_STREAM_WRITE(PIVariantTypes::Enumerator) {s << v.value << v.name; return s;} +BINARY_STREAM_READ (PIVariantTypes::Enumerator) {s >> v.value >> v.name; return s;} + +BINARY_STREAM_WRITE(PIVariantTypes::Enum) {s << v.enum_name << v.selected << v.enum_list; return s;} +BINARY_STREAM_READ (PIVariantTypes::Enum) {s >> v.enum_name >> v.selected >> v.enum_list; return s;} + +BINARY_STREAM_WRITE(PIVariantTypes::File) {s << v.file << v.filter << uchar((v.is_abs ? 1 : 0) + (v.is_save ? 2 : 0)); return s;} +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;} + +BINARY_STREAM_WRITE(PIVariantTypes::Dir) {s << v.dir << v.is_abs; return s;} +BINARY_STREAM_READ (PIVariantTypes::Dir) {s >> v.dir >> v.is_abs; return s;} + +BINARY_STREAM_WRITE(PIVariantTypes::Color) {s << v.rgba; return s;} +BINARY_STREAM_READ (PIVariantTypes::Color) {s >> v.rgba; return s;} + +BINARY_STREAM_WRITE(PIVariantTypes::IODevice) {s << v.prefix << v.mode << v.options << v.props; return s;} +BINARY_STREAM_READ (PIVariantTypes::IODevice) {s >> v.prefix >> v.mode >> v.options >> v.props; return s;} + #endif // PIVARIANTYPES_H diff --git a/libs/main/introspection/piintrospection_containers_p.cpp b/libs/main/introspection/piintrospection_containers_p.cpp index 039e461b..75d80037 100644 --- a/libs/main/introspection/piintrospection_containers_p.cpp +++ b/libs/main/introspection/piintrospection_containers_p.cpp @@ -96,15 +96,3 @@ PIVector PIIntrospectionContainers::getInfo } return ret; } - - - - -PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::TypeInfo & v) { - s << PIByteArray::RawData(&v, sizeof(PIIntrospectionContainers::_Type)) << v.name; - return s; -} -PIByteArray & operator >>(PIByteArray & s, PIIntrospectionContainers::TypeInfo & v) { - s >> PIByteArray::RawData(&v, sizeof(PIIntrospectionContainers::_Type)) >> v.name; - return s; -} diff --git a/libs/main/introspection/piintrospection_containers_p.h b/libs/main/introspection/piintrospection_containers_p.h index cd066d00..da0049be 100644 --- a/libs/main/introspection/piintrospection_containers_p.h +++ b/libs/main/introspection/piintrospection_containers_p.h @@ -65,7 +65,14 @@ public: mutable PISpinlock mutex; }; -PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::TypeInfo & v); -PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIIntrospectionContainers::TypeInfo & v); + +BINARY_STREAM_WRITE(PIIntrospectionContainers::TypeInfo) { + s << PIMemoryBlock(&v, sizeof(PIIntrospectionContainers::_Type)) << v.name; + return s; +} +BINARY_STREAM_READ(PIIntrospectionContainers::TypeInfo) { + s >> PIMemoryBlock(&v, sizeof(PIIntrospectionContainers::_Type)) >> v.name; + return s; +} #endif // PIINTROSPECTION_CONTAINERS_P_H diff --git a/libs/main/introspection/piintrospection_server_p.cpp b/libs/main/introspection/piintrospection_server_p.cpp index eb818065..b32f2de5 100644 --- a/libs/main/introspection/piintrospection_server_p.cpp +++ b/libs/main/introspection/piintrospection_server_p.cpp @@ -77,82 +77,6 @@ PIVector PIIntrospection::getObjects() { } -PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::RequiredInfo & v) { - PIChunkStream cs; - cs.add(1, v.types); - b << cs.data(); - return b; -} - - -PIByteArray & operator >>(PIByteArray & b, PIIntrospection::RequiredInfo & v) { - PIByteArray csba; b >> csba; - PIChunkStream cs(csba); - while (!cs.atEnd()) { - switch (cs.read()) { - case 1: cs.get(v.types); break; - default: break; - } - } - return b; -} - - -PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ProcessInfo & v) { - PIChunkStream cs; - cs.add(1, v.architecture).add(2, v.execCommand).add(3, v.execDateTime).add(4, v.hostname).add(5, v.OS_name) - .add(6, v.OS_version).add(7, v.processorsCount).add(8, v.user).add(9, v.build_options); - b << cs.data(); - return b; -} - - -PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ProcessInfo & v) { - PIByteArray csba; b >> csba; - PIChunkStream cs(csba); - while (!cs.atEnd()) { - switch (cs.read()) { - case 1: cs.get(v.architecture); break; - case 2: cs.get(v.execCommand); break; - case 3: cs.get(v.execDateTime); break; - case 4: cs.get(v.hostname); break; - case 5: cs.get(v.OS_name); break; - case 6: cs.get(v.OS_version); break; - case 7: cs.get(v.processorsCount); break; - case 8: cs.get(v.user); break; - case 9: cs.get(v.build_options); break; - default: break; - } - } - return b; -} - - -PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ObjectInfo & v) { - PIChunkStream cs; - cs.add(1, v.classname).add(2, v.name).add(3, v.parents).add(4, v.properties).add(5, v.queued_events); - b << cs.data(); - return b; -} - - -PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ObjectInfo & v) { - PIByteArray csba; b >> csba; - PIChunkStream cs(csba); - while (!cs.atEnd()) { - switch (cs.read()) { - case 1: cs.get(v.classname); break; - case 2: cs.get(v.name); break; - case 3: cs.get(v.parents); break; - case 4: cs.get(v.properties); break; - case 5: cs.get(v.queued_events); break; - default: break; - } - } - return b; -} - - PIByteArray PIIntrospection::packInfo() { diff --git a/libs/main/introspection/piintrospection_server_p.h b/libs/main/introspection/piintrospection_server_p.h index 549dd044..8935ac0d 100644 --- a/libs/main/introspection/piintrospection_server_p.h +++ b/libs/main/introspection/piintrospection_server_p.h @@ -24,6 +24,7 @@ #include "piintrospection_containers_p.h" #include "piintrospection_threads.h" #include "piintrospection_threads_p.h" +#include "pichunkstream.h" #include "pisystemmonitor.h" @@ -91,13 +92,72 @@ public: }; -PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::RequiredInfo & v); -PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIIntrospection::RequiredInfo & v); -PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ProcessInfo & v); -PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ProcessInfo & v); +BINARY_STREAM_WRITE(PIIntrospection::RequiredInfo) { + PIChunkStream cs; + cs.add(1, v.types); + s << cs.data(); + return s; +} +BINARY_STREAM_READ(PIIntrospection::RequiredInfo) { + PIByteArray csba; s >> csba; + PIChunkStream cs(csba); + while (!cs.atEnd()) { + switch (cs.read()) { + case 1: cs.get(v.types); break; + default: break; + } + } + return s; +} -PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ObjectInfo & v); -PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ObjectInfo & v); +BINARY_STREAM_WRITE(PIIntrospection::ProcessInfo) { + PIChunkStream cs; + cs.add(1, v.architecture).add(2, v.execCommand).add(3, v.execDateTime).add(4, v.hostname).add(5, v.OS_name) + .add(6, v.OS_version).add(7, v.processorsCount).add(8, v.user).add(9, v.build_options); + s << cs.data(); + return s; +} +BINARY_STREAM_READ(PIIntrospection::ProcessInfo) { + PIByteArray csba; s >> csba; + PIChunkStream cs(csba); + while (!cs.atEnd()) { + switch (cs.read()) { + case 1: cs.get(v.architecture); break; + case 2: cs.get(v.execCommand); break; + case 3: cs.get(v.execDateTime); break; + case 4: cs.get(v.hostname); break; + case 5: cs.get(v.OS_name); break; + case 6: cs.get(v.OS_version); break; + case 7: cs.get(v.processorsCount); break; + case 8: cs.get(v.user); break; + case 9: cs.get(v.build_options); break; + default: break; + } + } + return s; +} + +BINARY_STREAM_WRITE(PIIntrospection::ObjectInfo) { + PIChunkStream cs; + cs.add(1, v.classname).add(2, v.name).add(3, v.parents).add(4, v.properties).add(5, v.queued_events); + s << cs.data(); + return s; +} +BINARY_STREAM_READ(PIIntrospection::ObjectInfo) { + PIByteArray csba; s >> csba; + PIChunkStream cs(csba); + while (!cs.atEnd()) { + switch (cs.read()) { + case 1: cs.get(v.classname); break; + case 2: cs.get(v.name); break; + case 3: cs.get(v.parents); break; + case 4: cs.get(v.properties); break; + case 5: cs.get(v.queued_events); break; + default: break; + } + } + return s; +} #endif // PIINTROSPECTION_SERVER_P_H diff --git a/libs/main/introspection/piintrospection_threads_p.cpp b/libs/main/introspection/piintrospection_threads_p.cpp index d872d479..9c5bdd72 100644 --- a/libs/main/introspection/piintrospection_threads_p.cpp +++ b/libs/main/introspection/piintrospection_threads_p.cpp @@ -81,19 +81,3 @@ void PIIntrospectionThreads::threadRunDone(PIThread * t, ullong us) { ThreadInfo & ti(threads[t]); ti.run_us = (ti.run_us * 0.8) + (us * 0.2); /// WARNING } - - - - -PIByteArray & operator <<(PIByteArray & b, const PIIntrospectionThreads::ThreadInfo & v) { - b << v.classname << v.name << v.id << int(v.state) << v.priority << v.delay << v.run_us << v.run_count; - return b; -} - - -PIByteArray & operator >>(PIByteArray & b, PIIntrospectionThreads::ThreadInfo & v) { - int st(0); - b >> v.classname >> v.name >> v.id >> st >> v.priority >> v.delay >> v.run_us >> v.run_count; - v.state = (PIIntrospectionThreads::ThreadState)st; - return b; -} diff --git a/libs/main/introspection/piintrospection_threads_p.h b/libs/main/introspection/piintrospection_threads_p.h index 3318a4d2..42ab27e2 100644 --- a/libs/main/introspection/piintrospection_threads_p.h +++ b/libs/main/introspection/piintrospection_threads_p.h @@ -57,7 +57,14 @@ public: }; -PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIIntrospectionThreads::ThreadInfo & v); -PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIIntrospectionThreads::ThreadInfo & v); + +BINARY_STREAM_WRITE(PIIntrospectionThreads::ThreadInfo) { + s << v.classname << v.name << v.id << v.state << v.priority << v.delay << v.run_us << v.run_count; + return s; +} +BINARY_STREAM_READ(PIIntrospectionThreads::ThreadInfo) { + s >> v.classname >> v.name >> v.id >> v.state >> v.priority >> v.delay >> v.run_us >> v.run_count; + return s; +} #endif // PIINTROSPECTION_THREADS_P_H diff --git a/libs/main/io_devices/pican.cpp b/libs/main/io_devices/pican.cpp index b4d1f827..013166b5 100644 --- a/libs/main/io_devices/pican.cpp +++ b/libs/main/io_devices/pican.cpp @@ -148,7 +148,7 @@ int PICAN::readedCANID() const { PIString PICAN::constructFullPathDevice() const { PIString ret; - ret << path() << ":" << PIString::fromNumber(CANID(),16); + ret += path() + ":" + PIString::fromNumber(CANID(), 16); return ret; } diff --git a/libs/main/io_devices/piconfig.cpp b/libs/main/io_devices/piconfig.cpp index 816207ff..62212c01 100644 --- a/libs/main/io_devices/piconfig.cpp +++ b/libs/main/io_devices/piconfig.cpp @@ -400,7 +400,7 @@ PIString PIConfig::_readLineDev() { void PIConfig::_writeDev(const PIString & l) { //piCout << "write \"" << l << "\""; if (!dev) return; - if (PIString(dev->className()) == "PIFile") {*((PIFile*)dev) << (l); return;} + if (PIString(dev->className()) == "PIFile") {((PIFile*)dev)->write(l.toUTF8()); return;} if (PIString(dev->className()) == "PIIOString") {((PIIOString*)dev)->writeString(l); return;} dev->write(l.toByteArray()); } diff --git a/libs/main/io_devices/piethernet.cpp b/libs/main/io_devices/piethernet.cpp index 1070f635..9a848a8a 100644 --- a/libs/main/io_devices/piethernet.cpp +++ b/libs/main/io_devices/piethernet.cpp @@ -116,9 +116,9 @@ PIEthernet::Address::Address(const PIString & _ip, ushort _port) { PIString PIEthernet::Address::ipString() const { PIString ret = PIString::fromNumber(ip_b[0]); - ret << "." << PIString::fromNumber(ip_b[1]); - ret << "." << PIString::fromNumber(ip_b[2]); - ret << "." << PIString::fromNumber(ip_b[3]); + ret += "." + PIString::fromNumber(ip_b[1]); + ret += "." + PIString::fromNumber(ip_b[2]); + ret += "." + PIString::fromNumber(ip_b[3]); return ret; } @@ -930,11 +930,12 @@ void PIEthernet::propertyChanged(const char * name) { PIString PIEthernet::constructFullPathDevice() const { PIString ret; - ret << (type() == PIEthernet::UDP ? "UDP" : "TCP") << ":" << readIP() << ":" << readPort(); + ret += (type() == PIEthernet::UDP ? "UDP" : "TCP"); + ret += ":" + readIP() + ":" + PIString::fromNumber(readPort()); if (type() == PIEthernet::UDP) { - ret << ":" << sendIP() << ":" << sendPort(); + ret += ":" + sendIP() + ":" + PIString::fromNumber(sendPort()); piForeachC (PIString & m, multicastGroups()) - ret << ":mcast:" << m; + ret += ":mcast:" + m; } return ret; } diff --git a/libs/main/io_devices/pifile.cpp b/libs/main/io_devices/pifile.cpp index a16ae76b..b4d53be7 100644 --- a/libs/main/io_devices/pifile.cpp +++ b/libs/main/io_devices/pifile.cpp @@ -452,7 +452,8 @@ void PIFile::setPrecision(int prec) { PIFile & PIFile::put(const PIByteArray & v) { - writeBinary((int)v.size_s()); + int sz = (int)v.size_s(); + write(createMemoryBlock(&sz)); write(v); return *this; } @@ -461,7 +462,7 @@ PIFile & PIFile::put(const PIByteArray & v) { PIByteArray PIFile::get() { PIByteArray ret; int sz(0); - read(&sz, sizeof(sz)); + read(createMemoryBlock(&sz)); if (sz > 0) { ret.resize(sz); read(ret.data(), sz); @@ -470,156 +471,6 @@ PIByteArray PIFile::get() { } -PIFile &PIFile::operator <<(double v) { - if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, ("%" + prec_str + "lf").data(), v); - return *this; -} - - -PIFile &PIFile::operator >>(double & v) { - if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%lf", &v); - return *this; -} - - -PIFile &PIFile::operator >>(float & v) { - if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%f", &v); - return *this; -} - - -PIFile &PIFile::operator >>(ullong & v) { - if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%lln", &v); - return *this; -} - - -PIFile &PIFile::operator >>(ulong & v) { - if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%ln", &v); - return *this; -} - - -PIFile &PIFile::operator >>(uint & v) { - if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%n", &v); - return *this; -} - - -PIFile &PIFile::operator >>(ushort & v) { - if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%hn", &v); - return *this; -} - - -PIFile &PIFile::operator >>(uchar & v) { - if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%hhn", &v); - return *this; -} - - -PIFile &PIFile::operator >>(llong & v) { - if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%lln", &v); - return *this; -} - - -PIFile &PIFile::operator >>(long & v) { - if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%ln", &v); - return *this; -} - - -PIFile &PIFile::operator >>(int & v) { - if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%n", &v); - return *this; -} - - -PIFile &PIFile::operator >>(short & v) { - if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%hn", &v); - return *this; -} - - -PIFile &PIFile::operator >>(char & v) { - if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%hhn", &v); - return *this; -} - - -PIFile &PIFile::operator <<(float v) { - if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, ("%" + prec_str + "f").data(), v); - return *this; -} - - -PIFile &PIFile::operator <<(ullong v) { - if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%llu", v); - return *this; -} - - -PIFile &PIFile::operator <<(ulong v) { - if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%lu", v); - return *this; -} - - -PIFile &PIFile::operator <<(uint v) { - if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%u", v); - return *this; -} - - -PIFile &PIFile::operator <<(ushort v) { - if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%hu", v); - return *this; -} - - -PIFile &PIFile::operator <<(uchar v) { - if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%u", int(v)); - return *this; -} - - -PIFile &PIFile::operator <<(llong v) { - if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%lld", v); - return *this; -} - - -PIFile &PIFile::operator <<(long v) { - if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%ld", v); - return *this; -} - - -PIFile &PIFile::operator <<(int v) { - if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%d", v); - return *this; -} - - -PIFile &PIFile::operator <<(short v) { - if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%hd", v); - return *this; -} - - -PIFile &PIFile::operator <<(const PIByteArray & v) { - if (canWrite() && PRIVATE->fd != 0) write(v.data(), v.size()); - return *this; -} - - -PIFile &PIFile::operator <<(const char v) { - if (canWrite() && PRIVATE->fd != 0) write(&v, 1); - return *this; -} - - int PIFile::readDevice(void * read_to, int max_size) { if (!canRead() || PRIVATE->fd == 0) return -1; return fread(read_to, 1, max_size, PRIVATE->fd); @@ -632,13 +483,6 @@ int PIFile::writeDevice(const void * data, int max_size) { } -PIFile &PIFile::operator <<(const PIString & v) { - if (canWrite() && v.isNotEmpty() && PRIVATE->fd != 0) - *this << v.toCharset(defaultCharset()); - return *this; -} - - void PIFile::clear() { close(); PRIVATE->fd = fopen(path().data(), "w"); diff --git a/libs/main/io_devices/pifile.h b/libs/main/io_devices/pifile.h index 8a9481dc..eb2f7506 100644 --- a/libs/main/io_devices/pifile.h +++ b/libs/main/io_devices/pifile.h @@ -260,161 +260,6 @@ public: //! \~russian Читает из файла размер байтового массива и его содержимое (десериализация) PIByteArray get(); - - //! \~english Write to file binary content of "v" - //! \~russian Пишет в файл байтовое содержимое "v" - PIFile & writeBinary(const char v) {write(&v, sizeof(v)); return *this;} - - //! \~english Write to file binary content of "v" - //! \~russian Пишет в файл байтовое содержимое "v" - PIFile & writeBinary(const short v) {write(&v, sizeof(v)); return *this;} - - //! \~english Write to file binary content of "v" - //! \~russian Пишет в файл байтовое содержимое "v" - PIFile & writeBinary(const int v) {write(&v, sizeof(v)); return *this;} - - //! \~english Write to file binary content of "v" - //! \~russian Пишет в файл байтовое содержимое "v" - PIFile & writeBinary(const long v) {write(&v, sizeof(v)); return *this;} - - //! \~english Write to file binary content of "v" - //! \~russian Пишет в файл байтовое содержимое "v" - PIFile & writeBinary(const llong v) {write(&v, sizeof(v)); return *this;} - - //! \~english Write to file binary content of "v" - //! \~russian Пишет в файл байтовое содержимое "v" - PIFile & writeBinary(const uchar v) {write(&v, sizeof(v)); return *this;} - - //! \~english Write to file binary content of "v" - //! \~russian Пишет в файл байтовое содержимое "v" - PIFile & writeBinary(const ushort v) {write(&v, sizeof(v)); return *this;} - - //! \~english Write to file binary content of "v" - //! \~russian Пишет в файл байтовое содержимое "v" - PIFile & writeBinary(const uint v) {write(&v, sizeof(v)); return *this;} - - //! \~english Write to file binary content of "v" - //! \~russian Пишет в файл байтовое содержимое "v" - PIFile & writeBinary(const ulong v) {write(&v, sizeof(v)); return *this;} - - //! \~english Write to file binary content of "v" - //! \~russian Пишет в файл байтовое содержимое "v" - PIFile & writeBinary(const ullong v) {write(&v, sizeof(v)); return *this;} - - //! \~english Write to file binary content of "v" - //! \~russian Пишет в файл байтовое содержимое "v" - PIFile & writeBinary(const float v) {write(&v, sizeof(v)); return *this;} - - //! \~english Write to file binary content of "v" - //! \~russian Пишет в файл байтовое содержимое "v" - PIFile & writeBinary(const double v) {write(&v, sizeof(v)); return *this;} - - - //! \~english Write to file text representation of "v" - //! \~russian Пишет в файл текстовое представление "v" - PIFile & operator <<(const char v); - - //! \~english Write to file string "v" - //! \~russian Пишет в файл строку "v" - PIFile & operator <<(const PIString & v); - - //! \~english Write to file text representation of "v" - //! \~russian Пишет в файл текстовое представление "v" - PIFile & operator <<(const PIByteArray & v); - - //! \~english Write to file text representation of "v" - //! \~russian Пишет в файл текстовое представление "v" - PIFile & operator <<(short v); - - //! \~english Write to file text representation of "v" - //! \~russian Пишет в файл текстовое представление "v" - PIFile & operator <<(int v); - - //! \~english Write to file text representation of "v" - //! \~russian Пишет в файл текстовое представление "v" - PIFile & operator <<(long v); - - //! \~english Write to file text representation of "v" - //! \~russian Пишет в файл текстовое представление "v" - PIFile & operator <<(llong v); - - //! \~english Write to file text representation of "v" - //! \~russian Пишет в файл текстовое представление "v" - PIFile & operator <<(uchar v); - - //! \~english Write to file text representation of "v" - //! \~russian Пишет в файл текстовое представление "v" - PIFile & operator <<(ushort v); - - //! \~english Write to file text representation of "v" - //! \~russian Пишет в файл текстовое представление "v" - PIFile & operator <<(uint v); - - //! \~english Write to file text representation of "v" - //! \~russian Пишет в файл текстовое представление "v" - PIFile & operator <<(ulong v); - - //! \~english Write to file text representation of "v" - //! \~russian Пишет в файл текстовое представление "v" - PIFile & operator <<(ullong v); - - //! \~english Write to file text representation of "v" with precision \a precision() - //! \~russian Пишет в файл текстовое представление "v" с точностью \a precision() - PIFile & operator <<(float v); - - //! \~english Write to file text representation of "v" with precision \a precision() - //! \~russian Пишет в файл текстовое представление "v" с точностью \a precision() - PIFile & operator <<(double v); - - - //! \~english Read from file text representation of "v" - //! \~russian Читает из файла текстовое представление "v" - PIFile & operator >>(char & v); - - //! \~english Read from file text representation of "v" - //! \~russian Читает из файла текстовое представление "v" - PIFile & operator >>(short & v); - - //! \~english Read from file text representation of "v" - //! \~russian Читает из файла текстовое представление "v" - PIFile & operator >>(int & v); - - //! \~english Read from file text representation of "v" - //! \~russian Читает из файла текстовое представление "v" - PIFile & operator >>(long & v); - - //! \~english Read from file text representation of "v" - //! \~russian Читает из файла текстовое представление "v" - PIFile & operator >>(llong & v); - - //! \~english Read from file text representation of "v" - //! \~russian Читает из файла текстовое представление "v" - PIFile & operator >>(uchar & v); - - //! \~english Read from file text representation of "v" - //! \~russian Читает из файла текстовое представление "v" - PIFile & operator >>(ushort & v); - - //! \~english Read from file text representation of "v" - //! \~russian Читает из файла текстовое представление "v" - PIFile & operator >>(uint & v); - - //! \~english Read from file text representation of "v" - //! \~russian Читает из файла текстовое представление "v" - PIFile & operator >>(ulong & v); - - //! \~english Read from file text representation of "v" - //! \~russian Читает из файла текстовое представление "v" - PIFile & operator >>(ullong & v); - - //! \~english Read from file text representation of "v" - //! \~russian Читает из файла текстовое представление "v" - PIFile & operator >>(float & v); - - //! \~english Read from file text representation of "v" - //! \~russian Читает из файла текстовое представление "v" - PIFile & operator >>(double & v); - EVENT_HANDLER(void, clear); EVENT_HANDLER(void, remove); EVENT_HANDLER1(void, resize, llong, new_size) {resize(new_size, 0);} @@ -518,14 +363,19 @@ inline PICout operator <<(PICout s, const PIFile::FileInfo & v) { //! \relatesalso PIByteArray //! \~english Store operator //! \~russian Оператор сохранения -inline PIByteArray & operator <<(PIByteArray & s, const PIFile::FileInfo & v) {s << v.path << v.size << v.time_access << v.time_modification << - (int)v.flags << v.id_user << v.id_group << v.perm_user.raw << v.perm_group.raw << v.perm_other.raw; return s;} +BINARY_STREAM_WRITE(PIFile::FileInfo) { + s << v.path << v.size << v.time_access << v.time_modification << + v.flags << v.id_user << v.id_group << v.perm_user.raw << v.perm_group.raw << v.perm_other.raw; + return s; +} //! \relatesalso PIByteArray //! \~english Restore operator //! \~russian Оператор извлечения -inline PIByteArray & operator >>(PIByteArray & s, PIFile::FileInfo & v) {s >> v.path >> v.size >> v.time_access >> v.time_modification >> - *(int*)(&(v.flags)) >> v.id_user >> v.id_group >> v.perm_user.raw >> v.perm_group.raw >> v.perm_other.raw; return s;} - +BINARY_STREAM_READ(PIFile::FileInfo) { + s >> v.path >> v.size >> v.time_access >> v.time_modification >> + v.flags >> v.id_user >> v.id_group >> v.perm_user.raw >> v.perm_group.raw >> v.perm_other.raw; + return s; +} #endif // PIFILE_H diff --git a/libs/main/io_devices/piiodevice.h b/libs/main/io_devices/piiodevice.h index df36d4db..3ecf77da 100644 --- a/libs/main/io_devices/piiodevice.h +++ b/libs/main/io_devices/piiodevice.h @@ -276,6 +276,10 @@ public: //! \~russian Читает из устройства не более "max_size" байт в "read_to" int read(void * read_to, int max_size) {return readDevice(read_to, max_size);} + //! \~english Read from device to memory block "mb" + //! \~russian Читает из устройства в блок памяти "mb" + int read(PIMemoryBlock mb) {return readDevice(mb.data(), mb.size());} + //! \~english Read from device maximum "max_size" bytes and returns them as PIByteArray //! \~russian Читает из устройства не более "max_size" байт и возвращает данные как PIByteArray PIByteArray read(int max_size); @@ -357,6 +361,10 @@ public: EVENT_HANDLER(bool, close); EVENT_HANDLER1(int, write, PIByteArray, data); + //! \~english Write memory block "mb" to device + //! \~russian Пишет в устройство блок памяти "mb" + int write(const PIMemoryBlock & mb) {return write(mb.data(), mb.size());} + EVENT_VHANDLER(void, flush) {;} EVENT(opened) diff --git a/libs/main/io_devices/piiostream.h b/libs/main/io_devices/piiostream.h new file mode 100644 index 00000000..6f038aba --- /dev/null +++ b/libs/main/io_devices/piiostream.h @@ -0,0 +1,99 @@ +/*! \file piiostream.h + * \ingroup IO + * \~\brief + * \~english PIBinaryStream functionality for PIIODevice + * \~russian Функциональность PIBinaryStream для PIIODevice + */ +/* + PIP - Platform Independent Primitives + PIBinaryStream functionality for PIIODevice + 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 . +*/ + +#ifndef PIIOSTREAM_H +#define PIIOSTREAM_H + +#include "piiostring.h" +#include "pitextstream.h" + + +//! \ingroup IO +//! \~\brief +//! \~english PIBinaryStream functionality for PIIODevice. +//! \~russian Функциональность PIBinaryStream для PIIODevice. +class PIP_EXPORT PIIOBinaryStream: public PIBinaryStream { +public: + + //! \~english Contructs %PIIOBinaryStream for "device" device + //! \~russian Создает %PIIOBinaryStream для устройства "device" + PIIOBinaryStream(PIIODevice * device = nullptr): dev(device) {} + + //! \~english Assign "device" device + //! \~russian Назначает устройство "device" + void setDevice(PIIODevice * device) {dev = device;} + + bool binaryStreamAppendImp(const void * d, size_t s) { + if (!dev) return false; + return dev->write(d, s); + } + + bool binaryStreamTakeImp(void * d, size_t s) { + if (!dev) return false; + return dev->read(d, s); + } + +private: + PIIODevice * dev; + +}; + + +//! \ingroup IO +//! \~\brief +//! \~english PITextStream functionality for PIIODevice. +//! \~russian Функциональность PITextStream для PIIODevice. +class PIP_EXPORT PIIOTextStream: public PITextStream { +public: + + //! \~english Contructs %PIIOTextStream for "device" device + //! \~russian Создает %PIIOTextStream для устройства "device" + PIIOTextStream(PIIODevice * device): PITextStream(&bin_stream), bin_stream(device) {} + + //! \~english Contructs %PIIOTextStream for "string" string + //! \~russian Создает %PIIOTextStream для строки "string" + PIIOTextStream(PIString * string): PITextStream(&bin_stream) { + io_string = new PIIOString(string); + bin_stream.setDevice(io_string); + } + + ~PIIOTextStream() { + if (io_string) + delete io_string; + } + + void setDevice(PIIODevice * device) { + bin_stream = PIIOBinaryStream(device); + setStream(&bin_stream); + } + +private: + PIIOString * io_string = nullptr; + PIIOBinaryStream bin_stream; + +}; + + +#endif // PIIOSTREAM_H diff --git a/libs/main/io_devices/pipeer.cpp b/libs/main/io_devices/pipeer.cpp index 96a07810..eb5c339e 100644 --- a/libs/main/io_devices/pipeer.cpp +++ b/libs/main/io_devices/pipeer.cpp @@ -573,7 +573,7 @@ bool PIPeer::mbcastRead(uchar * data, int size) { if (type <= 0 || type >= 4) return true; PeerInfo pi; ba >> pi.name; -// piCoutObj << "received mb from" << pi.name << "packet" << type; + //piCout << "received mb from" << pi.name << "packet" << type; if (pi.name == self_info.name) return true; PIMutexLocker locker(mc_mutex); diag_s.received(size); @@ -789,6 +789,7 @@ void PIPeer::sendPeerInfo(const PeerInfo & info) { void PIPeer::sendPeerRemove(const PIString & peer) { + //piCout << name() << "sendPeerRemove" << peer; PIByteArray ba; ba << int(2) << peer; sendMBcast(ba); @@ -858,7 +859,7 @@ void PIPeer::syncPeers() { PeerInfo & cp(peers[i]); if (cp.sync > 3) { pn = cp.name; - //piCoutObj << "sync: remove " << pn; + //piCout << "sync: remove " << pn; cp.destroy(); addToRemoved(cp); peers.remove(i); @@ -967,7 +968,7 @@ void PIPeer::newTcpClient(PIEthernet *client) { PIString PIPeer::constructFullPathDevice() const { PIString ret; - ret << self_info.name << ":" << trustPeerName(); + ret += self_info.name + ":" + trustPeerName(); return ret; } diff --git a/libs/main/io_devices/pipeer.h b/libs/main/io_devices/pipeer.h index a592eb90..0a2ddf93 100644 --- a/libs/main/io_devices/pipeer.h +++ b/libs/main/io_devices/pipeer.h @@ -41,8 +41,7 @@ public: class PIP_EXPORT PeerInfo { friend class PIPeer; - friend PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v); - friend PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v); + BINARY_STREAM_FRIEND(PIPeer::PeerInfo); public: PeerInfo() {dist = sync = cnt = 0; trace = -1; was_update = false; _data = 0;} ~PeerInfo() {} @@ -80,9 +79,8 @@ public: PeerData * _data; }; - - friend PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v); - friend PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v); + + BINARY_STREAM_FRIEND(PIPeer::PeerInfo); bool send(const PIString & to, const PIByteArray & data) {return send(to, data.data(), data.size_s());} bool send(const PIString & to, const PIString & data) {return send(to, data.data(), data.size_s());} @@ -209,10 +207,10 @@ private: inline PICout operator <<(PICout c, const PIPeer::PeerInfo::PeerAddress & v) {c.space(); c << "PeerAddress(" << v.address << ", " << v.netmask << ", " << v.ping << ")"; return c;} inline PICout operator <<(PICout c, const PIPeer::PeerInfo & v) {c.space(); c << "PeerInfo(" << v.name << ", " << v.dist << ", " << v.addresses << ")"; return c;} -inline PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo::PeerAddress & v) {s << v.address << v.netmask << v.ping; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo::PeerAddress & v) {s >> v.address >> v.netmask >> v.ping; return s;} +BINARY_STREAM_WRITE(PIPeer::PeerInfo::PeerAddress) {s << v.address << v.netmask << v.ping; return s;} +BINARY_STREAM_READ (PIPeer::PeerInfo::PeerAddress) {s >> v.address >> v.netmask >> v.ping; return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v) {s << v.name << v.addresses << v.dist << v.neighbours << v.cnt << v.time; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v) {s >> v.name >> v.addresses >> v.dist >> v.neighbours >> v.cnt >> v.time; return s;} +BINARY_STREAM_WRITE(PIPeer::PeerInfo) {s << v.name << v.addresses << v.dist << v.neighbours << v.cnt << v.time; return s;} +BINARY_STREAM_READ (PIPeer::PeerInfo) {s >> v.name >> v.addresses >> v.dist >> v.neighbours >> v.cnt >> v.time; return s;} #endif // PIPEER_H diff --git a/libs/main/io_devices/piserial.cpp b/libs/main/io_devices/piserial.cpp index 781dd972..7a3fada6 100644 --- a/libs/main/io_devices/piserial.cpp +++ b/libs/main/io_devices/piserial.cpp @@ -521,14 +521,14 @@ PIString PISerial::readString(int size, double timeout_ms) { while (tm_.elapsed_m() < timeout_ms) { ret = readDevice(td, 1024); if (ret <= 0) piMinSleep(); - else str << PIString((char*)td, ret); + else str += PIString((char*)td, ret); } } else { while (all < size && tm_.elapsed_m() < timeout_ms) { ret = readDevice(td, size - all); if (ret <= 0) piMinSleep(); else { - str << PIString((char*)td, ret); + str += PIString((char*)td, ret); all += ret; } } @@ -537,12 +537,12 @@ PIString PISerial::readString(int size, double timeout_ms) { } else { bool br = setOption(BlockingRead, true); all = readDevice(td, 1); - str << PIString((char*)td, all); + str += PIString((char*)td, all); while (all < size) { ret = readDevice(td, size - all); if (ret <= 0) piMinSleep(); else { - str << PIString((char*)td, ret); + str += PIString((char*)td, ret); all += ret; } } @@ -862,13 +862,13 @@ bool PISerial::configureDevice(const void * e_main, const void * e_parent) { PIString PISerial::constructFullPathDevice() const { PIString ret; - ret << path() << ":" << int(inSpeed()) << ":" << dataBitsCount(); + ret += path() + ":" + PIString::fromNumber(int(inSpeed())) + ":" + PIString::fromNumber(dataBitsCount()); if (parameters()[ParityControl]) { - if (parameters()[ParityOdd]) ret << ":O"; - else ret << ":E"; - } else ret << ":N"; - if (parameters()[TwoStopBits]) ret << ":2"; - else ret << ":1"; + if (parameters()[ParityOdd]) ret += ":O"; + else ret += ":E"; + } else ret += ":N"; + if (parameters()[TwoStopBits]) ret += ":2"; + else ret += ":1"; return ret; } diff --git a/libs/main/io_devices/piserial.h b/libs/main/io_devices/piserial.h index efb30010..0c661eb7 100644 --- a/libs/main/io_devices/piserial.h +++ b/libs/main/io_devices/piserial.h @@ -336,12 +336,12 @@ inline bool operator !=(const PISerial::DeviceInfo & v0, const PISerial::DeviceI //! \relatesalso PIByteArray //! \~english Store operator //! \~russian Оператор сохранения -inline PIByteArray & operator <<(PIByteArray & s, const PISerial::DeviceInfo & v) {s << v.vID << v.pID << v.path << v.description << v.manufacturer; return s;} +BINARY_STREAM_WRITE(PISerial::DeviceInfo) {s << v.vID << v.pID << v.path << v.description << v.manufacturer; return s;} //! \relatesalso PIByteArray //! \~english Restore operator //! \~russian Оператор извлечения -inline PIByteArray & operator >>(PIByteArray & s, PISerial::DeviceInfo & v) {s >> v.vID >> v.pID >> v.path >> v.description >> v.manufacturer; return s;} +BINARY_STREAM_READ (PISerial::DeviceInfo) {s >> v.vID >> v.pID >> v.path >> v.description >> v.manufacturer; return s;} #endif // PISERIAL_H diff --git a/libs/main/io_devices/pisharedmemory.cpp b/libs/main/io_devices/pisharedmemory.cpp index bf966d98..a2354b09 100644 --- a/libs/main/io_devices/pisharedmemory.cpp +++ b/libs/main/io_devices/pisharedmemory.cpp @@ -170,7 +170,7 @@ bool PISharedMemory::closeDevice() { PIString PISharedMemory::constructFullPathDevice() const { PIString ret; - ret << path() << ":" << dsize; + ret += path() + ":" + PIString::fromNumber(dsize); return ret; } diff --git a/libs/main/io_devices/pispi.cpp b/libs/main/io_devices/pispi.cpp index 4dd441e5..a9c74253 100644 --- a/libs/main/io_devices/pispi.cpp +++ b/libs/main/io_devices/pispi.cpp @@ -157,7 +157,7 @@ int PISPI::writeDevice(const void * data, int max_size) { PIString PISPI::constructFullPathDevice() const { PIString ret; - ret << path() << ":" << int(speed()) << ":" << int(bits()) << ":" << (int)parameters(); + ret += path() + ":" + PIString::fromNumber((int)speed()) + ":" + PIString::fromNumber((int)bits()) + ":" + PIString::fromNumber((int)parameters()); return ret; } diff --git a/libs/main/io_utils/pibasetransfer.h b/libs/main/io_utils/pibasetransfer.h index 2cadd57f..3ae90311 100644 --- a/libs/main/io_utils/pibasetransfer.h +++ b/libs/main/io_utils/pibasetransfer.h @@ -115,8 +115,7 @@ private: }; # pragma pack(pop) - friend PIByteArray & operator >>(PIByteArray & s, PIBaseTransfer::StartRequest & v); - friend PIByteArray & operator <<(PIByteArray & s, const PIBaseTransfer::StartRequest & v); + BINARY_STREAM_FRIEND(PIBaseTransfer::StartRequest); void processData(int id, PIByteArray &data); PIByteArray build_packet(int id); @@ -145,14 +144,14 @@ private: PIString pm_string; }; -inline PIByteArray & operator <<(PIByteArray & s, const PIBaseTransfer::PacketHeader & v) {s << v.sig << v.type << v.session_id << v.id << v.crc; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIBaseTransfer::PacketHeader & v) {s >> v.sig >> v.type >> v.session_id >> v.id >> v.crc; return s;} +BINARY_STREAM_WRITE(PIBaseTransfer::PacketHeader) {s << v.sig << v.type << v.session_id << v.id << v.crc; return s;} +BINARY_STREAM_READ (PIBaseTransfer::PacketHeader) {s >> v.sig >> v.type >> v.session_id >> v.id >> v.crc; return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIBaseTransfer::Part & v) {s << v.id << v.size << v.start; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIBaseTransfer::Part & v) {s >> v.id >> v.size >> v.start; return s;} +BINARY_STREAM_WRITE(PIBaseTransfer::Part) {s << v.id << v.size << v.start; return s;} +BINARY_STREAM_READ (PIBaseTransfer::Part) {s >> v.id >> v.size >> v.start; return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIBaseTransfer::StartRequest & v) {s << v.packets << v.size; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIBaseTransfer::StartRequest & v) {s >> v.packets >> v.size; return s;} +BINARY_STREAM_WRITE(PIBaseTransfer::StartRequest) {s << v.packets << v.size; return s;} +BINARY_STREAM_READ (PIBaseTransfer::StartRequest) {s >> v.packets >> v.size; return s;} inline PICout operator <<(PICout s, const PIBaseTransfer::Part & v) {s.setControl(0, true); s << "Part(\"" << v.id << "\", " << PIString::readableSize(v.start) << " b | " << PIString::readableSize(v.size) << " b)"; s.restoreControl(); return s;} diff --git a/libs/main/io_utils/piconnection.cpp b/libs/main/io_utils/piconnection.cpp index c82d8c7c..14dc1dcd 100644 --- a/libs/main/io_utils/piconnection.cpp +++ b/libs/main/io_utils/piconnection.cpp @@ -19,6 +19,7 @@ #include "piconnection.h" #include "piconfig.h" +#include "piiostream.h" /** \class PIConnection * \brief Complex Input/Output point @@ -259,18 +260,19 @@ bool PIConnection::configure(PIConfig & conf, const PIString & name_) { PIString PIConnection::makeConfig() const { PIString ret; - ret << "[" << name() << "]\n"; + PIIOTextStream ts(&ret); + ts << "[" << name() << "]\n"; PIVector devs(boundedDevices()); int dn(-1); piForeachC (PIIODevice * d, devs) { PIStringList dnl(deviceNames(d)); if (dnl.isEmpty()) dnl << PIString::fromNumber(++dn); piForeachC (PIString & dname, dnl) { - ret << "device." << dname << " = " << d->constructFullPath() << " #s\n"; - ret << "device." << dname << ".bufferSize = " << d->threadedReadBufferSize() << " #n\n"; + ts << "device." << dname << " = " << d->constructFullPath() << " #s\n"; + ts << "device." << dname << ".bufferSize = " << d->threadedReadBufferSize() << " #n\n"; PIDiagnostics * diag = diags_.value(const_cast(d), 0); if (diag != 0) - ret << "device." << dname << ".disconnectTimeout = " << diag->disconnectTimeout() << " #f\n"; + ts << "device." << dname << ".disconnectTimeout = " << diag->disconnectTimeout() << " #f\n"; } } piForeachC (PEPair & f, extractors) { @@ -280,27 +282,27 @@ PIString PIConnection::makeConfig() const { for (int i = 0; i < f.second->devices.size_s(); ++i) { PIString dname = device_names.key(f.second->devices[i]); if (dname.isEmpty()) dname = devPath(f.second->devices[i]); - ret << prefix << ".device." << i << " = " << dname << " #s\n"; + ts << prefix << ".device." << i << " = " << dname << " #s\n"; } PIDiagnostics * diag = diags_.value(f.second->extractor, 0); - ret << prefix << ".bufferSize = " << f.second->extractor->bufferSize() << " #n\n"; + ts << prefix << ".bufferSize = " << f.second->extractor->bufferSize() << " #n\n"; if (diag != 0) - ret << prefix << ".disconnectTimeout = " << diag->disconnectTimeout() << " #f\n"; - ret << prefix << ".splitMode = "; + ts << prefix << ".disconnectTimeout = " << diag->disconnectTimeout() << " #f\n"; + ts << prefix << ".splitMode = "; switch (f.second->extractor->splitMode()) { - case PIPacketExtractor::None: ret << "none"; break; - case PIPacketExtractor::Header: ret << "header"; break; - case PIPacketExtractor::Footer: ret << "footer"; break; - case PIPacketExtractor::HeaderAndFooter: ret << "header & footer"; break; - case PIPacketExtractor::Size: ret << "size"; break; - case PIPacketExtractor::Timeout: ret << "timeout"; break; + case PIPacketExtractor::None: ts << "none"; break; + case PIPacketExtractor::Header: ts << "header"; break; + case PIPacketExtractor::Footer: ts << "footer"; break; + case PIPacketExtractor::HeaderAndFooter: ts << "header & footer"; break; + case PIPacketExtractor::Size: ts << "size"; break; + case PIPacketExtractor::Timeout: ts << "timeout"; break; } - ret << " #s\n"; - ret << prefix << ".payloadSize = " << f.second->extractor->payloadSize() << " #n\n"; - ret << prefix << ".packetSize = " << f.second->extractor->packetSize() << " #n\n"; - ret << prefix << ".timeout = " << f.second->extractor->timeout() << " #f\n"; - ret << prefix << ".header = " << f.second->extractor->header().toString() << " #s\n"; - ret << prefix << ".footer = " << f.second->extractor->footer().toString() << " #s\n"; + ts << " #s\n"; + ts << prefix << ".payloadSize = " << f.second->extractor->payloadSize() << " #n\n"; + ts << prefix << ".packetSize = " << f.second->extractor->packetSize() << " #n\n"; + ts << prefix << ".timeout = " << f.second->extractor->timeout() << " #f\n"; + ts << prefix << ".header = " << f.second->extractor->header().toString() << " #s\n"; + ts << prefix << ".footer = " << f.second->extractor->footer().toString() << " #s\n"; } dn = 0; piForeachC (CPair & c, channels_) { @@ -308,10 +310,10 @@ PIString PIConnection::makeConfig() const { PIString prefix = "channel." + PIString::fromNumber(dn); ++dn; PIString dname = device_names.key(c.first); if (dname.isEmpty()) dname = devPath(c.first); - ret << prefix << ".from = " << dname << " #s\n"; + ts << prefix << ".from = " << dname << " #s\n"; dname = device_names.key(const_cast(d)); if (dname.isEmpty()) dname = devPath(d); - ret << prefix << ".to = " << dname << " #s\n"; + ts << prefix << ".to = " << dname << " #s\n"; } } piForeachC (SPair & s, senders) { @@ -320,15 +322,15 @@ PIString PIConnection::makeConfig() const { for (int i = 0; i < s.second->devices.size_s(); ++i) { PIString dname = device_names.key(s.second->devices[i]); if (dname.isEmpty()) dname = devPath(s.second->devices[i]); - ret << prefix << ".device." << i << " = " << dname << " #s\n"; + ts << prefix << ".device." << i << " = " << dname << " #s\n"; } double int_ = s.second->int_; if (int_ > 0.) - ret << prefix << ".frequency = " << (1000. / int_) << " #f\n"; + ts << prefix << ".frequency = " << (1000. / int_) << " #f\n"; if (!s.second->sdata.isEmpty()) - ret << prefix << ".fixedData = " << s.second->sdata.toString() << " #s\n"; + ts << prefix << ".fixedData = " << s.second->sdata.toString() << " #s\n"; } - ret << "[]\n"; + ts << "[]\n"; return ret; } diff --git a/libs/main/io_utils/pifiletransfer.h b/libs/main/io_utils/pifiletransfer.h index 4638e876..93981c76 100644 --- a/libs/main/io_utils/pifiletransfer.h +++ b/libs/main/io_utils/pifiletransfer.h @@ -111,13 +111,19 @@ private: EVENT_HANDLER1(void, receive_finished, bool, ok); }; -inline PIByteArray & operator <<(PIByteArray & s, const PIFileTransfer::PFTHeader & v) {s << v.raw_sig << v.step << v.session_id; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIFileTransfer::PFTHeader & v) {s >> v.raw_sig >> v.step >> v.session_id; return s;} +BINARY_STREAM_WRITE(PIFileTransfer::PFTHeader) {s << v.raw_sig << v.step << v.session_id; return s;} +BINARY_STREAM_READ (PIFileTransfer::PFTHeader) {s >> v.raw_sig >> v.step >> v.session_id; return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIFileTransfer::PFTFileInfo & v) {s << v.dest_path << v.size << v.time_access << v.time_modification << - v.flags << v.id_user << v.id_group << v.perm_user.raw << v.perm_group.raw << v.perm_other.raw; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIFileTransfer::PFTFileInfo & v) {s >> v.dest_path >> v.size >> v.time_access >> v.time_modification >> - v.flags >> v.id_user >> v.id_group >> v.perm_user.raw >> v.perm_group.raw >> v.perm_other.raw; return s;} +BINARY_STREAM_WRITE(PIFileTransfer::PFTFileInfo) { + s << v.dest_path << v.size << v.time_access << v.time_modification << + v.flags << v.id_user << v.id_group << v.perm_user.raw << v.perm_group.raw << v.perm_other.raw; + return s; +} +BINARY_STREAM_READ (PIFileTransfer::PFTFileInfo) { + s >> v.dest_path >> v.size >> v.time_access >> v.time_modification >> + v.flags >> v.id_user >> v.id_group >> v.perm_user.raw >> v.perm_group.raw >> v.perm_other.raw; + return s; +} inline PICout operator <<(PICout s, const PIFileTransfer::PFTFileInfo & v) { s.setControl(0, true); diff --git a/libs/main/math/pievaluator.h b/libs/main/math/pievaluator.h index 01aadca2..89835ac3 100644 --- a/libs/main/math/pievaluator.h +++ b/libs/main/math/pievaluator.h @@ -96,8 +96,7 @@ namespace PIEvaluatorTypes { class PIP_EXPORT PIEvaluatorContent { friend class PIEvaluator; - friend inline PIByteArray & operator <<(PIByteArray & s, const PIEvaluatorContent & v); - friend inline PIByteArray & operator >>(PIByteArray & s, PIEvaluatorContent & v); + BINARY_STREAM_FRIEND(PIEvaluatorContent); public: PIEvaluatorContent(); ~PIEvaluatorContent() {;} @@ -229,37 +228,16 @@ private: inline bool operator ==(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type == e2.type && e1.num == e2.num);} inline bool operator !=(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type != e2.type || e1.num != e2.num);} -inline PIByteArray & operator <<(PIByteArray & s, const PIEvaluatorTypes::Instruction & v) { - s << PIByteArray::RawData(&v, sizeof(v) - sizeof(v.operators)) << v.operators; - return s; -} -inline PIByteArray & operator >>(PIByteArray & s, PIEvaluatorTypes::Instruction & v) { - s >> PIByteArray::RawData(&v, sizeof(v) - sizeof(v.operators)) >> v.operators; - return s; -} -inline PIByteArray & operator <<(PIByteArray & s, const PIEvaluatorTypes::Element & v) { - s << PIByteArray::RawData(&v, sizeof(v)); - return s; -} -inline PIByteArray & operator >>(PIByteArray & s, PIEvaluatorTypes::Element & v) { - s >> PIByteArray::RawData(&v, sizeof(v)); - return s; -} -inline PIByteArray & operator <<(PIByteArray & s, const PIEvaluatorTypes::Variable & v) { - s << v.name << v.value; - return s; -} -inline PIByteArray & operator >>(PIByteArray & s, PIEvaluatorTypes::Variable & v) { - s >> v.name >> v.value; - return s; -} -inline PIByteArray & operator <<(PIByteArray & s, const PIEvaluatorContent & v) { - s << v.variables << v.cv_count; - return s; -} -inline PIByteArray & operator >>(PIByteArray & s, PIEvaluatorContent & v) { - s >> v.variables >> v.cv_count; - return s; -} +BINARY_STREAM_WRITE(PIEvaluatorTypes::Instruction) {s << PIMemoryBlock(&v, sizeof(v) - sizeof(v.operators)) << v.operators; return s;} +BINARY_STREAM_READ (PIEvaluatorTypes::Instruction) {s >> PIMemoryBlock(&v, sizeof(v) - sizeof(v.operators)) >> v.operators; return s;} + +BINARY_STREAM_WRITE(PIEvaluatorTypes::Element) {s << createMemoryBlock(&v); return s;} +BINARY_STREAM_READ (PIEvaluatorTypes::Element) {s >> createMemoryBlock(&v); return s;} + +BINARY_STREAM_WRITE(PIEvaluatorTypes::Variable) {s << v.name << v.value; return s;} +BINARY_STREAM_READ (PIEvaluatorTypes::Variable) {s >> v.name >> v.value; return s;} + +BINARY_STREAM_WRITE(PIEvaluatorContent) {s << v.variables << v.cv_count; return s;} +BINARY_STREAM_READ (PIEvaluatorContent) {s >> v.variables >> v.cv_count; return s;} #endif // PIEVALUATOR_H diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index fc48ae84..92a48b7d 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -1172,9 +1172,9 @@ inline PICout operator<<(PICout s, const PIMathMatrix &m) { * @param v PIMathMatrix type * @return PIBiteArray serialized PIMathMatrix */ -template -inline PIByteArray &operator<<(PIByteArray &s, const PIMathMatrix &v) { - s << (const PIVector2D &) v; +template +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIMathMatrix & v) { + s << (const PIVector2D &) v; return s; } @@ -1185,9 +1185,9 @@ inline PIByteArray &operator<<(PIByteArray &s, const PIMathMatrix &v) { * @param v PIMathMatrix type * @return PIMathMatrix deserialized from PIByteArray */ -template -inline PIByteArray &operator>>(PIByteArray &s, PIMathMatrix &v) { - s >> (PIVector2D &) v; +template +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIMathMatrix & v) { + s >> (PIVector2D &) v; return s; } diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 5ec4c13d..f6d9281c 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -258,8 +258,10 @@ typedef PIMathVectorT<4u, double> PIMathVectorT4d; template class PIP_EXPORT PIMathVector { typedef PIMathVector _CVector; - template friend PIByteArray & operator <<(PIByteArray & s, const PIMathVector & v); - template friend PIByteArray & operator >>(PIByteArray & s, PIMathVector & v); + template + friend PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIMathVector & v); + template + friend PIBinaryStream

& operator >>(PIBinaryStream

& s, PIMathVector & v); public: PIMathVector(const uint size = 0, const Type & new_value = Type()) {c.resize(size, new_value);} PIMathVector(const PIVector & val) {c = val;} @@ -510,10 +512,10 @@ inline std::ostream & operator <<(std::ostream & s, const PIMathVector & v template inline PICout operator <<(PICout s, const PIMathVector & v) {s << "Vector{"; for (uint i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;} -template -inline PIByteArray & operator <<(PIByteArray & s, const PIMathVector & v) {s << v.c; return s;} -template -inline PIByteArray & operator >>(PIByteArray & s, PIMathVector & v) {s >> v.c; return s;} +template +inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const PIMathVector & v) {s << v.c; return s;} +template +inline PIBinaryStream

& operator >>(PIBinaryStream

& s, PIMathVector & v) {s >> v.c; return s;} typedef PIMathVector PIMathVectori; diff --git a/libs/main/resources/piresources.cpp b/libs/main/resources/piresources.cpp index 035d4d8f..39c0cc73 100644 --- a/libs/main/resources/piresources.cpp +++ b/libs/main/resources/piresources.cpp @@ -43,7 +43,7 @@ void PIResources::dump() { auto fi = si.value()->entries.makeIterator(); while (fi.next()) { PIString s = fi.key() + ": "; - s << (fi.value() ? fi.value()->size_s() : 0) << " b"; + s += PIString::fromNumber(fi.value() ? fi.value()->size_s() : 0) + " b"; piCout << " " << s; } } diff --git a/libs/main/resources/piresourcesstorage.cpp b/libs/main/resources/piresourcesstorage.cpp index 054e900c..ab721895 100644 --- a/libs/main/resources/piresourcesstorage.cpp +++ b/libs/main/resources/piresourcesstorage.cpp @@ -140,30 +140,3 @@ PIResourcesStorage * PIResourcesStorage::instance() { static PIResourcesStorage * ret = new PIResourcesStorage(); return ret; } - - -PIByteArray & operator <<(PIByteArray & b, const PIResourcesStorage::__RCEntry & v) { - PIChunkStream cs; - cs.add(1, v.section).add(2, v.name).add(3, v.file).add(4, v.size) - .add(5, v.offset).add(6, v.flags).add(7, v.alias); - b << cs.data(); - return b; -} - - -PIByteArray & operator >>(PIByteArray & b, PIResourcesStorage::__RCEntry & v) { - PIByteArray ba; b >> ba; - PIChunkStream cs(ba); - while (!cs.atEnd()) { - switch (cs.read()) { - case 1: cs.get(v.section); break; - case 2: cs.get(v.name); break; - case 3: cs.get(v.file); break; - case 4: cs.get(v.size); break; - case 5: cs.get(v.offset); break; - case 6: cs.get(v.flags); break; - case 7: cs.get(v.alias); break; - } - } - return b; -} diff --git a/libs/main/resources/piresourcesstorage.h b/libs/main/resources/piresourcesstorage.h index 3f67aac2..26f0b872 100644 --- a/libs/main/resources/piresourcesstorage.h +++ b/libs/main/resources/piresourcesstorage.h @@ -22,6 +22,7 @@ #include "pistring.h" #include "pimap.h" +#include "pichunkstream.h" class PIResources; @@ -75,8 +76,29 @@ private: }; -PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIResourcesStorage::__RCEntry & v); -PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIResourcesStorage::__RCEntry & v); +BINARY_STREAM_WRITE(PIResourcesStorage::__RCEntry) { + PIChunkStream cs; + cs.add(1, v.section).add(2, v.name).add(3, v.file).add(4, v.size) + .add(5, v.offset).add(6, v.flags).add(7, v.alias); + s << cs.data(); + return s; +} +BINARY_STREAM_READ (PIResourcesStorage::__RCEntry) { + PIByteArray ba; s >> ba; + PIChunkStream cs(ba); + while (!cs.atEnd()) { + switch (cs.read()) { + case 1: cs.get(v.section); break; + case 2: cs.get(v.name); break; + case 3: cs.get(v.file); break; + case 4: cs.get(v.size); break; + case 5: cs.get(v.offset); break; + case 6: cs.get(v.flags); break; + case 7: cs.get(v.alias); break; + } + } + return s; +} #endif // PIRESOURCES_H diff --git a/libs/main/system/piplugin.cpp b/libs/main/system/piplugin.cpp index 638db298..49642971 100644 --- a/libs/main/system/piplugin.cpp +++ b/libs/main/system/piplugin.cpp @@ -468,7 +468,7 @@ PIStringList PIPluginLoader::pluginsDirectories(const PIString & name) { piForeachC (PIString d, dl) { PIString dp = d + "/" + name; if (PIDir::isExists(dp)) - ret << dp; + ret += dp; } return ret; } diff --git a/libs/main/system/pisystemmonitor.cpp b/libs/main/system/pisystemmonitor.cpp index 4912d3dd..11e735f9 100644 --- a/libs/main/system/pisystemmonitor.cpp +++ b/libs/main/system/pisystemmonitor.cpp @@ -457,34 +457,3 @@ void PISystemMonitor::Pool::remove(PISystemMonitor * sm) { PIMutexLocker _ml(mutex); sysmons.remove(sm->pID()); } - - - - -PIByteArray & operator <<(PIByteArray & s, const PISystemMonitor::ProcessStats & v) { - s << PIByteArray::RawData(&v, sizeof(PISystemMonitor::ProcessStatsFixed)) - << v.exec_name << v.state; - return s; -} - - -PIByteArray & operator >>(PIByteArray & s, PISystemMonitor::ProcessStats & v) { - s >> PIByteArray::RawData(&v, sizeof(PISystemMonitor::ProcessStatsFixed)) - >> v.exec_name >> v.state; - v.makeStrings(); - return s; -} - - -PIByteArray & operator <<(PIByteArray & s, const PISystemMonitor::ThreadStats & v) { - s << PIByteArray::RawData(&v, sizeof(PISystemMonitor::ThreadStatsFixed)) - << v.name; - return s; -} - - -PIByteArray & operator >>(PIByteArray & s, PISystemMonitor::ThreadStats & v) { - s >> PIByteArray::RawData(&v, sizeof(PISystemMonitor::ThreadStatsFixed)) - >> v.name; - return s; -} diff --git a/libs/main/system/pisystemmonitor.h b/libs/main/system/pisystemmonitor.h index 50c2a855..e03e379d 100644 --- a/libs/main/system/pisystemmonitor.h +++ b/libs/main/system/pisystemmonitor.h @@ -291,24 +291,37 @@ inline PICout operator <<(PICout s, const PISystemMonitor::ThreadStats & v) { } -//! \relatesalso PIByteArray //! \~english Store operator //! \~russian Оператор сохранения -PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PISystemMonitor::ProcessStats & v); +BINARY_STREAM_WRITE(PISystemMonitor::ProcessStats) { + s << PIMemoryBlock(&v, sizeof(PISystemMonitor::ProcessStatsFixed)) + << v.exec_name << v.state; + return s; +} -//! \relatesalso PIByteArray //! \~english Restore operator //! \~russian Оператор извлечения -PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PISystemMonitor::ProcessStats & v); +BINARY_STREAM_READ (PISystemMonitor::ProcessStats) { + s >> PIMemoryBlock(&v, sizeof(PISystemMonitor::ProcessStatsFixed)) + >> v.exec_name >> v.state; + v.makeStrings(); + return s; +} -//! \relatesalso PIByteArray //! \~english Store operator //! \~russian Оператор сохранения -PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PISystemMonitor::ThreadStats & v); +BINARY_STREAM_WRITE(PISystemMonitor::ThreadStats) { + s << PIMemoryBlock(&v, sizeof(PISystemMonitor::ThreadStatsFixed)) + << v.name; + return s; +} -//! \relatesalso PIByteArray //! \~english Restore operator //! \~russian Оператор извлечения -PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PISystemMonitor::ThreadStats & v); +BINARY_STREAM_READ (PISystemMonitor::ThreadStats) { + s >> PIMemoryBlock(&v, sizeof(PISystemMonitor::ThreadStatsFixed)) + >> v.name; + return s; +} #endif // PISYSTEMMONITOR_H diff --git a/libs/opencl/piopencl.cpp b/libs/opencl/piopencl.cpp index 1558d749..66584ce0 100644 --- a/libs/opencl/piopencl.cpp +++ b/libs/opencl/piopencl.cpp @@ -250,7 +250,7 @@ PIOpenCL::Program * PIOpenCL::Context::createProgram(const PIString & source, co cl_program prog = clCreateProgramWithSource(PRIVATE->context, 1, &csrc, &src_size, &ret); if (ret != 0) { piCout << "[PIOpenCL::Context]" << "clCreateProgramWithSource error" << ret; - if (error) (*error) << "clCreateProgramWithSource error " << ret; + if (error) (*error) += "clCreateProgramWithSource error " + PIString::fromNumber(ret); return 0; } PIString carg = (PIStringList(args) << "-cl-kernel-arg-info").join(' '); @@ -286,7 +286,7 @@ PIOpenCL::Program * PIOpenCL::Context::createProgram(const PIString & source, co cl_kernel kern = clCreateKernel(prog, k.dataAscii(), &ret); if (ret != 0) { piCout << "[PIOpenCL::Context]" << "clCreateKernel" << k << "error" << ret; - if (error) (*error) << "clCreateKernel(\"" << k << "\") error " << ret; + if (error) (*error) += "clCreateKernel(\"" + k + "\") error " + ret; piForeach (void* _k, kerns) clReleaseKernel((cl_kernel)_k); clReleaseProgram(prog); diff --git a/main.cpp b/main.cpp index ca852d33..774c1845 100644 --- a/main.cpp +++ b/main.cpp @@ -1,235 +1,113 @@ #include "pip.h" - -static const char * smallstr = "abcdef"; - -static const char * bigstr = "zsxdcgfhvbncjdbasljcvavcjadnwnxudvbabdhjlavudvdaljsvclavjlasdhvcjhldsavhjldasvfjlhsavdjhavdjhvfjhldasvfjlasvfhjldasvfhjasvfdjdasfhvjldasvhfjlasvfhjlahsvdfhjfvfvdjalsvfjlhasdvfdjsalvfhhjldasvfdjhaldsvfhjdvsfjhlavfjhlavfladlsvfjlasdvfdhjlavfhjldasvfhjlavfhjldvfhjlalsdvfjlhvasfhjlvchjlavchjladvchjldladvschjlladscvjlhdcahjchjllcahjllvcdjladsvhldbcljadsbcjdhlsachjlvdsa hjlcldajc hljdascbhaldb cldhashd l cajlhs chdsbfhlbfdasdffadsfjkbfkjldsabflhbcldhsbhclabchljadsbchldahsbcladsbhclhabhasbclasbdhl"; - -PIKbdListener kbd(0, 0, false); -#include -#include - +#include "pibinarystream.h" +#include "pitextstream.h" +#include "piiostream.h" +//#include "stream.h" +//#include "ccm_.h" +//#include "pisystemmonitor_.h" using namespace PICoutManipulators; +/* +class File: public PIBinaryStream { +public: + PIFile file; + bool binaryStreamAppendImp(const void * d, size_t s) { + file.write(d, s); + return true; + } + bool binaryStreamTakeImp(void * d, size_t s) { + if (file.isEnd()) + return false; + file.read(d, s); + return true; + } +}; + +struct TS { + TS(int v0 = -1, float v1 = -1, PIString v2 = "") {i = v0; f = v1; +// s = v2; + } + int i; + float f; + //PIString s; +}; +PICout operator << (PICout c, const TS & v) {c << '{' << v.i << ", " << v.f << '}'; return c;} + +template inline PIBinaryStream

& operator <<(PIBinaryStream

& s, const TS & v) {s << v.i; return s;} +template inline PIBinaryStream

& operator >>(PIBinaryStream

& s, TS & v) {s >> v.i; return s;} + +*/ int main(int argc, char * argv[]) { - /*PIVariant vi; - piCout << vi; - vi = 1; - piCout << vi << vi.toString(); - vi = "string"; - piCout << vi << vi.toStringList(); - vi = PIStringList("2"); - piCout << vi << vi.toInt();*/ + PIString s = "str 1 2"; + PIIOTextStream ts(&s); + PIString ss; int i, j; + ts >> ss >> i >> j; + piCout << s; + piCout << ss << i << j; + /*KMM::NS::Project p, p1; + p.sms_path = "mypath"; + p.time_0 = "0.05"; + p.time_1 = "10e + 3"; + PIByteArray ba; + ba << p; + piCout << ba; + piCout << p1.sms_path << p1.time_0 << p1.time_1; + ba >> p1; + piCout << p1.sms_path << p1.time_0 << p1.time_1;*/ - /*auto cmp = [](const PIConstChars & c0, const PIConstChars & c1){ - PICout(DefaultControls) << c0 << "==" << c1 << "->" << (c0 != c1); - }; - PIConstChars s; - PICout(DefaultControls | AddQuotes) << s; - s = PIConstChars("str", 2); - PICout(DefaultControls | AddQuotes) << s; - cmp(PIConstChars(), PIConstChars()); - cmp(PIConstChars("str"), PIConstChars()); - cmp(PIConstChars(), PIConstChars("s_tr")); - cmp(PIConstChars("str1"), PIConstChars("str")); - cmp(PIConstChars("str"), PIConstChars("str2")); - cmp(PIConstChars("str"), PIConstChars("sTr")); - cmp(PIConstChars("str"), PIConstChars("str")); - cmp(PIConstChars("1a"), PIConstChars("1b")); - cmp(PIConstChars("1c"), PIConstChars("1b"));*/ + /*PIFile f; + f.open("_test.h", PIIODevice::ReadOnly); + PIIOTextStream ts(&f); + ts.setEncoding(PIIOTextStream::System); + while (!ts.isEnd()) { + PIString v; + ts >> v; + piCout << v; + //piCout << ts.takeCWord(); + }*/ - /*PIMap map; - map[PIConstChars()] = 0; - map[PIConstChars()] = -1; - map["_2"] = 22; - map["1"] = 11; - map["__3"] = 33; - map["10"] = 10; - map[""] = 999; + /*PIByteArray ba; + PIIOByteArray ioba(&ba); + //PIIOBinaryStream stream(&ioba); + PISystemMonitor::ProcessStatsFixed ps; + ba << PIByteArray::RawData("123", 3); + piCout << "s" << ba;*/ + + + + //File f; + //f.file.open("_", PIIODevice::ReadWrite); + //f.file.clear(); + //PIVector vi({TS(1,20), TS(3,40)}); + /*PIVector vi({{'a', 10}, {'b', 20}, {'c', 30}}); + ba << vi; + ba.binaryStreamAppend(&ba, sizeof(ba)); + piCout << "src" << vi; + piCout << "s" << ba.data; + vi.fill(TS()); + vi.clear(); + //f.file.seekToBegin(); + ba >> vi; + piCout << "res" << vi; + piCout << "r" << ba.data;*/ + + /*PIMap map; + map[PIIODevice::ReadOnly] = {"str0", PIString::fromUTF8("русский!")}; + piMSleep(100); + map[PIIODevice::ReadWrite] = {""}; + piMSleep(100); + map[PIIODevice::WriteOnly] = {PIString::fromUTF8("русский!"), "", "1234567890", "qwertyuiop[]"}; piCout << map; - piCout << PIConstChars().toString(); - piCout << PIConstChars("").toString(); - piCout << PIConstChars("str").toString(); - PIConstChars s = " 1 2 \t"; - piCout << "trim:"; - PICout(DefaultControls | AddQuotes) << s.trimmed(); - PICout(DefaultControls | AddQuotes) << s; - PICout(DefaultControls | AddQuotes) << s.isEmpty();*/ + stream << map; + piCout << ba; + map.clear(); - /*piCout << PIIODevice::availablePrefixes(); - auto * d = PIIODevice::createFromFullPath("ser://COM1"); - piCout << ""; - piCout << d; - d->dump(); - d = PIIODevice::createFromFullPath("eth://udp:127.0.0.1:5000"); - piCout << ""; - piCout << d; - d->dump();*/ + ioba.seekToBegin(); + stream >> map; + piCout << map; + piCout << ba;*/ - piCout << ""; - dumpApplication(); - - return 0; - - auto rstr = PIString::fromUTF8("ascii русский!"); - /*for (PIChar c: rstr) - std::wcout << c.toWChar(); - std::wcout << std::endl;*/ - piCout << PIChar::fromUTF8("│"); - piCout << PICoutManipulators::Hex << (int)PIChar::fromUTF8("│").toWChar(); - piCout << rstr; - - /*char rs[] = "й"; - piCout << PIString(PIChar::fromUTF8(rs)); - std::cout << sizeof(rs) << " chars "; - for (int i = 0; i < sizeof(rs); ++i) - std::cout << "'" << (char)(rs[i]) << "' " << (int)(uchar)(rs[i]); - std::cout << std::endl; - CONNECTL(&kbd, keyPressed, ([](PIKbdListener::KeyEvent k, void*){ - ; - piCout << k.key << PIChar((ushort)k.key); - })); - kbd.start(); - WAIT_FOR_EXIT;*/ - //return 0; - static const int cc = 1000000; - PITimeMeasurer tm; - int l = 0; - tm.reset(); - for(int i=0; i & v);\n" -"PIByteArray & operator >>(PIByteArray & s, & v);\n" +"BINARY_STREAM_WRITE();\n" +"BINARY_STREAM_READ ();\n" "Only public variables used. All variables stored/restored\n" "using PIChunkStream. IDs are variable number, starting from 1.\n" "You can override ID with PIMETA(id=). If in class or struct\n" @@ -118,69 +119,69 @@ PIString toCName(const PIString &s) { } -void makeClassInfo(PIFile & f, const PICodeParser::Entity * e) { - f << "\n\t{\n\tClassInfo * ci = new ClassInfo();\n"; - f << "\tci->type = \"" << e->type << "\";\n"; - f << "\tci->name = \"" << e->name << "\";\n"; - f << "\tci->has_name = " << (e->has_name ? "true" : "false") << ";\n"; +void makeClassInfo(PIIOTextStream & ts, const PICodeParser::Entity * e) { + ts << "\n\t{\n\tClassInfo * ci = new ClassInfo();\n"; + ts << "\tci->type = \"" << e->type << "\";\n"; + ts << "\tci->name = \"" << e->name << "\";\n"; + ts << "\tci->has_name = " << (e->has_name ? "true" : "false") << ";\n"; if (!e->meta.isEmpty()) { auto i = e->meta.makeIterator(); while (i.next()) - f << "\tci->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; + ts << "\tci->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; } - f << "\t(*classesInfo)[ci->name] = ci;\n"; + ts << "\t(*classesInfo)[ci->name] = ci;\n"; if (e->parent_scope) { - f << "\tpci = " << "classesInfo->value(\"" << e->parent_scope->name << "\", 0);\n"; - f << "\tif (pci) pci->children_info << ci;\n"; + ts << "\tpci = " << "classesInfo->value(\"" << e->parent_scope->name << "\", 0);\n"; + ts << "\tif (pci) pci->children_info << ci;\n"; } piForeachC (PICodeParser::Entity * p, e->parents) - f << "\tci->parents << \"" << p->name << "\";\n"; - if (!e->members.isEmpty()) f << "\n\tTypeInfo ti;\n"; + ts << "\tci->parents << \"" << p->name << "\";\n"; + if (!e->members.isEmpty()) ts << "\n\tTypeInfo ti;\n"; piForeachC (PICodeParser::Member & m, e->members) { - f << "\tti = TypeInfo(\"" << m.name << "\", \"" << m.type << "\""; + ts << "\tti = TypeInfo(\"" << m.name << "\", \"" << m.type << "\""; if (m.attributes != 0) { bool fir = true; - f << ", "; - if (m.attributes[PICodeParser::Const ]) {if (fir) fir = false; else f << " | "; f << "Const";} - if (m.attributes[PICodeParser::Static ]) {if (fir) fir = false; else f << " | "; f << "Static";} - if (m.attributes[PICodeParser::Mutable ]) {if (fir) fir = false; else f << " | "; f << "Mutable";} - if (m.attributes[PICodeParser::Volatile]) {if (fir) fir = false; else f << " | "; f << "Volatile";} - if (m.attributes[PICodeParser::Inline ]) {if (fir) fir = false; else f << " | "; f << "Inline";} - if (m.attributes[PICodeParser::Virtual ]) {if (fir) fir = false; else f << " | "; f << "Virtual";} + ts << ", "; + if (m.attributes[PICodeParser::Const ]) {if (fir) fir = false; else ts << " | "; ts << "Const";} + if (m.attributes[PICodeParser::Static ]) {if (fir) fir = false; else ts << " | "; ts << "Static";} + if (m.attributes[PICodeParser::Mutable ]) {if (fir) fir = false; else ts << " | "; ts << "Mutable";} + if (m.attributes[PICodeParser::Volatile]) {if (fir) fir = false; else ts << " | "; ts << "Volatile";} + if (m.attributes[PICodeParser::Inline ]) {if (fir) fir = false; else ts << " | "; ts << "Inline";} + if (m.attributes[PICodeParser::Virtual ]) {if (fir) fir = false; else ts << " | "; ts << "Virtual";} } else { if (m.isBitfield()) - f << ", 0"; + ts << ", 0"; } if (m.isBitfield()) - f << ", " << m.bits; - f << ");\n"; + ts << ", " << m.bits; + ts << ");\n"; if (!m.meta.isEmpty()) { for (PICodeParser::MetaMap::const_iterator i = m.meta.begin(); i != m.meta.end(); ++i) - f << "\tti.meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; + ts << "\tti.meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; } - f << "\tci->variables << ti;\n"; + ts << "\tci->variables << ti;\n"; } PIString arg; bool has_fi = false; piForeachC (PICodeParser::Member & m, e->functions) { if (e->name.findCWord(m.name) >= 0) continue; if (!has_fi) - f << "\n\tFunctionInfo * fi;\n"; + ts << "\n\tFunctionInfo * fi;\n"; has_fi = true; - f << "\tci->functions.push_back(FunctionInfo()); fi = &(ci->functions.back());\n"; - f << "\tfi->name = \"" << m.name << "\";"; - f << " fi->return_type = TypeInfo(\"\", \"" << m.type << "\""; + ts << "\tci->functions.push_back(FunctionInfo()); fi = &(ci->functions.back());\n"; + ts << "\tfi->name = \"" << m.name << "\";"; + ts << " fi->return_type = TypeInfo(\"\", \"" << m.type << "\""; if (m.attributes[PICodeParser::Const] || m.attributes[PICodeParser::Static]) { bool fir = true; - f << ", "; - if (m.attributes[PICodeParser::Const ]) {if (fir) fir = false; else f << " | "; f << "Const";} - if (m.attributes[PICodeParser::Static]) {if (fir) fir = false; else f << " | "; f << "Static";} + ts << ", "; + if (m.attributes[PICodeParser::Const ]) {if (fir) fir = false; else ts << " | "; ts << "Const";} + if (m.attributes[PICodeParser::Static]) {if (fir) fir = false; else ts << " | "; ts << "Static";} } - f << ");\n"; + ts << ");\n"; //piCout << "write func" << m.name; piForeachC (PIString & a, m.arguments_full) { //piCout << "write arg" << a; - f << "\tfi->arguments << TypeInfo("; + ts << "\tfi->arguments << TypeInfo("; arg = a; bool con = false; arg.prepend(" "); @@ -189,48 +190,48 @@ void makeClassInfo(PIFile & f, const PICodeParser::Entity * e) { con = true; } arg.trim(); - int ts = 0; - for (ts = arg.size_s() - 1; ts > 0; --ts) - if (!_isCChar(arg[ts]) && !(arg[ts].isDigit())) break; - f << "\"" << arg.takeRight(arg.size_s() - ts - 1).trim() << "\", "; - f << "\"" << arg.trim() << "\""; - if (con) f << ", Const"; - f << ");\n"; + int i = 0; + for (i = arg.size_s() - 1; i > 0; --i) + if (!_isCChar(arg[i]) && !(arg[i].isDigit())) break; + ts << "\"" << arg.takeRight(arg.size_s() - i - 1).trim() << "\", "; + ts << "\"" << arg.trim() << "\""; + if (con) ts << ", Const"; + ts << ");\n"; } if (!m.meta.isEmpty()) { for (PICodeParser::MetaMap::const_iterator i = m.meta.begin(); i != m.meta.end(); ++i) - f << "\tfi->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; + ts << "\tfi->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; } } - f << "\n\t}"; + ts << "\n\t}"; } -void makeEnumInfo(PIFile & f, const PICodeParser::Enum * e) { +void makeEnumInfo(PIIOTextStream & ts, const PICodeParser::Enum * e) { if (e->name.isEmpty()) { - f << "\n\tei = (*enumsInfo)[\"\"];\n"; + ts << "\n\tei = (*enumsInfo)[\"\"];\n"; } else { - f << "\n\tei = new EnumInfo();\n"; - f << "\t(*enumsInfo)[\"" << e->name << "\"] = ei;\n"; - f << "\tei->name = \"" << e->name << "\";\n"; + ts << "\n\tei = new EnumInfo();\n"; + ts << "\t(*enumsInfo)[\"" << e->name << "\"] = ei;\n"; + ts << "\tei->name = \"" << e->name << "\";\n"; if (!e->meta.isEmpty()) { auto i = e->meta.makeIterator(); while (i.next()) - f << "\tei->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; + ts << "\tei->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; } } piForeachC (PICodeParser::EnumeratorInfo & m, e->members) { - f << "\tei->members << PICodeInfo::EnumeratorInfo(\"" << m.name << "\", " << m.value << ");\n"; + ts << "\tei->members << PICodeInfo::EnumeratorInfo(\"" << m.name << "\", " << m.value << ");\n"; if (!m.meta.isEmpty()) { auto i = m.meta.makeIterator(); while (i.next()) - f << "\tei->members.back().meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; + ts << "\tei->members.back().meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; } } } -void writeClassStreamMembersOut(PIFile & f, const PICodeParser::Entity * e, int & cnt, bool simple) { +void writeClassStreamMembersOut(PIIOTextStream & ts, const PICodeParser::Entity * e, int & cnt, bool simple) { PIVector ml; piForeachC (PICodeParser::Member & m, e->members) { if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue; @@ -246,15 +247,15 @@ void writeClassStreamMembersOut(PIFile & f, const PICodeParser::Entity * e, int cnt = m.meta.value("id").toInt(); if (m.dims.isEmpty()) { if (simple) { - f << "\ts << "; + ts << "\ts << "; if (parser.isEnum(m.type)) - f << "(int)"; - f << "v." << m.name << ";\n"; + ts << "(int)"; + ts << "v." << m.name << ";\n"; } else { - f << "\tcs << cs.chunk(" << cnt << ", "; + ts << "\tcs << cs.chunk(" << cnt << ", "; if (parser.isEnum(m.type)) - f << "(int)"; - f << "v." << m.name << ");\n"; + ts << "(int)"; + ts << "v." << m.name << ");\n"; } } else { PIString ptype = m.type.left(m.type.find('[')).trim(); @@ -264,11 +265,11 @@ void writeClassStreamMembersOut(PIFile & f, const PICodeParser::Entity * e, int size += m.dims[i]; } if (simple) { - f << "\tfor (int i = 0; i < " << size << "; ++i)\n"; - f << "\t\ts << ((const " << ptype << " *)(v." << m.name << "))[i];\n"; + ts << "\tfor (int i = 0; i < " << size << "; ++i)\n"; + ts << "\t\ts << ((const " << ptype << " *)(v." << m.name << "))[i];\n"; } else { - f << "\tcs << cs.chunk(" << cnt << ", PIVector<" << ptype << " >((const " << ptype << " *)(v." << m.name << "), "; - f << size << "));\n"; + ts << "\tcs << cs.chunk(" << cnt << ", PIVector<" << ptype << " >((const " << ptype << " *)(v." << m.name << "), "; + ts << size << "));\n"; } } if (is_union) @@ -277,12 +278,12 @@ void writeClassStreamMembersOut(PIFile & f, const PICodeParser::Entity * e, int if (is_union) return; piForeachC (PICodeParser::Entity * ce, e->children) { if (ce->has_name) continue; - writeClassStreamMembersOut(f, ce, cnt, simple); + writeClassStreamMembersOut(ts, ce, cnt, simple); } } -void writeClassStreamMembersIn(PIFile & f, const PICodeParser::Entity * e, int & cnt, bool simple) { +void writeClassStreamMembersIn(PIIOTextStream & ts, const PICodeParser::Entity * e, int & cnt, bool simple) { PIVector ml; piForeachC (PICodeParser::Member & m, e->members) { if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue; @@ -298,15 +299,15 @@ void writeClassStreamMembersIn(PIFile & f, const PICodeParser::Entity * e, int & cnt = m.meta.value("id").toInt(); if (m.dims.isEmpty()) { if (simple) { - f << "\ts >> "; + ts << "\ts >> "; if (parser.isEnum(m.type)) - f << "(int&)"; - f << "v." << m.name << ";\n"; + ts << "(int&)"; + ts << "v." << m.name << ";\n"; } else { - f << "\t\tcase " << cnt << ": cs.get("; + ts << "\t\tcase " << cnt << ": cs.get("; if (parser.isEnum(m.type)) - f << "(int&)"; - f << "v." << m.name << "); break;\n"; + ts << "(int&)"; + ts << "v." << m.name << "); break;\n"; } } else { PIString ptype = m.type.left(m.type.find('[')).trim(); @@ -316,15 +317,15 @@ void writeClassStreamMembersIn(PIFile & f, const PICodeParser::Entity * e, int & size += m.dims[i]; } if (simple) { - f << "\tfor (int i = 0; i < " << size << "; ++i)\n"; - f << "\t\ts >> ((" << ptype << " *)(v." << m.name << "))[i];\n"; + ts << "\tfor (int i = 0; i < " << size << "; ++i)\n"; + ts << "\t\ts >> ((" << ptype << " *)(v." << m.name << "))[i];\n"; } else { - f << "\t\tcase " << cnt << ": {\n\t\t\tPIVector<" << ptype << " > d; cs.get(d);\n"; - f << "\t\t\tint cnt = piMini(d.size_s(), " << size << ");\n"; - f << "\t\t\tfor (int i = 0; i < cnt; ++i)\n"; - f << "\t\t\t\t((" << ptype << " *)(v." << m.name << "))[i] = d[i];\n"; - f << "\t\t\t}\n"; - f << "\t\t\tbreak;\n"; + ts << "\t\tcase " << cnt << ": {\n\t\t\tPIVector<" << ptype << " > d; cs.get(d);\n"; + ts << "\t\t\tint cnt = piMini(d.size_s(), " << size << ");\n"; + ts << "\t\t\tfor (int i = 0; i < cnt; ++i)\n"; + ts << "\t\t\t\t((" << ptype << " *)(v." << m.name << "))[i] = d[i];\n"; + ts << "\t\t\t}\n"; + ts << "\t\t\tbreak;\n"; } } if (is_union) @@ -333,7 +334,7 @@ void writeClassStreamMembersIn(PIFile & f, const PICodeParser::Entity * e, int & if (is_union) return; piForeachC (PICodeParser::Entity * ce, e->children) { if (ce->has_name) continue; - writeClassStreamMembersIn(f, ce, cnt, simple); + writeClassStreamMembersIn(ts, ce, cnt, simple); } } @@ -350,152 +351,128 @@ bool needClassStream(const PICodeParser::Entity * e) { } -void makeClassStream(PIFile & f, const PICodeParser::Entity * e) { +void makeClassStream(PIIOTextStream & ts, const PICodeParser::Entity * e) { if (!needClassStream(e)) return; bool simple = e->meta.contains("simple-stream"); - f << "\nPIByteArray & operator <<(PIByteArray & s, const " << e->name << " & v) {\n"; + ts << "\nBINARY_STREAM_WRITE(" << e->name << ") {\n"; if (!simple) - f << "\tPIChunkStream cs;\n"; + ts << "\tPIChunkStream cs;\n"; int cnt = 0; - writeClassStreamMembersOut(f, e, cnt, simple); + writeClassStreamMembersOut(ts, e, cnt, simple); if (!simple) - f << "\ts << cs.data();\n"; - f << "\treturn s;\n}\n"; - f << "PIByteArray & operator >>(PIByteArray & s, " << e->name << " & v) {\n"; + ts << "\ts << cs.data();\n"; + ts << "\treturn s;\n}\n"; + ts << "BINARY_STREAM_READ (" << e->name << ") {\n"; if (!simple) { - f << "\tif (s.size_s() < 4) return s;\n"; - f << "\tPIByteArray csba; s >> csba;\n"; - f << "\tPIChunkStream cs(csba);\n"; - f << "\twhile (!cs.atEnd()) {\n"; - f << "\t\tswitch (cs.read()) {\n"; + //ts << "\tif (s.size_s() < 4) return s;\n"; + ts << "\tPIByteArray csba; s >> csba;\n"; + ts << "\tPIChunkStream cs(csba);\n"; + ts << "\twhile (!cs.atEnd()) {\n"; + ts << "\t\tswitch (cs.read()) {\n"; } cnt = 0; - writeClassStreamMembersIn(f, e, cnt, simple); + writeClassStreamMembersIn(ts, e, cnt, simple); if (!simple) - f << "\t\t}\n\t}\n"; - f << "\treturn s;\n}\n"; + ts << "\t\t}\n\t}\n"; + ts << "\treturn s;\n}\n"; } -void makeClassStreamHeader(PIFile & f, const PICodeParser::Entity * e) { +void makeGetterType(PIIOTextStream & ts, const PICodeParser::Entity * e) { if (!needClassStream(e)) return; - f << "\n"; - PIStringList sl = e->name.split("::"); - for (int i = 0; i < sl.size_s() - 1; ++i) - f << "namespace " << sl[i] << " {"; - f << e->type << " " << sl.back() << ";"; - if (sl.size_s() > 1) f << PIString('}').repeat(sl.size_s() - 1); - - f << "\nPIByteArray & operator <<(PIByteArray & s, const " << e->name << " & v);"; - f << "\nPIByteArray & operator >>(PIByteArray & s, " << e->name << " & v);\n"; -} - - -void makeGetterType(PIFile & f, const PICodeParser::Entity * e) { - if (!needClassStream(e)) return; - f << "\nconst char * getterType" << toCName(e->name) << "(const char * name) {\n"; - f << "\tif (!name) return \"\";\n"; + ts << "\nconst char * getterType" << toCName(e->name) << "(const char * name) {\n"; + ts << "\tif (!name) return \"\";\n"; piForeachC (PICodeParser::Member & m, e->members) { if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue; - f << "\tif (strcmp(name, \"" << m.name << "\") == 0) return \"" << m.type << "\";\n"; + ts << "\tif (strcmp(name, \"" << m.name << "\") == 0) return \"" << m.type << "\";\n"; } - f << "\treturn \"\";\n}\n"; + ts << "\treturn \"\";\n}\n"; } -void makeGetterValue(PIFile & f, const PICodeParser::Entity * e) { +void makeGetterValue(PIIOTextStream & ts, const PICodeParser::Entity * e) { if (!needClassStream(e)) return; - f << "\nPIByteArray getterValue" << toCName(e->name) << "(const void * p, const char * name) {\n"; - f << "\tPIByteArray ret;\n"; - f << "\tif (!p || !name) return ret;\n"; - f << "\t" << e->name << " * o = (" << e->name << "*)p;\n"; + ts << "\nPIByteArray getterValue" << toCName(e->name) << "(const void * p, const char * name) {\n"; + ts << "\tPIByteArray ret;\n"; + ts << "\tif (!p || !name) return ret;\n"; + ts << "\t" << e->name << " * o = (" << e->name << "*)p;\n"; piForeachC (PICodeParser::Member & m, e->members) { if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue; - f << "\tif (strcmp(name, \"" << m.name << "\") == 0) {serialize(ret, o->" << m.name << "); return ret;}\n"; + ts << "\tif (strcmp(name, \"" << m.name << "\") == 0) {serialize(ret, o->" << m.name << "); return ret;}\n"; } - f << "\treturn ret;\n}\n"; + ts << "\treturn ret;\n}\n"; } -void writeModel(PICodeParser & parser, PICLI & cli, const PIString out, const PIStringList & files, bool meta, bool enums, bool streams, bool texts, bool getters) { +bool writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool meta, bool enums, bool streams, bool texts, bool getters) { PIString defname = "CCM_" + PIString::fromNumber(out.hash()) + "_H"; PISet inc_files; piForeachC (PICodeParser::Entity * e, parser.entities) if (!e->name.startsWith("_PI")) inc_files << e->file; - PIVector incf = inc_files.toVector(); - for (auto & f: files) incf << f; PIString inc_string; + PIVector incf = inc_files.toVector(); piForeachC (PIString & i, incf) { if ((i != parser.mainFile()) && (streams || texts || getters)) - inc_string << "\n#include \"" << i << "\""; + inc_string += "\n#include \"" + i + "\""; } - //piCout << parser.mainFile() << streams << texts << getters; - //piCout << incf; - //piCout << inc_string; PIFile f(out + ".cpp"); f.clear(); - f.open(PIIODevice::WriteOnly); - f << "// Generated by \"PIP Code model generator\" " << PIDateTime::current().toString("dd.MM.yyyy hh:mm:ss\n\n"); - f << "#include \n"; - if (streams || texts) - f << "#include \n"; - f << "#include \"" << out << ".h\""; - f << inc_string << "\n"; - f << "\nusing namespace PICodeInfo;\n\n"; + if (!f.open(PIIODevice::WriteOnly)) { + piCout << "Error: can`t open out file" << f.path(); + return false; + } + PIIOTextStream ts(&f); + ts << "// Generated by \"PIP Code model generator\" " << PIDateTime::current().toString("dd.MM.yyyy hh:mm:ss\n\n"); + ts << "#include \n"; + ts << "#include \"" << out << ".h\"\n"; + ts << "\nusing namespace PICodeInfo;\n"; if (meta || enums || getters) { if (getters) { - f << "\n\n// Getter funtions\n"; + ts << "\n\n// Getter funtions\n"; piForeachC (PICodeParser::Entity * e, parser.entities) { if (!e->has_name || e->name.startsWith("_PI")) continue; - makeGetterType(f, e); - makeGetterValue(f, e); + makeGetterType(ts, e); + makeGetterValue(ts, e); } } - f << "\n\n// Metainformation\n\n__ClassInfo_" << defname << "_Initializer__::__ClassInfo_" << defname << "_Initializer__() {\n"; - f << "\tif (_inited_) return;\n\t_inited_ = true;\n\n"; + ts << "\n\n// Metainformation\n\n__ClassInfo_" << defname << "_Initializer__::__ClassInfo_" << defname << "_Initializer__() {\n"; + ts << "\tif (_inited_) return;\n\t_inited_ = true;\n\n"; if (meta) { - f << "\tClassInfo * pci = new ClassInfo();\n"; - f << "\t(*classesInfo)[\"\"] = pci;\n"; + ts << "\tClassInfo * pci = new ClassInfo();\n"; + ts << "\t(*classesInfo)[\"\"] = pci;\n"; } if (enums && !parser.enums.isEmpty()) { - f << "\tEnumInfo * ei;\n"; - f << "\t(*enumsInfo)[\"\"] = new EnumInfo();\n"; + ts << "\tEnumInfo * ei;\n"; + ts << "\t(*enumsInfo)[\"\"] = new EnumInfo();\n"; } if (meta) { - f << "\n\n// Classes\n"; + ts << "\n\n// Classes\n"; piForeachC (PICodeParser::Entity * e, parser.entities) { if (e->name.startsWith("_PI")) continue; - makeClassInfo(f, e); + makeClassInfo(ts, e); } } if (enums) { - f << "\n// Enums\n"; + ts << "\n// Enums\n"; piForeachC (PICodeParser::Enum & e, parser.enums) - makeEnumInfo(f, &e); + makeEnumInfo(ts, &e); } if (getters) { - f << "\n// Getters\n"; + ts << "\n// Getters\n"; piForeachC (PICodeParser::Entity * e, parser.entities) { if (!needClassStream(e)) continue; if (!e->has_name || e->name.startsWith("_PI")) continue; - f << "\t(*accessValueFunctions)[\"" << e->name << "\"] = getterValue" << toCName(e->name) << ";\n"; - f << "\t(*accessTypeFunctions)[\"" << e->name << "\"] = getterType" << toCName(e->name) << ";\n"; + ts << "\t(*accessValueFunctions)[\"" << e->name << "\"] = getterValue" << toCName(e->name) << ";\n"; + ts << "\t(*accessTypeFunctions)[\"" << e->name << "\"] = getterType" << toCName(e->name) << ";\n"; } } - f << "}\n"; - f << "\n\nbool __ClassInfo_" << defname << "_Initializer__::_inited_ = false;\n"; - } - if (streams) { - f << "\n\n// Stream operators\n"; - piForeachC (PICodeParser::Entity * e, parser.entities) { - if (!e->has_name || e->name.startsWith("_PI")) continue; - makeClassStream(f, e); - } + ts << "}\n"; + ts << "\n\nbool __ClassInfo_" << defname << "_Initializer__::_inited_ = false;\n"; } f.close(); @@ -503,28 +480,36 @@ void writeModel(PICodeParser & parser, PICLI & cli, const PIString out, const PI f.setPath(out + ".h"); f.clear(); - f.open(PIIODevice::WriteOnly); - f << "// Generated by \"PIP Code model generator\" " << PIDateTime::current().toString("dd.MM.yyyy hh:mm:ss\n"); - f << "// Execute command:\n"; + if (!f.open(PIIODevice::WriteOnly)) { + piCout << "Error: can`t open out file" << f.path(); + return false; + } + ts << "// Generated by \"PIP Code model generator\" " << PIDateTime::current().toString("dd.MM.yyyy hh:mm:ss\n"); + ts << "// Execute command:\n"; piForeachC (PIString & _a, cli.rawArguments()) - f << "// \"" << _a << "\"\n"; - f << "\n"; - f << "#ifndef " << defname << "\n#define " << defname << "\n\n"; - f << "#include \n#include "; + ts << "// \"" << _a << "\"\n"; + ts << "\n"; + ts << "#ifndef " << defname << "\n#define " << defname << "\n\n"; + ts << "#include \n#include "; + if (streams || texts) + ts << "\n#include "; + ts << inc_string << "\n"; if (streams) { - f << "\n\n// Stream operators\n"; + ts << "\n\n// Stream operators\n"; piForeachC (PICodeParser::Entity * e, parser.entities) { if (!e->has_name || e->name.startsWith("_PI")) continue; - makeClassStreamHeader(f, e); + makeClassStream(ts, e); } } if (meta || enums || getters) { - f << "\n\n// Metainformation\n\nclass __ClassInfo_" << defname << "_Initializer__ {\n"; - f << "public:\n\t__ClassInfo_" << defname << "_Initializer__();\n\tstatic bool _inited_;\n};\n"; - f << "\nstatic __ClassInfo_" << defname << "_Initializer__ __classinfo_" << defname.toLowerCase() << "_initializer__;\n"; + ts << "\n\n// Metainformation\n\nclass __ClassInfo_" << defname << "_Initializer__ {\n"; + ts << "public:\n\t__ClassInfo_" << defname << "_Initializer__();\n\tstatic bool _inited_;\n};\n"; + ts << "\nstatic __ClassInfo_" << defname << "_Initializer__ __classinfo_" << defname.toLowerCase() << "_initializer__;\n"; } - f << "\n\n#endif // " << defname << "\n"; + ts << "\n\n#endif // " << defname << "\n"; f.close(); + + return true; } @@ -566,12 +551,12 @@ int main(int argc, char * argv[]) { piCout << Cyan << Bold << "Parsing done"; piCout << Cyan << Bold << "Writing code model ..."; bool all = cli.hasArgument("All"); - writeModel(parser, cli, cli.argumentValue("output"), files, - cli.hasArgument("Metainfo") || all, - cli.hasArgument("Enum") || all, - cli.hasArgument("Stream") || all, - cli.hasArgument("Text") || all, - cli.hasArgument("Getter") || all); + if (!writeModel(parser, cli, cli.argumentValue("output"), cli.hasArgument("Metainfo") || all, + cli.hasArgument("Enum") || all, + cli.hasArgument("Stream") || all, + cli.hasArgument("Text") || all, + cli.hasArgument("Getter") || all)) + return 1; piCout << Cyan << Bold << "Writing done"; if (cli.hasArgument("print") || cli.hasArgument("Print")) { bool womain = cli.hasArgument("print"); diff --git a/utils/deploy_tool/main.cpp b/utils/deploy_tool/main.cpp index 0966ba82..87bbee22 100644 --- a/utils/deploy_tool/main.cpp +++ b/utils/deploy_tool/main.cpp @@ -17,9 +17,10 @@ along with this program. If not, see . */ -#include -#include -#include +#include "picli.h" +#include "pidir.h" +#include "piprocess.h" +#include "piiostream.h" #define DELIM "::" @@ -735,7 +736,8 @@ int main(int argc, char * argv[]) { lp = "Resources/lang"; } //piCout << pp; - qtc << "[Paths]\n\tPlugins = " << pp << "\n\tTranslations = " << lp << "\n"; + PIIOTextStream ts(&qtc); + ts << "[Paths]\n\tPlugins = " << pp << "\n\tTranslations = " << lp << "\n"; } } } diff --git a/utils/piterminal/main.cpp b/utils/piterminal/main.cpp index aeae643d..d8283dfc 100644 --- a/utils/piterminal/main.cpp +++ b/utils/piterminal/main.cpp @@ -185,7 +185,7 @@ public: void parseMessage() { if (msg.size_s() < 4) return; PIMutexLocker _ml(con_mutex); - int type; msg >> type; + int type = 0; msg >> type; //piCout << "msg" << type; switch ((PITerminalAuxMessageType)type) { case mtKey: { diff --git a/utils/resources_compiler/generator.cpp b/utils/resources_compiler/generator.cpp index bd112fcf..9f8270ef 100644 --- a/utils/resources_compiler/generator.cpp +++ b/utils/resources_compiler/generator.cpp @@ -1,5 +1,6 @@ #include "generator.h" #include "piresourcesstorage.h" +#include "piiostream.h" PIString initName(const PIString & n) { @@ -25,7 +26,8 @@ bool generate(const PIString & init_name, PIFile & file, const PIVector= 32) { - file << '\n'; + ts << '\n'; rcnt = 0; } - file << int(readed[i]); + ts << int(readed[i]); } } e.size = curfile; curoff += curfile; } - file << "\n};\n"; + ts << "\n};\n"; PIByteArray dba; dba << fv; - file << "\nstatic const uchar " << descname << "[] = {\n"; + ts << "\nstatic const uchar " << descname << "[] = {\n"; first = true; rcnt = -1; for (int i = 0; i < dba.size_s(); ++i) { if (!first) - file << ','; + ts << ','; first = false; if (++rcnt >= 32) { - file << '\n'; + ts << '\n'; rcnt = 0; } - file << int(dba[i]); + ts << int(dba[i]); } - file << "\n};\n"; + ts << "\n};\n"; - file << "\nvoid " << funcname << "() {\n"; - file << "\tPIResourcesStorage::instance()->registerSection(" << dataname << ", " << descname << ", sizeof(" << descname << "));\n"; - file << "}\n"; + ts << "\nvoid " << funcname << "() {\n"; + ts << "\tPIResourcesStorage::instance()->registerSection(" << dataname << ", " << descname << ", sizeof(" << descname << "));\n"; + ts << "}\n"; - file << "\nclass " << icname << " {\n"; - file << "public:\n\t" << icname << "() {\n"; - file << "\t\t" << funcname << "();\n"; - file << "\t}\n"; - file << "} _pirc_" << fcname << "_initializer_;\n"; + ts << "\nclass " << icname << " {\n"; + ts << "public:\n\t" << icname << "() {\n"; + ts << "\t\t" << funcname << "();\n"; + ts << "\t}\n"; + ts << "} _pirc_" << fcname << "_initializer_;\n"; return true; } diff --git a/utils/resources_compiler/main.cpp b/utils/resources_compiler/main.cpp index 22189afb..3dd99f52 100644 --- a/utils/resources_compiler/main.cpp +++ b/utils/resources_compiler/main.cpp @@ -20,6 +20,7 @@ #include "parser.h" #include "generator.h" #include "picli.h" +#include "piiostream.h" using namespace PICoutManipulators; @@ -76,12 +77,16 @@ int main (int argc, char * argv[]) { if (!out_file.isEmpty()) { if (outf.open(out_file, PIIODevice::ReadWrite)) { outf.clear(); - } else piCout << "Error: can`t open out file"; - outf << "// Generated by \"PIP Resources Compiler\" " << PIDateTime::current().toString("dd.MM.yyyy hh:mm:ss\n"); - outf << "// Execute command:\n"; + } else { + piCout << "Error: can`t open out file" << out_file; + return 1; + } + PIIOTextStream ts(&outf); + ts << "// Generated by \"PIP Resources Compiler\" " << PIDateTime::current().toString("dd.MM.yyyy hh:mm:ss\n"); + ts << "// Execute command:\n"; piForeachC (PIString & _a, cli.rawArguments()) - outf << "// \"" << _a << "\"\n"; - outf << "\n"; + ts << "// \"" << _a << "\"\n"; + ts << "\n"; if (!generate(init_name, outf, files)) { piCout << "Error: generate fail"; return 1; diff --git a/utils/system_daemon/daemon.h b/utils/system_daemon/daemon.h index 05a084f3..e469900c 100644 --- a/utils/system_daemon/daemon.h +++ b/utils/system_daemon/daemon.h @@ -195,21 +195,21 @@ private: int offset, cur, height; }; -inline PIByteArray & operator <<(PIByteArray & b, const Daemon::HostInfo & v) { - b << v.execCommand << v.hostname << v.user << v.OS_name +BINARY_STREAM_WRITE(Daemon::HostInfo) { + s << v.execCommand << v.hostname << v.user << v.OS_name << v.OS_version << v.architecture << v.execDateTime << v.processorsCount << v.ID << v.threads << v.priority << v.physical_memsize << v.share_memsize << v.cpu_load_system << v.cpu_load_user; - return b; + return s; } -inline PIByteArray & operator >>(PIByteArray & b, Daemon::HostInfo & v) { - b >> v.execCommand >> v.hostname >> v.user >> v.OS_name +BINARY_STREAM_READ (Daemon::HostInfo) { + s >> v.execCommand >> v.hostname >> v.user >> v.OS_name >> v.OS_version >> v.architecture >> v.execDateTime >> v.processorsCount >> v.ID >> v.threads >> v.priority >> v.physical_memsize >> v.share_memsize >> v.cpu_load_system >> v.cpu_load_user; - return b; + return s; } #endif // DAEMON_H diff --git a/utils/system_daemon/main.cpp b/utils/system_daemon/main.cpp index dc74f203..ba1f2ba8 100755 --- a/utils/system_daemon/main.cpp +++ b/utils/system_daemon/main.cpp @@ -394,7 +394,7 @@ int main(int argc, char * argv[]) { MainMenu * menu = new MainMenu(*daemon); if (sapp) CONNECTU(sapp, messageReceived, menu, messageFromApp); if (cli.hasArgument("silent")) { - PICout::setBufferActive(false); + PICout::setOutputDevices(PICout::StdOut); PIKbdListener ls; ls.enableExitCapture(PIKbdListener::F10); ls.start();