30.11.2010 - initial commit

This commit is contained in:
peri4
2010-11-30 08:11:27 +03:00
commit 2925e4d786
24 changed files with 2403 additions and 0 deletions

32
.kdev4/pip.kdev4 Normal file
View File

@@ -0,0 +1,32 @@
[Buildset]
BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00p\x00i\x00p)
[CMake]
BuildDirs=/home/peri4/pprojects/pip/
CMakeDir=/usr/share/cmake/Modules
Current CMake Binary=file:///usr/bin/cmake
CurrentBuildDir=file:///home/peri4/pprojects/pip/
CurrentBuildType=Debug
CurrentInstallDir=
ProjectRootRelative=./
[Launch]
Launch Configurations=Launch Configuration 0
[Launch][Launch Configuration 0]
Configured Launch Modes=execute
Configured Launchers=nativeAppLauncher
Name=pip
Type=Native Application
[Launch][Launch Configuration 0][Data]
Arguments=
Dependencies=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00p\x00i\x00p)
Dependency Action=Build
EnvironmentGroup=default
Project Target=pip,pip
Working Directory=
isExecutable=false
[Project]
VersionControlSupport=kdevgit

11
CMakeLists.txt Normal file
View File

@@ -0,0 +1,11 @@
project(pip)
cmake_minimum_required(VERSION 2.6)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} .)
file(GLOB CPPS "*.cpp")
add_definitions(-O2 -g3 -DMV_DEBUG)
add_executable(pip ${CPPS})
if (${WIN32})
target_link_libraries(pip pthread ws2_32)
else (${WIN32})
target_link_libraries(pip pthread rt)
endif (${WIN32})

5
main.cpp Normal file
View File

@@ -0,0 +1,5 @@
#include "pitimer.h"
int main(int argc, char * argv[]) {
cout << date2string(currentDate()) << endl;
};

253
piconfig.cpp Normal file
View File

@@ -0,0 +1,253 @@
#include "piconfig.h"
PIConfig::PIConfig(const string & path): PIFile(path) {
if (!isOpened())
open(path, Read | Write | New);
parse();
}
bool PIConfig::getValue(const string & vname, const bool def, bool * exist) const {
return atob(getValue(vname, btos(def), exist));}
char PIConfig::getValue(const string & vname, const char def, bool * exist) const {
return atoi(getValue(vname, string(1, def), exist).c_str());}
short PIConfig::getValue(const string & vname, const short def, bool * exist) const {
return atoi(getValue(vname, itos(def), exist).c_str());}
int PIConfig::getValue(const string & vname, const int def, bool * exist) const {
return atoi(getValue(vname, itos(def), exist).c_str());}
long PIConfig::getValue(const string & vname, const long def, bool * exist) const {
return atoi(getValue(vname, ltos(def), exist).c_str());}
uchar PIConfig::getValue(const string & vname, const uchar def, bool * exist) const {
return atoi(getValue(vname, uitos(def), exist).c_str());}
ushort PIConfig::getValue(const string & vname, const ushort def, bool * exist) const {
return atoi(getValue(vname, uitos(def), exist).c_str());}
uint PIConfig::getValue(const string & vname, const uint def, bool * exist) const {
return atoi(getValue(vname, uitos(def), exist).c_str());}
ulong PIConfig::getValue(const string & vname, const ulong def, bool * exist) const {
return atoi(getValue(vname, ultos(def), exist).c_str());}
float PIConfig::getValue(const string & vname, const float def, bool * exist) const {
return atof(getValue(vname, ftos(def), exist).c_str());}
double PIConfig::getValue(const string & vname, const double def, bool * exist) const {
return atof(getValue(vname, dtos(def), exist).c_str());}
void PIConfig::setValue(const string & name, const char * value, bool write) {
setValue(name, string(value), "s", write);}
void PIConfig::setValue(const string & name, const bool value, bool write) {
setValue(name, btos(value), "b", write);}
void PIConfig::setValue(const string & name, const char value, bool write) {
setValue(name, string(1, value), "s", write);}
void PIConfig::setValue(const string & name, const short value, bool write) {
setValue(name, itos(value), "n", write);}
void PIConfig::setValue(const string & name, const int value, bool write) {
setValue(name, itos(value), "n", write);}
void PIConfig::setValue(const string & name, const long value, bool write) {
setValue(name, ltos(value), "n", write);}
void PIConfig::setValue(const string & name, const uchar value, bool write) {
setValue(name, uitos(value), "n", write);}
void PIConfig::setValue(const string & name, const ushort value, bool write) {
setValue(name, uitos(value), "n", write);}
void PIConfig::setValue(const string & name, const uint value, bool write) {
setValue(name, uitos(value), "n", write);}
void PIConfig::setValue(const string & name, const ulong value, bool write) {
setValue(name, ultos(value), "n", write);}
void PIConfig::setValue(const string & name, const float value, bool write) {
setValue(name, ftos(value), "f", write);}
void PIConfig::setValue(const string & name, const double value, bool write) {
setValue(name, dtos(value), "f", write);}
string PIConfig::getValue(const string & vname, const string & def, bool * exist) const {
for (int i = 0; i < settname.size(); i++) {
if (settname[i] == vname) {
if (exist != 0) *exist = true;
return settval[i];
}
}
if (exist != 0) *exist = false;
return def;
}
void PIConfig::setValue(const string & name, const string & value, const string & type, bool write) {
int number = getNumber(name);
if (number == -1) {
addLine(name, value, type);
return;
}
string tmp = settname[number] + " = " + value + " #" + setttype[number] + " " + settcom[number];
settval[number] = value;
all[settlines[number]] = tmp;
if (write) writeAll();
}
bool PIConfig::existsValue(const string & name) {
for (int i = 0; i < settname.size(); i++)
if (settname[i] == name) return true;
return false;
}
void PIConfig::addLine(const string & name, const string & value, const string & type) {
if (setttab.size() > 0) *this << setttab[setttab.size() - 1] << name << " = " << value << " #" << type << "\n";
else *this << name << " = " << value << " #" << type << "\n";
settname.push_back(name);
settval.push_back(value);
settcom.push_back("");
setttype.push_back(type);
if (setttab.size() > 0) setttab.push_back(setttab[setttab.size() - 1]);
else setttab.push_back("\t");
settlines.push_back(all.size());
all.push_back(name + " = " + value + " #" + type);
flush();
}
void PIConfig::insertLine(int number, const string & name, const string & value, const string & type) {
if (number >= settname.size()) {
addLine(name, value, type);
return;
}
settname.insert(settname.begin() + number, name);
settval.insert(settval.begin() + number, value);
settcom.insert(settcom.begin() + number, "");
setttab.insert(setttab.begin() + number, setttab[number]);
setttype.insert(setttype.begin() + number, type);
settlines.insert(settlines.begin() + number, settlines[number]);
for (int i = number + 1; i < settlines.size(); i++) settlines[i]++;
all.insert(all.begin() + settlines[number], name + " = " + value + " #" + type);
flush();
writeAll();
}
int PIConfig::getNumber(const string & name) {
for (int i = 0; i < settname.size(); i++)
if (settname[i] == name)
return i;
return -1;
}
void PIConfig::setValue(int number, const string & value, bool write) {
string tmp = settname[number] + " = " + value + " #" + setttype[number] + " " + settcom[number];
settval[number] = value;
all[settlines[number]] = tmp;
if (write) writeAll();
}
void PIConfig::setName(int number, const string & name) {
string tmp = name + " = " + settval[number] + " #" + setttype[number] + " " + settcom[number];
settname[number] = name;
all[settlines[number]] = tmp;
writeAll();
}
void PIConfig::setType(int number, const string & type) {
string tmp = settname[number] + " = " + settval[number] + " #" + type + " " + settcom[number];
setttype[number] = type;
all[settlines[number]] = tmp;
writeAll();
}
void PIConfig::setComment(int number, const string & comment) {
string tmp = settname[number] + " = " + settval[number] + " #" + setttype[number] + " " + comment;
settcom[number] = comment;
all[settlines[number]] = tmp;
writeAll();
}
void PIConfig::deleteLine(const string & name) {
bool exist = false;
int i;
for (i = 0; i < settname.size(); i++) {
if (settname[i] == name) {
exist = true;
break;
}
}
if (!exist) return;
deleteLine(i);
}
void PIConfig::deleteLine(int number) {
settname.erase(settname.begin() + number);
settval.erase(settval.begin() + number);
settcom.erase(settcom.begin() + number);
setttab.erase(setttab.begin() + number);
setttype.erase(setttype.begin() + number);
all.erase(all.begin() + settlines[number]);
for (int i = number; i < settlines.size(); i++) settlines[i]--;
settlines.erase(settlines.begin() + number);
writeAll();
}
void PIConfig::writeAll() {
clear();
int c = 0;
for (int i = 0; i < all.size() - 1; i++) {
if (c < settlines.size() && c < setttab.size()) {
if (settlines[c] == i) {
*this << setttab[c];
c++;
}
}
*this << all[i] << "\n";
}
readAll();
}
void PIConfig::readAll() {
settname.clear();
settval.clear();
settcom.clear();
setttab.clear();
settlines.clear();
setttype.clear();
all.clear();
flush();
parse();
}
void PIConfig::parse() {
string str, tab, comm;
int ind, sind;
if (!isOpened()) return;
seek(0);
lines = 0;
while (!isEnd()) {
str = readLine();
tab = s_left(str, str.find_first_of(s_left(s_trimmed(str), 1)));
str = s_trimmed(str);
all.push_back(str);
ind = str.find_first_of('=');
if ((ind > 0) && !(str[0] == '#')) {
sind = str.find_first_of('#');
if (sind > 0) {
comm = s_trimmed(s_right(str, str.size() - sind - 1));
setttype.push_back(s_left(comm, 1));
comm = s_trimmed(s_right(comm, comm.size() - 1));
settcom.push_back(comm);
str = s_left(str, sind);
} else {
setttype.push_back("s");
settcom.push_back("");
}
settname.push_back(s_trimmed(s_left(str, ind)));
settval.push_back(s_trimmed(s_right(str, str.size() - ind - 1)));
setttab.push_back(tab);
settlines.push_back(lines);
}
lines++;
}
}

