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)
set(PIP_MAJOR 4)
set(PIP_MINOR 4)
set(PIP_REVISION 0)
set(PIP_REVISION 1)
set(PIP_SUFFIX )
set(PIP_COMPANY SHS)
set(PIP_DOMAIN org.SHS)
@@ -97,7 +97,7 @@ set(PIP_UTILS_LIST)
set(PIP_TESTS_LIST)
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})
set(PIP_MSG_${_m} "no")
endforeach()
@@ -286,9 +286,14 @@ endif()
# Check if ICU used for PIString and PIChar
set(PIP_ICU "no")
if(ICU)
set(PIP_ICU "yes")
add_definitions(-DPIP_ICU)
list(APPEND LIBS_MAIN icuuc)
pip_find_lib(icuuc)
if (icuuc_FOUND)
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()
@@ -376,6 +381,17 @@ foreach(_m ${PIP_SRC_MODULES})
endforeach()
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 PIP_FREERTOS)
@@ -482,10 +498,8 @@ if (NOT CROSSTOOLS)
list(APPEND HDRS ${_lua_src_hdr})
# libmicrohttpd
find_library(microhttpd_LIBRARIES microhttpd HINTS "${MINGW_LIB}")
set(microhttpd_FOUND FALSE)
if (microhttpd_LIBRARIES)
set(microhttpd_FOUND TRUE)
pip_find_lib(microhttpd HINTS "${MINGW_LIB}")
if (microhttpd_FOUND)
set(_microhttpd_add_libs microhttpd)
if(WIN32)
if("${C_COMPILER}" STREQUAL "cl.exe")
@@ -512,6 +526,12 @@ if (NOT CROSSTOOLS)
pip_module(http_server "${_microhttpd_add_libs}" "PIP HTTP server" "" "" "")
endif()
# libcurl
pip_find_lib(curl HINTS "${MINGW_LIB}")
if (curl_FOUND)
pip_module(http_client curl "PIP HTTP client" "" "" "")
endif()
# Test program
if(PIP_UTILS)
@@ -519,9 +539,9 @@ if (NOT CROSSTOOLS)
#target_link_libraries(pip_plugin pip)
if (NOT DEFINED ANDROID_PLATFORM)
if(microhttpd_FOUND)
if(microhttpd_FOUND AND curl_FOUND)
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)
add_executable(pip_cloud_test "main_picloud_test.cpp")
target_link_libraries(pip_cloud_test pip_cloud)
@@ -651,7 +671,7 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
find_package(Doxygen)
if(DOXYGEN_FOUND)
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)
list(APPEND DOXY_DEFINES "PIP_${_mdef}_EXPORT")
endforeach()
@@ -707,6 +727,7 @@ macro(expand_to_length _out _str _len)
endmacro()
list(REMOVE_ITEM LIBS_STATUS ${PIP_MODULES})
list(REMOVE_DUPLICATES LIBS_STATUS)
message("----------PIP----------")
message(" Version: ${PIP_VERSION} ")
message(" Linkage: ${PIP_LIB_TYPE_MSG}")

View File

@@ -12,6 +12,7 @@ Create imported targets:
* PIP::ClientServer
* PIP::Cloud
* PIP::Lua
* PIP::HTTPClient
* PIP::HTTPServer
These targets include directories and depends on
@@ -24,10 +25,10 @@ include(SHSTKMacros)
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)
#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")
#get_target_property(_path pip BINARY_DIR)
#get_target_property(_path pip LIBRARY_OUTPUT_NAME)
@@ -97,6 +98,7 @@ set(__module_io_utils IOUtils )
set(__module_client_server ClientServer)
set(__module_cloud Cloud )
set(__module_lua Lua )
set(__module_http_client HTTPClient )
set(__module_http_server HTTPServer )
foreach (_l ${__libs})

View File

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

View File

