Compare commits

12 Commits

Author SHA1 Message Date
6f6b717354 pip_test 2024-11-25 15:53:12 +03:00
58b3fa64bc http server fix 2024-11-25 15:00:42 +03:00
1acaf24df9 PIHTTPServer basic auth works 2024-11-24 23:23:08 +03:00
c2c9822169 fix FindPIP.cmake 2024-11-23 17:55:59 +03:00
dff4f2b3a0 add http_client library, using libcurl
take out common http entities to http_common dir
2024-11-23 17:54:22 +03:00
bf9ad65ff0 take out "asize" from vector/dequeue to picontainers.h->calcNewSize()
minAlloc and maxPoTAlloc now can be override from CMake by PIP_CONTAINERS_MIN_ALLOC and PIP_CONTAINERS_MAX_POT_ALLOC variables
2024-11-21 20:15:18 +03:00
53ec75bf0c remove junk 2024-11-21 16:31:40 +03:00
f5270d75eb multi-utf16 fix 2024-11-21 16:28:19 +03:00
4aa596b179 last commit error 2024-11-21 00:18:57 +03:00
002f21fc9e version 4.4.1 2024-11-21 00:10:35 +03:00
9ab46e4afc version 4.4.1
PIVector and PIDeque now growth to 64 MiB with PoT, then increments size by 64 MiB
in case of large containers it significantly save memory
2024-11-21 00:10:14 +03:00
caa7880cc4 get rid of piForeach
apply some code analyzer recommendations
ICU flag now check if libicu exists
prepare for more accurate growth of containers (limited PoT, then constantly increase size)
2024-11-20 20:01:47 +03:00
56 changed files with 1582 additions and 524 deletions

View File

@@ -3,7 +3,7 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake
project(PIP) project(PIP)
set(PIP_MAJOR 4) set(PIP_MAJOR 4)
set(PIP_MINOR 4) set(PIP_MINOR 4)
set(PIP_REVISION 0) set(PIP_REVISION 1)
set(PIP_SUFFIX ) set(PIP_SUFFIX )
set(PIP_COMPANY SHS) set(PIP_COMPANY SHS)
set(PIP_DOMAIN org.SHS) set(PIP_DOMAIN org.SHS)
@@ -97,7 +97,7 @@ set(PIP_UTILS_LIST)
set(PIP_TESTS_LIST) set(PIP_TESTS_LIST)
set(PIP_EXPORTS) set(PIP_EXPORTS)
set(PIP_SRC_MODULES "console;crypt;compress;usb;fftw;opencl;io_utils;client_server;cloud;lua;http_server") set(PIP_SRC_MODULES "console;crypt;compress;usb;fftw;opencl;io_utils;client_server;cloud;lua;http_client;http_server")
foreach(_m ${PIP_SRC_MODULES}) foreach(_m ${PIP_SRC_MODULES})
set(PIP_MSG_${_m} "no") set(PIP_MSG_${_m} "no")
endforeach() endforeach()
@@ -286,9 +286,14 @@ endif()
# Check if ICU used for PIString and PIChar # Check if ICU used for PIString and PIChar
set(PIP_ICU "no") set(PIP_ICU "no")
if(ICU) if(ICU)
set(PIP_ICU "yes") pip_find_lib(icuuc)
add_definitions(-DPIP_ICU) if (icuuc_FOUND)
list(APPEND LIBS_MAIN icuuc) set(PIP_ICU "yes")
add_definitions(-DPIP_ICU)
list(APPEND LIBS_MAIN icuuc)
else()
message(STATUS "Warning: ICU requested, but not found. Build without ICU")
endif()
endif() endif()
@@ -376,6 +381,17 @@ foreach(_m ${PIP_SRC_MODULES})
endforeach() endforeach()
set_target_properties(pip PROPERTIES DEFINE_SYMBOL pip_EXPORTS) set_target_properties(pip PROPERTIES DEFINE_SYMBOL pip_EXPORTS)
# Override containers minimum bytes allocation
if(NOT "x${PIP_CONTAINERS_MIN_ALLOC}" STREQUAL "x")
target_compile_definitions(pip PRIVATE "-DPIP_CONTAINERS_MIN_ALLOC=${PIP_CONTAINERS_MIN_ALLOC}")
message(STATUS "Attention: Override PIP_CONTAINERS_MIN_ALLOC = ${PIP_CONTAINERS_MIN_ALLOC}")
endif()
# Override containers maximum bytes for power of two expansion, may be bytes or X_KiB, or X_MiB
if(NOT "x${PIP_CONTAINERS_MAX_POT_ALLOC}" STREQUAL "x")
target_compile_definitions(pip PRIVATE "-DPIP_CONTAINERS_MAX_POT_ALLOC=${PIP_CONTAINERS_MAX_POT_ALLOC}")
message(STATUS "Attention: Override PIP_CONTAINERS_MAX_POT_ALLOC = ${PIP_CONTAINERS_MAX_POT_ALLOC}")
endif()
if (NOT CROSSTOOLS) if (NOT CROSSTOOLS)
if (NOT PIP_FREERTOS) if (NOT PIP_FREERTOS)
@@ -482,10 +498,8 @@ if (NOT CROSSTOOLS)
list(APPEND HDRS ${_lua_src_hdr}) list(APPEND HDRS ${_lua_src_hdr})
# libmicrohttpd # libmicrohttpd
find_library(microhttpd_LIBRARIES microhttpd HINTS "${MINGW_LIB}") pip_find_lib(microhttpd HINTS "${MINGW_LIB}")
set(microhttpd_FOUND FALSE) if (microhttpd_FOUND)
if (microhttpd_LIBRARIES)
set(microhttpd_FOUND TRUE)
set(_microhttpd_add_libs microhttpd) set(_microhttpd_add_libs microhttpd)
if(WIN32) if(WIN32)
if("${C_COMPILER}" STREQUAL "cl.exe") if("${C_COMPILER}" STREQUAL "cl.exe")
@@ -512,6 +526,12 @@ if (NOT CROSSTOOLS)
pip_module(http_server "${_microhttpd_add_libs}" "PIP HTTP server" "" "" "") pip_module(http_server "${_microhttpd_add_libs}" "PIP HTTP server" "" "" "")
endif() endif()
# libcurl
pip_find_lib(curl HINTS "${MINGW_LIB}")
if (curl_FOUND)
pip_module(http_client curl "PIP HTTP client" "" "" "")
endif()
# Test program # Test program
if(PIP_UTILS) if(PIP_UTILS)
@@ -519,9 +539,9 @@ if (NOT CROSSTOOLS)
#target_link_libraries(pip_plugin pip) #target_link_libraries(pip_plugin pip)
if (NOT DEFINED ANDROID_PLATFORM) if (NOT DEFINED ANDROID_PLATFORM)
if(microhttpd_FOUND) if(microhttpd_FOUND AND curl_FOUND)
add_executable(pip_test "main.cpp") add_executable(pip_test "main.cpp")
target_link_libraries(pip_test pip pip_io_utils pip_client_server pip_http_server) target_link_libraries(pip_test pip pip_io_utils pip_client_server pip_http_server pip_http_client)
if(sodium_FOUND) if(sodium_FOUND)
add_executable(pip_cloud_test "main_picloud_test.cpp") add_executable(pip_cloud_test "main_picloud_test.cpp")
target_link_libraries(pip_cloud_test pip_cloud) target_link_libraries(pip_cloud_test pip_cloud)
@@ -651,7 +671,7 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
find_package(Doxygen) find_package(Doxygen)
if(DOXYGEN_FOUND) if(DOXYGEN_FOUND)
set(DOXY_DEFINES "${PIP_EXPORTS}") set(DOXY_DEFINES "${PIP_EXPORTS}")
foreach (_m "console" "usb" "compress" "crypt" "client_server" "cloud" "fftw" "opencl" "io_utils" "lua") foreach (_m "console" "usb" "compress" "crypt" "client_server" "cloud" "fftw" "opencl" "io_utils" "lua" "http_server" "http_client")
string(TOUPPER "${_m}" _mdef) string(TOUPPER "${_m}" _mdef)
list(APPEND DOXY_DEFINES "PIP_${_mdef}_EXPORT") list(APPEND DOXY_DEFINES "PIP_${_mdef}_EXPORT")
endforeach() endforeach()
@@ -707,6 +727,7 @@ macro(expand_to_length _out _str _len)
endmacro() endmacro()
list(REMOVE_ITEM LIBS_STATUS ${PIP_MODULES}) list(REMOVE_ITEM LIBS_STATUS ${PIP_MODULES})
list(REMOVE_DUPLICATES LIBS_STATUS)
message("----------PIP----------") message("----------PIP----------")
message(" Version: ${PIP_VERSION} ") message(" Version: ${PIP_VERSION} ")
message(" Linkage: ${PIP_LIB_TYPE_MSG}") message(" Linkage: ${PIP_LIB_TYPE_MSG}")

View File

@@ -12,6 +12,7 @@ Create imported targets:
* PIP::ClientServer * PIP::ClientServer
* PIP::Cloud * PIP::Cloud
* PIP::Lua * PIP::Lua
* PIP::HTTPClient
* PIP::HTTPServer * PIP::HTTPServer
These targets include directories and depends on These targets include directories and depends on
@@ -24,10 +25,10 @@ include(SHSTKMacros)
shstk_set_find_dirs(PIP) shstk_set_find_dirs(PIP)
set(__libs "usb;crypt;console;fftw;compress;opencl;io_utils;client_server;cloud;lua;http_server") set(__libs "usb;crypt;console;fftw;compress;opencl;io_utils;client_server;cloud;lua;http_client;http_server")
if (BUILDING_PIP) if (BUILDING_PIP)
#set(_libs "pip;pip_usb;pip_console;pip_crypt;pip_fftw;pip_compress;pip_opencl;pip_io_utils;pip_cloud;pip_lua;pip_http_server") #set(_libs "pip;pip_usb;pip_console;pip_crypt;pip_fftw;pip_compress;pip_opencl;pip_io_utils;pip_cloud;pip_lua;pip_http_client;pip_http_server")
#set(_bins "pip_cmg;pip_rc;deploy_tool") #set(_bins "pip_cmg;pip_rc;deploy_tool")
#get_target_property(_path pip BINARY_DIR) #get_target_property(_path pip BINARY_DIR)
#get_target_property(_path pip LIBRARY_OUTPUT_NAME) #get_target_property(_path pip LIBRARY_OUTPUT_NAME)
@@ -97,6 +98,7 @@ set(__module_io_utils IOUtils )
set(__module_client_server ClientServer) set(__module_client_server ClientServer)
set(__module_cloud Cloud ) set(__module_cloud Cloud )
set(__module_lua Lua ) set(__module_lua Lua )
set(__module_http_client HTTPClient )
set(__module_http_server HTTPServer ) set(__module_http_server HTTPServer )
foreach (_l ${__libs}) foreach (_l ${__libs})

View File

