diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f21bfe6..a3f12d30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -537,7 +537,7 @@ if(LIB) #add_custom_target(pip_pch ALL COMMAND ${CMAKE_CXX_COMPILER} -O2 -fPIC -g3 ${CMAKE_INSTALL_PREFIX}/include/pip/pip.h DEPENDS pip SOURCES ${HDRS}) #list(APPEND HDRS "pip.h.gch") file(GLOB CMAKES "*.cmake") -# install(FILES ${CMAKES} DESTINATION ${CMAKE_ROOT}/Modules) + install(FILES ${CMAKES} DESTINATION ${CMAKE_ROOT}/Modules) else() if(NOT PIP_FREERTOS) install(TARGETS ${PIP_LIBS_TARGETS} DESTINATION bin) diff --git a/src_main/core/pichunkstream.cpp b/src_main/core/pichunkstream.cpp index 8216b155..c892be58 100644 --- a/src_main/core/pichunkstream.cpp +++ b/src_main/core/pichunkstream.cpp @@ -44,6 +44,32 @@ void PIChunkStream::setSource(PIByteArray * data) { } +int PIChunkStream::read() { + switch (version_) { + case Version_1: + (*data_) >> last_id >> last_data; + break; + case Version_2: + last_id = readVInt(*data_); + last_data.resize(readVInt(*data_)); + //piCout << last_id << last_data.size(); + (*data_) >> PIByteArray::RawData(last_data.data(), last_data.size_s()); + break; + default: break; + } + return last_id; +} + + +void PIChunkStream::readAll() { + data_map.clear(); + while (!atEnd()) { + read(); + data_map[last_id] = last_data; + } +} + + PIChunkStream::~PIChunkStream() { } @@ -52,4 +78,53 @@ PIChunkStream::~PIChunkStream() { void PIChunkStream::_init() { last_id = -1; last_data.clear(); + if (!data_->isEmpty()) { + uchar v = data_->at(0); + if ((v & 0x80) == 0x80) { + v &= 0x7f; + switch (v) { + case 2: version_ = (uchar)Version_2; data_->pop_front(); break; + default: break; + } + } else + version_ = Version_1; + } +} + + +uint PIChunkStream::readVInt(PIByteArray & s) { + if (s.isEmpty()) return 0; + uchar bytes[4]; s >> bytes[0]; + uchar abc = 0; + for (abc = 0; abc < 3; ++abc) { + uchar mask = (0x80 >> abc); + if ((bytes[0] & mask) == mask) { + //if (s.isEmpty()) return 0; + bytes[0] &= (mask - 1); + s >> bytes[abc + 1]; + } else break; + } + uint ret = 0; + for (int i = 0; i <= abc; ++i) { + ret += (bytes[i] << (8 * ((int)abc - i))); + } + return ret; +} + + +void PIChunkStream::writeVInt(PIByteArray & s, uint val) { + if (val > 0xfffffff) return; + if (val <= 0x7f) { + s << uchar(val); + return; + } + if (val <= 0x3fff) { + s << uchar((val >> 8) | 0x80) << uchar(val & 0xff); + return; + } + if (val <= 0x1fffff) { + s << uchar((val >> 16) | 0xc0) << uchar((val >> 8) & 0xff) << uchar(val & 0xff); + return; + } + s << uchar((val >> 24) | 0xe0) << uchar((val >> 16) & 0xff) << uchar((val >> 8) & 0xff) << uchar(val & 0xff); } diff --git a/src_main/core/pichunkstream.h b/src_main/core/pichunkstream.h index 72ba0bfc..67e3ea54 100644 --- a/src_main/core/pichunkstream.h +++ b/src_main/core/pichunkstream.h @@ -29,12 +29,22 @@ class PIP_EXPORT PIChunkStream { public: - + + //! Version of data packing. Read-access %PIChunkStream automatic detect version, but write-access + //! %PIChunkStream by default write in new version, be careful! + enum Version { + Version_1 /*! First, old version */, + Version_2 /*! Second, more optimized version */ = 2, + }; + //! Contructs stream for read from "data" - PIChunkStream(const PIByteArray & data) {setSource(data);} - + PIChunkStream(const PIByteArray & data): version_(Version_2) {setSource(data);} + //! Contructs stream for read or write to/from "data", or empty stream for write - PIChunkStream(PIByteArray * data = 0) {setSource(data);} + PIChunkStream(PIByteArray * data = 0, Version v = Version_2): version_(v) {setSource(data);} + + //! Contructs empty stream for write with version \"v\" + PIChunkStream(Version v): version_(v) {setSource(0);} ~PIChunkStream(); @@ -58,11 +68,17 @@ public: PIByteArray data() const {return tmp_data;} //! Returns if there is end of stream - bool atEnd() const {return data_->isEmpty();} + bool atEnd() const {return data_->size_s() <= 1;} + + //! Returns stream version + Version version() const {return (Version)version_;} //! Read one chunk from stream and returns its ID - int read() {(*data_) >> last_id >> last_data; return last_id;} + int read(); + + //! Read all chunks from stream + void readAll(); //! Returns last readed chunk ID int getID() {return last_id;} @@ -71,15 +87,29 @@ public: template T getData() const {T ret; PIByteArray s(last_data); s >> ret; return ret;} - //! Place value of last readed chunk into "v" + //! Place value of last readed chunk into \"v\" template void get(T & v) const {v = getData();} - + + //! Place value of chunk with id \"id\" into \"v\". You should call \a readAll() before using this function! + template + const PIChunkStream & get(int id, T & v) const { + PIByteArray ba = data_map.value(id); + if (!ba.isEmpty()) + ba >> v; + return *this; + } + private: void _init(); + static uint readVInt(PIByteArray & s); + static void writeVInt(PIByteArray & s, uint val); + int last_id; + uchar version_; PIByteArray * data_, last_data, tmp_data; + PIMap data_map; template friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk & c); }; @@ -88,7 +118,19 @@ template PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk & c) { PIByteArray ba; ba << c.data; - (*(s.data_)) << c.id << ba; + switch (s.version_) { + case PIChunkStream::Version_1: + (*(s.data_)) << c.id << ba; + break; + case PIChunkStream::Version_2: + if (s.data_->isEmpty()) + (*(s.data_)) << uchar(uchar(s.version_) | 0x80); + PIChunkStream::writeVInt(*(s.data_), c.id); + PIChunkStream::writeVInt(*(s.data_), ba.size()); + s.data_->append(ba); + break; + default: break; + } return s; } diff --git a/src_main/core/picout.cpp b/src_main/core/picout.cpp index 55d6cbbd..60cd2185 100644 --- a/src_main/core/picout.cpp +++ b/src_main/core/picout.cpp @@ -114,25 +114,32 @@ WORD PICout::__Private__::dattr = 0; DWORD PICout::__Private__::smode = 0; #endif -PICout::PICout(PIFlags controls): fo_(true), cc_(false), fc_(false), cnb_(10), co_(controls) { +PICout::PICout(PIFlags controls): fo_(true), cc_(false), fc_(false), act_(true), cnb_(10), co_(controls) { init(); } +PICout::PICout(bool active): fo_(true), cc_(false), fc_(false), act_(active), cnb_(10), co_(PICoutManipulators::DefaultControls) { + if (act_) + init(); +} + + PICout::PICout(PIString * buffer, int id, PIFlags controls): fo_(true), cc_(false), - fc_(false), cnb_(10), co_(controls) { + fc_(false), act_(true), cnb_(10), co_(controls) { init(); buffer_ = buffer; id_ = id; } -PICout::PICout(const PICout & other): fo_(other.fo_), cc_(true), fc_(false), cnb_(other.cnb_), attr_(other.attr_), +PICout::PICout(const PICout & other): fo_(other.fo_), cc_(true), fc_(false), act_(other.act_), cnb_(other.cnb_), attr_(other.attr_), id_(other.id_), buffer_(other.buffer_), co_(other.co_) { } PICout::~PICout() { + if (!act_) return; if (fc_) applyFormat(PICoutManipulators::Default); if (cc_) return; newLine(); @@ -144,6 +151,7 @@ PICout::~PICout() { PICout PICout::operator <<(const PICoutAction v) { + if (!act_) return *this; #ifdef WINDOWS CONSOLE_SCREEN_BUFFER_INFO sbi; COORD coord; @@ -255,39 +263,40 @@ PICout PICout::operator <<(const PICoutAction v) { #define PINUMERICCOUT if (cnb_ == 10) PICOUTTOTARGET(v) else PICOUTTOTARGETS(PIString::fromNumber(v, cnb_)) -PICout PICout::operator <<(const char * v) {if (v[0] == '\0') return *this; space(); quote(); PICOUTTOTARGET(v) quote(); return *this;} +PICout PICout::operator <<(const char * v) {if (!act_) return *this; if (v[0] == '\0') return *this; space(); quote(); PICOUTTOTARGET(v) quote(); return *this;} //PICout PICout::operator <<(const std::string & v) {space(); quote(); if (PICout::isOutputDeviceActive(PICout::Buffer)) PICout::__string__() << StdString2PIString(v); else std::cout << (v); quote(); return *this;} -PICout PICout::operator <<(const bool v) {space(); if (v) PICOUTTOTARGET("true") else PICOUTTOTARGET("false") return *this;} +PICout PICout::operator <<(const bool v) {if (!act_) return *this; space(); if (v) PICOUTTOTARGET("true") else PICOUTTOTARGET("false") return *this;} -PICout PICout::operator <<(const char v) {space(); PICOUTTOTARGET(v) return *this;} +PICout PICout::operator <<(const char v) {if (!act_) return *this; space(); PICOUTTOTARGET(v) return *this;} -PICout PICout::operator <<(const uchar v) {space(); if (cnb_ == 10) PICOUTTOTARGET(ushort(v)) else PICOUTTOTARGETS(PIString::fromNumber(v, cnb_)) return *this;} +PICout PICout::operator <<(const uchar v) {if (!act_) return *this; space(); if (cnb_ == 10) PICOUTTOTARGET(ushort(v)) else PICOUTTOTARGETS(PIString::fromNumber(v, cnb_)) return *this;} -PICout PICout::operator <<(const short int v) {space(); PINUMERICCOUT return *this;} +PICout PICout::operator <<(const short int v) {if (!act_) return *this; space(); PINUMERICCOUT return *this;} -PICout PICout::operator <<(const ushort v) {space(); PINUMERICCOUT return *this;} +PICout PICout::operator <<(const ushort v) {if (!act_) return *this; space(); PINUMERICCOUT return *this;} -PICout PICout::operator <<(const int v) {space(); PINUMERICCOUT return *this;} +PICout PICout::operator <<(const int v) {if (!act_) return *this; space(); PINUMERICCOUT return *this;} -PICout PICout::operator <<(const uint v) {space(); PINUMERICCOUT return *this;} +PICout PICout::operator <<(const uint v) {if (!act_) return *this; space(); PINUMERICCOUT return *this;} -PICout PICout::operator <<(const long v) {space(); PINUMERICCOUT return *this;} +PICout PICout::operator <<(const long v) {if (!act_) return *this; space(); PINUMERICCOUT return *this;} -PICout PICout::operator <<(const ulong v) {space(); PINUMERICCOUT return *this;} +PICout PICout::operator <<(const ulong v) {if (!act_) return *this; space(); PINUMERICCOUT return *this;} -PICout PICout::operator <<(const llong v) {space(); PINUMERICCOUT return *this;} +PICout PICout::operator <<(const llong v) {if (!act_) return *this; space(); PINUMERICCOUT return *this;} -PICout PICout::operator <<(const ullong v) {space(); PINUMERICCOUT return *this;} +PICout PICout::operator <<(const ullong v) {if (!act_) return *this; space(); PINUMERICCOUT return *this;} -PICout PICout::operator <<(const float v) {space(); PICOUTTOTARGET(v) return *this;} +PICout PICout::operator <<(const float v) {if (!act_) return *this; space(); PICOUTTOTARGET(v) return *this;} -PICout PICout::operator <<(const double v) {space(); PICOUTTOTARGET(v) return *this;} +PICout PICout::operator <<(const double v) {if (!act_) return *this; space(); PICOUTTOTARGET(v) return *this;} -PICout PICout::operator <<(const void * v) {space(); PICOUTTOTARGET("0x") PICOUTTOTARGETS(PIString::fromNumber(ullong(v), 16)) return *this;} +PICout PICout::operator <<(const void * v) {if (!act_) return *this; space(); PICOUTTOTARGET("0x") PICOUTTOTARGETS(PIString::fromNumber(ullong(v), 16)) return *this;} PICout PICout::operator <<(const PIObject * v) { + if (!act_) return *this; space(); if (v == 0) PICOUTTOTARGET("PIObject*(0x0)") else { @@ -302,6 +311,7 @@ PICout PICout::operator <<(const PIObject * v) { } PICout PICout::operator <<(const PICoutSpecialChar v) { + if (!act_) return *this; switch (v) { case Null: if (buffer_) { @@ -359,12 +369,14 @@ PICout PICout::operator <<(const PICoutSpecialChar v) { PICout & PICout::saveControl() { + if (!act_) return *this; PRIVATE->cos_.push(co_); return *this; } PICout & PICout::restoreControl() { + if (!act_) return *this; if (!PRIVATE->cos_.isEmpty()) { co_ = PRIVATE->cos_.top(); PRIVATE->cos_.pop(); @@ -377,6 +389,7 @@ PICout & PICout::restoreControl() { #undef PINUMERICCOUT PICout & PICout::space() { + if (!act_) return *this; if (!fo_ && co_[AddSpaces]) { if (buffer_) { (*buffer_) << " "; @@ -390,6 +403,7 @@ PICout & PICout::space() { } PICout & PICout::quote() { + if (!act_) return *this; if (co_[AddQuotes]) { if (buffer_) { (*buffer_) << "\""; @@ -403,6 +417,7 @@ PICout & PICout::quote() { } PICout & PICout::newLine() { + if (!act_) return *this; if (co_[AddNewLine]) { if (buffer_) { (*buffer_) << "\n"; @@ -434,6 +449,7 @@ void PICout::init() { void PICout::applyFormat(PICoutFormat f) { + if (!act_) return; if (buffer_ || !isOutputDeviceActive(StdOut)) return; fc_ = true; #ifdef WINDOWS diff --git a/src_main/core/picout.h b/src_main/core/picout.h index ee260daf..dfac74aa 100644 --- a/src_main/core/picout.h +++ b/src_main/core/picout.h @@ -34,8 +34,8 @@ # define piCoutObj #else -# define piCout if (piDebug) PICout() -# define piCoutObj if (piDebug && debug()) PICout() << "" << (PIStringAscii("[") + className() + " \"" + name() + "\"]") +# define piCout PICout(piDebug) +# define piCoutObj PICout(piDebug && debug()) << (PIStringAscii("[") + className() + PIStringAscii(" \"") + name() + PIStringAscii("\"]")) #endif @@ -117,6 +117,9 @@ public: //! Default constructor with default features (AddSpaces and AddNewLine) explicit PICout(PIFlags controls = PICoutManipulators::DefaultControls); + //! Construct with default features (AddSpaces and AddNewLine), but if \"active\" is false does nothing + PICout(bool active); + //! Construct with external buffer and id "id". See \a Notifier for details PICout(PIString * buffer, int id = 0, PIFlags controls = PICoutManipulators::AddSpaces | PICoutManipulators::AddNewLine); @@ -288,7 +291,7 @@ private: static OutputDevices devs; PRIVATE_DECLARATION - bool fo_, cc_, fc_; + bool fo_, cc_, fc_, act_; int cnb_, attr_, id_; PIString * buffer_; PICoutManipulators::PICoutControls co_; diff --git a/src_main/io_devices/piserial.h b/src_main/io_devices/piserial.h index fe99c669..3385eebf 100755 --- a/src_main/io_devices/piserial.h +++ b/src_main/io_devices/piserial.h @@ -166,7 +166,7 @@ public: //! \returns \b true if sended bytes count = "size" bool send(const void * data, int size); - //! \brief Write to device byte array "data" and wait for data written if "wait" is \b true. + //! \brief Write to device byte array "data" //! \returns \b true if sended bytes count = size of string bool send(const PIByteArray & data) {return send(data.data(), data.size_s());} diff --git a/src_main/piversion.h b/src_main/piversion.h index 180079e6..f97d83e2 100644 --- a/src_main/piversion.h +++ b/src_main/piversion.h @@ -2,8 +2,8 @@ #define PIVERSION_H #define PIP_VERSION_MAJOR 1 -#define PIP_VERSION_MINOR 10 +#define PIP_VERSION_MINOR 11 #define PIP_VERSION_REVISION 0 -#define PIP_VERSION_SUFFIX "_beta" +#define PIP_VERSION_SUFFIX "_alpha" #endif // PIVERSION_H diff --git a/utils/code_model_generator/main.cpp b/utils/code_model_generator/main.cpp index f0dde8b7..916fdda4 100755 --- a/utils/code_model_generator/main.cpp +++ b/utils/code_model_generator/main.cpp @@ -24,13 +24,18 @@ using namespace PICoutManipulators; PICodeParser parser; -void usage() { +void header() { piCout << Bold << "PIP Code model generator"; piCout << Cyan << "Version" << Bold << PIPVersion() << NewLine; piCout << Green << Bold << "Usage:" << Default << "\"pip_cmg [-hqPpsAMEST] -o [-I] [-I] [...] [-D] [-D] [...] [] [] [...]\"" << NewLine; +} + +void usage() { + header(); piCout << Green << Bold << "Details:"; piCout << Bold << "Debug control"; piCout << "-h " << Green << "- display this message and exit"; + piCout << "-H " << Green << "- display details help"; piCout << "-q " << Green << "- quiet, no debug output to console"; piCout << "-P " << Green << "- print list of all parsed files to console before exit"; piCout << "-p " << Green << "- print list of all parsed files without file with \"main\" function to console before exit"; @@ -38,7 +43,7 @@ void usage() { piCout << Bold << "Parsing control"; piCout << "-s " << Green << "- single file (don`t follow includes)"; piCout << "-I " << Green << "- add include dir (e.g. -I.. -I../some_dir -I/usr/include)"; - piCout << "-D " << Green << "- add define to preprocessor, define PICODE is always defined (e.g. -DMY_DEFINE will add MY_DEFINE define)"; + piCout << "-D " << Green << "- add define to preprocessor, macro PICODE is always defined (e.g. -DMY_DEFINE will add MY_DEFINE define)"; piCout << ""; piCout << Bold << "Output control"; piCout << "-A " << Green << "- write all"; @@ -53,6 +58,12 @@ void usage() { piCout << " " << Green << "- add file to code model, all includes of this file will be proceed (e.g. \"main.cpp\")"; } +void help() { + header(); + piCout << Bold << "Metainfo"; + piCout << "-h " << Green << "- display this message and exit"; +} + PIString toCName(const PIString &s) { PIString ret(s.trimmed()); @@ -483,6 +494,7 @@ int main(int argc, char * argv[]) { cli.setOptionalArgumentsCount(-1); cli.addArgument("output", true); cli.addArgument("help"); + cli.addArgument("Help"); cli.addArgument("quiet"); cli.addArgument("All"); cli.addArgument("Metainfo"); @@ -493,6 +505,10 @@ int main(int argc, char * argv[]) { cli.addArgument("print"); cli.addArgument("Print"); cli.addArgument("single"); + if (cli.hasArgument("Help")) { + help(); + return 0; + } if (cli.hasArgument("help") || cli.argumentValue("output").isEmpty() || cli.optionalArguments().isEmpty()) { usage(); return 0; @@ -526,4 +542,4 @@ int main(int argc, char * argv[]) { } } return 0; -}; +} diff --git a/utils/udp_file_transfer/main.cpp b/utils/udp_file_transfer/main.cpp index 084f52f7..6dbbb4b4 100644 --- a/utils/udp_file_transfer/main.cpp +++ b/utils/udp_file_transfer/main.cpp @@ -225,12 +225,12 @@ int main (int argc, char * argv[]) { if (fls.size() > 0) { piCout << "send files" << fls; f.startSend(fls); - PICout(0) << "\n"; + PICout(PICoutControl::AddNone) << "\n"; return 0; } else { piCout << "wait for receiving"; } - PICout(0) << "\n"; + PICout(PICoutControl::AddNone) << "\n"; screen.waitForFinish(); return 0;