18.03.2013 - Bug fixes, add in/out speed diagnostic to PIProtocol, fixed PIConsole tab switch segfault, PIObject EVENT / EVENT_HANDLER mechanism update - new EVENT macros that use EVENT_HANDLER with raiseEvent implementation.
This allow compile check event for CONNECT and use EVENT as CONNECT target, also raise event now is simple execute EVENT function.
This commit is contained in:
@@ -1,22 +1,23 @@
|
||||
project(pip)
|
||||
find_package(Qt4)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} . ${QT_INCLUDES})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${QT_INCLUDES} . ../peri4_widgets)
|
||||
file(GLOB CPPS "pi*.cpp")
|
||||
if (${WIN32})
|
||||
add_definitions(-Wall -O2)
|
||||
else (${WIN32})
|
||||
add_definitions(-Wall -O2 -g3)
|
||||
add_definitions(-Wall -O2 -g3 --fast-math)
|
||||
endif (${WIN32})
|
||||
add_library(pip SHARED ${CPPS})
|
||||
if (${WIN32})
|
||||
target_link_libraries(pip pthread ws2_32)
|
||||
target_link_libraries(pip pthread ws2_32 Iphlpapi)
|
||||
else (${WIN32})
|
||||
target_link_libraries(pip pthread rt)
|
||||
endif (${WIN32})
|
||||
add_executable(pip_test "main.cpp")
|
||||
if (${WIN32})
|
||||
target_link_libraries(pip_test pthread ws2_32 pip)
|
||||
target_link_libraries(pip_test pthread ws2_32 Iphlpapi pip)
|
||||
else (${WIN32})
|
||||
target_link_libraries(pip_test pthread rt pip ${QT_QTCORE_LIBRARY})
|
||||
target_link_libraries(pip_test pip ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} pcollection)
|
||||
endif (${WIN32})
|
||||
add_subdirectory(system_test)
|
||||
|
||||
22
clean
22
clean
@@ -1,19 +1,7 @@
|
||||
#! /bin/bash
|
||||
#! /bin/sh
|
||||
VERBOSE=1 make clean
|
||||
rm -vf ./lib/*
|
||||
#for i in $( ls -1 ); do
|
||||
# if [ "`ls -1 --file-type | grep $i | grep -o /`" = "/" ]; then
|
||||
# cd $i
|
||||
# rm -rvf ./CMakeFiles
|
||||
# rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~
|
||||
# cd ../
|
||||
# fi
|
||||
#done
|
||||
rm -rvf ./CMakeFiles
|
||||
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o
|
||||
#cd ./include
|
||||
#for i in $( ls -1 ); do
|
||||
# if [ "`ls -1 --file-type $i | grep -v @`" = "" ]; then
|
||||
# rm -v $i
|
||||
# fi
|
||||
#done
|
||||
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
|
||||
cd system_test
|
||||
rm -rvf ./CMakeFiles
|
||||
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
|
||||
|
||||
256
main.cpp
Executable file → Normal file
256
main.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Test program
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -63,8 +63,7 @@ void timerEvent(void * data, int delim) {
|
||||
cout << " tick from constuctor, delimiter = " << delim << ", data = " << data << endl;
|
||||
};
|
||||
|
||||
bool
|
||||
t2 = false;
|
||||
bool t2 = false;
|
||||
void timerEvent2(void * data, int delim) {
|
||||
t2 = true;
|
||||
cout << " tick from delimiter " << delim << ", data = " << data << endl;
|
||||
@@ -86,12 +85,16 @@ 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;
|
||||
};
|
||||
|
||||
@@ -124,60 +127,212 @@ struct Packet {
|
||||
int cs;
|
||||
};
|
||||
|
||||
bool retH(void * d, uchar * src, uchar * rec, int size) {
|
||||
return (*((int*)rec)) == 1;
|
||||
|
||||
#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]; // Данные
|
||||
};
|
||||
|
||||
bool retF(void * d, uchar * data, int size) {
|
||||
cout << "rec " << size << endl;
|
||||
return true;
|
||||
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[]) {
|
||||
/*Packet p, mp;
|
||||
p.from = mp.from = 1;
|
||||
p.to = mp.to = 2;
|
||||
PISerial ser("/dev/ttyS0");
|
||||
ser.setSpeed(PISerial::S115200);
|
||||
/*tm_.start(10.);
|
||||
PIConsole con(false, ke);
|
||||
con.enableExitCapture();
|
||||
//ser.setParameter(PISerial::HardwareFlowControl);
|
||||
ser.open();
|
||||
ser.setReadIsBlocking(true);
|
||||
PIPacketExtractor pe(&ser, &mp, 8, 8);
|
||||
pe.setThreadedReadSlot(retF);
|
||||
pe.setHeaderCheckSlot(retH);
|
||||
pe.startThreadedRead();
|
||||
ser.write(&p, sizeof(p));
|
||||
p.from = 2;
|
||||
ser.write(&p, sizeof(p));
|
||||
msleep(1000);
|
||||
exit(0);*/
|
||||
PICodec codec;
|
||||
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;*/
|
||||
|
||||
exit(0);
|
||||
/*
|
||||
vec<int> my_v; vector<int> stl_v; QVector<int> qt_v;
|
||||
double el;
|
||||
PITimer tm;
|
||||
/*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;*/
|
||||
|
||||
tm.reset();
|
||||
for (uint i = 0; i < 500000; ++i)
|
||||
my_v.push_back(i);
|
||||
el = tm.elapsed_m();
|
||||
cout << el << endl;
|
||||
/*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;*/
|
||||
|
||||
tm.reset();
|
||||
for (uint i = 0; i < 500000; ++i)
|
||||
stl_v.push_back(i);
|
||||
el = tm.elapsed_m();
|
||||
cout << el << 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;*/
|
||||
|
||||
tm.reset();
|
||||
for (uint i = 0; i < 500000; ++i)
|
||||
qt_v.append(i);
|
||||
el = tm.elapsed_m();
|
||||
cout << el << 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();*/
|
||||
|
||||
exit(0);
|
||||
*/
|
||||
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;
|
||||
@@ -189,8 +344,10 @@ int main(int argc, char * argv[]) {
|
||||
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;
|
||||
@@ -199,9 +356,11 @@ int main(int argc, char * argv[]) {
|
||||
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() != 10) succ = r_string = false;
|
||||
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;
|
||||
@@ -244,6 +403,7 @@ int main(int argc, char * argv[]) {
|
||||
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;
|
||||
@@ -264,7 +424,7 @@ int main(int argc, char * argv[]) {
|
||||
cout << " error = \"" << evaluator.error() << '\"' << endl;
|
||||
cout << " \"x\" = " << evaluator.content.variable("x").value << endl;
|
||||
cout << " result = " << evaluator.evaluate() << endl;
|
||||
r_eval = round(evaluator.lastResult()) == complexd(9., 12.);
|
||||
r_eval = round(evaluator.lastResult()) == complexd(6., 9.);
|
||||
if (r_eval) cout << "== Success ==" << endl;
|
||||
else cout << "== Fail ==" << endl;
|
||||
|
||||
|
||||
2
make.sh
Executable file → Normal file
2
make.sh
Executable file → Normal file
@@ -1,3 +1,3 @@
|
||||
#! /bin/bash
|
||||
#! /bin/sh
|
||||
cmake ./
|
||||
make $@
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /bin/bash
|
||||
#! /bin/sh
|
||||
cmake .
|
||||
make $@
|
||||
cp -vf *.h /usr/include/
|
||||
|
||||
2
pibitarray.h
Executable file → Normal file
2
pibitarray.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Bit array
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
50
pibytearray.cpp
Executable file → Normal file
50
pibytearray.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Byte array
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -59,29 +59,29 @@ PIByteArray & PIByteArray::convertToBase64() {
|
||||
if (size() == 0) return *this;
|
||||
int sz = (size_s() / 3) * 3;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
hs.byte0 = hs.byte1 = hs.byte2 = 0;
|
||||
hs.byte0 = at(i);
|
||||
hs.byte1 = at(++i);
|
||||
hs.byte2 = at(++i);
|
||||
t.push_back(base64Table[hs.ascii0]);
|
||||
t.push_back(base64Table[hs.ascii1]);
|
||||
t.push_back(base64Table[hs.ascii2]);
|
||||
t.push_back(base64Table[hs.ascii3]);
|
||||
hs.byte.byte0 = hs.byte.byte1 = hs.byte.byte2 = 0;
|
||||
hs.byte.byte0 = at(i);
|
||||
hs.byte.byte1 = at(++i);
|
||||
hs.byte.byte2 = at(++i);
|
||||
t.push_back(base64Table[hs.ascii.ascii0]);
|
||||
t.push_back(base64Table[hs.ascii.ascii1]);
|
||||
t.push_back(base64Table[hs.ascii.ascii2]);
|
||||
t.push_back(base64Table[hs.ascii.ascii3]);
|
||||
}
|
||||
hs.byte0 = hs.byte1 = hs.byte2 = 0; sz = size() % 3;
|
||||
hs.byte.byte0 = hs.byte.byte1 = hs.byte.byte2 = 0; sz = size() % 3;
|
||||
switch (sz) {
|
||||
case 1:
|
||||
hs.byte0 = back();
|
||||
t.push_back(base64Table[hs.ascii0]);
|
||||
t.push_back(base64Table[hs.ascii1]);
|
||||
hs.byte.byte0 = back();
|
||||
t.push_back(base64Table[hs.ascii.ascii0]);
|
||||
t.push_back(base64Table[hs.ascii.ascii1]);
|
||||
t.push_back('=');
|
||||
t.push_back('=');
|
||||
break;
|
||||
case 2:
|
||||
hs.byte0 = at(size() - 2); hs.byte1 = back();
|
||||
t.push_back(base64Table[hs.ascii0]);
|
||||
t.push_back(base64Table[hs.ascii1]);
|
||||
t.push_back(base64Table[hs.ascii2]);
|
||||
hs.byte.byte0 = at(size() - 2); hs.byte.byte1 = back();
|
||||
t.push_back(base64Table[hs.ascii.ascii0]);
|
||||
t.push_back(base64Table[hs.ascii.ascii1]);
|
||||
t.push_back(base64Table[hs.ascii.ascii2]);
|
||||
t.push_back('=');
|
||||
break;
|
||||
default: break;
|
||||
@@ -97,14 +97,14 @@ PIByteArray & PIByteArray::convertFromBase64() {
|
||||
uint sz = size();
|
||||
if (sz == 0) return *this;
|
||||
for (uint i = 0; i < sz; ++i) {
|
||||
hs.byte0 = hs.byte1 = hs.byte2 = 0;
|
||||
hs.ascii0 = base64InvTable[at(i)];
|
||||
hs.ascii1 = base64InvTable[at(++i)];
|
||||
hs.ascii2 = base64InvTable[at(++i)];
|
||||
hs.ascii3 = base64InvTable[at(++i)];
|
||||
t.push_back(hs.byte0);
|
||||
t.push_back(hs.byte1);
|
||||
t.push_back(hs.byte2);
|
||||
hs.byte.byte0 = hs.byte.byte1 = hs.byte.byte2 = 0;
|
||||
hs.ascii.ascii0 = base64InvTable[at(i)];
|
||||
hs.ascii.ascii1 = base64InvTable[at(++i)];
|
||||
hs.ascii.ascii2 = base64InvTable[at(++i)];
|
||||
hs.ascii.ascii3 = base64InvTable[at(++i)];
|
||||
t.push_back(hs.byte.byte0);
|
||||
t.push_back(hs.byte.byte1);
|
||||
t.push_back(hs.byte.byte2);
|
||||
}
|
||||
if (back() == '=') t.pop_back();
|
||||
if (sz > 1) if (at(sz - 2) == '=') t.pop_back();
|
||||
|
||||
51
pibytearray.h
Executable file → Normal file
51
pibytearray.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Byte array
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -110,6 +110,15 @@ public:
|
||||
|
||||
PIByteArray & compressHuffman() {*this = huffman.compress(*this); return *this;}
|
||||
|
||||
PIByteArray & append(void * data, int size) {for (int i = 0; i < size; ++i) push_back(((uchar*)data)[i]); return *this;}
|
||||
/*PIByteArray & operator <<(short v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}
|
||||
PIByteArray & operator <<(ushort v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}
|
||||
PIByteArray & operator <<(int v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}
|
||||
PIByteArray & operator <<(uint v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}
|
||||
PIByteArray & operator <<(llong v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}
|
||||
PIByteArray & operator <<(ullong v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}*/
|
||||
PIByteArray & operator <<(const PIByteArray & v) {for (uint i = 0; i < v.size(); ++i) push_back(v[i]); return *this;}
|
||||
|
||||
uchar checksumPlain8();
|
||||
uint checksumPlain32();
|
||||
uchar checksumCRC8();
|
||||
@@ -125,12 +134,12 @@ private:
|
||||
uchar ascii1: 6;
|
||||
uchar ascii2: 6;
|
||||
uchar ascii3: 6;
|
||||
};
|
||||
} ascii;
|
||||
struct {
|
||||
uchar byte0;
|
||||
uchar byte1;
|
||||
uchar byte2;
|
||||
};
|
||||
} byte;
|
||||
};
|
||||
|
||||
static PIHuffman huffman;
|
||||
@@ -139,4 +148,40 @@ 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 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;}
|
||||
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;}
|
||||
|
||||
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;}
|
||||
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;}
|
||||
|
||||
#endif // PIBYTEARRAY_H
|
||||
|
||||
9
pichar.h
Executable file → Normal file
9
pichar.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Unicode char
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,11 +20,13 @@
|
||||
#ifndef PICHAR_H
|
||||
#define PICHAR_H
|
||||
|
||||
#include "piincludes.h"
|
||||
#include "pibytearray.h"
|
||||
|
||||
class PIChar
|
||||
{
|
||||
friend class PIString;
|
||||
friend PIByteArray & operator <<(PIByteArray & s, const PIChar & v);
|
||||
friend PIByteArray & operator >>(PIByteArray & s, PIChar & v);
|
||||
public:
|
||||
PIChar(const char c) {ch = c; ch &= 0xFF;}
|
||||
PIChar(const short c) {ch = c; ch &= 0xFFFF;}
|
||||
@@ -100,6 +102,9 @@ private:
|
||||
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIChar & v) {s << v.toCharPtr(); return s;}
|
||||
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {s << uint(v.ch); return s;}
|
||||
inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {uint i; s >> i; v.ch = wchar_t(i); return s;}
|
||||
|
||||
inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);}
|
||||
inline bool operator >(const char v, const PIChar & c) {return (PIChar(v) > c);}
|
||||
inline bool operator <(const char v, const PIChar & c) {return (PIChar(v) < c);}
|
||||
|
||||
4
picli.cpp
Executable file → Normal file
4
picli.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Command-Line Parser
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,7 +25,7 @@ PICLI::PICLI(int argc, char * argv[]) {
|
||||
_prefix_short = "-";
|
||||
_prefix_full = "--";
|
||||
_count_opt = 0;
|
||||
_count_mand = 1;
|
||||
_count_mand = 0;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
_args_raw << argv[i];
|
||||
}
|
||||
|
||||
2
picli.h
Executable file → Normal file
2
picli.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Command-Line Parser
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
picodec.cpp
Executable file → Normal file
2
picodec.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Text codings coder, based on "iconv"
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
picodec.h
Executable file → Normal file
2
picodec.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Text codings coder, based on "iconv"
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
5
piconfig.cpp
Executable file → Normal file
5
piconfig.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Config parser
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -396,6 +396,7 @@ void PIConfig::writeAll() {
|
||||
*this << other[i];
|
||||
if (i < other.size_s() - 1) *this << '\n';
|
||||
}
|
||||
//cout << other[i] << endl;
|
||||
}
|
||||
flush();
|
||||
readAll();
|
||||
@@ -433,9 +434,9 @@ void PIConfig::parse() {
|
||||
while (!isEnd()) {
|
||||
other.push_back(PIString());
|
||||
src = str = readLine();
|
||||
//cout << str << endl;
|
||||
tab = str.left(str.find(str.trimmed().left(1)));
|
||||
str.trim();
|
||||
//cout << endl << str << endl << endl;
|
||||
all = str;
|
||||
ind = str.find('=');
|
||||
if ((ind > 0) && !(str[0] == '#')) {
|
||||
|
||||
2
piconfig.h
Executable file → Normal file
2
piconfig.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Config parser
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
119
piconsole.cpp
Executable file → Normal file
119
piconsole.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Console output/input
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -56,16 +56,20 @@ PIConsole::~PIConsole() {
|
||||
|
||||
|
||||
int PIConsole::addTab(const PIString & name, char bind_key) {
|
||||
if (isRunning()) lock();
|
||||
tabs.push_back(Tab(name, bind_key));
|
||||
cur_tab = tabs.size() - 1;
|
||||
if (isRunning()) unlock();
|
||||
return tabs.size();
|
||||
}
|
||||
|
||||
|
||||
void PIConsole::removeTab(uint index) {
|
||||
if (index >= tabs.size()) return;
|
||||
if (isRunning()) lock();
|
||||
tabs.remove(index);
|
||||
if (cur_tab >= tabs.size()) cur_tab = tabs.size() - 1;
|
||||
if (isRunning()) unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -84,9 +88,12 @@ void PIConsole::removeTab(const PIString & name) {
|
||||
bool PIConsole::setTab(uint index) {
|
||||
if (index >= tabs.size())
|
||||
return false;
|
||||
if (!isRunning()) {
|
||||
cur_tab = index;
|
||||
if (!isRunning()) return true;
|
||||
return true;
|
||||
}
|
||||
lock();
|
||||
cur_tab = index;
|
||||
clearScreen();
|
||||
fillLabels();
|
||||
unlock();
|
||||
@@ -156,6 +163,7 @@ PIString PIConsole::fstr(PIFlags<PIConsole::Format> f) {
|
||||
if (f[PIConsole::Dec]) num_format = 0;
|
||||
if (f[PIConsole::Hex]) num_format = 1;
|
||||
if (f[PIConsole::Oct]) num_format = 2;
|
||||
if (f[PIConsole::Bin]) num_format = 4;
|
||||
if (f[PIConsole::Scientific]) num_format = 3;
|
||||
|
||||
#ifdef WINDOWS
|
||||
@@ -232,15 +240,15 @@ PIString PIConsole::fstr(PIFlags<PIConsole::Format> f) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#define siprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; default: return printf("%hd", x); break;}
|
||||
#define iprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; default: return printf("%d", x); break;}
|
||||
#define liprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; default: return printf("%ld", x); break;}
|
||||
#define lliprint(x) switch (num_format) {case (1): return printf("0x%.16llX", x); break; case (2): return printf("%llo", x); break; default: return printf("%lld", x); break;}
|
||||
#define cuprint(x) switch (num_format) {case (1): return printf("0x%.2X", x); break; case (2): return printf("%o", x); break; default: return printf("%u", x); break;}
|
||||
#define suprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; default: return printf("%hu", x); break;}
|
||||
#define uprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; default: return printf("%u", x); break;}
|
||||
#define luprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; default: return printf("%lu", x); break;}
|
||||
#define lluprint(x) switch (num_format) {case (1): return printf("0x%.16llX", x); break; case (2): return printf("%llo", x); break; default: return printf("%llu", x); break;}
|
||||
#define siprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; case (4): return printf("%s", toBin(&x, 2)); break; default: return printf("%hd", x); break;}
|
||||
#define iprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; case (4): return printf("%s", toBin(&x, 4)); break; default: return printf("%d", x); break;}
|
||||
#define liprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; case (4): return printf("%s", toBin(&x, sizeof(x))); break; default: return printf("%ld", x); break;}
|
||||
#define lliprint(x) switch (num_format) {case (1): return printf("0x%.16llX", x); break; case (2): return printf("%llo", x); break; case (4): return printf("%s", toBin(&x, sizeof(x))); break; default: return printf("%lld", x); break;}
|
||||
#define cuprint(x) switch (num_format) {case (1): return printf("0x%.2X", x); break; case (2): return printf("%o", x); break; case (4): return printf("%s", toBin(&x, 1)); break; default: return printf("%u", x); break;}
|
||||
#define suprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; case (4): return printf("%s", toBin(&x, 2)); break; default: return printf("%hu", x); break;}
|
||||
#define uprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; case (4): return printf("%s", toBin(&x, 4)); break; default: return printf("%u", x); break;}
|
||||
#define luprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; case (4): return printf("%s", toBin(&x, sizeof(x))); break; default: return printf("%lu", x); break;}
|
||||
#define lluprint(x) switch (num_format) {case (1): return printf("0x%.16llX", x); break; case (2): return printf("%llo", x); break; case (4): return printf("%s", toBin(&x, sizeof(x))); break; default: return printf("%llu", x); break;}
|
||||
#define fprint(x) switch (num_format) {case (3): return printf("%e", x); break; default: return printf("%.5g", x); break;}
|
||||
#define dprint(x) switch (num_format) {case (3): return printf("%le", x); break; default: return printf("%.5lg", x); break;}
|
||||
|
||||
@@ -312,20 +320,20 @@ void PIConsole::run() {
|
||||
case 1: clen = printValue(tv.b != 0 ? *tv.b : false, tv.format); break;
|
||||
case 2: clen = printValue(tv.i != 0 ? *tv.i : 0, tv.format); break;
|
||||
case 3: clen = printValue(tv.l != 0 ? *tv.l : 0l, tv.format); break;
|
||||
case 4: clen = printValue(tv.c != 0 ? *tv.c : 0, tv.format); break;
|
||||
case 4: clen = printValue(tv.c != 0 ? *tv.c : char(0), tv.format); break;
|
||||
case 5: clen = printValue(tv.f != 0 ? *tv.f : 0.f, tv.format); break;
|
||||
case 6: clen = printValue(tv.d != 0 ? *tv.d : 0., tv.format); break;
|
||||
case 7: clen = printValue(tv.sh != 0 ? *tv.sh : 0, tv.format); break;
|
||||
case 7: clen = printValue(tv.sh != 0 ? *tv.sh : short(0), tv.format); break;
|
||||
case 8: clen = printValue(tv.ui != 0 ? *tv.ui : 0u, tv.format); break;
|
||||
case 9: clen = printValue(tv.ul != 0 ? *tv.ul : 0ul, tv.format); break;
|
||||
case 10: clen = printValue(tv.ush != 0 ? *tv.ush : 0u, tv.format); break;
|
||||
case 11: clen = printValue(tv.uc != 0 ? *tv.uc : 0u, tv.format); break;
|
||||
case 10: clen = printValue(tv.ush != 0 ? *tv.ush : ushort(0), tv.format); break;
|
||||
case 11: clen = printValue(tv.uc != 0 ? *tv.uc : uchar(0), tv.format); break;
|
||||
case 12: clen = printValue(tv.ll != 0 ? *tv.ll : 0l, tv.format); break;
|
||||
case 13: clen = printValue(tv.ull != 0 ? *tv.ull : 0ull, tv.format); break;
|
||||
case 14: clen = printValue(bitsValue(tv.ptr, tv.bitFrom, tv.bitCount), tv.format); break;
|
||||
}
|
||||
if (clen + tv.offset < (uint)col_wid) {
|
||||
#ifdef QNX
|
||||
#if defined(QNX) || defined(FREE_BSD)
|
||||
string ts = PIString(col_wid - clen - tv.offset - 1, ' ').stdString();
|
||||
#else
|
||||
string ts = PIString(col_wid - clen - tv.offset, ' ').stdString();
|
||||
@@ -340,6 +348,7 @@ void PIConsole::run() {
|
||||
|
||||
|
||||
void PIConsole::fillLabels() {
|
||||
if (!isRunning()) return;
|
||||
uint cx, cy, my = 0, mx = 0, dx;
|
||||
#ifdef WINDOWS
|
||||
GetConsoleScreenBufferInfo(hOut, &sbi);
|
||||
@@ -359,7 +368,7 @@ void PIConsole::fillLabels() {
|
||||
if (ccol.alignment != Nothing) {
|
||||
mx = 0;
|
||||
piForeachC (Variable & j, cvars)
|
||||
if (j.type != 0 && j.s != 0)
|
||||
if (j.s != 0)
|
||||
if (mx < j.name.size())
|
||||
mx = j.name.size();
|
||||
mx += 2;
|
||||
@@ -390,6 +399,7 @@ void PIConsole::fillLabels() {
|
||||
cy++;
|
||||
continue;
|
||||
}
|
||||
if (tv.s != 0) {
|
||||
switch (ccol.alignment) {
|
||||
case Nothing:
|
||||
cvars[j].offset = (tv.name + ": ").length();
|
||||
@@ -410,6 +420,7 @@ void PIConsole::fillLabels() {
|
||||
moveLeft(dx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
newLine();
|
||||
cy++;
|
||||
}
|
||||
@@ -442,78 +453,98 @@ void PIConsole::status() {
|
||||
}
|
||||
|
||||
|
||||
int PIConsole::bitsValue(void * src, int offset, int count) {
|
||||
int PIConsole::bitsValue(const void * src, int offset, int count) {
|
||||
int ret = 0, stbyte = offset / 8, cbit = offset - stbyte * 8;
|
||||
char cbyte = reinterpret_cast<char * >(src)[stbyte];
|
||||
char cbyte = reinterpret_cast<const char * >(src)[stbyte];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret |= ((cbyte >> cbit & 1) << i);
|
||||
cbit++;
|
||||
if (cbit == 8) {
|
||||
cbit = 0;
|
||||
stbyte++;
|
||||
cbyte = reinterpret_cast<char * >(src)[stbyte];
|
||||
cbyte = reinterpret_cast<const char * >(src)[stbyte];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const char * PIConsole::toBin(const void * d, int s) {
|
||||
binstr.clear();
|
||||
uchar cc, b;
|
||||
for (int i = 0; i < s; ++i) {
|
||||
cc = ((const uchar *)d)[i];
|
||||
b = 1;
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
binstr << (cc & b ? "1" : "0");
|
||||
b <<= 1;
|
||||
}
|
||||
if (i < s - 1) binstr << " ";
|
||||
}
|
||||
binstr.reverse();
|
||||
return binstr.data();
|
||||
}
|
||||
|
||||
|
||||
#define ADD_VAR_BODY tv.name = name; tv.bitFrom = tv.bitCount = 0; tv.format = format; checkColumn(col);
|
||||
|
||||
void PIConsole::addString(const PIString & name, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 0; tv.s = 0; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, PIString* ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const PIString* ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 0; tv.s = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, bool * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const bool * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 1; tv.b = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, int * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const int * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 2; tv.i = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, long * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const long * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 3; tv.l = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, char * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const char * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 4; tv.c = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, float * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const float * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 5; tv.f = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, double * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const double * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 6; tv.d = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, short * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const short * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 7; tv.sh = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, uint * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const uint * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 8; tv.ui = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, ulong * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const ulong * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 9; tv.ul = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, ushort * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const ushort * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 10; tv.ush = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, uchar * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const uchar * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 11; tv.uc = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, llong * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const llong * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 12; tv.ll = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, ullong * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const ullong * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 13; tv.ull = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, PIProtocol * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const PIProtocol * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
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("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("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), col, format);
|
||||
addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), col, format);
|
||||
addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), col, format);
|
||||
addVariable("Receive speed", ptr->receiveSpeed_ptr(), col, format);
|
||||
addVariable("Send speed", ptr->sendSpeed_ptr(), col, format);
|
||||
addVariable("Receiver history size", ptr->receiverHistorySize_ptr(), col, format);
|
||||
addVariable("Sender history size", ptr->senderHistorySize_ptr(), col, format);
|
||||
addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), col, format);
|
||||
addVariable("Quality", ptr->quality_ptr(), col, format);
|
||||
}
|
||||
void PIConsole::addVariable(const PIString & name, PISystemMonitor * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, const PISystemMonitor * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
addString("monitor " + name, col, format | PIConsole::Bold);
|
||||
addVariable("state ", &(ptr->statistic().state), col, format);
|
||||
addVariable("threads ", &(ptr->statistic().threads), col, format);
|
||||
addVariable("state", &(ptr->statistic().state), col, format);
|
||||
addVariable("threads", &(ptr->statistic().threads), col, format);
|
||||
addVariable("priority", &(ptr->statistic().priority), col, format);
|
||||
addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), col, format);
|
||||
addVariable("memory shared ", &(ptr->statistic().share_memsize_readable), col, format);
|
||||
addVariable("memory shared", &(ptr->statistic().share_memsize_readable), col, format);
|
||||
addVariable("cpu load", &(ptr->statistic().cpu_load_system), col, format);
|
||||
}
|
||||
void PIConsole::addBitVariable(const PIString & name, void * ptr, int fromBit, int bitCount, int col, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addBitVariable(const PIString & name, const void * ptr, int fromBit, int bitCount, int col, PIFlags<PIConsole::Format> format) {
|
||||
tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.ptr = ptr; tv.format = format;
|
||||
checkColumn(col); column(col).push_back(tv);}
|
||||
void PIConsole::addEmptyLine(int col, uint count) {
|
||||
@@ -562,7 +593,7 @@ PIString PIConsole::getString(const PIString & name) {
|
||||
|
||||
inline void PIConsole::printLine(const PIString & value, int dx, PIFlags<PIConsole::Format> format) {
|
||||
int i = width - value.length() - dx;
|
||||
#ifdef QNX
|
||||
#if defined(QNX) || defined(FREE_BSD)
|
||||
--i;
|
||||
#endif
|
||||
PIString ts = fstr(format);
|
||||
|
||||
77
piconsole.h
Executable file → Normal file
77
piconsole.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Console output/input
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -28,6 +28,10 @@
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
/// handlers:
|
||||
/// void clearVariables(bool clearScreen = true)
|
||||
/// void start(bool wait = false)
|
||||
/// void stop(bool clear = false)
|
||||
class PIConsole: public PIThread
|
||||
{
|
||||
public:
|
||||
@@ -60,27 +64,28 @@ public:
|
||||
Dec = 0x1000000,
|
||||
Hex = 0x2000000,
|
||||
Oct = 0x4000000,
|
||||
Scientific = 0x8000000};
|
||||
Bin = 0x8000000,
|
||||
Scientific = 0x10000000};
|
||||
enum Alignment {Nothing, Left, Right};
|
||||
|
||||
void addString(const PIString & name, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, PIString * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, char * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, bool * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, short * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, int * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, long * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, llong * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, uchar * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, ushort * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, uint * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, ulong * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, ullong * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, float * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, double * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, PIProtocol * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, PISystemMonitor * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addBitVariable(const PIString & name, void * ptr, int fromBit, int bitCount, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const PIString * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const char * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const bool * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const short * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const int * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const long * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const llong * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const uchar * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const ushort * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const uint * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const ulong * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const ullong * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const float * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const double * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, const PIProtocol * 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);
|
||||
|
||||
PIString getString(int x, int y);
|
||||
@@ -162,7 +167,8 @@ private:
|
||||
#endif
|
||||
void status();
|
||||
void checkColumn(uint col) {while (columns().size() < col) columns().push_back(Column(def_align));}
|
||||
int bitsValue(void * src, int offset, int count);
|
||||
int bitsValue(const void * src, int offset, int count);
|
||||
const char * toBin(const void * d, int s);
|
||||
inline void printLine(const PIString & str, int dx = 0, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const PIString & str, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const char * str, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
@@ -191,21 +197,21 @@ private:
|
||||
int bitFrom;
|
||||
int bitCount;
|
||||
union {
|
||||
PIString * s;
|
||||
bool * b;
|
||||
short * sh;
|
||||
int * i;
|
||||
long * l;
|
||||
llong * ll;
|
||||
float * f;
|
||||
double * d;
|
||||
char * c;
|
||||
uchar * uc;
|
||||
ushort * ush;
|
||||
uint * ui;
|
||||
ulong * ul;
|
||||
ullong * ull;
|
||||
void * ptr;
|
||||
const PIString * s;
|
||||
const bool * b;
|
||||
const short * sh;
|
||||
const int * i;
|
||||
const long * l;
|
||||
const llong * ll;
|
||||
const float * f;
|
||||
const double * d;
|
||||
const char * c;
|
||||
const uchar * uc;
|
||||
const ushort * ush;
|
||||
const uint * ui;
|
||||
const ulong * ul;
|
||||
const ullong * ull;
|
||||
const void * ptr;
|
||||
};
|
||||
void operator =(const Variable & src) {name = src.name; format = src.format; type = src.type; offset = src.offset;
|
||||
bitFrom = src.bitFrom; bitCount = src.bitCount; ptr = src.ptr; nx = src.nx; ny = src.ny;}
|
||||
@@ -261,6 +267,7 @@ private:
|
||||
struct termios sterm, vterm;
|
||||
#endif
|
||||
PIVector<Tab> tabs;
|
||||
PIString binstr;
|
||||
Variable tv;
|
||||
PIKbdListener * listener;
|
||||
Alignment def_align;
|
||||
|
||||
26
picontainers.h
Executable file → Normal file
26
picontainers.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Generic containers, based on STL
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -157,7 +157,7 @@ public:
|
||||
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) {return (flags & e) == e;}
|
||||
bool operator [](Enum e) const {return (flags & e) == e;}
|
||||
operator int() const {return flags;}
|
||||
private:
|
||||
int flags;
|
||||
@@ -394,12 +394,15 @@ public:
|
||||
_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 & 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;}
|
||||
_CVector & insert(uint pos, const _CVector & t) {_stlc::insert(_stlc::begin() + pos, t.begin(), t.end()); return *this;}
|
||||
_CVector & operator <<(const Type & t) {_stlc::push_back(t); return *this;}
|
||||
_CVector & operator <<(const _CVector & t) {for (typename _stlc::const_iterator i = t.begin(); i != t.end(); i++) _stlc::push_back(*i); return *this;}
|
||||
bool operator ==(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return false; return true;}
|
||||
@@ -518,16 +521,19 @@ 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 Type, typename Key = int>
|
||||
class PIMap: public PISet<PIPair<Key, Type> > {
|
||||
typedef PIMap<Type, Key> _CMap;
|
||||
typedef PISet<PIPair<Key, Type> > _CSet;
|
||||
template<typename Key, typename Type>
|
||||
class 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 Type & value, const Key & key) {insert(value, key);}
|
||||
_CMap & insert(const Type & value, const Key & key) {_CSet::insert(PIPair<Key, Type>(key, value)); return *this;}
|
||||
Type value(Key key) const {for (typename _CMap::iterator i = _CMap::begin(); i != _CMap::end(); i++) if ((*i).first == key) return (*i).second; return Type();}
|
||||
Type operator[](Key key) const {return value(key);}
|
||||
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;}
|
||||
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_];}
|
||||
};
|
||||
|
||||
#endif // PICONTAINERS_H
|
||||
|
||||
216
picrc.h
Normal file
216
picrc.h
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Abstract input/output device
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef PICRC_H
|
||||
#define PICRC_H
|
||||
|
||||
#include "pistring.h"
|
||||
|
||||
template <int L>
|
||||
class 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];}
|
||||
uint_cl(uchar v) {for (int i = 0; i < L / 8; ++i) data_[i] = (i == 0 ? v : 0);}
|
||||
uint_cl(char v) {for (int i = 0; i < L / 8; ++i) data_[i] = (i == 0 ? v : 0);}
|
||||
uint_cl(ushort v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(short v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(uint v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(int v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(ulong v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(long v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(ullong v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(llong v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
|
||||
operator bool() {for (int i = 0; i < L / 8; ++i) if (data_[i] > 0) return true; return false;}
|
||||
operator char() {return (char)data_[0];}
|
||||
operator short() {short t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator int() {int t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator long() {long t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator llong() {llong t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator uchar() {return data_[0];}
|
||||
operator ushort() {ushort t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator uint() {uint t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator ulong() {ulong t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator ullong() {ullong t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
|
||||
uint_cl<L> operator +(const uint_cl<L> & v) {
|
||||
uint_cl<L> t;
|
||||
uint cv;
|
||||
bool ov = false;
|
||||
for (int i = 0; i < L / 8; ++i) {
|
||||
cv = v.data_[i] + data_[i];
|
||||
if (ov) ++cv;
|
||||
ov = cv > 255;
|
||||
t.data_[i] = ov ? cv - 256 : cv;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
uint_cl<L> operator &(const uint_cl<L> & v) const {uint_cl<L> t; for (int i = 0; i < L / 8; ++i) t.data_[i] = v.data_[i] & data_[i]; return t;}
|
||||
uint_cl<L> operator &(const uchar & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const ushort & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const uint & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const ulong & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const ullong & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const char & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const short & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const int & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const long & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const llong & v) const {return *this & uint_cl<L>(v);}
|
||||
|
||||
uint_cl<L> operator |(const uint_cl<L> & v) const {uint_cl<L> t; for (int i = 0; i < L / 8; ++i) t.data_[i] = v.data_[i] | data_[i]; return t;}
|
||||
uint_cl<L> operator |(const uchar & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const ushort & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const uint & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const ulong & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const ullong & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const char & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const short & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const int & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const long & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const llong & v) const {return *this | uint_cl<L>(v);}
|
||||
|
||||
uint_cl<L> operator ^(const uint_cl<L> & v) const {uint_cl<L> t; for (int i = 0; i < L / 8; ++i) t.data_[i] = v.data_[i] ^ data_[i]; return t;}
|
||||
uint_cl<L> operator ^(const uchar & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const ushort & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const uint & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const ulong & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const ullong & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const char & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const short & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const int & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const long & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const llong & v) const {return *this ^ uint_cl<L>(v);}
|
||||
|
||||
bool operator <(const uint_cl<L> & v) const {for (int i = 0; i < L / 8; ++i) {if (v.data_[i] > data_[i]) return true; if (v.data_[i] < data_[i]) return false;} return false;}
|
||||
bool operator <=(const uint_cl<L> & v) const {for (int i = 0; i < L / 8; ++i) {if (v.data_[i] > data_[i]) return true; if (v.data_[i] < data_[i]) return false;} return true;}
|
||||
bool operator >(const uint_cl<L> & v) const {for (int i = 0; i < L / 8; ++i) {if (v.data_[i] < data_[i]) return true; if (v.data_[i] > data_[i]) return false;} return false;}
|
||||
bool operator >=(const uint_cl<L> & v) const {for (int i = 0; i < L / 8; ++i) {if (v.data_[i] < data_[i]) return true; if (v.data_[i] > data_[i]) return false;} return true;}
|
||||
bool operator ==(const uint_cl<L> & v) const {for (int i = 0; i < L / 8; ++i) if (v.data_[i] != data_[i]) return false; return true;}
|
||||
bool operator !=(const uint_cl<L> & v) const {for (int i = 0; i < L / 8; ++i) if (v.data_[i] != data_[i]) return true; return false;}
|
||||
|
||||
uint_cl<L> operator >>(const int & c) const {
|
||||
uint_cl<L> t;
|
||||
int l = L - c;
|
||||
bool bit;
|
||||
if (l <= 0) return t;
|
||||
for (int i = 0; i < l; ++i) {
|
||||
bit = 1 & (data_[(i + c) / 8] >> ((i + c) % 8));
|
||||
if (bit) t.data_[i / 8] |= (1 << (i % 8));
|
||||
else t.data_[i / 8] &= ~(1 << (i % 8));
|
||||
}
|
||||
return t;
|
||||
}
|
||||
uint_cl<L> operator >>(const uint & c) const {return (*this << (int)c);}
|
||||
uint_cl<L> operator <<(const int & c) const {
|
||||
uint_cl<L> t;
|
||||
int l = L - c;
|
||||
bool bit;
|
||||
if (l <= 0) return t;
|
||||
for (int i = c; i < L; ++i) {
|
||||
bit = 1 & (data_[(i - c) / 8] >> ((i - c) % 8));
|
||||
if (bit) t.data_[i / 8] |= (1 << (i % 8));
|
||||
else t.data_[i / 8] &= ~(1 << (i % 8));
|
||||
}
|
||||
return t;
|
||||
}
|
||||
uint_cl<L> operator <<(const uint & c) const {return (*this >> (int)c);}
|
||||
|
||||
uint_cl<L> & inverse() const {for (int i = 0; i < L / 8; ++i) data_[i] = ~data_[i]; return *this;}
|
||||
uint_cl<L> inversed() const {uint_cl<L> t(*this); for (int i = 0; i < L / 8; ++i) t.data_[i] = ~t.data_[i]; return t;}
|
||||
uint_cl<L> reversed() const {
|
||||
uint_cl<L> t;
|
||||
bool bit;
|
||||
for (int i = 0; i < L; ++i) {
|
||||
bit = 1 & (data_[(L - i - 1) / 8] >> ((L - i - 1) % 8));
|
||||
if (bit) t.data_[i / 8] |= (1 << (i % 8));
|
||||
else t.data_[i / 8] &= ~(1 << (i % 8));
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
const uchar * data() const {return data_;}
|
||||
uchar * data() {return data_;}
|
||||
uint length() const {return L / 8;}
|
||||
|
||||
private:
|
||||
uchar data_[L / 8];
|
||||
|
||||
};
|
||||
|
||||
template <uint L>
|
||||
inline std::ostream & operator <<(std::ostream & s, const uint_cl<L> & v) {std::ios::fmtflags f = s.flags(); s << std::hex; for (uint i = 0; i < v.length(); ++i) {s << int(v.data()[i]); if (v.data()[i] < 0x10) s << '0'; s << ' ';} s.flags(f); return s;}
|
||||
|
||||
|
||||
template <uint L>
|
||||
class 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();}
|
||||
|
||||
void setInitial(const uint_cl<L> & v) {init_ = v;}
|
||||
void setOutXor(const uint_cl<L> & v) {out_ = v;}
|
||||
void setReversePolynome(bool yes) {reverse_poly = yes; initTable();}
|
||||
|
||||
void initTable() {
|
||||
uint_cl<L> tmp, pol = reverse_poly ? poly_.reversed() : poly_;
|
||||
//cout << std::hex << "poly " << (uint)uint_cl<L>(poly_) << " -> " << (uint)uint_cl<L>(pol) << endl;
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
tmp = uchar(i);
|
||||
for (int j = 0; j < 8; ++j)
|
||||
tmp = ((tmp & 1) ? ((tmp >> 1) ^ pol) : (tmp >> 1));
|
||||
table[i] = tmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint_cl<L> calculate(const void * data, int size) {
|
||||
uint_cl<L> crc = init_;
|
||||
uchar * data_ = (uchar * )data;
|
||||
//cout << "process " << size << endl;
|
||||
uchar nTemp;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
nTemp = data_[i] ^ uchar(crc);
|
||||
crc = crc >> 8;
|
||||
crc = crc ^ table[nTemp];
|
||||
}
|
||||
return crc ^ out_;
|
||||
|
||||
}
|
||||
uint_cl<L> calculate(const PIByteArray & d) {return calculate(d.data(), d.size());}
|
||||
uint_cl<L> calculate(const char * str) {string s(str); return calculate((void * )s.data(), s.size());}
|
||||
|
||||
private:
|
||||
uint_cl<L> table[256];
|
||||
uint_cl<L> poly_, init_, out_;
|
||||
bool reverse_poly;
|
||||
|
||||
};
|
||||
|
||||
typedef PICRC<32> CRC_32;
|
||||
typedef PICRC<24> CRC_24;
|
||||
typedef PICRC<16> CRC_16;
|
||||
typedef PICRC<8> CRC_8;
|
||||
|
||||
inline CRC_32 standardCRC_32() {return CRC_32(0x04C11DB7, true, 0xFFFFFFFF, 0xFFFFFFFF);}
|
||||
inline CRC_16 standardCRC_16() {return CRC_16(0x8005, true, 0x0, 0x0);}
|
||||
inline CRC_8 standardCRC_8() {return CRC_8(0xD5, true, 0x0, 0x0);}
|
||||
|
||||
#endif // CRC_H
|
||||
30
pidir.cpp
Executable file → Normal file
30
pidir.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Directory
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -78,17 +78,11 @@ PIDir & PIDir::cleanPath() {
|
||||
open();
|
||||
return *this;
|
||||
}
|
||||
path_.replaceAll(PIString(separator) + PIString(separator), PIString(separator));
|
||||
bool isAbs = isAbsolute();
|
||||
for (uint i = p.size() - 1; i > 0; --i) {
|
||||
if (p[i] == separator && p[i - 1] == separator) {
|
||||
p.cutLeft(i);
|
||||
isAbs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PIStringList l = PIString(p).split(separator);
|
||||
l.removeStrings(".");
|
||||
l.removeStrings("");
|
||||
l.removeAll(".");
|
||||
l.removeAll("");
|
||||
bool found = true;
|
||||
while (found) {
|
||||
found = false;
|
||||
@@ -118,20 +112,19 @@ PIDir & PIDir::cleanPath() {
|
||||
|
||||
PIDir & PIDir::cd(const PIString & path) {
|
||||
if (path_.size() == 0) return *this;
|
||||
if (path_[path_.size() - 1] == separator) path_ << path;
|
||||
else path_ << separator << path;
|
||||
if (path_[path_.size() - 1] != separator) path_ << separator;
|
||||
path_ << path;
|
||||
return cleanPath();
|
||||
}
|
||||
|
||||
|
||||
bool PIDir::mkDir(bool withParents) {
|
||||
PIDir d = cleanedPath();
|
||||
string p = d.path_;
|
||||
PIString tp;
|
||||
int ret;
|
||||
bool isAbs = isAbsolute();
|
||||
if (withParents) {
|
||||
PIStringList l = PIString(p).split(separator);
|
||||
PIStringList l = d.path_.split(separator);
|
||||
for (int i = l.size_s() - 1; i >= 0; --i) {
|
||||
if (i > 1) tp = PIStringList(l).remove(i, l.size_s() - i).join(separator);
|
||||
else {
|
||||
@@ -143,19 +136,18 @@ bool PIDir::mkDir(bool withParents) {
|
||||
for (int j = i + 1; j <= l.size_s(); ++j) {
|
||||
tp = PIStringList(l).remove(j, l.size_s() - j).join(separator);
|
||||
//cout << tp << endl;
|
||||
p = tp.stdString();
|
||||
ret = mkdir(p.c_str(), 16877);
|
||||
ret = mkdir(tp.data(), 16877);
|
||||
if (ret == 0) continue;
|
||||
printf("[PIDir] mkDir(\"%s\") error: %s\n", p.c_str(), strerror(errno));
|
||||
printf("[PIDir] mkDir(\"%s\") error: %s\n", d.path_.data(), strerror(errno));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
} else {
|
||||
ret = mkdir(p.c_str(), 16877);
|
||||
ret = mkdir(d.path_.data(), 16877);
|
||||
if (ret == 0) return true;
|
||||
printf("[PIDir] mkDir(\"%s\") error: %s\n", p.c_str(), strerror(errno));
|
||||
printf("[PIDir] mkDir(\"%s\") error: %s\n", d.path_.data(), strerror(errno));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
19
pidir.h
Executable file → Normal file
19
pidir.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Directory
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -21,6 +21,7 @@
|
||||
#define PIDIR_H
|
||||
|
||||
#include "pifile.h"
|
||||
#include "pistring.h"
|
||||
#ifndef WINDOWS
|
||||
#include <sys/dir.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -43,23 +44,23 @@ public:
|
||||
|
||||
bool isDir() const {return (mode & S_IFDIR);}
|
||||
bool isFile() const {return (mode & S_IFREG);}
|
||||
bool isSymLink() const {return (mode & S_IFLNK);}
|
||||
bool isBlkDevice() const {return (mode & S_IFBLK);}
|
||||
bool isChrDevice() const {return (mode & S_IFCHR);}
|
||||
bool isSymbolicLink() const {return (mode & S_IFLNK);}
|
||||
bool isBlockDevice() const {return (mode & S_IFBLK);}
|
||||
bool isCharacterDevice() const {return (mode & S_IFCHR);}
|
||||
bool isSocket() const {return (mode & S_IFSOCK);}
|
||||
};
|
||||
|
||||
inline const bool isExists() {return (dir_ != 0);}
|
||||
inline const bool isAbsolute() {if (path_.size() == 0) return false; return (path_[0] == separator);}
|
||||
inline PIString path() {return PIString(path_);}
|
||||
const bool isExists() {return (dir_ != 0);}
|
||||
const bool isAbsolute() {if (path_.size() == 0) return false; return (path_[0] == separator);}
|
||||
PIString path() {return PIString(path_);}
|
||||
PIDir & cleanPath();
|
||||
inline PIDir cleanedPath() {PIDir d(path_); d.cleanPath(); return d;}
|
||||
PIDir cleanedPath() {PIDir d(path_); d.cleanPath(); return d;}
|
||||
PIString absolutePath();
|
||||
bool mkDir(bool withParents = true);
|
||||
PIVector<DirEntry> entries();
|
||||
|
||||
PIDir & cd(const PIString & path);
|
||||
inline PIDir & up() {return cd("..");}
|
||||
PIDir & up() {return cd("..");}
|
||||
|
||||
bool operator ==(const PIDir & d) const;
|
||||
|
||||
|
||||
351
piethernet.cpp
Executable file → Normal file
351
piethernet.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Ethernet, UDP
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -27,16 +27,13 @@ PIEthernet::PIEthernet(void * data, ReadRetFunc slot): PIIODevice("", ReadWrite)
|
||||
ret_data_ = data;
|
||||
ip_ = ip_s = "";
|
||||
port_ = port_s = 0;
|
||||
sock = -1;
|
||||
sock = sock_s = -1;
|
||||
ret_func_ = slot;
|
||||
connected_ = false;
|
||||
params = PIEthernet::ReuseAddress;
|
||||
server_thread_.setData(this);
|
||||
setThreadedReadBufferSize(65536);
|
||||
#ifdef WINDOWS
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
#endif
|
||||
init();
|
||||
if (type_ != UDP) init();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,16 +44,13 @@ PIEthernet::PIEthernet(PIEthernet::Type type, void * data, ReadRetFunc slot): PI
|
||||
ret_data_ = data;
|
||||
ip_ = ip_s = "";
|
||||
port_ = port_s = 0;
|
||||
sock = -1;
|
||||
sock = sock_s = -1;
|
||||
ret_func_ = slot;
|
||||
connected_ = false;
|
||||
params = PIEthernet::ReuseAddress;
|
||||
server_thread_.setData(this);
|
||||
setThreadedReadBufferSize(65536);
|
||||
#ifdef WINDOWS
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
#endif
|
||||
init();
|
||||
if (type_ != UDP) init();
|
||||
}
|
||||
|
||||
|
||||
@@ -66,13 +60,11 @@ PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
|
||||
type_ = TCP_Client;
|
||||
parseAddress(ip_port, &ip_s, &port_s);
|
||||
sock = sock_;
|
||||
sock_s = -1;
|
||||
server_thread_.setData(this);
|
||||
params = PIEthernet::ReuseAddress;
|
||||
init_ = opened_ = connected_ = true;
|
||||
setThreadedReadBufferSize(65536);
|
||||
#ifdef WINDOWS
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -80,9 +72,6 @@ PIEthernet::~PIEthernet() {
|
||||
piMonitor.ethernets--;
|
||||
if (server_thread_.isRunning()) server_thread_.terminate();
|
||||
closeSocket(sock);
|
||||
#ifdef WINDOWS
|
||||
WSACleanup();
|
||||
#endif
|
||||
//if (buffer_ != 0) delete buffer_;
|
||||
//buffer_ = 0;
|
||||
}
|
||||
@@ -91,15 +80,29 @@ PIEthernet::~PIEthernet() {
|
||||
bool PIEthernet::init() {
|
||||
//cout << "init " << type_ << endl;
|
||||
closeSocket(sock);
|
||||
int st = 0, so = 1;
|
||||
int st = 0;
|
||||
#ifdef WINDOWS
|
||||
int flags = WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF;
|
||||
#else
|
||||
int so = 1;
|
||||
#endif
|
||||
if (type_ == UDP) st = SOCK_DGRAM;
|
||||
if (type_ == TCP_Client || type_ == TCP_Server) st = SOCK_STREAM;
|
||||
sock = socket(PF_INET, st, 0);
|
||||
else st = SOCK_STREAM;
|
||||
#ifdef WINDOWS
|
||||
if (params[ReuseAddress]) flags |= WSA_FLAG_OVERLAPPED;
|
||||
sock = WSASocket(AF_INET, st, type_ == UDP ? IPPROTO_UDP : IPPROTO_TCP, NULL, 0, flags);
|
||||
#else
|
||||
sock = socket(AF_INET, st, type_ == UDP ? IPPROTO_UDP : IPPROTO_TCP);
|
||||
#endif
|
||||
if (sock == -1) {
|
||||
piCout << "[PIEthernet] Cant`t create socket, " << errorString() << endl;
|
||||
piCout << "[PIEthernet] Cant`t create socket, " << EthErrorString() << endl;
|
||||
return false;
|
||||
}
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &so, sizeof(so));
|
||||
#ifndef WINDOWS
|
||||
if (params[PIEthernet::ReuseAddress]) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &so, sizeof(so));
|
||||
if (params[PIEthernet::Broadcast]) setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &so, sizeof(so));
|
||||
#endif
|
||||
//cout << "inited " << sock << ": bc = " << params << endl;
|
||||
//fcntl(sock, F_SETFL, 0/*O_NONBLOCK*/);
|
||||
return true;
|
||||
}
|
||||
@@ -114,15 +117,24 @@ void PIEthernet::parseAddress(const PIString & ipp, PIString * ip, int * port) {
|
||||
bool PIEthernet::openDevice() {
|
||||
if (connected_) return true;
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
//cout << " bind to " << path_ << " ..." <<endl;
|
||||
if (sock == -1 || path_.isEmpty()) return false;
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
//cout << " bind to " << sock << ": " << (params[PIEthernet::Broadcast] ? "0.0.0.0" : path_) << ": " << port_ << " ..." <<endl;
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
addr_.sin_family = AF_INET;
|
||||
addr_.sin_port = htons(port_);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||
addr_.sin_family = PF_INET;
|
||||
//cout << "openDevice\n";
|
||||
if (bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) {
|
||||
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << errorString() << endl;
|
||||
if (params[PIEthernet::Broadcast]) addr_.sin_addr.s_addr = INADDR_ANY;
|
||||
else addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||
#ifdef QNX
|
||||
addr_.sin_len = sizeof(addr_);
|
||||
#endif
|
||||
int tries = 0;
|
||||
while ((bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) && (tries < 10)) {
|
||||
init();
|
||||
tries++;
|
||||
}
|
||||
if (tries == 10) {
|
||||
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << EthErrorString() << endl;
|
||||
return false;
|
||||
}
|
||||
//cout << "!" << endl;
|
||||
@@ -143,15 +155,89 @@ bool PIEthernet::closeDevice() {
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::connect(PIString ip, int port) {
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
addr_.sin_family = AF_INET;
|
||||
addr_.sin_port = htons(port_);
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
leafs.insert(group, ret);
|
||||
#else
|
||||
# ifndef QNX
|
||||
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());
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
SOCKET s = leafs[group];
|
||||
if (s != SOCKET()) {
|
||||
leafs.erase(group);
|
||||
closesocket(s);
|
||||
}
|
||||
#else
|
||||
# ifndef QNX
|
||||
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());
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::connect(const PIString & ip, int port) {
|
||||
if (sock == -1) return false;
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
addr_.sin_port = htons(port);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip.data());
|
||||
addr_.sin_family = PF_INET;
|
||||
addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
addr_.sin_len = sizeof(addr_);
|
||||
#endif
|
||||
//piCout << "[PIEthernet] connect to " << ip << ":" << port << endl;
|
||||
connected_ = (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) == 0);
|
||||
if (!connected_)
|
||||
piCout << "[PIEthernet] Cant`t connect to " << ip << ":" << port << ", " << errorString() << endl;
|
||||
piCout << "[PIEthernet] Cant`t connect to " << ip << ":" << port << ", " << EthErrorString() << endl;
|
||||
opened_ = connected_;
|
||||
return connected_;
|
||||
}
|
||||
@@ -161,15 +247,24 @@ bool PIEthernet::listen() {
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
addr_.sin_port = htons(port_);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||
addr_.sin_family = PF_INET;
|
||||
if (bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) {
|
||||
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << errorString() << endl;
|
||||
addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
addr_.sin_len = sizeof(addr_);
|
||||
#endif
|
||||
int tries = 0;
|
||||
while ((bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) && (tries < 10)) {
|
||||
init();
|
||||
tries++;
|
||||
}
|
||||
if (tries == 10) {
|
||||
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << EthErrorString() << endl;
|
||||
return false;
|
||||
}
|
||||
if (::listen(sock, 64) == -1) {
|
||||
piCout << "[PIEthernet] Can`t listen on "<< ip_ << ":" << port_ << ", " << errorString() << endl;
|
||||
piCout << "[PIEthernet] Can`t listen on "<< ip_ << ":" << port_ << ", " << EthErrorString() << endl;
|
||||
return false;
|
||||
}
|
||||
//piCout << "[PIEthernet] listen on " << ip_ << ":" << port_ << endl;
|
||||
@@ -181,11 +276,30 @@ bool PIEthernet::listen() {
|
||||
int PIEthernet::read(void * read_to, int max_size) {
|
||||
//cout << "read " << sock << endl;
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return -1;
|
||||
if (sock == -1 || read_to == 0) return -1;
|
||||
int rs = 0, s = 0;
|
||||
sockaddr_in client_addr;
|
||||
socklen_t slen = sizeof(client_addr);
|
||||
//piCout << "[PIEthernet] read from " << ip_ << ":" << port_ << endl;
|
||||
switch (type_) {
|
||||
case TCP_SingleTCP:
|
||||
::listen(sock, 64);
|
||||
s = accept(sock, (sockaddr * )&client_addr, &slen);
|
||||
if (s == -1) {
|
||||
piCout << "[PIEthernet] Cant`t accept new connection, " << EthErrorString() << endl;
|
||||
return -1;
|
||||
}
|
||||
rs = recv(s, (char * )read_to, max_size, 0);
|
||||
closeSocket(s);
|
||||
return rs;
|
||||
case UDP: case TCP_Client:
|
||||
return recv(sock, read_to, max_size, 0);
|
||||
#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);
|
||||
return rs;
|
||||
//return ::read(sock, read_to, max_size);
|
||||
default: break;
|
||||
//return ::read(sock, (char * )read_to, max_size);
|
||||
@@ -201,12 +315,34 @@ int PIEthernet::write(const void * data, int max_size) {
|
||||
return -1;
|
||||
}
|
||||
//piCout << "[PIEthernet] sending to " << ip_s << ":" << port_s << " " << max_size << " bytes" << endl;
|
||||
int ret = 0;
|
||||
switch (type_) {
|
||||
case TCP_SingleTCP:
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
addr_.sin_port = htons(port_s);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip_s.data());
|
||||
addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
addr_.sin_len = sizeof(addr_);
|
||||
#endif
|
||||
if (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) != 0) {
|
||||
piCout << "[PIEthernet] Cant`t connect to " << ip_s << ":" << port_s << ", " << EthErrorString() << endl;
|
||||
return -1;
|
||||
}
|
||||
ret = ::write(sock, data, max_size);
|
||||
closeSocket(sock);
|
||||
init();
|
||||
return ret;
|
||||
case UDP:
|
||||
saddr_.sin_port = htons(port_s);
|
||||
saddr_.sin_addr.s_addr = inet_addr(ip_s.data());
|
||||
saddr_.sin_family = PF_INET;
|
||||
if (params[PIEthernet::Broadcast]) saddr_.sin_addr.s_addr = INADDR_BROADCAST;
|
||||
else saddr_.sin_addr.s_addr = inet_addr(ip_s.data());
|
||||
saddr_.sin_family = AF_INET;
|
||||
#ifdef WINDOWS
|
||||
return sendto(sock, (const char * )data, max_size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
||||
#else
|
||||
return sendto(sock, data, max_size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
||||
#endif
|
||||
case TCP_Client:
|
||||
return ::write(sock, data, max_size);
|
||||
default: break;
|
||||
@@ -219,18 +355,139 @@ void PIEthernet::server_func(void * eth) {
|
||||
PIEthernet * ce = (PIEthernet * )eth;
|
||||
sockaddr_in client_addr;
|
||||
socklen_t slen = sizeof(client_addr);
|
||||
int s;
|
||||
s = accept(ce->sock, (sockaddr * )&client_addr, &slen);
|
||||
int s = accept(ce->sock, (sockaddr * )&client_addr, &slen);
|
||||
if (s == -1) {
|
||||
piCout << "[PIEthernet] Cant`t accept new connection, " << errorString() << endl;
|
||||
piCout << "[PIEthernet] Cant`t accept new connection, " << EthErrorString() << endl;
|
||||
return;
|
||||
}
|
||||
PIString ip(inet_ntoa(client_addr.sin_addr));
|
||||
ip += ":" + PIString::fromNumber(htons(client_addr.sin_port));
|
||||
ce->clients_ << new PIEthernet(s, ip);
|
||||
cout << "connected " << ip << endl;
|
||||
//cout << "connected " << ip << endl;
|
||||
//char d[256];
|
||||
//cout << " recv " << recv(s, d, 256, 0) << endl;
|
||||
//cout << recv(ce->clients_.back()->sock, d, 256, 0) << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
PIStringList PIEthernet::interfaces() {
|
||||
#ifdef WINDOWS
|
||||
piCout << "[PIEthernet] Not implemented on Windows, use \"PIEthernet::allAddresses\" instead" << endl;
|
||||
return PIStringList();
|
||||
#else
|
||||
# ifdef QNX
|
||||
PIStringList il, sl;
|
||||
/*struct if_nameindex * ni = if_nameindex();
|
||||
for (int i = 0; ; ++i) {
|
||||
if (ni[i].if_name == 0 || ni[i].if_index == 0) break;
|
||||
sl << PIString(ni[i].if_name);
|
||||
}
|
||||
if_freenameindex(ni);*/
|
||||
PIProcess proc;
|
||||
proc.setGrabOutput(true);
|
||||
proc.exec(ifconfigPath.c_str(), "-l");
|
||||
if (!proc.waitForFinish(1000)) return sl;
|
||||
PIString out(proc.readOutput());
|
||||
il = out.split(" ");
|
||||
il.removeAll("");
|
||||
piForeachC (PIString & i, il) {
|
||||
proc.exec(ifconfigPath.c_str(), i);
|
||||
if (!proc.waitForFinish(1000)) return il;
|
||||
sl << i.trimmed();
|
||||
out = proc.readOutput();
|
||||
int al = out.length();
|
||||
al = (al - out.replaceAll("alias", "").length()) / 5;
|
||||
for (int j = 0; j < al; ++j)
|
||||
sl << i.trimmed() + ":" + PIString::fromNumber(j);
|
||||
}
|
||||
//cout << out;
|
||||
//cout << sl << endl;
|
||||
return sl;
|
||||
# else
|
||||
PIStringList sl;
|
||||
/*struct if_nameindex * ni = if_nameindex();
|
||||
for (int i = 0; ; ++i) {
|
||||
if (ni[i].if_name == 0 || ni[i].if_index == 0) break;
|
||||
sl << PIString(ni[i].if_name);
|
||||
}
|
||||
if_freenameindex(ni);*/
|
||||
PIProcess proc;
|
||||
proc.setGrabOutput(true);
|
||||
proc.exec(ifconfigPath.c_str(), "-s");
|
||||
if (!proc.waitForFinish(1000)) return sl;
|
||||
PIString out(proc.readOutput());
|
||||
//cout << out << endl;
|
||||
out.cutLeft(out.find('\n') + 1);
|
||||
while (!out.isEmpty()) {
|
||||
sl << out.left(out.find(' '));
|
||||
out.cutLeft(out.find('\n') + 1);
|
||||
}
|
||||
//cout << sl << endl;
|
||||
return sl;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PIString PIEthernet::interfaceAddress(const PIString & interface_) {
|
||||
#ifdef WINDOWS
|
||||
piCout << "[PIEthernet] Not implemented on Windows, use \"PIEthernet::allAddresses\" instead" << endl;
|
||||
return PIString();
|
||||
#else
|
||||
struct ifreq ifr;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strcpy(ifr.ifr_name, interface_.data());
|
||||
int s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
ioctl(s, SIOCGIFADDR, &ifr);
|
||||
::close(s);
|
||||
struct sockaddr_in * sa = (struct sockaddr_in * )&ifr.ifr_addr;
|
||||
return PIString(inet_ntoa(sa->sin_addr));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
PIStringList PIEthernet::allAddresses() {
|
||||
#ifdef WINDOWS
|
||||
PIStringList al;
|
||||
PIString ca;
|
||||
PIP_ADAPTER_INFO pAdapterInfo, pAdapter = 0;
|
||||
int ret = 0;
|
||||
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;
|
||||
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;
|
||||
return PIStringList();
|
||||
}
|
||||
}
|
||||
if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
|
||||
pAdapter = pAdapterInfo;
|
||||
while (pAdapter) {
|
||||
/*if (pAdapter->Type != MIB_IF_TYPE_ETHERNET && pAdapter->Type != MIB_IF_TYPE_LOOPBACK) {
|
||||
pAdapter = pAdapter->Next;
|
||||
continue;
|
||||
}*/
|
||||
ca = PIString(pAdapter->IpAddressList.IpAddress.String);
|
||||
if (ca != "0.0.0.0") al << ca;
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
} else
|
||||
piCout << "[PIEthernet] GetAdaptersInfo failed with error: " << ret << endl;
|
||||
if (pAdapterInfo)
|
||||
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
||||
return al;
|
||||
#else
|
||||
PIStringList il = interfaces(), al;
|
||||
piForeachC (PIString & i, il)
|
||||
al << interfaceAddress(i);
|
||||
return al;
|
||||
#endif
|
||||
}
|
||||
|
||||
82
piethernet.h
Executable file → Normal file
82
piethernet.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Ethernet, UDP
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -22,61 +22,74 @@
|
||||
|
||||
#include "pitimer.h"
|
||||
#include "piiodevice.h"
|
||||
#ifndef WINDOWS
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/socket.h>
|
||||
# include <fcntl.h>
|
||||
#else
|
||||
# ifdef CC_VC
|
||||
# include <winsock.h>
|
||||
# define SHUT_RDWR 2
|
||||
# else
|
||||
# include <winsock2.h>
|
||||
# define SHUT_RDWR SD_BOTH
|
||||
# endif
|
||||
#endif
|
||||
#include "piprocess.h"
|
||||
|
||||
class PIEthernet: public PIIODevice
|
||||
{
|
||||
friend class PIPeer;
|
||||
public:
|
||||
// slot is any function format "bool <func>(void*, uchar*, int)"
|
||||
PIEthernet(void * data, ReadRetFunc slot);
|
||||
|
||||
enum Type {UDP, TCP_Client, TCP_Server};
|
||||
enum Type {UDP, TCP_Client, TCP_Server, TCP_SingleTCP};
|
||||
enum Parameters {ReuseAddress = 0x1, Broadcast = 0x2};
|
||||
|
||||
PIEthernet(Type type = UDP, void * data = 0, ReadRetFunc slot = 0);
|
||||
~PIEthernet();
|
||||
|
||||
void setReadAddress(PIString ip, int port) {path_ = ip + ":" + PIString::fromNumber(port);}
|
||||
void setReadAddress(PIString ip_port) {path_ = ip_port;}
|
||||
void setSendAddress(PIString ip, int port) {ip_s = ip; port_s = port;}
|
||||
void setSendAddress(PIString ip_port) {parseAddress(ip_port, &ip_s, &port_s);}
|
||||
void setReadAddress(const PIString & ip, int port) {path_ = ip + ":" + PIString::fromNumber(port);}
|
||||
void setReadAddress(const PIString & ip_port) {path_ = ip_port;}
|
||||
void setReadIP(const PIString & ip) {parseAddress(path_, &ip_, &port_); path_ = ip + ":" + PIString::fromNumber(port_);}
|
||||
void setReadPort(int port) {parseAddress(path_, &ip_, &port_); path_ = ip_ + ":" + PIString::fromNumber(port);}
|
||||
void setSendAddress(const PIString & ip, int port) {ip_s = ip; port_s = port;}
|
||||
void setSendAddress(const PIString & ip_port) {parseAddress(ip_port, &ip_s, &port_s);}
|
||||
void setSendIP(const PIString & ip) {ip_s = ip;}
|
||||
void setSendPort(int port) {port_s = port;}
|
||||
PIString readIP() {parseAddress(path_, &ip_, &port_); return ip_;}
|
||||
int readPort() {parseAddress(path_, &ip_, &port_); return port_;}
|
||||
PIString sendIP() {return ip_s;}
|
||||
int sendPort() {return port_s;}
|
||||
|
||||
void setParameters(PIFlags<PIEthernet::Parameters> parameters_) {params = parameters_;}
|
||||
void setParameter(PIEthernet::Parameters parameter, bool on = true) {params.setFlag(parameter, on);}
|
||||
bool isParameterSet(PIEthernet::Parameters parameter) const {return params[parameter];}
|
||||
PIFlags<PIEthernet::Parameters> parameters() const {return params;}
|
||||
|
||||
//PIByteArray macAddress() {if (!init_) init(); struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); memcpy(ifr.ifr_name, "eth0", 5); ioctl(sock, SIOCSIFHWADDR, &ifr); return PIByteArray(&ifr.ifr_hwaddr.sa_data, 6);}
|
||||
Type type() const {return type_;}
|
||||
|
||||
bool connect(PIString ip, int port);
|
||||
bool connect(PIString ip_port) {parseAddress(ip_port, &ip_c, &port_c); return connect(ip_c, port_c);}
|
||||
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 isConnected() const {return connected_;}
|
||||
|
||||
bool listen();
|
||||
bool listen(PIString ip, int port) {setReadAddress(ip, port); return listen();}
|
||||
bool listen(PIString ip_port) {setReadAddress(ip_port); return listen();}
|
||||
bool listen(const PIString & ip, int port) {setReadAddress(ip, port); return listen();}
|
||||
bool listen(const PIString & ip_port) {setReadAddress(ip_port); return listen();}
|
||||
|
||||
PIEthernet * client(int index) {return clients_[index];}
|
||||
int clientsCount() const {return clients_.size_s();}
|
||||
PIVector<PIEthernet * > clients() {return clients_;}
|
||||
|
||||
bool send(PIString ip, int port, const void * data, int size) {ip_s = ip; port_s = port; return send(data, size);}
|
||||
bool send(PIString ip_port, const void * data, int size) {parseAddress(ip_port, &ip_s, &port_s); return send(data, size);}
|
||||
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);}
|
||||
|
||||
int read(void * read_to, int max_size);
|
||||
int write(const void * data, int max_size);
|
||||
int write(const PIByteArray & data) {return write(data.data(), data.size_s());}
|
||||
|
||||
static PIStringList interfaces();
|
||||
static PIString interfaceAddress(const PIString & interface_);
|
||||
static PIStringList allAddresses();
|
||||
|
||||
protected:
|
||||
PIEthernet(int sock, PIString ip_port);
|
||||
|
||||
virtual void received(void * data, int size) {;}
|
||||
|
||||
bool init();
|
||||
bool openDevice();
|
||||
bool closeDevice();
|
||||
@@ -87,17 +100,32 @@ protected:
|
||||
#endif
|
||||
void parseAddress(const PIString & ipp, PIString * ip, int * port);
|
||||
|
||||
int sock, port_, port_s, port_c, wrote;
|
||||
int sock, sock_s, port_, port_s, port_c, wrote;
|
||||
bool connected_;
|
||||
sockaddr_in addr_, saddr_;
|
||||
PIString ip_, ip_s, ip_c;
|
||||
PIThread server_thread_;
|
||||
PIVector<PIEthernet * > clients_;
|
||||
#ifdef WINDOWS
|
||||
PIMap<PIString, SOCKET> leafs;
|
||||
#endif
|
||||
PIFlags<PIEthernet::Parameters> params;
|
||||
Type type_;
|
||||
|
||||
private:
|
||||
static void server_func(void * eth);
|
||||
|
||||
static std::string EthErrorString() {
|
||||
#ifdef WINDOWS
|
||||
char * msg;
|
||||
int err = WSAGetLastError();
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL);
|
||||
return "code " + itos(err) + " - " + string(msg);
|
||||
#else
|
||||
return errorString();
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // PIETHERNET_H
|
||||
|
||||
2
pievaluator.cpp
Executable file → Normal file
2
pievaluator.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Evaluator designed for stream computing
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pievaluator.h
Executable file → Normal file
2
pievaluator.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Evaluator designed for stream computing
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
24
pifile.cpp
Executable file → Normal file
24
pifile.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
File
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -33,21 +33,20 @@ bool PIFile::openDevice() {
|
||||
|
||||
bool PIFile::closeDevice() {
|
||||
if (!opened_) return true;
|
||||
return (fclose(fd) != 0);
|
||||
return (fclose(fd) == 0);
|
||||
}
|
||||
|
||||
|
||||
PIString PIFile::readLine() {
|
||||
PIString str;
|
||||
if (!opened_) return str;
|
||||
char cc;
|
||||
int cp = 0;
|
||||
int cc, cp = 0;
|
||||
while (!isEnd() && cp < 4095) {
|
||||
cc = char(fgetc(fd));
|
||||
if (cc == '\n') break;
|
||||
str.push_back(cc);
|
||||
cc = fgetc(fd);
|
||||
if (char(cc) == '\n' || cc == EOF) break;
|
||||
str.push_back(char(cc));
|
||||
}
|
||||
//cout << "readline: " << buff << endl;
|
||||
//cout << "readline: " << str << endl;
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -66,17 +65,20 @@ llong PIFile::readAll(void * data) {
|
||||
|
||||
|
||||
PIByteArray PIFile::readAll(bool forceRead) {
|
||||
llong cp = pos(), s = size();
|
||||
PIByteArray a;
|
||||
if (s < 0) {
|
||||
if (!forceRead) return a;
|
||||
llong cp = pos();
|
||||
if (forceRead) {
|
||||
seekToBegin();
|
||||
while (!isEnd())
|
||||
a.push_back(readChar());
|
||||
seek(cp);
|
||||
return a;
|
||||
}
|
||||
llong s = size();
|
||||
if (s < 0) return a;
|
||||
a.resize(s);
|
||||
s = readAll(a.data());
|
||||
seek(cp);
|
||||
if (s >= 0) a.resize(s);
|
||||
return a;
|
||||
}
|
||||
|
||||
57
pifile.h
Executable file → Normal file
57
pifile.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
File
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -23,10 +23,14 @@
|
||||
#include "piiodevice.h"
|
||||
#include <cstdio>
|
||||
|
||||
/// handlers:
|
||||
/// void clear()
|
||||
/// void resize(llong new_size, char fill = 0)
|
||||
/// void remove()
|
||||
class PIFile: public PIIODevice
|
||||
{
|
||||
public:
|
||||
PIFile(const PIString & path = PIString(), DeviceMode type = ReadWrite): PIIODevice(path, type) {openDevice();}
|
||||
PIFile(const PIString & path = PIString(), DeviceMode type = ReadWrite): PIIODevice(path, type) {setPrecision(5); openDevice();}
|
||||
|
||||
//PIFile & operator =(const PIFile & f) {path_ = f.path_; type_ = f.type_; return *this;}
|
||||
|
||||
@@ -51,6 +55,9 @@ public:
|
||||
bool isEnd() {return (feof(fd) || ferror(fd));}
|
||||
bool isEmpty() {return (size() <= 0);}
|
||||
|
||||
int precision() const {return prec;}
|
||||
void setPrecision(int prec_) {prec = prec_; prec_str = "." + itos(prec_);}
|
||||
|
||||
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;}
|
||||
@@ -59,10 +66,12 @@ public:
|
||||
PIFile & writeBinary(const short v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const int v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const long v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const llong v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const uchar v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const ushort v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const uint v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const ulong v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const ullong v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const float v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const double v) {write(&v, sizeof(v)); return *this;}
|
||||
|
||||
@@ -70,26 +79,30 @@ public:
|
||||
//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;}
|
||||
PIFile & operator <<(short v) {if (!isWriteable()) return *this; fprintf(fd, "%hd", v); return *this;}
|
||||
PIFile & operator <<(int v) {if (!isWriteable()) return *this; fprintf(fd, "%d", v); return *this;}
|
||||
PIFile & operator <<(long v) {if (!isWriteable()) return *this; fprintf(fd, "%ld", v); return *this;}
|
||||
PIFile & operator <<(uchar v) {if (!isWriteable()) return *this; fprintf(fd, "%c", v); return *this;}
|
||||
PIFile & operator <<(ushort v) {if (!isWriteable()) return *this; fprintf(fd, "%hd", v); return *this;}
|
||||
PIFile & operator <<(uint v) {if (!isWriteable()) return *this; fprintf(fd, "%d", v); return *this;}
|
||||
PIFile & operator <<(ulong v) {if (!isWriteable()) return *this; fprintf(fd, "%ld", v); return *this;}
|
||||
PIFile & operator <<(float v) {if (!isWriteable()) return *this; fprintf(fd, "%f", v); return *this;}
|
||||
PIFile & operator <<(double v) {if (!isWriteable()) return *this; fprintf(fd, "%lf", v); return *this;}
|
||||
PIFile & operator <<(short v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%hd", v); return *this;}
|
||||
PIFile & operator <<(int v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%d", v); return *this;}
|
||||
PIFile & operator <<(long v) {if (!isWriteable()) return *this; ret = fprintf(fd, "%ld", v); return *this;}
|
||||
PIFile & operator <<(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 <<(float v) {if (!isWriteable()) return *this; ret = fprintf(fd, ("%" + prec_str + "f").c_str(), v); return *this;}
|
||||
PIFile & operator <<(double v) {if (!isWriteable()) return *this; ret = fprintf(fd, ("%" + prec_str + "lf").c_str(), v); return *this;}
|
||||
|
||||
PIFile & operator >>(char & v) {if (!isWriteable()) return *this; fscanf(fd, "%hhn", &v); return *this;}
|
||||
PIFile & operator >>(short & v) {if (!isWriteable()) return *this; fscanf(fd, "%hn", &v); return *this;}
|
||||
PIFile & operator >>(int & v) {if (!isWriteable()) return *this; fscanf(fd, "%n", &v); return *this;}
|
||||
PIFile & operator >>(long & v) {if (!isWriteable()) return *this; fscanf(fd, "%ln", &v); return *this;}
|
||||
PIFile & operator >>(uchar & v) {if (!isWriteable()) return *this; fscanf(fd, "%hhn", &v); return *this;}
|
||||
PIFile & operator >>(ushort & v) {if (!isWriteable()) return *this; fscanf(fd, "%hn", &v); return *this;}
|
||||
PIFile & operator >>(uint & v) {if (!isWriteable()) return *this; fscanf(fd, "%n", &v); return *this;}
|
||||
PIFile & operator >>(ulong & v) {if (!isWriteable()) return *this; fscanf(fd, "%ln", &v); return *this;}
|
||||
PIFile & operator >>(float & v) {if (!isWriteable()) return *this; fscanf(fd, "%f", &v); return *this;}
|
||||
PIFile & operator >>(double & v) {if (!isWriteable()) return *this; fscanf(fd, "%lf", &v); return *this;}
|
||||
PIFile & operator >>(char & v) {if (!isWriteable()) return *this; ret = fscanf(fd, "%hhn", &v); return *this;}
|
||||
PIFile & operator >>(short & v) {if (!isWriteable()) return *this; ret = fscanf(fd, "%hn", &v); return *this;}
|
||||
PIFile & operator >>(int & v) {if (!isWriteable()) return *this; ret = fscanf(fd, "%n", &v); return *this;}
|
||||
PIFile & operator >>(long & v) {if (!isWriteable()) return *this; ret = fscanf(fd, "%ln", &v); return *this;}
|
||||
PIFile & operator >>(llong & v) {if (!isWriteable()) return *this; ret = fscanf(fd, "%lln", &v); return *this;}
|
||||
PIFile & operator >>(uchar & v) {if (!isWriteable()) return *this; ret = fscanf(fd, "%hhn", &v); return *this;}
|
||||
PIFile & operator >>(ushort & v) {if (!isWriteable()) return *this; ret = fscanf(fd, "%hn", &v); return *this;}
|
||||
PIFile & operator >>(uint & v) {if (!isWriteable()) return *this; ret = fscanf(fd, "%n", &v); return *this;}
|
||||
PIFile & operator >>(ulong & v) {if (!isWriteable()) return *this; ret = fscanf(fd, "%ln", &v); return *this;}
|
||||
PIFile & operator >>(ullong & v) {if (!isWriteable()) return *this; ret = fscanf(fd, "%lln", &v); return *this;}
|
||||
PIFile & operator >>(float & v) {if (!isWriteable()) return *this; ret = fscanf(fd, "%f", &v); return *this;}
|
||||
PIFile & operator >>(double & v) {if (!isWriteable()) return *this; ret = fscanf(fd, "%lf", &v); return *this;}
|
||||
|
||||
static PIFile openTemporary(PIIODevice::DeviceMode mode = PIIODevice::ReadWrite) {return PIFile(PIString(tmpnam(0)), mode);}
|
||||
static bool isExists(const PIString & path);
|
||||
@@ -103,6 +116,8 @@ private:
|
||||
PIString strType(const PIIODevice::DeviceMode type) {switch (type) {case PIIODevice::ReadOnly: return "rb"; case WriteOnly: return "ab"; case ReadWrite: return "a+b";} return "rb";}
|
||||
|
||||
FILE * fd;
|
||||
int ret, prec;
|
||||
string prec_str;
|
||||
|
||||
};
|
||||
|
||||
|
||||
2
pigeometry.h
Executable file → Normal file
2
pigeometry.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Geometry
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Global includes
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -21,3 +21,7 @@
|
||||
|
||||
bool isPIInit = false;
|
||||
bool piDebug = true;
|
||||
string ifconfigPath;
|
||||
|
||||
PIInit piInit;
|
||||
lconv * currentLocale = std::localeconv();
|
||||
|
||||
183
piincludes.h
Executable file → Normal file
183
piincludes.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Global includes
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,11 +20,11 @@
|
||||
#ifndef PIINCLUDES_H
|
||||
#define PIINCLUDES_H
|
||||
|
||||
#define PIP_VERSION 0x000200
|
||||
#define PIP_VERSION 0x000206
|
||||
#define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16
|
||||
#define PIP_VERSION_MINOR (PIP_VERSION & 0xFF00) >> 8
|
||||
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF
|
||||
#define PIP_VERSION_SUFFIX ""
|
||||
#define PIP_VERSION_SUFFIX "_beta"
|
||||
|
||||
#if WIN32 || WIN64 || _WIN32 || _WIN64 || __WIN32__ || __WIN64__
|
||||
# define WINDOWS
|
||||
@@ -32,15 +32,33 @@
|
||||
#if __QNX__ || __QNXNTO__
|
||||
# define QNX
|
||||
#endif
|
||||
#if __FreeBSD__
|
||||
# define FREE_BSD
|
||||
#endif
|
||||
#if __APPLE__ || __MACH__
|
||||
# define MAC_OS
|
||||
#endif
|
||||
#ifndef WINDOWS
|
||||
# ifndef QNX
|
||||
# ifndef FREE_BSD
|
||||
# ifndef MAC_OS
|
||||
# define LINUX
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if __GNUC__
|
||||
# define CC_GCC
|
||||
# define CC_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
|
||||
# if CC_GCC_VERSION > 0x025F // > 2.95
|
||||
# ifdef LINUX
|
||||
# define HAS_LOCALE
|
||||
# endif
|
||||
# endif
|
||||
#elif _MSC_VER
|
||||
# define CC_VC
|
||||
#else
|
||||
# define CC_OTHER
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS
|
||||
@@ -70,6 +88,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <cctype>
|
||||
#include <ctime>
|
||||
#include <csignal>
|
||||
//#include <signal.h>
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
@@ -80,10 +101,46 @@
|
||||
#include <deque>
|
||||
#include <stack>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#ifdef WINDOWS
|
||||
typedef int socklen_t;
|
||||
# include <conio.h>
|
||||
# include <io.h>
|
||||
# include <winsock2.h>
|
||||
# ifdef CC_VC
|
||||
# define SHUT_RDWR 2
|
||||
# pragma comment(lib, "Ws2_32.lib")
|
||||
# pragma comment(lib, "Iphlpapi.lib")
|
||||
# else
|
||||
# define SHUT_RDWR SD_BOTH
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# include <wincon.h>
|
||||
# include <iphlpapi.h>
|
||||
#else
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/socket.h>
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <net/if.h>
|
||||
#endif
|
||||
#ifndef QNX
|
||||
# ifndef WINDOWS
|
||||
# ifndef FREE_BSD
|
||||
# define environ __environ
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(WINDOWS) && !defined(MAC_OS)
|
||||
# define PIP_TIMER_RT
|
||||
#endif
|
||||
#ifdef FREE_BSD
|
||||
extern char ** environ;
|
||||
#endif
|
||||
#ifdef MAC_OS
|
||||
typedef long time_t;
|
||||
clock_serv_t __pi_mac_clock;
|
||||
#endif
|
||||
#include "pimonitor.h"
|
||||
|
||||
@@ -110,18 +167,65 @@ using std::queue;
|
||||
using std::deque;
|
||||
using std::stack;
|
||||
using std::set;
|
||||
using std::map;
|
||||
using std::string;
|
||||
#ifndef QNX
|
||||
using std::wstring;
|
||||
# ifndef WINDOWS
|
||||
static locale_t currentLocale_t = 0;
|
||||
# endif
|
||||
//# ifndef WINDOWS
|
||||
//static locale_t currentLocale_t = 0;
|
||||
//# endif
|
||||
#else
|
||||
typedef std::basic_string<wchar_t> wstring;
|
||||
#endif
|
||||
#ifdef HAS_LOCALE
|
||||
static locale_t currentLocale_t = 0;
|
||||
#endif
|
||||
|
||||
template<typename T> inline void piSwap(T & f, T & s) {T t = f; f = s; s = t;}
|
||||
template<typename T> inline int piRound(const T & v) {return int(v >= T(0.) ? v + T(0.5) : v - T(0.5));}
|
||||
template<typename T> inline int piFloor(const T & v) {return v < T(0) ? int(v) - 1 : int(v);}
|
||||
template<typename T> inline int piCeil(const T & v) {return v < T(0) ? int(v) : int(v) + 1;}
|
||||
template<typename T> inline T piAbs(const T & v) {return (v >= T(0) ? v : -v);}
|
||||
template<typename T> inline T piMin(const T & f, const T & s) {return (f > s) ? s : f;}
|
||||
template<typename T> inline T piMin(const T & f, const T & s, const T & t) {return (f < s && f < t) ? f : ((s < t) ? s : t);}
|
||||
template<typename T> inline T piMax(const T & f, const T & s) {return (f < s) ? s : f;}
|
||||
template<typename T> inline T piMax(const T & f, const T & s, const T & t) {return (f > s && f > t) ? f : ((s > t) ? s : t);}
|
||||
template<typename T> inline T piClamp(const T & v, const T & min, const T & max) {return (v > max ? max : (v < min ? min : v));}
|
||||
|
||||
#define piRoundf piRound<float>
|
||||
#define piRoundd piRound<double>
|
||||
#define piFloorf piFloor<float>
|
||||
#define piFloord piFloor<double>
|
||||
#define piCeilf piCeil<float>
|
||||
#define piCeild piCeil<double>
|
||||
#define piAbss piAbs<short>
|
||||
#define piAbsi piAbs<int>
|
||||
#define piAbsl piAbs<long>
|
||||
#define piAbsll piAbs<llong>
|
||||
#define piAbsf piAbs<float>
|
||||
#define piAbsd piAbs<double>
|
||||
#define piMins piMin<short>
|
||||
#define piMini piMin<int>
|
||||
#define piMinl piMin<long>
|
||||
#define piMinll piMin<llong>
|
||||
#define piMinf piMin<float>
|
||||
#define piMind piMin<double>
|
||||
#define piMaxs piMax<short>
|
||||
#define piMaxi piMax<int>
|
||||
#define piMaxl piMax<long>
|
||||
#define piMaxll piMax<llong>
|
||||
#define piMaxf piMax<float>
|
||||
#define piMaxd piMax<double>
|
||||
#define piClamps piClamp<short>
|
||||
#define piClampi piClamp<int>
|
||||
#define piClampl piClamp<long>
|
||||
#define piClampll piClamp<llong>
|
||||
#define piClampf piClamp<float>
|
||||
#define piClampd piClamp<double>
|
||||
|
||||
extern bool isPIInit;
|
||||
extern bool piDebug;
|
||||
extern string ifconfigPath;
|
||||
|
||||
#define piCout if (piDebug) cout
|
||||
|
||||
@@ -130,8 +234,34 @@ public:
|
||||
PIInit() {
|
||||
if (isPIInit) return;
|
||||
isPIInit = true;
|
||||
#ifndef WINDOWS
|
||||
sigset_t ss;
|
||||
sigemptyset(&ss);
|
||||
sigaddset(&ss, SIGALRM);
|
||||
if (pthread_sigmask(SIG_BLOCK, &ss, 0) == -1) {
|
||||
//cout << "[PITimer] sigaction error: " << errorString() << endl;
|
||||
//return 0;
|
||||
}
|
||||
ifconfigPath = "/bin/ifconfig";
|
||||
if (!fileExists(ifconfigPath)) {
|
||||
ifconfigPath = "/sbin/ifconfig";
|
||||
if (!fileExists(ifconfigPath)) {
|
||||
ifconfigPath = "/usr/bin/ifconfig";
|
||||
if (!fileExists(ifconfigPath)) {
|
||||
ifconfigPath = "/usr/sbin/ifconfig";
|
||||
if (!fileExists(ifconfigPath)) {
|
||||
ifconfigPath = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
#endif
|
||||
//piDebug = true;
|
||||
#ifdef LINUX
|
||||
#ifdef HAS_LOCALE
|
||||
//cout << "has locale" << endl;
|
||||
if (currentLocale_t != 0) {
|
||||
freelocale(currentLocale_t);
|
||||
currentLocale_t = 0;
|
||||
@@ -139,21 +269,26 @@ public:
|
||||
currentLocale_t = newlocale(LC_ALL, setlocale(LC_ALL, ""), 0);
|
||||
#else
|
||||
setlocale(LC_ALL, "");
|
||||
#endif
|
||||
#ifdef MAC_OS
|
||||
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &__pi_mac_clock);
|
||||
#endif
|
||||
}
|
||||
~PIInit() {
|
||||
#ifdef WINDOWS
|
||||
WSACleanup();
|
||||
#endif
|
||||
#ifdef MAC_OS
|
||||
mach_port_deallocate(mach_task_self(), __pi_mac_clock);
|
||||
#endif
|
||||
//if (currentLocale_t != 0) freelocale(currentLocale_t);
|
||||
}
|
||||
private:
|
||||
bool fileExists(const string & p) {FILE * f = fopen(p.c_str(), "r"); if (f == 0) return false; fclose(f); return true;}
|
||||
};
|
||||
|
||||
static PIInit piInit;
|
||||
static lconv * currentLocale = std::localeconv();
|
||||
|
||||
#ifdef CC_VC
|
||||
inline string errorString() {char buff[1024]; strerror_s(buff, 1024, GetLastError()); return string(buff);}
|
||||
#else
|
||||
inline string errorString() {return string(strerror(errno));}
|
||||
#endif
|
||||
extern PIInit piInit;
|
||||
extern lconv * currentLocale;
|
||||
|
||||
#ifdef WINDOWS
|
||||
inline int random() {return rand();}
|
||||
@@ -162,12 +297,6 @@ inline double round(const double & v) {return floor(v + 0.5);}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
template<typename Type> inline void piSwap(Type & f, Type & s) {Type t = f; f = s; s = t;}
|
||||
template<typename Type> inline Type piMin(const Type & f, const Type & s) {return (f > s) ? s : f;}
|
||||
template<typename Type> inline Type piMin(const Type & f, const Type & s, const Type & t) {return (f < s && f < t) ? f : ((s < t) ? s : t);}
|
||||
template<typename Type> inline Type piMax(const Type & f, const Type & s) {return (f < s) ? s : f;}
|
||||
template<typename Type> inline Type piMax(const Type & f, const Type & s, const Type & t) {return (f > s && f > t) ? f : ((s > t) ? s : t);}
|
||||
template<typename Type> inline Type piClamp(const Type & v, const Type & min, const Type & max) {return (v > max ? max : (v < min ? min : v));}
|
||||
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";};
|
||||
@@ -220,6 +349,18 @@ inline string dtos(const double num) {
|
||||
#endif
|
||||
return string(ch); };
|
||||
|
||||
#ifdef CC_VC
|
||||
inline string errorString() {
|
||||
char * msg;
|
||||
int err = GetLastError();
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL);
|
||||
return "code " + itos(err) + " - " + string(msg);
|
||||
}
|
||||
#else
|
||||
inline void errorClear() {errno = 0;}
|
||||
inline string errorString() {int e = errno; return "code " + itos(e) + " - " + string(strerror(e));}
|
||||
#endif
|
||||
|
||||
inline string PIPVersion() {return itos(PIP_VERSION_MAJOR) + "." + itos(PIP_VERSION_MINOR) + "." + itos(PIP_VERSION_REVISION) + PIP_VERSION_SUFFIX;}
|
||||
|
||||
#endif // PIINCLUDES_H
|
||||
|
||||
3
piiodevice.cpp
Executable file → Normal file
3
piiodevice.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Abstract input/output device
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -96,7 +96,6 @@ void PIIODevice::run() {
|
||||
//cout << "not started\n";
|
||||
return;
|
||||
}
|
||||
|
||||
readed_ = read(buffer_tr.data(), buffer_tr.size_s());
|
||||
if (readed_ <= 0) {
|
||||
msleep(10);
|
||||
|
||||
34
piiodevice.h
Executable file → Normal file
34
piiodevice.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Abstract input/output device
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,6 +25,18 @@
|
||||
// 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 {
|
||||
public:
|
||||
PIIODevice();
|
||||
@@ -32,7 +44,7 @@ public:
|
||||
enum DeviceMode {ReadOnly = 0x01, WriteOnly = 0x02, ReadWrite = 0x03};
|
||||
|
||||
PIIODevice(const PIString & path, DeviceMode type = ReadWrite, bool initNow = true);
|
||||
~PIIODevice() {if (opened_) closeDevice();}
|
||||
virtual ~PIIODevice() {if (opened_) {closeDevice(); if (!opened_) closed();}}
|
||||
|
||||
|
||||
DeviceMode mode() const {return mode_;}
|
||||
@@ -66,15 +78,19 @@ public:
|
||||
void startThreadedRead(ReadRetFunc func) {ret_func_ = func; if (!isRunning()) start();}
|
||||
|
||||
|
||||
EVENT_HANDLER(PIIODevice, bool, open) {if (!init_) init(); opened_ = openDevice(); return opened_;}
|
||||
EVENT_HANDLER1(PIIODevice, bool, open, const PIString &, _path) {path_ = _path; if (!init_) init(); opened_ = openDevice(); return opened_;}
|
||||
EVENT_HANDLER1(PIIODevice, bool, open, const DeviceMode &, _type) {mode_ = _type; if (!init_) init(); opened_ = openDevice(); return opened_;}
|
||||
EVENT_HANDLER2(PIIODevice, bool, open, const PIString &, _path, const DeviceMode &, _type) {path_ = _path; mode_ = _type; if (!init_) init(); opened_ = openDevice(); return opened_;}
|
||||
EVENT_HANDLER(PIIODevice, bool, close) {opened_ = !closeDevice(); return !opened_;}
|
||||
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)
|
||||
|
||||
|
||||
// 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;}
|
||||
@@ -84,6 +100,7 @@ public:
|
||||
|
||||
// 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());}
|
||||
|
||||
|
||||
protected:
|
||||
@@ -97,6 +114,8 @@ protected:
|
||||
// Function executed when thread read some data, default implementation execute external slot "ret_func_"
|
||||
virtual bool threadedRead(uchar * readed, int size) {if (ret_func_ != 0) return ret_func_(ret_data_, readed, size); return true;}
|
||||
|
||||
void terminate();
|
||||
|
||||
PIString path_;
|
||||
DeviceMode mode_;
|
||||
ReadRetFunc ret_func_;
|
||||
@@ -106,7 +125,6 @@ protected:
|
||||
|
||||
private:
|
||||
EVENT_HANDLER2(PIIODevice, void, check_start, void * , data, int, delim);
|
||||
void terminate();
|
||||
|
||||
void begin();
|
||||
void run();
|
||||
|
||||
3
pikbdlistener.cpp
Executable file → Normal file
3
pikbdlistener.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Keyboard grabber for console
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -64,6 +64,7 @@ void PIKbdListener::run() {
|
||||
PIKbdListener::exiting = true;
|
||||
return;
|
||||
}
|
||||
keyPressed(rc, data);
|
||||
if (ret_func != 0 && ret > 0) ret_func(rc, data);
|
||||
}
|
||||
|
||||
|
||||
16
pikbdlistener.h
Executable file → Normal file
16
pikbdlistener.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Keyboard grabber for console
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -29,6 +29,12 @@
|
||||
|
||||
typedef void (*KBFunc)(char, void * );
|
||||
|
||||
/// events:
|
||||
/// keyPressed(char key, void * data)
|
||||
///
|
||||
/// handlers:
|
||||
/// void enableExitCapture(char key = 'Q')
|
||||
/// void setActive(bool yes = true)
|
||||
class PIKbdListener: public PIThread {
|
||||
friend class PIConsole;
|
||||
public:
|
||||
@@ -38,12 +44,16 @@ public:
|
||||
|
||||
void setData(void * data_) {data = data_;}
|
||||
void setSlot(KBFunc slot_) {ret_func = slot_;}
|
||||
void enableExitCapture(char key = 'Q') {exit_enabled = true; exit_key = key;}
|
||||
EVENT_HANDLER(PIKbdListener, void, enableExitCapture) {enableExitCapture('Q');}
|
||||
EVENT_HANDLER1(PIKbdListener, 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;}
|
||||
void setActive(bool yes = true);
|
||||
EVENT_HANDLER(PIKbdListener, void, setActive) {setActive(true);}
|
||||
EVENT_HANDLER1(PIKbdListener, void, setActive, bool, yes);
|
||||
|
||||
EVENT2(PIKbdListener, keyPressed, char, key, void * , data)
|
||||
|
||||
static bool exiting;
|
||||
|
||||
|
||||
1134
pimath.cpp
Executable file → Normal file
1134
pimath.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Math
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -19,160 +19,6 @@
|
||||
|
||||
#include "pimath.h"
|
||||
|
||||
/*
|
||||
* Fast Fourier Transformation
|
||||
* ====================================================
|
||||
* Coded by Miroslav Voinarovsky, 2002
|
||||
* This source is freeware.
|
||||
*/
|
||||
|
||||
// This array contains values from 0 to 255 with reverse bit order
|
||||
static uchar reverse256[]= {
|
||||
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
|
||||
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
|
||||
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
|
||||
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
|
||||
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
|
||||
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
|
||||
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
|
||||
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
|
||||
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
|
||||
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
|
||||
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
|
||||
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
|
||||
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
|
||||
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
|
||||
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
|
||||
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
|
||||
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
|
||||
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
|
||||
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
|
||||
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
|
||||
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
|
||||
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
|
||||
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
|
||||
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
|
||||
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
|
||||
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
|
||||
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
|
||||
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
|
||||
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
|
||||
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
|
||||
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
|
||||
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF,
|
||||
};
|
||||
|
||||
//This is array exp(-2*pi*j/2^n) for n= 1,...,32
|
||||
//exp(-2*pi*j/2^n) = complexd( cos(2*pi/2^n), -sin(2*pi/2^n) )
|
||||
static complexd W2n[32] = {
|
||||
complexd(-1.00000000000000000000000000000000, 0.00000000000000000000000000000000), // W2 calculator (copy/paste) : po, ps
|
||||
complexd( 0.00000000000000000000000000000000, -1.00000000000000000000000000000000), // W4: p/2=o, p/2=s
|
||||
complexd( 0.70710678118654752440084436210485, -0.70710678118654752440084436210485), // W8: p/4=o, p/4=s
|
||||
complexd( 0.92387953251128675612818318939679, -0.38268343236508977172845998403040), // p/8=o, p/8=s
|
||||
complexd( 0.98078528040323044912618223613424, -0.19509032201612826784828486847702), // p/16=
|
||||
complexd( 0.99518472667219688624483695310948, -9.80171403295606019941955638886e-2), // p/32=
|
||||
complexd( 0.99879545620517239271477160475910, -4.90676743274180142549549769426e-2), // p/64=
|
||||
complexd( 0.99969881869620422011576564966617, -2.45412285229122880317345294592e-2), // p/128=
|
||||
complexd( 0.99992470183914454092164649119638, -1.22715382857199260794082619510e-2), // p/256=
|
||||
complexd( 0.99998117528260114265699043772857, -6.13588464915447535964023459037e-3), // p/(2y9)=
|
||||
complexd( 0.99999529380957617151158012570012, -3.06795676296597627014536549091e-3), // p/(2y10)=
|
||||
complexd( 0.99999882345170190992902571017153, -1.53398018628476561230369715026e-3), // p/(2y11)=
|
||||
complexd( 0.99999970586288221916022821773877, -7.66990318742704526938568357948e-4), // p/(2y12)=
|
||||
complexd( 0.99999992646571785114473148070739, -3.83495187571395589072461681181e-4), // p/(2y13)=
|
||||
complexd( 0.99999998161642929380834691540291, -1.91747597310703307439909561989e-4), // p/(2y14)=
|
||||
complexd( 0.99999999540410731289097193313961, -9.58737990959773458705172109764e-5), // p/(2y15)=
|
||||
complexd( 0.99999999885102682756267330779455, -4.79368996030668845490039904946e-5), // p/(2y16)=
|
||||
complexd( 0.99999999971275670684941397221864, -2.39684498084182187291865771650e-5), // p/(2y17)=
|
||||
complexd( 0.99999999992818917670977509588385, -1.19842249050697064215215615969e-5), // p/(2y18)=
|
||||
complexd( 0.99999999998204729417728262414778, -5.99211245264242784287971180889e-6), // p/(2y19)=
|
||||
complexd( 0.99999999999551182354431058417300, -2.99605622633466075045481280835e-6), // p/(2y20)=
|
||||
complexd( 0.99999999999887795588607701655175, -1.49802811316901122885427884615e-6), // p/(2y21)=
|
||||
complexd( 0.99999999999971948897151921479472, -7.49014056584715721130498566730e-7), // p/(2y22)=
|
||||
complexd( 0.99999999999992987224287980123973, -3.74507028292384123903169179084e-7), // p/(2y23)=
|
||||
complexd( 0.99999999999998246806071995015625, -1.87253514146195344868824576593e-7), // p/(2y24)=
|
||||
complexd( 0.99999999999999561701517998752946, -9.36267570730980827990672866808e-8), // p/(2y25)=
|
||||
complexd( 0.99999999999999890425379499688176, -4.68133785365490926951155181385e-8), // p/(2y26)=
|
||||
complexd( 0.99999999999999972606344874922040, -2.34066892682745527595054934190e-8), // p/(2y27)=
|
||||
complexd( 0.99999999999999993151586218730510, -1.17033446341372771812462135032e-8), // p/(2y28)=
|
||||
complexd( 0.99999999999999998287896554682627, -5.85167231706863869080979010083e-9), // p/(2y29)=
|
||||
complexd( 0.99999999999999999571974138670657, -2.92583615853431935792823046906e-9), // p/(2y30)=
|
||||
complexd( 0.99999999999999999892993534667664, -1.46291807926715968052953216186e-9), // p/(2y31)=
|
||||
};
|
||||
|
||||
/*
|
||||
* x: x - array of items
|
||||
* T: 1 << T = 2 power T - number of items in array
|
||||
* complement: false - normal (direct) transformation, true - reverse transformation
|
||||
*/
|
||||
void fft(complexd * x, int T, bool complement)
|
||||
{
|
||||
uint I, J, Nmax, N, Nd2, k, m, mpNd2, Skew;
|
||||
uchar *Ic = (uchar*) &I;
|
||||
uchar *Jc = (uchar*) &J;
|
||||
complexd S;
|
||||
complexd * Wstore, * Warray;
|
||||
complexd WN, W, Temp, *pWN;
|
||||
|
||||
Nmax = 1 << T;
|
||||
|
||||
//first interchanging
|
||||
for(I = 1; I < Nmax - 1; I++)
|
||||
{
|
||||
Jc[0] = reverse256[Ic[3]];
|
||||
Jc[1] = reverse256[Ic[2]];
|
||||
Jc[2] = reverse256[Ic[1]];
|
||||
Jc[3] = reverse256[Ic[0]];
|
||||
J >>= (32 - T);
|
||||
if (I < J)
|
||||
{
|
||||
S = x[I];
|
||||
x[I] = x[J];
|
||||
x[J] = S;
|
||||
}
|
||||
}
|
||||
|
||||
//rotation multiplier array allocation
|
||||
Wstore = new complexd[Nmax / 2];
|
||||
Wstore[0] = complexd(1., 0.);
|
||||
|
||||
//main loop
|
||||
for(N = 2, Nd2 = 1, pWN = W2n, Skew = Nmax >> 1; N <= Nmax; Nd2 = N, N += N, pWN++, Skew >>= 1)
|
||||
{
|
||||
//WN = W(1, N) = exp(-2*pi*j/N)
|
||||
WN= *pWN;
|
||||
if (complement)
|
||||
WN = complexd(WN.real(), -WN.imag());
|
||||
for(Warray = Wstore, k = 0; k < Nd2; k++, Warray += Skew)
|
||||
{
|
||||
if (k & 1)
|
||||
{
|
||||
W *= WN;
|
||||
*Warray = W;
|
||||
}
|
||||
else
|
||||
W = *Warray;
|
||||
|
||||
for(m = k; m < Nmax; m += N)
|
||||
{
|
||||
mpNd2 = m + Nd2;
|
||||
Temp = W;
|
||||
Temp *= x[mpNd2];
|
||||
x[mpNd2] = x[m];
|
||||
x[mpNd2] -= Temp;
|
||||
x[m] += Temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete[] Wstore;
|
||||
|
||||
if (complement)
|
||||
{
|
||||
for( I = 0; I < Nmax; I++ )
|
||||
x[I] /= Nmax;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char Solver::methods_desc[] = "b{Methods:}\
|
||||
\n -1 - Global settings\
|
||||
@@ -401,3 +247,981 @@ void Solver::solvePA(double u, double h, uint deg) {
|
||||
}
|
||||
moveF();
|
||||
}
|
||||
|
||||
|
||||
|
||||
PIFFT::PIFFT() {
|
||||
prepared = false;
|
||||
}
|
||||
|
||||
|
||||
PIVector<complexd> * PIFFT::calcFFT(const PIVector<complexd> & val) {
|
||||
// for (uint i=0; i<result.size(); i+=2)
|
||||
// {
|
||||
// result[i] = val.at(indexes[i]) + val.at(indexes[i+1]);
|
||||
// result[i+1] = val.at(indexes[i]) - val.at(indexes[i+1]);
|
||||
// }
|
||||
// return &result;
|
||||
result.clear();
|
||||
if (val.size_s() < 4) return &result;
|
||||
fftc1d(val, val.size());
|
||||
return &result;
|
||||
}
|
||||
|
||||
|
||||
PIVector<complexd> *PIFFT::calcFFTinverse(const PIVector<complexd> &val)
|
||||
{
|
||||
result.clear();
|
||||
if (val.size_s() < 4) return &result;
|
||||
fftc1dinv(val, val.size());
|
||||
return &result;
|
||||
}
|
||||
|
||||
|
||||
PIVector<complexd> *PIFFT::calcHilbert(const PIVector<double> &val)
|
||||
{
|
||||
result.clear();
|
||||
if (val.size_s() < 4) return &result;
|
||||
fftc1r(val, val.size());
|
||||
for (uint i=0; i<result.size()/2; i++) result[i] = result[i]*2.;
|
||||
for (uint i=result.size()/2; i<result.size(); i++) result[i] = 0;
|
||||
fftc1dinv(result, result.size());
|
||||
return &result;
|
||||
}
|
||||
|
||||
|
||||
PIVector< complexd >* PIFFT::calcFFT(const PIVector<double> & val) {
|
||||
result.clear();
|
||||
if (val.size_s() < 4) return &result;
|
||||
fftc1r(val, val.size());
|
||||
return &result;
|
||||
}
|
||||
|
||||
|
||||
PIVector<double> PIFFT::getAmplitude() {
|
||||
PIVector<double> a;
|
||||
double tmp;
|
||||
for (uint i=0; i<result.size(); i++) {
|
||||
tmp = sqrt(result.at(i).real()*result.at(i).real()+result.at(i).imag()*result.at(i).imag());
|
||||
a.push_back(tmp);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
void PIFFT::fftc1d(const PIVector<complexd> &a, uint n) {
|
||||
createPlan(n);
|
||||
uint i;
|
||||
PIVector<double> buf;
|
||||
buf.resize(2*n);
|
||||
for(i=0; i<n; i++) {
|
||||
buf[2*i+0] = a.at(i).real();// a->ptr.p_complex[i].x;
|
||||
buf[2*i+1] = a.at(i).imag();//a->ptr.p_complex[i].y;
|
||||
}
|
||||
ftbaseexecuteplan(&buf, 0, n, &curplan);
|
||||
result.resize(n);
|
||||
for(i=0; i<n; i++)
|
||||
result[i]=complexd(buf[2*i+0],buf[2*i+1]);
|
||||
}
|
||||
|
||||
|
||||
void PIFFT::fftc1r(const PIVector<double> & a, uint n) {
|
||||
uint i;
|
||||
if( n%2==0 ) {
|
||||
PIVector<double> buf;
|
||||
uint n2 = n/2;
|
||||
//buf.resize(n);
|
||||
buf = a;
|
||||
createPlan(n2);
|
||||
//cout << "fftr " << n2 << endl;
|
||||
ftbaseexecuteplan(&buf, 0, n2, &curplan);
|
||||
result.resize(n);
|
||||
uint idx;
|
||||
complexd hn, hmnc, v;
|
||||
for(i=0; i<=n2; i++) {
|
||||
idx = 2*(i%n2);
|
||||
hn = complexd(buf[idx+0], buf[idx+1]);
|
||||
idx = 2*((n2-i)%n2);
|
||||
hmnc = complexd(buf[idx+0], -buf[idx+1]);
|
||||
v = complexd(sin(M_PI*i/n2), cos(M_PI*i/n2));
|
||||
result[i] = ((hn + hmnc) - (v * (hn - hmnc)));
|
||||
result[i] *= 0.5;
|
||||
}
|
||||
for(i=n2+1; i<n; i++)
|
||||
result[i] = conj(result[n-i]);
|
||||
} else {
|
||||
PIVector<complexd> cbuf;
|
||||
cbuf.resize(n);
|
||||
for(i=0; i<n; i++)
|
||||
cbuf[i] = complexd(a[i], 0.);
|
||||
fftc1d(cbuf, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIFFT::fftc1dinv(const PIVector<complexd> &a, uint n)
|
||||
{
|
||||
PIVector<complexd> cbuf;
|
||||
cbuf.resize(n);
|
||||
uint i;
|
||||
for(i=0; i<n; i++)
|
||||
{
|
||||
cbuf[i] = conj(a[i]);
|
||||
}
|
||||
fftc1d(cbuf, n);
|
||||
// result.resize(n);
|
||||
for(i=0; i<n; i++)
|
||||
{
|
||||
result[i] = conj(result[i] / (double)n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIFFT::createPlan(uint n) {
|
||||
curplan.plan.clear();
|
||||
curplan.precomputed.clear();
|
||||
curplan.stackbuf.clear();
|
||||
curplan.tmpbuf.clear();
|
||||
if (n<2) return;
|
||||
ftbasegeneratecomplexfftplan(n, &curplan);
|
||||
prepared = true;
|
||||
}
|
||||
|
||||
|
||||
void PIFFT::ftbasegeneratecomplexfftplan(uint n, ftplan* plan) {
|
||||
int planarraysize;
|
||||
int plansize;
|
||||
int precomputedsize;
|
||||
int tmpmemsize;
|
||||
int stackmemsize;
|
||||
ae_int_t stackptr;
|
||||
planarraysize = 1;
|
||||
plansize = 0;
|
||||
precomputedsize = 0;
|
||||
stackmemsize = 0;
|
||||
stackptr = 0;
|
||||
tmpmemsize = 2*n;
|
||||
curplan.plan.resize(planarraysize);
|
||||
int ftbase_ftbasecffttask = 0;
|
||||
ftbase_ftbasegenerateplanrec(n, ftbase_ftbasecffttask, plan, &plansize, &precomputedsize, &planarraysize, &tmpmemsize, &stackmemsize, stackptr);
|
||||
if (stackptr!=0) { return;}//ae_assert(stackptr==0, "Internal error in FTBaseGenerateComplexFFTPlan: stack ptr!");
|
||||
curplan.stackbuf.resize(piMax(stackmemsize,1));//ae_vector_set_length(&curplan.stackbuf, ae_maxint(stackmemsize, 1));
|
||||
curplan.tmpbuf.resize(piMax(tmpmemsize,1));//ae_vector_set_length(&(curplan.tmpbuf), ae_maxint(tmpmemsize, 1));
|
||||
curplan.precomputed.resize(piMax(precomputedsize,1));//ae_vector_set_length(&curplan.precomputed, ae_maxint(precomputedsize, 1));
|
||||
stackptr = 0;
|
||||
ftbase_ftbaseprecomputeplanrec(plan, 0, stackptr);
|
||||
if (stackptr!=0) { return;}//ae_assert(stackptr==0, "Internal error in FTBaseGenerateComplexFFTPlan: stack ptr!");
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Recurrent subroutine for the FFTGeneratePlan:
|
||||
|
||||
PARAMETERS:
|
||||
N plan size
|
||||
IsReal whether input is real or not.
|
||||
subroutine MUST NOT ignore this flag because real
|
||||
inputs comes with non-initialized imaginary parts,
|
||||
so ignoring this flag will result in corrupted output
|
||||
HalfOut whether full output or only half of it from 0 to
|
||||
floor(N/2) is needed. This flag may be ignored if
|
||||
doing so will simplify calculations
|
||||
Plan plan array
|
||||
PlanSize size of used part (in integers)
|
||||
PrecomputedSize size of precomputed array allocated yet
|
||||
PlanArraySize plan array size (actual)
|
||||
TmpMemSize temporary memory required size
|
||||
BluesteinMemSize temporary memory required size
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT::ftbase_ftbasegenerateplanrec(
|
||||
int n,
|
||||
int tasktype,
|
||||
ftplan* plan,
|
||||
int* plansize,
|
||||
int* precomputedsize,
|
||||
int* planarraysize,
|
||||
int* tmpmemsize,
|
||||
int* stackmemsize,
|
||||
ae_int_t stackptr, int debugi)
|
||||
{
|
||||
int k, m, n1, n2, esize, entryoffset;
|
||||
int ftbase_ftbaseplanentrysize = 8;
|
||||
int ftbase_ftbasecffttask = 0;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fftrealcooleytukeyplan = 5;
|
||||
int ftbase_fftemptyplan = 6;
|
||||
if( *plansize+ftbase_ftbaseplanentrysize>(*planarraysize) ) {
|
||||
curplan.plan.resize(8*(*planarraysize));
|
||||
*planarraysize = 8*(*planarraysize);
|
||||
}
|
||||
entryoffset = *plansize;
|
||||
esize = ftbase_ftbaseplanentrysize;
|
||||
*plansize = *plansize+esize;
|
||||
if( n==1 ) {
|
||||
curplan.plan[entryoffset+0] = esize;
|
||||
curplan.plan[entryoffset+1] = -1;
|
||||
curplan.plan[entryoffset+2] = -1;
|
||||
curplan.plan[entryoffset+3] = ftbase_fftemptyplan;
|
||||
curplan.plan[entryoffset+4] = -1;
|
||||
curplan.plan[entryoffset+5] = -1;
|
||||
curplan.plan[entryoffset+6] = -1;
|
||||
curplan.plan[entryoffset+7] = -1;
|
||||
return;
|
||||
}
|
||||
ftbasefactorize(n, &n1, &n2);
|
||||
if( n1!=1 ) {
|
||||
*tmpmemsize = piMax(*tmpmemsize, 2*n1*n2);
|
||||
curplan.plan[entryoffset+0] = esize;
|
||||
curplan.plan[entryoffset+1] = n1;
|
||||
curplan.plan[entryoffset+2] = n2;
|
||||
if( tasktype==ftbase_ftbasecffttask )
|
||||
curplan.plan[entryoffset+3] = ftbase_fftcooleytukeyplan;
|
||||
else
|
||||
curplan.plan[entryoffset+3] = ftbase_fftrealcooleytukeyplan;
|
||||
curplan.plan[entryoffset+4] = 0;
|
||||
curplan.plan[entryoffset+5] = *plansize;
|
||||
debugi++;
|
||||
ftbase_ftbasegenerateplanrec(n1, ftbase_ftbasecffttask, plan, plansize, precomputedsize, planarraysize, tmpmemsize, stackmemsize, stackptr,debugi);
|
||||
curplan.plan[entryoffset+6] = *plansize;
|
||||
ftbase_ftbasegenerateplanrec(n2, ftbase_ftbasecffttask, plan, plansize, precomputedsize, planarraysize, tmpmemsize, stackmemsize, stackptr,debugi);
|
||||
curplan.plan[entryoffset+7] = -1;
|
||||
return;
|
||||
} else {
|
||||
if (n>=2 && n<=5) {
|
||||
curplan.plan[entryoffset+0] = esize;
|
||||
curplan.plan[entryoffset+1] = n1;
|
||||
curplan.plan[entryoffset+2] = n2;
|
||||
curplan.plan[entryoffset+3] = ftbase_fftcodeletplan;
|
||||
curplan.plan[entryoffset+4] = 0;
|
||||
curplan.plan[entryoffset+5] = -1;
|
||||
curplan.plan[entryoffset+6] = -1;
|
||||
curplan.plan[entryoffset+7] = *precomputedsize;
|
||||
if( n==3 )
|
||||
*precomputedsize = *precomputedsize+2;
|
||||
if( n==5 )
|
||||
*precomputedsize = *precomputedsize+5;
|
||||
return;
|
||||
} else {
|
||||
k = 2*n2-1;
|
||||
m = ftbasefindsmooth(k);
|
||||
*tmpmemsize = piMax(*tmpmemsize, 2*m);
|
||||
curplan.plan[entryoffset+0] = esize;
|
||||
curplan.plan[entryoffset+1] = n2;
|
||||
curplan.plan[entryoffset+2] = -1;
|
||||
curplan.plan[entryoffset+3] = ftbase_fftbluesteinplan;
|
||||
curplan.plan[entryoffset+4] = m;
|
||||
curplan.plan[entryoffset+5] = *plansize;
|
||||
stackptr = stackptr+2*2*m;
|
||||
*stackmemsize = piMax(*stackmemsize, stackptr);
|
||||
ftbase_ftbasegenerateplanrec(m, ftbase_ftbasecffttask, plan, plansize, precomputedsize, planarraysize, tmpmemsize, stackmemsize, stackptr);
|
||||
stackptr = stackptr-2*2*m;
|
||||
curplan.plan[entryoffset+6] = -1;
|
||||
curplan.plan[entryoffset+7] = *precomputedsize;
|
||||
*precomputedsize = *precomputedsize+2*m+2*n;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Recurrent subroutine for precomputing FFT plans
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT::ftbase_ftbaseprecomputeplanrec(ftplan* plan,
|
||||
int entryoffset,
|
||||
ae_int_t stackptr)
|
||||
{
|
||||
int n1, n2, n, m, offs;
|
||||
double v, bx, by;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fhtcooleytukeyplan = 3;
|
||||
int ftbase_fhtcodeletplan = 4;
|
||||
int ftbase_fftrealcooleytukeyplan = 5;
|
||||
if( (curplan.plan[entryoffset+3]==ftbase_fftcooleytukeyplan||curplan.plan[entryoffset+3]==ftbase_fftrealcooleytukeyplan)||curplan.plan[entryoffset+3]==ftbase_fhtcooleytukeyplan ) {
|
||||
ftbase_ftbaseprecomputeplanrec(plan, curplan.plan[entryoffset+5], stackptr);
|
||||
ftbase_ftbaseprecomputeplanrec(plan, curplan.plan[entryoffset+6], stackptr);
|
||||
return;
|
||||
}
|
||||
if( curplan.plan[entryoffset+3]==ftbase_fftcodeletplan||curplan.plan[entryoffset+3]==ftbase_fhtcodeletplan ) {
|
||||
n1 = curplan.plan[entryoffset+1];
|
||||
n2 = curplan.plan[entryoffset+2];
|
||||
n = n1*n2;
|
||||
if( n==3 ) {
|
||||
offs = curplan.plan[entryoffset+7];
|
||||
curplan.precomputed[offs+0] = cos(2*M_PI/3)-1;
|
||||
curplan.precomputed[offs+1] = sin(2*M_PI/3);
|
||||
return;
|
||||
}
|
||||
if( n==5 ) {
|
||||
offs = curplan.plan[entryoffset+7];
|
||||
v = 2*M_PI/5;
|
||||
curplan.precomputed[offs+0] = (cos(v)+cos(2*v))/2-1;
|
||||
curplan.precomputed[offs+1] = (cos(v)-cos(2*v))/2;
|
||||
curplan.precomputed[offs+2] = -sin(v);
|
||||
curplan.precomputed[offs+3] = -(sin(v)+sin(2*v));
|
||||
curplan.precomputed[offs+4] = sin(v)-sin(2*v);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if( curplan.plan[entryoffset+3]==ftbase_fftbluesteinplan ) {
|
||||
ftbase_ftbaseprecomputeplanrec(plan, curplan.plan[entryoffset+5], stackptr);
|
||||
n = curplan.plan[entryoffset+1];
|
||||
m = curplan.plan[entryoffset+4];
|
||||
offs = curplan.plan[entryoffset+7];
|
||||
for(int i=0; i<=2*m-1; i++)
|
||||
curplan.precomputed[offs+i] = 0;
|
||||
for(int i=0; i<n; i++) {
|
||||
bx = cos(M_PI*sqr(i)/n);
|
||||
by = sin(M_PI*sqr(i)/n);
|
||||
curplan.precomputed[offs+2*i+0] = bx;
|
||||
curplan.precomputed[offs+2*i+1] = by;
|
||||
curplan.precomputed[offs+2*m+2*i+0] = bx;
|
||||
curplan.precomputed[offs+2*m+2*i+1] = by;
|
||||
if( i>0 ) {
|
||||
curplan.precomputed[offs+2*(m-i)+0] = bx;
|
||||
curplan.precomputed[offs+2*(m-i)+1] = by;
|
||||
}
|
||||
}
|
||||
ftbaseexecuteplanrec(&curplan.precomputed, offs, plan, curplan.plan[entryoffset+5], stackptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIFFT::ftbasefactorize(int n, int* n1, int* n2) {
|
||||
*n1 = *n2 = 0;
|
||||
int ftbase_ftbasecodeletrecommended = 5;
|
||||
if( (*n1)*(*n2)!=n ) {
|
||||
for(int j=ftbase_ftbasecodeletrecommended; j>=2; j--) {
|
||||
if( n%j==0 ) {
|
||||
*n1 = j;
|
||||
*n2 = n/j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( (*n1)*(*n2)!=n ) {
|
||||
for(int j=ftbase_ftbasecodeletrecommended+1; j<=n-1; j++) {
|
||||
if( n%j==0 ) {
|
||||
*n1 = j;
|
||||
*n2 = n/j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( (*n1)*(*n2)!=n ) {
|
||||
*n1 = 1;
|
||||
*n2 = n;
|
||||
}
|
||||
if( (*n2)==1 && (*n1)!=1 ) {
|
||||
*n2 = *n1;
|
||||
*n1 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Is number smooth?
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT::ftbase_ftbasefindsmoothrec(int n, int seed, int leastfactor, int* best) {
|
||||
if( seed>=n ) {
|
||||
*best = piMin(*best, seed);
|
||||
return;
|
||||
}
|
||||
if( leastfactor<=2 )
|
||||
ftbase_ftbasefindsmoothrec(n, seed*2, 2, best);
|
||||
if( leastfactor<=3 )
|
||||
ftbase_ftbasefindsmoothrec(n, seed*3, 3, best);
|
||||
if( leastfactor<=5 )
|
||||
ftbase_ftbasefindsmoothrec(n, seed*5, 5, best);
|
||||
}
|
||||
|
||||
|
||||
int PIFFT::ftbasefindsmooth(int n) {
|
||||
int best, result;
|
||||
best = 2;
|
||||
while(best<n)
|
||||
best = 2*best;
|
||||
ftbase_ftbasefindsmoothrec(n, 1, 2, &best);
|
||||
result = best;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void PIFFT::ftbase_internalreallintranspose(PIVector<double>* a, int m, int n, int astart, PIVector<double>* buf) {
|
||||
ftbase_fftirltrec(a, astart, n, buf, 0, m, m, n);
|
||||
for (int i=0; i<2*m*n; i++) (*a)[astart+i] = (*buf)[i];
|
||||
}
|
||||
|
||||
|
||||
void PIFFT::ftbase_fftirltrec(PIVector<double>* a, int astart, int astride, PIVector<double>* b, int bstart, int bstride, int m, int n) {
|
||||
int idx1, idx2;
|
||||
int m1, n1;
|
||||
if( m==0||n==0 )
|
||||
return;
|
||||
if( piMax(m, n)<=8 ) {
|
||||
for(int i=0; i<=m-1; i++) {
|
||||
idx1 = bstart+i;
|
||||
idx2 = astart+i*astride;
|
||||
for(int j=0; j<=n-1; j++) {
|
||||
(*b)[idx1] = a->at(idx2);
|
||||
idx1 = idx1+bstride;
|
||||
idx2 = idx2+1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if( n>m ) {
|
||||
n1 = n/2;
|
||||
if( n-n1>=8&&n1%8!=0 )
|
||||
n1 = n1+(8-n1%8);
|
||||
ftbase_fftirltrec(a, astart, astride, b, bstart, bstride, m, n1);
|
||||
ftbase_fftirltrec(a, astart+n1, astride, b, bstart+n1*bstride, bstride, m, n-n1);
|
||||
} else {
|
||||
m1 = m/2;
|
||||
if( m-m1>=8&&m1%8!=0 )
|
||||
m1 = m1+(8-m1%8);
|
||||
ftbase_fftirltrec(a, astart, astride, b, bstart, bstride, m1, n);
|
||||
ftbase_fftirltrec(a, astart+m1*astride, astride, b, bstart+m1, bstride, m-m1, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIFFT::ftbase_internalcomplexlintranspose(PIVector<double>* a, int m, int n, int astart, PIVector<double>* buf) {
|
||||
ftbase_ffticltrec(a, astart, n, buf, 0, m, m, n);
|
||||
for (int i=0; i<2*m*n; i++)
|
||||
(*a)[astart+i] = (*buf)[i];
|
||||
}
|
||||
|
||||
|
||||
void PIFFT::ftbase_ffticltrec(PIVector<double>* a, int astart, int astride, PIVector<double>* b, int bstart, int bstride, int m, int n) {
|
||||
int idx1, idx2, m2, m1, n1;
|
||||
if( m==0||n==0 )
|
||||
return;
|
||||
if( piMax(m, n)<=8 ) {
|
||||
m2 = 2*bstride;
|
||||
for(int i=0; i<=m-1; i++) {
|
||||
idx1 = bstart+2*i;
|
||||
idx2 = astart+2*i*astride;
|
||||
for(int j=0; j<=n-1; j++) {
|
||||
(*b)[idx1+0] = a->at(idx2+0);
|
||||
(*b)[idx1+1] = a->at(idx2+1);
|
||||
idx1 = idx1+m2;
|
||||
idx2 = idx2+2;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if( n>m ) {
|
||||
n1 = n/2;
|
||||
if( n-n1>=8&&n1%8!=0 )
|
||||
n1 = n1+(8-n1%8);
|
||||
ftbase_ffticltrec(a, astart, astride, b, bstart, bstride, m, n1);
|
||||
ftbase_ffticltrec(a, astart+2*n1, astride, b, bstart+2*n1*bstride, bstride, m, n-n1);
|
||||
} else {
|
||||
m1 = m/2;
|
||||
if( m-m1>=8&&m1%8!=0 )
|
||||
m1 = m1+(8-m1%8);
|
||||
ftbase_ffticltrec(a, astart, astride, b, bstart, bstride, m1, n);
|
||||
ftbase_ffticltrec(a, astart+2*m1*astride, astride, b, bstart+2*m1, bstride, m-m1, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIFFT::ftbaseexecuteplan(PIVector<double>* a, int aoffset, int n, ftplan* plan) {
|
||||
ae_int_t stackptr;
|
||||
stackptr = 0;
|
||||
ftbaseexecuteplanrec(a, aoffset, plan, 0, stackptr);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Recurrent subroutine for the FTBaseExecutePlan
|
||||
|
||||
Parameters:
|
||||
A FFT'ed array
|
||||
AOffset offset of the FFT'ed part (distance is measured in doubles)
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT::ftbaseexecuteplanrec(PIVector<double>* a, int aoffset, ftplan* plan, int entryoffset, ae_int_t stackptr) {
|
||||
int n1, n2, n, m, offs, offs1, offs2, offsa, offsb, offsp;
|
||||
double hk, hnk, x, y, bx, by, v0, v1, v2, v3;
|
||||
double a0x, a0y, a1x, a1y, a2x, a2y, a3x, a3y;
|
||||
double t1x, t1y, t2x, t2y, t3x, t3y, t4x, t4y, t5x, t5y;
|
||||
double m1x, m1y, m2x, m2y, m3x, m3y, m4x, m4y, m5x, m5y;
|
||||
double s1x, s1y, s2x, s2y, s3x, s3y, s4x, s4y, s5x, s5y;
|
||||
double c1, c2, c3, c4, c5;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fhtcooleytukeyplan = 3;
|
||||
int ftbase_fhtcodeletplan = 4;
|
||||
int ftbase_fftrealcooleytukeyplan = 5;
|
||||
int ftbase_fftemptyplan = 6;
|
||||
PIVector<double> & tmpb(curplan.tmpbuf);
|
||||
|
||||
if( curplan.plan[entryoffset+3]==ftbase_fftemptyplan )
|
||||
return;
|
||||
if( curplan.plan[entryoffset+3]==ftbase_fftcooleytukeyplan ) {
|
||||
n1 = curplan.plan[entryoffset+1];
|
||||
n2 = curplan.plan[entryoffset+2];
|
||||
ftbase_internalcomplexlintranspose(a, n1, n2, aoffset, &(curplan.tmpbuf));
|
||||
for(int i=0; i<=n2-1; i++)
|
||||
ftbaseexecuteplanrec(a, aoffset+i*n1*2, plan, curplan.plan[entryoffset+5], stackptr);
|
||||
ftbase_ffttwcalc(a, aoffset, n1, n2);
|
||||
ftbase_internalcomplexlintranspose(a, n2, n1, aoffset, &(curplan.tmpbuf));
|
||||
for(int i=0; i<=n1-1; i++)
|
||||
ftbaseexecuteplanrec(a, aoffset+i*n2*2, plan, curplan.plan[entryoffset+6], stackptr);
|
||||
ftbase_internalcomplexlintranspose(a, n1, n2, aoffset, &(curplan.tmpbuf));
|
||||
return;
|
||||
}
|
||||
if( curplan.plan[entryoffset+3]==ftbase_fftrealcooleytukeyplan ) {
|
||||
n1 = curplan.plan[entryoffset+1];
|
||||
n2 = curplan.plan[entryoffset+2];
|
||||
ftbase_internalcomplexlintranspose(a, n2, n1, aoffset, &(curplan.tmpbuf));
|
||||
for(int i=0; i<=n1/2-1; i++) {
|
||||
offs = aoffset+2*i*n2*2;
|
||||
for(int k=0; k<=n2-1; k++)
|
||||
(*a)[offs+2*k+1] = (*a)[offs+2*n2+2*k+0];
|
||||
ftbaseexecuteplanrec(a, offs, plan, curplan.plan[entryoffset+6], stackptr);
|
||||
tmpb[0] = (*a)[offs+0];
|
||||
tmpb[1] = 0;
|
||||
tmpb[2*n2+0] = (*a)[offs+1];
|
||||
tmpb[2*n2+1] = 0;
|
||||
for(int k=1; k<=n2-1; k++) {
|
||||
offs1 = 2*k;
|
||||
offs2 = 2*n2+2*k;
|
||||
hk = (*a)[offs+2*k+0];
|
||||
hnk = (*a)[offs+2*(n2-k)+0];
|
||||
tmpb[offs1+0] = 0.5*(hk+hnk);
|
||||
tmpb[offs2+1] = -0.5*(hk-hnk);
|
||||
hk = (*a)[offs+2*k+1];
|
||||
hnk = (*a)[offs+2*(n2-k)+1];
|
||||
tmpb[offs2+0] = 0.5*(hk+hnk);
|
||||
tmpb[offs1+1] = 0.5*(hk-hnk);
|
||||
}
|
||||
for (int i=0; i<2*n2*2; i++) (*a)[offs+i] = tmpb[i];
|
||||
}
|
||||
if( n1%2!=0 )
|
||||
ftbaseexecuteplanrec(a, aoffset+(n1-1)*n2*2, plan, curplan.plan[entryoffset+6], stackptr);
|
||||
ftbase_ffttwcalc(a, aoffset, n2, n1);
|
||||
ftbase_internalcomplexlintranspose(a, n1, n2, aoffset, &(curplan.tmpbuf));
|
||||
for(int i=0; i<=n2-1; i++)
|
||||
ftbaseexecuteplanrec(a, aoffset+i*n1*2, plan, curplan.plan[entryoffset+5], stackptr);
|
||||
ftbase_internalcomplexlintranspose(a, n2, n1, aoffset, &(curplan.tmpbuf));
|
||||
return;
|
||||
}
|
||||
if( curplan.plan[entryoffset+3]==ftbase_fhtcooleytukeyplan ) {
|
||||
n1 = curplan.plan[entryoffset+1];
|
||||
n2 = curplan.plan[entryoffset+2];
|
||||
n = n1*n2;
|
||||
ftbase_internalreallintranspose(a, n1, n2, aoffset, &(curplan.tmpbuf));
|
||||
for(int i=0; i<=n2-1; i++)
|
||||
ftbaseexecuteplanrec(a, aoffset+i*n1, plan, curplan.plan[entryoffset+5], stackptr);
|
||||
for(int i=0; i<=n2-1; i++) {
|
||||
for(int j=0; j<=n1-1; j++) {
|
||||
offsa = aoffset+i*n1;
|
||||
hk = (*a)[offsa+j];
|
||||
hnk = (*a)[offsa+(n1-j)%n1];
|
||||
offs = 2*(i*n1+j);
|
||||
tmpb[offs+0] = -0.5*(hnk-hk);
|
||||
tmpb[offs+1] = 0.5*(hk+hnk);
|
||||
}
|
||||
}
|
||||
ftbase_ffttwcalc(&(curplan.tmpbuf), 0, n1, n2);
|
||||
for(int j=0; j<=n1-1; j++)
|
||||
(*a)[aoffset+j] = tmpb[2*j+0]+tmpb[2*j+1];
|
||||
if( n2%2==0 ) {
|
||||
offs = 2*(n2/2)*n1;
|
||||
offsa = aoffset+n2/2*n1;
|
||||
for(int j=0; j<=n1-1; j++)
|
||||
(*a)[offsa+j] = tmpb[offs+2*j+0]+tmpb[offs+2*j+1];
|
||||
}
|
||||
for(int i=1; i<=(n2+1)/2-1; i++) {
|
||||
offs = 2*i*n1;
|
||||
offs2 = 2*(n2-i)*n1;
|
||||
offsa = aoffset+i*n1;
|
||||
for(int j=0; j<=n1-1; j++)
|
||||
(*a)[offsa+j] = tmpb[offs+2*j+1]+tmpb[offs2+2*j+0];
|
||||
offsa = aoffset+(n2-i)*n1;
|
||||
for(int j=0; j<=n1-1; j++)
|
||||
(*a)[offsa+j] = tmpb[offs+2*j+0]+tmpb[offs2+2*j+1];
|
||||
}
|
||||
ftbase_internalreallintranspose(a, n2, n1, aoffset, &(curplan.tmpbuf));
|
||||
for(int i=0; i<=n1-1; i++)
|
||||
ftbaseexecuteplanrec(a, aoffset+i*n2, plan, curplan.plan[entryoffset+6], stackptr);
|
||||
ftbase_internalreallintranspose(a, n1, n2, aoffset, &(curplan.tmpbuf));
|
||||
return;
|
||||
}
|
||||
if( curplan.plan[entryoffset+3]==ftbase_fftcodeletplan ) {
|
||||
n1 = curplan.plan[entryoffset+1];
|
||||
n2 = curplan.plan[entryoffset+2];
|
||||
n = n1*n2;
|
||||
if( n==2 ) {
|
||||
a0x = (*a)[aoffset+0];
|
||||
a0y = (*a)[aoffset+1];
|
||||
a1x = (*a)[aoffset+2];
|
||||
a1y = (*a)[aoffset+3];
|
||||
v0 = a0x+a1x;
|
||||
v1 = a0y+a1y;
|
||||
v2 = a0x-a1x;
|
||||
v3 = a0y-a1y;
|
||||
(*a)[aoffset+0] = v0;
|
||||
(*a)[aoffset+1] = v1;
|
||||
(*a)[aoffset+2] = v2;
|
||||
(*a)[aoffset+3] = v3;
|
||||
return;
|
||||
}
|
||||
if( n==3 ) {
|
||||
offs = curplan.plan[entryoffset+7];
|
||||
c1 = curplan.precomputed[offs+0];
|
||||
c2 = curplan.precomputed[offs+1];
|
||||
a0x = (*a)[aoffset+0];
|
||||
a0y = (*a)[aoffset+1];
|
||||
a1x = (*a)[aoffset+2];
|
||||
a1y = (*a)[aoffset+3];
|
||||
a2x = (*a)[aoffset+4];
|
||||
a2y = (*a)[aoffset+5];
|
||||
t1x = a1x+a2x;
|
||||
t1y = a1y+a2y;
|
||||
a0x = a0x+t1x;
|
||||
a0y = a0y+t1y;
|
||||
m1x = c1*t1x;
|
||||
m1y = c1*t1y;
|
||||
m2x = c2*(a1y-a2y);
|
||||
m2y = c2*(a2x-a1x);
|
||||
s1x = a0x+m1x;
|
||||
s1y = a0y+m1y;
|
||||
a1x = s1x+m2x;
|
||||
a1y = s1y+m2y;
|
||||
a2x = s1x-m2x;
|
||||
a2y = s1y-m2y;
|
||||
(*a)[aoffset+0] = a0x;
|
||||
(*a)[aoffset+1] = a0y;
|
||||
(*a)[aoffset+2] = a1x;
|
||||
(*a)[aoffset+3] = a1y;
|
||||
(*a)[aoffset+4] = a2x;
|
||||
(*a)[aoffset+5] = a2y;
|
||||
return;
|
||||
}
|
||||
if( n==4 ) {
|
||||
a0x = (*a)[aoffset+0];
|
||||
a0y = (*a)[aoffset+1];
|
||||
a1x = (*a)[aoffset+2];
|
||||
a1y = (*a)[aoffset+3];
|
||||
a2x = (*a)[aoffset+4];
|
||||
a2y = (*a)[aoffset+5];
|
||||
a3x = (*a)[aoffset+6];
|
||||
a3y = (*a)[aoffset+7];
|
||||
t1x = a0x+a2x;
|
||||
t1y = a0y+a2y;
|
||||
t2x = a1x+a3x;
|
||||
t2y = a1y+a3y;
|
||||
m2x = a0x-a2x;
|
||||
m2y = a0y-a2y;
|
||||
m3x = a1y-a3y;
|
||||
m3y = a3x-a1x;
|
||||
(*a)[aoffset+0] = t1x+t2x;
|
||||
(*a)[aoffset+1] = t1y+t2y;
|
||||
(*a)[aoffset+4] = t1x-t2x;
|
||||
(*a)[aoffset+5] = t1y-t2y;
|
||||
(*a)[aoffset+2] = m2x+m3x;
|
||||
(*a)[aoffset+3] = m2y+m3y;
|
||||
(*a)[aoffset+6] = m2x-m3x;
|
||||
(*a)[aoffset+7] = m2y-m3y;
|
||||
return;
|
||||
}
|
||||
if( n==5 ) {
|
||||
offs = curplan.plan[entryoffset+7];
|
||||
c1 = curplan.precomputed[offs+0];
|
||||
c2 = curplan.precomputed[offs+1];
|
||||
c3 = curplan.precomputed[offs+2];
|
||||
c4 = curplan.precomputed[offs+3];
|
||||
c5 = curplan.precomputed[offs+4];
|
||||
t1x = (*a)[aoffset+2]+(*a)[aoffset+8];
|
||||
t1y = (*a)[aoffset+3]+(*a)[aoffset+9];
|
||||
t2x = (*a)[aoffset+4]+(*a)[aoffset+6];
|
||||
t2y = (*a)[aoffset+5]+(*a)[aoffset+7];
|
||||
t3x = (*a)[aoffset+2]-(*a)[aoffset+8];
|
||||
t3y = (*a)[aoffset+3]-(*a)[aoffset+9];
|
||||
t4x = (*a)[aoffset+6]-(*a)[aoffset+4];
|
||||
t4y = (*a)[aoffset+7]-(*a)[aoffset+5];
|
||||
t5x = t1x+t2x;
|
||||
t5y = t1y+t2y;
|
||||
(*a)[aoffset+0] = (*a)[aoffset+0]+t5x;
|
||||
(*a)[aoffset+1] = (*a)[aoffset+1]+t5y;
|
||||
m1x = c1*t5x;
|
||||
m1y = c1*t5y;
|
||||
m2x = c2*(t1x-t2x);
|
||||
m2y = c2*(t1y-t2y);
|
||||
m3x = -c3*(t3y+t4y);
|
||||
m3y = c3*(t3x+t4x);
|
||||
m4x = -c4*t4y;
|
||||
m4y = c4*t4x;
|
||||
m5x = -c5*t3y;
|
||||
m5y = c5*t3x;
|
||||
s3x = m3x-m4x;
|
||||
s3y = m3y-m4y;
|
||||
s5x = m3x+m5x;
|
||||
s5y = m3y+m5y;
|
||||
s1x = (*a)[aoffset+0]+m1x;
|
||||
s1y = (*a)[aoffset+1]+m1y;
|
||||
s2x = s1x+m2x;
|
||||
s2y = s1y+m2y;
|
||||
s4x = s1x-m2x;
|
||||
s4y = s1y-m2y;
|
||||
(*a)[aoffset+2] = s2x+s3x;
|
||||
(*a)[aoffset+3] = s2y+s3y;
|
||||
(*a)[aoffset+4] = s4x+s5x;
|
||||
(*a)[aoffset+5] = s4y+s5y;
|
||||
(*a)[aoffset+6] = s4x-s5x;
|
||||
(*a)[aoffset+7] = s4y-s5y;
|
||||
(*a)[aoffset+8] = s2x-s3x;
|
||||
(*a)[aoffset+9] = s2y-s3y;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if( curplan.plan[entryoffset+3]==ftbase_fhtcodeletplan ) {
|
||||
n1 = curplan.plan[entryoffset+1];
|
||||
n2 = curplan.plan[entryoffset+2];
|
||||
n = n1*n2;
|
||||
if( n==2 ) {
|
||||
a0x = (*a)[aoffset+0];
|
||||
a1x = (*a)[aoffset+1];
|
||||
(*a)[aoffset+0] = a0x+a1x;
|
||||
(*a)[aoffset+1] = a0x-a1x;
|
||||
return;
|
||||
}
|
||||
if( n==3 ) {
|
||||
offs = curplan.plan[entryoffset+7];
|
||||
c1 = curplan.precomputed[offs+0];
|
||||
c2 = curplan.precomputed[offs+1];
|
||||
a0x = (*a)[aoffset+0];
|
||||
a1x = (*a)[aoffset+1];
|
||||
a2x = (*a)[aoffset+2];
|
||||
t1x = a1x+a2x;
|
||||
a0x = a0x+t1x;
|
||||
m1x = c1*t1x;
|
||||
m2y = c2*(a2x-a1x);
|
||||
s1x = a0x+m1x;
|
||||
(*a)[aoffset+0] = a0x;
|
||||
(*a)[aoffset+1] = s1x-m2y;
|
||||
(*a)[aoffset+2] = s1x+m2y;
|
||||
return;
|
||||
}
|
||||
if( n==4 ) {
|
||||
a0x = (*a)[aoffset+0];
|
||||
a1x = (*a)[aoffset+1];
|
||||
a2x = (*a)[aoffset+2];
|
||||
a3x = (*a)[aoffset+3];
|
||||
t1x = a0x+a2x;
|
||||
t2x = a1x+a3x;
|
||||
m2x = a0x-a2x;
|
||||
m3y = a3x-a1x;
|
||||
(*a)[aoffset+0] = t1x+t2x;
|
||||
(*a)[aoffset+1] = m2x-m3y;
|
||||
(*a)[aoffset+2] = t1x-t2x;
|
||||
(*a)[aoffset+3] = m2x+m3y;
|
||||
return;
|
||||
}
|
||||
if( n==5 ) {
|
||||
offs = curplan.plan[entryoffset+7];
|
||||
c1 = curplan.precomputed[offs+0];
|
||||
c2 = curplan.precomputed[offs+1];
|
||||
c3 = curplan.precomputed[offs+2];
|
||||
c4 = curplan.precomputed[offs+3];
|
||||
c5 = curplan.precomputed[offs+4];
|
||||
t1x = (*a)[aoffset+1]+(*a)[aoffset+4];
|
||||
t2x = (*a)[aoffset+2]+(*a)[aoffset+3];
|
||||
t3x = (*a)[aoffset+1]-(*a)[aoffset+4];
|
||||
t4x = (*a)[aoffset+3]-(*a)[aoffset+2];
|
||||
t5x = t1x+t2x;
|
||||
v0 = (*a)[aoffset+0]+t5x;
|
||||
(*a)[aoffset+0] = v0;
|
||||
m2x = c2*(t1x-t2x);
|
||||
m3y = c3*(t3x+t4x);
|
||||
s3y = m3y-c4*t4x;
|
||||
s5y = m3y+c5*t3x;
|
||||
s1x = v0+c1*t5x;
|
||||
s2x = s1x+m2x;
|
||||
s4x = s1x-m2x;
|
||||
(*a)[aoffset+1] = s2x-s3y;
|
||||
(*a)[aoffset+2] = s4x-s5y;
|
||||
(*a)[aoffset+3] = s4x+s5y;
|
||||
(*a)[aoffset+4] = s2x+s3y;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if( curplan.plan[entryoffset+3]==ftbase_fftbluesteinplan ) {
|
||||
n = curplan.plan[entryoffset+1];
|
||||
m = curplan.plan[entryoffset+4];
|
||||
offs = curplan.plan[entryoffset+7];
|
||||
for(int i=stackptr+2*n; i<=stackptr+2*m-1; i++)
|
||||
curplan.stackbuf[i] = 0;
|
||||
offsp = offs+2*m;
|
||||
offsa = aoffset;
|
||||
offsb = stackptr;
|
||||
for(int i=0; i<n; i++) {
|
||||
bx = curplan.precomputed[offsp+0];
|
||||
by = curplan.precomputed[offsp+1];
|
||||
x = (*a)[offsa+0];
|
||||
y = (*a)[offsa+1];
|
||||
curplan.stackbuf[offsb+0] = x*bx-y*(-by);
|
||||
curplan.stackbuf[offsb+1] = x*(-by)+y*bx;
|
||||
offsp = offsp+2;
|
||||
offsa = offsa+2;
|
||||
offsb = offsb+2;
|
||||
}
|
||||
ftbaseexecuteplanrec(&curplan.stackbuf, stackptr, plan, curplan.plan[entryoffset+5], stackptr+2*2*m);
|
||||
offsb = stackptr;
|
||||
offsp = offs;
|
||||
for(int i=0; i<=m-1; i++) {
|
||||
x = curplan.stackbuf[offsb+0];
|
||||
y = curplan.stackbuf[offsb+1];
|
||||
bx = curplan.precomputed[offsp+0];
|
||||
by = curplan.precomputed[offsp+1];
|
||||
curplan.stackbuf[offsb+0] = x*bx-y*by;
|
||||
curplan.stackbuf[offsb+1] = -(x*by+y*bx);
|
||||
offsb = offsb+2;
|
||||
offsp = offsp+2;
|
||||
}
|
||||
ftbaseexecuteplanrec(&curplan.stackbuf, stackptr, plan, curplan.plan[entryoffset+5], stackptr+2*2*m);
|
||||
offsb = stackptr;
|
||||
offsp = offs+2*m;
|
||||
offsa = aoffset;
|
||||
for(int i=0; i<n; i++) {
|
||||
x = curplan.stackbuf[offsb+0]/m;
|
||||
y = -curplan.stackbuf[offsb+1]/m;
|
||||
bx = curplan.precomputed[offsp+0];
|
||||
by = curplan.precomputed[offsp+1];
|
||||
(*a)[offsa+0] = x*bx-y*(-by);
|
||||
(*a)[offsa+1] = x*(-by)+y*bx;
|
||||
offsp = offsp+2;
|
||||
offsa = offsa+2;
|
||||
offsb = offsb+2;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Twiddle factors calculation
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT::ftbase_ffttwcalc(PIVector<double> * a, int aoffset, int n1, int n2) {
|
||||
int n, idx, offs;
|
||||
double x, y, twxm1, twy, twbasexm1, twbasey, twrowxm1, twrowy, tmpx, tmpy, v;
|
||||
int ftbase_ftbaseupdatetw = 4;
|
||||
n = n1*n2;
|
||||
v = -2*M_PI/n;
|
||||
twbasexm1 = -2*sqr(sin(0.5*v));
|
||||
twbasey = sin(v);
|
||||
twrowxm1 = 0;
|
||||
twrowy = 0;
|
||||
for(int i=0, j = 0; i<=n2-1; i++) {
|
||||
twxm1 = 0;
|
||||
twy = 0;
|
||||
for(j=0; j<=n1-1; j++) {
|
||||
idx = i*n1+j;
|
||||
offs = aoffset+2*idx;
|
||||
x = (*a)[offs+0];
|
||||
y = (*a)[offs+1];
|
||||
tmpx = x*twxm1-y*twy;
|
||||
tmpy = x*twy+y*twxm1;
|
||||
(*a)[offs+0] = x+tmpx;
|
||||
(*a)[offs+1] = y+tmpy;
|
||||
if( j<n1-1 ) {
|
||||
if( j%ftbase_ftbaseupdatetw==0 ) {
|
||||
v = -2*M_PI*i*(j+1)/n;
|
||||
twxm1 = -2*sqr(sin(0.5*v));
|
||||
twy = sin(v);
|
||||
} else {
|
||||
tmpx = twrowxm1+twxm1*twrowxm1-twy*twrowy;
|
||||
tmpy = twrowy+twxm1*twrowy+twy*twrowxm1;
|
||||
twxm1 = twxm1+tmpx;
|
||||
twy = twy+tmpy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( i<n2-1 ) {
|
||||
if( j%ftbase_ftbaseupdatetw==0 ) {
|
||||
v = -2*M_PI*(i+1)/n;
|
||||
twrowxm1 = -2*sqr(sin(0.5*v));
|
||||
twrowy = sin(v);
|
||||
} else {
|
||||
tmpx = twbasexm1+twrowxm1*twbasexm1-twrowy*twbasey;
|
||||
tmpy = twbasey+twrowxm1*twbasey+twrowy*twbasexm1;
|
||||
twrowxm1 = twrowxm1+tmpx;
|
||||
twrowy = twrowy+tmpy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PIStatistic::PIStatistic() {
|
||||
mean = 0.;
|
||||
variance = 0.;
|
||||
skewness = 0.;
|
||||
kurtosis = 0.;
|
||||
}
|
||||
|
||||
|
||||
bool PIStatistic::calculate(const PIVector<double> & val) {
|
||||
double v = 0., v1 = 0., v2 = 0., stddev = 0.;
|
||||
int i, n = val.size();
|
||||
if (n < 2)
|
||||
return false;
|
||||
/*
|
||||
* Mean
|
||||
*/
|
||||
for (i = 0; i < n; i++)
|
||||
mean += val[i];
|
||||
mean /= n;
|
||||
/*
|
||||
* Variance (using corrected two-pass algorithm)
|
||||
*/
|
||||
for (i = 0; i < n; i++)
|
||||
v1 += sqr(val[i] - mean);
|
||||
for (i = 0; i < n; i++)
|
||||
v2 += val[i] - mean;
|
||||
v2 = sqr(v2) / n;
|
||||
variance = (v1 - v2) / (n - 1);
|
||||
if(variance < 0)
|
||||
variance = 0.;
|
||||
stddev = sqrt(variance);
|
||||
/*
|
||||
* Skewness and kurtosis
|
||||
*/
|
||||
if (stddev != 0) {
|
||||
for (i = 0; i < n; i++) {
|
||||
v = (val[i] - mean) / stddev;
|
||||
v2 = sqr(v);
|
||||
skewness = skewness + v2 * v;
|
||||
kurtosis = kurtosis + sqr(v2);
|
||||
}
|
||||
skewness /= n;
|
||||
kurtosis = kurtosis / n - 3.;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
147
pimath.h
Executable file → Normal file
147
pimath.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Math
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -22,18 +22,37 @@
|
||||
|
||||
#include "picontainers.h"
|
||||
#ifndef QNX
|
||||
# include <cmath>
|
||||
# include <complex>
|
||||
# include <cmath>
|
||||
#else
|
||||
# include <math.h>
|
||||
# include <complex.h>
|
||||
#endif
|
||||
#ifdef CC_VC
|
||||
#define M_PI 3.14159265358979323846
|
||||
# include <math.h>
|
||||
#endif
|
||||
|
||||
#define M_2PI 6.28318530717958647692
|
||||
#define M_PI_3 1.04719755119659774615
|
||||
#ifndef M_LN2
|
||||
# define M_LN2 0.69314718055994530942
|
||||
#endif
|
||||
#ifndef M_LN10
|
||||
# define M_LN10 2.30258509299404568402
|
||||
#endif
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
#ifndef M_2PI
|
||||
# define M_2PI 6.28318530717958647692
|
||||
#endif
|
||||
#ifndef M_PI_3
|
||||
# define M_PI_3 1.04719755119659774615
|
||||
#endif
|
||||
#ifndef M_2PI_3
|
||||
# define M_2PI_3 2.0943951023931954923
|
||||
#endif
|
||||
#ifndef M_180_PI
|
||||
# define M_180_PI 57.2957795130823208768
|
||||
#endif
|
||||
#ifndef M_PI_180
|
||||
# define M_PI_180 1.74532925199432957692e-2
|
||||
#endif
|
||||
|
||||
using std::complex;
|
||||
|
||||
@@ -48,30 +67,47 @@ const complexd complexd_i(0., 1.);
|
||||
const complexd complexd_0(0.);
|
||||
const complexd complexd_1(1.);
|
||||
|
||||
const double deg2rad = atan(1.) / 45.;
|
||||
const double rad2deg = 45. / atan(1.);
|
||||
const double deg2rad = M_PI_180;
|
||||
const double rad2deg = M_180_PI;
|
||||
|
||||
inline int pow2(const int p) {return 1 << p;}
|
||||
inline double sqr(const double & v) {return v * v;}
|
||||
inline double sinc(const double & v) {double t = M_PI * v; return sin(t) / t;}
|
||||
inline complexd round(const complexd & c) {return complexd(round(c.real()), round(c.imag()));}
|
||||
inline double sinc(const double & v) {if (v == 0.) return 1.; double t = M_PI * v; return sin(t) / t;}
|
||||
inline complexd round(const complexd & c) {return complexd(piRound<double>(c.real()), piRound<double>(c.imag()));}
|
||||
inline complexd floor(const complexd & c) {return complexd(floor(c.real()), floor(c.imag()));}
|
||||
inline complexd ceil(const complexd & c) {return complexd(ceil(c.real()), ceil(c.imag()));}
|
||||
inline complexd atanc(const complexd & c) {return -complexd(-0.5, 1.) * log((complexd_1 + complexd_i * c) / (complexd_1 - complexd_i * c));}
|
||||
inline complexd asinc(const complexd & c) {return -complexd_i * log(complexd_i * c + sqrt(complexd_1 - c * c));}
|
||||
inline complexd acosc(const complexd & c) {return -complexd_i * log(c + complexd_i * sqrt(complexd_1 - c * c));}
|
||||
#ifdef QNX
|
||||
#if CC_GCC_VERSION <= 0x025F
|
||||
inline complexd tan(const complexd & c) {return sin(c) / cos(c);}
|
||||
inline complexd tanh(const complexd & c) {return sinh(c) / cosh(c);}
|
||||
inline complexd log2(const complexd & c) {return log(c) / M_LN2;}
|
||||
inline complexd log10(const complexd & c) {return log(c) / M_LN10;}
|
||||
inline double j0(const double & v) {v;}
|
||||
inline double j0(const double & v) {return v;}
|
||||
inline double j1(const double & v) {v;}
|
||||
inline double jn(const int & n, const double & v) {v;}
|
||||
inline double y0(const double & v) {v;}
|
||||
inline double y1(const double & v) {v;}
|
||||
inline double yn(const int & n, const double & v) {v;}
|
||||
inline double jn(const int & n, const double & v) {return v;}
|
||||
inline double y0(const double & v) {return v;}
|
||||
inline double y1(const double & v) {return v;}
|
||||
inline double yn(const int & n, const double & v) {return v;}
|
||||
#endif
|
||||
inline double toDb(double val) {return 10. * log10(val);}
|
||||
inline double fromDb(double val) {return pow(10., val / 10.);}
|
||||
inline double toRad(double deg) {return deg * M_PI_180;}
|
||||
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));
|
||||
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));
|
||||
return result;
|
||||
}
|
||||
|
||||
template<uint Cols, uint Rows, typename Type>
|
||||
class PIMathMatrixT;
|
||||
@@ -103,7 +139,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 acos(angleCos(v)) * rad2deg;}
|
||||
Type angleDeg(const _CVector & v) const {return toGrad(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;}
|
||||
@@ -404,7 +440,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 acos(angleCos(v)) * rad2deg;}
|
||||
Type angleDeg(const _CVector & v) const {return toGrad(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;}
|
||||
@@ -669,13 +705,6 @@ typedef PIMathMatrix<double> PIMathMatrixd;
|
||||
#undef PIMM_FOR_R
|
||||
|
||||
|
||||
/*
|
||||
Fast Fourier Transformation: direct (complement= false)
|
||||
and complement (complement = true). 'x' is data source.
|
||||
'x' contains 2^T items.
|
||||
*/
|
||||
void fft(complexd * x, int T, bool complement);
|
||||
|
||||
/// Differential evaluations
|
||||
|
||||
struct TransferFunction { // Для задания передаточной функции
|
||||
@@ -744,4 +773,68 @@ private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
class PIFFT
|
||||
{
|
||||
public:
|
||||
PIFFT();
|
||||
// const PIVector<uint> & getIndexes() {return indexes;}
|
||||
// const PIVector<complexd> & getCoefs() {return coefs;}
|
||||
PIVector<complexd> * calcFFT(const PIVector<complexd> &val);
|
||||
PIVector<complexd> * calcFFT(const PIVector<double> &val);
|
||||
PIVector<complexd> * calcFFTinverse(const PIVector<complexd> &val);
|
||||
PIVector<complexd> * calcHilbert(const PIVector<double> &val);
|
||||
PIVector<double> getAmplitude();
|
||||
private:
|
||||
// PIVector<uint> indexes;
|
||||
// PIVector<complexd> coefs;
|
||||
PIVector<complexd> result;
|
||||
// uint iterations;
|
||||
bool prepared;
|
||||
// uint out_size;
|
||||
typedef ptrdiff_t ae_int_t;
|
||||
void calc_coefs(uint cnt2);
|
||||
void calc_indexes(uint cnt2, uint deep2);
|
||||
complexd coef(uint n, uint k);
|
||||
|
||||
struct ftplan {
|
||||
PIVector<int> plan;
|
||||
PIVector<double> precomputed;
|
||||
PIVector<double> tmpbuf;
|
||||
PIVector<double> stackbuf;
|
||||
};
|
||||
|
||||
ftplan curplan;
|
||||
|
||||
void fftc1d(const PIVector<complexd> &a, uint n);
|
||||
void fftc1r(const PIVector<double> &a, uint n);
|
||||
void fftc1dinv(const PIVector<complexd> &a, uint n);
|
||||
|
||||
void createPlan(uint n);
|
||||
void ftbasegeneratecomplexfftplan(uint n, ftplan *plan);
|
||||
void ftbase_ftbasegenerateplanrec(int n, int tasktype, ftplan *plan, int *plansize, int *precomputedsize, int *planarraysize, int *tmpmemsize, int *stackmemsize, ae_int_t stackptr, int debugi=0);
|
||||
void ftbase_ftbaseprecomputeplanrec(ftplan *plan, int entryoffset, ae_int_t stackptr);
|
||||
void ftbasefactorize(int n, int *n1, int *n2);
|
||||
void ftbase_ftbasefindsmoothrec(int n, int seed, int leastfactor, int *best);
|
||||
int ftbasefindsmooth(int n);
|
||||
void ftbaseexecuteplan(PIVector<double> *a, int aoffset, int n, ftplan *plan);
|
||||
void ftbaseexecuteplanrec(PIVector<double> *a, int aoffset, ftplan *plan, int entryoffset, ae_int_t stackptr);
|
||||
void ftbase_internalcomplexlintranspose(PIVector<double> *a, int m, int n, int astart, PIVector<double> *buf);
|
||||
void ftbase_ffticltrec(PIVector<double> *a, int astart, int astride, PIVector<double> *b, int bstart, int bstride, int m, int n);
|
||||
void ftbase_internalreallintranspose(PIVector<double> *a, int m, int n, int astart, PIVector<double> *buf);
|
||||
void ftbase_fftirltrec(PIVector<double> *a, int astart, int astride, PIVector<double> *b, int bstart, int bstride, int m, int n);
|
||||
void ftbase_ffttwcalc(PIVector<double> *a, int aoffset, int n1, int n2);
|
||||
};
|
||||
|
||||
|
||||
class PIStatistic {
|
||||
public:
|
||||
PIStatistic();
|
||||
bool calculate(const PIVector<double> &val);
|
||||
double mean;
|
||||
double variance;
|
||||
double skewness;
|
||||
double kurtosis;
|
||||
};
|
||||
|
||||
#endif // PIMATH_H
|
||||
|
||||
2
pimonitor.cpp
Executable file → Normal file
2
pimonitor.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Counter of some PIP types
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pimonitor.h
Executable file → Normal file
2
pimonitor.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Counter of some PIP types
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
6
pimultiprotocol.h
Executable file → Normal file
6
pimultiprotocol.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Multiprotocol
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -81,9 +81,9 @@ public:
|
||||
PIString secondChannelName() {if (count() == 2) return protocol(1)->receiverDeviceName() + " -> " + protocol(0)->senderDeviceName(); return "Config error";}
|
||||
|
||||
ullong receiveCount() {if (count() == 2) return protocol(0)->receiveCount(); return 0;}
|
||||
ullong * receiveCount_ptr() {if (count() == 2) return protocol(0)->receiveCount_ptr(); return 0;}
|
||||
const ullong * receiveCount_ptr() {if (count() == 2) return protocol(0)->receiveCount_ptr(); return 0;}
|
||||
ullong sendCount() {if (count() == 2) return protocol(0)->sendCount(); return 0;}
|
||||
ullong * sendCount_ptr() {if (count() == 2) return protocol(0)->sendCount_ptr(); return 0;}
|
||||
const ullong * sendCount_ptr() {if (count() == 2) return protocol(0)->sendCount_ptr(); return 0;}
|
||||
|
||||
private:
|
||||
void received(PIProtocol * prot, bool , uchar * data, int size) {if (prot == protocol(0)) protocol(1)->send(data, size); else protocol(0)->send(data, size);}
|
||||
|
||||
2
pimutex.h
Executable file → Normal file
2
pimutex.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Mutex
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
piobject.cpp
Executable file → Normal file
2
piobject.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
120
piobject.h
Executable file → Normal file
120
piobject.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -22,37 +22,62 @@
|
||||
|
||||
#include "pistring.h"
|
||||
|
||||
//#ifdef CC_VC
|
||||
//#define HANDLER(c,s) #s,PIObject::handlerPtr<c>((void(c::*)())&c::s)
|
||||
//#else
|
||||
//#define HANDLER(c,s) #s,(void*)&c::s
|
||||
//#endif
|
||||
|
||||
//#define EVENT_HANDLER0(obj, name) static void __stat_##name##__(obj * o) {o->name();} void name()
|
||||
//#define EVENT_HANDLER1(obj, name, a0, n0) static void __stat_##name##__(obj * o, a0 n0) {o->name(n0);} void name(a0 n0)
|
||||
//#define EVENT_HANDLER2(obj, name, a0, n0, a1, n1) static void __stat_##name##__(obj * o, a0 n0, a1 n1) {o->name(n0, n1);} void name(a0 n0, a1 n1)
|
||||
|
||||
#define EVENT_HANDLER0(obj, ret, name) static ret __stat_##name##__(void * o) {return ((obj*)o)->name();} ret name()
|
||||
#define EVENT_HANDLER1(obj, ret, name, a0, n0) static ret __stat_##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_##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_##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_##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)
|
||||
/// 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)
|
||||
#define EVENT_HANDLER EVENT_HANDLER0
|
||||
|
||||
#define EVENT_VHANDLER0(obj, ret, name) static ret __stat_##name##__(void * o) {return ((obj*)o)->name();} virtual ret name()
|
||||
#define EVENT_VHANDLER1(obj, ret, name, a0, n0) static ret __stat_##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_##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_##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_##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)
|
||||
/// 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)
|
||||
#define EVENT_VHANDLER EVENT_VHANDLER0
|
||||
|
||||
#define CONNECT0(ret, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*))(&(dst)->__stat_##handler##__));
|
||||
#define CONNECT1(ret, a0, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0))(&(dst)->__stat_##handler##__));
|
||||
#define CONNECT2(ret, a0, a1, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0, a1))(&(dst)->__stat_##handler##__));
|
||||
#define CONNECT3(ret, a0, a1, a2, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2))(&(dst)->__stat_##handler##__));
|
||||
#define CONNECT4(ret, a0, a1, a2, a3, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dst)->__stat_##handler##__));
|
||||
/// 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);}
|
||||
#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);
|
||||
#define RAISE_EVENT3(src, event, v0, v1, v2) (src)->event(v0, v1, v2);
|
||||
#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 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_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 DISCONNECT DISCONNECT0
|
||||
|
||||
class PIObject
|
||||
{
|
||||
friend class PIObjectManager;
|
||||
@@ -109,24 +134,34 @@ public:
|
||||
}
|
||||
*/
|
||||
/// Direct connect
|
||||
static void connect(PIObject * src, const PIString & sig, void * dest, void * ev_h) {src->connections << Connection(ev_h, sig, dest);}
|
||||
//static void connect(PIObject & src, const PIString & sig, PIObject * dest, void * ev_h) {src.connections << Connection(ev_h, sig, dest);}
|
||||
//static void connect(PIObject * src, const PIString & sig, PIObject & dest, void * ev_h) {src->connections << Connection(ev_h, sig, &dest);}
|
||||
//static void connect(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, void * dest, void * ev_h) {src->connections << Connection(ev_h, 0, sig, dest);}
|
||||
static void piConnect(PIObject * src, const PIString & sig, void * dest, void * ev_h, void * e_h) {src->connections << Connection(ev_h, e_h, sig, dest);}
|
||||
static void piDisconnect(PIObject * src, const PIString & sig, void * dest, void * ev_h) {
|
||||
for (int i = 0; i < src->connections.size_s(); ++i) {
|
||||
Connection & cc(src->connections[i]);
|
||||
if (cc.event == sig && cc.dest == dest && cc.slot == ev_h) {
|
||||
src->connections.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
//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);}
|
||||
|
||||
/*/// Connect through manager
|
||||
static bool connect(const PIString & srcObject, const PIString & event, const PIString & destObject, const PIString & handler, bool force = false) {
|
||||
static bool piConnect(const PIString & srcObject, const PIString & event, const PIString & destObject, const PIString & handler, bool force = false) {
|
||||
PIObject * src = findByName(srcObject);
|
||||
if (src == 0) {
|
||||
cout << "PIObject::connect: can`t find PIObject with \"" << srcObject << "\" name!" << endl;
|
||||
cout << "PIObject::piConnect: can`t find PIObject with \"" << srcObject << "\" name!" << endl;
|
||||
return false;
|
||||
}
|
||||
PIObject * dest = findByName(destObject);
|
||||
if (dest == 0) {
|
||||
cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
|
||||
cout << "PIObject::piConnect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
|
||||
return false;
|
||||
}
|
||||
return PIObject::connect(src, event, dest, handler, force);
|
||||
return PIObject::piConnect(src, event, dest, handler, force);
|
||||
}*/
|
||||
|
||||
/// Raise events
|
||||
@@ -195,7 +230,7 @@ public:
|
||||
static void raiseEvent(const PIString & destObject, const PIString & name) {
|
||||
PIObject * dest = findByName(destObject);
|
||||
if (dest == 0) {
|
||||
cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
|
||||
cout << "PIObject::piConnect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
|
||||
return;
|
||||
}
|
||||
raiseEvent(dest, name);
|
||||
@@ -204,7 +239,7 @@ public:
|
||||
static void raiseEvent(const PIString & destObject, const PIString & name, const T0 & v0 = T0()) {
|
||||
PIObject * dest = findByName(destObject);
|
||||
if (dest == 0) {
|
||||
cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
|
||||
cout << "PIObject::piConnect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
|
||||
return;
|
||||
}
|
||||
raiseEvent<T0>(dest, name, v0);
|
||||
@@ -213,7 +248,7 @@ public:
|
||||
static void raiseEvent(const PIString & destObject, const PIString & name, const T0 & v0 = T0(), const T1 & v1 = T1()) {
|
||||
PIObject * dest = findByName(destObject);
|
||||
if (dest == 0) {
|
||||
cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
|
||||
cout << "PIObject::piConnect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
|
||||
return;
|
||||
}
|
||||
raiseEvent<T0, T1>(dest, name, v0, v1);
|
||||
@@ -222,7 +257,7 @@ public:
|
||||
static void raiseEvent(const PIString & destObject, const PIString & name, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2()) {
|
||||
PIObject * dest = findByName(destObject);
|
||||
if (dest == 0) {
|
||||
cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
|
||||
cout << "PIObject::piConnect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
|
||||
return;
|
||||
}
|
||||
raiseEvent<T0, T1, T2>(name, dest, v0, v1, v2);
|
||||
@@ -231,21 +266,24 @@ public:
|
||||
static void raiseEvent(const PIString & destObject, const PIString & name, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2(), const T3 & v3 = T3()) {
|
||||
PIObject * dest = findByName(destObject);
|
||||
if (dest == 0) {
|
||||
cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
|
||||
cout << "PIObject::piConnect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
|
||||
return;
|
||||
}
|
||||
raiseEvent<T0, T1, T2, T3>(name,dest , v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
protected:
|
||||
PIString name_;
|
||||
|
||||
private:
|
||||
struct Connection {
|
||||
Connection(void * s = 0, const PIString & e = PIString(), void * o = 0) {slot = s; event = e; dest = o;}
|
||||
Connection(void * sl = 0, void * si = 0, const PIString & e = PIString(), void * o = 0) {slot = sl; signal = si; event = e; dest = o;}
|
||||
void * slot;
|
||||
void * signal;
|
||||
PIString event;
|
||||
void * dest;
|
||||
};
|
||||
|
||||
PIString name_;
|
||||
PIVector<Connection> connections;
|
||||
|
||||
static PIVector<PIObject * > objects;
|
||||
|
||||
4
pip.h
Executable file → Normal file
4
pip.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
All includes
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -27,3 +27,5 @@
|
||||
#include "pisignals.h"
|
||||
#include "piobject.h"
|
||||
#include "pisystemmonitor.h"
|
||||
#include "pipeer.h"
|
||||
#include "picrc.h"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Packets extractor
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -23,9 +23,10 @@
|
||||
PIPacketExtractor::PIPacketExtractor(PIIODevice * device_, void * recHeaderPtr, int recHeaderSize, int recDataSize) {
|
||||
ret_func_header = 0;
|
||||
setPacketData(recHeaderPtr, recHeaderSize, recDataSize);
|
||||
setBufferSize(4096);
|
||||
setThreadedReadBufferSize(65536);
|
||||
setBufferSize(65536);
|
||||
setDevice(device_);
|
||||
allReaded = addSize = curInd = 0;
|
||||
allReaded = addSize = curInd = missed = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +56,8 @@ bool PIPacketExtractor::threadedRead(uchar * readed, int size_) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
memcpy(mheader.data(), buffer.data(curInd + headerSize), headerSize);
|
||||
memcpy(mheader.data(), buffer.data(curInd), headerSize);
|
||||
if (headerPtr != 0) memcpy(headerPtr, buffer.data(curInd), headerSize);
|
||||
if (!packetValidate(buffer.data(curInd + headerSize), dataSize)) {
|
||||
curInd++; missed++;
|
||||
if (packetSize > 0) missed_packets = missed / packetSize;
|
||||
@@ -65,11 +67,18 @@ bool PIPacketExtractor::threadedRead(uchar * readed, int size_) {
|
||||
memcpy(buffer.data(), sbuffer.data(packetSize + curInd), allReaded);
|
||||
allReaded -= packetSize + curInd;
|
||||
curInd = addSize = 0;
|
||||
} else {
|
||||
if (dataSize == 0) {
|
||||
packetValidate(buffer.data(), size_);
|
||||
memcpy(sbuffer.data(), buffer.data(), allReaded);
|
||||
memcpy(buffer.data(), sbuffer.data(size_), allReaded);
|
||||
allReaded -= size_;
|
||||
} else {
|
||||
packetValidate(buffer.data(), dataSize);
|
||||
memcpy(sbuffer.data(), buffer.data(), allReaded);
|
||||
memcpy(buffer.data(), sbuffer.data(packetSize), allReaded);
|
||||
allReaded -= packetSize;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Packets extractor
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -30,18 +30,19 @@ class PIPacketExtractor: public PIIODevice
|
||||
{
|
||||
public:
|
||||
PIPacketExtractor(PIIODevice * device_ = 0, void * recHeaderPtr = 0, int recHeaderSize = 0, int recDataSize = 0);
|
||||
virtual ~PIPacketExtractor() {}
|
||||
|
||||
PIIODevice * device() {return dev;}
|
||||
void setDevice(PIIODevice * device_);
|
||||
|
||||
int bufferSize() const {return buffer_size;}
|
||||
void setBufferSize(int new_size) {buffer_size = new_size; buffer.resize(buffer_size); sbuffer.resize(buffer_size);}
|
||||
void setBufferSize(int new_size) {buffer_size = new_size; buffer.resize(buffer_size); sbuffer.resize(buffer_size); memset(buffer.data(), 0, buffer.size()); memset(sbuffer.data(), 0, sbuffer.size());}
|
||||
|
||||
void setHeaderCheckSlot(HeaderCheckFunc f) {ret_func_header = f;}
|
||||
void setPacketData(void * recHeaderPtr, int recHeaderSize, int recDataSize) {headerPtr = recHeaderPtr; headerSize = recHeaderSize; dataSize = recDataSize; packetSize = headerSize + dataSize; if (headerSize > 0) mheader.resize(headerSize);}
|
||||
|
||||
ullong missedBytes() const {return missed;}
|
||||
ullong missedPackets() const {return missed / packetSize;}
|
||||
ullong missedPackets() const {if (packetSize == 0) return missed; return missed / packetSize;}
|
||||
const ullong * missedBytes_ptr() const {return &missed;}
|
||||
const ullong * missedPackets_ptr() const {return &missed_packets;}
|
||||
|
||||
@@ -56,7 +57,7 @@ protected:
|
||||
|
||||
private:
|
||||
bool threadedRead(uchar * readed, int size);
|
||||
bool openDevice() {if (dev == 0) return false; return dev->isOpened();}
|
||||
bool openDevice() {if (dev == 0) return false; return dev->open();}
|
||||
|
||||
PIIODevice * dev;
|
||||
PIByteArray mheader, buffer, sbuffer;
|
||||
|
||||
186
pipeer.cpp
Normal file
186
pipeer.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Peer - named I/O ethernet node
|
||||
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 "pipeer.h"
|
||||
|
||||
|
||||
PIPeer::PIPeer(const PIString & name): PIEthernet() {
|
||||
setName(name);
|
||||
setParameter(PIEthernet::Broadcast);
|
||||
setReadPort(13312);
|
||||
setSendPort(13312);
|
||||
srand(uint(PITimer::elapsed_system_m()));
|
||||
//id_ = name() + "_" + PIString::fromNumber(rand());
|
||||
CONNECT2(void, void * , int, &timer, timeout, this, timerEvent);
|
||||
|
||||
PIEthernet * ce;
|
||||
PIStringList sl = PIEthernet::allAddresses();
|
||||
PIString ta;
|
||||
self_info.name = name_;
|
||||
self_info.dist = 0;
|
||||
piForeachC (PIString & i, sl) {
|
||||
ce = new PIEthernet(this, func_readed);
|
||||
ce->setReadAddress(i, 13313);
|
||||
eths << ce;
|
||||
ce->startThreadedRead();
|
||||
self_info.addresses << i;
|
||||
//cout << i << ": " << ta << endl;
|
||||
}
|
||||
eth_send = new PIEthernet();
|
||||
eth_send->initialize();
|
||||
|
||||
startThreadedRead();
|
||||
//joinMulticastGroup("239.13.3.12");
|
||||
//timer.addDelimiter(5);
|
||||
timer.start(1000);
|
||||
sendSelfInfo();
|
||||
}
|
||||
|
||||
|
||||
PIPeer::~PIPeer() {
|
||||
terminate();
|
||||
sendSelfRemove();
|
||||
//leaveMulticastGroup("239.13.3.12");
|
||||
delete eth_send;
|
||||
piForeach (PIEthernet * i, eths)
|
||||
delete i;
|
||||
eths.clear();
|
||||
}
|
||||
|
||||
|
||||
void PIPeer::timerEvent(void * data, int delim) {
|
||||
switch (delim) {
|
||||
case 1: // 5 s
|
||||
syncPeers();
|
||||
break;
|
||||
}
|
||||
//send("broadcast", 9);
|
||||
}
|
||||
|
||||
|
||||
bool PIPeer::threadedRead(uchar * data, int size) {
|
||||
int header;
|
||||
PeerInfo pi;
|
||||
PIByteArray ba(data, size);
|
||||
PIVector<PeerInfo> rpeers;
|
||||
ba >> header >> pi.name;
|
||||
if (pi.name == name_) return true;
|
||||
switch (header) {
|
||||
case 1: // new peer accepted
|
||||
if (hasPeer(pi.name)) break;
|
||||
ba >> pi.dist >> pi.addresses;
|
||||
pi.sync = 0;
|
||||
peers << pi;
|
||||
cout << "[PIPeer \"" + name_ + "\"] new peer \"" << pi.name << "\"" << " dist " << pi.dist << endl;
|
||||
pi.dist++;
|
||||
sendSelfInfo();
|
||||
sendPeerInfo(pi);
|
||||
findNearestAddresses();
|
||||
break;
|
||||
case 2: // remove peer accepted
|
||||
if (removePeer(pi.name)) {
|
||||
cout << "[PIPeer \"" + name_ + "\"] remove peer \"" << pi.name << "\"" << endl;
|
||||
sendPeerRemove(pi.name);
|
||||
findNearestAddresses();
|
||||
}
|
||||
break;
|
||||
case 3: // sync peers
|
||||
ba >> pi.addresses >> rpeers;
|
||||
rpeers << pi;
|
||||
//cout << "[PIPeer \"" + name_ + "\"] rec sync " << rpeers.size_s() << " peers" << endl;
|
||||
for (uint i = 0; i < rpeers.size(); ++i) {
|
||||
PeerInfo & rpeer(rpeers[i]);
|
||||
//cout << " to sync " << rpeer.name << endl;
|
||||
if (rpeer.name == name_) continue;
|
||||
bool exist = false;
|
||||
for (uint j = 0; j < peers.size(); ++j) {
|
||||
PeerInfo & peer(peers[j]);
|
||||
if (peer.name == rpeer.name) {
|
||||
//cout << "synced " << peer.name << endl;
|
||||
peer.addresses == rpeer.addresses;
|
||||
if (peer.name == pi.name) peer.sync = 0;
|
||||
exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (exist) continue;
|
||||
peers << rpeer;
|
||||
peers.back().dist++;
|
||||
findNearestAddresses();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIPeer::func_readed(void * peer, uchar * data, int size) {
|
||||
PIPeer * p = (PIPeer * )peer;
|
||||
cout << "[PIPeer \"" + p->name_ + "\"] received " << data << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PIPeer::sendPeerInfo(const PeerInfo & info) {
|
||||
PIByteArray ba;
|
||||
ba << int(1) << info.name << info.dist << info.addresses;
|
||||
write(ba);
|
||||
}
|
||||
|
||||
|
||||
void PIPeer::sendPeerRemove(const PIString & peer) {
|
||||
PIByteArray ba;
|
||||
ba << int(2) << peer;
|
||||
write(ba);
|
||||
}
|
||||
|
||||
|
||||
void PIPeer::syncPeers() {
|
||||
//cout << "[PIPeer \"" + name_ + "\"] sync " << peers.size_s() << " peers" << endl;
|
||||
PIString pn;
|
||||
for (uint i = 0; i < peers.size(); ++i) {
|
||||
PeerInfo & cp(peers[i]);
|
||||
if (cp.sync > 1 && cp.dist == 0) {
|
||||
pn = cp.name;
|
||||
cout << "[PIPeer \"" + name_ + "\"] sync: remove " << pn << endl;
|
||||
peers.remove(i);
|
||||
sendPeerRemove(pn);
|
||||
--i;
|
||||
findNearestAddresses();
|
||||
continue;
|
||||
}
|
||||
cp.sync++;
|
||||
}
|
||||
PIByteArray ba;
|
||||
ba << int(3) << self_info.name << self_info.addresses << peers;
|
||||
write(ba);
|
||||
}
|
||||
|
||||
|
||||
void PIPeer::findNearestAddresses() {
|
||||
cout << "[PIPeer \"" + name_ + "\"] findNearestAddresses" << endl;
|
||||
int max_dist = -1;
|
||||
piForeach (PeerInfo & i, peers)
|
||||
if (max_dist < i.dist)
|
||||
max_dist = i.dist;
|
||||
PIVector<PeerInfo * > cwave;
|
||||
for (int d = 0; d <= max_dist; ++d) {
|
||||
//if ()
|
||||
}
|
||||
}
|
||||
81
pipeer.h
Normal file
81
pipeer.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Peer - named I/O ethernet node
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef PIPEER_H
|
||||
#define PIPEER_H
|
||||
|
||||
#include "piethernet.h"
|
||||
|
||||
class PIPeer: public PIEthernet
|
||||
{
|
||||
struct PeerInfo;
|
||||
friend PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v);
|
||||
friend PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v);
|
||||
public:
|
||||
PIPeer(const PIString & name);
|
||||
~PIPeer();
|
||||
|
||||
//const PIString & id() const {return id_;}
|
||||
|
||||
protected:
|
||||
bool threadedRead(uchar * readed, int size);
|
||||
|
||||
private:
|
||||
EVENT_HANDLER2(PIPeer, void, timerEvent, void * , data, int, delim);
|
||||
static bool func_readed(void * peer, uchar * data, int size);
|
||||
|
||||
struct PeerInfo {
|
||||
PIString name;
|
||||
PIString nearest_address;
|
||||
PIStringList addresses;
|
||||
int dist;
|
||||
int sync;
|
||||
int _wave;
|
||||
};
|
||||
|
||||
|
||||
bool hasPeer(const PIString & name) {piForeachC (PeerInfo & i, peers) if (i.name == name) return true; return false;}
|
||||
bool removePeer(const PIString & name) {for (uint i = 0; i < peers.size(); ++i) if (peers[i].name == name) {peers.remove(i); return true;} return false;}
|
||||
|
||||
void sendPeerInfo(const PeerInfo & info);
|
||||
void sendPeerRemove(const PIString & peer);
|
||||
void sendSelfInfo() {sendPeerInfo(self_info);}
|
||||
void sendSelfRemove() {sendPeerRemove(name_);}
|
||||
void syncPeers();
|
||||
void findNearestAddresses();
|
||||
|
||||
struct PeerPacket {
|
||||
int header; // 1 - new peer, 2 - remove peer, 3 - sync peers
|
||||
|
||||
};
|
||||
|
||||
PIList<PIEthernet * > eths;
|
||||
PIEthernet * eth_send;
|
||||
PITimer timer;
|
||||
|
||||
PeerInfo self_info;
|
||||
PIVector<PeerInfo> peers;
|
||||
//PIString id_;
|
||||
|
||||
};
|
||||
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v) {s << v.name << v.addresses << v.dist; return s;}
|
||||
inline PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v) {s >> v.name >> v.addresses >> v.dist; return s;}
|
||||
|
||||
#endif // PIPEER_H
|
||||
29
piprocess.cpp
Executable file → Normal file
29
piprocess.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Process
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -55,7 +55,7 @@ void PIProcess::run() {
|
||||
//cout << "run" << endl;
|
||||
string str;
|
||||
/// arguments convertion
|
||||
int as = 0;
|
||||
as = 0;
|
||||
#ifdef WINDOWS
|
||||
//args.pop_front();
|
||||
piForeachC (PIString & i, args)
|
||||
@@ -96,30 +96,31 @@ void PIProcess::run() {
|
||||
f_in = PIFile::openTemporary(PIIODevice::ReadWrite);
|
||||
t_in = true;
|
||||
}
|
||||
f_in.open(PIIODevice::ReadWrite); f_in.close();
|
||||
//f_in.open(PIIODevice::ReadWrite); f_in.close();
|
||||
if (f_out.path().isEmpty()) {
|
||||
f_out = PIFile::openTemporary(PIIODevice::ReadWrite);
|
||||
t_out = true;
|
||||
}
|
||||
f_out.open(PIIODevice::WriteOnly); f_out.close();
|
||||
//f_out.open(PIIODevice::WriteOnly); f_out.close();
|
||||
if (f_err.path().isEmpty()) {
|
||||
f_err = PIFile::openTemporary(PIIODevice::ReadWrite);
|
||||
t_err = true;
|
||||
}
|
||||
f_err.open(PIIODevice::WriteOnly); f_err.close();
|
||||
//f_err.open(PIIODevice::WriteOnly); f_err.close();
|
||||
|
||||
str = args.front().stdString();
|
||||
is_exec = true;
|
||||
execStarted(PIString(str));
|
||||
#ifndef WINDOWS
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
#endif
|
||||
FILE * tf = 0;
|
||||
//cout << "exec" << endl;
|
||||
tf_in = tf_out = tf_err = 0;
|
||||
//cout << "exec " << tf_in << ", " << tf_out << ", " << tf_err << endl;
|
||||
//cout << f_out.path() << endl;
|
||||
if (g_in) tf = freopen(f_in.path().data(), "r", stdin);
|
||||
if (g_out) tf = freopen(f_out.path().data(), "w", stdout);
|
||||
if (g_err) tf = freopen(f_err.path().data(), "w", stderr);
|
||||
if (g_in) tf_in = freopen(f_in.path().data(), "r", stdin);
|
||||
if (g_out) tf_out = freopen(f_out.path().data(), "w", stdout);
|
||||
if (g_err) tf_err = freopen(f_err.path().data(), "w", stderr);
|
||||
#ifndef WINDOWS
|
||||
if (!wd.isEmpty()) as = chdir(wd.data());
|
||||
#endif
|
||||
@@ -142,16 +143,22 @@ void PIProcess::run() {
|
||||
} else
|
||||
piCout << "[PIProcess] \"CreateProcess\" error, " << errorString() << endl;
|
||||
#else
|
||||
|
||||
//cout << "exec " << tf_in << ", " << tf_out << ", " << tf_err << endl;
|
||||
if (execve(str.c_str(), a, e) < 0)
|
||||
piCout << "[PIProcess] \"execve\" error, " << errorString() << endl;
|
||||
} else {
|
||||
msleep(1);
|
||||
//cout << "wait" << endl;
|
||||
wait(&exit_code);
|
||||
/*if (tf_in != 0) fclose(tf_in);
|
||||
if (tf_out != 0) fclose(tf_out);
|
||||
if (tf_err != 0) fclose(tf_err);*/
|
||||
pid = 0;
|
||||
//cout << "wait done" << endl;
|
||||
}
|
||||
#endif
|
||||
execFinished(PIString(str), exit_code);
|
||||
is_exec = false;
|
||||
for (int i = 0; i < env.size_s(); ++i)
|
||||
delete e[i];
|
||||
@@ -162,7 +169,7 @@ void PIProcess::run() {
|
||||
for (int i = 0; i < args.size_s(); ++i)
|
||||
delete a[i];
|
||||
#endif
|
||||
//cout << "end" << endl;
|
||||
//cout << "end " << tf_in << ", " << tf_out << ", " << tf_err << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
37
piprocess.h
Executable file → Normal file
37
piprocess.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Process
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -28,6 +28,18 @@
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
/// events:
|
||||
/// execStarted(PIString program)
|
||||
/// execFinished(PIString program, int exit_code)
|
||||
///
|
||||
/// handlers:
|
||||
/// bool exec(const PIString & program)
|
||||
/// bool exec(const PIString & program, const PIString & arg1)
|
||||
/// bool exec(const PIString & program, const PIString & arg1, const PIString & arg2)
|
||||
/// bool exec(const PIString & program, const PIString & arg1, const PIString & arg2, const PIString & arg3)
|
||||
/// bool exec(const PIString & program, const PIStringList & args)
|
||||
/// void terminate()
|
||||
/// bool waitForFinish(int timeout_msecs = 60000)
|
||||
class PIProcess: private PIThread
|
||||
{
|
||||
public:
|
||||
@@ -53,17 +65,18 @@ public:
|
||||
PIString workingDirectory() const {return wd;}
|
||||
void setWorkingDirectory(const PIString & path) {wd = path;}
|
||||
void resetWorkingDirectory() {wd.clear();}
|
||||
void exec(const PIString & program) {args.clear(); args << program; exec_();}
|
||||
void exec(const PIString & program, const PIString & arg) {args.clear(); args << program << arg; exec_();}
|
||||
void exec(const PIString & program, const PIString & arg1, const PIString & arg2) {args.clear(); args << program << arg1 << arg2; exec_();}
|
||||
void exec(const PIString & program, const PIString & arg1, const PIString & arg2, const PIString & arg3) {args.clear(); args << program << arg1 << arg2 << arg3; exec_();}
|
||||
void exec(const PIString & program, const PIStringList & args_) {args << program << args_; exec_();}
|
||||
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_();}
|
||||
#ifdef WINDOWS
|
||||
void terminate() {if (is_exec) if (!TerminateProcess(pi.hProcess, 0)) return; pi.dwProcessId = 0;}
|
||||
EVENT_HANDLER(PIProcess, void, terminate) {if (is_exec) if (!TerminateProcess(pi.hProcess, 0)) return; pi.dwProcessId = 0;}
|
||||
#else
|
||||
void terminate() {if (is_exec) kill(pid, SIGKILL); pid = 0;}
|
||||
EVENT_HANDLER(PIProcess, void, terminate) {if (is_exec) kill(pid, SIGKILL); pid = 0;}
|
||||
#endif
|
||||
bool waitForFinish(int timeout_msecs = 60000) {return PIThread::waitForFinish(timeout_msecs);}
|
||||
EVENT_HANDLER(PIProcess, bool, waitForFinish) {return waitForFinish(60000);}
|
||||
EVENT_HANDLER1(PIProcess, 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();}
|
||||
|
||||
@@ -79,6 +92,9 @@ public:
|
||||
static int currentPID() {return getpid();}
|
||||
#endif
|
||||
|
||||
EVENT1(PIProcess, execStarted, PIString, program)
|
||||
EVENT2(PIProcess, execFinished, PIString, program, int, exit_code)
|
||||
|
||||
private:
|
||||
virtual void run();
|
||||
void exec_();
|
||||
@@ -94,7 +110,8 @@ private:
|
||||
#else
|
||||
pid_t pid;
|
||||
#endif
|
||||
int exit_code, sz;
|
||||
FILE * tf_in, * tf_out, * tf_err;
|
||||
int exit_code, sz, as;
|
||||
bool is_exec;
|
||||
|
||||
};
|
||||
|
||||
145
piprotocol.cpp
Executable file → Normal file
145
piprotocol.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Protocol, input/output channel (COM, UDP)
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@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
|
||||
@@ -33,7 +33,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
int ps, gps;
|
||||
bool ok, gok, flag, gflag, has_dev = false;
|
||||
float freq, gfreq;
|
||||
PIFlags<PISerial::Parameters> pp;
|
||||
PIFlags<PISerial::Parameters> pp(0);
|
||||
PIConfig::Entry & b(conf.getValue(name)),
|
||||
& rb(b.getValue("receiver")),
|
||||
& sb(b.getValue("sender"));
|
||||
@@ -65,7 +65,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
}
|
||||
type_rec = PIProtocol::Ethernet;
|
||||
eth = new PIEthernet();
|
||||
packet_ext.setDevice(eth);
|
||||
packet_ext->setDevice(eth);
|
||||
//setSenderAddress(dev, ps);
|
||||
setReceiverAddress(dev, ps);
|
||||
has_dev = true;
|
||||
@@ -128,7 +128,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
pp |= PISerial::ParityControl;
|
||||
pp.setFlag(PISerial::ParityControl, flag);
|
||||
}
|
||||
flag = rb.getValue("twoStopBits", false, &ok);
|
||||
gflag = b.getValue("twoStopBits", false, &gok);
|
||||
@@ -139,12 +139,12 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
pp |= PISerial::TwoStopBits;
|
||||
pp.setFlag(PISerial::TwoStopBits, flag);
|
||||
}
|
||||
type_rec = PIProtocol::Serial;
|
||||
type_send = PIProtocol::Serial;
|
||||
ser = new PISerial(dev);
|
||||
packet_ext.setDevice(ser);
|
||||
packet_ext->setDevice(ser);
|
||||
//setSenderDevice(dev, (PISerial::Speed)ps);
|
||||
setReceiverDevice(dev, (PISerial::Speed)ps);
|
||||
ser->setInSpeed((PISerial::Speed)ps);
|
||||
@@ -297,7 +297,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
pp |= PISerial::ParityControl;
|
||||
pp.setFlag(PISerial::ParityControl, flag);
|
||||
}
|
||||
flag = sb.getValue("twoStopBits", false, &ok);
|
||||
gflag = b.getValue("twoStopBits", false, &gok);
|
||||
@@ -308,7 +308,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
pp |= PISerial::TwoStopBits;
|
||||
pp.setFlag(PISerial::TwoStopBits, flag);
|
||||
}
|
||||
} else {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.speed\" or \"" << name << ".speed\" in \"" << config << "\"!" << endl;
|
||||
@@ -365,14 +365,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
dataSize = recDataSize;
|
||||
sendDataPtr = (uchar * )sendDataPtr_;
|
||||
sendDataSize = sendDataSize_;
|
||||
packet_ext.setPacketData(recHeaderPtr, recHeaderSize, recDataSize);
|
||||
if (type_rec == PIProtocol::Ethernet) {
|
||||
if (recHeaderPtr != 0) {
|
||||
dataPtr = (uchar * )recHeaderPtr;
|
||||
dataSize = recHeaderSize + recDataSize;
|
||||
if (dataSize > 0) packet = new char[dataSize];
|
||||
} else if (recDataSize > 0) packet = new char[recDataSize];
|
||||
} else if (recHeaderSize + recDataSize > 0) packet = new char[recHeaderSize + recDataSize];
|
||||
packet_ext->setPacketData(recHeaderPtr, recHeaderSize, recDataSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -394,16 +387,18 @@ PIProtocol::~PIProtocol() {
|
||||
}
|
||||
delete diagTimer;
|
||||
delete sendTimer;
|
||||
if (packet != 0) delete packet;
|
||||
delete secTimer;
|
||||
if (eth != 0) delete eth;
|
||||
if (ser != 0) delete ser;
|
||||
delete packet_ext;
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::init() {
|
||||
packet_ext.setThreadedReadData(this);
|
||||
packet_ext.setThreadedReadSlot(receiveEvent);
|
||||
packet_ext.setHeaderCheckSlot(headerValidateEvent);
|
||||
packet_ext = new PIPacketExtractor();
|
||||
packet_ext->setThreadedReadData(this);
|
||||
packet_ext->setThreadedReadSlot(receiveEvent);
|
||||
packet_ext->setHeaderCheckSlot(headerValidateEvent);
|
||||
work = new_mp_prot = history_write_rec = history_write_send = false;
|
||||
eth = 0;
|
||||
ser = 0;
|
||||
@@ -412,18 +407,20 @@ void PIProtocol::init() {
|
||||
net_diag = PIProtocol::Unknown;
|
||||
cur_pckt = 0;
|
||||
diagTimer = 0;
|
||||
packet = 0;
|
||||
timeout_ = 3.f;
|
||||
sendTimer = new PITimer(sendEvent, this);
|
||||
diagTimer = new PITimer(diagEvent, this);
|
||||
secTimer = new PITimer(secEvent, this);
|
||||
wrong_count = receive_count = send_count = missed_count = 0;
|
||||
immediate_freq = integral_freq = 0.f;
|
||||
packets_in_sec = packets_out_sec = bytes_in_sec = bytes_out_sec = 0;
|
||||
immediate_freq = integral_freq = ifreq = 0.f;
|
||||
headerPtr = dataPtr = sendDataPtr = 0;
|
||||
headerSize = dataSize = sendDataSize = 0;
|
||||
type_rec = type_send = PIProtocol::None;
|
||||
devSenderState = devReceiverState = "Unknown";
|
||||
devSenderName = devReceiverName = "no device";
|
||||
history_rsize_rec = history_rsize_send = "no file";
|
||||
secTimer->start(1000.);
|
||||
/*addEvent("receiver started");
|
||||
addEvent("receiver stopped");
|
||||
addEvent("sender started");
|
||||
@@ -444,7 +441,7 @@ void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed spee
|
||||
type_send = type_rec = PIProtocol::Serial;
|
||||
if (ser == 0) {
|
||||
ser = new PISerial();
|
||||
packet_ext.setDevice(ser);
|
||||
packet_ext->setDevice(ser);
|
||||
}
|
||||
}
|
||||
if (type_rec == PIProtocol::Serial && ser != 0) {
|
||||
@@ -461,7 +458,7 @@ void PIProtocol::setReceiverAddress(const PIString & ip, int port, bool force) {
|
||||
type_rec = PIProtocol::Ethernet;
|
||||
if (eth == 0) {
|
||||
eth = new PIEthernet();
|
||||
packet_ext.setDevice(eth);
|
||||
packet_ext->setDevice(eth);
|
||||
}
|
||||
}
|
||||
if (type_rec == PIProtocol::Ethernet && eth != 0) {
|
||||
@@ -493,13 +490,38 @@ void PIProtocol::setSenderAddress(const PIString & ip, int port, bool force) {
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet && eth != 0) {
|
||||
eth->setSendAddress(ip, port);
|
||||
eth->open();
|
||||
if (ip.isEmpty()) devSenderName = "no ip";
|
||||
else devSenderName = ip + ":" + PIString::fromNumber(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::setSenderIP(const PIString & ip, bool force) {
|
||||
if (force) {
|
||||
type_send = PIProtocol::Ethernet;
|
||||
if (eth == 0) eth = new PIEthernet();
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet && eth != 0) {
|
||||
eth->setSendIP(ip);
|
||||
if (ip.isEmpty()) devSenderName = "no ip";
|
||||
else devSenderName = ip + ":" + PIString::fromNumber(eth->sendPort());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::setSenderPort(int port, bool force) {
|
||||
if (force) {
|
||||
type_send = PIProtocol::Ethernet;
|
||||
if (eth == 0) eth = new PIEthernet();
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet && eth != 0) {
|
||||
eth->setSendPort(port);
|
||||
if (eth->sendIP().isEmpty()) devSenderName = "no ip";
|
||||
else devSenderName = eth->sendIP() + ":" + PIString::fromNumber(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::setExpectedFrequency(float frequency) {
|
||||
exp_freq = frequency;
|
||||
changeDisconnectTimeout();
|
||||
@@ -517,29 +539,35 @@ void PIProtocol::startReceive(float exp_frequency) {
|
||||
if (exp_frequency > 0.f) exp_freq = exp_frequency;
|
||||
//if (type_rec == PIProtocol::Serial) ser->start();
|
||||
//if (type_rec == PIProtocol::Ethernet) eth->start();
|
||||
packet_ext->startThreadedRead();
|
||||
msleep(1);
|
||||
check_state();
|
||||
if (exp_freq <= 0.f) return;
|
||||
packet_ext.startThreadedRead();
|
||||
setExpectedFrequency(exp_freq);
|
||||
diagTimer->start(1000. / exp_freq);
|
||||
diagTimer->reset();
|
||||
raiseEvent(this, "receiver started");
|
||||
receiverStarted();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::startSend(float frequency) {
|
||||
//cout << "** start send " << send_freq << ", " << frequency << endl;
|
||||
if (frequency > 0.f) send_freq = frequency;
|
||||
msleep(1);
|
||||
check_state();
|
||||
if (send_freq <= 0.f) return;
|
||||
sendTimer->start(1000. / send_freq);
|
||||
raiseEvent(this, "sender started");
|
||||
diagTimer->reset();
|
||||
senderStarted();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::stopReceive() {
|
||||
//if (type_rec == PIProtocol::Serial) ser->stop();
|
||||
//if (type_rec == PIProtocol::Ethernet) eth->stop();
|
||||
packet_ext.stop();
|
||||
packet_ext->stop();
|
||||
diagTimer->stop();
|
||||
raiseEvent(this, "receiver stopped");
|
||||
receiverStopped();
|
||||
}
|
||||
|
||||
|
||||
@@ -553,15 +581,20 @@ bool PIProtocol::receiveEvent(void * t, uchar * data, int size) {
|
||||
p->history_file_rec.writeToBinLog(p->history_id_rec, data, size);
|
||||
p->history_rsize_rec.setReadableSize(p->history_file_rec.pos());
|
||||
}
|
||||
raiseEvent<bool>(p, "received", true);
|
||||
p->received(true);
|
||||
//p->unlock();
|
||||
p->ifreq = p->diagTimer->elapsed_m();
|
||||
if (p->ifreq > 0.) p->ifreq = 1000. / p->ifreq;
|
||||
p->diagTimer->reset();
|
||||
p->receive_count++;
|
||||
p->packets_in_sec++;
|
||||
p->bytes_in_sec += size;
|
||||
p->cur_pckt = 1;
|
||||
if (p->ret_func != 0) p->ret_func(p);
|
||||
if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, true, data, size);
|
||||
return true;
|
||||
}
|
||||
raiseEvent<bool>(p, "received", false);
|
||||
p->received(false);
|
||||
//p->unlock();
|
||||
p->wrong_count++;
|
||||
if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, false, data, size);
|
||||
@@ -569,19 +602,21 @@ bool PIProtocol::receiveEvent(void * t, uchar * data, int size) {
|
||||
}
|
||||
|
||||
|
||||
bool PIProtocol::headerValidateEvent(void * t, uchar * src, uchar * rec, int size) {
|
||||
PIProtocol * p = (PIProtocol * )t;
|
||||
//cout << "validate\n";
|
||||
return p->headerValidate(src, rec, size);
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::diagEvent(void * t, int) {
|
||||
PIProtocol * p = (PIProtocol * )t;
|
||||
p->calc_freq();
|
||||
p->calc_diag();
|
||||
p->check_state();
|
||||
if (p->ser != 0) p->missed_count = p->packet_ext.missedPackets();
|
||||
if (p->ser != 0) p->missed_count = p->packet_ext->missedPackets();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::secEvent(void * t, int ) {
|
||||
PIProtocol * p = (PIProtocol * )t;
|
||||
p->speedIn = PIString::readableSize(p->bytes_in_sec) + "/s";
|
||||
p->speedOut = PIString::readableSize(p->bytes_out_sec) + "/s";
|
||||
p->bytes_in_sec = p->bytes_out_sec = p->packets_in_sec = p->packets_out_sec = 0;
|
||||
if (p->ser != 0) p->missed_count = p->packet_ext->missedPackets();
|
||||
}
|
||||
|
||||
|
||||
@@ -608,17 +643,16 @@ 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);
|
||||
net_diag = diag;
|
||||
raiseEvent<PIProtocol::Quality>(this, "quality changed", diag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::calc_freq() {
|
||||
float tf = float(1000.f / diagTimer->elapsed_m());
|
||||
diagTimer->reset();
|
||||
if (cur_pckt != 1) tf = 0.f;
|
||||
immediate_freq = tf;
|
||||
float tf;// = float(1000.f / diagTimer->elapsed_m());
|
||||
tf = immediate_freq = ifreq;
|
||||
ifreq = 0.f;
|
||||
if (last_freq.size_s() >= pckt_cnt_max && last_freq.size_s() > 0) last_freq.pop_front();
|
||||
last_freq.push_back(tf);
|
||||
tf = last_freq[0];
|
||||
@@ -670,11 +704,17 @@ void PIProtocol::send(const void * data, int size, bool direct) {
|
||||
history_rsize_send.setReadableSize(history_file_send.pos());
|
||||
}
|
||||
if (type_send == PIProtocol::Serial)
|
||||
if (ser->send(data, size))
|
||||
if (ser->send(data, size)) {
|
||||
send_count++;
|
||||
packets_out_sec++;
|
||||
bytes_out_sec += size;
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet)
|
||||
if (eth->send(data, size))
|
||||
if (eth->send(data, size)) {
|
||||
send_count++;
|
||||
packets_out_sec++;
|
||||
bytes_out_sec += size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -682,6 +722,7 @@ void PIProtocol::send() {
|
||||
//lock();
|
||||
//memcpy(packet, sendDataPtr, sendDataSize);
|
||||
//unlock();
|
||||
//cout << "**send" << endl;
|
||||
if (!aboutSend()) return;
|
||||
if (sendDataPtr == 0 || sendDataSize == 0) return;
|
||||
if (history_write_send) {
|
||||
@@ -689,9 +730,15 @@ void PIProtocol::send() {
|
||||
history_rsize_send.setReadableSize(history_file_send.pos());
|
||||
}
|
||||
if (type_send == PIProtocol::Serial)
|
||||
if (ser->send(sendDataPtr, sendDataSize))
|
||||
if (ser->send(sendDataPtr, sendDataSize)) {
|
||||
send_count++;
|
||||
packets_out_sec++;
|
||||
bytes_out_sec += sendDataSize;
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet)
|
||||
if (eth->send(sendDataPtr, sendDataSize))
|
||||
if (eth->send(sendDataPtr, sendDataSize)) {
|
||||
send_count++;
|
||||
packets_out_sec++;
|
||||
bytes_out_sec += sendDataSize;
|
||||
}
|
||||
}
|
||||
|
||||
102
piprotocol.h
Executable file → Normal file
102
piprotocol.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Protocol, input/output channel (COM, UDP)
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@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
|
||||
@@ -34,7 +34,7 @@ class PIMultiProtocolBase
|
||||
friend class PIProtocol;
|
||||
public:
|
||||
PIMultiProtocolBase() {;}
|
||||
~PIMultiProtocolBase() {;}
|
||||
virtual ~PIMultiProtocolBase() {;}
|
||||
|
||||
protected:
|
||||
virtual void received(PIProtocol * prot, bool corrected, uchar * data, int size) {;}
|
||||
@@ -48,6 +48,23 @@ private:
|
||||
|
||||
typedef void (*ReceiveFunc)(void * );
|
||||
|
||||
/// events:
|
||||
/// void receiverStarted()
|
||||
/// void receiverStopped()
|
||||
/// void senderStarted()
|
||||
/// void senderStopped()
|
||||
/// void received(bool validate_is_ok)
|
||||
/// void qualityChanged(PIProtocol::Quality old_quality, PIProtocol::Quality new_quality)
|
||||
///
|
||||
/// handlers:
|
||||
/// void startReceive(float exp_frequency = -1.f)
|
||||
/// void stopReceive()
|
||||
/// void startSend(float frequency = -1.f)
|
||||
/// void stopSend()
|
||||
/// void start()
|
||||
/// void stop()
|
||||
/// void send()
|
||||
/// void send(const void * data, int size, bool direct = false)
|
||||
class PIProtocol: public PIObject
|
||||
{
|
||||
friend class PIMultiProtocolBase;
|
||||
@@ -58,7 +75,7 @@ public:
|
||||
PIProtocol(): PIObject() {init();}
|
||||
PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0,
|
||||
void * recDataPtr = 0, int recDataSize = 0, void * sendDataPtr = 0, int sendDataSize = 0); // from config
|
||||
~PIProtocol();
|
||||
virtual ~PIProtocol();
|
||||
|
||||
enum Quality {Unknown = 1, Failure = 2, Bad = 3, Average = 4, Good = 5};
|
||||
|
||||
@@ -67,8 +84,8 @@ public:
|
||||
EVENT_HANDLER0(PIProtocol, 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);}
|
||||
void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; packet_ext.setPacketData(headerPtr, headerSize, dataSize);}
|
||||
void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; packet_ext->setPacketData(headerPtr, headerSize, dataSize);}
|
||||
void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; packet_ext->setPacketData(headerPtr, headerSize, dataSize);}
|
||||
void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet
|
||||
void setReceiverParameters(PIFlags<PISerial::Parameters> parameters) {if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
|
||||
void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;}
|
||||
@@ -76,11 +93,13 @@ public:
|
||||
|
||||
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(); raiseEvent(this, "sender stopped");}
|
||||
EVENT_HANDLER0(PIProtocol, 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;}
|
||||
void setSenderAddress(const PIString & ip, int port, bool force = false); // for Ethernet
|
||||
void setSenderIP(const PIString & ip, bool force = false); // for Ethernet
|
||||
void setSenderPort(int port, bool force = false); // for Ethernet
|
||||
void setSenderParameters(PIFlags<PISerial::Parameters> parameters) {if (type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
|
||||
float senderFrequency() const {return send_freq;}
|
||||
|
||||
@@ -94,40 +113,60 @@ public:
|
||||
PIString name() const {return protName;}
|
||||
void setDisconnectTimeout(float timeout) {timeout_ = timeout; changeDisconnectTimeout();}
|
||||
float disconnectTimeout() const {return timeout_;}
|
||||
float * disconnectTimeout_ptr() {return &timeout_;}
|
||||
const float * disconnectTimeout_ptr() const {return &timeout_;}
|
||||
float immediateFrequency() const {return immediate_freq;}
|
||||
float integralFrequency() const {return integral_freq;}
|
||||
float * immediateFrequency_ptr() {return &immediate_freq;}
|
||||
float * integralFrequency_ptr() {return &integral_freq;}
|
||||
const float * immediateFrequency_ptr() const {return &immediate_freq;}
|
||||
const float * integralFrequency_ptr() const {return &integral_freq;}
|
||||
ullong receiveCountPerSec() const {return packets_in_sec;}
|
||||
const ullong * receiveCountPerSec_ptr() const {return &packets_in_sec;}
|
||||
ullong sendCountPerSec() const {return packets_out_sec;}
|
||||
const ullong * sendCountPerSec_ptr() const {return &packets_out_sec;}
|
||||
ullong receiveBytesPerSec() const {return bytes_in_sec;}
|
||||
const ullong * receiveBytesPerSec_ptr() const {return &bytes_in_sec;}
|
||||
ullong sendBytesPerSec() const {return bytes_out_sec;}
|
||||
const ullong * sendBytesPerSec_ptr() const {return &bytes_out_sec;}
|
||||
ullong receiveCount() const {return receive_count;}
|
||||
ullong * receiveCount_ptr() {return &receive_count;}
|
||||
const ullong * receiveCount_ptr() const {return &receive_count;}
|
||||
ullong wrongCount() const {return wrong_count;}
|
||||
ullong * wrongCount_ptr() {return &wrong_count;}
|
||||
const ullong * wrongCount_ptr() const {return &wrong_count;}
|
||||
ullong sendCount() const {return send_count;}
|
||||
ullong * sendCount_ptr() {return &send_count;}
|
||||
const ullong * sendCount_ptr() const {return &send_count;}
|
||||
ullong missedCount() const {return missed_count;}
|
||||
ullong * missedCount_ptr() {return &missed_count;}
|
||||
const ullong * missedCount_ptr() const {return &missed_count;}
|
||||
PIProtocol::Quality quality() const {return net_diag;} // receive quality
|
||||
int * quality_ptr() {return (int * )&net_diag;} // receive quality pointer
|
||||
const int * quality_ptr() const {return (int * )&net_diag;} // receive quality pointer
|
||||
PIString receiverDeviceName() const {return devReceiverName;}
|
||||
PIString senderDeviceName() const {return devSenderName;}
|
||||
PIString receiverDeviceState() const {return devReceiverState;}
|
||||
PIString * receiverDeviceState_ptr() {return &devReceiverState;}
|
||||
const PIString * receiverDeviceState_ptr() const {return &devReceiverState;}
|
||||
PIString senderDeviceState() const {return devSenderState;}
|
||||
PIString * senderDeviceState_ptr() {return &devSenderState;}
|
||||
const PIString * senderDeviceState_ptr() const {return &devSenderState;}
|
||||
PIString receiveSpeed() const {return speedIn;}
|
||||
const PIString * receiveSpeed_ptr() const {return &speedIn;}
|
||||
PIString sendSpeed() const {return speedOut;}
|
||||
const PIString * sendSpeed_ptr() const {return &speedOut;}
|
||||
PIString receiverHistorySize() const {return history_rsize_rec;}
|
||||
PIString * receiverHistorySize_ptr() {return &history_rsize_rec;}
|
||||
const PIString * receiverHistorySize_ptr() const {return &history_rsize_rec;}
|
||||
PIString senderHistorySize() const {return history_rsize_send;}
|
||||
PIString * senderHistorySize_ptr() {return &history_rsize_send;}
|
||||
const PIString * senderHistorySize_ptr() const {return &history_rsize_send;}
|
||||
bool writeReceiverHistory() const {return history_write_rec;}
|
||||
bool * writeReceiverHistory_ptr() {return &history_write_rec;}
|
||||
const bool * writeReceiverHistory_ptr() const {return &history_write_rec;}
|
||||
bool writeSenderHistory() const {return history_write_send;}
|
||||
bool * writeSenderHistory_ptr() {return &history_write_send;}
|
||||
const bool * writeSenderHistory_ptr() const {return &history_write_send;}
|
||||
|
||||
void * receiveData() {return dataPtr;}
|
||||
void * sendData() {return sendDataPtr;}
|
||||
|
||||
PIByteArray lastHeader() {return packet_ext.lastHeader();}
|
||||
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)
|
||||
|
||||
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
|
||||
@@ -137,15 +176,13 @@ protected:
|
||||
uint c = 0;
|
||||
for (int i = 0; i < size; ++i)
|
||||
c += ((uchar*)data)[i];
|
||||
c = ~(c + 1);
|
||||
return c;
|
||||
return ~(c + 1);
|
||||
}
|
||||
virtual uchar checksum_c(void * data, int size) { // function for checksum (uchar)
|
||||
uchar c = 0;
|
||||
for (int i = 0; i < size; ++i)
|
||||
c += ((uchar*)data)[i];
|
||||
c = ~(c + 1);
|
||||
return c;
|
||||
return ~(c + 1);
|
||||
}
|
||||
virtual bool aboutSend() {return true;} // executed before send data, if return 'false' then data is not sending
|
||||
|
||||
@@ -162,30 +199,31 @@ protected:
|
||||
private:
|
||||
static void sendEvent(void * e, int) {((PIProtocol * )e)->send();}
|
||||
static bool receiveEvent(void * t, uchar * data, int size);
|
||||
static bool headerValidateEvent(void * t, uchar * src, uchar * rec, int size);
|
||||
static bool headerValidateEvent(void * t, uchar * src, uchar * rec, int size) {return ((PIProtocol * )t)->headerValidate(src, rec, size);}
|
||||
static void diagEvent(void * t, int);
|
||||
static void secEvent(void * t, int);
|
||||
|
||||
void setMultiProtocolOwner(PIMultiProtocolBase * mp) {mp_owner = mp;}
|
||||
PIMultiProtocolBase * multiProtocolOwner() const {return mp_owner;}
|
||||
void changeDisconnectTimeout();
|
||||
|
||||
ReceiveFunc ret_func;
|
||||
PIPacketExtractor packet_ext;
|
||||
PITimer * diagTimer, * sendTimer;
|
||||
PIPacketExtractor * packet_ext;
|
||||
PITimer * diagTimer, * sendTimer, * secTimer;
|
||||
PIMultiProtocolBase * mp_owner;
|
||||
PIProtocol::Type type_send, type_rec;
|
||||
PIProtocol::Quality net_diag;
|
||||
PIDeque<float> last_freq;
|
||||
PIDeque<char> last_packets;
|
||||
PIString protName, devReceiverName, devReceiverState, devSenderName, devSenderState;
|
||||
PIString protName, devReceiverName, devReceiverState, devSenderName, devSenderState, speedIn, speedOut;
|
||||
PIString history_path_rec, history_path_send, history_rsize_rec, history_rsize_send;
|
||||
PIFile history_file_rec, history_file_send;
|
||||
ushort history_id_rec, history_id_send;
|
||||
bool work, new_mp_prot, history_write_rec, history_write_send;
|
||||
float exp_freq, send_freq, immediate_freq, integral_freq, timeout_;
|
||||
float exp_freq, send_freq, ifreq, immediate_freq, integral_freq, timeout_;
|
||||
int packets[2], pckt_cnt, pckt_cnt_max;
|
||||
char * packet, cur_pckt;
|
||||
ullong wrong_count, receive_count, send_count, missed_count;
|
||||
char cur_pckt;
|
||||
ullong wrong_count, receive_count, send_count, missed_count, packets_in_sec, packets_out_sec, bytes_in_sec, bytes_out_sec;
|
||||
|
||||
};
|
||||
|
||||
|
||||
188
piserial.cpp
Executable file → Normal file
188
piserial.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
COM
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@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
|
||||
@@ -60,6 +60,81 @@ PISerial::~PISerial() {
|
||||
}
|
||||
|
||||
|
||||
bool PISerial::setPin(int number, bool on) {
|
||||
switch (number) {
|
||||
case 1: return setCAR(on); break;
|
||||
case 2: return setSR(on); break;
|
||||
case 3: return setST(on); break;
|
||||
case 4: return setDTR(on); break;
|
||||
case 5:
|
||||
piCout << "[PISerial] Pin number 5 is ground" << endl;
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PISerial::isPin(int number) const {
|
||||
switch (number) {
|
||||
case 1: return isCAR(); break;
|
||||
case 2: return isSR(); break;
|
||||
case 3: return isST(); break;
|
||||
case 4: return isDTR(); break;
|
||||
case 5: return false;
|
||||
case 6: return isDSR(); break;
|
||||
case 7: return isRTS(); break;
|
||||
case 8: return isCTS(); break;
|
||||
case 9: return isRNG(); break;
|
||||
default:
|
||||
piCout << "[PISerial] Pin number " << number << " doesn`t exists!" << endl;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
if (ioctl(fd, on ? TIOCMBIS : TIOCMBIC, &bit) < 0) {
|
||||
piCout << "[PISerial] set" << bname << " error: " << errorString();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
piCout << "[PISerial] set" << bname << " doesn`t implemented on Windows, sorry :-(" << endl;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PISerial::isBit(int bit, const PIString & bname) const {
|
||||
#ifndef WINDOWS
|
||||
if (fd < 0) {
|
||||
piCout << "[PISerial] is" << bname << " error: \"" << path_ << "\" is not opened!" << endl;
|
||||
return false;
|
||||
}
|
||||
int ret = 0;
|
||||
if (ioctl(fd, TIOCMGET, &ret) < 0)
|
||||
piCout << "[PISerial] is" << bname << " error: " << errorString();
|
||||
return ret & bit;
|
||||
#else
|
||||
piCout << "[PISerial] set" << bname << " doesn`t implemented on Windows, sorry :-(" << endl;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PISerial::closeDevice() {
|
||||
if (!isInitialized()) return true;
|
||||
if (isRunning()) {
|
||||
@@ -86,6 +161,8 @@ bool PISerial::closeDevice() {
|
||||
|
||||
int PISerial::convertSpeed(PISerial::Speed speed) {
|
||||
switch (speed) {
|
||||
case S50: return B50;
|
||||
case S75: return B75;
|
||||
case S110: return B110;
|
||||
case S300: return B300;
|
||||
case S600: return B600;
|
||||
@@ -97,6 +174,13 @@ int PISerial::convertSpeed(PISerial::Speed speed) {
|
||||
case S38400: return B38400;
|
||||
case S57600: return B57600;
|
||||
case S115200: return B115200;
|
||||
case S1500000: return B1500000;
|
||||
case S2000000: return B2000000;
|
||||
case S2500000: return B2500000;
|
||||
case S3000000: return B3000000;
|
||||
case S3500000: return B3500000;
|
||||
case S4000000: return B4000000;
|
||||
default: break;
|
||||
}
|
||||
return B115200;
|
||||
}
|
||||
@@ -114,6 +198,7 @@ bool PISerial::read(void * data, int size, double timeout_ms) {
|
||||
if (ret > 0) all += ret;
|
||||
else msleep(1);
|
||||
}
|
||||
received(data, all);
|
||||
return (all == size);
|
||||
} else {
|
||||
setReadIsBlocking(true);
|
||||
@@ -122,15 +207,96 @@ bool PISerial::read(void * data, int size, double timeout_ms) {
|
||||
ret = ::read(fd, &((uchar * )data)[all], size - all);
|
||||
if (ret > 0) all += ret;
|
||||
}
|
||||
received(data, all);
|
||||
return (all == size);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PISerial::readData(int size, double timeout_ms) {
|
||||
int ret, all = 0;
|
||||
uchar td[1024];
|
||||
PIByteArray str;
|
||||
if (timeout_ms > 0.) {
|
||||
setReadIsBlocking(false);
|
||||
timer.reset();
|
||||
if (size <= 0) {
|
||||
while (timer.elapsed_m() < timeout_ms) {
|
||||
ret = ::read(fd, td, 1024);
|
||||
if (ret <= 0) msleep(1);
|
||||
else str << PIByteArray(td, ret);
|
||||
}
|
||||
} else {
|
||||
while (all < size && timer.elapsed_m() < timeout_ms) {
|
||||
ret = ::read(fd, td, size - all);
|
||||
if (ret <= 0) msleep(1);
|
||||
else {
|
||||
str << PIByteArray(td, ret);
|
||||
all += ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setReadIsBlocking(true);
|
||||
all = ::read(fd, td, 1);
|
||||
str << PIByteArray(td, all);
|
||||
while (all < size) {
|
||||
ret = ::read(fd, td, size - all);
|
||||
if (ret <= 0) msleep(1);
|
||||
else {
|
||||
str << PIByteArray(td, ret);
|
||||
all += ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
PIString PISerial::read(int size, double timeout_ms) {
|
||||
int ret, all = 0;
|
||||
uchar td[1024];
|
||||
PIString str;
|
||||
if (timeout_ms > 0.) {
|
||||
setReadIsBlocking(false);
|
||||
timer.reset();
|
||||
if (size <= 0) {
|
||||
while (timer.elapsed_m() < timeout_ms) {
|
||||
ret = ::read(fd, td, 1024);
|
||||
if (ret <= 0) msleep(1);
|
||||
else str << PIString((char*)td, ret);
|
||||
}
|
||||
} else {
|
||||
while (all < size && timer.elapsed_m() < timeout_ms) {
|
||||
ret = ::read(fd, td, size - all);
|
||||
if (ret <= 0) msleep(1);
|
||||
else {
|
||||
str << PIString((char*)td, ret);
|
||||
all += ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setReadIsBlocking(true);
|
||||
all = ::read(fd, td, 1);
|
||||
str << PIString((char*)td, all);
|
||||
while (all < size) {
|
||||
ret = ::read(fd, td, size - all);
|
||||
if (ret <= 0) msleep(1);
|
||||
else {
|
||||
str << PIString((char*)td, ret);
|
||||
all += ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
bool PISerial::openDevice() {
|
||||
#ifdef WINDOWS
|
||||
DWORD da = 0, sm = 0;
|
||||
DWORD ds = 0, sm = 0;
|
||||
if (isReadable()) {ds |= GENERIC_READ; sm |= FILE_SHARE_READ;}
|
||||
if (isWriteable()) {ds |= GENERIC_WRITE; sm |= FILE_SHARE_WRITE;}
|
||||
hCom = CreateFileA(path_.data(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||
@@ -176,19 +342,19 @@ bool PISerial::openDevice() {
|
||||
case PIIODevice::WriteOnly: om = O_WRONLY; break;
|
||||
case PIIODevice::ReadWrite: om = O_RDWR; break;
|
||||
}
|
||||
//cout << "init ser " << path_ << " mode " << om << endl;
|
||||
//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;
|
||||
return false;
|
||||
}
|
||||
fcntl(fd, F_SETFL, 0);
|
||||
|
||||
tcgetattr(fd, &desc);
|
||||
sdesc = desc;
|
||||
desc.c_iflag = desc.c_oflag = desc.c_lflag = 0;
|
||||
desc.c_iflag = desc.c_oflag = desc.c_lflag = desc.c_cflag = 0;
|
||||
desc.c_cflag = CLOCAL | CSIZE | CS8;
|
||||
if (isReadable()) desc.c_cflag |= CREAD;
|
||||
if (params[PISerial::HardwareFlowControl]) desc.c_cflag |= CRTSCTS;
|
||||
if (params[PISerial::TwoStopBits]) desc.c_cflag |= CSTOPB;
|
||||
if (params[PISerial::ParityControl]) {
|
||||
desc.c_iflag |= INPCK;
|
||||
@@ -201,12 +367,14 @@ bool PISerial::openDevice() {
|
||||
cfsetispeed(&desc, convertSpeed(ispeed));
|
||||
cfsetospeed(&desc, convertSpeed(ospeed));
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
fcntl(fd, F_SETFL, 0);
|
||||
|
||||
if(tcsetattr(fd, TCSANOW, &desc) < 0) {
|
||||
piCout << "[PISerial] Can`t set attributes for \"" << path_ << "\"" << endl;
|
||||
::close(fd);
|
||||
return false;
|
||||
}
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
//piCout << "[PISerial] Initialized " << path_ << endl;
|
||||
#endif
|
||||
return true;
|
||||
@@ -214,7 +382,7 @@ bool PISerial::openDevice() {
|
||||
|
||||
|
||||
int PISerial::write(const void * data, int max_size, bool wait) {
|
||||
//piCout << "[PISerial] send size: " << sizeof(data) << endl;
|
||||
//piCout << "[PISerial] send " << max_size << ": " << PIString((char*)data, max_size) << endl;
|
||||
if (fd == -1 || !canWrite()) {
|
||||
//piCout << "[PISerial] Can`t write to uninitialized COM" << endl;
|
||||
return -1;
|
||||
@@ -222,6 +390,12 @@ int PISerial::write(const void * data, int max_size, bool wait) {
|
||||
#ifdef WINDOWS
|
||||
DWORD wrote;
|
||||
WriteFile(hCom, data, max_size, &wrote, 0);
|
||||
if (wait) {
|
||||
DWORD event;
|
||||
SetCommMask(hCom, EV_TXEMPTY);
|
||||
WaitCommEvent(hCom, &event, NULL);
|
||||
SetCommMask(hCom, EV_RXCHAR);
|
||||
}
|
||||
#else
|
||||
int wrote;
|
||||
wrote = ::write(fd, data, max_size);
|
||||
|
||||
110
piserial.h
Executable file → Normal file
110
piserial.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
COM
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@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
|
||||
@@ -25,7 +25,43 @@
|
||||
#ifndef WINDOWS
|
||||
# include <termios.h>
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# ifndef B50
|
||||
# define B50 0000001
|
||||
# endif
|
||||
# ifndef B50
|
||||
# define B75 0000002
|
||||
# endif
|
||||
# ifndef B1500000
|
||||
# define B1500000 0010012
|
||||
# endif
|
||||
# ifndef B2000000
|
||||
# define B2000000 0010013
|
||||
# endif
|
||||
# ifndef B2500000
|
||||
# define B2500000 0010014
|
||||
# endif
|
||||
# ifndef B3000000
|
||||
# define B3000000 0010015
|
||||
# endif
|
||||
# ifndef B3500000
|
||||
# define B3500000 0010016
|
||||
# endif
|
||||
# ifndef B4000000
|
||||
# define B4000000 0010017
|
||||
# endif
|
||||
#else
|
||||
# define TIOCM_LE 1
|
||||
# define TIOCM_DTR 4
|
||||
# define TIOCM_RTS 7
|
||||
# define TIOCM_CTS 8
|
||||
# define TIOCM_ST 3
|
||||
# define TIOCM_SR 2
|
||||
# define TIOCM_CAR 1
|
||||
# define TIOCM_RNG 9
|
||||
# define TIOCM_DSR 6
|
||||
# define B50 50
|
||||
# define B75 75
|
||||
# define B110 110
|
||||
# define B300 300
|
||||
# define B600 600
|
||||
@@ -40,6 +76,12 @@
|
||||
# define B115200 115200
|
||||
# define B128000 128000
|
||||
# define B256000 256000
|
||||
# define B1500000 1500000
|
||||
# define B2000000 2000000
|
||||
# define B2500000 2500000
|
||||
# define B3000000 3000000
|
||||
# define B3500000 3500000
|
||||
# define B4000000 4000000
|
||||
#endif
|
||||
|
||||
class PISerial: public PIIODevice {
|
||||
@@ -50,8 +92,10 @@ public:
|
||||
PISerial(void * data = 0, ReadRetFunc slot = 0);
|
||||
~PISerial();
|
||||
|
||||
enum Parameters {ParityControl = 0x01, ParityOdd = 0x02, TwoStopBits = 0x04};
|
||||
enum Parameters {ParityControl = 0x1, ParityOdd = 0x2, TwoStopBits = 0x4, HardwareFlowControl = 0x8};
|
||||
enum Speed {
|
||||
S50 = 50,
|
||||
S75 = 75,
|
||||
S110 = 110,
|
||||
S300 = 300,
|
||||
S600 = 600,
|
||||
@@ -62,7 +106,13 @@ public:
|
||||
S19200 = 19200,
|
||||
S38400 = 38400,
|
||||
S57600 = 57600,
|
||||
S115200 = 115200
|
||||
S115200 = 115200,
|
||||
S1500000 = 1500000, // Linux only
|
||||
S2000000 = 2000000, // Linux only
|
||||
S2500000 = 2500000, // Linux only
|
||||
S3000000 = 3000000, // Linux only
|
||||
S3500000 = 3500000, // Linux only
|
||||
S4000000 = 4000000 // Linux only
|
||||
};
|
||||
|
||||
void setData(void * d) {data = d;}
|
||||
@@ -72,12 +122,39 @@ public:
|
||||
void setOutSpeed(PISerial::Speed speed) {ospeed = speed;}
|
||||
void setInSpeed(PISerial::Speed speed) {ispeed = speed;}
|
||||
void setDevice(const PIString & dev) {path_ = dev;}
|
||||
void setParameters(PIFlags<PISerial::Parameters> parameters) {params = parameters;}
|
||||
|
||||
void setParameters(PIFlags<PISerial::Parameters> parameters_) {params = parameters_;}
|
||||
void setParameter(PISerial::Parameters parameter, bool on = true) {params.setFlag(parameter, on);}
|
||||
bool isParameterSet(PISerial::Parameters parameter) const {return params[parameter];}
|
||||
PIFlags<PISerial::Parameters> parameters() const {return params;}
|
||||
|
||||
bool setPin(int number, bool on);
|
||||
bool isPin(int number) const;
|
||||
|
||||
bool setLE(bool on) {return setBit(TIOCM_LE, on, "LE");} // useless function, just formally
|
||||
bool setDTR(bool on) {return setBit(TIOCM_DTR, on, "DTR");}
|
||||
bool setRTS(bool on) {return setBit(TIOCM_RTS, on, "RTS");}
|
||||
bool setCTS(bool on) {return setBit(TIOCM_CTS, on, "CTS");} // useless function, just formally
|
||||
bool setST(bool on) {return setBit(TIOCM_ST, on, "ST");} // useless function, just formally
|
||||
bool setSR(bool on) {return setBit(TIOCM_SR, on, "SR");} // useless function, just formally
|
||||
bool setCAR(bool on) {return setBit(TIOCM_CAR, on, "CAR");} // useless function, just formally
|
||||
bool setRNG(bool on) {return setBit(TIOCM_RNG, on, "RNG");} // useless function, just formally
|
||||
bool setDSR(bool on) {return setBit(TIOCM_DSR, on, "DSR");} // useless function, just formally
|
||||
|
||||
bool isLE() const {return isBit(TIOCM_LE, "LE");}
|
||||
bool isDTR() const {return isBit(TIOCM_DTR, "DTR");}
|
||||
bool isRTS() const {return isBit(TIOCM_RTS, "RTS");}
|
||||
bool isCTS() const {return isBit(TIOCM_CTS, "CTS");}
|
||||
bool isST() const {return isBit(TIOCM_ST, "ST");}
|
||||
bool isSR() const {return isBit(TIOCM_SR, "SR");}
|
||||
bool isCAR() const {return isBit(TIOCM_CAR, "CAR");}
|
||||
bool isRNG() const {return isBit(TIOCM_RNG, "RNG");}
|
||||
bool isDSR() const {return isBit(TIOCM_DSR, "DSR");}
|
||||
|
||||
void setVTime(int t) {vtime = t;}
|
||||
|
||||
#ifdef WINDOWS
|
||||
void setReadIsBlocking(bool yes) {
|
||||
#ifdef WINDOWS
|
||||
COMMTIMEOUTS times;
|
||||
times.ReadIntervalTimeout = yes ? vtime : MAXDWORD;
|
||||
times.ReadTotalTimeoutConstant = yes ? 1 : 0;
|
||||
@@ -85,35 +162,48 @@ public:
|
||||
times.WriteTotalTimeoutConstant = 1;
|
||||
times.WriteTotalTimeoutMultiplier = 0;
|
||||
if (isOpened()) SetCommTimeouts(hCom, ×);
|
||||
}
|
||||
#else
|
||||
void setReadIsBlocking(bool yes) {if (isOpened()) fcntl(fd, F_SETFL, yes ? 0 : O_NONBLOCK);}
|
||||
if (isOpened()) fcntl(fd, F_SETFL, yes ? 0 : O_NONBLOCK);
|
||||
#endif
|
||||
}
|
||||
|
||||
const PIString & device() const {return path_;}
|
||||
PISerial::Speed outSpeed() const {return ospeed;}
|
||||
PISerial::Speed inSpeed() const {return ispeed;}
|
||||
int VTime() const {return vtime;}
|
||||
|
||||
#ifdef WINDOWS
|
||||
#ifndef WINDOWS
|
||||
void flush() {if (fd != -1) tcflush(fd, TCIOFLUSH);}
|
||||
#endif
|
||||
|
||||
int read(void * read_to, int max_size) {
|
||||
#ifdef WINDOWS
|
||||
if (!canRead()) return -1;
|
||||
WaitCommEvent(hCom, 0, 0);
|
||||
ReadFile(hCom, read_to, max_size, &readed, 0);
|
||||
return readed;
|
||||
}
|
||||
#else
|
||||
int read(void * read_to, int max_size) {if (!canRead()) return -1; return ::read(fd, read_to, max_size);}
|
||||
if (!canRead()) return -1;
|
||||
return ::read(fd, read_to, max_size);
|
||||
#endif
|
||||
}
|
||||
bool read(void * data, int size, double timeout_ms);
|
||||
PIString read(int size = -1, double timeout_ms = 1000.);
|
||||
PIByteArray readData(int size = -1, double timeout_ms = 1000.);
|
||||
|
||||
int write(const void * data, int max_size, bool wait);
|
||||
int write(const void * data, int max_size) {return write(data, max_size, false);}
|
||||
bool send(const void * data, int size, bool wait = false) {return (write(data, size, wait) == size);}
|
||||
bool send(const PIString & data, bool wait = false) {return (write(data.data(), data.lengthAscii(), wait) == data.size_s());}
|
||||
bool send(const PIByteArray & data, bool wait = false) {return (write(data.data(), data.size_s(), wait) == data.size_s());}
|
||||
|
||||
|
||||
protected:
|
||||
virtual void received(void * data, int size) {;}
|
||||
|
||||
int convertSpeed(PISerial::Speed speed);
|
||||
bool setBit(int bit, bool on, const PIString & bname);
|
||||
bool isBit(int bit, const PIString & bname) const;
|
||||
static bool headerValidate(void * d, uchar * src, uchar * rec, int size) {for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;}
|
||||
|
||||
bool openDevice();
|
||||
|
||||
2
pisignals.cpp
Executable file → Normal file
2
pisignals.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Signals
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pisignals.h
Executable file → Normal file
2
pisignals.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Signals
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
58
pistring.cpp
Executable file → Normal file
58
pistring.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
String
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,6 +20,28 @@
|
||||
#include "pistring.h"
|
||||
|
||||
|
||||
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',
|
||||
'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^'};
|
||||
const int PIString::fromBaseN[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
|
||||
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, -1,
|
||||
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||||
|
||||
|
||||
void PIString::appendFromChars(const char * c, int s) {
|
||||
int sz;
|
||||
wchar_t wc;
|
||||
@@ -88,11 +110,13 @@ PIString & PIString::operator +=(const wchar_t * str) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAS_LOCALE
|
||||
PIString & PIString::operator +=(const wstring & str) {
|
||||
uint l = str.size();
|
||||
for (uint i = 0; i < l; ++i) push_back(str[i]);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
PIString & PIString::operator +=(const PIString & str) {
|
||||
@@ -324,13 +348,20 @@ int PIString::lengthAscii() const {
|
||||
const char * PIString::data() const {
|
||||
PIByteArray & d_(*(const_cast<PIByteArray * >(&data_)));
|
||||
d_.clear();
|
||||
for (int i = 0, j = 0; i < size_s(); ++i, ++j) {
|
||||
if (at(i).isAscii())
|
||||
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;
|
||||
wc >>= 8;
|
||||
}
|
||||
/*if (at(i).isAscii())
|
||||
d_.push_back(uchar(at(i).toAscii()));
|
||||
else {
|
||||
d_.push_back((at(i).toCharPtr()[0])); ++j;
|
||||
d_.push_back((at(i).toCharPtr()[1]));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
d_.push_back(uchar('\0'));
|
||||
return (const char * )d_.data();
|
||||
@@ -339,14 +370,21 @@ const char * PIString::data() const {
|
||||
|
||||
string PIString::convertToStd() const {
|
||||
string s;
|
||||
int wc;
|
||||
uchar tc;
|
||||
if (size() > 0) {
|
||||
for (int i = 0; i < length(); ++i) {
|
||||
if (at(i).isAscii())
|
||||
wc = at(i).toInt();
|
||||
while (tc = wc & 0xFF, tc) {
|
||||
s.push_back(char(tc));
|
||||
wc >>= 8;
|
||||
}
|
||||
/*if (at(i).isAscii())
|
||||
s.push_back(at(i).toAscii());
|
||||
else {
|
||||
s.push_back(at(i).toCharPtr()[0]);
|
||||
s.push_back(at(i).toCharPtr()[1]);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
return s;
|
||||
@@ -360,7 +398,7 @@ char PIString::toChar() const {
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
short PIString::toShort() const {
|
||||
PIString s(trimmed().toLowerCase().toNativeDecimalPoints());
|
||||
short v;
|
||||
@@ -399,7 +437,7 @@ llong PIString::toLLong() const {
|
||||
sscanf(s.data(), "%lld", &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
PIString & PIString::setReadableSize(long bytes) {
|
||||
clear();
|
||||
@@ -424,14 +462,14 @@ PIString & PIString::setReadableSize(long bytes) {
|
||||
}
|
||||
|
||||
|
||||
char chrUpr(char c) {
|
||||
inline char chrUpr(char c) {
|
||||
if (c >= 'a' && c <= 'z') return c + 'A' - 'a';
|
||||
//if (c >= 'а' && c <= 'я') return c + 'А' - 'а';
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
char chrLwr(char c) {
|
||||
inline char chrLwr(char c) {
|
||||
if (c >= 'A' && c <= 'Z') return c + 'a' - 'A';
|
||||
//if (c >= 'А' && c <= 'Я') return c + 'а' - 'А';
|
||||
return c;
|
||||
|
||||
123
pistring.h
Executable file → Normal file
123
pistring.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
String
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -38,19 +38,23 @@ public:
|
||||
PIString & operator +=(const string & str) {appendFromChars(str.c_str(), str.length()); return *this;}
|
||||
PIString & operator +=(const PIByteArray & ba) {appendFromChars((const char * )ba.data(), ba.size_s()); return *this;}
|
||||
PIString & operator +=(const PIString & str);
|
||||
#ifdef HAS_LOCALE
|
||||
PIString & operator +=(const wstring & str);
|
||||
#endif
|
||||
|
||||
//PIString(const char c) {*this += c;}
|
||||
PIString(const PIChar c) {piMonitor.strings++; piMonitor.containers--;*this += c;}
|
||||
PIString(const char * str) {piMonitor.strings++; piMonitor.containers--;*this += str;}
|
||||
PIString(const wchar_t * str) {piMonitor.strings++; piMonitor.containers--;*this += str;}
|
||||
PIString(const string & str) {piMonitor.strings++; piMonitor.containers--;*this += str;}
|
||||
PIString(const wstring & str) {piMonitor.strings++; piMonitor.containers--;*this += str;}
|
||||
PIString(const PIByteArray & ba) {piMonitor.strings++; piMonitor.containers--;*this += ba;}
|
||||
PIString(const char * str, const int len) {piMonitor.strings++; piMonitor.containers--;*this += string(str, len);}
|
||||
PIString(const int len, const char c) {piMonitor.strings++; piMonitor.containers--;for (int i = 0; i < len; ++i) push_back(c);}
|
||||
PIString(const int len, const PIChar & c) {piMonitor.strings++; piMonitor.containers--;for (int i = 0; i < len; ++i) push_back(c);}
|
||||
PIString(const PIString & str) {piMonitor.strings++; piMonitor.containers--;*this += str;}
|
||||
PIString(const PIChar c) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += c;}
|
||||
PIString(const char * str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||
PIString(const wchar_t * str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += 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
|
||||
PIString(const PIByteArray & ba) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += ba;}
|
||||
PIString(const char * str, const int len) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += string(str, len);}
|
||||
PIString(const int len, const char c) {reserve(256); piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
|
||||
PIString(const int len, const PIChar & c) {reserve(256); piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
|
||||
PIString(const PIString & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||
~PIString() {piMonitor.strings--; piMonitor.containers++;}
|
||||
|
||||
operator const char*() {return data();}
|
||||
@@ -133,16 +137,18 @@ public:
|
||||
int lengthAscii() const;
|
||||
const char * data() const;
|
||||
const string stdString() const {return convertToStd();}
|
||||
#ifdef HAS_LOCALE
|
||||
wstring stdWString() const {return convertToWString();}
|
||||
PIByteArray toByteArray() {string s(convertToStd()); return PIByteArray(s.c_str(), s.length());}
|
||||
#endif
|
||||
PIByteArray toByteArray() const {const char * d = data(); return PIByteArray(d, lengthAscii());}
|
||||
PIStringList split(const PIString & delim) const;
|
||||
|
||||
PIString toUpperCase() const;
|
||||
PIString toLowerCase() const;
|
||||
#ifdef QNX
|
||||
PIString toNativeDecimalPoints() const {PIString s(*this); return s;}
|
||||
#else
|
||||
#ifdef HAS_LOCALE
|
||||
PIString toNativeDecimalPoints() const {PIString s(*this); if (currentLocale == 0) return s; return s.replaceAll(".", currentLocale->decimal_point);}
|
||||
#else
|
||||
PIString toNativeDecimalPoints() const {PIString s(*this); return s;}
|
||||
#endif
|
||||
|
||||
int find(const char str, const int start = 0) const;
|
||||
@@ -157,30 +163,43 @@ public:
|
||||
int length() const {return size();}
|
||||
bool isEmpty() const {return (size() == 0 || *this == "");}
|
||||
|
||||
bool toBool() const {PIString s(*this); if (atof(s.toNativeDecimalPoints().data()) > 0. || s.trimmed().toLowerCase() == "true") return true; return false;}
|
||||
bool toBool() const {PIString s(*this); if (atof(s.toNativeDecimalPoints().data()) > 0. || s.trimmed().toLowerCase() == "true" || s.trimmed().toLowerCase() == "on") return true; return false;}
|
||||
char toChar() const;
|
||||
short toShort() const;
|
||||
int toInt() const;
|
||||
long toLong() const;
|
||||
llong toLLong() const;
|
||||
short toShort(int base = -1, bool * ok = 0) const {return short(toNumberBase(*this, base, ok));}
|
||||
ushort toUShort(int base = -1, bool * ok = 0) const {return ushort(toNumberBase(*this, base, ok));}
|
||||
int toInt(int base = -1, bool * ok = 0) const {return int(toNumberBase(*this, base, ok));}
|
||||
uint toUInt(int base = -1, bool * ok = 0) const {return uint(toNumberBase(*this, base, ok));}
|
||||
long toLong(int base = -1, bool * ok = 0) const {return long(toNumberBase(*this, base, ok));}
|
||||
ulong toULong(int base = -1, bool * ok = 0) const {return ulong(toNumberBase(*this, base, ok));}
|
||||
llong toLLong(int base = -1, bool * ok = 0) const {return toNumberBase(*this, base, ok);}
|
||||
ullong toULLong(int base = -1, bool * ok = 0) const {return ullong(toNumberBase(*this, base, ok));}
|
||||
float toFloat() const {PIString s(*this); return (float)atof(s.toNativeDecimalPoints().data());}
|
||||
double toDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());}
|
||||
ldouble toLDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());}
|
||||
|
||||
//inline PIString & setNumber(const char value) {clear(); *this += itos(value); return *this;}
|
||||
PIString & setNumber(const int value) {clear(); *this += itos(value); return *this;}
|
||||
PIString & setNumber(const short value) {clear(); *this += itos(value); return *this;}
|
||||
PIString & setNumber(const long value) {clear(); *this += ltos(value); return *this;}
|
||||
PIString & setNumber(const short value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||
PIString & setNumber(const ushort value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||
PIString & setNumber(const int value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||
PIString & setNumber(const uint value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||
PIString & setNumber(const long value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||
PIString & setNumber(const ulong value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||
PIString & setNumber(const llong value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||
PIString & setNumber(const ullong value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
|
||||
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);
|
||||
|
||||
//inline static PIString fromNumber(const char value) {return PIString(itos(value));}
|
||||
static PIString fromNumber(const int value) {return PIString(itos(value));}
|
||||
static PIString fromNumber(const uint value) {return PIString(itos(value));}
|
||||
static PIString fromNumber(const short value) {return PIString(itos(value));}
|
||||
static PIString fromNumber(const long value) {return PIString(ltos(value));}
|
||||
static PIString fromNumber(const short value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||
static PIString fromNumber(const ushort value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||
static PIString fromNumber(const int value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||
static PIString fromNumber(const uint value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||
static PIString fromNumber(const long value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||
static PIString fromNumber(const ulong value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||
static PIString fromNumber(const llong value, int base = 10, bool * ok = 0) {return fromNumberBase(value, base, ok);}
|
||||
static PIString fromNumber(const ullong value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);}
|
||||
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));}
|
||||
@@ -188,9 +207,52 @@ public:
|
||||
static PIString readableSize(long bytes) {PIString s; s.setReadableSize(bytes); return s;}
|
||||
|
||||
private:
|
||||
static const char toBaseN[];
|
||||
static const int fromBaseN[];
|
||||
|
||||
static PIString fromNumberBase(const llong value, int base = 10, bool * ok = 0) {
|
||||
if (base < 2 || base > 40) {if (ok != 0) *ok = false; return PIString();}
|
||||
if (ok != 0) *ok = true;
|
||||
if (base == 10) return itos(value);
|
||||
PIString ret;
|
||||
llong v = value < 0 ? -value : value, cn, b = base;
|
||||
while (v >= base) {
|
||||
cn = v % b;
|
||||
v /= b;
|
||||
//cout << int(cn) << ", " << int(v) << endl;
|
||||
ret.push_front(PIChar(toBaseN[cn]));
|
||||
}
|
||||
if (v > 0) ret.push_front(PIChar(toBaseN[v]));
|
||||
if (value < 0) ret.push_front('-');
|
||||
return ret;
|
||||
}
|
||||
static llong toNumberBase(const PIString & value, int base = -1, bool * ok = 0) {
|
||||
PIString v = value.trimmed();
|
||||
if (base < 0) {
|
||||
int ind = v.find("0x");
|
||||
if (ind == 0 || ind == 1) {v.remove(ind, 2); base = 16;}
|
||||
else base = 10;
|
||||
} else
|
||||
if (base < 2 || base > 40) {if (ok != 0) *ok = false; return 0;}
|
||||
v.reverse();
|
||||
if (ok != 0) *ok = true;
|
||||
llong ret = 0, m = 1;
|
||||
int cs;
|
||||
piForeachC (PIChar & i, v) {
|
||||
if (i == PIChar('-')) {ret = -ret; continue;}
|
||||
//cout << i << ", " << fromBaseN[int(i.toAscii())] << ", " << m << endl;
|
||||
cs = fromBaseN[int(i.toAscii())];
|
||||
if (cs < 0 || cs >= base) break;
|
||||
ret += cs * m;
|
||||
m *= base;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void appendFromChars(const char * c, int s);
|
||||
string convertToStd() const;
|
||||
#ifdef HAS_LOCALE
|
||||
wstring convertToWString() const {wstring s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toWChar()); return s;}
|
||||
#endif
|
||||
|
||||
PIByteArray data_;
|
||||
//string std_string;
|
||||
@@ -201,6 +263,9 @@ private:
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIString & v) {for (int i = 0; i < v.length(); ++i) s << v[i]; return s;}
|
||||
inline std::istream & operator >>(std::istream & s, PIString & v) {string ss; s >> ss; v << PIString(ss); return s;}
|
||||
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const PIString & v) {s << v.size_s(); for (int i = 0; i < v.length(); ++i) s << v[i]; return s;}
|
||||
inline PIByteArray & operator >>(PIByteArray & s, PIString & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||
|
||||
inline 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;}
|
||||
@@ -211,8 +276,8 @@ inline PIString operator +(const PIString & f, const string & str) {PIString s(f
|
||||
inline PIString operator +(const char * str, const PIString & f) {return PIString(str) + f;}
|
||||
inline PIString operator +(const string & str, const PIString & f) {return PIString(str) + f;}
|
||||
|
||||
char chrUpr(char c);
|
||||
char chrLwr(char c);
|
||||
inline char chrUpr(char c);
|
||||
inline char chrLwr(char c);
|
||||
|
||||
class PIStringList: public PIVector<PIString>
|
||||
{
|
||||
|
||||
4
pisystemmonitor.cpp
Executable file → Normal file
4
pisystemmonitor.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Process resource monitor
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -53,6 +53,7 @@ bool PISystemMonitor::startOnProcess(int pID) {
|
||||
|
||||
void PISystemMonitor::run() {
|
||||
#ifndef WINDOWS
|
||||
file.seekToBegin();
|
||||
PIString str(file.readAll(true));
|
||||
int si = str.find('(') + 1, fi = 0, cc = 1;
|
||||
for (int i = si; i < str.size_s(); ++i) {
|
||||
@@ -93,6 +94,7 @@ void PISystemMonitor::run() {
|
||||
stat.priority = sl[16].toInt();
|
||||
stat.threads = sl[18].toInt();
|
||||
|
||||
filem.seekToBegin();
|
||||
str = filem.readAll(true);
|
||||
sl = str.split(" ");
|
||||
if (sl.size_s() < 5) return;
|
||||
|
||||
4
pisystemmonitor.h
Executable file → Normal file
4
pisystemmonitor.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Process resource monitor
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
|
||||
bool startOnProcess(int pID);
|
||||
bool startOnSelf() {return startOnProcess(PIProcess::currentPID());}
|
||||
ProcessStats & statistic() {return stat;}
|
||||
const ProcessStats & statistic() const {return stat;}
|
||||
|
||||
private:
|
||||
void run();
|
||||
|
||||
44
pisystemtests.cpp
Normal file
44
pisystemtests.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
System tests results (see system_test folder)
|
||||
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 "pisystemtests.h"
|
||||
|
||||
|
||||
namespace PISystemTests {
|
||||
long time_resolution_ns = 1;
|
||||
long time_elapsed_ns = 0;
|
||||
long usleep_offset_us = 60;
|
||||
|
||||
PISystemTestReader pisystestreader;
|
||||
|
||||
};
|
||||
|
||||
|
||||
PISystemTests::PISystemTestReader::PISystemTestReader() {
|
||||
PIConfig conf(
|
||||
#ifndef WINDOWS
|
||||
"/etc/pip.conf"
|
||||
#else
|
||||
"pip.conf"
|
||||
#endif
|
||||
, PIIODevice::ReadOnly);
|
||||
time_resolution_ns = conf.getValue("time_resolution_ns", 1);
|
||||
time_elapsed_ns = conf.getValue("time_elapsed_ns", 0);
|
||||
usleep_offset_us = conf.getValue("usleep_offset_us", 60);
|
||||
}
|
||||
24
pimultiprotocol.cpp → pisystemtests.h
Executable file → Normal file
24
pimultiprotocol.cpp → pisystemtests.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Multiprotocol
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
System tests results (see system_test folder)
|
||||
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
|
||||
@@ -17,5 +17,23 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pimultiprotocol.h"
|
||||
#ifndef PISYSTEMTESTS_H
|
||||
#define PISYSTEMTESTS_H
|
||||
|
||||
#include "piconfig.h"
|
||||
|
||||
namespace PISystemTests {
|
||||
extern long time_resolution_ns;
|
||||
extern long time_elapsed_ns;
|
||||
extern long usleep_offset_us;
|
||||
|
||||
class PISystemTestReader {
|
||||
public:
|
||||
PISystemTestReader();
|
||||
};
|
||||
|
||||
extern PISystemTestReader pisystestreader;
|
||||
|
||||
};
|
||||
|
||||
#endif // PISYSTEMTESTS_H
|
||||
63
pithread.cpp
Executable file → Normal file
63
pithread.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Thread
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -18,6 +18,17 @@
|
||||
*/
|
||||
|
||||
#include "pithread.h"
|
||||
#include "pisystemtests.h"
|
||||
|
||||
|
||||
void piUSleep(int usecs) {
|
||||
#ifdef WINDOWS
|
||||
if (usecs > 0) Sleep(usecs / 1000);
|
||||
#else
|
||||
usecs -= PISystemTests::usleep_offset_us;
|
||||
if (usecs > 0) usleep(usecs);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay): PIObject() {
|
||||
@@ -103,7 +114,7 @@ void PIThread::terminate(bool hard) {
|
||||
if (thread == 0) return;
|
||||
running = false;
|
||||
#ifndef WINDOWS
|
||||
if (hard) kill(thread, SIGKILL);
|
||||
if (hard) kill((ullong)thread, SIGKILL);
|
||||
else pthread_cancel(thread);
|
||||
#else
|
||||
CloseHandle(thread);
|
||||
@@ -114,20 +125,20 @@ void PIThread::terminate(bool hard) {
|
||||
|
||||
|
||||
void * PIThread::thread_function(void * t) {
|
||||
PIThread * ct = (PIThread * )t;
|
||||
ct->running = true;
|
||||
ct->begin();
|
||||
raiseEvent(ct, "started");
|
||||
while (!ct->terminating) {
|
||||
if (ct->lockRun) ct->mutex_.lock();
|
||||
ct->run();
|
||||
if (ct->ret_func != 0) ct->ret_func(ct->data_);
|
||||
if (ct->lockRun) ct->mutex_.unlock();
|
||||
if (ct->timer > 0) msleep(ct->timer);
|
||||
PIThread & ct = *((PIThread * )t);
|
||||
ct.running = true;
|
||||
ct.begin();
|
||||
ct.started();
|
||||
while (!ct.terminating) {
|
||||
if (ct.lockRun) ct.mutex_.lock();
|
||||
ct.run();
|
||||
if (ct.ret_func != 0) ct.ret_func(ct.data_);
|
||||
if (ct.lockRun) ct.mutex_.unlock();
|
||||
if (ct.timer > 0) msleep(ct.timer);
|
||||
}
|
||||
raiseEvent(ct, "stopped");
|
||||
ct->end();
|
||||
ct->running = false;
|
||||
ct.stopped();
|
||||
ct.end();
|
||||
ct.running = false;
|
||||
//cout << "thread " << t << " exiting ... " << endl;
|
||||
#ifndef WINDOWS
|
||||
pthread_exit(0);
|
||||
@@ -139,17 +150,17 @@ void * PIThread::thread_function(void * t) {
|
||||
|
||||
|
||||
void * PIThread::thread_function_once(void * t) {
|
||||
PIThread * ct = (PIThread * )t;
|
||||
ct->running = true;
|
||||
ct->begin();
|
||||
raiseEvent(ct, "started");
|
||||
if (ct->lockRun) ct->mutex_.lock();
|
||||
ct->run();
|
||||
if (ct->ret_func != 0) ct->ret_func(ct->data_);
|
||||
if (ct->lockRun) ct->mutex_.unlock();
|
||||
raiseEvent(ct, "stopped");
|
||||
ct->end();
|
||||
ct->running = false;
|
||||
PIThread & ct = *((PIThread * )t);
|
||||
ct.running = true;
|
||||
ct.begin();
|
||||
ct.started();
|
||||
if (ct.lockRun) ct.mutex_.lock();
|
||||
ct.run();
|
||||
if (ct.ret_func != 0) ct.ret_func(ct.data_);
|
||||
if (ct.lockRun) ct.mutex_.unlock();
|
||||
ct.stopped();
|
||||
ct.end();
|
||||
ct.running = false;
|
||||
//cout << "thread " << t << " exiting ... " << endl;
|
||||
#ifndef WINDOWS
|
||||
pthread_exit(0);
|
||||
|
||||
24
pithread.h
Executable file → Normal file
24
pithread.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Thread
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -29,14 +29,31 @@ inline void msleep(int msecs) {Sleep(msecs);}
|
||||
#else
|
||||
inline void msleep(int msecs) {usleep(msecs * 1000);}
|
||||
#endif
|
||||
void piUSleep(int usecs); // on !Windows consider constant "usleep" offset
|
||||
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 {
|
||||
public:
|
||||
PIThread(void * data, ThreadFunc func, bool startNow = false, int timer_delay = -1);
|
||||
PIThread(bool startNow = false, int timer_delay = -1);
|
||||
~PIThread();
|
||||
virtual ~PIThread();
|
||||
|
||||
#ifdef QNX
|
||||
enum Priority {piHighest = 12,
|
||||
@@ -77,6 +94,9 @@ public:
|
||||
EVENT_HANDLER0(PIThread, void, unlock) {mutex_.unlock();}
|
||||
PIMutex & mutex() {return mutex_;}
|
||||
|
||||
EVENT(PIThread, started)
|
||||
EVENT(PIThread, stopped)
|
||||
|
||||
protected:
|
||||
static void * thread_function(void * t);
|
||||
static void * thread_function_once(void * t);
|
||||
|
||||
368
pitimer.cpp
368
pitimer.cpp
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Timer
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -18,49 +18,87 @@
|
||||
*/
|
||||
|
||||
#include "pitimer.h"
|
||||
#include "pisystemtests.h"
|
||||
|
||||
|
||||
PITimer::PITimer(TimerEvent slot, void * data_)
|
||||
#ifdef WINDOWS
|
||||
#ifdef PIP_TIMER_RT
|
||||
PITimer::TimerPool * pool = 0;
|
||||
#endif
|
||||
|
||||
|
||||
PITimer::PITimer(TimerEvent slot, void * data_, bool threaded_)
|
||||
#ifndef PIP_TIMER_RT
|
||||
: PIThread() {
|
||||
#else
|
||||
: PIObject() {
|
||||
#endif
|
||||
ret_func = slot;
|
||||
data = data_;
|
||||
#ifndef WINDOWS
|
||||
#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 = timer_event;
|
||||
se.sigev_notify_function = PITimer::timer_event;
|
||||
se.sigev_notify_attributes = 0;
|
||||
lockRun = false;
|
||||
#endif
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
PITimer::PITimer(bool threaded_)
|
||||
#ifndef PIP_TIMER_RT
|
||||
: PIThread() {
|
||||
#else
|
||||
: PIObject() {
|
||||
#endif
|
||||
ret_func = 0;
|
||||
data = 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;
|
||||
#endif
|
||||
reset();
|
||||
/*addEvent<void*, int>("timeout");
|
||||
addEventHandler<double>(HANDLER(PITimer, start));
|
||||
addEventHandler(HANDLER(PITimer, stop));
|
||||
addEventHandler(HANDLER(PITimer, reset));*/
|
||||
}
|
||||
|
||||
|
||||
PITimer::~PITimer() {
|
||||
#ifndef WINDOWS
|
||||
#ifdef PIP_TIMER_RT
|
||||
piMonitor.timers--;
|
||||
#endif
|
||||
stop();
|
||||
}
|
||||
|
||||
|
||||
#ifndef WINDOWS
|
||||
#ifdef PIP_TIMER_RT
|
||||
void PITimer::start(double msecs) {
|
||||
if (ti == 0 || msecs < 0) return;
|
||||
if (ti != -1 || msecs < 0 || running) return;
|
||||
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;
|
||||
return;
|
||||
}
|
||||
spec.it_interval.tv_nsec = ((int)(msecs * 1000) % 1000000) * 1000;
|
||||
spec.it_interval.tv_sec = (time_t)(msecs / 1000);
|
||||
spec.it_value = spec.it_interval;
|
||||
ti = timer_create(CLOCK_REALTIME, &se, &timer);
|
||||
//cout << "***create timer " << msecs << " msecs\n";
|
||||
if (ti == -1) {
|
||||
piCout << "[PITimer] Can`t create timer for " << msecs << " msecs: " << errorString() << endl;
|
||||
return;
|
||||
@@ -70,18 +108,146 @@ void PITimer::start(double msecs) {
|
||||
}
|
||||
|
||||
|
||||
void PITimer::deferredStart(double interval_msecs, double delay_msecs) {
|
||||
if (ti != -1 || interval_msecs < 0 || running) return;
|
||||
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;
|
||||
spec.it_value.tv_sec = (time_t)(delay_msecs / 1000);
|
||||
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;
|
||||
return;
|
||||
}
|
||||
timer_settime(timer, 0, &spec, 0);
|
||||
running = true;
|
||||
}
|
||||
|
||||
|
||||
void PITimer::deferredStart(double interval_msecs, const PIDateTime & start_datetime) {
|
||||
if (ti != -1 || interval_msecs < 0 || running) return;
|
||||
spec.it_interval.tv_nsec = ((int)(interval_msecs * 1000) % 1000000) * 1000;
|
||||
spec.it_interval.tv_sec = (time_t)(interval_msecs / 1000);
|
||||
struct tm dtm;
|
||||
memset(&dtm, 0, sizeof(dtm));
|
||||
dtm.tm_sec = start_datetime.seconds;
|
||||
dtm.tm_min = start_datetime.minutes;
|
||||
dtm.tm_hour = start_datetime.hours;
|
||||
dtm.tm_mday = start_datetime.day;
|
||||
dtm.tm_mon = start_datetime.month - 1;
|
||||
dtm.tm_year = start_datetime.year - 1900;
|
||||
spec.it_value.tv_nsec = 0;
|
||||
spec.it_value.tv_sec = mktime(&dtm);
|
||||
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;
|
||||
return;
|
||||
}
|
||||
timer_settime(timer, TIMER_ABSTIME, &spec, 0);
|
||||
running = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PITimer::TimerPool::remove(PITimer * t) {
|
||||
mutex.lock();
|
||||
for (int i = 0; i < timers.size_s(); ++i)
|
||||
if (timers[i].first == t) {
|
||||
timers.remove(i);
|
||||
mutex.unlock();
|
||||
return;
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
void PITimer::TimerPool::begin() {
|
||||
//cout << "pool begin\n";
|
||||
/*struct sigaction sa;
|
||||
sa.sa_flags = 0;
|
||||
sa.sa_handler = empty_handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
if (sigaction(SIGALRM, &sa, 0) == -1) {
|
||||
piCout << "[PITimer] sigaction error: " << errorString() << endl;
|
||||
stop();
|
||||
return;
|
||||
}*/
|
||||
sigemptyset(&ss);
|
||||
sigaddset(&ss, SIGALRM);
|
||||
memset(&se, 0, sizeof(se));
|
||||
se.sigev_notify = SIGEV_SIGNAL;
|
||||
se.sigev_signo = SIGALRM;
|
||||
spec.it_interval.tv_nsec = 1000000;
|
||||
spec.it_interval.tv_sec = 0;
|
||||
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;
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
if (timer_settime(timer, 0, &spec, 0) == -1) {
|
||||
piCout << "[PITimer] Can`t set timer for pool: " << errorString() << endl;
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
ti = 1;
|
||||
}
|
||||
|
||||
|
||||
void PITimer::TimerPool::run() {
|
||||
//cout << "wait ...\n";
|
||||
sigwait(&ss, &si);
|
||||
//cout << "ok\n";
|
||||
mutex.lock();
|
||||
//cout << "* pool tick , pool = " << this <<", timers = " << timers.size()<<"\n";
|
||||
for (int i = 0; i < timers.size_s(); ++i) {
|
||||
TimerPair & ct(timers[i]);
|
||||
sv.sival_ptr = ct.first;
|
||||
ct.second++;
|
||||
//cout << "** pool tick for " << ct.first << ", cnt " << ct.second << ", " << ct.first->ticks << "\n";
|
||||
if (ct.second >= ct.first->ticks) {
|
||||
//cout << "*** timer "<<ct.first<<" tick start\n";
|
||||
PITimer::timer_event(sv);
|
||||
//cout << "*** timer "<<ct.first<<" tick end\n";
|
||||
ct.second = 0;
|
||||
}
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PITimer::stop() {
|
||||
if (!running) return;
|
||||
running = false;
|
||||
if (!threaded) {
|
||||
if (pool != 0) {
|
||||
pool->remove(this);
|
||||
if (pool->isEmpty()) pool->terminate();
|
||||
}
|
||||
}
|
||||
if (ti != -1) timer_delete(timer);
|
||||
ti = -1;
|
||||
}
|
||||
|
||||
|
||||
void PITimer::timer_event(sigval e) {
|
||||
PITimer * ct = (PITimer * )e.sival_ptr;
|
||||
if (!ct->running) return;
|
||||
if (ct->lockRun) ct->lock();
|
||||
if (ct->ret_func != 0) ct->ret_func(ct->data, 1);
|
||||
raiseEvent<void*, int>(ct, "timeout", ct->data, 1);
|
||||
ct->timeout(ct->data, 1);
|
||||
ct->tick(ct->data, 1);
|
||||
piForeach (TimerSlot & i, ct->ret_funcs) {
|
||||
if (i.delim > ++(i.tick)) continue;
|
||||
i.tick = 0;
|
||||
if (i.slot != 0) i.slot(ct->data, i.delim);
|
||||
else if (ct->ret_func != 0) ct->ret_func(ct->data, i.delim);
|
||||
raiseEvent<void*, int>(ct, "timeout", ct->data, i.delim);
|
||||
ct->timeout(ct->data, i.delim);
|
||||
ct->tick(ct->data, i.delim);
|
||||
}
|
||||
if (ct->lockRun) ct->unlock();
|
||||
}
|
||||
@@ -101,32 +267,48 @@ bool PITimer::waitForFinish(int timeout_msecs) {
|
||||
return cnt < timeout_msecs;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
void PITimer::start(double msecs) {
|
||||
if (msecs < 0 || running) return;
|
||||
inc_time = PISystemTime::fromMilliseconds(msecs);
|
||||
st_time = currentSystemTime() + inc_time;
|
||||
PIThread::start();
|
||||
}
|
||||
|
||||
|
||||
void PITimer::run() {
|
||||
if (!running) return;
|
||||
(st_time - currentSystemTime()).sleep();
|
||||
st_time += inc_time;
|
||||
if (lockRun) lock();
|
||||
if (ret_func != 0) ret_func(data, 1);
|
||||
raiseEvent<void*, int>(this, "timeout", data, 1);
|
||||
timeout(data, 1);
|
||||
tick(data, 1);
|
||||
piForeach (TimerSlot & i, ret_funcs) {
|
||||
if (i.delim > ++(i.tick)) continue;
|
||||
i.tick = 0;
|
||||
if (i.slot != 0) i.slot(data, i.delim);
|
||||
else if (ret_func != 0) ret_func(data, i.delim);
|
||||
raiseEvent<void*, int>(this, "timeout", data, i.delim);
|
||||
timeout(data, i.delim);
|
||||
tick(data, i.delim);
|
||||
}
|
||||
if (lockRun) unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
double PITimer::elapsed_n() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur - t_st) * 1000000.;
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+9 + (t_cur.tv_nsec - t_st.tv_nsec);
|
||||
# endif
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+9 + (t_cur.tv_nsec - t_st.tv_nsec - PISystemTests::time_elapsed_ns);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -136,8 +318,12 @@ double PITimer::elapsed_u() {
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur - t_st) * 1000.;
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+6 + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+3;
|
||||
# endif
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+6 + (t_cur.tv_nsec - t_st.tv_nsec - PISystemTests::time_elapsed_ns) / 1.e+3;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -147,8 +333,12 @@ double PITimer::elapsed_m() {
|
||||
t_cur = GetCurrentTime();
|
||||
return (double)(t_cur - t_st);
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+3 + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+6;
|
||||
# endif
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+3 + (t_cur.tv_nsec - t_st.tv_nsec - PISystemTests::time_elapsed_ns) / 1.e+6;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -158,18 +348,20 @@ double PITimer::elapsed_s() {
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur - t_st) / 1000.;
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec - t_st.tv_sec) + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+9;
|
||||
# endif
|
||||
return (t_cur.tv_sec - t_st.tv_sec) + (t_cur.tv_nsec - t_st.tv_nsec - PISystemTests::time_elapsed_ns) / 1.e+9;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double PITimer::reset_time_n() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return t_st * 1000000.;
|
||||
return t_st * 1.e+6;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return t_st.tv_sec * 1.e+9 + t_st.tv_nsec;
|
||||
#endif
|
||||
}
|
||||
@@ -177,10 +369,8 @@ double PITimer::reset_time_n() {
|
||||
|
||||
double PITimer::reset_time_u() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur - t_st) * 1000.;
|
||||
return t_st * 1.e+3;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return t_st.tv_sec * 1.e+6 + t_st.tv_nsec / 1.e+3;
|
||||
#endif
|
||||
}
|
||||
@@ -188,10 +378,8 @@ double PITimer::reset_time_u() {
|
||||
|
||||
double PITimer::reset_time_m() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (double)(t_cur - t_st);
|
||||
return (double)t_st;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return t_st.tv_sec * 1.e+3 + t_st.tv_nsec / 1.e+6;
|
||||
#endif
|
||||
}
|
||||
@@ -199,22 +387,34 @@ double PITimer::reset_time_m() {
|
||||
|
||||
double PITimer::reset_time_s() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur - t_st) / 1000.;
|
||||
return t_st / 1000.;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return t_st.tv_sec + t_st.tv_nsec / 1.e+9;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PISystemTime PITimer::reset_time() {
|
||||
#ifdef WINDOWS
|
||||
return PISystemTime(t_st / 1000, (t_st % 1000) * 1000000);
|
||||
#else
|
||||
return PISystemTime(t_st.tv_sec, t_st.tv_nsec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double PITimer::elapsed_system_n() {
|
||||
#ifdef WINDOWS
|
||||
long t_cur = GetCurrentTime();
|
||||
return (t_cur * 1000000.);
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
mach_timespec_t t_cur;
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
# endif
|
||||
return (t_cur.tv_sec * 1.e+9 + t_cur.tv_nsec);
|
||||
#endif
|
||||
}
|
||||
@@ -225,8 +425,13 @@ double PITimer::elapsed_system_u() {
|
||||
long t_cur = GetCurrentTime();
|
||||
return (t_cur * 1000.);
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
mach_timespec_t t_cur;
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
# endif
|
||||
return (t_cur.tv_sec * 1.e+6 + (t_cur.tv_nsec / 1.e+3));
|
||||
#endif
|
||||
}
|
||||
@@ -237,8 +442,13 @@ double PITimer::elapsed_system_m() {
|
||||
long t_cur = GetCurrentTime();
|
||||
return (double)t_cur;
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
mach_timespec_t t_cur;
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
# endif
|
||||
return (t_cur.tv_sec * 1.e+3 + (t_cur.tv_nsec / 1.e+6));
|
||||
#endif
|
||||
}
|
||||
@@ -249,8 +459,13 @@ double PITimer::elapsed_system_s() {
|
||||
long t_cur = GetCurrentTime();
|
||||
return (t_cur / 1000.);
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
mach_timespec_t t_cur;
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
# endif
|
||||
return (t_cur.tv_sec + (t_cur.tv_nsec / 1.e+9));
|
||||
#endif
|
||||
}
|
||||
@@ -278,6 +493,37 @@ PIDate currentDate() {
|
||||
}
|
||||
|
||||
|
||||
PIDateTime currentDateTime() {
|
||||
time_t rt = time(0);
|
||||
tm * pt = localtime(&rt);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
PISystemTime currentSystemTime() {
|
||||
#ifdef WINDOWS
|
||||
long t_cur = GetCurrentTime();
|
||||
return PISystemTime(t_cur / 1000, (t_cur % 1000) * 1000000);
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
mach_timespec_t t_cur;
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
# endif
|
||||
return PISystemTime(t_cur.tv_sec, t_cur.tv_nsec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PIString PITime::toString(const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
||||
@@ -293,10 +539,29 @@ PIString PITime::toString(const PIString & format) {
|
||||
PIString PIDate::toString(const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(year).expandLeftTo(2, '0'));
|
||||
ts.replace("y", PIString::fromNumber(year));
|
||||
ts.replace("mm", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(month));
|
||||
ts.replace("yy", PIString::fromNumber(year).right(2));
|
||||
ts.replace("y", PIString::fromNumber(year).right(1));
|
||||
ts.replace("MM", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
||||
ts.replace("M", PIString::fromNumber(month));
|
||||
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(day));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
PIString PIDateTime::toString(const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
||||
ts.replace("h", PIString::fromNumber(hours));
|
||||
ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(minutes));
|
||||
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
||||
ts.replace("s", PIString::fromNumber(seconds));
|
||||
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(year).right(2));
|
||||
ts.replace("y", PIString::fromNumber(year).right(1));
|
||||
ts.replace("MM", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
||||
ts.replace("M", PIString::fromNumber(month));
|
||||
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(day));
|
||||
return ts;
|
||||
@@ -318,10 +583,29 @@ PIString time2string(const PITime & time, const PIString & format) {
|
||||
PIString date2string(const PIDate & date, const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(date.year).expandLeftTo(2, '0'));
|
||||
ts.replace("y", PIString::fromNumber(date.year));
|
||||
ts.replace("mm", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(date.month));
|
||||
ts.replace("yy", PIString::fromNumber(date.year).right(2));
|
||||
ts.replace("y", PIString::fromNumber(date.year).right(1));
|
||||
ts.replace("MM", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
||||
ts.replace("M", PIString::fromNumber(date.month));
|
||||
ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(date.day));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
PIString datetime2string(const PIDateTime & date, const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(date.hours).expandLeftTo(2, '0'));
|
||||
ts.replace("h", PIString::fromNumber(date.hours));
|
||||
ts.replace("mm", PIString::fromNumber(date.minutes).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(date.minutes));
|
||||
ts.replace("ss", PIString::fromNumber(date.seconds).expandLeftTo(2, '0'));
|
||||
ts.replace("s", PIString::fromNumber(date.seconds));
|
||||
ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(date.year).right(2));
|
||||
ts.replace("y", PIString::fromNumber(date.year).right(1));
|
||||
ts.replace("MM", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
||||
ts.replace("M", PIString::fromNumber(date.month));
|
||||
ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(date.day));
|
||||
return ts;
|
||||
|
||||
158
pitimer.h
158
pitimer.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Timer
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -28,6 +28,45 @@
|
||||
|
||||
typedef void (*TimerEvent)(void * , int );
|
||||
|
||||
class PISystemTime {
|
||||
public:
|
||||
PISystemTime() {seconds = nanoseconds = 0;}
|
||||
PISystemTime(long s, long ns) {seconds = s; nanoseconds = ns; checkOverflows();}
|
||||
PISystemTime(const PISystemTime & t) {seconds = t.seconds; nanoseconds = t.nanoseconds;}
|
||||
|
||||
double toSeconds() const {return double(seconds) + nanoseconds / 1.e+9;}
|
||||
double toMilliseconds() const {return seconds * 1.e+3 + nanoseconds / 1.e+6;}
|
||||
double toMicroseconds() const {return seconds * 1.e+6 + nanoseconds / 1.e+3;}
|
||||
double toNanoseconds() const {return seconds * 1.e+9 + double(nanoseconds);}
|
||||
void sleep() {piUSleep(piFloord(toMicroseconds()));} // wait self value, useful to wait some dT = (t1 - t0)
|
||||
PISystemTime abs() const {return PISystemTime(piAbsl(seconds), piAbsl(nanoseconds));}
|
||||
PISystemTime operator +(const PISystemTime & t) {PISystemTime tt(*this); tt.seconds += t.seconds; tt.nanoseconds += t.nanoseconds; tt.checkOverflows(); return tt;}
|
||||
PISystemTime operator -(const PISystemTime & t) {PISystemTime tt(*this); tt.seconds -= t.seconds; tt.nanoseconds -= t.nanoseconds; tt.checkOverflows(); return tt;}
|
||||
PISystemTime & operator +=(const PISystemTime & t) {seconds += t.seconds; nanoseconds += t.nanoseconds; checkOverflows(); return *this;}
|
||||
PISystemTime & operator -=(const PISystemTime & t) {seconds -= t.seconds; nanoseconds -= t.nanoseconds; checkOverflows(); return *this;}
|
||||
bool operator ==(const PISystemTime & t) {return ((seconds == t.seconds) && (nanoseconds == t.nanoseconds));}
|
||||
bool operator !=(const PISystemTime & t) {return ((seconds != t.seconds) || (nanoseconds != t.nanoseconds));}
|
||||
bool operator >(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds > t.nanoseconds; return seconds > t.seconds;}
|
||||
bool operator <(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds < t.nanoseconds; return seconds < t.seconds;}
|
||||
bool operator >=(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds >= t.nanoseconds; return seconds >= t.seconds;}
|
||||
bool operator <=(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds <= t.nanoseconds; return seconds <= t.seconds;}
|
||||
|
||||
static PISystemTime fromSeconds(double v) {long s = piFloord(v); return PISystemTime(s, (v - s) * 1000000000);}
|
||||
static PISystemTime fromMilliseconds(double v) {long s = piFloord(v / 1000.); return PISystemTime(s, (v / 1000. - s) * 1000000000);}
|
||||
static PISystemTime fromMicroseconds(double v) {long s = piFloord(v / 1000000.); return PISystemTime(s, (v / 1000000. - s) * 1000000000);}
|
||||
static PISystemTime fromNanoseconds(double v) {long s = piFloord(v / 1000000000.); return PISystemTime(s, (v / 1000000000. - s) * 1000000000);}
|
||||
|
||||
long seconds;
|
||||
long nanoseconds;
|
||||
|
||||
private:
|
||||
void checkOverflows() {while (nanoseconds >= 1000000000) {nanoseconds -= 1000000000; seconds++;} while (nanoseconds < 0) {nanoseconds += 1000000000; seconds--;}}
|
||||
|
||||
};
|
||||
|
||||
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 {
|
||||
int seconds;
|
||||
int minutes;
|
||||
@@ -38,29 +77,67 @@ struct PITime {
|
||||
struct PIDate {
|
||||
int day;
|
||||
int month;
|
||||
int year; // since 1900
|
||||
PIString toString(const PIString & format = "d.mm.yyyy");
|
||||
int year;
|
||||
PIString toString(const PIString & format = "d.MM.yyyy");
|
||||
};
|
||||
|
||||
struct PIDateTime {
|
||||
int seconds;
|
||||
int minutes;
|
||||
int hours;
|
||||
int day;
|
||||
int month;
|
||||
int year;
|
||||
PIString toString(const PIString & format = "h:mm:ss d.MM.yyyy");
|
||||
};
|
||||
|
||||
/// events:
|
||||
/// void timeout(void * data, int delimiter)
|
||||
///
|
||||
/// handlers:
|
||||
/// void start(double msecs)
|
||||
/// void deferredStart(double interval_msecs, double delay_msecs)
|
||||
/// void deferredStart(double interval_msecs, const PIDateTime & start_datetime)
|
||||
/// void stop()
|
||||
/// bool waitForFinish(int timeout_msecs = -1)
|
||||
/// void reset()
|
||||
/// void clearDelimiters()
|
||||
/// void lock()
|
||||
/// void unlock()
|
||||
class PITimer
|
||||
#ifdef WINDOWS
|
||||
#ifndef PIP_TIMER_RT
|
||||
: public PIThread
|
||||
#else
|
||||
: public PIObject
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
PITimer(TimerEvent slot = 0, void * data = 0);
|
||||
~PITimer();
|
||||
PITimer(TimerEvent slot = 0, void * data = 0, bool threaded = true);
|
||||
PITimer(bool threaded);
|
||||
virtual ~PITimer();
|
||||
|
||||
void setData(void * data_) {data = data_;}
|
||||
void setSlot(TimerEvent slot) {ret_func = slot;}
|
||||
#ifdef WINDOWS
|
||||
void reset() {t_st = GetCurrentTime();}
|
||||
#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);
|
||||
# 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);
|
||||
# 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);
|
||||
# endif
|
||||
#else
|
||||
EVENT_HANDLER0(PITimer, void, reset) {clock_gettime(0, &t_st);}
|
||||
EVENT_HANDLER1(PITimer, void, start, double, msecs);
|
||||
EVENT_HANDLER0(PITimer, void, stop) {if (ti == 0) timer_delete(timer); ti = -1; running = false;}
|
||||
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;}
|
||||
@@ -83,29 +160,71 @@ public:
|
||||
double reset_time_u(); // microseconds
|
||||
double reset_time_m(); // miliseconds
|
||||
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_s(); // seconds
|
||||
|
||||
|
||||
#ifdef PIP_TIMER_RT
|
||||
class TimerPool: public PIThread {
|
||||
public:
|
||||
TimerPool(): PIThread() {/*cout << "+++++new pool\n"; */ti = -1;}
|
||||
~TimerPool() {stop();}
|
||||
void add(PITimer * t) {mutex.lock(); timers << TimerPair(t, 0); mutex.unlock();}
|
||||
void remove(PITimer * t);
|
||||
bool isEmpty() const {return timers.isEmpty();}
|
||||
typedef PIPair<PITimer * , int> TimerPair;
|
||||
private:
|
||||
static void empty_handler(int) {}
|
||||
void begin();
|
||||
void run();
|
||||
void end() {/*cout << "pool end\n"; */if (ti != -1) timer_delete(timer); ti = -1;}
|
||||
int ti, si;
|
||||
sigset_t ss;
|
||||
sigevent se;
|
||||
sigval sv;
|
||||
itimerspec spec;
|
||||
|
||||
timer_t timer;
|
||||
PIVector<TimerPair> timers;
|
||||
PIMutex mutex;
|
||||
};
|
||||
static void timer_event(sigval e);
|
||||
int ticks;
|
||||
#endif
|
||||
|
||||
EVENT2(PITimer, timeout, void * , data, int, delimiter)
|
||||
|
||||
protected:
|
||||
virtual void tick(void * data, int delimiter) {;}
|
||||
|
||||
private:
|
||||
#ifdef WINDOWS
|
||||
#ifndef PIP_TIMER_RT
|
||||
void run();
|
||||
|
||||
long t_st, t_cur;
|
||||
PISystemTime st_time, inc_time;
|
||||
#else
|
||||
static void timer_event(sigval e);
|
||||
|
||||
bool running;
|
||||
bool running, threaded;
|
||||
volatile bool lockRun;
|
||||
PIMutex mutex_;
|
||||
int ti;
|
||||
itimerspec spec;
|
||||
timespec t_st, t_cur;
|
||||
timer_t timer;
|
||||
sigevent se;
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS
|
||||
long
|
||||
#elif defined(MAC_OS)
|
||||
mach_timespec_t
|
||||
#else
|
||||
timespec
|
||||
#endif
|
||||
t_st, t_cur;
|
||||
|
||||
struct TimerSlot {
|
||||
TimerSlot(TimerEvent slot_ = 0, int delim_ = 1) {slot = slot_; delim = delim_; tick = 0;}
|
||||
TimerEvent slot;
|
||||
@@ -119,9 +238,16 @@ private:
|
||||
|
||||
};
|
||||
|
||||
#ifdef PIP_TIMER_RT
|
||||
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 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
|
||||
|
||||
#endif // PITIMER_H
|
||||
|
||||
2
pivariable.cpp
Executable file → Normal file
2
pivariable.cpp
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Variable, Struct (simple serialization)
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pivariable.h
Executable file → Normal file
2
pivariable.h
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Variable, Struct (simple serialization)
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
192
protocols.conf
Normal file
192
protocols.conf
Normal file
@@ -0,0 +1,192 @@
|
||||
# Eth
|
||||
|
||||
#gas.receiver.ip = 192.168.5.36 #i
|
||||
#gas.receiver.ip = 192.168.0.190 #i
|
||||
gas.receiver.ip = 192.168.6.36 #i
|
||||
gas.receiver.port = 9217 #n
|
||||
gas.receiver.frequency = 100 #f
|
||||
#gas.sender.ip = 192.168.5.2 #i
|
||||
#gas.sender.ip = 192.168.0.190 #i
|
||||
gas.sender.ip = 192.168.6.133 #i
|
||||
#gas.sender.port = 1 #n
|
||||
gas.sender.port = 10000 #n
|
||||
gas.sender.frequency = 10 #f
|
||||
gas.writeHistory = false #b
|
||||
|
||||
# Eth
|
||||
mcp1_c.receiver.ip = 192.168.5.36 #i
|
||||
#mcp1.receiver.ip = 127.0.0.1 #i
|
||||
mcp1_c.receiver.port = 4012 #n
|
||||
mcp1_c.receiver.frequency = 20 #f
|
||||
mcp1_c.sender.ip = 192.168.5.13 #i
|
||||
#mcp1.sender.ip = 127.0.0.1 #i
|
||||
mcp1_c.sender.port = 4013 #n
|
||||
mcp1_c.sender.frequency = 20 #f
|
||||
mcp1_c.writeHistory = false #b
|
||||
|
||||
# Eth
|
||||
mcp1_m.sender.ip = 192.168.5.13 #i
|
||||
mcp1_m.sender.port = 4014 #n
|
||||
mcp1_m.sender.frequency = 20 #f
|
||||
mcp1_m.writeHistory = false #b
|
||||
|
||||
# Eth
|
||||
mcp1_i.receiver.ip = 192.168.5.36 #i
|
||||
mcp1_i.receiver.port = 4016 #n
|
||||
mcp1_i.sender.ip = 192.168.5.13 #i
|
||||
mcp1_i.sender.port = 4015 #n
|
||||
mcp1_i.writeHistory = false #b
|
||||
|
||||
# Eth
|
||||
mcp2.receiver.ip = 192.168.6.36 #i
|
||||
mcp2.receiver.port = 4014 #n
|
||||
mcp2.receiver.frequency = 20 #f
|
||||
mcp2.sender.ip = 192.168.6.133 #i
|
||||
mcp2.sender.port = 4015 #n
|
||||
mcp2.sender.frequency = 20 #f
|
||||
mcp2.writeHistory = false #b
|
||||
|
||||
# RS
|
||||
#slk.receiver.ip = 192.168.0.190 #i
|
||||
slk.receiver.ip = 192.168.6.36 #i
|
||||
slk.receiver.port = 3108 #n
|
||||
slk.receiver.frequency = 10 #f
|
||||
#slk.sender.ip = 192.168.0.175 #i
|
||||
slk.sender.ip = 192.168.6.133 #i
|
||||
slk.sender.port = 3109 #n
|
||||
slk.sender.frequency = 10 #f
|
||||
slk.disconnectTimeout = 1.5 #f
|
||||
slk.writeHistory = false #b
|
||||
|
||||
# RS
|
||||
#ts.receiver.device = /dev/ttyS0
|
||||
#ts.receiver.speed = 57600
|
||||
#ts.receiver.parity = false
|
||||
#ts.receiver.twoStopBits = false
|
||||
ts.receiver.ip = 192.168.0.190 #i
|
||||
ts.receiver.port = 4023 #n
|
||||
ts.receiver.frequency = 23 #f
|
||||
ts.sender.ip = 192.168.0.175 #i
|
||||
ts.sender.port = 4023 #n
|
||||
#ts.sender.frequency = 23
|
||||
ts_mcp1.receiver.ip = 192.168.0.190 #i
|
||||
ts_mcp1.receiver.port = 4022 #n
|
||||
ts_mcp1.sender.ip = 192.168.0.175 #i
|
||||
ts_mcp1.sender.port = 4022 #n
|
||||
ts.writeHistory = false #b
|
||||
|
||||
# Eth
|
||||
mv2.receiver.ip = 192.168.150.1 #i
|
||||
mv2.receiver.port = 3003 #n
|
||||
mv2.receiver.frequency = 20 #f
|
||||
mv2.sender.ip = 192.168.150.16 #i
|
||||
mv2.sender.port = 3003 #n
|
||||
mv2.sender.frequency = 20 #f
|
||||
mv2.writeHistory = false #b
|
||||
mv2.historyID = 43079 #n
|
||||
|
||||
#RS422
|
||||
mv2_res.device = /dev/ttyMI0 #s
|
||||
mv2_res.speed = 115200 #n
|
||||
mv2_res.frequency = 10 #f
|
||||
mv2_res.twoStopBits = false #b
|
||||
mv2_res.parity = false #b
|
||||
|
||||
|
||||
# Eth
|
||||
ki.mcp1.receiver.ip = 192.168.5.36 #i
|
||||
ki.mcp1.receiver.port = 4102 #n
|
||||
ki.mcp1.sender.ip = 192.168.5.13 #i
|
||||
ki.mcp1.sender.port = 4101 #n
|
||||
ki.mv2.receiver.ip = 192.168.150.1 #i
|
||||
ki.mv2.receiver.port = 4104 #n
|
||||
ki.mv2.sender.ip = 192.168.150.16 #i
|
||||
ki.mv2.sender.port = 4103 #n
|
||||
|
||||
# Eth
|
||||
kpi_mcp1.receiver.ip = 192.168.5.36 #i
|
||||
kpi_mcp1.receiver.port = 4204 #n
|
||||
kpi_mcp1.sender.ip = 192.168.5.13 #i
|
||||
kpi_mcp1.sender.port = 4203 #n
|
||||
|
||||
# Eth
|
||||
kpi_mcp2.receiver.ip = 192.168.6.36 #i
|
||||
kpi_mcp2.receiver.port = 4206 #n
|
||||
kpi_mcp2.sender.ip = 192.168.6.133 #i
|
||||
kpi_mcp2.sender.port = 4205 #n
|
||||
|
||||
# Eth
|
||||
#rud.receiver.ip = 192.168.5.36 #i
|
||||
rud.receiver.ip = 192.168.6.36 #i
|
||||
rud.receiver.port = 4050 #n
|
||||
rud.receiver.frequency = 20 #f
|
||||
|
||||
# Eth
|
||||
vpu.ip = 127.0.0.1 #i
|
||||
vpu.receiver.port = 6001 #n
|
||||
vpu.sender.port = 6000 #n
|
||||
vpu.frequency = 20 #f
|
||||
|
||||
# Eth
|
||||
#kku.receiver.ip = 192.168.6.36 #i
|
||||
kku.receiver.ip = 192.168.5.36 #i
|
||||
kku.receiver.port = 5011 #n
|
||||
kku.receiver.frequency = 20 #f
|
||||
#kku.sender.ip = 192.168.6.133 #i
|
||||
kku.sender.ip = 192.168.5.133 #i
|
||||
kku.sender.port = 5010 #n
|
||||
kku.sender.frequency = 20 #f
|
||||
|
||||
# ???
|
||||
sep.receiver.ip = 192.168.150.1 #i
|
||||
sep.receiver.port = 4031 #n
|
||||
sep.receiver.frequency = 4 #f
|
||||
sep.sender.ip = 192.168.150.16 #i
|
||||
sep.sender.port = 4030 #n
|
||||
#sep.sender.frequency = 4 #f
|
||||
|
||||
# Eth
|
||||
108ua.receiver.ip = 192.168.5.36 #i
|
||||
108ua.receiver.port = 2002 #n
|
||||
108ua.receiver.frequency = 10 #f
|
||||
108ua.sender.ip = 192.168.5.36 #i
|
||||
108ua.sender.port = 2011 #n
|
||||
108ua.sender.frequency = 10 #f
|
||||
|
||||
# Eth
|
||||
108ua_r.receiver.ip = 192.168.6.36 #i
|
||||
108ua_r.receiver.port = 2002 #n
|
||||
108ua_r.receiver.frequency = 10 #f
|
||||
108ua_r.sender.ip = 192.168.6.2 #i
|
||||
108ua_r.sender.port = 2011 #n
|
||||
108ua_r.sender.frequency = 10 #f
|
||||
|
||||
# Eth
|
||||
vpu_driver.ip = 127.0.0.1 #i
|
||||
vpu_driver.receiver.port = 6000 #n
|
||||
vpu_driver.sender.port = 6001 #n
|
||||
vpu_driver.frequency = 20 #f
|
||||
|
||||
# Eth
|
||||
tvk.mv2.receiver.ip = 192.168.150.1 #i
|
||||
tvk.mv2.receiver.port = 4024 #n
|
||||
tvk.mv2.sender.ip = 192.168.150.16 #i
|
||||
tvk.mv2.sender.port = 4024 #n
|
||||
tvk.mcp2.receiver.ip = 192.168.6.36 #i
|
||||
tvk.mcp2.receiver.port = 4024 #n
|
||||
tvk.mcp2.sender.ip = 192.168.6.133 #i
|
||||
tvk.mcp2.sender.port = 4024 #n
|
||||
|
||||
#Eth
|
||||
bpd.receiver.ip = 127.0.0.1 #i
|
||||
bpd.receiver.port = 2012 #n
|
||||
bpd.sender.ip = 127.0.0.1 #i
|
||||
bpd.sender.port = 2013 #n
|
||||
|
||||
# Eth
|
||||
astd.receiver.ip = 192.168.5.36 #i
|
||||
astd.receiver.port = 5298 #n
|
||||
astd.sender.ip = 192.168.5.2 #i
|
||||
astd.sender.port = 1101 #n
|
||||
astd.frequency = 1 #f
|
||||
astd.writeHistory = false #b
|
||||
6
system_test/CMakeLists.txt
Normal file
6
system_test/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} . ../)
|
||||
file(GLOB CPPS "*.cpp")
|
||||
add_definitions(-Wall -O2)
|
||||
add_executable(pip_sys_test "main.cpp")
|
||||
target_link_libraries(pip_sys_test pip)
|
||||
106
system_test/main.cpp
Normal file
106
system_test/main.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
System tests 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"
|
||||
#include "pisystemtests.h"
|
||||
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
#ifdef WINDOWS
|
||||
cout << "This program is useless for Windows" << endl;
|
||||
return 0;
|
||||
#else
|
||||
if (getuid() != 0) {
|
||||
cout << "You should run this program as root!" << endl;
|
||||
return 0;
|
||||
}
|
||||
PIConfig conf(
|
||||
#ifndef WINDOWS
|
||||
"/etc/pip.conf"
|
||||
#else
|
||||
"pip.conf"
|
||||
#endif
|
||||
);
|
||||
PITimer timer, tm;
|
||||
timespec ts;
|
||||
long stc = 0;
|
||||
double st;
|
||||
llong sts = 0;
|
||||
clock_getres(CLOCK_REALTIME, &ts);
|
||||
stc = long(ts.tv_sec) * 1000000000l + long(ts.tv_nsec);
|
||||
conf.setValue("time_resolution_ns", stc);
|
||||
cout << "Timer resolution is " << stc << " ns" << endl;
|
||||
|
||||
cout << "\"PITimer.elapsed_*\" test ... " << flush;
|
||||
stc = 0;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1000;
|
||||
PIVector<double> times;
|
||||
times.resize(8192);
|
||||
tm.reset();
|
||||
PISystemTests::time_elapsed_ns = 0;
|
||||
while (tm.elapsed_s() < 3.) {
|
||||
for (int i = 0; i < times.size_s(); ++i) {
|
||||
timer.reset();
|
||||
times[i] = timer.elapsed_m();
|
||||
times[i] = timer.elapsed_s();
|
||||
times[i] = timer.elapsed_u();
|
||||
}
|
||||
st = 0;
|
||||
for (int i = 0; i < times.size_s(); ++i)
|
||||
st += times[i];
|
||||
//cout << times[0] << endl;
|
||||
//cout << st / times.size_s() / 3. * 1000. << endl;
|
||||
sts += piRoundd(st / times.size_s() / 3. * 1000.);
|
||||
//cout << sts << endl;
|
||||
stc++;
|
||||
}
|
||||
sts /= stc;
|
||||
conf.setValue("time_elapsed_ns", long(sts));
|
||||
cout << "ok, cost " << sts << " ns, average in " << stc << " series (" << (stc * 3 * times.size_s()) << " executes)" << endl;
|
||||
|
||||
cout << "\"usleep\" offset test ... " << flush;
|
||||
PISystemTests::time_elapsed_ns = sts;
|
||||
tm.reset();
|
||||
stc = 0;
|
||||
sts = 0;
|
||||
times.resize(128);
|
||||
while (tm.elapsed_s() < 3.) {
|
||||
for (int i = 0; i < times.size_s(); ++i) {
|
||||
timer.reset();
|
||||
usleep(1000);
|
||||
times[i] = timer.elapsed_u();
|
||||
}
|
||||
st = 0;
|
||||
for (int i = 0; i < times.size_s(); ++i)
|
||||
st += times[i] - 1000;
|
||||
//cout << times[0] << endl;
|
||||
//cout << st / times.size_s() / 3. * 1000. << endl;
|
||||
sts += piRoundd(st / times.size_s());
|
||||
//cout << sts << endl;
|
||||
stc++;
|
||||
}
|
||||
sts /= stc;
|
||||
conf.setValue("usleep_offset_us", long(sts));
|
||||
cout << "ok, " << sts << " us, average in " << stc << " series (" << (stc * times.size_s()) << " executes)" << endl;
|
||||
|
||||
//WAIT_FOR_EXIT
|
||||
return 0;
|
||||
#endif
|
||||
};
|
||||
BIN
Описание.odt
Executable file → Normal file
BIN
Описание.odt
Executable file → Normal file
Binary file not shown.
0
Описание.pdf
Executable file → Normal file
0
Описание.pdf
Executable file → Normal file
Reference in New Issue
Block a user