@@ -505,7 +505,7 @@ void PIScreen::wheel_event(PIKbdListener::WheelEvent we) {
bool PIScreen::nextFocus(PIScreenTile * rt, PIKbdListener::KeyEvent key) { bool PIScreen::nextFocus(PIScreenTile * rt, PIKbdListener::KeyEvent key) {
PIVector<PIScreenTile *> vtl = rt->children(true), ftl; PIVector<PIScreenTile *> vtl = rt->children(true), ftl;
piForeach(PIScreenTile * t, vtl) { for (PIScreenTile * t: vtl) {
if (t->focus_flags[CanHasFocus]) ftl << t; if (t->focus_flags[CanHasFocus]) ftl << t;
} }
int ind = -1; int ind = -1;
@@ -535,7 +535,7 @@ bool PIScreen::nextFocus(PIScreenTile * rt, PIKbdListener::KeyEvent key) {
// piCout << ftl.size() << ind << next; // piCout << ftl.size() << ind << next;
if (next != 0) { if (next != 0) {
PIVector<PIScreenTile *> tl = rt->children(); PIVector<PIScreenTile *> tl = rt->children();
piForeach(PIScreenTile * t, tl) for (PIScreenTile * t: tl)
t->has_focus = false; t->has_focus = false;
if (!ftl.isEmpty()) { if (!ftl.isEmpty()) {
ind += next; ind += next;
@@ -565,7 +565,7 @@ void PIScreen::tileSetFocusInternal(PIScreenTile * t) {
PIScreenTile * rt = rootTile(); PIScreenTile * rt = rootTile();
if (tile_dialog) rt = tile_dialog; if (tile_dialog) rt = tile_dialog;
PIVector<PIScreenTile *> tl = rt->children(), ftl; PIVector<PIScreenTile *> tl = rt->children(), ftl;
piForeach(PIScreenTile * i, tl) for (PIScreenTile * i: tl)
i->has_focus = false; i->has_focus = false;
tile_focus = t; tile_focus = t;
if (!tile_focus) return; if (!tile_focus) return;
@@ -651,7 +651,7 @@ void PIScreen::end() {
PIScreenTile * PIScreen::tileByName(const PIString & name) { PIScreenTile * PIScreen::tileByName(const PIString & name) {
PIVector<PIScreenTile *> tl(tiles()); PIVector<PIScreenTile *> tl(tiles());
piForeach(PIScreenTile * t, tl) for (PIScreenTile * t: tl)
if (t->name() == name) return t; if (t->name() == name) return t;
return 0; return 0;
} }

View File

@@ -78,14 +78,14 @@ void PIScreenTile::removeTile(PIScreenTile * t) {
PIVector<PIScreenTile *> PIScreenTile::children(bool only_visible) { PIVector<PIScreenTile *> PIScreenTile::children(bool only_visible) {
PIVector<PIScreenTile *> ret; PIVector<PIScreenTile *> ret;
piForeach(PIScreenTile * t, tiles) for (auto * t: tiles)
if (t->visible || !only_visible) ret << t << t->children(only_visible); if (t->visible || !only_visible) ret << t << t->children(only_visible);
return ret; return ret;
} }
PIScreenTile * PIScreenTile::childUnderMouse(int x, int y) { PIScreenTile * PIScreenTile::childUnderMouse(int x, int y) {
piForeach(PIScreenTile * t, tiles) { for (auto * t: tiles) {
if (!t->visible) continue; 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; return t;
@@ -103,13 +103,13 @@ void PIScreenTile::raiseEvent(TileEvent e) {
void PIScreenTile::setScreen(PIScreenBase * s) { void PIScreenTile::setScreen(PIScreenBase * s) {
screen = s; screen = s;
piForeach(PIScreenTile * t, tiles) for (auto * t: tiles)
t->setScreen(s); t->setScreen(s);
} }
void PIScreenTile::deleteChildren() { void PIScreenTile::deleteChildren() {
piForeach(PIScreenTile * t, tiles) { for (auto * t: tiles) {
t->parent = 0; t->parent = 0;
delete t; delete t;
} }
@@ -136,7 +136,7 @@ void PIScreenTile::drawEventInternal(PIScreenDrawer * d) {
(Color)back_format.color_back, (Color)back_format.color_back,
back_format.flags); back_format.flags);
drawEvent(d); drawEvent(d);
piForeach(PIScreenTile * t, tiles) for (auto * t: tiles)
t->drawEventInternal(d); t->drawEventInternal(d);
} }
@@ -150,7 +150,7 @@ void PIScreenTile::sizeHint(int & w, int & h) const {
w += sl; w += sl;
else else
h += sl; h += sl;
piForeachC(PIScreenTile * t, tiles) { for (const auto * t: tiles) {
if (!t->visible) continue; if (!t->visible) continue;
int cw(0), ch(0); int cw(0), ch(0);
t->sizeHint(cw, ch); t->sizeHint(cw, ch);

View File

@@ -38,7 +38,7 @@ TileSimple::TileSimple(const TileSimple::Row & r): PIScreenTile() {
void TileSimple::sizeHint(int & w, int & h) const { void TileSimple::sizeHint(int & w, int & h) const {
w = h = 0; w = h = 0;
piForeachC(Row & r, content) for (const auto & r: content)
w = piMaxi(w, r.first.size_s()); w = piMaxi(w, r.first.size_s());
h = content.size_s(); h = content.size_s();
} }
@@ -139,7 +139,7 @@ TileList::TileList(const PIString & n, SelectionMode sm): PIScreenTile(n) {
void TileList::sizeHint(int & w, int & h) const { void TileList::sizeHint(int & w, int & h) const {
w = h = 0; w = h = 0;
piForeachC(Row & r, content) for (const auto & r: content)
w = piMaxi(w, r.first.size_s()); w = piMaxi(w, r.first.size_s());
h = 3; h = 3;
} }
@@ -361,12 +361,12 @@ TileButtons::TileButtons(const PIString & n): PIScreenTile(n) {
void TileButtons::sizeHint(int & w, int & h) const { void TileButtons::sizeHint(int & w, int & h) const {
w = h = 0; w = h = 0;
if (direction == Horizontal) { if (direction == Horizontal) {
piForeachC(Button & b, content) for (const auto & b: content)
w += b.first.size_s() + 4; w += b.first.size_s() + 4;
w += piMaxi(0, content.size_s() - 1) * 2; w += piMaxi(0, content.size_s() - 1) * 2;
h += 1; h += 1;
} else { } else {
piForeachC(Button & b, content) for (const auto & b: content)
w = piMaxi(w, b.first.size_s() + 4); w = piMaxi(w, b.first.size_s() + 4);
h += content.size_s(); h += content.size_s();
h += piMaxi(0, content.size_s() - 1); h += piMaxi(0, content.size_s() - 1);
@@ -539,7 +539,7 @@ void TilePICout::drawEvent(PIScreenDrawer * d) {
if (!out.isEmpty()) { if (!out.isEmpty()) {
PIStringList l = out.split("\n"); PIStringList l = out.split("\n");
bool scroll = (cur == content.size_s() - 1) || !has_focus; bool scroll = (cur == content.size_s() - 1) || !has_focus;
piForeachC(PIString & s, l) for (const auto & s: l)
content << TileList::Row(s.trimmed(), format); content << TileList::Row(s.trimmed(), format);
if (content.size_s() > max_lines) content.remove(0, content.size_s() - max_lines); if (content.size_s() > max_lines) content.remove(0, content.size_s() - max_lines);
if (scroll) { if (scroll) {

View File

@@ -518,7 +518,7 @@ void PITerminal::applyEscSeq(PIString es) {
return; return;
} }
PIStringList args = es.split(";"); PIStringList args = es.split(";");
piForeachC(PIString & a, args) { for (const auto & a: args) {
int av = a.toInt(); int av = a.toInt();
switch (av) { switch (av) {
case 0: PRIVATE->cur_format = PIScreenTypes::CellFormat(); break; case 0: PRIVATE->cur_format = PIScreenTypes::CellFormat(); break;
@@ -862,7 +862,7 @@ bool PITerminal::initialize() {
ws.ws_col = dsize_x; ws.ws_col = dsize_x;
ws.ws_row = dsize_y; ws.ws_row = dsize_y;
PIStringList env = PIProcess::currentEnvironment(); PIStringList env = PIProcess::currentEnvironment();
piForeachC(PIString & e, env) for (const auto & e: env)
if (e.startsWith("TERM=")) { if (e.startsWith("TERM=")) {
PRIVATE->term_type = termType(e.mid(5).trim().toLowerCase()); PRIVATE->term_type = termType(e.mid(5).trim().toLowerCase());
// piCout << PRIVATE->term_type; // piCout << PRIVATE->term_type;

View File

@@ -0,0 +1,75 @@
#include "curl_thread_pool_p.h"
#include "pihttpclient.h"
#include "pitime.h"
CurlThreadPool::CurlThreadPool() {
piForTimes(10) {
auto * t = new PIThread([this]() { threadFunc(); }, true);
threads << t;
}
}
CurlThreadPool::~CurlThreadPool() {
exiting = true;
for (auto * t: threads)
t->stop();
{
auto cr = clients.getRef();
for (auto c: *cr)
c->abort();
}
sem.release(threads.size());
for (auto * t: threads) {
t->waitForFinish();
t->setDebug(false);
t->terminate();
}
piDeleteAllAndClear(threads);
{
auto cr = clients.getRef();
for (auto c: *cr)
delete c;
}
}
void CurlThreadPool::threadFunc() {
if (exiting) return;
// piCout << "threadFuncl w ...";
sem.acquire();
// piCout << "threadFuncl wdone";
if (exiting) return;
PIHTTPClient * c = nullptr;
{
auto cr = clients.getRef();
if (cr->isEmpty()) return;
c = cr->dequeue();
// piCout << "threadFuncl get c";
}
// piCout << "threadFuncl proc c";
procClient(c);
// piCout << "threadFuncl end";
}
void CurlThreadPool::procClient(PIHTTPClient * c) {
if (c->init()) c->perform();
delete c;
}
void CurlThreadPool::registerClient(PIHTTPClient * c) {
clients.getRef()->enqueue(c);
sem.release();
// piCout << "registerClient";
}
CurlThreadPool * CurlThreadPool::instance() {
static CurlThreadPool ret;
return &ret;
}

View File

@@ -0,0 +1,31 @@
#ifndef curl_thread_pool_p_H
#define curl_thread_pool_p_H
#include "piprotectedvariable.h"
#include "pisemaphore.h"
#include "pithread.h"
class PIHTTPClient;
class CurlThreadPool {
public:
void registerClient(PIHTTPClient * c);
static CurlThreadPool * instance();
private:
NO_COPY_CLASS(CurlThreadPool)
CurlThreadPool();
~CurlThreadPool();
void threadFunc();
void procClient(PIHTTPClient * c);
PIProtectedVariable<PIQueue<PIHTTPClient *>> clients;
PISemaphore sem;
PIVector<PIThread *> threads;
std::atomic_bool exiting = {false};
};
#endif

View File

@@ -0,0 +1,210 @@
#include "pihttpclient.h"
#include "curl_thread_pool_p.h"
#include "piliterals_bytes.h"
#include "piliterals_string.h"
#include "pisystemtime.h"
#include <curl/curl.h>
int xfer_callback(void * ptr, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) {
return reinterpret_cast<PIHTTPClientBase *>(ptr)->__infoFunc(dltotal, dlnow, ultotal, ulnow);
}
int debug_callback(CURL * handle, curl_infotype type, char * data, size_t size, void * ptr) {
return reinterpret_cast<PIHTTPClientBase *>(ptr)->__debugFunc(type, data, size);
}
PRIVATE_DEFINITION_START(PIHTTPClient)
CURL * handle = nullptr;
PRIVATE_DEFINITION_END(PIHTTPClient)
PIHTTPClient::PIHTTPClient() {}
PIHTTPClient::~PIHTTPClient() {}
bool PIHTTPClient::init() {
if (is_cancel) return false;
PRIVATE->handle = curl_easy_init();
if (!PRIVATE->handle) return false;
curl_easy_setopt(PRIVATE->handle, CURLOPT_WRITEDATA, this);
curl_easy_setopt(PRIVATE->handle, CURLOPT_READDATA, this);
curl_easy_setopt(PRIVATE->handle, CURLOPT_XFERINFODATA, this);
curl_easy_setopt(PRIVATE->handle, CURLOPT_DEBUGDATA, this);
curl_easy_setopt(PRIVATE->handle, CURLOPT_HEADERDATA, this);
curl_easy_setopt(PRIVATE->handle, CURLOPT_WRITEFUNCTION, writeMemoryFunc);
curl_easy_setopt(PRIVATE->handle, CURLOPT_READFUNCTION, readMemoryFunc);
curl_easy_setopt(PRIVATE->handle, CURLOPT_XFERINFOFUNCTION, xfer_callback);
curl_easy_setopt(PRIVATE->handle, CURLOPT_DEBUGFUNCTION, debug_callback);
curl_easy_setopt(PRIVATE->handle, CURLOPT_HEADERFUNCTION, headerFunc);
curl_easy_setopt(PRIVATE->handle, CURLOPT_URL, url.dataUTF8());
curl_easy_setopt(PRIVATE->handle, CURLOPT_CUSTOMREQUEST, PIHTTP::methodName(request.method()));
curl_easy_setopt(PRIVATE->handle, CURLOPT_NOPROGRESS, 0L);
// curl_easy_setopt(PRIVATE->handle, CURLOPT_VERBOSE, 1L);
// curl_easy_setopt(PRIVATE->handle, CURLOPT_ERRORBUFFER, buffer_error.data());
curl_easy_setopt(PRIVATE->handle, CURLOPT_SSL_VERIFYPEER, 0L);
if (request.body().isNotEmpty()) {
curl_easy_setopt(PRIVATE->handle, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(PRIVATE->handle, CURLOPT_INFILESIZE_LARGE, static_cast<curl_off_t>(request.body().size()));
}
return true;
}
void PIHTTPClient::perform() {
if (!PRIVATE->handle) return;
if (!is_cancel) {
// piCout << "perform ...";
PITimeMeasurer tm;
CURLcode res = curl_easy_perform(PRIVATE->handle);
// piCout << "done" << res << "in" << tm.elapsed_m() << ", bytes" << buffer_out.size();
if (res == CURLE_OK) {
reply.setBody(std::move(buffer_out));
if (on_finish) on_finish(reply);
} else {
if (res == CURLE_ABORTED_BY_CALLBACK || is_cancel) {
// piCerr << "curl_easy_perform() failed:" << curl_easy_strerror(res);
if (on_abort) on_abort(reply);
} else {
last_error = curl_easy_strerror(res);
if (on_error) on_error(reply);
}
}
}
// piCout << last_error;
curl_easy_cleanup(PRIVATE->handle);
PRIVATE->handle = nullptr;
}
void PIHTTPClient::procHeaderLine(PIString & line) {
if (line.startsWith("HTTP"_a)) {
// HTTP/Версия КодСостояния Пояснение
line.cutLeft(5);
line.takeWord();
int code = line.takeWord().toInt();
// piCout << "code" << code;
reply.setCode(static_cast<PIHTTP::Code>(code));
return;
}
int ind = line.find(':');
if (ind < 0) return;
PIString hname = line.takeLeft(ind);
line.cutLeft(1).trim();
reply.addHeader(hname, line);
}
size_t PIHTTPClient::writeMemoryFunc(void * contents, size_t size, size_t nmemb, void * ptr) {
size_t bytes = size * nmemb;
// piCout << "writeMemoryFunc" << bytes;
auto client = reinterpret_cast<PIHTTPClient *>(ptr);
if (client->is_cancel) return CURL_WRITEFUNC_ERROR;
client->buffer_out.append(contents, bytes);
return bytes;
}
size_t PIHTTPClient::readMemoryFunc(void * contents, size_t size, size_t nmemb, void * ptr) {
size_t bytes = size * nmemb;
// piCout << "readMemoryFunc" << bytes;
auto client = reinterpret_cast<PIHTTPClient *>(ptr);
if (client->is_cancel) return CURL_READFUNC_ABORT;
const auto & buffer(client->request.body());
if (buffer.isEmpty()) return 0;
// piCout << bytes;
ssize_t ret = piClamp<ssize_t>(bytes, 0, buffer.size_s() - client->read_pos);
if (ret < 0) ret = 0;
if (ret > 0) memcpy(contents, buffer.data(client->read_pos), ret);
return ret;
}
size_t PIHTTPClient::headerFunc(char * contents, size_t size, size_t nmemb, void * ptr) {
size_t bytes = size * nmemb;
auto client = reinterpret_cast<PIHTTPClient *>(ptr);
if (client->is_cancel) return CURL_WRITEFUNC_ERROR;
PIString line = PIString::fromUTF8(contents, bytes).trim();
if (line.isNotEmpty()) client->procHeaderLine(line);
return bytes;
}
int PIHTTPClient::infoFunc(ssize_t dltotal, ssize_t dlnow, ssize_t ultotal, ssize_t ulnow) {
// piCout << "infoFunc" << dltotal << dlnow << ultotal << ulnow;
if (is_cancel) return 1;
return 0;
}
int PIHTTPClient::debugFunc(int type, char * data, size_t size) {
// piCout << "debugFunc" << type << PIString::fromUTF8(data, size);
return 0;
}
PIHTTPClient * PIHTTPClient::create(const PIString & url_, PIHTTP::Method method, const PIHTTP::MessageConst & req) {
PIHTTPClient * ret = new PIHTTPClient();
static_cast<PIHTTP::MessageConst &>(ret->request) = req;
ret->request.setMethod(method);
ret->url = url_;
return ret;
}
PIHTTPClient * PIHTTPClient::onFinish(std::function<void()> f) {
return onFinish([f](const PIHTTP::MessageConst &) { f(); });
}
PIHTTPClient * PIHTTPClient::onFinish(std::function<void(const PIHTTP::MessageConst &)> f) {
on_finish = f;
return this;
}
PIHTTPClient * PIHTTPClient::onError(std::function<void()> f) {
return onError([f](const PIHTTP::MessageConst &) { f(); });
}
PIHTTPClient * PIHTTPClient::onError(std::function<void(const PIHTTP::MessageConst &)> f) {
on_error = f;
return this;
}
PIHTTPClient * PIHTTPClient::onAbort(std::function<void()> f) {
return onAbort([f](const PIHTTP::MessageConst &) { f(); });
}
PIHTTPClient * PIHTTPClient::onAbort(std::function<void(const PIHTTP::MessageConst &)> f) {
on_abort = f;
return this;
}
void PIHTTPClient::start() {
CurlThreadPool::instance()->registerClient(this);
}
void PIHTTPClient::abort() {
is_cancel = true;
}
int PIHTTPClientBase::__infoFunc(ssize_t dltotal, ssize_t dlnow, ssize_t ultotal, ssize_t ulnow) {
return reinterpret_cast<PIHTTPClient *>(this)->infoFunc(dltotal, dlnow, ultotal, ulnow);
}
int PIHTTPClientBase::__debugFunc(int type, char * data, size_t size) {
return reinterpret_cast<PIHTTPClient *>(this)->debugFunc(type, data, size);
}

View File

@@ -1,4 +1,5 @@
#include "microhttpd_server.h" #include "microhttpd_server.h"
#include "piliterals_bytes.h"
#include "piliterals_string.h" #include "piliterals_string.h"
#include "piliterals_time.h" #include "piliterals_time.h"
@@ -29,13 +30,23 @@
// clang-format on // clang-format on
struct MicrohttpdServerConnection { using namespace PIHTTP;
bool ready();
int send_reply(const MicrohttpdServer::Reply & r);
int send_error();
bool done = false;
MicrohttpdServer::Method method = MicrohttpdServer::Method::Unknown; struct BasicAuthCred {
bool exists = false;
PIString user;
PIString pass;
};
struct MicrohttpdServerConnection {
bool checkBasicAuth();
bool ready();
int sendReply(const MessageMutable & r);
BasicAuthCred getBasicAuthCred();
bool done = false, authorized = false;
Method method = Method::Unknown;
PIString path; PIString path;
PIByteArray body; PIByteArray body;
PIMap<PIString, PIString> headers, args, post; PIMap<PIString, PIString> headers, args, post;
@@ -45,52 +56,85 @@ struct MicrohttpdServerConnection {
}; };
bool MicrohttpdServerConnection::checkBasicAuth() {
if (headers.contains(Header::Authorization)) {
auto ba_up = getBasicAuthCred();
bool ok = false; // server->callback_auth(ba_up.user, ba_up.pass);
if (server->callback_auth) ok = server->callback_auth(ba_up.user, ba_up.pass);
if (ok) {
authorized = true;
return true;
}
}
// piCout << "miss authorization";
sendReply(MessageMutable::fromCode(Code::Unauthorized)
.addHeader(Header::WWWAuthenticate, "Basic realm=\"%1\", charset=\"UTF-8\""_a.arg(server->realm))
.setBody(PIByteArray::fromAscii("Authorization required")));
// piCout << "answer sent";
return false;
}
bool MicrohttpdServerConnection::ready() { bool MicrohttpdServerConnection::ready() {
if (!server) return false; if (!server) return false;
if (done) return true; if (done) return true;
done = true; done = true;
MicrohttpdServer::Reply rep; MessageMutable rep;
if (method == MicrohttpdServer::Method::Get) { if (method == Method::Get) {
if (path == "/favicon.ico"_a) { if (path == "/favicon.ico"_a) {
// piCout << "send favicon" << server->favicon.size() << "bytes"; // piCout << "send favicon" << server->favicon.size() << "bytes";
rep.setBody(server->favicon); rep.setBody(server->favicon);
send_reply(rep); sendReply(rep);
return true; return true;
} }
} }
// piCout << "ready" << (int)method << path; // piCout << "ready" << (int)method << path << body.size();
MicrohttpdServer::Request req; MessageMutable req;
req.method = method; req.setMethod(method);
req.path = path; req.setPath(path);
req.body = body; req.setBody(body);
req.headers = headers; req.headers() = headers;
req.args = args; req.arguments() = args;
rep.setCode(MHD_HTTP_BAD_REQUEST); rep.setCode(Code::BadRequest);
if (server->callback) rep = server->callback(req); if (server->callback) rep = server->callback(req);
rep.addFixedHeaders(); MicrohttpdServer::addFixedHeaders(rep);
send_reply(rep); sendReply(rep);
// piCout << "ready ok" << (int)rep.code() << rep.body().size();
return true; return true;
} }
int MicrohttpdServerConnection::send_reply(const MicrohttpdServer::Reply & r) { int MicrohttpdServerConnection::sendReply(const MessageMutable & r) {
MHD_Response * response = MHD_create_response_from_buffer(r.body.size(), (void *)r.body.data(), MHD_RESPMEM_MUST_COPY); MHD_Response * response = MHD_create_response_from_buffer(r.body().size(), (void *)r.body().data(), MHD_RESPMEM_MUST_COPY);
if (!response) { if (!response) {
// piCout << "null response" << r.body.size() << (void *)r.body.data(); // piCout << "null response" << r.body.size() << (void *)r.body.data();
return MHD_NO; return MHD_NO;
} }
auto it = r.headers.makeIterator(); auto it = r.headers().makeIterator();
while (it.next()) while (it.next())
MHD_add_response_header(response, it.key().dataAscii(), it.value().dataUTF8()); MHD_add_response_header(response, it.key().dataAscii(), it.value().dataUTF8());
// piCout << "status" << r.code; // piCout << "status" << r.code;
int ret = MHD_queue_response(connection, r.code, response); int ret = MHD_queue_response(connection, static_cast<int>(r.code()), response);
MHD_destroy_response(response); MHD_destroy_response(response);
return ret; return ret;
} }
int MicrohttpdServerConnection::send_error() { BasicAuthCred MicrohttpdServerConnection::getBasicAuthCred() {
return MHD_queue_response(connection, MHD_HTTP_BAD_REQUEST, MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_MUST_COPY)); BasicAuthCred ret;
char * p = nullptr;
auto u = MHD_basic_auth_get_username_password(connection, &p);
if (u) {
ret.user = PIString::fromUTF8(u);
ret.exists = true;
MHD_free(u);
}
if (p) {
ret.pass = PIString::fromUTF8(p);
ret.exists = true;
MHD_free(p);
}
return ret;
} }
@@ -98,9 +142,9 @@ void log_callback(void * cls, const char * fmt, va_list ap) {
MicrohttpdServer * server = (MicrohttpdServer *)cls; MicrohttpdServer * server = (MicrohttpdServer *)cls;
piCout << "log" << server; piCout << "log" << server;
if (!server) return; if (!server) return;
char buffer[1024]; char buffer[1_KiB];
memset(buffer, 0, 1024); memset(buffer, 0, 1_KiB);
std::vsnprintf(buffer, 1024, fmt, ap); std::vsnprintf(buffer, 1_KiB, fmt, ap);
piCout << buffer; piCout << buffer;
} }
@@ -150,38 +194,38 @@ int args_iterate(void * cls, MHD_ValueKind kind, const char * key, const char *
} }
int answer_to_connection(void * cls, int answer_callback(void * cls,
MHD_Connection * connection, MHD_Connection * connection,
const char * url, const char * url,
const char * method, const char * method,
const char * version, const char * version,
const char * upload_data, const char * upload_data,
size_t * upload_data_size, size_t * upload_data_size,
void ** con_cls) { void ** con_cls) {
MicrohttpdServer * server = (MicrohttpdServer *)cls; MicrohttpdServer * server = (MicrohttpdServer *)cls;
MicrohttpdServer::Method m = MicrohttpdServer::Method::Unknown; Method m = Method::Unknown;
if (0 == strcmp(method, "GET")) if (0 == strcmp(method, "GET"))
m = MicrohttpdServer::Method::Get; m = Method::Get;
else if (0 == strcmp(method, "POST")) else if (0 == strcmp(method, "POST"))
m = MicrohttpdServer::Method::Post; m = Method::Post;
else if (0 == strcmp(method, "HEAD")) else if (0 == strcmp(method, "HEAD"))
m = MicrohttpdServer::Method::Head; m = Method::Head;
else if (0 == strcmp(method, "PUT")) else if (0 == strcmp(method, "PUT"))
m = MicrohttpdServer::Method::Put; m = Method::Put;
else if (0 == strcmp(method, "DELETE")) else if (0 == strcmp(method, "DELETE"))
m = MicrohttpdServer::Method::Delete; m = Method::Delete;
else if (0 == strcmp(method, "CONNECT")) else if (0 == strcmp(method, "CONNECT"))
m = MicrohttpdServer::Method::Connect; m = Method::Connect;
else if (0 == strcmp(method, "OPTIONS")) else if (0 == strcmp(method, "OPTIONS"))
m = MicrohttpdServer::Method::Options; m = Method::Options;
else if (0 == strcmp(method, "TRACE")) else if (0 == strcmp(method, "TRACE"))
m = MicrohttpdServer::Method::Trace; m = Method::Trace;
else if (0 == strcmp(method, "PATCH")) else if (0 == strcmp(method, "PATCH"))
m = MicrohttpdServer::Method::Patch; m = Method::Patch;
if (m == MicrohttpdServer::Method::Unknown) { if (m == Method::Unknown) {
piCout << "[MicrohttpdServer]" piCout << "[MicrohttpdServer]"
<< "Warning:" << "Warning:"
<< "Unknown method!"; << "Unknown method!";
@@ -198,23 +242,27 @@ int answer_to_connection(void * cls,
conn->method = m; conn->method = m;
MHD_get_connection_values(connection, MHD_HEADER_KIND, (MHD_KeyValueIterator)header_iterate, *con_cls); MHD_get_connection_values(connection, MHD_HEADER_KIND, (MHD_KeyValueIterator)header_iterate, *con_cls);
MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, (MHD_KeyValueIterator)args_iterate, *con_cls); MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, (MHD_KeyValueIterator)args_iterate, *con_cls);
if (server->isBasicAuthEnabled() && !conn->authorized) {
if (!conn->checkBasicAuth()) return MHD_YES;
}
return MHD_YES; return MHD_YES;
} }
if (m == MicrohttpdServer::Method::Unknown) { if (m == Method::Unknown) {
return conn->send_error(); return conn->sendReply(MessageMutable::fromCode(Code::MethodNotAllowed));
} }
if (*upload_data_size) { if (*upload_data_size) {
if (!conn->postprocessor) { if (!conn->postprocessor) {
conn->postprocessor = MHD_create_post_processor(connection, 65536, (MHD_PostDataIterator)iterate_post, (void *)conn); conn->postprocessor = MHD_create_post_processor(connection, 64_KiB, (MHD_PostDataIterator)iterate_post, (void *)conn);
} }
conn->body.append(upload_data, *upload_data_size); conn->body.append(upload_data, *upload_data_size);
MHD_post_process(conn->postprocessor, upload_data, *upload_data_size); MHD_post_process(conn->postprocessor, upload_data, *upload_data_size);
*upload_data_size = 0; *upload_data_size = 0;
} else { } else {
// qDebug() << "answer ok"; // qDebug() << "answer ok";
if (!conn->ready()) return conn->send_error(); if (!conn->ready()) return conn->sendReply(MessageMutable::fromCode(Code::InternalServerError));
} }
return MHD_YES; return MHD_YES;
} }
@@ -229,6 +277,7 @@ MicrohttpdServer::MicrohttpdServer() {
PRIVATE->daemon = nullptr; PRIVATE->daemon = nullptr;
opts[Option::ConnectionLimit] = FD_SETSIZE - 4; opts[Option::ConnectionLimit] = FD_SETSIZE - 4;
opts[Option::ConnectionTimeout] = 0_s; opts[Option::ConnectionTimeout] = 0_s;
realm = "Restricted"_a;
} }
@@ -283,7 +332,7 @@ bool MicrohttpdServer::listen(PINetworkAddress addr) {
addr.port(), addr.port(),
nullptr, nullptr,
nullptr, nullptr,
(MHD_AccessHandlerCallback)answer_to_connection, (MHD_AccessHandlerCallback)answer_callback,
this, this,
MHD_OPTION_ARRAY, MHD_OPTION_ARRAY,
options.data(), options.data(),
@@ -305,34 +354,14 @@ void MicrohttpdServer::stop() {
} }
void MicrohttpdServer::Reply::addHeader(const PIString & header, const PIString & value) { void MicrohttpdServer::addFixedHeaders(MessageMutable & msg) {
headers[header] = value; if (!msg.headers().contains(Header::ContentType)) {
} if (msg.body().isNotEmpty()) {
if (msg.body().startsWith(PIByteArray::fromAscii("<!DOCTYPE html>")))
msg.addHeader(Header::ContentType, "text/html; charset=utf-8");
void MicrohttpdServer::Reply::removeHeader(const PIString & header) { else if (msg.body()[0] == '[' || msg.body()[0] == '{')
headers.remove(header); msg.addHeader(Header::ContentType, "application/json; charset=utf-8");
}
void MicrohttpdServer::Reply::setBody(const PIByteArray & b) {
body = b;
}
void MicrohttpdServer::Reply::setCode(int c) {
code = c;
}
void MicrohttpdServer::Reply::addFixedHeaders() {
if (!headers.contains(MHD_HTTP_HEADER_CONTENT_TYPE)) {
if (body.isNotEmpty()) {
if (body.startsWith(PIByteArray::fromAscii("<!DOCTYPE html>")))
addHeader(MHD_HTTP_HEADER_CONTENT_TYPE, "text/html; charset=utf-8");
else if (body[0] == '[' || body[0] == '{')
addHeader(MHD_HTTP_HEADER_CONTENT_TYPE, "application/json; charset=utf-8");
} }
} }
addHeader(MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, "*"); msg.addHeader(Header::AccessControlAllowOrigin, "*");
} }

View File

@@ -4,29 +4,29 @@
PIHTTPServer::PIHTTPServer() { PIHTTPServer::PIHTTPServer() {
setRequestCallback([this](const MicrohttpdServer::Request & r) -> MicrohttpdServer::Reply { setRequestCallback([this](const PIHTTP::MessageConst & r) -> PIHTTP::MessageMutable {
MicrohttpdServer::Reply rep; PIHTTP::MessageMutable reply;
rep.setCode(404); reply.setCode(PIHTTP::Code::NotFound);
auto in_path = r.path.split("/"); auto in_path = r.path().split("/");
in_path.removeAll(""); in_path.removeAll("");
auto it = functions.makeReverseIterator(); auto it = functions.makeReverseIterator();
bool found = false; bool found = false;
while (it.next()) { while (it.next()) {
if (it.value().function) { if (it.value().function) {
if (it.value().method == r.method) { if (it.value().method == r.method()) {
if (it.value().match(in_path)) { if (it.value().match(in_path)) {
rep = it.value().function(r); reply = it.value().function(r);
found = true; found = true;
break; break;
} }
} }
} }
} }
if (!found && unhandled) rep = unhandled(r); if (!found && unhandled) reply = unhandled(r);
auto hit = reply_headers.makeIterator(); auto hit = reply_headers.makeIterator();
while (hit.next()) while (hit.next())
rep.addHeader(hit.key(), hit.value()); reply.addHeader(hit.key(), hit.value());
return rep; return reply;
}); });
} }
@@ -36,8 +36,8 @@ PIHTTPServer::~PIHTTPServer() {
} }
void PIHTTPServer::registerPath(const PIString & path, Method method, RequestFunction functor) { void PIHTTPServer::registerPath(const PIString & path, PIHTTP::Method method, RequestFunction functor) {
auto & ep(functions[path + PIString::fromNumber((int)method)]); auto & ep(functions[path + PIString::fromNumber(static_cast<int>(method))]);
ep.path = path.split("/"); ep.path = path.split("/");
ep.method = method; ep.method = method;
ep.function = functor; ep.function = functor;
@@ -50,7 +50,7 @@ void PIHTTPServer::registerUnhandled(RequestFunction functor) {
} }
void PIHTTPServer::unregisterPath(const PIString & path, Method method) { void PIHTTPServer::unregisterPath(const PIString & path, PIHTTP::Method method) {
auto pl = path.split("/"); auto pl = path.split("/");
pl.removeAll(""); pl.removeAll("");
auto it = functions.makeIterator(); auto it = functions.makeIterator();

View File

@@ -181,14 +181,14 @@ void PISystemMonitor::run() {
__PIThreadCollection * pitc = __PIThreadCollection::instance(); __PIThreadCollection * pitc = __PIThreadCollection::instance();
pitc->lock(); pitc->lock();
PIVector<PIThread *> tv = pitc->threads(); PIVector<PIThread *> tv = pitc->threads();
piForeach(PIThread * t, tv) for (auto * t: tv)
if (t->isPIObject()) tbid[t->tid()] = t->name(); if (t->isPIObject()) tbid[t->tid()] = t->name();
pitc->unlock(); pitc->unlock();
// piCout << tbid.keys().toType<uint>(); // piCout << tbid.keys().toType<uint>();
ProcessStats tstat; ProcessStats tstat;
tstat.ID = pID_; tstat.ID = pID_;
#ifdef MICRO_PIP #ifdef MICRO_PIP
piForeach(PIThread * t, tv) for (auto * t: tv)
if (t->isPIObject()) gatherThread(t->tid()); if (t->isPIObject()) gatherThread(t->tid());
#else #else
# ifndef WINDOWS # ifndef WINDOWS
@@ -260,7 +260,7 @@ void PISystemMonitor::run() {
tstat.physical_memsize = tstat.resident_memsize - tstat.share_memsize; tstat.physical_memsize = tstat.resident_memsize - tstat.share_memsize;
PIVector<PIFile::FileInfo> tld = PIDir(PRIVATE->proc_dir + "task").entries(); PIVector<PIFile::FileInfo> tld = PIDir(PRIVATE->proc_dir + "task").entries();
piForeachC(PIFile::FileInfo & i, tld) { for (const auto & i: tld) {
if (i.flags[PIFile::FileInfo::Dot] || i.flags[PIFile::FileInfo::DotDot]) continue; if (i.flags[PIFile::FileInfo::Dot] || i.flags[PIFile::FileInfo::DotDot]) continue;
gatherThread(i.name().toInt()); gatherThread(i.name().toInt());
} }

View File

@@ -23,14 +23,14 @@
PIString PICodeInfo::EnumInfo::memberName(int value_) const { PIString PICodeInfo::EnumInfo::memberName(int value_) const {
piForeachC(PICodeInfo::EnumeratorInfo & e, members) for (const auto & e: members)
if (e.value == value_) return e.name.toString(); if (e.value == value_) return e.name.toString();
return PIString(); return PIString();
} }
int PICodeInfo::EnumInfo::memberValue(const PIString & name_) const { int PICodeInfo::EnumInfo::memberValue(const PIString & name_) const {
piForeachC(PICodeInfo::EnumeratorInfo & e, members) for (const auto & e: members)
if (e.name.toString() == name_) return e.value; if (e.name.toString() == name_) return e.value;
return -1; return -1;
} }

View File

@@ -86,55 +86,55 @@ void PICodeParser::parseFile(const PIString & file, bool follow_includes) {
clear(); clear();
parseFileInternal(file, follow_includes); parseFileInternal(file, follow_includes);
/*piCout << "\n\n"; /*piCout << "\n\n";
piForeachC (Entity * c, entities) { for (const auto * c: entities) {
piCout << ""; piCout << "";
piCout << c->type << c->name << c->parent_scope << c->parents << c->children << c->meta; piCout << c->type << c->name << c->parent_scope << c->parents << c->children << c->meta;
if (c->parent_scope) if (c->parent_scope)
piCout << "parent" << c->parent_scope->name; piCout << "parent" << c->parent_scope->name;
piCout << "Functions:"; piCout << "Functions:";
piForeachC (Member & m, c->functions) for (const auto & m: c->functions)
piCout << m.type << m.name << m.meta; piCout << m.type << m.name << m.meta;
piCout << "Members:"; piCout << "Members:";
piForeachC (Member & m, c->members) for (const auto & m: c->members)
piCout << m.type << m.name << m.meta; piCout << m.type << m.name << m.meta;
} }
piCout << "\n\nDefines:"; piCout << "\n\nDefines:";
piForeachC (Define & m, defines) for (const auto & m: defines)
piCout << PIStringAscii("define") << m.first << m.second; piCout << PIStringAscii("define") << m.first << m.second;
piCout << "\n\nMacros:"; piCout << "\n\nMacros:";
piForeachC (Macro & m, macros) for (const auto & m: macros)
piCout << "Macro:" << m.name << m.args << m.value; piCout << "Macro:" << m.name << m.args << m.value;
piCout << "\n\nClasses:"; piCout << "\n\nClasses:";
piCout << "\n\nEnums:"; piCout << "\n\nEnums:";
piForeachC (Enum & c, enums) { for (const auto & c: enums) {
piCout << PIStringAscii("enum") << c.name << c.meta; piCout << PIStringAscii("enum") << c.name << c.meta;
piForeachC (EnumeratorInfo & e, c.members) for (const auto & e: c.members)
piCout << " " << e.name << '=' << e.value << e.meta; piCout << " " << e.name << '=' << e.value << e.meta;
} }
piCout << "\n\nTypedefs:"; piCout << "\n\nTypedefs:";
piForeachC (Typedef & c, typedefs) for (const auto & c: typedefs)
piCout << PIStringAscii("typedef") << c;*/ piCout << PIStringAscii("typedef") << c;*/
} }
void PICodeParser::parseFiles(const PIStringList & files, bool follow_includes) { void PICodeParser::parseFiles(const PIStringList & files, bool follow_includes) {
clear(); clear();
piForeachC(PIString & f, files) for (const auto & f: files)
parseFileInternal(f, follow_includes); parseFileInternal(f, follow_includes);
/*piCout << "\n\nDefines:"; /*piCout << "\n\nDefines:";
piForeachC (Define & m, defines) for (const auto & m: defines)
piCout << PIStringAscii("define") << m.first << m.second; piCout << PIStringAscii("define") << m.first << m.second;
piCout << "\n\nMacros:"; piCout << "\n\nMacros:";
piForeachC (Macro & m, macros) for (const auto & m: macros)
piCout << "Macro:" << m.name << m.args << m.value; piCout << "Macro:" << m.name << m.args << m.value;
piCout << "\n\nClasses:"; piCout << "\n\nClasses:";
piForeachC (Entity * c, entities) for (const auto * c: entities)
piCout << PIStringAscii("class") << c->name << c->parents; piCout << PIStringAscii("class") << c->name << c->parents;
piCout << "\n\nEnums:"; piCout << "\n\nEnums:";
piForeachC (Enum & c, enums) for (const auto & c: enums)
piCout << PIStringAscii("enum") << c.name << c.members; piCout << PIStringAscii("enum") << c.name << c.members;
piCout << "\n\nTypedefs:"; piCout << "\n\nTypedefs:";
piForeachC (Typedef & c, typedefs) for (const auto & c: typedefs)
piCout << PIStringAscii("typedef") << c;*/ piCout << PIStringAscii("typedef") << c;*/
} }
@@ -145,7 +145,7 @@ void PICodeParser::parseFileContent(PIString fc) {
bool PICodeParser::isEnum(const PIString & name) { bool PICodeParser::isEnum(const PIString & name) {
piForeachC(Enum & e, enums) for (const auto & e: enums)
if (e.name == name) return true; if (e.name == name) return true;
return false; return false;
} }
@@ -179,7 +179,7 @@ bool PICodeParser::parseFileInternal(const PIString & file, bool follow_includes
void PICodeParser::clear() { void PICodeParser::clear() {
piForeach(Entity * i, entities) for (auto * i: entities)
delete i; delete i;
defines.clear(); defines.clear();
macros.clear(); macros.clear();
@@ -193,7 +193,7 @@ void PICodeParser::clear() {
cur_def_vis = Global; cur_def_vis = Global;
anon_num = 0; anon_num = 0;
PIStringList defs = PIStringAscii(PICODE_DEFINES).split(","); PIStringList defs = PIStringAscii(PICODE_DEFINES).split(",");
piForeachC(PIString & d, defs) for (const auto & d: defs)
defines << Define(d, ""); defines << Define(d, "");
defines << Define(PIStringAscii("PICODE"), "") << custom_defines; defines << Define(PIStringAscii("PICODE"), "") << custom_defines;
macros << Macro(PIStringAscii("PIOBJECT"), "", PIStringList() << "name") macros << Macro(PIStringAscii("PIOBJECT"), "", PIStringList() << "name")
@@ -406,7 +406,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
} }
replaced_cnt++; replaced_cnt++;
replaced = false; replaced = false;
piForeachC(Define & d, defines) { for (const auto & d: defines) {
int ind(-1); int ind(-1);
while ((ind = pfc.find(d.first, ind + 1)) >= 0) { while ((ind = pfc.find(d.first, ind + 1)) >= 0) {
PIChar pc, nc; PIChar pc, nc;
@@ -418,7 +418,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
replaced = true; replaced = true;
} }
} }
piForeachC(Macro & m, macros) { for (const auto & m: macros) {
int ind(-1); int ind(-1);
while ((ind = pfc.find(m.name, ind + 1)) >= 0) { while ((ind = pfc.find(m.name, ind + 1)) >= 0) {
PIChar pc, nc; PIChar pc, nc;
@@ -550,7 +550,7 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc)
PIStringList pl = cd.takeMid(ind + 1).trim().split(','); PIStringList pl = cd.takeMid(ind + 1).trim().split(',');
cd.cutRight(1); cd.cutRight(1);
Entity * pe = 0; Entity * pe = 0;
piForeachC(PIString & p, pl) { for (const auto & p: pl) {
if (p.contains(' ')) if (p.contains(' '))
pn = p.mid(p.find(' ') + 1); pn = p.mid(p.find(' ') + 1);
else else
@@ -717,7 +717,7 @@ PICodeParser::MetaMap PICodeParser::parseMeta(PIString & fc) {
PICodeParser::MetaMap ret; PICodeParser::MetaMap ret;
if (fc.isEmpty()) return ret; if (fc.isEmpty()) return ret;
PIStringList ml = fc.split(','); PIStringList ml = fc.split(',');
piForeachC(PIString & m, ml) { for (const auto & m: ml) {
int i = m.find('='); int i = m.find('=');
if (i < 0) { if (i < 0) {
ret[m.trimmed()] = PIString(); ret[m.trimmed()] = PIString();
@@ -742,7 +742,7 @@ bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc
PIStringList vl(fc.split(',')); PIStringList vl(fc.split(','));
PIString vn; PIString vn;
int cv = -1, ind = 0; int cv = -1, ind = 0;
piForeach(PIString & v, vl) { for (auto & v: vl) {
MetaMap meta; MetaMap meta;
int mi = v.find(s_M); int mi = v.find(s_M);
if (mi >= 0) { if (mi >= 0) {
@@ -872,7 +872,7 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
normalizeEntityNamespace(me.type); normalizeEntityNamespace(me.type);
int i = 0; int i = 0;
// piCout << me.arguments_full; // piCout << me.arguments_full;
piForeach(PIString & a, me.arguments_full) for (auto & a: me.arguments_full)
if ((i = a.find('=')) > 0) a.cutRight(a.size_s() - i).trim(); if ((i = a.find('=')) > 0) a.cutRight(a.size_s() - i).trim();
for (int j = 0; j < me.arguments_full.size_s(); ++j) for (int j = 0; j < me.arguments_full.size_s(); ++j)
if (me.arguments_full[j] == s_void) { if (me.arguments_full[j] == s_void) {
@@ -880,7 +880,7 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
--j; --j;
} }
me.arguments_type = me.arguments_full; me.arguments_type = me.arguments_full;
piForeach(PIString & a, me.arguments_type) { for (auto & a: me.arguments_type) {
crepl.clear(); 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) for (ts = a.size_s() - 1; ts >= 0; --ts)
@@ -902,7 +902,7 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
// piCout << "member" << fc << tl; // piCout << "member" << fc << tl;
// piCout << "member after eb" << fc << ", bits =" << bits; // piCout << "member after eb" << fc << ", bits =" << bits;
if (tl.isEmpty()) return true; if (tl.isEmpty()) return true;
piForeach(PIString & v, tl) for (auto & v: tl)
removeAssignment(v); removeAssignment(v);
bool vn = true; bool vn = true;
ctemp = tl.front().trim(); ctemp = tl.front().trim();
@@ -947,7 +947,7 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
normalizeEntityNamespace(type); normalizeEntityNamespace(type);
tl[0] = ctemp.trim(); tl[0] = ctemp.trim();
// piCout << "vars" << tl; // piCout << "vars" << tl;
piForeachC(PIString & v, tl) { for (const auto & v: tl) {
crepl.clear(); crepl.clear();
me.name = v.trimmed(); me.name = v.trimmed();
@@ -1025,7 +1025,7 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) {
} }
n.trim(); n.trim();
int f = 0; int f = 0;
piForeachC(Entity * e, entities) { for (const auto * e: entities) {
if (e->name == n) { if (e->name == n) {
n = (pref + n + suff).trim(); n = (pref + n + suff).trim();
return; return;
@@ -1037,7 +1037,7 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) {
return; return;
} }
} }
piForeachC(Enum & e, enums) { for (const auto & e: enums) {
if ((f = e.name.find(n)) >= 0) if ((f = e.name.find(n)) >= 0)
if (e.name.at(f - 1) == PIChar(':')) if (e.name.at(f - 1) == PIChar(':'))
if (e.name.find(cur_namespace) >= 0) { if (e.name.find(cur_namespace) >= 0) {
@@ -1046,7 +1046,7 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) {
return; return;
} }
} }
piForeachC(Typedef & e, typedefs) { for (const auto & e: typedefs) {
if ((f = e.first.find(n)) >= 0) if ((f = e.first.find(n)) >= 0)
if (e.first.at(f - 1) == PIChar(':')) if (e.first.at(f - 1) == PIChar(':'))
if (e.first.find(cur_namespace) >= 0) { if (e.first.find(cur_namespace) >= 0) {
@@ -1062,11 +1062,11 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) {
void PICodeParser::restoreTmpTemp(Member * e) { void PICodeParser::restoreTmpTemp(Member * e) {
static const PIString s_T = PIStringAscii("$T"); static const PIString s_T = PIStringAscii("$T");
int i = 0; int i = 0;
piForeach(PIString & a, e->arguments_full) { for (auto & a: e->arguments_full) {
while ((i = a.find(s_T)) >= 0) while ((i = a.find(s_T)) >= 0)
a.replace(i, 5, tmp_temp[a.mid(i, 5)]); a.replace(i, 5, tmp_temp[a.mid(i, 5)]);
} }
piForeach(PIString & a, e->arguments_type) { for (auto & a: e->arguments_type) {
while ((i = a.find(s_T)) >= 0) while ((i = a.find(s_T)) >= 0)
a.replace(i, 5, tmp_temp[a.mid(i, 5)]); a.replace(i, 5, tmp_temp[a.mid(i, 5)]);
} }
@@ -1167,7 +1167,7 @@ double PICodeParser::procMacrosCond(PIString fc) {
bool PICodeParser::isDefineExists(const PIString & dn) { bool PICodeParser::isDefineExists(const PIString & dn) {
piForeachC(Define & d, defines) { for (const auto & d: defines) {
if (d.first == dn) return true; if (d.first == dn) return true;
} }
return false; return false;
@@ -1175,7 +1175,7 @@ bool PICodeParser::isDefineExists(const PIString & dn) {
double PICodeParser::defineValue(const PIString & dn) { double PICodeParser::defineValue(const PIString & dn) {
piForeachC(Define & d, defines) { for (const auto & d: defines) {
if (d.first == dn) return d.second.isEmpty() ? 1. : d.second.toDouble(); if (d.first == dn) return d.second.isEmpty() ? 1. : d.second.toDouble();
} }
return dn.toDouble(); return dn.toDouble();
@@ -1203,7 +1203,7 @@ void PICodeParser::replaceMeta(PIString & dn) {
PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) { PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) {
piForeach(Entity * e, entities) for (auto * e: entities)
if (e->name == en) return e; if (e->name == en) return e;
return 0; return 0;
} }

View File

@@ -19,8 +19,24 @@
#include "picontainers.h" #include "picontainers.h"
#include "piliterals_bytes.h"
const size_t minAlloc = 64;
#if defined(PIP_CONTAINERS_MIN_ALLOC)
# define ACTUAL_MIN_ALLOC PIP_CONTAINERS_MIN_ALLOC
#else
# define ACTUAL_MIN_ALLOC 64
#endif
#if defined(PIP_CONTAINERS_MAX_POT_ALLOC)
# define ACTUAL_MAX_POT_ALLOC PIP_CONTAINERS_MAX_POT_ALLOC
#else
# define ACTUAL_MAX_POT_ALLOC 64_MiB
#endif
const size_t minAlloc = ACTUAL_MIN_ALLOC;
const size_t maxPoTAlloc = ACTUAL_MAX_POT_ALLOC;
size_t _PIContainerConstantsBase::calcMinCountPoT(size_t szof) { size_t _PIContainerConstantsBase::calcMinCountPoT(size_t szof) {
@@ -33,3 +49,15 @@ size_t _PIContainerConstantsBase::calcMinCountPoT(size_t szof) {
// printf("calcMinCount sizeof = %d, min_count = %d, pot = %d\n", szof, elc, ret); // printf("calcMinCount sizeof = %d, min_count = %d, pot = %d\n", szof, elc, ret);
return ret; return ret;
} }
size_t _PIContainerConstantsBase::calcMaxCountForPoT(size_t szof) {
// printf("calcMaxCountForPoT sizeof = %d, size = %d\n", szof, maxPoTAlloc / szof);
return maxPoTAlloc / szof;
}
size_t _PIContainerConstantsBase::calcStepAfterPoT(size_t szof) {
// printf("calcStepAfterPoT sizeof = %d, size = %d\n", szof, calcMaxCountForPoT(szof));
return calcMaxCountForPoT(szof);
}

View File

@@ -67,15 +67,48 @@ private:
class PIP_EXPORT _PIContainerConstantsBase { class PIP_EXPORT _PIContainerConstantsBase {
public: public:
static size_t calcMinCountPoT(size_t szof); static size_t calcMinCountPoT(size_t szof);
static size_t calcMaxCountForPoT(size_t szof);
static size_t calcStepAfterPoT(size_t szof);
}; };
template<typename T> template<typename T>
class _PIContainerConstants { class _PIContainerConstants {
public: public:
// minimum elements for container
static size_t minCountPoT() { static size_t minCountPoT() {
static const size_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T)); static const size_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T));
return ret; return ret;
} }
// maximum elements for 2^n growth
static size_t maxCountForPoT() {
static const size_t ret = _PIContainerConstantsBase::calcMaxCountForPoT(sizeof(T));
return ret;
}
// add elements after 2^n growth
static size_t stepAfterPoT() {
static const size_t ret = _PIContainerConstantsBase::calcStepAfterPoT(sizeof(T));
return ret;
}
static size_t calcNewSize(size_t old_size, size_t new_size) {
if (new_size == 0) return 0;
if (new_size < maxCountForPoT()) {
if (old_size * 2 >= new_size && old_size < new_size) {
return old_size * 2;
}
ssize_t t = minCountPoT();
new_size -= 1;
while (new_size >> t)
++t;
return (1 << t);
} else {
size_t ret = old_size;
while (ret < new_size)
ret += stepAfterPoT();
return ret;
}
return 0;
}
}; };

View File

@@ -2575,19 +2575,6 @@ private:
pid_data = nullptr; pid_data = nullptr;
} }
inline size_t asize(ssize_t s) {
if (s <= 0) return 0;
if (pid_rsize * 2 >= size_t(s) && pid_rsize < size_t(s)) {
return pid_rsize * 2;
}
size_t t = _PIContainerConstants<T>::minCountPoT();
s -= 1;
while (s >> t) {
++t;
}
return (1 << t);
}
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0> template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
inline void newT(T * dst, const T * src, size_t s) { inline void newT(T * dst, const T * src, size_t s) {
PIINTROSPECTION_CONTAINER_USED(T, s) PIINTROSPECTION_CONTAINER_USED(T, s)
@@ -2682,35 +2669,38 @@ private:
if (pid_start > 0) checkMove(); if (pid_start > 0) checkMove();
return; return;
} }
pid_size = new_size; pid_size = new_size;
const size_t as = asize(pid_start + new_size); const size_t new_rsize = _PIContainerConstants<T>::calcNewSize(pid_rsize, pid_start + new_size);
if (as != pid_rsize) { if (new_rsize != pid_rsize) {
PIINTROSPECTION_CONTAINER_ALLOC(T, (as - pid_rsize)) PIINTROSPECTION_CONTAINER_ALLOC(T, (as - pid_rsize))
T * p_d = reinterpret_cast<T *>(realloc(reinterpret_cast<void *>(pid_data), as * sizeof(T))); T * new_data = reinterpret_cast<T *>(realloc(reinterpret_cast<void *>(pid_data), new_rsize * sizeof(T)));
#ifndef NDEBUG #ifndef NDEBUG
if (!p_d) { if (!new_data) {
fprintf(stderr, "error with PIDeque<%s>::alloc\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>::alloc\n", __PIP_TYPENAME__(T));
} }
#endif #endif
assert(p_d); assert(new_data);
pid_data = p_d; pid_data = new_data;
pid_rsize = as; pid_rsize = new_rsize;
} }
} }
inline void alloc_backward(size_t new_size, ssize_t start_offset = 0) { inline void alloc_backward(size_t new_size, ssize_t start_offset = 0) {
const size_t as = ssize_t(pid_start) + start_offset < 0 ? asize(pid_rsize - start_offset) : pid_rsize; const size_t new_rsize =
if (as > pid_rsize) { ssize_t(pid_start) + start_offset < 0 ? _PIContainerConstants<T>::calcNewSize(pid_rsize, pid_rsize - start_offset) : pid_rsize;
T * td = reinterpret_cast<T *>(malloc(as * sizeof(T))); if (new_rsize > pid_rsize) {
const size_t ns = pid_start + as - pid_rsize; T * tmp_data = reinterpret_cast<T *>(malloc(new_rsize * sizeof(T)));
const size_t new_start = pid_start + new_rsize - pid_rsize;
PIINTROSPECTION_CONTAINER_ALLOC(T, (as - pid_rsize)) PIINTROSPECTION_CONTAINER_ALLOC(T, (as - pid_rsize))
if (pid_rsize > 0 && pid_data != 0) { if (pid_rsize > 0 && pid_data) {
memcpy(reinterpret_cast<void *>(td + ns), reinterpret_cast<const void *>(pid_data + pid_start), pid_size * sizeof(T)); memcpy(reinterpret_cast<void *>(tmp_data + new_start),
reinterpret_cast<const void *>(pid_data + pid_start),
pid_size * sizeof(T));
dealloc(); dealloc();
} }
pid_data = td; pid_data = tmp_data;
pid_rsize = as; pid_rsize = new_rsize;
pid_start = ns; pid_start = new_start;
} }
pid_start += start_offset; pid_start += start_offset;
pid_size = new_size; pid_size = new_size;

View File

@@ -2459,18 +2459,6 @@ private:
piv_data = nullptr; piv_data = nullptr;
} }
inline size_t asize(size_t s) {
if (s == 0) return 0;
if (piv_rsize * 2 >= s && piv_rsize < s) {
return piv_rsize * 2;
}
ssize_t t = _PIContainerConstants<T>::minCountPoT();
s -= 1;
while (s >> t)
++t;
return (1 << t);
}
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0> template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
inline void newT(T * dst, const T * src, size_t s) { inline void newT(T * dst, const T * src, size_t s) {
PIINTROSPECTION_CONTAINER_USED(T, s) PIINTROSPECTION_CONTAINER_USED(T, s)
@@ -2558,19 +2546,19 @@ private:
piv_size = new_size; piv_size = new_size;
return; return;
} }
piv_size = new_size; piv_size = new_size;
const size_t as = asize(new_size); const size_t new_rsize = _PIContainerConstants<T>::calcNewSize(piv_rsize, new_size);
if (as == piv_rsize) return; if (new_rsize == piv_rsize) return;
PIINTROSPECTION_CONTAINER_ALLOC(T, (as - piv_rsize)) PIINTROSPECTION_CONTAINER_ALLOC(T, (as - piv_rsize))
T * p_d = reinterpret_cast<T *>(realloc(reinterpret_cast<void *>(piv_data), as * sizeof(T))); T * new_data = reinterpret_cast<T *>(realloc(reinterpret_cast<void *>(piv_data), new_rsize * sizeof(T)));
#ifndef NDEBUG #ifndef NDEBUG
if (!p_d) { if (!new_data) {
fprintf(stderr, "error with PIVector<%s>::alloc\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>::alloc\n", __PIP_TYPENAME__(T));
} }
#endif #endif
assert(p_d); assert(new_data);
piv_data = p_d; piv_data = new_data;
piv_rsize = as; piv_rsize = new_rsize;
} }
T * piv_data = nullptr; T * piv_data = nullptr;

View File

@@ -40,7 +40,7 @@
PIStringList PICollection::groups() { PIStringList PICollection::groups() {
PIStringList sl; PIStringList sl;
PIVector<PICollection::Group> & cg(_groups()); PIVector<PICollection::Group> & cg(_groups());
piForeachC(Group & g, cg) for (const auto & g: cg)
sl << g.name; sl << g.name;
return sl; return sl;
} }
@@ -48,7 +48,7 @@ PIStringList PICollection::groups() {
PIVector<const PIObject *> PICollection::groupElements(const PIString & group) { PIVector<const PIObject *> PICollection::groupElements(const PIString & group) {
PIVector<PICollection::Group> & cg(_groups()); PIVector<PICollection::Group> & cg(_groups());
piForeachC(Group & g, cg) for (const auto & g: cg)
if (g.name == group) return g.elements; if (g.name == group) return g.elements;
return PIVector<const PIObject *>(); return PIVector<const PIObject *>();
} }
@@ -58,7 +58,7 @@ bool PICollection::addToGroup(const PIString & group, const PIObject * element)
// piCout << "add to" << group << element; // piCout << "add to" << group << element;
PIString n = PIStringAscii(element->className()); PIString n = PIStringAscii(element->className());
PIVector<PICollection::Group> & cg(_groups()); PIVector<PICollection::Group> & cg(_groups());
piForeach(Group & g, cg) for (auto & g: cg)
if (g.name == group) { if (g.name == group) {
for (int i = 0; i < g.elements.size_s(); ++i) for (int i = 0; i < g.elements.size_s(); ++i)
if (PIString(g.elements[i]->className()) == n) return false; if (PIString(g.elements[i]->className()) == n) return false;

View File

@@ -366,7 +366,7 @@ PICout & PICout::operator<<(PIFlags<PICoutManipulators::PICoutFormat> v) {
void PICout::stdoutPIString(const PIString & str, PICoutStdStream s) { void PICout::stdoutPIString(const PIString & str, PICoutStdStream s) {
#ifdef HAS_LOCALE #ifdef HAS_LOCALE
std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> utf8conv; std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf8conv;
getStdStream(s) << utf8conv.to_bytes((char16_t *)&(const_cast<PIString &>(str).front()), getStdStream(s) << utf8conv.to_bytes((char16_t *)&(const_cast<PIString &>(str).front()),
(char16_t *)&(const_cast<PIString &>(str).front()) + str.size()); (char16_t *)&(const_cast<PIString &>(str).front()) + str.size());
#else #else

View File

@@ -177,7 +177,9 @@ public:
private: private:
Notifier(); Notifier();
PIObject * o; NO_COPY_CLASS(Notifier)
PIObject * o = nullptr;
std::atomic_int new_id = {1}; std::atomic_int new_id = {1};
}; };

View File

@@ -32,7 +32,6 @@
# ifdef ESP_PLATFORM # ifdef ESP_PLATFORM
# include "esp_system.h" # include "esp_system.h"
# endif # endif
# include <codecvt>
# ifdef WINDOWS # ifdef WINDOWS
# include <winsock2.h> # include <winsock2.h>
extern FILETIME __pi_ftjan1970; extern FILETIME __pi_ftjan1970;
@@ -108,7 +107,7 @@ PIInit::PIInit() {
PIStringList ifpathes; PIStringList ifpathes;
ifpathes << PIStringAscii("/bin/ifconfig") << PIStringAscii("/sbin/ifconfig") << PIStringAscii("/usr/bin/ifconfig") ifpathes << PIStringAscii("/bin/ifconfig") << PIStringAscii("/sbin/ifconfig") << PIStringAscii("/usr/bin/ifconfig")
<< PIStringAscii("/usr/sbin/ifconfig"); << PIStringAscii("/usr/sbin/ifconfig");
piForeachC(PIString & i, ifpathes) { for (const auto & i: ifpathes) {
if (fileExists(i)) { if (fileExists(i)) {
sinfo->ifconfigPath = i; sinfo->ifconfigPath = i;
break; break;
@@ -149,9 +148,6 @@ PIInit::PIInit() {
} }
currentLocale_t = newlocale(LC_ALL, setlocale(LC_ALL, "C"), 0); currentLocale_t = newlocale(LC_ALL, setlocale(LC_ALL, "C"), 0);
setlocale(LC_CTYPE, "en_US.UTF-8"); setlocale(LC_CTYPE, "en_US.UTF-8");
// std::ios_base::sync_with_stdio(false);
// std::locale utf8( std::locale(), new std::codecvt_utf8<wchar_t> );
// std::wcout.imbue(utf8);
# else // HAS_LOCALE # else // HAS_LOCALE
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
setlocale(LC_NUMERIC, "C"); setlocale(LC_NUMERIC, "C");

View File

@@ -360,9 +360,9 @@ PIObject::Connection PIObject::piConnectU(PIObject * src,
void *addr_src(0), *addr_dest(0); void *addr_src(0), *addr_dest(0);
int args(0); int args(0);
bool que = (performer != 0); bool que = (performer != 0);
piForeachC(__MetaFunc & fs, m_src) { for (const auto & fs: m_src) {
if (addr_src != 0) break; if (addr_src != 0) break;
piForeachC(__MetaFunc & fd, m_dest) { for (const auto & fd: m_dest) {
if (addr_src != 0) break; if (addr_src != 0) break;
if (fs.canConnectTo(fd, args)) { if (fs.canConnectTo(fd, args)) {
addr_src = fs.addr; addr_src = fs.addr;
@@ -477,7 +477,7 @@ void PIObject::piDisconnectAll() {
PIMutexLocker _ml(mutex_connect); PIMutexLocker _ml(mutex_connect);
PIVector<PIObject *> cv = connectors.toVector(); PIVector<PIObject *> cv = connectors.toVector();
// piCout << "disconnect connectors =" << connectors.size(); // piCout << "disconnect connectors =" << connectors.size();
piForeach(PIObject * o, cv) { for (auto * o: cv) {
// piCout << "disconnect"<< src << o; // piCout << "disconnect"<< src << o;
if (!o || (o == this)) continue; if (!o || (o == this)) continue;
if (!o->isPIObject()) continue; if (!o->isPIObject()) continue;
@@ -496,7 +496,7 @@ void PIObject::piDisconnectAll() {
} }
} }
// piCout << "disconnect connections =" << connections.size(); // piCout << "disconnect connections =" << connections.size();
piForeachC(PIObject::Connection & c, connections) { for (const auto & c: connections) {
if (c.functor) continue; if (c.functor) continue;
if (!c.dest_o) continue; if (!c.dest_o) continue;
if (!c.dest_o->isPIObject()) continue; if (!c.dest_o->isPIObject()) continue;
@@ -512,10 +512,10 @@ void PIObject::updateConnectors() {
// piCout << "*** updateConnectors" << this; // piCout << "*** updateConnectors" << this;
connectors.clear(); connectors.clear();
PIMutexLocker _ml(mutexObjects()); PIMutexLocker _ml(mutexObjects());
piForeach(PIObject * o, objects()) { for (auto * o: objects()) {
if (o == this) continue; if (o == this) continue;
PIVector<Connection> & oc(o->connections); PIVector<Connection> & oc(o->connections);
piForeach(Connection & c, oc) for (auto & c: oc)
if (c.dest == this) connectors << o; if (c.dest == this) connectors << o;
} }
} }
@@ -551,7 +551,7 @@ void PIObject::callQueuedEvents() {
PIVector<__QueuedEvent> qe = events_queue; PIVector<__QueuedEvent> qe = events_queue;
events_queue.clear(); events_queue.clear();
mutex_queue.unlock(); mutex_queue.unlock();
piForeachC(__QueuedEvent & e, qe) { for (const auto & e: qe) {
if (e.dest_o->thread_safe_) e.dest_o->mutex_.lock(); if (e.dest_o->thread_safe_) e.dest_o->mutex_.lock();
e.dest_o->emitter_ = e.src; e.dest_o->emitter_ = e.src;
callAddrV(e.slot, e.dest, e.values.size_s(), e.values); callAddrV(e.slot, e.dest, e.values.size_s(), e.values);

View File

@@ -510,7 +510,7 @@ public:
//! Returns PIObject* with name "name" or 0, if there is no object found //! Returns PIObject* with name "name" or 0, if there is no object found
static PIObject * findByName(const PIString & name) { static PIObject * findByName(const PIString & name) {
PIMutexLocker _ml(mutexObjects()); PIMutexLocker _ml(mutexObjects());
piForeach(PIObject * i, PIObject::objects()) { for (auto * i: PIObject::objects()) {
if (i->name() != name) continue; if (i->name() != name) continue;
return i; return i;
} }

View File

@@ -0,0 +1,61 @@
#ifndef pihttpclient_h
#define pihttpclient_h
#include "pihttptypes.h"
#include "pip_http_client_export.h"
class PIHTTPClientBase {
public:
int __infoFunc(ssize_t dltotal, ssize_t dlnow, ssize_t ultotal, ssize_t ulnow);
int __debugFunc(int type, char * data, size_t size);
};
class PIP_HTTP_CLIENT_EXPORT PIHTTPClient: private PIHTTPClientBase {
friend class PIHTTPClientBase;
friend class CurlThreadPool;
public:
static PIHTTPClient * create(const PIString & url, PIHTTP::Method method = PIHTTP::Method::Get, const PIHTTP::MessageConst & req = {});
PIHTTPClient * onFinish(std::function<void()> f);
PIHTTPClient * onFinish(std::function<void(const PIHTTP::MessageConst &)> f);
PIHTTPClient * onError(std::function<void()> f);
PIHTTPClient * onError(std::function<void(const PIHTTP::MessageConst &)> f);
PIHTTPClient * onAbort(std::function<void()> f);
PIHTTPClient * onAbort(std::function<void(const PIHTTP::MessageConst &)> f);
void start();
void abort();
PIString lastError() const { return last_error; }
private:
NO_COPY_CLASS(PIHTTPClient)
PIHTTPClient();
virtual ~PIHTTPClient();
PRIVATE_DECLARATION(PIP_HTTP_CLIENT_EXPORT)
bool init();
void perform();
void procHeaderLine(PIString & line);
static size_t writeMemoryFunc(void * contents, size_t size, size_t nmemb, void * ptr);
static size_t readMemoryFunc(void * contents, size_t size, size_t nmemb, void * ptr);
static size_t headerFunc(char * contents, size_t size, size_t nmemb, void * ptr);
int infoFunc(ssize_t dltotal, ssize_t dlnow, ssize_t ultotal, ssize_t ulnow);
int debugFunc(int type, char * data, size_t size);
PIString url;
PIString last_error;
PIByteArray buffer_out;
PIHTTP::MessageMutable request, reply;
std::atomic_bool is_cancel = {false};
ssize_t read_pos = 0;
std::function<void(const PIHTTP::MessageConst &)> on_finish, on_error, on_abort;
};
#endif

View File

@@ -0,0 +1,54 @@
/*
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 distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//! \defgroup HTTPServer HTTPServer
//! \~\brief
//! \~english HTTP client
//! \~russian HTTP сервер
//!
//! \~\details
//! \~english \section cmake_module_HTTPServer Building with CMake
//! \~russian \section cmake_module_HTTPServer Сборка с использованием CMake
//!
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP::HTTPServer)
//! \endcode
//!
//! \~english \par Common
//! \~russian \par Общее
//!
//! \~english
//! These files provides HTTP server based on libmicrohttpd
//!
//! \~russian
//! Эти файлы обеспечивают HTTP сервер, основанный на libmicrohttpd
//!
//! \~\authors
//! \~english
//! Ivan Pelipenko peri4ko@yandex.ru;
//! \~russian
//! Иван Пелипенко peri4ko@yandex.ru;
//!
#ifndef pihttpclientmodule_H
#define pihttpclientmodule_H
#include "pihttpclient.h"
#endif

View File

@@ -0,0 +1,328 @@
#ifndef pihttpconstants_h
#define pihttpconstants_h
namespace PIHTTP {
enum class Method {
Unknown,
Get,
Head,
Post,
Put,
Delete,
Connect,
Options,
Trace,
Patch
};
enum class Code {
Unknown,
Continue = 100,
SwitchingProtocols = 101,
Processing = 102,
EarlyHints = 103,
Ok = 200,
Created = 201,
Accepted = 202,
NonAuthoritativeInformation = 203,
NoContent = 204,
ResetContent = 205,
PartialContent = 206,
MultiStatus = 207,
AlreadyReported = 208,
IMUsed = 226,
MultipleChoices = 300,
MovedPermanently = 301,
Found = 302,
SeeOther = 303,
NotModified = 304,
UseProxy = 305,
SwitchProxy = 306,
TemporaryRedirect = 307,
PermanentRedirect = 308,
BadRequest = 400,
Unauthorized = 401,
PaymentRequired = 402,
Forbidden = 403,
NotFound = 404,
MethodNotAllowed = 405,
NotAcceptable = 406,
ProxyAuthenticationRequired = 407,
RequestTimeout = 408,
Conflict = 409,
Gone = 410,
LengthRequired = 411,
PreconditionFailed = 412,
ContentTooLarge = 413,
UriTooLong = 414,
UnsupportedMediaType = 415,
RangeNotSatisfiable = 416,
ExpectationFailed = 417,
MisdirectedRequest = 421,
UnprocessableContent = 422,
Locked = 423,
FailedDependency = 424,
TooEarly = 425,
UpgradeRequired = 426,
PreconditionRequired = 428,
TooManyRequests = 429,
RequestHeaderFieldsTooLarge = 431,
RetryWith = 449,
BlockedByWindowsParentalControls = 450,
UnavailableForLegalReasons = 451,
InternalServerError = 500,
NotImplemented = 501,
BadGateway = 502,
ServiceUnavailable = 503,
GatewayTimeout = 504,
HttpVersionNotSupported = 505,
VariantAlsoNegotiates = 506,
InsufficientStorage = 507,
LoopDetected = 508,
NotExtended = 510,
BandwidthLimitExceeded = 509,
NetworkAuthenticationRequired = 511,
};
namespace Header {
constexpr static char Accept[] = "Accept";
constexpr static char AcceptCharset[] = "Accept-Charset";
constexpr static char AcceptEncoding[] = "Accept-Encoding";
constexpr static char AcceptLanguage[] = "Accept-Language";
constexpr static char AcceptRanges[] = "Accept-Ranges";
constexpr static char Age[] = "Age";
constexpr static char Allow[] = "Allow";
constexpr static char AuthenticationInfo[] = "Authentication-Info";
constexpr static char Authorization[] = "Authorization";
constexpr static char CacheControl[] = "Cache-Control";
constexpr static char Close[] = "Close";
constexpr static char Connection[] = "Connection";
constexpr static char ContentEncoding[] = "Content-Encoding";
constexpr static char ContentLanguage[] = "Content-Language";
constexpr static char ContentLength[] = "Content-Length";
constexpr static char ContentLocation[] = "Content-Location";
constexpr static char ContentRange[] = "Content-Range";
constexpr static char ContentType[] = "Content-Type";
constexpr static char Date[] = "Date";
constexpr static char ETag[] = "ETag";
constexpr static char Expect[] = "Expect";
constexpr static char Expires[] = "Expires";
constexpr static char From[] = "From";
constexpr static char Host[] = "Host";
constexpr static char IfMatch[] = "If-Match";
constexpr static char IfModifiedSince[] = "If-Modified-Since";
constexpr static char IfNoneMatch[] = "If-None-Match";
constexpr static char IfRange[] = "If-Range";
constexpr static char IfUnmodifiedSince[] = "If-Unmodified-Since";
constexpr static char LastModified[] = "Last-Modified";
constexpr static char Location[] = "Location";
constexpr static char MaxForwards[] = "Max-Forwards";
constexpr static char MimeVersion[] = "MIME-Version";
constexpr static char Pragma[] = "Pragma";
constexpr static char ProxyAuthenticate[] = "Proxy-Authenticate";
constexpr static char ProxyAuthenticationInfo[] = "Proxy-Authentication-Info";
constexpr static char ProxyAuthorization[] = "Proxy-Authorization";
constexpr static char Range[] = "Range";
constexpr static char Referer[] = "Referer";
constexpr static char RetryAfter[] = "Retry-After";
constexpr static char Server[] = "Server";
constexpr static char TE[] = "TE";
constexpr static char Trailer[] = "Trailer";
constexpr static char TransferEncoding[] = "Transfer-Encoding";
constexpr static char Upgrade[] = "Upgrade";
constexpr static char UserAgent[] = "User-Agent";
constexpr static char Vary[] = "Vary";
constexpr static char Via[] = "Via";
constexpr static char WWWAuthenticate[] = "WWW-Authenticate";
constexpr static char Asterisk[] = "*";
constexpr static char AIM[] = "A-IM";
constexpr static char AcceptAdditions[] = "Accept-Additions";
constexpr static char AcceptCH[] = "Accept-CH";
constexpr static char AcceptDatetime[] = "Accept-Datetime";
constexpr static char AcceptFeatures[] = "Accept-Features";
constexpr static char AcceptPatch[] = "Accept-Patch";
constexpr static char AcceptPost[] = "Accept-Post";
constexpr static char AcceptSignature[] = "Accept-Signature";
constexpr static char AccessControlAllowCredentials[] = "Access-Control-Allow-Credentials";
constexpr static char AccessControlAllowHeaders[] = "Access-Control-Allow-Headers";
constexpr static char AccessControlAllowMethods[] = "Access-Control-Allow-Methods";
constexpr static char AccessControlAllowOrigin[] = "Access-Control-Allow-Origin";
constexpr static char AccessControlExposeHeaders[] = "Access-Control-Expose-Headers";
constexpr static char AccessControlMaxAge[] = "Access-Control-Max-Age";
constexpr static char AccessControlRequestHeaders[] = "Access-Control-Request-Headers";
constexpr static char AccessControlRequestMethod[] = "Access-Control-Request-Method";
constexpr static char ALPN[] = "ALPN";
constexpr static char AltSvc[] = "Alt-Svc";
constexpr static char AltUsed[] = "Alt-Used";
constexpr static char Alternates[] = "Alternates";
constexpr static char ApplyToRedirectRef[] = "Apply-To-Redirect-Ref";
constexpr static char AuthenticationControl[] = "Authentication-Control";
constexpr static char CacheStatus[] = "Cache-Status";
constexpr static char CalManagedID[] = "Cal-Managed-ID";
constexpr static char CalDAVTimezones[] = "CalDAV-Timezones";
constexpr static char CapsuleProtocol[] = "Capsule-Protocol";
constexpr static char CDNCacheControl[] = "CDN-Cache-Control";
constexpr static char CDNLoop[] = "CDN-Loop";
constexpr static char CertNotAfter[] = "Cert-Not-After";
constexpr static char CertNotBefore[] = "Cert-Not-Before";
constexpr static char ClearSiteData[] = "Clear-Site-Data";
constexpr static char ClientCert[] = "Client-Cert";
constexpr static char ClientCertChain[] = "Client-Cert-Chain";
constexpr static char ContentDigest[] = "Content-Digest";
constexpr static char ContentDisposition[] = "Content-Disposition";
constexpr static char ContentID[] = "Content-ID";
constexpr static char ContentSecurityPolicy[] = "Content-Security-Policy";
constexpr static char ContentSecurityPolicyReportOnly[] = "Content-Security-Policy-Report-Only";
constexpr static char Cookie[] = "Cookie";
constexpr static char CrossOriginEmbedderPolicy[] = "Cross-Origin-Embedder-Policy";
constexpr static char CrossOriginEmbedderPolicyReportOnly[] = "Cross-Origin-Embedder-Policy-Report-Only";
constexpr static char CrossOriginOpenerPolicy[] = "Cross-Origin-Opener-Policy";
constexpr static char CrossOriginOpenerPolicyReportOnly[] = "Cross-Origin-Opener-Policy-Report-Only";
constexpr static char CrossOriginResourcePolicy[] = "Cross-Origin-Resource-Policy";
constexpr static char DASL[] = "DASL";
constexpr static char DAV[] = "DAV";
constexpr static char DeltaBase[] = "Delta-Base";
constexpr static char Depth[] = "Depth";
constexpr static char Destination[] = "Destination";
constexpr static char DifferentialID[] = "Differential-ID";
constexpr static char DPoP[] = "DPoP";
constexpr static char DPoPNonce[] = "DPoP-Nonce";
constexpr static char EarlyData[] = "Early-Data";
constexpr static char ExpectCT[] = "Expect-CT";
constexpr static char Forwarded[] = "Forwarded";
constexpr static char Hobareg[] = "Hobareg";
constexpr static char If[] = "If";
constexpr static char IfScheduleTagMatch[] = "If-Schedule-Tag-Match";
constexpr static char IM[] = "IM";
constexpr static char IncludeReferredTokenBindingID[] = "Include-Referred-Token-Binding-ID";
constexpr static char KeepAlive[] = "Keep-Alive";
constexpr static char Label[] = "Label";
constexpr static char LastEventID[] = "Last-Event-ID";
constexpr static char Link[] = "Link";
constexpr static char LockToken[] = "Lock-Token";
constexpr static char MementoDatetime[] = "Memento-Datetime";
constexpr static char Meter[] = "Meter";
constexpr static char Negotiate[] = "Negotiate";
constexpr static char NEL[] = "NEL";
constexpr static char ODataEntityid[] = "OData-EntityId";
constexpr static char ODataIsolation[] = "OData-Isolation";
constexpr static char ODataMaxversion[] = "OData-MaxVersion";
constexpr static char ODataVersion[] = "OData-Version";
constexpr static char OptionalWWWAuthenticate[] = "Optional-WWW-Authenticate";
constexpr static char OrderingType[] = "Ordering-Type";
constexpr static char Origin[] = "Origin";
constexpr static char OriginAgentCluster[] = "Origin-Agent-Cluster";
constexpr static char OSCORE[] = "OSCORE";
constexpr static char OSLCCoreVersion[] = "OSLC-Core-Version";
constexpr static char Overwrite[] = "Overwrite";
constexpr static char PingFrom[] = "Ping-From";
constexpr static char PingTo[] = "Ping-To";
constexpr static char Position[] = "Position";
constexpr static char Prefer[] = "Prefer";
constexpr static char PreferenceApplied[] = "Preference-Applied";
constexpr static char Priority[] = "Priority";
constexpr static char ProxyStatus[] = "Proxy-Status";
constexpr static char PublicKeyPins[] = "Public-Key-Pins";
constexpr static char PublicKeyPinsReportOnly[] = "Public-Key-Pins-Report-Only";
constexpr static char RedirectRef[] = "Redirect-Ref";
constexpr static char Refresh[] = "Refresh";
constexpr static char ReplayNonce[] = "Replay-Nonce";
constexpr static char ReprDigest[] = "Repr-Digest";
constexpr static char ScheduleReply[] = "Schedule-Reply";
constexpr static char ScheduleTag[] = "Schedule-Tag";
constexpr static char SecPurpose[] = "Sec-Purpose";
constexpr static char SecTokenBinding[] = "Sec-Token-Binding";
constexpr static char SecWebsocketAccept[] = "Sec-WebSocket-Accept";
constexpr static char SecWebsocketExtensions[] = "Sec-WebSocket-Extensions";
constexpr static char SecWebsocketKey[] = "Sec-WebSocket-Key";
constexpr static char SecWebsocketProtocol[] = "Sec-WebSocket-Protocol";
constexpr static char SecWebsocketVersion[] = "Sec-WebSocket-Version";
constexpr static char ServerTiming[] = "Server-Timing";
constexpr static char SetCookie[] = "Set-Cookie";
constexpr static char Signature[] = "Signature";
constexpr static char SignatureInput[] = "Signature-Input";
constexpr static char SLUG[] = "SLUG";
constexpr static char Soapaction[] = "SoapAction";
constexpr static char StatusURI[] = "Status-URI";
constexpr static char StrictTransportSecurity[] = "Strict-Transport-Security";
constexpr static char Sunset[] = "Sunset";
constexpr static char SurrogateCapability[] = "Surrogate-Capability";
constexpr static char SurrogateControl[] = "Surrogate-Control";
constexpr static char TCN[] = "TCN";
constexpr static char Timeout[] = "Timeout";
constexpr static char Topic[] = "Topic";
constexpr static char Traceparent[] = "Traceparent";
constexpr static char Tracestate[] = "Tracestate";
constexpr static char TTL[] = "TTL";
constexpr static char Urgency[] = "Urgency";
constexpr static char VariantVary[] = "Variant-Vary";
constexpr static char WantContentDigest[] = "Want-Content-Digest";
constexpr static char WantReprDigest[] = "Want-Repr-Digest";
constexpr static char XContentTypeOptions[] = "X-Content-Type-Options";
constexpr static char XFrameOptions[] = "X-Frame-Options";
constexpr static char AmpCacheTransform[] = "AMP-Cache-Transform";
constexpr static char ConfigurationContext[] = "Configuration-Context";
constexpr static char EDIINTFeatures[] = "EDIINT-Features";
constexpr static char Isolation[] = "Isolation";
constexpr static char PermissionsPolicy[] = "Permissions-Policy";
constexpr static char RepeatabilityClientID[] = "Repeatability-Client-ID";
constexpr static char RepeatabilityFirstSent[] = "Repeatability-First-Sent";
constexpr static char RepeatabilityRequestID[] = "Repeatability-Request-ID";
constexpr static char RepeatabilityResult[] = "Repeatability-Result";
constexpr static char ReportingEndpoints[] = "Reporting-Endpoints";
constexpr static char SecGPC[] = "Sec-GPC";
constexpr static char TimingAllowOrigin[] = "Timing-Allow-Origin";
constexpr static char CPEPInfo[] = "C-PEP-Info";
constexpr static char ProtocolInfo[] = "Protocol-Info";
constexpr static char ProtocolQuery[] = "Protocol-Query";
constexpr static char AccessControl[] = "Access-Control";
constexpr static char CExt[] = "C-Ext";
constexpr static char CMan[] = "C-Man";
constexpr static char COpt[] = "C-Opt";
constexpr static char CPEP[] = "C-PEP";
constexpr static char ContentBase[] = "Content-Base";
constexpr static char ContentMD5[] = "Content-MD5";
constexpr static char ContentScriptType[] = "Content-Script-Type";
constexpr static char ContentStyleType[] = "Content-Style-Type";
constexpr static char ContentVersion[] = "Content-Version";
constexpr static char Cookie2[] = "Cookie2";
constexpr static char DefaultStyle[] = "Default-Style";
constexpr static char DerivedFrom[] = "Derived-From";
constexpr static char Digest[] = "Digest";
constexpr static char Ext[] = "Ext";
constexpr static char Getprofile[] = "GetProfile";
constexpr static char HTTP2Settings[] = "HTTP2-Settings";
constexpr static char Man[] = "Man";
constexpr static char MethodCheck[] = "Method-Check";
constexpr static char MethodCheckExpires[] = "Method-Check-Expires";
constexpr static char Opt[] = "Opt";
constexpr static char P3P[] = "P3P";
constexpr static char PEP[] = "PEP";
constexpr static char PepInfo[] = "Pep-Info";
constexpr static char PICSLabel[] = "PICS-Label";
constexpr static char Profileobject[] = "ProfileObject";
constexpr static char Protocol[] = "Protocol";
constexpr static char ProtocolRequest[] = "Protocol-Request";
constexpr static char ProxyFeatures[] = "Proxy-Features";
constexpr static char ProxyInstruction[] = "Proxy-Instruction";
constexpr static char Public[] = "Public";
constexpr static char RefererRoot[] = "Referer-Root";
constexpr static char Safe[] = "Safe";
constexpr static char SecurityScheme[] = "Security-Scheme";
constexpr static char SetCookie2[] = "Set-Cookie2";
constexpr static char Setprofile[] = "SetProfile";
constexpr static char URI[] = "URI";
constexpr static char WantDigest[] = "Want-Digest";
constexpr static char Warning[] = "Warning";
}; // namespace Header
}; // namespace PIHTTP
#endif

View File

@@ -0,0 +1,62 @@
#include "pihttptypes.h"
const char * PIHTTP::methodName(Method m) {
switch (m) {
case Method::Get: return "GET";
case Method::Head: return "HEAD";
case Method::Post: return "POST";
case Method::Put: return "PUT";
case Method::Delete: return "DELETE";
case Method::Connect: return "CONNECT";
case Method::Options: return "OPTIONS";
case Method::Trace: return "TRACE";
case Method::Patch: return "PATCH";
default: break;
};
return "UNKNOWN";
}
PIHTTP::MessageMutable & PIHTTP::MessageMutable::addHeader(const PIString & header, const PIString & value) {
m_headers[header] = value;
return *this;
}
PIHTTP::MessageMutable & PIHTTP::MessageMutable::setMethod(Method m) {
m_method = m;
return *this;
}
PIHTTP::MessageMutable & PIHTTP::MessageMutable::setCode(Code c) {
m_code = c;
return *this;
}
PIHTTP::MessageMutable & PIHTTP::MessageMutable::setPath(PIString p) {
m_path = std::move(p);
return *this;
}
PIHTTP::MessageMutable & PIHTTP::MessageMutable::setBody(PIByteArray b) {
m_body = std::move(b);
return *this;
}
PIHTTP::MessageMutable PIHTTP::MessageMutable::fromCode(Code c) {
PIHTTP::MessageMutable ret;
ret.setCode(c);
return ret;
}
PIHTTP::MessageMutable PIHTTP::MessageMutable::fromMethod(Method m) {
PIHTTP::MessageMutable ret;
ret.setMethod(m);
return ret;
}

View File

@@ -0,0 +1,54 @@
#ifndef pihttptypes_h
#define pihttptypes_h
#include "pihttpconstants.h"
#include "pip_export.h"
#include "pistring.h"
namespace PIHTTP {
class PIP_EXPORT MessageConst {
public:
PIHTTP::Method method() const { return m_method; }
PIHTTP::Code code() const { return m_code; }
const PIString & path() const { return m_path; }
const PIByteArray & body() const { return m_body; }
const PIMap<PIString, PIString> & headers() const { return m_headers; }
const PIMap<PIString, PIString> & arguments() const { return m_arguments; }
protected:
PIHTTP::Method m_method = PIHTTP::Method::Unknown;
PIHTTP::Code m_code = PIHTTP::Code::Ok;
PIString m_path;
PIByteArray m_body;
PIMap<PIString, PIString> m_headers;
PIMap<PIString, PIString> m_arguments;
};
class PIP_EXPORT MessageMutable: public MessageConst {
public:
MessageMutable & setMethod(PIHTTP::Method m);
MessageMutable & setCode(PIHTTP::Code c);
MessageMutable & setPath(PIString p);
MessageMutable & setBody(PIByteArray b);
const PIMap<PIString, PIString> & headers() const { return m_headers; }
const PIMap<PIString, PIString> & arguments() const { return m_arguments; }
PIMap<PIString, PIString> & headers() { return m_headers; }
PIMap<PIString, PIString> & arguments() { return m_arguments; }
MessageMutable & addHeader(const PIString & header, const PIString & value);
void removeHeader(const PIString & header) { m_headers.remove(header); }
static MessageMutable fromCode(PIHTTP::Code c);
static MessageMutable fromMethod(PIHTTP::Method m);
};
PIP_EXPORT const char * methodName(Method m);
}; // namespace PIHTTP
#endif

View File

@@ -1,7 +1,7 @@
#ifndef MICROHTTPD_SERVER_P_H #ifndef MICROHTTPD_SERVER_P_H
#define MICROHTTPD_SERVER_P_H #define MICROHTTPD_SERVER_P_H
#include "pibase.h" #include "pihttptypes.h"
#include "piobject.h" #include "piobject.h"
#include "pip_http_server_export.h" #include "pip_http_server_export.h"
@@ -15,18 +15,6 @@ public:
MicrohttpdServer(); MicrohttpdServer();
virtual ~MicrohttpdServer(); virtual ~MicrohttpdServer();
enum class Method {
Unknown,
Get,
Head,
Post,
Put,
Delete,
Connect,
Options,
Trace,
Patch
};
enum class Option { enum class Option {
ConnectionLimit, // uint ConnectionLimit, // uint
ConnectionTimeout, // uint, sec ConnectionTimeout, // uint, sec
@@ -36,30 +24,6 @@ public:
HTTPSKeyPassword // const char * to passwd for key.pem HTTPSKeyPassword // const char * to passwd for key.pem
}; };
struct PIP_HTTP_SERVER_EXPORT Request {
MicrohttpdServer::Method method;
PIString path;
PIByteArray body;
PIMap<PIString, PIString> headers;
PIMap<PIString, PIString> args;
};
class PIP_HTTP_SERVER_EXPORT Reply {
friend struct MicrohttpdServerConnection;
public:
void addHeader(const PIString & header, const PIString & value);
void removeHeader(const PIString & header);
void setBody(const PIByteArray & b);
void setCode(int c);
private:
void addFixedHeaders();
int code = 200;
PIByteArray body;
PIMap<PIString, PIString> headers;
};
void setOption(Option o, PIVariant v); void setOption(Option o, PIVariant v);
void setFavicon(const PIByteArray & im); void setFavicon(const PIByteArray & im);
@@ -68,14 +32,25 @@ public:
bool isListen() const; bool isListen() const;
void stop(); void stop();
void setRequestCallback(std::function<Reply(Request)> c) { callback = c; } void enableBasicAuth() { setBasicAuthEnabled(true); }
void disableBasicAuth() { setBasicAuthEnabled(false); }
void setBasicAuthEnabled(bool yes) { use_basic_auth = yes; }
bool isBasicAuthEnabled() const { return use_basic_auth; }
void setBasicAuthRealm(const PIString & r) { realm = r; }
void setRequestCallback(std::function<PIHTTP::MessageMutable(const PIHTTP::MessageConst &)> c) { callback = c; }
void setBasicAuthCallback(std::function<bool(const PIString &, const PIString &)> c) { callback_auth = c; }
private: private:
static void addFixedHeaders(PIHTTP::MessageMutable & msg);
PRIVATE_DECLARATION(PIP_HTTP_SERVER_EXPORT) PRIVATE_DECLARATION(PIP_HTTP_SERVER_EXPORT)
PIByteArray favicon; PIByteArray favicon;
PIString realm;
PIMap<Option, PIVariant> opts; PIMap<Option, PIVariant> opts;
std::function<Reply(Request)> callback; std::function<PIHTTP::MessageMutable(const PIHTTP::MessageConst &)> callback;
std::function<bool(const PIString &, const PIString &)> callback_auth;
std::atomic_bool use_basic_auth = {false};
PIByteArray mem_key, mem_cert, key_pass; PIByteArray mem_key, mem_cert, key_pass;
}; };

View File

@@ -10,13 +10,15 @@ public:
PIHTTPServer(); PIHTTPServer();
virtual ~PIHTTPServer(); virtual ~PIHTTPServer();
using RequestFunction = std::function<MicrohttpdServer::Reply(const MicrohttpdServer::Request &)>; using RequestFunction = std::function<PIHTTP::MessageMutable(const PIHTTP::MessageConst &)>;
void registerPath(const PIString & path, MicrohttpdServer::Method method, RequestFunction functor); void registerPath(const PIString & path, PIHTTP::Method method, RequestFunction functor);
void registerUnhandled(RequestFunction functor); void registerUnhandled(RequestFunction functor);
void unregisterPath(const PIString & path, MicrohttpdServer::Method method); void unregisterPath(const PIString & path, PIHTTP::Method method);
void unregisterPath(const PIString & path); void unregisterPath(const PIString & path);
// void registerBasicAuth() {}
void addReplyHeader(const PIString & name, const PIString & value) { reply_headers[name] = value; } void addReplyHeader(const PIString & name, const PIString & value) { reply_headers[name] = value; }
void removeReplyHeader(const PIString & name) { reply_headers.remove(name); } void removeReplyHeader(const PIString & name) { reply_headers.remove(name); }
void clearReplyHeaders() { reply_headers.clear(); } void clearReplyHeaders() { reply_headers.clear(); }
@@ -25,7 +27,7 @@ private:
struct Endpoint { struct Endpoint {
bool match(const PIStringList & in_path) const; bool match(const PIStringList & in_path) const;
PIStringList path; PIStringList path;
MicrohttpdServer::Method method = MicrohttpdServer::Method::Unknown; PIHTTP::Method method = PIHTTP::Method::Unknown;
RequestFunction function; RequestFunction function;
}; };
PIMap<PIString, PIString> reply_headers; PIMap<PIString, PIString> reply_headers;

View File

@@ -114,7 +114,7 @@ bool PIBinaryLog::openDevice() {
PIDir ld(logDir()); PIDir ld(logDir());
if (ld.isExists()) { if (ld.isExists()) {
PIVector<PIFile::FileInfo> es = ld.allEntries(); PIVector<PIFile::FileInfo> es = ld.allEntries();
piForeachC(PIFile::FileInfo & i, es) { for (const auto & i: es) {
if (i.extension() == "binlog" && i.isFile() && i.baseName().startsWith(filePrefix())) { if (i.extension() == "binlog" && i.isFile() && i.baseName().startsWith(filePrefix())) {
setPath(i.path); setPath(i.path);
break; break;

View File

@@ -107,7 +107,7 @@ PIConfig::Entry PIConfig::Entry::_empty;
PIConfig::Branch PIConfig::Branch::allLeaves() { PIConfig::Branch PIConfig::Branch::allLeaves() {
Branch b; Branch b;
b.delim = delim; b.delim = delim;
piForeach(Entry * i, *this) { for (auto * i: *this) {
if (i->isLeaf()) if (i->isLeaf())
b << i; b << i;
else else
@@ -128,7 +128,7 @@ PIConfig::Entry & PIConfig::Branch::getValue(const PIString & vname, const PIStr
PIString name = tree.front(); PIString name = tree.front();
tree.pop_front(); tree.pop_front();
Entry * ce = 0; Entry * ce = 0;
piForeach(Entry * i, *this) for (auto * i: *this)
if (i->_name == name) { if (i->_name == name) {
ce = i; ce = i;
break; break;
@@ -140,7 +140,7 @@ PIConfig::Entry & PIConfig::Branch::getValue(const PIString & vname, const PIStr
if (exist != 0) *exist = false; if (exist != 0) *exist = false;
return _empty; return _empty;
} }
piForeach(PIString & i, tree) { for (auto & i: tree) {
ce = ce->findChild(i); ce = ce->findChild(i);
if (ce == 0) { if (ce == 0) {
_empty._name = vname; _empty._name = vname;
@@ -158,11 +158,11 @@ PIConfig::Entry & PIConfig::Branch::getValue(const PIString & vname, const PIStr
PIConfig::Branch PIConfig::Branch::getValues(const PIString & name) { PIConfig::Branch PIConfig::Branch::getValues(const PIString & name) {
Branch b; Branch b;
b.delim = delim; b.delim = delim;
piForeach(Entry * i, *this) { for (auto * i: *this) {
if (i->isLeaf()) { if (i->isLeaf()) {
if (i->_name.find(name) >= 0) b << i; if (i->_name.find(name) >= 0) b << i;
} else { } else {
piForeach(Entry * j, i->_children) for (auto * j: i->_children)
if (j->_name.find(name) >= 0) b << j; if (j->_name.find(name) >= 0) b << j;
} }
} }
@@ -173,7 +173,7 @@ PIConfig::Branch PIConfig::Branch::getValues(const PIString & name) {
PIConfig::Branch PIConfig::Branch::getLeaves() { PIConfig::Branch PIConfig::Branch::getLeaves() {
Branch b; Branch b;
b.delim = delim; b.delim = delim;
piForeach(Entry * i, *this) for (auto * i: *this)
if (i->isLeaf()) b << i; if (i->isLeaf()) b << i;
return b; return b;
} }
@@ -182,7 +182,7 @@ PIConfig::Branch PIConfig::Branch::getLeaves() {
PIConfig::Branch PIConfig::Branch::getBranches() { PIConfig::Branch PIConfig::Branch::getBranches() {
Branch b; Branch b;
b.delim = delim; b.delim = delim;
piForeach(Entry * i, *this) for (auto * i: *this)
if (!i->isLeaf()) b << i; if (!i->isLeaf()) b << i;
return b; return b;
} }
@@ -203,7 +203,7 @@ bool PIConfig::Branch::entryExists(const Entry * e, const PIString & name) const
if (e->_children.isEmpty()) { if (e->_children.isEmpty()) {
return (e->_name == name); return (e->_name == name);
} }
piForeachC(Entry * i, e->_children) for (const auto * i: e->_children)
if (entryExists(i, name)) return true; if (entryExists(i, name)) return true;
return false; return false;
} }
@@ -212,7 +212,7 @@ bool PIConfig::Branch::entryExists(const Entry * e, const PIString & name) const
PIConfig::Entry & PIConfig::Entry::getValue(const PIString & vname, const PIString & def, bool * exist) { PIConfig::Entry & PIConfig::Entry::getValue(const PIString & vname, const PIString & def, bool * exist) {
PIStringList tree = vname.split(delim); PIStringList tree = vname.split(delim);
Entry * ce = this; Entry * ce = this;
piForeach(PIString & i, tree) { for (auto & i: tree) {
ce = ce->findChild(i); ce = ce->findChild(i);
if (ce == 0) { if (ce == 0) {
_empty._name = vname; _empty._name = vname;
@@ -230,7 +230,7 @@ PIConfig::Entry & PIConfig::Entry::getValue(const PIString & vname, const PIStri
PIConfig::Branch PIConfig::Entry::getValues(const PIString & vname) { PIConfig::Branch PIConfig::Entry::getValues(const PIString & vname) {
Branch b; Branch b;
b.delim = delim; b.delim = delim;
piForeach(Entry * i, _children) for (auto * i: _children)
if (i->_name.find(vname) >= 0) b << i; if (i->_name.find(vname) >= 0) b << i;
return b; return b;
} }
@@ -240,7 +240,7 @@ bool PIConfig::Entry::entryExists(const Entry * e, const PIString & name) const
if (e->_children.isEmpty()) { if (e->_children.isEmpty()) {
return (e->_name == name); return (e->_name == name);
} }
piForeachC(Entry * i, e->_children) for (const auto * i: e->_children)
if (entryExists(i, name)) return true; if (entryExists(i, name)) return true;
return false; return false;
} }
@@ -253,7 +253,7 @@ void PIConfig::Entry::coutt(std::ostream & s, const PIString & p) const {
s << p << _name << " = " << _value << std::endl; s << p << _name << " = " << _value << std::endl;
else else
std::cout << p << _name << std::endl; std::cout << p << _name << std::endl;
piForeachC(Entry * i, _children) for (const auto * i: _children)
i->coutt(s, nl); i->coutt(s, nl);
} }
#endif #endif
@@ -265,7 +265,7 @@ void PIConfig::Entry::piCoutt(PICout s, const PIString & p) const {
s << p << _name << " = " << _value << " (" << _type << " " << _comment << ")" << PICoutManipulators::NewLine; s << p << _name << " = " << _value << " (" << _type << " " << _comment << ")" << PICoutManipulators::NewLine;
else else
s << p << _name << PICoutManipulators::NewLine; s << p << _name << PICoutManipulators::NewLine;
piForeachC(Entry * i, _children) for (const auto * i: _children)
i->piCoutt(s, nl); i->piCoutt(s, nl);
} }
@@ -368,7 +368,7 @@ void PIConfig::_destroy() {
piDeleteSafety(stream); piDeleteSafety(stream);
if (own_dev && dev) delete dev; if (own_dev && dev) delete dev;
dev = nullptr; dev = nullptr;
piForeach(PIConfig * c, inc_devs) for (auto * c: inc_devs)
delete c; delete c;
inc_devs.clear(); inc_devs.clear();
} }
@@ -445,7 +445,7 @@ bool PIConfig::isOpened() const {
PIConfig::Entry & PIConfig::getValue(const PIString & vname, const PIString & def, bool * exist) { PIConfig::Entry & PIConfig::getValue(const PIString & vname, const PIString & def, bool * exist) {
PIStringList tree = vname.split(delim); PIStringList tree = vname.split(delim);
Entry * ce = &root; Entry * ce = &root;
piForeach(PIString & i, tree) { for (auto & i: tree) {
ce = ce->findChild(i); ce = ce->findChild(i);
if (ce == 0) { if (ce == 0) {
if (exist != 0) *exist = false; if (exist != 0) *exist = false;
@@ -463,7 +463,7 @@ PIConfig::Entry & PIConfig::getValue(const PIString & vname, const PIString & de
PIConfig::Branch PIConfig::getValues(const PIString & vname) { PIConfig::Branch PIConfig::getValues(const PIString & vname) {
Branch b; Branch b;
b.delim = delim; b.delim = delim;
piForeach(Entry * i, root._children) for (auto * i: root._children)
if (i->_name.find(vname) >= 0) b << i; if (i->_name.find(vname) >= 0) b << i;
return b; return b;
}; };
@@ -477,7 +477,7 @@ void PIConfig::addEntry(const PIString & name, const PIString & value, const PIS
tree.pop_back(); tree.pop_back();
Entry *te, *ce, *entry = &root; Entry *te, *ce, *entry = &root;
if (tree.isEmpty()) toRoot = true; if (tree.isEmpty()) toRoot = true;
piForeach(PIString & i, tree) { for (auto & i: tree) {
te = entry->findChild(i); te = entry->findChild(i);
if (te == 0) { if (te == 0) {
ce = new Entry(); ce = new Entry();
@@ -550,7 +550,7 @@ void PIConfig::setValue(const PIString & name, const PIString & value, const PIS
int PIConfig::entryIndex(const PIString & name) { int PIConfig::entryIndex(const PIString & name) {
PIStringList tree = name.split(delim); PIStringList tree = name.split(delim);
Entry * ce = &root; Entry * ce = &root;
piForeach(PIString & i, tree) { for (auto & i: tree) {
ce = ce->findChild(i); ce = ce->findChild(i);
if (ce == 0) return -1; if (ce == 0) return -1;
} }
@@ -716,7 +716,7 @@ bool PIConfig::entryExists(const Entry * e, const PIString & name) const {
if (e->_children.isEmpty()) { if (e->_children.isEmpty()) {
return (e->_name == name); return (e->_name == name);
} }
piForeachC(Entry * i, e->_children) for (const auto * i: e->_children)
if (entryExists(i, name)) return true; if (entryExists(i, name)) return true;
return false; return false;
} }
@@ -725,7 +725,7 @@ bool PIConfig::entryExists(const Entry * e, const PIString & name) const {
void PIConfig::updateIncludes() { void PIConfig::updateIncludes() {
if (internal) return; if (internal) return;
all_includes.clear(); all_includes.clear();
piForeach(PIConfig * c, includes) for (auto * c: includes)
all_includes << c->allLeaves(); all_includes << c->allLeaves();
} }
@@ -744,7 +744,7 @@ PIString PIConfig::parseLine(PIString v) {
if (ex) { if (ex) {
r = me._value; r = me._value;
} else { } else {
piForeachC(PIConfig::Entry * e, all_includes) for (const auto * e: all_includes)
if (e->_full_name == w) { if (e->_full_name == w) {
r = e->_value; r = e->_value;
break; break;
@@ -763,9 +763,7 @@ void PIConfig::parse() {
Entry *entry = 0, *te = 0, *ce = 0; Entry *entry = 0, *te = 0, *ce = 0;
int ind, sind; int ind, sind;
bool isNew = false, isPrefix = false, wasMultiline = false, isMultiline = false; bool isNew = false, isPrefix = false, wasMultiline = false, isMultiline = false;
piForeach(PIConfig * c, inc_devs) piDeleteAllAndClear(inc_devs);
delete c;
inc_devs.clear();
includes.clear(); includes.clear();
if (!isOpened()) return; if (!isOpened()) return;
_seekToBeginDev(); _seekToBeginDev();
@@ -835,7 +833,7 @@ void PIConfig::parse() {
name = tree.back(); name = tree.back();
tree.pop_back(); tree.pop_back();
entry = &root; entry = &root;
piForeachC(PIString & i, tree) { for (const auto & i: tree) {
te = entry->findChild(i); te = entry->findChild(i);
if (te == 0) { if (te == 0) {
ce = new Entry(); ce = new Entry();

View File

@@ -102,7 +102,7 @@ public:
Branch getBranches(); Branch getBranches();
Branch & filter(const PIString & f); Branch & filter(const PIString & f);
bool isEntryExists(const PIString & name) const { bool isEntryExists(const PIString & name) const {
piForeachC(Entry * i, *this) for (const auto * i: *this)
if (entryExists(i, name)) return true; if (entryExists(i, name)) return true;
return false; return false;
} }
@@ -115,7 +115,7 @@ public:
private: private:
bool entryExists(const Entry * e, const PIString & name) const; bool entryExists(const Entry * e, const PIString & name) const;
void allLeaves(Branch & b, Entry * e) { void allLeaves(Branch & b, Entry * e) {
piForeach(Entry * i, e->_children) { for (auto * i: e->_children) {
if (i->isLeaf()) if (i->isLeaf())
b << i; b << i;
else else
@@ -124,12 +124,12 @@ public:
} }
#ifdef PIP_STD_IOSTREAM #ifdef PIP_STD_IOSTREAM
void coutt(std::ostream & s, const PIString & p) const { void coutt(std::ostream & s, const PIString & p) const {
piForeachC(Entry * i, *this) for (const auto * i: *this)
i->coutt(s, p); i->coutt(s, p);
} }
#endif #endif
void piCoutt(PICout s, const PIString & p) const { void piCoutt(PICout s, const PIString & p) const {
piForeachC(Entry * i, *this) for (const auto * i: *this)
i->piCoutt(s, p); i->piCoutt(s, p);
} }
@@ -165,14 +165,14 @@ public:
//! Returns first child with name "name" //! Returns first child with name "name"
Entry * findChild(const PIString & name) { Entry * findChild(const PIString & name) {
piForeach(Entry * i, _children) for (auto * i: _children)
if (i->_name == name) return i; if (i->_name == name) return i;
return 0; return 0;
} }
//! Returns first child with name "name" //! Returns first child with name "name"
const Entry * findChild(const PIString & name) const { const Entry * findChild(const PIString & name) const {
piForeachC(Entry * i, _children) for (const auto * i: _children)
if (i->_name == name) return i; if (i->_name == name) return i;
return 0; return 0;
} }
@@ -425,7 +425,7 @@ public:
#endif #endif
void piCoutt(PICout s, const PIString & p) const; void piCoutt(PICout s, const PIString & p) const;
void deleteBranch() { void deleteBranch() {
piForeach(Entry * i, _children) { for (auto * i: _children) {
i->deleteBranch(); i->deleteBranch();
delete i; delete i;
} }
@@ -573,7 +573,7 @@ public:
//! Returns all top-level entries //! Returns all top-level entries
Branch allTree() { Branch allTree() {
Branch b; Branch b;
piForeach(Entry * i, root._children) for (auto * i: root._children)
b << i; b << i;
b.delim = delim; b.delim = delim;
return b; return b;
@@ -636,14 +636,14 @@ private:
void _writeDev(const PIString & l); void _writeDev(const PIString & l);
int childCount(const Entry * e) const { int childCount(const Entry * e) const {
int c = 0; int c = 0;
piForeachC(Entry * i, e->_children) for (const auto * i: e->_children)
c += childCount(i); c += childCount(i);
c += e->_children.size_s(); c += e->_children.size_s();
return c; return c;
} }
bool entryExists(const Entry * e, const PIString & name) const; bool entryExists(const Entry * e, const PIString & name) const;
void buildFullNames(Entry * e) { void buildFullNames(Entry * e) {
piForeach(Entry * i, e->_children) { for (auto * i: e->_children) {
if (e != &root) if (e != &root)
i->_full_name = e->_full_name + delim + i->_name; i->_full_name = e->_full_name + delim + i->_name;
else else
@@ -652,13 +652,13 @@ private:
} }
} }
void allLeaves(Branch & b, Entry * e) { void allLeaves(Branch & b, Entry * e) {
piForeach(Entry * i, e->_children) { for (auto * i: e->_children) {
if ((!i->_value.isEmpty() && !i->isLeaf()) || i->isLeaf()) b << i; if ((!i->_value.isEmpty() && !i->isLeaf()) || i->isLeaf()) b << i;
allLeaves(b, i); allLeaves(b, i);
} }
} }
void setEntryDelim(Entry * e, const PIString & d) { void setEntryDelim(Entry * e, const PIString & d) {
piForeach(Entry * i, e->_children) for (auto * i: e->_children)
setEntryDelim(i, d); setEntryDelim(i, d);
e->delim = d; e->delim = d;
} }
@@ -669,7 +669,7 @@ private:
} }
void removeEntry(Branch & b, Entry * e); void removeEntry(Branch & b, Entry * e);
void deleteEntry(Entry * e) { void deleteEntry(Entry * e) {
piForeach(Entry * i, e->_children) for (auto * i: e->_children)
deleteEntry(i); deleteEntry(i);
delete e; delete e;
} }

View File

@@ -234,7 +234,7 @@ bool PIDir::make(bool withParents) {
l.removeAll(""); l.removeAll("");
// piCout << l; // piCout << l;
PIString cdp; PIString cdp;
piForeachC(PIString & i, l) { for (const auto & i: l) {
if (!cdp.isEmpty() if (!cdp.isEmpty()
#ifndef WINDOWS #ifndef WINDOWS
|| is_abs || is_abs
@@ -400,10 +400,10 @@ PIVector<PIFile::FileInfo> PIDir::allEntries() {
PIStringList cdirs, ndirs; PIStringList cdirs, ndirs;
cdirs << path(); cdirs << path();
while (!cdirs.isEmpty()) { while (!cdirs.isEmpty()) {
piForeachC(PIString & d, cdirs) { for (const auto & d: cdirs) {
scan_ = d; scan_ = d;
PIVector<PIFile::FileInfo> el = PIDir(d).entries(); PIVector<PIFile::FileInfo> el = PIDir(d).entries();
piForeachC(PIFile::FileInfo & de, el) { for (const auto & de: el) {
if (de.name() == "." || de.name() == "..") continue; if (de.name() == "." || de.name() == "..") continue;
if (de.isSymbolicLink()) continue; /// TODO: resolve symlinks if (de.isSymbolicLink()) continue; /// TODO: resolve symlinks
if (de.isDir()) { if (de.isDir()) {

View File

@@ -229,7 +229,7 @@ PIString PIEthernet::macFromBytes(const PIByteArray & mac) {
PIByteArray PIEthernet::macToBytes(const PIString & mac) { PIByteArray PIEthernet::macToBytes(const PIString & mac) {
PIByteArray r; PIByteArray r;
PIStringList sl = mac.split(PIStringAscii(":")); PIStringList sl = mac.split(PIStringAscii(":"));
piForeachC(PIString & i, sl) for (const auto & i: sl)
r << uchar(i.toInt(16)); r << uchar(i.toInt(16));
return r; return r;
} }
@@ -997,7 +997,7 @@ PIString PIEthernet::constructFullPathDevice() const {
ret += ":" + readIP() + ":" + PIString::fromNumber(readPort()); ret += ":" + readIP() + ":" + PIString::fromNumber(readPort());
if (type() == PIEthernet::UDP) { if (type() == PIEthernet::UDP) {
ret += ":" + sendIP() + ":" + PIString::fromNumber(sendPort()); ret += ":" + sendIP() + ":" + PIString::fromNumber(sendPort());
piForeachC(PIString & m, multicastGroups()) for (const auto & m: multicastGroups())
ret += ":mcast:" + m; ret += ":mcast:" + m;
} }
return ret; return ret;
@@ -1067,7 +1067,7 @@ void PIEthernet::configureFromVariantDevice(const PIPropertyStorage & d) {
setSendIP(d.propertyValueByName("send IP").toString()); setSendIP(d.propertyValueByName("send IP").toString());
setSendPort(d.propertyValueByName("send port").toInt()); setSendPort(d.propertyValueByName("send port").toInt());
PIStringList mcgl = d.propertyValueByName("multicast").toStringList(); PIStringList mcgl = d.propertyValueByName("multicast").toStringList();
piForeachC(PIString & g, mcgl) { for (const auto & g: mcgl) {
joinMulticastGroup(g); joinMulticastGroup(g);
} }
} }
@@ -1260,8 +1260,8 @@ PIVector<PINetworkAddress> PIEthernet::allAddresses() {
PIEthernet::InterfaceList il = interfaces(); PIEthernet::InterfaceList il = interfaces();
PIVector<PINetworkAddress> ret; PIVector<PINetworkAddress> ret;
bool has_127 = false; bool has_127 = false;
piForeachC(PIEthernet::Interface & i, il) { for (const auto & i: il) {
if (i.address == "127.0.0.1") has_127 = true; if (i.address.startsWith("127.0.0.")) has_127 = true;
PINetworkAddress a(i.address); PINetworkAddress a(i.address);
if (a.ip() == 0) continue; if (a.ip() == 0) continue;
ret << a; ret << a;

View File

@@ -130,7 +130,7 @@ PIPeer::PeerInfo::PeerAddress::PeerAddress(const PINetworkAddress & a, const PIN
int PIPeer::PeerInfo::ping() const { int PIPeer::PeerInfo::ping() const {
int ret = -1; int ret = -1;
piForeachC(PeerAddress & a, addresses) for (const auto & a: addresses)
if (a.ping > 0.) { if (a.ping > 0.) {
if (ret < 0) if (ret < 0)
ret = piRoundd(a.ping); ret = piRoundd(a.ping);
@@ -155,7 +155,7 @@ void PIPeer::PeerInfo::destroy() {
PINetworkAddress PIPeer::PeerInfo::fastestAddress() const { PINetworkAddress PIPeer::PeerInfo::fastestAddress() const {
double mp = -1.; double mp = -1.;
PINetworkAddress ret; PINetworkAddress ret;
piForeachC(PeerAddress & a, addresses) { for (const auto & a: addresses) {
if (a.ping <= 0.) continue; if (a.ping <= 0.) continue;
if ((mp < 0) || (mp > a.ping)) { if ((mp < 0) || (mp > a.ping)) {
mp = a.ping; mp = a.ping;
@@ -166,6 +166,27 @@ PINetworkAddress PIPeer::PeerInfo::fastestAddress() const {
} }
void PIPeer::PeerInfo::addNeighbour(const PIString & n) {
if (!neighbours.contains(n)) neighbours << n;
}
void PIPeer::PeerInfo::addNeighbours(const PIStringList & l) {
for (const auto & n: l)
if (!neighbours.contains(n)) neighbours << n;
}
void PIPeer::PeerInfo::removeNeighbour(const PIString & n) {
neighbours.removeAll(n);
}
void PIPeer::PeerInfo::resetPing() {
for (auto & a: addresses)
a.ping = -1;
}
REGISTER_DEVICE(PIPeer) REGISTER_DEVICE(PIPeer)
PIPeer::PIPeer(const PIString & n) PIPeer::PIPeer(const PIString & n)
@@ -226,7 +247,7 @@ void PIPeer::initEths(PIStringList al) {
// piCoutObj << "initEths start"; // piCoutObj << "initEths start";
PIEthernet * ce; PIEthernet * ce;
const PIEthernet::Interface * cint = 0; const PIEthernet::Interface * cint = 0;
piForeachC(PIString & a, al) { for (const auto & a: al) {
ce = new PIEthernet(); ce = new PIEthernet();
ce->setDebug(false); ce->setDebug(false);
ce->setName("_S.PIPeer.traf_rec_" + a); ce->setName("_S.PIPeer.traf_rec_" + a);
@@ -261,7 +282,7 @@ void PIPeer::initMBcasts(PIStringList al) {
PIString nm; PIString nm;
al << _PIPEER_MULTICAST_IP; al << _PIPEER_MULTICAST_IP;
// piCoutObj << "initMBcasts start" << al; // piCoutObj << "initMBcasts start" << al;
piForeachC(PIString & a, al) { for (const auto & a: al) {
// piCout << "mcast try" << a; // piCout << "mcast try" << a;
ce = new PIEthernet(); ce = new PIEthernet();
ce->setDebug(false); ce->setDebug(false);
@@ -282,7 +303,7 @@ void PIPeer::initMBcasts(PIStringList al) {
} }
} }
al.removeAll(_PIPEER_MULTICAST_IP); al.removeAll(_PIPEER_MULTICAST_IP);
piForeachC(PIString & a, al) { for (const auto & a: al) {
ce = new PIEthernet(); ce = new PIEthernet();
ce->setDebug(false); ce->setDebug(false);
ce->setName("_S.PIPeer.bcast_" + a); ce->setName("_S.PIPeer.bcast_" + a);
@@ -429,6 +450,42 @@ bool PIPeer::send(const PIString & to, const void * data, int size) {
} }
bool PIPeer::send(const PeerInfo * to, const PIByteArray & data) {
if (!to) return false;
return send(to->name, data.data(), data.size_s());
}
bool PIPeer::send(const PeerInfo * to, const PIString & data) {
if (!to) return false;
return send(to->name, data.data(), data.size_s());
}
bool PIPeer::send(const PeerInfo * to, const void * data, int size) {
if (!to) return false;
return send(to->name, data, size);
}
void PIPeer::sendToAll(const PIByteArray & data) {
for (const auto & i: peers)
send(i.name, data.data(), data.size_s());
}
void PIPeer::sendToAll(const PIString & data) {
for (const auto & i: peers)
send(i.name, data.data(), data.size_s());
}
void PIPeer::sendToAll(const void * data, int size) {
for (const auto & i: peers)
send(i.name, data, size);
}
bool PIPeer::sendInternal(const PIString & to, const PIByteArray & data) { bool PIPeer::sendInternal(const PIString & to, const PIByteArray & data) {
PIMutexLocker mlocker(peers_mutex); PIMutexLocker mlocker(peers_mutex);
PeerInfo * dp = quickestPeer(to); PeerInfo * dp = quickestPeer(to);
@@ -484,7 +541,7 @@ bool PIPeer::dataRead(const uchar * readed, ssize_t size) {
sba << int(6) << to << from << addr << time; sba << int(6) << to << from << addr << time;
// piCout << " ping from" << from << addr << ", send back to" << pi->name; // piCout << " ping from" << from << addr << ", send back to" << pi->name;
send_mutex.lock(); send_mutex.lock();
piForeachC(PeerInfo::PeerAddress & a, pi->addresses) { for (const auto & a: pi->addresses) {
if (eth_send.send(a.address, sba)) diag_s.received(sba.size_s()); if (eth_send.send(a.address, sba)) diag_s.received(sba.size_s());
} }
send_mutex.unlock(); send_mutex.unlock();
@@ -501,10 +558,10 @@ bool PIPeer::dataRead(const uchar * readed, ssize_t size) {
// piCout << "ping reply" << to << from << addr; // piCout << "ping reply" << to << from << addr;
PIMutexLocker plocker(peers_mutex); PIMutexLocker plocker(peers_mutex);
if (to == self_info.name) { // ping echo if (to == self_info.name) { // ping echo
piForeach(PeerInfo & p, peers) { for (auto & p: peers) {
if (!p.isNeighbour()) continue; if (!p.isNeighbour()) continue;
if (p.name != from) continue; if (p.name != from) continue;
piForeach(PeerInfo::PeerAddress & a, p.addresses) { for (auto & a: p.addresses) {
if (a.address != addr) continue; if (a.address != addr) continue;
if (a.last_ping >= time) break; if (a.last_ping >= time) break;
ptime = ctime - time; ptime = ctime - time;
@@ -662,11 +719,11 @@ bool PIPeer::mbcastRead(const uchar * data, ssize_t size) {
} }
ch = true; ch = true;
} }
piForeach(PeerInfo & rpeer, rpeers) { for (auto & rpeer: rpeers) {
// piCout << " to sync " << rpeer.name; // piCout << " to sync " << rpeer.name;
if (rpeer.name == self_info.name) continue; if (rpeer.name == self_info.name) continue;
bool exist = false; bool exist = false;
piForeach(PeerInfo & peer, peers) { for (auto & peer: peers) {
if (peer.name == rpeer.name) { if (peer.name == rpeer.name) {
exist = true; exist = true;
if (isPeerRecent(peer, rpeer)) { if (isPeerRecent(peer, rpeer)) {
@@ -706,7 +763,7 @@ bool PIPeer::mbcastRead(const uchar * data, ssize_t size) {
} }
// piCout << "***"; // piCout << "***";
// piCout << self_info.name << self_info.neighbours; // piCout << self_info.name << self_info.neighbours;
piForeach(PeerInfo & i, peers) { for (auto & i: peers) {
if (i.dist == 0) { if (i.dist == 0) {
self_info.addNeighbour(i.name); self_info.addNeighbour(i.name);
i.addNeighbour(self_info.name); i.addNeighbour(self_info.name);
@@ -737,11 +794,11 @@ bool PIPeer::sendToNeighbour(PIPeer::PeerInfo * peer, const PIByteArray & ba) {
void PIPeer::sendMBcast(const PIByteArray & ba) { void PIPeer::sendMBcast(const PIByteArray & ba) {
send_mc_mutex.lock(); send_mc_mutex.lock();
// piCout << "sendMBcast" << ba.size() << "bytes ..."; // piCout << "sendMBcast" << ba.size() << "bytes ...";
piForeach(PIEthernet * e, eths_mcast) { for (auto * e: eths_mcast) {
if (e->isOpened()) if (e->isOpened())
if (e->send(ba)) diag_s.sended(ba.size_s()); if (e->send(ba)) diag_s.sended(ba.size_s());
} }
piForeach(PIEthernet * e, eths_bcast) { for (auto * e: eths_bcast) {
if (e->isOpened()) if (e->isOpened())
if (e->send(ba)) diag_s.sended(ba.size_s()); if (e->send(ba)) diag_s.sended(ba.size_s());
} }
@@ -750,7 +807,7 @@ void PIPeer::sendMBcast(const PIByteArray & ba) {
if (eth_lo.send(ba)) diag_s.sended(ba.size_s()); if (eth_lo.send(ba)) diag_s.sended(ba.size_s());
} }
PIVector<PIEthernet *> cl = eth_tcp_srv.clients(); PIVector<PIEthernet *> cl = eth_tcp_srv.clients();
piForeach(PIEthernet * e, cl) { for (auto * e: cl) {
if (e->isOpened() && e->isConnected()) if (e->isOpened() && e->isConnected())
if (e->send(ba)) diag_s.sended(ba.size_s()); if (e->send(ba)) diag_s.sended(ba.size_s());
} }
@@ -763,7 +820,7 @@ void PIPeer::sendMBcast(const PIByteArray & ba) {
void PIPeer::removeNeighbour(const PIString & name) { void PIPeer::removeNeighbour(const PIString & name) {
piForeach(PeerInfo & p, peers) for (auto & p: peers)
p.neighbours.removeOne(name); p.neighbours.removeOne(name);
self_info.removeNeighbour(name); self_info.removeNeighbour(name);
} }
@@ -809,11 +866,11 @@ void PIPeer::pingNeighbours() {
PIByteArray ba, sba; PIByteArray ba, sba;
ba << int(5) << self_info.name; ba << int(5) << self_info.name;
// piCoutObj << "*** pingNeighbours" << peers.size() << "..."; // piCoutObj << "*** pingNeighbours" << peers.size() << "...";
piForeach(PeerInfo & p, peers) { for (auto & p: peers) {
if (!p.isNeighbour()) continue; if (!p.isNeighbour()) continue;
// piCout << " ping neighbour" << p.name << p.ping(); // piCout << " ping neighbour" << p.name << p.ping();
send_mutex.lock(); send_mutex.lock();
piForeach(PeerInfo::PeerAddress & a, p.addresses) { for (auto & a: p.addresses) {
// piCout << " address" << a.address << a.wait_ping; // piCout << " address" << a.address << a.wait_ping;
if (a.wait_ping) { if (a.wait_ping) {
if ((PISystemTime::current(true) - a.last_ping).abs().toSeconds() <= _PIPEER_PING_TIMEOUT) continue; if ((PISystemTime::current(true) - a.last_ping).abs().toSeconds() <= _PIPEER_PING_TIMEOUT) continue;
@@ -891,7 +948,7 @@ void PIPeer::syncPeers() {
ba << int(3) << self_info.name << self_info << peers; ba << int(3) << self_info.name << self_info << peers;
peers_mutex.unlock(); peers_mutex.unlock();
sendMBcast(ba); sendMBcast(ba);
piForeachC(PIString & p, dpeers) { for (const auto & p: dpeers) {
peerDisconnected(p); peerDisconnected(p);
peerDisconnectedEvent(p); peerDisconnectedEvent(p);
} }
@@ -930,6 +987,12 @@ void PIPeer::changeName(const PIString & new_name) {
} }
void PIPeer::setTcpServerIP(const PIString & ip) {
server_ip = ip;
tcpClientReconnect();
}
ssize_t PIPeer::bytesAvailable() const { ssize_t PIPeer::bytesAvailable() const {
ssize_t ret = 0; ssize_t ret = 0;
read_buffer_mutex.lock(); read_buffer_mutex.lock();
@@ -1054,7 +1117,7 @@ void PIPeer::buildMap() {
// piCout << "[PIPeer \"" + name_ + "\"] buildMap"; // piCout << "[PIPeer \"" + name_ + "\"] buildMap";
peers_map.clear(); peers_map.clear();
addresses_map.clear(); addresses_map.clear();
piForeach(PeerInfo & i, peers) { for (auto & i: peers) {
i.trace = -1; i.trace = -1;
peers_map[i.name] = &i; peers_map[i.name] = &i;
} }
@@ -1065,8 +1128,8 @@ void PIPeer::buildMap() {
while (!cwave.isEmpty()) { while (!cwave.isEmpty()) {
nwave.clear(); nwave.clear();
++cwi; ++cwi;
piForeachC(PeerInfo * p, cwave) { for (const auto * p: cwave) {
piForeachC(PIString & nn, p->neighbours) { for (const auto & nn: p->neighbours) {
PeerInfo * np = peers_map.value(nn); PeerInfo * np = peers_map.value(nn);
if (!np) continue; if (!np) continue;
if (np->trace >= 0) continue; if (np->trace >= 0) continue;
@@ -1077,14 +1140,14 @@ void PIPeer::buildMap() {
cwave = nwave; cwave = nwave;
} }
PIVector<PeerInfo *> cpath; PIVector<PeerInfo *> cpath;
piForeach(PeerInfo & c, peers) { for (auto & c: peers) {
cpath.clear(); cpath.clear();
cpath << &c; cpath << &c;
cwave << &c; cwave << &c;
for (int w = c.trace - 1; w >= 0; --w) { for (int w = c.trace - 1; w >= 0; --w) {
nwave.clear(); nwave.clear();
piForeachC(PeerInfo * p, cwave) { for (const auto * p: cwave) {
piForeachC(PIString & nn, p->neighbours) { for (const auto & nn: p->neighbours) {
PeerInfo * np = peers_map.value(nn); PeerInfo * np = peers_map.value(nn);
if (!np) continue; if (!np) continue;
if (np->trace != w) continue; if (np->trace != w) continue;
@@ -1103,3 +1166,10 @@ void PIPeer::buildMap() {
void PIPeer::tcpClientReconnect() { void PIPeer::tcpClientReconnect() {
eth_tcp_cli.connect(server_ip, _PIPEER_TCP_PORT); eth_tcp_cli.connect(server_ip, _PIPEER_TCP_PORT);
} }
bool PIPeer::hasPeer(const PIString & name) {
for (const auto & i: peers)
if (i.name == name) return true;
return false;
}

View File

@@ -72,18 +72,10 @@ public:
PINetworkAddress fastestAddress() const; PINetworkAddress fastestAddress() const;
protected: protected:
void addNeighbour(const PIString & n) { void addNeighbour(const PIString & n);
if (!neighbours.contains(n)) neighbours << n; void addNeighbours(const PIStringList & l);
} void removeNeighbour(const PIString & n);
void addNeighbours(const PIStringList & l) { void resetPing();
piForeachC(PIString & n, l)
if (!neighbours.contains(n)) neighbours << n;
}
void removeNeighbour(const PIString & n) { neighbours.removeAll(n); }
void resetPing() {
for (int i = 0; i < addresses.size_s(); ++i)
addresses[i].ping = -1;
}
void init(); void init();
void destroy(); void destroy();
@@ -101,30 +93,12 @@ public:
bool send(const PeerInfo & to, const PIByteArray & data) { return send(to.name, data.data(), data.size_s()); } bool send(const PeerInfo & to, const PIByteArray & data) { return send(to.name, data.data(), data.size_s()); }
bool send(const PeerInfo & to, const PIString & data) { return send(to.name, data.data(), data.size_s()); } bool send(const PeerInfo & to, const PIString & data) { return send(to.name, data.data(), data.size_s()); }
bool send(const PeerInfo & to, const void * data, int size) { return send(to.name, data, size); } bool send(const PeerInfo & to, const void * data, int size) { return send(to.name, data, size); }
bool send(const PeerInfo * to, const PIByteArray & data) { bool send(const PeerInfo * to, const PIByteArray & data);
if (to == 0) return false; bool send(const PeerInfo * to, const PIString & data);
return send(to->name, data.data(), data.size_s()); bool send(const PeerInfo * to, const void * data, int size);
} void sendToAll(const PIByteArray & data);
bool send(const PeerInfo * to, const PIString & data) { void sendToAll(const PIString & data);
if (to == 0) return false; void sendToAll(const void * data, int size);
return send(to->name, data.data(), data.size_s());
}
bool send(const PeerInfo * to, const void * data, int size) {
if (to == 0) return false;
return send(to->name, data, size);
}
void sendToAll(const PIByteArray & data) {
piForeachC(PeerInfo & i, peers)
send(i.name, data.data(), data.size_s());
}
void sendToAll(const PIString & data) {
piForeachC(PeerInfo & i, peers)
send(i.name, data.data(), data.size_s());
}
void sendToAll(const void * data, int size) {
piForeachC(PeerInfo & i, peers)
send(i.name, data, size);
}
bool isMulticastReceive() const { return !eths_mcast.isEmpty(); } bool isMulticastReceive() const { return !eths_mcast.isEmpty(); }
bool isBroadcastReceive() const { return !eths_bcast.isEmpty(); } bool isBroadcastReceive() const { return !eths_bcast.isEmpty(); }
@@ -145,10 +119,7 @@ public:
void changeName(const PIString & new_name); void changeName(const PIString & new_name);
const PIString & trustPeerName() const { return trust_peer; } const PIString & trustPeerName() const { return trust_peer; }
void setTrustPeerName(const PIString & peer_name) { trust_peer = peer_name; } void setTrustPeerName(const PIString & peer_name) { trust_peer = peer_name; }
void setTcpServerIP(const PIString & ip) { void setTcpServerIP(const PIString & ip);
server_ip = ip;
tcpClientReconnect();
}
ssize_t bytesAvailable() const override; ssize_t bytesAvailable() const override;
@@ -180,11 +151,7 @@ private:
EVENT_HANDLER1(void, newTcpClient, PIEthernet *, client); EVENT_HANDLER1(void, newTcpClient, PIEthernet *, client);
EVENT_HANDLER(void, tcpClientReconnect); EVENT_HANDLER(void, tcpClientReconnect);
bool hasPeer(const PIString & name) { bool hasPeer(const PIString & name);
piForeachC(PeerInfo & i, peers)
if (i.name == name) return true;
return false;
}
bool removePeer(const PIString & name); bool removePeer(const PIString & name);
void removeNeighbour(const PIString & name); void removeNeighbour(const PIString & name);
void addPeer(const PeerInfo & pd); void addPeer(const PeerInfo & pd);

View File

@@ -685,7 +685,7 @@ bool PISerial::openDevice() {
if (!pl.startsWith("/") && !pl.startsWith("com")) { if (!pl.startsWith("/") && !pl.startsWith("com")) {
p.clear(); p.clear();
PIVector<DeviceInfo> devs = availableDevicesInfo(); PIVector<DeviceInfo> devs = availableDevicesInfo();
piForeachC(DeviceInfo & d, devs) { for (const auto & d: devs) {
if (d.id() == pl) { if (d.id() == pl) {
p = d.path; p = d.path;
break; break;
@@ -1011,7 +1011,7 @@ PIPropertyStorage PISerial::constructVariantDevice() const {
PIVariantTypes::Enum e; PIVariantTypes::Enum e;
PIVector<int> as = availableSpeeds(); PIVector<int> as = availableSpeeds();
piForeachC(int s, as) { for (const auto s: as) {
e << PIVariantTypes::Enumerator(s, PIString::fromNumber(s)); e << PIVariantTypes::Enumerator(s, PIString::fromNumber(s));
} }
e.selectValue((int)inSpeed()); e.selectValue((int)inSpeed());
@@ -1073,7 +1073,7 @@ PIVector<int> PISerial::availableSpeeds() {
PIStringList PISerial::availableDevices(bool test) { PIStringList PISerial::availableDevices(bool test) {
PIVector<DeviceInfo> devs = availableDevicesInfo(test); PIVector<DeviceInfo> devs = availableDevicesInfo(test);
PIStringList ret; PIStringList ret;
piForeachC(DeviceInfo & d, devs) for (const auto & d: devs)
ret << d.path; ret << d.path;
return ret; return ret;
} }
@@ -1232,8 +1232,8 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
# ifdef LINUX # ifdef LINUX
char linkbuf[1024]; char linkbuf[1024];
# endif # endif
piForeachC(PIFile::FileInfo & e, de) { // TODO changes in FileInfo for (const auto & e: de) { // TODO changes in FileInfo
piForeachC(PIString & p, prefixes) { for (const auto & p: prefixes) {
if (e.name().startsWith(p)) { if (e.name().startsWith(p)) {
di = DeviceInfo(); di = DeviceInfo();
di.path = e.path; di.path = e.path;

View File

@@ -53,7 +53,7 @@ bool PIFileTransfer::send(const PIString & file) {
bool PIFileTransfer::send(const PIStringList & files) { bool PIFileTransfer::send(const PIStringList & files) {
PIVector<PIFile::FileInfo> fil; PIVector<PIFile::FileInfo> fil;
piForeachC(PIString & file, files) for (const auto & file: files)
fil << PIFile::fileInfo(file); fil << PIFile::fileInfo(file);
return send(fil); return send(fil);
} }
@@ -305,7 +305,7 @@ void PIFileTransfer::receive_finished(bool ok) {
desc >> files_; desc >> files_;
// piCoutObj << files_; // piCoutObj << files_;
PIStringList files; PIStringList files;
piForeachC(PFTFileInfo & fi, files_) for (const auto & fi: files_)
files << fi.dest_path; files << fi.dest_path;
pause(); pause();
receiveFilesRequest(files, bytesAll(), &user_ok); receiveFilesRequest(files, bytesAll(), &user_ok);

View File

@@ -633,7 +633,7 @@ public:
//! \~russian //! \~russian
//! \brief Транспонирование матрицы. //! \brief Транспонирование матрицы.
//! \details Работает только с квадратными матрицами. //! \details Работает только с квадратными матрицами.
//! \return копия транспонированной матрицы. //! \return Копия транспонированной матрицы.
PIMathMatrixT<Cols, Rows, Type> transposed() const { PIMathMatrixT<Cols, Rows, Type> transposed() const {
PIMathMatrixT<Cols, Rows, Type> tm; PIMathMatrixT<Cols, Rows, Type> tm;
PIMM_FOR tm[c][r] = m[r][c]; PIMM_FOR tm[c][r] = m[r][c];
@@ -647,8 +647,8 @@ public:
//! \~russian //! \~russian
//! \brief Операция поворота матрицы. //! \brief Операция поворота матрицы.
//! \details Работает только с матрицами 2x2. //! \details Работает только с матрицами 2x2.
//! \return повернутая матрица. //! \return Эта повернутая матрица.
PIMathMatrixT<Rows, Cols, Type> rotate(Type angle) { PIMathMatrixT<Rows, Cols, Type> & rotate(Type angle) {
static_assert(Rows == 2 && Cols == 2, "Works only with 2x2 matrix"); static_assert(Rows == 2 && Cols == 2, "Works only with 2x2 matrix");
Type c = std::cos(angle); Type c = std::cos(angle);
Type s = std::sin(angle); Type s = std::sin(angle);
@@ -667,8 +667,8 @@ public:
//! \~russian //! \~russian
//! \brief Операция поворота матрицы. //! \brief Операция поворота матрицы.
//! \details Работает только с матрицами 2x2. //! \details Работает только с матрицами 2x2.
//! \return копия повернутой матрицы. //! \return Копия повернутой матрицы.
PIMathMatrixT<Rows, Cols, Type> & rotated(Type angle) { PIMathMatrixT<Rows, Cols, Type> rotated(Type angle) {
static_assert(Rows == 2 && Cols == 2, "Works only with 2x2 matrix"); static_assert(Rows == 2 && Cols == 2, "Works only with 2x2 matrix");
PIMathMatrixT<Cols, Rows, Type> outm; PIMathMatrixT<Cols, Rows, Type> outm;
Type c = std::cos(angle); Type c = std::cos(angle);

View File

@@ -34,6 +34,11 @@ const char PIMathSolver::methods_desc[] = "b{Methods:}\
PIMathSolver::Method PIMathSolver::method_global = PIMathSolver::Eyler_2; PIMathSolver::Method PIMathSolver::method_global = PIMathSolver::Eyler_2;
PIMathSolver::PIMathSolver() {
times.resize(4);
}
void PIMathSolver::solve(double u, double h) { void PIMathSolver::solve(double u, double h) {
switch (method) { switch (method) {
case Global: case Global:
@@ -128,6 +133,12 @@ void PIMathSolver::fromTF(const TransferFunction & TF) {
} }
void PIMathSolver::setTime(double time) {
times.pop_back();
times.push_front(time);
}
void PIMathSolver::solveEyler1(double u, double h) { void PIMathSolver::solveEyler1(double u, double h) {
F[0] = A * X + d * u; F[0] = A * X + d * u;
X += F[0] * h; X += F[0] * h;
@@ -258,3 +269,41 @@ void PIMathSolver::solvePA(double u, double h, uint deg) {
} }
moveF(); moveF();
} }
void PIMathSolver::solvePA2(double u, double h) {
if (step > 0)
solvePA(u, h, 2);
else
solveEyler1(u, h);
}
void PIMathSolver::solvePA3(double u, double h) {
if (step > 1)
solvePA(u, h, 3);
else
solvePA2(u, h);
}
void PIMathSolver::solvePA4(double u, double h) {
if (step > 2)
solvePA(u, h, 4);
else
solvePA3(u, h);
}
void PIMathSolver::solvePA5(double u, double h) {
if (step > 3)
solvePA(u, h, 5);
else
solvePA4(u, h);
}
void PIMathSolver::moveF() {
for (uint i = F.size() - 1; i > 0; --i)
F[i] = F[i - 1];
}

View File

@@ -48,18 +48,12 @@ public:
PolynomialApproximation_5 = 35 PolynomialApproximation_5 = 35
}; };
PIMathSolver() { PIMathSolver();
times.resize(4);
step = 0;
}
void solve(double u, double h); void solve(double u, double h);
void fromTF(const TransferFunction & TF); void fromTF(const TransferFunction & TF);
void setMethod(Method m) { method = m; } void setMethod(Method m) { method = m; }
void setTime(double time) { void setTime(double time);
times.pop_back();
times.push_front(time);
}
void solveEyler1(double u, double h); void solveEyler1(double u, double h);
void solveEyler2(double u, double h); void solveEyler2(double u, double h);
@@ -68,40 +62,17 @@ public:
void solveABM3(double u, double h); void solveABM3(double u, double h);
void solveABM4(double u, double h); void solveABM4(double u, double h);
void solvePA(double u, double h, uint deg); void solvePA(double u, double h, uint deg);
void solvePA2(double u, double h) { void solvePA2(double u, double h);
if (step > 0) void solvePA3(double u, double h);
solvePA(u, h, 2); void solvePA4(double u, double h);
else void solvePA5(double u, double h);
solveEyler1(u, h);
}
void solvePA3(double u, double h) {
if (step > 1)
solvePA(u, h, 3);
else
solvePA2(u, h);
}
void solvePA4(double u, double h) {
if (step > 2)
solvePA(u, h, 4);
else
solvePA3(u, h);
}
void solvePA5(double u, double h) {
if (step > 3)
solvePA(u, h, 5);
else
solvePA4(u, h);
}
PIMathVectord X; PIMathVectord X;
static Method method_global; static Method method_global;
static const char methods_desc[]; static const char methods_desc[];
private: private:
void moveF() { void moveF();
for (uint i = F.size() - 1; i > 0; --i)
F[i] = F[i - 1];
}
PIMathMatrixd A, M; PIMathMatrixd A, M;
PIMathVectord d, a1, b1; PIMathVectord d, a1, b1;
@@ -109,10 +80,10 @@ private:
PIMathVectord XX, Y, pY; PIMathVectord XX, Y, pY;
PIVector<PIMathVectord> F; PIVector<PIMathVectord> F;
PIVector<double> times; PIVector<double> times;
uint size, step; uint size = 0, step = 0;
Method method; Method method = Global;
double sum, td, ct, lp, dh, t, x1, x0; double sum = 0., td = 0., ct = 0., lp = 0., dh = 0., t = 0., x1 = 0., x0 = 0.;
bool ok; bool ok = false;
}; };
#endif // PIMATHSOLVER_H #endif // PIMATHSOLVER_H

View File

@@ -457,7 +457,7 @@ void PIPluginLoader::mergeStatic() {
PIStringList PIPluginLoader::pluginsDirectories(const PIString & name) { PIStringList PIPluginLoader::pluginsDirectories(const PIString & name) {
static PIStringList dl({".", "./plugins", "../PlugIns"}); static PIStringList dl({".", "./plugins", "../PlugIns"});
PIString ret; PIString ret;
piForeachC(PIString d, dl) { for (const auto & d: dl) {
PIString dp = d + "/" + name; PIString dp = d + "/" + name;
if (PIDir::isExists(dp)) ret += dp; if (PIDir::isExists(dp)) ret += dp;
} }
@@ -470,8 +470,8 @@ PIString PIPluginLoader::findLibrary(const PIString & path) {
static const PIStringList suffixes({"", libExtension()}); static const PIStringList suffixes({"", libExtension()});
PIFile::FileInfo fi(path); PIFile::FileInfo fi(path);
PIString dir = fi.dir(), name = fi.name(); PIString dir = fi.dir(), name = fi.name();
piForeachC(PIString & p, prefixes) { for (const auto & p: prefixes) {
piForeachC(PIString & s, suffixes) { for (const auto & s: suffixes) {
PIString fn = dir + p + name + s; PIString fn = dir + p + name + s;
if (PIFile::isExists(fn)) return fn; if (PIFile::isExists(fn)) return fn;
} }

View File

@@ -175,7 +175,7 @@ PIVector<PISystemInfo::MountInfo> PISystemInfo::mountInfo(bool ignore_cache) {
} }
if (l_df.size_s() < 2) return ret; if (l_df.size_s() < 2) return ret;
l_df.pop_front(); l_df.pop_front();
piForeachC(PIString & s, l_df) { for (const auto & s: l_df) {
PIStringList ml(s.replacedAll(" ", " ").split(" ")); PIStringList ml(s.replacedAll(" ", " ").split(" "));
if (ml.size_s() < 2) continue; if (ml.size_s() < 2) continue;
if (ml.front() == "none") continue; if (ml.front() == "none") continue;
@@ -234,17 +234,10 @@ PIString PISystemInfo::machineKey() {
PISystemInfo * si = instance(); PISystemInfo * si = instance();
PIByteArray salt; PIByteArray salt;
PIString conf = confDir() + "/.pip_machine_salt"; PIString conf = confDir() + "/.pip_machine_salt";
if (PIFile::isExists(conf)) { if (PIFile::isExists(conf)) salt = PIFile::readAll(conf, false);
PIFile f(conf, PIIODevice::ReadOnly);
f.open();
salt = f.readAll();
}
if (salt.size_s() != SALT_SIZE) { if (salt.size_s() != SALT_SIZE) {
salt = generateSalt(); salt = generateSalt();
PIFile f(conf, PIIODevice::ReadWrite); PIFile::writeAll(conf, salt);
f.open();
f.clear();
f.write(salt);
} }
ret = si->OS_name + "_" + si->architecture + "_" + si->hostname + "_" + salt.toHex(); ret = si->OS_name + "_" + si->architecture + "_" + si->hostname + "_" + salt.toHex();
} }

View File

@@ -320,7 +320,7 @@ void PIString::appendFromChars(const char * c, int s, const char * codepage) {
d.enlarge(sz); d.enlarge(sz);
MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, s, (LPWSTR)d.data(old_sz), sz); MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, s, (LPWSTR)d.data(old_sz), sz);
# else # else
std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> ucs2conv; std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> ucs2conv;
std::u16string ucs2 = ucs2conv.from_bytes(c, c + s); std::u16string ucs2 = ucs2conv.from_bytes(c, c + s);
d.enlarge(ucs2.size()); d.enlarge(ucs2.size());
ucs2.copy((char16_t *)d.data(old_sz), ucs2.size()); ucs2.copy((char16_t *)d.data(old_sz), ucs2.size());
@@ -488,7 +488,7 @@ void PIString::buildData(const char * cp) const {
data_size_ = sz; data_size_ = sz;
return; return;
# else # else
std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> ucs2conv; std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> ucs2conv;
std::string u8str = ucs2conv.to_bytes((char16_t *)d.data(), (char16_t *)d.data() + d.size()); std::string u8str = ucs2conv.to_bytes((char16_t *)d.data(), (char16_t *)d.data() + d.size());
data_ = (char *)malloc(u8str.size() + 1); data_ = (char *)malloc(u8str.size() + 1);
strcpy(data_, u8str.c_str()); strcpy(data_, u8str.c_str());
@@ -1515,6 +1515,7 @@ PIString PIString::takeNumber() {
} }
phase = 9; phase = 9;
break; break;
default: break;
} }
if (phase == 6) { if (phase == 6) {
if (c == 'f' || c == 's' || c == 'u' || c == 'l' || c == 'L') if (c == 'f' || c == 's' || c == 'u' || c == 'l' || c == 'L')

View File

@@ -83,7 +83,7 @@ public:
private: private:
PIVector<PIThread *> threads; PIVector<PIThread *> threads;
std::function<void(int)> func; std::function<void(int)> func;
std::atomic_int counter; std::atomic_int counter = {0};
}; };

View File

@@ -121,7 +121,7 @@ int PIPropertyStorage::removePropertiesByFlag(int flag) {
//! \~russian "flag_ignore" - битовое поле для исключения свойств из процесса слияния //! \~russian "flag_ignore" - битовое поле для исключения свойств из процесса слияния
void PIPropertyStorage::updateProperties(const PIVector<PIPropertyStorage::Property> & properties_, int flag_ignore) { void PIPropertyStorage::updateProperties(const PIVector<PIPropertyStorage::Property> & properties_, int flag_ignore) {
PIMap<PIString, PIVariant> values; PIMap<PIString, PIVariant> values;
piForeachC(Property & p, props) for (const auto & p: props)
if (((p.flags & flag_ignore) != flag_ignore) || (flag_ignore == 0)) values[p.name] = p.value; if (((p.flags & flag_ignore) != flag_ignore) || (flag_ignore == 0)) values[p.name] = p.value;
props = properties_; props = properties_;
for (uint i = 0; i < props.size(); ++i) { for (uint i = 0; i < props.size(); ++i) {
@@ -135,14 +135,14 @@ void PIPropertyStorage::updateProperties(const PIVector<PIPropertyStorage::Prope
PIPropertyStorage::Property PIPropertyStorage::propertyByName(const PIString & name) const { PIPropertyStorage::Property PIPropertyStorage::propertyByName(const PIString & name) const {
piForeachC(Property & p, props) for (const auto & p: props)
if (p.name == name) return p; if (p.name == name) return p;
return Property(); return Property();
} }
PIVariant PIPropertyStorage::propertyValueByName(const PIString & name) const { PIVariant PIPropertyStorage::propertyValueByName(const PIString & name) const {
piForeachC(Property & p, props) for (const auto & p: props)
if (p.name == name) return p.value; if (p.name == name) return p.value;
return PIVariant(); return PIVariant();
} }
@@ -182,7 +182,7 @@ bool PIPropertyStorage::setPropertyFlags(const PIString & name, int flags) {
PIPropertyStorage::Property & PIPropertyStorage::operator[](const PIString & name) { PIPropertyStorage::Property & PIPropertyStorage::operator[](const PIString & name) {
piForeach(Property & p, props) for (auto & p: props)
if (p.name == name) return p; if (p.name == name) return p;
addProperty(name, ""); addProperty(name, "");
return props.back(); return props.back();
@@ -190,7 +190,7 @@ PIPropertyStorage::Property & PIPropertyStorage::operator[](const PIString & nam
const PIPropertyStorage::Property PIPropertyStorage::operator[](const PIString & name) const { const PIPropertyStorage::Property PIPropertyStorage::operator[](const PIString & name) const {
piForeachC(Property & p, props) for (const auto & p: props)
if (p.name == name) return p; if (p.name == name) return p;
return Property(); return Property();
} }

View File

@@ -128,7 +128,7 @@ PIString PIVariantTypes::IODevice::toPICout() const {
} }
#endif // MICRO_PIP #endif // MICRO_PIP
PIPropertyStorage ps = get(); PIPropertyStorage ps = get();
piForeachC(PIPropertyStorage::Property & p, ps) { for (const auto & p: ps) {
s += ", " + p.name + "=\"" + p.value.toString() + "\""; s += ", " + p.name + "=\"" + p.value.toString() + "\"";
} }
s += ")"; s += ")";

View File

@@ -48,7 +48,7 @@ const PIVector<PIOpenCL::Platform> & PIOpenCL::platforms() {
const PIVector<PIOpenCL::Device> PIOpenCL::devices() { const PIVector<PIOpenCL::Device> PIOpenCL::devices() {
PIVector<PIOpenCL::Device> ret; PIVector<PIOpenCL::Device> ret;
PIVector<PIOpenCL::Platform> pl = platforms(); PIVector<PIOpenCL::Platform> pl = platforms();
piForeachC(PIOpenCL::Platform & p, pl) for (const auto & p: pl)
ret << p.devices; ret << p.devices;
return ret; return ret;
} }
@@ -56,8 +56,8 @@ const PIVector<PIOpenCL::Device> PIOpenCL::devices() {
PIOpenCL::Device PIOpenCL::deviceByID(void * id) { PIOpenCL::Device PIOpenCL::deviceByID(void * id) {
PIVector<PIOpenCL::Platform> pl = platforms(); PIVector<PIOpenCL::Platform> pl = platforms();
piForeachC(PIOpenCL::Platform & p, pl) { for (const auto & p: pl) {
piForeachC(PIOpenCL::Device & d, p.devices) { for (const auto & d: p.devices) {
if (d.id == id) return d; if (d.id == id) return d;
} }
} }
@@ -179,7 +179,7 @@ void PIOpenCL::Context::deletePrograms() {
piCout << "context: delete" << programs_.size() << "programs"; piCout << "context: delete" << programs_.size() << "programs";
PIVector<Program *> ptdl = programs_; PIVector<Program *> ptdl = programs_;
programs_.clear(); programs_.clear();
piForeach(Program * p, ptdl) { for (auto * p: ptdl) {
if (p) delete p; if (p) delete p;
} }
} }
@@ -189,7 +189,7 @@ void PIOpenCL::Context::deleteBuffers() {
piCout << "context: delete" << buffers_.size() << "buffers"; piCout << "context: delete" << buffers_.size() << "buffers";
PIVector<Buffer *> btdl = buffers_; PIVector<Buffer *> btdl = buffers_;
buffers_.clear(); buffers_.clear();
piForeach(Buffer * b, btdl) { for (auto * b: btdl) {
if (b) delete b; if (b) delete b;
} }
} }
@@ -227,7 +227,7 @@ PIOpenCL::Context * PIOpenCL::Context::create(const PIOpenCL::DeviceList & dl) {
PIOpenCL::Context * PIOpenCL::Context::create(const PIString & part_name) { PIOpenCL::Context * PIOpenCL::Context::create(const PIString & part_name) {
PIString pn = part_name.toLowerCase(); PIString pn = part_name.toLowerCase();
PIVector<Device> dl = PIOpenCL::devices(); PIVector<Device> dl = PIOpenCL::devices();
piForeachC(Device & d, dl) { for (const auto & d: dl) {
if (d.displayText().toLowerCase().contains(pn)) return create(d); if (d.displayText().toLowerCase().contains(pn)) return create(d);
} }
return 0; return 0;
@@ -283,13 +283,13 @@ PIOpenCL::Program * PIOpenCL::Context::createProgram(const PIString & source, co
} }
PIStringList knl = PIString(knames).trim().split(";"); PIStringList knl = PIString(knames).trim().split(";");
PIVector<void *> kerns; PIVector<void *> kerns;
piForeachC(PIString & k, knl) { for (const auto & k: knl) {
cl_kernel kern = clCreateKernel(prog, k.dataAscii(), &ret); cl_kernel kern = clCreateKernel(prog, k.dataAscii(), &ret);
if (ret != 0) { if (ret != 0) {
piCout << "[PIOpenCL::Context]" piCout << "[PIOpenCL::Context]"
<< "clCreateKernel" << k << "error" << ret; << "clCreateKernel" << k << "error" << ret;
if (error) (*error) += "clCreateKernel(\"" + k + "\") error " + ret; if (error) (*error) += "clCreateKernel(\"" + k + "\") error " + ret;
piForeach(void * _k, kerns) for (auto * _k: kerns)
clReleaseKernel((cl_kernel)_k); clReleaseKernel((cl_kernel)_k);
clReleaseProgram(prog); clReleaseProgram(prog);
return 0; return 0;
@@ -472,7 +472,7 @@ PIOpenCL::Program::Program() {
PIOpenCL::Program::~Program() { PIOpenCL::Program::~Program() {
// piCout << "destroy program" << this; // piCout << "destroy program" << this;
if (context_) context_->programs_.removeAll(this); if (context_) context_->programs_.removeAll(this);
piForeach(Kernel * k, kernels_) for (auto * k: kernels_)
delete k; delete k;
if (PRIVATE->program) clReleaseProgram(PRIVATE->program); if (PRIVATE->program) clReleaseProgram(PRIVATE->program);
zero(); zero();
@@ -487,7 +487,7 @@ void PIOpenCL::Program::zero() {
bool PIOpenCL::Program::initKernels(PIVector<void *> kerns) { bool PIOpenCL::Program::initKernels(PIVector<void *> kerns) {
piForeach(void * _k, kerns) { for (auto * _k: kerns) {
cl_kernel k = (cl_kernel)_k; cl_kernel k = (cl_kernel)_k;
// piCout << "init kernel" << k; // piCout << "init kernel" << k;
Kernel * kern = new Kernel(); Kernel * kern = new Kernel();
@@ -635,7 +635,7 @@ int PIOpenCL::Kernel::argIndex(const PIString & an) const {
PIOpenCL::KernelArg PIOpenCL::Kernel::argByName(const PIString & an) const { PIOpenCL::KernelArg PIOpenCL::Kernel::argByName(const PIString & an) const {
piForeachC(KernelArg & a, args_) for (const auto & a: args_)
if (a.arg_name == an) return a; if (a.arg_name == an) return a;
return KernelArg(); return KernelArg();
} }

View File

@@ -1,3 +1,4 @@
#include "pihttpclient.h"
#include "pip.h" #include "pip.h"
using namespace PICoutManipulators; using namespace PICoutManipulators;
@@ -10,9 +11,74 @@ const char * pageTitle = "<!DOCTYPE html>"
"</body>" "</body>"
"</html>"; "</html>";
template<typename T>
PIString stringify(const T & v) {
PIString ret;
PICout::withExternalBuffer(&ret, 0, PICoutManipulators::AddSpaces) << v;
return ret;
}
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
PIHTTPServer server;
server.listen({"127.0.0.1:7777"});
server.setBasicAuthRealm("pip");
server.setBasicAuthEnabled(true);
server.setBasicAuthCallback([](const PIString & u, const PIString & p) -> bool {
piCout << "basic auth" << u << p;
return (u == "u" && p == "p");
});
server.registerUnhandled([](const PIHTTP::MessageConst & msg) -> PIHTTP::MessageMutable {
PIHTTP::MessageMutable ret;
piCout << "server rec:\n\tpath: %1\n\tmethod: %2\n\targs: %3\n\theaders: %4\n\tbody: %5\n"_a.arg(msg.path())
.arg((int)msg.method())
.arg(stringify(msg.arguments()))
.arg(PIStringList(msg.headers().map<PIString>([](PIString k, PIString v) { return k + " = " + v; })).join("\n\t\t"))
.arg(PIString::fromUTF8(msg.body()));
ret.setCode(PIHTTP::Code::BadRequest);
ret.setBody(PIByteArray::fromAscii("hello client! 0123456789"));
return ret;
});
PIHTTP::MessageMutable req;
req.setBody(PIByteArray::fromAscii("hello server!"));
auto * c = PIHTTPClient::create("http://u:p@127.0.0.1:7777/api", PIHTTP::Method::Get, req);
c->onFinish([](PIHTTP::MessageConst msg) {
piCout << "client rec:\n\tcode: %5\n\tpath: %1\n\tmethod: %2\n\targs: %3\n\tbody: %4\n"_a.arg(msg.path())
.arg((int)msg.method())
.arg(stringify(msg.arguments()))
.arg(PIString::fromUTF8(msg.body()))
.arg((int)msg.code());
})
->onError([c](PIHTTP::MessageConst r) {
piCout << "error" << (int)r.code();
piCout << "msg" << c->lastError();
})
->onAbort([c](PIHTTP::MessageConst r) {
piCout << "abort" << (int)r.code();
piCout << "msg" << c->lastError();
})
->start();
// piMSleep(500);
kbd.enableExitCapture(); kbd.enableExitCapture();
WAIT_FOR_EXIT
server.stop();
// c->abort();
return 0;
// piCout << PIString::readableSize(PISystemMonitor::usedRAM());
/*PIVector<int> vi;
piForTimes(10) {
piSleep(2.);
vi.enlarge(1000000);
piCout << "now" << vi.size() << vi.capacity();
}
piSleep(5.);*/
/*kbd.enableExitCapture();
PIHTTPServer server; PIHTTPServer server;
@@ -39,7 +105,7 @@ int main(int argc, char * argv[]) {
return ret; return ret;
}); });
server.registerPath("/api/*", MicrohttpdServer::Method::Post, [](const MicrohttpdServer::Request & r) -> MicrohttpdServer::Reply { server.registerPath("/api/", MicrohttpdServer::Method::Post, [](const MicrohttpdServer::Request & r) -> MicrohttpdServer::Reply {
MicrohttpdServer::Reply ret; MicrohttpdServer::Reply ret;
ret.setBody("<!DOCTYPE html><html><body>API etry %1</body></html>"_a.arg(r.path).toUTF8()); ret.setBody("<!DOCTYPE html><html><body>API etry %1</body></html>"_a.arg(r.path).toUTF8());
ret.setCode(405); ret.setCode(405);
@@ -51,7 +117,7 @@ int main(int argc, char * argv[]) {
ret.setBody("<!DOCTYPE html><html><body>Unknown</body></html>"_a.arg(r.path).toUTF8()); ret.setBody("<!DOCTYPE html><html><body>Unknown</body></html>"_a.arg(r.path).toUTF8());
ret.setCode(404); ret.setCode(404);
return ret; return ret;
}); });*/
/*server.setRequestCallback([](MicrohttpdServer::Request r) -> MicrohttpdServer::Reply { /*server.setRequestCallback([](MicrohttpdServer::Request r) -> MicrohttpdServer::Reply {
MicrohttpdServer::Reply rep; MicrohttpdServer::Reply rep;
@@ -63,10 +129,12 @@ int main(int argc, char * argv[]) {
rep.setBody(PIByteArray::fromAscii("[{\"value1\": true, \"value2\": \"ыекштп\"}]")); rep.setBody(PIByteArray::fromAscii("[{\"value1\": true, \"value2\": \"ыекштп\"}]"));
return rep; return rep;
});*/ });*/
piCout << "start" << server.isListen();
/*piCout << "start" << server.isListen();
WAIT_FOR_EXIT WAIT_FOR_EXIT
server.stop(); server.stop();*/
return 0; return 0;
} }

View File

@@ -152,7 +152,7 @@ PIMap<PIString, PIStringList> qt_filters;
PIString findLib(const PIString & l) { PIString findLib(const PIString & l) {
if (PIFile::isExists(l)) return l; if (PIFile::isExists(l)) return l;
piForeachC(PIString & s, lib_dirs) { for (const auto & s: lib_dirs) {
if (PIFile::isExists(s + l)) return s + l; if (PIFile::isExists(s + l)) return s + l;
if (win_target || l.toLowerCase().endsWith("dll")) { if (win_target || l.toLowerCase().endsWith("dll")) {
PIFile::FileInfo info(l); PIFile::FileInfo info(l);
@@ -308,13 +308,13 @@ void procLdd(PIString file, bool ext_lib = false, int cur_depth = 0) {
} }
if (!otool.isEmpty()) { if (!otool.isEmpty()) {
lines = filter(execute(otool + " -L \"" + file + "\""), "("); lines = filter(execute(otool + " -L \"" + file + "\""), "(");
piForeach(PIString & l, lines) { for (auto & l: lines) {
l = l.left(l.find('(')); l = l.left(l.find('('));
l.trim(); //.append('.').prepend('.'); l.trim(); //.append('.').prepend('.');
} }
} }
} }
piForeachC(PIString & sl, lines) { for (const auto & sl: lines) {
PIString l = sl.trimmed(); PIString l = sl.trimmed();
if (!otool.isEmpty()) { if (!otool.isEmpty()) {
PIString fname = frameworkName(l); PIString fname = frameworkName(l);
@@ -367,7 +367,7 @@ void procLdd(PIString file, bool ext_lib = false, int cur_depth = 0) {
} }
PIVector<PIString> clibs = cur_libs.toVector(); PIVector<PIString> clibs = cur_libs.toVector();
if (!clibs.isEmpty()) piCout << " new dependencies:\n -" << PIStringList(clibs).join("\n - "); if (!clibs.isEmpty()) piCout << " new dependencies:\n -" << PIStringList(clibs).join("\n - ");
piForeachC(PIString & l, clibs) { for (const auto & l: clibs) {
procLdd(l, false, cur_depth); procLdd(l, false, cur_depth);
} }
} }
@@ -402,7 +402,7 @@ void procQt() {
PIDir(qt_plugins_dir).make(true); PIDir(qt_plugins_dir).make(true);
PIDir(qt_qml_dir).make(true); PIDir(qt_qml_dir).make(true);
} }
piForeach(PIString l, vsl) { for (auto l: vsl) {
if (l.trim().contains("Qt version")) { if (l.trim().contains("Qt version")) {
l.cutLeft(l.find("Qt version") + 10).trim(); l.cutLeft(l.find("Qt version") + 10).trim();
PIString qv = l.takeWord(); PIString qv = l.takeWord();
@@ -411,7 +411,7 @@ void procQt() {
piCout << "Qt" << qv << "in" << qloc; piCout << "Qt" << qv << "in" << qloc;
PIString qdir; PIString qdir;
PIStringList suffixes({".", "..", "qt5", "../qt5", "qt6", "../qt6"}); PIStringList suffixes({".", "..", "qt5", "../qt5", "qt6", "../qt6"});
piForeachC(PIString s, suffixes) { for (const auto & s: suffixes) {
PIString qd = qloc + "/" + s + "/plugins/"; PIString qd = qloc + "/" + s + "/plugins/";
if (piDebug) PICout(AddSpaces) << "Qt plugins root try" << qd << "..."; if (piDebug) PICout(AddSpaces) << "Qt plugins root try" << qd << "...";
if (PIDir::isExists(qd + "platforms")) { if (PIDir::isExists(qd + "platforms")) {
@@ -422,14 +422,14 @@ void procQt() {
piCout << " no"; piCout << " no";
} }
if (qdir.isEmpty()) break; if (qdir.isEmpty()) break;
piForeachC(PIString & plugin, pdirs) { for (const auto & plugin: pdirs) {
PIStringList filters = qt_filters[plugin]; PIStringList filters = qt_filters[plugin];
piCout << "PLUG" << plugin << filters; piCout << "PLUG" << plugin << filters;
piForeachC(PIString & f, filters) { for (const auto & f: filters) {
if (f.isEmpty()) continue; if (f.isEmpty()) continue;
copyWildcard(qdir + "plugins/" + plugin + "/" + f, qt_plugins_dir + plugin); copyWildcard(qdir + "plugins/" + plugin + "/" + f, qt_plugins_dir + plugin);
PIVector<PIFile::FileInfo> copied = PIDir(qt_plugins_dir + plugin).entries(); PIVector<PIFile::FileInfo> copied = PIDir(qt_plugins_dir + plugin).entries();
piForeachC(PIFile::FileInfo & fi, copied) { for (const auto & fi: copied) {
if (fi.isFile()) { if (fi.isFile()) {
procLdd(fi.path); procLdd(fi.path);
plugin_libs << fi.path; plugin_libs << fi.path;
@@ -441,7 +441,7 @@ void procQt() {
if (q.isEmpty()) continue; if (q.isEmpty()) continue;
copyWildcard(qdir + "qml/" + q + "/*", qt_qml_dir + q); copyWildcard(qdir + "qml/" + q + "/*", qt_qml_dir + q);
PIVector<PIFile::FileInfo> copied = PIDir(qt_qml_dir + q).allEntries(); PIVector<PIFile::FileInfo> copied = PIDir(qt_qml_dir + q).allEntries();
piForeachC(PIFile::FileInfo & fi, copied) { for (const auto & fi: copied) {
if (fi.isFile()) { if (fi.isFile()) {
procLdd(fi.path); procLdd(fi.path);
plugin_libs << fi.path; plugin_libs << fi.path;
@@ -481,11 +481,11 @@ void patchNameTool() {
PIFile::FileInfo fi; PIFile::FileInfo fi;
patch_list = input_files; patch_list = input_files;
patch_list << plugin_libs; patch_list << plugin_libs;
piForeach(PIString l, clibs) { for (const auto & l: clibs) {
fi.path = l; fi.path = l;
patch_list << (out_dir + fi.name()); patch_list << (out_dir + fi.name());
} }
piForeach(PIString local_lib, patch_list) { for (const auto & local_lib: patch_list) {
execute("chmod +w \"" + local_lib + "\""); execute("chmod +w \"" + local_lib + "\"");
fi.path = local_lib; fi.path = local_lib;
cmd = nametool + " -id \"@executable_path/../Frameworks/" + fi.name() + "\""; cmd = nametool + " -id \"@executable_path/../Frameworks/" + fi.name() + "\"";
@@ -493,15 +493,15 @@ void patchNameTool() {
// piCout << " " << cmd; // piCout << " " << cmd;
execute(cmd); execute(cmd);
} }
piForeach(PIString f, flibs) { for (const auto & f: flibs) {
PIString fl = findLib(frameworkName(f)); PIString fl = findLib(frameworkName(f));
if (fl.isEmpty()) continue; if (fl.isEmpty()) continue;
patch_list << (out_dir + frameworkName(f) + "/" + frameworkInternalPath(f)); patch_list << (out_dir + frameworkName(f) + "/" + frameworkInternalPath(f));
// PICout(DefaultControls) << "map" << f << "->" << (out_dir + frameworkName(f) + "/" + frameworkInternalPath(f)); // PICout(DefaultControls) << "map" << f << "->" << (out_dir + frameworkName(f) + "/" + frameworkInternalPath(f));
} }
piForeach(PIString local_lib, patch_list) { for (const auto & local_lib: patch_list) {
dlibs = filter(execute(otool + " -L \"" + local_lib + "\""), "("); dlibs = filter(execute(otool + " -L \"" + local_lib + "\""), "(");
piForeach(PIString & l, dlibs) { for (auto & l: dlibs) {
l = l.left(l.find('(')); l = l.left(l.find('('));
l.trim(); l.trim();
} }
@@ -509,7 +509,7 @@ void patchNameTool() {
execute("chmod +w \"" + local_lib + "\""); execute("chmod +w \"" + local_lib + "\"");
} }
piCout << "patch" << local_lib; piCout << "patch" << local_lib;
piForeach(PIString sys_lib, dlibs) { for (auto sys_lib: dlibs) {
sys_lib.cutRight(1).trim(); sys_lib.cutRight(1).trim();
fi.path = sys_lib; fi.path = sys_lib;
libname = fi.name(); libname = fi.name();
@@ -536,7 +536,7 @@ void patchNameTool() {
} }
} }
} }
piForeach(PIString bin, input_files) { for (const auto & bin: input_files) {
cmd = nametool + " -add_rpath \"@executable_path/../Frameworks\""; cmd = nametool + " -add_rpath \"@executable_path/../Frameworks\"";
cmd += " \"" + bin + "\"" + ign_err_suffix; cmd += " \"" + bin + "\"" + ign_err_suffix;
execute(cmd); execute(cmd);
@@ -559,9 +559,9 @@ void patchRPathFile(const PIFile::FileInfo & file) {
void patchRPath() { void patchRPath() {
PIStringList dirs({out_dir, target_dir, qt_plugins_dir, qt_qml_dir}); PIStringList dirs({out_dir, target_dir, qt_plugins_dir, qt_qml_dir});
dirs.removeDuplicates().removeStrings(PIString()); dirs.removeDuplicates().removeStrings(PIString());
piForeachC(PIString & d, dirs) { for (const auto & d: dirs) {
PIVector<PIFile::FileInfo> files = PIDir(d).allEntries(); PIVector<PIFile::FileInfo> files = PIDir(d).allEntries();
piForeachC(PIFile::FileInfo & f, files) { for (const auto & f: files) {
if (f.isDir()) continue; if (f.isDir()) continue;
patchRPathFile(f.path); patchRPathFile(f.path);
} }
@@ -649,7 +649,7 @@ int main(int argc, char * argv[]) {
if (!qroot.endsWith("/")) qroot.append("/"); if (!qroot.endsWith("/")) qroot.append("/");
lib_dirs << (qroot + "bin") << (qroot + "lib") << (qroot + "Frameworks"); lib_dirs << (qroot + "bin") << (qroot + "lib") << (qroot + "Frameworks");
} }
piForeach(PIString & s, lib_dirs) { for (auto & s: lib_dirs) {
s.trim(); s.trim();
if (!s.endsWith("/")) s += "/"; if (!s.endsWith("/")) s += "/";
} }
@@ -669,7 +669,7 @@ int main(int argc, char * argv[]) {
styles = cli.argumentValue("Styles").split(","); styles = cli.argumentValue("Styles").split(",");
if (styles.isEmpty()) styles << ""; if (styles.isEmpty()) styles << "";
PIStringList qpd = cli.argumentValue("qt-plugins").toLowerCase().split(DELIM).removeAll(""); PIStringList qpd = cli.argumentValue("qt-plugins").toLowerCase().split(DELIM).removeAll("");
piForeachC(PIString & qp, qpd) { for (const auto & qp: qpd) {
int _i = qp.find('='); int _i = qp.find('=');
if (_i < 0) continue; if (_i < 0) continue;
PIString pname = qp.left(_i).trim(); PIString pname = qp.left(_i).trim();
@@ -739,7 +739,7 @@ int main(int argc, char * argv[]) {
checkQtLib(f); checkQtLib(f);
}); });
} }
piForeach(PIString & s, add_libs) { for (auto & s: add_libs) {
if (s.isEmpty()) continue; if (s.isEmpty()) continue;
PIString alib = findLib(s); PIString alib = findLib(s);
if (alib.isEmpty()) continue; if (alib.isEmpty()) continue;
@@ -752,7 +752,7 @@ int main(int argc, char * argv[]) {
if (is_deps) { // if Qt in system, then no plugins copy if (is_deps) { // if Qt in system, then no plugins copy
PIVector<PIString> qlibs = qt_libs.toVector(); PIVector<PIString> qlibs = qt_libs.toVector();
piCout << "check for installed Qt" << qlibs; piCout << "check for installed Qt" << qlibs;
piForeach(PIString l, qlibs) { for (const auto & l: qlibs) {
if (procDpkg(l)) { if (procDpkg(l)) {
piCout << "system Qt found!"; piCout << "system Qt found!";
need_qt_plugins = false; need_qt_plugins = false;
@@ -783,7 +783,7 @@ int main(int argc, char * argv[]) {
out_dir.replaceAll("/", "\\"); out_dir.replaceAll("/", "\\");
#endif #endif
PIVector<PIString> clibs = all_libs.toVector(); PIVector<PIString> clibs = all_libs.toVector();
piForeach(PIString l, clibs) { for (auto l: clibs) {
PIFile::FileInfo fi; PIFile::FileInfo fi;
fi.path = l; fi.path = l;
#ifdef WINDOWS #ifdef WINDOWS
@@ -803,7 +803,7 @@ int main(int argc, char * argv[]) {
} }
} }
PIVector<PIString> fwdirs = frameworks.toVector(); PIVector<PIString> fwdirs = frameworks.toVector();
piForeachC(PIString & f, fwdirs) { for (const auto & f: fwdirs) {
PIString fd = findLib(f); PIString fd = findLib(f);
if (!fd.isEmpty()) { if (!fd.isEmpty()) {
piCout << "copy framework" << f; piCout << "copy framework" << f;

View File

@@ -78,7 +78,7 @@ void Daemon::Remote::termTimerTick() {
void Daemon::Remote::startAction(Daemon::PacketType a, const PIString & dir, const PIStringList & fl) { void Daemon::Remote::startAction(Daemon::PacketType a, const PIString & dir, const PIStringList & fl) {
_fl = fl; _fl = fl;
if (!dir.isEmpty()) if (!dir.isEmpty())
piForeach(PIString & s, _fl) for (auto & s: _fl)
s.prepend(dir); s.prepend(dir);
// piCout << "send" << _fl; // piCout << "send" << _fl;
action = a; action = a;
@@ -122,7 +122,7 @@ void Daemon::Remote::updateDirEntries() {
// piCout << dir_my; // piCout << dir_my;
if (!dir_my.isExists()) dir_my = PIDir::current(); if (!dir_my.isExists()) dir_my = PIDir::current();
my_filelist = dir_my.entries(); my_filelist = dir_my.entries();
piForeach(PIFile::FileInfo & f, my_filelist) for (auto & f: my_filelist)
f.path = f.name(); f.path = f.name();
} }
@@ -325,7 +325,7 @@ Daemon::~Daemon() {
dtimer.stopAndWait(); dtimer.stopAndWait();
requestCloseShell(); requestCloseShell();
PIVector<Remote *> rl = remotes.values(); PIVector<Remote *> rl = remotes.values();
piForeach(Remote * r, rl) { for (auto * r: rl) {
r->shellClose(); r->shellClose();
delete r; delete r;
} }
@@ -554,7 +554,7 @@ void Daemon::timerEvent(int delim) {
screen->lock(); screen->lock();
list_daemons->content.clear(); list_daemons->content.clear();
availableDaemons(); availableDaemons();
piForeachC(PIString & i, available_daemons) for (const auto & i: available_daemons)
list_daemons->content << TileList::Row(i, CellFormat()); list_daemons->content << TileList::Row(i, CellFormat());
screen->unlock(); screen->unlock();
if (delim == 5 && mode == rmInformation) { if (delim == 5 && mode == rmInformation) {
@@ -570,7 +570,7 @@ void Daemon::timerEvent(int delim) {
PIStringList Daemon::availableDaemons() { PIStringList Daemon::availableDaemons() {
available_daemons.clear(); available_daemons.clear();
lock(); lock();
piForeachC(PIPeer::PeerInfo & p, allPeers()) { for (const auto & p: allPeers()) {
if (!p.name.startsWith(pisd_prefix)) continue; if (!p.name.startsWith(pisd_prefix)) continue;
available_daemons << p.name.mid(6); available_daemons << p.name.mid(6);
} }

View File

@@ -15,7 +15,7 @@ PIStringList FileManager::TileDir::selectedNames() const {
PIStringList ret; PIStringList ret;
PIMutexLocker ml(e_mutex); PIMutexLocker ml(e_mutex);
PIVector<int> sind = selected.toVector(); PIVector<int> sind = selected.toVector();
piForeachC(int i, sind) for (const auto i: sind)
ret << entries[i].name(); ret << entries[i].name();
ret.removeOne(".."); ret.removeOne("..");
return ret; return ret;
@@ -181,7 +181,7 @@ void FileManager::TileDir::buildNames() {
CharFlags cf = 0; CharFlags cf = 0;
Color cc = Default; Color cc = Default;
PIString fcol, scol; PIString fcol, scol;
piForeachC(PIFile::FileInfo & e, entries) { for (const auto & e: entries) {
if (e.isDir()) { if (e.isDir()) {
t = '/'; t = '/';
cf = Bold; cf = Bold;
@@ -258,7 +258,7 @@ FileManager::FileManager() {
labels->direction = Horizontal; labels->direction = Horizontal;
PIVector<SSPair> ll; PIVector<SSPair> ll;
ll << SSPair(" Esc", "Exit") << SSPair(" F5", "Copy") << SSPair(" F6", "Move") << SSPair(" F7", "MkDir") << SSPair(" F8", "Delete"); ll << SSPair(" Esc", "Exit") << SSPair(" F5", "Copy") << SSPair(" F6", "Move") << SSPair(" F7", "MkDir") << SSPair(" F8", "Delete");
piForeachC(SSPair & l, ll) { for (const auto & l: ll) {
tl = new TileSimple(); tl = new TileSimple();
labels->addTile(tl); labels->addTile(tl);
tl->content << TileSimple::Row(l.first, CellFormat(White, Transparent, Bold)); tl->content << TileSimple::Row(l.first, CellFormat(White, Transparent, Bold));
@@ -315,7 +315,7 @@ PIStringList FileManager::selectedRemote() const {
PIStringList ret; PIStringList ret;
panels[1]->lock(); panels[1]->lock();
PIVector<int> sil = panels[1]->selected.toVector(); PIVector<int> sil = panels[1]->selected.toVector();
piForeachC(int i, sil) for (const auto i: sil)
ret << panels[1]->entries[i].path; ret << panels[1]->entries[i].path;
panels[1]->unlock(); panels[1]->unlock();
return ret; return ret;

View File

@@ -197,7 +197,7 @@ public:
// "]" // "]"
, ,
CellFormat()); CellFormat());
piForeachC(PIPeer::PeerInfo & p, daemon_.allPeers()) for (const auto & p: daemon_.allPeers())
peers_tl->content << TileList::Row(p.name + " | d = " + PIString::fromNumber(p.dist) + " | p = " + peers_tl->content << TileList::Row(p.name + " | d = " + PIString::fromNumber(p.dist) + " | p = " +
PIString::fromNumber(p.ping()) + " | n = " + PIString::fromBool(p.isNeighbour()), PIString::fromNumber(p.ping()) + " | n = " + PIString::fromBool(p.isNeighbour()),
CellFormat()); CellFormat());
@@ -206,7 +206,7 @@ public:
peerinfo_tl->content << TileSimple::Row("Name: " + pi.name, CellFormat()); peerinfo_tl->content << TileSimple::Row("Name: " + pi.name, CellFormat());
peerinfo_tl->content << TileSimple::Row("Addreses: " + PIString::fromNumber(pi.addresses.size()), CellFormat()); peerinfo_tl->content << TileSimple::Row("Addreses: " + PIString::fromNumber(pi.addresses.size()), CellFormat());
peerinfo_tl->content << TileSimple::Row("Neighbours: " + pi.neighbours.join(", "), CellFormat()); peerinfo_tl->content << TileSimple::Row("Neighbours: " + pi.neighbours.join(", "), CellFormat());
piForeachC(PIPeer::PeerInfo::PeerAddress & a, pi.addresses) for (const auto & a: pi.addresses)
addrs_tl->content << TileList::Row(a.address.toString() + " | p = " + PIString::fromNumber(a.ping) + addrs_tl->content << TileList::Row(a.address.toString() + " | p = " + PIString::fromNumber(a.ping) +
" | a = " + PIString::fromBool(a.isAvailable()), " | a = " + PIString::fromBool(a.isAvailable()),
CellFormat()); CellFormat());
@@ -217,7 +217,7 @@ public:
s += " -> " + pp->name; s += " -> " + pp->name;
peermap << s; peermap << s;
} }
piForeachC(PIString & s, peermap) for (const auto & s: peermap)
peermap_tl->content << TileList::Row(s, CellFormat()); peermap_tl->content << TileList::Row(s, CellFormat());
updatePeerDiag(peerdiagdata_tl, daemon_.diagnosticData()); updatePeerDiag(peerdiagdata_tl, daemon_.diagnosticData());
updatePeerDiag(peerdiagservice_tl, daemon_.diagnosticService()); updatePeerDiag(peerdiagservice_tl, daemon_.diagnosticService());
@@ -238,9 +238,9 @@ public:
tile->content << TileList::Row("PID: " + PIString::fromNumber(sys_mon.statistic().ID), CellFormat()); tile->content << TileList::Row("PID: " + PIString::fromNumber(sys_mon.statistic().ID), CellFormat());
tile->content << TileList::Row(line, CellFormat()); tile->content << TileList::Row(line, CellFormat());
tile->content << TileList::Row("Threads:", CellFormat()); tile->content << TileList::Row("Threads:", CellFormat());
piForeachC(PISystemMonitor::ThreadStats & t, ts) for (const auto & t: ts)
maxlen = piMaxi(maxlen, t.name.length()); maxlen = piMaxi(maxlen, t.name.length());
piForeachC(PISystemMonitor::ThreadStats & t, ts) { for (const auto & t: ts) {
line = PIString::fromNumber(++num).expandLeftTo(2, ' ') + ": "; line = PIString::fromNumber(++num).expandLeftTo(2, ' ') + ": ";
line += PIString(t.name).expandRightTo(maxlen, ' ') + ": k "; line += PIString(t.name).expandRightTo(maxlen, ' ') + ": k ";
PIString ns = PIString::fromNumber(t.cpu_load_kernel, 'f', 2); PIString ns = PIString::fromNumber(t.cpu_load_kernel, 'f', 2);
@@ -256,7 +256,7 @@ public:
if (tinfo->visible) updateSysMon(); if (tinfo->visible) updateSysMon();
} }
EVENT_HANDLER(void, menuRequest) { EVENT_HANDLER(void, menuRequest) {
piForeach(PIScreenTile * t, mtiles) for (auto * t: mtiles)
t->hide(); t->hide();
daemon_.disconnect(); daemon_.disconnect();
tmenu->show(); tmenu->show();
@@ -265,7 +265,7 @@ public:
EVENT_HANDLER2(void, tileEvent, PIScreenTile *, t, PIScreenTypes::TileEvent, e) { EVENT_HANDLER2(void, tileEvent, PIScreenTile *, t, PIScreenTypes::TileEvent, e) {
if (t == tmenu) { if (t == tmenu) {
if (e.type == TileList::RowPressed) { if (e.type == TileList::RowPressed) {
piForeach(PIScreenTile * t, mtiles) for (auto * t: mtiles)
t->hide(); t->hide();
switch (e.data.toInt()) { switch (e.data.toInt()) {
case 0: tinfo->show(); break; case 0: tinfo->show(); break;
@@ -360,7 +360,6 @@ void usage() {
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
sys_mon.startOnSelf();
// piDebug = false; // piDebug = false;
PICLI cli(argc, argv); PICLI cli(argc, argv);
cli.addArgument("help"); cli.addArgument("help");
@@ -375,6 +374,7 @@ int main(int argc, char * argv[]) {
usage(); usage();
return 0; return 0;
} }
sys_mon.startOnSelf();
PIString name = cli.argumentValue("name"); PIString name = cli.argumentValue("name");
PIString sip = cli.argumentValue("address"); PIString sip = cli.argumentValue("address");
PISingleApplication * sapp = 0; PISingleApplication * sapp = 0;

View File

@@ -130,7 +130,7 @@ void removeFiles(const PIDir & dir, PIStringList l) {
l.removeAll(".."); l.removeAll("..");
PIString ap = dir.absolutePath(); PIString ap = dir.absolutePath();
// piCout << "remove from" << ap; // piCout << "remove from" << ap;
piForeachC(PIString & s, l) { for (const auto & s: l) {
PIFile::FileInfo fi = PIFile::fileInfo(ap + PIDir::separator + s); PIFile::FileInfo fi = PIFile::fileInfo(ap + PIDir::separator + s);
if (fi.isDir()) { if (fi.isDir()) {
PIVector<PIFile::FileInfo> el = PIDir::allEntries(fi.path); PIVector<PIFile::FileInfo> el = PIDir::allEntries(fi.path);
@@ -149,7 +149,7 @@ bool cryptFiles(const PIDir & dir, PIStringList l, const PIByteArray & secret) {
if (secret.size() != PICrypt::sizeKey() || secret.isEmpty()) return false; if (secret.size() != PICrypt::sizeKey() || secret.isEmpty()) return false;
l.removeAll(".."); l.removeAll("..");
PIString ap = dir.absolutePath(); PIString ap = dir.absolutePath();
piForeachC(PIString & s, l) { for (const auto & s: l) {
PIFile::FileInfo fi = PIFile::fileInfo(ap + PIDir::separator + s); PIFile::FileInfo fi = PIFile::fileInfo(ap + PIDir::separator + s);
if (fi.isDir()) { if (fi.isDir()) {
PIVector<PIFile::FileInfo> el = PIDir::allEntries(fi.path); PIVector<PIFile::FileInfo> el = PIDir::allEntries(fi.path);