diff --git a/.kdev4/pip.kdev4 b/.kdev4/pip.kdev4 index 6f91f02d..00397325 100644 --- a/.kdev4/pip.kdev4 +++ b/.kdev4/pip.kdev4 @@ -2,14 +2,17 @@ BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00p\x00i\x00p) [CMake] -BuildDirs=/home/peri4/pprojects/pip/ +Build Directory Count=1 CMakeDir=/usr/share/cmake/Modules -Current CMake Binary=file:///usr/bin/cmake -CurrentBuildDir=file:///home/peri4/pprojects/pip/ -CurrentBuildType=Debug -CurrentInstallDir= +Current Build Directory Index=0 ProjectRootRelative=./ +[CMake][CMake Build Directory 0] +Build Directory Path=file:///home/peri4/pprojects/pip/ +Build Type= +CMake Binary=file:///usr/bin/cmake +Install Directory=file:///usr/local + [Launch] Launch Configurations=Launch Configuration 0 @@ -24,15 +27,15 @@ Arguments= Dependencies=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00p\x00i\x00p) Dependency Action=Build EnvironmentGroup=default -Executable= +Executable=file:///home/peri4/pprojects/pip/pip_test External Terminal=konsole --noclose --workdir %workdir -e %exe -Project Target=pip,pip_test +Project Target= Use External Terminal=false Working Directory= -isExecutable=false +isExecutable=true [MakeBuilder] -Number Of Jobs=5 +Number Of Jobs=8 [Project] VersionControlSupport=kdevgit diff --git a/CMakeLists.txt b/CMakeLists.txt index 8eab44c7..4b95cf08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ project(pip) +find_package(Qt4) cmake_minimum_required(VERSION 2.6) -include_directories(${CMAKE_CURRENT_SOURCE_DIR} .) +include_directories(${CMAKE_CURRENT_SOURCE_DIR} . ${QT_INCLUDES}) file(GLOB CPPS "pi*.cpp") if (${WIN32}) add_definitions(-Wall -O2) @@ -17,5 +18,5 @@ add_executable(pip_test "main.cpp") if (${WIN32}) target_link_libraries(pip_test pthread ws2_32 pip) else (${WIN32}) - target_link_libraries(pip_test pthread rt pip) + target_link_libraries(pip_test pthread rt pip ${QT_QTCORE_LIBRARY}) endif (${WIN32}) diff --git a/main.cpp b/main.cpp old mode 100644 new mode 100755 index 81a4bd42..c7b55c43 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Test program - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -117,66 +117,67 @@ public: }; - -#pragma pack(push, 1) -struct Data { - ushort header; - int counter; - float f0; - float f1; - ushort checksum; -}; -#pragma pack(pop) - -class Prot: public PIProtocol { -public: - Prot() { - setReceiverDevice("/dev/ttyS0", PISerial::S115200, true); - setReceiverDataHeader(&rec, 2); - setReceiverData(&rec.counter, sizeof(rec) - 2); - setSenderData(&send, sizeof(send)); - setExpectedFrequency(20.f); - setSenderFrequency(20.f); - send.header = 0xAABB; - rec.header = 0xAABB; - start(); - } - - virtual bool validate() { - if (rec.checksum != PIByteArray(&rec, sizeof(rec)-2).checksumCRC16()) return false; - return true; - } - virtual bool aboutSend() { - send.counter++; - send.checksum = PIByteArray(&send, sizeof(send)-2).checksumCRC16(); - return true; - } - - Data send, rec; +struct Packet { + int from; + int to; + float data; + int cs; }; -Prot p; +bool retH(void * d, uchar * src, uchar * rec, int size) { + return (*((int*)rec)) == 1; +}; -void key(char k, void*) { - switch (k) { - case '0': p.setSenderData(&p.send, sizeof(p.send)); break; - case '1': p.setSenderData(&p.send, sizeof(p.send) - 1); break; - case '2': p.send.header = 0xAABB; break; - case '3': p.send.header = 0xACBD; break; - } -} +bool retF(void * d, uchar * data, int size) { + cout << "rec " << size << endl; + return true; +}; -PIConsole c(false, key); int main(int argc, char * argv[]) { - c.enableExitCapture(); - c.addVariable("prot", &p); - if (argc > 1) c.start(); - c.waitForFinish(); - c.stop(); + /*Packet p, mp; + p.from = mp.from = 1; + p.to = mp.to = 2; + PISerial ser("/dev/ttyS0"); + ser.setSpeed(PISerial::S115200); + ser.open(); + ser.setReadIsBlocking(true); + PIPacketExtractor pe(&ser, &mp, 8, 8); + pe.setThreadedReadSlot(retF); + pe.setHeaderCheckSlot(retH); + pe.startThreadedRead(); + ser.write(&p, sizeof(p)); + p.from = 2; + ser.write(&p, sizeof(p)); + msleep(1000); + exit(0);*/ + PICodec codec; + exit(0); +/* + vec my_v; vector stl_v; QVector qt_v; + double el; + PITimer tm; + tm.reset(); + for (uint i = 0; i < 500000; ++i) + my_v.push_back(i); + el = tm.elapsed_m(); + cout << el << endl; + tm.reset(); + for (uint i = 0; i < 500000; ++i) + stl_v.push_back(i); + el = tm.elapsed_m(); + cout << el << endl; + tm.reset(); + for (uint i = 0; i < 500000; ++i) + qt_v.append(i); + el = tm.elapsed_m(); + cout << el << endl; + + exit(0); +*/ bool r_string = true, r_thread = true, r_mutex = true, r_timer = true, r_file = true, r_eval = true, r_event = true; bool succ = true; cout << "== PIP test program ==" << endl; @@ -239,7 +240,7 @@ int main(int argc, char * argv[]) { else cout << "== Fail ==" << endl; cout << endl << "== File test ==" << endl; - PIFile file(" file_test", PIFile::New | PIFile::ReadWrite); + PIFile file(" file_test", PIIODevice::ReadWrite); cout << " file \"" << file.path() << "\" is "; if (!file.isOpened()) cout << "not "; cout << "opened" << endl; diff --git a/pibitarray.h b/pibitarray.h old mode 100644 new mode 100755 index 569557a0..f67bd600 --- a/pibitarray.h +++ b/pibitarray.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Bit array - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,16 +31,16 @@ public: PIBitArray(ulong val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));} PIBitArray(ullong val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));} PIBitArray(uchar * bytes, uint size) {resize(size * 8); memcpy(data(), bytes, size);} - + uint bitSize() const {return size_;} uint byteSize() const {return bytesInBits(size_);} PIBitArray & resize(const uint & size) {size_ = size; data_.resize(bytesInBits(size_)); return *this;} - + PIBitArray & clearBit(const uint & index) {data_[index / 8] &= ~(1 << (index % 8)); return *this;} PIBitArray & setBit(const uint & index) {data_[index / 8] |= (1 << (index % 8)); return *this;} PIBitArray & writeBit(const uint & index, const bool & value) {if (value) setBit(index); else clearBit(index); return *this;} PIBitArray & writeBit(const uint & index, const uchar & value) {return writeBit(index, value > 0);} - + PIBitArray & push_back(const bool & value) {resize(size_ + 1); writeBit(size_ - 1, value); return *this;} PIBitArray & push_back(const uchar & value) {return push_back(value > 0);} PIBitArray & insert(const uint & index, const bool & value) { @@ -71,14 +71,14 @@ public: resize(size_ - 1); return *this;} PIBitArray & append(const PIBitArray & ba) {for (uint i = 0; i < ba.bitSize(); ++i) push_back(ba[i]); return *this;} - + uchar * data() {return data_.data();} uchar toUChar() {if (size_ == 0) return 0; return data_[0];} ushort toUShort() {ushort t = 0; memcpy(&t, data(), piMin(byteSize(), sizeof(t))); return t;} uint toUInt() {uint t = 0; memcpy(&t, data(), piMin(byteSize(), sizeof(t))); return t;} ulong toULong() {ulong t = 0; memcpy(&t, data(), piMin(byteSize(), sizeof(t))); return t;} ullong toULLong() {ullong t = 0; memcpy(&t, data(), piMin(byteSize(), sizeof(t))); return t;} - + bool at(const uint & index) const {return (1 & (data_[index / 8] >> (index % 8))) == 1 ? true : false;} bool operator [](const uint & index) const {return at(index);} void operator +=(const PIBitArray & ba) {append(ba);} @@ -89,13 +89,13 @@ public: void operator =(const uint & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));} void operator =(const ulong & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));} void operator =(const ullong & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));} - + private: uint bytesInBits(const uint & bits) const {return (bits + 7) / 8;} - + PIVector data_; uint size_; - + }; inline std::ostream & operator <<(std::ostream & s, const PIBitArray & ba) {for (uint i = 0; i < ba.bitSize(); ++i) {s << ba[i]; if (i % 8 == 7) s << ' ';} return s;} diff --git a/pibytearray.cpp b/pibytearray.cpp old mode 100644 new mode 100755 index da0bddd5..589a4b7f --- a/pibytearray.cpp +++ b/pibytearray.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Byte array - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -255,7 +255,7 @@ ushort PIByteArray::checksumCRC16() { 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040}; - + int sz = size_s(); uchar nTemp; ushort ret = 0xFFFF; @@ -302,7 +302,7 @@ uint PIByteArray::checksumCRC32() { 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D}; - + int sz = size_s(); uchar nTemp; uint ret = 0xFFFFFFFF; diff --git a/pibytearray.h b/pibytearray.h old mode 100644 new mode 100755 index 120c8d31..3f607c97 --- a/pibytearray.h +++ b/pibytearray.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Byte array - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -75,7 +75,7 @@ class PIByteArray; class PIHuffman { public: PIVector compress(const PIVector & src); - + private: struct node { int freq; @@ -95,27 +95,29 @@ public: PIByteArray() {;} PIByteArray(const uint size) {resize(size);} PIByteArray(const void * data, const uint size) {for (uint i = 0; i < size; ++i) push_back(((uchar * )data)[i]);} - + + PIByteArray resized(int new_size) {PIByteArray tv(*this); tv.resize(new_size); return tv;} + PIByteArray & convertToBase64(); PIByteArray & convertFromBase64(); PIByteArray toBase64() {PIByteArray ba(*this); ba.convertToBase64(); return ba;} PIByteArray fromBase64() {PIByteArray ba(*this); ba.convertFromBase64(); return ba;} - + PIByteArray & compressRLE(uchar threshold = 192); PIByteArray & decompressRLE(uchar threshold = 192); PIByteArray compressedRLE(uchar threshold = 192) {PIByteArray ba(*this); ba.compressedRLE(threshold); return ba;} PIByteArray decompressedRLE(uchar threshold = 192) {PIByteArray ba(*this); ba.decompressedRLE(threshold); return ba;} - + PIByteArray & compressHuffman() {*this = huffman.compress(*this); return *this;} - + uchar checksumPlain8(); uint checksumPlain32(); uchar checksumCRC8(); ushort checksumCRC16(); uint checksumCRC32(); - + void operator =(const PIVector & d) {resize(d.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = d[i];} - + private: union base64HelpStruct { struct { @@ -130,9 +132,9 @@ private: uchar byte2; }; }; - + static PIHuffman huffman; - + }; inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba) {for (uint i = 0; i < ba.size(); ++i) s << ba[i]; return s;} diff --git a/pichar.h b/pichar.h old mode 100644 new mode 100755 index 7521f924..65b5d262 --- a/pichar.h +++ b/pichar.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Unicode char - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/picli.cpp b/picli.cpp old mode 100644 new mode 100755 index d0eb6904..93ba9014 --- a/picli.cpp +++ b/picli.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Command-Line Parser - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -69,7 +69,7 @@ void PICLI::parse() { _args_opt << cra; continue; } - cout << "[PICli] Arguments overflow, \"" << cra << "\" ignored" << endl; + piCout << "[PICli] Arguments overflow, \"" << cra << "\" ignored" << endl; } if (last == 0 ? false : last->has_value) { last->value = cra; diff --git a/picli.h b/picli.h old mode 100644 new mode 100755 index 5108c4ff..6b835e1d --- a/picli.h +++ b/picli.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Command-Line Parser - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/picodec.cpp b/picodec.cpp old mode 100644 new mode 100755 index 4d23ada9..564dfbd5 --- a/picodec.cpp +++ b/picodec.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Text codings coder, based on "iconv" - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/picodec.h b/picodec.h old mode 100644 new mode 100755 index 6fe2e51d..6793428e --- a/picodec.h +++ b/picodec.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Text codings coder, based on "iconv" - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,26 +25,26 @@ class PICodec: private PIProcess { public: - PICodec(): PIProcess() {setGrabOutput(true); tf = PIFile::openTemporary(PIFile::New | PIFile::Read | PIFile::Write); tf.open();} - PICodec(const PIString & from, const PIString & to): PIProcess() {setCodings(from, to); tf = PIFile::openTemporary(PIFile::New | PIFile::Read | PIFile::Write);} + PICodec(): PIProcess() {setGrabOutput(true); tf = PIFile::openTemporary(PIIODevice::ReadWrite); tf.open();} + PICodec(const PIString & from, const PIString & to): PIProcess() {setCodings(from, to); tf = PIFile::openTemporary(PIIODevice::ReadWrite);} ~PICodec() {tf.remove();} - + void setFromCoding(const PIString & from) {c_from = from;} void setToCoding(const PIString & to) {c_to = to;} void setCodings(const PIString & from, const PIString & to) {c_from = from; c_to = to;} - + PIStringList availableCodecs(); PIString encode(PIString & str) {return PIString(exec_iconv(c_from, c_to, str.toByteArray()));} PIString encode(const PIByteArray & str) {return PIString(exec_iconv(c_from, c_to, str));} PIString decode(PIString & str) {return PIString(exec_iconv(c_to, c_from, str.toByteArray()));} PIString decode(const PIByteArray & str) {return PIString(exec_iconv(c_to, c_from, str));} - + private: PIByteArray exec_iconv(const PIString & from, const PIString & to, const PIByteArray & str); - + PIString c_from, c_to; PIFile tf; - + }; #endif // PICODEC_H diff --git a/piconfig.cpp b/piconfig.cpp old mode 100644 new mode 100755 index fbc70f6c..8e6e81b9 --- a/piconfig.cpp +++ b/piconfig.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Config parser - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -171,13 +171,13 @@ bool PIConfig::Entry::entryExists(const Entry * e, const PIString & name) const } -PIConfig::PIConfig(const PIString & path, PIFlags mode): PIFile(path, mode) { +PIConfig::PIConfig(const PIString & path, PIIODevice::DeviceMode mode): PIFile(path, mode) { delim = "."; root.delim = delim; empty.delim = delim; empty._parent = 0; - if (!isOpened() && (mode[Write] || mode[New])) - open(path, Read | Write | New); + if (!isOpened()) + open(path, mode); parse(); } @@ -233,7 +233,7 @@ void PIConfig::addEntry(const PIString & name, const PIString & value, const PIS } else entry = te; } PIConfig::Branch ch = entry->_children; - std::sort(ch.begin(), ch.end(), PIConfig::Entry::compare); + ch.sort(PIConfig::Entry::compare); te = (entry->isLeaf() ? 0 : ch.back()); ce = new Entry(); ce->delim = delim; @@ -249,7 +249,7 @@ void PIConfig::addEntry(const PIString & name, const PIString & value, const PIS if (toRoot) ce->_line = other.size_s() - 1; else { ch = entry->_parent->_children; - std::sort(ch.begin(), ch.end(), PIConfig::Entry::compare); + ch.sort(PIConfig::Entry::compare); ce->_line = ch.back()->_line + 1; } } @@ -369,8 +369,8 @@ void PIConfig::removeEntry(Branch & b, PIConfig::Entry * e) { if (b[i] == e) found = true; } if (!leaf) return; - e->_parent->_children.remove(e); - b.remove(e); + e->_parent->_children.removeOne(e); + b.removeOne(e); delete e; } diff --git a/piconfig.h b/piconfig.h old mode 100644 new mode 100755 index db166e9e..23de194b --- a/piconfig.h +++ b/piconfig.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Config parser - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -54,8 +54,8 @@ class PIConfig: public PIFile friend class Entry; friend class Branch; public: - PIConfig(const PIString & path, PIFlags mode = Read | Write); - ~PIConfig() {piForeach (Entry * i, root._children) deleteEntry(i);} + PIConfig(const PIString & path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite); + ~PIConfig() {piForeach (Entry * i, root._children) deleteEntry(i); close();} class Entry; @@ -127,7 +127,7 @@ public: Entry & setValue(const ulong value) {setValue(ultos(value)); setType("n"); return *this;} Entry & setValue(const float value) {setValue(ftos(value)); setType("f"); return *this;} Entry & setValue(const double value) {setValue(dtos(value)); setType("f"); return *this;} - + Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0); Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0) const {return const_cast(this)->getValue(vname, def, exist);} PICONFIG_GET_VALUE @@ -151,7 +151,8 @@ public: operator PIStringList() {return _value.split("%|%");} private: - static bool compare(const PIConfig::Entry * f, const PIConfig::Entry * s) {return f->_line < s->_line;} + typedef PIConfig::Entry * EntryPtr; + static int compare(const EntryPtr * f, const EntryPtr * s) {return (*f)->_line == (*s)->_line ? 0 : (*f)->_line < (*s)->_line ? -1 : 1;} bool entryExists(const Entry * e, const PIString & name) const; void buildLine() {_all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment;} void clear() {_children.clear(); _name = _value = _type = _comment = _all = PIString(); _line = 0; _parent = 0;} @@ -170,7 +171,7 @@ public: PIString delim; int _line; }; - + Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0); Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0) const {return const_cast(this)->getValue(vname, def, exist);} PICONFIG_GET_VALUE @@ -196,26 +197,26 @@ public: bool isEntryExists(const PIString & name) const {return entryExists(&root, name);} Branch allTree() {Branch b; piForeach (Entry * i, root._children) b << i; return b;} - Branch allLeaves() {Branch b; allLeaves(b, &root); std::sort(b.begin(), b.end(), Entry::compare); return b;} + Branch allLeaves() {Branch b; allLeaves(b, &root); b.sort(Entry::compare); return b;} int entryIndex(const PIString & name); PIString getName(uint number) {return entryByIndex(number)._name;} PIString getValue(uint number) {return entryByIndex(number)._value;} PIChar getType(uint number) {return entryByIndex(number)._type[0];} PIString getComment(uint number) {return entryByIndex(number)._comment;} - + void addEntry(const PIString & name, const PIString & value, const PIString & type = "s", bool write = true); void setName(uint number, const PIString & name, bool write = true); void setValue(uint number, const PIString & value, bool write = true); void setType(uint number, const PIString & type, bool write = true); void setComment(uint number, const PIString & comment, bool write = true); - + void removeEntry(const PIString & name, bool write = true); void removeEntry(uint number, bool write = true); - + void readAll(); void writeAll(); - + const PIString & delimiter() const {return delim;} void setDelimiter(const PIString & d) {delim = d; setEntryDelim(&root, d); readAll();} diff --git a/piconsole.cpp b/piconsole.cpp old mode 100644 new mode 100755 index 746d0ba0..f5d7e19f --- a/piconsole.cpp +++ b/piconsole.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Console output/input - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +26,7 @@ PIConsole::PIConsole(bool startNow, KBFunc slot): PIThread() { ret_func = slot; num_format = 0; cur_tab = width = height = pwidth = pheight = my = 0; + def_align = Nothing; #ifdef WINDOWS ulcoord.X = ulcoord.Y = 0; hOut = GetStdHandle(STD_OUTPUT_HANDLE); @@ -142,7 +143,7 @@ void PIConsole::stop(bool clear) { if (clear) clearScreen(); moveTo(0, my + 4); showCursor(); - couts(fstr(Normal).stdString()); + couts(fstr(Normal)); #ifdef WINDOWS SetConsoleMode(hOut, smode); SetConsoleTextAttribute(hOut, dattr); @@ -243,7 +244,7 @@ PIString PIConsole::fstr(PIFlags f) { #define fprint(x) switch (num_format) {case (3): return printf("%e", x); break; default: return printf("%.5g", x); break;} #define dprint(x) switch (num_format) {case (3): return printf("%le", x); break; default: return printf("%.5lg", x); break;} -inline int PIConsole::couts(const string v) {return printf("%s", v.c_str());} +inline int PIConsole::couts(const PIString & v) {return printf("%s", v.data());} inline int PIConsole::couts(const char * v) {return printf("%s", v);} inline int PIConsole::couts(const bool v) {return (v ? printf("true") : printf("false"));} inline int PIConsole::couts(const char v) {return printf("%c", v);} @@ -289,14 +290,15 @@ void PIConsole::run() { } pwidth = width; pheight = height; - col_cnt = vars().size(); + col_cnt = columns().size(); col_wid = (col_cnt > 0) ? width / col_cnt : width; for (uint i = 0; i < col_cnt; ++i) { + PIVector & cvars(tabs[cur_tab].columns[i].variables); cx = col_wid * i; toUpperLeft(); - if (my < vars()[i].size()) my = vars()[i].size(); + if (my < cvars.size()) my = cvars.size(); j = 0; - piForeachC (Variable & tv, vars()[i]) { + piForeachC (Variable & tv, cvars) { if (j > height - 3) continue; j++; moveRight(cx); @@ -338,7 +340,7 @@ void PIConsole::run() { void PIConsole::fillLabels() { - uint cx, cy, my = 0; + uint cx, cy, my = 0, mx = 0, dx; #ifdef WINDOWS GetConsoleScreenBufferInfo(hOut, &sbi); width = sbi.srWindow.Right - sbi.srWindow.Left; @@ -349,21 +351,31 @@ void PIConsole::fillLabels() { width = ws.ws_col; height = ws.ws_row; #endif - col_cnt = vars().size(); + col_cnt = columns().size(); col_wid = (col_cnt > 0) ? width / col_cnt : width; for (uint i = 0; i < col_cnt; ++i) { + Column & ccol(tabs[cur_tab].columns[i]); + PIVector & cvars(ccol.variables); + if (ccol.alignment != Nothing) { + mx = 0; + piForeachC (Variable & j, cvars) + if (j.type != 0 && j.s != 0) + if (mx < j.name.size()) + mx = j.name.size(); + mx += 2; + } cx = col_wid * i; cy = 1; toUpperLeft(); - for (uint j = 0; j < vars()[i].size(); ++j) { + for (uint j = 0; j < cvars.size(); ++j) { if (int(j) > height - 3) continue; if (my < j) my = j; moveRight(cx); - tv = vars()[i][j]; - vars()[i][j].nx = cx; - vars()[i][j].ny = cy; + Variable & tv(cvars[j]); + cvars[j].nx = cx; + cvars[j].ny = cy; if (tv.name.size() == 0) { - vars()[i][j].offset = 0; + cvars[j].offset = 0; clearLine(); newLine(); cy++; @@ -371,16 +383,33 @@ void PIConsole::fillLabels() { } clearLine(); if (tv.type == 0 && tv.s == 0) { - vars()[i][j].offset = vars()[i][j].name.length(); - vars()[i][j].nx += vars()[i][j].offset; + cvars[j].offset = cvars[j].name.length(); + cvars[j].nx += cvars[j].offset; printLine(tv.name, cx, tv.format); newLine(); cy++; continue; } - vars()[i][j].offset = (tv.name + ": ").length(); - vars()[i][j].nx += vars()[i][j].offset; - printValue(tv.name + ": ", tv.format); + switch (ccol.alignment) { + case Nothing: + cvars[j].offset = (tv.name + ": ").length(); + cvars[j].nx += cvars[j].offset; + printValue(tv.name + ": ", tv.format); + break; + case Left: + cvars[j].offset = mx; + cvars[j].nx += cvars[j].offset; + printValue(tv.name + ": ", tv.format); + break; + case Right: + cvars[j].offset = mx; + cvars[j].nx += cvars[j].offset; + dx = mx - (tv.name + ": ").length(); + moveRight(dx); + printValue(tv.name + ": ", tv.format); + moveLeft(dx); + break; + } newLine(); cy++; } @@ -428,70 +457,70 @@ int PIConsole::bitsValue(void * src, int offset, int count) { return ret; } -#define ADD_VAR_BODY tv.name = name; tv.bitFrom = tv.bitCount = 0; tv.format = format; checkColumn(column); +#define ADD_VAR_BODY tv.name = name; tv.bitFrom = tv.bitCount = 0; tv.format = format; checkColumn(col); -void PIConsole::addString(const PIString & name, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 0; tv.s = 0; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, PIString* ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 0; tv.s = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, bool * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 1; tv.b = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, int * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 2; tv.i = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, long * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 3; tv.l = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, char * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 4; tv.c = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, float * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 5; tv.f = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, double * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 6; tv.d = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, short * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 7; tv.sh = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, uint * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 8; tv.ui = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, ulong * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 9; tv.ul = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, ushort * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 10; tv.ush = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, uchar * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 11; tv.uc = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, llong * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 12; tv.ll = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, ullong * ptr, int column, PIFlags format) { - ADD_VAR_BODY tv.type = 13; tv.ull = ptr; vars()[column - 1].push_back(tv);} -void PIConsole::addVariable(const PIString & name, PIProtocol * ptr, int column, PIFlags format) { - addString("protocol " + name, column, format | PIConsole::Bold); - addVariable("Rec :" + ptr->receiverDeviceName() + " ", ptr->receiverDeviceState_ptr(), column, format); - addVariable("Send:" + ptr->senderDeviceName() + " ", ptr->senderDeviceState_ptr(), column, format); - addVariable("Sended count", ptr->sendCount_ptr(), column, format); - addVariable("Received count", ptr->receiveCount_ptr(), column, format); - addVariable("Invalid count", ptr->wrongCount_ptr(), column, format); - addVariable("Missed count", ptr->missedCount_ptr(), column, format); - addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), column, format); - addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), column, format); - addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), column, format); - addVariable("Receiver history size", ptr->receiverHistorySize_ptr(), column, format); - addVariable("Sender history size", ptr->senderHistorySize_ptr(), column, format); - addVariable("Quality", ptr->quality_ptr(), column, format); +void PIConsole::addString(const PIString & name, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 0; tv.s = 0; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, PIString* ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 0; tv.s = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, bool * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 1; tv.b = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, int * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 2; tv.i = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, long * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 3; tv.l = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, char * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 4; tv.c = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, float * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 5; tv.f = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, double * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 6; tv.d = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, short * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 7; tv.sh = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, uint * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 8; tv.ui = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, ulong * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 9; tv.ul = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, ushort * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 10; tv.ush = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, uchar * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 11; tv.uc = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, llong * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 12; tv.ll = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, ullong * ptr, int col, PIFlags format) { + ADD_VAR_BODY tv.type = 13; tv.ull = ptr; column(col).push_back(tv);} +void PIConsole::addVariable(const PIString & name, PIProtocol * ptr, int col, PIFlags format) { + addString("protocol " + name, col, format | PIConsole::Bold); + addVariable("Rec :" + ptr->receiverDeviceName() + " ", ptr->receiverDeviceState_ptr(), col, format); + addVariable("Send:" + ptr->senderDeviceName() + " ", ptr->senderDeviceState_ptr(), col, format); + addVariable("Sended count", ptr->sendCount_ptr(), col, format); + addVariable("Received count", ptr->receiveCount_ptr(), col, format); + addVariable("Invalid count", ptr->wrongCount_ptr(), col, format); + addVariable("Missed count", ptr->missedCount_ptr(), col, format); + addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), col, format); + addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), col, format); + addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), col, format); + addVariable("Receiver history size", ptr->receiverHistorySize_ptr(), col, format); + addVariable("Sender history size", ptr->senderHistorySize_ptr(), col, format); + addVariable("Quality", ptr->quality_ptr(), col, format); } -void PIConsole::addVariable(const PIString & name, PISystemMonitor * ptr, int column, PIFlags format) { - addString("monitor " + name, column, format | PIConsole::Bold); - addVariable("state ", &(ptr->statistic().state), column, format); - addVariable("threads ", &(ptr->statistic().threads), column, format); - addVariable("priority", &(ptr->statistic().priority), column, format); - addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), column, format); - addVariable("memory shared ", &(ptr->statistic().share_memsize_readable), column, format); - addVariable("cpu load", &(ptr->statistic().cpu_load_system), column, format); +void PIConsole::addVariable(const PIString & name, PISystemMonitor * ptr, int col, PIFlags format) { + addString("monitor " + name, col, format | PIConsole::Bold); + addVariable("state ", &(ptr->statistic().state), col, format); + addVariable("threads ", &(ptr->statistic().threads), col, format); + addVariable("priority", &(ptr->statistic().priority), col, format); + addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), col, format); + addVariable("memory shared ", &(ptr->statistic().share_memsize_readable), col, format); + addVariable("cpu load", &(ptr->statistic().cpu_load_system), col, format); } -void PIConsole::addBitVariable(const PIString & name, void * ptr, int fromBit, int bitCount, int column, PIFlags format) { +void PIConsole::addBitVariable(const PIString & name, void * ptr, int fromBit, int bitCount, int col, PIFlags format) { tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.ptr = ptr; tv.format = format; - checkColumn(column); vars()[column - 1].push_back(tv);} -void PIConsole::addEmptyLine(int column, uint count) { + checkColumn(col); column(col).push_back(tv);} +void PIConsole::addEmptyLine(int col, uint count) { tv.name = ""; tv.type = 0; tv.d = 0; tv.format = Normal; for (uint i = 0; i < count; ++i) { - checkColumn(column); - vars()[column - 1].push_back(tv); + checkColumn(col); + column(col).push_back(tv); } } @@ -521,15 +550,15 @@ PIString PIConsole::getString(int x, int y) { PIString PIConsole::getString(const PIString & name) { - piForeachC (PIVector & i, tabs[cur_tab].variables) - piForeachC (Variable & j, i) + piForeachC (Column & i, tabs[cur_tab].columns) + piForeachC (Variable & j, i.variables) if (j.name == name) return getString(j.nx + 1, j.ny); return PIString(); } -#define PRINT_VAR_BODY couts(fstr(format).stdString()); int ret = couts(value); couts(fstr(PIConsole::Dec).stdString()); return ret; +#define PRINT_VAR_BODY couts(fstr(format)); int ret = couts(value); couts(fstr(PIConsole::Dec)); return ret; inline void PIConsole::printLine(const PIString & value, int dx, PIFlags format) { int i = width - value.length() - dx; @@ -537,15 +566,15 @@ inline void PIConsole::printLine(const PIString & value, int dx, PIFlags= 0) ts = value + PIString(i, ' '); else ts = value.left(value.size() + i); - couts(ts.stdString()); - couts(fstr(Dec).stdString()); + couts(ts); + couts(fstr(Dec)); } inline int PIConsole::printValue(const PIString & value, PIFlags format) { - couts(fstr(format).stdString()); - int ret = couts(value.stdString()); + couts(fstr(format)); + int ret = couts(value); fstr(PIConsole::Dec); return ret; } diff --git a/piconsole.h b/piconsole.h old mode 100644 new mode 100755 index 36397aac..2afd4bbf --- a/piconsole.h +++ b/piconsole.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Console output/input - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -61,6 +61,7 @@ public: Hex = 0x2000000, Oct = 0x4000000, Scientific = 0x8000000}; + enum Alignment {Nothing, Left, Right}; void addString(const PIString & name, int column = 1, PIFlags format = PIConsole::Normal); void addVariable(const PIString & name, PIString * ptr, int column = 1, PIFlags format = PIConsole::Normal); @@ -81,7 +82,7 @@ public: void addVariable(const PIString & name, PISystemMonitor * ptr, int column = 1, PIFlags format = PIConsole::Normal); void addBitVariable(const PIString & name, void * ptr, int fromBit, int bitCount, int column = 1, PIFlags format = PIConsole::Normal); void addEmptyLine(int column = 1, uint count = 1); - + PIString getString(int x, int y); short getShort(int x, int y) {return getString(x, y).toShort();} int getInt(int x, int y) {return getString(x, y).toInt();} @@ -92,7 +93,7 @@ public: int getInt(const PIString & name) {return getString(name).toInt();} float getFloat(const PIString & name) {return getString(name).toFloat();} double getDouble(const PIString & name) {return getString(name).toDouble();} - + uint tabsCount() const {return tabs.size();} PIString currentTab() const {return tabs[cur_tab].name;} int addTab(const PIString & name, char bind_key = 0); @@ -103,13 +104,17 @@ public: bool setTabBindKey(uint index, char bind_key); bool setTabBindKey(const PIString & name, char bind_key); void clearTabs(bool clearScreen = true) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} tabs.clear();} - + void addCustomStatus(const PIString & str) {tabs[cur_tab].status = str;} void clearCustomStatus() {tabs[cur_tab].status.clear();} - + Alignment defaultAlignment() const {return def_align;} + void setDefaultAlignment(Alignment align) {def_align = align;} + void setColumnAlignment(int col, Alignment align) {if (col < 0 || col >= columns().size_s()) return; column(col).alignment = align;} + void setColumnAlignmentToAll(Alignment align) {piForeach (Tab & i, tabs) piForeach (Column & j, i.columns) j.alignment = align; fillLabels();} + EVENT_HANDLER0(PIConsole, void, clearVariables) {clearVariables(true);} - EVENT_HANDLER1(PIConsole, void, clearVariables, bool, clearScreen) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} vars().clear();} - + EVENT_HANDLER1(PIConsole, void, clearVariables, bool, clearScreen) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} columns().clear();} + EVENT_HANDLER0(PIConsole, void, waitForFinish) {WAIT_FOR_EXIT} EVENT_HANDLER0(PIConsole, void, start) {start(false);} EVENT_HANDLER1(PIConsole, void, start, bool, wait) {PIThread::start(40); if (wait) waitForFinish();} @@ -156,7 +161,7 @@ private: void showCursor() {printf("\e[?25h");} #endif void status(); - void checkColumn(uint col) {if (vars().size() < col) {vars().resize(col);}} + void checkColumn(uint col) {while (columns().size() < col) columns().push_back(Column(def_align));} int bitsValue(void * src, int offset, int count); inline void printLine(const PIString & str, int dx = 0, PIFlags format = PIConsole::Normal); inline int printValue(const PIString & str, PIFlags format = PIConsole::Normal); @@ -203,21 +208,33 @@ private: void * ptr; }; void operator =(const Variable & src) {name = src.name; format = src.format; type = src.type; offset = src.offset; - bitFrom = src.bitFrom; bitCount = src.bitCount; c = src.c; nx = src.nx; ny = src.ny;} + bitFrom = src.bitFrom; bitCount = src.bitCount; ptr = src.ptr; nx = src.nx; ny = src.ny;} + }; + + struct Column { + PIVector variables; + Alignment alignment; + Column(Alignment align = PIConsole::Right) { alignment = align;} + uint size() const {return variables.size();} + Variable & operator [](int index) {return variables[index];} + const Variable & operator [](int index) const {return variables[index];} + void push_back(const Variable & v) {variables.push_back(v);} + void operator =(const Column & src) {variables = src.variables; alignment = src.alignment;} }; struct Tab { - PIVector > variables; + PIVector columns; PIString name; PIString status; char key; - Tab() {;} + Tab() {} Tab(PIString n, char k) {name = n; key = k;} ~Tab() {;} }; - PIVector > & vars() {return tabs[cur_tab].variables;} - inline int couts(const string v); + PIVector & columns() {return tabs[cur_tab].columns;} + Column & column(int index) {return tabs[cur_tab].columns[index - 1];} + inline int couts(const PIString & v); inline int couts(const char * v); inline int couts(const bool v); inline int couts(const char v); @@ -246,6 +263,7 @@ private: PIVector tabs; Variable tv; PIKbdListener * listener; + Alignment def_align; KBFunc ret_func; int width, height, pwidth, pheight, ret, col_wid, num_format; uint my; diff --git a/picontainers.h b/picontainers.h old mode 100644 new mode 100755 index 60b3d7f9..635a3540 --- a/picontainers.h +++ b/picontainers.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Generic containers, based on STL - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -124,7 +124,7 @@ template inline _PIForeachC * _PIForeachCastC(_PIForeachBase & c #define piForeachRC piForeachCR -#define piForTimes(c) for(int i = 0; i < c; ++i) +#define piForTimes(c) for(int _i##c = 0; _i##c < c; ++_i##c) template class PIFlags { @@ -133,27 +133,243 @@ public: PIFlags(Enum e): flags(e) {;} PIFlags(const PIFlags & f): flags(f.flags) {;} PIFlags(const int i): flags(i) {;} + PIFlags & setFlag(const PIFlags & f, bool on = true) {if (on) flags |= f.flags; else flags &= ~f.flags; return *this;} + PIFlags & setFlag(const Enum & e, bool on = true) {if (on) flags |= e; else flags &= ~e; return *this;} + PIFlags & setFlag(const int & i, bool on = true) {if (on) flags |= i; else flags &= ~i; return *this;} void operator =(const PIFlags & f) {flags = f.flags;} void operator =(const Enum & e) {flags = e;} void operator =(const int & i) {flags = i;} - void operator |=(const PIFlags & f) {flags = flags | f.flags;} - void operator |=(const Enum & e) {flags = flags | e;} - void operator |=(const int i) {flags = flags | i;} - void operator &=(const PIFlags & f) {flags = flags & f.flags;} - void operator &=(const Enum & e) {flags = flags & e;} - void operator &=(const int i) {flags = flags & i;} + void operator |=(const PIFlags & f) {flags |= f.flags;} + void operator |=(const Enum & e) {flags |= e;} + void operator |=(const int i) {flags |= i;} + void operator &=(const PIFlags & f) {flags &= f.flags;} + void operator &=(const Enum & e) {flags &= e;} + void operator &=(const int i) {flags &= i;} + void operator ^=(const PIFlags & f) {flags ^= f.flags;} + void operator ^=(const Enum & e) {flags ^= e;} + void operator ^=(const int i) {flags ^= i;} PIFlags operator |(PIFlags f) const {PIFlags tf(flags | f.flags); return tf;} PIFlags operator |(Enum e) const {PIFlags tf(flags | e); return tf;} PIFlags operator |(int i) const {PIFlags tf(flags | i); return tf;} PIFlags operator &(PIFlags f) const {PIFlags tf(flags & f.flags); return tf;} PIFlags operator &(Enum e) const {PIFlags tf(flags & e); return tf;} PIFlags operator &(int i) const {PIFlags tf(flags & i); return tf;} + PIFlags operator ^(PIFlags f) const {PIFlags tf(flags ^ f.flags); return tf;} + PIFlags operator ^(Enum e) const {PIFlags tf(flags ^ e); return tf;} + PIFlags operator ^(int i) const {PIFlags tf(flags ^ i); return tf;} bool operator [](Enum e) {return (flags & e) == e;} operator int() const {return flags;} private: int flags; }; +/* +template +class PIVector { +public: + PIVector(uint size = 0, const T & f = T()): data_(0), size_(0), rsize_(0) {resize(size, f);} + PIVector(T * d, uint size): data_(0), size_(0), rsize_(0) {alloc(size); for (uint i = 0; i < size; ++i) data_[i] = d[i];} + ~PIVector() {dealloc();} + typedef T value_type; + + class iterator { + friend class PIVector; + private: + iterator(PIVector * v, int p): parent(v), pos(p) {} + PIVector * parent; + int pos; + public: + iterator(): parent(0) {} + T & operator *() {return (*parent)[pos];} + const T & operator *() const {return (*parent)[pos];} + void operator ++() {++pos;} + void operator ++(int) {++pos;} + void operator --() {--pos;} + void operator --(int) {--pos;} + bool operator ==(const iterator & it) const {return (pos == it.pos);} + bool operator !=(const iterator & it) const {return (pos != it.pos);} + }; + + class const_iterator { + friend class PIVector; + private: + const_iterator(const PIVector * v, int p): parent(v), pos(p) {} + const PIVector * parent; + int pos; + public: + const_iterator(): parent(0) {} + //T & operator *() {return (*parent)[pos];} + const T & operator *() const {return (*parent)[pos];} + void operator ++() {++pos;} + void operator ++(int) {++pos;} + void operator --() {--pos;} + void operator --(int) {--pos;} + bool operator ==(const const_iterator & it) const {return (pos == it.pos);} + bool operator !=(const const_iterator & it) const {return (pos != it.pos);} + }; + + class reverse_iterator { + friend class PIVector; + private: + reverse_iterator(PIVector * v, int p): parent(v), pos(p) {} + PIVector * parent; + int pos; + public: + reverse_iterator(): parent(0) {} + T & operator *() {return (*parent)[pos];} + const T & operator *() const {return (*parent)[pos];} + void operator ++() {--pos;} + void operator ++(int) {--pos;} + void operator --() {++pos;} + void operator --(int) {++pos;} + bool operator ==(const reverse_iterator & it) const {return (pos == it.pos);} + bool operator !=(const reverse_iterator & it) const {return (pos != it.pos);} + }; + + class const_reverse_iterator { + friend class PIVector; + private: + const_reverse_iterator(const PIVector * v, int p): parent(v), pos(p) {} + const PIVector * parent; + int pos; + public: + const_reverse_iterator(): parent(0) {} + //T & operator *() {return (*parent)[pos];} + const T & operator *() const {return (*parent)[pos];} + void operator ++() {--pos;} + void operator ++(int) {--pos;} + void operator --() {++pos;} + void operator --(int) {++pos;} + bool operator ==(const const_reverse_iterator & it) const {return (pos == it.pos);} + bool operator !=(const const_reverse_iterator & it) const {return (pos != it.pos);} + }; + + iterator begin() {return iterator(this, 0);} + iterator end() {return iterator(this, size_);} + const_iterator begin() const {return const_iterator(this, 0);} + const_iterator end() const {return const_iterator(this, size_);} + reverse_iterator rbegin() {return reverse_iterator(this, size_ - 1);} + reverse_iterator rend() {return reverse_iterator(this, -1);} + const_reverse_iterator rbegin() const {return const_reverse_iterator(this, size_ - 1);} + const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);} + + uint size() const {return size_;} + int size_s() const {return size_;} + int length() const {return size_;} + bool isEmpty() const {return (size_ == 0);} + + T & operator [](int index) {return data_[index];} + T & at(uint index) {return data_[index];} + const T & operator [](int index) const {return data_[index];} + const T & at(uint index) const {return data_[index];} + T & back() {return data_[size_ - 1];} + const T & back() const {return data_[size_ - 1];} + T & front() {return data_[0];} + const T & front() const {return data_[0];} + + bool operator ==(const PIVector & t) const {if (size_ != t.size_) return false; for (uint i = 0; i < size_; ++i) if (t[i] != data_[i]) return false; return true;} + bool operator !=(const PIVector & t) const {if (size_ != t.size_) return true; for (uint i = 0; i < size_; ++i) if (t[i] != data_[i]) return true; return false;} + bool contain(const T & v) const {for (uint i = 0; i < size_; ++i) if (v == data_[i]) return true; return false;} + + T * data(int index = 0) {return &(data_[index]);} + const T * data(int index = 0) const {return &(data_[index]);} + PIVector & clear() {resize(0); return *this;} + PIVector & fill(const T & f = T()) { + if (sizeof(T) == 1) memset(data_, f, size_); + else for (uint i = 0; i < size_; ++i) memcpy(&(data_[i]), &f, sizeof(T)); + return *this; + } + PIVector & assign(const T & f = T()) {return fill(f);} + PIVector & resize(uint new_size, const T & f = T()) { + if (new_size < size_) { + size_ = new_size; + return *this; + } + if (new_size > size_) { + os = size_; + alloc(new_size); + uint ds = size_ - os; + //if (sizeof(T) == 1) memset(&(data_[os]), f, ds); + for (uint i = 0; i < ds; ++i) data_[os + i] = f; + return *this; + } + return *this; + } + + PIVector & insert(int index, const T & v = T()) { + push_back(v); + if (index >= int(size_ - 1)) return *this; + os = size_ - index; + T * pd = new T[os * sizeof(T)]; + memcpy(pd, &(data_[index]), os * sizeof(T)); + memcpy(&(data_[index + 1]), pd, os * sizeof(T)); + delete[] pd; + data_[index] = v; + return *this; + } + + PIVector & remove(int index, int count = 1) { + if (index + count >= int(size_)) { + resize(index); + return *this; + } + os = size_ - index - count; + T * pd = new T[os * sizeof(T)]; + memcpy(pd, &(data_[index + count]), os * sizeof(T)); + memcpy(&(data_[index]), pd, os * sizeof(T)); + delete[] pd; + resize(size_ - count); + return *this; + } + + typedef int (*CompareFunc)(const T * , const T * ); + static int compare_func(const T * t0, const T * t1) {return (*t0) == (*t1) ? 0 : ((*t0) < (*t1) ? -1 : 1);} + PIVector & sort(CompareFunc compare = compare_func) {qsort(data_, size_, sizeof(T), (int(*)(const void * , const void * ))compare); return *this;} + + PIVector & removeOne(const T & v) {for (uint i = 0; i < size_; ++i) if (data_[i] == v) {remove(i); return *this;} return *this;} + PIVector & removeAll(const T & v) {for (uint i = 0; i < size_; ++i) if (data_[i] == v) {remove(i); --i;} return *this;} + + PIVector & push_back(const T & v) {alloc(size_ + 1); data_[size_ - 1] = v; return *this;} + PIVector & append(const T & v) {return push_back(v);} + PIVector & operator <<(const T & v) {return push_back(v);} + + PIVector & push_front(const T & v) {insert(0, v); return *this;} + PIVector & prepend(const T & v) {return push_front(v);} + //PIVector & operator <<(const T & v) {return push_back(v);} + + PIVector & pop_back() {if (size_ == 0) return *this; resize(size_ - 1); return *this;} + PIVector & pop_front() {if (size_ == 0) return *this; remove(0); return *this;} + +private: + uint asize(uint s) {if (s == 0) return 0; if (rsize_ + rsize_ >= s && rsize_ < s) return rsize_ + rsize_; uint t = 0, s_ = s - 1; while (s_ >> t) ++t; return (1 << t);} + void dealloc() {if (data_ != 0) delete[] data_; data_ = 0;} + void alloc(uint new_size) { + if (new_size <= rsize_) { + size_ = new_size; + return; + } + os = size_; + size_ = new_size; + uint as = asize(new_size); + if (as == rsize_) return; + T * pd = 0; + if (os > 0) { + pd = new T[os * sizeof(T)]; + memcpy(pd, data_, os * sizeof(T)); + } + rsize_ = as; + dealloc(); + data_ = new T[rsize_ * sizeof(T)]; + if (os > 0) { + memcpy(data_, pd, size_ * sizeof(T)); + delete[] pd; + } + } + + T * data_; + uint size_, rsize_, os; +}; +*/ template > class PIVector: public vector { typedef PIVector _CVector; @@ -172,15 +388,20 @@ public: Type * data(uint index = 0) {return &(*this)[index];} int size_s() const {return static_cast(_stlc::size());} bool isEmpty() const {return _stlc::empty();} + typedef int (*CompareFunc)(const Type * , const Type * ); + static int compare_func(const Type * t0, const Type * t1) {return (*t0) == (*t1) ? 0 : ((*t0) < (*t1) ? -1 : 1);} + _CVector & sort(CompareFunc compare = compare_func) {qsort(&at(0), _stlc::size(), sizeof(Type), (int(*)(const void * , const void * ))compare); return *this;} _CVector & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;} _CVector & pop_front() {_stlc::erase(_stlc::begin()); return *this;} _CVector & push_front(const Type & t) {_stlc::insert(_stlc::begin(), t); return *this;} _CVector & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;} _CVector & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;} - _CVector & remove(const Type & t) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) {_stlc::erase(i); --i;} return *this;} + //_CVector & remove(const Type & t) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) {_stlc::erase(i); --i;} return *this;} + _CVector & removeOne(const Type & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); return *this;} return *this;} + _CVector & removeAll(const Type & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); --i;} return *this;} _CVector & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;} _CVector & operator <<(const Type & t) {_stlc::push_back(t); return *this;} - _CVector & operator <<(const _CVector & t) {for (typename _stlc::iterator i = t.begin(); i != t.end(); i++) _stlc::push_back(*i); return *this;} + _CVector & operator <<(const _CVector & t) {for (typename _stlc::const_iterator i = t.begin(); i != t.end(); i++) _stlc::push_back(*i); return *this;} bool operator ==(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return false; return true;} bool operator !=(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return true; return false;} bool contain(const Type & v) const {for (uint i = 0; i < _stlc::size(); ++i) if (v == at(i)) return true; return false;} @@ -212,7 +433,7 @@ public: _CList & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;} _CList & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;} _CList & operator <<(const Type & t) {_stlc::push_back(t); return *this;} - PIVector toVector() {PIVector v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;} + PIVector toVector() {PIVector v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;} }; template, typename Allocator = std::allocator > @@ -232,7 +453,7 @@ public: _CSet & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;} _CSet & operator <<(const Type & t) {_stlc::insert(t); return *this;} bool operator [](const Type & t) {return _stlc::find(t);} - PIVector toVector() {PIVector v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;} + PIVector toVector() {PIVector v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;} }; template @@ -265,7 +486,7 @@ public: int size_s() const {return static_cast(_stlc::size());} bool isEmpty() const {return _stlc::empty();} _CDeque & operator <<(const Type & t) {_CDeque::push_back(t); return *this;} - PIVector toVector() {PIVector v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;} + PIVector toVector() {PIVector v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;} }; template diff --git a/pidir.cpp b/pidir.cpp old mode 100644 new mode 100755 index d007ecca..bfde7fcb --- a/pidir.cpp +++ b/pidir.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Directory - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,7 +35,7 @@ PIDir::PIDir() { PIDir::PIDir(const PIString & dir) { - path_ = dir.stdString(); + path_ = dir; dir_ = 0; open(); } diff --git a/pidir.h b/pidir.h old mode 100644 new mode 100755 index 702f220c..c6fd7d97 --- a/pidir.h +++ b/pidir.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Directory - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/piethernet.cpp b/piethernet.cpp old mode 100644 new mode 100755 index 5b5ae6ce..1fd93494 --- a/piethernet.cpp +++ b/piethernet.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Ethernet, UDP - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,182 +20,217 @@ #include "piethernet.h" -PIEthernet::PIEthernet(PIString ip, int port, void * data_, EthernetFunc slot): PIThread() { +PIEthernet::PIEthernet(void * data, ReadRetFunc slot): PIIODevice("", ReadWrite) { piMonitor.ethernets++; setPriority(piHigh); - data = data_; - ip_ = ip_s = ip; - port_ = port_s = port; - sock = sock_s = -1; - ret_func = slot; - tries = 0; - //buffer_ = new char[BUFFER_SIZE]; + type_ = UDP; + ret_data_ = data; + ip_ = ip_s = ""; + port_ = port_s = 0; + sock = -1; + ret_func_ = slot; + connected_ = false; + server_thread_.setData(this); + setThreadedReadBufferSize(65536); +#ifdef WINDOWS + WSADATA wsaData; + WSAStartup(MAKEWORD(2, 2), &wsaData); +#endif + init(); +} + + +PIEthernet::PIEthernet(PIEthernet::Type type, void * data, ReadRetFunc slot): PIIODevice("", ReadWrite) { + piMonitor.ethernets++; + setPriority(piHigh); + type_ = type; + ret_data_ = data; + ip_ = ip_s = ""; + port_ = port_s = 0; + sock = -1; + ret_func_ = slot; + connected_ = false; + server_thread_.setData(this); + setThreadedReadBufferSize(65536); +#ifdef WINDOWS + WSADATA wsaData; + WSAStartup(MAKEWORD(2, 2), &wsaData); +#endif + init(); +} + + +PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) { + piMonitor.ethernets++; + setPriority(piHigh); + type_ = TCP_Client; + parseAddress(ip_port, &ip_s, &port_s); + sock = sock_; + server_thread_.setData(this); + init_ = opened_ = connected_ = true; + setThreadedReadBufferSize(65536); #ifdef WINDOWS WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); #endif - initSend(); } PIEthernet::~PIEthernet() { piMonitor.ethernets--; - terminate(); + if (server_thread_.isRunning()) server_thread_.terminate(); + closeSocket(sock); #ifdef WINDOWS WSACleanup(); #endif - if (sock != -1) { - shutdown(sock, SHUT_RDWR); -#ifdef WINDOWS - closesocket(sock); -#else - close(sock); -#endif - sock = -1; - } - if (sock_s != -1) { - shutdown(sock_s, SHUT_RDWR); -#ifdef WINDOWS - closesocket(sock_s); -#else - close(sock_s); -#endif - sock_s = -1; - } //if (buffer_ != 0) delete buffer_; //buffer_ = 0; } -void PIEthernet::terminate() { - if (!receiverInitialized()) return; - if (isRunning()) { - stop(); - PIThread::terminate(); - } - tries = 0; - /*if (sock != -1) { - shutdown(sock, SHUT_RDWR); - shutdown(sock, SHUT_RDWR); - close(sock); - sock = -1; - } - if (sock_s != -1) { - shutdown(sock_s, SHUT_RDWR); - close(sock_s); - sock_s = -1; - }*/ -} - - -void PIEthernet::begin() { - if (!init()) stop(); -} - - -void PIEthernet::run() { -/*#ifdef WINDOWS - int addr_len = sizeof(sockaddr); -#else - socklen_t addr_len = sizeof(sockaddr_storage); -#endif*/ - //cout << "[PIEthernet] reading from " << &addr_ << endl; - readed = recv(sock, buffer_, BUFFER_SIZE, 0/*, (sockaddr * )&addr_, &addr_len*/); - //cout << WSAGetLastError() << endl; - if (readed < 0) { - cout << "[PIEthernet] Error while reading, " << errorString() << endl; - //stop(); - //init(); - return; - } - if (ret_func != 0) ret_func(data, buffer_, readed); -} - - -void PIEthernet::end() { - terminate(); -} - - bool PIEthernet::init() { + //cout << "init " << type_ << endl; + closeSocket(sock); + int st = 0, so = 1; + if (type_ == UDP) st = SOCK_DGRAM; + if (type_ == TCP_Client || type_ == TCP_Server) st = SOCK_STREAM; + sock = socket(PF_INET, st, 0); + if (sock == -1) { + piCout << "[PIEthernet] Cant`t create socket, " << errorString() << endl; + return false; + } + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &so, sizeof(so)); + //fcntl(sock, F_SETFL, 0/*O_NONBLOCK*/); + return true; +} + + +void PIEthernet::parseAddress(const PIString & ipp, PIString * ip, int * port) { + if (ip != 0) *ip = ipp.left(ipp.find(":")); + if (port != 0) *port = ipp.right(ipp.length() - ipp.find(":") - 1).toInt(); +} + + +bool PIEthernet::openDevice() { + if (connected_) return true; + if (sock == -1) init(); + if (sock == -1) return false; + //cout << " bind to " << path_ << " ..." <sock, (sockaddr * )&client_addr, &slen); + if (s == -1) { + piCout << "[PIEthernet] Cant`t accept new connection, " << errorString() << endl; + return; + } + PIString ip(inet_ntoa(client_addr.sin_addr)); + ip += ":" + PIString::fromNumber(htons(client_addr.sin_port)); + ce->clients_ << new PIEthernet(s, ip); + cout << "connected " << ip << endl; + //char d[256]; + //cout << " recv " << recv(s, d, 256, 0) << endl; + //cout << recv(ce->clients_.back()->sock, d, 256, 0) << endl; + } diff --git a/piethernet.h b/piethernet.h old mode 100644 new mode 100755 index cb24377b..50e95db3 --- a/piethernet.h +++ b/piethernet.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Ethernet, UDP - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,12 +20,13 @@ #ifndef PIETHERNET_H #define PIETHERNET_H -#include "pithread.h" -#include "pistring.h" +#include "pitimer.h" +#include "piiodevice.h" #ifndef WINDOWS # include # include # include +# include #else # ifdef CC_VC # include @@ -36,42 +37,66 @@ # endif #endif -#define BUFFER_SIZE 4096 - -typedef bool (*EthernetFunc)(void * , uchar * , int ); - -class PIEthernet: public PIThread +class PIEthernet: public PIIODevice { public: // slot is any function format "bool (void*, uchar*, int)" - PIEthernet(PIString ip = "", int port = 0, void * data = 0, EthernetFunc slot = 0); + PIEthernet(void * data, ReadRetFunc slot); + + enum Type {UDP, TCP_Client, TCP_Server}; + + PIEthernet(Type type = UDP, void * data = 0, ReadRetFunc slot = 0); ~PIEthernet(); - void setSlot(EthernetFunc func) {ret_func = func;} - void setData(void * d) {data = d;} - void setReadAddress(PIString ip, int port) {ip_ = ip; port_ = port;} + void setReadAddress(PIString ip, int port) {path_ = ip + ":" + PIString::fromNumber(port);} + void setReadAddress(PIString ip_port) {path_ = ip_port;} void setSendAddress(PIString ip, int port) {ip_s = ip; port_s = port;} + void setSendAddress(PIString ip_port) {parseAddress(ip_port, &ip_s, &port_s);} + + Type type() const {return type_;} + + bool connect(PIString ip, int port); + bool connect(PIString ip_port) {parseAddress(ip_port, &ip_c, &port_c); return connect(ip_c, port_c);} + bool isConnected() const {return connected_;} + + bool listen(); + bool listen(PIString ip, int port) {setReadAddress(ip, port); return listen();} + bool listen(PIString ip_port) {setReadAddress(ip_port); return listen();} + + PIEthernet * client(int index) {return clients_[index];} + int clientsCount() const {return clients_.size_s();} + PIVector clients() {return clients_;} + + bool send(PIString ip, int port, const void * data, int size) {ip_s = ip; port_s = port; return send(data, size);} + bool send(PIString ip_port, const void * data, int size) {parseAddress(ip_port, &ip_s, &port_s); return send(data, size);} + bool send(const void * data, int size) {return (write(data, size) == size);} + + int read(void * read_to, int max_size); + int write(const void * data, int max_size); + +protected: + PIEthernet(int sock, PIString ip_port); - bool send(PIString ip, int port, char * data, int size); - bool send(uchar * data, int size); bool init(); - bool initSend(); - bool receiverInitialized() const {return sock != -1;} - bool senderInitialized() const {return sock_s != -1;} - void terminate(); - const uchar * buffer() const {return buffer_;} + bool openDevice(); + bool closeDevice(); +#ifdef WINDOWS + void closeSocket(int & sd) {if (sd != -1) closesocket(sd); sd = -1;} +#else + void closeSocket(int & sd) {if (sd != -1) ::close(sd); sd = -1;} +#endif + void parseAddress(const PIString & ipp, PIString * ip, int * port); + + int sock, port_, port_s, port_c, wrote; + bool connected_; + sockaddr_in addr_, saddr_; + PIString ip_, ip_s, ip_c; + PIThread server_thread_; + PIVector clients_; + Type type_; private: - void begin(); - void run(); - void end(); - - int sock, sock_s, port_, port_s, wrote, readed, tries; - sockaddr_in addr_, saddr_; - PIString ip_, ip_s; - EthernetFunc ret_func; - void * data; - uchar buffer_[BUFFER_SIZE]; + static void server_func(void * eth); }; diff --git a/pievaluator.cpp b/pievaluator.cpp old mode 100644 new mode 100755 index b3ef9283..5bef2b45 --- a/pievaluator.cpp +++ b/pievaluator.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Evaluator designed for stream computing - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/pievaluator.h b/pievaluator.h old mode 100644 new mode 100755 index 9009c59d..545c78cd --- a/pievaluator.h +++ b/pievaluator.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Evaluator designed for stream computing - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/pifile.cpp b/pifile.cpp old mode 100644 new mode 100755 index 78b7b3aa..ac4d5cad --- a/pifile.cpp +++ b/pifile.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives File - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,35 +20,46 @@ #include "pifile.h" -bool PIFile::open(const PIString & path_, PIFlags mode_) { - cpath = path_; - cmode = mode_; - string st = cpath.stdString(); - if (cmode[New]) { - stream.open(st.c_str(), fstream::in | fstream::out | fstream::trunc | fstream::binary); - stream.close(); - cmode &= ~New; - stream.open(st.c_str(), (fstream::openmode)(int)cmode | fstream::binary); - } else stream.open(st.c_str(), (fstream::openmode)(int)cmode | fstream::binary); - return isOpened(); +bool PIFile::openDevice() { + if (opened_) close(); + if (path_.isEmpty()) return false; + //cout << "fopen " << path_.data() << ": " << strType(mode_).data() << endl; + fd = fopen(path_.data(), strType(mode_).data()); + opened_ = (fd != 0); + seekToBegin(); + return opened_; +} + + +bool PIFile::closeDevice() { + if (!opened_) return true; + return (fclose(fd) != 0); } PIString PIFile::readLine() { - char * buff = new char[4096]; - stream.getline(buff, 4096); - return PIString(buff); + PIString str; + if (!opened_) return str; + char cc; + int cp = 0; + while (!isEnd() && cp < 4095) { + cc = char(fgetc(fd)); + if (cc == '\n') break; + str.push_back(cc); + } + //cout << "readline: " << buff << endl; + return str; } llong PIFile::readAll(void * data) { llong cp = pos(), s = size(), i = -1; - stream.seekg(0); + seekToBegin(); if (s < 0) { - while (!stream.eof()) - stream.read(&(((char*)data)[++i]), 1); + while (!isEnd()) + read(&(((char*)data)[++i]), 1); } else - stream.read((char * )data, s); + read((char * )data, s); seek(cp); return s; } @@ -56,14 +67,11 @@ llong PIFile::readAll(void * data) { PIByteArray PIFile::readAll(bool forceRead) { llong cp = pos(), s = size(); - char c; PIByteArray a; if (s < 0) { if (!forceRead) return a; - while (!stream.eof()) { - stream.read(&c, 1); - a.push_back(c); - } + while (!isEnd()) + a.push_back(readChar()); seek(cp); return a; } @@ -75,12 +83,11 @@ PIByteArray PIFile::readAll(bool forceRead) { llong PIFile::size() { - if (!stream.is_open()) return -1; - llong s, cp = stream.tellg(); - stream.seekg(0, fstream::end); - s = stream.tellg(); - stream.seekg(cp, fstream::beg); - stream.clear(); + if (!opened_) return -1; + llong s, cp = pos(); + seekToEnd(); + s = pos(); + seek(cp); return s; } @@ -91,23 +98,18 @@ void PIFile::resize(llong new_size, char fill_) { if (ds > 0) { char * buff = new char[ds]; memset(buff, fill_, ds); - stream.write(buff, ds); - delete buff; + write(buff, ds); + delete[] buff; return; } - cout << "[PIFile] Downsize is not support yet :-(" << endl; + piCout << "[PIFile] Downsize is not support yet :-(" << endl; } -llong PIFile::pos() { - if (cmode[Write]) return stream.tellp(); - if (cmode[Read]) return stream.tellg(); - return -1; -} - -PIFile PIFile::openTemporary(PIFlags mode) { - char * rc; - rc = tmpnam(0); - return PIFile(PIString(rc), mode); +bool PIFile::isExists(const PIString & path) { + FILE * f = fopen(PIString(path).data(), "r"); + bool ok = (f != 0); + if (ok) fclose(f); + return ok; } diff --git a/pifile.h b/pifile.h old mode 100644 new mode 100755 index 7793f906..6c378f86 --- a/pifile.h +++ b/pifile.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives File - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,100 +20,89 @@ #ifndef PIFILE_H #define PIFILE_H -#include "piobject.h" -#include +#include "piiodevice.h" +#include -using std::fstream; - -class PIFile: public PIObject +class PIFile: public PIIODevice { public: - PIFile(): PIObject() {;} + PIFile(const PIString & path = PIString(), DeviceMode type = ReadWrite): PIIODevice(path, type) {openDevice();} - enum Mode {Read = fstream::in, Write = fstream::out, Truncate = fstream::trunc, New = fstream::app, ReadWrite = Read | Write}; + //PIFile & operator =(const PIFile & f) {path_ = f.path_; type_ = f.type_; return *this;} - PIFile(const PIString & path, PIFlags mode = ReadWrite): PIObject(path) {open(path, mode);} - PIFile(const PIFile & file): PIObject(file.cpath) {cpath = file.cpath; cmode = file.cmode;} - ~PIFile() {close();} - - PIFile & operator =(const PIFile & f) {cpath = f.cpath; cmode = f.cmode; return *this;} - - EVENT_HANDLER2(PIFile, bool, open, const PIString & , path, PIFlags, mode); - EVENT_HANDLER1(PIFile, bool, open, PIFlags, mode) {return open(cpath, mode);} - EVENT_HANDLER1(PIFile, bool, open, const PIString & , path) {return open(path, cmode);} - EVENT_HANDLER0(PIFile, bool, open) {return open(cpath, cmode);} - EVENT_HANDLER0(PIFile, void, close) {stream.clear(); stream.close();} - EVENT_HANDLER0(PIFile, void, clear) {string st = cpath.stdString(); close(); stream.open(st.c_str(), fstream::trunc | fstream::binary | (fstream::openmode)(int)cmode);} - void seek(llong position) {stream.clear(); stream.seekg(position); stream.seekp(position);} - void seekToBegin() {stream.clear(); stream.seekg(0, fstream::beg); stream.seekp(0, fstream::beg);} - void seekToEnd() {stream.clear(); stream.seekg(0, fstream::end); stream.seekp(0, fstream::end);} - void seekToLine(llong line) {stream.clear(); seekToBegin(); piForTimes (line) readLine();} // line 0 - begin of file + void flush() {fflush(fd);} + EVENT_HANDLER(PIFile, void, clear) {close(); fd = fopen(path_.data(), "w"); close(); open();} + void seek(llong position) {if (!opened_) return; fseek(fd, position, SEEK_SET); clearerr(fd);} + void seekToBegin() {if (!opened_) return; fseek(fd, 0, SEEK_SET); clearerr(fd);} + void seekToEnd() {if (!opened_) return; fseek(fd, 0, SEEK_END); clearerr(fd);} + void seekToLine(llong line) {if (!opened_) return; seekToBegin(); piForTimes (line) readLine(); clearerr(fd);} // line 0 - begin of file EVENT_HANDLER1(PIFile, void, resize, llong, new_size) {resize(new_size, 0);} EVENT_HANDLER2(PIFile, void, resize, llong, new_size, char, fill); - void fill(char c) {stream.fill(c);} - EVENT_HANDLER0(PIFile, void, flush) {stream.flush();} + //void fill(char c) {stream.fill(c);} + char readChar() {return (char)fgetc(fd);} PIString readLine(); llong readAll(void * data); PIByteArray readAll(bool forceRead = false); - EVENT_HANDLER0(PIFile, void, remove) {close(); std::remove(cpath.data());} + EVENT_HANDLER0(PIFile, void, remove) {close(); std::remove(path_.data());} - PIString path() const {return cpath;} - void setPath(const PIString & path) {cpath = path;} - PIFlags mode() const {return cmode;} + void setPath(const PIString & path) {path_ = path; if (opened_) openDevice();} llong size(); - llong pos(); - bool isOpened() {return stream.is_open();} - bool isEnd() {return stream.eof();} + llong pos() {if (!opened_) return -1; return ftell(fd);} + bool isEnd() {return (feof(fd) || ferror(fd));} bool isEmpty() {return (size() <= 0);} - PIFile & writeData(const void * data, int size_) {stream.write((char * )data, size_); return *this;} - PIFile & readData(void * data, int size_) {stream.read((char * )data, size_); return *this;} - PIFile & writeToBinLog(ushort id, const void * data, int size) {writeBinary(id).writeBinary((ushort)size).writeData(data, size); flush(); return *this;} + int read(void * read_to, int max_size) {if (!canRead()) return -1; return fread(read_to, max_size, 1, fd);} + int write(const void * data, int max_size) {if (!canWrite()) return -1; return fwrite(data, max_size, 1, fd);} + PIFile & writeToBinLog(ushort id, const void * data, int size) {if (!isWriteable()) return *this; writeBinary(id).writeBinary((ushort)size); write(data, size); flush(); return *this;} - PIFile & writeBinary(const char v) {stream.write((char * )&v, sizeof(v)); return *this;} - PIFile & writeBinary(const short v) {stream.write((char * )&v, sizeof(v)); return *this;} - PIFile & writeBinary(const int v) {stream.write((char * )&v, sizeof(v)); return *this;} - PIFile & writeBinary(const long v) {stream.write((char * )&v, sizeof(v)); return *this;} - PIFile & writeBinary(const uchar v) {stream.write((char * )&v, sizeof(v)); return *this;} - PIFile & writeBinary(const ushort v) {stream.write((char * )&v, sizeof(v)); return *this;} - PIFile & writeBinary(const uint v) {stream.write((char * )&v, sizeof(v)); return *this;} - PIFile & writeBinary(const ulong v) {stream.write((char * )&v, sizeof(v)); return *this;} - PIFile & writeBinary(const float v) {stream.write((char * )&v, sizeof(v)); return *this;} - PIFile & writeBinary(const double v) {stream.write((char * )&v, sizeof(v)); return *this;} + PIFile & writeBinary(const char v) {write(&v, sizeof(v)); return *this;} + PIFile & writeBinary(const short v) {write(&v, sizeof(v)); return *this;} + PIFile & writeBinary(const int v) {write(&v, sizeof(v)); return *this;} + PIFile & writeBinary(const long v) {write(&v, sizeof(v)); return *this;} + PIFile & writeBinary(const uchar v) {write(&v, sizeof(v)); return *this;} + PIFile & writeBinary(const ushort v) {write(&v, sizeof(v)); return *this;} + PIFile & writeBinary(const uint v) {write(&v, sizeof(v)); return *this;} + PIFile & writeBinary(const ulong v) {write(&v, sizeof(v)); return *this;} + PIFile & writeBinary(const float v) {write(&v, sizeof(v)); return *this;} + PIFile & writeBinary(const double v) {write(&v, sizeof(v)); return *this;} - PIFile & operator <<(const char & v) {stream.write(&v, 1); return *this;} - //PIFile & operator <<(const string & v) {stream.write(v.c_str(), v.size()); return *this;} - PIFile & operator <<(const PIString & v) {string s = v.stdString(); stream.write(s.c_str(), s.size()); return *this;} - PIFile & operator <<(const PIByteArray & v) {stream.write((char * )v.data(), v.size()); return *this;} - PIFile & operator <<(const short & v) {stream << v; return *this;} - PIFile & operator <<(const int & v) {stream << v; return *this;} - PIFile & operator <<(const long & v) {stream << v; return *this;} - PIFile & operator <<(const uchar & v) {stream << v; return *this;} - PIFile & operator <<(const ushort & v) {stream << v; return *this;} - PIFile & operator <<(const uint & v) {stream << v; return *this;} - PIFile & operator <<(const ulong & v) {stream << v; return *this;} - PIFile & operator <<(const float & v) {stream << v; return *this;} - PIFile & operator <<(const double & v) {stream << v; return *this;} + PIFile & operator <<(const char & v) {if (!isWriteable()) return *this; write(&v, 1); return *this;} + //PIFile & operator <<(const string & v) {write(v.c_str(), v.size()); return *this;} + PIFile & operator <<(const PIString & v) {if (!isWriteable()) return *this; write(v.data(), v.lengthAscii()); return *this;} + PIFile & operator <<(const PIByteArray & v) {if (!isWriteable()) return *this; write(v.data(), v.size()); return *this;} + PIFile & operator <<(short v) {if (!isWriteable()) return *this; fprintf(fd, "%hd", v); return *this;} + PIFile & operator <<(int v) {if (!isWriteable()) return *this; fprintf(fd, "%d", v); return *this;} + PIFile & operator <<(long v) {if (!isWriteable()) return *this; fprintf(fd, "%ld", v); return *this;} + PIFile & operator <<(uchar v) {if (!isWriteable()) return *this; fprintf(fd, "%c", v); return *this;} + PIFile & operator <<(ushort v) {if (!isWriteable()) return *this; fprintf(fd, "%hd", v); return *this;} + PIFile & operator <<(uint v) {if (!isWriteable()) return *this; fprintf(fd, "%d", v); return *this;} + PIFile & operator <<(ulong v) {if (!isWriteable()) return *this; fprintf(fd, "%ld", v); return *this;} + PIFile & operator <<(float v) {if (!isWriteable()) return *this; fprintf(fd, "%f", v); return *this;} + PIFile & operator <<(double v) {if (!isWriteable()) return *this; fprintf(fd, "%lf", v); return *this;} - PIFile & operator >>(char & v) {stream >> v; return *this;} - PIFile & operator >>(short & v) {stream >> v; return *this;} - PIFile & operator >>(int & v) {stream >> v; return *this;} - PIFile & operator >>(long & v) {stream >> v; return *this;} - PIFile & operator >>(uchar & v) {stream >> v; return *this;} - PIFile & operator >>(ushort & v) {stream >> v; return *this;} - PIFile & operator >>(uint & v) {stream >> v; return *this;} - PIFile & operator >>(ulong & v) {stream >> v; return *this;} - PIFile & operator >>(float & v) {stream >> v; return *this;} - PIFile & operator >>(double & v) {stream >> v; return *this;} - - static PIFile openTemporary(PIFlags mode = PIFile::ReadWrite); - static bool isExists(const PIString & path) {return std::ifstream(path.stdString().c_str()).good();} - static bool remove(const PIString & path) {return std::remove(path.stdString().c_str()) == 0;} + PIFile & operator >>(char & v) {if (!isWriteable()) return *this; fscanf(fd, "%hhn", &v); return *this;} + PIFile & operator >>(short & v) {if (!isWriteable()) return *this; fscanf(fd, "%hn", &v); return *this;} + PIFile & operator >>(int & v) {if (!isWriteable()) return *this; fscanf(fd, "%n", &v); return *this;} + PIFile & operator >>(long & v) {if (!isWriteable()) return *this; fscanf(fd, "%ln", &v); return *this;} + PIFile & operator >>(uchar & v) {if (!isWriteable()) return *this; fscanf(fd, "%hhn", &v); return *this;} + PIFile & operator >>(ushort & v) {if (!isWriteable()) return *this; fscanf(fd, "%hn", &v); return *this;} + PIFile & operator >>(uint & v) {if (!isWriteable()) return *this; fscanf(fd, "%n", &v); return *this;} + PIFile & operator >>(ulong & v) {if (!isWriteable()) return *this; fscanf(fd, "%ln", &v); return *this;} + PIFile & operator >>(float & v) {if (!isWriteable()) return *this; fscanf(fd, "%f", &v); return *this;} + PIFile & operator >>(double & v) {if (!isWriteable()) return *this; fscanf(fd, "%lf", &v); return *this;} + + static PIFile openTemporary(PIIODevice::DeviceMode mode = PIIODevice::ReadWrite) {return PIFile(PIString(tmpnam(0)), mode);} + static bool isExists(const PIString & path); + static bool remove(const PIString & path) {return std::remove(path.data()) == 0;} + +protected: + bool openDevice(); + bool closeDevice(); private: - fstream stream; - PIString cpath; - PIFlags cmode; + PIString strType(const PIIODevice::DeviceMode type) {switch (type) {case PIIODevice::ReadOnly: return "rb"; case WriteOnly: return "ab"; case ReadWrite: return "a+b";} return "rb";} + + FILE * fd; }; diff --git a/pigeometry.h b/pigeometry.h old mode 100644 new mode 100755 index a64fb4bc..642b559d --- a/pigeometry.h +++ b/pigeometry.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Geometry - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/piincludes.cpp b/piincludes.cpp new file mode 100644 index 00000000..35736881 --- /dev/null +++ b/piincludes.cpp @@ -0,0 +1,23 @@ +/* + PIP - Platform Independent Primitives + Global includes + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "piincludes.h" + +bool isPIInit = false; +bool piDebug = true; diff --git a/piincludes.h b/piincludes.h old mode 100644 new mode 100755 index 5f53af69..bede5cb1 --- a/piincludes.h +++ b/piincludes.h @@ -20,10 +20,11 @@ #ifndef PIINCLUDES_H #define PIINCLUDES_H -#define PIP_VERSION 0x000102 +#define PIP_VERSION 0x000200 #define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16 #define PIP_VERSION_MINOR (PIP_VERSION & 0xFF00) >> 8 #define PIP_VERSION_REVISION PIP_VERSION & 0xFF +#define PIP_VERSION_SUFFIX "" #if WIN32 || WIN64 || _WIN32 || _WIN64 || __WIN32__ || __WIN64__ # define WINDOWS @@ -119,13 +120,17 @@ static locale_t currentLocale_t = 0; typedef std::basic_string wstring; #endif -static bool isPIInit = false; +extern bool isPIInit; +extern bool piDebug; + +#define piCout if (piDebug) cout class PIInit { public: PIInit() { if (isPIInit) return; isPIInit = true; + //piDebug = true; #ifdef LINUX if (currentLocale_t != 0) { freelocale(currentLocale_t); @@ -215,6 +220,6 @@ inline string dtos(const double num) { #endif return string(ch); }; -inline string PIPVersion() {return itos(PIP_VERSION_MAJOR) + "." + itos(PIP_VERSION_MINOR) + "." + itos(PIP_VERSION_REVISION);} +inline string PIPVersion() {return itos(PIP_VERSION_MAJOR) + "." + itos(PIP_VERSION_MINOR) + "." + itos(PIP_VERSION_REVISION) + PIP_VERSION_SUFFIX;} #endif // PIINCLUDES_H diff --git a/piiodevice.cpp b/piiodevice.cpp new file mode 100755 index 00000000..27a78afe --- /dev/null +++ b/piiodevice.cpp @@ -0,0 +1,107 @@ +/* + PIP - Platform Independent Primitives + Abstract input/output device + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "piiodevice.h" + + +PIIODevice::PIIODevice(): PIThread() { + mode_ = ReadOnly; + opened_ = init_ = thread_started_ = false; + reopen_enabled_ = true; + reopen_timeout_ = 1000; + ret_func_ = 0; + ret_data_ = 0; + buffer_tr.resize(4096); + CONNECT2(void, void * , int, &timer, timeout, this, check_start); + init(); +} + + +PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode type, bool initNow): PIThread() { + path_ = path; + mode_ = type; + opened_ = init_ = thread_started_ = false; + reopen_enabled_ = true; + reopen_timeout_ = 1000; + ret_func_ = 0; + ret_data_ = 0; + buffer_tr.resize(4096); + CONNECT2(void, void * , int, &timer, timeout, this, check_start); + if (initNow) init(); +} + + +void PIIODevice::check_start(void * data, int delim) { + //cout << "check " << tread_started_ << endl; + if (open()) { + thread_started_ = true; + timer.stop(); + } +} + + +void PIIODevice::terminate() { + thread_started_ = false; + if (!isInitialized()) return; + if (isRunning()) { + stop(); + PIThread::terminate(); + } +} + + +void PIIODevice::begin() { + //cout << " begin\n"; + thread_started_ = false; + if (!opened_) { + if (open()) { + thread_started_ = true; + //cout << " open && ok\n"; + return; + } + } else { + thread_started_ = true; + //cout << " ok\n"; + return; + } + //init(); + if (!timer.isRunning() && reopen_enabled_) timer.start(reopen_timeout_); +} + + +void PIIODevice::run() { + if (!isReadable()) { + //cout << "not readable\n"; + stop(); + return; + } + if (!thread_started_) { + msleep(1); + //cout << "not started\n"; + return; + } + + readed_ = read(buffer_tr.data(), buffer_tr.size_s()); + if (readed_ <= 0) { + msleep(10); + //cout << readed_ << ", " << errno << ", " << errorString() << endl; + return; + } + threadedRead(buffer_tr.data(), readed_); +} diff --git a/piiodevice.h b/piiodevice.h new file mode 100755 index 00000000..8fee6051 --- /dev/null +++ b/piiodevice.h @@ -0,0 +1,121 @@ +/* + PIP - Platform Independent Primitives + Abstract input/output device + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef PIIODEVICE_H +#define PIIODEVICE_H + +#include "pitimer.h" + +// function executed from threaded read, pass ThreadedReadData, readedData, sizeOfData +typedef bool (*ReadRetFunc)(void * , uchar * , int ); + +class PIIODevice: public PIThread { +public: + PIIODevice(); + + enum DeviceMode {ReadOnly = 0x01, WriteOnly = 0x02, ReadWrite = 0x03}; + + PIIODevice(const PIString & path, DeviceMode type = ReadWrite, bool initNow = true); + ~PIIODevice() {if (opened_) closeDevice();} + + + DeviceMode mode() const {return mode_;} + PIString path() const {return path_;} + bool isReadable() const {return (mode_ & ReadOnly);} + bool isWriteable() const {return (mode_ & WriteOnly);} + bool isInitialized() const {return init_;} + bool isOpened() const {return opened_;} + bool isClosed() const {return !opened_;} + bool canRead() const {return opened_ && (mode_ & ReadOnly);} + bool canWrite() const {return opened_ && (mode_ & WriteOnly);} + + + // Enable timer to periodically open device until it will be opened + void setReopenEnabled(bool yes = true) {reopen_enabled_ = yes;} + void setReopenTimeout(int msecs = 1000) {reopen_timeout_ = msecs;} + + bool isReopenEnabled() const {return reopen_enabled_;} + int reopenTimeout() {return reopen_timeout_;} + + + // set return function executed when successful read in thread + void setThreadedReadSlot(ReadRetFunc func) {ret_func_ = func;} + void setThreadedReadData(void * d) {ret_data_ = d;} + void setThreadedReadBufferSize(int new_size) {buffer_tr.resize(new_size);} + + int threadedReadBufferSize() const {return buffer_tr.size_s();} + const uchar * threadedReadBuffer() const {return buffer_tr.data();} + + void startThreadedRead() {if (!isRunning()) start();} + void startThreadedRead(ReadRetFunc func) {ret_func_ = func; if (!isRunning()) start();} + + + EVENT_HANDLER(PIIODevice, bool, open) {if (!init_) init(); opened_ = openDevice(); return opened_;} + EVENT_HANDLER1(PIIODevice, bool, open, const PIString &, _path) {path_ = _path; if (!init_) init(); opened_ = openDevice(); return opened_;} + EVENT_HANDLER1(PIIODevice, bool, open, const DeviceMode &, _type) {mode_ = _type; if (!init_) init(); opened_ = openDevice(); return opened_;} + EVENT_HANDLER2(PIIODevice, bool, open, const PIString &, _path, const DeviceMode &, _type) {path_ = _path; mode_ = _type; if (!init_) init(); opened_ = openDevice(); return opened_;} + EVENT_HANDLER(PIIODevice, bool, close) {opened_ = !closeDevice(); return !opened_;} + + // Flush device + EVENT_VHANDLER(PIIODevice, void, flush) {;} + + + // Read from device to "read_to" maximum "max_size" bytes, return readed bytes count + virtual int read(void * read_to, int max_size) {piCout << "[PIIODevice] \"read\" not implemented!" << endl; return -2;} + + // Write to device "data" maximum "max_size" bytes, return written bytes count + virtual int write(const void * data, int max_size) {piCout << "[PIIODevice] \"write\" not implemented!" << endl; return -2;} + + // Read from device maximum "max_size" bytes and return them as PIByteArray + PIByteArray read(int max_size) {buffer_in.resize(max_size); int ret = read(buffer_in.data(), max_size); if (ret < 0) return PIByteArray(); return buffer_in.resized(ret);} + + +protected: + // Function executed before first openDevice() or from constructor + virtual bool init() {return true;} + + // Functions to open and close device, return value will set to "opened_" variable + virtual bool openDevice() = 0; // use path_, type_, opened_, init_ variables + virtual bool closeDevice() {return true;} // use path_, type_, opened_, init_ variables + + // Function executed when thread read some data, default implementation execute external slot "ret_func_" + virtual bool threadedRead(uchar * readed, int size) {if (ret_func_ != 0) return ret_func_(ret_data_, readed, size); return true;} + + PIString path_; + DeviceMode mode_; + ReadRetFunc ret_func_; + bool init_, opened_, thread_started_, reopen_enabled_; + int reopen_timeout_; + void * ret_data_; + +private: + EVENT_HANDLER2(PIIODevice, void, check_start, void * , data, int, delim); + void terminate(); + + void begin(); + void run(); + void end() {terminate();} + + PITimer timer; + PIByteArray buffer_in, buffer_tr; + int readed_; + +}; + +#endif // PIIODEVICE_H diff --git a/pikbdlistener.cpp b/pikbdlistener.cpp old mode 100644 new mode 100755 index 4b3e66cb..e505eb45 --- a/pikbdlistener.cpp +++ b/pikbdlistener.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Keyboard grabber for console - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -60,7 +60,10 @@ void PIKbdListener::run() { #else ret = read(0, &rc, 1); #endif - if (exit_enabled && rc == exit_key) PIKbdListener::exiting = true; + if (exit_enabled && rc == exit_key) { + PIKbdListener::exiting = true; + return; + } if (ret_func != 0 && ret > 0) ret_func(rc, data); } diff --git a/pikbdlistener.h b/pikbdlistener.h old mode 100644 new mode 100755 index a24a3129..c8ed6b87 --- a/pikbdlistener.h +++ b/pikbdlistener.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Keyboard grabber for console - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/pimath.cpp b/pimath.cpp old mode 100644 new mode 100755 index d74bc2aa..b0107e67 --- a/pimath.cpp +++ b/pimath.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Math - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/pimath.h b/pimath.h old mode 100644 new mode 100755 index 6c13fecb..45e11f83 --- a/pimath.h +++ b/pimath.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Math - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/pimonitor.cpp b/pimonitor.cpp old mode 100644 new mode 100755 index 3e3d917d..9ded81ad --- a/pimonitor.cpp +++ b/pimonitor.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Counter of some PIP types - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/pimonitor.h b/pimonitor.h old mode 100644 new mode 100755 index 0395e847..486f86b9 --- a/pimonitor.h +++ b/pimonitor.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Counter of some PIP types - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/pimultiprotocol.cpp b/pimultiprotocol.cpp old mode 100644 new mode 100755 index e3eed978..422263cf --- a/pimultiprotocol.cpp +++ b/pimultiprotocol.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Multiprotocol - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/pimultiprotocol.h b/pimultiprotocol.h old mode 100644 new mode 100755 index c8bc7ca8..7fe7d6e7 --- a/pimultiprotocol.h +++ b/pimultiprotocol.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Multiprotocol - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,7 +27,7 @@ class PIMultiProtocol: public PIMultiProtocolBase public: PIMultiProtocol() {;} virtual ~PIMultiProtocol() {clear();} - + void addProtocol(PIProtocol & prot) {prots.push_back(&prot); prot.setMultiProtocolOwner(this); prot.new_mp_prot = false;} void addProtocol(PIProtocol * prot) {prots.push_back(prot); prot->setMultiProtocolOwner(this); prot->new_mp_prot = false;} void addProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0, @@ -39,55 +39,55 @@ public: PIProtocol * protocol(const PIString & name) {piForeach (PIProtocol * i, prots) if (i->name() == name) return i; return 0;} PIProtocol * protocol(const int index) {return prots[index];} PIProtocol * operator [](const int index) {return prots[index];} - + void startSend() {piForeach (PIProtocol * i, prots) i->startSend();} void startReceive() {piForeach (PIProtocol * i, prots) i->startReceive();} void start() {piForeach (PIProtocol * i, prots) i->start();} - + void stopSend() {piForeach (PIProtocol * i, prots) i->stopSend();} void stopReceive() {piForeach (PIProtocol * i, prots) i->stopReceive();} void stop() {piForeach (PIProtocol * i, prots) i->stop();} - + PIProtocol::Quality worseQuality() const {PIProtocol::Quality cq = PIProtocol::Good; piForeachC (PIProtocol * i, prots) if (cq > i->quality()) cq = i->quality(); return cq;} PIProtocol::Quality bestQuality() const {PIProtocol::Quality cq = PIProtocol::Unknown; piForeachC (PIProtocol * i, prots) if (cq < i->quality()) cq = i->quality(); return cq;} - + int count() const {return prots.size_s();} void clear() {stop(); piForeach (PIProtocol * i, prots) if (i->new_mp_prot) delete i; prots.clear();} - + private: PIVector prots; - + }; class PIRepeater: public PIMultiProtocol { public: PIRepeater(const PIString & config, const PIString & name) { - PIConfig conf(config, PIFile::Read); + PIConfig conf(config, PIIODevice::ReadOnly); if (!conf.isOpened()) { - cout << "[PIRepeater \"" << name << "\"] Can`t open \"" << config << "\"!" << endl; + piCout << "[PIRepeater \"" << name << "\"] Can`t open \"" << config << "\"!" << endl; return; } PIConfig::Entry & b(conf.getValue(name)); if (b.childCount() != 2) { - cout << "[PIRepeater \"" << name << "\"] \"" << config << "\" should consist 2 nodes!" << endl; + piCout << "[PIRepeater \"" << name << "\"] \"" << config << "\" should consist 2 nodes!" << endl; return; } addProtocol(config, b.child(0)->fullName()); addProtocol(config, b.child(1)->fullName()); start(); } - + PIString firstChannelName() {if (count() == 2) return protocol(0)->receiverDeviceName() + " -> " + protocol(1)->senderDeviceName(); return "Config error";} PIString secondChannelName() {if (count() == 2) return protocol(1)->receiverDeviceName() + " -> " + protocol(0)->senderDeviceName(); return "Config error";} - + ullong receiveCount() {if (count() == 2) return protocol(0)->receiveCount(); return 0;} ullong * receiveCount_ptr() {if (count() == 2) return protocol(0)->receiveCount_ptr(); return 0;} ullong sendCount() {if (count() == 2) return protocol(0)->sendCount(); return 0;} ullong * sendCount_ptr() {if (count() == 2) return protocol(0)->sendCount_ptr(); return 0;} - + private: - void received(PIProtocol * prot, bool , char * data, int size) {if (prot == protocol(0)) protocol(1)->send(data, size); else protocol(0)->send(data, size);} - + void received(PIProtocol * prot, bool , uchar * data, int size) {if (prot == protocol(0)) protocol(1)->send(data, size); else protocol(0)->send(data, size);} + }; #endif // PIMULTIPROTOCOL_H diff --git a/pimutex.h b/pimutex.h old mode 100644 new mode 100755 index 87019202..dba34ec0 --- a/pimutex.h +++ b/pimutex.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Mutex - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/piobject.cpp b/piobject.cpp old mode 100644 new mode 100755 index ec2ac440..3674cdc2 --- a/piobject.cpp +++ b/piobject.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/piobject.h b/piobject.h old mode 100644 new mode 100755 index 5aad2fa0..826e9732 --- a/piobject.h +++ b/piobject.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -39,6 +39,13 @@ #define EVENT_HANDLER4(obj, ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((obj*)o)->name(n0, n1, n2, n3);} ret name(a0 n0, a1 n1, a2 n2, a3 n3) #define EVENT_HANDLER EVENT_HANDLER0 +#define EVENT_VHANDLER0(obj, ret, name) static ret __stat_##name##__(void * o) {return ((obj*)o)->name();} virtual ret name() +#define EVENT_VHANDLER1(obj, ret, name, a0, n0) static ret __stat_##name##__(void * o, a0 n0) {return ((obj*)o)->name(n0);} virtual ret name(a0 n0) +#define EVENT_VHANDLER2(obj, ret, name, a0, n0, a1, n1) static ret __stat_##name##__(void * o, a0 n0, a1 n1) {return ((obj*)o)->name(n0, n1);} virtual ret name(a0 n0, a1 n1) +#define EVENT_VHANDLER3(obj, ret, name, a0, n0, a1, n1, a2, n2) static ret __stat_##name##__(void * o, a0 n0, a1 n1, a2 n2) {return ((obj*)o)->name(n0, n1, n2);} virtual ret name(a0 n0, a1 n1, a2 n2) +#define EVENT_VHANDLER4(obj, ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((obj*)o)->name(n0, n1, n2, n3);} virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3) +#define EVENT_VHANDLER EVENT_VHANDLER0 + #define CONNECT0(ret, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*))(&(dst)->__stat_##handler##__)); #define CONNECT1(ret, a0, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0))(&(dst)->__stat_##handler##__)); #define CONNECT2(ret, a0, a1, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0, a1))(&(dst)->__stat_##handler##__)); @@ -51,7 +58,7 @@ class PIObject friend class PIObjectManager; public: PIObject(const PIString & name = PIString()) {piMonitor.objects++; setName(name); objects << this;} - ~PIObject() {piMonitor.objects--; objects.remove(this);} + ~PIObject() {piMonitor.objects--; objects.removeAll(this);} const PIString & name() const {return name_;} void setName(const PIString & name) {name_ = name;} diff --git a/pip.h b/pip.h old mode 100644 new mode 100755 index b132a014..eba95202 --- a/pip.h +++ b/pip.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives All includes - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/pip.kdev4 b/pip.kdev4 index a47a22f6..fb90c960 100644 --- a/pip.kdev4 +++ b/pip.kdev4 @@ -1,3 +1,3 @@ [Project] -Manager= +Manager=KDevCMakeManager Name=pip diff --git a/pipacketextractor.cpp b/pipacketextractor.cpp new file mode 100644 index 00000000..a68c2883 --- /dev/null +++ b/pipacketextractor.cpp @@ -0,0 +1,75 @@ +/* + PIP - Platform Independent Primitives + Packets extractor + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "pipacketextractor.h" + + +PIPacketExtractor::PIPacketExtractor(PIIODevice * device_, void * recHeaderPtr, int recHeaderSize, int recDataSize) { + ret_func_header = 0; + setPacketData(recHeaderPtr, recHeaderSize, recDataSize); + setBufferSize(4096); + setDevice(device_); + allReaded = addSize = curInd = 0; +} + + +void PIPacketExtractor::setDevice(PIIODevice * device_) { + dev = device_; + if (dev == 0) return; +} + + +bool PIPacketExtractor::threadedRead(uchar * readed, int size_) { + //cout << "extractor readed " << size_ << endl; + memcpy(buffer.data(allReaded), readed, size_); + allReaded += size_; + if (allReaded < packetSize + addSize) return true; + if (headerSize > 0) { + if (allReaded + curInd >= buffer_size) { + memcpy(sbuffer.data(), buffer.data(), buffer_size); + memcpy(buffer.data(), sbuffer.data(buffer_size - packetSize), allReaded); + allReaded = packetSize; + addSize = curInd = 0; + } + while (!packetHeaderValidate((uchar * )headerPtr, buffer.data(curInd), headerSize)) { + curInd++; missed++; + if (packetSize > 0) missed_packets = missed / packetSize; + if (curInd > addSize) { + addSize += packetSize; + return true; + } + } + memcpy(mheader.data(), buffer.data(curInd + headerSize), headerSize); + if (!packetValidate(buffer.data(curInd + headerSize), dataSize)) { + curInd++; missed++; + if (packetSize > 0) missed_packets = missed / packetSize; + return true; + } + memcpy(sbuffer.data(), buffer.data(), allReaded); + memcpy(buffer.data(), sbuffer.data(packetSize + curInd), allReaded); + allReaded -= packetSize + curInd; + curInd = addSize = 0; + } else { + packetValidate(buffer.data(), dataSize); + memcpy(sbuffer.data(), buffer.data(), allReaded); + memcpy(buffer.data(), sbuffer.data(packetSize), allReaded); + allReaded -= packetSize; + } + return true; +} diff --git a/pipacketextractor.h b/pipacketextractor.h new file mode 100644 index 00000000..38bdb2cb --- /dev/null +++ b/pipacketextractor.h @@ -0,0 +1,71 @@ +/* + PIP - Platform Independent Primitives + Packets extractor + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#ifndef PIPACKETEXTRACTOR_H +#define PIPACKETEXTRACTOR_H + +#include "piiodevice.h" + +// Pass data, recHeaderPtr, received_data, recHeaderSize. Return true if packet is correct nor return false. +typedef bool (*HeaderCheckFunc)(void * , uchar * , uchar * , int ); + +class PIPacketExtractor: public PIIODevice +{ +public: + PIPacketExtractor(PIIODevice * device_ = 0, void * recHeaderPtr = 0, int recHeaderSize = 0, int recDataSize = 0); + + PIIODevice * device() {return dev;} + void setDevice(PIIODevice * device_); + + int bufferSize() const {return buffer_size;} + void setBufferSize(int new_size) {buffer_size = new_size; buffer.resize(buffer_size); sbuffer.resize(buffer_size);} + + void setHeaderCheckSlot(HeaderCheckFunc f) {ret_func_header = f;} + void setPacketData(void * recHeaderPtr, int recHeaderSize, int recDataSize) {headerPtr = recHeaderPtr; headerSize = recHeaderSize; dataSize = recDataSize; packetSize = headerSize + dataSize; if (headerSize > 0) mheader.resize(headerSize);} + + ullong missedBytes() const {return missed;} + ullong missedPackets() const {return missed / packetSize;} + const ullong * missedBytes_ptr() const {return &missed;} + const ullong * missedPackets_ptr() const {return &missed_packets;} + + PIByteArray lastHeader() {return mheader;} + + int read(void * read_to, int max_size) {if (dev == 0) return -1; return dev->read(read_to, max_size);} + int write(const void * data, int max_size) {if (dev == 0) return -1; return dev->write(data, max_size);} + +protected: + virtual bool packetValidate(uchar * rec, int size) {if (ret_func_ != 0) return ret_func_(ret_data_, rec, size); return true;} + virtual bool packetHeaderValidate(uchar * src, uchar * rec, int size) {if (ret_func_header != 0) return ret_func_header(ret_data_, src, rec, size); for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;} + +private: + bool threadedRead(uchar * readed, int size); + bool openDevice() {if (dev == 0) return false; return dev->isOpened();} + + PIIODevice * dev; + PIByteArray mheader, buffer, sbuffer; + HeaderCheckFunc ret_func_header; + void * headerPtr, * data; + int buffer_size, dataSize, headerSize, packetSize, allReaded, addSize, curInd; + ullong missed, missed_packets; + + +}; + +#endif // PIPACKETEXTRACTOR_H diff --git a/piprocess.cpp b/piprocess.cpp old mode 100644 new mode 100755 index 12f2cfc9..1971858b --- a/piprocess.cpp +++ b/piprocess.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Process - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -59,7 +59,7 @@ void PIProcess::run() { #ifdef WINDOWS //args.pop_front(); piForeachC (PIString & i, args) - as += i.stdString().length() + 1; + as += i.lengthAscii() + 1; char * a = new char[as]; memset(a, ' ', as - 1); as = 0; @@ -93,28 +93,28 @@ void PIProcess::run() { /// files for stdin/out/err t_in = t_out = t_err = false; if (f_in.path().isEmpty()) { - f_in = PIFile::openTemporary(PIFile::New | PIFile::Read); + f_in = PIFile::openTemporary(PIIODevice::ReadWrite); t_in = true; } - f_in.open(PIFile::New | PIFile::Read); f_in.close(); + f_in.open(PIIODevice::ReadWrite); f_in.close(); if (f_out.path().isEmpty()) { - f_out = PIFile::openTemporary(PIFile::New | PIFile::Write); + f_out = PIFile::openTemporary(PIIODevice::ReadWrite); t_out = true; } - f_out.open(PIFile::New | PIFile::Write); f_out.close(); + f_out.open(PIIODevice::WriteOnly); f_out.close(); if (f_err.path().isEmpty()) { - f_err = PIFile::openTemporary(PIFile::New | PIFile::Write); + f_err = PIFile::openTemporary(PIIODevice::ReadWrite); t_err = true; } - f_err.open(PIFile::New | PIFile::Write); f_err.close(); - + f_err.open(PIIODevice::WriteOnly); f_err.close(); + str = args.front().stdString(); is_exec = true; #ifndef WINDOWS pid = fork(); if (pid == 0) { #endif - FILE * tf; + FILE * tf = 0; //cout << "exec" << endl; //cout << f_out.path() << endl; if (g_in) tf = freopen(f_in.path().data(), "r", stdin); @@ -140,10 +140,10 @@ void PIProcess::run() { WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); } else - cout << "[PIProcess] \"CreateProcess\" error, " << errorString() << endl; + piCout << "[PIProcess] \"CreateProcess\" error, " << errorString() << endl; #else if (execve(str.c_str(), a, e) < 0) - cout << "[PIProcess] \"execve\" error, " << errorString() << endl; + piCout << "[PIProcess] \"execve\" error, " << errorString() << endl; } else { msleep(1); //cout << "wait" << endl; diff --git a/piprocess.h b/piprocess.h old mode 100644 new mode 100755 index 60fe32c2..0dd951e8 --- a/piprocess.h +++ b/piprocess.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Process - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,14 +33,14 @@ class PIProcess: private PIThread public: PIProcess(); ~PIProcess(); - + int exitCode() const {return exit_code;} #ifdef WINDOWS int pID() const {return pi.dwProcessId;} #else int pID() const {return pid;} #endif - + void setGrabInput(bool yes) {g_in = yes;} void setGrabOutput(bool yes) {g_out = yes;} void setGrabError(bool yes) {g_err = yes;} @@ -64,25 +64,25 @@ public: void terminate() {if (is_exec) kill(pid, SIGKILL); pid = 0;} #endif bool waitForFinish(int timeout_msecs = 60000) {return PIThread::waitForFinish(timeout_msecs);} - PIByteArray readOutput() {f_out.open(PIFile::Read); return f_out.readAll();} - PIByteArray readError() {f_err.open(PIFile::Read); return f_err.readAll();} - + PIByteArray readOutput() {f_out.open(PIIODevice::ReadOnly); return f_out.readAll();} + PIByteArray readError() {f_err.open(PIIODevice::ReadOnly); return f_err.readAll();} + PIStringList environment() {return env;} void clearEnvironment() {env.clear();} void removeEnvironmentVariable(const PIString & variable); void setEnvironmentVariable(const PIString & variable, const PIString & value); - + static PIStringList currentEnvironment() {PIStringList l; int i = 0; while (environ[i] != 0) {l << environ[i]; ++i;} return l;} #ifdef WINDOWS static int currentPID() {return GetCurrentProcessId();} #else static int currentPID() {return getpid();} #endif - + private: virtual void run(); void exec_(); - + PIStringList args, env; PIString wd; PIByteArray out; @@ -96,7 +96,7 @@ private: #endif int exit_code, sz; bool is_exec; - + }; #endif // PIPROCESS_H diff --git a/piprotocol.cpp b/piprotocol.cpp old mode 100644 new mode 100755 index cde5ed91..357ad9c1 --- a/piprotocol.cpp +++ b/piprotocol.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Protocol, input/output channel (COM, UDP) - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,14 +24,15 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re init(); protName = name; PIObject::setName(name); - PIConfig conf(config, PIFile::Read); + PIConfig conf(config, PIIODevice::ReadOnly); if (!conf.isOpened()) { - cout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl; devReceiverState = devSenderState = "Config error"; return; } int ps, gps; bool ok, gok, flag, gflag, has_dev = false; + float freq, gfreq; PIFlags pp; PIConfig::Entry & b(conf.getValue(name)), & rb(b.getValue("receiver")), @@ -40,7 +41,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re /// receiver section if (rb.isEntryExists("ip") && rb.isEntryExists("device")) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl; devReceiverState = "Config error"; return; } @@ -49,7 +50,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) dev = gdev; if (gok && ok && (dev != gdev)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl; devReceiverState = "Config error"; return; } @@ -58,20 +59,44 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) ps = gps; if (gok && ok && (ps != gps)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous receive port in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive port in \"" << config << "\"!" << endl; devReceiverState = "Config error"; return; } type_rec = PIProtocol::Ethernet; - eth = new PIEthernet(dev, ps, this, receiveEvent); + eth = new PIEthernet(); + packet_ext.setDevice(eth); + //setSenderAddress(dev, ps); setReceiverAddress(dev, ps); has_dev = true; + flag = rb.getValue("reconnectEnabled", true, &ok); + gflag = b.getValue("reconnectEnabled", true, &gok); + if (ok || gok) { + if (gok && !ok) flag = gflag; + if (gok && ok && (flag != gflag)) { + piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectEnabled\" flag in \"" << config << "\"!" << endl; + devReceiverState = "Config error"; + return; + } + eth->setReopenEnabled(flag); + } + freq = rb.getValue("reconnectTimeout", 1., &ok); + gfreq = b.getValue("reconnectTimeout", 1., &gok); + if (ok || gok) { + if (gok && !ok) freq = gfreq; + if (gok && ok && (freq != gfreq)) { + piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectTimeout\" value in \"" << config << "\"!" << endl; + devReceiverState = "Config error"; + return; + } + eth->setReopenTimeout(freq * 1000); + } if (recDataPtr == 0) - cout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl; if (recDataSize == 0) - cout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl; } else { - cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.port\" or \"" << name << ".port\" in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.port\" or \"" << name << ".port\" in \"" << config << "\"!" << endl; devReceiverState = "Config error"; return; } @@ -81,7 +106,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) dev = gdev; if (gok && ok && (dev != gdev)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl; devReceiverState = "Config error"; return; } @@ -90,7 +115,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) ps = gps; if (gok && ok && (ps != gps)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"speed\" in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"speed\" in \"" << config << "\"!" << endl; devReceiverState = "Config error"; return; } @@ -99,7 +124,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) flag = gflag; if (gok && ok && (flag != gflag)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"parity\" in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"parity\" in \"" << config << "\"!" << endl; devReceiverState = "Config error"; return; } @@ -110,7 +135,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) flag = gflag; if (gok && ok && (flag != gflag)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"twoStopBits\" parity in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"twoStopBits\" parity in \"" << config << "\"!" << endl; devReceiverState = "Config error"; return; } @@ -118,19 +143,30 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re } type_rec = PIProtocol::Serial; type_send = PIProtocol::Serial; - ser = new PISerial(dev, this, receiveEvent, headerValidateEvent); + ser = new PISerial(dev); + packet_ext.setDevice(ser); + //setSenderDevice(dev, (PISerial::Speed)ps); setReceiverDevice(dev, (PISerial::Speed)ps); - setSenderDevice(dev, (PISerial::Speed)ps); ser->setInSpeed((PISerial::Speed)ps); ser->setParameters(pp); - ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize); + ps = rb.getValue("vtime", 1, &ok); + gps = b.getValue("vtime", 1, &gok); + if (ok || gok) { + if (gok && !ok) ps = gps; + if (gok && ok && (ps != gps)) { + piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"vtime\" in \"" << config << "\"!" << endl; + devReceiverState = "Config error"; + return; + } + ser->setVTime(ps); + } has_dev = true; if (recDataPtr == 0) - cout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl; if (recDataSize == 0) - cout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl; } else { - cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.speed\" or \"" << name << ".speed\" in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.speed\" or \"" << name << ".speed\" in \"" << config << "\"!" << endl; devReceiverState = "Config error"; return; } @@ -140,7 +176,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) history_write_rec = ghist; if (gok && ok && (history_write_rec != ghist)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous receiver history in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver history in \"" << config << "\"!" << endl; devReceiverState = "Config error"; return; } @@ -151,29 +187,30 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re history_id_rec = rb.getValue("historyID", 0, &ok); if (!ok) { history_id_rec = protName.toByteArray().checksumCRC16(); - cout << "[PIProtocol \"" << name << "\"] Warning: no receiver history ID defined, write with ID = " << history_id_rec << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: no receiver history ID defined, write with ID = " << history_id_rec << endl; } - history_file_rec.open(history_path_rec, PIFile::Write | PIFile::New); + history_file_rec.open(history_path_rec, PIIODevice::WriteOnly); } } - float freq = rb.getValue("frequency", -1.f, &ok), gfreq = b.getValue("frequency", -1.f, &gok); + freq = rb.getValue("frequency", -1.f, &ok); + gfreq = b.getValue("frequency", -1.f, &gok); if (gok && !ok) freq = gfreq; if (gok && ok && (freq != gfreq)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous expected frequency in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous expected frequency in \"" << config << "\"!" << endl; devReceiverState = "Config error"; return; } if (freq > 0.f && !has_dev) - cout << "[PIProtocol \"" << name << "\"] Warning: no receiver device and not null expected frequency!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: no receiver device and not null expected frequency!" << endl; float tm = b.getValue("disconnectTimeout", 3.f); if (tm <= 0.f) - cout << "[PIProtocol \"" << name << "\"] Warning: diconnect timeout <= 0 s!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: diconnect timeout <= 0 s!" << endl; timeout_ = (tm < 0.f) ? 0.f : tm; setExpectedFrequency(freq); /// sender section if (sb.isEntryExists("ip") && sb.isEntryExists("device")) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl; devSenderState = "Config error"; return; } @@ -183,7 +220,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) dev = gdev; if (gok && ok && (dev != gdev)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl; devSenderState = "Config error"; return; } @@ -192,20 +229,43 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) ps = gps; if (gok && ok && (ps != gps)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous send port in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous send port in \"" << config << "\"!" << endl; devSenderState = "Config error"; return; } type_send = PIProtocol::Ethernet; - if (eth == 0) eth = new PIEthernet(dev, ps, this, receiveEvent); + if (eth == 0) eth = new PIEthernet(); setSenderAddress(dev, ps); + //setReceiverAddress(dev, ps); has_dev = true; + flag = sb.getValue("reconnectEnabled", true, &ok); + gflag = b.getValue("reconnectEnabled", true, &gok); + if (ok || gok) { + if (gok && !ok) flag = gflag; + if (gok && ok && (flag != gflag)) { + piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectEnabled\" flag in \"" << config << "\"!" << endl; + devReceiverState = "Config error"; + return; + } + eth->setReopenEnabled(flag); + } + freq = sb.getValue("reconnectTimeout", 1., &ok); + gfreq = b.getValue("reconnectTimeout", 1., &gok); + if (ok || gok) { + if (gok && !ok) freq = gfreq; + if (gok && ok && (freq != gfreq)) { + piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectTimeout\" value in \"" << config << "\"!" << endl; + devReceiverState = "Config error"; + return; + } + eth->setReopenTimeout(freq * 1000); + } if (sendDataPtr_ == 0) - cout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl; if (sendDataSize_ == 0) - cout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl; } else { - cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.port\" or \"" << name << ".port\" in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.port\" or \"" << name << ".port\" in \"" << config << "\"!" << endl; devSenderState = "Config error"; return; } @@ -215,7 +275,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) dev = gdev; if (gok && ok && (dev != gdev)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl; devSenderState = "Config error"; return; } @@ -224,7 +284,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) ps = gps; if (gok && ok && (ps != gps)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous send \"speed\" in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"speed\" in \"" << config << "\"!" << endl; devSenderState = "Config error"; return; } @@ -233,7 +293,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) flag = gflag; if (gok && ok && (flag != gflag)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous send \"parity\" in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"parity\" in \"" << config << "\"!" << endl; devSenderState = "Config error"; return; } @@ -244,35 +304,34 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok || gok) { if (gok && !ok) flag = gflag; if (gok && ok && (flag != gflag)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous send \"twoStopBits\" parity in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"twoStopBits\" parity in \"" << config << "\"!" << endl; devSenderState = "Config error"; return; } pp |= PISerial::TwoStopBits; } } else { - cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.speed\" or \"" << name << ".speed\" in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.speed\" or \"" << name << ".speed\" in \"" << config << "\"!" << endl; devSenderState = "Config error"; return; } type_send = PIProtocol::Serial; - if (ser == 0) ser = new PISerial(dev, this, receiveEvent, headerValidateEvent); + if (ser == 0) ser = new PISerial(dev); setSenderDevice(dev, (PISerial::Speed)ps); ser->setOutSpeed((PISerial::Speed)ps); ser->setParameters(pp); - ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize); has_dev = true; if (sendDataPtr_ == 0) - cout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl; if (sendDataSize_ == 0) - cout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl; } history_write_send = sb.getValue("writeHistory", false, &ok); ghist = b.getValue("writeHistory", false, &gok); if (ok || gok) { if (gok && !ok) history_write_send = ghist; if (gok && ok && (history_write_send != ghist)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous sender history in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender history in \"" << config << "\"!" << endl; devSenderState = "Config error"; return; } @@ -283,21 +342,21 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re history_id_send = sb.getValue("historyID", 0, &ok); if (!ok) { history_id_send = protName.toByteArray().checksumCRC16() + 1; - cout << "[PIProtocol \"" << name << "\"] Warning: no sender history ID defined, write with ID = " << history_id_send << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: no sender history ID defined, write with ID = " << history_id_send << endl; } - history_file_send.open(history_path_send, PIFile::Write | PIFile::New); + history_file_send.open(history_path_send, PIIODevice::WriteOnly); } } freq = sb.getValue("frequency", -1.f, &ok); gfreq = b.getValue("frequency", -1.f, &gok); if (gok && !ok) freq = gfreq; if (gok && ok && (freq != gfreq)) { - cout << "[PIProtocol \"" << name << "\"] Ambiguous sender frequency in \"" << config << "\"!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender frequency in \"" << config << "\"!" << endl; devSenderState = "Config error"; return; } if (freq > 0.f && !has_dev) - cout << "[PIProtocol \"" << name << "\"] Warning: no sender device and not null send frequency!" << endl; + piCout << "[PIProtocol \"" << name << "\"] Warning: no sender device and not null send frequency!" << endl; setSenderFrequency(freq); headerPtr = (uchar * )recHeaderPtr; @@ -306,6 +365,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re dataSize = recDataSize; sendDataPtr = (uchar * )sendDataPtr_; sendDataSize = sendDataSize_; + packet_ext.setPacketData(recHeaderPtr, recHeaderSize, recDataSize); if (type_rec == PIProtocol::Ethernet) { if (recHeaderPtr != 0) { dataPtr = (uchar * )recHeaderPtr; @@ -341,6 +401,9 @@ PIProtocol::~PIProtocol() { void PIProtocol::init() { + packet_ext.setThreadedReadData(this); + packet_ext.setThreadedReadSlot(receiveEvent); + packet_ext.setHeaderCheckSlot(headerValidateEvent); work = new_mp_prot = history_write_rec = history_write_send = false; eth = 0; ser = 0; @@ -379,7 +442,10 @@ void PIProtocol::init() { void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force) { if (force) { type_send = type_rec = PIProtocol::Serial; - if (ser == 0) ser = new PISerial("", this, receiveEvent, headerValidateEvent); + if (ser == 0) { + ser = new PISerial(); + packet_ext.setDevice(ser); + } } if (type_rec == PIProtocol::Serial && ser != 0) { ser->setDevice(device); @@ -393,7 +459,10 @@ void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed spee void PIProtocol::setReceiverAddress(const PIString & ip, int port, bool force) { if (force) { type_rec = PIProtocol::Ethernet; - if (eth == 0) eth = new PIEthernet("", 0, this, receiveEvent); + if (eth == 0) { + eth = new PIEthernet(); + packet_ext.setDevice(eth); + } } if (type_rec == PIProtocol::Ethernet && eth != 0) { eth->setReadAddress(ip, port); @@ -406,11 +475,12 @@ void PIProtocol::setReceiverAddress(const PIString & ip, int port, bool force) { void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed, bool force) { if (force) { type_send = type_rec = PIProtocol::Serial; - if (ser == 0) ser = new PISerial("", this, receiveEvent, headerValidateEvent); + if (ser == 0) ser = new PISerial(); } if (type_send == PIProtocol::Serial && ser != 0) { ser->setDevice(device); ser->setSpeed(speed); + ser->open(); devSenderName = device; } } @@ -419,10 +489,11 @@ void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed, void PIProtocol::setSenderAddress(const PIString & ip, int port, bool force) { if (force) { type_send = PIProtocol::Ethernet; - if (eth == 0) eth = new PIEthernet("", 0, this, receiveEvent); + if (eth == 0) eth = new PIEthernet(); } if (type_send == PIProtocol::Ethernet && eth != 0) { eth->setSendAddress(ip, port); + eth->open(); if (ip.isEmpty()) devSenderName = "no ip"; else devSenderName = ip + ":" + PIString::fromNumber(port); } @@ -444,9 +515,10 @@ void PIProtocol::changeDisconnectTimeout() { void PIProtocol::startReceive(float exp_frequency) { if (exp_frequency > 0.f) exp_freq = exp_frequency; - if (type_rec == PIProtocol::Serial) ser->start(); - if (type_rec == PIProtocol::Ethernet) eth->start(); + //if (type_rec == PIProtocol::Serial) ser->start(); + //if (type_rec == PIProtocol::Ethernet) eth->start(); if (exp_freq <= 0.f) return; + packet_ext.startThreadedRead(); setExpectedFrequency(exp_freq); diagTimer->start(1000. / exp_freq); diagTimer->reset(); @@ -463,8 +535,9 @@ void PIProtocol::startSend(float frequency) { void PIProtocol::stopReceive() { - if (type_rec == PIProtocol::Serial) ser->stop(); - if (type_rec == PIProtocol::Ethernet) eth->stop(); + //if (type_rec == PIProtocol::Serial) ser->stop(); + //if (type_rec == PIProtocol::Ethernet) eth->stop(); + packet_ext.stop(); diagTimer->stop(); raiseEvent(this, "receiver stopped"); } @@ -508,7 +581,7 @@ void PIProtocol::diagEvent(void * t, int) { p->calc_freq(); p->calc_diag(); p->check_state(); - if (p->ser != 0) p->missed_count = p->ser->missedPackets(); + if (p->ser != 0) p->missed_count = p->packet_ext.missedPackets(); } @@ -558,47 +631,49 @@ void PIProtocol::calc_freq() { void PIProtocol::check_state() { if (type_rec == PIProtocol::Serial) { if (ser != 0) { - if (ser->initialized()) devReceiverState = "Initialized"; - else devReceiverState = "Uninitialized"; + if (ser->isOpened()) devReceiverState = "Opened"; + else devReceiverState = "Not opened"; } - else devReceiverState = "Uninitialized"; + else devReceiverState = "Not exists"; } if (type_rec == PIProtocol::Ethernet) { if (eth != 0) { - if (eth->receiverInitialized()) devReceiverState = "Initialized"; - else devReceiverState = "Uninitialized"; + if (eth->isOpened()) devReceiverState = "Opened"; + else devReceiverState = "Not opened"; } - else devReceiverState = "Uninitialized"; + else devReceiverState = "Not exists"; } if (type_send == PIProtocol::Serial) { if (ser != 0) { - if (ser->initialized()) devSenderState = "Initialized"; - else devSenderState = "Uninitialized"; + if (ser->isOpened()) devSenderState = "Opened"; + else devSenderState = "Not opened"; } - else devSenderState = "Uninitialized"; + else devSenderState = "Not exists"; } if (type_send == PIProtocol::Ethernet) { if (eth != 0) { - if (eth->senderInitialized()) devSenderState = "Initialized"; - else devSenderState = "Uninitialized"; + if (eth->isOpened()) devSenderState = "Opened"; + else devSenderState = "Not opened"; } - else devSenderState = "Uninitialized"; + else devSenderState = "Not exists"; } } -void PIProtocol::send(const void * data, int size) { - if (data == 0 || size == 0) return; - if (!aboutSend()) return; +void PIProtocol::send(const void * data, int size, bool direct) { + if (!direct) { + if (data == 0 || size == 0) return; + if (!aboutSend()) return; + } if (history_write_send) { history_file_send.writeToBinLog(history_id_send, data, size); history_rsize_send.setReadableSize(history_file_send.pos()); } if (type_send == PIProtocol::Serial) - if (ser->send((uchar * )data, size)) + if (ser->send(data, size)) send_count++; if (type_send == PIProtocol::Ethernet) - if (eth->send((uchar * )data, size)) + if (eth->send(data, size)) send_count++; } @@ -607,16 +682,16 @@ void PIProtocol::send() { //lock(); //memcpy(packet, sendDataPtr, sendDataSize); //unlock(); - if (sendDataPtr == 0 || sendDataSize == 0) return; if (!aboutSend()) return; + if (sendDataPtr == 0 || sendDataSize == 0) return; if (history_write_send) { history_file_send.writeToBinLog(history_id_send, sendDataPtr, sendDataSize); history_rsize_send.setReadableSize(history_file_send.pos()); } if (type_send == PIProtocol::Serial) - if (ser->send((uchar * )sendDataPtr, sendDataSize)) + if (ser->send(sendDataPtr, sendDataSize)) send_count++; if (type_send == PIProtocol::Ethernet) - if (eth->send((uchar * )sendDataPtr, sendDataSize)) + if (eth->send(sendDataPtr, sendDataSize)) send_count++; } diff --git a/piprotocol.h b/piprotocol.h old mode 100644 new mode 100755 index 479a36d8..1f512a62 --- a/piprotocol.h +++ b/piprotocol.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Protocol, input/output channel (COM, UDP) - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,10 +22,10 @@ #include "piserial.h" #include "piethernet.h" +#include "pipacketextractor.h" #include "pitimer.h" #include "piconfig.h" #include "math.h" -#include "piobject.h" class PIProtocol; @@ -67,8 +67,8 @@ public: EVENT_HANDLER0(PIProtocol, void, stopReceive); void setExpectedFrequency(float frequency); // for connection quality diagnostic void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial - void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setReadData(headerPtr, headerSize, dataSize);} - void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setReadData(headerPtr, headerSize, dataSize);} + void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; packet_ext.setPacketData(headerPtr, headerSize, dataSize);} + void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; packet_ext.setPacketData(headerPtr, headerSize, dataSize);} void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet void setReceiverParameters(PIFlags parameters) {if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;} @@ -87,7 +87,8 @@ public: EVENT_HANDLER0(PIProtocol, void, start) {startReceive(); startSend();} EVENT_HANDLER0(PIProtocol, void, stop) {stopReceive(); stopSend();} EVENT_HANDLER0(PIProtocol, void, send); - EVENT_HANDLER2(PIProtocol, void, send, const void *, data, int, size); + EVENT_HANDLER2(PIProtocol, void, send, const void *, data, int, size) {send(data, size, false);} + EVENT_HANDLER3(PIProtocol, void, send, const void *, data, int, size, bool, direct); void setName(const PIString & name) {protName = name; PIObject::setName(name);} PIString name() const {return protName;} @@ -126,7 +127,7 @@ public: void * receiveData() {return dataPtr;} void * sendData() {return sendDataPtr;} - PIByteArray lastHeader() {if (ser != 0) return ser->lastHeader(); return PIByteArray();} + PIByteArray lastHeader() {return packet_ext.lastHeader();} protected: virtual bool receive(uchar * data, int size) {if (dataPtr != 0) memcpy(dataPtr, data, size); return true;} // executed when raw data received, break if 'false' return @@ -169,6 +170,7 @@ private: void changeDisconnectTimeout(); ReceiveFunc ret_func; + PIPacketExtractor packet_ext; PITimer * diagTimer, * sendTimer; PIMultiProtocolBase * mp_owner; PIProtocol::Type type_send, type_rec; diff --git a/piserial.cpp b/piserial.cpp old mode 100644 new mode 100755 index f00b9942..a5f90322 --- a/piserial.cpp +++ b/piserial.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives COM - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,32 +20,48 @@ #include "piserial.h" -PISerial::PISerial(PIString name, void * data_, SerialFunc slot, SerialHeaderFunc slot_header): PIThread() { +PISerial::PISerial(const PIString & device, void * data_, ReadRetFunc slot): PIIODevice(device, ReadWrite) { piMonitor.serials++; setPriority(piHigh); + path_ = device; data = data_; - devName = name; fd = -1; - missed = 0; - dataSize = headerSize = 0; headerPtr = 0; - ret_func = slot; - ret_func_header = slot_header; + params = 0; + vtime = 1; + ret_func_ = slot; #ifdef WINDOWS hCom = 0; #endif ispeed = ospeed = S115200; + init(); +} + + +PISerial::PISerial(void * data_, ReadRetFunc slot): PIIODevice("", ReadWrite) { + piMonitor.serials++; + setPriority(piHigh); + data = data_; + fd = -1; + headerPtr = 0; + params = 0; + vtime = 1; + ret_func_ = slot; +#ifdef WINDOWS + hCom = 0; +#endif + ispeed = ospeed = S115200; + init(); } PISerial::~PISerial() { piMonitor.serials--; - terminate(); } -void PISerial::terminate() { - if (!initialized()) return; +bool PISerial::closeDevice() { + if (!isInitialized()) return true; if (isRunning()) { stop(); PIThread::terminate(); @@ -60,10 +76,11 @@ void PISerial::terminate() { #else if (fd != -1) { tcsetattr(fd, TCSANOW, &sdesc); - close(fd); + ::close(fd); fd = -1; } #endif + return true; } @@ -85,79 +102,51 @@ int PISerial::convertSpeed(PISerial::Speed speed) { } -void PISerial::begin() { - allReaded = addSize = curInd = 0; - first = false; - packetSize = headerSize + dataSize; - if (headerSize > 0) mheader.resize(headerSize); - if (!init()) stop(); -} - - -void PISerial::run() { - if (dataSize == 0) return; - while (allReaded < packetSize + addSize) { -#ifdef WINDOWS - WaitCommEvent(hCom, 0, 0); - ReadFile(hCom, &buffer[allReaded], SERIAL_BUFFER_SIZE, &readed, 0); -#else - readed = read(fd, &buffer[allReaded], SERIAL_BUFFER_SIZE); -#endif - allReaded += readed; - } - if (headerSize > 0) { - if (allReaded + curInd >= SERIAL_BUFFER_SIZE) { - memcpy(sbuffer, buffer, SERIAL_BUFFER_SIZE); - memcpy(buffer, &sbuffer[SERIAL_BUFFER_SIZE - packetSize], allReaded); - allReaded = packetSize; - addSize = curInd = 0; +bool PISerial::read(void * data, int size, double timeout_ms) { + if (data == 0) return false; + int ret, all = 0; + if (timeout_ms > 0.) { + setReadIsBlocking(false); + all = ::read(fd, data, 1); + timer.reset(); + while (all < size && timer.elapsed_m() < timeout_ms) { + ret = ::read(fd, &((uchar * )data)[all], size - all); + if (ret > 0) all += ret; + else msleep(1); } - while (!ret_func_header(data, (uchar * )headerPtr, &buffer[curInd], headerSize)) { - curInd++; missed++; - if (curInd > addSize) { - addSize += packetSize; - return; - } - } - memcpy(mheader.data(), &buffer[curInd + headerSize], headerSize); - if (!ret_func(data, &buffer[curInd + headerSize], dataSize)) { - curInd++; missed++; - return; - } - memcpy(sbuffer, buffer, allReaded); - memcpy(buffer, &sbuffer[packetSize + curInd], allReaded); - allReaded -= packetSize + curInd; - curInd = addSize = 0; + return (all == size); } else { - ret_func(data, buffer, dataSize); - memcpy(sbuffer, buffer, allReaded); - memcpy(buffer, &sbuffer[packetSize], allReaded); - allReaded -= packetSize; + setReadIsBlocking(true); + all = ::read(fd, data, 1); + while (all < size) { + ret = ::read(fd, &((uchar * )data)[all], size - all); + if (ret > 0) all += ret; + } + return (all == size); } + return false; } -void PISerial::end() { - terminate(); -} - - -bool PISerial::init() { +bool PISerial::openDevice() { #ifdef WINDOWS - hCom = CreateFileA(devName.stdString().c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); + DWORD da = 0, sm = 0; + if (isReadable()) {ds |= GENERIC_READ; sm |= FILE_SHARE_READ;} + if (isWriteable()) {ds |= GENERIC_WRITE; sm |= FILE_SHARE_WRITE;} + hCom = CreateFileA(path_.data(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); if(hCom == INVALID_HANDLE_VALUE) { - cout << "[PISerial] Unable to open \"" << devName << "\"" << endl; + piCout << "[PISerial] Unable to open \"" << path_ << "\"" << endl; return false; } fd = 0; COMMTIMEOUTS times; - times.ReadIntervalTimeout = 1; + times.ReadIntervalTimeout = vtime; times.ReadTotalTimeoutConstant = 1; times.ReadTotalTimeoutMultiplier = 0; - times.WriteTotalTimeoutConstant = 0; - times.WriteTotalTimeoutMultiplier = 1; + times.WriteTotalTimeoutConstant = 1; + times.WriteTotalTimeoutMultiplier = 0; if (SetCommTimeouts(hCom, ×) == -1) { - cout << "[PISerial] Unable to set timeouts for \"" << devName << "\"" << endl; + piCout << "[PISerial] Unable to set timeouts for \"" << path_ << "\"" << endl; CloseHandle(hCom); fd = -1; return false; @@ -175,15 +164,22 @@ bool PISerial::init() { } desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT; if (SetCommState(hCom, &desc) == -1) { - cout << "[PISerial] Unable to set comm state for \"" << devName << "\"" << endl; + piCout << "[PISerial] Unable to set comm state for \"" << path_ << "\"" << endl; CloseHandle(hCom); fd = -1; return false; } #else - fd = open(devName.data(), O_NOCTTY | O_RDWR); + int om = 0; + switch (mode_) { + case PIIODevice::ReadOnly: om = O_RDONLY; break; + case PIIODevice::WriteOnly: om = O_WRONLY; break; + case PIIODevice::ReadWrite: om = O_RDWR; break; + } + //cout << "init ser " << path_ << " mode " << om << endl; + fd = ::open(path_.data(), O_NOCTTY | om); if(fd == -1) { - cout << "[PISerial] Unable to open \"" << devName << "\"" << endl; + piCout << "[PISerial] Unable to open \"" << path_ << "\"" << endl; return false; } fcntl(fd, F_SETFL, 0); @@ -191,48 +187,47 @@ bool PISerial::init() { tcgetattr(fd, &desc); sdesc = desc; desc.c_iflag = desc.c_oflag = desc.c_lflag = 0; - desc.c_cflag = CLOCAL | CREAD | CSIZE; + desc.c_cflag = CLOCAL | CSIZE | CS8; + if (isReadable()) desc.c_cflag |= CREAD; if (params[PISerial::TwoStopBits]) desc.c_cflag |= CSTOPB; if (params[PISerial::ParityControl]) { desc.c_iflag |= INPCK; desc.c_cflag |= PARENB; if (params[PISerial::ParityOdd]) desc.c_cflag |= PARODD; } - desc.c_cc[VMIN] = 0; - desc.c_cc[VTIME] = 1; + desc.c_cc[VMIN] = 1; + desc.c_cc[VTIME] = vtime; cfsetispeed(&desc, convertSpeed(ispeed)); cfsetospeed(&desc, convertSpeed(ospeed)); if(tcsetattr(fd, TCSANOW, &desc) < 0) { - cout << "[PISerial] Can`t set attributes for \"" << devName << "\"" << endl; - close(fd); + piCout << "[PISerial] Can`t set attributes for \"" << path_ << "\"" << endl; + ::close(fd); return false; } tcflush(fd, TCIOFLUSH); - //cout << "[PISerial] Initialized " << devName << endl; + //piCout << "[PISerial] Initialized " << path_ << endl; #endif return true; } -bool PISerial::send(uchar * data, int size) { - //cout << "[PISerial] send size: " << sizeof(data) << endl; - if (fd == -1) { - //cout << "[PISerial] Can`t write to uninitialized COM" << endl; - return false; +int PISerial::write(const void * data, int max_size, bool wait) { + //piCout << "[PISerial] send size: " << sizeof(data) << endl; + if (fd == -1 || !canWrite()) { + //piCout << "[PISerial] Can`t write to uninitialized COM" << endl; + return -1; } #ifdef WINDOWS DWORD wrote; - WriteFile(hCom, data, size, &wrote, 0); + WriteFile(hCom, data, max_size, &wrote, 0); #else int wrote; - wrote = write(fd, data, size); + wrote = ::write(fd, data, max_size); + if (wait) tcdrain(fd); #endif - if ((int)wrote != size) { - //cout << "[PISerial] Error while sending" << endl; - return false; - } - //cout << "[PISerial] Wrote " << wrote << " bytes in " << devName << endl; - return true; + return (int)wrote; + //piCout << "[PISerial] Error while sending" << endl; + //piCout << "[PISerial] Wrote " << wrote << " bytes in " << path_ << endl; } diff --git a/piserial.h b/piserial.h old mode 100644 new mode 100755 index 2811390b..1b823831 --- a/piserial.h +++ b/piserial.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives COM - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,8 +20,8 @@ #ifndef PISERIAL_H #define PISERIAL_H -#include "pithread.h" -#include "pistring.h" +#include "pitimer.h" +#include "piiodevice.h" #ifndef WINDOWS # include # include @@ -42,16 +42,12 @@ # define B256000 256000 #endif -#define SERIAL_BUFFER_SIZE 4096 - -typedef bool (*SerialFunc)(void * , uchar * , int ); -typedef bool (*SerialHeaderFunc)(void * , uchar * , uchar * , int ); - -class PISerial: public PIThread { +class PISerial: public PIIODevice { public: // slot is any function format "bool (void*, uchar*, int)" // slot_header is any function format "bool (void*, uchar*, uchar*, int)" - PISerial(PIString name = "serial", void * data = 0, SerialFunc slot = 0, SerialHeaderFunc slot_header = headerValidate); + PISerial(const PIString & device, void * data = 0, ReadRetFunc slot = 0); + PISerial(void * data = 0, ReadRetFunc slot = 0); ~PISerial(); enum Parameters {ParityControl = 0x01, ParityOdd = 0x02, TwoStopBits = 0x04}; @@ -69,31 +65,59 @@ public: S115200 = 115200 }; - void setSlot(SerialFunc func) {ret_func = func;} + void setData(void * d) {data = d;} + + //void setSlot(SerialFunc func) {ret_func = func;} void setSpeed(PISerial::Speed speed) {ospeed = ispeed = speed;} void setOutSpeed(PISerial::Speed speed) {ospeed = speed;} void setInSpeed(PISerial::Speed speed) {ispeed = speed;} - void setDevice(const PIString & dev) {devName = dev;} + void setDevice(const PIString & dev) {path_ = dev;} void setParameters(PIFlags parameters) {params = parameters;} - void setData(void * d) {data = d;} - void setReadData(void * headerPtr, int headerSize, int dataSize) {this->headerPtr = headerPtr; this->headerSize = headerSize; this->dataSize = dataSize;} + void setParameter(PISerial::Parameters parameter, bool on = true) {params.setFlag(parameter, on);} + void setVTime(int t) {vtime = t;} - bool send(uchar * data, int size); - bool init(); - bool initialized() const {return fd != -1;} - void terminate(); +#ifdef WINDOWS + void setReadIsBlocking(bool yes) { + COMMTIMEOUTS times; + times.ReadIntervalTimeout = yes ? vtime : MAXDWORD; + times.ReadTotalTimeoutConstant = yes ? 1 : 0; + times.ReadTotalTimeoutMultiplier = 0; + times.WriteTotalTimeoutConstant = 1; + times.WriteTotalTimeoutMultiplier = 0; + if (isOpened()) SetCommTimeouts(hCom, ×); + } +#else + void setReadIsBlocking(bool yes) {if (isOpened()) fcntl(fd, F_SETFL, yes ? 0 : O_NONBLOCK);} +#endif - PIByteArray lastHeader() {return mheader;} - ullong missedBytes() const {return missed;} - ullong missedPackets() const {return (packetSize == 0 ? 0 : missed / packetSize);} + const PIString & device() const {return path_;} + PISerial::Speed outSpeed() const {return ospeed;} + PISerial::Speed inSpeed() const {return ispeed;} + int VTime() const {return vtime;} -private: +#ifdef WINDOWS + int read(void * read_to, int max_size) { + if (!canRead()) return -1; + WaitCommEvent(hCom, 0, 0); + ReadFile(hCom, read_to, max_size, &readed, 0); + return readed; + } +#else + int read(void * read_to, int max_size) {if (!canRead()) return -1; return ::read(fd, read_to, max_size);} +#endif + bool read(void * data, int size, double timeout_ms); + + int write(const void * data, int max_size, bool wait); + int write(const void * data, int max_size) {return write(data, max_size, false);} + bool send(const void * data, int size, bool wait = false) {return (write(data, size, wait) == size);} + + +protected: int convertSpeed(PISerial::Speed speed); static bool headerValidate(void * d, uchar * src, uchar * rec, int size) {for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;} - void begin(); - void run(); - void end(); + bool openDevice(); + bool closeDevice(); #ifdef WINDOWS DCB desc, sdesc; @@ -103,18 +127,11 @@ private: termios desc, sdesc; uint readed; #endif - int fd; + int fd, vtime; PISerial::Speed ospeed, ispeed; - PIString devName; - SerialFunc ret_func; - SerialHeaderFunc ret_func_header; - uchar buffer[SERIAL_BUFFER_SIZE], sbuffer[SERIAL_BUFFER_SIZE]; - PIByteArray mheader; + PITimer timer; void * headerPtr, * data; - int dataSize, headerSize, packetSize, allReaded, addSize, curInd; - ullong missed; PIFlags params; - bool first; }; diff --git a/pisignals.cpp b/pisignals.cpp old mode 100644 new mode 100755 index 2c955182..12f4705c --- a/pisignals.cpp +++ b/pisignals.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Signals - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/pisignals.h b/pisignals.h old mode 100644 new mode 100755 index 6fb83e45..43b58119 --- a/pisignals.h +++ b/pisignals.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Signals - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -50,23 +50,23 @@ public: #endif All = 0xFFFFF }; - + typedef void (*SignalEvent)(PISignals::Signal); // slot is any function format "void (PISignals::Signal)" static void setSlot(SignalEvent slot) {ret_func = slot;} static void grabSignals(PIFlags signals_); static void raiseSignal(PISignals::Signal signal) {raise(signalCode(signal));} - + private: PISignals() {ret_func = 0;} ~PISignals() {} - + static int signalCode(PISignals::Signal signal); static PISignals::Signal signalFromCode(int signal); static void signal_event(int signal); - + static SignalEvent ret_func; - + }; diff --git a/pistring.cpp b/pistring.cpp old mode 100644 new mode 100755 index 9689f096..cb1329a9 --- a/pistring.cpp +++ b/pistring.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives String - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -83,7 +83,7 @@ PIString & PIString::operator +=(const wchar_t * str) { break; } } - delete c; + delete[] c; return *this; } @@ -313,6 +313,30 @@ PIString PIString::toLowerCase() const { } +int PIString::lengthAscii() const { + int j = 0; + for (int i = 0; i < size_s(); ++i, ++j) + if (!at(i).isAscii()) ++j; + return j; +} + + +const char * PIString::data() const { + PIByteArray & d_(*(const_cast(&data_))); + d_.clear(); + for (int i = 0, j = 0; i < size_s(); ++i, ++j) { + if (at(i).isAscii()) + d_.push_back(uchar(at(i).toAscii())); + else { + d_.push_back((at(i).toCharPtr()[0])); ++j; + d_.push_back((at(i).toCharPtr()[1])); + } + } + d_.push_back(uchar('\0')); + return (const char * )d_.data(); +} + + string PIString::convertToStd() const { string s; if (size() > 0) { @@ -332,7 +356,7 @@ string PIString::convertToStd() const { char PIString::toChar() const { PIString s(toNativeDecimalPoints()); char v; - sscanf(s.stdString().c_str(), "%c", &v); + sscanf(s.data(), "%c", &v); return v; } @@ -340,9 +364,9 @@ char PIString::toChar() const { short PIString::toShort() const { PIString s(trimmed().toLowerCase().toNativeDecimalPoints()); short v; - if (s.left(2) == "0x") {sscanf(s.stdString().c_str(), "%hx", &v); return v;} - if (s.left(1) == "0") {sscanf(s.stdString().c_str(), "%ho", &v); return v;} - sscanf(s.stdString().c_str(), "%hd", &v); + if (s.left(2) == "0x") {sscanf(s.data(), "%hx", &v); return v;} + if (s.left(1) == "0") {sscanf(s.data(), "%ho", &v); return v;} + sscanf(s.data(), "%hd", &v); return v; } @@ -350,9 +374,9 @@ short PIString::toShort() const { int PIString::toInt() const { PIString s(trimmed().toLowerCase().toNativeDecimalPoints()); int v; - if (s.left(2) == "0x") {sscanf(s.stdString().c_str(), "%x", &v); return v;} - if (s.left(1) == "0") {sscanf(s.stdString().c_str(), "%o", &v); return v;} - sscanf(s.stdString().c_str(), "%d", &v); + if (s.left(2) == "0x") {sscanf(s.data(), "%x", &v); return v;} + if (s.left(1) == "0") {sscanf(s.data(), "%o", &v); return v;} + sscanf(s.data(), "%d", &v); return v; } @@ -360,9 +384,9 @@ int PIString::toInt() const { long PIString::toLong() const { PIString s(trimmed().toLowerCase().toNativeDecimalPoints()); long v; - if (s.left(2) == "0x") {sscanf(s.stdString().c_str(), "%lx", &v); return v;} - if (s.left(1) == "0") {sscanf(s.stdString().c_str(), "%lo", &v); return v;} - sscanf(s.stdString().c_str(), "%ld", &v); + if (s.left(2) == "0x") {sscanf(s.data(), "%lx", &v); return v;} + if (s.left(1) == "0") {sscanf(s.data(), "%lo", &v); return v;} + sscanf(s.data(), "%ld", &v); return v; } @@ -370,9 +394,9 @@ long PIString::toLong() const { llong PIString::toLLong() const { PIString s(trimmed().toLowerCase().toNativeDecimalPoints()); llong v; - if (s.left(2) == "0x") {sscanf(s.stdString().c_str(), "%llx", &v); return v;} - if (s.left(1) == "0") {sscanf(s.stdString().c_str(), "%llo", &v); return v;} - sscanf(s.stdString().c_str(), "%lld", &v); + if (s.left(2) == "0x") {sscanf(s.data(), "%llx", &v); return v;} + if (s.left(1) == "0") {sscanf(s.data(), "%llo", &v); return v;} + sscanf(s.data(), "%lld", &v); return v; } diff --git a/pistring.h b/pistring.h old mode 100644 new mode 100755 index 9aa44e80..7f1d784f --- a/pistring.h +++ b/pistring.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives String - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -126,8 +126,12 @@ public: PIString & insert(const int index, const char * c) {return insert(index, PIString(c));} PIString & expandRightTo(const int len, const PIChar & c) {if (len > length()) resize(len, c); return *this;} PIString & expandLeftTo(const int len, const PIChar & c) {if (len > length()) insert(0, PIString(len - length(), c)); return *this;} + PIString & reverse() {PIString str(*this); clear(); piForeachR (const PIChar & c, str) push_back(c); return *this;} + PIString reversed() const {PIString str(*this); str.reverse(); return str;} - const char * data() {return convertToStd().c_str();} + //const char * data() {return convertToStd().c_str();} + int lengthAscii() const; + const char * data() const; const string stdString() const {return convertToStd();} wstring stdWString() const {return convertToWString();} PIByteArray toByteArray() {string s(convertToStd()); return PIByteArray(s.c_str(), s.length());} @@ -140,7 +144,7 @@ public: #else PIString toNativeDecimalPoints() const {PIString s(*this); if (currentLocale == 0) return s; return s.replaceAll(".", currentLocale->decimal_point);} #endif - + int find(const char str, const int start = 0) const; int find(const PIString str, const int start = 0) const; int find(const char * str, const int start = 0) const {return find(PIString(str), start);} @@ -153,15 +157,15 @@ public: int length() const {return size();} bool isEmpty() const {return (size() == 0 || *this == "");} - bool toBool() const {PIString s(*this); if (atof(s.toNativeDecimalPoints().stdString().c_str()) > 0. || s.trimmed().toLowerCase() == "true") return true; return false;} + bool toBool() const {PIString s(*this); if (atof(s.toNativeDecimalPoints().data()) > 0. || s.trimmed().toLowerCase() == "true") return true; return false;} char toChar() const; short toShort() const; int toInt() const; long toLong() const; llong toLLong() const; - float toFloat() const {PIString s(*this); return (float)atof(s.toNativeDecimalPoints().stdString().c_str());} - double toDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().stdString().c_str());} - ldouble toLDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().stdString().c_str());} + float toFloat() const {PIString s(*this); return (float)atof(s.toNativeDecimalPoints().data());} + double toDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());} + ldouble toLDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());} //inline PIString & setNumber(const char value) {clear(); *this += itos(value); return *this;} PIString & setNumber(const int value) {clear(); *this += itos(value); return *this;} @@ -188,11 +192,14 @@ private: string convertToStd() const; wstring convertToWString() const {wstring s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toWChar()); return s;} + PIByteArray data_; //string std_string; + //wstring std_wstring; }; inline std::ostream & operator <<(std::ostream & s, const PIString & v) {for (int i = 0; i < v.length(); ++i) s << v[i]; return s;} +inline std::istream & operator >>(std::istream & s, PIString & v) {string ss; s >> ss; v << PIString(ss); return s;} inline PIString operator +(const PIString & str, const PIString & f) {PIString s(str); s += f; return s;} diff --git a/pisystemmonitor.cpp b/pisystemmonitor.cpp old mode 100644 new mode 100755 index 0db64b1f..661ed91d --- a/pisystemmonitor.cpp +++ b/pisystemmonitor.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Process resource monitor - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -39,10 +39,10 @@ bool PISystemMonitor::startOnProcess(int pID) { stop(); pID_ = pID; #ifndef WINDOWS - file.open("/proc/" + PIString::fromNumber(pID_) + "/stat", PIFile::Read); - filem.open("/proc/" + PIString::fromNumber(pID_) + "/statm", PIFile::Read); + file.open("/proc/" + PIString::fromNumber(pID_) + "/stat", PIIODevice::ReadOnly); + filem.open("/proc/" + PIString::fromNumber(pID_) + "/statm", PIIODevice::ReadOnly); if (!file.isOpened()) { - cout << "[PISystemMonitor] Can`t find process with ID = " << pID_ << "!" << endl; + piCout << "[PISystemMonitor] Can`t find process with ID = " << pID_ << "!" << endl; return false; } cycle = -1; @@ -92,7 +92,7 @@ void PISystemMonitor::run() { } stat.priority = sl[16].toInt(); stat.threads = sl[18].toInt(); - + str = filem.readAll(true); sl = str.split(" "); if (sl.size_s() < 5) return; @@ -101,7 +101,7 @@ void PISystemMonitor::run() { stat.share_memsize = sl[2].toLong() * page_size; stat.data_memsize = sl[5].toLong() * page_size; stat.physical_memsize = stat.resident_memsize - stat.share_memsize; - + stat.physical_memsize_readable = PIString::readableSize(stat.physical_memsize); stat.resident_memsize_readable = PIString::readableSize(stat.resident_memsize); stat.share_memsize_readable = PIString::readableSize(stat.share_memsize); diff --git a/pisystemmonitor.h b/pisystemmonitor.h old mode 100644 new mode 100755 index 1f997364..d721646d --- a/pisystemmonitor.h +++ b/pisystemmonitor.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Process resource monitor - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/pithread.cpp b/pithread.cpp old mode 100644 new mode 100755 index 0ebdc930..f9d796df --- a/pithread.cpp +++ b/pithread.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Thread - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,23 +20,26 @@ #include "pithread.h" -PIThread::PIThread(bool startNow, int timer_delay): PIObject() { +PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay): PIObject() { piMonitor.threads++; + data_ = data; + ret_func = func; + running = lockRun = false; + priority_ = piNormal; + timer = timer_delay; + if (startNow) start(timer_delay); +} + + +PIThread::PIThread(bool startNow, int timer_delay): PIObject() { + piMonitor.threads++; + ret_func = 0; running = lockRun = false; priority_ = piNormal; timer = timer_delay; - /*addEvent("started"); - addEvent("stopped"); - addEventHandler(HANDLER(PIThread, start)); - addEventHandler(HANDLER(PIThread, startOnce)); - addEventHandler(HANDLER(PIThread, stop)); - addEventHandler(HANDLER(PIThread, terminate));*/ if (startNow) start(timer_delay); } -#ifndef WINDOWS -#else -#endif PIThread::~PIThread() { piMonitor.threads--; @@ -57,14 +60,17 @@ bool PIThread::start(int timer_delay) { pthread_attr_init(&attr); pthread_attr_setschedparam(&attr, &sparam); if (pthread_create(&thread, &attr, thread_function, this) == 0) { + setPriority(priority_); running = true; return true; } #else thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, this, 0, 0); - if (thread == 0) - return false; - setPriority(priority_); + if (thread != 0) { + setPriority(priority_); + running = true; + return true; + } #endif return false; } @@ -76,13 +82,18 @@ bool PIThread::startOnce() { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setschedparam(&attr, &sparam); - if (pthread_create(&thread, &attr, thread_function_once, this) == 0) + if (pthread_create(&thread, &attr, thread_function_once, this) == 0) { + setPriority(priority_); + running = true; return true; + } #else thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function_once, this, 0, 0); - if (thread == 0) + if (thread != 0) { + setPriority(priority_); + running = true; return false; - setPriority(priority_); + } #endif return false; } @@ -110,6 +121,7 @@ void * PIThread::thread_function(void * t) { while (!ct->terminating) { if (ct->lockRun) ct->mutex_.lock(); ct->run(); + if (ct->ret_func != 0) ct->ret_func(ct->data_); if (ct->lockRun) ct->mutex_.unlock(); if (ct->timer > 0) msleep(ct->timer); } @@ -133,6 +145,7 @@ void * PIThread::thread_function_once(void * t) { raiseEvent(ct, "started"); if (ct->lockRun) ct->mutex_.lock(); ct->run(); + if (ct->ret_func != 0) ct->ret_func(ct->data_); if (ct->lockRun) ct->mutex_.unlock(); raiseEvent(ct, "stopped"); ct->end(); diff --git a/pithread.h b/pithread.h old mode 100644 new mode 100755 index 9371d335..b01d4a02 --- a/pithread.h +++ b/pithread.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Thread - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,8 +30,11 @@ inline void msleep(int msecs) {Sleep(msecs);} inline void msleep(int msecs) {usleep(msecs * 1000);} #endif +typedef void (*ThreadFunc)(void * ); + class PIThread: public PIObject { public: + PIThread(void * data, ThreadFunc func, bool startNow = false, int timer_delay = -1); PIThread(bool startNow = false, int timer_delay = -1); ~PIThread(); @@ -52,11 +55,16 @@ public: //bool start(int timer_delay = -1); EVENT_HANDLER0(PIThread, bool, start) {return start(-1);} EVENT_HANDLER1(PIThread, bool, start, int, timer_delay); + EVENT_HANDLER1(PIThread, bool, start, ThreadFunc, func) {ret_func = func; return start(-1);} + EVENT_HANDLER2(PIThread, bool, start, ThreadFunc, func, int, timer_delay) {ret_func = func; return start(timer_delay);} EVENT_HANDLER0(PIThread, bool, startOnce); + EVENT_HANDLER1(PIThread, bool, startOnce, ThreadFunc, func) {ret_func = func; return startOnce();} EVENT_HANDLER0(PIThread, void, stop) {stop(false);} EVENT_HANDLER1(PIThread, void, stop, bool, wait) {terminating = true; if (wait) waitForFinish();} EVENT_HANDLER0(PIThread, void, terminate) {terminate(false);} EVENT_HANDLER1(PIThread, void, terminate, bool, hard); + void setData(void * d) {data_ = d;} + void setSlot(ThreadFunc func) {ret_func = func;} void setPriority(PIThread::Priority prior); PIThread::Priority priority() const {return priority_;} bool isRunning() const {return running;} @@ -69,19 +77,20 @@ public: EVENT_HANDLER0(PIThread, void, unlock) {mutex_.unlock();} PIMutex & mutex() {return mutex_;} -private: - virtual void begin() {;} // executed at start - virtual void run() {;} // main loop - virtual void end() {;} // executed at finish - protected: static void * thread_function(void * t); static void * thread_function_once(void * t); + virtual void begin() {;} // executed at start + virtual void run() {;} // main loop executed with "timer_delay" timeout + virtual void end() {;} // executed at finish + volatile bool terminating, running, lockRun; int timer, policy; + void * data_; PIMutex mutex_; PIThread::Priority priority_; + ThreadFunc ret_func; #ifndef WINDOWS pthread_t thread; sched_param sparam; diff --git a/pitimer.cpp b/pitimer.cpp index 0071cd57..802df41d 100644 --- a/pitimer.cpp +++ b/pitimer.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Timer - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -56,11 +56,15 @@ PITimer::~PITimer() { #ifndef WINDOWS void PITimer::start(double msecs) { - if (ti == 0) return; + if (ti == 0 || msecs < 0) return; spec.it_interval.tv_nsec = ((int)(msecs * 1000) % 1000000) * 1000; spec.it_interval.tv_sec = (time_t)(msecs / 1000); spec.it_value = spec.it_interval; ti = timer_create(CLOCK_REALTIME, &se, &timer); + if (ti == -1) { + piCout << "[PITimer] Can`t create timer for " << msecs << " msecs: " << errorString() << endl; + return; + } timer_settime(timer, 0, &spec, 0); running = true; } @@ -119,11 +123,10 @@ void PITimer::run() { double PITimer::elapsed_n() { #ifdef WINDOWS t_cur = GetCurrentTime(); - return (t_cur * 1000000. - t_st * 1000000.); + return (t_cur - t_st) * 1000000.; #else clock_gettime(0, &t_cur); - return (t_cur.tv_sec * 1.e+9 + t_cur.tv_nsec) - - (t_st.tv_sec * 1.e+9 + t_st.tv_nsec); + return (t_cur.tv_sec - t_st.tv_sec) * 1.e+9 + (t_cur.tv_nsec - t_st.tv_nsec); #endif } @@ -131,11 +134,10 @@ double PITimer::elapsed_n() { double PITimer::elapsed_u() { #ifdef WINDOWS t_cur = GetCurrentTime(); - return (t_cur * 1000. - t_st * 1000.); + return (t_cur - t_st) * 1000.; #else clock_gettime(0, &t_cur); - return (t_cur.tv_sec * 1.e+6 + (t_cur.tv_nsec / 1.e+3)) - - (t_st.tv_sec * 1.e+6 + (t_st.tv_nsec / 1.e+3)); + return (t_cur.tv_sec - t_st.tv_sec) * 1.e+6 + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+3; #endif } @@ -146,8 +148,7 @@ double PITimer::elapsed_m() { return (double)(t_cur - t_st); #else clock_gettime(0, &t_cur); - return (t_cur.tv_sec * 1.e+3 + (t_cur.tv_nsec / 1.e+6)) - - (t_st.tv_sec * 1.e+3 + (t_st.tv_nsec / 1.e+6)); + return (t_cur.tv_sec - t_st.tv_sec) * 1.e+3 + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+6; #endif } @@ -155,11 +156,102 @@ double PITimer::elapsed_m() { double PITimer::elapsed_s() { #ifdef WINDOWS t_cur = GetCurrentTime(); - return (t_cur / 1000. - t_st / 1000.); + return (t_cur - t_st) / 1000.; #else clock_gettime(0, &t_cur); - return (t_cur.tv_sec + (t_cur.tv_nsec / 1.e+9)) - - (t_st.tv_sec + (t_st.tv_nsec / 1.e+9)); + return (t_cur.tv_sec - t_st.tv_sec) + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+9; +#endif +} + + +double PITimer::reset_time_n() { +#ifdef WINDOWS + t_cur = GetCurrentTime(); + return t_st * 1000000.; +#else + clock_gettime(0, &t_cur); + return t_st.tv_sec * 1.e+9 + t_st.tv_nsec; +#endif +} + + +double PITimer::reset_time_u() { +#ifdef WINDOWS + t_cur = GetCurrentTime(); + return (t_cur - t_st) * 1000.; +#else + clock_gettime(0, &t_cur); + return t_st.tv_sec * 1.e+6 + t_st.tv_nsec / 1.e+3; +#endif +} + + +double PITimer::reset_time_m() { +#ifdef WINDOWS + t_cur = GetCurrentTime(); + return (double)(t_cur - t_st); +#else + clock_gettime(0, &t_cur); + return t_st.tv_sec * 1.e+3 + t_st.tv_nsec / 1.e+6; +#endif +} + + +double PITimer::reset_time_s() { +#ifdef WINDOWS + t_cur = GetCurrentTime(); + return (t_cur - t_st) / 1000.; +#else + clock_gettime(0, &t_cur); + return t_st.tv_sec + t_st.tv_nsec / 1.e+9; +#endif +} + + +double PITimer::elapsed_system_n() { +#ifdef WINDOWS + long t_cur = GetCurrentTime(); + return (t_cur * 1000000.); +#else + timespec t_cur; + clock_gettime(0, &t_cur); + return (t_cur.tv_sec * 1.e+9 + t_cur.tv_nsec); +#endif +} + + +double PITimer::elapsed_system_u() { +#ifdef WINDOWS + long t_cur = GetCurrentTime(); + return (t_cur * 1000.); +#else + timespec t_cur; + clock_gettime(0, &t_cur); + return (t_cur.tv_sec * 1.e+6 + (t_cur.tv_nsec / 1.e+3)); +#endif +} + + +double PITimer::elapsed_system_m() { +#ifdef WINDOWS + long t_cur = GetCurrentTime(); + return (double)t_cur; +#else + timespec t_cur; + clock_gettime(0, &t_cur); + return (t_cur.tv_sec * 1.e+3 + (t_cur.tv_nsec / 1.e+6)); +#endif +} + + +double PITimer::elapsed_system_s() { +#ifdef WINDOWS + long t_cur = GetCurrentTime(); + return (t_cur / 1000.); +#else + timespec t_cur; + clock_gettime(0, &t_cur); + return (t_cur.tv_sec + (t_cur.tv_nsec / 1.e+9)); #endif } @@ -186,6 +278,31 @@ PIDate currentDate() { } +PIString PITime::toString(const PIString & format) { + PIString ts = format; + ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0')); + ts.replace("h", PIString::fromNumber(hours)); + ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0')); + ts.replace("m", PIString::fromNumber(minutes)); + ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0')); + ts.replace("s", PIString::fromNumber(seconds)); + return ts; +} + + +PIString PIDate::toString(const PIString & format) { + PIString ts = format; + ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0')); + ts.replace("yy", PIString::fromNumber(year).expandLeftTo(2, '0')); + ts.replace("y", PIString::fromNumber(year)); + ts.replace("mm", PIString::fromNumber(month).expandLeftTo(2, '0')); + ts.replace("m", PIString::fromNumber(month)); + ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0')); + ts.replace("d", PIString::fromNumber(day)); + return ts; +} + + PIString time2string(const PITime & time, const PIString & format) { PIString ts = format; ts.replace("hh", PIString::fromNumber(time.hours).expandLeftTo(2, '0')); diff --git a/pitimer.h b/pitimer.h index 4a846ebc..8dc21ac2 100644 --- a/pitimer.h +++ b/pitimer.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Timer - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,12 +32,14 @@ struct PITime { int seconds; int minutes; int hours; + PIString toString(const PIString & format = "h:mm:ss"); }; struct PIDate { int day; int month; int year; // since 1900 + PIString toString(const PIString & format = "d.mm.yyyy"); }; class PITimer @@ -50,7 +52,7 @@ class PITimer public: PITimer(TimerEvent slot = 0, void * data = 0); ~PITimer(); - + void setData(void * data_) {data = data_;} void setSlot(TimerEvent slot) {ret_func = slot;} #ifdef WINDOWS @@ -76,15 +78,25 @@ public: double elapsed_u(); // microseconds double elapsed_m(); // miliseconds double elapsed_s(); // seconds - + + double reset_time_n(); // nanoseconds + double reset_time_u(); // microseconds + double reset_time_m(); // miliseconds + double reset_time_s(); // seconds + + static double elapsed_system_n(); // nanoseconds + static double elapsed_system_u(); // microseconds + static double elapsed_system_m(); // miliseconds + static double elapsed_system_s(); // seconds + private: #ifdef WINDOWS void run(); - - long int t_st, t_cur; + + long t_st, t_cur; #else static void timer_event(sigval e); - + bool running; volatile bool lockRun; PIMutex mutex_; @@ -100,16 +112,16 @@ private: int delim; int tick; }; - + void * data; TimerEvent ret_func; PIVector ret_funcs; - + }; PITime currentTime(); PIDate currentDate(); -PIString time2string(const PITime & time, const PIString & format = "h:mm:ss"); -PIString date2string(const PIDate & date, const PIString & format = "d.mm.yyyy"); +PIString time2string(const PITime & time, const PIString & format = "h:mm:ss"); // obsolete, use PITime.toString() instead +PIString date2string(const PIDate & date, const PIString & format = "d.mm.yyyy"); // obsolete, use PITime.toString() instead #endif // PITIMER_H diff --git a/pivariable.cpp b/pivariable.cpp old mode 100644 new mode 100755 index d7b7f1e3..5890ae1d --- a/pivariable.cpp +++ b/pivariable.cpp @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Variable, Struct (simple serialization) - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,6 +40,7 @@ bool PIVariant::operator ==(const PIVariant & v) const { case PIVariant::String: return vString == v.vString; case PIVariant::StringList: return vStringList == v.vStringList; }; + return false; } @@ -84,6 +85,7 @@ PIString PIVariant::stringValue() const { case PIVariant::String: return vString; case PIVariant::StringList: return vStringList.join("%|%"); }; + return vString; } @@ -214,7 +216,7 @@ void PIVariable::writeVariable(char * dest) { void PIStruct::parseFile(const PIString & file) { - PIConfig conf(file, PIFile::Read); + PIConfig conf(file, PIIODevice::ReadOnly); PIVariable var; PIString ts; uint sz = 0; diff --git a/pivariable.h b/pivariable.h old mode 100644 new mode 100755 index 32855e9d..ba35da6b --- a/pivariable.h +++ b/pivariable.h @@ -1,7 +1,7 @@ /* PIP - Platform Independent Primitives Variable, Struct (simple serialization) - Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com + Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/Описание.odt b/Описание.odt old mode 100644 new mode 100755 index 6e0a6c27..3ccc99e6 Binary files a/Описание.odt and b/Описание.odt differ diff --git a/Описание.pdf b/Описание.pdf old mode 100644 new mode 100755 index 2a7b0ddc..1ed384af Binary files a/Описание.pdf and b/Описание.pdf differ