452 lines
14 KiB
C++
452 lines
14 KiB
C++
/*
|
|
PIP - Platform Independent Primitives
|
|
Test program
|
|
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
//#define PIP_DEBUG
|
|
#include "pip.h"
|
|
|
|
|
|
class ThreadTest: public PIThread {
|
|
public:
|
|
ThreadTest(): PIThread() {cnt = 0; b = r = e = false;}
|
|
int cnt;
|
|
bool b, r, e;
|
|
private:
|
|
void begin() {b = true; cout << " thread begin\n";}
|
|
void run() {r = true; cout << " thread run " << cnt++ << endl; if (cnt == 10) stop();}
|
|
void end() {e = true; cout << " thread end\n";}
|
|
};
|
|
|
|
PIMutex mutex_;
|
|
bool m = false;
|
|
int cnt = 0, gm = 0;
|
|
|
|
class MutexTest: public PIThread {
|
|
public:
|
|
MutexTest(): PIThread() {;}
|
|
private:
|
|
void run() {mutex_.lock(); if (m && cnt > 1) gm++; m = true; cout << " " << flush; if (cnt++ >= 128) stop(); msleep(1); mutex_.unlock();}
|
|
};
|
|
|
|
class MutexTest2: public PIThread {
|
|
public:
|
|
MutexTest2(): PIThread() {;}
|
|
private:
|
|
void run() {mutex_.lock(); if (!m && cnt > 1) gm++; m = false; cout << "|" << flush; if (cnt++ >= 128) stop(); msleep(1); mutex_.unlock();}
|
|
};
|
|
|
|
|
|
void signalFunc(PISignals::Signal signal) {
|
|
if (signal != PISignals::Interrupt) return;
|
|
cout << endl << "Ctrl+C pressed, exiting ..." << endl;
|
|
exit(0);
|
|
};
|
|
|
|
|
|
bool t = false;
|
|
void timerEvent(void * data, int delim) {
|
|
t = true;
|
|
cout << " tick from constuctor, delimiter = " << delim << ", data = " << data << endl;
|
|
};
|
|
|
|
bool t2 = false;
|
|
void timerEvent2(void * data, int delim) {
|
|
t2 = true;
|
|
cout << " tick from delimiter " << delim << ", data = " << data << endl;
|
|
};
|
|
|
|
|
|
class ObjectTest: public PIObject {
|
|
PIOBJECT(ObjectTest)
|
|
public:
|
|
ObjectTest(const PIString & name = PIString()): PIObject(name) {h = hi = ht = false;}
|
|
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(event0)
|
|
EVENT(event2)
|
|
|
|
};
|
|
|
|
class CA: public PIObject {
|
|
PIOBJECT(CA)
|
|
public:
|
|
CA(const PIString & n): PIObject(n) {;}
|
|
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(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(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(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);
|
|
}
|
|
|
|
|
|
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 msgHeader {
|
|
msgHeader(ushort msg_id_ = 0) {
|
|
sign[0] = 'B';
|
|
sign[1] = 'R';
|
|
sign[2] = 'K';
|
|
sign[3] = 'D';
|
|
msg_id = msg_id_;
|
|
sys_id = 2;
|
|
subsys_id = 1;
|
|
fragment = security = cnt = 0;
|
|
size = sizeof(msgHeader);
|
|
}
|
|
char sign[4];
|
|
ushort size;
|
|
ushort cnt;
|
|
uchar fragment;
|
|
ushort msg_id;
|
|
uchar sys_id;
|
|
uchar subsys_id;
|
|
uchar security;
|
|
bool verify_sign() {return (sign[0] == 'B' && sign[1] == 'R' && sign[2] == 'K' && sign[3] == 'D');}
|
|
};
|
|
|
|
|
|
struct msg2105base {
|
|
msgHeader header;
|
|
union {
|
|
ullong msgTime;
|
|
struct {
|
|
uint time_ns;
|
|
uint time_s;
|
|
};
|
|
};
|
|
uint id;
|
|
ushort type1kod;
|
|
float type1ver;
|
|
ushort type2kod;
|
|
float type2ver;
|
|
ushort type3kod;
|
|
float type3ver;
|
|
double azimut;
|
|
ullong imp_recv_time;
|
|
double geo_width_PEC;
|
|
double geo_length_PEC;
|
|
double geo_width_CP;
|
|
double geo_length_CP;
|
|
float height;
|
|
float kurs_CP;
|
|
float kren_CP;
|
|
float tangaj_CP;
|
|
};
|
|
|
|
|
|
struct InpuData {
|
|
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)
|
|
|
|
class RC: public PIObject {
|
|
PIOBJECT(RC)
|
|
public:
|
|
EVENT_HANDLER2(void, re, ullong, id, int, size) {piCout << "written id =" << id << "size =" << size;}
|
|
};
|
|
|
|
|
|
int main(int argc, char ** argv) {
|
|
InpuData data;
|
|
PIEthernet eth(PIEthernet::UDP);
|
|
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(((ci >> b) & 1) == 1);
|
|
}
|
|
//cout << ba_.byteSize() << ", " << ba_.bitSize() << endl;
|
|
memcpy(data.data, ba_.data(), 122);
|
|
eth.send("127.0.0.1:5000", &data, sizeof(data));
|
|
}
|
|
/*cout << ba_ << endl;
|
|
for (int i = 0; i < 122; ++i)
|
|
cout << int(data.data[i]) << ", ";
|
|
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;*/
|
|
|
|
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;
|
|
cout << "== Built with PIP " << PIPVersion() << " ==" << endl << endl;
|
|
cout << "== String test ==" << endl;
|
|
PIString string("test string");
|
|
cout << " \"test string\" -> \"" << string << "\"" << endl;
|
|
if (string.length() != 11) succ = r_string = false;
|
|
cout << " to char * = \"" << string.data() << "\"" << endl;
|
|
cout << " to std::string = \"" << string.stdString() << "\"" << endl;
|
|
if (string.stdString().length() != 11) succ = r_string = false;
|
|
#ifdef HAS_LOCALE
|
|
cout << " to std::wstring = \"" << string.stdWString() << "\"" << endl;
|
|
if (string.stdWString().length() != 11) succ = r_string = false;
|
|
#endif
|
|
if (succ) cout << " convertions success" << endl;
|
|
else cout << " convertions fail" << endl;
|
|
succ = true;
|
|
string = PIString("αβγ°℃");
|
|
cout << " \"αβγ°℃\" -> \"" << string << "\"" << endl;
|
|
if (string.length() != 5) succ = r_string = false;
|
|
cout << " to char * = \"" << string.data() << "\"" << endl;
|
|
cout << " to std::string = \"" << string.stdString() << "\"" << endl;
|
|
if (string.stdString().length() != 11) succ = r_string = false;
|
|
#ifdef HAS_LOCALE
|
|
cout << " to std::wstring = \"" << string.stdWString() << "\"" << endl;
|
|
if (string.stdWString().length() != 5) succ = r_string = false;
|
|
#endif
|
|
if (succ) cout << " complex convertions success" << endl;
|
|
else cout << " complex convertions fail" << endl;
|
|
if (r_string) cout << "== Success ==" << endl;
|
|
else cout << "== Fail ==" << endl;
|
|
|
|
cout << endl << "== Thread test ==" << endl;
|
|
ThreadTest thread;
|
|
thread.start(100);
|
|
msleep(10);
|
|
thread.waitForFinish();
|
|
r_thread = thread.b && thread.r && thread.e && thread.cnt == 10;
|
|
if (r_thread) cout << "== Success ==" << endl;
|
|
else cout << "== Fail ==" << endl;
|
|
|
|
cout << endl << "== Mutex test ==" << endl << " ";
|
|
MutexTest thread_m;
|
|
MutexTest2 thread_m2;
|
|
thread_m.start();
|
|
thread_m2.start();
|
|
thread_m.waitForFinish();
|
|
thread_m2.waitForFinish();
|
|
cout << endl;
|
|
r_mutex = gm < 5;
|
|
if (r_mutex) cout << "== Success ==" << endl;
|
|
else cout << "== Fail ==" << endl;
|
|
|
|
cout << endl << "== Timer test ==" << endl;
|
|
PITimer timer(timerEvent, (void*)255);
|
|
timer.addDelimiter(2);
|
|
timer.addDelimiter(5, timerEvent2);
|
|
timer.start(100.f);
|
|
msleep(1005);
|
|
timer.stop();
|
|
r_timer = t && t2;
|
|
if (r_timer) cout << "== Success ==" << endl;
|
|
else cout << "== Fail ==" << endl;
|
|
|
|
cout << endl << "== File test ==" << endl;
|
|
PIFile file(" file_test", PIIODevice::ReadWrite);
|
|
cout << " file \"" << file.path() << "\" is ";
|
|
if (!file.isOpened()) cout << "not ";
|
|
cout << "opened" << endl;
|
|
file.clear();
|
|
file << "test string";
|
|
cout << " write " << file.pos() << " bytes" << endl;
|
|
if (file.pos() != 11) r_file = false;
|
|
PIByteArray ba = file.readAll();
|
|
if (ba.size() != 11) r_file = false;
|
|
cout << " read " << ba.size() << " bytes: \"" << PIString(ba) << '\"' << endl;
|
|
file.remove();
|
|
if (r_file) cout << "== Success ==" << endl;
|
|
else cout << "== Fail ==" << endl;
|
|
|
|
cout << endl << "== Evaluator test ==" << endl;
|
|
PIEvaluator evaluator;
|
|
evaluator.setVariable("x", complexd(2., 1.));
|
|
PIString expression("2x^2 + i");
|
|
evaluator.check(expression);
|
|
cout << " expression = \"" << expression << '\"' << endl;
|
|
cout << " recognized = \"" << evaluator.expression() << '\"' << endl;
|
|
cout << " error = \"" << evaluator.error() << '\"' << endl;
|
|
cout << " \"x\" = " << evaluator.content.variable("x").value << endl;
|
|
cout << " result = " << evaluator.evaluate() << endl;
|
|
r_eval = round(evaluator.lastResult()) == complexd(6., 9.);
|
|
if (r_eval) cout << "== Success ==" << endl;
|
|
else cout << "== Fail ==" << endl;
|
|
|
|
cout << endl << "== Event test ==" << endl;
|
|
ObjectTest object("obj");
|
|
ObjectTest2 object2("obj2");
|
|
PITimer timer2;
|
|
timer2.setData((void * )128);
|
|
timer2.addDelimiter(2);
|
|
timer2.addDelimiter(5);
|
|
CONNECT0(void, &object2, event0, &object, handler);
|
|
CONNECT2(void, int, PIString, &object2, event2, &object, handler_i_s);
|
|
CONNECT2(void, void * , int, &timer2, timeout, &object, handler_timeout);
|
|
object2.raise0("event0");
|
|
object2.raise2("event2", 123, "string");
|
|
timer2.start(100.f);
|
|
msleep(505);
|
|
timer2.stop();
|
|
CA ca("cd");
|
|
CD cd("cd");
|
|
CONNECT(void, &ca, event_ca, &cd, handler_cd);
|
|
CONNECT(void, &ca, event_ca, &cd, handler_cc);
|
|
CONNECT(void, &ca, event_ca, &cd, handler_cb);
|
|
CONNECT(void, &ca, event_ca, &cd, handler_ca);
|
|
PIObject::raiseEvent(&ca, "event_ca");
|
|
r_event = object.h && object.hi && object.ht && cd.a && cd.b && cd.c && cd.d;
|
|
if (r_event) cout << "== Success ==" << endl;
|
|
else cout << "== Fail ==" << endl;
|
|
|
|
cout << endl << "== Results ==" << endl;
|
|
cout << "= String " << r_string << " =" << endl;
|
|
cout << "= Thread " << r_thread << " =" << endl;
|
|
cout << "= Mutex " << r_mutex << " =" << endl;
|
|
cout << "= Timer " << r_timer << " =" << endl;
|
|
cout << "= File " << r_file << " =" << endl;
|
|
cout << "= Evaluator " << r_eval << " =" << endl;
|
|
cout << "= Event " << r_event << " =" << endl;
|
|
if (r_string && r_thread && r_mutex && r_timer && r_file && r_eval && r_event)
|
|
cout << "== All tests successful ==" << endl;
|
|
};
|