72
piconfig.h Normal file
View File

@@ -0,0 +1,72 @@
#ifndef PICONFIG_H
#define PICONFIG_H
#include "pifile.h"
class PIConfig: public PIFile
{
public:
PIConfig(const string & path);
~PIConfig() {;}
string getValue(const string & vname, const string & def = "", bool * exist = 0) const;
string getValue(const string & vname, const char * def = "", bool * exist = 0) const;
bool getValue(const string & vname, const bool def = false, bool * exist = 0) const;
char getValue(const string & vname, const char def = 0, bool * exist = 0) const;
short getValue(const string & vname, const short def = 0, bool * exist = 0) const;
int getValue(const string & vname, const int def = 0, bool * exist = 0) const;
long getValue(const string & vname, const long def = 0, bool * exist = 0) const;
uchar getValue(const string & vname, const uchar def = 0, bool * exist = 0) const;
ushort getValue(const string & vname, const ushort def = 0, bool * exist = 0) const;
uint getValue(const string & vname, const uint def = 0, bool * exist = 0) const;
ulong getValue(const string & vname, const ulong def = 0, bool * exist = 0) const;
float getValue(const string & vname, const float def = 0., bool * exist = 0) const;
double getValue(const string & vname, const double def = 0., bool * exist = 0) const;
void setValue(const string & name, const string & value, const string & type = "s", bool write = true);
void setValue(const string & name, const char * value, bool write = true);
void setValue(const string & name, const bool value, bool write = true);
void setValue(const string & name, const char value, bool write = true);
void setValue(const string & name, const short value, bool write = true);
void setValue(const string & name, const int value, bool write = true);
void setValue(const string & name, const long value, bool write = true);
void setValue(const string & name, const uchar value, bool write = true);
void setValue(const string & name, const ushort value, bool write = true);
void setValue(const string & name, const uint value, bool write = true);
void setValue(const string & name, const ulong value, bool write = true);
void setValue(const string & name, const float value, bool write = true);
void setValue(const string & name, const double value, bool write = true);
string getValue(int number) const {return settval[number];}
string getName(int number) const {return settname[number];}
string getComment(int number) const {return settcom[number];}
void setValue(int number, const string & value, bool write = true);
bool existsValue(const string & name);
char getType(int number) const {return setttype[number][0];}
int getNumber(const string & name);
void setName(int number, const string & name);
void setType(int number, const string & type);
void setComment(int number, const string & comment);
int numValues() const {return settval.size();}
void addLine(const string & name, const string & value, const string & type = "s");
void insertLine(int number, const string & name, const string & value, const string & type = "s");
void deleteLine(const string & name);
void deleteLine(int number);
void readAll();
void writeAll();
private:
void parse();
vector<string> settname;
vector<string> settval;
vector<string> settcom;
vector<string> setttab;
vector<string> setttype;
vector<string> all;
vector<int> settlines;
int lines;
};
#endif // PICONFIG_H

412
piconsole.cpp Normal file
View File

