15.10.2012 - version 0.2.0 - PIIODevice - base of file, ethernet, serial and packets extractor. PIEthernet now support also TCP (client and server). PIConsole now can align labels in each column individually.

This commit is contained in:
peri4
2012-10-15 23:36:18 +04:00
parent 5558add03e
commit cfc5eed75e
64 changed files with 1879 additions and 867 deletions

View File

@@ -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) 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] [CMake]
BuildDirs=/home/peri4/pprojects/pip/ Build Directory Count=1
CMakeDir=/usr/share/cmake/Modules CMakeDir=/usr/share/cmake/Modules
Current CMake Binary=file:///usr/bin/cmake Current Build Directory Index=0
CurrentBuildDir=file:///home/peri4/pprojects/pip/
CurrentBuildType=Debug
CurrentInstallDir=
ProjectRootRelative=./ 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]
Launch Configurations=Launch Configuration 0 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) 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 Dependency Action=Build
EnvironmentGroup=default EnvironmentGroup=default
Executable= Executable=file:///home/peri4/pprojects/pip/pip_test
External Terminal=konsole --noclose --workdir %workdir -e %exe External Terminal=konsole --noclose --workdir %workdir -e %exe
Project Target=pip,pip_test Project Target=
Use External Terminal=false Use External Terminal=false
Working Directory= Working Directory=
isExecutable=false isExecutable=true
[MakeBuilder] [MakeBuilder]
Number Of Jobs=5 Number Of Jobs=8
[Project] [Project]
VersionControlSupport=kdevgit VersionControlSupport=kdevgit

View File

@@ -1,6 +1,7 @@
project(pip) project(pip)
find_package(Qt4)
cmake_minimum_required(VERSION 2.6) 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") file(GLOB CPPS "pi*.cpp")
if (${WIN32}) if (${WIN32})
add_definitions(-Wall -O2) add_definitions(-Wall -O2)
@@ -17,5 +18,5 @@ add_executable(pip_test "main.cpp")
if (${WIN32}) if (${WIN32})
target_link_libraries(pip_test pthread ws2_32 pip) target_link_libraries(pip_test pthread ws2_32 pip)
else (${WIN32}) else (${WIN32})
target_link_libraries(pip_test pthread rt pip) target_link_libraries(pip_test pthread rt pip ${QT_QTCORE_LIBRARY})
endif (${WIN32}) endif (${WIN32})

