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)
|
||||
find_package(Qt4)
|
||||
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")
|
||||
if (${WIN32})
|
||||
add_definitions(-Wall -O2)
|
||||
else (${WIN32})
|
||||
add_definitions(-Wall -O2 -g3 --fast-math)
|
||||
endif (${WIN32})
|
||||
include(GenerateExportHeader)
|
||||
execute_process(COMMAND "make_rc_win.bat")
|
||||
add_definitions("-O2")
|
||||
#add_definitions(-DEF)
|
||||
list(APPEND CPPS "pip_resource_win.o")
|
||||
add_library(pip SHARED ${CPPS})
|
||||
if (${WIN32})
|
||||
target_link_libraries(pip pthread ws2_32 Iphlpapi)
|
||||
generate_export_header(pip)
|
||||
target_link_libraries(pip ws2_32 Iphlpapi)
|
||||
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)
|
||||
endif (${WIN32})
|
||||
add_executable(pip_test "main.cpp")
|
||||
if (${WIN32})
|
||||
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})
|
||||
target_link_libraries(pip_test pip)
|
||||
add_subdirectory(system_test)
|
||||
|
||||
399
main.cpp
399
main.cpp
@@ -16,7 +16,7 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//#define PIP_DEBUG
|
||||
#include "pip.h"
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ private:
|
||||
|
||||
void signalFunc(PISignals::Signal signal) {
|
||||
if (signal != PISignals::Interrupt) return;
|
||||
cout << "Ctrl+C pressed, exiting ..." << endl;
|
||||
cout << endl << "Ctrl+C pressed, exiting ..." << endl;
|
||||
exit(0);
|
||||
};
|
||||
|
||||
@@ -71,293 +71,252 @@ void timerEvent2(void * data, int delim) {
|
||||
|
||||
|
||||
class ObjectTest: public PIObject {
|
||||
PIOBJECT(ObjectTest)
|
||||
public:
|
||||
ObjectTest(const PIString & name = PIString()): PIObject(name) {h = hi = ht = false;}
|
||||
EVENT_HANDLER(ObjectTest, 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(ObjectTest, void, handler_timeout, void * , data, int, delim) {ht = true; cout << " handler_timeout in \"" << name() << "\", data = " << data << ", delim = " << delim << endl;}
|
||||
EVENT_HANDLER(void, handler) {h = true; cout << " handler in \"" << name() << "\"" << 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(void, handler_timeout, void * , data, int, delim) {ht = true; cout << " handler_timeout in \"" << name() << "\", data = " << data << ", delim = " << delim << endl;}
|
||||
bool h, hi, ht;
|
||||
};
|
||||
|
||||
|
||||
class ObjectTest2: public PIObject {
|
||||
PIOBJECT(ObjectTest2)
|
||||
public:
|
||||
ObjectTest2(const PIString & name = PIString()): PIObject(name) {;}
|
||||
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);}
|
||||
EVENT(ObjectTest2, event0)
|
||||
EVENT(ObjectTest2, event2)
|
||||
EVENT(event0)
|
||||
EVENT(event2)
|
||||
|
||||
};
|
||||
|
||||
class CA: public PIObject {
|
||||
PIOBJECT(CA)
|
||||
public:
|
||||
CA(const PIString & n): PIObject(n) {;}
|
||||
EVENT_HANDLER(CA, void, handler_ca) {a = true; cout << " handler CA" << endl;}
|
||||
EVENT(CA, event_ca)
|
||||
EVENT_HANDLER(void, handler_ca) {a = true; cout << " handler CA" << endl;}
|
||||
EVENT(event_ca)
|
||||
bool a;
|
||||
};
|
||||
|
||||
class CB: public CA {
|
||||
PIOBJECT(CB)
|
||||
public:
|
||||
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;
|
||||
};
|
||||
|
||||
class CC: public CB {
|
||||
PIOBJECT(CC)
|
||||
public:
|
||||
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;
|
||||
};
|
||||
|
||||
class CD: public CC {
|
||||
PIOBJECT(CD)
|
||||
public:
|
||||
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;
|
||||
};
|
||||
|
||||
PIDiagnostics diag;
|
||||
bool corr = true;
|
||||
void te(void * , int) {
|
||||
diag.received(256, corr);
|
||||
diag.sended(512);
|
||||
}
|
||||
|
||||
struct Packet {
|
||||
int from;
|
||||
int to;
|
||||
float data;
|
||||
int cs;
|
||||
|
||||
class ObjectA: public PIObject {
|
||||
PIOBJECT(ObjectA)
|
||||
public:
|
||||
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 InpuData {
|
||||
uint first_number; // Номер первого отсчета
|
||||
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 {
|
||||
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];
|
||||
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;
|
||||
}
|
||||
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');}
|
||||
};
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
struct msg2105base {
|
||||
msgHeader header;
|
||||
uchar command; // 3
|
||||
union {
|
||||
ullong msgTime;
|
||||
struct {
|
||||
uchar fi_number: 7; // номер частотного участка, 1 - 36
|
||||
uchar bort : 1; // борт: 0 - левый, 1 - правый
|
||||
uint time_ns;
|
||||
uint time_s;
|
||||
};
|
||||
ushort freq_start; // начальная частота, 0 - 6100
|
||||
ushort freq_end; // конечная частота, 0 - 6100
|
||||
uchar filter_bandwith; // полоса проспускания фильтра
|
||||
ushort filter_time_step; // время шага фильтра по времени
|
||||
uchar reserve;
|
||||
ushort record_time_start; // начальное время записи, 1 - 60 мс
|
||||
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;
|
||||
};
|
||||
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 {
|
||||
InpuData() {header.msg_id = 2113;}
|
||||
msgHeader header;
|
||||
uint first_number;
|
||||
struct {
|
||||
uchar packet_number: 7;
|
||||
uchar packet_last : 1;
|
||||
};
|
||||
struct {
|
||||
uchar antenna_number : 3;
|
||||
uchar frequency_number: 3;
|
||||
uchar data_type : 2;
|
||||
};
|
||||
uchar data[122];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
void te(void*, int);
|
||||
PITimer tm_(te);
|
||||
PISerial ser("/dev/ttyS0");
|
||||
bool pins[9];
|
||||
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;
|
||||
class RC: public PIObject {
|
||||
PIOBJECT(RC)
|
||||
public:
|
||||
EVENT_HANDLER2(void, re, ullong, id, int, size) {piCout << "written id =" << id << "size =" << size;}
|
||||
};
|
||||
|
||||
/*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");
|
||||
char fd[4096];
|
||||
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;
|
||||
int main(int argc, char ** argv) {
|
||||
InpuData data;
|
||||
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;
|
||||
float t = 0.f;
|
||||
int pc = 20, cnt = 0;
|
||||
for (int p = 0; p < pc; ++p) {
|
||||
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(((i >> b) & 1) == 1);
|
||||
ba_.push_back(((ci >> b) & 1) == 1);
|
||||
}
|
||||
//cout << ba_.byteSize() << ", " << ba_.bitSize() << endl;
|
||||
memcpy(data.data, ba_.data(), 122);
|
||||
cout << ba_ << endl;
|
||||
eth.send("127.0.0.1:5000", &data, sizeof(data));
|
||||
}
|
||||
/*cout << ba_ << endl;
|
||||
for (int i = 0; i < 122; ++i)
|
||||
cout << int(data.data[i]) << ", ";
|
||||
cout << endl;
|
||||
eth.send("127.0.0.1:5000", &data, sizeof(data));
|
||||
cout << endl;*/
|
||||
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;*/
|
||||
|
||||
/*QApplication app(argc, argv);
|
||||
PIFFT fft;
|
||||
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();*/
|
||||
|
||||
PISignals::setSlot(signalFunc);
|
||||
//PISignals::grabSignals(PISignals::Interrupt);
|
||||
bool r_string = true, r_thread = true, r_mutex = true, r_timer = true, r_file = true, r_eval = true, r_event = true;
|
||||
bool succ = true;
|
||||
cout << "== PIP test program ==" << endl;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "picontainers.h"
|
||||
|
||||
class PIBitArray {
|
||||
class PIP_EXPORT PIBitArray {
|
||||
public:
|
||||
PIBitArray(const int & size = 0) {resize(size);}
|
||||
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 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
|
||||
|
||||
@@ -90,12 +90,24 @@ private:
|
||||
PIVector<node> nodes;
|
||||
};
|
||||
|
||||
class PIByteArray: public PIVector<uchar> {
|
||||
class PIP_EXPORT PIByteArray: public PIVector<uchar> {
|
||||
public:
|
||||
PIByteArray() {;}
|
||||
PIByteArray(const uint size) {resize(size);}
|
||||
PIByteArray(const void * data, const uint size) {for (uint i = 0; i < size; ++i) push_back(((uchar * )data)[i]);}
|
||||
|
||||
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 & 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, 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 int & 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) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); 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 ushort & 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) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); 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 ullong & 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) {for (uint i = 0; i < sizeof(v); ++i) s.push_back(((uchar * )&v)[i]); 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 short v) {PBA_OPERATOR_TO return s;}
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const int v) {PBA_OPERATOR_TO return s;}
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const long & v) {PBA_OPERATOR_TO return s;}
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const llong & v) {PBA_OPERATOR_TO return s;}
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const ushort v) {PBA_OPERATOR_TO return s;}
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const uint v) {PBA_OPERATOR_TO return s;}
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const ulong & v) {PBA_OPERATOR_TO return s;}
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const ullong & v) {PBA_OPERATOR_TO return s;}
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const float v) {PBA_OPERATOR_TO 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>
|
||||
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>
|
||||
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>
|
||||
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;}
|
||||
inline PIByteArray & operator >>(PIByteArray & s, short & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); return s;}
|
||||
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, llong & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); 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, uint & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); 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, ullong & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); 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, double & v) {for (uint i = 0; i < sizeof(v); ++i) ((uchar * )&v)[i] = s.take_front(); return s;}
|
||||
#undef PBA_OPERATOR_TO
|
||||
#define PBA_OPERATOR_FROM memcpy(&v, s.data(), sizeof(v)); s.remove(0, sizeof(v));
|
||||
|
||||
inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= 1u); v = 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, int & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
inline PIByteArray & operator >>(PIByteArray & s, long & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
inline PIByteArray & operator >>(PIByteArray & s, llong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
inline PIByteArray & operator >>(PIByteArray & s, ushort & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
inline PIByteArray & operator >>(PIByteArray & s, uint & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM 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>
|
||||
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>
|
||||
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>
|
||||
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
|
||||
|
||||
110
pichar.h
110
pichar.h
@@ -1,3 +1,6 @@
|
||||
/*! \file pichar.h
|
||||
* \brief Unicode char
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Unicode char
|
||||
@@ -21,24 +24,41 @@
|
||||
#define PICHAR_H
|
||||
|
||||
#include "pibytearray.h"
|
||||
|
||||
class PIChar
|
||||
/*! \brief Unicode char
|
||||
* \details This class is wrapper around \c "uint".
|
||||
* There are many contructors and information functions;
|
||||
*/
|
||||
class PIP_EXPORT PIChar
|
||||
{
|
||||
friend class PIString;
|
||||
friend PIByteArray & operator <<(PIByteArray & s, const PIChar & v);
|
||||
friend PIByteArray & operator >>(PIByteArray & s, PIChar & v);
|
||||
public:
|
||||
//! Contructs ascii symbol
|
||||
PIChar(const char c) {ch = c; ch &= 0xFF;}
|
||||
|
||||
//! Contructs 2-bytes symbol
|
||||
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;}
|
||||
|
||||
//! Contructs 2-bytes symbol
|
||||
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);}
|
||||
|
||||
//inline operator const int() {return static_cast<const int>(ch);}
|
||||
//inline operator const char() {return toAscii();}
|
||||
|
||||
//! Copy operator
|
||||
PIChar & operator =(const char 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;}
|
||||
@@ -46,6 +66,7 @@ public:
|
||||
inline PIChar & operator =(const ushort 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;}
|
||||
/*inline bool operator ==(const PIChar & o) const {if (o.isAscii() ^ isAscii()) return false;
|
||||
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 uint o) const {return (PIChar(o) == *this);}*/
|
||||
|
||||
//! Compare operator
|
||||
bool operator !=(const PIChar & o) const {return !(o == *this);}
|
||||
/*inline bool operator !=(const char 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 uint o) const {return (PIChar(o) != *this);}*/
|
||||
|
||||
//! Compare operator
|
||||
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;}
|
||||
|
||||
//! Compare operator
|
||||
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;}
|
||||
|
||||
//! Return \b true if symbol is digit ('0' to '9')
|
||||
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;}
|
||||
|
||||
//! Return \b true if symbol is drawable (without space)
|
||||
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;}
|
||||
|
||||
//! Return \b true if symbol is in lower case
|
||||
bool isLower() const {return islower(ch) != 0;}
|
||||
|
||||
//! Return \b true if symbol is in upper case
|
||||
bool isUpper() const {return isupper(ch) != 0;}
|
||||
|
||||
//! Return \b true if symbol is printable (with space)
|
||||
bool isPrint() const {return isprint(ch) != 0;}
|
||||
|
||||
//! Return \b true if symbol is space or tab
|
||||
bool isSpace() const {return isspace(ch) != 0;}
|
||||
|
||||
//! Return \b true if symbol is alphabetical letter
|
||||
bool isAlpha() const {return isalpha(ch) != 0;}
|
||||
|
||||
//! Return \b true if symbol is ascii (< 128)
|
||||
bool isAscii() const {return isascii(ch) != 0;}
|
||||
|
||||
int toInt() const {return static_cast<const int>(ch);}
|
||||
const wchar_t * toWCharPtr() const {return &ch;}
|
||||
int toInt() const {return int(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);}
|
||||
wchar_t toWChar() const {return ch;}
|
||||
|
||||
wchar_t toWChar() const {return wchar_t(ch);}
|
||||
char toAscii() const {return ch % 256;}
|
||||
int unicode16Code() const {wchar_t wc; if (mbtowc(&wc, toCharPtr(), 4) > 0) return wc; return 0;}
|
||||
//#ifdef WINDOWS
|
||||
// inline PIChar toUpper() const __attribute__ ((optimize(0))) {return PIChar(toupper(ch));}
|
||||
// inline PIChar toLower() const __attribute__ ((optimize(0))) {return PIChar(tolower(ch));}
|
||||
//#else
|
||||
|
||||
//! Return symbol in upper case
|
||||
PIChar toUpper() const {return PIChar(toupper(ch));}
|
||||
|
||||
//! Return symbol in lower case
|
||||
PIChar toLower() const {return PIChar(tolower(ch));}
|
||||
//#endif
|
||||
|
||||
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;}
|
||||
|
||||
//! 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;}
|
||||
|
||||
//! Read operator from \c PIByteArray
|
||||
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);}
|
||||
|
||||
//! Compare operator
|
||||
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);}
|
||||
|
||||
//! Compare operator
|
||||
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);}
|
||||
|
||||
|
||||
//! Compare operator
|
||||
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);}
|
||||
|
||||
//! Compare operator
|
||||
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);}
|
||||
|
||||
//! Compare operator
|
||||
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);}
|
||||
|
||||
//! Compare operator
|
||||
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);}
|
||||
|
||||
//! Compare operator
|
||||
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);}
|
||||
|
||||
#endif // PICHAR_H
|
||||
|
||||
@@ -69,7 +69,7 @@ void PICLI::parse() {
|
||||
_args_opt << cra;
|
||||
continue;
|
||||
}
|
||||
piCout << "[PICli] Arguments overflow, \"" << cra << "\" ignored" << endl;
|
||||
piCout << "[PICli] Arguments overflow, \"" << cra << "\" ignored";
|
||||
}
|
||||
if (last == 0 ? false : last->has_value) {
|
||||
last->value = cra;
|
||||
|
||||
2
picli.h
2
picli.h
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "pistring.h"
|
||||
|
||||
class PICLI
|
||||
class PIP_EXPORT PICLI
|
||||
{
|
||||
public:
|
||||
PICLI(int argc, char * argv[]);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "piprocess.h"
|
||||
|
||||
class PICodec: private PIProcess
|
||||
class PIP_EXPORT PICodec: private PIProcess
|
||||
{
|
||||
public:
|
||||
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) {
|
||||
Entry & e(getValue(name));
|
||||
if (&e == &empty) {
|
||||
addEntry(name, value, type);
|
||||
addEntry(name, value, type, write);
|
||||
return;
|
||||
}
|
||||
e._value = value;
|
||||
@@ -376,10 +376,14 @@ void PIConfig::removeEntry(Branch & b, PIConfig::Entry * e) {
|
||||
|
||||
|
||||
void PIConfig::writeAll() {
|
||||
//cout << this << " write < " << size() << endl;
|
||||
clear();
|
||||
//*this << "1234567894132456798\n"; return;
|
||||
//writeEntry(&root);
|
||||
buildFullNames(&root);
|
||||
Branch b = allLeaves();
|
||||
//for (int i = 0; i < b.size_s(); ++i)
|
||||
// cout << b[i]->_name << " = " << b[i]->_value << endl;
|
||||
int j = 0;
|
||||
for (int i = 0; i < other.size_s(); ++i) {
|
||||
//cout << j << endl;
|
||||
@@ -387,25 +391,27 @@ void PIConfig::writeAll() {
|
||||
if (b[j]->_line == i) {
|
||||
b[j]->buildLine();
|
||||
*this << b[j]->_all << '\n';
|
||||
//cout << this << " " << b[j]->_all << endl;
|
||||
++j;
|
||||
} else {
|
||||
*this << other[i];
|
||||
if (i < other.size_s() - 1) *this << '\n';
|
||||
//cout << this << " " << other[i] << endl;
|
||||
}
|
||||
} else {
|
||||
*this << other[i];
|
||||
if (i < other.size_s() - 1) *this << '\n';
|
||||
//cout << this << " " << other[i] << endl;
|
||||
}
|
||||
//cout << other[i] << endl;
|
||||
}
|
||||
flush();
|
||||
readAll();
|
||||
//cout << this << " write > " << size() << endl;
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::readAll() {
|
||||
root.clear();
|
||||
flush();
|
||||
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 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 Branch;
|
||||
public:
|
||||
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 Branch: public PIVector<Entry * > {
|
||||
class PIP_EXPORT Branch: public PIVector<Entry * > {
|
||||
friend class PIConfig;
|
||||
friend class Entry;
|
||||
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 Branch;
|
||||
public:
|
||||
|
||||
@@ -20,12 +20,15 @@
|
||||
#include "piconsole.h"
|
||||
|
||||
|
||||
extern PIMutex __PICout_mutex__;
|
||||
|
||||
|
||||
PIConsole::PIConsole(bool startNow, KBFunc slot): PIThread() {
|
||||
setPriority(piLow);
|
||||
needLockRun(true);
|
||||
ret_func = slot;
|
||||
num_format = 0;
|
||||
cur_tab = width = height = pwidth = pheight = my = 0;
|
||||
cur_tab = width = height = pwidth = pheight = max_y = 0;
|
||||
def_align = Nothing;
|
||||
#ifdef WINDOWS
|
||||
ulcoord.X = ulcoord.Y = 0;
|
||||
@@ -93,9 +96,11 @@ bool PIConsole::setTab(uint index) {
|
||||
return true;
|
||||
}
|
||||
lock();
|
||||
__PICout_mutex__.lock();
|
||||
cur_tab = index;
|
||||
clearScreen();
|
||||
fillLabels();
|
||||
__PICout_mutex__.unlock();
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
@@ -135,6 +140,23 @@ bool PIConsole::setTabBindKey(const PIString & name, char bind_key) {
|
||||
|
||||
void PIConsole::key_event(char key, void * 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) {
|
||||
if (p->tabs[i].key == key) {
|
||||
p->setTab(i);
|
||||
@@ -148,7 +170,7 @@ void PIConsole::key_event(char key, void * t) {
|
||||
void PIConsole::stop(bool clear) {
|
||||
PIThread::stop(true);
|
||||
if (clear) clearScreen();
|
||||
moveTo(0, my + 4);
|
||||
moveTo(0, max_y + 4);
|
||||
showCursor();
|
||||
couts(fstr(Normal));
|
||||
#ifdef WINDOWS
|
||||
@@ -273,9 +295,12 @@ void PIConsole::begin() {
|
||||
#ifdef WINDOWS
|
||||
SetConsoleMode(hOut, ENABLE_WRAP_AT_EOL_OUTPUT);
|
||||
#endif
|
||||
max_y = 0;
|
||||
__PICout_mutex__.lock();
|
||||
clearScreen();
|
||||
hideCursor();
|
||||
fillLabels();
|
||||
__PICout_mutex__.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -292,6 +317,7 @@ void PIConsole::run() {
|
||||
width = ws.ws_col;
|
||||
height = ws.ws_row;
|
||||
#endif
|
||||
__PICout_mutex__.lock();
|
||||
if (pwidth != width || pheight != height) {
|
||||
clearScreen();
|
||||
fillLabels();
|
||||
@@ -304,7 +330,7 @@ void PIConsole::run() {
|
||||
PIVector<Variable> & cvars(tabs[cur_tab].columns[i].variables);
|
||||
cx = col_wid * i;
|
||||
toUpperLeft();
|
||||
if (my < cvars.size()) my = cvars.size();
|
||||
if (max_y < cvars.size()) max_y = cvars.size();
|
||||
j = 0;
|
||||
piForeachC (Variable & tv, cvars) {
|
||||
if (j > height - 3) continue;
|
||||
@@ -343,13 +369,19 @@ void PIConsole::run() {
|
||||
newLine();
|
||||
}
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
moveTo(0, max_y + 1);
|
||||
#else
|
||||
moveTo(0, max_y + 2);
|
||||
#endif
|
||||
fflush(0);
|
||||
__PICout_mutex__.unlock();
|
||||
}
|
||||
|
||||
|
||||
void PIConsole::fillLabels() {
|
||||
if (!isRunning()) return;
|
||||
uint cx, cy, my = 0, mx = 0, dx;
|
||||
uint cx, cy, mx = 0, dx;
|
||||
#ifdef WINDOWS
|
||||
GetConsoleScreenBufferInfo(hOut, &sbi);
|
||||
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
||||
@@ -360,6 +392,7 @@ void PIConsole::fillLabels() {
|
||||
width = ws.ws_col;
|
||||
height = ws.ws_row;
|
||||
#endif
|
||||
max_y = 0;
|
||||
col_cnt = columns().size();
|
||||
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
||||
for (uint i = 0; i < col_cnt; ++i) {
|
||||
@@ -378,7 +411,7 @@ void PIConsole::fillLabels() {
|
||||
toUpperLeft();
|
||||
for (uint j = 0; j < cvars.size(); ++j) {
|
||||
if (int(j) > height - 3) continue;
|
||||
if (my < j) my = j;
|
||||
if (max_y < j) max_y = j;
|
||||
moveRight(cx);
|
||||
Variable & tv(cvars[j]);
|
||||
cvars[j].nx = cx;
|
||||
@@ -426,9 +459,9 @@ void PIConsole::fillLabels() {
|
||||
}
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
moveTo(0, my + 1);
|
||||
moveTo(0, max_y + 1);
|
||||
#else
|
||||
moveTo(0, my + 2);
|
||||
moveTo(0, max_y + 2);
|
||||
#endif
|
||||
if (!tabs[cur_tab].status.isEmpty()) {
|
||||
printValue(tabs[cur_tab].status);
|
||||
@@ -446,6 +479,9 @@ void PIConsole::status() {
|
||||
ctab = &tabs[i];
|
||||
if (ctab->key == 0) continue;
|
||||
printValue(ctab->key, PIConsole::White | PIConsole::Bold);
|
||||
if (i == cur_tab)
|
||||
printValue(ctab->name + " ", PIConsole::BackYellow | PIConsole::Black);
|
||||
else
|
||||
printValue(ctab->name + " ", PIConsole::Cyan | PIConsole::Inverse);
|
||||
printValue(" ");
|
||||
}
|
||||
@@ -522,10 +558,10 @@ void PIConsole::addVariable(const PIString & name, const PIProtocol * ptr, int c
|
||||
addString("protocol " + name, col, format | PIConsole::Bold);
|
||||
addVariable("Rec - " + ptr->receiverDeviceName(), ptr->receiverDeviceState_ptr(), col, format);
|
||||
addVariable("Send - " + ptr->senderDeviceName(), ptr->senderDeviceState_ptr(), col, format);
|
||||
addVariable("Sended count", ptr->sendCount_ptr(), col, format);
|
||||
addVariable("Received count", ptr->receiveCount_ptr(), col, format);
|
||||
addVariable("Invalid count", ptr->wrongCount_ptr(), col, format);
|
||||
addVariable("Missed count", ptr->missedCount_ptr(), col, format);
|
||||
addVariable("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);
|
||||
@@ -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("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) {
|
||||
addString("monitor " + name, col, format | PIConsole::Bold);
|
||||
addVariable("state", &(ptr->statistic().state), col, format);
|
||||
|
||||
21
piconsole.h
21
piconsole.h
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "pikbdlistener.h"
|
||||
#include "piprotocol.h"
|
||||
#include "pidiagnostics.h"
|
||||
#include "pisystemmonitor.h"
|
||||
#ifndef WINDOWS
|
||||
# include <sys/ioctl.h>
|
||||
@@ -32,8 +33,9 @@
|
||||
/// void clearVariables(bool clearScreen = true)
|
||||
/// void start(bool wait = false)
|
||||
/// void stop(bool clear = false)
|
||||
class PIConsole: public PIThread
|
||||
class PIP_EXPORT PIConsole: public PIThread
|
||||
{
|
||||
PIOBJECT(PIConsole)
|
||||
public:
|
||||
PIConsole(bool startNow = true, KBFunc slot = 0);
|
||||
~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 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 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 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);
|
||||
@@ -117,14 +120,14 @@ public:
|
||||
void setColumnAlignment(int col, Alignment align) {if (col < 0 || col >= columns().size_s()) return; column(col).alignment = align;}
|
||||
void setColumnAlignmentToAll(Alignment align) {piForeach (Tab & i, tabs) piForeach (Column & j, i.columns) j.alignment = align; fillLabels();}
|
||||
|
||||
EVENT_HANDLER0(PIConsole, void, clearVariables) {clearVariables(true);}
|
||||
EVENT_HANDLER1(PIConsole, void, clearVariables, bool, clearScreen) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} columns().clear();}
|
||||
EVENT_HANDLER0(void, clearVariables) {clearVariables(true);}
|
||||
EVENT_HANDLER1(void, clearVariables, bool, clearScreen) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} columns().clear();}
|
||||
|
||||
EVENT_HANDLER0(PIConsole, void, waitForFinish) {WAIT_FOR_EXIT}
|
||||
EVENT_HANDLER0(PIConsole, void, start) {start(false);}
|
||||
EVENT_HANDLER1(PIConsole, void, start, bool, wait) {PIThread::start(40); if (wait) waitForFinish();}
|
||||
EVENT_HANDLER0(PIConsole, void, stop) {stop(false);}
|
||||
EVENT_HANDLER1(PIConsole, void, stop, bool, clear);
|
||||
EVENT_HANDLER0(void, waitForFinish) {WAIT_FOR_EXIT}
|
||||
EVENT_HANDLER0(void, start) {start(false);}
|
||||
EVENT_HANDLER1(void, start, bool, wait) {PIThread::start(40); if (wait) waitForFinish();}
|
||||
EVENT_HANDLER0(void, stop) {stop(false);}
|
||||
EVENT_HANDLER1(void, stop, bool, clear);
|
||||
PIString fstr(PIFlags<PIConsole::Format> f);
|
||||
|
||||
void enableExitCapture(char key = 'Q') {listener->enableExitCapture(key);}
|
||||
@@ -273,7 +276,7 @@ private:
|
||||
Alignment def_align;
|
||||
KBFunc ret_func;
|
||||
int width, height, pwidth, pheight, ret, col_wid, num_format;
|
||||
uint my;
|
||||
uint max_y;
|
||||
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
|
||||
Generic containers, based on STL
|
||||
Generic containers based on STL
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -22,6 +28,37 @@
|
||||
|
||||
#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
|
||||
|
||||
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)
|
||||
|
||||
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>
|
||||
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 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]);}
|
||||
const T * data(int index = 0) const {return &(data_[index]);}
|
||||
@@ -370,35 +371,193 @@ private:
|
||||
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> >
|
||||
class PIVector: public vector<Type, Allocator> {
|
||||
class PIP_EXPORT PIVector: public vector<Type, Allocator> {
|
||||
typedef PIVector<Type, Allocator> _CVector;
|
||||
typedef vector<Type, Allocator> _stlc;
|
||||
public:
|
||||
//! Contructs an empty vector
|
||||
PIVector() {piMonitor.containers++;}
|
||||
|
||||
//! Contructs vector with single element "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);}
|
||||
|
||||
//! 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);}
|
||||
|
||||
//! 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);}
|
||||
|
||||
/*! \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() {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];}
|
||||
|
||||
/*! \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];}
|
||||
|
||||
/*! \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];}
|
||||
|
||||
/*! \brief Pointer to element by index "index"
|
||||
* \details Example: \snippet picontainers.cpp PIVector::data */
|
||||
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());}
|
||||
|
||||
//! Return \c "true" if vector is empty, i.e. size = 0
|
||||
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 * );
|
||||
|
||||
//! 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);}
|
||||
#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 & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
|
||||
_CVector & pop_front() {_stlc::erase(_stlc::begin()); return *this;}
|
||||
_CVector & push_front(const Type & t) {_stlc::insert(_stlc::begin(), t); return *this;}
|
||||
Type take_front() {Type t(_stlc::front()); pop_front(); 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 num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
||||
//_CVector & remove(const Type & t) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) {_stlc::erase(i); --i;} return *this;}
|
||||
_CVector & remove(uint index) {_stlc::erase(_stlc::begin() + index); return *this;}
|
||||
_CVector & remove(uint index, uint count) {_stlc::erase(_stlc::begin() + index, _stlc::begin() + index + count); return *this;}
|
||||
_CVector & removeOne(const Type & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); return *this;} return *this;}
|
||||
_CVector & removeAll(const Type & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); --i;} return *this;}
|
||||
_CVector & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
|
||||
@@ -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;}
|
||||
bool operator ==(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return false; return true;}
|
||||
bool operator !=(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return true; return false;}
|
||||
bool contain(const Type & v) const {for (uint i = 0; i < _stlc::size(); ++i) if (v == at(i)) return true; return false;}
|
||||
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>
|
||||
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> >
|
||||
class PIList: public list<Type, Allocator> {
|
||||
class PIP_EXPORT PIList: public list<Type, Allocator> {
|
||||
typedef PIList<Type, Allocator> _CList;
|
||||
typedef list<Type, Allocator> _stlc;
|
||||
public:
|
||||
@@ -431,16 +600,18 @@ public:
|
||||
Type * data(uint index = 0) {return &(*this)[index];}
|
||||
int size_s() const {return static_cast<int>(_stlc::size());}
|
||||
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 & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;}
|
||||
_CList & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
||||
_CList & remove(uint index) {_stlc::erase(_stlc::begin() + index); 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 & 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;}
|
||||
};
|
||||
|
||||
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 set<Type, Compare, Allocator> _stlc;
|
||||
public:
|
||||
@@ -452,15 +623,15 @@ public:
|
||||
~PISet() {piMonitor.containers--;}
|
||||
int size_s() const {return static_cast<int>(_stlc::size());}
|
||||
bool isEmpty() const {return _stlc::empty();}
|
||||
_CSet & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;}
|
||||
_CSet & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
||||
_CSet & remove(uint index) {_stlc::erase(_stlc::begin() + index); 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;}
|
||||
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;}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
class PIStack: public PIVector<Type> {
|
||||
class PIP_EXPORT PIStack: public PIVector<Type> {
|
||||
typedef PIStack<Type> _CStack;
|
||||
public:
|
||||
PIStack() {;}
|
||||
@@ -476,7 +647,7 @@ public:
|
||||
};
|
||||
|
||||
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 deque<Type, Allocator> _stlc;
|
||||
public:
|
||||
@@ -488,12 +659,14 @@ public:
|
||||
~PIDeque() {piMonitor.containers--;}
|
||||
int size_s() const {return static_cast<int>(_stlc::size());}
|
||||
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;}
|
||||
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>
|
||||
class PIQueue: public PIDeque<Type> {
|
||||
class PIP_EXPORT PIQueue: public PIDeque<Type> {
|
||||
typedef PIQueue<Type> _CQueue;
|
||||
public:
|
||||
PIQueue() {;}
|
||||
@@ -510,7 +683,7 @@ public:
|
||||
|
||||
|
||||
template<typename Type0, typename Type1>
|
||||
class PIPair {
|
||||
class PIP_EXPORT PIPair {
|
||||
public:
|
||||
PIPair() {first = Type0(); second = Type1();}
|
||||
PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;}
|
||||
@@ -519,21 +692,62 @@ public:
|
||||
};
|
||||
template<typename Type0, typename Type1>
|
||||
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>
|
||||
class PIMap: public map<Key, Type> {
|
||||
class PIP_EXPORT PIMap: public map<Key, Type> {
|
||||
typedef PIMap<Key, Type> _CMap;
|
||||
typedef map<Key, Type> _stlc;
|
||||
typedef std::pair<Key, Type> _stlpair;
|
||||
public:
|
||||
PIMap() {;}
|
||||
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;}
|
||||
_CMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(std::pair<Key, Type>(entry_.first, entry_.second)); return *this;}
|
||||
bool isEmpty() const {return _stlc::empty();}
|
||||
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();}
|
||||
Type & value(Key key_) {return (*this)[key_];}
|
||||
Type value(Key key_) const {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(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
|
||||
|
||||
4
picrc.h
4
picrc.h
@@ -23,7 +23,7 @@
|
||||
#include "pistring.h"
|
||||
|
||||
template <int L>
|
||||
class uint_cl {
|
||||
class PIP_EXPORT uint_cl {
|
||||
public:
|
||||
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];}
|
||||
@@ -160,7 +160,7 @@ inline std::ostream & operator <<(std::ostream & s, const uint_cl<L> & v) {std::
|
||||
|
||||
|
||||
template <uint L>
|
||||
class PICRC {
|
||||
class PIP_EXPORT PICRC {
|
||||
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, 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/stat.h>
|
||||
|
||||
class PIDir
|
||||
class PIP_EXPORT PIDir
|
||||
{
|
||||
public:
|
||||
PIDir();
|
||||
|
||||
117
piethernet.cpp
117
piethernet.cpp
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Ethernet, UDP
|
||||
Ethernet, UDP/TCP Broadcast/Multicast
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
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;
|
||||
ret_func_ = slot;
|
||||
connected_ = false;
|
||||
params = PIEthernet::ReuseAddress;
|
||||
params = (type == UDP ? PIEthernet::ReuseAddress : 0);
|
||||
server_thread_.setData(this);
|
||||
setThreadedReadBufferSize(65536);
|
||||
if (type_ != UDP) init();
|
||||
@@ -58,6 +58,7 @@ PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
|
||||
piMonitor.ethernets++;
|
||||
setPriority(piHigh);
|
||||
type_ = TCP_Client;
|
||||
path_ = ip_port;
|
||||
parseAddress(ip_port, &ip_s, &port_s);
|
||||
sock = sock_;
|
||||
sock_s = -1;
|
||||
@@ -80,22 +81,28 @@ PIEthernet::~PIEthernet() {
|
||||
bool PIEthernet::init() {
|
||||
//cout << "init " << type_ << endl;
|
||||
closeSocket(sock);
|
||||
int st = 0;
|
||||
int st = 0, pr = 0;;
|
||||
#ifdef WINDOWS
|
||||
int flags = WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF;
|
||||
int flags = 0;
|
||||
#else
|
||||
int so = 1;
|
||||
#endif
|
||||
if (type_ == UDP) st = SOCK_DGRAM;
|
||||
else st = SOCK_STREAM;
|
||||
if (type_ == UDP) {
|
||||
st = SOCK_DGRAM;
|
||||
pr = IPPROTO_UDP;
|
||||
} else {
|
||||
st = SOCK_STREAM;
|
||||
pr = IPPROTO_TCP;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
if (type_ == UDP) flags = WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF;
|
||||
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
|
||||
sock = socket(AF_INET, st, type_ == UDP ? IPPROTO_UDP : IPPROTO_TCP);
|
||||
sock = socket(AF_INET, st, pr);
|
||||
#endif
|
||||
if (sock == -1) {
|
||||
piCout << "[PIEthernet] Cant`t create socket, " << EthErrorString() << endl;
|
||||
piCout << "[PIEthernet] Cant`t create socket, " << ethErrorString();
|
||||
return false;
|
||||
}
|
||||
#ifndef WINDOWS
|
||||
@@ -116,9 +123,11 @@ void PIEthernet::parseAddress(const PIString & ipp, PIString * ip, int * port) {
|
||||
|
||||
bool PIEthernet::openDevice() {
|
||||
if (connected_) return true;
|
||||
if (sock == -1) init();
|
||||
init();
|
||||
if (sock == -1 || path_.isEmpty()) return false;
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
if (type_ != UDP)
|
||||
return true;
|
||||
//cout << " bind to " << sock << ": " << (params[PIEthernet::Broadcast] ? "0.0.0.0" : path_) << ": " << port_ << " ..." <<endl;
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
addr_.sin_family = AF_INET;
|
||||
@@ -134,9 +143,12 @@ bool PIEthernet::openDevice() {
|
||||
tries++;
|
||||
}
|
||||
if (tries == 10) {
|
||||
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << EthErrorString() << endl;
|
||||
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
||||
return false;
|
||||
}
|
||||
opened_ = true;
|
||||
while (!mcast_queue.isEmpty())
|
||||
joinMulticastGroup(mcast_queue.dequeue());
|
||||
//cout << "!" << endl;
|
||||
return true;
|
||||
}
|
||||
@@ -150,6 +162,7 @@ bool PIEthernet::closeDevice() {
|
||||
delete i;
|
||||
clients_.clear();
|
||||
if (server_thread_.isRunning()) server_thread_.terminate();
|
||||
if (connected_) disconnected(false);
|
||||
connected_ = false;
|
||||
return true;
|
||||
}
|
||||
@@ -159,9 +172,15 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
if (type_ != UDP) {
|
||||
piCout << "[PIEthernet] Only UDP sockets can join multicast groups" << endl;
|
||||
piCout << "[PIEthernet] Only UDP sockets can join multicast groups";
|
||||
return false;
|
||||
}
|
||||
if (!opened_) {
|
||||
if (mcast_queue.has(group))
|
||||
return false;
|
||||
mcast_queue.enqueue(group);
|
||||
return true;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
@@ -170,23 +189,23 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
addr_.sin_addr.s_addr = inet_addr(group.data());
|
||||
SOCKET ret = WSAJoinLeaf(sock, (sockaddr *)&addr_, sizeof(addr_), NULL, NULL, NULL, NULL, JL_BOTH);
|
||||
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;
|
||||
}
|
||||
leafs.insert(group, ret);
|
||||
#else
|
||||
# ifndef QNX
|
||||
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_);
|
||||
struct ip_mreqn mreq;
|
||||
memset(&mreq, 0, sizeof(mreq));
|
||||
if (params[PIEthernet::Broadcast]) mreq.imr_address.s_addr = INADDR_ANY;
|
||||
else mreq.imr_address.s_addr = inet_addr(ip_.data());
|
||||
/*if (params[PIEthernet::Broadcast]) mreq.imr_address.s_addr = INADDR_ANY;
|
||||
else*/ mreq.imr_address.s_addr = inet_addr(ip_.data());
|
||||
mreq.imr_multiaddr.s_addr = inet_addr(group.data());
|
||||
mreq.imr_ifindex = 0;
|
||||
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;
|
||||
}
|
||||
# endif
|
||||
@@ -199,7 +218,7 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
if (type_ != UDP) {
|
||||
piCout << "[PIEthernet] Only UDP sockets can leave multicast groups" << endl;
|
||||
piCout << "[PIEthernet] Only UDP sockets can leave multicast groups";
|
||||
return false;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
@@ -218,7 +237,7 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
||||
mreq.imr_multiaddr.s_addr = inet_addr(group.data());
|
||||
mreq.imr_ifindex = 0;
|
||||
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;
|
||||
}
|
||||
#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;
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
addr_.sin_port = htons(port);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip.data());
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
addr_.sin_port = htons(port_);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||
addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
addr_.sin_len = sizeof(addr_);
|
||||
#endif
|
||||
//piCout << "[PIEthernet] connect to " << ip << ":" << port << endl;
|
||||
//piCout << "[PIEthernet] connect to " << ip << ":" << port_;
|
||||
connected_ = (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) == 0);
|
||||
if (!connected_)
|
||||
piCout << "[PIEthernet] Cant`t connect to " << ip << ":" << port << ", " << EthErrorString() << endl;
|
||||
piCout << "[PIEthernet] Cant`t connect to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
||||
opened_ = connected_;
|
||||
if (connected_) connected();
|
||||
return connected_;
|
||||
}
|
||||
|
||||
@@ -262,14 +283,14 @@ bool PIEthernet::listen() {
|
||||
tries++;
|
||||
}
|
||||
if (tries == 10) {
|
||||
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << EthErrorString() << endl;
|
||||
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
//piCout << "[PIEthernet] listen on " << ip_ << ":" << port_ << endl;
|
||||
//piCout << "[PIEthernet] listen on " << ip_ << ":" << port_;
|
||||
server_thread_.start(server_func);
|
||||
return true;
|
||||
}
|
||||
@@ -288,19 +309,27 @@ int PIEthernet::read(void * read_to, int max_size) {
|
||||
::listen(sock, 64);
|
||||
s = accept(sock, (sockaddr * )&client_addr, &slen);
|
||||
if (s == -1) {
|
||||
piCout << "[PIEthernet] Cant`t accept new connection, " << EthErrorString() << endl;
|
||||
piCout << "[PIEthernet] Cant`t accept new connection, " << ethErrorString();
|
||||
return -1;
|
||||
}
|
||||
rs = recv(s, (char * )read_to, max_size, 0);
|
||||
closeSocket(s);
|
||||
return rs;
|
||||
case UDP: case TCP_Client:
|
||||
case TCP_Client:
|
||||
if (!connected_) return -1;
|
||||
case UDP:
|
||||
#ifdef WINDOWS
|
||||
rs = recv(sock, (char * )read_to, max_size, 0);
|
||||
#else
|
||||
rs = recv(sock, read_to, max_size, 0);
|
||||
#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 ::read(sock, read_to, max_size);
|
||||
default: break;
|
||||
@@ -313,10 +342,10 @@ int PIEthernet::read(void * read_to, int max_size) {
|
||||
int PIEthernet::write(const void * data, int max_size) {
|
||||
if (sock == -1) init();
|
||||
if (sock == -1 || !isWriteable()) {
|
||||
//piCout << "[PIEthernet] Can`t send to uninitialized socket" << endl;
|
||||
//piCout << "[PIEthernet] Can`t send to uninitialized socket";
|
||||
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;
|
||||
switch (type_) {
|
||||
case TCP_SingleTCP:
|
||||
@@ -327,11 +356,14 @@ int PIEthernet::write(const void * data, int max_size) {
|
||||
#ifdef QNX
|
||||
addr_.sin_len = sizeof(addr_);
|
||||
#endif
|
||||
//piCout << "connect SingleTCP" << ip_s << ":" << port_s << "...";
|
||||
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;
|
||||
}
|
||||
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);
|
||||
init();
|
||||
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_));
|
||||
#endif
|
||||
case TCP_Client:
|
||||
return ::write(sock, data, max_size);
|
||||
return ::send(sock, (const char *)data, max_size, 0);
|
||||
default: break;
|
||||
//return ::read(sock, read_to, max_size);
|
||||
}
|
||||
@@ -359,12 +391,13 @@ void PIEthernet::server_func(void * eth) {
|
||||
socklen_t slen = sizeof(client_addr);
|
||||
int s = accept(ce->sock, (sockaddr * )&client_addr, &slen);
|
||||
if (s == -1) {
|
||||
piCout << "[PIEthernet] Cant`t accept new connection, " << EthErrorString() << endl;
|
||||
piCout << "[PIEthernet] Cant`t accept new connection, " << ethErrorString();
|
||||
return;
|
||||
}
|
||||
PIString ip(inet_ntoa(client_addr.sin_addr));
|
||||
ip += ":" + PIString::fromNumber(htons(client_addr.sin_port));
|
||||
ce->clients_ << new PIEthernet(s, ip);
|
||||
ce->newConnection(ce->clients_.back());
|
||||
//cout << "connected " << ip << endl;
|
||||
//char d[256];
|
||||
//cout << " recv " << recv(s, d, 256, 0) << endl;
|
||||
@@ -375,7 +408,7 @@ void PIEthernet::server_func(void * eth) {
|
||||
|
||||
PIStringList PIEthernet::interfaces() {
|
||||
#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();
|
||||
#else
|
||||
# ifdef QNX
|
||||
@@ -434,7 +467,7 @@ PIStringList PIEthernet::interfaces() {
|
||||
|
||||
PIString PIEthernet::interfaceAddress(const PIString & interface_) {
|
||||
#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();
|
||||
#else
|
||||
struct ifreq ifr;
|
||||
@@ -459,14 +492,14 @@ PIStringList PIEthernet::allAddresses() {
|
||||
ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||
pAdapterInfo = (IP_ADAPTER_INFO * ) HeapAlloc(GetProcessHeap(), 0, (sizeof (IP_ADAPTER_INFO)));
|
||||
if (pAdapterInfo == 0) {
|
||||
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersinfo" << endl;
|
||||
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersinfo";
|
||||
return PIStringList();
|
||||
}
|
||||
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
|
||||
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
||||
pAdapterInfo = (IP_ADAPTER_INFO *) HeapAlloc(GetProcessHeap(), 0, (ulOutBufLen));
|
||||
if (pAdapterInfo == 0) {
|
||||
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersinfo" << endl;
|
||||
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersinfo";
|
||||
return PIStringList();
|
||||
}
|
||||
}
|
||||
@@ -482,7 +515,7 @@ PIStringList PIEthernet::allAddresses() {
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
} else
|
||||
piCout << "[PIEthernet] GetAdaptersInfo failed with error: " << ret << endl;
|
||||
piCout << "[PIEthernet] GetAdaptersInfo failed with error: " << ret;
|
||||
if (pAdapterInfo)
|
||||
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
||||
return al;
|
||||
@@ -490,6 +523,6 @@ PIStringList PIEthernet::allAddresses() {
|
||||
PIStringList il = interfaces(), al;
|
||||
piForeachC (PIString & i, il)
|
||||
al << interfaceAddress(i);
|
||||
return al;
|
||||
return al.removeStrings("0.0.0.0");
|
||||
#endif
|
||||
}
|
||||
|
||||
26
piethernet.h
26
piethernet.h
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Ethernet, UDP
|
||||
Ethernet, UDP/TCP Broadcast/Multicast
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -24,8 +24,9 @@
|
||||
#include "piiodevice.h"
|
||||
#include "piprocess.h"
|
||||
|
||||
class PIEthernet: public PIIODevice
|
||||
class PIP_EXPORT PIEthernet: public PIIODevice
|
||||
{
|
||||
PIOBJECT(PIEthernet)
|
||||
friend class PIPeer;
|
||||
public:
|
||||
// slot is any function format "bool <func>(void*, uchar*, int)"
|
||||
@@ -35,7 +36,7 @@ public:
|
||||
enum Parameters {ReuseAddress = 0x1, Broadcast = 0x2};
|
||||
|
||||
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_port) {path_ = ip_port;}
|
||||
@@ -61,8 +62,9 @@ public:
|
||||
bool joinMulticastGroup(const PIString & group);
|
||||
bool leaveMulticastGroup(const PIString & group);
|
||||
|
||||
bool connect(const PIString & ip, int port);
|
||||
bool connect(const PIString & ip_port) {parseAddress(ip_port, &ip_c, &port_c); return connect(ip_c, port_c);}
|
||||
bool connect();
|
||||
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 listen();
|
||||
@@ -73,9 +75,10 @@ public:
|
||||
int clientsCount() const {return clients_.size_s();}
|
||||
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_port, const void * data, int size) {parseAddress(ip_port, &ip_s, &port_s); return send(data, size);}
|
||||
bool send(const void * data, int size) {return (write(data, size) == size);}
|
||||
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, 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, 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 write(const void * data, int max_size);
|
||||
@@ -85,6 +88,10 @@ public:
|
||||
static PIString interfaceAddress(const PIString & interface_);
|
||||
static PIStringList allAddresses();
|
||||
|
||||
EVENT1(newConnection, PIEthernet * , client)
|
||||
EVENT0(connected)
|
||||
EVENT1(disconnected, bool, withError)
|
||||
|
||||
protected:
|
||||
PIEthernet(int sock, PIString ip_port);
|
||||
|
||||
@@ -106,6 +113,7 @@ protected:
|
||||
PIString ip_, ip_s, ip_c;
|
||||
PIThread server_thread_;
|
||||
PIVector<PIEthernet * > clients_;
|
||||
PIQueue<PIString> mcast_queue;
|
||||
#ifdef WINDOWS
|
||||
PIMap<PIString, SOCKET> leafs;
|
||||
#endif
|
||||
@@ -115,7 +123,7 @@ protected:
|
||||
private:
|
||||
static void server_func(void * eth);
|
||||
|
||||
static std::string EthErrorString() {
|
||||
static std::string ethErrorString() {
|
||||
#ifdef WINDOWS
|
||||
char * msg;
|
||||
int err = WSAGetLastError();
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace PIEvaluatorTypes {
|
||||
⋀ &
|
||||
⋁ |
|
||||
*/
|
||||
class PIEvaluatorContent
|
||||
class PIP_EXPORT PIEvaluatorContent
|
||||
{
|
||||
friend class PIEvaluator;
|
||||
public:
|
||||
@@ -108,7 +108,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class PIEvaluator
|
||||
class PIP_EXPORT PIEvaluator
|
||||
{
|
||||
public:
|
||||
PIEvaluator() {;}
|
||||
|
||||
@@ -32,7 +32,7 @@ bool PIFile::openDevice() {
|
||||
|
||||
|
||||
bool PIFile::closeDevice() {
|
||||
if (!opened_) return true;
|
||||
if (!opened_ || fd == 0) return true;
|
||||
return (fclose(fd) == 0);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ void PIFile::resize(llong new_size, char fill_) {
|
||||
delete[] buff;
|
||||
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 resize(llong new_size, char fill = 0)
|
||||
/// void remove()
|
||||
class PIFile: public PIIODevice
|
||||
class PIP_EXPORT PIFile: public PIIODevice
|
||||
{
|
||||
PIOBJECT(PIFile)
|
||||
public:
|
||||
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;}
|
||||
|
||||
void flush() {fflush(fd);}
|
||||
EVENT_HANDLER(PIFile, void, clear) {close(); fd = fopen(path_.data(), "w"); close(); open();}
|
||||
void flush() {if (!opened_) fflush(fd);}
|
||||
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 seekToBegin() {if (!opened_) return; fseek(fd, 0, SEEK_SET); clearerr(fd);}
|
||||
void seekToEnd() {if (!opened_) return; fseek(fd, 0, SEEK_END); clearerr(fd);}
|
||||
void seekToLine(llong line) {if (!opened_) return; seekToBegin(); piForTimes (line) readLine(); clearerr(fd);} // line 0 - begin of file
|
||||
EVENT_HANDLER1(PIFile, void, resize, llong, new_size) {resize(new_size, 0);}
|
||||
EVENT_HANDLER2(PIFile, void, resize, llong, new_size, char, fill);
|
||||
EVENT_HANDLER1(void, resize, llong, new_size) {resize(new_size, 0);}
|
||||
EVENT_HANDLER2(void, resize, llong, new_size, char, fill);
|
||||
//void fill(char c) {stream.fill(c);}
|
||||
char readChar() {return (char)fgetc(fd);}
|
||||
PIString readLine();
|
||||
llong readAll(void * data);
|
||||
PIByteArray readAll(bool forceRead = false);
|
||||
EVENT_HANDLER0(PIFile, void, remove) {close(); std::remove(path_.data());}
|
||||
EVENT_HANDLER0(void, remove) {close(); std::remove(path_.data());}
|
||||
|
||||
void setPath(const PIString & path) {path_ = path; if (opened_) openDevice();}
|
||||
llong size();
|
||||
@@ -56,11 +58,11 @@ public:
|
||||
bool isEmpty() {return (size() <= 0);}
|
||||
|
||||
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 write(const void * data, int max_size) {if (!canWrite()) return -1; return fwrite(data, max_size, 1, fd);}
|
||||
PIFile & writeToBinLog(ushort id, const void * data, int size) {if (!isWriteable()) return *this; writeBinary(id).writeBinary((ushort)size); write(data, size); flush(); return *this;}
|
||||
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() || fd == 0) return -1; return fwrite(data, max_size, 1, fd);}
|
||||
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 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 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 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;}
|
||||
@@ -83,11 +87,11 @@ public:
|
||||
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 <<(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 <<(ushort v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%hd", v); return *this;}
|
||||
PIFile & operator <<(uint v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%d", v); return *this;}
|
||||
PIFile & operator <<(ulong v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%ld", v); return *this;}
|
||||
PIFile & operator <<(ullong v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%lld", 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, "%hu", 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, "%lu", 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 <<(double v) {if (!isWriteable()) return *this; ret = fprintf(fd, ("%" + prec_str + "lf").c_str(), v); return *this;}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "pimath.h"
|
||||
|
||||
template<typename Type>
|
||||
class PIPoint {
|
||||
class PIP_EXPORT PIPoint {
|
||||
public:
|
||||
Type x;
|
||||
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;}
|
||||
|
||||
template<typename Type>
|
||||
class PIRect {
|
||||
class PIP_EXPORT PIRect {
|
||||
public:
|
||||
Type x0;
|
||||
Type y0;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "piincludes.h"
|
||||
#include "pimutex.h"
|
||||
|
||||
bool isPIInit = false;
|
||||
bool piDebug = true;
|
||||
@@ -29,3 +30,41 @@ lconv * currentLocale = std::localeconv();
|
||||
#ifdef MAC_OS
|
||||
clock_serv_t __pi_mac_clock;
|
||||
#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
|
||||
Global includes
|
||||
@@ -20,12 +26,58 @@
|
||||
#ifndef 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
|
||||
|
||||
//! Minor value of PIP version
|
||||
#define PIP_VERSION_MINOR (PIP_VERSION & 0xFF00) >> 8
|
||||
|
||||
//! Revision value of PIP version
|
||||
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF
|
||||
|
||||
//! Suffix of PIP version
|
||||
#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__
|
||||
# define WINDOWS
|
||||
#endif
|
||||
@@ -60,6 +112,13 @@
|
||||
#else
|
||||
# define CC_OTHER
|
||||
#endif
|
||||
#ifdef PIP_DEBUG
|
||||
# undef NDEBUG
|
||||
#else
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS
|
||||
# ifdef CC_GCC
|
||||
@@ -69,6 +128,11 @@
|
||||
# define typeof __typeof__
|
||||
#endif
|
||||
|
||||
#include "pip_export.h"
|
||||
#if defined(DOXYGEN) || defined(CC_GCC)
|
||||
# undef PIP_EXPORT
|
||||
# define PIP_EXPORT
|
||||
#endif
|
||||
#include <iostream>
|
||||
#ifdef CC_GCC
|
||||
# include <unistd.h>
|
||||
@@ -90,6 +154,7 @@
|
||||
#include <cctype>
|
||||
#include <ctime>
|
||||
#include <csignal>
|
||||
#include <cassert>
|
||||
//#include <signal.h>
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
@@ -153,7 +218,10 @@ extern char ** environ;
|
||||
|
||||
extern PIMonitor piMonitor;
|
||||
|
||||
//! Macro used for infinite loop
|
||||
#define FOREVER for (;;)
|
||||
|
||||
//! Macro used for infinite wait
|
||||
#define FOREVER_WAIT FOREVER msleep(1);
|
||||
|
||||
typedef long long llong;
|
||||
@@ -175,6 +243,7 @@ using std::deque;
|
||||
using std::stack;
|
||||
using std::set;
|
||||
using std::map;
|
||||
using std::multimap;
|
||||
using std::string;
|
||||
#ifndef QNX
|
||||
using std::wstring;
|
||||
@@ -188,15 +257,118 @@ typedef std::basic_string<wchar_t> wstring;
|
||||
static locale_t currentLocale_t = 0;
|
||||
#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;}
|
||||
|
||||
/*! \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));}
|
||||
|
||||
/*! \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);}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
/*! \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);}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
/*! \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);}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
/*! \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);}
|
||||
|
||||
/*! \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));}
|
||||
|
||||
#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>
|
||||
|
||||
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 {
|
||||
public:
|
||||
@@ -245,10 +418,8 @@ public:
|
||||
sigset_t ss;
|
||||
sigemptyset(&ss);
|
||||
sigaddset(&ss, SIGALRM);
|
||||
if (pthread_sigmask(SIG_BLOCK, &ss, 0) == -1) {
|
||||
//cout << "[PITimer] sigaction error: " << errorString() << endl;
|
||||
//return 0;
|
||||
}
|
||||
sigprocmask(SIG_BLOCK, &ss, 0);
|
||||
pthread_sigmask(SIG_BLOCK, &ss, 0);
|
||||
ifconfigPath = "/bin/ifconfig";
|
||||
if (!fileExists(ifconfigPath)) {
|
||||
ifconfigPath = "/sbin/ifconfig";
|
||||
@@ -305,8 +476,8 @@ inline double round(const double & v) {return floor(v + 0.5);}
|
||||
#endif
|
||||
|
||||
inline ushort letobe_s(ushort v) {return v = (v << 8) | (v >> 8);}
|
||||
inline bool atob(const string & str) { return str == "1" ? true : false;};
|
||||
inline string btos(const bool num) { return num ? "0" : "1";};
|
||||
inline bool atob(const string & str) {return str == "1" ? true : false;}
|
||||
inline string btos(const bool num) {return num ? "0" : "1";}
|
||||
inline string itos(const int num) {
|
||||
char ch[256];
|
||||
#ifndef CC_VC
|
||||
@@ -314,7 +485,7 @@ inline string itos(const int num) {
|
||||
#else
|
||||
sprintf_s(ch, 256, "%d", num);
|
||||
#endif
|
||||
return string(ch); };
|
||||
return string(ch);}
|
||||
inline string ltos(const long num) {
|
||||
char ch[256];
|
||||
#ifndef CC_VC
|
||||
@@ -322,23 +493,23 @@ inline string ltos(const long num) {
|
||||
#else
|
||||
sprintf_s(ch, 256, "%ld", num);
|
||||
#endif
|
||||
return string(ch); };
|
||||
return string(ch);}
|
||||
inline string uitos(const uint num) {
|
||||
char ch[256];
|
||||
#ifndef CC_VC
|
||||
sprintf(ch, "%ud", num);
|
||||
sprintf(ch, "%u", num);
|
||||
#else
|
||||
sprintf_s(ch, 256, "%ud", num);
|
||||
sprintf_s(ch, 256, "%u", num);
|
||||
#endif
|
||||
return string(ch); };
|
||||
return string(ch);}
|
||||
inline string ultos(const ulong num) {
|
||||
char ch[256];
|
||||
#ifndef CC_VC
|
||||
sprintf(ch, "%lud", num);
|
||||
sprintf(ch, "%lu", num);
|
||||
#else
|
||||
sprintf_s(ch, 256, "%lud", num);
|
||||
sprintf_s(ch, 256, "%lu", num);
|
||||
#endif
|
||||
return string(ch); };
|
||||
return string(ch);}
|
||||
inline string ftos(const float num) {
|
||||
char ch[256];
|
||||
#ifndef CC_VC
|
||||
@@ -346,7 +517,7 @@ inline string ftos(const float num) {
|
||||
#else
|
||||
sprintf_s(ch, 256, "%g", num);
|
||||
#endif
|
||||
return string(ch); };
|
||||
return string(ch);}
|
||||
inline string dtos(const double num) {
|
||||
char ch[256];
|
||||
#ifndef CC_VC
|
||||
@@ -354,9 +525,11 @@ inline string dtos(const double num) {
|
||||
#else
|
||||
sprintf_s(ch, 256, "%g", num);
|
||||
#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() {
|
||||
char * msg;
|
||||
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));}
|
||||
#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;}
|
||||
|
||||
/*! \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
|
||||
|
||||
@@ -20,6 +20,45 @@
|
||||
#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() {
|
||||
mode_ = ReadOnly;
|
||||
opened_ = init_ = thread_started_ = false;
|
||||
@@ -27,12 +66,18 @@ PIIODevice::PIIODevice(): PIThread() {
|
||||
reopen_timeout_ = 1000;
|
||||
ret_func_ = 0;
|
||||
ret_data_ = 0;
|
||||
tri = 0;
|
||||
buffer_tr.resize(4096);
|
||||
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
|
||||
CONNECT(void, &write_thread, started, this, write_func);
|
||||
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() {
|
||||
path_ = path;
|
||||
mode_ = type;
|
||||
@@ -41,8 +86,10 @@ PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode type, bool
|
||||
reopen_timeout_ = 1000;
|
||||
ret_func_ = 0;
|
||||
ret_data_ = 0;
|
||||
tri = 0;
|
||||
buffer_tr.resize(4096);
|
||||
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
|
||||
CONNECT(void, &write_thread, started, this, write_func);
|
||||
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() {
|
||||
thread_started_ = false;
|
||||
if (!isInitialized()) return;
|
||||
@@ -103,4 +165,14 @@ void PIIODevice::run() {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
141
piiodevice.h
141
piiodevice.h
@@ -1,3 +1,6 @@
|
||||
/*! \file piiodevice.h
|
||||
* \brief Abstract input/output device
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Abstract input/output device
|
||||
@@ -25,36 +28,59 @@
|
||||
// function executed from threaded read, pass ThreadedReadData, readedData, sizeOfData
|
||||
typedef bool (*ReadRetFunc)(void * , uchar * , int );
|
||||
|
||||
/// events:
|
||||
/// void opened()
|
||||
/// void closed()
|
||||
///
|
||||
/// handlers:
|
||||
/// bool open()
|
||||
/// bool open(const PIString & path)
|
||||
/// bool open(const DeviceMode & type)
|
||||
/// bool open(const PIString & path, const DeviceMode & type)
|
||||
/// bool close()
|
||||
/// bool initialize()
|
||||
/// void flush()
|
||||
class PIIODevice: public PIThread {
|
||||
// events:
|
||||
// void opened()
|
||||
// void closed()
|
||||
//
|
||||
// handlers:
|
||||
// bool open()
|
||||
// bool open(const PIString & path)
|
||||
// bool open(const DeviceMode & type)
|
||||
// bool open(const PIString & path, const DeviceMode & type)
|
||||
// bool close()
|
||||
// bool initialize()
|
||||
// void flush()
|
||||
|
||||
class PIP_EXPORT PIIODevice: public PIThread
|
||||
{
|
||||
PIOBJECT(PIIODevice)
|
||||
public:
|
||||
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);
|
||||
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_;}
|
||||
|
||||
//! Current path of device
|
||||
PIString path() const {return path_;}
|
||||
|
||||
//! return \b true if mode is ReadOnly or ReadWrite
|
||||
bool isReadable() const {return (mode_ & ReadOnly);}
|
||||
|
||||
//! return \b true if mode is WriteOnly or ReadWrite
|
||||
bool isWriteable() const {return (mode_ & WriteOnly);}
|
||||
|
||||
bool isInitialized() const {return init_;}
|
||||
|
||||
//! return \b true if device is successfully opened
|
||||
bool isOpened() const {return opened_;}
|
||||
|
||||
//! return \b true if device is closed
|
||||
bool isClosed() const {return !opened_;}
|
||||
|
||||
//! return \b true if device can read \b now
|
||||
bool canRead() const {return opened_ && (mode_ & ReadOnly);}
|
||||
|
||||
//! return \b true if device can write \b now
|
||||
bool canWrite() const {return opened_ && (mode_ & WriteOnly);}
|
||||
|
||||
|
||||
@@ -74,34 +100,83 @@ public:
|
||||
int threadedReadBufferSize() const {return buffer_tr.size_s();}
|
||||
const uchar * threadedReadBuffer() const {return buffer_tr.data();}
|
||||
|
||||
bool isThreadedRead() const {return isRunning();}
|
||||
void startThreadedRead() {if (!isRunning()) start();}
|
||||
void startThreadedRead(ReadRetFunc func) {ret_func_ = func; if (!isRunning()) start();}
|
||||
|
||||
|
||||
EVENT_HANDLER(PIIODevice, bool, open) {if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
||||
EVENT_HANDLER1(PIIODevice, bool, open, const PIString &, _path) {path_ = _path; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
||||
EVENT_HANDLER1(PIIODevice, bool, open, const DeviceMode &, _type) {mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
||||
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_;}
|
||||
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)
|
||||
bool isThreadedWrite() const {return write_thread.isRunning();}
|
||||
void startThreadedWrite() {if (!write_thread.isRunning()) write_thread.startOnce();}
|
||||
void stopThreadedWrite() {write_thread.stop();}
|
||||
void clearThreadedWriteQueue() {write_thread.lock(); write_queue.clear(); write_thread.unlock();}
|
||||
|
||||
|
||||
// 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
|
||||
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
|
||||
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());}
|
||||
|
||||
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:
|
||||
// Function executed before first openDevice() or from constructor
|
||||
@@ -124,14 +199,18 @@ protected:
|
||||
void * ret_data_;
|
||||
|
||||
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 run();
|
||||
void end() {terminate();}
|
||||
|
||||
PITimer timer;
|
||||
PIThread write_thread;
|
||||
PIByteArray buffer_in, buffer_tr;
|
||||
PIQueue<PIPair<PIByteArray, ullong> > write_queue;
|
||||
ullong tri;
|
||||
int readed_;
|
||||
|
||||
};
|
||||
|
||||
@@ -42,8 +42,8 @@ PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() {
|
||||
void PIKbdListener::begin() {
|
||||
//cout << "list begin" << endl;
|
||||
#ifdef WINDOWS
|
||||
SetConsoleMode(hIn, ENABLE_PROCESSED_INPUT);
|
||||
GetConsoleMode(hIn, &tmode);
|
||||
SetConsoleMode(hIn, ENABLE_PROCESSED_INPUT);
|
||||
#else
|
||||
struct termios term;
|
||||
tcgetattr(0, &term);
|
||||
@@ -55,17 +55,68 @@ void PIKbdListener::begin() {
|
||||
|
||||
|
||||
void PIKbdListener::run() {
|
||||
rc = 0;
|
||||
char lc = 0;
|
||||
#ifdef WINDOWS
|
||||
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
|
||||
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
|
||||
if (exit_enabled && rc == exit_key) {
|
||||
if (exit_enabled && ret == 1 && lc == exit_key) {
|
||||
PIKbdListener::exiting = true;
|
||||
return;
|
||||
}
|
||||
keyPressed(rc, data);
|
||||
if (ret_func != 0 && ret > 0) ret_func(rc, data);
|
||||
keyPressed(lc, data);
|
||||
if (ret_func != 0 && ret > 0) ret_func(lc, data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,25 +35,38 @@ typedef void (*KBFunc)(char, void * );
|
||||
/// handlers:
|
||||
/// void enableExitCapture(char key = 'Q')
|
||||
/// void setActive(bool yes = true)
|
||||
class PIKbdListener: public PIThread {
|
||||
class PIP_EXPORT PIKbdListener: public PIThread
|
||||
{
|
||||
PIOBJECT(PIKbdListener)
|
||||
friend class PIConsole;
|
||||
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 * )"
|
||||
PIKbdListener(KBFunc slot = 0, void * data = 0);
|
||||
~PIKbdListener() {terminate(); end();}
|
||||
|
||||
void setData(void * data_) {data = data_;}
|
||||
void setSlot(KBFunc slot_) {ret_func = slot_;}
|
||||
EVENT_HANDLER(PIKbdListener, void, enableExitCapture) {enableExitCapture('Q');}
|
||||
EVENT_HANDLER1(PIKbdListener, void, enableExitCapture, char, key) {exit_enabled = true; exit_key = key;}
|
||||
EVENT_HANDLER( void, enableExitCapture) {enableExitCapture('Q');}
|
||||
EVENT_HANDLER1(void, enableExitCapture, char, key) {exit_enabled = true; exit_key = key;}
|
||||
void disableExitCapture() {exit_enabled = false;}
|
||||
bool exitCaptured() const {return exit_enabled;}
|
||||
char exitKey() const {return exit_key;}
|
||||
bool isActive() {return is_active;}
|
||||
EVENT_HANDLER(PIKbdListener, void, setActive) {setActive(true);}
|
||||
EVENT_HANDLER1(PIKbdListener, void, setActive, bool, yes);
|
||||
EVENT_HANDLER(void, setActive) {setActive(true);}
|
||||
EVENT_HANDLER1(void, setActive, bool, yes);
|
||||
|
||||
EVENT2(PIKbdListener, keyPressed, char, key, void * , data)
|
||||
EVENT2(keyPressed, char, key, void * , data)
|
||||
|
||||
static bool exiting;
|
||||
|
||||
@@ -62,6 +75,8 @@ private:
|
||||
void run();
|
||||
void end();
|
||||
|
||||
void raiseSpecial();
|
||||
|
||||
KBFunc ret_func;
|
||||
char exit_key;
|
||||
bool exit_enabled, is_active;
|
||||
@@ -71,7 +86,7 @@ private:
|
||||
void * hIn;
|
||||
DWORD smode, tmode;
|
||||
#else
|
||||
char rc;
|
||||
int rc;
|
||||
int ret;
|
||||
struct termios sterm, tterm;
|
||||
#endif
|
||||
|
||||
24
pimath.h
24
pimath.h
@@ -99,13 +99,15 @@ inline double toDeg(double rad) {return rad * M_180_PI;}
|
||||
inline PIVector<double> abs(const PIVector<complexd> & v) {
|
||||
PIVector<double> result;
|
||||
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;
|
||||
}
|
||||
inline PIVector<double> abs(const PIVector<double> & v) {
|
||||
PIVector<double> result;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -117,7 +119,7 @@ class PIMathMatrixT;
|
||||
#define PIMV_FOR(v, s) for (uint v = s; v < Size; ++v)
|
||||
|
||||
template<uint Size, typename Type = double>
|
||||
class PIMathVectorT {
|
||||
class PIP_EXPORT PIMathVectorT {
|
||||
typedef PIMathVectorT<Size, Type> _CVector;
|
||||
public:
|
||||
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 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 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 & 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;}
|
||||
@@ -207,7 +209,7 @@ typedef PIMathVectorT<4u, double> PIMathVectorT4d;
|
||||
#define PIMM_FOR_R(v) for (uint v = 0; v < Rows; ++v)
|
||||
|
||||
template<uint Cols, uint Rows = Cols, typename Type = double>
|
||||
class PIMathMatrixT {
|
||||
class PIP_EXPORT PIMathMatrixT {
|
||||
typedef PIMathMatrixT<Cols, Rows, Type> _CMatrix;
|
||||
typedef PIMathMatrixT<Rows, Cols, Type> _CMatrixI;
|
||||
typedef PIMathVectorT<Rows, Type> _CMCol;
|
||||
@@ -417,7 +419,7 @@ class PIMathMatrix;
|
||||
#define PIMV_FOR(v, s) for (uint v = s; v < size_; ++v)
|
||||
|
||||
template<typename Type>
|
||||
class PIMathVector {
|
||||
class PIP_EXPORT PIMathVector {
|
||||
typedef PIMathVector<Type> _CVector;
|
||||
public:
|
||||
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 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 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 & 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;}
|
||||
@@ -499,7 +501,7 @@ typedef PIMathVector<double> PIMathVectord;
|
||||
#define PIMM_FOR_R(v) for (uint v = 0; v < rows_; ++v)
|
||||
|
||||
template<typename Type>
|
||||
class PIMathMatrix {
|
||||
class PIP_EXPORT PIMathMatrix {
|
||||
typedef PIMathMatrix<Type> _CMatrix;
|
||||
typedef PIMathVector<Type> _CMCol;
|
||||
typedef PIMathVector<Type> _CMRow;
|
||||
@@ -716,7 +718,7 @@ struct TransferFunction { // Для задания передаточной фу
|
||||
// Эйлера
|
||||
// Рунге-Кутта 4-го порядка
|
||||
// Адамса-Бэшфортса-Моултона 2, 3, 4 порядков
|
||||
class Solver
|
||||
class PIP_EXPORT Solver
|
||||
{
|
||||
public:
|
||||
enum Method {Global = -1,
|
||||
@@ -774,7 +776,7 @@ private:
|
||||
|
||||
|
||||
|
||||
class PIFFT
|
||||
class PIP_EXPORT PIFFT
|
||||
{
|
||||
public:
|
||||
PIFFT();
|
||||
@@ -827,7 +829,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class PIStatistic {
|
||||
class PIP_EXPORT PIStatistic {
|
||||
public:
|
||||
PIStatistic();
|
||||
bool calculate(const PIVector<double> &val);
|
||||
|
||||
@@ -20,7 +20,14 @@
|
||||
#ifndef 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:
|
||||
PIMonitor();
|
||||
|
||||
@@ -64,12 +64,12 @@ public:
|
||||
PIRepeater(const PIString & config, const PIString & name) {
|
||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||
if (!conf.isOpened()) {
|
||||
piCout << "[PIRepeater \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
|
||||
piCout << "[PIRepeater \"" << name << "\"] Can`t open \"" << config << "\"!";
|
||||
return;
|
||||
}
|
||||
PIConfig::Entry & b(conf.getValue(name));
|
||||
if (b.childCount() != 2) {
|
||||
piCout << "[PIRepeater \"" << name << "\"] \"" << config << "\" should consist 2 nodes!" << endl;
|
||||
piCout << "[PIRepeater \"" << name << "\"] \"" << config << "\" should consist 2 nodes!";
|
||||
return;
|
||||
}
|
||||
addProtocol(config, b.child(0)->fullName());
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
#define PIMUTEX_H
|
||||
|
||||
#include "piincludes.h"
|
||||
#ifdef CC_GCC
|
||||
#ifndef WINDOWS
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
class PIMutex
|
||||
class PIP_EXPORT PIMutex
|
||||
{
|
||||
public:
|
||||
#ifndef WINDOWS
|
||||
@@ -59,7 +59,8 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class PIMutexLocker
|
||||
|
||||
class PIP_EXPORT PIMutexLocker
|
||||
{
|
||||
public:
|
||||
PIMutexLocker(PIMutex * m): mutex(m) {mutex->lock();}
|
||||
|
||||
266
piobject.h
266
piobject.h
@@ -1,3 +1,8 @@
|
||||
/*! \file piobject.h
|
||||
* \brief Base object
|
||||
*
|
||||
* This file declare PIObject class and associated macros
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism
|
||||
@@ -22,31 +27,166 @@
|
||||
|
||||
#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()
|
||||
#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)
|
||||
#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)
|
||||
|
||||
#ifdef DOXYGEN
|
||||
|
||||
|
||||
/// \relatesalso PIObject \brief you should use this macro after class declaration to use EVENT and EVENT_HANDLER
|
||||
#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
|
||||
|
||||
/// 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()
|
||||
#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_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)
|
||||
#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)
|
||||
|
||||
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\", virtual ret name()
|
||||
#define EVENT_VHANDLER0(ret, name) virtual ret name()
|
||||
|
||||
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\", virtual ret name(type0 var0)
|
||||
#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
|
||||
|
||||
/// declare event \"event\" inside class \"obj\" with name \"name\", void name();
|
||||
#define EVENT0(obj, name) EVENT_HANDLER0(obj, void, name) {PIObject::raiseEvent(this, #name);}
|
||||
#define EVENT1(obj, name, a0, n0) EVENT_HANDLER1(obj, void, name, a0, n0) {PIObject::raiseEvent(this, #name, n0);}
|
||||
#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);}
|
||||
#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);}
|
||||
|
||||
/// \relatesalso PIObject \brief declare event \"event\" with name \"name\", void name();
|
||||
#define EVENT0(name) void name();
|
||||
|
||||
/// \relatesalso PIObject \brief declare event \"event\" with name \"name\", void name(type0 var0);
|
||||
#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
|
||||
|
||||
/// raise event \"event\" from object \"src\"
|
||||
#define RAISE_EVENT0(src, event) (src)->event();
|
||||
#define RAISE_EVENT1(src, event, v0) (src)->event(v0);
|
||||
#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_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, 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, 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, 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, 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, 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 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 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 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 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 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 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, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*))(&(dst)->__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, 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, 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, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dst)->__stat_eh_##handler##__));
|
||||
#define WEAK_CONNECT0(ret, src, event, dest, handler) PIObject::piConnect(src, #event, dest, (void*)(ret(*)(void*))(&(dest)->__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_CONNECT2(ret, a0, a1, src, event, dest, handler) PIObject::piConnect(src, #event, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__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_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_CONNECT WEAK_CONNECT0
|
||||
|
||||
/// piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dst\"
|
||||
#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, dst, handler) PIObject::piDisconnect(src, #event, dst, (void*)(ret(*)(void*, a0))(&(dst)->__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, 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, dst, handler) PIObject::piDisconnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dst)->__stat_eh_##handler##__));
|
||||
#define DISCONNECT0(ret, src, event, dest, handler) PIObject::piDisconnect(src, #event, dest, (void*)(ret(*)(void*))(&(dest)->__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 DISCONNECT2(ret, a0, a1, src, event, dest, handler) PIObject::piDisconnect(src, #event, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__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 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 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;
|
||||
public:
|
||||
@@ -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);}
|
||||
|
||||
1
pip.h
1
pip.h
@@ -29,3 +29,4 @@
|
||||
#include "pisystemmonitor.h"
|
||||
#include "pipeer.h"
|
||||
#include "picrc.h"
|
||||
#include "pistatemachine.h"
|
||||
|
||||
125
pip.pro
125
pip.pro
@@ -2,65 +2,82 @@
|
||||
# Automatically generated by qmake (2.01a) ?? ???. 5 22:55:18 2011
|
||||
######################################################################
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET = pip_test
|
||||
TEMPLATE = lib
|
||||
TARGET = pip
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
QT -= core gui
|
||||
LIBS = -lpthread -lrt
|
||||
CONFIG -= qt
|
||||
CONFIG += dll
|
||||
VERSION = 0.3.4
|
||||
|
||||
# Input
|
||||
HEADERS += pibitarray.h \
|
||||
pibytearray.h \
|
||||
pichar.h \
|
||||
picli.h \
|
||||
picodec.h \
|
||||
piconfig.h \
|
||||
piconsole.h \
|
||||
picontainers.h \
|
||||
pidir.h \
|
||||
piethernet.h \
|
||||
pievaluator.h \
|
||||
pifile.h \
|
||||
pigeometry.h \
|
||||
piincludes.h \
|
||||
pikbdlistener.h \
|
||||
pimath.h \
|
||||
pimonitor.h \
|
||||
pimultiprotocol.h \
|
||||
pimutex.h \
|
||||
piobject.h \
|
||||
pip.h \
|
||||
piprocess.h \
|
||||
piprotocol.h \
|
||||
piserial.h \
|
||||
pisignals.h \
|
||||
pistring.h \
|
||||
pisystemmonitor.h \
|
||||
pithread.h \
|
||||
HEADERS += \
|
||||
pivariable.h \
|
||||
pitimer.h \
|
||||
pivariable.h
|
||||
pithread.h \
|
||||
pisystemtests.h \
|
||||
pisystemmonitor.h \
|
||||
pistring.h \
|
||||
pisignals.h \
|
||||
piserial.h \
|
||||
piprotocol.h \
|
||||
piprocess.h \
|
||||
pipeer.h \
|
||||
pipacketextractor.h \
|
||||
pip.h \
|
||||
piobject.h \
|
||||
pimutex.h \
|
||||
pimultiprotocol.h \
|
||||
pimonitor.h \
|
||||
pimath.h \
|
||||
pikbdlistener.h \
|
||||
piiodevice.h \
|
||||
piincludes.h \
|
||||
pigeometry.h \
|
||||
pifile.h \
|
||||
pievaluator.h \
|
||||
piethernet.h \
|
||||
pidir.h \
|
||||
picrc.h \
|
||||
picontainers.h \
|
||||
piconsole.h \
|
||||
piconfig.h \
|
||||
picodec.h \
|
||||
picli.h \
|
||||
pichar.h \
|
||||
pibytearray.h \
|
||||
pibitarray.h
|
||||
SOURCES += main.cpp \
|
||||
pibytearray.cpp \
|
||||
picli.cpp \
|
||||
picodec.cpp \
|
||||
piconfig.cpp \
|
||||
piconsole.cpp \
|
||||
pidir.cpp \
|
||||
piethernet.cpp \
|
||||
pievaluator.cpp \
|
||||
pifile.cpp \
|
||||
pikbdlistener.cpp \
|
||||
pimath.cpp \
|
||||
pimonitor.cpp \
|
||||
pimultiprotocol.cpp \
|
||||
piobject.cpp \
|
||||
piprocess.cpp \
|
||||
piprotocol.cpp \
|
||||
piserial.cpp \
|
||||
pisignals.cpp \
|
||||
pistring.cpp \
|
||||
pisystemmonitor.cpp \
|
||||
pithread.cpp \
|
||||
pivariable.cpp \
|
||||
pitimer.cpp \
|
||||
pivariable.cpp
|
||||
pithread.cpp \
|
||||
pisystemtests.cpp \
|
||||
pisystemmonitor.cpp \
|
||||
pistring.cpp \
|
||||
pisignals.cpp \
|
||||
piserial.cpp \
|
||||
piprotocol.cpp \
|
||||
piprocess.cpp \
|
||||
pipeer.cpp \
|
||||
pipacketextractor.cpp \
|
||||
piobject.cpp \
|
||||
pimonitor.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.
|
||||
typedef bool (*HeaderCheckFunc)(void * , uchar * , uchar * , int );
|
||||
|
||||
class PIPacketExtractor: public PIIODevice
|
||||
class PIP_EXPORT PIPacketExtractor: public PIIODevice
|
||||
{
|
||||
public:
|
||||
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"
|
||||
|
||||
class PIPeer: public PIEthernet
|
||||
class PIP_EXPORT PIPeer: public PIEthernet
|
||||
{
|
||||
PIOBJECT(PIPeer)
|
||||
struct PeerInfo;
|
||||
friend PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v);
|
||||
friend PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v);
|
||||
@@ -37,7 +38,7 @@ protected:
|
||||
bool threadedRead(uchar * readed, int size);
|
||||
|
||||
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);
|
||||
|
||||
struct PeerInfo {
|
||||
|
||||
@@ -141,12 +141,12 @@ void PIProcess::run() {
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
CloseHandle(pi.hProcess);
|
||||
} else
|
||||
piCout << "[PIProcess] \"CreateProcess\" error, " << errorString() << endl;
|
||||
piCout << "[PIProcess] \"CreateProcess\" error, " << errorString();
|
||||
#else
|
||||
|
||||
//cout << "exec " << tf_in << ", " << tf_out << ", " << tf_err << endl;
|
||||
if (execve(str.c_str(), a, e) < 0)
|
||||
piCout << "[PIProcess] \"execve\" error, " << errorString() << endl;
|
||||
piCout << "[PIProcess] \"execve\" error, " << errorString();
|
||||
} else {
|
||||
msleep(1);
|
||||
//cout << "wait" << endl;
|
||||
|
||||
27
piprocess.h
27
piprocess.h
@@ -40,11 +40,12 @@
|
||||
/// bool exec(const PIString & program, const PIStringList & args)
|
||||
/// void terminate()
|
||||
/// bool waitForFinish(int timeout_msecs = 60000)
|
||||
class PIProcess: private PIThread
|
||||
class PIP_EXPORT PIProcess: private PIThread
|
||||
{
|
||||
PIOBJECT(PIProcess)
|
||||
public:
|
||||
PIProcess();
|
||||
~PIProcess();
|
||||
virtual ~PIProcess();
|
||||
|
||||
int exitCode() const {return exit_code;}
|
||||
#ifdef WINDOWS
|
||||
@@ -65,18 +66,18 @@ public:
|
||||
PIString workingDirectory() const {return wd;}
|
||||
void setWorkingDirectory(const PIString & path) {wd = path;}
|
||||
void resetWorkingDirectory() {wd.clear();}
|
||||
EVENT_HANDLER1(PIProcess, 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_HANDLER3(PIProcess, 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_HANDLER2(PIProcess, void, exec, const PIString & , program, const PIStringList & , args_) {args << program << args_; exec_();}
|
||||
EVENT_HANDLER1(void, exec, const PIString & , program) {args.clear(); args << program; exec_();}
|
||||
EVENT_HANDLER2(void, exec, const PIString & , program, const PIString & , arg) {args.clear(); args << program << arg; exec_();}
|
||||
EVENT_HANDLER3(void, exec, const PIString & , program, const PIString & , arg1, const PIString & , arg2) {args.clear(); args << program << arg1 << arg2; 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(void, exec, const PIString & , program, const PIStringList & , args_) {args << program << args_; exec_();}
|
||||
#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
|
||||
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
|
||||
EVENT_HANDLER(PIProcess, bool, waitForFinish) {return waitForFinish(60000);}
|
||||
EVENT_HANDLER1(PIProcess, bool, waitForFinish, int, timeout_msecs) {return PIThread::waitForFinish(timeout_msecs);}
|
||||
EVENT_HANDLER(bool, waitForFinish) {return waitForFinish(60000);}
|
||||
EVENT_HANDLER1(bool, waitForFinish, int, timeout_msecs) {return PIThread::waitForFinish(timeout_msecs);}
|
||||
PIByteArray readOutput() {f_out.open(PIIODevice::ReadOnly); return f_out.readAll();}
|
||||
PIByteArray readError() {f_err.open(PIIODevice::ReadOnly); return f_err.readAll();}
|
||||
|
||||
@@ -92,8 +93,8 @@ public:
|
||||
static int currentPID() {return getpid();}
|
||||
#endif
|
||||
|
||||
EVENT1(PIProcess, execStarted, PIString, program)
|
||||
EVENT2(PIProcess, execFinished, PIString, program, int, exit_code)
|
||||
EVENT1(execStarted, PIString, program)
|
||||
EVENT2(execFinished, PIString, program, int, exit_code)
|
||||
|
||||
private:
|
||||
virtual void run();
|
||||
|
||||
@@ -26,7 +26,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
PIObject::setName(name);
|
||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||
if (!conf.isOpened()) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!";
|
||||
devReceiverState = devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -41,7 +41,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
|
||||
/// receiver section
|
||||
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";
|
||||
return;
|
||||
}
|
||||
@@ -50,7 +50,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) dev = gdev;
|
||||
if (gok && ok && (dev != gdev)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -59,7 +59,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
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";
|
||||
return;
|
||||
}
|
||||
@@ -74,7 +74,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
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";
|
||||
return;
|
||||
}
|
||||
@@ -85,18 +85,18 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
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";
|
||||
return;
|
||||
}
|
||||
eth->setReopenTimeout(freq * 1000);
|
||||
}
|
||||
if (recDataPtr == 0)
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!";
|
||||
if (recDataSize == 0)
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!";
|
||||
} 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";
|
||||
return;
|
||||
}
|
||||
@@ -106,7 +106,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) dev = gdev;
|
||||
if (gok && ok && (dev != gdev)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -115,7 +115,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) ps = gps;
|
||||
if (gok && ok && (ps != gps)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"speed\" in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"speed\" in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -124,7 +124,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"parity\" in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"parity\" in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -135,7 +135,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"twoStopBits\" parity in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"twoStopBits\" parity in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -154,7 +154,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
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";
|
||||
return;
|
||||
}
|
||||
@@ -162,11 +162,11 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
}
|
||||
has_dev = true;
|
||||
if (recDataPtr == 0)
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!";
|
||||
if (recDataSize == 0)
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!";
|
||||
} 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";
|
||||
return;
|
||||
}
|
||||
@@ -176,7 +176,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) history_write_rec = ghist;
|
||||
if (gok && ok && (history_write_rec != ghist)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver history in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver history in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -187,7 +187,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
history_id_rec = rb.getValue("historyID", 0, &ok);
|
||||
if (!ok) {
|
||||
history_id_rec = protName.toByteArray().checksumCRC16();
|
||||
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);
|
||||
}
|
||||
@@ -196,21 +196,21 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
gfreq = b.getValue("frequency", -1.f, &gok);
|
||||
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";
|
||||
return;
|
||||
}
|
||||
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);
|
||||
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;
|
||||
setExpectedFrequency(freq);
|
||||
|
||||
/// sender section
|
||||
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";
|
||||
return;
|
||||
}
|
||||
@@ -220,7 +220,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) dev = gdev;
|
||||
if (gok && ok && (dev != gdev)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -229,7 +229,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
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";
|
||||
return;
|
||||
}
|
||||
@@ -243,7 +243,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
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";
|
||||
return;
|
||||
}
|
||||
@@ -254,18 +254,18 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
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";
|
||||
return;
|
||||
}
|
||||
eth->setReopenTimeout(freq * 1000);
|
||||
}
|
||||
if (sendDataPtr_ == 0)
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!";
|
||||
if (sendDataSize_ == 0)
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data size!";
|
||||
} 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";
|
||||
return;
|
||||
}
|
||||
@@ -275,7 +275,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) dev = gdev;
|
||||
if (gok && ok && (dev != gdev)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -284,7 +284,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) ps = gps;
|
||||
if (gok && ok && (ps != gps)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"speed\" in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"speed\" in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -293,7 +293,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"parity\" in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"parity\" in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -304,14 +304,14 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
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";
|
||||
return;
|
||||
}
|
||||
pp.setFlag(PISerial::TwoStopBits, flag);
|
||||
}
|
||||
} 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";
|
||||
return;
|
||||
}
|
||||
@@ -322,16 +322,16 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
ser->setParameters(pp);
|
||||
has_dev = true;
|
||||
if (sendDataPtr_ == 0)
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!";
|
||||
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);
|
||||
ghist = b.getValue("writeHistory", false, &gok);
|
||||
if (ok || gok) {
|
||||
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";
|
||||
return;
|
||||
}
|
||||
@@ -342,7 +342,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
history_id_send = sb.getValue("historyID", 0, &ok);
|
||||
if (!ok) {
|
||||
history_id_send = protName.toByteArray().checksumCRC16() + 1;
|
||||
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);
|
||||
}
|
||||
@@ -351,12 +351,12 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
gfreq = b.getValue("frequency", -1.f, &gok);
|
||||
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";
|
||||
return;
|
||||
}
|
||||
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);
|
||||
|
||||
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 diag = PIProtocol::Good;
|
||||
if (diag != net_diag) {
|
||||
qualityChanged(net_diag, diag);
|
||||
qualityChanged(diag, net_diag);
|
||||
net_diag = diag;
|
||||
}
|
||||
}
|
||||
|
||||
40
piprotocol.h
40
piprotocol.h
@@ -29,7 +29,7 @@
|
||||
|
||||
class PIProtocol;
|
||||
|
||||
class PIMultiProtocolBase
|
||||
class PIP_EXPORT PIMultiProtocolBase
|
||||
{
|
||||
friend class PIProtocol;
|
||||
public:
|
||||
@@ -65,12 +65,12 @@ typedef void (*ReceiveFunc)(void * );
|
||||
/// void stop()
|
||||
/// void send()
|
||||
/// 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 PIMultiProtocol;
|
||||
enum Type {None, Serial, Ethernet};
|
||||
|
||||
public:
|
||||
PIProtocol(): PIObject() {init();}
|
||||
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};
|
||||
|
||||
EVENT_HANDLER0(PIProtocol, void, startReceive) {startReceive(-1.f);}
|
||||
EVENT_HANDLER1(PIProtocol, void, startReceive, float, exp_frequency); // if "frequency = -1" used last passed value
|
||||
EVENT_HANDLER0(PIProtocol, void, stopReceive);
|
||||
EVENT_HANDLER0(void, startReceive) {startReceive(-1.f);}
|
||||
EVENT_HANDLER1(void, startReceive, float, exp_frequency); // if "frequency = -1" used last passed value
|
||||
EVENT_HANDLER0(void, stopReceive);
|
||||
void setExpectedFrequency(float frequency); // for connection quality diagnostic
|
||||
void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
|
||||
void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; packet_ext->setPacketData(headerPtr, headerSize, dataSize);}
|
||||
@@ -91,9 +91,9 @@ public:
|
||||
void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;}
|
||||
float expectedFrequency() const {return exp_freq;}
|
||||
|
||||
EVENT_HANDLER0(PIProtocol, 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_HANDLER0(PIProtocol, void, stopSend) {sendTimer->stop(); senderStopped();}
|
||||
EVENT_HANDLER0(void, startSend) {startSend(-1.f);} // if "frequency = -1" used last passed value
|
||||
EVENT_HANDLER1(void, startSend, float, frequency); // if "frequency = -1" used last passed value
|
||||
EVENT_HANDLER0(void, stopSend) {sendTimer->stop(); senderStopped();}
|
||||
void setSenderFrequency(float frequency) {send_freq = frequency;}
|
||||
void setSenderDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
|
||||
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
|
||||
float senderFrequency() const {return send_freq;}
|
||||
|
||||
EVENT_HANDLER0(PIProtocol, void, start) {startReceive(); startSend();}
|
||||
EVENT_HANDLER0(PIProtocol, void, stop) {stopReceive(); stopSend();}
|
||||
EVENT_HANDLER0(PIProtocol, void, send);
|
||||
EVENT_HANDLER2(PIProtocol, void, send, const void *, data, int, size) {send(data, size, false);}
|
||||
EVENT_HANDLER3(PIProtocol, void, send, const void *, data, int, size, bool, direct);
|
||||
EVENT_HANDLER0(void, start) {startReceive(); startSend();}
|
||||
EVENT_HANDLER0(void, stop) {stopReceive(); stopSend();}
|
||||
EVENT_HANDLER0(void, send);
|
||||
EVENT_HANDLER2(void, send, const void *, data, int, size) {send(data, size, false);}
|
||||
EVENT_HANDLER3(void, send, const void *, data, int, size, bool, direct);
|
||||
|
||||
void setName(const PIString & name) {protName = name; PIObject::setName(name);}
|
||||
PIString name() const {return protName;}
|
||||
@@ -161,12 +161,12 @@ public:
|
||||
PIPacketExtractor * packetExtractor() {return packet_ext;}
|
||||
PIByteArray lastHeader() {return packet_ext->lastHeader();}
|
||||
|
||||
EVENT0(PIProtocol, receiverStarted)
|
||||
EVENT0(PIProtocol, receiverStopped)
|
||||
EVENT0(PIProtocol, senderStarted)
|
||||
EVENT0(PIProtocol, senderStopped)
|
||||
EVENT1(PIProtocol, received, bool, validate_is_ok)
|
||||
EVENT2(PIProtocol, qualityChanged, PIProtocol::Quality, old_quality, PIProtocol::Quality, new_quality)
|
||||
EVENT0(receiverStarted)
|
||||
EVENT0(receiverStopped)
|
||||
EVENT0(senderStarted)
|
||||
EVENT0(senderStopped)
|
||||
EVENT1(received, bool, validate_is_ok)
|
||||
EVENT2(qualityChanged, PIProtocol::Quality, new_quality, PIProtocol::Quality, old_quality)
|
||||
|
||||
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
|
||||
|
||||
34
piserial.cpp
34
piserial.cpp
@@ -67,14 +67,14 @@ bool PISerial::setPin(int number, bool on) {
|
||||
case 3: return setST(on); break;
|
||||
case 4: return setDTR(on); break;
|
||||
case 5:
|
||||
piCout << "[PISerial] Pin number 5 is ground" << endl;
|
||||
piCout << "[PISerial] Pin number 5 is ground";
|
||||
return false;
|
||||
case 6: return setDSR(on); break;
|
||||
case 7: return setRTS(on); break;
|
||||
case 8: return setCTS(on); break;
|
||||
case 9: return setRNG(on); break;
|
||||
default:
|
||||
piCout << "[PISerial] Pin number " << number << " doesn`t exists!" << endl;
|
||||
piCout << "[PISerial] Pin number " << number << " doesn`t exists!";
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
@@ -93,7 +93,7 @@ bool PISerial::isPin(int number) const {
|
||||
case 8: return isCTS(); break;
|
||||
case 9: return isRNG(); break;
|
||||
default:
|
||||
piCout << "[PISerial] Pin number " << number << " doesn`t exists!" << endl;
|
||||
piCout << "[PISerial] Pin number " << number << " doesn`t exists!";
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
@@ -103,7 +103,7 @@ bool PISerial::isPin(int number) const {
|
||||
bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
||||
#ifndef WINDOWS
|
||||
if (fd < 0) {
|
||||
piCout << "[PISerial] set" << bname << " error: \"" << path_ << "\" is not opened!" << endl;
|
||||
piCout << "[PISerial] set" << bname << " error: \"" << path_ << "\" is not opened!";
|
||||
return false;
|
||||
}
|
||||
if (ioctl(fd, on ? TIOCMBIS : TIOCMBIC, &bit) < 0) {
|
||||
@@ -112,7 +112,7 @@ bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
piCout << "[PISerial] set" << bname << " doesn`t implemented on Windows, sorry :-(" << endl;
|
||||
piCout << "[PISerial] set" << bname << " doesn`t implemented on Windows, sorry :-(";
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
@@ -121,7 +121,7 @@ bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
||||
bool PISerial::isBit(int bit, const PIString & bname) const {
|
||||
#ifndef WINDOWS
|
||||
if (fd < 0) {
|
||||
piCout << "[PISerial] is" << bname << " error: \"" << path_ << "\" is not opened!" << endl;
|
||||
piCout << "[PISerial] is" << bname << " error: \"" << path_ << "\" is not opened!";
|
||||
return false;
|
||||
}
|
||||
int ret = 0;
|
||||
@@ -129,7 +129,7 @@ bool PISerial::isBit(int bit, const PIString & bname) const {
|
||||
piCout << "[PISerial] is" << bname << " error: " << errorString();
|
||||
return ret & bit;
|
||||
#else
|
||||
piCout << "[PISerial] set" << bname << " doesn`t implemented on Windows, sorry :-(" << endl;
|
||||
piCout << "[PISerial] set" << bname << " doesn`t implemented on Windows, sorry :-(";
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
@@ -301,7 +301,7 @@ bool PISerial::openDevice() {
|
||||
if (isWriteable()) {ds |= GENERIC_WRITE; sm |= FILE_SHARE_WRITE;}
|
||||
hCom = CreateFileA(path_.data(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||
if(hCom == INVALID_HANDLE_VALUE) {
|
||||
piCout << "[PISerial] Unable to open \"" << path_ << "\"" << endl;
|
||||
piCout << "[PISerial] Unable to open \"" << path_ << "\"";
|
||||
return false;
|
||||
}
|
||||
fd = 0;
|
||||
@@ -312,7 +312,7 @@ bool PISerial::openDevice() {
|
||||
times.WriteTotalTimeoutConstant = 1;
|
||||
times.WriteTotalTimeoutMultiplier = 0;
|
||||
if (SetCommTimeouts(hCom, ×) == -1) {
|
||||
piCout << "[PISerial] Unable to set timeouts for \"" << path_ << "\"" << endl;
|
||||
piCout << "[PISerial] Unable to set timeouts for \"" << path_ << "\"";
|
||||
CloseHandle(hCom);
|
||||
fd = -1;
|
||||
return false;
|
||||
@@ -330,7 +330,7 @@ bool PISerial::openDevice() {
|
||||
}
|
||||
desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
|
||||
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);
|
||||
fd = -1;
|
||||
return false;
|
||||
@@ -345,7 +345,7 @@ bool PISerial::openDevice() {
|
||||
//cout << "init ser " << path_ << " mode " << om << " param " << params << endl;
|
||||
fd = ::open(path_.data(), O_NOCTTY | om);
|
||||
if(fd == -1) {
|
||||
piCout << "[PISerial] Unable to open \"" << path_ << "\"" << endl;
|
||||
piCout << "[PISerial] Unable to open \"" << path_ << "\"";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -371,20 +371,20 @@ bool PISerial::openDevice() {
|
||||
fcntl(fd, F_SETFL, 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);
|
||||
return false;
|
||||
}
|
||||
//piCout << "[PISerial] Initialized " << path_ << endl;
|
||||
//piCout << "[PISerial] Initialized " << path_;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
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()) {
|
||||
//piCout << "[PISerial] Can`t write to uninitialized COM" << endl;
|
||||
//piCout << "[PISerial] Can`t write to uninitialized COM";
|
||||
return -1;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
@@ -402,6 +402,6 @@ int PISerial::write(const void * data, int max_size, bool wait) {
|
||||
if (wait) tcdrain(fd);
|
||||
#endif
|
||||
return (int)wrote;
|
||||
//piCout << "[PISerial] Error while sending" << endl;
|
||||
//piCout << "[PISerial] Wrote " << wrote << " bytes in " << path_ << endl;
|
||||
//piCout << "[PISerial] Error while sending";
|
||||
//piCout << "[PISerial] Wrote " << wrote << " bytes in " << path_;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
# ifndef B50
|
||||
# define B50 0000001
|
||||
# endif
|
||||
# ifndef B50
|
||||
# ifndef B75
|
||||
# define B75 0000002
|
||||
# endif
|
||||
# ifndef B1500000
|
||||
@@ -83,8 +83,11 @@
|
||||
# define B3500000 3500000
|
||||
# define B4000000 4000000
|
||||
#endif
|
||||
#ifndef CRTSCTS
|
||||
# define CRTSCTS 020000000000
|
||||
#endif
|
||||
|
||||
class PISerial: public PIIODevice {
|
||||
class PIP_EXPORT PISerial: public PIIODevice {
|
||||
public:
|
||||
// slot is any function format "bool <func>(void*, uchar*, int)"
|
||||
// slot_header is any function format "bool <func>(void*, uchar*, uchar*, int)"
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "picontainers.h"
|
||||
#include <csignal>
|
||||
|
||||
class PISignals
|
||||
class PIP_EXPORT PISignals
|
||||
{
|
||||
public:
|
||||
enum Signal {
|
||||
|
||||
67
pistring.cpp
67
pistring.cpp
@@ -20,6 +20,41 @@
|
||||
#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',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||
@@ -346,25 +381,24 @@ int PIString::lengthAscii() const {
|
||||
|
||||
|
||||
const char * PIString::data() const {
|
||||
PIByteArray & d_(*(const_cast<PIByteArray * >(&data_)));
|
||||
d_.clear();
|
||||
data_.clear();
|
||||
int wc;
|
||||
uchar tc;
|
||||
for (int i = 0, j = 0; i < size_s(); ++i) {
|
||||
wc = at(i).toInt();
|
||||
while (tc = wc & 0xFF, tc) {
|
||||
d_.push_back(uchar(tc)); ++j;
|
||||
data_.push_back(uchar(tc)); ++j;
|
||||
wc >>= 8;
|
||||
}
|
||||
/*if (at(i).isAscii())
|
||||
d_.push_back(uchar(at(i).toAscii()));
|
||||
data_.push_back(uchar(at(i).toAscii()));
|
||||
else {
|
||||
d_.push_back((at(i).toCharPtr()[0])); ++j;
|
||||
d_.push_back((at(i).toCharPtr()[1]));
|
||||
data_.push_back((at(i).toCharPtr()[0])); ++j;
|
||||
data_.push_back((at(i).toCharPtr()[1]));
|
||||
}*/
|
||||
}
|
||||
d_.push_back(uchar('\0'));
|
||||
return (const char * )d_.data();
|
||||
data_.push_back(uchar('\0'));
|
||||
return (const char * )data_.data();
|
||||
}
|
||||
|
||||
|
||||
@@ -439,25 +473,29 @@ llong PIString::toLLong() const {
|
||||
}
|
||||
*/
|
||||
|
||||
PIString & PIString::setReadableSize(long bytes) {
|
||||
PIString & PIString::setReadableSize(llong bytes) {
|
||||
clear();
|
||||
if (bytes < 1024) {*this += (PIString::fromNumber(bytes) + " B"); return *this;}
|
||||
double fres = bytes / 1024.;
|
||||
long res = bytes / 1024;
|
||||
llong res = bytes / 1024;
|
||||
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.;
|
||||
res /= 1024;
|
||||
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.;
|
||||
res /= 1024;
|
||||
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.;
|
||||
res /= 1024;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -476,6 +514,7 @@ inline char chrLwr(char c) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
PIStringList& PIStringList::removeDuplicates() {
|
||||
PIStringList l;
|
||||
PIString s;
|
||||
|
||||
458
pistring.h
458
pistring.h
@@ -1,3 +1,8 @@
|
||||
/*! \file pistring.h
|
||||
* \brief String
|
||||
*
|
||||
* This file declare string and string list classes
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
String
|
||||
@@ -26,13 +31,14 @@
|
||||
|
||||
class PIStringList;
|
||||
|
||||
class PIString: public PIVector<PIChar>
|
||||
class PIP_EXPORT PIString: public PIVector<PIChar>
|
||||
{
|
||||
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;}
|
||||
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 wchar_t * str);
|
||||
PIString & operator +=(const string & str) {appendFromChars(str.c_str(), str.length()); return *this;}
|
||||
@@ -43,107 +49,335 @@ public:
|
||||
#endif
|
||||
|
||||
//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;}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
//! Contructs string from std::string "str"
|
||||
PIString(const string & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||
|
||||
#ifdef HAS_LOCALE
|
||||
PIString(const wstring & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||
#endif
|
||||
|
||||
//! Contructs string from byte array "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);}
|
||||
|
||||
/*! \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);}
|
||||
|
||||
/*! \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);}
|
||||
|
||||
//! Contructs string from other string "str"
|
||||
PIString(const PIString & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||
|
||||
~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();}
|
||||
|
||||
//! 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;}
|
||||
|
||||
//! Return symbol at index "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);}
|
||||
|
||||
//! Compare operator
|
||||
bool operator ==(const PIString & str) const;
|
||||
|
||||
//! Compare operator
|
||||
bool operator ==(const PIChar 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);}
|
||||
|
||||
//! Compare operator
|
||||
bool operator ==(const string & str) const {return *this == PIString(str);}
|
||||
|
||||
|
||||
//! Compare operator
|
||||
bool operator !=(const PIString & str) const;
|
||||
|
||||
//! Compare operator
|
||||
bool operator !=(const PIChar 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);}
|
||||
|
||||
//! Compare operator
|
||||
bool operator !=(const string & str) const {return *this != PIString(str);}
|
||||
|
||||
|
||||
//! Compare operator
|
||||
bool operator <(const PIString & str) const;
|
||||
|
||||
//! Compare operator
|
||||
bool operator <(const PIChar 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);}
|
||||
|
||||
//! Compare operator
|
||||
bool operator <(const string & str) const {return *this < PIString(str);}
|
||||
|
||||
|
||||
//! Compare operator
|
||||
bool operator >(const PIString & str) const;
|
||||
|
||||
//! Compare operator
|
||||
bool operator >(const PIChar 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);}
|
||||
|
||||
//! Compare operator
|
||||
bool operator >(const string & str) const {return *this > PIString(str);}
|
||||
|
||||
|
||||
//! Compare operator
|
||||
bool operator <=(const PIString & str) const {return !(*this > str);}
|
||||
|
||||
//! Compare operator
|
||||
bool operator <=(const PIChar 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);}
|
||||
|
||||
//! Compare operator
|
||||
bool operator <=(const string & str) const {return *this <= PIString(str);}
|
||||
|
||||
|
||||
//! Compare operator
|
||||
bool operator >=(const PIString & str) const {return !(*this < str);}
|
||||
|
||||
//! Compare operator
|
||||
bool operator >=(const PIChar 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);}
|
||||
|
||||
//! Compare operator
|
||||
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;}
|
||||
//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;}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
//! Append std::string "str" at the end of string
|
||||
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;}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
|
||||
/*! \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;
|
||||
|
||||
/*! \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);}
|
||||
|
||||
/*! \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);}
|
||||
|
||||
/*! \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);
|
||||
|
||||
/*! \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);}
|
||||
|
||||
/*! \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);}
|
||||
|
||||
/*! \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();
|
||||
|
||||
/*! \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;
|
||||
|
||||
/*! \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);
|
||||
|
||||
/*! \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;}
|
||||
|
||||
/*! \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);
|
||||
|
||||
/*! \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;}
|
||||
|
||||
/*! \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) 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;}
|
||||
|
||||
/*! \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));}
|
||||
|
||||
/*! \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);
|
||||
|
||||
/*! \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));}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
/*! \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;}
|
||||
|
||||
//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;
|
||||
|
||||
/*! \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;
|
||||
|
||||
//! \brief Return \c std::string representation of this string
|
||||
const string stdString() const {return convertToStd();}
|
||||
#ifdef HAS_LOCALE
|
||||
wstring stdWString() const {return convertToWString();}
|
||||
#endif
|
||||
|
||||
//! \brief Return \a PIByteArray contains \a data() of this string
|
||||
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;
|
||||
|
||||
|
||||
//! \brief Convert each symbol in copyed string to upper case and return it
|
||||
PIString toUpperCase() const;
|
||||
|
||||
//! \brief Convert each symbol in copyed string to lower case and return it
|
||||
PIString toLowerCase() const;
|
||||
#ifdef HAS_LOCALE
|
||||
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;}
|
||||
#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;
|
||||
|
||||
//! \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;
|
||||
|
||||
//! \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);}
|
||||
|
||||
//! \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);}
|
||||
|
||||
//! \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;
|
||||
|
||||
//! \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;
|
||||
|
||||
//! \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);}
|
||||
|
||||
//! \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);}
|
||||
|
||||
|
||||
//! \brief Return symbols length of string
|
||||
int length() const {return size();}
|
||||
|
||||
//! \brief Return \c true if string is empty, i.e. length = 0
|
||||
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;}
|
||||
|
||||
//! \brief Return \c char numeric value of string
|
||||
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));}
|
||||
|
||||
//! \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));}
|
||||
|
||||
//! \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));}
|
||||
|
||||
//! \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));}
|
||||
|
||||
//! \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));}
|
||||
|
||||
//! \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));}
|
||||
|
||||
//! \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);}
|
||||
|
||||
//! \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));}
|
||||
|
||||
//! \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());}
|
||||
|
||||
//! \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());}
|
||||
|
||||
//! \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());}
|
||||
|
||||
//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;}
|
||||
|
||||
//! \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;}
|
||||
|
||||
//! \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;}
|
||||
|
||||
//! \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;}
|
||||
|
||||
//! \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;}
|
||||
|
||||
//! \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 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 double value) {clear(); *this += dtos(value); return *this;}
|
||||
PIString & setNumber(const ldouble value) {clear(); *this += dtos(value); return *this;}
|
||||
PIString & setReadableSize(long bytes);
|
||||
|
||||
//! \brief Set string content to numeric representation of "value"
|
||||
//! \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));}
|
||||
|
||||
//! \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);}
|
||||
|
||||
//! \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);}
|
||||
|
||||
//! \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);}
|
||||
|
||||
//! \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);}
|
||||
|
||||
//! \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);}
|
||||
|
||||
//! \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 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 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 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:
|
||||
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;}
|
||||
#endif
|
||||
|
||||
PIByteArray data_;
|
||||
mutable PIByteArray data_;
|
||||
//string std_string;
|
||||
//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;}
|
||||
|
||||
//! \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;}
|
||||
|
||||
//! \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;}
|
||||
|
||||
//! \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;}
|
||||
|
||||
|
||||
//! \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 & 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;}
|
||||
|
||||
//! \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 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;}
|
||||
|
||||
//! \relatesalso PIString \brief Return concatenated string
|
||||
inline PIString operator +(const string & str, const PIString & f) {return PIString(str) + f;}
|
||||
|
||||
inline char chrUpr(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:
|
||||
|
||||
//! Contructs empty strings list
|
||||
PIStringList() {;}
|
||||
|
||||
//! Contructs strings list with one string "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);}
|
||||
|
||||
//! 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);}
|
||||
|
||||
//! 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);}
|
||||
|
||||
|
||||
//! \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;}
|
||||
|
||||
//! \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 & remove(uint num) {PIVector<PIString>::remove(num); 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();
|
||||
|
||||
//! 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;}
|
||||
|
||||
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;}
|
||||
|
||||
//! \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
|
||||
|
||||
@@ -42,7 +42,7 @@ bool PISystemMonitor::startOnProcess(int pID) {
|
||||
file.open("/proc/" + PIString::fromNumber(pID_) + "/stat", PIIODevice::ReadOnly);
|
||||
filem.open("/proc/" + PIString::fromNumber(pID_) + "/statm", PIIODevice::ReadOnly);
|
||||
if (!file.isOpened()) {
|
||||
piCout << "[PISystemMonitor] Can`t find process with ID = " << pID_ << "!" << endl;
|
||||
piCout << "[PISystemMonitor] Can`t find process with ID = " << pID_ << "!";
|
||||
return false;
|
||||
}
|
||||
cycle = -1;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "pithread.h"
|
||||
#include "piprocess.h"
|
||||
|
||||
class PISystemMonitor: public PIThread
|
||||
class PIP_EXPORT PISystemMonitor: public PIThread
|
||||
{
|
||||
public:
|
||||
PISystemMonitor();
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
#include "piconfig.h"
|
||||
|
||||
namespace PISystemTests {
|
||||
extern long time_resolution_ns;
|
||||
extern long time_elapsed_ns;
|
||||
extern long usleep_offset_us;
|
||||
PIP_EXPORT extern long time_resolution_ns;
|
||||
PIP_EXPORT extern long time_elapsed_ns;
|
||||
PIP_EXPORT extern long usleep_offset_us;
|
||||
|
||||
class PISystemTestReader {
|
||||
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() {
|
||||
piMonitor.threads++;
|
||||
data_ = data;
|
||||
@@ -58,12 +88,14 @@ PIThread::~PIThread() {
|
||||
#ifndef WINDOWS
|
||||
pthread_cancel(thread);
|
||||
#else
|
||||
TerminateThread(thread, 0);
|
||||
CloseHandle(thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIThread::start(int timer_delay) {
|
||||
if (running) return false;
|
||||
terminating = running = false;
|
||||
timer = timer_delay;
|
||||
#ifndef WINDOWS
|
||||
@@ -88,6 +120,7 @@ bool PIThread::start(int timer_delay) {
|
||||
|
||||
|
||||
bool PIThread::startOnce() {
|
||||
if (running) return false;
|
||||
terminating = running = false;
|
||||
#ifndef WINDOWS
|
||||
pthread_attr_t attr;
|
||||
@@ -110,13 +143,13 @@ bool PIThread::startOnce() {
|
||||
}
|
||||
|
||||
|
||||
void PIThread::terminate(bool hard) {
|
||||
void PIThread::terminate() {
|
||||
if (thread == 0) return;
|
||||
running = false;
|
||||
#ifndef WINDOWS
|
||||
if (hard) kill((ullong)thread, SIGKILL);
|
||||
else pthread_cancel(thread);
|
||||
pthread_cancel(thread);
|
||||
#else
|
||||
TerminateThread(thread, 0);
|
||||
CloseHandle(thread);
|
||||
#endif
|
||||
thread = 0;
|
||||
@@ -125,6 +158,10 @@ void PIThread::terminate(bool hard) {
|
||||
|
||||
|
||||
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);
|
||||
ct.running = true;
|
||||
ct.begin();
|
||||
@@ -150,6 +187,10 @@ void * PIThread::thread_function(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);
|
||||
ct.running = true;
|
||||
ct.begin();
|
||||
|
||||
183
pithread.h
183
pithread.h
@@ -1,3 +1,8 @@
|
||||
/*! \file pithread.h
|
||||
* \brief Thread
|
||||
*
|
||||
* This file declare thread class and some wait functions
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Thread
|
||||
@@ -24,37 +29,49 @@
|
||||
#include "pimutex.h"
|
||||
#include "piobject.h"
|
||||
|
||||
#ifdef DOXYGEN
|
||||
//! \brief Sleep for "msecs" milliseconds
|
||||
void msleep(int msecs);
|
||||
#else
|
||||
# ifdef WINDOWS
|
||||
inline void msleep(int msecs) {Sleep(msecs);}
|
||||
# else
|
||||
inline void msleep(int msecs) {usleep(msecs * 1000);}
|
||||
# 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
|
||||
|
||||
/*! \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
|
||||
|
||||
typedef void (*ThreadFunc)(void * );
|
||||
|
||||
/// events:
|
||||
/// void started()
|
||||
/// void stopped()
|
||||
///
|
||||
/// 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 {
|
||||
|
||||
class PIP_EXPORT PIThread: public PIObject
|
||||
{
|
||||
PIOBJECT(PIThread)
|
||||
public:
|
||||
PIThread(void * data, ThreadFunc func, bool startNow = false, int timer_delay = -1);
|
||||
PIThread(bool startNow = false, int timer_delay = -1);
|
||||
virtual ~PIThread();
|
||||
|
||||
#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,
|
||||
piHigh = 11,
|
||||
@@ -67,43 +84,133 @@ public:
|
||||
piNormal = 0,
|
||||
piLow = 1,
|
||||
piLowerst = 2 };
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//bool start(int timer_delay = -1);
|
||||
EVENT_HANDLER0(PIThread, bool, start) {return start(-1);}
|
||||
EVENT_HANDLER1(PIThread, bool, start, int, timer_delay);
|
||||
EVENT_HANDLER1(PIThread, bool, start, ThreadFunc, func) {ret_func = func; return start(-1);}
|
||||
EVENT_HANDLER2(PIThread, bool, start, ThreadFunc, func, int, timer_delay) {ret_func = func; return start(timer_delay);}
|
||||
EVENT_HANDLER0(PIThread, bool, startOnce);
|
||||
EVENT_HANDLER1(PIThread, bool, startOnce, ThreadFunc, func) {ret_func = func; return startOnce();}
|
||||
EVENT_HANDLER0(PIThread, void, stop) {stop(false);}
|
||||
EVENT_HANDLER1(PIThread, void, stop, bool, wait) {terminating = true; if (wait) waitForFinish();}
|
||||
EVENT_HANDLER0(PIThread, void, terminate) {terminate(false);}
|
||||
EVENT_HANDLER1(PIThread, void, terminate, bool, hard);
|
||||
EVENT_HANDLER0(bool, start) {return start(-1);}
|
||||
EVENT_HANDLER1(bool, start, int, timer_delay);
|
||||
EVENT_HANDLER1(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_HANDLER0(bool, startOnce);
|
||||
EVENT_HANDLER1(bool, startOnce, ThreadFunc, func) {ret_func = func; return startOnce();}
|
||||
EVENT_HANDLER0(void, stop) {stop(false);}
|
||||
EVENT_HANDLER1(void, stop, bool, wait) {terminating = true; if (wait) waitForFinish();}
|
||||
EVENT_HANDLER0(void, terminate);
|
||||
|
||||
//! \brief Set common data passed to external function
|
||||
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;}
|
||||
|
||||
//! \brief Set priority of thread
|
||||
void setPriority(PIThread::Priority prior);
|
||||
|
||||
//! \brief Return priority of thread
|
||||
PIThread::Priority priority() const {return priority_;}
|
||||
|
||||
//! \brief Return \c true if thread is running
|
||||
bool isRunning() const {return running;}
|
||||
EVENT_HANDLER0(PIThread, bool, waitForFinish) {return waitForFinish(-1);}
|
||||
EVENT_HANDLER1(PIThread, bool, waitForFinish, int, timeout_msecs);
|
||||
EVENT_HANDLER0(PIThread, bool, waitForStart) {return waitForStart(-1);}
|
||||
EVENT_HANDLER1(PIThread, bool, waitForStart, int, timeout_msecs);
|
||||
|
||||
bool isStopping() const {return running && terminating;}
|
||||
|
||||
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;}
|
||||
EVENT_HANDLER0(PIThread, void, lock) {mutex_.lock();}
|
||||
EVENT_HANDLER0(PIThread, void, unlock) {mutex_.unlock();}
|
||||
EVENT_HANDLER0(void, lock) {mutex_.lock();}
|
||||
EVENT_HANDLER0(void, unlock) {mutex_.unlock();}
|
||||
|
||||
//! \brief Return internal mutex
|
||||
PIMutex & mutex() {return mutex_;}
|
||||
|
||||
EVENT(PIThread, started)
|
||||
EVENT(PIThread, stopped)
|
||||
EVENT(started)
|
||||
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:
|
||||
static void * thread_function(void * t);
|
||||
static void * thread_function_once(void * t);
|
||||
|
||||
virtual void begin() {;} // executed at start
|
||||
virtual void run() {;} // main loop executed with "timer_delay" timeout
|
||||
virtual void end() {;} // executed at finish
|
||||
virtual void begin() {;}
|
||||
virtual void run() {;}
|
||||
virtual void end() {;}
|
||||
|
||||
volatile bool terminating, running, lockRun;
|
||||
int timer, policy;
|
||||
|
||||
222
pitimer.cpp
222
pitimer.cpp
@@ -20,6 +20,73 @@
|
||||
#include "pitimer.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
|
||||
PITimer::TimerPool * pool = 0;
|
||||
@@ -34,17 +101,20 @@ PITimer::PITimer(TimerEvent slot, void * data_, bool threaded_)
|
||||
#endif
|
||||
ret_func = slot;
|
||||
data = data_;
|
||||
running_ = false;
|
||||
interval_ = 0.;
|
||||
#ifdef PIP_TIMER_RT
|
||||
piMonitor.timers++;
|
||||
ti = -1;
|
||||
threaded = threaded_;
|
||||
running = false;
|
||||
memset(&se, 0, sizeof(se));
|
||||
se.sigev_notify = SIGEV_THREAD;
|
||||
se.sigev_value.sival_ptr = this;
|
||||
se.sigev_notify_function = PITimer::timer_event;
|
||||
se.sigev_notify_attributes = 0;
|
||||
lockRun = false;
|
||||
#else
|
||||
deferred_ = false;
|
||||
#endif
|
||||
reset();
|
||||
}
|
||||
@@ -58,17 +128,20 @@ PITimer::PITimer(bool threaded_)
|
||||
#endif
|
||||
ret_func = 0;
|
||||
data = 0;
|
||||
running_ = false;
|
||||
interval_ = 0.;
|
||||
#ifdef PIP_TIMER_RT
|
||||
piMonitor.timers++;
|
||||
ti = -1;
|
||||
threaded = threaded_;
|
||||
running = false;
|
||||
memset(&se, 0, sizeof(se));
|
||||
se.sigev_notify = SIGEV_THREAD;
|
||||
se.sigev_value.sival_ptr = this;
|
||||
se.sigev_notify_function = PITimer::timer_event;
|
||||
se.sigev_notify_attributes = 0;
|
||||
lockRun = false;
|
||||
#else
|
||||
deferred_ = false;
|
||||
#endif
|
||||
reset();
|
||||
}
|
||||
@@ -84,14 +157,15 @@ PITimer::~PITimer() {
|
||||
|
||||
#ifdef PIP_TIMER_RT
|
||||
void PITimer::start(double msecs) {
|
||||
if (ti != -1 || msecs < 0 || running) return;
|
||||
if (ti != -1 || msecs < 0 || running_) return;
|
||||
interval_ = msecs;
|
||||
if (!threaded) {
|
||||
ticks = int(msecs);
|
||||
if (pool == 0) pool = new TimerPool();
|
||||
pool->add(this);
|
||||
//cout << "not threaded timer start " << msecs << " msecs\n";
|
||||
if (!pool->isRunning()) pool->start();
|
||||
running = true;
|
||||
running_ = true;
|
||||
return;
|
||||
}
|
||||
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);
|
||||
//cout << "***create timer " << msecs << " msecs\n";
|
||||
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;
|
||||
}
|
||||
timer_settime(timer, 0, &spec, 0);
|
||||
running = true;
|
||||
running_ = true;
|
||||
}
|
||||
|
||||
|
||||
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_sec = (time_t)(interval_msecs / 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);
|
||||
//cout << "***create timer\n";
|
||||
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;
|
||||
}
|
||||
timer_settime(timer, 0, &spec, 0);
|
||||
running = true;
|
||||
running_ = true;
|
||||
}
|
||||
|
||||
|
||||
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_sec = (time_t)(interval_msecs / 1000);
|
||||
struct tm dtm;
|
||||
@@ -142,11 +218,11 @@ void PITimer::deferredStart(double interval_msecs, const PIDateTime & start_date
|
||||
ti = timer_create(CLOCK_REALTIME, &se, &timer);
|
||||
//cout << "***create timer\n";
|
||||
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;
|
||||
}
|
||||
timer_settime(timer, TIMER_ABSTIME, &spec, 0);
|
||||
running = true;
|
||||
running_ = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -170,7 +246,7 @@ void PITimer::TimerPool::begin() {
|
||||
sa.sa_handler = empty_handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
if (sigaction(SIGALRM, &sa, 0) == -1) {
|
||||
piCout << "[PITimer] sigaction error: " << errorString() << endl;
|
||||
piCout << "[PITimer] sigaction error: " << errorString();
|
||||
stop();
|
||||
return;
|
||||
}*/
|
||||
@@ -184,12 +260,12 @@ void PITimer::TimerPool::begin() {
|
||||
spec.it_value = spec.it_interval;
|
||||
//cout << "***create pool timer\n";
|
||||
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();
|
||||
return;
|
||||
}
|
||||
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();
|
||||
return;
|
||||
}
|
||||
@@ -221,8 +297,8 @@ void PITimer::TimerPool::run() {
|
||||
|
||||
|
||||
void PITimer::stop() {
|
||||
if (!running) return;
|
||||
running = false;
|
||||
if (!running_) return;
|
||||
running_ = false;
|
||||
if (!threaded) {
|
||||
if (pool != 0) {
|
||||
pool->remove(this);
|
||||
@@ -231,12 +307,13 @@ void PITimer::stop() {
|
||||
}
|
||||
if (ti != -1) timer_delete(timer);
|
||||
ti = -1;
|
||||
interval_ = 0.;
|
||||
}
|
||||
|
||||
|
||||
void PITimer::timer_event(sigval e) {
|
||||
PITimer * ct = (PITimer * )e.sival_ptr;
|
||||
if (!ct->running) return;
|
||||
if (!ct->running_) return;
|
||||
if (ct->lockRun) ct->lock();
|
||||
if (ct->ret_func != 0) ct->ret_func(ct->data, 1);
|
||||
ct->timeout(ct->data, 1);
|
||||
@@ -255,12 +332,12 @@ void PITimer::timer_event(sigval e) {
|
||||
|
||||
bool PITimer::waitForFinish(int timeout_msecs) {
|
||||
if (timeout_msecs < 0) {
|
||||
while (running)
|
||||
while (running_)
|
||||
msleep(1);
|
||||
return true;
|
||||
}
|
||||
int cnt = 0;
|
||||
while (running && cnt < timeout_msecs) {
|
||||
while (running_ && cnt < timeout_msecs) {
|
||||
msleep(1);
|
||||
++cnt;
|
||||
}
|
||||
@@ -270,18 +347,65 @@ bool PITimer::waitForFinish(int timeout_msecs) {
|
||||
#else
|
||||
|
||||
void PITimer::start(double msecs) {
|
||||
if (msecs < 0 || running) return;
|
||||
if (msecs < 0 || running_) return;
|
||||
interval_ = msecs;
|
||||
inc_time = PISystemTime::fromMilliseconds(msecs);
|
||||
st_time = currentSystemTime() + inc_time;
|
||||
deferred_ = false;
|
||||
running_ = true;
|
||||
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() {
|
||||
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 += inc_time;
|
||||
if (lockRun) lock();
|
||||
//if (lockRun) lock();
|
||||
if (ret_func != 0) ret_func(data, 1);
|
||||
timeout(data, 1);
|
||||
tick(data, 1);
|
||||
@@ -293,7 +417,7 @@ void PITimer::run() {
|
||||
timeout(data, i.delim);
|
||||
tick(data, i.delim);
|
||||
}
|
||||
if (lockRun) unlock();
|
||||
//if (lockRun) unlock();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -524,7 +648,7 @@ PISystemTime currentSystemTime() {
|
||||
}
|
||||
|
||||
|
||||
PIString PITime::toString(const PIString & format) {
|
||||
PIString PITime::toString(const PIString & format) const {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
||||
ts.replace("h", PIString::fromNumber(hours));
|
||||
@@ -532,11 +656,14 @@ PIString PITime::toString(const PIString & format) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
PIString PIDate::toString(const PIString & format) {
|
||||
PIString PIDate::toString(const PIString & format) const {
|
||||
PIString ts = format;
|
||||
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
||||
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;
|
||||
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("yy", PIString::fromNumber(year).right(2));
|
||||
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("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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 ts = format;
|
||||
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 );
|
||||
|
||||
class PISystemTime {
|
||||
class PIP_EXPORT PISystemTime {
|
||||
public:
|
||||
PISystemTime() {seconds = nanoseconds = 0;}
|
||||
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, 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 minutes;
|
||||
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 month;
|
||||
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 minutes;
|
||||
int hours;
|
||||
int day;
|
||||
int month;
|
||||
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:
|
||||
/// void timeout(void * data, int delimiter)
|
||||
@@ -108,13 +144,14 @@ struct PIDateTime {
|
||||
/// void clearDelimiters()
|
||||
/// void lock()
|
||||
/// void unlock()
|
||||
class PITimer
|
||||
class PIP_EXPORT PITimer
|
||||
#ifndef PIP_TIMER_RT
|
||||
: public PIThread
|
||||
#else
|
||||
: public PIObject
|
||||
#endif
|
||||
{
|
||||
PIOBJECT(PITimer)
|
||||
public:
|
||||
PITimer(TimerEvent slot = 0, void * data = 0, bool threaded = true);
|
||||
PITimer(bool threaded);
|
||||
@@ -122,53 +159,53 @@ public:
|
||||
|
||||
void setData(void * data_) {data = data_;}
|
||||
void setSlot(TimerEvent slot) {ret_func = slot;}
|
||||
double interval() const {return interval_;}
|
||||
#ifndef PIP_TIMER_RT
|
||||
# ifdef WINDOWS
|
||||
EVENT_HANDLER0(PITimer, 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);
|
||||
EVENT_HANDLER0(void, reset) {t_st = GetCurrentTime();}
|
||||
# elif defined(MAC_OS)
|
||||
EVENT_HANDLER0(PITimer, 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);
|
||||
EVENT_HANDLER0(void, reset) {clock_get_time(__pi_mac_clock, &t_st);}
|
||||
# else
|
||||
EVENT_HANDLER0(PITimer, 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);
|
||||
EVENT_HANDLER0(void, reset) {clock_gettime(0, &t_st);}
|
||||
# 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
|
||||
EVENT_HANDLER0(PITimer, void, reset) {clock_gettime(0, &t_st);}
|
||||
EVENT_HANDLER1(PITimer, void, start, double, msecs);
|
||||
EVENT_HANDLER2(PITimer, void, deferredStart, double, interval_msecs, double, delay_msecs);
|
||||
EVENT_HANDLER2(PITimer, void, deferredStart, double, interval_msecs, const PIDateTime &, start_datetime);
|
||||
EVENT_HANDLER0(PITimer, void, stop);
|
||||
EVENT_HANDLER0(PITimer, bool, waitForFinish) {return waitForFinish(-1);}
|
||||
EVENT_HANDLER1(PITimer, bool, waitForFinish, int, timeout_msecs);
|
||||
bool isRunning() const {return running;}
|
||||
EVENT_HANDLER0(void, reset) {clock_gettime(0, &t_st);}
|
||||
EVENT_HANDLER1(void, start, double, msecs);
|
||||
EVENT_HANDLER2(void, deferredStart, double, interval_msecs, double, delay_msecs);
|
||||
EVENT_HANDLER2(void, deferredStart, double, interval_msecs, const PIDateTime &, start_datetime);
|
||||
EVENT_HANDLER0(void, stop);
|
||||
EVENT_HANDLER0(bool, waitForFinish) {return waitForFinish(-1);}
|
||||
EVENT_HANDLER1(bool, waitForFinish, int, timeout_msecs);
|
||||
bool isRunning() const {return running_;}
|
||||
void needLockRun(bool need) {lockRun = need;}
|
||||
EVENT_HANDLER0(PITimer, void, lock) {mutex_.lock();}
|
||||
EVENT_HANDLER0(PITimer, void, unlock) {mutex_.unlock();}
|
||||
EVENT_HANDLER0(void, lock) {mutex_.lock();}
|
||||
EVENT_HANDLER0(void, unlock) {mutex_.unlock();}
|
||||
#endif
|
||||
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(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--;}}
|
||||
EVENT_HANDLER0(PITimer, void, clearDelimiters) {ret_funcs.clear();}
|
||||
EVENT_HANDLER0(void, clearDelimiters) {ret_funcs.clear();}
|
||||
|
||||
double elapsed_n(); // nanoseconds
|
||||
double elapsed_u(); // microseconds
|
||||
double elapsed_m(); // miliseconds
|
||||
double elapsed_m(); // milliseconds
|
||||
double elapsed_s(); // seconds
|
||||
|
||||
double reset_time_n(); // nanoseconds
|
||||
double reset_time_u(); // microseconds
|
||||
double reset_time_m(); // miliseconds
|
||||
double reset_time_m(); // milliseconds
|
||||
double reset_time_s(); // seconds
|
||||
PISystemTime reset_time();
|
||||
|
||||
static double elapsed_system_n(); // nanoseconds
|
||||
static double elapsed_system_u(); // microseconds
|
||||
static double elapsed_system_m(); // miliseconds
|
||||
static double elapsed_system_m(); // milliseconds
|
||||
static double elapsed_system_s(); // seconds
|
||||
|
||||
|
||||
@@ -200,7 +237,7 @@ public:
|
||||
int ticks;
|
||||
#endif
|
||||
|
||||
EVENT2(PITimer, timeout, void * , data, int, delimiter)
|
||||
EVENT2(timeout, void * , data, int, delimiter)
|
||||
|
||||
protected:
|
||||
virtual void tick(void * data, int delimiter) {;}
|
||||
@@ -208,10 +245,12 @@ protected:
|
||||
private:
|
||||
#ifndef PIP_TIMER_RT
|
||||
void run();
|
||||
void end() {interval_ = 0.;}
|
||||
|
||||
PISystemTime st_time, inc_time;
|
||||
bool deferred_;
|
||||
#else
|
||||
bool running, threaded;
|
||||
bool threaded;
|
||||
volatile bool lockRun;
|
||||
PIMutex mutex_;
|
||||
int ti;
|
||||
@@ -219,6 +258,8 @@ private:
|
||||
timer_t timer;
|
||||
sigevent se;
|
||||
#endif
|
||||
bool running_;
|
||||
double interval_;
|
||||
|
||||
#ifdef WINDOWS
|
||||
long
|
||||
@@ -246,12 +287,12 @@ private:
|
||||
extern PITimer::TimerPool * pool;
|
||||
#endif
|
||||
|
||||
PITime currentTime();
|
||||
PIDate currentDate();
|
||||
PIDateTime currentDateTime();
|
||||
PISystemTime currentSystemTime();
|
||||
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
|
||||
PIString datetime2string(const PIDateTime & datetime, const PIString & format = "h:mm:ss d.MM.yyyy"); // obsolete, use PIDateTime.toString() instead
|
||||
PIP_EXPORT PITime currentTime();
|
||||
PIP_EXPORT PIDate currentDate();
|
||||
PIP_EXPORT PIDateTime currentDateTime();
|
||||
PIP_EXPORT PISystemTime currentSystemTime();
|
||||
PIP_EXPORT PIString time2string(const PITime & time, const PIString & format = "h:mm:ss"); // obsolete, use PITime.toString() instead
|
||||
PIP_EXPORT PIString date2string(const PIDate & date, const PIString & format = "d.MM.yyyy"); // obsolete, use PITime.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
|
||||
|
||||
11
pivariable.h
11
pivariable.h
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "piconfig.h"
|
||||
|
||||
class PIVariant {
|
||||
class PIP_EXPORT PIVariant {
|
||||
friend class PIVariable;
|
||||
public:
|
||||
enum Type {Bool, Char, Short, Int, Long, LLong, UChar, UShort, UInt, ULong, ULLong, Float, Double, LDouble, String, StringList};
|
||||
@@ -128,7 +128,7 @@ private:
|
||||
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIVariant & v) {s << v.typeName() << ": " << v.stringValue(); return s;}
|
||||
|
||||
class PIVariable {
|
||||
class PIP_EXPORT PIVariable {
|
||||
public:
|
||||
PIVariable() {;}
|
||||
PIVariable(const PIString & str) {setVariable(str);}
|
||||
@@ -169,7 +169,7 @@ private:
|
||||
* "double value = struct["pi"].value();"
|
||||
*/
|
||||
|
||||
class PIStruct {
|
||||
class PIP_EXPORT PIStruct {
|
||||
public:
|
||||
PIStruct() {;}
|
||||
PIStruct(const PIString & str) {parseFile(str);}
|
||||
@@ -193,8 +193,3 @@ private:
|
||||
};
|
||||
|
||||
#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