4.06.2013 - Version 0.3.4 - PIOBJECT() macro, ethernet improvement, documentation based on Doxygen
This commit is contained in:
@@ -1,23 +1,29 @@
|
|||||||
project(pip)
|
project(pip)
|
||||||
find_package(Qt4)
|
|
||||||
cmake_minimum_required(VERSION 2.6)
|
cmake_minimum_required(VERSION 2.6)
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${QT_INCLUDES} . ../peri4_widgets)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR} .)
|
||||||
|
set(VERSION "0.0304")
|
||||||
|
set(SOVERSION ${VERSION})
|
||||||
|
set(CMAKE_BUILD_TYPE "Release")
|
||||||
file(GLOB CPPS "pi*.cpp")
|
file(GLOB CPPS "pi*.cpp")
|
||||||
if (${WIN32})
|
if (${WIN32})
|
||||||
add_definitions(-Wall -O2)
|
include(GenerateExportHeader)
|
||||||
else (${WIN32})
|
execute_process(COMMAND "make_rc_win.bat")
|
||||||
add_definitions(-Wall -O2 -g3 --fast-math)
|
add_definitions("-O2")
|
||||||
endif (${WIN32})
|
#add_definitions(-DEF)
|
||||||
add_library(pip SHARED ${CPPS})
|
list(APPEND CPPS "pip_resource_win.o")
|
||||||
if (${WIN32})
|
add_library(pip SHARED ${CPPS})
|
||||||
target_link_libraries(pip pthread ws2_32 Iphlpapi)
|
generate_export_header(pip)
|
||||||
|
target_link_libraries(pip ws2_32 Iphlpapi)
|
||||||
else (${WIN32})
|
else (${WIN32})
|
||||||
|
if(DEFINED ENV{QNX_HOST})
|
||||||
|
add_definitions("-O2")
|
||||||
|
add_library(pip STATIC ${CPPS})
|
||||||
|
else()
|
||||||
|
add_definitions("-Wall -O2 -g3")
|
||||||
|
add_library(pip SHARED ${CPPS})
|
||||||
|
endif()
|
||||||
target_link_libraries(pip pthread rt)
|
target_link_libraries(pip pthread rt)
|
||||||
endif (${WIN32})
|
endif (${WIN32})
|
||||||
add_executable(pip_test "main.cpp")
|
add_executable(pip_test "main.cpp")
|
||||||
if (${WIN32})
|
target_link_libraries(pip_test pip)
|
||||||
target_link_libraries(pip_test pthread ws2_32 Iphlpapi pip)
|
|
||||||
else (${WIN32})
|
|
||||||
target_link_libraries(pip_test pip ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} pcollection)
|
|
||||||
endif (${WIN32})
|
|
||||||
add_subdirectory(system_test)
|
add_subdirectory(system_test)
|
||||||
|
|||||||
419
main.cpp
419
main.cpp
@@ -16,7 +16,7 @@
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
//#define PIP_DEBUG
|
||||||
#include "pip.h"
|
#include "pip.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ private:
|
|||||||
|
|
||||||
void signalFunc(PISignals::Signal signal) {
|
void signalFunc(PISignals::Signal signal) {
|
||||||
if (signal != PISignals::Interrupt) return;
|
if (signal != PISignals::Interrupt) return;
|
||||||
cout << "Ctrl+C pressed, exiting ..." << endl;
|
cout << endl << "Ctrl+C pressed, exiting ..." << endl;
|
||||||
exit(0);
|
exit(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,293 +71,252 @@ void timerEvent2(void * data, int delim) {
|
|||||||
|
|
||||||
|
|
||||||
class ObjectTest: public PIObject {
|
class ObjectTest: public PIObject {
|
||||||
|
PIOBJECT(ObjectTest)
|
||||||
public:
|
public:
|
||||||
ObjectTest(const PIString & name = PIString()): PIObject(name) {h = hi = ht = false;}
|
ObjectTest(const PIString & name = PIString()): PIObject(name) {h = hi = ht = false;}
|
||||||
EVENT_HANDLER(ObjectTest, void, handler) {h = true; cout << " handler in \"" << name() << "\"" << endl;}
|
EVENT_HANDLER(void, handler) {h = true; cout << " handler in \"" << name() << "\"" << endl;}
|
||||||
EVENT_HANDLER2(ObjectTest, void, handler_i_s, int, i, PIString, s) {hi = true; cout << " handler_i_s in \"" << name() << "\", i = " << i << ", s = \"" << s << "\"" << endl;}
|
EVENT_HANDLER2(void, handler_i_s, int, i, PIString, s) {hi = true; cout << " handler_i_s in \"" << name() << "\", i = " << i << ", s = \"" << s << "\"" << endl;}
|
||||||
EVENT_HANDLER2(ObjectTest, void, handler_timeout, void * , data, int, delim) {ht = true; cout << " handler_timeout in \"" << name() << "\", data = " << data << ", delim = " << delim << endl;}
|
EVENT_HANDLER2(void, handler_timeout, void * , data, int, delim) {ht = true; cout << " handler_timeout in \"" << name() << "\", data = " << data << ", delim = " << delim << endl;}
|
||||||
bool h, hi, ht;
|
bool h, hi, ht;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ObjectTest2: public PIObject {
|
class ObjectTest2: public PIObject {
|
||||||
|
PIOBJECT(ObjectTest2)
|
||||||
public:
|
public:
|
||||||
ObjectTest2(const PIString & name = PIString()): PIObject(name) {;}
|
ObjectTest2(const PIString & name = PIString()): PIObject(name) {;}
|
||||||
void raise0(const PIString & e) {cout << " event \"" << e << "\" from \"" << name() << "\"" << endl; raiseEvent(this, e);}
|
void raise0(const PIString & e) {cout << " event \"" << e << "\" from \"" << name() << "\"" << endl; raiseEvent(this, e);}
|
||||||
void raise2(const PIString & e, int i, const PIString & s) {cout << " event \"" << e << "\" from \"" << name() << "\"" << endl; raiseEvent<int, PIString>(this, e, i, s);}
|
void raise2(const PIString & e, int i, const PIString & s) {cout << " event \"" << e << "\" from \"" << name() << "\"" << endl; raiseEvent<int, PIString>(this, e, i, s);}
|
||||||
EVENT(ObjectTest2, event0)
|
EVENT(event0)
|
||||||
EVENT(ObjectTest2, event2)
|
EVENT(event2)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CA: public PIObject {
|
class CA: public PIObject {
|
||||||
|
PIOBJECT(CA)
|
||||||
public:
|
public:
|
||||||
CA(const PIString & n): PIObject(n) {;}
|
CA(const PIString & n): PIObject(n) {;}
|
||||||
EVENT_HANDLER(CA, void, handler_ca) {a = true; cout << " handler CA" << endl;}
|
EVENT_HANDLER(void, handler_ca) {a = true; cout << " handler CA" << endl;}
|
||||||
EVENT(CA, event_ca)
|
EVENT(event_ca)
|
||||||
bool a;
|
bool a;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CB: public CA {
|
class CB: public CA {
|
||||||
|
PIOBJECT(CB)
|
||||||
public:
|
public:
|
||||||
CB(const PIString & n): CA(n) {;}
|
CB(const PIString & n): CA(n) {;}
|
||||||
EVENT_HANDLER(CB, void, handler_cb) {b = true; cout << " handler CB" << endl;}
|
EVENT_HANDLER(void, handler_cb) {b = true; cout << " handler CB" << endl;}
|
||||||
bool b;
|
bool b;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CC: public CB {
|
class CC: public CB {
|
||||||
|
PIOBJECT(CC)
|
||||||
public:
|
public:
|
||||||
CC(const PIString & n): CB(n) {;}
|
CC(const PIString & n): CB(n) {;}
|
||||||
EVENT_HANDLER(CC, void, handler_cc) {c = true; cout << " handler CC" << endl;}
|
EVENT_HANDLER(void, handler_cc) {c = true; cout << " handler CC" << endl;}
|
||||||
bool c;
|
bool c;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CD: public CC {
|
class CD: public CC {
|
||||||
|
PIOBJECT(CD)
|
||||||
public:
|
public:
|
||||||
CD(const PIString & n): CC(n) {;}
|
CD(const PIString & n): CC(n) {;}
|
||||||
EVENT_HANDLER(CD, void, handler_cd) {d = true; cout << " handler CD" << endl;}
|
EVENT_HANDLER(void, handler_cd) {d = true; cout << " handler CD" << endl;}
|
||||||
bool d;
|
bool d;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PIDiagnostics diag;
|
||||||
|
bool corr = true;
|
||||||
|
void te(void * , int) {
|
||||||
|
diag.received(256, corr);
|
||||||
|
diag.sended(512);
|
||||||
|
}
|
||||||
|
|
||||||
struct Packet {
|
|
||||||
int from;
|
class ObjectA: public PIObject {
|
||||||
int to;
|
PIOBJECT(ObjectA)
|
||||||
float data;
|
public:
|
||||||
int cs;
|
EVENT_HANDLER1(void, handlerA, const PIString & , str) {piCout << "handler A:" << str;}
|
||||||
|
EVENT2(eventA2, int, i, float, f);
|
||||||
|
EVENT1(eventA1, const PIString & , str);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ObjectB: public PIObject {
|
||||||
|
PIOBJECT(ObjectB)
|
||||||
|
public:
|
||||||
|
EVENT_HANDLER2(void, handlerB, int, i, float, f) {piCout << "handler B:" << i << "," << f;}
|
||||||
|
EVENT1(eventB, PIString, str);
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
struct msgHeader {
|
||||||
|
msgHeader(ushort msg_id_ = 0) {
|
||||||
|
sign[0] = 'B';
|
||||||
|
sign[1] = 'R';
|
||||||
|
sign[2] = 'K';
|
||||||
|
sign[3] = 'D';
|
||||||
|
msg_id = msg_id_;
|
||||||
|
sys_id = 2;
|
||||||
|
subsys_id = 1;
|
||||||
|
fragment = security = cnt = 0;
|
||||||
|
size = sizeof(msgHeader);
|
||||||
|
}
|
||||||
|
char sign[4];
|
||||||
|
ushort size;
|
||||||
|
ushort cnt;
|
||||||
|
uchar fragment;
|
||||||
|
ushort msg_id;
|
||||||
|
uchar sys_id;
|
||||||
|
uchar subsys_id;
|
||||||
|
uchar security;
|
||||||
|
bool verify_sign() {return (sign[0] == 'B' && sign[1] == 'R' && sign[2] == 'K' && sign[3] == 'D');}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#pragma pack(push,1)
|
struct msg2105base {
|
||||||
|
msgHeader header;
|
||||||
|
union {
|
||||||
|
ullong msgTime;
|
||||||
|
struct {
|
||||||
|
uint time_ns;
|
||||||
|
uint time_s;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
uint id;
|
||||||
|
ushort type1kod;
|
||||||
|
float type1ver;
|
||||||
|
ushort type2kod;
|
||||||
|
float type2ver;
|
||||||
|
ushort type3kod;
|
||||||
|
float type3ver;
|
||||||
|
double azimut;
|
||||||
|
ullong imp_recv_time;
|
||||||
|
double geo_width_PEC;
|
||||||
|
double geo_length_PEC;
|
||||||
|
double geo_width_CP;
|
||||||
|
double geo_length_CP;
|
||||||
|
float height;
|
||||||
|
float kurs_CP;
|
||||||
|
float kren_CP;
|
||||||
|
float tangaj_CP;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct InpuData {
|
struct InpuData {
|
||||||
uint first_number; // Номер первого отсчета
|
InpuData() {header.msg_id = 2113;}
|
||||||
struct {
|
|
||||||
uchar packet_number: 7; // Идентификационный код пакета
|
|
||||||
uchar packet_last : 1; // Признак последнего пакета
|
|
||||||
};
|
|
||||||
struct {
|
|
||||||
uchar antenna_number : 3; // Номер антенного канала
|
|
||||||
uchar frequency_number: 3; // Номер частотного канала
|
|
||||||
uchar data_type : 2; // Вид передаваемой информации: 0 – оцифровка, 1 – измеренные параметры
|
|
||||||
};
|
|
||||||
uchar data[122]; // Данные
|
|
||||||
};
|
|
||||||
|
|
||||||
struct msgHeader {
|
|
||||||
char sign[4];
|
|
||||||
unsigned short size;
|
|
||||||
unsigned short cnt;
|
|
||||||
unsigned char fragment;
|
|
||||||
unsigned short msg_id;
|
|
||||||
unsigned char sys_id;
|
|
||||||
unsigned char subsys_id;
|
|
||||||
unsigned char security;
|
|
||||||
bool verify_sign()
|
|
||||||
{
|
|
||||||
bool ok;
|
|
||||||
ok = sign[0] == 'B';
|
|
||||||
ok = ok && sign[1] == 'R';
|
|
||||||
ok = ok && sign[2] == 'K';
|
|
||||||
ok = ok && sign[3] == 'D';
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct FilterCommand {
|
|
||||||
FilterCommand() {
|
|
||||||
memset(this, 0, sizeof(FilterCommand));
|
|
||||||
header.sign[0] = 'B'; header.sign[1] = 'R'; header.sign[2] = 'K'; header.sign[3] = 'D';
|
|
||||||
header.size = sizeof(FilterCommand);
|
|
||||||
header.cnt = header.fragment = header.security = 0;
|
|
||||||
header.msg_id = 2102;
|
|
||||||
header.sys_id = header.subsys_id = 2;
|
|
||||||
command = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHeader header;
|
msgHeader header;
|
||||||
uchar command; // 3
|
uint first_number;
|
||||||
struct {
|
struct {
|
||||||
uchar fi_number: 7; // номер частотного участка, 1 - 36
|
uchar packet_number: 7;
|
||||||
uchar bort : 1; // борт: 0 - левый, 1 - правый
|
uchar packet_last : 1;
|
||||||
};
|
};
|
||||||
ushort freq_start; // начальная частота, 0 - 6100
|
struct {
|
||||||
ushort freq_end; // конечная частота, 0 - 6100
|
uchar antenna_number : 3;
|
||||||
uchar filter_bandwith; // полоса проспускания фильтра
|
uchar frequency_number: 3;
|
||||||
ushort filter_time_step; // время шага фильтра по времени
|
uchar data_type : 2;
|
||||||
uchar reserve;
|
};
|
||||||
ushort record_time_start; // начальное время записи, 1 - 60 мс
|
uchar data[122];
|
||||||
ushort record_time_end; // конечное время записи, 1 - 60 мс
|
|
||||||
uchar record_channels; // номера каналов для записи, 0 - 5 биты
|
|
||||||
uchar play_channels; // номера каналов для воспроизведения, 0 - 5 биты
|
|
||||||
uchar signal_type; // тип сигнала для выдачи, 0 - С3, 1 - С4, 2 - С4Ф, 3 - выборка
|
|
||||||
ushort play_time_start; // начальное время воспроизведения, 1 - 60 мс
|
|
||||||
ushort play_time_end; // конечное время воспроизведения, 1 - 60 мс
|
|
||||||
uchar checksum;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
void te(void*, int);
|
class RC: public PIObject {
|
||||||
PITimer tm_(te);
|
PIOBJECT(RC)
|
||||||
PISerial ser("/dev/ttyS0");
|
public:
|
||||||
bool pins[9];
|
EVENT_HANDLER2(void, re, ullong, id, int, size) {piCout << "written id =" << id << "size =" << size;}
|
||||||
void te(void*, int) {
|
};
|
||||||
for (int i = 1; i <= 9; ++i)
|
|
||||||
pins[i - 1] = ser.isPin(i);
|
|
||||||
}
|
|
||||||
void ke(char key, void*) {
|
|
||||||
int p = key - '0';
|
|
||||||
if (key >= '1' && key <= '9')
|
|
||||||
ser.setPin(p, !pins[p - 1]);
|
|
||||||
}
|
|
||||||
int main(int argc, char * argv[]) {
|
|
||||||
PIKbdListener kbd;
|
|
||||||
kbd.enableExitCapture();
|
|
||||||
PICLI cli(argc, argv);
|
|
||||||
cli.addArgument("sender");
|
|
||||||
PIEthernet eth;
|
|
||||||
int i = 0;
|
|
||||||
bool _ok;
|
|
||||||
if (cli.hasArgument("sender")) {
|
|
||||||
while (!PIKbdListener::exiting) {
|
|
||||||
_ok = eth.send("234.0.2.1", 10101, &i, sizeof(i));
|
|
||||||
cout << "send " << i << " - " << (_ok ? "ok" : "fail") << endl;
|
|
||||||
i++;
|
|
||||||
msleep(100);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
eth.setParameter(PIEthernet::Broadcast);
|
|
||||||
eth.open(":10101");
|
|
||||||
eth.joinMulticastGroup("234.0.2.1");
|
|
||||||
while (!PIKbdListener::exiting) {
|
|
||||||
eth.read(&i, sizeof(i));
|
|
||||||
cout << "receive " << i << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*tm_.start(10.);
|
|
||||||
PIConsole con(false, ke);
|
|
||||||
con.enableExitCapture();
|
|
||||||
//ser.setParameter(PISerial::HardwareFlowControl);
|
|
||||||
ser.open();
|
|
||||||
con.addVariable("1 (CAR)", pins);
|
|
||||||
con.addVariable("2 (SR) ", pins + 1);
|
|
||||||
con.addVariable("3 (ST) ", pins + 2);
|
|
||||||
con.addVariable("4 (DTR)", pins + 3);
|
|
||||||
con.addVariable("5 (GND)", pins + 4);
|
|
||||||
con.addVariable("6 (DSR)", pins + 5);
|
|
||||||
con.addVariable("7 (RTS)", pins + 6);
|
|
||||||
con.addVariable("8 (CTS)", pins + 7);
|
|
||||||
con.addVariable("9 (RNG)", pins + 8);
|
|
||||||
con.start();
|
|
||||||
con.waitForFinish();
|
|
||||||
return 0;*/
|
|
||||||
|
|
||||||
/*FilterCommand fc;
|
|
||||||
PIEthernet eth(PIEthernet::TCP_SingleTCP);
|
|
||||||
eth.open("127.0.0.1:10201");
|
|
||||||
while (1) {
|
|
||||||
eth.read(&fc, sizeof(fc));
|
|
||||||
cout << int(fc.fi_number) << ", " << int(fc.bort) << ", " << int(fc.freq_start) << ", " << int(fc.freq_end) << ", " << int(fc.play_channels) << ", " << int(fc.record_channels) << endl;
|
|
||||||
}
|
|
||||||
return 0;*/
|
|
||||||
|
|
||||||
/*PIDir dir(argv[1]);
|
|
||||||
FILE*f = popen("cd ../ && pwd", "w");
|
int main(int argc, char ** argv) {
|
||||||
char fd[4096];
|
InpuData data;
|
||||||
int ret = fread(fd, 4096, 1, f);
|
|
||||||
pclose(f);
|
|
||||||
cout << PIString(fd, ret);
|
|
||||||
f = popen("cd ../ && pwd", "w");
|
|
||||||
ret = fread(fd, 4096, 1, f);
|
|
||||||
pclose(f);
|
|
||||||
cout << PIString(fd, ret);
|
|
||||||
return 0;
|
|
||||||
cout << dir.path() << endl;
|
|
||||||
dir.up();
|
|
||||||
cout << dir.path() << endl;
|
|
||||||
PIVector<PIDir::DirEntry> ent = dir.entries();
|
|
||||||
piForeachC (PIDir::DirEntry & i, ent)
|
|
||||||
cout << i.mode << " " << PIString::readableSize(i.size).expandRightTo(10, ' ') << " " << i.name << endl;*/
|
|
||||||
|
|
||||||
/*PISystemTime st_time, inc_time;
|
|
||||||
PITimer tm_;
|
|
||||||
tm_.reset();
|
|
||||||
inc_time = PISystemTime::fromMilliseconds(50);
|
|
||||||
st_time = currentSystemTime() + inc_time;
|
|
||||||
int cnt = 100;
|
|
||||||
while (cnt--) {
|
|
||||||
(st_time - currentSystemTime()).sleep();
|
|
||||||
{
|
|
||||||
msleep(49);
|
|
||||||
cout << "tick " << cnt << endl;
|
|
||||||
}
|
|
||||||
st_time += inc_time;
|
|
||||||
}
|
|
||||||
cout << tm_.elapsed_s() - 0.049 << endl;*/
|
|
||||||
|
|
||||||
/*PISystemTime t0, inc_time;
|
|
||||||
PITimer tm_;
|
|
||||||
tm_.reset();
|
|
||||||
inc_time = PISystemTime::fromMilliseconds(50);
|
|
||||||
inc_time.sleep();
|
|
||||||
int cnt = 100;
|
|
||||||
while (cnt--) {
|
|
||||||
t0 = currentSystemTime();
|
|
||||||
{
|
|
||||||
msleep(49);
|
|
||||||
cout << "tick " << cnt << endl;
|
|
||||||
}
|
|
||||||
(inc_time - (currentSystemTime() - t0)).sleep();
|
|
||||||
}
|
|
||||||
cout << tm_.elapsed_s() - 0.049 << endl;*/
|
|
||||||
|
|
||||||
//return 0;
|
|
||||||
|
|
||||||
/*InpuData data;
|
|
||||||
PIEthernet eth(PIEthernet::UDP);
|
PIEthernet eth(PIEthernet::UDP);
|
||||||
data.first_number = 0;
|
|
||||||
data.packet_number = 0;
|
|
||||||
data.packet_last = 0;
|
|
||||||
data.antenna_number = data.frequency_number = data.data_type = 0;
|
data.antenna_number = data.frequency_number = data.data_type = 0;
|
||||||
PIBitArray ba_;
|
float t = 0.f;
|
||||||
for (int i = 0; i < 97; ++i) {
|
int pc = 20, cnt = 0;
|
||||||
for (int b = 0; b < 10; ++b)
|
for (int p = 0; p < pc; ++p) {
|
||||||
ba_.push_back(((i >> b) & 1) == 1);
|
data.packet_number = p;
|
||||||
|
data.packet_last = (p == pc - 1 ? 1 : 0);
|
||||||
|
data.first_number = p * 97;
|
||||||
|
PIBitArray ba_;
|
||||||
|
int ci = 0;
|
||||||
|
for (int i = 0; i < 97; ++i) {
|
||||||
|
t += M_PI/4;
|
||||||
|
ci = sin(t) * 511 + 511;
|
||||||
|
if (cnt % 500 > 80) ci = 512;
|
||||||
|
cnt++;
|
||||||
|
for (int b = 0; b < 10; ++b)
|
||||||
|
ba_.push_back(((ci >> b) & 1) == 1);
|
||||||
|
}
|
||||||
|
//cout << ba_.byteSize() << ", " << ba_.bitSize() << endl;
|
||||||
|
memcpy(data.data, ba_.data(), 122);
|
||||||
|
eth.send("127.0.0.1:5000", &data, sizeof(data));
|
||||||
}
|
}
|
||||||
//cout << ba_.byteSize() << ", " << ba_.bitSize() << endl;
|
/*cout << ba_ << endl;
|
||||||
memcpy(data.data, ba_.data(), 122);
|
|
||||||
cout << ba_ << endl;
|
|
||||||
for (int i = 0; i < 122; ++i)
|
for (int i = 0; i < 122; ++i)
|
||||||
cout << int(data.data[i]) << ", ";
|
cout << int(data.data[i]) << ", ";
|
||||||
cout << endl;
|
cout << endl;*/
|
||||||
eth.send("127.0.0.1:5000", &data, sizeof(data));
|
return 0;
|
||||||
|
|
||||||
|
/*PIKbdListener kbd;
|
||||||
|
kbd.enableExitCapture();
|
||||||
|
PIEthernet * _eth;
|
||||||
|
PIByteArray ba_(16);
|
||||||
|
if (PIString(argv[argc - 1]) == "s") {
|
||||||
|
_eth = new PIEthernet(PIEthernet::TCP_Server);
|
||||||
|
piCout << "listen" << _eth->listen("127.0.0.1:1111");
|
||||||
|
int cc = 0;
|
||||||
|
while (!PIKbdListener::exiting) {
|
||||||
|
if (cc != _eth->clientsCount()) {
|
||||||
|
piCout << "new client";
|
||||||
|
_eth->clients().back()->startThreadedRead();
|
||||||
|
cc++;
|
||||||
|
}
|
||||||
|
msleep(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_eth = new PIEthernet(PIEthernet::TCP_Client);
|
||||||
|
piCout << "connection" << _eth->connect("127.0.0.1:1111");
|
||||||
|
_eth->send(PIString("0123456789101112").data(), 16);
|
||||||
|
while (!PIKbdListener::exiting) {
|
||||||
|
msleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete _eth;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
msg2105base msg;
|
||||||
|
msg.header.size = sizeof(msg);
|
||||||
|
msg.header.msg_id = 2105;
|
||||||
|
msg.msgTime = 1;
|
||||||
|
//PIKbdListener kbd;
|
||||||
|
//kbd.enableExitCapture();
|
||||||
|
RC rc_;
|
||||||
|
PIEthernet eth;
|
||||||
|
CONNECT2(void, ullong, int, ð, threadedWriteEvent, &rc_, re);
|
||||||
|
eth.setParameter(PIEthernet::Broadcast);
|
||||||
|
eth.open("127.0.0.1:10211");
|
||||||
|
eth.setSendAddress("234.0.2.1:10211");
|
||||||
|
eth.joinMulticastGroup("234.0.2.1");
|
||||||
|
eth.startThreadedWrite();
|
||||||
|
for (int i = 0; i < 100000; ++i) {
|
||||||
|
PISystemTime tm = currentSystemTime();
|
||||||
|
msg.type1kod = (i + 1) % 34;
|
||||||
|
msg.id = piRoundd(double(i) / 5. + 50);
|
||||||
|
if (i % 15 >= 10) msg.id += 10000;
|
||||||
|
msg.time_ns = tm.seconds;
|
||||||
|
msg.time_s = tm.nanoseconds;
|
||||||
|
msg.azimut = sin(float(i) / 20.) * 90;
|
||||||
|
msg.geo_width_PEC = sin(float(i) / 50.) * 90;
|
||||||
|
msg.geo_length_PEC = cos(float(i) / 50.) * 90;
|
||||||
|
piCout << "push to queue with id =" << eth.writeThreaded(&msg, sizeof(msg));
|
||||||
|
piMSleep(50);
|
||||||
|
if (PIKbdListener::exiting) break;
|
||||||
|
}
|
||||||
return 0;*/
|
return 0;*/
|
||||||
|
|
||||||
/*QApplication app(argc, argv);
|
PISignals::setSlot(signalFunc);
|
||||||
PIFFT fft;
|
//PISignals::grabSignals(PISignals::Interrupt);
|
||||||
PIVector<complexd> in;
|
|
||||||
in.resize(50*1000);
|
|
||||||
for (int i=400; i<404; i++) in[i] = complexd(1,0);
|
|
||||||
PITimer timer_;
|
|
||||||
fft.prepareFFT(in.size());
|
|
||||||
timer_.reset();
|
|
||||||
PIVector<complexd> * out = fft.calcFFT(in);
|
|
||||||
cout << timer_.elapsed_m() << endl;
|
|
||||||
Graphic * g = new Graphic();
|
|
||||||
QVector<QPointF> res;
|
|
||||||
fft.getAmplitude();
|
|
||||||
for (int i=0; i<out->size(); i++) res.append(QPointF(i,abs(out->at(i))));
|
|
||||||
g->setGraphicData(res);
|
|
||||||
g->addGraphic("arg", Qt::darkBlue);
|
|
||||||
res.clear();
|
|
||||||
for (int i=0; i< out->size(); i++) res.append(QPointF(i,arg(out->at(i))));
|
|
||||||
g->setGraphicData(res, 1);
|
|
||||||
g->show();
|
|
||||||
|
|
||||||
return app.exec();*/
|
|
||||||
|
|
||||||
bool r_string = true, r_thread = true, r_mutex = true, r_timer = true, r_file = true, r_eval = true, r_event = true;
|
bool r_string = true, r_thread = true, r_mutex = true, r_timer = true, r_file = true, r_eval = true, r_event = true;
|
||||||
bool succ = true;
|
bool succ = true;
|
||||||
cout << "== PIP test program ==" << endl;
|
cout << "== PIP test program ==" << endl;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "picontainers.h"
|
#include "picontainers.h"
|
||||||
|
|
||||||
class PIBitArray {
|
class PIP_EXPORT PIBitArray {
|
||||||
public:
|
public:
|
||||||
PIBitArray(const int & size = 0) {resize(size);}
|
PIBitArray(const int & size = 0) {resize(size);}
|
||||||
PIBitArray(uchar val) {resize(sizeof(val) * 8); data_[0] = val;}
|
PIBitArray(uchar val) {resize(sizeof(val) * 8); data_[0] = val;}
|
||||||
@@ -99,5 +99,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIBitArray & ba) {for (uint i = 0; i < ba.bitSize(); ++i) {s << ba[i]; if (i % 8 == 7) s << ' ';} return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIBitArray & ba) {for (uint i = 0; i < ba.bitSize(); ++i) {s << ba[i]; if (i % 8 == 7) s << ' ';} return s;}
|
||||||
|
inline PICout operator <<(PICout s, const PIBitArray & ba) {s.space(); s.setControl(0, true); for (uint i = 0; i < ba.bitSize(); ++i) {s << ba[i]; if (i % 8 == 7) s << ' ';} s.restoreControl(); return s;}
|
||||||
|
|
||||||
#endif // PIBITARRAY_H
|
#endif // PIBITARRAY_H
|
||||||
|
|||||||
@@ -90,12 +90,24 @@ private:
|
|||||||
PIVector<node> nodes;
|
PIVector<node> nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PIByteArray: public PIVector<uchar> {
|
class PIP_EXPORT PIByteArray: public PIVector<uchar> {
|
||||||
public:
|
public:
|
||||||
PIByteArray() {;}
|
PIByteArray() {;}
|
||||||
PIByteArray(const uint size) {resize(size);}
|
PIByteArray(const uint size) {resize(size);}
|
||||||
PIByteArray(const void * data, const uint size) {for (uint i = 0; i < size; ++i) push_back(((uchar * )data)[i]);}
|
PIByteArray(const void * data, const uint size) {for (uint i = 0; i < size; ++i) push_back(((uchar * )data)[i]);}
|
||||||
|
|
||||||
|
struct RawData {
|
||||||
|
friend PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v);
|
||||||
|
friend PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v);
|
||||||
|
public:
|
||||||
|
RawData(void * data, int size) {d = data; s = size;}
|
||||||
|
RawData(const void * data, const int size) {d = const_cast<void * >(data); s = size;}
|
||||||
|
RawData & operator =(const RawData & o) {d = o.d; s = o.s; return *this;}
|
||||||
|
private:
|
||||||
|
void * d;
|
||||||
|
int s;
|
||||||
|
};
|
||||||
|
|
||||||
PIByteArray resized(int new_size) {PIByteArray tv(*this); tv.resize(new_size); return tv;}
|
PIByteArray resized(int new_size) {PIByteArray tv(*this); tv.resize(new_size); return tv;}
|
||||||
|
|
||||||
PIByteArray & convertToBase64();
|
PIByteArray & convertToBase64();
|
||||||
@@ -146,42 +158,56 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba) {for (uint i = 0; i < ba.size(); ++i) s << ba[i]; return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba) {s << "{"; for (uint i = 0; i < ba.size(); ++i) {s << ba[i]; if (i < ba.size() - 1) s << ", ";} s << "}"; return s;}
|
||||||
|
inline PICout operator <<(PICout s, const PIByteArray & ba) {s.space(); s.setControl(0, true); s << "{"; for (uint i = 0; i < ba.size(); ++i) {s << ba[i]; if (i < ba.size() - 1) s << ", ";} s << "}"; s.restoreControl(); return s;}
|
||||||
|
|
||||||
|
#define PBA_OPERATOR_TO int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v));
|
||||||
|
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, uchar v) {s.push_back(v); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, uchar v) {s.push_back(v); return s;}
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const short & v) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const short v) {PBA_OPERATOR_TO return s;}
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const int & v) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const int v) {PBA_OPERATOR_TO return s;}
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const long & v) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const long & v) {PBA_OPERATOR_TO return s;}
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const llong & v) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const llong & v) {PBA_OPERATOR_TO return s;}
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const ushort & v) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const ushort v) {PBA_OPERATOR_TO return s;}
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const uint & v) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const uint v) {PBA_OPERATOR_TO return s;}
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const ulong & v) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const ulong & v) {PBA_OPERATOR_TO return s;}
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const ullong & v) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const ullong & v) {PBA_OPERATOR_TO return s;}
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const float & v) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const float v) {PBA_OPERATOR_TO return s;}
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const double & v) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const double & v) {PBA_OPERATOR_TO return s;}
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v) {int os = s.size_s(); s.enlarge(v.s); memcpy(s.data(os), v.d, v.s); return s;}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const PIList<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIList<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const PIDeque<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIDeque<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
||||||
|
template <typename T>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const T & v) {PBA_OPERATOR_TO return s;}
|
||||||
|
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {v = s.take_front(); return s;}
|
#undef PBA_OPERATOR_TO
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, short & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); return s;}
|
#define PBA_OPERATOR_FROM memcpy(&v, s.data(), sizeof(v)); s.remove(0, sizeof(v));
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, int & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); return s;}
|
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, long & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= 1u); v = s.take_front(); return s;}
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, llong & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, short & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, ushort & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, int & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, uint & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, long & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, ulong & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, llong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, ullong & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, ushort & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, float & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, uint & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, double & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, ulong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, ullong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, float & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, double & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) {assert(s.size_s() >= v.s); memcpy(v.d, s.data(), v.s); s.remove(0, v.s); return s;}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, PIVector<T> & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIVector<T> & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, PIList<T> & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIList<T> & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, PIDeque<T> & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIDeque<T> & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||||
|
template <typename T>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||||
|
|
||||||
|
#undef PBA_OPERATOR_FROM
|
||||||
|
|
||||||
#endif // PIBYTEARRAY_H
|
#endif // PIBYTEARRAY_H
|
||||||
|
|||||||
110
pichar.h
110
pichar.h
@@ -1,3 +1,6 @@
|
|||||||
|
/*! \file pichar.h
|
||||||
|
* \brief Unicode char
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Unicode char
|
Unicode char
|
||||||
@@ -21,24 +24,41 @@
|
|||||||
#define PICHAR_H
|
#define PICHAR_H
|
||||||
|
|
||||||
#include "pibytearray.h"
|
#include "pibytearray.h"
|
||||||
|
/*! \brief Unicode char
|
||||||
class PIChar
|
* \details This class is wrapper around \c "uint".
|
||||||
|
* There are many contructors and information functions;
|
||||||
|
*/
|
||||||
|
class PIP_EXPORT PIChar
|
||||||
{
|
{
|
||||||
friend class PIString;
|
friend class PIString;
|
||||||
friend PIByteArray & operator <<(PIByteArray & s, const PIChar & v);
|
friend PIByteArray & operator <<(PIByteArray & s, const PIChar & v);
|
||||||
friend PIByteArray & operator >>(PIByteArray & s, PIChar & v);
|
friend PIByteArray & operator >>(PIByteArray & s, PIChar & v);
|
||||||
public:
|
public:
|
||||||
|
//! Contructs ascii symbol
|
||||||
PIChar(const char c) {ch = c; ch &= 0xFF;}
|
PIChar(const char c) {ch = c; ch &= 0xFF;}
|
||||||
|
|
||||||
|
//! Contructs 2-bytes symbol
|
||||||
PIChar(const short c) {ch = c; ch &= 0xFFFF;}
|
PIChar(const short c) {ch = c; ch &= 0xFFFF;}
|
||||||
PIChar(const int c = 0) {ch = c;}
|
|
||||||
|
//! Contructs 4-bytes symbol
|
||||||
|
PIChar(const int c) {ch = c;}
|
||||||
|
|
||||||
|
//! Contructs ascii symbol
|
||||||
PIChar(const uchar c) {ch = c; ch &= 0xFF;}
|
PIChar(const uchar c) {ch = c; ch &= 0xFF;}
|
||||||
|
|
||||||
|
//! Contructs 2-bytes symbol
|
||||||
PIChar(const ushort c) {ch = c; ch &= 0xFFFF;}
|
PIChar(const ushort c) {ch = c; ch &= 0xFFFF;}
|
||||||
PIChar(const uint c) {ch = c;}
|
|
||||||
|
//! Default constructor. Contructs 4-bytes symbol
|
||||||
|
PIChar(const uint c = 0) {ch = c;}
|
||||||
|
|
||||||
|
//! Contructs symbol from no more than 4 bytes of string
|
||||||
PIChar(const char * c) {ch = *reinterpret_cast<const int * >(c);}
|
PIChar(const char * c) {ch = *reinterpret_cast<const int * >(c);}
|
||||||
|
|
||||||
//inline operator const int() {return static_cast<const int>(ch);}
|
//inline operator const int() {return static_cast<const int>(ch);}
|
||||||
//inline operator const char() {return toAscii();}
|
//inline operator const char() {return toAscii();}
|
||||||
|
|
||||||
|
//! Copy operator
|
||||||
PIChar & operator =(const char v) {ch = v; return *this;}
|
PIChar & operator =(const char v) {ch = v; return *this;}
|
||||||
/*inline PIChar & operator =(const short v) {ch = v; return *this;}
|
/*inline PIChar & operator =(const short v) {ch = v; return *this;}
|
||||||
inline PIChar & operator =(const int v) {ch = v; return *this;}
|
inline PIChar & operator =(const int v) {ch = v; return *this;}
|
||||||
@@ -46,6 +66,7 @@ public:
|
|||||||
inline PIChar & operator =(const ushort v) {ch = v; return *this;}
|
inline PIChar & operator =(const ushort v) {ch = v; return *this;}
|
||||||
inline PIChar & operator =(const uint v) {ch = v; return *this;}*/
|
inline PIChar & operator =(const uint v) {ch = v; return *this;}*/
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator ==(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) == 0;}
|
bool operator ==(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) == 0;}
|
||||||
/*inline bool operator ==(const PIChar & o) const {if (o.isAscii() ^ isAscii()) return false;
|
/*inline bool operator ==(const PIChar & o) const {if (o.isAscii() ^ isAscii()) return false;
|
||||||
if (isAscii()) return (o.toAscii() == toAscii());
|
if (isAscii()) return (o.toAscii() == toAscii());
|
||||||
@@ -57,6 +78,7 @@ public:
|
|||||||
inline bool operator ==(const ushort o) const {return (PIChar(o) == *this);}
|
inline bool operator ==(const ushort o) const {return (PIChar(o) == *this);}
|
||||||
inline bool operator ==(const uint o) const {return (PIChar(o) == *this);}*/
|
inline bool operator ==(const uint o) const {return (PIChar(o) == *this);}*/
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator !=(const PIChar & o) const {return !(o == *this);}
|
bool operator !=(const PIChar & o) const {return !(o == *this);}
|
||||||
/*inline bool operator !=(const char o) const {return (PIChar(o) != *this);}
|
/*inline bool operator !=(const char o) const {return (PIChar(o) != *this);}
|
||||||
inline bool operator !=(const short o) const {return (PIChar(o) != *this);}
|
inline bool operator !=(const short o) const {return (PIChar(o) != *this);}
|
||||||
@@ -65,62 +87,134 @@ public:
|
|||||||
inline bool operator !=(const ushort o) const {return (PIChar(o) != *this);}
|
inline bool operator !=(const ushort o) const {return (PIChar(o) != *this);}
|
||||||
inline bool operator !=(const uint o) const {return (PIChar(o) != *this);}*/
|
inline bool operator !=(const uint o) const {return (PIChar(o) != *this);}*/
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator >(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) < 0;}
|
bool operator >(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) < 0;}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator <(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) > 0;}
|
bool operator <(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) > 0;}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator >=(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) <= 0;}
|
bool operator >=(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) <= 0;}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator <=(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) >= 0;}
|
bool operator <=(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) >= 0;}
|
||||||
|
|
||||||
|
//! Return \b true if symbol is digit ('0' to '9')
|
||||||
bool isDigit() const {return isdigit(ch) != 0;}
|
bool isDigit() const {return isdigit(ch) != 0;}
|
||||||
|
|
||||||
|
//! Return \b true if symbol is HEX digit ('0' to '9', 'a' to 'f', 'A' to 'F')
|
||||||
bool isHex() const {return isxdigit(ch) != 0;}
|
bool isHex() const {return isxdigit(ch) != 0;}
|
||||||
|
|
||||||
|
//! Return \b true if symbol is drawable (without space)
|
||||||
bool isGraphical() const {return isgraph(ch) != 0;}
|
bool isGraphical() const {return isgraph(ch) != 0;}
|
||||||
|
|
||||||
|
//! Return \b true if symbol is control byte (< 32 or 127)
|
||||||
bool isControl() const {return iscntrl(ch) != 0;}
|
bool isControl() const {return iscntrl(ch) != 0;}
|
||||||
|
|
||||||
|
//! Return \b true if symbol is in lower case
|
||||||
bool isLower() const {return islower(ch) != 0;}
|
bool isLower() const {return islower(ch) != 0;}
|
||||||
|
|
||||||
|
//! Return \b true if symbol is in upper case
|
||||||
bool isUpper() const {return isupper(ch) != 0;}
|
bool isUpper() const {return isupper(ch) != 0;}
|
||||||
|
|
||||||
|
//! Return \b true if symbol is printable (with space)
|
||||||
bool isPrint() const {return isprint(ch) != 0;}
|
bool isPrint() const {return isprint(ch) != 0;}
|
||||||
|
|
||||||
|
//! Return \b true if symbol is space or tab
|
||||||
bool isSpace() const {return isspace(ch) != 0;}
|
bool isSpace() const {return isspace(ch) != 0;}
|
||||||
|
|
||||||
|
//! Return \b true if symbol is alphabetical letter
|
||||||
bool isAlpha() const {return isalpha(ch) != 0;}
|
bool isAlpha() const {return isalpha(ch) != 0;}
|
||||||
|
|
||||||
|
//! Return \b true if symbol is ascii (< 128)
|
||||||
bool isAscii() const {return isascii(ch) != 0;}
|
bool isAscii() const {return isascii(ch) != 0;}
|
||||||
|
|
||||||
int toInt() const {return static_cast<const int>(ch);}
|
int toInt() const {return int(ch);}
|
||||||
const wchar_t * toWCharPtr() const {return &ch;}
|
const wchar_t * toWCharPtr() const {return reinterpret_cast<const wchar_t * >(&ch);}
|
||||||
|
|
||||||
|
//! Return as <tt>"char * "</tt> string
|
||||||
const char * toCharPtr() const {return reinterpret_cast<const char * >(&ch);}
|
const char * toCharPtr() const {return reinterpret_cast<const char * >(&ch);}
|
||||||
wchar_t toWChar() const {return ch;}
|
|
||||||
|
wchar_t toWChar() const {return wchar_t(ch);}
|
||||||
char toAscii() const {return ch % 256;}
|
char toAscii() const {return ch % 256;}
|
||||||
int unicode16Code() const {wchar_t wc; if (mbtowc(&wc, toCharPtr(), 4) > 0) return wc; return 0;}
|
int unicode16Code() const {wchar_t wc; if (mbtowc(&wc, toCharPtr(), 4) > 0) return wc; return 0;}
|
||||||
//#ifdef WINDOWS
|
//#ifdef WINDOWS
|
||||||
// inline PIChar toUpper() const __attribute__ ((optimize(0))) {return PIChar(toupper(ch));}
|
// inline PIChar toUpper() const __attribute__ ((optimize(0))) {return PIChar(toupper(ch));}
|
||||||
// inline PIChar toLower() const __attribute__ ((optimize(0))) {return PIChar(tolower(ch));}
|
// inline PIChar toLower() const __attribute__ ((optimize(0))) {return PIChar(tolower(ch));}
|
||||||
//#else
|
//#else
|
||||||
|
|
||||||
|
//! Return symbol in upper case
|
||||||
PIChar toUpper() const {return PIChar(toupper(ch));}
|
PIChar toUpper() const {return PIChar(toupper(ch));}
|
||||||
|
|
||||||
|
//! Return symbol in lower case
|
||||||
PIChar toLower() const {return PIChar(tolower(ch));}
|
PIChar toLower() const {return PIChar(tolower(ch));}
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wchar_t ch;
|
uint ch;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//! Output operator to \c std::ostream
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIChar & v) {s << v.toCharPtr(); return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIChar & v) {s << v.toCharPtr(); return s;}
|
||||||
|
|
||||||
|
//! Output operator to \a PICout
|
||||||
|
inline PICout operator <<(PICout s, const PIChar & v) {s.space(); s.setControl(0, true); s << v.toCharPtr(); s.restoreControl(); return s;}
|
||||||
|
|
||||||
|
|
||||||
|
//! Write operator to \c PIByteArray
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {s << uint(v.ch); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {s << uint(v.ch); return s;}
|
||||||
|
|
||||||
|
//! Read operator from \c PIByteArray
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {uint i; s >> i; v.ch = wchar_t(i); return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {uint i; s >> i; v.ch = wchar_t(i); return s;}
|
||||||
|
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);}
|
inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator >(const char v, const PIChar & c) {return (PIChar(v) > c);}
|
inline bool operator >(const char v, const PIChar & c) {return (PIChar(v) > c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator <(const char v, const PIChar & c) {return (PIChar(v) < c);}
|
inline bool operator <(const char v, const PIChar & c) {return (PIChar(v) < c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator >=(const char v, const PIChar & c) {return (PIChar(v) >= c);}
|
inline bool operator >=(const char v, const PIChar & c) {return (PIChar(v) >= c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator <=(const char v, const PIChar & c) {return (PIChar(v) <= c);}
|
inline bool operator <=(const char v, const PIChar & c) {return (PIChar(v) <= c);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator ==(const char * v, const PIChar & c) {return (PIChar(v) == c);}
|
inline bool operator ==(const char * v, const PIChar & c) {return (PIChar(v) == c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator >(const char * v, const PIChar & c) {return (PIChar(v) > c);}
|
inline bool operator >(const char * v, const PIChar & c) {return (PIChar(v) > c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator <(const char * v, const PIChar & c) {return (PIChar(v) < c);}
|
inline bool operator <(const char * v, const PIChar & c) {return (PIChar(v) < c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator >=(const char * v, const PIChar & c) {return (PIChar(v) >= c);}
|
inline bool operator >=(const char * v, const PIChar & c) {return (PIChar(v) >= c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator <=(const char * v, const PIChar & c) {return (PIChar(v) <= c);}
|
inline bool operator <=(const char * v, const PIChar & c) {return (PIChar(v) <= c);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator ==(const int v, const PIChar & c) {return (PIChar(v) == c);}
|
inline bool operator ==(const int v, const PIChar & c) {return (PIChar(v) == c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator >(const int v, const PIChar & c) {return (PIChar(v) > c);}
|
inline bool operator >(const int v, const PIChar & c) {return (PIChar(v) > c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator <(const int v, const PIChar & c) {return (PIChar(v) < c);}
|
inline bool operator <(const int v, const PIChar & c) {return (PIChar(v) < c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator >=(const int v, const PIChar & c) {return (PIChar(v) >= c);}
|
inline bool operator >=(const int v, const PIChar & c) {return (PIChar(v) >= c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
inline bool operator <=(const int v, const PIChar & c) {return (PIChar(v) <= c);}
|
inline bool operator <=(const int v, const PIChar & c) {return (PIChar(v) <= c);}
|
||||||
|
|
||||||
#endif // PICHAR_H
|
#endif // PICHAR_H
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ void PICLI::parse() {
|
|||||||
_args_opt << cra;
|
_args_opt << cra;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
piCout << "[PICli] Arguments overflow, \"" << cra << "\" ignored" << endl;
|
piCout << "[PICli] Arguments overflow, \"" << cra << "\" ignored";
|
||||||
}
|
}
|
||||||
if (last == 0 ? false : last->has_value) {
|
if (last == 0 ? false : last->has_value) {
|
||||||
last->value = cra;
|
last->value = cra;
|
||||||
|
|||||||
2
picli.h
2
picli.h
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "pistring.h"
|
#include "pistring.h"
|
||||||
|
|
||||||
class PICLI
|
class PIP_EXPORT PICLI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PICLI(int argc, char * argv[]);
|
PICLI(int argc, char * argv[]);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "piprocess.h"
|
#include "piprocess.h"
|
||||||
|
|
||||||
class PICodec: private PIProcess
|
class PIP_EXPORT PICodec: private PIProcess
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PICodec(): PIProcess() {setGrabOutput(true); tf = PIFile::openTemporary(PIIODevice::ReadWrite); tf.open();}
|
PICodec(): PIProcess() {setGrabOutput(true); tf = PIFile::openTemporary(PIIODevice::ReadWrite); tf.open();}
|
||||||
|
|||||||
12
piconfig.cpp
12
piconfig.cpp
@@ -277,7 +277,7 @@ void PIConfig::addEntry(const PIString & name, const PIString & value, const PIS
|
|||||||
void PIConfig::setValue(const PIString & name, const PIString & value, const PIString & type, bool write) {
|
void PIConfig::setValue(const PIString & name, const PIString & value, const PIString & type, bool write) {
|
||||||
Entry & e(getValue(name));
|
Entry & e(getValue(name));
|
||||||
if (&e == &empty) {
|
if (&e == &empty) {
|
||||||
addEntry(name, value, type);
|
addEntry(name, value, type, write);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e._value = value;
|
e._value = value;
|
||||||
@@ -376,10 +376,14 @@ void PIConfig::removeEntry(Branch & b, PIConfig::Entry * e) {
|
|||||||
|
|
||||||
|
|
||||||
void PIConfig::writeAll() {
|
void PIConfig::writeAll() {
|
||||||
|
//cout << this << " write < " << size() << endl;
|
||||||
clear();
|
clear();
|
||||||
|
//*this << "1234567894132456798\n"; return;
|
||||||
//writeEntry(&root);
|
//writeEntry(&root);
|
||||||
buildFullNames(&root);
|
buildFullNames(&root);
|
||||||
Branch b = allLeaves();
|
Branch b = allLeaves();
|
||||||
|
//for (int i = 0; i < b.size_s(); ++i)
|
||||||
|
// cout << b[i]->_name << " = " << b[i]->_value << endl;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (int i = 0; i < other.size_s(); ++i) {
|
for (int i = 0; i < other.size_s(); ++i) {
|
||||||
//cout << j << endl;
|
//cout << j << endl;
|
||||||
@@ -387,25 +391,27 @@ void PIConfig::writeAll() {
|
|||||||
if (b[j]->_line == i) {
|
if (b[j]->_line == i) {
|
||||||
b[j]->buildLine();
|
b[j]->buildLine();
|
||||||
*this << b[j]->_all << '\n';
|
*this << b[j]->_all << '\n';
|
||||||
|
//cout << this << " " << b[j]->_all << endl;
|
||||||
++j;
|
++j;
|
||||||
} else {
|
} else {
|
||||||
*this << other[i];
|
*this << other[i];
|
||||||
if (i < other.size_s() - 1) *this << '\n';
|
if (i < other.size_s() - 1) *this << '\n';
|
||||||
|
//cout << this << " " << other[i] << endl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*this << other[i];
|
*this << other[i];
|
||||||
if (i < other.size_s() - 1) *this << '\n';
|
if (i < other.size_s() - 1) *this << '\n';
|
||||||
|
//cout << this << " " << other[i] << endl;
|
||||||
}
|
}
|
||||||
//cout << other[i] << endl;
|
|
||||||
}
|
}
|
||||||
flush();
|
flush();
|
||||||
readAll();
|
readAll();
|
||||||
|
//cout << this << " write > " << size() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIConfig::readAll() {
|
void PIConfig::readAll() {
|
||||||
root.clear();
|
root.clear();
|
||||||
flush();
|
|
||||||
parse();
|
parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,17 +49,17 @@
|
|||||||
Entry & getValue(const PIString & vname, const float def, bool * exist = 0) const {return getValue(vname, ftos(def), exist);} \
|
Entry & getValue(const PIString & vname, const float def, bool * exist = 0) const {return getValue(vname, ftos(def), exist);} \
|
||||||
Entry & getValue(const PIString & vname, const double def, bool * exist = 0) const {return getValue(vname, dtos(def), exist);}
|
Entry & getValue(const PIString & vname, const double def, bool * exist = 0) const {return getValue(vname, dtos(def), exist);}
|
||||||
|
|
||||||
class PIConfig: public PIFile
|
class PIP_EXPORT PIConfig: public PIFile
|
||||||
{
|
{
|
||||||
friend class Entry;
|
friend class Entry;
|
||||||
friend class Branch;
|
friend class Branch;
|
||||||
public:
|
public:
|
||||||
PIConfig(const PIString & path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
PIConfig(const PIString & path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||||
~PIConfig() {piForeach (Entry * i, root._children) deleteEntry(i); close();}
|
~PIConfig() {/*piForeach (Entry * i, root._children) deleteEntry(i); close();*/}
|
||||||
|
|
||||||
class Entry;
|
class Entry;
|
||||||
|
|
||||||
class Branch: public PIVector<Entry * > {
|
class PIP_EXPORT Branch: public PIVector<Entry * > {
|
||||||
friend class PIConfig;
|
friend class PIConfig;
|
||||||
friend class Entry;
|
friend class Entry;
|
||||||
friend std::ostream & operator <<(std::ostream & s, const Branch & v);
|
friend std::ostream & operator <<(std::ostream & s, const Branch & v);
|
||||||
@@ -90,7 +90,7 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Entry {
|
class PIP_EXPORT Entry {
|
||||||
friend class PIConfig;
|
friend class PIConfig;
|
||||||
friend class Branch;
|
friend class Branch;
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -20,12 +20,15 @@
|
|||||||
#include "piconsole.h"
|
#include "piconsole.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern PIMutex __PICout_mutex__;
|
||||||
|
|
||||||
|
|
||||||
PIConsole::PIConsole(bool startNow, KBFunc slot): PIThread() {
|
PIConsole::PIConsole(bool startNow, KBFunc slot): PIThread() {
|
||||||
setPriority(piLow);
|
setPriority(piLow);
|
||||||
needLockRun(true);
|
needLockRun(true);
|
||||||
ret_func = slot;
|
ret_func = slot;
|
||||||
num_format = 0;
|
num_format = 0;
|
||||||
cur_tab = width = height = pwidth = pheight = my = 0;
|
cur_tab = width = height = pwidth = pheight = max_y = 0;
|
||||||
def_align = Nothing;
|
def_align = Nothing;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
ulcoord.X = ulcoord.Y = 0;
|
ulcoord.X = ulcoord.Y = 0;
|
||||||
@@ -93,9 +96,11 @@ bool PIConsole::setTab(uint index) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
lock();
|
lock();
|
||||||
|
__PICout_mutex__.lock();
|
||||||
cur_tab = index;
|
cur_tab = index;
|
||||||
clearScreen();
|
clearScreen();
|
||||||
fillLabels();
|
fillLabels();
|
||||||
|
__PICout_mutex__.unlock();
|
||||||
unlock();
|
unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -135,6 +140,23 @@ bool PIConsole::setTabBindKey(const PIString & name, char bind_key) {
|
|||||||
|
|
||||||
void PIConsole::key_event(char key, void * t) {
|
void PIConsole::key_event(char key, void * t) {
|
||||||
PIConsole * p = (PIConsole * )t;
|
PIConsole * p = (PIConsole * )t;
|
||||||
|
int ct = p->cur_tab;
|
||||||
|
if (key == char(PIKbdListener::LeftArrow)) {
|
||||||
|
do {
|
||||||
|
ct--;
|
||||||
|
if (ct < 0) return;
|
||||||
|
} while (p->tabs[ct].key == 0);
|
||||||
|
p->setTab(ct);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (key == char(PIKbdListener::RightArrow)) {
|
||||||
|
do {
|
||||||
|
ct++;
|
||||||
|
if (ct >= p->tabs.size_s()) return;
|
||||||
|
} while (p->tabs[ct].key == 0);
|
||||||
|
p->setTab(ct);
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (uint i = 0; i < p->tabsCount(); ++i) {
|
for (uint i = 0; i < p->tabsCount(); ++i) {
|
||||||
if (p->tabs[i].key == key) {
|
if (p->tabs[i].key == key) {
|
||||||
p->setTab(i);
|
p->setTab(i);
|
||||||
@@ -148,7 +170,7 @@ void PIConsole::key_event(char key, void * t) {
|
|||||||
void PIConsole::stop(bool clear) {
|
void PIConsole::stop(bool clear) {
|
||||||
PIThread::stop(true);
|
PIThread::stop(true);
|
||||||
if (clear) clearScreen();
|
if (clear) clearScreen();
|
||||||
moveTo(0, my + 4);
|
moveTo(0, max_y + 4);
|
||||||
showCursor();
|
showCursor();
|
||||||
couts(fstr(Normal));
|
couts(fstr(Normal));
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
@@ -273,9 +295,12 @@ void PIConsole::begin() {
|
|||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
SetConsoleMode(hOut, ENABLE_WRAP_AT_EOL_OUTPUT);
|
SetConsoleMode(hOut, ENABLE_WRAP_AT_EOL_OUTPUT);
|
||||||
#endif
|
#endif
|
||||||
|
max_y = 0;
|
||||||
|
__PICout_mutex__.lock();
|
||||||
clearScreen();
|
clearScreen();
|
||||||
hideCursor();
|
hideCursor();
|
||||||
fillLabels();
|
fillLabels();
|
||||||
|
__PICout_mutex__.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -292,6 +317,7 @@ void PIConsole::run() {
|
|||||||
width = ws.ws_col;
|
width = ws.ws_col;
|
||||||
height = ws.ws_row;
|
height = ws.ws_row;
|
||||||
#endif
|
#endif
|
||||||
|
__PICout_mutex__.lock();
|
||||||
if (pwidth != width || pheight != height) {
|
if (pwidth != width || pheight != height) {
|
||||||
clearScreen();
|
clearScreen();
|
||||||
fillLabels();
|
fillLabels();
|
||||||
@@ -304,7 +330,7 @@ void PIConsole::run() {
|
|||||||
PIVector<Variable> & cvars(tabs[cur_tab].columns[i].variables);
|
PIVector<Variable> & cvars(tabs[cur_tab].columns[i].variables);
|
||||||
cx = col_wid * i;
|
cx = col_wid * i;
|
||||||
toUpperLeft();
|
toUpperLeft();
|
||||||
if (my < cvars.size()) my = cvars.size();
|
if (max_y < cvars.size()) max_y = cvars.size();
|
||||||
j = 0;
|
j = 0;
|
||||||
piForeachC (Variable & tv, cvars) {
|
piForeachC (Variable & tv, cvars) {
|
||||||
if (j > height - 3) continue;
|
if (j > height - 3) continue;
|
||||||
@@ -343,13 +369,19 @@ void PIConsole::run() {
|
|||||||
newLine();
|
newLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef WINDOWS
|
||||||
|
moveTo(0, max_y + 1);
|
||||||
|
#else
|
||||||
|
moveTo(0, max_y + 2);
|
||||||
|
#endif
|
||||||
fflush(0);
|
fflush(0);
|
||||||
|
__PICout_mutex__.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIConsole::fillLabels() {
|
void PIConsole::fillLabels() {
|
||||||
if (!isRunning()) return;
|
if (!isRunning()) return;
|
||||||
uint cx, cy, my = 0, mx = 0, dx;
|
uint cx, cy, mx = 0, dx;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
GetConsoleScreenBufferInfo(hOut, &sbi);
|
GetConsoleScreenBufferInfo(hOut, &sbi);
|
||||||
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
||||||
@@ -360,6 +392,7 @@ void PIConsole::fillLabels() {
|
|||||||
width = ws.ws_col;
|
width = ws.ws_col;
|
||||||
height = ws.ws_row;
|
height = ws.ws_row;
|
||||||
#endif
|
#endif
|
||||||
|
max_y = 0;
|
||||||
col_cnt = columns().size();
|
col_cnt = columns().size();
|
||||||
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
||||||
for (uint i = 0; i < col_cnt; ++i) {
|
for (uint i = 0; i < col_cnt; ++i) {
|
||||||
@@ -378,7 +411,7 @@ void PIConsole::fillLabels() {
|
|||||||
toUpperLeft();
|
toUpperLeft();
|
||||||
for (uint j = 0; j < cvars.size(); ++j) {
|
for (uint j = 0; j < cvars.size(); ++j) {
|
||||||
if (int(j) > height - 3) continue;
|
if (int(j) > height - 3) continue;
|
||||||
if (my < j) my = j;
|
if (max_y < j) max_y = j;
|
||||||
moveRight(cx);
|
moveRight(cx);
|
||||||
Variable & tv(cvars[j]);
|
Variable & tv(cvars[j]);
|
||||||
cvars[j].nx = cx;
|
cvars[j].nx = cx;
|
||||||
@@ -426,9 +459,9 @@ void PIConsole::fillLabels() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
moveTo(0, my + 1);
|
moveTo(0, max_y + 1);
|
||||||
#else
|
#else
|
||||||
moveTo(0, my + 2);
|
moveTo(0, max_y + 2);
|
||||||
#endif
|
#endif
|
||||||
if (!tabs[cur_tab].status.isEmpty()) {
|
if (!tabs[cur_tab].status.isEmpty()) {
|
||||||
printValue(tabs[cur_tab].status);
|
printValue(tabs[cur_tab].status);
|
||||||
@@ -446,7 +479,10 @@ void PIConsole::status() {
|
|||||||
ctab = &tabs[i];
|
ctab = &tabs[i];
|
||||||
if (ctab->key == 0) continue;
|
if (ctab->key == 0) continue;
|
||||||
printValue(ctab->key, PIConsole::White | PIConsole::Bold);
|
printValue(ctab->key, PIConsole::White | PIConsole::Bold);
|
||||||
printValue(ctab->name + " ", PIConsole::Cyan | PIConsole::Inverse);
|
if (i == cur_tab)
|
||||||
|
printValue(ctab->name + " ", PIConsole::BackYellow | PIConsole::Black);
|
||||||
|
else
|
||||||
|
printValue(ctab->name + " ", PIConsole::Cyan | PIConsole::Inverse);
|
||||||
printValue(" ");
|
printValue(" ");
|
||||||
}
|
}
|
||||||
newLine();
|
newLine();
|
||||||
@@ -522,10 +558,10 @@ void PIConsole::addVariable(const PIString & name, const PIProtocol * ptr, int c
|
|||||||
addString("protocol " + name, col, format | PIConsole::Bold);
|
addString("protocol " + name, col, format | PIConsole::Bold);
|
||||||
addVariable("Rec - " + ptr->receiverDeviceName(), ptr->receiverDeviceState_ptr(), col, format);
|
addVariable("Rec - " + ptr->receiverDeviceName(), ptr->receiverDeviceState_ptr(), col, format);
|
||||||
addVariable("Send - " + ptr->senderDeviceName(), ptr->senderDeviceState_ptr(), col, format);
|
addVariable("Send - " + ptr->senderDeviceName(), ptr->senderDeviceState_ptr(), col, format);
|
||||||
addVariable("Sended count", ptr->sendCount_ptr(), col, format);
|
|
||||||
addVariable("Received count", ptr->receiveCount_ptr(), col, format);
|
addVariable("Received count", ptr->receiveCount_ptr(), col, format);
|
||||||
addVariable("Invalid count", ptr->wrongCount_ptr(), col, format);
|
addVariable("Invalid count", ptr->wrongCount_ptr(), col, format);
|
||||||
addVariable("Missed count", ptr->missedCount_ptr(), col, format);
|
addVariable("Missed count", ptr->missedCount_ptr(), col, format);
|
||||||
|
addVariable("Sended count", ptr->sendCount_ptr(), col, format);
|
||||||
addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), col, format);
|
addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), col, format);
|
||||||
addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), col, format);
|
addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), col, format);
|
||||||
addVariable("Receive speed", ptr->receiveSpeed_ptr(), col, format);
|
addVariable("Receive speed", ptr->receiveSpeed_ptr(), col, format);
|
||||||
@@ -535,6 +571,17 @@ void PIConsole::addVariable(const PIString & name, const PIProtocol * ptr, int c
|
|||||||
addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), col, format);
|
addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), col, format);
|
||||||
addVariable("Quality", ptr->quality_ptr(), col, format);
|
addVariable("Quality", ptr->quality_ptr(), col, format);
|
||||||
}
|
}
|
||||||
|
void PIConsole::addVariable(const PIString & name, const PIDiagnostics * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||||
|
addString(name + " diagnostics", col, format | PIConsole::Bold);
|
||||||
|
addVariable("Received count", ptr->receiveCount_ptr(), col, format);
|
||||||
|
addVariable("Invalid count", ptr->wrongCount_ptr(), col, format);
|
||||||
|
addVariable("Sended count", ptr->sendCount_ptr(), col, format);
|
||||||
|
addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), col, format);
|
||||||
|
addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), col, format);
|
||||||
|
addVariable("Receive speed", ptr->receiveSpeed_ptr(), col, format);
|
||||||
|
addVariable("Send speed", ptr->sendSpeed_ptr(), col, format);
|
||||||
|
addVariable("Quality", ptr->quality_ptr(), col, format);
|
||||||
|
}
|
||||||
void PIConsole::addVariable(const PIString & name, const PISystemMonitor * ptr, int col, PIFlags<PIConsole::Format> format) {
|
void PIConsole::addVariable(const PIString & name, const PISystemMonitor * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||||
addString("monitor " + name, col, format | PIConsole::Bold);
|
addString("monitor " + name, col, format | PIConsole::Bold);
|
||||||
addVariable("state", &(ptr->statistic().state), col, format);
|
addVariable("state", &(ptr->statistic().state), col, format);
|
||||||
|
|||||||
21
piconsole.h
21
piconsole.h
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "pikbdlistener.h"
|
#include "pikbdlistener.h"
|
||||||
#include "piprotocol.h"
|
#include "piprotocol.h"
|
||||||
|
#include "pidiagnostics.h"
|
||||||
#include "pisystemmonitor.h"
|
#include "pisystemmonitor.h"
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
# include <sys/ioctl.h>
|
# include <sys/ioctl.h>
|
||||||
@@ -32,8 +33,9 @@
|
|||||||
/// void clearVariables(bool clearScreen = true)
|
/// void clearVariables(bool clearScreen = true)
|
||||||
/// void start(bool wait = false)
|
/// void start(bool wait = false)
|
||||||
/// void stop(bool clear = false)
|
/// void stop(bool clear = false)
|
||||||
class PIConsole: public PIThread
|
class PIP_EXPORT PIConsole: public PIThread
|
||||||
{
|
{
|
||||||
|
PIOBJECT(PIConsole)
|
||||||
public:
|
public:
|
||||||
PIConsole(bool startNow = true, KBFunc slot = 0);
|
PIConsole(bool startNow = true, KBFunc slot = 0);
|
||||||
~PIConsole();
|
~PIConsole();
|
||||||
@@ -84,6 +86,7 @@ public:
|
|||||||
void addVariable(const PIString & name, const float * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
void addVariable(const PIString & name, const float * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
void addVariable(const PIString & name, const double * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
void addVariable(const PIString & name, const double * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
void addVariable(const PIString & name, const PIProtocol * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
void addVariable(const PIString & name, const PIProtocol * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
|
void addVariable(const PIString & name, const PIDiagnostics * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
void addVariable(const PIString & name, const PISystemMonitor * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
void addVariable(const PIString & name, const PISystemMonitor * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
void addBitVariable(const PIString & name, const void * ptr, int fromBit, int bitCount, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
void addBitVariable(const PIString & name, const void * ptr, int fromBit, int bitCount, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
void addEmptyLine(int column = 1, uint count = 1);
|
void addEmptyLine(int column = 1, uint count = 1);
|
||||||
@@ -117,14 +120,14 @@ public:
|
|||||||
void setColumnAlignment(int col, Alignment align) {if (col < 0 || col >= columns().size_s()) return; column(col).alignment = align;}
|
void setColumnAlignment(int col, Alignment align) {if (col < 0 || col >= columns().size_s()) return; column(col).alignment = align;}
|
||||||
void setColumnAlignmentToAll(Alignment align) {piForeach (Tab & i, tabs) piForeach (Column & j, i.columns) j.alignment = align; fillLabels();}
|
void setColumnAlignmentToAll(Alignment align) {piForeach (Tab & i, tabs) piForeach (Column & j, i.columns) j.alignment = align; fillLabels();}
|
||||||
|
|
||||||
EVENT_HANDLER0(PIConsole, void, clearVariables) {clearVariables(true);}
|
EVENT_HANDLER0(void, clearVariables) {clearVariables(true);}
|
||||||
EVENT_HANDLER1(PIConsole, void, clearVariables, bool, clearScreen) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} columns().clear();}
|
EVENT_HANDLER1(void, clearVariables, bool, clearScreen) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} columns().clear();}
|
||||||
|
|
||||||
EVENT_HANDLER0(PIConsole, void, waitForFinish) {WAIT_FOR_EXIT}
|
EVENT_HANDLER0(void, waitForFinish) {WAIT_FOR_EXIT}
|
||||||
EVENT_HANDLER0(PIConsole, void, start) {start(false);}
|
EVENT_HANDLER0(void, start) {start(false);}
|
||||||
EVENT_HANDLER1(PIConsole, void, start, bool, wait) {PIThread::start(40); if (wait) waitForFinish();}
|
EVENT_HANDLER1(void, start, bool, wait) {PIThread::start(40); if (wait) waitForFinish();}
|
||||||
EVENT_HANDLER0(PIConsole, void, stop) {stop(false);}
|
EVENT_HANDLER0(void, stop) {stop(false);}
|
||||||
EVENT_HANDLER1(PIConsole, void, stop, bool, clear);
|
EVENT_HANDLER1(void, stop, bool, clear);
|
||||||
PIString fstr(PIFlags<PIConsole::Format> f);
|
PIString fstr(PIFlags<PIConsole::Format> f);
|
||||||
|
|
||||||
void enableExitCapture(char key = 'Q') {listener->enableExitCapture(key);}
|
void enableExitCapture(char key = 'Q') {listener->enableExitCapture(key);}
|
||||||
@@ -273,7 +276,7 @@ private:
|
|||||||
Alignment def_align;
|
Alignment def_align;
|
||||||
KBFunc ret_func;
|
KBFunc ret_func;
|
||||||
int width, height, pwidth, pheight, ret, col_wid, num_format;
|
int width, height, pwidth, pheight, ret, col_wid, num_format;
|
||||||
uint my;
|
uint max_y;
|
||||||
uint cur_tab, col_cnt;
|
uint cur_tab, col_cnt;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
330
picontainers.h
330
picontainers.h
@@ -1,6 +1,12 @@
|
|||||||
|
/*! \file picontainers.h
|
||||||
|
* \brief Generic containers based on STL
|
||||||
|
*
|
||||||
|
* This file declare all containers and useful macroses
|
||||||
|
* to use them
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Generic containers, based on STL
|
Generic containers based on STL
|
||||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -22,6 +28,37 @@
|
|||||||
|
|
||||||
#include "piincludes.h"
|
#include "piincludes.h"
|
||||||
|
|
||||||
|
#ifdef DOXYGEN
|
||||||
|
/*! \def piForeach(i,c)
|
||||||
|
* \brief Macro for iterate any container
|
||||||
|
* \details Use this macros instead of standard "for"
|
||||||
|
* to get read/write access to each element of container.
|
||||||
|
* Pass direction is direct \n
|
||||||
|
* Example: \snippet picontainers.cpp foreach
|
||||||
|
*/
|
||||||
|
/*! \def piForeachC(i,c)
|
||||||
|
* \brief Macro for iterate any container only for read
|
||||||
|
* \details Use this macros instead of standard "for"
|
||||||
|
* to get read access to each element of container.
|
||||||
|
* Pass direction is direct \n
|
||||||
|
* Example: \snippet picontainers.cpp foreachC
|
||||||
|
*/
|
||||||
|
/*! \def piForeachR(i,c)
|
||||||
|
* \brief Macro for iterate any container with reverse direction
|
||||||
|
* \details Use this macros instead of standard "for"
|
||||||
|
* to get read/write access to each element of container.
|
||||||
|
* Pass direction is reverse \n
|
||||||
|
* Example: \snippet picontainers.cpp foreachR
|
||||||
|
*/
|
||||||
|
/*! \def piForeachCR(i,c)
|
||||||
|
* \brief Macro for iterate any container only for read with reverse direction
|
||||||
|
* \details Use this macros instead of standard "for"
|
||||||
|
* to get read access to each element of container.
|
||||||
|
* Pass direction is reverse \n
|
||||||
|
* Example: \snippet picontainers.cpp foreachCR
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CC_GCC
|
#ifdef CC_GCC
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
@@ -126,42 +163,6 @@ template <typename T> inline _PIForeachC<T> * _PIForeachCastC(_PIForeachBase & c
|
|||||||
|
|
||||||
#define piForTimes(c) for(int _i##c = 0; _i##c < c; ++_i##c)
|
#define piForTimes(c) for(int _i##c = 0; _i##c < c; ++_i##c)
|
||||||
|
|
||||||
template<typename Enum>
|
|
||||||
class PIFlags {
|
|
||||||
public:
|
|
||||||
PIFlags(): flags(0) {;}
|
|
||||||
PIFlags(Enum e): flags(e) {;}
|
|
||||||
PIFlags(const PIFlags & f): flags(f.flags) {;}
|
|
||||||
PIFlags(const int i): flags(i) {;}
|
|
||||||
PIFlags & setFlag(const PIFlags & f, bool on = true) {if (on) flags |= f.flags; else flags &= ~f.flags; return *this;}
|
|
||||||
PIFlags & setFlag(const Enum & e, bool on = true) {if (on) flags |= e; else flags &= ~e; return *this;}
|
|
||||||
PIFlags & setFlag(const int & i, bool on = true) {if (on) flags |= i; else flags &= ~i; return *this;}
|
|
||||||
void operator =(const PIFlags & f) {flags = f.flags;}
|
|
||||||
void operator =(const Enum & e) {flags = e;}
|
|
||||||
void operator =(const int & i) {flags = i;}
|
|
||||||
void operator |=(const PIFlags & f) {flags |= f.flags;}
|
|
||||||
void operator |=(const Enum & e) {flags |= e;}
|
|
||||||
void operator |=(const int i) {flags |= i;}
|
|
||||||
void operator &=(const PIFlags & f) {flags &= f.flags;}
|
|
||||||
void operator &=(const Enum & e) {flags &= e;}
|
|
||||||
void operator &=(const int i) {flags &= i;}
|
|
||||||
void operator ^=(const PIFlags & f) {flags ^= f.flags;}
|
|
||||||
void operator ^=(const Enum & e) {flags ^= e;}
|
|
||||||
void operator ^=(const int i) {flags ^= i;}
|
|
||||||
PIFlags operator |(PIFlags f) const {PIFlags tf(flags | f.flags); return tf;}
|
|
||||||
PIFlags operator |(Enum e) const {PIFlags tf(flags | e); return tf;}
|
|
||||||
PIFlags operator |(int i) const {PIFlags tf(flags | i); return tf;}
|
|
||||||
PIFlags operator &(PIFlags f) const {PIFlags tf(flags & f.flags); return tf;}
|
|
||||||
PIFlags operator &(Enum e) const {PIFlags tf(flags & e); return tf;}
|
|
||||||
PIFlags operator &(int i) const {PIFlags tf(flags & i); return tf;}
|
|
||||||
PIFlags operator ^(PIFlags f) const {PIFlags tf(flags ^ f.flags); return tf;}
|
|
||||||
PIFlags operator ^(Enum e) const {PIFlags tf(flags ^ e); return tf;}
|
|
||||||
PIFlags operator ^(int i) const {PIFlags tf(flags ^ i); return tf;}
|
|
||||||
bool operator [](Enum e) const {return (flags & e) == e;}
|
|
||||||
operator int() const {return flags;}
|
|
||||||
private:
|
|
||||||
int flags;
|
|
||||||
};
|
|
||||||
/*
|
/*
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class PIVector {
|
class PIVector {
|
||||||
@@ -269,7 +270,7 @@ public:
|
|||||||
|
|
||||||
bool operator ==(const PIVector<T> & t) const {if (size_ != t.size_) return false; for (uint i = 0; i < size_; ++i) if (t[i] != data_[i]) return false; return true;}
|
bool operator ==(const PIVector<T> & t) const {if (size_ != t.size_) return false; for (uint i = 0; i < size_; ++i) if (t[i] != data_[i]) return false; return true;}
|
||||||
bool operator !=(const PIVector<T> & t) const {if (size_ != t.size_) return true; for (uint i = 0; i < size_; ++i) if (t[i] != data_[i]) return true; return false;}
|
bool operator !=(const PIVector<T> & t) const {if (size_ != t.size_) return true; for (uint i = 0; i < size_; ++i) if (t[i] != data_[i]) return true; return false;}
|
||||||
bool contain(const T & v) const {for (uint i = 0; i < size_; ++i) if (v == data_[i]) return true; return false;}
|
bool contains(const T & v) const {for (uint i = 0; i < size_; ++i) if (v == data_[i]) return true; return false;}
|
||||||
|
|
||||||
T * data(int index = 0) {return &(data_[index]);}
|
T * data(int index = 0) {return &(data_[index]);}
|
||||||
const T * data(int index = 0) const {return &(data_[index]);}
|
const T * data(int index = 0) const {return &(data_[index]);}
|
||||||
@@ -370,35 +371,193 @@ private:
|
|||||||
uint size_, rsize_, os;
|
uint size_, rsize_, os;
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*! \brief Dynamic array for any type
|
||||||
|
* \details This class used to store dynamic array of any
|
||||||
|
* type of data. In memory data stored linear. You can insert
|
||||||
|
* item in any place of remove some items from any place.
|
||||||
|
* For quick add elements there is stream operator <<.
|
||||||
|
* This class based on std::vector, expanding his
|
||||||
|
* functionality.
|
||||||
|
*/
|
||||||
template<typename Type, typename Allocator = std::allocator<Type> >
|
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||||
class PIVector: public vector<Type, Allocator> {
|
class PIP_EXPORT PIVector: public vector<Type, Allocator> {
|
||||||
typedef PIVector<Type, Allocator> _CVector;
|
typedef PIVector<Type, Allocator> _CVector;
|
||||||
typedef vector<Type, Allocator> _stlc;
|
typedef vector<Type, Allocator> _stlc;
|
||||||
public:
|
public:
|
||||||
|
//! Contructs an empty vector
|
||||||
PIVector() {piMonitor.containers++;}
|
PIVector() {piMonitor.containers++;}
|
||||||
|
|
||||||
|
//! Contructs vector with single element "value"
|
||||||
PIVector(const Type & value) {piMonitor.containers++; _stlc::push_back(value);}
|
PIVector(const Type & value) {piMonitor.containers++; _stlc::push_back(value);}
|
||||||
|
|
||||||
|
//! Contructs vector with two elements "v0" and "v1"
|
||||||
PIVector(const Type & v0, const Type & v1) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1);}
|
PIVector(const Type & v0, const Type & v1) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1);}
|
||||||
|
|
||||||
|
//! Contructs vector with three elements "v0", "v1" and "v2"
|
||||||
PIVector(const Type & v0, const Type & v1, const Type & v2) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);}
|
PIVector(const Type & v0, const Type & v1, const Type & v2) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);}
|
||||||
|
|
||||||
|
//! Contructs vector with four elements "v0", "v1", "v2" and "v3"
|
||||||
PIVector(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);}
|
PIVector(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);}
|
||||||
|
|
||||||
|
/*! \brief Contructs vector with size "size" filled elements "value"
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::PIVector */
|
||||||
PIVector(uint size, const Type & value = Type()) {piMonitor.containers++; _stlc::resize(size, value);}
|
PIVector(uint size, const Type & value = Type()) {piMonitor.containers++; _stlc::resize(size, value);}
|
||||||
~PIVector() {piMonitor.containers--;}
|
~PIVector() {piMonitor.containers--;}
|
||||||
|
|
||||||
|
/*! \brief Read-only access to element by index "index"
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::at_c
|
||||||
|
* \sa \a operator[] */
|
||||||
const Type & at(uint index) const {return (*this)[index];}
|
const Type & at(uint index) const {return (*this)[index];}
|
||||||
|
|
||||||
|
/*! \brief Full access to element by index "index"
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::at
|
||||||
|
* \sa \a operator[] */
|
||||||
Type & at(uint index) {return (*this)[index];}
|
Type & at(uint index) {return (*this)[index];}
|
||||||
|
|
||||||
|
/*! \brief Read-only pointer to element by index "index"
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::data_c */
|
||||||
const Type * data(uint index = 0) const {return &(*this)[index];}
|
const Type * data(uint index = 0) const {return &(*this)[index];}
|
||||||
|
|
||||||
|
/*! \brief Pointer to element by index "index"
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::data */
|
||||||
Type * data(uint index = 0) {return &(*this)[index];}
|
Type * data(uint index = 0) {return &(*this)[index];}
|
||||||
|
|
||||||
|
#ifdef DOXYGEN
|
||||||
|
//! Elements count
|
||||||
|
uint size() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! Elements count
|
||||||
int size_s() const {return static_cast<int>(_stlc::size());}
|
int size_s() const {return static_cast<int>(_stlc::size());}
|
||||||
|
|
||||||
|
//! Return \c "true" if vector is empty, i.e. size = 0
|
||||||
bool isEmpty() const {return _stlc::empty();}
|
bool isEmpty() const {return _stlc::empty();}
|
||||||
|
|
||||||
|
//! Return \c "true" if vector has at least one element equal "t"
|
||||||
|
bool has(const Type & t) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) return true; return false;}
|
||||||
|
|
||||||
|
//! Return how many times element "t" appears in vector
|
||||||
|
int etries(const Type & t) const {int ec = 0; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) ++ec; return ec;}
|
||||||
typedef int (*CompareFunc)(const Type * , const Type * );
|
typedef int (*CompareFunc)(const Type * , const Type * );
|
||||||
|
|
||||||
|
//! Standard compare function for type "Type". Return 0 if t0 = t1, -1 if t0 < t1 and 1 if t0 > t1.
|
||||||
static int compare_func(const Type * t0, const Type * t1) {return (*t0) == (*t1) ? 0 : ((*t0) < (*t1) ? -1 : 1);}
|
static int compare_func(const Type * t0, const Type * t1) {return (*t0) == (*t1) ? 0 : ((*t0) < (*t1) ? -1 : 1);}
|
||||||
|
#ifdef DOXYGEN
|
||||||
|
|
||||||
|
/*! \brief Resize vector to size "size"
|
||||||
|
* \details Elements removed from end of vector if new size < old size, or added new elements = "new_type" if new size > old size.\n
|
||||||
|
* Example: \snippet picontainers.cpp PIVector::resize
|
||||||
|
* \sa \a size(), \a clear() */
|
||||||
|
void resize(uint size, const Type & new_type = Type());
|
||||||
|
|
||||||
|
//! Increase vector size with "size" elements
|
||||||
|
PIVector<Type, Allocator> & enlarge(uint size);
|
||||||
|
|
||||||
|
//! Clear vector. Equivalent to call <tt>"resize(0)"</tt>
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
/*! \brief Sort vector using quick sort algorithm and standard compare function
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::sort_0
|
||||||
|
* With custom compare function: \snippet picontainers.cpp PIVector::sort_1 */
|
||||||
|
PIVector<Type, Allocator> & sort(CompareFunc compare = compare_func) {qsort(&at(0), _stlc::size(), sizeof(Type), (int(*)(const void * , const void * ))compare); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Fill vector with elements "t" leave size is unchanged and return reference to vector
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::fill */
|
||||||
|
PIVector<Type, Allocator> & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
|
||||||
|
|
||||||
|
//! Last element of vector
|
||||||
|
Type & back();
|
||||||
|
|
||||||
|
//! Last element of vector
|
||||||
|
const Type & back() const;
|
||||||
|
|
||||||
|
//! First element of vector
|
||||||
|
Type & front();
|
||||||
|
|
||||||
|
//! First element of vector
|
||||||
|
const Type & front() const;
|
||||||
|
|
||||||
|
//! Add new element "t" at the end of vector and return reference to vector
|
||||||
|
PIVector<Type, Allocator> & push_back(const Type & t);
|
||||||
|
|
||||||
|
//! Add new element "t" at the beginning of vector and return reference to vector
|
||||||
|
PIVector<Type, Allocator> & push_front(const Type & t) {_stlc::insert(_stlc::begin(), t); return *this;}
|
||||||
|
|
||||||
|
//! Remove one element from the end of vector and return reference to vector
|
||||||
|
PIVector<Type, Allocator> & pop_back();
|
||||||
|
|
||||||
|
//! Remove one element from the beginning of vector and return reference to vector
|
||||||
|
PIVector<Type, Allocator> & pop_front() {_stlc::erase(_stlc::begin()); return *this;}
|
||||||
|
|
||||||
|
//! Remove one element from the end of vector and return it
|
||||||
|
Type take_back() {Type t(_stlc::back()); _stlc::pop_back(); return t;}
|
||||||
|
|
||||||
|
//! Remove one element from the beginning of vector and return it
|
||||||
|
Type take_front() {Type t(_stlc::front()); pop_front(); return t;}
|
||||||
|
|
||||||
|
/*! \brief Remove one element by index "index" and return reference to vector
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::remove_0
|
||||||
|
* \sa \a removeOne(), \a removeAll() */
|
||||||
|
PIVector<Type, Allocator> & remove(uint index) {_stlc::erase(_stlc::begin() + index); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Remove "count" elements by first index "index" and return reference to vector
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::remove_1
|
||||||
|
* \sa \a removeOne(), \a removeAll() */
|
||||||
|
PIVector<Type, Allocator> & remove(uint index, uint count) {_stlc::erase(_stlc::begin() + index, _stlc::begin() + index + count); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Remove no more than one element equal "v" and return reference to vector
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::removeOne
|
||||||
|
* \sa \a remove(), \a removeAll() */
|
||||||
|
PIVector<Type, Allocator> & removeOne(const Type & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); return *this;} return *this;}
|
||||||
|
|
||||||
|
/*! \brief Remove all elements equal "v" and return reference to vector
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::removeAll
|
||||||
|
* \sa \a remove(), \a removeOne() */ */
|
||||||
|
PIVector<Type, Allocator> & removeAll(const Type & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); --i;} return *this;}
|
||||||
|
|
||||||
|
/*! \brief Insert element "t" after index "pos" and return reference to vector
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::insert_0 */
|
||||||
|
PIVector<Type, Allocator> & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Insert other vector "t" after index "pos" and return reference to vector
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::insert_1 */
|
||||||
|
PIVector<Type, Allocator> & insert(uint pos, const PIVector<Type, Allocator> & t) {_stlc::insert(_stlc::begin() + pos, t.begin(), t.end()); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Full access to element by index "index"
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::()
|
||||||
|
* \sa \a at() */
|
||||||
|
Type & operator [](uint index);
|
||||||
|
|
||||||
|
/*! \brief Read-only access to element by index "index"
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::()_c
|
||||||
|
* \sa \a at() */
|
||||||
|
const Type & operator [](uint index) const;
|
||||||
|
|
||||||
|
//! Add new element "t" at the end of vector and return reference to vector
|
||||||
|
PIVector<Type, Allocator> & operator <<(const Type & t) {_stlc::push_back(t); return *this;}
|
||||||
|
|
||||||
|
//! Add vector "t" at the end of vector and return reference to vector
|
||||||
|
PIVector<Type, Allocator> & operator <<(const PIVector<Type, Allocator> & t) {for (typename _stlc::const_iterator i = t.begin(); i != t.end(); i++) _stlc::push_back(*i); return *this;}
|
||||||
|
|
||||||
|
//! Compare with vector "t"
|
||||||
|
bool operator ==(const PIVector<Type, Allocator> & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return false; return true;}
|
||||||
|
|
||||||
|
//! Compare with vector "t"
|
||||||
|
bool operator !=(const PIVector<Type, Allocator> & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return true; return false;}
|
||||||
|
|
||||||
|
bool contains(const Type & v) const {for (uint i = 0; i < _stlc::size(); ++i) if (v == at(i)) return true; return false;}
|
||||||
|
|
||||||
|
#else
|
||||||
|
_CVector & enlarge(uint size_) {int ns = size_s() + size_; if (ns <= 0) _stlc::clear(); else _stlc::resize(ns); return *this;}
|
||||||
_CVector & sort(CompareFunc compare = compare_func) {qsort(&at(0), _stlc::size(), sizeof(Type), (int(*)(const void * , const void * ))compare); return *this;}
|
_CVector & sort(CompareFunc compare = compare_func) {qsort(&at(0), _stlc::size(), sizeof(Type), (int(*)(const void * , const void * ))compare); return *this;}
|
||||||
_CVector & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
|
_CVector & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
|
||||||
_CVector & pop_front() {_stlc::erase(_stlc::begin()); return *this;}
|
_CVector & pop_front() {_stlc::erase(_stlc::begin()); return *this;}
|
||||||
_CVector & push_front(const Type & t) {_stlc::insert(_stlc::begin(), t); return *this;}
|
_CVector & push_front(const Type & t) {_stlc::insert(_stlc::begin(), t); return *this;}
|
||||||
Type take_front() {Type t(_stlc::front()); pop_front(); return t;}
|
Type take_front() {Type t(_stlc::front()); pop_front(); return t;}
|
||||||
Type take_back() {Type t(_stlc::back()); _stlc::pop_back(); return t;}
|
Type take_back() {Type t(_stlc::back()); _stlc::pop_back(); return t;}
|
||||||
_CVector & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;}
|
_CVector & remove(uint index) {_stlc::erase(_stlc::begin() + index); return *this;}
|
||||||
_CVector & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
_CVector & remove(uint index, uint count) {_stlc::erase(_stlc::begin() + index, _stlc::begin() + index + count); return *this;}
|
||||||
//_CVector & remove(const Type & t) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) {_stlc::erase(i); --i;} return *this;}
|
|
||||||
_CVector & removeOne(const Type & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); return *this;} return *this;}
|
_CVector & removeOne(const Type & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); return *this;} return *this;}
|
||||||
_CVector & removeAll(const Type & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); --i;} return *this;}
|
_CVector & removeAll(const Type & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); --i;} return *this;}
|
||||||
_CVector & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
|
_CVector & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
|
||||||
@@ -407,14 +566,24 @@ public:
|
|||||||
_CVector & operator <<(const _CVector & t) {for (typename _stlc::const_iterator i = t.begin(); i != t.end(); i++) _stlc::push_back(*i); return *this;}
|
_CVector & operator <<(const _CVector & t) {for (typename _stlc::const_iterator i = t.begin(); i != t.end(); i++) _stlc::push_back(*i); return *this;}
|
||||||
bool operator ==(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return false; return true;}
|
bool operator ==(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return false; return true;}
|
||||||
bool operator !=(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return true; return false;}
|
bool operator !=(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return true; return false;}
|
||||||
bool contain(const Type & v) const {for (uint i = 0; i < _stlc::size(); ++i) if (v == at(i)) return true; return false;}
|
bool contains(const Type & v) const {for (uint i = 0; i < _stlc::size(); ++i) if (v == at(i)) return true; return false;}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*! \brief Output operator for std::ostream
|
||||||
|
* \relates PIVector
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::ostream<< */
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIVector<Type> & v) {s << "{"; for (uint i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIVector<Type> & v) {s << "{"; for (uint i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
||||||
|
|
||||||
|
/*! \brief Output operator for PICout
|
||||||
|
* \relates PIVector
|
||||||
|
* \details Example: \snippet picontainers.cpp PIVector::PICout<< */
|
||||||
|
template<typename Type>
|
||||||
|
inline PICout operator <<(PICout s, const PIVector<Type> & v) {s.space(); s.setControl(0, true); s << "{"; for (uint i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; s.restoreControl(); return s;}
|
||||||
|
|
||||||
template<typename Type, typename Allocator = std::allocator<Type> >
|
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||||
class PIList: public list<Type, Allocator> {
|
class PIP_EXPORT PIList: public list<Type, Allocator> {
|
||||||
typedef PIList<Type, Allocator> _CList;
|
typedef PIList<Type, Allocator> _CList;
|
||||||
typedef list<Type, Allocator> _stlc;
|
typedef list<Type, Allocator> _stlc;
|
||||||
public:
|
public:
|
||||||
@@ -431,16 +600,18 @@ public:
|
|||||||
Type * data(uint index = 0) {return &(*this)[index];}
|
Type * data(uint index = 0) {return &(*this)[index];}
|
||||||
int size_s() const {return static_cast<int>(_stlc::size());}
|
int size_s() const {return static_cast<int>(_stlc::size());}
|
||||||
bool isEmpty() const {return _stlc::empty();}
|
bool isEmpty() const {return _stlc::empty();}
|
||||||
|
bool has(const Type & t) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) return true; return false;}
|
||||||
|
int etries(const Type & t) const {int ec = 0; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) ++ec; return ec;}
|
||||||
_CList & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
|
_CList & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
|
||||||
_CList & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;}
|
_CList & remove(uint index) {_stlc::erase(_stlc::begin() + index); return *this;}
|
||||||
_CList & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
_CList & remove(uint index, uint count) {_stlc::erase(_stlc::begin() + index, _stlc::begin() + index + count); return *this;}
|
||||||
_CList & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
|
_CList & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
|
||||||
_CList & operator <<(const Type & t) {_stlc::push_back(t); return *this;}
|
_CList & operator <<(const Type & t) {_stlc::push_back(t); return *this;}
|
||||||
PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Type, typename Compare = std::less<Type>, typename Allocator = std::allocator<Type> >
|
template<typename Type, typename Compare = std::less<Type>, typename Allocator = std::allocator<Type> >
|
||||||
class PISet: public set<Type, Compare, Allocator> {
|
class PIP_EXPORT PISet: public set<Type, Compare, Allocator> {
|
||||||
typedef PISet<Type, Compare, Allocator> _CSet;
|
typedef PISet<Type, Compare, Allocator> _CSet;
|
||||||
typedef set<Type, Compare, Allocator> _stlc;
|
typedef set<Type, Compare, Allocator> _stlc;
|
||||||
public:
|
public:
|
||||||
@@ -452,15 +623,15 @@ public:
|
|||||||
~PISet() {piMonitor.containers--;}
|
~PISet() {piMonitor.containers--;}
|
||||||
int size_s() const {return static_cast<int>(_stlc::size());}
|
int size_s() const {return static_cast<int>(_stlc::size());}
|
||||||
bool isEmpty() const {return _stlc::empty();}
|
bool isEmpty() const {return _stlc::empty();}
|
||||||
_CSet & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;}
|
_CSet & remove(uint index) {_stlc::erase(_stlc::begin() + index); return *this;}
|
||||||
_CSet & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
_CSet & remove(uint index, uint count) {_stlc::erase(_stlc::begin() + index, _stlc::begin() + index + count); return *this;}
|
||||||
_CSet & operator <<(const Type & t) {_stlc::insert(t); return *this;}
|
_CSet & operator <<(const Type & t) {_stlc::insert(t); return *this;}
|
||||||
bool operator [](const Type & t) {return _stlc::find(t);}
|
bool operator [](const Type & t) {return _stlc::find(t);}
|
||||||
PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
class PIStack: public PIVector<Type> {
|
class PIP_EXPORT PIStack: public PIVector<Type> {
|
||||||
typedef PIStack<Type> _CStack;
|
typedef PIStack<Type> _CStack;
|
||||||
public:
|
public:
|
||||||
PIStack() {;}
|
PIStack() {;}
|
||||||
@@ -476,7 +647,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Type, typename Allocator = std::allocator<Type> >
|
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||||
class PIDeque: public deque<Type, Allocator> {
|
class PIP_EXPORT PIDeque: public deque<Type, Allocator> {
|
||||||
typedef PIDeque<Type, Allocator> _CDeque;
|
typedef PIDeque<Type, Allocator> _CDeque;
|
||||||
typedef deque<Type, Allocator> _stlc;
|
typedef deque<Type, Allocator> _stlc;
|
||||||
public:
|
public:
|
||||||
@@ -488,12 +659,14 @@ public:
|
|||||||
~PIDeque() {piMonitor.containers--;}
|
~PIDeque() {piMonitor.containers--;}
|
||||||
int size_s() const {return static_cast<int>(_stlc::size());}
|
int size_s() const {return static_cast<int>(_stlc::size());}
|
||||||
bool isEmpty() const {return _stlc::empty();}
|
bool isEmpty() const {return _stlc::empty();}
|
||||||
|
bool has(const Type & t) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) return true; return false;}
|
||||||
|
int etries(const Type & t) const {int ec = 0; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) ++ec; return ec;}
|
||||||
_CDeque & operator <<(const Type & t) {_CDeque::push_back(t); return *this;}
|
_CDeque & operator <<(const Type & t) {_CDeque::push_back(t); return *this;}
|
||||||
PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
class PIQueue: public PIDeque<Type> {
|
class PIP_EXPORT PIQueue: public PIDeque<Type> {
|
||||||
typedef PIQueue<Type> _CQueue;
|
typedef PIQueue<Type> _CQueue;
|
||||||
public:
|
public:
|
||||||
PIQueue() {;}
|
PIQueue() {;}
|
||||||
@@ -510,7 +683,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
template<typename Type0, typename Type1>
|
template<typename Type0, typename Type1>
|
||||||
class PIPair {
|
class PIP_EXPORT PIPair {
|
||||||
public:
|
public:
|
||||||
PIPair() {first = Type0(); second = Type1();}
|
PIPair() {first = Type0(); second = Type1();}
|
||||||
PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;}
|
PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;}
|
||||||
@@ -519,21 +692,62 @@ public:
|
|||||||
};
|
};
|
||||||
template<typename Type0, typename Type1>
|
template<typename Type0, typename Type1>
|
||||||
inline bool operator <(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return value0.first < value1.first;}
|
inline bool operator <(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return value0.first < value1.first;}
|
||||||
|
template<typename Type0, typename Type1>
|
||||||
|
inline std::ostream & operator <<(std::ostream & s, const PIPair<Type0, Type1> & v) {s << "(" << v.first << ", " << v.second << ")"; return s;}
|
||||||
|
template<typename Type0, typename Type1>
|
||||||
|
inline PICout operator <<(PICout s, const PIPair<Type0, Type1> & v) {s.space(); s.setControl(0, true); s << "(" << v.first << ", " << v.second << ")"; s.restoreControl(); return s;}
|
||||||
|
|
||||||
|
|
||||||
template<typename Key, typename Type>
|
template<typename Key, typename Type>
|
||||||
class PIMap: public map<Key, Type> {
|
class PIP_EXPORT PIMap: public map<Key, Type> {
|
||||||
typedef PIMap<Key, Type> _CMap;
|
typedef PIMap<Key, Type> _CMap;
|
||||||
typedef map<Key, Type> _stlc;
|
typedef map<Key, Type> _stlc;
|
||||||
typedef std::pair<Key, Type> _stlpair;
|
typedef std::pair<Key, Type> _stlpair;
|
||||||
public:
|
public:
|
||||||
PIMap() {;}
|
PIMap() {;}
|
||||||
PIMap(const Key & key_, const Type & value_) {insert(key_, value_);}
|
PIMap(const Key & key_, const Type & value_) {insert(key_, value_);}
|
||||||
_CMap & insert(const Key & key_, const Type & value_) {_stlc::insert(std::pair<Key, Type>(key_, value_)); return *this;}
|
bool isEmpty() const {return _stlc::empty();}
|
||||||
_CMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(std::pair<Key, Type>(entry_.first, entry_.second)); return *this;}
|
bool contains(const Key & key_) const {return _stlc::count(key_) > 0;}
|
||||||
|
_CMap & insert(const Key & key_, const Type & value_) {_stlc::insert(_stlpair(key_, value_)); return *this;}
|
||||||
|
_CMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
|
||||||
Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();}
|
Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();}
|
||||||
Type & value(Key key_) {return (*this)[key_];}
|
Type & value(const Key & key_) {typename _stlc::iterator it = _stlc::find(key_); if (it == _stlc::end()) it->second = Type(); return it->second;}
|
||||||
Type value(Key key_) const {return (*this)[key_];}
|
Type value(const Key & key_) const {return _stlc::find(key_)->second;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Key, typename Type>
|
||||||
|
class PIP_EXPORT PIMultiMap: public multimap<Key, Type> {
|
||||||
|
typedef PIMultiMap<Key, Type> _CMultiMap;
|
||||||
|
typedef multimap<Key, Type> _stlc;
|
||||||
|
typedef std::pair<Key, Type> _stlpair;
|
||||||
|
public:
|
||||||
|
PIMultiMap() {;}
|
||||||
|
PIMultiMap(const Key & key_, const Type & value_) {insert(key_, value_);}
|
||||||
|
_CMultiMap & insert(const Key & key_, const Type & value_) {_stlc::insert(_stlpair(key_, value_)); return *this;}
|
||||||
|
_CMultiMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
|
||||||
|
bool isEmpty() const {return _stlc::empty();}
|
||||||
|
bool contains(const Key & key_) const {return _stlc::count(key_) > 0;}
|
||||||
|
Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();}
|
||||||
|
PIVector<Key> keys(Type value_) const {
|
||||||
|
PIVector<Key> ret;
|
||||||
|
for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++)
|
||||||
|
if (i->second == value_)
|
||||||
|
ret << i->first;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Type & value(const Key & key_) {return _stlc::find(key_)->second;}
|
||||||
|
Type value(const Key & key_) const {return _stlc::find(key_)->second;}
|
||||||
|
PIVector<Type> values(const Key & key_) const {
|
||||||
|
std::pair<typename _stlc::const_iterator, typename _stlc::const_iterator> range = _stlc::equal_range(key_);
|
||||||
|
PIVector<Type> ret;
|
||||||
|
for (typename _stlc::const_iterator i = range.first; i != range.second; ++i)
|
||||||
|
ret << i->second;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Type & operator [](const Key & key_) {if (!contains(key_)) return _stlc::insert(_stlpair(key_, Type()))->second; return _stlc::find(key_)->second;}
|
||||||
|
Type operator [](const Key & key_) const {return _stlc::find(key_)->second;}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // PICONTAINERS_H
|
#endif // PICONTAINERS_H
|
||||||
|
|||||||
4
picrc.h
4
picrc.h
@@ -23,7 +23,7 @@
|
|||||||
#include "pistring.h"
|
#include "pistring.h"
|
||||||
|
|
||||||
template <int L>
|
template <int L>
|
||||||
class uint_cl {
|
class PIP_EXPORT uint_cl {
|
||||||
public:
|
public:
|
||||||
uint_cl() {for (int i = 0; i < L / 8; ++i) data_[i] = 0;}
|
uint_cl() {for (int i = 0; i < L / 8; ++i) data_[i] = 0;}
|
||||||
uint_cl(const uint_cl<L> & v) {for (int i = 0; i < L / 8; ++i) data_[i] = v.data_[i];}
|
uint_cl(const uint_cl<L> & v) {for (int i = 0; i < L / 8; ++i) data_[i] = v.data_[i];}
|
||||||
@@ -160,7 +160,7 @@ inline std::ostream & operator <<(std::ostream & s, const uint_cl<L> & v) {std::
|
|||||||
|
|
||||||
|
|
||||||
template <uint L>
|
template <uint L>
|
||||||
class PICRC {
|
class PIP_EXPORT PICRC {
|
||||||
public:
|
public:
|
||||||
PICRC(const uint_cl<L> & poly) {poly_ = poly; reverse_poly = true; init_ = uint_cl<L>(0).inversed(); out_ = uint_cl<L>(0).inversed(); initTable();}
|
PICRC(const uint_cl<L> & poly) {poly_ = poly; reverse_poly = true; init_ = uint_cl<L>(0).inversed(); out_ = uint_cl<L>(0).inversed(); initTable();}
|
||||||
PICRC(const uint_cl<L> & poly, bool reverse, const uint_cl<L> & initial, const uint_cl<L> & out_xor) {poly_ = poly; reverse_poly = reverse; init_ = initial; out_ = out_xor; initTable();}
|
PICRC(const uint_cl<L> & poly, bool reverse, const uint_cl<L> & initial, const uint_cl<L> & out_xor) {poly_ = poly; reverse_poly = reverse; init_ = initial; out_ = out_xor; initTable();}
|
||||||
|
|||||||
2
pidir.h
2
pidir.h
@@ -26,7 +26,7 @@
|
|||||||
#include <sys/dir.h>
|
#include <sys/dir.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
class PIDir
|
class PIP_EXPORT PIDir
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PIDir();
|
PIDir();
|
||||||
|
|||||||
117
piethernet.cpp
117
piethernet.cpp
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Ethernet, UDP
|
Ethernet, UDP/TCP Broadcast/Multicast
|
||||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -47,7 +47,7 @@ PIEthernet::PIEthernet(PIEthernet::Type type, void * data, ReadRetFunc slot): PI
|
|||||||
sock = sock_s = -1;
|
sock = sock_s = -1;
|
||||||
ret_func_ = slot;
|
ret_func_ = slot;
|
||||||
connected_ = false;
|
connected_ = false;
|
||||||
params = PIEthernet::ReuseAddress;
|
params = (type == UDP ? PIEthernet::ReuseAddress : 0);
|
||||||
server_thread_.setData(this);
|
server_thread_.setData(this);
|
||||||
setThreadedReadBufferSize(65536);
|
setThreadedReadBufferSize(65536);
|
||||||
if (type_ != UDP) init();
|
if (type_ != UDP) init();
|
||||||
@@ -58,6 +58,7 @@ PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
|
|||||||
piMonitor.ethernets++;
|
piMonitor.ethernets++;
|
||||||
setPriority(piHigh);
|
setPriority(piHigh);
|
||||||
type_ = TCP_Client;
|
type_ = TCP_Client;
|
||||||
|
path_ = ip_port;
|
||||||
parseAddress(ip_port, &ip_s, &port_s);
|
parseAddress(ip_port, &ip_s, &port_s);
|
||||||
sock = sock_;
|
sock = sock_;
|
||||||
sock_s = -1;
|
sock_s = -1;
|
||||||
@@ -80,22 +81,28 @@ PIEthernet::~PIEthernet() {
|
|||||||
bool PIEthernet::init() {
|
bool PIEthernet::init() {
|
||||||
//cout << "init " << type_ << endl;
|
//cout << "init " << type_ << endl;
|
||||||
closeSocket(sock);
|
closeSocket(sock);
|
||||||
int st = 0;
|
int st = 0, pr = 0;;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
int flags = WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF;
|
int flags = 0;
|
||||||
#else
|
#else
|
||||||
int so = 1;
|
int so = 1;
|
||||||
#endif
|
#endif
|
||||||
if (type_ == UDP) st = SOCK_DGRAM;
|
if (type_ == UDP) {
|
||||||
else st = SOCK_STREAM;
|
st = SOCK_DGRAM;
|
||||||
|
pr = IPPROTO_UDP;
|
||||||
|
} else {
|
||||||
|
st = SOCK_STREAM;
|
||||||
|
pr = IPPROTO_TCP;
|
||||||
|
}
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
if (type_ == UDP) flags = WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF;
|
||||||
if (params[ReuseAddress]) flags |= WSA_FLAG_OVERLAPPED;
|
if (params[ReuseAddress]) flags |= WSA_FLAG_OVERLAPPED;
|
||||||
sock = WSASocket(AF_INET, st, type_ == UDP ? IPPROTO_UDP : IPPROTO_TCP, NULL, 0, flags);
|
sock = WSASocket(AF_INET, st, pr, NULL, 0, flags);
|
||||||
#else
|
#else
|
||||||
sock = socket(AF_INET, st, type_ == UDP ? IPPROTO_UDP : IPPROTO_TCP);
|
sock = socket(AF_INET, st, pr);
|
||||||
#endif
|
#endif
|
||||||
if (sock == -1) {
|
if (sock == -1) {
|
||||||
piCout << "[PIEthernet] Cant`t create socket, " << EthErrorString() << endl;
|
piCout << "[PIEthernet] Cant`t create socket, " << ethErrorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
@@ -116,9 +123,11 @@ void PIEthernet::parseAddress(const PIString & ipp, PIString * ip, int * port) {
|
|||||||
|
|
||||||
bool PIEthernet::openDevice() {
|
bool PIEthernet::openDevice() {
|
||||||
if (connected_) return true;
|
if (connected_) return true;
|
||||||
if (sock == -1) init();
|
init();
|
||||||
if (sock == -1 || path_.isEmpty()) return false;
|
if (sock == -1 || path_.isEmpty()) return false;
|
||||||
parseAddress(path_, &ip_, &port_);
|
parseAddress(path_, &ip_, &port_);
|
||||||
|
if (type_ != UDP)
|
||||||
|
return true;
|
||||||
//cout << " bind to " << sock << ": " << (params[PIEthernet::Broadcast] ? "0.0.0.0" : path_) << ": " << port_ << " ..." <<endl;
|
//cout << " bind to " << sock << ": " << (params[PIEthernet::Broadcast] ? "0.0.0.0" : path_) << ": " << port_ << " ..." <<endl;
|
||||||
memset(&addr_, 0, sizeof(addr_));
|
memset(&addr_, 0, sizeof(addr_));
|
||||||
addr_.sin_family = AF_INET;
|
addr_.sin_family = AF_INET;
|
||||||
@@ -134,9 +143,12 @@ bool PIEthernet::openDevice() {
|
|||||||
tries++;
|
tries++;
|
||||||
}
|
}
|
||||||
if (tries == 10) {
|
if (tries == 10) {
|
||||||
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << EthErrorString() << endl;
|
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
opened_ = true;
|
||||||
|
while (!mcast_queue.isEmpty())
|
||||||
|
joinMulticastGroup(mcast_queue.dequeue());
|
||||||
//cout << "!" << endl;
|
//cout << "!" << endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -150,6 +162,7 @@ bool PIEthernet::closeDevice() {
|
|||||||
delete i;
|
delete i;
|
||||||
clients_.clear();
|
clients_.clear();
|
||||||
if (server_thread_.isRunning()) server_thread_.terminate();
|
if (server_thread_.isRunning()) server_thread_.terminate();
|
||||||
|
if (connected_) disconnected(false);
|
||||||
connected_ = false;
|
connected_ = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -159,9 +172,15 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
|||||||
if (sock == -1) init();
|
if (sock == -1) init();
|
||||||
if (sock == -1) return false;
|
if (sock == -1) return false;
|
||||||
if (type_ != UDP) {
|
if (type_ != UDP) {
|
||||||
piCout << "[PIEthernet] Only UDP sockets can join multicast groups" << endl;
|
piCout << "[PIEthernet] Only UDP sockets can join multicast groups";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!opened_) {
|
||||||
|
if (mcast_queue.has(group))
|
||||||
|
return false;
|
||||||
|
mcast_queue.enqueue(group);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
parseAddress(path_, &ip_, &port_);
|
parseAddress(path_, &ip_, &port_);
|
||||||
memset(&addr_, 0, sizeof(addr_));
|
memset(&addr_, 0, sizeof(addr_));
|
||||||
@@ -170,23 +189,23 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
|||||||
addr_.sin_addr.s_addr = inet_addr(group.data());
|
addr_.sin_addr.s_addr = inet_addr(group.data());
|
||||||
SOCKET ret = WSAJoinLeaf(sock, (sockaddr *)&addr_, sizeof(addr_), NULL, NULL, NULL, NULL, JL_BOTH);
|
SOCKET ret = WSAJoinLeaf(sock, (sockaddr *)&addr_, sizeof(addr_), NULL, NULL, NULL, NULL, JL_BOTH);
|
||||||
if (ret == INVALID_SOCKET) {
|
if (ret == INVALID_SOCKET) {
|
||||||
piCout << "[PIEthernet] Cant`t join multicast group " << group << ", " << EthErrorString() << endl;
|
piCout << "[PIEthernet] Cant`t join multicast group " << group << ", " << ethErrorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
leafs.insert(group, ret);
|
leafs.insert(group, ret);
|
||||||
#else
|
#else
|
||||||
# ifndef QNX
|
# ifndef QNX
|
||||||
if (!params[Broadcast])
|
if (!params[Broadcast])
|
||||||
piCout << "[PIEthernet] Warning: \"Broadcast\" parameter not set, \"joinMulticastGroup(\"" << group << "\")\" may be useless!" << endl;
|
piCout << "[PIEthernet] Warning: \"Broadcast\" parameter not set, \"joinMulticastGroup(\"" << group << "\")\" may be useless!";
|
||||||
parseAddress(path_, &ip_, &port_);
|
parseAddress(path_, &ip_, &port_);
|
||||||
struct ip_mreqn mreq;
|
struct ip_mreqn mreq;
|
||||||
memset(&mreq, 0, sizeof(mreq));
|
memset(&mreq, 0, sizeof(mreq));
|
||||||
if (params[PIEthernet::Broadcast]) mreq.imr_address.s_addr = INADDR_ANY;
|
/*if (params[PIEthernet::Broadcast]) mreq.imr_address.s_addr = INADDR_ANY;
|
||||||
else mreq.imr_address.s_addr = inet_addr(ip_.data());
|
else*/ mreq.imr_address.s_addr = inet_addr(ip_.data());
|
||||||
mreq.imr_multiaddr.s_addr = inet_addr(group.data());
|
mreq.imr_multiaddr.s_addr = inet_addr(group.data());
|
||||||
mreq.imr_ifindex = 0;
|
mreq.imr_ifindex = 0;
|
||||||
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) {
|
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) {
|
||||||
piCout << "[PIEthernet] Cant`t join multicast group " << group << ", " << EthErrorString() << endl;
|
piCout << "[PIEthernet] Cant`t join multicast group " << group << ", " << ethErrorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
@@ -199,7 +218,7 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
|||||||
if (sock == -1) init();
|
if (sock == -1) init();
|
||||||
if (sock == -1) return false;
|
if (sock == -1) return false;
|
||||||
if (type_ != UDP) {
|
if (type_ != UDP) {
|
||||||
piCout << "[PIEthernet] Only UDP sockets can leave multicast groups" << endl;
|
piCout << "[PIEthernet] Only UDP sockets can leave multicast groups";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
@@ -218,7 +237,7 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
|||||||
mreq.imr_multiaddr.s_addr = inet_addr(group.data());
|
mreq.imr_multiaddr.s_addr = inet_addr(group.data());
|
||||||
mreq.imr_ifindex = 0;
|
mreq.imr_ifindex = 0;
|
||||||
if (setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) {
|
if (setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) {
|
||||||
piCout << "[PIEthernet] Cant`t leave multicast group " << group << ", " << EthErrorString() << endl;
|
piCout << "[PIEthernet] Cant`t leave multicast group " << group << ", " << ethErrorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -227,20 +246,22 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIEthernet::connect(const PIString & ip, int port) {
|
bool PIEthernet::connect() {
|
||||||
if (sock == -1) return false;
|
if (sock == -1) return false;
|
||||||
memset(&addr_, 0, sizeof(addr_));
|
memset(&addr_, 0, sizeof(addr_));
|
||||||
addr_.sin_port = htons(port);
|
parseAddress(path_, &ip_, &port_);
|
||||||
addr_.sin_addr.s_addr = inet_addr(ip.data());
|
addr_.sin_port = htons(port_);
|
||||||
|
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||||
addr_.sin_family = AF_INET;
|
addr_.sin_family = AF_INET;
|
||||||
#ifdef QNX
|
#ifdef QNX
|
||||||
addr_.sin_len = sizeof(addr_);
|
addr_.sin_len = sizeof(addr_);
|
||||||
#endif
|
#endif
|
||||||
//piCout << "[PIEthernet] connect to " << ip << ":" << port << endl;
|
//piCout << "[PIEthernet] connect to " << ip << ":" << port_;
|
||||||
connected_ = (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) == 0);
|
connected_ = (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) == 0);
|
||||||
if (!connected_)
|
if (!connected_)
|
||||||
piCout << "[PIEthernet] Cant`t connect to " << ip << ":" << port << ", " << EthErrorString() << endl;
|
piCout << "[PIEthernet] Cant`t connect to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
||||||
opened_ = connected_;
|
opened_ = connected_;
|
||||||
|
if (connected_) connected();
|
||||||
return connected_;
|
return connected_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,14 +283,14 @@ bool PIEthernet::listen() {
|
|||||||
tries++;
|
tries++;
|
||||||
}
|
}
|
||||||
if (tries == 10) {
|
if (tries == 10) {
|
||||||
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << EthErrorString() << endl;
|
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (::listen(sock, 64) == -1) {
|
if (::listen(sock, 64) == -1) {
|
||||||
piCout << "[PIEthernet] Can`t listen on "<< ip_ << ":" << port_ << ", " << EthErrorString() << endl;
|
piCout << "[PIEthernet] Can`t listen on "<< ip_ << ":" << port_ << ", " << ethErrorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//piCout << "[PIEthernet] listen on " << ip_ << ":" << port_ << endl;
|
//piCout << "[PIEthernet] listen on " << ip_ << ":" << port_;
|
||||||
server_thread_.start(server_func);
|
server_thread_.start(server_func);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -288,19 +309,27 @@ int PIEthernet::read(void * read_to, int max_size) {
|
|||||||
::listen(sock, 64);
|
::listen(sock, 64);
|
||||||
s = accept(sock, (sockaddr * )&client_addr, &slen);
|
s = accept(sock, (sockaddr * )&client_addr, &slen);
|
||||||
if (s == -1) {
|
if (s == -1) {
|
||||||
piCout << "[PIEthernet] Cant`t accept new connection, " << EthErrorString() << endl;
|
piCout << "[PIEthernet] Cant`t accept new connection, " << ethErrorString();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rs = recv(s, (char * )read_to, max_size, 0);
|
rs = recv(s, (char * )read_to, max_size, 0);
|
||||||
closeSocket(s);
|
closeSocket(s);
|
||||||
return rs;
|
return rs;
|
||||||
case UDP: case TCP_Client:
|
case TCP_Client:
|
||||||
|
if (!connected_) return -1;
|
||||||
|
case UDP:
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
rs = recv(sock, (char * )read_to, max_size, 0);
|
rs = recv(sock, (char * )read_to, max_size, 0);
|
||||||
#else
|
#else
|
||||||
rs = recv(sock, read_to, max_size, 0);
|
rs = recv(sock, read_to, max_size, 0);
|
||||||
#endif
|
#endif
|
||||||
if (rs >= 0) received(read_to, rs);
|
piCout << "eth" << path_ << "read return" << rs << errno;
|
||||||
|
if (rs <= 0) {
|
||||||
|
connected_ = false;
|
||||||
|
disconnected(rs < 0);
|
||||||
|
piCout << "eth" << path_ << "disconnected";
|
||||||
|
}
|
||||||
|
if (rs > 0) received(read_to, rs);
|
||||||
return rs;
|
return rs;
|
||||||
//return ::read(sock, read_to, max_size);
|
//return ::read(sock, read_to, max_size);
|
||||||
default: break;
|
default: break;
|
||||||
@@ -313,10 +342,10 @@ int PIEthernet::read(void * read_to, int max_size) {
|
|||||||
int PIEthernet::write(const void * data, int max_size) {
|
int PIEthernet::write(const void * data, int max_size) {
|
||||||
if (sock == -1) init();
|
if (sock == -1) init();
|
||||||
if (sock == -1 || !isWriteable()) {
|
if (sock == -1 || !isWriteable()) {
|
||||||
//piCout << "[PIEthernet] Can`t send to uninitialized socket" << endl;
|
//piCout << "[PIEthernet] Can`t send to uninitialized socket";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
//piCout << "[PIEthernet] sending to " << ip_s << ":" << port_s << " " << max_size << " bytes" << endl;
|
//piCout << "[PIEthernet] sending to " << ip_s << ":" << port_s << " " << max_size << " bytes";
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case TCP_SingleTCP:
|
case TCP_SingleTCP:
|
||||||
@@ -327,11 +356,14 @@ int PIEthernet::write(const void * data, int max_size) {
|
|||||||
#ifdef QNX
|
#ifdef QNX
|
||||||
addr_.sin_len = sizeof(addr_);
|
addr_.sin_len = sizeof(addr_);
|
||||||
#endif
|
#endif
|
||||||
|
//piCout << "connect SingleTCP" << ip_s << ":" << port_s << "...";
|
||||||
if (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) != 0) {
|
if (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) != 0) {
|
||||||
piCout << "[PIEthernet] Cant`t connect to " << ip_s << ":" << port_s << ", " << EthErrorString() << endl;
|
piCout << "[PIEthernet] Cant`t connect to " << ip_s << ":" << port_s << ", " << ethErrorString();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = ::write(sock, data, max_size);
|
//piCout << "ok, write SingleTCP" << int(data) << max_size << "bytes ...";
|
||||||
|
ret = ::send(sock, (const char *)data, max_size, 0);
|
||||||
|
//piCout << "ok, ret" << ret;
|
||||||
closeSocket(sock);
|
closeSocket(sock);
|
||||||
init();
|
init();
|
||||||
return ret;
|
return ret;
|
||||||
@@ -346,7 +378,7 @@ int PIEthernet::write(const void * data, int max_size) {
|
|||||||
return sendto(sock, data, max_size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
return sendto(sock, data, max_size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
||||||
#endif
|
#endif
|
||||||
case TCP_Client:
|
case TCP_Client:
|
||||||
return ::write(sock, data, max_size);
|
return ::send(sock, (const char *)data, max_size, 0);
|
||||||
default: break;
|
default: break;
|
||||||
//return ::read(sock, read_to, max_size);
|
//return ::read(sock, read_to, max_size);
|
||||||
}
|
}
|
||||||
@@ -359,12 +391,13 @@ void PIEthernet::server_func(void * eth) {
|
|||||||
socklen_t slen = sizeof(client_addr);
|
socklen_t slen = sizeof(client_addr);
|
||||||
int s = accept(ce->sock, (sockaddr * )&client_addr, &slen);
|
int s = accept(ce->sock, (sockaddr * )&client_addr, &slen);
|
||||||
if (s == -1) {
|
if (s == -1) {
|
||||||
piCout << "[PIEthernet] Cant`t accept new connection, " << EthErrorString() << endl;
|
piCout << "[PIEthernet] Cant`t accept new connection, " << ethErrorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PIString ip(inet_ntoa(client_addr.sin_addr));
|
PIString ip(inet_ntoa(client_addr.sin_addr));
|
||||||
ip += ":" + PIString::fromNumber(htons(client_addr.sin_port));
|
ip += ":" + PIString::fromNumber(htons(client_addr.sin_port));
|
||||||
ce->clients_ << new PIEthernet(s, ip);
|
ce->clients_ << new PIEthernet(s, ip);
|
||||||
|
ce->newConnection(ce->clients_.back());
|
||||||
//cout << "connected " << ip << endl;
|
//cout << "connected " << ip << endl;
|
||||||
//char d[256];
|
//char d[256];
|
||||||
//cout << " recv " << recv(s, d, 256, 0) << endl;
|
//cout << " recv " << recv(s, d, 256, 0) << endl;
|
||||||
@@ -375,7 +408,7 @@ void PIEthernet::server_func(void * eth) {
|
|||||||
|
|
||||||
PIStringList PIEthernet::interfaces() {
|
PIStringList PIEthernet::interfaces() {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
piCout << "[PIEthernet] Not implemented on Windows, use \"PIEthernet::allAddresses\" instead" << endl;
|
piCout << "[PIEthernet] Not implemented on Windows, use \"PIEthernet::allAddresses\" instead";
|
||||||
return PIStringList();
|
return PIStringList();
|
||||||
#else
|
#else
|
||||||
# ifdef QNX
|
# ifdef QNX
|
||||||
@@ -434,7 +467,7 @@ PIStringList PIEthernet::interfaces() {
|
|||||||
|
|
||||||
PIString PIEthernet::interfaceAddress(const PIString & interface_) {
|
PIString PIEthernet::interfaceAddress(const PIString & interface_) {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
piCout << "[PIEthernet] Not implemented on Windows, use \"PIEthernet::allAddresses\" instead" << endl;
|
piCout << "[PIEthernet] Not implemented on Windows, use \"PIEthernet::allAddresses\" instead";
|
||||||
return PIString();
|
return PIString();
|
||||||
#else
|
#else
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
@@ -459,14 +492,14 @@ PIStringList PIEthernet::allAddresses() {
|
|||||||
ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||||
pAdapterInfo = (IP_ADAPTER_INFO * ) HeapAlloc(GetProcessHeap(), 0, (sizeof (IP_ADAPTER_INFO)));
|
pAdapterInfo = (IP_ADAPTER_INFO * ) HeapAlloc(GetProcessHeap(), 0, (sizeof (IP_ADAPTER_INFO)));
|
||||||
if (pAdapterInfo == 0) {
|
if (pAdapterInfo == 0) {
|
||||||
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersinfo" << endl;
|
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersinfo";
|
||||||
return PIStringList();
|
return PIStringList();
|
||||||
}
|
}
|
||||||
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
|
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
|
||||||
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
||||||
pAdapterInfo = (IP_ADAPTER_INFO *) HeapAlloc(GetProcessHeap(), 0, (ulOutBufLen));
|
pAdapterInfo = (IP_ADAPTER_INFO *) HeapAlloc(GetProcessHeap(), 0, (ulOutBufLen));
|
||||||
if (pAdapterInfo == 0) {
|
if (pAdapterInfo == 0) {
|
||||||
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersinfo" << endl;
|
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersinfo";
|
||||||
return PIStringList();
|
return PIStringList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -482,7 +515,7 @@ PIStringList PIEthernet::allAddresses() {
|
|||||||
pAdapter = pAdapter->Next;
|
pAdapter = pAdapter->Next;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
piCout << "[PIEthernet] GetAdaptersInfo failed with error: " << ret << endl;
|
piCout << "[PIEthernet] GetAdaptersInfo failed with error: " << ret;
|
||||||
if (pAdapterInfo)
|
if (pAdapterInfo)
|
||||||
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
||||||
return al;
|
return al;
|
||||||
@@ -490,6 +523,6 @@ PIStringList PIEthernet::allAddresses() {
|
|||||||
PIStringList il = interfaces(), al;
|
PIStringList il = interfaces(), al;
|
||||||
piForeachC (PIString & i, il)
|
piForeachC (PIString & i, il)
|
||||||
al << interfaceAddress(i);
|
al << interfaceAddress(i);
|
||||||
return al;
|
return al.removeStrings("0.0.0.0");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
26
piethernet.h
26
piethernet.h
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Ethernet, UDP
|
Ethernet, UDP/TCP Broadcast/Multicast
|
||||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -24,8 +24,9 @@
|
|||||||
#include "piiodevice.h"
|
#include "piiodevice.h"
|
||||||
#include "piprocess.h"
|
#include "piprocess.h"
|
||||||
|
|
||||||
class PIEthernet: public PIIODevice
|
class PIP_EXPORT PIEthernet: public PIIODevice
|
||||||
{
|
{
|
||||||
|
PIOBJECT(PIEthernet)
|
||||||
friend class PIPeer;
|
friend class PIPeer;
|
||||||
public:
|
public:
|
||||||
// slot is any function format "bool <func>(void*, uchar*, int)"
|
// slot is any function format "bool <func>(void*, uchar*, int)"
|
||||||
@@ -35,7 +36,7 @@ public:
|
|||||||
enum Parameters {ReuseAddress = 0x1, Broadcast = 0x2};
|
enum Parameters {ReuseAddress = 0x1, Broadcast = 0x2};
|
||||||
|
|
||||||
PIEthernet(Type type = UDP, void * data = 0, ReadRetFunc slot = 0);
|
PIEthernet(Type type = UDP, void * data = 0, ReadRetFunc slot = 0);
|
||||||
~PIEthernet();
|
virtual ~PIEthernet();
|
||||||
|
|
||||||
void setReadAddress(const PIString & ip, int port) {path_ = ip + ":" + PIString::fromNumber(port);}
|
void setReadAddress(const PIString & ip, int port) {path_ = ip + ":" + PIString::fromNumber(port);}
|
||||||
void setReadAddress(const PIString & ip_port) {path_ = ip_port;}
|
void setReadAddress(const PIString & ip_port) {path_ = ip_port;}
|
||||||
@@ -61,8 +62,9 @@ public:
|
|||||||
bool joinMulticastGroup(const PIString & group);
|
bool joinMulticastGroup(const PIString & group);
|
||||||
bool leaveMulticastGroup(const PIString & group);
|
bool leaveMulticastGroup(const PIString & group);
|
||||||
|
|
||||||
bool connect(const PIString & ip, int port);
|
bool connect();
|
||||||
bool connect(const PIString & ip_port) {parseAddress(ip_port, &ip_c, &port_c); return connect(ip_c, port_c);}
|
bool connect(const PIString & ip, int port) {path_ = ip + ":" + PIString::fromNumber(port); return connect();}
|
||||||
|
bool connect(const PIString & ip_port) {path_ = ip_port; return connect();}
|
||||||
bool isConnected() const {return connected_;}
|
bool isConnected() const {return connected_;}
|
||||||
|
|
||||||
bool listen();
|
bool listen();
|
||||||
@@ -73,9 +75,10 @@ public:
|
|||||||
int clientsCount() const {return clients_.size_s();}
|
int clientsCount() const {return clients_.size_s();}
|
||||||
PIVector<PIEthernet * > clients() {return clients_;}
|
PIVector<PIEthernet * > clients() {return clients_;}
|
||||||
|
|
||||||
bool send(const PIString & ip, int port, const void * data, int size) {ip_s = ip; port_s = port; return send(data, size);}
|
bool send(const PIString & ip, int port, const void * data, int size, bool threaded = false) {ip_s = ip; port_s = port; if (threaded) {writeThreaded(data, size); return true;} return send(data, size);}
|
||||||
bool send(const PIString & ip_port, const void * data, int size) {parseAddress(ip_port, &ip_s, &port_s); return send(data, size);}
|
bool send(const PIString & ip_port, const void * data, int size, bool threaded = false) {parseAddress(ip_port, &ip_s, &port_s); if (threaded) {writeThreaded(data, size); return true;} return send(data, size);}
|
||||||
bool send(const void * data, int size) {return (write(data, size) == size);}
|
bool send(const void * data, int size, bool threaded = false) {if (threaded) {writeThreaded(data, size); return true;} return (write(data, size) == size);}
|
||||||
|
bool send(const PIByteArray & ba, bool threaded = false) {if (threaded) {writeThreaded(ba); return true;} return (write(ba) == ba.size_s());}
|
||||||
|
|
||||||
int read(void * read_to, int max_size);
|
int read(void * read_to, int max_size);
|
||||||
int write(const void * data, int max_size);
|
int write(const void * data, int max_size);
|
||||||
@@ -84,6 +87,10 @@ public:
|
|||||||
static PIStringList interfaces();
|
static PIStringList interfaces();
|
||||||
static PIString interfaceAddress(const PIString & interface_);
|
static PIString interfaceAddress(const PIString & interface_);
|
||||||
static PIStringList allAddresses();
|
static PIStringList allAddresses();
|
||||||
|
|
||||||
|
EVENT1(newConnection, PIEthernet * , client)
|
||||||
|
EVENT0(connected)
|
||||||
|
EVENT1(disconnected, bool, withError)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PIEthernet(int sock, PIString ip_port);
|
PIEthernet(int sock, PIString ip_port);
|
||||||
@@ -106,6 +113,7 @@ protected:
|
|||||||
PIString ip_, ip_s, ip_c;
|
PIString ip_, ip_s, ip_c;
|
||||||
PIThread server_thread_;
|
PIThread server_thread_;
|
||||||
PIVector<PIEthernet * > clients_;
|
PIVector<PIEthernet * > clients_;
|
||||||
|
PIQueue<PIString> mcast_queue;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
PIMap<PIString, SOCKET> leafs;
|
PIMap<PIString, SOCKET> leafs;
|
||||||
#endif
|
#endif
|
||||||
@@ -115,7 +123,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
static void server_func(void * eth);
|
static void server_func(void * eth);
|
||||||
|
|
||||||
static std::string EthErrorString() {
|
static std::string ethErrorString() {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
char * msg;
|
char * msg;
|
||||||
int err = WSAGetLastError();
|
int err = WSAGetLastError();
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ namespace PIEvaluatorTypes {
|
|||||||
⋀ &
|
⋀ &
|
||||||
⋁ |
|
⋁ |
|
||||||
*/
|
*/
|
||||||
class PIEvaluatorContent
|
class PIP_EXPORT PIEvaluatorContent
|
||||||
{
|
{
|
||||||
friend class PIEvaluator;
|
friend class PIEvaluator;
|
||||||
public:
|
public:
|
||||||
@@ -108,7 +108,7 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PIEvaluator
|
class PIP_EXPORT PIEvaluator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PIEvaluator() {;}
|
PIEvaluator() {;}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ bool PIFile::openDevice() {
|
|||||||
|
|
||||||
|
|
||||||
bool PIFile::closeDevice() {
|
bool PIFile::closeDevice() {
|
||||||
if (!opened_) return true;
|
if (!opened_ || fd == 0) return true;
|
||||||
return (fclose(fd) == 0);
|
return (fclose(fd) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ void PIFile::resize(llong new_size, char fill_) {
|
|||||||
delete[] buff;
|
delete[] buff;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
piCout << "[PIFile] Downsize is not support yet :-(" << endl;
|
piCout << "[PIFile] Downsize is not support yet :-(";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
36
pifile.h
36
pifile.h
@@ -27,27 +27,29 @@
|
|||||||
/// void clear()
|
/// void clear()
|
||||||
/// void resize(llong new_size, char fill = 0)
|
/// void resize(llong new_size, char fill = 0)
|
||||||
/// void remove()
|
/// void remove()
|
||||||
class PIFile: public PIIODevice
|
class PIP_EXPORT PIFile: public PIIODevice
|
||||||
{
|
{
|
||||||
|
PIOBJECT(PIFile)
|
||||||
public:
|
public:
|
||||||
PIFile(const PIString & path = PIString(), DeviceMode type = ReadWrite): PIIODevice(path, type) {setPrecision(5); openDevice();}
|
PIFile(const PIString & path = PIString(), DeviceMode type = ReadWrite): PIIODevice(path, type) {setPrecision(5); openDevice();}
|
||||||
|
~PIFile() {close();}
|
||||||
|
|
||||||
//PIFile & operator =(const PIFile & f) {path_ = f.path_; type_ = f.type_; return *this;}
|
//PIFile & operator =(const PIFile & f) {path_ = f.path_; type_ = f.type_; return *this;}
|
||||||
|
|
||||||
void flush() {fflush(fd);}
|
void flush() {if (!opened_) fflush(fd);}
|
||||||
EVENT_HANDLER(PIFile, void, clear) {close(); fd = fopen(path_.data(), "w"); close(); open();}
|
EVENT_HANDLER(void, clear) {close(); fd = fopen(path_.data(), "w"); if (fd != 0) fclose(fd); fd = 0; opened_ = false; open();}
|
||||||
void seek(llong position) {if (!opened_) return; fseek(fd, position, SEEK_SET); clearerr(fd);}
|
void seek(llong position) {if (!opened_) return; fseek(fd, position, SEEK_SET); clearerr(fd);}
|
||||||
void seekToBegin() {if (!opened_) return; fseek(fd, 0, SEEK_SET); clearerr(fd);}
|
void seekToBegin() {if (!opened_) return; fseek(fd, 0, SEEK_SET); clearerr(fd);}
|
||||||
void seekToEnd() {if (!opened_) return; fseek(fd, 0, SEEK_END); clearerr(fd);}
|
void seekToEnd() {if (!opened_) return; fseek(fd, 0, SEEK_END); clearerr(fd);}
|
||||||
void seekToLine(llong line) {if (!opened_) return; seekToBegin(); piForTimes (line) readLine(); clearerr(fd);} // line 0 - begin of file
|
void seekToLine(llong line) {if (!opened_) return; seekToBegin(); piForTimes (line) readLine(); clearerr(fd);} // line 0 - begin of file
|
||||||
EVENT_HANDLER1(PIFile, void, resize, llong, new_size) {resize(new_size, 0);}
|
EVENT_HANDLER1(void, resize, llong, new_size) {resize(new_size, 0);}
|
||||||
EVENT_HANDLER2(PIFile, void, resize, llong, new_size, char, fill);
|
EVENT_HANDLER2(void, resize, llong, new_size, char, fill);
|
||||||
//void fill(char c) {stream.fill(c);}
|
//void fill(char c) {stream.fill(c);}
|
||||||
char readChar() {return (char)fgetc(fd);}
|
char readChar() {return (char)fgetc(fd);}
|
||||||
PIString readLine();
|
PIString readLine();
|
||||||
llong readAll(void * data);
|
llong readAll(void * data);
|
||||||
PIByteArray readAll(bool forceRead = false);
|
PIByteArray readAll(bool forceRead = false);
|
||||||
EVENT_HANDLER0(PIFile, void, remove) {close(); std::remove(path_.data());}
|
EVENT_HANDLER0(void, remove) {close(); std::remove(path_.data());}
|
||||||
|
|
||||||
void setPath(const PIString & path) {path_ = path; if (opened_) openDevice();}
|
void setPath(const PIString & path) {path_ = path; if (opened_) openDevice();}
|
||||||
llong size();
|
llong size();
|
||||||
@@ -56,11 +58,11 @@ public:
|
|||||||
bool isEmpty() {return (size() <= 0);}
|
bool isEmpty() {return (size() <= 0);}
|
||||||
|
|
||||||
int precision() const {return prec;}
|
int precision() const {return prec;}
|
||||||
void setPrecision(int prec_) {prec = prec_; prec_str = "." + itos(prec_);}
|
void setPrecision(int prec_) {prec = prec_; if (prec >= 0) prec_str = "." + itos(prec_); else prec_str = "";}
|
||||||
|
|
||||||
int read(void * read_to, int max_size) {if (!canRead()) return -1; return fread(read_to, max_size, 1, fd);}
|
int read(void * read_to, int max_size) {if (!canRead() || fd == 0) return -1; return fread(read_to, max_size, 1, fd);}
|
||||||
int write(const void * data, int max_size) {if (!canWrite()) return -1; return fwrite(data, max_size, 1, fd);}
|
int write(const void * data, int max_size) {if (!canWrite() || fd == 0) return -1; return fwrite(data, max_size, 1, fd);}
|
||||||
PIFile & writeToBinLog(ushort id, const void * data, int size) {if (!isWriteable()) return *this; writeBinary(id).writeBinary((ushort)size); write(data, size); flush(); return *this;}
|
PIFile & writeToBinLog(ushort id, const void * data, int size) {if (!isWriteable() || fd == 0) return *this; writeBinary(id).writeBinary((ushort)size); write(data, size); flush(); return *this;}
|
||||||
|
|
||||||
PIFile & writeBinary(const char v) {write(&v, sizeof(v)); return *this;}
|
PIFile & writeBinary(const char v) {write(&v, sizeof(v)); return *this;}
|
||||||
PIFile & writeBinary(const short v) {write(&v, sizeof(v)); return *this;}
|
PIFile & writeBinary(const short v) {write(&v, sizeof(v)); return *this;}
|
||||||
@@ -75,7 +77,9 @@ public:
|
|||||||
PIFile & writeBinary(const float v) {write(&v, sizeof(v)); return *this;}
|
PIFile & writeBinary(const float v) {write(&v, sizeof(v)); return *this;}
|
||||||
PIFile & writeBinary(const double v) {write(&v, sizeof(v)); return *this;}
|
PIFile & writeBinary(const double v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
PIFile & operator <<(const char & v) {if (!isWriteable()) return *this; write(&v, 1); return *this;}
|
PIFile & operator =(const PIFile & f) {path_ = f.path_; mode_ = f.mode_; return *this;}
|
||||||
|
|
||||||
|
PIFile & operator <<(const char v) {if (!isWriteable()) return *this; write(&v, 1); return *this;}
|
||||||
//PIFile & operator <<(const string & v) {write(v.c_str(), v.size()); return *this;}
|
//PIFile & operator <<(const string & v) {write(v.c_str(), v.size()); return *this;}
|
||||||
PIFile & operator <<(const PIString & v) {if (!isWriteable()) return *this; write(v.data(), v.lengthAscii()); return *this;}
|
PIFile & operator <<(const PIString & v) {if (!isWriteable()) return *this; write(v.data(), v.lengthAscii()); return *this;}
|
||||||
PIFile & operator <<(const PIByteArray & v) {if (!isWriteable()) return *this; write(v.data(), v.size()); return *this;}
|
PIFile & operator <<(const PIByteArray & v) {if (!isWriteable()) return *this; write(v.data(), v.size()); return *this;}
|
||||||
@@ -83,11 +87,11 @@ public:
|
|||||||
PIFile & operator <<(int v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%d", v); return *this;}
|
PIFile & operator <<(int v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%d", v); return *this;}
|
||||||
PIFile & operator <<(long v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%ld", v); return *this;}
|
PIFile & operator <<(long v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%ld", v); return *this;}
|
||||||
PIFile & operator <<(llong v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%lld", v); return *this;}
|
PIFile & operator <<(llong v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%lld", v); return *this;}
|
||||||
PIFile & operator <<(uchar v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%c", v); return *this;}
|
PIFile & operator <<(uchar v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%u", int(v)); return *this;}
|
||||||
PIFile & operator <<(ushort v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%hd", v); return *this;}
|
PIFile & operator <<(ushort v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%hu", v); return *this;}
|
||||||
PIFile & operator <<(uint v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%d", v); return *this;}
|
PIFile & operator <<(uint v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%u", v); return *this;}
|
||||||
PIFile & operator <<(ulong v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%ld", v); return *this;}
|
PIFile & operator <<(ulong v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%lu", v); return *this;}
|
||||||
PIFile & operator <<(ullong v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%lld", v); return *this;}
|
PIFile & operator <<(ullong v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%llu", v); return *this;}
|
||||||
PIFile & operator <<(float v) {if (!isWriteable()) return *this; ret = fprintf(fd, ("%" + prec_str + "f").c_str(), v); return *this;}
|
PIFile & operator <<(float v) {if (!isWriteable()) return *this; ret = fprintf(fd, ("%" + prec_str + "f").c_str(), v); return *this;}
|
||||||
PIFile & operator <<(double v) {if (!isWriteable()) return *this; ret = fprintf(fd, ("%" + prec_str + "lf").c_str(), v); return *this;}
|
PIFile & operator <<(double v) {if (!isWriteable()) return *this; ret = fprintf(fd, ("%" + prec_str + "lf").c_str(), v); return *this;}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "pimath.h"
|
#include "pimath.h"
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
class PIPoint {
|
class PIP_EXPORT PIPoint {
|
||||||
public:
|
public:
|
||||||
Type x;
|
Type x;
|
||||||
Type y;
|
Type y;
|
||||||
@@ -55,7 +55,7 @@ template<typename Type>
|
|||||||
std::ostream & operator <<(std::ostream & s, const PIPoint<Type> & v) {s << '{' << v.x << ", " << v.y << '}'; return s;}
|
std::ostream & operator <<(std::ostream & s, const PIPoint<Type> & v) {s << '{' << v.x << ", " << v.y << '}'; return s;}
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
class PIRect {
|
class PIP_EXPORT PIRect {
|
||||||
public:
|
public:
|
||||||
Type x0;
|
Type x0;
|
||||||
Type y0;
|
Type y0;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "piincludes.h"
|
#include "piincludes.h"
|
||||||
|
#include "pimutex.h"
|
||||||
|
|
||||||
bool isPIInit = false;
|
bool isPIInit = false;
|
||||||
bool piDebug = true;
|
bool piDebug = true;
|
||||||
@@ -29,3 +30,41 @@ lconv * currentLocale = std::localeconv();
|
|||||||
#ifdef MAC_OS
|
#ifdef MAC_OS
|
||||||
clock_serv_t __pi_mac_clock;
|
clock_serv_t __pi_mac_clock;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PIMutex __PICout_mutex__;
|
||||||
|
|
||||||
|
|
||||||
|
/*! \class PICout
|
||||||
|
* \brief Class for formatted output similar std::cout
|
||||||
|
*
|
||||||
|
* \section PICout_sec0 Synopsis
|
||||||
|
* This class provide many stream operators for output with some features.
|
||||||
|
* Output to PICout is thread-sequential, i.e. doesn`t mixed from parallel
|
||||||
|
* threads.
|
||||||
|
*
|
||||||
|
* \section PICout_sec1 Features
|
||||||
|
* - insertion spaces between entries
|
||||||
|
* - insertion new line at the end of output
|
||||||
|
* - strings are quoted
|
||||||
|
* - custom output operator can be easily written
|
||||||
|
*
|
||||||
|
* \section PICout_ex0 Example
|
||||||
|
* \snippet picout.cpp 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
PICout::PICout(PIFlags<PICoutControl> controls): fo_(true), cc_(false), co_(controls) {
|
||||||
|
__PICout_mutex__.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PICout::~PICout() {
|
||||||
|
if (cc_) return;
|
||||||
|
newLine();
|
||||||
|
__PICout_mutex__.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \mainpage Title
|
||||||
|
* This is main page
|
||||||
|
*/
|
||||||
|
|||||||
468
piincludes.h
468
piincludes.h
@@ -1,3 +1,9 @@
|
|||||||
|
/*! \file piincludes.h
|
||||||
|
* \brief Global includes of PIP
|
||||||
|
*
|
||||||
|
* This file include all needed STL and declare many useful
|
||||||
|
* macros and functions
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Global includes
|
Global includes
|
||||||
@@ -20,12 +26,58 @@
|
|||||||
#ifndef PIINCLUDES_H
|
#ifndef PIINCLUDES_H
|
||||||
#define PIINCLUDES_H
|
#define PIINCLUDES_H
|
||||||
|
|
||||||
#define PIP_VERSION 0x000300
|
//! Version of PIP in hex - 0x##(Major)##(Minor)##(Revision)
|
||||||
|
#define PIP_VERSION 0x000304
|
||||||
|
|
||||||
|
//! Major value of PIP version
|
||||||
#define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16
|
#define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16
|
||||||
|
|
||||||
|
//! Minor value of PIP version
|
||||||
#define PIP_VERSION_MINOR (PIP_VERSION & 0xFF00) >> 8
|
#define PIP_VERSION_MINOR (PIP_VERSION & 0xFF00) >> 8
|
||||||
|
|
||||||
|
//! Revision value of PIP version
|
||||||
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF
|
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF
|
||||||
|
|
||||||
|
//! Suffix of PIP version
|
||||||
#define PIP_VERSION_SUFFIX ""
|
#define PIP_VERSION_SUFFIX ""
|
||||||
|
|
||||||
|
#ifdef DOXYGEN
|
||||||
|
|
||||||
|
//! Macro is defined when compile-time debug is enabled
|
||||||
|
# define PIP_DEBUG
|
||||||
|
|
||||||
|
//! Macro is defined when host is any Windows
|
||||||
|
# define WINDOWS
|
||||||
|
|
||||||
|
//! Macro is defined when host is QNX
|
||||||
|
# define QNX
|
||||||
|
|
||||||
|
//! Macro is defined when host is FreeBSD
|
||||||
|
# define FREE_BSD
|
||||||
|
|
||||||
|
//! Macro is defined when host is Mac OS
|
||||||
|
# define MAC_OS
|
||||||
|
|
||||||
|
//! Macro is defined when host is any Linux
|
||||||
|
# define LINUX
|
||||||
|
|
||||||
|
//! Macro is defined when compiler is GCC or MinGW
|
||||||
|
# define CC_GCC
|
||||||
|
|
||||||
|
//! Macro is defined when PIP is decided that host is support language
|
||||||
|
# define HAS_LOCALE
|
||||||
|
|
||||||
|
//! Macro is defined when compiler is Visual Studio
|
||||||
|
# define CC_VC
|
||||||
|
|
||||||
|
//! Macro is defined when compiler is unknown
|
||||||
|
# define CC_OTHER
|
||||||
|
|
||||||
|
//! Macro is defined when PIP use "rt" library for timers implementation
|
||||||
|
# define PIP_TIMER_RT
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if WIN32 || WIN64 || _WIN32 || _WIN64 || __WIN32__ || __WIN64__
|
#if WIN32 || WIN64 || _WIN32 || _WIN64 || __WIN32__ || __WIN64__
|
||||||
# define WINDOWS
|
# define WINDOWS
|
||||||
#endif
|
#endif
|
||||||
@@ -60,6 +112,13 @@
|
|||||||
#else
|
#else
|
||||||
# define CC_OTHER
|
# define CC_OTHER
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef PIP_DEBUG
|
||||||
|
# undef NDEBUG
|
||||||
|
#else
|
||||||
|
# ifndef NDEBUG
|
||||||
|
# define NDEBUG
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
# ifdef CC_GCC
|
# ifdef CC_GCC
|
||||||
@@ -69,6 +128,11 @@
|
|||||||
# define typeof __typeof__
|
# define typeof __typeof__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "pip_export.h"
|
||||||
|
#if defined(DOXYGEN) || defined(CC_GCC)
|
||||||
|
# undef PIP_EXPORT
|
||||||
|
# define PIP_EXPORT
|
||||||
|
#endif
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#ifdef CC_GCC
|
#ifdef CC_GCC
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
@@ -90,6 +154,7 @@
|
|||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
|
#include <cassert>
|
||||||
//#include <signal.h>
|
//#include <signal.h>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -153,7 +218,10 @@ extern char ** environ;
|
|||||||
|
|
||||||
extern PIMonitor piMonitor;
|
extern PIMonitor piMonitor;
|
||||||
|
|
||||||
|
//! Macro used for infinite loop
|
||||||
#define FOREVER for (;;)
|
#define FOREVER for (;;)
|
||||||
|
|
||||||
|
//! Macro used for infinite wait
|
||||||
#define FOREVER_WAIT FOREVER msleep(1);
|
#define FOREVER_WAIT FOREVER msleep(1);
|
||||||
|
|
||||||
typedef long long llong;
|
typedef long long llong;
|
||||||
@@ -175,6 +243,7 @@ using std::deque;
|
|||||||
using std::stack;
|
using std::stack;
|
||||||
using std::set;
|
using std::set;
|
||||||
using std::map;
|
using std::map;
|
||||||
|
using std::multimap;
|
||||||
using std::string;
|
using std::string;
|
||||||
#ifndef QNX
|
#ifndef QNX
|
||||||
using std::wstring;
|
using std::wstring;
|
||||||
@@ -188,15 +257,118 @@ typedef std::basic_string<wchar_t> wstring;
|
|||||||
static locale_t currentLocale_t = 0;
|
static locale_t currentLocale_t = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*! \brief Templated function for swap two values
|
||||||
|
* \details Example:\n \snippet piincludes.cpp swap */
|
||||||
template<typename T> inline void piSwap(T & f, T & s) {T t = f; f = s; s = t;}
|
template<typename T> inline void piSwap(T & f, T & s) {T t = f; f = s; s = t;}
|
||||||
|
|
||||||
|
/*! \brief Templated function return round of float falue
|
||||||
|
* \details Round is the nearest integer value \n
|
||||||
|
* There is some macros:
|
||||||
|
* - \c piRoundf for "float"
|
||||||
|
* - \c piRoundd for "double"
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* \snippet piincludes.cpp round */
|
||||||
template<typename T> inline int piRound(const T & v) {return int(v >= T(0.) ? v + T(0.5) : v - T(0.5));}
|
template<typename T> inline int piRound(const T & v) {return int(v >= T(0.) ? v + T(0.5) : v - T(0.5));}
|
||||||
|
|
||||||
|
/*! \brief Templated function return floor of float falue
|
||||||
|
* \details Floor is the largest integer that is not greater than value \n
|
||||||
|
* There is some macros:
|
||||||
|
* - \c piFloorf for "float"
|
||||||
|
* - \c piFloord for "double"
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* \snippet piincludes.cpp floor */
|
||||||
template<typename T> inline int piFloor(const T & v) {return v < T(0) ? int(v) - 1 : int(v);}
|
template<typename T> inline int piFloor(const T & v) {return v < T(0) ? int(v) - 1 : int(v);}
|
||||||
|
|
||||||
|
/*! \brief Templated function return ceil of float falue
|
||||||
|
* \details Ceil is the smallest integer that is not less than value \n
|
||||||
|
* There is some macros:
|
||||||
|
* - \c piCeilf for "float"
|
||||||
|
* - \c piCeild for "double"
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* \snippet piincludes.cpp ceil */
|
||||||
template<typename T> inline int piCeil(const T & v) {return v < T(0) ? int(v) : int(v) + 1;}
|
template<typename T> inline int piCeil(const T & v) {return v < T(0) ? int(v) : int(v) + 1;}
|
||||||
|
|
||||||
|
/*! \brief Templated function return absolute of numeric falue
|
||||||
|
* \details Absolute is the positive or equal 0 value \n
|
||||||
|
* There is some macros:
|
||||||
|
* - \c piAbss for "short"
|
||||||
|
* - \c piAbsi for "int"
|
||||||
|
* - \c piAbsl for "long"
|
||||||
|
* - \c piAbsll for "llong"
|
||||||
|
* - \c piAbsf for "float"
|
||||||
|
* - \c piAbsd for "double"
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* \snippet piincludes.cpp abs */
|
||||||
template<typename T> inline T piAbs(const T & v) {return (v >= T(0) ? v : -v);}
|
template<typename T> inline T piAbs(const T & v) {return (v >= T(0) ? v : -v);}
|
||||||
|
|
||||||
|
/*! \brief Templated function return minimum of two values
|
||||||
|
* \details There is some macros:
|
||||||
|
* - \c piMins for "short"
|
||||||
|
* - \c piMini for "int"
|
||||||
|
* - \c piMinl for "long"
|
||||||
|
* - \c piMinll for "llong"
|
||||||
|
* - \c piMinf for "float"
|
||||||
|
* - \c piMind for "double"
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* \snippet piincludes.cpp min2 */
|
||||||
template<typename T> inline T piMin(const T & f, const T & s) {return (f > s) ? s : f;}
|
template<typename T> inline T piMin(const T & f, const T & s) {return (f > s) ? s : f;}
|
||||||
|
|
||||||
|
/*! \brief Templated function return minimum of tree values
|
||||||
|
* \details There is some macros:
|
||||||
|
* - \c piMins for "short"
|
||||||
|
* - \c piMini for "int"
|
||||||
|
* - \c piMinl for "long"
|
||||||
|
* - \c piMinll for "llong"
|
||||||
|
* - \c piMinf for "float"
|
||||||
|
* - \c piMind for "double"
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* \snippet piincludes.cpp min3 */
|
||||||
template<typename T> inline T piMin(const T & f, const T & s, const T & t) {return (f < s && f < t) ? f : ((s < t) ? s : t);}
|
template<typename T> inline T piMin(const T & f, const T & s, const T & t) {return (f < s && f < t) ? f : ((s < t) ? s : t);}
|
||||||
|
|
||||||
|
/*! \brief Templated function return maximum of two values
|
||||||
|
* \details There is some macros:
|
||||||
|
* - \c piMaxs for "short"
|
||||||
|
* - \c piMaxi for "int"
|
||||||
|
* - \c piMaxl for "long"
|
||||||
|
* - \c piMaxll for "llong"
|
||||||
|
* - \c piMaxf for "float"
|
||||||
|
* - \c piMaxd for "double"
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* \snippet piincludes.cpp max2 */
|
||||||
template<typename T> inline T piMax(const T & f, const T & s) {return (f < s) ? s : f;}
|
template<typename T> inline T piMax(const T & f, const T & s) {return (f < s) ? s : f;}
|
||||||
|
|
||||||
|
/*! \brief Templated function return maximum of tree values
|
||||||
|
* \details There is some macros:
|
||||||
|
* - \c piMaxs for "short"
|
||||||
|
* - \c piMaxi for "int"
|
||||||
|
* - \c piMaxl for "long"
|
||||||
|
* - \c piMaxll for "llong"
|
||||||
|
* - \c piMaxf for "float"
|
||||||
|
* - \c piMaxd for "double"
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* \snippet piincludes.cpp max3 */
|
||||||
template<typename T> inline T piMax(const T & f, const T & s, const T & t) {return (f > s && f > t) ? f : ((s > t) ? s : t);}
|
template<typename T> inline T piMax(const T & f, const T & s, const T & t) {return (f > s && f > t) ? f : ((s > t) ? s : t);}
|
||||||
|
|
||||||
|
/*! \brief Templated function return clamped value
|
||||||
|
* \details Clamped is the not greater than "max" and not lesser than "min" value \n
|
||||||
|
* There is some macros:
|
||||||
|
* - \c piClamps for "short"
|
||||||
|
* - \c piClampi for "int"
|
||||||
|
* - \c piClampl for "long"
|
||||||
|
* - \c piClampll for "llong"
|
||||||
|
* - \c piClampf for "float"
|
||||||
|
* - \c piClampd for "double"
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* \snippet piincludes.cpp clamp */
|
||||||
template<typename T> inline T piClamp(const T & v, const T & min, const T & max) {return (v > max ? max : (v < min ? min : v));}
|
template<typename T> inline T piClamp(const T & v, const T & min, const T & max) {return (v > max ? max : (v < min ? min : v));}
|
||||||
|
|
||||||
#define piRoundf piRound<float>
|
#define piRoundf piRound<float>
|
||||||
@@ -231,10 +403,11 @@ template<typename T> inline T piClamp(const T & v, const T & min, const T & max)
|
|||||||
#define piClampd piClamp<double>
|
#define piClampd piClamp<double>
|
||||||
|
|
||||||
extern bool isPIInit;
|
extern bool isPIInit;
|
||||||
extern bool piDebug;
|
|
||||||
extern string ifconfigPath;
|
|
||||||
|
|
||||||
#define piCout if (piDebug) cout
|
//! global variable enabling output to piCout
|
||||||
|
extern bool piDebug;
|
||||||
|
|
||||||
|
extern string ifconfigPath;
|
||||||
|
|
||||||
class PIInit {
|
class PIInit {
|
||||||
public:
|
public:
|
||||||
@@ -245,10 +418,8 @@ public:
|
|||||||
sigset_t ss;
|
sigset_t ss;
|
||||||
sigemptyset(&ss);
|
sigemptyset(&ss);
|
||||||
sigaddset(&ss, SIGALRM);
|
sigaddset(&ss, SIGALRM);
|
||||||
if (pthread_sigmask(SIG_BLOCK, &ss, 0) == -1) {
|
sigprocmask(SIG_BLOCK, &ss, 0);
|
||||||
//cout << "[PITimer] sigaction error: " << errorString() << endl;
|
pthread_sigmask(SIG_BLOCK, &ss, 0);
|
||||||
//return 0;
|
|
||||||
}
|
|
||||||
ifconfigPath = "/bin/ifconfig";
|
ifconfigPath = "/bin/ifconfig";
|
||||||
if (!fileExists(ifconfigPath)) {
|
if (!fileExists(ifconfigPath)) {
|
||||||
ifconfigPath = "/sbin/ifconfig";
|
ifconfigPath = "/sbin/ifconfig";
|
||||||
@@ -305,8 +476,8 @@ inline double round(const double & v) {return floor(v + 0.5);}
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline ushort letobe_s(ushort v) {return v = (v << 8) | (v >> 8);}
|
inline ushort letobe_s(ushort v) {return v = (v << 8) | (v >> 8);}
|
||||||
inline bool atob(const string & str) { return str == "1" ? true : false;};
|
inline bool atob(const string & str) {return str == "1" ? true : false;}
|
||||||
inline string btos(const bool num) { return num ? "0" : "1";};
|
inline string btos(const bool num) {return num ? "0" : "1";}
|
||||||
inline string itos(const int num) {
|
inline string itos(const int num) {
|
||||||
char ch[256];
|
char ch[256];
|
||||||
#ifndef CC_VC
|
#ifndef CC_VC
|
||||||
@@ -314,7 +485,7 @@ inline string itos(const int num) {
|
|||||||
#else
|
#else
|
||||||
sprintf_s(ch, 256, "%d", num);
|
sprintf_s(ch, 256, "%d", num);
|
||||||
#endif
|
#endif
|
||||||
return string(ch); };
|
return string(ch);}
|
||||||
inline string ltos(const long num) {
|
inline string ltos(const long num) {
|
||||||
char ch[256];
|
char ch[256];
|
||||||
#ifndef CC_VC
|
#ifndef CC_VC
|
||||||
@@ -322,23 +493,23 @@ inline string ltos(const long num) {
|
|||||||
#else
|
#else
|
||||||
sprintf_s(ch, 256, "%ld", num);
|
sprintf_s(ch, 256, "%ld", num);
|
||||||
#endif
|
#endif
|
||||||
return string(ch); };
|
return string(ch);}
|
||||||
inline string uitos(const uint num) {
|
inline string uitos(const uint num) {
|
||||||
char ch[256];
|
char ch[256];
|
||||||
#ifndef CC_VC
|
#ifndef CC_VC
|
||||||
sprintf(ch, "%ud", num);
|
sprintf(ch, "%u", num);
|
||||||
#else
|
#else
|
||||||
sprintf_s(ch, 256, "%ud", num);
|
sprintf_s(ch, 256, "%u", num);
|
||||||
#endif
|
#endif
|
||||||
return string(ch); };
|
return string(ch);}
|
||||||
inline string ultos(const ulong num) {
|
inline string ultos(const ulong num) {
|
||||||
char ch[256];
|
char ch[256];
|
||||||
#ifndef CC_VC
|
#ifndef CC_VC
|
||||||
sprintf(ch, "%lud", num);
|
sprintf(ch, "%lu", num);
|
||||||
#else
|
#else
|
||||||
sprintf_s(ch, 256, "%lud", num);
|
sprintf_s(ch, 256, "%lu", num);
|
||||||
#endif
|
#endif
|
||||||
return string(ch); };
|
return string(ch);}
|
||||||
inline string ftos(const float num) {
|
inline string ftos(const float num) {
|
||||||
char ch[256];
|
char ch[256];
|
||||||
#ifndef CC_VC
|
#ifndef CC_VC
|
||||||
@@ -346,7 +517,7 @@ inline string ftos(const float num) {
|
|||||||
#else
|
#else
|
||||||
sprintf_s(ch, 256, "%g", num);
|
sprintf_s(ch, 256, "%g", num);
|
||||||
#endif
|
#endif
|
||||||
return string(ch); };
|
return string(ch);}
|
||||||
inline string dtos(const double num) {
|
inline string dtos(const double num) {
|
||||||
char ch[256];
|
char ch[256];
|
||||||
#ifndef CC_VC
|
#ifndef CC_VC
|
||||||
@@ -354,9 +525,11 @@ inline string dtos(const double num) {
|
|||||||
#else
|
#else
|
||||||
sprintf_s(ch, 256, "%g", num);
|
sprintf_s(ch, 256, "%g", num);
|
||||||
#endif
|
#endif
|
||||||
return string(ch); };
|
return string(ch);}
|
||||||
|
|
||||||
#ifdef CC_VC
|
/*! \fn errorString()
|
||||||
|
* \brief Return readable error description in format "code <number> - <description>" */
|
||||||
|
#ifdef WINDOWS
|
||||||
inline string errorString() {
|
inline string errorString() {
|
||||||
char * msg;
|
char * msg;
|
||||||
int err = GetLastError();
|
int err = GetLastError();
|
||||||
@@ -368,6 +541,259 @@ inline void errorClear() {errno = 0;}
|
|||||||
inline string errorString() {int e = errno; return "code " + itos(e) + " - " + string(strerror(e));}
|
inline string errorString() {int e = errno; return "code " + itos(e) + " - " + string(strerror(e));}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// Return readable version of PIP
|
||||||
inline string PIPVersion() {return itos(PIP_VERSION_MAJOR) + "." + itos(PIP_VERSION_MINOR) + "." + itos(PIP_VERSION_REVISION) + PIP_VERSION_SUFFIX;}
|
inline string PIPVersion() {return itos(PIP_VERSION_MAJOR) + "." + itos(PIP_VERSION_MINOR) + "." + itos(PIP_VERSION_REVISION) + PIP_VERSION_SUFFIX;}
|
||||||
|
|
||||||
|
/*! \brief This class used as container for bit flags
|
||||||
|
* \details PIFlags is wrapper around \c "int". There are many
|
||||||
|
* bit-wise operators, native conversion to int and function
|
||||||
|
* to test flag. \n Example:
|
||||||
|
* \snippet piincludes.cpp flags
|
||||||
|
*/
|
||||||
|
template<typename Enum>
|
||||||
|
class PIP_EXPORT PIFlags {
|
||||||
|
public:
|
||||||
|
//! Constructor with flags = 0
|
||||||
|
PIFlags(): flags(0) {;}
|
||||||
|
//! Constructor with flags = Enum "e"
|
||||||
|
PIFlags(Enum e): flags(e) {;}
|
||||||
|
//! Constructor with flags = PIFlags "f"
|
||||||
|
PIFlags(const PIFlags & f): flags(f.flags) {;}
|
||||||
|
//! Constructor with flags = int "i"
|
||||||
|
PIFlags(const int i): flags(i) {;}
|
||||||
|
//! Set flags "f" to value "on"
|
||||||
|
PIFlags & setFlag(const PIFlags & f, bool on = true) {if (on) flags |= f.flags; else flags &= ~f.flags; return *this;}
|
||||||
|
//! Set flag "e" to value "on"
|
||||||
|
PIFlags & setFlag(const Enum & e, bool on = true) {if (on) flags |= e; else flags &= ~e; return *this;}
|
||||||
|
//! Set flag "i" to value "on"
|
||||||
|
PIFlags & setFlag(const int & i, bool on = true) {if (on) flags |= i; else flags &= ~i; return *this;}
|
||||||
|
//! copy operator
|
||||||
|
void operator =(const PIFlags & f) {flags = f.flags;}
|
||||||
|
//! copy operator
|
||||||
|
void operator =(const Enum & e) {flags = e;}
|
||||||
|
//! copy operator
|
||||||
|
void operator =(const int & i) {flags = i;}
|
||||||
|
//! compare operator
|
||||||
|
void operator ==(const PIFlags & f) {flags == f.flags;}
|
||||||
|
//! compare operator
|
||||||
|
void operator ==(const Enum & e) {flags == e;}
|
||||||
|
//! compare operator
|
||||||
|
void operator ==(const int i) {flags == i;}
|
||||||
|
//! compare operator
|
||||||
|
void operator !=(const PIFlags & f) {flags != f.flags;}
|
||||||
|
//! compare operator
|
||||||
|
void operator !=(const Enum & e) {flags != e;}
|
||||||
|
//! compare operator
|
||||||
|
void operator !=(const int i) {flags != i;}
|
||||||
|
//! compare operator
|
||||||
|
void operator >(const PIFlags & f) {flags > f.flags;}
|
||||||
|
//! compare operator
|
||||||
|
void operator >(const Enum & e) {flags > e;}
|
||||||
|
//! compare operator
|
||||||
|
void operator >(const int i) {flags > i;}
|
||||||
|
//! compare operator
|
||||||
|
void operator <(const PIFlags & f) {flags < f.flags;}
|
||||||
|
//! compare operator
|
||||||
|
void operator <(const Enum & e) {flags < e;}
|
||||||
|
//! compare operator
|
||||||
|
void operator <(const int i) {flags < i;}
|
||||||
|
//! compare operator
|
||||||
|
void operator >=(const PIFlags & f) {flags >= f.flags;}
|
||||||
|
//! compare operator
|
||||||
|
void operator >=(const Enum & e) {flags >= e;}
|
||||||
|
//! compare operator
|
||||||
|
void operator >=(const int i) {flags >= i;}
|
||||||
|
//! compare operator
|
||||||
|
void operator <=(const PIFlags & f) {flags <= f.flags;}
|
||||||
|
//! compare operator
|
||||||
|
void operator <=(const Enum & e) {flags <= e;}
|
||||||
|
//! compare operator
|
||||||
|
void operator <=(const int i) {flags <= i;}
|
||||||
|
//! Bit-wise AND operator
|
||||||
|
void operator &=(const PIFlags & f) {flags &= f.flags;}
|
||||||
|
//! Bit-wise AND operator
|
||||||
|
void operator &=(const Enum & e) {flags &= e;}
|
||||||
|
//! Bit-wise AND operator
|
||||||
|
void operator &=(const int i) {flags &= i;}
|
||||||
|
//! Bit-wise OR operator
|
||||||
|
void operator |=(const PIFlags & f) {flags |= f.flags;}
|
||||||
|
//! Bit-wise OR operator
|
||||||
|
void operator |=(const Enum & e) {flags |= e;}
|
||||||
|
//! Bit-wise OR operator
|
||||||
|
void operator |=(const int i) {flags |= i;}
|
||||||
|
//! Bit-wise XOR operator
|
||||||
|
void operator ^=(const PIFlags & f) {flags ^= f.flags;}
|
||||||
|
//! Bit-wise XOR operator
|
||||||
|
void operator ^=(const Enum & e) {flags ^= e;}
|
||||||
|
//! Bit-wise XOR operator
|
||||||
|
void operator ^=(const int i) {flags ^= i;}
|
||||||
|
//! Bit-wise AND operator
|
||||||
|
PIFlags operator &(PIFlags f) const {PIFlags tf(flags & f.flags); return tf;}
|
||||||
|
//! Bit-wise AND operator
|
||||||
|
PIFlags operator &(Enum e) const {PIFlags tf(flags & e); return tf;}
|
||||||
|
//! Bit-wise AND operator
|
||||||
|
PIFlags operator &(int i) const {PIFlags tf(flags & i); return tf;}
|
||||||
|
//! Bit-wise OR operator
|
||||||
|
PIFlags operator |(PIFlags f) const {PIFlags tf(flags | f.flags); return tf;}
|
||||||
|
//! Bit-wise OR operator
|
||||||
|
PIFlags operator |(Enum e) const {PIFlags tf(flags | e); return tf;}
|
||||||
|
//! Bit-wise OR operator
|
||||||
|
PIFlags operator |(int i) const {PIFlags tf(flags | i); return tf;}
|
||||||
|
//! Bit-wise XOR operator
|
||||||
|
PIFlags operator ^(PIFlags f) const {PIFlags tf(flags ^ f.flags); return tf;}
|
||||||
|
//! Bit-wise XOR operator
|
||||||
|
PIFlags operator ^(Enum e) const {PIFlags tf(flags ^ e); return tf;}
|
||||||
|
//! Bit-wise XOR operator
|
||||||
|
PIFlags operator ^(int i) const {PIFlags tf(flags ^ i); return tf;}
|
||||||
|
//! Test flag operator
|
||||||
|
bool operator [](Enum e) const {return (flags & e) == e;}
|
||||||
|
//! Implicity conversion to \c int
|
||||||
|
operator int() const {return flags;}
|
||||||
|
private:
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Macro used for conditional (piDebug) output to PICout
|
||||||
|
#define piCout if (piDebug) PICout()
|
||||||
|
|
||||||
|
class PIMutex;
|
||||||
|
extern PIMutex __PICout_mutex__;
|
||||||
|
|
||||||
|
//! \brief Namespace contains enums controlled PICout
|
||||||
|
namespace PICoutManipulators {
|
||||||
|
|
||||||
|
//! \brief Enum contains special characters
|
||||||
|
enum PIP_EXPORT PICoutSpecialChar {
|
||||||
|
Null /*! Null-character, '\\0' */,
|
||||||
|
NewLine /*! New line character, '\\n' */,
|
||||||
|
Tab /*! Tab character, '\\t' */,
|
||||||
|
Esc /*! Escape character, '\\e' */,
|
||||||
|
Quote /*! Quote character, '"' */
|
||||||
|
};
|
||||||
|
|
||||||
|
//! \brief Enum contains immediate action
|
||||||
|
enum PIP_EXPORT PICoutAction {
|
||||||
|
Flush /*! Flush the output */
|
||||||
|
};
|
||||||
|
|
||||||
|
//! \brief Enum contains control of PICout
|
||||||
|
enum PIP_EXPORT PICoutControl {
|
||||||
|
AddNone /*! No controls */ = 0x0,
|
||||||
|
AddSpaces /*! Spaces will be appear after each output */ = 0x1,
|
||||||
|
AddNewLine /*! New line will be appear after all output */ = 0x2,
|
||||||
|
AddQuotes /*! Each string will be quoted */ = 0x4,
|
||||||
|
AddAll /*! All controls */ = 0xFFFFFFFF
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
using namespace PICoutManipulators;
|
||||||
|
|
||||||
|
typedef PIFlags<PICoutControl> PICoutControls;
|
||||||
|
|
||||||
|
class PIP_EXPORT PICout {
|
||||||
|
public:
|
||||||
|
//! Default constructor with default features
|
||||||
|
PICout(PIFlags<PICoutControl> controls = AddSpaces | AddNewLine);
|
||||||
|
|
||||||
|
PICout(const PICout & other): fo_(other.fo_), cc_(true), co_(other.co_) {;}
|
||||||
|
~PICout();
|
||||||
|
|
||||||
|
//! Output operator for strings with <tt>"const char * "</tt> type
|
||||||
|
PICout operator <<(const char * v) {space(); quote(); std::cout << v; quote(); return *this;}
|
||||||
|
|
||||||
|
//! Output operator for strings with <tt>"std::string"</tt> type
|
||||||
|
PICout operator <<(const string & v) {space(); quote(); std::cout << v; quote(); return *this;}
|
||||||
|
|
||||||
|
//! Output operator for boolean values
|
||||||
|
PICout operator <<(const bool v) {space(); std::cout << v; return *this;}
|
||||||
|
|
||||||
|
//! Output operator for <tt>"char"</tt> values
|
||||||
|
PICout operator <<(const char v) {space(); std::cout << v; return *this;}
|
||||||
|
|
||||||
|
//! Output operator for <tt>"unsigned char"</tt> values
|
||||||
|
PICout operator <<(const uchar v) {space(); std::cout << ushort(v); return *this;}
|
||||||
|
|
||||||
|
//! Output operator for <tt>"short"</tt> values
|
||||||
|
PICout operator <<(const short v) {space(); std::cout << v; return *this;}
|
||||||
|
|
||||||
|
//! Output operator for <tt>"unsigned short"</tt> values
|
||||||
|
PICout operator <<(const ushort v) {space(); std::cout << v; return *this;}
|
||||||
|
|
||||||
|
//! Output operator for <tt>"int"</tt> values
|
||||||
|
PICout operator <<(const int v) {space(); std::cout << v; return *this;}
|
||||||
|
|
||||||
|
//! Output operator for <tt>"unsigned int"</tt> values
|
||||||
|
PICout operator <<(const uint v) {space(); std::cout << v; return *this;}
|
||||||
|
|
||||||
|
//! Output operator for <tt>"long"</tt> values
|
||||||
|
PICout operator <<(const long v) {space(); std::cout << v; return *this;}
|
||||||
|
|
||||||
|
//! Output operator for <tt>"unsigned long"</tt> values
|
||||||
|
PICout operator <<(const ulong v) {space(); std::cout << v; return *this;}
|
||||||
|
|
||||||
|
//! Output operator for <tt>"long long"</tt> values
|
||||||
|
PICout operator <<(const llong v) {space(); std::cout << v; return *this;}
|
||||||
|
|
||||||
|
//! Output operator for <tt>"unsigned long long"</tt> values
|
||||||
|
PICout operator <<(const ullong v) {space(); std::cout << v; return *this;}
|
||||||
|
|
||||||
|
//! Output operator for <tt>"float"</tt> values
|
||||||
|
PICout operator <<(const float v) {space(); std::cout << v; return *this;}
|
||||||
|
|
||||||
|
//! Output operator for <tt>"double"</tt> values
|
||||||
|
PICout operator <<(const double v) {space(); std::cout << v; return *this;}
|
||||||
|
|
||||||
|
//! Output operator for \a PICoutSpecialChar values
|
||||||
|
PICout operator <<(const PICoutSpecialChar v) {
|
||||||
|
switch (v) {
|
||||||
|
case Null: std::cout << char(0);
|
||||||
|
case NewLine: std::cout << '\n';
|
||||||
|
case Tab: std::cout << '\t';
|
||||||
|
case Esc: std::cout << '\e';
|
||||||
|
case Quote: std::cout << '"';
|
||||||
|
};
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Do some action
|
||||||
|
PICout operator <<(const PICoutAction v) {
|
||||||
|
switch (v) {
|
||||||
|
case Flush: std::cout << std::flush;
|
||||||
|
};
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Set control flag "c" is "on" state
|
||||||
|
void setControl(PICoutControl c, bool on = true) {co_.setFlag(c, on);}
|
||||||
|
|
||||||
|
//! Set control flags "c" and if "save" exec \a saveControl()
|
||||||
|
void setControl(PICoutControls c, bool save = false) {if (save) saveControl(); co_ = c;}
|
||||||
|
|
||||||
|
//! Save control flags to internal stack \sa \a restoreControl()
|
||||||
|
void saveControl() {cos_.push(co_);}
|
||||||
|
|
||||||
|
//! Restore control flags from internal stack \sa \a saveControl()
|
||||||
|
void restoreControl() {if (!cos_.empty()) {co_ = cos_.top(); cos_.pop();}}
|
||||||
|
|
||||||
|
/*! \brief Conditional put space character to output
|
||||||
|
* \details If it is not a first output and control \a AddSpaces is set
|
||||||
|
* space character is put \sa \a quote(), \a newLine() */
|
||||||
|
inline void space() {if (!fo_ && co_[AddSpaces]) std::cout << ' '; fo_ = false;}
|
||||||
|
|
||||||
|
/*! \brief Conditional put quote character to output
|
||||||
|
* \details If control \a AddQuotes is set
|
||||||
|
* quote character is put \sa \a space(), \a newLine() */
|
||||||
|
inline void quote() {if (co_[AddQuotes]) std::cout << '"'; fo_ = false;}
|
||||||
|
|
||||||
|
/*! \brief Conditional put new line character to output
|
||||||
|
* \details If control \a AddNewLine is set
|
||||||
|
* new line character is put \sa \a space(), \a quote() */
|
||||||
|
inline void newLine() {if (co_[AddNewLine]) std::cout << std::endl; fo_ = false;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool fo_, cc_;
|
||||||
|
PICoutControls co_;
|
||||||
|
std::stack<PICoutControls> cos_;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // PIINCLUDES_H
|
#endif // PIINCLUDES_H
|
||||||
|
|||||||
@@ -20,6 +20,45 @@
|
|||||||
#include "piiodevice.h"
|
#include "piiodevice.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*! \class PIIODevice
|
||||||
|
* \brief Base class for input/output classes
|
||||||
|
*
|
||||||
|
* \section PIIODevice_sec0 Synopsis
|
||||||
|
* This class provide open/close logic, threaded read and virtual input/output
|
||||||
|
* functions \a read() and \a write(). You should implement pure virtual
|
||||||
|
* function \a openDevice() in your subclass.
|
||||||
|
*
|
||||||
|
* \section PIIODevice_sec1 Open and close
|
||||||
|
* PIIODevice have boolean variable indicated open status. Returns of functions
|
||||||
|
* \a openDevice() and \a closeDevice() change this variable.
|
||||||
|
*
|
||||||
|
* \section PIIODevice_sec2 Threaded read
|
||||||
|
* PIIODevice based on PIThread, so it`s overload \a run() to exec \a read()
|
||||||
|
* in background thread. If read is successful virtual function \a threadedRead()
|
||||||
|
* is executed. Default implementation of this function execute external static
|
||||||
|
* function set by \a setThreadedReadSlot() with data set by \a setThreadedReadData().
|
||||||
|
* Extrenal static function should have format \n
|
||||||
|
* bool func_name(void * Threaded_read_data, uchar * readed_data, int readed_size)\n
|
||||||
|
* Threaded read starts with function \a startThreadedRead().
|
||||||
|
*
|
||||||
|
* \section PIIODevice_sec3 Internal buffer
|
||||||
|
* PIIODevice have internal buffer for threaded read, and \a threadedRead() function
|
||||||
|
* receive pointer to this buffer in first argument. You can adjust size of this buffer
|
||||||
|
* by function \a setThreadedReadBufferSize() \n
|
||||||
|
* Default size of this buffer is 4096 bytes
|
||||||
|
*
|
||||||
|
* \section PIIODevice_sec4 Reopen
|
||||||
|
* When threaded read is begin its call \a open() if device is closed. While threaded
|
||||||
|
* read running PIIODevice check if device opened every read and if not call \a open()
|
||||||
|
* every reopen timeout if reopen enabled. Reopen timeout is set by \a setReopenTimeout(),
|
||||||
|
* reopen enable is set by \a setReopenEnabled().
|
||||||
|
*
|
||||||
|
* \section PIIODevice_ex0 Example
|
||||||
|
* \snippet piiodevice.cpp 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//! Constructs a empty PIIODevice
|
||||||
PIIODevice::PIIODevice(): PIThread() {
|
PIIODevice::PIIODevice(): PIThread() {
|
||||||
mode_ = ReadOnly;
|
mode_ = ReadOnly;
|
||||||
opened_ = init_ = thread_started_ = false;
|
opened_ = init_ = thread_started_ = false;
|
||||||
@@ -27,12 +66,18 @@ PIIODevice::PIIODevice(): PIThread() {
|
|||||||
reopen_timeout_ = 1000;
|
reopen_timeout_ = 1000;
|
||||||
ret_func_ = 0;
|
ret_func_ = 0;
|
||||||
ret_data_ = 0;
|
ret_data_ = 0;
|
||||||
|
tri = 0;
|
||||||
buffer_tr.resize(4096);
|
buffer_tr.resize(4096);
|
||||||
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
|
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
|
||||||
|
CONNECT(void, &write_thread, started, this, write_func);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Constructs a PIIODevice with path and mode
|
||||||
|
* \param path path to device
|
||||||
|
* \param type mode for open
|
||||||
|
* \param initNow init or not in constructor */
|
||||||
PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode type, bool initNow): PIThread() {
|
PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode type, bool initNow): PIThread() {
|
||||||
path_ = path;
|
path_ = path;
|
||||||
mode_ = type;
|
mode_ = type;
|
||||||
@@ -41,8 +86,10 @@ PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode type, bool
|
|||||||
reopen_timeout_ = 1000;
|
reopen_timeout_ = 1000;
|
||||||
ret_func_ = 0;
|
ret_func_ = 0;
|
||||||
ret_data_ = 0;
|
ret_data_ = 0;
|
||||||
|
tri = 0;
|
||||||
buffer_tr.resize(4096);
|
buffer_tr.resize(4096);
|
||||||
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
|
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
|
||||||
|
CONNECT(void, &write_thread, started, this, write_func);
|
||||||
if (initNow) init();
|
if (initNow) init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +103,21 @@ void PIIODevice::check_start(void * data, int delim) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIIODevice::write_func() {
|
||||||
|
while (!write_thread.isStopping()) {
|
||||||
|
while (!write_queue.isEmpty()) {
|
||||||
|
if (write_thread.isStopping()) return;
|
||||||
|
write_thread.lock();
|
||||||
|
PIPair<PIByteArray, ullong> item(write_queue.dequeue());
|
||||||
|
write_thread.unlock();
|
||||||
|
int ret = write(item.first);
|
||||||
|
threadedWriteEvent(item.second, ret);
|
||||||
|
}
|
||||||
|
msleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIIODevice::terminate() {
|
void PIIODevice::terminate() {
|
||||||
thread_started_ = false;
|
thread_started_ = false;
|
||||||
if (!isInitialized()) return;
|
if (!isInitialized()) return;
|
||||||
@@ -103,4 +165,14 @@ void PIIODevice::run() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
threadedRead(buffer_tr.data(), readed_);
|
threadedRead(buffer_tr.data(), readed_);
|
||||||
|
threadedReadEvent(buffer_tr.data(), readed_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ullong PIIODevice::writeThreaded(const PIByteArray & data) {
|
||||||
|
write_thread.lock();
|
||||||
|
write_queue.enqueue(PIPair<PIByteArray, ullong>(data, tri));
|
||||||
|
++tri;
|
||||||
|
write_thread.unlock();
|
||||||
|
return tri - 1;
|
||||||
}
|
}
|
||||||
|
|||||||
143
piiodevice.h
143
piiodevice.h
@@ -1,3 +1,6 @@
|
|||||||
|
/*! \file piiodevice.h
|
||||||
|
* \brief Abstract input/output device
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Abstract input/output device
|
Abstract input/output device
|
||||||
@@ -25,36 +28,59 @@
|
|||||||
// function executed from threaded read, pass ThreadedReadData, readedData, sizeOfData
|
// function executed from threaded read, pass ThreadedReadData, readedData, sizeOfData
|
||||||
typedef bool (*ReadRetFunc)(void * , uchar * , int );
|
typedef bool (*ReadRetFunc)(void * , uchar * , int );
|
||||||
|
|
||||||
/// events:
|
// events:
|
||||||
/// void opened()
|
// void opened()
|
||||||
/// void closed()
|
// void closed()
|
||||||
///
|
//
|
||||||
/// handlers:
|
// handlers:
|
||||||
/// bool open()
|
// bool open()
|
||||||
/// bool open(const PIString & path)
|
// bool open(const PIString & path)
|
||||||
/// bool open(const DeviceMode & type)
|
// bool open(const DeviceMode & type)
|
||||||
/// bool open(const PIString & path, const DeviceMode & type)
|
// bool open(const PIString & path, const DeviceMode & type)
|
||||||
/// bool close()
|
// bool close()
|
||||||
/// bool initialize()
|
// bool initialize()
|
||||||
/// void flush()
|
// void flush()
|
||||||
class PIIODevice: public PIThread {
|
|
||||||
|
class PIP_EXPORT PIIODevice: public PIThread
|
||||||
|
{
|
||||||
|
PIOBJECT(PIIODevice)
|
||||||
public:
|
public:
|
||||||
PIIODevice();
|
PIIODevice();
|
||||||
|
|
||||||
enum DeviceMode {ReadOnly = 0x01, WriteOnly = 0x02, ReadWrite = 0x03};
|
//! \brief Open modes for PIIODevice
|
||||||
|
enum DeviceMode {
|
||||||
|
ReadOnly /*! Device can only read */ = 0x01,
|
||||||
|
WriteOnly /*! Device can only write */ = 0x02,
|
||||||
|
ReadWrite /*! Device can both read and write */ = 0x03
|
||||||
|
};
|
||||||
|
|
||||||
PIIODevice(const PIString & path, DeviceMode type = ReadWrite, bool initNow = true);
|
PIIODevice(const PIString & path, DeviceMode type = ReadWrite, bool initNow = true);
|
||||||
virtual ~PIIODevice() {if (opened_) {closeDevice(); if (!opened_) closed();}}
|
virtual ~PIIODevice() {stop(); write_thread.stop(); if (opened_) {closeDevice(); if (!opened_) closed();}}
|
||||||
|
|
||||||
|
|
||||||
|
//! Current open mode of device
|
||||||
DeviceMode mode() const {return mode_;}
|
DeviceMode mode() const {return mode_;}
|
||||||
|
|
||||||
|
//! Current path of device
|
||||||
PIString path() const {return path_;}
|
PIString path() const {return path_;}
|
||||||
|
|
||||||
|
//! return \b true if mode is ReadOnly or ReadWrite
|
||||||
bool isReadable() const {return (mode_ & ReadOnly);}
|
bool isReadable() const {return (mode_ & ReadOnly);}
|
||||||
|
|
||||||
|
//! return \b true if mode is WriteOnly or ReadWrite
|
||||||
bool isWriteable() const {return (mode_ & WriteOnly);}
|
bool isWriteable() const {return (mode_ & WriteOnly);}
|
||||||
|
|
||||||
bool isInitialized() const {return init_;}
|
bool isInitialized() const {return init_;}
|
||||||
|
|
||||||
|
//! return \b true if device is successfully opened
|
||||||
bool isOpened() const {return opened_;}
|
bool isOpened() const {return opened_;}
|
||||||
|
|
||||||
|
//! return \b true if device is closed
|
||||||
bool isClosed() const {return !opened_;}
|
bool isClosed() const {return !opened_;}
|
||||||
|
|
||||||
|
//! return \b true if device can read \b now
|
||||||
bool canRead() const {return opened_ && (mode_ & ReadOnly);}
|
bool canRead() const {return opened_ && (mode_ & ReadOnly);}
|
||||||
|
|
||||||
|
//! return \b true if device can write \b now
|
||||||
bool canWrite() const {return opened_ && (mode_ & WriteOnly);}
|
bool canWrite() const {return opened_ && (mode_ & WriteOnly);}
|
||||||
|
|
||||||
|
|
||||||
@@ -74,34 +100,83 @@ public:
|
|||||||
int threadedReadBufferSize() const {return buffer_tr.size_s();}
|
int threadedReadBufferSize() const {return buffer_tr.size_s();}
|
||||||
const uchar * threadedReadBuffer() const {return buffer_tr.data();}
|
const uchar * threadedReadBuffer() const {return buffer_tr.data();}
|
||||||
|
|
||||||
|
bool isThreadedRead() const {return isRunning();}
|
||||||
void startThreadedRead() {if (!isRunning()) start();}
|
void startThreadedRead() {if (!isRunning()) start();}
|
||||||
void startThreadedRead(ReadRetFunc func) {ret_func_ = func; if (!isRunning()) start();}
|
void startThreadedRead(ReadRetFunc func) {ret_func_ = func; if (!isRunning()) start();}
|
||||||
|
|
||||||
|
|
||||||
EVENT_HANDLER(PIIODevice, bool, open) {if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
bool isThreadedWrite() const {return write_thread.isRunning();}
|
||||||
EVENT_HANDLER1(PIIODevice, bool, open, const PIString &, _path) {path_ = _path; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
void startThreadedWrite() {if (!write_thread.isRunning()) write_thread.startOnce();}
|
||||||
EVENT_HANDLER1(PIIODevice, bool, open, const DeviceMode &, _type) {mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
void stopThreadedWrite() {write_thread.stop();}
|
||||||
EVENT_HANDLER2(PIIODevice, bool, open, const PIString &, _path, const DeviceMode &, _type) {path_ = _path; mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
void clearThreadedWriteQueue() {write_thread.lock(); write_queue.clear(); write_thread.unlock();}
|
||||||
EVENT_HANDLER(PIIODevice, bool, close) {opened_ = !closeDevice(); if (!opened_) closed(); return !opened_;}
|
|
||||||
EVENT_HANDLER(PIIODevice, bool, initialize) {init_ = init(); return init_;}
|
|
||||||
|
|
||||||
// Flush device
|
|
||||||
EVENT_VHANDLER(PIIODevice, void, flush) {;}
|
|
||||||
|
|
||||||
EVENT(PIIODevice, opened)
|
|
||||||
EVENT(PIIODevice, closed)
|
|
||||||
|
|
||||||
|
|
||||||
// Read from device to "read_to" maximum "max_size" bytes, return readed bytes count
|
// Read from device to "read_to" maximum "max_size" bytes, return readed bytes count
|
||||||
virtual int read(void * read_to, int max_size) {piCout << "[PIIODevice] \"read\" not implemented!" << endl; return -2;}
|
virtual int read(void * read_to, int max_size) {piCout << "[PIIODevice] \"read\" not implemented!"; return -2;}
|
||||||
|
|
||||||
// Write to device "data" maximum "max_size" bytes, return written bytes count
|
// Write to device "data" maximum "max_size" bytes, return written bytes count
|
||||||
virtual int write(const void * data, int max_size) {piCout << "[PIIODevice] \"write\" not implemented!" << endl; return -2;}
|
virtual int write(const void * data, int max_size) {piCout << "[PIIODevice] \"write\" not implemented!"; return -2;}
|
||||||
|
|
||||||
// Read from device maximum "max_size" bytes and return them as PIByteArray
|
// Read from device maximum "max_size" bytes and return them as PIByteArray
|
||||||
PIByteArray read(int max_size) {buffer_in.resize(max_size); int ret = read(buffer_in.data(), max_size); if (ret < 0) return PIByteArray(); return buffer_in.resized(ret);}
|
PIByteArray read(int max_size) {buffer_in.resize(max_size); int ret = read(buffer_in.data(), max_size); if (ret < 0) return PIByteArray(); return buffer_in.resized(ret);}
|
||||||
int write(const PIByteArray & data) {return write(data.data(), data.size_s());}
|
int write(const PIByteArray & data) {return write(data.data(), data.size_s());}
|
||||||
|
|
||||||
|
ullong writeThreaded(const void * data, int max_size) {return writeThreaded(PIByteArray(data, uint(max_size)));}
|
||||||
|
ullong writeThreaded(const PIByteArray & data);
|
||||||
|
|
||||||
|
EVENT_HANDLER(bool, open) {if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
||||||
|
EVENT_HANDLER1(bool, open, const PIString &, _path) {path_ = _path; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
||||||
|
EVENT_HANDLER1(bool, open, const DeviceMode &, _type) {mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
||||||
|
EVENT_HANDLER2(bool, open, const PIString &, _path, const DeviceMode &, _type) {path_ = _path; mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
||||||
|
EVENT_HANDLER(bool, close) {opened_ = !closeDevice(); if (!opened_) closed(); return !opened_;}
|
||||||
|
EVENT_HANDLER(bool, initialize) {init_ = init(); return init_;}
|
||||||
|
|
||||||
|
EVENT_VHANDLER(void, flush) {;}
|
||||||
|
|
||||||
|
EVENT(opened)
|
||||||
|
EVENT(closed)
|
||||||
|
EVENT2(threadedReadEvent, uchar * , readed, int, size)
|
||||||
|
EVENT2(threadedWriteEvent, ullong, id, int, written_size)
|
||||||
|
|
||||||
|
//! \handlers
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! \fn bool open()
|
||||||
|
//! \brief Open device
|
||||||
|
|
||||||
|
//! \fn bool open(const PIString & path)
|
||||||
|
//! \brief Open device with path "path"
|
||||||
|
|
||||||
|
//! \fn bool open(const DeviceMode & mode)
|
||||||
|
//! \brief Open device with mode "mode"
|
||||||
|
|
||||||
|
//! \fn bool open(const PIString & path, const DeviceMode & mode)
|
||||||
|
//! \brief Open device with path "path" and mode "mode"
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
//! \vhandlers
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! \fn void flush()
|
||||||
|
//! \brief Immediate write all buffers
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
//! \events
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! \fn void opened()
|
||||||
|
//! \brief Raise if succesfull open
|
||||||
|
|
||||||
|
//! \fn void closed()
|
||||||
|
//! \brief Raise if succesfull close
|
||||||
|
|
||||||
|
//! \fn void threadedReadEvent(uchar * readed, int size)
|
||||||
|
//! \brief Raise if read thread succesfull read some data
|
||||||
|
|
||||||
|
//! \fn void threadedWriteEvent(ullong id, int written_size)
|
||||||
|
//! \brief Raise if write thread succesfull write some data of queue item with id "id"
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Function executed before first openDevice() or from constructor
|
// Function executed before first openDevice() or from constructor
|
||||||
@@ -124,14 +199,18 @@ protected:
|
|||||||
void * ret_data_;
|
void * ret_data_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EVENT_HANDLER2(PIIODevice, void, check_start, void * , data, int, delim);
|
EVENT_HANDLER2(void, check_start, void * , data, int, delim);
|
||||||
|
EVENT_HANDLER(void, write_func);
|
||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
void run();
|
void run();
|
||||||
void end() {terminate();}
|
void end() {terminate();}
|
||||||
|
|
||||||
PITimer timer;
|
PITimer timer;
|
||||||
|
PIThread write_thread;
|
||||||
PIByteArray buffer_in, buffer_tr;
|
PIByteArray buffer_in, buffer_tr;
|
||||||
|
PIQueue<PIPair<PIByteArray, ullong> > write_queue;
|
||||||
|
ullong tri;
|
||||||
int readed_;
|
int readed_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() {
|
|||||||
void PIKbdListener::begin() {
|
void PIKbdListener::begin() {
|
||||||
//cout << "list begin" << endl;
|
//cout << "list begin" << endl;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
SetConsoleMode(hIn, ENABLE_PROCESSED_INPUT);
|
|
||||||
GetConsoleMode(hIn, &tmode);
|
GetConsoleMode(hIn, &tmode);
|
||||||
|
SetConsoleMode(hIn, ENABLE_PROCESSED_INPUT);
|
||||||
#else
|
#else
|
||||||
struct termios term;
|
struct termios term;
|
||||||
tcgetattr(0, &term);
|
tcgetattr(0, &term);
|
||||||
@@ -55,17 +55,68 @@ void PIKbdListener::begin() {
|
|||||||
|
|
||||||
|
|
||||||
void PIKbdListener::run() {
|
void PIKbdListener::run() {
|
||||||
|
rc = 0;
|
||||||
|
char lc = 0;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
ReadConsole(hIn, &rc, 1, &ret, 0);
|
INPUT_RECORD ir;
|
||||||
|
ReadConsoleInput(hIn, &ir, 1, &ret);
|
||||||
|
if (ir.EventType == KEY_EVENT) {
|
||||||
|
KEY_EVENT_RECORD ker = ir.Event.KeyEvent;
|
||||||
|
if (ker.bKeyDown) {
|
||||||
|
bool ctrl = ((ker.dwControlKeyState & LEFT_CTRL_PRESSED) || (ker.dwControlKeyState & RIGHT_CTRL_PRESSED));
|
||||||
|
//cout << "key " << int(ker.wVirtualKeyCode) << endl;
|
||||||
|
switch (ker.wVirtualKeyCode) {
|
||||||
|
case 37: ret = 1; lc = (ctrl ? CtrlLeftArrow : LeftArrow); break;
|
||||||
|
case 38: ret = 1; lc = (ctrl ? CtrlUpArrow : UpArrow); break;
|
||||||
|
case 39: ret = 1; lc = (ctrl ? CtrlRightArrow : RightArrow); break;
|
||||||
|
case 40: ret = 1; lc = (ctrl ? CtrlDownArrow : DownArrow); break;
|
||||||
|
default: ret = 1; lc = ker.uChar.AsciiChar; break;
|
||||||
|
}
|
||||||
|
if (lc == 0) return;
|
||||||
|
} else return;
|
||||||
|
} else return;
|
||||||
|
/*if (lc == 0) {
|
||||||
|
ReadConsole(hIn, &rc, 1, &ret, 0);
|
||||||
|
//cout << "read console" << endl;
|
||||||
|
lc = char(rc);
|
||||||
|
}*/
|
||||||
|
/*if (ret < 0 || ret > 3) return;
|
||||||
|
lc = char(((uchar * )&rc)[ret - 1]);
|
||||||
|
for (int i = 0; i < ret; ++i)
|
||||||
|
cout << std::hex << int(((uchar * )&rc)[i]) << ' ';
|
||||||
|
cout << endl << std::hex << rc << endl;*/
|
||||||
#else
|
#else
|
||||||
ret = read(0, &rc, 1);
|
ret = read(0, &rc, 4);
|
||||||
|
if (ret < 0 || ret > 3) return;
|
||||||
|
lc = char(((uchar * )&rc)[ret - 1]);
|
||||||
|
//for (int i = 0; i < ret; ++i)
|
||||||
|
// cout << std::hex << int(((uchar * )&rc)[i]) << ' ';
|
||||||
|
//cout << endl << std::hex << rc << endl;
|
||||||
|
if (((char * )&rc)[0] == '\e' && ret == 3) {
|
||||||
|
if (((char * )&rc)[1] == '[') {
|
||||||
|
switch (((char * )&rc)[2]) {
|
||||||
|
case 'A': lc = UpArrow; break; // up
|
||||||
|
case 'B': lc = DownArrow; break; // down
|
||||||
|
case 'C': lc = RightArrow; break; // right
|
||||||
|
case 'D': lc = LeftArrow; break; // left
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (((char * )&rc)[0] == '5' && ret == 2) {
|
||||||
|
switch (((char * )&rc)[1]) {
|
||||||
|
case 'A': lc = CtrlUpArrow; break; // up
|
||||||
|
case 'B': lc = CtrlDownArrow; break; // down
|
||||||
|
case 'C': lc = CtrlRightArrow; break; // right
|
||||||
|
case 'D': lc = CtrlLeftArrow; break; // left
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (exit_enabled && rc == exit_key) {
|
if (exit_enabled && ret == 1 && lc == exit_key) {
|
||||||
PIKbdListener::exiting = true;
|
PIKbdListener::exiting = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
keyPressed(rc, data);
|
keyPressed(lc, data);
|
||||||
if (ret_func != 0 && ret > 0) ret_func(rc, data);
|
if (ret_func != 0 && ret > 0) ret_func(lc, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,25 +35,38 @@ typedef void (*KBFunc)(char, void * );
|
|||||||
/// handlers:
|
/// handlers:
|
||||||
/// void enableExitCapture(char key = 'Q')
|
/// void enableExitCapture(char key = 'Q')
|
||||||
/// void setActive(bool yes = true)
|
/// void setActive(bool yes = true)
|
||||||
class PIKbdListener: public PIThread {
|
class PIP_EXPORT PIKbdListener: public PIThread
|
||||||
|
{
|
||||||
|
PIOBJECT(PIKbdListener)
|
||||||
friend class PIConsole;
|
friend class PIConsole;
|
||||||
public:
|
public:
|
||||||
|
enum SpecialSymbol {
|
||||||
|
UpArrow = -1,
|
||||||
|
DownArrow = -2,
|
||||||
|
RightArrow = -3,
|
||||||
|
LeftArrow = -4,
|
||||||
|
CtrlUpArrow = -5,
|
||||||
|
CtrlDownArrow = -6,
|
||||||
|
CtrlRightArrow = -7,
|
||||||
|
CtrlLeftArrow = -8
|
||||||
|
};
|
||||||
|
|
||||||
// slot is any function format "void <func>(char, void * )"
|
// slot is any function format "void <func>(char, void * )"
|
||||||
PIKbdListener(KBFunc slot = 0, void * data = 0);
|
PIKbdListener(KBFunc slot = 0, void * data = 0);
|
||||||
~PIKbdListener() {terminate(); end();}
|
~PIKbdListener() {terminate(); end();}
|
||||||
|
|
||||||
void setData(void * data_) {data = data_;}
|
void setData(void * data_) {data = data_;}
|
||||||
void setSlot(KBFunc slot_) {ret_func = slot_;}
|
void setSlot(KBFunc slot_) {ret_func = slot_;}
|
||||||
EVENT_HANDLER(PIKbdListener, void, enableExitCapture) {enableExitCapture('Q');}
|
EVENT_HANDLER( void, enableExitCapture) {enableExitCapture('Q');}
|
||||||
EVENT_HANDLER1(PIKbdListener, void, enableExitCapture, char, key) {exit_enabled = true; exit_key = key;}
|
EVENT_HANDLER1(void, enableExitCapture, char, key) {exit_enabled = true; exit_key = key;}
|
||||||
void disableExitCapture() {exit_enabled = false;}
|
void disableExitCapture() {exit_enabled = false;}
|
||||||
bool exitCaptured() const {return exit_enabled;}
|
bool exitCaptured() const {return exit_enabled;}
|
||||||
char exitKey() const {return exit_key;}
|
char exitKey() const {return exit_key;}
|
||||||
bool isActive() {return is_active;}
|
bool isActive() {return is_active;}
|
||||||
EVENT_HANDLER(PIKbdListener, void, setActive) {setActive(true);}
|
EVENT_HANDLER(void, setActive) {setActive(true);}
|
||||||
EVENT_HANDLER1(PIKbdListener, void, setActive, bool, yes);
|
EVENT_HANDLER1(void, setActive, bool, yes);
|
||||||
|
|
||||||
EVENT2(PIKbdListener, keyPressed, char, key, void * , data)
|
EVENT2(keyPressed, char, key, void * , data)
|
||||||
|
|
||||||
static bool exiting;
|
static bool exiting;
|
||||||
|
|
||||||
@@ -61,6 +74,8 @@ private:
|
|||||||
void begin();
|
void begin();
|
||||||
void run();
|
void run();
|
||||||
void end();
|
void end();
|
||||||
|
|
||||||
|
void raiseSpecial();
|
||||||
|
|
||||||
KBFunc ret_func;
|
KBFunc ret_func;
|
||||||
char exit_key;
|
char exit_key;
|
||||||
@@ -71,7 +86,7 @@ private:
|
|||||||
void * hIn;
|
void * hIn;
|
||||||
DWORD smode, tmode;
|
DWORD smode, tmode;
|
||||||
#else
|
#else
|
||||||
char rc;
|
int rc;
|
||||||
int ret;
|
int ret;
|
||||||
struct termios sterm, tterm;
|
struct termios sterm, tterm;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
28
pimath.h
28
pimath.h
@@ -96,16 +96,18 @@ inline double fromDb(double val) {return pow(10., val / 10.);}
|
|||||||
inline double toRad(double deg) {return deg * M_PI_180;}
|
inline double toRad(double deg) {return deg * M_PI_180;}
|
||||||
inline double toDeg(double rad) {return rad * M_180_PI;}
|
inline double toDeg(double rad) {return rad * M_180_PI;}
|
||||||
|
|
||||||
inline PIVector<double> abs(const PIVector<complexd> &v) {
|
inline PIVector<double> abs(const PIVector<complexd> & v) {
|
||||||
PIVector<double> result;
|
PIVector<double> result;
|
||||||
result.resize(v.size());
|
result.resize(v.size());
|
||||||
for(uint i=0; i<v.size(); i++) result[i] = abs(v.at(i));
|
for (uint i = 0; i < v.size(); i++)
|
||||||
|
result[i] = abs(v[i]);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
inline PIVector<double> abs(const PIVector<double> &v) {
|
inline PIVector<double> abs(const PIVector<double> & v) {
|
||||||
PIVector<double> result;
|
PIVector<double> result;
|
||||||
result.resize(v.size());
|
result.resize(v.size());
|
||||||
for(uint i=0; i<v.size(); i++) result[i] = abs(v.at(i));
|
for (uint i = 0; i < v.size(); i++)
|
||||||
|
result[i] = abs(v[i]);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +119,7 @@ class PIMathMatrixT;
|
|||||||
#define PIMV_FOR(v, s) for (uint v = s; v < Size; ++v)
|
#define PIMV_FOR(v, s) for (uint v = s; v < Size; ++v)
|
||||||
|
|
||||||
template<uint Size, typename Type = double>
|
template<uint Size, typename Type = double>
|
||||||
class PIMathVectorT {
|
class PIP_EXPORT PIMathVectorT {
|
||||||
typedef PIMathVectorT<Size, Type> _CVector;
|
typedef PIMathVectorT<Size, Type> _CVector;
|
||||||
public:
|
public:
|
||||||
PIMathVectorT() {resize(Size);}
|
PIMathVectorT() {resize(Size);}
|
||||||
@@ -139,7 +141,7 @@ public:
|
|||||||
Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);}
|
Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);}
|
||||||
Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);}
|
Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);}
|
||||||
Type angleRad(const _CVector & v) const {return acos(angleCos(v));}
|
Type angleRad(const _CVector & v) const {return acos(angleCos(v));}
|
||||||
Type angleDeg(const _CVector & v) const {return toGrad(acos(angleCos(v)));}
|
Type angleDeg(const _CVector & v) const {return toDeg(acos(angleCos(v)));}
|
||||||
_CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));}
|
_CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));}
|
||||||
_CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; PIMV_FOR(i, 0) c[i] /= tv; return *this;}
|
_CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; PIMV_FOR(i, 0) c[i] /= tv; return *this;}
|
||||||
_CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;}
|
_CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;}
|
||||||
@@ -207,7 +209,7 @@ typedef PIMathVectorT<4u, double> PIMathVectorT4d;
|
|||||||
#define PIMM_FOR_R(v) for (uint v = 0; v < Rows; ++v)
|
#define PIMM_FOR_R(v) for (uint v = 0; v < Rows; ++v)
|
||||||
|
|
||||||
template<uint Cols, uint Rows = Cols, typename Type = double>
|
template<uint Cols, uint Rows = Cols, typename Type = double>
|
||||||
class PIMathMatrixT {
|
class PIP_EXPORT PIMathMatrixT {
|
||||||
typedef PIMathMatrixT<Cols, Rows, Type> _CMatrix;
|
typedef PIMathMatrixT<Cols, Rows, Type> _CMatrix;
|
||||||
typedef PIMathMatrixT<Rows, Cols, Type> _CMatrixI;
|
typedef PIMathMatrixT<Rows, Cols, Type> _CMatrixI;
|
||||||
typedef PIMathVectorT<Rows, Type> _CMCol;
|
typedef PIMathVectorT<Rows, Type> _CMCol;
|
||||||
@@ -417,7 +419,7 @@ class PIMathMatrix;
|
|||||||
#define PIMV_FOR(v, s) for (uint v = s; v < size_; ++v)
|
#define PIMV_FOR(v, s) for (uint v = s; v < size_; ++v)
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
class PIMathVector {
|
class PIP_EXPORT PIMathVector {
|
||||||
typedef PIMathVector<Type> _CVector;
|
typedef PIMathVector<Type> _CVector;
|
||||||
public:
|
public:
|
||||||
PIMathVector(const uint size = 3) {resize(size);}
|
PIMathVector(const uint size = 3) {resize(size);}
|
||||||
@@ -440,7 +442,7 @@ public:
|
|||||||
Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);}
|
Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);}
|
||||||
Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);}
|
Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);}
|
||||||
Type angleRad(const _CVector & v) const {return acos(angleCos(v));}
|
Type angleRad(const _CVector & v) const {return acos(angleCos(v));}
|
||||||
Type angleDeg(const _CVector & v) const {return toGrad(acos(angleCos(v)));}
|
Type angleDeg(const _CVector & v) const {return toDeg(acos(angleCos(v)));}
|
||||||
_CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));}
|
_CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));}
|
||||||
_CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; PIMV_FOR(i, 0) c[i] /= tv; return *this;}
|
_CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; PIMV_FOR(i, 0) c[i] /= tv; return *this;}
|
||||||
_CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;}
|
_CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;}
|
||||||
@@ -499,7 +501,7 @@ typedef PIMathVector<double> PIMathVectord;
|
|||||||
#define PIMM_FOR_R(v) for (uint v = 0; v < rows_; ++v)
|
#define PIMM_FOR_R(v) for (uint v = 0; v < rows_; ++v)
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
class PIMathMatrix {
|
class PIP_EXPORT PIMathMatrix {
|
||||||
typedef PIMathMatrix<Type> _CMatrix;
|
typedef PIMathMatrix<Type> _CMatrix;
|
||||||
typedef PIMathVector<Type> _CMCol;
|
typedef PIMathVector<Type> _CMCol;
|
||||||
typedef PIMathVector<Type> _CMRow;
|
typedef PIMathVector<Type> _CMRow;
|
||||||
@@ -716,7 +718,7 @@ struct TransferFunction { // Для задания передаточной фу
|
|||||||
// Эйлера
|
// Эйлера
|
||||||
// Рунге-Кутта 4-го порядка
|
// Рунге-Кутта 4-го порядка
|
||||||
// Адамса-Бэшфортса-Моултона 2, 3, 4 порядков
|
// Адамса-Бэшфортса-Моултона 2, 3, 4 порядков
|
||||||
class Solver
|
class PIP_EXPORT Solver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Method {Global = -1,
|
enum Method {Global = -1,
|
||||||
@@ -774,7 +776,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PIFFT
|
class PIP_EXPORT PIFFT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PIFFT();
|
PIFFT();
|
||||||
@@ -827,7 +829,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PIStatistic {
|
class PIP_EXPORT PIStatistic {
|
||||||
public:
|
public:
|
||||||
PIStatistic();
|
PIStatistic();
|
||||||
bool calculate(const PIVector<double> &val);
|
bool calculate(const PIVector<double> &val);
|
||||||
|
|||||||
@@ -20,7 +20,14 @@
|
|||||||
#ifndef PIMONITOR_H
|
#ifndef PIMONITOR_H
|
||||||
#define PIMONITOR_H
|
#define PIMONITOR_H
|
||||||
|
|
||||||
class PIMonitor
|
#include "pip_export.h"
|
||||||
|
|
||||||
|
#if defined(DOXYGEN) || defined(__GNUC__)
|
||||||
|
# undef PIP_EXPORT
|
||||||
|
# define PIP_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class PIP_EXPORT PIMonitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PIMonitor();
|
PIMonitor();
|
||||||
|
|||||||
@@ -64,12 +64,12 @@ public:
|
|||||||
PIRepeater(const PIString & config, const PIString & name) {
|
PIRepeater(const PIString & config, const PIString & name) {
|
||||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||||
if (!conf.isOpened()) {
|
if (!conf.isOpened()) {
|
||||||
piCout << "[PIRepeater \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
|
piCout << "[PIRepeater \"" << name << "\"] Can`t open \"" << config << "\"!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PIConfig::Entry & b(conf.getValue(name));
|
PIConfig::Entry & b(conf.getValue(name));
|
||||||
if (b.childCount() != 2) {
|
if (b.childCount() != 2) {
|
||||||
piCout << "[PIRepeater \"" << name << "\"] \"" << config << "\" should consist 2 nodes!" << endl;
|
piCout << "[PIRepeater \"" << name << "\"] \"" << config << "\" should consist 2 nodes!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addProtocol(config, b.child(0)->fullName());
|
addProtocol(config, b.child(0)->fullName());
|
||||||
|
|||||||
@@ -21,11 +21,11 @@
|
|||||||
#define PIMUTEX_H
|
#define PIMUTEX_H
|
||||||
|
|
||||||
#include "piincludes.h"
|
#include "piincludes.h"
|
||||||
#ifdef CC_GCC
|
#ifndef WINDOWS
|
||||||
#include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class PIMutex
|
class PIP_EXPORT PIMutex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
@@ -59,7 +59,8 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PIMutexLocker
|
|
||||||
|
class PIP_EXPORT PIMutexLocker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PIMutexLocker(PIMutex * m): mutex(m) {mutex->lock();}
|
PIMutexLocker(PIMutex * m): mutex(m) {mutex->lock();}
|
||||||
|
|||||||
272
piobject.h
272
piobject.h
@@ -1,3 +1,8 @@
|
|||||||
|
/*! \file piobject.h
|
||||||
|
* \brief Base object
|
||||||
|
*
|
||||||
|
* This file declare PIObject class and associated macros
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism
|
Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism
|
||||||
@@ -22,31 +27,166 @@
|
|||||||
|
|
||||||
#include "pistring.h"
|
#include "pistring.h"
|
||||||
|
|
||||||
/// declare event handler \"event\" inside class \"obj\" with name \"name\", ret name()
|
|
||||||
#define EVENT_HANDLER0(obj, ret, name) static ret __stat_eh_##name##__(void * o) {return ((obj*)o)->name();} ret name()
|
#ifdef DOXYGEN
|
||||||
#define EVENT_HANDLER1(obj, ret, name, a0, n0) static ret __stat_eh_##name##__(void * o, a0 n0) {return ((obj*)o)->name(n0);} ret name(a0 n0)
|
|
||||||
#define EVENT_HANDLER2(obj, ret, name, a0, n0, a1, n1) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1) {return ((obj*)o)->name(n0, n1);} ret name(a0 n0, a1 n1)
|
|
||||||
#define EVENT_HANDLER3(obj, ret, name, a0, n0, a1, n1, a2, n2) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1, a2 n2) {return ((obj*)o)->name(n0, n1, n2);} ret name(a0 n0, a1 n1, a2 n2)
|
/// \relatesalso PIObject \brief you should use this macro after class declaration to use EVENT and EVENT_HANDLER
|
||||||
#define EVENT_HANDLER4(obj, ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((obj*)o)->name(n0, n1, n2, n3);} ret name(a0 n0, a1 n1, a2 n2, a3 n3)
|
#define PIOBJECT(name)
|
||||||
|
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\", ret name()
|
||||||
|
#define EVENT_HANDLER0(ret, name) ret name()
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\", ret name(type0 var0)
|
||||||
|
#define EVENT_HANDLER1(ret, name, type0, var0) ret name(type0 var0)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\", ret name(type0 var0, type1 var1)
|
||||||
|
#define EVENT_HANDLER2(ret, name, type0, var0, type1, var1) ret name(type0 var0, type1 var1)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\", ret name(type0 var0, type1 var1, type2 var2)
|
||||||
|
#define EVENT_HANDLER3(ret, name, type0, var0, type1, var1, type2, var2) ret name(type0 var0, type1 var1, type2 var2)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\", ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||||
|
#define EVENT_HANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief EVENT_HANDLER is synonym of EVENT_HANDLER0
|
||||||
#define EVENT_HANDLER EVENT_HANDLER0
|
#define EVENT_HANDLER EVENT_HANDLER0
|
||||||
|
|
||||||
/// declare virtual event handler \"event\" inside class \"obj\" with name \"name\", virtual ret name()
|
|
||||||
#define EVENT_VHANDLER0(obj, ret, name) static ret __stat_eh_##name##__(void * o) {return ((obj*)o)->name();} virtual ret name()
|
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\", virtual ret name()
|
||||||
#define EVENT_VHANDLER1(obj, ret, name, a0, n0) static ret __stat_eh_##name##__(void * o, a0 n0) {return ((obj*)o)->name(n0);} virtual ret name(a0 n0)
|
#define EVENT_VHANDLER0(ret, name) virtual ret name()
|
||||||
#define EVENT_VHANDLER2(obj, ret, name, a0, n0, a1, n1) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1) {return ((obj*)o)->name(n0, n1);} virtual ret name(a0 n0, a1 n1)
|
|
||||||
#define EVENT_VHANDLER3(obj, ret, name, a0, n0, a1, n1, a2, n2) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1, a2 n2) {return ((obj*)o)->name(n0, n1, n2);} virtual ret name(a0 n0, a1 n1, a2 n2)
|
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\", virtual ret name(type0 var0)
|
||||||
#define EVENT_VHANDLER4(obj, ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((obj*)o)->name(n0, n1, n2, n3);} virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)
|
#define EVENT_VHANDLER1(ret, name, type0, var0) virtual ret name(type0 var0)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\", virtual ret name(type0 var0, type1 var1)
|
||||||
|
#define EVENT_VHANDLER2(ret, name, type0, var0, type1, var1) virtual ret name(type0 var0, type1 var1)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\", virtual ret name(type0 var0, type1 var1, type2 var2)
|
||||||
|
#define EVENT_VHANDLER3(ret, name, type0, var0, type1, var1, type2, var2) virtual ret name(type0 var0, type1 var1, type2 var2)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\", virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||||
|
#define EVENT_VHANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief EVENT_VHANDLER is synonym of EVENT_VHANDLER0
|
||||||
#define EVENT_VHANDLER EVENT_VHANDLER0
|
#define EVENT_VHANDLER EVENT_VHANDLER0
|
||||||
|
|
||||||
/// declare event \"event\" inside class \"obj\" with name \"name\", void name();
|
|
||||||
#define EVENT0(obj, name) EVENT_HANDLER0(obj, void, name) {PIObject::raiseEvent(this, #name);}
|
/// \relatesalso PIObject \brief declare event \"event\" with name \"name\", void name();
|
||||||
#define EVENT1(obj, name, a0, n0) EVENT_HANDLER1(obj, void, name, a0, n0) {PIObject::raiseEvent(this, #name, n0);}
|
#define EVENT0(name) void name();
|
||||||
#define EVENT2(obj, name, a0, n0, a1, n1) EVENT_HANDLER2(obj, void, name, a0, n0, a1, n1) {PIObject::raiseEvent(this, #name, n0, n1);}
|
|
||||||
#define EVENT3(obj, name, a0, n0, a1, n1, a2, n2) EVENT_HANDLER3(obj, void, name, a0, n0, a1, n1, a2, n2) {PIObject::raiseEvent(this, #name, n0, n1, n2);}
|
/// \relatesalso PIObject \brief declare event \"event\" with name \"name\", void name(type0 var0);
|
||||||
#define EVENT4(obj, name, a0, n0, a1, n1, a2, n2, a3, n3) EVENT_HANDLER4(obj, void, name, a0, n0, a1, n1, a2, n2, a3, n3) {PIObject::raiseEvent(this, #name, n0, n1, n2, n3);}
|
#define EVENT1(name, type0, var0) void name(type0 var0);
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief declare event \"event\" with name \"name\", void name(type0 var0, type1 var1);
|
||||||
|
#define EVENT2(name, type0, var0, type1, var1) void name(type0 var0, type1 var1);
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief declare event \"event\" with name \"name\", void name(type0 var0, type1 var1, type2 var2);
|
||||||
|
#define EVENT3(name, type0, var0, type1, var1, type2, var2) void name(type0 var0, type1 var1, type2 var2);
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief declare event \"event\" with name \"name\", void name(type0 var0, type1 var1, type2 var2, type3 var3);
|
||||||
|
#define EVENT4(name, type0, var0, type1, var1, type2, var2, type3, var3) void name(type0 var0, type1 var1, type2 var2, type3 var3);
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief EVENT is synonym of EVENT0
|
||||||
|
#define EVENT EVENT0
|
||||||
|
|
||||||
|
|
||||||
|
#define RAISE_EVENT0(src, event)
|
||||||
|
#define RAISE_EVENT1(src, event, v0)
|
||||||
|
#define RAISE_EVENT2(src, event, v0, v1)
|
||||||
|
#define RAISE_EVENT3(src, event, v0, v1, v2)
|
||||||
|
#define RAISE_EVENT4(src, event, v0, v1, v2, v3)
|
||||||
|
#define RAISE_EVENT RAISE_EVENT0
|
||||||
|
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" with check of event and handler exists
|
||||||
|
#define CONNECT0(ret, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" with check of event and handler exists
|
||||||
|
#define CONNECT1(ret, type0, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" with check of event and handler exists
|
||||||
|
#define CONNECT2(ret, type0, type1, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" with check of event and handler exists
|
||||||
|
#define CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" with check of event and handler exists
|
||||||
|
#define CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief CONNECT is synonym of CONNECT0
|
||||||
|
#define CONNECT CONNECT0
|
||||||
|
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" without check of event exists
|
||||||
|
#define WEAK_CONNECT0(ret, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" without check of event exists
|
||||||
|
#define WEAK_CONNECT1(ret, type0, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" without check of event exists
|
||||||
|
#define WEAK_CONNECT2(ret, type0, type1, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" without check of event exists
|
||||||
|
#define WEAK_CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" without check of event exists
|
||||||
|
#define WEAK_CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief WEAK_CONNECT is synonym of WEAK_CONNECT0
|
||||||
|
#define WEAK_CONNECT WEAK_CONNECT0
|
||||||
|
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dest\"
|
||||||
|
#define DISCONNECT0(ret, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dest\"
|
||||||
|
#define DISCONNECT1(ret, type0, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dest\"
|
||||||
|
#define DISCONNECT2(ret, type0, type1, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dest\"
|
||||||
|
#define DISCONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dest\"
|
||||||
|
#define DISCONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief DISCONNECT is synonym of DISCONNECT0
|
||||||
|
#define DISCONNECT DISCONNECT0
|
||||||
|
|
||||||
|
|
||||||
|
/// \relatesalso PIObject \brief Returns pointer to events handler \"handler\"
|
||||||
|
#define HANDLER(handler)
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
#define PIOBJECT(obj) typedef obj __PIObject__;
|
||||||
|
|
||||||
|
#define EVENT_HANDLER0(ret, name) static ret __stat_eh_##name##__(void * o) {return ((__PIObject__*)o)->name();} ret name()
|
||||||
|
#define EVENT_HANDLER1(ret, name, a0, n0) static ret __stat_eh_##name##__(void * o, a0 n0) {return ((__PIObject__*)o)->name(n0);} ret name(a0 n0)
|
||||||
|
#define EVENT_HANDLER2(ret, name, a0, n0, a1, n1) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1) {return ((__PIObject__*)o)->name(n0, n1);} ret name(a0 n0, a1 n1)
|
||||||
|
#define EVENT_HANDLER3(ret, name, a0, n0, a1, n1, a2, n2) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)o)->name(n0, n1, n2);} ret name(a0 n0, a1 n1, a2 n2)
|
||||||
|
#define EVENT_HANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((__PIObject__*)o)->name(n0, n1, n2, n3);} ret name(a0 n0, a1 n1, a2 n2, a3 n3)
|
||||||
|
#define EVENT_HANDLER EVENT_HANDLER0
|
||||||
|
|
||||||
|
#define EVENT_VHANDLER0(ret, name) static ret __stat_eh_##name##__(void * o) {return ((__PIObject__*)o)->name();} virtual ret name()
|
||||||
|
#define EVENT_VHANDLER1(ret, name, a0, n0) static ret __stat_eh_##name##__(void * o, a0 n0) {return ((__PIObject__*)o)->name(n0);} virtual ret name(a0 n0)
|
||||||
|
#define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1) {return ((__PIObject__*)o)->name(n0, n1);} virtual ret name(a0 n0, a1 n1)
|
||||||
|
#define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)o)->name(n0, n1, n2);} virtual ret name(a0 n0, a1 n1, a2 n2)
|
||||||
|
#define EVENT_VHANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((__PIObject__*)o)->name(n0, n1, n2, n3);} virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)
|
||||||
|
#define EVENT_VHANDLER EVENT_VHANDLER0
|
||||||
|
|
||||||
|
#define EVENT0(name) EVENT_HANDLER0(void, name) {PIObject::raiseEvent(this, #name);}
|
||||||
|
#define EVENT1(name, a0, n0) EVENT_HANDLER1(void, name, a0, n0) {PIObject::raiseEvent(this, #name, n0);}
|
||||||
|
#define EVENT2(name, a0, n0, a1, n1) EVENT_HANDLER2(void, name, a0, n0, a1, n1) {PIObject::raiseEvent(this, #name, n0, n1);}
|
||||||
|
#define EVENT3(name, a0, n0, a1, n1, a2, n2) EVENT_HANDLER3(void, name, a0, n0, a1, n1, a2, n2) {PIObject::raiseEvent(this, #name, n0, n1, n2);}
|
||||||
|
#define EVENT4(name, a0, n0, a1, n1, a2, n2, a3, n3) EVENT_HANDLER4(void, name, a0, n0, a1, n1, a2, n2, a3, n3) {PIObject::raiseEvent(this, #name, n0, n1, n2, n3);}
|
||||||
#define EVENT EVENT0
|
#define EVENT EVENT0
|
||||||
|
|
||||||
/// raise event \"event\" from object \"src\"
|
|
||||||
#define RAISE_EVENT0(src, event) (src)->event();
|
#define RAISE_EVENT0(src, event) (src)->event();
|
||||||
#define RAISE_EVENT1(src, event, v0) (src)->event(v0);
|
#define RAISE_EVENT1(src, event, v0) (src)->event(v0);
|
||||||
#define RAISE_EVENT2(src, event, v0, v1) (src)->event(v0, v1);
|
#define RAISE_EVENT2(src, event, v0, v1) (src)->event(v0, v1);
|
||||||
@@ -54,31 +194,62 @@
|
|||||||
#define RAISE_EVENT4(src, event, v0, v1, v2, v3) (src)->event(v0, v1, v2, v3);
|
#define RAISE_EVENT4(src, event, v0, v1, v2, v3) (src)->event(v0, v1, v2, v3);
|
||||||
#define RAISE_EVENT RAISE_EVENT0
|
#define RAISE_EVENT RAISE_EVENT0
|
||||||
|
|
||||||
/// connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dst\" with check of event and handler exists
|
#define CONNECT0(ret, src, event, dest, handler) PIObject::piConnect(src, #event, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*))(&(src)->__stat_eh_##event##__));
|
||||||
#define CONNECT0(ret, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*))(&(dst)->__stat_eh_##handler##__), (void*)(void(*)(void*))(&(src)->__stat_eh_##event##__));
|
#define CONNECT1(ret, a0, src, event, dest, handler) PIObject::piConnect(src, #event, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0))(&(src)->__stat_eh_##event##__));
|
||||||
#define CONNECT1(ret, a0, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0))(&(dst)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0))(&(src)->__stat_eh_##event##__));
|
#define CONNECT2(ret, a0, a1, src, event, dest, handler) PIObject::piConnect(src, #event, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1))(&(src)->__stat_eh_##event##__));
|
||||||
#define CONNECT2(ret, a0, a1, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1))(&(dst)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1))(&(src)->__stat_eh_##event##__));
|
#define CONNECT3(ret, a0, a1, a2, src, event, dest, handler) PIObject::piConnect(src, #event, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1, a2))(&(src)->__stat_eh_##event##__));
|
||||||
#define CONNECT3(ret, a0, a1, a2, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2))(&(dst)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1, a2))(&(src)->__stat_eh_##event##__));
|
#define CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) PIObject::piConnect(src, #event, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1, a2, a3))(&(src)->__stat_eh_##event##__));
|
||||||
#define CONNECT4(ret, a0, a1, a2, a3, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dst)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1, a2, a3))(&(src)->__stat_eh_##event##__));
|
|
||||||
#define CONNECT CONNECT0
|
#define CONNECT CONNECT0
|
||||||
|
|
||||||
/// connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dst\" without check of event exists
|
#define WEAK_CONNECT0(ret, src, event, dest, handler) PIObject::piConnect(src, #event, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__));
|
||||||
#define WEAK_CONNECT0(ret, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*))(&(dst)->__stat_eh_##handler##__));
|
#define WEAK_CONNECT1(ret, a0, src, event, dest, handler) PIObject::piConnect(src, #event, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__));
|
||||||
#define WEAK_CONNECT1(ret, a0, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0))(&(dst)->__stat_eh_##handler##__));
|
#define WEAK_CONNECT2(ret, a0, a1, src, event, dest, handler) PIObject::piConnect(src, #event, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__));
|
||||||
#define WEAK_CONNECT2(ret, a0, a1, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1))(&(dst)->__stat_eh_##handler##__));
|
#define WEAK_CONNECT3(ret, a0, a1, a2, src, event, dest, handler) PIObject::piConnect(src, #event, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__));
|
||||||
#define WEAK_CONNECT3(ret, a0, a1, a2, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2))(&(dst)->__stat_eh_##handler##__));
|
#define WEAK_CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) PIObject::piConnect(src, #event, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__));
|
||||||
#define WEAK_CONNECT4(ret, a0, a1, a2, a3, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dst)->__stat_eh_##handler##__));
|
|
||||||
#define WEAK_CONNECT WEAK_CONNECT0
|
#define WEAK_CONNECT WEAK_CONNECT0
|
||||||
|
|
||||||
/// piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dst\"
|
#define DISCONNECT0(ret, src, event, dest, handler) PIObject::piDisconnect(src, #event, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__));
|
||||||
#define DISCONNECT0(ret, src, event, dst, handler) PIObject::piDisconnect(src, #event, dst, (void*)(ret(*)(void*))(&(dst)->__stat_eh_##handler##__));
|
#define DISCONNECT1(ret, a0, src, event, dest, handler) PIObject::piDisconnect(src, #event, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__));
|
||||||
#define DISCONNECT1(ret, a0, src, event, dst, handler) PIObject::piDisconnect(src, #event, dst, (void*)(ret(*)(void*, a0))(&(dst)->__stat_eh_##handler##__));
|
#define DISCONNECT2(ret, a0, a1, src, event, dest, handler) PIObject::piDisconnect(src, #event, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__));
|
||||||
#define DISCONNECT2(ret, a0, a1, src, event, dst, handler) PIObject::piDisconnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1))(&(dst)->__stat_eh_##handler##__));
|
#define DISCONNECT3(ret, a0, a1, a2, src, event, dest, handler) PIObject::piDisconnect(src, #event, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__));
|
||||||
#define DISCONNECT3(ret, a0, a1, a2, src, event, dst, handler) PIObject::piDisconnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2))(&(dst)->__stat_eh_##handler##__));
|
#define DISCONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) PIObject::piDisconnect(src, #event, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__));
|
||||||
#define DISCONNECT4(ret, a0, a1, a2, a3, src, event, dst, handler) PIObject::piDisconnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dst)->__stat_eh_##handler##__));
|
|
||||||
#define DISCONNECT DISCONNECT0
|
#define DISCONNECT DISCONNECT0
|
||||||
|
|
||||||
class PIObject
|
#define HANDLER(handler) __stat_eh_##handler##__
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef void (*Handler)(void * );
|
||||||
|
|
||||||
|
/** \brief This is base class for any classes which use events -> handlers mechanism.
|
||||||
|
* \details
|
||||||
|
* \section PIObject_sec0 Events and Event handlers
|
||||||
|
* %PIObject provide notification mechanism similar Qt but implemented
|
||||||
|
* on language capabilities without any special preprocessors or compilers.
|
||||||
|
* Any class inherits PIObject should use macro \a PIOBJECT() immediate
|
||||||
|
* after declaration to proper compile.
|
||||||
|
*
|
||||||
|
* Event is a some abstract event that can be raised at any time.
|
||||||
|
* Event is a function but declared with special macro \a EVENT().
|
||||||
|
* To raise event simply execute event function.
|
||||||
|
*
|
||||||
|
* Event handler is a function but declared with special macro
|
||||||
|
* \a EVENT_HANDLER(). You can use event handlers as ordinary functions.
|
||||||
|
*
|
||||||
|
* Main goal of this mechanism is perform abstract connections between
|
||||||
|
* various objects. This functionality provide macro \a CONNECT() which
|
||||||
|
* connect some event of first object to some event handler or event of
|
||||||
|
* second object. Each event can be connected any times to any event handlers.
|
||||||
|
*
|
||||||
|
* Example: \snippet piobject.cpp main
|
||||||
|
* Result:
|
||||||
|
* \code{.cpp}
|
||||||
|
* handler B: 2 , 0.5
|
||||||
|
* handler A: event to handler
|
||||||
|
* handler A: event to event
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
class PIP_EXPORT PIObject
|
||||||
{
|
{
|
||||||
friend class PIObjectManager;
|
friend class PIObjectManager;
|
||||||
public:
|
public:
|
||||||
@@ -133,7 +304,7 @@ public:
|
|||||||
slots_.insert(NamedFunction(func, name, PIStringList(typeid(T0).name(), typeid(T1).name(), typeid(T2).name(), typeid(T3).name())), name);
|
slots_.insert(NamedFunction(func, name, PIStringList(typeid(T0).name(), typeid(T1).name(), typeid(T2).name(), typeid(T3).name())), name);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/// Direct connect
|
// / Direct connect
|
||||||
static void piConnect(PIObject * src, const PIString & sig, void * dest, void * ev_h) {src->connections << Connection(ev_h, 0, sig, dest);}
|
static void piConnect(PIObject * src, const PIString & sig, void * dest, void * ev_h) {src->connections << Connection(ev_h, 0, sig, dest);}
|
||||||
static void piConnect(PIObject * src, const PIString & sig, void * dest, void * ev_h, void * e_h) {src->connections << Connection(ev_h, e_h, sig, dest);}
|
static void piConnect(PIObject * src, const PIString & sig, void * dest, void * ev_h, void * e_h) {src->connections << Connection(ev_h, e_h, sig, dest);}
|
||||||
static void piDisconnect(PIObject * src, const PIString & sig, void * dest, void * ev_h) {
|
static void piDisconnect(PIObject * src, const PIString & sig, void * dest, void * ev_h) {
|
||||||
@@ -145,6 +316,25 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static void piDisconnect(PIObject * src, const PIString & sig, void * dest) {
|
||||||
|
for (int i = 0; i < src->connections.size_s(); ++i) {
|
||||||
|
Connection & cc(src->connections[i]);
|
||||||
|
if (cc.event == sig && cc.dest == dest) {
|
||||||
|
src->connections.remove(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void piDisconnect(PIObject * src, const PIString & sig) {
|
||||||
|
for (int i = 0; i < src->connections.size_s(); ++i) {
|
||||||
|
Connection & cc(src->connections[i]);
|
||||||
|
if (cc.event == sig) {
|
||||||
|
src->connections.remove(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void piDisconnect(PIObject * src) {src->connections.clear();}
|
||||||
//static void piConnect(PIObject & src, const PIString & sig, PIObject * dest, void * ev_h) {src.connections << Connection(ev_h, sig, dest);}
|
//static void piConnect(PIObject & src, const PIString & sig, PIObject * dest, void * ev_h) {src.connections << Connection(ev_h, sig, dest);}
|
||||||
//static void piConnect(PIObject * src, const PIString & sig, PIObject & dest, void * ev_h) {src->connections << Connection(ev_h, sig, &dest);}
|
//static void piConnect(PIObject * src, const PIString & sig, PIObject & dest, void * ev_h) {src->connections << Connection(ev_h, sig, &dest);}
|
||||||
//static void piConnect(PIObject & src, const PIString & sig, PIObject & dest, void * ev_h) {src.connections << Connection(ev_h, sig, &dest);}
|
//static void piConnect(PIObject & src, const PIString & sig, PIObject & dest, void * ev_h) {src.connections << Connection(ev_h, sig, &dest);}
|
||||||
@@ -164,7 +354,7 @@ public:
|
|||||||
return PIObject::piConnect(src, event, dest, handler, force);
|
return PIObject::piConnect(src, event, dest, handler, force);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
/// Raise events
|
// / Raise events
|
||||||
static void raiseEvent(PIObject * sender, const PIString & event) {
|
static void raiseEvent(PIObject * sender, const PIString & event) {
|
||||||
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
||||||
Connection & i(sender->connections[j]);
|
Connection & i(sender->connections[j]);
|
||||||
@@ -226,7 +416,7 @@ public:
|
|||||||
destObject->raiseEvent<T0, T1, T2, T3>(name, v0, v1, v2, v3);
|
destObject->raiseEvent<T0, T1, T2, T3>(name, v0, v1, v2, v3);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/// Raise events through manager
|
// / Raise events through manager
|
||||||
static void raiseEvent(const PIString & destObject, const PIString & name) {
|
static void raiseEvent(const PIString & destObject, const PIString & name) {
|
||||||
PIObject * dest = findByName(destObject);
|
PIObject * dest = findByName(destObject);
|
||||||
if (dest == 0) {
|
if (dest == 0) {
|
||||||
|
|||||||
1
pip.h
1
pip.h
@@ -29,3 +29,4 @@
|
|||||||
#include "pisystemmonitor.h"
|
#include "pisystemmonitor.h"
|
||||||
#include "pipeer.h"
|
#include "pipeer.h"
|
||||||
#include "picrc.h"
|
#include "picrc.h"
|
||||||
|
#include "pistatemachine.h"
|
||||||
|
|||||||
149
pip.pro
149
pip.pro
@@ -1,66 +1,83 @@
|
|||||||
######################################################################
|
######################################################################
|
||||||
# Automatically generated by qmake (2.01a) ?? ???. 5 22:55:18 2011
|
# Automatically generated by qmake (2.01a) ?? ???. 5 22:55:18 2011
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = lib
|
||||||
TARGET = pip_test
|
TARGET = pip
|
||||||
DEPENDPATH += .
|
DEPENDPATH += .
|
||||||
INCLUDEPATH += .
|
INCLUDEPATH += .
|
||||||
QT -= core gui
|
QT -= core gui
|
||||||
LIBS = -lpthread -lrt
|
CONFIG -= qt
|
||||||
|
CONFIG += dll
|
||||||
# Input
|
VERSION = 0.3.4
|
||||||
HEADERS += pibitarray.h \
|
|
||||||
pibytearray.h \
|
# Input
|
||||||
pichar.h \
|
HEADERS += \
|
||||||
picli.h \
|
pivariable.h \
|
||||||
picodec.h \
|
pitimer.h \
|
||||||
piconfig.h \
|
pithread.h \
|
||||||
piconsole.h \
|
pisystemtests.h \
|
||||||
picontainers.h \
|
pisystemmonitor.h \
|
||||||
pidir.h \
|
pistring.h \
|
||||||
piethernet.h \
|
pisignals.h \
|
||||||
pievaluator.h \
|
piserial.h \
|
||||||
pifile.h \
|
piprotocol.h \
|
||||||
pigeometry.h \
|
piprocess.h \
|
||||||
piincludes.h \
|
pipeer.h \
|
||||||
pikbdlistener.h \
|
pipacketextractor.h \
|
||||||
pimath.h \
|
pip.h \
|
||||||
pimonitor.h \
|
piobject.h \
|
||||||
pimultiprotocol.h \
|
pimutex.h \
|
||||||
pimutex.h \
|
pimultiprotocol.h \
|
||||||
piobject.h \
|
pimonitor.h \
|
||||||
pip.h \
|
pimath.h \
|
||||||
piprocess.h \
|
pikbdlistener.h \
|
||||||
piprotocol.h \
|
piiodevice.h \
|
||||||
piserial.h \
|
piincludes.h \
|
||||||
pisignals.h \
|
pigeometry.h \
|
||||||
pistring.h \
|
pifile.h \
|
||||||
pisystemmonitor.h \
|
pievaluator.h \
|
||||||
pithread.h \
|
piethernet.h \
|
||||||
pitimer.h \
|
pidir.h \
|
||||||
pivariable.h
|
picrc.h \
|
||||||
SOURCES += main.cpp \
|
picontainers.h \
|
||||||
pibytearray.cpp \
|
piconsole.h \
|
||||||
picli.cpp \
|
piconfig.h \
|
||||||
picodec.cpp \
|
picodec.h \
|
||||||
piconfig.cpp \
|
picli.h \
|
||||||
piconsole.cpp \
|
pichar.h \
|
||||||
pidir.cpp \
|
pibytearray.h \
|
||||||
piethernet.cpp \
|
pibitarray.h
|
||||||
pievaluator.cpp \
|
SOURCES += main.cpp \
|
||||||
pifile.cpp \
|
pivariable.cpp \
|
||||||
pikbdlistener.cpp \
|
pitimer.cpp \
|
||||||
pimath.cpp \
|
pithread.cpp \
|
||||||
pimonitor.cpp \
|
pisystemtests.cpp \
|
||||||
pimultiprotocol.cpp \
|
pisystemmonitor.cpp \
|
||||||
piobject.cpp \
|
pistring.cpp \
|
||||||
piprocess.cpp \
|
pisignals.cpp \
|
||||||
piprotocol.cpp \
|
piserial.cpp \
|
||||||
piserial.cpp \
|
piprotocol.cpp \
|
||||||
pisignals.cpp \
|
piprocess.cpp \
|
||||||
pistring.cpp \
|
pipeer.cpp \
|
||||||
pisystemmonitor.cpp \
|
pipacketextractor.cpp \
|
||||||
pithread.cpp \
|
piobject.cpp \
|
||||||
pitimer.cpp \
|
pimonitor.cpp \
|
||||||
pivariable.cpp
|
pimath.cpp \
|
||||||
|
pikbdlistener.cpp \
|
||||||
|
piiodevice.cpp \
|
||||||
|
piincludes.cpp \
|
||||||
|
pifile.cpp \
|
||||||
|
pievaluator.cpp \
|
||||||
|
piethernet.cpp \
|
||||||
|
pidir.cpp \
|
||||||
|
piconsole.cpp \
|
||||||
|
piconfig.cpp \
|
||||||
|
picodec.cpp \
|
||||||
|
picli.cpp \
|
||||||
|
pibytearray.cpp
|
||||||
|
win32 {
|
||||||
|
LIBS += -lws2_32 -lIphlpapi
|
||||||
|
} else {
|
||||||
|
LIBS = -lpthread -lrt
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
// Pass data, recHeaderPtr, received_data, recHeaderSize. Return true if packet is correct nor return false.
|
// Pass data, recHeaderPtr, received_data, recHeaderSize. Return true if packet is correct nor return false.
|
||||||
typedef bool (*HeaderCheckFunc)(void * , uchar * , uchar * , int );
|
typedef bool (*HeaderCheckFunc)(void * , uchar * , uchar * , int );
|
||||||
|
|
||||||
class PIPacketExtractor: public PIIODevice
|
class PIP_EXPORT PIPacketExtractor: public PIIODevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PIPacketExtractor(PIIODevice * device_ = 0, void * recHeaderPtr = 0, int recHeaderSize = 0, int recDataSize = 0);
|
PIPacketExtractor(PIIODevice * device_ = 0, void * recHeaderPtr = 0, int recHeaderSize = 0, int recDataSize = 0);
|
||||||
|
|||||||
5
pipeer.h
5
pipeer.h
@@ -22,8 +22,9 @@
|
|||||||
|
|
||||||
#include "piethernet.h"
|
#include "piethernet.h"
|
||||||
|
|
||||||
class PIPeer: public PIEthernet
|
class PIP_EXPORT PIPeer: public PIEthernet
|
||||||
{
|
{
|
||||||
|
PIOBJECT(PIPeer)
|
||||||
struct PeerInfo;
|
struct PeerInfo;
|
||||||
friend PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v);
|
friend PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v);
|
||||||
friend PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v);
|
friend PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v);
|
||||||
@@ -37,7 +38,7 @@ protected:
|
|||||||
bool threadedRead(uchar * readed, int size);
|
bool threadedRead(uchar * readed, int size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EVENT_HANDLER2(PIPeer, void, timerEvent, void * , data, int, delim);
|
EVENT_HANDLER2(void, timerEvent, void * , data, int, delim);
|
||||||
static bool func_readed(void * peer, uchar * data, int size);
|
static bool func_readed(void * peer, uchar * data, int size);
|
||||||
|
|
||||||
struct PeerInfo {
|
struct PeerInfo {
|
||||||
|
|||||||
@@ -141,12 +141,12 @@ void PIProcess::run() {
|
|||||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||||
CloseHandle(pi.hProcess);
|
CloseHandle(pi.hProcess);
|
||||||
} else
|
} else
|
||||||
piCout << "[PIProcess] \"CreateProcess\" error, " << errorString() << endl;
|
piCout << "[PIProcess] \"CreateProcess\" error, " << errorString();
|
||||||
#else
|
#else
|
||||||
|
|
||||||
//cout << "exec " << tf_in << ", " << tf_out << ", " << tf_err << endl;
|
//cout << "exec " << tf_in << ", " << tf_out << ", " << tf_err << endl;
|
||||||
if (execve(str.c_str(), a, e) < 0)
|
if (execve(str.c_str(), a, e) < 0)
|
||||||
piCout << "[PIProcess] \"execve\" error, " << errorString() << endl;
|
piCout << "[PIProcess] \"execve\" error, " << errorString();
|
||||||
} else {
|
} else {
|
||||||
msleep(1);
|
msleep(1);
|
||||||
//cout << "wait" << endl;
|
//cout << "wait" << endl;
|
||||||
|
|||||||
27
piprocess.h
27
piprocess.h
@@ -40,11 +40,12 @@
|
|||||||
/// bool exec(const PIString & program, const PIStringList & args)
|
/// bool exec(const PIString & program, const PIStringList & args)
|
||||||
/// void terminate()
|
/// void terminate()
|
||||||
/// bool waitForFinish(int timeout_msecs = 60000)
|
/// bool waitForFinish(int timeout_msecs = 60000)
|
||||||
class PIProcess: private PIThread
|
class PIP_EXPORT PIProcess: private PIThread
|
||||||
{
|
{
|
||||||
|
PIOBJECT(PIProcess)
|
||||||
public:
|
public:
|
||||||
PIProcess();
|
PIProcess();
|
||||||
~PIProcess();
|
virtual ~PIProcess();
|
||||||
|
|
||||||
int exitCode() const {return exit_code;}
|
int exitCode() const {return exit_code;}
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
@@ -65,18 +66,18 @@ public:
|
|||||||
PIString workingDirectory() const {return wd;}
|
PIString workingDirectory() const {return wd;}
|
||||||
void setWorkingDirectory(const PIString & path) {wd = path;}
|
void setWorkingDirectory(const PIString & path) {wd = path;}
|
||||||
void resetWorkingDirectory() {wd.clear();}
|
void resetWorkingDirectory() {wd.clear();}
|
||||||
EVENT_HANDLER1(PIProcess, void, exec, const PIString & , program) {args.clear(); args << program; exec_();}
|
EVENT_HANDLER1(void, exec, const PIString & , program) {args.clear(); args << program; exec_();}
|
||||||
EVENT_HANDLER2(PIProcess, void, exec, const PIString & , program, const PIString & , arg) {args.clear(); args << program << arg; exec_();}
|
EVENT_HANDLER2(void, exec, const PIString & , program, const PIString & , arg) {args.clear(); args << program << arg; exec_();}
|
||||||
EVENT_HANDLER3(PIProcess, void, exec, const PIString & , program, const PIString & , arg1, const PIString & , arg2) {args.clear(); args << program << arg1 << arg2; exec_();}
|
EVENT_HANDLER3(void, exec, const PIString & , program, const PIString & , arg1, const PIString & , arg2) {args.clear(); args << program << arg1 << arg2; exec_();}
|
||||||
EVENT_HANDLER4(PIProcess, void, exec, const PIString & , program, const PIString & , arg1, const PIString & , arg2, const PIString & , arg3) {args.clear(); args << program << arg1 << arg2 << arg3; exec_();}
|
EVENT_HANDLER4(void, exec, const PIString & , program, const PIString & , arg1, const PIString & , arg2, const PIString & , arg3) {args.clear(); args << program << arg1 << arg2 << arg3; exec_();}
|
||||||
EVENT_HANDLER2(PIProcess, void, exec, const PIString & , program, const PIStringList & , args_) {args << program << args_; exec_();}
|
EVENT_HANDLER2(void, exec, const PIString & , program, const PIStringList & , args_) {args << program << args_; exec_();}
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
EVENT_HANDLER(PIProcess, void, terminate) {if (is_exec) if (!TerminateProcess(pi.hProcess, 0)) return; pi.dwProcessId = 0;}
|
EVENT_HANDLER(void, terminate) {if (is_exec) if (!TerminateProcess(pi.hProcess, 0)) return; pi.dwProcessId = 0;}
|
||||||
#else
|
#else
|
||||||
EVENT_HANDLER(PIProcess, void, terminate) {if (is_exec) kill(pid, SIGKILL); pid = 0;}
|
EVENT_HANDLER(void, terminate) {if (is_exec) kill(pid, SIGKILL); pid = 0;}
|
||||||
#endif
|
#endif
|
||||||
EVENT_HANDLER(PIProcess, bool, waitForFinish) {return waitForFinish(60000);}
|
EVENT_HANDLER(bool, waitForFinish) {return waitForFinish(60000);}
|
||||||
EVENT_HANDLER1(PIProcess, bool, waitForFinish, int, timeout_msecs) {return PIThread::waitForFinish(timeout_msecs);}
|
EVENT_HANDLER1(bool, waitForFinish, int, timeout_msecs) {return PIThread::waitForFinish(timeout_msecs);}
|
||||||
PIByteArray readOutput() {f_out.open(PIIODevice::ReadOnly); return f_out.readAll();}
|
PIByteArray readOutput() {f_out.open(PIIODevice::ReadOnly); return f_out.readAll();}
|
||||||
PIByteArray readError() {f_err.open(PIIODevice::ReadOnly); return f_err.readAll();}
|
PIByteArray readError() {f_err.open(PIIODevice::ReadOnly); return f_err.readAll();}
|
||||||
|
|
||||||
@@ -92,8 +93,8 @@ public:
|
|||||||
static int currentPID() {return getpid();}
|
static int currentPID() {return getpid();}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EVENT1(PIProcess, execStarted, PIString, program)
|
EVENT1(execStarted, PIString, program)
|
||||||
EVENT2(PIProcess, execFinished, PIString, program, int, exit_code)
|
EVENT2(execFinished, PIString, program, int, exit_code)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void run();
|
virtual void run();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
PIObject::setName(name);
|
PIObject::setName(name);
|
||||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||||
if (!conf.isOpened()) {
|
if (!conf.isOpened()) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!";
|
||||||
devReceiverState = devSenderState = "Config error";
|
devReceiverState = devSenderState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
|
|
||||||
/// receiver section
|
/// receiver section
|
||||||
if (rb.isEntryExists("ip") && rb.isEntryExists("device")) {
|
if (rb.isEntryExists("ip") && rb.isEntryExists("device")) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) dev = gdev;
|
if (gok && !ok) dev = gdev;
|
||||||
if (gok && ok && (dev != gdev)) {
|
if (gok && ok && (dev != gdev)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) ps = gps;
|
if (gok && !ok) ps = gps;
|
||||||
if (gok && ok && (ps != gps)) {
|
if (gok && ok && (ps != gps)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive port in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive port in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) flag = gflag;
|
if (gok && !ok) flag = gflag;
|
||||||
if (gok && ok && (flag != gflag)) {
|
if (gok && ok && (flag != gflag)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectEnabled\" flag in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectEnabled\" flag in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -85,18 +85,18 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) freq = gfreq;
|
if (gok && !ok) freq = gfreq;
|
||||||
if (gok && ok && (freq != gfreq)) {
|
if (gok && ok && (freq != gfreq)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectTimeout\" value in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectTimeout\" value in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
eth->setReopenTimeout(freq * 1000);
|
eth->setReopenTimeout(freq * 1000);
|
||||||
}
|
}
|
||||||
if (recDataPtr == 0)
|
if (recDataPtr == 0)
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!";
|
||||||
if (recDataSize == 0)
|
if (recDataSize == 0)
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!";
|
||||||
} else {
|
} else {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.port\" or \"" << name << ".port\" in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.port\" or \"" << name << ".port\" in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) dev = gdev;
|
if (gok && !ok) dev = gdev;
|
||||||
if (gok && ok && (dev != gdev)) {
|
if (gok && ok && (dev != gdev)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) ps = gps;
|
if (gok && !ok) ps = gps;
|
||||||
if (gok && ok && (ps != gps)) {
|
if (gok && ok && (ps != gps)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"speed\" in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"speed\" in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) flag = gflag;
|
if (gok && !ok) flag = gflag;
|
||||||
if (gok && ok && (flag != gflag)) {
|
if (gok && ok && (flag != gflag)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"parity\" in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"parity\" in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) flag = gflag;
|
if (gok && !ok) flag = gflag;
|
||||||
if (gok && ok && (flag != gflag)) {
|
if (gok && ok && (flag != gflag)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"twoStopBits\" parity in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"twoStopBits\" parity in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) ps = gps;
|
if (gok && !ok) ps = gps;
|
||||||
if (gok && ok && (ps != gps)) {
|
if (gok && ok && (ps != gps)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"vtime\" in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"vtime\" in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -162,11 +162,11 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
}
|
}
|
||||||
has_dev = true;
|
has_dev = true;
|
||||||
if (recDataPtr == 0)
|
if (recDataPtr == 0)
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!";
|
||||||
if (recDataSize == 0)
|
if (recDataSize == 0)
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!";
|
||||||
} else {
|
} else {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.speed\" or \"" << name << ".speed\" in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.speed\" or \"" << name << ".speed\" in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -176,7 +176,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) history_write_rec = ghist;
|
if (gok && !ok) history_write_rec = ghist;
|
||||||
if (gok && ok && (history_write_rec != ghist)) {
|
if (gok && ok && (history_write_rec != ghist)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver history in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver history in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -187,7 +187,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
history_id_rec = rb.getValue("historyID", 0, &ok);
|
history_id_rec = rb.getValue("historyID", 0, &ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
history_id_rec = protName.toByteArray().checksumCRC16();
|
history_id_rec = protName.toByteArray().checksumCRC16();
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: no receiver history ID defined, write with ID = " << history_id_rec << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: no receiver history ID defined, write with ID = " << history_id_rec;
|
||||||
}
|
}
|
||||||
history_file_rec.open(history_path_rec, PIIODevice::WriteOnly);
|
history_file_rec.open(history_path_rec, PIIODevice::WriteOnly);
|
||||||
}
|
}
|
||||||
@@ -196,21 +196,21 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
gfreq = b.getValue("frequency", -1.f, &gok);
|
gfreq = b.getValue("frequency", -1.f, &gok);
|
||||||
if (gok && !ok) freq = gfreq;
|
if (gok && !ok) freq = gfreq;
|
||||||
if (gok && ok && (freq != gfreq)) {
|
if (gok && ok && (freq != gfreq)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous expected frequency in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous expected frequency in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (freq > 0.f && !has_dev)
|
if (freq > 0.f && !has_dev)
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: no receiver device and not null expected frequency!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: no receiver device and not null expected frequency!";
|
||||||
float tm = b.getValue("disconnectTimeout", 3.f);
|
float tm = b.getValue("disconnectTimeout", 3.f);
|
||||||
if (tm <= 0.f)
|
if (tm <= 0.f)
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: diconnect timeout <= 0 s!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: diconnect timeout <= 0 s!";
|
||||||
timeout_ = (tm < 0.f) ? 0.f : tm;
|
timeout_ = (tm < 0.f) ? 0.f : tm;
|
||||||
setExpectedFrequency(freq);
|
setExpectedFrequency(freq);
|
||||||
|
|
||||||
/// sender section
|
/// sender section
|
||||||
if (sb.isEntryExists("ip") && sb.isEntryExists("device")) {
|
if (sb.isEntryExists("ip") && sb.isEntryExists("device")) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!";
|
||||||
devSenderState = "Config error";
|
devSenderState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -220,7 +220,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) dev = gdev;
|
if (gok && !ok) dev = gdev;
|
||||||
if (gok && ok && (dev != gdev)) {
|
if (gok && ok && (dev != gdev)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!";
|
||||||
devSenderState = "Config error";
|
devSenderState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -229,7 +229,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) ps = gps;
|
if (gok && !ok) ps = gps;
|
||||||
if (gok && ok && (ps != gps)) {
|
if (gok && ok && (ps != gps)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send port in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send port in \"" << config << "\"!";
|
||||||
devSenderState = "Config error";
|
devSenderState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) flag = gflag;
|
if (gok && !ok) flag = gflag;
|
||||||
if (gok && ok && (flag != gflag)) {
|
if (gok && ok && (flag != gflag)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectEnabled\" flag in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectEnabled\" flag in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -254,18 +254,18 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) freq = gfreq;
|
if (gok && !ok) freq = gfreq;
|
||||||
if (gok && ok && (freq != gfreq)) {
|
if (gok && ok && (freq != gfreq)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectTimeout\" value in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectTimeout\" value in \"" << config << "\"!";
|
||||||
devReceiverState = "Config error";
|
devReceiverState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
eth->setReopenTimeout(freq * 1000);
|
eth->setReopenTimeout(freq * 1000);
|
||||||
}
|
}
|
||||||
if (sendDataPtr_ == 0)
|
if (sendDataPtr_ == 0)
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!";
|
||||||
if (sendDataSize_ == 0)
|
if (sendDataSize_ == 0)
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data size!";
|
||||||
} else {
|
} else {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.port\" or \"" << name << ".port\" in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.port\" or \"" << name << ".port\" in \"" << config << "\"!";
|
||||||
devSenderState = "Config error";
|
devSenderState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -275,7 +275,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) dev = gdev;
|
if (gok && !ok) dev = gdev;
|
||||||
if (gok && ok && (dev != gdev)) {
|
if (gok && ok && (dev != gdev)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!";
|
||||||
devSenderState = "Config error";
|
devSenderState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -284,7 +284,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) ps = gps;
|
if (gok && !ok) ps = gps;
|
||||||
if (gok && ok && (ps != gps)) {
|
if (gok && ok && (ps != gps)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"speed\" in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"speed\" in \"" << config << "\"!";
|
||||||
devSenderState = "Config error";
|
devSenderState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -293,7 +293,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) flag = gflag;
|
if (gok && !ok) flag = gflag;
|
||||||
if (gok && ok && (flag != gflag)) {
|
if (gok && ok && (flag != gflag)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"parity\" in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"parity\" in \"" << config << "\"!";
|
||||||
devSenderState = "Config error";
|
devSenderState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -304,14 +304,14 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) flag = gflag;
|
if (gok && !ok) flag = gflag;
|
||||||
if (gok && ok && (flag != gflag)) {
|
if (gok && ok && (flag != gflag)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"twoStopBits\" parity in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"twoStopBits\" parity in \"" << config << "\"!";
|
||||||
devSenderState = "Config error";
|
devSenderState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pp.setFlag(PISerial::TwoStopBits, flag);
|
pp.setFlag(PISerial::TwoStopBits, flag);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.speed\" or \"" << name << ".speed\" in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.speed\" or \"" << name << ".speed\" in \"" << config << "\"!";
|
||||||
devSenderState = "Config error";
|
devSenderState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -322,16 +322,16 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
ser->setParameters(pp);
|
ser->setParameters(pp);
|
||||||
has_dev = true;
|
has_dev = true;
|
||||||
if (sendDataPtr_ == 0)
|
if (sendDataPtr_ == 0)
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!";
|
||||||
if (sendDataSize_ == 0)
|
if (sendDataSize_ == 0)
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data size!";
|
||||||
}
|
}
|
||||||
history_write_send = sb.getValue("writeHistory", false, &ok);
|
history_write_send = sb.getValue("writeHistory", false, &ok);
|
||||||
ghist = b.getValue("writeHistory", false, &gok);
|
ghist = b.getValue("writeHistory", false, &gok);
|
||||||
if (ok || gok) {
|
if (ok || gok) {
|
||||||
if (gok && !ok) history_write_send = ghist;
|
if (gok && !ok) history_write_send = ghist;
|
||||||
if (gok && ok && (history_write_send != ghist)) {
|
if (gok && ok && (history_write_send != ghist)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender history in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender history in \"" << config << "\"!";
|
||||||
devSenderState = "Config error";
|
devSenderState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -342,7 +342,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
history_id_send = sb.getValue("historyID", 0, &ok);
|
history_id_send = sb.getValue("historyID", 0, &ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
history_id_send = protName.toByteArray().checksumCRC16() + 1;
|
history_id_send = protName.toByteArray().checksumCRC16() + 1;
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: no sender history ID defined, write with ID = " << history_id_send << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: no sender history ID defined, write with ID = " << history_id_send;
|
||||||
}
|
}
|
||||||
history_file_send.open(history_path_send, PIIODevice::WriteOnly);
|
history_file_send.open(history_path_send, PIIODevice::WriteOnly);
|
||||||
}
|
}
|
||||||
@@ -351,12 +351,12 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
|||||||
gfreq = b.getValue("frequency", -1.f, &gok);
|
gfreq = b.getValue("frequency", -1.f, &gok);
|
||||||
if (gok && !ok) freq = gfreq;
|
if (gok && !ok) freq = gfreq;
|
||||||
if (gok && ok && (freq != gfreq)) {
|
if (gok && ok && (freq != gfreq)) {
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender frequency in \"" << config << "\"!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender frequency in \"" << config << "\"!";
|
||||||
devSenderState = "Config error";
|
devSenderState = "Config error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (freq > 0.f && !has_dev)
|
if (freq > 0.f && !has_dev)
|
||||||
piCout << "[PIProtocol \"" << name << "\"] Warning: no sender device and not null send frequency!" << endl;
|
piCout << "[PIProtocol \"" << name << "\"] Warning: no sender device and not null send frequency!";
|
||||||
setSenderFrequency(freq);
|
setSenderFrequency(freq);
|
||||||
|
|
||||||
headerPtr = (uchar * )recHeaderPtr;
|
headerPtr = (uchar * )recHeaderPtr;
|
||||||
@@ -643,7 +643,7 @@ void PIProtocol::calc_diag() {
|
|||||||
else if (good_percents > 20.f && good_percents <= 80.f) diag = PIProtocol::Average;
|
else if (good_percents > 20.f && good_percents <= 80.f) diag = PIProtocol::Average;
|
||||||
else diag = PIProtocol::Good;
|
else diag = PIProtocol::Good;
|
||||||
if (diag != net_diag) {
|
if (diag != net_diag) {
|
||||||
qualityChanged(net_diag, diag);
|
qualityChanged(diag, net_diag);
|
||||||
net_diag = diag;
|
net_diag = diag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
40
piprotocol.h
40
piprotocol.h
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
class PIProtocol;
|
class PIProtocol;
|
||||||
|
|
||||||
class PIMultiProtocolBase
|
class PIP_EXPORT PIMultiProtocolBase
|
||||||
{
|
{
|
||||||
friend class PIProtocol;
|
friend class PIProtocol;
|
||||||
public:
|
public:
|
||||||
@@ -65,12 +65,12 @@ typedef void (*ReceiveFunc)(void * );
|
|||||||
/// void stop()
|
/// void stop()
|
||||||
/// void send()
|
/// void send()
|
||||||
/// void send(const void * data, int size, bool direct = false)
|
/// void send(const void * data, int size, bool direct = false)
|
||||||
class PIProtocol: public PIObject
|
class PIP_EXPORT PIProtocol: public PIObject
|
||||||
{
|
{
|
||||||
|
PIOBJECT(PIProtocol)
|
||||||
friend class PIMultiProtocolBase;
|
friend class PIMultiProtocolBase;
|
||||||
friend class PIMultiProtocol;
|
friend class PIMultiProtocol;
|
||||||
enum Type {None, Serial, Ethernet};
|
enum Type {None, Serial, Ethernet};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PIProtocol(): PIObject() {init();}
|
PIProtocol(): PIObject() {init();}
|
||||||
PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0,
|
PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0,
|
||||||
@@ -79,9 +79,9 @@ public:
|
|||||||
|
|
||||||
enum Quality {Unknown = 1, Failure = 2, Bad = 3, Average = 4, Good = 5};
|
enum Quality {Unknown = 1, Failure = 2, Bad = 3, Average = 4, Good = 5};
|
||||||
|
|
||||||
EVENT_HANDLER0(PIProtocol, void, startReceive) {startReceive(-1.f);}
|
EVENT_HANDLER0(void, startReceive) {startReceive(-1.f);}
|
||||||
EVENT_HANDLER1(PIProtocol, void, startReceive, float, exp_frequency); // if "frequency = -1" used last passed value
|
EVENT_HANDLER1(void, startReceive, float, exp_frequency); // if "frequency = -1" used last passed value
|
||||||
EVENT_HANDLER0(PIProtocol, void, stopReceive);
|
EVENT_HANDLER0(void, stopReceive);
|
||||||
void setExpectedFrequency(float frequency); // for connection quality diagnostic
|
void setExpectedFrequency(float frequency); // for connection quality diagnostic
|
||||||
void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
|
void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
|
||||||
void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; packet_ext->setPacketData(headerPtr, headerSize, dataSize);}
|
void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; packet_ext->setPacketData(headerPtr, headerSize, dataSize);}
|
||||||
@@ -91,9 +91,9 @@ public:
|
|||||||
void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;}
|
void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;}
|
||||||
float expectedFrequency() const {return exp_freq;}
|
float expectedFrequency() const {return exp_freq;}
|
||||||
|
|
||||||
EVENT_HANDLER0(PIProtocol, void, startSend) {startSend(-1.f);} // if "frequency = -1" used last passed value
|
EVENT_HANDLER0(void, startSend) {startSend(-1.f);} // if "frequency = -1" used last passed value
|
||||||
EVENT_HANDLER1(PIProtocol, void, startSend, float, frequency); // if "frequency = -1" used last passed value
|
EVENT_HANDLER1(void, startSend, float, frequency); // if "frequency = -1" used last passed value
|
||||||
EVENT_HANDLER0(PIProtocol, void, stopSend) {sendTimer->stop(); senderStopped();}
|
EVENT_HANDLER0(void, stopSend) {sendTimer->stop(); senderStopped();}
|
||||||
void setSenderFrequency(float frequency) {send_freq = frequency;}
|
void setSenderFrequency(float frequency) {send_freq = frequency;}
|
||||||
void setSenderDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
|
void setSenderDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
|
||||||
void setSenderData(void * dataPtr, int dataSize) {sendDataPtr = (uchar * )dataPtr; sendDataSize = dataSize;}
|
void setSenderData(void * dataPtr, int dataSize) {sendDataPtr = (uchar * )dataPtr; sendDataSize = dataSize;}
|
||||||
@@ -103,11 +103,11 @@ public:
|
|||||||
void setSenderParameters(PIFlags<PISerial::Parameters> parameters) {if (type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
|
void setSenderParameters(PIFlags<PISerial::Parameters> parameters) {if (type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
|
||||||
float senderFrequency() const {return send_freq;}
|
float senderFrequency() const {return send_freq;}
|
||||||
|
|
||||||
EVENT_HANDLER0(PIProtocol, void, start) {startReceive(); startSend();}
|
EVENT_HANDLER0(void, start) {startReceive(); startSend();}
|
||||||
EVENT_HANDLER0(PIProtocol, void, stop) {stopReceive(); stopSend();}
|
EVENT_HANDLER0(void, stop) {stopReceive(); stopSend();}
|
||||||
EVENT_HANDLER0(PIProtocol, void, send);
|
EVENT_HANDLER0(void, send);
|
||||||
EVENT_HANDLER2(PIProtocol, void, send, const void *, data, int, size) {send(data, size, false);}
|
EVENT_HANDLER2(void, send, const void *, data, int, size) {send(data, size, false);}
|
||||||
EVENT_HANDLER3(PIProtocol, void, send, const void *, data, int, size, bool, direct);
|
EVENT_HANDLER3(void, send, const void *, data, int, size, bool, direct);
|
||||||
|
|
||||||
void setName(const PIString & name) {protName = name; PIObject::setName(name);}
|
void setName(const PIString & name) {protName = name; PIObject::setName(name);}
|
||||||
PIString name() const {return protName;}
|
PIString name() const {return protName;}
|
||||||
@@ -161,12 +161,12 @@ public:
|
|||||||
PIPacketExtractor * packetExtractor() {return packet_ext;}
|
PIPacketExtractor * packetExtractor() {return packet_ext;}
|
||||||
PIByteArray lastHeader() {return packet_ext->lastHeader();}
|
PIByteArray lastHeader() {return packet_ext->lastHeader();}
|
||||||
|
|
||||||
EVENT0(PIProtocol, receiverStarted)
|
EVENT0(receiverStarted)
|
||||||
EVENT0(PIProtocol, receiverStopped)
|
EVENT0(receiverStopped)
|
||||||
EVENT0(PIProtocol, senderStarted)
|
EVENT0(senderStarted)
|
||||||
EVENT0(PIProtocol, senderStopped)
|
EVENT0(senderStopped)
|
||||||
EVENT1(PIProtocol, received, bool, validate_is_ok)
|
EVENT1(received, bool, validate_is_ok)
|
||||||
EVENT2(PIProtocol, qualityChanged, PIProtocol::Quality, old_quality, PIProtocol::Quality, new_quality)
|
EVENT2(qualityChanged, PIProtocol::Quality, new_quality, PIProtocol::Quality, old_quality)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool receive(uchar * data, int size) {if (dataPtr != 0) memcpy(dataPtr, data, size); return true;} // executed when raw data received, break if 'false' return
|
virtual bool receive(uchar * data, int size) {if (dataPtr != 0) memcpy(dataPtr, data, size); return true;} // executed when raw data received, break if 'false' return
|
||||||
|
|||||||
34
piserial.cpp
34
piserial.cpp
@@ -67,14 +67,14 @@ bool PISerial::setPin(int number, bool on) {
|
|||||||
case 3: return setST(on); break;
|
case 3: return setST(on); break;
|
||||||
case 4: return setDTR(on); break;
|
case 4: return setDTR(on); break;
|
||||||
case 5:
|
case 5:
|
||||||
piCout << "[PISerial] Pin number 5 is ground" << endl;
|
piCout << "[PISerial] Pin number 5 is ground";
|
||||||
return false;
|
return false;
|
||||||
case 6: return setDSR(on); break;
|
case 6: return setDSR(on); break;
|
||||||
case 7: return setRTS(on); break;
|
case 7: return setRTS(on); break;
|
||||||
case 8: return setCTS(on); break;
|
case 8: return setCTS(on); break;
|
||||||
case 9: return setRNG(on); break;
|
case 9: return setRNG(on); break;
|
||||||
default:
|
default:
|
||||||
piCout << "[PISerial] Pin number " << number << " doesn`t exists!" << endl;
|
piCout << "[PISerial] Pin number " << number << " doesn`t exists!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -93,7 +93,7 @@ bool PISerial::isPin(int number) const {
|
|||||||
case 8: return isCTS(); break;
|
case 8: return isCTS(); break;
|
||||||
case 9: return isRNG(); break;
|
case 9: return isRNG(); break;
|
||||||
default:
|
default:
|
||||||
piCout << "[PISerial] Pin number " << number << " doesn`t exists!" << endl;
|
piCout << "[PISerial] Pin number " << number << " doesn`t exists!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -103,7 +103,7 @@ bool PISerial::isPin(int number) const {
|
|||||||
bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
piCout << "[PISerial] set" << bname << " error: \"" << path_ << "\" is not opened!" << endl;
|
piCout << "[PISerial] set" << bname << " error: \"" << path_ << "\" is not opened!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ioctl(fd, on ? TIOCMBIS : TIOCMBIC, &bit) < 0) {
|
if (ioctl(fd, on ? TIOCMBIS : TIOCMBIC, &bit) < 0) {
|
||||||
@@ -112,7 +112,7 @@ bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
piCout << "[PISerial] set" << bname << " doesn`t implemented on Windows, sorry :-(" << endl;
|
piCout << "[PISerial] set" << bname << " doesn`t implemented on Windows, sorry :-(";
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
|||||||
bool PISerial::isBit(int bit, const PIString & bname) const {
|
bool PISerial::isBit(int bit, const PIString & bname) const {
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
piCout << "[PISerial] is" << bname << " error: \"" << path_ << "\" is not opened!" << endl;
|
piCout << "[PISerial] is" << bname << " error: \"" << path_ << "\" is not opened!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -129,7 +129,7 @@ bool PISerial::isBit(int bit, const PIString & bname) const {
|
|||||||
piCout << "[PISerial] is" << bname << " error: " << errorString();
|
piCout << "[PISerial] is" << bname << " error: " << errorString();
|
||||||
return ret & bit;
|
return ret & bit;
|
||||||
#else
|
#else
|
||||||
piCout << "[PISerial] set" << bname << " doesn`t implemented on Windows, sorry :-(" << endl;
|
piCout << "[PISerial] set" << bname << " doesn`t implemented on Windows, sorry :-(";
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -301,7 +301,7 @@ bool PISerial::openDevice() {
|
|||||||
if (isWriteable()) {ds |= GENERIC_WRITE; sm |= FILE_SHARE_WRITE;}
|
if (isWriteable()) {ds |= GENERIC_WRITE; sm |= FILE_SHARE_WRITE;}
|
||||||
hCom = CreateFileA(path_.data(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
hCom = CreateFileA(path_.data(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||||
if(hCom == INVALID_HANDLE_VALUE) {
|
if(hCom == INVALID_HANDLE_VALUE) {
|
||||||
piCout << "[PISerial] Unable to open \"" << path_ << "\"" << endl;
|
piCout << "[PISerial] Unable to open \"" << path_ << "\"";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fd = 0;
|
fd = 0;
|
||||||
@@ -312,7 +312,7 @@ bool PISerial::openDevice() {
|
|||||||
times.WriteTotalTimeoutConstant = 1;
|
times.WriteTotalTimeoutConstant = 1;
|
||||||
times.WriteTotalTimeoutMultiplier = 0;
|
times.WriteTotalTimeoutMultiplier = 0;
|
||||||
if (SetCommTimeouts(hCom, ×) == -1) {
|
if (SetCommTimeouts(hCom, ×) == -1) {
|
||||||
piCout << "[PISerial] Unable to set timeouts for \"" << path_ << "\"" << endl;
|
piCout << "[PISerial] Unable to set timeouts for \"" << path_ << "\"";
|
||||||
CloseHandle(hCom);
|
CloseHandle(hCom);
|
||||||
fd = -1;
|
fd = -1;
|
||||||
return false;
|
return false;
|
||||||
@@ -330,7 +330,7 @@ bool PISerial::openDevice() {
|
|||||||
}
|
}
|
||||||
desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
|
desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
|
||||||
if (SetCommState(hCom, &desc) == -1) {
|
if (SetCommState(hCom, &desc) == -1) {
|
||||||
piCout << "[PISerial] Unable to set comm state for \"" << path_ << "\"" << endl;
|
piCout << "[PISerial] Unable to set comm state for \"" << path_ << "\"";
|
||||||
CloseHandle(hCom);
|
CloseHandle(hCom);
|
||||||
fd = -1;
|
fd = -1;
|
||||||
return false;
|
return false;
|
||||||
@@ -345,7 +345,7 @@ bool PISerial::openDevice() {
|
|||||||
//cout << "init ser " << path_ << " mode " << om << " param " << params << endl;
|
//cout << "init ser " << path_ << " mode " << om << " param " << params << endl;
|
||||||
fd = ::open(path_.data(), O_NOCTTY | om);
|
fd = ::open(path_.data(), O_NOCTTY | om);
|
||||||
if(fd == -1) {
|
if(fd == -1) {
|
||||||
piCout << "[PISerial] Unable to open \"" << path_ << "\"" << endl;
|
piCout << "[PISerial] Unable to open \"" << path_ << "\"";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,20 +371,20 @@ bool PISerial::openDevice() {
|
|||||||
fcntl(fd, F_SETFL, 0);
|
fcntl(fd, F_SETFL, 0);
|
||||||
|
|
||||||
if(tcsetattr(fd, TCSANOW, &desc) < 0) {
|
if(tcsetattr(fd, TCSANOW, &desc) < 0) {
|
||||||
piCout << "[PISerial] Can`t set attributes for \"" << path_ << "\"" << endl;
|
piCout << "[PISerial] Can`t set attributes for \"" << path_ << "\"";
|
||||||
::close(fd);
|
::close(fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//piCout << "[PISerial] Initialized " << path_ << endl;
|
//piCout << "[PISerial] Initialized " << path_;
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PISerial::write(const void * data, int max_size, bool wait) {
|
int PISerial::write(const void * data, int max_size, bool wait) {
|
||||||
//piCout << "[PISerial] send " << max_size << ": " << PIString((char*)data, max_size) << endl;
|
//piCout << "[PISerial] send " << max_size << ": " << PIString((char*)data, max_size);
|
||||||
if (fd == -1 || !canWrite()) {
|
if (fd == -1 || !canWrite()) {
|
||||||
//piCout << "[PISerial] Can`t write to uninitialized COM" << endl;
|
//piCout << "[PISerial] Can`t write to uninitialized COM";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
@@ -402,6 +402,6 @@ int PISerial::write(const void * data, int max_size, bool wait) {
|
|||||||
if (wait) tcdrain(fd);
|
if (wait) tcdrain(fd);
|
||||||
#endif
|
#endif
|
||||||
return (int)wrote;
|
return (int)wrote;
|
||||||
//piCout << "[PISerial] Error while sending" << endl;
|
//piCout << "[PISerial] Error while sending";
|
||||||
//piCout << "[PISerial] Wrote " << wrote << " bytes in " << path_ << endl;
|
//piCout << "[PISerial] Wrote " << wrote << " bytes in " << path_;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
# ifndef B50
|
# ifndef B50
|
||||||
# define B50 0000001
|
# define B50 0000001
|
||||||
# endif
|
# endif
|
||||||
# ifndef B50
|
# ifndef B75
|
||||||
# define B75 0000002
|
# define B75 0000002
|
||||||
# endif
|
# endif
|
||||||
# ifndef B1500000
|
# ifndef B1500000
|
||||||
@@ -83,8 +83,11 @@
|
|||||||
# define B3500000 3500000
|
# define B3500000 3500000
|
||||||
# define B4000000 4000000
|
# define B4000000 4000000
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef CRTSCTS
|
||||||
|
# define CRTSCTS 020000000000
|
||||||
|
#endif
|
||||||
|
|
||||||
class PISerial: public PIIODevice {
|
class PIP_EXPORT PISerial: public PIIODevice {
|
||||||
public:
|
public:
|
||||||
// slot is any function format "bool <func>(void*, uchar*, int)"
|
// slot is any function format "bool <func>(void*, uchar*, int)"
|
||||||
// slot_header is any function format "bool <func>(void*, uchar*, uchar*, int)"
|
// slot_header is any function format "bool <func>(void*, uchar*, uchar*, int)"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "picontainers.h"
|
#include "picontainers.h"
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
|
|
||||||
class PISignals
|
class PIP_EXPORT PISignals
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Signal {
|
enum Signal {
|
||||||
|
|||||||
67
pistring.cpp
67
pistring.cpp
@@ -20,6 +20,41 @@
|
|||||||
#include "pistring.h"
|
#include "pistring.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*! \class PIString
|
||||||
|
* \brief String class
|
||||||
|
* \details PIP use this class for use string information.
|
||||||
|
*
|
||||||
|
* \section PIString_sec0 Synopsis
|
||||||
|
* This class based on \a PIVector to store information.
|
||||||
|
* String is a sequence of \a PIChar and can contain multibyte
|
||||||
|
* symbols. Therefore real memory size of string is symbols count * 4.
|
||||||
|
* String can be constucted from many types of data and can be converted
|
||||||
|
* to many types. There are man operators and handly functions to use
|
||||||
|
* string as you wish.
|
||||||
|
*
|
||||||
|
* \section PIString_sec1 To/from data convertions
|
||||||
|
* Most common constructor is \a PIString(const char * str), where "str"
|
||||||
|
* is null-terminated string, e.g. \c "string". This is 7 chars with last char = 0.
|
||||||
|
* Also you can constructs \a PIString from single \a PIChar, \a PIByteArray,
|
||||||
|
* other \a PIString or sequency of the same characters with custom length.\n \n
|
||||||
|
* This class has implicit conversions to <tt>const char * </tt> and
|
||||||
|
* \c std::string. Also there are functions to make same convertions:
|
||||||
|
* * \a data() - to <tt>const char * </tt>,
|
||||||
|
* * \a stdString() - to \c std::string,
|
||||||
|
* * \a toByteArray() - to \a PIByteArray.
|
||||||
|
*
|
||||||
|
* \section PIString_sec2 Numeric operations
|
||||||
|
* You can get symbolic representation of any numeric value with function
|
||||||
|
* \a setNumber(any integer value, int base = 10, bool * ok = 0). Default
|
||||||
|
* arguments are set for decimal base system, but you can choose any system
|
||||||
|
* from 2 to 40. There are the same static functions \a fromNumber(), that
|
||||||
|
* returns \a PIString. \n
|
||||||
|
* Also there is function \a setReadableSize() which is set human-readable
|
||||||
|
* size in bytes, Kb, Mb, Gb or Pb. Static analog is \a readableSize().
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
const char PIString::toBaseN[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
const char PIString::toBaseN[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||||
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||||
@@ -346,25 +381,24 @@ int PIString::lengthAscii() const {
|
|||||||
|
|
||||||
|
|
||||||
const char * PIString::data() const {
|
const char * PIString::data() const {
|
||||||
PIByteArray & d_(*(const_cast<PIByteArray * >(&data_)));
|
data_.clear();
|
||||||
d_.clear();
|
|
||||||
int wc;
|
int wc;
|
||||||
uchar tc;
|
uchar tc;
|
||||||
for (int i = 0, j = 0; i < size_s(); ++i) {
|
for (int i = 0, j = 0; i < size_s(); ++i) {
|
||||||
wc = at(i).toInt();
|
wc = at(i).toInt();
|
||||||
while (tc = wc & 0xFF, tc) {
|
while (tc = wc & 0xFF, tc) {
|
||||||
d_.push_back(uchar(tc)); ++j;
|
data_.push_back(uchar(tc)); ++j;
|
||||||
wc >>= 8;
|
wc >>= 8;
|
||||||
}
|
}
|
||||||
/*if (at(i).isAscii())
|
/*if (at(i).isAscii())
|
||||||
d_.push_back(uchar(at(i).toAscii()));
|
data_.push_back(uchar(at(i).toAscii()));
|
||||||
else {
|
else {
|
||||||
d_.push_back((at(i).toCharPtr()[0])); ++j;
|
data_.push_back((at(i).toCharPtr()[0])); ++j;
|
||||||
d_.push_back((at(i).toCharPtr()[1]));
|
data_.push_back((at(i).toCharPtr()[1]));
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
d_.push_back(uchar('\0'));
|
data_.push_back(uchar('\0'));
|
||||||
return (const char * )d_.data();
|
return (const char * )data_.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -439,25 +473,29 @@ llong PIString::toLLong() const {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PIString & PIString::setReadableSize(long bytes) {
|
PIString & PIString::setReadableSize(llong bytes) {
|
||||||
clear();
|
clear();
|
||||||
if (bytes < 1024) {*this += (PIString::fromNumber(bytes) + " B"); return *this;}
|
if (bytes < 1024) {*this += (PIString::fromNumber(bytes) + " B"); return *this;}
|
||||||
double fres = bytes / 1024.;
|
double fres = bytes / 1024.;
|
||||||
long res = bytes / 1024;
|
llong res = bytes / 1024;
|
||||||
fres -= res;
|
fres -= res;
|
||||||
if (res < 1024) {*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(int(fres * 10)).left(1) + " kB"); return *this;}
|
if (res < 1024) {*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(llong(fres * 10)).left(1) + " kB"); return *this;}
|
||||||
fres = res / 1024.;
|
fres = res / 1024.;
|
||||||
res /= 1024;
|
res /= 1024;
|
||||||
fres -= res;
|
fres -= res;
|
||||||
if (res < 1024) {*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(int(fres * 10)).left(1) + " MB"); return *this;}
|
if (res < 1024) {*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(llong(fres * 10)).left(1) + " MB"); return *this;}
|
||||||
fres = res / 1024.;
|
fres = res / 1024.;
|
||||||
res /= 1024;
|
res /= 1024;
|
||||||
fres -= res;
|
fres -= res;
|
||||||
if (res < 1024) {*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(int(fres * 10)).left(1) + " GB"); return *this;}
|
if (res < 1024) {*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(llong(fres * 10)).left(1) + " GB"); return *this;}
|
||||||
fres = res / 1024.;
|
fres = res / 1024.;
|
||||||
res /= 1024;
|
res /= 1024;
|
||||||
fres -= res;
|
fres -= res;
|
||||||
*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(int(fres * 10)).left(1) + " PB");
|
if (res < 1024) {*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(llong(fres * 10)).left(1) + " TB"); return *this;}
|
||||||
|
fres = res / 1024.;
|
||||||
|
res /= 1024;
|
||||||
|
fres -= res;
|
||||||
|
*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(llong(fres * 10)).left(1) + " PB");
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,6 +514,7 @@ inline char chrLwr(char c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PIStringList& PIStringList::removeDuplicates() {
|
PIStringList& PIStringList::removeDuplicates() {
|
||||||
PIStringList l;
|
PIStringList l;
|
||||||
PIString s;
|
PIString s;
|
||||||
|
|||||||
460
pistring.h
460
pistring.h
@@ -1,3 +1,8 @@
|
|||||||
|
/*! \file pistring.h
|
||||||
|
* \brief String
|
||||||
|
*
|
||||||
|
* This file declare string and string list classes
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
String
|
String
|
||||||
@@ -26,13 +31,14 @@
|
|||||||
|
|
||||||
class PIStringList;
|
class PIStringList;
|
||||||
|
|
||||||
class PIString: public PIVector<PIChar>
|
class PIP_EXPORT PIString: public PIVector<PIChar>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PIString() {piMonitor.strings++; piMonitor.containers--;}
|
//! Contructs an empty string
|
||||||
|
PIString() {reserve(256); piMonitor.strings++; piMonitor.containers--;}
|
||||||
|
|
||||||
//inline PIString & operator +=(const char c) {push_back(c); return *this;}
|
//inline PIString & operator +=(const char c) {push_back(c); return *this;}
|
||||||
PIString & operator +=(const PIChar c) {push_back(c); return *this;}
|
PIString & operator +=(const PIChar & c) {push_back(c); return *this;}
|
||||||
PIString & operator +=(const char * str);
|
PIString & operator +=(const char * str);
|
||||||
PIString & operator +=(const wchar_t * str);
|
PIString & operator +=(const wchar_t * str);
|
||||||
PIString & operator +=(const string & str) {appendFromChars(str.c_str(), str.length()); return *this;}
|
PIString & operator +=(const string & str) {appendFromChars(str.c_str(), str.length()); return *this;}
|
||||||
@@ -43,107 +49,335 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//PIString(const char c) {*this += c;}
|
//PIString(const char c) {*this += c;}
|
||||||
PIString(const PIChar c) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += c;}
|
|
||||||
|
//! Contructs string with single symbol "c"
|
||||||
|
PIString(const PIChar & c) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += c;}
|
||||||
|
|
||||||
|
/*! \brief Contructs string from c-string "str"
|
||||||
|
* \details "str" should be null-terminated\n
|
||||||
|
* Example: \snippet pistring.cpp PIString(char * ) */
|
||||||
PIString(const char * str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
PIString(const char * str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||||
|
|
||||||
|
/*! \brief Contructs string from \c wchar_t c-string "str"
|
||||||
|
* \details "str" should be null-terminated\n
|
||||||
|
* Example: \snippet pistring.cpp PIString(wchar_t * ) */
|
||||||
PIString(const wchar_t * str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
PIString(const wchar_t * str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||||
|
|
||||||
|
//! Contructs string from std::string "str"
|
||||||
PIString(const string & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
PIString(const string & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||||
#ifdef HAS_LOCALE
|
|
||||||
|
#ifdef HAS_LOCALE
|
||||||
PIString(const wstring & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
PIString(const wstring & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//! Contructs string from byte array "ba"
|
||||||
PIString(const PIByteArray & ba) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += ba;}
|
PIString(const PIByteArray & ba) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += ba;}
|
||||||
|
|
||||||
|
/*! \brief Contructs string from "len" characters of buffer "str"
|
||||||
|
* \details Example: \snippet pistring.cpp PIString(char * , int) */
|
||||||
PIString(const char * str, const int len) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += string(str, len);}
|
PIString(const char * str, const int len) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += string(str, len);}
|
||||||
|
|
||||||
|
/*! \brief Contructs string as sequence of characters "c" of buffer with length "len"
|
||||||
|
* \details Example: \snippet pistring.cpp PIString(int, char) */
|
||||||
PIString(const int len, const char c) {reserve(256); piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
|
PIString(const int len, const char c) {reserve(256); piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
|
||||||
|
|
||||||
|
/*! \brief Contructs string as sequence of symbols "c" of buffer with length "len"
|
||||||
|
* \details Example: \snippet pistring.cpp PIString(int, PIChar) */
|
||||||
PIString(const int len, const PIChar & c) {reserve(256); piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
|
PIString(const int len, const PIChar & c) {reserve(256); piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
|
||||||
|
|
||||||
|
//! Contructs string from other string "str"
|
||||||
PIString(const PIString & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
PIString(const PIString & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||||
|
|
||||||
~PIString() {piMonitor.strings--; piMonitor.containers++;}
|
~PIString() {piMonitor.strings--; piMonitor.containers++;}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Return c-string representation of string
|
||||||
|
* \details Converts content of string to c-string and return
|
||||||
|
* pointer to first char. This buffer is valid until new convertion
|
||||||
|
* or execution \a data() or \a toByteArray().\n
|
||||||
|
* Example: \snippet pistring.cpp PIString::char* */
|
||||||
operator const char*() {return data();}
|
operator const char*() {return data();}
|
||||||
|
|
||||||
|
//! Return std::string representation of string
|
||||||
operator const string() {if (size() == 0) return string(); string s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toAscii()); return s;}
|
operator const string() {if (size() == 0) return string(); string s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toAscii()); return s;}
|
||||||
|
|
||||||
|
//! Return symbol at index "pos"
|
||||||
PIChar operator [](const int pos) const {return at(pos);}
|
PIChar operator [](const int pos) const {return at(pos);}
|
||||||
|
|
||||||
|
//! Return const reference symbol at index "pos"
|
||||||
PIChar & operator [](const int pos) {return at(pos);}
|
PIChar & operator [](const int pos) {return at(pos);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator ==(const PIString & str) const;
|
bool operator ==(const PIString & str) const;
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator ==(const PIChar c) const {return *this == PIString(c);}
|
bool operator ==(const PIChar c) const {return *this == PIString(c);}
|
||||||
//inline bool operator ==(const char c) const {return *this == PIString(c);}
|
//inline bool operator ==(const char c) const {return *this == PIString(c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator ==(const char * str) const {return *this == PIString(str);}
|
bool operator ==(const char * str) const {return *this == PIString(str);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator ==(const string & str) const {return *this == PIString(str);}
|
bool operator ==(const string & str) const {return *this == PIString(str);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator !=(const PIString & str) const;
|
bool operator !=(const PIString & str) const;
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator !=(const PIChar c) const {return *this != PIString(c);}
|
bool operator !=(const PIChar c) const {return *this != PIString(c);}
|
||||||
//inline bool operator !=(const char c) const {return *this != PIString(c);}
|
//inline bool operator !=(const char c) const {return *this != PIString(c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator !=(const char * str) const {return *this != PIString(str);}
|
bool operator !=(const char * str) const {return *this != PIString(str);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator !=(const string & str) const {return *this != PIString(str);}
|
bool operator !=(const string & str) const {return *this != PIString(str);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator <(const PIString & str) const;
|
bool operator <(const PIString & str) const;
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator <(const PIChar c) const {return *this < PIString(c);}
|
bool operator <(const PIChar c) const {return *this < PIString(c);}
|
||||||
//inline bool operator <(const char c) const {return *this < PIString(c);}
|
//inline bool operator <(const char c) const {return *this < PIString(c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator <(const char * str) const {return *this < PIString(str);}
|
bool operator <(const char * str) const {return *this < PIString(str);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator <(const string & str) const {return *this < PIString(str);}
|
bool operator <(const string & str) const {return *this < PIString(str);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator >(const PIString & str) const;
|
bool operator >(const PIString & str) const;
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator >(const PIChar c) const {return *this > PIString(c);}
|
bool operator >(const PIChar c) const {return *this > PIString(c);}
|
||||||
//inline bool operator >(const char c) const {return *this > PIString(c);}
|
//inline bool operator >(const char c) const {return *this > PIString(c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator >(const char * str) const {return *this > PIString(str);}
|
bool operator >(const char * str) const {return *this > PIString(str);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator >(const string & str) const {return *this > PIString(str);}
|
bool operator >(const string & str) const {return *this > PIString(str);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator <=(const PIString & str) const {return !(*this > str);}
|
bool operator <=(const PIString & str) const {return !(*this > str);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator <=(const PIChar c) const {return *this <= PIString(c);}
|
bool operator <=(const PIChar c) const {return *this <= PIString(c);}
|
||||||
//inline bool operator <=(const char c) const {return *this <= PIString(c);}
|
//inline bool operator <=(const char c) const {return *this <= PIString(c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator <=(const char * str) const {return *this <= PIString(str);}
|
bool operator <=(const char * str) const {return *this <= PIString(str);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator <=(const string & str) const {return *this <= PIString(str);}
|
bool operator <=(const string & str) const {return *this <= PIString(str);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator >=(const PIString & str) const {return !(*this < str);}
|
bool operator >=(const PIString & str) const {return !(*this < str);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator >=(const PIChar c) const {return *this >= PIString(c);}
|
bool operator >=(const PIChar c) const {return *this >= PIString(c);}
|
||||||
//inline bool operator >=(const char c) const {return *this >= PIString(c);}
|
//inline bool operator >=(const char c) const {return *this >= PIString(c);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator >=(const char * str) const {return *this >= PIString(str);}
|
bool operator >=(const char * str) const {return *this >= PIString(str);}
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator >=(const string & str) const {return *this >= PIString(str);}
|
bool operator >=(const string & str) const {return *this >= PIString(str);}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Append string "str" at the end of string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::<<(PIString) */
|
||||||
PIString & operator <<(const PIString & str) {*this += str; return *this;}
|
PIString & operator <<(const PIString & str) {*this += str; return *this;}
|
||||||
//inline PIString & operator <<(const char c) {*this += c; return *this;}
|
//inline PIString & operator <<(const char c) {*this += c; return *this;}
|
||||||
PIString & operator <<(const PIChar c) {*this += c; return *this;}
|
|
||||||
|
/*! \brief Append symbol "c" at the end of string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::<<(PIChar) */
|
||||||
|
PIString & operator <<(const PIChar & c) {*this += c; return *this;}
|
||||||
|
|
||||||
|
/*! \brief Append c-string "str" at the end of string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::<<(char * ) */
|
||||||
PIString & operator <<(const char * str) {*this += str; return *this;}
|
PIString & operator <<(const char * str) {*this += str; return *this;}
|
||||||
|
|
||||||
|
/*! \brief Append \c wchar_t c-string "str" at the end of string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::<<(wchar_t * ) */
|
||||||
PIString & operator <<(const wchar_t * str) {*this += str; return *this;}
|
PIString & operator <<(const wchar_t * str) {*this += str; return *this;}
|
||||||
|
|
||||||
|
//! Append std::string "str" at the end of string
|
||||||
PIString & operator <<(const string & str) {*this += str; return *this;}
|
PIString & operator <<(const string & str) {*this += str; return *this;}
|
||||||
|
|
||||||
|
/*! \brief Append string representation of "num" at the end of string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
||||||
PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;}
|
PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Append string representation of "num" at the end of string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
||||||
PIString & operator <<(const short & num) {*this += PIString::fromNumber(num); return *this;}
|
PIString & operator <<(const short & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Append string representation of "num" at the end of string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
||||||
PIString & operator <<(const long & num) {*this += PIString::fromNumber(num); return *this;}
|
PIString & operator <<(const long & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Append string representation of "num" at the end of string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
||||||
PIString & operator <<(const float & num) {*this += PIString::fromNumber(num); return *this;}
|
PIString & operator <<(const float & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Append string representation of "num" at the end of string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
||||||
PIString & operator <<(const double & num) {*this += PIString::fromNumber(num); return *this;}
|
PIString & operator <<(const double & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Return part of string from symbol at index "start" and maximum length "len"
|
||||||
|
* \details All variants demonstrated in example: \snippet pistring.cpp PIString::mid
|
||||||
|
* \sa \a left(), \a right() */
|
||||||
PIString mid(const int start, const int len = -1) const;
|
PIString mid(const int start, const int len = -1) const;
|
||||||
|
|
||||||
|
/*! \brief Return part of string from left and maximum length "len"
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::left
|
||||||
|
* \sa \a mid(), \a right() */
|
||||||
PIString left(const int len) const {return len <= 0 ? PIString() : mid(0, len);}
|
PIString left(const int len) const {return len <= 0 ? PIString() : mid(0, len);}
|
||||||
|
|
||||||
|
/*! \brief Return part of string from right and maximum length "len"
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::right
|
||||||
|
* \sa \a mid(), \a left() */
|
||||||
PIString right(const int len) const {return len <= 0 ? PIString() : mid(size() - len, len);}
|
PIString right(const int len) const {return len <= 0 ? PIString() : mid(size() - len, len);}
|
||||||
|
|
||||||
|
/*! \brief Remove part of string from symbol as index "start" and maximum length "len"
|
||||||
|
* and return this string
|
||||||
|
* \details All variants demonstrated in example: \snippet pistring.cpp PIString::cutMid
|
||||||
|
* \sa \a cutLeft(), \a cutRight() */
|
||||||
PIString & cutMid(const int start, const int len);
|
PIString & cutMid(const int start, const int len);
|
||||||
|
|
||||||
|
/*! \brief Remove part of string from left and maximum length "len" and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::cutLeft
|
||||||
|
* \sa \a cutMid(), \a cutRight() */
|
||||||
PIString & cutLeft(const int len) {return len <= 0 ? *this : cutMid(0, len);}
|
PIString & cutLeft(const int len) {return len <= 0 ? *this : cutMid(0, len);}
|
||||||
|
|
||||||
|
/*! \brief Remove part of string from right and maximum length "len" and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::cutRight
|
||||||
|
* \sa \a cutMid(), \a cutLeft() */
|
||||||
PIString & cutRight(const int len) {return len <= 0 ? *this : cutMid(size() - len, len);}
|
PIString & cutRight(const int len) {return len <= 0 ? *this : cutMid(size() - len, len);}
|
||||||
|
|
||||||
|
/*! \brief Remove spaces at the start and at the end of string and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::trim
|
||||||
|
* \sa \a trimmed() */
|
||||||
PIString & trim();
|
PIString & trim();
|
||||||
|
|
||||||
|
/*! \brief Return copy of this string without spaces at the start and at the end
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::trimmed
|
||||||
|
* \sa \a trim() */
|
||||||
PIString trimmed() const;
|
PIString trimmed() const;
|
||||||
|
|
||||||
|
/*! \brief Replace part of string from index "from" and maximum length "len"
|
||||||
|
* with string "with" and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::replace_0
|
||||||
|
* \sa \a replaced(), \a replaceAll() */
|
||||||
PIString & replace(const int from, const int count, const PIString & with);
|
PIString & replace(const int from, const int count, const PIString & with);
|
||||||
|
|
||||||
|
/*! \brief Replace part copy of this string from index "from" and maximum length "len"
|
||||||
|
* with string "with" and return copied string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::replaced_0
|
||||||
|
* \sa \a replace(), \a replaceAll() */
|
||||||
PIString replaced(const int from, const int count, const PIString & with) const {PIString str(*this); str.replace(from, count, with); return str;}
|
PIString replaced(const int from, const int count, const PIString & with) const {PIString str(*this); str.replace(from, count, with); return str;}
|
||||||
|
|
||||||
|
/*! \brief Replace first founded substring "what" with string "with" and return this string
|
||||||
|
* \details If "ok" is not null, it set to "true" if something was replaced\n
|
||||||
|
* Example: \snippet pistring.cpp PIString::replace_1
|
||||||
|
* \sa \a replaced(), \a replaceAll() */
|
||||||
PIString & replace(const PIString & what, const PIString & with, bool * ok = 0);
|
PIString & replace(const PIString & what, const PIString & with, bool * ok = 0);
|
||||||
|
|
||||||
|
/*! \brief Replace first founded substring "what" with string "with" and return copied string
|
||||||
|
* \details If "ok" is not null, it set to "true" if something was replaced\n
|
||||||
|
* Example: \snippet pistring.cpp PIString::replaced_1
|
||||||
|
* \sa \a replaced(), \a replaceAll() */
|
||||||
PIString replaced(const PIString & what, const PIString & with, bool * ok = 0) const {PIString str(*this); str.replace(what, with, ok); return str;}
|
PIString replaced(const PIString & what, const PIString & with, bool * ok = 0) const {PIString str(*this); str.replace(what, with, ok); return str;}
|
||||||
|
|
||||||
|
/*! \brief Replace all founded substrings "what" with strings "with" and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::replaceAll
|
||||||
|
* \sa \a replace(), \a replaced() */
|
||||||
PIString & replaceAll(const PIString & what, const PIString & with);
|
PIString & replaceAll(const PIString & what, const PIString & with);
|
||||||
PIString replaceAll(const PIString & what, const PIString & with) const {PIString str(*this); str.replaceAll(what, with); return str;}
|
PIString replaceAll(const PIString & what, const PIString & with) const {PIString str(*this); str.replaceAll(what, with); return str;}
|
||||||
|
|
||||||
|
/*! \brief Insert symbol "c" after index "index" and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::insert_0 */
|
||||||
PIString & insert(const int index, const PIChar & c) {PIVector<PIChar>::insert(index, c); return *this;}
|
PIString & insert(const int index, const PIChar & c) {PIVector<PIChar>::insert(index, c); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Insert symbol "c" after index "index" and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::insert_1 */
|
||||||
PIString & insert(const int index, const char & c) {return insert(index, PIChar(c));}
|
PIString & insert(const int index, const char & c) {return insert(index, PIChar(c));}
|
||||||
|
|
||||||
|
/*! \brief Insert string "str" after index "index" and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::insert_2 */
|
||||||
PIString & insert(const int index, const PIString & str);
|
PIString & insert(const int index, const PIString & str);
|
||||||
|
|
||||||
|
/*! \brief Insert string "str" after index "index" and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::insert_2 */
|
||||||
PIString & insert(const int index, const char * c) {return insert(index, PIString(c));}
|
PIString & insert(const int index, const char * c) {return insert(index, PIString(c));}
|
||||||
|
|
||||||
|
/*! \brief Enlarge string to length "len" by addition sequence of symbols
|
||||||
|
* "c" at the end of string, and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::expandRightTo
|
||||||
|
* \sa \a expandLeftTo() */
|
||||||
PIString & expandRightTo(const int len, const PIChar & c) {if (len > length()) resize(len, c); return *this;}
|
PIString & expandRightTo(const int len, const PIChar & c) {if (len > length()) resize(len, c); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Enlarge string to length "len" by addition sequence of symbols
|
||||||
|
* "c" at the beginning of string, and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::expandLeftTo
|
||||||
|
* \sa \a expandRightTo() */
|
||||||
PIString & expandLeftTo(const int len, const PIChar & c) {if (len > length()) insert(0, PIString(len - length(), c)); return *this;}
|
PIString & expandLeftTo(const int len, const PIChar & c) {if (len > length()) insert(0, PIString(len - length(), c)); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Reverse string and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::reverse
|
||||||
|
* \sa \a reversed() */
|
||||||
PIString & reverse() {PIString str(*this); clear(); piForeachR (const PIChar & c, str) push_back(c); return *this;}
|
PIString & reverse() {PIString str(*this); clear(); piForeachR (const PIChar & c, str) push_back(c); return *this;}
|
||||||
|
|
||||||
|
/*! \brief Reverse copy of this string and return it
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::reversed
|
||||||
|
* \sa \a reverse() */
|
||||||
PIString reversed() const {PIString str(*this); str.reverse(); return str;}
|
PIString reversed() const {PIString str(*this); str.reverse(); return str;}
|
||||||
|
|
||||||
//const char * data() {return convertToStd().c_str();}
|
//const char * data() {return convertToStd().c_str();}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Return real bytes count of this string
|
||||||
|
* \details It`s equivalent length os char sequence
|
||||||
|
* returned by function \a data() \n
|
||||||
|
* Example: \snippet pistring.cpp PIString::lengthAscii
|
||||||
|
* \sa \a data() */
|
||||||
int lengthAscii() const;
|
int lengthAscii() const;
|
||||||
|
|
||||||
|
/*! \brief Return \c char * representation of this string
|
||||||
|
* \details This function fill buffer by sequence
|
||||||
|
* of chars. Minimum length of this buffer is count
|
||||||
|
* of symbols. Returned \c char * is valid until next
|
||||||
|
* execution of this function.\n
|
||||||
|
* Example: \snippet pistring.cpp PIString::data
|
||||||
|
* \sa \a lengthAscii() */
|
||||||
const char * data() const;
|
const char * data() const;
|
||||||
|
|
||||||
|
//! \brief Return \c std::string representation of this string
|
||||||
const string stdString() const {return convertToStd();}
|
const string stdString() const {return convertToStd();}
|
||||||
#ifdef HAS_LOCALE
|
#ifdef HAS_LOCALE
|
||||||
wstring stdWString() const {return convertToWString();}
|
wstring stdWString() const {return convertToWString();}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//! \brief Return \a PIByteArray contains \a data() of this string
|
||||||
PIByteArray toByteArray() const {const char * d = data(); return PIByteArray(d, lengthAscii());}
|
PIByteArray toByteArray() const {const char * d = data(); return PIByteArray(d, lengthAscii());}
|
||||||
|
|
||||||
|
/*! \brief Split string with delimiter "delim" to \a PIStringList and return it
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::split */
|
||||||
PIStringList split(const PIString & delim) const;
|
PIStringList split(const PIString & delim) const;
|
||||||
|
|
||||||
|
|
||||||
|
//! \brief Convert each symbol in copyed string to upper case and return it
|
||||||
PIString toUpperCase() const;
|
PIString toUpperCase() const;
|
||||||
|
|
||||||
|
//! \brief Convert each symbol in copyed string to lower case and return it
|
||||||
PIString toLowerCase() const;
|
PIString toLowerCase() const;
|
||||||
#ifdef HAS_LOCALE
|
#ifdef HAS_LOCALE
|
||||||
PIString toNativeDecimalPoints() const {PIString s(*this); if (currentLocale == 0) return s; return s.replaceAll(".", currentLocale->decimal_point);}
|
PIString toNativeDecimalPoints() const {PIString s(*this); if (currentLocale == 0) return s; return s.replaceAll(".", currentLocale->decimal_point);}
|
||||||
@@ -151,60 +385,199 @@ public:
|
|||||||
PIString toNativeDecimalPoints() const {PIString s(*this); return s;}
|
PIString toNativeDecimalPoints() const {PIString s(*this); return s;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//! \brief Search substring "str" from symbol at index "start" and return first occur position
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::find
|
||||||
int find(const char str, const int start = 0) const;
|
int find(const char str, const int start = 0) const;
|
||||||
|
|
||||||
|
//! \brief Search substring "str" from symbol at index "start" and return first occur position
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::find
|
||||||
int find(const PIString str, const int start = 0) const;
|
int find(const PIString str, const int start = 0) const;
|
||||||
|
|
||||||
|
//! \brief Search substring "str" from symbol at index "start" and return first occur position
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::find
|
||||||
int find(const char * str, const int start = 0) const {return find(PIString(str), start);}
|
int find(const char * str, const int start = 0) const {return find(PIString(str), start);}
|
||||||
|
|
||||||
|
//! \brief Search substring "str" from symbol at index "start" and return first occur position
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::find
|
||||||
int find(const string str, const int start = 0) const {return find(PIString(str), start);}
|
int find(const string str, const int start = 0) const {return find(PIString(str), start);}
|
||||||
|
|
||||||
|
//! \brief Search substring "str" from symbol at index "start" and return last occur position
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::findLast
|
||||||
int findLast(const char str, const int start = 0) const;
|
int findLast(const char str, const int start = 0) const;
|
||||||
|
|
||||||
|
//! \brief Search substring "str" from symbol at index "start" and return last occur position
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::findLast
|
||||||
int findLast(const PIString str, const int start = 0) const;
|
int findLast(const PIString str, const int start = 0) const;
|
||||||
|
|
||||||
|
//! \brief Search substring "str" from symbol at index "start" and return last occur position
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::findLast
|
||||||
int findLast(const char * str, const int start = 0) const {return findLast(PIString(str), start);}
|
int findLast(const char * str, const int start = 0) const {return findLast(PIString(str), start);}
|
||||||
|
|
||||||
|
//! \brief Search substring "str" from symbol at index "start" and return last occur position
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::findLast
|
||||||
int findLast(const string str, const int start = 0) const {return findLast(PIString(str), start);}
|
int findLast(const string str, const int start = 0) const {return findLast(PIString(str), start);}
|
||||||
|
|
||||||
|
|
||||||
|
//! \brief Return symbols length of string
|
||||||
int length() const {return size();}
|
int length() const {return size();}
|
||||||
|
|
||||||
|
//! \brief Return \c true if string is empty, i.e. length = 0
|
||||||
bool isEmpty() const {return (size() == 0 || *this == "");}
|
bool isEmpty() const {return (size() == 0 || *this == "");}
|
||||||
|
|
||||||
|
|
||||||
|
//! \brief Return \c true if string equal "true" or "on" or positive numeric value
|
||||||
bool toBool() const {PIString s(*this); if (atof(s.toNativeDecimalPoints().data()) > 0. || s.trimmed().toLowerCase() == "true" || s.trimmed().toLowerCase() == "on") return true; return false;}
|
bool toBool() const {PIString s(*this); if (atof(s.toNativeDecimalPoints().data()) > 0. || s.trimmed().toLowerCase() == "true" || s.trimmed().toLowerCase() == "on") return true; return false;}
|
||||||
|
|
||||||
|
//! \brief Return \c char numeric value of string
|
||||||
char toChar() const;
|
char toChar() const;
|
||||||
|
|
||||||
|
//! \brief Return \c short numeric value of string in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::toNumber
|
||||||
short toShort(int base = -1, bool * ok = 0) const {return short(toNumberBase(*this, base, ok));}
|
short toShort(int base = -1, bool * ok = 0) const {return short(toNumberBase(*this, base, ok));}
|
||||||
|
|
||||||
|
//! \brief Return \c ushort numeric value of string in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::toNumber
|
||||||
ushort toUShort(int base = -1, bool * ok = 0) const {return ushort(toNumberBase(*this, base, ok));}
|
ushort toUShort(int base = -1, bool * ok = 0) const {return ushort(toNumberBase(*this, base, ok));}
|
||||||
|
|
||||||
|
//! \brief Return \c int numeric value of string in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::toNumber
|
||||||
int toInt(int base = -1, bool * ok = 0) const {return int(toNumberBase(*this, base, ok));}
|
int toInt(int base = -1, bool * ok = 0) const {return int(toNumberBase(*this, base, ok));}
|
||||||
|
|
||||||
|
//! \brief Return \c uint numeric value of string in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::toNumber
|
||||||
uint toUInt(int base = -1, bool * ok = 0) const {return uint(toNumberBase(*this, base, ok));}
|
uint toUInt(int base = -1, bool * ok = 0) const {return uint(toNumberBase(*this, base, ok));}
|
||||||
|
|
||||||
|
//! \brief Return \c long numeric value of string in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::toNumber
|
||||||
long toLong(int base = -1, bool * ok = 0) const {return long(toNumberBase(*this, base, ok));}
|
long toLong(int base = -1, bool * ok = 0) const {return long(toNumberBase(*this, base, ok));}
|
||||||
|
|
||||||
|
//! \brief Return \c ulong numeric value of string in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::toNumber
|
||||||
ulong toULong(int base = -1, bool * ok = 0) const {return ulong(toNumberBase(*this, base, ok));}
|
ulong toULong(int base = -1, bool * ok = 0) const {return ulong(toNumberBase(*this, base, ok));}
|
||||||
|
|
||||||
|
//! \brief Return \c llong numeric value of string in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::toNumber
|
||||||
llong toLLong(int base = -1, bool * ok = 0) const {return toNumberBase(*this, base, ok);}
|
llong toLLong(int base = -1, bool * ok = 0) const {return toNumberBase(*this, base, ok);}
|
||||||
|
|
||||||
|
//! \brief Return \c ullong numeric value of string in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::toNumber
|
||||||
ullong toULLong(int base = -1, bool * ok = 0) const {return ullong(toNumberBase(*this, base, ok));}
|
ullong toULLong(int base = -1, bool * ok = 0) const {return ullong(toNumberBase(*this, base, ok));}
|
||||||
|
|
||||||
|
//! \brief Return \c float numeric value of string
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::toFloat
|
||||||
float toFloat() const {PIString s(*this); return (float)atof(s.toNativeDecimalPoints().data());}
|
float toFloat() const {PIString s(*this); return (float)atof(s.toNativeDecimalPoints().data());}
|
||||||
|
|
||||||
|
//! \brief Return \c double numeric value of string
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::toFloat
|
||||||
double toDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());}
|
double toDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());}
|
||||||
|
|
||||||
|
//! \brief Return \c ldouble numeric value of string
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::toFloat
|
||||||
ldouble toLDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());}
|
ldouble toLDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());}
|
||||||
|
|
||||||
//inline PIString & setNumber(const char value) {clear(); *this += itos(value); return *this;}
|
//inline PIString & setNumber(const char value) {clear(); *this += itos(value); return *this;}
|
||||||
|
|
||||||
|
//! \brief Set string content to numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::setNumber
|
||||||
PIString & setNumber(const short value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
PIString & setNumber(const short value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||||
|
|
||||||
|
//! \brief Set string content to numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::setNumber
|
||||||
PIString & setNumber(const ushort value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
PIString & setNumber(const ushort value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||||
|
|
||||||
|
//! \brief Set string content to numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::setNumber
|
||||||
PIString & setNumber(const int value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
PIString & setNumber(const int value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||||
|
|
||||||
|
//! \brief Set string content to numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::setNumber
|
||||||
PIString & setNumber(const uint value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
PIString & setNumber(const uint value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||||
|
|
||||||
|
//! \brief Set string content to numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::setNumber
|
||||||
PIString & setNumber(const long value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
PIString & setNumber(const long value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||||
|
|
||||||
|
//! \brief Set string content to numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::setNumber
|
||||||
PIString & setNumber(const ulong value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
PIString & setNumber(const ulong value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||||
PIString & setNumber(const llong value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
|
||||||
PIString & setNumber(const ullong value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
//! \brief Set string content to numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::setNumber
|
||||||
|
PIString & setNumber(const llong & value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||||
|
|
||||||
|
//! \brief Set string content to numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::setNumber
|
||||||
|
PIString & setNumber(const ullong & value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||||
|
|
||||||
|
//! \brief Set string content to numeric representation of "value"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::setFloat
|
||||||
PIString & setNumber(const float value) {clear(); *this += ftos(value); return *this;}
|
PIString & setNumber(const float value) {clear(); *this += ftos(value); return *this;}
|
||||||
PIString & setNumber(const double value) {clear(); *this += dtos(value); return *this;}
|
|
||||||
PIString & setNumber(const ldouble value) {clear(); *this += dtos(value); return *this;}
|
//! \brief Set string content to numeric representation of "value"
|
||||||
PIString & setReadableSize(long bytes);
|
//! \details Example: \snippet pistring.cpp PIString::setFloat
|
||||||
|
PIString & setNumber(const double & value) {clear(); *this += dtos(value); return *this;}
|
||||||
|
|
||||||
|
//! \brief Set string content to numeric representation of "value"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::setFloat
|
||||||
|
PIString & setNumber(const ldouble & value) {clear(); *this += dtos(value); return *this;}
|
||||||
|
|
||||||
|
//! \brief Set string content to human readable size in B/kB/MB/GB/TB
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::setReadableSize
|
||||||
|
PIString & setReadableSize(llong bytes);
|
||||||
|
|
||||||
//inline static PIString fromNumber(const char value) {return PIString(itos(value));}
|
//inline static PIString fromNumber(const char value) {return PIString(itos(value));}
|
||||||
|
|
||||||
|
//! \brief Return string contains numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::fromNumber
|
||||||
static PIString fromNumber(const short value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
static PIString fromNumber(const short value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||||
|
|
||||||
|
//! \brief Return string contains numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::fromNumber
|
||||||
static PIString fromNumber(const ushort value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
static PIString fromNumber(const ushort value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||||
|
|
||||||
|
//! \brief Return string contains numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::fromNumber
|
||||||
static PIString fromNumber(const int value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
static PIString fromNumber(const int value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||||
|
|
||||||
|
//! \brief Return string contains numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::fromNumber
|
||||||
static PIString fromNumber(const uint value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
static PIString fromNumber(const uint value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||||
|
|
||||||
|
//! \brief Return string contains numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::fromNumber
|
||||||
static PIString fromNumber(const long value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
static PIString fromNumber(const long value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||||
|
|
||||||
|
//! \brief Return string contains numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::fromNumber
|
||||||
static PIString fromNumber(const ulong value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
static PIString fromNumber(const ulong value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||||
static PIString fromNumber(const llong value, int base = 10, bool * ok = 0) {return fromNumberBase(value, base, ok);}
|
|
||||||
static PIString fromNumber(const ullong value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
//! \brief Return string contains numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::fromNumber
|
||||||
|
static PIString fromNumber(const llong & value, int base = 10, bool * ok = 0) {return fromNumberBase(value, base, ok);}
|
||||||
|
|
||||||
|
//! \brief Return string contains numeric representation of "value" in base "base"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::fromNumber
|
||||||
|
static PIString fromNumber(const ullong & value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||||
|
|
||||||
|
//! \brief Return string contains numeric representation of "value"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::fromFloat
|
||||||
static PIString fromNumber(const float value) {return PIString(ftos(value));}
|
static PIString fromNumber(const float value) {return PIString(ftos(value));}
|
||||||
static PIString fromNumber(const double value) {return PIString(dtos(value));}
|
|
||||||
static PIString fromNumber(const ldouble value) {return PIString(dtos(value));}
|
//! \brief Return string contains numeric representation of "value"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::fromFloat
|
||||||
|
static PIString fromNumber(const double & value) {return PIString(dtos(value));}
|
||||||
|
|
||||||
|
//! \brief Return string contains numeric representation of "value"
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::fromFloat
|
||||||
|
static PIString fromNumber(const ldouble & value) {return PIString(dtos(value));}
|
||||||
|
|
||||||
|
//! \brief Return "true" or "false"
|
||||||
static PIString fromBool(const bool value) {return PIString(value ? "true" : "false");}
|
static PIString fromBool(const bool value) {return PIString(value ? "true" : "false");}
|
||||||
static PIString readableSize(long bytes) {PIString s; s.setReadableSize(bytes); return s;}
|
|
||||||
|
//! \brief Return string contains human readable size in B/kB/MB/GB/TB
|
||||||
|
//! \details Example: \snippet pistring.cpp PIString::readableSize
|
||||||
|
static PIString readableSize(llong bytes) {PIString s; s.setReadableSize(bytes); return s;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const char toBaseN[];
|
static const char toBaseN[];
|
||||||
@@ -254,45 +627,92 @@ private:
|
|||||||
wstring convertToWString() const {wstring s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toWChar()); return s;}
|
wstring convertToWString() const {wstring s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toWChar()); return s;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PIByteArray data_;
|
mutable PIByteArray data_;
|
||||||
//string std_string;
|
//string std_string;
|
||||||
//wstring std_wstring;
|
//wstring std_wstring;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//! \relatesalso PIString \brief Output operator to std::ostream (cout)
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIString & v) {for (int i = 0; i < v.length(); ++i) s << v[i]; return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIString & v) {for (int i = 0; i < v.length(); ++i) s << v[i]; return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIString \brief Input operator from std::istream (cin)
|
||||||
inline std::istream & operator >>(std::istream & s, PIString & v) {string ss; s >> ss; v << PIString(ss); return s;}
|
inline std::istream & operator >>(std::istream & s, PIString & v) {string ss; s >> ss; v << PIString(ss); return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIString \relatesalso PICout \brief Output operator to PICout
|
||||||
|
inline PICout operator <<(PICout s, const PIString & v) {s.space(); s.quote(); s.setControl(0, true); for (int i = 0; i < v.length(); ++i) s << v[i]; s.restoreControl(); s.quote(); return s;}
|
||||||
|
|
||||||
|
|
||||||
|
//! \relatesalso PIString \relatesalso PIByteArray \brief Output operator to PIByteArray
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const PIString & v) {s << v.size_s(); for (int i = 0; i < v.length(); ++i) s << v[i]; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIString & v) {s << v.size_s(); for (int i = 0; i < v.length(); ++i) s << v[i]; return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIString \relatesalso PIByteArray \brief Input operator from PIByteArray
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, PIString & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIString & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||||
|
|
||||||
|
|
||||||
|
//! \relatesalso PIString \brief Return concatenated string
|
||||||
inline PIString operator +(const PIString & str, const PIString & f) {PIString s(str); s += f; return s;}
|
inline PIString operator +(const PIString & str, const PIString & f) {PIString s(str); s += f; return s;}
|
||||||
|
|
||||||
//inline PIString operator +(const PIString & f, const char c) {PIString s(f); s.push_back(c); return s;}
|
//inline PIString operator +(const PIString & f, const char c) {PIString s(f); s.push_back(c); return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIString \brief Return concatenated string
|
||||||
inline PIString operator +(const PIString & f, const char * str) {PIString s(f); s += str; return s;}
|
inline PIString operator +(const PIString & f, const char * str) {PIString s(f); s += str; return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIString \brief Return concatenated string
|
||||||
inline PIString operator +(const PIString & f, const string & str) {PIString s(f); s += str; return s;}
|
inline PIString operator +(const PIString & f, const string & str) {PIString s(f); s += str; return s;}
|
||||||
|
|
||||||
//inline PIString operator +(const char c, const PIString & f) {return PIString(c) + f;}
|
//inline PIString operator +(const char c, const PIString & f) {return PIString(c) + f;}
|
||||||
|
|
||||||
|
//! \relatesalso PIString \brief Return concatenated string
|
||||||
inline PIString operator +(const char * str, const PIString & f) {return PIString(str) + f;}
|
inline PIString operator +(const char * str, const PIString & f) {return PIString(str) + f;}
|
||||||
|
|
||||||
|
//! \relatesalso PIString \brief Return concatenated string
|
||||||
inline PIString operator +(const string & str, const PIString & f) {return PIString(str) + f;}
|
inline PIString operator +(const string & str, const PIString & f) {return PIString(str) + f;}
|
||||||
|
|
||||||
inline char chrUpr(char c);
|
inline char chrUpr(char c);
|
||||||
inline char chrLwr(char c);
|
inline char chrLwr(char c);
|
||||||
|
|
||||||
class PIStringList: public PIVector<PIString>
|
|
||||||
|
/*!\brief Strings array class
|
||||||
|
* \details This class is based on \a PIVector<PIString> and
|
||||||
|
* expand it functionality. */
|
||||||
|
class PIP_EXPORT PIStringList: public PIVector<PIString>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
//! Contructs empty strings list
|
||||||
PIStringList() {;}
|
PIStringList() {;}
|
||||||
|
|
||||||
|
//! Contructs strings list with one string "str"
|
||||||
PIStringList(const PIString & str) {push_back(str);}
|
PIStringList(const PIString & str) {push_back(str);}
|
||||||
|
|
||||||
|
//! Contructs empty strings list with strings "s0" and "s1"
|
||||||
PIStringList(const PIString & s0, const PIString & s1) {push_back(s0); push_back(s1);}
|
PIStringList(const PIString & s0, const PIString & s1) {push_back(s0); push_back(s1);}
|
||||||
|
|
||||||
|
//! Contructs empty strings list with strings "s0", "s1" and "s2"
|
||||||
PIStringList(const PIString & s0, const PIString & s1, const PIString & s2) {push_back(s0); push_back(s1); push_back(s2);}
|
PIStringList(const PIString & s0, const PIString & s1, const PIString & s2) {push_back(s0); push_back(s1); push_back(s2);}
|
||||||
|
|
||||||
|
//! Contructs empty strings list with strings "s0", "s1", "s2" and "s3"
|
||||||
PIStringList(const PIString & s0, const PIString & s1, const PIString & s2, const PIString & s3) {push_back(s0); push_back(s1); push_back(s2); push_back(s3);}
|
PIStringList(const PIString & s0, const PIString & s1, const PIString & s2, const PIString & s3) {push_back(s0); push_back(s1); push_back(s2); push_back(s3);}
|
||||||
|
|
||||||
|
|
||||||
|
//! \brief Join all strings in one with delimiter "delim" and return it
|
||||||
|
//! \details Example: \snippet pistring.cpp PIStringList::join
|
||||||
PIString join(const PIString & delim) const {PIString s; for (uint i = 0; i < size(); ++i) {s += at(i); if (i < size() - 1) s += delim;} return s;}
|
PIString join(const PIString & delim) const {PIString s; for (uint i = 0; i < size(); ++i) {s += at(i); if (i < size() - 1) s += delim;} return s;}
|
||||||
|
|
||||||
|
//! \brief Remove all strings equal "value" and return this
|
||||||
|
//! \details Example: \snippet pistring.cpp PIStringList::removeStrings
|
||||||
PIStringList & removeStrings(const PIString & value) {for (uint i = 0; i < size(); ++i) {if (at(i) == value) {remove(i); --i;}} return *this;}
|
PIStringList & removeStrings(const PIString & value) {for (uint i = 0; i < size(); ++i) {if (at(i) == value) {remove(i); --i;}} return *this;}
|
||||||
|
|
||||||
PIStringList & remove(uint num) {PIVector<PIString>::remove(num); return *this;}
|
PIStringList & remove(uint num) {PIVector<PIString>::remove(num); return *this;}
|
||||||
PIStringList & remove(uint num, uint count) {PIVector<PIString>::remove(num, count); return *this;}
|
PIStringList & remove(uint num, uint count) {PIVector<PIString>::remove(num, count); return *this;}
|
||||||
|
|
||||||
|
//! \brief Remove duplicated strings and return this
|
||||||
|
//! \details Example: \snippet pistring.cpp PIStringList::removeDuplicates
|
||||||
PIStringList & removeDuplicates();
|
PIStringList & removeDuplicates();
|
||||||
|
|
||||||
|
//! Return sum of lengths of all strings
|
||||||
uint contentSize() {uint s = 0; for (uint i = 0; i < size(); ++i) s += at(i).size(); return s;}
|
uint contentSize() {uint s = 0; for (uint i = 0; i < size(); ++i) s += at(i).size(); return s;}
|
||||||
|
|
||||||
PIStringList & operator <<(const PIString & str) {push_back(str); return *this;}
|
PIStringList & operator <<(const PIString & str) {push_back(str); return *this;}
|
||||||
@@ -308,6 +728,10 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! \relatesalso PIStringList \brief Output operator to std::ostream (cout)
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIStringList & v) {s << "{"; for (uint i = 0; i < v.size(); ++i) {s << '\"' << v[i] << '\"'; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIStringList & v) {s << "{"; for (uint i = 0; i < v.size(); ++i) {s << '\"' << v[i] << '\"'; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIStringList \relatesalso PICout \brief Output operator to PICout
|
||||||
|
inline PICout operator <<(PICout s, const PIStringList & v) {s.space(); s.setControl(0, true); s << "{"; for (uint i = 0; i < v.size(); ++i) {s << '\"' << v[i] << '\"'; if (i < v.size() - 1) s << ", ";} s << "}"; s.restoreControl(); return s;}
|
||||||
|
|
||||||
#endif // PISTRING_H
|
#endif // PISTRING_H
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ bool PISystemMonitor::startOnProcess(int pID) {
|
|||||||
file.open("/proc/" + PIString::fromNumber(pID_) + "/stat", PIIODevice::ReadOnly);
|
file.open("/proc/" + PIString::fromNumber(pID_) + "/stat", PIIODevice::ReadOnly);
|
||||||
filem.open("/proc/" + PIString::fromNumber(pID_) + "/statm", PIIODevice::ReadOnly);
|
filem.open("/proc/" + PIString::fromNumber(pID_) + "/statm", PIIODevice::ReadOnly);
|
||||||
if (!file.isOpened()) {
|
if (!file.isOpened()) {
|
||||||
piCout << "[PISystemMonitor] Can`t find process with ID = " << pID_ << "!" << endl;
|
piCout << "[PISystemMonitor] Can`t find process with ID = " << pID_ << "!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cycle = -1;
|
cycle = -1;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "pithread.h"
|
#include "pithread.h"
|
||||||
#include "piprocess.h"
|
#include "piprocess.h"
|
||||||
|
|
||||||
class PISystemMonitor: public PIThread
|
class PIP_EXPORT PISystemMonitor: public PIThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PISystemMonitor();
|
PISystemMonitor();
|
||||||
|
|||||||
@@ -23,9 +23,9 @@
|
|||||||
#include "piconfig.h"
|
#include "piconfig.h"
|
||||||
|
|
||||||
namespace PISystemTests {
|
namespace PISystemTests {
|
||||||
extern long time_resolution_ns;
|
PIP_EXPORT extern long time_resolution_ns;
|
||||||
extern long time_elapsed_ns;
|
PIP_EXPORT extern long time_elapsed_ns;
|
||||||
extern long usleep_offset_us;
|
PIP_EXPORT extern long usleep_offset_us;
|
||||||
|
|
||||||
class PISystemTestReader {
|
class PISystemTestReader {
|
||||||
public:
|
public:
|
||||||
|
|||||||
47
pithread.cpp
47
pithread.cpp
@@ -31,6 +31,36 @@ void piUSleep(int usecs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \class PIThread
|
||||||
|
* \brief Thread class
|
||||||
|
* \details This class allow you exec your code in separate thread.
|
||||||
|
*
|
||||||
|
* \section PIThread_sec0 Synopsis
|
||||||
|
* Multithread .
|
||||||
|
*
|
||||||
|
* \section PIThread_sec1 To/from data convertions
|
||||||
|
* Most common constructor is \a PIThread(const char * str), where "str"
|
||||||
|
* is null-terminated string, e.g. \c "string". This is 7 chars with last char = 0.
|
||||||
|
* Also you can constructs \a PIThread from single \a PIChar, \a PIByteArray,
|
||||||
|
* other \a PIThread or sequency of the same characters with custom length.\n \n
|
||||||
|
* This class has implicit conversions to <tt>const char * </tt> and
|
||||||
|
* \c std::string. Also there are functions to make same convertions:
|
||||||
|
* * \a data() - to <tt>const char * </tt>,
|
||||||
|
* * \a stdString() - to \c std::string,
|
||||||
|
* * \a toByteArray() - to \a PIByteArray.
|
||||||
|
*
|
||||||
|
* \section PIThread_sec2 Numeric operations
|
||||||
|
* You can get symbolic representation of any numeric value with function
|
||||||
|
* \a setNumber(any integer value, int base = 10, bool * ok = 0). Default
|
||||||
|
* arguments are set for decimal base system, but you can choose any system
|
||||||
|
* from 2 to 40. There are the same static functions \a fromNumber(), that
|
||||||
|
* returns \a PIThread. \n
|
||||||
|
* Also there is function \a setReadableSize() which is set human-readable
|
||||||
|
* size in bytes, Kb, Mb, Gb or Pb. Static analog is \a readableSize().
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay): PIObject() {
|
PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay): PIObject() {
|
||||||
piMonitor.threads++;
|
piMonitor.threads++;
|
||||||
data_ = data;
|
data_ = data;
|
||||||
@@ -58,12 +88,14 @@ PIThread::~PIThread() {
|
|||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
pthread_cancel(thread);
|
pthread_cancel(thread);
|
||||||
#else
|
#else
|
||||||
|
TerminateThread(thread, 0);
|
||||||
CloseHandle(thread);
|
CloseHandle(thread);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIThread::start(int timer_delay) {
|
bool PIThread::start(int timer_delay) {
|
||||||
|
if (running) return false;
|
||||||
terminating = running = false;
|
terminating = running = false;
|
||||||
timer = timer_delay;
|
timer = timer_delay;
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
@@ -88,6 +120,7 @@ bool PIThread::start(int timer_delay) {
|
|||||||
|
|
||||||
|
|
||||||
bool PIThread::startOnce() {
|
bool PIThread::startOnce() {
|
||||||
|
if (running) return false;
|
||||||
terminating = running = false;
|
terminating = running = false;
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
@@ -110,13 +143,13 @@ bool PIThread::startOnce() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIThread::terminate(bool hard) {
|
void PIThread::terminate() {
|
||||||
if (thread == 0) return;
|
if (thread == 0) return;
|
||||||
running = false;
|
running = false;
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
if (hard) kill((ullong)thread, SIGKILL);
|
pthread_cancel(thread);
|
||||||
else pthread_cancel(thread);
|
|
||||||
#else
|
#else
|
||||||
|
TerminateThread(thread, 0);
|
||||||
CloseHandle(thread);
|
CloseHandle(thread);
|
||||||
#endif
|
#endif
|
||||||
thread = 0;
|
thread = 0;
|
||||||
@@ -125,6 +158,10 @@ void PIThread::terminate(bool hard) {
|
|||||||
|
|
||||||
|
|
||||||
void * PIThread::thread_function(void * t) {
|
void * PIThread::thread_function(void * t) {
|
||||||
|
#ifndef WINDOWS
|
||||||
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
|
||||||
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||||
|
#endif
|
||||||
PIThread & ct = *((PIThread * )t);
|
PIThread & ct = *((PIThread * )t);
|
||||||
ct.running = true;
|
ct.running = true;
|
||||||
ct.begin();
|
ct.begin();
|
||||||
@@ -150,6 +187,10 @@ void * PIThread::thread_function(void * t) {
|
|||||||
|
|
||||||
|
|
||||||
void * PIThread::thread_function_once(void * t) {
|
void * PIThread::thread_function_once(void * t) {
|
||||||
|
#ifndef WINDOWS
|
||||||
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
|
||||||
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||||
|
#endif
|
||||||
PIThread & ct = *((PIThread * )t);
|
PIThread & ct = *((PIThread * )t);
|
||||||
ct.running = true;
|
ct.running = true;
|
||||||
ct.begin();
|
ct.begin();
|
||||||
|
|||||||
191
pithread.h
191
pithread.h
@@ -1,3 +1,8 @@
|
|||||||
|
/*! \file pithread.h
|
||||||
|
* \brief Thread
|
||||||
|
*
|
||||||
|
* This file declare thread class and some wait functions
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Thread
|
Thread
|
||||||
@@ -24,86 +29,188 @@
|
|||||||
#include "pimutex.h"
|
#include "pimutex.h"
|
||||||
#include "piobject.h"
|
#include "piobject.h"
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef DOXYGEN
|
||||||
inline void msleep(int msecs) {Sleep(msecs);}
|
//! \brief Sleep for "msecs" milliseconds
|
||||||
|
void msleep(int msecs);
|
||||||
#else
|
#else
|
||||||
|
# ifdef WINDOWS
|
||||||
|
inline void msleep(int msecs) {Sleep(msecs);}
|
||||||
|
# else
|
||||||
inline void msleep(int msecs) {usleep(msecs * 1000);}
|
inline void msleep(int msecs) {usleep(msecs * 1000);}
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*! \brief Precise sleep for "usecs" microseconds
|
||||||
|
* \details This function consider \c "usleep" offset
|
||||||
|
* on QNX/Linux/Mac, which is calculated with
|
||||||
|
* \a pip_sys_test program. If there is correct
|
||||||
|
* offset value in system config, this function
|
||||||
|
* wait \b exactly "usecs" microseconds. */
|
||||||
void piUSleep(int usecs); // on !Windows consider constant "usleep" offset
|
void piUSleep(int usecs); // on !Windows consider constant "usleep" offset
|
||||||
|
|
||||||
|
/*! \brief Precise sleep for "msecs" milliseconds
|
||||||
|
* \details This function exec \a piUSleep (msecs * 1000). */
|
||||||
inline void piMSleep(int msecs) {piUSleep(msecs * 1000);} // on !Windows consider constant "usleep" offset
|
inline void piMSleep(int msecs) {piUSleep(msecs * 1000);} // on !Windows consider constant "usleep" offset
|
||||||
|
|
||||||
typedef void (*ThreadFunc)(void * );
|
typedef void (*ThreadFunc)(void * );
|
||||||
|
|
||||||
/// events:
|
|
||||||
/// void started()
|
class PIP_EXPORT PIThread: public PIObject
|
||||||
/// void stopped()
|
{
|
||||||
///
|
PIOBJECT(PIThread)
|
||||||
/// handlers:
|
|
||||||
/// bool start(int timer_delay = -1)
|
|
||||||
/// bool start(ThreadFunc func, int timer_delay = -1)
|
|
||||||
/// bool startOnce()
|
|
||||||
/// bool startOnce(ThreadFunc func)
|
|
||||||
/// void stop(bool wait = false)
|
|
||||||
/// void terminate(bool hard = false)
|
|
||||||
/// bool waitForStart(int timeout_msecs = -1)
|
|
||||||
/// bool waitForFinish(int timeout_msecs = -1)
|
|
||||||
/// void lock()
|
|
||||||
/// void unlock()
|
|
||||||
class PIThread: public PIObject {
|
|
||||||
public:
|
public:
|
||||||
PIThread(void * data, ThreadFunc func, bool startNow = false, int timer_delay = -1);
|
PIThread(void * data, ThreadFunc func, bool startNow = false, int timer_delay = -1);
|
||||||
PIThread(bool startNow = false, int timer_delay = -1);
|
PIThread(bool startNow = false, int timer_delay = -1);
|
||||||
virtual ~PIThread();
|
virtual ~PIThread();
|
||||||
|
|
||||||
#ifdef QNX
|
#ifdef DOXYGEN
|
||||||
|
//! Priority of thread
|
||||||
|
enum Priority {piHighest /** Highest */,
|
||||||
|
piHigh /** High */,
|
||||||
|
piNormal /** Normal, default */,
|
||||||
|
piLow /** Low */,
|
||||||
|
piLowerst /** Lowest */
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
# ifdef QNX
|
||||||
enum Priority {piHighest = 12,
|
enum Priority {piHighest = 12,
|
||||||
piHigh = 11,
|
piHigh = 11,
|
||||||
piNormal = 10,
|
piNormal = 10,
|
||||||
piLow = 9,
|
piLow = 9,
|
||||||
piLowerst = 8 };
|
piLowerst = 8 };
|
||||||
#else
|
# else
|
||||||
enum Priority {piHighest = -2,
|
enum Priority {piHighest = -2,
|
||||||
piHigh = -1,
|
piHigh = -1,
|
||||||
piNormal = 0,
|
piNormal = 0,
|
||||||
piLow = 1,
|
piLow = 1,
|
||||||
piLowerst = 2 };
|
piLowerst = 2 };
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//bool start(int timer_delay = -1);
|
EVENT_HANDLER0(bool, start) {return start(-1);}
|
||||||
EVENT_HANDLER0(PIThread, bool, start) {return start(-1);}
|
EVENT_HANDLER1(bool, start, int, timer_delay);
|
||||||
EVENT_HANDLER1(PIThread, bool, start, int, timer_delay);
|
EVENT_HANDLER1(bool, start, ThreadFunc, func) {ret_func = func; return start(-1);}
|
||||||
EVENT_HANDLER1(PIThread, bool, start, ThreadFunc, func) {ret_func = func; return start(-1);}
|
EVENT_HANDLER2(bool, start, ThreadFunc, func, int, timer_delay) {ret_func = func; return start(timer_delay);}
|
||||||
EVENT_HANDLER2(PIThread, bool, start, ThreadFunc, func, int, timer_delay) {ret_func = func; return start(timer_delay);}
|
EVENT_HANDLER0(bool, startOnce);
|
||||||
EVENT_HANDLER0(PIThread, bool, startOnce);
|
EVENT_HANDLER1(bool, startOnce, ThreadFunc, func) {ret_func = func; return startOnce();}
|
||||||
EVENT_HANDLER1(PIThread, bool, startOnce, ThreadFunc, func) {ret_func = func; return startOnce();}
|
EVENT_HANDLER0(void, stop) {stop(false);}
|
||||||
EVENT_HANDLER0(PIThread, void, stop) {stop(false);}
|
EVENT_HANDLER1(void, stop, bool, wait) {terminating = true; if (wait) waitForFinish();}
|
||||||
EVENT_HANDLER1(PIThread, void, stop, bool, wait) {terminating = true; if (wait) waitForFinish();}
|
EVENT_HANDLER0(void, terminate);
|
||||||
EVENT_HANDLER0(PIThread, void, terminate) {terminate(false);}
|
|
||||||
EVENT_HANDLER1(PIThread, void, terminate, bool, hard);
|
//! \brief Set common data passed to external function
|
||||||
void setData(void * d) {data_ = d;}
|
void setData(void * d) {data_ = d;}
|
||||||
|
|
||||||
|
//! \brief Set external function that will be executed after every \a run()
|
||||||
void setSlot(ThreadFunc func) {ret_func = func;}
|
void setSlot(ThreadFunc func) {ret_func = func;}
|
||||||
|
|
||||||
|
//! \brief Set priority of thread
|
||||||
void setPriority(PIThread::Priority prior);
|
void setPriority(PIThread::Priority prior);
|
||||||
|
|
||||||
|
//! \brief Return priority of thread
|
||||||
PIThread::Priority priority() const {return priority_;}
|
PIThread::Priority priority() const {return priority_;}
|
||||||
|
|
||||||
|
//! \brief Return \c true if thread is running
|
||||||
bool isRunning() const {return running;}
|
bool isRunning() const {return running;}
|
||||||
EVENT_HANDLER0(PIThread, bool, waitForFinish) {return waitForFinish(-1);}
|
|
||||||
EVENT_HANDLER1(PIThread, bool, waitForFinish, int, timeout_msecs);
|
bool isStopping() const {return running && terminating;}
|
||||||
EVENT_HANDLER0(PIThread, bool, waitForStart) {return waitForStart(-1);}
|
|
||||||
EVENT_HANDLER1(PIThread, bool, waitForStart, int, timeout_msecs);
|
EVENT_HANDLER0(bool, waitForStart) {return waitForStart(-1);}
|
||||||
|
EVENT_HANDLER1(bool, waitForStart, int, timeout_msecs);
|
||||||
|
EVENT_HANDLER0(bool, waitForFinish) {return waitForFinish(-1);}
|
||||||
|
EVENT_HANDLER1(bool, waitForFinish, int, timeout_msecs);
|
||||||
|
|
||||||
|
//! \brief Set necessity of lock every \a run with internal mutex
|
||||||
void needLockRun(bool need) {lockRun = need;}
|
void needLockRun(bool need) {lockRun = need;}
|
||||||
EVENT_HANDLER0(PIThread, void, lock) {mutex_.lock();}
|
EVENT_HANDLER0(void, lock) {mutex_.lock();}
|
||||||
EVENT_HANDLER0(PIThread, void, unlock) {mutex_.unlock();}
|
EVENT_HANDLER0(void, unlock) {mutex_.unlock();}
|
||||||
|
|
||||||
|
//! \brief Return internal mutex
|
||||||
PIMutex & mutex() {return mutex_;}
|
PIMutex & mutex() {return mutex_;}
|
||||||
|
|
||||||
EVENT(PIThread, started)
|
EVENT(started)
|
||||||
EVENT(PIThread, stopped)
|
EVENT(stopped)
|
||||||
|
|
||||||
|
//! \handlers
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
/** \fn bool start(int timer_delay = -1)
|
||||||
|
* \brief Start thread
|
||||||
|
* \details Start execution of \a run() in internal loop with
|
||||||
|
* "timer_delay" delay in milliseconds. If "timer_delay" <= 0
|
||||||
|
* there is no delay in loop. Thread also exec external function
|
||||||
|
* set by \a setSlot() if it`s not null
|
||||||
|
*
|
||||||
|
* \return \c false if thread already started or can`t start thread */
|
||||||
|
|
||||||
|
/** \fn bool start(ThreadFunc func, int timer_delay = -1)
|
||||||
|
* \brief Start thread
|
||||||
|
* \details Overloaded function. Set external function "func" before start
|
||||||
|
*
|
||||||
|
* \return \c false if thread already started or can`t start thread */
|
||||||
|
|
||||||
|
/** \fn bool startOnce()
|
||||||
|
* \brief Start thread without internal loop
|
||||||
|
* \details Start execution of \a run() once. Thread also exec
|
||||||
|
* external function set by \a setSlot() if it`s not null
|
||||||
|
*
|
||||||
|
* \return \c false if thread already started or can`t start thread */
|
||||||
|
|
||||||
|
/** \fn bool startOnce(ThreadFunc func)
|
||||||
|
* \brief Start thread without internal loop
|
||||||
|
* \details Overloaded function. Set external function "func" before start
|
||||||
|
*
|
||||||
|
* \return \c false if thread already started or can`t start thread */
|
||||||
|
|
||||||
|
/** \fn void stop(bool wait = false)
|
||||||
|
* \brief Stop thread
|
||||||
|
* \details Stop execution of thread and wait for it finish
|
||||||
|
* if "wait" is \c true. This function can block for infinite
|
||||||
|
* time if "wait" is \c true and any of thread function is
|
||||||
|
* busy forever */
|
||||||
|
|
||||||
|
/** \fn void terminate()
|
||||||
|
* \brief Strongly stop thread
|
||||||
|
* \details Stop execution of thread immediately */
|
||||||
|
|
||||||
|
/** \fn bool waitForStart(int timeout_msecs = -1)
|
||||||
|
* \brief Wait for thread start
|
||||||
|
* \details This function block until thread finish for "timeout_msecs"
|
||||||
|
* or forever if "timeout_msecs" < 0
|
||||||
|
*
|
||||||
|
* \return \c false if timeout is exceeded */
|
||||||
|
|
||||||
|
/** \fn bool waitForFinish(int timeout_msecs = -1)
|
||||||
|
* \brief Wait for thread finish
|
||||||
|
* \details This function block until thread start for "timeout_msecs"
|
||||||
|
* or forever if "timeout_msecs" < 0
|
||||||
|
*
|
||||||
|
* \return \c false if timeout is exceeded */
|
||||||
|
|
||||||
|
//! \fn void lock()
|
||||||
|
//! \brief Lock internal mutex
|
||||||
|
|
||||||
|
//! \fn void unlock()
|
||||||
|
//! \brief Unlock internal mutex
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
//! \events
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! \fn void started()
|
||||||
|
//! \brief Raise on thread start
|
||||||
|
|
||||||
|
//! \fn void stopped()
|
||||||
|
//! \brief Raise on thread stop
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void * thread_function(void * t);
|
static void * thread_function(void * t);
|
||||||
static void * thread_function_once(void * t);
|
static void * thread_function_once(void * t);
|
||||||
|
|
||||||
virtual void begin() {;} // executed at start
|
virtual void begin() {;}
|
||||||
virtual void run() {;} // main loop executed with "timer_delay" timeout
|
virtual void run() {;}
|
||||||
virtual void end() {;} // executed at finish
|
virtual void end() {;}
|
||||||
|
|
||||||
volatile bool terminating, running, lockRun;
|
volatile bool terminating, running, lockRun;
|
||||||
int timer, policy;
|
int timer, policy;
|
||||||
|
|||||||
222
pitimer.cpp
222
pitimer.cpp
@@ -20,6 +20,73 @@
|
|||||||
#include "pitimer.h"
|
#include "pitimer.h"
|
||||||
#include "pisystemtests.h"
|
#include "pisystemtests.h"
|
||||||
|
|
||||||
|
bool operator ==(const PITime & t0, const PITime & t1) {
|
||||||
|
return (t0.hours == t1.hours && t0.minutes == t1.minutes && t0.seconds == t1.seconds);
|
||||||
|
}
|
||||||
|
bool operator <(const PITime & t0, const PITime & t1) {
|
||||||
|
if (t0.hours == t1.hours) {
|
||||||
|
if (t0.minutes == t1.minutes) {
|
||||||
|
return t0.seconds < t1.seconds;
|
||||||
|
} else return t0.minutes < t1.minutes;
|
||||||
|
} else return t0.hours < t1.hours;
|
||||||
|
}
|
||||||
|
bool operator >(const PITime & t0, const PITime & t1) {
|
||||||
|
if (t0.hours == t1.hours) {
|
||||||
|
if (t0.minutes == t1.minutes) {
|
||||||
|
return t0.seconds > t1.seconds;
|
||||||
|
} else return t0.minutes > t1.minutes;
|
||||||
|
} else return t0.hours > t1.hours;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator ==(const PIDate & t0, const PIDate & t1) {
|
||||||
|
return (t0.year == t1.year && t0.month == t1.month && t0.day == t1.day);
|
||||||
|
}
|
||||||
|
bool operator <(const PIDate & t0, const PIDate & t1) {
|
||||||
|
if (t0.year == t1.year) {
|
||||||
|
if (t0.month == t1.month) {
|
||||||
|
return t0.day < t1.day;
|
||||||
|
} else return t0.month < t1.month;
|
||||||
|
} else return t0.year < t1.year;
|
||||||
|
}
|
||||||
|
bool operator >(const PIDate & t0, const PIDate & t1) {
|
||||||
|
if (t0.year == t1.year) {
|
||||||
|
if (t0.month == t1.month) {
|
||||||
|
return t0.day > t1.day;
|
||||||
|
} else return t0.month > t1.month;
|
||||||
|
} else return t0.year > t1.year;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator ==(const PIDateTime & t0, const PIDateTime & t1) {
|
||||||
|
return (t0.year == t1.year && t0.month == t1.month && t0.day == t1.day &&
|
||||||
|
t0.hours == t1.hours && t0.minutes == t1.minutes && t0.seconds == t1.seconds);
|
||||||
|
}
|
||||||
|
bool operator <(const PIDateTime & t0, const PIDateTime & t1) {
|
||||||
|
if (t0.year == t1.year) {
|
||||||
|
if (t0.month == t1.month) {
|
||||||
|
if (t0.day == t1.day) {
|
||||||
|
if (t0.hours == t1.hours) {
|
||||||
|
if (t0.minutes == t1.minutes) {
|
||||||
|
return t0.seconds < t1.seconds;
|
||||||
|
} else return t0.minutes < t1.minutes;
|
||||||
|
} else return t0.hours < t1.hours;
|
||||||
|
} else return t0.day < t1.day;
|
||||||
|
} else return t0.month < t1.month;
|
||||||
|
} else return t0.year < t1.year;
|
||||||
|
}
|
||||||
|
bool operator >(const PIDateTime & t0, const PIDateTime & t1) {
|
||||||
|
if (t0.year == t1.year) {
|
||||||
|
if (t0.month == t1.month) {
|
||||||
|
if (t0.day == t1.day) {
|
||||||
|
if (t0.hours == t1.hours) {
|
||||||
|
if (t0.minutes == t1.minutes) {
|
||||||
|
return t0.seconds > t1.seconds;
|
||||||
|
} else return t0.minutes > t1.minutes;
|
||||||
|
} else return t0.hours > t1.hours;
|
||||||
|
} else return t0.day > t1.day;
|
||||||
|
} else return t0.month > t1.month;
|
||||||
|
} else return t0.year > t1.year;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef PIP_TIMER_RT
|
#ifdef PIP_TIMER_RT
|
||||||
PITimer::TimerPool * pool = 0;
|
PITimer::TimerPool * pool = 0;
|
||||||
@@ -34,17 +101,20 @@ PITimer::PITimer(TimerEvent slot, void * data_, bool threaded_)
|
|||||||
#endif
|
#endif
|
||||||
ret_func = slot;
|
ret_func = slot;
|
||||||
data = data_;
|
data = data_;
|
||||||
|
running_ = false;
|
||||||
|
interval_ = 0.;
|
||||||
#ifdef PIP_TIMER_RT
|
#ifdef PIP_TIMER_RT
|
||||||
piMonitor.timers++;
|
piMonitor.timers++;
|
||||||
ti = -1;
|
ti = -1;
|
||||||
threaded = threaded_;
|
threaded = threaded_;
|
||||||
running = false;
|
|
||||||
memset(&se, 0, sizeof(se));
|
memset(&se, 0, sizeof(se));
|
||||||
se.sigev_notify = SIGEV_THREAD;
|
se.sigev_notify = SIGEV_THREAD;
|
||||||
se.sigev_value.sival_ptr = this;
|
se.sigev_value.sival_ptr = this;
|
||||||
se.sigev_notify_function = PITimer::timer_event;
|
se.sigev_notify_function = PITimer::timer_event;
|
||||||
se.sigev_notify_attributes = 0;
|
se.sigev_notify_attributes = 0;
|
||||||
lockRun = false;
|
lockRun = false;
|
||||||
|
#else
|
||||||
|
deferred_ = false;
|
||||||
#endif
|
#endif
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
@@ -58,17 +128,20 @@ PITimer::PITimer(bool threaded_)
|
|||||||
#endif
|
#endif
|
||||||
ret_func = 0;
|
ret_func = 0;
|
||||||
data = 0;
|
data = 0;
|
||||||
|
running_ = false;
|
||||||
|
interval_ = 0.;
|
||||||
#ifdef PIP_TIMER_RT
|
#ifdef PIP_TIMER_RT
|
||||||
piMonitor.timers++;
|
piMonitor.timers++;
|
||||||
ti = -1;
|
ti = -1;
|
||||||
threaded = threaded_;
|
threaded = threaded_;
|
||||||
running = false;
|
|
||||||
memset(&se, 0, sizeof(se));
|
memset(&se, 0, sizeof(se));
|
||||||
se.sigev_notify = SIGEV_THREAD;
|
se.sigev_notify = SIGEV_THREAD;
|
||||||
se.sigev_value.sival_ptr = this;
|
se.sigev_value.sival_ptr = this;
|
||||||
se.sigev_notify_function = PITimer::timer_event;
|
se.sigev_notify_function = PITimer::timer_event;
|
||||||
se.sigev_notify_attributes = 0;
|
se.sigev_notify_attributes = 0;
|
||||||
lockRun = false;
|
lockRun = false;
|
||||||
|
#else
|
||||||
|
deferred_ = false;
|
||||||
#endif
|
#endif
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
@@ -84,14 +157,15 @@ PITimer::~PITimer() {
|
|||||||
|
|
||||||
#ifdef PIP_TIMER_RT
|
#ifdef PIP_TIMER_RT
|
||||||
void PITimer::start(double msecs) {
|
void PITimer::start(double msecs) {
|
||||||
if (ti != -1 || msecs < 0 || running) return;
|
if (ti != -1 || msecs < 0 || running_) return;
|
||||||
|
interval_ = msecs;
|
||||||
if (!threaded) {
|
if (!threaded) {
|
||||||
ticks = int(msecs);
|
ticks = int(msecs);
|
||||||
if (pool == 0) pool = new TimerPool();
|
if (pool == 0) pool = new TimerPool();
|
||||||
pool->add(this);
|
pool->add(this);
|
||||||
//cout << "not threaded timer start " << msecs << " msecs\n";
|
//cout << "not threaded timer start " << msecs << " msecs\n";
|
||||||
if (!pool->isRunning()) pool->start();
|
if (!pool->isRunning()) pool->start();
|
||||||
running = true;
|
running_ = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
spec.it_interval.tv_nsec = ((int)(msecs * 1000) % 1000000) * 1000;
|
spec.it_interval.tv_nsec = ((int)(msecs * 1000) % 1000000) * 1000;
|
||||||
@@ -100,16 +174,17 @@ void PITimer::start(double msecs) {
|
|||||||
ti = timer_create(CLOCK_REALTIME, &se, &timer);
|
ti = timer_create(CLOCK_REALTIME, &se, &timer);
|
||||||
//cout << "***create timer " << msecs << " msecs\n";
|
//cout << "***create timer " << msecs << " msecs\n";
|
||||||
if (ti == -1) {
|
if (ti == -1) {
|
||||||
piCout << "[PITimer] Can`t create timer for " << msecs << " msecs: " << errorString() << endl;
|
piCout << "[PITimer] Can`t create timer for " << msecs << " msecs: " << errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
timer_settime(timer, 0, &spec, 0);
|
timer_settime(timer, 0, &spec, 0);
|
||||||
running = true;
|
running_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PITimer::deferredStart(double interval_msecs, double delay_msecs) {
|
void PITimer::deferredStart(double interval_msecs, double delay_msecs) {
|
||||||
if (ti != -1 || interval_msecs < 0 || running) return;
|
if (ti != -1 || interval_msecs < 0 || running_) return;
|
||||||
|
interval_ = interval_msecs;
|
||||||
spec.it_interval.tv_nsec = ((int)(interval_msecs * 1000) % 1000000) * 1000;
|
spec.it_interval.tv_nsec = ((int)(interval_msecs * 1000) % 1000000) * 1000;
|
||||||
spec.it_interval.tv_sec = (time_t)(interval_msecs / 1000);
|
spec.it_interval.tv_sec = (time_t)(interval_msecs / 1000);
|
||||||
spec.it_value.tv_nsec = ((int)(delay_msecs * 1000) % 1000000) * 1000;
|
spec.it_value.tv_nsec = ((int)(delay_msecs * 1000) % 1000000) * 1000;
|
||||||
@@ -117,16 +192,17 @@ void PITimer::deferredStart(double interval_msecs, double delay_msecs) {
|
|||||||
ti = timer_create(CLOCK_REALTIME, &se, &timer);
|
ti = timer_create(CLOCK_REALTIME, &se, &timer);
|
||||||
//cout << "***create timer\n";
|
//cout << "***create timer\n";
|
||||||
if (ti == -1) {
|
if (ti == -1) {
|
||||||
piCout << "[PITimer] Can`t create timer for " << interval_msecs << " msecs: " << errorString() << endl;
|
piCout << "[PITimer] Can`t create timer for " << interval_msecs << " msecs: " << errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
timer_settime(timer, 0, &spec, 0);
|
timer_settime(timer, 0, &spec, 0);
|
||||||
running = true;
|
running_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PITimer::deferredStart(double interval_msecs, const PIDateTime & start_datetime) {
|
void PITimer::deferredStart(double interval_msecs, const PIDateTime & start_datetime) {
|
||||||
if (ti != -1 || interval_msecs < 0 || running) return;
|
if (ti != -1 || interval_msecs < 0 || running_) return;
|
||||||
|
interval_ = interval_msecs;
|
||||||
spec.it_interval.tv_nsec = ((int)(interval_msecs * 1000) % 1000000) * 1000;
|
spec.it_interval.tv_nsec = ((int)(interval_msecs * 1000) % 1000000) * 1000;
|
||||||
spec.it_interval.tv_sec = (time_t)(interval_msecs / 1000);
|
spec.it_interval.tv_sec = (time_t)(interval_msecs / 1000);
|
||||||
struct tm dtm;
|
struct tm dtm;
|
||||||
@@ -142,11 +218,11 @@ void PITimer::deferredStart(double interval_msecs, const PIDateTime & start_date
|
|||||||
ti = timer_create(CLOCK_REALTIME, &se, &timer);
|
ti = timer_create(CLOCK_REALTIME, &se, &timer);
|
||||||
//cout << "***create timer\n";
|
//cout << "***create timer\n";
|
||||||
if (ti == -1) {
|
if (ti == -1) {
|
||||||
piCout << "[PITimer] Can`t create timer for " << interval_msecs << " msecs: " << errorString() << endl;
|
piCout << "[PITimer] Can`t create timer for " << interval_msecs << " msecs: " << errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
timer_settime(timer, TIMER_ABSTIME, &spec, 0);
|
timer_settime(timer, TIMER_ABSTIME, &spec, 0);
|
||||||
running = true;
|
running_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -170,7 +246,7 @@ void PITimer::TimerPool::begin() {
|
|||||||
sa.sa_handler = empty_handler;
|
sa.sa_handler = empty_handler;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
if (sigaction(SIGALRM, &sa, 0) == -1) {
|
if (sigaction(SIGALRM, &sa, 0) == -1) {
|
||||||
piCout << "[PITimer] sigaction error: " << errorString() << endl;
|
piCout << "[PITimer] sigaction error: " << errorString();
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
}*/
|
}*/
|
||||||
@@ -184,12 +260,12 @@ void PITimer::TimerPool::begin() {
|
|||||||
spec.it_value = spec.it_interval;
|
spec.it_value = spec.it_interval;
|
||||||
//cout << "***create pool timer\n";
|
//cout << "***create pool timer\n";
|
||||||
if (timer_create(CLOCK_REALTIME, &se, &timer) == -1) {
|
if (timer_create(CLOCK_REALTIME, &se, &timer) == -1) {
|
||||||
piCout << "[PITimer] Can`t create timer for pool: " << errorString() << endl;
|
piCout << "[PITimer] Can`t create timer for pool: " << errorString();
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (timer_settime(timer, 0, &spec, 0) == -1) {
|
if (timer_settime(timer, 0, &spec, 0) == -1) {
|
||||||
piCout << "[PITimer] Can`t set timer for pool: " << errorString() << endl;
|
piCout << "[PITimer] Can`t set timer for pool: " << errorString();
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -221,8 +297,8 @@ void PITimer::TimerPool::run() {
|
|||||||
|
|
||||||
|
|
||||||
void PITimer::stop() {
|
void PITimer::stop() {
|
||||||
if (!running) return;
|
if (!running_) return;
|
||||||
running = false;
|
running_ = false;
|
||||||
if (!threaded) {
|
if (!threaded) {
|
||||||
if (pool != 0) {
|
if (pool != 0) {
|
||||||
pool->remove(this);
|
pool->remove(this);
|
||||||
@@ -231,12 +307,13 @@ void PITimer::stop() {
|
|||||||
}
|
}
|
||||||
if (ti != -1) timer_delete(timer);
|
if (ti != -1) timer_delete(timer);
|
||||||
ti = -1;
|
ti = -1;
|
||||||
|
interval_ = 0.;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PITimer::timer_event(sigval e) {
|
void PITimer::timer_event(sigval e) {
|
||||||
PITimer * ct = (PITimer * )e.sival_ptr;
|
PITimer * ct = (PITimer * )e.sival_ptr;
|
||||||
if (!ct->running) return;
|
if (!ct->running_) return;
|
||||||
if (ct->lockRun) ct->lock();
|
if (ct->lockRun) ct->lock();
|
||||||
if (ct->ret_func != 0) ct->ret_func(ct->data, 1);
|
if (ct->ret_func != 0) ct->ret_func(ct->data, 1);
|
||||||
ct->timeout(ct->data, 1);
|
ct->timeout(ct->data, 1);
|
||||||
@@ -255,12 +332,12 @@ void PITimer::timer_event(sigval e) {
|
|||||||
|
|
||||||
bool PITimer::waitForFinish(int timeout_msecs) {
|
bool PITimer::waitForFinish(int timeout_msecs) {
|
||||||
if (timeout_msecs < 0) {
|
if (timeout_msecs < 0) {
|
||||||
while (running)
|
while (running_)
|
||||||
msleep(1);
|
msleep(1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
while (running && cnt < timeout_msecs) {
|
while (running_ && cnt < timeout_msecs) {
|
||||||
msleep(1);
|
msleep(1);
|
||||||
++cnt;
|
++cnt;
|
||||||
}
|
}
|
||||||
@@ -270,18 +347,65 @@ bool PITimer::waitForFinish(int timeout_msecs) {
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
void PITimer::start(double msecs) {
|
void PITimer::start(double msecs) {
|
||||||
if (msecs < 0 || running) return;
|
if (msecs < 0 || running_) return;
|
||||||
|
interval_ = msecs;
|
||||||
inc_time = PISystemTime::fromMilliseconds(msecs);
|
inc_time = PISystemTime::fromMilliseconds(msecs);
|
||||||
st_time = currentSystemTime() + inc_time;
|
st_time = currentSystemTime() + inc_time;
|
||||||
|
deferred_ = false;
|
||||||
|
running_ = true;
|
||||||
PIThread::start();
|
PIThread::start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PITimer::deferredStart(double interval_msecs, double delay_msecs) {
|
||||||
|
//piCout << "defStart exec with" << delay_msecs << interval_msecs;
|
||||||
|
if (interval_msecs < 0 || running_) return;
|
||||||
|
interval_ = interval_msecs;
|
||||||
|
PISystemTime cst = currentSystemTime();
|
||||||
|
inc_time = PISystemTime::fromMilliseconds(interval_msecs);
|
||||||
|
st_time = currentSystemTime() + PISystemTime::fromMilliseconds(delay_msecs);
|
||||||
|
if (st_time < cst) st_time = cst;
|
||||||
|
running_ = deferred_ = true;
|
||||||
|
PIThread::start();
|
||||||
|
//piCout << "timer start def";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PITimer::deferredStart(double interval_msecs, const PIDateTime & start_datetime) {
|
||||||
|
//piCout << "defStart exec to" << start_datetime.toString() << interval_msecs;
|
||||||
|
if (interval_msecs < 0 || running_) return;
|
||||||
|
interval_ = interval_msecs;
|
||||||
|
PISystemTime cst = currentSystemTime();
|
||||||
|
inc_time = PISystemTime::fromMilliseconds(interval_msecs);
|
||||||
|
st_time = start_datetime.toSystemTime();
|
||||||
|
if (st_time < cst) st_time = cst;
|
||||||
|
running_ = deferred_ = true;
|
||||||
|
PIThread::start();
|
||||||
|
//piCout << "timer start def";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PITimer::run() {
|
void PITimer::run() {
|
||||||
if (!running) return;
|
if (!running_) return;
|
||||||
|
while (deferred_) {
|
||||||
|
PISystemTime tst = st_time - currentSystemTime();
|
||||||
|
if (tst.seconds > 0) {
|
||||||
|
piMSleep(100);
|
||||||
|
if (!running_) return;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (tst.nanoseconds > 100000000) {
|
||||||
|
piMSleep(100);
|
||||||
|
if (!running_) return;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tst.sleep();
|
||||||
|
deferred_ = false;
|
||||||
|
if (!running_) return;
|
||||||
|
}
|
||||||
(st_time - currentSystemTime()).sleep();
|
(st_time - currentSystemTime()).sleep();
|
||||||
st_time += inc_time;
|
st_time += inc_time;
|
||||||
if (lockRun) lock();
|
//if (lockRun) lock();
|
||||||
if (ret_func != 0) ret_func(data, 1);
|
if (ret_func != 0) ret_func(data, 1);
|
||||||
timeout(data, 1);
|
timeout(data, 1);
|
||||||
tick(data, 1);
|
tick(data, 1);
|
||||||
@@ -293,7 +417,7 @@ void PITimer::run() {
|
|||||||
timeout(data, i.delim);
|
timeout(data, i.delim);
|
||||||
tick(data, i.delim);
|
tick(data, i.delim);
|
||||||
}
|
}
|
||||||
if (lockRun) unlock();
|
//if (lockRun) unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -524,7 +648,7 @@ PISystemTime currentSystemTime() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIString PITime::toString(const PIString & format) {
|
PIString PITime::toString(const PIString & format) const {
|
||||||
PIString ts = format;
|
PIString ts = format;
|
||||||
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
||||||
ts.replace("h", PIString::fromNumber(hours));
|
ts.replace("h", PIString::fromNumber(hours));
|
||||||
@@ -532,11 +656,14 @@ PIString PITime::toString(const PIString & format) {
|
|||||||
ts.replace("m", PIString::fromNumber(minutes));
|
ts.replace("m", PIString::fromNumber(minutes));
|
||||||
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
||||||
ts.replace("s", PIString::fromNumber(seconds));
|
ts.replace("s", PIString::fromNumber(seconds));
|
||||||
|
ts.replace("zzz", PIString::fromNumber(milliseconds).expandLeftTo(3, '0'));
|
||||||
|
ts.replace("zz", PIString::fromNumber(milliseconds).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("z", PIString::fromNumber(milliseconds));
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIString PIDate::toString(const PIString & format) {
|
PIString PIDate::toString(const PIString & format) const {
|
||||||
PIString ts = format;
|
PIString ts = format;
|
||||||
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
||||||
ts.replace("yy", PIString::fromNumber(year).right(2));
|
ts.replace("yy", PIString::fromNumber(year).right(2));
|
||||||
@@ -549,14 +676,8 @@ PIString PIDate::toString(const PIString & format) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIString PIDateTime::toString(const PIString & format) {
|
PIString PIDateTime::toString(const PIString & format) const {
|
||||||
PIString ts = format;
|
PIString ts = format;
|
||||||
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("h", PIString::fromNumber(hours));
|
|
||||||
ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("m", PIString::fromNumber(minutes));
|
|
||||||
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("s", PIString::fromNumber(seconds));
|
|
||||||
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
||||||
ts.replace("yy", PIString::fromNumber(year).right(2));
|
ts.replace("yy", PIString::fromNumber(year).right(2));
|
||||||
ts.replace("y", PIString::fromNumber(year).right(1));
|
ts.replace("y", PIString::fromNumber(year).right(1));
|
||||||
@@ -564,10 +685,45 @@ PIString PIDateTime::toString(const PIString & format) {
|
|||||||
ts.replace("M", PIString::fromNumber(month));
|
ts.replace("M", PIString::fromNumber(month));
|
||||||
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
||||||
ts.replace("d", PIString::fromNumber(day));
|
ts.replace("d", PIString::fromNumber(day));
|
||||||
|
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("h", PIString::fromNumber(hours));
|
||||||
|
ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("m", PIString::fromNumber(minutes));
|
||||||
|
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("s", PIString::fromNumber(seconds));
|
||||||
|
ts.replace("zzz", PIString::fromNumber(milliseconds).expandLeftTo(3, '0'));
|
||||||
|
ts.replace("zz", PIString::fromNumber(milliseconds).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("z", PIString::fromNumber(milliseconds));
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
time_t PIDateTime::toSecondSinceEpoch() const {
|
||||||
|
tm pt;
|
||||||
|
pt.tm_sec = seconds;
|
||||||
|
pt.tm_min = minutes;
|
||||||
|
pt.tm_hour = hours;
|
||||||
|
pt.tm_mday = day;
|
||||||
|
pt.tm_mon = month - 1;
|
||||||
|
pt.tm_year = year - 1900;
|
||||||
|
return mktime(&pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIDateTime PIDateTime::fromSecondSinceEpoch(const time_t sec) {
|
||||||
|
tm * pt = localtime(&sec);
|
||||||
|
PIDateTime dt;
|
||||||
|
dt.seconds = pt->tm_sec;
|
||||||
|
dt.minutes = pt->tm_min;
|
||||||
|
dt.hours = pt->tm_hour;
|
||||||
|
dt.day = pt->tm_mday;
|
||||||
|
dt.month = pt->tm_mon + 1;
|
||||||
|
dt.year = pt->tm_year + 1900;
|
||||||
|
return dt;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PIString time2string(const PITime & time, const PIString & format) {
|
PIString time2string(const PITime & time, const PIString & format) {
|
||||||
PIString ts = format;
|
PIString ts = format;
|
||||||
ts.replace("hh", PIString::fromNumber(time.hours).expandLeftTo(2, '0'));
|
ts.replace("hh", PIString::fromNumber(time.hours).expandLeftTo(2, '0'));
|
||||||
|
|||||||
121
pitimer.h
121
pitimer.h
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
typedef void (*TimerEvent)(void * , int );
|
typedef void (*TimerEvent)(void * , int );
|
||||||
|
|
||||||
class PISystemTime {
|
class PIP_EXPORT PISystemTime {
|
||||||
public:
|
public:
|
||||||
PISystemTime() {seconds = nanoseconds = 0;}
|
PISystemTime() {seconds = nanoseconds = 0;}
|
||||||
PISystemTime(long s, long ns) {seconds = s; nanoseconds = ns; checkOverflows();}
|
PISystemTime(long s, long ns) {seconds = s; nanoseconds = ns; checkOverflows();}
|
||||||
@@ -71,29 +71,65 @@ private:
|
|||||||
inline PIByteArray & operator <<(PIByteArray & s, const PISystemTime & v) {s << v.seconds << v.nanoseconds; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PISystemTime & v) {s << v.seconds << v.nanoseconds; return s;}
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, PISystemTime & v) {s >> v.seconds >> v.nanoseconds; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PISystemTime & v) {s >> v.seconds >> v.nanoseconds; return s;}
|
||||||
|
|
||||||
struct PITime {
|
struct PIP_EXPORT PITime {
|
||||||
|
PITime() {hours = minutes = seconds = milliseconds = 0;}
|
||||||
|
int milliseconds;
|
||||||
int seconds;
|
int seconds;
|
||||||
int minutes;
|
int minutes;
|
||||||
int hours;
|
int hours;
|
||||||
PIString toString(const PIString & format = "h:mm:ss");
|
PIString toString(const PIString & format = "h:mm:ss") const;
|
||||||
};
|
};
|
||||||
|
PIP_EXPORT bool operator ==(const PITime & t0, const PITime & t1);
|
||||||
|
PIP_EXPORT bool operator <(const PITime & t0, const PITime & t1);
|
||||||
|
PIP_EXPORT bool operator >(const PITime & t0, const PITime & t1);
|
||||||
|
inline bool operator !=(const PITime & t0, const PITime & t1) {return !(t0 == t1);}
|
||||||
|
inline bool operator <=(const PITime & t0, const PITime & t1) {return !(t0 > t1);}
|
||||||
|
inline bool operator >=(const PITime & t0, const PITime & t1) {return !(t0 < t1);}
|
||||||
|
|
||||||
struct PIDate {
|
struct PIP_EXPORT PIDate {
|
||||||
|
PIDate() {year = month = day = 0;}
|
||||||
int day;
|
int day;
|
||||||
int month;
|
int month;
|
||||||
int year;
|
int year;
|
||||||
PIString toString(const PIString & format = "d.MM.yyyy");
|
PIString toString(const PIString & format = "d.MM.yyyy") const;
|
||||||
};
|
};
|
||||||
|
PIP_EXPORT bool operator ==(const PIDate & t0, const PIDate & t1);
|
||||||
|
PIP_EXPORT bool operator <(const PIDate & t0, const PIDate & t1);
|
||||||
|
PIP_EXPORT bool operator >(const PIDate & t0, const PIDate & t1);
|
||||||
|
inline bool operator !=(const PIDate & t0, const PIDate & t1) {return !(t0 == t1);}
|
||||||
|
inline bool operator <=(const PIDate & t0, const PIDate & t1) {return !(t0 > t1);}
|
||||||
|
inline bool operator >=(const PIDate & t0, const PIDate & t1) {return !(t0 < t1);}
|
||||||
|
|
||||||
struct PIDateTime {
|
struct PIP_EXPORT PIDateTime {
|
||||||
|
PIDateTime() {year = month = day = hours = minutes = seconds = 0;}
|
||||||
|
PIDateTime(const PITime & time) {year = month = day = 0; hours = time.hours; minutes = time.minutes; seconds = time.seconds; milliseconds = time.milliseconds;}
|
||||||
|
PIDateTime(const PIDate & date) {year = date.year; month = date.month; day = date.day; hours = minutes = seconds = milliseconds = 0;}
|
||||||
|
PIDateTime(const PIDate & date, const PITime & time) {year = date.year; month = date.month; day = date.day; hours = time.hours; minutes = time.minutes; seconds = time.seconds; milliseconds = time.milliseconds;}
|
||||||
|
int milliseconds;
|
||||||
int seconds;
|
int seconds;
|
||||||
int minutes;
|
int minutes;
|
||||||
int hours;
|
int hours;
|
||||||
int day;
|
int day;
|
||||||
int month;
|
int month;
|
||||||
int year;
|
int year;
|
||||||
PIString toString(const PIString & format = "h:mm:ss d.MM.yyyy");
|
PIDateTime normalized() const {return PIDateTime::fromSecondSinceEpoch(toSecondSinceEpoch());}
|
||||||
|
void normalize() {*this = normalized();}
|
||||||
|
PIString toString(const PIString & format = "h:mm:ss d.MM.yyyy") const;
|
||||||
|
time_t toSecondSinceEpoch() const;
|
||||||
|
PISystemTime toSystemTime() const {return PISystemTime(int(toSecondSinceEpoch()), milliseconds * 1000000);}
|
||||||
|
void operator +=(const PIDateTime & d1) {year += d1.year; month += d1.month; day += d1.day; hours += d1.hours; minutes += d1.minutes; seconds += d1.seconds; normalize();}
|
||||||
|
void operator -=(const PIDateTime & d1) {year -= d1.year; month -= d1.month; day -= d1.day; hours -= d1.hours; minutes -= d1.minutes; seconds -= d1.seconds; normalize();}
|
||||||
|
static PIDateTime fromSecondSinceEpoch(const time_t sec);
|
||||||
|
static PIDateTime fromSystemTime(const PISystemTime & st) {PIDateTime dt = fromSecondSinceEpoch(st.seconds); dt.milliseconds = piClampi(st.nanoseconds / 1000000, 0, 999); return dt;}
|
||||||
};
|
};
|
||||||
|
inline PIDateTime operator +(const PIDateTime & d0, const PIDateTime & d1) {PIDateTime td = d0; td += d1; return td.normalized();}
|
||||||
|
inline PIDateTime operator -(const PIDateTime & d0, const PIDateTime & d1) {PIDateTime td = d0; td -= d1; return td.normalized();}
|
||||||
|
PIP_EXPORT bool operator ==(const PIDateTime & t0, const PIDateTime & t1);
|
||||||
|
PIP_EXPORT bool operator <(const PIDateTime & t0, const PIDateTime & t1);
|
||||||
|
PIP_EXPORT bool operator >(const PIDateTime & t0, const PIDateTime & t1);
|
||||||
|
inline bool operator !=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 == t1);}
|
||||||
|
inline bool operator <=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 > t1);}
|
||||||
|
inline bool operator >=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 < t1);}
|
||||||
|
|
||||||
/// events:
|
/// events:
|
||||||
/// void timeout(void * data, int delimiter)
|
/// void timeout(void * data, int delimiter)
|
||||||
@@ -108,13 +144,14 @@ struct PIDateTime {
|
|||||||
/// void clearDelimiters()
|
/// void clearDelimiters()
|
||||||
/// void lock()
|
/// void lock()
|
||||||
/// void unlock()
|
/// void unlock()
|
||||||
class PITimer
|
class PIP_EXPORT PITimer
|
||||||
#ifndef PIP_TIMER_RT
|
#ifndef PIP_TIMER_RT
|
||||||
: public PIThread
|
: public PIThread
|
||||||
#else
|
#else
|
||||||
: public PIObject
|
: public PIObject
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
PIOBJECT(PITimer)
|
||||||
public:
|
public:
|
||||||
PITimer(TimerEvent slot = 0, void * data = 0, bool threaded = true);
|
PITimer(TimerEvent slot = 0, void * data = 0, bool threaded = true);
|
||||||
PITimer(bool threaded);
|
PITimer(bool threaded);
|
||||||
@@ -122,53 +159,53 @@ public:
|
|||||||
|
|
||||||
void setData(void * data_) {data = data_;}
|
void setData(void * data_) {data = data_;}
|
||||||
void setSlot(TimerEvent slot) {ret_func = slot;}
|
void setSlot(TimerEvent slot) {ret_func = slot;}
|
||||||
|
double interval() const {return interval_;}
|
||||||
#ifndef PIP_TIMER_RT
|
#ifndef PIP_TIMER_RT
|
||||||
# ifdef WINDOWS
|
# ifdef WINDOWS
|
||||||
EVENT_HANDLER0(PITimer, void, reset) {t_st = GetCurrentTime();}
|
EVENT_HANDLER0(void, reset) {t_st = GetCurrentTime();}
|
||||||
EVENT_HANDLER1(PIThread, bool, start, int, timer_delay) {start(double(timer_delay)); return true;}
|
|
||||||
EVENT_HANDLER1(PITimer, void, start, double, msecs);
|
|
||||||
# elif defined(MAC_OS)
|
# elif defined(MAC_OS)
|
||||||
EVENT_HANDLER0(PITimer, void, reset) {clock_get_time(__pi_mac_clock, &t_st);}
|
EVENT_HANDLER0(void, reset) {clock_get_time(__pi_mac_clock, &t_st);}
|
||||||
EVENT_HANDLER1(PIThread, bool, start, int, timer_delay) {start(double(timer_delay)); return true;}
|
|
||||||
EVENT_HANDLER1(PITimer, void, start, double, msecs);
|
|
||||||
# else
|
# else
|
||||||
EVENT_HANDLER0(PITimer, void, reset) {clock_gettime(0, &t_st);}
|
EVENT_HANDLER0(void, reset) {clock_gettime(0, &t_st);}
|
||||||
EVENT_HANDLER1(PIThread, bool, start, int, timer_delay) {start(double(timer_delay)); return true;}
|
|
||||||
EVENT_HANDLER1(PITimer, void, start, double, msecs);
|
|
||||||
# endif
|
# endif
|
||||||
|
EVENT_HANDLER1(bool, start, int, timer_delay) {start(double(timer_delay)); return true;}
|
||||||
|
EVENT_HANDLER1(void, start, double, msecs);
|
||||||
|
EVENT_HANDLER0(void, stop) {running_ = false;}
|
||||||
|
EVENT_HANDLER2(void, deferredStart, double, interval_msecs, double, delay_msecs);
|
||||||
|
EVENT_HANDLER2(void, deferredStart, double, interval_msecs, const PIDateTime &, start_datetime);
|
||||||
#else
|
#else
|
||||||
EVENT_HANDLER0(PITimer, void, reset) {clock_gettime(0, &t_st);}
|
EVENT_HANDLER0(void, reset) {clock_gettime(0, &t_st);}
|
||||||
EVENT_HANDLER1(PITimer, void, start, double, msecs);
|
EVENT_HANDLER1(void, start, double, msecs);
|
||||||
EVENT_HANDLER2(PITimer, void, deferredStart, double, interval_msecs, double, delay_msecs);
|
EVENT_HANDLER2(void, deferredStart, double, interval_msecs, double, delay_msecs);
|
||||||
EVENT_HANDLER2(PITimer, void, deferredStart, double, interval_msecs, const PIDateTime &, start_datetime);
|
EVENT_HANDLER2(void, deferredStart, double, interval_msecs, const PIDateTime &, start_datetime);
|
||||||
EVENT_HANDLER0(PITimer, void, stop);
|
EVENT_HANDLER0(void, stop);
|
||||||
EVENT_HANDLER0(PITimer, bool, waitForFinish) {return waitForFinish(-1);}
|
EVENT_HANDLER0(bool, waitForFinish) {return waitForFinish(-1);}
|
||||||
EVENT_HANDLER1(PITimer, bool, waitForFinish, int, timeout_msecs);
|
EVENT_HANDLER1(bool, waitForFinish, int, timeout_msecs);
|
||||||
bool isRunning() const {return running;}
|
bool isRunning() const {return running_;}
|
||||||
void needLockRun(bool need) {lockRun = need;}
|
void needLockRun(bool need) {lockRun = need;}
|
||||||
EVENT_HANDLER0(PITimer, void, lock) {mutex_.lock();}
|
EVENT_HANDLER0(void, lock) {mutex_.lock();}
|
||||||
EVENT_HANDLER0(PITimer, void, unlock) {mutex_.unlock();}
|
EVENT_HANDLER0(void, unlock) {mutex_.unlock();}
|
||||||
#endif
|
#endif
|
||||||
void addDelimiter(int delim, TimerEvent slot = 0) {ret_funcs << TimerSlot(slot, delim);}
|
void addDelimiter(int delim, TimerEvent slot = 0) {ret_funcs << TimerSlot(slot, delim);}
|
||||||
void removeDelimiter(int delim) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].delim == delim) {ret_funcs.remove(i); i--;}}
|
void removeDelimiter(int delim) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].delim == delim) {ret_funcs.remove(i); i--;}}
|
||||||
void removeDelimiter(TimerEvent slot) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].slot == slot) {ret_funcs.remove(i); i--;}}
|
void removeDelimiter(TimerEvent slot) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].slot == slot) {ret_funcs.remove(i); i--;}}
|
||||||
void removeDelimiter(int delim, TimerEvent slot) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].slot == slot && ret_funcs[i].delim == delim) {ret_funcs.remove(i); i--;}}
|
void removeDelimiter(int delim, TimerEvent slot) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].slot == slot && ret_funcs[i].delim == delim) {ret_funcs.remove(i); i--;}}
|
||||||
EVENT_HANDLER0(PITimer, void, clearDelimiters) {ret_funcs.clear();}
|
EVENT_HANDLER0(void, clearDelimiters) {ret_funcs.clear();}
|
||||||
|
|
||||||
double elapsed_n(); // nanoseconds
|
double elapsed_n(); // nanoseconds
|
||||||
double elapsed_u(); // microseconds
|
double elapsed_u(); // microseconds
|
||||||
double elapsed_m(); // miliseconds
|
double elapsed_m(); // milliseconds
|
||||||
double elapsed_s(); // seconds
|
double elapsed_s(); // seconds
|
||||||
|
|
||||||
double reset_time_n(); // nanoseconds
|
double reset_time_n(); // nanoseconds
|
||||||
double reset_time_u(); // microseconds
|
double reset_time_u(); // microseconds
|
||||||
double reset_time_m(); // miliseconds
|
double reset_time_m(); // milliseconds
|
||||||
double reset_time_s(); // seconds
|
double reset_time_s(); // seconds
|
||||||
PISystemTime reset_time();
|
PISystemTime reset_time();
|
||||||
|
|
||||||
static double elapsed_system_n(); // nanoseconds
|
static double elapsed_system_n(); // nanoseconds
|
||||||
static double elapsed_system_u(); // microseconds
|
static double elapsed_system_u(); // microseconds
|
||||||
static double elapsed_system_m(); // miliseconds
|
static double elapsed_system_m(); // milliseconds
|
||||||
static double elapsed_system_s(); // seconds
|
static double elapsed_system_s(); // seconds
|
||||||
|
|
||||||
|
|
||||||
@@ -200,7 +237,7 @@ public:
|
|||||||
int ticks;
|
int ticks;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EVENT2(PITimer, timeout, void * , data, int, delimiter)
|
EVENT2(timeout, void * , data, int, delimiter)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void tick(void * data, int delimiter) {;}
|
virtual void tick(void * data, int delimiter) {;}
|
||||||
@@ -208,10 +245,12 @@ protected:
|
|||||||
private:
|
private:
|
||||||
#ifndef PIP_TIMER_RT
|
#ifndef PIP_TIMER_RT
|
||||||
void run();
|
void run();
|
||||||
|
void end() {interval_ = 0.;}
|
||||||
|
|
||||||
PISystemTime st_time, inc_time;
|
PISystemTime st_time, inc_time;
|
||||||
|
bool deferred_;
|
||||||
#else
|
#else
|
||||||
bool running, threaded;
|
bool threaded;
|
||||||
volatile bool lockRun;
|
volatile bool lockRun;
|
||||||
PIMutex mutex_;
|
PIMutex mutex_;
|
||||||
int ti;
|
int ti;
|
||||||
@@ -219,6 +258,8 @@ private:
|
|||||||
timer_t timer;
|
timer_t timer;
|
||||||
sigevent se;
|
sigevent se;
|
||||||
#endif
|
#endif
|
||||||
|
bool running_;
|
||||||
|
double interval_;
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
long
|
long
|
||||||
@@ -246,12 +287,12 @@ private:
|
|||||||
extern PITimer::TimerPool * pool;
|
extern PITimer::TimerPool * pool;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PITime currentTime();
|
PIP_EXPORT PITime currentTime();
|
||||||
PIDate currentDate();
|
PIP_EXPORT PIDate currentDate();
|
||||||
PIDateTime currentDateTime();
|
PIP_EXPORT PIDateTime currentDateTime();
|
||||||
PISystemTime currentSystemTime();
|
PIP_EXPORT PISystemTime currentSystemTime();
|
||||||
PIString time2string(const PITime & time, const PIString & format = "h:mm:ss"); // obsolete, use PITime.toString() instead
|
PIP_EXPORT PIString time2string(const PITime & time, const PIString & format = "h:mm:ss"); // obsolete, use PITime.toString() instead
|
||||||
PIString date2string(const PIDate & date, const PIString & format = "d.MM.yyyy"); // obsolete, use PITime.toString() instead
|
PIP_EXPORT PIString date2string(const PIDate & date, const PIString & format = "d.MM.yyyy"); // obsolete, use PITime.toString() instead
|
||||||
PIString datetime2string(const PIDateTime & datetime, const PIString & format = "h:mm:ss d.MM.yyyy"); // obsolete, use PIDateTime.toString() instead
|
PIP_EXPORT PIString datetime2string(const PIDateTime & datetime, const PIString & format = "h:mm:ss d.MM.yyyy"); // obsolete, use PIDateTime.toString() instead
|
||||||
|
|
||||||
#endif // PITIMER_H
|
#endif // PITIMER_H
|
||||||
|
|||||||
43
pivariable.h
43
pivariable.h
@@ -22,11 +22,11 @@
|
|||||||
|
|
||||||
#include "piconfig.h"
|
#include "piconfig.h"
|
||||||
|
|
||||||
class PIVariant {
|
class PIP_EXPORT PIVariant {
|
||||||
friend class PIVariable;
|
friend class PIVariable;
|
||||||
public:
|
public:
|
||||||
enum Type {Bool, Char, Short, Int, Long, LLong, UChar, UShort, UInt, ULong, ULLong, Float, Double, LDouble, String, StringList};
|
enum Type {Bool, Char, Short, Int, Long, LLong, UChar, UShort, UInt, ULong, ULLong, Float, Double, LDouble, String, StringList};
|
||||||
|
|
||||||
PIVariant() {setValue(0.);}
|
PIVariant() {setValue(0.);}
|
||||||
PIVariant(const char * v) {setValue(v);}
|
PIVariant(const char * v) {setValue(v);}
|
||||||
PIVariant(const bool & v) {setValue(v);}
|
PIVariant(const bool & v) {setValue(v);}
|
||||||
@@ -45,7 +45,7 @@ public:
|
|||||||
PIVariant(const ldouble & v) {setValue(v);}
|
PIVariant(const ldouble & v) {setValue(v);}
|
||||||
PIVariant(const PIString & v) {setValue(v);}
|
PIVariant(const PIString & v) {setValue(v);}
|
||||||
PIVariant(const PIStringList & v) {setValue(v);}
|
PIVariant(const PIStringList & v) {setValue(v);}
|
||||||
|
|
||||||
inline void setValue(const char * v) {setValue(PIString(v));}
|
inline void setValue(const char * v) {setValue(PIString(v));}
|
||||||
inline void setValue(const bool & v) {type = PIVariant::Bool; vBool = v;}
|
inline void setValue(const bool & v) {type = PIVariant::Bool; vBool = v;}
|
||||||
inline void setValue(const char & v) {type = PIVariant::Char; vChar = v;}
|
inline void setValue(const char & v) {type = PIVariant::Char; vChar = v;}
|
||||||
@@ -92,7 +92,7 @@ public:
|
|||||||
inline void operator =(const ldouble & v) {type = PIVariant::LDouble; vLDouble = v;}
|
inline void operator =(const ldouble & v) {type = PIVariant::LDouble; vLDouble = v;}
|
||||||
inline void operator =(const PIString & v) {type = PIVariant::String; vString = v;}
|
inline void operator =(const PIString & v) {type = PIVariant::String; vString = v;}
|
||||||
inline void operator =(const PIStringList & v) {type = PIVariant::StringList; vStringList = v;}
|
inline void operator =(const PIStringList & v) {type = PIVariant::StringList; vStringList = v;}
|
||||||
|
|
||||||
bool operator ==(const PIVariant & v) const;
|
bool operator ==(const PIVariant & v) const;
|
||||||
inline bool operator !=(const PIVariant & v) const {return !(*this == v);}
|
inline bool operator !=(const PIVariant & v) const {return !(*this == v);}
|
||||||
|
|
||||||
@@ -115,25 +115,25 @@ public:
|
|||||||
};
|
};
|
||||||
PIString vString;
|
PIString vString;
|
||||||
PIStringList vStringList;
|
PIStringList vStringList;
|
||||||
|
|
||||||
static PIVariant readFromString(const PIString & s);
|
static PIVariant readFromString(const PIString & s);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static PIVariant::Type fromString(const PIString & str);
|
static PIVariant::Type fromString(const PIString & str);
|
||||||
static PIString toString(const PIVariant::Type & var);
|
static PIString toString(const PIVariant::Type & var);
|
||||||
static uint variableSize(const PIVariant::Type & var);
|
static uint variableSize(const PIVariant::Type & var);
|
||||||
static double variableValue(const char * var_ptr, const PIVariant::Type & var);
|
static double variableValue(const char * var_ptr, const PIVariant::Type & var);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIVariant & v) {s << v.typeName() << ": " << v.stringValue(); return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIVariant & v) {s << v.typeName() << ": " << v.stringValue(); return s;}
|
||||||
|
|
||||||
class PIVariable {
|
class PIP_EXPORT PIVariable {
|
||||||
public:
|
public:
|
||||||
PIVariable() {;}
|
PIVariable() {;}
|
||||||
PIVariable(const PIString & str) {setVariable(str);}
|
PIVariable(const PIString & str) {setVariable(str);}
|
||||||
~PIVariable() {;}
|
~PIVariable() {;}
|
||||||
|
|
||||||
void setVariable(const PIString & str);
|
void setVariable(const PIString & str);
|
||||||
void writeVariable(char * dest);
|
void writeVariable(char * dest);
|
||||||
inline void readVariable(const char * var_ptr) {value_ = PIVariant::variableValue((char * )((long)var_ptr + offset), type_);}
|
inline void readVariable(const char * var_ptr) {value_ = PIVariant::variableValue((char * )((long)var_ptr + offset), type_);}
|
||||||
@@ -143,37 +143,37 @@ public:
|
|||||||
inline void setName(const PIString & str) {name_ = str;}
|
inline void setName(const PIString & str) {name_ = str;}
|
||||||
inline double value() const {return value_;}
|
inline double value() const {return value_;}
|
||||||
inline void setValue(const double & val) {value_ = val;}
|
inline void setValue(const double & val) {value_ = val;}
|
||||||
|
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PIVariant::Type type_;
|
PIVariant::Type type_;
|
||||||
uint size_;
|
uint size_;
|
||||||
PIString name_;
|
PIString name_;
|
||||||
double value_;
|
double value_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PIStruct is abstract structure, described by *.conf file with format of each line:
|
* PIStruct is abstract structure, described by *.conf file with format of each line:
|
||||||
* "<name> = <type> #<n|f|b> <start_value>".
|
* "<name> = <type> #<n|f|b> <start_value>".
|
||||||
* e.g. "pi = double #f 3.1418"
|
* e.g. "pi = double #f 3.1418"
|
||||||
*
|
*
|
||||||
* You can write or read binary content of this struct
|
* You can write or read binary content of this struct
|
||||||
* by functions "writeData" and "readData", e.g.
|
* by functions "writeData" and "readData", e.g.
|
||||||
* "char * data = new char[struct.size()];
|
* "char * data = new char[struct.size()];
|
||||||
* struct.writeData(data);"
|
* struct.writeData(data);"
|
||||||
*
|
*
|
||||||
* Access to each variable in struct is looks like
|
* Access to each variable in struct is looks like
|
||||||
* "double value = struct["pi"].value();"
|
* "double value = struct["pi"].value();"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PIStruct {
|
class PIP_EXPORT PIStruct {
|
||||||
public:
|
public:
|
||||||
PIStruct() {;}
|
PIStruct() {;}
|
||||||
PIStruct(const PIString & str) {parseFile(str);}
|
PIStruct(const PIString & str) {parseFile(str);}
|
||||||
|
|
||||||
void parseFile(const PIString & file);
|
void parseFile(const PIString & file);
|
||||||
void readData(const char * data);
|
void readData(const char * data);
|
||||||
void writeData(char * data);
|
void writeData(char * data);
|
||||||
@@ -184,17 +184,12 @@ public:
|
|||||||
inline void setName(const PIString & str) {name_ = str;}
|
inline void setName(const PIString & str) {name_ = str;}
|
||||||
inline PIVariable & operator[](const uint & index) {return vars[index];}
|
inline PIVariable & operator[](const uint & index) {return vars[index];}
|
||||||
inline PIVariable & operator[](const PIString & name) {for (uint i = 0; i < vars.size(); ++i) if (vars[i].name() == name) return vars[i];}
|
inline PIVariable & operator[](const PIString & name) {for (uint i = 0; i < vars.size(); ++i) if (vars[i].name() == name) return vars[i];}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint size_;
|
uint size_;
|
||||||
PIString name_;
|
PIString name_;
|
||||||
PIVector<PIVariable> vars;
|
PIVector<PIVariable> vars;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PIVARIABLE_H
|
#endif // PIVARIABLE_H
|
||||||
|
|
||||||
#/** PhEDIT attribute block
|
|
||||||
#-11:16777215
|
|
||||||
#0:7338:monospace10:-3:-3:0
|
|
||||||
#** PhEDIT attribute block ends (-0000117)**/
|
|
||||||
|
|||||||
Reference in New Issue
Block a user