@@ -78,14 +78,14 @@ void PIScreenTile::removeTile(PIScreenTile * t) {
PIVector<PIScreenTile *> PIScreenTile::children(bool only_visible) {
PIVector<PIScreenTile *> ret;
piForeach(PIScreenTile * t, tiles)
for (auto * t: tiles)
if (t->visible || !only_visible) ret << t << t->children(only_visible);
return ret;
}
PIScreenTile * PIScreenTile::childUnderMouse(int x, int y) {
piForeach(PIScreenTile * t, tiles) {
for (auto * t: tiles) {
if (!t->visible) continue;
if (x >= t->x_ && (x - t->x_) < t->width_ && y >= t->y_ && (y - t->y_) < t->height_) {
return t;
@@ -103,13 +103,13 @@ void PIScreenTile::raiseEvent(TileEvent e) {
void PIScreenTile::setScreen(PIScreenBase * s) {
screen = s;
piForeach(PIScreenTile * t, tiles)
for (auto * t: tiles)
t->setScreen(s);
}
void PIScreenTile::deleteChildren() {
piForeach(PIScreenTile * t, tiles) {
for (auto * t: tiles) {
t->parent = 0;
delete t;
}
@@ -136,7 +136,7 @@ void PIScreenTile::drawEventInternal(PIScreenDrawer * d) {
(Color)back_format.color_back,
back_format.flags);
drawEvent(d);
piForeach(PIScreenTile * t, tiles)
for (auto * t: tiles)
t->drawEventInternal(d);
}
@@ -150,7 +150,7 @@ void PIScreenTile::sizeHint(int & w, int & h) const {
w += sl;
else
h += sl;
piForeachC(PIScreenTile * t, tiles) {
for (const auto * t: tiles) {
if (!t->visible) continue;
int cw(0), ch(0);
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 {
w = h = 0;
piForeachC(Row & r, content)
for (const auto & r: content)
w = piMaxi(w, r.first.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 {
w = h = 0;
piForeachC(Row & r, content)
for (const auto & r: content)
w = piMaxi(w, r.first.size_s());
h = 3;
}
@@ -361,12 +361,12 @@ TileButtons::TileButtons(const PIString & n): PIScreenTile(n) {
void TileButtons::sizeHint(int & w, int & h) const {
w = h = 0;
if (direction == Horizontal) {
piForeachC(Button & b, content)
for (const auto & b: content)
w += b.first.size_s() + 4;
w += piMaxi(0, content.size_s() - 1) * 2;
h += 1;
} else {
piForeachC(Button & b, content)
for (const auto & b: content)
w = piMaxi(w, b.first.size_s() + 4);
h += content.size_s();
h += piMaxi(0, content.size_s() - 1);
@@ -539,7 +539,7 @@ void TilePICout::drawEvent(PIScreenDrawer * d) {
if (!out.isEmpty()) {
PIStringList l = out.split("\n");
bool scroll = (cur == content.size_s() - 1) || !has_focus;
piForeachC(PIString & s, l)
for (const auto & s: l)
content << TileList::Row(s.trimmed(), format);
if (content.size_s() > max_lines) content.remove(0, content.size_s() - max_lines);
if (scroll) {

View File

@@ -518,7 +518,7 @@ void PITerminal::applyEscSeq(PIString es) {
return;
}
PIStringList args = es.split(";");
piForeachC(PIString & a, args) {
for (const auto & a: args) {
int av = a.toInt();
switch (av) {
case 0: PRIVATE->cur_format = PIScreenTypes::CellFormat(); break;
@@ -862,7 +862,7 @@ bool PITerminal::initialize() {
ws.ws_col = dsize_x;
ws.ws_row = dsize_y;
PIStringList env = PIProcess::currentEnvironment();
piForeachC(PIString & e, env)
for (const auto & e: env)
if (e.startsWith("TERM=")) {
PRIVATE->term_type = termType(e.mid(5).trim().toLowerCase());
// 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 "piliterals_bytes.h"
#include "piliterals_string.h"
#include "piliterals_time.h"
@@ -29,13 +30,23 @@
// clang-format on
struct MicrohttpdServerConnection {
bool ready();
int send_reply(const MicrohttpdServer::Reply & r);
int send_error();
using namespace PIHTTP;
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;
PIByteArray body;
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() {
if (!server) return false;
if (done) return true;
done = true;
MicrohttpdServer::Reply rep;
if (method == MicrohttpdServer::Method::Get) {
MessageMutable rep;
if (method == Method::Get) {
if (path == "/favicon.ico"_a) {
// piCout << "send favicon" << server->favicon.size() << "bytes";
rep.setBody(server->favicon);
send_reply(rep);
sendReply(rep);
return true;
}
}
// piCout << "ready" << (int)method << path;
MicrohttpdServer::Request req;
req.method = method;
req.path = path;
req.body = body;
req.headers = headers;
req.args = args;
rep.setCode(MHD_HTTP_BAD_REQUEST);
// piCout << "ready" << (int)method << path << body.size();
MessageMutable req;
req.setMethod(method);
req.setPath(path);
req.setBody(body);
req.headers() = headers;
req.arguments() = args;
rep.setCode(Code::BadRequest);
if (server->callback) rep = server->callback(req);
rep.addFixedHeaders();
send_reply(rep);
MicrohttpdServer::addFixedHeaders(rep);
sendReply(rep);
// piCout << "ready ok" << (int)rep.code() << rep.body().size();
return true;
}
int MicrohttpdServerConnection::send_reply(const MicrohttpdServer::Reply & r) {
MHD_Response * response = MHD_create_response_from_buffer(r.body.size(), (void *)r.body.data(), MHD_RESPMEM_MUST_COPY);
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);
if (!response) {
// piCout << "null response" << r.body.size() << (void *)r.body.data();
return MHD_NO;
}
auto it = r.headers.makeIterator();
auto it = r.headers().makeIterator();
while (it.next())
MHD_add_response_header(response, it.key().dataAscii(), it.value().dataUTF8());
// 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);
return ret;
}
int MicrohttpdServerConnection::send_error() {
return MHD_queue_response(connection, MHD_HTTP_BAD_REQUEST, MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_MUST_COPY));
BasicAuthCred MicrohttpdServerConnection::getBasicAuthCred() {
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;
piCout << "log" << server;
if (!server) return;
char buffer[1024];
memset(buffer, 0, 1024);
std::vsnprintf(buffer, 1024, fmt, ap);
char buffer[1_KiB];
memset(buffer, 0, 1_KiB);
std::vsnprintf(buffer, 1_KiB, fmt, ap);
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,
MHD_Connection * connection,
const char * url,
const char * method,
const char * version,
const char * upload_data,
size_t * upload_data_size,
void ** con_cls) {
MicrohttpdServer * server = (MicrohttpdServer *)cls;
int answer_callback(void * cls,
MHD_Connection * connection,
const char * url,
const char * method,
const char * version,
const char * upload_data,
size_t * upload_data_size,
void ** con_cls) {
MicrohttpdServer * server = (MicrohttpdServer *)cls;
MicrohttpdServer::Method m = MicrohttpdServer::Method::Unknown;
Method m = Method::Unknown;
if (0 == strcmp(method, "GET"))
m = MicrohttpdServer::Method::Get;
m = Method::Get;
else if (0 == strcmp(method, "POST"))
m = MicrohttpdServer::Method::Post;
m = Method::Post;
else if (0 == strcmp(method, "HEAD"))
m = MicrohttpdServer::Method::Head;
m = Method::Head;
else if (0 == strcmp(method, "PUT"))
m = MicrohttpdServer::Method::Put;
m = Method::Put;
else if (0 == strcmp(method, "DELETE"))
m = MicrohttpdServer::Method::Delete;
m = Method::Delete;
else if (0 == strcmp(method, "CONNECT"))
m = MicrohttpdServer::Method::Connect;
m = Method::Connect;
else if (0 == strcmp(method, "OPTIONS"))
m = MicrohttpdServer::Method::Options;
m = Method::Options;
else if (0 == strcmp(method, "TRACE"))
m = MicrohttpdServer::Method::Trace;
m = Method::Trace;
else if (0 == strcmp(method, "PATCH"))
m = MicrohttpdServer::Method::Patch;
m = Method::Patch;
if (m == MicrohttpdServer::Method::Unknown) {
if (m == Method::Unknown) {
piCout << "[MicrohttpdServer]"
<< "Warning:"
<< "Unknown method!";
@@ -198,23 +242,27 @@ int answer_to_connection(void * cls,
conn->method = m;
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);
if (server->isBasicAuthEnabled() && !conn->authorized) {
if (!conn->checkBasicAuth()) return MHD_YES;
}
return MHD_YES;
}
if (m == MicrohttpdServer::Method::Unknown) {
return conn->send_error();
if (m == Method::Unknown) {
return conn->sendReply(MessageMutable::fromCode(Code::MethodNotAllowed));
}
if (*upload_data_size) {
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);
MHD_post_process(conn->postprocessor, upload_data, *upload_data_size);
*upload_data_size = 0;
} else {
// qDebug() << "answer ok";
if (!conn->ready()) return conn->send_error();
if (!conn->ready()) return conn->sendReply(MessageMutable::fromCode(Code::InternalServerError));
}
return MHD_YES;
}
@@ -229,6 +277,7 @@ MicrohttpdServer::MicrohttpdServer() {
PRIVATE->daemon = nullptr;
opts[Option::ConnectionLimit] = FD_SETSIZE - 4;
opts[Option::ConnectionTimeout] = 0_s;
realm = "Restricted"_a;
}
@@ -283,7 +332,7 @@ bool MicrohttpdServer::listen(PINetworkAddress addr) {
addr.port(),
nullptr,
nullptr,
(MHD_AccessHandlerCallback)answer_to_connection,
(MHD_AccessHandlerCallback)answer_callback,
this,
MHD_OPTION_ARRAY,
options.data(),
@@ -305,34 +354,14 @@ void MicrohttpdServer::stop() {
}
void MicrohttpdServer::Reply::addHeader(const PIString & header, const PIString & value) {
headers[header] = value;
}
void MicrohttpdServer::Reply::removeHeader(const PIString & header) {
headers.remove(header);
}
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");
void MicrohttpdServer::addFixedHeaders(MessageMutable & msg) {
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");
else if (msg.body()[0] == '[' || msg.body()[0] == '{')
msg.addHeader(Header::ContentType, "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() {
setRequestCallback([this](const MicrohttpdServer::Request & r) -> MicrohttpdServer::Reply {
MicrohttpdServer::Reply rep;
rep.setCode(404);
auto in_path = r.path.split("/");
setRequestCallback([this](const PIHTTP::MessageConst & r) -> PIHTTP::MessageMutable {
PIHTTP::MessageMutable reply;
reply.setCode(PIHTTP::Code::NotFound);
auto in_path = r.path().split("/");
in_path.removeAll("");
auto it = functions.makeReverseIterator();
bool found = false;
while (it.next()) {
if (it.value().function) {
if (it.value().method == r.method) {
if (it.value().method == r.method()) {
if (it.value().match(in_path)) {
rep = it.value().function(r);
reply = it.value().function(r);
found = true;
break;
}
}
}
}
if (!found && unhandled) rep = unhandled(r);
if (!found && unhandled) reply = unhandled(r);
auto hit = reply_headers.makeIterator();
while (hit.next())
rep.addHeader(hit.key(), hit.value());
return rep;
reply.addHeader(hit.key(), hit.value());
return reply;
});
}
@@ -36,8 +36,8 @@ PIHTTPServer::~PIHTTPServer() {
}
void PIHTTPServer::registerPath(const PIString & path, Method method, RequestFunction functor) {
auto & ep(functions[path + PIString::fromNumber((int)method)]);
void PIHTTPServer::registerPath(const PIString & path, PIHTTP::Method method, RequestFunction functor) {
auto & ep(functions[path + PIString::fromNumber(static_cast<int>(method))]);
ep.path = path.split("/");
ep.method = method;
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("/");
pl.removeAll("");
auto it = functions.makeIterator();

View File

@@ -181,14 +181,14 @@ void PISystemMonitor::run() {
__PIThreadCollection * pitc = __PIThreadCollection::instance();
pitc->lock();
PIVector<PIThread *> tv = pitc->threads();
piForeach(PIThread * t, tv)
for (auto * t: tv)
if (t->isPIObject()) tbid[t->tid()] = t->name();
pitc->unlock();
// piCout << tbid.keys().toType<uint>();
ProcessStats tstat;
tstat.ID = pID_;
#ifdef MICRO_PIP
piForeach(PIThread * t, tv)
for (auto * t: tv)
if (t->isPIObject()) gatherThread(t->tid());
#else
# ifndef WINDOWS
@@ -260,7 +260,7 @@ void PISystemMonitor::run() {
tstat.physical_memsize = tstat.resident_memsize - tstat.share_memsize;
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;
gatherThread(i.name().toInt());
}

View File

@@ -23,14 +23,14 @@
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();
return PIString();
}
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;
return -1;
}

View File

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

View File

@@ -19,8 +19,24 @@
#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) {
@@ -33,3 +49,15 @@ size_t _PIContainerConstantsBase::calcMinCountPoT(size_t szof) {
// printf("calcMinCount sizeof = %d, min_count = %d, pot = %d\n", szof, elc, 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 {
public:
static size_t calcMinCountPoT(size_t szof);
static size_t calcMaxCountForPoT(size_t szof);
static size_t calcStepAfterPoT(size_t szof);
};
template<typename T>
class _PIContainerConstants {
public:
// minimum elements for container
static size_t minCountPoT() {
static const size_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T));
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;
}
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>
inline void newT(T * dst, const T * src, size_t s) {
PIINTROSPECTION_CONTAINER_USED(T, s)
@@ -2682,35 +2669,38 @@ private:
if (pid_start > 0) checkMove();
return;
}
pid_size = new_size;
const size_t as = asize(pid_start + new_size);
if (as != pid_rsize) {
pid_size = new_size;
const size_t new_rsize = _PIContainerConstants<T>::calcNewSize(pid_rsize, pid_start + new_size);
if (new_rsize != 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
if (!p_d) {
if (!new_data) {
fprintf(stderr, "error with PIDeque<%s>::alloc\n", __PIP_TYPENAME__(T));
}
#endif
assert(p_d);
pid_data = p_d;
pid_rsize = as;
assert(new_data);
pid_data = new_data;
pid_rsize = new_rsize;
}
}
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;
if (as > pid_rsize) {
T * td = reinterpret_cast<T *>(malloc(as * sizeof(T)));
const size_t ns = pid_start + as - pid_rsize;
const size_t new_rsize =
ssize_t(pid_start) + start_offset < 0 ? _PIContainerConstants<T>::calcNewSize(pid_rsize, pid_rsize - start_offset) : pid_rsize;
if (new_rsize > 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))
if (pid_rsize > 0 && pid_data != 0) {
memcpy(reinterpret_cast<void *>(td + ns), reinterpret_cast<const void *>(pid_data + pid_start), pid_size * sizeof(T));
if (pid_rsize > 0 && pid_data) {
memcpy(reinterpret_cast<void *>(tmp_data + new_start),
reinterpret_cast<const void *>(pid_data + pid_start),
pid_size * sizeof(T));
dealloc();
}
pid_data = td;
pid_rsize = as;
pid_start = ns;
pid_data = tmp_data;
pid_rsize = new_rsize;
pid_start = new_start;
}
pid_start += start_offset;
pid_size = new_size;

View File

@@ -2459,18 +2459,6 @@ private:
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>
inline void newT(T * dst, const T * src, size_t s) {
PIINTROSPECTION_CONTAINER_USED(T, s)
@@ -2558,19 +2546,19 @@ private:
piv_size = new_size;
return;
}
piv_size = new_size;
const size_t as = asize(new_size);
if (as == piv_rsize) return;
piv_size = new_size;
const size_t new_rsize = _PIContainerConstants<T>::calcNewSize(piv_rsize, new_size);
if (new_rsize == piv_rsize) return;
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
if (!p_d) {
if (!new_data) {
fprintf(stderr, "error with PIVector<%s>::alloc\n", __PIP_TYPENAME__(T));
}
#endif
assert(p_d);
piv_data = p_d;
piv_rsize = as;
assert(new_data);
piv_data = new_data;
piv_rsize = new_rsize;
}
T * piv_data = nullptr;

View File

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

View File

@@ -366,7 +366,7 @@ PICout & PICout::operator<<(PIFlags<PICoutManipulators::PICoutFormat> v) {
void PICout::stdoutPIString(const PIString & str, PICoutStdStream s) {
#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()),
(char16_t *)&(const_cast<PIString &>(str).front()) + str.size());
#else

View File

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

View File

@@ -32,7 +32,6 @@
# ifdef ESP_PLATFORM
# include "esp_system.h"
# endif
# include <codecvt>
# ifdef WINDOWS
# include <winsock2.h>
extern FILETIME __pi_ftjan1970;
@@ -108,7 +107,7 @@ PIInit::PIInit() {
PIStringList ifpathes;
ifpathes << PIStringAscii("/bin/ifconfig") << PIStringAscii("/sbin/ifconfig") << PIStringAscii("/usr/bin/ifconfig")
<< PIStringAscii("/usr/sbin/ifconfig");
piForeachC(PIString & i, ifpathes) {
for (const auto & i: ifpathes) {
if (fileExists(i)) {
sinfo->ifconfigPath = i;
break;
@@ -149,9 +148,6 @@ PIInit::PIInit() {
}
currentLocale_t = newlocale(LC_ALL, setlocale(LC_ALL, "C"), 0);
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
setlocale(LC_ALL, "");
setlocale(LC_NUMERIC, "C");

View File

@@ -360,9 +360,9 @@ PIObject::Connection PIObject::piConnectU(PIObject * src,
void *addr_src(0), *addr_dest(0);
int args(0);
bool que = (performer != 0);
piForeachC(__MetaFunc & fs, m_src) {
for (const auto & fs: m_src) {
if (addr_src != 0) break;
piForeachC(__MetaFunc & fd, m_dest) {
for (const auto & fd: m_dest) {
if (addr_src != 0) break;
if (fs.canConnectTo(fd, args)) {
addr_src = fs.addr;
@@ -477,7 +477,7 @@ void PIObject::piDisconnectAll() {
PIMutexLocker _ml(mutex_connect);
PIVector<PIObject *> cv = connectors.toVector();
// piCout << "disconnect connectors =" << connectors.size();
piForeach(PIObject * o, cv) {
for (auto * o: cv) {
// piCout << "disconnect"<< src << o;
if (!o || (o == this)) continue;
if (!o->isPIObject()) continue;
@@ -496,7 +496,7 @@ void PIObject::piDisconnectAll() {
}
}
// piCout << "disconnect connections =" << connections.size();
piForeachC(PIObject::Connection & c, connections) {
for (const auto & c: connections) {
if (c.functor) continue;
if (!c.dest_o) continue;
if (!c.dest_o->isPIObject()) continue;
@@ -512,10 +512,10 @@ void PIObject::updateConnectors() {
// piCout << "*** updateConnectors" << this;
connectors.clear();
PIMutexLocker _ml(mutexObjects());
piForeach(PIObject * o, objects()) {
for (auto * o: objects()) {
if (o == this) continue;
PIVector<Connection> & oc(o->connections);
piForeach(Connection & c, oc)
for (auto & c: oc)
if (c.dest == this) connectors << o;
}
}
@@ -551,7 +551,7 @@ void PIObject::callQueuedEvents() {
PIVector<__QueuedEvent> qe = events_queue;
events_queue.clear();
mutex_queue.unlock();
piForeachC(__QueuedEvent & e, qe) {
for (const auto & e: qe) {
if (e.dest_o->thread_safe_) e.dest_o->mutex_.lock();
e.dest_o->emitter_ = e.src;
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
static PIObject * findByName(const PIString & name) {
PIMutexLocker _ml(mutexObjects());
piForeach(PIObject * i, PIObject::objects()) {
for (auto * i: PIObject::objects()) {
if (i->name() != name) continue;
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
#define MICROHTTPD_SERVER_P_H
#include "pibase.h"
#include "pihttptypes.h"
#include "piobject.h"
#include "pip_http_server_export.h"
@@ -15,18 +15,6 @@ public:
MicrohttpdServer();
virtual ~MicrohttpdServer();
enum class Method {
Unknown,
Get,
Head,
Post,
Put,
Delete,
Connect,
Options,
Trace,
Patch
};
enum class Option {
ConnectionLimit, // uint
ConnectionTimeout, // uint, sec
@@ -36,30 +24,6 @@ public:
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 setFavicon(const PIByteArray & im);
@@ -68,14 +32,25 @@ public:
bool isListen() const;
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:
static void addFixedHeaders(PIHTTP::MessageMutable & msg);
PRIVATE_DECLARATION(PIP_HTTP_SERVER_EXPORT)
PIByteArray favicon;
PIString realm;
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;
};

View File

@@ -10,13 +10,15 @@ public:
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 unregisterPath(const PIString & path, MicrohttpdServer::Method method);
void unregisterPath(const PIString & path, PIHTTP::Method method);
void unregisterPath(const PIString & path);
// void registerBasicAuth() {}
void addReplyHeader(const PIString & name, const PIString & value) { reply_headers[name] = value; }
void removeReplyHeader(const PIString & name) { reply_headers.remove(name); }
void clearReplyHeaders() { reply_headers.clear(); }
@@ -25,7 +27,7 @@ private:
struct Endpoint {
bool match(const PIStringList & in_path) const;
PIStringList path;
MicrohttpdServer::Method method = MicrohttpdServer::Method::Unknown;
PIHTTP::Method method = PIHTTP::Method::Unknown;
RequestFunction function;
};
PIMap<PIString, PIString> reply_headers;

View File

@@ -114,7 +114,7 @@ bool PIBinaryLog::openDevice() {
PIDir ld(logDir());
if (ld.isExists()) {
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())) {
setPath(i.path);
break;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -633,7 +633,7 @@ public:
//! \~russian
//! \brief Транспонирование матрицы.
//! \details Работает только с квадратными матрицами.
//! \return копия транспонированной матрицы.
//! \return Копия транспонированной матрицы.
PIMathMatrixT<Cols, Rows, Type> transposed() const {
PIMathMatrixT<Cols, Rows, Type> tm;
PIMM_FOR tm[c][r] = m[r][c];
@@ -647,8 +647,8 @@ public:
//! \~russian
//! \brief Операция поворота матрицы.
//! \details Работает только с матрицами 2x2.
//! \return повернутая матрица.
PIMathMatrixT<Rows, Cols, Type> rotate(Type angle) {
//! \return Эта повернутая матрица.
PIMathMatrixT<Rows, Cols, Type> & rotate(Type angle) {
static_assert(Rows == 2 && Cols == 2, "Works only with 2x2 matrix");
Type c = std::cos(angle);
Type s = std::sin(angle);
@@ -667,8 +667,8 @@ public:
//! \~russian
//! \brief Операция поворота матрицы.
//! \details Работает только с матрицами 2x2.
//! \return копия повернутой матрицы.
PIMathMatrixT<Rows, Cols, Type> & rotated(Type angle) {
//! \return Копия повернутой матрицы.
PIMathMatrixT<Rows, Cols, Type> rotated(Type angle) {
static_assert(Rows == 2 && Cols == 2, "Works only with 2x2 matrix");
PIMathMatrixT<Cols, Rows, Type> outm;
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::PIMathSolver() {
times.resize(4);
}
void PIMathSolver::solve(double u, double h) {
switch (method) {
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) {
F[0] = A * X + d * u;
X += F[0] * h;
@@ -258,3 +269,41 @@ void PIMathSolver::solvePA(double u, double h, uint deg) {
}
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
};
PIMathSolver() {
times.resize(4);
step = 0;
}
PIMathSolver();
void solve(double u, double h);
void fromTF(const TransferFunction & TF);
void setMethod(Method m) { method = m; }
void setTime(double time) {
times.pop_back();
times.push_front(time);
}
void setTime(double time);
void solveEyler1(double u, double h);
void solveEyler2(double u, double h);
@@ -68,40 +62,17 @@ public:
void solveABM3(double u, double h);
void solveABM4(double u, double h);
void solvePA(double u, double h, uint deg);
void solvePA2(double u, double h) {
if (step > 0)
solvePA(u, h, 2);
else
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);
}
void solvePA2(double u, double h);
void solvePA3(double u, double h);
void solvePA4(double u, double h);
void solvePA5(double u, double h);
PIMathVectord X;
static Method method_global;
static const char methods_desc[];
private:
void moveF() {
for (uint i = F.size() - 1; i > 0; --i)
F[i] = F[i - 1];
}
void moveF();
PIMathMatrixd A, M;
PIMathVectord d, a1, b1;
@@ -109,10 +80,10 @@ private:
PIMathVectord XX, Y, pY;
PIVector<PIMathVectord> F;
PIVector<double> times;
uint size, step;
Method method;
double sum, td, ct, lp, dh, t, x1, x0;
bool ok;
uint size = 0, step = 0;
Method method = Global;
double sum = 0., td = 0., ct = 0., lp = 0., dh = 0., t = 0., x1 = 0., x0 = 0.;
bool ok = false;
};
#endif // PIMATHSOLVER_H

View File

@@ -457,7 +457,7 @@ void PIPluginLoader::mergeStatic() {
PIStringList PIPluginLoader::pluginsDirectories(const PIString & name) {
static PIStringList dl({".", "./plugins", "../PlugIns"});
PIString ret;
piForeachC(PIString d, dl) {
for (const auto & d: dl) {
PIString dp = d + "/" + name;
if (PIDir::isExists(dp)) ret += dp;
}
@@ -470,8 +470,8 @@ PIString PIPluginLoader::findLibrary(const PIString & path) {
static const PIStringList suffixes({"", libExtension()});
PIFile::FileInfo fi(path);
PIString dir = fi.dir(), name = fi.name();
piForeachC(PIString & p, prefixes) {
piForeachC(PIString & s, suffixes) {
for (const auto & p: prefixes) {
for (const auto & s: suffixes) {
PIString fn = dir + p + name + s;
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;
l_df.pop_front();
piForeachC(PIString & s, l_df) {
for (const auto & s: l_df) {
PIStringList ml(s.replacedAll(" ", " ").split(" "));
if (ml.size_s() < 2) continue;
if (ml.front() == "none") continue;
@@ -234,17 +234,10 @@ PIString PISystemInfo::machineKey() {
PISystemInfo * si = instance();
PIByteArray salt;
PIString conf = confDir() + "/.pip_machine_salt";
if (PIFile::isExists(conf)) {
PIFile f(conf, PIIODevice::ReadOnly);
f.open();
salt = f.readAll();
}
if (PIFile::isExists(conf)) salt = PIFile::readAll(conf, false);
if (salt.size_s() != SALT_SIZE) {
salt = generateSalt();
PIFile f(conf, PIIODevice::ReadWrite);
f.open();
f.clear();
f.write(salt);
PIFile::writeAll(conf, salt);
}
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);
MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, s, (LPWSTR)d.data(old_sz), sz);
# 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);
d.enlarge(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;
return;
# 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());
data_ = (char *)malloc(u8str.size() + 1);
strcpy(data_, u8str.c_str());
@@ -1515,6 +1515,7 @@ PIString PIString::takeNumber() {
}
phase = 9;
break;
default: break;
}
if (phase == 6) {
if (c == 'f' || c == 's' || c == 'u' || c == 'l' || c == 'L')

View File

@@ -83,7 +83,7 @@ public:
private:
PIVector<PIThread *> threads;
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" - битовое поле для исключения свойств из процесса слияния
void PIPropertyStorage::updateProperties(const PIVector<PIPropertyStorage::Property> & properties_, int flag_ignore) {
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;
props = properties_;
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 {
piForeachC(Property & p, props)
for (const auto & p: props)
if (p.name == name) return p;
return Property();
}
PIVariant PIPropertyStorage::propertyValueByName(const PIString & name) const {
piForeachC(Property & p, props)
for (const auto & p: props)
if (p.name == name) return p.value;
return PIVariant();
}
@@ -182,7 +182,7 @@ bool PIPropertyStorage::setPropertyFlags(const PIString & name, int flags) {
PIPropertyStorage::Property & PIPropertyStorage::operator[](const PIString & name) {
piForeach(Property & p, props)
for (auto & p: props)
if (p.name == name) return p;
addProperty(name, "");
return props.back();
@@ -190,7 +190,7 @@ PIPropertyStorage::Property & PIPropertyStorage::operator[](const PIString & nam
const PIPropertyStorage::Property PIPropertyStorage::operator[](const PIString & name) const {
piForeachC(Property & p, props)
for (const auto & p: props)
if (p.name == name) return p;
return Property();
}

View File

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

View File

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

View File

@@ -1,3 +1,4 @@
#include "pihttpclient.h"
#include "pip.h"
using namespace PICoutManipulators;
@@ -10,9 +11,74 @@ const char * pageTitle = "<!DOCTYPE html>"
"</body>"
"</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[]) {
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();
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;
@@ -39,7 +105,7 @@ int main(int argc, char * argv[]) {
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;
ret.setBody("<!DOCTYPE html><html><body>API etry %1</body></html>"_a.arg(r.path).toUTF8());
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.setCode(404);
return ret;
});
});*/
/*server.setRequestCallback([](MicrohttpdServer::Request r) -> MicrohttpdServer::Reply {
MicrohttpdServer::Reply rep;
@@ -63,10 +129,12 @@ int main(int argc, char * argv[]) {
rep.setBody(PIByteArray::fromAscii("[{\"value1\": true, \"value2\": \"ыекштп\"}]"));
return rep;
});*/
piCout << "start" << server.isListen();
/*piCout << "start" << server.isListen();
WAIT_FOR_EXIT
server.stop();
server.stop();*/
return 0;
}

View File

@@ -152,7 +152,7 @@ PIMap<PIString, PIStringList> qt_filters;
PIString findLib(const PIString & 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 (win_target || l.toLowerCase().endsWith("dll")) {
PIFile::FileInfo info(l);
@@ -308,13 +308,13 @@ void procLdd(PIString file, bool ext_lib = false, int cur_depth = 0) {
}
if (!otool.isEmpty()) {
lines = filter(execute(otool + " -L \"" + file + "\""), "(");
piForeach(PIString & l, lines) {
for (auto & l: lines) {
l = l.left(l.find('('));
l.trim(); //.append('.').prepend('.');
}
}
}
piForeachC(PIString & sl, lines) {
for (const auto & sl: lines) {
PIString l = sl.trimmed();
if (!otool.isEmpty()) {
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();
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);
}
}
@@ -402,7 +402,7 @@ void procQt() {
PIDir(qt_plugins_dir).make(true);
PIDir(qt_qml_dir).make(true);
}
piForeach(PIString l, vsl) {
for (auto l: vsl) {
if (l.trim().contains("Qt version")) {
l.cutLeft(l.find("Qt version") + 10).trim();
PIString qv = l.takeWord();
@@ -411,7 +411,7 @@ void procQt() {
piCout << "Qt" << qv << "in" << qloc;
PIString qdir;
PIStringList suffixes({".", "..", "qt5", "../qt5", "qt6", "../qt6"});
piForeachC(PIString s, suffixes) {
for (const auto & s: suffixes) {
PIString qd = qloc + "/" + s + "/plugins/";
if (piDebug) PICout(AddSpaces) << "Qt plugins root try" << qd << "...";
if (PIDir::isExists(qd + "platforms")) {
@@ -422,14 +422,14 @@ void procQt() {
piCout << " no";
}
if (qdir.isEmpty()) break;
piForeachC(PIString & plugin, pdirs) {
for (const auto & plugin: pdirs) {
PIStringList filters = qt_filters[plugin];
piCout << "PLUG" << plugin << filters;
piForeachC(PIString & f, filters) {
for (const auto & f: filters) {
if (f.isEmpty()) continue;
copyWildcard(qdir + "plugins/" + plugin + "/" + f, qt_plugins_dir + plugin);
PIVector<PIFile::FileInfo> copied = PIDir(qt_plugins_dir + plugin).entries();
piForeachC(PIFile::FileInfo & fi, copied) {
for (const auto & fi: copied) {
if (fi.isFile()) {
procLdd(fi.path);
plugin_libs << fi.path;
@@ -441,7 +441,7 @@ void procQt() {
if (q.isEmpty()) continue;
copyWildcard(qdir + "qml/" + q + "/*", qt_qml_dir + q);
PIVector<PIFile::FileInfo> copied = PIDir(qt_qml_dir + q).allEntries();
piForeachC(PIFile::FileInfo & fi, copied) {
for (const auto & fi: copied) {
if (fi.isFile()) {
procLdd(fi.path);
plugin_libs << fi.path;
@@ -481,11 +481,11 @@ void patchNameTool() {
PIFile::FileInfo fi;
patch_list = input_files;
patch_list << plugin_libs;
piForeach(PIString l, clibs) {
for (const auto & l: clibs) {
fi.path = l;
patch_list << (out_dir + fi.name());
}
piForeach(PIString local_lib, patch_list) {
for (const auto & local_lib: patch_list) {
execute("chmod +w \"" + local_lib + "\"");
fi.path = local_lib;
cmd = nametool + " -id \"@executable_path/../Frameworks/" + fi.name() + "\"";
@@ -493,15 +493,15 @@ void patchNameTool() {
// piCout << " " << cmd;
execute(cmd);
}
piForeach(PIString f, flibs) {
for (const auto & f: flibs) {
PIString fl = findLib(frameworkName(f));
if (fl.isEmpty()) continue;
patch_list << (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 + "\""), "(");
piForeach(PIString & l, dlibs) {
for (auto & l: dlibs) {
l = l.left(l.find('('));
l.trim();
}
@@ -509,7 +509,7 @@ void patchNameTool() {
execute("chmod +w \"" + local_lib + "\"");
}
piCout << "patch" << local_lib;
piForeach(PIString sys_lib, dlibs) {
for (auto sys_lib: dlibs) {
sys_lib.cutRight(1).trim();
fi.path = sys_lib;
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 += " \"" + bin + "\"" + ign_err_suffix;
execute(cmd);
@@ -559,9 +559,9 @@ void patchRPathFile(const PIFile::FileInfo & file) {
void patchRPath() {
PIStringList dirs({out_dir, target_dir, qt_plugins_dir, qt_qml_dir});
dirs.removeDuplicates().removeStrings(PIString());
piForeachC(PIString & d, dirs) {
for (const auto & d: dirs) {
PIVector<PIFile::FileInfo> files = PIDir(d).allEntries();
piForeachC(PIFile::FileInfo & f, files) {
for (const auto & f: files) {
if (f.isDir()) continue;
patchRPathFile(f.path);
}
@@ -649,7 +649,7 @@ int main(int argc, char * argv[]) {
if (!qroot.endsWith("/")) qroot.append("/");
lib_dirs << (qroot + "bin") << (qroot + "lib") << (qroot + "Frameworks");
}
piForeach(PIString & s, lib_dirs) {
for (auto & s: lib_dirs) {
s.trim();
if (!s.endsWith("/")) s += "/";
}
@@ -669,7 +669,7 @@ int main(int argc, char * argv[]) {
styles = cli.argumentValue("Styles").split(",");
if (styles.isEmpty()) styles << "";
PIStringList qpd = cli.argumentValue("qt-plugins").toLowerCase().split(DELIM).removeAll("");
piForeachC(PIString & qp, qpd) {
for (const auto & qp: qpd) {
int _i = qp.find('=');
if (_i < 0) continue;
PIString pname = qp.left(_i).trim();
@@ -739,7 +739,7 @@ int main(int argc, char * argv[]) {
checkQtLib(f);
});
}
piForeach(PIString & s, add_libs) {
for (auto & s: add_libs) {
if (s.isEmpty()) continue;
PIString alib = findLib(s);
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
PIVector<PIString> qlibs = qt_libs.toVector();
piCout << "check for installed Qt" << qlibs;
piForeach(PIString l, qlibs) {
for (const auto & l: qlibs) {
if (procDpkg(l)) {
piCout << "system Qt found!";
need_qt_plugins = false;
@@ -783,7 +783,7 @@ int main(int argc, char * argv[]) {
out_dir.replaceAll("/", "\\");
#endif
PIVector<PIString> clibs = all_libs.toVector();
piForeach(PIString l, clibs) {
for (auto l: clibs) {
PIFile::FileInfo fi;
fi.path = l;
#ifdef WINDOWS
@@ -803,7 +803,7 @@ int main(int argc, char * argv[]) {
}
}
PIVector<PIString> fwdirs = frameworks.toVector();
piForeachC(PIString & f, fwdirs) {
for (const auto & f: fwdirs) {
PIString fd = findLib(f);
if (!fd.isEmpty()) {
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) {
_fl = fl;
if (!dir.isEmpty())
piForeach(PIString & s, _fl)
for (auto & s: _fl)
s.prepend(dir);
// piCout << "send" << _fl;
action = a;
@@ -122,7 +122,7 @@ void Daemon::Remote::updateDirEntries() {
// piCout << dir_my;
if (!dir_my.isExists()) dir_my = PIDir::current();
my_filelist = dir_my.entries();
piForeach(PIFile::FileInfo & f, my_filelist)
for (auto & f: my_filelist)
f.path = f.name();
}
@@ -325,7 +325,7 @@ Daemon::~Daemon() {
dtimer.stopAndWait();
requestCloseShell();
PIVector<Remote *> rl = remotes.values();
piForeach(Remote * r, rl) {
for (auto * r: rl) {
r->shellClose();
delete r;
}
@@ -554,7 +554,7 @@ void Daemon::timerEvent(int delim) {
screen->lock();
list_daemons->content.clear();
availableDaemons();
piForeachC(PIString & i, available_daemons)
for (const auto & i: available_daemons)
list_daemons->content << TileList::Row(i, CellFormat());
screen->unlock();
if (delim == 5 && mode == rmInformation) {
@@ -570,7 +570,7 @@ void Daemon::timerEvent(int delim) {
PIStringList Daemon::availableDaemons() {
available_daemons.clear();
lock();
piForeachC(PIPeer::PeerInfo & p, allPeers()) {
for (const auto & p: allPeers()) {
if (!p.name.startsWith(pisd_prefix)) continue;
available_daemons << p.name.mid(6);
}

View File

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

View File

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

View File

@@ -130,7 +130,7 @@ void removeFiles(const PIDir & dir, PIStringList l) {
l.removeAll("..");
PIString ap = dir.absolutePath();
// piCout << "remove from" << ap;
piForeachC(PIString & s, l) {
for (const auto & s: l) {
PIFile::FileInfo fi = PIFile::fileInfo(ap + PIDir::separator + s);
if (fi.isDir()) {
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;
l.removeAll("..");
PIString ap = dir.absolutePath();
piForeachC(PIString & s, l) {
for (const auto & s: l) {
PIFile::FileInfo fi = PIFile::fileInfo(ap + PIDir::separator + s);
if (fi.isDir()) {
PIVector<PIFile::FileInfo> el = PIDir::allEntries(fi.path);