Compare commits
3 Commits
16c12a2756
...
pimap
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e85b11a233 | ||
|
|
831adf3fc9 | ||
|
|
a18f461ce3 |
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lapi_c
|
#define lapi_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lcode_c
|
#define lcode_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lctype_c
|
#define lctype_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define ldebug_c
|
#define ldebug_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define ldo_c
|
#define ldo_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define ldump_c
|
#define ldump_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lfunc_c
|
#define lfunc_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lgc_c
|
#define lgc_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define llex_c
|
#define llex_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lmem_c
|
#define lmem_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lobject_c
|
#define lobject_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lopcodes_c
|
#define lopcodes_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lparser_c
|
#define lparser_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lstate_c
|
#define lstate_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lstring_c
|
#define lstring_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define ltable_c
|
#define ltable_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define ltm_c
|
#define ltm_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lundump_c
|
#define lundump_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lvm_c
|
#define lvm_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define lzio_c
|
#define lzio_c
|
||||||
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "lprefix.h"
|
#include "lprefix.h"
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
|
|||||||
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
||||||
project(pip)
|
project(pip)
|
||||||
set(pip_MAJOR 2)
|
set(pip_MAJOR 2)
|
||||||
set(pip_MINOR 97)
|
set(pip_MINOR 39)
|
||||||
set(pip_REVISION 0)
|
set(pip_REVISION 0)
|
||||||
set(pip_SUFFIX )
|
set(pip_SUFFIX )
|
||||||
set(pip_COMPANY SHS)
|
set(pip_COMPANY SHS)
|
||||||
|
|||||||
@@ -7,19 +7,19 @@ class SomeIO: public PIIODevice {
|
|||||||
public:
|
public:
|
||||||
SomeIO(): PIIODevice() {}
|
SomeIO(): PIIODevice() {}
|
||||||
protected:
|
protected:
|
||||||
bool openDevice() override {
|
bool openDevice() {
|
||||||
// open your device here
|
// open your device here
|
||||||
return if_success;
|
return if_success;
|
||||||
}
|
}
|
||||||
int readDevice(void * read_to, int max_size) override {
|
int read(void * read_to, int max_size) {
|
||||||
// read from your device here
|
// read from your device here
|
||||||
return readed_bytes;
|
return readed_bytes;
|
||||||
}
|
}
|
||||||
int writeDevice(const void * data, int max_size) override {
|
int write(const void * data, int max_size) {
|
||||||
// write to your device here
|
// write to your device here
|
||||||
return written_bytes;
|
return written_bytes;
|
||||||
}
|
}
|
||||||
void configureFromFullPathDevice(const PIString & full_path) override {
|
void configureFromFullPath(const PIString & full_path) {
|
||||||
// parse full_path and configure device here
|
// parse full_path and configure device here
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -38,7 +38,7 @@ ser.configure("example.conf", "dev");
|
|||||||
//! [configureDevice]
|
//! [configureDevice]
|
||||||
class SomeIO: public PIIODevice {
|
class SomeIO: public PIIODevice {
|
||||||
...
|
...
|
||||||
bool configureDevice(const void * e_main, const void * e_parent) override {
|
bool configureDevice(const void * e_main, const void * e_parent) {
|
||||||
PIConfig::Entry * em = (PIConfig::Entry * )e_main;
|
PIConfig::Entry * em = (PIConfig::Entry * )e_main;
|
||||||
PIConfig::Entry * ep = (PIConfig::Entry * )e_parent;
|
PIConfig::Entry * ep = (PIConfig::Entry * )e_parent;
|
||||||
setStringParam(readDeviceSetting<PIString>("stringParam", stringParam(), em, ep));
|
setStringParam(readDeviceSetting<PIString>("stringParam", stringParam(), em, ep));
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode)
|
|||||||
is_deleted = false;
|
is_deleted = false;
|
||||||
// setReopenEnabled(false);
|
// setReopenEnabled(false);
|
||||||
CONNECTL(ð, connected, [this](){opened_ = true; tcp.sendStart();});
|
CONNECTL(ð, connected, [this](){opened_ = true; tcp.sendStart();});
|
||||||
CONNECT1(void, PIByteArray, &streampacker, packetReceiveEvent, this, _readed);
|
CONNECTU(&streampacker, packetReceiveEvent, this, _readed);
|
||||||
CONNECTL(ð, disconnected, [this](bool){
|
CONNECTL(ð, disconnected, [this](bool){
|
||||||
if (is_deleted) return;
|
if (is_deleted) return;
|
||||||
bool need_disconn = is_connected;
|
bool need_disconn = is_connected;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode)
|
|||||||
tcp.setRole(PICloud::TCP::Server);
|
tcp.setRole(PICloud::TCP::Server);
|
||||||
tcp.setServerName(server_name);
|
tcp.setServerName(server_name);
|
||||||
setName("cloud_server__" + server_name);
|
setName("cloud_server__" + server_name);
|
||||||
CONNECT1(void, PIByteArray, &streampacker, packetReceiveEvent, this, _readed);
|
CONNECTU(&streampacker, packetReceiveEvent, this, _readed);
|
||||||
CONNECTL(ð, connected, [this](){opened_ = true; piCoutObj << "connected"; tcp.sendStart();});
|
CONNECTL(ð, connected, [this](){opened_ = true; piCoutObj << "connected"; tcp.sendStart();});
|
||||||
CONNECTL(ð, disconnected, [this](bool){
|
CONNECTL(ð, disconnected, [this](bool){
|
||||||
piCoutObj << "disconnected";
|
piCoutObj << "disconnected";
|
||||||
@@ -189,7 +189,7 @@ void PICloudServer::_readed(PIByteArray & ba) {
|
|||||||
} else {
|
} else {
|
||||||
//piCoutObj << "new Client" << id;
|
//piCoutObj << "new Client" << id;
|
||||||
Client * c = new Client(this, id);
|
Client * c = new Client(this, id);
|
||||||
CONNECT1(void, PIObject *, c, deleted, this, clientDeleted);
|
CONNECTU(c, deleted, this, clientDeleted);
|
||||||
clients_mutex.lock();
|
clients_mutex.lock();
|
||||||
clients_ << c;
|
clients_ << c;
|
||||||
index_clients.insert(id, c);
|
index_clients.insert(id, c);
|
||||||
|
|||||||
@@ -168,14 +168,14 @@ PIByteArray PICloud::TCP::parseConnect_d(PIByteArray & ba) {
|
|||||||
|
|
||||||
|
|
||||||
uint PICloud::TCP::parseConnect(PIByteArray & ba) {
|
uint PICloud::TCP::parseConnect(PIByteArray & ba) {
|
||||||
uint ret = 0;
|
uint ret;
|
||||||
ba >> ret;
|
ba >> ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint PICloud::TCP::parseDisconnect(PIByteArray & ba) {
|
uint PICloud::TCP::parseDisconnect(PIByteArray & ba) {
|
||||||
uint ret = 0;
|
uint ret;
|
||||||
ba >> ret;
|
ba >> ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ PIByteArray piCompress(const PIByteArray & ba, int level) {
|
|||||||
|
|
||||||
PIByteArray piDecompress(const PIByteArray & zba) {
|
PIByteArray piDecompress(const PIByteArray & zba) {
|
||||||
#ifdef PIP_COMPRESS
|
#ifdef PIP_COMPRESS
|
||||||
ullong sz = 0;
|
ullong sz;
|
||||||
if (zba.size() < sizeof(ullong)) {
|
if (zba.size() < sizeof(ullong)) {
|
||||||
piCout << "[PICompress]" << "Error: invalid input";
|
piCout << "[PICompress]" << "Error: invalid input";
|
||||||
return zba;
|
return zba;
|
||||||
|
|||||||
@@ -51,18 +51,6 @@ PRIVATE_DEFINITION_END(PIScreen::SystemConsole)
|
|||||||
PIScreen::SystemConsole::SystemConsole() {
|
PIScreen::SystemConsole::SystemConsole() {
|
||||||
width = height = pwidth = pheight = 0;
|
width = height = pwidth = pheight = 0;
|
||||||
mouse_x = mouse_y = -1;
|
mouse_x = mouse_y = -1;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIScreen::SystemConsole::~SystemConsole() {
|
|
||||||
#ifdef WINDOWS
|
|
||||||
SetConsoleMode(PRIVATE->hOut, PRIVATE->smode);
|
|
||||||
SetConsoleTextAttribute(PRIVATE->hOut, PRIVATE->dattr);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIScreen::SystemConsole::begin() {
|
|
||||||
int w, h;
|
int w, h;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
PRIVATE->ulcoord.X = 0;
|
PRIVATE->ulcoord.X = 0;
|
||||||
@@ -86,6 +74,18 @@ void PIScreen::SystemConsole::begin() {
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
resize(w, h);
|
resize(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIScreen::SystemConsole::~SystemConsole() {
|
||||||
|
#ifdef WINDOWS
|
||||||
|
SetConsoleMode(PRIVATE->hOut, PRIVATE->smode);
|
||||||
|
SetConsoleTextAttribute(PRIVATE->hOut, PRIVATE->dattr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIScreen::SystemConsole::begin() {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
SetConsoleMode(PRIVATE->hOut, ENABLE_WRAP_AT_EOL_OUTPUT);
|
SetConsoleMode(PRIVATE->hOut, ENABLE_WRAP_AT_EOL_OUTPUT);
|
||||||
GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi);
|
GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi);
|
||||||
@@ -93,7 +93,6 @@ void PIScreen::SystemConsole::begin() {
|
|||||||
PRIVATE->bc.Y = 0;
|
PRIVATE->bc.Y = 0;
|
||||||
#endif
|
#endif
|
||||||
clear();
|
clear();
|
||||||
clearScreen();
|
|
||||||
hideCursor();
|
hideCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,17 +391,18 @@ PIScreen::PIScreen(bool startNow, PIKbdListener::KBFunc slot): PIThread(), drawe
|
|||||||
needLockRun(true);
|
needLockRun(true);
|
||||||
mouse_ = false;
|
mouse_ = false;
|
||||||
ret_func = slot;
|
ret_func = slot;
|
||||||
tile_focus = tile_dialog = nullptr;
|
tile_focus = tile_dialog = 0;
|
||||||
root.screen = this;
|
root.screen = this;
|
||||||
listener = new PIKbdListener(key_eventS, this, startNow);
|
listener = new PIKbdListener(key_eventS, this, startNow);
|
||||||
CONNECT1(void, PIKbdListener::MouseEvent, listener, mouseEvent, this, mouse_event);
|
CONNECTU(listener, mouseEvent, this, mouse_event);
|
||||||
CONNECT1(void, PIKbdListener::WheelEvent, listener, wheelEvent, this, wheel_event);
|
CONNECTU(listener, wheelEvent, this, wheel_event);
|
||||||
if (startNow) start();
|
if (startNow) start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIScreen::~PIScreen() {
|
PIScreen::~PIScreen() {
|
||||||
if (isRunning()) stop();
|
if (isRunning())
|
||||||
|
stop();
|
||||||
PIThread::waitForFinish(10);
|
PIThread::waitForFinish(10);
|
||||||
listener->waitForFinish(10);
|
listener->waitForFinish(10);
|
||||||
delete listener;
|
delete listener;
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
|
|||||||
//piCout << "mcast " << ce->readAddress() << ce->sendAddress();
|
//piCout << "mcast " << ce->readAddress() << ce->sendAddress();
|
||||||
if (ce->open()) {
|
if (ce->open()) {
|
||||||
eth_mcast << ce;
|
eth_mcast << ce;
|
||||||
CONNECT2(void, const uchar *, int, ce, threadedReadEvent, this, mcastRead);
|
CONNECTU(ce, threadedReadEvent, this, mcastRead);
|
||||||
} else {
|
} else {
|
||||||
delete ce;
|
delete ce;
|
||||||
}
|
}
|
||||||
@@ -173,7 +173,7 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
|
|||||||
//piCout << "bcast " << ce->readAddress() << ce->sendAddress();
|
//piCout << "bcast " << ce->readAddress() << ce->sendAddress();
|
||||||
if (ce->open()) {
|
if (ce->open()) {
|
||||||
eth_mcast << ce;
|
eth_mcast << ce;
|
||||||
CONNECT2(void, const uchar *, int, ce, threadedReadEvent, this, mcastRead);
|
CONNECTU(ce, threadedReadEvent, this, mcastRead);
|
||||||
} else {
|
} else {
|
||||||
delete ce;
|
delete ce;
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
|
|||||||
eth_lo->setName("PIMulticast_loopback");
|
eth_lo->setName("PIMulticast_loopback");
|
||||||
if (!_send_only) {
|
if (!_send_only) {
|
||||||
eth_lo->setParameter(PIEthernet::ReuseAddress, false);
|
eth_lo->setParameter(PIEthernet::ReuseAddress, false);
|
||||||
CONNECT2(void, const uchar *, int, eth_lo, threadedReadEvent, this, mcastRead);
|
CONNECTU(eth_lo, threadedReadEvent, this, mcastRead);
|
||||||
for (int i = 0; i < lo_pcnt; ++i) {
|
for (int i = 0; i < lo_pcnt; ++i) {
|
||||||
eth_lo->setReadAddress("127.0.0.1", lo_port + i);
|
eth_lo->setReadAddress("127.0.0.1", lo_port + i);
|
||||||
if (eth_lo->open()) {
|
if (eth_lo->open()) {
|
||||||
@@ -248,7 +248,7 @@ void PIBroadcast::reinit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIBroadcast::mcastRead(const uchar * data, int size) {
|
void PIBroadcast::mcastRead(uchar * data, int size) {
|
||||||
PIByteArray cd = decryptData(PIByteArray(data, size));
|
PIByteArray cd = decryptData(PIByteArray(data, size));
|
||||||
if (cd.isEmpty()) return;
|
if (cd.isEmpty()) return;
|
||||||
received(cd);
|
received(cd);
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ void PIStreamPacker::send(const PIByteArray & data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIStreamPacker::received(const uchar * readed, int size) {
|
void PIStreamPacker::received(uchar * readed, int size) {
|
||||||
received(PIByteArray(readed, size));
|
received(PIByteArray(readed, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,9 +195,8 @@ void PIStreamPacker::received(const PIByteArray & data) {
|
|||||||
|
|
||||||
void PIStreamPacker::assignDevice(PIIODevice * dev) {
|
void PIStreamPacker::assignDevice(PIIODevice * dev) {
|
||||||
if (!dev) return;
|
if (!dev) return;
|
||||||
if (!dev->infoFlags()[PIIODevice::Reliable]) {
|
if (!dev->infoFlags()[PIIODevice::Reliable])
|
||||||
piCoutObj << "Warning! Not recommended to use with non-reliable" << dev;
|
piCoutObj << "Warning! Not recommended to use with non-reliable" << dev;
|
||||||
}
|
CONNECTU(dev, threadedReadEvent, this, received);
|
||||||
CONNECT2(void, const uchar *, int, dev, threadedReadEvent, this, received);
|
CONNECTU(this, sendRequest, dev, write);
|
||||||
CONNECT1(void, PIByteArray, this, sendRequest, dev, write);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
class PIP_CLOUD_EXPORT PICloudClient: public PIIODevice, public PICloudBase
|
class PIP_CLOUD_EXPORT PICloudClient: public PIIODevice, public PICloudBase
|
||||||
{
|
{
|
||||||
PIIODEVICE(PICloudClient, "");
|
PIIODEVICE(PICloudClient, "")
|
||||||
public:
|
public:
|
||||||
explicit PICloudClient(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
explicit PICloudClient(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||||
virtual ~PICloudClient();
|
virtual ~PICloudClient();
|
||||||
@@ -42,17 +42,16 @@ public:
|
|||||||
void setServerName(const PIString & server_name);
|
void setServerName(const PIString & server_name);
|
||||||
void setKeepConnection(bool on);
|
void setKeepConnection(bool on);
|
||||||
bool isConnected() const {return is_connected;}
|
bool isConnected() const {return is_connected;}
|
||||||
ssize_t bytesAvailable() const override {return buff.size();}
|
|
||||||
|
|
||||||
EVENT(connected);
|
EVENT(connected)
|
||||||
EVENT(disconnected);
|
EVENT(disconnected)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool openDevice() override;
|
bool openDevice();
|
||||||
bool closeDevice() override;
|
bool closeDevice();
|
||||||
int readDevice(void * read_to, int max_size) override;
|
int readDevice(void * read_to, int max_size);
|
||||||
int writeDevice(const void * data, int size) override;
|
int writeDevice(const void * data, int size);
|
||||||
DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Reliable;}
|
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Reliable;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EVENT_HANDLER1(void, _readed, PIByteArray &, data);
|
EVENT_HANDLER1(void, _readed, PIByteArray &, data);
|
||||||
|
|||||||
@@ -32,25 +32,24 @@
|
|||||||
|
|
||||||
class PIP_CLOUD_EXPORT PICloudServer: public PIIODevice, public PICloudBase
|
class PIP_CLOUD_EXPORT PICloudServer: public PIIODevice, public PICloudBase
|
||||||
{
|
{
|
||||||
PIIODEVICE(PICloudServer, "");
|
PIIODEVICE(PICloudServer, "")
|
||||||
public:
|
public:
|
||||||
//! PICloudServer
|
//! PICloudServer
|
||||||
explicit PICloudServer(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
explicit PICloudServer(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||||
virtual ~PICloudServer();
|
virtual ~PICloudServer();
|
||||||
|
|
||||||
class Client : public PIIODevice {
|
class Client : public PIIODevice {
|
||||||
PIIODEVICE(PICloudServer::Client, "");
|
PIIODEVICE(PICloudServer::Client, "")
|
||||||
friend class PICloudServer;
|
friend class PICloudServer;
|
||||||
public:
|
public:
|
||||||
Client(PICloudServer * srv = nullptr, uint id = 0);
|
Client(PICloudServer * srv = nullptr, uint id = 0);
|
||||||
virtual ~Client();
|
virtual ~Client();
|
||||||
protected:
|
protected:
|
||||||
bool openDevice() override;
|
bool openDevice();
|
||||||
bool closeDevice() override;
|
bool closeDevice();
|
||||||
int readDevice(void * read_to, int max_size) override;
|
int readDevice(void * read_to, int max_size);
|
||||||
int writeDevice(const void * data, int size) override;
|
int writeDevice(const void * data, int size);
|
||||||
DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Reliable;}
|
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Reliable;}
|
||||||
ssize_t bytesAvailable() const override {return buff.size();}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void pushBuffer(const PIByteArray & ba);
|
void pushBuffer(const PIByteArray & ba);
|
||||||
@@ -66,13 +65,13 @@ public:
|
|||||||
|
|
||||||
PIVector<PICloudServer::Client *> clients() const;
|
PIVector<PICloudServer::Client *> clients() const;
|
||||||
|
|
||||||
EVENT1(newConnection, PICloudServer::Client * , client);
|
EVENT1(newConnection, PICloudServer::Client * , client)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool openDevice() override;
|
bool openDevice();
|
||||||
bool closeDevice() override;
|
bool closeDevice();
|
||||||
int readDevice(void * read_to, int max_size) override;
|
int readDevice(void * read_to, int max_size);
|
||||||
int writeDevice(const void * data, int max_size) override;
|
int writeDevice(const void * data, int max_size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EVENT_HANDLER1(void, _readed, PIByteArray &, ba);
|
EVENT_HANDLER1(void, _readed, PIByteArray &, ba);
|
||||||
|
|||||||
@@ -1050,7 +1050,7 @@ PIString PICodeParser::procMacros(PIString fc) {
|
|||||||
if (ifcnt > 0) ifcnt--;
|
if (ifcnt > 0) ifcnt--;
|
||||||
else {
|
else {
|
||||||
//piCout << "main endif" << skip << grab;
|
//piCout << "main endif" << skip << grab;
|
||||||
if (grab) pfc += procMacros(nfc);
|
if (grab) pfc << procMacros(nfc);
|
||||||
skip = grab = false;
|
skip = grab = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1059,7 +1059,7 @@ PIString PICodeParser::procMacros(PIString fc) {
|
|||||||
//piCout << "main elif" << skip << grab << cond_ok;
|
//piCout << "main elif" << skip << grab << cond_ok;
|
||||||
if (cond_ok) {
|
if (cond_ok) {
|
||||||
if (grab) {
|
if (grab) {
|
||||||
pfc += procMacros(nfc);
|
pfc << procMacros(nfc);
|
||||||
skip = true; grab = false;
|
skip = true; grab = false;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -1075,12 +1075,12 @@ PIString PICodeParser::procMacros(PIString fc) {
|
|||||||
}
|
}
|
||||||
if (mif.left(4) == s_else && ifcnt == 0) {
|
if (mif.left(4) == s_else && ifcnt == 0) {
|
||||||
//piCout << "main else" << skip << grab;
|
//piCout << "main else" << skip << grab;
|
||||||
if (grab) pfc += procMacros(nfc);
|
if (grab) pfc << procMacros(nfc);
|
||||||
if (skip && !cond_ok) {skip = false; grab = true;}
|
if (skip && !cond_ok) {skip = false; grab = true;}
|
||||||
else {skip = true; grab = false;}
|
else {skip = true; grab = false;}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (grab) nfc += line + '\n';
|
if (grab) nfc << line << '\n';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (mif.left(2) == s_if) {
|
if (mif.left(2) == s_if) {
|
||||||
@@ -1095,8 +1095,8 @@ PIString PICodeParser::procMacros(PIString fc) {
|
|||||||
//return false; /// WARNING: now skip errors
|
//return false; /// WARNING: now skip errors
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (grab) nfc += line + '\n';
|
if (grab) nfc << line << '\n';
|
||||||
else if (!skip) pfc += line + '\n';
|
else if (!skip) pfc << line << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pfc;
|
return pfc;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
class PIP_EXPORT PIKbdListener: public PIThread
|
class PIP_EXPORT PIKbdListener: public PIThread
|
||||||
{
|
{
|
||||||
PIOBJECT_SUBCLASS(PIKbdListener, PIThread);
|
PIOBJECT_SUBCLASS(PIKbdListener, PIThread)
|
||||||
friend class PIConsole;
|
friend class PIConsole;
|
||||||
friend class PITerminal;
|
friend class PITerminal;
|
||||||
public:
|
public:
|
||||||
@@ -176,9 +176,9 @@ public:
|
|||||||
EVENT_HANDLER(void, setActive) {setActive(true);}
|
EVENT_HANDLER(void, setActive) {setActive(true);}
|
||||||
EVENT_HANDLER1(void, setActive, bool, yes);
|
EVENT_HANDLER1(void, setActive, bool, yes);
|
||||||
|
|
||||||
EVENT2(keyPressed, PIKbdListener::KeyEvent, key, void * , data);
|
EVENT2(keyPressed, PIKbdListener::KeyEvent, key, void * , data)
|
||||||
EVENT2(mouseEvent, PIKbdListener::MouseEvent, mouse, void * , data);
|
EVENT2(mouseEvent, PIKbdListener::MouseEvent, mouse, void * , data)
|
||||||
EVENT2(wheelEvent, PIKbdListener::WheelEvent, wheel, void * , data);
|
EVENT2(wheelEvent, PIKbdListener::WheelEvent, wheel, void * , data)
|
||||||
|
|
||||||
//! \handlers
|
//! \handlers
|
||||||
//! \{
|
//! \{
|
||||||
@@ -205,9 +205,9 @@ public:
|
|||||||
static PIKbdListener * instance() {return _object;}
|
static PIKbdListener * instance() {return _object;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void begin() override;
|
void begin();
|
||||||
void run() override {readKeyboard();}
|
void run() {readKeyboard();}
|
||||||
void end() override;
|
void end();
|
||||||
|
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
struct PIP_EXPORT EscSeq {
|
struct PIP_EXPORT EscSeq {
|
||||||
@@ -247,11 +247,13 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIKbdListener::MouseEvent) {s << v.x << v.y << v.action << v.buttons << v.modifiers; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIKbdListener::KeyEvent & v) {s << v.key << v.modifiers; return s;}
|
||||||
BINARY_STREAM_READ (PIKbdListener::MouseEvent) {s >> v.x >> v.y >> v.action >> v.buttons >> v.modifiers; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIKbdListener::MouseEvent & v) {s << v.x << v.y << (int)v.action << v.buttons << v.modifiers; return s;}
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIKbdListener::WheelEvent & v) {s << (*(PIKbdListener::MouseEvent*)&v) << (uchar)v.direction; return s;}
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIKbdListener::WheelEvent) {s << (*(PIKbdListener::MouseEvent*)&v) << v.direction; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::KeyEvent & v) {s >> v.key >> v.modifiers; return s;}
|
||||||
BINARY_STREAM_READ (PIKbdListener::WheelEvent) {s >> (*(PIKbdListener::MouseEvent*)&v) >> v.direction; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::MouseEvent & v) {int a(0); s >> v.x >> v.y >> a >> v.buttons >> v.modifiers; v.action = (PIKbdListener::MouseAction)a; return s;}
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::WheelEvent & v) {uchar d(0); s >> (*(PIKbdListener::MouseEvent*)&v) >> d; v.direction = d; return s;}
|
||||||
|
|
||||||
REGISTER_PIVARIANTSIMPLE(PIKbdListener::KeyEvent)
|
REGISTER_PIVARIANTSIMPLE(PIKbdListener::KeyEvent)
|
||||||
REGISTER_PIVARIANTSIMPLE(PIKbdListener::MouseEvent)
|
REGISTER_PIVARIANTSIMPLE(PIKbdListener::MouseEvent)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
class PIP_CONSOLE_EXPORT PIScreen: public PIThread, public PIScreenTypes::PIScreenBase
|
class PIP_CONSOLE_EXPORT PIScreen: public PIThread, public PIScreenTypes::PIScreenBase
|
||||||
{
|
{
|
||||||
PIOBJECT_SUBCLASS(PIScreen, PIThread);
|
PIOBJECT_SUBCLASS(PIScreen, PIThread)
|
||||||
class SystemConsole;
|
class SystemConsole;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -76,8 +76,8 @@ public:
|
|||||||
EVENT_HANDLER0(void, stop) {stop(false);}
|
EVENT_HANDLER0(void, stop) {stop(false);}
|
||||||
EVENT_HANDLER1(void, stop, bool, clear);
|
EVENT_HANDLER1(void, stop, bool, clear);
|
||||||
|
|
||||||
EVENT2(keyPressed, PIKbdListener::KeyEvent, key, void * , data);
|
EVENT2(keyPressed, PIKbdListener::KeyEvent, key, void * , data)
|
||||||
EVENT2(tileEvent, PIScreenTile * , tile, PIScreenTypes::TileEvent, e);
|
EVENT2(tileEvent, PIScreenTile * , tile, PIScreenTypes::TileEvent, e)
|
||||||
|
|
||||||
//! \handlers
|
//! \handlers
|
||||||
//! \{
|
//! \{
|
||||||
@@ -134,9 +134,9 @@ private:
|
|||||||
PIVector<PIVector<PIScreenTypes::Cell> > cells, pcells;
|
PIVector<PIVector<PIScreenTypes::Cell> > cells, pcells;
|
||||||
};
|
};
|
||||||
|
|
||||||
void begin() override;
|
void begin();
|
||||||
void run() override;
|
void run();
|
||||||
void end() override;
|
void end();
|
||||||
void key_event(PIKbdListener::KeyEvent key);
|
void key_event(PIKbdListener::KeyEvent key);
|
||||||
EVENT_HANDLER1(void, mouse_event, PIKbdListener::MouseEvent, me);
|
EVENT_HANDLER1(void, mouse_event, PIKbdListener::MouseEvent, me);
|
||||||
EVENT_HANDLER1(void, wheel_event, PIKbdListener::WheelEvent, we);
|
EVENT_HANDLER1(void, wheel_event, PIKbdListener::WheelEvent, we);
|
||||||
@@ -145,9 +145,9 @@ private:
|
|||||||
PIVector<PIScreenTile*> prepareMouse(PIKbdListener::MouseEvent * e);
|
PIVector<PIScreenTile*> prepareMouse(PIKbdListener::MouseEvent * e);
|
||||||
PIVector<PIScreenTile*> tilesUnderMouse(int x, int y);
|
PIVector<PIScreenTile*> tilesUnderMouse(int x, int y);
|
||||||
bool nextFocus(PIScreenTile * rt, PIKbdListener::KeyEvent key = PIKbdListener::KeyEvent());
|
bool nextFocus(PIScreenTile * rt, PIKbdListener::KeyEvent key = PIKbdListener::KeyEvent());
|
||||||
void tileEventInternal(PIScreenTile * t, PIScreenTypes::TileEvent e) override;
|
void tileEventInternal(PIScreenTile * t, PIScreenTypes::TileEvent e);
|
||||||
void tileRemovedInternal(PIScreenTile * t) override;
|
void tileRemovedInternal(PIScreenTile * t);
|
||||||
void tileSetFocusInternal(PIScreenTile * t) override;
|
void tileSetFocusInternal(PIScreenTile * t);
|
||||||
|
|
||||||
bool mouse_;
|
bool mouse_;
|
||||||
SystemConsole console;
|
SystemConsole console;
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ protected:
|
|||||||
};
|
};
|
||||||
PIVector<Variable> variables;
|
PIVector<Variable> variables;
|
||||||
PIScreenTypes::Alignment alignment;
|
PIScreenTypes::Alignment alignment;
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const;
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class PIScreenDrawer;
|
|||||||
|
|
||||||
class PIP_CONSOLE_EXPORT PIScreenTile: public PIObject {
|
class PIP_CONSOLE_EXPORT PIScreenTile: public PIObject {
|
||||||
friend class PIScreen;
|
friend class PIScreen;
|
||||||
PIOBJECT_SUBCLASS(PIScreenTile, PIObject);
|
PIOBJECT_SUBCLASS(PIScreenTile, PIObject)
|
||||||
public:
|
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();
|
virtual ~PIScreenTile();
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TileSimple: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileSimple: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileSimple, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileSimple, PIScreenTile)
|
||||||
public:
|
public:
|
||||||
typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
|
typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
|
||||||
TileSimple(const PIString & n = PIString());
|
TileSimple(const PIString & n = PIString());
|
||||||
@@ -40,15 +40,15 @@ public:
|
|||||||
PIVector<Row> content;
|
PIVector<Row> content;
|
||||||
PIScreenTypes::Alignment alignment;
|
PIScreenTypes::Alignment alignment;
|
||||||
protected:
|
protected:
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const;
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class TileList;
|
class TileList;
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TileScrollBar: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileScrollBar: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileScrollBar, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileScrollBar, PIScreenTile)
|
||||||
friend class TileList;
|
friend class TileList;
|
||||||
public:
|
public:
|
||||||
TileScrollBar(const PIString & n = PIString());
|
TileScrollBar(const PIString & n = PIString());
|
||||||
@@ -62,16 +62,16 @@ public:
|
|||||||
int thickness;
|
int thickness;
|
||||||
protected:
|
protected:
|
||||||
void _check();
|
void _check();
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const;
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d);
|
||||||
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
bool mouseEvent(PIKbdListener::MouseEvent me);
|
||||||
int minimum_, maximum_, value_;
|
int minimum_, maximum_, value_;
|
||||||
PIChar line_char;
|
PIChar line_char;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TileList: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileList: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileList, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileList, PIScreenTile)
|
||||||
public:
|
public:
|
||||||
enum SelectionMode {
|
enum SelectionMode {
|
||||||
NoSelection,
|
NoSelection,
|
||||||
@@ -93,19 +93,19 @@ public:
|
|||||||
PISet<int> selected;
|
PISet<int> selected;
|
||||||
int lhei, cur, offset;
|
int lhei, cur, offset;
|
||||||
protected:
|
protected:
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const;
|
||||||
void resizeEvent(int w, int h) override;
|
void resizeEvent(int w, int h);
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d);
|
||||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
bool keyEvent(PIKbdListener::KeyEvent key);
|
||||||
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
bool mouseEvent(PIKbdListener::MouseEvent me);
|
||||||
bool wheelEvent(PIKbdListener::WheelEvent we) override;
|
bool wheelEvent(PIKbdListener::WheelEvent we);
|
||||||
TileScrollBar * scroll;
|
TileScrollBar * scroll;
|
||||||
bool mouse_sel;
|
bool mouse_sel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TileButton: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileButton: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileButton, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileButton, PIScreenTile)
|
||||||
public:
|
public:
|
||||||
TileButton(const PIString & n = PIString());
|
TileButton(const PIString & n = PIString());
|
||||||
virtual ~TileButton() {}
|
virtual ~TileButton() {}
|
||||||
@@ -115,17 +115,17 @@ public:
|
|||||||
PIScreenTypes::CellFormat format;
|
PIScreenTypes::CellFormat format;
|
||||||
PIString text;
|
PIString text;
|
||||||
protected:
|
protected:
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const;
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d);
|
||||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
bool keyEvent(PIKbdListener::KeyEvent key);
|
||||||
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
bool mouseEvent(PIKbdListener::MouseEvent me);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TileButtons: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileButtons: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileButtons, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileButtons, PIScreenTile)
|
||||||
public:
|
public:
|
||||||
TileButtons(const PIString & n = PIString());
|
TileButtons(const PIString & n = PIString());
|
||||||
virtual ~TileButtons() {}
|
virtual ~TileButtons() {}
|
||||||
@@ -137,10 +137,10 @@ public:
|
|||||||
PIVector<Button> content;
|
PIVector<Button> content;
|
||||||
int cur;
|
int cur;
|
||||||
protected:
|
protected:
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const;
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d);
|
||||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
bool keyEvent(PIKbdListener::KeyEvent key);
|
||||||
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
bool mouseEvent(PIKbdListener::MouseEvent me);
|
||||||
struct Rect {
|
struct Rect {
|
||||||
Rect(int _x0 = 0, int _y0 = 0, int _x1 = 0, int _y1 = 0): x0(_x0),y0(_y0),x1(_x1),y1(_y1) {}
|
Rect(int _x0 = 0, int _y0 = 0, int _x1 = 0, int _y1 = 0): x0(_x0),y0(_y0),x1(_x1),y1(_y1) {}
|
||||||
int x0,y0,x1,y1;
|
int x0,y0,x1,y1;
|
||||||
@@ -150,7 +150,7 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TileCheck: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileCheck: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileCheck, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileCheck, PIScreenTile)
|
||||||
public:
|
public:
|
||||||
TileCheck(const PIString & n = PIString());
|
TileCheck(const PIString & n = PIString());
|
||||||
virtual ~TileCheck() {}
|
virtual ~TileCheck() {}
|
||||||
@@ -161,15 +161,15 @@ public:
|
|||||||
PIString text;
|
PIString text;
|
||||||
bool toggled;
|
bool toggled;
|
||||||
protected:
|
protected:
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const;
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d);
|
||||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
bool keyEvent(PIKbdListener::KeyEvent key);
|
||||||
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
bool mouseEvent(PIKbdListener::MouseEvent me);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TileProgress: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileProgress: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileProgress, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileProgress, PIScreenTile)
|
||||||
public:
|
public:
|
||||||
TileProgress(const PIString & n = PIString());
|
TileProgress(const PIString & n = PIString());
|
||||||
virtual ~TileProgress() {}
|
virtual ~TileProgress() {}
|
||||||
@@ -179,26 +179,26 @@ public:
|
|||||||
double maximum;
|
double maximum;
|
||||||
double value;
|
double value;
|
||||||
protected:
|
protected:
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const;
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TilePICout: public TileList {
|
class PIP_CONSOLE_EXPORT TilePICout: public TileList {
|
||||||
PIOBJECT_SUBCLASS(TilePICout, PIScreenTile);
|
PIOBJECT_SUBCLASS(TilePICout, PIScreenTile)
|
||||||
public:
|
public:
|
||||||
TilePICout(const PIString & n = PIString());
|
TilePICout(const PIString & n = PIString());
|
||||||
virtual ~TilePICout() {}
|
virtual ~TilePICout() {}
|
||||||
PIScreenTypes::CellFormat format;
|
PIScreenTypes::CellFormat format;
|
||||||
int max_lines;
|
int max_lines;
|
||||||
protected:
|
protected:
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d);
|
||||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
bool keyEvent(PIKbdListener::KeyEvent key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TileInput: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileInput: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileInput, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileInput, PIScreenTile)
|
||||||
public:
|
public:
|
||||||
TileInput(const PIString & n = PIString());
|
TileInput(const PIString & n = PIString());
|
||||||
virtual ~TileInput() {}
|
virtual ~TileInput() {}
|
||||||
@@ -206,9 +206,9 @@ public:
|
|||||||
PIString text;
|
PIString text;
|
||||||
int max_length;
|
int max_length;
|
||||||
protected:
|
protected:
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const;
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d);
|
||||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
bool keyEvent(PIKbdListener::KeyEvent key);
|
||||||
void reserCursor();
|
void reserCursor();
|
||||||
int cur, offset;
|
int cur, offset;
|
||||||
bool inv;
|
bool inv;
|
||||||
|
|||||||
@@ -143,14 +143,11 @@ namespace PIScreenTypes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//inline PIByteArray & operator <<(PIByteArray & s, const PIScreenTypes::Cell & v) {s << v.format.raw_format << v.symbol; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIScreenTypes::Cell & v) {s << v.format.raw_format << v.symbol; return s;}
|
||||||
//inline PIByteArray & operator >>(PIByteArray & s, PIScreenTypes::Cell & v) {s >> v.format.raw_format >> v.symbol; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIScreenTypes::Cell & v) {s >> v.format.raw_format >> v.symbol; return s;}
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIScreenTypes::Cell) {s << v.format.raw_format << v.symbol; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIScreenTypes::TileEvent & v) {s << v.type << v.data; return s;}
|
||||||
BINARY_STREAM_READ (PIScreenTypes::Cell) {s >> v.format.raw_format >> v.symbol; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIScreenTypes::TileEvent & v) {s >> v.type >> v.data; return s;}
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(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)
|
REGISTER_PIVARIANTSIMPLE(PIScreenTypes::TileEvent)
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
class PIP_CONSOLE_EXPORT PITerminal: public PIThread
|
class PIP_CONSOLE_EXPORT PITerminal: public PIThread
|
||||||
{
|
{
|
||||||
PIOBJECT_SUBCLASS(PITerminal, PIThread);
|
PIOBJECT_SUBCLASS(PITerminal, PIThread)
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Constructs %PITerminal
|
//! Constructs %PITerminal
|
||||||
@@ -58,7 +58,7 @@ private:
|
|||||||
void readConsole();
|
void readConsole();
|
||||||
void getCursor(int & x, int & y);
|
void getCursor(int & x, int & y);
|
||||||
uchar invertColor(uchar c);
|
uchar invertColor(uchar c);
|
||||||
void run() override;
|
void run();
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
void parseInput(const PIString & s);
|
void parseInput(const PIString & s);
|
||||||
bool isCompleteEscSeq(const PIString & es);
|
bool isCompleteEscSeq(const PIString & es);
|
||||||
|
|||||||
@@ -20,11 +20,11 @@
|
|||||||
#include "picontainers.h"
|
#include "picontainers.h"
|
||||||
|
|
||||||
|
|
||||||
const size_t minAlloc = 64;
|
const ssize_t minAlloc = 64;
|
||||||
|
|
||||||
|
|
||||||
size_t _PIContainerConstantsBase::calcMinCountPoT(size_t szof) {
|
ssize_t _PIContainerConstantsBase::calcMinCountPoT(ssize_t szof) {
|
||||||
size_t ret = 0, elc = 1;
|
ssize_t ret = 0, elc = 1;
|
||||||
while (elc * szof < minAlloc) {
|
while (elc * szof < minAlloc) {
|
||||||
elc *= 2;
|
elc *= 2;
|
||||||
++ret;
|
++ret;
|
||||||
|
|||||||
@@ -65,13 +65,13 @@ private:
|
|||||||
|
|
||||||
class PIP_EXPORT _PIContainerConstantsBase {
|
class PIP_EXPORT _PIContainerConstantsBase {
|
||||||
public:
|
public:
|
||||||
static size_t calcMinCountPoT(size_t szof);
|
static ssize_t calcMinCountPoT(ssize_t szof);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class _PIContainerConstants {
|
class _PIContainerConstants {
|
||||||
public:
|
public:
|
||||||
static size_t minCountPoT() {static size_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T)); return ret;}
|
static ssize_t minCountPoT() {static ssize_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T)); return ret;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -645,7 +645,7 @@ public:
|
|||||||
inline size_t length() const {return pid_size;}
|
inline size_t length() const {return pid_size;}
|
||||||
|
|
||||||
//! \~english Number of elements that the container has currently allocated space for.
|
//! \~english Number of elements that the container has currently allocated space for.
|
||||||
//! \~russian Количество элементов, для которого сейчас выделена память массивом.
|
//! \~russian Количество элементов, для которого сейчас выделена память контейнером.
|
||||||
//! \~\details
|
//! \~\details
|
||||||
//! \~english To find out the actual number of items, use the function \a size().
|
//! \~english To find out the actual number of items, use the function \a size().
|
||||||
//! \~russian Чтобы узнать фактическое количество элементов используйте функцию \a size().
|
//! \~russian Чтобы узнать фактическое количество элементов используйте функцию \a size().
|
||||||
@@ -655,18 +655,18 @@ public:
|
|||||||
inline size_t _start() const {return pid_start;}
|
inline size_t _start() const {return pid_start;}
|
||||||
|
|
||||||
//! \~english Checks if the container has no elements.
|
//! \~english Checks if the container has no elements.
|
||||||
//! \~russian Проверяет пуст ли массив.
|
//! \~russian Проверяет пуст ли контейнер.
|
||||||
//! \~\return
|
//! \~\return
|
||||||
//! \~english **true** if the container is empty, **false** otherwise
|
//! \~english **true** if the container is empty, **false** otherwise
|
||||||
//! \~russian **true** если массив пуст, **false** иначе.
|
//! \~russian **true** если контейнер пуст, **false** иначе.
|
||||||
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
||||||
inline bool isEmpty() const {return (pid_size == 0);}
|
inline bool isEmpty() const {return (pid_size == 0);}
|
||||||
|
|
||||||
//! \~english Checks if the container has elements.
|
//! \~english Checks if the container has elements.
|
||||||
//! \~russian Проверяет не пуст ли массив.
|
//! \~russian Проверяет не пуст ли контейнер.
|
||||||
//! \~\return
|
//! \~\return
|
||||||
//! \~english **true** if the container is not empty, **false** otherwise
|
//! \~english **true** if the container is not empty, **false** otherwise
|
||||||
//! \~russian **true** если массив не пуст, **false** иначе.
|
//! \~russian **true** если контейнер не пуст, **false** иначе.
|
||||||
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
||||||
inline bool isNotEmpty() const {return (pid_size > 0);}
|
inline bool isNotEmpty() const {return (pid_size > 0);}
|
||||||
|
|
||||||
@@ -689,7 +689,7 @@ public:
|
|||||||
//! \endcode
|
//! \endcode
|
||||||
//! \~\sa \a every(), \a contains(), \a entries(), \a forEach()
|
//! \~\sa \a every(), \a contains(), \a entries(), \a forEach()
|
||||||
inline bool any(std::function<bool(const T & e)> test) const {
|
inline bool any(std::function<bool(const T & e)> test) const {
|
||||||
for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
|
for (ssize_t i = pid_start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
if (test(pid_data[i])) return true;
|
if (test(pid_data[i])) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -714,7 +714,7 @@ public:
|
|||||||
//! \endcode
|
//! \endcode
|
||||||
//! \~\sa \a any(), \a contains(), \a entries(), \a forEach()
|
//! \~\sa \a any(), \a contains(), \a entries(), \a forEach()
|
||||||
inline bool every(std::function<bool(const T & e)> test) const {
|
inline bool every(std::function<bool(const T & e)> test) const {
|
||||||
for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
|
for (ssize_t i = pid_start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
if (!test(pid_data[i])) return false;
|
if (!test(pid_data[i])) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -825,7 +825,7 @@ public:
|
|||||||
start = pid_size + start;
|
start = pid_size + start;
|
||||||
if (start < 0) start = 0;
|
if (start < 0) start = 0;
|
||||||
}
|
}
|
||||||
for (size_t i = pid_start + size_t(start); i < pid_start + pid_size; ++i) {
|
for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
if (e == pid_data[i]) return true;
|
if (e == pid_data[i]) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -856,13 +856,13 @@ public:
|
|||||||
//! piCout << v.entries(2, -4); // 2
|
//! piCout << v.entries(2, -4); // 2
|
||||||
//! \endcode
|
//! \endcode
|
||||||
//! \~\sa \a every(), \a any(), \a contains(), \a forEach(), \a indexOf()
|
//! \~\sa \a every(), \a any(), \a contains(), \a forEach(), \a indexOf()
|
||||||
inline int entries(const T & e, ssize_t start = 0) const {
|
inline int entries(const T & e, size_t start = 0) const {
|
||||||
int ec = 0;
|
int ec = 0;
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
start = pid_size + start;
|
start = pid_size + start;
|
||||||
if (start < 0) start = 0;
|
if (start < 0) start = 0;
|
||||||
}
|
}
|
||||||
for (size_t i = pid_start + size_t(start); i < pid_start + pid_size; ++i) {
|
for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
if (e == pid_data[i]) ++ec;
|
if (e == pid_data[i]) ++ec;
|
||||||
}
|
}
|
||||||
return ec;
|
return ec;
|
||||||
@@ -890,13 +890,13 @@ public:
|
|||||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
|
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
|
||||||
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
|
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
|
||||||
//! \~\sa \a every(), \a any(), \a contains(), \a forEach(), \a indexWhere()
|
//! \~\sa \a every(), \a any(), \a contains(), \a forEach(), \a indexWhere()
|
||||||
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const {
|
inline int entries(std::function<bool(const T & e)> test, size_t start = 0) const {
|
||||||
int ec = 0;
|
int ec = 0;
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
start = pid_size + start;
|
start = pid_size + start;
|
||||||
if (start < 0) start = 0;
|
if (start < 0) start = 0;
|
||||||
}
|
}
|
||||||
for (size_t i = pid_start + size_t(start); i < pid_start + pid_size; ++i) {
|
for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
if (test(pid_data[i])) ++ec;
|
if (test(pid_data[i])) ++ec;
|
||||||
}
|
}
|
||||||
return ec;
|
return ec;
|
||||||
@@ -931,14 +931,14 @@ public:
|
|||||||
//! piCout << v.indexOf(2, -3); // 0
|
//! piCout << v.indexOf(2, -3); // 0
|
||||||
//! \endcode
|
//! \endcode
|
||||||
//! \~\sa \a indexWhere(), \a lastIndexOf(), \a lastIndexWhere(), \a contains()
|
//! \~\sa \a indexWhere(), \a lastIndexOf(), \a lastIndexWhere(), \a contains()
|
||||||
inline ssize_t indexOf(const T & e, ssize_t start = 0) const {
|
inline ssize_t indexOf(const T & e, size_t start = 0) const {
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
start = pid_size + start;
|
start = pid_size + start;
|
||||||
if (start < 0) start = 0;
|
if (start < 0) start = 0;
|
||||||
}
|
}
|
||||||
for (size_t i = pid_start + size_t(start); i < pid_start + pid_size; ++i) {
|
for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
if (e == pid_data[i]) {
|
if (e == pid_data[i]) {
|
||||||
return ssize_t(i) - pid_start;
|
return i - pid_start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -972,14 +972,14 @@ public:
|
|||||||
//! piCout << v.indexWhere([](const PIString & s){return s.startsWith('k');}); // -1
|
//! piCout << v.indexWhere([](const PIString & s){return s.startsWith('k');}); // -1
|
||||||
//! \endcode
|
//! \endcode
|
||||||
//! \~\sa \a indexOf(), \a lastIndexOf(), \a lastIndexWhere(), \a contains()
|
//! \~\sa \a indexOf(), \a lastIndexOf(), \a lastIndexWhere(), \a contains()
|
||||||
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
|
inline ssize_t indexWhere(std::function<bool(const T & e)> test, size_t start = 0) const {
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
start = pid_size + start;
|
start = pid_size + start;
|
||||||
if (start < 0) start = 0;
|
if (start < 0) start = 0;
|
||||||
}
|
}
|
||||||
for (size_t i = pid_start + size_t(start); i < pid_start + pid_size; ++i) {
|
for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
if (test(pid_data[i])) {
|
if (test(pid_data[i])) {
|
||||||
return ssize_t(i) - pid_start;
|
return i - pid_start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1022,9 +1022,9 @@ public:
|
|||||||
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
|
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
|
||||||
if (start >= size_s()) start = pid_size - 1;
|
if (start >= size_s()) start = pid_size - 1;
|
||||||
if (start < 0) start = pid_size + start;
|
if (start < 0) start = pid_size + start;
|
||||||
for (size_t i = pid_start + size_t(start); i >= pid_start; --i) {
|
for (ssize_t i = pid_start + start; i >= pid_start; --i) {
|
||||||
if (e == pid_data[i]) {
|
if (e == pid_data[i]) {
|
||||||
return ssize_t(i) - pid_start;
|
return i - pid_start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1058,9 +1058,9 @@ public:
|
|||||||
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
||||||
if (start >= size_s()) start = pid_size - 1;
|
if (start >= size_s()) start = pid_size - 1;
|
||||||
if (start < 0) start = pid_size + start;
|
if (start < 0) start = pid_size + start;
|
||||||
for (size_t i = pid_start + size_t(start); i >= pid_start; --i) {
|
for (ssize_t i = pid_start + start; i >= pid_start; --i) {
|
||||||
if (test(pid_data[i])) {
|
if (test(pid_data[i])) {
|
||||||
return ssize_t(i) - pid_start;
|
return i - pid_start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1406,7 +1406,7 @@ public:
|
|||||||
inline PIDeque<T> & insert(size_t index, std::initializer_list<T> init_list) {
|
inline PIDeque<T> & insert(size_t index, std::initializer_list<T> init_list) {
|
||||||
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
ssize_t os = ssize_t(pid_size) - index;
|
ssize_t os = pid_size - index;
|
||||||
alloc_forward(pid_size + init_list.size());
|
alloc_forward(pid_size + init_list.size());
|
||||||
if (os > 0) {
|
if (os > 0) {
|
||||||
memmove((void*)(&(pid_data[index + pid_start + init_list.size()])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T));
|
memmove((void*)(&(pid_data[index + pid_start + init_list.size()])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T));
|
||||||
@@ -1461,7 +1461,7 @@ public:
|
|||||||
piSwap<T*>(pid_data, other.pid_data);
|
piSwap<T*>(pid_data, other.pid_data);
|
||||||
piSwap<size_t>(pid_size, other.pid_size);
|
piSwap<size_t>(pid_size, other.pid_size);
|
||||||
piSwap<size_t>(pid_rsize, other.pid_rsize);
|
piSwap<size_t>(pid_rsize, other.pid_rsize);
|
||||||
piSwap<size_t>(pid_start, other.pid_start);
|
piSwap<ssize_t>(pid_start, other.pid_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Sorts the elements in non-descending order.
|
//! \~english Sorts the elements in non-descending order.
|
||||||
@@ -1572,10 +1572,10 @@ public:
|
|||||||
//! Если `add_size < 0`, то с конца массива удаляются элементы.
|
//! Если `add_size < 0`, то с конца массива удаляются элементы.
|
||||||
//! Если `add_size < 0` и в массиве меньше элементов чем указано, то массив становится пустым.
|
//! Если `add_size < 0` и в массиве меньше элементов чем указано, то массив становится пустым.
|
||||||
//! \~\sa \a resize()
|
//! \~\sa \a resize()
|
||||||
inline PIDeque<T> & enlarge(ssize_t add_size, const T & e = T()) {
|
inline PIDeque<T> & enlarge(llong pid_size) {
|
||||||
ssize_t ns = size_s() + add_size;
|
llong ns = size_s() + pid_size;
|
||||||
if (ns <= 0) clear();
|
if (ns <= 0) clear();
|
||||||
else resize(size_t(ns), e);
|
else resize(size_t(ns));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1608,7 +1608,7 @@ public:
|
|||||||
//! \endcode
|
//! \endcode
|
||||||
//! \~\sa \a remove(), \a removeOne(), \a removeWhere()
|
//! \~\sa \a remove(), \a removeOne(), \a removeWhere()
|
||||||
inline PIDeque<T> & removeAll(const T & e) {
|
inline PIDeque<T> & removeAll(const T & e) {
|
||||||
for (size_t i = 0; i < pid_size; ++i) {
|
for (ssize_t i = 0; i < ssize_t(pid_size); ++i) {
|
||||||
if (pid_data[i + pid_start] == e) {
|
if (pid_data[i + pid_start] == e) {
|
||||||
remove(i);
|
remove(i);
|
||||||
--i;
|
--i;
|
||||||
@@ -1629,7 +1629,7 @@ public:
|
|||||||
//! \endcode
|
//! \endcode
|
||||||
//! \~\sa \a remove(), \a removeOne(), \a removeWhere()
|
//! \~\sa \a remove(), \a removeOne(), \a removeWhere()
|
||||||
inline PIDeque<T> & removeWhere(std::function<bool(const T & e)> test) {
|
inline PIDeque<T> & removeWhere(std::function<bool(const T & e)> test) {
|
||||||
for (size_t i = 0; i < pid_size; ++i) {
|
for (ssize_t i = 0; i < ssize_t(pid_size); ++i) {
|
||||||
if (test(pid_data[i + pid_start])) {
|
if (test(pid_data[i + pid_start])) {
|
||||||
remove(i);
|
remove(i);
|
||||||
--i;
|
--i;
|
||||||
@@ -1938,7 +1938,7 @@ public:
|
|||||||
//! Добавляет элементы из
|
//! Добавляет элементы из
|
||||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||||
//! \~\sa \a append()
|
//! \~\sa \a append()
|
||||||
inline PIDeque<T> & prepend(std::initializer_list<T> init_list) {return push_front(init_list);}
|
inline PIDeque<T> & prepend(std::initializer_list<T> init_list) {return prepend(init_list);}
|
||||||
|
|
||||||
//! \~english Remove one element from the end of the array.
|
//! \~english Remove one element from the end of the array.
|
||||||
//! \~russian Удаляет один элемент с конца массива.
|
//! \~russian Удаляет один элемент с конца массива.
|
||||||
@@ -2280,8 +2280,7 @@ private:
|
|||||||
if (pid_rsize + pid_rsize >= size_t(s) && pid_rsize < size_t(s)) {
|
if (pid_rsize + pid_rsize >= size_t(s) && pid_rsize < size_t(s)) {
|
||||||
return pid_rsize + pid_rsize;
|
return pid_rsize + pid_rsize;
|
||||||
}
|
}
|
||||||
size_t t = _PIContainerConstants<T>::minCountPoT();
|
ssize_t t = _PIContainerConstants<T>::minCountPoT(), s_ = s - 1;
|
||||||
size_t s_ = s - 1;
|
|
||||||
while (s_ >> t)
|
while (s_ >> t)
|
||||||
++t;
|
++t;
|
||||||
return (1 << t);
|
return (1 << t);
|
||||||
@@ -2349,8 +2348,8 @@ private:
|
|||||||
inline void checkMove() {
|
inline void checkMove() {
|
||||||
if (pid_size >= 4) {
|
if (pid_size >= 4) {
|
||||||
if (pid_size < pid_rsize / 6) {
|
if (pid_size < pid_rsize / 6) {
|
||||||
if (pid_start < (pid_size + pid_size) || ssize_t(pid_start) > (ssize_t(pid_rsize) - ssize_t(pid_size) - ssize_t(pid_size))) {
|
if (pid_start < ssize_t(pid_size + pid_size) || pid_start > (ssize_t(pid_rsize) - ssize_t(pid_size) - ssize_t(pid_size))) {
|
||||||
size_t ns = (pid_rsize - pid_size) / 2;
|
ssize_t ns = (pid_rsize - pid_size) / 2;
|
||||||
if (pid_start != ns) {
|
if (pid_start != ns) {
|
||||||
memmove((void*)(pid_data + ns), (const void*)(pid_data + pid_start), pid_size * sizeof(T));
|
memmove((void*)(pid_data + ns), (const void*)(pid_data + pid_start), pid_size * sizeof(T));
|
||||||
pid_start = ns;
|
pid_start = ns;
|
||||||
@@ -2358,7 +2357,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
size_t ns = (pid_rsize - pid_size) / 2;
|
ssize_t ns = (pid_rsize - pid_size) / 2;
|
||||||
if (pid_start != ns) {
|
if (pid_start != ns) {
|
||||||
memmove((void*)(pid_data + ns), (const void*)(pid_data + pid_start), pid_size * sizeof(T));
|
memmove((void*)(pid_data + ns), (const void*)(pid_data + pid_start), pid_size * sizeof(T));
|
||||||
pid_start = ns;
|
pid_start = ns;
|
||||||
@@ -2388,14 +2387,14 @@ private:
|
|||||||
}
|
}
|
||||||
inline void alloc_backward(size_t new_size, ssize_t start_offset = 0) { //alloc backward
|
inline void alloc_backward(size_t new_size, ssize_t start_offset = 0) { //alloc backward
|
||||||
size_t as;
|
size_t as;
|
||||||
if (ssize_t(pid_start) + start_offset < 0) {
|
if (pid_start + start_offset < 0) {
|
||||||
as = asize(pid_rsize - start_offset);
|
as = asize(pid_rsize - start_offset);
|
||||||
} else {
|
} else {
|
||||||
as = pid_rsize;
|
as = pid_rsize;
|
||||||
}
|
}
|
||||||
if (as > pid_rsize) {
|
if (as > pid_rsize) {
|
||||||
T * td = (T*)(malloc(as * sizeof(T)));
|
T * td = (T*)(malloc(as * sizeof(T)));
|
||||||
size_t ns = pid_start + as - pid_rsize;
|
ssize_t ns = pid_start + as - pid_rsize;
|
||||||
PIINTROSPECTION_CONTAINER_ALLOC(T, (as-pid_rsize))
|
PIINTROSPECTION_CONTAINER_ALLOC(T, (as-pid_rsize))
|
||||||
if (pid_rsize > 0 && pid_data != 0) {
|
if (pid_rsize > 0 && pid_data != 0) {
|
||||||
memcpy((void*)(td + ns), (const void*)(pid_data + pid_start), pid_size * sizeof(T));
|
memcpy((void*)(td + ns), (const void*)(pid_data + pid_start), pid_size * sizeof(T));
|
||||||
@@ -2411,9 +2410,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
T * pid_data;
|
T * pid_data;
|
||||||
size_t pid_size;
|
size_t pid_size, pid_rsize;
|
||||||
size_t pid_rsize;
|
ssize_t pid_start;
|
||||||
size_t pid_start;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,56 +30,19 @@
|
|||||||
#include "pipair.h"
|
#include "pipair.h"
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void piQuickSort(T * a, ssize_t N) {
|
|
||||||
if (N < 1) return;
|
|
||||||
if (N < 46) {
|
|
||||||
T tmp;
|
|
||||||
ssize_t i,j;
|
|
||||||
for(i=1; i<=N; i++) {
|
|
||||||
tmp = a[i];
|
|
||||||
j = i-1;
|
|
||||||
while(tmp<a[j] && j>=0) {
|
|
||||||
a[j+1] = a[j];
|
|
||||||
j = j-1;
|
|
||||||
}
|
|
||||||
a[j+1] = tmp;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ssize_t i = 0, j = N;
|
|
||||||
T & p(a[N >> 1]);
|
|
||||||
do {
|
|
||||||
while (a[i] < p) i++;
|
|
||||||
while (a[j] > p) j--;
|
|
||||||
if (i <= j) {
|
|
||||||
if (i != j) {
|
|
||||||
//piCout << "swap" << i << j << a[i] << a[j];
|
|
||||||
piSwap<T>(a[i], a[j]);
|
|
||||||
}
|
|
||||||
i++; j--;
|
|
||||||
}
|
|
||||||
} while (i <= j);
|
|
||||||
if (j > 0) piQuickSort(a, j);
|
|
||||||
if (N > i) piQuickSort(a + i, N - i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Key, typename T>
|
template <typename Key, typename T>
|
||||||
class PIMapIterator;
|
class PIMapIterator;
|
||||||
|
|
||||||
|
|
||||||
template <typename Key, typename T>
|
template <typename Key, typename T>
|
||||||
class PIMap {
|
class PIMap {
|
||||||
|
template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIMap<Key1, T1> & v);
|
||||||
|
template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIMap<Key1, T1> & v);
|
||||||
template <typename Key1, typename T1> friend class PIMapIterator;
|
template <typename Key1, typename T1> friend class PIMapIterator;
|
||||||
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:
|
public:
|
||||||
PIMap() {;}
|
PIMap() {}
|
||||||
PIMap(const PIMap<Key, T> & other) {*this = other;}
|
PIMap(const PIMap<Key, T> & other) {*this = other;}
|
||||||
PIMap(PIMap<Key, T> && other) : pim_content(std::move(other.pim_content)), pim_index(std::move(other.pim_index)) {}
|
PIMap(PIMap<Key, T> && other) : pim_content(std::move(other.pim_content)) {}
|
||||||
PIMap(std::initializer_list<std::pair<Key, T>> init_list) {
|
PIMap(std::initializer_list<std::pair<Key, T>> init_list) {
|
||||||
for (auto i: init_list)
|
for (auto i: init_list)
|
||||||
insert(std::get<0>(i), std::get<1>(i));
|
insert(std::get<0>(i), std::get<1>(i));
|
||||||
@@ -90,7 +53,6 @@ public:
|
|||||||
if (this == &other) return *this;
|
if (this == &other) return *this;
|
||||||
clear();
|
clear();
|
||||||
pim_content = other.pim_content;
|
pim_content = other.pim_content;
|
||||||
pim_index = other.pim_index;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,12 +167,15 @@ public:
|
|||||||
T & operator [](const Key & key) {
|
T & operator [](const Key & key) {
|
||||||
bool f(false);
|
bool f(false);
|
||||||
ssize_t i = _find(key, f);
|
ssize_t i = _find(key, f);
|
||||||
if (f) return pim_content[pim_index[i].index];
|
if (!f) pim_content.insert(i, PIPair<Key, T>(key, T()));
|
||||||
pim_content.push_back(T());
|
return pim_content[i].second;
|
||||||
pim_index.insert(i, MapIndex(key, pim_content.size() - 1));
|
}
|
||||||
return pim_content.back();
|
const T operator [](const Key & key) const {
|
||||||
|
bool f(false);
|
||||||
|
ssize_t i = _find(key, f);
|
||||||
|
if (f) return pim_content[i].second;
|
||||||
|
return T();
|
||||||
}
|
}
|
||||||
const T operator [](const Key & key) const {bool f(false); ssize_t i = _find(key, f); if (f) return pim_content[pim_index[i].index]; return T();}
|
|
||||||
const T at(const Key & key) const {return (*this)[key];}
|
const T at(const Key & key) const {return (*this)[key];}
|
||||||
|
|
||||||
PIMap<Key, T> & operator <<(const PIMap<Key, T> & other) {
|
PIMap<Key, T> & operator <<(const PIMap<Key, T> & other) {
|
||||||
@@ -221,27 +186,26 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
assert(&other != this);
|
assert(&other != this);
|
||||||
if (other.isEmpty()) return *this;
|
if (other.isEmpty()) return *this;
|
||||||
if (other.size() == 1) {insert(other.pim_index[0].key, other.pim_content[0]); return *this;}
|
// if (other.size() == 1) {insert(other.pim_index[0].key, other.pim_content[0]); return *this;}
|
||||||
if (other.size() == 2) {insert(other.pim_index[0].key, other.pim_content[0]); insert(other.pim_index[1].key, other.pim_content[1]); return *this;}
|
// if (other.size() == 2) {insert(other.pim_index[0].key, other.pim_content[0]); insert(other.pim_index[1].key, other.pim_content[1]); return *this;}
|
||||||
for (int i = 0; i < other.pim_index.size_s(); ++i)
|
for (int i = 0; i < other.pim_content.size_s(); ++i)
|
||||||
insert(other.pim_index[i].key, other.pim_content[other.pim_index[i].index]);
|
insert(other.pim_content[i].first, other.pim_content[i].second);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator ==(const PIMap<Key, T> & t) const {return (pim_content == t.pim_content && pim_index == t.pim_index);}
|
bool operator ==(const PIMap<Key, T> & t) const {return (pim_content == t.pim_content);}
|
||||||
bool operator !=(const PIMap<Key, T> & t) const {return (pim_content != t.pim_content || pim_index != t.pim_index);}
|
bool operator !=(const PIMap<Key, T> & t) const {return (pim_content != t.pim_content);}
|
||||||
bool contains(const Key & key) const {bool f(false); _find(key, f); return f;}
|
bool contains(const Key & key) const {bool f(false); _find(key, f); return f;}
|
||||||
|
|
||||||
PIMap<Key, T> & reserve(size_t new_size) {pim_content.reserve(new_size); pim_index.reserve(new_size); return *this;}
|
PIMap<Key, T> & reserve(size_t new_size) {pim_content.reserve(new_size);return *this;}
|
||||||
|
|
||||||
PIMap<Key, T> & removeOne(const Key & key) {bool f(false); ssize_t i = _find(key, f); if (f) _remove(i); return *this;}
|
PIMap<Key, T> & removeOne(const Key & key) {bool f(false); ssize_t i = _find(key, f); if (f) _remove(i); return *this;}
|
||||||
PIMap<Key, T> & remove(const Key & key) {return removeOne(key);}
|
PIMap<Key, T> & remove(const Key & key) {return removeOne(key);}
|
||||||
PIMap<Key, T> & erase(const Key & key) {return removeOne(key);}
|
PIMap<Key, T> & erase(const Key & key) {return removeOne(key);}
|
||||||
PIMap<Key, T> & clear() {pim_content.clear(); pim_index.clear(); return *this;}
|
PIMap<Key, T> & clear() {pim_content.clear(); return *this;}
|
||||||
|
|
||||||
void swap(PIMap<Key, T> & other) {
|
void swap(PIMap<Key, T> & other) {
|
||||||
pim_content.swap(other.pim_content);
|
pim_content.swap(other.pim_content);
|
||||||
pim_index.swap(other.pim_index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PIMap<Key, T> & insert(const Key & key, const T & value) {
|
PIMap<Key, T> & insert(const Key & key, const T & value) {
|
||||||
@@ -249,10 +213,9 @@ public:
|
|||||||
ssize_t i = _find(key, f);
|
ssize_t i = _find(key, f);
|
||||||
//piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value;
|
//piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value;
|
||||||
if (f) {
|
if (f) {
|
||||||
pim_content[pim_index[i].index] = value;
|
pim_content[i].second = value;
|
||||||
} else {
|
} else {
|
||||||
pim_content.push_back(value);
|
pim_content.insert(i, PIPair<Key, T>(key, value));
|
||||||
pim_index.insert(i, MapIndex(key, pim_content.size() - 1));
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -261,20 +224,34 @@ public:
|
|||||||
ssize_t i = _find(key, f);
|
ssize_t i = _find(key, f);
|
||||||
//piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value;
|
//piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value;
|
||||||
if (f) {
|
if (f) {
|
||||||
pim_content[pim_index[i].index] = std::move(value);
|
pim_content[i].second = std::move(value);
|
||||||
} else {
|
} else {
|
||||||
pim_content.push_back(std::move(value));
|
// pim_content.push_back(std::move(value));
|
||||||
pim_index.insert(i, MapIndex(key, pim_content.size() - 1));
|
// pim_index.insert(i, MapIndex(key, pim_content.size() - 1));
|
||||||
|
pim_content.insert(i, PIPair<Key, T>(key, std::move(value)));
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
const T value(const Key & key, const T & default_ = T()) const {bool f(false); ssize_t i = _find(key, f); if (!f) return default_; return pim_content[pim_index[i].index];}
|
const T value(const Key & key, const T & default_ = T()) const {
|
||||||
PIVector<T> values() const {return pim_content;}
|
bool f(false);
|
||||||
Key key(const T & value_, const Key & default_ = Key()) const {for (int i = 0; i < pim_index.size_s(); ++i) if (pim_content[pim_index[i].index] == value_) return pim_index[i].key; return default_;}
|
ssize_t i = _find(key, f);
|
||||||
|
if (!f) return default_;
|
||||||
|
return pim_content[i].second;
|
||||||
|
}
|
||||||
|
PIVector<T> values() const {
|
||||||
|
PIVector<T> ret;
|
||||||
|
for (size_t i = 0; i < pim_content.size(); ++i) ret << pim_content[i].second;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Key key(const T & value_, const Key & default_ = Key()) const {
|
||||||
|
for (int i = 0; i < pim_content.size_s(); ++i)
|
||||||
|
if (pim_content[i].second == value_)
|
||||||
|
return pim_content[i].first;
|
||||||
|
return default_;
|
||||||
|
}
|
||||||
PIVector<Key> keys() const {
|
PIVector<Key> keys() const {
|
||||||
PIVector<Key> ret;
|
PIVector<Key> ret;
|
||||||
for (int i = 0; i < pim_index.size_s(); ++i)
|
for (size_t i = 0; i < pim_content.size(); ++i) ret << pim_content[i].first;
|
||||||
ret << pim_index[i].key;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,68 +259,53 @@ public:
|
|||||||
piCout << "PIMap" << size() << "entries" << PICoutManipulators::NewLine << "content:";
|
piCout << "PIMap" << size() << "entries" << PICoutManipulators::NewLine << "content:";
|
||||||
for (size_t i = 0; i < pim_content.size(); ++i)
|
for (size_t i = 0; i < pim_content.size(); ++i)
|
||||||
piCout << PICoutManipulators::Tab << i << ":" << pim_content[i];
|
piCout << PICoutManipulators::Tab << i << ":" << pim_content[i];
|
||||||
piCout << "index:";
|
// piCout << "index:";
|
||||||
for (size_t i = 0; i < pim_index.size(); ++i)
|
// for (size_t i = 0; i < pim_index.size(); ++i)
|
||||||
piCout << PICoutManipulators::Tab << i << ":" << pim_index[i].key << "->" << pim_index[i].index;
|
// piCout << PICoutManipulators::Tab << i << ":" << pim_index[i].key << "->" << pim_index[i].index;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct MapIndex {
|
// struct MapIndex {
|
||||||
MapIndex(Key k = Key(), size_t i = 0): key(k), index(i) {;}
|
// MapIndex(Key k = Key(), size_t i = 0): key(k), index(i) {;}
|
||||||
Key key;
|
// Key key;
|
||||||
size_t index;
|
// size_t index;
|
||||||
bool operator ==(const MapIndex & s) const {return key == s.key;}
|
// bool operator ==(const MapIndex & s) const {return key == s.key;}
|
||||||
bool operator !=(const MapIndex & s) const {return key != s.key;}
|
// bool operator !=(const MapIndex & s) const {return key != s.key;}
|
||||||
bool operator <(const MapIndex & s) const {return key < s.key;}
|
// bool operator <(const MapIndex & s) const {return key < s.key;}
|
||||||
bool operator >(const MapIndex & s) const {return key > s.key;}
|
// bool operator >(const MapIndex & s) const {return key > s.key;}
|
||||||
};
|
// };
|
||||||
template <typename P, typename Key1, typename T1>
|
// template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
|
||||||
friend PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
|
// template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
|
||||||
template <typename P, typename Key1, typename T1>
|
|
||||||
friend PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
|
|
||||||
|
|
||||||
ssize_t binarySearch(ssize_t first, ssize_t last, const Key & key, bool & found) const {
|
ssize_t binarySearch(ssize_t first, ssize_t last, const Key & key, bool & found) const {
|
||||||
ssize_t mid;
|
ssize_t mid;
|
||||||
while (first <= last) {
|
while (first <= last) {
|
||||||
mid = (first + last) / 2;
|
mid = (first + last) / 2;
|
||||||
if (key > pim_index[mid].key) first = mid + 1;
|
if (key > pim_content[mid].first) first = mid + 1;
|
||||||
else if (key < pim_index[mid].key) last = mid - 1;
|
else if (key < pim_content[mid].first) last = mid - 1;
|
||||||
else {found = true; return mid;}
|
else {found = true; return mid;}
|
||||||
}
|
}
|
||||||
found = false;
|
found = false;
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
void _sort() {piQuickSort<MapIndex>(pim_index.data(), pim_index.size_s() - 1);}
|
|
||||||
ssize_t _find(const Key & k, bool & found) const {
|
ssize_t _find(const Key & k, bool & found) const {
|
||||||
if (pim_index.isEmpty()) {
|
if (pim_content.isEmpty()) {
|
||||||
found = false;
|
found = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return binarySearch(0, pim_index.size_s() - 1, k, found);
|
return binarySearch(0, pim_content.size_s() - 1, k, found);
|
||||||
}
|
}
|
||||||
void _remove(ssize_t index) {
|
void _remove(ssize_t index) {
|
||||||
//if (index >= pim_index.size()) return;
|
pim_content.remove(index);
|
||||||
size_t ci = pim_index[index].index, bi = pim_index.size() - 1;
|
|
||||||
pim_index.remove(index);
|
|
||||||
for (size_t i = 0; i < pim_index.size(); ++i)
|
|
||||||
if (pim_index[i].index == bi) {
|
|
||||||
pim_index[i].index = ci;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
piSwap<T>(pim_content[ci], pim_content.back());
|
|
||||||
pim_content.resize(pim_index.size());
|
|
||||||
}
|
}
|
||||||
const value_type _pair(ssize_t index) const {
|
const value_type _pair(ssize_t index) const {
|
||||||
if (index < 0 || index >= pim_index.size_s())
|
if (index < 0 || index >= pim_content.size_s()) return value_type();
|
||||||
return value_type();
|
return pim_content[index];
|
||||||
//piCout << "_pair" << index << pim_index[index].index;
|
|
||||||
return value_type(pim_index[index].key, pim_content[pim_index[index].index]);
|
|
||||||
}
|
}
|
||||||
Key & _key(ssize_t index) {return pim_index[index].key;}
|
Key & _key(ssize_t index) {return pim_content[index].first;}
|
||||||
T & _value(ssize_t index) {return pim_content[pim_index[index].index];}
|
T & _value(ssize_t index) {return pim_content[index].second;}
|
||||||
|
|
||||||
PIVector<T> pim_content;
|
PIDeque<PIPair<Key, T>> pim_content;
|
||||||
PIDeque<MapIndex> pim_index;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,6 @@ PIPair<T1,T2> createPIPair(const T1 & f, const T2 & s) {
|
|||||||
return PIPair<T1,T2>(f, s);
|
return PIPair<T1,T2>(f, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! \~english Creates \a PIPair object, deducing the target type from the types of arguments.
|
//! \~english Creates \a PIPair object, deducing the target type from the types of arguments.
|
||||||
//! \~russian Создает \a PIPair выводя типы из аргументов.
|
//! \~russian Создает \a PIPair выводя типы из аргументов.
|
||||||
//! \sa \a createPIPair()
|
//! \sa \a createPIPair()
|
||||||
@@ -142,5 +141,4 @@ PIPair<T1,T2> createPIPair(T1 && f, T2 && s) {
|
|||||||
return PIPair<T1,T2>(std::move(f), std::move(s));
|
return PIPair<T1,T2>(std::move(f), std::move(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // PIPAIR_H
|
#endif // PIPAIR_H
|
||||||
|
|||||||
@@ -645,7 +645,7 @@ public:
|
|||||||
inline size_t length() const {return piv_size;}
|
inline size_t length() const {return piv_size;}
|
||||||
|
|
||||||
//! \~english Number of elements that the container has currently allocated space for.
|
//! \~english Number of elements that the container has currently allocated space for.
|
||||||
//! \~russian Количество элементов, для которого сейчас выделена память массивом.
|
//! \~russian Количество элементов, для которого сейчас выделена память контейнером.
|
||||||
//! \~\details
|
//! \~\details
|
||||||
//! \~english To find out the actual number of items, use the function \a size().
|
//! \~english To find out the actual number of items, use the function \a size().
|
||||||
//! \~russian Чтобы узнать фактическое количество элементов используйте функцию \a size().
|
//! \~russian Чтобы узнать фактическое количество элементов используйте функцию \a size().
|
||||||
@@ -653,18 +653,18 @@ public:
|
|||||||
inline size_t capacity() const {return piv_rsize;}
|
inline size_t capacity() const {return piv_rsize;}
|
||||||
|
|
||||||
//! \~english Checks if the container has no elements.
|
//! \~english Checks if the container has no elements.
|
||||||
//! \~russian Проверяет пуст ли массив.
|
//! \~russian Проверяет пуст ли контейнер.
|
||||||
//! \~\return
|
//! \~\return
|
||||||
//! \~english **true** if the container is empty, **false** otherwise
|
//! \~english **true** if the container is empty, **false** otherwise
|
||||||
//! \~russian **true** если массив пуст, **false** иначе.
|
//! \~russian **true** если контейнер пуст, **false** иначе.
|
||||||
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
||||||
inline bool isEmpty() const {return (piv_size == 0);}
|
inline bool isEmpty() const {return (piv_size == 0);}
|
||||||
|
|
||||||
//! \~english Checks if the container has elements.
|
//! \~english Checks if the container has elements.
|
||||||
//! \~russian Проверяет не пуст ли массив.
|
//! \~russian Проверяет не пуст ли контейнер.
|
||||||
//! \~\return
|
//! \~\return
|
||||||
//! \~english **true** if the container is not empty, **false** otherwise
|
//! \~english **true** if the container is not empty, **false** otherwise
|
||||||
//! \~russian **true** если массив не пуст, **false** иначе.
|
//! \~russian **true** если контейнер не пуст, **false** иначе.
|
||||||
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
||||||
inline bool isNotEmpty() const {return (piv_size > 0);}
|
inline bool isNotEmpty() const {return (piv_size > 0);}
|
||||||
|
|
||||||
@@ -1512,8 +1512,8 @@ public:
|
|||||||
//! Если `add_size < 0`, то с конца массива удаляются элементы.
|
//! Если `add_size < 0`, то с конца массива удаляются элементы.
|
||||||
//! Если `add_size < 0` и в массиве меньше элементов чем указано, то массив становится пустым.
|
//! Если `add_size < 0` и в массиве меньше элементов чем указано, то массив становится пустым.
|
||||||
//! \~\sa \a resize()
|
//! \~\sa \a resize()
|
||||||
inline PIVector<T> & enlarge(ssize_t add_size, const T & e = T()) {
|
inline PIVector<T> & enlarge(llong add_size, const T & e = T()) {
|
||||||
ssize_t ns = size_s() + add_size;
|
llong ns = size_s() + add_size;
|
||||||
if (ns <= 0) clear();
|
if (ns <= 0) clear();
|
||||||
else resize(size_t(ns), e);
|
else resize(size_t(ns), e);
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
@@ -265,15 +265,13 @@
|
|||||||
|
|
||||||
#ifdef CC_GCC
|
#ifdef CC_GCC
|
||||||
# undef DEPRECATED
|
# undef DEPRECATED
|
||||||
# undef DEPRECATEDM
|
|
||||||
# define DEPRECATED __attribute__((deprecated))
|
# define DEPRECATED __attribute__((deprecated))
|
||||||
# define DEPRECATEDM(msg) __attribute__((deprecated(msg)))
|
|
||||||
# if CC_GCC_VERSION > 0x025F // > 2.95
|
# if CC_GCC_VERSION > 0x025F // > 2.95
|
||||||
# pragma GCC diagnostic warning "-Wdeprecated-declarations"
|
|
||||||
# ifdef LINUX
|
# ifdef LINUX
|
||||||
# define HAS_LOCALE
|
# define HAS_LOCALE
|
||||||
# endif
|
# endif
|
||||||
# ifdef MAC_OS
|
# ifdef MAC_OS
|
||||||
|
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
# pragma GCC diagnostic ignored "-Wundefined-bool-conversion"
|
# pragma GCC diagnostic ignored "-Wundefined-bool-conversion"
|
||||||
# pragma GCC diagnostic ignored "-Wc++11-extensions"
|
# pragma GCC diagnostic ignored "-Wc++11-extensions"
|
||||||
# endif
|
# endif
|
||||||
@@ -289,9 +287,7 @@
|
|||||||
|
|
||||||
#ifdef CC_VC
|
#ifdef CC_VC
|
||||||
# undef DEPRECATED
|
# undef DEPRECATED
|
||||||
# undef DEPRECATEDM
|
# define DEPRECATED
|
||||||
# define DEPRECATED __declspec(deprecated)
|
|
||||||
# define DEPRECATEDM(msg) __declspec(deprecated(msg))
|
|
||||||
# pragma warning(disable: 4018)
|
# pragma warning(disable: 4018)
|
||||||
# pragma warning(disable: 4061)
|
# pragma warning(disable: 4061)
|
||||||
# pragma warning(disable: 4100)
|
# pragma warning(disable: 4100)
|
||||||
@@ -316,9 +312,7 @@
|
|||||||
|
|
||||||
#ifdef CC_OTHER
|
#ifdef CC_OTHER
|
||||||
# undef DEPRECATED
|
# undef DEPRECATED
|
||||||
# undef DEPRECATEDM
|
|
||||||
# define DEPRECATED
|
# define DEPRECATED
|
||||||
# define DEPRECATEDM(msg)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif //DOXYGEN
|
#endif //DOXYGEN
|
||||||
|
|||||||
@@ -1,523 +0,0 @@
|
|||||||
/*! \file pibinarystream.h
|
|
||||||
* \ingroup Core
|
|
||||||
* \~\brief
|
|
||||||
* \~english Binary serialization interface
|
|
||||||
* \~russian Интерфейс бинарной сериализации
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
PIP - Platform Independent Primitives
|
|
||||||
Binary serialization interface
|
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PIBINARYSTREAM_H
|
|
||||||
#define PIBINARYSTREAM_H
|
|
||||||
|
|
||||||
#include "pimemoryblock.h"
|
|
||||||
#include "pibitarray.h"
|
|
||||||
#include "pimap.h"
|
|
||||||
#include "pivector2d.h"
|
|
||||||
|
|
||||||
#define PIP_BINARY_STREAM
|
|
||||||
|
|
||||||
#define BINARY_STREAM_FRIEND(T) \
|
|
||||||
template<typename P> friend PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const T & v); \
|
|
||||||
template<typename P> friend PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, T & v);
|
|
||||||
#define BINARY_STREAM_WRITE(T) \
|
|
||||||
template<typename P> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const T & v)
|
|
||||||
#define BINARY_STREAM_READ(T) \
|
|
||||||
template<typename P> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, T & v)
|
|
||||||
|
|
||||||
|
|
||||||
//! \ingroup Core
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english Binary serialization interface.
|
|
||||||
//! \~russian Интерфейс бинарной сериализации.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english In your class you should implement this methods:
|
|
||||||
//! \~russian В производном классе вы должны реализовать следующие методы:
|
|
||||||
//! \~\code
|
|
||||||
//! bool binaryStreamAppendImp (const void * d, size_t s);
|
|
||||||
//! bool binaryStreamTakeImp (void * d, size_t s);
|
|
||||||
//! ssize_t binaryStreamSizeImp () const;
|
|
||||||
//! \endcode
|
|
||||||
//! \~english function binaryStreamSizeImp must return -1 if size unknown
|
|
||||||
//! \~russian функция binaryStreamSizeImp должна возвращать -1 если нет информации о размере
|
|
||||||
template<typename P>
|
|
||||||
class PIBinaryStream {
|
|
||||||
public:
|
|
||||||
//! \~russian Записать данные
|
|
||||||
bool binaryStreamAppend(const void * d, size_t s) {
|
|
||||||
if (!static_cast<P*>(this)->binaryStreamAppendImp(d, s)) {
|
|
||||||
return false;
|
|
||||||
printf("[PIBinaryStream] binaryStreamAppend() error\n");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//! \~russian Прочитать данные
|
|
||||||
bool binaryStreamTake(void * d, size_t s) {
|
|
||||||
if (!static_cast<P*>(this)->binaryStreamTakeImp(d, s)) {
|
|
||||||
return false;
|
|
||||||
printf("[PIBinaryStream] binaryStreamTake() error\n");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~russian Узнать оставшийся размер
|
|
||||||
//!\~\details
|
|
||||||
//!\~russian возвращает -1 если нет информации о размере
|
|
||||||
ssize_t binaryStreamSize() const {
|
|
||||||
return static_cast<P*>(this)->binaryStreamSizeImp();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~russian Записать данные
|
|
||||||
template<typename T>
|
|
||||||
void binaryStreamAppend(T v) {binaryStreamAppend(&v, sizeof(v));}
|
|
||||||
|
|
||||||
//! \~russian Прочитать int
|
|
||||||
int binaryStreamTakeInt() {
|
|
||||||
int r = 0;
|
|
||||||
binaryStreamTake(&r, sizeof(r));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// helper class to detect default operators
|
|
||||||
template<typename P>
|
|
||||||
class PIBinaryStreamTrivialRef {
|
|
||||||
public:
|
|
||||||
PIBinaryStreamTrivialRef(PIBinaryStream<P> & s): p(s) {}
|
|
||||||
PIBinaryStream<P> & p;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<typename P, typename T> inline PIBinaryStream<P> & operator <<(PIBinaryStreamTrivialRef<P> s, const T & v) {
|
|
||||||
s.p << v;
|
|
||||||
return s.p;
|
|
||||||
}
|
|
||||||
template<typename P, typename T> inline PIBinaryStream<P> & operator >>(PIBinaryStreamTrivialRef<P> s, T & v) {
|
|
||||||
s.p >> v;
|
|
||||||
return s.p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// specify types
|
|
||||||
template<typename P> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const bool v) {
|
|
||||||
s.binaryStreamAppend((uchar)v);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template<typename P> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, bool & v) {
|
|
||||||
uchar c;
|
|
||||||
s.binaryStreamTake(&c, sizeof(c));
|
|
||||||
v = c;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIMemoryBlock v) {
|
|
||||||
s.binaryStreamAppend(v.data(), v.size());
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template<typename P> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIMemoryBlock v) {
|
|
||||||
s.binaryStreamTake(v.data(), v.size());
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// store simple types
|
|
||||||
|
|
||||||
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const T & v) {
|
|
||||||
//piCout << "<< enum";
|
|
||||||
s.binaryStreamAppend((int)v);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if<!std::is_enum<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStreamTrivialRef<P> operator <<(PIBinaryStream<P> & s, const T & v) {
|
|
||||||
s.binaryStreamAppend(&v, sizeof(v));
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Store operator for PIVector of any trivial copyable type
|
|
||||||
//! \~russian Оператор сохранения для PIVector тривиальных типов
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector<T> & v) {
|
|
||||||
//piCout << "<< vector trivial default";
|
|
||||||
s.binaryStreamAppend((int)v.size());
|
|
||||||
s.binaryStreamAppend(v.data(), v.size() * sizeof(T));
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector<T> & v) {
|
|
||||||
//piCout << "<< vector trivial custom";
|
|
||||||
s.binaryStreamAppend((int)v.size());
|
|
||||||
for (size_t i = 0; i < v.size(); ++i) s << v[i];
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Store operator for PIDeque of any trivial copyable type
|
|
||||||
//! \~russian Оператор сохранения для PIDeque тривиальных типов
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
|
|
||||||
//piCout << "<< deque trivial default";
|
|
||||||
s.binaryStreamAppend((int)v.size());
|
|
||||||
s.binaryStreamAppend(v.data(), v.size() * sizeof(T));
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
|
|
||||||
//piCout << "<< deque trivial custom";
|
|
||||||
s.binaryStreamAppend((int)v.size());
|
|
||||||
for (size_t i = 0; i < v.size(); ++i) s << v[i];
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Store operator for PIVector2D of any trivial copyable type
|
|
||||||
//! \~russian Оператор сохранения для PIVector2D тривиальных типов
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
|
|
||||||
//piCout << "<< vector2d trivial default";
|
|
||||||
s.binaryStreamAppend((int)v.rows());
|
|
||||||
s.binaryStreamAppend((int)v.cols());
|
|
||||||
s.binaryStreamAppend(v.data(), v.size() * sizeof(T));
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
|
|
||||||
//piCout << "<< vector2d trivial custom";
|
|
||||||
s.binaryStreamAppend((int)v.rows());
|
|
||||||
s.binaryStreamAppend((int)v.cols());
|
|
||||||
s << v.toPlainVector();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Store operator
|
|
||||||
//! \~russian Оператор сохранения
|
|
||||||
template<typename P>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Store operator
|
|
||||||
//! \~russian Оператор сохранения
|
|
||||||
template<typename P, typename Type0, typename Type1>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIPair<Type0, Type1> & v) {s << v.first << v.second; return s;}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// restore simple types
|
|
||||||
|
|
||||||
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, T & v) {
|
|
||||||
//piCout << ">> enum";
|
|
||||||
v = (T)s.binaryStreamTakeInt();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if<!std::is_enum<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStreamTrivialRef<P> operator >>(PIBinaryStream<P> & s, T & v) {
|
|
||||||
if (!s.binaryStreamTake(&v, sizeof(v))) {
|
|
||||||
printf("error with %s\n", __PIP_TYPENAME__(T));
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Restore operator for PIVector of any trivial copyable type
|
|
||||||
//! \~russian Оператор извлечения для PIVector тривиальных типов
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
|
|
||||||
//piCout << ">> vector trivial default";
|
|
||||||
int sz = s.binaryStreamTakeInt();
|
|
||||||
v._resizeRaw(sz);
|
|
||||||
if (!s.binaryStreamTake(v.data(), sz * sizeof(T))) {
|
|
||||||
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
|
|
||||||
//piCout << ">> vector trivial custom";
|
|
||||||
int sz = s.binaryStreamTakeInt();
|
|
||||||
v._resizeRaw(sz);
|
|
||||||
for (int i = 0; i < sz; ++i) s >> v[i];
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Restore operator for PIDeque of any trivial copyable type
|
|
||||||
//! \~russian Оператор извлечения для PIDeque тривиальных типов
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
|
|
||||||
//piCout << ">> deque trivial default";
|
|
||||||
int sz = s.binaryStreamTakeInt();
|
|
||||||
v._resizeRaw(sz);
|
|
||||||
if (!s.binaryStreamTake(v.data(), sz * sizeof(T))) {
|
|
||||||
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
|
|
||||||
//piCout << ">> deque trivial custom";
|
|
||||||
int sz = s.binaryStreamTakeInt();
|
|
||||||
v._resizeRaw(sz);
|
|
||||||
for (int i = 0; i < sz; ++i) s >> v[i];
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Restore operator for PIVector2D of any trivial copyable type
|
|
||||||
//! \~russian Оператор извлечения для PIVector2D тривиальных типов
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
|
|
||||||
//piCout << ">> vector2d trivial default";
|
|
||||||
int r, c;
|
|
||||||
r = s.binaryStreamTakeInt();
|
|
||||||
c = s.binaryStreamTakeInt();
|
|
||||||
v._resizeRaw(r, c);
|
|
||||||
if (!s.binaryStreamTake(v.data(), v.size() * sizeof(T))) {
|
|
||||||
printf("error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template<typename P, typename T,
|
|
||||||
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
|
||||||
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
|
|
||||||
//piCout << ">> vector2d trivial custom";
|
|
||||||
int r, c;
|
|
||||||
PIVector<T> tmp;
|
|
||||||
r = s.binaryStreamTakeInt();
|
|
||||||
c = s.binaryStreamTakeInt();
|
|
||||||
s >> tmp;
|
|
||||||
v = PIVector2D<T>(r, c, tmp);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Restore operator
|
|
||||||
//! \~russian Оператор извлечения
|
|
||||||
template<typename P>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIBitArray & v) {s >> v.size_ >> v.data_; return s;}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Restore operator
|
|
||||||
//! \~russian Оператор извлечения
|
|
||||||
template<typename P, typename Type0, typename Type1>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIPair<Type0, Type1> & v) {s >> v.first >> v.second; return s;}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// store complex types
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Store operator for PIVector of any compound type
|
|
||||||
//! \~russian Оператор сохранения для PIVector сложных типов
|
|
||||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector<T> & v) {
|
|
||||||
//piCout << "<< vector complex";
|
|
||||||
s.binaryStreamAppend(int(v.size_s()));
|
|
||||||
for (size_t i = 0; i < v.size(); ++i) s << v[i];
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Store operator for PIDeque of any compound type
|
|
||||||
//! \~russian Оператор сохранения для PIDeque сложных типов
|
|
||||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
|
|
||||||
//piCout << "<< deque complex";
|
|
||||||
s.binaryStreamAppend(int(v.size_s()));
|
|
||||||
for (size_t i = 0; i < v.size(); ++i) s << v[i];
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Store operator for PIVector2D of any compound type
|
|
||||||
//! \~russian Оператор сохранения для PIVector2D сложных типов
|
|
||||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
|
|
||||||
//piCout << "<< vector2d complex";
|
|
||||||
s.binaryStreamAppend(int(v.rows()));
|
|
||||||
s.binaryStreamAppend(int(v.cols()));
|
|
||||||
s << v.toPlainVector();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// restore complex types
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Restore operator for PIVector of any compound type
|
|
||||||
//! \~russian Оператор извлечения для PIVector сложных типов
|
|
||||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
|
|
||||||
//piCout << ">> vector complex";
|
|
||||||
/*if (s.size_s() < 4) {
|
|
||||||
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
|
|
||||||
assert(s.size_s() >= 4);
|
|
||||||
}*/
|
|
||||||
v.resize(s.binaryStreamTakeInt());
|
|
||||||
for (size_t i = 0; i < v.size(); ++i) s >> v[i];
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Restore operator for PIDeque of any compound type
|
|
||||||
//! \~russian Оператор извлечения для PIDeque сложных типов
|
|
||||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
|
|
||||||
//piCout << ">> deque complex";
|
|
||||||
/*if (s.size_s() < 4) {
|
|
||||||
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
|
|
||||||
assert(s.size_s() >= 4);
|
|
||||||
}*/
|
|
||||||
v.resize(s.binaryStreamTakeInt());
|
|
||||||
for (size_t i = 0; i < v.size(); ++i) s >> v[i];
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Restore operator for PIVector2D of any compound type
|
|
||||||
//! \~russian Оператор извлечения для PIVector2D сложных типов
|
|
||||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
|
|
||||||
//piCout << ">> vector2d complex";
|
|
||||||
/*if (s.size_s() < 8) {
|
|
||||||
printf("error with PIVecto2Dr<%s>\n", __PIP_TYPENAME__(T));
|
|
||||||
assert(s.size_s() >= 8);
|
|
||||||
}*/
|
|
||||||
int r, c;
|
|
||||||
PIVector<T> tmp;
|
|
||||||
r = s.binaryStreamTakeInt();
|
|
||||||
c = s.binaryStreamTakeInt();
|
|
||||||
s >> tmp;
|
|
||||||
v = PIVector2D<T>(r, c, tmp);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// other types
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Store operator
|
|
||||||
//! \~russian Оператор сохранения
|
|
||||||
template <typename P, typename Key, typename T>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIMap<Key, T> & v) {
|
|
||||||
s.binaryStreamAppend((int)v.pim_index.size_s());
|
|
||||||
for (uint i = 0; i < v.size(); ++i) {
|
|
||||||
s.binaryStreamAppend((int)v.pim_index[i].index);
|
|
||||||
s << v.pim_index[i].key;
|
|
||||||
}
|
|
||||||
s << v.pim_content;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Restore operator
|
|
||||||
//! \~russian Оператор извлечения
|
|
||||||
template <typename P, typename Key, typename T>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIMap<Key, T> & v) {
|
|
||||||
/*if (s.size_s() < 4) {
|
|
||||||
printf("error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
|
|
||||||
assert(s.size_s() >= 4);
|
|
||||||
}*/
|
|
||||||
int sz = s.binaryStreamTakeInt(); v.pim_index.resize(sz);
|
|
||||||
int ind = 0;
|
|
||||||
for (int i = 0; i < sz; ++i) {
|
|
||||||
ind = s.binaryStreamTakeInt();
|
|
||||||
s >> v.pim_index[i].key;
|
|
||||||
v.pim_index[i].index = ind;
|
|
||||||
}
|
|
||||||
s >> v.pim_content;
|
|
||||||
if (v.pim_content.size_s() != v.pim_index.size_s()) {
|
|
||||||
piCout << "Warning: loaded invalid PIMap, clear";
|
|
||||||
v.clear();
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// non-defined complex types
|
|
||||||
|
|
||||||
|
|
||||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const T & ) {
|
|
||||||
static_assert(std::is_trivially_copyable<T>::value, "[PIBinaryStream] Error: using undeclared operator << for complex type!");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
|
||||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, T & ) {
|
|
||||||
static_assert(std::is_trivially_copyable<T>::value, "[PIBinaryStream] Error: using undeclared operator >> for complex type!");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -28,10 +28,8 @@
|
|||||||
#include "pivector.h"
|
#include "pivector.h"
|
||||||
|
|
||||||
class PIP_EXPORT PIBitArray {
|
class PIP_EXPORT PIBitArray {
|
||||||
template <typename P>
|
friend PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v);
|
||||||
friend PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIBitArray & v);
|
friend PIByteArray & operator >>(PIByteArray & s, PIBitArray & v);
|
||||||
template <typename P>
|
|
||||||
friend PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIBitArray & v);
|
|
||||||
public:
|
public:
|
||||||
PIBitArray(const int & size = 0) {resize(size);}
|
PIBitArray(const int & size = 0) {resize(size);}
|
||||||
PIBitArray(uchar val) {resize(sizeof(val) * 8); data_[0] = val;}
|
PIBitArray(uchar val) {resize(sizeof(val) * 8); data_[0] = val;}
|
||||||
|
|||||||
@@ -28,14 +28,14 @@
|
|||||||
//! It can be constructed from any data and size.
|
//! It can be constructed from any data and size.
|
||||||
//! You can use %PIByteArray as binary stream
|
//! You can use %PIByteArray as binary stream
|
||||||
//! to serialize/deserialize any objects and data.
|
//! to serialize/deserialize any objects and data.
|
||||||
//! This class use PIDeque<uchar> and provide some handle function
|
//! This class based on PIDeque<uchar> and provide some handle function
|
||||||
//! to manipulate it.
|
//! to manipulate it.
|
||||||
//! \~russian
|
//! \~russian
|
||||||
//! %PIByteArray используется для хранения байтов.
|
//! %PIByteArray используется для хранения байтов.
|
||||||
//! Он может быть сконструирован из любых даных.
|
//! Он может быть сконструирован из любых даных.
|
||||||
//! Можно использовать %PIByteArray как потоковый объект
|
//! Можно использовать %PIByteArray как потоковый объект
|
||||||
//! для сериализации/десериализации любых типов и данных.
|
//! для сериализации/десериализации любых типов и данных.
|
||||||
//! Этот класс использует PIDeque<uchar> и предоставляет набор
|
//! Этот класс наследован от PIDeque<uchar> и предоставляет набор
|
||||||
//! удобных методов для работы с байтами.
|
//! удобных методов для работы с байтами.
|
||||||
//!
|
//!
|
||||||
//! \~english \section PIByteArray_sec0 Usage
|
//! \~english \section PIByteArray_sec0 Usage
|
||||||
@@ -438,3 +438,38 @@ std::ostream &operator <<(std::ostream & s, const PIByteArray & ba) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray & operator >>(PIByteArray & s, PIByteArray & v) {
|
||||||
|
if (s.size_s() < 4) {
|
||||||
|
s.clear();
|
||||||
|
v.clear();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
assert(s.size_s() >= 4);
|
||||||
|
int sz = 0;
|
||||||
|
s >> sz;
|
||||||
|
if (sz > s.size_s()) {
|
||||||
|
piCout << "[PIByteArray] Warning: operator >> wants too much data, discard!" << sz << s.size_s();
|
||||||
|
s.clear();
|
||||||
|
v.clear();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
v.resize(sz);
|
||||||
|
if (sz > 0) {
|
||||||
|
memcpy(v.data(), s.data(), sz);
|
||||||
|
s.remove(0, sz);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v) {
|
||||||
|
s << int(v.size_s());
|
||||||
|
int os = s.size_s();
|
||||||
|
if (v.size_s() > 0) {
|
||||||
|
s.enlarge(v.size_s());
|
||||||
|
memcpy(s.data(os), v.data(), v.size());
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,7 +27,9 @@
|
|||||||
#define PIBYTEARRAY_H
|
#define PIBYTEARRAY_H
|
||||||
|
|
||||||
#include "pichar.h"
|
#include "pichar.h"
|
||||||
#include "pibinarystream.h"
|
#include "pibitarray.h"
|
||||||
|
#include "pimap.h"
|
||||||
|
#include "pivector2d.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
class PIString;
|
class PIString;
|
||||||
@@ -38,24 +40,23 @@ class PIByteArray;
|
|||||||
//! \~\brief
|
//! \~\brief
|
||||||
//! \~english The %PIByteArray class provides an array of bytes.
|
//! \~english The %PIByteArray class provides an array of bytes.
|
||||||
//! \~russian Класс %PIByteArray представляет собой массив байтов.
|
//! \~russian Класс %PIByteArray представляет собой массив байтов.
|
||||||
class PIP_EXPORT PIByteArray: public PIBinaryStream<PIByteArray>
|
class PIP_EXPORT PIByteArray: public PIDeque<uchar>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef ::PIMemoryBlock RawData DEPRECATEDM("use PIMemoryBlock instead");
|
|
||||||
|
|
||||||
//! \~english Constructs an empty byte array
|
//! \~english Constructs an empty byte array
|
||||||
//! \~russian Создает пустой байтовый массив
|
//! \~russian Создает пустой байтовый массив
|
||||||
PIByteArray() {}
|
PIByteArray() {;}
|
||||||
|
|
||||||
//! \~english Constructs copy of byte array "o"
|
//! \~english Constructs copy of byte array "o"
|
||||||
//! \~russian Создает копию байтового массива "o"
|
//! \~russian Создает копию байтового массива "o"
|
||||||
PIByteArray(const PIByteArray & o): d(o.d) {}
|
PIByteArray(const PIByteArray & o): PIDeque<uchar>(o) {}
|
||||||
|
|
||||||
//! \~english Constructs copy of byte array "o"
|
//! \~english Constructs copy of byte array "o"
|
||||||
//! \~russian Создает копию байтового массива "o"
|
//! \~russian Создает копию байтового массива "o"
|
||||||
PIByteArray(const PIDeque<uchar> & o): d(o) {}
|
PIByteArray(const PIDeque<uchar> & o): PIDeque<uchar>(o) {}
|
||||||
|
|
||||||
PIByteArray(PIByteArray && o): d(std::move(o.d)) {}
|
PIByteArray(PIByteArray && o): PIDeque<uchar>(std::move(o)) {}
|
||||||
|
|
||||||
//! \~english Constructs 0-filled byte array with size "size"
|
//! \~english Constructs 0-filled byte array with size "size"
|
||||||
//! \~russian Создает заполненный "0" байтовый массив размером "size"
|
//! \~russian Создает заполненный "0" байтовый массив размером "size"
|
||||||
@@ -63,989 +64,42 @@ public:
|
|||||||
|
|
||||||
//! \~english Constructs byte array from data "data" and size "size"
|
//! \~english Constructs byte array from data "data" and size "size"
|
||||||
//! \~russian Создает байтовый массив из данных по указателю "data" размером "size"
|
//! \~russian Создает байтовый массив из данных по указателю "data" размером "size"
|
||||||
PIByteArray(const void * data, const uint size): d((const uchar*)data, size_t(size)) {}
|
PIByteArray(const void * data, const uint size): PIDeque<uchar>((const uchar*)data, size_t(size)) {}
|
||||||
|
|
||||||
//! \~english Constructs byte array with size "size" filled by "t"
|
//! \~english Constructs byte array with size "size" filled by "t"
|
||||||
//! \~russian Создает заполненный "t" байтовый массив размером "size"
|
//! \~russian Создает заполненный "t" байтовый массив размером "size"
|
||||||
PIByteArray(const uint size, uchar t): d(size, t) {}
|
PIByteArray(const uint size, uchar t): PIDeque<uchar>(size, t) {}
|
||||||
|
|
||||||
//! \~english Contructs array from
|
|
||||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~russian Создает массив из
|
|
||||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~\details
|
|
||||||
//! \~\code
|
|
||||||
//! PIByteArray v{1,2,3};
|
|
||||||
//! piCout << v; // {1, 2, 3}
|
|
||||||
//! \endcode
|
|
||||||
PIByteArray(std::initializer_list<uchar> init_list) : d(init_list) {}
|
|
||||||
|
|
||||||
//! \~english Swaps array `v` other with this array.
|
//! \~english Help struct to store/restore custom blocks of data to/from PIByteArray
|
||||||
//! \~russian Меняет местами массив `v` с этим массивом.
|
//! \~russian Вспомогательная структура для сохранения/извлечения произвольного блока данных в/из байтового массива
|
||||||
//! \~\details
|
struct RawData {
|
||||||
//! \~english This operation is very fast and never fails.
|
friend PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v);
|
||||||
//! \~russian Эта операция выполняется мгновенно без копирования памяти и никогда не дает сбоев.
|
friend PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v);
|
||||||
inline void swap(PIByteArray & other) {
|
public:
|
||||||
d.swap(other.d);
|
//! \~english Constructs data block
|
||||||
}
|
//! \~russian Создает блок данных
|
||||||
|
RawData(void * data = 0, int size = 0) {d = data; s = size;}
|
||||||
//! \~english Iterator to the first element.
|
RawData(const RawData & o) {d = o.d; s = o.s;}
|
||||||
//! \~russian Итератор на первый элемент.
|
//! \~english Constructs data block
|
||||||
//! \~\details 
|
//! \~russian Создает блок данных
|
||||||
//!
|
RawData(const void * data, const int size) {d = const_cast<void * >(data); s = size;}
|
||||||
//! \~english If the array is empty, the returned iterator is equal to \a end().
|
RawData & operator =(const RawData & o) {d = o.d; s = o.s; return *this;}
|
||||||
//! \~russian Если массив - пуст, возвращаемый итератор будет равен \a end().
|
private:
|
||||||
//! \~\return \ref stl_iterators
|
void * d;
|
||||||
//! \~\sa \a end(), \a rbegin(), \a rend()
|
int s;
|
||||||
inline PIDeque<uchar>::iterator begin() {return d.begin();}
|
};
|
||||||
|
|
||||||
//! \~english Iterator to the element following the last element.
|
|
||||||
//! \~russian Итератор на элемент, следующий за последним элементом.
|
|
||||||
//! \~\details 
|
|
||||||
//!
|
|
||||||
//! \~english This element acts as a placeholder;
|
|
||||||
//! attempting to access it results in undefined behavior.
|
|
||||||
//! \~russian Этот элемент существует лишь условно,
|
|
||||||
//! попытка доступа к нему приведёт к выходу за разрешенную память.
|
|
||||||
//! \~\return \ref stl_iterators
|
|
||||||
//! \~\sa \a begin(), \a rbegin(), \a rend()
|
|
||||||
inline PIDeque<uchar>::iterator end() {return d.end();}
|
|
||||||
|
|
||||||
inline PIDeque<uchar>::const_iterator begin() const {return d.begin();}
|
|
||||||
inline PIDeque<uchar>::const_iterator end() const {return d.end();}
|
|
||||||
|
|
||||||
//! \~english Returns a reverse iterator to the first element of the reversed array.
|
|
||||||
//! \~russian Обратный итератор на первый элемент.
|
|
||||||
//! \~\details 
|
|
||||||
//!
|
|
||||||
//! \~english It corresponds to the last element of the non-reversed array.
|
|
||||||
//! If the array is empty, the returned iterator is equal to \a rend().
|
|
||||||
//! \~russian Итератор для прохода массива в обратном порядке.
|
|
||||||
//! Указывает на последний элемент.
|
|
||||||
//! Если массив пустой, то совпадает с итератором \a rend().
|
|
||||||
//! \~\return \ref stl_iterators
|
|
||||||
//! \~\sa \a rend(), \a begin(), \a end()
|
|
||||||
inline PIDeque<uchar>::reverse_iterator rbegin() {return d.rbegin();}
|
|
||||||
|
|
||||||
//! \~english Returns a reverse iterator to the element.
|
|
||||||
//! following the last element of the reversed array.
|
|
||||||
//! \~russian Обратный итератор на элемент, следующий за последним элементом.
|
|
||||||
//! \~\details 
|
|
||||||
//!
|
|
||||||
//! \~english It corresponds to the element preceding the first element of the non-reversed array.
|
|
||||||
//! This element acts as a placeholder, attempting to access it results in undefined behavior.
|
|
||||||
//! \~russian Итератор для прохода массива в обратном порядке.
|
|
||||||
//! Указывает на элемент, предшествующий первому элементу.
|
|
||||||
//! Этот элемент существует лишь условно,
|
|
||||||
//! попытка доступа к нему приведёт к выходу за разрешенную память.
|
|
||||||
//! \~\return \ref stl_iterators
|
|
||||||
//! \~\sa \a rbegin(), \a begin(), \a end()
|
|
||||||
inline PIDeque<uchar>::reverse_iterator rend() {return d.rend();}
|
|
||||||
|
|
||||||
inline PIDeque<uchar>::const_reverse_iterator rbegin() const {return d.rbegin();}
|
|
||||||
inline PIDeque<uchar>::const_reverse_iterator rend() const {return d.rend();}
|
|
||||||
|
|
||||||
//! \~english Number of elements in the container.
|
|
||||||
//! \~russian Количество элементов массива.
|
|
||||||
//! \~\sa \a size_s(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
|
||||||
inline size_t size() const {return d.size();}
|
|
||||||
|
|
||||||
//! \~english Number of elements in the container as signed value.
|
|
||||||
//! \~russian Количество элементов массива в виде знакового числа.
|
|
||||||
//! \~\sa \a size(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
|
||||||
inline ssize_t size_s() const {return d.size_s();}
|
|
||||||
|
|
||||||
//! \~english Same as \a size().
|
|
||||||
//! \~russian Синоним \a size().
|
|
||||||
//! \~\sa \a size(), \a size_s(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
|
||||||
inline size_t length() const {return d.length();}
|
|
||||||
|
|
||||||
//! \~english Number of elements that the container has currently allocated space for.
|
|
||||||
//! \~russian Количество элементов, для которого сейчас выделена память массивом.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english To find out the actual number of items, use the function \a size().
|
|
||||||
//! \~russian Чтобы узнать фактическое количество элементов используйте функцию \a size().
|
|
||||||
//! \~\sa \a reserve(), \a size(), \a size_s()
|
|
||||||
inline size_t capacity() const {return d.capacity();}
|
|
||||||
|
|
||||||
//! \~english Checks if the container has no elements.
|
|
||||||
//! \~russian Проверяет пуст ли массив.
|
|
||||||
//! \~\return
|
|
||||||
//! \~english **true** if the container is empty, **false** otherwise
|
|
||||||
//! \~russian **true** если массив пуст, **false** иначе.
|
|
||||||
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
|
||||||
inline bool isEmpty() const {return d.isEmpty();}
|
|
||||||
|
|
||||||
//! \~english Checks if the container has elements.
|
|
||||||
//! \~russian Проверяет не пуст ли массив.
|
|
||||||
//! \~\return
|
|
||||||
//! \~english **true** if the container is not empty, **false** otherwise
|
|
||||||
//! \~russian **true** если массив не пуст, **false** иначе.
|
|
||||||
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
|
|
||||||
inline bool isNotEmpty() const {return d.isNotEmpty();}
|
|
||||||
|
|
||||||
//! \~english Tests whether at least one element in the array
|
|
||||||
//! passes the test implemented by the provided function `test`.
|
|
||||||
//! \~russian Проверяет, удовлетворяет ли какой-либо элемент массива условию,
|
|
||||||
//! заданному в передаваемой функции `test`.
|
|
||||||
//! \~\return
|
|
||||||
//! \~english **true** if, in the array,
|
|
||||||
//! it finds an element for which the provided function returns **true**;
|
|
||||||
//! otherwise it returns **false**. Always returns **false** if is empty.
|
|
||||||
//! \~russian **true** если хотя бы для одного элемента
|
|
||||||
//! передаваемая функция возвращает **true**, в остальных случаях **false**.
|
|
||||||
//! Метод возвращает **false** при любом условии для пустого массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~\sa \a every(), \a contains(), \a entries(), \a forEach()
|
|
||||||
inline bool any(std::function<bool(uchar e)> test) const {
|
|
||||||
return d.any(test);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Tests whether all elements in the array passes the test
|
|
||||||
//! implemented by the provided function `test`.
|
|
||||||
//! \~russian Проверяет, удовлетворяют ли все элементы массива условию,
|
|
||||||
//! заданному в передаваемой функции `test`.
|
|
||||||
//! \~\return
|
|
||||||
//! \~english **true** if, in the array,
|
|
||||||
//! it finds an element for which the provided function returns **true**;
|
|
||||||
//! otherwise it returns **false**. Always returns **true** if is empty.
|
|
||||||
//! \~russian **true** если для всех элементов передаваемая функция возвращает **true**,
|
|
||||||
//! в остальных случаях **false**.
|
|
||||||
//! Метод возвращает **true** при любом условии для пустого массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~\sa \a any(), \a contains(), \a entries(), \a forEach()
|
|
||||||
inline bool every(std::function<bool(uchar e)> test) const {
|
|
||||||
return d.every(test);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Full access to element by `index`.
|
|
||||||
//! \~russian Полный доступ к элементу по индексу `index`.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Element index starts from `0`.
|
|
||||||
//! Element index must be in range from `0` to `size()-1`.
|
|
||||||
//! Otherwise will be undefined behavior.
|
|
||||||
//! \~russian Индекс элемента считается от `0`.
|
|
||||||
//! Индекс элемента должен лежать в пределах от `0` до `size()-1`.
|
|
||||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
|
||||||
//! \~\sa \a at()
|
|
||||||
inline uchar & operator [](size_t index) {return d[index];}
|
|
||||||
inline uchar operator [](size_t index) const {return d[index];}
|
|
||||||
|
|
||||||
//! \~english Read only access to element by `index`.
|
|
||||||
//! \~russian Доступ исключительно на чтение к элементу по индексу `index`.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Element index starts from `0`.
|
|
||||||
//! Element index must be in range from `0` to `size()-1`.
|
|
||||||
//! Otherwise will be undefined behavior.
|
|
||||||
//! \~russian Индекс элемента считается от `0`.
|
|
||||||
//! Индекс элемента должен лежать в пределах от `0` до `size()-1`.
|
|
||||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
|
||||||
inline uchar at(size_t index) const {return d.at(index);}
|
|
||||||
|
|
||||||
//! \~english Last element.
|
|
||||||
//! \~russian Последний элемент массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Returns a reference to the last item in the array.
|
|
||||||
//! This function assumes that the array isn't empty.
|
|
||||||
//! Otherwise will be undefined behavior.
|
|
||||||
//! \~russian Возвращает ссылку на последний элемент в массиве.
|
|
||||||
//! Эта функция предполагает, что массив не пустой.
|
|
||||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
|
||||||
inline uchar & back() {return d.back();}
|
|
||||||
inline uchar back() const {return d.back();}
|
|
||||||
|
|
||||||
//! \~english Last element.
|
|
||||||
//! \~russian Первый элемент массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Returns a reference to the last item in the array.
|
|
||||||
//! This function assumes that the array isn't empty.
|
|
||||||
//! Otherwise will be undefined behavior.
|
|
||||||
//! \~russian Возвращает ссылку на пенрвый элемент в массиве.
|
|
||||||
//! Эта функция предполагает, что массив не пустой.
|
|
||||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
|
||||||
inline uchar & front() {return d.front();}
|
|
||||||
inline uchar front() const {return d.front();}
|
|
||||||
|
|
||||||
//! \~english Tests if element `e` exists in the array.
|
|
||||||
//! \~russian Проверяет наличие элемента `e` в массиве.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Optional argument `start` - the position in this array at which to begin searching.
|
|
||||||
//! If the index is greater than or equal to the array's size,
|
|
||||||
//! **false** is returned, which means the array will not be searched.
|
|
||||||
//! If the provided index value is a negative number,
|
|
||||||
//! it is taken as the offset from the end of the array.
|
|
||||||
//! Note: if the provided index is negative,
|
|
||||||
//! the array is still searched from front to back.
|
|
||||||
//! Default: 0 (entire array is searched).
|
|
||||||
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
|
|
||||||
//! Если индекс больше или равен длине массива,
|
|
||||||
//! возвращается **false**, что означает, что массив даже не просматривается.
|
|
||||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
|
||||||
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
|
|
||||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
|
|
||||||
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
|
|
||||||
//! \~\code
|
|
||||||
//! PIByteArray v{1, 2, 3, 4};
|
|
||||||
//! piCout << v.contains(3); // true
|
|
||||||
//! piCout << v.contains(5); // false
|
|
||||||
//! piCout << v.contains(3, 3); // false
|
|
||||||
//! piCout << v.contains(3, -2); // true
|
|
||||||
//! piCout << v.contains(3, -99); // true
|
|
||||||
//! \endcode
|
|
||||||
//! \~\return
|
|
||||||
//! \~english **true** if the array contains an occurrence of element `e`,
|
|
||||||
//! otherwise it returns **false**.
|
|
||||||
//! \~russian **true** если элемент `e` присутствует в массиве,
|
|
||||||
//! в остальных случаях **false**.
|
|
||||||
//! \~\sa \a every(), \a any(), \a entries()
|
|
||||||
inline bool contains(uchar e, ssize_t start = 0) const {
|
|
||||||
return d.contains(e, start);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Count elements equal `e` in the array.
|
|
||||||
//! \~russian Подсчитывает количество элементов, совпадающих с элементом `e` в массиве.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Optional argument `start` - the position in this array at which to begin searching.
|
|
||||||
//! If the index is greater than or equal to the array's size,
|
|
||||||
//! 0 is returned, which means the array will not be searched.
|
|
||||||
//! If the provided index value is a negative number,
|
|
||||||
//! it is taken as the offset from the end of the array.
|
|
||||||
//! Note: if the provided index is negative,
|
|
||||||
//! the array is still searched from front to back.
|
|
||||||
//! Default: 0 (entire array is searched).
|
|
||||||
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
|
|
||||||
//! Если индекс больше или равен длине массива,
|
|
||||||
//! возвращается 0, что означает, что массив даже не просматривается.
|
|
||||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
|
||||||
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
|
|
||||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
|
|
||||||
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
|
|
||||||
//! \~\sa \a every(), \a any(), \a contains(), \a indexOf()
|
|
||||||
inline int entries(uchar e, ssize_t start = 0) const {
|
|
||||||
return d.entries(e, start);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Count elements in the array passes the test implemented by the provided function `test`.
|
|
||||||
//! \~russian Подсчитывает количество элементов в массиве,
|
|
||||||
//! проходящих по условию, заданному в передаваемой функции `test`.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Overloaded function.
|
|
||||||
//! Optional argument `start` - the position in this array at which to begin searching.
|
|
||||||
//! If the index is greater than or equal to the array's size,
|
|
||||||
//! 0 is returned, which means the array will not be searched.
|
|
||||||
//! If the provided index value is a negative number,
|
|
||||||
//! it is taken as the offset from the end of the array.
|
|
||||||
//! Note: if the provided index is negative,
|
|
||||||
//! the array is still searched from front to back.
|
|
||||||
//! Default: 0 (entire array is searched).
|
|
||||||
//! \~russian Перегруженная функция.
|
|
||||||
//! Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
|
|
||||||
//! Если индекс больше или равен длине массива,
|
|
||||||
//! возвращается 0, что означает, что массив даже не просматривается.
|
|
||||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
|
||||||
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
|
|
||||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
|
|
||||||
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
|
|
||||||
//! \~\sa \a every(), \a any(), \a contains(), \a indexWhere()
|
|
||||||
inline int entries(std::function<bool(uchar e)> test, ssize_t start = 0) const {
|
|
||||||
return d.entries(test, start);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Returns the first index at which a given element `e`
|
|
||||||
//! can be found in the array, or `-1` if it is not present.
|
|
||||||
//! \~russian Возвращает первый индекс, по которому данный элемент `e`
|
|
||||||
//! может быть найден в массиве или `-1`, если такого индекса нет.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Optional argument `start` - the position in this array at which to begin searching.
|
|
||||||
//! If the index is greater than or equal to the array's size,
|
|
||||||
//! `-1` is returned, which means the array will not be searched.
|
|
||||||
//! If the provided index value is a negative number,
|
|
||||||
//! it is taken as the offset from the end of the array.
|
|
||||||
//! Note: if the provided index is negative,
|
|
||||||
//! the array is still searched from front to back.
|
|
||||||
//! Default: 0 (entire array is searched).
|
|
||||||
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
|
|
||||||
//! Если индекс больше или равен длине массива,
|
|
||||||
//! возвращается `-1`, что означает, что массив даже не просматривается.
|
|
||||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
|
||||||
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
|
|
||||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
|
|
||||||
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
|
|
||||||
//! \~\code
|
|
||||||
//! PIByteArray v{2, 5, 9};
|
|
||||||
//! piCout << v.indexOf(2); // 0
|
|
||||||
//! piCout << v.indexOf(7); // -1
|
|
||||||
//! piCout << v.indexOf(9, 2); // 2
|
|
||||||
//! piCout << v.indexOf(2, -1); // -1
|
|
||||||
//! piCout << v.indexOf(2, -3); // 0
|
|
||||||
//! \endcode
|
|
||||||
//! \~\sa \a indexWhere(), \a lastIndexOf(), \a lastIndexWhere(), \a contains()
|
|
||||||
inline ssize_t indexOf(const uchar & e, ssize_t start = 0) const {
|
|
||||||
return d.indexOf(e, start);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Returns the first index passes the test implemented by the provided function `test`,
|
|
||||||
//! or `-1` if it is not present.
|
|
||||||
//! can be found in the array, or `-1` if it is not present.
|
|
||||||
//! \~russian Возвращает первый индекс элемента проходящего по условию,
|
|
||||||
//! заданному в передаваемой функции `test`, или `-1`, если таких элементов нет.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Optional argument `start` - the position in this array at which to begin searching.
|
|
||||||
//! If the index is greater than or equal to the array's size,
|
|
||||||
//! `-1` is returned, which means the array will not be searched.
|
|
||||||
//! If the provided index value is a negative number,
|
|
||||||
//! it is taken as the offset from the end of the array.
|
|
||||||
//! Note: if the provided index is negative,
|
|
||||||
//! the array is still searched from front to back.
|
|
||||||
//! Default: 0 (entire array is searched).
|
|
||||||
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
|
|
||||||
//! Если индекс больше или равен длине массива,
|
|
||||||
//! возвращается `-1`, что означает, что массив даже не просматривается.
|
|
||||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
|
||||||
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
|
|
||||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
|
|
||||||
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
|
|
||||||
//! \~\code
|
|
||||||
//! PIByteArray v{2, 5, 9};
|
|
||||||
//! piCout << v.indexWhere([](const uchar & s){return s > 3;}); // 1
|
|
||||||
//! piCout << v.indexWhere([](const uchar & s){return s > 3;}, 2); // 2
|
|
||||||
//! piCout << v.indexWhere([](const uchar & s){return s > 10;}); // -1
|
|
||||||
//! \endcode
|
|
||||||
//! \~\sa \a indexOf(), \a lastIndexOf(), \a lastIndexWhere(), \a contains()
|
|
||||||
inline ssize_t indexWhere(std::function<bool(const uchar & e)> test, ssize_t start = 0) const {
|
|
||||||
return d.indexWhere(test, start);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Returns the last index at which a given element `e`
|
|
||||||
//! can be found in the array, or `-1` if it is not present.
|
|
||||||
//! \~russian Возвращает последний индекс, по которому данный элемент `e`
|
|
||||||
//! может быть найден в массиве или `-1`, если такого индекса нет.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Optional argument `start` - the position in this array
|
|
||||||
//! at which to start searching backwards.
|
|
||||||
//! If the index is greater than or equal to the array's size,
|
|
||||||
//! causes the whole array to be searched.
|
|
||||||
//! If the provided index value is a negative number,
|
|
||||||
//! it is taken as the offset from the end of the array.
|
|
||||||
//! Therefore, if calculated index less than 0,
|
|
||||||
//! the array is not searched, and the method returns `-1`.
|
|
||||||
//! Note: if the provided index is negative,
|
|
||||||
//! the array is still searched from back to front.
|
|
||||||
//! Default: -1 (entire array is searched).
|
|
||||||
//! \~russian Опциональный аргумент `start` указывает на индекс
|
|
||||||
//! c которого начинать поиск в обратном направлении.
|
|
||||||
//! Если индекс больше или равен длине массива, просматривается весь массив.
|
|
||||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
|
||||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от конца к началу.
|
|
||||||
//! Если рассчитанный индекс оказывается меньше 0, массив даже не просматривается.
|
|
||||||
//! Значение по умолчанию равно `-1`, что равно индексу последнего элемента
|
|
||||||
//! и означает, что просматривается весь массив.
|
|
||||||
//! \~\code
|
|
||||||
//! PIByteArray v{2, 5, 9, 2};
|
|
||||||
//! piCout << v.lastIndexOf(2); // 3
|
|
||||||
//! piCout << v.lastIndexOf(7); // -1
|
|
||||||
//! piCout << v.lastIndexOf(2, 2); // 0
|
|
||||||
//! piCout << v.lastIndexOf(2, -3); // 0
|
|
||||||
//! piCout << v.lastIndexOf(2, -300); // -1
|
|
||||||
//! piCout << v.lastIndexOf(2, 300); // 3
|
|
||||||
//! \endcode
|
|
||||||
//! \~\sa \a indexOf(), \a indexWhere(), \a lastIndexWhere(), \a contains()
|
|
||||||
inline ssize_t lastIndexOf(const uchar & e, ssize_t start = -1) const {
|
|
||||||
return d.lastIndexOf(e, start);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Returns the last index passes the test implemented by the provided function `test`,
|
|
||||||
//! or `-1` if it is not present.
|
|
||||||
//! \~russian Возвращает последний индекс элемента проходящего по условию,
|
|
||||||
//! заданному в передаваемой функции `test`, или `-1`, если таких элементов нет.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Optional argument `start` - the position in this array
|
|
||||||
//! at which to start searching backwards.
|
|
||||||
//! If the index is greater than or equal to the array's size,
|
|
||||||
//! causes the whole array to be searched.
|
|
||||||
//! If the provided index value is a negative number,
|
|
||||||
//! it is taken as the offset from the end of the array.
|
|
||||||
//! Therefore, if calculated index less than 0,
|
|
||||||
//! the array is not searched, and the method returns `-1`.
|
|
||||||
//! Note: if the provided index is negative,
|
|
||||||
//! the array is still searched from back to front.
|
|
||||||
//! Default: -1 (entire array is searched).
|
|
||||||
//! \~russian Опциональный аргумент `start` указывает на индекс
|
|
||||||
//! c которого начинать поиск в обратном направлении.
|
|
||||||
//! Если индекс больше или равен длине массива, просматривается весь массив.
|
|
||||||
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
|
|
||||||
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от конца к началу.
|
|
||||||
//! Если рассчитанный индекс оказывается меньше 0, массив даже не просматривается.
|
|
||||||
//! Значение по умолчанию равно `-1`, что равно индексу последнего элемента
|
|
||||||
//! и означает, что просматривается весь массив.
|
|
||||||
//! \~\sa \a indexOf(), \a lastIndexOf(), \a indexWhere(), \a contains()
|
|
||||||
inline ssize_t lastIndexWhere(std::function<bool(const uchar & e)> test, ssize_t start = -1) const {
|
|
||||||
return d.lastIndexWhere(test, start);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Pointer to array
|
|
||||||
//! \~russian Указатель на память массива
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Optional argument `index` the position in this array,
|
|
||||||
//! where is pointer. Default: start of array.
|
|
||||||
//! \~russian Опциональный аргумент `index` указывает на индекс c которого брать указатель.
|
|
||||||
//! По умолчанию указывает на начало массива.
|
|
||||||
inline uchar * data(size_t index = 0) {return d.data(index);}
|
|
||||||
|
|
||||||
//! \~english Read only pointer to array
|
|
||||||
//! \~russian Указатель на память массива только для чтения.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english The pointer can be used to access and modify the items in the array.
|
|
||||||
//! The pointer remains valid as long as the array isn't reallocated.
|
|
||||||
//! Optional argument `index` the position in this array,
|
|
||||||
//! where is pointer. Default: start of array.
|
|
||||||
//! \~russian Указатель можно использовать для доступа и изменения элементов в массиве.
|
|
||||||
//! Указатель остается действительным только до тех пор, пока массив не будет перераспределен.
|
|
||||||
//! Опциональный аргумент `index` указывает на индекс c которого брать указатель.
|
|
||||||
//! По умолчанию указывает на начало массива.
|
|
||||||
inline const uchar * data(size_t index = 0) const {return d.data(index);}
|
|
||||||
|
|
||||||
//! \~english Clear array, remove all elements.
|
|
||||||
//! \~russian Очищает массив, удаляет все элементы.
|
|
||||||
//! \~\details
|
|
||||||
//! \~\note
|
|
||||||
//! \~english Reserved memory will not be released.
|
|
||||||
//! \~russian Зарезервированная память не освободится.
|
|
||||||
//! \~\sa \a resize()
|
|
||||||
inline PIByteArray & clear() {
|
|
||||||
resize(0);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Assigns element 'e' to all items in the array.
|
|
||||||
//! \~russian Заполняет весь массив копиями элемента 'e'.
|
|
||||||
//! \~\details
|
|
||||||
//! \~\sa \a resize()
|
|
||||||
inline PIByteArray & fill(uchar e = 0) {
|
|
||||||
d.fill(e);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Assigns result of function 'f(size_t i)' to all items in the array.
|
|
||||||
//! \~russian Заполняет весь массив результатом вызова функции 'f(size_t i)'.
|
|
||||||
//! \~\details
|
|
||||||
//! \~\sa \a resize()
|
|
||||||
inline PIByteArray & fill(std::function<uchar(size_t i)> f) {
|
|
||||||
d.fill(f);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Same as \a fill().
|
|
||||||
//! \~russian Тоже самое что и \a fill().
|
|
||||||
//! \~\sa \a fill(), \a resize()
|
|
||||||
inline PIByteArray & assign(uchar e = 0) {return fill(e);}
|
|
||||||
|
|
||||||
//! \~english First does `resize(new_size)` then `fill(e)`.
|
|
||||||
//! \~russian Сначала делает `resize(new_size)`, затем `fill(e)`.
|
|
||||||
//! \~\sa \a fill(), \a resize()
|
|
||||||
inline PIByteArray & assign(size_t new_size, uchar e) {
|
|
||||||
resize(new_size);
|
|
||||||
return fill(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Sets size of the array, new elements are copied from `e`.
|
|
||||||
//! \~russian Устанавливает размер массива, новые элементы копируются из `e`.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english If `new_size` is greater than the current \a size(),
|
|
||||||
//! elements are added to the end; the new elements are initialized from `e`.
|
|
||||||
//! If `new_size` is less than the current \a size(), elements are removed from the end.
|
|
||||||
//! \~russian Если `new_size` больше чем текущий размер массива \a size(),
|
|
||||||
//! новые элементы добавляются в конец массива и создаются из `e`.
|
|
||||||
//! Если `new_size` меньше чем текущий размер массива \a size(),
|
|
||||||
//! лишние элементы удаляются с конца массива.
|
|
||||||
//! \~\sa \a size(), \a clear()
|
|
||||||
inline PIByteArray & resize(size_t new_size, uchar e = 0) {
|
|
||||||
d.resize(new_size, e);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Sets size of the array, new elements created by function `f(size_t i)`.
|
|
||||||
//! \~russian Устанавливает размер массива, новые элементы создаются функцией `f(size_t i)`.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english If `new_size` is greater than the current \a size(),
|
|
||||||
//! elements are added to the end; the new elements created by function `f(size_t i)`.
|
|
||||||
//! If `new_size` is less than the current \a size(), elements are removed from the end.
|
|
||||||
//! \~russian Если `new_size` больше чем текущий размер массива \a size(),
|
|
||||||
//! новые элементы добавляются в конец массива и функцией `f(size_t i)`.
|
|
||||||
//! Если `new_size` меньше чем текущий размер массива \a size(),
|
|
||||||
//! лишние элементы удаляются с конца массива.
|
|
||||||
//! \~\sa \a size(), \a clear()
|
|
||||||
inline PIByteArray & resize(size_t new_size, std::function<uchar(size_t i)> f) {
|
|
||||||
d.resize(new_size, f);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Return resized byte array
|
//! \~english Return resized byte array
|
||||||
//! \~russian Возвращает копию байтового массива с измененным размером
|
//! \~russian Возвращает копию байтового массива с измененным размером
|
||||||
PIByteArray resized(uint new_size) const {
|
PIByteArray resized(uint new_size) const {PIByteArray ret(new_size); memcpy(ret.data(), data(), new_size); return ret;}
|
||||||
PIByteArray ret(new_size);
|
|
||||||
memcpy(ret.data(), data(), new_size);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Attempts to allocate memory for at least `new_size` elements.
|
|
||||||
//! \~russian Резервируется память под как минимум `new_size` элементов.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english If you know in advance how large the array will be,
|
|
||||||
//! you should call this function to prevent reallocations and memory fragmentation.
|
|
||||||
//! If `new_size` is greater than the current \a capacity(),
|
|
||||||
//! new storage is allocated, otherwise the function does nothing.
|
|
||||||
//! This function does not change the \a size() of the array.
|
|
||||||
//! \~russian Если вы заранее знаете, насколько велик будет массив,
|
|
||||||
//! вы можете вызвать эту функцию, чтобы предотвратить перераспределение и фрагментацию памяти.
|
|
||||||
//! Если размер `new_size` больше чем выделенная память \a capacity(),
|
|
||||||
//! то произойдёт выделение новой памяти и перераспределение массива.
|
|
||||||
//! Эта функция не изменяет количество элементов в массиве \a size().
|
|
||||||
//! \~\sa \a size(), \a capacity(), \a resize()
|
|
||||||
inline PIByteArray & reserve(size_t new_size) {
|
|
||||||
d.reserve(new_size);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Inserts value `e` at `index` position in the array.
|
|
||||||
//! \~russian Вставляет значение `e` в позицию `index` в массиве.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english The index must be greater than 0 and less than or equal to \a size().
|
|
||||||
//! \~russian Индекс должен быть больше 0 и меньше или равен \a size().
|
|
||||||
//! \~\sa \a append(), \a prepend(), \a remove()
|
|
||||||
inline PIByteArray & insert(size_t index, uchar e = 0) {
|
|
||||||
d.insert(index, e);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Inserts array `v` at `index` position in the array.
|
|
||||||
//! \~russian Вставляет массив `v` в позицию `index` в массиве.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english The index must be greater than or equal to 0 and less than or equal to \a size().
|
|
||||||
//! \~russian Индекс должен быть больше или равен 0 и меньше или равен \a size().
|
|
||||||
//! \~\sa \a append(), \a prepend(), \a remove()
|
|
||||||
inline PIByteArray & insert(size_t index, const PIByteArray & v) {
|
|
||||||
d.insert(index, v.d);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Inserts the given elements at `index` position in the array.
|
|
||||||
//! \~russian Вставляет элементы в позицию `index` в массиве.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english The index must be greater than or equal to 0 and less than or equal to \a size().
|
|
||||||
//! Inserts the given elements from
|
|
||||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~russian Индекс должен быть больше или равен 0 и меньше или равен \a size().
|
|
||||||
//! Вставляет элементы из
|
|
||||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~\sa \a append(), \a prepend(), \a remove()
|
|
||||||
inline PIByteArray & insert(size_t index, std::initializer_list<uchar> init_list) {
|
|
||||||
d.insert(index, init_list);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Removes `count` elements from the middle of the array, starting at `index` position.
|
|
||||||
//! \~russian Удаляет элементы из массива, начиная с позиции `index` в количестве `count`.
|
|
||||||
//! \~\details
|
|
||||||
//! \~\sa \a resize(), \a insert(), \a removeOne(), \a removeAll(), \a removeWhere()
|
|
||||||
inline PIByteArray & remove(size_t index, size_t count = 1) {
|
|
||||||
d.remove(index, count);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Return sub-array starts from "index" and has "count" or less bytes
|
//! \~english Return sub-array starts from "index" and has "count" or less bytes
|
||||||
//! \~russian Возвращает подмассив с данными от индекса "index" и размером не более "count"
|
//! \~russian Возвращает подмассив с данными от индекса "index" и размером не более "count"
|
||||||
PIByteArray getRange(size_t index, size_t count) const {
|
PIByteArray getRange(size_t index, size_t count) const {
|
||||||
return d.getRange(index, count);
|
return PIDeque<uchar>::getRange(index, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Reverses this array.
|
|
||||||
//! \~russian Обращает порядок следования элементов этого массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english This method reverses an array [in place](https://en.wikipedia.org/wiki/In-place_algorithm).
|
|
||||||
//! The first array element becomes the last, and the last array element becomes the first.
|
|
||||||
//! The reverse method transposes the elements of the calling array object in place,
|
|
||||||
//! mutating the array, and returning a reference to the array.
|
|
||||||
//! \~russian Метод reverse() на месте переставляет элементы массива,
|
|
||||||
//! на котором он был вызван, изменяет массив и возвращает ссылку на него.
|
|
||||||
//! Первый элемент массива становится последним, а последний — первым.
|
|
||||||
//! \~\sa \a reversed()
|
|
||||||
inline PIByteArray & reverse() {
|
|
||||||
d.reverse();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Returns reversed array.
|
|
||||||
//! \~russian Возвращает перевернутый массив.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Returns a copy of the array with elements in reverse order.
|
|
||||||
//! The first array element becomes the last, and the last array element becomes the first.
|
|
||||||
//! \~russian Возвращает копию массива с элементами в обратном порядке.
|
|
||||||
//! Первый элемент массива становится последним, а последний — первым.
|
|
||||||
//! \~\sa \a reverse()
|
|
||||||
inline PIByteArray reversed() const {
|
|
||||||
PIByteArray ret(*this);
|
|
||||||
return ret.reverse();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Increases or decreases the size of the array by `add_size` elements.
|
|
||||||
//! \~russian Увеличивает или уменьшает размер массива на `add_size` элементов.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english If `add_size > 0` then elements are added to the end of the array.
|
|
||||||
//! If `add_size < 0` then elements are removed from the end of the array.
|
|
||||||
//! If `add_size < 0` and there are fewer elements in the array than specified, then the array becomes empty.
|
|
||||||
//! \~russian Если `add_size > 0`, то в конец массива добавляются элементы.
|
|
||||||
//! Если `add_size < 0`, то с конца массива удаляются элементы.
|
|
||||||
//! Если `add_size < 0` и в массиве меньше элементов чем указано, то массив становится пустым.
|
|
||||||
//! \~\sa \a resize()
|
|
||||||
inline PIByteArray & enlarge(ssize_t add_size, uchar e = 0) {
|
|
||||||
d.enlarge(add_size, e);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Remove no more than one element equal `e`.
|
|
||||||
//! \~russian Удаляет первый элемент, который равен элементу `e`.
|
|
||||||
//! \~\details
|
|
||||||
//! \~\sa \a remove(), \a removeAll(), \a removeWhere()
|
|
||||||
inline PIByteArray & removeOne(uchar e) {
|
|
||||||
d.removeOne(e);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Remove all elements equal `e`.
|
|
||||||
//! \~russian Удаляет все элементы, равные элементу `e`.
|
|
||||||
//! \~\details
|
|
||||||
//! \~\sa \a remove(), \a removeOne(), \a removeWhere()
|
|
||||||
inline PIByteArray & removeAll(uchar e) {
|
|
||||||
d.removeAll(e);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Remove all elements in the array
|
|
||||||
//! passes the test implemented by the provided function `test`.
|
|
||||||
//! \~russian Удаляет все элементы, удовлетворяющие условию,
|
|
||||||
//! заданному в передаваемой функции `test`.
|
|
||||||
//! \~\details
|
|
||||||
//! \~\sa \a remove(), \a removeOne(), \a removeWhere()
|
|
||||||
inline PIByteArray & removeWhere(std::function<bool(uchar e)> test) {
|
|
||||||
d.removeWhere(test);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Appends the given element `e` to the end of the array.
|
|
||||||
//! \~russian Добавляет элемент `e` в конец массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english If size() is less than capacity(), which is most often
|
|
||||||
//! then the addition will be very fast.
|
|
||||||
//! In any case, the addition is fast and does not depend on the size of the array.
|
|
||||||
//! If the new size() is greater than capacity()
|
|
||||||
//! then all iterators and references
|
|
||||||
//! (including the past-the-end iterator) are invalidated.
|
|
||||||
//! Otherwise only the past-the-end iterator is invalidated.
|
|
||||||
//! \~russian Если size() меньше capacity(), что часто бывает,
|
|
||||||
//! то добавление будет очень быстрым.
|
|
||||||
//! В любом случае добавление быстрое и не зависит от размера массива.
|
|
||||||
//! Если новый size() больше, чем capacity(),
|
|
||||||
//! то все итераторы и указатели становятся нерабочими.
|
|
||||||
//! В противном случае все, кроме итераторов, указывающих на конец массива,
|
|
||||||
//! остаются в рабочем состоянии.
|
|
||||||
//! \~\sa \a push_front(), \a append(), \a prepend(), \a insert()
|
|
||||||
inline PIByteArray & push_back(uchar e) {
|
|
||||||
d.push_back(e);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Appends the given elements to the end of the array.
|
|
||||||
//! \~russian Добавляет элементы в конец массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Overloaded function.
|
|
||||||
//! Appends the given elements from
|
|
||||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~russian Перегруженая функция.
|
|
||||||
//! Добавляет элементы из
|
|
||||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~\sa \a push_back()
|
|
||||||
inline PIByteArray & push_back(std::initializer_list<uchar> init_list) {
|
|
||||||
d.push_back(init_list);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Appends the given array `v` to the end of the array.
|
|
||||||
//! \~russian Добавляет массив `v` в конец массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Overloaded function.
|
|
||||||
//! \~russian Перегруженая функция.
|
|
||||||
//! \~\sa \a push_back()
|
|
||||||
inline PIByteArray & push_back(const PIByteArray & v) {
|
|
||||||
d.push_back(v.d);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Add to the end data "data" with size "size"
|
|
||||||
//! \~russian Добавляет в конец массива данные по указателю "data" размером "size"
|
|
||||||
PIByteArray & push_back(const void * data_, int size_) {uint ps = size(); enlarge(size_); memcpy(data(ps), data_, size_); return *this;}
|
|
||||||
|
|
||||||
//! \~english Appends the given element `e` to the begin of the array.
|
|
||||||
//! \~russian Добавляет элемент `e` в начало массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english If there is free space at the beginning of the array,
|
|
||||||
//! which is most often, then the addition will be very fast.
|
|
||||||
//! In any case, the addition is fast and does not depend on the size of the array.
|
|
||||||
//! If there is no free space at the beginning of the array
|
|
||||||
//! then all iterators and references
|
|
||||||
//! (including the past-the-begin iterator) are invalidated.
|
|
||||||
//! Otherwise only the past-the-begin iterator is invalidated.
|
|
||||||
//! \~russian Если в начале массива имеется свободное место,
|
|
||||||
//! что часто бывает, то добавление будет очень быстрым.
|
|
||||||
//! В любом случае добавление быстрое и не зависит от размера массива.
|
|
||||||
//! Если в начале массива нет свободного места,
|
|
||||||
//! то все итераторы и указатели становятся нерабочими.
|
|
||||||
//! В противном случае все, кроме итераторов указывающих, на начало массива,
|
|
||||||
//! остаются в рабочем состоянии.
|
|
||||||
//! \~\sa \a push_back(), \a append(), \a prepend(), \a insert()
|
|
||||||
inline PIByteArray & push_front(uchar e) {
|
|
||||||
d.push_front(e);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Appends the given array `v` to the begin of the array.
|
|
||||||
//! \~russian Добавляет массив `v` в начало массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Overloaded function.
|
|
||||||
//! \~russian Перегруженая функция.
|
|
||||||
//! \~\sa \a push_front()
|
|
||||||
inline PIByteArray & push_front(const PIByteArray & v) {
|
|
||||||
d.push_front(v.d);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Appends the given elements to the begin of the array.
|
|
||||||
//! \~russian Добавляет элементы в начало массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Overloaded function.
|
|
||||||
//! Appends the given elements from
|
|
||||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~russian Перегруженая функция.
|
|
||||||
//! Добавляет элементы из
|
|
||||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~\sa \a append()
|
|
||||||
inline PIByteArray & push_front(std::initializer_list<uchar> init_list) {
|
|
||||||
d.push_front(init_list);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Appends the given element `e` to the begin of the array.
|
|
||||||
//! \~russian Добавляет элемент `e` в начало массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english If there is free space at the beginning of the array,
|
|
||||||
//! which is most often, then the addition will be very fast.
|
|
||||||
//! In any case, the addition is fast and does not depend on the size of the array.
|
|
||||||
//! If there is no free space at the beginning of the array
|
|
||||||
//! then all iterators and references
|
|
||||||
//! (including the past-the-begin iterator) are invalidated.
|
|
||||||
//! Otherwise only the past-the-begin iterator is invalidated.
|
|
||||||
//! \~russian Если в начале массива имеется свободное место,
|
|
||||||
//! что часто бывает, то добавление будет очень быстрым.
|
|
||||||
//! В любом случае добавление быстрое и не зависит от размера массива.
|
|
||||||
//! Если в начале массива нет свободного места,
|
|
||||||
//! то все итераторы и указатели становятся нерабочими.
|
|
||||||
//! В противном случае все, кроме итераторов указывающих, на начало массива,
|
|
||||||
//! остаются в рабочем состоянии.
|
|
||||||
//! \~\sa \a push_back(), \a append(), \a prepend(), \a insert()
|
|
||||||
inline PIByteArray & prepend(uchar e) {
|
|
||||||
d.prepend(e);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Appends the given array `v` to the begin of the array.
|
|
||||||
//! \~russian Добавляет массив `v` в начало массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Overloaded function.
|
|
||||||
//! \~russian Перегруженая функция.
|
|
||||||
//! \~\sa \a prepend()
|
|
||||||
inline PIByteArray & prepend(const PIByteArray & v) {
|
|
||||||
d.prepend(v.d);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Appends the given elements to the begin of the array.
|
|
||||||
//! \~russian Добавляет элементы в начало массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Overloaded function.
|
|
||||||
//! Appends the given elements from
|
|
||||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~russian Перегруженая функция.
|
|
||||||
//! Добавляет элементы из
|
|
||||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~\sa \a append()
|
|
||||||
inline PIByteArray & prepend(std::initializer_list<uchar> init_list) {
|
|
||||||
d.prepend(init_list);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Remove one element from the end of the array.
|
|
||||||
//! \~russian Удаляет один элемент с конца массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Deleting an element from the end is very fast
|
|
||||||
//! and does not depend on the size of the array.
|
|
||||||
//! \~russian Удаление элемента с конца выполняется очень быстро
|
|
||||||
//! и не зависит от размера массива.
|
|
||||||
//! \~\sa \a pop_front(), \a take_back(), \a take_front()
|
|
||||||
inline PIByteArray & pop_back() {
|
|
||||||
d.pop_back();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Remove one element from the begining of the array.
|
|
||||||
//! \~russian Удаляет один элемент с начала массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Removing an element from the beginning takes longer than from the end.
|
|
||||||
//! This time is directly proportional to the size of the array.
|
|
||||||
//! All iterators and references are invalidated.
|
|
||||||
//! \~russian Удаление элемента с начала выполняется дольше, чем с конца.
|
|
||||||
//! Это время прямопропорционально размеру массива.
|
|
||||||
//! При удалении элемента все итераторы и указатели становятся нерабочими.
|
|
||||||
//! \~\sa \a pop_back(), \a take_back(), \a take_front()
|
|
||||||
inline PIByteArray & pop_front() {
|
|
||||||
d.pop_front();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Remove one element from the end of the array and return it.
|
|
||||||
//! \~russian Удаляет один элемент с начала массива и возвращает его.
|
|
||||||
//! \~\details
|
|
||||||
//! \~\sa \a take_front(), \a pop_back(), \a pop_front()
|
|
||||||
inline uchar take_back() {
|
|
||||||
return d.take_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Remove one element from the begining of the array and return it.
|
|
||||||
//! \~russian Удаляет один элемент с конца массива и возвращает его.
|
|
||||||
//! \~\details
|
|
||||||
//! \~\sa \a take_front(), \a pop_back(), \a pop_front()
|
|
||||||
inline uchar take_front() {
|
|
||||||
return d.take_front();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Returns a new array with all elements
|
|
||||||
//! that pass the test implemented by the provided function `test`.
|
|
||||||
//! \~russian Возвращает новый массив со всеми элементами,
|
|
||||||
//! прошедшими проверку, задаваемую в передаваемой функции `test`.
|
|
||||||
//! \~\details
|
|
||||||
//! \~\code
|
|
||||||
//! PIByteArray v{3, 2, 5, 2, 7};
|
|
||||||
//! PIByteArray v2 = v.filter([](const uchar & i){return i > 2;});
|
|
||||||
//! piCout << v2; // {3, 5, 7}
|
|
||||||
//! \endcode
|
|
||||||
//! \~\sa \a map(), \a any(), \a every()
|
|
||||||
inline PIByteArray filter(std::function<bool(const uchar & e)> test) const {
|
|
||||||
return PIByteArray(d.filter(test));
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Execute function `void f(const uchar & e)` for every element in array.
|
|
||||||
//! \~russian Выполняет функцию `void f(const uchar & e)` для каждого элемента массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~russian Не позволяет изменять элементы массива.
|
|
||||||
//! Для редактирования элементов используйте функцию вида `void f(uchar & e)`.
|
|
||||||
//! \~english Does not allow changing array elements.
|
|
||||||
//! To edit elements, use the function like `void f(T & e)`
|
|
||||||
//! \~\code
|
|
||||||
//! PIByteArray v{1, 2, 3, 4, 5};
|
|
||||||
//! int s = 0;
|
|
||||||
//! v.forEach([&s](const uchar & e){s += e;});
|
|
||||||
//! piCout << s; // 15
|
|
||||||
//! \endcode
|
|
||||||
//! \~\sa \a filter(), \a map(), \a reduce(), \a any(), \a every()
|
|
||||||
inline void forEach(std::function<void(const uchar & e)> f) const {
|
|
||||||
d.forEach(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Execute function `void f(uchar & e)` for every element in array.
|
|
||||||
//! \~russian Выполняет функцию `void f(uchar & e)` для каждого элемента массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Overloaded function.
|
|
||||||
//! Allows you to change the elements of the array.
|
|
||||||
//! \~russian Перегруженая функция.
|
|
||||||
//! Позволяет изменять элементы массива.
|
|
||||||
//! \~\code
|
|
||||||
//! PIByteArray v{1, 2, 3, 4, 5};
|
|
||||||
//! v.forEach([](uchar & e){e++;});
|
|
||||||
//! piCout << v; // {2, 3, 4, 5, 6}
|
|
||||||
//! \endcode
|
|
||||||
//! \~\sa \a filter(), \a map(), \a reduce(), \a any(), \a every()
|
|
||||||
inline PIByteArray & forEach(std::function<void(uchar & e)> f) {
|
|
||||||
d.forEach(f);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Сreates a new array populated with the results
|
|
||||||
//! of calling a provided function `ST f(const uchar & e)` on every element in the calling array.
|
|
||||||
//! \~russian Создаёт новый массив с результатом вызова указанной функции
|
|
||||||
//! `ST f(const T & e)` для каждого элемента массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Calls a provided function`ST f(const uchar & e)`
|
|
||||||
//! once for each element in an array, in order,
|
|
||||||
//! and constructs a new array from the results.
|
|
||||||
//! \~russian Метод `map` вызывает переданную функцию `ST f(const uchar & e)`
|
|
||||||
//! один раз для каждого элемента в порядке их появления
|
|
||||||
//! и конструирует новый массив из результатов её вызова.
|
|
||||||
//! \~\code
|
|
||||||
//! PIByteArray v{0x31, 0x0A, 0xFF};
|
|
||||||
//! PIStringList sl = v.map<PIString>([](const uchar & i){return PIString::fromNumber(i, 16);});
|
|
||||||
//! piCout << sl; {"31", "A", "FF"}
|
|
||||||
//! \endcode
|
|
||||||
//! \~\sa \a forEach(), \a reduce()
|
|
||||||
template <typename ST>
|
|
||||||
inline PIDeque<ST> map(std::function<ST(const uchar & e)> f) const {
|
|
||||||
return d.map<ST>(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Applies the function `ST f(const uchar & e, const ST & acc)`
|
|
||||||
//! to each element of the array (from left to right), returns one value.
|
|
||||||
//! \~russian Применяет функцию `ST f(const uchar & e, const ST & acc)`
|
|
||||||
//! к каждому элементу массива (слева-направо), возвращает одно значение.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english The reduce() method performs the `f` function
|
|
||||||
//! once for each element in the array.
|
|
||||||
//! If the `initial` argument is passed when calling reduce(),
|
|
||||||
//! then when the function `f` is called for the first time,
|
|
||||||
//! the value of `acc` will be assigned to `initial`.
|
|
||||||
//! If the array is empty, the value `initial` will be returned.
|
|
||||||
//! \param f is a function like `ST f(const uchar & e, const ST & acc)`,
|
|
||||||
//! executed for each element of the array. It takes two arguments:
|
|
||||||
//! * **e** - current element of the array
|
|
||||||
//! * **acc** - accumulator accumulating the value
|
|
||||||
//! which this function returns after visiting the next element
|
|
||||||
//!
|
|
||||||
//! \param initial _optional_ Object used as the second argument
|
|
||||||
//! when the `f` function is first called.
|
|
||||||
//! \~russian Метод reduce() выполняет функцию `f`
|
|
||||||
//! один раз для каждого элемента, присутствующего в массиве.
|
|
||||||
//! Если при вызове reduce() передан аргумент `initial`,
|
|
||||||
//! то при первом вызове функции `f` значение `acc`
|
|
||||||
//! будет равным значению `initial`.
|
|
||||||
//! Если массив пустой то будет возвращено значение `initial`.
|
|
||||||
//! \param f Функция, вида `ST f(const uchar & e, const ST & acc)`,
|
|
||||||
//! выполняющаяся для каждого элемента массива.
|
|
||||||
//! Она принимает два аргумента:
|
|
||||||
//! * **e** - текущий элемент массива
|
|
||||||
//! * **acc** - аккумулятор, аккумулирующий значение
|
|
||||||
//! которое возвращает эта функция после посещения очередного элемента
|
|
||||||
//!
|
|
||||||
//! \param initial _опциональный_ Объект,
|
|
||||||
//! используемый в качестве второго аргумента при первом вызове функции `f`.
|
|
||||||
//!
|
|
||||||
//! \~\code
|
|
||||||
//! PIByteArray v{1, 2, 3, 4, 5};
|
|
||||||
//! PIString s = v.reduce<PIString>([](const uchar & e, const PIString & acc){return acc + PIString::fromNumber(e);});
|
|
||||||
//! piCout << s; // "12345"
|
|
||||||
//! \endcode
|
|
||||||
//! \~\sa \a forEach(), \a map()
|
|
||||||
template <typename ST>
|
|
||||||
inline ST reduce(std::function<ST(const uchar & e, const ST & acc)> f, const ST & initial = ST()) const {
|
|
||||||
return d.reduce<ST>(f, initial);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Convert data to Base 64 and return this byte array
|
//! \~english Convert data to Base 64 and return this byte array
|
||||||
//! \~russian Преобразует данные в Base 64 и возвращает текущий массив
|
//! \~russian Преобразует данные в Base 64 и возвращает текущий массив
|
||||||
@@ -1088,21 +142,6 @@ public:
|
|||||||
//! \~russian Добавляет в конец массива байт "t"
|
//! \~russian Добавляет в конец массива байт "t"
|
||||||
PIByteArray & append(uchar t) {push_back(t); return *this;}
|
PIByteArray & append(uchar t) {push_back(t); return *this;}
|
||||||
|
|
||||||
//! \~english Appends the given elements to the end of the array.
|
|
||||||
//! \~russian Добавляет элементы в конец массива.
|
|
||||||
//! \~\details
|
|
||||||
//! \~english Overloaded function.
|
|
||||||
//! Appends the given elements from
|
|
||||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~russian Перегруженая функция.
|
|
||||||
//! Добавляет элементы из
|
|
||||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~\sa \a push_back()
|
|
||||||
inline PIByteArray & append(std::initializer_list<uchar> init_list) {
|
|
||||||
d.append(init_list);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Returns 8-bit checksum
|
//! \~english Returns 8-bit checksum
|
||||||
//! \~russian Возвращает 8-битную контрольную сумму
|
//! \~russian Возвращает 8-битную контрольную сумму
|
||||||
uchar checksumPlain8(bool inverse = true) const;
|
uchar checksumPlain8(bool inverse = true) const;
|
||||||
@@ -1115,7 +154,7 @@ public:
|
|||||||
//! \~russian Возвращает хэш содержимого
|
//! \~russian Возвращает хэш содержимого
|
||||||
uint hash() const;
|
uint hash() const;
|
||||||
|
|
||||||
void operator =(const PIDeque<uchar> & o) {resize(o.size()); memcpy(data(), o.data(), o.size());}
|
void operator =(const PIDeque<uchar> & d) {resize(d.size()); memcpy(data(), d.data(), d.size());}
|
||||||
|
|
||||||
PIByteArray & operator =(const PIByteArray & o) {if (this == &o) return *this; clear(); append(o); return *this;}
|
PIByteArray & operator =(const PIByteArray & o) {if (this == &o) return *this; clear(); append(o); return *this;}
|
||||||
|
|
||||||
@@ -1131,22 +170,13 @@ public:
|
|||||||
static PIByteArray fromBase64(const PIString & base64);
|
static PIByteArray fromBase64(const PIString & base64);
|
||||||
|
|
||||||
|
|
||||||
bool binaryStreamAppendImp(const void * d_, size_t s) {
|
class StreamRef {
|
||||||
append(d_, s);
|
public:
|
||||||
return true;
|
StreamRef(PIByteArray & s): ba(s) {}
|
||||||
}
|
operator PIByteArray&() {return ba;}
|
||||||
bool binaryStreamTakeImp(void * d_, size_t s) {
|
private:
|
||||||
size_t rs = size();
|
PIByteArray & ba;
|
||||||
if (rs > s) rs = s;
|
};
|
||||||
memcpy(d_, data(), rs);
|
|
||||||
remove(0, rs);
|
|
||||||
return rs == s;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t binaryStreamSizeImp() const {return size();}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PIDeque<uchar> d;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1205,14 +235,443 @@ inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba);
|
|||||||
PIP_EXPORT PICout operator <<(PICout s, const PIByteArray & ba);
|
PIP_EXPORT PICout operator <<(PICout s, const PIByteArray & ba);
|
||||||
|
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIByteArray) {
|
|
||||||
s.binaryStreamAppend((int)v.size_s());
|
|
||||||
s.binaryStreamAppend(v.data(), v.size());
|
// store operators for basic types
|
||||||
|
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator
|
||||||
|
//! \~russian Оператор сохранения
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const bool v) {s.push_back(v); return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator
|
||||||
|
//! \~russian Оператор сохранения
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const char v) {s.push_back(v); return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator
|
||||||
|
//! \~russian Оператор сохранения
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const uchar v) {s.push_back(v); return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator for any trivial copyable type
|
||||||
|
//! \~russian Оператор сохранения для тривиальных типов
|
||||||
|
template<typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||||
|
inline PIByteArray::StreamRef operator <<(PIByteArray & s, const T & v) {
|
||||||
|
int os = s.size_s();
|
||||||
|
s.enlarge(sizeof(v));
|
||||||
|
memcpy(s.data(os), &v, sizeof(v));
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
BINARY_STREAM_READ(PIByteArray) {
|
|
||||||
v.resize(s.binaryStreamTakeInt());
|
//! \relatesalso PIByteArray
|
||||||
s.binaryStreamTake(v.data(), v.size());
|
//! \~english Store operator, see \ref PIByteArray_sec1 for details
|
||||||
|
//! \~russian Оператор сохранения, подробнее в \ref PIByteArray_sec1
|
||||||
|
PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v);
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator
|
||||||
|
//! \~russian Оператор сохранения
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v) {
|
||||||
|
int os = s.size_s();
|
||||||
|
if (v.s > 0) {
|
||||||
|
s.enlarge(v.s);
|
||||||
|
memcpy(s.data(os), v.d, v.s);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator for PIVector of any trivial copyable type
|
||||||
|
//! \~russian Оператор сохранения для PIVector тривиальных типов
|
||||||
|
template<typename T,
|
||||||
|
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||||
|
typename std::enable_if< std::is_same<decltype(std::declval<PIByteArray&>() << std::declval<const T &>()), PIByteArray::StreamRef>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & v) {
|
||||||
|
s << int(v.size_s());
|
||||||
|
int os = s.size_s();
|
||||||
|
if (v.size_s() > 0) {
|
||||||
|
s.enlarge(v.size_s()*sizeof(T));
|
||||||
|
memcpy(s.data(os), v.data(), v.size_s()*sizeof(T));
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename T,
|
||||||
|
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||||
|
typename std::enable_if<!std::is_same<decltype(std::declval<PIByteArray&>() << std::declval<const T &>()), PIByteArray::StreamRef>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & v) {
|
||||||
|
s << int(v.size_s());
|
||||||
|
for (uint i = 0; i < v.size(); ++i) s << v[i];
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator for PIDeque of any trivial copyable type
|
||||||
|
//! \~russian Оператор сохранения для PIDeque тривиальных типов
|
||||||
|
template<typename T,
|
||||||
|
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||||
|
typename std::enable_if< std::is_same<decltype(std::declval<PIByteArray&>() << std::declval<const T &>()), PIByteArray::StreamRef>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIDeque<T> & v) {
|
||||||
|
s << int(v.size_s());
|
||||||
|
int os = s.size_s();
|
||||||
|
if (v.size_s() > 0) {
|
||||||
|
s.enlarge(v.size_s()*sizeof(T));
|
||||||
|
memcpy(s.data(os), v.data(), v.size_s()*sizeof(T));
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename T,
|
||||||
|
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||||
|
typename std::enable_if<!std::is_same<decltype(std::declval<PIByteArray&>() << std::declval<const T &>()), PIByteArray::StreamRef>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIDeque<T> & v) {
|
||||||
|
s << int(v.size_s());
|
||||||
|
for (uint i = 0; i < v.size(); ++i) s << v[i];
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator for PIVector2D of any trivial copyable type
|
||||||
|
//! \~russian Оператор сохранения для PIVector2D тривиальных типов
|
||||||
|
template<typename T,
|
||||||
|
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||||
|
typename std::enable_if< std::is_same<decltype(std::declval<PIByteArray&>() << std::declval<const T &>()), PIByteArray::StreamRef>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D<T> & v) {
|
||||||
|
s << int(v.rows()) << int(v.cols());
|
||||||
|
int os = s.size_s();
|
||||||
|
if (v.size_s() > 0) {
|
||||||
|
s.enlarge(v.size_s()*sizeof(T));
|
||||||
|
memcpy(s.data(os), v.data(), v.size_s()*sizeof(T));
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename T,
|
||||||
|
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||||
|
typename std::enable_if<!std::is_same<decltype(std::declval<PIByteArray&>() << std::declval<const T &>()), PIByteArray::StreamRef>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D<T> & v) {
|
||||||
|
s << int(v.rows()) << int(v.cols()) << v.toPlainVector();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator
|
||||||
|
//! \~russian Оператор сохранения
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIPair
|
||||||
|
//! \~english Store operator
|
||||||
|
//! \~russian Оператор сохранения
|
||||||
|
template<typename Type0, typename Type1>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIPair<Type0, Type1> & v) {s << v.first << v.second; return s;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// restore operators for basic types
|
||||||
|
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator
|
||||||
|
//! \~russian Оператор извлечения
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, bool & v) {assert(s.size() >= 1u); v = s.take_front(); return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator
|
||||||
|
//! \~russian Оператор извлечения
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, char & v) {assert(s.size() >= 1u); v = s.take_front(); return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator
|
||||||
|
//! \~russian Оператор извлечения
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= 1u); v = s.take_front(); return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator for any trivial copyable type
|
||||||
|
//! \~russian Оператор извлечения для тривиальных типов
|
||||||
|
template<typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||||
|
inline PIByteArray::StreamRef operator >>(PIByteArray & s, T & v) {
|
||||||
|
if (s.size() < sizeof(v)) {
|
||||||
|
printf("error with %s\n", __PIP_TYPENAME__(T));
|
||||||
|
assert(s.size() >= sizeof(v));
|
||||||
|
}
|
||||||
|
memcpy((void*)(&v), s.data(), sizeof(v));
|
||||||
|
s.remove(0, sizeof(v));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator, see \ref PIByteArray_sec1 for details
|
||||||
|
//! \~russian Оператор извлечения, подробнее в \ref PIByteArray_sec1
|
||||||
|
PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIByteArray & v);
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator
|
||||||
|
//! \~russian Оператор извлечения
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) {
|
||||||
|
if (s.size_s() < v.s) {
|
||||||
|
printf("error with RawData %d < %d\n", (int)s.size_s(), v.s);
|
||||||
|
assert(s.size_s() >= v.s);
|
||||||
|
}
|
||||||
|
if (v.s > 0) {
|
||||||
|
memcpy((void*)(v.d), s.data(), v.s);
|
||||||
|
s.remove(0, v.s);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator for PIVector of any trivial copyable type
|
||||||
|
//! \~russian Оператор извлечения для PIVector тривиальных типов
|
||||||
|
template<typename T,
|
||||||
|
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||||
|
typename std::enable_if< std::is_same<decltype(std::declval<PIByteArray&>() << std::declval<const T &>()), PIByteArray::StreamRef>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIVector<T> & v) {
|
||||||
|
if (s.size_s() < 4) {
|
||||||
|
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
|
||||||
|
assert(s.size_s() >= 4);
|
||||||
|
}
|
||||||
|
int sz; s >> sz;
|
||||||
|
v._resizeRaw(sz);
|
||||||
|
if (sz > 0) {
|
||||||
|
memcpy(v.data(), s.data(), sz*sizeof(T));
|
||||||
|
s.remove(0, sz*sizeof(T));
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename T,
|
||||||
|
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||||
|
typename std::enable_if<!std::is_same<decltype(std::declval<PIByteArray&>() << std::declval<const T &>()), PIByteArray::StreamRef>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIVector<T> & v) {
|
||||||
|
if (s.size_s() < 4) {
|
||||||
|
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
|
||||||
|
assert(s.size_s() >= 4);
|
||||||
|
}
|
||||||
|
int sz; s >> sz;
|
||||||
|
v.resize(sz);
|
||||||
|
for (int i = 0; i < sz; ++i) s >> v[i];
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator for PIDeque of any trivial copyable type
|
||||||
|
//! \~russian Оператор извлечения для PIDeque тривиальных типов
|
||||||
|
template<typename T,
|
||||||
|
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||||
|
typename std::enable_if< std::is_same<decltype(std::declval<PIByteArray&>() << std::declval<const T &>()), PIByteArray::StreamRef>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIDeque<T> & v) {
|
||||||
|
if (s.size_s() < 4) {
|
||||||
|
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
|
||||||
|
assert(s.size_s() >= 4);
|
||||||
|
}
|
||||||
|
int sz; s >> sz;
|
||||||
|
v._resizeRaw(sz);
|
||||||
|
if (sz > 0) {
|
||||||
|
memcpy(v.data(), s.data(), sz*sizeof(T));
|
||||||
|
s.remove(0, sz*sizeof(T));
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename T,
|
||||||
|
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||||
|
typename std::enable_if<!std::is_same<decltype(std::declval<PIByteArray&>() << std::declval<const T &>()), PIByteArray::StreamRef>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIDeque<T> & v) {
|
||||||
|
if (s.size_s() < 4) {
|
||||||
|
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
|
||||||
|
assert(s.size_s() >= 4);
|
||||||
|
}
|
||||||
|
int sz; s >> sz;
|
||||||
|
v.resize(sz);
|
||||||
|
for (int i = 0; i < sz; ++i) s >> v[i];
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator for PIVector2D of any trivial copyable type
|
||||||
|
//! \~russian Оператор извлечения для PIVector2D тривиальных типов
|
||||||
|
template<typename T,
|
||||||
|
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||||
|
typename std::enable_if< std::is_same<decltype(std::declval<PIByteArray&>() << std::declval<const T &>()), PIByteArray::StreamRef>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIVector2D<T> & v) {
|
||||||
|
if (s.size_s() < 8) {
|
||||||
|
printf("error with PIVecto2Dr<%s>\n", __PIP_TYPENAME__(T));
|
||||||
|
assert(s.size_s() >= 8);
|
||||||
|
}
|
||||||
|
int r, c; s >> r >> c;
|
||||||
|
v._resizeRaw(r, c);
|
||||||
|
int sz = r*c;
|
||||||
|
if (sz > 0) {
|
||||||
|
memcpy(v.data(), s.data(), sz*sizeof(T));
|
||||||
|
s.remove(0, sz*sizeof(T));
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename T,
|
||||||
|
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
|
||||||
|
typename std::enable_if<!std::is_same<decltype(std::declval<PIByteArray&>() << std::declval<const T &>()), PIByteArray::StreamRef>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIVector2D<T> & v) {
|
||||||
|
if (s.size_s() < 8) {
|
||||||
|
printf("error with PIVecto2Dr<%s>\n", __PIP_TYPENAME__(T));
|
||||||
|
assert(s.size_s() >= 8);
|
||||||
|
}
|
||||||
|
int r,c;
|
||||||
|
PIVector<T> tmp;
|
||||||
|
s >> r >> c >> tmp;
|
||||||
|
v = PIVector2D<T>(r, c, tmp);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator
|
||||||
|
//! \~russian Оператор извлечения
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIBitArray & v) {assert(s.size_s() >= 8); s >> v.size_ >> v.data_; return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIPair
|
||||||
|
//! \~english Restore operator
|
||||||
|
//! \~russian Оператор извлечения
|
||||||
|
template<typename Type0, typename Type1>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIPair<Type0, Type1> & v) {s >> v.first >> v.second; return s;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// store operators for complex types
|
||||||
|
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator for PIVector of any compound type
|
||||||
|
//! \~russian Оператор сохранения для PIVector сложных типов
|
||||||
|
template<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & v) {
|
||||||
|
s << int(v.size_s());
|
||||||
|
for (uint i = 0; i < v.size(); ++i) s << v[i];
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator for PIDeque of any compound type
|
||||||
|
//! \~russian Оператор сохранения для PIDeque сложных типов
|
||||||
|
template<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIDeque<T> & v) {
|
||||||
|
s << int(v.size_s());
|
||||||
|
for (uint i = 0; i < v.size(); ++i) s << v[i];
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator for PIVector2D of any compound type
|
||||||
|
//! \~russian Оператор сохранения для PIVector2D сложных типов
|
||||||
|
template<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D<T> & v) {
|
||||||
|
s << int(v.rows()) << int(v.cols()) << v.toPlainVector();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// restore operators for complex types
|
||||||
|
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator for PIVector of any compound type
|
||||||
|
//! \~russian Оператор извлечения для PIVector сложных типов
|
||||||
|
template<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIVector<T> & v) {
|
||||||
|
if (s.size_s() < 4) {
|
||||||
|
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
|
||||||
|
assert(s.size_s() >= 4);
|
||||||
|
}
|
||||||
|
int sz; s >> sz;
|
||||||
|
v.resize(sz);
|
||||||
|
for (int i = 0; i < sz; ++i) s >> v[i];
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator for PIDeque of any compound type
|
||||||
|
//! \~russian Оператор извлечения для PIDeque сложных типов
|
||||||
|
template<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIDeque<T> & v) {
|
||||||
|
if (s.size_s() < 4) {
|
||||||
|
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
|
||||||
|
assert(s.size_s() >= 4);
|
||||||
|
}
|
||||||
|
int sz; s >> sz;
|
||||||
|
v.resize(sz);
|
||||||
|
for (int i = 0; i < sz; ++i) s >> v[i];
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator for PIVector2D of any compound type
|
||||||
|
//! \~russian Оператор извлечения для PIVector2D сложных типов
|
||||||
|
template<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIVector2D<T> & v) {
|
||||||
|
if (s.size_s() < 8) {
|
||||||
|
printf("error with PIVecto2Dr<%s>\n", __PIP_TYPENAME__(T));
|
||||||
|
assert(s.size_s() >= 8);
|
||||||
|
}
|
||||||
|
int r,c;
|
||||||
|
PIVector<T> tmp;
|
||||||
|
s >> r >> c >> tmp;
|
||||||
|
v = PIVector2D<T>(r, c, tmp);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// other types
|
||||||
|
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator
|
||||||
|
//! \~russian Оператор сохранения
|
||||||
|
template <typename Key, typename T>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIMap<Key, T> & v) {
|
||||||
|
// s << int(v.pim_index.size_s());
|
||||||
|
// for (uint i = 0; i < v.size(); ++i)
|
||||||
|
// s << int(v.pim_index[i].index) << v.pim_index[i].key;
|
||||||
|
s << v.pim_content;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator
|
||||||
|
//! \~russian Оператор извлечения
|
||||||
|
template <typename Key, typename T>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIMap<Key, T> & v) {
|
||||||
|
if (s.size_s() < 4) {
|
||||||
|
printf("error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
|
||||||
|
assert(s.size_s() >= 4);
|
||||||
|
}
|
||||||
|
// int sz; s >> sz; v.pim_index.resize(sz);
|
||||||
|
// int ind = 0;
|
||||||
|
// for (int i = 0; i < sz; ++i) {
|
||||||
|
// s >> ind >> v.pim_index[i].key;
|
||||||
|
// v.pim_index[i].index = ind;
|
||||||
|
// }
|
||||||
|
s >> v.pim_content;
|
||||||
|
// if (v.pim_content.size_s() != v.pim_index.size_s()) {
|
||||||
|
// piCout << "Warning: loaded invalid PIMap, clear";
|
||||||
|
// v.clear();
|
||||||
|
// }
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const T & ) {
|
||||||
|
static_assert(std::is_trivially_copyable<T>::value, "[PIByteArray] Error: using undeclared operator << for complex type!");
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, T & ) {
|
||||||
|
static_assert(std::is_trivially_copyable<T>::value, "[PIByteArray] Error: using undeclared operator >> for complex type!");
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ int PIChunkStream::read() {
|
|||||||
last_id = readVInt(*data_);
|
last_id = readVInt(*data_);
|
||||||
last_data.resize(readVInt(*data_));
|
last_data.resize(readVInt(*data_));
|
||||||
//piCout << last_id << last_data.size();
|
//piCout << last_id << last_data.size();
|
||||||
(*data_) >> PIMemoryBlock(last_data.data(), last_data.size_s());
|
(*data_) >> PIByteArray::RawData(last_data.data(), last_data.size_s());
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ public:
|
|||||||
//! \~english Returns value of last readed chunk
|
//! \~english Returns value of last readed chunk
|
||||||
//! \~russian Возвращает значение последнего прочитанного чанка
|
//! \~russian Возвращает значение последнего прочитанного чанка
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T getData() const {T ret{}; PIByteArray s(last_data); s >> ret; return ret;}
|
T getData() const {T ret; PIByteArray s(last_data); s >> ret; return ret;}
|
||||||
|
|
||||||
//! \~english Place value of last readed chunk into \"v\"
|
//! \~english Place value of last readed chunk into \"v\"
|
||||||
//! \~russian Записывает значение последнего прочитанного чанка в \"v\"
|
//! \~russian Записывает значение последнего прочитанного чанка в \"v\"
|
||||||
|
|||||||
@@ -42,13 +42,6 @@
|
|||||||
//!
|
//!
|
||||||
|
|
||||||
|
|
||||||
bool PIConstChars::contains(char c) const {
|
|
||||||
for (int i = 0; i < (int)len; ++i)
|
|
||||||
if (str[i] == c) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool PIConstChars::startsWith(const PIConstChars & str) const {
|
bool PIConstChars::startsWith(const PIConstChars & str) const {
|
||||||
if (size() < str.size()) return false;
|
if (size() < str.size()) return false;
|
||||||
return str == left(str.size());
|
return str == left(str.size());
|
||||||
|
|||||||
@@ -86,10 +86,6 @@ public:
|
|||||||
//! \~russian Возвращает \c true если строка непустая, т.е. длина > 0.
|
//! \~russian Возвращает \c true если строка непустая, т.е. длина > 0.
|
||||||
inline bool isNotEmpty() const {return len > 0;}
|
inline bool isNotEmpty() const {return len > 0;}
|
||||||
|
|
||||||
//! \~english Returns \c true if string contains character "c".
|
|
||||||
//! \~russian Возвращает \c true если строка содержит символ "c".
|
|
||||||
bool contains(char c) const;
|
|
||||||
|
|
||||||
//! \~english Returns characters length of string.
|
//! \~english Returns characters length of string.
|
||||||
//! \~russian Возвращает длину строки в символах.
|
//! \~russian Возвращает длину строки в символах.
|
||||||
inline size_t length() const {return len;}
|
inline size_t length() const {return len;}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ class NotifierObject: public PIObject {
|
|||||||
PIOBJECT(NotifierObject)
|
PIOBJECT(NotifierObject)
|
||||||
public:
|
public:
|
||||||
NotifierObject() {}
|
NotifierObject() {}
|
||||||
EVENT2(finished, int, id, PIString*, buffer);
|
EVENT2(finished, int, id, PIString*, buffer)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -320,10 +320,10 @@ PICout PICout::operator <<(const PIFlags<PICoutManipulators::PICoutFormat> & v)
|
|||||||
|
|
||||||
#define PICOUTTOTARGET(v) { \
|
#define PICOUTTOTARGET(v) { \
|
||||||
if (buffer_) {\
|
if (buffer_) {\
|
||||||
(*buffer_) += (v);\
|
(*buffer_) << (v);\
|
||||||
} else {\
|
} else {\
|
||||||
if (PICout::isOutputDeviceActive(PICout::StdOut)) std::cout << (v);\
|
if (PICout::isOutputDeviceActive(PICout::StdOut)) std::cout << (v);\
|
||||||
if (PICout::isOutputDeviceActive(PICout::Buffer)) PICout::__string__() += (v);\
|
if (PICout::isOutputDeviceActive(PICout::Buffer)) PICout::__string__() << (v);\
|
||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,52 +386,52 @@ PICout PICout::operator <<(const PICoutSpecialChar v) {
|
|||||||
switch (v) {
|
switch (v) {
|
||||||
case Null:
|
case Null:
|
||||||
if (buffer_) {
|
if (buffer_) {
|
||||||
(*buffer_) += PIChar();
|
(*buffer_) << PIChar();
|
||||||
} else {
|
} else {
|
||||||
if (isOutputDeviceActive(StdOut)) std::cout << char(0);
|
if (isOutputDeviceActive(StdOut)) std::cout << char(0);
|
||||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIChar();
|
if (isOutputDeviceActive(Buffer)) PICout::__string__() << PIChar();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NewLine:
|
case NewLine:
|
||||||
if (buffer_) {
|
if (buffer_) {
|
||||||
(*buffer_) += "\n";
|
(*buffer_) << "\n";
|
||||||
} else {
|
} else {
|
||||||
if (isOutputDeviceActive(StdOut)) std::cout << '\n';
|
if (isOutputDeviceActive(StdOut)) std::cout << '\n';
|
||||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\n";
|
if (isOutputDeviceActive(Buffer)) PICout::__string__() << "\n";
|
||||||
}
|
}
|
||||||
fo_ = true;
|
fo_ = true;
|
||||||
break;
|
break;
|
||||||
case Tab:
|
case Tab:
|
||||||
if (buffer_) {
|
if (buffer_) {
|
||||||
(*buffer_) += "\t";
|
(*buffer_) << "\t";
|
||||||
} else {
|
} else {
|
||||||
if (isOutputDeviceActive(StdOut)) std::cout << '\t';
|
if (isOutputDeviceActive(StdOut)) std::cout << '\t';
|
||||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\t";
|
if (isOutputDeviceActive(Buffer)) PICout::__string__() << "\t";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Esc:
|
case Esc:
|
||||||
#ifdef CC_VC
|
#ifdef CC_VC
|
||||||
if (buffer_) {
|
if (buffer_) {
|
||||||
(*buffer_) += PIChar(27);
|
(*buffer_) << PIChar(27);
|
||||||
} else {
|
} else {
|
||||||
if (isOutputDeviceActive(StdOut)) std::cout << char(27);
|
if (isOutputDeviceActive(StdOut)) std::cout << char(27);
|
||||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIChar(27);
|
if (isOutputDeviceActive(Buffer)) PICout::__string__() << PIChar(27);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (buffer_) {
|
if (buffer_) {
|
||||||
(*buffer_) += "\e";
|
(*buffer_) << "\e";
|
||||||
} else {
|
} else {
|
||||||
if (isOutputDeviceActive(StdOut)) std::cout << '\e';
|
if (isOutputDeviceActive(StdOut)) std::cout << '\e';
|
||||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\e";
|
if (isOutputDeviceActive(Buffer)) PICout::__string__() << "\e";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case Quote:
|
case Quote:
|
||||||
if (buffer_) {
|
if (buffer_) {
|
||||||
(*buffer_) += "\"";
|
(*buffer_) << "\"";
|
||||||
} else {
|
} else {
|
||||||
if (isOutputDeviceActive(StdOut)) std::cout << '"';
|
if (isOutputDeviceActive(StdOut)) std::cout << '"';
|
||||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\"";
|
if (isOutputDeviceActive(Buffer)) PICout::__string__() << "\"";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
@@ -469,10 +469,10 @@ PICout & PICout::space() {
|
|||||||
if (!act_) return *this;
|
if (!act_) return *this;
|
||||||
if (!fo_ && co_[AddSpaces]) {
|
if (!fo_ && co_[AddSpaces]) {
|
||||||
if (buffer_) {
|
if (buffer_) {
|
||||||
(*buffer_) += " ";
|
(*buffer_) << " ";
|
||||||
} else {
|
} else {
|
||||||
if (isOutputDeviceActive(StdOut)) std::cout << ' ';
|
if (isOutputDeviceActive(StdOut)) std::cout << ' ';
|
||||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += " ";
|
if (isOutputDeviceActive(Buffer)) PICout::__string__() << " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fo_ = false;
|
fo_ = false;
|
||||||
@@ -489,10 +489,10 @@ PICout & PICout::quote() {
|
|||||||
if (!act_) return *this;
|
if (!act_) return *this;
|
||||||
if (co_[AddQuotes]) {
|
if (co_[AddQuotes]) {
|
||||||
if (buffer_) {
|
if (buffer_) {
|
||||||
(*buffer_) += "\"";
|
(*buffer_) << "\"";
|
||||||
} else {
|
} else {
|
||||||
if (isOutputDeviceActive(StdOut)) std::cout << '"';
|
if (isOutputDeviceActive(StdOut)) std::cout << '"';
|
||||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\"";
|
if (isOutputDeviceActive(Buffer)) PICout::__string__() << "\"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fo_ = false;
|
fo_ = false;
|
||||||
@@ -509,10 +509,10 @@ PICout & PICout::newLine() {
|
|||||||
if (!act_) return *this;
|
if (!act_) return *this;
|
||||||
if (co_[AddNewLine]) {
|
if (co_[AddNewLine]) {
|
||||||
if (buffer_) {
|
if (buffer_) {
|
||||||
(*buffer_) += "\n";
|
(*buffer_) << "\n";
|
||||||
} else {
|
} else {
|
||||||
if (isOutputDeviceActive(StdOut)) std::cout << std::endl;
|
if (isOutputDeviceActive(StdOut)) std::cout << std::endl;
|
||||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\n";
|
if (isOutputDeviceActive(Buffer)) PICout::__string__() << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fo_ = false;
|
fo_ = false;
|
||||||
|
|||||||
@@ -311,6 +311,16 @@ inline bool operator <=(const PIDateTime & t0, const PIDateTime & t1) {return !(
|
|||||||
//! \~russian Оператор сравнения
|
//! \~russian Оператор сравнения
|
||||||
inline bool operator >=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 < t1);}
|
inline bool operator >=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 < t1);}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Store operator
|
||||||
|
//! \~russian Оператор сохранения
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIDateTime & v) {s << v.year << v.month << v.day << v.hours << v.minutes << v.seconds << v.milliseconds; return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator
|
||||||
|
//! \~russian Оператор извлечения
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIDateTime & v) {s >> v.year >> v.month >> v.day >> v.hours >> v.minutes >> v.seconds >> v.milliseconds; return s;}
|
||||||
|
|
||||||
//! \relatesalso PICout
|
//! \relatesalso PICout
|
||||||
//! \~english \brief Output operator to PICout
|
//! \~english \brief Output operator to PICout
|
||||||
//! \~russian \brief Оператор вывода в PICout
|
//! \~russian \brief Оператор вывода в PICout
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ class PIMutexLocker;
|
|||||||
class PIObject;
|
class PIObject;
|
||||||
class PIString;
|
class PIString;
|
||||||
class PIByteArray;
|
class PIByteArray;
|
||||||
template <typename P> class PIBinaryStream;
|
|
||||||
#ifndef MICRO_PIP
|
#ifndef MICRO_PIP
|
||||||
class PIInit;
|
class PIInit;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
/*! \file pimemoryblock.h
|
|
||||||
* \ingroup Core
|
|
||||||
* \~\brief
|
|
||||||
* \~english Base types and functions
|
|
||||||
* \~russian Базовые типы и методы
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
PIP - Platform Independent Primitives
|
|
||||||
Base types and functions
|
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PIMEMORYBLOCK_H
|
|
||||||
#define PIMEMORYBLOCK_H
|
|
||||||
|
|
||||||
|
|
||||||
//! \ingroup Core
|
|
||||||
//! \include pimemoryblock.h
|
|
||||||
//! \brief
|
|
||||||
//! \~english Help struct to store/restore custom blocks of data to/from PIBinaryStream
|
|
||||||
//! \~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(const void * data_, const int size_) {d = const_cast<void * >(data_); s = size_;}
|
|
||||||
|
|
||||||
PIMemoryBlock(const PIMemoryBlock & o) {d = o.d; s = o.s;}
|
|
||||||
|
|
||||||
PIMemoryBlock & operator =(const PIMemoryBlock & o) {d = o.d; s = o.s; return *this;}
|
|
||||||
|
|
||||||
void * data() {return d;}
|
|
||||||
const void * data() const {return d;}
|
|
||||||
int size() const {return s;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void * d;
|
|
||||||
int s;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
PIMemoryBlock createMemoryBlock(const T * ptr) {return PIMemoryBlock(ptr, sizeof(T));}
|
|
||||||
|
|
||||||
#endif // PIMEMORYBLOCK_H
|
|
||||||
@@ -23,7 +23,6 @@
|
|||||||
#ifndef MICRO_PIP
|
#ifndef MICRO_PIP
|
||||||
# include "pisysteminfo.h"
|
# include "pisysteminfo.h"
|
||||||
# include "pifile.h"
|
# include "pifile.h"
|
||||||
# include "piiostream.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -754,8 +753,7 @@ bool dumpApplicationToFile(const PIString & path, bool with_objects) {
|
|||||||
bool ba = PICout::isBufferActive();
|
bool ba = PICout::isBufferActive();
|
||||||
PICout::setBufferActive(true, true);
|
PICout::setBufferActive(true, true);
|
||||||
dumpApplication(with_objects);
|
dumpApplication(with_objects);
|
||||||
PIIOTextStream ts(&f);
|
f << PICout::buffer();
|
||||||
ts << PICout::buffer();
|
|
||||||
f.close();
|
f.close();
|
||||||
PICout::setBufferActive(ba, true);
|
PICout::setBufferActive(ba, true);
|
||||||
PIFile::rename(path + "_tmp", path);
|
PIFile::rename(path + "_tmp", path);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class PIP_EXPORT PIObject {
|
|||||||
typedef PIObject __PIObject__;
|
typedef PIObject __PIObject__;
|
||||||
typedef void __Parent__;
|
typedef void __Parent__;
|
||||||
public:
|
public:
|
||||||
NO_COPY_CLASS(PIObject);
|
NO_COPY_CLASS(PIObject)
|
||||||
|
|
||||||
//! \~english Contructs %PIObject with name "name"
|
//! \~english Contructs %PIObject with name "name"
|
||||||
//! \~russian Создает %PIObject с именем "name"
|
//! \~russian Создает %PIObject с именем "name"
|
||||||
@@ -518,7 +518,7 @@ protected:
|
|||||||
//! \~russian Виртуальная функция, вызывается после изменения любого свойства.
|
//! \~russian Виртуальная функция, вызывается после изменения любого свойства.
|
||||||
virtual void propertyChanged(const char * name) {}
|
virtual void propertyChanged(const char * name) {}
|
||||||
|
|
||||||
EVENT1(deleted, PIObject *, o);
|
EVENT1(deleted, PIObject *, o)
|
||||||
|
|
||||||
//! \events
|
//! \events
|
||||||
//! \{
|
//! \{
|
||||||
|
|||||||
@@ -271,11 +271,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIPropertyStorage::Property) {s << v.name << v.value << v.comment << v.flags; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIPropertyStorage::Property & v) {s << v.name << v.value << v.comment << v.flags; return s;}
|
||||||
BINARY_STREAM_READ (PIPropertyStorage::Property) {s >> v.name >> v.value >> v.comment >> v.flags; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIPropertyStorage::Property & v) {s >> v.name >> v.value >> v.comment >> v.flags; return s;}
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIPropertyStorage) {s << v.properties(); return s;}
|
|
||||||
BINARY_STREAM_READ (PIPropertyStorage) {s >> v.properties(); return s;}
|
|
||||||
|
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIPropertyStorage & v) {s << v.properties(); return s;}
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIPropertyStorage & v) {s >> v.properties(); return s;}
|
||||||
|
|
||||||
#endif // PIPROPERTYSTORAGE_H
|
#endif // PIPROPERTYSTORAGE_H
|
||||||
|
|||||||
@@ -215,13 +215,6 @@ void PIString::appendFromChars(const char * c, int s, const char * codepage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIString PIString::fromConsole(const PIByteArray & ba) {
|
|
||||||
PIString ret;
|
|
||||||
if (ba.isNotEmpty()) ret.appendFromChars((const char*)ba.data(), ba.size(), __sysoemname__);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIString PIString::fromConsole(const char * s) {
|
PIString PIString::fromConsole(const char * s) {
|
||||||
PIString ret;
|
PIString ret;
|
||||||
if (!s) return ret;
|
if (!s) return ret;
|
||||||
@@ -231,13 +224,6 @@ PIString PIString::fromConsole(const char * s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIString PIString::fromSystem(const PIByteArray & ba) {
|
|
||||||
PIString ret;
|
|
||||||
if (ba.isNotEmpty()) ret.appendFromChars((const char*)ba.data(), ba.size(), __syslocname__);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIString PIString::fromSystem(const char * s) {
|
PIString PIString::fromSystem(const char * s) {
|
||||||
PIString ret;
|
PIString ret;
|
||||||
if (!s) return ret;
|
if (!s) return ret;
|
||||||
@@ -375,13 +361,6 @@ uint PIString::hash() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIByteArray PIString::toSystem() const {
|
|
||||||
if (isEmpty()) return PIByteArray();
|
|
||||||
buildData(__syslocname__);
|
|
||||||
return PIByteArray(data_, strlen(data_));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIByteArray PIString::toUTF8() const {
|
PIByteArray PIString::toUTF8() const {
|
||||||
if (isEmpty()) return PIByteArray();
|
if (isEmpty()) return PIByteArray();
|
||||||
buildData(__utf8name__);
|
buildData(__utf8name__);
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ class PIStringList;
|
|||||||
//! \~russian Класс строки.
|
//! \~russian Класс строки.
|
||||||
class PIP_EXPORT PIString
|
class PIP_EXPORT PIString
|
||||||
{
|
{
|
||||||
BINARY_STREAM_FRIEND(PIString);
|
friend PIByteArray & operator >>(PIByteArray & s, PIString & v);
|
||||||
|
friend PIByteArray & operator <<(PIByteArray & s, const PIString & v);
|
||||||
public:
|
public:
|
||||||
typedef PIDeque<PIChar>::iterator iterator;
|
typedef PIDeque<PIChar>::iterator iterator;
|
||||||
typedef PIDeque<PIChar>::const_iterator const_iterator;
|
typedef PIDeque<PIChar>::const_iterator const_iterator;
|
||||||
@@ -241,6 +242,94 @@ public:
|
|||||||
//! \~russian Оператор сравнения.
|
//! \~russian Оператор сравнения.
|
||||||
bool operator >=(const char * str) const {return *this >= PIString(str);}
|
bool operator >=(const char * str) const {return *this >= PIString(str);}
|
||||||
|
|
||||||
|
//! \~english Append string "str" at the end of string.
|
||||||
|
//! \~russian Добавляет в конец строку "str".
|
||||||
|
//! \~\details
|
||||||
|
//! \~\code
|
||||||
|
//! PIString s("this"), s1(" is"), s2(" string");
|
||||||
|
//! s << s1 << s2; // s = "this is string"
|
||||||
|
//! \endcode
|
||||||
|
PIString & operator <<(const PIString & str) {*this += str; return *this;}
|
||||||
|
|
||||||
|
//! \~english Append character "c" at the end of string.
|
||||||
|
//! \~russian Добавляет в конец символ "c".
|
||||||
|
//! \~\details
|
||||||
|
//! \~\code
|
||||||
|
//! PIString s("stri");
|
||||||
|
//! s << PIChar('n') << PIChar('g'); // s = "string"
|
||||||
|
//! \endcode
|
||||||
|
PIString & operator <<(const PIChar c) {d.append(c); return *this;}
|
||||||
|
|
||||||
|
//! \~english Append character `c` at the end of string.
|
||||||
|
//! \~russian Добавляет в конец символ `c`.
|
||||||
|
//! \~\details
|
||||||
|
//! \~\code
|
||||||
|
//! PIString s("stri");
|
||||||
|
//! s << 'n' << 'g'; // s = "string"
|
||||||
|
//! \endcode
|
||||||
|
PIString & operator <<(const char c) {d.append(PIChar(c)); return *this;}
|
||||||
|
|
||||||
|
//! \~english Append С-string "str" at the end of string.
|
||||||
|
//! \~russian Добавляет в конец C-строку "str".
|
||||||
|
//! \~\details
|
||||||
|
//! \~\code
|
||||||
|
//! PIString s("this");
|
||||||
|
//! s << " is" << " string"; // s = "this is string"
|
||||||
|
//! \endcode
|
||||||
|
PIString & operator <<(const char * str) {*this += str; return *this;}
|
||||||
|
|
||||||
|
//! \~english Append \c wchar_t C-string "str" at the end of string.
|
||||||
|
//! \~russian Добавляет в конец \c wchar_t C-строку "str".
|
||||||
|
//! \~\details
|
||||||
|
//! \~\code
|
||||||
|
//! PIString s;
|
||||||
|
//! s << L"№ -" << " number"; // s = "№ - number"
|
||||||
|
//! \endcode
|
||||||
|
PIString & operator <<(const wchar_t * str) {*this += str; return *this;}
|
||||||
|
|
||||||
|
PIString & operator <<(const PIConstChars & str) {*this += str; return *this;}
|
||||||
|
|
||||||
|
//! \~english Append string representation of "num" at the end of string.
|
||||||
|
//! \~russian Добавляет в конец строковое представление "num".
|
||||||
|
//! \~\details
|
||||||
|
//! \~\code
|
||||||
|
//! PIString s("ten - ");
|
||||||
|
//! s << 10; // s = "ten - 10"
|
||||||
|
//! \endcode
|
||||||
|
PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
PIString & operator <<(const uint & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
|
//! \~english Append string representation of "num" at the end of string.
|
||||||
|
//! \~russian Добавляет в конец строковое представление "num".
|
||||||
|
//! \~\details
|
||||||
|
//! \~\code
|
||||||
|
//! PIString s("ten - ");
|
||||||
|
//! s << 10; // s = "ten - 10"
|
||||||
|
//! \endcode
|
||||||
|
PIString & operator <<(const long & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
PIString & operator <<(const ulong & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
|
PIString & operator <<(const llong & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
PIString & operator <<(const ullong & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
|
//! \~english Append string representation of "num" at the end of string.
|
||||||
|
//! \~russian Добавляет в конец строковое представление "num".
|
||||||
|
//! \~\details
|
||||||
|
//! \~\code
|
||||||
|
//! PIString s("1/10 - ");
|
||||||
|
//! s << 0.1; // s = "1/10 - 0.1"
|
||||||
|
//! \endcode
|
||||||
|
PIString & operator <<(const float & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
|
//! \~english Append string representation of "num" at the end of string.
|
||||||
|
//! \~russian Добавляет в конец строковое представление "num".
|
||||||
|
//! \~\details
|
||||||
|
//! \~\code
|
||||||
|
//! PIString s("1/10 - ");
|
||||||
|
//! s << 0.1; // s = "1/10 - 0.1"
|
||||||
|
//! \endcode
|
||||||
|
PIString & operator <<(const double & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
//! \~english Iterator to the first element.
|
//! \~english Iterator to the first element.
|
||||||
//! \~russian Итератор на первый элемент.
|
//! \~russian Итератор на первый элемент.
|
||||||
//! \~\details
|
//! \~\details
|
||||||
@@ -820,10 +909,6 @@ public:
|
|||||||
//! \~russian Тоже самое, что \a toUTF8().
|
//! \~russian Тоже самое, что \a toUTF8().
|
||||||
PIByteArray toByteArray() const {return toUTF8();}
|
PIByteArray toByteArray() const {return toUTF8();}
|
||||||
|
|
||||||
//! \~english Returns \a PIByteArray contains \a data() of this string without terminating null-char.
|
|
||||||
//! \~russian Возвращает \a PIByteArray содержащий \a data() строки без завершающего нулевого байта.
|
|
||||||
PIByteArray toSystem() const;
|
|
||||||
|
|
||||||
//! \~english Returns \a PIByteArray contains \a dataUTF8() of this string without terminating null-char.
|
//! \~english Returns \a PIByteArray contains \a dataUTF8() of this string without terminating null-char.
|
||||||
//! \~russian Возвращает \a PIByteArray содержащий \a dataUTF8() строки без завершающего нулевого байта.
|
//! \~russian Возвращает \a PIByteArray содержащий \a dataUTF8() строки без завершающего нулевого байта.
|
||||||
PIByteArray toUTF8() const;
|
PIByteArray toUTF8() const;
|
||||||
@@ -1422,18 +1507,10 @@ public:
|
|||||||
//! \~english Returns "true" or "false"
|
//! \~english Returns "true" or "false"
|
||||||
//! \~russian Возвращает "true" или "false"
|
//! \~russian Возвращает "true" или "false"
|
||||||
static PIString fromBool(const bool value) {return PIString(value ? PIStringAscii("true") : PIStringAscii("false"));}
|
static PIString fromBool(const bool value) {return PIString(value ? PIStringAscii("true") : PIStringAscii("false"));}
|
||||||
|
|
||||||
//! \~english Returns string constructed from terminal codepage.
|
|
||||||
//! \~russian Возвращает строку созданную из кодировки консоли.
|
|
||||||
static PIString fromConsole(const PIByteArray & s);
|
|
||||||
|
|
||||||
//! \~english Returns string constructed from terminal codepage.
|
//! \~english Returns string constructed from terminal codepage.
|
||||||
//! \~russian Возвращает строку созданную из кодировки консоли.
|
//! \~russian Возвращает строку созданную из кодировки консоли.
|
||||||
static PIString fromConsole(const char * s);
|
static PIString fromConsole(const char * s);
|
||||||
|
|
||||||
//! \~english Returns string constructed from system codepage.
|
|
||||||
//! \~russian Возвращает строку созданную из кодировки системы.
|
|
||||||
static PIString fromSystem(const PIByteArray & s);
|
|
||||||
|
|
||||||
//! \~english Returns string constructed from system codepage.
|
//! \~english Returns string constructed from system codepage.
|
||||||
//! \~russian Возвращает строку созданную из кодировки системы.
|
//! \~russian Возвращает строку созданную из кодировки системы.
|
||||||
@@ -1506,12 +1583,12 @@ PIP_EXPORT PICout operator <<(PICout s, const PIString & v);
|
|||||||
//! \relatesalso PIByteArray
|
//! \relatesalso PIByteArray
|
||||||
//! \~english Store operator.
|
//! \~english Store operator.
|
||||||
//! \~russian Оператор сохранения.
|
//! \~russian Оператор сохранения.
|
||||||
BINARY_STREAM_WRITE(PIString) {s << v.d; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIString & v) {s << v.d; return s;}
|
||||||
|
|
||||||
//! \relatesalso PIByteArray
|
//! \relatesalso PIByteArray
|
||||||
//! \~english Restore operator.
|
//! \~english Restore operator.
|
||||||
//! \~russian Оператор извлечения.
|
//! \~russian Оператор извлечения.
|
||||||
BINARY_STREAM_READ(PIString) {s >> v.d; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIString & v) {v.d.clear(); s >> v.d; return s;}
|
||||||
|
|
||||||
|
|
||||||
//! \~english Returns concatenated string.
|
//! \~english Returns concatenated string.
|
||||||
|
|||||||
@@ -126,15 +126,15 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIStringList) {
|
//! \relatesalso PIByteArray
|
||||||
s << static_cast<const PIDeque<PIString> &>(v);
|
//! \~english Store operator
|
||||||
return s;
|
//! \~russian Оператор сохранения
|
||||||
}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIStringList & v) {s << int(v.size_s()); for (int i = 0; i < v.size_s(); ++i) s << v[i]; return s;}
|
||||||
BINARY_STREAM_READ(PIStringList) {
|
|
||||||
s >> static_cast<PIDeque<PIString> &>(v);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray
|
||||||
|
//! \~english Restore operator
|
||||||
|
//! \~russian Оператор извлечения
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIStringList & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||||
|
|
||||||
//! \relatesalso PICout
|
//! \relatesalso PICout
|
||||||
//! \~english Output operator to \a PICout
|
//! \~english Output operator to \a PICout
|
||||||
|
|||||||
@@ -1,341 +0,0 @@
|
|||||||
/*! \file pitextstream.h
|
|
||||||
* \ingroup Core
|
|
||||||
* \~\brief
|
|
||||||
* \~english Text serialization functionality over PIBinaryStream
|
|
||||||
* \~russian Функциональность текстовой сериализации поверх PIBinaryStream
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
PIP - Platform Independent Primitives
|
|
||||||
Text serialization functionality over PIBinaryStream
|
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PITEXTSTREAM_H
|
|
||||||
#define PITEXTSTREAM_H
|
|
||||||
|
|
||||||
#include "pistring.h"
|
|
||||||
|
|
||||||
|
|
||||||
//! \ingroup Core
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english Text serialization functionality over PIBinaryStream.
|
|
||||||
//! \~russian Функциональность текстовой сериализации поверх PIBinaryStream.
|
|
||||||
template<typename P>
|
|
||||||
class PITextStream {
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! \~english Floating-point numbers write format
|
|
||||||
//! \~russian Формат записи чисел с плавающей точкой
|
|
||||||
enum FloatFormat {
|
|
||||||
DecimalFormat /** \~english Decimal format, "*.*" \~russian Десятичный формат, "*.*" */ = 'f',
|
|
||||||
ExponentFormat /** \~english Exponential format, "*e+-<E>" \~russian Экспонентный формат, "*e+-<E>" */ = 'e'
|
|
||||||
};
|
|
||||||
|
|
||||||
//! \~english String encoding
|
|
||||||
//! \~russian Кодировка строк
|
|
||||||
enum Encoding {
|
|
||||||
System /** \~english System encoding \~russian Системная кодировка */,
|
|
||||||
UTF8 /** \~english UTF-8 encoding \~russian Кодировка UTF-8 */,
|
|
||||||
};
|
|
||||||
|
|
||||||
//! \~english Construct text stream binded to "stream_"
|
|
||||||
//! \~russian Возвращает привязанный к "stream_" текстовый поток
|
|
||||||
PITextStream(PIBinaryStream<P> * stream_) {setStream(stream_);}
|
|
||||||
|
|
||||||
//! \~english Returns binded PIBinaryStream
|
|
||||||
//! \~russian Возвращает привязанный PIBinaryStream
|
|
||||||
PIBinaryStream<P> * stream() const {return s;}
|
|
||||||
void setStream(PIBinaryStream<P> * stream_) {
|
|
||||||
s = stream_;
|
|
||||||
is_end = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Returns if end of stream reached
|
|
||||||
//! \~russian Возвращает достигнут ли конец потока
|
|
||||||
bool isEnd() const {return is_end;}
|
|
||||||
|
|
||||||
//! \~english Returns read/write encoding
|
|
||||||
//! \~russian Возвращает кодировку чтения/записи
|
|
||||||
Encoding encoding() const {return enc;}
|
|
||||||
|
|
||||||
//! \~english Set read/write encoding, default UTF8
|
|
||||||
//! \~russian Устанавливает кодировку чтения/записи, по умолчанию UTF8
|
|
||||||
void setEncoding(Encoding e) {enc = e;}
|
|
||||||
|
|
||||||
//! \~english Returns float numbers write format
|
|
||||||
//! \~russian Возвращает формат записи чисел с плавающей точкой
|
|
||||||
FloatFormat floatFormat() const {return format_;}
|
|
||||||
|
|
||||||
//! \~english Set float numbers write format, default DecimalFormat
|
|
||||||
//! \~russian Устанавливает формат записи чисел с плавающей точкой, по умолчанию DecimalFormat
|
|
||||||
void setFloatFormat(FloatFormat format) {format_ = format;}
|
|
||||||
|
|
||||||
//! \~english Returns float numbers write precision
|
|
||||||
//! \~russian Возвращает точность записи чисел с плавающей точкой
|
|
||||||
int floatPrecision() const {return prec_;}
|
|
||||||
|
|
||||||
//! \~english Set float numbers write precision to "prec_" digits, default 5
|
|
||||||
//! \~russian Устанавливает точность записи чисел с плавающей точкой, по умолчанию 5
|
|
||||||
void setFloatPrecision(int prec) {prec_ = prec;}
|
|
||||||
|
|
||||||
//! \~english Append space
|
|
||||||
//! \~russian Добавляет пробел
|
|
||||||
PITextStream<P> & space() {s->binaryStreamAppend(' '); return *this;}
|
|
||||||
|
|
||||||
//! \~english Append new line
|
|
||||||
//! \~russian Добавляет новую строку
|
|
||||||
PITextStream<P> & newLine() {s->binaryStreamAppend('\n'); return *this;}
|
|
||||||
|
|
||||||
//! \~english Append "v" string
|
|
||||||
//! \~russian Добавляет строку "v"
|
|
||||||
void append(const PIString & v) {
|
|
||||||
if (v.isEmpty()) return;
|
|
||||||
PIByteArray d;
|
|
||||||
switch (enc) {
|
|
||||||
case System: d = v.toSystem(); break;
|
|
||||||
case UTF8 : d = v.toUTF8(); break;
|
|
||||||
}
|
|
||||||
s->binaryStreamAppend(d.data(), d.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Append "v" as ASCII
|
|
||||||
//! \~russian Добавляет "v" как ASCII
|
|
||||||
void append(const PIConstChars & v) {if (!v.isEmpty()) s->binaryStreamAppend(v.data(), v.size());}
|
|
||||||
|
|
||||||
//! \~english Append "v" char as character
|
|
||||||
//! \~russian Добавляет "v" как символ
|
|
||||||
void append(char v) {s->binaryStreamAppend(v);}
|
|
||||||
|
|
||||||
//! \~english Append "v" as ASCII
|
|
||||||
//! \~russian Добавляет "v" как ASCII
|
|
||||||
void append(const char * v) {append(PIConstChars(v));}
|
|
||||||
|
|
||||||
//! \~english Append boolean, "true" of "false"
|
|
||||||
//! \~russian Добавляет логическое, "true" of "false"
|
|
||||||
void append(bool v) {append(v ? "true" : "false");}
|
|
||||||
|
|
||||||
//! \~english Append integer
|
|
||||||
//! \~russian Добавляет целое
|
|
||||||
void append(int v) {append(PIString::fromNumber(v));}
|
|
||||||
|
|
||||||
//! \~english Append integer
|
|
||||||
//! \~russian Добавляет целое
|
|
||||||
void append(llong v) {append(PIString::fromNumber(v));}
|
|
||||||
|
|
||||||
//! \~english Append floating-point number, using \a floatFormat() and \a floatPrecision()
|
|
||||||
//! \~russian Добавляет число с плавающей точкой, используя \a floatFormat() и \a floatPrecision()
|
|
||||||
void append(float v) {append(PIString::fromNumber(v, (char)format_, prec_));}
|
|
||||||
|
|
||||||
//! \~english Append floating-point number, using \a floatFormat() and \a floatPrecision()
|
|
||||||
//! \~russian Добавляет число с плавающей точкой, используя \a floatFormat() и \a floatPrecision()
|
|
||||||
void append(double v) {append(PIString::fromNumber(v, (char)format_, prec_));}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Read character
|
|
||||||
//! \~russian Читает символ
|
|
||||||
char takeChar(bool * rok) {
|
|
||||||
char ret;
|
|
||||||
bool ok = s->binaryStreamTake(&ret, sizeof(ret));
|
|
||||||
if (!ok) is_end = true;
|
|
||||||
if (rok) *rok = ok;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Read line
|
|
||||||
//! \~russian Читает строку
|
|
||||||
PIString takeLine() {
|
|
||||||
PIByteArray ret;
|
|
||||||
bool ok = true;
|
|
||||||
for (;;) {
|
|
||||||
char b = takeChar(&ok);
|
|
||||||
if (!ok || b == '\n') break;
|
|
||||||
if (b != '\r')
|
|
||||||
ret.append((uchar)b);
|
|
||||||
}
|
|
||||||
return fromBytes(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Read word, skip leading whitespaces, until next whitespace
|
|
||||||
//! \~russian Читает слово, пропуская начальные пробельные символы, до следующего пробельного символа
|
|
||||||
PIString takeWord() {
|
|
||||||
static PIConstChars spaces(" \t\n\r");
|
|
||||||
return takeUntil(spaces);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english
|
|
||||||
//! \~russian
|
|
||||||
PIString takeCWord() {
|
|
||||||
static PIConstChars chars(" \t\n\r:;%$&#@!?~/*-+=.,\\\"'`[](){}<>");
|
|
||||||
return takeUntil(chars);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PIString fromBytes(const PIByteArray & ba) {
|
|
||||||
switch (enc) {
|
|
||||||
case System: return PIString::fromSystem(ba);
|
|
||||||
case UTF8 : return PIString::fromUTF8(ba);
|
|
||||||
}
|
|
||||||
return PIString();
|
|
||||||
}
|
|
||||||
PIString takeUntil(const PIConstChars & chars) {
|
|
||||||
//static PIConstChars spaces(" \t\n\r");
|
|
||||||
bool ok = true;
|
|
||||||
char c = skipWhile(chars, &ok);
|
|
||||||
if (!ok) return PIString();
|
|
||||||
PIByteArray ret;
|
|
||||||
ret.append((uchar)c);
|
|
||||||
for (;;) {
|
|
||||||
c = takeChar(&ok);
|
|
||||||
if (!ok || chars.contains(c)) break;
|
|
||||||
ret.append((uchar)c);
|
|
||||||
}
|
|
||||||
return fromBytes(ret);
|
|
||||||
}
|
|
||||||
// returns first non-"chars" char
|
|
||||||
char skipWhile(const PIConstChars & chars, bool * rok) {
|
|
||||||
bool ok = true;
|
|
||||||
char c = 0;
|
|
||||||
for (;;) {
|
|
||||||
c = takeChar(&ok);
|
|
||||||
if (!ok || !chars.contains(c)) break;
|
|
||||||
}
|
|
||||||
if (rok) *rok = ok;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIBinaryStream<P> * s;
|
|
||||||
Encoding enc = UTF8;
|
|
||||||
FloatFormat format_ = DecimalFormat;
|
|
||||||
bool is_end = false;
|
|
||||||
int prec_ = 5;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Returns PITextStream for binary stream "stream"
|
|
||||||
//! \~russian Возвращает PITextStream для бинарного потока "stream"
|
|
||||||
template<typename P>
|
|
||||||
inline PITextStream<P> createPITextStream(PIBinaryStream<P> * stream) {return PITextStream<P>(stream);}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Append boolean
|
|
||||||
//! \~russian Добавляет логическое
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, bool v) {s.append(v); return s;}
|
|
||||||
|
|
||||||
//! \~english Append character
|
|
||||||
//! \~russian Добавляет символ
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, char v) {s.append(v); return s;}
|
|
||||||
|
|
||||||
//! \~english Append integer
|
|
||||||
//! \~russian Добавляет целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, uchar v) {s.append((int)v); return s;}
|
|
||||||
|
|
||||||
//! \~english Append integer
|
|
||||||
//! \~russian Добавляет целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, short v) {s.append((int)v); return s;}
|
|
||||||
|
|
||||||
//! \~english Append integer
|
|
||||||
//! \~russian Добавляет целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, ushort v) {s.append((int)v); return s;}
|
|
||||||
|
|
||||||
//! \~english Append integer
|
|
||||||
//! \~russian Добавляет целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, int v) {s.append((int)v); return s;}
|
|
||||||
|
|
||||||
//! \~english Append integer
|
|
||||||
//! \~russian Добавляет целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, uint v) {s.append((int)v); return s;}
|
|
||||||
|
|
||||||
//! \~english Append integer
|
|
||||||
//! \~russian Добавляет целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, llong v) {s.append((llong)v); return s;}
|
|
||||||
|
|
||||||
//! \~english Append integer
|
|
||||||
//! \~russian Добавляет целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, ullong v) {s.append((llong)v); return s;}
|
|
||||||
|
|
||||||
//! \~english Append floating-point number
|
|
||||||
//! \~russian Добавляет число с плавающей точкой
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, float v) {s.append(v); return s;}
|
|
||||||
|
|
||||||
//! \~english Append floating-point number
|
|
||||||
//! \~russian Добавляет число с плавающей точкой
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, double v) {s.append(v); return s;}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Append string
|
|
||||||
//! \~russian Добавляет строку
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, const char * v) {s.append(v); return s;}
|
|
||||||
|
|
||||||
//! \~english Append string
|
|
||||||
//! \~russian Добавляет строку
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, const PIConstChars & v) {s.append(v); return s;}
|
|
||||||
|
|
||||||
//! \~english Append string
|
|
||||||
//! \~russian Добавляет строку
|
|
||||||
template<typename P> inline PITextStream<P> & operator <<(PITextStream<P> & s, const PIString & v) {s.append(v); return s;}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Read word as bool
|
|
||||||
//! \~russian Читает слово как логическое
|
|
||||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, bool & v) {v = s.takeWord().toBool(); return s;}
|
|
||||||
|
|
||||||
//! \~english Read character
|
|
||||||
//! \~russian Читает символ
|
|
||||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, char & v) {v = s.takeChar(); return s;}
|
|
||||||
|
|
||||||
//! \~english Read word as integer
|
|
||||||
//! \~russian Читает слово как целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, uchar & v) {v = s.takeWord().toUInt(); return s;}
|
|
||||||
|
|
||||||
//! \~english Read word as integer
|
|
||||||
//! \~russian Читает слово как целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, short & v) {v = s.takeWord().toInt(); return s;}
|
|
||||||
|
|
||||||
//! \~english Read word as integer
|
|
||||||
//! \~russian Читает слово как целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, ushort & v) {v = s.takeWord().toUInt(); return s;}
|
|
||||||
|
|
||||||
//! \~english Read word as integer
|
|
||||||
//! \~russian Читает слово как целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, int & v) {v = s.takeWord().toInt(); return s;}
|
|
||||||
|
|
||||||
//! \~english Read word as integer
|
|
||||||
//! \~russian Читает слово как целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, uint & v) {v = s.takeWord().toUInt(); return s;}
|
|
||||||
|
|
||||||
//! \~english Read word as integer
|
|
||||||
//! \~russian Читает слово как целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, llong & v) {v = s.takeWord().toLLong(); return s;}
|
|
||||||
|
|
||||||
//! \~english Read word as integer
|
|
||||||
//! \~russian Читает слово как целое
|
|
||||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, ullong & v) {v = s.takeWord().toULLong(); return s;}
|
|
||||||
|
|
||||||
//! \~english Read word as floating-point number
|
|
||||||
//! \~russian Читает слово как число с плавающей точкой
|
|
||||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, float & v) {v = s.takeWord().toFloat(); return s;}
|
|
||||||
|
|
||||||
//! \~english Read word as floating-point number
|
|
||||||
//! \~russian Читает слово как число с плавающей точкой
|
|
||||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, double & v) {v = s.takeWord().toDouble(); return s;}
|
|
||||||
|
|
||||||
|
|
||||||
//! \~english Read word
|
|
||||||
//! \~russian Читает слово
|
|
||||||
template<typename P> inline PITextStream<P> & operator >>(PITextStream<P> & s, PIString & v) {v = s.takeWord(); return s;}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -206,7 +206,8 @@ classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(c
|
|||||||
//! \~english Variant type.
|
//! \~english Variant type.
|
||||||
class PIP_EXPORT PIVariant {
|
class PIP_EXPORT PIVariant {
|
||||||
friend PICout operator <<(PICout s, const PIVariant & v);
|
friend PICout operator <<(PICout s, const PIVariant & v);
|
||||||
BINARY_STREAM_FRIEND(PIVariant);
|
friend PIByteArray & operator <<(PIByteArray & s, const PIVariant & v);
|
||||||
|
friend PIByteArray & operator >>(PIByteArray & s, PIVariant & v);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Type of %PIVariant content
|
//! Type of %PIVariant content
|
||||||
@@ -772,9 +773,8 @@ REGISTER_VARIANT(PILined)
|
|||||||
REGISTER_VARIANT(PIMathVectord)
|
REGISTER_VARIANT(PIMathVectord)
|
||||||
REGISTER_VARIANT(PIMathMatrixd)
|
REGISTER_VARIANT(PIMathMatrixd)
|
||||||
|
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVariant & v) {
|
||||||
BINARY_STREAM_WRITE(PIVariant) {
|
s << v._content << int(v._type);
|
||||||
s << v._content << v._type;
|
|
||||||
if (v._type == PIVariant::pivCustom) {
|
if (v._type == PIVariant::pivCustom) {
|
||||||
#ifdef CUSTOM_PIVARIANT
|
#ifdef CUSTOM_PIVARIANT
|
||||||
if (v._info) {
|
if (v._info) {
|
||||||
@@ -788,8 +788,10 @@ BINARY_STREAM_WRITE(PIVariant) {
|
|||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
BINARY_STREAM_READ(PIVariant) {
|
inline PIByteArray & operator >>(PIByteArray & s, PIVariant & v) {
|
||||||
s >> v._content >> v._type;
|
int t(0);
|
||||||
|
s >> v._content >> t;
|
||||||
|
v._type = (PIVariant::Type)t;
|
||||||
if (v._type == PIVariant::pivCustom) {
|
if (v._type == PIVariant::pivCustom) {
|
||||||
PIString tn;
|
PIString tn;
|
||||||
s >> tn;
|
s >> tn;
|
||||||
|
|||||||
@@ -110,25 +110,25 @@ PIPropertyStorage PIVariantTypes::IODevice::get() const {
|
|||||||
|
|
||||||
PIString PIVariantTypes::IODevice::toPICout() const {
|
PIString PIVariantTypes::IODevice::toPICout() const {
|
||||||
PIString s;
|
PIString s;
|
||||||
s += "IODevice(" + prefix + ", mode=";
|
s << "IODevice(" << prefix << ", mode=";
|
||||||
int rwc = 0;
|
int rwc = 0;
|
||||||
if (mode & 1) {s += "r"; ++rwc;}
|
if (mode & 1) {s << "r"; ++rwc;}
|
||||||
if (mode & 2) {s += "w"; ++rwc;}
|
if (mode & 2) {s << "w"; ++rwc;}
|
||||||
if (rwc == 1) s += "o";
|
if (rwc == 1) s << "o";
|
||||||
s += ", flags=";
|
s << ", flags=";
|
||||||
#ifndef MICRO_PIP // TODO: PIIODevice for MICRO PIP
|
#ifndef MICRO_PIP // TODO: PIIODevice for MICRO PIP
|
||||||
if (options != 0) {
|
if (options != 0) {
|
||||||
if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingRead])
|
if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingRead])
|
||||||
s += " br";
|
s << " br";
|
||||||
if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingWrite])
|
if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingWrite])
|
||||||
s += " bw";
|
s << " bw";
|
||||||
}
|
}
|
||||||
#endif // MICRO_PIP
|
#endif // MICRO_PIP
|
||||||
PIPropertyStorage ps = get();
|
PIPropertyStorage ps = get();
|
||||||
piForeachC (PIPropertyStorage::Property & p, ps) {
|
piForeachC (PIPropertyStorage::Property & p, ps) {
|
||||||
s += ", " + p.name + "=\"" + p.value.toString() + "\"";
|
s << ", " << p.name << "=\"" << p.value.toString() << "\"";
|
||||||
}
|
}
|
||||||
s += ")";
|
s << ")";
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -164,34 +164,28 @@ struct PIP_EXPORT IODevice {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Enumerator & v) {s << v.value << v.name; return s;}
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Enumerator & v) {s >> v.value >> v.name; return s;}
|
||||||
inline PICout operator <<(PICout s, const PIVariantTypes::Enumerator & v) {s << v.name << "(" << v.value << ")"; return s;}
|
inline PICout operator <<(PICout s, const PIVariantTypes::Enumerator & v) {s << v.name << "(" << v.value << ")"; return s;}
|
||||||
|
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Enum & v) {s << v.enum_name << v.selected << v.enum_list; return s;}
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Enum & v) {s >> v.enum_name >> v.selected >> v.enum_list; return s;}
|
||||||
inline PICout operator <<(PICout s, const PIVariantTypes::Enum & v) {s << "Enum(" << v.selectedValue() << "=" << v.selectedName() << ")"; return s;}
|
inline PICout operator <<(PICout s, const PIVariantTypes::Enum & v) {s << "Enum(" << v.selectedValue() << "=" << v.selectedName() << ")"; return s;}
|
||||||
|
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::File & v) {s << v.file << v.filter << uchar((v.is_abs ? 1 : 0) + (v.is_save ? 2 : 0)); return s;}
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::File & v) {uchar f(0); s >> v.file >> v.filter >> f; v.is_abs = ((f & 1) == 1); v.is_save = ((f & 2) == 2); return s;}
|
||||||
inline PICout operator <<(PICout s, const PIVariantTypes::File & v) {s << "File(\"" << v.file << "\")"; return s;}
|
inline PICout operator <<(PICout s, const PIVariantTypes::File & v) {s << "File(\"" << v.file << "\")"; return s;}
|
||||||
|
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Dir & v) {s << v.dir << v.is_abs; return s;}
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Dir & v) {s >> v.dir >> v.is_abs; return s;}
|
||||||
inline PICout operator <<(PICout s, const PIVariantTypes::Dir & v) {s << "Dir(\"" << v.dir << "\")"; return s;}
|
inline PICout operator <<(PICout s, const PIVariantTypes::Dir & v) {s << "Dir(\"" << v.dir << "\")"; return s;}
|
||||||
|
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Color & v) {s << v.rgba; return s;}
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Color & v) {s >> v.rgba; return s;}
|
||||||
inline PICout operator <<(PICout s, const PIVariantTypes::Color & v) {s.saveControl(); s << PICoutManipulators::Hex << "Color(#" << v.rgba << ")"; s.restoreControl(); return s;}
|
inline PICout operator <<(PICout s, const PIVariantTypes::Color & v) {s.saveControl(); s << PICoutManipulators::Hex << "Color(#" << v.rgba << ")"; s.restoreControl(); return s;}
|
||||||
|
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::IODevice & v) {s << v.prefix << v.mode << v.options << v.props; return s;}
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::IODevice & v) {s >> v.prefix >> v.mode >> v.options >> v.props; return s;}
|
||||||
inline PICout operator <<(PICout s, const PIVariantTypes::IODevice & v) {s << v.toPICout(); return s;}
|
inline PICout operator <<(PICout s, const PIVariantTypes::IODevice & v) {s << v.toPICout(); return s;}
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIVariantTypes::Enumerator) {s << v.value << v.name; return s;}
|
|
||||||
BINARY_STREAM_READ (PIVariantTypes::Enumerator) {s >> v.value >> v.name; return s;}
|
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIVariantTypes::Enum) {s << v.enum_name << v.selected << v.enum_list; return s;}
|
|
||||||
BINARY_STREAM_READ (PIVariantTypes::Enum) {s >> v.enum_name >> v.selected >> v.enum_list; return s;}
|
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIVariantTypes::File) {s << v.file << v.filter << uchar((v.is_abs ? 1 : 0) + (v.is_save ? 2 : 0)); return s;}
|
|
||||||
BINARY_STREAM_READ (PIVariantTypes::File) {uchar f(0); s >> v.file >> v.filter >> f; v.is_abs = ((f & 1) == 1); v.is_save = ((f & 2) == 2); return s;}
|
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIVariantTypes::Dir) {s << v.dir << v.is_abs; return s;}
|
|
||||||
BINARY_STREAM_READ (PIVariantTypes::Dir) {s >> v.dir >> v.is_abs; return s;}
|
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIVariantTypes::Color) {s << v.rgba; return s;}
|
|
||||||
BINARY_STREAM_READ (PIVariantTypes::Color) {s >> v.rgba; return s;}
|
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIVariantTypes::IODevice) {s << v.prefix << v.mode << v.options << v.props; return s;}
|
|
||||||
BINARY_STREAM_READ (PIVariantTypes::IODevice) {s >> v.prefix >> v.mode >> v.options >> v.props; return s;}
|
|
||||||
|
|
||||||
#endif // PIVARIANTYPES_H
|
#endif // PIVARIANTYPES_H
|
||||||
|
|||||||
@@ -76,19 +76,19 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//! Disconneted event
|
//! Disconneted event
|
||||||
EVENT1(disconnected, PIString, reason);
|
EVENT1(disconnected, PIString, reason)
|
||||||
|
|
||||||
//! Conneted event
|
//! Conneted event
|
||||||
EVENT1(connected, PIString, info);
|
EVENT1(connected, PIString, info)
|
||||||
|
|
||||||
//! Client event for authorize new server
|
//! Client event for authorize new server
|
||||||
EVENT2(authorize, PIByteArray, info, bool *, ok);
|
EVENT2(authorize, PIByteArray, info, bool *, ok)
|
||||||
|
|
||||||
//! Client event for input server password
|
//! Client event for input server password
|
||||||
EVENT1(passwordRequest, PIString *, pass);
|
EVENT1(passwordRequest, PIString *, pass)
|
||||||
|
|
||||||
//! Server event on check client password
|
//! Server event on check client password
|
||||||
EVENT1(passwordCheck, bool, result);
|
EVENT1(passwordCheck, bool, result)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Role {Client, Server};
|
enum Role {Client, Server};
|
||||||
|
|||||||
@@ -96,3 +96,15 @@ PIVector<PIIntrospectionContainers::TypeInfo> PIIntrospectionContainers::getInfo
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::TypeInfo & v) {
|
||||||
|
s << PIByteArray::RawData(&v, sizeof(PIIntrospectionContainers::_Type)) << v.name;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
PIByteArray & operator >>(PIByteArray & s, PIIntrospectionContainers::TypeInfo & v) {
|
||||||
|
s >> PIByteArray::RawData(&v, sizeof(PIIntrospectionContainers::_Type)) >> v.name;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|||||||
@@ -65,14 +65,7 @@ public:
|
|||||||
mutable PISpinlock mutex;
|
mutable PISpinlock mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::TypeInfo & v);
|
||||||
BINARY_STREAM_WRITE(PIIntrospectionContainers::TypeInfo) {
|
PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIIntrospectionContainers::TypeInfo & v);
|
||||||
s << PIMemoryBlock(&v, sizeof(PIIntrospectionContainers::_Type)) << v.name;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
BINARY_STREAM_READ(PIIntrospectionContainers::TypeInfo) {
|
|
||||||
s >> PIMemoryBlock(&v, sizeof(PIIntrospectionContainers::_Type)) >> v.name;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // PIINTROSPECTION_CONTAINERS_P_H
|
#endif // PIINTROSPECTION_CONTAINERS_P_H
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ void PIIntrospectionServer::start(const PIString & server_name) {
|
|||||||
sysmon = PISystemMonitor::Pool::instance()->getByPID(PIProcess::currentPID());
|
sysmon = PISystemMonitor::Pool::instance()->getByPID(PIProcess::currentPID());
|
||||||
if (sysmon) {
|
if (sysmon) {
|
||||||
piCoutObj << "using existing sysmon";
|
piCoutObj << "using existing sysmon";
|
||||||
CONNECT1(void, PIObject *, sysmon, deleted, this, sysmonDeleted);
|
CONNECTU(sysmon, deleted, this, sysmonDeleted);
|
||||||
} else {
|
} else {
|
||||||
piCoutObj << "create own sysmon";
|
piCoutObj << "create own sysmon";
|
||||||
sysmon = new PISystemMonitor();
|
sysmon = new PISystemMonitor();
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class PISystemMonitor;
|
|||||||
# define PIINTROSPECTION_START(name) PIINTROSPECTION_SERVER->start(#name);
|
# define PIINTROSPECTION_START(name) PIINTROSPECTION_SERVER->start(#name);
|
||||||
|
|
||||||
class PIP_EXPORT PIIntrospectionServer: public PIPeer {
|
class PIP_EXPORT PIIntrospectionServer: public PIPeer {
|
||||||
PIOBJECT_SUBCLASS(PIIntrospectionServer, PIPeer);
|
PIOBJECT_SUBCLASS(PIIntrospectionServer, PIPeer)
|
||||||
public:
|
public:
|
||||||
static PIIntrospectionServer * instance();
|
static PIIntrospectionServer * instance();
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
PIIntrospectionServer();
|
PIIntrospectionServer();
|
||||||
~PIIntrospectionServer();
|
~PIIntrospectionServer();
|
||||||
NO_COPY_CLASS(PIIntrospectionServer);
|
NO_COPY_CLASS(PIIntrospectionServer)
|
||||||
|
|
||||||
PIString genName();
|
PIString genName();
|
||||||
virtual void dataReceived(const PIString & from, const PIByteArray & data);
|
virtual void dataReceived(const PIString & from, const PIByteArray & data);
|
||||||
|
|||||||
@@ -77,6 +77,82 @@ PIVector<PIIntrospection::ObjectInfo> PIIntrospection::getObjects() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::RequiredInfo & v) {
|
||||||
|
PIChunkStream cs;
|
||||||
|
cs.add(1, v.types);
|
||||||
|
b << cs.data();
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray & operator >>(PIByteArray & b, PIIntrospection::RequiredInfo & v) {
|
||||||
|
PIByteArray csba; b >> csba;
|
||||||
|
PIChunkStream cs(csba);
|
||||||
|
while (!cs.atEnd()) {
|
||||||
|
switch (cs.read()) {
|
||||||
|
case 1: cs.get(v.types); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ProcessInfo & v) {
|
||||||
|
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);
|
||||||
|
b << cs.data();
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ProcessInfo & v) {
|
||||||
|
PIByteArray csba; b >> csba;
|
||||||
|
PIChunkStream cs(csba);
|
||||||
|
while (!cs.atEnd()) {
|
||||||
|
switch (cs.read()) {
|
||||||
|
case 1: cs.get(v.architecture); break;
|
||||||
|
case 2: cs.get(v.execCommand); break;
|
||||||
|
case 3: cs.get(v.execDateTime); break;
|
||||||
|
case 4: cs.get(v.hostname); break;
|
||||||
|
case 5: cs.get(v.OS_name); break;
|
||||||
|
case 6: cs.get(v.OS_version); break;
|
||||||
|
case 7: cs.get(v.processorsCount); break;
|
||||||
|
case 8: cs.get(v.user); break;
|
||||||
|
case 9: cs.get(v.build_options); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ObjectInfo & v) {
|
||||||
|
PIChunkStream cs;
|
||||||
|
cs.add(1, v.classname).add(2, v.name).add(3, v.parents).add(4, v.properties).add(5, v.queued_events);
|
||||||
|
b << cs.data();
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ObjectInfo & v) {
|
||||||
|
PIByteArray csba; b >> csba;
|
||||||
|
PIChunkStream cs(csba);
|
||||||
|
while (!cs.atEnd()) {
|
||||||
|
switch (cs.read()) {
|
||||||
|
case 1: cs.get(v.classname); break;
|
||||||
|
case 2: cs.get(v.name); break;
|
||||||
|
case 3: cs.get(v.parents); break;
|
||||||
|
case 4: cs.get(v.properties); break;
|
||||||
|
case 5: cs.get(v.queued_events); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PIByteArray PIIntrospection::packInfo() {
|
PIByteArray PIIntrospection::packInfo() {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include "piintrospection_containers_p.h"
|
#include "piintrospection_containers_p.h"
|
||||||
#include "piintrospection_threads.h"
|
#include "piintrospection_threads.h"
|
||||||
#include "piintrospection_threads_p.h"
|
#include "piintrospection_threads_p.h"
|
||||||
#include "pichunkstream.h"
|
|
||||||
#include "pisystemmonitor.h"
|
#include "pisystemmonitor.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -92,72 +91,13 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::RequiredInfo & v);
|
||||||
|
PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIIntrospection::RequiredInfo & v);
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIIntrospection::RequiredInfo) {
|
PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ProcessInfo & v);
|
||||||
PIChunkStream cs;
|
PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ProcessInfo & v);
|
||||||
cs.add(1, v.types);
|
|
||||||
s << cs.data();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
BINARY_STREAM_READ(PIIntrospection::RequiredInfo) {
|
|
||||||
PIByteArray csba; s >> csba;
|
|
||||||
PIChunkStream cs(csba);
|
|
||||||
while (!cs.atEnd()) {
|
|
||||||
switch (cs.read()) {
|
|
||||||
case 1: cs.get(v.types); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIIntrospection::ProcessInfo) {
|
PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ObjectInfo & v);
|
||||||
PIChunkStream cs;
|
PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ObjectInfo & v);
|
||||||
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;
|
|
||||||
PIChunkStream cs(csba);
|
|
||||||
while (!cs.atEnd()) {
|
|
||||||
switch (cs.read()) {
|
|
||||||
case 1: cs.get(v.architecture); break;
|
|
||||||
case 2: cs.get(v.execCommand); break;
|
|
||||||
case 3: cs.get(v.execDateTime); break;
|
|
||||||
case 4: cs.get(v.hostname); break;
|
|
||||||
case 5: cs.get(v.OS_name); break;
|
|
||||||
case 6: cs.get(v.OS_version); break;
|
|
||||||
case 7: cs.get(v.processorsCount); break;
|
|
||||||
case 8: cs.get(v.user); break;
|
|
||||||
case 9: cs.get(v.build_options); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIIntrospection::ObjectInfo) {
|
|
||||||
PIChunkStream cs;
|
|
||||||
cs.add(1, v.classname).add(2, v.name).add(3, v.parents).add(4, v.properties).add(5, v.queued_events);
|
|
||||||
s << cs.data();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
BINARY_STREAM_READ(PIIntrospection::ObjectInfo) {
|
|
||||||
PIByteArray csba; s >> csba;
|
|
||||||
PIChunkStream cs(csba);
|
|
||||||
while (!cs.atEnd()) {
|
|
||||||
switch (cs.read()) {
|
|
||||||
case 1: cs.get(v.classname); break;
|
|
||||||
case 2: cs.get(v.name); break;
|
|
||||||
case 3: cs.get(v.parents); break;
|
|
||||||
case 4: cs.get(v.properties); break;
|
|
||||||
case 5: cs.get(v.queued_events); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // PIINTROSPECTION_SERVER_P_H
|
#endif // PIINTROSPECTION_SERVER_P_H
|
||||||
|
|||||||
@@ -81,3 +81,19 @@ void PIIntrospectionThreads::threadRunDone(PIThread * t, ullong us) {
|
|||||||
ThreadInfo & ti(threads[t]);
|
ThreadInfo & ti(threads[t]);
|
||||||
ti.run_us = (ti.run_us * 0.8) + (us * 0.2); /// WARNING
|
ti.run_us = (ti.run_us * 0.8) + (us * 0.2); /// WARNING
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray & operator <<(PIByteArray & b, const PIIntrospectionThreads::ThreadInfo & v) {
|
||||||
|
b << v.classname << v.name << v.id << int(v.state) << v.priority << v.delay << v.run_us << v.run_count;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray & operator >>(PIByteArray & b, PIIntrospectionThreads::ThreadInfo & v) {
|
||||||
|
int st(0);
|
||||||
|
b >> v.classname >> v.name >> v.id >> st >> v.priority >> v.delay >> v.run_us >> v.run_count;
|
||||||
|
v.state = (PIIntrospectionThreads::ThreadState)st;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|||||||
@@ -57,14 +57,7 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIIntrospectionThreads::ThreadInfo & v);
|
||||||
BINARY_STREAM_WRITE(PIIntrospectionThreads::ThreadInfo) {
|
PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIIntrospectionThreads::ThreadInfo & v);
|
||||||
s << v.classname << v.name << v.id << v.state << v.priority << v.delay << v.run_us << v.run_count;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
BINARY_STREAM_READ(PIIntrospectionThreads::ThreadInfo) {
|
|
||||||
s >> v.classname >> v.name >> v.id >> v.state >> v.priority >> v.delay >> v.run_us >> v.run_count;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // PIINTROSPECTION_THREADS_P_H
|
#endif // PIINTROSPECTION_THREADS_P_H
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ PIBinaryLog::PIBinaryLog() {
|
|||||||
is_started = is_indexed = is_pause = false;
|
is_started = is_indexed = is_pause = false;
|
||||||
current_index = -1;
|
current_index = -1;
|
||||||
log_size = 0;
|
log_size = 0;
|
||||||
f_new_path = nullptr;
|
|
||||||
setPlaySpeed(1.);
|
setPlaySpeed(1.);
|
||||||
setDefaultID(1);
|
setDefaultID(1);
|
||||||
setPlaySpeed(1.0);
|
setPlaySpeed(1.0);
|
||||||
@@ -101,8 +100,7 @@ bool PIBinaryLog::openDevice() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (path().isEmpty() && mode_ == WriteOnly) {
|
if (path().isEmpty() && mode_ == WriteOnly) {
|
||||||
if (f_new_path) setPath(f_new_path());
|
setPath(getLogfilePath());
|
||||||
else setPath(getLogfilePath(logDir(), filePrefix()));
|
|
||||||
}
|
}
|
||||||
if (path().isEmpty() && mode_ == ReadOnly) {
|
if (path().isEmpty() && mode_ == ReadOnly) {
|
||||||
PIDir ld(logDir());
|
PIDir ld(logDir());
|
||||||
@@ -170,7 +168,7 @@ bool PIBinaryLog::closeDevice() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIBinaryLog::threadedRead(const uchar *readed, int size) {
|
bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
||||||
// piCout << "binlog threaded read";
|
// piCout << "binlog threaded read";
|
||||||
if (!canRead() || isEnd()) return PIIODevice::threadedRead(readed, size);
|
if (!canRead() || isEnd()) return PIIODevice::threadedRead(readed, size);
|
||||||
is_thread_ok = false;
|
is_thread_ok = false;
|
||||||
@@ -245,18 +243,18 @@ bool PIBinaryLog::threadedRead(const uchar *readed, int size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIString PIBinaryLog::getLogfilePath(const PIString & log_dir, const PIString & prefix) {
|
PIString PIBinaryLog::getLogfilePath() const {
|
||||||
PIDir dir(log_dir);
|
PIDir dir(logDir());
|
||||||
dir.setDir(dir.absolutePath());
|
dir.setDir(dir.absolutePath());
|
||||||
if (!dir.isExists()) {
|
if (!dir.isExists()) {
|
||||||
piCout << "[PIBinaryLog]" << "Creating directory" << dir.path();
|
piCoutObj << "Creating directory" << dir.path();
|
||||||
dir.make(true);
|
dir.make(true);
|
||||||
}
|
}
|
||||||
PIString npath = log_dir + PIDir::separator + prefix + PIDateTime::current().toString("yyyy_MM_dd__hh_mm_ss");
|
PIString npath = logDir() + "/" + filePrefix() + PIDateTime::current().toString("yyyy_MM_dd__hh_mm_ss");
|
||||||
PIString cnpath = npath + ".binlog";
|
PIString cnpath = npath + ".binlog";
|
||||||
int i = 1;
|
int i = 1;
|
||||||
while (PIFile::isExists(cnpath)) {
|
while (PIFile::isExists(cnpath)) {
|
||||||
cnpath = npath + '_' + PIString::fromNumber(i) + ".binlog";
|
cnpath = npath + "_" + PIString::fromNumber(i) + ".binlog";
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return cnpath;
|
return cnpath;
|
||||||
@@ -264,14 +262,12 @@ PIString PIBinaryLog::getLogfilePath(const PIString & log_dir, const PIString &
|
|||||||
|
|
||||||
PIString PIBinaryLog::createNewFile() {
|
PIString PIBinaryLog::createNewFile() {
|
||||||
if (!file.close()) return PIString();
|
if (!file.close()) return PIString();
|
||||||
PIString cnpath;
|
PIString cnpath = getLogfilePath();
|
||||||
if (f_new_path) cnpath = f_new_path();
|
|
||||||
else cnpath = getLogfilePath(logDir(), filePrefix());
|
|
||||||
if (open(cnpath, PIIODevice::WriteOnly)) {
|
if (open(cnpath, PIIODevice::WriteOnly)) {
|
||||||
newFile(file.path());
|
newFile(file.path());
|
||||||
return file.path();
|
return file.path();
|
||||||
}
|
}
|
||||||
piCoutObj << "Can't create new file, maybe LogDir" << ("\"" + logDir() + "\"") << "is invalid.";
|
piCoutObj << "Can't create new file, maybe LogDir is invalid.";
|
||||||
return PIString();
|
return PIString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +276,7 @@ void PIBinaryLog::createNewFile(const PIString &path) {
|
|||||||
if (open(path, PIIODevice::WriteOnly)) {
|
if (open(path, PIIODevice::WriteOnly)) {
|
||||||
newFile(file.path());
|
newFile(file.path());
|
||||||
}
|
}
|
||||||
else piCoutObj << "Can't create new file, maybe path" << ("\"" + path + "\"") << "is invalid.";
|
else piCoutObj << "Can't create new file, maybe path is invalid.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -299,20 +295,13 @@ void PIBinaryLog::setPause(bool pause) {
|
|||||||
int PIBinaryLog::writeBinLog(int id, const void *data, int size) {
|
int PIBinaryLog::writeBinLog(int id, const void *data, int size) {
|
||||||
if (size <= 0 || !canWrite()) return -1;
|
if (size <= 0 || !canWrite()) return -1;
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
piCoutObj << "Error: can`t write with id = 0! Id must be > 0";
|
piCoutObj << "Error: can`t write with id = 0!";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (is_pause) return 0;
|
|
||||||
logmutex.lock();
|
logmutex.lock();
|
||||||
PIByteArray logdata;
|
|
||||||
logdata << id << size << (PISystemTime::current() - startlogtime) << PIMemoryBlock(data, size);
|
|
||||||
int res = file.write(logdata.data(), logdata.size());
|
|
||||||
file.flush();
|
|
||||||
write_count++;
|
|
||||||
log_size = file.size();
|
|
||||||
switch (split_mode) {
|
switch (split_mode) {
|
||||||
case SplitSize:
|
case SplitSize:
|
||||||
if (log_size > split_size) createNewFile();
|
if (file.size() > split_size) createNewFile();
|
||||||
break;
|
break;
|
||||||
case SplitTime:
|
case SplitTime:
|
||||||
if ((PISystemTime::current() - startlogtime) > split_time) createNewFile();
|
if ((PISystemTime::current() - startlogtime) > split_time) createNewFile();
|
||||||
@@ -322,6 +311,16 @@ int PIBinaryLog::writeBinLog(int id, const void *data, int size) {
|
|||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
if (is_pause) {
|
||||||
|
logmutex.unlock();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
PIByteArray logdata;
|
||||||
|
logdata << id << size << (PISystemTime::current() - startlogtime) << PIByteArray::RawData(data, size);
|
||||||
|
int res = file.write(logdata.data(), logdata.size());
|
||||||
|
file.flush();
|
||||||
|
write_count++;
|
||||||
|
log_size = file.size();
|
||||||
logmutex.unlock();
|
logmutex.unlock();
|
||||||
if (res > 0) return size;
|
if (res > 0) return size;
|
||||||
else return res;
|
else return res;
|
||||||
@@ -331,7 +330,7 @@ int PIBinaryLog::writeBinLog(int id, const void *data, int size) {
|
|||||||
int PIBinaryLog::writeBinLog_raw(int id, const PISystemTime &time, const void *data, int size) {
|
int PIBinaryLog::writeBinLog_raw(int id, const PISystemTime &time, const void *data, int size) {
|
||||||
if (size <= 0 || !canWrite()) return -1;
|
if (size <= 0 || !canWrite()) return -1;
|
||||||
PIByteArray logdata;
|
PIByteArray logdata;
|
||||||
logdata << id << size << time << PIMemoryBlock(data, size);
|
logdata << id << size << time << PIByteArray::RawData(data, size);
|
||||||
logmutex.lock();
|
logmutex.lock();
|
||||||
int res = file.write(logdata.data(), logdata.size());
|
int res = file.write(logdata.data(), logdata.size());
|
||||||
file.flush();
|
file.flush();
|
||||||
@@ -409,9 +408,8 @@ int PIBinaryLog::readDevice(void *read_to, int max_size) {
|
|||||||
if (max_size <= 0 || read_to == 0) return -1;
|
if (max_size <= 0 || read_to == 0) return -1;
|
||||||
BinLogRecord br;
|
BinLogRecord br;
|
||||||
br.id = 0;
|
br.id = 0;
|
||||||
if (filterID.isEmpty()) {
|
if (filterID.isEmpty()) br = readRecord();
|
||||||
br = readRecord();
|
else {
|
||||||
} else {
|
|
||||||
while (!filterID.contains(br.id) && !isEnd()) br = readRecord();
|
while (!filterID.contains(br.id) && !isEnd()) br = readRecord();
|
||||||
}
|
}
|
||||||
if (br.id == -1) {
|
if (br.id == -1) {
|
||||||
@@ -430,11 +428,6 @@ int PIBinaryLog::readDevice(void *read_to, int max_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PIBinaryLog::writeDevice(const void * data, int size) {
|
|
||||||
return writeBinLog(default_id, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIBinaryLog::restart() {
|
void PIBinaryLog::restart() {
|
||||||
bool th = isRunning();
|
bool th = isRunning();
|
||||||
if (th) stopThreadedRead();
|
if (th) stopThreadedRead();
|
||||||
@@ -550,33 +543,15 @@ void PIBinaryLog::parseLog(PIFile * f, PIBinaryLog::BinLogInfo * info, PIVector<
|
|||||||
}
|
}
|
||||||
uchar read_sig[PIBINARYLOG_SIGNATURE_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) {
|
bool ok = true;
|
||||||
if (info) info->records_count = -1;
|
if (f->read(read_sig, PIBINARYLOG_SIGNATURE_SIZE) < 0) {if (info) info->records_count = -1; ok = false;}
|
||||||
return;
|
for (uint i=0; i<PIBINARYLOG_SIGNATURE_SIZE; i++)
|
||||||
}
|
if (read_sig[i] != binlog_sig[i]) {if (info) info->records_count = -2; ok = false;}
|
||||||
for (uint i=0; i<PIBINARYLOG_SIGNATURE_SIZE; i++) {
|
|
||||||
if (read_sig[i] != binlog_sig[i]) {
|
|
||||||
if (info) info->records_count = -2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uchar read_version = 0;
|
uchar read_version = 0;
|
||||||
if (f->read(&read_version, 1) < 0) {
|
if (f->read(&read_version, 1) < 0) {if (info) info->records_count = -3; ok = false;}
|
||||||
if (info) info->records_count = -3;
|
if (read_version == 0) {if (info) info->records_count = -4; ok = false;}
|
||||||
return;
|
if (read_version < PIBINARYLOG_VERSION_OLD) {if (info) info->records_count = -5; ok = false;}
|
||||||
}
|
if (read_version > PIBINARYLOG_VERSION) {if (info) info->records_count = -6; ok = false;}
|
||||||
if (read_version == 0) {
|
|
||||||
if (info) info->records_count = -4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (read_version < PIBINARYLOG_VERSION_OLD) {
|
|
||||||
if (info) info->records_count = -5;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (read_version > PIBINARYLOG_VERSION) {
|
|
||||||
if (info) info->records_count = -6;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (read_version == PIBINARYLOG_VERSION) {
|
if (read_version == PIBINARYLOG_VERSION) {
|
||||||
uint32_t sz = 0;
|
uint32_t sz = 0;
|
||||||
f->read(&sz, 4);
|
f->read(&sz, 4);
|
||||||
@@ -584,10 +559,9 @@ void PIBinaryLog::parseLog(PIFile * f, PIBinaryLog::BinLogInfo * info, PIVector<
|
|||||||
info->user_header = f->read(sz);
|
info->user_header = f->read(sz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!ok) return;
|
||||||
PIByteArray ba;
|
PIByteArray ba;
|
||||||
BinLogRecord br;
|
BinLogRecord br;
|
||||||
br.id = 0;
|
|
||||||
br.size = 0;
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
size_t hdr_size = sizeof(BinLogRecord) - sizeof(PIByteArray);
|
size_t hdr_size = sizeof(BinLogRecord) - sizeof(PIByteArray);
|
||||||
ba.resize(hdr_size);
|
ba.resize(hdr_size);
|
||||||
@@ -596,16 +570,15 @@ void PIBinaryLog::parseLog(PIFile * f, PIBinaryLog::BinLogInfo * info, PIVector<
|
|||||||
{
|
{
|
||||||
if (f->read(ba.data(), ba.size()) > 0) {
|
if (f->read(ba.data(), ba.size()) > 0) {
|
||||||
ba >> br.id >> br.size >> br.timestamp;
|
ba >> br.id >> br.size >> br.timestamp;
|
||||||
} else break;
|
} else
|
||||||
if (info) {
|
break;
|
||||||
if (info->log_size - f->pos() >= br.size) {
|
if (info->log_size - f->pos() >= br.size)
|
||||||
f->seek(f->pos() + br.size);
|
f->seek(f->pos() + br.size);
|
||||||
}
|
else
|
||||||
}
|
break;
|
||||||
else break;
|
|
||||||
}
|
}
|
||||||
if (br.id > 0) {
|
if (br.id > 0) {
|
||||||
if (index) {
|
if (info) {
|
||||||
BinLogIndex bl_ind;
|
BinLogIndex bl_ind;
|
||||||
bl_ind.id = br.id;
|
bl_ind.id = br.id;
|
||||||
bl_ind.data_size = br.size;
|
bl_ind.data_size = br.size;
|
||||||
@@ -658,22 +631,14 @@ PIBinaryLog::BinLogInfo PIBinaryLog::getLogInfo(const PIString & path) {
|
|||||||
|
|
||||||
bool PIBinaryLog::cutBinLog(const PIBinaryLog::BinLogInfo & src, const PIString & dst, int from, int to) {
|
bool PIBinaryLog::cutBinLog(const PIBinaryLog::BinLogInfo & src, const PIString & dst, int from, int to) {
|
||||||
PIBinaryLog slog;
|
PIBinaryLog slog;
|
||||||
if (!slog.open(src.path, PIIODevice::ReadOnly)) {
|
if (!slog.open(src.path, PIIODevice::ReadOnly)) return false;
|
||||||
piCout << "[PIBinaryLog]" << "Error, can't open" << src.path;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
PIVector<int> ids = src.records.keys();
|
PIVector<int> ids = src.records.keys();
|
||||||
slog.seekTo(from);
|
slog.seekTo(from);
|
||||||
PIBinaryLog dlog;
|
PIBinaryLog dlog;
|
||||||
dlog.createNewFile(dst);
|
dlog.createNewFile(dst);
|
||||||
if (!dlog.isOpened()) {
|
|
||||||
piCout << "[PIBinaryLog]" << "Error, can't create" << dst;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
BinLogRecord br;
|
BinLogRecord br;
|
||||||
PISystemTime st;
|
PISystemTime st;
|
||||||
PITimeMeasurer tm;
|
|
||||||
while (!slog.isEnd() && ((slog.pos() <= to) || to < 0)) {
|
while (!slog.isEnd() && ((slog.pos() <= to) || to < 0)) {
|
||||||
br = slog.readRecord();
|
br = slog.readRecord();
|
||||||
if (first) {
|
if (first) {
|
||||||
@@ -681,74 +646,9 @@ bool PIBinaryLog::cutBinLog(const PIBinaryLog::BinLogInfo & src, const PIString
|
|||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
if (ids.contains(br.id)) {
|
if (ids.contains(br.id)) {
|
||||||
if (dlog.writeBinLog_raw(br.id, br.timestamp - st, br.data) <= 0) {
|
dlog.writeBinLog_raw(br.id, br.timestamp - st, br.data);
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool PIBinaryLog::joinBinLogsSerial(const PIStringList & src, const PIString & dst, std::function<bool (const PIString &, PISystemTime)> progress) {
|
|
||||||
PIBinaryLog slog;
|
|
||||||
PIBinaryLog dlog;
|
|
||||||
PISystemTime dtime;
|
|
||||||
PISystemTime lt;
|
|
||||||
PITimeMeasurer tm;
|
|
||||||
bool first = true;
|
|
||||||
for (const PIString & fn : src) {
|
|
||||||
if (!slog.open(fn, PIIODevice::ReadOnly)) {
|
|
||||||
piCout << "[PIBinaryLog]" << "Error, can't open" << fn;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (first) {
|
|
||||||
first = false;
|
|
||||||
dlog.setHeader(slog.getHeader());
|
|
||||||
dlog.createNewFile(dst);
|
|
||||||
if (!dlog.isOpened()) {
|
|
||||||
piCout << "[PIBinaryLog]" << "Error, can't create" << dst;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
piCout << "[PIBinaryLog]" << "Start join binlogs to" << dst;
|
|
||||||
} else {
|
|
||||||
dtime = lt;
|
|
||||||
}
|
|
||||||
tm.reset();
|
|
||||||
BinLogRecord br;
|
|
||||||
PISystemTime st;
|
|
||||||
while (!slog.isEnd()) {
|
|
||||||
br = slog.readRecord();
|
|
||||||
if (br.data.isEmpty() || br.id < 1) continue;
|
|
||||||
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;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (tm.elapsed_s() > 0.1) {
|
|
||||||
tm.reset();
|
|
||||||
if (progress) {
|
|
||||||
if (!progress(fn, lt)) {
|
|
||||||
slog.close();
|
|
||||||
dlog.close();
|
|
||||||
PIFile::remove(dlog.path());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
piCout << "[PIBinaryLog]" << "process" << PITime::fromSystemTime(lt).toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
slog.close();
|
|
||||||
//piCout << "[PIBinaryLog]" << "complete" << fn;
|
|
||||||
}
|
|
||||||
piCout << "[PIBinaryLog]" << "Finish join binlogs, total time" << PITime::fromSystemTime(lt).toString();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -828,19 +728,19 @@ bool PIBinaryLog::seek(llong filepos) {
|
|||||||
|
|
||||||
PIString PIBinaryLog::constructFullPathDevice() const {
|
PIString PIBinaryLog::constructFullPathDevice() const {
|
||||||
PIString ret;
|
PIString ret;
|
||||||
ret += logDir() + ":" + filePrefix() + ":" + PIString::fromNumber(defaultID()) + ":";
|
ret << logDir() << ":" << filePrefix() << ":" << defaultID() << ":";
|
||||||
switch (play_mode) {
|
switch (play_mode) {
|
||||||
case PlayRealTime:
|
case PlayRealTime:
|
||||||
ret += "RT";
|
ret << "RT";
|
||||||
break;
|
break;
|
||||||
case PlayVariableSpeed:
|
case PlayVariableSpeed:
|
||||||
ret += PIString::fromNumber(playSpeed()) + "X";
|
ret << PIString::fromNumber(playSpeed()) << "X";
|
||||||
break;
|
break;
|
||||||
case PlayStaticDelay:
|
case PlayStaticDelay:
|
||||||
ret += PIString::fromNumber(playDelay().toMilliseconds()) + "M";
|
ret << PIString::fromNumber(playDelay().toMilliseconds()) << "M";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret += "RT";
|
ret << "RT";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -28,13 +28,10 @@
|
|||||||
|
|
||||||
#include "pifile.h"
|
#include "pifile.h"
|
||||||
|
|
||||||
//! \ingroup IO
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english Binary log
|
|
||||||
//! \~russian Бинарный лог
|
|
||||||
class PIP_EXPORT PIBinaryLog: public PIIODevice
|
class PIP_EXPORT PIBinaryLog: public PIIODevice
|
||||||
{
|
{
|
||||||
PIIODEVICE(PIBinaryLog, "binlog");
|
PIIODEVICE(PIBinaryLog, "binlog")
|
||||||
public:
|
public:
|
||||||
explicit PIBinaryLog();
|
explicit PIBinaryLog();
|
||||||
virtual ~PIBinaryLog();
|
virtual ~PIBinaryLog();
|
||||||
@@ -168,11 +165,6 @@ public:
|
|||||||
//! Set pause while playing via \a threadedRead or writing via write
|
//! Set pause while playing via \a threadedRead or writing via write
|
||||||
void setPause(bool pause);
|
void setPause(bool pause);
|
||||||
|
|
||||||
//! Set function wich returns new binlog file path when using split mode.
|
|
||||||
//! Overrides internal file path generator (logdir() + prefix() + current_time()).
|
|
||||||
//! To restore internal file path generator set this function to "nullptr".
|
|
||||||
void setFuncGetNewFilePath(std::function<PIString()> f) {f_new_path = f;}
|
|
||||||
|
|
||||||
//! Write one record to BinLog file, with ID = id, id must be greather than 0
|
//! Write one record to BinLog file, with ID = id, id must be greather than 0
|
||||||
int writeBinLog(int id, PIByteArray data) {return writeBinLog(id, data.data(), data.size_s());}
|
int writeBinLog(int id, PIByteArray data) {return writeBinLog(id, data.data(), data.size_s());}
|
||||||
|
|
||||||
@@ -286,33 +278,28 @@ public:
|
|||||||
//! \}
|
//! \}
|
||||||
|
|
||||||
EVENT_HANDLER(PIString, createNewFile);
|
EVENT_HANDLER(PIString, createNewFile);
|
||||||
EVENT(fileEnd);
|
EVENT(fileEnd)
|
||||||
EVENT(fileError);
|
EVENT(fileError)
|
||||||
EVENT1(newFile, const PIString &, filename);
|
EVENT1(newFile, const PIString &, filename)
|
||||||
EVENT1(posChanged, int, pos);
|
EVENT1(posChanged, int, pos)
|
||||||
|
|
||||||
//! Get binlog info and statistic
|
//! Get binlog info and statistic
|
||||||
static BinLogInfo getLogInfo(const PIString & path);
|
static BinLogInfo getLogInfo(const PIString & path);
|
||||||
|
|
||||||
//! Create new binlog from part of "src" with allowed IDs and "from" to "to" file position
|
|
||||||
static bool cutBinLog(const BinLogInfo & src, const PIString & dst, int from, int to);
|
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);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PIString constructFullPathDevice() const override;
|
PIString constructFullPathDevice() const;
|
||||||
void configureFromFullPathDevice(const PIString & full_path) override;
|
void configureFromFullPathDevice(const PIString & full_path);
|
||||||
PIPropertyStorage constructVariantDevice() const override;
|
PIPropertyStorage constructVariantDevice() const;
|
||||||
void configureFromVariantDevice(const PIPropertyStorage & d) override;
|
void configureFromVariantDevice(const PIPropertyStorage & d);
|
||||||
int readDevice(void *read_to, int max_size) override;
|
int readDevice(void *read_to, int max_size);
|
||||||
int writeDevice(const void * data, int size) override;
|
int writeDevice(const void * data, int size) {return writeBinLog(default_id, data, size);}
|
||||||
bool openDevice() override;
|
bool openDevice();
|
||||||
bool closeDevice() override;
|
bool closeDevice();
|
||||||
void propertyChanged(const char * s) override;
|
void propertyChanged(const char * s);
|
||||||
bool threadedRead(const uchar *readed, int size) override;
|
bool threadedRead(uchar *readed, int size);
|
||||||
void threadedReadTerminated() override {pausemutex.unlock();}
|
void threadedReadTerminated() {pausemutex.unlock();}
|
||||||
DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Reliable;}
|
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Reliable;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct PIP_EXPORT BinLogRecord {
|
struct PIP_EXPORT BinLogRecord {
|
||||||
@@ -327,7 +314,7 @@ private:
|
|||||||
BinLogRecord readRecord();
|
BinLogRecord readRecord();
|
||||||
static void parseLog(PIFile *f, BinLogInfo *info, PIVector<BinLogIndex> * index);
|
static void parseLog(PIFile *f, BinLogInfo *info, PIVector<BinLogIndex> * index);
|
||||||
void moveIndex(int i);
|
void moveIndex(int i);
|
||||||
static PIString getLogfilePath(const PIString & log_dir, const PIString & prefix);
|
PIString getLogfilePath() const;
|
||||||
|
|
||||||
PIVector<BinLogIndex> index;
|
PIVector<BinLogIndex> index;
|
||||||
PIMap<llong, int> index_pos;
|
PIMap<llong, int> index_pos;
|
||||||
@@ -344,7 +331,6 @@ private:
|
|||||||
int write_count, split_count, default_id, current_index;
|
int write_count, split_count, default_id, current_index;
|
||||||
bool is_started, is_thread_ok, is_indexed, rapid_start, is_pause;
|
bool is_started, is_thread_ok, is_indexed, rapid_start, is_pause;
|
||||||
PIByteArray user_header;
|
PIByteArray user_header;
|
||||||
std::function<PIString()> f_new_path;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \relatesalso PICout \brief Output operator PIBinaryLog::BinLogInfo to PICout
|
//! \relatesalso PICout \brief Output operator PIBinaryLog::BinLogInfo to PICout
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ int PICAN::readedCANID() const {
|
|||||||
|
|
||||||
PIString PICAN::constructFullPathDevice() const {
|
PIString PICAN::constructFullPathDevice() const {
|
||||||
PIString ret;
|
PIString ret;
|
||||||
ret += path() + ":" + PIString::fromNumber(CANID(), 16);
|
ret << path() << ":" << PIString::fromNumber(CANID(),16);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
class PIP_EXPORT PICAN: public PIIODevice
|
class PIP_EXPORT PICAN: public PIIODevice
|
||||||
{
|
{
|
||||||
PIIODEVICE(PICAN, "can");
|
PIIODEVICE(PICAN, "can")
|
||||||
public:
|
public:
|
||||||
explicit PICAN(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
explicit PICAN(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||||
virtual ~PICAN();
|
virtual ~PICAN();
|
||||||
@@ -41,15 +41,15 @@ public:
|
|||||||
int readedCANID() const;
|
int readedCANID() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool openDevice() override;
|
bool openDevice();
|
||||||
bool closeDevice() override;
|
bool closeDevice();
|
||||||
int readDevice(void * read_to, int max_size) override;
|
int readDevice(void * read_to, int max_size);
|
||||||
int writeDevice(const void * data, int max_size) override;
|
int writeDevice(const void * data, int max_size);
|
||||||
PIString constructFullPathDevice() const override;
|
PIString constructFullPathDevice() const;
|
||||||
void configureFromFullPathDevice(const PIString & full_path) override;
|
void configureFromFullPathDevice(const PIString & full_path);
|
||||||
PIPropertyStorage constructVariantDevice() const override;
|
PIPropertyStorage constructVariantDevice() const;
|
||||||
void configureFromVariantDevice(const PIPropertyStorage & d) override;
|
void configureFromVariantDevice(const PIPropertyStorage & d);
|
||||||
DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Reliable;}
|
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Reliable;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int sock;
|
int sock;
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ PIString PIConfig::_readLineDev() {
|
|||||||
void PIConfig::_writeDev(const PIString & l) {
|
void PIConfig::_writeDev(const PIString & l) {
|
||||||
//piCout << "write \"" << l << "\"";
|
//piCout << "write \"" << l << "\"";
|
||||||
if (!dev) return;
|
if (!dev) return;
|
||||||
if (PIString(dev->className()) == "PIFile") {((PIFile*)dev)->write(l.toUTF8()); return;}
|
if (PIString(dev->className()) == "PIFile") {*((PIFile*)dev) << (l); return;}
|
||||||
if (PIString(dev->className()) == "PIIOString") {((PIIOString*)dev)->writeString(l); return;}
|
if (PIString(dev->className()) == "PIIOString") {((PIIOString*)dev)->writeString(l); return;}
|
||||||
dev->write(l.toByteArray());
|
dev->write(l.toByteArray());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,9 +116,9 @@ PIEthernet::Address::Address(const PIString & _ip, ushort _port) {
|
|||||||
|
|
||||||
PIString PIEthernet::Address::ipString() const {
|
PIString PIEthernet::Address::ipString() const {
|
||||||
PIString ret = PIString::fromNumber(ip_b[0]);
|
PIString ret = PIString::fromNumber(ip_b[0]);
|
||||||
ret += "." + PIString::fromNumber(ip_b[1]);
|
ret << "." << PIString::fromNumber(ip_b[1]);
|
||||||
ret += "." + PIString::fromNumber(ip_b[2]);
|
ret << "." << PIString::fromNumber(ip_b[2]);
|
||||||
ret += "." + PIString::fromNumber(ip_b[3]);
|
ret << "." << PIString::fromNumber(ip_b[3]);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -901,7 +901,7 @@ void PIEthernet::server_func(void * eth) {
|
|||||||
ip += ":" + PIString::fromNumber(htons(client_addr.sin_port));
|
ip += ":" + PIString::fromNumber(htons(client_addr.sin_port));
|
||||||
PIEthernet * e = new PIEthernet(s, ip);
|
PIEthernet * e = new PIEthernet(s, ip);
|
||||||
ce->clients_mutex.lock();
|
ce->clients_mutex.lock();
|
||||||
CONNECT1(void, PIObject *, e, deleted, ce, clientDeleted)
|
CONNECTU(e, deleted, ce, clientDeleted)
|
||||||
ce->clients_ << e;
|
ce->clients_ << e;
|
||||||
ce->clients_mutex.unlock();
|
ce->clients_mutex.unlock();
|
||||||
ce->newConnection(e);
|
ce->newConnection(e);
|
||||||
@@ -930,12 +930,11 @@ void PIEthernet::propertyChanged(const char * name) {
|
|||||||
|
|
||||||
PIString PIEthernet::constructFullPathDevice() const {
|
PIString PIEthernet::constructFullPathDevice() const {
|
||||||
PIString ret;
|
PIString ret;
|
||||||
ret += (type() == PIEthernet::UDP ? "UDP" : "TCP");
|
ret << (type() == PIEthernet::UDP ? "UDP" : "TCP") << ":" << readIP() << ":" << readPort();
|
||||||
ret += ":" + readIP() + ":" + PIString::fromNumber(readPort());
|
|
||||||
if (type() == PIEthernet::UDP) {
|
if (type() == PIEthernet::UDP) {
|
||||||
ret += ":" + sendIP() + ":" + PIString::fromNumber(sendPort());
|
ret << ":" << sendIP() << ":" << sendPort();
|
||||||
piForeachC (PIString & m, multicastGroups())
|
piForeachC (PIString & m, multicastGroups())
|
||||||
ret += ":mcast:" + m;
|
ret << ":mcast:" << m;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class
|
|||||||
|
|
||||||
class PIP_EXPORT PIEthernet: public PIIODevice
|
class PIP_EXPORT PIEthernet: public PIIODevice
|
||||||
{
|
{
|
||||||
PIIODEVICE(PIEthernet, "eth");
|
PIIODEVICE(PIEthernet, "eth")
|
||||||
friend class PIPeer;
|
friend class PIPeer;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -317,9 +317,9 @@ public:
|
|||||||
|
|
||||||
int socket() const {return sock;}
|
int socket() const {return sock;}
|
||||||
|
|
||||||
EVENT1(newConnection, PIEthernet * , client);
|
EVENT1(newConnection, PIEthernet * , client)
|
||||||
EVENT0(connected);
|
EVENT0(connected)
|
||||||
EVENT1(disconnected, bool, withError);
|
EVENT1(disconnected, bool, withError)
|
||||||
|
|
||||||
|
|
||||||
//! Flags of network interface
|
//! Flags of network interface
|
||||||
@@ -462,24 +462,24 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
explicit PIEthernet(int sock, PIString ip_port);
|
explicit PIEthernet(int sock, PIString ip_port);
|
||||||
|
|
||||||
void propertyChanged(const char * name) override;
|
void propertyChanged(const char * name);
|
||||||
|
|
||||||
PIString constructFullPathDevice() const override;
|
PIString constructFullPathDevice() const;
|
||||||
void configureFromFullPathDevice(const PIString & full_path) override;
|
void configureFromFullPathDevice(const PIString & full_path);
|
||||||
PIPropertyStorage constructVariantDevice() const override;
|
PIPropertyStorage constructVariantDevice() const;
|
||||||
void configureFromVariantDevice(const PIPropertyStorage & d) override;
|
void configureFromVariantDevice(const PIPropertyStorage & d);
|
||||||
bool configureDevice(const void * e_main, const void * e_parent = 0) override;
|
bool configureDevice(const void * e_main, const void * e_parent = 0);
|
||||||
int readDevice(void * read_to, int max_size) override;
|
int readDevice(void * read_to, int max_size);
|
||||||
int writeDevice(const void * data, int max_size) override;
|
int writeDevice(const void * data, int max_size);
|
||||||
DeviceInfoFlags deviceInfoFlags() const override;
|
DeviceInfoFlags deviceInfoFlags() const;
|
||||||
|
|
||||||
//! Executes when any read function was successful. Default implementation does nothing
|
//! Executes when any read function was successful. Default implementation does nothing
|
||||||
virtual void received(const void * data, int size) {;}
|
virtual void received(const void * data, int size) {;}
|
||||||
|
|
||||||
void construct();
|
void construct();
|
||||||
bool init() override;
|
bool init();
|
||||||
bool openDevice() override;
|
bool openDevice();
|
||||||
bool closeDevice() override;
|
bool closeDevice();
|
||||||
void closeSocket(int & sd);
|
void closeSocket(int & sd);
|
||||||
void applyTimeouts();
|
void applyTimeouts();
|
||||||
void applyTimeout(int fd, int opt, double ms);
|
void applyTimeout(int fd, int opt, double ms);
|
||||||
|
|||||||
@@ -452,8 +452,7 @@ void PIFile::setPrecision(int prec) {
|
|||||||
|
|
||||||
|
|
||||||
PIFile & PIFile::put(const PIByteArray & v) {
|
PIFile & PIFile::put(const PIByteArray & v) {
|
||||||
int sz = (int)v.size_s();
|
writeBinary((int)v.size_s());
|
||||||
write(createMemoryBlock(&sz));
|
|
||||||
write(v);
|
write(v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -462,7 +461,7 @@ PIFile & PIFile::put(const PIByteArray & v) {
|
|||||||
PIByteArray PIFile::get() {
|
PIByteArray PIFile::get() {
|
||||||
PIByteArray ret;
|
PIByteArray ret;
|
||||||
int sz(0);
|
int sz(0);
|
||||||
read(createMemoryBlock(&sz));
|
read(&sz, sizeof(sz));
|
||||||
if (sz > 0) {
|
if (sz > 0) {
|
||||||
ret.resize(sz);
|
ret.resize(sz);
|
||||||
read(ret.data(), sz);
|
read(ret.data(), sz);
|
||||||
@@ -471,6 +470,156 @@ PIByteArray PIFile::get() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(double v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, ("%" + prec_str + "lf").data(), v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator >>(double & v) {
|
||||||
|
if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%lf", &v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator >>(float & v) {
|
||||||
|
if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%f", &v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator >>(ullong & v) {
|
||||||
|
if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%lln", &v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator >>(ulong & v) {
|
||||||
|
if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%ln", &v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator >>(uint & v) {
|
||||||
|
if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%n", &v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator >>(ushort & v) {
|
||||||
|
if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%hn", &v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator >>(uchar & v) {
|
||||||
|
if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%hhn", &v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator >>(llong & v) {
|
||||||
|
if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%lln", &v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator >>(long & v) {
|
||||||
|
if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%ln", &v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator >>(int & v) {
|
||||||
|
if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%n", &v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator >>(short & v) {
|
||||||
|
if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%hn", &v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator >>(char & v) {
|
||||||
|
if (canRead() && PRIVATE->fd != 0) ret = fscanf(PRIVATE->fd, "%hhn", &v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(float v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, ("%" + prec_str + "f").data(), v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(ullong v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%llu", v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(ulong v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%lu", v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(uint v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%u", v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(ushort v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%hu", v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(uchar v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%u", int(v));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(llong v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%lld", v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(long v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%ld", v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(int v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%d", v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(short v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, "%hd", v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(const PIByteArray & v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) write(v.data(), v.size());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(const char v) {
|
||||||
|
if (canWrite() && PRIVATE->fd != 0) write(&v, 1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int PIFile::readDevice(void * read_to, int max_size) {
|
int PIFile::readDevice(void * read_to, int max_size) {
|
||||||
if (!canRead() || PRIVATE->fd == 0) return -1;
|
if (!canRead() || PRIVATE->fd == 0) return -1;
|
||||||
return fread(read_to, 1, max_size, PRIVATE->fd);
|
return fread(read_to, 1, max_size, PRIVATE->fd);
|
||||||
@@ -483,6 +632,13 @@ int PIFile::writeDevice(const void * data, int max_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile &PIFile::operator <<(const PIString & v) {
|
||||||
|
if (canWrite() && v.isNotEmpty() && PRIVATE->fd != 0)
|
||||||
|
*this << v.toCharset(defaultCharset());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIFile::clear() {
|
void PIFile::clear() {
|
||||||
close();
|
close();
|
||||||
PRIVATE->fd = fopen(path().data(), "w");
|
PRIVATE->fd = fopen(path().data(), "w");
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
//! \~russian Локальный файл.
|
//! \~russian Локальный файл.
|
||||||
class PIP_EXPORT PIFile: public PIIODevice
|
class PIP_EXPORT PIFile: public PIIODevice
|
||||||
{
|
{
|
||||||
PIIODEVICE(PIFile, "file");
|
PIIODEVICE(PIFile, "file")
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! \~english Constructs file with empty path
|
//! \~english Constructs file with empty path
|
||||||
@@ -180,7 +180,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Immediate write all buffered data to disk
|
//! \~english Immediate write all buffered data to disk
|
||||||
//! \~russian Немедленно записывает все буферизированные данные на диск
|
//! \~russian Немедленно записывает все буферизированные данные на диск
|
||||||
void flush() override;
|
void flush();
|
||||||
|
|
||||||
//! \~english Move read/write position to "position"
|
//! \~english Move read/write position to "position"
|
||||||
//! \~russian Перемещает позицию чтения/записи на "position"
|
//! \~russian Перемещает позицию чтения/записи на "position"
|
||||||
@@ -226,8 +226,6 @@ public:
|
|||||||
//! \~english Returns file size in bytes
|
//! \~english Returns file size in bytes
|
||||||
//! \~russian Возвращает размер файла в байтах
|
//! \~russian Возвращает размер файла в байтах
|
||||||
llong size() const;
|
llong size() const;
|
||||||
|
|
||||||
ssize_t bytesAvailable() const override {return size() - pos();}
|
|
||||||
|
|
||||||
//! \~english Returns read/write position
|
//! \~english Returns read/write position
|
||||||
//! \~russian Возвращает позицию чтения/записи
|
//! \~russian Возвращает позицию чтения/записи
|
||||||
@@ -262,6 +260,161 @@ public:
|
|||||||
//! \~russian Читает из файла размер байтового массива и его содержимое (десериализация)
|
//! \~russian Читает из файла размер байтового массива и его содержимое (десериализация)
|
||||||
PIByteArray get();
|
PIByteArray get();
|
||||||
|
|
||||||
|
|
||||||
|
//! \~english Write to file binary content of "v"
|
||||||
|
//! \~russian Пишет в файл байтовое содержимое "v"
|
||||||
|
PIFile & writeBinary(const char v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
|
//! \~english Write to file binary content of "v"
|
||||||
|
//! \~russian Пишет в файл байтовое содержимое "v"
|
||||||
|
PIFile & writeBinary(const short v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
|
//! \~english Write to file binary content of "v"
|
||||||
|
//! \~russian Пишет в файл байтовое содержимое "v"
|
||||||
|
PIFile & writeBinary(const int v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
|
//! \~english Write to file binary content of "v"
|
||||||
|
//! \~russian Пишет в файл байтовое содержимое "v"
|
||||||
|
PIFile & writeBinary(const long v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
|
//! \~english Write to file binary content of "v"
|
||||||
|
//! \~russian Пишет в файл байтовое содержимое "v"
|
||||||
|
PIFile & writeBinary(const llong v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
|
//! \~english Write to file binary content of "v"
|
||||||
|
//! \~russian Пишет в файл байтовое содержимое "v"
|
||||||
|
PIFile & writeBinary(const uchar v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
|
//! \~english Write to file binary content of "v"
|
||||||
|
//! \~russian Пишет в файл байтовое содержимое "v"
|
||||||
|
PIFile & writeBinary(const ushort v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
|
//! \~english Write to file binary content of "v"
|
||||||
|
//! \~russian Пишет в файл байтовое содержимое "v"
|
||||||
|
PIFile & writeBinary(const uint v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
|
//! \~english Write to file binary content of "v"
|
||||||
|
//! \~russian Пишет в файл байтовое содержимое "v"
|
||||||
|
PIFile & writeBinary(const ulong v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
|
//! \~english Write to file binary content of "v"
|
||||||
|
//! \~russian Пишет в файл байтовое содержимое "v"
|
||||||
|
PIFile & writeBinary(const ullong v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
|
//! \~english Write to file binary content of "v"
|
||||||
|
//! \~russian Пишет в файл байтовое содержимое "v"
|
||||||
|
PIFile & writeBinary(const float v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
|
//! \~english Write to file binary content of "v"
|
||||||
|
//! \~russian Пишет в файл байтовое содержимое "v"
|
||||||
|
PIFile & writeBinary(const double v) {write(&v, sizeof(v)); return *this;}
|
||||||
|
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v"
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v"
|
||||||
|
PIFile & operator <<(const char v);
|
||||||
|
|
||||||
|
//! \~english Write to file string "v"
|
||||||
|
//! \~russian Пишет в файл строку "v"
|
||||||
|
PIFile & operator <<(const PIString & v);
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v"
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v"
|
||||||
|
PIFile & operator <<(const PIByteArray & v);
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v"
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v"
|
||||||
|
PIFile & operator <<(short v);
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v"
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v"
|
||||||
|
PIFile & operator <<(int v);
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v"
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v"
|
||||||
|
PIFile & operator <<(long v);
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v"
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v"
|
||||||
|
PIFile & operator <<(llong v);
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v"
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v"
|
||||||
|
PIFile & operator <<(uchar v);
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v"
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v"
|
||||||
|
PIFile & operator <<(ushort v);
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v"
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v"
|
||||||
|
PIFile & operator <<(uint v);
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v"
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v"
|
||||||
|
PIFile & operator <<(ulong v);
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v"
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v"
|
||||||
|
PIFile & operator <<(ullong v);
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v" with precision \a precision()
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v" с точностью \a precision()
|
||||||
|
PIFile & operator <<(float v);
|
||||||
|
|
||||||
|
//! \~english Write to file text representation of "v" with precision \a precision()
|
||||||
|
//! \~russian Пишет в файл текстовое представление "v" с точностью \a precision()
|
||||||
|
PIFile & operator <<(double v);
|
||||||
|
|
||||||
|
|
||||||
|
//! \~english Read from file text representation of "v"
|
||||||
|
//! \~russian Читает из файла текстовое представление "v"
|
||||||
|
PIFile & operator >>(char & v);
|
||||||
|
|
||||||
|
//! \~english Read from file text representation of "v"
|
||||||
|
//! \~russian Читает из файла текстовое представление "v"
|
||||||
|
PIFile & operator >>(short & v);
|
||||||
|
|
||||||
|
//! \~english Read from file text representation of "v"
|
||||||
|
//! \~russian Читает из файла текстовое представление "v"
|
||||||
|
PIFile & operator >>(int & v);
|
||||||
|
|
||||||
|
//! \~english Read from file text representation of "v"
|
||||||
|
//! \~russian Читает из файла текстовое представление "v"
|
||||||
|
PIFile & operator >>(long & v);
|
||||||
|
|
||||||
|
//! \~english Read from file text representation of "v"
|
||||||
|
//! \~russian Читает из файла текстовое представление "v"
|
||||||
|
PIFile & operator >>(llong & v);
|
||||||
|
|
||||||
|
//! \~english Read from file text representation of "v"
|
||||||
|
//! \~russian Читает из файла текстовое представление "v"
|
||||||
|
PIFile & operator >>(uchar & v);
|
||||||
|
|
||||||
|
//! \~english Read from file text representation of "v"
|
||||||
|
//! \~russian Читает из файла текстовое представление "v"
|
||||||
|
PIFile & operator >>(ushort & v);
|
||||||
|
|
||||||
|
//! \~english Read from file text representation of "v"
|
||||||
|
//! \~russian Читает из файла текстовое представление "v"
|
||||||
|
PIFile & operator >>(uint & v);
|
||||||
|
|
||||||
|
//! \~english Read from file text representation of "v"
|
||||||
|
//! \~russian Читает из файла текстовое представление "v"
|
||||||
|
PIFile & operator >>(ulong & v);
|
||||||
|
|
||||||
|
//! \~english Read from file text representation of "v"
|
||||||
|
//! \~russian Читает из файла текстовое представление "v"
|
||||||
|
PIFile & operator >>(ullong & v);
|
||||||
|
|
||||||
|
//! \~english Read from file text representation of "v"
|
||||||
|
//! \~russian Читает из файла текстовое представление "v"
|
||||||
|
PIFile & operator >>(float & v);
|
||||||
|
|
||||||
|
//! \~english Read from file text representation of "v"
|
||||||
|
//! \~russian Читает из файла текстовое представление "v"
|
||||||
|
PIFile & operator >>(double & v);
|
||||||
|
|
||||||
EVENT_HANDLER(void, clear);
|
EVENT_HANDLER(void, clear);
|
||||||
EVENT_HANDLER(void, remove);
|
EVENT_HANDLER(void, remove);
|
||||||
EVENT_HANDLER1(void, resize, llong, new_size) {resize(new_size, 0);}
|
EVENT_HANDLER1(void, resize, llong, new_size) {resize(new_size, 0);}
|
||||||
@@ -326,15 +479,15 @@ public:
|
|||||||
//! \}
|
//! \}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PIString constructFullPathDevice() const override;
|
PIString constructFullPathDevice() const;
|
||||||
void configureFromFullPathDevice(const PIString & full_path) override;
|
void configureFromFullPathDevice(const PIString & full_path);
|
||||||
PIPropertyStorage constructVariantDevice() const override;
|
PIPropertyStorage constructVariantDevice() const;
|
||||||
void configureFromVariantDevice(const PIPropertyStorage & d) override;
|
void configureFromVariantDevice(const PIPropertyStorage & d);
|
||||||
int readDevice(void * read_to, int max_size) override;
|
int readDevice(void * read_to, int max_size);
|
||||||
int writeDevice(const void * data, int max_size) override;
|
int writeDevice(const void * data, int max_size);
|
||||||
bool openDevice() override;
|
bool openDevice();
|
||||||
bool closeDevice() override;
|
bool closeDevice();
|
||||||
DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Sequential | PIIODevice::Reliable;}
|
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Sequential | PIIODevice::Reliable;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PIString strType(const PIIODevice::DeviceMode type);
|
PIString strType(const PIIODevice::DeviceMode type);
|
||||||
@@ -365,19 +518,14 @@ inline PICout operator <<(PICout s, const PIFile::FileInfo & v) {
|
|||||||
//! \relatesalso PIByteArray
|
//! \relatesalso PIByteArray
|
||||||
//! \~english Store operator
|
//! \~english Store operator
|
||||||
//! \~russian Оператор сохранения
|
//! \~russian Оператор сохранения
|
||||||
BINARY_STREAM_WRITE(PIFile::FileInfo) {
|
inline PIByteArray & operator <<(PIByteArray & s, const PIFile::FileInfo & v) {s << v.path << v.size << v.time_access << v.time_modification <<
|
||||||
s << v.path << v.size << v.time_access << v.time_modification <<
|
(int)v.flags << v.id_user << v.id_group << v.perm_user.raw << v.perm_group.raw << v.perm_other.raw; return s;}
|
||||||
v.flags << v.id_user << v.id_group << v.perm_user.raw << v.perm_group.raw << v.perm_other.raw;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \relatesalso PIByteArray
|
//! \relatesalso PIByteArray
|
||||||
//! \~english Restore operator
|
//! \~english Restore operator
|
||||||
//! \~russian Оператор извлечения
|
//! \~russian Оператор извлечения
|
||||||
BINARY_STREAM_READ(PIFile::FileInfo) {
|
inline PIByteArray & operator >>(PIByteArray & s, PIFile::FileInfo & v) {s >> v.path >> v.size >> v.time_access >> v.time_modification >>
|
||||||
s >> v.path >> v.size >> v.time_access >> v.time_modification >>
|
*(int*)(&(v.flags)) >> v.id_user >> v.id_group >> v.perm_user.raw >> v.perm_group.raw >> v.perm_other.raw; return s;}
|
||||||
v.flags >> v.id_user >> v.id_group >> v.perm_user.raw >> v.perm_group.raw >> v.perm_other.raw;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // PIFILE_H
|
#endif // PIFILE_H
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
//! \~russian Поддержка GPIO.
|
//! \~russian Поддержка GPIO.
|
||||||
class PIP_EXPORT PIGPIO: public PIThread
|
class PIP_EXPORT PIGPIO: public PIThread
|
||||||
{
|
{
|
||||||
PIOBJECT_SUBCLASS(PIGPIO, PIThread);
|
PIOBJECT_SUBCLASS(PIGPIO, PIThread)
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! \~english Work mode for pin
|
//! \~english Work mode for pin
|
||||||
@@ -82,7 +82,7 @@ public:
|
|||||||
//! \~russian Заканчивает наблюдение за всеми пинами
|
//! \~russian Заканчивает наблюдение за всеми пинами
|
||||||
void clearWatch();
|
void clearWatch();
|
||||||
|
|
||||||
EVENT2(pinChanged, int, gpio_num, bool, new_value);
|
EVENT2(pinChanged, int, gpio_num, bool, new_value)
|
||||||
|
|
||||||
//! \events
|
//! \events
|
||||||
//! \{
|
//! \{
|
||||||
@@ -100,7 +100,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
PIGPIO();
|
PIGPIO();
|
||||||
virtual ~PIGPIO();
|
virtual ~PIGPIO();
|
||||||
NO_COPY_CLASS(PIGPIO);
|
NO_COPY_CLASS(PIGPIO)
|
||||||
|
|
||||||
struct PIP_EXPORT GPIOData {
|
struct PIP_EXPORT GPIOData {
|
||||||
GPIOData() {dir = PIGPIO::In; num = fd = -1;}
|
GPIOData() {dir = PIGPIO::In; num = fd = -1;}
|
||||||
@@ -112,9 +112,9 @@ private:
|
|||||||
void exportGPIO(int gpio_num);
|
void exportGPIO(int gpio_num);
|
||||||
void openGPIO(GPIOData & g);
|
void openGPIO(GPIOData & g);
|
||||||
bool getPinState(int gpio_num);
|
bool getPinState(int gpio_num);
|
||||||
void begin() override;
|
void begin();
|
||||||
void run() override;
|
void run();
|
||||||
void end() override;
|
void end();
|
||||||
|
|
||||||
static PIString GPIOName(int gpio_num);
|
static PIString GPIOName(int gpio_num);
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
//! \~russian Обёртка PIIODevice вокруг PIByteArray
|
//! \~russian Обёртка PIIODevice вокруг PIByteArray
|
||||||
class PIP_EXPORT PIIOByteArray: public PIIODevice
|
class PIP_EXPORT PIIOByteArray: public PIIODevice
|
||||||
{
|
{
|
||||||
PIIODEVICE(PIIOByteArray, "");
|
PIIODEVICE(PIIOByteArray, "")
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! \~english Contructs %PIIOByteArray with "buffer" content and "mode" open mode
|
//! \~english Contructs %PIIOByteArray with "buffer" content and "mode" open mode
|
||||||
@@ -83,17 +83,12 @@ public:
|
|||||||
//! \~english Insert data "ba" into content at current position
|
//! \~english Insert data "ba" into content at current position
|
||||||
//! \~russian Вставляет данные "ba" в содержимое буфера в текущую позицию
|
//! \~russian Вставляет данные "ba" в содержимое буфера в текущую позицию
|
||||||
int writeByteArray(const PIByteArray & ba);
|
int writeByteArray(const PIByteArray & ba);
|
||||||
|
|
||||||
ssize_t bytesAvailable() const override {
|
|
||||||
if (data_) return data_->size();
|
|
||||||
else return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool openDevice() override;
|
bool openDevice();
|
||||||
int readDevice(void * read_to, int size) override;
|
int readDevice(void * read_to, int size);
|
||||||
int writeDevice(const void * data_, int size) override;
|
int writeDevice(const void * data_, int size);
|
||||||
DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Sequential | PIIODevice::Reliable;}
|
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Sequential | PIIODevice::Reliable;}
|
||||||
|
|
||||||
ssize_t pos;
|
ssize_t pos;
|
||||||
PIByteArray * data_;
|
PIByteArray * data_;
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ bool PIIODevice::setOption(PIIODevice::DeviceOption o, bool yes) {
|
|||||||
//! после каждого успешного потокового чтения. Метод должен быть
|
//! после каждого успешного потокового чтения. Метод должен быть
|
||||||
//! в формате "bool func(void * data, uchar * readed, int size)"
|
//! в формате "bool func(void * data, uchar * readed, int size)"
|
||||||
void PIIODevice::setThreadedReadSlot(ReadRetFunc func) {
|
void PIIODevice::setThreadedReadSlot(ReadRetFunc func) {
|
||||||
func_read = func;
|
ret_func_ = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -230,7 +230,8 @@ void PIIODevice::stop(bool hard) {
|
|||||||
PIByteArray PIIODevice::read(int max_size) {
|
PIByteArray PIIODevice::read(int max_size) {
|
||||||
buffer_in.resize(max_size);
|
buffer_in.resize(max_size);
|
||||||
int ret = readDevice(buffer_in.data(), max_size);
|
int ret = readDevice(buffer_in.data(), max_size);
|
||||||
if (ret < 0) return PIByteArray();
|
if (ret < 0)
|
||||||
|
return PIByteArray();
|
||||||
return buffer_in.resized(ret);
|
return buffer_in.resized(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,8 +239,8 @@ PIByteArray PIIODevice::read(int max_size) {
|
|||||||
void PIIODevice::_init() {
|
void PIIODevice::_init() {
|
||||||
opened_ = init_ = thread_started_ = false;
|
opened_ = init_ = thread_started_ = false;
|
||||||
raise_threaded_read_ = true;
|
raise_threaded_read_ = true;
|
||||||
func_read = nullptr;
|
ret_func_ = 0;
|
||||||
ret_data_ = nullptr;
|
ret_data_ = 0;
|
||||||
tri = 0;
|
tri = 0;
|
||||||
setOptions(0);
|
setOptions(0);
|
||||||
setReopenEnabled(true);
|
setReopenEnabled(true);
|
||||||
@@ -595,9 +596,9 @@ PIMap<PIConstChars, PIIODevice::FabricInfo> & PIIODevice::fabrics() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIIODevice::threadedRead(const uchar *readed, int size) {
|
bool PIIODevice::threadedRead(uchar *readed, int size) {
|
||||||
// piCout << "iodevice threaded read";
|
// piCout << "iodevice threaded read";
|
||||||
if (func_read != 0) return func_read(readed, size, ret_data_);
|
if (ret_func_ != 0) return ret_func_(ret_data_, readed, size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,9 +30,9 @@
|
|||||||
#include "pitimer.h"
|
#include "pitimer.h"
|
||||||
#include "piqueue.h"
|
#include "piqueue.h"
|
||||||
|
|
||||||
/// TODO: написать документацию, тут ничего не понятно
|
|
||||||
// function executed from threaded read, pass readedData, sizeOfData, ThreadedReadData
|
// function executed from threaded read, pass ThreadedReadData, readedData, sizeOfData
|
||||||
typedef bool (*ReadRetFunc)(const uchar *, int, void *);
|
typedef bool (*ReadRetFunc)(void * , uchar * , int );
|
||||||
|
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
#ifdef DOXYGEN
|
||||||
@@ -64,9 +64,9 @@ typedef bool (*ReadRetFunc)(const uchar *, int, void *);
|
|||||||
|
|
||||||
# define PIIODEVICE(name, prefix) \
|
# define PIIODEVICE(name, prefix) \
|
||||||
PIOBJECT_SUBCLASS(name, PIIODevice) \
|
PIOBJECT_SUBCLASS(name, PIIODevice) \
|
||||||
PIIODevice * copy() const override {return new name();} \
|
PIIODevice * copy() const {return new name();} \
|
||||||
public: \
|
public: \
|
||||||
PIConstChars fullPathPrefix() const override {return prefix;} \
|
virtual PIConstChars fullPathPrefix() const {return prefix;} \
|
||||||
static PIConstChars fullPathPrefixS() {return prefix;} \
|
static PIConstChars fullPathPrefixS() {return prefix;} \
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -79,10 +79,10 @@ typedef bool (*ReadRetFunc)(const uchar *, int, void *);
|
|||||||
//! \~russian Базовый класс утройств ввода/вывода.
|
//! \~russian Базовый класс утройств ввода/вывода.
|
||||||
class PIP_EXPORT PIIODevice: public PIThread
|
class PIP_EXPORT PIIODevice: public PIThread
|
||||||
{
|
{
|
||||||
PIOBJECT_SUBCLASS(PIIODevice, PIThread);
|
PIOBJECT_SUBCLASS(PIIODevice, PIThread)
|
||||||
friend void __DevicePool_threadReadDP(void * ddp);
|
friend void __DevicePool_threadReadDP(void * ddp);
|
||||||
public:
|
public:
|
||||||
NO_COPY_CLASS(PIIODevice);
|
NO_COPY_CLASS(PIIODevice)
|
||||||
|
|
||||||
//! \~english Constructs a empty %PIIODevice
|
//! \~english Constructs a empty %PIIODevice
|
||||||
//! \~russian Создает пустой %PIIODevice
|
//! \~russian Создает пустой %PIIODevice
|
||||||
@@ -239,7 +239,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Start threaded read and assign threaded read callback to "func"
|
//! \~english Start threaded read and assign threaded read callback to "func"
|
||||||
//! \~russian Запускает потоковое чтение и устанавливает callback потокового чтения в "func"
|
//! \~russian Запускает потоковое чтение и устанавливает callback потокового чтения в "func"
|
||||||
void startThreadedRead(ReadRetFunc func) {func_read = func; startThreadedRead();}
|
void startThreadedRead(ReadRetFunc func) {ret_func_ = func; startThreadedRead();}
|
||||||
|
|
||||||
//! \~english Stop threaded read. Hard stop terminate thread, otherwise wait fo 10 seconds
|
//! \~english Stop threaded read. Hard stop terminate thread, otherwise wait fo 10 seconds
|
||||||
//! \~russian Останавливает потоковое чтение. Жесткая остановка убивает поток, иначе ожидает 10 секунд
|
//! \~russian Останавливает потоковое чтение. Жесткая остановка убивает поток, иначе ожидает 10 секунд
|
||||||
@@ -276,25 +276,10 @@ public:
|
|||||||
//! \~russian Читает из устройства не более "max_size" байт в "read_to"
|
//! \~russian Читает из устройства не более "max_size" байт в "read_to"
|
||||||
int read(void * read_to, int max_size) {return readDevice(read_to, max_size);}
|
int read(void * read_to, int max_size) {return readDevice(read_to, max_size);}
|
||||||
|
|
||||||
//! \~english Read from device to memory block "mb"
|
|
||||||
//! \~russian Читает из устройства в блок памяти "mb"
|
|
||||||
int read(PIMemoryBlock mb) {return readDevice(mb.data(), mb.size());}
|
|
||||||
|
|
||||||
//! \~english Read from device maximum "max_size" bytes and returns them as PIByteArray
|
//! \~english Read from device maximum "max_size" bytes and returns them as PIByteArray
|
||||||
//! \~russian Читает из устройства не более "max_size" байт и возвращает данные как PIByteArray
|
//! \~russian Читает из устройства не более "max_size" байт и возвращает данные как PIByteArray
|
||||||
PIByteArray read(int max_size);
|
PIByteArray read(int max_size);
|
||||||
|
|
||||||
//! \~english Returns the number of bytes that are available for reading.
|
|
||||||
//! \~russian Возвращает количество байт доступных для чтения
|
|
||||||
//! \~\details
|
|
||||||
//! \~english This function is commonly used with sequential devices
|
|
||||||
//! to determine the number of bytes to allocate in a buffer before reading.
|
|
||||||
//! If function returns -1 it mean that number of bytes undefined.
|
|
||||||
//! \~russian Эта функция как правило используется чтобы знать какой
|
|
||||||
//! размер буфера нужен в памяти для чтения.
|
|
||||||
//! Если функция возвращает -1 это значит что количество байт для чтения не известно.
|
|
||||||
virtual ssize_t bytesAvailable() const {return -1;}
|
|
||||||
|
|
||||||
//! \~english Write maximum "max_size" bytes of "data" to device
|
//! \~english Write maximum "max_size" bytes of "data" to device
|
||||||
//! \~russian Пишет в устройство не более "max_size" байт из "data"
|
//! \~russian Пишет в устройство не более "max_size" байт из "data"
|
||||||
int write(const void * data, int max_size) {return writeDevice(data, max_size);}
|
int write(const void * data, int max_size) {return writeDevice(data, max_size);}
|
||||||
@@ -372,16 +357,12 @@ public:
|
|||||||
EVENT_HANDLER(bool, close);
|
EVENT_HANDLER(bool, close);
|
||||||
EVENT_HANDLER1(int, write, PIByteArray, data);
|
EVENT_HANDLER1(int, write, PIByteArray, data);
|
||||||
|
|
||||||
//! \~english Write memory block "mb" to device
|
|
||||||
//! \~russian Пишет в устройство блок памяти "mb"
|
|
||||||
int write(const PIMemoryBlock & mb) {return write(mb.data(), mb.size());}
|
|
||||||
|
|
||||||
EVENT_VHANDLER(void, flush) {;}
|
EVENT_VHANDLER(void, flush) {;}
|
||||||
|
|
||||||
EVENT(opened);
|
EVENT(opened)
|
||||||
EVENT(closed);
|
EVENT(closed)
|
||||||
EVENT2(threadedReadEvent, const uchar * , readed, int, size);
|
EVENT2(threadedReadEvent, uchar * , readed, int, size)
|
||||||
EVENT2(threadedWriteEvent, ullong, id, int, written_size);
|
EVENT2(threadedWriteEvent, ullong, id, int, written_size)
|
||||||
|
|
||||||
//! \handlers
|
//! \handlers
|
||||||
//! \{
|
//! \{
|
||||||
@@ -430,7 +411,7 @@ public:
|
|||||||
//! \~english Raise if succesfull close
|
//! \~english Raise if succesfull close
|
||||||
//! \~russian Вызывается при успешном закрытии
|
//! \~russian Вызывается при успешном закрытии
|
||||||
|
|
||||||
//! \fn void threadedReadEvent(const uchar * readed, int size)
|
//! \fn void threadedReadEvent(uchar * readed, int size)
|
||||||
//! \~english Raise if read thread succesfull read some data
|
//! \~english Raise if read thread succesfull read some data
|
||||||
//! \~russian Вызывается при успешном потоковом чтении данных
|
//! \~russian Вызывается при успешном потоковом чтении данных
|
||||||
|
|
||||||
@@ -486,7 +467,7 @@ protected:
|
|||||||
|
|
||||||
//! \~english Function executed when thread read some data, default implementation execute external callback "ret_func_"
|
//! \~english Function executed when thread read some data, default implementation execute external callback "ret_func_"
|
||||||
//! \~russian Метод вызывается после каждого успешного потокового чтения, по умолчанию вызывает callback "ret_func_"
|
//! \~russian Метод вызывается после каждого успешного потокового чтения, по умолчанию вызывает callback "ret_func_"
|
||||||
virtual bool threadedRead(const uchar * readed, int size);
|
virtual bool threadedRead(uchar * readed, int size);
|
||||||
|
|
||||||
//! \~english Reimplement to construct full unambiguous string, describes this device.
|
//! \~english Reimplement to construct full unambiguous string, describes this device.
|
||||||
//! Default implementation returns \a path()
|
//! Default implementation returns \a path()
|
||||||
@@ -539,7 +520,7 @@ protected:
|
|||||||
|
|
||||||
DeviceMode mode_;
|
DeviceMode mode_;
|
||||||
DeviceOptions options_;
|
DeviceOptions options_;
|
||||||
ReadRetFunc func_read;
|
ReadRetFunc ret_func_;
|
||||||
bool opened_;
|
bool opened_;
|
||||||
void * ret_data_;
|
void * ret_data_;
|
||||||
|
|
||||||
@@ -547,12 +528,12 @@ private:
|
|||||||
EVENT_HANDLER2(void, check_start, void * , data, int, delim);
|
EVENT_HANDLER2(void, check_start, void * , data, int, delim);
|
||||||
EVENT_HANDLER(void, write_func);
|
EVENT_HANDLER(void, write_func);
|
||||||
|
|
||||||
virtual PIIODevice * copy() const {return nullptr;}
|
virtual PIIODevice * copy() const {return 0;}
|
||||||
PIString fullPathOptions() const;
|
PIString fullPathOptions() const;
|
||||||
void _init();
|
void _init();
|
||||||
void begin() override;
|
void begin();
|
||||||
void run() override;
|
void run();
|
||||||
void end() override {terminate();}
|
void end() {terminate();}
|
||||||
static void cacheFullPath(const PIString & full_path, const PIIODevice * d);
|
static void cacheFullPath(const PIString & full_path, const PIIODevice * d);
|
||||||
static PIMap<PIConstChars, FabricInfo> & fabrics();
|
static PIMap<PIConstChars, FabricInfo> & fabrics();
|
||||||
|
|
||||||
|
|||||||
@@ -1,104 +0,0 @@
|
|||||||
/*! \file piiostream.h
|
|
||||||
* \ingroup IO
|
|
||||||
* \~\brief
|
|
||||||
* \~english PIBinaryStream functionality for PIIODevice
|
|
||||||
* \~russian Функциональность PIBinaryStream для PIIODevice
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
PIP - Platform Independent Primitives
|
|
||||||
PIBinaryStream functionality for PIIODevice
|
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PIIOSTREAM_H
|
|
||||||
#define PIIOSTREAM_H
|
|
||||||
|
|
||||||
#include "piiostring.h"
|
|
||||||
#include "pitextstream.h"
|
|
||||||
|
|
||||||
|
|
||||||
//! \ingroup IO
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english PIBinaryStream functionality for PIIODevice.
|
|
||||||
//! \~russian Функциональность PIBinaryStream для PIIODevice.
|
|
||||||
class PIP_EXPORT PIIOBinaryStream: public PIBinaryStream<PIIOBinaryStream> {
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! \~english Contructs %PIIOBinaryStream for "device" device
|
|
||||||
//! \~russian Создает %PIIOBinaryStream для устройства "device"
|
|
||||||
PIIOBinaryStream(PIIODevice * device = nullptr): dev(device) {}
|
|
||||||
|
|
||||||
//! \~english Assign "device" device
|
|
||||||
//! \~russian Назначает устройство "device"
|
|
||||||
void setDevice(PIIODevice * device) {dev = device;}
|
|
||||||
|
|
||||||
bool binaryStreamAppendImp(const void * d, size_t s) {
|
|
||||||
if (!dev) return false;
|
|
||||||
return (dev->write(d, s) == (int)s);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool binaryStreamTakeImp(void * d, size_t s) {
|
|
||||||
if (!dev) return false;
|
|
||||||
return (dev->read(d, s) == (int)s);
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t binaryStreamSizeImp() const {
|
|
||||||
if (!dev) return 0;
|
|
||||||
return dev->bytesAvailable();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PIIODevice * dev;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//! \ingroup IO
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english PITextStream functionality for PIIODevice.
|
|
||||||
//! \~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) {}
|
|
||||||
|
|
||||||
//! \~english Contructs %PIIOTextStream for "string" string
|
|
||||||
//! \~russian Создает %PIIOTextStream для строки "string"
|
|
||||||
PIIOTextStream(PIString * string): PITextStream<PIIOBinaryStream>(&bin_stream) {
|
|
||||||
io_string = new PIIOString(string);
|
|
||||||
bin_stream.setDevice(io_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
~PIIOTextStream() {
|
|
||||||
if (io_string)
|
|
||||||
delete io_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDevice(PIIODevice * device) {
|
|
||||||
bin_stream = PIIOBinaryStream(device);
|
|
||||||
setStream(&bin_stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PIIOString * io_string = nullptr;
|
|
||||||
PIIOBinaryStream bin_stream;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // PIIOSTREAM_H
|
|
||||||
@@ -56,9 +56,9 @@ bool PIIOString::open(const PIString & string) {
|
|||||||
PIString PIIOString::readLine() {
|
PIString PIIOString::readLine() {
|
||||||
if (!canRead() || !str) return PIString();
|
if (!canRead() || !str) return PIString();
|
||||||
int np = pos;
|
int np = pos;
|
||||||
while (++np < str->size_s()) {
|
while (++np < str->size_s())
|
||||||
if ((*str)[np] == '\n') break;
|
if ((*str)[np] == '\n')
|
||||||
}
|
break;
|
||||||
PIString ret = str->mid(pos, np - pos);
|
PIString ret = str->mid(pos, np - pos);
|
||||||
pos = piMini(np + 1, str->size_s());
|
pos = piMini(np + 1, str->size_s());
|
||||||
return ret;
|
return ret;
|
||||||
@@ -66,7 +66,7 @@ PIString PIIOString::readLine() {
|
|||||||
|
|
||||||
|
|
||||||
int PIIOString::readDevice(void * read_to, int max_size) {
|
int PIIOString::readDevice(void * read_to, int max_size) {
|
||||||
if (!canRead() || !str || max_size <= 0) return -1;
|
if (!canRead() || !str) return -1;
|
||||||
PIString rs = str->mid(pos, max_size);
|
PIString rs = str->mid(pos, max_size);
|
||||||
pos += max_size;
|
pos += max_size;
|
||||||
if (pos > str->size_s()) pos = str->size_s();
|
if (pos > str->size_s()) pos = str->size_s();
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
//! \~russian Обёртка PIIODevice вокруг PIString.
|
//! \~russian Обёртка PIIODevice вокруг PIString.
|
||||||
class PIP_EXPORT PIIOString: public PIIODevice
|
class PIP_EXPORT PIIOString: public PIIODevice
|
||||||
{
|
{
|
||||||
PIIODEVICE(PIIOString, "");
|
PIIODEVICE(PIIOString, "")
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! \~english Contructs %PIIOString with "string" content and "mode" open mode
|
//! \~english Contructs %PIIOString with "string" content and "mode" open mode
|
||||||
@@ -88,16 +88,11 @@ public:
|
|||||||
//! \~russian Вставляет строку "string" в содержимое буфера в текущую позицию
|
//! \~russian Вставляет строку "string" в содержимое буфера в текущую позицию
|
||||||
int writeString(const PIString & string);
|
int writeString(const PIString & string);
|
||||||
|
|
||||||
ssize_t bytesAvailable() const override {
|
|
||||||
if (str) return str->size() - pos;
|
|
||||||
else return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool openDevice() override;
|
bool openDevice();
|
||||||
int readDevice(void * read_to, int max_size) override;
|
int readDevice(void * read_to, int max_size);
|
||||||
int writeDevice(const void * data, int max_size) override;
|
int writeDevice(const void * data, int max_size);
|
||||||
DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Sequential | PIIODevice::Reliable;}
|
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Sequential | PIIODevice::Reliable;}
|
||||||
|
|
||||||
ssize_t pos;
|
ssize_t pos;
|
||||||
PIString * str;
|
PIString * str;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
#define _PIPEER_PING_TIMEOUT 5.0
|
#define _PIPEER_PING_TIMEOUT 5.0
|
||||||
|
|
||||||
class PIPeer::PeerData: public PIObject {
|
class PIPeer::PeerData: public PIObject {
|
||||||
PIOBJECT_SUBCLASS(PeerData, PIObject);
|
PIOBJECT_SUBCLASS(PeerData, PIObject)
|
||||||
public:
|
public:
|
||||||
PeerData(const PIString & n);
|
PeerData(const PIString & n);
|
||||||
~PeerData();
|
~PeerData();
|
||||||
@@ -45,8 +45,8 @@ public:
|
|||||||
EVENT_HANDLER1(void, dtReceiveFinishedIn, bool, ok) {if (ok) received(name(), dt_in.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, dtReceiveFinishedOut, bool, ok) {if (ok) received(name(), dt_out.data());}
|
||||||
EVENT_HANDLER(void, dtThread);
|
EVENT_HANDLER(void, dtThread);
|
||||||
EVENT2(received, const PIString &, from, const PIByteArray &, data);
|
EVENT2(received, const PIString &, from, const PIByteArray &, data)
|
||||||
EVENT2(sendRequest, const PIString &, to, const PIByteArray &, data);
|
EVENT2(sendRequest, const PIString &, to, const PIByteArray &, data)
|
||||||
bool send(const PIByteArray & d);
|
bool send(const PIByteArray & d);
|
||||||
void receivedPacket(uchar type, const PIByteArray & d);
|
void receivedPacket(uchar type, const PIByteArray & d);
|
||||||
void setDist(int dist);
|
void setDist(int dist);
|
||||||
@@ -61,11 +61,11 @@ PIPeer::PeerData::PeerData(const PIString & n): PIObject(n) {
|
|||||||
dt_out.setPacketSize(_PIPEER_MSG_SIZE);
|
dt_out.setPacketSize(_PIPEER_MSG_SIZE);
|
||||||
dt_in.setCRCEnabled(false);
|
dt_in.setCRCEnabled(false);
|
||||||
dt_out.setCRCEnabled(false);
|
dt_out.setCRCEnabled(false);
|
||||||
CONNECT1(void, PIByteArray &, &dt_in, sendRequest, this, dtSendRequestIn);
|
CONNECTU(&dt_in, sendRequest, this, dtSendRequestIn)
|
||||||
CONNECT1(void, PIByteArray &, &dt_out, sendRequest, this, dtSendRequestOut);
|
CONNECTU(&dt_out, sendRequest, this, dtSendRequestOut)
|
||||||
CONNECT1(void, bool, &dt_in, receiveFinished, this, dtReceiveFinishedIn);
|
CONNECTU(&dt_in, receiveFinished, this, dtReceiveFinishedIn)
|
||||||
CONNECT1(void, bool, &dt_out, receiveFinished, this, dtReceiveFinishedOut);
|
CONNECTU(&dt_out, receiveFinished, this, dtReceiveFinishedOut)
|
||||||
CONNECT0(void, &t, started, this, dtThread);
|
CONNECTU(&t, started, this, dtThread)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ PIPeer::PIPeer(const PIString & n): PIIODevice(), inited__(false), eth_tcp_srv(P
|
|||||||
self_info.dist = 0;
|
self_info.dist = 0;
|
||||||
self_info.time = PISystemTime::current();
|
self_info.time = PISystemTime::current();
|
||||||
randomize();
|
randomize();
|
||||||
CONNECT2(void, void *, int, &sync_timer, tickEvent, this, timerEvent);
|
CONNECTU(&sync_timer, tickEvent, this, timerEvent);
|
||||||
prev_ifaces = PIEthernet::interfaces();
|
prev_ifaces = PIEthernet::interfaces();
|
||||||
no_timer = false;
|
no_timer = false;
|
||||||
sync_timer.addDelimiter(5);
|
sync_timer.addDelimiter(5);
|
||||||
@@ -247,7 +247,7 @@ void PIPeer::initEths(PIStringList al) {
|
|||||||
eths_traffic << ce;
|
eths_traffic << ce;
|
||||||
cint = prev_ifaces.getByAddress(a);
|
cint = prev_ifaces.getByAddress(a);
|
||||||
self_info.addresses << PeerInfo::PeerAddress(ce->path(), cint == 0 ? "255.255.255.0" : cint->netmask);
|
self_info.addresses << PeerInfo::PeerAddress(ce->path(), cint == 0 ? "255.255.255.0" : cint->netmask);
|
||||||
CONNECT2(void, const uchar *, int, ce, threadedReadEvent, this, dataRead);
|
CONNECTU(ce, threadedReadEvent, this, dataRead);
|
||||||
ce->startThreadedRead();
|
ce->startThreadedRead();
|
||||||
// piCoutObj << "dc binded to" << ce->path();
|
// piCoutObj << "dc binded to" << ce->path();
|
||||||
// piCoutObj << "add eth" << a;
|
// piCoutObj << "add eth" << a;
|
||||||
@@ -282,7 +282,7 @@ void PIPeer::initMBcasts(PIStringList al) {
|
|||||||
ce->joinMulticastGroup(_PIPEER_MULTICAST_IP);
|
ce->joinMulticastGroup(_PIPEER_MULTICAST_IP);
|
||||||
if (ce->open()) {
|
if (ce->open()) {
|
||||||
eths_mcast << ce;
|
eths_mcast << ce;
|
||||||
CONNECT2(void, const uchar *, int, ce, threadedReadEvent, this, mbcastRead);
|
CONNECTU(ce, threadedReadEvent, this, mbcastRead);
|
||||||
ce->startThreadedRead();
|
ce->startThreadedRead();
|
||||||
// piCout << "mcast bind to" << a << ce->sendIP();
|
// piCout << "mcast bind to" << a << ce->sendIP();
|
||||||
} else {
|
} else {
|
||||||
@@ -302,7 +302,7 @@ void PIPeer::initMBcasts(PIStringList al) {
|
|||||||
ce->setReadAddress(a, _PIPEER_BROADCAST_PORT);
|
ce->setReadAddress(a, _PIPEER_BROADCAST_PORT);
|
||||||
if (ce->open()) {
|
if (ce->open()) {
|
||||||
eths_bcast << ce;
|
eths_bcast << ce;
|
||||||
CONNECT2(void, const uchar *, int, ce, threadedReadEvent, this, mbcastRead);
|
CONNECTU(ce, threadedReadEvent, this, mbcastRead);
|
||||||
ce->startThreadedRead();
|
ce->startThreadedRead();
|
||||||
// piCout << "mc BC try" << a << nm << ce->sendIP();
|
// piCout << "mc BC try" << a << nm << ce->sendIP();
|
||||||
// piCout << "bcast bind to" << a << nm;
|
// piCout << "bcast bind to" << a << nm;
|
||||||
@@ -319,7 +319,7 @@ void PIPeer::initMBcasts(PIStringList al) {
|
|||||||
eth_lo.setReadAddress("127.0.0.1", p);
|
eth_lo.setReadAddress("127.0.0.1", p);
|
||||||
if (eth_lo.open()) {
|
if (eth_lo.open()) {
|
||||||
eth_lo.setSendIP("127.0.0.1");
|
eth_lo.setSendIP("127.0.0.1");
|
||||||
CONNECT2(void, const uchar *, int, ð_lo, threadedReadEvent, this, mbcastRead);
|
CONNECTU(ð_lo, threadedReadEvent, this, mbcastRead);
|
||||||
eth_lo.startThreadedRead();
|
eth_lo.startThreadedRead();
|
||||||
// piCout << "lo binded to" << eth_lo.readAddress() << eth_lo.sendAddress();
|
// piCout << "lo binded to" << eth_lo.readAddress() << eth_lo.sendAddress();
|
||||||
//piCout << "add eth" << ta;
|
//piCout << "add eth" << ta;
|
||||||
@@ -330,13 +330,13 @@ void PIPeer::initMBcasts(PIStringList al) {
|
|||||||
eth_tcp_srv.init();
|
eth_tcp_srv.init();
|
||||||
eth_tcp_srv.listen("0.0.0.0", _PIPEER_TCP_PORT, true);
|
eth_tcp_srv.listen("0.0.0.0", _PIPEER_TCP_PORT, true);
|
||||||
eth_tcp_srv.setDebug(false);
|
eth_tcp_srv.setDebug(false);
|
||||||
CONNECT1(void, PIEthernet *, ð_tcp_srv, newConnection, this, newTcpClient);
|
CONNECTU(ð_tcp_srv, newConnection, this, newTcpClient);
|
||||||
eth_tcp_srv.startThreadedRead();
|
eth_tcp_srv.startThreadedRead();
|
||||||
eth_tcp_cli.setName("__S__PIPeer_eth_TCP_Client");
|
eth_tcp_cli.setName("__S__PIPeer_eth_TCP_Client");
|
||||||
eth_tcp_cli.init();
|
eth_tcp_cli.init();
|
||||||
eth_tcp_cli.setDebug(false);
|
eth_tcp_cli.setDebug(false);
|
||||||
tcpClientReconnect();
|
tcpClientReconnect();
|
||||||
CONNECT2(void, const uchar *, int, ð_tcp_cli, threadedReadEvent, this, mbcastRead);
|
CONNECTU(ð_tcp_cli, threadedReadEvent, this, mbcastRead);
|
||||||
CONNECTU(ð_tcp_cli, disconnected, this, tcpClientReconnect);
|
CONNECTU(ð_tcp_cli, disconnected, this, tcpClientReconnect);
|
||||||
eth_tcp_cli.startThreadedRead();
|
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!";
|
||||||
@@ -444,7 +444,7 @@ void PIPeer::dtReceived(const PIString & from, const PIByteArray & data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIPeer::dataRead(const uchar * readed, int size) {
|
bool PIPeer::dataRead(uchar * readed, int size) {
|
||||||
if (destroyed) {
|
if (destroyed) {
|
||||||
//piCout << "[PIPeer] SegFault";
|
//piCout << "[PIPeer] SegFault";
|
||||||
return true;
|
return true;
|
||||||
@@ -561,7 +561,7 @@ bool PIPeer::dataRead(const uchar * readed, int size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIPeer::mbcastRead(const uchar * data, int size) {
|
bool PIPeer::mbcastRead(uchar * data, int size) {
|
||||||
if (destroyed) {
|
if (destroyed) {
|
||||||
//piCout << "[PIPeer] SegFault";
|
//piCout << "[PIPeer] SegFault";
|
||||||
return true;
|
return true;
|
||||||
@@ -573,7 +573,7 @@ bool PIPeer::mbcastRead(const uchar * data, int size) {
|
|||||||
if (type <= 0 || type >= 4) return true;
|
if (type <= 0 || type >= 4) return true;
|
||||||
PeerInfo pi;
|
PeerInfo pi;
|
||||||
ba >> pi.name;
|
ba >> pi.name;
|
||||||
//piCout << "received mb from" << pi.name << "packet" << type;
|
// piCoutObj << "received mb from" << pi.name << "packet" << type;
|
||||||
if (pi.name == self_info.name) return true;
|
if (pi.name == self_info.name) return true;
|
||||||
PIMutexLocker locker(mc_mutex);
|
PIMutexLocker locker(mc_mutex);
|
||||||
diag_s.received(size);
|
diag_s.received(size);
|
||||||
@@ -765,8 +765,8 @@ void PIPeer::addPeer(const PIPeer::PeerInfo & pd) {
|
|||||||
peers << pd;
|
peers << pd;
|
||||||
PeerInfo & p(peers.back());
|
PeerInfo & p(peers.back());
|
||||||
p.init();
|
p.init();
|
||||||
CONNECT2(void, const PIString &, const PIByteArray &, p._data, sendRequest, this, sendInternal)
|
CONNECTU(p._data, sendRequest, this, sendInternal)
|
||||||
CONNECT2(void, const PIString &, const PIByteArray &, p._data, received, this, dtReceived)
|
CONNECTU(p._data, received, this, dtReceived)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -789,7 +789,6 @@ void PIPeer::sendPeerInfo(const PeerInfo & info) {
|
|||||||
|
|
||||||
|
|
||||||
void PIPeer::sendPeerRemove(const PIString & peer) {
|
void PIPeer::sendPeerRemove(const PIString & peer) {
|
||||||
//piCout << name() << "sendPeerRemove" << peer;
|
|
||||||
PIByteArray ba;
|
PIByteArray ba;
|
||||||
ba << int(2) << peer;
|
ba << int(2) << peer;
|
||||||
sendMBcast(ba);
|
sendMBcast(ba);
|
||||||
@@ -859,7 +858,7 @@ void PIPeer::syncPeers() {
|
|||||||
PeerInfo & cp(peers[i]);
|
PeerInfo & cp(peers[i]);
|
||||||
if (cp.sync > 3) {
|
if (cp.sync > 3) {
|
||||||
pn = cp.name;
|
pn = cp.name;
|
||||||
//piCout << "sync: remove " << pn;
|
//piCoutObj << "sync: remove " << pn;
|
||||||
cp.destroy();
|
cp.destroy();
|
||||||
addToRemoved(cp);
|
addToRemoved(cp);
|
||||||
peers.remove(i);
|
peers.remove(i);
|
||||||
@@ -924,15 +923,6 @@ void PIPeer::changeName(const PIString &new_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t PIPeer::bytesAvailable() const {
|
|
||||||
ssize_t ret = 0;
|
|
||||||
read_buffer_mutex.lock();
|
|
||||||
if (!read_buffer.isEmpty()) ret = read_buffer.back().size();
|
|
||||||
read_buffer_mutex.unlock();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int PIPeer::readDevice(void *read_to, int max_size) {
|
int PIPeer::readDevice(void *read_to, int max_size) {
|
||||||
read_buffer_mutex.lock();
|
read_buffer_mutex.lock();
|
||||||
bool empty = read_buffer.isEmpty();
|
bool empty = read_buffer.isEmpty();
|
||||||
@@ -970,14 +960,14 @@ int PIPeer::writeDevice(const void *data, int size) {
|
|||||||
void PIPeer::newTcpClient(PIEthernet *client) {
|
void PIPeer::newTcpClient(PIEthernet *client) {
|
||||||
client->setName("__S__PIPeer_eth_TCP_ServerClient" + client->path());
|
client->setName("__S__PIPeer_eth_TCP_ServerClient" + client->path());
|
||||||
piCoutObj << "client" << client->path();
|
piCoutObj << "client" << client->path();
|
||||||
CONNECT2(void, const uchar *, int, client, threadedReadEvent, this, mbcastRead);
|
CONNECTU(client, threadedReadEvent, this, mbcastRead);
|
||||||
client->startThreadedRead();
|
client->startThreadedRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIString PIPeer::constructFullPathDevice() const {
|
PIString PIPeer::constructFullPathDevice() const {
|
||||||
PIString ret;
|
PIString ret;
|
||||||
ret += self_info.name + ":" + trustPeerName();
|
ret << self_info.name << ":" << trustPeerName();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1018,9 +1008,8 @@ void PIPeer::initNetwork() {
|
|||||||
self_info.addresses.clear();
|
self_info.addresses.clear();
|
||||||
PIVector<PIEthernet::Address> al = PIEthernet::allAddresses();
|
PIVector<PIEthernet::Address> al = PIEthernet::allAddresses();
|
||||||
PIStringList sl;
|
PIStringList sl;
|
||||||
for (const PIEthernet::Address & a : al) {
|
piForeachC (PIEthernet::Address & a, al)
|
||||||
sl << a.ipString();
|
sl << a.ipString();
|
||||||
}
|
|
||||||
initEths(sl);
|
initEths(sl);
|
||||||
// piCoutObj << sl << self_info.addresses.size();
|
// piCoutObj << sl << self_info.addresses.size();
|
||||||
sl.removeAll("127.0.0.1");
|
sl.removeAll("127.0.0.1");
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
class PIP_EXPORT PIPeer: public PIIODevice
|
class PIP_EXPORT PIPeer: public PIIODevice
|
||||||
{
|
{
|
||||||
PIIODEVICE(PIPeer, "peer");
|
PIIODEVICE(PIPeer, "peer")
|
||||||
private:
|
private:
|
||||||
class PeerData;
|
class PeerData;
|
||||||
|
|
||||||
@@ -41,7 +41,8 @@ public:
|
|||||||
|
|
||||||
class PIP_EXPORT PeerInfo {
|
class PIP_EXPORT PeerInfo {
|
||||||
friend class PIPeer;
|
friend class PIPeer;
|
||||||
BINARY_STREAM_FRIEND(PIPeer::PeerInfo);
|
friend PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v);
|
||||||
|
friend PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v);
|
||||||
public:
|
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() {}
|
~PeerInfo() {}
|
||||||
@@ -79,8 +80,9 @@ public:
|
|||||||
PeerData * _data;
|
PeerData * _data;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
BINARY_STREAM_FRIEND(PIPeer::PeerInfo);
|
friend PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v);
|
||||||
|
friend PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v);
|
||||||
|
|
||||||
bool send(const PIString & to, const PIByteArray & data) {return send(to, data.data(), data.size_s());}
|
bool send(const PIString & to, const PIByteArray & data) {return send(to, data.data(), data.size_s());}
|
||||||
bool send(const PIString & to, const PIString & data) {return send(to, data.data(), data.size_s());}
|
bool send(const PIString & to, const PIString & data) {return send(to, data.data(), data.size_s());}
|
||||||
@@ -116,12 +118,10 @@ public:
|
|||||||
void setTrustPeerName(const PIString & peer_name) {trust_peer = peer_name;}
|
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;
|
|
||||||
|
|
||||||
|
|
||||||
EVENT2(dataReceivedEvent, const PIString &, from, const PIByteArray &, data);
|
EVENT2(dataReceivedEvent, const PIString &, from, const PIByteArray &, data)
|
||||||
EVENT1(peerConnectedEvent, const PIString &, name);
|
EVENT1(peerConnectedEvent, const PIString &, name)
|
||||||
EVENT1(peerDisconnectedEvent, const PIString &, name);
|
EVENT1(peerDisconnectedEvent, const PIString &, name)
|
||||||
|
|
||||||
// bool lockedEth() const {return eth_mutex.isLocked();}
|
// bool lockedEth() const {return eth_mutex.isLocked();}
|
||||||
// bool lockedPeers() const {return peers_mutex.isLocked();}
|
// bool lockedPeers() const {return peers_mutex.isLocked();}
|
||||||
@@ -134,8 +134,8 @@ protected:
|
|||||||
virtual void peerConnected(const PIString & name) {;}
|
virtual void peerConnected(const PIString & name) {;}
|
||||||
virtual void peerDisconnected(const PIString & name) {;}
|
virtual void peerDisconnected(const PIString & name) {;}
|
||||||
|
|
||||||
EVENT_HANDLER2(bool, dataRead, const uchar *, readed, int, size);
|
EVENT_HANDLER2(bool, dataRead, uchar *, readed, int, size);
|
||||||
EVENT_HANDLER2(bool, mbcastRead, const uchar *, readed, int, size);
|
EVENT_HANDLER2(bool, mbcastRead, uchar *, readed, int, size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EVENT_HANDLER2(void, timerEvent, void * , data, int, delim);
|
EVENT_HANDLER2(void, timerEvent, void * , data, int, delim);
|
||||||
@@ -166,15 +166,15 @@ private:
|
|||||||
void addToRemoved(const PeerInfo & pi) {removed[pi.name] = PIPair<int, PISystemTime>(pi.cnt, pi.time);}
|
void addToRemoved(const PeerInfo & pi) {removed[pi.name] = PIPair<int, PISystemTime>(pi.cnt, pi.time);}
|
||||||
bool isRemoved(const PeerInfo & pi) const {return (removed.value(pi.name) == PIPair<int, PISystemTime>(pi.cnt, pi.time));}
|
bool isRemoved(const PeerInfo & pi) const {return (removed.value(pi.name) == PIPair<int, PISystemTime>(pi.cnt, pi.time));}
|
||||||
|
|
||||||
bool openDevice() override;
|
bool openDevice();
|
||||||
bool closeDevice() override;
|
bool closeDevice();
|
||||||
PIString constructFullPathDevice() const override;
|
PIString constructFullPathDevice() const;
|
||||||
void configureFromFullPathDevice(const PIString &full_path) override;
|
void configureFromFullPathDevice(const PIString &full_path);
|
||||||
PIPropertyStorage constructVariantDevice() const override;
|
PIPropertyStorage constructVariantDevice() const;
|
||||||
void configureFromVariantDevice(const PIPropertyStorage & d) override;
|
void configureFromVariantDevice(const PIPropertyStorage & d);
|
||||||
int readDevice(void * read_to, int max_size) override;
|
int readDevice(void * read_to, int max_size);
|
||||||
int writeDevice(const void * data, int size) override;
|
int writeDevice(const void * data, int size);
|
||||||
DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Reliable;}
|
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Reliable;}
|
||||||
|
|
||||||
PeerInfo * quickestPeer(const PIString & to);
|
PeerInfo * quickestPeer(const PIString & to);
|
||||||
bool sendToNeighbour(PeerInfo * peer, const PIByteArray & ba);
|
bool sendToNeighbour(PeerInfo * peer, const PIByteArray & ba);
|
||||||
@@ -200,7 +200,7 @@ private:
|
|||||||
bool destroyed, no_timer;
|
bool destroyed, no_timer;
|
||||||
PIString trust_peer;
|
PIString trust_peer;
|
||||||
PIString server_ip;
|
PIString server_ip;
|
||||||
mutable PIMutex read_buffer_mutex;
|
PIMutex read_buffer_mutex;
|
||||||
PIQueue<PIByteArray> read_buffer;
|
PIQueue<PIByteArray> read_buffer;
|
||||||
int read_buffer_size;
|
int read_buffer_size;
|
||||||
PIMutex mc_mutex, eth_mutex, peers_mutex, send_mutex, send_mc_mutex;
|
PIMutex mc_mutex, eth_mutex, peers_mutex, send_mutex, send_mc_mutex;
|
||||||
@@ -209,10 +209,10 @@ private:
|
|||||||
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::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 & v) {c.space(); c << "PeerInfo(" << v.name << ", " << v.dist << ", " << v.addresses << ")"; return c;}
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIPeer::PeerInfo::PeerAddress) {s << v.address << v.netmask << v.ping; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo::PeerAddress & v) {s << v.address << v.netmask << v.ping; return s;}
|
||||||
BINARY_STREAM_READ (PIPeer::PeerInfo::PeerAddress) {s >> v.address >> v.netmask >> v.ping; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo::PeerAddress & v) {s >> v.address >> v.netmask >> v.ping; return s;}
|
||||||
|
|
||||||
BINARY_STREAM_WRITE(PIPeer::PeerInfo) {s << v.name << v.addresses << v.dist << v.neighbours << v.cnt << v.time; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v) {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;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v) {s >> v.name >> v.addresses >> v.dist >> v.neighbours >> v.cnt >> v.time; return s;}
|
||||||
|
|
||||||
#endif // PIPEER_H
|
#endif // PIPEER_H
|
||||||
|
|||||||
@@ -433,13 +433,8 @@ int PISerial::convertSpeed(PISerial::Speed speed) {
|
|||||||
case S4000000: return B4000000;
|
case S4000000: return B4000000;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
#ifdef WINDOWS
|
|
||||||
piCoutObj << "Warning: Custom speed" << (int)speed;
|
|
||||||
return (int)speed;
|
|
||||||
#else
|
|
||||||
piCoutObj << "Warning: Unknown speed" << (int)speed << ", using 115200";
|
piCoutObj << "Warning: Unknown speed" << (int)speed << ", using 115200";
|
||||||
return B115200;
|
return B115200;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -521,14 +516,14 @@ PIString PISerial::readString(int size, double timeout_ms) {
|
|||||||
while (tm_.elapsed_m() < timeout_ms) {
|
while (tm_.elapsed_m() < timeout_ms) {
|
||||||
ret = readDevice(td, 1024);
|
ret = readDevice(td, 1024);
|
||||||
if (ret <= 0) piMinSleep();
|
if (ret <= 0) piMinSleep();
|
||||||
else str += PIString((char*)td, ret);
|
else str << PIString((char*)td, ret);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
||||||
ret = readDevice(td, size - all);
|
ret = readDevice(td, size - all);
|
||||||
if (ret <= 0) piMinSleep();
|
if (ret <= 0) piMinSleep();
|
||||||
else {
|
else {
|
||||||
str += PIString((char*)td, ret);
|
str << PIString((char*)td, ret);
|
||||||
all += ret;
|
all += ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -537,12 +532,12 @@ PIString PISerial::readString(int size, double timeout_ms) {
|
|||||||
} else {
|
} else {
|
||||||
bool br = setOption(BlockingRead, true);
|
bool br = setOption(BlockingRead, true);
|
||||||
all = readDevice(td, 1);
|
all = readDevice(td, 1);
|
||||||
str += PIString((char*)td, all);
|
str << PIString((char*)td, all);
|
||||||
while (all < size) {
|
while (all < size) {
|
||||||
ret = readDevice(td, size - all);
|
ret = readDevice(td, size - all);
|
||||||
if (ret <= 0) piMinSleep();
|
if (ret <= 0) piMinSleep();
|
||||||
else {
|
else {
|
||||||
str += PIString((char*)td, ret);
|
str << PIString((char*)td, ret);
|
||||||
all += ret;
|
all += ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -862,13 +857,13 @@ bool PISerial::configureDevice(const void * e_main, const void * e_parent) {
|
|||||||
|
|
||||||
PIString PISerial::constructFullPathDevice() const {
|
PIString PISerial::constructFullPathDevice() const {
|
||||||
PIString ret;
|
PIString ret;
|
||||||
ret += path() + ":" + PIString::fromNumber(int(inSpeed())) + ":" + PIString::fromNumber(dataBitsCount());
|
ret << path() << ":" << int(inSpeed()) << ":" << dataBitsCount();
|
||||||
if (parameters()[ParityControl]) {
|
if (parameters()[ParityControl]) {
|
||||||
if (parameters()[ParityOdd]) ret += ":O";
|
if (parameters()[ParityOdd]) ret << ":O";
|
||||||
else ret += ":E";
|
else ret << ":E";
|
||||||
} else ret += ":N";
|
} else ret << ":N";
|
||||||
if (parameters()[TwoStopBits]) ret += ":2";
|
if (parameters()[TwoStopBits]) ret << ":2";
|
||||||
else ret += ":1";
|
else ret << ":1";
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
//! \~russian Последовательный порт.
|
//! \~russian Последовательный порт.
|
||||||
class PIP_EXPORT PISerial: public PIIODevice
|
class PIP_EXPORT PISerial: public PIIODevice
|
||||||
{
|
{
|
||||||
PIIODEVICE(PISerial, "ser");
|
PIIODEVICE(PISerial, "ser")
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! \~english Contructs an empty %PISerial
|
//! \~english Contructs an empty %PISerial
|
||||||
@@ -216,7 +216,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Discard all buffered input and output data
|
//! \~english Discard all buffered input and output data
|
||||||
//! \~russian Откидывает все буферизированные данные для передачи и приема
|
//! \~russian Откидывает все буферизированные данные для передачи и приема
|
||||||
virtual void flush() override;
|
void flush();
|
||||||
|
|
||||||
int read(void * read_to, int max_size) {return readDevice(read_to, max_size);}
|
int read(void * read_to, int max_size) {return readDevice(read_to, max_size);}
|
||||||
|
|
||||||
@@ -282,19 +282,19 @@ public:
|
|||||||
//! \}
|
//! \}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PIString constructFullPathDevice() const override;
|
PIString constructFullPathDevice() const;
|
||||||
void configureFromFullPathDevice(const PIString & full_path) override;
|
void configureFromFullPathDevice(const PIString & full_path);
|
||||||
PIPropertyStorage constructVariantDevice() const override;
|
PIPropertyStorage constructVariantDevice() const;
|
||||||
void configureFromVariantDevice(const PIPropertyStorage & d) override;
|
void configureFromVariantDevice(const PIPropertyStorage & d);
|
||||||
bool configureDevice(const void * e_main, const void * e_parent = 0) override;
|
bool configureDevice(const void * e_main, const void * e_parent = 0);
|
||||||
void optionsChanged() override;
|
void optionsChanged();
|
||||||
void threadedReadBufferSizeChanged() override;
|
void threadedReadBufferSizeChanged();
|
||||||
|
|
||||||
//! \~english Basic read function
|
//! \~english Basic read function
|
||||||
//! \~russian Базовое чтение
|
//! \~russian Базовое чтение
|
||||||
int readDevice(void * read_to, int max_size) override;
|
int readDevice(void * read_to, int max_size);
|
||||||
int writeDevice(const void * data, int max_size) override;
|
int writeDevice(const void * data, int max_size);
|
||||||
DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Sequential;}
|
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Sequential;}
|
||||||
|
|
||||||
//! Executes when any read function was successful. Default implementation does nothing
|
//! Executes when any read function was successful. Default implementation does nothing
|
||||||
virtual void received(const void * data, int size) {;}
|
virtual void received(const void * data, int size) {;}
|
||||||
@@ -306,8 +306,8 @@ protected:
|
|||||||
bool setBit(int bit, bool on, const PIString & bname);
|
bool setBit(int bit, bool on, const PIString & bname);
|
||||||
bool isBit(int bit, const PIString & bname) const;
|
bool isBit(int bit, const PIString & bname) const;
|
||||||
|
|
||||||
bool openDevice() override;
|
bool openDevice();
|
||||||
bool closeDevice() override;
|
bool closeDevice();
|
||||||
|
|
||||||
PRIVATE_DECLARATION(PIP_EXPORT)
|
PRIVATE_DECLARATION(PIP_EXPORT)
|
||||||
int fd, vtime;
|
int fd, vtime;
|
||||||
@@ -336,12 +336,12 @@ inline bool operator !=(const PISerial::DeviceInfo & v0, const PISerial::DeviceI
|
|||||||
//! \relatesalso PIByteArray
|
//! \relatesalso PIByteArray
|
||||||
//! \~english Store operator
|
//! \~english Store operator
|
||||||
//! \~russian Оператор сохранения
|
//! \~russian Оператор сохранения
|
||||||
BINARY_STREAM_WRITE(PISerial::DeviceInfo) {s << v.vID << v.pID << v.path << v.description << v.manufacturer; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PISerial::DeviceInfo & v) {s << v.vID << v.pID << v.path << v.description << v.manufacturer; return s;}
|
||||||
|
|
||||||
//! \relatesalso PIByteArray
|
//! \relatesalso PIByteArray
|
||||||
//! \~english Restore operator
|
//! \~english Restore operator
|
||||||
//! \~russian Оператор извлечения
|
//! \~russian Оператор извлечения
|
||||||
BINARY_STREAM_READ (PISerial::DeviceInfo) {s >> v.vID >> v.pID >> v.path >> v.description >> v.manufacturer; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PISerial::DeviceInfo & v) {s >> v.vID >> v.pID >> v.path >> v.description >> v.manufacturer; return s;}
|
||||||
|
|
||||||
|
|
||||||
#endif // PISERIAL_H
|
#endif // PISERIAL_H
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ bool PISharedMemory::closeDevice() {
|
|||||||
|
|
||||||
PIString PISharedMemory::constructFullPathDevice() const {
|
PIString PISharedMemory::constructFullPathDevice() const {
|
||||||
PIString ret;
|
PIString ret;
|
||||||
ret += path() + ":" + PIString::fromNumber(dsize);
|
ret << path() << ":" << dsize;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
//! \~russian Разделяемая память.
|
//! \~russian Разделяемая память.
|
||||||
class PIP_EXPORT PISharedMemory: public PIIODevice
|
class PIP_EXPORT PISharedMemory: public PIIODevice
|
||||||
{
|
{
|
||||||
PIIODEVICE(PISharedMemory, "shm");
|
PIIODEVICE(PISharedMemory, "shm")
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! \~english Constructs empty %PISharedMemory
|
//! \~english Constructs empty %PISharedMemory
|
||||||
@@ -91,15 +91,15 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool openDevice() override;
|
bool openDevice();
|
||||||
bool closeDevice() override;
|
bool closeDevice();
|
||||||
PIString constructFullPathDevice() const override;
|
PIString constructFullPathDevice() const;
|
||||||
void configureFromFullPathDevice(const PIString & full_path) override;
|
void configureFromFullPathDevice(const PIString & full_path);
|
||||||
PIPropertyStorage constructVariantDevice() const override;
|
PIPropertyStorage constructVariantDevice() const;
|
||||||
void configureFromVariantDevice(const PIPropertyStorage & d) override;
|
void configureFromVariantDevice(const PIPropertyStorage & d);
|
||||||
int readDevice(void * read_to, int max_size) override {return read(read_to, max_size, 0);}
|
int readDevice(void * read_to, int max_size) {return read(read_to, max_size, 0);}
|
||||||
int writeDevice(const void * data, int max_size) override {return write(data, max_size, 0);}
|
int writeDevice(const void * data, int max_size) {return write(data, max_size, 0);}
|
||||||
DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Reliable;}
|
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Reliable;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initPrivate();
|
void initPrivate();
|
||||||
|
|||||||
@@ -88,11 +88,6 @@ bool PISPI::isParameterSet(PISPI::Parameters parameter) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t PISPI::bytesAvailable() const {
|
|
||||||
return recv_buf.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool PISPI::openDevice() {
|
bool PISPI::openDevice() {
|
||||||
#ifdef PIP_SPI
|
#ifdef PIP_SPI
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -131,7 +126,7 @@ bool PISPI::closeDevice() {
|
|||||||
int PISPI::readDevice(void * read_to, int max_size) {
|
int PISPI::readDevice(void * read_to, int max_size) {
|
||||||
int sz = piMini(recv_buf.size_s(), max_size);
|
int sz = piMini(recv_buf.size_s(), max_size);
|
||||||
memcpy(read_to, recv_buf.data(), sz);
|
memcpy(read_to, recv_buf.data(), sz);
|
||||||
recv_buf.remove(0, sz);
|
recv_buf.resize(recv_buf.size_s() - sz);
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +157,7 @@ int PISPI::writeDevice(const void * data, int max_size) {
|
|||||||
|
|
||||||
PIString PISPI::constructFullPathDevice() const {
|
PIString PISPI::constructFullPathDevice() const {
|
||||||
PIString ret;
|
PIString ret;
|
||||||
ret += path() + ":" + PIString::fromNumber((int)speed()) + ":" + PIString::fromNumber((int)bits()) + ":" + PIString::fromNumber((int)parameters());
|
ret << path() << ":" << int(speed()) << ":" << int(bits()) << ":" << (int)parameters();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user