107
main.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Test program 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 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 it under the terms of the GNU General Public License as published by
@@ -117,66 +117,67 @@ public:
}; };
struct Packet {
#pragma pack(push, 1) int from;
struct Data { int to;
ushort header; float data;
int counter; int cs;
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;
}; };
Prot p; bool retH(void * d, uchar * src, uchar * rec, int size) {
return (*((int*)rec)) == 1;
};
void key(char k, void*) { bool retF(void * d, uchar * data, int size) {
switch (k) { cout << "rec " << size << endl;
case '0': p.setSenderData(&p.send, sizeof(p.send)); break; return true;
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;
}
}
PIConsole c(false, key);
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
c.enableExitCapture(); /*Packet p, mp;
c.addVariable("prot", &p); p.from = mp.from = 1;
if (argc > 1) c.start(); p.to = mp.to = 2;
c.waitForFinish(); PISerial ser("/dev/ttyS0");
c.stop(); 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); exit(0);
/*
vec<int> my_v; vector<int> stl_v; QVector<int> 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 r_string = true, r_thread = true, r_mutex = true, r_timer = true, r_file = true, r_eval = true, r_event = true;
bool succ = true; bool succ = true;
cout << "== PIP test program ==" << endl; cout << "== PIP test program ==" << endl;
@@ -239,7 +240,7 @@ int main(int argc, char * argv[]) {
else cout << "== Fail ==" << endl; else cout << "== Fail ==" << endl;
cout << endl << "== File test ==" << 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 "; cout << " file \"" << file.path() << "\" is ";
if (!file.isOpened()) cout << "not "; if (!file.isOpened()) cout << "not ";
cout << "opened" << endl; cout << "opened" << endl;

2
pibitarray.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Bit array 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 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 it under the terms of the GNU General Public License as published by

2
pibytearray.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Byte array 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 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 it under the terms of the GNU General Public License as published by

4
pibytearray.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Byte array 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 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 it under the terms of the GNU General Public License as published by
@@ -96,6 +96,8 @@ public:
PIByteArray(const uint size) {resize(size);} 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(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 & convertToBase64();
PIByteArray & convertFromBase64(); PIByteArray & convertFromBase64();
PIByteArray toBase64() {PIByteArray ba(*this); ba.convertToBase64(); return ba;} PIByteArray toBase64() {PIByteArray ba(*this); ba.convertToBase64(); return ba;}

2
pichar.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Unicode char 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 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 it under the terms of the GNU General Public License as published by

4
picli.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Command-Line Parser 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 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 it under the terms of the GNU General Public License as published by
@@ -69,7 +69,7 @@ void PICLI::parse() {
_args_opt << cra; _args_opt << cra;
continue; continue;
} }
cout << "[PICli] Arguments overflow, \"" << cra << "\" ignored" << endl; piCout << "[PICli] Arguments overflow, \"" << cra << "\" ignored" << endl;
} }
if (last == 0 ? false : last->has_value) { if (last == 0 ? false : last->has_value) {
last->value = cra; last->value = cra;

2
picli.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Command-Line Parser 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 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 it under the terms of the GNU General Public License as published by

2
picodec.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Text codings coder, based on "iconv" 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 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 it under the terms of the GNU General Public License as published by

6
picodec.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Text codings coder, based on "iconv" 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 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 it under the terms of the GNU General Public License as published by
@@ -25,8 +25,8 @@
class PICodec: private PIProcess class PICodec: private PIProcess
{ {
public: public:
PICodec(): PIProcess() {setGrabOutput(true); tf = PIFile::openTemporary(PIFile::New | PIFile::Read | PIFile::Write); tf.open();} 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(PIFile::New | PIFile::Read | PIFile::Write);} PICodec(const PIString & from, const PIString & to): PIProcess() {setCodings(from, to); tf = PIFile::openTemporary(PIIODevice::ReadWrite);}
~PICodec() {tf.remove();} ~PICodec() {tf.remove();}
void setFromCoding(const PIString & from) {c_from = from;} void setFromCoding(const PIString & from) {c_from = from;}

16
piconfig.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Config parser 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 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 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> mode): PIFile(path, mode) { PIConfig::PIConfig(const PIString & path, PIIODevice::DeviceMode mode): PIFile(path, mode) {
delim = "."; delim = ".";
root.delim = delim; root.delim = delim;
empty.delim = delim; empty.delim = delim;
empty._parent = 0; empty._parent = 0;
if (!isOpened() && (mode[Write] || mode[New])) if (!isOpened())
open(path, Read | Write | New); open(path, mode);
parse(); parse();
} }
@@ -233,7 +233,7 @@ void PIConfig::addEntry(const PIString & name, const PIString & value, const PIS
} else entry = te; } else entry = te;
} }
PIConfig::Branch ch = entry->_children; 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()); te = (entry->isLeaf() ? 0 : ch.back());
ce = new Entry(); ce = new Entry();
ce->delim = delim; 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; if (toRoot) ce->_line = other.size_s() - 1;
else { else {
ch = entry->_parent->_children; ch = entry->_parent->_children;
std::sort(ch.begin(), ch.end(), PIConfig::Entry::compare); ch.sort(PIConfig::Entry::compare);
ce->_line = ch.back()->_line + 1; 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 (b[i] == e) found = true;
} }
if (!leaf) return; if (!leaf) return;
e->_parent->_children.remove(e); e->_parent->_children.removeOne(e);
b.remove(e); b.removeOne(e);
delete e; delete e;
} }

11
piconfig.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Config parser 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 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 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 Entry;
friend class Branch; friend class Branch;
public: public:
PIConfig(const PIString & path, PIFlags<Mode> mode = Read | Write); PIConfig(const PIString & path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
~PIConfig() {piForeach (Entry * i, root._children) deleteEntry(i);} ~PIConfig() {piForeach (Entry * i, root._children) deleteEntry(i); close();}
class Entry; class Entry;
@@ -151,7 +151,8 @@ public:
operator PIStringList() {return _value.split("%|%");} operator PIStringList() {return _value.split("%|%");}
private: 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; bool entryExists(const Entry * e, const PIString & name) const;
void buildLine() {_all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment;} void buildLine() {_all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment;}
void clear() {_children.clear(); _name = _value = _type = _comment = _all = PIString(); _line = 0; _parent = 0;} void clear() {_children.clear(); _name = _value = _type = _comment = _all = PIString(); _line = 0; _parent = 0;}
@@ -196,7 +197,7 @@ public:
bool isEntryExists(const PIString & name) const {return entryExists(&root, name);} bool isEntryExists(const PIString & name) const {return entryExists(&root, name);}
Branch allTree() {Branch b; piForeach (Entry * i, root._children) b << i; return b;} 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); int entryIndex(const PIString & name);
PIString getName(uint number) {return entryByIndex(number)._name;} PIString getName(uint number) {return entryByIndex(number)._name;}

195
piconsole.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Console output/input 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 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 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; ret_func = slot;
num_format = 0; num_format = 0;
cur_tab = width = height = pwidth = pheight = my = 0; cur_tab = width = height = pwidth = pheight = my = 0;
def_align = Nothing;
#ifdef WINDOWS #ifdef WINDOWS
ulcoord.X = ulcoord.Y = 0; ulcoord.X = ulcoord.Y = 0;
hOut = GetStdHandle(STD_OUTPUT_HANDLE); hOut = GetStdHandle(STD_OUTPUT_HANDLE);
@@ -142,7 +143,7 @@ void PIConsole::stop(bool clear) {
if (clear) clearScreen(); if (clear) clearScreen();
moveTo(0, my + 4); moveTo(0, my + 4);
showCursor(); showCursor();
couts(fstr(Normal).stdString()); couts(fstr(Normal));
#ifdef WINDOWS #ifdef WINDOWS
SetConsoleMode(hOut, smode); SetConsoleMode(hOut, smode);
SetConsoleTextAttribute(hOut, dattr); SetConsoleTextAttribute(hOut, dattr);
@@ -243,7 +244,7 @@ PIString PIConsole::fstr(PIFlags<PIConsole::Format> f) {
#define fprint(x) switch (num_format) {case (3): return printf("%e", x); break; default: return printf("%.5g", x); break;} #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;} #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 char * v) {return printf("%s", v);}
inline int PIConsole::couts(const bool v) {return (v ? printf("true") : printf("false"));} inline int PIConsole::couts(const bool v) {return (v ? printf("true") : printf("false"));}
inline int PIConsole::couts(const char v) {return printf("%c", v);} inline int PIConsole::couts(const char v) {return printf("%c", v);}
@@ -289,14 +290,15 @@ void PIConsole::run() {
} }
pwidth = width; pwidth = width;
pheight = height; pheight = height;
col_cnt = vars().size(); col_cnt = columns().size();
col_wid = (col_cnt > 0) ? width / col_cnt : width; col_wid = (col_cnt > 0) ? width / col_cnt : width;
for (uint i = 0; i < col_cnt; ++i) { for (uint i = 0; i < col_cnt; ++i) {
PIVector<Variable> & cvars(tabs[cur_tab].columns[i].variables);
cx = col_wid * i; cx = col_wid * i;
toUpperLeft(); toUpperLeft();
if (my < vars()[i].size()) my = vars()[i].size(); if (my < cvars.size()) my = cvars.size();
j = 0; j = 0;
piForeachC (Variable & tv, vars()[i]) { piForeachC (Variable & tv, cvars) {
if (j > height - 3) continue; if (j > height - 3) continue;
j++; j++;
moveRight(cx); moveRight(cx);
@@ -338,7 +340,7 @@ void PIConsole::run() {
void PIConsole::fillLabels() { void PIConsole::fillLabels() {
uint cx, cy, my = 0; uint cx, cy, my = 0, mx = 0, dx;
#ifdef WINDOWS #ifdef WINDOWS
GetConsoleScreenBufferInfo(hOut, &sbi); GetConsoleScreenBufferInfo(hOut, &sbi);
width = sbi.srWindow.Right - sbi.srWindow.Left; width = sbi.srWindow.Right - sbi.srWindow.Left;
@@ -349,21 +351,31 @@ void PIConsole::fillLabels() {
width = ws.ws_col; width = ws.ws_col;
height = ws.ws_row; height = ws.ws_row;
#endif #endif
col_cnt = vars().size(); col_cnt = columns().size();
col_wid = (col_cnt > 0) ? width / col_cnt : width; col_wid = (col_cnt > 0) ? width / col_cnt : width;
for (uint i = 0; i < col_cnt; ++i) { for (uint i = 0; i < col_cnt; ++i) {
Column & ccol(tabs[cur_tab].columns[i]);
PIVector<Variable> & 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; cx = col_wid * i;
cy = 1; cy = 1;
toUpperLeft(); 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 (int(j) > height - 3) continue;
if (my < j) my = j; if (my < j) my = j;
moveRight(cx); moveRight(cx);
tv = vars()[i][j]; Variable & tv(cvars[j]);
vars()[i][j].nx = cx; cvars[j].nx = cx;
vars()[i][j].ny = cy; cvars[j].ny = cy;
if (tv.name.size() == 0) { if (tv.name.size() == 0) {
vars()[i][j].offset = 0; cvars[j].offset = 0;
clearLine(); clearLine();
newLine(); newLine();
cy++; cy++;
@@ -371,16 +383,33 @@ void PIConsole::fillLabels() {
} }
clearLine(); clearLine();
if (tv.type == 0 && tv.s == 0) { if (tv.type == 0 && tv.s == 0) {
vars()[i][j].offset = vars()[i][j].name.length(); cvars[j].offset = cvars[j].name.length();
vars()[i][j].nx += vars()[i][j].offset; cvars[j].nx += cvars[j].offset;
printLine(tv.name, cx, tv.format); printLine(tv.name, cx, tv.format);
newLine(); newLine();
cy++; cy++;
continue; continue;
} }
vars()[i][j].offset = (tv.name + ": ").length(); switch (ccol.alignment) {
vars()[i][j].nx += vars()[i][j].offset; case Nothing:
cvars[j].offset = (tv.name + ": ").length();
cvars[j].nx += cvars[j].offset;
printValue(tv.name + ": ", tv.format); 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(); newLine();
cy++; cy++;
} }
@@ -428,70 +457,70 @@ int PIConsole::bitsValue(void * src, int offset, int count) {
return ret; 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<PIConsole::Format> format) { void PIConsole::addString(const PIString & name, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 0; tv.s = 0; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 0; tv.s = 0; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, PIString* ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, PIString* ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 0; tv.s = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 0; tv.s = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, bool * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, bool * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 1; tv.b = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 1; tv.b = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, int * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, int * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 2; tv.i = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 2; tv.i = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, long * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, long * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 3; tv.l = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 3; tv.l = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, char * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, char * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 4; tv.c = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 4; tv.c = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, float * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, float * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 5; tv.f = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 5; tv.f = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, double * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, double * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 6; tv.d = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 6; tv.d = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, short * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, short * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 7; tv.sh = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 7; tv.sh = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, uint * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, uint * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 8; tv.ui = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 8; tv.ui = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, ulong * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, ulong * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 9; tv.ul = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 9; tv.ul = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, ushort * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, ushort * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 10; tv.ush = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 10; tv.ush = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, uchar * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, uchar * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 11; tv.uc = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 11; tv.uc = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, llong * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, llong * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 12; tv.ll = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 12; tv.ll = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, ullong * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, ullong * ptr, int col, PIFlags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 13; tv.ull = ptr; vars()[column - 1].push_back(tv);} ADD_VAR_BODY tv.type = 13; tv.ull = ptr; column(col).push_back(tv);}
void PIConsole::addVariable(const PIString & name, PIProtocol * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, PIProtocol * ptr, int col, PIFlags<PIConsole::Format> format) {
addString("protocol " + name, column, format | PIConsole::Bold); addString("protocol " + name, col, format | PIConsole::Bold);
addVariable("Rec :" + ptr->receiverDeviceName() + " ", ptr->receiverDeviceState_ptr(), column, format); addVariable("Rec :" + ptr->receiverDeviceName() + " ", ptr->receiverDeviceState_ptr(), col, format);
addVariable("Send:" + ptr->senderDeviceName() + " ", ptr->senderDeviceState_ptr(), column, format); addVariable("Send:" + ptr->senderDeviceName() + " ", ptr->senderDeviceState_ptr(), col, format);
addVariable("Sended count", ptr->sendCount_ptr(), column, format); addVariable("Sended count", ptr->sendCount_ptr(), col, format);
addVariable("Received count", ptr->receiveCount_ptr(), column, format); addVariable("Received count", ptr->receiveCount_ptr(), col, format);
addVariable("Invalid count", ptr->wrongCount_ptr(), column, format); addVariable("Invalid count", ptr->wrongCount_ptr(), col, format);
addVariable("Missed count", ptr->missedCount_ptr(), column, format); addVariable("Missed count", ptr->missedCount_ptr(), col, format);
addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), column, format); addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), col, format);
addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), column, format); addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), col, format);
addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), column, format); addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), col, format);
addVariable("Receiver history size", ptr->receiverHistorySize_ptr(), column, format); addVariable("Receiver history size", ptr->receiverHistorySize_ptr(), col, format);
addVariable("Sender history size", ptr->senderHistorySize_ptr(), column, format); addVariable("Sender history size", ptr->senderHistorySize_ptr(), col, format);
addVariable("Quality", ptr->quality_ptr(), column, format); addVariable("Quality", ptr->quality_ptr(), col, format);
} }
void PIConsole::addVariable(const PIString & name, PISystemMonitor * ptr, int column, PIFlags<PIConsole::Format> format) { void PIConsole::addVariable(const PIString & name, PISystemMonitor * ptr, int col, PIFlags<PIConsole::Format> format) {
addString("monitor " + name, column, format | PIConsole::Bold); addString("monitor " + name, col, format | PIConsole::Bold);
addVariable("state ", &(ptr->statistic().state), column, format); addVariable("state ", &(ptr->statistic().state), col, format);
addVariable("threads ", &(ptr->statistic().threads), column, format); addVariable("threads ", &(ptr->statistic().threads), col, format);
addVariable("priority", &(ptr->statistic().priority), column, format); addVariable("priority", &(ptr->statistic().priority), col, format);
addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), column, format); addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), col, format);
addVariable("memory shared ", &(ptr->statistic().share_memsize_readable), column, format); addVariable("memory shared ", &(ptr->statistic().share_memsize_readable), col, format);
addVariable("cpu load", &(ptr->statistic().cpu_load_system), column, 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<PIConsole::Format> format) { void PIConsole::addBitVariable(const PIString & name, void * ptr, int fromBit, int bitCount, int col, PIFlags<PIConsole::Format> format) {
tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.ptr = ptr; tv.format = 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);} checkColumn(col); column(col).push_back(tv);}
void PIConsole::addEmptyLine(int column, uint count) { void PIConsole::addEmptyLine(int col, uint count) {
tv.name = ""; tv.type = 0; tv.d = 0; tv.format = Normal; tv.name = ""; tv.type = 0; tv.d = 0; tv.format = Normal;
for (uint i = 0; i < count; ++i) { for (uint i = 0; i < count; ++i) {
checkColumn(column); checkColumn(col);
vars()[column - 1].push_back(tv); column(col).push_back(tv);
} }
} }
@@ -521,15 +550,15 @@ PIString PIConsole::getString(int x, int y) {
PIString PIConsole::getString(const PIString & name) { PIString PIConsole::getString(const PIString & name) {
piForeachC (PIVector<Variable> & i, tabs[cur_tab].variables) piForeachC (Column & i, tabs[cur_tab].columns)
piForeachC (Variable & j, i) piForeachC (Variable & j, i.variables)
if (j.name == name) if (j.name == name)
return getString(j.nx + 1, j.ny); return getString(j.nx + 1, j.ny);
return PIString(); 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<PIConsole::Format> format) { inline void PIConsole::printLine(const PIString & value, int dx, PIFlags<PIConsole::Format> format) {
int i = width - value.length() - dx; int i = width - value.length() - dx;
@@ -537,15 +566,15 @@ inline void PIConsole::printLine(const PIString & value, int dx, PIFlags<PIConso
--i; --i;
#endif #endif
PIString ts = fstr(format); PIString ts = fstr(format);
couts(ts.stdString()); couts(ts);
if (i >= 0) ts = value + PIString(i, ' '); if (i >= 0) ts = value + PIString(i, ' ');
else ts = value.left(value.size() + i); else ts = value.left(value.size() + i);
couts(ts.stdString()); couts(ts);
couts(fstr(Dec).stdString()); couts(fstr(Dec));
} }
inline int PIConsole::printValue(const PIString & value, PIFlags<PIConsole::Format> format) { inline int PIConsole::printValue(const PIString & value, PIFlags<PIConsole::Format> format) {
couts(fstr(format).stdString()); couts(fstr(format));
int ret = couts(value.stdString()); int ret = couts(value);
fstr(PIConsole::Dec); fstr(PIConsole::Dec);
return ret; return ret;
} }

34
piconsole.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Console output/input 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 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 it under the terms of the GNU General Public License as published by
@@ -61,6 +61,7 @@ public:
Hex = 0x2000000, Hex = 0x2000000,
Oct = 0x4000000, Oct = 0x4000000,
Scientific = 0x8000000}; Scientific = 0x8000000};
enum Alignment {Nothing, Left, Right};
void addString(const PIString & name, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal); void addString(const PIString & name, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(const PIString & name, PIString * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal); void addVariable(const PIString & name, PIString * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
@@ -106,9 +107,13 @@ public:
void addCustomStatus(const PIString & str) {tabs[cur_tab].status = str;} void addCustomStatus(const PIString & str) {tabs[cur_tab].status = str;}
void clearCustomStatus() {tabs[cur_tab].status.clear();} 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_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, waitForFinish) {WAIT_FOR_EXIT}
EVENT_HANDLER0(PIConsole, void, start) {start(false);} EVENT_HANDLER0(PIConsole, void, start) {start(false);}
@@ -156,7 +161,7 @@ private:
void showCursor() {printf("\e[?25h");} void showCursor() {printf("\e[?25h");}
#endif #endif
void status(); 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); int bitsValue(void * src, int offset, int count);
inline void printLine(const PIString & str, int dx = 0, PIFlags<PIConsole::Format> format = PIConsole::Normal); inline void printLine(const PIString & str, int dx = 0, PIFlags<PIConsole::Format> format = PIConsole::Normal);
inline int printValue(const PIString & str, PIFlags<PIConsole::Format> format = PIConsole::Normal); inline int printValue(const PIString & str, PIFlags<PIConsole::Format> format = PIConsole::Normal);
@@ -203,21 +208,33 @@ private:
void * ptr; void * ptr;
}; };
void operator =(const Variable & src) {name = src.name; format = src.format; type = src.type; offset = src.offset; 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<Variable> 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 { struct Tab {
PIVector<PIVector<Variable> > variables; PIVector<Column> columns;
PIString name; PIString name;
PIString status; PIString status;
char key; char key;
Tab() {;} Tab() {}
Tab(PIString n, char k) {name = n; key = k;} Tab(PIString n, char k) {name = n; key = k;}
~Tab() {;} ~Tab() {;}
}; };
PIVector<PIVector<Variable> > & vars() {return tabs[cur_tab].variables;} PIVector<Column> & columns() {return tabs[cur_tab].columns;}
inline int couts(const string v); 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 char * v);
inline int couts(const bool v); inline int couts(const bool v);
inline int couts(const char v); inline int couts(const char v);
@@ -246,6 +263,7 @@ private:
PIVector<Tab> tabs; PIVector<Tab> tabs;
Variable tv; Variable tv;
PIKbdListener * listener; PIKbdListener * listener;
Alignment def_align;
KBFunc ret_func; KBFunc ret_func;
int width, height, pwidth, pheight, ret, col_wid, num_format; int width, height, pwidth, pheight, ret, col_wid, num_format;
uint my; uint my;

247
picontainers.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Generic containers, based on STL 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 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 it under the terms of the GNU General Public License as published by
@@ -124,7 +124,7 @@ template <typename T> inline _PIForeachC<T> * _PIForeachCastC(_PIForeachBase & c
#define piForeachRC piForeachCR #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<typename Enum> template<typename Enum>
class PIFlags { class PIFlags {
@@ -133,27 +133,243 @@ public:
PIFlags(Enum e): flags(e) {;} PIFlags(Enum e): flags(e) {;}
PIFlags(const PIFlags & f): flags(f.flags) {;} PIFlags(const PIFlags & f): flags(f.flags) {;}
PIFlags(const int i): flags(i) {;} 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 PIFlags & f) {flags = f.flags;}
void operator =(const Enum & e) {flags = e;} void operator =(const Enum & e) {flags = e;}
void operator =(const int & i) {flags = i;} void operator =(const int & i) {flags = i;}
void operator |=(const PIFlags & f) {flags = flags | f.flags;} void operator |=(const PIFlags & f) {flags |= f.flags;}
void operator |=(const Enum & e) {flags = flags | e;} void operator |=(const Enum & e) {flags |= e;}
void operator |=(const int i) {flags = flags | i;} void operator |=(const int i) {flags |= i;}
void operator &=(const PIFlags & f) {flags = flags & f.flags;} void operator &=(const PIFlags & f) {flags &= f.flags;}
void operator &=(const Enum & e) {flags = flags & e;} void operator &=(const Enum & e) {flags &= e;}
void operator &=(const int i) {flags = flags & i;} 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 |(PIFlags f) const {PIFlags tf(flags | f.flags); return tf;}
PIFlags operator |(Enum e) const {PIFlags tf(flags | e); 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 |(int i) const {PIFlags tf(flags | i); return tf;}
PIFlags operator &(PIFlags f) const {PIFlags tf(flags & f.flags); 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 &(Enum e) const {PIFlags tf(flags & e); return tf;}
PIFlags operator &(int i) const {PIFlags tf(flags & i); 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;} bool operator [](Enum e) {return (flags & e) == e;}
operator int() const {return flags;} operator int() const {return flags;}
private: private:
int flags; int flags;
}; };
/*
template <typename T>
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<T>;
private:
iterator(PIVector<T> * v, int p): parent(v), pos(p) {}
PIVector<T> * 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<T>;
private:
const_iterator(const PIVector<T> * v, int p): parent(v), pos(p) {}
const PIVector<T> * 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<T>;
private:
reverse_iterator(PIVector<T> * v, int p): parent(v), pos(p) {}
PIVector<T> * 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<T>;
private:
const_reverse_iterator(const PIVector<T> * v, int p): parent(v), pos(p) {}
const PIVector<T> * 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> & 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> & 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<T> & clear() {resize(0); return *this;}
PIVector<T> & 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<T> & assign(const T & f = T()) {return fill(f);}
PIVector<T> & 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<T> & 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<T> & 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<T> & sort(CompareFunc compare = compare_func) {qsort(data_, size_, sizeof(T), (int(*)(const void * , const void * ))compare); return *this;}
PIVector<T> & removeOne(const T & v) {for (uint i = 0; i < size_; ++i) if (data_[i] == v) {remove(i); return *this;} return *this;}
PIVector<T> & removeAll(const T & v) {for (uint i = 0; i < size_; ++i) if (data_[i] == v) {remove(i); --i;} return *this;}
PIVector<T> & push_back(const T & v) {alloc(size_ + 1); data_[size_ - 1] = v; return *this;}
PIVector<T> & append(const T & v) {return push_back(v);}
PIVector<T> & operator <<(const T & v) {return push_back(v);}
PIVector<T> & push_front(const T & v) {insert(0, v); return *this;}
PIVector<T> & prepend(const T & v) {return push_front(v);}
//PIVector<T> & operator <<(const T & v) {return push_back(v);}
PIVector<T> & pop_back() {if (size_ == 0) return *this; resize(size_ - 1); return *this;}
PIVector<T> & 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<typename Type, typename Allocator = std::allocator<Type> > template<typename Type, typename Allocator = std::allocator<Type> >
class PIVector: public vector<Type, Allocator> { class PIVector: public vector<Type, Allocator> {
typedef PIVector<Type, Allocator> _CVector; typedef PIVector<Type, Allocator> _CVector;
@@ -172,15 +388,20 @@ public:
Type * data(uint index = 0) {return &(*this)[index];} Type * data(uint index = 0) {return &(*this)[index];}
int size_s() const {return static_cast<int>(_stlc::size());} int size_s() const {return static_cast<int>(_stlc::size());}
bool isEmpty() const {return _stlc::empty();} 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 & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
_CVector & pop_front() {_stlc::erase(_stlc::begin()); 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 & 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) {_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(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 & 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 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 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 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;} 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 & 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 & 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;} _CList & operator <<(const Type & t) {_stlc::push_back(t); return *this;}
PIVector<Type, Allocator> toVector() {PIVector<Type, Allocator> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;} PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
}; };
template<typename Type, typename Compare = std::less<Type>, typename Allocator = std::allocator<Type> > template<typename Type, typename Compare = std::less<Type>, typename Allocator = std::allocator<Type> >
@@ -232,7 +453,7 @@ public:
_CSet & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;} _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;} _CSet & operator <<(const Type & t) {_stlc::insert(t); return *this;}
bool operator [](const Type & t) {return _stlc::find(t);} bool operator [](const Type & t) {return _stlc::find(t);}
PIVector<Type, Allocator> toVector() {PIVector<Type, Allocator> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;} PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
}; };
template<typename Type> template<typename Type>
@@ -265,7 +486,7 @@ public:
int size_s() const {return static_cast<int>(_stlc::size());} int size_s() const {return static_cast<int>(_stlc::size());}
bool isEmpty() const {return _stlc::empty();} bool isEmpty() const {return _stlc::empty();}
_CDeque & operator <<(const Type & t) {_CDeque::push_back(t); return *this;} _CDeque & operator <<(const Type & t) {_CDeque::push_back(t); return *this;}
PIVector<Type, Allocator> toVector() {PIVector<Type, Allocator> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;} PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
}; };
template<typename Type> template<typename Type>

4
pidir.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Directory 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 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 it under the terms of the GNU General Public License as published by
@@ -35,7 +35,7 @@ PIDir::PIDir() {
PIDir::PIDir(const PIString & dir) { PIDir::PIDir(const PIString & dir) {
path_ = dir.stdString(); path_ = dir;
dir_ = 0; dir_ = 0;
open(); open();
} }

2
pidir.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Directory 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 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 it under the terms of the GNU General Public License as published by

301
piethernet.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Ethernet, UDP 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 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 it under the terms of the GNU General Public License as published by
@@ -20,182 +20,217 @@
#include "piethernet.h" #include "piethernet.h"
PIEthernet::PIEthernet(PIString ip, int port, void * data_, EthernetFunc slot): PIThread() { PIEthernet::PIEthernet(void * data, ReadRetFunc slot): PIIODevice("", ReadWrite) {
piMonitor.ethernets++; piMonitor.ethernets++;
setPriority(piHigh); setPriority(piHigh);
data = data_; type_ = UDP;
ip_ = ip_s = ip; ret_data_ = data;
port_ = port_s = port; ip_ = ip_s = "";
sock = sock_s = -1; port_ = port_s = 0;
ret_func = slot; sock = -1;
tries = 0; ret_func_ = slot;
//buffer_ = new char[BUFFER_SIZE]; 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 #ifdef WINDOWS
WSADATA wsaData; WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData); WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif #endif
initSend();
} }
PIEthernet::~PIEthernet() { PIEthernet::~PIEthernet() {
piMonitor.ethernets--; piMonitor.ethernets--;
terminate(); if (server_thread_.isRunning()) server_thread_.terminate();
closeSocket(sock);
#ifdef WINDOWS #ifdef WINDOWS
WSACleanup(); WSACleanup();
#endif #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_; //if (buffer_ != 0) delete buffer_;
//buffer_ = 0; //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() { 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_ << " ..." <<endl;
parseAddress(path_, &ip_, &port_);
addr_.sin_port = htons(port_);
addr_.sin_addr.s_addr = inet_addr(ip_.data()); addr_.sin_addr.s_addr = inet_addr(ip_.data());
addr_.sin_family = PF_INET; addr_.sin_family = PF_INET;
addr_.sin_port = htons(port_); //cout << "openDevice\n";
#ifdef WINDOWS
closesocket(sock);
#else
close(sock);
#endif
sock = socket(PF_INET, SOCK_DGRAM, 0);
if (bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) { if (bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) {
tries++; piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << errorString() << endl;
if (tries < 10) {
if (init()) {
tries = 0;
return true;
} else return false;
} else
cout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << errorString() << endl;
return false; return false;
} }
//cout << "!" << endl;
return true; return true;
} }
bool PIEthernet::initSend() { bool PIEthernet::closeDevice() {
#ifdef WINDOWS //cout << "close\n";
closesocket(sock_s); if (sock != -1) shutdown(sock, SHUT_RDWR);
#else closeSocket(sock);
close(sock_s); piForeach (PIEthernet * i, clients_)
#endif delete i;
sock_s = socket(PF_INET, SOCK_DGRAM, 0); clients_.clear();
if (sock_s == -1) { if (server_thread_.isRunning()) server_thread_.terminate();
tries++; connected_ = false;
if (tries < 10) {
if (init()) {
tries = 0;
return true;
} else return false;
} else
cout << "[PIEthernet] Unable to create socket, " << errorString() << endl;
return false;
}
return true; return true;
} }
bool PIEthernet::send(PIString ip, int port, char * data, int size) { bool PIEthernet::connect(PIString ip, int port) {
if (sock_s == -1) { if (sock == -1) return false;
//cout << "[PIEthernet] Can`t send to uninitialized socket" << endl; addr_.sin_port = htons(port);
addr_.sin_addr.s_addr = inet_addr(ip.data());
addr_.sin_family = PF_INET;
//piCout << "[PIEthernet] connect to " << ip << ":" << port << endl;
connected_ = (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) == 0);
if (!connected_)
piCout << "[PIEthernet] Cant`t connect to " << ip << ":" << port << ", " << errorString() << endl;
opened_ = connected_;
return connected_;
}
bool PIEthernet::listen() {
if (sock == -1) init();
if (sock == -1) return false;
parseAddress(path_, &ip_, &port_);
addr_.sin_port = htons(port_);
addr_.sin_addr.s_addr = inet_addr(ip_.data());
addr_.sin_family = PF_INET;
if (bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) {
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << errorString() << endl;
return false; return false;
} }
saddr_.sin_port = htons(port); if (::listen(sock, 64) == -1) {
saddr_.sin_addr.s_addr = inet_addr(ip.data()); piCout << "[PIEthernet] Can`t listen on "<< ip_ << ":" << port_ << ", " << errorString() << endl;
saddr_.sin_family = PF_INET;
wrote = sendto(sock_s, data, size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
if (wrote != size) {
//cout << "[PIEthernet] Error while sending" << endl;
return false; return false;
} }
//cout << "[PIEthernet] Wrote " << wrote << " bytes in " << devName << endl; //piCout << "[PIEthernet] listen on " << ip_ << ":" << port_ << endl;
server_thread_.start(server_func);
return true; return true;
} }
bool PIEthernet::send(uchar * data, int size) { int PIEthernet::read(void * read_to, int max_size) {
if (sock_s == -1) { //cout << "read " << sock << endl;
//cout << "[PIEthernet] Can`t send to uninitialized socket" << endl; if (sock == -1) init();
return false; if (sock == -1) return -1;
//piCout << "[PIEthernet] read from " << ip_ << ":" << port_ << endl;
switch (type_) {
case UDP: case TCP_Client:
return recv(sock, read_to, max_size, 0);
//return ::read(sock, read_to, max_size);
default: break;
//return ::read(sock, (char * )read_to, max_size);
} }
return -1;
}
int PIEthernet::write(const void * data, int max_size) {
if (sock == -1) init();
if (sock == -1 || !isWriteable()) {
//piCout << "[PIEthernet] Can`t send to uninitialized socket" << endl;
return -1;
}
//piCout << "[PIEthernet] sending to " << ip_s << ":" << port_s << " " << max_size << " bytes" << endl;
switch (type_) {
case UDP:
saddr_.sin_port = htons(port_s); saddr_.sin_port = htons(port_s);
saddr_.sin_addr.s_addr = inet_addr(ip_s.data()); saddr_.sin_addr.s_addr = inet_addr(ip_s.data());
saddr_.sin_family = PF_INET; saddr_.sin_family = PF_INET;
//cout << "[PIEthernet] sending in " << sock_s << endl; return sendto(sock, data, max_size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
wrote = sendto(sock_s, data, size, 0, (sockaddr * )&saddr_, sizeof(saddr_)); case TCP_Client:
if (wrote != size) { return ::write(sock, data, max_size);
//cout << "[PIEthernet] Error while sending" << endl; default: break;
return false; //return ::read(sock, read_to, max_size);
} }
//cout << "[PIEthernet] Wrote " << wrote << " bytes" << endl; return -1;
return true; }
void PIEthernet::server_func(void * eth) {
PIEthernet * ce = (PIEthernet * )eth;
sockaddr_in client_addr;
socklen_t slen = sizeof(client_addr);
int s;
s = accept(ce->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;
} }

83
piethernet.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Ethernet, UDP 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 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 it under the terms of the GNU General Public License as published by
@@ -20,12 +20,13 @@
#ifndef PIETHERNET_H #ifndef PIETHERNET_H
#define PIETHERNET_H #define PIETHERNET_H
#include "pithread.h" #include "pitimer.h"
#include "pistring.h" #include "piiodevice.h"
#ifndef WINDOWS #ifndef WINDOWS
# include <netinet/in.h> # include <netinet/in.h>
# include <arpa/inet.h> # include <arpa/inet.h>
# include <sys/socket.h> # include <sys/socket.h>
# include <fcntl.h>
#else #else
# ifdef CC_VC # ifdef CC_VC
# include <winsock.h> # include <winsock.h>
@@ -36,42 +37,66 @@
# endif # endif
#endif #endif
#define BUFFER_SIZE 4096 class PIEthernet: public PIIODevice
typedef bool (*EthernetFunc)(void * , uchar * , int );
class PIEthernet: public PIThread
{ {
public: public:
// slot is any function format "bool <func>(void*, uchar*, int)" // slot is any function format "bool <func>(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(); ~PIEthernet();
void setSlot(EthernetFunc func) {ret_func = func;} void setReadAddress(PIString ip, int port) {path_ = ip + ":" + PIString::fromNumber(port);}
void setData(void * d) {data = d;} void setReadAddress(PIString ip_port) {path_ = ip_port;}
void setReadAddress(PIString ip, int port) {ip_ = ip; port_ = port;}
void setSendAddress(PIString ip, int port) {ip_s = ip; port_s = 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<PIEthernet * > 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 init();
bool initSend(); bool openDevice();
bool receiverInitialized() const {return sock != -1;} bool closeDevice();
bool senderInitialized() const {return sock_s != -1;} #ifdef WINDOWS
void terminate(); void closeSocket(int & sd) {if (sd != -1) closesocket(sd); sd = -1;}
const uchar * buffer() const {return buffer_;} #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<PIEthernet * > clients_;
Type type_;
private: private:
void begin(); static void server_func(void * eth);
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];
}; };

2
pievaluator.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Evaluator designed for stream computing 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 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 it under the terms of the GNU General Public License as published by

2
pievaluator.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Evaluator designed for stream computing 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 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 it under the terms of the GNU General Public License as published by

88
pifile.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
File 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 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 it under the terms of the GNU General Public License as published by
@@ -20,35 +20,46 @@
#include "pifile.h" #include "pifile.h"
bool PIFile::open(const PIString & path_, PIFlags<Mode> mode_) { bool PIFile::openDevice() {
cpath = path_; if (opened_) close();
cmode = mode_; if (path_.isEmpty()) return false;
string st = cpath.stdString(); //cout << "fopen " << path_.data() << ": " << strType(mode_).data() << endl;
if (cmode[New]) { fd = fopen(path_.data(), strType(mode_).data());
stream.open(st.c_str(), fstream::in | fstream::out | fstream::trunc | fstream::binary); opened_ = (fd != 0);
stream.close(); seekToBegin();
cmode &= ~New; return opened_;
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::closeDevice() {
if (!opened_) return true;
return (fclose(fd) != 0);
} }
PIString PIFile::readLine() { PIString PIFile::readLine() {
char * buff = new char[4096]; PIString str;
stream.getline(buff, 4096); if (!opened_) return str;
return PIString(buff); 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 PIFile::readAll(void * data) {
llong cp = pos(), s = size(), i = -1; llong cp = pos(), s = size(), i = -1;
stream.seekg(0); seekToBegin();
if (s < 0) { if (s < 0) {
while (!stream.eof()) while (!isEnd())
stream.read(&(((char*)data)[++i]), 1); read(&(((char*)data)[++i]), 1);
} else } else
stream.read((char * )data, s); read((char * )data, s);
seek(cp); seek(cp);
return s; return s;
} }
@@ -56,14 +67,11 @@ llong PIFile::readAll(void * data) {
PIByteArray PIFile::readAll(bool forceRead) { PIByteArray PIFile::readAll(bool forceRead) {
llong cp = pos(), s = size(); llong cp = pos(), s = size();
char c;
PIByteArray a; PIByteArray a;
if (s < 0) { if (s < 0) {
if (!forceRead) return a; if (!forceRead) return a;
while (!stream.eof()) { while (!isEnd())
stream.read(&c, 1); a.push_back(readChar());
a.push_back(c);
}
seek(cp); seek(cp);
return a; return a;
} }
@@ -75,12 +83,11 @@ PIByteArray PIFile::readAll(bool forceRead) {
llong PIFile::size() { llong PIFile::size() {
if (!stream.is_open()) return -1; if (!opened_) return -1;
llong s, cp = stream.tellg(); llong s, cp = pos();
stream.seekg(0, fstream::end); seekToEnd();
s = stream.tellg(); s = pos();
stream.seekg(cp, fstream::beg); seek(cp);
stream.clear();
return s; return s;
} }
@@ -91,23 +98,18 @@ void PIFile::resize(llong new_size, char fill_) {
if (ds > 0) { if (ds > 0) {
char * buff = new char[ds]; char * buff = new char[ds];
memset(buff, fill_, ds); memset(buff, fill_, ds);
stream.write(buff, ds); write(buff, ds);
delete buff; delete[] buff;
return; 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;
}
bool PIFile::isExists(const PIString & path) {
PIFile PIFile::openTemporary(PIFlags<PIFile::Mode> mode) { FILE * f = fopen(PIString(path).data(), "r");
char * rc; bool ok = (f != 0);
rc = tmpnam(0); if (ok) fclose(f);
return PIFile(PIString(rc), mode); return ok;
} }

139
pifile.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
File 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 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 it under the terms of the GNU General Public License as published by
@@ -20,100 +20,89 @@
#ifndef PIFILE_H #ifndef PIFILE_H
#define PIFILE_H #define PIFILE_H
#include "piobject.h" #include "piiodevice.h"
#include <fstream> #include <cstdio>
using std::fstream; class PIFile: public PIIODevice
class PIFile: public PIObject
{ {
public: 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> mode = ReadWrite): PIObject(path) {open(path, mode);} void flush() {fflush(fd);}
PIFile(const PIFile & file): PIObject(file.cpath) {cpath = file.cpath; cmode = file.cmode;} EVENT_HANDLER(PIFile, void, clear) {close(); fd = fopen(path_.data(), "w"); close(); open();}
~PIFile() {close();} 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);}
PIFile & operator =(const PIFile & f) {cpath = f.cpath; cmode = f.cmode; return *this;} 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_HANDLER2(PIFile, bool, open, const PIString & , path, PIFlags<Mode>, mode);
EVENT_HANDLER1(PIFile, bool, open, PIFlags<Mode>, 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
EVENT_HANDLER1(PIFile, void, resize, llong, new_size) {resize(new_size, 0);} EVENT_HANDLER1(PIFile, void, resize, llong, new_size) {resize(new_size, 0);}
EVENT_HANDLER2(PIFile, void, resize, llong, new_size, char, fill); EVENT_HANDLER2(PIFile, void, resize, llong, new_size, char, fill);
void fill(char c) {stream.fill(c);} //void fill(char c) {stream.fill(c);}
EVENT_HANDLER0(PIFile, void, flush) {stream.flush();} char readChar() {return (char)fgetc(fd);}
PIString readLine(); PIString readLine();
llong readAll(void * data); llong readAll(void * data);
PIByteArray readAll(bool forceRead = false); 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) {path_ = path; if (opened_) openDevice();}
void setPath(const PIString & path) {cpath = path;}
PIFlags<Mode> mode() const {return cmode;}
llong size(); llong size();
llong pos(); llong pos() {if (!opened_) return -1; return ftell(fd);}
bool isOpened() {return stream.is_open();} bool isEnd() {return (feof(fd) || ferror(fd));}
bool isEnd() {return stream.eof();}
bool isEmpty() {return (size() <= 0);} bool isEmpty() {return (size() <= 0);}
PIFile & writeData(const void * data, int size_) {stream.write((char * )data, size_); return *this;} int read(void * read_to, int max_size) {if (!canRead()) return -1; return fread(read_to, max_size, 1, fd);}
PIFile & readData(void * data, int size_) {stream.read((char * )data, size_); return *this;} 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) {writeBinary(id).writeBinary((ushort)size).writeData(data, size); flush(); return *this;} 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 char v) {write(&v, sizeof(v)); return *this;}
PIFile & writeBinary(const short v) {stream.write((char * )&v, sizeof(v)); return *this;} PIFile & writeBinary(const short v) {write(&v, sizeof(v)); return *this;}
PIFile & writeBinary(const int v) {stream.write((char * )&v, sizeof(v)); return *this;} PIFile & writeBinary(const int v) {write(&v, sizeof(v)); return *this;}
PIFile & writeBinary(const long v) {stream.write((char * )&v, sizeof(v)); return *this;} PIFile & writeBinary(const long v) {write(&v, sizeof(v)); return *this;}
PIFile & writeBinary(const uchar v) {stream.write((char * )&v, sizeof(v)); return *this;} PIFile & writeBinary(const uchar v) {write(&v, sizeof(v)); return *this;}
PIFile & writeBinary(const ushort v) {stream.write((char * )&v, sizeof(v)); return *this;} PIFile & writeBinary(const ushort v) {write(&v, sizeof(v)); return *this;}
PIFile & writeBinary(const uint v) {stream.write((char * )&v, sizeof(v)); return *this;} PIFile & writeBinary(const uint v) {write(&v, sizeof(v)); return *this;}
PIFile & writeBinary(const ulong v) {stream.write((char * )&v, sizeof(v)); return *this;} PIFile & writeBinary(const ulong v) {write(&v, sizeof(v)); return *this;}
PIFile & writeBinary(const float v) {stream.write((char * )&v, sizeof(v)); return *this;} PIFile & writeBinary(const float v) {write(&v, sizeof(v)); return *this;}
PIFile & writeBinary(const double v) {stream.write((char * )&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 char & v) {if (!isWriteable()) return *this; write(&v, 1); return *this;}
//PIFile & operator <<(const string & v) {stream.write(v.c_str(), v.size()); return *this;} //PIFile & operator <<(const string & v) {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 PIString & v) {if (!isWriteable()) return *this; write(v.data(), v.lengthAscii()); return *this;}
PIFile & operator <<(const PIByteArray & v) {stream.write((char * )v.data(), v.size()); return *this;} PIFile & operator <<(const PIByteArray & v) {if (!isWriteable()) return *this; write(v.data(), v.size()); return *this;}
PIFile & operator <<(const short & v) {stream << v; return *this;} PIFile & operator <<(short v) {if (!isWriteable()) return *this; fprintf(fd, "%hd", v); return *this;}
PIFile & operator <<(const int & v) {stream << v; return *this;} PIFile & operator <<(int v) {if (!isWriteable()) return *this; fprintf(fd, "%d", v); return *this;}
PIFile & operator <<(const long & v) {stream << v; return *this;} PIFile & operator <<(long v) {if (!isWriteable()) return *this; fprintf(fd, "%ld", v); return *this;}
PIFile & operator <<(const uchar & v) {stream << v; return *this;} PIFile & operator <<(uchar v) {if (!isWriteable()) return *this; fprintf(fd, "%c", v); return *this;}
PIFile & operator <<(const ushort & v) {stream << v; return *this;} PIFile & operator <<(ushort v) {if (!isWriteable()) return *this; fprintf(fd, "%hd", v); return *this;}
PIFile & operator <<(const uint & v) {stream << v; return *this;} PIFile & operator <<(uint v) {if (!isWriteable()) return *this; fprintf(fd, "%d", v); return *this;}
PIFile & operator <<(const ulong & v) {stream << v; return *this;} PIFile & operator <<(ulong v) {if (!isWriteable()) return *this; fprintf(fd, "%ld", v); return *this;}
PIFile & operator <<(const float & v) {stream << v; return *this;} PIFile & operator <<(float v) {if (!isWriteable()) return *this; fprintf(fd, "%f", v); return *this;}
PIFile & operator <<(const double & v) {stream << 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 >>(char & v) {if (!isWriteable()) return *this; fscanf(fd, "%hhn", &v); return *this;}
PIFile & operator >>(short & v) {stream >> v; return *this;} PIFile & operator >>(short & v) {if (!isWriteable()) return *this; fscanf(fd, "%hn", &v); return *this;}
PIFile & operator >>(int & v) {stream >> v; return *this;} PIFile & operator >>(int & v) {if (!isWriteable()) return *this; fscanf(fd, "%n", &v); return *this;}
PIFile & operator >>(long & v) {stream >> v; return *this;} PIFile & operator >>(long & v) {if (!isWriteable()) return *this; fscanf(fd, "%ln", &v); return *this;}
PIFile & operator >>(uchar & v) {stream >> v; return *this;} PIFile & operator >>(uchar & v) {if (!isWriteable()) return *this; fscanf(fd, "%hhn", &v); return *this;}
PIFile & operator >>(ushort & v) {stream >> v; return *this;} PIFile & operator >>(ushort & v) {if (!isWriteable()) return *this; fscanf(fd, "%hn", &v); return *this;}
PIFile & operator >>(uint & v) {stream >> v; return *this;} PIFile & operator >>(uint & v) {if (!isWriteable()) return *this; fscanf(fd, "%n", &v); return *this;}
PIFile & operator >>(ulong & v) {stream >> v; return *this;} PIFile & operator >>(ulong & v) {if (!isWriteable()) return *this; fscanf(fd, "%ln", &v); return *this;}
PIFile & operator >>(float & v) {stream >> v; return *this;} PIFile & operator >>(float & v) {if (!isWriteable()) return *this; fscanf(fd, "%f", &v); return *this;}
PIFile & operator >>(double & v) {stream >> v; return *this;} PIFile & operator >>(double & v) {if (!isWriteable()) return *this; fscanf(fd, "%lf", &v); return *this;}
static PIFile openTemporary(PIFlags<PIFile::Mode> mode = PIFile::ReadWrite); static PIFile openTemporary(PIIODevice::DeviceMode mode = PIIODevice::ReadWrite) {return PIFile(PIString(tmpnam(0)), mode);}
static bool isExists(const PIString & path) {return std::ifstream(path.stdString().c_str()).good();} static bool isExists(const PIString & path);
static bool remove(const PIString & path) {return std::remove(path.stdString().c_str()) == 0;} static bool remove(const PIString & path) {return std::remove(path.data()) == 0;}
protected:
bool openDevice();
bool closeDevice();
private: private:
fstream stream; PIString strType(const PIIODevice::DeviceMode type) {switch (type) {case PIIODevice::ReadOnly: return "rb"; case WriteOnly: return "ab"; case ReadWrite: return "a+b";} return "rb";}
PIString cpath;
PIFlags<Mode> cmode; FILE * fd;
}; };

2
pigeometry.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Geometry 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 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 it under the terms of the GNU General Public License as published by

23
piincludes.cpp Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#include "piincludes.h"
bool isPIInit = false;
bool piDebug = true;

11
piincludes.h Normal file → Executable file
View File

@@ -20,10 +20,11 @@
#ifndef PIINCLUDES_H #ifndef PIINCLUDES_H
#define PIINCLUDES_H #define PIINCLUDES_H
#define PIP_VERSION 0x000102 #define PIP_VERSION 0x000200
#define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16 #define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16
#define PIP_VERSION_MINOR (PIP_VERSION & 0xFF00) >> 8 #define PIP_VERSION_MINOR (PIP_VERSION & 0xFF00) >> 8
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF #define PIP_VERSION_REVISION PIP_VERSION & 0xFF
#define PIP_VERSION_SUFFIX ""
#if WIN32 || WIN64 || _WIN32 || _WIN64 || __WIN32__ || __WIN64__ #if WIN32 || WIN64 || _WIN32 || _WIN64 || __WIN32__ || __WIN64__
# define WINDOWS # define WINDOWS
@@ -119,13 +120,17 @@ static locale_t currentLocale_t = 0;
typedef std::basic_string<wchar_t> wstring; typedef std::basic_string<wchar_t> wstring;
#endif #endif
static bool isPIInit = false; extern bool isPIInit;
extern bool piDebug;
#define piCout if (piDebug) cout
class PIInit { class PIInit {
public: public:
PIInit() { PIInit() {
if (isPIInit) return; if (isPIInit) return;
isPIInit = true; isPIInit = true;
//piDebug = true;
#ifdef LINUX #ifdef LINUX
if (currentLocale_t != 0) { if (currentLocale_t != 0) {
freelocale(currentLocale_t); freelocale(currentLocale_t);
@@ -215,6 +220,6 @@ inline string dtos(const double num) {
#endif #endif
return string(ch); }; 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 #endif // PIINCLUDES_H

107
piiodevice.cpp Executable file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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_);
}

121
piiodevice.h Executable file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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

7
pikbdlistener.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Keyboard grabber for console 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 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 it under the terms of the GNU General Public License as published by
@@ -60,7 +60,10 @@ void PIKbdListener::run() {
#else #else
ret = read(0, &rc, 1); ret = read(0, &rc, 1);
#endif #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); if (ret_func != 0 && ret > 0) ret_func(rc, data);
} }

2
pikbdlistener.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Keyboard grabber for console 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 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 it under the terms of the GNU General Public License as published by

2
pimath.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Math 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 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 it under the terms of the GNU General Public License as published by

2
pimath.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Math 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 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 it under the terms of the GNU General Public License as published by

2
pimonitor.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Counter of some PIP types 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 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 it under the terms of the GNU General Public License as published by

2
pimonitor.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Counter of some PIP types 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 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 it under the terms of the GNU General Public License as published by

2
pimultiprotocol.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Multiprotocol 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 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 it under the terms of the GNU General Public License as published by

10
pimultiprotocol.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Multiprotocol 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 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 it under the terms of the GNU General Public License as published by
@@ -62,14 +62,14 @@ private:
class PIRepeater: public PIMultiProtocol { class PIRepeater: public PIMultiProtocol {
public: public:
PIRepeater(const PIString & config, const PIString & name) { PIRepeater(const PIString & config, const PIString & name) {
PIConfig conf(config, PIFile::Read); PIConfig conf(config, PIIODevice::ReadOnly);
if (!conf.isOpened()) { if (!conf.isOpened()) {
cout << "[PIRepeater \"" << name << "\"] Can`t open \"" << config << "\"!" << endl; piCout << "[PIRepeater \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
return; return;
} }
PIConfig::Entry & b(conf.getValue(name)); PIConfig::Entry & b(conf.getValue(name));
if (b.childCount() != 2) { if (b.childCount() != 2) {
cout << "[PIRepeater \"" << name << "\"] \"" << config << "\" should consist 2 nodes!" << endl; piCout << "[PIRepeater \"" << name << "\"] \"" << config << "\" should consist 2 nodes!" << endl;
return; return;
} }
addProtocol(config, b.child(0)->fullName()); addProtocol(config, b.child(0)->fullName());
@@ -86,7 +86,7 @@ public:
ullong * sendCount_ptr() {if (count() == 2) return protocol(0)->sendCount_ptr(); return 0;} ullong * sendCount_ptr() {if (count() == 2) return protocol(0)->sendCount_ptr(); return 0;}
private: 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);}
}; };

2
pimutex.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Mutex 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 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 it under the terms of the GNU General Public License as published by

2
piobject.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism 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 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 it under the terms of the GNU General Public License as published by

11
piobject.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism 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 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 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_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_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 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 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##__)); #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; friend class PIObjectManager;
public: public:
PIObject(const PIString & name = PIString()) {piMonitor.objects++; setName(name); objects << this;} 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_;} const PIString & name() const {return name_;}
void setName(const PIString & name) {name_ = name;} void setName(const PIString & name) {name_ = name;}

2
pip.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
All includes 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 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,3 +1,3 @@
[Project] [Project]
Manager= Manager=KDevCMakeManager
Name=pip Name=pip

75
pipacketextractor.cpp Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}

71
pipacketextractor.h Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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

22
piprocess.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Process 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 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 it under the terms of the GNU General Public License as published by
@@ -59,7 +59,7 @@ void PIProcess::run() {
#ifdef WINDOWS #ifdef WINDOWS
//args.pop_front(); //args.pop_front();
piForeachC (PIString & i, args) piForeachC (PIString & i, args)
as += i.stdString().length() + 1; as += i.lengthAscii() + 1;
char * a = new char[as]; char * a = new char[as];
memset(a, ' ', as - 1); memset(a, ' ', as - 1);
as = 0; as = 0;
@@ -93,20 +93,20 @@ void PIProcess::run() {
/// files for stdin/out/err /// files for stdin/out/err
t_in = t_out = t_err = false; t_in = t_out = t_err = false;
if (f_in.path().isEmpty()) { if (f_in.path().isEmpty()) {
f_in = PIFile::openTemporary(PIFile::New | PIFile::Read); f_in = PIFile::openTemporary(PIIODevice::ReadWrite);
t_in = true; 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()) { if (f_out.path().isEmpty()) {
f_out = PIFile::openTemporary(PIFile::New | PIFile::Write); f_out = PIFile::openTemporary(PIIODevice::ReadWrite);
t_out = true; 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()) { if (f_err.path().isEmpty()) {
f_err = PIFile::openTemporary(PIFile::New | PIFile::Write); f_err = PIFile::openTemporary(PIIODevice::ReadWrite);
t_err = true; 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(); str = args.front().stdString();
is_exec = true; is_exec = true;
@@ -114,7 +114,7 @@ void PIProcess::run() {
pid = fork(); pid = fork();
if (pid == 0) { if (pid == 0) {
#endif #endif
FILE * tf; FILE * tf = 0;
//cout << "exec" << endl; //cout << "exec" << endl;
//cout << f_out.path() << endl; //cout << f_out.path() << endl;
if (g_in) tf = freopen(f_in.path().data(), "r", stdin); if (g_in) tf = freopen(f_in.path().data(), "r", stdin);
@@ -140,10 +140,10 @@ void PIProcess::run() {
WaitForSingleObject(pi.hProcess, INFINITE); WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess); CloseHandle(pi.hProcess);
} else } else
cout << "[PIProcess] \"CreateProcess\" error, " << errorString() << endl; piCout << "[PIProcess] \"CreateProcess\" error, " << errorString() << endl;
#else #else
if (execve(str.c_str(), a, e) < 0) if (execve(str.c_str(), a, e) < 0)
cout << "[PIProcess] \"execve\" error, " << errorString() << endl; piCout << "[PIProcess] \"execve\" error, " << errorString() << endl;
} else { } else {
msleep(1); msleep(1);
//cout << "wait" << endl; //cout << "wait" << endl;

6
piprocess.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Process 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 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 it under the terms of the GNU General Public License as published by
@@ -64,8 +64,8 @@ public:
void terminate() {if (is_exec) kill(pid, SIGKILL); pid = 0;} void terminate() {if (is_exec) kill(pid, SIGKILL); pid = 0;}
#endif #endif
bool waitForFinish(int timeout_msecs = 60000) {return PIThread::waitForFinish(timeout_msecs);} bool waitForFinish(int timeout_msecs = 60000) {return PIThread::waitForFinish(timeout_msecs);}
PIByteArray readOutput() {f_out.open(PIFile::Read); return f_out.readAll();} PIByteArray readOutput() {f_out.open(PIIODevice::ReadOnly); return f_out.readAll();}
PIByteArray readError() {f_err.open(PIFile::Read); return f_err.readAll();} PIByteArray readError() {f_err.open(PIIODevice::ReadOnly); return f_err.readAll();}
PIStringList environment() {return env;} PIStringList environment() {return env;}
void clearEnvironment() {env.clear();} void clearEnvironment() {env.clear();}

225
piprotocol.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Protocol, input/output channel (COM, UDP) 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 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 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(); init();
protName = name; protName = name;
PIObject::setName(name); PIObject::setName(name);
PIConfig conf(config, PIFile::Read); PIConfig conf(config, PIIODevice::ReadOnly);
if (!conf.isOpened()) { if (!conf.isOpened()) {
cout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl; piCout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
devReceiverState = devSenderState = "Config error"; devReceiverState = devSenderState = "Config error";
return; return;
} }
int ps, gps; int ps, gps;
bool ok, gok, flag, gflag, has_dev = false; bool ok, gok, flag, gflag, has_dev = false;
float freq, gfreq;
PIFlags<PISerial::Parameters> pp; PIFlags<PISerial::Parameters> pp;
PIConfig::Entry & b(conf.getValue(name)), PIConfig::Entry & b(conf.getValue(name)),
& rb(b.getValue("receiver")), & rb(b.getValue("receiver")),
@@ -40,7 +41,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
/// receiver section /// receiver section
if (rb.isEntryExists("ip") && rb.isEntryExists("device")) { 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"; devReceiverState = "Config error";
return; return;
} }
@@ -49,7 +50,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) dev = gdev; if (gok && !ok) dev = gdev;
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"; devReceiverState = "Config error";
return; return;
} }
@@ -58,20 +59,44 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) ps = gps; if (gok && !ok) ps = gps;
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"; devReceiverState = "Config error";
return; return;
} }
type_rec = PIProtocol::Ethernet; type_rec = PIProtocol::Ethernet;
eth = new PIEthernet(dev, ps, this, receiveEvent); eth = new PIEthernet();
packet_ext.setDevice(eth);
//setSenderAddress(dev, ps);
setReceiverAddress(dev, ps); setReceiverAddress(dev, ps);
has_dev = true; 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) if (recDataPtr == 0)
cout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl; piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl;
if (recDataSize == 0) if (recDataSize == 0)
cout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl; piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl;
} else { } 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"; devReceiverState = "Config error";
return; return;
} }
@@ -81,7 +106,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) dev = gdev; if (gok && !ok) dev = gdev;
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"; devReceiverState = "Config error";
return; return;
} }
@@ -90,7 +115,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) ps = gps; if (gok && !ok) ps = gps;
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"; devReceiverState = "Config error";
return; return;
} }
@@ -99,7 +124,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) flag = gflag; if (gok && !ok) flag = gflag;
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"; devReceiverState = "Config error";
return; return;
} }
@@ -110,7 +135,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) flag = gflag; if (gok && !ok) flag = gflag;
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"; devReceiverState = "Config error";
return; return;
} }
@@ -118,19 +143,30 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
} }
type_rec = PIProtocol::Serial; type_rec = PIProtocol::Serial;
type_send = 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); setReceiverDevice(dev, (PISerial::Speed)ps);
setSenderDevice(dev, (PISerial::Speed)ps);
ser->setInSpeed((PISerial::Speed)ps); ser->setInSpeed((PISerial::Speed)ps);
ser->setParameters(pp); 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; has_dev = true;
if (recDataPtr == 0) if (recDataPtr == 0)
cout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl; piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl;
if (recDataSize == 0) if (recDataSize == 0)
cout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl; piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl;
} else { } 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"; devReceiverState = "Config error";
return; return;
} }
@@ -140,7 +176,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) history_write_rec = ghist; if (gok && !ok) history_write_rec = ghist;
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"; devReceiverState = "Config error";
return; return;
} }
@@ -151,29 +187,30 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
history_id_rec = rb.getValue("historyID", 0, &ok); history_id_rec = rb.getValue("historyID", 0, &ok);
if (!ok) { if (!ok) {
history_id_rec = protName.toByteArray().checksumCRC16(); 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;
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"; devReceiverState = "Config error";
return; return;
} }
if (freq > 0.f && !has_dev) 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); float tm = b.getValue("disconnectTimeout", 3.f);
if (tm <= 0.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; timeout_ = (tm < 0.f) ? 0.f : tm;
setExpectedFrequency(freq); setExpectedFrequency(freq);
/// sender section /// sender section
if (sb.isEntryExists("ip") && sb.isEntryExists("device")) { 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"; devSenderState = "Config error";
return; return;
} }
@@ -183,7 +220,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) dev = gdev; if (gok && !ok) dev = gdev;
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"; devSenderState = "Config error";
return; return;
} }
@@ -192,20 +229,43 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) ps = gps; if (gok && !ok) ps = gps;
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"; devSenderState = "Config error";
return; return;
} }
type_send = PIProtocol::Ethernet; type_send = PIProtocol::Ethernet;
if (eth == 0) eth = new PIEthernet(dev, ps, this, receiveEvent); if (eth == 0) eth = new PIEthernet();
setSenderAddress(dev, ps); setSenderAddress(dev, ps);
//setReceiverAddress(dev, ps);
has_dev = true; 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) if (sendDataPtr_ == 0)
cout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl; piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl;
if (sendDataSize_ == 0) if (sendDataSize_ == 0)
cout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl; piCout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl;
} else { } 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"; devSenderState = "Config error";
return; return;
} }
@@ -215,7 +275,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) dev = gdev; if (gok && !ok) dev = gdev;
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"; devSenderState = "Config error";
return; return;
} }
@@ -224,7 +284,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) ps = gps; if (gok && !ok) ps = gps;
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"; devSenderState = "Config error";
return; return;
} }
@@ -233,7 +293,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) flag = gflag; if (gok && !ok) flag = gflag;
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"; devSenderState = "Config error";
return; return;
} }
@@ -244,35 +304,34 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
if (ok || gok) { if (ok || gok) {
if (gok && !ok) flag = gflag; if (gok && !ok) flag = gflag;
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"; devSenderState = "Config error";
return; return;
} }
pp |= PISerial::TwoStopBits; pp |= PISerial::TwoStopBits;
} }
} else { } 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"; devSenderState = "Config error";
return; return;
} }
type_send = PIProtocol::Serial; 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); setSenderDevice(dev, (PISerial::Speed)ps);
ser->setOutSpeed((PISerial::Speed)ps); ser->setOutSpeed((PISerial::Speed)ps);
ser->setParameters(pp); ser->setParameters(pp);
ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize);
has_dev = true; has_dev = true;
if (sendDataPtr_ == 0) if (sendDataPtr_ == 0)
cout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl; piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl;
if (sendDataSize_ == 0) 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); history_write_send = sb.getValue("writeHistory", false, &ok);
ghist = b.getValue("writeHistory", false, &gok); ghist = b.getValue("writeHistory", false, &gok);
if (ok || gok) { if (ok || gok) {
if (gok && !ok) history_write_send = ghist; if (gok && !ok) history_write_send = ghist;
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"; devSenderState = "Config error";
return; return;
} }
@@ -283,21 +342,21 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
history_id_send = sb.getValue("historyID", 0, &ok); history_id_send = sb.getValue("historyID", 0, &ok);
if (!ok) { if (!ok) {
history_id_send = protName.toByteArray().checksumCRC16() + 1; 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); freq = sb.getValue("frequency", -1.f, &ok);
gfreq = b.getValue("frequency", -1.f, &gok); gfreq = b.getValue("frequency", -1.f, &gok);
if (gok && !ok) freq = gfreq; if (gok && !ok) freq = gfreq;
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"; devSenderState = "Config error";
return; return;
} }
if (freq > 0.f && !has_dev) 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); setSenderFrequency(freq);
headerPtr = (uchar * )recHeaderPtr; headerPtr = (uchar * )recHeaderPtr;
@@ -306,6 +365,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
dataSize = recDataSize; dataSize = recDataSize;
sendDataPtr = (uchar * )sendDataPtr_; sendDataPtr = (uchar * )sendDataPtr_;
sendDataSize = sendDataSize_; sendDataSize = sendDataSize_;
packet_ext.setPacketData(recHeaderPtr, recHeaderSize, recDataSize);
if (type_rec == PIProtocol::Ethernet) { if (type_rec == PIProtocol::Ethernet) {
if (recHeaderPtr != 0) { if (recHeaderPtr != 0) {
dataPtr = (uchar * )recHeaderPtr; dataPtr = (uchar * )recHeaderPtr;
@@ -341,6 +401,9 @@ PIProtocol::~PIProtocol() {
void PIProtocol::init() { 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; work = new_mp_prot = history_write_rec = history_write_send = false;
eth = 0; eth = 0;
ser = 0; ser = 0;
@@ -379,7 +442,10 @@ void PIProtocol::init() {
void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force) { void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force) {
if (force) { if (force) {
type_send = type_rec = PIProtocol::Serial; 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) { if (type_rec == PIProtocol::Serial && ser != 0) {
ser->setDevice(device); 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) { void PIProtocol::setReceiverAddress(const PIString & ip, int port, bool force) {
if (force) { if (force) {
type_rec = PIProtocol::Ethernet; 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) { if (type_rec == PIProtocol::Ethernet && eth != 0) {
eth->setReadAddress(ip, port); 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) { void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed, bool force) {
if (force) { if (force) {
type_send = type_rec = PIProtocol::Serial; 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) { if (type_send == PIProtocol::Serial && ser != 0) {
ser->setDevice(device); ser->setDevice(device);
ser->setSpeed(speed); ser->setSpeed(speed);
ser->open();
devSenderName = device; 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) { void PIProtocol::setSenderAddress(const PIString & ip, int port, bool force) {
if (force) { if (force) {
type_send = PIProtocol::Ethernet; 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) { if (type_send == PIProtocol::Ethernet && eth != 0) {
eth->setSendAddress(ip, port); eth->setSendAddress(ip, port);
eth->open();
if (ip.isEmpty()) devSenderName = "no ip"; if (ip.isEmpty()) devSenderName = "no ip";
else devSenderName = ip + ":" + PIString::fromNumber(port); else devSenderName = ip + ":" + PIString::fromNumber(port);
} }
@@ -444,9 +515,10 @@ void PIProtocol::changeDisconnectTimeout() {
void PIProtocol::startReceive(float exp_frequency) { void PIProtocol::startReceive(float exp_frequency) {
if (exp_frequency > 0.f) exp_freq = exp_frequency; if (exp_frequency > 0.f) exp_freq = exp_frequency;
if (type_rec == PIProtocol::Serial) ser->start(); //if (type_rec == PIProtocol::Serial) ser->start();
if (type_rec == PIProtocol::Ethernet) eth->start(); //if (type_rec == PIProtocol::Ethernet) eth->start();
if (exp_freq <= 0.f) return; if (exp_freq <= 0.f) return;
packet_ext.startThreadedRead();
setExpectedFrequency(exp_freq); setExpectedFrequency(exp_freq);
diagTimer->start(1000. / exp_freq); diagTimer->start(1000. / exp_freq);
diagTimer->reset(); diagTimer->reset();
@@ -463,8 +535,9 @@ void PIProtocol::startSend(float frequency) {
void PIProtocol::stopReceive() { void PIProtocol::stopReceive() {
if (type_rec == PIProtocol::Serial) ser->stop(); //if (type_rec == PIProtocol::Serial) ser->stop();
if (type_rec == PIProtocol::Ethernet) eth->stop(); //if (type_rec == PIProtocol::Ethernet) eth->stop();
packet_ext.stop();
diagTimer->stop(); diagTimer->stop();
raiseEvent(this, "receiver stopped"); raiseEvent(this, "receiver stopped");
} }
@@ -508,7 +581,7 @@ void PIProtocol::diagEvent(void * t, int) {
p->calc_freq(); p->calc_freq();
p->calc_diag(); p->calc_diag();
p->check_state(); 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() { void PIProtocol::check_state() {
if (type_rec == PIProtocol::Serial) { if (type_rec == PIProtocol::Serial) {
if (ser != 0) { if (ser != 0) {
if (ser->initialized()) devReceiverState = "Initialized"; if (ser->isOpened()) devReceiverState = "Opened";
else devReceiverState = "Uninitialized"; else devReceiverState = "Not opened";
} }
else devReceiverState = "Uninitialized"; else devReceiverState = "Not exists";
} }
if (type_rec == PIProtocol::Ethernet) { if (type_rec == PIProtocol::Ethernet) {
if (eth != 0) { if (eth != 0) {
if (eth->receiverInitialized()) devReceiverState = "Initialized"; if (eth->isOpened()) devReceiverState = "Opened";
else devReceiverState = "Uninitialized"; else devReceiverState = "Not opened";
} }
else devReceiverState = "Uninitialized"; else devReceiverState = "Not exists";
} }
if (type_send == PIProtocol::Serial) { if (type_send == PIProtocol::Serial) {
if (ser != 0) { if (ser != 0) {
if (ser->initialized()) devSenderState = "Initialized"; if (ser->isOpened()) devSenderState = "Opened";
else devSenderState = "Uninitialized"; else devSenderState = "Not opened";
} }
else devSenderState = "Uninitialized"; else devSenderState = "Not exists";
} }
if (type_send == PIProtocol::Ethernet) { if (type_send == PIProtocol::Ethernet) {
if (eth != 0) { if (eth != 0) {
if (eth->senderInitialized()) devSenderState = "Initialized"; if (eth->isOpened()) devSenderState = "Opened";
else devSenderState = "Uninitialized"; else devSenderState = "Not opened";
} }
else devSenderState = "Uninitialized"; else devSenderState = "Not exists";
} }
} }
void PIProtocol::send(const void * data, int size) { void PIProtocol::send(const void * data, int size, bool direct) {
if (!direct) {
if (data == 0 || size == 0) return; if (data == 0 || size == 0) return;
if (!aboutSend()) return; if (!aboutSend()) return;
}
if (history_write_send) { if (history_write_send) {
history_file_send.writeToBinLog(history_id_send, data, size); history_file_send.writeToBinLog(history_id_send, data, size);
history_rsize_send.setReadableSize(history_file_send.pos()); history_rsize_send.setReadableSize(history_file_send.pos());
} }
if (type_send == PIProtocol::Serial) if (type_send == PIProtocol::Serial)
if (ser->send((uchar * )data, size)) if (ser->send(data, size))
send_count++; send_count++;
if (type_send == PIProtocol::Ethernet) if (type_send == PIProtocol::Ethernet)
if (eth->send((uchar * )data, size)) if (eth->send(data, size))
send_count++; send_count++;
} }
@@ -607,16 +682,16 @@ void PIProtocol::send() {
//lock(); //lock();
//memcpy(packet, sendDataPtr, sendDataSize); //memcpy(packet, sendDataPtr, sendDataSize);
//unlock(); //unlock();
if (sendDataPtr == 0 || sendDataSize == 0) return;
if (!aboutSend()) return; if (!aboutSend()) return;
if (sendDataPtr == 0 || sendDataSize == 0) return;
if (history_write_send) { if (history_write_send) {
history_file_send.writeToBinLog(history_id_send, sendDataPtr, sendDataSize); history_file_send.writeToBinLog(history_id_send, sendDataPtr, sendDataSize);
history_rsize_send.setReadableSize(history_file_send.pos()); history_rsize_send.setReadableSize(history_file_send.pos());
} }
if (type_send == PIProtocol::Serial) if (type_send == PIProtocol::Serial)
if (ser->send((uchar * )sendDataPtr, sendDataSize)) if (ser->send(sendDataPtr, sendDataSize))
send_count++; send_count++;
if (type_send == PIProtocol::Ethernet) if (type_send == PIProtocol::Ethernet)
if (eth->send((uchar * )sendDataPtr, sendDataSize)) if (eth->send(sendDataPtr, sendDataSize))
send_count++; send_count++;
} }

14
piprotocol.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Protocol, input/output channel (COM, UDP) 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 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 it under the terms of the GNU General Public License as published by
@@ -22,10 +22,10 @@
#include "piserial.h" #include "piserial.h"
#include "piethernet.h" #include "piethernet.h"
#include "pipacketextractor.h"
#include "pitimer.h" #include "pitimer.h"
#include "piconfig.h" #include "piconfig.h"
#include "math.h" #include "math.h"
#include "piobject.h"
class PIProtocol; class PIProtocol;
@@ -67,8 +67,8 @@ public:
EVENT_HANDLER0(PIProtocol, void, stopReceive); EVENT_HANDLER0(PIProtocol, void, stopReceive);
void setExpectedFrequency(float frequency); // for connection quality diagnostic void setExpectedFrequency(float frequency); // for connection quality diagnostic
void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial 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 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; 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; packet_ext.setPacketData(headerPtr, headerSize, dataSize);}
void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet
void setReceiverParameters(PIFlags<PISerial::Parameters> parameters) {if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial void setReceiverParameters(PIFlags<PISerial::Parameters> parameters) {if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;} void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;}
@@ -87,7 +87,8 @@ public:
EVENT_HANDLER0(PIProtocol, void, start) {startReceive(); startSend();} EVENT_HANDLER0(PIProtocol, void, start) {startReceive(); startSend();}
EVENT_HANDLER0(PIProtocol, void, stop) {stopReceive(); stopSend();} EVENT_HANDLER0(PIProtocol, void, stop) {stopReceive(); stopSend();}
EVENT_HANDLER0(PIProtocol, void, send); 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);} void setName(const PIString & name) {protName = name; PIObject::setName(name);}
PIString name() const {return protName;} PIString name() const {return protName;}
@@ -126,7 +127,7 @@ public:
void * receiveData() {return dataPtr;} void * receiveData() {return dataPtr;}
void * sendData() {return sendDataPtr;} void * sendData() {return sendDataPtr;}
PIByteArray lastHeader() {if (ser != 0) return ser->lastHeader(); return PIByteArray();} PIByteArray lastHeader() {return packet_ext.lastHeader();}
protected: 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 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(); void changeDisconnectTimeout();
ReceiveFunc ret_func; ReceiveFunc ret_func;
PIPacketExtractor packet_ext;
PITimer * diagTimer, * sendTimer; PITimer * diagTimer, * sendTimer;
PIMultiProtocolBase * mp_owner; PIMultiProtocolBase * mp_owner;
PIProtocol::Type type_send, type_rec; PIProtocol::Type type_send, type_rec;

177
piserial.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
COM 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 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 it under the terms of the GNU General Public License as published by
@@ -20,32 +20,48 @@
#include "piserial.h" #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++; piMonitor.serials++;
setPriority(piHigh); setPriority(piHigh);
path_ = device;
data = data_; data = data_;
devName = name;
fd = -1; fd = -1;
missed = 0;
dataSize = headerSize = 0;
headerPtr = 0; headerPtr = 0;
ret_func = slot; params = 0;
ret_func_header = slot_header; vtime = 1;
ret_func_ = slot;
#ifdef WINDOWS #ifdef WINDOWS
hCom = 0; hCom = 0;
#endif #endif
ispeed = ospeed = S115200; 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() { PISerial::~PISerial() {
piMonitor.serials--; piMonitor.serials--;
terminate();
} }
void PISerial::terminate() { bool PISerial::closeDevice() {
if (!initialized()) return; if (!isInitialized()) return true;
if (isRunning()) { if (isRunning()) {
stop(); stop();
PIThread::terminate(); PIThread::terminate();
@@ -60,10 +76,11 @@ void PISerial::terminate() {
#else #else
if (fd != -1) { if (fd != -1) {
tcsetattr(fd, TCSANOW, &sdesc); tcsetattr(fd, TCSANOW, &sdesc);
close(fd); ::close(fd);
fd = -1; fd = -1;
} }
#endif #endif
return true;
} }
@@ -85,79 +102,51 @@ int PISerial::convertSpeed(PISerial::Speed speed) {
} }
void PISerial::begin() { bool PISerial::read(void * data, int size, double timeout_ms) {
allReaded = addSize = curInd = 0; if (data == 0) return false;
first = false; int ret, all = 0;
packetSize = headerSize + dataSize; if (timeout_ms > 0.) {
if (headerSize > 0) mheader.resize(headerSize); setReadIsBlocking(false);
if (!init()) stop(); 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);
} }
return (all == size);
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;
}
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;
} else { } else {
ret_func(data, buffer, dataSize); setReadIsBlocking(true);
memcpy(sbuffer, buffer, allReaded); all = ::read(fd, data, 1);
memcpy(buffer, &sbuffer[packetSize], allReaded); while (all < size) {
allReaded -= packetSize; ret = ::read(fd, &((uchar * )data)[all], size - all);
if (ret > 0) all += ret;
} }
return (all == size);
}
return false;
} }
void PISerial::end() { bool PISerial::openDevice() {
terminate();
}
bool PISerial::init() {
#ifdef WINDOWS #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) { if(hCom == INVALID_HANDLE_VALUE) {
cout << "[PISerial] Unable to open \"" << devName << "\"" << endl; piCout << "[PISerial] Unable to open \"" << path_ << "\"" << endl;
return false; return false;
} }
fd = 0; fd = 0;
COMMTIMEOUTS times; COMMTIMEOUTS times;
times.ReadIntervalTimeout = 1; times.ReadIntervalTimeout = vtime;
times.ReadTotalTimeoutConstant = 1; times.ReadTotalTimeoutConstant = 1;
times.ReadTotalTimeoutMultiplier = 0; times.ReadTotalTimeoutMultiplier = 0;
times.WriteTotalTimeoutConstant = 0; times.WriteTotalTimeoutConstant = 1;
times.WriteTotalTimeoutMultiplier = 1; times.WriteTotalTimeoutMultiplier = 0;
if (SetCommTimeouts(hCom, &times) == -1) { if (SetCommTimeouts(hCom, &times) == -1) {
cout << "[PISerial] Unable to set timeouts for \"" << devName << "\"" << endl; piCout << "[PISerial] Unable to set timeouts for \"" << path_ << "\"" << endl;
CloseHandle(hCom); CloseHandle(hCom);
fd = -1; fd = -1;
return false; return false;
@@ -175,15 +164,22 @@ bool PISerial::init() {
} }
desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT; desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
if (SetCommState(hCom, &desc) == -1) { 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); CloseHandle(hCom);
fd = -1; fd = -1;
return false; return false;
} }
#else #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) { if(fd == -1) {
cout << "[PISerial] Unable to open \"" << devName << "\"" << endl; piCout << "[PISerial] Unable to open \"" << path_ << "\"" << endl;
return false; return false;
} }
fcntl(fd, F_SETFL, 0); fcntl(fd, F_SETFL, 0);
@@ -191,48 +187,47 @@ bool PISerial::init() {
tcgetattr(fd, &desc); tcgetattr(fd, &desc);
sdesc = desc; sdesc = desc;
desc.c_iflag = desc.c_oflag = desc.c_lflag = 0; 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::TwoStopBits]) desc.c_cflag |= CSTOPB;
if (params[PISerial::ParityControl]) { if (params[PISerial::ParityControl]) {
desc.c_iflag |= INPCK; desc.c_iflag |= INPCK;
desc.c_cflag |= PARENB; desc.c_cflag |= PARENB;
if (params[PISerial::ParityOdd]) desc.c_cflag |= PARODD; if (params[PISerial::ParityOdd]) desc.c_cflag |= PARODD;
} }
desc.c_cc[VMIN] = 0; desc.c_cc[VMIN] = 1;
desc.c_cc[VTIME] = 1; desc.c_cc[VTIME] = vtime;
cfsetispeed(&desc, convertSpeed(ispeed)); cfsetispeed(&desc, convertSpeed(ispeed));
cfsetospeed(&desc, convertSpeed(ospeed)); cfsetospeed(&desc, convertSpeed(ospeed));
if(tcsetattr(fd, TCSANOW, &desc) < 0) { if(tcsetattr(fd, TCSANOW, &desc) < 0) {
cout << "[PISerial] Can`t set attributes for \"" << devName << "\"" << endl; piCout << "[PISerial] Can`t set attributes for \"" << path_ << "\"" << endl;
close(fd); ::close(fd);
return false; return false;
} }
tcflush(fd, TCIOFLUSH); tcflush(fd, TCIOFLUSH);
//cout << "[PISerial] Initialized " << devName << endl; //piCout << "[PISerial] Initialized " << path_ << endl;
#endif #endif
return true; return true;
} }
bool PISerial::send(uchar * data, int size) { int PISerial::write(const void * data, int max_size, bool wait) {
//cout << "[PISerial] send size: " << sizeof(data) << endl; //piCout << "[PISerial] send size: " << sizeof(data) << endl;
if (fd == -1) { if (fd == -1 || !canWrite()) {
//cout << "[PISerial] Can`t write to uninitialized COM" << endl; //piCout << "[PISerial] Can`t write to uninitialized COM" << endl;
return false; return -1;
} }
#ifdef WINDOWS #ifdef WINDOWS
DWORD wrote; DWORD wrote;
WriteFile(hCom, data, size, &wrote, 0); WriteFile(hCom, data, max_size, &wrote, 0);
#else #else
int wrote; int wrote;
wrote = write(fd, data, size); wrote = ::write(fd, data, max_size);
if (wait) tcdrain(fd);
#endif #endif
if ((int)wrote != size) { return (int)wrote;
//cout << "[PISerial] Error while sending" << endl; //piCout << "[PISerial] Error while sending" << endl;
return false; //piCout << "[PISerial] Wrote " << wrote << " bytes in " << path_ << endl;
}
//cout << "[PISerial] Wrote " << wrote << " bytes in " << devName << endl;
return true;
} }

85
piserial.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
COM 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 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 it under the terms of the GNU General Public License as published by
@@ -20,8 +20,8 @@
#ifndef PISERIAL_H #ifndef PISERIAL_H
#define PISERIAL_H #define PISERIAL_H
#include "pithread.h" #include "pitimer.h"
#include "pistring.h" #include "piiodevice.h"
#ifndef WINDOWS #ifndef WINDOWS
# include <termios.h> # include <termios.h>
# include <fcntl.h> # include <fcntl.h>
@@ -42,16 +42,12 @@
# define B256000 256000 # define B256000 256000
#endif #endif
#define SERIAL_BUFFER_SIZE 4096 class PISerial: public PIIODevice {
typedef bool (*SerialFunc)(void * , uchar * , int );
typedef bool (*SerialHeaderFunc)(void * , uchar * , uchar * , int );
class PISerial: public PIThread {
public: public:
// slot is any function format "bool <func>(void*, uchar*, int)" // slot is any function format "bool <func>(void*, uchar*, int)"
// slot_header is any function format "bool <func>(void*, uchar*, uchar*, int)" // slot_header is any function format "bool <func>(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(); ~PISerial();
enum Parameters {ParityControl = 0x01, ParityOdd = 0x02, TwoStopBits = 0x04}; enum Parameters {ParityControl = 0x01, ParityOdd = 0x02, TwoStopBits = 0x04};
@@ -69,31 +65,59 @@ public:
S115200 = 115200 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 setSpeed(PISerial::Speed speed) {ospeed = ispeed = speed;}
void setOutSpeed(PISerial::Speed speed) {ospeed = speed;} void setOutSpeed(PISerial::Speed speed) {ospeed = speed;}
void setInSpeed(PISerial::Speed speed) {ispeed = 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<PISerial::Parameters> parameters) {params = parameters;} void setParameters(PIFlags<PISerial::Parameters> parameters) {params = parameters;}
void setData(void * d) {data = d;} void setParameter(PISerial::Parameters parameter, bool on = true) {params.setFlag(parameter, on);}
void setReadData(void * headerPtr, int headerSize, int dataSize) {this->headerPtr = headerPtr; this->headerSize = headerSize; this->dataSize = dataSize;} void setVTime(int t) {vtime = t;}
bool send(uchar * data, int size); #ifdef WINDOWS
bool init(); void setReadIsBlocking(bool yes) {
bool initialized() const {return fd != -1;} COMMTIMEOUTS times;
void terminate(); times.ReadIntervalTimeout = yes ? vtime : MAXDWORD;
times.ReadTotalTimeoutConstant = yes ? 1 : 0;
times.ReadTotalTimeoutMultiplier = 0;
times.WriteTotalTimeoutConstant = 1;
times.WriteTotalTimeoutMultiplier = 0;
if (isOpened()) SetCommTimeouts(hCom, &times);
}
#else
void setReadIsBlocking(bool yes) {if (isOpened()) fcntl(fd, F_SETFL, yes ? 0 : O_NONBLOCK);}
#endif
PIByteArray lastHeader() {return mheader;} const PIString & device() const {return path_;}
ullong missedBytes() const {return missed;} PISerial::Speed outSpeed() const {return ospeed;}
ullong missedPackets() const {return (packetSize == 0 ? 0 : missed / packetSize);} 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); 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;} 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(); bool openDevice();
void run(); bool closeDevice();
void end();
#ifdef WINDOWS #ifdef WINDOWS
DCB desc, sdesc; DCB desc, sdesc;
@@ -103,18 +127,11 @@ private:
termios desc, sdesc; termios desc, sdesc;
uint readed; uint readed;
#endif #endif
int fd; int fd, vtime;
PISerial::Speed ospeed, ispeed; PISerial::Speed ospeed, ispeed;
PIString devName; PITimer timer;
SerialFunc ret_func;
SerialHeaderFunc ret_func_header;
uchar buffer[SERIAL_BUFFER_SIZE], sbuffer[SERIAL_BUFFER_SIZE];
PIByteArray mheader;
void * headerPtr, * data; void * headerPtr, * data;
int dataSize, headerSize, packetSize, allReaded, addSize, curInd;
ullong missed;
PIFlags<PISerial::Parameters> params; PIFlags<PISerial::Parameters> params;
bool first;
}; };

2
pisignals.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Signals 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 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 it under the terms of the GNU General Public License as published by

2
pisignals.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Signals 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 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 it under the terms of the GNU General Public License as published by

54
pistring.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
String 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 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 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; break;
} }
} }
delete c; delete[] c;
return *this; 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<PIByteArray * >(&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 PIString::convertToStd() const {
string s; string s;
if (size() > 0) { if (size() > 0) {
@@ -332,7 +356,7 @@ string PIString::convertToStd() const {
char PIString::toChar() const { char PIString::toChar() const {
PIString s(toNativeDecimalPoints()); PIString s(toNativeDecimalPoints());
char v; char v;
sscanf(s.stdString().c_str(), "%c", &v); sscanf(s.data(), "%c", &v);
return v; return v;
} }
@@ -340,9 +364,9 @@ char PIString::toChar() const {
short PIString::toShort() const { short PIString::toShort() const {
PIString s(trimmed().toLowerCase().toNativeDecimalPoints()); PIString s(trimmed().toLowerCase().toNativeDecimalPoints());
short v; short v;
if (s.left(2) == "0x") {sscanf(s.stdString().c_str(), "%hx", &v); return v;} if (s.left(2) == "0x") {sscanf(s.data(), "%hx", &v); return v;}
if (s.left(1) == "0") {sscanf(s.stdString().c_str(), "%ho", &v); return v;} if (s.left(1) == "0") {sscanf(s.data(), "%ho", &v); return v;}
sscanf(s.stdString().c_str(), "%hd", &v); sscanf(s.data(), "%hd", &v);
return v; return v;
} }
@@ -350,9 +374,9 @@ short PIString::toShort() const {
int PIString::toInt() const { int PIString::toInt() const {
PIString s(trimmed().toLowerCase().toNativeDecimalPoints()); PIString s(trimmed().toLowerCase().toNativeDecimalPoints());
int v; int v;
if (s.left(2) == "0x") {sscanf(s.stdString().c_str(), "%x", &v); return v;} if (s.left(2) == "0x") {sscanf(s.data(), "%x", &v); return v;}
if (s.left(1) == "0") {sscanf(s.stdString().c_str(), "%o", &v); return v;} if (s.left(1) == "0") {sscanf(s.data(), "%o", &v); return v;}
sscanf(s.stdString().c_str(), "%d", &v); sscanf(s.data(), "%d", &v);
return v; return v;
} }
@@ -360,9 +384,9 @@ int PIString::toInt() const {
long PIString::toLong() const { long PIString::toLong() const {
PIString s(trimmed().toLowerCase().toNativeDecimalPoints()); PIString s(trimmed().toLowerCase().toNativeDecimalPoints());
long v; long v;
if (s.left(2) == "0x") {sscanf(s.stdString().c_str(), "%lx", &v); return v;} if (s.left(2) == "0x") {sscanf(s.data(), "%lx", &v); return v;}
if (s.left(1) == "0") {sscanf(s.stdString().c_str(), "%lo", &v); return v;} if (s.left(1) == "0") {sscanf(s.data(), "%lo", &v); return v;}
sscanf(s.stdString().c_str(), "%ld", &v); sscanf(s.data(), "%ld", &v);
return v; return v;
} }
@@ -370,9 +394,9 @@ long PIString::toLong() const {
llong PIString::toLLong() const { llong PIString::toLLong() const {
PIString s(trimmed().toLowerCase().toNativeDecimalPoints()); PIString s(trimmed().toLowerCase().toNativeDecimalPoints());
llong v; llong v;
if (s.left(2) == "0x") {sscanf(s.stdString().c_str(), "%llx", &v); return v;} if (s.left(2) == "0x") {sscanf(s.data(), "%llx", &v); return v;}
if (s.left(1) == "0") {sscanf(s.stdString().c_str(), "%llo", &v); return v;} if (s.left(1) == "0") {sscanf(s.data(), "%llo", &v); return v;}
sscanf(s.stdString().c_str(), "%lld", &v); sscanf(s.data(), "%lld", &v);
return v; return v;
} }

19
pistring.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
String 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 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 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 & 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 & 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 & 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();} const string stdString() const {return convertToStd();}
wstring stdWString() const {return convertToWString();} wstring stdWString() const {return convertToWString();}
PIByteArray toByteArray() {string s(convertToStd()); return PIByteArray(s.c_str(), s.length());} PIByteArray toByteArray() {string s(convertToStd()); return PIByteArray(s.c_str(), s.length());}
@@ -153,15 +157,15 @@ public:
int length() const {return size();} int length() const {return size();}
bool isEmpty() const {return (size() == 0 || *this == "");} 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; char toChar() const;
short toShort() const; short toShort() const;
int toInt() const; int toInt() const;
long toLong() const; long toLong() const;
llong toLLong() const; llong toLLong() const;
float toFloat() const {PIString s(*this); return (float)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().stdString().c_str());} double toDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());}
ldouble toLDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().stdString().c_str());} ldouble toLDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());}
//inline PIString & setNumber(const char value) {clear(); *this += itos(value); return *this;} //inline PIString & setNumber(const char value) {clear(); *this += itos(value); return *this;}
PIString & setNumber(const int 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; string convertToStd() const;
wstring convertToWString() const {wstring s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toWChar()); return s;} 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; //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::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;} inline PIString operator +(const PIString & str, const PIString & f) {PIString s(str); s += f; return s;}

8
pisystemmonitor.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Process resource monitor 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 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 it under the terms of the GNU General Public License as published by
@@ -39,10 +39,10 @@ bool PISystemMonitor::startOnProcess(int pID) {
stop(); stop();
pID_ = pID; pID_ = pID;
#ifndef WINDOWS #ifndef WINDOWS
file.open("/proc/" + PIString::fromNumber(pID_) + "/stat", PIFile::Read); file.open("/proc/" + PIString::fromNumber(pID_) + "/stat", PIIODevice::ReadOnly);
filem.open("/proc/" + PIString::fromNumber(pID_) + "/statm", PIFile::Read); filem.open("/proc/" + PIString::fromNumber(pID_) + "/statm", PIIODevice::ReadOnly);
if (!file.isOpened()) { 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; return false;
} }
cycle = -1; cycle = -1;

2
pisystemmonitor.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Process resource monitor 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 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 it under the terms of the GNU General Public License as published by

45
pithread.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Thread 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 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 it under the terms of the GNU General Public License as published by
@@ -20,23 +20,26 @@
#include "pithread.h" #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++; 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; running = lockRun = false;
priority_ = piNormal; priority_ = piNormal;
timer = timer_delay; timer = timer_delay;
/*addEvent("started");
addEvent("stopped");
addEventHandler<int>(HANDLER(PIThread, start));
addEventHandler(HANDLER(PIThread, startOnce));
addEventHandler(HANDLER(PIThread, stop));
addEventHandler<bool>(HANDLER(PIThread, terminate));*/
if (startNow) start(timer_delay); if (startNow) start(timer_delay);
} }
#ifndef WINDOWS
#else
#endif
PIThread::~PIThread() { PIThread::~PIThread() {
piMonitor.threads--; piMonitor.threads--;
@@ -57,14 +60,17 @@ bool PIThread::start(int timer_delay) {
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setschedparam(&attr, &sparam); pthread_attr_setschedparam(&attr, &sparam);
if (pthread_create(&thread, &attr, thread_function, this) == 0) { if (pthread_create(&thread, &attr, thread_function, this) == 0) {
setPriority(priority_);
running = true; running = true;
return true; return true;
} }
#else #else
thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, this, 0, 0); thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, this, 0, 0);
if (thread == 0) if (thread != 0) {
return false;
setPriority(priority_); setPriority(priority_);
running = true;
return true;
}
#endif #endif
return false; return false;
} }
@@ -76,13 +82,18 @@ bool PIThread::startOnce() {
pthread_attr_t attr; pthread_attr_t attr;
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setschedparam(&attr, &sparam); 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; return true;
}
#else #else
thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function_once, this, 0, 0); thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function_once, this, 0, 0);
if (thread == 0) if (thread != 0) {
return false;
setPriority(priority_); setPriority(priority_);
running = true;
return false;
}
#endif #endif
return false; return false;
} }
@@ -110,6 +121,7 @@ void * PIThread::thread_function(void * t) {
while (!ct->terminating) { while (!ct->terminating) {
if (ct->lockRun) ct->mutex_.lock(); if (ct->lockRun) ct->mutex_.lock();
ct->run(); ct->run();
if (ct->ret_func != 0) ct->ret_func(ct->data_);
if (ct->lockRun) ct->mutex_.unlock(); if (ct->lockRun) ct->mutex_.unlock();
if (ct->timer > 0) msleep(ct->timer); if (ct->timer > 0) msleep(ct->timer);
} }
@@ -133,6 +145,7 @@ void * PIThread::thread_function_once(void * t) {
raiseEvent(ct, "started"); raiseEvent(ct, "started");
if (ct->lockRun) ct->mutex_.lock(); if (ct->lockRun) ct->mutex_.lock();
ct->run(); ct->run();
if (ct->ret_func != 0) ct->ret_func(ct->data_);
if (ct->lockRun) ct->mutex_.unlock(); if (ct->lockRun) ct->mutex_.unlock();
raiseEvent(ct, "stopped"); raiseEvent(ct, "stopped");
ct->end(); ct->end();

21
pithread.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Thread 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 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 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);} inline void msleep(int msecs) {usleep(msecs * 1000);}
#endif #endif
typedef void (*ThreadFunc)(void * );
class PIThread: public PIObject { class PIThread: public PIObject {
public: public:
PIThread(void * data, ThreadFunc func, bool startNow = false, int timer_delay = -1);
PIThread(bool startNow = false, int timer_delay = -1); PIThread(bool startNow = false, int timer_delay = -1);
~PIThread(); ~PIThread();
@@ -52,11 +55,16 @@ public:
//bool start(int timer_delay = -1); //bool start(int timer_delay = -1);
EVENT_HANDLER0(PIThread, bool, start) {return start(-1);} EVENT_HANDLER0(PIThread, bool, start) {return start(-1);}
EVENT_HANDLER1(PIThread, bool, start, int, timer_delay); 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_HANDLER0(PIThread, bool, startOnce);
EVENT_HANDLER1(PIThread, bool, startOnce, ThreadFunc, func) {ret_func = func; return startOnce();}
EVENT_HANDLER0(PIThread, void, stop) {stop(false);} EVENT_HANDLER0(PIThread, void, stop) {stop(false);}
EVENT_HANDLER1(PIThread, void, stop, bool, wait) {terminating = true; if (wait) waitForFinish();} EVENT_HANDLER1(PIThread, void, stop, bool, wait) {terminating = true; if (wait) waitForFinish();}
EVENT_HANDLER0(PIThread, void, terminate) {terminate(false);} EVENT_HANDLER0(PIThread, void, terminate) {terminate(false);}
EVENT_HANDLER1(PIThread, void, terminate, bool, hard); 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); void setPriority(PIThread::Priority prior);
PIThread::Priority priority() const {return priority_;} PIThread::Priority priority() const {return priority_;}
bool isRunning() const {return running;} bool isRunning() const {return running;}
@@ -69,19 +77,20 @@ public:
EVENT_HANDLER0(PIThread, void, unlock) {mutex_.unlock();} EVENT_HANDLER0(PIThread, void, unlock) {mutex_.unlock();}
PIMutex & mutex() {return mutex_;} PIMutex & mutex() {return mutex_;}
private:
virtual void begin() {;} // executed at start
virtual void run() {;} // main loop
virtual void end() {;} // executed at finish
protected: protected:
static void * thread_function(void * t); static void * thread_function(void * t);
static void * thread_function_once(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; volatile bool terminating, running, lockRun;
int timer, policy; int timer, policy;
void * data_;
PIMutex mutex_; PIMutex mutex_;
PIThread::Priority priority_; PIThread::Priority priority_;
ThreadFunc ret_func;
#ifndef WINDOWS #ifndef WINDOWS
pthread_t thread; pthread_t thread;
sched_param sparam; sched_param sparam;

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Timer 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 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 it under the terms of the GNU General Public License as published by
@@ -56,11 +56,15 @@ PITimer::~PITimer() {
#ifndef WINDOWS #ifndef WINDOWS
void PITimer::start(double msecs) { 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_nsec = ((int)(msecs * 1000) % 1000000) * 1000;
spec.it_interval.tv_sec = (time_t)(msecs / 1000); spec.it_interval.tv_sec = (time_t)(msecs / 1000);
spec.it_value = spec.it_interval; spec.it_value = spec.it_interval;
ti = timer_create(CLOCK_REALTIME, &se, &timer); 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); timer_settime(timer, 0, &spec, 0);
running = true; running = true;
} }
@@ -119,11 +123,10 @@ void PITimer::run() {
double PITimer::elapsed_n() { double PITimer::elapsed_n() {
#ifdef WINDOWS #ifdef WINDOWS
t_cur = GetCurrentTime(); t_cur = GetCurrentTime();
return (t_cur * 1000000. - t_st * 1000000.); return (t_cur - t_st) * 1000000.;
#else #else
clock_gettime(0, &t_cur); clock_gettime(0, &t_cur);
return (t_cur.tv_sec * 1.e+9 + t_cur.tv_nsec) - return (t_cur.tv_sec - t_st.tv_sec) * 1.e+9 + (t_cur.tv_nsec - t_st.tv_nsec);
(t_st.tv_sec * 1.e+9 + t_st.tv_nsec);
#endif #endif
} }
@@ -131,11 +134,10 @@ double PITimer::elapsed_n() {
double PITimer::elapsed_u() { double PITimer::elapsed_u() {
#ifdef WINDOWS #ifdef WINDOWS
t_cur = GetCurrentTime(); t_cur = GetCurrentTime();
return (t_cur * 1000. - t_st * 1000.); return (t_cur - t_st) * 1000.;
#else #else
clock_gettime(0, &t_cur); clock_gettime(0, &t_cur);
return (t_cur.tv_sec * 1.e+6 + (t_cur.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;
(t_st.tv_sec * 1.e+6 + (t_st.tv_nsec / 1.e+3));
#endif #endif
} }
@@ -146,8 +148,7 @@ double PITimer::elapsed_m() {
return (double)(t_cur - t_st); return (double)(t_cur - t_st);
#else #else
clock_gettime(0, &t_cur); clock_gettime(0, &t_cur);
return (t_cur.tv_sec * 1.e+3 + (t_cur.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;
(t_st.tv_sec * 1.e+3 + (t_st.tv_nsec / 1.e+6));
#endif #endif
} }
@@ -155,11 +156,102 @@ double PITimer::elapsed_m() {
double PITimer::elapsed_s() { double PITimer::elapsed_s() {
#ifdef WINDOWS #ifdef WINDOWS
t_cur = GetCurrentTime(); t_cur = GetCurrentTime();
return (t_cur / 1000. - t_st / 1000.); return (t_cur - t_st) / 1000.;
#else #else
clock_gettime(0, &t_cur); clock_gettime(0, &t_cur);
return (t_cur.tv_sec + (t_cur.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;
(t_st.tv_sec + (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 #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 time2string(const PITime & time, const PIString & format) {
PIString ts = format; PIString ts = format;
ts.replace("hh", PIString::fromNumber(time.hours).expandLeftTo(2, '0')); ts.replace("hh", PIString::fromNumber(time.hours).expandLeftTo(2, '0'));

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Timer 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 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 it under the terms of the GNU General Public License as published by
@@ -32,12 +32,14 @@ struct PITime {
int seconds; int seconds;
int minutes; int minutes;
int hours; int hours;
PIString toString(const PIString & format = "h:mm:ss");
}; };
struct PIDate { struct PIDate {
int day; int day;
int month; int month;
int year; // since 1900 int year; // since 1900
PIString toString(const PIString & format = "d.mm.yyyy");
}; };
class PITimer class PITimer
@@ -77,11 +79,21 @@ public:
double elapsed_m(); // miliseconds double elapsed_m(); // miliseconds
double elapsed_s(); // seconds 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: private:
#ifdef WINDOWS #ifdef WINDOWS
void run(); void run();
long int t_st, t_cur; long t_st, t_cur;
#else #else
static void timer_event(sigval e); static void timer_event(sigval e);
@@ -109,7 +121,7 @@ private:
PITime currentTime(); PITime currentTime();
PIDate currentDate(); PIDate currentDate();
PIString time2string(const PITime & time, const PIString & format = "h:mm:ss"); 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"); PIString date2string(const PIDate & date, const PIString & format = "d.mm.yyyy"); // obsolete, use PITime.toString() instead
#endif // PITIMER_H #endif // PITIMER_H

6
pivariable.cpp Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Variable, Struct (simple serialization) 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 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 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::String: return vString == v.vString;
case PIVariant::StringList: return vStringList == v.vStringList; case PIVariant::StringList: return vStringList == v.vStringList;
}; };
return false;
} }
@@ -84,6 +85,7 @@ PIString PIVariant::stringValue() const {
case PIVariant::String: return vString; case PIVariant::String: return vString;
case PIVariant::StringList: return vStringList.join("%|%"); case PIVariant::StringList: return vStringList.join("%|%");
}; };
return vString;
} }
@@ -214,7 +216,7 @@ void PIVariable::writeVariable(char * dest) {
void PIStruct::parseFile(const PIString & file) { void PIStruct::parseFile(const PIString & file) {
PIConfig conf(file, PIFile::Read); PIConfig conf(file, PIIODevice::ReadOnly);
PIVariable var; PIVariable var;
PIString ts; PIString ts;
uint sz = 0; uint sz = 0;

2
pivariable.h Normal file → Executable file
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Variable, Struct (simple serialization) 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 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 it under the terms of the GNU General Public License as published by

BIN
Описание.odt Normal file → Executable file

Binary file not shown.

BIN
Описание.pdf Normal file → Executable file

Binary file not shown.