30.11.2010 - initial commit
This commit is contained in:
32
.kdev4/pip.kdev4
Normal file
32
.kdev4/pip.kdev4
Normal 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
11
CMakeLists.txt
Normal 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
5
main.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
#include "pitimer.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
cout << date2string(currentDate()) << endl;
|
||||
};
|
||||
253
piconfig.cpp
Normal file
253
piconfig.cpp
Normal 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
72
piconfig.h
Normal 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
412
piconsole.cpp
Normal 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
197
piconsole.h
Normal 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
128
piethernet.cpp
Normal 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
50
piethernet.h
Normal 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
57
pifile.cpp
Normal 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
77
pifile.h
Normal 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
112
piincludes.h
Normal 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
39
pikbdlistener.cpp
Normal 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
34
pikbdlistener.h
Normal 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
37
pimutex.h
Normal 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
|
||||
167
piprotocol.cpp
Normal file
167
piprotocol.cpp
Normal 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
78
piprotocol.h
Normal 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
245
piserial.cpp
Normal 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, ×) == -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
75
piserial.h
Normal 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
61
pithread.cpp
Normal 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
61
pithread.h
Normal 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
128
pitimer.cpp
Normal 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
69
pitimer.h
Normal 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
|
||||
Reference in New Issue
Block a user