From c2b8a8d6da47bf09c45cccf0b9f860f40d3fe96f Mon Sep 17 00:00:00 2001 From: peri4 Date: Wed, 14 Dec 2022 14:13:52 +0300 Subject: [PATCH] code format --- esp-pip/main.cpp | 1 - libs/cloud/picloudbase.cpp | 2 +- libs/cloud/picloudclient.cpp | 377 ++-- libs/cloud/picloudserver.cpp | 608 +++--- libs/cloud/picloudtcp.cpp | 365 ++-- libs/compress/picompress.cpp | 157 +- libs/console/piscreen.cpp | 54 +- libs/console/piscreenconsole.cpp | 41 +- libs/console/piscreendrawer.cpp | 173 +- libs/console/piscreentile.cpp | 109 +- libs/console/piscreentiles.cpp | 26 +- libs/console/piterminal.cpp | 589 +++--- libs/crypt/piauth.cpp | 594 +++--- libs/crypt/picrypt.cpp | 905 ++++----- libs/fftw/pifft.cpp | 82 +- libs/fftw/pifft_p.h | 427 ++-- libs/io_utils/pibroadcast.cpp | 535 ++--- libs/io_utils/piethutilbase.cpp | 241 ++- libs/io_utils/pistreampacker.cpp | 418 ++-- libs/lua/piluaprogram.cpp | 27 +- libs/main/cloud/picloudbase.h | 29 +- libs/main/cloud/picloudclient.h | 39 +- libs/main/cloud/picloudmodule.h | 28 +- libs/main/cloud/picloudserver.h | 42 +- libs/main/cloud/picloudtcp.h | 50 +- libs/main/code/picodeinfo.cpp | 46 +- libs/main/code/picodeinfo.h | 121 +- libs/main/code/picodemodule.h | 26 +- libs/main/code/picodeparser.cpp | 736 ++++--- libs/main/code/picodeparser.h | 129 +- libs/main/compress/picompress.h | 28 +- libs/main/console/piconsolemodule.h | 26 +- libs/main/console/pikbdlistener.cpp | 32 +- libs/main/console/pikbdlistener.h | 26 +- libs/main/console/piscreen.h | 147 +- libs/main/console/piscreenconsole.h | 59 +- libs/main/console/piscreendrawer.h | 98 +- libs/main/console/piscreentile.h | 90 +- libs/main/console/piscreentiles.h | 56 +- libs/main/console/piscreentypes.h | 282 +-- libs/main/console/piterminal.h | 47 +- libs/main/containers/picontainers.cpp | 28 +- libs/main/containers/picontainers.h | 80 +- libs/main/containers/picontainersmodule.h | 28 +- libs/main/containers/pideque.h | 644 +++--- libs/main/containers/pimap.h | 369 ++-- libs/main/containers/pipair.h | 55 +- libs/main/containers/piqueue.h | 51 +- libs/main/containers/piset.h | 144 +- libs/main/containers/pistack.h | 49 +- libs/main/containers/pivector.h | 598 +++--- libs/main/containers/pivector2d.h | 223 ++- libs/main/core/pibase.h | 584 +++--- libs/main/core/picli.cpp | 50 +- libs/main/core/picli.h | 195 +- libs/main/core/picollection.cpp | 54 +- libs/main/core/picollection.h | 59 +- libs/main/core/picoremodule.h | 36 +- libs/main/core/picout.cpp | 201 +- libs/main/core/picout.h | 244 +-- libs/main/core/piincludes.cpp | 53 +- libs/main/core/piincludes.h | 32 +- libs/main/core/piincludes_p.h | 54 +- libs/main/core/piinit.cpp | 396 ++-- libs/main/core/piinit.h | 50 +- libs/main/core/pimemoryblock.h | 65 +- libs/main/core/piobject.cpp | 301 +-- libs/main/core/piobject.h | 435 ++-- libs/main/core/piobject_macros.h | 857 ++++---- libs/main/core/piwaitevent_p.cpp | 58 +- libs/main/core/piwaitevent_p.h | 31 +- libs/main/crypt/piauth.h | 56 +- libs/main/crypt/picrypt.h | 33 +- libs/main/crypt/picryptmodule.h | 28 +- libs/main/geo/piellipsoidmodel.cpp | 55 +- libs/main/geo/piellipsoidmodel.h | 37 +- libs/main/geo/pigeomodule.h | 26 +- libs/main/geo/pigeoposition.cpp | 462 +++-- libs/main/geo/pigeoposition.h | 180 +- .../main/introspection/piintrospection_base.h | 39 +- .../piintrospection_containers.cpp | 49 +- .../piintrospection_containers.h | 36 +- .../piintrospection_containers_p.cpp | 50 +- .../piintrospection_containers_p.h | 26 +- .../introspection/piintrospection_server.cpp | 219 +- .../introspection/piintrospection_server.h | 154 +- .../piintrospection_server_p.cpp | 341 ++-- .../introspection/piintrospection_server_p.h | 50 +- .../introspection/piintrospection_threads.cpp | 31 +- .../introspection/piintrospection_threads.h | 44 +- .../piintrospection_threads_p.cpp | 41 +- .../introspection/piintrospection_threads_p.h | 26 +- libs/main/io_devices/pibinarylog.cpp | 339 ++-- libs/main/io_devices/pibinarylog.h | 223 ++- libs/main/io_devices/pican.cpp | 80 +- libs/main/io_devices/pican.h | 32 +- libs/main/io_devices/piconfig.cpp | 356 ++-- libs/main/io_devices/piconfig.h | 26 +- libs/main/io_devices/pidir.cpp | 176 +- libs/main/io_devices/pidir.h | 130 +- libs/main/io_devices/piethernet.cpp | 526 ++--- libs/main/io_devices/piethernet.h | 508 ++--- libs/main/io_devices/pifile.cpp | 212 +- libs/main/io_devices/pifile.h | 170 +- libs/main/io_devices/pigpio.cpp | 76 +- libs/main/io_devices/pigpio.h | 63 +- libs/main/io_devices/piiobytearray.cpp | 48 +- libs/main/io_devices/piiobytearray.h | 88 +- libs/main/io_devices/piiodevice.cpp | 118 +- libs/main/io_devices/piiodevice.h | 261 +-- libs/main/io_devices/piiodevicesmodule.h | 26 +- libs/main/io_devices/piiostream.h | 35 +- libs/main/io_devices/piiostring.cpp | 34 +- libs/main/io_devices/piiostring.h | 90 +- libs/main/io_devices/pipeer.cpp | 439 ++-- libs/main/io_devices/pipeer.h | 247 ++- libs/main/io_devices/piserial.cpp | 608 +++--- libs/main/io_devices/piserial.h | 26 +- libs/main/io_devices/pisharedmemory.cpp | 77 +- libs/main/io_devices/pisharedmemory.h | 60 +- libs/main/io_devices/pispi.cpp | 93 +- libs/main/io_devices/pispi.h | 42 +- libs/main/io_devices/pitransparentdevice.cpp | 29 +- libs/main/io_devices/pitransparentdevice.h | 38 +- libs/main/io_devices/piusb.h | 125 +- libs/main/io_utils/pibasetransfer.cpp | 502 ++--- libs/main/io_utils/pibasetransfer.h | 149 +- libs/main/io_utils/pibroadcast.h | 66 +- libs/main/io_utils/piconnection.cpp | 301 ++- libs/main/io_utils/piconnection.h | 332 ++-- libs/main/io_utils/pidatatransfer.cpp | 30 +- libs/main/io_utils/pidatatransfer.h | 42 +- libs/main/io_utils/pidiagnostics.cpp | 112 +- libs/main/io_utils/pidiagnostics.h | 136 +- libs/main/io_utils/piethutilbase.h | 32 +- libs/main/io_utils/pifiletransfer.cpp | 210 +- libs/main/io_utils/pifiletransfer.h | 99 +- libs/main/io_utils/piioutilsmodule.h | 26 +- libs/main/io_utils/pipacketextractor.cpp | 52 +- libs/main/io_utils/pipacketextractor.h | 87 +- libs/main/io_utils/piparsehelper.h | 62 +- libs/main/io_utils/pistreampacker.h | 79 +- libs/main/lua/piluaprogram.h | 31 +- libs/main/lua/pip_lua.h | 49 +- libs/main/math/picrc.h | 460 +++-- libs/main/math/pievaluator.cpp | 743 ++++--- libs/main/math/pievaluator.h | 345 +++- libs/main/math/pifft.cpp | 1370 +++++++------ libs/main/math/pifft.h | 280 ++- libs/main/math/pigeometry.h | 30 +- libs/main/math/piline.h | 63 +- libs/main/math/pimathbase.cpp | 474 +++-- libs/main/math/pimathbase.h | 26 +- libs/main/math/pimathcomplex.h | 100 +- libs/main/math/pimathmatrix.h | 335 ++-- libs/main/math/pimathmodule.h | 32 +- libs/main/math/pimathsolver.cpp | 96 +- libs/main/math/pimathsolver.h | 103 +- libs/main/math/pimathvector.h | 319 +-- libs/main/math/pipoint.h | 67 +- libs/main/math/piquaternion.cpp | 100 +- libs/main/math/piquaternion.h | 26 +- libs/main/math/pirect.h | 151 +- libs/main/math/pistatistic.h | 56 +- libs/main/opencl/piopencl.h | 123 +- libs/main/pip.h | 38 +- libs/main/piplatform.h | 64 +- libs/main/resources/piresources.cpp | 30 +- libs/main/resources/piresources.h | 34 +- libs/main/resources/piresourcesstorage.cpp | 72 +- libs/main/resources/piresourcesstorage.h | 65 +- libs/main/serialization/pibinarystream.h | 381 ++-- libs/main/serialization/pichunkstream.cpp | 60 +- libs/main/serialization/pichunkstream.h | 131 +- libs/main/serialization/pijson.cpp | 112 +- libs/main/serialization/pijson.h | 96 +- .../serialization/piserializationmodule.h | 26 +- .../serialization/pivaluetree_conversions.cpp | 86 +- .../serialization/pivaluetree_conversions.h | 26 +- libs/main/system/pilibrary.cpp | 81 +- libs/main/system/pilibrary.h | 50 +- libs/main/system/piplugin.cpp | 126 +- libs/main/system/piplugin.h | 131 +- libs/main/system/piprocess.cpp | 322 ++- libs/main/system/piprocess.h | 114 +- libs/main/system/pisignals.cpp | 43 +- libs/main/system/pisignals.h | 75 +- libs/main/system/pisingleapplication.cpp | 24 +- libs/main/system/pisingleapplication.h | 41 +- libs/main/system/pisysteminfo.cpp | 117 +- libs/main/system/pisysteminfo.h | 46 +- libs/main/system/pisystemmodule.h | 34 +- libs/main/system/pisystemmonitor.cpp | 914 +++++---- libs/main/system/pisystemmonitor.h | 654 +++--- libs/main/system/pisystemtests.cpp | 44 +- libs/main/system/pisystemtests.h | 44 +- libs/main/text/pichar.cpp | 91 +- libs/main/text/pichar.h | 26 +- libs/main/text/piconstchars.cpp | 30 +- libs/main/text/piconstchars.h | 92 +- libs/main/text/pistring.cpp | 319 +-- libs/main/text/pistring.h | 860 +++++--- libs/main/text/pistring_std.h | 43 +- libs/main/text/pistringlist.cpp | 36 +- libs/main/text/pistringlist.h | 144 +- libs/main/text/pitextmodule.h | 28 +- libs/main/text/pitextstream.h | 259 ++- libs/main/thread/piblockingqueue.h | 72 +- libs/main/thread/piconditionvar.cpp | 60 +- libs/main/thread/piconditionvar.h | 30 +- libs/main/thread/pigrabberbase.h | 70 +- libs/main/thread/pimutex.cpp | 42 +- libs/main/thread/pimutex.h | 42 +- libs/main/thread/pipipelinethread.h | 71 +- libs/main/thread/pispinlock.cpp | 26 +- libs/main/thread/pispinlock.h | 52 +- libs/main/thread/pithread.cpp | 608 +++--- libs/main/thread/pithread.h | 156 +- libs/main/thread/pithreadmodule.h | 36 +- libs/main/thread/pithreadnotifier.cpp | 33 +- libs/main/thread/pithreadnotifier.h | 26 +- libs/main/thread/pithreadpoolexecutor.cpp | 34 +- libs/main/thread/pithreadpoolexecutor.h | 24 +- libs/main/thread/pithreadpoolloop.cpp | 43 +- libs/main/thread/pithreadpoolloop.h | 36 +- libs/main/thread/pitimer.cpp | 216 +- libs/main/thread/pitimer.h | 32 +- libs/main/types/colors.cpp | 26 +- libs/main/types/colors_p.h | 31 +- libs/main/types/pibitarray.cpp | 32 +- libs/main/types/pibitarray.h | 210 +- libs/main/types/pibytearray.cpp | 32 +- libs/main/types/pibytearray.h | 236 ++- libs/main/types/pidatetime.cpp | 180 +- libs/main/types/pidatetime.h | 190 +- libs/main/types/piflags.h | 167 +- libs/main/types/pipropertystorage.cpp | 57 +- libs/main/types/pipropertystorage.h | 141 +- libs/main/types/pisystemtime.cpp | 81 +- libs/main/types/pisystemtime.h | 288 ++- libs/main/types/pitime.cpp | 31 +- libs/main/types/pitime.h | 38 +- libs/main/types/pitime_win.h | 49 +- libs/main/types/pitypesmodule.h | 30 +- libs/main/types/pivaluetree.cpp | 26 +- libs/main/types/pivaluetree.h | 26 +- libs/main/types/pivariant.cpp | 34 +- libs/main/types/pivariant.h | 28 +- libs/main/types/pivariantsimple.h | 147 +- libs/main/types/pivarianttypes.cpp | 26 +- libs/main/types/pivarianttypes.h | 227 ++- libs/opencl/3rd/clcomplex.h | 563 +++--- libs/opencl/piopencl.cpp | 1436 +++++++------- libs/usb/piusb.cpp | 245 +-- main.cpp | 146 +- main_picloud_test.cpp | 51 +- main_tcp_server.cpp | 188 +- tests/concurrent/BlockingDequeueUnitTest.cpp | 262 +-- .../ConditionLockIntegrationTest.cpp | 19 +- .../ConditionVariableIntegrationTest.cpp | 68 +- tests/concurrent/ExecutorIntegrationTest.cpp | 75 +- tests/concurrent/pithreadnotifier_test.cpp | 37 +- tests/concurrent/testutil.h | 72 +- tests/core/piStringListTest.cpp | 174 +- tests/core/pistringTest.cpp | 316 +-- tests/math/testpimathmatrix.cpp | 61 +- tests/math/testpimathmatrixt.cpp | 302 ++- tests/math/testpivector2d.cpp | 19 +- tests/piobject/connect.cpp | 76 +- tests/piobject/delete_later.cpp | 27 +- utils/cloud_dispatcher/cloudserver.cpp | 33 +- utils/cloud_dispatcher/cloudserver.h | 11 +- utils/cloud_dispatcher/dispatcherclient.cpp | 58 +- utils/cloud_dispatcher/dispatcherclient.h | 9 +- utils/cloud_dispatcher/dispatcherserver.cpp | 57 +- utils/cloud_dispatcher/dispatcherserver.h | 11 +- utils/cloud_dispatcher/main.cpp | 315 +-- utils/code_model_generator/main.cpp | 1245 ++++++------ utils/crypt_tool/main.cpp | 250 +-- utils/deploy_tool/main.cpp | 373 ++-- utils/piterminal/main.cpp | 174 +- utils/resources_compiler/generator.cpp | 169 +- utils/resources_compiler/generator.h | 18 +- utils/resources_compiler/main.cpp | 193 +- utils/resources_compiler/parser.cpp | 240 ++- utils/resources_compiler/parser.h | 54 +- utils/system_daemon/daemon.cpp | 1765 ++++++++--------- utils/system_daemon/daemon.h | 434 ++-- utils/system_daemon/file_manager.cpp | 682 +++---- utils/system_daemon/file_manager.h | 157 +- utils/system_daemon/main.cpp | 849 ++++---- utils/system_daemon/shared.cpp | 357 ++-- utils/system_daemon/shared.h | 42 +- utils/system_daemon/terminal_tile.cpp | 69 +- utils/system_daemon/terminal_tile.h | 60 +- utils/system_test/main.cpp | 212 +- utils/udp_file_transfer/main.cpp | 496 +++-- 297 files changed, 27331 insertions(+), 24162 deletions(-) diff --git a/esp-pip/main.cpp b/esp-pip/main.cpp index 87e4eb10..95dd9753 100644 --- a/esp-pip/main.cpp +++ b/esp-pip/main.cpp @@ -1,2 +1 @@ #include "pip.h" - diff --git a/libs/cloud/picloudbase.cpp b/libs/cloud/picloudbase.cpp index 10110a31..20c7d5f2 100644 --- a/libs/cloud/picloudbase.cpp +++ b/libs/cloud/picloudbase.cpp @@ -1,7 +1,7 @@ #include "picloudbase.h" -PICloudBase::PICloudBase() : eth(PIEthernet::TCP_Client), streampacker(ð), tcp(&streampacker) { +PICloudBase::PICloudBase(): eth(PIEthernet::TCP_Client), streampacker(ð), tcp(&streampacker) { eth.setDebug(false); } diff --git a/libs/cloud/picloudclient.cpp b/libs/cloud/picloudclient.cpp index 9a3adc1c..00bfea3e 100644 --- a/libs/cloud/picloudclient.cpp +++ b/libs/cloud/picloudclient.cpp @@ -1,187 +1,190 @@ -/* - PIP - Platform Independent Primitives - PICloud Client - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . -*/ - -#include "picloudclient.h" -#include "picloudtcp.h" - - -PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), PICloudBase() { - tcp.setRole(PICloud::TCP::Client); - setThreadedReadBufferSize(eth.threadedReadBufferSize()); - setName("cloud_client"); - is_connected = false; - is_deleted = false; -// setReopenEnabled(false); - CONNECTL(ð, connected, [this](){opened_ = true; tcp.sendStart();}); - CONNECT1(void, PIByteArray, &streampacker, packetReceiveEvent, this, _readed); - CONNECTL(ð, disconnected, [this](bool){ - if (is_deleted) return; - bool need_disconn = is_connected; - //piCoutObj << "eth disconnected"; - eth.stop(); - opened_ = false; - internalDisconnect(); - if (need_disconn) disconnected(); - //piCoutObj << "eth disconnected done"; - }); -} - - -PICloudClient::~PICloudClient() { - //piCoutObj << "~PICloudClient() ..." << this; - is_deleted = true; - stopAndWait(); - close(); - internalDisconnect(); - //piCoutObj << "~PICloudClient() done" << this; -} - - -void PICloudClient::setServerName(const PIString & server_name) { - setName("cloud_client__" + server_name); - tcp.setServerName(server_name); -} - - -void PICloudClient::setKeepConnection(bool on) { - eth.setParameter(PIEthernet::KeepConnection, on); -} - - -void PICloudClient::interrupt() { - cond_buff.notifyOne(); - cond_connect.notifyOne(); -} - - -bool PICloudClient::openDevice() { - //piCoutObj << "open";// << path(); - bool op = eth.connect(PIEthernet::Address::resolve(path()), false); - if (op) { - mutex_connect.lock(); - eth.startThreadedRead(); - //piCoutObj << "connecting..."; - bool conn_ok = cond_connect.waitFor(mutex_connect, (int)eth.readTimeout()); - //piCoutObj << "conn_ok" << conn_ok << is_connected; - mutex_connect.unlock(); - if (!conn_ok) { - mutex_connect.lock(); - eth.stopAndWait(); - eth.close(); - mutex_connect.unlock(); - } - return is_connected; - } else { - //eth.close(); - return false; - } -} - - -bool PICloudClient::closeDevice() { - //PIThread::stop(); - if (is_connected) { - internalDisconnect(); - } - eth.stopAndWait(); - eth.close(); - return true; -} - - -ssize_t PICloudClient::readDevice(void * read_to, ssize_t max_size) { - if (is_deleted || max_size <= 0) return -1; - //piCoutObj << "readDevice ..."; - if (!is_connected && eth.isClosed()) openDevice(); - ssize_t sz = -1; - mutex_buff.lock(); - if (is_connected) { - if (buff.isEmpty()) { - sz = 0; - } else { - sz = piMin(max_size, buff.size_s()); - memcpy(read_to, buff.data(), sz); - buff.remove(0, sz); - } - if (sz == 0) cond_buff.wait(mutex_buff); - } - mutex_buff.unlock(); - if (!is_connected) opened_ = false; - //piCoutObj << "readDevice done" << sz; - return sz; -} - - -ssize_t PICloudClient::writeDevice(const void * data, ssize_t size) { - if (is_deleted || !is_connected) return -1; - //piCoutObj << "writeDevice" << size; - return tcp.sendData(PIByteArray(data, size)); -} - - -void PICloudClient::internalDisconnect() { - //piCoutObj << "internalDisconnect"; - is_connected = false; - cond_buff.notifyOne(); - cond_connect.notifyOne(); - streampacker.clear(); - buff.clear(); -} - - -void PICloudClient::_readed(PIByteArray & ba) { - if (is_deleted) return; - PIPair hdr = tcp.parseHeader(ba); - //piCoutObj << "_readed" << ba.size() << hdr.first << hdr.second; - if (hdr.second == tcp.role()) { - switch (hdr.first) { - case PICloud::TCP::Connect: - if (tcp.parseConnect(ba) == 1) { - mutex_connect.lock(); - is_connected = true; - mutex_connect.unlock(); - cond_connect.notifyOne(); - connected(); - } - break; - case PICloud::TCP::Disconnect: - eth.stop(); - opened_ = false; - eth.close(); - break; - case PICloud::TCP::Data: - if (is_connected) { - mutex_buff.lock(); - if (buff.size_s() > threadedReadBufferSize()) { - piCoutObj << "Error: buffer overflow, drop" << ba.size() << "bytes"; - mutex_buff.unlock(); - return; - } - buff.append(ba); - mutex_buff.unlock(); - cond_buff.notifyOne(); - } - break; - default: - break; - } - //piCoutObj << "readed" << ba.toHex(); - } - //piCoutObj << "_readed done"; -} +/* + PIP - Platform Independent Primitives + PICloud Client + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . +*/ + +#include "picloudclient.h" + +#include "picloudtcp.h" + + +PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode): PIIODevice(path, mode), PICloudBase() { + tcp.setRole(PICloud::TCP::Client); + setThreadedReadBufferSize(eth.threadedReadBufferSize()); + setName("cloud_client"); + is_connected = false; + is_deleted = false; + // setReopenEnabled(false); + CONNECTL(ð, connected, [this]() { + opened_ = true; + tcp.sendStart(); + }); + CONNECT1(void, PIByteArray, &streampacker, packetReceiveEvent, this, _readed); + CONNECTL(ð, disconnected, [this](bool) { + if (is_deleted) return; + bool need_disconn = is_connected; + // piCoutObj << "eth disconnected"; + eth.stop(); + opened_ = false; + internalDisconnect(); + if (need_disconn) disconnected(); + // piCoutObj << "eth disconnected done"; + }); +} + + +PICloudClient::~PICloudClient() { + // piCoutObj << "~PICloudClient() ..." << this; + is_deleted = true; + stopAndWait(); + close(); + internalDisconnect(); + // piCoutObj << "~PICloudClient() done" << this; +} + + +void PICloudClient::setServerName(const PIString & server_name) { + setName("cloud_client__" + server_name); + tcp.setServerName(server_name); +} + + +void PICloudClient::setKeepConnection(bool on) { + eth.setParameter(PIEthernet::KeepConnection, on); +} + + +void PICloudClient::interrupt() { + cond_buff.notifyOne(); + cond_connect.notifyOne(); +} + + +bool PICloudClient::openDevice() { + // piCoutObj << "open";// << path(); + bool op = eth.connect(PIEthernet::Address::resolve(path()), false); + if (op) { + mutex_connect.lock(); + eth.startThreadedRead(); + // piCoutObj << "connecting..."; + bool conn_ok = cond_connect.waitFor(mutex_connect, (int)eth.readTimeout()); + // piCoutObj << "conn_ok" << conn_ok << is_connected; + mutex_connect.unlock(); + if (!conn_ok) { + mutex_connect.lock(); + eth.stopAndWait(); + eth.close(); + mutex_connect.unlock(); + } + return is_connected; + } else { + // eth.close(); + return false; + } +} + + +bool PICloudClient::closeDevice() { + // PIThread::stop(); + if (is_connected) { + internalDisconnect(); + } + eth.stopAndWait(); + eth.close(); + return true; +} + + +ssize_t PICloudClient::readDevice(void * read_to, ssize_t max_size) { + if (is_deleted || max_size <= 0) return -1; + // piCoutObj << "readDevice ..."; + if (!is_connected && eth.isClosed()) openDevice(); + ssize_t sz = -1; + mutex_buff.lock(); + if (is_connected) { + if (buff.isEmpty()) { + sz = 0; + } else { + sz = piMin(max_size, buff.size_s()); + memcpy(read_to, buff.data(), sz); + buff.remove(0, sz); + } + if (sz == 0) cond_buff.wait(mutex_buff); + } + mutex_buff.unlock(); + if (!is_connected) opened_ = false; + // piCoutObj << "readDevice done" << sz; + return sz; +} + + +ssize_t PICloudClient::writeDevice(const void * data, ssize_t size) { + if (is_deleted || !is_connected) return -1; + // piCoutObj << "writeDevice" << size; + return tcp.sendData(PIByteArray(data, size)); +} + + +void PICloudClient::internalDisconnect() { + // piCoutObj << "internalDisconnect"; + is_connected = false; + cond_buff.notifyOne(); + cond_connect.notifyOne(); + streampacker.clear(); + buff.clear(); +} + + +void PICloudClient::_readed(PIByteArray & ba) { + if (is_deleted) return; + PIPair hdr = tcp.parseHeader(ba); + // piCoutObj << "_readed" << ba.size() << hdr.first << hdr.second; + if (hdr.second == tcp.role()) { + switch (hdr.first) { + case PICloud::TCP::Connect: + if (tcp.parseConnect(ba) == 1) { + mutex_connect.lock(); + is_connected = true; + mutex_connect.unlock(); + cond_connect.notifyOne(); + connected(); + } + break; + case PICloud::TCP::Disconnect: + eth.stop(); + opened_ = false; + eth.close(); + break; + case PICloud::TCP::Data: + if (is_connected) { + mutex_buff.lock(); + if (buff.size_s() > threadedReadBufferSize()) { + piCoutObj << "Error: buffer overflow, drop" << ba.size() << "bytes"; + mutex_buff.unlock(); + return; + } + buff.append(ba); + mutex_buff.unlock(); + cond_buff.notifyOne(); + } + break; + default: break; + } + // piCoutObj << "readed" << ba.toHex(); + } + // piCoutObj << "_readed done"; +} diff --git a/libs/cloud/picloudserver.cpp b/libs/cloud/picloudserver.cpp index 61125f85..c805afe0 100644 --- a/libs/cloud/picloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -1,304 +1,304 @@ -/* - PIP - Platform Independent Primitives - PICloud Server - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . -*/ - -#include "picloudserver.h" - - -PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), PICloudBase() { - PIString server_name = "PCS_" + PIString::fromNumber(randomi()%1000); - tcp.setRole(PICloud::TCP::Server); - tcp.setServerName(server_name); - setName("cloud_server__" + server_name); - is_deleted = false; - eth.setReopenEnabled(false); - setThreadedReadBufferSize(eth.threadedReadBufferSize()); - CONNECT1(void, PIByteArray, &streampacker, packetReceiveEvent, this, _readed); - CONNECTL(ð, connected, [this](){ - open_mutex.lock(); - opened_ = true; - cvar.notifyOne(); - open_mutex.unlock(); - //piCoutObj << "connected"; - tcp.sendStart(); - }); - CONNECTL(ð, disconnected, [this](bool){ - if (is_deleted) return; - //piCoutObj << "disconnected"; - clients_mutex.lock(); - for (auto c : clients_) { - c->is_connected = false; - c->close(); - } - removed_clients_.append(clients_); - clients_.clear(); - index_clients.clear(); - clients_mutex.unlock(); - open_mutex.lock(); - opened_ = false; - cvar.notifyOne(); - open_mutex.unlock(); - ping_timer.stop(); - }); - CONNECTL(&ping_timer, tickEvent, [this] (void *, int){ - if (eth.isConnected()) tcp.sendPing(); - }); -} - - -PICloudServer::~PICloudServer() { - //piCoutObj << "~PICloudServer ..." << this; - is_deleted = true; - stop(); - close(); - waitThreadedReadFinished(); - //piCout << "wait"; - while(removed_clients_.isNotEmpty()) { - Client * c = removed_clients_.take_back(); - delete c; - } - //piCoutObj << "~PICloudServer done" << this; -} - - -void PICloudServer::setServerName(const PIString & server_name) { - setName("cloud_server__" + server_name); - tcp.setServerName(server_name); -} - - -PIVector PICloudServer::clients() const { - PIMutexLocker _ml(clients_mutex); - return clients_; -} - - -bool PICloudServer::openDevice() { - //piCout << "PICloudServer open device" << path(); - if (is_deleted) return false; - bool op = eth.connect(PIEthernet::Address::resolve(path()), false); - if (op) { - eth.startThreadedRead(); - ping_timer.start(5000); - return true; - } else { - ping_timer.stop(); - eth.close(); - return false; - } -} - - -bool PICloudServer::closeDevice() { - //piCoutObj << "closeDevice" << this; - eth.stopAndWait(); - ping_timer.stop(); - eth.close(); - cvar.notifyOne(); - clients_mutex.lock(); - for (auto c : clients_) { - c->is_connected = false; - c->close(); - } - removed_clients_.append(clients_); - clients_.clear(); - index_clients.clear(); - clients_mutex.unlock(); - return true; -} - - -ssize_t PICloudServer::readDevice(void * read_to, ssize_t max_size) { - if (is_deleted) return -1; - //piCoutObj << "readDevice"; - open_mutex.lock(); - if (isOpened()) cvar.wait(open_mutex); - open_mutex.unlock(); - //piCoutObj << "opened_ = " << opened_; - //else piMSleep(eth.readTimeout()); - return -1; -} - - -ssize_t PICloudServer::writeDevice(const void * data, ssize_t max_size) { - //piCoutObj << "writeDevice"; - return -1; -} - - -void PICloudServer::interrupt() { - eth.interrupt(); - cvar.notifyOne(); -} - - -void PICloudServer::clientDisconnect(uint client_id) { - tcp.sendDisconnected(client_id); -} - - -int PICloudServer::sendData(const PIByteArray & data, uint client_id) { - if (!opened_) return -1; - return tcp.sendData(data, client_id); -} - - -PICloudServer::Client::Client(PICloudServer * srv, uint id) : server(srv), client_id(id) { - setMode(PIIODevice::ReadWrite); - setReopenEnabled(false); - setThreadedReadBufferSize(server->threadedReadBufferSize()); - is_connected = true; -} - - -PICloudServer::Client::~Client() { - //piCoutObj << "~PICloudServer::Client..." << this; - close(); - stopAndWait(); - //piCoutObj << "~PICloudServer::Client done" << this; -} - - -bool PICloudServer::Client::openDevice() { - return is_connected; -} - - -bool PICloudServer::Client::closeDevice() { - //piCoutObj << "closeDevice" << this; - if (is_connected) { - server->clientDisconnect(client_id); - is_connected = false; - } - cond_buff.notifyOne(); - return true; -} - - -ssize_t PICloudServer::Client::readDevice(void * read_to, ssize_t max_size) { - if (!is_connected) return -1; - ssize_t sz = -1; - mutex_buff.lock(); - if (is_connected) { - if (buff.isEmpty()) { - sz = 0; - } else { - sz = piMini(max_size, buff.size()); - memcpy(read_to, buff.data(), sz); - buff.remove(0, sz); - } - if (sz == 0) cond_buff.wait(mutex_buff); - } - mutex_buff.unlock(); - return sz; -} - - -ssize_t PICloudServer::Client::writeDevice(const void * data, ssize_t size) { - if (!is_connected) return -1; - return server->sendData(PIByteArray(data, size), client_id); -} - - -void PICloudServer::Client::interrupt() { - cond_buff.notifyOne(); -} - - -void PICloudServer::Client::pushBuffer(const PIByteArray & ba) { - if (!is_connected) return; - mutex_buff.lock(); - if (buff.size_s() > threadedReadBufferSize()) { - piCoutObj << "Error: buffer overflow, drop" << ba.size() << "bytes"; - mutex_buff.unlock(); - return; - } - buff.append(ba); - cond_buff.notifyOne(); - mutex_buff.unlock(); -} - - -void PICloudServer::_readed(PIByteArray & ba) { - if (is_deleted) return; - PIPair hdr = tcp.parseHeader(ba); - if (hdr.second == tcp.role()) { - switch (hdr.first) { - case PICloud::TCP::Connect: { - uint id = tcp.parseConnect(ba); - clients_mutex.lock(); - Client * oc = index_clients.value(id, nullptr); - clients_mutex.unlock(); - if (oc) { - piCoutObj << "Warning: reject client with duplicated ID"; - tcp.sendDisconnected(id); - } else { - Client * c = new Client(this, id); - //piCoutObj << "new Client" << id << c; - CONNECT1(void, PIObject *, c, deleted, this, clientDeleted); - clients_mutex.lock(); - clients_ << c; - index_clients.insert(id, c); - clients_mutex.unlock(); - newConnection(c); - } - } break; - case PICloud::TCP::Disconnect: { - uint id = tcp.parseDisconnect(ba); - //piCoutObj << "Close on logic"; - clients_mutex.lock(); - Client * oc = index_clients.take(id, nullptr); - clients_.removeOne(oc); - clients_mutex.unlock(); - if (oc) { - oc->stopAndWait(); - oc->is_connected = false; - oc->close(); - removed_clients_ << oc; - //delete oc; - } - } break; - case PICloud::TCP::Data: { - PIPair d = tcp.parseDataServer(ba); - clients_mutex.lock(); - Client * oc = index_clients.value(d.first, nullptr); - clients_mutex.unlock(); - //piCoutObj << "data for" << d.first << d.second.size(); - if (oc && !d.second.isEmpty()) oc->pushBuffer(d.second); - } break; - default: break; - } - } -} - - -void PICloudServer::clientDeleted(PIObject * o) { - PICloudServer::Client * c = (PICloudServer::Client*)o; - //piCoutObj << "clientDeleted" << c; - clients_mutex.lock(); - clients_.removeOne(c); - removed_clients_.removeAll(c); - auto it = index_clients.makeIterator(); - while (it.next()) { - if (it.value() == c) { - index_clients.remove(it.key()); - break; - } - } - clients_mutex.unlock(); -} +/* + PIP - Platform Independent Primitives + PICloud Server + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . +*/ + +#include "picloudserver.h" + + +PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode): PIIODevice(path, mode), PICloudBase() { + PIString server_name = "PCS_" + PIString::fromNumber(randomi() % 1000); + tcp.setRole(PICloud::TCP::Server); + tcp.setServerName(server_name); + setName("cloud_server__" + server_name); + is_deleted = false; + eth.setReopenEnabled(false); + setThreadedReadBufferSize(eth.threadedReadBufferSize()); + CONNECT1(void, PIByteArray, &streampacker, packetReceiveEvent, this, _readed); + CONNECTL(ð, connected, [this]() { + open_mutex.lock(); + opened_ = true; + cvar.notifyOne(); + open_mutex.unlock(); + // piCoutObj << "connected"; + tcp.sendStart(); + }); + CONNECTL(ð, disconnected, [this](bool) { + if (is_deleted) return; + // piCoutObj << "disconnected"; + clients_mutex.lock(); + for (auto c: clients_) { + c->is_connected = false; + c->close(); + } + removed_clients_.append(clients_); + clients_.clear(); + index_clients.clear(); + clients_mutex.unlock(); + open_mutex.lock(); + opened_ = false; + cvar.notifyOne(); + open_mutex.unlock(); + ping_timer.stop(); + }); + CONNECTL(&ping_timer, tickEvent, [this](void *, int) { + if (eth.isConnected()) tcp.sendPing(); + }); +} + + +PICloudServer::~PICloudServer() { + // piCoutObj << "~PICloudServer ..." << this; + is_deleted = true; + stop(); + close(); + waitThreadedReadFinished(); + // piCout << "wait"; + while (removed_clients_.isNotEmpty()) { + Client * c = removed_clients_.take_back(); + delete c; + } + // piCoutObj << "~PICloudServer done" << this; +} + + +void PICloudServer::setServerName(const PIString & server_name) { + setName("cloud_server__" + server_name); + tcp.setServerName(server_name); +} + + +PIVector PICloudServer::clients() const { + PIMutexLocker _ml(clients_mutex); + return clients_; +} + + +bool PICloudServer::openDevice() { + // piCout << "PICloudServer open device" << path(); + if (is_deleted) return false; + bool op = eth.connect(PIEthernet::Address::resolve(path()), false); + if (op) { + eth.startThreadedRead(); + ping_timer.start(5000); + return true; + } else { + ping_timer.stop(); + eth.close(); + return false; + } +} + + +bool PICloudServer::closeDevice() { + // piCoutObj << "closeDevice" << this; + eth.stopAndWait(); + ping_timer.stop(); + eth.close(); + cvar.notifyOne(); + clients_mutex.lock(); + for (auto c: clients_) { + c->is_connected = false; + c->close(); + } + removed_clients_.append(clients_); + clients_.clear(); + index_clients.clear(); + clients_mutex.unlock(); + return true; +} + + +ssize_t PICloudServer::readDevice(void * read_to, ssize_t max_size) { + if (is_deleted) return -1; + // piCoutObj << "readDevice"; + open_mutex.lock(); + if (isOpened()) cvar.wait(open_mutex); + open_mutex.unlock(); + // piCoutObj << "opened_ = " << opened_; + // else piMSleep(eth.readTimeout()); + return -1; +} + + +ssize_t PICloudServer::writeDevice(const void * data, ssize_t max_size) { + // piCoutObj << "writeDevice"; + return -1; +} + + +void PICloudServer::interrupt() { + eth.interrupt(); + cvar.notifyOne(); +} + + +void PICloudServer::clientDisconnect(uint client_id) { + tcp.sendDisconnected(client_id); +} + + +int PICloudServer::sendData(const PIByteArray & data, uint client_id) { + if (!opened_) return -1; + return tcp.sendData(data, client_id); +} + + +PICloudServer::Client::Client(PICloudServer * srv, uint id): server(srv), client_id(id) { + setMode(PIIODevice::ReadWrite); + setReopenEnabled(false); + setThreadedReadBufferSize(server->threadedReadBufferSize()); + is_connected = true; +} + + +PICloudServer::Client::~Client() { + // piCoutObj << "~PICloudServer::Client..." << this; + close(); + stopAndWait(); + // piCoutObj << "~PICloudServer::Client done" << this; +} + + +bool PICloudServer::Client::openDevice() { + return is_connected; +} + + +bool PICloudServer::Client::closeDevice() { + // piCoutObj << "closeDevice" << this; + if (is_connected) { + server->clientDisconnect(client_id); + is_connected = false; + } + cond_buff.notifyOne(); + return true; +} + + +ssize_t PICloudServer::Client::readDevice(void * read_to, ssize_t max_size) { + if (!is_connected) return -1; + ssize_t sz = -1; + mutex_buff.lock(); + if (is_connected) { + if (buff.isEmpty()) { + sz = 0; + } else { + sz = piMini(max_size, buff.size()); + memcpy(read_to, buff.data(), sz); + buff.remove(0, sz); + } + if (sz == 0) cond_buff.wait(mutex_buff); + } + mutex_buff.unlock(); + return sz; +} + + +ssize_t PICloudServer::Client::writeDevice(const void * data, ssize_t size) { + if (!is_connected) return -1; + return server->sendData(PIByteArray(data, size), client_id); +} + + +void PICloudServer::Client::interrupt() { + cond_buff.notifyOne(); +} + + +void PICloudServer::Client::pushBuffer(const PIByteArray & ba) { + if (!is_connected) return; + mutex_buff.lock(); + if (buff.size_s() > threadedReadBufferSize()) { + piCoutObj << "Error: buffer overflow, drop" << ba.size() << "bytes"; + mutex_buff.unlock(); + return; + } + buff.append(ba); + cond_buff.notifyOne(); + mutex_buff.unlock(); +} + + +void PICloudServer::_readed(PIByteArray & ba) { + if (is_deleted) return; + PIPair hdr = tcp.parseHeader(ba); + if (hdr.second == tcp.role()) { + switch (hdr.first) { + case PICloud::TCP::Connect: { + uint id = tcp.parseConnect(ba); + clients_mutex.lock(); + Client * oc = index_clients.value(id, nullptr); + clients_mutex.unlock(); + if (oc) { + piCoutObj << "Warning: reject client with duplicated ID"; + tcp.sendDisconnected(id); + } else { + Client * c = new Client(this, id); + // piCoutObj << "new Client" << id << c; + CONNECT1(void, PIObject *, c, deleted, this, clientDeleted); + clients_mutex.lock(); + clients_ << c; + index_clients.insert(id, c); + clients_mutex.unlock(); + newConnection(c); + } + } break; + case PICloud::TCP::Disconnect: { + uint id = tcp.parseDisconnect(ba); + // piCoutObj << "Close on logic"; + clients_mutex.lock(); + Client * oc = index_clients.take(id, nullptr); + clients_.removeOne(oc); + clients_mutex.unlock(); + if (oc) { + oc->stopAndWait(); + oc->is_connected = false; + oc->close(); + removed_clients_ << oc; + // delete oc; + } + } break; + case PICloud::TCP::Data: { + PIPair d = tcp.parseDataServer(ba); + clients_mutex.lock(); + Client * oc = index_clients.value(d.first, nullptr); + clients_mutex.unlock(); + // piCoutObj << "data for" << d.first << d.second.size(); + if (oc && !d.second.isEmpty()) oc->pushBuffer(d.second); + } break; + default: break; + } + } +} + + +void PICloudServer::clientDeleted(PIObject * o) { + PICloudServer::Client * c = (PICloudServer::Client *)o; + // piCoutObj << "clientDeleted" << c; + clients_mutex.lock(); + clients_.removeOne(c); + removed_clients_.removeAll(c); + auto it = index_clients.makeIterator(); + while (it.next()) { + if (it.value() == c) { + index_clients.remove(it.key()); + break; + } + } + clients_mutex.unlock(); +} diff --git a/libs/cloud/picloudtcp.cpp b/libs/cloud/picloudtcp.cpp index a5ff2a6c..861a8069 100644 --- a/libs/cloud/picloudtcp.cpp +++ b/libs/cloud/picloudtcp.cpp @@ -1,181 +1,184 @@ -/* - PIP - Platform Independent Primitives - PICloud TCP transport - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . -*/ - -#include "picloudtcp.h" -#include "picrypt.h" -#include "pichunkstream.h" -#include "piethernet.h" -#include "pistreampacker.h" - - -const char hash_cloud_key[] = "_picloud_"; - - -PICloud::TCP::Header::Header() { - version = Version_2; -} - - -PICloud::TCP::TCP(PIStreamPacker * s) : streampacker(s) { - streampacker->setMaxPacketSize(63*1024); -} - -void PICloud::TCP::setRole(PICloud::TCP::Role r) { - header.role = r; -} - - -void PICloud::TCP::setServerName(const PIString & server_name_) { - server_name = server_name_; - suuid = PICrypt::hash(PIByteArray(server_name_.data(), server_name_.size()), (const unsigned char *)hash_cloud_key, sizeof(hash_cloud_key)); -} - - -PIString PICloud::TCP::serverName() const { - return server_name; -} - - -void PICloud::TCP::sendStart() { - //piCout << "sendStart"; - if (suuid.size() != PICrypt::sizeHash()) { - piCout << "PICloud ERROR, server not set, invoke setServerName first"; - return; - } - header.type = PICloud::TCP::Connect; - PIByteArray ba; - ba << header; - ba.append(suuid); - //mutex_send.lock(); - streampacker->send(ba); - //mutex_send.unlock(); -} - - -void PICloud::TCP::sendConnected(uint client_id) { - header.type = PICloud::TCP::Connect; - PIByteArray ba; - ba << header << client_id; -// mutex_send.lock(); - streampacker->send(ba); -// mutex_send.unlock(); -} - - -void PICloud::TCP::sendDisconnected(uint client_id) { - header.type = PICloud::TCP::Disconnect; - PIByteArray ba; - ba << header << client_id; -// mutex_send.lock(); - streampacker->send(ba); -// mutex_send.unlock(); -} - - -int PICloud::TCP::sendData(const PIByteArray & data) { - header.type = PICloud::TCP::Data; - PIByteArray ba; - ba << header; - ba.append(data); -// piCout << "[PICloud::TCP] sendData" << ba.toHex(); - mutex_send.lock(); - streampacker->send(ba); - mutex_send.unlock(); - return data.size_s(); -} - - -int PICloud::TCP::sendData(const PIByteArray & data, uint client_id) { - header.type = PICloud::TCP::Data; - PIByteArray ba; - ba << header << client_id; - ba.append(data); - mutex_send.lock(); - streampacker->send(ba); - mutex_send.unlock(); - return data.size_s(); -} - - -void PICloud::TCP::sendPing() { - header.type = PICloud::TCP::Ping; - PIByteArray ba; - ba << header; - ba.append(suuid); - mutex_send.lock(); - streampacker->send(ba); - mutex_send.unlock(); -} - - -PIPair PICloud::TCP::parseHeader(PIByteArray & ba) { - PIPair ret; - ret.first = InvalidType; - ret.second = InvalidRole; - if (ba.size() < sizeof(Header)) return ret; - PICloud::TCP::Header hdr; - ba >> hdr; - if (hdr.version != header.version) { - piCout << "[PICloud]" << "invalid PICloud::TCP version!"; - return ret; - } - ret.first = (Type)hdr.type; - ret.second = (Role)hdr.role; - return ret; -} - - -bool PICloud::TCP::canParseData(PIByteArray & ba) { - return header.role == Client; -} - - -PIPair PICloud::TCP::parseDataServer(PIByteArray & ba) { - PIPair ret; - ret.first = 0; - if (header.role == Server) { - ba >> ret.first; - ret.second.swap(ba); - } - return ret; -} - - -PIByteArray PICloud::TCP::parseConnect_d(PIByteArray & ba) { - if (ba.size() != PICrypt::sizeHash()) { - piCout << "PICloud ERROR, invalid server uuid"; - return PIByteArray(); - } else { - return ba; - } -} - - -uint PICloud::TCP::parseConnect(PIByteArray & ba) { - uint ret = 0; - ba >> ret; - return ret; -} - - -uint PICloud::TCP::parseDisconnect(PIByteArray & ba) { - uint ret = 0; - ba >> ret; - return ret; -} +/* + PIP - Platform Independent Primitives + PICloud TCP transport + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . +*/ + +#include "picloudtcp.h" + +#include "pichunkstream.h" +#include "picrypt.h" +#include "piethernet.h" +#include "pistreampacker.h" + + +const char hash_cloud_key[] = "_picloud_"; + + +PICloud::TCP::Header::Header() { + version = Version_2; +} + + +PICloud::TCP::TCP(PIStreamPacker * s): streampacker(s) { + streampacker->setMaxPacketSize(63 * 1024); +} + +void PICloud::TCP::setRole(PICloud::TCP::Role r) { + header.role = r; +} + + +void PICloud::TCP::setServerName(const PIString & server_name_) { + server_name = server_name_; + suuid = + PICrypt::hash(PIByteArray(server_name_.data(), server_name_.size()), (const unsigned char *)hash_cloud_key, sizeof(hash_cloud_key)); +} + + +PIString PICloud::TCP::serverName() const { + return server_name; +} + + +void PICloud::TCP::sendStart() { + // piCout << "sendStart"; + if (suuid.size() != PICrypt::sizeHash()) { + piCout << "PICloud ERROR, server not set, invoke setServerName first"; + return; + } + header.type = PICloud::TCP::Connect; + PIByteArray ba; + ba << header; + ba.append(suuid); + // mutex_send.lock(); + streampacker->send(ba); + // mutex_send.unlock(); +} + + +void PICloud::TCP::sendConnected(uint client_id) { + header.type = PICloud::TCP::Connect; + PIByteArray ba; + ba << header << client_id; + // mutex_send.lock(); + streampacker->send(ba); + // mutex_send.unlock(); +} + + +void PICloud::TCP::sendDisconnected(uint client_id) { + header.type = PICloud::TCP::Disconnect; + PIByteArray ba; + ba << header << client_id; + // mutex_send.lock(); + streampacker->send(ba); + // mutex_send.unlock(); +} + + +int PICloud::TCP::sendData(const PIByteArray & data) { + header.type = PICloud::TCP::Data; + PIByteArray ba; + ba << header; + ba.append(data); + // piCout << "[PICloud::TCP] sendData" << ba.toHex(); + mutex_send.lock(); + streampacker->send(ba); + mutex_send.unlock(); + return data.size_s(); +} + + +int PICloud::TCP::sendData(const PIByteArray & data, uint client_id) { + header.type = PICloud::TCP::Data; + PIByteArray ba; + ba << header << client_id; + ba.append(data); + mutex_send.lock(); + streampacker->send(ba); + mutex_send.unlock(); + return data.size_s(); +} + + +void PICloud::TCP::sendPing() { + header.type = PICloud::TCP::Ping; + PIByteArray ba; + ba << header; + ba.append(suuid); + mutex_send.lock(); + streampacker->send(ba); + mutex_send.unlock(); +} + + +PIPair PICloud::TCP::parseHeader(PIByteArray & ba) { + PIPair ret; + ret.first = InvalidType; + ret.second = InvalidRole; + if (ba.size() < sizeof(Header)) return ret; + PICloud::TCP::Header hdr; + ba >> hdr; + if (hdr.version != header.version) { + piCout << "[PICloud]" + << "invalid PICloud::TCP version!"; + return ret; + } + ret.first = (Type)hdr.type; + ret.second = (Role)hdr.role; + return ret; +} + + +bool PICloud::TCP::canParseData(PIByteArray & ba) { + return header.role == Client; +} + + +PIPair PICloud::TCP::parseDataServer(PIByteArray & ba) { + PIPair ret; + ret.first = 0; + if (header.role == Server) { + ba >> ret.first; + ret.second.swap(ba); + } + return ret; +} + + +PIByteArray PICloud::TCP::parseConnect_d(PIByteArray & ba) { + if (ba.size() != PICrypt::sizeHash()) { + piCout << "PICloud ERROR, invalid server uuid"; + return PIByteArray(); + } else { + return ba; + } +} + + +uint PICloud::TCP::parseConnect(PIByteArray & ba) { + uint ret = 0; + ba >> ret; + return ret; +} + + +uint PICloud::TCP::parseDisconnect(PIByteArray & ba) { + uint ret = 0; + ba >> ret; + return ret; +} diff --git a/libs/compress/picompress.cpp b/libs/compress/picompress.cpp index 3e450960..b82f6208 100644 --- a/libs/compress/picompress.cpp +++ b/libs/compress/picompress.cpp @@ -1,76 +1,81 @@ -/* - PIP - Platform Independent Primitives - Compress class using zlib - Andrey Bychkov work.a.b@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 . -*/ - -#include "picompress.h" -#ifdef PIP_COMPRESS -# ifdef ESP_PLATFORM -# include "esp32/rom/miniz.h" -# define compress2 mz_compress2 -# define Z_OK MZ_OK -# define uncompress mz_uncompress -# else -# include -# endif -#endif - - -PIByteArray piCompress(const PIByteArray & ba, int level) { -#ifdef PIP_COMPRESS - PIByteArray zba; - zba.resize(ba.size() + 128); - int ret = 0; - ulong sz = zba.size(); - ret = compress2(zba.data(), &sz, ba.data(), ba.size(), level); - if (ret != Z_OK) { - piCout << "[PICompress]" << "Error: invalid input or not enought memory"; - return ba; - } - zba.resize(sz); - zba << ullong(ba.size()); - return zba; -#else - piCout << "[PICompress]" << "Warning: PICompress is disabled, to enable install zlib library and build pip_compress library"; -#endif - return ba; -} - - -PIByteArray piDecompress(const PIByteArray & zba) { -#ifdef PIP_COMPRESS - ullong sz = 0; - if (zba.size() < sizeof(ullong)) { - piCout << "[PICompress]" << "Error: invalid input"; - return zba; - } - PIByteArray ba(zba.data(zba.size() - sizeof(ullong)), sizeof(ullong)); - ba >> sz; - ba.resize(sz); - int ret = 0; - ulong s = sz; - ret = uncompress(ba.data(), &s, zba.data(), zba.size()); - if (ret != Z_OK) { - piCout << "[PICompress]" << "Error: invalid input or not enought memory"; - return zba; - } - return ba; -#else - piCout << "[PICompress]" << "Warning: PICompress is disabled, to enable install zlib library and build pip_compress library"; -#endif - return zba; -} +/* + PIP - Platform Independent Primitives + Compress class using zlib + Andrey Bychkov work.a.b@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 . +*/ + +#include "picompress.h" +#ifdef PIP_COMPRESS +# ifdef ESP_PLATFORM +# include "esp32/rom/miniz.h" +# define compress2 mz_compress2 +# define Z_OK MZ_OK +# define uncompress mz_uncompress +# else +# include +# endif +#endif + + +PIByteArray piCompress(const PIByteArray & ba, int level) { +#ifdef PIP_COMPRESS + PIByteArray zba; + zba.resize(ba.size() + 128); + int ret = 0; + ulong sz = zba.size(); + ret = compress2(zba.data(), &sz, ba.data(), ba.size(), level); + if (ret != Z_OK) { + piCout << "[PICompress]" + << "Error: invalid input or not enought memory"; + return ba; + } + zba.resize(sz); + zba << ullong(ba.size()); + return zba; +#else + piCout << "[PICompress]" + << "Warning: PICompress is disabled, to enable install zlib library and build pip_compress library"; +#endif + return ba; +} + + +PIByteArray piDecompress(const PIByteArray & zba) { +#ifdef PIP_COMPRESS + ullong sz = 0; + if (zba.size() < sizeof(ullong)) { + piCout << "[PICompress]" + << "Error: invalid input"; + return zba; + } + PIByteArray ba(zba.data(zba.size() - sizeof(ullong)), sizeof(ullong)); + ba >> sz; + ba.resize(sz); + int ret = 0; + ulong s = sz; + ret = uncompress(ba.data(), &s, zba.data(), zba.size()); + if (ret != Z_OK) { + piCout << "[PICompress]" + << "Error: invalid input or not enought memory"; + return zba; + } + return ba; +#else + piCout << "[PICompress]" + << "Warning: PICompress is disabled, to enable install zlib library and build pip_compress library"; +#endif + return zba; +} diff --git a/libs/console/piscreen.cpp b/libs/console/piscreen.cpp index 70521fda..1cd0baf7 100644 --- a/libs/console/piscreen.cpp +++ b/libs/console/piscreen.cpp @@ -1,20 +1,20 @@ /* - PIP - Platform Independent Primitives - Console output/input - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Console output/input + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include "piscreen.h" @@ -365,15 +365,15 @@ void PIScreen::SystemConsole::clearScreenLower() { #ifdef WINDOWS getWinCurCoord(); FillConsoleOutputAttribute(PRIVATE->hOut, - PRIVATE->dattr, - width * height - width * PRIVATE->ccoord.Y + PRIVATE->ccoord.X, - PRIVATE->ccoord, - &PRIVATE->written); + PRIVATE->dattr, + width * height - width * PRIVATE->ccoord.Y + PRIVATE->ccoord.X, + PRIVATE->ccoord, + &PRIVATE->written); FillConsoleOutputCharacter(PRIVATE->hOut, - ' ', - width * height - width * PRIVATE->ccoord.Y + PRIVATE->ccoord.X, - PRIVATE->ccoord, - &PRIVATE->written); + ' ', + width * height - width * PRIVATE->ccoord.Y + PRIVATE->ccoord.X, + PRIVATE->ccoord, + &PRIVATE->written); #else printf("\e[0m\e[J"); #endif @@ -624,12 +624,12 @@ void PIScreen::run() { tile_dialog->layout(); int dx = tile_dialog->x_ - 1, dy = tile_dialog->y_ - 1, dw = tile_dialog->width_, dh = tile_dialog->height_; drawer_.drawFrame(dx, - dy, - dx + dw + 1, - dy + dh + 1, - (Color)tile_dialog->back_format.color_char, - (Color)tile_dialog->back_format.color_back, - (CharFlags)tile_dialog->back_format.flags); + dy, + dx + dw + 1, + dy + dh + 1, + (Color)tile_dialog->back_format.color_char, + (Color)tile_dialog->back_format.color_back, + (CharFlags)tile_dialog->back_format.flags); tile_dialog->drawEventInternal(&drawer_); } console.print(); diff --git a/libs/console/piscreenconsole.cpp b/libs/console/piscreenconsole.cpp index 6a56825c..9983c878 100644 --- a/libs/console/piscreenconsole.cpp +++ b/libs/console/piscreenconsole.cpp @@ -1,20 +1,20 @@ /* - PIP - Platform Independent Primitives - Tile for PIScreen with PIConsole API - Andrey Bychkov work.a.b@yandex.ru + PIP - Platform Independent Primitives + Tile for PIScreen with PIConsole API + Andrey Bychkov work.a.b@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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include "piscreenconsole.h" @@ -22,21 +22,14 @@ using namespace PIScreenTypes; -TileVars::TileVars(const PIString &n) : PIScreenTile(n) { +TileVars::TileVars(const PIString & n): PIScreenTile(n) { alignment = Left; } -void TileVars::sizeHint(int &w, int &h) const { +void TileVars::sizeHint(int & w, int & h) const {} -} - -void TileVars::drawEvent(PIScreenDrawer *d) { - -} +void TileVars::drawEvent(PIScreenDrawer * d) {} -PIScreenConsoleTile::PIScreenConsoleTile() { - -} - +PIScreenConsoleTile::PIScreenConsoleTile() {} diff --git a/libs/console/piscreendrawer.cpp b/libs/console/piscreendrawer.cpp index 9cec3ce3..0d925bb3 100644 --- a/libs/console/piscreendrawer.cpp +++ b/libs/console/piscreendrawer.cpp @@ -1,20 +1,20 @@ /* - PIP - Platform Independent Primitives - Console output/input - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Console output/input + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include "piscreendrawer.h" @@ -25,68 +25,68 @@ using namespace PIScreenTypes; -PIScreenDrawer::PIScreenDrawer(PIVector > & c): cells(c) { +PIScreenDrawer::PIScreenDrawer(PIVector> & c): cells(c) { arts_[LineVertical] = #ifdef USE_UNICODE - PIChar::fromUTF8("│"); + PIChar::fromUTF8("│"); #else - PIChar('|'); + PIChar('|'); #endif - + arts_[LineHorizontal] = #ifdef USE_UNICODE - PIChar::fromUTF8("─"); + PIChar::fromUTF8("─"); #else - PIChar('-'); + PIChar('-'); #endif - + arts_[Cross] = #ifdef USE_UNICODE - PIChar::fromUTF8("┼"); + PIChar::fromUTF8("┼"); #else - PIChar('+'); + PIChar('+'); #endif - + arts_[CornerTopLeft] = #ifdef USE_UNICODE - PIChar::fromUTF8("┌"); + PIChar::fromUTF8("┌"); #else - PIChar('+'); + PIChar('+'); #endif - + arts_[CornerTopRight] = #ifdef USE_UNICODE - PIChar::fromUTF8("┐"); + PIChar::fromUTF8("┐"); #else - PIChar('+'); + PIChar('+'); #endif - + arts_[CornerBottomLeft] = #ifdef USE_UNICODE - PIChar::fromUTF8("└"); + PIChar::fromUTF8("└"); #else - PIChar('+'); + PIChar('+'); #endif - + arts_[CornerBottomRight] = #ifdef USE_UNICODE - PIChar::fromUTF8("┘"); + PIChar::fromUTF8("┘"); #else - PIChar('+'); + PIChar('+'); #endif arts_[Unchecked] = #ifdef USE_UNICODE - PIChar::fromUTF8("☐"); + PIChar::fromUTF8("☐"); #else - PIChar('O'); + PIChar('O'); #endif arts_[Checked] = #ifdef USE_UNICODE - PIChar::fromUTF8("☑"); + PIChar::fromUTF8("☑"); #else - PIChar('0'); + PIChar('0'); #endif } @@ -98,45 +98,43 @@ void PIScreenDrawer::clear() { void PIScreenDrawer::drawPixel(int x, int y, const PIChar & c, Color col_char, Color col_back, CharFlags flags_char) { if (x < 0 || x >= width || y < 0 || y >= height) return; - cells[y][x].symbol = c; + cells[y][x].symbol = c; cells[y][x].format.color_char = col_char; cells[y][x].format.color_back = col_back; - cells[y][x].format.flags = flags_char; + cells[y][x].format.flags = flags_char; } void PIScreenDrawer::drawLine(int x0, int y0, int x1, int y1, const PIChar & c, Color col_char, Color col_back, CharFlags flags_char) { if (x0 == x1 && y0 == y1) drawPixel(x0, y0, c, col_char, col_back, flags_char); Cell cc; - cc.symbol = c; + cc.symbol = c; cc.format.color_char = col_char; cc.format.color_back = col_back; - cc.format.flags = flags_char; + cc.format.flags = flags_char; int x = 0, y = 0; if (piAbsi(x1 - x0) >= piAbsi(y1 - y0)) { float dy = (y1 - y0) / float(piAbsi(x1 - x0)), cy = y0; int dx = x0 < x1 ? 1 : -1; for (int i = x0; i != x1; i += dx) { - x = i; y = piRound(cy); - if (x >= 0 && x < width && y >= 0 && y < height) - cells[y][x] = cc; + x = i; + y = piRound(cy); + if (x >= 0 && x < width && y >= 0 && y < height) cells[y][x] = cc; cy += dy; } y = piRound(cy); - if (x1 >= 0 && x1 < width && y >= 0 && y < height) - cells[y][x1] = cc; + if (x1 >= 0 && x1 < width && y >= 0 && y < height) cells[y][x1] = cc; } else { float dx = (x1 - x0) / float(piAbsi(y1 - y0)), cx = x0; int dy = y0 < y1 ? 1 : -1; for (int i = y0; i != y1; i += dy) { - x = piRound(cx); y = i; - if (x >= 0 && x < width && y >= 0 && y < height) - cells[y][x] = cc; + x = piRound(cx); + y = i; + if (x >= 0 && x < width && y >= 0 && y < height) cells[y][x] = cc; cx += dx; } x = piRound(cx); - if (x >= 0 && x < width && y1 >= 0 && y1 < height) - cells[y1][x] = cc; + if (x >= 0 && x < width && y1 >= 0 && y1 < height) cells[y1][x] = cc; } } @@ -144,32 +142,29 @@ void PIScreenDrawer::drawLine(int x0, int y0, int x1, int y1, const PIChar & c, void PIScreenDrawer::drawRect(int x0, int y0, int x1, int y1, const PIChar & c, Color col_char, Color col_back, CharFlags flags_char) { if (x0 == x1 && y0 == y1) drawPixel(x0, y0, c, col_char, col_back, flags_char); Cell cc; - cc.symbol = c; + cc.symbol = c; cc.format.color_char = col_char; cc.format.color_back = col_back; - cc.format.flags = flags_char; - int dx = x0 < x1 ? 1 : -1; - int dy = y0 < y1 ? 1 : -1; - int xs[2] = {x0, x1}; - int ys[2] = {y0, y1}; + cc.format.flags = flags_char; + int dx = x0 < x1 ? 1 : -1; + int dy = y0 < y1 ? 1 : -1; + int xs[2] = {x0, x1}; + int ys[2] = {y0, y1}; for (int k = 0; k < 2; ++k) { int j = ys[k]; if (j >= 0 && j < height) { PIVector & cv(cells[j]); for (int i = x0; i != x1; i += dx) - if (i >= 0 && i < width) - cv[i] = cc; + if (i >= 0 && i < width) cv[i] = cc; } j = xs[k]; if (j >= 0 && j < width) { for (int i = y0; i != y1; i += dy) - if (i >= 0 && i < height) - cells[i][j] = cc; + if (i >= 0 && i < height) cells[i][j] = cc; } } int i = x1, j = y1; - if (i >= 0 && i < width && j >= 0 && j < height) - cells[j][i] = cc; + if (i >= 0 && i < width && j >= 0 && j < height) cells[j][i] = cc; } @@ -178,35 +173,37 @@ void PIScreenDrawer::drawFrame(int x0, int y0, int x1, int y1, Color col_char, C Cell cc; cc.format.color_char = col_char; cc.format.color_back = col_back; - cc.format.flags = flags_char; - int dx = x0 < x1 ? 1 : -1; - int dy = y0 < y1 ? 1 : -1; - int xs[2] = {x0, x1}; - int ys[2] = {y0, y1}; + cc.format.flags = flags_char; + int dx = x0 < x1 ? 1 : -1; + int dy = y0 < y1 ? 1 : -1; + int xs[2] = {x0, x1}; + int ys[2] = {y0, y1}; for (int k = 0; k < 2; ++k) { int j = ys[k]; if (j >= 0 && j < height) { PIVector & cv(cells[j]); cc.symbol = artChar(LineHorizontal); for (int i = x0 + 1; i != x1; i += dx) - if (i >= 0 && i < width) - cv[i] = cc; + if (i >= 0 && i < width) cv[i] = cc; } j = xs[k]; if (j >= 0 && j < width) { cc.symbol = artChar(LineVertical); for (int i = y0 + 1; i != y1; i += dy) - if (i >= 0 && i < height) - cells[i][j] = cc; + if (i >= 0 && i < height) cells[i][j] = cc; } } - int i = x0, j = y0; cc.symbol = artChar(CornerTopLeft); + int i = x0, j = y0; + cc.symbol = artChar(CornerTopLeft); if (i >= 0 && i < width && j >= 0 && j < height) cells[j][i] = cc; - i = x1, j = y0; cc.symbol = artChar(CornerTopRight); + i = x1, j = y0; + cc.symbol = artChar(CornerTopRight); if (i >= 0 && i < width && j >= 0 && j < height) cells[j][i] = cc; - i = x0, j = y1; cc.symbol = artChar(CornerBottomLeft); + i = x0, j = y1; + cc.symbol = artChar(CornerBottomLeft); if (i >= 0 && i < width && j >= 0 && j < height) cells[j][i] = cc; - i = x1, j = y1; cc.symbol = artChar(CornerBottomRight); + i = x1, j = y1; + cc.symbol = artChar(CornerBottomRight); if (i >= 0 && i < width && j >= 0 && j < height) cells[j][i] = cc; } @@ -214,23 +211,22 @@ void PIScreenDrawer::drawFrame(int x0, int y0, int x1, int y1, Color col_char, C void PIScreenDrawer::fillRect(int x0, int y0, int x1, int y1, const PIChar & c, Color col_char, Color col_back, CharFlags flags_char) { if (x0 == x1 && y0 == y1) drawPixel(x0, y0, c, col_char, col_back, flags_char); Cell cc; - cc.symbol = c; + cc.symbol = c; cc.format.color_char = col_char; cc.format.color_back = col_back; - cc.format.flags = flags_char; - int dx = x0 < x1 ? 1 : -1; - int dy = y0 < y1 ? 1 : -1; + cc.format.flags = flags_char; + int dx = x0 < x1 ? 1 : -1; + int dy = y0 < y1 ? 1 : -1; for (int j = y0; j != y1; j += dy) if (j >= 0 && j < height) { PIVector & cv(cells[j]); for (int i = x0; i != x1; i += dx) - if (i >= 0 && i < width) - cv[i] = cc; + if (i >= 0 && i < width) cv[i] = cc; } } -void PIScreenDrawer::fillRect(int x0, int y0, int x1, int y1, PIVector > & content) { +void PIScreenDrawer::fillRect(int x0, int y0, int x1, int y1, PIVector> & content) { if (x0 > x1) piSwap(x0, x1); if (y0 > y1) piSwap(y0, y1); int w = x1 - x0; @@ -241,14 +237,13 @@ void PIScreenDrawer::fillRect(int x0, int y0, int x1, int y1, PIVector & cv(cells[y0 + j]); PIVector & contv(content[j]); for (int i = 0; i < piMini(w, contv.size_s()); ++i) - if ((i + x0) >= 0 && (i + x0) < width) - cv[x0 + i] = contv[i]; + if ((i + x0) >= 0 && (i + x0) < width) cv[x0 + i] = contv[i]; } } } -void PIScreenDrawer::clear(PIVector > & cells) { +void PIScreenDrawer::clear(PIVector> & cells) { for (int i = 0; i < cells.size_s(); ++i) cells[i].fill(Cell()); } @@ -260,12 +255,12 @@ void PIScreenDrawer::drawText(int x, int y, const PIString & s, Color col_char, Cell cc; cc.format.color_char = col_char; cc.format.color_back = col_back; - cc.format.flags = flags_char; + cc.format.flags = flags_char; for (int i = 0; i < s.size_s(); ++i) { int j = i + x; if (j >= 0 && j < width) { cc.symbol = s[i]; - cv[j] = cc; + cv[j] = cc; } } } diff --git a/libs/console/piscreentile.cpp b/libs/console/piscreentile.cpp index f24ebf17..d4c499c5 100644 --- a/libs/console/piscreentile.cpp +++ b/libs/console/piscreentile.cpp @@ -1,23 +1,24 @@ /* - PIP - Platform Independent Primitives - Basic PIScreen tile - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Basic PIScreen tile + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include "piscreentile.h" + #include "piscreendrawer.h" @@ -25,24 +26,23 @@ using namespace PIScreenTypes; PIScreenTile::PIScreenTile(const PIString & n, Direction d, SizePolicy p): PIObject(n) { - direction = d; - size_policy = p; - focus_flags = 0; - screen = 0; + direction = d; + size_policy = p; + focus_flags = 0; + screen = 0; minimumWidth = minimumHeight = x_ = y_ = width_ = height_ = pw = ph = 0; maximumWidth = maximumHeight = 65535; marginLeft = marginRight = marginTop = marginBottom = spacing = 0; - parent = 0; - back_symbol = ' '; - visible = true; - has_focus = false; + parent = 0; + back_symbol = ' '; + visible = true; + has_focus = false; } PIScreenTile::~PIScreenTile() { - //piCout << this << "~"; - if (screen) - screen->tileRemovedInternal(this); + // piCout << this << "~"; + if (screen) screen->tileRemovedInternal(this); setScreen(0); deleteChildren(); if (!parent) return; @@ -76,20 +76,18 @@ void PIScreenTile::removeTile(PIScreenTile * t) { } -PIVector PIScreenTile::children(bool only_visible) { - PIVector ret; - piForeach (PIScreenTile * t, tiles) - if (t->visible || !only_visible) - ret << t << t->children(only_visible); +PIVector PIScreenTile::children(bool only_visible) { + PIVector ret; + piForeach(PIScreenTile * t, tiles) + if (t->visible || !only_visible) ret << t << t->children(only_visible); return ret; } PIScreenTile * PIScreenTile::childUnderMouse(int x, int y) { - piForeach (PIScreenTile * t, tiles) { + piForeach(PIScreenTile * t, tiles) { if (!t->visible) continue; - if (x >= t->x_ && (x - t->x_) < t->width_ && - y >= t->y_ && (y - t->y_) < t->height_) { + if (x >= t->x_ && (x - t->x_) < t->width_ && y >= t->y_ && (y - t->y_) < t->height_) { return t; } } @@ -105,13 +103,13 @@ void PIScreenTile::raiseEvent(TileEvent e) { void PIScreenTile::setScreen(PIScreenBase * s) { screen = s; - piForeach (PIScreenTile * t, tiles) + piForeach(PIScreenTile * t, tiles) t->setScreen(s); } void PIScreenTile::deleteChildren() { - piForeach (PIScreenTile * t, tiles) { + piForeach(PIScreenTile * t, tiles) { t->parent = 0; delete t; } @@ -129,9 +127,16 @@ void PIScreenTile::drawEventInternal(PIScreenDrawer * d) { if (!visible) { return; } - d->fillRect(x_, y_, x_ + width_, y_ + height_, back_symbol, (Color)back_format.color_char, (Color)back_format.color_back, back_format.flags); + d->fillRect(x_, + y_, + x_ + width_, + y_ + height_, + back_symbol, + (Color)back_format.color_char, + (Color)back_format.color_back, + back_format.flags); drawEvent(d); - piForeach (PIScreenTile * t, tiles) + piForeach(PIScreenTile * t, tiles) t->drawEventInternal(d); } @@ -141,18 +146,22 @@ void PIScreenTile::sizeHint(int & w, int & h) const { h = 0; if (tiles.isEmpty()) return; int sl = spacing * (tiles.size_s() - 1); - if (direction == Horizontal) w += sl; - else h += sl; - piForeachC (PIScreenTile * t, tiles) { + if (direction == Horizontal) + w += sl; + else + h += sl; + piForeachC(PIScreenTile * t, tiles) { if (!t->visible) continue; int cw(0), ch(0); t->sizeHint(cw, ch); cw = piClampi(cw, t->minimumWidth, t->maximumWidth); ch = piClampi(ch, t->minimumHeight, t->maximumHeight); if (direction == Horizontal) { - w += cw; h = piMaxi(h, ch); + w += cw; + h = piMaxi(h, ch); } else { - h += ch; w = piMaxi(w, cw); + h += ch; + w = piMaxi(w, cw); } } w += marginLeft + marginRight; @@ -163,7 +172,7 @@ void PIScreenTile::sizeHint(int & w, int & h) const { void PIScreenTile::layout() { if (tiles.isEmpty() || !visible) return; int as(0), ts(0), ts2(0), ecnt(0), pcnt(0); - ts = (direction == Horizontal) ? (width_ - marginLeft - marginRight) : (height_ - marginTop - marginBottom); + ts = (direction == Horizontal) ? (width_ - marginLeft - marginRight) : (height_ - marginTop - marginBottom); ts2 = (direction != Horizontal) ? (width_ - marginLeft - marginRight) : (height_ - marginTop - marginBottom); ts -= spacing * (tiles.size_s() - 1); PIVector hints(tiles.size_s()); @@ -180,7 +189,7 @@ void PIScreenTile::layout() { cs = (direction == Horizontal) ? cw : ch; as += cs; } - hints[i] = cs; + hints[i] = cs; asizes[i] = 0.f; } if (as <= ts) { @@ -188,10 +197,10 @@ void PIScreenTile::layout() { SizePolicy pol = Fixed; if (ecnt > 0) { acnt = ecnt; - pol = Expanding; + pol = Expanding; } else if (pcnt > 0) { acnt = pcnt; - pol = Preferred; + pol = Preferred; } if (acnt > 0) { float add_a = float(ts - as), add_s = add_a / acnt, add_da(0.); @@ -210,8 +219,7 @@ void PIScreenTile::layout() { for (int j = 0; j < tiles.size_s(); ++j) { if (i == j) continue; if (max_tl[j]) continue; - if (tiles[j]->size_policy == pol && tiles[j]->visible && tiles[j]->needLayout()) - asizes[j] += pas; + if (tiles[j]->size_policy == pol && tiles[j]->visible && tiles[j]->needLayout()) asizes[j] += pas; } } } @@ -233,16 +241,15 @@ void PIScreenTile::layout() { t->x_ = cx; t->y_ = cy; if (direction == Horizontal) { - t->width_ = hints[i]; + t->width_ = hints[i]; t->height_ = ts2; cx += hints[i] + spacing; } else { - t->width_ = ts2; + t->width_ = ts2; t->height_ = hints[i]; cy += hints[i] + spacing; } - if (t->pw != t->width_ || t->ph != t->height_) - t->resizeEvent(t->width_, t->height_); + if (t->pw != t->width_ || t->ph != t->height_) t->resizeEvent(t->width_, t->height_); t->pw = t->width_; t->ph = t->height_; t->layout(); diff --git a/libs/console/piscreentiles.cpp b/libs/console/piscreentiles.cpp index e73f95c1..087f407c 100644 --- a/libs/console/piscreentiles.cpp +++ b/libs/console/piscreentiles.cpp @@ -1,20 +1,20 @@ /* - PIP - Platform Independent Primitives - Various tiles for PIScreen - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Various tiles for PIScreen + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include "piscreentiles.h" diff --git a/libs/console/piterminal.cpp b/libs/console/piterminal.cpp index bde71d51..47bde073 100644 --- a/libs/console/piterminal.cpp +++ b/libs/console/piterminal.cpp @@ -1,58 +1,60 @@ /* - PIP - Platform Independent Primitives - Virtual terminal - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Virtual terminal + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ -#include "piincludes_p.h" #include "piterminal.h" + +#include "piincludes_p.h" #include "pisharedmemory.h" #ifndef MICRO_PIP -#ifdef WINDOWS -# include -# include -# include -# include -#else -# include "piprocess.h" -# include -# include -# include -# if defined(QNX) || defined(BLACKBERRY) -# include +# ifdef WINDOWS +# include +# include +# include +# include # else -# ifdef MAC_OS -# include -# else -# include -# endif +# include "piprocess.h" + +# include +# include +# include +# if defined(QNX) || defined(BLACKBERRY) +# include +# else +# ifdef MAC_OS +# include +# else +# include +# endif +# endif +# ifdef ANDROID +# if __ANDROID_API__ >= 23 +# define HAS_FORKPTY +# endif +# else +# define HAS_FORKPTY +# endif # endif -# ifdef ANDROID -# if __ANDROID_API__ >= 23 -# define HAS_FORKPTY -# endif -# else -# define HAS_FORKPTY -# endif -#endif -//extern PIMutex PICout::__mutex__; +// extern PIMutex PICout::__mutex__; -#ifdef WINDOWS -# define PIPE_BUFFER_SIZE 1024 +# ifdef WINDOWS +# define PIPE_BUFFER_SIZE 1024 enum PITerminalAuxMessageType { mtKey = 1, mtResize, @@ -65,22 +67,22 @@ struct PITerminalAuxData { int size_y; int cells_size; }; -#else -# define BUFFER_SIZE 4096 +# else +# define BUFFER_SIZE 4096 enum DECType { CKM = 1 }; -#endif +# endif PRIVATE_DEFINITION_START(PITerminal) -#ifdef WINDOWS +# ifdef WINDOWS PISharedMemory * shm; HANDLE hConBuf; STARTUPINFOA si; PROCESS_INFORMATION pi; HANDLE pipe; -#else +# else PIString shell; PIByteArray read_buf, tmp_buf; PIScreenTypes::CellFormat cur_format, line_format; @@ -92,21 +94,21 @@ PRIVATE_DEFINITION_START(PITerminal) PIString esc_seq; bool is_esc_seq, last_read; PIMap DEC; - PIVector > cells_save; -#endif + PIVector> cells_save; +# endif PRIVATE_DEFINITION_END(PITerminal) -#ifdef WINDOWS +# ifdef WINDOWS int writePipe(HANDLE pipe, const PIByteArray & ba) { DWORD wrote[2]; int sz = ba.size_s(); WriteFile(pipe, &sz, 4, &(wrote[0]), 0); WriteFile(pipe, ba.data(), ba.size_s(), &(wrote[1]), 0); - //piCout << "send" << ba.size_s(); + // piCout << "send" << ba.size_s(); return int(wrote[0] + wrote[1]); } -#endif +# endif PITerminal::PITerminal(): PIThread() { @@ -114,42 +116,41 @@ PITerminal::PITerminal(): PIThread() { initPrivate(); cursor_blink = false; cursor_x = cursor_y = 0; - dsize_x = 80; - dsize_y = 24; -#ifdef WINDOWS + dsize_x = 80; + dsize_y = 24; +# ifdef WINDOWS PRIVATE->shm = 0; -#endif +# endif } PITerminal::~PITerminal() { - if (isRunning()) - stop(); + if (isRunning()) stop(); PIThread::waitForFinish(10); destroy(); -#ifdef WINDOWS +# ifdef WINDOWS if (PRIVATE->shm) delete PRIVATE->shm; -#endif +# endif } void PITerminal::write(const PIByteArray & d) { -#ifdef WINDOWS +# ifdef WINDOWS PIByteArray msg; PIVector ke; for (int i = 0; i < d.size_s(); ++i) ke << PIKbdListener::KeyEvent(d[i]); msg << int(mtKey) << ke; writePipe(PRIVATE->pipe, msg); -#else -# ifdef HAS_FORKPTY +# else +# ifdef HAS_FORKPTY if (PRIVATE->fd == 0) return; - //ssize_t wrote = 0; - //wrote = + // ssize_t wrote = 0; + // wrote = ::write(PRIVATE->fd, d.data(), d.size_s()); - //piCout << "wrote" << wrote << d; + // piCout << "wrote" << wrote << d; +# endif # endif -#endif cursor_tm.reset(); cursor_blink = true; } @@ -157,15 +158,16 @@ void PITerminal::write(const PIByteArray & d) { void PITerminal::write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers m) { PIByteArray ba; -#ifdef WINDOWS +# ifdef WINDOWS switch (k) { - case PIKbdListener::Tab: ba << uchar('\t'); break; + case PIKbdListener::Tab: ba << uchar('\t'); break; case PIKbdListener::Return: ba << uchar('\r') << uchar('\n'); break; - case PIKbdListener::Space: ba << uchar(' '); break; + case PIKbdListener::Space: ba << uchar(' '); break; default: break; } - //piCout << "write" << ba.size(); - if (!ba.isEmpty()) write(ba); + // piCout << "write" << ba.size(); + if (!ba.isEmpty()) + write(ba); else { PIByteArray msg; PIVector ke; @@ -173,19 +175,20 @@ void PITerminal::write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers msg << int(mtKey) << ke; writePipe(PRIVATE->pipe, msg); } -#else - int term = PRIVATE->term_type; +# else + int term = PRIVATE->term_type; int flags = 0; switch (k) { - case PIKbdListener::Tab: ba << uchar('\t'); break; - case PIKbdListener::Return: ba << uchar('\n'); break; - case PIKbdListener::Esc: ba << uchar('\e'); break; - case PIKbdListener::Space: ba << uchar(' '); break; - case PIKbdListener::Backspace: ba << uchar(0x7f); break; - case PIKbdListener::UpArrow: - case PIKbdListener::DownArrow: - case PIKbdListener::RightArrow: - case PIKbdListener::LeftArrow: if (PRIVATE->DEC.value(CKM, false)) flags = 1; + case PIKbdListener::Tab: ba << uchar('\t'); break; + case PIKbdListener::Return: ba << uchar('\n'); break; + case PIKbdListener::Esc: ba << uchar('\e'); break; + case PIKbdListener::Space: ba << uchar(' '); break; + case PIKbdListener::Backspace: ba << uchar(0x7f); break; + case PIKbdListener::UpArrow: + case PIKbdListener::DownArrow: + case PIKbdListener::RightArrow: + case PIKbdListener::LeftArrow: + if (PRIVATE->DEC.value(CKM, false)) flags = 1; /*case PIKbdListener::Home: //break; case PIKbdListener::End: //break; case PIKbdListener::PageUp: //ba << uchar('\e') << uchar('[') << uchar('5') << uchar('~'); break; @@ -206,55 +209,55 @@ void PITerminal::write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers case PIKbdListener::F12: //break; */ default: { - //piCout << flags; - //int mod = 0; + // piCout << flags; + // int mod = 0; if (m[PIKbdListener::Shift]) m |= 1; - if (m[PIKbdListener::Alt]) m |= 2; - if (m[PIKbdListener::Ctrl]) m |= 4; - for (int i = 0; ; ++i) { + if (m[PIKbdListener::Alt]) m |= 2; + if (m[PIKbdListener::Ctrl]) m |= 4; + for (int i = 0;; ++i) { const PIKbdListener::EscSeq & e(PIKbdListener::esc_seq[i]); if (!e.seq) break; - //piCout << "search" << rc[1] << esc_seq[i].seq; + // piCout << "search" << rc[1] << esc_seq[i].seq; if (e.key == k && e.mod == m) { if (((e.vt & term) == term) || (((e.flags & flags) == flags) && (flags != 0))) { - //piCout << "found key" << PIString(e.seq).replaceAll("\e", "\\e"); + // piCout << "found key" << PIString(e.seq).replaceAll("\e", "\\e"); PIByteArray d = ("\e" + PIString(e.seq)).toByteArray(); write(d); break; } } } - } break; + } break; } - //piCout << "write" << ba.size(); + // piCout << "write" << ba.size(); if (!ba.isEmpty()) write(ba); -#endif +# endif cursor_tm.reset(); cursor_blink = true; } void PITerminal::write(PIKbdListener::KeyEvent ke) { - if (isSpecialKey(ke.key)) write((PIKbdListener::SpecialKey)ke.key, ke.modifiers); + if (isSpecialKey(ke.key)) + write((PIKbdListener::SpecialKey)ke.key, ke.modifiers); else { PIByteArray ba; -#ifdef WINDOWS +# ifdef WINDOWS ba << uchar(PIChar((ushort)ke.key).toConsole1Byte()); -#else +# else ba = PIString(PIChar((ushort)ke.key)).toUTF8(); -#endif +# endif write(ba); } } -PIVector > PITerminal::content() { +PIVector> PITerminal::content() { readConsole(); - PIVector > ret = cells; + PIVector> ret = cells; if (cursor_blink && cursor_visible) if (cursor_x >= 0 && cursor_x < size_x) - if (cursor_y >= 0 && cursor_y < size_y) - ret[cursor_y][cursor_x].format.flags ^= PIScreenTypes::Inverse; + if (cursor_y >= 0 && cursor_y < size_y) ret[cursor_y][cursor_x].format.flags ^= PIScreenTypes::Inverse; return ret; } @@ -295,56 +298,56 @@ bool PITerminal::isSpecialKey(int k) { void PITerminal::initPrivate() { -#ifdef WINDOWS - PRIVATE->hConBuf = INVALID_HANDLE_VALUE; - PRIVATE->pipe = INVALID_HANDLE_VALUE; +# ifdef WINDOWS + PRIVATE->hConBuf = INVALID_HANDLE_VALUE; + PRIVATE->pipe = INVALID_HANDLE_VALUE; PRIVATE->pi.hProcess = 0; -#else +# else PRIVATE->shell = "/bin/bash"; PRIVATE->read_buf.reserve(BUFFER_SIZE); PRIVATE->read_buf.fill(0); PRIVATE->fd = PRIVATE->cur_x = PRIVATE->cur_y = 0; PRIVATE->save_cur_x = PRIVATE->save_cur_y = 0; - PRIVATE->pid = 0; - PRIVATE->term_type = 0; - PRIVATE->is_esc_seq = false; - PRIVATE->last_read = true; + PRIVATE->pid = 0; + PRIVATE->term_type = 0; + PRIVATE->is_esc_seq = false; + PRIVATE->last_read = true; PRIVATE->esc_seq.clear(); PRIVATE->cur_format = PIScreenTypes::CellFormat(); -#endif +# endif cursor_blink = cursor_visible = true; size_x = size_y = 0; } void PITerminal::readConsole() { -#ifdef WINDOWS +# ifdef WINDOWS if (!PRIVATE->shm) return; PITerminalAuxData data; PRIVATE->shm->read(&data, sizeof(data)); if (data.cells_size <= 4) return; cursor_x = data.cursor_x; cursor_y = data.cursor_y; - size_x = data.size_x; - size_y = data.size_y; + size_x = data.size_x; + size_y = data.size_y; PIByteArray ba; ba.resize(data.cells_size); PRIVATE->shm->read(ba.data(), ba.size_s(), sizeof(data)); ba >> cells; -#endif - //piCout << cursor_x << cursor_y; +# endif + // piCout << cursor_x << cursor_y; } void PITerminal::getCursor(int & x, int & y) { -#ifdef WINDOWS +# ifdef WINDOWS if (!PRIVATE->shm) return; int sz = 0; PRIVATE->shm->read(&sz, 4); -#else - x = PRIVATE->cur_x; - y = PRIVATE->cur_y; -#endif +# else + x = PRIVATE->cur_x; + y = PRIVATE->cur_y; +# endif } @@ -370,16 +373,16 @@ void PITerminal::run() { cursor_tm.reset(); cursor_blink = !cursor_blink; } -#ifndef WINDOWS -# ifdef HAS_FORKPTY +# ifndef WINDOWS +# ifdef HAS_FORKPTY if (PRIVATE->fd == 0) return; PRIVATE->tmp_buf.resize(BUFFER_SIZE); int readed = ::read(PRIVATE->fd, PRIVATE->tmp_buf.data(), BUFFER_SIZE - PRIVATE->read_buf.size_s()); - bool used = false; + bool used = false; if (readed > 0) { PRIVATE->last_read = true; - //piCoutObj << "readed" << readed << PIString(PRIVATE->tmp_buf.resized(readed)).replaceAll("\e", "\\e"); - //piCoutObj << "readed" << readed << (PRIVATE->tmp_buf.resized(readed)); + // piCoutObj << "readed" << readed << PIString(PRIVATE->tmp_buf.resized(readed)).replaceAll("\e", "\\e"); + // piCoutObj << "readed" << readed << (PRIVATE->tmp_buf.resized(readed)); PRIVATE->read_buf.append(PRIVATE->tmp_buf.resized(readed)); for (;;) { int ind = -1; @@ -395,28 +398,27 @@ void PITerminal::run() { } bool parse = PRIVATE->read_buf.size_s() >= BUFFER_SIZE; if (PRIVATE->read_buf.size_s() == 1) - if (PRIVATE->read_buf[0] < 0x80) - parse = true; + if (PRIVATE->read_buf[0] < 0x80) parse = true; if (parse) { parseInput(PIString(PRIVATE->read_buf)); PRIVATE->read_buf.clear(); } - //printf("%s", PRIVATE->read_buf.data()); + // printf("%s", PRIVATE->read_buf.data()); } if (!used && !PRIVATE->last_read && !PRIVATE->read_buf.isEmpty()) { parseInput(PIString(PRIVATE->read_buf)); PRIVATE->read_buf.clear(); } PRIVATE->last_read = false; +# endif # endif -#endif } -#ifndef WINDOWS +# ifndef WINDOWS void PITerminal::parseInput(const PIString & s) { - //piCoutObj << s.replaceAll("\e", "\\e"); - //printf("%s", s.data()); + // piCoutObj << s.replaceAll("\e", "\\e"); + // printf("%s", s.data()); for (int i = 0; i < s.size_s(); ++i) { if (s[i].unicode16Code() == 0) break; if (PRIVATE->is_esc_seq) { @@ -429,7 +431,7 @@ void PITerminal::parseInput(const PIString & s) { if (isCompleteEscSeq(PRIVATE->esc_seq)) { PRIVATE->is_esc_seq = false; applyEscSeq(PRIVATE->esc_seq); - //piCoutObj << PRIVATE->esc_seq; + // piCoutObj << PRIVATE->esc_seq; } } } else { @@ -444,14 +446,15 @@ void PITerminal::parseInput(const PIString & s) { } if (s[i] == '\r') continue; if (s[i] == '\n') { - //piCoutObj << "new line"; - for (int i = PRIVATE->cur_x; i < size_x; ++i) cells[PRIVATE->cur_y][i].format = PRIVATE->cur_format; + // piCoutObj << "new line"; + for (int i = PRIVATE->cur_x; i < size_x; ++i) + cells[PRIVATE->cur_y][i].format = PRIVATE->cur_format; PRIVATE->line_format = PRIVATE->cur_format; - PRIVATE->cur_x = 0; + PRIVATE->cur_x = 0; moveCursor(0, 1); continue; } - //piCoutObj << "char" << s[i] << s[i].unicode16Code() << "at" << PRIVATE->cur_x << PRIVATE->cur_y; + // piCoutObj << "char" << s[i] << s[i].unicode16Code() << "at" << PRIVATE->cur_x << PRIVATE->cur_y; cells[PRIVATE->cur_y][PRIVATE->cur_x].symbol = s[i]; cells[PRIVATE->cur_y][PRIVATE->cur_x].format = PRIVATE->cur_format; moveCursor(1, 0); @@ -475,10 +478,10 @@ bool PITerminal::isCompleteEscSeq(const PIString & es) { void PITerminal::applyEscSeq(PIString es) { piCoutObj << es; if (es.size_s() < 2) return; -// PIScreenTypes::Cell line_cell = PIScreenTypes::Cell(' ', PRIVATE->line_format); + // PIScreenTypes::Cell line_cell = PIScreenTypes::Cell(' ', PRIVATE->line_format); PIScreenTypes::Cell def_cell = PIScreenTypes::Cell(' ', PRIVATE->cur_format); if (es[1] == '?' && es.size_s() >= 2) { - char a = es.takeRight(1)[0].toAscii(); + char a = es.takeRight(1)[0].toAscii(); bool val = false; if (a == 'l') val = false; if (a == 'h') val = true; @@ -498,7 +501,8 @@ void PITerminal::applyEscSeq(PIString es) { case 1047: if (val) { PRIVATE->cells_save = cells; - for (int i = 0; i < size_y; ++i) cells[i].fill(def_cell); + for (int i = 0; i < size_y; ++i) + cells[i].fill(def_cell); } else { cells = PRIVATE->cells_save; } @@ -513,7 +517,7 @@ void PITerminal::applyEscSeq(PIString es) { return; } PIStringList args = es.split(";"); - piForeachC (PIString & a, args) { + piForeachC(PIString & a, args) { int av = a.toInt(); switch (av) { case 0: PRIVATE->cur_format = PIScreenTypes::CellFormat(); break; @@ -524,8 +528,14 @@ void PITerminal::applyEscSeq(PIString es) { default: { bool col = false, target = false; int cid = av % 10; - if (av >= 30 && av <= 37) {col = true; target = false;} - if (av >= 40 && av <= 47) {col = true; target = true;} + if (av >= 30 && av <= 37) { + col = true; + target = false; + } + if (av >= 40 && av <= 47) { + col = true; + target = true; + } if (col) { int cfl = 0; switch (cid) { @@ -544,13 +554,13 @@ void PITerminal::applyEscSeq(PIString es) { PRIVATE->cur_format.color_char = cfl; break; } - } break; + } break; } } /*if ((PRIVATE->cur_format.flags & PIScreenTypes::Inverse) == PIScreenTypes::Inverse) { - uchar t = PRIVATE->cur_format.color_char; - PRIVATE->cur_format.color_char = PRIVATE->cur_format.color_back; - PRIVATE->cur_format.color_back = t; + uchar t = PRIVATE->cur_format.color_char; + PRIVATE->cur_format.color_char = PRIVATE->cur_format.color_back; + PRIVATE->cur_format.color_back = t; }*/ } if (es.back() == 'r') { @@ -579,33 +589,37 @@ void PITerminal::applyEscSeq(PIString es) { int x(0), y(0); if (!args[0].isEmpty()) y = args[0].toInt() - 1; if (!args[1].isEmpty()) x = args[1].toInt() - 1; - //piCoutObj << x << y; - PRIVATE->cur_x = piClamp(x, 0, size_x - 1); - PRIVATE->cur_y = piClamp(y, 0, size_y - 1); + // piCoutObj << x << y; + PRIVATE->cur_x = piClamp(x, 0, size_x - 1); + PRIVATE->cur_y = piClamp(y, 0, size_y - 1); PRIVATE->line_format = PRIVATE->cur_format; } if (es.back() == 'A') { // cursor up es.cutLeft(1).cutRight(1); - int v = es.toInt(); if (v == 0) v = 1; - PRIVATE->cur_y = piClamp(PRIVATE->cur_y - v, 0, size_y - 1); + int v = es.toInt(); + if (v == 0) v = 1; + PRIVATE->cur_y = piClamp(PRIVATE->cur_y - v, 0, size_y - 1); PRIVATE->line_format = PRIVATE->cur_format; } if (es.back() == 'B') { // cursor down es.cutLeft(1).cutRight(1); - int v = es.toInt(); if (v == 0) v = 1; - PRIVATE->cur_y = piClamp(PRIVATE->cur_y + v, 0, size_y - 1); + int v = es.toInt(); + if (v == 0) v = 1; + PRIVATE->cur_y = piClamp(PRIVATE->cur_y + v, 0, size_y - 1); PRIVATE->line_format = PRIVATE->cur_format; } if (es.back() == 'C' || es.back() == 'a') { // cursor forward, next column es.cutLeft(1).cutRight(1); - int v = es.toInt(); if (v == 0) v = 1; - PRIVATE->cur_x = piClamp(PRIVATE->cur_x + v, 0, size_x - 1); + int v = es.toInt(); + if (v == 0) v = 1; + PRIVATE->cur_x = piClamp(PRIVATE->cur_x + v, 0, size_x - 1); PRIVATE->line_format = PRIVATE->cur_format; } if (es.back() == 'D') { // cursor back es.cutLeft(1).cutRight(1); - int v = es.toInt(); if (v == 0) v = 1; - PRIVATE->cur_x = piClamp(PRIVATE->cur_x - v, 0, size_x - 1); + int v = es.toInt(); + if (v == 0) v = 1; + PRIVATE->cur_x = piClamp(PRIVATE->cur_x - v, 0, size_x - 1); PRIVATE->line_format = PRIVATE->cur_format; } if (es.back() == 'G' || es.back() == '`') { // goto column @@ -616,66 +630,92 @@ void PITerminal::applyEscSeq(PIString es) { } if (es.back() == 'd') { // goto line es.cutLeft(1).cutRight(1); - int v = es.toInt(); if (v == 0) v = 1; - PRIVATE->cur_x = 0; - PRIVATE->cur_y = piClamp(v - 1, 0, size_y - 1); + int v = es.toInt(); + if (v == 0) v = 1; + PRIVATE->cur_x = 0; + PRIVATE->cur_y = piClamp(v - 1, 0, size_y - 1); PRIVATE->line_format = PRIVATE->cur_format; } if (es.back() == 'E' || es.back() == 'e') { // next line es.cutLeft(1).cutRight(1); - int v = es.toInt(); if (v == 0) v = 1; - PRIVATE->cur_x = 0; - PRIVATE->cur_y = piClamp(PRIVATE->cur_y + v, 0, size_y - 1); + int v = es.toInt(); + if (v == 0) v = 1; + PRIVATE->cur_x = 0; + PRIVATE->cur_y = piClamp(PRIVATE->cur_y + v, 0, size_y - 1); PRIVATE->line_format = PRIVATE->cur_format; } if (es.back() == 'F') { // previous line es.cutLeft(1).cutRight(1); - int v = es.toInt(); if (v == 0) v = 1; - PRIVATE->cur_x = 0; - PRIVATE->cur_y = piClamp(PRIVATE->cur_y - v, 0, size_y - 1); + int v = es.toInt(); + if (v == 0) v = 1; + PRIVATE->cur_x = 0; + PRIVATE->cur_y = piClamp(PRIVATE->cur_y - v, 0, size_y - 1); PRIVATE->line_format = PRIVATE->cur_format; } if (es.back() == 'L') { // insert lines es.cutLeft(1).cutRight(1); - int v = es.toInt(); if (v == 0) v = 1; - for (int i = piClamp(size_y - 1, PRIVATE->win_y0, PRIVATE->win_y1); i >= piClamp(PRIVATE->cur_y + v, PRIVATE->win_y0, PRIVATE->win_y1); --i) cells[i] = cells[i - v]; - for (int j = piClamp(PRIVATE->cur_y, PRIVATE->win_y0, PRIVATE->win_y1); j < piClamp(PRIVATE->cur_y + v, PRIVATE->win_y0, PRIVATE->win_y1); ++j) - for (int i = 0; i < PRIVATE->cur_x; ++i) cells[j][i] = def_cell; + int v = es.toInt(); + if (v == 0) v = 1; + for (int i = piClamp(size_y - 1, PRIVATE->win_y0, PRIVATE->win_y1); + i >= piClamp(PRIVATE->cur_y + v, PRIVATE->win_y0, PRIVATE->win_y1); + --i) + cells[i] = cells[i - v]; + for (int j = piClamp(PRIVATE->cur_y, PRIVATE->win_y0, PRIVATE->win_y1); + j < piClamp(PRIVATE->cur_y + v, PRIVATE->win_y0, PRIVATE->win_y1); + ++j) + for (int i = 0; i < PRIVATE->cur_x; ++i) + cells[j][i] = def_cell; } if (es.back() == 'M') { // delete lines es.cutLeft(1).cutRight(1); - int v = es.toInt(); if (v == 0) v = 1; - for (int i = piClamp(PRIVATE->cur_y, PRIVATE->win_y0, PRIVATE->win_y1); i < piClamp(size_y - v, PRIVATE->win_y0, PRIVATE->win_y1); ++i) cells[i] = cells[i + v]; + int v = es.toInt(); + if (v == 0) v = 1; + for (int i = piClamp(PRIVATE->cur_y, PRIVATE->win_y0, PRIVATE->win_y1); + i < piClamp(size_y - v, PRIVATE->win_y0, PRIVATE->win_y1); + ++i) + cells[i] = cells[i + v]; for (int j = piClamp(size_y - v, PRIVATE->win_y0, PRIVATE->win_y1); j < piClamp(size_y, PRIVATE->win_y0, PRIVATE->win_y1); ++j) - for (int i = 0; i < PRIVATE->cur_x; ++i) cells[j][i] = def_cell; + for (int i = 0; i < PRIVATE->cur_x; ++i) + cells[j][i] = def_cell; } if (es.back() == 'P') { // delete characters es.cutLeft(1).cutRight(1); - int v = es.toInt(); if (v == 0) v = 1; - for (int i = PRIVATE->cur_x; i < size_x - v; ++i) cells[PRIVATE->cur_y][i] = cells[PRIVATE->cur_y][i + v]; - for (int i = size_x - v; i < size_x; ++i) cells[PRIVATE->cur_y][i] = def_cell; + int v = es.toInt(); + if (v == 0) v = 1; + for (int i = PRIVATE->cur_x; i < size_x - v; ++i) + cells[PRIVATE->cur_y][i] = cells[PRIVATE->cur_y][i + v]; + for (int i = size_x - v; i < size_x; ++i) + cells[PRIVATE->cur_y][i] = def_cell; } if (es.back() == '@') { // delete characters es.cutLeft(1).cutRight(1); - int v = es.toInt(); if (v == 0) v = 1; - for (int i = size_x - 1; i >= PRIVATE->cur_x + v; --i) cells[PRIVATE->cur_y][i] = cells[PRIVATE->cur_y][i - v]; - for (int i = PRIVATE->cur_x; i < PRIVATE->cur_x + v; ++i) cells[PRIVATE->cur_y][i] = def_cell; + int v = es.toInt(); + if (v == 0) v = 1; + for (int i = size_x - 1; i >= PRIVATE->cur_x + v; --i) + cells[PRIVATE->cur_y][i] = cells[PRIVATE->cur_y][i - v]; + for (int i = PRIVATE->cur_x; i < PRIVATE->cur_x + v; ++i) + cells[PRIVATE->cur_y][i] = def_cell; } if (es.back() == 'J') { // erase data es.cutLeft(1).cutRight(1); int v = es.toInt(); switch (v) { case 0: - for (int i = PRIVATE->cur_x; i < size_x; ++i) cells[PRIVATE->cur_y][i] = def_cell; - for (int i = PRIVATE->cur_y + 1; i < size_y; ++i) cells[i].fill(def_cell); + for (int i = PRIVATE->cur_x; i < size_x; ++i) + cells[PRIVATE->cur_y][i] = def_cell; + for (int i = PRIVATE->cur_y + 1; i < size_y; ++i) + cells[i].fill(def_cell); break; case 1: - for (int i = 0; i <= PRIVATE->cur_x; ++i) cells[PRIVATE->cur_y][i] = def_cell; - for (int i = 0; i < PRIVATE->cur_y; ++i) cells[i].fill(def_cell); + for (int i = 0; i <= PRIVATE->cur_x; ++i) + cells[PRIVATE->cur_y][i] = def_cell; + for (int i = 0; i < PRIVATE->cur_y; ++i) + cells[i].fill(def_cell); break; case 2: - for (int i = 0; i < size_y; ++i) cells[i].fill(def_cell); - //PRIVATE->cur_x = PRIVATE->cur_y = 0; + for (int i = 0; i < size_y; ++i) + cells[i].fill(def_cell); + // PRIVATE->cur_x = PRIVATE->cur_y = 0; break; } } @@ -684,14 +724,14 @@ void PITerminal::applyEscSeq(PIString es) { int v = es.toInt(); switch (v) { case 0: - for (int i = PRIVATE->cur_x; i < size_x; ++i) cells[PRIVATE->cur_y][i] = def_cell; + for (int i = PRIVATE->cur_x; i < size_x; ++i) + cells[PRIVATE->cur_y][i] = def_cell; break; case 1: - for (int i = 0; i <= PRIVATE->cur_x; ++i) cells[PRIVATE->cur_y][i] = def_cell; - break; - case 2: - cells[PRIVATE->cur_y].fill(def_cell); + for (int i = 0; i <= PRIVATE->cur_x; ++i) + cells[PRIVATE->cur_y][i] = def_cell; break; + case 2: cells[PRIVATE->cur_y].fill(def_cell); break; } } } @@ -705,12 +745,12 @@ void PITerminal::moveCursor(int dx, int dy) { if (PRIVATE->cur_y < 0) PRIVATE->cur_y = 0; if (PRIVATE->cur_x >= size_x) { PRIVATE->line_format = PRIVATE->cur_format; - PRIVATE->cur_x = 0; + PRIVATE->cur_x = 0; PRIVATE->cur_y++; } if (PRIVATE->cur_y >= size_y) { - int scroll = piMini(PRIVATE->cur_y - size_y + 1, size_y - 1); - //piCout << "scroll" << size_x << size_y << size_y - scroll - 1; + int scroll = piMini(PRIVATE->cur_y - size_y + 1, size_y - 1); + // piCout << "scroll" << size_x << size_y << size_y - scroll - 1; PRIVATE->cur_y = size_y - 1; for (int y = 0; y < size_y - scroll; ++y) cells[y] = cells[y + scroll]; @@ -721,58 +761,76 @@ void PITerminal::moveCursor(int dx, int dy) { int PITerminal::termType(const PIString & t) { - if (t == "xterm") return PIKbdListener::vt_xterm; - else if (t == "linux") return PIKbdListener::vt_linux; + if (t == "xterm") + return PIKbdListener::vt_xterm; + else if (t == "linux") + return PIKbdListener::vt_linux; return PIKbdListener::vt_none; } -#endif +# endif bool PITerminal::initialize() { destroy(); -#ifdef WINDOWS +# ifdef WINDOWS /*SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = true; sa.lpSecurityDescriptor = 0; if (!CreatePipe(&(PRIVATE->pipe_in[0]), &(PRIVATE->pipe_in[1]), &sa, 0)) { - piCoutObj << "CreatePipe error," << errorString(); - initPrivate(); - return false; + piCoutObj << "CreatePipe error," << errorString(); + initPrivate(); + return false; } PRIVATE->hConBuf = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, &sa, CONSOLE_TEXTMODE_BUFFER, 0); if (PRIVATE->hConBuf == INVALID_HANDLE_VALUE) { - piCoutObj << "CreateConsoleScreenBuffer error," << errorString(); - destroy(); - return false; + piCoutObj << "CreateConsoleScreenBuffer error," << errorString(); + destroy(); + return false; }*/ - //CreatePipe(&(PRIVATE->pipe_out[0]), &(PRIVATE->pipe_out[1]), &sa, 0); - //SetHandleInformation(PRIVATE->pipe_in[1], HANDLE_FLAG_INHERIT, 0); - //SetHandleInformation(PRIVATE->hConBuf, HANDLE_FLAG_INHERIT, 0); - //GetStartupInfoA(&PRIVATE->si); + // CreatePipe(&(PRIVATE->pipe_out[0]), &(PRIVATE->pipe_out[1]), &sa, 0); + // SetHandleInformation(PRIVATE->pipe_in[1], HANDLE_FLAG_INHERIT, 0); + // SetHandleInformation(PRIVATE->hConBuf, HANDLE_FLAG_INHERIT, 0); + // GetStartupInfoA(&PRIVATE->si); memset(&PRIVATE->si, 0, sizeof(PRIVATE->si)); PRIVATE->si.cb = sizeof(STARTUPINFO); - //PRIVATE->si.dwFlags |= STARTF_USESTDHANDLES; + // PRIVATE->si.dwFlags |= STARTF_USESTDHANDLES; PRIVATE->si.dwFlags |= STARTF_USESHOWWINDOW; PRIVATE->si.dwFlags |= STARTF_USECOUNTCHARS; - //PRIVATE->si.hStdInput = PRIVATE->pipe; - //PRIVATE->si.hStdOutput = PRIVATE->hConBuf; - //PRIVATE->si.hStdError = PRIVATE->hConBuf; - PRIVATE->si.wShowWindow = SW_HIDE; + // PRIVATE->si.hStdInput = PRIVATE->pipe; + // PRIVATE->si.hStdOutput = PRIVATE->hConBuf; + // PRIVATE->si.hStdError = PRIVATE->hConBuf; + PRIVATE->si.wShowWindow = SW_HIDE; PRIVATE->si.dwXCountChars = 80; PRIVATE->si.dwYCountChars = 24; memset(&PRIVATE->pi, 0, sizeof(PRIVATE->pi)); - PIString shmh = PIString::fromNumber(randomi() % 10000); + PIString shmh = PIString::fromNumber(randomi() % 10000); PIString pname = "\\\\.\\pipe\\piterm" + shmh; - PIString cmd = "piterminal \"" + shmh + "\" \"" + pname + "\""; - if(!CreateProcessA(0, (LPSTR)cmd.dataAscii(), 0, 0, false, CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, 0, 0, &PRIVATE->si, &PRIVATE->pi)) { + PIString cmd = "piterminal \"" + shmh + "\" \"" + pname + "\""; + if (!CreateProcessA(0, + (LPSTR)cmd.dataAscii(), + 0, + 0, + false, + CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, + 0, + 0, + &PRIVATE->si, + &PRIVATE->pi)) { piCoutObj << "CreateProcess error," << errorString(); destroy(); return false; } - PRIVATE->pipe = CreateNamedPipeA((LPSTR)pname.dataAscii(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 2, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 1000, NULL); + PRIVATE->pipe = CreateNamedPipeA((LPSTR)pname.dataAscii(), + PIPE_ACCESS_DUPLEX, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + 2, + PIPE_BUFFER_SIZE, + PIPE_BUFFER_SIZE, + 1000, + NULL); if (PRIVATE->pipe == INVALID_HANDLE_VALUE) { piCoutObj << "CreateNamedPipe error," << errorString(); destroy(); @@ -792,31 +850,32 @@ bool PITerminal::initialize() { return false; } if (PRIVATE->shm) delete PRIVATE->shm; - PRIVATE->shm = new PISharedMemory("piterm_aux" + shmh, 1024*1024); + PRIVATE->shm = new PISharedMemory("piterm_aux" + shmh, 1024 * 1024); CloseHandle(PRIVATE->pi.hThread); resize(dsize_x, dsize_y); -#else -# ifdef HAS_FORKPTY - char pty[256]; memset(pty, 0, 256); +# else +# ifdef HAS_FORKPTY + char pty[256]; + memset(pty, 0, 256); winsize ws; - ws.ws_col = dsize_x; - ws.ws_row = dsize_y; + ws.ws_col = dsize_x; + ws.ws_row = dsize_y; PIStringList env = PIProcess::currentEnvironment(); - piForeachC (PIString & e, env) + piForeachC(PIString & e, env) if (e.startsWith("TERM=")) { PRIVATE->term_type = termType(e.mid(5).trim().toLowerCase()); - //piCout << PRIVATE->term_type; + // piCout << PRIVATE->term_type; break; } pid_t fr = forkpty(&(PRIVATE->fd), pty, 0, &ws); - //piCoutObj << fr << PRIVATE->fd << pty; + // piCoutObj << fr << PRIVATE->fd << pty; if (fr == 0) { - char ** argv = new char*[2]; + char ** argv = new char *[2]; PIByteArray shell = PRIVATE->shell.toByteArray(); - argv[0] = new char[shell.size() + 1]; + argv[0] = new char[shell.size() + 1]; memcpy(argv[0], shell.data(), shell.size()); argv[0][shell.size()] = 0; - argv[1] = 0; + argv[1] = 0; execvp(argv[0], argv); delete[] argv[0]; delete[] argv; @@ -829,31 +888,31 @@ bool PITerminal::initialize() { } PRIVATE->pid = fr; fcntl(PRIVATE->fd, F_SETFL, O_NONBLOCK); - /* - tcgetattr(PRIVATE->fd, &PRIVATE->desc); - PRIVATE->desc.c_oflag = PRIVATE->desc.c_lflag = PRIVATE->desc.c_cflag = 0; - PRIVATE->desc.c_iflag = IGNBRK; - PRIVATE->desc.c_cflag = CLOCAL | HUPCL; - PRIVATE->desc.c_cflag |= (CSIZE & CS8); - PRIVATE->desc.c_cflag |= CREAD; - PRIVATE->desc.c_cc[VMIN] = 1; - PRIVATE->desc.c_cc[VTIME] = 1; + /* + tcgetattr(PRIVATE->fd, &PRIVATE->desc); + PRIVATE->desc.c_oflag = PRIVATE->desc.c_lflag = PRIVATE->desc.c_cflag = 0; + PRIVATE->desc.c_iflag = IGNBRK; + PRIVATE->desc.c_cflag = CLOCAL | HUPCL; + PRIVATE->desc.c_cflag |= (CSIZE & CS8); + PRIVATE->desc.c_cflag |= CREAD; + PRIVATE->desc.c_cc[VMIN] = 1; + PRIVATE->desc.c_cc[VTIME] = 1; - cfsetispeed(&PRIVATE->desc, B38400); - cfsetospeed(&PRIVATE->desc, B38400); + cfsetispeed(&PRIVATE->desc, B38400); + cfsetospeed(&PRIVATE->desc, B38400); - if (tcsetattr(PRIVATE->fd, TCSANOW, &PRIVATE->desc) < 0) { - piCoutObj << "Can`t set attributes for \"" << pty << "\""; - destroy(); - return false; - } - */ + if (tcsetattr(PRIVATE->fd, TCSANOW, &PRIVATE->desc) < 0) { + piCoutObj << "Can`t set attributes for \"" << pty << "\""; + destroy(); + return false; + } + */ size_x = dsize_x; size_y = dsize_y; resize(size_x, size_y); } +# endif # endif -#endif cursor_blink = false; cursor_tm.reset(); start(40); @@ -862,46 +921,44 @@ bool PITerminal::initialize() { void PITerminal::destroy() { - //piCout << "destroy ..."; + // piCout << "destroy ..."; stop(); waitForFinish(1000); -#ifdef WINDOWS +# ifdef WINDOWS if (PRIVATE->pi.hProcess) { - //piCout << "term"; - //TerminateProcess(PRIVATE->pi.hProcess, 0); + // piCout << "term"; + // TerminateProcess(PRIVATE->pi.hProcess, 0); GenerateConsoleCtrlEvent(CTRL_C_EVENT, PRIVATE->pi.dwProcessId); CloseHandle(PRIVATE->pi.hProcess); } if (PRIVATE->pipe != INVALID_HANDLE_VALUE) CloseHandle(PRIVATE->pipe); if (PRIVATE->hConBuf != INVALID_HANDLE_VALUE) CloseHandle(PRIVATE->hConBuf); - //piCout << "destroy" << size_y; -#else -# ifdef HAS_FORKPTY - if (PRIVATE->pid != 0) - kill(PRIVATE->pid, SIGKILL); - if (PRIVATE->fd != 0) - ::close(PRIVATE->fd); + // piCout << "destroy" << size_y; +# else +# ifdef HAS_FORKPTY + if (PRIVATE->pid != 0) kill(PRIVATE->pid, SIGKILL); + if (PRIVATE->fd != 0) ::close(PRIVATE->fd); +# endif # endif -#endif initPrivate(); } bool PITerminal::resize(int cols, int rows) { bool ret = true; - dsize_x = cols; - dsize_y = rows; -#ifdef WINDOWS + dsize_x = cols; + dsize_y = rows; +# ifdef WINDOWS if (PRIVATE->pipe == INVALID_HANDLE_VALUE) return false; PIByteArray msg; msg << int(mtResize) << dsize_x << dsize_y; writePipe(PRIVATE->pipe, msg); -#else -# ifdef HAS_FORKPTY +# else +# ifdef HAS_FORKPTY if (PRIVATE->fd == 0) return false; size_x = dsize_x; size_y = dsize_y; - //piCout << "resize" << PRIVATE->fd << size_x << size_y; + // piCout << "resize" << PRIVATE->fd << size_x << size_y; winsize ws; ws.ws_col = cols; ws.ws_row = rows; @@ -911,8 +968,8 @@ bool PITerminal::resize(int cols, int rows) { PRIVATE->cells_save.resize(size_y); for (int i = 0; i < size_y; ++i) PRIVATE->cells_save[i].resize(size_x); +# endif # endif -#endif cells.resize(size_y); for (int i = 0; i < size_y; ++i) cells[i].resize(size_x); diff --git a/libs/crypt/piauth.cpp b/libs/crypt/piauth.cpp index 223e3ad5..f5643f24 100644 --- a/libs/crypt/piauth.cpp +++ b/libs/crypt/piauth.cpp @@ -1,297 +1,297 @@ -/* - PIP - Platform Independent Primitives - PIP Authentication API - Andrey Bychkov work.a.b@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 . -*/ - -#include "piauth.h" -#define PIAUTH_NOISE_MAX_SIZE 256 - -PIAuth::PIAuth(const PIByteArray & sign) : PIObject() { - setName("Client"); - role = Client; - state = NotConnected; - sign_sk = sign; - sign_pk = crypt.extractSignPublicKey(sign); -} - - -void PIAuth::setServerPassword(const PIString & ps) { - pass_hash = crypt.passwordHash(ps, PIString("PIAuth").toByteArray()); -} - - -void PIAuth::stop() { - role = Client; - state = NotConnected; - auth_sign.clear(); - box_sk.clear(); - box_pk.clear(); - my_pk.clear(); -} - - -void PIAuth::startClient() { - role = Client; - state = AuthProbe; -} - - -PIByteArray PIAuth::startServer() { - setName("Server"); - role = Server; - state = AuthProbe; - PIByteArray ba; - crypt.generateKeypair(my_pk, box_sk); - PIByteArray noise = crypt.generateRandomBuff(randomi()%PIAUTH_NOISE_MAX_SIZE+128); - ba << (int)state << custom_info << sign_pk << my_pk << noise; - PIByteArray sign = crypt.signMessage(ba, sign_sk); - ba << sign; - return ba; -} - - -PIAuth::State PIAuth::receive(PIByteArray & ba) { - if (ba.size() < sizeof(int)) return disconnect(ba, "invalid data size"); - State rstate; - int s; - ba >> s; - rstate = (State)s; -// if (state != rstate) return disconect(ba); - - //client side - if (role == Client) { - if (state == AuthProbe && rstate == AuthProbe) { - if (ba.size() < sizeof(int)*5) return disconnect(ba, "invalid data size"); - PIByteArray rinfo; - PIByteArray rsign; - PIByteArray rsign_pk; - PIByteArray noise; - ba >> rinfo >> rsign_pk >> box_pk >> noise >> rsign; - if (rsign_pk.isEmpty() || box_pk.isEmpty() || rsign.isEmpty()) return disconnect(ba, "invalid key size"); - - PIByteArray tba; - tba << (int)rstate << rinfo << rsign_pk << box_pk << noise; - if (!crypt.verifySign(tba, rsign, rsign_pk)) return disconnect(ba, "Incorrect sign"); - bool auth = false; - if (isAuthorizedKey(rsign_pk)) { - auth = true; - } else { - authorize(rinfo, &auth); - if (auth) auth_pkeys << rsign_pk; - } - if (!auth) return disconnect(ba, "Unauthorised"); - ba.clear(); - auth_sign = rsign_pk; - crypt.generateKeypair(my_pk, box_sk); - tba.clear(); - tba << sign_pk << my_pk << box_pk; - PIByteArray sign = crypt.signMessage(tba, sign_sk); - tba << sign; - tba = crypt.crypt(tba, box_pk, box_sk); - state = AuthReply; - noise = crypt.generateRandomBuff(randomi()%PIAUTH_NOISE_MAX_SIZE); - ba << (int)state << tba << my_pk << noise; - sign = crypt.signMessage(ba, sign_sk); - ba << sign; - return state; - } - if (state == AuthReply && rstate == PassRequest) { - PIByteArray ctba, tba; - PIByteArray noise; - PIByteArray rsign, rsign_pk; - ba >> ctba >> rsign; - bool ok = false; - tba = crypt.decrypt(ctba, box_pk, box_sk, &ok); - if (tba.isEmpty() || !ok) return disconnect(ba, "Message corrupted"); - ba.clear(); - ba << (int)rstate << ctba; - if (!crypt.verifySign(ba, rsign, auth_sign)) return disconnect(ba, "Incorrect sign"); - ctba.clear(); - tba >> rsign_pk >> noise >> ctba; - if (rsign_pk != auth_sign || ctba != my_pk) return disconnect(ba, "Invalid public key"); - PIString ps; - PIByteArray ph; - passwordRequest(&ps); - if (ps.isEmpty()) return disconnect(ba, "Canceled by user"); - ph = crypt.passwordHash(ps, PIString("PIAuth").toByteArray()); - ps.fill(PIChar()); - tba.clear(); - tba << ph << auth_sign << sign_pk; - tba = crypt.crypt(tba, box_pk, box_sk); - ba.clear(); - state = PassRequest; - ba << (int)state << tba; - rsign = crypt.signMessage(ba, sign_sk); - ba << rsign; - return state; - } - if ((state == AuthReply && rstate == KeyExchange) || (state == PassRequest && rstate == KeyExchange)) { - PIByteArray tba, ctba; - PIByteArray rsign; - ba >> ctba >> rsign; - bool ok = false; - tba = crypt.decrypt(ctba, box_pk, box_sk, &ok); - if (tba.isEmpty() || !ok) return disconnect(ba, "Message corrupted"); - ba.clear(); - ba << (int)rstate << ctba; - if (!crypt.verifySign(ba, rsign, auth_sign)) return disconnect(ba, "Incorrect sign"); - tba >> secret_key; - if (secret_key.size() != crypt.sizeKey()) return disconnect(ba, "Invalid key"); - ba.clear(); - state = Connected; - connected(PIString()); - ba << (int)state << crypt.crypt(custom_info, secret_key) << crypt.generateRandomBuff(randomi()%PIAUTH_NOISE_MAX_SIZE); - return state; - } - if (state == Connected && rstate == Connected) { - ba.clear(); - state = Connected; - connected(PIString()); - ba << (int)state << crypt.crypt(custom_info, secret_key) << crypt.generateRandomBuff(randomi()%PIAUTH_NOISE_MAX_SIZE); - return state; - } - } - - // server side - if (role == Server) { - if (state == AuthProbe && rstate == AuthReply) { - if (ba.size() < sizeof(int)*4) return disconnect(ba, "invalid data size"); - PIByteArray ctba, tba; - PIByteArray noise; - PIByteArray rsign1, rsign2; - PIByteArray rsign_pk; - PIByteArray pk, mpk; - ba >> ctba >> pk >> noise >> rsign1; - bool ok = false; - tba = crypt.decrypt(ctba, pk, box_sk, &ok); - if (tba.isEmpty() || !ok) return disconnect(ba, "Message corrupted"); - if (tba.size() < sizeof(int)*3) return disconnect(tba, "invalid data size"); - tba >> rsign_pk >> box_pk >> mpk >> rsign2; - if (pk != box_pk || mpk != my_pk) return disconnect(ba, "Invalid public key"); - ba.clear(); - ba << (int)rstate << ctba << box_pk << noise; - if (!crypt.verifySign(ba, rsign1, rsign_pk)) return disconnect(ba, "Incorrect sign"); - ba.clear(); - ba << rsign_pk << box_pk << my_pk; - if (!crypt.verifySign(ba, rsign2, rsign_pk)) return disconnect(ba, "Incorrect sign"); - auth_sign = rsign_pk; - if (isAuthorizedKey(rsign_pk)) { - state = KeyExchange; - ba = createSKMessage(); - return state; - } else { - ba.clear(); - tba.clear(); - state = PassRequest; - noise = crypt.generateRandomBuff(randomi()%PIAUTH_NOISE_MAX_SIZE); - tba << sign_pk << noise << box_pk; - tba = crypt.crypt(tba, box_pk, box_sk); - ba << (int)state << tba; - rsign1 = crypt.signMessage(ba, sign_sk); - ba << rsign1; - return state; - } - } - if (state == PassRequest && rstate == PassRequest) { - PIByteArray tba, ctba; - PIByteArray rsign_pk, rsign, mpk; - ba >> ctba >> rsign; - bool ok = false; - tba = crypt.decrypt(ctba, box_pk, box_sk, &ok); - if (tba.isEmpty() || !ok) return disconnect(ba, "Message corrupted"); - ba.clear(); - ba << (int)rstate << ctba; - if (!crypt.verifySign(ba, rsign, auth_sign)) return disconnect(ba, "Incorrect sign"); - ctba.clear(); - tba >> ctba >> mpk >> rsign_pk; - if (rsign_pk != auth_sign || mpk != sign_pk) return disconnect(ba, "Invalid public key"); - bool auth = (ctba == pass_hash); - if (ctba.isEmpty() || pass_hash.isEmpty()) auth = false; - passwordCheck(auth); - if (!auth) { -// piSleep(1); - return disconnect(ba, "Invalid password"); - } - state = KeyExchange; - ba = createSKMessage(); - return state; - } - if ((state == KeyExchange && rstate == Connected) || (state == Connected && rstate == Connected)) { - ba.clear(); - PIByteArray rinfo; - ba >> rinfo; - bool ok = false; - rinfo = crypt.decrypt(rinfo, secret_key, &ok); - if (!ok) return disconnect(ba, "Error while exchange keys"); - state = Connected; - connected(rinfo); - ba << (int)state << crypt.generateRandomBuff(randomi()%PIAUTH_NOISE_MAX_SIZE); - return state; - } - } - - return disconnect(ba, "invalid state " + PIString::fromNumber((int)state)); -} - - -PIByteArray PIAuth::getSecretKey() { - if (state == Connected) return secret_key; - return PIByteArray(); -} - - -PIByteArray PIAuth::generateSign(const PIByteArray & seed) { - PIByteArray pk, sk; - PICrypt::generateSignKeys(pk, sk, seed); - return sk; -} - - -PIAuth::State PIAuth::disconnect(PIByteArray & ba, const PIString & error) { - if (!error.isEmpty()) piCoutObj << error; - auth_sign.clear(); - box_sk.clear(); - box_pk.clear(); - my_pk.clear(); - secret_key.clear(); - ba.clear(); - state = NotConnected; - disconnected(error); - return state; -} - - -bool PIAuth::isAuthorizedKey(const PIByteArray & pkey) { - for (int i=0; i. +*/ + +#include "piauth.h" +#define PIAUTH_NOISE_MAX_SIZE 256 + +PIAuth::PIAuth(const PIByteArray & sign): PIObject() { + setName("Client"); + role = Client; + state = NotConnected; + sign_sk = sign; + sign_pk = crypt.extractSignPublicKey(sign); +} + + +void PIAuth::setServerPassword(const PIString & ps) { + pass_hash = crypt.passwordHash(ps, PIString("PIAuth").toByteArray()); +} + + +void PIAuth::stop() { + role = Client; + state = NotConnected; + auth_sign.clear(); + box_sk.clear(); + box_pk.clear(); + my_pk.clear(); +} + + +void PIAuth::startClient() { + role = Client; + state = AuthProbe; +} + + +PIByteArray PIAuth::startServer() { + setName("Server"); + role = Server; + state = AuthProbe; + PIByteArray ba; + crypt.generateKeypair(my_pk, box_sk); + PIByteArray noise = crypt.generateRandomBuff(randomi() % PIAUTH_NOISE_MAX_SIZE + 128); + ba << (int)state << custom_info << sign_pk << my_pk << noise; + PIByteArray sign = crypt.signMessage(ba, sign_sk); + ba << sign; + return ba; +} + + +PIAuth::State PIAuth::receive(PIByteArray & ba) { + if (ba.size() < sizeof(int)) return disconnect(ba, "invalid data size"); + State rstate; + int s; + ba >> s; + rstate = (State)s; + // if (state != rstate) return disconect(ba); + + // client side + if (role == Client) { + if (state == AuthProbe && rstate == AuthProbe) { + if (ba.size() < sizeof(int) * 5) return disconnect(ba, "invalid data size"); + PIByteArray rinfo; + PIByteArray rsign; + PIByteArray rsign_pk; + PIByteArray noise; + ba >> rinfo >> rsign_pk >> box_pk >> noise >> rsign; + if (rsign_pk.isEmpty() || box_pk.isEmpty() || rsign.isEmpty()) return disconnect(ba, "invalid key size"); + + PIByteArray tba; + tba << (int)rstate << rinfo << rsign_pk << box_pk << noise; + if (!crypt.verifySign(tba, rsign, rsign_pk)) return disconnect(ba, "Incorrect sign"); + bool auth = false; + if (isAuthorizedKey(rsign_pk)) { + auth = true; + } else { + authorize(rinfo, &auth); + if (auth) auth_pkeys << rsign_pk; + } + if (!auth) return disconnect(ba, "Unauthorised"); + ba.clear(); + auth_sign = rsign_pk; + crypt.generateKeypair(my_pk, box_sk); + tba.clear(); + tba << sign_pk << my_pk << box_pk; + PIByteArray sign = crypt.signMessage(tba, sign_sk); + tba << sign; + tba = crypt.crypt(tba, box_pk, box_sk); + state = AuthReply; + noise = crypt.generateRandomBuff(randomi() % PIAUTH_NOISE_MAX_SIZE); + ba << (int)state << tba << my_pk << noise; + sign = crypt.signMessage(ba, sign_sk); + ba << sign; + return state; + } + if (state == AuthReply && rstate == PassRequest) { + PIByteArray ctba, tba; + PIByteArray noise; + PIByteArray rsign, rsign_pk; + ba >> ctba >> rsign; + bool ok = false; + tba = crypt.decrypt(ctba, box_pk, box_sk, &ok); + if (tba.isEmpty() || !ok) return disconnect(ba, "Message corrupted"); + ba.clear(); + ba << (int)rstate << ctba; + if (!crypt.verifySign(ba, rsign, auth_sign)) return disconnect(ba, "Incorrect sign"); + ctba.clear(); + tba >> rsign_pk >> noise >> ctba; + if (rsign_pk != auth_sign || ctba != my_pk) return disconnect(ba, "Invalid public key"); + PIString ps; + PIByteArray ph; + passwordRequest(&ps); + if (ps.isEmpty()) return disconnect(ba, "Canceled by user"); + ph = crypt.passwordHash(ps, PIString("PIAuth").toByteArray()); + ps.fill(PIChar()); + tba.clear(); + tba << ph << auth_sign << sign_pk; + tba = crypt.crypt(tba, box_pk, box_sk); + ba.clear(); + state = PassRequest; + ba << (int)state << tba; + rsign = crypt.signMessage(ba, sign_sk); + ba << rsign; + return state; + } + if ((state == AuthReply && rstate == KeyExchange) || (state == PassRequest && rstate == KeyExchange)) { + PIByteArray tba, ctba; + PIByteArray rsign; + ba >> ctba >> rsign; + bool ok = false; + tba = crypt.decrypt(ctba, box_pk, box_sk, &ok); + if (tba.isEmpty() || !ok) return disconnect(ba, "Message corrupted"); + ba.clear(); + ba << (int)rstate << ctba; + if (!crypt.verifySign(ba, rsign, auth_sign)) return disconnect(ba, "Incorrect sign"); + tba >> secret_key; + if (secret_key.size() != crypt.sizeKey()) return disconnect(ba, "Invalid key"); + ba.clear(); + state = Connected; + connected(PIString()); + ba << (int)state << crypt.crypt(custom_info, secret_key) << crypt.generateRandomBuff(randomi() % PIAUTH_NOISE_MAX_SIZE); + return state; + } + if (state == Connected && rstate == Connected) { + ba.clear(); + state = Connected; + connected(PIString()); + ba << (int)state << crypt.crypt(custom_info, secret_key) << crypt.generateRandomBuff(randomi() % PIAUTH_NOISE_MAX_SIZE); + return state; + } + } + + // server side + if (role == Server) { + if (state == AuthProbe && rstate == AuthReply) { + if (ba.size() < sizeof(int) * 4) return disconnect(ba, "invalid data size"); + PIByteArray ctba, tba; + PIByteArray noise; + PIByteArray rsign1, rsign2; + PIByteArray rsign_pk; + PIByteArray pk, mpk; + ba >> ctba >> pk >> noise >> rsign1; + bool ok = false; + tba = crypt.decrypt(ctba, pk, box_sk, &ok); + if (tba.isEmpty() || !ok) return disconnect(ba, "Message corrupted"); + if (tba.size() < sizeof(int) * 3) return disconnect(tba, "invalid data size"); + tba >> rsign_pk >> box_pk >> mpk >> rsign2; + if (pk != box_pk || mpk != my_pk) return disconnect(ba, "Invalid public key"); + ba.clear(); + ba << (int)rstate << ctba << box_pk << noise; + if (!crypt.verifySign(ba, rsign1, rsign_pk)) return disconnect(ba, "Incorrect sign"); + ba.clear(); + ba << rsign_pk << box_pk << my_pk; + if (!crypt.verifySign(ba, rsign2, rsign_pk)) return disconnect(ba, "Incorrect sign"); + auth_sign = rsign_pk; + if (isAuthorizedKey(rsign_pk)) { + state = KeyExchange; + ba = createSKMessage(); + return state; + } else { + ba.clear(); + tba.clear(); + state = PassRequest; + noise = crypt.generateRandomBuff(randomi() % PIAUTH_NOISE_MAX_SIZE); + tba << sign_pk << noise << box_pk; + tba = crypt.crypt(tba, box_pk, box_sk); + ba << (int)state << tba; + rsign1 = crypt.signMessage(ba, sign_sk); + ba << rsign1; + return state; + } + } + if (state == PassRequest && rstate == PassRequest) { + PIByteArray tba, ctba; + PIByteArray rsign_pk, rsign, mpk; + ba >> ctba >> rsign; + bool ok = false; + tba = crypt.decrypt(ctba, box_pk, box_sk, &ok); + if (tba.isEmpty() || !ok) return disconnect(ba, "Message corrupted"); + ba.clear(); + ba << (int)rstate << ctba; + if (!crypt.verifySign(ba, rsign, auth_sign)) return disconnect(ba, "Incorrect sign"); + ctba.clear(); + tba >> ctba >> mpk >> rsign_pk; + if (rsign_pk != auth_sign || mpk != sign_pk) return disconnect(ba, "Invalid public key"); + bool auth = (ctba == pass_hash); + if (ctba.isEmpty() || pass_hash.isEmpty()) auth = false; + passwordCheck(auth); + if (!auth) { + // piSleep(1); + return disconnect(ba, "Invalid password"); + } + state = KeyExchange; + ba = createSKMessage(); + return state; + } + if ((state == KeyExchange && rstate == Connected) || (state == Connected && rstate == Connected)) { + ba.clear(); + PIByteArray rinfo; + ba >> rinfo; + bool ok = false; + rinfo = crypt.decrypt(rinfo, secret_key, &ok); + if (!ok) return disconnect(ba, "Error while exchange keys"); + state = Connected; + connected(rinfo); + ba << (int)state << crypt.generateRandomBuff(randomi() % PIAUTH_NOISE_MAX_SIZE); + return state; + } + } + + return disconnect(ba, "invalid state " + PIString::fromNumber((int)state)); +} + + +PIByteArray PIAuth::getSecretKey() { + if (state == Connected) return secret_key; + return PIByteArray(); +} + + +PIByteArray PIAuth::generateSign(const PIByteArray & seed) { + PIByteArray pk, sk; + PICrypt::generateSignKeys(pk, sk, seed); + return sk; +} + + +PIAuth::State PIAuth::disconnect(PIByteArray & ba, const PIString & error) { + if (!error.isEmpty()) piCoutObj << error; + auth_sign.clear(); + box_sk.clear(); + box_pk.clear(); + my_pk.clear(); + secret_key.clear(); + ba.clear(); + state = NotConnected; + disconnected(error); + return state; +} + + +bool PIAuth::isAuthorizedKey(const PIByteArray & pkey) { + for (int i = 0; i < auth_pkeys.size_s(); ++i) { + if (pkey == auth_pkeys[i]) return true; + } + return false; +} + + +PIByteArray PIAuth::createSKMessage() { + secret_key = crypt.generateKey(); + PIByteArray tba; + PIByteArray noise = crypt.generateRandomBuff(randomi() % PIAUTH_NOISE_MAX_SIZE); + tba << secret_key << noise; + tba = crypt.crypt(tba, box_pk, box_sk); + PIByteArray ret; + ret << (int)state << tba; + PIByteArray sign = crypt.signMessage(ret, sign_sk); + ret << sign; + return ret; +} diff --git a/libs/crypt/picrypt.cpp b/libs/crypt/picrypt.cpp index 9b35c202..38e55853 100644 --- a/libs/crypt/picrypt.cpp +++ b/libs/crypt/picrypt.cpp @@ -1,448 +1,457 @@ -/* - PIP - Platform Independent Primitives - Cryptographic class using lib Sodium - Andrey Bychkov work.a.b@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 . -*/ - -#include "picrypt.h" -#ifdef PIP_CRYPT -# include -#endif - -#define PICRYPT_DISABLED_WARNING piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and rebuild pip"; - -const char hash_def_key[] = "_picrypt_\0\0\0\0\0\0\0"; -const int hash_def_key_size = 9; - - -PICrypt::PICrypt() { -#ifdef PIP_CRYPT - if (!init()) piCout << "[PICrypt]" << "Error while initialize sodium!"; - nonce_.resize(crypto_secretbox_NONCEBYTES); - key_.resize(crypto_secretbox_KEYBYTES); - randombytes_buf(key_.data(), key_.size()); - randombytes_buf(nonce_.data(), nonce_.size()); -#else - PICRYPT_DISABLED_WARNING -#endif -} - - -bool PICrypt::setKey(const PIByteArray & _key) { - if (_key.size() != key_.size()) return false; - key_ = _key; - return true; -} - - -PIByteArray PICrypt::setKey(const PIString & secret) { - PIByteArray hash; -#ifdef PIP_CRYPT - hash.resize(crypto_generichash_BYTES); - PIByteArray s(secret.data(), secret.size()); - crypto_generichash(hash.data(), hash.size(), s.data(), s.size(), (const uchar*)hash_def_key, hash_def_key_size); - hash.resize(key_.size()); - setKey(hash); -#endif - return hash; -} - - -PIByteArray PICrypt::crypt(const PIByteArray & data) { - PIByteArray ret; -#ifdef PIP_CRYPT - ret.resize(data.size() + crypto_secretbox_MACBYTES); - randombytes_buf(nonce_.data(), nonce_.size()); - crypto_secretbox_easy(ret.data(), data.data(), data.size(), nonce_.data(), key_.data()); - ret.append(nonce_); -#endif - return ret; -} - - -PIByteArray PICrypt::crypt(const PIByteArray & data, PIByteArray key) { - PIByteArray ret; -#ifdef PIP_CRYPT - if (key.size() != crypto_secretbox_KEYBYTES) - key.resize(crypto_secretbox_KEYBYTES, ' '); - //return PIByteArray(); - if (!init()) return ret; - PIByteArray n; - ret.resize(data.size() + crypto_secretbox_MACBYTES); - n.resize(crypto_secretbox_NONCEBYTES); - randombytes_buf(n.data(), n.size()); - crypto_secretbox_easy(ret.data(), data.data(), data.size(), n.data(), key.data()); - ret.append(n); -#else - PICRYPT_DISABLED_WARNING -#endif - return ret; -} - - -PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, bool *ok) { - PIByteArray ret; -#ifdef PIP_CRYPT - if (crypt_data.size() < nonce_.size() + crypto_secretbox_MACBYTES) { - if (ok) *ok = false; - return PIByteArray(); - } - ret.resize(crypt_data.size() - nonce_.size() - crypto_secretbox_MACBYTES); - memcpy(nonce_.data(), crypt_data.data(crypt_data.size() - nonce_.size()), nonce_.size()); - if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - nonce_.size(), nonce_.data(), key_.data()) != 0) { - if (ok) *ok = false; - // piCout << "[PICrypt]" << "bad key_"; - return PIByteArray(); - } -#endif - if (ok) *ok = true; - return ret; -} - - -PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bool *ok) { - PIByteArray ret; -#ifdef PIP_CRYPT - if (key.size() != crypto_secretbox_KEYBYTES) - key.resize(crypto_secretbox_KEYBYTES, ' '); - /*if (ok) *ok = false; - return PIByteArray(); - }*/ - if (crypt_data.size() < crypto_secretbox_NONCEBYTES + crypto_secretbox_MACBYTES) { - if (ok) *ok = false; - return PIByteArray(); - } - if (!init()) return ret; - PIByteArray n; - n.resize(crypto_secretbox_NONCEBYTES); - ret.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES); - memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size()); - if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), key.data()) != 0) { - if (ok) *ok = false; - // piCout << "[PICrypt]" << "bad key_"; - return PIByteArray(); - } else if (ok) *ok = true; -#else - PICRYPT_DISABLED_WARNING -#endif - return ret; -} - - -PIByteArray PICrypt::hash(const PIString & secret) { - PIByteArray hash; -#ifdef PIP_CRYPT - if (!init()) return hash; - hash.resize(crypto_generichash_BYTES); - PIByteArray s(secret.data(), secret.size()); - crypto_generichash(hash.data(), hash.size(), s.data(), s.size(),(const uchar*)hash_def_key, hash_def_key_size); -#else - PICRYPT_DISABLED_WARNING -#endif - return hash; -} - - -PIByteArray PICrypt::hash(const PIByteArray & data) { - PIByteArray hash; -#ifdef PIP_CRYPT - if (!init()) return hash; - hash.resize(crypto_generichash_BYTES); - crypto_generichash(hash.data(), hash.size(), data.data(), data.size(), (const uchar*)hash_def_key, hash_def_key_size); -#else - PICRYPT_DISABLED_WARNING -#endif - return hash; -} - - -PIByteArray PICrypt::hash(const PIByteArray & data, const unsigned char *key, size_t keylen) { - PIByteArray hash; -#ifdef PIP_CRYPT - if (!init()) return hash; - hash.resize(crypto_generichash_BYTES); - crypto_generichash(hash.data(), hash.size(), data.data(), data.size(), key, keylen); -#else - PICRYPT_DISABLED_WARNING -#endif - return hash; -} - - -size_t PICrypt::sizeHash() { -#ifdef PIP_CRYPT - return crypto_generichash_BYTES; -#else - PICRYPT_DISABLED_WARNING -#endif - return 0; -} - - -ullong PICrypt::shorthash(const PIString& s, PIByteArray key) { - ullong hash = 0; -#ifdef PIP_CRYPT - if (crypto_shorthash_BYTES != sizeof(hash)) piCout << "[PICrypt]" << "internal error: bad hash size"; - if (!init()) return hash; - if (key.size() != crypto_shorthash_KEYBYTES) { - piCout << "[PICrypt]" << "invalid key size" << key.size() << ", shoud be" << crypto_shorthash_KEYBYTES << ", filled zeros"; - key.resize(crypto_shorthash_KEYBYTES, 0); - } - PIByteArray in(s.data(), s.size()); - crypto_shorthash((uchar *)&hash, in.data(), in.size(), key.data()); -#else - PICRYPT_DISABLED_WARNING -#endif - return hash; -} - - -PIByteArray PICrypt::generateKey() { - PIByteArray hash; -#ifdef PIP_CRYPT - if (!init()) return hash; - hash.resize(crypto_secretbox_KEYBYTES); - randombytes_buf(hash.data(), hash.size()); -#else - PICRYPT_DISABLED_WARNING -#endif - return hash; -} - - -PIByteArray PICrypt::generateRandomBuff(int size) { - PIByteArray hash; -#ifdef PIP_CRYPT - if (!init() || size <= 0) return hash; - hash.resize(size); - randombytes_buf(hash.data(), hash.size()); -#else - PICRYPT_DISABLED_WARNING -#endif - return hash; -} - - -size_t PICrypt::sizeKey() { -#ifdef PIP_CRYPT - return crypto_secretbox_KEYBYTES; -#else - PICRYPT_DISABLED_WARNING -#endif - return 0; -} - - -size_t PICrypt::sizeCrypt() { -#ifdef PIP_CRYPT - return crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES; -#else - PICRYPT_DISABLED_WARNING -#endif - return 0; -} - - -void PICrypt::generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key) { -#ifdef PIP_CRYPT - if (!init()) return; - public_key.resize(crypto_sign_PUBLICKEYBYTES); - secret_key.resize(crypto_sign_SECRETKEYBYTES); - crypto_sign_keypair(public_key.data(), secret_key.data()); -#else - PICRYPT_DISABLED_WARNING -#endif -} - - -void PICrypt::generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed) { -#ifdef PIP_CRYPT - if (!init() || seed.isEmpty()) return; - public_key.resize(crypto_sign_PUBLICKEYBYTES); - secret_key.resize(crypto_sign_SECRETKEYBYTES); - crypto_sign_seed_keypair(public_key.data(), secret_key.data(), hash(seed).data()); -#else - PICRYPT_DISABLED_WARNING -#endif -} - - -PIByteArray PICrypt::extractSignPublicKey(const PIByteArray & secret_key) { - PIByteArray pk; -#ifdef PIP_CRYPT - if (!init() || secret_key.size() != crypto_sign_SECRETKEYBYTES) return pk; - pk.resize(crypto_sign_PUBLICKEYBYTES); - crypto_sign_ed25519_sk_to_pk(pk.data(), secret_key.data()); -#else - PICRYPT_DISABLED_WARNING -#endif - return pk; -} - - -PIByteArray PICrypt::signMessage(const PIByteArray & data, PIByteArray secret_key) { - PIByteArray sign; -#ifdef PIP_CRYPT - if (!init()) return sign; - sign.resize(crypto_sign_BYTES); - crypto_sign_detached(sign.data(), 0, data.data(), data.size(), secret_key.data()); -#else - PICRYPT_DISABLED_WARNING -#endif - return sign; -} - - -bool PICrypt::verifySign(const PIByteArray & data, const PIByteArray & signature, PIByteArray public_key) { -#ifdef PIP_CRYPT - if (!init()) return false; - return (crypto_sign_verify_detached(signature.data(), data.data(), data.size(), public_key.data()) == 0); -#else - PICRYPT_DISABLED_WARNING -#endif - return false; -} - - -void PICrypt::generateKeypair(PIByteArray & public_key, PIByteArray & secret_key) { -#ifdef PIP_CRYPT - if (!init()) return; - public_key.resize(crypto_box_PUBLICKEYBYTES); - secret_key.resize(crypto_box_SECRETKEYBYTES); - crypto_box_keypair(public_key.data(), secret_key.data()); -#else - PICRYPT_DISABLED_WARNING -#endif -} - - -void PICrypt::generateKeypair(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed) { -#ifdef PIP_CRYPT - if (!init()) return; - public_key.resize(crypto_box_PUBLICKEYBYTES); - secret_key.resize(crypto_box_SECRETKEYBYTES); - crypto_box_seed_keypair(public_key.data(), secret_key.data(), hash(seed).data()); -#else - PICRYPT_DISABLED_WARNING -#endif -} - - -PIByteArray PICrypt::crypt(const PIByteArray & data, const PIByteArray & public_key, const PIByteArray & secret_key) { - PIByteArray ret; -#ifdef PIP_CRYPT - if (!init()) return ret; - if (public_key.size() != crypto_box_PUBLICKEYBYTES) - return ret; - if (secret_key.size() != crypto_box_SECRETKEYBYTES) - return ret; - PIByteArray n; - ret.resize(data.size() + crypto_box_MACBYTES); - n.resize(crypto_box_NONCEBYTES); - randombytes_buf(n.data(), n.size()); - if (crypto_box_easy(ret.data(), data.data(), data.size(), n.data(), public_key.data(), secret_key.data()) != 0) - return PIByteArray(); - ret.append(n); -#else - PICRYPT_DISABLED_WARNING -#endif - return ret; -} - - -PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, const PIByteArray & public_key, const PIByteArray & secret_key, bool * ok) { - PIByteArray ret; -#ifdef PIP_CRYPT - if (!init()) return ret; - if (public_key.size() != crypto_box_PUBLICKEYBYTES) { - if (ok) *ok = false; - return ret; - } - if (secret_key.size() != crypto_box_SECRETKEYBYTES) { - if (ok) *ok = false; - return ret; - } - if (crypt_data.size() < crypto_box_NONCEBYTES + crypto_box_MACBYTES) { - if (ok) *ok = false; - return ret; - } - PIByteArray n; - n.resize(crypto_secretbox_NONCEBYTES); - ret.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES); - memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size()); - if (crypto_box_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), public_key.data(), secret_key.data()) != 0) { - if (ok) *ok = false; - // piCout << "[PICrypt]" << "bad key_"; - return PIByteArray(); - } else if (ok) *ok = true; -#else - PICRYPT_DISABLED_WARNING -#endif - return ret; -} - - -PIByteArray PICrypt::passwordHash(const PIString & password, const PIByteArray & seed) { -#ifdef crypto_pwhash_ALG_ARGON2I13 -// char out[crypto_pwhash_STRBYTES]; - PIByteArray pass = password.toUTF8(); - PIByteArray n = hash(seed); - PIByteArray ph; - ph.resize(crypto_box_SEEDBYTES); - n.resize(crypto_pwhash_SALTBYTES); -// randombytes_buf(n.data(), n.size()); -// crypto_shorthash(n.data(), seed.data(), seed.size(), PIByteArray(crypto_shorthash_KEYBYTES).data()); - int r = crypto_pwhash(ph.data(), ph.size(), (const char*)pass.data(), pass.size(), n.data(), crypto_pwhash_argon2i_opslimit_moderate(), crypto_pwhash_argon2i_memlimit_moderate(), crypto_pwhash_ALG_ARGON2I13); - //crypto_pwhash_str(out, (const char*)pass.data(), pass.size(), crypto_pwhash_argon2i_opslimit_moderate(), crypto_pwhash_argon2i_memlimit_moderate()); - pass.fill(0); - if (r != 0) return PIByteArray(); - return ph; -// PIByteArray ret; -// ret << ph << n << crypto_pwhash_argon2i_opslimit_moderate() << crypto_pwhash_argon2i_memlimit_moderate(); -// return ret; -#else - return PIByteArray(); -#endif -} - - -PIString PICrypt::version() { -#ifdef PIP_CRYPT - return SODIUM_VERSION_STRING; -#else - return PIString(); -#endif -} - - -bool PICrypt::init() { -#ifdef PIP_CRYPT - static bool inited = false; - if (inited) return true; - //piCout << "[PICrypt]" << "init ..."; - inited = sodium_init(); - if (!inited) - inited = sodium_init(); - //piCout << "[PICrypt]" << "init" << inited; - return inited; -#else - PICRYPT_DISABLED_WARNING -#endif - return false; -} - - - +/* + PIP - Platform Independent Primitives + Cryptographic class using lib Sodium + Andrey Bychkov work.a.b@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 . +*/ + +#include "picrypt.h" +#ifdef PIP_CRYPT +# include +#endif + +#define PICRYPT_DISABLED_WARNING \ + piCout << "[PICrypt]" \ + << "Warning: PICrypt is disabled, to enable install sodium library and rebuild pip"; + +const char hash_def_key[] = "_picrypt_\0\0\0\0\0\0\0"; +const int hash_def_key_size = 9; + + +PICrypt::PICrypt() { +#ifdef PIP_CRYPT + if (!init()) + piCout << "[PICrypt]" + << "Error while initialize sodium!"; + nonce_.resize(crypto_secretbox_NONCEBYTES); + key_.resize(crypto_secretbox_KEYBYTES); + randombytes_buf(key_.data(), key_.size()); + randombytes_buf(nonce_.data(), nonce_.size()); +#else + PICRYPT_DISABLED_WARNING +#endif +} + + +bool PICrypt::setKey(const PIByteArray & _key) { + if (_key.size() != key_.size()) return false; + key_ = _key; + return true; +} + + +PIByteArray PICrypt::setKey(const PIString & secret) { + PIByteArray hash; +#ifdef PIP_CRYPT + hash.resize(crypto_generichash_BYTES); + PIByteArray s(secret.data(), secret.size()); + crypto_generichash(hash.data(), hash.size(), s.data(), s.size(), (const uchar *)hash_def_key, hash_def_key_size); + hash.resize(key_.size()); + setKey(hash); +#endif + return hash; +} + + +PIByteArray PICrypt::crypt(const PIByteArray & data) { + PIByteArray ret; +#ifdef PIP_CRYPT + ret.resize(data.size() + crypto_secretbox_MACBYTES); + randombytes_buf(nonce_.data(), nonce_.size()); + crypto_secretbox_easy(ret.data(), data.data(), data.size(), nonce_.data(), key_.data()); + ret.append(nonce_); +#endif + return ret; +} + + +PIByteArray PICrypt::crypt(const PIByteArray & data, PIByteArray key) { + PIByteArray ret; +#ifdef PIP_CRYPT + if (key.size() != crypto_secretbox_KEYBYTES) key.resize(crypto_secretbox_KEYBYTES, ' '); + // return PIByteArray(); + if (!init()) return ret; + PIByteArray n; + ret.resize(data.size() + crypto_secretbox_MACBYTES); + n.resize(crypto_secretbox_NONCEBYTES); + randombytes_buf(n.data(), n.size()); + crypto_secretbox_easy(ret.data(), data.data(), data.size(), n.data(), key.data()); + ret.append(n); +#else + PICRYPT_DISABLED_WARNING +#endif + return ret; +} + + +PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, bool * ok) { + PIByteArray ret; +#ifdef PIP_CRYPT + if (crypt_data.size() < nonce_.size() + crypto_secretbox_MACBYTES) { + if (ok) *ok = false; + return PIByteArray(); + } + ret.resize(crypt_data.size() - nonce_.size() - crypto_secretbox_MACBYTES); + memcpy(nonce_.data(), crypt_data.data(crypt_data.size() - nonce_.size()), nonce_.size()); + if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - nonce_.size(), nonce_.data(), key_.data()) != 0) { + if (ok) *ok = false; + // piCout << "[PICrypt]" << "bad key_"; + return PIByteArray(); + } +#endif + if (ok) *ok = true; + return ret; +} + + +PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bool * ok) { + PIByteArray ret; +#ifdef PIP_CRYPT + if (key.size() != crypto_secretbox_KEYBYTES) key.resize(crypto_secretbox_KEYBYTES, ' '); + /*if (ok) *ok = false; + return PIByteArray(); +}*/ + if (crypt_data.size() < crypto_secretbox_NONCEBYTES + crypto_secretbox_MACBYTES) { + if (ok) *ok = false; + return PIByteArray(); + } + if (!init()) return ret; + PIByteArray n; + n.resize(crypto_secretbox_NONCEBYTES); + ret.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES); + memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size()); + if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), key.data()) != 0) { + if (ok) *ok = false; + // piCout << "[PICrypt]" << "bad key_"; + return PIByteArray(); + } else if (ok) + *ok = true; +#else + PICRYPT_DISABLED_WARNING +#endif + return ret; +} + + +PIByteArray PICrypt::hash(const PIString & secret) { + PIByteArray hash; +#ifdef PIP_CRYPT + if (!init()) return hash; + hash.resize(crypto_generichash_BYTES); + PIByteArray s(secret.data(), secret.size()); + crypto_generichash(hash.data(), hash.size(), s.data(), s.size(), (const uchar *)hash_def_key, hash_def_key_size); +#else + PICRYPT_DISABLED_WARNING +#endif + return hash; +} + + +PIByteArray PICrypt::hash(const PIByteArray & data) { + PIByteArray hash; +#ifdef PIP_CRYPT + if (!init()) return hash; + hash.resize(crypto_generichash_BYTES); + crypto_generichash(hash.data(), hash.size(), data.data(), data.size(), (const uchar *)hash_def_key, hash_def_key_size); +#else + PICRYPT_DISABLED_WARNING +#endif + return hash; +} + + +PIByteArray PICrypt::hash(const PIByteArray & data, const unsigned char * key, size_t keylen) { + PIByteArray hash; +#ifdef PIP_CRYPT + if (!init()) return hash; + hash.resize(crypto_generichash_BYTES); + crypto_generichash(hash.data(), hash.size(), data.data(), data.size(), key, keylen); +#else + PICRYPT_DISABLED_WARNING +#endif + return hash; +} + + +size_t PICrypt::sizeHash() { +#ifdef PIP_CRYPT + return crypto_generichash_BYTES; +#else + PICRYPT_DISABLED_WARNING +#endif + return 0; +} + + +ullong PICrypt::shorthash(const PIString & s, PIByteArray key) { + ullong hash = 0; +#ifdef PIP_CRYPT + if (crypto_shorthash_BYTES != sizeof(hash)) + piCout << "[PICrypt]" + << "internal error: bad hash size"; + if (!init()) return hash; + if (key.size() != crypto_shorthash_KEYBYTES) { + piCout << "[PICrypt]" + << "invalid key size" << key.size() << ", shoud be" << crypto_shorthash_KEYBYTES << ", filled zeros"; + key.resize(crypto_shorthash_KEYBYTES, 0); + } + PIByteArray in(s.data(), s.size()); + crypto_shorthash((uchar *)&hash, in.data(), in.size(), key.data()); +#else + PICRYPT_DISABLED_WARNING +#endif + return hash; +} + + +PIByteArray PICrypt::generateKey() { + PIByteArray hash; +#ifdef PIP_CRYPT + if (!init()) return hash; + hash.resize(crypto_secretbox_KEYBYTES); + randombytes_buf(hash.data(), hash.size()); +#else + PICRYPT_DISABLED_WARNING +#endif + return hash; +} + + +PIByteArray PICrypt::generateRandomBuff(int size) { + PIByteArray hash; +#ifdef PIP_CRYPT + if (!init() || size <= 0) return hash; + hash.resize(size); + randombytes_buf(hash.data(), hash.size()); +#else + PICRYPT_DISABLED_WARNING +#endif + return hash; +} + + +size_t PICrypt::sizeKey() { +#ifdef PIP_CRYPT + return crypto_secretbox_KEYBYTES; +#else + PICRYPT_DISABLED_WARNING +#endif + return 0; +} + + +size_t PICrypt::sizeCrypt() { +#ifdef PIP_CRYPT + return crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES; +#else + PICRYPT_DISABLED_WARNING +#endif + return 0; +} + + +void PICrypt::generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key) { +#ifdef PIP_CRYPT + if (!init()) return; + public_key.resize(crypto_sign_PUBLICKEYBYTES); + secret_key.resize(crypto_sign_SECRETKEYBYTES); + crypto_sign_keypair(public_key.data(), secret_key.data()); +#else + PICRYPT_DISABLED_WARNING +#endif +} + + +void PICrypt::generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed) { +#ifdef PIP_CRYPT + if (!init() || seed.isEmpty()) return; + public_key.resize(crypto_sign_PUBLICKEYBYTES); + secret_key.resize(crypto_sign_SECRETKEYBYTES); + crypto_sign_seed_keypair(public_key.data(), secret_key.data(), hash(seed).data()); +#else + PICRYPT_DISABLED_WARNING +#endif +} + + +PIByteArray PICrypt::extractSignPublicKey(const PIByteArray & secret_key) { + PIByteArray pk; +#ifdef PIP_CRYPT + if (!init() || secret_key.size() != crypto_sign_SECRETKEYBYTES) return pk; + pk.resize(crypto_sign_PUBLICKEYBYTES); + crypto_sign_ed25519_sk_to_pk(pk.data(), secret_key.data()); +#else + PICRYPT_DISABLED_WARNING +#endif + return pk; +} + + +PIByteArray PICrypt::signMessage(const PIByteArray & data, PIByteArray secret_key) { + PIByteArray sign; +#ifdef PIP_CRYPT + if (!init()) return sign; + sign.resize(crypto_sign_BYTES); + crypto_sign_detached(sign.data(), 0, data.data(), data.size(), secret_key.data()); +#else + PICRYPT_DISABLED_WARNING +#endif + return sign; +} + + +bool PICrypt::verifySign(const PIByteArray & data, const PIByteArray & signature, PIByteArray public_key) { +#ifdef PIP_CRYPT + if (!init()) return false; + return (crypto_sign_verify_detached(signature.data(), data.data(), data.size(), public_key.data()) == 0); +#else + PICRYPT_DISABLED_WARNING +#endif + return false; +} + + +void PICrypt::generateKeypair(PIByteArray & public_key, PIByteArray & secret_key) { +#ifdef PIP_CRYPT + if (!init()) return; + public_key.resize(crypto_box_PUBLICKEYBYTES); + secret_key.resize(crypto_box_SECRETKEYBYTES); + crypto_box_keypair(public_key.data(), secret_key.data()); +#else + PICRYPT_DISABLED_WARNING +#endif +} + + +void PICrypt::generateKeypair(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed) { +#ifdef PIP_CRYPT + if (!init()) return; + public_key.resize(crypto_box_PUBLICKEYBYTES); + secret_key.resize(crypto_box_SECRETKEYBYTES); + crypto_box_seed_keypair(public_key.data(), secret_key.data(), hash(seed).data()); +#else + PICRYPT_DISABLED_WARNING +#endif +} + + +PIByteArray PICrypt::crypt(const PIByteArray & data, const PIByteArray & public_key, const PIByteArray & secret_key) { + PIByteArray ret; +#ifdef PIP_CRYPT + if (!init()) return ret; + if (public_key.size() != crypto_box_PUBLICKEYBYTES) return ret; + if (secret_key.size() != crypto_box_SECRETKEYBYTES) return ret; + PIByteArray n; + ret.resize(data.size() + crypto_box_MACBYTES); + n.resize(crypto_box_NONCEBYTES); + randombytes_buf(n.data(), n.size()); + if (crypto_box_easy(ret.data(), data.data(), data.size(), n.data(), public_key.data(), secret_key.data()) != 0) return PIByteArray(); + ret.append(n); +#else + PICRYPT_DISABLED_WARNING +#endif + return ret; +} + + +PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, const PIByteArray & public_key, const PIByteArray & secret_key, bool * ok) { + PIByteArray ret; +#ifdef PIP_CRYPT + if (!init()) return ret; + if (public_key.size() != crypto_box_PUBLICKEYBYTES) { + if (ok) *ok = false; + return ret; + } + if (secret_key.size() != crypto_box_SECRETKEYBYTES) { + if (ok) *ok = false; + return ret; + } + if (crypt_data.size() < crypto_box_NONCEBYTES + crypto_box_MACBYTES) { + if (ok) *ok = false; + return ret; + } + PIByteArray n; + n.resize(crypto_secretbox_NONCEBYTES); + ret.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES); + memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size()); + if (crypto_box_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), public_key.data(), secret_key.data()) != + 0) { + if (ok) *ok = false; + // piCout << "[PICrypt]" << "bad key_"; + return PIByteArray(); + } else if (ok) + *ok = true; +#else + PICRYPT_DISABLED_WARNING +#endif + return ret; +} + + +PIByteArray PICrypt::passwordHash(const PIString & password, const PIByteArray & seed) { +#ifdef crypto_pwhash_ALG_ARGON2I13 + // char out[crypto_pwhash_STRBYTES]; + PIByteArray pass = password.toUTF8(); + PIByteArray n = hash(seed); + PIByteArray ph; + ph.resize(crypto_box_SEEDBYTES); + n.resize(crypto_pwhash_SALTBYTES); + // randombytes_buf(n.data(), n.size()); + // crypto_shorthash(n.data(), seed.data(), seed.size(), PIByteArray(crypto_shorthash_KEYBYTES).data()); + int r = crypto_pwhash(ph.data(), + ph.size(), + (const char *)pass.data(), + pass.size(), + n.data(), + crypto_pwhash_argon2i_opslimit_moderate(), + crypto_pwhash_argon2i_memlimit_moderate(), + crypto_pwhash_ALG_ARGON2I13); + // crypto_pwhash_str(out, (const char*)pass.data(), pass.size(), crypto_pwhash_argon2i_opslimit_moderate(), + // crypto_pwhash_argon2i_memlimit_moderate()); + pass.fill(0); + if (r != 0) return PIByteArray(); + return ph; +// PIByteArray ret; +// ret << ph << n << crypto_pwhash_argon2i_opslimit_moderate() << crypto_pwhash_argon2i_memlimit_moderate(); +// return ret; +#else + return PIByteArray(); +#endif +} + + +PIString PICrypt::version() { +#ifdef PIP_CRYPT + return SODIUM_VERSION_STRING; +#else + return PIString(); +#endif +} + + +bool PICrypt::init() { +#ifdef PIP_CRYPT + static bool inited = false; + if (inited) return true; + // piCout << "[PICrypt]" << "init ..."; + inited = sodium_init(); + if (!inited) inited = sodium_init(); + // piCout << "[PICrypt]" << "init" << inited; + return inited; +#else + PICRYPT_DISABLED_WARNING +#endif + return false; +} diff --git a/libs/fftw/pifft.cpp b/libs/fftw/pifft.cpp index 88ae4843..5fc83bcc 100644 --- a/libs/fftw/pifft.cpp +++ b/libs/fftw/pifft.cpp @@ -1,34 +1,48 @@ -/* - PIP - Platform Independent Primitives - Class for FFT, IFFT and Hilbert transformations - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . -*/ - -#include "pifft.h" -#include "pifft_p.h" - - -#define _PIFFTW_CPP(type) \ - _PIFFTW_P_##type##_::_PIFFTW_P_##type##_() {impl = new PIFFTW_Private();;} \ - _PIFFTW_P_##type##_::~_PIFFTW_P_##type##_() {delete (PIFFTW_Private*)impl;} \ - const PIVector > & _PIFFTW_P_##type##_::calcFFT(const PIVector > & in) {return ((PIFFTW_Private*)impl)->calcFFT(in);} \ - const PIVector > & _PIFFTW_P_##type##_::calcFFTR(const PIVector & in) {return ((PIFFTW_Private*)impl)->calcFFT(in);} \ - const PIVector > & _PIFFTW_P_##type##_::calcFFTI(const PIVector > & in) {return ((PIFFTW_Private*)impl)->calcFFTinverse(in);} \ - void _PIFFTW_P_##type##_::preparePlan(int size, int op) {return ((PIFFTW_Private*)impl)->preparePlan(size, op);} - -_PIFFTW_CPP(float) -_PIFFTW_CPP(double) -_PIFFTW_CPP(ldouble) +/* + PIP - Platform Independent Primitives + Class for FFT, IFFT and Hilbert transformations + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . +*/ + +#include "pifft.h" + +#include "pifft_p.h" + + +#define _PIFFTW_CPP(type) \ + _PIFFTW_P_##type##_::_PIFFTW_P_##type##_() { \ + impl = new PIFFTW_Private(); \ + ; \ + } \ + _PIFFTW_P_##type##_::~_PIFFTW_P_##type##_() { \ + delete (PIFFTW_Private *)impl; \ + } \ + const PIVector> & _PIFFTW_P_##type##_::calcFFT(const PIVector> & in) { \ + return ((PIFFTW_Private *)impl)->calcFFT(in); \ + } \ + const PIVector> & _PIFFTW_P_##type##_::calcFFTR(const PIVector & in) { \ + return ((PIFFTW_Private *)impl)->calcFFT(in); \ + } \ + const PIVector> & _PIFFTW_P_##type##_::calcFFTI(const PIVector> & in) { \ + return ((PIFFTW_Private *)impl)->calcFFTinverse(in); \ + } \ + void _PIFFTW_P_##type##_::preparePlan(int size, int op) { \ + return ((PIFFTW_Private *)impl)->preparePlan(size, op); \ + } + +_PIFFTW_CPP(float) +_PIFFTW_CPP(double) +_PIFFTW_CPP(ldouble) diff --git a/libs/fftw/pifft_p.h b/libs/fftw/pifft_p.h index 1f5bc258..45795601 100644 --- a/libs/fftw/pifft_p.h +++ b/libs/fftw/pifft_p.h @@ -1,180 +1,247 @@ -/*! \file pifft_p.h - * \brief Class for FFT, IFFT and Hilbert transformations -*/ -/* - PIP - Platform Independent Primitives - Private header for fftw3 - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . -*/ - -#ifndef PIFFT_P_H -#define PIFFT_P_H - -#include "pivector.h" -#include "picout.h" -#if defined(PIP_FFTW) || defined(PIP_FFTWf) || defined(PIP_FFTWl) || defined(PIP_FFTWq) -# include "fftw3.h" -#else -# define FFTW_FORWARD 0 -# define FFTW_BACKWARD 0 -# define FFTW_ESTIMATE 0 -# define FFTW_MEASURE 0 -#endif - - -template -class PIFFTW_Private -{ -public: - explicit PIFFTW_Private() { - plan = 0; -//#ifndef PIP_FFTW -// piCout << "[PIFFTW]" << "Warning: PIFFTW is disabled, to enable install libfftw3-dev library and build pip with -DFFTW=1"; -//#endif - p_makeThreadSafe(); - } - ~PIFFTW_Private() {p_destroyPlan(plan);} - - const PIVector > & calcFFT(const PIVector > & in) { - if (prepare != PlanParams(in.size(), fo_complex)) { - p_out.resize(in.size()); - //piCout << "[PIFFTW]" << "creating plan"; - p_createPlan_c2c_1d(plan, in.size(), in.data(), p_out.data(), FFTW_FORWARD, FFTW_ESTIMATE | FFTW_UNALIGNED); - prepare = PlanParams(in.size(), fo_complex); - } - p_executePlan_c2c(plan, in.data(), p_out.data()); - return p_out; - } - const PIVector > & calcFFT(const PIVector & in) { - if (prepare != PlanParams(in.size(), fo_real)) { - p_out.resize(in.size()); - //piCout << "[PIFFTW]" << "creating plan"; - p_createPlan_r2c_1d(plan, in.size(), in.data(), p_out.data(), FFTW_ESTIMATE | FFTW_UNALIGNED); - prepare = PlanParams(in.size(), fo_real); - } - p_executePlan_r2c(plan, in.data(), p_out.data()); - return p_out; - } - const PIVector > & calcFFTinverse(const PIVector > & in) { - if (prepare != PlanParams(in.size(), fo_inverse)) { - p_out.resize(in.size()); - //piCout << "[PIFFTW]" << "creating plan"; - p_createPlan_c2c_1d(plan, in.size(), in.data(), p_out.data(), FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_UNALIGNED); - prepare = PlanParams(in.size(), fo_inverse); - } - p_executePlan_c2c(plan, in.data(), p_out.data()); - return p_out; - } - - enum FFT_Operation {fo_real, fo_complex, fo_inverse}; - - void preparePlan(int size, int op) { - p_inr.clear(); - p_in.clear(); - p_out.clear(); - switch ((FFT_Operation)op) { - case fo_real: - p_inr.resize(size); - p_out.resize(size); - p_createPlan_r2c_1d(plan, size, p_inr.data(), p_out.data(), FFTW_MEASURE | FFTW_UNALIGNED); - break; - case fo_complex: - p_in.resize(size); - p_out.resize(size); - p_createPlan_c2c_1d(plan, size, p_in.data(), p_out.data(), FFTW_FORWARD, FFTW_MEASURE | FFTW_UNALIGNED); - break; - case fo_inverse: - p_in.resize(size); - p_out.resize(size); - p_createPlan_c2c_1d(plan, size, p_in.data(), p_out.data(), FFTW_BACKWARD, FFTW_MEASURE | FFTW_UNALIGNED); - break; - default: - size = 0; - break; - } - prepare = PlanParams(size, (FFT_Operation)op); - } - - inline void p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) {} - inline void p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) {} - inline void p_executePlan(void * plan) {} - inline void p_executePlan_c2c(void * plan, const void * in, void * out) {} - inline void p_executePlan_r2c(void * plan, const void * in, void * out) {} - inline void p_destroyPlan(void *& plan) {} - inline void p_makeThreadSafe() {} - - struct PlanParams { - PlanParams() {size = 0; op = fo_complex;} - PlanParams(int size_, FFT_Operation op_) {size = size_; op = op_;} - bool isValid() {return size > 0;} - bool operator ==(const PlanParams & v) const {return (v.size == size) && (v.op == op);} - bool operator !=(const PlanParams & v) const {return !(*this == v);} - int size; - FFT_Operation op; - }; - - PIVector > p_in; - PIVector p_inr; - PIVector > p_out; - void * plan; - PlanParams prepare; -}; - - -#ifdef PIP_FFTWf -template<> inline void PIFFTW_Private::p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) { - plan = fftwf_plan_dft_1d(size, (fftwf_complex *)in, (fftwf_complex *)out, dir, flags);} -template<> inline void PIFFTW_Private::p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) { - plan = fftwf_plan_dft_r2c_1d(size, (float *)in, (fftwf_complex *)out, flags);} -template<> inline void PIFFTW_Private::p_executePlan(void * plan) {fftwf_execute((fftwf_plan)plan);} -template<> inline void PIFFTW_Private::p_executePlan_c2c(void * plan, const void * in, void * out) {fftwf_execute_dft((fftwf_plan)plan, (fftwf_complex *)in, (fftwf_complex *)out);} -template<> inline void PIFFTW_Private::p_executePlan_r2c(void * plan, const void * in, void * out) {fftwf_execute_dft_r2c((fftwf_plan)plan, (float *)in, (fftwf_complex *)out);} -template<> inline void PIFFTW_Private::p_destroyPlan(void *& plan) {if (plan) fftwf_destroy_plan((fftwf_plan)plan); plan = 0;} -# ifdef PIP_FFTWf_THREADSAFE -template<> inline void PIFFTW_Private::p_makeThreadSafe() {fftwf_make_planner_thread_safe();} -# endif -#endif // PIP_FFTWf - -#ifdef PIP_FFTW -template<> inline void PIFFTW_Private::p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) { - plan = fftw_plan_dft_1d(size, (fftw_complex *)in, (fftw_complex *)out, dir, flags);} -template<> inline void PIFFTW_Private::p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) { - plan = fftw_plan_dft_r2c_1d(size, (double *)in, (fftw_complex *)out, flags);} -template<> inline void PIFFTW_Private::p_executePlan(void * plan) {fftw_execute((fftw_plan)plan);} -template<> inline void PIFFTW_Private::p_executePlan_c2c(void * plan, const void * in, void * out) {fftw_execute_dft((fftw_plan)plan, (fftw_complex *)in, (fftw_complex *)out);} -template<> inline void PIFFTW_Private::p_executePlan_r2c(void * plan, const void * in, void * out) {fftw_execute_dft_r2c((fftw_plan)plan, (double *)in, (fftw_complex *)out);} -template<> inline void PIFFTW_Private::p_destroyPlan(void *& plan) {if (plan) fftw_destroy_plan((fftw_plan)plan); plan = 0;} -# ifdef PIP_FFTW_THREADSAFE -template<> inline void PIFFTW_Private::p_makeThreadSafe() {fftw_make_planner_thread_safe();} -# endif -#endif // PIP_FFTW - -#ifdef PIP_FFTWl -template<> inline void PIFFTW_Private::p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) { - plan = fftwl_plan_dft_1d(size, (fftwl_complex *)in, (fftwl_complex *)out, dir, flags);} -template<> inline void PIFFTW_Private::p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) { - plan = fftwl_plan_dft_r2c_1d(size, (ldouble *)in, (fftwl_complex *)out, flags);} -template<> inline void PIFFTW_Private::p_executePlan(void * plan) {fftwl_execute((fftwl_plan)plan);} -template<> inline void PIFFTW_Private::p_executePlan_c2c(void * plan, const void * in, void * out) {fftwl_execute_dft((fftwl_plan)plan, (fftwl_complex *)in, (fftwl_complex *)out);} -template<> inline void PIFFTW_Private::p_executePlan_r2c(void * plan, const void * in, void * out) {fftwl_execute_dft_r2c((fftwl_plan)plan, (ldouble *)in, (fftwl_complex *)out);} -template<> inline void PIFFTW_Private::p_destroyPlan(void *& plan) {if (plan) fftwl_destroy_plan((fftwl_plan)plan); plan = 0;} -# ifdef PIP_FFTWl_THREADSAFE -template<> inline void PIFFTW_Private::p_makeThreadSafe() {fftwl_make_planner_thread_safe();} -# endif -#endif // PIP_FFTWl - - -#endif // PIFFT_H +/*! \file pifft_p.h + * \brief Class for FFT, IFFT and Hilbert transformations + */ +/* + PIP - Platform Independent Primitives + Private header for fftw3 + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . +*/ + +#ifndef PIFFT_P_H +#define PIFFT_P_H + +#include "picout.h" +#include "pivector.h" +#if defined(PIP_FFTW) || defined(PIP_FFTWf) || defined(PIP_FFTWl) || defined(PIP_FFTWq) +# include "fftw3.h" +#else +# define FFTW_FORWARD 0 +# define FFTW_BACKWARD 0 +# define FFTW_ESTIMATE 0 +# define FFTW_MEASURE 0 +#endif + + +template +class PIFFTW_Private { +public: + explicit PIFFTW_Private() { + plan = 0; + // #ifndef PIP_FFTW + // piCout << "[PIFFTW]" << "Warning: PIFFTW is disabled, to enable install libfftw3-dev library and build pip with -DFFTW=1"; + // #endif + p_makeThreadSafe(); + } + ~PIFFTW_Private() { p_destroyPlan(plan); } + + const PIVector> & calcFFT(const PIVector> & in) { + if (prepare != PlanParams(in.size(), fo_complex)) { + p_out.resize(in.size()); + // piCout << "[PIFFTW]" << "creating plan"; + p_createPlan_c2c_1d(plan, in.size(), in.data(), p_out.data(), FFTW_FORWARD, FFTW_ESTIMATE | FFTW_UNALIGNED); + prepare = PlanParams(in.size(), fo_complex); + } + p_executePlan_c2c(plan, in.data(), p_out.data()); + return p_out; + } + const PIVector> & calcFFT(const PIVector & in) { + if (prepare != PlanParams(in.size(), fo_real)) { + p_out.resize(in.size()); + // piCout << "[PIFFTW]" << "creating plan"; + p_createPlan_r2c_1d(plan, in.size(), in.data(), p_out.data(), FFTW_ESTIMATE | FFTW_UNALIGNED); + prepare = PlanParams(in.size(), fo_real); + } + p_executePlan_r2c(plan, in.data(), p_out.data()); + return p_out; + } + const PIVector> & calcFFTinverse(const PIVector> & in) { + if (prepare != PlanParams(in.size(), fo_inverse)) { + p_out.resize(in.size()); + // piCout << "[PIFFTW]" << "creating plan"; + p_createPlan_c2c_1d(plan, in.size(), in.data(), p_out.data(), FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_UNALIGNED); + prepare = PlanParams(in.size(), fo_inverse); + } + p_executePlan_c2c(plan, in.data(), p_out.data()); + return p_out; + } + + enum FFT_Operation { + fo_real, + fo_complex, + fo_inverse + }; + + void preparePlan(int size, int op) { + p_inr.clear(); + p_in.clear(); + p_out.clear(); + switch ((FFT_Operation)op) { + case fo_real: + p_inr.resize(size); + p_out.resize(size); + p_createPlan_r2c_1d(plan, size, p_inr.data(), p_out.data(), FFTW_MEASURE | FFTW_UNALIGNED); + break; + case fo_complex: + p_in.resize(size); + p_out.resize(size); + p_createPlan_c2c_1d(plan, size, p_in.data(), p_out.data(), FFTW_FORWARD, FFTW_MEASURE | FFTW_UNALIGNED); + break; + case fo_inverse: + p_in.resize(size); + p_out.resize(size); + p_createPlan_c2c_1d(plan, size, p_in.data(), p_out.data(), FFTW_BACKWARD, FFTW_MEASURE | FFTW_UNALIGNED); + break; + default: size = 0; break; + } + prepare = PlanParams(size, (FFT_Operation)op); + } + + inline void p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) {} + inline void p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) {} + inline void p_executePlan(void * plan) {} + inline void p_executePlan_c2c(void * plan, const void * in, void * out) {} + inline void p_executePlan_r2c(void * plan, const void * in, void * out) {} + inline void p_destroyPlan(void *& plan) {} + inline void p_makeThreadSafe() {} + + struct PlanParams { + PlanParams() { + size = 0; + op = fo_complex; + } + PlanParams(int size_, FFT_Operation op_) { + size = size_; + op = op_; + } + bool isValid() { return size > 0; } + bool operator==(const PlanParams & v) const { return (v.size == size) && (v.op == op); } + bool operator!=(const PlanParams & v) const { return !(*this == v); } + int size; + FFT_Operation op; + }; + + PIVector> p_in; + PIVector p_inr; + PIVector> p_out; + void * plan; + PlanParams prepare; +}; + + +#ifdef PIP_FFTWf +template<> +inline void PIFFTW_Private::p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) { + plan = fftwf_plan_dft_1d(size, (fftwf_complex *)in, (fftwf_complex *)out, dir, flags); +} +template<> +inline void PIFFTW_Private::p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) { + plan = fftwf_plan_dft_r2c_1d(size, (float *)in, (fftwf_complex *)out, flags); +} +template<> +inline void PIFFTW_Private::p_executePlan(void * plan) { + fftwf_execute((fftwf_plan)plan); +} +template<> +inline void PIFFTW_Private::p_executePlan_c2c(void * plan, const void * in, void * out) { + fftwf_execute_dft((fftwf_plan)plan, (fftwf_complex *)in, (fftwf_complex *)out); +} +template<> +inline void PIFFTW_Private::p_executePlan_r2c(void * plan, const void * in, void * out) { + fftwf_execute_dft_r2c((fftwf_plan)plan, (float *)in, (fftwf_complex *)out); +} +template<> +inline void PIFFTW_Private::p_destroyPlan(void *& plan) { + if (plan) fftwf_destroy_plan((fftwf_plan)plan); + plan = 0; +} +# ifdef PIP_FFTWf_THREADSAFE +template<> +inline void PIFFTW_Private::p_makeThreadSafe() { + fftwf_make_planner_thread_safe(); +} +# endif +#endif // PIP_FFTWf + +#ifdef PIP_FFTW +template<> +inline void PIFFTW_Private::p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) { + plan = fftw_plan_dft_1d(size, (fftw_complex *)in, (fftw_complex *)out, dir, flags); +} +template<> +inline void PIFFTW_Private::p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) { + plan = fftw_plan_dft_r2c_1d(size, (double *)in, (fftw_complex *)out, flags); +} +template<> +inline void PIFFTW_Private::p_executePlan(void * plan) { + fftw_execute((fftw_plan)plan); +} +template<> +inline void PIFFTW_Private::p_executePlan_c2c(void * plan, const void * in, void * out) { + fftw_execute_dft((fftw_plan)plan, (fftw_complex *)in, (fftw_complex *)out); +} +template<> +inline void PIFFTW_Private::p_executePlan_r2c(void * plan, const void * in, void * out) { + fftw_execute_dft_r2c((fftw_plan)plan, (double *)in, (fftw_complex *)out); +} +template<> +inline void PIFFTW_Private::p_destroyPlan(void *& plan) { + if (plan) fftw_destroy_plan((fftw_plan)plan); + plan = 0; +} +# ifdef PIP_FFTW_THREADSAFE +template<> +inline void PIFFTW_Private::p_makeThreadSafe() { + fftw_make_planner_thread_safe(); +} +# endif +#endif // PIP_FFTW + +#ifdef PIP_FFTWl +template<> +inline void PIFFTW_Private::p_createPlan_c2c_1d(void *& plan, int size, const void * in, void * out, int dir, int flags) { + plan = fftwl_plan_dft_1d(size, (fftwl_complex *)in, (fftwl_complex *)out, dir, flags); +} +template<> +inline void PIFFTW_Private::p_createPlan_r2c_1d(void *& plan, int size, const void * in, void * out, int flags) { + plan = fftwl_plan_dft_r2c_1d(size, (ldouble *)in, (fftwl_complex *)out, flags); +} +template<> +inline void PIFFTW_Private::p_executePlan(void * plan) { + fftwl_execute((fftwl_plan)plan); +} +template<> +inline void PIFFTW_Private::p_executePlan_c2c(void * plan, const void * in, void * out) { + fftwl_execute_dft((fftwl_plan)plan, (fftwl_complex *)in, (fftwl_complex *)out); +} +template<> +inline void PIFFTW_Private::p_executePlan_r2c(void * plan, const void * in, void * out) { + fftwl_execute_dft_r2c((fftwl_plan)plan, (ldouble *)in, (fftwl_complex *)out); +} +template<> +inline void PIFFTW_Private::p_destroyPlan(void *& plan) { + if (plan) fftwl_destroy_plan((fftwl_plan)plan); + plan = 0; +} +# ifdef PIP_FFTWl_THREADSAFE +template<> +inline void PIFFTW_Private::p_makeThreadSafe() { + fftwl_make_planner_thread_safe(); +} +# endif +#endif // PIP_FFTWl + + +#endif // PIFFT_H diff --git a/libs/io_utils/pibroadcast.cpp b/libs/io_utils/pibroadcast.cpp index e8dc3367..703c7f9c 100644 --- a/libs/io_utils/pibroadcast.cpp +++ b/libs/io_utils/pibroadcast.cpp @@ -1,266 +1,269 @@ -/* - PIP - Platform Independent Primitives - Broadcast for all interfaces, including loopback - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . -*/ - -#include "pibroadcast.h" - -/** \class PIBroadcast - * \brief Broadcast for all interfaces, including loopback - * - * \section PIBroadcast_synopsis Synopsis - * %PIBroadcast used as multichannel IO device. It can use - * multicast, broadcast and loopback ethernet channels to - * send/receive packets. \a send() function send packet to - * all initialized ethernets. \a receiveEvent() raised on - * packet received by any ethernet. All multi/broadcast - * ethernets created for all current addresses, obtained - * by \a PIEthernets::allAddresses(). - * - * * \a Multicast ethernets use \a multicastGroup() and \a multicastPort() - * * \a Broadcast ethernets use \a broadcastPort() - * * \a Loopback ethernet use \a loopbackPortsCount() started from \a loopbackPort() - * - * %PIBroadcast starts thread, which every 3 seconds check if - * current \a PIEthernet::allAddresses() was changed and call - * \a reinit() if it necessary. - * -*/ - -#define MULTICAST_TTL 4 - - -PIBroadcast::PIBroadcast(bool send_only): PIThread(), PIEthUtilBase() { - _channels = All; - eth_lo = 0; - mcast_address.set("232.13.3.14", 14100); - lo_port = 14200; - lo_pcnt = 5; - _started = false; - _send_only = send_only; - _reinit = true; -} - - -PIBroadcast::~PIBroadcast() { - PIThread::stop(); - mcast_mutex.unlock(); - destroyAll(); -} - - -void PIBroadcast::setChannels(PIBroadcast::Channels ch) { - PIMutexLocker ml(mcast_mutex); - _channels = ch; - _reinit = true; -} - - -void PIBroadcast::setMulticastGroup(const PIString & mg) { - PIMutexLocker ml(mcast_mutex); - mcast_address.setIP(mg); - _reinit = true; -} - - -void PIBroadcast::setMulticastPort(ushort port) { - PIMutexLocker ml(mcast_mutex); - mcast_address.setPort(port); - _reinit = true; -} - - -void PIBroadcast::setMulticastAddress(const PIEthernet::Address & addr) { - PIMutexLocker ml(mcast_mutex); - mcast_address = addr; - _reinit = true; -} - - -void PIBroadcast::setBroadcastPort(ushort port) { - PIMutexLocker ml(mcast_mutex); - bcast_port = port; - _reinit = true; -} - - -void PIBroadcast::setLoopbackPort(ushort port) { - PIMutexLocker ml(mcast_mutex); - lo_port = port; - _reinit = true; -} - - -void PIBroadcast::setLoopbackPortsCount(int count) { - PIMutexLocker ml(mcast_mutex); - lo_pcnt = count; - _reinit = true; -} - - -void PIBroadcast::destroyAll() { - piForeach (PIEthernet * e, eth_mcast) { - e->stopThreadedRead(); - delete e; - } - eth_mcast.clear(); - if (eth_lo) { - eth_lo->stopThreadedRead(); - delete eth_lo; - eth_lo = 0; - } -} - - -void PIBroadcast::initAll(PIVector al) { - PIMutexLocker ml(mcast_mutex); - destroyAll(); - _reinit = false; - prev_al = al; - al.removeAll(PIEthernet::Address("127.0.0.1")); - al << mcast_address; - eth_mcast.clear(); - PIEthernet::InterfaceList ifaces = PIEthernet::interfaces(); - piForeachC (PIEthernet::Address & a, al) { - PIEthernet * ce = 0; - //piCout << "mcast try" << a; - if (_channels[Multicast]) { - ce = new PIEthernet(); - ce->setDebug(false); - ce->setName("PIMulticast_" + a.toString()); - ce->setParameters(0); - ce->setSendAddress(mcast_address); - ce->setMulticastTTL(MULTICAST_TTL); - if (!_send_only) { - ce->setReadAddress(a.ipString(), mcast_address.port()); - ce->joinMulticastGroup(mcast_address.ipString()); - //piCout << "mcast " << ce->readAddress() << ce->sendAddress(); - if (ce->open()) { - eth_mcast << ce; - CONNECT2(void, const uchar *, ssize_t, ce, threadedReadEvent, this, mcastRead); - } else { - delete ce; - } - } else { - eth_mcast << ce; - } - } - - if (_channels[Broadcast]) { - ce = new PIEthernet(); - ce->setDebug(false); - ce->setName("PIMulticast_" + a.toString()); - ce->setParameters(PIEthernet::Broadcast); - const PIEthernet::Interface * cint = ifaces.getByAddress(a.ipString()); - PIEthernet::Address nm((cint == 0) ? "255.255.255.0" : cint->netmask); - ce->setSendAddress(PIEthernet::getBroadcast(a, nm).ipString(), bcast_port); - if (!_send_only) { - ce->setReadAddress(PIEthernet::Address(a.ip(), bcast_port)); - //piCout << "bcast " << ce->readAddress() << ce->sendAddress(); - if (ce->open()) { - eth_mcast << ce; - CONNECT2(void, const uchar *, ssize_t, ce, threadedReadEvent, this, mcastRead); - } else { - delete ce; - } - } else { - eth_mcast << ce; - } - } - } - - if (_channels[Loopback]) { - eth_lo = new PIEthernet(); - eth_lo->setDebug(false); - eth_lo->setName("PIMulticast_loopback"); - if (!_send_only) { - eth_lo->setParameter(PIEthernet::ReuseAddress, false); - CONNECT2(void, const uchar *, ssize_t, eth_lo, threadedReadEvent, this, mcastRead); - for (int i = 0; i < lo_pcnt; ++i) { - eth_lo->setReadAddress("127.0.0.1", lo_port + i); - if (eth_lo->open()) { - //piCout << "bind local to" << (lo_port + i); - break; - } - } - } - } -} - - -void PIBroadcast::send(const PIByteArray & data) { - if (!isRunning()) { - reinit(); - PIThread::start(3000); - } - PIByteArray cd = cryptData(data); - if (cd.isEmpty()) return; - PIMutexLocker ml(mcast_mutex); - piForeach (PIEthernet * e, eth_mcast) e->send(cd); - if (eth_lo) { - for (int i = 0; i < lo_pcnt; ++i) { - eth_lo->send("127.0.0.1", lo_port + i, cd); - } - } -} - - -void PIBroadcast::startRead() { - if (!isRunning()) { - _started = false; - reinit(); - PIThread::start(3000); - } - if (_send_only) return; - PIMutexLocker ml(mcast_mutex); - piForeach (PIEthernet * e, eth_mcast) e->startThreadedRead(); - if (eth_lo) eth_lo->startThreadedRead(); - _started = true; -} - - -void PIBroadcast::stopRead() { - if (isRunning()) stop(); - PIMutexLocker ml(mcast_mutex); - piForeach (PIEthernet * e, eth_mcast) e->stopThreadedRead(); - if (eth_lo) eth_lo->stopThreadedRead(); - _started = false; -} - - -void PIBroadcast::reinit() { - initAll(PIEthernet::allAddresses()); - if (_started) startRead(); -} - - -void PIBroadcast::mcastRead(const uchar * data, ssize_t size) { - PIByteArray cd = decryptData(PIByteArray(data, size)); - if (cd.isEmpty()) return; - received(cd); - receiveEvent(cd); -} - - -void PIBroadcast::run() { - PIVector al = PIEthernet::allAddresses(); - mcast_mutex.lock(); - bool r = _reinit, ac = (al != prev_al); - mcast_mutex.unlock(); - if (ac || r) reinit(); - if (ac) addressesChanged(); -} +/* + PIP - Platform Independent Primitives + Broadcast for all interfaces, including loopback + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . +*/ + +#include "pibroadcast.h" + +/** \class PIBroadcast + * \brief Broadcast for all interfaces, including loopback + * + * \section PIBroadcast_synopsis Synopsis + * %PIBroadcast used as multichannel IO device. It can use + * multicast, broadcast and loopback ethernet channels to + * send/receive packets. \a send() function send packet to + * all initialized ethernets. \a receiveEvent() raised on + * packet received by any ethernet. All multi/broadcast + * ethernets created for all current addresses, obtained + * by \a PIEthernets::allAddresses(). + * + * * \a Multicast ethernets use \a multicastGroup() and \a multicastPort() + * * \a Broadcast ethernets use \a broadcastPort() + * * \a Loopback ethernet use \a loopbackPortsCount() started from \a loopbackPort() + * + * %PIBroadcast starts thread, which every 3 seconds check if + * current \a PIEthernet::allAddresses() was changed and call + * \a reinit() if it necessary. + * + */ + +#define MULTICAST_TTL 4 + + +PIBroadcast::PIBroadcast(bool send_only): PIThread(), PIEthUtilBase() { + _channels = All; + eth_lo = 0; + mcast_address.set("232.13.3.14", 14100); + lo_port = 14200; + lo_pcnt = 5; + _started = false; + _send_only = send_only; + _reinit = true; +} + + +PIBroadcast::~PIBroadcast() { + PIThread::stop(); + mcast_mutex.unlock(); + destroyAll(); +} + + +void PIBroadcast::setChannels(PIBroadcast::Channels ch) { + PIMutexLocker ml(mcast_mutex); + _channels = ch; + _reinit = true; +} + + +void PIBroadcast::setMulticastGroup(const PIString & mg) { + PIMutexLocker ml(mcast_mutex); + mcast_address.setIP(mg); + _reinit = true; +} + + +void PIBroadcast::setMulticastPort(ushort port) { + PIMutexLocker ml(mcast_mutex); + mcast_address.setPort(port); + _reinit = true; +} + + +void PIBroadcast::setMulticastAddress(const PIEthernet::Address & addr) { + PIMutexLocker ml(mcast_mutex); + mcast_address = addr; + _reinit = true; +} + + +void PIBroadcast::setBroadcastPort(ushort port) { + PIMutexLocker ml(mcast_mutex); + bcast_port = port; + _reinit = true; +} + + +void PIBroadcast::setLoopbackPort(ushort port) { + PIMutexLocker ml(mcast_mutex); + lo_port = port; + _reinit = true; +} + + +void PIBroadcast::setLoopbackPortsCount(int count) { + PIMutexLocker ml(mcast_mutex); + lo_pcnt = count; + _reinit = true; +} + + +void PIBroadcast::destroyAll() { + piForeach(PIEthernet * e, eth_mcast) { + e->stopThreadedRead(); + delete e; + } + eth_mcast.clear(); + if (eth_lo) { + eth_lo->stopThreadedRead(); + delete eth_lo; + eth_lo = 0; + } +} + + +void PIBroadcast::initAll(PIVector al) { + PIMutexLocker ml(mcast_mutex); + destroyAll(); + _reinit = false; + prev_al = al; + al.removeAll(PIEthernet::Address("127.0.0.1")); + al << mcast_address; + eth_mcast.clear(); + PIEthernet::InterfaceList ifaces = PIEthernet::interfaces(); + piForeachC(PIEthernet::Address & a, al) { + PIEthernet * ce = 0; + // piCout << "mcast try" << a; + if (_channels[Multicast]) { + ce = new PIEthernet(); + ce->setDebug(false); + ce->setName("PIMulticast_" + a.toString()); + ce->setParameters(0); + ce->setSendAddress(mcast_address); + ce->setMulticastTTL(MULTICAST_TTL); + if (!_send_only) { + ce->setReadAddress(a.ipString(), mcast_address.port()); + ce->joinMulticastGroup(mcast_address.ipString()); + // piCout << "mcast " << ce->readAddress() << ce->sendAddress(); + if (ce->open()) { + eth_mcast << ce; + CONNECT2(void, const uchar *, ssize_t, ce, threadedReadEvent, this, mcastRead); + } else { + delete ce; + } + } else { + eth_mcast << ce; + } + } + + if (_channels[Broadcast]) { + ce = new PIEthernet(); + ce->setDebug(false); + ce->setName("PIMulticast_" + a.toString()); + ce->setParameters(PIEthernet::Broadcast); + const PIEthernet::Interface * cint = ifaces.getByAddress(a.ipString()); + PIEthernet::Address nm((cint == 0) ? "255.255.255.0" : cint->netmask); + ce->setSendAddress(PIEthernet::getBroadcast(a, nm).ipString(), bcast_port); + if (!_send_only) { + ce->setReadAddress(PIEthernet::Address(a.ip(), bcast_port)); + // piCout << "bcast " << ce->readAddress() << ce->sendAddress(); + if (ce->open()) { + eth_mcast << ce; + CONNECT2(void, const uchar *, ssize_t, ce, threadedReadEvent, this, mcastRead); + } else { + delete ce; + } + } else { + eth_mcast << ce; + } + } + } + + if (_channels[Loopback]) { + eth_lo = new PIEthernet(); + eth_lo->setDebug(false); + eth_lo->setName("PIMulticast_loopback"); + if (!_send_only) { + eth_lo->setParameter(PIEthernet::ReuseAddress, false); + CONNECT2(void, const uchar *, ssize_t, eth_lo, threadedReadEvent, this, mcastRead); + for (int i = 0; i < lo_pcnt; ++i) { + eth_lo->setReadAddress("127.0.0.1", lo_port + i); + if (eth_lo->open()) { + // piCout << "bind local to" << (lo_port + i); + break; + } + } + } + } +} + + +void PIBroadcast::send(const PIByteArray & data) { + if (!isRunning()) { + reinit(); + PIThread::start(3000); + } + PIByteArray cd = cryptData(data); + if (cd.isEmpty()) return; + PIMutexLocker ml(mcast_mutex); + piForeach(PIEthernet * e, eth_mcast) + e->send(cd); + if (eth_lo) { + for (int i = 0; i < lo_pcnt; ++i) { + eth_lo->send("127.0.0.1", lo_port + i, cd); + } + } +} + + +void PIBroadcast::startRead() { + if (!isRunning()) { + _started = false; + reinit(); + PIThread::start(3000); + } + if (_send_only) return; + PIMutexLocker ml(mcast_mutex); + piForeach(PIEthernet * e, eth_mcast) + e->startThreadedRead(); + if (eth_lo) eth_lo->startThreadedRead(); + _started = true; +} + + +void PIBroadcast::stopRead() { + if (isRunning()) stop(); + PIMutexLocker ml(mcast_mutex); + piForeach(PIEthernet * e, eth_mcast) + e->stopThreadedRead(); + if (eth_lo) eth_lo->stopThreadedRead(); + _started = false; +} + + +void PIBroadcast::reinit() { + initAll(PIEthernet::allAddresses()); + if (_started) startRead(); +} + + +void PIBroadcast::mcastRead(const uchar * data, ssize_t size) { + PIByteArray cd = decryptData(PIByteArray(data, size)); + if (cd.isEmpty()) return; + received(cd); + receiveEvent(cd); +} + + +void PIBroadcast::run() { + PIVector al = PIEthernet::allAddresses(); + mcast_mutex.lock(); + bool r = _reinit, ac = (al != prev_al); + mcast_mutex.unlock(); + if (ac || r) reinit(); + if (ac) addressesChanged(); +} diff --git a/libs/io_utils/piethutilbase.cpp b/libs/io_utils/piethutilbase.cpp index 38301e2c..5121239d 100644 --- a/libs/io_utils/piethutilbase.cpp +++ b/libs/io_utils/piethutilbase.cpp @@ -1,121 +1,120 @@ -/* - PIP - Platform Independent Primitives - Base class for ethernet utils - 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 . -*/ - -#include "piethutilbase.h" -#ifdef PIP_CRYPT -# include "picrypt.h" -#endif - -/** \class PIEthUtilBase - * \brief Base class for ethernet utils - * - * \section PIEthUtilBase_synopsis Synopsis - * %PIEthUtilBase provides crypt layer for derived classes: - * \a PIStreamPacker and \a PIBroadcast. All input and output - * (sended and received) data can be decrypted/encrypted by this layer. - * - * By default crypt layer is disabled. - * - * You can separetely enable it and set ready-to-use - * key by \a setCryptEnabled() and \a setCryptKey(). Or you can - * use \a createCryptKey() to generate key from your passphrase - * and automatic enable crypt layer. - * - * \note To use crypt layer, PIP should be built with crypt module, - * otherwise your in/out data will be lost. - * - * You can use this class as base for your own classes. Use \a cryptData() - * and \a decryptData() when send and receive your data. - * -*/ - - -PIEthUtilBase::PIEthUtilBase() { - _crypt = false; -} - - -PIEthUtilBase::~PIEthUtilBase() { -} - - -void PIEthUtilBase::setCryptEnabled(bool on) { - _crypt = on; -} - - -void PIEthUtilBase::cryptEnable() { - setCryptEnabled(true); -} - - -void PIEthUtilBase::cryptDisable() { - setCryptEnabled(false); -} - - -bool PIEthUtilBase::isCryptEnabled() const { - return _crypt; -} - - -void PIEthUtilBase::setCryptKey(const PIByteArray & k) { - _key = k; - setCryptEnabled(true); -} - - -void PIEthUtilBase::createCryptKey(const PIString & k) { -#ifdef PIP_CRYPT - _key = PICrypt::hash("sodium_bug"); - _key = PICrypt::hash(k); -#else - piCout << "[PIEthUtilBase] PICrypt wasn`t built!"; -#endif - _crypt = true; -} - - -PIByteArray PIEthUtilBase::cryptKey() const { - return _key; -} - - -PIByteArray PIEthUtilBase::cryptData(const PIByteArray & data) { - if (!_crypt) return data; - return -#ifdef PIP_CRYPT - PICrypt::crypt(data, _key); -#else - PIByteArray(); -#endif -} - - -PIByteArray PIEthUtilBase::decryptData(const PIByteArray & data) { - if (!_crypt) return data; -#ifdef PIP_CRYPT - bool ok = false; - PIByteArray ret = PICrypt::decrypt(data, _key, &ok); - if (!ok) return PIByteArray(); - return ret; -#else - return PIByteArray(); -#endif -} +/* + PIP - Platform Independent Primitives + Base class for ethernet utils + 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 . +*/ + +#include "piethutilbase.h" +#ifdef PIP_CRYPT +# include "picrypt.h" +#endif + +/** \class PIEthUtilBase + * \brief Base class for ethernet utils + * + * \section PIEthUtilBase_synopsis Synopsis + * %PIEthUtilBase provides crypt layer for derived classes: + * \a PIStreamPacker and \a PIBroadcast. All input and output + * (sended and received) data can be decrypted/encrypted by this layer. + * + * By default crypt layer is disabled. + * + * You can separetely enable it and set ready-to-use + * key by \a setCryptEnabled() and \a setCryptKey(). Or you can + * use \a createCryptKey() to generate key from your passphrase + * and automatic enable crypt layer. + * + * \note To use crypt layer, PIP should be built with crypt module, + * otherwise your in/out data will be lost. + * + * You can use this class as base for your own classes. Use \a cryptData() + * and \a decryptData() when send and receive your data. + * + */ + + +PIEthUtilBase::PIEthUtilBase() { + _crypt = false; +} + + +PIEthUtilBase::~PIEthUtilBase() {} + + +void PIEthUtilBase::setCryptEnabled(bool on) { + _crypt = on; +} + + +void PIEthUtilBase::cryptEnable() { + setCryptEnabled(true); +} + + +void PIEthUtilBase::cryptDisable() { + setCryptEnabled(false); +} + + +bool PIEthUtilBase::isCryptEnabled() const { + return _crypt; +} + + +void PIEthUtilBase::setCryptKey(const PIByteArray & k) { + _key = k; + setCryptEnabled(true); +} + + +void PIEthUtilBase::createCryptKey(const PIString & k) { +#ifdef PIP_CRYPT + _key = PICrypt::hash("sodium_bug"); + _key = PICrypt::hash(k); +#else + piCout << "[PIEthUtilBase] PICrypt wasn`t built!"; +#endif + _crypt = true; +} + + +PIByteArray PIEthUtilBase::cryptKey() const { + return _key; +} + + +PIByteArray PIEthUtilBase::cryptData(const PIByteArray & data) { + if (!_crypt) return data; + return +#ifdef PIP_CRYPT + PICrypt::crypt(data, _key); +#else + PIByteArray(); +#endif +} + + +PIByteArray PIEthUtilBase::decryptData(const PIByteArray & data) { + if (!_crypt) return data; +#ifdef PIP_CRYPT + bool ok = false; + PIByteArray ret = PICrypt::decrypt(data, _key, &ok); + if (!ok) return PIByteArray(); + return ret; +#else + return PIByteArray(); +#endif +} diff --git a/libs/io_utils/pistreampacker.cpp b/libs/io_utils/pistreampacker.cpp index 7a4473ef..579718fd 100644 --- a/libs/io_utils/pistreampacker.cpp +++ b/libs/io_utils/pistreampacker.cpp @@ -1,203 +1,215 @@ -/* - PIP - Platform Independent Primitives - Simple packet wrap aroud any PIIODevice - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . -*/ - -#ifdef __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wnonnull" -#endif -#include "pistreampacker.h" -#include "piiodevice.h" -#ifdef __GNUC__ -# pragma GCC diagnostic pop -#endif - -/** \class PIStreamPacker - * \brief Simple packet wrap aroud any PIIODevice - * - * \section PIStreamPacker_synopsis Synopsis - * %PIStreamPacker provides simple pack/unpack logic for any data packets. - * - * When you call \a send() function data splited into several - * parts, \a packetSign() prepended to first part and \a sendRequest() - * event raised several times. - * - * When your device receive some data, call \a received() function. - * \a packetReceiveEvent() event will be raised when packet will be - * collected. - * - * Use \a assignDevice() to connect device to this %PIStreamPacker. - * -*/ - - -PIStreamPacker::PIStreamPacker(PIIODevice * dev): PIObject() { - crypt_frag = crypt_size = false; - aggressive_optimization = true; - packet_size = -1; - size_crypted_size = sizeof(int); - crypt_frag_size = 1024*1024; - max_packet_size = 1400; - packet_sign = 0xAFBE; - assignDevice(dev); -} - - -void PIStreamPacker::setCryptSizeEnabled(bool on) { - crypt_size = on; - if (crypt_size) { - PIByteArray ba; ba << int(0); - size_crypted_size = cryptData(ba).size_s(); - } else - size_crypted_size = sizeof(int); -} - - -void PIStreamPacker::clear() { - packet.clear(); - packet_size = -1; - stream.clear(); -} - - -void PIStreamPacker::send(const PIByteArray & data) { - if (data.isEmpty()) return; - PIByteArray cd; - if (crypt_frag) { - int fcnt = (data.size_s() - 1) / crypt_frag_size + 1, fst = 0; - //piCout << "crypt_frag send" << fcnt << "frags"; - PIByteArray frag; - for (int i = 0; i < fcnt; ++i) { - if (i == fcnt - 1) frag = PIByteArray(data.data(fst), data.size_s() - fst); - else frag = PIByteArray(data.data(fst), crypt_frag_size); - fst += crypt_frag_size; - cd << cryptData(frag); - } - } else { - cd = cryptData(data); - } - //piCout << "crypt" << data.size() << "->" << cd.size() << key().size(); - PIByteArray hdr, part; - hdr << packet_sign; - if (crypt_size) { - PIByteArray crsz; crsz << int(cd.size_s()); - hdr.append(cryptData(crsz)); - } else - hdr << int(cd.size_s()); - cd.insert(0, hdr); - int pcnt = (cd.size_s() - 1) / max_packet_size + 1, pst = 0; - for (int i = 0; i < pcnt; ++i) { - if (i == pcnt - 1) part = PIByteArray(cd.data(pst), cd.size_s() - pst); - else part = PIByteArray(cd.data(pst), max_packet_size); - //piCout << "send" << part.size(); - sendRequest(part); - pst += max_packet_size; - } -} - - -void PIStreamPacker::received(const uchar * readed, ssize_t size) { - received(PIByteArray(readed, size)); -} - - -void PIStreamPacker::received(const PIByteArray & data) { - stream.append(data); - //piCout << "rec" << data.size(); - while (!stream.isEmpty()) { - int hdr_size = sizeof(packet_sign) + size_crypted_size; - if (packet_size < 0) { - if (stream.size_s() < hdr_size) return; - ushort sign(0); - memcpy(&sign, stream.data(), 2); - if (sign != packet_sign) { - if (aggressive_optimization) stream.clear(); - else stream.pop_front(); - continue; - } - int sz = -1; - if (crypt_size) { - PIByteArray crsz((uint)size_crypted_size); - memcpy(crsz.data(), stream.data(2), size_crypted_size); - crsz = decryptData(crsz); - if (crsz.size() < sizeof(sz)) { - if (aggressive_optimization) stream.clear(); - else stream.pop_front(); - continue; - } - crsz >> sz; - } else { - memcpy(&sz, stream.data(2), size_crypted_size); - } - if (sz < 0) { - if (aggressive_optimization) stream.clear(); - else stream.pop_front(); - continue; - } - stream.remove(0, hdr_size); - packet.clear(); - packet_size = sz; - if (packet_size == 0) - packet_size = -1; - continue; - } else { - int ps = piMini(stream.size_s(), packet_size - packet.size_s()); - packet.append(stream.data(), ps); - stream.remove(0, ps); - if (packet.size_s() == packet_size) { - PIByteArray cd; - if (crypt_frag) { - //piCout << "decrypt frags ..." << packet_size; - while (packet.size_s() >= 4) { - //piCout << "decrypt frags take data ..."; - PIByteArray frag; - //piCout << "decrypt frags take data done" << frag.size_s(); - packet >> frag; - if (frag.isEmpty()) { - //piCout << "decrypt frags corrupt, break"; - cd.clear(); - break; - } - cd.append(decryptData(frag)); - //piCout << "decrypt frags add" << frag.size_s(); - } - //piCout << "decrypt frags done" << cd.size(); - } else { - cd = decryptData(packet); - } - //piCout << "decrypt" << packet.size() << "->" << cd.size() << key().size(); - if (!cd.isEmpty()) { - packetReceived(cd); - packetReceiveEvent(cd); - } - packet.clear(); - packet_size = -1; - } - } - } -} - - -void PIStreamPacker::assignDevice(PIIODevice * dev) { - if (!dev) return; - if (!dev->infoFlags()[PIIODevice::Reliable]) { - piCoutObj << "Warning! Not recommended to use with non-reliable" << dev; - } - CONNECT2(void, const uchar *, ssize_t, dev, threadedReadEvent, this, received); - CONNECT1(void, PIByteArray, this, sendRequest, dev, write); -} +/* + PIP - Platform Independent Primitives + Simple packet wrap aroud any PIIODevice + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 . +*/ + +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wnonnull" +#endif +#include "pistreampacker.h" + +#include "piiodevice.h" +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + +/** \class PIStreamPacker + * \brief Simple packet wrap aroud any PIIODevice + * + * \section PIStreamPacker_synopsis Synopsis + * %PIStreamPacker provides simple pack/unpack logic for any data packets. + * + * When you call \a send() function data splited into several + * parts, \a packetSign() prepended to first part and \a sendRequest() + * event raised several times. + * + * When your device receive some data, call \a received() function. + * \a packetReceiveEvent() event will be raised when packet will be + * collected. + * + * Use \a assignDevice() to connect device to this %PIStreamPacker. + * + */ + + +PIStreamPacker::PIStreamPacker(PIIODevice * dev): PIObject() { + crypt_frag = crypt_size = false; + aggressive_optimization = true; + packet_size = -1; + size_crypted_size = sizeof(int); + crypt_frag_size = 1024 * 1024; + max_packet_size = 1400; + packet_sign = 0xAFBE; + assignDevice(dev); +} + + +void PIStreamPacker::setCryptSizeEnabled(bool on) { + crypt_size = on; + if (crypt_size) { + PIByteArray ba; + ba << int(0); + size_crypted_size = cryptData(ba).size_s(); + } else + size_crypted_size = sizeof(int); +} + + +void PIStreamPacker::clear() { + packet.clear(); + packet_size = -1; + stream.clear(); +} + + +void PIStreamPacker::send(const PIByteArray & data) { + if (data.isEmpty()) return; + PIByteArray cd; + if (crypt_frag) { + int fcnt = (data.size_s() - 1) / crypt_frag_size + 1, fst = 0; + // piCout << "crypt_frag send" << fcnt << "frags"; + PIByteArray frag; + for (int i = 0; i < fcnt; ++i) { + if (i == fcnt - 1) + frag = PIByteArray(data.data(fst), data.size_s() - fst); + else + frag = PIByteArray(data.data(fst), crypt_frag_size); + fst += crypt_frag_size; + cd << cryptData(frag); + } + } else { + cd = cryptData(data); + } + // piCout << "crypt" << data.size() << "->" << cd.size() << key().size(); + PIByteArray hdr, part; + hdr << packet_sign; + if (crypt_size) { + PIByteArray crsz; + crsz << int(cd.size_s()); + hdr.append(cryptData(crsz)); + } else + hdr << int(cd.size_s()); + cd.insert(0, hdr); + int pcnt = (cd.size_s() - 1) / max_packet_size + 1, pst = 0; + for (int i = 0; i < pcnt; ++i) { + if (i == pcnt - 1) + part = PIByteArray(cd.data(pst), cd.size_s() - pst); + else + part = PIByteArray(cd.data(pst), max_packet_size); + // piCout << "send" << part.size(); + sendRequest(part); + pst += max_packet_size; + } +} + + +void PIStreamPacker::received(const uchar * readed, ssize_t size) { + received(PIByteArray(readed, size)); +} + + +void PIStreamPacker::received(const PIByteArray & data) { + stream.append(data); + // piCout << "rec" << data.size(); + while (!stream.isEmpty()) { + int hdr_size = sizeof(packet_sign) + size_crypted_size; + if (packet_size < 0) { + if (stream.size_s() < hdr_size) return; + ushort sign(0); + memcpy(&sign, stream.data(), 2); + if (sign != packet_sign) { + if (aggressive_optimization) + stream.clear(); + else + stream.pop_front(); + continue; + } + int sz = -1; + if (crypt_size) { + PIByteArray crsz((uint)size_crypted_size); + memcpy(crsz.data(), stream.data(2), size_crypted_size); + crsz = decryptData(crsz); + if (crsz.size() < sizeof(sz)) { + if (aggressive_optimization) + stream.clear(); + else + stream.pop_front(); + continue; + } + crsz >> sz; + } else { + memcpy(&sz, stream.data(2), size_crypted_size); + } + if (sz < 0) { + if (aggressive_optimization) + stream.clear(); + else + stream.pop_front(); + continue; + } + stream.remove(0, hdr_size); + packet.clear(); + packet_size = sz; + if (packet_size == 0) packet_size = -1; + continue; + } else { + int ps = piMini(stream.size_s(), packet_size - packet.size_s()); + packet.append(stream.data(), ps); + stream.remove(0, ps); + if (packet.size_s() == packet_size) { + PIByteArray cd; + if (crypt_frag) { + // piCout << "decrypt frags ..." << packet_size; + while (packet.size_s() >= 4) { + // piCout << "decrypt frags take data ..."; + PIByteArray frag; + // piCout << "decrypt frags take data done" << frag.size_s(); + packet >> frag; + if (frag.isEmpty()) { + // piCout << "decrypt frags corrupt, break"; + cd.clear(); + break; + } + cd.append(decryptData(frag)); + // piCout << "decrypt frags add" << frag.size_s(); + } + // piCout << "decrypt frags done" << cd.size(); + } else { + cd = decryptData(packet); + } + // piCout << "decrypt" << packet.size() << "->" << cd.size() << key().size(); + if (!cd.isEmpty()) { + packetReceived(cd); + packetReceiveEvent(cd); + } + packet.clear(); + packet_size = -1; + } + } + } +} + + +void PIStreamPacker::assignDevice(PIIODevice * dev) { + if (!dev) return; + if (!dev->infoFlags()[PIIODevice::Reliable]) { + piCoutObj << "Warning! Not recommended to use with non-reliable" << dev; + } + CONNECT2(void, const uchar *, ssize_t, dev, threadedReadEvent, this, received); + CONNECT1(void, PIByteArray, this, sendRequest, dev, write); +} diff --git a/libs/lua/piluaprogram.cpp b/libs/lua/piluaprogram.cpp index 93603e86..2a09518b 100644 --- a/libs/lua/piluaprogram.cpp +++ b/libs/lua/piluaprogram.cpp @@ -1,20 +1,20 @@ /* - PIP - Platform Independent Primitives - PILuaProgram - Andrey Bychkov work.a.b@yandex.ru + PIP - Platform Independent Primitives + PILuaProgram + Andrey Bychkov work.a.b@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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include "piluaprogram.h" @@ -50,4 +50,3 @@ luabridge::LuaRef PILuaProgram::getGlobal(const PIString & name) { luabridge::Namespace PILuaProgram::getGlobalNamespace() { return luabridge::getGlobalNamespace(PRIVATE->lua_state); } - diff --git a/libs/main/cloud/picloudbase.h b/libs/main/cloud/picloudbase.h index 76262390..f6978bd2 100644 --- a/libs/main/cloud/picloudbase.h +++ b/libs/main/cloud/picloudbase.h @@ -5,22 +5,22 @@ * \~russian Базовый класс для PICloudClient и PICloudServer */ /* - PIP - Platform Independent Primitives - PICloud Base - Base class for PICloudClient and PICloud Server - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + PIP - Platform Independent Primitives + PICloud Base - Base class for PICloudClient and PICloud Server + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef PICLOUDBASE_H @@ -31,8 +31,7 @@ #include "pistreampacker.h" -class PIP_CLOUD_EXPORT PICloudBase -{ +class PIP_CLOUD_EXPORT PICloudBase { public: PICloudBase(); diff --git a/libs/main/cloud/picloudclient.h b/libs/main/cloud/picloudclient.h index e9217dd3..505ed027 100644 --- a/libs/main/cloud/picloudclient.h +++ b/libs/main/cloud/picloudclient.h @@ -5,22 +5,22 @@ * \~russian Клиент PICloud */ /* - PIP - Platform Independent Primitives - PICloud Client - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + PIP - Platform Independent Primitives + PICloud Client + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef PICLOUDCLIENT_H @@ -32,17 +32,19 @@ //! \brief PICloudClient -class PIP_CLOUD_EXPORT PICloudClient: public PIIODevice, public PICloudBase -{ +class PIP_CLOUD_EXPORT PICloudClient + : public PIIODevice + , public PICloudBase { PIIODEVICE(PICloudClient, ""); + public: explicit PICloudClient(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite); virtual ~PICloudClient(); void setServerName(const PIString & server_name); void setKeepConnection(bool on); - bool isConnected() const {return is_connected;} - ssize_t bytesAvailable() const override {return buff.size();} + bool isConnected() const { return is_connected; } + ssize_t bytesAvailable() const override { return buff.size(); } void interrupt() override; EVENT(connected); @@ -53,7 +55,7 @@ protected: bool closeDevice() override; ssize_t readDevice(void * read_to, ssize_t max_size) override; ssize_t writeDevice(const void * data, ssize_t size) override; - DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Reliable;} + DeviceInfoFlags deviceInfoFlags() const override { return PIIODevice::Reliable; } private: EVENT_HANDLER1(void, _readed, PIByteArray &, data); @@ -66,7 +68,6 @@ private: PIConditionVariable cond_connect; std::atomic_bool is_connected; std::atomic_bool is_deleted; - }; #endif // PICLOUDCLIENT_H diff --git a/libs/main/cloud/picloudmodule.h b/libs/main/cloud/picloudmodule.h index f54e20ca..e171c9e3 100644 --- a/libs/main/cloud/picloudmodule.h +++ b/libs/main/cloud/picloudmodule.h @@ -1,20 +1,20 @@ /* - PIP - Platform Independent Primitives - Module includes - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + PIP - Platform Independent Primitives + Module includes + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ //! \defgroup Cloud Cloud //! \~\brief @@ -51,8 +51,8 @@ #ifndef PICLOUDMODULE_H #define PICLOUDMODULE_H -#include "picloudtcp.h" #include "picloudclient.h" #include "picloudserver.h" +#include "picloudtcp.h" #endif // PICLOUDMODULE_H diff --git a/libs/main/cloud/picloudserver.h b/libs/main/cloud/picloudserver.h index 3a637b35..c41c36b6 100644 --- a/libs/main/cloud/picloudserver.h +++ b/libs/main/cloud/picloudserver.h @@ -5,22 +5,22 @@ * \~russian Сервер PICloud */ /* - PIP - Platform Independent Primitives - PICloud Server - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + PIP - Platform Independent Primitives + PICloud Server + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef PICLOUDSERVER_H @@ -30,27 +30,31 @@ #include "piconditionvar.h" -class PIP_CLOUD_EXPORT PICloudServer: public PIIODevice, public PICloudBase -{ +class PIP_CLOUD_EXPORT PICloudServer + : public PIIODevice + , public PICloudBase { PIIODEVICE(PICloudServer, ""); + public: //! PICloudServer explicit PICloudServer(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite); virtual ~PICloudServer(); - class Client : public PIIODevice { + class Client: public PIIODevice { PIIODEVICE(PICloudServer::Client, ""); friend class PICloudServer; + public: Client(PICloudServer * srv = nullptr, uint id = 0); virtual ~Client(); + protected: bool openDevice() override; bool closeDevice() override; ssize_t readDevice(void * read_to, ssize_t max_size) override; ssize_t writeDevice(const void * data, ssize_t size) override; - DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Reliable;} - ssize_t bytesAvailable() const override {return buff.size();} + DeviceInfoFlags deviceInfoFlags() const override { return PIIODevice::Reliable; } + ssize_t bytesAvailable() const override { return buff.size(); } void interrupt() override; private: @@ -67,7 +71,7 @@ public: PIVector clients() const; - EVENT1(newConnection, PICloudServer::Client * , client); + EVENT1(newConnection, PICloudServer::Client *, client); protected: bool openDevice() override; diff --git a/libs/main/cloud/picloudtcp.h b/libs/main/cloud/picloudtcp.h index decb0727..43756ec4 100644 --- a/libs/main/cloud/picloudtcp.h +++ b/libs/main/cloud/picloudtcp.h @@ -5,30 +5,30 @@ * \~russian TCP слой PICloud */ /* - PIP - Platform Independent Primitives - PICloud TCP transport - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + PIP - Platform Independent Primitives + PICloud TCP transport + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef PICLOUDTCP_H #define PICLOUDTCP_H +#include "pimutex.h" #include "pip_cloud_export.h" #include "pistring.h" -#include "pimutex.h" class PIEthernet; @@ -37,7 +37,6 @@ class PIStreamPacker; namespace PICloud { - class PIP_CLOUD_EXPORT TCP { public: enum Version { @@ -47,21 +46,21 @@ public: enum Role { InvalidRole = 0, - Server = 1, - Client = 2, + Server = 1, + Client = 2, }; enum Type { InvalidType = 0, - Connect = 1, - Disconnect = 2, - Data = 3, - Ping = 4, + Connect = 1, + Disconnect = 2, + Data = 3, + Ping = 4, }; TCP(PIStreamPacker * s); void setRole(Role r); - Role role() const {return (Role)header.role;} + Role role() const { return (Role)header.role; } void setServerName(const PIString & server_name_); PIString serverName() const; @@ -82,8 +81,8 @@ private: struct Header { Header(); uchar version; // PICloud::Version - uchar type; // PICloud::Type - uchar role; // PICloud::Role + uchar type; // PICloud::Type + uchar role; // PICloud::Role }; Header header; @@ -91,9 +90,8 @@ private: PIString server_name; PIStreamPacker * streampacker; PIMutex mutex_send; - }; -} +} // namespace PICloud #endif // PICLOUDTCP_H diff --git a/libs/main/code/picodeinfo.cpp b/libs/main/code/picodeinfo.cpp index 65932054..21ebceb9 100644 --- a/libs/main/code/picodeinfo.cpp +++ b/libs/main/code/picodeinfo.cpp @@ -1,52 +1,52 @@ /* - PIP - Platform Independent Primitives - C++ code info structs - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + C++ code info structs + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include "picodeinfo.h" + #include "pivariant.h" PIString PICodeInfo::EnumInfo::memberName(int value_) const { - piForeachC (PICodeInfo::EnumeratorInfo & e, members) - if (e.value == value_) - return e.name.toString(); + piForeachC(PICodeInfo::EnumeratorInfo & e, members) + if (e.value == value_) return e.name.toString(); return PIString(); } int PICodeInfo::EnumInfo::memberValue(const PIString & name_) const { - piForeachC (PICodeInfo::EnumeratorInfo & e, members) - if (e.name.toString() == name_) - return e.value; + piForeachC(PICodeInfo::EnumeratorInfo & e, members) + if (e.name.toString() == name_) return e.value; return -1; } PIVariantTypes::Enum PICodeInfo::EnumInfo::toPIVariantEnum() { PIVariantTypes::Enum en(name.toString()); - for (auto m: members) en << m.toPIVariantEnumerator(); + for (auto m: members) + en << m.toPIVariantEnumerator(); if (!en.isEmpty()) en.selectValue(members.front().value); return en; } -PIMap * PICodeInfo::classesInfo; -PIMap * PICodeInfo::enumsInfo; +PIMap * PICodeInfo::classesInfo; +PIMap * PICodeInfo::enumsInfo; PIMap * PICodeInfo::accessValueFunctions; PIMap * PICodeInfo::accessTypeFunctions; @@ -55,7 +55,7 @@ bool __PICodeInfoInitializer__::_inited_ = false; PIVariant PICodeInfo::getMemberAsVariant(const void * p, const char * class_name, const char * member_name) { if (!p || !class_name || !member_name || !accessTypeFunctions || !accessValueFunctions) return PIVariant(); - AccessTypeFunction atf = accessTypeFunctions->value(class_name, (AccessTypeFunction)0); + AccessTypeFunction atf = accessTypeFunctions->value(class_name, (AccessTypeFunction)0); AccessValueFunction avf = accessValueFunctions->value(class_name, (AccessValueFunction)0); if (!atf || !avf) return PIVariant(); return PIVariant::fromValue(avf(p, member_name), PIStringAscii(atf(member_name))); diff --git a/libs/main/code/picodeinfo.h b/libs/main/code/picodeinfo.h index 7153ba04..7e9e36d6 100644 --- a/libs/main/code/picodeinfo.h +++ b/libs/main/code/picodeinfo.h @@ -5,22 +5,22 @@ * \~russian Структуры для C++ кода. Подробнее \ref code_model. */ /* - PIP - Platform Independent Primitives - C++ code info structs - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + C++ code info structs + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ @@ -45,29 +45,34 @@ namespace PICodeInfo { //! Модификаторы типа enum TypeFlag { NoFlag, - Const /** const */ = 0x01, - Static /** static */ = 0x02, - Mutable /** mutable */ = 0x04, + Const /** const */ = 0x01, + Static /** static */ = 0x02, + Mutable /** mutable */ = 0x04, Volatile /** volatile */ = 0x08, - Inline /** inline */ = 0x10, - Virtual /** virtual */ = 0x20, - Extern /** extern */ = 0x40 + Inline /** inline */ = 0x10, + Virtual /** virtual */ = 0x20, + Extern /** extern */ = 0x40 }; typedef PIFlags TypeFlags; typedef PIMap MetaMap; -typedef PIByteArray(*AccessValueFunction)(const void *, const char *); -typedef const char*(*AccessTypeFunction)(const char *); +typedef PIByteArray (*AccessValueFunction)(const void *, const char *); +typedef const char * (*AccessTypeFunction)(const char *); //! \~english Type information //! \~russian Информация о типе struct PIP_EXPORT TypeInfo { - TypeInfo(const PIConstChars & n = PIConstChars(), const PIConstChars & t = PIConstChars(), PICodeInfo::TypeFlags f = 0, int b = -1) {name = n; type = t; flags = f; bits = b;} + TypeInfo(const PIConstChars & n = PIConstChars(), const PIConstChars & t = PIConstChars(), PICodeInfo::TypeFlags f = 0, int b = -1) { + name = n; + type = t; + flags = f; + bits = b; + } //! \~english Returns if variable if bitfield //! \~russian Возвращает битовым ли полем является переменная - bool isBitfield() const {return bits > 0;} + bool isBitfield() const { return bits > 0; } //! \~english Custom PIMETA content //! \~russian Произвольное содержимое PIMETA @@ -94,7 +99,6 @@ struct PIP_EXPORT TypeInfo { //! \~english Method information //! \~russian Информация о методе struct PIP_EXPORT FunctionInfo { - //! \~english Custom PIMETA content //! \~russian Произвольное содержимое PIMETA MetaMap meta; @@ -116,7 +120,7 @@ struct PIP_EXPORT FunctionInfo { //! \~english Class or struct information //! \~russian Информация о классе или структуре struct PIP_EXPORT ClassInfo { - ClassInfo() {has_name = true;} + ClassInfo() { has_name = true; } //! \~english Custom PIMETA content //! \~russian Произвольное содержимое PIMETA @@ -148,15 +152,18 @@ struct PIP_EXPORT ClassInfo { //! \~english Subclass list //! \~russian Список наследников - PIVector children_info; + PIVector children_info; }; //! \~english Enumerator information //! \~russian Информация об элементе перечисления struct PIP_EXPORT EnumeratorInfo { - EnumeratorInfo(const PIConstChars & n = PIConstChars(), int v = 0) {name = n; value = v;} - PIVariantTypes::Enumerator toPIVariantEnumerator() {return PIVariantTypes::Enumerator(value, name.toString());} + EnumeratorInfo(const PIConstChars & n = PIConstChars(), int v = 0) { + name = n; + value = v; + } + PIVariantTypes::Enumerator toPIVariantEnumerator() { return PIVariantTypes::Enumerator(value, name.toString()); } //! \~english Custom PIMETA content //! \~russian Произвольное содержимое PIMETA @@ -175,7 +182,6 @@ struct PIP_EXPORT EnumeratorInfo { //! \~english Enum information //! \~russian Информация о перечислении struct PIP_EXPORT EnumInfo { - //! \~english Returns member name with value "value" //! \~russian Возвращает имя элемента со значением "value" PIString memberName(int value) const; @@ -202,7 +208,7 @@ struct PIP_EXPORT EnumInfo { }; -inline PICout operator <<(PICout s, const PICodeInfo::TypeInfo & v) { +inline PICout operator<<(PICout s, const PICodeInfo::TypeInfo & v) { if (v.flags[Inline]) s << "inline "; if (v.flags[Virtual]) s << "virtual "; if (v.flags[Mutable]) s << "mutable "; @@ -210,22 +216,26 @@ inline PICout operator <<(PICout s, const PICodeInfo::TypeInfo & v) { if (v.flags[Static]) s << "static "; if (v.flags[Const]) s << "const "; s << v.type; - if (!v.name.isEmpty()) - s << " " << v.name; + if (!v.name.isEmpty()) s << " " << v.name; return s; } -inline PICout operator <<(PICout s, const PICodeInfo::EnumeratorInfo & v) {s << v.name << " = " << v.value << " Meta" << v.meta; return s;} +inline PICout operator<<(PICout s, const PICodeInfo::EnumeratorInfo & v) { + s << v.name << " = " << v.value << " Meta" << v.meta; + return s; +} -inline PICout operator <<(PICout s, const PICodeInfo::ClassInfo & v) { +inline PICout operator<<(PICout s, const PICodeInfo::ClassInfo & v) { s.saveAndSetControls(0); s << "class " << v.name; if (!v.parents.isEmpty()) { s << ": "; bool first = true; for (const auto & i: v.parents) { - if (first) first = false; - else s << ", "; + if (first) + first = false; + else + s << ", "; s << i; } } @@ -234,14 +244,15 @@ inline PICout operator <<(PICout s, const PICodeInfo::ClassInfo & v) { s << PICoutManipulators::Tab << i.return_type << " " << i.name << "("; bool fa = true; for (const auto & a: i.arguments) { - if (fa) fa = false; - else s << ", "; + if (fa) + fa = false; + else + s << ", "; s << a; } s << ") Meta" << i.meta << ";\n"; } - if (!v.functions.isEmpty() && !v.variables.isEmpty()) - s << "\n"; + if (!v.functions.isEmpty() && !v.variables.isEmpty()) s << "\n"; for (const auto & i: v.variables) { s << PICoutManipulators::Tab << i << " Meta" << i.meta << ";\n"; } @@ -250,13 +261,15 @@ inline PICout operator <<(PICout s, const PICodeInfo::ClassInfo & v) { return s; } -inline PICout operator <<(PICout s, const PICodeInfo::EnumInfo & v) { +inline PICout operator<<(PICout s, const PICodeInfo::EnumInfo & v) { s.saveAndSetControls(0); s << "enum " << v.name << " Meta" << v.meta << " {\n"; for (const auto & i: v.members) { bool f = true; - if (f) f = false; - else s << ", "; + if (f) + f = false; + else + s << ", "; s << PICoutManipulators::Tab << i << "\n"; } s << "}\n"; @@ -267,11 +280,11 @@ inline PICout operator <<(PICout s, const PICodeInfo::EnumInfo & v) { //! \~english Pointer to single storage of PICodeInfo::ClassInfo, access by name //! \~russian Указатель на единое хренилище PICodeInfo::ClassInfo, доступ по имени -extern PIP_EXPORT PIMap * classesInfo; +extern PIP_EXPORT PIMap * classesInfo; //! \~english Pointer to single storage of PICodeInfo::EnumInfo, access by name //! \~russian Указатель на единое хренилище PICodeInfo::EnumInfo, доступ по имени -extern PIP_EXPORT PIMap * enumsInfo; +extern PIP_EXPORT PIMap * enumsInfo; extern PIP_EXPORT PIMap * accessValueFunctions; @@ -294,23 +307,25 @@ inline const char * getMemberType(const char * class_name, const char * member_n PIP_EXPORT PIVariant getMemberAsVariant(const void * p, const char * class_name, const char * member_name); -template::value, int>::type = 0> -void serialize(PIByteArray & ret, const T & v) {ret << v;} +template::value, int>::type = 0> +void serialize(PIByteArray & ret, const T & v) { + ret << v; +} -template::value, int>::type = 0> +template::value, int>::type = 0> void serialize(PIByteArray & ret, const T & v) {} -} +} // namespace PICodeInfo class PIP_EXPORT __PICodeInfoInitializer__ { public: __PICodeInfoInitializer__() { if (_inited_) return; - _inited_ = true; - PICodeInfo::classesInfo = new PIMap; - PICodeInfo::enumsInfo = new PIMap; + _inited_ = true; + PICodeInfo::classesInfo = new PIMap; + PICodeInfo::enumsInfo = new PIMap; PICodeInfo::accessValueFunctions = new PIMap; - PICodeInfo::accessTypeFunctions = new PIMap; + PICodeInfo::accessTypeFunctions = new PIMap; } static bool _inited_; }; diff --git a/libs/main/code/picodemodule.h b/libs/main/code/picodemodule.h index 207d3310..6fc20f44 100644 --- a/libs/main/code/picodemodule.h +++ b/libs/main/code/picodemodule.h @@ -1,20 +1,20 @@ /* - PIP - Platform Independent Primitives - Module includes - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Module includes + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ //! \defgroup Code Code //! \~\brief diff --git a/libs/main/code/picodeparser.cpp b/libs/main/code/picodeparser.cpp index 63855cd0..c0f98f55 100644 --- a/libs/main/code/picodeparser.cpp +++ b/libs/main/code/picodeparser.cpp @@ -1,26 +1,25 @@ /* - PIP - Platform Independent Primitives - C++ code parser - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + C++ code parser + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include "picodeparser.h" - PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const { PIStringList arg_vals; while (!args_.isEmpty()) { @@ -32,29 +31,32 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const { PIString ca; if (bi >= 0 && bi < ci) { ca = args_.left(args_.takeLeft(bi).toInt()); - ci -= ca.size_s(); bi -= ca.size_s(); + ci -= ca.size_s(); + bi -= ca.size_s(); ca += '(' + args_.takeRange('(', ')') + ')'; } else { ca = args_.takeLeft(ci); } arg_vals << ca; - args_.trim(); args_.takeLeft(1); args_.trim(); + args_.trim(); + args_.takeLeft(1); + args_.trim(); } if (args.size() != arg_vals.size()) { - piCout << ("Error: in expansion of macro \"" + name + '(' + args.join(", ") + ")\": expect") - << args.size() << "arguments but takes" << arg_vals.size() << "!"; + piCout << ("Error: in expansion of macro \"" + name + '(' + args.join(", ") + ")\": expect") << args.size() << "arguments but takes" + << arg_vals.size() << "!"; if (ok != 0) *ok = false; return PIString(); } PIString ret = value; for (int i = 0; i < args.size_s(); ++i) { - const PIString & an(args[i]), av(arg_vals[i]); + const PIString &an(args[i]), av(arg_vals[i]); int ind(-1); while ((ind = ret.find(an, ind + 1)) >= 0) { PIChar ppc, pc, nc; if (ind > 1) ppc = ret[ind - 2]; if (ind > 0) pc = ret[ind - 1]; - if (ind + an.size_s() < ret.size_s()) nc = ret.mid(ind + an.size_s(),1)[0]; + if (ind + an.size_s() < ret.size_s()) nc = ret.mid(ind + an.size_s(), 1)[0]; if (ppc != '#' && pc == '#' && !_isCChar(nc)) { // to chars ind--; ret.replace(ind, an.size_s() + 1, '\"' + av + '\"'); @@ -72,9 +74,8 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const { } - PICodeParser::PICodeParser() { - macros_iter = 32; + macros_iter = 32; with_includes = true; clear(); includes << ""; @@ -86,62 +87,61 @@ void PICodeParser::parseFile(const PIString & file, bool follow_includes) { parseFileInternal(file, follow_includes); /*piCout << "\n\n"; piForeachC (Entity * c, entities) { - piCout << ""; - piCout << c->type << c->name << c->parent_scope << c->parents << c->children << c->meta; - if (c->parent_scope) - piCout << "parent" << c->parent_scope->name; - piCout << "Functions:"; - piForeachC (Member & m, c->functions) - piCout << m.type << m.name << m.meta; - piCout << "Members:"; - piForeachC (Member & m, c->members) - piCout << m.type << m.name << m.meta; + piCout << ""; + piCout << c->type << c->name << c->parent_scope << c->parents << c->children << c->meta; + if (c->parent_scope) + piCout << "parent" << c->parent_scope->name; + piCout << "Functions:"; + piForeachC (Member & m, c->functions) + piCout << m.type << m.name << m.meta; + piCout << "Members:"; + piForeachC (Member & m, c->members) + piCout << m.type << m.name << m.meta; } piCout << "\n\nDefines:"; piForeachC (Define & m, defines) - piCout << PIStringAscii("define") << m.first << m.second; + piCout << PIStringAscii("define") << m.first << m.second; piCout << "\n\nMacros:"; piForeachC (Macro & m, macros) - piCout << "Macro:" << m.name << m.args << m.value; + piCout << "Macro:" << m.name << m.args << m.value; piCout << "\n\nClasses:"; piCout << "\n\nEnums:"; piForeachC (Enum & c, enums) { - piCout << PIStringAscii("enum") << c.name << c.meta; - piForeachC (EnumeratorInfo & e, c.members) - piCout << " " << e.name << '=' << e.value << e.meta; + piCout << PIStringAscii("enum") << c.name << c.meta; + piForeachC (EnumeratorInfo & e, c.members) + piCout << " " << e.name << '=' << e.value << e.meta; } piCout << "\n\nTypedefs:"; piForeachC (Typedef & c, typedefs) - piCout << PIStringAscii("typedef") << c;*/ + piCout << PIStringAscii("typedef") << c;*/ } void PICodeParser::parseFiles(const PIStringList & files, bool follow_includes) { clear(); - piForeachC (PIString & f, files) + piForeachC(PIString & f, files) parseFileInternal(f, follow_includes); /*piCout << "\n\nDefines:"; piForeachC (Define & m, defines) - piCout << PIStringAscii("define") << m.first << m.second; + piCout << PIStringAscii("define") << m.first << m.second; piCout << "\n\nMacros:"; piForeachC (Macro & m, macros) - piCout << "Macro:" << m.name << m.args << m.value; + piCout << "Macro:" << m.name << m.args << m.value; piCout << "\n\nClasses:"; piForeachC (Entity * c, entities) - piCout << PIStringAscii("class") << c->name << c->parents; + piCout << PIStringAscii("class") << c->name << c->parents; piCout << "\n\nEnums:"; piForeachC (Enum & c, enums) - piCout << PIStringAscii("enum") << c.name << c.members; + piCout << PIStringAscii("enum") << c.name << c.members; piCout << "\n\nTypedefs:"; piForeachC (Typedef & c, typedefs) - piCout << PIStringAscii("typedef") << c;*/ + piCout << PIStringAscii("typedef") << c;*/ } bool PICodeParser::isEnum(const PIString & name) { - piForeachC (Enum & e, enums) - if (e.name == name) - return true; + piForeachC(Enum & e, enums) + if (e.name == name) return true; return false; } @@ -149,19 +149,19 @@ bool PICodeParser::isEnum(const PIString & name) { bool PICodeParser::parseFileInternal(const PIString & file, bool follow_includes) { if (proc_files[file]) return true; with_includes = follow_includes; - cur_file = file; + cur_file = file; PIFile f(file, PIIODevice::ReadOnly); int ii = 0; while (!f.isOpened() && ii < (includes.size_s() - 1)) { f.setPath(includes[++ii] + '/' + file); - //piCout << "try" << f.path(); + // piCout << "try" << f.path(); f.open(PIIODevice::ReadOnly); } if (!f.isOpened()) { piCout << ("Error: can`t open file \"" + file + "\"!"); return false; } - //piCout << "add" << file; + // piCout << "add" << file; proc_files << f.path(); PIString fc = PIString::fromUTF8(f.readAll()); piCout << "parsing" << f.path() << "..."; @@ -174,7 +174,8 @@ bool PICodeParser::parseFileInternal(const PIString & file, bool follow_includes void PICodeParser::clear() { - piForeach (Entity * i, entities) delete i; + piForeach(Entity * i, entities) + delete i; defines.clear(); macros.clear(); enums.clear(); @@ -184,40 +185,145 @@ void PICodeParser::clear() { cur_namespace.clear(); main_file.clear(); evaluator.clearCustomVariables(); - cur_def_vis = Global; - anon_num = 0; + cur_def_vis = Global; + anon_num = 0; PIStringList defs = PIStringAscii(PICODE_DEFINES).split(","); - piForeachC (PIString & d, defs) + piForeachC(PIString & d, defs) defines << Define(d, ""); defines << Define(PIStringAscii("PICODE"), "") << custom_defines; macros << Macro(PIStringAscii("PIOBJECT"), "", PIStringList() << "name") << Macro(PIStringAscii("PIOBJECT_PARENT"), "", PIStringList() << "parent") - << Macro(PIStringAscii("PIOBJECT_SUBCLASS"), "", PIStringList() << "name" << "parent") + << Macro(PIStringAscii("PIOBJECT_SUBCLASS"), + "", + PIStringList() << "name" + << "parent") << Macro(PIStringAscii("PIIODEVICE"), "", PIStringList() << "name") - << Macro(PIStringAscii("NO_COPY_CLASS"), "", PIStringList() << "name") - << Macro(PIStringAscii("PRIVATE_DECLARATION")) + << Macro(PIStringAscii("NO_COPY_CLASS"), "", PIStringList() << "name") << Macro(PIStringAscii("PRIVATE_DECLARATION")) - << Macro(PIStringAscii("EVENT" ), "void name();", PIStringList() << "name") + << Macro(PIStringAscii("EVENT"), "void name();", PIStringList() << "name") << Macro(PIStringAscii("EVENT0"), "void name();", PIStringList() << "name") - << Macro(PIStringAscii("EVENT1"), "void name(a0 n0);", PIStringList() << "name" << "a0" << "n0") - << Macro(PIStringAscii("EVENT2"), "void name(a0 n0, a1 n1);", PIStringList() << "name" << "a0" << "n0" << "a1" << "n1") - << Macro(PIStringAscii("EVENT3"), "void name(a0 n0, a1 n1, a2 n2);", PIStringList() << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2") - << Macro(PIStringAscii("EVENT4"), "void name(a0 n0, a1 n1, a2 n2, a3 n3);", PIStringList() << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2" << "a3" << "n3") + << Macro(PIStringAscii("EVENT1"), + "void name(a0 n0);", + PIStringList() << "name" + << "a0" + << "n0") + << Macro(PIStringAscii("EVENT2"), + "void name(a0 n0, a1 n1);", + PIStringList() << "name" + << "a0" + << "n0" + << "a1" + << "n1") + << Macro(PIStringAscii("EVENT3"), + "void name(a0 n0, a1 n1, a2 n2);", + PIStringList() << "name" + << "a0" + << "n0" + << "a1" + << "n1" + << "a2" + << "n2") + << Macro(PIStringAscii("EVENT4"), + "void name(a0 n0, a1 n1, a2 n2, a3 n3);", + PIStringList() << "name" + << "a0" + << "n0" + << "a1" + << "n1" + << "a2" + << "n2" + << "a3" + << "n3") - << Macro(PIStringAscii("EVENT_HANDLER" ), "ret name()", PIStringList() << "ret" << "name") - << Macro(PIStringAscii("EVENT_HANDLER0"), "ret name()", PIStringList() << "ret" << "name") - << Macro(PIStringAscii("EVENT_HANDLER1"), "ret name(a0 n0)", PIStringList() << "ret" << "name" << "a0" << "n0") - << Macro(PIStringAscii("EVENT_HANDLER2"), "ret name(a0 n0, a1 n1)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1") - << Macro(PIStringAscii("EVENT_HANDLER3"), "ret name(a0 n0, a1 n1, a2 n2)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2") - << Macro(PIStringAscii("EVENT_HANDLER4"), "ret name(a0 n0, a1 n1, a2 n2, a3 n3)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2" << "a3" << "n3") + << Macro(PIStringAscii("EVENT_HANDLER"), + "ret name()", + PIStringList() << "ret" + << "name") + << Macro(PIStringAscii("EVENT_HANDLER0"), + "ret name()", + PIStringList() << "ret" + << "name") + << Macro(PIStringAscii("EVENT_HANDLER1"), + "ret name(a0 n0)", + PIStringList() << "ret" + << "name" + << "a0" + << "n0") + << Macro(PIStringAscii("EVENT_HANDLER2"), + "ret name(a0 n0, a1 n1)", + PIStringList() << "ret" + << "name" + << "a0" + << "n0" + << "a1" + << "n1") + << Macro(PIStringAscii("EVENT_HANDLER3"), + "ret name(a0 n0, a1 n1, a2 n2)", + PIStringList() << "ret" + << "name" + << "a0" + << "n0" + << "a1" + << "n1" + << "a2" + << "n2") + << Macro(PIStringAscii("EVENT_HANDLER4"), + "ret name(a0 n0, a1 n1, a2 n2, a3 n3)", + PIStringList() << "ret" + << "name" + << "a0" + << "n0" + << "a1" + << "n1" + << "a2" + << "n2" + << "a3" + << "n3") - << Macro(PIStringAscii("EVENT_VHANDLER" ), "virtual ret name()", PIStringList() << "ret" << "name") - << Macro(PIStringAscii("EVENT_VHANDLER0"), "virtual ret name()", PIStringList() << "ret" << "name") - << Macro(PIStringAscii("EVENT_VHANDLER1"), "virtual ret name(a0 n0)", PIStringList() << "ret" << "name" << "a0" << "n0") - << Macro(PIStringAscii("EVENT_VHANDLER2"), "virtual ret name(a0 n0, a1 n1)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1") - << Macro(PIStringAscii("EVENT_VHANDLER3"), "virtual ret name(a0 n0, a1 n1, a2 n2)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2") - << Macro(PIStringAscii("EVENT_VHANDLER4"), "virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2" << "a3" << "n3") - ; + << Macro(PIStringAscii("EVENT_VHANDLER"), + "virtual ret name()", + PIStringList() << "ret" + << "name") + << Macro(PIStringAscii("EVENT_VHANDLER0"), + "virtual ret name()", + PIStringList() << "ret" + << "name") + << Macro(PIStringAscii("EVENT_VHANDLER1"), + "virtual ret name(a0 n0)", + PIStringList() << "ret" + << "name" + << "a0" + << "n0") + << Macro(PIStringAscii("EVENT_VHANDLER2"), + "virtual ret name(a0 n0, a1 n1)", + PIStringList() << "ret" + << "name" + << "a0" + << "n0" + << "a1" + << "n1") + << Macro(PIStringAscii("EVENT_VHANDLER3"), + "virtual ret name(a0 n0, a1 n1, a2 n2)", + PIStringList() << "ret" + << "name" + << "a0" + << "n0" + << "a1" + << "n1" + << "a2" + << "n2") + << Macro(PIStringAscii("EVENT_VHANDLER4"), + "virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)", + PIStringList() << "ret" + << "name" + << "a0" + << "n0" + << "a1" + << "n1" + << "a2" + << "n2" + << "a3" + << "n3"); } @@ -238,7 +344,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { char c = 0, pc = 0; PIString pfc, line, ccmn, tmp; PIMap cchars; - + /// Remove comments, join multiline '*' and replace '*' to $n (cchars) fc.replaceAll("\r\n", '\n'); fc.replaceAll('\r', '\n'); @@ -247,7 +353,8 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { if (i > 0) pc = c; c = fc[i].toAscii(); if (c == '"' && !mlc && pc != '\'') { - if (i > 0) if (fc[i - 1] == '\\') continue; + if (i > 0) + if (fc[i - 1] == '\\') continue; cc = !cc; continue; } @@ -258,46 +365,62 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { continue; } if (cc) continue; - if (fc.mid(i, 2) == "/*") {mlc = true; mls = i; ++i; continue;} - if (fc.mid(i, 2) == "*/" && mlc) {mlc = false; fc.cutMid(mls, i - mls + 2); i = mls - 1; continue;} - if (fc.mid(i, 2) == "//" && !mlc) {ole = fc.find('\n', i); fc.cutMid(i, ole < 0 ? -1 : ole - i); --i; continue;} + if (fc.mid(i, 2) == "/*") { + mlc = true; + mls = i; + ++i; + continue; + } + if (fc.mid(i, 2) == "*/" && mlc) { + mlc = false; + fc.cutMid(mls, i - mls + 2); + i = mls - 1; + continue; + } + if (fc.mid(i, 2) == "//" && !mlc) { + ole = fc.find('\n', i); + fc.cutMid(i, ole < 0 ? -1 : ole - i); + --i; + continue; + } } pfc = procMacros(fc); - + if (main) return true; - - bool replaced = true; + + bool replaced = true; int replaced_cnt = 0; while (replaced) { - //piCout << "MACRO iter" << replaced_cnt; + // piCout << "MACRO iter" << replaced_cnt; if (replaced_cnt >= macros_iter) { piCout << "Error: recursive macros detected!"; - break;//return false; + break; // return false; } replaced_cnt++; replaced = false; - piForeachC (Define & d, defines) { + piForeachC(Define & d, defines) { int ind(-1); while ((ind = pfc.find(d.first, ind + 1)) >= 0) { PIChar pc, nc; if (ind > 0) pc = pfc[ind - 1]; - if (ind + d.first.size_s() < pfc.size_s()) nc = pfc.mid(ind + d.first.size_s(),1)[0]; + if (ind + d.first.size_s() < pfc.size_s()) nc = pfc.mid(ind + d.first.size_s(), 1)[0]; if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue; pfc.replace(ind, d.first.size_s(), d.second); ind -= d.first.size_s() - d.second.size_s(); replaced = true; } } - piForeachC (Macro & m, macros) { + piForeachC(Macro & m, macros) { int ind(-1); while ((ind = pfc.find(m.name, ind + 1)) >= 0) { PIChar pc, nc; if (ind > 0) pc = pfc[ind - 1]; - if (ind + m.name.size_s() < pfc.size_s()) nc = pfc.mid(ind + m.name.size_s(),1)[0]; + if (ind + m.name.size_s() < pfc.size_s()) nc = pfc.mid(ind + m.name.size_s(), 1)[0]; if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue; - PIString ret, range; bool ok(false); + PIString ret, range; + bool ok(false); range = pfc.mid(ind + m.name.size_s()).takeRange('(', ')'); - ret = m.expand(range, &ok); + ret = m.expand(range, &ok); if (!ok) return false; int rlen = pfc.find(range, ind + m.name.size_s()) + range.size_s() + 1 - ind; pfc.replace(ind, rlen, ret); @@ -308,9 +431,9 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { } replaceMeta(pfc); - - //piCout << PICoutManipulators::NewLine << "file" << cur_file << pfc; - int pl = -1; + + // piCout << PICoutManipulators::NewLine << "file" << cur_file << pfc; + int pl = -1; cur_def_vis = Global; while (!pfc.isEmpty()) { pfc.trim(); @@ -331,14 +454,22 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { pfc.takeRange('<', '>'); bool def = !isDeclaration(pfc, 0, &end); pfc.cutLeft(end); - if (def) pfc.takeRange('{', '}'); - else pfc.takeSymbol(); + if (def) + pfc.takeRange('{', '}'); + else + pfc.takeSymbol(); continue; } if (pfc.left(5) == s_class || pfc.left(6) == s_struct || pfc.left(5) == s_union) { int dind = pfc.find('{', 0), find = pfc.find(';', 0); - if (dind < 0 && find < 0) {pfc.cutLeft(6); continue;} - if (dind < 0 || find < dind) {pfc.cutLeft(6); continue;} + if (dind < 0 && find < 0) { + pfc.cutLeft(6); + continue; + } + if (dind < 0 || find < dind) { + pfc.cutLeft(6); + continue; + } ccmn = pfc.left(dind) + s_bo + pfc.mid(dind).takeRange('{', '}') + s_bc; pfc.remove(0, ccmn.size()); parseClass(0, ccmn, false); @@ -356,8 +487,10 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { if (pfc.left(7) == s_typedef) { pfc.cutLeft(7); typedefs << parseTypedef(pfc.takeLeft(pfc.find(';'))); - if (typedefs.back().first.isEmpty()) typedefs.pop_back(); - else root_.typedefs << typedefs.back(); + if (typedefs.back().first.isEmpty()) + typedefs.pop_back(); + else + root_.typedefs << typedefs.back(); pfc.takeSymbol(); continue; } @@ -375,7 +508,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { } parseMember(&root_, str); } - + return true; } @@ -384,45 +517,49 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) static const PIString s_ss = PIStringAscii(" "); static const PIString s_M = PIStringAscii("$M"); static const PIString s_class = PIStringAscii("class"); - PIString cd = fc.trimmed().removeAll('\n').replaceAll('\t', ' ').replaceAll(s_ss, ' '), pn; + PIString cd = fc.trimmed().removeAll('\n').replaceAll('\t', ' ').replaceAll(s_ss, ' '), pn; MetaMap meta; int ind = cd.find(s_M); if (ind >= 0) { meta = tmp_meta.value(cd.takeMid(ind, 5)); cd.replaceAll(s_ss, ' '); } - //piCout << "found class <****\n" << cd << "\n****>"; + // piCout << "found class <****\n" << cd << "\n****>"; ind = cd.find(':'); - PIVector parents; + PIVector parents; if (ind > 0) { PIStringList pl = cd.takeMid(ind + 1).trim().split(','); cd.cutRight(1); Entity * pe = 0; - piForeachC (PIString & p, pl) { - if (p.contains(' ')) pn = p.mid(p.find(' ') + 1); - else pn = p; + piForeachC(PIString & p, pl) { + if (p.contains(' ')) + pn = p.mid(p.find(' ') + 1); + else + pn = p; pe = findEntityByName(pn); - if (pe == 0) ;//{piCout << "Error: can`t find" << pn;} - else parents << pe; + if (pe == 0) + ; //{piCout << "Error: can`t find" << pn;} + else + parents << pe; } } PIString typename_ = cd.left(6).trim(); - bool is_class = typename_ == s_class; - Visibility vis = cur_def_vis; - cur_def_vis = (is_class ? Private : Public); - PIString cn = cd.mid(6).trim(); - bool has_name = !cn.isEmpty(); + bool is_class = typename_ == s_class; + Visibility vis = cur_def_vis; + cur_def_vis = (is_class ? Private : Public); + PIString cn = cd.mid(6).trim(); + bool has_name = !cn.isEmpty(); if (cn.isEmpty()) cn = PIStringAscii("'; - //piCout << "found " << typename_ << cn; + // piCout << "found " << typename_ << cn; if (cn.isEmpty()) return 0; - Entity * e = new Entity(); - e->meta = meta; - e->name = cur_namespace + cn; - e->type = typename_; - e->has_name = has_name; - e->parents = parents; + Entity * e = new Entity(); + e->meta = meta; + e->name = cur_namespace + cn; + e->type = typename_; + e->has_name = has_name; + e->parents = parents; e->visibility = vis; - e->file = cur_file; + e->file = cur_file; entities << e; return e; } @@ -441,37 +578,49 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) static const PIString s_typedef = PIStringAscii("typedef"); static const PIString s_namespace = PIStringAscii("namespace"); static const PIString s_template = PIStringAscii("template"); - Visibility prev_vis = cur_def_vis; + Visibility prev_vis = cur_def_vis; int dind = fc.find('{'), find = fc.find(';'), end = 0; if (dind < 0 && find < 0) return; if (dind < 0 || find < dind) { fc.left(find); return; } - //piCout << "parse class <****\n" << fc << "\n****>"; + // piCout << "parse class <****\n" << fc << "\n****>"; Entity * ce = parent; if (!is_namespace) { ce = parseClassDeclaration(fc.takeLeft(dind)); fc.trim().cutLeft(1).cutRight(1).trim(); } - //piCout << "found class <****\n" << fc << "\n****>"; - ///if (!ce) return PIString(); + // piCout << "found class <****\n" << fc << "\n****>"; + /// if (!ce) return PIString(); if (ce) { if (parent) parent->children << ce; ce->parent_scope = parent; } - int ps = -1; - bool def = false; + int ps = -1; + bool def = false; PIString prev_namespace = cur_namespace, stmp; if (ce) cur_namespace += ce->name + s_ns; - //piCout << "parse class" << ce->name << "namespace" << cur_namespace; - //piCout << "\nparse class" << ce->name << "namespace" << cur_namespace; + // piCout << "parse class" << ce->name << "namespace" << cur_namespace; + // piCout << "\nparse class" << ce->name << "namespace" << cur_namespace; while (!fc.isEmpty()) { PIString cw = fc.takeCWord(), tmp; - //piCout << "\ntaked word" << cw; - if (cw == s_public ) {cur_def_vis = Public; fc.cutLeft(1); continue;} - if (cw == s_protected) {cur_def_vis = Protected; fc.cutLeft(1); continue;} - if (cw == s_private ) {cur_def_vis = Private; fc.cutLeft(1); continue;} + // piCout << "\ntaked word" << cw; + if (cw == s_public) { + cur_def_vis = Public; + fc.cutLeft(1); + continue; + } + if (cw == s_protected) { + cur_def_vis = Protected; + fc.cutLeft(1); + continue; + } + if (cw == s_private) { + cur_def_vis = Private; + fc.cutLeft(1); + continue; + } if (cw == s_namespace) { PIString prev_namespace = cur_namespace, ccmn; cur_namespace += fc.takeCWord() + s_ns; @@ -486,10 +635,10 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) fc.takeSymbol(); continue; } - tmp = fc.takeLeft(fc.find('{')); + tmp = fc.takeLeft(fc.find('{')); stmp = fc.takeRange('{', '}'); fc.takeSymbol(); - stmp = cw + ' ' + tmp + '{' + stmp + '}'; + stmp = cw + ' ' + tmp + '{' + stmp + '}'; parseClass(ce, stmp, false); continue; } @@ -501,14 +650,16 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) fc.takeSymbol(); continue; } - if (cw == s_friend) {fc.cutLeft(fc.find(';') + 1); continue;} + if (cw == s_friend) { + fc.cutLeft(fc.find(';') + 1); + continue; + } if (cw == s_typedef) { if (ce) { ce->typedefs << parseTypedef(fc.takeLeft(fc.find(';'))); typedefs << ce->typedefs.back(); typedefs.back().first.insert(0, cur_namespace); - if (ce->typedefs.back().first.isEmpty()) - ce->typedefs.pop_back(); + if (ce->typedefs.back().first.isEmpty()) ce->typedefs.pop_back(); } fc.takeSymbol(); continue; @@ -517,20 +668,25 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) fc.takeRange('<', '>'); def = !isDeclaration(fc, 0, &end); fc.cutLeft(end); - if (def) fc.takeRange('{', '}'); - else fc.takeSymbol(); + if (def) + fc.takeRange('{', '}'); + else + fc.takeSymbol(); continue; } def = !isDeclaration(fc, 0, &end); tmp = (cw + fc.takeLeft(end)).trim(); - if (!tmp.isEmpty() && ce) - parseMember(ce, tmp); - if (def) fc.takeRange('{', '}'); - else fc.takeSymbol(); - if (ps == fc.size_s()) {fc.cutLeft(1);} + if (!tmp.isEmpty() && ce) parseMember(ce, tmp); + if (def) + fc.takeRange('{', '}'); + else + fc.takeSymbol(); + if (ps == fc.size_s()) { + fc.cutLeft(1); + } ps = fc.size_s(); } - cur_def_vis = prev_vis; + cur_def_vis = prev_vis; cur_namespace = prev_namespace; } @@ -539,7 +695,7 @@ PICodeParser::MetaMap PICodeParser::parseMeta(PIString & fc) { PICodeParser::MetaMap ret; if (fc.isEmpty()) return ret; PIStringList ml = fc.split(','); - piForeachC (PIString & m, ml) { + piForeachC(PIString & m, ml) { int i = m.find('='); if (i < 0) { ret[m.trimmed()] = PIString(); @@ -550,55 +706,61 @@ PICodeParser::MetaMap PICodeParser::parseMeta(PIString & fc) { ret[m.left(i).trim()] = mv; } } - //piCout << ms << ret; + // piCout << ms << ret; return ret; } bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta) { static const PIString s_ss = PIStringAscii(" "); - static const PIString s_M = PIStringAscii("$M"); - //piCout << PIStringAscii("enum") << name << fc; + static const PIString s_M = PIStringAscii("$M"); + // piCout << PIStringAscii("enum") << name << fc; Enum e(name); e.meta = meta; PIStringList vl(fc.split(',')); PIString vn; int cv = -1, ind = 0; - piForeach (PIString & v, vl) { + piForeach(PIString & v, vl) { MetaMap meta; int mi = v.find(s_M); if (mi >= 0) { meta = tmp_meta.value(v.takeMid(mi, 5)); v.replaceAll(s_ss, ' '); } - vn = v; ind = v.find('='); - if (ind > 0) {cv = v.right(v.size_s() - ind - 1).toInt(); vn = v.left(ind);} + vn = v; + ind = v.find('='); + if (ind > 0) { + cv = v.right(v.size_s() - ind - 1).toInt(); + vn = v.left(ind); + } if (ind < 0) ++cv; e.members << EnumeratorInfo(vn.trim(), cv, meta); } if (!e.members.isEmpty()) - if (e.members.back().name.isEmpty()) - e.members.pop_back(); + if (e.members.back().name.isEmpty()) e.members.pop_back(); enums << e; return true; } PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) { - //piCout << "parse typedef" << fc; + // piCout << "parse typedef" << fc; Typedef td; fc.replaceAll('\t', ' '); - + if (fc.contains('(')) { int start = fc.find('('), end = fc.find(')'); td.first = fc.takeMid(start + 1, end - start - 1).trim(); - if (td.first.left(1) == PIChar('*')) {td.first.cutLeft(1).trim(); fc.insert(start + 1, '*');} + if (td.first.left(1) == PIChar('*')) { + td.first.cutLeft(1).trim(); + fc.insert(start + 1, '*'); + } td.second = fc.trim(); } else { - td.first = fc.takeMid(fc.findLast(' ')).trim(); + td.first = fc.takeMid(fc.findLast(' ')).trim(); td.second = fc.trim(); } - //piCout << "found typedef" << td; + // piCout << "found typedef" << td; return td; } @@ -634,22 +796,26 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { if (fc.trim().isEmpty()) return true; if (fc.find(s_operator) >= 0) return true; tmp_temp.clear(); - //piCout << "parse member" << fc; + // piCout << "parse member" << fc; int ts = fc.find('<'), te = 0; PIString ctemp, crepl; while (ts >= 0) { ctemp = fc.mid(ts).takeRange('<', '>'); - if (ctemp.isEmpty()) {te = ts + 1; ts = fc.find('<', te); continue;} + if (ctemp.isEmpty()) { + te = ts + 1; + ts = fc.find('<', te); + continue; + } crepl = s_T + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, '0'); fc.replace(ts, ctemp.size_s() + 2, crepl); tmp_temp[crepl] = '<' + ctemp + '>'; - ts = fc.find('<', te); + ts = fc.find('<', te); } fc.replaceAll('\n', ' ').replaceAll('\t', ' ').replaceAll(s_ss, ' ').replaceAll(s_cs, ',').replaceAll(s_sb, '(').replaceAll(s_sM, s_M); - //piCout << "parse member" << fc; + // piCout << "parse member" << fc; PIStringList tl, al; Member me; - //piCout << fc; + // piCout << fc; if (fc.contains('(')) { MetaMap meta; int ind = fc.find(s_M); @@ -659,16 +825,16 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { } fc.cutRight(fc.size_s() - fc.findLast(')') - 1); te = fc.find('('); - //piCout << fc; + // piCout << fc; for (ts = te - 1; ts >= 0; --ts) if (!_isCChar(fc[ts]) && !(fc[ts].isDigit())) break; - //piCout << "takeMid" << ts + 1 << te - ts - 1; + // piCout << "takeMid" << ts + 1 << te - ts - 1; me.meta = meta; me.name = fc.takeMid(ts + 1, te - ts - 1); if (me.name == parent->name) return true; me.arguments_full = fc.takeMid(ts + 2).cutRight(1).split(','); - me.type = fc.cutRight(1).trim(); - me.visibility = cur_def_vis; + me.type = fc.cutRight(1).trim(); + me.visibility = cur_def_vis; if (me.type.find(s_inline_s) >= 0) { me.attributes |= Inline; me.type.removeAll(s_inline_s); @@ -683,20 +849,18 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { } normalizeEntityNamespace(me.type); int i = 0; - //piCout << me.arguments_full; - piForeach (PIString & a, me.arguments_full) - if ((i = a.find('=')) > 0) - a.cutRight(a.size_s() - i).trim(); + // piCout << me.arguments_full; + piForeach(PIString & a, me.arguments_full) + if ((i = a.find('=')) > 0) a.cutRight(a.size_s() - i).trim(); for (int j = 0; j < me.arguments_full.size_s(); ++j) if (me.arguments_full[j] == s_void) { me.arguments_full.remove(j); --j; } me.arguments_type = me.arguments_full; - piForeach (PIString & a, me.arguments_type) { + piForeach(PIString & a, me.arguments_type) { crepl.clear(); - if (a.contains('[')) - crepl = a.takeMid(a.find('['), a.findLast(']') - a.find('[') + 1); + if (a.contains('[')) crepl = a.takeMid(a.find('['), a.findLast(']') - a.find('[') + 1); for (ts = a.size_s() - 1; ts >= 0; --ts) if (!_isCChar(a[ts]) && !(a[ts].isDigit())) break; a.cutRight(a.size_s() - ts - 1); @@ -705,31 +869,34 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { a.trim(); } restoreTmpTemp(&me); - //piCout << "func" << me.type << me.name << me.arguments_full << me.arguments_type; + // piCout << "func" << me.type << me.name << me.arguments_full << me.arguments_type; parent->functions << me; } else { if (fc.endsWith(';')) fc.cutRight(1); - //piCout << "member" << fc; + // piCout << "member" << fc; if (fc.startsWith(s_using) || !(fc.contains(' ') || fc.contains('\t') || fc.contains('\n'))) return true; int bits = extractMemberBits(fc); - tl = fc.split(','); - //piCout << "member" << fc << tl; - //piCout << "member after eb" << fc << ", bits =" << bits; + tl = fc.split(','); + // piCout << "member" << fc << tl; + // piCout << "member after eb" << fc << ", bits =" << bits; if (tl.isEmpty()) return true; - piForeach (PIString & v, tl) + piForeach(PIString & v, tl) removeAssignment(v); bool vn = true; - ctemp = tl.front().trim(); + ctemp = tl.front().trim(); PIString meta_t; if (ctemp.contains(s_M)) { meta_t = ctemp.takeMid(ctemp.find(s_M), 5); ctemp.trim(); } for (ts = ctemp.size_s() - 1; ts > 0; --ts) { - if (vn) {if (!_isCChar(ctemp[ts]) && !ctemp[ts].isDigit() && ctemp[ts] != '[' && ctemp[ts] != ']') vn = false;} - else {if (_isCChar(ctemp[ts]) || ctemp[ts].isDigit()) break;} + if (vn) { + if (!_isCChar(ctemp[ts]) && !ctemp[ts].isDigit() && ctemp[ts] != '[' && ctemp[ts] != ']') vn = false; + } else { + if (_isCChar(ctemp[ts]) || ctemp[ts].isDigit()) break; + } } - me.type = ctemp.takeLeft(ts + 1); + me.type = ctemp.takeLeft(ts + 1); me.visibility = cur_def_vis; ctemp += meta_t; restoreTmpTemp(&me); @@ -757,21 +924,21 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { type.trim(); normalizeEntityNamespace(type); tl[0] = ctemp.trim(); - //piCout << "vars" << tl; - piForeachC (PIString & v, tl) { + // piCout << "vars" << tl; + piForeachC(PIString & v, tl) { crepl.clear(); me.name = v.trimmed(); me.type = type; restoreTmpMeta(&me); if (me.name.isEmpty()) continue; - if (me.name.contains('[')) - crepl = me.name.takeMid(me.name.find('['), me.name.findLast(']') - me.name.find('[') + 1); + if (me.name.contains('[')) crepl = me.name.takeMid(me.name.find('['), me.name.findLast(']') - me.name.find('[') + 1); while (!me.name.isEmpty()) { if (me.name.front() == PIChar('*') || me.name.front() == PIChar('&')) { me.type += me.name.takeLeft(1); me.name.trim(); - } else break; + } else + break; } me.is_type_ptr = (me.type.right(1) == PIChar(']') || me.type.right(1) == PIChar('*')); me.type += crepl; @@ -781,12 +948,12 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { if (cdim.isEmpty()) break; me.dims << cdim; } - //PICout(PICoutManipulators::AddAll) << "var" << me.type << me.name << me.bits; - //piCout << "var" << v << me.type << me.name << me.bits; + // PICout(PICoutManipulators::AddAll) << "var" << me.type << me.name << me.bits; + // piCout << "var" << v << me.type << me.name << me.bits; parent->members << me; } } - //piCout << "parse member" << fc; + // piCout << "parse member" << fc; return true; } @@ -818,13 +985,25 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) { break; } n.push_front(' '); - if (n.find(s_s_const_s) >= 0) {n.replaceAll(s_s_const_s, ""); pref += s_const_s;} - if (n.find(s_s_static_s) >= 0) {n.replaceAll(s_s_static_s, ""); pref += s_static_s;} - if (n.find(s_s_mutable_s) >= 0) {n.replaceAll(s_s_mutable_s, ""); pref += s_mutable_s;} - if (n.find(s_s_volatile_s) >= 0) {n.replaceAll(s_s_volatile_s, ""); pref += s_volatile_s;} + if (n.find(s_s_const_s) >= 0) { + n.replaceAll(s_s_const_s, ""); + pref += s_const_s; + } + if (n.find(s_s_static_s) >= 0) { + n.replaceAll(s_s_static_s, ""); + pref += s_static_s; + } + if (n.find(s_s_mutable_s) >= 0) { + n.replaceAll(s_s_mutable_s, ""); + pref += s_mutable_s; + } + if (n.find(s_s_volatile_s) >= 0) { + n.replaceAll(s_s_volatile_s, ""); + pref += s_volatile_s; + } n.trim(); int f = 0; - piForeachC (Entity * e, entities) { + piForeachC(Entity * e, entities) { if (e->name == n) { n = (pref + n + suff).trim(); return; @@ -836,20 +1015,20 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) { return; } } - piForeachC (Enum & e, enums) { + piForeachC(Enum & e, enums) { if ((f = e.name.find(n)) >= 0) if (e.name.at(f - 1) == PIChar(':')) if (e.name.find(cur_namespace) >= 0) { - //piCout << "change" << n << "to" << e.name + suff; + // piCout << "change" << n << "to" << e.name + suff; n = pref + e.name + suff; return; } } - piForeachC (Typedef & e, typedefs) { + piForeachC(Typedef & e, typedefs) { if ((f = e.first.find(n)) >= 0) if (e.first.at(f - 1) == PIChar(':')) if (e.first.find(cur_namespace) >= 0) { - //piCout << "change" << n << "to" << e.name + suff; + // piCout << "change" << n << "to" << e.name + suff; n = pref + e.first + suff; return; } @@ -860,12 +1039,12 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) { void PICodeParser::restoreTmpTemp(Member * e) { static const PIString s_T = PIStringAscii("$T"); - int i = 0; - piForeach (PIString & a, e->arguments_full) { + int i = 0; + piForeach(PIString & a, e->arguments_full) { while ((i = a.find(s_T)) >= 0) a.replace(i, 5, tmp_temp[a.mid(i, 5)]); } - piForeach (PIString & a, e->arguments_type) { + piForeach(PIString & a, e->arguments_type) { while ((i = a.find(s_T)) >= 0) a.replace(i, 5, tmp_temp[a.mid(i, 5)]); } @@ -876,7 +1055,7 @@ void PICodeParser::restoreTmpTemp(Member * e) { void PICodeParser::restoreTmpMeta(PICodeParser::Member * e) { static const PIString s_M = PIStringAscii("$M"); - int i = e->name.find(s_M); + int i = e->name.find(s_M); if (i < 0) return; e->meta = tmp_meta[e->name.takeMid(i, 5)]; } @@ -898,7 +1077,7 @@ bool PICodeParser::macroCondition(const PIString & mif, PIString mifcond) { static const PIString s_ifndef = PIStringAscii("ifndef"); static const PIString s_if = PIStringAscii("if"); static const PIString s_elif = PIStringAscii("elif"); - //piCout << "macroCondition" << mif << mifcond; + // piCout << "macroCondition" << mif << mifcond; if (mif == s_ifdef) return isDefineExists(mifcond); if (mif == s_ifndef) return !isDefineExists(mifcond); if (mif == s_if || mif == s_elif) { @@ -917,52 +1096,65 @@ double PICodeParser::procMacrosCond(PIString fc) { char cc, nc; PIString ce; fc.removeAll(s_defined); - //piCout << "procMacrosCond" << fc; + // piCout << "procMacrosCond" << fc; while (!fc.isEmpty()) { cc = fc[0].toAscii(); nc = (fc.size() > 1 ? fc[1].toAscii() : 0); - if (cc == '!') {neg = true; fc.pop_front(); continue;} - if (cc == '(') {br = true; brv = procMacrosCond(fc.takeRange('(', ')'));} - if (cc == '&' && nc == '&') {fc.remove(0, 2); oper = 1; continue;} - if (cc == '|' && nc == '|') {fc.remove(0, 2); oper = 2; continue;} + if (cc == '!') { + neg = true; + fc.pop_front(); + continue; + } + if (cc == '(') { + br = true; + brv = procMacrosCond(fc.takeRange('(', ')')); + } + if (cc == '&' && nc == '&') { + fc.remove(0, 2); + oper = 1; + continue; + } + if (cc == '|' && nc == '|') { + fc.remove(0, 2); + oper = 2; + continue; + } if (!br) { ce = fc.takeCWord(); if (ce.isEmpty()) ce = fc.takeNumber(); } if (first) { first = false; - ret = br ? brv : defineValue(ce); + ret = br ? brv : defineValue(ce); if (neg) ret = -ret; } else { - //piCout << "oper" << oper << "with" << ce; + // piCout << "oper" << oper << "with" << ce; if (!br) brv = defineValue(ce); switch (oper) { - case 1: ret = ret && (neg ? -brv : brv); break; - case 2: ret = ret || (neg ? -brv : brv); break; + case 1: ret = ret && (neg ? -brv : brv); break; + case 2: ret = ret || (neg ? -brv : brv); break; } } if (ps == fc.size_s()) fc.cutLeft(1); ps = fc.size_s(); br = neg = false; } - //piCout << "return" << ret; + // piCout << "return" << ret; return ret; } bool PICodeParser::isDefineExists(const PIString & dn) { - piForeachC (Define & d, defines) { - if (d.first == dn) - return true; + piForeachC(Define & d, defines) { + if (d.first == dn) return true; } return false; } double PICodeParser::defineValue(const PIString & dn) { - piForeachC (Define & d, defines) { - if (d.first == dn) - return d.second.isEmpty() ? 1. : d.second.toDouble(); + piForeachC(Define & d, defines) { + if (d.first == dn) return d.second.isEmpty() ? 1. : d.second.toDouble(); } return dn.toDouble(); } @@ -979,28 +1171,33 @@ void PICodeParser::replaceMeta(PIString & dn) { ms = dn.findRange('(', ')', '\\', s + 6, &ml); if (ms < 0) return; PIString meta = dn.mid(ms, ml).trim(); - PIString rm = s_M + PIString::fromNumber(tmp_meta.size_s()).expandLeftTo(3, '0'); + PIString rm = s_M + PIString::fromNumber(tmp_meta.size_s()).expandLeftTo(3, '0'); dn.replace(s, ms + ml + 1 - s, rm); - //piCout << "FOUND META \"" << meta << '\"'; + // piCout << "FOUND META \"" << meta << '\"'; tmp_meta[rm] = parseMeta(meta); - s = dn.find(s_PIMETA); + s = dn.find(s_PIMETA); } } PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) { - piForeach (Entity * e, entities) - if (e->name == en) - return e; + piForeach(Entity * e, entities) + if (e->name == en) return e; return 0; } bool PICodeParser::isDeclaration(const PIString & fc, int start, int * end) { int dind = fc.find('{', start), find = fc.find(';', start); - //piCout << "isDeclaration" << dind << find << fc.left(10); - if (dind < 0 && find < 0) {if (end) *end = -1; return true;} - if (dind < 0 || find < dind) {if (end) *end = find; return true;} + // piCout << "isDeclaration" << dind << find << fc.left(10); + if (dind < 0 && find < 0) { + if (end) *end = -1; + return true; + } + if (dind < 0 || find < dind) { + if (end) *end = find; + return true; + } if (end) *end = dind; return false; } @@ -1013,7 +1210,7 @@ bool PICodeParser::isMainFile(const PIString & fc) { if (csi < 0) csi = fc.find(PIStringAscii("\tmain"), si); if (csi < 0) csi = fc.find(PIStringAscii("\nmain"), si); if (csi < 0) return false; - si = csi; + si = csi; int fi = fc.find('(', si + 5); if (fi < 0) return false; if (fi - si < 10) { @@ -1038,68 +1235,80 @@ PIString PICodeParser::procMacros(PIString fc) { int ifcnt = 0; bool grab = false, skip = false, cond_ok = false; PIString pfc, nfc, line, mif, mifcond; - //piCout << "procMacros\n<******" << fc << "\n******>"; + // piCout << "procMacros\n<******" << fc << "\n******>"; fc += '\n'; while (!fc.isEmpty()) { line = fc.takeLine().trimmed(); if (line.left(1) == PIChar('#')) { mifcond = line.mid(1); - mif = mifcond.takeCWord(); - //piCout << mif; - //piCout << "mif mifcond" << mif << mifcond << ifcnt; + mif = mifcond.takeCWord(); + // piCout << mif; + // piCout << "mif mifcond" << mif << mifcond << ifcnt; if (skip || grab) { if (mif.left(2) == s_if) ifcnt++; if (mif.left(5) == s_endif) { - if (ifcnt > 0) ifcnt--; + if (ifcnt > 0) + ifcnt--; else { - //piCout << "main endif" << skip << grab; + // piCout << "main endif" << skip << grab; if (grab) pfc += procMacros(nfc); skip = grab = false; continue; } } if (mif.left(4) == s_elif && ifcnt == 0) { - //piCout << "main elif" << skip << grab << cond_ok; + // piCout << "main elif" << skip << grab << cond_ok; if (cond_ok) { if (grab) { pfc += procMacros(nfc); - skip = true; grab = false; + skip = true; + grab = false; } continue; } if (skip) { - //piCout << "check elif" << skip << grab << cond_ok; + // piCout << "check elif" << skip << grab << cond_ok; if (!macroCondition(mif, mifcond.trimmed())) continue; - //piCout << "check elif ok"; - skip = false; grab = cond_ok = true; + // piCout << "check elif ok"; + skip = false; + grab = cond_ok = true; continue; } continue; } if (mif.left(4) == s_else && ifcnt == 0) { - //piCout << "main else" << skip << grab; + // piCout << "main else" << skip << grab; if (grab) pfc += procMacros(nfc); - if (skip && !cond_ok) {skip = false; grab = true;} - else {skip = true; grab = false;} + if (skip && !cond_ok) { + skip = false; + grab = true; + } else { + skip = true; + grab = false; + } continue; } if (grab) nfc += line + '\n'; continue; } if (mif.left(2) == s_if) { - //piCout << "main if"; + // piCout << "main if"; skip = grab = cond_ok = false; - if (macroCondition(mif, mifcond.trimmed())) grab = cond_ok = true; - else skip = true; + if (macroCondition(mif, mifcond.trimmed())) + grab = cond_ok = true; + else + skip = true; ifcnt = 0; nfc.clear(); } else { parseDirective(line.cutLeft(1).trim()); - //return false; /// WARNING: now skip errors + // return false; /// WARNING: now skip errors } } else { - if (grab) nfc += line + '\n'; - else if (!skip) pfc += line + '\n'; + if (grab) + nfc += line + '\n'; + else if (!skip) + pfc += line + '\n'; } } return pfc; @@ -1107,13 +1316,13 @@ PIString PICodeParser::procMacros(PIString fc) { bool PICodeParser::parseDirective(PIString d) { - static const PIString s_include = PIStringAscii("include"); - static const PIString s_define = PIStringAscii("define"); - static const PIString s_undef = PIStringAscii("undef"); - static const PIString s_PIMETA = PIStringAscii("PIMETA"); + static const PIString s_include = PIStringAscii("include"); + static const PIString s_define = PIStringAscii("define"); + static const PIString s_undef = PIStringAscii("undef"); + static const PIString s_PIMETA = PIStringAscii("PIMETA"); if (d.isEmpty()) return true; PIString dname = d.takeCWord(); - //piCout << "parseDirective" << d; + // piCout << "parseDirective" << d; if (dname == s_include) { d.replaceAll('<', '\"').replaceAll('>', '\"'); PIString cf = cur_file, ifc = d.takeRange('\"', '\"'); @@ -1125,7 +1334,7 @@ bool PICodeParser::parseDirective(PIString d) { } if (dname == s_define) { PIString mname = d.takeCWord(); - //piCout << mname; + // piCout << mname; if (mname == s_PIMETA) return true; if (d.left(1) == PIChar('(')) { // macro PIStringList args = d.takeRange('(', ')').split(',').trim(); @@ -1150,7 +1359,10 @@ bool PICodeParser::parseDirective(PIString d) { if (dname == s_undef) { PIString mname = d.takeCWord(); for (int i = 0; i < defines.size_s(); ++i) - if (defines[i].first == mname) {defines.remove(i); --i;} + if (defines[i].first == mname) { + defines.remove(i); + --i; + } return true; } return true; diff --git a/libs/main/code/picodeparser.h b/libs/main/code/picodeparser.h index ecea0b4b..6d4be409 100644 --- a/libs/main/code/picodeparser.h +++ b/libs/main/code/picodeparser.h @@ -5,49 +5,59 @@ * \~russian Разбор C++ кода */ /* - PIP - Platform Independent Primitives - C++ code parser - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + C++ code parser + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef PICODEPARSER_H #define PICODEPARSER_H -#include "pifile.h" #include "pievaluator.h" +#include "pifile.h" -inline bool _isCChar(const PIChar & c) {return (c.isAlpha() || (c.toAscii() == '_'));} -inline bool _isCChar(const PIString & c) {if (c.isEmpty()) return false; return _isCChar(c[0]);} +inline bool _isCChar(const PIChar & c) { + return (c.isAlpha() || (c.toAscii() == '_')); +} +inline bool _isCChar(const PIString & c) { + if (c.isEmpty()) return false; + return _isCChar(c[0]); +} class PIP_EXPORT PICodeParser { public: PICodeParser(); - - enum Visibility {Global, Public, Protected, Private}; + + enum Visibility { + Global, + Public, + Protected, + Private + }; enum Attribute { NoAttributes = 0x0, - Const = 0x01, - Static = 0x02, - Mutable = 0x04, - Volatile = 0x08, - Inline = 0x10, - Virtual = 0x20, - Extern = 0x40 + Const = 0x01, + Static = 0x02, + Mutable = 0x04, + Volatile = 0x08, + Inline = 0x10, + Virtual = 0x20, + Extern = 0x40 }; - + typedef PIFlags Attributes; typedef PIPair Define; typedef PIPair Typedef; @@ -55,25 +65,25 @@ public: struct PIP_EXPORT Macro { Macro(const PIString & n = PIString(), const PIString & v = PIString(), const PIStringList & a = PIStringList()) { - name = n; + name = n; value = v; - args = a; + args = a; } PIString expand(PIString args_, bool * ok = 0) const; PIString name; PIString value; PIStringList args; }; - + struct PIP_EXPORT Member { Member() { - visibility = Global; - size = 0; - bits = -1; + visibility = Global; + size = 0; + bits = -1; is_type_ptr = false; - attributes = NoAttributes; + attributes = NoAttributes; } - bool isBitfield() const {return bits > 0;} + bool isBitfield() const { return bits > 0; } MetaMap meta; PIString type; PIString name; @@ -86,12 +96,12 @@ public: int size; int bits; }; - + struct PIP_EXPORT Entity { Entity() { - visibility = Global; - has_name = true; - size = 0; + visibility = Global; + has_name = true; + size = 0; parent_scope = 0; } MetaMap meta; @@ -102,49 +112,51 @@ public: int size; bool has_name; Entity * parent_scope; - PIVector parents; - PIVector children; + PIVector parents; + PIVector children; PIVector functions; PIVector members; PIVector typedefs; }; struct PIP_EXPORT EnumeratorInfo { - EnumeratorInfo(const PIString & n = PIString(), int v = 0, const MetaMap & m = MetaMap()) {name = n; value = v; meta = m;} + EnumeratorInfo(const PIString & n = PIString(), int v = 0, const MetaMap & m = MetaMap()) { + name = n; + value = v; + meta = m; + } MetaMap meta; PIString name; int value; }; struct PIP_EXPORT Enum { - Enum(const PIString & n = PIString()) { - name = n; - } + Enum(const PIString & n = PIString()) { name = n; } MetaMap meta; PIString name; PIVector members; }; - + void parseFile(const PIString & file, bool follow_includes = true); void parseFiles(const PIStringList & files, bool follow_includes = true); - - void includeDirectory(const PIString & dir) {includes << dir;} - void addDefine(const PIString & def_name, const PIString & def_value) {custom_defines << Define(def_name, def_value);} + + void includeDirectory(const PIString & dir) { includes << dir; } + void addDefine(const PIString & def_name, const PIString & def_value) { custom_defines << Define(def_name, def_value); } bool isEnum(const PIString & name); Entity * findEntityByName(const PIString & en); - PIStringList parsedFiles() const {return PIStringList(proc_files.toVector());} - PIString mainFile() const {return main_file;} - const PICodeParser::Entity * global() const {return &root_;} - - int macrosSubstitutionMaxIterations() const {return macros_iter;} - void setMacrosSubstitutionMaxIterations(int value) {macros_iter = value;} - + PIStringList parsedFiles() const { return PIStringList(proc_files.toVector()); } + PIString mainFile() const { return main_file; } + const PICodeParser::Entity * global() const { return &root_; } + + int macrosSubstitutionMaxIterations() const { return macros_iter; } + void setMacrosSubstitutionMaxIterations(int value) { macros_iter = value; } + PIVector defines, custom_defines; PIVector macros; PIVector enums; PIVector typedefs; - PIVector entities; - + PIVector entities; + private: void clear(); bool parseFileInternal(const PIString & file, bool follow_includes); @@ -169,7 +181,7 @@ private: bool isDeclaration(const PIString & fc, int start, int * end); bool isMainFile(const PIString & fc); void normalizeEntityNamespace(PIString & n); - + int macros_iter, anon_num; bool with_includes; PIEvaluator evaluator; @@ -181,7 +193,6 @@ private: PIString cur_namespace; PIMap tmp_temp; PIMap tmp_meta; - }; #endif // PICODEPARSER_H diff --git a/libs/main/compress/picompress.h b/libs/main/compress/picompress.h index dcd18b06..248b7028 100644 --- a/libs/main/compress/picompress.h +++ b/libs/main/compress/picompress.h @@ -6,22 +6,22 @@ * \~russian Сжатие с помощью zlib */ /* - PIP - Platform Independent Primitives - Compress class using zlib - Andrey Bychkov work.a.b@yandex.ru + PIP - Platform Independent Primitives + Compress class using zlib + Andrey Bychkov work.a.b@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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ //! \defgroup Compress Compress //! \~\brief @@ -58,8 +58,8 @@ #ifndef PICOMPRESS_H #define PICOMPRESS_H -#include "pip_compress_export.h" #include "pibytearray.h" +#include "pip_compress_export.h" //! \~english Compress "ba" with compression level "level", return empty %PIByteArray if no compression supports //! \~russian Сжимает "ba" с уровнем сжатия "level", возвращает пустой %PIByteArray если нет поддержки diff --git a/libs/main/console/piconsolemodule.h b/libs/main/console/piconsolemodule.h index b3b3cf24..766d2d64 100644 --- a/libs/main/console/piconsolemodule.h +++ b/libs/main/console/piconsolemodule.h @@ -1,20 +1,20 @@ /* - PIP - Platform Independent Primitives - Module includes - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Module includes + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ //! \defgroup Console Console //! \~\brief diff --git a/libs/main/console/pikbdlistener.cpp b/libs/main/console/pikbdlistener.cpp index 89e1f744..194cf090 100644 --- a/libs/main/console/pikbdlistener.cpp +++ b/libs/main/console/pikbdlistener.cpp @@ -1,20 +1,20 @@ /* - PIP - Platform Independent Primitives - Keyboard grabber for console - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Keyboard grabber for console + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include "pikbdlistener.h" @@ -406,11 +406,11 @@ void PIKbdListener::readKeyboard() { PRIVATE->ret = read(0, rc, 8); /*piCout << "key" << PIString(rc).replaceAll("\e", "\\e"); for (int i = 0; i < PRIVATE->ret; ++i) - PICout(0) << PICoutManipulators::Hex << int(((uchar * )&rc)[i]) << ' '; + PICout(0) << PICoutManipulators::Hex << int(((uchar * )&rc)[i]) << ' '; PICout(0) << "\n"; std::cout << PRIVATE->ret << " chars "; for (int i = 0; i < PRIVATE->ret; ++i) - std::cout << "'" << (char)(rc[i]) << "' " << (int)(uchar)(rc[i]); + std::cout << "'" << (char)(rc[i]) << "' " << (int)(uchar)(rc[i]); std::cout << std::endl;*/ if (rc[0] == 0) { piMSleep(10); @@ -523,7 +523,7 @@ void PIKbdListener::readKeyboard() { } /*cout << "wo mods (" << mod << ")\n"; for (int i = 0; i < PRIVATE->ret; ++i) - cout << "'" << (char)(rc[i]) << "' "; + cout << "'" << (char)(rc[i]) << "' "; cout << endl;*/ } if (ke.key == 0 && PRIVATE->ret > 1) ke.key = PIChar(rc).unicode16Code(); diff --git a/libs/main/console/pikbdlistener.h b/libs/main/console/pikbdlistener.h index 7b0d3fe4..165ed9ad 100644 --- a/libs/main/console/pikbdlistener.h +++ b/libs/main/console/pikbdlistener.h @@ -5,22 +5,22 @@ * \~russian Консольный захват клавиатуры */ /* - PIP - Platform Independent Primitives - Keyboard grabber for console - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Keyboard grabber for console + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef PIKBDLISTENER_H diff --git a/libs/main/console/piscreen.h b/libs/main/console/piscreen.h index 576cf232..67fdf15c 100644 --- a/libs/main/console/piscreen.h +++ b/libs/main/console/piscreen.h @@ -5,104 +5,108 @@ * \~russian Консольный тайловый менеджер */ /* - PIP - Platform Independent Primitives - Console GUI - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Console GUI + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef PISCREEN_H #define PISCREEN_H #include "pip_console_export.h" -#include "piscreentile.h" #include "piscreendrawer.h" +#include "piscreentile.h" -class PIP_CONSOLE_EXPORT PIScreen: public PIThread, public PIScreenTypes::PIScreenBase -{ +class PIP_CONSOLE_EXPORT PIScreen + : public PIThread + , public PIScreenTypes::PIScreenBase { PIOBJECT_SUBCLASS(PIScreen, PIThread); class SystemConsole; + public: - //! Constructs %PIScreen with key handler "slot" and if "startNow" start it PIScreen(bool startNow = true, PIKbdListener::KBFunc slot = 0); - - ~PIScreen(); - - //! Directly call function from \a PIKbdListener - void enableExitCapture(int key = 'Q') {listener->enableExitCapture(key);} - - //! Directly call function from \a PIKbdListener - void disableExitCapture() {listener->disableExitCapture();} - - //! Directly call function from \a PIKbdListener - bool exitCaptured() const {return listener->exitCaptured();} - - //! Directly call function from \a PIKbdListener - int exitKey() const {return listener->exitKey();} - - int windowWidth() const {return console.width;} - int windowHeight() const {return console.height;} - bool isMouseEnabled() const {return mouse_;} + ~PIScreen(); + + //! Directly call function from \a PIKbdListener + void enableExitCapture(int key = 'Q') { listener->enableExitCapture(key); } + + //! Directly call function from \a PIKbdListener + void disableExitCapture() { listener->disableExitCapture(); } + + //! Directly call function from \a PIKbdListener + bool exitCaptured() const { return listener->exitCaptured(); } + + //! Directly call function from \a PIKbdListener + int exitKey() const { return listener->exitKey(); } + + int windowWidth() const { return console.width; } + int windowHeight() const { return console.height; } + + bool isMouseEnabled() const { return mouse_; } void setMouseEnabled(bool on); - - PIScreenTile * rootTile() {return &root;} + + PIScreenTile * rootTile() { return &root; } PIScreenTile * tileByName(const PIString & name); - + void setDialogTile(PIScreenTile * t); - PIScreenTile * dialogTile() const {return tile_dialog;} - - PIScreenDrawer * drawer() {return &drawer_;} - void clear() {drawer_.clear();} - void resize(int w, int h) {console.resize(w, h);} - + PIScreenTile * dialogTile() const { return tile_dialog; } + + PIScreenDrawer * drawer() { return &drawer_; } + void clear() { drawer_.clear(); } + void resize(int w, int h) { console.resize(w, h); } + EVENT_HANDLER0(void, waitForFinish); - EVENT_HANDLER0(void, start) {start(false);} - EVENT_HANDLER1(void, start, bool, wait) {PIThread::start(40); if (wait) waitForFinish();} - EVENT_HANDLER0(void, stop) {stop(false);} + EVENT_HANDLER0(void, start) { start(false); } + EVENT_HANDLER1(void, start, bool, wait) { + PIThread::start(40); + if (wait) waitForFinish(); + } + EVENT_HANDLER0(void, stop) { stop(false); } EVENT_HANDLER1(void, stop, bool, clear); - - EVENT2(keyPressed, PIKbdListener::KeyEvent, key, void * , data); - EVENT2(tileEvent, PIScreenTile * , tile, PIScreenTypes::TileEvent, e); - -//! \handlers -//! \{ - + + EVENT2(keyPressed, PIKbdListener::KeyEvent, key, void *, data); + EVENT2(tileEvent, PIScreenTile *, tile, PIScreenTypes::TileEvent, e); + + //! \handlers + //! \{ + //! \fn void waitForFinish() //! \brief block until finished (exit key will be pressed) - + //! \fn void start(bool wait = false) //! \brief Start console output and if "wait" block until finished (exit key will be pressed) - + //! \fn void stop(bool clear = false) //! \brief Stop console output and if "clear" clear the screen - -//! \} -//! \events -//! \{ - + + //! \} + //! \events + //! \{ + //! \fn void keyPressed(PIKbdListener::KeyEvent key, void * data) //! \brief Raise on key "key" pressed, "data" is pointer to %PIConsole object - + //! \fn void tileEvent(PIScreenTile * tile, PIScreenTypes::TileEvent e) //! \brief Raise on some event "e" from tile "tile" - -//! \} - + + //! \} + private: class PIP_CONSOLE_EXPORT SystemConsole { public: @@ -131,7 +135,7 @@ private: PRIVATE_DECLARATION(PIP_CONSOLE_EXPORT) int width, height, pwidth, pheight; int mouse_x, mouse_y; - PIVector > cells, pcells; + PIVector> cells, pcells; }; void begin() override; @@ -140,10 +144,10 @@ private: void key_event(PIKbdListener::KeyEvent key); EVENT_HANDLER1(void, mouse_event, PIKbdListener::MouseEvent, me); EVENT_HANDLER1(void, wheel_event, PIKbdListener::WheelEvent, we); - static void key_eventS(PIKbdListener::KeyEvent key, void * t) {((PIScreen*)t)->key_event(key);} - PIVector tiles() {return root.children();} - PIVector prepareMouse(PIKbdListener::MouseEvent * e); - PIVector tilesUnderMouse(int x, int y); + static void key_eventS(PIKbdListener::KeyEvent key, void * t) { ((PIScreen *)t)->key_event(key); } + PIVector tiles() { return root.children(); } + PIVector prepareMouse(PIKbdListener::MouseEvent * e); + PIVector tilesUnderMouse(int x, int y); bool nextFocus(PIScreenTile * rt, PIKbdListener::KeyEvent key = PIKbdListener::KeyEvent()); void tileEventInternal(PIScreenTile * t, PIScreenTypes::TileEvent e) override; void tileRemovedInternal(PIScreenTile * t) override; @@ -155,8 +159,7 @@ private: PIKbdListener * listener; PIKbdListener::KBFunc ret_func; PIScreenTile root; - PIScreenTile * tile_focus, * tile_dialog; - + PIScreenTile *tile_focus, *tile_dialog; }; diff --git a/libs/main/console/piscreenconsole.h b/libs/main/console/piscreenconsole.h index 60ddf9dc..ad2f7d6c 100644 --- a/libs/main/console/piscreenconsole.h +++ b/libs/main/console/piscreenconsole.h @@ -5,22 +5,22 @@ * \~russian Тайл для PIScreen с API PIConsole */ /* - PIP - Platform Independent Primitives - Tile for PIScreen with PIConsole API - Andrey Bychkov work.a.b@yandex.ru + PIP - Platform Independent Primitives + Tile for PIScreen with PIConsole API + Andrey Bychkov work.a.b@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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef PISCREENCONSOLE_H @@ -35,10 +35,15 @@ class PIP_CONSOLE_EXPORT TileVars: public PIScreenTile { public: TileVars(const PIString & n = PIString()); + protected: struct PIP_CONSOLE_EXPORT Variable { - Variable() {nx = ny = type = offset = bitFrom = bitCount = size = 0; format = PIScreenTypes::CellFormat(); ptr = 0;} - bool isEmpty() const {return (ptr == 0);} + Variable() { + nx = ny = type = offset = bitFrom = bitCount = size = 0; + format = PIScreenTypes::CellFormat(); + ptr = 0; + } + bool isEmpty() const { return (ptr == 0); } PIString name; PIScreenTypes::CellFormat format; int nx; @@ -50,16 +55,16 @@ protected: int size; const void * ptr; /*void operator =(const Variable & src) { - name = src.name; - format = src.format; - nx = src.nx; - ny = src.ny; - type = src.type; - offset = src.offset; - bitFrom = src.bitFrom; - bitCount = src.bitCount; - size = src.size; - ptr = src.ptr; + name = src.name; + format = src.format; + nx = src.nx; + ny = src.ny; + type = src.type; + offset = src.offset; + bitFrom = src.bitFrom; + bitCount = src.bitCount; + size = src.size; + ptr = src.ptr; }*/ }; PIVector variables; @@ -69,9 +74,7 @@ protected: }; - -class PIP_CONSOLE_EXPORT PIScreenConsoleTile : public PIScreenTile -{ +class PIP_CONSOLE_EXPORT PIScreenConsoleTile: public PIScreenTile { public: PIScreenConsoleTile(); }; diff --git a/libs/main/console/piscreendrawer.h b/libs/main/console/piscreendrawer.h index 0928305b..81b7c91a 100644 --- a/libs/main/console/piscreendrawer.h +++ b/libs/main/console/piscreendrawer.h @@ -5,22 +5,22 @@ * \~russian Отрисовщик для PIScreen */ /* - PIP - Platform Independent Primitives - Drawer for PIScreen - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Drawer for PIScreen + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef PISCREENDRAWER_H @@ -30,10 +30,10 @@ #include "piscreentypes.h" #include "pistring.h" -class PIP_CONSOLE_EXPORT PIScreenDrawer -{ +class PIP_CONSOLE_EXPORT PIScreenDrawer { friend class PIScreen; - PIScreenDrawer(PIVector > & c); + PIScreenDrawer(PIVector> & c); + public: enum ArtChar { LineVertical = 1, @@ -46,26 +46,62 @@ public: Unchecked, Checked }; - - void clear(); - void clearRect(int x0, int y0, int x1, int y1) {fillRect(x0, y0, x1, y1, ' ');} - void drawPixel(int x, int y, const PIChar & c, PIScreenTypes::Color col_char = PIScreenTypes::Default, PIScreenTypes::Color col_back = PIScreenTypes::Default, PIScreenTypes::CharFlags flags_char = 0); - void drawLine(int x0, int y0, int x1, int y1, const PIChar & c, PIScreenTypes::Color col_char = PIScreenTypes::Default, PIScreenTypes::Color col_back = PIScreenTypes::Default, PIScreenTypes::CharFlags flags_char = 0); - void drawRect(int x0, int y0, int x1, int y1, const PIChar & c, PIScreenTypes::Color col_char = PIScreenTypes::Default, PIScreenTypes::Color col_back = PIScreenTypes::Default, PIScreenTypes::CharFlags flags_char = 0); - void drawFrame(int x0, int y0, int x1, int y1, PIScreenTypes::Color col_char = PIScreenTypes::Default, PIScreenTypes::Color col_back = PIScreenTypes::Default, PIScreenTypes::CharFlags flags_char = 0); - void drawText(int x, int y, const PIString & s, PIScreenTypes::Color col_char = PIScreenTypes::Default, PIScreenTypes::Color col_back = PIScreenTypes::Transparent, PIScreenTypes::CharFlags flags_char = 0); - void fillRect(int x0, int y0, int x1, int y1, const PIChar & c, PIScreenTypes::Color col_char = PIScreenTypes::Default, PIScreenTypes::Color col_back = PIScreenTypes::Default, PIScreenTypes::CharFlags flags_char = 0); - void fillRect(int x0, int y0, int x1, int y1, PIVector > & content); - - PIChar artChar(const ArtChar type) const {return arts_.value(type, PIChar(' '));} - static void clear(PIVector > & cells); + void clear(); + void clearRect(int x0, int y0, int x1, int y1) { fillRect(x0, y0, x1, y1, ' '); } + void drawPixel(int x, + int y, + const PIChar & c, + PIScreenTypes::Color col_char = PIScreenTypes::Default, + PIScreenTypes::Color col_back = PIScreenTypes::Default, + PIScreenTypes::CharFlags flags_char = 0); + void drawLine(int x0, + int y0, + int x1, + int y1, + const PIChar & c, + PIScreenTypes::Color col_char = PIScreenTypes::Default, + PIScreenTypes::Color col_back = PIScreenTypes::Default, + PIScreenTypes::CharFlags flags_char = 0); + void drawRect(int x0, + int y0, + int x1, + int y1, + const PIChar & c, + PIScreenTypes::Color col_char = PIScreenTypes::Default, + PIScreenTypes::Color col_back = PIScreenTypes::Default, + PIScreenTypes::CharFlags flags_char = 0); + void drawFrame(int x0, + int y0, + int x1, + int y1, + PIScreenTypes::Color col_char = PIScreenTypes::Default, + PIScreenTypes::Color col_back = PIScreenTypes::Default, + PIScreenTypes::CharFlags flags_char = 0); + void drawText(int x, + int y, + const PIString & s, + PIScreenTypes::Color col_char = PIScreenTypes::Default, + PIScreenTypes::Color col_back = PIScreenTypes::Transparent, + PIScreenTypes::CharFlags flags_char = 0); + void fillRect(int x0, + int y0, + int x1, + int y1, + const PIChar & c, + PIScreenTypes::Color col_char = PIScreenTypes::Default, + PIScreenTypes::Color col_back = PIScreenTypes::Default, + PIScreenTypes::CharFlags flags_char = 0); + void fillRect(int x0, int y0, int x1, int y1, PIVector> & content); + + PIChar artChar(const ArtChar type) const { return arts_.value(type, PIChar(' ')); } + + static void clear(PIVector> & cells); private: - PIVector > & cells; + PIVector> & cells; int width, height; PIMap arts_; - }; diff --git a/libs/main/console/piscreentile.h b/libs/main/console/piscreentile.h index 8af829fa..be420e18 100644 --- a/libs/main/console/piscreentile.h +++ b/libs/main/console/piscreentile.h @@ -5,58 +5,66 @@ * \~russian Базовый тайл для PIScreen */ /* - PIP - Platform Independent Primitives - Basic PIScreen tile - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Basic PIScreen tile + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef PISCREENTILE_H #define PISCREENTILE_H +#include "pikbdlistener.h" #include "pip_console_export.h" #include "piscreentypes.h" -#include "pikbdlistener.h" class PIScreenDrawer; class PIP_CONSOLE_EXPORT PIScreenTile: public PIObject { friend class PIScreen; PIOBJECT_SUBCLASS(PIScreenTile, PIObject); + public: - PIScreenTile(const PIString & n = PIString(), PIScreenTypes::Direction d = PIScreenTypes::Vertical, PIScreenTypes::SizePolicy p = PIScreenTypes::Preferred); + PIScreenTile(const PIString & n = PIString(), + PIScreenTypes::Direction d = PIScreenTypes::Vertical, + PIScreenTypes::SizePolicy p = PIScreenTypes::Preferred); virtual ~PIScreenTile(); - + void addTile(PIScreenTile * t); void takeTile(PIScreenTile * t); void removeTile(PIScreenTile * t); - PIScreenTile * parentTile() const {return parent;} - PIVector children(bool only_visible = false); + PIScreenTile * parentTile() const { return parent; } + PIVector children(bool only_visible = false); PIScreenTile * childUnderMouse(int x, int y); - void show() {visible = true;} - void hide() {visible = false;} + void show() { visible = true; } + void hide() { visible = false; } void setFocus(); - bool hasFocus() const {return has_focus;} - void setMargins(int m) {marginLeft = marginRight = marginTop = marginBottom = m;} - void setMargins(int l, int r, int t, int b) {marginLeft = l; marginRight = r; marginTop = t; marginBottom = b;} + bool hasFocus() const { return has_focus; } + void setMargins(int m) { marginLeft = marginRight = marginTop = marginBottom = m; } + void setMargins(int l, int r, int t, int b) { + marginLeft = l; + marginRight = r; + marginTop = t; + marginBottom = b; + } + + int x() const { return x_; } + int y() const { return y_; } + int width() const { return width_; } + int height() const { return height_; } - int x() const {return x_;} - int y() const {return y_;} - int width() const {return width_;} - int height() const {return height_;} - PIScreenTypes::Direction direction; PIScreenTypes::SizePolicy size_policy; PIScreenTypes::FocusFlags focus_flags; @@ -67,43 +75,41 @@ public: int marginLeft, marginRight, marginTop, marginBottom; int spacing; bool visible; - + protected: - //! Returns desired tile size in "w" and "h" virtual void sizeHint(int & w, int & h) const; - + //! Tile has been resized to "w"x"h" virtual void resizeEvent(int w, int h) {} - + //! Draw tile with drawer "d" in world-space coordinates virtual void drawEvent(PIScreenDrawer * d) {} - + //! Return "true" if you process key - virtual bool keyEvent(PIKbdListener::KeyEvent key) {return false;} + virtual bool keyEvent(PIKbdListener::KeyEvent key) { return false; } //! Return "true" if you process event - virtual bool mouseEvent(PIKbdListener::MouseEvent me) {return false;} + virtual bool mouseEvent(PIKbdListener::MouseEvent me) { return false; } //! Return "true" if you process wheel - virtual bool wheelEvent(PIKbdListener::WheelEvent we) {return false;} - + virtual bool wheelEvent(PIKbdListener::WheelEvent we) { return false; } + void raiseEvent(PIScreenTypes::TileEvent e); void setScreen(PIScreenTypes::PIScreenBase * s); void deleteChildren(); void drawEventInternal(PIScreenDrawer * d); void layout(); - bool needLayout() {return size_policy != PIScreenTypes::Ignore;} - - PIVector tiles; + bool needLayout() { return size_policy != PIScreenTypes::Ignore; } + + PIVector tiles; PIScreenTile * parent; PIScreenTypes::PIScreenBase * screen; int x_, y_, width_, height_; bool has_focus; - + private: int pw, ph; - }; diff --git a/libs/main/console/piscreentiles.h b/libs/main/console/piscreentiles.h index 62f83929..51dbde43 100644 --- a/libs/main/console/piscreentiles.h +++ b/libs/main/console/piscreentiles.h @@ -5,22 +5,22 @@ * \~russian Различные тайлы для PIScreen */ /* - PIP - Platform Independent Primitives - Various tiles for PIScreen - Ivan Pelipenko peri4ko@yandex.ru + PIP - Platform Independent Primitives + Various tiles for PIScreen + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef PISCREENTILES_H @@ -32,6 +32,7 @@ class PIP_CONSOLE_EXPORT TileSimple: public PIScreenTile { PIOBJECT_SUBCLASS(TileSimple, PIScreenTile); + public: typedef PIPair Row; TileSimple(const PIString & n = PIString()); @@ -39,6 +40,7 @@ public: virtual ~TileSimple() {} PIVector content; PIScreenTypes::Alignment alignment; + protected: void sizeHint(int & w, int & h) const override; void drawEvent(PIScreenDrawer * d) override; @@ -50,16 +52,18 @@ class TileList; class PIP_CONSOLE_EXPORT TileScrollBar: public PIScreenTile { PIOBJECT_SUBCLASS(TileScrollBar, PIScreenTile); friend class TileList; + public: TileScrollBar(const PIString & n = PIString()); virtual ~TileScrollBar() {} void setMinimum(int v); void setMaximum(int v); void setValue(int v); - int minimum() const {return minimum_;} - int maximum() const {return maximum_;} - int value() const {return value_;} + int minimum() const { return minimum_; } + int maximum() const { return maximum_; } + int value() const { return value_; } int thickness; + protected: void _check(); void sizeHint(int & w, int & h) const override; @@ -72,6 +76,7 @@ protected: class PIP_CONSOLE_EXPORT TileList: public PIScreenTile { PIOBJECT_SUBCLASS(TileList, PIScreenTile); + public: enum SelectionMode { NoSelection, @@ -92,6 +97,7 @@ public: SelectionMode selection_mode; PISet selected; int lhei, cur, offset; + protected: void sizeHint(int & w, int & h) const override; void resizeEvent(int w, int h) override; @@ -106,6 +112,7 @@ protected: class PIP_CONSOLE_EXPORT TileButton: public PIScreenTile { PIOBJECT_SUBCLASS(TileButton, PIScreenTile); + public: TileButton(const PIString & n = PIString()); virtual ~TileButton() {} @@ -114,6 +121,7 @@ public: }; PIScreenTypes::CellFormat format; PIString text; + protected: void sizeHint(int & w, int & h) const override; void drawEvent(PIScreenDrawer * d) override; @@ -122,10 +130,9 @@ protected: }; - - class PIP_CONSOLE_EXPORT TileButtons: public PIScreenTile { PIOBJECT_SUBCLASS(TileButtons, PIScreenTile); + public: TileButtons(const PIString & n = PIString()); virtual ~TileButtons() {} @@ -136,14 +143,15 @@ public: PIScreenTypes::Alignment alignment; PIVector