code format
This commit is contained in:
@@ -1,2 +1 @@
|
||||
#include "pip.h"
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "picloudclient.h"
|
||||
|
||||
#include "picloudtcp.h"
|
||||
|
||||
|
||||
@@ -28,7 +29,10 @@ PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode)
|
||||
is_connected = false;
|
||||
is_deleted = false;
|
||||
// setReopenEnabled(false);
|
||||
CONNECTL(ð, connected, [this](){opened_ = true; tcp.sendStart();});
|
||||
CONNECTL(ð, connected, [this]() {
|
||||
opened_ = true;
|
||||
tcp.sendStart();
|
||||
});
|
||||
CONNECT1(void, PIByteArray, &streampacker, packetReceiveEvent, this, _readed);
|
||||
CONNECTL(ð, disconnected, [this](bool) {
|
||||
if (is_deleted) return;
|
||||
@@ -178,8 +182,7 @@ void PICloudClient::_readed(PIByteArray & ba) {
|
||||
cond_buff.notifyOne();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
// piCoutObj << "readed" << ba.toHex();
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
*/
|
||||
|
||||
#include "picloudtcp.h"
|
||||
#include "picrypt.h"
|
||||
|
||||
#include "pichunkstream.h"
|
||||
#include "picrypt.h"
|
||||
#include "piethernet.h"
|
||||
#include "pistreampacker.h"
|
||||
|
||||
@@ -43,7 +44,8 @@ void PICloud::TCP::setRole(PICloud::TCP::Role r) {
|
||||
|
||||
void PICloud::TCP::setServerName(const PIString & server_name_) {
|
||||
server_name = server_name_;
|
||||
suuid = PICrypt::hash(PIByteArray(server_name_.data(), server_name_.size()), (const unsigned char *)hash_cloud_key, sizeof(hash_cloud_key));
|
||||
suuid =
|
||||
PICrypt::hash(PIByteArray(server_name_.data(), server_name_.size()), (const unsigned char *)hash_cloud_key, sizeof(hash_cloud_key));
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +134,8 @@ PIPair<PICloud::TCP::Type, PICloud::TCP::Role> PICloud::TCP::parseHeader(PIByteA
|
||||
PICloud::TCP::Header hdr;
|
||||
ba >> hdr;
|
||||
if (hdr.version != header.version) {
|
||||
piCout << "[PICloud]" << "invalid PICloud::TCP version!";
|
||||
piCout << "[PICloud]"
|
||||
<< "invalid PICloud::TCP version!";
|
||||
return ret;
|
||||
}
|
||||
ret.first = (Type)hdr.type;
|
||||
|
||||
@@ -38,14 +38,16 @@ PIByteArray piCompress(const PIByteArray & ba, int level) {
|
||||
ulong sz = zba.size();
|
||||
ret = compress2(zba.data(), &sz, ba.data(), ba.size(), level);
|
||||
if (ret != Z_OK) {
|
||||
piCout << "[PICompress]" << "Error: invalid input or not enought memory";
|
||||
piCout << "[PICompress]"
|
||||
<< "Error: invalid input or not enought memory";
|
||||
return ba;
|
||||
}
|
||||
zba.resize(sz);
|
||||
zba << ullong(ba.size());
|
||||
return zba;
|
||||
#else
|
||||
piCout << "[PICompress]" << "Warning: PICompress is disabled, to enable install zlib library and build pip_compress library";
|
||||
piCout << "[PICompress]"
|
||||
<< "Warning: PICompress is disabled, to enable install zlib library and build pip_compress library";
|
||||
#endif
|
||||
return ba;
|
||||
}
|
||||
@@ -55,7 +57,8 @@ PIByteArray piDecompress(const PIByteArray & zba) {
|
||||
#ifdef PIP_COMPRESS
|
||||
ullong sz = 0;
|
||||
if (zba.size() < sizeof(ullong)) {
|
||||
piCout << "[PICompress]" << "Error: invalid input";
|
||||
piCout << "[PICompress]"
|
||||
<< "Error: invalid input";
|
||||
return zba;
|
||||
}
|
||||
PIByteArray ba(zba.data(zba.size() - sizeof(ullong)), sizeof(ullong));
|
||||
@@ -65,12 +68,14 @@ PIByteArray piDecompress(const PIByteArray & zba) {
|
||||
ulong s = sz;
|
||||
ret = uncompress(ba.data(), &s, zba.data(), zba.size());
|
||||
if (ret != Z_OK) {
|
||||
piCout << "[PICompress]" << "Error: invalid input or not enought memory";
|
||||
piCout << "[PICompress]"
|
||||
<< "Error: invalid input or not enought memory";
|
||||
return zba;
|
||||
}
|
||||
return ba;
|
||||
#else
|
||||
piCout << "[PICompress]" << "Warning: PICompress is disabled, to enable install zlib library and build pip_compress library";
|
||||
piCout << "[PICompress]"
|
||||
<< "Warning: PICompress is disabled, to enable install zlib library and build pip_compress library";
|
||||
#endif
|
||||
return zba;
|
||||
}
|
||||
|
||||
@@ -27,16 +27,9 @@ TileVars::TileVars(const PIString &n) : PIScreenTile(n) {
|
||||
}
|
||||
|
||||
|
||||
void TileVars::sizeHint(int &w, int &h) const {
|
||||
void TileVars::sizeHint(int & w, int & h) const {}
|
||||
|
||||
}
|
||||
|
||||
void TileVars::drawEvent(PIScreenDrawer *d) {
|
||||
|
||||
}
|
||||
void TileVars::drawEvent(PIScreenDrawer * d) {}
|
||||
|
||||
|
||||
PIScreenConsoleTile::PIScreenConsoleTile() {
|
||||
|
||||
}
|
||||
|
||||
PIScreenConsoleTile::PIScreenConsoleTile() {}
|
||||
|
||||
@@ -117,26 +117,24 @@ void PIScreenDrawer::drawLine(int x0, int y0, int x1, int y1, const PIChar & c,
|
||||
float dy = (y1 - y0) / float(piAbsi(x1 - x0)), cy = y0;
|
||||
int dx = x0 < x1 ? 1 : -1;
|
||||
for (int i = x0; i != x1; i += dx) {
|
||||
x = i; y = piRound(cy);
|
||||
if (x >= 0 && x < width && y >= 0 && y < height)
|
||||
cells[y][x] = cc;
|
||||
x = i;
|
||||
y = piRound(cy);
|
||||
if (x >= 0 && x < width && y >= 0 && y < height) cells[y][x] = cc;
|
||||
cy += dy;
|
||||
}
|
||||
y = piRound(cy);
|
||||
if (x1 >= 0 && x1 < width && y >= 0 && y < height)
|
||||
cells[y][x1] = cc;
|
||||
if (x1 >= 0 && x1 < width && y >= 0 && y < height) cells[y][x1] = cc;
|
||||
} else {
|
||||
float dx = (x1 - x0) / float(piAbsi(y1 - y0)), cx = x0;
|
||||
int dy = y0 < y1 ? 1 : -1;
|
||||
for (int i = y0; i != y1; i += dy) {
|
||||
x = piRound(cx); y = i;
|
||||
if (x >= 0 && x < width && y >= 0 && y < height)
|
||||
cells[y][x] = cc;
|
||||
x = piRound(cx);
|
||||
y = i;
|
||||
if (x >= 0 && x < width && y >= 0 && y < height) cells[y][x] = cc;
|
||||
cx += dx;
|
||||
}
|
||||
x = piRound(cx);
|
||||
if (x >= 0 && x < width && y1 >= 0 && y1 < height)
|
||||
cells[y1][x] = cc;
|
||||
if (x >= 0 && x < width && y1 >= 0 && y1 < height) cells[y1][x] = cc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,19 +155,16 @@ void PIScreenDrawer::drawRect(int x0, int y0, int x1, int y1, const PIChar & c,
|
||||
if (j >= 0 && j < height) {
|
||||
PIVector<Cell> & cv(cells[j]);
|
||||
for (int i = x0; i != x1; i += dx)
|
||||
if (i >= 0 && i < width)
|
||||
cv[i] = cc;
|
||||
if (i >= 0 && i < width) cv[i] = cc;
|
||||
}
|
||||
j = xs[k];
|
||||
if (j >= 0 && j < width) {
|
||||
for (int i = y0; i != y1; i += dy)
|
||||
if (i >= 0 && i < height)
|
||||
cells[i][j] = cc;
|
||||
if (i >= 0 && i < height) cells[i][j] = cc;
|
||||
}
|
||||
}
|
||||
int i = x1, j = y1;
|
||||
if (i >= 0 && i < width && j >= 0 && j < height)
|
||||
cells[j][i] = cc;
|
||||
if (i >= 0 && i < width && j >= 0 && j < height) cells[j][i] = cc;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,24 +184,26 @@ void PIScreenDrawer::drawFrame(int x0, int y0, int x1, int y1, Color col_char, C
|
||||
PIVector<Cell> & cv(cells[j]);
|
||||
cc.symbol = artChar(LineHorizontal);
|
||||
for (int i = x0 + 1; i != x1; i += dx)
|
||||
if (i >= 0 && i < width)
|
||||
cv[i] = cc;
|
||||
if (i >= 0 && i < width) cv[i] = cc;
|
||||
}
|
||||
j = xs[k];
|
||||
if (j >= 0 && j < width) {
|
||||
cc.symbol = artChar(LineVertical);
|
||||
for (int i = y0 + 1; i != y1; i += dy)
|
||||
if (i >= 0 && i < height)
|
||||
cells[i][j] = cc;
|
||||
if (i >= 0 && i < height) cells[i][j] = cc;
|
||||
}
|
||||
}
|
||||
int i = x0, j = y0; cc.symbol = artChar(CornerTopLeft);
|
||||
int i = x0, j = y0;
|
||||
cc.symbol = artChar(CornerTopLeft);
|
||||
if (i >= 0 && i < width && j >= 0 && j < height) cells[j][i] = cc;
|
||||
i = x1, j = y0; cc.symbol = artChar(CornerTopRight);
|
||||
i = x1, j = y0;
|
||||
cc.symbol = artChar(CornerTopRight);
|
||||
if (i >= 0 && i < width && j >= 0 && j < height) cells[j][i] = cc;
|
||||
i = x0, j = y1; cc.symbol = artChar(CornerBottomLeft);
|
||||
i = x0, j = y1;
|
||||
cc.symbol = artChar(CornerBottomLeft);
|
||||
if (i >= 0 && i < width && j >= 0 && j < height) cells[j][i] = cc;
|
||||
i = x1, j = y1; cc.symbol = artChar(CornerBottomRight);
|
||||
i = x1, j = y1;
|
||||
cc.symbol = artChar(CornerBottomRight);
|
||||
if (i >= 0 && i < width && j >= 0 && j < height) cells[j][i] = cc;
|
||||
}
|
||||
|
||||
@@ -224,8 +221,7 @@ void PIScreenDrawer::fillRect(int x0, int y0, int x1, int y1, const PIChar & c,
|
||||
if (j >= 0 && j < height) {
|
||||
PIVector<Cell> & cv(cells[j]);
|
||||
for (int i = x0; i != x1; i += dx)
|
||||
if (i >= 0 && i < width)
|
||||
cv[i] = cc;
|
||||
if (i >= 0 && i < width) cv[i] = cc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,8 +237,7 @@ void PIScreenDrawer::fillRect(int x0, int y0, int x1, int y1, PIVector<PIVector<
|
||||
PIVector<Cell> & cv(cells[y0 + j]);
|
||||
PIVector<Cell> & contv(content[j]);
|
||||
for (int i = 0; i < piMini(w, contv.size_s()); ++i)
|
||||
if ((i + x0) >= 0 && (i + x0) < width)
|
||||
cv[x0 + i] = contv[i];
|
||||
if ((i + x0) >= 0 && (i + x0) < width) cv[x0 + i] = contv[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "piscreentile.h"
|
||||
|
||||
#include "piscreendrawer.h"
|
||||
|
||||
|
||||
@@ -41,8 +42,7 @@ PIScreenTile::PIScreenTile(const PIString & n, Direction d, SizePolicy p): PIObj
|
||||
|
||||
PIScreenTile::~PIScreenTile() {
|
||||
// piCout << this << "~";
|
||||
if (screen)
|
||||
screen->tileRemovedInternal(this);
|
||||
if (screen) screen->tileRemovedInternal(this);
|
||||
setScreen(0);
|
||||
deleteChildren();
|
||||
if (!parent) return;
|
||||
@@ -79,8 +79,7 @@ void PIScreenTile::removeTile(PIScreenTile * t) {
|
||||
PIVector<PIScreenTile *> PIScreenTile::children(bool only_visible) {
|
||||
PIVector<PIScreenTile *> ret;
|
||||
piForeach(PIScreenTile * t, tiles)
|
||||
if (t->visible || !only_visible)
|
||||
ret << t << t->children(only_visible);
|
||||
if (t->visible || !only_visible) ret << t << t->children(only_visible);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -88,8 +87,7 @@ PIVector<PIScreenTile * > PIScreenTile::children(bool only_visible) {
|
||||
PIScreenTile * PIScreenTile::childUnderMouse(int x, int y) {
|
||||
piForeach(PIScreenTile * t, tiles) {
|
||||
if (!t->visible) continue;
|
||||
if (x >= t->x_ && (x - t->x_) < t->width_ &&
|
||||
y >= t->y_ && (y - t->y_) < t->height_) {
|
||||
if (x >= t->x_ && (x - t->x_) < t->width_ && y >= t->y_ && (y - t->y_) < t->height_) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
@@ -129,7 +127,14 @@ void PIScreenTile::drawEventInternal(PIScreenDrawer * d) {
|
||||
if (!visible) {
|
||||
return;
|
||||
}
|
||||
d->fillRect(x_, y_, x_ + width_, y_ + height_, back_symbol, (Color)back_format.color_char, (Color)back_format.color_back, back_format.flags);
|
||||
d->fillRect(x_,
|
||||
y_,
|
||||
x_ + width_,
|
||||
y_ + height_,
|
||||
back_symbol,
|
||||
(Color)back_format.color_char,
|
||||
(Color)back_format.color_back,
|
||||
back_format.flags);
|
||||
drawEvent(d);
|
||||
piForeach(PIScreenTile * t, tiles)
|
||||
t->drawEventInternal(d);
|
||||
@@ -141,8 +146,10 @@ void PIScreenTile::sizeHint(int & w, int & h) const {
|
||||
h = 0;
|
||||
if (tiles.isEmpty()) return;
|
||||
int sl = spacing * (tiles.size_s() - 1);
|
||||
if (direction == Horizontal) w += sl;
|
||||
else h += sl;
|
||||
if (direction == Horizontal)
|
||||
w += sl;
|
||||
else
|
||||
h += sl;
|
||||
piForeachC(PIScreenTile * t, tiles) {
|
||||
if (!t->visible) continue;
|
||||
int cw(0), ch(0);
|
||||
@@ -150,9 +157,11 @@ void PIScreenTile::sizeHint(int & w, int & h) const {
|
||||
cw = piClampi(cw, t->minimumWidth, t->maximumWidth);
|
||||
ch = piClampi(ch, t->minimumHeight, t->maximumHeight);
|
||||
if (direction == Horizontal) {
|
||||
w += cw; h = piMaxi(h, ch);
|
||||
w += cw;
|
||||
h = piMaxi(h, ch);
|
||||
} else {
|
||||
h += ch; w = piMaxi(w, cw);
|
||||
h += ch;
|
||||
w = piMaxi(w, cw);
|
||||
}
|
||||
}
|
||||
w += marginLeft + marginRight;
|
||||
@@ -210,8 +219,7 @@ void PIScreenTile::layout() {
|
||||
for (int j = 0; j < tiles.size_s(); ++j) {
|
||||
if (i == j) continue;
|
||||
if (max_tl[j]) continue;
|
||||
if (tiles[j]->size_policy == pol && tiles[j]->visible && tiles[j]->needLayout())
|
||||
asizes[j] += pas;
|
||||
if (tiles[j]->size_policy == pol && tiles[j]->visible && tiles[j]->needLayout()) asizes[j] += pas;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -241,8 +249,7 @@ void PIScreenTile::layout() {
|
||||
t->height_ = hints[i];
|
||||
cy += hints[i] + spacing;
|
||||
}
|
||||
if (t->pw != t->width_ || t->ph != t->height_)
|
||||
t->resizeEvent(t->width_, t->height_);
|
||||
if (t->pw != t->width_ || t->ph != t->height_) t->resizeEvent(t->width_, t->height_);
|
||||
t->pw = t->width_;
|
||||
t->ph = t->height_;
|
||||
t->layout();
|
||||
|
||||
@@ -16,17 +16,19 @@
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "piincludes_p.h"
|
||||
#include "piterminal.h"
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "pisharedmemory.h"
|
||||
#ifndef MICRO_PIP
|
||||
# ifdef WINDOWS
|
||||
# include <wincon.h>
|
||||
# include <windows.h>
|
||||
# include <wingdi.h>
|
||||
# include <wincon.h>
|
||||
# include <winuser.h>
|
||||
# else
|
||||
# include "piprocess.h"
|
||||
|
||||
# include <csignal>
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
@@ -123,8 +125,7 @@ PITerminal::PITerminal(): PIThread() {
|
||||
|
||||
|
||||
PITerminal::~PITerminal() {
|
||||
if (isRunning())
|
||||
stop();
|
||||
if (isRunning()) stop();
|
||||
PIThread::waitForFinish(10);
|
||||
destroy();
|
||||
# ifdef WINDOWS
|
||||
@@ -165,7 +166,8 @@ void PITerminal::write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers
|
||||
default: break;
|
||||
}
|
||||
// piCout << "write" << ba.size();
|
||||
if (!ba.isEmpty()) write(ba);
|
||||
if (!ba.isEmpty())
|
||||
write(ba);
|
||||
else {
|
||||
PIByteArray msg;
|
||||
PIVector<PIKbdListener::KeyEvent> ke;
|
||||
@@ -185,7 +187,8 @@ void PITerminal::write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers
|
||||
case PIKbdListener::UpArrow:
|
||||
case PIKbdListener::DownArrow:
|
||||
case PIKbdListener::RightArrow:
|
||||
case PIKbdListener::LeftArrow: if (PRIVATE->DEC.value(CKM, false)) flags = 1;
|
||||
case PIKbdListener::LeftArrow:
|
||||
if (PRIVATE->DEC.value(CKM, false)) flags = 1;
|
||||
/*case PIKbdListener::Home: //break;
|
||||
case PIKbdListener::End: //break;
|
||||
case PIKbdListener::PageUp: //ba << uchar('\e') << uchar('[') << uchar('5') << uchar('~'); break;
|
||||
@@ -235,7 +238,8 @@ void PITerminal::write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers
|
||||
|
||||
|
||||
void PITerminal::write(PIKbdListener::KeyEvent ke) {
|
||||
if (isSpecialKey(ke.key)) write((PIKbdListener::SpecialKey)ke.key, ke.modifiers);
|
||||
if (isSpecialKey(ke.key))
|
||||
write((PIKbdListener::SpecialKey)ke.key, ke.modifiers);
|
||||
else {
|
||||
PIByteArray ba;
|
||||
# ifdef WINDOWS
|
||||
@@ -253,8 +257,7 @@ PIVector<PIVector<PIScreenTypes::Cell> > PITerminal::content() {
|
||||
PIVector<PIVector<PIScreenTypes::Cell>> ret = cells;
|
||||
if (cursor_blink && cursor_visible)
|
||||
if (cursor_x >= 0 && cursor_x < size_x)
|
||||
if (cursor_y >= 0 && cursor_y < size_y)
|
||||
ret[cursor_y][cursor_x].format.flags ^= PIScreenTypes::Inverse;
|
||||
if (cursor_y >= 0 && cursor_y < size_y) ret[cursor_y][cursor_x].format.flags ^= PIScreenTypes::Inverse;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -395,8 +398,7 @@ void PITerminal::run() {
|
||||
}
|
||||
bool parse = PRIVATE->read_buf.size_s() >= BUFFER_SIZE;
|
||||
if (PRIVATE->read_buf.size_s() == 1)
|
||||
if (PRIVATE->read_buf[0] < 0x80)
|
||||
parse = true;
|
||||
if (PRIVATE->read_buf[0] < 0x80) parse = true;
|
||||
if (parse) {
|
||||
parseInput(PIString(PRIVATE->read_buf));
|
||||
PRIVATE->read_buf.clear();
|
||||
@@ -445,7 +447,8 @@ void PITerminal::parseInput(const PIString & s) {
|
||||
if (s[i] == '\r') continue;
|
||||
if (s[i] == '\n') {
|
||||
// piCoutObj << "new line";
|
||||
for (int i = PRIVATE->cur_x; i < size_x; ++i) cells[PRIVATE->cur_y][i].format = PRIVATE->cur_format;
|
||||
for (int i = PRIVATE->cur_x; i < size_x; ++i)
|
||||
cells[PRIVATE->cur_y][i].format = PRIVATE->cur_format;
|
||||
PRIVATE->line_format = PRIVATE->cur_format;
|
||||
PRIVATE->cur_x = 0;
|
||||
moveCursor(0, 1);
|
||||
@@ -498,7 +501,8 @@ void PITerminal::applyEscSeq(PIString es) {
|
||||
case 1047:
|
||||
if (val) {
|
||||
PRIVATE->cells_save = cells;
|
||||
for (int i = 0; i < size_y; ++i) cells[i].fill(def_cell);
|
||||
for (int i = 0; i < size_y; ++i)
|
||||
cells[i].fill(def_cell);
|
||||
} else {
|
||||
cells = PRIVATE->cells_save;
|
||||
}
|
||||
@@ -524,8 +528,14 @@ void PITerminal::applyEscSeq(PIString es) {
|
||||
default: {
|
||||
bool col = false, target = false;
|
||||
int cid = av % 10;
|
||||
if (av >= 30 && av <= 37) {col = true; target = false;}
|
||||
if (av >= 40 && av <= 47) {col = true; target = true;}
|
||||
if (av >= 30 && av <= 37) {
|
||||
col = true;
|
||||
target = false;
|
||||
}
|
||||
if (av >= 40 && av <= 47) {
|
||||
col = true;
|
||||
target = true;
|
||||
}
|
||||
if (col) {
|
||||
int cfl = 0;
|
||||
switch (cid) {
|
||||
@@ -586,25 +596,29 @@ void PITerminal::applyEscSeq(PIString es) {
|
||||
}
|
||||
if (es.back() == 'A') { // cursor up
|
||||
es.cutLeft(1).cutRight(1);
|
||||
int v = es.toInt(); if (v == 0) v = 1;
|
||||
int v = es.toInt();
|
||||
if (v == 0) v = 1;
|
||||
PRIVATE->cur_y = piClamp(PRIVATE->cur_y - v, 0, size_y - 1);
|
||||
PRIVATE->line_format = PRIVATE->cur_format;
|
||||
}
|
||||
if (es.back() == 'B') { // cursor down
|
||||
es.cutLeft(1).cutRight(1);
|
||||
int v = es.toInt(); if (v == 0) v = 1;
|
||||
int v = es.toInt();
|
||||
if (v == 0) v = 1;
|
||||
PRIVATE->cur_y = piClamp(PRIVATE->cur_y + v, 0, size_y - 1);
|
||||
PRIVATE->line_format = PRIVATE->cur_format;
|
||||
}
|
||||
if (es.back() == 'C' || es.back() == 'a') { // cursor forward, next column
|
||||
es.cutLeft(1).cutRight(1);
|
||||
int v = es.toInt(); if (v == 0) v = 1;
|
||||
int v = es.toInt();
|
||||
if (v == 0) v = 1;
|
||||
PRIVATE->cur_x = piClamp(PRIVATE->cur_x + v, 0, size_x - 1);
|
||||
PRIVATE->line_format = PRIVATE->cur_format;
|
||||
}
|
||||
if (es.back() == 'D') { // cursor back
|
||||
es.cutLeft(1).cutRight(1);
|
||||
int v = es.toInt(); if (v == 0) v = 1;
|
||||
int v = es.toInt();
|
||||
if (v == 0) v = 1;
|
||||
PRIVATE->cur_x = piClamp(PRIVATE->cur_x - v, 0, size_x - 1);
|
||||
PRIVATE->line_format = PRIVATE->cur_format;
|
||||
}
|
||||
@@ -616,65 +630,91 @@ void PITerminal::applyEscSeq(PIString es) {
|
||||
}
|
||||
if (es.back() == 'd') { // goto line
|
||||
es.cutLeft(1).cutRight(1);
|
||||
int v = es.toInt(); if (v == 0) v = 1;
|
||||
int v = es.toInt();
|
||||
if (v == 0) v = 1;
|
||||
PRIVATE->cur_x = 0;
|
||||
PRIVATE->cur_y = piClamp(v - 1, 0, size_y - 1);
|
||||
PRIVATE->line_format = PRIVATE->cur_format;
|
||||
}
|
||||
if (es.back() == 'E' || es.back() == 'e') { // next line
|
||||
es.cutLeft(1).cutRight(1);
|
||||
int v = es.toInt(); if (v == 0) v = 1;
|
||||
int v = es.toInt();
|
||||
if (v == 0) v = 1;
|
||||
PRIVATE->cur_x = 0;
|
||||
PRIVATE->cur_y = piClamp(PRIVATE->cur_y + v, 0, size_y - 1);
|
||||
PRIVATE->line_format = PRIVATE->cur_format;
|
||||
}
|
||||
if (es.back() == 'F') { // previous line
|
||||
es.cutLeft(1).cutRight(1);
|
||||
int v = es.toInt(); if (v == 0) v = 1;
|
||||
int v = es.toInt();
|
||||
if (v == 0) v = 1;
|
||||
PRIVATE->cur_x = 0;
|
||||
PRIVATE->cur_y = piClamp(PRIVATE->cur_y - v, 0, size_y - 1);
|
||||
PRIVATE->line_format = PRIVATE->cur_format;
|
||||
}
|
||||
if (es.back() == 'L') { // insert lines
|
||||
es.cutLeft(1).cutRight(1);
|
||||
int v = es.toInt(); if (v == 0) v = 1;
|
||||
for (int i = piClamp(size_y - 1, PRIVATE->win_y0, PRIVATE->win_y1); i >= piClamp(PRIVATE->cur_y + v, PRIVATE->win_y0, PRIVATE->win_y1); --i) cells[i] = cells[i - v];
|
||||
for (int j = piClamp(PRIVATE->cur_y, PRIVATE->win_y0, PRIVATE->win_y1); j < piClamp(PRIVATE->cur_y + v, PRIVATE->win_y0, PRIVATE->win_y1); ++j)
|
||||
for (int i = 0; i < PRIVATE->cur_x; ++i) cells[j][i] = def_cell;
|
||||
int v = es.toInt();
|
||||
if (v == 0) v = 1;
|
||||
for (int i = piClamp(size_y - 1, PRIVATE->win_y0, PRIVATE->win_y1);
|
||||
i >= piClamp(PRIVATE->cur_y + v, PRIVATE->win_y0, PRIVATE->win_y1);
|
||||
--i)
|
||||
cells[i] = cells[i - v];
|
||||
for (int j = piClamp(PRIVATE->cur_y, PRIVATE->win_y0, PRIVATE->win_y1);
|
||||
j < piClamp(PRIVATE->cur_y + v, PRIVATE->win_y0, PRIVATE->win_y1);
|
||||
++j)
|
||||
for (int i = 0; i < PRIVATE->cur_x; ++i)
|
||||
cells[j][i] = def_cell;
|
||||
}
|
||||
if (es.back() == 'M') { // delete lines
|
||||
es.cutLeft(1).cutRight(1);
|
||||
int v = es.toInt(); if (v == 0) v = 1;
|
||||
for (int i = piClamp(PRIVATE->cur_y, PRIVATE->win_y0, PRIVATE->win_y1); i < piClamp(size_y - v, PRIVATE->win_y0, PRIVATE->win_y1); ++i) cells[i] = cells[i + v];
|
||||
int v = es.toInt();
|
||||
if (v == 0) v = 1;
|
||||
for (int i = piClamp(PRIVATE->cur_y, PRIVATE->win_y0, PRIVATE->win_y1);
|
||||
i < piClamp(size_y - v, PRIVATE->win_y0, PRIVATE->win_y1);
|
||||
++i)
|
||||
cells[i] = cells[i + v];
|
||||
for (int j = piClamp(size_y - v, PRIVATE->win_y0, PRIVATE->win_y1); j < piClamp(size_y, PRIVATE->win_y0, PRIVATE->win_y1); ++j)
|
||||
for (int i = 0; i < PRIVATE->cur_x; ++i) cells[j][i] = def_cell;
|
||||
for (int i = 0; i < PRIVATE->cur_x; ++i)
|
||||
cells[j][i] = def_cell;
|
||||
}
|
||||
if (es.back() == 'P') { // delete characters
|
||||
es.cutLeft(1).cutRight(1);
|
||||
int v = es.toInt(); if (v == 0) v = 1;
|
||||
for (int i = PRIVATE->cur_x; i < size_x - v; ++i) cells[PRIVATE->cur_y][i] = cells[PRIVATE->cur_y][i + v];
|
||||
for (int i = size_x - v; i < size_x; ++i) cells[PRIVATE->cur_y][i] = def_cell;
|
||||
int v = es.toInt();
|
||||
if (v == 0) v = 1;
|
||||
for (int i = PRIVATE->cur_x; i < size_x - v; ++i)
|
||||
cells[PRIVATE->cur_y][i] = cells[PRIVATE->cur_y][i + v];
|
||||
for (int i = size_x - v; i < size_x; ++i)
|
||||
cells[PRIVATE->cur_y][i] = def_cell;
|
||||
}
|
||||
if (es.back() == '@') { // delete characters
|
||||
es.cutLeft(1).cutRight(1);
|
||||
int v = es.toInt(); if (v == 0) v = 1;
|
||||
for (int i = size_x - 1; i >= PRIVATE->cur_x + v; --i) cells[PRIVATE->cur_y][i] = cells[PRIVATE->cur_y][i - v];
|
||||
for (int i = PRIVATE->cur_x; i < PRIVATE->cur_x + v; ++i) cells[PRIVATE->cur_y][i] = def_cell;
|
||||
int v = es.toInt();
|
||||
if (v == 0) v = 1;
|
||||
for (int i = size_x - 1; i >= PRIVATE->cur_x + v; --i)
|
||||
cells[PRIVATE->cur_y][i] = cells[PRIVATE->cur_y][i - v];
|
||||
for (int i = PRIVATE->cur_x; i < PRIVATE->cur_x + v; ++i)
|
||||
cells[PRIVATE->cur_y][i] = def_cell;
|
||||
}
|
||||
if (es.back() == 'J') { // erase data
|
||||
es.cutLeft(1).cutRight(1);
|
||||
int v = es.toInt();
|
||||
switch (v) {
|
||||
case 0:
|
||||
for (int i = PRIVATE->cur_x; i < size_x; ++i) cells[PRIVATE->cur_y][i] = def_cell;
|
||||
for (int i = PRIVATE->cur_y + 1; i < size_y; ++i) cells[i].fill(def_cell);
|
||||
for (int i = PRIVATE->cur_x; i < size_x; ++i)
|
||||
cells[PRIVATE->cur_y][i] = def_cell;
|
||||
for (int i = PRIVATE->cur_y + 1; i < size_y; ++i)
|
||||
cells[i].fill(def_cell);
|
||||
break;
|
||||
case 1:
|
||||
for (int i = 0; i <= PRIVATE->cur_x; ++i) cells[PRIVATE->cur_y][i] = def_cell;
|
||||
for (int i = 0; i < PRIVATE->cur_y; ++i) cells[i].fill(def_cell);
|
||||
for (int i = 0; i <= PRIVATE->cur_x; ++i)
|
||||
cells[PRIVATE->cur_y][i] = def_cell;
|
||||
for (int i = 0; i < PRIVATE->cur_y; ++i)
|
||||
cells[i].fill(def_cell);
|
||||
break;
|
||||
case 2:
|
||||
for (int i = 0; i < size_y; ++i) cells[i].fill(def_cell);
|
||||
for (int i = 0; i < size_y; ++i)
|
||||
cells[i].fill(def_cell);
|
||||
// PRIVATE->cur_x = PRIVATE->cur_y = 0;
|
||||
break;
|
||||
}
|
||||
@@ -684,14 +724,14 @@ void PITerminal::applyEscSeq(PIString es) {
|
||||
int v = es.toInt();
|
||||
switch (v) {
|
||||
case 0:
|
||||
for (int i = PRIVATE->cur_x; i < size_x; ++i) cells[PRIVATE->cur_y][i] = def_cell;
|
||||
for (int i = PRIVATE->cur_x; i < size_x; ++i)
|
||||
cells[PRIVATE->cur_y][i] = def_cell;
|
||||
break;
|
||||
case 1:
|
||||
for (int i = 0; i <= PRIVATE->cur_x; ++i) cells[PRIVATE->cur_y][i] = def_cell;
|
||||
break;
|
||||
case 2:
|
||||
cells[PRIVATE->cur_y].fill(def_cell);
|
||||
for (int i = 0; i <= PRIVATE->cur_x; ++i)
|
||||
cells[PRIVATE->cur_y][i] = def_cell;
|
||||
break;
|
||||
case 2: cells[PRIVATE->cur_y].fill(def_cell); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -721,8 +761,10 @@ void PITerminal::moveCursor(int dx, int dy) {
|
||||
|
||||
|
||||
int PITerminal::termType(const PIString & t) {
|
||||
if (t == "xterm") return PIKbdListener::vt_xterm;
|
||||
else if (t == "linux") return PIKbdListener::vt_linux;
|
||||
if (t == "xterm")
|
||||
return PIKbdListener::vt_xterm;
|
||||
else if (t == "linux")
|
||||
return PIKbdListener::vt_linux;
|
||||
return PIKbdListener::vt_none;
|
||||
}
|
||||
# endif
|
||||
@@ -767,12 +809,28 @@ bool PITerminal::initialize() {
|
||||
PIString shmh = PIString::fromNumber(randomi() % 10000);
|
||||
PIString pname = "\\\\.\\pipe\\piterm" + shmh;
|
||||
PIString cmd = "piterminal \"" + shmh + "\" \"" + pname + "\"";
|
||||
if(!CreateProcessA(0, (LPSTR)cmd.dataAscii(), 0, 0, false, CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, 0, 0, &PRIVATE->si, &PRIVATE->pi)) {
|
||||
if (!CreateProcessA(0,
|
||||
(LPSTR)cmd.dataAscii(),
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
|
||||
0,
|
||||
0,
|
||||
&PRIVATE->si,
|
||||
&PRIVATE->pi)) {
|
||||
piCoutObj << "CreateProcess error," << errorString();
|
||||
destroy();
|
||||
return false;
|
||||
}
|
||||
PRIVATE->pipe = CreateNamedPipeA((LPSTR)pname.dataAscii(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 2, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 1000, NULL);
|
||||
PRIVATE->pipe = CreateNamedPipeA((LPSTR)pname.dataAscii(),
|
||||
PIPE_ACCESS_DUPLEX,
|
||||
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
||||
2,
|
||||
PIPE_BUFFER_SIZE,
|
||||
PIPE_BUFFER_SIZE,
|
||||
1000,
|
||||
NULL);
|
||||
if (PRIVATE->pipe == INVALID_HANDLE_VALUE) {
|
||||
piCoutObj << "CreateNamedPipe error," << errorString();
|
||||
destroy();
|
||||
@@ -797,7 +855,8 @@ bool PITerminal::initialize() {
|
||||
resize(dsize_x, dsize_y);
|
||||
# else
|
||||
# ifdef HAS_FORKPTY
|
||||
char pty[256]; memset(pty, 0, 256);
|
||||
char pty[256];
|
||||
memset(pty, 0, 256);
|
||||
winsize ws;
|
||||
ws.ws_col = dsize_x;
|
||||
ws.ws_row = dsize_y;
|
||||
@@ -877,10 +936,8 @@ void PITerminal::destroy() {
|
||||
// piCout << "destroy" << size_y;
|
||||
# else
|
||||
# ifdef HAS_FORKPTY
|
||||
if (PRIVATE->pid != 0)
|
||||
kill(PRIVATE->pid, SIGKILL);
|
||||
if (PRIVATE->fd != 0)
|
||||
::close(PRIVATE->fd);
|
||||
if (PRIVATE->pid != 0) kill(PRIVATE->pid, SIGKILL);
|
||||
if (PRIVATE->fd != 0) ::close(PRIVATE->fd);
|
||||
# endif
|
||||
# endif
|
||||
initPrivate();
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
# include <sodium.h>
|
||||
#endif
|
||||
|
||||
#define PICRYPT_DISABLED_WARNING piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and rebuild pip";
|
||||
#define PICRYPT_DISABLED_WARNING \
|
||||
piCout << "[PICrypt]" \
|
||||
<< "Warning: PICrypt is disabled, to enable install sodium library and rebuild pip";
|
||||
|
||||
const char hash_def_key[] = "_picrypt_\0\0\0\0\0\0\0";
|
||||
const int hash_def_key_size = 9;
|
||||
@@ -30,7 +32,9 @@ const int hash_def_key_size = 9;
|
||||
|
||||
PICrypt::PICrypt() {
|
||||
#ifdef PIP_CRYPT
|
||||
if (!init()) piCout << "[PICrypt]" << "Error while initialize sodium!";
|
||||
if (!init())
|
||||
piCout << "[PICrypt]"
|
||||
<< "Error while initialize sodium!";
|
||||
nonce_.resize(crypto_secretbox_NONCEBYTES);
|
||||
key_.resize(crypto_secretbox_KEYBYTES);
|
||||
randombytes_buf(key_.data(), key_.size());
|
||||
@@ -76,8 +80,7 @@ PIByteArray PICrypt::crypt(const PIByteArray & data) {
|
||||
PIByteArray PICrypt::crypt(const PIByteArray & data, PIByteArray key) {
|
||||
PIByteArray ret;
|
||||
#ifdef PIP_CRYPT
|
||||
if (key.size() != crypto_secretbox_KEYBYTES)
|
||||
key.resize(crypto_secretbox_KEYBYTES, ' ');
|
||||
if (key.size() != crypto_secretbox_KEYBYTES) key.resize(crypto_secretbox_KEYBYTES, ' ');
|
||||
// return PIByteArray();
|
||||
if (!init()) return ret;
|
||||
PIByteArray n;
|
||||
@@ -116,8 +119,7 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, bool *ok) {
|
||||
PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bool * ok) {
|
||||
PIByteArray ret;
|
||||
#ifdef PIP_CRYPT
|
||||
if (key.size() != crypto_secretbox_KEYBYTES)
|
||||
key.resize(crypto_secretbox_KEYBYTES, ' ');
|
||||
if (key.size() != crypto_secretbox_KEYBYTES) key.resize(crypto_secretbox_KEYBYTES, ' ');
|
||||
/*if (ok) *ok = false;
|
||||
return PIByteArray();
|
||||
}*/
|
||||
@@ -134,7 +136,8 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bo
|
||||
if (ok) *ok = false;
|
||||
// piCout << "[PICrypt]" << "bad key_";
|
||||
return PIByteArray();
|
||||
} else if (ok) *ok = true;
|
||||
} else if (ok)
|
||||
*ok = true;
|
||||
#else
|
||||
PICRYPT_DISABLED_WARNING
|
||||
#endif
|
||||
@@ -195,10 +198,13 @@ size_t PICrypt::sizeHash() {
|
||||
ullong PICrypt::shorthash(const PIString & s, PIByteArray key) {
|
||||
ullong hash = 0;
|
||||
#ifdef PIP_CRYPT
|
||||
if (crypto_shorthash_BYTES != sizeof(hash)) piCout << "[PICrypt]" << "internal error: bad hash size";
|
||||
if (crypto_shorthash_BYTES != sizeof(hash))
|
||||
piCout << "[PICrypt]"
|
||||
<< "internal error: bad hash size";
|
||||
if (!init()) return hash;
|
||||
if (key.size() != crypto_shorthash_KEYBYTES) {
|
||||
piCout << "[PICrypt]" << "invalid key size" << key.size() << ", shoud be" << crypto_shorthash_KEYBYTES << ", filled zeros";
|
||||
piCout << "[PICrypt]"
|
||||
<< "invalid key size" << key.size() << ", shoud be" << crypto_shorthash_KEYBYTES << ", filled zeros";
|
||||
key.resize(crypto_shorthash_KEYBYTES, 0);
|
||||
}
|
||||
PIByteArray in(s.data(), s.size());
|
||||
@@ -345,16 +351,13 @@ PIByteArray PICrypt::crypt(const PIByteArray & data, const PIByteArray & public_
|
||||
PIByteArray ret;
|
||||
#ifdef PIP_CRYPT
|
||||
if (!init()) return ret;
|
||||
if (public_key.size() != crypto_box_PUBLICKEYBYTES)
|
||||
return ret;
|
||||
if (secret_key.size() != crypto_box_SECRETKEYBYTES)
|
||||
return ret;
|
||||
if (public_key.size() != crypto_box_PUBLICKEYBYTES) return ret;
|
||||
if (secret_key.size() != crypto_box_SECRETKEYBYTES) return ret;
|
||||
PIByteArray n;
|
||||
ret.resize(data.size() + crypto_box_MACBYTES);
|
||||
n.resize(crypto_box_NONCEBYTES);
|
||||
randombytes_buf(n.data(), n.size());
|
||||
if (crypto_box_easy(ret.data(), data.data(), data.size(), n.data(), public_key.data(), secret_key.data()) != 0)
|
||||
return PIByteArray();
|
||||
if (crypto_box_easy(ret.data(), data.data(), data.size(), n.data(), public_key.data(), secret_key.data()) != 0) return PIByteArray();
|
||||
ret.append(n);
|
||||
#else
|
||||
PICRYPT_DISABLED_WARNING
|
||||
@@ -383,11 +386,13 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, const PIByteArray &
|
||||
n.resize(crypto_secretbox_NONCEBYTES);
|
||||
ret.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES);
|
||||
memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size());
|
||||
if (crypto_box_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), public_key.data(), secret_key.data()) != 0) {
|
||||
if (crypto_box_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), public_key.data(), secret_key.data()) !=
|
||||
0) {
|
||||
if (ok) *ok = false;
|
||||
// piCout << "[PICrypt]" << "bad key_";
|
||||
return PIByteArray();
|
||||
} else if (ok) *ok = true;
|
||||
} else if (ok)
|
||||
*ok = true;
|
||||
#else
|
||||
PICRYPT_DISABLED_WARNING
|
||||
#endif
|
||||
@@ -405,8 +410,16 @@ PIByteArray PICrypt::passwordHash(const PIString & password, const PIByteArray &
|
||||
n.resize(crypto_pwhash_SALTBYTES);
|
||||
// randombytes_buf(n.data(), n.size());
|
||||
// crypto_shorthash(n.data(), seed.data(), seed.size(), PIByteArray(crypto_shorthash_KEYBYTES).data());
|
||||
int r = crypto_pwhash(ph.data(), ph.size(), (const char*)pass.data(), pass.size(), n.data(), crypto_pwhash_argon2i_opslimit_moderate(), crypto_pwhash_argon2i_memlimit_moderate(), crypto_pwhash_ALG_ARGON2I13);
|
||||
//crypto_pwhash_str(out, (const char*)pass.data(), pass.size(), crypto_pwhash_argon2i_opslimit_moderate(), crypto_pwhash_argon2i_memlimit_moderate());
|
||||
int r = crypto_pwhash(ph.data(),
|
||||
ph.size(),
|
||||
(const char *)pass.data(),
|
||||
pass.size(),
|
||||
n.data(),
|
||||
crypto_pwhash_argon2i_opslimit_moderate(),
|
||||
crypto_pwhash_argon2i_memlimit_moderate(),
|
||||
crypto_pwhash_ALG_ARGON2I13);
|
||||
// crypto_pwhash_str(out, (const char*)pass.data(), pass.size(), crypto_pwhash_argon2i_opslimit_moderate(),
|
||||
// crypto_pwhash_argon2i_memlimit_moderate());
|
||||
pass.fill(0);
|
||||
if (r != 0) return PIByteArray();
|
||||
return ph;
|
||||
@@ -434,8 +447,7 @@ bool PICrypt::init() {
|
||||
if (inited) return true;
|
||||
// piCout << "[PICrypt]" << "init ...";
|
||||
inited = sodium_init();
|
||||
if (!inited)
|
||||
inited = sodium_init();
|
||||
if (!inited) inited = sodium_init();
|
||||
// piCout << "[PICrypt]" << "init" << inited;
|
||||
return inited;
|
||||
#else
|
||||
@@ -443,6 +455,3 @@ bool PICrypt::init() {
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -18,16 +18,30 @@
|
||||
*/
|
||||
|
||||
#include "pifft.h"
|
||||
|
||||
#include "pifft_p.h"
|
||||
|
||||
|
||||
#define _PIFFTW_CPP(type) \
|
||||
_PIFFTW_P_##type##_::_PIFFTW_P_##type##_() {impl = new PIFFTW_Private<type>();;} \
|
||||
_PIFFTW_P_##type##_::~_PIFFTW_P_##type##_() {delete (PIFFTW_Private<type>*)impl;} \
|
||||
const PIVector<complex<type> > & _PIFFTW_P_##type##_::calcFFT(const PIVector<complex<type> > & in) {return ((PIFFTW_Private<type>*)impl)->calcFFT(in);} \
|
||||
const PIVector<complex<type> > & _PIFFTW_P_##type##_::calcFFTR(const PIVector<type> & in) {return ((PIFFTW_Private<type>*)impl)->calcFFT(in);} \
|
||||
const PIVector<complex<type> > & _PIFFTW_P_##type##_::calcFFTI(const PIVector<complex<type> > & in) {return ((PIFFTW_Private<type>*)impl)->calcFFTinverse(in);} \
|
||||
void _PIFFTW_P_##type##_::preparePlan(int size, int op) {return ((PIFFTW_Private<type>*)impl)->preparePlan(size, op);}
|
||||
_PIFFTW_P_##type##_::_PIFFTW_P_##type##_() { \
|
||||
impl = new PIFFTW_Private<type>(); \
|
||||
; \
|
||||
} \
|
||||
_PIFFTW_P_##type##_::~_PIFFTW_P_##type##_() { \
|
||||
delete (PIFFTW_Private<type> *)impl; \
|
||||
} \
|
||||
const PIVector<complex<type>> & _PIFFTW_P_##type##_::calcFFT(const PIVector<complex<type>> & in) { \
|
||||
return ((PIFFTW_Private<type> *)impl)->calcFFT(in); \
|
||||
} \
|
||||
const PIVector<complex<type>> & _PIFFTW_P_##type##_::calcFFTR(const PIVector<type> & in) { \
|
||||
return ((PIFFTW_Private<type> *)impl)->calcFFT(in); \
|
||||
} \
|
||||
const PIVector<complex<type>> & _PIFFTW_P_##type##_::calcFFTI(const PIVector<complex<type>> & in) { \
|
||||
return ((PIFFTW_Private<type> *)impl)->calcFFTinverse(in); \
|
||||
} \
|
||||
void _PIFFTW_P_##type##_::preparePlan(int size, int op) { \
|
||||
return ((PIFFTW_Private<type> *)impl)->preparePlan(size, op); \
|
||||
}
|
||||
|
||||
_PIFFTW_CPP(float)
|
||||
_PIFFTW_CPP(double)
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#ifndef PIFFT_P_H
|
||||
#define PIFFT_P_H
|
||||
|
||||
#include "pivector.h"
|
||||
#include "picout.h"
|
||||
#include "pivector.h"
|
||||
#if defined(PIP_FFTW) || defined(PIP_FFTWf) || defined(PIP_FFTWl) || defined(PIP_FFTWq)
|
||||
# include "fftw3.h"
|
||||
#else
|
||||
@@ -36,8 +36,7 @@
|
||||
|
||||
|
||||
template<typename T>
|
||||
class PIFFTW_Private
|
||||
{
|
||||
class PIFFTW_Private {
|
||||
public:
|
||||
explicit PIFFTW_Private() {
|
||||
plan = 0;
|
||||
@@ -79,7 +78,11 @@ public:
|
||||
return p_out;
|
||||
}
|
||||
|
||||
enum FFT_Operation {fo_real, fo_complex, fo_inverse};
|
||||
enum FFT_Operation {
|
||||
fo_real,
|
||||
fo_complex,
|
||||
fo_inverse
|
||||
};
|
||||
|
||||
void preparePlan(int size, int op) {
|
||||
p_inr.clear();
|
||||
@@ -101,9 +104,7 @@ public:
|
||||
p_out.resize(size);
|
||||
p_createPlan_c2c_1d(plan, size, p_in.data(), p_out.data(), FFTW_BACKWARD, FFTW_MEASURE | FFTW_UNALIGNED);
|
||||
break;
|
||||
default:
|
||||
size = 0;
|
||||
break;
|
||||
default: size = 0; break;
|
||||
}
|
||||
prepare = PlanParams(size, (FFT_Operation)op);
|
||||
}
|
||||
@@ -117,8 +118,14 @@ public:
|
||||
inline void p_makeThreadSafe() {}
|
||||
|
||||
struct PlanParams {
|
||||
PlanParams() {size = 0; op = fo_complex;}
|
||||
PlanParams(int size_, FFT_Operation op_) {size = size_; op = op_;}
|
||||
PlanParams() {
|
||||
size = 0;
|
||||
op = fo_complex;
|
||||
}
|
||||
PlanParams(int size_, FFT_Operation op_) {
|
||||
size = size_;
|
||||
op = op_;
|
||||
}
|
||||
bool isValid() { return size > 0; }
|
||||
bool operator==(const PlanParams & v) const { return (v.size == size) && (v.op == op); }
|
||||
bool operator!=(const PlanParams & v) const { return !(*this == v); }
|
||||
@@ -135,44 +142,104 @@ public:
|
||||
|
||||
|
||||
#ifdef PIP_FFTWf
|
||||
template<> inline void PIFFTW_Private<float>::p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) {
|
||||
plan = fftwf_plan_dft_1d(size, (fftwf_complex *)in, (fftwf_complex *)out, dir, flags);}
|
||||
template<> inline void PIFFTW_Private<float>::p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) {
|
||||
plan = fftwf_plan_dft_r2c_1d(size, (float *)in, (fftwf_complex *)out, flags);}
|
||||
template<> inline void PIFFTW_Private<float>::p_executePlan(void * plan) {fftwf_execute((fftwf_plan)plan);}
|
||||
template<> inline void PIFFTW_Private<float>::p_executePlan_c2c(void * plan, const void * in, void * out) {fftwf_execute_dft((fftwf_plan)plan, (fftwf_complex *)in, (fftwf_complex *)out);}
|
||||
template<> inline void PIFFTW_Private<float>::p_executePlan_r2c(void * plan, const void * in, void * out) {fftwf_execute_dft_r2c((fftwf_plan)plan, (float *)in, (fftwf_complex *)out);}
|
||||
template<> inline void PIFFTW_Private<float>::p_destroyPlan(void *& plan) {if (plan) fftwf_destroy_plan((fftwf_plan)plan); plan = 0;}
|
||||
template<>
|
||||
inline void PIFFTW_Private<float>::p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) {
|
||||
plan = fftwf_plan_dft_1d(size, (fftwf_complex *)in, (fftwf_complex *)out, dir, flags);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<float>::p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) {
|
||||
plan = fftwf_plan_dft_r2c_1d(size, (float *)in, (fftwf_complex *)out, flags);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<float>::p_executePlan(void * plan) {
|
||||
fftwf_execute((fftwf_plan)plan);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<float>::p_executePlan_c2c(void * plan, const void * in, void * out) {
|
||||
fftwf_execute_dft((fftwf_plan)plan, (fftwf_complex *)in, (fftwf_complex *)out);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<float>::p_executePlan_r2c(void * plan, const void * in, void * out) {
|
||||
fftwf_execute_dft_r2c((fftwf_plan)plan, (float *)in, (fftwf_complex *)out);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<float>::p_destroyPlan(void *& plan) {
|
||||
if (plan) fftwf_destroy_plan((fftwf_plan)plan);
|
||||
plan = 0;
|
||||
}
|
||||
# ifdef PIP_FFTWf_THREADSAFE
|
||||
template<> inline void PIFFTW_Private<float>::p_makeThreadSafe() {fftwf_make_planner_thread_safe();}
|
||||
template<>
|
||||
inline void PIFFTW_Private<float>::p_makeThreadSafe() {
|
||||
fftwf_make_planner_thread_safe();
|
||||
}
|
||||
# endif
|
||||
#endif // PIP_FFTWf
|
||||
|
||||
#ifdef PIP_FFTW
|
||||
template<> inline void PIFFTW_Private<double>::p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) {
|
||||
plan = fftw_plan_dft_1d(size, (fftw_complex *)in, (fftw_complex *)out, dir, flags);}
|
||||
template<> inline void PIFFTW_Private<double>::p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) {
|
||||
plan = fftw_plan_dft_r2c_1d(size, (double *)in, (fftw_complex *)out, flags);}
|
||||
template<> inline void PIFFTW_Private<double>::p_executePlan(void * plan) {fftw_execute((fftw_plan)plan);}
|
||||
template<> inline void PIFFTW_Private<double>::p_executePlan_c2c(void * plan, const void * in, void * out) {fftw_execute_dft((fftw_plan)plan, (fftw_complex *)in, (fftw_complex *)out);}
|
||||
template<> inline void PIFFTW_Private<double>::p_executePlan_r2c(void * plan, const void * in, void * out) {fftw_execute_dft_r2c((fftw_plan)plan, (double *)in, (fftw_complex *)out);}
|
||||
template<> inline void PIFFTW_Private<double>::p_destroyPlan(void *& plan) {if (plan) fftw_destroy_plan((fftw_plan)plan); plan = 0;}
|
||||
template<>
|
||||
inline void PIFFTW_Private<double>::p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) {
|
||||
plan = fftw_plan_dft_1d(size, (fftw_complex *)in, (fftw_complex *)out, dir, flags);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<double>::p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) {
|
||||
plan = fftw_plan_dft_r2c_1d(size, (double *)in, (fftw_complex *)out, flags);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<double>::p_executePlan(void * plan) {
|
||||
fftw_execute((fftw_plan)plan);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<double>::p_executePlan_c2c(void * plan, const void * in, void * out) {
|
||||
fftw_execute_dft((fftw_plan)plan, (fftw_complex *)in, (fftw_complex *)out);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<double>::p_executePlan_r2c(void * plan, const void * in, void * out) {
|
||||
fftw_execute_dft_r2c((fftw_plan)plan, (double *)in, (fftw_complex *)out);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<double>::p_destroyPlan(void *& plan) {
|
||||
if (plan) fftw_destroy_plan((fftw_plan)plan);
|
||||
plan = 0;
|
||||
}
|
||||
# ifdef PIP_FFTW_THREADSAFE
|
||||
template<> inline void PIFFTW_Private<double>::p_makeThreadSafe() {fftw_make_planner_thread_safe();}
|
||||
template<>
|
||||
inline void PIFFTW_Private<double>::p_makeThreadSafe() {
|
||||
fftw_make_planner_thread_safe();
|
||||
}
|
||||
# endif
|
||||
#endif // PIP_FFTW
|
||||
|
||||
#ifdef PIP_FFTWl
|
||||
template<> inline void PIFFTW_Private<ldouble>::p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) {
|
||||
plan = fftwl_plan_dft_1d(size, (fftwl_complex *)in, (fftwl_complex *)out, dir, flags);}
|
||||
template<> inline void PIFFTW_Private<ldouble>::p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) {
|
||||
plan = fftwl_plan_dft_r2c_1d(size, (ldouble *)in, (fftwl_complex *)out, flags);}
|
||||
template<> inline void PIFFTW_Private<ldouble>::p_executePlan(void * plan) {fftwl_execute((fftwl_plan)plan);}
|
||||
template<> inline void PIFFTW_Private<ldouble>::p_executePlan_c2c(void * plan, const void * in, void * out) {fftwl_execute_dft((fftwl_plan)plan, (fftwl_complex *)in, (fftwl_complex *)out);}
|
||||
template<> inline void PIFFTW_Private<ldouble>::p_executePlan_r2c(void * plan, const void * in, void * out) {fftwl_execute_dft_r2c((fftwl_plan)plan, (ldouble *)in, (fftwl_complex *)out);}
|
||||
template<> inline void PIFFTW_Private<ldouble>::p_destroyPlan(void *& plan) {if (plan) fftwl_destroy_plan((fftwl_plan)plan); plan = 0;}
|
||||
template<>
|
||||
inline void PIFFTW_Private<ldouble>::p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) {
|
||||
plan = fftwl_plan_dft_1d(size, (fftwl_complex *)in, (fftwl_complex *)out, dir, flags);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<ldouble>::p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) {
|
||||
plan = fftwl_plan_dft_r2c_1d(size, (ldouble *)in, (fftwl_complex *)out, flags);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<ldouble>::p_executePlan(void * plan) {
|
||||
fftwl_execute((fftwl_plan)plan);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<ldouble>::p_executePlan_c2c(void * plan, const void * in, void * out) {
|
||||
fftwl_execute_dft((fftwl_plan)plan, (fftwl_complex *)in, (fftwl_complex *)out);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<ldouble>::p_executePlan_r2c(void * plan, const void * in, void * out) {
|
||||
fftwl_execute_dft_r2c((fftwl_plan)plan, (ldouble *)in, (fftwl_complex *)out);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW_Private<ldouble>::p_destroyPlan(void *& plan) {
|
||||
if (plan) fftwl_destroy_plan((fftwl_plan)plan);
|
||||
plan = 0;
|
||||
}
|
||||
# ifdef PIP_FFTWl_THREADSAFE
|
||||
template<> inline void PIFFTW_Private<ldouble>::p_makeThreadSafe() {fftwl_make_planner_thread_safe();}
|
||||
template<>
|
||||
inline void PIFFTW_Private<ldouble>::p_makeThreadSafe() {
|
||||
fftwl_make_planner_thread_safe();
|
||||
}
|
||||
# endif
|
||||
#endif // PIP_FFTWl
|
||||
|
||||
|
||||
@@ -210,7 +210,8 @@ void PIBroadcast::send(const PIByteArray & data) {
|
||||
PIByteArray cd = cryptData(data);
|
||||
if (cd.isEmpty()) return;
|
||||
PIMutexLocker ml(mcast_mutex);
|
||||
piForeach (PIEthernet * e, eth_mcast) e->send(cd);
|
||||
piForeach(PIEthernet * e, eth_mcast)
|
||||
e->send(cd);
|
||||
if (eth_lo) {
|
||||
for (int i = 0; i < lo_pcnt; ++i) {
|
||||
eth_lo->send("127.0.0.1", lo_port + i, cd);
|
||||
@@ -227,7 +228,8 @@ void PIBroadcast::startRead() {
|
||||
}
|
||||
if (_send_only) return;
|
||||
PIMutexLocker ml(mcast_mutex);
|
||||
piForeach (PIEthernet * e, eth_mcast) e->startThreadedRead();
|
||||
piForeach(PIEthernet * e, eth_mcast)
|
||||
e->startThreadedRead();
|
||||
if (eth_lo) eth_lo->startThreadedRead();
|
||||
_started = true;
|
||||
}
|
||||
@@ -236,7 +238,8 @@ void PIBroadcast::startRead() {
|
||||
void PIBroadcast::stopRead() {
|
||||
if (isRunning()) stop();
|
||||
PIMutexLocker ml(mcast_mutex);
|
||||
piForeach (PIEthernet * e, eth_mcast) e->stopThreadedRead();
|
||||
piForeach(PIEthernet * e, eth_mcast)
|
||||
e->stopThreadedRead();
|
||||
if (eth_lo) eth_lo->stopThreadedRead();
|
||||
_started = false;
|
||||
}
|
||||
|
||||
@@ -51,8 +51,7 @@ PIEthUtilBase::PIEthUtilBase() {
|
||||
}
|
||||
|
||||
|
||||
PIEthUtilBase::~PIEthUtilBase() {
|
||||
}
|
||||
PIEthUtilBase::~PIEthUtilBase() {}
|
||||
|
||||
|
||||
void PIEthUtilBase::setCryptEnabled(bool on) {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
# pragma GCC diagnostic ignored "-Wnonnull"
|
||||
#endif
|
||||
#include "pistreampacker.h"
|
||||
|
||||
#include "piiodevice.h"
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic pop
|
||||
@@ -61,7 +62,8 @@ PIStreamPacker::PIStreamPacker(PIIODevice * dev): PIObject() {
|
||||
void PIStreamPacker::setCryptSizeEnabled(bool on) {
|
||||
crypt_size = on;
|
||||
if (crypt_size) {
|
||||
PIByteArray ba; ba << int(0);
|
||||
PIByteArray ba;
|
||||
ba << int(0);
|
||||
size_crypted_size = cryptData(ba).size_s();
|
||||
} else
|
||||
size_crypted_size = sizeof(int);
|
||||
@@ -83,8 +85,10 @@ void PIStreamPacker::send(const PIByteArray & data) {
|
||||
// piCout << "crypt_frag send" << fcnt << "frags";
|
||||
PIByteArray frag;
|
||||
for (int i = 0; i < fcnt; ++i) {
|
||||
if (i == fcnt - 1) frag = PIByteArray(data.data(fst), data.size_s() - fst);
|
||||
else frag = PIByteArray(data.data(fst), crypt_frag_size);
|
||||
if (i == fcnt - 1)
|
||||
frag = PIByteArray(data.data(fst), data.size_s() - fst);
|
||||
else
|
||||
frag = PIByteArray(data.data(fst), crypt_frag_size);
|
||||
fst += crypt_frag_size;
|
||||
cd << cryptData(frag);
|
||||
}
|
||||
@@ -95,15 +99,18 @@ void PIStreamPacker::send(const PIByteArray & data) {
|
||||
PIByteArray hdr, part;
|
||||
hdr << packet_sign;
|
||||
if (crypt_size) {
|
||||
PIByteArray crsz; crsz << int(cd.size_s());
|
||||
PIByteArray crsz;
|
||||
crsz << int(cd.size_s());
|
||||
hdr.append(cryptData(crsz));
|
||||
} else
|
||||
hdr << int(cd.size_s());
|
||||
cd.insert(0, hdr);
|
||||
int pcnt = (cd.size_s() - 1) / max_packet_size + 1, pst = 0;
|
||||
for (int i = 0; i < pcnt; ++i) {
|
||||
if (i == pcnt - 1) part = PIByteArray(cd.data(pst), cd.size_s() - pst);
|
||||
else part = PIByteArray(cd.data(pst), max_packet_size);
|
||||
if (i == pcnt - 1)
|
||||
part = PIByteArray(cd.data(pst), cd.size_s() - pst);
|
||||
else
|
||||
part = PIByteArray(cd.data(pst), max_packet_size);
|
||||
// piCout << "send" << part.size();
|
||||
sendRequest(part);
|
||||
pst += max_packet_size;
|
||||
@@ -126,8 +133,10 @@ void PIStreamPacker::received(const PIByteArray & data) {
|
||||
ushort sign(0);
|
||||
memcpy(&sign, stream.data(), 2);
|
||||
if (sign != packet_sign) {
|
||||
if (aggressive_optimization) stream.clear();
|
||||
else stream.pop_front();
|
||||
if (aggressive_optimization)
|
||||
stream.clear();
|
||||
else
|
||||
stream.pop_front();
|
||||
continue;
|
||||
}
|
||||
int sz = -1;
|
||||
@@ -136,8 +145,10 @@ void PIStreamPacker::received(const PIByteArray & data) {
|
||||
memcpy(crsz.data(), stream.data(2), size_crypted_size);
|
||||
crsz = decryptData(crsz);
|
||||
if (crsz.size() < sizeof(sz)) {
|
||||
if (aggressive_optimization) stream.clear();
|
||||
else stream.pop_front();
|
||||
if (aggressive_optimization)
|
||||
stream.clear();
|
||||
else
|
||||
stream.pop_front();
|
||||
continue;
|
||||
}
|
||||
crsz >> sz;
|
||||
@@ -145,15 +156,16 @@ void PIStreamPacker::received(const PIByteArray & data) {
|
||||
memcpy(&sz, stream.data(2), size_crypted_size);
|
||||
}
|
||||
if (sz < 0) {
|
||||
if (aggressive_optimization) stream.clear();
|
||||
else stream.pop_front();
|
||||
if (aggressive_optimization)
|
||||
stream.clear();
|
||||
else
|
||||
stream.pop_front();
|
||||
continue;
|
||||
}
|
||||
stream.remove(0, hdr_size);
|
||||
packet.clear();
|
||||
packet_size = sz;
|
||||
if (packet_size == 0)
|
||||
packet_size = -1;
|
||||
if (packet_size == 0) packet_size = -1;
|
||||
continue;
|
||||
} else {
|
||||
int ps = piMini(stream.size_s(), packet_size - packet.size_s());
|
||||
|
||||
@@ -50,4 +50,3 @@ luabridge::LuaRef PILuaProgram::getGlobal(const PIString & name) {
|
||||
luabridge::Namespace PILuaProgram::getGlobalNamespace() {
|
||||
return luabridge::getGlobalNamespace(PRIVATE->lua_state);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
#include "pistreampacker.h"
|
||||
|
||||
|
||||
class PIP_CLOUD_EXPORT PICloudBase
|
||||
{
|
||||
class PIP_CLOUD_EXPORT PICloudBase {
|
||||
public:
|
||||
PICloudBase();
|
||||
|
||||
|
||||
@@ -32,9 +32,11 @@
|
||||
|
||||
//! \brief PICloudClient
|
||||
|
||||
class PIP_CLOUD_EXPORT PICloudClient: public PIIODevice, public PICloudBase
|
||||
{
|
||||
class PIP_CLOUD_EXPORT PICloudClient
|
||||
: public PIIODevice
|
||||
, public PICloudBase {
|
||||
PIIODEVICE(PICloudClient, "");
|
||||
|
||||
public:
|
||||
explicit PICloudClient(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||
virtual ~PICloudClient();
|
||||
@@ -66,7 +68,6 @@ private:
|
||||
PIConditionVariable cond_connect;
|
||||
std::atomic_bool is_connected;
|
||||
std::atomic_bool is_deleted;
|
||||
|
||||
};
|
||||
|
||||
#endif // PICLOUDCLIENT_H
|
||||
|
||||
@@ -51,8 +51,8 @@
|
||||
#ifndef PICLOUDMODULE_H
|
||||
#define PICLOUDMODULE_H
|
||||
|
||||
#include "picloudtcp.h"
|
||||
#include "picloudclient.h"
|
||||
#include "picloudserver.h"
|
||||
#include "picloudtcp.h"
|
||||
|
||||
#endif // PICLOUDMODULE_H
|
||||
|
||||
@@ -30,9 +30,11 @@
|
||||
#include "piconditionvar.h"
|
||||
|
||||
|
||||
class PIP_CLOUD_EXPORT PICloudServer: public PIIODevice, public PICloudBase
|
||||
{
|
||||
class PIP_CLOUD_EXPORT PICloudServer
|
||||
: public PIIODevice
|
||||
, public PICloudBase {
|
||||
PIIODEVICE(PICloudServer, "");
|
||||
|
||||
public:
|
||||
//! PICloudServer
|
||||
explicit PICloudServer(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||
@@ -41,9 +43,11 @@ public:
|
||||
class Client: public PIIODevice {
|
||||
PIIODEVICE(PICloudServer::Client, "");
|
||||
friend class PICloudServer;
|
||||
|
||||
public:
|
||||
Client(PICloudServer * srv = nullptr, uint id = 0);
|
||||
virtual ~Client();
|
||||
|
||||
protected:
|
||||
bool openDevice() override;
|
||||
bool closeDevice() override;
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
#ifndef PICLOUDTCP_H
|
||||
#define PICLOUDTCP_H
|
||||
|
||||
#include "pimutex.h"
|
||||
#include "pip_cloud_export.h"
|
||||
#include "pistring.h"
|
||||
#include "pimutex.h"
|
||||
|
||||
|
||||
class PIEthernet;
|
||||
@@ -37,7 +37,6 @@ class PIStreamPacker;
|
||||
namespace PICloud {
|
||||
|
||||
|
||||
|
||||
class PIP_CLOUD_EXPORT TCP {
|
||||
public:
|
||||
enum Version {
|
||||
@@ -91,9 +90,8 @@ private:
|
||||
PIString server_name;
|
||||
PIStreamPacker * streampacker;
|
||||
PIMutex mutex_send;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace PICloud
|
||||
|
||||
#endif // PICLOUDTCP_H
|
||||
|
||||
@@ -18,28 +18,28 @@
|
||||
*/
|
||||
|
||||
#include "picodeinfo.h"
|
||||
|
||||
#include "pivariant.h"
|
||||
|
||||
|
||||
PIString PICodeInfo::EnumInfo::memberName(int value_) const {
|
||||
piForeachC(PICodeInfo::EnumeratorInfo & e, members)
|
||||
if (e.value == value_)
|
||||
return e.name.toString();
|
||||
if (e.value == value_) return e.name.toString();
|
||||
return PIString();
|
||||
}
|
||||
|
||||
|
||||
int PICodeInfo::EnumInfo::memberValue(const PIString & name_) const {
|
||||
piForeachC(PICodeInfo::EnumeratorInfo & e, members)
|
||||
if (e.name.toString() == name_)
|
||||
return e.value;
|
||||
if (e.name.toString() == name_) return e.value;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
PIVariantTypes::Enum PICodeInfo::EnumInfo::toPIVariantEnum() {
|
||||
PIVariantTypes::Enum en(name.toString());
|
||||
for (auto m: members) en << m.toPIVariantEnumerator();
|
||||
for (auto m: members)
|
||||
en << m.toPIVariantEnumerator();
|
||||
if (!en.isEmpty()) en.selectValue(members.front().value);
|
||||
return en;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,12 @@ typedef const char*(*AccessTypeFunction)(const char *);
|
||||
//! \~english Type information
|
||||
//! \~russian Информация о типе
|
||||
struct PIP_EXPORT TypeInfo {
|
||||
TypeInfo(const PIConstChars & n = PIConstChars(), const PIConstChars & t = PIConstChars(), PICodeInfo::TypeFlags f = 0, int b = -1) {name = n; type = t; flags = f; bits = b;}
|
||||
TypeInfo(const PIConstChars & n = PIConstChars(), const PIConstChars & t = PIConstChars(), PICodeInfo::TypeFlags f = 0, int b = -1) {
|
||||
name = n;
|
||||
type = t;
|
||||
flags = f;
|
||||
bits = b;
|
||||
}
|
||||
|
||||
//! \~english Returns if variable if bitfield
|
||||
//! \~russian Возвращает битовым ли полем является переменная
|
||||
@@ -94,7 +99,6 @@ struct PIP_EXPORT TypeInfo {
|
||||
//! \~english Method information
|
||||
//! \~russian Информация о методе
|
||||
struct PIP_EXPORT FunctionInfo {
|
||||
|
||||
//! \~english Custom PIMETA content
|
||||
//! \~russian Произвольное содержимое PIMETA
|
||||
MetaMap meta;
|
||||
@@ -155,7 +159,10 @@ struct PIP_EXPORT ClassInfo {
|
||||
//! \~english Enumerator information
|
||||
//! \~russian Информация об элементе перечисления
|
||||
struct PIP_EXPORT EnumeratorInfo {
|
||||
EnumeratorInfo(const PIConstChars & n = PIConstChars(), int v = 0) {name = n; value = v;}
|
||||
EnumeratorInfo(const PIConstChars & n = PIConstChars(), int v = 0) {
|
||||
name = n;
|
||||
value = v;
|
||||
}
|
||||
PIVariantTypes::Enumerator toPIVariantEnumerator() { return PIVariantTypes::Enumerator(value, name.toString()); }
|
||||
|
||||
//! \~english Custom PIMETA content
|
||||
@@ -175,7 +182,6 @@ struct PIP_EXPORT EnumeratorInfo {
|
||||
//! \~english Enum information
|
||||
//! \~russian Информация о перечислении
|
||||
struct PIP_EXPORT EnumInfo {
|
||||
|
||||
//! \~english Returns member name with value "value"
|
||||
//! \~russian Возвращает имя элемента со значением "value"
|
||||
PIString memberName(int value) const;
|
||||
@@ -210,12 +216,14 @@ inline PICout operator <<(PICout s, const PICodeInfo::TypeInfo & v) {
|
||||
if (v.flags[Static]) s << "static ";
|
||||
if (v.flags[Const]) s << "const ";
|
||||
s << v.type;
|
||||
if (!v.name.isEmpty())
|
||||
s << " " << v.name;
|
||||
if (!v.name.isEmpty()) s << " " << v.name;
|
||||
return s;
|
||||
}
|
||||
|
||||
inline PICout operator <<(PICout s, const PICodeInfo::EnumeratorInfo & v) {s << v.name << " = " << v.value << " Meta" << v.meta; return s;}
|
||||
inline PICout operator<<(PICout s, const PICodeInfo::EnumeratorInfo & v) {
|
||||
s << v.name << " = " << v.value << " Meta" << v.meta;
|
||||
return s;
|
||||
}
|
||||
|
||||
inline PICout operator<<(PICout s, const PICodeInfo::ClassInfo & v) {
|
||||
s.saveAndSetControls(0);
|
||||
@@ -224,8 +232,10 @@ inline PICout operator <<(PICout s, const PICodeInfo::ClassInfo & v) {
|
||||
s << ": ";
|
||||
bool first = true;
|
||||
for (const auto & i: v.parents) {
|
||||
if (first) first = false;
|
||||
else s << ", ";
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
s << ", ";
|
||||
s << i;
|
||||
}
|
||||
}
|
||||
@@ -234,14 +244,15 @@ inline PICout operator <<(PICout s, const PICodeInfo::ClassInfo & v) {
|
||||
s << PICoutManipulators::Tab << i.return_type << " " << i.name << "(";
|
||||
bool fa = true;
|
||||
for (const auto & a: i.arguments) {
|
||||
if (fa) fa = false;
|
||||
else s << ", ";
|
||||
if (fa)
|
||||
fa = false;
|
||||
else
|
||||
s << ", ";
|
||||
s << a;
|
||||
}
|
||||
s << ") Meta" << i.meta << ";\n";
|
||||
}
|
||||
if (!v.functions.isEmpty() && !v.variables.isEmpty())
|
||||
s << "\n";
|
||||
if (!v.functions.isEmpty() && !v.variables.isEmpty()) s << "\n";
|
||||
for (const auto & i: v.variables) {
|
||||
s << PICoutManipulators::Tab << i << " Meta" << i.meta << ";\n";
|
||||
}
|
||||
@@ -255,8 +266,10 @@ inline PICout operator <<(PICout s, const PICodeInfo::EnumInfo & v) {
|
||||
s << "enum " << v.name << " Meta" << v.meta << " {\n";
|
||||
for (const auto & i: v.members) {
|
||||
bool f = true;
|
||||
if (f) f = false;
|
||||
else s << ", ";
|
||||
if (f)
|
||||
f = false;
|
||||
else
|
||||
s << ", ";
|
||||
s << PICoutManipulators::Tab << i << "\n";
|
||||
}
|
||||
s << "}\n";
|
||||
@@ -295,12 +308,14 @@ PIP_EXPORT PIVariant getMemberAsVariant(const void * p, const char * class_name,
|
||||
|
||||
|
||||
template<typename T, typename std::enable_if<std::is_assignable<T &, const T &>::value, int>::type = 0>
|
||||
void serialize(PIByteArray & ret, const T & v) {ret << v;}
|
||||
void serialize(PIByteArray & ret, const T & v) {
|
||||
ret << v;
|
||||
}
|
||||
|
||||
template<typename T, typename std::enable_if<!std::is_assignable<T &, const T &>::value, int>::type = 0>
|
||||
void serialize(PIByteArray & ret, const T & v) {}
|
||||
|
||||
}
|
||||
} // namespace PICodeInfo
|
||||
|
||||
class PIP_EXPORT __PICodeInfoInitializer__ {
|
||||
public:
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "picodeparser.h"
|
||||
|
||||
|
||||
|
||||
PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const {
|
||||
PIStringList arg_vals;
|
||||
while (!args_.isEmpty()) {
|
||||
@@ -32,17 +31,20 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const {
|
||||
PIString ca;
|
||||
if (bi >= 0 && bi < ci) {
|
||||
ca = args_.left(args_.takeLeft(bi).toInt());
|
||||
ci -= ca.size_s(); bi -= ca.size_s();
|
||||
ci -= ca.size_s();
|
||||
bi -= ca.size_s();
|
||||
ca += '(' + args_.takeRange('(', ')') + ')';
|
||||
} else {
|
||||
ca = args_.takeLeft(ci);
|
||||
}
|
||||
arg_vals << ca;
|
||||
args_.trim(); args_.takeLeft(1); args_.trim();
|
||||
args_.trim();
|
||||
args_.takeLeft(1);
|
||||
args_.trim();
|
||||
}
|
||||
if (args.size() != arg_vals.size()) {
|
||||
piCout << ("Error: in expansion of macro \"" + name + '(' + args.join(", ") + ")\": expect")
|
||||
<< args.size() << "arguments but takes" << arg_vals.size() << "!";
|
||||
piCout << ("Error: in expansion of macro \"" + name + '(' + args.join(", ") + ")\": expect") << args.size() << "arguments but takes"
|
||||
<< arg_vals.size() << "!";
|
||||
if (ok != 0) *ok = false;
|
||||
return PIString();
|
||||
}
|
||||
@@ -72,7 +74,6 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const {
|
||||
}
|
||||
|
||||
|
||||
|
||||
PICodeParser::PICodeParser() {
|
||||
macros_iter = 32;
|
||||
with_includes = true;
|
||||
@@ -140,8 +141,7 @@ void PICodeParser::parseFiles(const PIStringList & files, bool follow_includes)
|
||||
|
||||
bool PICodeParser::isEnum(const PIString & name) {
|
||||
piForeachC(Enum & e, enums)
|
||||
if (e.name == name)
|
||||
return true;
|
||||
if (e.name == name) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,8 @@ bool PICodeParser::parseFileInternal(const PIString & file, bool follow_includes
|
||||
|
||||
|
||||
void PICodeParser::clear() {
|
||||
piForeach (Entity * i, entities) delete i;
|
||||
piForeach(Entity * i, entities)
|
||||
delete i;
|
||||
defines.clear();
|
||||
macros.clear();
|
||||
enums.clear();
|
||||
@@ -192,32 +193,137 @@ void PICodeParser::clear() {
|
||||
defines << Define(PIStringAscii("PICODE"), "") << custom_defines;
|
||||
macros << Macro(PIStringAscii("PIOBJECT"), "", PIStringList() << "name")
|
||||
<< Macro(PIStringAscii("PIOBJECT_PARENT"), "", PIStringList() << "parent")
|
||||
<< Macro(PIStringAscii("PIOBJECT_SUBCLASS"), "", PIStringList() << "name" << "parent")
|
||||
<< Macro(PIStringAscii("PIOBJECT_SUBCLASS"),
|
||||
"",
|
||||
PIStringList() << "name"
|
||||
<< "parent")
|
||||
<< Macro(PIStringAscii("PIIODEVICE"), "", PIStringList() << "name")
|
||||
<< Macro(PIStringAscii("NO_COPY_CLASS"), "", PIStringList() << "name")
|
||||
<< Macro(PIStringAscii("PRIVATE_DECLARATION"))
|
||||
<< Macro(PIStringAscii("NO_COPY_CLASS"), "", PIStringList() << "name") << Macro(PIStringAscii("PRIVATE_DECLARATION"))
|
||||
|
||||
<< Macro(PIStringAscii("EVENT"), "void name();", PIStringList() << "name")
|
||||
<< Macro(PIStringAscii("EVENT0"), "void name();", PIStringList() << "name")
|
||||
<< Macro(PIStringAscii("EVENT1"), "void name(a0 n0);", PIStringList() << "name" << "a0" << "n0")
|
||||
<< Macro(PIStringAscii("EVENT2"), "void name(a0 n0, a1 n1);", PIStringList() << "name" << "a0" << "n0" << "a1" << "n1")
|
||||
<< Macro(PIStringAscii("EVENT3"), "void name(a0 n0, a1 n1, a2 n2);", PIStringList() << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2")
|
||||
<< Macro(PIStringAscii("EVENT4"), "void name(a0 n0, a1 n1, a2 n2, a3 n3);", PIStringList() << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2" << "a3" << "n3")
|
||||
<< Macro(PIStringAscii("EVENT1"),
|
||||
"void name(a0 n0);",
|
||||
PIStringList() << "name"
|
||||
<< "a0"
|
||||
<< "n0")
|
||||
<< Macro(PIStringAscii("EVENT2"),
|
||||
"void name(a0 n0, a1 n1);",
|
||||
PIStringList() << "name"
|
||||
<< "a0"
|
||||
<< "n0"
|
||||
<< "a1"
|
||||
<< "n1")
|
||||
<< Macro(PIStringAscii("EVENT3"),
|
||||
"void name(a0 n0, a1 n1, a2 n2);",
|
||||
PIStringList() << "name"
|
||||
<< "a0"
|
||||
<< "n0"
|
||||
<< "a1"
|
||||
<< "n1"
|
||||
<< "a2"
|
||||
<< "n2")
|
||||
<< Macro(PIStringAscii("EVENT4"),
|
||||
"void name(a0 n0, a1 n1, a2 n2, a3 n3);",
|
||||
PIStringList() << "name"
|
||||
<< "a0"
|
||||
<< "n0"
|
||||
<< "a1"
|
||||
<< "n1"
|
||||
<< "a2"
|
||||
<< "n2"
|
||||
<< "a3"
|
||||
<< "n3")
|
||||
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER" ), "ret name()", PIStringList() << "ret" << "name")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER0"), "ret name()", PIStringList() << "ret" << "name")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER1"), "ret name(a0 n0)", PIStringList() << "ret" << "name" << "a0" << "n0")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER2"), "ret name(a0 n0, a1 n1)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER3"), "ret name(a0 n0, a1 n1, a2 n2)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER4"), "ret name(a0 n0, a1 n1, a2 n2, a3 n3)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2" << "a3" << "n3")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER"),
|
||||
"ret name()",
|
||||
PIStringList() << "ret"
|
||||
<< "name")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER0"),
|
||||
"ret name()",
|
||||
PIStringList() << "ret"
|
||||
<< "name")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER1"),
|
||||
"ret name(a0 n0)",
|
||||
PIStringList() << "ret"
|
||||
<< "name"
|
||||
<< "a0"
|
||||
<< "n0")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER2"),
|
||||
"ret name(a0 n0, a1 n1)",
|
||||
PIStringList() << "ret"
|
||||
<< "name"
|
||||
<< "a0"
|
||||
<< "n0"
|
||||
<< "a1"
|
||||
<< "n1")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER3"),
|
||||
"ret name(a0 n0, a1 n1, a2 n2)",
|
||||
PIStringList() << "ret"
|
||||
<< "name"
|
||||
<< "a0"
|
||||
<< "n0"
|
||||
<< "a1"
|
||||
<< "n1"
|
||||
<< "a2"
|
||||
<< "n2")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER4"),
|
||||
"ret name(a0 n0, a1 n1, a2 n2, a3 n3)",
|
||||
PIStringList() << "ret"
|
||||
<< "name"
|
||||
<< "a0"
|
||||
<< "n0"
|
||||
<< "a1"
|
||||
<< "n1"
|
||||
<< "a2"
|
||||
<< "n2"
|
||||
<< "a3"
|
||||
<< "n3")
|
||||
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER" ), "virtual ret name()", PIStringList() << "ret" << "name")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER0"), "virtual ret name()", PIStringList() << "ret" << "name")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER1"), "virtual ret name(a0 n0)", PIStringList() << "ret" << "name" << "a0" << "n0")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER2"), "virtual ret name(a0 n0, a1 n1)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER3"), "virtual ret name(a0 n0, a1 n1, a2 n2)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER4"), "virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2" << "a3" << "n3")
|
||||
;
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER"),
|
||||
"virtual ret name()",
|
||||
PIStringList() << "ret"
|
||||
<< "name")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER0"),
|
||||
"virtual ret name()",
|
||||
PIStringList() << "ret"
|
||||
<< "name")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER1"),
|
||||
"virtual ret name(a0 n0)",
|
||||
PIStringList() << "ret"
|
||||
<< "name"
|
||||
<< "a0"
|
||||
<< "n0")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER2"),
|
||||
"virtual ret name(a0 n0, a1 n1)",
|
||||
PIStringList() << "ret"
|
||||
<< "name"
|
||||
<< "a0"
|
||||
<< "n0"
|
||||
<< "a1"
|
||||
<< "n1")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER3"),
|
||||
"virtual ret name(a0 n0, a1 n1, a2 n2)",
|
||||
PIStringList() << "ret"
|
||||
<< "name"
|
||||
<< "a0"
|
||||
<< "n0"
|
||||
<< "a1"
|
||||
<< "n1"
|
||||
<< "a2"
|
||||
<< "n2")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER4"),
|
||||
"virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)",
|
||||
PIStringList() << "ret"
|
||||
<< "name"
|
||||
<< "a0"
|
||||
<< "n0"
|
||||
<< "a1"
|
||||
<< "n1"
|
||||
<< "a2"
|
||||
<< "n2"
|
||||
<< "a3"
|
||||
<< "n3");
|
||||
}
|
||||
|
||||
|
||||
@@ -247,7 +353,8 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
|
||||
if (i > 0) pc = c;
|
||||
c = fc[i].toAscii();
|
||||
if (c == '"' && !mlc && pc != '\'') {
|
||||
if (i > 0) if (fc[i - 1] == '\\') continue;
|
||||
if (i > 0)
|
||||
if (fc[i - 1] == '\\') continue;
|
||||
cc = !cc;
|
||||
continue;
|
||||
}
|
||||
@@ -258,9 +365,24 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
|
||||
continue;
|
||||
}
|
||||
if (cc) continue;
|
||||
if (fc.mid(i, 2) == "/*") {mlc = true; mls = i; ++i; continue;}
|
||||
if (fc.mid(i, 2) == "*/" && mlc) {mlc = false; fc.cutMid(mls, i - mls + 2); i = mls - 1; continue;}
|
||||
if (fc.mid(i, 2) == "//" && !mlc) {ole = fc.find('\n', i); fc.cutMid(i, ole < 0 ? -1 : ole - i); --i; continue;}
|
||||
if (fc.mid(i, 2) == "/*") {
|
||||
mlc = true;
|
||||
mls = i;
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (fc.mid(i, 2) == "*/" && mlc) {
|
||||
mlc = false;
|
||||
fc.cutMid(mls, i - mls + 2);
|
||||
i = mls - 1;
|
||||
continue;
|
||||
}
|
||||
if (fc.mid(i, 2) == "//" && !mlc) {
|
||||
ole = fc.find('\n', i);
|
||||
fc.cutMid(i, ole < 0 ? -1 : ole - i);
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
pfc = procMacros(fc);
|
||||
|
||||
@@ -295,7 +417,8 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
|
||||
if (ind > 0) pc = pfc[ind - 1];
|
||||
if (ind + m.name.size_s() < pfc.size_s()) nc = pfc.mid(ind + m.name.size_s(), 1)[0];
|
||||
if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue;
|
||||
PIString ret, range; bool ok(false);
|
||||
PIString ret, range;
|
||||
bool ok(false);
|
||||
range = pfc.mid(ind + m.name.size_s()).takeRange('(', ')');
|
||||
ret = m.expand(range, &ok);
|
||||
if (!ok) return false;
|
||||
@@ -331,14 +454,22 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
|
||||
pfc.takeRange('<', '>');
|
||||
bool def = !isDeclaration(pfc, 0, &end);
|
||||
pfc.cutLeft(end);
|
||||
if (def) pfc.takeRange('{', '}');
|
||||
else pfc.takeSymbol();
|
||||
if (def)
|
||||
pfc.takeRange('{', '}');
|
||||
else
|
||||
pfc.takeSymbol();
|
||||
continue;
|
||||
}
|
||||
if (pfc.left(5) == s_class || pfc.left(6) == s_struct || pfc.left(5) == s_union) {
|
||||
int dind = pfc.find('{', 0), find = pfc.find(';', 0);
|
||||
if (dind < 0 && find < 0) {pfc.cutLeft(6); continue;}
|
||||
if (dind < 0 || find < dind) {pfc.cutLeft(6); continue;}
|
||||
if (dind < 0 && find < 0) {
|
||||
pfc.cutLeft(6);
|
||||
continue;
|
||||
}
|
||||
if (dind < 0 || find < dind) {
|
||||
pfc.cutLeft(6);
|
||||
continue;
|
||||
}
|
||||
ccmn = pfc.left(dind) + s_bo + pfc.mid(dind).takeRange('{', '}') + s_bc;
|
||||
pfc.remove(0, ccmn.size());
|
||||
parseClass(0, ccmn, false);
|
||||
@@ -356,8 +487,10 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
|
||||
if (pfc.left(7) == s_typedef) {
|
||||
pfc.cutLeft(7);
|
||||
typedefs << parseTypedef(pfc.takeLeft(pfc.find(';')));
|
||||
if (typedefs.back().first.isEmpty()) typedefs.pop_back();
|
||||
else root_.typedefs << typedefs.back();
|
||||
if (typedefs.back().first.isEmpty())
|
||||
typedefs.pop_back();
|
||||
else
|
||||
root_.typedefs << typedefs.back();
|
||||
pfc.takeSymbol();
|
||||
continue;
|
||||
}
|
||||
@@ -399,11 +532,15 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc)
|
||||
cd.cutRight(1);
|
||||
Entity * pe = 0;
|
||||
piForeachC(PIString & p, pl) {
|
||||
if (p.contains(' ')) pn = p.mid(p.find(' ') + 1);
|
||||
else pn = p;
|
||||
if (p.contains(' '))
|
||||
pn = p.mid(p.find(' ') + 1);
|
||||
else
|
||||
pn = p;
|
||||
pe = findEntityByName(pn);
|
||||
if (pe == 0) ;//{piCout << "Error: can`t find" << pn;}
|
||||
else parents << pe;
|
||||
if (pe == 0)
|
||||
; //{piCout << "Error: can`t find" << pn;}
|
||||
else
|
||||
parents << pe;
|
||||
}
|
||||
}
|
||||
PIString typename_ = cd.left(6).trim();
|
||||
@@ -469,9 +606,21 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace)
|
||||
while (!fc.isEmpty()) {
|
||||
PIString cw = fc.takeCWord(), tmp;
|
||||
// piCout << "\ntaked word" << cw;
|
||||
if (cw == s_public ) {cur_def_vis = Public; fc.cutLeft(1); continue;}
|
||||
if (cw == s_protected) {cur_def_vis = Protected; fc.cutLeft(1); continue;}
|
||||
if (cw == s_private ) {cur_def_vis = Private; fc.cutLeft(1); continue;}
|
||||
if (cw == s_public) {
|
||||
cur_def_vis = Public;
|
||||
fc.cutLeft(1);
|
||||
continue;
|
||||
}
|
||||
if (cw == s_protected) {
|
||||
cur_def_vis = Protected;
|
||||
fc.cutLeft(1);
|
||||
continue;
|
||||
}
|
||||
if (cw == s_private) {
|
||||
cur_def_vis = Private;
|
||||
fc.cutLeft(1);
|
||||
continue;
|
||||
}
|
||||
if (cw == s_namespace) {
|
||||
PIString prev_namespace = cur_namespace, ccmn;
|
||||
cur_namespace += fc.takeCWord() + s_ns;
|
||||
@@ -501,14 +650,16 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace)
|
||||
fc.takeSymbol();
|
||||
continue;
|
||||
}
|
||||
if (cw == s_friend) {fc.cutLeft(fc.find(';') + 1); continue;}
|
||||
if (cw == s_friend) {
|
||||
fc.cutLeft(fc.find(';') + 1);
|
||||
continue;
|
||||
}
|
||||
if (cw == s_typedef) {
|
||||
if (ce) {
|
||||
ce->typedefs << parseTypedef(fc.takeLeft(fc.find(';')));
|
||||
typedefs << ce->typedefs.back();
|
||||
typedefs.back().first.insert(0, cur_namespace);
|
||||
if (ce->typedefs.back().first.isEmpty())
|
||||
ce->typedefs.pop_back();
|
||||
if (ce->typedefs.back().first.isEmpty()) ce->typedefs.pop_back();
|
||||
}
|
||||
fc.takeSymbol();
|
||||
continue;
|
||||
@@ -517,17 +668,22 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace)
|
||||
fc.takeRange('<', '>');
|
||||
def = !isDeclaration(fc, 0, &end);
|
||||
fc.cutLeft(end);
|
||||
if (def) fc.takeRange('{', '}');
|
||||
else fc.takeSymbol();
|
||||
if (def)
|
||||
fc.takeRange('{', '}');
|
||||
else
|
||||
fc.takeSymbol();
|
||||
continue;
|
||||
}
|
||||
def = !isDeclaration(fc, 0, &end);
|
||||
tmp = (cw + fc.takeLeft(end)).trim();
|
||||
if (!tmp.isEmpty() && ce)
|
||||
parseMember(ce, tmp);
|
||||
if (def) fc.takeRange('{', '}');
|
||||
else fc.takeSymbol();
|
||||
if (ps == fc.size_s()) {fc.cutLeft(1);}
|
||||
if (!tmp.isEmpty() && ce) parseMember(ce, tmp);
|
||||
if (def)
|
||||
fc.takeRange('{', '}');
|
||||
else
|
||||
fc.takeSymbol();
|
||||
if (ps == fc.size_s()) {
|
||||
fc.cutLeft(1);
|
||||
}
|
||||
ps = fc.size_s();
|
||||
}
|
||||
cur_def_vis = prev_vis;
|
||||
@@ -571,14 +727,17 @@ bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc
|
||||
meta = tmp_meta.value(v.takeMid(mi, 5));
|
||||
v.replaceAll(s_ss, ' ');
|
||||
}
|
||||
vn = v; ind = v.find('=');
|
||||
if (ind > 0) {cv = v.right(v.size_s() - ind - 1).toInt(); vn = v.left(ind);}
|
||||
vn = v;
|
||||
ind = v.find('=');
|
||||
if (ind > 0) {
|
||||
cv = v.right(v.size_s() - ind - 1).toInt();
|
||||
vn = v.left(ind);
|
||||
}
|
||||
if (ind < 0) ++cv;
|
||||
e.members << EnumeratorInfo(vn.trim(), cv, meta);
|
||||
}
|
||||
if (!e.members.isEmpty())
|
||||
if (e.members.back().name.isEmpty())
|
||||
e.members.pop_back();
|
||||
if (e.members.back().name.isEmpty()) e.members.pop_back();
|
||||
enums << e;
|
||||
return true;
|
||||
}
|
||||
@@ -592,7 +751,10 @@ PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) {
|
||||
if (fc.contains('(')) {
|
||||
int start = fc.find('('), end = fc.find(')');
|
||||
td.first = fc.takeMid(start + 1, end - start - 1).trim();
|
||||
if (td.first.left(1) == PIChar('*')) {td.first.cutLeft(1).trim(); fc.insert(start + 1, '*');}
|
||||
if (td.first.left(1) == PIChar('*')) {
|
||||
td.first.cutLeft(1).trim();
|
||||
fc.insert(start + 1, '*');
|
||||
}
|
||||
td.second = fc.trim();
|
||||
} else {
|
||||
td.first = fc.takeMid(fc.findLast(' ')).trim();
|
||||
@@ -639,7 +801,11 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
|
||||
PIString ctemp, crepl;
|
||||
while (ts >= 0) {
|
||||
ctemp = fc.mid(ts).takeRange('<', '>');
|
||||
if (ctemp.isEmpty()) {te = ts + 1; ts = fc.find('<', te); continue;}
|
||||
if (ctemp.isEmpty()) {
|
||||
te = ts + 1;
|
||||
ts = fc.find('<', te);
|
||||
continue;
|
||||
}
|
||||
crepl = s_T + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, '0');
|
||||
fc.replace(ts, ctemp.size_s() + 2, crepl);
|
||||
tmp_temp[crepl] = '<' + ctemp + '>';
|
||||
@@ -685,8 +851,7 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
|
||||
int i = 0;
|
||||
// piCout << me.arguments_full;
|
||||
piForeach(PIString & a, me.arguments_full)
|
||||
if ((i = a.find('=')) > 0)
|
||||
a.cutRight(a.size_s() - i).trim();
|
||||
if ((i = a.find('=')) > 0) a.cutRight(a.size_s() - i).trim();
|
||||
for (int j = 0; j < me.arguments_full.size_s(); ++j)
|
||||
if (me.arguments_full[j] == s_void) {
|
||||
me.arguments_full.remove(j);
|
||||
@@ -695,8 +860,7 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
|
||||
me.arguments_type = me.arguments_full;
|
||||
piForeach(PIString & a, me.arguments_type) {
|
||||
crepl.clear();
|
||||
if (a.contains('['))
|
||||
crepl = a.takeMid(a.find('['), a.findLast(']') - a.find('[') + 1);
|
||||
if (a.contains('[')) crepl = a.takeMid(a.find('['), a.findLast(']') - a.find('[') + 1);
|
||||
for (ts = a.size_s() - 1; ts >= 0; --ts)
|
||||
if (!_isCChar(a[ts]) && !(a[ts].isDigit())) break;
|
||||
a.cutRight(a.size_s() - ts - 1);
|
||||
@@ -726,8 +890,11 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
|
||||
ctemp.trim();
|
||||
}
|
||||
for (ts = ctemp.size_s() - 1; ts > 0; --ts) {
|
||||
if (vn) {if (!_isCChar(ctemp[ts]) && !ctemp[ts].isDigit() && ctemp[ts] != '[' && ctemp[ts] != ']') vn = false;}
|
||||
else {if (_isCChar(ctemp[ts]) || ctemp[ts].isDigit()) break;}
|
||||
if (vn) {
|
||||
if (!_isCChar(ctemp[ts]) && !ctemp[ts].isDigit() && ctemp[ts] != '[' && ctemp[ts] != ']') vn = false;
|
||||
} else {
|
||||
if (_isCChar(ctemp[ts]) || ctemp[ts].isDigit()) break;
|
||||
}
|
||||
}
|
||||
me.type = ctemp.takeLeft(ts + 1);
|
||||
me.visibility = cur_def_vis;
|
||||
@@ -765,13 +932,13 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
|
||||
me.type = type;
|
||||
restoreTmpMeta(&me);
|
||||
if (me.name.isEmpty()) continue;
|
||||
if (me.name.contains('['))
|
||||
crepl = me.name.takeMid(me.name.find('['), me.name.findLast(']') - me.name.find('[') + 1);
|
||||
if (me.name.contains('[')) crepl = me.name.takeMid(me.name.find('['), me.name.findLast(']') - me.name.find('[') + 1);
|
||||
while (!me.name.isEmpty()) {
|
||||
if (me.name.front() == PIChar('*') || me.name.front() == PIChar('&')) {
|
||||
me.type += me.name.takeLeft(1);
|
||||
me.name.trim();
|
||||
} else break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
me.is_type_ptr = (me.type.right(1) == PIChar(']') || me.type.right(1) == PIChar('*'));
|
||||
me.type += crepl;
|
||||
@@ -818,10 +985,22 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) {
|
||||
break;
|
||||
}
|
||||
n.push_front(' ');
|
||||
if (n.find(s_s_const_s) >= 0) {n.replaceAll(s_s_const_s, ""); pref += s_const_s;}
|
||||
if (n.find(s_s_static_s) >= 0) {n.replaceAll(s_s_static_s, ""); pref += s_static_s;}
|
||||
if (n.find(s_s_mutable_s) >= 0) {n.replaceAll(s_s_mutable_s, ""); pref += s_mutable_s;}
|
||||
if (n.find(s_s_volatile_s) >= 0) {n.replaceAll(s_s_volatile_s, ""); pref += s_volatile_s;}
|
||||
if (n.find(s_s_const_s) >= 0) {
|
||||
n.replaceAll(s_s_const_s, "");
|
||||
pref += s_const_s;
|
||||
}
|
||||
if (n.find(s_s_static_s) >= 0) {
|
||||
n.replaceAll(s_s_static_s, "");
|
||||
pref += s_static_s;
|
||||
}
|
||||
if (n.find(s_s_mutable_s) >= 0) {
|
||||
n.replaceAll(s_s_mutable_s, "");
|
||||
pref += s_mutable_s;
|
||||
}
|
||||
if (n.find(s_s_volatile_s) >= 0) {
|
||||
n.replaceAll(s_s_volatile_s, "");
|
||||
pref += s_volatile_s;
|
||||
}
|
||||
n.trim();
|
||||
int f = 0;
|
||||
piForeachC(Entity * e, entities) {
|
||||
@@ -921,10 +1100,25 @@ double PICodeParser::procMacrosCond(PIString fc) {
|
||||
while (!fc.isEmpty()) {
|
||||
cc = fc[0].toAscii();
|
||||
nc = (fc.size() > 1 ? fc[1].toAscii() : 0);
|
||||
if (cc == '!') {neg = true; fc.pop_front(); continue;}
|
||||
if (cc == '(') {br = true; brv = procMacrosCond(fc.takeRange('(', ')'));}
|
||||
if (cc == '&' && nc == '&') {fc.remove(0, 2); oper = 1; continue;}
|
||||
if (cc == '|' && nc == '|') {fc.remove(0, 2); oper = 2; continue;}
|
||||
if (cc == '!') {
|
||||
neg = true;
|
||||
fc.pop_front();
|
||||
continue;
|
||||
}
|
||||
if (cc == '(') {
|
||||
br = true;
|
||||
brv = procMacrosCond(fc.takeRange('(', ')'));
|
||||
}
|
||||
if (cc == '&' && nc == '&') {
|
||||
fc.remove(0, 2);
|
||||
oper = 1;
|
||||
continue;
|
||||
}
|
||||
if (cc == '|' && nc == '|') {
|
||||
fc.remove(0, 2);
|
||||
oper = 2;
|
||||
continue;
|
||||
}
|
||||
if (!br) {
|
||||
ce = fc.takeCWord();
|
||||
if (ce.isEmpty()) ce = fc.takeNumber();
|
||||
@@ -952,8 +1146,7 @@ double PICodeParser::procMacrosCond(PIString fc) {
|
||||
|
||||
bool PICodeParser::isDefineExists(const PIString & dn) {
|
||||
piForeachC(Define & d, defines) {
|
||||
if (d.first == dn)
|
||||
return true;
|
||||
if (d.first == dn) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -961,8 +1154,7 @@ bool PICodeParser::isDefineExists(const PIString & dn) {
|
||||
|
||||
double PICodeParser::defineValue(const PIString & dn) {
|
||||
piForeachC(Define & d, defines) {
|
||||
if (d.first == dn)
|
||||
return d.second.isEmpty() ? 1. : d.second.toDouble();
|
||||
if (d.first == dn) return d.second.isEmpty() ? 1. : d.second.toDouble();
|
||||
}
|
||||
return dn.toDouble();
|
||||
}
|
||||
@@ -990,8 +1182,7 @@ void PICodeParser::replaceMeta(PIString & dn) {
|
||||
|
||||
PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) {
|
||||
piForeach(Entity * e, entities)
|
||||
if (e->name == en)
|
||||
return e;
|
||||
if (e->name == en) return e;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -999,8 +1190,14 @@ PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) {
|
||||
bool PICodeParser::isDeclaration(const PIString & fc, int start, int * end) {
|
||||
int dind = fc.find('{', start), find = fc.find(';', start);
|
||||
// piCout << "isDeclaration" << dind << find << fc.left(10);
|
||||
if (dind < 0 && find < 0) {if (end) *end = -1; return true;}
|
||||
if (dind < 0 || find < dind) {if (end) *end = find; return true;}
|
||||
if (dind < 0 && find < 0) {
|
||||
if (end) *end = -1;
|
||||
return true;
|
||||
}
|
||||
if (dind < 0 || find < dind) {
|
||||
if (end) *end = find;
|
||||
return true;
|
||||
}
|
||||
if (end) *end = dind;
|
||||
return false;
|
||||
}
|
||||
@@ -1050,7 +1247,8 @@ PIString PICodeParser::procMacros(PIString fc) {
|
||||
if (skip || grab) {
|
||||
if (mif.left(2) == s_if) ifcnt++;
|
||||
if (mif.left(5) == s_endif) {
|
||||
if (ifcnt > 0) ifcnt--;
|
||||
if (ifcnt > 0)
|
||||
ifcnt--;
|
||||
else {
|
||||
// piCout << "main endif" << skip << grab;
|
||||
if (grab) pfc += procMacros(nfc);
|
||||
@@ -1063,7 +1261,8 @@ PIString PICodeParser::procMacros(PIString fc) {
|
||||
if (cond_ok) {
|
||||
if (grab) {
|
||||
pfc += procMacros(nfc);
|
||||
skip = true; grab = false;
|
||||
skip = true;
|
||||
grab = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -1071,7 +1270,8 @@ PIString PICodeParser::procMacros(PIString fc) {
|
||||
// piCout << "check elif" << skip << grab << cond_ok;
|
||||
if (!macroCondition(mif, mifcond.trimmed())) continue;
|
||||
// piCout << "check elif ok";
|
||||
skip = false; grab = cond_ok = true;
|
||||
skip = false;
|
||||
grab = cond_ok = true;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
@@ -1079,8 +1279,13 @@ PIString PICodeParser::procMacros(PIString fc) {
|
||||
if (mif.left(4) == s_else && ifcnt == 0) {
|
||||
// piCout << "main else" << skip << grab;
|
||||
if (grab) pfc += procMacros(nfc);
|
||||
if (skip && !cond_ok) {skip = false; grab = true;}
|
||||
else {skip = true; grab = false;}
|
||||
if (skip && !cond_ok) {
|
||||
skip = false;
|
||||
grab = true;
|
||||
} else {
|
||||
skip = true;
|
||||
grab = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (grab) nfc += line + '\n';
|
||||
@@ -1089,8 +1294,10 @@ PIString PICodeParser::procMacros(PIString fc) {
|
||||
if (mif.left(2) == s_if) {
|
||||
// piCout << "main if";
|
||||
skip = grab = cond_ok = false;
|
||||
if (macroCondition(mif, mifcond.trimmed())) grab = cond_ok = true;
|
||||
else skip = true;
|
||||
if (macroCondition(mif, mifcond.trimmed()))
|
||||
grab = cond_ok = true;
|
||||
else
|
||||
skip = true;
|
||||
ifcnt = 0;
|
||||
nfc.clear();
|
||||
} else {
|
||||
@@ -1098,8 +1305,10 @@ PIString PICodeParser::procMacros(PIString fc) {
|
||||
// return false; /// WARNING: now skip errors
|
||||
}
|
||||
} else {
|
||||
if (grab) nfc += line + '\n';
|
||||
else if (!skip) pfc += line + '\n';
|
||||
if (grab)
|
||||
nfc += line + '\n';
|
||||
else if (!skip)
|
||||
pfc += line + '\n';
|
||||
}
|
||||
}
|
||||
return pfc;
|
||||
@@ -1150,7 +1359,10 @@ bool PICodeParser::parseDirective(PIString d) {
|
||||
if (dname == s_undef) {
|
||||
PIString mname = d.takeCWord();
|
||||
for (int i = 0; i < defines.size_s(); ++i)
|
||||
if (defines[i].first == mname) {defines.remove(i); --i;}
|
||||
if (defines[i].first == mname) {
|
||||
defines.remove(i);
|
||||
--i;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -26,17 +26,27 @@
|
||||
#ifndef PICODEPARSER_H
|
||||
#define PICODEPARSER_H
|
||||
|
||||
#include "pifile.h"
|
||||
#include "pievaluator.h"
|
||||
#include "pifile.h"
|
||||
|
||||
inline bool _isCChar(const PIChar & c) {return (c.isAlpha() || (c.toAscii() == '_'));}
|
||||
inline bool _isCChar(const PIString & c) {if (c.isEmpty()) return false; return _isCChar(c[0]);}
|
||||
inline bool _isCChar(const PIChar & c) {
|
||||
return (c.isAlpha() || (c.toAscii() == '_'));
|
||||
}
|
||||
inline bool _isCChar(const PIString & c) {
|
||||
if (c.isEmpty()) return false;
|
||||
return _isCChar(c[0]);
|
||||
}
|
||||
|
||||
class PIP_EXPORT PICodeParser {
|
||||
public:
|
||||
PICodeParser();
|
||||
|
||||
enum Visibility {Global, Public, Protected, Private};
|
||||
enum Visibility {
|
||||
Global,
|
||||
Public,
|
||||
Protected,
|
||||
Private
|
||||
};
|
||||
enum Attribute {
|
||||
NoAttributes = 0x0,
|
||||
Const = 0x01,
|
||||
@@ -110,16 +120,18 @@ public:
|
||||
};
|
||||
|
||||
struct PIP_EXPORT EnumeratorInfo {
|
||||
EnumeratorInfo(const PIString & n = PIString(), int v = 0, const MetaMap & m = MetaMap()) {name = n; value = v; meta = m;}
|
||||
EnumeratorInfo(const PIString & n = PIString(), int v = 0, const MetaMap & m = MetaMap()) {
|
||||
name = n;
|
||||
value = v;
|
||||
meta = m;
|
||||
}
|
||||
MetaMap meta;
|
||||
PIString name;
|
||||
int value;
|
||||
};
|
||||
|
||||
struct PIP_EXPORT Enum {
|
||||
Enum(const PIString & n = PIString()) {
|
||||
name = n;
|
||||
}
|
||||
Enum(const PIString & n = PIString()) { name = n; }
|
||||
MetaMap meta;
|
||||
PIString name;
|
||||
PIVector<EnumeratorInfo> members;
|
||||
@@ -181,7 +193,6 @@ private:
|
||||
PIString cur_namespace;
|
||||
PIMap<PIString, PIString> tmp_temp;
|
||||
PIMap<PIString, MetaMap> tmp_meta;
|
||||
|
||||
};
|
||||
|
||||
#endif // PICODEPARSER_H
|
||||
|
||||
@@ -58,8 +58,8 @@
|
||||
#ifndef PICOMPRESS_H
|
||||
#define PICOMPRESS_H
|
||||
|
||||
#include "pip_compress_export.h"
|
||||
#include "pibytearray.h"
|
||||
#include "pip_compress_export.h"
|
||||
|
||||
//! \~english Compress "ba" with compression level "level", return empty %PIByteArray if no compression supports
|
||||
//! \~russian Сжимает "ba" с уровнем сжатия "level", возвращает пустой %PIByteArray если нет поддержки
|
||||
|
||||
@@ -27,16 +27,17 @@
|
||||
#define PISCREEN_H
|
||||
|
||||
#include "pip_console_export.h"
|
||||
#include "piscreentile.h"
|
||||
#include "piscreendrawer.h"
|
||||
#include "piscreentile.h"
|
||||
|
||||
|
||||
class PIP_CONSOLE_EXPORT PIScreen: public PIThread, public PIScreenTypes::PIScreenBase
|
||||
{
|
||||
class PIP_CONSOLE_EXPORT PIScreen
|
||||
: public PIThread
|
||||
, public PIScreenTypes::PIScreenBase {
|
||||
PIOBJECT_SUBCLASS(PIScreen, PIThread);
|
||||
class SystemConsole;
|
||||
public:
|
||||
|
||||
public:
|
||||
//! Constructs %PIScreen with key handler "slot" and if "startNow" start it
|
||||
PIScreen(bool startNow = true, PIKbdListener::KBFunc slot = 0);
|
||||
|
||||
@@ -72,7 +73,10 @@ public:
|
||||
|
||||
EVENT_HANDLER0(void, waitForFinish);
|
||||
EVENT_HANDLER0(void, start) { start(false); }
|
||||
EVENT_HANDLER1(void, start, bool, wait) {PIThread::start(40); if (wait) waitForFinish();}
|
||||
EVENT_HANDLER1(void, start, bool, wait) {
|
||||
PIThread::start(40);
|
||||
if (wait) waitForFinish();
|
||||
}
|
||||
EVENT_HANDLER0(void, stop) { stop(false); }
|
||||
EVENT_HANDLER1(void, stop, bool, clear);
|
||||
|
||||
@@ -156,7 +160,6 @@ private:
|
||||
PIKbdListener::KBFunc ret_func;
|
||||
PIScreenTile root;
|
||||
PIScreenTile *tile_focus, *tile_dialog;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -35,9 +35,14 @@
|
||||
class PIP_CONSOLE_EXPORT TileVars: public PIScreenTile {
|
||||
public:
|
||||
TileVars(const PIString & n = PIString());
|
||||
|
||||
protected:
|
||||
struct PIP_CONSOLE_EXPORT Variable {
|
||||
Variable() {nx = ny = type = offset = bitFrom = bitCount = size = 0; format = PIScreenTypes::CellFormat(); ptr = 0;}
|
||||
Variable() {
|
||||
nx = ny = type = offset = bitFrom = bitCount = size = 0;
|
||||
format = PIScreenTypes::CellFormat();
|
||||
ptr = 0;
|
||||
}
|
||||
bool isEmpty() const { return (ptr == 0); }
|
||||
PIString name;
|
||||
PIScreenTypes::CellFormat format;
|
||||
@@ -69,9 +74,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
|
||||
class PIP_CONSOLE_EXPORT PIScreenConsoleTile : public PIScreenTile
|
||||
{
|
||||
class PIP_CONSOLE_EXPORT PIScreenConsoleTile: public PIScreenTile {
|
||||
public:
|
||||
PIScreenConsoleTile();
|
||||
};
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
#include "piscreentypes.h"
|
||||
#include "pistring.h"
|
||||
|
||||
class PIP_CONSOLE_EXPORT PIScreenDrawer
|
||||
{
|
||||
class PIP_CONSOLE_EXPORT PIScreenDrawer {
|
||||
friend class PIScreen;
|
||||
PIScreenDrawer(PIVector<PIVector<PIScreenTypes::Cell>> & c);
|
||||
|
||||
public:
|
||||
enum ArtChar {
|
||||
LineVertical = 1,
|
||||
@@ -49,12 +49,49 @@ public:
|
||||
|
||||
void clear();
|
||||
void clearRect(int x0, int y0, int x1, int y1) { fillRect(x0, y0, x1, y1, ' '); }
|
||||
void drawPixel(int x, int y, const PIChar & c, PIScreenTypes::Color col_char = PIScreenTypes::Default, PIScreenTypes::Color col_back = PIScreenTypes::Default, PIScreenTypes::CharFlags flags_char = 0);
|
||||
void drawLine(int x0, int y0, int x1, int y1, const PIChar & c, PIScreenTypes::Color col_char = PIScreenTypes::Default, PIScreenTypes::Color col_back = PIScreenTypes::Default, PIScreenTypes::CharFlags flags_char = 0);
|
||||
void drawRect(int x0, int y0, int x1, int y1, const PIChar & c, PIScreenTypes::Color col_char = PIScreenTypes::Default, PIScreenTypes::Color col_back = PIScreenTypes::Default, PIScreenTypes::CharFlags flags_char = 0);
|
||||
void drawFrame(int x0, int y0, int x1, int y1, PIScreenTypes::Color col_char = PIScreenTypes::Default, PIScreenTypes::Color col_back = PIScreenTypes::Default, PIScreenTypes::CharFlags flags_char = 0);
|
||||
void drawText(int x, int y, const PIString & s, PIScreenTypes::Color col_char = PIScreenTypes::Default, PIScreenTypes::Color col_back = PIScreenTypes::Transparent, PIScreenTypes::CharFlags flags_char = 0);
|
||||
void fillRect(int x0, int y0, int x1, int y1, const PIChar & c, PIScreenTypes::Color col_char = PIScreenTypes::Default, PIScreenTypes::Color col_back = PIScreenTypes::Default, PIScreenTypes::CharFlags flags_char = 0);
|
||||
void drawPixel(int x,
|
||||
int y,
|
||||
const PIChar & c,
|
||||
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
||||
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
||||
PIScreenTypes::CharFlags flags_char = 0);
|
||||
void drawLine(int x0,
|
||||
int y0,
|
||||
int x1,
|
||||
int y1,
|
||||
const PIChar & c,
|
||||
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
||||
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
||||
PIScreenTypes::CharFlags flags_char = 0);
|
||||
void drawRect(int x0,
|
||||
int y0,
|
||||
int x1,
|
||||
int y1,
|
||||
const PIChar & c,
|
||||
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
||||
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
||||
PIScreenTypes::CharFlags flags_char = 0);
|
||||
void drawFrame(int x0,
|
||||
int y0,
|
||||
int x1,
|
||||
int y1,
|
||||
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
||||
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
||||
PIScreenTypes::CharFlags flags_char = 0);
|
||||
void drawText(int x,
|
||||
int y,
|
||||
const PIString & s,
|
||||
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
||||
PIScreenTypes::Color col_back = PIScreenTypes::Transparent,
|
||||
PIScreenTypes::CharFlags flags_char = 0);
|
||||
void fillRect(int x0,
|
||||
int y0,
|
||||
int x1,
|
||||
int y1,
|
||||
const PIChar & c,
|
||||
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
||||
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
||||
PIScreenTypes::CharFlags flags_char = 0);
|
||||
void fillRect(int x0, int y0, int x1, int y1, PIVector<PIVector<PIScreenTypes::Cell>> & content);
|
||||
|
||||
PIChar artChar(const ArtChar type) const { return arts_.value(type, PIChar(' ')); }
|
||||
@@ -65,7 +102,6 @@ private:
|
||||
PIVector<PIVector<PIScreenTypes::Cell>> & cells;
|
||||
int width, height;
|
||||
PIMap<ArtChar, PIChar> arts_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -26,17 +26,20 @@
|
||||
#ifndef PISCREENTILE_H
|
||||
#define PISCREENTILE_H
|
||||
|
||||
#include "pikbdlistener.h"
|
||||
#include "pip_console_export.h"
|
||||
#include "piscreentypes.h"
|
||||
#include "pikbdlistener.h"
|
||||
|
||||
class PIScreenDrawer;
|
||||
|
||||
class PIP_CONSOLE_EXPORT PIScreenTile: public PIObject {
|
||||
friend class PIScreen;
|
||||
PIOBJECT_SUBCLASS(PIScreenTile, PIObject);
|
||||
|
||||
public:
|
||||
PIScreenTile(const PIString & n = PIString(), PIScreenTypes::Direction d = PIScreenTypes::Vertical, PIScreenTypes::SizePolicy p = PIScreenTypes::Preferred);
|
||||
PIScreenTile(const PIString & n = PIString(),
|
||||
PIScreenTypes::Direction d = PIScreenTypes::Vertical,
|
||||
PIScreenTypes::SizePolicy p = PIScreenTypes::Preferred);
|
||||
virtual ~PIScreenTile();
|
||||
|
||||
void addTile(PIScreenTile * t);
|
||||
@@ -50,7 +53,12 @@ public:
|
||||
void setFocus();
|
||||
bool hasFocus() const { return has_focus; }
|
||||
void setMargins(int m) { marginLeft = marginRight = marginTop = marginBottom = m; }
|
||||
void setMargins(int l, int r, int t, int b) {marginLeft = l; marginRight = r; marginTop = t; marginBottom = b;}
|
||||
void setMargins(int l, int r, int t, int b) {
|
||||
marginLeft = l;
|
||||
marginRight = r;
|
||||
marginTop = t;
|
||||
marginBottom = b;
|
||||
}
|
||||
|
||||
int x() const { return x_; }
|
||||
int y() const { return y_; }
|
||||
@@ -69,7 +77,6 @@ public:
|
||||
bool visible;
|
||||
|
||||
protected:
|
||||
|
||||
//! Returns desired tile size in "w" and "h"
|
||||
virtual void sizeHint(int & w, int & h) const;
|
||||
|
||||
@@ -103,7 +110,6 @@ protected:
|
||||
|
||||
private:
|
||||
int pw, ph;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
class PIP_CONSOLE_EXPORT TileSimple: public PIScreenTile {
|
||||
PIOBJECT_SUBCLASS(TileSimple, PIScreenTile);
|
||||
|
||||
public:
|
||||
typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
|
||||
TileSimple(const PIString & n = PIString());
|
||||
@@ -39,6 +40,7 @@ public:
|
||||
virtual ~TileSimple() {}
|
||||
PIVector<Row> content;
|
||||
PIScreenTypes::Alignment alignment;
|
||||
|
||||
protected:
|
||||
void sizeHint(int & w, int & h) const override;
|
||||
void drawEvent(PIScreenDrawer * d) override;
|
||||
@@ -50,6 +52,7 @@ class TileList;
|
||||
class PIP_CONSOLE_EXPORT TileScrollBar: public PIScreenTile {
|
||||
PIOBJECT_SUBCLASS(TileScrollBar, PIScreenTile);
|
||||
friend class TileList;
|
||||
|
||||
public:
|
||||
TileScrollBar(const PIString & n = PIString());
|
||||
virtual ~TileScrollBar() {}
|
||||
@@ -60,6 +63,7 @@ public:
|
||||
int maximum() const { return maximum_; }
|
||||
int value() const { return value_; }
|
||||
int thickness;
|
||||
|
||||
protected:
|
||||
void _check();
|
||||
void sizeHint(int & w, int & h) const override;
|
||||
@@ -72,6 +76,7 @@ protected:
|
||||
|
||||
class PIP_CONSOLE_EXPORT TileList: public PIScreenTile {
|
||||
PIOBJECT_SUBCLASS(TileList, PIScreenTile);
|
||||
|
||||
public:
|
||||
enum SelectionMode {
|
||||
NoSelection,
|
||||
@@ -92,6 +97,7 @@ public:
|
||||
SelectionMode selection_mode;
|
||||
PISet<int> selected;
|
||||
int lhei, cur, offset;
|
||||
|
||||
protected:
|
||||
void sizeHint(int & w, int & h) const override;
|
||||
void resizeEvent(int w, int h) override;
|
||||
@@ -106,6 +112,7 @@ protected:
|
||||
|
||||
class PIP_CONSOLE_EXPORT TileButton: public PIScreenTile {
|
||||
PIOBJECT_SUBCLASS(TileButton, PIScreenTile);
|
||||
|
||||
public:
|
||||
TileButton(const PIString & n = PIString());
|
||||
virtual ~TileButton() {}
|
||||
@@ -114,6 +121,7 @@ public:
|
||||
};
|
||||
PIScreenTypes::CellFormat format;
|
||||
PIString text;
|
||||
|
||||
protected:
|
||||
void sizeHint(int & w, int & h) const override;
|
||||
void drawEvent(PIScreenDrawer * d) override;
|
||||
@@ -122,10 +130,9 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class PIP_CONSOLE_EXPORT TileButtons: public PIScreenTile {
|
||||
PIOBJECT_SUBCLASS(TileButtons, PIScreenTile);
|
||||
|
||||
public:
|
||||
TileButtons(const PIString & n = PIString());
|
||||
virtual ~TileButtons() {}
|
||||
@@ -136,6 +143,7 @@ public:
|
||||
PIScreenTypes::Alignment alignment;
|
||||
PIVector<Button> content;
|
||||
int cur;
|
||||
|
||||
protected:
|
||||
void sizeHint(int & w, int & h) const override;
|
||||
void drawEvent(PIScreenDrawer * d) override;
|
||||
@@ -151,6 +159,7 @@ protected:
|
||||
|
||||
class PIP_CONSOLE_EXPORT TileCheck: public PIScreenTile {
|
||||
PIOBJECT_SUBCLASS(TileCheck, PIScreenTile);
|
||||
|
||||
public:
|
||||
TileCheck(const PIString & n = PIString());
|
||||
virtual ~TileCheck() {}
|
||||
@@ -160,6 +169,7 @@ public:
|
||||
PIScreenTypes::CellFormat format;
|
||||
PIString text;
|
||||
bool toggled;
|
||||
|
||||
protected:
|
||||
void sizeHint(int & w, int & h) const override;
|
||||
void drawEvent(PIScreenDrawer * d) override;
|
||||
@@ -170,6 +180,7 @@ protected:
|
||||
|
||||
class PIP_CONSOLE_EXPORT TileProgress: public PIScreenTile {
|
||||
PIOBJECT_SUBCLASS(TileProgress, PIScreenTile);
|
||||
|
||||
public:
|
||||
TileProgress(const PIString & n = PIString());
|
||||
virtual ~TileProgress() {}
|
||||
@@ -178,6 +189,7 @@ public:
|
||||
PIString suffix;
|
||||
double maximum;
|
||||
double value;
|
||||
|
||||
protected:
|
||||
void sizeHint(int & w, int & h) const override;
|
||||
void drawEvent(PIScreenDrawer * d) override;
|
||||
@@ -186,11 +198,13 @@ protected:
|
||||
|
||||
class PIP_CONSOLE_EXPORT TilePICout: public TileList {
|
||||
PIOBJECT_SUBCLASS(TilePICout, PIScreenTile);
|
||||
|
||||
public:
|
||||
TilePICout(const PIString & n = PIString());
|
||||
virtual ~TilePICout() {}
|
||||
PIScreenTypes::CellFormat format;
|
||||
int max_lines;
|
||||
|
||||
protected:
|
||||
void drawEvent(PIScreenDrawer * d) override;
|
||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
||||
@@ -199,12 +213,14 @@ protected:
|
||||
|
||||
class PIP_CONSOLE_EXPORT TileInput: public PIScreenTile {
|
||||
PIOBJECT_SUBCLASS(TileInput, PIScreenTile);
|
||||
|
||||
public:
|
||||
TileInput(const PIString & n = PIString());
|
||||
virtual ~TileInput() {}
|
||||
PIScreenTypes::CellFormat format;
|
||||
PIString text;
|
||||
int max_length;
|
||||
|
||||
protected:
|
||||
void sizeHint(int & w, int & h) const override;
|
||||
void drawEvent(PIScreenDrawer * d) override;
|
||||
|
||||
@@ -110,7 +110,10 @@ namespace PIScreenTypes {
|
||||
};
|
||||
|
||||
struct PIP_CONSOLE_EXPORT Cell {
|
||||
Cell(PIChar c = PIChar(' '), CellFormat f = CellFormat()) {symbol = c; format = f;}
|
||||
Cell(PIChar c = PIChar(' '), CellFormat f = CellFormat()) {
|
||||
symbol = c;
|
||||
format = f;
|
||||
}
|
||||
CellFormat format;
|
||||
PIChar symbol;
|
||||
bool operator==(const Cell & c) const { return format == c.format && symbol == c.symbol; }
|
||||
@@ -120,7 +123,8 @@ namespace PIScreenTypes {
|
||||
if (c.format.color_back == Transparent) {
|
||||
format.color_char = c.format.color_char;
|
||||
format.flags = c.format.flags;
|
||||
} else format = c.format;
|
||||
} else
|
||||
format = c.format;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
@@ -140,7 +144,7 @@ namespace PIScreenTypes {
|
||||
virtual void tileSetFocusInternal(PIScreenTile *) {}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace PIScreenTypes
|
||||
|
||||
|
||||
// inline PIByteArray & operator <<(PIByteArray & s, const PIScreenTypes::Cell & v) {s << v.format.raw_format << v.symbol; return s;}
|
||||
@@ -149,23 +153,35 @@ namespace PIScreenTypes {
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator
|
||||
//! \~russian Оператор сохранения
|
||||
BINARY_STREAM_WRITE(PIScreenTypes::Cell) {s << v.format.raw_format << v.symbol; return s;}
|
||||
BINARY_STREAM_WRITE(PIScreenTypes::Cell) {
|
||||
s << v.format.raw_format << v.symbol;
|
||||
return s;
|
||||
}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator
|
||||
//! \~russian Оператор извлечения
|
||||
BINARY_STREAM_READ (PIScreenTypes::Cell) {s >> v.format.raw_format >> v.symbol; return s;}
|
||||
BINARY_STREAM_READ(PIScreenTypes::Cell) {
|
||||
s >> v.format.raw_format >> v.symbol;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator
|
||||
//! \~russian Оператор сохранения
|
||||
BINARY_STREAM_WRITE(PIScreenTypes::TileEvent) {s << v.type << v.data; return s;}
|
||||
BINARY_STREAM_WRITE(PIScreenTypes::TileEvent) {
|
||||
s << v.type << v.data;
|
||||
return s;
|
||||
}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator
|
||||
//! \~russian Оператор извлечения
|
||||
BINARY_STREAM_READ (PIScreenTypes::TileEvent) {s >> v.type >> v.data; return s;}
|
||||
BINARY_STREAM_READ(PIScreenTypes::TileEvent) {
|
||||
s >> v.type >> v.data;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
REGISTER_PIVARIANTSIMPLE(PIScreenTypes::TileEvent)
|
||||
|
||||
@@ -26,16 +26,15 @@
|
||||
#ifndef PITERMINAL_H
|
||||
#define PITERMINAL_H
|
||||
|
||||
#include "pip_console_export.h"
|
||||
#include "pikbdlistener.h"
|
||||
#include "pip_console_export.h"
|
||||
#include "piscreentypes.h"
|
||||
|
||||
|
||||
class PIP_CONSOLE_EXPORT PITerminal: public PIThread
|
||||
{
|
||||
class PIP_CONSOLE_EXPORT PITerminal: public PIThread {
|
||||
PIOBJECT_SUBCLASS(PITerminal, PIThread);
|
||||
public:
|
||||
|
||||
public:
|
||||
//! Constructs %PITerminal
|
||||
PITerminal();
|
||||
|
||||
@@ -53,6 +52,7 @@ public:
|
||||
|
||||
bool initialize();
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
void initPrivate();
|
||||
void readConsole();
|
||||
@@ -73,7 +73,6 @@ private:
|
||||
bool cursor_blink, cursor_visible;
|
||||
PITimeMeasurer cursor_tm;
|
||||
PIVector<PIVector<PIScreenTypes::Cell>> cells;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -41,12 +41,12 @@
|
||||
#else
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include <string.h>
|
||||
#include <new>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <new>
|
||||
#include <string.h>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
template<typename C>
|
||||
@@ -58,6 +58,7 @@ public:
|
||||
typename C::reverse_iterator end() { return c_.rend(); }
|
||||
typename C::const_reverse_iterator begin() const { return c_.rbegin(); }
|
||||
typename C::const_reverse_iterator end() const { return c_.rend(); }
|
||||
|
||||
private:
|
||||
C & c_;
|
||||
};
|
||||
@@ -71,15 +72,24 @@ public:
|
||||
template<typename T>
|
||||
class _PIContainerConstants {
|
||||
public:
|
||||
static size_t minCountPoT() {static size_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T)); return ret;}
|
||||
static size_t minCountPoT() {
|
||||
static size_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T));
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! \brief
|
||||
//! \~english Template reverse wrapper over any container
|
||||
//! \~russian Шаблонная функция обертки любого контейнера для обратного доступа через итераторы
|
||||
template <typename C> _PIReverseWrapper<C> PIReverseWrap(C & c) {return _PIReverseWrapper<C>(c);}
|
||||
template <typename C> _PIReverseWrapper<C> PIReverseWrap(const C & c) {return _PIReverseWrapper<C>(c);}
|
||||
template<typename C>
|
||||
_PIReverseWrapper<C> PIReverseWrap(C & c) {
|
||||
return _PIReverseWrapper<C>(c);
|
||||
}
|
||||
template<typename C>
|
||||
_PIReverseWrapper<C> PIReverseWrap(const C & c) {
|
||||
return _PIReverseWrapper<C>(c);
|
||||
}
|
||||
|
||||
|
||||
//! \brief
|
||||
@@ -177,7 +187,9 @@ template <typename C> _PIReverseWrapper<C> PIReverseWrap(const C & c) {return _P
|
||||
//! \~russian Порядок обхода для функции изменения размерности reshape().
|
||||
//! \~ \sa \a PIVector::reshape(), \a PIDeque::reshape()
|
||||
enum ReshapeOrder {
|
||||
ReshapeByRow /*! \~english Traversing elements by line, just as they stay in memory \~russian Обход элементов построчно, так же как они находятся в памяти */,
|
||||
ReshapeByRow /*! \~english Traversing elements by line, just as they stay in memory \~russian Обход элементов построчно, так же как они
|
||||
находятся в памяти */
|
||||
,
|
||||
ReshapeByColumn /*! \~english Traversing elements by column \~russian Обход элементов по столбцам */,
|
||||
};
|
||||
|
||||
|
||||
@@ -180,12 +180,12 @@
|
||||
#ifndef PICONTAINERSMODULE_H
|
||||
#define PICONTAINERSMODULE_H
|
||||
|
||||
#include "pivector.h"
|
||||
#include "pideque.h"
|
||||
#include "pimap.h"
|
||||
#include "piqueue.h"
|
||||
#include "piset.h"
|
||||
#include "pistack.h"
|
||||
#include "pivector.h"
|
||||
#include "pivector2d.h"
|
||||
|
||||
|
||||
|
||||
@@ -127,9 +127,7 @@ public:
|
||||
|
||||
//! \~english Constructs an empty array.
|
||||
//! \~russian Создает пустой массив.
|
||||
inline PIDeque() {
|
||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||
}
|
||||
inline PIDeque() { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) }
|
||||
|
||||
//! \~english Copy constructor.
|
||||
//! \~russian Копирующий конструктор.
|
||||
@@ -226,10 +224,12 @@ public:
|
||||
|
||||
class iterator {
|
||||
friend class PIDeque<T>;
|
||||
|
||||
private:
|
||||
inline iterator(PIDeque<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
PIDeque<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
@@ -286,9 +286,7 @@ public:
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const iterator & it1, const iterator & it2) {
|
||||
return it1.pos - it2.pos;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const iterator & it1, const iterator & it2) { return it1.pos - it2.pos; }
|
||||
|
||||
friend inline iterator operator+(size_t p, const iterator & it) { return it + p; }
|
||||
friend inline iterator operator+(const iterator & it, size_t p) {
|
||||
@@ -299,26 +297,20 @@ public:
|
||||
|
||||
inline bool operator==(const iterator & it) const { return (pos == it.pos); }
|
||||
inline bool operator!=(const iterator & it) const { return (pos != it.pos); }
|
||||
friend inline bool operator <(const iterator & it1, const iterator & it2) {
|
||||
return it1.pos < it2.pos;
|
||||
}
|
||||
friend inline bool operator <=(const iterator & it1, const iterator & it2) {
|
||||
return it1.pos <= it2.pos;
|
||||
}
|
||||
friend inline bool operator >(const iterator & it1, const iterator & it2) {
|
||||
return it1.pos > it2.pos;
|
||||
}
|
||||
friend inline bool operator >=(const iterator & it1, const iterator & it2) {
|
||||
return it1.pos >= it2.pos;
|
||||
}
|
||||
friend inline bool operator<(const iterator & it1, const iterator & it2) { return it1.pos < it2.pos; }
|
||||
friend inline bool operator<=(const iterator & it1, const iterator & it2) { return it1.pos <= it2.pos; }
|
||||
friend inline bool operator>(const iterator & it1, const iterator & it2) { return it1.pos > it2.pos; }
|
||||
friend inline bool operator>=(const iterator & it1, const iterator & it2) { return it1.pos >= it2.pos; }
|
||||
};
|
||||
|
||||
class const_iterator {
|
||||
friend class PIDeque<T>;
|
||||
|
||||
private:
|
||||
inline const_iterator(const PIDeque<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIDeque<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
@@ -373,9 +365,7 @@ public:
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const const_iterator & it1, const const_iterator & it2) {
|
||||
return it1.pos - it2.pos;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const const_iterator & it1, const const_iterator & it2) { return it1.pos - it2.pos; }
|
||||
|
||||
friend inline const_iterator operator+(size_t p, const const_iterator & it) { return it + p; }
|
||||
friend inline const_iterator operator+(const const_iterator & it, size_t p) {
|
||||
@@ -386,26 +376,20 @@ public:
|
||||
|
||||
inline bool operator==(const const_iterator & it) const { return (pos == it.pos); }
|
||||
inline bool operator!=(const const_iterator & it) const { return (pos != it.pos); }
|
||||
friend inline bool operator <(const const_iterator & it1, const const_iterator & it2) {
|
||||
return it1.pos < it2.pos;
|
||||
}
|
||||
friend inline bool operator <=(const const_iterator & it1, const const_iterator & it2) {
|
||||
return it1.pos <= it2.pos;
|
||||
}
|
||||
friend inline bool operator >(const const_iterator & it1, const const_iterator & it2) {
|
||||
return it1.pos > it2.pos;
|
||||
}
|
||||
friend inline bool operator >=(const const_iterator & it1, const const_iterator & it2) {
|
||||
return it1.pos >= it2.pos;
|
||||
}
|
||||
friend inline bool operator<(const const_iterator & it1, const const_iterator & it2) { return it1.pos < it2.pos; }
|
||||
friend inline bool operator<=(const const_iterator & it1, const const_iterator & it2) { return it1.pos <= it2.pos; }
|
||||
friend inline bool operator>(const const_iterator & it1, const const_iterator & it2) { return it1.pos > it2.pos; }
|
||||
friend inline bool operator>=(const const_iterator & it1, const const_iterator & it2) { return it1.pos >= it2.pos; }
|
||||
};
|
||||
|
||||
class reverse_iterator {
|
||||
friend class PIDeque<T>;
|
||||
|
||||
private:
|
||||
inline reverse_iterator(PIDeque<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
PIDeque<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
@@ -462,9 +446,7 @@ public:
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const reverse_iterator & it1, const reverse_iterator & it2) {
|
||||
return it2.pos - it1.pos;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const reverse_iterator & it1, const reverse_iterator & it2) { return it2.pos - it1.pos; }
|
||||
|
||||
friend inline reverse_iterator operator+(size_t p, const reverse_iterator & it) { return it + p; }
|
||||
friend inline reverse_iterator operator+(const reverse_iterator & it, size_t p) {
|
||||
@@ -475,26 +457,20 @@ public:
|
||||
|
||||
inline bool operator==(const reverse_iterator & it) const { return (pos == it.pos); }
|
||||
inline bool operator!=(const reverse_iterator & it) const { return (pos != it.pos); }
|
||||
friend inline bool operator <(const reverse_iterator & it1, const reverse_iterator & it2) {
|
||||
return it1.pos < it2.pos;
|
||||
}
|
||||
friend inline bool operator <=(const reverse_iterator & it1, const reverse_iterator & it2) {
|
||||
return it1.pos <= it2.pos;
|
||||
}
|
||||
friend inline bool operator >(const reverse_iterator & it1, const reverse_iterator & it2) {
|
||||
return it1.pos > it2.pos;
|
||||
}
|
||||
friend inline bool operator >=(const reverse_iterator & it1, const reverse_iterator & it2) {
|
||||
return it1.pos >= it2.pos;
|
||||
}
|
||||
friend inline bool operator<(const reverse_iterator & it1, const reverse_iterator & it2) { return it1.pos < it2.pos; }
|
||||
friend inline bool operator<=(const reverse_iterator & it1, const reverse_iterator & it2) { return it1.pos <= it2.pos; }
|
||||
friend inline bool operator>(const reverse_iterator & it1, const reverse_iterator & it2) { return it1.pos > it2.pos; }
|
||||
friend inline bool operator>=(const reverse_iterator & it1, const reverse_iterator & it2) { return it1.pos >= it2.pos; }
|
||||
};
|
||||
|
||||
class const_reverse_iterator {
|
||||
friend class PIDeque<T>;
|
||||
|
||||
private:
|
||||
inline const_reverse_iterator(const PIDeque<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIDeque<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
@@ -561,18 +537,10 @@ public:
|
||||
|
||||
inline bool operator==(const const_reverse_iterator & it) const { return (pos == it.pos); }
|
||||
inline bool operator!=(const const_reverse_iterator & it) const { return (pos != it.pos); }
|
||||
friend inline bool operator <(const const_reverse_iterator & it1, const const_reverse_iterator & it2) {
|
||||
return it1.pos < it2.pos;
|
||||
}
|
||||
friend inline bool operator <=(const const_reverse_iterator & it1, const const_reverse_iterator & it2) {
|
||||
return it1.pos <= it2.pos;
|
||||
}
|
||||
friend inline bool operator >(const const_reverse_iterator & it1, const const_reverse_iterator & it2) {
|
||||
return it1.pos > it2.pos;
|
||||
}
|
||||
friend inline bool operator >=(const const_reverse_iterator & it1, const const_reverse_iterator & it2) {
|
||||
return it1.pos >= it2.pos;
|
||||
}
|
||||
friend inline bool operator<(const const_reverse_iterator & it1, const const_reverse_iterator & it2) { return it1.pos < it2.pos; }
|
||||
friend inline bool operator<=(const const_reverse_iterator & it1, const const_reverse_iterator & it2) { return it1.pos <= it2.pos; }
|
||||
friend inline bool operator>(const const_reverse_iterator & it1, const const_reverse_iterator & it2) { return it1.pos > it2.pos; }
|
||||
friend inline bool operator>=(const const_reverse_iterator & it1, const const_reverse_iterator & it2) { return it1.pos >= it2.pos; }
|
||||
};
|
||||
|
||||
|
||||
@@ -762,8 +730,10 @@ public:
|
||||
//! \~\sa \a indexWhere()
|
||||
inline const T & atWhere(std::function<bool(const T & e)> test, ssize_t start = 0, const T & def = T()) const {
|
||||
ssize_t i = indexWhere(test, start);
|
||||
if (i < 0) return def;
|
||||
else return at(i);
|
||||
if (i < 0)
|
||||
return def;
|
||||
else
|
||||
return at(i);
|
||||
}
|
||||
|
||||
//! \~english Returns the last element of the array that
|
||||
@@ -774,8 +744,10 @@ public:
|
||||
//! \~\sa \a lastIndexWhere()
|
||||
inline const T & lastAtWhere(std::function<bool(const T & e)> test, ssize_t start = -1, const T & def = T()) const {
|
||||
ssize_t i = lastIndexWhere(test, start);
|
||||
if (i < 0) return def;
|
||||
else return at(i);
|
||||
if (i < 0)
|
||||
return def;
|
||||
else
|
||||
return at(i);
|
||||
}
|
||||
|
||||
//! \~english Last element.
|
||||
@@ -1184,18 +1156,14 @@ public:
|
||||
//! \~english Reserved memory will not be released.
|
||||
//! \~russian Зарезервированная память не освободится.
|
||||
//! \~\sa \a resize()
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIDeque<T> & clear() {
|
||||
deleteT(pid_data + pid_start, pid_size);
|
||||
pid_size = 0;
|
||||
pid_start = (pid_rsize - pid_size) / 2;
|
||||
return *this;
|
||||
}
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIDeque<T> & clear() {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, pid_size)
|
||||
pid_size = 0;
|
||||
@@ -1247,16 +1215,12 @@ public:
|
||||
//! \~english First does `resize(new_size)` then `fill(e)`.
|
||||
//! \~russian Сначала делает `resize(new_size)`, затем `fill(e)`.
|
||||
//! \~\sa \a fill(), \a resize()
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIDeque<T> & assign(size_t new_size, const T & e) {
|
||||
resize(new_size);
|
||||
return fill(e);
|
||||
}
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIDeque<T> & assign(size_t new_size, const T & e) {
|
||||
_resizeRaw(new_size);
|
||||
return fill(e);
|
||||
@@ -1306,9 +1270,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIDeque<T> & _resizeRaw(size_t new_size) {
|
||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
if (new_size > pid_size) {
|
||||
@@ -1322,9 +1284,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void _copyRaw(T * dst, const T * src, size_t size) {
|
||||
newT(dst, src, size);
|
||||
}
|
||||
inline void _copyRaw(T * dst, const T * src, size_t size) { newT(dst, src, size); }
|
||||
|
||||
//! \~english Attempts to allocate memory for at least `new_size` elements.
|
||||
//! \~russian Резервируется память под как минимум `new_size` элементов.
|
||||
@@ -1453,7 +1413,9 @@ public:
|
||||
ssize_t os = ssize_t(pid_size) - index;
|
||||
alloc_forward(pid_size + init_list.size());
|
||||
if (os > 0) {
|
||||
memmove((void*)(pid_data + pid_start + index + init_list.size()), (const void*)(pid_data + pid_start + index), os * sizeof(T));
|
||||
memmove((void *)(pid_data + pid_start + index + init_list.size()),
|
||||
(const void *)(pid_data + pid_start + index),
|
||||
os * sizeof(T));
|
||||
}
|
||||
} else {
|
||||
alloc_backward(pid_size + init_list.size(), -init_list.size());
|
||||
@@ -1548,16 +1510,11 @@ public:
|
||||
//! Complexity `O(N·log(N))`.
|
||||
//! \~russian Сохранность порядка элементов, имеющих одинаковое значение, не гарантируется.
|
||||
//! Для сравнения элементов используется функция сравнения `comp`.
|
||||
//! Функция сравнения, возвращает `true` если первый аргумент меньше второго.
|
||||
//! Сигнатура функции сравнения должна быть эквивалентна следующей:
|
||||
//! \code
|
||||
//! bool comp(const T &a, const T &b);
|
||||
//! \endcode
|
||||
//! Сигнатура не обязана содержать const &, однако, функция не может изменять переданные объекты.
|
||||
//! Функция обязана возвращать `false` для одинаковых элементов,
|
||||
//! иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
//! Для сортировки используется функция [std::sort](https://ru.cppreference.com/w/cpp/algorithm/sort).
|
||||
//! Сложность сортировки `O(N·log(N))`.
|
||||
//! Функция сравнения, возвращает `true` если первый аргумент меньше
|
||||
//! второго. Сигнатура функции сравнения должна быть эквивалентна следующей: \code bool comp(const T &a, const T &b); \endcode Сигнатура
|
||||
//! не обязана содержать const &, однако, функция не может изменять переданные объекты. Функция обязана возвращать `false` для
|
||||
//! одинаковых элементов, иначе это приведёт к неопределённому поведению программы и ошибкам памяти. Для сортировки используется функция
|
||||
//! [std::sort](https://ru.cppreference.com/w/cpp/algorithm/sort). Сложность сортировки `O(N·log(N))`.
|
||||
//! \~\code
|
||||
//! PIDeque<int> v{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
|
||||
//! v.sort([](const int & a, const int & b){return a > b;});
|
||||
@@ -1619,8 +1576,10 @@ public:
|
||||
//! \~\sa \a resize()
|
||||
inline PIDeque<T> & enlarge(ssize_t add_size, const T & e = T()) {
|
||||
ssize_t ns = size_s() + add_size;
|
||||
if (ns <= 0) clear();
|
||||
else resize(size_t(ns), e);
|
||||
if (ns <= 0)
|
||||
clear();
|
||||
else
|
||||
resize(size_t(ns), e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1912,9 +1871,7 @@ public:
|
||||
//! piCout << v; // {4, 5, 1, 2, 3}
|
||||
//! \endcode
|
||||
//! \~\sa \a push_front()
|
||||
inline PIDeque<T> & push_front(const PIDeque<T> & v) {
|
||||
return insert(0, v);
|
||||
}
|
||||
inline PIDeque<T> & push_front(const PIDeque<T> & v) { return insert(0, v); }
|
||||
|
||||
//! \~english Appends the given elements to the begin of the array.
|
||||
//! \~russian Добавляет элементы в начало массива.
|
||||
@@ -1926,9 +1883,7 @@ public:
|
||||
//! Добавляет элементы из
|
||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~\sa \a append()
|
||||
inline PIDeque<T> & push_front(std::initializer_list<T> init_list) {
|
||||
return insert(0, init_list);
|
||||
}
|
||||
inline PIDeque<T> & push_front(std::initializer_list<T> init_list) { return insert(0, init_list); }
|
||||
|
||||
//! \~english Appends the given element `e` to the begin of the array.
|
||||
//! \~russian Добавляет элемент `e` в начало массива.
|
||||
@@ -2249,7 +2204,8 @@ public:
|
||||
//! \~\sa \a forEach(), \a reduce()
|
||||
template<typename ST>
|
||||
inline PIDeque<ST> map(std::function<ST(const T & e)> f) const {
|
||||
PIDeque<ST> ret; ret.reserve(pid_size);
|
||||
PIDeque<ST> ret;
|
||||
ret.reserve(pid_size);
|
||||
for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
|
||||
ret << f(pid_data[i]);
|
||||
}
|
||||
@@ -2266,7 +2222,8 @@ public:
|
||||
//! \~\sa \a map()
|
||||
template<typename ST>
|
||||
inline PIDeque<ST> mapIndexed(std::function<ST(size_t index, const T & e)> f) const {
|
||||
PIDeque<ST> ret; ret.reserve(pid_size);
|
||||
PIDeque<ST> ret;
|
||||
ret.reserve(pid_size);
|
||||
for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
|
||||
ret << f(i - pid_start, pid_data[i]);
|
||||
}
|
||||
@@ -2283,7 +2240,8 @@ public:
|
||||
//! \~\sa \a map()
|
||||
template<typename ST>
|
||||
inline PIDeque<ST> mapReverse(std::function<ST(const T & e)> f) const {
|
||||
PIDeque<ST> ret; ret.reserve(pid_size);
|
||||
PIDeque<ST> ret;
|
||||
ret.reserve(pid_size);
|
||||
for (ssize_t i = ssize_t(pid_start + pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
ret << f(pid_data[i]);
|
||||
}
|
||||
@@ -2300,7 +2258,8 @@ public:
|
||||
//! \~\sa \a mapReverse()
|
||||
template<typename ST>
|
||||
inline PIDeque<ST> mapReverseIndexed(std::function<ST(size_t index, const T & e)> f) const {
|
||||
PIDeque<ST> ret; ret.reserve(pid_size);
|
||||
PIDeque<ST> ret;
|
||||
ret.reserve(pid_size);
|
||||
for (ssize_t i = ssize_t(pid_start + pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
ret << f(size_t(i) - pid_start, pid_data[i]);
|
||||
}
|
||||
@@ -2452,9 +2411,7 @@ public:
|
||||
//! piCout << xv.flatten<int>(); // {1, 2, 3, 4, 5, 6}
|
||||
//! \endcode
|
||||
//! \~\sa \a map(), \a reduce(), \a reshape()
|
||||
template<typename C, typename std::enable_if<
|
||||
std::is_same<T, PIDeque<C>>::value
|
||||
, int>::type = 0>
|
||||
template<typename C, typename std::enable_if<std::is_same<T, PIDeque<C>>::value, int>::type = 0>
|
||||
inline PIDeque<C> flatten(ReshapeOrder order = ReshapeByRow) const {
|
||||
PIDeque<C> ret;
|
||||
if (isEmpty()) return ret;
|
||||
@@ -2495,9 +2452,7 @@ public:
|
||||
//! piCout << xv.reshape<int>(2,3); // {{1, 2, 3}, {4, 5, 6}}
|
||||
//! \endcode
|
||||
//! \~\sa \a map(), \a reduce(), \a reshape()
|
||||
template<typename C, typename std::enable_if<
|
||||
std::is_same<T, PIDeque<C>>::value
|
||||
, int>::type = 0>
|
||||
template<typename C, typename std::enable_if<std::is_same<T, PIDeque<C>>::value, int>::type = 0>
|
||||
inline PIDeque<PIDeque<C>> reshape(size_t rows, size_t cols, ReshapeOrder order = ReshapeByRow) const {
|
||||
PIDeque<C> fl = flatten<C>();
|
||||
return fl.reshape(rows, cols, order);
|
||||
@@ -2597,13 +2552,12 @@ private:
|
||||
}
|
||||
size_t t = _PIContainerConstants<T>::minCountPoT();
|
||||
size_t s_ = s - 1;
|
||||
while (s_ >> t) ++t;
|
||||
while (s_ >> t)
|
||||
++t;
|
||||
return (1 << t);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void newT(T * dst, const T * src, size_t s) {
|
||||
PIINTROSPECTION_CONTAINER_USED(T, s)
|
||||
for (size_t i = 0; i < s; ++i) {
|
||||
@@ -2611,17 +2565,13 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void newT(T * dst, const T * src, size_t s) {
|
||||
PIINTROSPECTION_CONTAINER_USED(T, s)
|
||||
memcpy((void *)(dst), (const void *)(src), s * sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void deleteT(T * d, size_t sz) {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
|
||||
if (d != nullptr) {
|
||||
@@ -2631,51 +2581,37 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void deleteT(T * d, size_t sz) {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T * to, const T & from) {
|
||||
new (to) T(from);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T * to, T && from) {
|
||||
new (to) T(std::move(from));
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T1 * to, const T & from) {
|
||||
(*to) = from;
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T * to, T && from) {
|
||||
(*to) = std::move(from);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementDelete(T & from) {
|
||||
from.~T();
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementDelete(T & from) {}
|
||||
|
||||
inline void dealloc() {
|
||||
@@ -2810,7 +2746,9 @@ inline PICout operator <<(PICout s, const PIDeque<T> & v) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void piSwap(PIDeque<T> & f, PIDeque<T> & s) {f.swap(s);}
|
||||
inline void piSwap(PIDeque<T> & f, PIDeque<T> & s) {
|
||||
f.swap(s);
|
||||
}
|
||||
|
||||
|
||||
#endif // PIDEQUE_H
|
||||
|
||||
@@ -34,15 +34,19 @@
|
||||
#ifndef PIMAP_H
|
||||
#define PIMAP_H
|
||||
|
||||
#include "pivector.h"
|
||||
#include "pideque.h"
|
||||
#include "pipair.h"
|
||||
#include "pivector.h"
|
||||
|
||||
|
||||
template <typename Key, typename T> class PIMapIteratorConst;
|
||||
template <typename Key, typename T> class PIMapIteratorConstReverse;
|
||||
template <typename Key, typename T> class PIMapIterator;
|
||||
template <typename Key, typename T> class PIMapIteratorReverse;
|
||||
template<typename Key, typename T>
|
||||
class PIMapIteratorConst;
|
||||
template<typename Key, typename T>
|
||||
class PIMapIteratorConstReverse;
|
||||
template<typename Key, typename T>
|
||||
class PIMapIterator;
|
||||
template<typename Key, typename T>
|
||||
class PIMapIteratorReverse;
|
||||
|
||||
|
||||
//! \addtogroup Containers
|
||||
@@ -76,14 +80,19 @@ template <typename Key, typename T> class PIMapIteratorReverse;
|
||||
//! и если такого эелемента не было, то он будет создан.
|
||||
template<typename Key, typename T>
|
||||
class PIMap {
|
||||
template <typename Key1, typename T1> friend class PIMapIteratorConst;
|
||||
template <typename Key1, typename T1> friend class PIMapIteratorConstReverse;
|
||||
template <typename Key1, typename T1> friend class PIMapIterator;
|
||||
template <typename Key1, typename T1> friend class PIMapIteratorReverse;
|
||||
template<typename Key1, typename T1>
|
||||
friend class PIMapIteratorConst;
|
||||
template<typename Key1, typename T1>
|
||||
friend class PIMapIteratorConstReverse;
|
||||
template<typename Key1, typename T1>
|
||||
friend class PIMapIterator;
|
||||
template<typename Key1, typename T1>
|
||||
friend class PIMapIteratorReverse;
|
||||
template<typename P, typename Key1, typename T1>
|
||||
friend PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIMap<Key1, T1> & v);
|
||||
template<typename P, typename Key1, typename T1>
|
||||
friend PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMap<Key1, T1> & v);
|
||||
|
||||
public:
|
||||
typedef T mapped_type;
|
||||
typedef Key key_type;
|
||||
@@ -135,10 +144,12 @@ public:
|
||||
|
||||
class iterator {
|
||||
friend class PIMap<Key, T>;
|
||||
|
||||
private:
|
||||
iterator(const PIMap<Key, T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIMap<Key, T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
iterator(): parent(nullptr), pos(0) {}
|
||||
const Key & key() const { return const_cast<PIMap<Key, T> *>(parent)->_key(pos); }
|
||||
@@ -156,10 +167,12 @@ public:
|
||||
|
||||
class reverse_iterator {
|
||||
friend class PIMap<Key, T>;
|
||||
|
||||
private:
|
||||
reverse_iterator(const PIMap<Key, T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIMap<Key, T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
reverse_iterator(): parent(nullptr), pos(0) {}
|
||||
const Key & key() const { return const_cast<PIMap<Key, T> *>(parent)->_key(pos); }
|
||||
@@ -177,10 +190,12 @@ public:
|
||||
|
||||
class const_iterator {
|
||||
friend class PIMap<Key, T>;
|
||||
|
||||
private:
|
||||
const_iterator(const PIMap<Key, T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIMap<Key, T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
const_iterator(): parent(nullptr), pos(0) {}
|
||||
const value_type operator*() const { return parent->_pair(pos); }
|
||||
@@ -196,10 +211,12 @@ public:
|
||||
|
||||
class const_reverse_iterator {
|
||||
friend class PIMap<Key, T>;
|
||||
|
||||
private:
|
||||
const_reverse_iterator(const PIMap<Key, T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIMap<Key, T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
const_reverse_iterator(): parent(nullptr), pos(0) {}
|
||||
const value_type operator*() const { return parent->_pair(pos); }
|
||||
@@ -351,28 +368,23 @@ public:
|
||||
|
||||
//! \~english Compare operator with array `m`.
|
||||
//! \~russian Оператор сравнения с массивом `m`.
|
||||
inline bool operator ==(const PIMap<Key, T> & m) const {
|
||||
return (pim_content == m.pim_content && pim_index == m.pim_index);
|
||||
}
|
||||
inline bool operator==(const PIMap<Key, T> & m) const { return (pim_content == m.pim_content && pim_index == m.pim_index); }
|
||||
|
||||
//! \~english Compare operator with array `m`.
|
||||
//! \~russian Оператор сравнения с массивом `m`.
|
||||
inline bool operator !=(const PIMap<Key, T> & m) const {
|
||||
return (pim_content != m.pim_content || pim_index != m.pim_index);
|
||||
}
|
||||
inline bool operator!=(const PIMap<Key, T> & m) const { return (pim_content != m.pim_content || pim_index != m.pim_index); }
|
||||
|
||||
//! \~english Tests if element with key `key` exists in the array.
|
||||
//! \~russian Проверяет наличие элемента с ключом `key` в массиве.
|
||||
inline bool contains(const Key & key) const {
|
||||
bool f(false); _find(key, f);
|
||||
bool f(false);
|
||||
_find(key, f);
|
||||
return f;
|
||||
}
|
||||
|
||||
//! \~english Tests if element with value `value` exists in the array.
|
||||
//! \~russian Проверяет наличие элемента со значением `value` в массиве.
|
||||
inline bool containsValue(const T & value) const {
|
||||
return pim_content.contains(value);
|
||||
}
|
||||
inline bool containsValue(const T & value) const { return pim_content.contains(value); }
|
||||
|
||||
//! \~english Attempts to allocate memory for at least `new_size` elements.
|
||||
//! \~russian Резервируется память под как минимум `new_size` элементов.
|
||||
@@ -407,9 +419,7 @@ public:
|
||||
|
||||
//! \~english Same as \a remove().
|
||||
//! \~russian Синоним функции \a remove().
|
||||
inline PIMap<Key, T> & erase(const Key & key) {
|
||||
return remove(key);
|
||||
}
|
||||
inline PIMap<Key, T> & erase(const Key & key) { return remove(key); }
|
||||
|
||||
|
||||
//! \~english Clear array, remove all elements.
|
||||
@@ -547,7 +557,8 @@ public:
|
||||
//! `PIPair<Key2, T2> f(const Key & key, const T & value)` для каждого элемента массива.
|
||||
template<typename Key2, typename T2>
|
||||
inline PIMap<Key2, T2> map(std::function<PIPair<Key2, T2>(const Key & key, const T & value)> f) const {
|
||||
PIMap<Key2, T2> ret; ret.reserve(size());
|
||||
PIMap<Key2, T2> ret;
|
||||
ret.reserve(size());
|
||||
for (int i = 0; i < pim_index.size_s(); ++i) {
|
||||
ret.insert(f(pim_index[i].key, pim_content[pim_index[i].index]));
|
||||
}
|
||||
@@ -560,7 +571,8 @@ public:
|
||||
//! `ST f(const Key & key, const T & value)` для каждого элемента массива.
|
||||
template<typename ST>
|
||||
inline PIVector<ST> map(std::function<ST(const Key & key, const T & value)> f) const {
|
||||
PIVector<ST> ret; ret.reserve(size());
|
||||
PIVector<ST> ret;
|
||||
ret.reserve(size());
|
||||
for (int i = 0; i < pim_index.size_s(); ++i) {
|
||||
ret << f(pim_index[i].key, pim_content[pim_index[i].index]);
|
||||
}
|
||||
@@ -602,9 +614,14 @@ private:
|
||||
ssize_t mid;
|
||||
while (first <= last) {
|
||||
mid = (first + last) / 2;
|
||||
if (key > pim_index[mid].key) first = mid + 1;
|
||||
else if (key < pim_index[mid].key) last = mid - 1;
|
||||
else {found = true; return mid;}
|
||||
if (key > pim_index[mid].key)
|
||||
first = mid + 1;
|
||||
else if (key < pim_index[mid].key)
|
||||
last = mid - 1;
|
||||
else {
|
||||
found = true;
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
found = false;
|
||||
return first;
|
||||
@@ -681,30 +698,25 @@ private:
|
||||
template<typename Key, typename T>
|
||||
class PIMapIteratorConst {
|
||||
typedef PIMap<Key, T> MapType;
|
||||
|
||||
public:
|
||||
inline PIMapIteratorConst(const PIMap<Key, T> & map): m(map), pos(-1) {}
|
||||
|
||||
//! \~english Returns current key.
|
||||
//! \~russian Возвращает ключ текущего элемента.
|
||||
//! \~\sa \a value()
|
||||
inline const Key & key() const {
|
||||
return m._key(pos);
|
||||
}
|
||||
inline const Key & key() const { return m._key(pos); }
|
||||
|
||||
//! \~english Returns current value.
|
||||
//! \~russian Возвращает значение текущего элемента.
|
||||
//! \~\sa \a key()
|
||||
inline const T & value() const {
|
||||
return m._value(pos);
|
||||
}
|
||||
inline const T & value() const { return m._value(pos); }
|
||||
|
||||
|
||||
//! \~english Returns true if iterator can jump to next entry
|
||||
//! \~russian Возвращает true если итератор может перейти к следующему элементу.
|
||||
//! \~\sa \a next()
|
||||
inline bool hasNext() const {
|
||||
return pos < (m.size_s() - 1);
|
||||
}
|
||||
inline bool hasNext() const { return pos < (m.size_s() - 1); }
|
||||
|
||||
//! \~english Jump to next entry and return true if new position is valid.
|
||||
//! \~russian Переходит к следующему элементу и возвращает true если он существует.
|
||||
@@ -717,9 +729,8 @@ public:
|
||||
//! \~english Reset iterator to initial position.
|
||||
//! \~russian Переходит на начало.
|
||||
//! \~\sa \a next()
|
||||
inline void reset() {
|
||||
pos = -1;
|
||||
}
|
||||
inline void reset() { pos = -1; }
|
||||
|
||||
private:
|
||||
const MapType & m;
|
||||
ssize_t pos;
|
||||
@@ -757,29 +768,24 @@ private:
|
||||
template<typename Key, typename T>
|
||||
class PIMapIteratorConstReverse {
|
||||
typedef PIMap<Key, T> MapType;
|
||||
|
||||
public:
|
||||
inline PIMapIteratorConstReverse(const PIMap<Key, T> & map): m(map), pos(m.size_s()) {}
|
||||
|
||||
//! \~english Returns current key.
|
||||
//! \~russian Возвращает ключ текущего элемента.
|
||||
//! \~\sa \a value()
|
||||
inline const Key & key() const {
|
||||
return m._key(pos);
|
||||
}
|
||||
inline const Key & key() const { return m._key(pos); }
|
||||
|
||||
//! \~english Returns current value.
|
||||
//! \~russian Возвращает значение текущего элемента.
|
||||
//! \~\sa \a key()
|
||||
inline const T & value() const {
|
||||
return m._value(pos);
|
||||
}
|
||||
inline const T & value() const { return m._value(pos); }
|
||||
|
||||
//! \~english Returns true if iterator can jump to next entry
|
||||
//! \~russian Возвращает true если итератор может перейти к следующему элементу.
|
||||
//! \~\sa \a next()
|
||||
inline bool hasNext() const {
|
||||
return pos > 0;
|
||||
}
|
||||
inline bool hasNext() const { return pos > 0; }
|
||||
|
||||
//! \~english Jump to next entry and return true if new position is valid.
|
||||
//! \~russian Переходит к следующему элементу и возвращает true если он существует.
|
||||
@@ -792,9 +798,8 @@ public:
|
||||
//! \~english Reset iterator to initial position.
|
||||
//! \~russian Переходит на начало.
|
||||
//! \~\sa \a next()
|
||||
inline void reset() {
|
||||
pos = m.size_s();
|
||||
}
|
||||
inline void reset() { pos = m.size_s(); }
|
||||
|
||||
private:
|
||||
const MapType & m;
|
||||
ssize_t pos;
|
||||
@@ -833,29 +838,24 @@ private:
|
||||
template<typename Key, typename T>
|
||||
class PIMapIterator {
|
||||
typedef PIMap<Key, T> MapType;
|
||||
|
||||
public:
|
||||
inline PIMapIterator(PIMap<Key, T> & map): m(map), pos(-1) {}
|
||||
|
||||
//! \~english Returns current key.
|
||||
//! \~russian Возвращает ключ текущего элемента.
|
||||
//! \~\sa \a value()
|
||||
inline const Key & key() const {
|
||||
return m._key(pos);
|
||||
}
|
||||
inline const Key & key() const { return m._key(pos); }
|
||||
|
||||
//! \~english Returns current value.
|
||||
//! \~russian Возвращает значение текущего элемента.
|
||||
//! \~\sa \a key()
|
||||
inline T & value() {
|
||||
return m._value(pos);
|
||||
}
|
||||
inline T & value() { return m._value(pos); }
|
||||
|
||||
//! \~english Returns true if iterator can jump to next entry
|
||||
//! \~russian Возвращает true если итератор может перейти к следующему элементу.
|
||||
//! \~\sa \a next()
|
||||
inline bool hasNext() const {
|
||||
return pos < (m.size_s() - 1);
|
||||
}
|
||||
inline bool hasNext() const { return pos < (m.size_s() - 1); }
|
||||
|
||||
//! \~english Jump to next entry and return true if new position is valid.
|
||||
//! \~russian Переходит к следующему элементу и возвращает true если он существует.
|
||||
@@ -868,9 +868,8 @@ public:
|
||||
//! \~english Reset iterator to initial position.
|
||||
//! \~russian Переходит на начало.
|
||||
//! \~\sa \a next()
|
||||
inline void reset() {
|
||||
pos = -1;
|
||||
}
|
||||
inline void reset() { pos = -1; }
|
||||
|
||||
private:
|
||||
MapType & m;
|
||||
ssize_t pos;
|
||||
@@ -909,29 +908,24 @@ private:
|
||||
template<typename Key, typename T>
|
||||
class PIMapIteratorReverse {
|
||||
typedef PIMap<Key, T> MapType;
|
||||
|
||||
public:
|
||||
inline PIMapIteratorReverse(PIMap<Key, T> & map): m(map), pos(m.size_s()) {}
|
||||
|
||||
//! \~english Returns current key.
|
||||
//! \~russian Возвращает ключ текущего элемента.
|
||||
//! \~\sa \a value()
|
||||
inline const Key & key() const {
|
||||
return m._key(pos);
|
||||
}
|
||||
inline const Key & key() const { return m._key(pos); }
|
||||
|
||||
//! \~english Returns current value.
|
||||
//! \~russian Возвращает значение текущего элемента.
|
||||
//! \~\sa \a key()
|
||||
inline T & value() {
|
||||
return m._value(pos);
|
||||
}
|
||||
inline T & value() { return m._value(pos); }
|
||||
|
||||
//! \~english Returns true if iterator can jump to next entry
|
||||
//! \~russian Возвращает true если итератор может перейти к следующему элементу.
|
||||
//! \~\sa \a next()
|
||||
inline bool hasNext() const {
|
||||
return pos > 0;
|
||||
}
|
||||
inline bool hasNext() const { return pos > 0; }
|
||||
|
||||
//! \~english Jump to next entry and return true if new position is valid.
|
||||
//! \~russian Переходит к следующему элементу и возвращает true если он существует.
|
||||
@@ -944,9 +938,8 @@ public:
|
||||
//! \~english Reset iterator to initial position.
|
||||
//! \~russian Переходит на начало.
|
||||
//! \~\sa \a next()
|
||||
inline void reset() {
|
||||
pos = m.size_s();
|
||||
}
|
||||
inline void reset() { pos = m.size_s(); }
|
||||
|
||||
private:
|
||||
MapType & m;
|
||||
ssize_t pos;
|
||||
@@ -961,8 +954,7 @@ inline std::ostream & operator <<(std::ostream & s, const PIMap<Key, Type> & v)
|
||||
s << "{";
|
||||
bool first = true;
|
||||
for (typename PIMap<Key, Type>::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||
if (!first)
|
||||
s << ", ";
|
||||
if (!first) s << ", ";
|
||||
first = false;
|
||||
s << i.key() << ": " << i.value();
|
||||
}
|
||||
@@ -982,8 +974,7 @@ inline PICout operator <<(PICout s, const PIMap<Key, Type> & v) {
|
||||
s << "{";
|
||||
bool first = true;
|
||||
for (typename PIMap<Key, Type>::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||
if (!first)
|
||||
s << ", ";
|
||||
if (!first) s << ", ";
|
||||
first = false;
|
||||
s << i.key() << ": " << i.value();
|
||||
}
|
||||
@@ -993,7 +984,9 @@ inline PICout operator <<(PICout s, const PIMap<Key, Type> & v) {
|
||||
}
|
||||
|
||||
template<typename Key, typename Type>
|
||||
inline void piSwap(PIMap<Key, Type> & f, PIMap<Key, Type> & s) {f.swap(s);}
|
||||
inline void piSwap(PIMap<Key, Type> & f, PIMap<Key, Type> & s) {
|
||||
f.swap(s);
|
||||
}
|
||||
|
||||
|
||||
#endif // PIMAP_H
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
template<typename Type0, typename Type1>
|
||||
class PIPair {
|
||||
public:
|
||||
|
||||
//! \~english Constructs an empty PIPair.
|
||||
//! \~russian Создает пустой PIPair.
|
||||
PIPair(): first(), second() {}
|
||||
|
||||
@@ -53,18 +53,23 @@
|
||||
template<typename T>
|
||||
class PIQueue: public PIDeque<T> {
|
||||
public:
|
||||
|
||||
//! \~english Constructs an empty array.
|
||||
//! \~russian Создает пустой массив.
|
||||
PIQueue() {}
|
||||
|
||||
//! \~english Puts an element on the queue.
|
||||
//! \~russian Кладёт элемент в очередь.
|
||||
PIDeque<T> & enqueue(const T & v) {PIDeque<T>::push_front(v); return *this;}
|
||||
PIDeque<T> & enqueue(const T & v) {
|
||||
PIDeque<T>::push_front(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Move an element on the queue.
|
||||
//! \~russian Перемещает элемент в очередь.
|
||||
PIDeque<T> & enqueue(T && v) {PIDeque<T>::push_front(std::move(v)); return *this;}
|
||||
PIDeque<T> & enqueue(T && v) {
|
||||
PIDeque<T>::push_front(std::move(v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Retrieves and returns an element from the queue.
|
||||
//! \~russian Забирает и возвращает элемент из очереди.
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
template<typename T>
|
||||
class PISet: public PIMap<T, uchar> {
|
||||
typedef PIMap<T, uchar> _CSet;
|
||||
public:
|
||||
|
||||
public:
|
||||
//! Contructs an empty set
|
||||
PISet() {}
|
||||
|
||||
@@ -46,13 +46,25 @@ public:
|
||||
PISet(const T & value) { _CSet::insert(value, 0); }
|
||||
|
||||
//! Contructs set with elements "v0" and "v1"
|
||||
PISet(const T & v0, const T & v1) {_CSet::insert(v0, 0); _CSet::insert(v1, 0);}
|
||||
PISet(const T & v0, const T & v1) {
|
||||
_CSet::insert(v0, 0);
|
||||
_CSet::insert(v1, 0);
|
||||
}
|
||||
|
||||
//! Contructs set with elements "v0", "v1" and "v2"
|
||||
PISet(const T & v0, const T & v1, const T & v2) {_CSet::insert(v0, 0); _CSet::insert(v1, 0); _CSet::insert(v2, 0);}
|
||||
PISet(const T & v0, const T & v1, const T & v2) {
|
||||
_CSet::insert(v0, 0);
|
||||
_CSet::insert(v1, 0);
|
||||
_CSet::insert(v2, 0);
|
||||
}
|
||||
|
||||
//! Contructs set with elements "v0", "v1", "v2" and "v3"
|
||||
PISet(const T & v0, const T & v1, const T & v2, const T & v3) {_CSet::insert(v0, 0); _CSet::insert(v1, 0); _CSet::insert(v2, 0); _CSet::insert(v3, 0);}
|
||||
PISet(const T & v0, const T & v1, const T & v2, const T & v3) {
|
||||
_CSet::insert(v0, 0);
|
||||
_CSet::insert(v1, 0);
|
||||
_CSet::insert(v2, 0);
|
||||
_CSet::insert(v3, 0);
|
||||
}
|
||||
|
||||
//! Contructs set from vector of elements
|
||||
PISet(const PIVector<T> & values) {
|
||||
@@ -72,15 +84,27 @@ public:
|
||||
|
||||
typedef T key_type;
|
||||
|
||||
PISet<T> & operator <<(const T & t) {_CSet::insert(t, 0); return *this;}
|
||||
PISet<T> & operator <<(T && t) {_CSet::insert(std::move(t), 0); return *this;}
|
||||
PISet<T> & operator <<(const PISet<T> & other) {(*(_CSet*)this) << *((_CSet*)&other); return *this;}
|
||||
PISet<T> & operator<<(const T & t) {
|
||||
_CSet::insert(t, 0);
|
||||
return *this;
|
||||
}
|
||||
PISet<T> & operator<<(T && t) {
|
||||
_CSet::insert(std::move(t), 0);
|
||||
return *this;
|
||||
}
|
||||
PISet<T> & operator<<(const PISet<T> & other) {
|
||||
(*(_CSet *)this) << *((_CSet *)&other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Returns if element "t" exists in this set
|
||||
bool operator[](const T & t) const { return _CSet::contains(t); }
|
||||
|
||||
//! Returns if element "t" exists in this set
|
||||
PISet<T> & remove(const T & t) {_CSet::remove(t); return *this;}
|
||||
PISet<T> & remove(const T & t) {
|
||||
_CSet::remove(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Unite set with "v"
|
||||
PISet<T> & unite(const PISet<T> & v) {
|
||||
@@ -119,25 +143,54 @@ public:
|
||||
PISet<T> & operator&=(const PISet<T> & v) { return intersect(v); }
|
||||
|
||||
//! Returns content of set as PIVector
|
||||
PIVector<T> toVector() const {PIVector<T> ret; for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i) ret << i.key(); return ret;}
|
||||
PIVector<T> toVector() const {
|
||||
PIVector<T> ret;
|
||||
for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i)
|
||||
ret << i.key();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! Returns content of set as PIDeque
|
||||
PIDeque<T> toDeque() const {PIDeque<T> ret; for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i) ret << i.key(); return ret;}
|
||||
|
||||
PIDeque<T> toDeque() const {
|
||||
PIDeque<T> ret;
|
||||
for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i)
|
||||
ret << i.key();
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! \relatesalso PISet \brief Returns unite of two sets
|
||||
template <typename T> PISet<T> operator +(const PISet<T> & v0, const PISet<T> & v1) {PISet<T> ret(v0); ret.unite(v1); return ret;}
|
||||
template<typename T>
|
||||
PISet<T> operator+(const PISet<T> & v0, const PISet<T> & v1) {
|
||||
PISet<T> ret(v0);
|
||||
ret.unite(v1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! \relatesalso PISet \brief Returns subtraction of two sets
|
||||
template <typename T> PISet<T> operator -(const PISet<T> & v0, const PISet<T> & v1) {PISet<T> ret(v0); ret.subtract(v1); return ret;}
|
||||
template<typename T>
|
||||
PISet<T> operator-(const PISet<T> & v0, const PISet<T> & v1) {
|
||||
PISet<T> ret(v0);
|
||||
ret.subtract(v1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! \relatesalso PISet \brief Returns unite of two sets
|
||||
template <typename T> PISet<T> operator |(const PISet<T> & v0, const PISet<T> & v1) {PISet<T> ret(v0); ret.unite(v1); return ret;}
|
||||
template<typename T>
|
||||
PISet<T> operator|(const PISet<T> & v0, const PISet<T> & v1) {
|
||||
PISet<T> ret(v0);
|
||||
ret.unite(v1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! \relatesalso PISet \brief Returns intersetion of two sets
|
||||
template <typename T> PISet<T> operator &(const PISet<T> & v0, const PISet<T> & v1) {PISet<T> ret(v0); ret.intersect(v1); return ret;}
|
||||
template<typename T>
|
||||
PISet<T> operator&(const PISet<T> & v0, const PISet<T> & v1) {
|
||||
PISet<T> ret(v0);
|
||||
ret.intersect(v1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
template<typename Type>
|
||||
@@ -147,8 +200,7 @@ inline PICout operator <<(PICout s, const PISet<Type> & v) {
|
||||
s << "{";
|
||||
bool first = true;
|
||||
for (typename PIMap<Type, uchar>::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||
if (!first)
|
||||
s << ", ";
|
||||
if (!first) s << ", ";
|
||||
first = false;
|
||||
s << i.key();
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
#ifndef PISTACK_H
|
||||
#define PISTACK_H
|
||||
|
||||
#include "pivector.h"
|
||||
#include "pideque.h"
|
||||
#include "pivector.h"
|
||||
|
||||
//! \addtogroup Containers
|
||||
//! \{
|
||||
@@ -53,18 +53,23 @@
|
||||
template<typename T>
|
||||
class PIStack: public PIVector<T> {
|
||||
public:
|
||||
|
||||
//! \~english Constructs an empty array.
|
||||
//! \~russian Создает пустой массив.
|
||||
PIStack() {}
|
||||
|
||||
//! \~english Puts an element on the stack.
|
||||
//! \~russian Кладёт элемент в стек.
|
||||
PIVector<T> & push(const T & v) {PIVector<T>::push_back(v); return *this;}
|
||||
PIVector<T> & push(const T & v) {
|
||||
PIVector<T>::push_back(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Move an element on the stack.
|
||||
//! \~russian Перемещает элемент в стек.
|
||||
PIVector<T> & push(T && v) {PIVector<T>::push_back(std::move(v)); return *this;}
|
||||
PIVector<T> & push(T && v) {
|
||||
PIVector<T>::push_back(std::move(v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Retrieves and returns an element from the stack.
|
||||
//! \~russian Забирает и возвращает элемент из стека.
|
||||
|
||||
@@ -127,9 +127,7 @@ public:
|
||||
|
||||
//! \~english Constructs an empty array.
|
||||
//! \~russian Создает пустой массив.
|
||||
inline PIVector() {
|
||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||
}
|
||||
inline PIVector() { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) }
|
||||
|
||||
//! \~english Contructs array from raw `data`.
|
||||
//! This constructor reserve `size` and copy from `data` pointer.
|
||||
@@ -225,10 +223,12 @@ public:
|
||||
|
||||
class iterator {
|
||||
friend class PIVector<T>;
|
||||
|
||||
private:
|
||||
inline iterator(PIVector<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
PIVector<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
@@ -285,9 +285,7 @@ public:
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const iterator & it1, const iterator & it2) {
|
||||
return it1.pos - it2.pos;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const iterator & it1, const iterator & it2) { return it1.pos - it2.pos; }
|
||||
|
||||
friend inline iterator operator+(size_t p, const iterator & it) { return it + p; }
|
||||
friend inline iterator operator+(const iterator & it, size_t p) {
|
||||
@@ -298,26 +296,20 @@ public:
|
||||
|
||||
inline bool operator==(const iterator & it) const { return (pos == it.pos); }
|
||||
inline bool operator!=(const iterator & it) const { return (pos != it.pos); }
|
||||
friend inline bool operator <(const iterator & it1, const iterator & it2) {
|
||||
return it1.pos < it2.pos;
|
||||
}
|
||||
friend inline bool operator <=(const iterator & it1, const iterator & it2) {
|
||||
return it1.pos <= it2.pos;
|
||||
}
|
||||
friend inline bool operator >(const iterator & it1, const iterator & it2) {
|
||||
return it1.pos > it2.pos;
|
||||
}
|
||||
friend inline bool operator >=(const iterator & it1, const iterator & it2) {
|
||||
return it1.pos >= it2.pos;
|
||||
}
|
||||
friend inline bool operator<(const iterator & it1, const iterator & it2) { return it1.pos < it2.pos; }
|
||||
friend inline bool operator<=(const iterator & it1, const iterator & it2) { return it1.pos <= it2.pos; }
|
||||
friend inline bool operator>(const iterator & it1, const iterator & it2) { return it1.pos > it2.pos; }
|
||||
friend inline bool operator>=(const iterator & it1, const iterator & it2) { return it1.pos >= it2.pos; }
|
||||
};
|
||||
|
||||
class const_iterator {
|
||||
friend class PIVector<T>;
|
||||
|
||||
private:
|
||||
inline const_iterator(const PIVector<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIVector<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
@@ -372,9 +364,7 @@ public:
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const const_iterator & it1, const const_iterator & it2) {
|
||||
return it1.pos - it2.pos;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const const_iterator & it1, const const_iterator & it2) { return it1.pos - it2.pos; }
|
||||
|
||||
friend inline const_iterator operator+(size_t p, const const_iterator & it) { return it + p; }
|
||||
friend inline const_iterator operator+(const const_iterator & it, size_t p) {
|
||||
@@ -385,26 +375,20 @@ public:
|
||||
|
||||
inline bool operator==(const const_iterator & it) const { return (pos == it.pos); }
|
||||
inline bool operator!=(const const_iterator & it) const { return (pos != it.pos); }
|
||||
friend inline bool operator <(const const_iterator & it1, const const_iterator & it2) {
|
||||
return it1.pos < it2.pos;
|
||||
}
|
||||
friend inline bool operator <=(const const_iterator & it1, const const_iterator & it2) {
|
||||
return it1.pos <= it2.pos;
|
||||
}
|
||||
friend inline bool operator >(const const_iterator & it1, const const_iterator & it2) {
|
||||
return it1.pos > it2.pos;
|
||||
}
|
||||
friend inline bool operator >=(const const_iterator & it1, const const_iterator & it2) {
|
||||
return it1.pos >= it2.pos;
|
||||
}
|
||||
friend inline bool operator<(const const_iterator & it1, const const_iterator & it2) { return it1.pos < it2.pos; }
|
||||
friend inline bool operator<=(const const_iterator & it1, const const_iterator & it2) { return it1.pos <= it2.pos; }
|
||||
friend inline bool operator>(const const_iterator & it1, const const_iterator & it2) { return it1.pos > it2.pos; }
|
||||
friend inline bool operator>=(const const_iterator & it1, const const_iterator & it2) { return it1.pos >= it2.pos; }
|
||||
};
|
||||
|
||||
class reverse_iterator {
|
||||
friend class PIVector<T>;
|
||||
|
||||
private:
|
||||
inline reverse_iterator(PIVector<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
PIVector<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
@@ -461,9 +445,7 @@ public:
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const reverse_iterator & it1, const reverse_iterator & it2) {
|
||||
return it2.pos - it1.pos;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const reverse_iterator & it1, const reverse_iterator & it2) { return it2.pos - it1.pos; }
|
||||
|
||||
friend inline reverse_iterator operator+(size_t p, const reverse_iterator & it) { return it + p; }
|
||||
friend inline reverse_iterator operator+(const reverse_iterator & it, size_t p) {
|
||||
@@ -474,26 +456,20 @@ public:
|
||||
|
||||
inline bool operator==(const reverse_iterator & it) const { return (pos == it.pos); }
|
||||
inline bool operator!=(const reverse_iterator & it) const { return (pos != it.pos); }
|
||||
friend inline bool operator <(const reverse_iterator & it1, const reverse_iterator & it2) {
|
||||
return it1.pos < it2.pos;
|
||||
}
|
||||
friend inline bool operator <=(const reverse_iterator & it1, const reverse_iterator & it2) {
|
||||
return it1.pos <= it2.pos;
|
||||
}
|
||||
friend inline bool operator >(const reverse_iterator & it1, const reverse_iterator & it2) {
|
||||
return it1.pos > it2.pos;
|
||||
}
|
||||
friend inline bool operator >=(const reverse_iterator & it1, const reverse_iterator & it2) {
|
||||
return it1.pos >= it2.pos;
|
||||
}
|
||||
friend inline bool operator<(const reverse_iterator & it1, const reverse_iterator & it2) { return it1.pos < it2.pos; }
|
||||
friend inline bool operator<=(const reverse_iterator & it1, const reverse_iterator & it2) { return it1.pos <= it2.pos; }
|
||||
friend inline bool operator>(const reverse_iterator & it1, const reverse_iterator & it2) { return it1.pos > it2.pos; }
|
||||
friend inline bool operator>=(const reverse_iterator & it1, const reverse_iterator & it2) { return it1.pos >= it2.pos; }
|
||||
};
|
||||
|
||||
class const_reverse_iterator {
|
||||
friend class PIVector<T>;
|
||||
|
||||
private:
|
||||
inline const_reverse_iterator(const PIVector<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIVector<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
@@ -560,18 +536,10 @@ public:
|
||||
|
||||
inline bool operator==(const const_reverse_iterator & it) const { return (pos == it.pos); }
|
||||
inline bool operator!=(const const_reverse_iterator & it) const { return (pos != it.pos); }
|
||||
friend inline bool operator <(const const_reverse_iterator & it1, const const_reverse_iterator & it2) {
|
||||
return it1.pos < it2.pos;
|
||||
}
|
||||
friend inline bool operator <=(const const_reverse_iterator & it1, const const_reverse_iterator & it2) {
|
||||
return it1.pos <= it2.pos;
|
||||
}
|
||||
friend inline bool operator >(const const_reverse_iterator & it1, const const_reverse_iterator & it2) {
|
||||
return it1.pos > it2.pos;
|
||||
}
|
||||
friend inline bool operator >=(const const_reverse_iterator & it1, const const_reverse_iterator & it2) {
|
||||
return it1.pos >= it2.pos;
|
||||
}
|
||||
friend inline bool operator<(const const_reverse_iterator & it1, const const_reverse_iterator & it2) { return it1.pos < it2.pos; }
|
||||
friend inline bool operator<=(const const_reverse_iterator & it1, const const_reverse_iterator & it2) { return it1.pos <= it2.pos; }
|
||||
friend inline bool operator>(const const_reverse_iterator & it1, const const_reverse_iterator & it2) { return it1.pos > it2.pos; }
|
||||
friend inline bool operator>=(const const_reverse_iterator & it1, const const_reverse_iterator & it2) { return it1.pos >= it2.pos; }
|
||||
};
|
||||
|
||||
//! \~english Iterator to the first element.
|
||||
@@ -758,8 +726,10 @@ public:
|
||||
//! \~\sa \a indexWhere()
|
||||
inline const T & atWhere(std::function<bool(const T & e)> test, ssize_t start = 0, const T & def = T()) const {
|
||||
ssize_t i = indexWhere(test, start);
|
||||
if (i < 0) return def;
|
||||
else return at(i);
|
||||
if (i < 0)
|
||||
return def;
|
||||
else
|
||||
return at(i);
|
||||
}
|
||||
|
||||
//! \~english Returns the last element of the array that
|
||||
@@ -770,8 +740,10 @@ public:
|
||||
//! \~\sa \a lastIndexWhere()
|
||||
inline const T & lastAtWhere(std::function<bool(const T & e)> test, ssize_t start = -1, const T & def = T()) const {
|
||||
ssize_t i = lastIndexWhere(test, start);
|
||||
if (i < 0) return def;
|
||||
else return at(i);
|
||||
if (i < 0)
|
||||
return def;
|
||||
else
|
||||
return at(i);
|
||||
}
|
||||
|
||||
//! \~english Last element.
|
||||
@@ -1172,17 +1144,13 @@ public:
|
||||
//! \~english Reserved memory will not be released.
|
||||
//! \~russian Зарезервированная память не освободится.
|
||||
//! \~\sa \a resize()
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector<T> & clear() {
|
||||
deleteT(piv_data, piv_size);
|
||||
piv_size = 0;
|
||||
return *this;
|
||||
}
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector<T> & clear() {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, piv_size)
|
||||
piv_size = 0;
|
||||
@@ -1233,16 +1201,12 @@ public:
|
||||
//! \~english First does `resize(new_size)` then `fill(e)`.
|
||||
//! \~russian Сначала делает `resize(new_size)`, затем `fill(e)`.
|
||||
//! \~\sa \a fill(), \a resize()
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector<T> & assign(size_t new_size, const T & f) {
|
||||
resize(new_size);
|
||||
return fill(f);
|
||||
}
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector<T> & assign(size_t new_size, const T & f) {
|
||||
_resizeRaw(new_size);
|
||||
return fill(f);
|
||||
@@ -1290,9 +1254,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector<T> & _resizeRaw(size_t new_size) {
|
||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
if (new_size > piv_size) {
|
||||
@@ -1306,9 +1268,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void _copyRaw(T * dst, const T * src, size_t size) {
|
||||
newT(dst, src, size);
|
||||
}
|
||||
inline void _copyRaw(T * dst, const T * src, size_t size) { newT(dst, src, size); }
|
||||
|
||||
//! \~english Attempts to allocate memory for at least `new_size` elements.
|
||||
//! \~russian Резервируется память под как минимум `new_size` элементов.
|
||||
@@ -1490,16 +1450,11 @@ public:
|
||||
//! Complexity `O(N·log(N))`.
|
||||
//! \~russian Сохранность порядка элементов, имеющих одинаковое значение, не гарантируется.
|
||||
//! Для сравнения элементов используется функция сравнения `comp`.
|
||||
//! Функция сравнения, возвращает `true` если первый аргумент меньше второго.
|
||||
//! Сигнатура функции сравнения должна быть эквивалентна следующей:
|
||||
//! \code
|
||||
//! bool comp(const T &a, const T &b);
|
||||
//! \endcode
|
||||
//! Сигнатура не обязана содержать const &, однако, функция не может изменять переданные объекты.
|
||||
//! Функция обязана возвращать `false` для одинаковых элементов,
|
||||
//! иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
//! Для сортировки используется функция [std::sort](https://ru.cppreference.com/w/cpp/algorithm/sort).
|
||||
//! Сложность сортировки `O(N·log(N))`.
|
||||
//! Функция сравнения, возвращает `true` если первый аргумент меньше
|
||||
//! второго. Сигнатура функции сравнения должна быть эквивалентна следующей: \code bool comp(const T &a, const T &b); \endcode Сигнатура
|
||||
//! не обязана содержать const &, однако, функция не может изменять переданные объекты. Функция обязана возвращать `false` для
|
||||
//! одинаковых элементов, иначе это приведёт к неопределённому поведению программы и ошибкам памяти. Для сортировки используется функция
|
||||
//! [std::sort](https://ru.cppreference.com/w/cpp/algorithm/sort). Сложность сортировки `O(N·log(N))`.
|
||||
//! \~\code
|
||||
//! PIVector<int> v{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
|
||||
//! v.sort([](const int & a, const int & b){return a > b;});
|
||||
@@ -1560,8 +1515,10 @@ public:
|
||||
//! \~\sa \a resize()
|
||||
inline PIVector<T> & enlarge(ssize_t add_size, const T & e = T()) {
|
||||
ssize_t ns = size_s() + add_size;
|
||||
if (ns <= 0) clear();
|
||||
else resize(size_t(ns), e);
|
||||
if (ns <= 0)
|
||||
clear();
|
||||
else
|
||||
resize(size_t(ns), e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1815,9 +1772,7 @@ public:
|
||||
//! piCout << v; // {5, 4, 1, 2, 3}
|
||||
//! \endcode
|
||||
//! \~\sa \a push_back(), \a append(), \a prepend(), \a insert()
|
||||
inline PIVector<T> & push_front(const T & e) {
|
||||
return insert(0, e);
|
||||
}
|
||||
inline PIVector<T> & push_front(const T & e) { return insert(0, e); }
|
||||
|
||||
//! \~english Appends the given element `e` to the begin of the array.
|
||||
//! \~russian Добавляет элемент `e` в начало массива.
|
||||
@@ -1825,9 +1780,7 @@ public:
|
||||
//! \~english Overloaded function.
|
||||
//! \~russian Перегруженая функция.
|
||||
//! \~\sa \a push_front()
|
||||
inline PIVector<T> & push_front(T && e) {
|
||||
return insert(0, std::move(e));
|
||||
}
|
||||
inline PIVector<T> & push_front(T && e) { return insert(0, std::move(e)); }
|
||||
|
||||
//! \~english Appends the given array `v` to the begin of the array.
|
||||
//! \~russian Добавляет массив `v` в начало массива.
|
||||
@@ -1840,9 +1793,7 @@ public:
|
||||
//! piCout << v; // {4, 5, 1, 2, 3}
|
||||
//! \endcode
|
||||
//! \~\sa \a push_front()
|
||||
inline PIVector<T> & push_front(const PIVector<T> & v) {
|
||||
return insert(0, v);
|
||||
}
|
||||
inline PIVector<T> & push_front(const PIVector<T> & v) { return insert(0, v); }
|
||||
|
||||
//! \~english Appends the given elements to the begin of the array.
|
||||
//! \~russian Добавляет элементы в начало массива.
|
||||
@@ -1854,9 +1805,7 @@ public:
|
||||
//! Добавляет элементы из
|
||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~\sa \a append()
|
||||
inline PIVector<T> & push_front(std::initializer_list<T> init_list) {
|
||||
return insert(0, init_list);
|
||||
}
|
||||
inline PIVector<T> & push_front(std::initializer_list<T> init_list) { return insert(0, init_list); }
|
||||
|
||||
//! \~english Appends the given element `e` to the begin of the array.
|
||||
//! \~russian Добавляет элемент `e` в начало массива.
|
||||
@@ -2167,7 +2116,8 @@ public:
|
||||
//! \~\sa \a forEach(), \a reduce()
|
||||
template<typename ST>
|
||||
inline PIVector<ST> map(std::function<ST(const T & e)> f) const {
|
||||
PIVector<ST> ret; ret.reserve(piv_size);
|
||||
PIVector<ST> ret;
|
||||
ret.reserve(piv_size);
|
||||
for (size_t i = 0; i < piv_size; ++i) {
|
||||
ret << f(piv_data[i]);
|
||||
}
|
||||
@@ -2184,7 +2134,8 @@ public:
|
||||
//! \~\sa \a map()
|
||||
template<typename ST>
|
||||
inline PIVector<ST> mapIndexed(std::function<ST(size_t index, const T & e)> f) const {
|
||||
PIVector<ST> ret; ret.reserve(piv_size);
|
||||
PIVector<ST> ret;
|
||||
ret.reserve(piv_size);
|
||||
for (size_t i = 0; i < piv_size; ++i) {
|
||||
ret << f(i, piv_data[i]);
|
||||
}
|
||||
@@ -2201,7 +2152,8 @@ public:
|
||||
//! \~\sa \a map()
|
||||
template<typename ST>
|
||||
inline PIVector<ST> mapReverse(std::function<ST(const T & e)> f) const {
|
||||
PIVector<ST> ret; ret.reserve(piv_size);
|
||||
PIVector<ST> ret;
|
||||
ret.reserve(piv_size);
|
||||
for (ssize_t i = piv_size; i >= 0; --i) {
|
||||
ret << f(piv_data[i]);
|
||||
}
|
||||
@@ -2218,7 +2170,8 @@ public:
|
||||
//! \~\sa \a mapReverse()
|
||||
template<typename ST>
|
||||
inline PIVector<ST> mapReverseIndexed(std::function<ST(size_t index, const T & e)> f) const {
|
||||
PIVector<ST> ret; ret.reserve(piv_size);
|
||||
PIVector<ST> ret;
|
||||
ret.reserve(piv_size);
|
||||
for (ssize_t i = piv_size; i >= 0; --i) {
|
||||
ret << f(i, piv_data[i]);
|
||||
}
|
||||
@@ -2370,9 +2323,7 @@ public:
|
||||
//! piCout << xv.flatten<int>(); // {1, 2, 3, 4, 5, 6}
|
||||
//! \endcode
|
||||
//! \~\sa \a map(), \a reduce(), \a reshape()
|
||||
template<typename C, typename std::enable_if<
|
||||
std::is_same<T, PIVector<C>>::value
|
||||
, int>::type = 0>
|
||||
template<typename C, typename std::enable_if<std::is_same<T, PIVector<C>>::value, int>::type = 0>
|
||||
inline PIVector<C> flatten(ReshapeOrder order = ReshapeByRow) const {
|
||||
PIVector<C> ret;
|
||||
if (isEmpty()) return ret;
|
||||
@@ -2413,9 +2364,7 @@ public:
|
||||
//! piCout << xv.reshape<int>(2,3); // {{1, 2, 3}, {4, 5, 6}}
|
||||
//! \endcode
|
||||
//! \~\sa \a map(), \a reduce(), \a reshape()
|
||||
template<typename C, typename std::enable_if<
|
||||
std::is_same<T, PIVector<C>>::value
|
||||
, int>::type = 0>
|
||||
template<typename C, typename std::enable_if<std::is_same<T, PIVector<C>>::value, int>::type = 0>
|
||||
inline PIVector<PIVector<C>> reshape(size_t rows, size_t cols, ReshapeOrder order = ReshapeByRow) const {
|
||||
PIVector<C> fl = flatten<C>();
|
||||
return fl.reshape(rows, cols, order);
|
||||
@@ -2506,13 +2455,12 @@ private:
|
||||
return piv_rsize * 2;
|
||||
}
|
||||
ssize_t t = _PIContainerConstants<T>::minCountPoT(), s_ = s - 1;
|
||||
while (s_ >> t) ++t;
|
||||
while (s_ >> t)
|
||||
++t;
|
||||
return (1 << t);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void newT(T * dst, const T * src, size_t s) {
|
||||
PIINTROSPECTION_CONTAINER_USED(T, s)
|
||||
for (size_t i = 0; i < s; ++i) {
|
||||
@@ -2520,17 +2468,13 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void newT(T * dst, const T * src, size_t s) {
|
||||
PIINTROSPECTION_CONTAINER_USED(T, s)
|
||||
memcpy((void *)(dst), (const void *)(src), s * sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void deleteT(T * d, size_t sz) {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
|
||||
if (d != nullptr) {
|
||||
@@ -2540,51 +2484,37 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void deleteT(T * d, size_t sz) {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T * to, const T & from) {
|
||||
new (to) T(from);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T * to, T && from) {
|
||||
new (to) T(std::move(from));
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T1 * to, const T & from) {
|
||||
(*to) = from;
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T * to, T && from) {
|
||||
(*to) = std::move(from);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementDelete(T & from) {
|
||||
from.~T();
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementDelete(T & from) {}
|
||||
|
||||
inline void dealloc() {
|
||||
@@ -2673,6 +2603,8 @@ inline PICout operator <<(PICout s, const PIVector<T> & v) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void piSwap(PIVector<T> & f, PIVector<T> & s) {f.swap(s);}
|
||||
inline void piSwap(PIVector<T> & f, PIVector<T> & s) {
|
||||
f.swap(s);
|
||||
}
|
||||
|
||||
#endif // PIVECTOR_H
|
||||
|
||||
@@ -46,13 +46,9 @@ public:
|
||||
mat.resize(rows * cols, f);
|
||||
}
|
||||
|
||||
inline PIVector2D(size_t rows, size_t cols, const PIVector<T> & v) : rows_(rows), cols_(cols), mat(v) {
|
||||
mat.resize(rows*cols);
|
||||
}
|
||||
inline PIVector2D(size_t rows, size_t cols, const PIVector<T> & v): rows_(rows), cols_(cols), mat(v) { mat.resize(rows * cols); }
|
||||
|
||||
inline PIVector2D(size_t rows, size_t cols, PIVector<T> && v) : rows_(rows), cols_(cols), mat(std::move(v)) {
|
||||
mat.resize(rows*cols);
|
||||
}
|
||||
inline PIVector2D(size_t rows, size_t cols, PIVector<T> && v): rows_(rows), cols_(cols), mat(std::move(v)) { mat.resize(rows * cols); }
|
||||
|
||||
inline PIVector2D(const PIVector<PIVector<T>> & v) {
|
||||
rows_ = v.size();
|
||||
@@ -85,10 +81,15 @@ public:
|
||||
|
||||
class Row {
|
||||
friend class PIVector2D<T>;
|
||||
|
||||
private:
|
||||
inline Row(PIVector2D<T> * p, size_t row) : p_(&(p->mat)) {st_ = p->cols_ * row; sz_ = p->cols_;}
|
||||
inline Row(PIVector2D<T> * p, size_t row): p_(&(p->mat)) {
|
||||
st_ = p->cols_ * row;
|
||||
sz_ = p->cols_;
|
||||
}
|
||||
PIVector<T> * p_;
|
||||
size_t st_, sz_;
|
||||
|
||||
public:
|
||||
inline size_t size() const { return sz_; }
|
||||
inline T & operator[](size_t index) { return (*p_)[st_ + index]; }
|
||||
@@ -111,10 +112,16 @@ public:
|
||||
|
||||
class Col {
|
||||
friend class PIVector2D<T>;
|
||||
|
||||
private:
|
||||
inline Col(PIVector2D<T> * p, size_t row) : p_(&(p->mat)) {step_ = p->cols_; row_ = row; sz_ = p->rows_;}
|
||||
inline Col(PIVector2D<T> * p, size_t row): p_(&(p->mat)) {
|
||||
step_ = p->cols_;
|
||||
row_ = row;
|
||||
sz_ = p->rows_;
|
||||
}
|
||||
PIVector<T> * p_;
|
||||
size_t step_, row_, sz_;
|
||||
|
||||
public:
|
||||
inline size_t size() const { return sz_; }
|
||||
inline T & operator[](size_t index) { return (*p_)[index * step_ + row_]; }
|
||||
@@ -124,28 +131,36 @@ public:
|
||||
inline Col & operator=(const Col & other) {
|
||||
if (p_ == other.p_ && row_ == other.row_) return *this;
|
||||
size_t sz = piMin<size_t>(sz_, other.sz_);
|
||||
for (int i=0; i<sz; ++i) (*p_)[i * step_ + row_] = other[i];
|
||||
for (int i = 0; i < sz; ++i)
|
||||
(*p_)[i * step_ + row_] = other[i];
|
||||
return *this;
|
||||
}
|
||||
inline Row & operator=(const PIVector<T> & other) {
|
||||
size_t sz = piMin<size_t>(sz_, other.size());
|
||||
for (int i=0; i<sz; ++i) (*p_)[i * step_ + row_] = other[i];
|
||||
for (int i = 0; i < sz; ++i)
|
||||
(*p_)[i * step_ + row_] = other[i];
|
||||
return *this;
|
||||
}
|
||||
inline PIVector<T> toVector() const {
|
||||
PIVector<T> ret;
|
||||
ret.reserve(sz_);
|
||||
for (size_t i=0; i<sz_; i++) ret << (*p_)[i * step_ + row_];
|
||||
for (size_t i = 0; i < sz_; i++)
|
||||
ret << (*p_)[i * step_ + row_];
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
class RowConst {
|
||||
friend class PIVector2D<T>;
|
||||
|
||||
private:
|
||||
inline RowConst(const PIVector2D<T> * p, size_t row) : p_(&(p->mat)) {st_ = p->cols_ * row; sz_ = p->cols_;}
|
||||
inline RowConst(const PIVector2D<T> * p, size_t row): p_(&(p->mat)) {
|
||||
st_ = p->cols_ * row;
|
||||
sz_ = p->cols_;
|
||||
}
|
||||
const PIVector<T> * p_;
|
||||
size_t st_, sz_;
|
||||
|
||||
public:
|
||||
inline size_t size() const { return sz_; }
|
||||
inline const T & operator[](size_t index) const { return (*p_)[st_ + index]; }
|
||||
@@ -155,10 +170,16 @@ public:
|
||||
|
||||
class ColConst {
|
||||
friend class PIVector2D<T>;
|
||||
|
||||
private:
|
||||
inline ColConst(const PIVector2D<T> * p, size_t row) : p_(&(p->mat)) {step_ = p->cols_; row_ = row; sz_ = p->rows_;}
|
||||
inline ColConst(const PIVector2D<T> * p, size_t row): p_(&(p->mat)) {
|
||||
step_ = p->cols_;
|
||||
row_ = row;
|
||||
sz_ = p->rows_;
|
||||
}
|
||||
const PIVector<T> * p_;
|
||||
size_t step_, row_, sz_;
|
||||
|
||||
public:
|
||||
inline size_t size() const { return p_->rows_; }
|
||||
inline const T & operator[](size_t index) const { return (*p_)[index * step_ + row_]; }
|
||||
@@ -166,7 +187,8 @@ public:
|
||||
inline PIVector<T> toVector() const {
|
||||
PIVector<T> ret;
|
||||
ret.reserve(sz_);
|
||||
for (int i=0; i<size(); i++) ret << (*p_)[i * step_ + row_];
|
||||
for (int i = 0; i < size(); i++)
|
||||
ret << (*p_)[i * step_ + row_];
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
@@ -249,8 +271,7 @@ public:
|
||||
}
|
||||
|
||||
inline bool operator==(const PIVector2D<T> & t) const {
|
||||
if (cols_ != t.cols_ || rows_ != t.rows_)
|
||||
return false;
|
||||
if (cols_ != t.cols_ || rows_ != t.rows_) return false;
|
||||
return mat == t.mat;
|
||||
}
|
||||
inline bool operator!=(const PIVector2D<T> & t) const { return !(*this == t); }
|
||||
@@ -275,9 +296,7 @@ public:
|
||||
piSwap<size_t>(cols_, other.cols_);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector2D<T> & _resizeRaw(size_t r, size_t c) {
|
||||
rows_ = r;
|
||||
cols_ = c;
|
||||
@@ -295,9 +314,7 @@ public:
|
||||
return PIVector2D<ST>(rows_, cols_, mat.map(f));
|
||||
}
|
||||
|
||||
inline void forEach(std::function<void(const T &)> f) const {
|
||||
mat.forEach(f);
|
||||
}
|
||||
inline void forEach(std::function<void(const T &)> f) const { mat.forEach(f); }
|
||||
|
||||
inline PIVector2D<T> & forEach(std::function<void(T &)> f) {
|
||||
mat.forEach(f);
|
||||
|
||||
@@ -34,10 +34,11 @@
|
||||
#ifndef PIBASE_H
|
||||
#define PIBASE_H
|
||||
|
||||
#include "pip_defs.h"
|
||||
#include "pip_export.h"
|
||||
#include "pip_version.h"
|
||||
#include "piplatform.h"
|
||||
#include "pip_export.h"
|
||||
#include "pip_defs.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
//! \~english
|
||||
@@ -211,11 +212,11 @@
|
||||
#ifdef CC_AVR_GCC
|
||||
# include <ArduinoSTL.h>
|
||||
#endif
|
||||
#include <functional>
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
|
||||
#ifdef WINDOWS
|
||||
# ifdef CC_VC
|
||||
@@ -347,15 +348,25 @@
|
||||
}; \
|
||||
__PrivateInitializer__ __privateinitializer__;
|
||||
|
||||
#define PRIVATE_DEFINITION_START(c) \
|
||||
struct c::__Private__ {
|
||||
|
||||
# define PRIVATE_DEFINITION_START(c) struct c::__Private__ {
|
||||
# define PRIVATE_DEFINITION_END(c) \
|
||||
}; \
|
||||
c::__PrivateInitializer__::__PrivateInitializer__() {p = new c::__Private__();} \
|
||||
c::__PrivateInitializer__::__PrivateInitializer__(const c::__PrivateInitializer__ & ) {/*if (p) delete p;*/ p = new c::__Private__();} \
|
||||
c::__PrivateInitializer__::~__PrivateInitializer__() {delete p; p = 0;} \
|
||||
c::__PrivateInitializer__ & c::__PrivateInitializer__::operator =(const c::__PrivateInitializer__ & ) {if (p) delete p; p = new c::__Private__(); return *this;}
|
||||
} \
|
||||
; \
|
||||
c::__PrivateInitializer__::__PrivateInitializer__() { \
|
||||
p = new c::__Private__(); \
|
||||
} \
|
||||
c::__PrivateInitializer__::__PrivateInitializer__(const c::__PrivateInitializer__ &) { /*if (p) delete p;*/ \
|
||||
p = new c::__Private__(); \
|
||||
} \
|
||||
c::__PrivateInitializer__::~__PrivateInitializer__() { \
|
||||
delete p; \
|
||||
p = 0; \
|
||||
} \
|
||||
c::__PrivateInitializer__ & c::__PrivateInitializer__::operator=(const c::__PrivateInitializer__ &) { \
|
||||
if (p) delete p; \
|
||||
p = new c::__Private__(); \
|
||||
return *this; \
|
||||
}
|
||||
|
||||
# define PRIVATE (__privateinitializer__.p)
|
||||
# define PRIVATEWB __privateinitializer__.p
|
||||
@@ -377,11 +388,12 @@
|
||||
class _Initializer_ { \
|
||||
public: \
|
||||
_Initializer_() {
|
||||
|
||||
#define STATIC_INITIALIZER_END \
|
||||
} \
|
||||
} _initializer_; \
|
||||
} _PIP_ADD_COUNTER(_pip_initializer_);
|
||||
} \
|
||||
_initializer_; \
|
||||
} \
|
||||
_PIP_ADD_COUNTER(_pip_initializer_);
|
||||
|
||||
|
||||
//! \~\brief
|
||||
@@ -441,7 +453,12 @@ typedef long double ldouble;
|
||||
//! \~\details
|
||||
//! \~english Example:\n \snippet piincludes.cpp swap
|
||||
//! \~russian Пример:\n \snippet piincludes.cpp swap
|
||||
template<typename T> inline void piSwap(T & f, T & s) {T t(std::move(f)); f = std::move(s); s = std::move(t);}
|
||||
template<typename T>
|
||||
inline void piSwap(T & f, T & s) {
|
||||
T t(std::move(f));
|
||||
f = std::move(s);
|
||||
s = std::move(t);
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Templated function for swap two values without "="
|
||||
@@ -449,7 +466,8 @@ template<typename T> inline void piSwap(T & f, T & s) {T t(std::move(f)); f = st
|
||||
//! \~\details
|
||||
//! \~english Example:\n \snippet piincludes.cpp swapBinary
|
||||
//! \~russian Пример:\n \snippet piincludes.cpp swapBinary
|
||||
template<typename T> inline void piSwapBinary(T & f, T & s) {
|
||||
template<typename T>
|
||||
inline void piSwapBinary(T & f, T & s) {
|
||||
if ((size_t *)&f == (size_t *)&s) return;
|
||||
size_t j = (sizeof(T) / sizeof(size_t)), bs = j * sizeof(size_t), bf = sizeof(T);
|
||||
size_t i = 0;
|
||||
@@ -465,7 +483,8 @@ template<typename T> inline void piSwapBinary(T & f, T & s) {
|
||||
}
|
||||
}
|
||||
|
||||
template<> inline void piSwapBinary(const void *& f, const void *& s) {
|
||||
template<>
|
||||
inline void piSwapBinary(const void *& f, const void *& s) {
|
||||
if ((size_t *)f == (size_t *)s) return;
|
||||
size_t j = (sizeof(void *) / sizeof(size_t)), bs = j * sizeof(size_t), bf = sizeof(void *);
|
||||
size_t i = 0;
|
||||
@@ -491,8 +510,7 @@ template<> inline void piSwapBinary(const void *& f, const void *& s) {
|
||||
//! \~russian Пример:\n \snippet piincludes.cpp compareBinary
|
||||
inline bool piCompareBinary(const void * f, const void * s, size_t size) {
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
if (((const uchar*)f)[i] != ((const uchar*)s)[i])
|
||||
return false;
|
||||
if (((const uchar *)f)[i] != ((const uchar *)s)[i]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -516,7 +534,10 @@ inline bool piCompareBinary(const void * f, const void * s, size_t size) {
|
||||
//!
|
||||
//! Пример:
|
||||
//! \snippet piincludes.cpp round
|
||||
template<typename T> inline constexpr int piRound(const T & v) {return int(v >= T(0.) ? v + T(0.5) : v - T(0.5));}
|
||||
template<typename T>
|
||||
inline constexpr int piRound(const T & v) {
|
||||
return int(v >= T(0.) ? v + T(0.5) : v - T(0.5));
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Templated function return floor of float falue
|
||||
@@ -538,7 +559,10 @@ template<typename T> inline constexpr int piRound(const T & v) {return int(v >=
|
||||
//!
|
||||
//! Пример:
|
||||
//! \snippet piincludes.cpp floor
|
||||
template<typename T> inline constexpr int piFloor(const T & v) {return v < T(0) ? int(v) - 1 : int(v);}
|
||||
template<typename T>
|
||||
inline constexpr int piFloor(const T & v) {
|
||||
return v < T(0) ? int(v) - 1 : int(v);
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Templated function return ceil of float falue
|
||||
@@ -560,7 +584,10 @@ template<typename T> inline constexpr int piFloor(const T & v) {return v < T(0)
|
||||
//!
|
||||
//! Пример:
|
||||
//! \snippet piincludes.cpp ceil
|
||||
template<typename T> inline constexpr int piCeil(const T & v) {return v < T(0) ? int(v) : int(v) + 1;}
|
||||
template<typename T>
|
||||
inline constexpr int piCeil(const T & v) {
|
||||
return v < T(0) ? int(v) : int(v) + 1;
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Templated function return absolute of numeric falue
|
||||
@@ -590,7 +617,10 @@ template<typename T> inline constexpr int piCeil(const T & v) {return v < T(0) ?
|
||||
//!
|
||||
//! Пример:
|
||||
//! \snippet piincludes.cpp abs
|
||||
template<typename T> inline constexpr T piAbs(const T & v) {return (v >= T(0) ? v : -v);}
|
||||
template<typename T>
|
||||
inline constexpr T piAbs(const T & v) {
|
||||
return (v >= T(0) ? v : -v);
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Templated function return minimum of two values
|
||||
@@ -618,7 +648,10 @@ template<typename T> inline constexpr T piAbs(const T & v) {return (v >= T(0) ?
|
||||
//!
|
||||
//! Пример:
|
||||
//! \snippet piincludes.cpp min2
|
||||
template<typename T> inline constexpr T piMin(const T & f, const T & s) {return ((f > s) ? s : f);}
|
||||
template<typename T>
|
||||
inline constexpr T piMin(const T & f, const T & s) {
|
||||
return ((f > s) ? s : f);
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Templated function return minimum of tree values
|
||||
@@ -646,7 +679,10 @@ template<typename T> inline constexpr T piMin(const T & f, const T & s) {return
|
||||
//!
|
||||
//! Пример:
|
||||
//! \snippet piincludes.cpp min3
|
||||
template<typename T> inline constexpr 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 constexpr T piMin(const T & f, const T & s, const T & t) {
|
||||
return ((f < s && f < t) ? f : ((s < t) ? s : t));
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Templated function return maximum of two values
|
||||
@@ -674,7 +710,10 @@ template<typename T> inline constexpr T piMin(const T & f, const T & s, const T
|
||||
//!
|
||||
//! Пример:
|
||||
//! \snippet piincludes.cpp max2
|
||||
template<typename T> inline constexpr T piMax(const T & f, const T & s) {return ((f < s) ? s : f);}
|
||||
template<typename T>
|
||||
inline constexpr T piMax(const T & f, const T & s) {
|
||||
return ((f < s) ? s : f);
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Templated function return maximum of tree values
|
||||
@@ -702,7 +741,10 @@ template<typename T> inline constexpr T piMax(const T & f, const T & s) {return
|
||||
//!
|
||||
//! Пример:
|
||||
//! \snippet piincludes.cpp max3
|
||||
template<typename T> inline constexpr 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 constexpr T piMax(const T & f, const T & s, const T & t) {
|
||||
return ((f > s && f > t) ? f : ((s > t) ? s : t));
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Templated function return clamped value
|
||||
@@ -732,7 +774,10 @@ template<typename T> inline constexpr T piMax(const T & f, const T & s, const T
|
||||
//!
|
||||
//! Пример:
|
||||
//! \snippet piincludes.cpp clamp
|
||||
template<typename T> inline constexpr T piClamp(const T & v, const T & min, const T & max) {return (v > max ? max : (v < min ? min : v));}
|
||||
template<typename T>
|
||||
inline constexpr T piClamp(const T & v, const T & min, const T & max) {
|
||||
return (v > max ? max : (v < min ? min : v));
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Function inverse byte order in memory block ([1..N] -> [N..1])
|
||||
@@ -768,7 +813,10 @@ inline bool piCompare(const T & a, const T & b, const T & epsilon = std::numeric
|
||||
//! \~\brief
|
||||
//! \~english Templated function that inverse byte order of value "v"
|
||||
//! \~russian Шаблонный метод, меняющий порядок байт в переменной "v"
|
||||
template<typename T> inline void piLetobe(T * v) {piLetobe(v, sizeof(T));}
|
||||
template<typename T>
|
||||
inline void piLetobe(T * v) {
|
||||
piLetobe(v, sizeof(T));
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english Templated function that returns "v" with inversed byte order
|
||||
@@ -794,12 +842,24 @@ template<typename T> inline void piLetobe(T * v) {piLetobe(v, sizeof(T));}
|
||||
//!
|
||||
//! Пример:
|
||||
//! \snippet piincludes.cpp letobe
|
||||
template<typename T> inline T piLetobe(const T & v) {T tv(v); piLetobe(&tv, sizeof(T)); return tv;}
|
||||
template<typename T>
|
||||
inline T piLetobe(const T & v) {
|
||||
T tv(v);
|
||||
piLetobe(&tv, sizeof(T));
|
||||
return tv;
|
||||
}
|
||||
|
||||
// specialization
|
||||
template<> inline uint16_t piLetobe(const uint16_t & v) {return (v << 8) | (v >> 8);}
|
||||
template<> inline uint32_t piLetobe(const uint32_t & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
|
||||
template<> inline float piLetobe(const float & v) {
|
||||
template<>
|
||||
inline uint16_t piLetobe(const uint16_t & v) {
|
||||
return (v << 8) | (v >> 8);
|
||||
}
|
||||
template<>
|
||||
inline uint32_t piLetobe(const uint32_t & v) {
|
||||
return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);
|
||||
}
|
||||
template<>
|
||||
inline float piLetobe(const float & v) {
|
||||
union _pletobe_f {
|
||||
_pletobe_f(const float & f_) { f = f_; }
|
||||
float f;
|
||||
@@ -852,27 +912,63 @@ inline uint piHashData(const uchar * data, uint len, uint seed = 0) {
|
||||
}
|
||||
|
||||
|
||||
template<typename T> inline uint piHash(const T & v) {
|
||||
template<typename T>
|
||||
inline uint piHash(const T & v) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<> inline uint piHash(const char & v) {return (uint)v;}
|
||||
template<> inline uint piHash(const uchar & v) {return (uint)v;}
|
||||
template<> inline uint piHash(const short & v) {return (uint)v;}
|
||||
template<> inline uint piHash(const ushort & v) {return (uint)v;}
|
||||
template<> inline uint piHash(const int & v) {return (uint)v;}
|
||||
template<> inline uint piHash(const uint & v) {return (uint)v;}
|
||||
template<> inline uint piHash(const llong & v) {return piHashData((const uchar *)&v, sizeof(v));}
|
||||
template<> inline uint piHash(const ullong & v) {return piHashData((const uchar *)&v, sizeof(v));}
|
||||
template<> inline uint piHash(const float & v) {return (uint)v;}
|
||||
template<> inline uint piHash(const double & v) {return piHashData((const uchar *)&v, sizeof(v));}
|
||||
template<> inline uint piHash(const ldouble & v) {return piHashData((const uchar *)&v, sizeof(v));}
|
||||
template<>
|
||||
inline uint piHash(const char & v) {
|
||||
return (uint)v;
|
||||
}
|
||||
template<>
|
||||
inline uint piHash(const uchar & v) {
|
||||
return (uint)v;
|
||||
}
|
||||
template<>
|
||||
inline uint piHash(const short & v) {
|
||||
return (uint)v;
|
||||
}
|
||||
template<>
|
||||
inline uint piHash(const ushort & v) {
|
||||
return (uint)v;
|
||||
}
|
||||
template<>
|
||||
inline uint piHash(const int & v) {
|
||||
return (uint)v;
|
||||
}
|
||||
template<>
|
||||
inline uint piHash(const uint & v) {
|
||||
return (uint)v;
|
||||
}
|
||||
template<>
|
||||
inline uint piHash(const llong & v) {
|
||||
return piHashData((const uchar *)&v, sizeof(v));
|
||||
}
|
||||
template<>
|
||||
inline uint piHash(const ullong & v) {
|
||||
return piHashData((const uchar *)&v, sizeof(v));
|
||||
}
|
||||
template<>
|
||||
inline uint piHash(const float & v) {
|
||||
return (uint)v;
|
||||
}
|
||||
template<>
|
||||
inline uint piHash(const double & v) {
|
||||
return piHashData((const uchar *)&v, sizeof(v));
|
||||
}
|
||||
template<>
|
||||
inline uint piHash(const ldouble & v) {
|
||||
return piHashData((const uchar *)&v, sizeof(v));
|
||||
}
|
||||
|
||||
template<typename T> inline void piDeleteAll(T & container) {
|
||||
template<typename T>
|
||||
inline void piDeleteAll(T & container) {
|
||||
for (auto i: container)
|
||||
delete i;
|
||||
}
|
||||
template<typename T> inline void piDeleteAllAndClear(T & container) {
|
||||
template<typename T>
|
||||
inline void piDeleteAllAndClear(T & container) {
|
||||
piDeleteAll(container);
|
||||
container.clear();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "picli.h"
|
||||
|
||||
#include "pisysteminfo.h"
|
||||
|
||||
|
||||
@@ -75,8 +76,7 @@ PICLI::PICLI(int argc, char * argv[]) {
|
||||
_count_mand = 0;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
_args_raw << argv[i];
|
||||
if (argc > 0)
|
||||
PISystemInfo::instance()->execCommand = argv[0];
|
||||
if (argc > 0) PISystemInfo::instance()->execCommand = argv[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,17 +26,15 @@
|
||||
#ifndef PICLI_H
|
||||
#define PICLI_H
|
||||
|
||||
#include "pistringlist.h"
|
||||
#include "piset.h"
|
||||
#include "pistringlist.h"
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Command-Line parser.
|
||||
//! \~russian Парсер командной строки.
|
||||
class PIP_EXPORT PICLI
|
||||
{
|
||||
class PIP_EXPORT PICLI {
|
||||
public:
|
||||
|
||||
//! \~english Constructs %PICLI from "argc" and "argv" from "int main()" method.
|
||||
//! \~russian Создает %PICLI из "argc" и "argv" из метода "int main()".
|
||||
PICLI(int argc, char * argv[]);
|
||||
@@ -44,65 +42,131 @@ public:
|
||||
|
||||
//! \~english Add argument with name "name", short key = name first letter and full key = name.
|
||||
//! \~russian Добавляет аргумент с именем "name", коротким ключом = первой букве имени и полным ключом = имени.
|
||||
void addArgument(const PIString & name, bool value = false) {_args << Argument(name, name[0], name, value); needParse = true;}
|
||||
void addArgument(const PIString & name, bool value = false) {
|
||||
_args << Argument(name, name[0], name, value);
|
||||
needParse = true;
|
||||
}
|
||||
|
||||
//! \~english Add argument with name "name", short key = "shortKey" and full key = name.
|
||||
//! \~russian Добавляет аргумент с именем "name", коротким ключом = "shortKey" и полным ключом = имени.
|
||||
void addArgument(const PIString & name, const PIChar & shortKey, bool value = false) {_args << Argument(name, shortKey, name, value); needParse = true;}
|
||||
void addArgument(const PIString & name, const PIChar & shortKey, bool value = false) {
|
||||
_args << Argument(name, shortKey, name, value);
|
||||
needParse = true;
|
||||
}
|
||||
|
||||
//! \~english Add argument with name "name", short key = "shortKey" and full key = name.
|
||||
//! \~russian Добавляет аргумент с именем "name", коротким ключом = "shortKey" и полным ключом = имени.
|
||||
void addArgument(const PIString & name, const char * shortKey, bool value = false) {_args << Argument(name, PIChar(shortKey), name, value); needParse = true;}
|
||||
void addArgument(const PIString & name, const char * shortKey, bool value = false) {
|
||||
_args << Argument(name, PIChar(shortKey), name, value);
|
||||
needParse = true;
|
||||
}
|
||||
|
||||
//! \~english Add argument with name "name", short key = "shortKey" and full key = "fullKey".
|
||||
//! \~russian Добавляет аргумент с именем "name", коротким ключом = "shortKey" и полным ключом = "fullKey".
|
||||
void addArgument(const PIString & name, const PIChar & shortKey, const PIString & fullKey, bool value = false) {_args << Argument(name, shortKey, fullKey, value); needParse = true;}
|
||||
void addArgument(const PIString & name, const PIChar & shortKey, const PIString & fullKey, bool value = false) {
|
||||
_args << Argument(name, shortKey, fullKey, value);
|
||||
needParse = true;
|
||||
}
|
||||
|
||||
//! \~english Add argument with name "name", short key = "shortKey" and full key = "fullKey".
|
||||
//! \~russian Добавляет аргумент с именем "name", коротким ключом = "shortKey" и полным ключом = "fullKey".
|
||||
void addArgument(const PIString & name, const char * shortKey, const PIString & fullKey, bool value = false) {_args << Argument(name, PIChar(shortKey), fullKey, value); needParse = true;}
|
||||
void addArgument(const PIString & name, const char * shortKey, const PIString & fullKey, bool value = false) {
|
||||
_args << Argument(name, PIChar(shortKey), fullKey, value);
|
||||
needParse = true;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Returns unparsed command-line argument by index "index". Index 0 is program execute command.
|
||||
//! \~russian Возвращает исходный аргумент командной строки по индексу "index". Индекс 0 это команда вызова программы.
|
||||
PIString rawArgument(int index) {parse(); return _args_raw[index];}
|
||||
PIString mandatoryArgument(int index) {parse(); return _args_mand[index];}
|
||||
PIString optionalArgument(int index) {parse(); return _args_opt[index];}
|
||||
PIString rawArgument(int index) {
|
||||
parse();
|
||||
return _args_raw[index];
|
||||
}
|
||||
PIString mandatoryArgument(int index) {
|
||||
parse();
|
||||
return _args_mand[index];
|
||||
}
|
||||
PIString optionalArgument(int index) {
|
||||
parse();
|
||||
return _args_opt[index];
|
||||
}
|
||||
|
||||
//! \~english Returns unparsed command-line arguments.
|
||||
//! \~russian Возвращает исходные аргументы командной строки.
|
||||
const PIStringList & rawArguments() {parse(); return _args_raw;}
|
||||
const PIStringList & mandatoryArguments() {parse(); return _args_mand;}
|
||||
const PIStringList & optionalArguments() {parse(); return _args_opt;}
|
||||
const PIStringList & rawArguments() {
|
||||
parse();
|
||||
return _args_raw;
|
||||
}
|
||||
const PIStringList & mandatoryArguments() {
|
||||
parse();
|
||||
return _args_mand;
|
||||
}
|
||||
const PIStringList & optionalArguments() {
|
||||
parse();
|
||||
return _args_opt;
|
||||
}
|
||||
|
||||
//! \~english Returns program execute command without arguments.
|
||||
//! \~russian Возвращает команду вызова программы без аргументов.
|
||||
PIString programCommand() {parse(); return _args_raw.size() > 0 ? _args_raw.front() : PIString();}
|
||||
PIString programCommand() {
|
||||
parse();
|
||||
return _args_raw.size() > 0 ? _args_raw.front() : PIString();
|
||||
}
|
||||
|
||||
//! \~english Returns if argument "name" found.
|
||||
//! \~russian Возвращает найден ли аргумент "name".
|
||||
bool hasArgument(const PIString & name) {parse(); piForeach (Argument & i, _args) if (i.name == name && i.found) return true; return false;}
|
||||
bool hasArgument(const PIString & name) {
|
||||
parse();
|
||||
piForeach(Argument & i, _args)
|
||||
if (i.name == name && i.found) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//! \~english Returns argument "name" value, or empty string if this is no value.
|
||||
//! \~russian Возвращает значение аргумента "name" или пустую строку, если значения нет.
|
||||
PIString argumentValue(const PIString & name) {parse(); piForeach (Argument &i, _args) if (i.name == name && i.found) return i.value; return PIString();}
|
||||
PIString argumentValue(const PIString & name) {
|
||||
parse();
|
||||
piForeach(Argument & i, _args)
|
||||
if (i.name == name && i.found) return i.value;
|
||||
return PIString();
|
||||
}
|
||||
|
||||
//! \~english Returns short key of argument "name", or empty string if this is no argument.
|
||||
//! \~russian Возвращает короткий ключ аргумента "name" или пустую строку, если аргумента нет.
|
||||
PIString argumentShortKey(const PIString & name) {piForeach (Argument &i, _args) if (i.name == name) return i.short_key; return PIString();}
|
||||
PIString argumentShortKey(const PIString & name) {
|
||||
piForeach(Argument & i, _args)
|
||||
if (i.name == name) return i.short_key;
|
||||
return PIString();
|
||||
}
|
||||
|
||||
//! \~english Returns full key of argument "name", or empty string if this is no argument.
|
||||
//! \~russian Возвращает полный ключ аргумента "name" или пустую строку, если аргумента нет.
|
||||
PIString argumentFullKey(const PIString & name) {piForeach (Argument &i, _args) if (i.name == name) return i.full_key; return PIString();}
|
||||
PIString argumentFullKey(const PIString & name) {
|
||||
piForeach(Argument & i, _args)
|
||||
if (i.name == name) return i.full_key;
|
||||
return PIString();
|
||||
}
|
||||
|
||||
const PIString & shortKeyPrefix() const { return _prefix_short; }
|
||||
const PIString & fullKeyPrefix() const { return _prefix_full; }
|
||||
int mandatoryArgumentsCount() const { return _count_mand; }
|
||||
int optionalArgumentsCount() const { return _count_opt; }
|
||||
void setShortKeyPrefix(const PIString & prefix) {_prefix_short = prefix; needParse = true;}
|
||||
void setFullKeyPrefix(const PIString & prefix) {_prefix_full = prefix; needParse = true;}
|
||||
void setMandatoryArgumentsCount(const int count) {_count_mand = count; needParse = true;}
|
||||
void setOptionalArgumentsCount(const int count) {_count_opt = count; needParse = true;}
|
||||
void setShortKeyPrefix(const PIString & prefix) {
|
||||
_prefix_short = prefix;
|
||||
needParse = true;
|
||||
}
|
||||
void setFullKeyPrefix(const PIString & prefix) {
|
||||
_prefix_full = prefix;
|
||||
needParse = true;
|
||||
}
|
||||
void setMandatoryArgumentsCount(const int count) {
|
||||
_count_mand = count;
|
||||
needParse = true;
|
||||
}
|
||||
void setOptionalArgumentsCount(const int count) {
|
||||
_count_opt = count;
|
||||
needParse = true;
|
||||
}
|
||||
|
||||
bool debug() const { return debug_; }
|
||||
void setDebug(bool debug) { debug_ = debug; }
|
||||
@@ -112,7 +176,13 @@ public:
|
||||
private:
|
||||
struct Argument {
|
||||
Argument() { has_value = found = false; }
|
||||
Argument(const PIString & n, const PIChar & s, const PIString & f, bool v) {name = n; short_key = s; full_key = f; has_value = v; found = false;}
|
||||
Argument(const PIString & n, const PIChar & s, const PIString & f, bool v) {
|
||||
name = n;
|
||||
short_key = s;
|
||||
full_key = f;
|
||||
has_value = v;
|
||||
found = false;
|
||||
}
|
||||
PIString name;
|
||||
PIChar short_key;
|
||||
PIString full_key;
|
||||
@@ -128,7 +198,6 @@ private:
|
||||
PIVector<Argument> _args;
|
||||
int _count_mand, _count_opt;
|
||||
bool needParse, debug_;
|
||||
|
||||
};
|
||||
|
||||
#endif // PICLI_H
|
||||
|
||||
@@ -49,8 +49,7 @@ PIStringList PICollection::groups() {
|
||||
PIVector<const PIObject *> PICollection::groupElements(const PIString & group) {
|
||||
PIVector<PICollection::Group> & cg(_groups());
|
||||
piForeachC(Group & g, cg)
|
||||
if (g.name == group)
|
||||
return g.elements;
|
||||
if (g.name == group) return g.elements;
|
||||
return PIVector<const PIObject *>();
|
||||
}
|
||||
|
||||
@@ -62,8 +61,7 @@ bool PICollection::addToGroup(const PIString & group, const PIObject * element)
|
||||
piForeach(Group & g, cg)
|
||||
if (g.name == group) {
|
||||
for (int i = 0; i < g.elements.size_s(); ++i)
|
||||
if (PIString(g.elements[i]->className()) == n)
|
||||
return false;
|
||||
if (PIString(g.elements[i]->className()) == n) return false;
|
||||
g.elements << element;
|
||||
// piCout << "new group" << group << ", ok";
|
||||
return true;
|
||||
@@ -83,9 +81,7 @@ PIVector<PICollection::Group> & PICollection::_groups() {
|
||||
|
||||
PICollection::CollectionAdder::CollectionAdder(const PIString & group, const PIObject * element, const PIString & name, bool own) {
|
||||
if (!element) return;
|
||||
if (name.isNotEmpty())
|
||||
const_cast<PIObject * >(element)->setName(name);
|
||||
if (name.isNotEmpty()) const_cast<PIObject *>(element)->setName(name);
|
||||
bool added = PICollection::addToGroup(group, element);
|
||||
if (!added && own)
|
||||
delete element;
|
||||
if (!added && own) delete element;
|
||||
}
|
||||
|
||||
@@ -104,9 +104,9 @@
|
||||
//! \~\brief
|
||||
//! \~english Helper to collect and retrieve classes to groups.
|
||||
//! \~russian Помощник для создания и получения классов в группы.
|
||||
class PIP_EXPORT PICollection
|
||||
{
|
||||
class PIP_EXPORT PICollection {
|
||||
friend class __PICollectionInitializer;
|
||||
|
||||
public:
|
||||
PICollection() { ; }
|
||||
|
||||
@@ -133,7 +133,6 @@ protected:
|
||||
};
|
||||
|
||||
static PIVector<Group> & _groups();
|
||||
|
||||
};
|
||||
|
||||
#endif // PICOLLECTION_H
|
||||
|
||||
@@ -51,12 +51,12 @@
|
||||
#ifndef PICOREMODULE_H
|
||||
#define PICOREMODULE_H
|
||||
|
||||
#include "picollection.h"
|
||||
#include "piobject.h"
|
||||
#include "pitime.h"
|
||||
#include "picli.h"
|
||||
#include "pichunkstream.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "picli.h"
|
||||
#include "picollection.h"
|
||||
#include "pijson.h"
|
||||
#include "piobject.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "pitime.h"
|
||||
|
||||
#endif // PICOREMODULE_H
|
||||
|
||||
@@ -16,20 +16,21 @@
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "piincludes_p.h"
|
||||
#include "picout.h"
|
||||
|
||||
#include "pibytearray.h"
|
||||
#include "pistack.h"
|
||||
#include "piincludes_p.h"
|
||||
#include "piobject.h"
|
||||
#include "pistack.h"
|
||||
#include "pistring_std.h"
|
||||
#ifdef HAS_LOCALE
|
||||
# include <locale>
|
||||
# include <codecvt>
|
||||
# include <locale>
|
||||
#endif
|
||||
#ifdef WINDOWS
|
||||
# include <wincon.h>
|
||||
# include <windows.h>
|
||||
# include <wingdi.h>
|
||||
# include <wincon.h>
|
||||
# define COMMON_LVB_UNDERSCORE 0x8000
|
||||
#endif
|
||||
|
||||
@@ -106,13 +107,13 @@
|
||||
|
||||
class NotifierObject: public PIObject {
|
||||
PIOBJECT(NotifierObject)
|
||||
|
||||
public:
|
||||
NotifierObject() {}
|
||||
EVENT2(finished, int, id, PIString *, buffer);
|
||||
};
|
||||
|
||||
|
||||
|
||||
PICout::Notifier::Notifier() {
|
||||
o = new NotifierObject();
|
||||
}
|
||||
@@ -129,12 +130,16 @@ PIObject * PICout::Notifier::object() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
using namespace PICoutManipulators;
|
||||
|
||||
PIMutex & PICout::__mutex__() {static PIMutex * ret = new PIMutex(); return *ret;}
|
||||
PIString & PICout::__string__() {static PIString * ret = new PIString(); return *ret;}
|
||||
PIMutex & PICout::__mutex__() {
|
||||
static PIMutex * ret = new PIMutex();
|
||||
return *ret;
|
||||
}
|
||||
PIString & PICout::__string__() {
|
||||
static PIString * ret = new PIString();
|
||||
return *ret;
|
||||
}
|
||||
|
||||
PICout::OutputDevices PICout::devs = PICout::StdOut;
|
||||
|
||||
@@ -164,9 +169,16 @@ PICout::PICout(bool active): fo_(true), cc_(false), fc_(false), act_(active), cn
|
||||
}
|
||||
|
||||
|
||||
PICout::PICout(const PICout & other): fo_(other.fo_), cc_(true), fc_(false), act_(other.act_), cnb_(other.cnb_), attr_(other.attr_),
|
||||
id_(other.id_), buffer_(other.buffer_), co_(other.co_) {
|
||||
}
|
||||
PICout::PICout(const PICout & other)
|
||||
: fo_(other.fo_)
|
||||
, cc_(true)
|
||||
, fc_(false)
|
||||
, act_(other.act_)
|
||||
, cnb_(other.cnb_)
|
||||
, attr_(other.attr_)
|
||||
, id_(other.id_)
|
||||
, buffer_(other.buffer_)
|
||||
, co_(other.co_) {}
|
||||
|
||||
|
||||
PICout::~PICout() {
|
||||
@@ -312,7 +324,8 @@ PICout & PICout::operator <<(PIFlags<PICoutManipulators::PICoutFormat> v) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
#define PIINTCOUT(v) { \
|
||||
#define PIINTCOUT(v) \
|
||||
{ \
|
||||
if (!act_) return *this; \
|
||||
space(); \
|
||||
if (cnb_ == 10) { \
|
||||
@@ -322,11 +335,13 @@ PICout & PICout::operator <<(PIFlags<PICoutManipulators::PICoutFormat> v) {
|
||||
if (PICout::isOutputDeviceActive(PICout::StdOut)) std::cout << (v); \
|
||||
if (PICout::isOutputDeviceActive(PICout::Buffer)) PICout::__string__() += PIString::fromNumber(v); \
|
||||
} \
|
||||
} else write(PIString::fromNumber(v, cnb_)); \
|
||||
} else \
|
||||
write(PIString::fromNumber(v, cnb_)); \
|
||||
return *this; \
|
||||
}
|
||||
|
||||
#define PIFLOATCOUT(v) { \
|
||||
#define PIFLOATCOUT(v) \
|
||||
{ \
|
||||
if (buffer_) { \
|
||||
(*buffer_) += PIString::fromNumber(v, 'g'); \
|
||||
} else { \
|
||||
@@ -358,8 +373,10 @@ PICout & PICout::operator <<(const char * v) {
|
||||
PICout & PICout::operator<<(bool v) {
|
||||
if (!act_) return *this;
|
||||
space();
|
||||
if (v) write("true");
|
||||
else write("false");
|
||||
if (v)
|
||||
write("true");
|
||||
else
|
||||
write("false");
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -388,11 +405,23 @@ PICout & PICout::operator <<(llong v) {PIINTCOUT(v)}
|
||||
|
||||
PICout & PICout::operator<<(ullong v){PIINTCOUT(v)}
|
||||
|
||||
PICout & PICout::operator <<(float v) {if (!act_) return *this; space(); PIFLOATCOUT(v)}
|
||||
PICout & PICout::operator<<(float v) {
|
||||
if (!act_) return *this;
|
||||
space();
|
||||
PIFLOATCOUT(v)
|
||||
}
|
||||
|
||||
PICout & PICout::operator <<(double v) {if (!act_) return *this; space(); PIFLOATCOUT(v)}
|
||||
PICout & PICout::operator<<(double v) {
|
||||
if (!act_) return *this;
|
||||
space();
|
||||
PIFLOATCOUT(v)
|
||||
}
|
||||
|
||||
PICout & PICout::operator <<(ldouble v) {if (!act_) return *this; space(); PIFLOATCOUT(v)}
|
||||
PICout & PICout::operator<<(ldouble v) {
|
||||
if (!act_) return *this;
|
||||
space();
|
||||
PIFLOATCOUT(v)
|
||||
}
|
||||
|
||||
PICout & PICout::operator<<(const void * v) {
|
||||
if (!act_) return *this;
|
||||
@@ -404,7 +433,8 @@ PICout & PICout::operator <<(const void * v) {
|
||||
PICout & PICout::operator<<(const PIObject * v) {
|
||||
if (!act_) return *this;
|
||||
space();
|
||||
if (v == 0) write("PIObject*(0x0)");
|
||||
if (v == 0)
|
||||
write("PIObject*(0x0)");
|
||||
else {
|
||||
write(v->className());
|
||||
write("*(0x" + PIString::fromNumber(ullong(v), 16) + ", \"" + v->name() + "\")");
|
||||
@@ -487,7 +517,6 @@ PICout & PICout::restoreControls() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! \details
|
||||
//! \~english
|
||||
//! If it is not a first output and control \a AddSpaces is set space character is put
|
||||
@@ -594,9 +623,11 @@ PICout & PICout::write(const PIString & s) {
|
||||
void PICout::stdoutPIString(const PIString & s) {
|
||||
#ifdef HAS_LOCALE
|
||||
std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> utf8conv;
|
||||
std::cout << utf8conv.to_bytes((char16_t*)&(const_cast<PIString&>(s).front()), (char16_t*)&(const_cast<PIString&>(s).front()) + s.size());
|
||||
std::cout << utf8conv.to_bytes((char16_t *)&(const_cast<PIString &>(s).front()),
|
||||
(char16_t *)&(const_cast<PIString &>(s).front()) + s.size());
|
||||
#else
|
||||
for (PIChar c: s) std::wcout.put(c.toWChar());
|
||||
for (PIChar c: s)
|
||||
std::wcout.put(c.toWChar());
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -626,7 +657,10 @@ void PICout::applyFormat(PICoutFormat f) {
|
||||
static int mask_fore = ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
static int mask_back = ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
|
||||
switch (f) {
|
||||
case Bin: case Oct: case Dec: case Hex: break;
|
||||
case Bin:
|
||||
case Oct:
|
||||
case Dec:
|
||||
case Hex: break;
|
||||
case PICoutManipulators::Bold: attr_ |= FOREGROUND_INTENSITY; break;
|
||||
case PICoutManipulators::Underline: attr_ |= COMMON_LVB_UNDERSCORE; break;
|
||||
case PICoutManipulators::Black: attr_ = (attr_ & mask_fore); break;
|
||||
@@ -651,7 +685,10 @@ void PICout::applyFormat(PICoutFormat f) {
|
||||
SetConsoleTextAttribute(__Private__::hOut, attr_);
|
||||
#else
|
||||
switch (f) {
|
||||
case Bin: case Oct: case Dec: case Hex: break;
|
||||
case Bin:
|
||||
case Oct:
|
||||
case Dec:
|
||||
case Hex: break;
|
||||
case PICoutManipulators::Bold: printf("\e[1m"); break;
|
||||
case PICoutManipulators::Faint: printf("\e[2m"); break;
|
||||
case PICoutManipulators::Italic: printf("\e[3m"); break;
|
||||
|
||||
@@ -41,7 +41,9 @@
|
||||
|
||||
#else
|
||||
# define piCout PICout(piDebug)
|
||||
# define piCoutObj PICout(piDebug && debug()) << (PIStringAscii("[") + className() + (name().isEmpty() ? "]" : PIStringAscii(" \"") + name() + PIStringAscii("\"]")))
|
||||
# define piCoutObj \
|
||||
PICout(piDebug && debug()) << (PIStringAscii("[") + className() + \
|
||||
(name().isEmpty() ? "]" : PIStringAscii(" \"") + name() + PIStringAscii("\"]")))
|
||||
#endif
|
||||
|
||||
|
||||
@@ -73,7 +75,8 @@ namespace PICoutManipulators {
|
||||
ClearLine /*! \~english Clear current line \~russian Очистить текущую строку */,
|
||||
ClearScreen /*! \~english Clear the screen \~russian Очистить экран */,
|
||||
SaveContol /*! \~english Save control flags, equivalent to \a saveControl() \~russian Сохранить флаги, аналогично \a saveControl() */,
|
||||
RestoreControl /*! \~english Restore control flags, equivalent to \a restoreControl() \~russian Восстановить флаги, аналогично \a restoreControl() */
|
||||
RestoreControl /*! \~english Restore control flags, equivalent to \a restoreControl() \~russian Восстановить флаги, аналогично \a
|
||||
restoreControl() */
|
||||
};
|
||||
|
||||
//! \~english Enum contains control of PICout
|
||||
@@ -120,9 +123,7 @@ namespace PICoutManipulators {
|
||||
};
|
||||
|
||||
typedef PIFlags<PICoutControl> PICoutControls;
|
||||
}
|
||||
|
||||
|
||||
} // namespace PICoutManipulators
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
@@ -131,7 +132,6 @@ namespace PICoutManipulators {
|
||||
//! \~russian Универсальный вывод в консоль.
|
||||
class PIP_EXPORT PICout {
|
||||
public:
|
||||
|
||||
//! \~english Default constructor with default features (AddSpaces and AddNewLine)
|
||||
//! \~russian Конструктор по умолчанию (AddSpaces и AddNewLine)
|
||||
PICout(int controls = PICoutManipulators::DefaultControls);
|
||||
@@ -154,6 +154,7 @@ public:
|
||||
//! \~english Object that emit events from %PICout
|
||||
//! \~russian Объект, который посылает события от %PICout
|
||||
static PIObject * object();
|
||||
|
||||
private:
|
||||
Notifier();
|
||||
PIObject * o;
|
||||
@@ -260,15 +261,25 @@ public:
|
||||
|
||||
//! \~english Set control flag "c" is "on" state
|
||||
//! \~russian Установить флаг "c" в "on" состояние
|
||||
PICout & setControl(PICoutManipulators::PICoutControl c, bool on = true) {co_.setFlag(c, on); return *this;}
|
||||
PICout & setControl(PICoutManipulators::PICoutControl c, bool on = true) {
|
||||
co_.setFlag(c, on);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Set control flags "c"
|
||||
//! \~russian Установить флаги "c"
|
||||
PICout & setControls(PICoutManipulators::PICoutControls c) {co_ = c; return *this;}
|
||||
PICout & setControls(PICoutManipulators::PICoutControls c) {
|
||||
co_ = c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Exec \a saveControls() and set control flags to "c"
|
||||
//! \~russian Иыполнить \a saveControls() и Установить флаги "c"
|
||||
PICout & saveAndSetControls(PICoutManipulators::PICoutControls c) {saveControls(); co_ = c; return *this;}
|
||||
PICout & saveAndSetControls(PICoutManipulators::PICoutControls c) {
|
||||
saveControls();
|
||||
co_ = c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Save control flags to internal stack
|
||||
//! \~russian Сохраняет состояние флагов во внутренний стек
|
||||
@@ -352,7 +363,10 @@ public:
|
||||
|
||||
//! \~english Construct with external buffer and ID "id". See \a Notifier for details
|
||||
//! \~russian Конструктор с внешним буфером и ID "id". Подробнее \a Notifier
|
||||
static PICout withExternalBuffer(PIString * buffer, int id = 0, PIFlags<PICoutManipulators::PICoutControl> controls = PICoutManipulators::AddSpaces | PICoutManipulators::AddNewLine);
|
||||
static PICout withExternalBuffer(PIString * buffer,
|
||||
int id = 0,
|
||||
PIFlags<PICoutManipulators::PICoutControl> controls = PICoutManipulators::AddSpaces |
|
||||
PICoutManipulators::AddNewLine);
|
||||
|
||||
static PIMutex & __mutex__();
|
||||
static PIString & __string__();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "piincludes.h"
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "pitime.h"
|
||||
#ifndef QNX
|
||||
@@ -66,7 +67,13 @@ PIString errorString() {
|
||||
#ifdef WINDOWS
|
||||
char * msg = nullptr;
|
||||
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);
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
err,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&msg,
|
||||
0,
|
||||
NULL);
|
||||
PIString ret = PIStringAscii("code ") + PIString::fromNumber(err) + PIStringAscii(" - ");
|
||||
if (msg) {
|
||||
ret += PIString::fromSystem(msg).trim();
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "pibase.h"
|
||||
#include "piflags.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef PIP_STD_IOSTREAM
|
||||
# include <iostream>
|
||||
@@ -38,7 +39,8 @@ class PIMutexLocker;
|
||||
class PIObject;
|
||||
class PIString;
|
||||
class PIByteArray;
|
||||
template <typename P> class PIBinaryStream;
|
||||
template<typename P>
|
||||
class PIBinaryStream;
|
||||
#ifndef MICRO_PIP
|
||||
class PIInit;
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define PIINCLUDES_P_H
|
||||
|
||||
|
||||
// clang-format off
|
||||
#include "picout.h"
|
||||
#ifdef WINDOWS
|
||||
# ifdef _WIN32_WINNT
|
||||
@@ -35,14 +36,14 @@ typedef LONG(NTAPI*PINtSetTimerResolution)(ULONG, BOOLEAN, PULONG);
|
||||
#ifdef CC_GCC
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef FREERTOS
|
||||
# ifdef ESP_PLATFORM
|
||||
@@ -53,6 +54,7 @@ typedef LONG(NTAPI*PINtSetTimerResolution)(ULONG, BOOLEAN, PULONG);
|
||||
# include <STM32FreeRTOS.h>
|
||||
# endif
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
|
||||
#endif // PIINCLUDES_P_H
|
||||
|
||||
@@ -17,17 +17,18 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "piinit.h"
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#ifndef MICRO_PIP
|
||||
|
||||
#include "pitime.h"
|
||||
#include "pisignals.h"
|
||||
#include "piobject.h"
|
||||
#include "pisysteminfo.h"
|
||||
#include "piresourcesstorage.h"
|
||||
# include "pidir.h"
|
||||
# include "piobject.h"
|
||||
# include "piprocess.h"
|
||||
# include "piresourcesstorage.h"
|
||||
# include "pisignals.h"
|
||||
# include "pisysteminfo.h"
|
||||
# include "pitime.h"
|
||||
# ifdef ESP_PLATFORM
|
||||
# include "esp_system.h"
|
||||
# endif
|
||||
@@ -38,20 +39,18 @@ extern FILETIME __pi_ftjan1970;
|
||||
extern PINtQueryTimerResolution getTimerResolutionAddr;
|
||||
extern PINtSetTimerResolution setTimerResolutionAddr;
|
||||
void __PISetTimerResolution() {
|
||||
if (setTimerResolutionAddr == NULL || getTimerResolutionAddr == NULL)
|
||||
return;
|
||||
if (setTimerResolutionAddr == NULL || getTimerResolutionAddr == NULL) return;
|
||||
ULONG _max(0), _min(0), _cur(0);
|
||||
// printf("getTimerResolution ...\n");
|
||||
LONG q = getTimerResolutionAddr(&_max, &_min, &_cur);
|
||||
// printf("getTimerResolution %d %lu %lu %lu\n", q, _min, _max, _cur);
|
||||
if (q == 0)
|
||||
setTimerResolutionAddr(_min, TRUE, &_cur);
|
||||
if (q == 0) setTimerResolutionAddr(_min, TRUE, &_cur);
|
||||
// printf("setTimerResolution %lu\n", cur);
|
||||
}
|
||||
# else
|
||||
# include <pthread.h>
|
||||
# include <pwd.h>
|
||||
# include <sys/utsname.h>
|
||||
# include <pthread.h>
|
||||
# ifdef BLACKBERRY
|
||||
# include <signal.h>
|
||||
# else
|
||||
@@ -59,9 +58,9 @@ void __PISetTimerResolution() {
|
||||
# endif
|
||||
# endif
|
||||
# ifdef MAC_OS
|
||||
# include <mach/mach_traps.h>
|
||||
# include <mach/mach.h>
|
||||
# include <mach/clock.h>
|
||||
# include <mach/mach.h>
|
||||
# include <mach/mach_traps.h>
|
||||
extern clock_serv_t __pi_mac_clock;
|
||||
# endif
|
||||
# ifdef PIP_ICU
|
||||
@@ -85,10 +84,10 @@ PRIVATE_DEFINITION_END(PIInit)
|
||||
|
||||
void __sighandler__(PISignals::Signal s) {
|
||||
// piCout << Hex << int(s);
|
||||
if (s == PISignals::StopTTYInput || s == PISignals::StopTTYOutput)
|
||||
piMSleep(10);
|
||||
if (s == PISignals::StopTTYInput || s == PISignals::StopTTYOutput) piMSleep(10);
|
||||
if (s == PISignals::UserDefined1)
|
||||
dumpApplicationToFile(PIDir::home().path() + PIDir::separator + PIStringAscii("_PIP_DUMP_") + PIString::fromNumber(PIProcess::currentPID()));
|
||||
dumpApplicationToFile(PIDir::home().path() + PIDir::separator + PIStringAscii("_PIP_DUMP_") +
|
||||
PIString::fromNumber(PIProcess::currentPID()));
|
||||
}
|
||||
|
||||
|
||||
@@ -109,8 +108,8 @@ PIInit::PIInit() {
|
||||
pthread_sigmask(SIG_BLOCK, &ss, 0);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
PIStringList ifpathes;
|
||||
ifpathes << PIStringAscii("/bin/ifconfig") << PIStringAscii("/sbin/ifconfig")
|
||||
<< PIStringAscii("/usr/bin/ifconfig") << PIStringAscii("/usr/sbin/ifconfig");
|
||||
ifpathes << PIStringAscii("/bin/ifconfig") << PIStringAscii("/sbin/ifconfig") << PIStringAscii("/usr/bin/ifconfig")
|
||||
<< PIStringAscii("/usr/sbin/ifconfig");
|
||||
piForeachC(PIString & i, ifpathes) {
|
||||
if (fileExists(i)) {
|
||||
sinfo->ifconfigPath = i;
|
||||
@@ -172,8 +171,7 @@ PIInit::PIInit() {
|
||||
int l = 0;
|
||||
GetCPInfoEx(CP_OEMCP, 0, &cpinfo);
|
||||
for (l = 0; l < MAX_PATH; ++l)
|
||||
if (cpinfo.CodePageName[l] == '\0' || cpinfo.CodePageName[l] == ' ')
|
||||
break;
|
||||
if (cpinfo.CodePageName[l] == '\0' || cpinfo.CodePageName[l] == ' ') break;
|
||||
__sysoemname__ = new char[256];
|
||||
memset(__sysoemname__, 0, 256);
|
||||
memcpy(__sysoemname__, "ibm-", 4);
|
||||
@@ -216,13 +214,11 @@ PIInit::PIInit() {
|
||||
}
|
||||
int argc_(0);
|
||||
wchar_t ** argv_ = CommandLineToArgvW(GetCommandLineW(), &argc_);
|
||||
if (argc_ > 0 && argv_ != 0)
|
||||
sinfo->execCommand = argv_[0];
|
||||
if (argc_ > 0 && argv_ != 0) sinfo->execCommand = argv_[0];
|
||||
LocalFree(argv_);
|
||||
memset(cbuff, 0, 1024);
|
||||
ulong unlen = 1023;
|
||||
if (GetUserNameA(cbuff, &unlen) != 0)
|
||||
sinfo->user = cbuff;
|
||||
if (GetUserNameA(cbuff, &unlen) != 0) sinfo->user = cbuff;
|
||||
# else // WINDOWS
|
||||
sinfo->processorsCount = piMaxi(1, int(sysconf(_SC_NPROCESSORS_ONLN)));
|
||||
passwd * ps = getpwuid(getuid());
|
||||
@@ -231,8 +227,7 @@ PIInit::PIInit() {
|
||||
else {
|
||||
memset(cbuff, 0, 1024);
|
||||
char * l = getlogin();
|
||||
if (l)
|
||||
sinfo->user = l;
|
||||
if (l) sinfo->user = l;
|
||||
}
|
||||
struct utsname uns;
|
||||
if (uname(&uns) == 0) {
|
||||
@@ -294,49 +289,57 @@ PIInit::~PIInit() {
|
||||
|
||||
bool PIInit::isBuildOptionEnabled(PIInit::BuildOption o) {
|
||||
switch (o) {
|
||||
case boICU: return
|
||||
case boICU:
|
||||
return
|
||||
# ifdef PIP_ICU
|
||||
true;
|
||||
# else
|
||||
false;
|
||||
# endif
|
||||
case boUSB: return
|
||||
case boUSB:
|
||||
return
|
||||
# ifdef PIP_USB
|
||||
true;
|
||||
# else
|
||||
false;
|
||||
# endif
|
||||
case boCrypt: return
|
||||
case boCrypt:
|
||||
return
|
||||
# ifdef PIP_CRYPT
|
||||
true;
|
||||
# else
|
||||
false;
|
||||
# endif
|
||||
case boIntrospection: return
|
||||
case boIntrospection:
|
||||
return
|
||||
# ifdef PIP_INTROSPECTION
|
||||
true;
|
||||
# else
|
||||
false;
|
||||
# endif
|
||||
case boFFTW: return
|
||||
case boFFTW:
|
||||
return
|
||||
# ifdef PIP_FFTW
|
||||
true;
|
||||
# else
|
||||
false;
|
||||
# endif
|
||||
case boCompress: return
|
||||
case boCompress:
|
||||
return
|
||||
# ifdef PIP_COMPRESS
|
||||
true;
|
||||
# else
|
||||
false;
|
||||
# endif
|
||||
case boOpenCL: return
|
||||
case boOpenCL:
|
||||
return
|
||||
# ifdef PIP_OPENCL
|
||||
true;
|
||||
# else
|
||||
false;
|
||||
# endif
|
||||
case boCloud: return
|
||||
case boCloud:
|
||||
return
|
||||
# ifdef PIP_CLOUD
|
||||
true;
|
||||
# else
|
||||
@@ -375,14 +378,12 @@ void PIInit::setFileCharset(const char *charset) {
|
||||
|
||||
bool PIInit::fileExists(const PIString & p) {
|
||||
FILE * f = fopen(p.data(), "r");
|
||||
if (f == 0)
|
||||
return false;
|
||||
if (f == 0) return false;
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int __PIInit_Initializer__::count_(0);
|
||||
PIInit * __PIInit_Initializer__::__instance__(0);
|
||||
|
||||
@@ -406,4 +407,3 @@ __PIInit_Initializer__::~__PIInit_Initializer__() {
|
||||
}
|
||||
|
||||
#endif // MICRO_PIP
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ static __PIInit_Initializer__ __piinit_initializer__;
|
||||
class PIP_EXPORT PIInit {
|
||||
friend class __PIInit_Initializer__;
|
||||
friend class PIFile;
|
||||
|
||||
public:
|
||||
~PIInit();
|
||||
|
||||
@@ -78,6 +79,7 @@ public:
|
||||
//! \~english Returns build options as stringlist
|
||||
//! \~russian Возвращает опции сборки как список строк
|
||||
static PIStringList buildOptions();
|
||||
|
||||
private:
|
||||
explicit PIInit();
|
||||
void setFileCharset(const char * charset);
|
||||
|
||||
@@ -34,18 +34,30 @@
|
||||
//! \~russian Вспомогательная структура для сохранения/извлечения произвольного блока данных в/из PIBinaryStream
|
||||
struct PIMemoryBlock {
|
||||
public:
|
||||
//! \~english Constructs data block
|
||||
//! \~russian Создает блок данных
|
||||
PIMemoryBlock(void * data_ = 0, int size_ = 0) {
|
||||
d = data_;
|
||||
s = size_;
|
||||
}
|
||||
|
||||
//! \~english Constructs data block
|
||||
//! \~russian Создает блок данных
|
||||
PIMemoryBlock(void * data_ = 0, int size_ = 0) {d = data_; s = size_;}
|
||||
PIMemoryBlock(const void * data_, const int size_) {
|
||||
d = const_cast<void *>(data_);
|
||||
s = size_;
|
||||
}
|
||||
|
||||
//! \~english Constructs data block
|
||||
//! \~russian Создает блок данных
|
||||
PIMemoryBlock(const void * data_, const int size_) {d = const_cast<void * >(data_); s = size_;}
|
||||
PIMemoryBlock(const PIMemoryBlock & o) {
|
||||
d = o.d;
|
||||
s = o.s;
|
||||
}
|
||||
|
||||
PIMemoryBlock(const PIMemoryBlock & o) {d = o.d; s = o.s;}
|
||||
|
||||
PIMemoryBlock & operator =(const PIMemoryBlock & o) {d = o.d; s = o.s; return *this;}
|
||||
PIMemoryBlock & operator=(const PIMemoryBlock & o) {
|
||||
d = o.d;
|
||||
s = o.s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Pointer to data
|
||||
//! \~russian Указатель на данные
|
||||
@@ -62,12 +74,13 @@ public:
|
||||
private:
|
||||
void * d;
|
||||
int s;
|
||||
|
||||
};
|
||||
|
||||
//! \~english Returns PIMemoryBlock from pointer to variable "ptr" with type "T"
|
||||
//! \~russian Возвращает PIMemoryBlock из указателя "ptr" типа "T"
|
||||
template<typename T>
|
||||
PIMemoryBlock createMemoryBlock(const T * ptr) {return PIMemoryBlock(ptr, sizeof(T));}
|
||||
PIMemoryBlock createMemoryBlock(const T * ptr) {
|
||||
return PIMemoryBlock(ptr, sizeof(T));
|
||||
}
|
||||
|
||||
#endif // PIMEMORYBLOCK_H
|
||||
|
||||
@@ -18,12 +18,13 @@
|
||||
*/
|
||||
|
||||
#include "piobject.h"
|
||||
#include "pithread.h"
|
||||
|
||||
#include "piconditionvar.h"
|
||||
#include "pithread.h"
|
||||
#ifndef MICRO_PIP
|
||||
# include "pisysteminfo.h"
|
||||
# include "pifile.h"
|
||||
# include "piiostream.h"
|
||||
# include "pisysteminfo.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -111,8 +112,7 @@ PIObject::__MetaFunc::__MetaFunc() {
|
||||
|
||||
int PIObject::__MetaFunc::argumentsCount() const {
|
||||
for (int i = 0; i < __PIOBJECT_MAX_ARGS__; ++i)
|
||||
if (!types[i])
|
||||
return i;
|
||||
if (!types[i]) return i;
|
||||
return __PIOBJECT_MAX_ARGS__;
|
||||
}
|
||||
|
||||
@@ -129,9 +129,7 @@ PIString PIObject::__MetaFunc::arguments() const {
|
||||
|
||||
|
||||
PIString PIObject::__MetaFunc::fullFormat() const {
|
||||
PIString ret = PIStringAscii(type_ret) + " " +
|
||||
PIStringAscii(scope) + "::" +
|
||||
PIStringAscii(func_name) +"(";
|
||||
PIString ret = PIStringAscii(type_ret) + " " + PIStringAscii(scope) + "::" + PIStringAscii(func_name) + "(";
|
||||
for (int i = 0; i < __PIOBJECT_MAX_ARGS__; ++i) {
|
||||
if (!types[i]) break;
|
||||
if (i > 0) ret += ", ";
|
||||
@@ -167,11 +165,9 @@ bool PIObject::__MetaFunc::canConnectTo(const __MetaFunc & dst, int & args_count
|
||||
args_count = i;
|
||||
if (!dst.types[i]) break;
|
||||
if (!types[i]) return false;
|
||||
if (types_id[i] != dst.types_id[i])
|
||||
return false;
|
||||
if (types_id[i] != dst.types_id[i]) return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -198,8 +194,6 @@ PIObject::~PIObject() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool PIObject::execute(const PIString & method, const PIVector<PIVariantSimple> & vl) {
|
||||
if (method.isEmpty()) return false;
|
||||
if (!isPIObject()) {
|
||||
@@ -209,8 +203,7 @@ bool PIObject::execute(const PIString & method, const PIVector<PIVariantSimple>
|
||||
int ac = 0;
|
||||
__MetaFunc func;
|
||||
bool ok = findSuitableMethodV(method, vl.size_s(), ac, func);
|
||||
if (!ok)
|
||||
return false;
|
||||
if (!ok) return false;
|
||||
callAddrV(func.addrV, toThis(), ac, vl);
|
||||
return true;
|
||||
}
|
||||
@@ -228,8 +221,7 @@ bool PIObject::executeQueued(PIObject * performer, const PIString & method, cons
|
||||
int ac = 0;
|
||||
__MetaFunc func;
|
||||
bool ok = findSuitableMethodV(method, vl.size_s(), ac, func);
|
||||
if (!ok)
|
||||
return false;
|
||||
if (!ok) return false;
|
||||
performer->postQueuedEvent(__QueuedEvent(func.addrV, toThis(), this, performer, vl));
|
||||
performer->proc_event_queue = true;
|
||||
return true;
|
||||
@@ -262,8 +254,7 @@ bool PIObject::isMethodEHContains(const PIString & name) const {
|
||||
PIMutexLocker ml(__meta_mutex());
|
||||
const __MetaData & ehd(__meta_data()[classNameID()]);
|
||||
for (auto eh = ehd.eh_func.begin(); eh != ehd.eh_func.end(); eh++) {
|
||||
if (eh.value().func_name_id == search_id)
|
||||
return true;
|
||||
if (eh.value().func_name_id == search_id) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -274,8 +265,7 @@ PIString PIObject::methodEHArguments(const PIString & name) const {
|
||||
PIMutexLocker ml(__meta_mutex());
|
||||
const __MetaData & ehd(__meta_data()[classNameID()]);
|
||||
for (auto eh = ehd.eh_func.begin(); eh != ehd.eh_func.end(); eh++) {
|
||||
if (eh.value().func_name_id == search_id)
|
||||
return eh.value().arguments();
|
||||
if (eh.value().func_name_id == search_id) return eh.value().arguments();
|
||||
}
|
||||
return PIString();
|
||||
}
|
||||
@@ -286,8 +276,7 @@ PIString PIObject::methodEHFullFormat(const PIString & name) const {
|
||||
PIMutexLocker ml(__meta_mutex());
|
||||
const __MetaData & ehd(__meta_data()[classNameID()]);
|
||||
for (auto eh = ehd.eh_func.begin(); eh != ehd.eh_func.end(); eh++) {
|
||||
if (eh.value().func_name_id == search_id)
|
||||
return eh.value().fullFormat();
|
||||
if (eh.value().func_name_id == search_id) return eh.value().fullFormat();
|
||||
}
|
||||
return PIString();
|
||||
}
|
||||
@@ -303,8 +292,7 @@ PIVector<PIObject::__MetaFunc> PIObject::findEH(const PIString & name) const {
|
||||
PIVector<__MetaFunc> ret;
|
||||
const __MetaData & ehd(__meta_data()[classNameID()]);
|
||||
for (auto eh = ehd.eh_func.begin(); eh != ehd.eh_func.end(); eh++) {
|
||||
if (eh.value().func_name_id == search_id)
|
||||
ret << eh.value();
|
||||
if (eh.value().func_name_id == search_id) ret << eh.value();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -316,7 +304,14 @@ PIObject::__MetaFunc PIObject::methodEH(const void * addr) const {
|
||||
}
|
||||
|
||||
|
||||
PIObject::Connection PIObject::piConnect(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, void * ev_h, void * e_h, int args, const char * loc) {
|
||||
PIObject::Connection PIObject::piConnect(PIObject * src,
|
||||
const PIString & sig,
|
||||
PIObject * dest_o,
|
||||
void * dest,
|
||||
void * ev_h,
|
||||
void * e_h,
|
||||
int args,
|
||||
const char * loc) {
|
||||
// piCout << "piConnect ...";
|
||||
// piCout << "piConnect" << src << (void*)(dest) << sig;
|
||||
// piCout << "piConnect" << src->className() << "->" << ((PIObject*)dest)->className();
|
||||
@@ -334,7 +329,13 @@ PIObject::Connection PIObject::piConnect(PIObject * src, const PIString & sig, P
|
||||
}
|
||||
|
||||
|
||||
PIObject::Connection PIObject::piConnectU(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, const PIString & hname, const char * loc, PIObject * performer) {
|
||||
PIObject::Connection PIObject::piConnectU(PIObject * src,
|
||||
const PIString & sig,
|
||||
PIObject * dest_o,
|
||||
void * dest,
|
||||
const PIString & hname,
|
||||
const char * loc,
|
||||
PIObject * performer) {
|
||||
if (src == 0 || dest_o == 0 || dest == 0) return Connection();
|
||||
if (!src->isPIObject()) {
|
||||
piCout << "[piConnectU] \"" << sig << "\" -> \"" << hname << "\" error: source object is not PIObject! (" << loc << ")";
|
||||
@@ -403,7 +404,8 @@ PIObject::Connection PIObject::piConnectLS(PIObject * src, const PIString & sig,
|
||||
return Connection();
|
||||
}
|
||||
if (m_src.size() != 1) {
|
||||
piCout << "[piConnectLS] Error: can`t connect overloaded event \"" << sig << "\" in class \"" << src->className() << "\"! (" << loc << ")";
|
||||
piCout << "[piConnectLS] Error: can`t connect overloaded event \"" << sig << "\" in class \"" << src->className() << "\"! (" << loc
|
||||
<< ")";
|
||||
delete f;
|
||||
return Connection();
|
||||
}
|
||||
@@ -509,8 +511,7 @@ void PIObject::updateConnectors() {
|
||||
if (o == this) continue;
|
||||
PIVector<Connection> & oc(o->connections);
|
||||
piForeach(Connection & c, oc)
|
||||
if (c.dest == this)
|
||||
connectors << o;
|
||||
if (c.dest == this) connectors << o;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,8 +613,13 @@ void PIObject::callAddrV(void * slot, void * obj, int args, const PIVector<PIVar
|
||||
case 0: ((void (*)(void *))slot)(obj); break;
|
||||
case 1: ((void (*)(void *, const PIVariantSimple &))slot)(obj, vl[0]); break;
|
||||
case 2: ((void (*)(void *, const PIVariantSimple &, const PIVariantSimple &))slot)(obj, vl[0], vl[1]); break;
|
||||
case 3: ((void(*)(void * , const PIVariantSimple & , const PIVariantSimple & , const PIVariantSimple & ))slot)(obj, vl[0], vl[1], vl[2]); break;
|
||||
case 4: ((void(*)(void * , const PIVariantSimple & , const PIVariantSimple & , const PIVariantSimple & , const PIVariantSimple & ))slot)(obj, vl[0], vl[1], vl[2], vl[3]); break;
|
||||
case 3:
|
||||
((void (*)(void *, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &))slot)(obj, vl[0], vl[1], vl[2]);
|
||||
break;
|
||||
case 4:
|
||||
((void (*)(void *, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &))
|
||||
slot)(obj, vl[0], vl[1], vl[2], vl[3]);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -652,11 +658,9 @@ PIString PIObject::simplifyType(const char * a, bool readable) {
|
||||
ret.replaceAll("> ", '>');
|
||||
ret.replaceAll("& ", '&');
|
||||
ret.replaceAll("* ", '*');
|
||||
if (ret.startsWith("const ") && ret.endsWith("&"))
|
||||
ret.cutLeft(6).cutRight(1).trim();
|
||||
if (ret.startsWith("const ") && ret.endsWith("&")) ret.cutLeft(6).cutRight(1).trim();
|
||||
} else {
|
||||
if (ret.startsWith("const ") && ret.endsWith("&"))
|
||||
ret.cutLeft(6).cutRight(1).trim();
|
||||
if (ret.startsWith("const ") && ret.endsWith("&")) ret.cutLeft(6).cutRight(1).trim();
|
||||
ret.removeAll(' ').removeAll('\t').removeAll('\r').removeAll('\n');
|
||||
}
|
||||
return ret;
|
||||
@@ -671,7 +675,8 @@ bool PIObject::isPIObject(const PIObject * o) {
|
||||
|
||||
void PIObject::dump(const PIString & line_prefix) const {
|
||||
// printf("dump %s \"%s\"\n", className(), name().data());
|
||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << "class " << className() << " (" << (const void*)this << ", \"" << name() << "\") {";
|
||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << "class " << className() << " (" << (const void *)this << ", \"" << name()
|
||||
<< "\") {";
|
||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << " scope: " << scopeList().join(" -> ");
|
||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << " properties {";
|
||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << " count: " << properties_.size_s();
|
||||
@@ -700,16 +705,19 @@ void PIObject::dump(const PIString & line_prefix) const {
|
||||
PIObject * dst = c.dest_o;
|
||||
__MetaFunc ef = methodEH(c.signal);
|
||||
PIString src(c.event);
|
||||
if (ef.func_name)
|
||||
src = PIStringAscii(ef.func_name) + "(" + ef.arguments() + ")";
|
||||
if (ef.func_name) src = PIStringAscii(ef.func_name) + "(" + ef.arguments() + ")";
|
||||
if (dst) {
|
||||
__MetaFunc hf = dst->methodEH(c.slot);
|
||||
PIString hf_fn;
|
||||
if (!hf.func_name) hf_fn = "[BROKEN]";
|
||||
else hf_fn = PIStringAscii(hf.func_name) + "(" + hf.arguments() + ")";
|
||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << src << " -> " << dst->className() << " (" << c.dest << ", \"" << dst->name() << "\")::" << hf_fn;
|
||||
if (!hf.func_name)
|
||||
hf_fn = "[BROKEN]";
|
||||
else
|
||||
hf_fn = PIStringAscii(hf.func_name) + "(" + hf.arguments() + ")";
|
||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << src << " -> " << dst->className() << " (" << c.dest
|
||||
<< ", \"" << dst->name() << "\")::" << hf_fn;
|
||||
} else {
|
||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << src << " -> " << "[lambda]";
|
||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << src << " -> "
|
||||
<< "[lambda]";
|
||||
}
|
||||
}
|
||||
// printf("dump %d connections ok\n",connections.size());
|
||||
@@ -734,7 +742,8 @@ void dumpApplication(bool with_objects) {
|
||||
PICout(PICoutManipulators::AddNewLine) << " username: \"" << pi->user << "\"";
|
||||
PICout(PICoutManipulators::AddNewLine) << " exec command: \"" << pi->execCommand << "\"";
|
||||
PICout(PICoutManipulators::AddNewLine) << " started: " << pi->execDateTime.toString();
|
||||
PICout(PICoutManipulators::AddNewLine) << " uptime: " << PITime::fromSystemTime(cd.toSystemTime() - pi->execDateTime.toSystemTime()).toString();
|
||||
PICout(PICoutManipulators::AddNewLine) << " uptime: "
|
||||
<< PITime::fromSystemTime(cd.toSystemTime() - pi->execDateTime.toSystemTime()).toString();
|
||||
PICout(PICoutManipulators::AddNewLine) << " PIObjects {";
|
||||
PICout(PICoutManipulators::AddNewLine) << " count: " << PIObject::objects().size_s();
|
||||
if (with_objects) {
|
||||
@@ -774,8 +783,6 @@ void PIObject::__MetaData::addScope(const char * s, uint shash) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PIObject::Connection::destroy() {
|
||||
if (functor) delete functor;
|
||||
functor = nullptr;
|
||||
@@ -804,11 +811,9 @@ bool PIObject::Connection::disconnect() {
|
||||
Connection & cc(src_o->connections[i]);
|
||||
if (cc.eventID == eventID) {
|
||||
if (dest_o && (cc.dest_o == dest_o)) {
|
||||
if (cc.slot == slot)
|
||||
found = true;
|
||||
if (cc.slot == slot) found = true;
|
||||
}
|
||||
if (functor && (cc.functor == functor))
|
||||
found = true;
|
||||
if (functor && (cc.functor == functor)) found = true;
|
||||
}
|
||||
if (found) {
|
||||
src_o->connections[i].destroy();
|
||||
@@ -818,16 +823,13 @@ bool PIObject::Connection::disconnect() {
|
||||
}
|
||||
}
|
||||
if (dest_o) {
|
||||
if (dest_o->isPIObject())
|
||||
dest_o->updateConnectors();
|
||||
if (dest_o->isPIObject()) dest_o->updateConnectors();
|
||||
}
|
||||
if (ndm) dest_o->mutex_connect.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PRIVATE_DEFINITION_START(PIObject::Deleter)
|
||||
PIThread thread;
|
||||
PIConditionVariable cond_var;
|
||||
@@ -843,7 +845,8 @@ PIObject::Deleter::Deleter() {
|
||||
if (PRIVATE->obj_queue.isEmpty()) PRIVATE->cond_var.wait(PRIVATE->thread.mutex());
|
||||
oq.swap(PRIVATE->obj_queue);
|
||||
PRIVATE->thread.unlock();
|
||||
for (PIObject * o : oq) deleteObject(o);
|
||||
for (PIObject * o: oq)
|
||||
deleteObject(o);
|
||||
});
|
||||
PRIVATE->thread.start();
|
||||
}
|
||||
@@ -854,7 +857,8 @@ PIObject::Deleter::~Deleter() {
|
||||
PRIVATE->thread.stop();
|
||||
PRIVATE->cond_var.notifyAll();
|
||||
PRIVATE->thread.waitForFinish();
|
||||
for (PIObject * o : PRIVATE->obj_queue) deleteObject(o);
|
||||
for (PIObject * o: PRIVATE->obj_queue)
|
||||
deleteObject(o);
|
||||
// piCout << "~Deleter ok";
|
||||
}
|
||||
|
||||
@@ -882,7 +886,8 @@ void PIObject::Deleter::deleteObject(PIObject * o) {
|
||||
// piCout << "[Deleter] delete" << (uintptr_t)o << "...";
|
||||
if (o->isPIObject()) {
|
||||
// piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic ...";
|
||||
while (o->isInEvent()) piMinSleep();
|
||||
while (o->isInEvent())
|
||||
piMinSleep();
|
||||
// piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic done";
|
||||
delete o;
|
||||
}
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
#define PIOBJECT_H
|
||||
|
||||
#include "piinit.h"
|
||||
#include "pimutex.h"
|
||||
#include "piobject_macros.h"
|
||||
#include "piqueue.h"
|
||||
#include "piset.h"
|
||||
#include "pivariant.h"
|
||||
#include "pivariantsimple.h"
|
||||
#include "pimutex.h"
|
||||
#include "piset.h"
|
||||
#include "piqueue.h"
|
||||
#include "piobject_macros.h"
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
@@ -46,6 +46,7 @@ class PIP_EXPORT PIObject {
|
||||
#endif
|
||||
typedef PIObject __PIObject__;
|
||||
typedef void __Parent__;
|
||||
|
||||
public:
|
||||
NO_COPY_CLASS(PIObject);
|
||||
|
||||
@@ -61,9 +62,14 @@ public:
|
||||
//! \~russian Вспомогательный класс для получения информации об успешности соединения и возможности его разрыва.
|
||||
class PIP_EXPORT Connection {
|
||||
friend class PIObject;
|
||||
Connection(void * sl, void * si, const PIString & e = PIString(),
|
||||
PIObject * s_o = nullptr, PIObject * d_o = nullptr,
|
||||
void * d = nullptr, int ac = 0, PIObject * p = nullptr) {
|
||||
Connection(void * sl,
|
||||
void * si,
|
||||
const PIString & e = PIString(),
|
||||
PIObject * s_o = nullptr,
|
||||
PIObject * d_o = nullptr,
|
||||
void * d = nullptr,
|
||||
int ac = 0,
|
||||
PIObject * p = nullptr) {
|
||||
slot = sl;
|
||||
signal = si;
|
||||
event = e;
|
||||
@@ -85,8 +91,8 @@ public:
|
||||
PIObject * performer;
|
||||
void * dest;
|
||||
int args_count;
|
||||
public:
|
||||
|
||||
public:
|
||||
//! \~english Contructs invalid %Connection
|
||||
//! \~russian Создает недействительный %Connection
|
||||
Connection();
|
||||
@@ -116,7 +122,6 @@ private:
|
||||
uint _signature_;
|
||||
|
||||
public:
|
||||
|
||||
//! \~english Returns object name
|
||||
//! \~russian Возвращает имя объекта
|
||||
PIString name() const { return property("name").toString(); }
|
||||
@@ -125,10 +130,16 @@ public:
|
||||
//! \~russian Возвращает имя класса объекта
|
||||
virtual const char * className() const { return "PIObject"; }
|
||||
|
||||
virtual uint classNameID() const {static uint ret = PIStringAscii("PIObject").hash(); return ret;}
|
||||
virtual uint classNameID() const {
|
||||
static uint ret = PIStringAscii("PIObject").hash();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char * __classNameCC() { return "PIObject"; }
|
||||
static uint __classNameIDS() {static uint ret = PIStringAscii("PIObject").hash(); return ret;}
|
||||
static uint __classNameIDS() {
|
||||
static uint ret = PIStringAscii("PIObject").hash();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! \~english Returns parent class name
|
||||
//! \~russian Возвращает имя родительского класса
|
||||
@@ -154,7 +165,10 @@ public:
|
||||
|
||||
//! \~english Set property with name "name" to "value". If there is no such property in object it will be added
|
||||
//! \~russian Устанавливает у объекта свойство по имени "name" в "value". Если такого свойства нет, оно добавляется
|
||||
void setProperty(const char * name, const PIVariant & value) {properties_[piHashData((const uchar *)name, strlen(name))] = value; propertyChanged(name);}
|
||||
void setProperty(const char * name, const PIVariant & value) {
|
||||
properties_[piHashData((const uchar *)name, strlen(name))] = value;
|
||||
propertyChanged(name);
|
||||
}
|
||||
|
||||
//! \~english Returns if property with name "name" exists
|
||||
//! \~russian Возвращает присутствует ли свойство по имени "name"
|
||||
@@ -166,30 +180,97 @@ public:
|
||||
bool execute(const PIString & method, const PIVector<PIVariantSimple> & vl);
|
||||
bool execute(const PIString & method) { return execute(method, PIVector<PIVariantSimple>()); }
|
||||
bool execute(const PIString & method, const PIVariantSimple & v0) { return execute(method, PIVector<PIVariantSimple>() << v0); }
|
||||
bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return execute(method, PIVector<PIVariantSimple>() << v0 << v1);}
|
||||
bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return execute(method, PIVector<PIVariantSimple>() << v0 << v1 << v2);}
|
||||
bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return execute(method, PIVector<PIVariantSimple>() << v0 << v1 << v2 << v3);}
|
||||
bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {
|
||||
return execute(method, PIVector<PIVariantSimple>() << v0 << v1);
|
||||
}
|
||||
bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {
|
||||
return execute(method, PIVector<PIVariantSimple>() << v0 << v1 << v2);
|
||||
}
|
||||
bool execute(const PIString & method,
|
||||
const PIVariantSimple & v0,
|
||||
const PIVariantSimple & v1,
|
||||
const PIVariantSimple & v2,
|
||||
const PIVariantSimple & v3) {
|
||||
return execute(method, PIVector<PIVariantSimple>() << v0 << v1 << v2 << v3);
|
||||
}
|
||||
|
||||
bool executeQueued(PIObject * performer, const PIString & method, const PIVector<PIVariantSimple> & vl);
|
||||
bool executeQueued(PIObject * performer, const PIString & method) {return executeQueued(performer, method, PIVector<PIVariantSimple>());}
|
||||
bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0) {return executeQueued(performer, method, PIVector<PIVariantSimple>() << v0);}
|
||||
bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return executeQueued(performer, method, PIVector<PIVariantSimple>() << v0 << v1);}
|
||||
bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return executeQueued(performer, method, PIVector<PIVariantSimple>() << v0 << v1 << v2);}
|
||||
bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return executeQueued(performer, method, PIVector<PIVariantSimple>() << v0 << v1 << v2 << v3);}
|
||||
bool executeQueued(PIObject * performer, const PIString & method) {
|
||||
return executeQueued(performer, method, PIVector<PIVariantSimple>());
|
||||
}
|
||||
bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0) {
|
||||
return executeQueued(performer, method, PIVector<PIVariantSimple>() << v0);
|
||||
}
|
||||
bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {
|
||||
return executeQueued(performer, method, PIVector<PIVariantSimple>() << v0 << v1);
|
||||
}
|
||||
bool executeQueued(PIObject * performer,
|
||||
const PIString & method,
|
||||
const PIVariantSimple & v0,
|
||||
const PIVariantSimple & v1,
|
||||
const PIVariantSimple & v2) {
|
||||
return executeQueued(performer, method, PIVector<PIVariantSimple>() << v0 << v1 << v2);
|
||||
}
|
||||
bool executeQueued(PIObject * performer,
|
||||
const PIString & method,
|
||||
const PIVariantSimple & v0,
|
||||
const PIVariantSimple & v1,
|
||||
const PIVariantSimple & v2,
|
||||
const PIVariantSimple & v3) {
|
||||
return executeQueued(performer, method, PIVector<PIVariantSimple>() << v0 << v1 << v2 << v3);
|
||||
}
|
||||
|
||||
static bool execute(PIObject * o, const PIString & method, const PIVector<PIVariantSimple> & vl) { return o->execute(method, vl); }
|
||||
static bool execute(PIObject * o, const PIString & method) { return execute(o, method, PIVector<PIVariantSimple>()); }
|
||||
static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0) {return execute(o, method, PIVector<PIVariantSimple>() << v0);}
|
||||
static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return execute(o, method, PIVector<PIVariantSimple>() << v0 << v1);}
|
||||
static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return execute(o, method, PIVector<PIVariantSimple>() << v0 << v1 << v2);}
|
||||
static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return execute(o, method, PIVector<PIVariantSimple>() << v0 << v1 << v2 << v3);}
|
||||
static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0) {
|
||||
return execute(o, method, PIVector<PIVariantSimple>() << v0);
|
||||
}
|
||||
static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {
|
||||
return execute(o, method, PIVector<PIVariantSimple>() << v0 << v1);
|
||||
}
|
||||
static bool
|
||||
execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {
|
||||
return execute(o, method, PIVector<PIVariantSimple>() << v0 << v1 << v2);
|
||||
}
|
||||
static bool execute(PIObject * o,
|
||||
const PIString & method,
|
||||
const PIVariantSimple & v0,
|
||||
const PIVariantSimple & v1,
|
||||
const PIVariantSimple & v2,
|
||||
const PIVariantSimple & v3) {
|
||||
return execute(o, method, PIVector<PIVariantSimple>() << v0 << v1 << v2 << v3);
|
||||
}
|
||||
|
||||
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVector<PIVariantSimple> & vl) {return o->executeQueued(performer, method, vl);}
|
||||
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method) {return executeQueued(o, performer, method, PIVector<PIVariantSimple>());}
|
||||
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0) {return executeQueued(o, performer, method, PIVector<PIVariantSimple>() << v0);}
|
||||
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return executeQueued(o, performer, method, PIVector<PIVariantSimple>() << v0 << v1);}
|
||||
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return executeQueued(o, performer, method, PIVector<PIVariantSimple>() << v0 << v1 << v2);}
|
||||
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return executeQueued(o, performer, method, PIVector<PIVariantSimple>() << v0 << v1 << v2 << v3);}
|
||||
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVector<PIVariantSimple> & vl) {
|
||||
return o->executeQueued(performer, method, vl);
|
||||
}
|
||||
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method) {
|
||||
return executeQueued(o, performer, method, PIVector<PIVariantSimple>());
|
||||
}
|
||||
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0) {
|
||||
return executeQueued(o, performer, method, PIVector<PIVariantSimple>() << v0);
|
||||
}
|
||||
static bool
|
||||
executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {
|
||||
return executeQueued(o, performer, method, PIVector<PIVariantSimple>() << v0 << v1);
|
||||
}
|
||||
static bool executeQueued(PIObject * o,
|
||||
PIObject * performer,
|
||||
const PIString & method,
|
||||
const PIVariantSimple & v0,
|
||||
const PIVariantSimple & v1,
|
||||
const PIVariantSimple & v2) {
|
||||
return executeQueued(o, performer, method, PIVector<PIVariantSimple>() << v0 << v1 << v2);
|
||||
}
|
||||
static bool executeQueued(PIObject * o,
|
||||
PIObject * performer,
|
||||
const PIString & method,
|
||||
const PIVariantSimple & v0,
|
||||
const PIVariantSimple & v1,
|
||||
const PIVariantSimple & v2,
|
||||
const PIVariantSimple & v3) {
|
||||
return executeQueued(o, performer, method, PIVector<PIVariantSimple>() << v0 << v1 << v2 << v3);
|
||||
}
|
||||
|
||||
void dump(const PIString & line_prefix = PIString()) const;
|
||||
|
||||
@@ -205,8 +286,15 @@ public:
|
||||
PIString methodEHFromAddr(const void * addr) const;
|
||||
|
||||
// / Direct connect
|
||||
static PIObject::Connection piConnect(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, void * ev_h, void * e_h, int args, const char * loc);
|
||||
static PIObject::Connection piConnectU(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, const PIString & hname, const char * loc, PIObject * performer = 0);
|
||||
static PIObject::Connection
|
||||
piConnect(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, void * ev_h, void * e_h, int args, const char * loc);
|
||||
static PIObject::Connection piConnectU(PIObject * src,
|
||||
const PIString & sig,
|
||||
PIObject * dest_o,
|
||||
void * dest,
|
||||
const PIString & hname,
|
||||
const char * loc,
|
||||
PIObject * performer = 0);
|
||||
static PIObject::Connection piConnectLS(PIObject * src, const PIString & sig, std::function<void()> * f, const char * loc);
|
||||
template<typename PIINPUT, typename... PITYPES>
|
||||
static std::function<void()> * __newFunctor(void (*stat_handler)(void *, PITYPES...), PIINPUT functor) {
|
||||
@@ -227,7 +315,8 @@ public:
|
||||
void piDisconnect(const PIString & sig) { piDisconnect(this, sig); }
|
||||
|
||||
|
||||
//! \~english Disconnect object "src" from all connections with event name "sig", connected to destination object "dest" and handler "ev_h"
|
||||
//! \~english Disconnect object "src" from all connections with event name "sig", connected to destination object "dest" and handler
|
||||
//! "ev_h"
|
||||
//! \~russian Разрывает все соединения от события "sig" объекта "src" к объекту "dest" и обработчику "ev_h"
|
||||
static void piDisconnect(PIObject * src, const PIString & sig, PIObject * dest, void * ev_h);
|
||||
|
||||
@@ -286,8 +375,10 @@ public:
|
||||
i.dest_o->eventBegin();
|
||||
sender->eventBegin();
|
||||
i.dest_o->emitter_ = sender;
|
||||
if (i.args_count == 0) ((void(*)(void *))i.slot)(i.dest);
|
||||
else ((void(*)(void * , T0))i.slot)(i.dest, v0);
|
||||
if (i.args_count == 0)
|
||||
((void (*)(void *))i.slot)(i.dest);
|
||||
else
|
||||
((void (*)(void *, T0))i.slot)(i.dest, v0);
|
||||
sender->eventEnd();
|
||||
if (i.dest_o->isPIObject()) {
|
||||
i.dest_o->emitter_ = 0;
|
||||
@@ -372,7 +463,12 @@ public:
|
||||
}
|
||||
}
|
||||
template<typename T0, typename T1, typename T2, typename T3>
|
||||
static void raiseEvent(PIObject * sender, const uint eventID, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2(), const T3 & v3 = T3()) {
|
||||
static void raiseEvent(PIObject * sender,
|
||||
const uint eventID,
|
||||
const T0 & v0 = T0(),
|
||||
const T1 & v1 = T1(),
|
||||
const T2 & v2 = T2(),
|
||||
const T3 & v3 = T3()) {
|
||||
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
||||
Connection i(sender->connections[j]);
|
||||
if (i.eventID != eventID) continue;
|
||||
@@ -435,7 +531,8 @@ public:
|
||||
}
|
||||
|
||||
//! \~english Returns cast to T if this is valid subclass "T" (check by \a isTypeOf()) or "nullptr"
|
||||
//! \~russian Возвращает преобразование к типу T если это действительный наследник типа "T" (проверяет через \a isTypeOf()), или "nullptr"
|
||||
//! \~russian Возвращает преобразование к типу T если это действительный наследник типа "T" (проверяет через \a isTypeOf()), или
|
||||
//! "nullptr"
|
||||
template<typename T>
|
||||
T * cast() const {
|
||||
if (!isTypeOf<T>()) return (T *)nullptr;
|
||||
@@ -450,9 +547,13 @@ public:
|
||||
//! \~english Returns if "o" is valid %PIObject subclass "T" (check signature and classname)
|
||||
//! \~russian Возвращает действительный ли "o" наследник %PIObject типа "T" (проверяет подпись и имя класса)
|
||||
template<typename T>
|
||||
static bool isTypeOf(const PIObject * o) {return o->isTypeOf<T>();}
|
||||
static bool isTypeOf(const PIObject * o) {
|
||||
return o->isTypeOf<T>();
|
||||
}
|
||||
template<typename T>
|
||||
static bool isTypeOf(const void * o) {return isTypeOf<T>((PIObject*)o);}
|
||||
static bool isTypeOf(const void * o) {
|
||||
return isTypeOf<T>((PIObject *)o);
|
||||
}
|
||||
static PIString simplifyType(const char * a, bool readable = true);
|
||||
|
||||
struct PIP_EXPORT __MetaFunc {
|
||||
@@ -476,7 +577,10 @@ public:
|
||||
};
|
||||
|
||||
struct PIP_EXPORT __MetaData {
|
||||
__MetaData() {scope_list << "PIObject"; scope_id << PIStringAscii("PIObject").hash();}
|
||||
__MetaData() {
|
||||
scope_list << "PIObject";
|
||||
scope_id << PIStringAscii("PIObject").hash();
|
||||
}
|
||||
void addScope(const char * s, uint shash);
|
||||
PIVector<const char *> scope_list;
|
||||
PISet<uint> scope_id;
|
||||
@@ -497,7 +601,10 @@ public:
|
||||
//! \brief Если было хотя бы одно CONNECTU_QUEUED соединение с исполнителем this, то выполнить события
|
||||
//! \details Этот метод более оптимален, чем \a callQueuedEvents(), для объектов, которые не были в роли
|
||||
//! \"performer\" в макросе CONNECTU_QUEUED
|
||||
bool maybeCallQueuedEvents() {if (proc_event_queue) callQueuedEvents(); return proc_event_queue;}
|
||||
bool maybeCallQueuedEvents() {
|
||||
if (proc_event_queue) callQueuedEvents();
|
||||
return proc_event_queue;
|
||||
}
|
||||
|
||||
//! \~english Mark object to delete
|
||||
//! \~russian Пометить объект на удаление
|
||||
@@ -507,7 +614,6 @@ public:
|
||||
static PIMap<uint, __MetaData> & __meta_data(); // [hash(classname)]=__MetaData
|
||||
|
||||
protected:
|
||||
|
||||
//! \~english Returns %PIObject* which has raised an event. This value is correct only in definition of some event handler
|
||||
//! \~russian Возвращает %PIObject* который вызвал это событие. Значение допустимо только из методов обработчиков событий
|
||||
PIObject * emitter() const { return emitter_; }
|
||||
@@ -536,9 +642,12 @@ protected:
|
||||
//! \}
|
||||
|
||||
private:
|
||||
|
||||
struct __QueuedEvent {
|
||||
__QueuedEvent(void * sl = 0, void * d = 0, PIObject * d_o = 0, PIObject * s = 0, const PIVector<PIVariantSimple> & v = PIVector<PIVariantSimple>()) {
|
||||
__QueuedEvent(void * sl = 0,
|
||||
void * d = 0,
|
||||
PIObject * d_o = 0,
|
||||
PIObject * s = 0,
|
||||
const PIVector<PIVariantSimple> & v = PIVector<PIVariantSimple>()) {
|
||||
slot = sl;
|
||||
dest = d;
|
||||
dest_o = d_o;
|
||||
@@ -558,6 +667,7 @@ private:
|
||||
~Deleter();
|
||||
static Deleter * instance();
|
||||
void post(PIObject * o);
|
||||
|
||||
private:
|
||||
void deleteObject(PIObject * o);
|
||||
PRIVATE_DECLARATION(PIP_EXPORT)
|
||||
@@ -589,7 +699,6 @@ private:
|
||||
PIObject * emitter_;
|
||||
bool thread_safe_, proc_event_queue;
|
||||
std::atomic_int in_event_cnt;
|
||||
|
||||
};
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
|
||||
@@ -33,7 +33,8 @@
|
||||
//! \relatesalso PIObject
|
||||
//! \~\brief
|
||||
//! \~english You should use this macro after class declaration to use EVENT and EVENT_HANDLER and correct piCoutObj output
|
||||
//! \~russian Необходимо использовать этот макрос после объявления класса для использования событийной системы и корректного вывода piCoutObj
|
||||
//! \~russian Необходимо использовать этот макрос после объявления класса для использования событийной системы и корректного вывода
|
||||
//! piCoutObj
|
||||
# define PIOBJECT(name)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
@@ -70,8 +71,10 @@
|
||||
//! \relatesalso PIObject
|
||||
//! \~\brief
|
||||
//! \~english Declare event handler with name \"name\" and return type \"ret\", ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||
//! \~russian Объявляет обработчик событий с именем \"name\" и возвращаемым типом \"ret\", ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||
#define EVENT_HANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||
//! \~russian Объявляет обработчик событий с именем \"name\" и возвращаемым типом \"ret\", ret name(type0 var0, type1 var1, type2 var2,
|
||||
//! type3 var3)
|
||||
# define EVENT_HANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) \
|
||||
ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
//! \~\brief
|
||||
@@ -95,20 +98,25 @@
|
||||
//! \relatesalso PIObject
|
||||
//! \~\brief
|
||||
//! \~english Declare virtual event handler with name \"name\" and return type \"ret\", virtual ret name(type0 var0, type1 var1)
|
||||
//! \~russian Объявляет виртуальный обработчик событий с именем \"name\" и возвращаемым типом \"ret\", virtual ret name(type0 var0, type1 var1)
|
||||
//! \~russian Объявляет виртуальный обработчик событий с именем \"name\" и возвращаемым типом \"ret\", virtual ret name(type0 var0, type1
|
||||
//! var1)
|
||||
# define EVENT_VHANDLER2(ret, name, type0, var0, type1, var1) virtual ret name(type0 var0, type1 var1)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
//! \~\brief
|
||||
//! \~english Declare virtual event handler with name \"name\" and return type \"ret\", virtual ret name(type0 var0, type1 var1, type2 var2)
|
||||
//! \~russian Объявляет виртуальный обработчик событий с именем \"name\" и возвращаемым типом \"ret\", virtual ret name(type0 var0, type1 var1, type2 var2)
|
||||
//! \~russian Объявляет виртуальный обработчик событий с именем \"name\" и возвращаемым типом \"ret\", virtual ret name(type0 var0, type1
|
||||
//! var1, type2 var2)
|
||||
# define EVENT_VHANDLER3(ret, name, type0, var0, type1, var1, type2, var2) virtual ret name(type0 var0, type1 var1, type2 var2)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
//! \~\brief
|
||||
//! \~english Declare virtual event handler with name \"name\" and return type \"ret\", virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||
//! \~russian Объявляет виртуальный обработчик событий с именем \"name\" и возвращаемым типом \"ret\", virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||
#define EVENT_VHANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||
//! \~english Declare virtual event handler with name \"name\" and return type \"ret\", virtual ret name(type0 var0, type1 var1, type2 var2,
|
||||
//! type3 var3)
|
||||
//! \~russian Объявляет виртуальный обработчик событий с именем \"name\" и возвращаемым типом \"ret\", virtual ret name(type0 var0, type1
|
||||
//! var1, type2 var2, type3 var3)
|
||||
# define EVENT_VHANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) \
|
||||
virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
//! \~\brief
|
||||
@@ -214,8 +222,10 @@
|
||||
//! \~english Use \a CONNECTU() instead
|
||||
//! \~russian Используйте \a CONNECTU()
|
||||
//! \~\brief
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта \"dest\" с проверкой наличия события и обработчика.
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with
|
||||
//! check of event and handler exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\" с проверкой наличия события и обработчика.
|
||||
//! \~\details
|
||||
//! Returns PIObject::Connection
|
||||
# define CONNECT0(ret, src, event, dest, handler)
|
||||
@@ -225,8 +235,10 @@
|
||||
//! \~english Use \a CONNECTU() instead
|
||||
//! \~russian Используйте \a CONNECTU()
|
||||
//! \~\brief
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта \"dest\" с проверкой наличия события и обработчика.
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with
|
||||
//! check of event and handler exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\" с проверкой наличия события и обработчика.
|
||||
//! \~\details
|
||||
//! Returns PIObject::Connection
|
||||
# define CONNECT1(ret, type0, src, event, dest, handler)
|
||||
@@ -236,8 +248,10 @@
|
||||
//! \~english Use \a CONNECTU() instead
|
||||
//! \~russian Используйте \a CONNECTU()
|
||||
//! \~\brief
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта \"dest\" с проверкой наличия события и обработчика.
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with
|
||||
//! check of event and handler exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\" с проверкой наличия события и обработчика.
|
||||
//! \~\details
|
||||
//! Returns PIObject::Connection
|
||||
# define CONNECT2(ret, type0, type1, src, event, dest, handler)
|
||||
@@ -247,8 +261,10 @@
|
||||
//! \~english Use \a CONNECTU() instead
|
||||
//! \~russian Используйте \a CONNECTU()
|
||||
//! \~\brief
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта \"dest\" с проверкой наличия события и обработчика.
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with
|
||||
//! check of event and handler exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\" с проверкой наличия события и обработчика.
|
||||
//! \~\details
|
||||
//! Returns PIObject::Connection
|
||||
# define CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
||||
@@ -258,8 +274,10 @@
|
||||
//! \~english Use \a CONNECTU() instead
|
||||
//! \~russian Используйте \a CONNECTU()
|
||||
//! \~\brief
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists.
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта \"dest\" с проверкой наличия события и обработчика.
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with
|
||||
//! check of event and handler exists.
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\" с проверкой наличия события и обработчика.
|
||||
//! \~\details
|
||||
//! Returns PIObject::Connection
|
||||
# define CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
||||
@@ -279,8 +297,10 @@
|
||||
//! \~english Use \a CONNECTU() instead
|
||||
//! \~russian Используйте \a CONNECTU()
|
||||
//! \~\brief
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without check of event exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта \"dest\" без проверки наличия события и обработчика.
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without
|
||||
//! check of event exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\" без проверки наличия события и обработчика.
|
||||
# define WEAK_CONNECT0(ret, src, event, dest, handler)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
@@ -288,8 +308,10 @@
|
||||
//! \~english Use \a CONNECTU() instead
|
||||
//! \~russian Используйте \a CONNECTU()
|
||||
//! \~\brief
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without check of event exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта \"dest\" без проверки наличия события и обработчика.
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without
|
||||
//! check of event exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\" без проверки наличия события и обработчика.
|
||||
# define WEAK_CONNECT1(ret, type0, src, event, dest, handler)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
@@ -297,8 +319,10 @@
|
||||
//! \~english Use \a CONNECTU() instead
|
||||
//! \~russian Используйте \a CONNECTU()
|
||||
//! \~\brief
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without check of event exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта \"dest\" без проверки наличия события и обработчика.
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without
|
||||
//! check of event exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\" без проверки наличия события и обработчика.
|
||||
# define WEAK_CONNECT2(ret, type0, type1, src, event, dest, handler)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
@@ -306,8 +330,10 @@
|
||||
//! \~english Use \a CONNECTU() instead
|
||||
//! \~russian Используйте \a CONNECTU()
|
||||
//! \~\brief
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without check of event exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта \"dest\" без проверки наличия события и обработчика.
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without
|
||||
//! check of event exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\" без проверки наличия события и обработчика.
|
||||
# define WEAK_CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
@@ -315,8 +341,10 @@
|
||||
//! \~english Use \a CONNECTU() instead
|
||||
//! \~russian Используйте \a CONNECTU()
|
||||
//! \~\brief
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without check of event exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта \"dest\" без проверки наличия события и обработчика.
|
||||
//! \~english Connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without
|
||||
//! check of event exists
|
||||
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\" без проверки наличия события и обработчика.
|
||||
# define WEAK_CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
@@ -332,31 +360,36 @@
|
||||
//! \relatesalso PIObject
|
||||
//! \~\brief
|
||||
//! \~english piDisconnect event \"event\" from object \"src\" from event handler \"handler\" with return type \"ret\" from object \"dest\"
|
||||
//! \~russian piDisconnect событие \"event\" объекта \"src\" от обработчика или события \"handler\" с возвращаемым типом \"ret\" объекта \"dest\"
|
||||
//! \~russian piDisconnect событие \"event\" объекта \"src\" от обработчика или события \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\"
|
||||
# define DISCONNECT0(ret, src, event, dest, handler)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
//! \~\brief
|
||||
//! \~english piDisconnect event \"event\" from object \"src\" from event handler \"handler\" with return type \"ret\" from object \"dest\"
|
||||
//! \~russian piDisconnect событие \"event\" объекта \"src\" от обработчика или события \"handler\" с возвращаемым типом \"ret\" объекта \"dest\"
|
||||
//! \~russian piDisconnect событие \"event\" объекта \"src\" от обработчика или события \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\"
|
||||
# define DISCONNECT1(ret, type0, src, event, dest, handler)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
//! \~\brief
|
||||
//! \~english piDisconnect event \"event\" from object \"src\" from event handler \"handler\" with return type \"ret\" from object \"dest\"
|
||||
//! \~russian piDisconnect событие \"event\" объекта \"src\" от обработчика или события \"handler\" с возвращаемым типом \"ret\" объекта \"dest\"
|
||||
//! \~russian piDisconnect событие \"event\" объекта \"src\" от обработчика или события \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\"
|
||||
# define DISCONNECT2(ret, type0, type1, src, event, dest, handler)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
//! \~\brief
|
||||
//! \~english piDisconnect event \"event\" from object \"src\" from event handler \"handler\" with return type \"ret\" from object \"dest\"
|
||||
//! \~russian piDisconnect событие \"event\" объекта \"src\" от обработчика или события \"handler\" с возвращаемым типом \"ret\" объекта \"dest\"
|
||||
//! \~russian piDisconnect событие \"event\" объекта \"src\" от обработчика или события \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\"
|
||||
# define DISCONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
//! \~\brief
|
||||
//! \~english piDisconnect event \"event\" from object \"src\" from event handler \"handler\" with return type \"ret\" from object \"dest\"
|
||||
//! \~russian piDisconnect событие \"event\" объекта \"src\" от обработчика или события \"handler\" с возвращаемым типом \"ret\" объекта \"dest\"
|
||||
//! \~russian piDisconnect событие \"event\" объекта \"src\" от обработчика или события \"handler\" с возвращаемым типом \"ret\" объекта
|
||||
//! \"dest\"
|
||||
# define DISCONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
||||
|
||||
//! \relatesalso PIObject
|
||||
@@ -389,15 +422,31 @@
|
||||
|
||||
|
||||
# define PIOBJECT(name) \
|
||||
\
|
||||
protected: \
|
||||
typedef name __PIObject__; \
|
||||
\
|
||||
public: \
|
||||
static const char * __classNameCC() {return #name;} \
|
||||
static uint __classNameIDS() {static uint ret = PIStringAscii(#name).hash(); return ret;} \
|
||||
const char * className() const override {return #name;} \
|
||||
uint classNameID() const override {static uint ret = PIStringAscii(#name).hash(); return ret;} \
|
||||
static const char * __classNameCC() { \
|
||||
return #name; \
|
||||
} \
|
||||
static uint __classNameIDS() { \
|
||||
static uint ret = PIStringAscii(#name).hash(); \
|
||||
return ret; \
|
||||
} \
|
||||
const char * className() const override { \
|
||||
return #name; \
|
||||
} \
|
||||
uint classNameID() const override { \
|
||||
static uint ret = PIStringAscii(#name).hash(); \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
int ptrOffset() const override {name * o = (name*)100; return int(llong((PIObject*)o) - llong(o));} \
|
||||
int ptrOffset() const override { \
|
||||
name * o = (name *)100; \
|
||||
return int(llong((PIObject *)o) - llong(o)); \
|
||||
} \
|
||||
class __BaseInitializer__ { \
|
||||
public: \
|
||||
__BaseInitializer__() { \
|
||||
@@ -436,9 +485,13 @@
|
||||
} \
|
||||
}; \
|
||||
__ParentInitializer__ __parent_init__; \
|
||||
\
|
||||
public: \
|
||||
const char * parentClassName() const override {return #name;} \
|
||||
const char * parentClassName() const override { \
|
||||
return #name; \
|
||||
} \
|
||||
typedef name __Parent__; \
|
||||
\
|
||||
private:
|
||||
|
||||
# define PIOBJECT_SUBCLASS(name, parent) PIOBJECT(name) PIOBJECT_PARENT(parent)
|
||||
@@ -483,7 +536,8 @@
|
||||
# define EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \
|
||||
STATIC_INITIALIZER_BEGIN \
|
||||
void * fp = (void *)(ret(*)(void *, a0, a1, a2))__stat_eh_##name##__; \
|
||||
void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \
|
||||
void * fpV = \
|
||||
(void *)(ret(*)(void *, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \
|
||||
__EH_INIT_BASE__(ret, name) \
|
||||
f.__addArgument(#a0, #n0); \
|
||||
f.__addArgument(#a1, #n1); \
|
||||
@@ -493,7 +547,9 @@
|
||||
# define EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
|
||||
STATIC_INITIALIZER_BEGIN \
|
||||
void * fp = (void *)(ret(*)(void *, a0, a1, a2, a3))__stat_eh_##name##__; \
|
||||
void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \
|
||||
void * fpV = \
|
||||
(void *)(ret(*)(void *, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &)) \
|
||||
__stat_eh_v_##name##__; \
|
||||
__EH_INIT_BASE__(ret, name) \
|
||||
f.__addArgument(#a0, #n0); \
|
||||
f.__addArgument(#a1, #n1); \
|
||||
@@ -504,45 +560,66 @@
|
||||
|
||||
# define EVENT_HANDLER0(ret, name) \
|
||||
EH_INIT0(ret, name) \
|
||||
static ret __stat_eh_##name##__(void * __o__) {return ((__PIObject__*)__o__)->name();} \
|
||||
static ret __stat_eh_##name##__(void * __o__) { \
|
||||
return ((__PIObject__ *)__o__)->name(); \
|
||||
} \
|
||||
ret name()
|
||||
|
||||
# define EVENT_HANDLER1(ret, name, a0, n0) \
|
||||
EH_INIT1(ret, name, a0, n0) \
|
||||
static ret __stat_eh_##name##__(void * __o__, a0 n0) {return ((__PIObject__*)__o__)->name(n0);} \
|
||||
static ret __stat_eh_##name##__(void * __o__, a0 n0) { \
|
||||
return ((__PIObject__ *)__o__)->name(n0); \
|
||||
} \
|
||||
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) { \
|
||||
__PTYPE(a0) tv0 = __VVALUE(a0, v0); \
|
||||
return ((__PIObject__*)__o__)->name(tv0);} \
|
||||
return ((__PIObject__ *)__o__)->name(tv0); \
|
||||
} \
|
||||
ret name(a0 n0)
|
||||
|
||||
# define EVENT_HANDLER2(ret, name, a0, n0, a1, n1) \
|
||||
EH_INIT2(ret, name, a0, n0, a1, n1) \
|
||||
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) {return ((__PIObject__*)__o__)->name(n0, n1);} \
|
||||
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) { \
|
||||
return ((__PIObject__ *)__o__)->name(n0, n1); \
|
||||
} \
|
||||
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1) { \
|
||||
__PTYPE(a0) tv0 = __VVALUE(a0, v0); \
|
||||
__PTYPE(a1) tv1 = __VVALUE(a1, v1); \
|
||||
return ((__PIObject__*)__o__)->name(tv0, tv1);} \
|
||||
return ((__PIObject__ *)__o__)->name(tv0, tv1); \
|
||||
} \
|
||||
ret name(a0 n0, a1 n1)
|
||||
|
||||
# define EVENT_HANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \
|
||||
EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \
|
||||
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)__o__)->name(n0, n1, n2);} \
|
||||
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) { \
|
||||
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) { \
|
||||
return ((__PIObject__ *)__o__)->name(n0, n1, n2); \
|
||||
} \
|
||||
static ret __stat_eh_v_##name##__(void * __o__, \
|
||||
const PIVariantSimple & v0, \
|
||||
const PIVariantSimple & v1, \
|
||||
const PIVariantSimple & v2) { \
|
||||
__PTYPE(a0) tv0 = __VVALUE(a0, v0); \
|
||||
__PTYPE(a1) tv1 = __VVALUE(a1, v1); \
|
||||
__PTYPE(a2) tv2 = __VVALUE(a2, v2); \
|
||||
return ((__PIObject__*)__o__)->name(tv0, tv1, tv2);} \
|
||||
return ((__PIObject__ *)__o__)->name(tv0, tv1, tv2); \
|
||||
} \
|
||||
ret name(a0 n0, a1 n1, a2 n2)
|
||||
|
||||
# define EVENT_HANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
|
||||
EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
|
||||
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) {return ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \
|
||||
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) { \
|
||||
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) { \
|
||||
return ((__PIObject__ *)__o__)->name(n0, n1, n2, n3); \
|
||||
} \
|
||||
static ret __stat_eh_v_##name##__(void * __o__, \
|
||||
const PIVariantSimple & v0, \
|
||||
const PIVariantSimple & v1, \
|
||||
const PIVariantSimple & v2, \
|
||||
const PIVariantSimple & v3) { \
|
||||
__PTYPE(a0) tv0 = __VVALUE(a0, v0); \
|
||||
__PTYPE(a1) tv1 = __VVALUE(a1, v1); \
|
||||
__PTYPE(a2) tv2 = __VVALUE(a2, v2); \
|
||||
__PTYPE(a3) tv3 = __VVALUE(a3, v3); \
|
||||
return ((__PIObject__*)__o__)->name(tv0, tv1, tv2, tv3);} \
|
||||
return ((__PIObject__ *)__o__)->name(tv0, tv1, tv2, tv3); \
|
||||
} \
|
||||
ret name(a0 n0, a1 n1, a2 n2, a3 n3)
|
||||
|
||||
# define EVENT_HANDLER EVENT_HANDLER0
|
||||
@@ -551,58 +628,89 @@
|
||||
# define EVENT_VHANDLER0(ret, name) \
|
||||
EH_INIT0(ret, name) \
|
||||
static ret __stat_eh_##name##__(void * __o__) { \
|
||||
return ((__PIObject__*)__o__)->name();} \
|
||||
return ((__PIObject__ *)__o__)->name(); \
|
||||
} \
|
||||
virtual ret name()
|
||||
|
||||
# define EVENT_VHANDLER1(ret, name, a0, n0) \
|
||||
EH_INIT1(ret, name, a0, n0) \
|
||||
static ret __stat_eh_##name##__(void * __o__, a0 n0) { \
|
||||
return ((__PIObject__*)__o__)->name(n0);} \
|
||||
return ((__PIObject__ *)__o__)->name(n0); \
|
||||
} \
|
||||
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) { \
|
||||
return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0));} \
|
||||
return ((__PIObject__ *)__o__)->name(__VVALUE(a0, v0)); \
|
||||
} \
|
||||
virtual ret name(a0 n0)
|
||||
|
||||
# define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) \
|
||||
EH_INIT2(ret, name, a0, n0, a1, n1) \
|
||||
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) { \
|
||||
return ((__PIObject__*)__o__)->name(n0, n1);} \
|
||||
return ((__PIObject__ *)__o__)->name(n0, n1); \
|
||||
} \
|
||||
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1) { \
|
||||
return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1));} \
|
||||
return ((__PIObject__ *)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1)); \
|
||||
} \
|
||||
virtual ret name(a0 n0, a1 n1)
|
||||
|
||||
# define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \
|
||||
EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \
|
||||
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) { \
|
||||
return ((__PIObject__*)__o__)->name(n0, n1, n2);} \
|
||||
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) { \
|
||||
return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2));} \
|
||||
return ((__PIObject__ *)__o__)->name(n0, n1, n2); \
|
||||
} \
|
||||
static ret __stat_eh_v_##name##__(void * __o__, \
|
||||
const PIVariantSimple & v0, \
|
||||
const PIVariantSimple & v1, \
|
||||
const PIVariantSimple & v2) { \
|
||||
return ((__PIObject__ *)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2)); \
|
||||
} \
|
||||
virtual ret name(a0 n0, a1 n1, a2 n2)
|
||||
|
||||
# define EVENT_VHANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
|
||||
EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
|
||||
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) { \
|
||||
return ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \
|
||||
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) { \
|
||||
return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2), __VVALUE(a3, v3));} \
|
||||
return ((__PIObject__ *)__o__)->name(n0, n1, n2, n3); \
|
||||
} \
|
||||
static ret __stat_eh_v_##name##__(void * __o__, \
|
||||
const PIVariantSimple & v0, \
|
||||
const PIVariantSimple & v1, \
|
||||
const PIVariantSimple & v2, \
|
||||
const PIVariantSimple & v3) { \
|
||||
return ((__PIObject__ *)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2), __VVALUE(a3, v3)); \
|
||||
} \
|
||||
virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)
|
||||
|
||||
# define EVENT_VHANDLER EVENT_VHANDLER0
|
||||
|
||||
|
||||
#define EVENT0(name) EVENT_HANDLER0(void, name) { \
|
||||
static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid);}
|
||||
# define EVENT0(name) \
|
||||
EVENT_HANDLER0(void, name) { \
|
||||
static uint eid = PIStringAscii(#name).hash(); \
|
||||
PIObject::raiseEvent(this, eid); \
|
||||
}
|
||||
|
||||
#define EVENT1(name, a0, n0) EVENT_HANDLER1(void, name, a0, n0) { \
|
||||
static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0);}
|
||||
# define EVENT1(name, a0, n0) \
|
||||
EVENT_HANDLER1(void, name, a0, n0) { \
|
||||
static uint eid = PIStringAscii(#name).hash(); \
|
||||
PIObject::raiseEvent(this, eid, n0); \
|
||||
}
|
||||
|
||||
#define EVENT2(name, a0, n0, a1, n1) EVENT_HANDLER2(void, name, a0, n0, a1, n1) { \
|
||||
static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1);}
|
||||
# define EVENT2(name, a0, n0, a1, n1) \
|
||||
EVENT_HANDLER2(void, name, a0, n0, a1, n1) { \
|
||||
static uint eid = PIStringAscii(#name).hash(); \
|
||||
PIObject::raiseEvent(this, eid, n0, n1); \
|
||||
}
|
||||
|
||||
#define EVENT3(name, a0, n0, a1, n1, a2, n2) EVENT_HANDLER3(void, name, a0, n0, a1, n1, a2, n2) { \
|
||||
static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1, n2);}
|
||||
# define EVENT3(name, a0, n0, a1, n1, a2, n2) \
|
||||
EVENT_HANDLER3(void, name, a0, n0, a1, n1, a2, n2) { \
|
||||
static uint eid = PIStringAscii(#name).hash(); \
|
||||
PIObject::raiseEvent(this, eid, n0, n1, n2); \
|
||||
}
|
||||
|
||||
#define EVENT4(name, a0, n0, a1, n1, a2, n2, a3, n3) EVENT_HANDLER4(void, name, a0, n0, a1, n1, a2, n2, a3, n3) { \
|
||||
static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1, n2, n3);}
|
||||
# define EVENT4(name, a0, n0, a1, n1, a2, n2, a3, n3) \
|
||||
EVENT_HANDLER4(void, name, a0, n0, a1, n1, a2, n2, a3, n3) { \
|
||||
static uint eid = PIStringAscii(#name).hash(); \
|
||||
PIObject::raiseEvent(this, eid, n0, n1, n2, n3); \
|
||||
}
|
||||
|
||||
# define EVENT EVENT0
|
||||
|
||||
@@ -626,42 +734,107 @@
|
||||
|
||||
|
||||
# define CONNECT0(ret, src, event, dest, handler) \
|
||||
PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), \
|
||||
(void*)(void(*)(void*))(&(src)->__stat_eh_##event##__), 0, LOCATION);
|
||||
PIObject::piConnect(src, \
|
||||
PIStringAscii(#event), \
|
||||
dest, \
|
||||
dest, \
|
||||
(void *)(ret(*)(void *))(&(dest)->__stat_eh_##handler##__), \
|
||||
(void *)(void (*)(void *))(&(src)->__stat_eh_##event##__), \
|
||||
0, \
|
||||
LOCATION);
|
||||
|
||||
# define CONNECT1(ret, a0, src, event, dest, handler) \
|
||||
PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), \
|
||||
(void*)(void(*)(void*, a0))(&(src)->__stat_eh_##event##__), 1, LOCATION);
|
||||
PIObject::piConnect(src, \
|
||||
PIStringAscii(#event), \
|
||||
dest, \
|
||||
dest, \
|
||||
(void *)(ret(*)(void *, a0))(&(dest)->__stat_eh_##handler##__), \
|
||||
(void *)(void (*)(void *, a0))(&(src)->__stat_eh_##event##__), \
|
||||
1, \
|
||||
LOCATION);
|
||||
|
||||
# define CONNECT2(ret, a0, a1, src, event, dest, handler) \
|
||||
PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__), \
|
||||
(void*)(void(*)(void*, a0, a1))(&(src)->__stat_eh_##event##__), 2, LOCATION);
|
||||
PIObject::piConnect(src, \
|
||||
PIStringAscii(#event), \
|
||||
dest, \
|
||||
dest, \
|
||||
(void *)(ret(*)(void *, a0, a1))(&(dest)->__stat_eh_##handler##__), \
|
||||
(void *)(void (*)(void *, a0, a1))(&(src)->__stat_eh_##event##__), \
|
||||
2, \
|
||||
LOCATION);
|
||||
|
||||
# define CONNECT3(ret, a0, a1, a2, src, event, dest, handler) \
|
||||
PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), \
|
||||
(void*)(void(*)(void*, a0, a1, a2))(&(src)->__stat_eh_##event##__), 3, LOCATION);
|
||||
PIObject::piConnect(src, \
|
||||
PIStringAscii(#event), \
|
||||
dest, \
|
||||
dest, \
|
||||
(void *)(ret(*)(void *, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), \
|
||||
(void *)(void (*)(void *, a0, a1, a2))(&(src)->__stat_eh_##event##__), \
|
||||
3, \
|
||||
LOCATION);
|
||||
|
||||
# define CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) \
|
||||
PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), \
|
||||
(void*)(void(*)(void*, a0, a1, a2, a3))(&(src)->__stat_eh_##event##__), 4, LOCATION);
|
||||
PIObject::piConnect(src, \
|
||||
PIStringAscii(#event), \
|
||||
dest, \
|
||||
dest, \
|
||||
(void *)(ret(*)(void *, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), \
|
||||
(void *)(void (*)(void *, a0, a1, a2, a3))(&(src)->__stat_eh_##event##__), \
|
||||
4, \
|
||||
LOCATION);
|
||||
|
||||
# define CONNECT CONNECT0
|
||||
|
||||
|
||||
# define WEAK_CONNECT0(ret, src, event, dest, handler) \
|
||||
PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), 0, 0, LOCATION);
|
||||
PIObject::piConnect(src, \
|
||||
PIStringAscii(#event), \
|
||||
dest, \
|
||||
dest, \
|
||||
(void *)(ret(*)(void *))(&(dest)->__stat_eh_##handler##__), \
|
||||
0, \
|
||||
0, \
|
||||
LOCATION);
|
||||
|
||||
# define WEAK_CONNECT1(ret, a0, src, event, dest, handler) \
|
||||
PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), 0, 1, LOCATION);
|
||||
PIObject::piConnect(src, \
|
||||
PIStringAscii(#event), \
|
||||
dest, \
|
||||
dest, \
|
||||
(void *)(ret(*)(void *, a0))(&(dest)->__stat_eh_##handler##__), \
|
||||
0, \
|
||||
1, \
|
||||
LOCATION);
|
||||
|
||||
# define WEAK_CONNECT2(ret, a0, a1, src, event, dest, handler) \
|
||||
PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__), 0, 2, LOCATION);
|
||||
PIObject::piConnect(src, \
|
||||
PIStringAscii(#event), \
|
||||
dest, \
|
||||
dest, \
|
||||
(void *)(ret(*)(void *, a0, a1))(&(dest)->__stat_eh_##handler##__), \
|
||||
0, \
|
||||
2, \
|
||||
LOCATION);
|
||||
|
||||
# define WEAK_CONNECT3(ret, a0, a1, a2, src, event, dest, handler) \
|
||||
PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), 0, 3, LOCATION);
|
||||
PIObject::piConnect(src, \
|
||||
PIStringAscii(#event), \
|
||||
dest, \
|
||||
dest, \
|
||||
(void *)(ret(*)(void *, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), \
|
||||
0, \
|
||||
3, \
|
||||
LOCATION);
|
||||
|
||||
# define WEAK_CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) \
|
||||
PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), 0, 4, LOCATION);
|
||||
PIObject::piConnect(src, \
|
||||
PIStringAscii(#event), \
|
||||
dest, \
|
||||
dest, \
|
||||
(void *)(ret(*)(void *, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), \
|
||||
0, \
|
||||
4, \
|
||||
LOCATION);
|
||||
|
||||
# define WEAK_CONNECT WEAK_CONNECT0
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
// # endif
|
||||
# include <synchapi.h>
|
||||
#else
|
||||
# include <errno.h>
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include "pistring.h"
|
||||
|
||||
@@ -45,7 +45,8 @@ void PIWaitEvent::create() {
|
||||
piCout << "Error with CreateEventA:" << errorString();
|
||||
}
|
||||
#else
|
||||
for (int i = 0; i < 3; ++i) memset(&(fds[i]), 0, sizeof(fds[i]));
|
||||
for (int i = 0; i < 3; ++i)
|
||||
memset(&(fds[i]), 0, sizeof(fds[i]));
|
||||
if (::pipe(pipe_fd) < 0) {
|
||||
piCout << "Error with pipe:" << errorString();
|
||||
} else {
|
||||
@@ -82,13 +83,15 @@ bool PIWaitEvent::wait(int fd, CheckRole role) {
|
||||
if (fd == -1) return false;
|
||||
int nfds = piMaxi(pipe_fd[ReadEnd], fd) + 1;
|
||||
int fd_index = role;
|
||||
for (int i = 0; i < 3; ++i) FD_ZERO(&(fds[i]));
|
||||
for (int i = 0; i < 3; ++i)
|
||||
FD_ZERO(&(fds[i]));
|
||||
FD_SET(pipe_fd[ReadEnd], &(fds[CheckRead]));
|
||||
FD_SET(fd, &(fds[CheckExeption]));
|
||||
if (fd_index != CheckExeption) FD_SET(fd, &(fds[fd_index]));
|
||||
int sr = ::select(nfds, &(fds[CheckRead]), &(fds[CheckWrite]), &(fds[CheckExeption]), nullptr);
|
||||
int buf = 0;
|
||||
while (::read(pipe_fd[ReadEnd], &buf, sizeof(buf)) > 0);
|
||||
while (::read(pipe_fd[ReadEnd], &buf, sizeof(buf)) > 0)
|
||||
;
|
||||
// piCout << "wait result" << sr << FD_ISSET(fd, &(fds[CheckExeption])) << FD_ISSET(fd, &(fds[fd_index]));
|
||||
if (sr == EBADF || sr == EINTR) return false;
|
||||
if (FD_ISSET(fd, &(fds[CheckExeption]))) return true;
|
||||
@@ -113,7 +116,8 @@ bool PIWaitEvent::sleep(int us) {
|
||||
timeout.tv_usec = us % 1000000;
|
||||
int ret = ::select(nfds, &(fds[CheckRead]), nullptr, nullptr, &timeout);
|
||||
int buf = 0;
|
||||
while (::read(pipe_fd[ReadEnd], &buf, sizeof(buf)) > 0);
|
||||
while (::read(pipe_fd[ReadEnd], &buf, sizeof(buf)) > 0)
|
||||
;
|
||||
return ret == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -21,14 +21,16 @@
|
||||
#define PIWAITEVENT_P_H
|
||||
|
||||
#include "pibase.h"
|
||||
// clang-format off
|
||||
#ifdef WINDOWS
|
||||
# include <stdarg.h>
|
||||
# include <windef.h>
|
||||
# include <winbase.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <sys/select.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
|
||||
class PIP_EXPORT PIWaitEvent {
|
||||
@@ -60,7 +62,6 @@ private:
|
||||
WriteEnd = 1
|
||||
};
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -26,16 +26,23 @@
|
||||
#ifndef PIAUTH_H
|
||||
#define PIAUTH_H
|
||||
|
||||
#include "pip_crypt_export.h"
|
||||
#include "piobject.h"
|
||||
#include "picrypt.h"
|
||||
#include "piobject.h"
|
||||
#include "pip_crypt_export.h"
|
||||
|
||||
|
||||
class PIP_CRYPT_EXPORT PIAuth : public PIObject
|
||||
{
|
||||
class PIP_CRYPT_EXPORT PIAuth: public PIObject {
|
||||
PIOBJECT(PIAuth)
|
||||
|
||||
public:
|
||||
enum State {NotConnected, AuthProbe, PassRequest, AuthReply, KeyExchange, Connected};
|
||||
enum State {
|
||||
NotConnected,
|
||||
AuthProbe,
|
||||
PassRequest,
|
||||
AuthReply,
|
||||
KeyExchange,
|
||||
Connected
|
||||
};
|
||||
|
||||
//! Create PIAuth with your digital sign
|
||||
PIAuth(const PIByteArray & sign);
|
||||
@@ -91,7 +98,10 @@ public:
|
||||
EVENT1(passwordCheck, bool, result);
|
||||
|
||||
private:
|
||||
enum Role {Client, Server};
|
||||
enum Role {
|
||||
Client,
|
||||
Server
|
||||
};
|
||||
|
||||
State disconnect(PIByteArray & ba, const PIString & error = PIString());
|
||||
bool isAuthorizedKey(const PIByteArray & pkey);
|
||||
|
||||
@@ -120,7 +120,6 @@ private:
|
||||
static bool init();
|
||||
|
||||
PIByteArray nonce_, key_;
|
||||
|
||||
};
|
||||
|
||||
#endif // PICRYPT_H
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
#ifndef PICRYPTMODULE_H
|
||||
#define PICRYPTMODULE_H
|
||||
|
||||
#include "picrypt.h"
|
||||
#include "piauth.h"
|
||||
#include "picrypt.h"
|
||||
|
||||
#endif // PICRYPTMODULE_H
|
||||
|
||||
@@ -63,4 +63,3 @@ PIEllipsoidModel PIEllipsoidModel::KrasovskiyEllipsoid() {
|
||||
v.angVelocity = 7.292115e-5;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,5 +47,4 @@ public:
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // PIELLIPSOIDMODEL_H
|
||||
|
||||
@@ -48,11 +48,11 @@ PIGeoPosition &PIGeoPosition::transformTo(PIGeoPosition::CoordinateSystem sys) {
|
||||
if (sys == Unknown || sys == s) return *this;
|
||||
PIGeoPosition tmp(*this);
|
||||
switch (s) {
|
||||
case Unknown:
|
||||
return *this;
|
||||
case Unknown: return *this;
|
||||
case Geodetic:
|
||||
switch (sys) {
|
||||
case Unknown: case Geodetic: return *this;
|
||||
case Unknown:
|
||||
case Geodetic: return *this;
|
||||
case Geocentric:
|
||||
convertGeodeticToGeocentric(*this, tmp, el);
|
||||
tmp.s = Geocentric;
|
||||
@@ -70,7 +70,8 @@ PIGeoPosition &PIGeoPosition::transformTo(PIGeoPosition::CoordinateSystem sys) {
|
||||
break;
|
||||
case Geocentric:
|
||||
switch (sys) {
|
||||
case Unknown: case Geocentric: return *this;
|
||||
case Unknown:
|
||||
case Geocentric: return *this;
|
||||
case Geodetic:
|
||||
convertGeocentricToGeodetic(*this, tmp, el);
|
||||
tmp.s = Geodetic;
|
||||
@@ -87,7 +88,8 @@ PIGeoPosition &PIGeoPosition::transformTo(PIGeoPosition::CoordinateSystem sys) {
|
||||
break;
|
||||
case Cartesian:
|
||||
switch (sys) {
|
||||
case Unknown: case Cartesian: return *this;
|
||||
case Unknown:
|
||||
case Cartesian: return *this;
|
||||
case Geodetic:
|
||||
convertCartesianToGeodetic(*this, tmp, el);
|
||||
tmp.s = Geodetic;
|
||||
@@ -104,7 +106,8 @@ PIGeoPosition &PIGeoPosition::transformTo(PIGeoPosition::CoordinateSystem sys) {
|
||||
break;
|
||||
case Spherical:
|
||||
switch (sys) {
|
||||
case Unknown: case Spherical: return *this;
|
||||
case Unknown:
|
||||
case Spherical: return *this;
|
||||
case Geodetic:
|
||||
(*this)[0] = 90 - (*this)[0]; // sph -> geocen
|
||||
convertGeocentricToGeodetic(*this, tmp, el);
|
||||
@@ -206,8 +209,10 @@ PIGeoPosition &PIGeoPosition::setGeodetic(double lat, double lon, double ht, PIE
|
||||
assertm(lat <= 90 && lat >= -90, "Achtung! Invalid latitude in setGeodetic");
|
||||
(*this)[0] = lat;
|
||||
(*this)[1] = lon;
|
||||
if((*this)[1] < 0) (*this)[1] += 360 * (1 + (unsigned long)((*this)[1]/360));
|
||||
else if((*this)[1] >= 360) (*this)[1] -= 360 * (unsigned long)((*this)[1]/360);
|
||||
if ((*this)[1] < 0)
|
||||
(*this)[1] += 360 * (1 + (unsigned long)((*this)[1] / 360));
|
||||
else if ((*this)[1] >= 360)
|
||||
(*this)[1] -= 360 * (unsigned long)((*this)[1] / 360);
|
||||
(*this)[2] = ht;
|
||||
el = ell;
|
||||
s = Geodetic;
|
||||
@@ -221,8 +226,10 @@ PIGeoPosition &PIGeoPosition::setGeocentric(double lat, double lon, double rad)
|
||||
(*this)[0] = lat;
|
||||
(*this)[1] = lon;
|
||||
(*this)[2] = rad;
|
||||
if((*this)[1] < 0) (*this)[1] += 360*(1+(unsigned long)((*this)[1]/360));
|
||||
else if((*this)[1] >= 360) (*this)[1] -= 360*(unsigned long)((*this)[1]/360);
|
||||
if ((*this)[1] < 0)
|
||||
(*this)[1] += 360 * (1 + (unsigned long)((*this)[1] / 360));
|
||||
else if ((*this)[1] >= 360)
|
||||
(*this)[1] -= 360 * (unsigned long)((*this)[1] / 360);
|
||||
s = Geocentric;
|
||||
return *this;
|
||||
}
|
||||
@@ -234,8 +241,10 @@ PIGeoPosition &PIGeoPosition::setSpherical(double theta, double phi, double rad)
|
||||
(*this)[0] = theta;
|
||||
(*this)[1] = phi;
|
||||
(*this)[2] = rad;
|
||||
if((*this)[1] < 0) (*this)[1] += 360*(1+(unsigned long)((*this)[1]/360));
|
||||
else if((*this)[1] >= 360) (*this)[1] -= 360*(unsigned long)((*this)[1]/360);
|
||||
if ((*this)[1] < 0)
|
||||
(*this)[1] += 360 * (1 + (unsigned long)((*this)[1] / 360));
|
||||
else if ((*this)[1] >= 360)
|
||||
(*this)[1] -= 360 * (unsigned long)((*this)[1] / 360);
|
||||
s = Spherical;
|
||||
return *this;
|
||||
}
|
||||
@@ -330,13 +339,16 @@ void PIGeoPosition::convertGeocentricToGeodetic(const PIMathVectorT3d &llr, PIMa
|
||||
llh[1] = llr[1]; // longitude is unchanged
|
||||
cl = sin(toRad(90.0 - llr[0]));
|
||||
sl = cos(toRad(90.0 - llr[0]));
|
||||
if(llr[2] <= PIGeoPosition::position_tolerance / 5) { // radius is below tolerance, hence assign zero-length, arbitrarily set latitude = longitude = 0
|
||||
if (llr[2] <= PIGeoPosition::position_tolerance /
|
||||
5) { // radius is below tolerance, hence assign zero-length, arbitrarily set latitude = longitude = 0
|
||||
llh[0] = llh[1] = 0.0;
|
||||
llh[2] = -ell.a;
|
||||
return;
|
||||
} else if (cl < 1.e-10) { // near pole ... note that 1mm/radius(Earth) = 1.5e-10
|
||||
if(llr[0] < 0.0) llh[0] = -90.0;
|
||||
else llh[0] = 90.0;
|
||||
if (llr[0] < 0.0)
|
||||
llh[0] = -90.0;
|
||||
else
|
||||
llh[0] = 90.0;
|
||||
llh[1] = 0.0;
|
||||
llh[2] = llr[2] - ell.a * sqrt(1.0 - ell.eccSquared());
|
||||
return;
|
||||
@@ -361,14 +373,17 @@ void PIGeoPosition::convertGeodeticToGeocentric(const PIMathVectorT3d &llh, PIMa
|
||||
double slat = sin(toRad(llh[0]));
|
||||
double nn = ell.a / sqrt(1.0 - ell.eccSquared() * slat * slat);
|
||||
llr[1] = llh[1]; // longitude is unchanged
|
||||
llr[2] = sqrt((nn+llh[2])*(nn+llh[2]) + nn*ell.eccSquared()*(nn*ell.eccSquared()-2*(nn+llh[2]))*slat*slat); // radius
|
||||
llr[2] =
|
||||
sqrt((nn + llh[2]) * (nn + llh[2]) + nn * ell.eccSquared() * (nn * ell.eccSquared() - 2 * (nn + llh[2])) * slat * slat); // radius
|
||||
if (llr[2] <= PIGeoPosition::position_tolerance / 5) { // radius is below tolerance, hence assign zero-length
|
||||
llr[0] = llr[1] = llr[2] = 0; // arbitrarily set latitude = longitude = 0
|
||||
return;
|
||||
}
|
||||
if (1 - piAbsd(slat) < 1.e-10) { // at the pole
|
||||
if(slat < 0) llr[0] = -90.0;
|
||||
else llr[0] = 90.0;
|
||||
if (slat < 0)
|
||||
llr[0] = -90.0;
|
||||
else
|
||||
llr[0] = 90.0;
|
||||
llr[1] = 0.0;
|
||||
return;
|
||||
}
|
||||
@@ -416,8 +431,10 @@ PIGeoPosition &PIGeoPosition::operator+=(const PIGeoPosition &right) {
|
||||
|
||||
bool PIGeoPosition::operator==(const PIGeoPosition & right) const {
|
||||
if (el.a != right.el.a || el.eccSquared() != right.el.eccSquared()) return false;
|
||||
if(range(*this, right) < position_tolerance) return true;
|
||||
else return false;
|
||||
if (range(*this, right) < position_tolerance)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -425,16 +442,20 @@ void PIGeoPosition::initialize(PIMathVectorT3d v, PIGeoPosition::CoordinateSyste
|
||||
double a(v[0]), b(v[1]), c(v[2]);
|
||||
if (sys == Geodetic || sys == Geocentric) {
|
||||
assertm(a <= 90 && a >= -90, "Achtung! Invalid latitude in constructor");
|
||||
if(b < 0) b += 360*(1+(unsigned long)(b/360));
|
||||
else if(b >= 360) b -= 360*(unsigned long)(b/360);
|
||||
if (b < 0)
|
||||
b += 360 * (1 + (unsigned long)(b / 360));
|
||||
else if (b >= 360)
|
||||
b -= 360 * (unsigned long)(b / 360);
|
||||
}
|
||||
if (sys == Geocentric || sys == Spherical) {
|
||||
assertm(c >= 0, "Achtung! Invalid radius in constructor");
|
||||
}
|
||||
if (sys == Spherical) {
|
||||
assertm(a >= 0 && a <= 180, "Achtung! Invalid theta in constructor");
|
||||
if(b < 0) b += 360*(1+(unsigned long)(b/360));
|
||||
else if(b >= 360) b -= 360*(unsigned long)(b/360);
|
||||
if (b < 0)
|
||||
b += 360 * (1 + (unsigned long)(b / 360));
|
||||
else if (b >= 360)
|
||||
b -= 360 * (unsigned long)(b / 360);
|
||||
}
|
||||
(*this)[0] = a;
|
||||
(*this)[1] = b;
|
||||
@@ -506,8 +527,10 @@ double PIGeoPosition::azimuth(const PIGeoPosition &p) const {
|
||||
p2 = (xe1 * z1) + (xe2 * z2);
|
||||
assertm((piAbsd(p1) + piAbsd(p2)) >= 1.0e-16, "azAngle(), failed p1+p2 test");
|
||||
alpha = 90 - toDeg(atan2(p1, p2));
|
||||
if (alpha < 0) return alpha + 360;
|
||||
else return alpha;
|
||||
if (alpha < 0)
|
||||
return alpha + 360;
|
||||
else
|
||||
return alpha;
|
||||
}
|
||||
|
||||
|
||||
@@ -533,8 +556,10 @@ double PIGeoPosition::azimuthGeodetic(const PIGeoPosition &p) const {
|
||||
double test = piAbsd(local_n) + piAbsd(local_e); // Let's test if computing azimuth has any sense
|
||||
if (test < 1.0e-16) return 0.0; // Warning: If elevation is very close to 90 degrees, we will return azimuth = 0.0
|
||||
double alpha = toDeg(atan2(local_e, local_n));
|
||||
if (alpha < 0.0) return alpha + 360.0;
|
||||
else return alpha;
|
||||
if (alpha < 0.0)
|
||||
return alpha + 360.0;
|
||||
else
|
||||
return alpha;
|
||||
}
|
||||
|
||||
double PIGeoPosition::getCurvMeridian() const {
|
||||
@@ -548,4 +573,3 @@ double PIGeoPosition::getCurvPrimeVertical() const {
|
||||
double slat = sin(toRad(latitudeGeodetic()));
|
||||
return el.a / sqrt(1.0 - el.eccSquared() * slat * slat);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,10 +29,8 @@
|
||||
#include "piellipsoidmodel.h"
|
||||
#include "pimathvector.h"
|
||||
|
||||
class PIP_EXPORT PIGeoPosition : public PIMathVectorT3d
|
||||
{
|
||||
class PIP_EXPORT PIGeoPosition: public PIMathVectorT3d {
|
||||
public:
|
||||
|
||||
enum CoordinateSystem {
|
||||
Unknown = 0, /// Unknown coordinate system
|
||||
Geodetic, /// Geodetic latitude, longitude, and height above ellipsoid
|
||||
@@ -45,7 +43,10 @@ public:
|
||||
static const double one_mm_tolerance; /// One millimeter tolerance.
|
||||
static const double one_um_tolerance; /// One micron tolerance.
|
||||
static double position_tolerance; /// Default tolerance (default 1mm)
|
||||
static double setPositionTolerance(const double tol) {position_tolerance = tol; return position_tolerance;}
|
||||
static double setPositionTolerance(const double tol) {
|
||||
position_tolerance = tol;
|
||||
return position_tolerance;
|
||||
}
|
||||
static double getPositionTolerance() { return position_tolerance; }
|
||||
|
||||
PIGeoPosition();
|
||||
@@ -54,9 +55,19 @@ public:
|
||||
|
||||
|
||||
PIGeoPosition & transformTo(CoordinateSystem sys);
|
||||
PIGeoPosition &asGeodetic() {transformTo(Geodetic); return *this; } /// Convert to geodetic coordinate
|
||||
PIGeoPosition &asGeodetic(const PIEllipsoidModel &ell) {setEllipsoidModel(ell); transformTo(Geodetic); return *this;} /// Convert to another ell, then to geodetic coordinates
|
||||
PIGeoPosition &asECEF() {transformTo(Cartesian); return *this; } /// Convert to cartesian coordinates
|
||||
PIGeoPosition & asGeodetic() {
|
||||
transformTo(Geodetic);
|
||||
return *this;
|
||||
} /// Convert to geodetic coordinate
|
||||
PIGeoPosition & asGeodetic(const PIEllipsoidModel & ell) {
|
||||
setEllipsoidModel(ell);
|
||||
transformTo(Geodetic);
|
||||
return *this;
|
||||
} /// Convert to another ell, then to geodetic coordinates
|
||||
PIGeoPosition & asECEF() {
|
||||
transformTo(Cartesian);
|
||||
return *this;
|
||||
} /// Convert to cartesian coordinates
|
||||
|
||||
double x() const;
|
||||
double y() const;
|
||||
@@ -91,10 +102,14 @@ public:
|
||||
static void convertCartesianToSpherical(const PIMathVectorT3d & xyz, PIMathVectorT3d & tpr);
|
||||
|
||||
/// Fundamental routine to convert ECEF (cartesian) to geodetic coordinates,
|
||||
static void convertCartesianToGeodetic(const PIMathVectorT3d &xyz, PIMathVectorT3d &llh, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||
static void convertCartesianToGeodetic(const PIMathVectorT3d & xyz,
|
||||
PIMathVectorT3d & llh,
|
||||
PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||
|
||||
/// Fundamental routine to convert geodetic to ECEF (cartesian) coordinates,
|
||||
static void convertGeodeticToCartesian(const PIMathVectorT3d &llh, PIMathVectorT3d &xyz, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||
static void convertGeodeticToCartesian(const PIMathVectorT3d & llh,
|
||||
PIMathVectorT3d & xyz,
|
||||
PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||
|
||||
/// Fundamental routine to convert cartesian (ECEF) to geocentric
|
||||
static void convertCartesianToGeocentric(const PIMathVectorT3d & xyz, PIMathVectorT3d & llr);
|
||||
@@ -103,10 +118,14 @@ public:
|
||||
static void convertGeocentricToCartesian(const PIMathVectorT3d & llr, PIMathVectorT3d & xyz);
|
||||
|
||||
/// Fundamental routine to convert geocentric to geodetic
|
||||
static void convertGeocentricToGeodetic(const PIMathVectorT3d &llr, PIMathVectorT3d &llh, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||
static void convertGeocentricToGeodetic(const PIMathVectorT3d & llr,
|
||||
PIMathVectorT3d & llh,
|
||||
PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||
|
||||
/// Fundamental routine to convert geodetic to geocentric
|
||||
static void convertGeodeticToGeocentric(const PIMathVectorT3d &llh, PIMathVectorT3d &llr, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||
static void convertGeodeticToGeocentric(const PIMathVectorT3d & llh,
|
||||
PIMathVectorT3d & llr,
|
||||
PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||
|
||||
/// Compute the radius of the ellipsoidal Earth, given the geodetic latitude.
|
||||
static double radiusEarth(double geolat, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||
@@ -118,9 +137,7 @@ public:
|
||||
|
||||
/// Compute the range in meters between two PIGeoPositions.
|
||||
static double range(const PIGeoPosition & a, const PIGeoPosition & b);
|
||||
double range(const PIGeoPosition &p) const {
|
||||
return range((*this), p);
|
||||
}
|
||||
double range(const PIGeoPosition & p) const { return range((*this), p); }
|
||||
|
||||
/// Computes the elevation of the input (p) position as seen from this PIGeoPosition.
|
||||
double elevation(const PIGeoPosition & p) const;
|
||||
@@ -161,15 +178,36 @@ private:
|
||||
|
||||
PIEllipsoidModel el;
|
||||
CoordinateSystem s;
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline PIGeoPosition operator-(const PIGeoPosition &left, const PIGeoPosition &right) {PIGeoPosition l(left),r(right); l.transformTo(PIGeoPosition::Cartesian); r.transformTo(PIGeoPosition::Cartesian); l -= r; return l;}
|
||||
inline PIGeoPosition operator+(const PIGeoPosition &left, const PIGeoPosition &right) {PIGeoPosition l(left),r(right); l.transformTo(PIGeoPosition::Cartesian); r.transformTo(PIGeoPosition::Cartesian); l += r; return l;}
|
||||
inline PIGeoPosition operator*(const double &scale, const PIGeoPosition &right) {PIMathVectorT3d tmp(right); tmp *= scale; return PIGeoPosition(tmp);}
|
||||
inline PIGeoPosition operator*(const PIGeoPosition &left, const double &scale) {return operator* (scale, left);}
|
||||
inline PIGeoPosition operator*(const int &scale, const PIGeoPosition &right) {return operator* (double(scale), right);}
|
||||
inline PIGeoPosition operator*(const PIGeoPosition &left, const int &scale) {return operator* (double(scale), left);}
|
||||
inline PIGeoPosition operator-(const PIGeoPosition & left, const PIGeoPosition & right) {
|
||||
PIGeoPosition l(left), r(right);
|
||||
l.transformTo(PIGeoPosition::Cartesian);
|
||||
r.transformTo(PIGeoPosition::Cartesian);
|
||||
l -= r;
|
||||
return l;
|
||||
}
|
||||
inline PIGeoPosition operator+(const PIGeoPosition & left, const PIGeoPosition & right) {
|
||||
PIGeoPosition l(left), r(right);
|
||||
l.transformTo(PIGeoPosition::Cartesian);
|
||||
r.transformTo(PIGeoPosition::Cartesian);
|
||||
l += r;
|
||||
return l;
|
||||
}
|
||||
inline PIGeoPosition operator*(const double & scale, const PIGeoPosition & right) {
|
||||
PIMathVectorT3d tmp(right);
|
||||
tmp *= scale;
|
||||
return PIGeoPosition(tmp);
|
||||
}
|
||||
inline PIGeoPosition operator*(const PIGeoPosition & left, const double & scale) {
|
||||
return operator*(scale, left);
|
||||
}
|
||||
inline PIGeoPosition operator*(const int & scale, const PIGeoPosition & right) {
|
||||
return operator*(double(scale), right);
|
||||
}
|
||||
inline PIGeoPosition operator*(const PIGeoPosition & left, const int & scale) {
|
||||
return operator*(double(scale), left);
|
||||
}
|
||||
|
||||
#endif // PIGEOPOSITION_H
|
||||
|
||||
@@ -61,8 +61,7 @@ class PIIntrospection;
|
||||
class PIIntrospectionServer;
|
||||
|
||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
#define __PIINTROSPECTION_SINGLETON_H__(T) \
|
||||
static PIIntrospection##T##Interface * instance();
|
||||
# define __PIINTROSPECTION_SINGLETON_H__(T) static PIIntrospection##T##Interface * instance();
|
||||
|
||||
# define __PIINTROSPECTION_SINGLETON_CPP__(T) \
|
||||
PIIntrospection##T##Interface * PIIntrospection##T##Interface::instance() { \
|
||||
|
||||
@@ -42,7 +42,9 @@ const char * demangle(const char * name) {
|
||||
return name;
|
||||
}
|
||||
# else
|
||||
const char * demangle(const char * name) {return name;}
|
||||
const char * demangle(const char * name) {
|
||||
return name;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
@@ -53,8 +55,7 @@ void PIIntrospectionContainersType::finish() {
|
||||
return;
|
||||
}
|
||||
size_t l = strlen(name);
|
||||
if (l > 0)
|
||||
id = piHashData((const uchar*)name, int(l));
|
||||
if (l > 0) id = piHashData((const uchar *)name, int(l));
|
||||
demangled = demangle(name);
|
||||
has_demangled = name != demangled;
|
||||
// printf("create typeinfo for %s -> %s\n", name, demangled);
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
*/
|
||||
|
||||
#include "piintrospection_containers_p.h"
|
||||
|
||||
#include "piintrospection_containers.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
@@ -20,9 +20,10 @@
|
||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
|
||||
# include "piintrospection_server.h"
|
||||
|
||||
# include "pichunkstream.h"
|
||||
# include "piintrospection_server_p.h"
|
||||
# include "piprocess.h"
|
||||
#include "pichunkstream.h"
|
||||
|
||||
|
||||
PRIVATE_DEFINITION_START(PIIntrospectionServer)
|
||||
@@ -39,8 +40,7 @@ PIIntrospectionServer::PIIntrospectionServer(): PIPeer(genName()) {
|
||||
PIIntrospectionServer::~PIIntrospectionServer() {
|
||||
PIPeer::stop();
|
||||
if (sysmon)
|
||||
if (sysmon->property("__iserver__").toBool())
|
||||
delete sysmon;
|
||||
if (sysmon->property("__iserver__").toBool()) delete sysmon;
|
||||
sysmon = 0;
|
||||
}
|
||||
|
||||
@@ -78,24 +78,21 @@ PIString PIIntrospectionServer::genName() {
|
||||
void PIIntrospectionServer::dataReceived(const PIString & from, const PIByteArray & data) {
|
||||
if (data.size() < 8) return;
|
||||
PIByteArray rba(data);
|
||||
uint _sign(0); rba >> _sign;
|
||||
uint _sign(0);
|
||||
rba >> _sign;
|
||||
if (_sign != PIIntrospection::sign) return;
|
||||
PIIntrospection::RequiredInfo ri;
|
||||
rba >> ri;
|
||||
PIChunkStream cs;
|
||||
if (ri.types[PIIntrospection::itInfo])
|
||||
cs.add(PIIntrospection::itInfo, PIIntrospection::packInfo());
|
||||
if (ri.types[PIIntrospection::itInfo]) cs.add(PIIntrospection::itInfo, PIIntrospection::packInfo());
|
||||
if (ri.types[PIIntrospection::itProcStat]) {
|
||||
sysmon_mutex.lock();
|
||||
cs.add(PIIntrospection::itProcStat, PIIntrospection::packProcStat(sysmon));
|
||||
sysmon_mutex.unlock();
|
||||
}
|
||||
if (ri.types[PIIntrospection::itContainers])
|
||||
cs.add(PIIntrospection::itContainers, PIIntrospection::packContainers());
|
||||
if (ri.types[PIIntrospection::itObjects])
|
||||
cs.add(PIIntrospection::itObjects, PIIntrospection::packObjects());
|
||||
if (ri.types[PIIntrospection::itThreads])
|
||||
cs.add(PIIntrospection::itThreads, PIIntrospection::packThreads());
|
||||
if (ri.types[PIIntrospection::itContainers]) cs.add(PIIntrospection::itContainers, PIIntrospection::packContainers());
|
||||
if (ri.types[PIIntrospection::itObjects]) cs.add(PIIntrospection::itObjects, PIIntrospection::packObjects());
|
||||
if (ri.types[PIIntrospection::itThreads]) cs.add(PIIntrospection::itThreads, PIIntrospection::packThreads());
|
||||
PIByteArray ba;
|
||||
ba << PIIntrospection::sign;
|
||||
ba.append(cs.data());
|
||||
|
||||
@@ -47,6 +47,7 @@ class PISystemMonitor;
|
||||
|
||||
class PIP_EXPORT PIIntrospectionServer: public PIPeer {
|
||||
PIOBJECT_SUBCLASS(PIIntrospectionServer, PIPeer);
|
||||
|
||||
public:
|
||||
static PIIntrospectionServer * instance();
|
||||
|
||||
@@ -65,7 +66,6 @@ private:
|
||||
PITimer itimer;
|
||||
PISystemMonitor * sysmon;
|
||||
PIMutex sysmon_mutex;
|
||||
|
||||
};
|
||||
|
||||
# else
|
||||
|
||||
@@ -18,10 +18,11 @@
|
||||
*/
|
||||
|
||||
#include "piintrospection_server_p.h"
|
||||
|
||||
#include "pichunkstream.h"
|
||||
#include "piinit.h"
|
||||
#include "pisysteminfo.h"
|
||||
#include "piobject.h"
|
||||
#include "pisysteminfo.h"
|
||||
|
||||
|
||||
const uint PIIntrospection::sign = 0x0F1C2B3A;
|
||||
@@ -77,8 +78,6 @@ PIVector<PIIntrospection::ObjectInfo> PIIntrospection::getObjects() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PIByteArray PIIntrospection::packInfo() {
|
||||
PIByteArray ret;
|
||||
ret << getInfo();
|
||||
|
||||
@@ -20,17 +20,16 @@
|
||||
#ifndef PIINTROSPECTION_SERVER_P_H
|
||||
#define PIINTROSPECTION_SERVER_P_H
|
||||
|
||||
#include "pichunkstream.h"
|
||||
#include "piintrospection_containers.h"
|
||||
#include "piintrospection_containers_p.h"
|
||||
#include "piintrospection_threads.h"
|
||||
#include "piintrospection_threads_p.h"
|
||||
#include "pichunkstream.h"
|
||||
#include "pisystemmonitor.h"
|
||||
|
||||
|
||||
class PIP_EXPORT PIIntrospection {
|
||||
public:
|
||||
|
||||
enum InfoTypes {
|
||||
itInfo = 0x01,
|
||||
itProcStat = 0x02,
|
||||
@@ -89,7 +88,6 @@ public:
|
||||
|
||||
static PIByteArray packObjects();
|
||||
static void unpackObjects(PIByteArray & ba, PIVector<PIIntrospection::ObjectInfo> & objects);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -100,7 +98,8 @@ BINARY_STREAM_WRITE(PIIntrospection::RequiredInfo) {
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ(PIIntrospection::RequiredInfo) {
|
||||
PIByteArray csba; s >> csba;
|
||||
PIByteArray csba;
|
||||
s >> csba;
|
||||
PIChunkStream cs(csba);
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
@@ -113,13 +112,21 @@ BINARY_STREAM_READ(PIIntrospection::RequiredInfo) {
|
||||
|
||||
BINARY_STREAM_WRITE(PIIntrospection::ProcessInfo) {
|
||||
PIChunkStream cs;
|
||||
cs.add(1, v.architecture).add(2, v.execCommand).add(3, v.execDateTime).add(4, v.hostname).add(5, v.OS_name)
|
||||
.add(6, v.OS_version).add(7, v.processorsCount).add(8, v.user).add(9, v.build_options);
|
||||
cs.add(1, v.architecture)
|
||||
.add(2, v.execCommand)
|
||||
.add(3, v.execDateTime)
|
||||
.add(4, v.hostname)
|
||||
.add(5, v.OS_name)
|
||||
.add(6, v.OS_version)
|
||||
.add(7, v.processorsCount)
|
||||
.add(8, v.user)
|
||||
.add(9, v.build_options);
|
||||
s << cs.data();
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ(PIIntrospection::ProcessInfo) {
|
||||
PIByteArray csba; s >> csba;
|
||||
PIByteArray csba;
|
||||
s >> csba;
|
||||
PIChunkStream cs(csba);
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
@@ -145,7 +152,8 @@ BINARY_STREAM_WRITE(PIIntrospection::ObjectInfo) {
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ(PIIntrospection::ObjectInfo) {
|
||||
PIByteArray csba; s >> csba;
|
||||
PIByteArray csba;
|
||||
s >> csba;
|
||||
PIChunkStream cs(csba);
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
|
||||
# include "piintrospection_threads.h"
|
||||
|
||||
# include "piintrospection_threads_p.h"
|
||||
|
||||
__PIINTROSPECTION_SINGLETON_CPP__(Threads)
|
||||
|
||||
@@ -28,7 +28,6 @@ class PIIntrospectionThreads;
|
||||
|
||||
# define PIINTROSPECTION_THREADS (PIIntrospectionThreadsInterface::instance())
|
||||
|
||||
// clang-format off
|
||||
# define PIINTROSPECTION_THREAD_NEW(t) PIINTROSPECTION_THREADS->threadNew(t);
|
||||
# define PIINTROSPECTION_THREAD_DELETE(t) PIINTROSPECTION_THREADS->threadDelete(t);
|
||||
# define PIINTROSPECTION_THREAD_START(t) PIINTROSPECTION_THREADS->threadStart(t);
|
||||
@@ -36,7 +35,6 @@ class PIIntrospectionThreads;
|
||||
# define PIINTROSPECTION_THREAD_WAIT(t) PIINTROSPECTION_THREADS->threadWait(t);
|
||||
# define PIINTROSPECTION_THREAD_STOP(t) PIINTROSPECTION_THREADS->threadStop(t);
|
||||
# define PIINTROSPECTION_THREAD_RUN_DONE(t, us) PIINTROSPECTION_THREADS->threadRunDone(t, us);
|
||||
// clang-format on
|
||||
|
||||
class PIP_EXPORT PIIntrospectionThreadsInterface {
|
||||
friend class PIIntrospection;
|
||||
|
||||
@@ -28,10 +28,7 @@ PIIntrospectionThreads::ThreadInfo::ThreadInfo() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PIIntrospectionThreads::PIIntrospectionThreads() {
|
||||
}
|
||||
PIIntrospectionThreads::PIIntrospectionThreads() {}
|
||||
|
||||
|
||||
void PIIntrospectionThreads::threadNew(PIThread * t) {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "pibinarylog.h"
|
||||
|
||||
#include "pidir.h"
|
||||
#include "pipropertystorage.h"
|
||||
|
||||
@@ -101,8 +102,10 @@ bool PIBinaryLog::openDevice() {
|
||||
return false;
|
||||
}
|
||||
if (path().isEmpty() && mode_ == WriteOnly) {
|
||||
if (f_new_path) setPath(f_new_path());
|
||||
else setPath(getLogfilePath(logDir(), filePrefix()));
|
||||
if (f_new_path)
|
||||
setPath(f_new_path());
|
||||
else
|
||||
setPath(getLogfilePath(logDir(), filePrefix()));
|
||||
}
|
||||
if (path().isEmpty() && mode_ == ReadOnly) {
|
||||
PIDir ld(logDir());
|
||||
@@ -192,8 +195,7 @@ bool PIBinaryLog::threadedRead(const uchar *readed, ssize_t size) {
|
||||
pausemutex.unlock();
|
||||
pt = PISystemTime::current() - startlogtime;
|
||||
if (is_started) {
|
||||
if (lastrec_timestamp > pt)
|
||||
(lastrec_timestamp - pt).sleep();
|
||||
if (lastrec_timestamp > pt) (lastrec_timestamp - pt).sleep();
|
||||
} else {
|
||||
startlogtime = PISystemTime::current() - lastrec_timestamp;
|
||||
is_started = true;
|
||||
@@ -218,13 +220,17 @@ bool PIBinaryLog::threadedRead(const uchar *readed, ssize_t size) {
|
||||
cdelay = delay * play_speed; // TODO: rewrite with condvar
|
||||
dtc = int(cdelay) / 100; // TODO: rewrite with condvar
|
||||
piMSleep(100); // TODO: rewrite with condvar
|
||||
if (play_speed <= 0.) {dtc = 2; j = 0;}
|
||||
if (play_speed <= 0.) {
|
||||
dtc = 2;
|
||||
j = 0;
|
||||
}
|
||||
// piCout << " " << play_speed << dtc << j;
|
||||
}
|
||||
cdelay = cdelay - dtc * 100; // TODO: rewrite with condvar
|
||||
PISystemTime::fromMilliseconds(cdelay).sleep();
|
||||
}
|
||||
} else is_started = true;
|
||||
} else
|
||||
is_started = true;
|
||||
play_time = lastrec_timestamp.toMilliseconds();
|
||||
break;
|
||||
case PlayStaticDelay:
|
||||
@@ -234,10 +240,10 @@ bool PIBinaryLog::threadedRead(const uchar *readed, ssize_t size) {
|
||||
return false;
|
||||
}
|
||||
play_delay.sleep();
|
||||
} else is_started = true;
|
||||
} else
|
||||
is_started = true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
default: return false;
|
||||
}
|
||||
bool res = PIIODevice::threadedRead(readed, size);
|
||||
is_thread_ok = true;
|
||||
@@ -249,7 +255,8 @@ PIString PIBinaryLog::getLogfilePath(const PIString & log_dir, const PIString &
|
||||
PIDir dir(log_dir);
|
||||
dir.setDir(dir.absolutePath());
|
||||
if (!dir.isExists()) {
|
||||
piCout << "[PIBinaryLog]" << "Creating directory" << dir.path();
|
||||
piCout << "[PIBinaryLog]"
|
||||
<< "Creating directory" << dir.path();
|
||||
dir.make(true);
|
||||
}
|
||||
PIString npath = log_dir + PIDir::separator + prefix + PIDateTime::current().toString("yyyy_MM_dd__hh_mm_ss");
|
||||
@@ -265,8 +272,10 @@ PIString PIBinaryLog::getLogfilePath(const PIString & log_dir, const PIString &
|
||||
PIString PIBinaryLog::createNewFile() {
|
||||
if (!file.close()) return PIString();
|
||||
PIString cnpath;
|
||||
if (f_new_path) cnpath = f_new_path();
|
||||
else cnpath = getLogfilePath(logDir(), filePrefix());
|
||||
if (f_new_path)
|
||||
cnpath = f_new_path();
|
||||
else
|
||||
cnpath = getLogfilePath(logDir(), filePrefix());
|
||||
if (open(cnpath, PIIODevice::WriteOnly)) {
|
||||
newFile(file.path());
|
||||
return file.path();
|
||||
@@ -279,18 +288,18 @@ PIString PIBinaryLog::createNewFile() {
|
||||
void PIBinaryLog::createNewFile(const PIString & path) {
|
||||
if (open(path, PIIODevice::WriteOnly)) {
|
||||
newFile(file.path());
|
||||
}
|
||||
else piCoutObj << "Can't create new file, maybe path" << ("\"" + path + "\"") << "is invalid.";
|
||||
} else
|
||||
piCoutObj << "Can't create new file, maybe path" << ("\"" + path + "\"") << "is invalid.";
|
||||
}
|
||||
|
||||
|
||||
void PIBinaryLog::setPause(bool pause) {
|
||||
pausemutex.lock();
|
||||
is_pause = pause;
|
||||
if (pause) pause_time = PISystemTime::current();
|
||||
if (pause)
|
||||
pause_time = PISystemTime::current();
|
||||
else {
|
||||
if (pause_time > PISystemTime())
|
||||
pause_time = PISystemTime::current() - pause_time;
|
||||
if (pause_time > PISystemTime()) pause_time = PISystemTime::current() - pause_time;
|
||||
}
|
||||
pausemutex.unlock();
|
||||
}
|
||||
@@ -323,8 +332,10 @@ int PIBinaryLog::writeBinLog(int id, const void *data, int size) {
|
||||
default: break;
|
||||
}
|
||||
logmutex.unlock();
|
||||
if (res > 0) return size;
|
||||
else return res;
|
||||
if (res > 0)
|
||||
return size;
|
||||
else
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -338,8 +349,10 @@ int PIBinaryLog::writeBinLog_raw(int id, const PISystemTime &time, const void *d
|
||||
write_count++;
|
||||
log_size = file.size();
|
||||
logmutex.unlock();
|
||||
if (res > 0) return size;
|
||||
else return res;
|
||||
if (res > 0)
|
||||
return size;
|
||||
else
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -359,7 +372,8 @@ PIByteArray PIBinaryLog::readBinLog(int id, PISystemTime * time, int * readed_id
|
||||
return br.data;
|
||||
}
|
||||
logmutex.lock();
|
||||
while (br.id != id && !isEnd()) br = readRecord();
|
||||
while (br.id != id && !isEnd())
|
||||
br = readRecord();
|
||||
logmutex.unlock();
|
||||
if (br.id == -1) {
|
||||
piCoutObj << "End of BinLog file";
|
||||
@@ -412,7 +426,8 @@ ssize_t PIBinaryLog::readDevice(void *read_to, ssize_t max_size) {
|
||||
if (filterID.isEmpty()) {
|
||||
br = readRecord();
|
||||
} else {
|
||||
while (!filterID.contains(br.id) && !isEnd()) br = readRecord();
|
||||
while (!filterID.contains(br.id) && !isEnd())
|
||||
br = readRecord();
|
||||
}
|
||||
if (br.id == -1) {
|
||||
fileEnd();
|
||||
@@ -468,7 +483,8 @@ bool PIBinaryLog::writeFileHeader() {
|
||||
bool PIBinaryLog::checkFileHeader() {
|
||||
binfo.user_header.clear();
|
||||
uchar read_sig[PIBINARYLOG_SIGNATURE_SIZE];
|
||||
for (uint i=0; i<PIBINARYLOG_SIGNATURE_SIZE; i++) read_sig[i] = 0;
|
||||
for (uint i = 0; i < PIBINARYLOG_SIGNATURE_SIZE; i++)
|
||||
read_sig[i] = 0;
|
||||
if (file.read(read_sig, PIBINARYLOG_SIGNATURE_SIZE) < 0) return false;
|
||||
bool correct = true;
|
||||
for (uint i = 0; i < PIBINARYLOG_SIGNATURE_SIZE; i++)
|
||||
@@ -492,12 +508,9 @@ bool PIBinaryLog::checkFileHeader() {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (read_version == 0)
|
||||
piCoutObj << "BinLogFile has invalid version";
|
||||
if (read_version < PIBINARYLOG_VERSION)
|
||||
piCoutObj << "BinLogFile has too old verion";
|
||||
if (read_version > PIBINARYLOG_VERSION)
|
||||
piCoutObj << "BinLogFile has too newest version";
|
||||
if (read_version == 0) piCoutObj << "BinLogFile has invalid version";
|
||||
if (read_version < PIBINARYLOG_VERSION) piCoutObj << "BinLogFile has too old verion";
|
||||
if (read_version > PIBINARYLOG_VERSION) piCoutObj << "BinLogFile has too newest version";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -521,9 +534,12 @@ PIBinaryLog::BinLogRecord PIBinaryLog::readRecord() {
|
||||
}
|
||||
if (br.id > 0 && br.size > 0) {
|
||||
ba.resize(br.size);
|
||||
if(file.read(ba.data(), ba.size_s()) > 0) br.data = ba;
|
||||
else br.id = 0;
|
||||
} else br.id = 0;
|
||||
if (file.read(ba.data(), ba.size_s()) > 0)
|
||||
br.data = ba;
|
||||
else
|
||||
br.id = 0;
|
||||
} else
|
||||
br.id = 0;
|
||||
lastrecord = br;
|
||||
if (br.id == 0) fileError();
|
||||
moveIndex(index_pos.value(file.pos(), -1));
|
||||
@@ -533,7 +549,6 @@ PIBinaryLog::BinLogRecord PIBinaryLog::readRecord() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PIBinaryLog::parseLog(PIFile * f, PIBinaryLog::BinLogInfo * info, PIVector<PIBinaryLog::BinLogIndex> * index) {
|
||||
if (!info && !index) return;
|
||||
if (info) {
|
||||
@@ -549,7 +564,8 @@ void PIBinaryLog::parseLog(PIFile * f, PIBinaryLog::BinLogInfo * info, PIVector<
|
||||
info->log_size = f->size();
|
||||
}
|
||||
uchar read_sig[PIBINARYLOG_SIGNATURE_SIZE];
|
||||
for (uint i=0; i<PIBINARYLOG_SIGNATURE_SIZE; i++) read_sig[i] = 0;
|
||||
for (uint i = 0; i < PIBINARYLOG_SIGNATURE_SIZE; i++)
|
||||
read_sig[i] = 0;
|
||||
if (f->read(read_sig, PIBINARYLOG_SIGNATURE_SIZE) < 0) {
|
||||
if (info) info->records_count = -1;
|
||||
return;
|
||||
@@ -596,13 +612,14 @@ void PIBinaryLog::parseLog(PIFile * f, PIBinaryLog::BinLogInfo * info, PIVector<
|
||||
{
|
||||
if (f->read(ba.data(), ba.size()) > 0) {
|
||||
ba >> br.id >> br.size >> br.timestamp;
|
||||
} else break;
|
||||
} else
|
||||
break;
|
||||
if (info) {
|
||||
if (info->log_size - f->pos() >= br.size) {
|
||||
f->seek(f->pos() + br.size);
|
||||
}
|
||||
}
|
||||
else break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (br.id > 0) {
|
||||
if (index) {
|
||||
@@ -659,7 +676,8 @@ PIBinaryLog::BinLogInfo PIBinaryLog::getLogInfo(const PIString & path) {
|
||||
bool PIBinaryLog::cutBinLog(const PIBinaryLog::BinLogInfo & src, const PIString & dst, int from, int to) {
|
||||
PIBinaryLog slog;
|
||||
if (!slog.open(src.path, PIIODevice::ReadOnly)) {
|
||||
piCout << "[PIBinaryLog]" << "Error, can't open" << src.path;
|
||||
piCout << "[PIBinaryLog]"
|
||||
<< "Error, can't open" << src.path;
|
||||
return false;
|
||||
}
|
||||
PIVector<int> ids = src.records.keys();
|
||||
@@ -667,7 +685,8 @@ bool PIBinaryLog::cutBinLog(const PIBinaryLog::BinLogInfo & src, const PIString
|
||||
PIBinaryLog dlog;
|
||||
dlog.createNewFile(dst);
|
||||
if (!dlog.isOpened()) {
|
||||
piCout << "[PIBinaryLog]" << "Error, can't create" << dst;
|
||||
piCout << "[PIBinaryLog]"
|
||||
<< "Error, can't create" << dst;
|
||||
return false;
|
||||
}
|
||||
bool first = true;
|
||||
@@ -682,20 +701,24 @@ bool PIBinaryLog::cutBinLog(const PIBinaryLog::BinLogInfo & src, const PIString
|
||||
}
|
||||
if (ids.contains(br.id)) {
|
||||
if (dlog.writeBinLog_raw(br.id, br.timestamp - st, br.data) <= 0) {
|
||||
piCout << "[PIBinaryLog]" << "Error, can't write to file" << dst;
|
||||
piCout << "[PIBinaryLog]"
|
||||
<< "Error, can't write to file" << dst;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (tm.elapsed_s() > 1) {
|
||||
tm.reset();
|
||||
piCout << "[PIBinaryLog]" << "process" << PITime::fromSystemTime(br.timestamp).toString();
|
||||
piCout << "[PIBinaryLog]"
|
||||
<< "process" << PITime::fromSystemTime(br.timestamp).toString();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIBinaryLog::joinBinLogsSerial(const PIStringList & src, const PIString & dst, std::function<bool (const PIString &, PISystemTime)> progress) {
|
||||
bool PIBinaryLog::joinBinLogsSerial(const PIStringList & src,
|
||||
const PIString & dst,
|
||||
std::function<bool(const PIString &, PISystemTime)> progress) {
|
||||
PIBinaryLog slog;
|
||||
PIBinaryLog dlog;
|
||||
PISystemTime dtime;
|
||||
@@ -704,7 +727,8 @@ bool PIBinaryLog::joinBinLogsSerial(const PIStringList & src, const PIString & d
|
||||
bool first = true;
|
||||
for (const PIString & fn: src) {
|
||||
if (!slog.open(fn, PIIODevice::ReadOnly)) {
|
||||
piCout << "[PIBinaryLog]" << "Error, can't open" << fn;
|
||||
piCout << "[PIBinaryLog]"
|
||||
<< "Error, can't open" << fn;
|
||||
return false;
|
||||
}
|
||||
if (first) {
|
||||
@@ -712,10 +736,12 @@ bool PIBinaryLog::joinBinLogsSerial(const PIStringList & src, const PIString & d
|
||||
dlog.setHeader(slog.getHeader());
|
||||
dlog.createNewFile(dst);
|
||||
if (!dlog.isOpened()) {
|
||||
piCout << "[PIBinaryLog]" << "Error, can't create" << dst;
|
||||
piCout << "[PIBinaryLog]"
|
||||
<< "Error, can't create" << dst;
|
||||
return false;
|
||||
}
|
||||
piCout << "[PIBinaryLog]" << "Start join binlogs to" << dst;
|
||||
piCout << "[PIBinaryLog]"
|
||||
<< "Start join binlogs to" << dst;
|
||||
} else {
|
||||
dtime = lt;
|
||||
}
|
||||
@@ -728,7 +754,8 @@ bool PIBinaryLog::joinBinLogsSerial(const PIStringList & src, const PIString & d
|
||||
st = br.timestamp;
|
||||
lt = dtime + br.timestamp;
|
||||
if (dlog.writeBinLog_raw(br.id, lt, br.data) <= 0) {
|
||||
piCout << "[PIBinaryLog]" << "Error, can't write to file" << dst;
|
||||
piCout << "[PIBinaryLog]"
|
||||
<< "Error, can't write to file" << dst;
|
||||
return false;
|
||||
}
|
||||
if (tm.elapsed_s() > 0.1) {
|
||||
@@ -741,14 +768,16 @@ bool PIBinaryLog::joinBinLogsSerial(const PIStringList & src, const PIString & d
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
piCout << "[PIBinaryLog]" << "process" << PITime::fromSystemTime(lt).toString();
|
||||
piCout << "[PIBinaryLog]"
|
||||
<< "process" << PITime::fromSystemTime(lt).toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
slog.close();
|
||||
// piCout << "[PIBinaryLog]" << "complete" << fn;
|
||||
}
|
||||
piCout << "[PIBinaryLog]" << "Finish join binlogs, total time" << PITime::fromSystemTime(lt).toString();
|
||||
piCout << "[PIBinaryLog]"
|
||||
<< "Finish join binlogs, total time" << PITime::fromSystemTime(lt).toString();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -762,7 +791,8 @@ bool PIBinaryLog::createIndex() {
|
||||
parseLog(&file, &binfo, &index);
|
||||
file.seek(cp);
|
||||
is_indexed = !index.isEmpty();
|
||||
for (uint i=0; i<index.size(); i++) index_pos[index[i].pos] = i;
|
||||
for (uint i = 0; i < index.size(); i++)
|
||||
index_pos[index[i].pos] = i;
|
||||
logmutex.unlock();
|
||||
return is_indexed;
|
||||
}
|
||||
@@ -830,18 +860,10 @@ PIString PIBinaryLog::constructFullPathDevice() const {
|
||||
PIString ret;
|
||||
ret += logDir() + ":" + filePrefix() + ":" + PIString::fromNumber(defaultID()) + ":";
|
||||
switch (play_mode) {
|
||||
case PlayRealTime:
|
||||
ret += "RT";
|
||||
break;
|
||||
case PlayVariableSpeed:
|
||||
ret += PIString::fromNumber(playSpeed()) + "X";
|
||||
break;
|
||||
case PlayStaticDelay:
|
||||
ret += PIString::fromNumber(playDelay().toMilliseconds()) + "M";
|
||||
break;
|
||||
default:
|
||||
ret += "RT";
|
||||
break;
|
||||
case PlayRealTime: ret += "RT"; break;
|
||||
case PlayVariableSpeed: ret += PIString::fromNumber(playSpeed()) + "X"; break;
|
||||
case PlayStaticDelay: ret += PIString::fromNumber(playDelay().toMilliseconds()) + "M"; break;
|
||||
default: ret += "RT"; break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -872,7 +894,9 @@ PIPropertyStorage PIBinaryLog::constructVariantDevice() const {
|
||||
ret.addProperty("log dir", PIVariantTypes::Dir(logDir()));
|
||||
ret.addProperty("file prefix", filePrefix());
|
||||
ret.addProperty("default ID", defaultID());
|
||||
e << "real-time" << "variable speed" << "static delay";
|
||||
e << "real-time"
|
||||
<< "variable speed"
|
||||
<< "static delay";
|
||||
e.selectValue((int)playMode());
|
||||
ret.addProperty("play mode", e);
|
||||
ret.addProperty("play speed", playSpeed());
|
||||
@@ -904,4 +928,3 @@ void PIBinaryLog::propertyChanged(const char * s) {
|
||||
split_count = property("splitRecordCount").toInt();
|
||||
// piCoutObj << "propertyChanged" << s << play_mode;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
//! \~\brief
|
||||
//! \~english Binary log
|
||||
//! \~russian Бинарный лог
|
||||
class PIP_EXPORT PIBinaryLog: public PIIODevice
|
||||
{
|
||||
class PIP_EXPORT PIBinaryLog: public PIIODevice {
|
||||
PIIODEVICE(PIBinaryLog, "binlog");
|
||||
|
||||
public:
|
||||
explicit PIBinaryLog();
|
||||
virtual ~PIBinaryLog();
|
||||
@@ -144,26 +144,41 @@ public:
|
||||
|
||||
//! Set play speed to "speed", default value is 1.0x
|
||||
//! Also this function set \a playMode to \a PlayVariableSpeed
|
||||
void setPlaySpeed(double speed) {setPlayMode(PlayVariableSpeed); setProperty("playSpeed", speed);}
|
||||
void setPlaySpeed(double speed) {
|
||||
setPlayMode(PlayVariableSpeed);
|
||||
setProperty("playSpeed", speed);
|
||||
}
|
||||
|
||||
//! Setting static delay between records, default value is 1 sec
|
||||
//! Also this function set \a playMode to \a PlayStaticDelay
|
||||
void setPlayDelay(const PISystemTime & delay) {setPlayMode(PlayStaticDelay); setProperty("playDelay", delay);}
|
||||
void setPlayDelay(const PISystemTime & delay) {
|
||||
setPlayMode(PlayStaticDelay);
|
||||
setProperty("playDelay", delay);
|
||||
}
|
||||
|
||||
//! Set \a playMode to \a PlayRealTime
|
||||
void setPlayRealTime() { setPlayMode(PlayRealTime); }
|
||||
|
||||
//! Set binlog file split time
|
||||
//! Also this function set \a splitMode to \a SplitTime
|
||||
void setSplitTime(const PISystemTime & time) {setSplitMode(SplitTime); setProperty("splitTime", time);}
|
||||
void setSplitTime(const PISystemTime & time) {
|
||||
setSplitMode(SplitTime);
|
||||
setProperty("splitTime", time);
|
||||
}
|
||||
|
||||
//! Set binlog file split size
|
||||
//! Also this function set \a splitMode to \a SplitSize
|
||||
void setSplitFileSize(llong size) {setSplitMode(SplitSize); setProperty("splitFileSize", size);}
|
||||
void setSplitFileSize(llong size) {
|
||||
setSplitMode(SplitSize);
|
||||
setProperty("splitFileSize", size);
|
||||
}
|
||||
|
||||
//! Set binlog file split records count
|
||||
//! Also this function set \a splitMode to \a SplitCount
|
||||
void setSplitRecordCount(int count) {setSplitMode(SplitCount); setProperty("splitRecordCount", count);}
|
||||
void setSplitRecordCount(int count) {
|
||||
setSplitMode(SplitCount);
|
||||
setProperty("splitRecordCount", count);
|
||||
}
|
||||
|
||||
//! Set pause while playing via \a threadedRead or writing via write
|
||||
void setPause(bool pause);
|
||||
@@ -180,7 +195,9 @@ public:
|
||||
int writeBinLog(int id, const void * data, int size);
|
||||
|
||||
//! Write one RAW record to BinLog file, with ID = id, Timestamp = time
|
||||
int writeBinLog_raw(int id, const PISystemTime &time, const PIByteArray &data) {return writeBinLog_raw(id, time, data.data(), data.size_s());}
|
||||
int writeBinLog_raw(int id, const PISystemTime & time, const PIByteArray & data) {
|
||||
return writeBinLog_raw(id, time, data.data(), data.size_s());
|
||||
}
|
||||
int writeBinLog_raw(int id, const PISystemTime & time, const void * data, int size);
|
||||
|
||||
//! Returns count of writed records
|
||||
@@ -199,7 +216,10 @@ public:
|
||||
llong logPos() const { return file.pos(); }
|
||||
|
||||
//! Return true, if position at the end of BinLog file
|
||||
bool isEnd() const {if (isClosed()) return true; return file.isEnd();}
|
||||
bool isEnd() const {
|
||||
if (isClosed()) return true;
|
||||
return file.isEnd();
|
||||
}
|
||||
|
||||
//! Returns if BinLog file is empty
|
||||
bool isEmpty() const;
|
||||
@@ -237,7 +257,10 @@ public:
|
||||
void restart();
|
||||
|
||||
//! Get binlog info \a BinLogInfo
|
||||
BinLogInfo logInfo() const {if (is_indexed) return binfo; return getLogInfo(path());}
|
||||
BinLogInfo logInfo() const {
|
||||
if (is_indexed) return binfo;
|
||||
return getLogInfo(path());
|
||||
}
|
||||
|
||||
//! Get binlog index \a BinLogIndex, need \a createIndex before getting index
|
||||
const PIVector<BinLogIndex> & logIndex() const { return index; }
|
||||
@@ -261,7 +284,10 @@ public:
|
||||
bool seek(llong filepos);
|
||||
|
||||
//! Get current record index (position record in file)
|
||||
int pos() const {if (is_indexed) return current_index; return -1;}
|
||||
int pos() const {
|
||||
if (is_indexed) return current_index;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//! \handlers
|
||||
//! \{
|
||||
@@ -298,7 +324,9 @@ public:
|
||||
static bool cutBinLog(const BinLogInfo & src, const PIString & dst, int from, int to);
|
||||
|
||||
//! Create new binlog from serial splitted binlogs "src"
|
||||
static bool joinBinLogsSerial(const PIStringList & src, const PIString & dst, std::function<bool (const PIString &, PISystemTime)> progress = nullptr);
|
||||
static bool joinBinLogsSerial(const PIStringList & src,
|
||||
const PIString & dst,
|
||||
std::function<bool(const PIString &, PISystemTime)> progress = nullptr);
|
||||
|
||||
protected:
|
||||
PIString constructFullPathDevice() const override;
|
||||
@@ -360,7 +388,8 @@ inline PICout operator <<(PICout s, const PIBinaryLog::BinLogInfo & bi) {
|
||||
s << "Invalid empty file";
|
||||
s.restoreControls();
|
||||
return s;
|
||||
} if (bi.records_count < 0 && bi.records_count > -4) {
|
||||
}
|
||||
if (bi.records_count < 0 && bi.records_count > -4) {
|
||||
s << "Invalid file or corrupted signature";
|
||||
s.restoreControls();
|
||||
return s;
|
||||
|
||||
@@ -17,16 +17,17 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "pican.h"
|
||||
|
||||
#include "pipropertystorage.h"
|
||||
#include "piwaitevent_p.h"
|
||||
#if !defined(WINDOWS) && !defined(MAC_OS) && !defined(MICRO_PIP)
|
||||
# define PIP_CAN
|
||||
#endif
|
||||
#ifdef PIP_CAN
|
||||
# include <sys/ioctl.h>
|
||||
# include <net/if.h>
|
||||
# include <linux/can.h>
|
||||
# include <linux/can/raw.h>
|
||||
# include <net/if.h>
|
||||
# include <sys/ioctl.h>
|
||||
# ifndef AF_CAN
|
||||
# define AF_CAN 29
|
||||
# endif
|
||||
@@ -111,9 +112,10 @@ ssize_t PICAN::readDevice(void * read_to, ssize_t max_size) {
|
||||
// piCout << "PICAN read";
|
||||
can_frame frame;
|
||||
ssize_t ret = 0;
|
||||
if (PRIVATE->event.wait(sock))
|
||||
ret = ::read(sock, &frame, sizeof(can_frame));
|
||||
if (ret < 0) {/*piCoutObj << "Error while read CAN frame " << ret;*/ return -1;}
|
||||
if (PRIVATE->event.wait(sock)) ret = ::read(sock, &frame, sizeof(can_frame));
|
||||
if (ret < 0) { /*piCoutObj << "Error while read CAN frame " << ret;*/
|
||||
return -1;
|
||||
}
|
||||
// piCoutObj << "receive CAN frame Id =" << frame.can_id;
|
||||
memcpy(read_to, frame.data, piMini(frame.can_dlc, max_size));
|
||||
readed_id = frame.can_id;
|
||||
@@ -126,14 +128,20 @@ ssize_t PICAN::readDevice(void * read_to, ssize_t max_size) {
|
||||
ssize_t PICAN::writeDevice(const void * data, ssize_t max_size) {
|
||||
#ifdef PIP_CAN
|
||||
// piCout << "PICAN write" << can_id << max_size;
|
||||
if (max_size > 8) {piCoutObj << "Can't send CAN frame bigger than 8 bytes (requested " << max_size << ")!"; return -1;}
|
||||
if (max_size > 8) {
|
||||
piCoutObj << "Can't send CAN frame bigger than 8 bytes (requested " << max_size << ")!";
|
||||
return -1;
|
||||
}
|
||||
can_frame frame;
|
||||
frame.can_id = can_id;
|
||||
frame.can_dlc = max_size;
|
||||
memcpy(frame.data, data, max_size);
|
||||
ssize_t ret = 0;
|
||||
ret = ::write(sock, &frame, sizeof(can_frame));
|
||||
if (ret < 0) {piCoutObj << "Error while send CAN frame " << ret; return -1;}
|
||||
if (ret < 0) {
|
||||
piCoutObj << "Error while send CAN frame " << ret;
|
||||
return -1;
|
||||
}
|
||||
return max_size;
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
#include "piiodevice.h"
|
||||
|
||||
|
||||
class PIP_EXPORT PICAN: public PIIODevice
|
||||
{
|
||||
class PIP_EXPORT PICAN: public PIIODevice {
|
||||
PIIODEVICE(PICAN, "can");
|
||||
|
||||
public:
|
||||
explicit PICAN(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||
virtual ~PICAN();
|
||||
|
||||
@@ -19,10 +19,12 @@
|
||||
|
||||
|
||||
#include "piconfig.h"
|
||||
|
||||
#include "pifile.h"
|
||||
#include "piiostring.h"
|
||||
#ifdef PIP_STD_IOSTREAM
|
||||
# include "pistring_std.h"
|
||||
|
||||
# include <iostream>
|
||||
#endif
|
||||
/*! \class PIConfig
|
||||
@@ -106,8 +108,10 @@ PIConfig::Branch PIConfig::Branch::allLeaves() {
|
||||
Branch b;
|
||||
b.delim = delim;
|
||||
piForeach(Entry * i, *this) {
|
||||
if (i->isLeaf()) b << i;
|
||||
else allLeaves(b, i);
|
||||
if (i->isLeaf())
|
||||
b << i;
|
||||
else
|
||||
allLeaves(b, i);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
@@ -156,12 +160,10 @@ PIConfig::Branch PIConfig::Branch::getValues(const PIString & name) {
|
||||
b.delim = delim;
|
||||
piForeach(Entry * i, *this) {
|
||||
if (i->isLeaf()) {
|
||||
if (i->_name.find(name) >= 0)
|
||||
b << i;
|
||||
if (i->_name.find(name) >= 0) b << i;
|
||||
} else {
|
||||
piForeach(Entry * j, i->_children)
|
||||
if (j->_name.find(name) >= 0)
|
||||
b << j;
|
||||
if (j->_name.find(name) >= 0) b << j;
|
||||
}
|
||||
}
|
||||
return b;
|
||||
@@ -172,8 +174,7 @@ PIConfig::Branch PIConfig::Branch::getLeaves() {
|
||||
Branch b;
|
||||
b.delim = delim;
|
||||
piForeach(Entry * i, *this)
|
||||
if (i->isLeaf())
|
||||
b << i;
|
||||
if (i->isLeaf()) b << i;
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -182,8 +183,7 @@ PIConfig::Branch PIConfig::Branch::getBranches() {
|
||||
Branch b;
|
||||
b.delim = delim;
|
||||
piForeach(Entry * i, *this)
|
||||
if (!i->isLeaf())
|
||||
b << i;
|
||||
if (!i->isLeaf()) b << i;
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -231,8 +231,7 @@ PIConfig::Branch PIConfig::Entry::getValues(const PIString & vname) {
|
||||
Branch b;
|
||||
b.delim = delim;
|
||||
piForeach(Entry * i, _children)
|
||||
if (i->_name.find(vname) >= 0)
|
||||
b << i;
|
||||
if (i->_name.find(vname) >= 0) b << i;
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -250,18 +249,24 @@ bool PIConfig::Entry::entryExists(const Entry * e, const PIString & name) const
|
||||
#ifdef PIP_STD_IOSTREAM
|
||||
void PIConfig::Entry::coutt(std::ostream & s, const PIString & p) const {
|
||||
PIString nl = p + " ";
|
||||
if (!_value.isEmpty()) s << p << _name << " = " << _value << std::endl;
|
||||
else std::cout << p << _name << std::endl;
|
||||
piForeachC (Entry * i, _children) i->coutt(s, nl);
|
||||
if (!_value.isEmpty())
|
||||
s << p << _name << " = " << _value << std::endl;
|
||||
else
|
||||
std::cout << p << _name << std::endl;
|
||||
piForeachC(Entry * i, _children)
|
||||
i->coutt(s, nl);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void PIConfig::Entry::piCoutt(PICout s, const PIString & p) const {
|
||||
PIString nl = p + " ";
|
||||
if (!_value.isEmpty()) s << p << _name << " = " << _value << " (" << _type << " " << _comment << ")" << PICoutManipulators::NewLine;
|
||||
else s << p << _name << PICoutManipulators::NewLine;
|
||||
piForeachC (Entry * i, _children) i->piCoutt(s, nl);
|
||||
if (!_value.isEmpty())
|
||||
s << p << _name << " = " << _value << " (" << _type << " " << _comment << ")" << PICoutManipulators::NewLine;
|
||||
else
|
||||
s << p << _name << PICoutManipulators::NewLine;
|
||||
piForeachC(Entry * i, _children)
|
||||
i->piCoutt(s, nl);
|
||||
}
|
||||
|
||||
|
||||
@@ -319,8 +324,7 @@ bool PIConfig::open(const PIString & path, PIIODevice::DeviceMode mode) {
|
||||
incdirs << PIFile::fileInfo(path).dir();
|
||||
own_dev = true;
|
||||
dev = new PIFile(path, mode);
|
||||
if (!dev->isOpened())
|
||||
dev->open(path, mode);
|
||||
if (!dev->isOpened()) dev->open(path, mode);
|
||||
_setupDev();
|
||||
parse();
|
||||
return dev->isOpened();
|
||||
@@ -343,8 +347,7 @@ bool PIConfig::open(PIIODevice * device, PIIODevice::DeviceMode mode) {
|
||||
dev = device;
|
||||
if (dev) {
|
||||
dev->open(mode);
|
||||
if (dev->isTypeOf<PIFile>())
|
||||
incdirs << PIFile::fileInfo(((PIFile*)dev)->path()).dir();
|
||||
if (dev->isTypeOf<PIFile>()) incdirs << PIFile::fileInfo(((PIFile *)dev)->path()).dir();
|
||||
}
|
||||
_setupDev();
|
||||
parse();
|
||||
@@ -383,14 +386,22 @@ void PIConfig::_setupDev() {
|
||||
|
||||
void PIConfig::_clearDev() {
|
||||
if (!dev) return;
|
||||
if (PIString(dev->className()) == "PIFile") {((PIFile*)dev)->clear(); return;}
|
||||
if (PIString(dev->className()) == "PIIOString") {((PIIOString*)dev)->clear(); return;}
|
||||
if (PIString(dev->className()) == "PIFile") {
|
||||
((PIFile *)dev)->clear();
|
||||
return;
|
||||
}
|
||||
if (PIString(dev->className()) == "PIIOString") {
|
||||
((PIIOString *)dev)->clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::_flushDev() {
|
||||
if (!dev) return;
|
||||
if (PIString(dev->className()) == "PIFile") {((PIFile*)dev)->flush();}
|
||||
if (PIString(dev->className()) == "PIFile") {
|
||||
((PIFile *)dev)->flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -402,8 +413,14 @@ bool PIConfig::_isEndDev() {
|
||||
|
||||
void PIConfig::_seekToBeginDev() {
|
||||
if (!dev) return;
|
||||
if (PIString(dev->className()) == "PIFile") {((PIFile*)dev)->seekToBegin(); return;}
|
||||
if (PIString(dev->className()) == "PIIOString") {((PIIOString*)dev)->seekToBegin(); return;}
|
||||
if (PIString(dev->className()) == "PIFile") {
|
||||
((PIFile *)dev)->seekToBegin();
|
||||
return;
|
||||
}
|
||||
if (PIString(dev->className()) == "PIIOString") {
|
||||
((PIIOString *)dev)->seekToBegin();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -448,15 +465,13 @@ PIConfig::Branch PIConfig::getValues(const PIString & vname) {
|
||||
Branch b;
|
||||
b.delim = delim;
|
||||
piForeach(Entry * i, root._children)
|
||||
if (i->_name.find(vname) >= 0)
|
||||
b << i;
|
||||
if (i->_name.find(vname) >= 0) b << i;
|
||||
return b;
|
||||
};
|
||||
|
||||
|
||||
void PIConfig::addEntry(const PIString & name, const PIString & value, const PIString & type, bool write) {
|
||||
if (getValue(name)._parent != 0)
|
||||
return;
|
||||
if (getValue(name)._parent != 0) return;
|
||||
bool toRoot = false;
|
||||
PIStringList tree = name.split(delim);
|
||||
PIString ename = tree.back();
|
||||
@@ -474,7 +489,8 @@ void PIConfig::addEntry(const PIString & name, const PIString & value, const PIS
|
||||
ce->_parent = entry;
|
||||
entry->_children << ce;
|
||||
entry = ce;
|
||||
} else entry = te;
|
||||
} else
|
||||
entry = te;
|
||||
}
|
||||
PIConfig::Branch ch = entry->_children;
|
||||
ch.sort(PIConfig::Entry::compare);
|
||||
@@ -486,11 +502,14 @@ void PIConfig::addEntry(const PIString & name, const PIString & value, const PIS
|
||||
ce->_type = type;
|
||||
if (te == 0) {
|
||||
ce->_tab = entry->_tab;
|
||||
if (toRoot) ce->_line = other.size_s() - 1;
|
||||
else ce->_line = entry->_line;
|
||||
if (toRoot)
|
||||
ce->_line = other.size_s() - 1;
|
||||
else
|
||||
ce->_line = entry->_line;
|
||||
} else {
|
||||
ce->_tab = te->_tab;
|
||||
if (toRoot) ce->_line = other.size_s() - 1;
|
||||
if (toRoot)
|
||||
ce->_line = other.size_s() - 1;
|
||||
else {
|
||||
ch = entry->_parent->_children;
|
||||
ch.sort(PIConfig::Entry::compare);
|
||||
@@ -510,8 +529,7 @@ void PIConfig::addEntry(const PIString & name, const PIString & value, const PIS
|
||||
if (b[i] == ce) {
|
||||
found = true;
|
||||
if (i > 0)
|
||||
if (b[i - 1]->_line == b[i]->_line)
|
||||
b[i - 1]->_line++;
|
||||
if (b[i - 1]->_line == b[i]->_line) b[i - 1]->_line++;
|
||||
}
|
||||
}
|
||||
if (write) writeAll();
|
||||
@@ -535,8 +553,7 @@ int PIConfig::entryIndex(const PIString & name) {
|
||||
Entry * ce = &root;
|
||||
piForeach(PIString & i, tree) {
|
||||
ce = ce->findChild(i);
|
||||
if (ce == 0)
|
||||
return -1;
|
||||
if (ce == 0) return -1;
|
||||
}
|
||||
return allLeaves().indexOf(ce);
|
||||
}
|
||||
@@ -600,8 +617,7 @@ void PIConfig::removeEntry(Branch & b, PIConfig::Entry * e) {
|
||||
leaf = false;
|
||||
} else {
|
||||
int cc = e->_children.size_s();
|
||||
piForTimes (cc)
|
||||
removeEntry(b, e->_children.back());
|
||||
piForTimes(cc) removeEntry(b, e->_children.back());
|
||||
}
|
||||
bool found = false;
|
||||
for (int i = 0; i < b.size_s(); ++i) {
|
||||
@@ -620,10 +636,16 @@ void PIConfig::removeEntry(Branch & b, PIConfig::Entry * e) {
|
||||
|
||||
PIString PIConfig::getPrefixFromLine(PIString line, bool * exists) {
|
||||
line.trim();
|
||||
if (line.left(1) == "#") {if (exists) *exists = false; return PIString();}
|
||||
if (line.left(1) == "#") {
|
||||
if (exists) *exists = false;
|
||||
return PIString();
|
||||
}
|
||||
int ci = line.find("#");
|
||||
if (ci >= 0) line.cutRight(line.size() - ci);
|
||||
if (line.find("=") >= 0) {if (exists) *exists = false; return PIString();}
|
||||
if (line.find("=") >= 0) {
|
||||
if (exists) *exists = false;
|
||||
return PIString();
|
||||
}
|
||||
if (line.find("[") >= 0 && line.find("]") >= 0) {
|
||||
if (exists) *exists = true;
|
||||
return line.takeRange('[', ']').trim();
|
||||
@@ -656,11 +678,9 @@ void PIConfig::writeAll() {
|
||||
tprefix = getPrefixFromLine(other[i], &isPrefix);
|
||||
if (isPrefix) {
|
||||
prefix = tprefix;
|
||||
if (!prefix.isEmpty())
|
||||
prefix += delim;
|
||||
if (!prefix.isEmpty()) prefix += delim;
|
||||
}
|
||||
if (i < other.size_s() - 1)
|
||||
_writeDev('\n');
|
||||
if (i < other.size_s() - 1) _writeDev('\n');
|
||||
// cout << this << " " << other[i] << endl;
|
||||
}
|
||||
} else {
|
||||
@@ -668,11 +688,9 @@ void PIConfig::writeAll() {
|
||||
tprefix = getPrefixFromLine(other[i], &isPrefix);
|
||||
if (isPrefix) {
|
||||
prefix = tprefix;
|
||||
if (!prefix.isEmpty())
|
||||
prefix += delim;
|
||||
if (!prefix.isEmpty()) prefix += delim;
|
||||
}
|
||||
if (i < other.size_s() - 1)
|
||||
_writeDev('\n');
|
||||
if (i < other.size_s() - 1) _writeDev('\n');
|
||||
// cout << this << " " << other[i] << endl;
|
||||
}
|
||||
}
|
||||
@@ -760,8 +778,7 @@ void PIConfig::parse() {
|
||||
tprefix = getPrefixFromLine(src, &isPrefix);
|
||||
if (isPrefix) {
|
||||
prefix = tprefix;
|
||||
if (!prefix.isEmpty())
|
||||
prefix += delim;
|
||||
if (!prefix.isEmpty()) prefix += delim;
|
||||
}
|
||||
// piCout << "line \"" << str << "\"";
|
||||
tab = str.left(str.find(str.trimmed().left(1)));
|
||||
@@ -774,7 +791,8 @@ void PIConfig::parse() {
|
||||
if (!comm.isEmpty()) {
|
||||
type = comm[0];
|
||||
comm.cutLeft(1).trim();
|
||||
} else type = "s";
|
||||
} else
|
||||
type = "s";
|
||||
str = str.left(sind).trim();
|
||||
} else {
|
||||
type = "s";
|
||||
@@ -829,7 +847,8 @@ void PIConfig::parse() {
|
||||
ce->_parent = entry;
|
||||
entry->_children << ce;
|
||||
entry = ce;
|
||||
} else entry = te;
|
||||
} else
|
||||
entry = te;
|
||||
}
|
||||
isNew = false;
|
||||
ce = entry->findChild(name);
|
||||
@@ -852,7 +871,8 @@ void PIConfig::parse() {
|
||||
entry->_children << ce;
|
||||
}
|
||||
}
|
||||
} else other.back() = src;
|
||||
} else
|
||||
other.back() = src;
|
||||
lines++;
|
||||
}
|
||||
setEntryDelim(&root, delim);
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "piincludes_p.h"
|
||||
#include "pidir.h"
|
||||
|
||||
#include "piincludes_p.h"
|
||||
|
||||
|
||||
const PIChar PIDir::separator = '/';
|
||||
#ifdef QNX
|
||||
@@ -150,8 +151,7 @@ PIDir & PIDir::cleanPath() {
|
||||
break;
|
||||
}
|
||||
path_ = l.join(separator);
|
||||
if (is_abs)
|
||||
path_.prepend(separator);
|
||||
if (is_abs) path_.prepend(separator);
|
||||
if (path_.isEmpty()) path_ = ".";
|
||||
return *this;
|
||||
}
|
||||
@@ -179,8 +179,7 @@ PIDir & PIDir::setDir(const PIString & path) {
|
||||
#ifdef WINDOWS
|
||||
path_.replaceAll("\\", separator);
|
||||
if (path_.length() > 2)
|
||||
if (path_.mid(1, 2).contains(":"))
|
||||
path_.prepend(separator);
|
||||
if (path_.mid(1, 2).contains(":")) path_.prepend(separator);
|
||||
#endif
|
||||
cleanPath();
|
||||
return *this;
|
||||
@@ -217,8 +216,7 @@ bool PIDir::make(bool withParents) {
|
||||
cdp += i;
|
||||
// piCout << "dir" << cdp;
|
||||
if (!isExists(cdp))
|
||||
if (!makeDir(cdp))
|
||||
return false;
|
||||
if (!makeDir(cdp)) return false;
|
||||
}
|
||||
/*for (int i = l.size_s() - 1; i >= 0; --i) {
|
||||
if (i > 1) tp = PIStringList(l).remove(i, l.size_s() - i).join(separator);
|
||||
@@ -238,15 +236,14 @@ bool PIDir::make(bool withParents) {
|
||||
};
|
||||
}*/
|
||||
return true;
|
||||
} else
|
||||
if (makeDir(d.path())) return true;
|
||||
} else if (makeDir(d.path()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PIDir::rename(const PIString & new_name) {
|
||||
if (!PIDir::rename(path(), new_name))
|
||||
return false;
|
||||
if (!PIDir::rename(path(), new_name)) return false;
|
||||
setDir(new_name);
|
||||
return true;
|
||||
}
|
||||
@@ -278,8 +275,10 @@ PIVector<PIFile::FileInfo> PIDir::entries() {
|
||||
if (!isExists()) return l;
|
||||
PIString dp = absolutePath();
|
||||
PIString p(dp);
|
||||
if (dp == ".") dp.clear();
|
||||
else if (!dp.endsWith(separator)) dp += separator;
|
||||
if (dp == ".")
|
||||
dp.clear();
|
||||
else if (!dp.endsWith(separator))
|
||||
dp += separator;
|
||||
// piCout << "start entries from" << p;
|
||||
#ifdef WINDOWS
|
||||
if (dp == separator) {
|
||||
@@ -298,7 +297,8 @@ PIVector<PIFile::FileInfo> PIDir::entries() {
|
||||
clet += PIChar(letters[i]);
|
||||
}
|
||||
} else {
|
||||
WIN32_FIND_DATAA fd; memset(&fd, 0, sizeof(fd));
|
||||
WIN32_FIND_DATAA fd;
|
||||
memset(&fd, 0, sizeof(fd));
|
||||
p += "\\*";
|
||||
void * hf = FindFirstFileA((LPCSTR)(p.data()), &fd);
|
||||
if (!hf) return l;
|
||||
@@ -334,7 +334,9 @@ PIVector<PIFile::FileInfo> PIDir::entries() {
|
||||
}
|
||||
# else
|
||||
dirent ** list;
|
||||
int cnt = scandir(p.data(), &list, 0,
|
||||
int cnt = scandir(p.data(),
|
||||
&list,
|
||||
0,
|
||||
# if defined(MAC_OS) || defined(ANDROID) || defined(BLACKBERRY)
|
||||
alphasort);
|
||||
# else
|
||||
@@ -379,7 +381,8 @@ PIVector<PIFile::FileInfo> PIDir::allEntries() {
|
||||
if (de.isDir()) {
|
||||
dirs << de;
|
||||
ndirs << de.path;
|
||||
} else ret << de;
|
||||
} else
|
||||
ret << de;
|
||||
}
|
||||
}
|
||||
cdirs = ndirs;
|
||||
@@ -391,7 +394,6 @@ PIVector<PIFile::FileInfo> PIDir::allEntries() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool PIDir::isExists(const PIString & path) {
|
||||
#ifdef WINDOWS
|
||||
DWORD ret = GetFileAttributes((LPCTSTR)(path.data()));
|
||||
@@ -535,5 +537,3 @@ bool PIDir::renameDir(const PIString & path, const PIString & new_name) {
|
||||
printf("[PIDir] renameDir(\"%s\", \"%s\") error: %s\n", path.data(), new_name.data(), errorString().data());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,10 +33,8 @@
|
||||
//! \~\brief
|
||||
//! \~english Local directory.
|
||||
//! \~russian Локальная директория.
|
||||
class PIP_EXPORT PIDir
|
||||
{
|
||||
class PIP_EXPORT PIDir {
|
||||
public:
|
||||
|
||||
//! \~english Constructs directory with path "dir"
|
||||
//! \~russian Создает директорию с путём "dir"
|
||||
PIDir(const PIString & dir = PIString());
|
||||
@@ -77,7 +75,11 @@ public:
|
||||
|
||||
//! \~english Returns %PIDir with simplified path of this directory
|
||||
//! \~russian Возвращает %PIDir с упрощённым путём директории
|
||||
PIDir cleanedPath() const {PIDir d(path()); d.cleanPath(); return d;}
|
||||
PIDir cleanedPath() const {
|
||||
PIDir d(path());
|
||||
d.cleanPath();
|
||||
return d;
|
||||
}
|
||||
|
||||
//! \~english Returns relative to this directory path "path"
|
||||
//! \~russian Возвращает путь "path" относительно этой директории
|
||||
@@ -177,19 +179,31 @@ private:
|
||||
static bool renameDir(const PIString & path, const PIString & new_name);
|
||||
|
||||
PIString path_, scan_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline bool operator <(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {return (v0.path < v1.path);}
|
||||
inline bool operator >(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {return (v0.path > v1.path);}
|
||||
inline bool operator ==(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {return (v0.path == v1.path);}
|
||||
inline bool operator !=(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {return (v0.path != v1.path);}
|
||||
inline bool operator<(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {
|
||||
return (v0.path < v1.path);
|
||||
}
|
||||
inline bool operator>(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {
|
||||
return (v0.path > v1.path);
|
||||
}
|
||||
inline bool operator==(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {
|
||||
return (v0.path == v1.path);
|
||||
}
|
||||
inline bool operator!=(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {
|
||||
return (v0.path != v1.path);
|
||||
}
|
||||
|
||||
//! \relatesalso PICout
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
inline PICout operator <<(PICout s, const PIDir & v) {s.saveAndSetControls(0); s << "PIDir(\"" << v.path() << "\")"; s.restoreControls(); return s;}
|
||||
inline PICout operator<<(PICout s, const PIDir & v) {
|
||||
s.saveAndSetControls(0);
|
||||
s << "PIDir(\"" << v.path() << "\")";
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
#endif // PIDIR_H
|
||||
|
||||
@@ -16,25 +16,27 @@
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "piincludes_p.h"
|
||||
#include "piethernet.h"
|
||||
|
||||
#include "piconfig.h"
|
||||
#include "pisysteminfo.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "piconstchars.h"
|
||||
#include "piincludes_p.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "pisysteminfo.h"
|
||||
// clang-format off
|
||||
#ifdef QNX
|
||||
# include <arpa/inet.h>
|
||||
# include <fcntl.h>
|
||||
# include <hw/nicinfo.h>
|
||||
# include <ifaddrs.h>
|
||||
# include <net/if.h>
|
||||
# include <net/if_dl.h>
|
||||
# include <hw/nicinfo.h>
|
||||
# include <netdb.h>
|
||||
# include <netinet/in.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/time.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <ifaddrs.h>
|
||||
# include <fcntl.h>
|
||||
# ifdef BLACKBERRY
|
||||
# include <netinet/in.h>
|
||||
# else
|
||||
@@ -67,7 +69,9 @@
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
// clang-format on
|
||||
#include "piwaitevent_p.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
@@ -145,7 +149,8 @@ void PIEthernet::Address::setPort(ushort _port) {
|
||||
|
||||
|
||||
void PIEthernet::Address::set(const PIString & ip_port) {
|
||||
PIString _ip; int p(0);
|
||||
PIString _ip;
|
||||
int p(0);
|
||||
splitIPPort(ip_port, &_ip, &p);
|
||||
port_ = p;
|
||||
initIP(_ip);
|
||||
@@ -176,7 +181,8 @@ bool PIEthernet::Address::isNull() const {
|
||||
|
||||
|
||||
PIEthernet::Address PIEthernet::Address::resolve(const PIString & host_port) {
|
||||
PIString host; int port(0);
|
||||
PIString host;
|
||||
int port(0);
|
||||
splitIPPort(host_port, &host, &port);
|
||||
return resolve(host, port);
|
||||
}
|
||||
@@ -185,10 +191,8 @@ PIEthernet::Address PIEthernet::Address::resolve(const PIString & host_port) {
|
||||
PIEthernet::Address PIEthernet::Address::resolve(const PIString & host, ushort port) {
|
||||
Address ret(0, port);
|
||||
hostent * he = gethostbyname(host.dataAscii());
|
||||
if (!he)
|
||||
return ret;
|
||||
if (he->h_addr_list[0])
|
||||
ret.setIP(*((uint*)(he->h_addr_list[0])));
|
||||
if (!he) return ret;
|
||||
if (he->h_addr_list[0]) ret.setIP(*((uint *)(he->h_addr_list[0])));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -224,7 +228,8 @@ PIEthernet::PIEthernet(): PIIODevice("", ReadWrite) {
|
||||
}
|
||||
|
||||
|
||||
PIEthernet::PIEthernet(PIEthernet::Type type_, const PIString & ip_port, const PIFlags<PIEthernet::Parameters> params_): PIIODevice(ip_port, ReadWrite) {
|
||||
PIEthernet::PIEthernet(PIEthernet::Type type_, const PIString & ip_port, const PIFlags<PIEthernet::Parameters> params_)
|
||||
: PIIODevice(ip_port, ReadWrite) {
|
||||
construct();
|
||||
addr_r.set(ip_port);
|
||||
setType(type_);
|
||||
@@ -282,8 +287,7 @@ bool PIEthernet::init() {
|
||||
if (sock != -1) return true;
|
||||
// piCout << "init " << type();
|
||||
PRIVATE->event.destroy();
|
||||
if (sock_s == sock)
|
||||
sock_s = -1;
|
||||
if (sock_s == sock) sock_s = -1;
|
||||
closeSocket(sock);
|
||||
closeSocket(sock_s);
|
||||
int st = 0, pr = 0;
|
||||
@@ -369,13 +373,14 @@ bool PIEthernet::openDevice() {
|
||||
addr_r.set(path());
|
||||
// if (type() == TCP_Client)
|
||||
// connecting_ = true;
|
||||
if (type() != UDP || mode() == PIIODevice::WriteOnly)
|
||||
return true;
|
||||
if (type() != UDP || mode() == PIIODevice::WriteOnly) return true;
|
||||
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
if (params[PIEthernet::Broadcast]) PRIVATE->addr_.sin_addr.s_addr = INADDR_ANY;
|
||||
else PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
if (params[PIEthernet::Broadcast])
|
||||
PRIVATE->addr_.sin_addr.s_addr = INADDR_ANY;
|
||||
else
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
#ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
#endif
|
||||
@@ -406,12 +411,10 @@ bool PIEthernet::closeDevice() {
|
||||
server_thread_.stop();
|
||||
PRIVATE->event.interrupt();
|
||||
if (server_thread_.isRunning()) {
|
||||
if (!server_thread_.waitForFinish(1000))
|
||||
server_thread_.terminate();
|
||||
if (!server_thread_.waitForFinish(1000)) server_thread_.terminate();
|
||||
}
|
||||
PRIVATE->event.destroy();
|
||||
if (sock_s == sock)
|
||||
sock_s = -1;
|
||||
if (sock_s == sock) sock_s = -1;
|
||||
closeSocket(sock);
|
||||
closeSocket(sock_s);
|
||||
while (!clients_.isEmpty())
|
||||
@@ -425,8 +428,7 @@ bool PIEthernet::closeDevice() {
|
||||
|
||||
|
||||
void PIEthernet::closeSocket(int & sd) {
|
||||
if (sd != -1)
|
||||
ethClosesocket(sd, type() != PIEthernet::UDP);
|
||||
if (sd != -1) ethClosesocket(sd, type() != PIEthernet::UDP);
|
||||
sd = -1;
|
||||
}
|
||||
|
||||
@@ -451,7 +453,8 @@ void PIEthernet::applyTimeout(int fd, int opt, double ms) {
|
||||
#else
|
||||
double s = ms / 1000.;
|
||||
timeval _tm;
|
||||
_tm.tv_sec = piFloord(s); s -= _tm.tv_sec;
|
||||
_tm.tv_sec = piFloord(s);
|
||||
s -= _tm.tv_sec;
|
||||
_tm.tv_usec = s * 1000000.;
|
||||
#endif
|
||||
ethSetsockopt(fd, SOL_SOCKET, opt, &_tm, sizeof(_tm));
|
||||
@@ -461,8 +464,7 @@ void PIEthernet::applyTimeout(int fd, int opt, double ms) {
|
||||
void PIEthernet::applyOptInt(int level, int opt, int val) {
|
||||
if (sock < 0) return;
|
||||
ethSetsockoptInt(sock, level, opt, val);
|
||||
if (sock_s != sock && sock_s != -1)
|
||||
ethSetsockoptInt(sock_s, level, opt, val);
|
||||
if (sock_s != sock && sock_s != -1) ethSetsockoptInt(sock_s, level, opt, val);
|
||||
}
|
||||
|
||||
|
||||
@@ -474,8 +476,7 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
return false;
|
||||
}
|
||||
if (isClosed()) {
|
||||
if (mcast_queue.contains(group))
|
||||
return false;
|
||||
if (mcast_queue.contains(group)) return false;
|
||||
mcast_queue.enqueue(group);
|
||||
if (!mcast_groups.contains(group)) mcast_groups << group;
|
||||
return true;
|
||||
@@ -592,8 +593,7 @@ bool PIEthernet::listen(bool threaded) {
|
||||
if (server_thread_.isRunning()) {
|
||||
if (!server_bounded) return true;
|
||||
server_thread_.stop();
|
||||
if (!server_thread_.waitForFinish(100))
|
||||
server_thread_.terminate();
|
||||
if (!server_thread_.waitForFinish(100)) server_thread_.terminate();
|
||||
}
|
||||
listen_threaded = true;
|
||||
server_bounded = false;
|
||||
@@ -707,8 +707,7 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
// piCoutObj << "connect to " << path() << "...";
|
||||
connected_ = connectTCP();
|
||||
// piCoutObj << "connect to " << path() << connected_;
|
||||
if (!connected_)
|
||||
piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
if (!connected_) piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
opened_.exchange(connected_);
|
||||
if (connected_) {
|
||||
connecting_ = false;
|
||||
@@ -831,13 +830,17 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
PRIVATE->saddr_.sin_addr.s_addr = addr_s.ip();
|
||||
PRIVATE->saddr_.sin_family = AF_INET;
|
||||
// piCoutObj << "write to" << ip_s << ":" << port_s << "socket" << sock_s << max_size << "bytes ...";
|
||||
return ethSendto(sock_s, data, max_size,
|
||||
return ethSendto(sock_s,
|
||||
data,
|
||||
max_size,
|
||||
#ifndef WINDOWS
|
||||
isOptionSet(BlockingWrite) ? 0 : MSG_DONTWAIT
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
, (sockaddr * )&PRIVATE->saddr_, sizeof(PRIVATE->saddr_));
|
||||
,
|
||||
(sockaddr *)&PRIVATE->saddr_,
|
||||
sizeof(PRIVATE->saddr_));
|
||||
// piCout << "[PIEth] write to" << ip_s << ":" << port_s << "ok";
|
||||
case TCP_Client: {
|
||||
if (connecting_) {
|
||||
@@ -851,8 +854,7 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
#endif
|
||||
// piCoutObj << "connect to " << ip << ":" << port_;
|
||||
connected_ = connectTCP();
|
||||
if (!connected_)
|
||||
piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
if (!connected_) piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
opened_.exchange(connected_);
|
||||
if (connected_) {
|
||||
connecting_ = false;
|
||||
@@ -899,7 +901,8 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
remain_size -= sr;
|
||||
}
|
||||
}
|
||||
return ret;}
|
||||
return ret;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
return -1;
|
||||
@@ -1004,7 +1007,8 @@ bool PIEthernet::connectTCP() {
|
||||
}
|
||||
#else
|
||||
if (PRIVATE->event.wait(sock, PIWaitEvent::CheckWrite)) {
|
||||
if (ethIsWriteable(sock)) return true;
|
||||
if (ethIsWriteable(sock))
|
||||
return true;
|
||||
else {
|
||||
closeSocket(sock);
|
||||
init();
|
||||
@@ -1019,8 +1023,7 @@ bool PIEthernet::connectTCP() {
|
||||
long PIEthernet::waitForEvent(PIWaitEvent & event, long mask) {
|
||||
if (!event.isCreate() || sock < 0) return 0;
|
||||
if (WSAEventSelect(sock, event.getEvent(), mask) == SOCKET_ERROR) {
|
||||
if (ethErrorCore() == WSAEINPROGRESS)
|
||||
return 0;
|
||||
if (ethErrorCore() == WSAEINPROGRESS) return 0;
|
||||
}
|
||||
if (event.wait()) {
|
||||
// DWORD wr = WSAWaitForMultipleEvents(1, &(PRIVATE->read_event), FALSE, WSA_INFINITE, TRUE);
|
||||
@@ -1079,14 +1082,26 @@ void PIEthernet::configureFromFullPathDevice(const PIString & full_path) {
|
||||
if (p == "udp") setType(UDP);
|
||||
if (p == "tcp") setType(TCP_Client);
|
||||
break;
|
||||
case 1: setReadIP(p); setSendIP(p); break;
|
||||
case 2: setReadPort(p.toInt()); setSendPort(p.toInt()); break;
|
||||
case 1:
|
||||
setReadIP(p);
|
||||
setSendIP(p);
|
||||
break;
|
||||
case 2:
|
||||
setReadPort(p.toInt());
|
||||
setSendPort(p.toInt());
|
||||
break;
|
||||
case 3: setSendIP(p); break;
|
||||
case 4: setSendPort(p.toInt()); break;
|
||||
}
|
||||
if (i <= 4) continue;
|
||||
if (i % 2 == 1) {if (p.toLowerCase() == "mcast") mcast = true;}
|
||||
else {if (mcast) {joinMulticastGroup(p); mcast = false;}}
|
||||
if (i % 2 == 1) {
|
||||
if (p.toLowerCase() == "mcast") mcast = true;
|
||||
} else {
|
||||
if (mcast) {
|
||||
joinMulticastGroup(p);
|
||||
mcast = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1095,7 +1110,8 @@ PIPropertyStorage PIEthernet::constructVariantDevice() const {
|
||||
PIPropertyStorage ret;
|
||||
PIVariantTypes::Enum e;
|
||||
|
||||
e << "UDP" << "TCP";
|
||||
e << "UDP"
|
||||
<< "TCP";
|
||||
if (type() == PIEthernet::UDP)
|
||||
e.selectValue(0);
|
||||
else
|
||||
@@ -1174,15 +1190,11 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
} else {
|
||||
switch (ret) {
|
||||
case ERROR_NO_DATA: break;
|
||||
case ERROR_NOT_SUPPORTED:
|
||||
piCout << "[PIEthernet] GetAdaptersInfo not supported";
|
||||
break;
|
||||
default:
|
||||
piCout << "[PIEthernet] GetAdaptersInfo failed with error:" << ret;
|
||||
case ERROR_NOT_SUPPORTED: piCout << "[PIEthernet] GetAdaptersInfo not supported"; break;
|
||||
default: piCout << "[PIEthernet] GetAdaptersInfo failed with error:" << ret;
|
||||
}
|
||||
}
|
||||
if (pAdapterInfo)
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
if (pAdapterInfo) HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
#else
|
||||
# ifdef MICRO_PIP
|
||||
# else
|
||||
@@ -1205,12 +1217,9 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
if (in.isEmpty()) continue;
|
||||
ci.name = in;
|
||||
strcpy(ir.ifr_name, in.dataAscii());
|
||||
if (ioctl(s, SIOCGIFHWADDR, &ir) == 0)
|
||||
ci.mac = macFromBytes(PIByteArray(ir.ifr_hwaddr.sa_data, 6));
|
||||
if (ioctl(s, SIOCGIFADDR, &ir) >= 0)
|
||||
ci.address = getSockAddr(&ir.ifr_addr);
|
||||
if (ioctl(s, SIOCGIFNETMASK, &ir) >= 0)
|
||||
ci.netmask = getSockAddr(&ir.ifr_addr);
|
||||
if (ioctl(s, SIOCGIFHWADDR, &ir) == 0) ci.mac = macFromBytes(PIByteArray(ir.ifr_hwaddr.sa_data, 6));
|
||||
if (ioctl(s, SIOCGIFADDR, &ir) >= 0) ci.address = getSockAddr(&ir.ifr_addr);
|
||||
if (ioctl(s, SIOCGIFNETMASK, &ir) >= 0) ci.netmask = getSockAddr(&ir.ifr_addr);
|
||||
ioctl(s, SIOCGIFMTU, &ci.mtu);
|
||||
if (ci.address == "127.0.0.1") ci.flags |= PIEthernet::ifLoopback;
|
||||
il << ci;
|
||||
@@ -1276,10 +1285,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
if (cif->ifa_flags & IFF_POINTOPOINT) ci.flags |= PIEthernet::ifPTP;
|
||||
ci.broadcast.clear();
|
||||
ci.ptp.clear();
|
||||
if (ci.flags[PIEthernet::ifBroadcast])
|
||||
ci.broadcast = getSockAddr(cif->ifa_broadaddr);
|
||||
if (ci.flags[PIEthernet::ifPTP])
|
||||
ci.ptp = getSockAddr(cif->ifa_dstaddr);
|
||||
if (ci.flags[PIEthernet::ifBroadcast]) ci.broadcast = getSockAddr(cif->ifa_broadaddr);
|
||||
if (ci.flags[PIEthernet::ifPTP]) ci.ptp = getSockAddr(cif->ifa_dstaddr);
|
||||
ci.index = if_nametoindex(cif->ifa_name);
|
||||
il << ci;
|
||||
cif = cif->ifa_next;
|
||||
@@ -1309,7 +1316,6 @@ PIEthernet::Address PIEthernet::interfaceAddress(const PIString & interface_) {
|
||||
struct sockaddr_in * sa = (struct sockaddr_in *)&ifr.ifr_addr;
|
||||
return Address(uint(sa->sin_addr.s_addr));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1344,7 +1350,13 @@ PIString PIEthernet::ethErrorString() {
|
||||
#ifdef WINDOWS
|
||||
char * msg = nullptr;
|
||||
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);
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
err,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&msg,
|
||||
0,
|
||||
NULL);
|
||||
PIString ret = PIStringAscii("code ") + PIString::fromNumber(err) + PIStringAscii(" - ");
|
||||
if (msg) {
|
||||
ret += PIString::fromSystem(msg).trim();
|
||||
@@ -1364,7 +1376,9 @@ int PIEthernet::ethRecv(int sock, void * buf, int size, int flags) {
|
||||
#ifdef WINDOWS
|
||||
(char *)
|
||||
#endif
|
||||
buf, size, flags);
|
||||
buf,
|
||||
size,
|
||||
flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -1378,7 +1392,11 @@ int PIEthernet::ethRecvfrom(int sock, void * buf, int size, int flags, sockaddr
|
||||
# ifdef WINDOWS
|
||||
(char *)
|
||||
# endif
|
||||
buf, size, flags, addr, &len);
|
||||
buf,
|
||||
size,
|
||||
flags,
|
||||
addr,
|
||||
&len);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1389,14 +1407,19 @@ int PIEthernet::ethSendto(int sock, const void * buf, int size, int flags, socka
|
||||
#ifdef WINDOWS
|
||||
(const char *)
|
||||
#endif
|
||||
buf, size, flags, addr, addr_len);
|
||||
buf,
|
||||
size,
|
||||
flags,
|
||||
addr,
|
||||
addr_len);
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::ethClosesocket(int sock, bool shutdown) {
|
||||
// piCout << "close socket" << sock << shutdown;
|
||||
if (sock < 0) return;
|
||||
if (shutdown) ::shutdown(sock,
|
||||
if (shutdown)
|
||||
::shutdown(sock,
|
||||
#ifdef WINDOWS
|
||||
SD_BOTH);
|
||||
closesocket(sock);
|
||||
@@ -1409,11 +1432,14 @@ void PIEthernet::ethClosesocket(int sock, bool shutdown) {
|
||||
|
||||
int PIEthernet::ethSetsockopt(int sock, int level, int optname, const void * optval, int optlen) {
|
||||
if (sock < 0) return -1;
|
||||
return setsockopt(sock, level, optname,
|
||||
return setsockopt(sock,
|
||||
level,
|
||||
optname,
|
||||
#ifdef WINDOWS
|
||||
(char *)
|
||||
#endif
|
||||
optval, optlen);
|
||||
optval,
|
||||
optlen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
#ifndef PIETHERNET_H
|
||||
#define PIETHERNET_H
|
||||
|
||||
#include "pitimer.h"
|
||||
#include "piiodevice.h"
|
||||
#include "pitimer.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
struct
|
||||
@@ -36,12 +36,11 @@ class
|
||||
#endif
|
||||
sockaddr;
|
||||
|
||||
class PIP_EXPORT PIEthernet: public PIIODevice
|
||||
{
|
||||
class PIP_EXPORT PIEthernet: public PIIODevice {
|
||||
PIIODEVICE(PIEthernet, "eth");
|
||||
friend class PIPeer;
|
||||
public:
|
||||
|
||||
public:
|
||||
//! Contructs UDP %PIEthernet with empty read address
|
||||
explicit PIEthernet();
|
||||
|
||||
@@ -57,7 +56,8 @@ public:
|
||||
ReuseAddress /** Rebind address if there is already binded. Enabled by default */ = 0x1,
|
||||
Broadcast /** Broadcast send. Disabled by default */ = 0x2,
|
||||
SeparateSockets /** If this parameter is set, %PIEthernet will initialize two different sockets,
|
||||
for receive and send, instead of single one. Disabled by default */ = 0x4,
|
||||
for receive and send, instead of single one. Disabled by default */
|
||||
= 0x4,
|
||||
MulticastLoop /** Enable receiving multicast packets from same host. Enabled by default */ = 0x8,
|
||||
KeepConnection /** Automatic reconnect TCP connection on disconnect. Enabled by default */ = 0x10,
|
||||
DisonnectOnTimeout /** Disconnect TCP connection on read timeout expired. Disabled by default */ = 0x20
|
||||
@@ -67,8 +67,8 @@ public:
|
||||
//! \brief IPv4 network address, IP and port
|
||||
class PIP_EXPORT Address {
|
||||
friend class PIEthernet;
|
||||
public:
|
||||
|
||||
public:
|
||||
//! Contructs %Address with binary representation of IP and port
|
||||
Address(uint ip = 0, ushort port = 0);
|
||||
|
||||
@@ -121,6 +121,7 @@ public:
|
||||
static Address resolve(const PIString & host, ushort port);
|
||||
|
||||
static void splitIPPort(const PIString & ipp, PIString * ip, int * port);
|
||||
|
||||
private:
|
||||
void initIP(const PIString & _ip);
|
||||
union {
|
||||
@@ -132,25 +133,43 @@ public:
|
||||
|
||||
|
||||
//! Contructs %PIEthernet with type "type", read address "ip_port" and parameters "params"
|
||||
explicit PIEthernet(Type type, const PIString & ip_port = PIString(), const PIFlags<Parameters> params = PIEthernet::ReuseAddress | PIEthernet::MulticastLoop | PIEthernet::KeepConnection);
|
||||
explicit PIEthernet(Type type,
|
||||
const PIString & ip_port = PIString(),
|
||||
const PIFlags<Parameters> params = PIEthernet::ReuseAddress | PIEthernet::MulticastLoop |
|
||||
PIEthernet::KeepConnection);
|
||||
|
||||
virtual ~PIEthernet();
|
||||
|
||||
|
||||
//! Set read address
|
||||
void setReadAddress(const PIString & ip, int port) {addr_r.set(ip, port); setPath(addr_r.toString());}
|
||||
void setReadAddress(const PIString & ip, int port) {
|
||||
addr_r.set(ip, port);
|
||||
setPath(addr_r.toString());
|
||||
}
|
||||
|
||||
//! Set read address in format "i.i.i.i:p"
|
||||
void setReadAddress(const PIString & ip_port) {addr_r.set(ip_port); setPath(addr_r.toString());}
|
||||
void setReadAddress(const PIString & ip_port) {
|
||||
addr_r.set(ip_port);
|
||||
setPath(addr_r.toString());
|
||||
}
|
||||
|
||||
//! Set read address
|
||||
void setReadAddress(const Address & addr) {addr_r = addr; setPath(addr_r.toString());}
|
||||
void setReadAddress(const Address & addr) {
|
||||
addr_r = addr;
|
||||
setPath(addr_r.toString());
|
||||
}
|
||||
|
||||
//! Set read IP
|
||||
void setReadIP(const PIString & ip) {addr_r.setIP(ip); setPath(addr_r.toString());}
|
||||
void setReadIP(const PIString & ip) {
|
||||
addr_r.setIP(ip);
|
||||
setPath(addr_r.toString());
|
||||
}
|
||||
|
||||
//! Set read port
|
||||
void setReadPort(int port) {addr_r.setPort(port); setPath(addr_r.toString());}
|
||||
void setReadPort(int port) {
|
||||
addr_r.setPort(port);
|
||||
setPath(addr_r.toString());
|
||||
}
|
||||
|
||||
|
||||
//! Set send address
|
||||
@@ -256,13 +275,22 @@ public:
|
||||
bool connect(bool threaded = true);
|
||||
|
||||
//! Connect to TCP server with address "ip":"port". Use only for TCP_Client
|
||||
bool connect(const PIString & ip, int port, bool threaded = true) {setPath(ip + PIStringAscii(":") + PIString::fromNumber(port)); return connect(threaded);}
|
||||
bool connect(const PIString & ip, int port, bool threaded = true) {
|
||||
setPath(ip + PIStringAscii(":") + PIString::fromNumber(port));
|
||||
return connect(threaded);
|
||||
}
|
||||
|
||||
//! Connect to TCP server with address "ip_port". Use only for TCP_Client
|
||||
bool connect(const PIString & ip_port, bool threaded = true) {setPath(ip_port); return connect(threaded);}
|
||||
bool connect(const PIString & ip_port, bool threaded = true) {
|
||||
setPath(ip_port);
|
||||
return connect(threaded);
|
||||
}
|
||||
|
||||
//! Connect to TCP server with address "addr". Use only for TCP_Client
|
||||
bool connect(const Address & addr, bool threaded = true) {setPath(addr.toString()); return connect(threaded);}
|
||||
bool connect(const Address & addr, bool threaded = true) {
|
||||
setPath(addr.toString());
|
||||
return connect(threaded);
|
||||
}
|
||||
|
||||
//! Returns if %PIEthernet connected to TCP server. Use only for TCP_Client
|
||||
bool isConnected() const { return connected_; }
|
||||
@@ -292,10 +320,14 @@ public:
|
||||
bool send(const void * data, int size, bool threaded = false);
|
||||
|
||||
//! Send data "data" with size "size" to address "ip":"port"
|
||||
bool send(const PIString & ip, int port, const void * data, int size, bool threaded = false) {return send(PIEthernet::Address(ip, port), data, size, threaded);}
|
||||
bool send(const PIString & ip, int port, const void * data, int size, bool threaded = false) {
|
||||
return send(PIEthernet::Address(ip, port), data, size, threaded);
|
||||
}
|
||||
|
||||
//! Send data "data" with size "size" to address "ip_port"
|
||||
bool send(const PIString & ip_port, const void * data, int size, bool threaded = false) {return send(PIEthernet::Address(ip_port), data, size, threaded);}
|
||||
bool send(const PIString & ip_port, const void * data, int size, bool threaded = false) {
|
||||
return send(PIEthernet::Address(ip_port), data, size, threaded);
|
||||
}
|
||||
|
||||
//! Send data "data" with size "size" to address "addr"
|
||||
bool send(const Address & addr, const void * data, int size, bool threaded = false);
|
||||
@@ -304,10 +336,14 @@ public:
|
||||
bool send(const PIByteArray & data, bool threaded = false);
|
||||
|
||||
//! Send data "data" to address "ip":"port" for UDP
|
||||
bool send(const PIString & ip, int port, const PIByteArray & data, bool threaded = false) {return send(PIEthernet::Address(ip, port), data, threaded);}
|
||||
bool send(const PIString & ip, int port, const PIByteArray & data, bool threaded = false) {
|
||||
return send(PIEthernet::Address(ip, port), data, threaded);
|
||||
}
|
||||
|
||||
//! Send data "data" to address "ip_port" for UDP
|
||||
bool send(const PIString & ip_port, const PIByteArray & data, bool threaded = false) {return send(PIEthernet::Address(ip_port), data, threaded);}
|
||||
bool send(const PIString & ip_port, const PIByteArray & data, bool threaded = false) {
|
||||
return send(PIEthernet::Address(ip_port), data, threaded);
|
||||
}
|
||||
|
||||
//! Send data "data" to address "addr" for UDP
|
||||
bool send(const Address & addr, const PIByteArray & data, bool threaded = false);
|
||||
@@ -339,7 +375,6 @@ public:
|
||||
|
||||
//! Network interface descriptor
|
||||
struct PIP_EXPORT Interface {
|
||||
|
||||
//! System index
|
||||
int index;
|
||||
|
||||
@@ -393,16 +428,32 @@ public:
|
||||
InterfaceList(): PIVector<PIEthernet::Interface>() {}
|
||||
|
||||
//! Get interface with system index "index" or 0 if there is no one
|
||||
const Interface * getByIndex(int index) const {for (int i = 0; i < size_s(); ++i) if ((*this)[i].index == index) return &((*this)[i]); return 0;}
|
||||
const Interface * getByIndex(int index) const {
|
||||
for (int i = 0; i < size_s(); ++i)
|
||||
if ((*this)[i].index == index) return &((*this)[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//! Get interface with system name "name" or 0 if there is no one
|
||||
const Interface * getByName(const PIString & name) const {for (int i = 0; i < size_s(); ++i) if ((*this)[i].name == name) return &((*this)[i]); return 0;}
|
||||
const Interface * getByName(const PIString & name) const {
|
||||
for (int i = 0; i < size_s(); ++i)
|
||||
if ((*this)[i].name == name) return &((*this)[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//! Get interface with IP address "address" or 0 if there is no one
|
||||
const Interface * getByAddress(const PIString & address) const {for (int i = 0; i < size_s(); ++i) if ((*this)[i].address == address) return &((*this)[i]); return 0;}
|
||||
const Interface * getByAddress(const PIString & address) const {
|
||||
for (int i = 0; i < size_s(); ++i)
|
||||
if ((*this)[i].address == address) return &((*this)[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//! Get loopback interface or 0 if there is no one
|
||||
const Interface * getLoopback() const {for (int i = 0; i < size_s(); ++i) if ((*this)[i].isLoopback()) return &((*this)[i]); return 0;}
|
||||
const Interface * getLoopback() const {
|
||||
for (int i = 0; i < size_s(); ++i)
|
||||
if ((*this)[i].isLoopback()) return &((*this)[i]);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -518,15 +569,30 @@ private:
|
||||
static int ethSetsockoptBool(int sock, int level, int optname, bool value = true);
|
||||
static void ethNonblocking(int sock);
|
||||
static bool ethIsWriteable(int sock);
|
||||
|
||||
};
|
||||
|
||||
inline bool operator <(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name < v1.name);}
|
||||
inline bool operator ==(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name == v1.name && v0.address == v1.address && v0.netmask == v1.netmask);}
|
||||
inline bool operator !=(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name != v1.name || v0.address != v1.address || v0.netmask != v1.netmask);}
|
||||
inline PICout operator <<(PICout s, const PIEthernet::Address & v) {s.space(); s.saveAndSetControls(0); s << "Address(" << v.toString() << ")"; s.restoreControls(); return s;}
|
||||
inline bool operator<(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {
|
||||
return (v0.name < v1.name);
|
||||
}
|
||||
inline bool operator==(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {
|
||||
return (v0.name == v1.name && v0.address == v1.address && v0.netmask == v1.netmask);
|
||||
}
|
||||
inline bool operator!=(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {
|
||||
return (v0.name != v1.name || v0.address != v1.address || v0.netmask != v1.netmask);
|
||||
}
|
||||
inline PICout operator<<(PICout s, const PIEthernet::Address & v) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
s << "Address(" << v.toString() << ")";
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
|
||||
inline bool operator ==(const PIEthernet::Address & v0, const PIEthernet::Address & v1) {return (v0.ip() == v1.ip() && v0.port() == v1.port());}
|
||||
inline bool operator !=(const PIEthernet::Address & v0, const PIEthernet::Address & v1) {return (v0.ip() != v1.ip() || v0.port() != v1.port());}
|
||||
inline bool operator==(const PIEthernet::Address & v0, const PIEthernet::Address & v1) {
|
||||
return (v0.ip() == v1.ip() && v0.port() == v1.port());
|
||||
}
|
||||
inline bool operator!=(const PIEthernet::Address & v0, const PIEthernet::Address & v1) {
|
||||
return (v0.ip() != v1.ip() || v0.port() != v1.port());
|
||||
}
|
||||
|
||||
#endif // PIETHERNET_H
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "pifile.h"
|
||||
|
||||
#include "pidir.h"
|
||||
#include "piincludes_p.h"
|
||||
#include "piiostream.h"
|
||||
#include "pitime_win.h"
|
||||
#ifdef WINDOWS
|
||||
@@ -36,9 +37,9 @@
|
||||
# define S_IFCHR 0x10
|
||||
# define S_IFSOCK 0x20
|
||||
#else
|
||||
# include <fcntl.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/time.h>
|
||||
# include <fcntl.h>
|
||||
# include <utime.h>
|
||||
#endif
|
||||
#define S_IFHDN 0x40
|
||||
@@ -152,10 +153,7 @@ PIString PIFile::FileInfo::dir() const {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PIFile::PIFile(): PIIODevice() {
|
||||
}
|
||||
PIFile::PIFile(): PIIODevice() {}
|
||||
|
||||
|
||||
PIFile::PIFile(const PIString & path, PIIODevice::DeviceMode mode): PIIODevice(path, mode) {
|
||||
@@ -264,9 +262,11 @@ PIByteArray PIFile::readAll(bool forceRead) {
|
||||
llong PIFile::size() const {
|
||||
if (isClosed()) return -1;
|
||||
llong s, cp = pos();
|
||||
_fseek_call_(PRIVATE->fd, 0, SEEK_END); clearerr(PRIVATE->fd);
|
||||
_fseek_call_(PRIVATE->fd, 0, SEEK_END);
|
||||
clearerr(PRIVATE->fd);
|
||||
s = pos();
|
||||
_fseek_call_(PRIVATE->fd, cp, SEEK_SET); clearerr(PRIVATE->fd);
|
||||
_fseek_call_(PRIVATE->fd, cp, SEEK_SET);
|
||||
clearerr(PRIVATE->fd);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -289,7 +289,6 @@ void PIFile::resize(llong new_size, uchar fill_) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool PIFile::isExists(const PIString & path) {
|
||||
FILE * f = _fopen_call_(PIString(path).data(), "r");
|
||||
bool ok = (f != 0);
|
||||
@@ -410,8 +409,7 @@ bool PIFile::isEnd() const {
|
||||
if (isClosed()) return true;
|
||||
bool ret = (feof(PRIVATE->fd) || ferror(PRIVATE->fd));
|
||||
if (!ret && (_size >= 0)) {
|
||||
if (pos() > _size)
|
||||
ret = true;
|
||||
if (pos() > _size) ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -466,8 +464,6 @@ void PIFile::remove() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PIFile::FileInfo PIFile::fileInfo(const PIString & path) {
|
||||
FileInfo ret;
|
||||
if (path.isEmpty()) return ret;
|
||||
@@ -490,14 +486,16 @@ PIFile::FileInfo PIFile::fileInfo(const PIString & path) {
|
||||
LARGE_INTEGER filesize;
|
||||
filesize.LowPart = filesize.HighPart = 0;
|
||||
if (fi.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ret.flags |= FileInfo::Hidden;
|
||||
if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ret.flags |= FileInfo::Dir;
|
||||
if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
ret.flags |= FileInfo::Dir;
|
||||
else {
|
||||
ret.flags |= FileInfo::File;
|
||||
filesize.LowPart = fi.nFileSizeLow;
|
||||
filesize.HighPart = fi.nFileSizeHigh;
|
||||
}
|
||||
PIString ext = ret.extension();
|
||||
ret.perm_user = FileInfo::Permissions(true, (attr & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY, ext == "bat" || ext == "exe");
|
||||
ret.perm_user =
|
||||
FileInfo::Permissions(true, (attr & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY, ext == "bat" || ext == "exe");
|
||||
ret.perm_group = ret.perm_other = ret.perm_user;
|
||||
ret.size = filesize.QuadPart;
|
||||
ret.time_access = FILETIME2PIDateTime(fi.ftLastAccessTime);
|
||||
@@ -567,7 +565,13 @@ bool PIFile::applyFileInfo(const PIString & path, const PIFile::FileInfo & info)
|
||||
}
|
||||
HANDLE hFile = 0;
|
||||
if ((attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) {
|
||||
hFile = CreateFileA(path.data(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||
hFile = CreateFileA(path.data(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
0,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS,
|
||||
0);
|
||||
} else {
|
||||
hFile = CreateFileA(path.data(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
|
||||
}
|
||||
|
||||
@@ -34,11 +34,10 @@
|
||||
//! \~\brief
|
||||
//! \~english Local file.
|
||||
//! \~russian Локальный файл.
|
||||
class PIP_EXPORT PIFile: public PIIODevice
|
||||
{
|
||||
class PIP_EXPORT PIFile: public PIIODevice {
|
||||
PIIODEVICE(PIFile, "file");
|
||||
public:
|
||||
|
||||
public:
|
||||
//! \~english Constructs file with empty path
|
||||
//! \~russian Создает файл с пустым путём
|
||||
explicit PIFile();
|
||||
@@ -55,10 +54,13 @@ public:
|
||||
//! \~english Local file or directory information.
|
||||
//! \~russian Информация о локальном файле или директории.
|
||||
struct PIP_EXPORT FileInfo {
|
||||
|
||||
//! \~english Constructs %FileInfo with path "path_". No information gathered
|
||||
//! \~russian Создает %FileInfo с путём "path_". Информация не собирается
|
||||
FileInfo(const PIString & path_ = PIString()) {path = path_; size = 0; id_group = id_user = 0;}
|
||||
FileInfo(const PIString & path_ = PIString()) {
|
||||
path = path_;
|
||||
size = 0;
|
||||
id_group = id_user = 0;
|
||||
}
|
||||
|
||||
//! \~english Type flags
|
||||
//! \~russian Флаги типа
|
||||
@@ -78,7 +80,11 @@ public:
|
||||
//! \~russian Разрешения локального файла или директории.
|
||||
struct PIP_EXPORT Permissions {
|
||||
Permissions(uchar r = 0): raw(r) {}
|
||||
Permissions(bool r, bool w, bool e): raw(0) {read = r; write = w; exec = e;}
|
||||
Permissions(bool r, bool w, bool e): raw(0) {
|
||||
read = r;
|
||||
write = w;
|
||||
exec = e;
|
||||
}
|
||||
|
||||
//! \~english Returns as string (from "---" to "rwx")
|
||||
//! \~russian Возвращает как строку (от "---" до "rwx")
|
||||
@@ -87,7 +93,10 @@ public:
|
||||
//! \~english Convertion to \c int
|
||||
//! \~russian Преобразование в \c int
|
||||
operator int() const { return raw; }
|
||||
Permissions & operator =(int v) {raw = v; return *this;}
|
||||
Permissions & operator=(int v) {
|
||||
raw = v;
|
||||
return *this;
|
||||
}
|
||||
union {
|
||||
uchar raw;
|
||||
struct {
|
||||
@@ -170,7 +179,6 @@ public:
|
||||
//! \~english Returns if Hidden flag set
|
||||
//! \~russian Возвращает установлен ли флаг Hidden
|
||||
bool isHidden() const { return flags[Hidden]; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -325,7 +333,6 @@ private:
|
||||
int fdi = -1;
|
||||
llong _size = -1;
|
||||
PIString prec_str;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -334,10 +341,9 @@ private:
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
inline PICout operator<<(PICout s, const PIFile::FileInfo & v) {
|
||||
s.saveAndSetControls(0);
|
||||
s << "FileInfo(\"" << v.path << "\", " << PIString::readableSize(v.size) << ", "
|
||||
<< v.perm_user.toString() << " " << v.perm_group.toString() << " " << v.perm_other.toString() << ", "
|
||||
<< v.time_access.toString() << ", " << v.time_modification.toString()
|
||||
<< ", 0x" << PICoutManipulators::Hex << v.flags << ")";
|
||||
s << "FileInfo(\"" << v.path << "\", " << PIString::readableSize(v.size) << ", " << v.perm_user.toString() << " "
|
||||
<< v.perm_group.toString() << " " << v.perm_other.toString() << ", " << v.time_access.toString() << ", "
|
||||
<< v.time_modification.toString() << ", 0x" << PICoutManipulators::Hex << v.flags << ")";
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
@@ -347,8 +353,8 @@ inline PICout operator <<(PICout s, const PIFile::FileInfo & v) {
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIFile::FileInfo) {
|
||||
s << v.path << v.size << v.time_access << v.time_modification <<
|
||||
v.flags << v.id_user << v.id_group << v.perm_user.raw << v.perm_group.raw << v.perm_other.raw;
|
||||
s << v.path << v.size << v.time_access << v.time_modification << v.flags << v.id_user << v.id_group << v.perm_user.raw
|
||||
<< v.perm_group.raw << v.perm_other.raw;
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -356,8 +362,8 @@ BINARY_STREAM_WRITE(PIFile::FileInfo) {
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ(PIFile::FileInfo) {
|
||||
s >> v.path >> v.size >> v.time_access >> v.time_modification >>
|
||||
v.flags >> v.id_user >> v.id_group >> v.perm_user.raw >> v.perm_group.raw >> v.perm_other.raw;
|
||||
s >> v.path >> v.size >> v.time_access >> v.time_modification >> v.flags >> v.id_user >> v.id_group >> v.perm_user.raw >>
|
||||
v.perm_group.raw >> v.perm_other.raw;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
# define GPIO_SYS_CLASS
|
||||
#endif
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
# include <cstdlib>
|
||||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
# include <cstdlib>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -64,8 +64,7 @@
|
||||
//!
|
||||
|
||||
|
||||
PIGPIO::PIGPIO(): PIThread() {
|
||||
}
|
||||
PIGPIO::PIGPIO(): PIThread() {}
|
||||
|
||||
|
||||
PIGPIO::~PIGPIO() {
|
||||
@@ -92,7 +91,6 @@ PIGPIO * PIGPIO::instance() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
PIString PIGPIO::GPIOName(int gpio_num) {
|
||||
return PIStringAscii("gpio") + PIString::fromNumber(gpio_num);
|
||||
}
|
||||
@@ -222,12 +220,8 @@ void PIGPIO::initPin(int gpio_num, Direction dir) {
|
||||
int ret = 0;
|
||||
NO_UNUSED(ret);
|
||||
switch (dir) {
|
||||
case In:
|
||||
ret = system(("echo in >> /sys/class/gpio/" + g.name + "/direction").dataAscii());
|
||||
break;
|
||||
case Out:
|
||||
ret = system(("echo out >> /sys/class/gpio/" + g.name + "/direction").dataAscii());
|
||||
break;
|
||||
case In: ret = system(("echo in >> /sys/class/gpio/" + g.name + "/direction").dataAscii()); break;
|
||||
case Out: ret = system(("echo out >> /sys/class/gpio/" + g.name + "/direction").dataAscii()); break;
|
||||
default: break;
|
||||
}
|
||||
openGPIO(g);
|
||||
@@ -242,8 +236,10 @@ void PIGPIO::pinSet(int gpio_num, bool value) {
|
||||
int ret = 0;
|
||||
NO_UNUSED(ret);
|
||||
if (g.fd != -1) {
|
||||
if (value) ret = ::write(g.fd, "1", 1);
|
||||
else ret = ::write(g.fd, "0", 1);
|
||||
if (value)
|
||||
ret = ::write(g.fd, "1", 1);
|
||||
else
|
||||
ret = ::write(g.fd, "0", 1);
|
||||
}
|
||||
// piCoutObj << "pinSet" << gpio_num << ":" << ret << errorString();
|
||||
#endif
|
||||
|
||||
@@ -33,11 +33,10 @@
|
||||
//! \~\brief
|
||||
//! \~english GPIO support.
|
||||
//! \~russian Поддержка GPIO.
|
||||
class PIP_EXPORT PIGPIO: public PIThread
|
||||
{
|
||||
class PIP_EXPORT PIGPIO: public PIThread {
|
||||
PIOBJECT_SUBCLASS(PIGPIO, PIThread);
|
||||
public:
|
||||
|
||||
public:
|
||||
//! \~english Work mode for pin
|
||||
//! \~russian Режим работы пина
|
||||
enum Direction {
|
||||
@@ -103,7 +102,10 @@ private:
|
||||
NO_COPY_CLASS(PIGPIO);
|
||||
|
||||
struct PIP_EXPORT GPIOData {
|
||||
GPIOData() {dir = PIGPIO::In; num = fd = -1;}
|
||||
GPIOData() {
|
||||
dir = PIGPIO::In;
|
||||
num = fd = -1;
|
||||
}
|
||||
PIString name;
|
||||
int dir;
|
||||
int num;
|
||||
@@ -121,7 +123,6 @@ private:
|
||||
PIMap<int, GPIOData> gpio_;
|
||||
PIMap<int, bool> watch_state;
|
||||
PIMutex mutex;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -33,11 +33,10 @@
|
||||
//! \~\brief
|
||||
//! \~english PIIODevice wrapper around PIByteArray
|
||||
//! \~russian Обёртка PIIODevice вокруг PIByteArray
|
||||
class PIP_EXPORT PIIOByteArray: public PIIODevice
|
||||
{
|
||||
class PIP_EXPORT PIIOByteArray: public PIIODevice {
|
||||
PIIODEVICE(PIIOByteArray, "");
|
||||
public:
|
||||
|
||||
public:
|
||||
//! \~english Contructs %PIIOByteArray with "buffer" content and "mode" open mode
|
||||
//! \~russian Создает %PIIOByteArray с содержимым "buffer" и режимом открытия "mode"
|
||||
explicit PIIOByteArray(PIByteArray * buffer = 0, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||
@@ -52,7 +51,10 @@ public:
|
||||
|
||||
//! \~english Clear content buffer
|
||||
//! \~russian Очищает содержимое буфера
|
||||
void clear() {if (data_) data_->clear(); pos = 0;}
|
||||
void clear() {
|
||||
if (data_) data_->clear();
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
//! \~english Open "buffer" content with "mode" open mode
|
||||
//! \~russian Открывает содержимое "buffer" с режимом открытия "mode"
|
||||
@@ -64,7 +66,10 @@ public:
|
||||
|
||||
//! \~english Returns if position is at the end of content
|
||||
//! \~russian Возвращает в конце содержимого ли позиция
|
||||
bool isEnd() const {if (!data_) return true; return pos >= data_->size_s();}
|
||||
bool isEnd() const {
|
||||
if (!data_) return true;
|
||||
return pos >= data_->size_s();
|
||||
}
|
||||
|
||||
|
||||
//! \~english Move read/write position to "position"
|
||||
@@ -73,11 +78,15 @@ public:
|
||||
|
||||
//! \~english Move read/write position to the beginning of the buffer
|
||||
//! \~russian Перемещает позицию чтения/записи на начало буфера
|
||||
void seekToBegin() {if (data_) pos = 0;}
|
||||
void seekToBegin() {
|
||||
if (data_) pos = 0;
|
||||
}
|
||||
|
||||
//! \~english Move read/write position to the end of the buffer
|
||||
//! \~russian Перемещает позицию чтения/записи на конец буфера
|
||||
void seekToEnd() {if (data_) pos = data_->size_s();}
|
||||
void seekToEnd() {
|
||||
if (data_) pos = data_->size_s();
|
||||
}
|
||||
|
||||
|
||||
//! \~english Insert data "ba" into content at current position
|
||||
@@ -85,8 +94,10 @@ public:
|
||||
int writeByteArray(const PIByteArray & ba);
|
||||
|
||||
ssize_t bytesAvailable() const override {
|
||||
if (data_) return data_->size();
|
||||
else return 0;
|
||||
if (data_)
|
||||
return data_->size();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -97,7 +108,6 @@ protected:
|
||||
|
||||
ssize_t pos;
|
||||
PIByteArray * data_;
|
||||
|
||||
};
|
||||
|
||||
#endif // PIIOBYTEARRAY_H
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "piiodevice.h"
|
||||
|
||||
#include "piconfig.h"
|
||||
#include "piconnection.h"
|
||||
#include "pipropertystorage.h"
|
||||
@@ -235,8 +236,7 @@ bool PIIODevice::isThreadedWrite() const {
|
||||
|
||||
|
||||
void PIIODevice::startThreadedWrite() {
|
||||
if (!write_thread.isRunning())
|
||||
write_thread.startOnce();
|
||||
if (!write_thread.isRunning()) write_thread.startOnce();
|
||||
}
|
||||
|
||||
|
||||
@@ -316,7 +316,9 @@ void PIIODevice::_init() {
|
||||
read_thread.setName("__S__.PIIODevice.read_thread");
|
||||
write_thread.setName("__S__.PIIODevice.write_thread");
|
||||
CONNECT(void, &write_thread, started, this, write_func);
|
||||
CONNECTL(&read_thread, started, [this](){if (!isOpened()) open();});
|
||||
CONNECTL(&read_thread, started, [this]() {
|
||||
if (!isOpened()) open();
|
||||
});
|
||||
read_thread.setSlot([this](void *) { read_func(); });
|
||||
}
|
||||
|
||||
@@ -339,8 +341,7 @@ void PIIODevice::write_func() {
|
||||
PIIODevice * PIIODevice::newDeviceByPrefix(const char * prefix) {
|
||||
if (!prefix) return nullptr;
|
||||
auto fi = fabrics().value(prefix);
|
||||
if (fi.fabricator)
|
||||
return fi.fabricator();
|
||||
if (fi.fabricator) return fi.fabricator();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -381,8 +382,10 @@ PIByteArray PIIODevice::readForTime(double timeout_ms) {
|
||||
tm.reset();
|
||||
while (tm.elapsed_m() < timeout_ms) {
|
||||
ret = read(td, threaded_read_buffer_size);
|
||||
if (ret <= 0) piMinSleep();
|
||||
else str.append(td, ret);
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else
|
||||
str.append(td, ret);
|
||||
}
|
||||
delete[] td;
|
||||
return str;
|
||||
@@ -442,8 +445,10 @@ bool PIIODevice::configure(const PIString & config_file, const PIString & sectio
|
||||
if (!conf.isOpened()) return false;
|
||||
bool ex = true;
|
||||
PIConfig::Entry em;
|
||||
if (section.isEmpty()) em = conf.rootEntry();
|
||||
else em = conf.getValue(section, PIString(), &ex);
|
||||
if (section.isEmpty())
|
||||
em = conf.rootEntry();
|
||||
else
|
||||
em = conf.getValue(section, PIString(), &ex);
|
||||
if (!ex) return false;
|
||||
PIConfig::Entry * ep = 0;
|
||||
if (parent_section) ep = em.parent();
|
||||
@@ -508,11 +513,14 @@ void PIIODevice::splitFullPath(PIString fpwm, PIString * full_path, DeviceMode *
|
||||
dm |= ReadOnly;
|
||||
if (o == PIStringAscii("w") || o == PIStringAscii("wo") || o == PIStringAscii("write") || o == PIStringAscii("writeonly"))
|
||||
dm |= WriteOnly;
|
||||
if (o == PIStringAscii("br") || o == PIStringAscii("blockr") || o == PIStringAscii("blockread") || o == PIStringAscii("blockingread"))
|
||||
if (o == PIStringAscii("br") || o == PIStringAscii("blockr") || o == PIStringAscii("blockread") ||
|
||||
o == PIStringAscii("blockingread"))
|
||||
op |= BlockingRead;
|
||||
if (o == PIStringAscii("bw") || o == PIStringAscii("blockw") || o == PIStringAscii("blockwrite") || o == PIStringAscii("blockingwrite"))
|
||||
if (o == PIStringAscii("bw") || o == PIStringAscii("blockw") || o == PIStringAscii("blockwrite") ||
|
||||
o == PIStringAscii("blockingwrite"))
|
||||
op |= BlockingWrite;
|
||||
if (o == PIStringAscii("brw") || o == PIStringAscii("bwr") || o == PIStringAscii("blockrw") || o == PIStringAscii("blockwr") || o == PIStringAscii("blockreadrite") || o == PIStringAscii("blockingreadwrite"))
|
||||
if (o == PIStringAscii("brw") || o == PIStringAscii("bwr") || o == PIStringAscii("blockrw") || o == PIStringAscii("blockwr") ||
|
||||
o == PIStringAscii("blockreadrite") || o == PIStringAscii("blockingreadwrite"))
|
||||
op |= BlockingRead | BlockingWrite;
|
||||
}
|
||||
fpwm.cutRight(fpwm.length() - fpwm.findLast('(')).trim();
|
||||
@@ -557,10 +565,26 @@ PIString PIIODevice::fullPathOptions() const {
|
||||
if (mode_ == ReadWrite && options_ == 0) return PIString();
|
||||
PIString ret(" (");
|
||||
bool f = true;
|
||||
if (mode_ == ReadOnly) {if (!f) ret += ","; f = false; ret += "ro";}
|
||||
if (mode_ == WriteOnly) {if (!f) ret += ","; f = false; ret += "wo";}
|
||||
if (options_[BlockingRead]) {if (!f) ret += ","; f = false; ret += "br";}
|
||||
if (options_[BlockingWrite]) {if (!f) ret += ","; f = false; ret += "bw";}
|
||||
if (mode_ == ReadOnly) {
|
||||
if (!f) ret += ",";
|
||||
f = false;
|
||||
ret += "ro";
|
||||
}
|
||||
if (mode_ == WriteOnly) {
|
||||
if (!f) ret += ",";
|
||||
f = false;
|
||||
ret += "wo";
|
||||
}
|
||||
if (options_[BlockingRead]) {
|
||||
if (!f) ret += ",";
|
||||
f = false;
|
||||
ret += "br";
|
||||
}
|
||||
if (options_[BlockingWrite]) {
|
||||
if (!f) ret += ",";
|
||||
f = false;
|
||||
ret += "bw";
|
||||
}
|
||||
return ret + ")";
|
||||
}
|
||||
|
||||
@@ -636,5 +660,3 @@ PIPropertyStorage PIIODevice::constructVariantDevice() const {
|
||||
void PIIODevice::configureFromVariantDevice(const PIPropertyStorage & d) {
|
||||
setPath(d.propertyValueByName("path").toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
#define PIIODEVICE_H
|
||||
|
||||
#include "piinit.h"
|
||||
#include "pitimer.h"
|
||||
#include "piqueue.h"
|
||||
#include "pitimer.h"
|
||||
|
||||
/// TODO: написать документацию, тут ничего не понятно
|
||||
// function executed from threaded read, pass readedData, sizeOfData, ThreadedReadData
|
||||
@@ -63,10 +63,18 @@ typedef std::function<bool(const uchar *, int, void *)> ReadRetFunc;
|
||||
|
||||
# define PIIODEVICE(name, prefix) \
|
||||
PIOBJECT_SUBCLASS(name, PIIODevice) \
|
||||
PIIODevice * copy() const override {return new name();} \
|
||||
PIIODevice * copy() const override { \
|
||||
return new name(); \
|
||||
} \
|
||||
\
|
||||
public: \
|
||||
PIConstChars fullPathPrefix() const override {return prefix;} \
|
||||
static PIConstChars fullPathPrefixS() {return prefix;} \
|
||||
PIConstChars fullPathPrefix() const override { \
|
||||
return prefix; \
|
||||
} \
|
||||
static PIConstChars fullPathPrefixS() { \
|
||||
return prefix; \
|
||||
} \
|
||||
\
|
||||
private:
|
||||
|
||||
|
||||
@@ -76,10 +84,10 @@ typedef std::function<bool(const uchar *, int, void *)> ReadRetFunc;
|
||||
//! \~\brief
|
||||
//! \~english Base class for input/output devices.
|
||||
//! \~russian Базовый класс утройств ввода/вывода.
|
||||
class PIP_EXPORT PIIODevice: public PIObject
|
||||
{
|
||||
class PIP_EXPORT PIIODevice: public PIObject {
|
||||
PIOBJECT_SUBCLASS(PIIODevice, PIObject);
|
||||
friend void __DevicePool_threadReadDP(void * ddp);
|
||||
|
||||
public:
|
||||
NO_COPY_CLASS(PIIODevice);
|
||||
|
||||
@@ -98,8 +106,12 @@ public:
|
||||
//! \~english Options for PIIODevice, works with some devices
|
||||
//! \~russian Опции для PIIODevice, работает для некоторых устройств
|
||||
enum DeviceOption {
|
||||
BlockingRead /*! \~english \a read() block until data is received, default off \~russian \a read() блокируется, пока данные не поступят, по умолчанию выключено */ = 0x01,
|
||||
BlockingWrite /*! \~english \a write() block until data is sent, default off \~russian \a write() блокируется, пока данные не запишутся, по умолчанию выключено */ = 0x02
|
||||
BlockingRead /*! \~english \a read() block until data is received, default off \~russian \a read() блокируется, пока данные не
|
||||
поступят, по умолчанию выключено */
|
||||
= 0x01,
|
||||
BlockingWrite /*! \~english \a write() block until data is sent, default off \~russian \a write() блокируется, пока данные не
|
||||
запишутся, по умолчанию выключено */
|
||||
= 0x02
|
||||
};
|
||||
|
||||
//! \~english Characteristics of PIIODevice channel
|
||||
@@ -487,11 +499,17 @@ protected:
|
||||
|
||||
//! \~english Reimplement this function to read from your device
|
||||
//! \~russian Переопределите для чтения данных из устройства
|
||||
virtual ssize_t readDevice(void * read_to, ssize_t max_size) {piCoutObj << "\"read\" is not implemented!"; return -2;}
|
||||
virtual ssize_t readDevice(void * read_to, ssize_t max_size) {
|
||||
piCoutObj << "\"read\" is not implemented!";
|
||||
return -2;
|
||||
}
|
||||
|
||||
//! \~english Reimplement this function to write to your device
|
||||
//! \~russian Переопределите для записи данных в устройство
|
||||
virtual ssize_t writeDevice(const void * data, ssize_t max_size) {piCoutObj << "\"write\" is not implemented!"; return -2;}
|
||||
virtual ssize_t writeDevice(const void * data, ssize_t max_size) {
|
||||
piCoutObj << "\"write\" is not implemented!";
|
||||
return -2;
|
||||
}
|
||||
|
||||
//! \~english Function executed when thread read some data, default implementation execute external callback "ret_func_"
|
||||
//! \~russian Метод вызывается после каждого успешного потокового чтения, по умолчанию вызывает callback "ret_func_"
|
||||
@@ -563,7 +581,6 @@ private:
|
||||
|
||||
static PIMutex nfp_mutex;
|
||||
static PIMap<PIString, PIString> nfp_cache;
|
||||
|
||||
};
|
||||
|
||||
#endif // PIIODEVICE_H
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
//! \~russian Подробнее \ref iostream
|
||||
class PIP_EXPORT PIIOBinaryStream: public PIBinaryStream<PIIOBinaryStream> {
|
||||
public:
|
||||
|
||||
//! \~english Contructs %PIIOBinaryStream for "device" device
|
||||
//! \~russian Создает %PIIOBinaryStream для устройства "device"
|
||||
PIIOBinaryStream(PIIODevice * device = nullptr): dev(device) {}
|
||||
@@ -64,7 +63,6 @@ public:
|
||||
|
||||
private:
|
||||
PIIODevice * dev;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -74,7 +72,6 @@ private:
|
||||
//! \~russian Функциональность PITextStream для PIIODevice.
|
||||
class PIP_EXPORT PIIOTextStream: public PITextStream<PIIOBinaryStream> {
|
||||
public:
|
||||
|
||||
//! \~english Contructs %PIIOTextStream for "device" device
|
||||
//! \~russian Создает %PIIOTextStream для устройства "device"
|
||||
PIIOTextStream(PIIODevice * device): PITextStream<PIIOBinaryStream>(&bin_stream), bin_stream(device) {}
|
||||
@@ -87,8 +84,7 @@ public:
|
||||
}
|
||||
|
||||
~PIIOTextStream() {
|
||||
if (io_string)
|
||||
delete io_string;
|
||||
if (io_string) delete io_string;
|
||||
}
|
||||
|
||||
void setDevice(PIIODevice * device) {
|
||||
@@ -99,7 +95,6 @@ public:
|
||||
private:
|
||||
PIIOString * io_string = nullptr;
|
||||
PIIOBinaryStream bin_stream;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -33,11 +33,10 @@
|
||||
//! \~\brief
|
||||
//! \~english PIIODevice wrapper around PIString.
|
||||
//! \~russian Обёртка PIIODevice вокруг PIString.
|
||||
class PIP_EXPORT PIIOString: public PIIODevice
|
||||
{
|
||||
class PIP_EXPORT PIIOString: public PIIODevice {
|
||||
PIIODEVICE(PIIOString, "");
|
||||
public:
|
||||
|
||||
public:
|
||||
//! \~english Contructs %PIIOString with "string" content and "mode" open mode
|
||||
//! \~russian Создает %PIIOString с содержимым "string" и режимом открытия "mode"
|
||||
explicit PIIOString(PIString * string = 0, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||
@@ -52,7 +51,10 @@ public:
|
||||
|
||||
//! \~english Clear content string
|
||||
//! \~russian Очищает содержимое строки
|
||||
void clear() {if (str) str->clear(); pos = 0;}
|
||||
void clear() {
|
||||
if (str) str->clear();
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
//! \~english Open "string" content with "mode" open mode
|
||||
//! \~russian Открывает содержимое "string" с режимом открытия "mode"
|
||||
@@ -64,7 +66,10 @@ public:
|
||||
|
||||
//! \~english Returns if position is at the end of content
|
||||
//! \~russian Возвращает в конце содержимого ли позиция
|
||||
bool isEnd() const {if (!str) return true; return pos >= str->size_s();}
|
||||
bool isEnd() const {
|
||||
if (!str) return true;
|
||||
return pos >= str->size_s();
|
||||
}
|
||||
|
||||
|
||||
//! \~english Move read/write position to "position"
|
||||
@@ -73,11 +78,15 @@ public:
|
||||
|
||||
//! \~english Move read/write position to the beginning of the string
|
||||
//! \~russian Перемещает позицию чтения/записи на начало строки
|
||||
void seekToBegin() {if (str) pos = 0;}
|
||||
void seekToBegin() {
|
||||
if (str) pos = 0;
|
||||
}
|
||||
|
||||
//! \~english Move read/write position to the end of the string
|
||||
//! \~russian Перемещает позицию чтения/записи на конец строки
|
||||
void seekToEnd() {if (str) pos = str->size_s();}
|
||||
void seekToEnd() {
|
||||
if (str) pos = str->size_s();
|
||||
}
|
||||
|
||||
|
||||
//! \~english Read one text line and return it
|
||||
@@ -89,8 +98,10 @@ public:
|
||||
int writeString(const PIString & string);
|
||||
|
||||
ssize_t bytesAvailable() const override {
|
||||
if (str) return str->size() - pos;
|
||||
else return 0;
|
||||
if (str)
|
||||
return str->size() - pos;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -101,7 +112,6 @@ protected:
|
||||
|
||||
ssize_t pos;
|
||||
PIString * str;
|
||||
|
||||
};
|
||||
|
||||
#endif // PIIOSTRING_H
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "pipeer.h"
|
||||
|
||||
#include "piconfig.h"
|
||||
#include "pidatatransfer.h"
|
||||
#include "pipropertystorage.h"
|
||||
@@ -37,13 +38,24 @@
|
||||
|
||||
class PIPeer::PeerData: public PIObject {
|
||||
PIOBJECT_SUBCLASS(PeerData, PIObject);
|
||||
|
||||
public:
|
||||
PeerData(const PIString & n);
|
||||
~PeerData();
|
||||
EVENT_HANDLER1(void, dtSendRequestIn, PIByteArray &, data) {data.push_front(uchar(2)); sendRequest(name(), data);}
|
||||
EVENT_HANDLER1(void, dtSendRequestOut, PIByteArray &, data) {data.push_front(uchar(3)); sendRequest(name(), data);}
|
||||
EVENT_HANDLER1(void, dtReceiveFinishedIn, bool, ok) {if (ok) received(name(), dt_in.data());}
|
||||
EVENT_HANDLER1(void, dtReceiveFinishedOut, bool, ok) {if (ok) received(name(), dt_out.data());}
|
||||
EVENT_HANDLER1(void, dtSendRequestIn, PIByteArray &, data) {
|
||||
data.push_front(uchar(2));
|
||||
sendRequest(name(), data);
|
||||
}
|
||||
EVENT_HANDLER1(void, dtSendRequestOut, PIByteArray &, data) {
|
||||
data.push_front(uchar(3));
|
||||
sendRequest(name(), data);
|
||||
}
|
||||
EVENT_HANDLER1(void, dtReceiveFinishedIn, bool, ok) {
|
||||
if (ok) received(name(), dt_in.data());
|
||||
}
|
||||
EVENT_HANDLER1(void, dtReceiveFinishedOut, bool, ok) {
|
||||
if (ok) received(name(), dt_out.data());
|
||||
}
|
||||
EVENT_HANDLER(void, dtThread);
|
||||
EVENT2(received, const PIString &, from, const PIByteArray &, data);
|
||||
EVENT2(sendRequest, const PIString &, to, const PIByteArray &, data);
|
||||
@@ -73,8 +85,7 @@ PIPeer::PeerData::~PeerData() {
|
||||
dt_in.stop();
|
||||
dt_out.stop();
|
||||
t.stop();
|
||||
if (!t.waitForFinish(1000))
|
||||
t.terminate();
|
||||
if (!t.waitForFinish(1000)) t.terminate();
|
||||
}
|
||||
|
||||
|
||||
@@ -95,10 +106,8 @@ bool PIPeer::PeerData::send(const PIByteArray & d) {
|
||||
|
||||
void PIPeer::PeerData::receivedPacket(uchar type, const PIByteArray & d) {
|
||||
PIDataTransfer * dt = 0;
|
||||
if (type == 3)
|
||||
dt = &dt_in;
|
||||
if (type == 2)
|
||||
dt = &dt_out;
|
||||
if (type == 3) dt = &dt_in;
|
||||
if (type == 2) dt = &dt_out;
|
||||
// piCoutObj << "DT received" << int(type) << d.size_s() << "...";
|
||||
if (dt) dt->received(d);
|
||||
// piCoutObj << "DT received" << int(type) << d.size_s() << "done";
|
||||
@@ -110,8 +119,6 @@ void PIPeer::PeerData::setDist(int dist) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PIPeer::PeerInfo::PeerAddress::PeerAddress(const PIEthernet::Address & a, const PIEthernet::Address & m): address(a), netmask(m) {
|
||||
ping = -1.;
|
||||
wait_ping = false;
|
||||
@@ -123,8 +130,10 @@ int PIPeer::PeerInfo::ping() const {
|
||||
int ret = -1;
|
||||
piForeachC(PeerAddress & a, addresses)
|
||||
if (a.ping > 0.) {
|
||||
if (ret < 0) ret = piRoundd(a.ping);
|
||||
else ret = piMini(ret, piRoundd(a.ping));
|
||||
if (ret < 0)
|
||||
ret = piRoundd(a.ping);
|
||||
else
|
||||
ret = piMini(ret, piRoundd(a.ping));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -157,7 +166,13 @@ PIEthernet::Address PIPeer::PeerInfo::fastestAddress() const {
|
||||
|
||||
REGISTER_DEVICE(PIPeer)
|
||||
|
||||
PIPeer::PIPeer(const PIString & n): PIIODevice(), inited__(false), eth_tcp_srv(PIEthernet::TCP_Server), eth_tcp_cli(PIEthernet::TCP_Client), diag_s(false), diag_d(false) {
|
||||
PIPeer::PIPeer(const PIString & n)
|
||||
: PIIODevice()
|
||||
, inited__(false)
|
||||
, eth_tcp_srv(PIEthernet::TCP_Server)
|
||||
, eth_tcp_cli(PIEthernet::TCP_Client)
|
||||
, diag_s(false)
|
||||
, diag_d(false) {
|
||||
sync_timer.setName("__S__.PIPeer.sync_timer");
|
||||
// piCout << " PIPeer" << uint(this);
|
||||
destroyed = false;
|
||||
@@ -339,7 +354,9 @@ void PIPeer::initMBcasts(PIStringList al) {
|
||||
CONNECT2(void, const uchar *, ssize_t, ð_tcp_cli, threadedReadEvent, this, mbcastRead);
|
||||
CONNECTU(ð_tcp_cli, disconnected, this, tcpClientReconnect);
|
||||
eth_tcp_cli.startThreadedRead();
|
||||
if (eths_mcast.isEmpty() && eths_bcast.isEmpty() && !eth_lo.isOpened()) piCoutObj << "Warning! Can`t find suitable network interface for multicast receive, check for exists at least one interface with multicasting enabled!";
|
||||
if (eths_mcast.isEmpty() && eths_bcast.isEmpty() && !eth_lo.isOpened())
|
||||
piCoutObj << "Warning! Can`t find suitable network interface for multicast receive, check for exists at least one interface with "
|
||||
"multicasting enabled!";
|
||||
// piCoutObj << "initMBcasts ok";
|
||||
}
|
||||
|
||||
@@ -470,8 +487,7 @@ bool PIPeer::dataRead(const uchar * readed, ssize_t size) {
|
||||
// piCout << " ping from" << from << addr << ", send back to" << pi->name;
|
||||
send_mutex.lock();
|
||||
piForeachC(PeerInfo::PeerAddress & a, pi->addresses) {
|
||||
if (eth_send.send(a.address, sba))
|
||||
diag_s.received(sba.size_s());
|
||||
if (eth_send.send(a.address, sba)) diag_s.received(sba.size_s());
|
||||
}
|
||||
send_mutex.unlock();
|
||||
}
|
||||
@@ -496,8 +512,10 @@ bool PIPeer::dataRead(const uchar * readed, ssize_t size) {
|
||||
ptime = ctime - time;
|
||||
a.last_ping = time;
|
||||
a.wait_ping = false;
|
||||
if (a.ping < 0) a.ping = ptime.toMilliseconds();
|
||||
else a.ping = 0.6 * a.ping + 0.4 * ptime.toMilliseconds();
|
||||
if (a.ping < 0)
|
||||
a.ping = ptime.toMilliseconds();
|
||||
else
|
||||
a.ping = 0.6 * a.ping + 0.4 * ptime.toMilliseconds();
|
||||
// piCout << " ping echo" << p.name << a.address << a.ping;
|
||||
eth_mutex.unlock();
|
||||
return true;
|
||||
@@ -535,8 +553,7 @@ bool PIPeer::dataRead(const uchar * readed, ssize_t size) {
|
||||
if (pt == 2 || pt == 3) {
|
||||
peers_mutex.unlock();
|
||||
eth_mutex.unlock();
|
||||
if (fp->_data)
|
||||
fp->_data->receivedPacket(pt, pba);
|
||||
if (fp->_data) fp->_data->receivedPacket(pt, pba);
|
||||
return true;
|
||||
}
|
||||
peers_mutex.unlock();
|
||||
@@ -619,8 +636,7 @@ bool PIPeer::mbcastRead(const uchar * data, ssize_t size) {
|
||||
addToRemoved(*rpi);
|
||||
removePeer(pi.name);
|
||||
// piCoutObj << "remove peer \"" << pi.name << "\"";
|
||||
if (dist == 0)
|
||||
self_info.removeNeighbour(pi.name);
|
||||
if (dist == 0) self_info.removeNeighbour(pi.name);
|
||||
sendPeerRemove(pi.name);
|
||||
buildMap();
|
||||
ch = true;
|
||||
@@ -699,8 +715,7 @@ bool PIPeer::mbcastRead(const uchar * data, ssize_t size) {
|
||||
}
|
||||
// piCout << i.name << i.neighbours;
|
||||
}
|
||||
if (ch)
|
||||
buildMap();
|
||||
if (ch) buildMap();
|
||||
peers_mutex.unlock();
|
||||
// piCoutObj << "after sync " << peers.size_s() << " peers";
|
||||
break;
|
||||
@@ -726,28 +741,23 @@ void PIPeer::sendMBcast(const PIByteArray & ba) {
|
||||
// piCout << "sendMBcast" << ba.size() << "bytes ...";
|
||||
piForeach(PIEthernet * e, eths_mcast) {
|
||||
if (e->isOpened())
|
||||
if (e->send(ba))
|
||||
diag_s.sended(ba.size_s());
|
||||
if (e->send(ba)) diag_s.sended(ba.size_s());
|
||||
}
|
||||
piForeach(PIEthernet * e, eths_bcast) {
|
||||
if (e->isOpened())
|
||||
if (e->send(ba))
|
||||
diag_s.sended(ba.size_s());
|
||||
if (e->send(ba)) diag_s.sended(ba.size_s());
|
||||
}
|
||||
for (int p = _PIPEER_LOOPBACK_PORT_S; p <= _PIPEER_LOOPBACK_PORT_E; ++p) {
|
||||
eth_lo.setSendPort(p);
|
||||
if (eth_lo.send(ba))
|
||||
diag_s.sended(ba.size_s());
|
||||
if (eth_lo.send(ba)) diag_s.sended(ba.size_s());
|
||||
}
|
||||
PIVector<PIEthernet *> cl = eth_tcp_srv.clients();
|
||||
piForeach(PIEthernet * e, cl) {
|
||||
if (e->isOpened() && e->isConnected())
|
||||
if (e->send(ba))
|
||||
diag_s.sended(ba.size_s());
|
||||
if (e->send(ba)) diag_s.sended(ba.size_s());
|
||||
}
|
||||
if (eth_tcp_cli.isOpened() && eth_tcp_cli.isConnected()) {
|
||||
if (eth_tcp_cli.send(ba))
|
||||
diag_s.sended(ba.size_s());
|
||||
if (eth_tcp_cli.send(ba)) diag_s.sended(ba.size_s());
|
||||
}
|
||||
// piCout << "sendMBcast ok";
|
||||
send_mc_mutex.unlock();
|
||||
@@ -808,16 +818,14 @@ void PIPeer::pingNeighbours() {
|
||||
piForeach(PeerInfo::PeerAddress & a, p.addresses) {
|
||||
// piCout << " address" << a.address << a.wait_ping;
|
||||
if (a.wait_ping) {
|
||||
if ((PISystemTime::current(true) - a.last_ping).abs().toSeconds() <= _PIPEER_PING_TIMEOUT)
|
||||
continue;
|
||||
if ((PISystemTime::current(true) - a.last_ping).abs().toSeconds() <= _PIPEER_PING_TIMEOUT) continue;
|
||||
a.ping = -1.;
|
||||
}
|
||||
a.wait_ping = true;
|
||||
sba = ba;
|
||||
sba << p.name << a.address << PISystemTime::current(true);
|
||||
// piCout << "ping" << p.name << a.address << a.last_ping;
|
||||
if (eth_send.send(a.address, sba))
|
||||
diag_s.sended(sba.size_s());
|
||||
if (eth_send.send(a.address, sba)) diag_s.sended(sba.size_s());
|
||||
}
|
||||
send_mutex.unlock();
|
||||
}
|
||||
@@ -832,7 +840,8 @@ bool PIPeer::openDevice() {
|
||||
#else
|
||||
"pip.conf"
|
||||
#endif
|
||||
, PIIODevice::ReadOnly);
|
||||
,
|
||||
PIIODevice::ReadOnly);
|
||||
server_ip = conf.getValue("peer_server_ip", "").toString();
|
||||
reinit();
|
||||
diag_d.reset();
|
||||
@@ -874,8 +883,7 @@ void PIPeer::syncPeers() {
|
||||
cp.sync = 0;
|
||||
else
|
||||
cp.sync++;
|
||||
if (cp._data)
|
||||
cp._data->setDist(cp.dist + 1);
|
||||
if (cp._data) cp._data->setDist(cp.dist + 1);
|
||||
cp.was_update = false;
|
||||
}
|
||||
if (change) buildMap();
|
||||
@@ -963,7 +971,8 @@ ssize_t PIPeer::writeDevice(const void *data, ssize_t size) {
|
||||
}
|
||||
if (send(trust_peer, data, size))
|
||||
return size;
|
||||
else return -1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
#ifndef PIPEER_H
|
||||
#define PIPEER_H
|
||||
|
||||
#include "piethernet.h"
|
||||
#include "pidiagnostics.h"
|
||||
#include "piethernet.h"
|
||||
|
||||
class PIP_EXPORT PIPeer: public PIIODevice
|
||||
{
|
||||
class PIP_EXPORT PIPeer: public PIIODevice {
|
||||
PIIODEVICE(PIPeer, "peer");
|
||||
|
||||
private:
|
||||
class PeerData;
|
||||
|
||||
@@ -42,12 +42,19 @@ public:
|
||||
class PIP_EXPORT PeerInfo {
|
||||
friend class PIPeer;
|
||||
BINARY_STREAM_FRIEND(PIPeer::PeerInfo);
|
||||
|
||||
public:
|
||||
PeerInfo() {dist = sync = cnt = 0; trace = -1; was_update = false; _data = 0;}
|
||||
PeerInfo() {
|
||||
dist = sync = cnt = 0;
|
||||
trace = -1;
|
||||
was_update = false;
|
||||
_data = 0;
|
||||
}
|
||||
~PeerInfo() {}
|
||||
|
||||
struct PIP_EXPORT PeerAddress {
|
||||
PeerAddress(const PIEthernet::Address & a = PIEthernet::Address(), const PIEthernet::Address & m = PIEthernet::Address("255.255.255.0"));
|
||||
PeerAddress(const PIEthernet::Address & a = PIEthernet::Address(),
|
||||
const PIEthernet::Address & m = PIEthernet::Address("255.255.255.0"));
|
||||
bool isAvailable() const { return ping > 0; }
|
||||
PIEthernet::Address address;
|
||||
PIEthernet::Address netmask;
|
||||
@@ -66,10 +73,18 @@ public:
|
||||
PIEthernet::Address fastestAddress() const;
|
||||
|
||||
protected:
|
||||
void addNeighbour(const PIString & n) {if (!neighbours.contains(n)) neighbours << n;}
|
||||
void addNeighbours(const PIStringList & l) {piForeachC (PIString & n, l) if (!neighbours.contains(n)) neighbours << n;}
|
||||
void addNeighbour(const PIString & n) {
|
||||
if (!neighbours.contains(n)) neighbours << n;
|
||||
}
|
||||
void addNeighbours(const PIStringList & l) {
|
||||
piForeachC(PIString & n, l)
|
||||
if (!neighbours.contains(n)) neighbours << n;
|
||||
}
|
||||
void removeNeighbour(const PIString & n) { neighbours.removeAll(n); }
|
||||
void resetPing() {for (int i = 0; i < addresses.size_s(); ++i) addresses[i].ping = -1;}
|
||||
void resetPing() {
|
||||
for (int i = 0; i < addresses.size_s(); ++i)
|
||||
addresses[i].ping = -1;
|
||||
}
|
||||
void init();
|
||||
void destroy();
|
||||
|
||||
@@ -77,7 +92,6 @@ public:
|
||||
bool was_update;
|
||||
PISystemTime time;
|
||||
PeerData * _data;
|
||||
|
||||
};
|
||||
|
||||
BINARY_STREAM_FRIEND(PIPeer::PeerInfo);
|
||||
@@ -88,12 +102,30 @@ public:
|
||||
bool send(const PeerInfo & to, const PIByteArray & data) { return send(to.name, data.data(), data.size_s()); }
|
||||
bool send(const PeerInfo & to, const PIString & data) { return send(to.name, data.data(), data.size_s()); }
|
||||
bool send(const PeerInfo & to, const void * data, int size) { return send(to.name, data, size); }
|
||||
bool send(const PeerInfo * to, const PIByteArray & data) {if (to == 0) return false; return send(to->name, data.data(), data.size_s());}
|
||||
bool send(const PeerInfo * to, const PIString & data) {if (to == 0) return false; return send(to->name, data.data(), data.size_s());}
|
||||
bool send(const PeerInfo * to, const void * data, int size) {if (to == 0) return false; return send(to->name, data, size);}
|
||||
void sendToAll(const PIByteArray & data) {piForeachC (PeerInfo & i, peers) send(i.name, data.data(), data.size_s());}
|
||||
void sendToAll(const PIString & data) {piForeachC (PeerInfo & i, peers) send(i.name, data.data(), data.size_s());}
|
||||
void sendToAll(const void * data, int size) {piForeachC (PeerInfo & i, peers) send(i.name, data, size);}
|
||||
bool send(const PeerInfo * to, const PIByteArray & data) {
|
||||
if (to == 0) return false;
|
||||
return send(to->name, data.data(), data.size_s());
|
||||
}
|
||||
bool send(const PeerInfo * to, const PIString & data) {
|
||||
if (to == 0) return false;
|
||||
return send(to->name, data.data(), data.size_s());
|
||||
}
|
||||
bool send(const PeerInfo * to, const void * data, int size) {
|
||||
if (to == 0) return false;
|
||||
return send(to->name, data, size);
|
||||
}
|
||||
void sendToAll(const PIByteArray & data) {
|
||||
piForeachC(PeerInfo & i, peers)
|
||||
send(i.name, data.data(), data.size_s());
|
||||
}
|
||||
void sendToAll(const PIString & data) {
|
||||
piForeachC(PeerInfo & i, peers)
|
||||
send(i.name, data.data(), data.size_s());
|
||||
}
|
||||
void sendToAll(const void * data, int size) {
|
||||
piForeachC(PeerInfo & i, peers)
|
||||
send(i.name, data, size);
|
||||
}
|
||||
|
||||
bool isMulticastReceive() const { return !eths_mcast.isEmpty(); }
|
||||
bool isBroadcastReceive() const { return !eths_bcast.isEmpty(); }
|
||||
@@ -114,7 +146,10 @@ public:
|
||||
void changeName(const PIString & new_name);
|
||||
const PIString & trustPeerName() const { return trust_peer; }
|
||||
void setTrustPeerName(const PIString & peer_name) { trust_peer = peer_name; }
|
||||
void setTcpServerIP(const PIString & ip) {server_ip = ip; tcpClientReconnect();}
|
||||
void setTcpServerIP(const PIString & ip) {
|
||||
server_ip = ip;
|
||||
tcpClientReconnect();
|
||||
}
|
||||
|
||||
ssize_t bytesAvailable() const override;
|
||||
|
||||
@@ -144,7 +179,11 @@ private:
|
||||
EVENT_HANDLER1(void, newTcpClient, PIEthernet *, client);
|
||||
EVENT_HANDLER(void, tcpClientReconnect);
|
||||
|
||||
bool hasPeer(const PIString & name) {piForeachC (PeerInfo & i, peers) if (i.name == name) return true; return false;}
|
||||
bool hasPeer(const PIString & name) {
|
||||
piForeachC(PeerInfo & i, peers)
|
||||
if (i.name == name) return true;
|
||||
return false;
|
||||
}
|
||||
bool removePeer(const PIString & name);
|
||||
void removeNeighbour(const PIString & name);
|
||||
void addPeer(const PeerInfo & pd);
|
||||
@@ -178,7 +217,9 @@ private:
|
||||
|
||||
PeerInfo * quickestPeer(const PIString & to);
|
||||
bool sendToNeighbour(PeerInfo * peer, const PIByteArray & ba);
|
||||
inline static bool isPeerRecent(const PeerInfo & my, const PeerInfo & income) {return (my.cnt < income.cnt) || (my.time < income.time);}
|
||||
inline static bool isPeerRecent(const PeerInfo & my, const PeerInfo & income) {
|
||||
return (my.cnt < income.cnt) || (my.time < income.time);
|
||||
}
|
||||
|
||||
// 1 - new peer, 2 - remove peer, 3 - sync peers, 4 - data, 5 - ping request, 6 - ping reply
|
||||
// Data packet: 4, from, to, ticks, data_size, data
|
||||
@@ -206,30 +247,50 @@ private:
|
||||
PIMutex mc_mutex, eth_mutex, peers_mutex, send_mutex, send_mc_mutex;
|
||||
};
|
||||
|
||||
inline PICout operator <<(PICout c, const PIPeer::PeerInfo::PeerAddress & v) {c.space(); c << "PeerAddress(" << v.address << ", " << v.netmask << ", " << v.ping << ")"; return c;}
|
||||
inline PICout operator <<(PICout c, const PIPeer::PeerInfo & v) {c.space(); c << "PeerInfo(" << v.name << ", " << v.dist << ", " << v.addresses << ")"; return c;}
|
||||
inline PICout operator<<(PICout c, const PIPeer::PeerInfo::PeerAddress & v) {
|
||||
c.space();
|
||||
c << "PeerAddress(" << v.address << ", " << v.netmask << ", " << v.ping << ")";
|
||||
return c;
|
||||
}
|
||||
inline PICout operator<<(PICout c, const PIPeer::PeerInfo & v) {
|
||||
c.space();
|
||||
c << "PeerInfo(" << v.name << ", " << v.dist << ", " << v.addresses << ")";
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIPeer::PeerInfo::PeerAddress) {s << v.address << v.netmask << v.ping; return s;}
|
||||
BINARY_STREAM_WRITE(PIPeer::PeerInfo::PeerAddress) {
|
||||
s << v.address << v.netmask << v.ping;
|
||||
return s;
|
||||
}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ (PIPeer::PeerInfo::PeerAddress) {s >> v.address >> v.netmask >> v.ping; return s;}
|
||||
BINARY_STREAM_READ(PIPeer::PeerInfo::PeerAddress) {
|
||||
s >> v.address >> v.netmask >> v.ping;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Store operator.
|
||||
//! \~russian Оператор сохранения.
|
||||
BINARY_STREAM_WRITE(PIPeer::PeerInfo) {s << v.name << v.addresses << v.dist << v.neighbours << v.cnt << v.time; return s;}
|
||||
BINARY_STREAM_WRITE(PIPeer::PeerInfo) {
|
||||
s << v.name << v.addresses << v.dist << v.neighbours << v.cnt << v.time;
|
||||
return s;
|
||||
}
|
||||
|
||||
//! \relatesalso PIBinaryStream
|
||||
//! \~english Restore operator.
|
||||
//! \~russian Оператор извлечения.
|
||||
BINARY_STREAM_READ (PIPeer::PeerInfo) {s >> v.name >> v.addresses >> v.dist >> v.neighbours >> v.cnt >> v.time; return s;}
|
||||
BINARY_STREAM_READ(PIPeer::PeerInfo) {
|
||||
s >> v.name >> v.addresses >> v.dist >> v.neighbours >> v.cnt >> v.time;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
#endif // PIPEER_H
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "piserial.h"
|
||||
|
||||
#include "piconfig.h"
|
||||
#include "pidir.h"
|
||||
#include "piincludes_p.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "piwaitevent_p.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(MICRO_PIP)
|
||||
@@ -47,12 +49,14 @@
|
||||
# else
|
||||
# include <guiddef.h>
|
||||
# endif
|
||||
// clang-format off
|
||||
# include <ntddmodm.h>
|
||||
# include <winreg.h>
|
||||
# include <windows.h>
|
||||
# include <winioctl.h>
|
||||
# include <cfgmgr32.h>
|
||||
# include <setupapi.h>
|
||||
// clang-format on
|
||||
# define B50 50
|
||||
# define B75 75
|
||||
# define B110 110
|
||||
@@ -81,9 +85,9 @@
|
||||
# define B3500000 3500000
|
||||
# define B4000000 4000000
|
||||
#else
|
||||
# include <termios.h>
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <termios.h>
|
||||
# ifndef B50
|
||||
# define B50 0000001
|
||||
# endif
|
||||
@@ -184,22 +188,19 @@ PRIVATE_DEFINITION_START(PISerial)
|
||||
PRIVATE_DEFINITION_END(PISerial)
|
||||
|
||||
|
||||
|
||||
|
||||
PIString PISerial::DeviceInfo::id() const {
|
||||
return PIString::fromNumber(vID, 16).toLowerCase().expandLeftTo(4, '0') + ":" +
|
||||
PIString::fromNumber(pID, 16).toLowerCase().expandLeftTo(4, '0');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PISerial::PISerial(): PIIODevice("", ReadWrite) {
|
||||
construct();
|
||||
}
|
||||
|
||||
|
||||
PISerial::PISerial(const PIString & device_, PISerial::Speed speed_, PIFlags<PISerial::Parameters> params_): PIIODevice(device_, ReadWrite) {
|
||||
PISerial::PISerial(const PIString & device_, PISerial::Speed speed_, PIFlags<PISerial::Parameters> params_)
|
||||
: PIIODevice(device_, ReadWrite) {
|
||||
construct();
|
||||
setPath(device_);
|
||||
setSpeed(speed_);
|
||||
@@ -245,16 +246,12 @@ bool PISerial::setPin(int number, bool on) {
|
||||
case 2: return setSR(on); break;
|
||||
case 3: return setST(on); break;
|
||||
case 4: return setDTR(on); break;
|
||||
case 5:
|
||||
piCoutObj << "Pin number 5 is ground";
|
||||
return false;
|
||||
case 5: piCoutObj << "Pin number 5 is ground"; return false;
|
||||
case 6: return setDSR(on); break;
|
||||
case 7: return setRTS(on); break;
|
||||
case 8: return setCTS(on); break;
|
||||
case 9: return setRNG(on); break;
|
||||
default:
|
||||
piCoutObj << "Pin number " << number << " doesn`t exists!";
|
||||
return false;
|
||||
default: piCoutObj << "Pin number " << number << " doesn`t exists!"; return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -271,32 +268,66 @@ bool PISerial::isPin(int number) const {
|
||||
case 7: return isRTS(); break;
|
||||
case 8: return isCTS(); break;
|
||||
case 9: return isRNG(); break;
|
||||
default:
|
||||
piCoutObj << "Pin number " << number << " doesn`t exists!";
|
||||
return false;
|
||||
default: piCoutObj << "Pin number " << number << " doesn`t exists!"; return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PISerial::setLE(bool on) {return setBit(TIOCM_LE, on, "LE");}
|
||||
bool PISerial::setDTR(bool on) {return setBit(TIOCM_DTR, on, "DTR");}
|
||||
bool PISerial::setRTS(bool on) {return setBit(TIOCM_RTS, on, "RTS");}
|
||||
bool PISerial::setCTS(bool on) {return setBit(TIOCM_CTS, on, "CTS");}
|
||||
bool PISerial::setST(bool on) {return setBit(TIOCM_ST, on, "ST");}
|
||||
bool PISerial::setSR(bool on) {return setBit(TIOCM_SR, on, "SR");}
|
||||
bool PISerial::setCAR(bool on) {return setBit(TIOCM_CAR, on, "CAR");}
|
||||
bool PISerial::setRNG(bool on) {return setBit(TIOCM_RNG, on, "RNG");}
|
||||
bool PISerial::setDSR(bool on) {return setBit(TIOCM_DSR, on, "DSR");}
|
||||
bool PISerial::setLE(bool on) {
|
||||
return setBit(TIOCM_LE, on, "LE");
|
||||
}
|
||||
bool PISerial::setDTR(bool on) {
|
||||
return setBit(TIOCM_DTR, on, "DTR");
|
||||
}
|
||||
bool PISerial::setRTS(bool on) {
|
||||
return setBit(TIOCM_RTS, on, "RTS");
|
||||
}
|
||||
bool PISerial::setCTS(bool on) {
|
||||
return setBit(TIOCM_CTS, on, "CTS");
|
||||
}
|
||||
bool PISerial::setST(bool on) {
|
||||
return setBit(TIOCM_ST, on, "ST");
|
||||
}
|
||||
bool PISerial::setSR(bool on) {
|
||||
return setBit(TIOCM_SR, on, "SR");
|
||||
}
|
||||
bool PISerial::setCAR(bool on) {
|
||||
return setBit(TIOCM_CAR, on, "CAR");
|
||||
}
|
||||
bool PISerial::setRNG(bool on) {
|
||||
return setBit(TIOCM_RNG, on, "RNG");
|
||||
}
|
||||
bool PISerial::setDSR(bool on) {
|
||||
return setBit(TIOCM_DSR, on, "DSR");
|
||||
}
|
||||
|
||||
bool PISerial::isLE() const {return isBit(TIOCM_LE, "LE");}
|
||||
bool PISerial::isDTR() const {return isBit(TIOCM_DTR, "DTR");}
|
||||
bool PISerial::isRTS() const {return isBit(TIOCM_RTS, "RTS");}
|
||||
bool PISerial::isCTS() const {return isBit(TIOCM_CTS, "CTS");}
|
||||
bool PISerial::isST() const {return isBit(TIOCM_ST, "ST");}
|
||||
bool PISerial::isSR() const {return isBit(TIOCM_SR, "SR");}
|
||||
bool PISerial::isCAR() const {return isBit(TIOCM_CAR, "CAR");}
|
||||
bool PISerial::isRNG() const {return isBit(TIOCM_RNG, "RNG");}
|
||||
bool PISerial::isDSR() const {return isBit(TIOCM_DSR, "DSR");}
|
||||
bool PISerial::isLE() const {
|
||||
return isBit(TIOCM_LE, "LE");
|
||||
}
|
||||
bool PISerial::isDTR() const {
|
||||
return isBit(TIOCM_DTR, "DTR");
|
||||
}
|
||||
bool PISerial::isRTS() const {
|
||||
return isBit(TIOCM_RTS, "RTS");
|
||||
}
|
||||
bool PISerial::isCTS() const {
|
||||
return isBit(TIOCM_CTS, "CTS");
|
||||
}
|
||||
bool PISerial::isST() const {
|
||||
return isBit(TIOCM_ST, "ST");
|
||||
}
|
||||
bool PISerial::isSR() const {
|
||||
return isBit(TIOCM_SR, "SR");
|
||||
}
|
||||
bool PISerial::isCAR() const {
|
||||
return isBit(TIOCM_CAR, "CAR");
|
||||
}
|
||||
bool PISerial::isRNG() const {
|
||||
return isBit(TIOCM_RNG, "RNG");
|
||||
}
|
||||
bool PISerial::isDSR() const {
|
||||
return isBit(TIOCM_DSR, "DSR");
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
@@ -381,8 +412,7 @@ bool PISerial::isBit(int bit, const PIString & bname) const {
|
||||
# ifdef WINDOWS
|
||||
# else
|
||||
int ret = 0;
|
||||
if (ioctl(fd, TIOCMGET, &ret) < 0)
|
||||
piCoutObj << "isBit" << bname << " error: " << errorString();
|
||||
if (ioctl(fd, TIOCMGET, &ret) < 0) piCoutObj << "isBit" << bname << " error: " << errorString();
|
||||
return ret & bit;
|
||||
# endif
|
||||
#endif
|
||||
@@ -468,8 +498,10 @@ bool PISerial::read(void * data, int size, double timeout_ms) {
|
||||
tm_.reset();
|
||||
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
||||
ret = readDevice(&((uchar *)data)[all], size - all);
|
||||
if (ret > 0) all += ret;
|
||||
else piMinSleep();
|
||||
if (ret > 0)
|
||||
all += ret;
|
||||
else
|
||||
piMinSleep();
|
||||
}
|
||||
setOption(BlockingRead, br);
|
||||
received(data, all);
|
||||
@@ -518,13 +550,16 @@ PIString PISerial::readString(int size, double timeout_ms) {
|
||||
if (size <= 0) {
|
||||
while (tm_.elapsed_m() < timeout_ms) {
|
||||
ret = readDevice(td, 1024);
|
||||
if (ret <= 0) piMinSleep();
|
||||
else str += PIString((char*)td, ret);
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else
|
||||
str += PIString((char *)td, ret);
|
||||
}
|
||||
} else {
|
||||
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
||||
ret = readDevice(td, size - all);
|
||||
if (ret <= 0) piMinSleep();
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else {
|
||||
str += PIString((char *)td, ret);
|
||||
all += ret;
|
||||
@@ -538,7 +573,8 @@ PIString PISerial::readString(int size, double timeout_ms) {
|
||||
str += PIString((char *)td, all);
|
||||
while (all < size) {
|
||||
ret = readDevice(td, size - all);
|
||||
if (ret <= 0) piMinSleep();
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else {
|
||||
str += PIString((char *)td, ret);
|
||||
all += ret;
|
||||
@@ -580,13 +616,16 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
|
||||
if (size <= 0) {
|
||||
while (tm_.elapsed_m() < timeout_ms) {
|
||||
ret = readDevice(td, 1024);
|
||||
if (ret <= 0) piMinSleep();
|
||||
else str.append(td, ret);
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else
|
||||
str.append(td, ret);
|
||||
}
|
||||
} else {
|
||||
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
||||
ret = readDevice(td, size - all);
|
||||
if (ret <= 0) piMinSleep();
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else {
|
||||
str.append(td, ret);
|
||||
all += ret;
|
||||
@@ -600,7 +639,8 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
|
||||
str.append(td, all);
|
||||
while (all < size) {
|
||||
ret = readDevice(td, size - all);
|
||||
if (ret <= 0) piMinSleep();
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else {
|
||||
str.append(td, ret);
|
||||
all += ret;
|
||||
@@ -620,7 +660,8 @@ bool PISerial::send(const void * data, int size) {
|
||||
ret = write(&(((uchar *)data)[wsz]), size - wsz);
|
||||
if (ret > 0) wsz += ret;
|
||||
// piCout << ret << wsz;
|
||||
else return false;
|
||||
else
|
||||
return false;
|
||||
} while (wsz < size);
|
||||
return (wsz == size);
|
||||
}
|
||||
@@ -655,8 +696,14 @@ bool PISerial::openDevice() {
|
||||
if (p.isEmpty()) return false;
|
||||
#ifdef WINDOWS
|
||||
DWORD ds = 0, sm = 0;
|
||||
if (isReadable()) {ds |= GENERIC_READ; sm |= FILE_SHARE_READ;}
|
||||
if (isWriteable()) {ds |= GENERIC_WRITE; sm |= FILE_SHARE_WRITE;}
|
||||
if (isReadable()) {
|
||||
ds |= GENERIC_READ;
|
||||
sm |= FILE_SHARE_READ;
|
||||
}
|
||||
if (isWriteable()) {
|
||||
ds |= GENERIC_WRITE;
|
||||
sm |= FILE_SHARE_WRITE;
|
||||
}
|
||||
PIString wp = "//./" + p;
|
||||
PRIVATE->hCom = CreateFileA(wp.dataAscii(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
|
||||
if (PRIVATE->hCom == INVALID_HANDLE_VALUE) {
|
||||
@@ -723,7 +770,8 @@ void PISerial::applySettings() {
|
||||
GetCommMask(PRIVATE->hCom, &PRIVATE->mask);
|
||||
SetCommMask(PRIVATE->hCom, EV_RXCHAR);
|
||||
GetCommState(PRIVATE->hCom, &PRIVATE->sdesc);
|
||||
// piCoutObj << PRIVATE->sdesc.fBinary << PRIVATE->sdesc.fAbortOnError << PRIVATE->sdesc.fDsrSensitivity << PRIVATE->sdesc.fDtrControl << PRIVATE->sdesc.fDummy2 << PRIVATE->sdesc.fErrorChar;
|
||||
// piCoutObj << PRIVATE->sdesc.fBinary << PRIVATE->sdesc.fAbortOnError << PRIVATE->sdesc.fDsrSensitivity << PRIVATE->sdesc.fDtrControl
|
||||
//<< PRIVATE->sdesc.fDummy2 << PRIVATE->sdesc.fErrorChar;
|
||||
PRIVATE->desc = PRIVATE->sdesc;
|
||||
PRIVATE->desc.DCBlength = sizeof(PRIVATE->desc);
|
||||
PRIVATE->desc.BaudRate = convertSpeed(outSpeed());
|
||||
@@ -751,7 +799,8 @@ void PISerial::applySettings() {
|
||||
case 5: PRIVATE->desc.c_cflag |= (CSIZE & CS5); break;
|
||||
case 6: PRIVATE->desc.c_cflag |= (CSIZE & CS6); break;
|
||||
case 7: PRIVATE->desc.c_cflag |= (CSIZE & CS7); break;
|
||||
case 8: default: PRIVATE->desc.c_cflag |= (CSIZE & CS8); break;
|
||||
case 8:
|
||||
default: PRIVATE->desc.c_cflag |= (CSIZE & CS8); break;
|
||||
};
|
||||
if (isReadable()) PRIVATE->desc.c_cflag |= CREAD;
|
||||
PIFlags<Parameters> params = parameters();
|
||||
@@ -786,8 +835,7 @@ void PISerial::setTimeouts() {
|
||||
times.ReadTotalTimeoutMultiplier = isOptionSet(BlockingRead) ? 0 : MAXDWORD;
|
||||
times.WriteTotalTimeoutConstant = isOptionSet(BlockingWrite) ? 0 : 1;
|
||||
times.WriteTotalTimeoutMultiplier = 0;
|
||||
if (SetCommTimeouts(PRIVATE->hCom, ×) == -1)
|
||||
piCoutObj << "Unable to set timeouts for \"" << path() << "\"";
|
||||
if (SetCommTimeouts(PRIVATE->hCom, ×) == -1) piCoutObj << "Unable to set timeouts for \"" << path() << "\"";
|
||||
#else
|
||||
fcntl(fd, F_SETFL, isOptionSet(BlockingRead) ? 0 : O_NONBLOCK);
|
||||
#endif
|
||||
@@ -823,8 +871,7 @@ ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) {
|
||||
return -1;
|
||||
// piCoutObj << "read done" << PRIVATE->readed;
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_TIMEOUT && PRIVATE->readed == 0)
|
||||
return 0;
|
||||
if (err == ERROR_TIMEOUT && PRIVATE->readed == 0) return 0;
|
||||
if (err == ERROR_BAD_COMMAND || err == ERROR_ACCESS_DENIED) {
|
||||
piCoutObj << "read error" << (PRIVATE->readed) << errorString();
|
||||
stop();
|
||||
@@ -894,11 +941,16 @@ PIString PISerial::constructFullPathDevice() const {
|
||||
PIString ret;
|
||||
ret += path() + ":" + PIString::fromNumber(int(inSpeed())) + ":" + PIString::fromNumber(dataBitsCount());
|
||||
if (parameters()[ParityControl]) {
|
||||
if (parameters()[ParityOdd]) ret += ":O";
|
||||
else ret += ":E";
|
||||
} else ret += ":N";
|
||||
if (parameters()[TwoStopBits]) ret += ":2";
|
||||
else ret += ":1";
|
||||
if (parameters()[ParityOdd])
|
||||
ret += ":O";
|
||||
else
|
||||
ret += ":E";
|
||||
} else
|
||||
ret += ":N";
|
||||
if (parameters()[TwoStopBits])
|
||||
ret += ":2";
|
||||
else
|
||||
ret += ":1";
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -916,14 +968,19 @@ void PISerial::configureFromFullPathDevice(const PIString & full_path) {
|
||||
PIString p(pl[i]);
|
||||
switch (i) {
|
||||
case 0: setProperty("path", p); break;
|
||||
case 1: setProperty("outSpeed", p.toInt()); setProperty("inSpeed", p.toInt()); break;
|
||||
case 1:
|
||||
setProperty("outSpeed", p.toInt());
|
||||
setProperty("inSpeed", p.toInt());
|
||||
break;
|
||||
case 2: setProperty("dataBitsCount", p.toInt()); break;
|
||||
case 3:
|
||||
p = p.left(1).toLowerCase();
|
||||
if (p != "n") setParameter(ParityControl);
|
||||
if (p == "o") setParameter(ParityOdd);
|
||||
break;
|
||||
case 4: if (p.toInt() == 2) setParameter(TwoStopBits); break;
|
||||
case 4:
|
||||
if (p.toInt() == 2) setParameter(TwoStopBits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
applySettings();
|
||||
@@ -936,17 +993,23 @@ PIPropertyStorage PISerial::constructVariantDevice() const {
|
||||
PIVariantTypes::Enum e;
|
||||
|
||||
PIVector<int> as = availableSpeeds();
|
||||
piForeachC (int s, as) {e << PIVariantTypes::Enumerator(s, PIString::fromNumber(s));}
|
||||
piForeachC(int s, as) {
|
||||
e << PIVariantTypes::Enumerator(s, PIString::fromNumber(s));
|
||||
}
|
||||
e.selectValue((int)inSpeed());
|
||||
ret.addProperty("speed", e);
|
||||
|
||||
e = PIVariantTypes::Enum();
|
||||
for (int i = 5; i <= 8; ++i) {e << PIVariantTypes::Enumerator(i, PIString::fromNumber(i));}
|
||||
for (int i = 5; i <= 8; ++i) {
|
||||
e << PIVariantTypes::Enumerator(i, PIString::fromNumber(i));
|
||||
}
|
||||
e.selectValue(dataBitsCount());
|
||||
ret.addProperty("dataBits", e);
|
||||
|
||||
e = PIVariantTypes::Enum();
|
||||
e << "None" << "Odd" << "Even";
|
||||
e << "None"
|
||||
<< "Odd"
|
||||
<< "Even";
|
||||
if (parameters()[ParityControl]) {
|
||||
if (parameters()[ParityOdd])
|
||||
e.selectValue(1);
|
||||
@@ -957,7 +1020,9 @@ PIPropertyStorage PISerial::constructVariantDevice() const {
|
||||
ret.addProperty("parity", e);
|
||||
|
||||
e = PIVariantTypes::Enum();
|
||||
for (int i = 1; i <= 2; ++i) {e << PIVariantTypes::Enumerator(i, PIString::fromNumber(i));}
|
||||
for (int i = 1; i <= 2; ++i) {
|
||||
e << PIVariantTypes::Enumerator(i, PIString::fromNumber(i));
|
||||
}
|
||||
e.selectValue(parameters()[TwoStopBits] ? 2 : 1);
|
||||
ret.addProperty("stopBits", e);
|
||||
return ret;
|
||||
@@ -977,14 +1042,12 @@ void PISerial::configureFromVariantDevice(const PIPropertyStorage & d) {
|
||||
|
||||
PIVector<int> PISerial::availableSpeeds() {
|
||||
PIVector<int> spds;
|
||||
spds << 50 << 75 << 110 << 300 << 600 << 1200 << 2400 << 4800 <<
|
||||
9600 <<
|
||||
spds << 50 << 75 << 110 << 300 << 600 << 1200 << 2400 << 4800 << 9600 <<
|
||||
#ifdef WINDOWS
|
||||
14400 <<
|
||||
#endif
|
||||
19200 << 38400 << 57600 << 115200 << 230400 <<
|
||||
460800 << 500000 << 576000 << 921600 << 1000000 << 1152000 <<
|
||||
1500000 << 2000000 << 2500000 << 3000000 << 3500000 << 4000000;
|
||||
19200 << 38400 << 57600 << 115200 << 230400 << 460800 << 500000 << 576000 << 921600 << 1000000 << 1152000 << 1500000 << 2000000
|
||||
<< 2500000 << 3000000 << 3500000 << 4000000;
|
||||
return spds;
|
||||
}
|
||||
|
||||
@@ -1002,12 +1065,8 @@ PIStringList PISerial::availableDevices(bool test) {
|
||||
PIString devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData) {
|
||||
PIString ret;
|
||||
const HKEY key = SetupDiOpenDevRegKey(deviceInfoSet, deviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
|
||||
if (key == INVALID_HANDLE_VALUE)
|
||||
return ret;
|
||||
static const wchar_t * const keyTokens[] = {
|
||||
L"PortName\0",
|
||||
L"PortNumber\0"
|
||||
};
|
||||
if (key == INVALID_HANDLE_VALUE) return ret;
|
||||
static const wchar_t * const keyTokens[] = {L"PortName\0", L"PortNumber\0"};
|
||||
static const int keys_count = sizeof(keyTokens) / sizeof(keyTokens[0]);
|
||||
for (int i = 0; i < keys_count; ++i) {
|
||||
DWORD dataType = 0;
|
||||
@@ -1026,8 +1085,7 @@ PIString devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ret.isEmpty())
|
||||
break;
|
||||
if (!ret.isEmpty()) break;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
return ret;
|
||||
@@ -1039,10 +1097,15 @@ PIString deviceRegistryProperty(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceI
|
||||
DWORD bytesRequired = MAX_PATH;
|
||||
PIVector<wchar_t> outputBuffer(MAX_PATH + 1);
|
||||
for (;;) {
|
||||
if (SetupDiGetDeviceRegistryPropertyW(deviceInfoSet, deviceInfoData, property, &dataType, (PBYTE)outputBuffer.data(), bytesRequired, &bytesRequired))
|
||||
if (SetupDiGetDeviceRegistryPropertyW(deviceInfoSet,
|
||||
deviceInfoData,
|
||||
property,
|
||||
&dataType,
|
||||
(PBYTE)outputBuffer.data(),
|
||||
bytesRequired,
|
||||
&bytesRequired))
|
||||
break;
|
||||
if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dataType != REG_SZ && dataType != REG_EXPAND_SZ))
|
||||
return PIString();
|
||||
if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dataType != REG_SZ && dataType != REG_EXPAND_SZ)) return PIString();
|
||||
outputBuffer.resize(bytesRequired / sizeof(wchar_t) + 2, 0);
|
||||
}
|
||||
return PIString(outputBuffer.data());
|
||||
@@ -1107,14 +1170,23 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
# ifdef QNX
|
||||
prefixes << "ser";
|
||||
# else
|
||||
prefixes << "ttyS" << "ttyO" << "ttyUSB" << "ttyACM" << "ttyGS"
|
||||
<< "ttyMI" << "ttymxc" << "ttyAMA" << "rfcomm" << "ircomm";
|
||||
prefixes << "ttyS"
|
||||
<< "ttyO"
|
||||
<< "ttyUSB"
|
||||
<< "ttyACM"
|
||||
<< "ttyGS"
|
||||
<< "ttyMI"
|
||||
<< "ttymxc"
|
||||
<< "ttyAMA"
|
||||
<< "rfcomm"
|
||||
<< "ircomm";
|
||||
# ifdef FREE_BSD
|
||||
prefixes << "cu";
|
||||
# endif
|
||||
# ifdef MAC_OS
|
||||
prefixes.clear();
|
||||
prefixes << "cu." << "tty.";
|
||||
prefixes << "cu."
|
||||
<< "tty.";
|
||||
# endif
|
||||
PIFile file_prefixes("/proc/tty/drivers", PIIODevice::ReadOnly);
|
||||
if (file_prefixes.open()) {
|
||||
@@ -1155,16 +1227,11 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
fpath += "../";
|
||||
// piCout << "try" << fpath;
|
||||
if (_f.open(fpath + "idVendor", PIIODevice::ReadOnly))
|
||||
di.vID = PIString(_f.readAll()).trim().toInt(16);
|
||||
if (_f.open(fpath + "idProduct", PIIODevice::ReadOnly))
|
||||
di.pID = PIString(_f.readAll()).trim().toInt(16);
|
||||
if (_f.open(fpath + "product", PIIODevice::ReadOnly))
|
||||
di.description = PIString(_f.readAll()).trim();
|
||||
if (_f.open(fpath + "manufacturer", PIIODevice::ReadOnly))
|
||||
di.manufacturer = PIString(_f.readAll()).trim();
|
||||
if (di.pID > 0)
|
||||
break;
|
||||
if (_f.open(fpath + "idVendor", PIIODevice::ReadOnly)) di.vID = PIString(_f.readAll()).trim().toInt(16);
|
||||
if (_f.open(fpath + "idProduct", PIIODevice::ReadOnly)) di.pID = PIString(_f.readAll()).trim().toInt(16);
|
||||
if (_f.open(fpath + "product", PIIODevice::ReadOnly)) di.description = PIString(_f.readAll()).trim();
|
||||
if (_f.open(fpath + "manufacturer", PIIODevice::ReadOnly)) di.manufacturer = PIString(_f.readAll()).trim();
|
||||
if (di.pID > 0) break;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
@@ -1177,7 +1244,13 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
if (test) {
|
||||
for (int i = 0; i < ret.size_s(); ++i) {
|
||||
#ifdef WINDOWS
|
||||
void * hComm = CreateFileA(ret[i].path.dataAscii(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
|
||||
void * hComm = CreateFileA(ret[i].path.dataAscii(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
0,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
|
||||
0);
|
||||
if (hComm == INVALID_HANDLE_VALUE) {
|
||||
#else
|
||||
int fd = ::open(ret[i].path.dataAscii(), O_NOCTTY | O_RDONLY);
|
||||
@@ -1191,8 +1264,7 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
#ifndef WINDOWS
|
||||
int void_ = 0;
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
if (::read(fd, &void_, 1) == -1)
|
||||
rok = errno != EIO;
|
||||
if (::read(fd, &void_, 1) == -1) rok = errno != EIO;
|
||||
|
||||
#endif
|
||||
if (!rok) {
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "pisharedmemory.h"
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "pipropertystorage.h"
|
||||
#if defined(LINUX) || defined(MAC_OS)
|
||||
# define SHM_POSIX
|
||||
@@ -35,8 +36,8 @@
|
||||
#endif
|
||||
#ifdef SHM_POSIX
|
||||
# include <fcntl.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/mman.h>
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -83,8 +84,7 @@ PISharedMemory::PISharedMemory(): PIIODevice() {
|
||||
PISharedMemory::PISharedMemory(const PIString & shm_name, int size, PIIODevice::DeviceMode mode): PIIODevice(shm_name, mode) {
|
||||
initPrivate();
|
||||
dsize = size;
|
||||
if (!shm_name.isEmpty())
|
||||
open();
|
||||
if (!shm_name.isEmpty()) open();
|
||||
}
|
||||
|
||||
|
||||
@@ -135,8 +135,7 @@ bool PISharedMemory::openDevice() {
|
||||
PRIVATE->owner = true;
|
||||
// piCoutObj << "created" << fd;
|
||||
}
|
||||
if (fd >= 0)
|
||||
ftruncate(fd, dsize);
|
||||
if (fd >= 0) ftruncate(fd, dsize);
|
||||
PRIVATE->data = mmap(0, dsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
::close(fd);
|
||||
if (PRIVATE->data == MAP_FAILED) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user