493 lines
16 KiB
C++
493 lines
16 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/>.
|
||
*/
|
||
|
||
#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 << "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 {
|
||
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;}
|
||
bool h, hi, ht;
|
||
};
|
||
|
||
|
||
class ObjectTest2: public PIObject {
|
||
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)
|
||
|
||
};
|
||
|
||
class CA: public PIObject {
|
||
public:
|
||
CA(const PIString & n): PIObject(n) {;}
|
||
EVENT_HANDLER(CA, void, handler_ca) {a = true; cout << " handler CA" << endl;}
|
||
EVENT(CA, event_ca)
|
||
bool a;
|
||
};
|
||
|
||
class CB: public CA {
|
||
public:
|
||
CB(const PIString & n): CA(n) {;}
|
||
EVENT_HANDLER(CB, void, handler_cb) {b = true; cout << " handler CB" << endl;}
|
||
bool b;
|
||
};
|
||
|
||
class CC: public CB {
|
||
public:
|
||
CC(const PIString & n): CB(n) {;}
|
||
EVENT_HANDLER(CC, void, handler_cc) {c = true; cout << " handler CC" << endl;}
|
||
bool c;
|
||
};
|
||
|
||
class CD: public CC {
|
||
public:
|
||
CD(const PIString & n): CC(n) {;}
|
||
EVENT_HANDLER(CD, void, handler_cd) {d = true; cout << " handler CD" << endl;}
|
||
bool d;
|
||
};
|
||
|
||
|
||
struct Packet {
|
||
int from;
|
||
int to;
|
||
float data;
|
||
int cs;
|
||
};
|
||
|
||
|
||
#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 {
|
||
char sign[4];
|
||
unsigned short size;
|
||
unsigned short cnt;
|
||
unsigned char fragment;
|
||
unsigned short msg_id;
|
||
unsigned char sys_id;
|
||
unsigned char subsys_id;
|
||
unsigned char security;
|
||
bool verify_sign()
|
||
{
|
||
bool ok;
|
||
ok = sign[0] == 'B';
|
||
ok = ok && sign[1] == 'R';
|
||
ok = ok && sign[2] == 'K';
|
||
ok = ok && sign[3] == 'D';
|
||
return ok;
|
||
}
|
||
};
|
||
struct FilterCommand {
|
||
FilterCommand() {
|
||
memset(this, 0, sizeof(FilterCommand));
|
||
header.sign[0] = 'B'; header.sign[1] = 'R'; header.sign[2] = 'K'; header.sign[3] = 'D';
|
||
header.size = sizeof(FilterCommand);
|
||
header.cnt = header.fragment = header.security = 0;
|
||
header.msg_id = 2102;
|
||
header.sys_id = header.subsys_id = 2;
|
||
command = 3;
|
||
}
|
||
|
||
msgHeader header;
|
||
uchar command; // 3
|
||
struct {
|
||
uchar fi_number: 7; // номер частотного участка, 1 - 36
|
||
uchar bort : 1; // борт: 0 - левый, 1 - правый
|
||
};
|
||
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;
|
||
};
|
||
|
||
#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;
|
||
|
||
/*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;
|
||
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;
|
||
PIBitArray ba_;
|
||
for (int i = 0; i < 97; ++i) {
|
||
for (int b = 0; b < 10; ++b)
|
||
ba_.push_back(((i >> b) & 1) == 1);
|
||
}
|
||
//cout << ba_.byteSize() << ", " << ba_.bitSize() << endl;
|
||
memcpy(data.data, ba_.data(), 122);
|
||
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));
|
||
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();*/
|
||
|
||
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;
|
||
};
|