@@ -0,0 +1,412 @@
#include "piconsole.h"
PIConsole::PIConsole(bool startNow, KeyFunc slot): PIThread() {
setPriority(piLow);
needLockRun(true);
ret_func = slot;
num_format = 0;
cur_tab = width = height = my = 0;
#ifdef WINDOWS
ulcoord.X = ulcoord.Y = 0;
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hOut, &sbi);
dattr = sbi.wAttributes;
width = sbi.srWindow.Right - sbi.srWindow.Left;
height = sbi.srWindow.Bottom - sbi.srWindow.Top;
GetConsoleMode(hOut, &smode);
GetConsoleCursorInfo(hOut, &curinfo);
#endif
addTab(string("main"));
listener = new PIKbdListener(key_event, this);
if (startNow) start(40);
}
PIConsole::~PIConsole() {
if (isRunning()) {
stop();
waitForFinish();
moveTo(0, my + 4);
showCursor();
}
delete listener;
clearTabs(false);
#ifdef WINDOWS
SetConsoleMode(hOut, smode);
SetConsoleTextAttribute(hOut, dattr);
#endif
}
int PIConsole::addTab(string name, char bind_key) {
tabs.push_back(Tab(name, bind_key));
cur_tab = tabs.size() - 1;
return tabs.size();
}
void PIConsole::removeTab(uint index) {
if (index >= tabs.size()) return;
tabs.erase(vector<Tab>::iterator(&tabs[index]));
if (cur_tab >= tabs.size()) cur_tab = tabs.size() - 1;
}
void PIConsole::removeTab(string name) {
uint index = tabs.size() + 1;
for (uint i = 0; i < tabs.size(); ++i) {
if (tabs[i].name == name) {
index = i;
break;
}
}
removeTab(index);
}
bool PIConsole::setTab(uint index) {
if (index >= tabs.size() || index < 0)
return false;
cur_tab = index;
if (!isRunning()) return true;
lock();
clearScreen();
fillLabels();
unlock();
return true;
}
bool PIConsole::setTab(string name) {
uint index = tabs.size() + 1;
for (uint i = 0; i < tabs.size(); ++i) {
if (tabs[i].name == name) {
index = i;
break;
}
}
return setTab(index);
}
bool PIConsole::setTabBindKey(uint index, char bind_key) {
if (index < 0 || index >= tabs.size())
return false;
tabs[index].key = bind_key;
return true;
}
bool PIConsole::setTabBindKey(string name, char bind_key) {
uint index =tabs.size() + 1;
for (uint i = 0; i < tabs.size(); ++i) {
if (tabs[i].name == name) {
index = i;
break;
}
}
return setTabBindKey(index, bind_key);
}
void PIConsole::key_event(void * t, char key) {
PIConsole * p = (PIConsole * )t;
for (uint i = 0; i < p->tabsCount(); ++i) {
if (p->tabs[i].key == key) {
p->setTab(i);
return;
}
}
if (p->ret_func != 0) p->ret_func(t, key);
}
string PIConsole::fstr(Flags<PIConsole::Format> f) {
if (f[PIConsole::Dec]) num_format = 0;
if (f[PIConsole::Hex]) num_format = 1;
if (f[PIConsole::Oct]) num_format = 2;
if (f[PIConsole::Scientific]) num_format = 3;
#ifdef WINDOWS
WORD attr = dattr;
if (f[PIConsole::Inverse]) {
if (f[PIConsole::Red]) attr |= BACKGROUND_RED;
if (f[PIConsole::Green]) attr |= BACKGROUND_GREEN;
if (f[PIConsole::Blue]) attr |= BACKGROUND_BLUE;
if (f[PIConsole::Yellow]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN);
if (f[PIConsole::Magenta]) attr |= (BACKGROUND_RED | BACKGROUND_BLUE);
if (f[PIConsole::Cyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE);
if (f[PIConsole::White]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
} else {
if (f[PIConsole::Red]) attr |= FOREGROUND_RED;
if (f[PIConsole::Green]) attr |= FOREGROUND_GREEN;
if (f[PIConsole::Blue]) attr |= FOREGROUND_BLUE;
if (f[PIConsole::Yellow]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN);
if (f[PIConsole::Magenta]) attr |= (FOREGROUND_RED | FOREGROUND_BLUE);
if (f[PIConsole::Cyan]) attr |= (FOREGROUND_GREEN | FOREGROUND_BLUE);
if (f[PIConsole::White]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
}
if (f[PIConsole::Bold]) attr |= FOREGROUND_INTENSITY;
SetConsoleTextAttribute(hOut, attr);
return "";
#else
string ts = "\e[0";
if (f[PIConsole::Bold]) ts += ";1";
if (f[PIConsole::Faint]) ts += ";2";
if (f[PIConsole::Italic]) ts += ";3";
if (f[PIConsole::Underline]) ts += ";4";
if (f[PIConsole::Blink]) ts += ";5";
if (f[PIConsole::Inverse]) ts += ";7";
if (f[PIConsole::Black]) ts += ";30";
if (f[PIConsole::Red]) ts += ";31";
if (f[PIConsole::Green]) ts += ";32";
if (f[PIConsole::Yellow]) ts += ";33";
if (f[PIConsole::Blue]) ts += ";34";
if (f[PIConsole::Magenta]) ts += ";35";
if (f[PIConsole::Cyan]) ts += ";36";
if (f[PIConsole::White]) ts += ";37";
return ts + "m";
#endif
}
#define siprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; default: return printf("%hd", x); break;}
#define iprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; default: return printf("%d", x); break;}
#define liprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; default: return printf("%ld", x); break;}
#define lliprint(x) switch (num_format) {case (1): return printf("0x%.16LX", x); break; case (2): return printf("%Lo", x); break; default: return printf("%Ld", x); break;}
#define suprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; default: return printf("%hd", x); break;}
#define uprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; default: return printf("%u", x); break;}
#define luprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; default: return printf("%lu", x); break;}
#define lluprint(x) switch (num_format) {case (1): return printf("0x%.16LX", x); break; case (2): return printf("%Lo", x); break; default: return printf("%Lu", 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;}
inline int PIConsole::couts(string v) {return printf("%s", v.c_str());}
inline int PIConsole::couts(char * v) {return printf("%s", v);}
inline int PIConsole::couts(bool v) {return (v ? printf("true") : printf("false"));}
inline int PIConsole::couts(char v) {return printf("%c", v);}
inline int PIConsole::couts(short v) {siprint(v);}
inline int PIConsole::couts(int v) {iprint(v);}
inline int PIConsole::couts(long v) {liprint(v);}
inline int PIConsole::couts(llong v) {lliprint(v);}
inline int PIConsole::couts(uchar v) {uprint(v);}
inline int PIConsole::couts(ushort v) {suprint(v);}
inline int PIConsole::couts(uint v) {uprint(v);}
inline int PIConsole::couts(ulong v) {luprint(v);}
inline int PIConsole::couts(ullong v) {lluprint(v);}
inline int PIConsole::couts(float v) {fprint(v);}
inline int PIConsole::couts(double v) {dprint(v);}
void PIConsole::begin() {
#ifdef WINDOWS
SetConsoleMode(hOut, ENABLE_WRAP_AT_EOL_OUTPUT);
#endif
clearScreen();
hideCursor();
fillLabels();
}
void PIConsole::run() {
uint cx, clen = 0;
#ifdef WINDOWS
GetConsoleScreenBufferInfo(hOut, &sbi);
width = sbi.srWindow.Right - sbi.srWindow.Left;
height = sbi.srWindow.Bottom - sbi.srWindow.Top;
#else
winsize ws;
ioctl(0, TIOCGWINSZ, &ws);
width = ws.ws_col;
height = ws.ws_row;
#endif
col_cnt = vars().size();
col_wid = (col_cnt > 0) ? width / col_cnt : width;
for (uint i = 0; i < col_cnt; ++i) {
cx = col_wid * i;
toUpperLeft();
for (uint j = 0; j < vars()[i].size(); ++j) {
if (my < j) my = j;
tv = vars()[i][j];
moveRight(cx);
if (tv.name.size() == 0) {
newLine();
continue;
}
if (tv.type == 0 && tv.s == 0) {
newLine();
continue;
}
moveRight(tv.offset);
switch (tv.type) {
case 0: clen = printValue(*tv.s, tv.format); break;
case 1: clen = printValue(*tv.b, tv.format); break;
case 2: clen = printValue(*tv.i, tv.format); break;
case 3: clen = printValue(*tv.l, tv.format); break;
case 4: clen = printValue(*tv.c, tv.format); break;
case 5: clen = printValue(*tv.f, tv.format); break;
case 6: clen = printValue(*tv.d, tv.format); break;
case 7: clen = printValue(*tv.sh, tv.format); break;
case 8: clen = printValue(*tv.ui, tv.format); break;
case 9: clen = printValue(*tv.ul, tv.format); break;
case 10: clen = printValue(*tv.ush, tv.format); break;
case 11: clen = printValue(*tv.uc, tv.format); break;
case 12: clen = printValue(*tv.ll, tv.format); break;
case 13: clen = printValue(*tv.ull, tv.format); break;
case 14: clen = printValue(bitsValue(tv.uc, tv.bitFrom, tv.bitCount), tv.format); break;
}
if (clen + tv.offset < (uint)col_wid)
printf("%s", string(col_wid - clen - tv.offset, ' ').c_str());
newLine();
}
}
fflush(0);
}
void PIConsole::fillLabels() {
uint cx, my = 0;
#ifdef WINDOWS
GetConsoleScreenBufferInfo(hOut, &sbi);
width = sbi.srWindow.Right - sbi.srWindow.Left;
height = sbi.srWindow.Bottom - sbi.srWindow.Top;
#else
winsize ws;
ioctl(0, TIOCGWINSZ, &ws);
width = ws.ws_col;
height = ws.ws_row;
#endif
col_cnt = vars().size();
col_wid = (col_cnt > 0) ? width / col_cnt : width;
for (uint i = 0; i < col_cnt; ++i) {
cx = col_wid * i;
toUpperLeft();
for (uint j = 0; j < vars()[i].size(); ++j) {
if (my < j) my = j;
moveRight(cx);
tv = vars()[i][j];
if (tv.name.size() == 0) {
newLine();
continue;
}
clearLine();
if (tv.type == 0 && tv.s == 0) {
printLine(tv.name, cx, tv.format);
newLine();
continue;
}
vars()[i][j].offset = printValue(tv.name + ": ", tv.format);
newLine();
}
}
moveTo(0, my + 2);
if (tabs[cur_tab].status.length() > 0) {
printValue(tabs[cur_tab].status);
newLine();
}
status();
//fflush(0);
}
void PIConsole::status() {
Tab * ctab;
//clearLine();
for (uint i = 0; i < tabsCount(); ++i) {
ctab = &tabs[i];
if (ctab->key == 0) continue;
printValue(ctab->key, PIConsole::Bold);
printValue(ctab->name + " ", PIConsole::Cyan | PIConsole::Inverse);
printValue(string(" "), PIConsole::Normal);
}
newLine();
}
int PIConsole::bitsValue(unsigned char * src, int offset, int count) {
int ret = 0, stbyte = offset / 8, cbit = offset - stbyte * 8;
char cbyte = src[stbyte];
for (int i = 0; i < count; i++) {
ret |= ((cbyte >> cbit & 1) << i);
cbit++;
if (cbit == 8) {
cbit = 0;
stbyte++;
cbyte = src[stbyte];
}
}
return ret;
}
#define ADD_VAR_BODY tv.name = name; tv.bitFrom = tv.bitCount = 0; tv.format = format; checkColumn(column);
void PIConsole::addString(string name, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 0; tv.s = 0; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, string* ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 0; tv.s = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, bool * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 1; tv.b = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, int * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 2; tv.i = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, long * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 3; tv.l = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, char * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 4; tv.c = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, float * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 5; tv.f = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, double * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 6; tv.d = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, short * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 7; tv.sh = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, uint * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 8; tv.ui = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, ulong * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 9; tv.ul = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, ushort * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 10; tv.ush = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, uchar * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 11; tv.uc = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, llong * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 12; tv.ll = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addVariable(string name, ullong * ptr, int column, Flags<PIConsole::Format> format) {
ADD_VAR_BODY tv.type = 13; tv.ull = ptr; vars()[column - 1].push_back(tv);}
void PIConsole::addBitVariable(string name, uchar * ptr, int fromBit, int bitCount, int column, Flags<PIConsole::Format> format) {
tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.uc = ptr; tv.format = format;
checkColumn(column); vars()[column - 1].push_back(tv);}
void PIConsole::addEmptyLine(int column) {
tv.name = ""; tv.type = 0; tv.d = 0; tv.format = Normal;
checkColumn(column); vars()[column - 1].push_back(tv);}
#define PRINT_VAR_BODY couts(fstr(format)); int ret = couts(value); fstr(PIConsole::Dec); return ret;
void PIConsole::printLine(string value, int dx, Flags<PIConsole::Format> format) {
int i = width - value.length() - dx;
#ifdef QNX
--i;
#endif
couts(fstr(format));
if (i >= 0) couts(value + string(i, ' '));
else couts(string(value, 0, value.length() + i));
couts(fstr(Dec));
}
int PIConsole::printValue(string value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(char * value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(bool value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(int value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(long value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(llong value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(float value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(double value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(char value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(short value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(uchar value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(ushort value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(uint value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(ulong value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
int PIConsole::printValue(ullong value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}

197
piconsole.h Normal file
View File

@@ -0,0 +1,197 @@
#ifndef PICONSOLE_H
#define PICONSOLE_H
#include "pikbdlistener.h"
#ifndef WINDOWS
#include <sys/ioctl.h>
#include <fcntl.h>
#endif
typedef void (*KeyFunc)(void * , char);
class PIConsole: public PIThread
{
public:
PIConsole(bool startNow = true, KeyFunc slot = 0);
~PIConsole();
enum Format {Normal = 0x01,
Bold = 0x02,
Faint = 0x04,
Italic = 0x08,
Underline = 0x10,
Blink = 0x20,
Inverse = 0x40,
Black = 0x100,
Red = 0x200,
Green = 0x400,
Yellow = 0x800,
Blue = 0x1000,
Magenta = 0x2000,
Cyan = 0x4000,
White = 0x8000,
Dec = 0x10000,
Hex = 0x20000,
Oct = 0x40000,
Scientific = 0x80000};
void addString(string name, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, string * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, char * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, bool * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, short * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, int * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, long * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, llong * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, uchar * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, ushort * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, uint * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, ulong * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, ullong * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, float * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addVariable(string name, double * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addBitVariable(string name, uchar * ptr, int fromBit, int bitCount, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
void addEmptyLine(int column = 1);
int addTab(string name, char bind_key = 0);
void removeTab(uint index);
void removeTab(string name);
uint tabsCount() const {return tabs.size();}
bool setTab(uint index);
bool setTab(string name);
bool setTabBindKey(uint index, char bind_key);
bool setTabBindKey(string name, char bind_key);
void addCustomStatus(string str) {tabs[cur_tab].status = str;}
void clearCustomStatus() {tabs[cur_tab].status = "";}
void clearVariables(bool clearScreen = true) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} vars().clear();}
void clearTabs(bool clearScreen = true) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} tabs.clear();}
string fstr(Flags<PIConsole::Format> f);
string currentTab() const {return tabs[cur_tab].name;}
private:
void begin();
void run();
void fillLabels();
#ifdef WINDOWS
inline void getWinCurCoord() {GetConsoleScreenBufferInfo(hOut, &csbi); ccoord = csbi.dwCursorPosition;}
inline COORD & getWinCoord(int dx = 0, int dy = 0) {getWinCurCoord(); ccoord.X += dx; ccoord.Y += dy; return ccoord;}
inline void toUpperLeft() {SetConsoleCursorPosition(hOut, ulcoord);}
inline void moveRight(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(n));}
inline void moveLeft(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(-n));}
inline void moveTo(int x = 0, int y = 0) {ccoord.X = x; ccoord.Y = y; SetConsoleCursorPosition(hOut, ccoord);}
inline void clearScreen() {FillConsoleOutputAttribute(hOut, dattr, width * (height + 1), ulcoord, &written);
FillConsoleOutputCharacter(hOut, ' ', width * (height + 1), ulcoord, &written);}
inline void clearScreenLower() {getWinCurCoord(); FillConsoleOutputAttribute(hOut, dattr, width * height - width * ccoord.Y + ccoord.X, ccoord, &written);
FillConsoleOutputCharacter(hOut, ' ', width * height - width * ccoord.Y + ccoord.X, ccoord, &written);}
inline void clearLine() {getWinCurCoord(); FillConsoleOutputAttribute(hOut, dattr, width - ccoord.X, ccoord, &written);
FillConsoleOutputCharacter(hOut, ' ', width - ccoord.X, ccoord, &written);}
inline void newLine() {getWinCurCoord(); ccoord.X = 0; ccoord.Y++; SetConsoleCursorPosition(hOut, ccoord);}
inline void hideCursor() {curinfo.bVisible = false; SetConsoleCursorInfo(hOut, &curinfo);}
inline void showCursor() {curinfo.bVisible = true; SetConsoleCursorInfo(hOut, &curinfo);}
#else
inline void toUpperLeft() {printf("\e[H");}
inline void moveRight(int n = 1) {if (n > 0) printf("\e[%dC", n);}
inline void moveLeft(int n = 1) {if (n > 0) printf("\e[%dD", n);}
inline void moveTo(int x = 0, int y = 0) {printf("\e[%d;%dH", y, x);}
inline void clearScreen() {printf("\e[H\e[J");}
inline void clearScreenLower() {printf("\e[J");}
inline void clearLine() {printf("\e[K");}
inline void newLine() {printf("\eE");}
inline void hideCursor() {printf("\e[?25l");}
inline void showCursor() {printf("\e[?25h");}
#endif
void status();
void checkColumn(uint col) {if (vars().size() < col) {vars().resize(col);}}
int bitsValue(unsigned char * src, int offset, int count);
void printLine(string str, int dx = 0, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(string str, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(char * str, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(bool value, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(int value, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(long value, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(llong value, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(float value, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(double value, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(char value, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(short value, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(uchar value, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(ushort value, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(uint value, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(ulong value, Flags<PIConsole::Format> format = PIConsole::Normal);
int printValue(ullong value, Flags<PIConsole::Format> format = PIConsole::Normal);
static void key_event(void * t, char key);
struct Variable {
string name;
Flags<PIConsole::Format> format;
int type;
int offset;
int bitFrom;
int bitCount;
union {
string * s;
bool * b;
short * sh;
int * i;
long * l;
llong * ll;
float * f;
double * d;
char * c;
uchar * uc;
ushort * ush;
uint * ui;
ulong * ul;
ullong * ull;
};
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;}
};
struct Tab {
vector<vector<Variable> > variables;
string name;
string status;
char key;
Tab() {;}
Tab(string n, char k) {name = n; key = k;}
};
inline vector<vector<Variable> > & vars() {return tabs[cur_tab].variables;}
inline int couts(string v);
inline int couts(char * v);
inline int couts(bool v);
inline int couts(char v);
inline int couts(short v);
inline int couts(int v);
inline int couts(long v);
inline int couts(llong v);
inline int couts(uchar v);
inline int couts(ushort v);
inline int couts(uint v);
inline int couts(ulong v);
inline int couts(ullong v);
inline int couts(float v);
inline int couts(double v);
#ifdef WINDOWS
void * hOut;
CONSOLE_SCREEN_BUFFER_INFO sbi, csbi;
CONSOLE_CURSOR_INFO curinfo;
COORD ccoord, ulcoord;
WORD dattr;
DWORD smode, written;
#else
struct termios sterm, vterm;
#endif
vector<Tab> tabs;
Variable tv;
PIKbdListener * listener;
KeyFunc ret_func;
int width, height, ret, col_wid, num_format;
uint my;
uint cur_tab, col_cnt;
};
#endif // PICONSOLE_H

128
piethernet.cpp Normal file
View File

@@ -0,0 +1,128 @@
#include "piethernet.h"
PIEthernet::PIEthernet(string ip, int port, void * data_, EthernetFunc slot): PIThread() {
setPriority(piHigh);
data = data_;
ip_ = ip_s = ip;
port_ = port_s = port;
sock = sock_s = -1;
ret_func = slot;
buffer = new char[BUFFER_SIZE];
#ifdef WINDOWS
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
sock = socket(PF_INET, SOCK_DGRAM, 0);
sock_s = socket(PF_INET, SOCK_DGRAM, 0);
if (sock == -1 || sock_s == -1)
cout << "[PIEthernet] Unable to create socket" << endl;
}
PIEthernet::~PIEthernet() {
if (isRunning()) {
stop();
pthread_cancel(thread);
}
if (sock != -1) {
shutdown(sock, SHUT_RDWR);
close(sock);
}
if (sock_s != -1) {
shutdown(sock_s, SHUT_RDWR);
close(sock_s);
}
#ifdef WINDOWS
WSACleanup();
#endif
delete buffer;
}
void PIEthernet::begin() {
if (!init()) stop();
}
void PIEthernet::run() {
#ifdef WINDOWS
int addr_len;
#else
socklen_t addr_len;
#endif
//cout << "[PIEthernet] reading ... ";
readed = recvfrom(sock, buffer, BUFFER_SIZE, 0, (sockaddr * )&addr_, &addr_len);
//cout << WSAGetLastError() << endl;
if (readed < 0) {
//cout << "[PIEthernet] Error while reading" << endl;
//stop();
//init();
return;
}
if (ret_func != 0) ret_func(data, buffer);
}
void PIEthernet::end() {
if (sock != -1) {
shutdown(sock, SHUT_RDWR);
close(sock);
sock = -1;
}
if (sock_s != -1) {
shutdown(sock_s, SHUT_RDWR);
close(sock_s);
sock_s = -1;
}
//cout << "[PIEthernet] end" << endl;
}
bool PIEthernet::init() {
addr_.sin_addr.s_addr = inet_addr(ip_.c_str());
addr_.sin_family = PF_INET;
addr_.sin_port = htons(port_);
if (bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) {
cout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << endl;
return false;
}
return true;
}
bool PIEthernet::send(string ip, int port, char * data, int size) {
if (sock_s == -1) {
//cout << "[PIEthernet] Can`t send to uninitialized socket" << endl;
return false;
}
saddr_.sin_port = htons(port);
saddr_.sin_addr.s_addr = inet_addr(ip.c_str());
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;
}
//cout << "[PIEthernet] Wrote " << wrote << " bytes in " << devName << endl;
return true;
}
bool PIEthernet::send(char * data, int size) {
if (sock_s == -1) {
//cout << "[PIEthernet] Can`t send to uninitialized socket" << endl;
return false;
}
saddr_.sin_port = htons(port_s);
saddr_.sin_addr.s_addr = inet_addr(ip_s.data());
saddr_.sin_family = PF_INET;
//cout << "[PIEthernet] sending in " << sock_s << endl;
wrote = sendto(sock_s, data, size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
if (wrote != size) {
//cout << "[PIEthernet] Error while sending" << endl;
return false;
}
//cout << "[PIEthernet] Wrote " << wrote << " bytes" << endl;
return true;
}

50
piethernet.h Normal file
View File

@@ -0,0 +1,50 @@
#ifndef PIETHERNET_H
#define PIETHERNET_H
#include "pithread.h"
#ifndef WINDOWS
# include <netinet/in.h>
# include <arpa/inet.h>
# include <sys/socket.h>
#else
# include <winsock2.h>
# define SHUT_RDWR SD_BOTH
#endif
#define BUFFER_SIZE 4096
typedef bool (*EthernetFunc)(void * , char * );
class PIEthernet: public PIThread
{
public:
// slot is any function format "bool <func>(void*, char*)"
PIEthernet(string ip, int port, void * data, EthernetFunc slot = 0);
~PIEthernet();
void setSlot(EthernetFunc func) {ret_func = func;}
void setReadAddress(string ip, int port) {ip_ = ip; port_ = port;}
void setSendAddress(string ip, int port) {ip_s = ip; port_s = port;}
bool send(string ip, int port, char * data, int size);
bool send(char * data, int size);
bool init();
bool initialized() const {return sock != -1;}
private:
void begin();
void run();
void end();
int sock, sock_s, port_, port_s, wrote;
sockaddr_in addr_, saddr_;
string ip_, ip_s;
EthernetFunc ret_func;
char * buffer;
void * data;
int readed;
};
#endif // PIETHERNET_H

57
pifile.cpp Normal file
View File

@@ -0,0 +1,57 @@
#include "pifile.h"
bool PIFile::open(const string & path_, Flags<Mode> mode_) {
cpath = path_;
cmode = mode_;
if (cmode[New]) {
stream.open(cpath.c_str(), fstream::in | fstream::out | fstream::trunc);
stream.close();
cmode &= ~New;
stream.open(cpath.c_str(), (fstream::openmode)(int)cmode | fstream::binary);
} else stream.open(cpath.c_str(), (fstream::openmode)(int)cmode | fstream::binary);
return isOpened();
}
string PIFile::readLine() {
char * buff = new char[4096];
stream.getline(buff, 4096);
return string(buff);
}
int PIFile::size() {
int s, cp = stream.tellg();
stream.seekg(0, fstream::end);
s = stream.tellg();
stream.seekg(cp);
return s;
}
void PIFile::seek(int position) {
if (cmode[Read]) stream.seekg(position);
if (cmode[Write]) stream.seekp(position);
}
void PIFile::resize(int new_size, char fill_) {
int ds = new_size - size();
if (ds == 0) return;
if (ds > 0) {
char * buff = new char[ds];
memset(buff, fill_, ds);
stream.write(buff, ds);
delete buff;
return;
}
cout << "[PIFile] Downsize is not support yet :-(" << endl;
}
int PIFile::pos() {
if (cmode[Read]) return stream.tellg();
if (cmode[Write]) return stream.tellp();
return -1;
}

77
pifile.h Normal file
View File

@@ -0,0 +1,77 @@
#ifndef PIFILE_H
#define PIFILE_H
#include <fstream>
#include "piincludes.h"
using std::fstream;
class PIFile
{
public:
PIFile() {;}
enum Mode {Read = fstream::in, Write = fstream::out, Truncate = fstream::trunc, New = fstream::app};
PIFile(const string & path, Flags<Mode> mode = Read | Write) {open(path, mode);}
~PIFile() {if (isOpened()) close();}
bool open(const string & path, Flags<Mode> mode = Read | Write);
void close() {stream.close();}
void clear() {close(); stream.open(cpath.c_str(), fstream::trunc | (fstream::openmode)(int)cmode);}
void seek(int position);
void resize(int new_size, char fill = 0);
void fill(char c) {stream.fill(c);}
void flush() {stream.flush();}
string readLine();
string path() const {return cpath;}
Flags<Mode> mode() const {return cmode;}
int size();
int pos();
bool isOpened() const {return stream.is_open();}
bool isEnd() const {return stream.eof();}
PIFile & writeData(const void * data, int size_) {stream.write((char * )data, size_); return *this;}
PIFile & readData(void * data, int size_) {stream.read((char * )data, size_); return *this;}
PIFile & writeBinary(const char v) {stream.write((char * )&v, sizeof(v)); return *this;}
PIFile & writeBinary(const short v) {stream.write((char * )&v, sizeof(v)); return *this;}
PIFile & writeBinary(const int v) {stream.write((char * )&v, sizeof(v)); return *this;}
PIFile & writeBinary(const long v) {stream.write((char * )&v, sizeof(v)); return *this;}
PIFile & writeBinary(const uchar v) {stream.write((char * )&v, sizeof(v)); return *this;}
PIFile & writeBinary(const ushort v) {stream.write((char * )&v, sizeof(v)); return *this;}
PIFile & writeBinary(const uint v) {stream.write((char * )&v, sizeof(v)); return *this;}
PIFile & writeBinary(const ulong v) {stream.write((char * )&v, sizeof(v)); return *this;}
PIFile & writeBinary(const float v) {stream.write((char * )&v, sizeof(v)); return *this;}
PIFile & writeBinary(const double v) {stream.write((char * )&v, sizeof(v)); return *this;}
PIFile & operator <<(const char & v) {stream.write(&v, 1); return *this;}
PIFile & operator <<(const string & v) {stream.write(v.c_str(), v.size()); return *this;}
PIFile & operator <<(const short & v) {stream << v; return *this;}
PIFile & operator <<(const int & v) {stream << v; return *this;}
PIFile & operator <<(const long & v) {stream << v; return *this;}
PIFile & operator <<(const uchar & v) {stream << v; return *this;}
PIFile & operator <<(const ushort & v) {stream << v; return *this;}
PIFile & operator <<(const uint & v) {stream << v; return *this;}
PIFile & operator <<(const ulong & v) {stream << v; return *this;}
PIFile & operator <<(const float & v) {stream << v; return *this;}
PIFile & operator <<(const double & v) {stream << v; return *this;}
PIFile & operator >>(char & v) {stream >> v; return *this;}
PIFile & operator >>(short & v) {stream >> v; return *this;}
PIFile & operator >>(int & v) {stream >> v; return *this;}
PIFile & operator >>(long & v) {stream >> v; return *this;}
PIFile & operator >>(uchar & v) {stream >> v; return *this;}
PIFile & operator >>(ushort & v) {stream >> v; return *this;}
PIFile & operator >>(uint & v) {stream >> v; return *this;}
PIFile & operator >>(ulong & v) {stream >> v; return *this;}
PIFile & operator >>(float & v) {stream >> v; return *this;}
PIFile & operator >>(double & v) {stream >> v; return *this;}
private:
fstream stream;
string cpath;
Flags<Mode> cmode;
};
#endif // PIFILE_H

112
piincludes.h Normal file
View File

@@ -0,0 +1,112 @@
#ifndef PIINCLUDES_H
#define PIINCLUDES_H
#if __WIN32__ || __WIN64__
# define WINDOWS
#endif
#if __QNX__
# define QNX
#endif
#include <iostream>
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <string.h>
#include <string>
#include <vector>
#include <list>
#include <deque>
#ifdef WINDOWS
#include <conio.h>
#include <windows.h>
#include <wincon.h>
#endif
#define FOREVER for (;;)
#define FOREVER_WAIT FOREVER msleep(10);
typedef long long llong;
typedef unsigned char uchar;
typedef unsigned short int ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned long long ullong;
using std::cout;
using std::cin;
using std::endl;
using std::flush;
using std::vector;
using std::list;
using std::deque;
using std::string;
template<typename Enum>
class Flags {
private:
int flags;
public:
inline Flags(): flags(0) {;}
inline Flags(Enum e): flags(e) {;}
inline Flags(const Flags & f): flags(f.flags) {;}
inline Flags(const int i): flags(i) {;}
inline void operator =(const Flags & f) {flags = f.flags;}
inline void operator |=(const Flags & f) {flags = flags | f.flags;}
inline void operator |=(const Enum & e) {flags = flags | e;}
inline void operator |=(const int i) {flags = flags | i;}
inline void operator &=(const Flags & f) {flags = flags & f.flags;}
inline void operator &=(const Enum & e) {flags = flags & e;}
inline void operator &=(const int i) {flags = flags & i;}
inline Flags & operator |(Flags f) const {Flags tf(flags | f.flags); return tf;}
inline Flags & operator |(Enum e) const {Flags tf(flags | e); return tf;}
inline Flags & operator |(int i) const {Flags tf(flags | i); return tf;}
inline Flags & operator &(Flags f) const {Flags tf(flags & f.flags); return tf;}
inline Flags & operator &(Enum e) const {Flags tf(flags & e); return tf;}
inline Flags & operator &(int i) const {Flags tf(flags & i); return tf;}
inline bool operator [](Enum e) {return (flags & e) == e;}
inline operator int() const {return flags;}
};
inline bool atob(const string & str) { return str == "1" ? true : false;};
inline string btos(const bool num) { return num ? "0" : "1";};
inline string itos(const int num) {
char ch[256];
sprintf(ch, "%d", num);
return string(ch); };
inline string ltos(const long num) {
char ch[256];
sprintf(ch, "%ld", num);
return string(ch); };
inline string uitos(const uint num) {
char ch[256];
sprintf(ch, "%ud", num);
return string(ch); };
inline string ultos(const ulong num) {
char ch[256];
sprintf(ch, "%lud", num);
return string(ch); };
inline string ftos(const float num) {
char ch[256];
sprintf(ch, "%g", num);
return string(ch); };
inline string dtos(const double num) {
char ch[256];
sprintf(ch, "%g", num);
return string(ch); };
inline string s_left(const string & str, int len) {return str.substr(0, len);};
inline string s_right(const string & str, int len) {return str.size() < len ? str : str.substr(str.size() - len, len);};
inline string s_trimmed(const string & str) {
int st = 0, fn = 0;
for (int i = 0; i < str.size(); ++i)
if (str[i] != ' ' && str[i] != '\t')
{st = i; break;}
for (int i = str.size() - 1; i >= 0; --i)
if (str[i] != ' ' && str[i] != '\t')
{fn = i; break;}
return str.substr(st, fn - st + 1);
};
#endif // PIINCLUDES_H

39
pikbdlistener.cpp Normal file
View File

@@ -0,0 +1,39 @@
#include "pikbdlistener.h"
PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() {
ret_func = slot;
data = data_;
#ifdef __WIN32__
hIn = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hIn, &smode);
SetConsoleMode(hIn, ENABLE_PROCESSED_INPUT);
#else
struct termios term;
tcgetattr(0, &term);
sterm = term;
term.c_lflag &= ~(ECHO | ICANON) | NOFLSH;
tcsetattr(0, TCSAFLUSH, &term);
#endif
start();
}
PIKbdListener::~PIKbdListener() {
#ifdef __WIN32__
SetConsoleMode(hIn, smode);
#else
tcsetattr(0, TCSANOW, &sterm);
#endif
}
void PIKbdListener::run() {
#ifdef __WIN32__
ReadConsole(hIn, &rc, 1, &ret, 0);
#else
ret = read(0, &rc, 1);
#endif
if (ret_func != 0 && ret > 0) ret_func(data, rc);
}

34
pikbdlistener.h Normal file
View File

@@ -0,0 +1,34 @@
#ifndef PIKBDLISTENER_H
#define PIKBDLISTENER_H
#include "pithread.h"
#ifndef __WIN32__
#include <termios.h>
#endif
typedef void (*KBFunc)(void * , char);
class PIKbdListener: public PIThread {
public:
// slot is any function format "void <func>(void * , char)"
PIKbdListener(KBFunc slot = 0, void * data = 0);
~PIKbdListener();
private:
void run();
KBFunc ret_func;
char rc;
void * data;
#ifdef __WIN32__
DWORD ret;
void * hIn;
DWORD smode;
#else
int ret;
struct termios sterm;
#endif
};
#endif // PIKBDLISTENER_H

37
pimutex.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef PIMUTEX_H
#define PIMUTEX_H
#include <pthread.h>
#include "piincludes.h"
class PIMutex
{
public:
PIMutex() {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&mutex, &attr);
pthread_mutexattr_destroy(&attr);
}
~PIMutex() {pthread_mutex_destroy(&mutex);}
void lock() {pthread_mutex_lock(&mutex);}
void unlock() {pthread_mutex_unlock(&mutex);}
bool tryLock() {return (pthread_mutex_trylock(&mutex) == 0);}
private:
pthread_mutex_t mutex;
};
class PIMutexLocker
{
public:
PIMutexLocker(PIMutex * m): mutex(m) {mutex->lock();}
PIMutexLocker(PIMutex & m): mutex(&m) {mutex->lock();}
~PIMutexLocker() {mutex->unlock();}
private:
PIMutex * mutex;
};
#endif // PIMUTEX_H

3
pip.kdev4 Normal file
View File

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

167
piprotocol.cpp Normal file
View File

@@ -0,0 +1,167 @@
#include "piprotocol.h"
PIProtocol::PIProtocol(string devName, int speed, void * headerPtr, int headerSize, void * dataPtr, int dataSize) {
init();
type = PIProtocol::Serial;
serial = new PISerial(devName, this, received);
serial->setReadData(headerPtr, headerSize, dataSize);
this->devName = devName;
this->headerPtr = (unsigned char * )headerPtr;
this->headerSize = headerSize;
this->dataPtr = (unsigned char * )dataPtr;
this->dataSize = dataSize;
packet = new char[headerSize + dataSize];
}
PIProtocol::PIProtocol(string ip, int port, void * dataPtr, int dataSize) {
init();
type = PIProtocol::Ethernet;
ether = new PIEthernet(ip, port, this, received);
this->devName = ip + ":" + itos(port);
this->dataPtr = (unsigned char * )dataPtr;
this->dataSize = dataSize;
packet = new char[dataSize];
}
PIProtocol::~PIProtocol() {
delete sendtimer;
if (timer != 0) delete timer;
if (type == PIProtocol::Serial) delete serial;
if (type == PIProtocol::Ethernet) delete ether;
}
void PIProtocol::init() {
work = false;
net_diag = PIProtocol::Unknown;
cur_pckt = 0;
timer = 0;
sendtimer = new PITimer(this, run);
wrong_count = receive_count = send_count = 0;
immediateFreq = integralFreq = 0.f;
headerPtr = dataPtr = sendDataPtr = 0;
headerSize = dataSize = sendDataSize = 0;
exp_freq = 20.f;
devState = "Unknown";
}
void PIProtocol::setExpectedFrequency(float frequency)
{
exp_freq = frequency;
if (exp_freq < 3.33) pckt_cnt_max = 10;
else pckt_cnt_max = 3 * (int)exp_freq;
last_packets.resize(pckt_cnt_max);
timer = new PITimer(this, diag_event);
timer->start(1000. / exp_freq);
timer->reset();
}
void PIProtocol::startReceive()
{
if (type == PIProtocol::Serial) serial->start();
if (type == PIProtocol::Ethernet) ether->start();
}
void PIProtocol::stopReceive()
{
if (type == PIProtocol::Serial) serial->stop();
if (type == PIProtocol::Ethernet) ether->stop();
}
bool PIProtocol::received(void * t, char * data) {
PIProtocol * p = (PIProtocol * )t;
memcpy(p->dataPtr, data, p->dataSize);
p->work = true;
//p->lock();
if (p->validate())
{
//p->unlock();
p->receive_count++;
p->cur_pckt = 1;
return true;
}
//p->unlock();
p->wrong_count++;
return false;
}
void PIProtocol::diag_event(void * t) {
PIProtocol * p = (PIProtocol * )t;
p->calc_freq();
p->calc_diag();
p->check_state();
}
void PIProtocol::calc_diag() {
PIProtocol::Quality diag;
if (!work) {
diag = PIProtocol::Unknown;
return;
}
if (pckt_cnt < pckt_cnt_max) {
last_packets[pckt_cnt] = cur_pckt;
pckt_cnt++;
} else {
packets[last_packets.back()]--;
last_packets.pop_back();
last_packets.push_front(cur_pckt);
}
packets[cur_pckt]++;
cur_pckt = 0;
float good_percents;
good_percents = (float)packets[1] / pckt_cnt * 100.0f;
if (good_percents == 0.0) diag = PIProtocol::Failure;
else if (good_percents <= 20.0) diag = PIProtocol::Bad;
else if (good_percents > 20.0 && good_percents <= 80.0) diag = PIProtocol::Average;
else diag = PIProtocol::Good;
if (diag != net_diag) net_diag = diag;
}
void PIProtocol::calc_freq() {
tf = 1000. / timer->elapsed_m();
timer->reset();
if (cur_pckt != 1) tf = 0.;
immediateFreq = tf;
if (last_freq.size() >= pckt_cnt_max) last_freq.pop_front();
last_freq.push_back(tf);
tf = last_freq[0];
for (int i = 1; i < last_freq.size(); ++i)
tf += last_freq[i];
integralFreq = tf / last_freq.size();
}
void PIProtocol::check_state() {
if (type == PIProtocol::Serial) {
if (serial->initialized()) devState = "Initialized";
else devState = "Uninitialized";
}
if (type == PIProtocol::Ethernet) {
if (ether->initialized()) devState = "Initialized";
else devState = "Uninitialized";
}
}
void PIProtocol::send() {
//lock();
memcpy(packet, sendDataPtr, sendDataSize);
//unlock();
if (type == PIProtocol::Serial)
if (serial->send(packet, sendDataSize))
send_count++;
if (type == PIProtocol::Ethernet)
if (ether->send(packet, sendDataSize))
send_count++;
}

78
piprotocol.h Normal file
View File

@@ -0,0 +1,78 @@
#ifndef PIPROTOCOL_H
#define PIPROTOCOL_H
#include "piserial.h"
#include "piethernet.h"
#include "pitimer.h"
class PIProtocol
{
enum Type {Serial, Ethernet};
public:
PIProtocol(string devName, int speed, void * headerPtr, int headerSize, void * dataPtr, int dataSize); // for RS
PIProtocol(string ip, int port, void * dataPtr, int dataSize); // for Ethernet
~PIProtocol();
enum Quality {Unknown = 1, Failure = 2, Bad = 3, Average = 4, Good = 5};
void startReceive(); // start receive
void stopReceive(); // stop receive
void startSend(float frequency = 20.f) {sendtimer->start(frequency > 0 ? 1000.f / frequency : 1000);} // start sending
void stopSend() {sendtimer->stop();} // stop sending
void setSendData(void * dataPtr, int dataSize) {sendDataPtr = (unsigned char * )dataPtr; sendDataSize = dataSize;}
void setReceiveData(void * dataPtr, int dataSize) {this->dataPtr = (unsigned char * )dataPtr; this->dataSize = dataSize;}
void setSendAddress(string ip, int port) {if (type == PIProtocol::Ethernet) ether->setReadAddress(ip, port);} // for Ethernet
void setParameters(Flags<PISerial::Parameters> parameters) {if (type == PIProtocol::Serial) serial->setParameters(parameters);} // for RS
void setExpectedFrequency(float frequency); // for start diagnostic connection quality
float * immediateFrequency_ptr() {return &immediateFreq;}
float * integralFrequency_ptr() {return &integralFreq;}
unsigned long long int * wrongCount_ptr() {return &wrong_count;}
unsigned long long int * receiveCount_ptr() {return &receive_count;}
unsigned long long int * sendCount_ptr() {return &send_count;}
PIProtocol::Quality * quality_ptr() {return &net_diag;}
string * deviceState_ptr() {return &devState;}
string deviceName() {return devName;}
protected:
virtual bool validate() {return true;} // function for validate algorithm and save data from dataPtr to external struct
virtual unsigned int checksum(unsigned char * data, int size) // function for checksum
{
unsigned char c = 0;
for (int i = 0; i < size; ++i)
c += data[i];
c = ~(c + 1);
return c;
}
virtual bool aboutSend() {return true;} // executed before send data, if return 'false' then data is not sending
void init();
void send();
void check_state();
void calc_freq();
void calc_diag();
static bool received(void * t, char * data);
static void diag_event(void * t);
PISerial * serial;
PIEthernet * ether;
unsigned int dataSize, headerSize, sendDataSize;
unsigned char * dataPtr, * headerPtr, * sendDataPtr;
private:
static void run(void * e) {PIProtocol* p = (PIProtocol*)e; if (p->aboutSend()) p->send();}
PITimer * timer, * sendtimer;
PIProtocol::Type type;
PIProtocol::Quality net_diag;
deque<float> last_freq;
deque<char> last_packets;
string devState, devName;
bool work;
float exp_freq, immediateFreq, integralFreq, tf;
int pckt_cnt, pckt_cnt_max, packets[2];
char * packet;
char cur_pckt;
unsigned long long int wrong_count, receive_count, send_count;
};
#endif // PIPROTOCOL_H

245
piserial.cpp Normal file
View File

@@ -0,0 +1,245 @@
#include "piserial.h"
PISerial::PISerial(string name, void * data_, SerialFunc slot): PIThread() {
setPriority(piHigh);
data = data_;
devName = name;
fd = -1;
dataSize = headerSize = 0;
headerPtr = 0;
ret_func = slot;
buffer = new char[BUFFER_SIZE];
sbuffer = new char[BUFFER_SIZE];
#ifdef WINDOWS
hCom = 0;
#endif
ispeed = ospeed = B115200;
}
PISerial::~PISerial() {
stop();
pthread_cancel(thread);
#ifdef WINDOWS
if (fd != -1) {
SetCommState(hCom, &sdesc);
SetCommMask(hCom, mask);
CloseHandle(hCom);
}
#else
if (fd != -1) {
tcsetattr(fd, TCSANOW, &sdesc);
close(fd);
}
#endif
delete buffer;
delete sbuffer;
}
void PISerial::begin() {
sbuffIndex = 0;
startIndex = 0;
backIndex = 0;
tryagain = first = false;
hbuffer = new char[headerSize];
pbuffer = new char[dataSize];
if (!init()) stop();
}
void PISerial::run() {
if (dataSize == 0) return;
char b;
int i = 0, j;
#ifdef WINDOWS
WaitCommEvent(hCom, 0, 0);
ReadFile(hCom, buffer, dataSize, &readed, 0);
#else
readed = read(fd, buffer, BUFFER_SIZE);
#endif
if (headerSize > 0)
{
while (i < readed)
{
//cout << sbuffIndex << ";" << startIndex << endl;
if (!tryagain)
{
b = buffer[i];
sbuffer[sbuffIndex] = b;
} else {
backIndex++;
if (backIndex == headerSize + dataSize) tryagain = false;
}
if (first)
{
if (sbuffIndex-startIndex == headerSize + dataSize - 1)
{
//cout << "vsdfgvb" << endl;
memcpy(pbuffer,&sbuffer[startIndex+headerSize],dataSize);
if (ret_func(data, pbuffer))
{
startIndex = 0;
sbuffIndex = -1;
} else {
//startIndex++;
memcpy(sbuffer, hbuffer, headerSize);
memcpy(&sbuffer[headerSize], pbuffer, dataSize);
backIndex = 0;
tryagain = true;
startIndex = 1;
sbuffIndex = -1;
}
first = false;
}
} else {
if (sbuffIndex - startIndex == headerSize - 1)
{
memcpy(hbuffer, &sbuffer[startIndex], headerSize);
for (j = 0; j < headerSize; ++j) {
if (hbuffer[j] != ((char*)headerPtr)[j]) {
startIndex++;
//cout << "no" << endl;
break;
}
}
if (j == headerSize) {
first = true;
//cout << "yes" << endl;
}
}
}
sbuffIndex++;
if (sbuffIndex >= BUFFER_SIZE)
{
if (first)
{
memcpy(pbuffer, &sbuffer[startIndex + headerSize], BUFFER_SIZE - startIndex - headerSize);
memcpy(sbuffer, hbuffer, headerSize);
memcpy(&sbuffer[headerSize], pbuffer, BUFFER_SIZE - startIndex - headerSize);
sbuffIndex = BUFFER_SIZE - startIndex - 1;
} else {
memcpy(sbuffer, hbuffer, headerSize);
sbuffIndex = headerSize - 1;
startIndex = 0;
}
}
if (!tryagain) i++;
}
} else {
for (uint i = 0; i < readed; ++i) {
b = buffer[i];
sbuffer[sbuffIndex] = b;
if (sbuffIndex == dataSize - 1) {
if (ret_func != 0) ret_func(data, sbuffer);
sbuffIndex = -1;
}
sbuffIndex++;
}
}
}
void PISerial::end() {
delete pbuffer;
delete hbuffer;
if (fd == -1) return;
#ifdef WINDOWS
SetCommState(hCom, &sdesc);
CloseHandle(hCom);
#else
tcsetattr(fd, TCSANOW, &sdesc);
close(fd);
#endif
fd = -1;
}
bool PISerial::init() {
#ifdef WINDOWS
hCom = CreateFile(devName.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
if(hCom == INVALID_HANDLE_VALUE) {
cout << "[PISerial] Unable to open " << devName << endl;
return false;
}
fd = 0;
COMMTIMEOUTS times;
times.ReadIntervalTimeout = 1;
times.ReadTotalTimeoutConstant = 1;
times.ReadTotalTimeoutMultiplier = 0;
times.WriteTotalTimeoutConstant = 0;
times.WriteTotalTimeoutMultiplier = 1;
if (SetCommTimeouts(hCom, &times) == -1) {
cout << "[PISerial] Unable to set timeouts for " << devName << endl;
CloseHandle(hCom);
fd = -1;
return false;
}
GetCommMask(hCom, &mask);
SetCommMask(hCom, EV_RXCHAR);
GetCommState(hCom, &sdesc);
desc = sdesc;
desc.DCBlength = sizeof(desc);
desc.BaudRate = ispeed;
desc.ByteSize = 8;
desc.fParity = params[PISerial::IgnoreParityControl] ? 0 : 1;
desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
if (SetCommState(hCom, &desc) == -1) {
cout << "[PISerial] Unable to set comm state for " << devName << endl;
CloseHandle(hCom);
fd = -1;
return false;
}
#else
fd = open(devName.data(), O_NOCTTY | O_RDWR);
if(fd == -1) {
cout << "[PISerial] Unable to open " << devName << endl;
return false;
}
fcntl(fd, F_SETFL, 0);
tcgetattr(fd, &desc);
sdesc = desc;
desc.c_iflag = desc.c_oflag = desc.c_lflag = 0;
desc.c_cflag = CLOCAL | CREAD | CSIZE;
if (params[PISerial::TwoStopBits]) desc.c_cflag &= CSTOPB;
if (params[PISerial::IgnoreParityControl]) desc.c_iflag &= IGNPAR ; // | INPCK | IGNBRK | IGNCR;
desc.c_cc[VMIN] = 0;
desc.c_cc[VTIME] = 1;
cfsetispeed(&desc, ispeed);
cfsetospeed(&desc, ospeed);
if(tcsetattr(fd, TCSANOW, &desc) < 0) {
cout << "[PISerial] Can`t set attributes for " << devName << endl;
close(fd);
return false;
}
tcflush(fd, TCIOFLUSH);
//cout << "[PISerial] Initialized " << devName << endl;
#endif
return true;
}
bool PISerial::send(char * data, int size) {
//cout << "[PISerial] send size: " << sizeof(data) << endl;
if (fd == -1) {
//cout << "[PISerial] Can`t write to uninitialized COM" << endl;
return false;
}
#ifdef WINDOWS
DWORD wrote;
WriteFile(hCom, data, size, &wrote, 0);
#else
int wrote;
wrote = write(fd, data, size);
#endif
if ((int)wrote != size) {
//cout << "[PISerial] Error while sending" << endl;
return false;
}
//cout << "[PISerial] Wrote " << wrote << " bytes in " << devName << endl;
return true;
}

75
piserial.h Normal file
View File

@@ -0,0 +1,75 @@
#ifndef PISERIAL_H
#define PISERIAL_H
#include "pithread.h"
#ifndef WINDOWS
#include <termios.h>
#include <fcntl.h>
#else
#define B110 110
#define B300 300
#define B600 600
#define B1200 1200
#define B2400 2400
#define B4800 4800
#define B9600 9600
#define B14400 14400
#define B19200 19200
#define B38400 38400
#define B57600 57600
#define B115200 115200
#define B128000 128000
#define B256000 256000
#endif
#define BUFFER_SIZE 4096
typedef bool (*SerialFunc)(void * , char * );
class PISerial: public PIThread
{
public:
// slot is any function format "bool <func>(void*, char*)"
PISerial(string name, void * data, SerialFunc slot = 0);
~PISerial();
enum Parameters {IgnoreParityControl = 0x01, TwoStopBits = 0x02};
void setSlot(SerialFunc func) {ret_func = func;}
void setSpeed(int speed) {ospeed = ispeed = speed;}
void setOutSpeed(int speed) {ospeed = speed;}
void setInSpeed(int speed) {ispeed = speed;}
void setParameters(Flags<PISerial::Parameters> parameters) {params = parameters;}
void setReadData(void * headerPtr, int headerSize, int dataSize) {this->headerPtr = headerPtr;
this->headerSize = headerSize;
this->dataSize = dataSize;}
bool send(char * data, int size);
bool init();
bool initialized() const {return fd != -1;}
private:
void begin();
void run();
void end();
#ifdef WINDOWS
DCB desc, sdesc;
void * hCom;
DWORD readed, mask;
#else
termios desc, sdesc;
int readed;
#endif
int fd, ospeed, ispeed;
string devName;
SerialFunc ret_func;
char * buffer, * sbuffer, * hbuffer, * pbuffer;
void * headerPtr, * data;
int dataSize, headerSize, sbuffIndex, startIndex, backIndex;
Flags<PISerial::Parameters> params;
bool first, tryagain;
};
#endif // PISERIAL_H

61
pithread.cpp Normal file
View File

@@ -0,0 +1,61 @@
#include "pithread.h"
PIThread::PIThread(bool startNow, int timer_delay) {
running = lockRun = false;
priority_ = piNormal;
timer = timer_delay;
if (startNow) start(timer_delay);
}
PIThread::~PIThread() {
if (!running) return;
pthread_cancel(thread);
}
bool PIThread::start(int timer_delay) {
pthread_attr_t attr;
terminating = false;
timer = timer_delay;
pthread_attr_init(&attr);
pthread_attr_setschedparam(&attr, &sparam);
if (pthread_create(&thread, &attr, thread_function, this) == 0) {
running = true;
return true;
}
return false;
}
void * PIThread::thread_function(void * t) {
PIThread * ct = (PIThread * )t;
ct->begin();
while (!ct->terminating) {
if (ct->lockRun) ct->mutex_.lock();
ct->run();
if (ct->lockRun) ct->mutex_.unlock();;
if (ct->timer > 0) msleep(ct->timer);
}
ct->end();
ct->running = false;
//cout << "thread " << t << " exiting ... " << endl;
pthread_exit(0);
return 0;
}
void PIThread::setPriority(PIThread::Priority prior) {
priority_ = prior;
#if __QNX__ || __WIN32__
sparam.sched_priority = (int)priority_;
#else
sparam.__sched_priority = (int)priority_;
#endif
if (!running) return;
pthread_getschedparam(thread, &policy, &sparam);
pthread_setschedparam(thread, policy, &sparam);
}

61
pithread.h Normal file
View File

@@ -0,0 +1,61 @@
#ifndef PITHREAD_H
#define PITHREAD_H
#include <pthread.h>
#include "piincludes.h"
#include "pimutex.h"
#ifdef WINDOWS
inline void msleep(int msecs) {Sleep(msecs);}
#else
inline void msleep(int msecs) {usleep(msecs * 1000);}
#endif
class PIThread {
public:
PIThread(bool startNow = false, int timer_delay = -1);
~PIThread();
#ifdef QNX
enum Priority {piHighest = 12,
piHigh = 11,
piNormal = 10,
piLow = 9,
piLowerst = 8 };
#else
enum Priority {piHighest = -2,
piHigh = -1,
piNormal = 0,
piLow = 1,
piLowerst = 2 };
#endif
bool start(int timer_delay = -1);
void stop() {terminating = true;}
void setPriority(PIThread::Priority prior);
PIThread::Priority priority() const {return priority_;}
bool isRunning() const {return running;}
void waitForFinish() {while (running) msleep(1);}
void needLockRun(bool need) {lockRun = need;}
void lock() {mutex_.lock();;}
void unlock() {mutex_.unlock();}
PIMutex & mutex() {return mutex_;}
private:
virtual void begin() {;} // executed at start
virtual void run() {;} // main loop
virtual void end() {;} // executed at finish
protected:
static void * thread_function(void * t);
volatile bool terminating, running, lockRun;
int timer, policy;
pthread_t thread;
PIMutex mutex_;
sched_param sparam;
PIThread::Priority priority_;
};
#endif // PITHREAD_H

128
pitimer.cpp Normal file
View File

@@ -0,0 +1,128 @@
#include "pitimer.h"
PITimer::PITimer(void * data_, TimerEvent slot) {
ret_func = slot;
data = data_;
#ifndef __WIN32__
ti = -1;
running = false;
se.sigev_notify = SIGEV_THREAD;
se.sigev_value.sival_ptr = this;
se.sigev_notify_function = timer_event;
se.sigev_notify_attributes = 0;
#endif
reset();
}
#ifndef __WIN32__
void PITimer::start(double msecs) {
spec.it_interval.tv_nsec = ((int)(msecs * 1000) % 1000000) * 1000;
spec.it_interval.tv_sec = (time_t)(msecs / 1000);
spec.it_value = spec.it_interval;
ti = timer_create(CLOCK_REALTIME, &se, &timer);
timer_settime(timer, 0, &spec, 0);
running = true;
}
void PITimer::timer_event(sigval e) {
PITimer * ct = (PITimer * )e.sival_ptr;
if (ct->ret_func != 0) ct->ret_func(ct->data);
}
#endif
double PITimer::elapsed_n() {
#ifdef __WIN32__
t_cur = GetCurrentTime();
return (t_cur * 1000000. - t_st * 1000000.);
#else
clock_gettime(0, &t_cur);
return (t_cur.tv_sec * 1.e+9 + t_cur.tv_nsec) -
(t_st.tv_sec * 1.e+9 + t_st.tv_nsec);
#endif
}
double PITimer::elapsed_u() {
#ifdef __WIN32__
t_cur = GetCurrentTime();
return (t_cur * 1000. - t_st * 1000.);
#else
clock_gettime(0, &t_cur);
return (t_cur.tv_sec * 1.e+6 + (t_cur.tv_nsec / 1.e+3)) -
(t_st.tv_sec * 1.e+6 + (t_st.tv_nsec / 1.e+3));
#endif
}
double PITimer::elapsed_m() {
#ifdef __WIN32__
t_cur = GetCurrentTime();
return (double)(t_cur - t_st);
#else
clock_gettime(0, &t_cur);
return (t_cur.tv_sec * 1.e+3 + (t_cur.tv_nsec / 1.e+6)) -
(t_st.tv_sec * 1.e+3 + (t_st.tv_nsec / 1.e+6));
#endif
}
double PITimer::elapsed_s() {
#ifdef __WIN32__
t_cur = GetCurrentTime();
return (t_cur / 1000. - t_st / 1000.);
#else
clock_gettime(0, &t_cur);
return (t_cur.tv_sec + (t_cur.tv_nsec / 1.e+9)) -
(t_st.tv_sec + (t_st.tv_nsec / 1.e+9));
#endif
}
PITime currentTime() {
time_t rt = time(0);
tm * pt = localtime(&rt);
PITime t;
t.seconds = pt->tm_sec;
t.minutes = pt->tm_min;
t.hours = pt->tm_hour;
return t;
}
PIDate currentDate() {
time_t rt = time(0);
tm * pt = localtime(&rt);
PIDate d;
d.day = pt->tm_mday;
d.month = pt->tm_mon + 1;
d.year = pt->tm_year + 1900;
return d;
}
string time2string(const PITime & time, const string & format) {
string ts = format;
int i = ts.find_first_of('h');
if (i >= 0) ts = ts.replace(i, 1, itos(time.hours));
i = ts.find_first_of('m');
if (i >= 0) ts = ts.replace(i, 1, itos(time.minutes));
i = ts.find_first_of('s');
if (i >= 0) ts = ts.replace(i, 1, itos(time.seconds));
return ts;
}
string date2string(const PIDate & date, const string & format) {
string ts = format;
int i = ts.find_first_of('y');
if (i >= 0) ts = ts.replace(i, 1, itos(date.year));
i = ts.find_first_of('m');
if (i >= 0) ts = ts.replace(i, 1, itos(date.month));
i = ts.find_first_of('d');
if (i >= 0) ts = ts.replace(i, 1, itos(date.day));
return ts;
}

69
pitimer.h Normal file
View File

@@ -0,0 +1,69 @@
#ifndef PITIMER_H
#define PITIMER_H
#include <ctime>
#include <csignal>
#include "pithread.h"
typedef void (*TimerEvent)(void * );
struct PITime {
int seconds;
int minutes;
int hours;
};
struct PIDate {
int day;
int month;
int year; // since 1900
};
class PITimer
#ifdef __WIN32__
: public PIThread
#endif
{
public:
PITimer(void * data = 0, TimerEvent slot = 0);
~PITimer() {stop();}
#ifdef __WIN32__
void reset() {t_st = GetCurrentTime();}
#else
void reset() {clock_gettime(0, &t_st);}
void start(double msecs);
void stop() {if (ti == 0) timer_delete(timer); ti = -1; running = false;}
bool isRunning() const {return running;}
#endif
double elapsed_n(); // nanoseconds
double elapsed_u(); // microseconds
double elapsed_m(); // miliseconds
double elapsed_s(); // seconds
private:
#ifdef __WIN32__
void run() {if (ret_func != 0) ret_func(data);}
long int t_st, t_cur;
#else
static void timer_event(sigval e);
bool running;
int ti;
itimerspec spec;
timespec t_st, t_cur;
timer_t timer;
sigevent se;
#endif
void * data;
TimerEvent ret_func;
};
PITime currentTime();
PIDate currentDate();
string time2string(const PITime & time, const string & format = "h:m:s");
string date2string(const PIDate & date, const string & format = "d.m.y");
#endif // PITIMER_H