95 Commits

Author SHA1 Message Date
Бычков Анлрей
e85b11a233 PIMap via pipair, fix tests 2022-05-26 18:07:44 +03:00
Бычков Анлрей
831adf3fc9 some new tests 2022-05-25 18:52:19 +03:00
Бычков Анлрей
a18f461ce3 pimap tests 2022-05-24 18:40:06 +03:00
12c032392c pip_cmg namespaces fix 2022-05-20 15:23:01 +03:00
ffa25c18f0 pip_cmg include fix 2022-05-15 17:56:52 +03:00
a502182eba NO_UNUSED 2022-05-09 11:56:09 +03:00
d219baee27 path fix 2022-05-08 22:29:35 +03:00
0ea1e2c856 support for git download of CMake project (standalone PIP build) 2022-05-08 22:22:48 +03:00
3107949e6f doc, small fixes 2022-05-08 19:23:52 +03:00
460519c075 PISingleApplication fix and optimize 2022-05-08 16:35:01 +03:00
9347ed2e55 doc 2022-05-06 23:42:20 +03:00
5770adfd34 PIMap fix 2022-05-06 16:27:40 +03:00
9714d8ea42 PIMap {{K, T}, {K, T}, ...} constructor
doc ru
2022-05-06 12:45:08 +03:00
0b3ee4bb6a doc ru 2022-05-05 22:31:59 +03:00
d1f7065c8a PICout::writePIString -> PICout::write 2022-05-05 10:35:15 +03:00
6995c25613 PIIODevice fullPathPrefix returns PIConstChars 2022-05-04 16:33:05 +03:00
28ce6e8f3f version 2.39.0
PIString works with PIConstChars
picodeinfo optimizations
PIIODevice::availableClasses
2022-05-03 18:44:00 +03:00
8d5730f715 PIPluginLoader +1 error 2022-04-30 16:07:30 +03:00
2bbdbc3ac9 PIIODevice registration dramatically optimization 2022-04-30 11:21:57 +03:00
19e4eee222 PIConstChars API 2022-04-30 09:05:14 +03:00
4139d88103 PIConstChars PIMap supports 2022-04-30 00:07:58 +03:00
6881fd13b7 PIConstChars 2022-04-29 23:53:07 +03:00
Andrey
8c8553a6af PIObject Property const char * 2022-04-29 18:17:03 +03:00
97dd19f0c7 !!!!!!!!!!!!!!!!!! 2022-04-27 16:34:12 +03:00
Andrey
784c949b1a Merge branch 'master' of https://git.shs.tools/SHS/pip 2022-04-27 15:49:37 +03:00
Andrey
7325e12e30 PIString doc 2022-04-27 15:49:30 +03:00
019ddbb80b TileInput fix 2022-04-27 13:35:27 +03:00
Andrey
6322b248a8 dtos fix 2022-04-27 13:27:58 +03:00
c1c47b4869 locale changes, piscreen 2022-04-27 12:41:38 +03:00
2f4e73ef13 console encoding patch 2022-04-26 22:49:31 +03:00
5ae1cfae87 Merge branch 'master' of https://git.shs.tools/SHS/pip 2022-04-26 21:02:07 +03:00
5d82caf889 Merge pull request 'PIString wo pideue parent' (#91) from pistring_unparent into master
Reviewed-on: https://git.shs.tools/SHS/pip/pulls/91
2022-04-26 21:01:36 +03:00
d3028a3ce8 pistring remove indexOf* 2022-04-26 21:01:20 +03:00
eef4573a68 Merge branch 'master' of https://git.shs.tools/SHS/pip 2022-04-26 20:04:10 +03:00
48f3b62540 deploy_tool/main.cpp 2022-04-26 20:04:05 +03:00
Andrey
f7d6302572 fix 2022-04-26 17:20:07 +03:00
Andrey
7ad520a1c3 PIString optimization 2022-04-26 17:19:05 +03:00
Andrey
4bc12989ca Merge branch 'master' of https://git.shs.tools/SHS/pip into pistring_unparent 2022-04-26 16:59:36 +03:00
Andrey
186c71d973 linux mb test 2022-04-26 16:41:04 +03:00
Andrey
06c8e6af10 linux mb test 2022-04-26 16:30:26 +03:00
Andrey
69b9589e84 linux mb test 2022-04-26 16:03:37 +03:00
Andrey
5c767c5e3e linux mb test 2022-04-26 16:01:14 +03:00
Andrey
9cd0389a0b PIString wo pideue parent 2022-04-26 14:41:12 +03:00
Andrey
a7ffc85404 piminsleep bug and PIIODevice splitFullPath optimization 2022-04-26 14:09:59 +03:00
Andrey
2e9c3a1dbf PIString benchmarks 2022-04-26 11:53:28 +03:00
9f581335d3 version 2.37 2022-04-26 00:33:17 +03:00
e70e1c0203 pichar fix 2022-04-26 00:17:53 +03:00
cb179de856 linux PIString fix 2022-04-26 00:11:27 +03:00
0aaa5ba890 linux PIString fix 2022-04-25 23:58:38 +03:00
0cf7fb9f25 linux PIString fix 2022-04-25 23:58:06 +03:00
a304997177 linux PIString fix 2022-04-25 23:56:57 +03:00
d6ba51e4bc linux PIString fix 2022-04-25 23:44:30 +03:00
892edb7d5b linux PIString fix 2022-04-25 23:42:46 +03:00
c3cf0f3586 linux PIString fix 2022-04-25 23:41:43 +03:00
2dec17e871 linux PIString fix 2022-04-25 23:41:21 +03:00
88ffd602d6 linux PIString fix 2022-04-25 23:40:17 +03:00
a57e51bdf8 linux PIString fix 2022-04-25 23:39:33 +03:00
44c52c40f1 linux PIString fix 2022-04-25 23:38:09 +03:00
6ecd04b0d8 linux PIString fix 2022-04-25 23:37:06 +03:00
964823b332 linux PIString fix 2022-04-25 23:35:54 +03:00
ca8839f097 linux PIString fix 2022-04-25 23:34:16 +03:00
546ad6a744 linux PIString fix 2022-04-25 23:32:21 +03:00
bd9ad16074 linux PIString fix 2022-04-25 23:31:46 +03:00
23907c7043 fix appendFromChars 2022-04-25 23:06:49 +03:00
a6cea11911 PIString ICU 2022-04-25 22:54:46 +03:00
cea7a7c121 piChar mbrtowc 2022-04-25 22:15:58 +03:00
095ecd254f piChar mbrtowc 2022-04-25 22:14:42 +03:00
2246b8b5fd linux test 2022-04-25 22:01:50 +03:00
914ff5355d Merge branch 'master' of https://git.shs.tools/SHS/pip 2022-04-25 21:55:14 +03:00
858269a46b linux test 2022-04-25 21:55:10 +03:00
5072d8c915 Merge branch 'master' of https://git.shs.tools/SHS/pip 2022-04-25 21:44:30 +03:00
5f8c04a78e containers minimum elements, windows memory leaks 2022-04-25 21:43:57 +03:00
41fb7cc40d linux fix 2022-04-25 21:32:35 +03:00
6a399c7d39 Merge branch 'master' of https://git.shs.tools/SHS/pip 2022-04-25 20:40:34 +03:00
90afc369f0 string brush 2022-04-25 15:29:27 +03:00
Andrey
765ef7368e PIString replace pibytearray by char * 2022-04-25 11:42:58 +03:00
03384d02a0 Merge branch 'master' of https://git.shs.tools/SHS/pip 2022-04-24 22:11:16 +03:00
cf48c9ebf7 string ascii 2022-04-24 19:15:51 +03:00
dd3d42944e Merge branch 'master' of https://git.shs.tools/SHS/pip 2022-04-23 13:59:23 +03:00
c2e44dc3ba doc fix 2022-04-23 13:59:06 +03:00
c1c324a5a8 doc 2022-04-23 12:44:09 +03:00
7f93ba55b4 doc 2022-04-23 12:37:55 +03:00
fcd871c0fc doc 2022-04-23 12:32:17 +03:00
0c54709414 doc ru 2022-04-23 11:27:07 +03:00
7a458c5cbe doc ru 2022-04-23 00:44:52 +03:00
8da0469dbf Merge branch 'master' of https://git.shs.tools/SHS/pip 2022-04-22 23:24:34 +03:00
38b75c85d7 doc fix 2022-04-22 23:24:28 +03:00
833d0333d7 doc fixes 2022-04-22 22:28:43 +03:00
e67a426ff2 doc fix 2022-04-22 21:48:35 +03:00
39e4d9a73c doc ru 2022-04-22 21:19:12 +03:00
Andrey
91216c4b17 PIPair doc 2022-04-22 19:20:50 +03:00
Andrey
416b142889 Merge branch 'master' of https://git.shs.tools/SHS/pip 2022-04-22 18:45:04 +03:00
Andrey
cb4df7dc42 fix PIVector and PIDeque typedefs 2022-04-22 18:44:58 +03:00
Andrey
99a4546775 ещё правки для PIVector и PIDeque iterator и убрал лишние строки 2022-04-22 17:54:08 +03:00
Andrey
8a9864a91c PIPair refactoring 2022-04-22 17:35:29 +03:00
127 changed files with 4907 additions and 2669 deletions

View File

@@ -2,15 +2,52 @@ cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
project(pip)
set(pip_MAJOR 2)
set(pip_MINOR 36)
set(pip_MINOR 39)
set(pip_REVISION 0)
set(pip_SUFFIX )
set(pip_COMPANY SHS)
set(pip_DOMAIN org.SHS)
set(GIT_CMAKE_DIR)
if (NOT DEFINED SHSTKPROJECT)
set(ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cmake-download/CMakeLists.txt"
"# This file was generated by PIP CMake, don`t edit it!
cmake_minimum_required(VERSION 2.8.2)
project(cmake-download NONE)
include(ExternalProject)
ExternalProject_Add(cmake
GIT_REPOSITORY https://git.shs.tools/SHS/cmake.git
GIT_TAG \"origin/master\"
GIT_CONFIG \"advice.detachedHead=false\"
SOURCE_DIR \"${CMAKE_CURRENT_BINARY_DIR}/cmake-src\"
BINARY_DIR \"${CMAKE_CURRENT_BINARY_DIR}/cmake-build\"
INSTALL_COMMAND \"\"
TEST_COMMAND \"\"
)
")
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/cmake-download)
if(result)
message(FATAL_ERROR "CMake step for cmake failed: ${result}")
endif()
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/cmake-download)
if(result)
message(FATAL_ERROR "Build step for cmake failed: ${result}")
endif()
install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_CURRENT_BINARY_DIR}/cmake-build\" --target install)")
set(GIT_CMAKE_DIR "${CMAKE_CURRENT_BINARY_DIR}/cmake-src")
endif()
if ("x${CMAKE_MODULE_PATH}" STREQUAL "x")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
endif()
if (NOT "x${GIT_CMAKE_DIR}" STREQUAL "x")
list(APPEND CMAKE_MODULE_PATH "${GIT_CMAKE_DIR}")
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
include(CheckFunctionExists)
include(PIPMacros)
@@ -550,6 +587,11 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
include(PIPDocumentation)
find_package(Doxygen)
if(DOXYGEN_FOUND)
set(DOXY_DEFINES "${PIP_EXPORTS}")
foreach (_m "console" "usb" "compress" "crypt" "cloud" "fftw" "opencl" "io_utils" "lua")
string(TOUPPER "${_m}" _mdef)
list(APPEND DOXY_DEFINES "PIP_${_mdef}_EXPORT")
endforeach()
set(DOXY_PROJECT_NUMBER "${pip_VERSION}")
set(DOXY_QHP_CUST_FILTER_ATTRS "\"PIP ${pip_VERSION}\"")
set(DOXY_QHP_SECT_FILTER_ATTRS "\"PIP ${pip_VERSION}\"")
@@ -574,9 +616,9 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
foreach(F ${PIP_MAIN_FOLDERS})
list(APPEND DOXY_INPUT "\"${F}\"")
endforeach(F)
string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/libs\"")
string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/libs\";\"${CMAKE_CURRENT_SOURCE_DIR}/doc/pages\"")
string(REPLACE ";" " " DOXY_INCLUDE_PATH "${PIP_INCLUDES}")
string(REPLACE ";" " " DOXY_DEFINES "${PIP_EXPORTS}")
string(REPLACE ";" " " DOXY_DEFINES "${DOXY_DEFINES}")
add_documentation(doc doc/Doxyfile.in)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html DESTINATION ../share/doc/pip COMPONENT doc EXCLUDE_FROM_ALL OPTIONAL)
endif()

View File

@@ -3,7 +3,7 @@ void _() {
//! [0]
class SomeIO: public PIIODevice {
PIIODEVICE(SomeIO)
PIIODEVICE(SomeIO, "myio")
public:
SomeIO(): PIIODevice() {}
protected:
@@ -19,9 +19,8 @@ protected:
// write to your device here
return written_bytes;
}
PIString fullPathPrefix() const {return "myio";}
void configureFromFullPath(const PIString & full_path) {
// parse full_path and configure device there
// parse full_path and configure device here
}
};
REGISTER_DEVICE(SomeIO)

44
doc/pages/main.md Normal file
View File

@@ -0,0 +1,44 @@
\~english \mainpage What is PIP
\~russian \mainpage Что такое PIP
\~english
PIP - Platform-Independent Primitives - is crossplatform library for C++ developers.
This library can help developers write non-GUI projects much more quickly, efficiently
and customizable than on pure C++.
Application written on PIP works the same on any system. One can read and write
any data types, serialize any types to device channels between any systems.
Many common data types, system primitives and devices implemented in this library.
PIP also tightly integrates with [CMake](https://cmake.org/) build system, providing handly search
main library, additional modules of PIP and several utilites. With
CMake with PIP one can easily generate and use code metainformation or
serialize custom types with it versions back-compatability.
Summary one can find at \ref summary page.
Basic using of PIP described at \ref using_basic page.
\~russian
PIP - Platform-Independent Primitives - кроссплатформенная библиотека для разработчиков на C++.
Эта библиотека поможет разработчику написать неграфическое приложение быстрее, эффективнее
и более гибко, чем на чистом C++.
Приложения, написанные на PIP, работают одинаково на многих системах. Можно читать и писать
любые типы данных, сериализовать любые типы в каналы устройств между любыми системами.
Многие типы данных, системные сущности и устройства реализованы в библиотеке.
PIP также тесно интегрируется с системой сборки [CMake](https://cmake.org/), предоставляя удобный поиск
главной библиотеки, модулей PIP и некоторых утилит. Используя CMake вместе с PIP
можно генерировать и использовать метаинформация о коде или сериализовать
свои типы данных с обратной совместимостью их версий.
Сводку можно найти на странице \ref summary.
Базовое использование PIP описано на странице \ref using_basic.

104
doc/pages/summary.md Normal file
View File

@@ -0,0 +1,104 @@
\~english \page summary Functionality summary
\~russian \page summary Сводка функциональности
\~english
* direct output to console (\a PICout)
* containers (\a PIVector, \a PIDeque, \a PIVector2D, \a PIStack, \a PIQueue, \a PIMap, \a PISet)
* byte array (\a PIByteArray)
* serialization (\a PIChunkStream)
* string (\a PIConstChars, \a PIString, \a PIStringList)
* base object (events and handlers) (\a PIObject)
* multithreading
* thread (\a PIThread)
* blocking (\a PIMutex, \a PISpinlock)
* executor (\a PIThreadPoolExecutor)
* blocking dequeue (\a PIBlockingDequeue)
* timer (\a PITimer)
* tiling console (with widgets) (\a PIScreen)
* simple text rows
* scroll bar
* list
* button
* buttons group
* check box
* progress bar
* PICout output
* text input
* I/O devices
* base class (\a PIIODevice)
* file (\a PIFile)
* serial port (\a PISerial)
* ethernet (\a PIEthernet)
* USB (\a PIUSB)
* packets extractor (\a PIPacketExtractor)
* binary log (\a PIBinaryLog)
* complex I/O point (\a PIConnection)
* peering net node (\a PIPeer)
* connection quality diagnotic (\a PIDiagnostics)
* Run-time libraries
* abstract (\a PILibrary)
* plugin (\a PIPluginLoader)
* Mathematics
* complex numbers
* vectors (\a PIMathVector, \a PIMathVectorT)
* matrices (\a PIMathMatrix, \a PIMathMatrixT)
* quaternion (\a PIQuaternion)
* 2D geometry (\a PIPoint, \a PILine, \a PIRect)
* statistic (\a PIStatistic)
* CRC checksum (\a PICRC)
* Fourier transform (\a PIFFTW, \a PIFFT)
* expression evaluator (\a PIEvaluator)
* command-line arguments parser (\a PICLI)
* process (\a PIProcess)
\~russian
* общение с консолью (\a PICout)
* контейнеры (\a PIVector, \a PIDeque, \a PIVector2D, \a PIStack, \a PIQueue, \a PIMap, \a PISet)
* байтовый массив (\a PIByteArray)
* сериализация (\a PIChunkStream)
* строка (\a PIConstChars, \a PIString, \a PIStringList)
* базовый объект (события и обработчики) (\a PIObject)
* многопоточность
* поток (\a PIThread)
* блокировки (\a PIMutex, \a PISpinlock)
* исполнитель (\a PIThreadPoolExecutor)
* блокирующая очередь (\a PIBlockingDequeue)
* таймер (\a PITimer)
* тайлинговая консоль (с виджетами) (\a PIScreen)
* простой вывод строк
* скроллбар
* лист
* кнопка
* группа кнопок
* галочка
* прогрессбар
* вывод PICout
* текстовый ввод
* устройства ввода/вывода
* базовый класс (\a PIIODevice)
* файл (\a PIFile)
* последовательный порт (\a PISerial)
* ethernet (\a PIEthernet)
* USB (\a PIUSB)
* packets extractor (\a PIPacketExtractor)
* бинарный логфайл (\a PIBinaryLog)
* сложное составное устройство (\a PIConnection)
* пиринговая сеть (\a PIPeer)
* диагностика качества связи (\a PIDiagnostics)
* поддержка библиотек времени выполнения
* базовая функциональность (\a PILibrary)
* плагин (\a PIPluginLoader)
* Математика
* комплексные числа
* вектора (\a PIMathVector, \a PIMathVectorT)
* матрицы (\a PIMathMatrix, \a PIMathMatrixT)
* кватернион (\a PIQuaternion)
* 2D геометрия (\a PIPoint, \a PILine, \a PIRect)
* статистика (\a PIStatistic)
* CRC контрольная сумма (\a PICRC)
* преобразования Фурье (\a PIFFTW, \a PIFFT)
* вычислитель выражений (\a PIEvaluator)
* парсер аргументов командной строки (\a PICLI)
* процесс (\a PIProcess)

128
doc/pages/using_basic.md Normal file
View File

@@ -0,0 +1,128 @@
\~english \page using_basic Getting started
\~russian \page using_basic Простые начала
\~english
Many novice programmers are solved many common task with system integrity: output to console,
keyboard buttons press detecting, working with serial ports, ethernet or files, and many other.
These tasks can solve this library, and code, based only on PIP will be compile and work
similar on many systems: Windows, any Linux, Red Hat, FreeBSD, MacOS X and QNX.
Typical application on PIP looks like this: \n
\~russian
Многие начинающие программисты решают общие задачи взаимодействия с операционной системой:
вывод в консоль, определение нажатия клавиш, работа с последовательными портами, сетью или файлами,
и многое другое. Эти задачи решены в библиотеке, и код, основанный на PIP будет компилироваться
и работать одинаково на многих системах: Windows, любой Linux, Red Hat, FreeBSD, MacOS X и QNX.
Типовое приложение на PIP выглядит примерно так: \n
\code{.cpp}
#include <pip.h>
// declare key press handler
void key_event(char key, void * );
PIConsole console(false, key_event); // don`t start now, key handler is "key_event"
// some vars
int i = 2, j = 3;
// implicit key press handler
void key_event(char key, void * ) {
switch (key) {
case '-':
i--;
break;
case '+':
i++;
break;
case '(':
j--;
break;
case ')':
j++;
break;
};
};
class MainClass: public PITimer {
PIOBJECT(MainClass)
public:
MainClass() {}
protected:
void tick(void * data, int delimiter) {
piCout << "timer tick";
// timer tick
}
};
MainClass main_class;
int main(int argc, char * argv[]) {
// enabling auto-detection of exit button press, by default 'Q' (shift+q)
console.enableExitCapture();
// if we want to parse command-line arguments
PICLI cli(argc, argv);
cli.addArgument("console"); // "-c" or "--console"
cli.addArgument("debug"); // "-d" or "--debug"
// enabling or disabling global debug flag
piDebug = cli.hasArgument("debug");
// configure console
console.addTab("first tab", '1');
console.addString("PIP console", 1, PIConsole::Bold);
console.addVariable("int var (i)", &i, 1);
console.addVariable("int green var (j)", &j, 1, PIConsole::Green);
console.addString("'-' - i--", 2);
console.addString("'+' - i++", 2);
console.addString("'(' - j--", 2);
console.addString("')' - j++", 2);
console.addTab("second tab", '2');
console.addString("col 1", 1);
console.addString("col 2", 2);
console.addString("col 3", 3);
console.setTab("first tab");
// start output to console if "console" argument exists
if (cli.hasArgument("console"))
console.start();
// start main class, e.g. 40 Hz
main_class.start(25.);
// wait for 'Q' press, independently if console is started or not
console.waitForFinish();
return 0;
};
\endcode
\~english
This code demonstrates simple interactive configurable program, which can be started with console
display or not, and with debug or not. \b MainClass is central class that also can be inherited from
\a PIThread and reimplement \a run() function.
\n Many PIP classes has events and event handlers, which can be connected one to another.
Details you can see at \a PIObject reference page (\ref PIObject_sec0).
\n To configure your program from file use \a PIConfig.
\n If you want more information see \ref using_advanced
\~russian
Этот код демонстрирует простую конфигурируемую программу, которая может быть запущена с
This code demonstrates simple interactive configurable program, which can be started with console
display or not, and with debug or not. \b MainClass is central class that also can be inherited from
\a PIThread and reimplement \a run() function.
\n Many PIP classes has events and event handlers, which can be connected one to another.
Details you can see at \a PIObject reference page (\ref PIObject_sec0).
\n To configure your program from file use \a PIConfig.

View File

@@ -219,14 +219,15 @@ void PIScreen::SystemConsole::print() {
} else {
if (!s.isEmpty()) {
moveTo(si, sj);
printf("%s", s.data());
PICout::stdoutPIString(s);
s.clear();
}
}
}
if (!s.isEmpty()) {
moveTo(si, sj);
printf("%s", s.data());
PICout::stdoutPIString(s);
//printf("%s", s.data());
s.clear();
}
}
@@ -295,32 +296,32 @@ void PIScreen::SystemConsole::newLine() {
}
#else // WINDOWS
PIString PIScreen::SystemConsole::formatString(const PIScreenTypes::Cell & c) {
PIString ts("\e[0");
PIString ts = PIStringAscii("\e[0");
switch (c.format.color_char) {
case Black: ts += ";30"; break;
case Red: ts += ";31"; break;
case Green: ts += ";32"; break;
case Blue: ts += ";34"; break;
case Cyan: ts += ";36"; break;
case Magenta: ts += ";35"; break;
case Yellow: ts += ";33"; break;
case White: ts += ";37"; break;
case Black: ts += PIStringAscii(";30"); break;
case Red: ts += PIStringAscii(";31"); break;
case Green: ts += PIStringAscii(";32"); break;
case Blue: ts += PIStringAscii(";34"); break;
case Cyan: ts += PIStringAscii(";36"); break;
case Magenta: ts += PIStringAscii(";35"); break;
case Yellow: ts += PIStringAscii(";33"); break;
case White: ts += PIStringAscii(";37"); break;
}
switch (c.format.color_back) {
case Black: ts += ";40"; break;
case Red: ts += ";41"; break;
case Green: ts += ";42"; break;
case Blue: ts += ";44"; break;
case Cyan: ts += ";46"; break;
case Magenta: ts += ";45"; break;
case Yellow: ts += ";43"; break;
case White: ts += ";47"; break;
case Black: ts += PIStringAscii(";40"); break;
case Red: ts += PIStringAscii(";41"); break;
case Green: ts += PIStringAscii(";42"); break;
case Blue: ts += PIStringAscii(";44"); break;
case Cyan: ts += PIStringAscii(";46"); break;
case Magenta: ts += PIStringAscii(";45"); break;
case Yellow: ts += PIStringAscii(";43"); break;
case White: ts += PIStringAscii(";47"); break;
}
if ((c.format.flags & Bold) == Bold) ts += ";1";
if ((c.format.flags & Underline) == Underline) ts += ";4";
if ((c.format.flags & Blink) == Blink) ts += ";5";
if ((c.format.flags & Inverse) == Inverse) ts += ";7";
return ts + "m";
if ((c.format.flags & Bold ) == Bold ) ts += PIStringAscii(";1");
if ((c.format.flags & Underline) == Underline) ts += PIStringAscii(";4");
if ((c.format.flags & Blink ) == Blink ) ts += PIStringAscii(";5");
if ((c.format.flags & Inverse ) == Inverse ) ts += PIStringAscii(";7");
return ts + 'm';
}
#endif // WINDOWS

View File

@@ -689,13 +689,7 @@ bool TileInput::keyEvent(PIKbdListener::KeyEvent key) {
case PIKbdListener::F12:
break;
default:
PIChar tc
#ifdef WINDOWS
= PIChar((ushort)key.key);
#else
= PIChar::fromUTF8((char *)&(key.key));
#endif
text.insert(cur, tc);
text.insert(cur, PIChar((ushort)key.key));
cur++;
oo++;
if (cur - offset >= lwid - osp) offset += oo;

View File

@@ -812,11 +812,12 @@ bool PITerminal::initialize() {
//piCoutObj << fr << PRIVATE->fd << pty;
if (fr == 0) {
char ** argv = new char*[2];
argv[0] = new char[PRIVATE->shell.lengthAscii() + 1];
memcpy(argv[0], PRIVATE->shell.dataAscii(), PRIVATE->shell.lengthAscii());
argv[0][PRIVATE->shell.lengthAscii()] = 0;
PIByteArray shell = PRIVATE->shell.toByteArray();
argv[0] = new char[shell.size() + 1];
memcpy(argv[0], shell.data(), shell.size());
argv[0][shell.size()] = 0;
argv[1] = 0;
execvp(PRIVATE->shell.dataAscii(), argv);
execvp(argv[0], argv);
delete[] argv[0];
delete[] argv;
exit(0);

View File

@@ -34,7 +34,7 @@
class PIP_CLOUD_EXPORT PICloudClient: public PIIODevice, public PICloudBase
{
PIIODEVICE(PICloudClient)
PIIODEVICE(PICloudClient, "")
public:
explicit PICloudClient(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
virtual ~PICloudClient();

View File

@@ -25,7 +25,7 @@
//! \~english \section cmake_module_Cloud Building with CMake
//! \~russian \section cmake_module_Cloud Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP::Cloud)
//! \endcode

View File

@@ -32,14 +32,14 @@
class PIP_CLOUD_EXPORT PICloudServer: public PIIODevice, public PICloudBase
{
PIIODEVICE(PICloudServer)
PIIODEVICE(PICloudServer, "")
public:
//! PICloudServer
explicit PICloudServer(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
virtual ~PICloudServer();
class Client : public PIIODevice {
PIIODEVICE(PICloudServer::Client)
PIIODEVICE(PICloudServer::Client, "")
friend class PICloudServer;
public:
Client(PICloudServer * srv = nullptr, uint id = 0);

View File

@@ -24,39 +24,39 @@
PIString PICodeInfo::EnumInfo::memberName(int value_) const {
piForeachC (PICodeInfo::EnumeratorInfo & e, members)
if (e.value == value_)
return e.name;
return e.name.toString();
return PIString();
}
int PICodeInfo::EnumInfo::memberValue(const PIString & name_) const {
piForeachC (PICodeInfo::EnumeratorInfo & e, members)
if (e.name == name_)
if (e.name.toString() == name_)
return e.value;
return -1;
}
PIVariantTypes::Enum PICodeInfo::EnumInfo::toPIVariantEnum() {
PIVariantTypes::Enum en(name);
PIVariantTypes::Enum en(name.toString());
for (auto m: members) en << m.toPIVariantEnumerator();
if (!en.isEmpty()) en.selectValue(members.front().value);
return en;
}
PIMap<PIString, PICodeInfo::ClassInfo * > * PICodeInfo::classesInfo;
PIMap<PIString, PICodeInfo::EnumInfo * > * PICodeInfo::enumsInfo;
PIMap<PIString, PICodeInfo::AccessValueFunction> * PICodeInfo::accessValueFunctions;
PIMap<PIString, PICodeInfo::AccessTypeFunction> * PICodeInfo::accessTypeFunctions;
PIMap<PIConstChars, PICodeInfo::ClassInfo * > * PICodeInfo::classesInfo;
PIMap<PIConstChars, PICodeInfo::EnumInfo * > * PICodeInfo::enumsInfo;
PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * PICodeInfo::accessValueFunctions;
PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * PICodeInfo::accessTypeFunctions;
bool __PICodeInfoInitializer__::_inited_ = false;
PIVariant PICodeInfo::getMemberAsVariant(const void * p, const char * class_name, const char * member_name) {
if (!p || !class_name || !member_name || !accessTypeFunctions || !accessValueFunctions) return PIVariant();
AccessTypeFunction atf = accessTypeFunctions->value(PIStringAscii(class_name), (AccessTypeFunction)0);
AccessValueFunction avf = accessValueFunctions->value(PIStringAscii(class_name), (AccessValueFunction)0);
AccessTypeFunction atf = accessTypeFunctions->value(class_name, (AccessTypeFunction)0);
AccessValueFunction avf = accessValueFunctions->value(class_name, (AccessValueFunction)0);
if (!atf || !avf) return PIVariant();
return PIVariant::fromValue(avf(p, member_name), PIStringAscii(atf(member_name)));
}

View File

@@ -27,6 +27,7 @@
#ifndef PICODEINFO_H
#define PICODEINFO_H
#include "piconstchars.h"
#include "pistringlist.h"
#include "pivarianttypes.h"
@@ -52,18 +53,18 @@ typedef PIByteArray(*AccessValueFunction)(const void *, const char *);
typedef const char*(*AccessTypeFunction)(const char *);
struct PIP_EXPORT TypeInfo {
TypeInfo(const PIString & n = PIString(), const PIString & t = PIString(), PICodeInfo::TypeFlags f = 0, int b = -1) {name = n; type = t; flags = f; bits = b;}
TypeInfo(const PIConstChars & n = PIConstChars(), const PIConstChars & t = PIConstChars(), PICodeInfo::TypeFlags f = 0, int b = -1) {name = n; type = t; flags = f; bits = b;}
bool isBitfield() const {return bits > 0;}
MetaMap meta;
PIString name;
PIString type;
PIConstChars name;
PIConstChars type;
PICodeInfo::TypeFlags flags;
int bits;
};
struct PIP_EXPORT FunctionInfo {
MetaMap meta;
PIString name;
PIConstChars name;
TypeInfo return_type;
PIVector<PICodeInfo::TypeInfo> arguments;
};
@@ -72,19 +73,19 @@ struct PIP_EXPORT ClassInfo {
ClassInfo() {has_name = true;}
MetaMap meta;
bool has_name;
PIString type;
PIString name;
PIStringList parents;
PIConstChars type;
PIConstChars name;
PIVector<PIConstChars> parents;
PIVector<PICodeInfo::TypeInfo> variables;
PIVector<PICodeInfo::FunctionInfo> functions;
PIVector<PICodeInfo::ClassInfo * > children_info;
};
struct PIP_EXPORT EnumeratorInfo {
EnumeratorInfo(const PIString & n = PIString(), int v = 0) {name = n; value = v;}
PIVariantTypes::Enumerator toPIVariantEnumerator() {return PIVariantTypes::Enumerator(value, name);}
EnumeratorInfo(const PIConstChars & n = PIConstChars(), int v = 0) {name = n; value = v;}
PIVariantTypes::Enumerator toPIVariantEnumerator() {return PIVariantTypes::Enumerator(value, name.toString());}
MetaMap meta;
PIString name;
PIConstChars name;
int value;
};
@@ -93,7 +94,7 @@ struct PIP_EXPORT EnumInfo {
int memberValue(const PIString & name) const;
PIVariantTypes::Enum toPIVariantEnum();
MetaMap meta;
PIString name;
PIConstChars name;
PIVector<PICodeInfo::EnumeratorInfo> members;
};
@@ -119,17 +120,17 @@ inline PICout operator <<(PICout s, const PICodeInfo::ClassInfo & v) {
if (!v.parents.isEmpty()) {
s << ": ";
bool first = true;
piForeachC (PIString & i, v.parents) {
for (const auto & i: v.parents) {
if (first) first = false;
else s << ", ";
s << i;
}
}
s << " Meta" << v.meta << " {\n";
piForeachC (FunctionInfo & i, v.functions) {
for (const auto & i: v.functions) {
s << PICoutManipulators::Tab << i.return_type << " " << i.name << "(";
bool fa = true;
piForeachC (TypeInfo & a, i.arguments) {
for (const auto & a: i.arguments) {
if (fa) fa = false;
else s << ", ";
s << a;
@@ -138,7 +139,7 @@ inline PICout operator <<(PICout s, const PICodeInfo::ClassInfo & v) {
}
if (!v.functions.isEmpty() && !v.variables.isEmpty())
s << "\n";
piForeachC (TypeInfo & i, v.variables) {
for (const auto & i: v.variables) {
s << PICoutManipulators::Tab << i << " Meta" << i.meta << ";\n";
}
s << "}\n";
@@ -149,7 +150,7 @@ inline PICout operator <<(PICout s, const PICodeInfo::ClassInfo & v) {
inline PICout operator <<(PICout s, const PICodeInfo::EnumInfo & v) {
s.setControl(0, true);
s << "enum " << v.name << " Meta" << v.meta << " {\n";
piForeachC (EnumeratorInfo & i, v.members) {
for (const auto & i: v.members) {
bool f = true;
if (f) f = false;
else s << ", ";
@@ -160,21 +161,21 @@ inline PICout operator <<(PICout s, const PICodeInfo::EnumInfo & v) {
return s;
}
extern PIP_EXPORT PIMap<PIString, PICodeInfo::ClassInfo * > * classesInfo;
extern PIP_EXPORT PIMap<PIString, PICodeInfo::EnumInfo * > * enumsInfo;
extern PIP_EXPORT PIMap<PIString, PICodeInfo::AccessValueFunction> * accessValueFunctions;
extern PIP_EXPORT PIMap<PIString, PICodeInfo::AccessTypeFunction> * accessTypeFunctions;
extern PIP_EXPORT PIMap<PIConstChars, PICodeInfo::ClassInfo * > * classesInfo;
extern PIP_EXPORT PIMap<PIConstChars, PICodeInfo::EnumInfo * > * enumsInfo;
extern PIP_EXPORT PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * accessValueFunctions;
extern PIP_EXPORT PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * accessTypeFunctions;
inline PIByteArray getMemberValue(const void * p, const char * class_name, const char * member_name) {
if (!p || !class_name || !member_name || !accessValueFunctions) return PIByteArray();
AccessValueFunction af = accessValueFunctions->value(PIStringAscii(class_name), (AccessValueFunction)0);
AccessValueFunction af = accessValueFunctions->value(class_name, (AccessValueFunction)0);
if (!af) return PIByteArray();
return af(p, member_name);
}
inline const char * getMemberType(const char * class_name, const char * member_name) {
if (!class_name || !member_name || !accessTypeFunctions) return "";
AccessTypeFunction af = accessTypeFunctions->value(PIStringAscii(class_name), (AccessTypeFunction)0);
AccessTypeFunction af = accessTypeFunctions->value(class_name, (AccessTypeFunction)0);
if (!af) return "";
return af(member_name);
}
@@ -195,10 +196,10 @@ public:
__PICodeInfoInitializer__() {
if (_inited_) return;
_inited_ = true;
PICodeInfo::classesInfo = new PIMap<PIString, PICodeInfo::ClassInfo * >;
PICodeInfo::enumsInfo = new PIMap<PIString, PICodeInfo::EnumInfo * >;
PICodeInfo::accessValueFunctions = new PIMap<PIString, PICodeInfo::AccessValueFunction>;
PICodeInfo::accessTypeFunctions = new PIMap<PIString, PICodeInfo::AccessTypeFunction>;
PICodeInfo::classesInfo = new PIMap<PIConstChars, PICodeInfo::ClassInfo * >;
PICodeInfo::enumsInfo = new PIMap<PIConstChars, PICodeInfo::EnumInfo * >;
PICodeInfo::accessValueFunctions = new PIMap<PIConstChars, PICodeInfo::AccessValueFunction>;
PICodeInfo::accessTypeFunctions = new PIMap<PIConstChars, PICodeInfo::AccessTypeFunction>;
}
static bool _inited_;
};

View File

@@ -25,7 +25,7 @@
//! \~english \section cmake_module_Code Building with CMake
//! \~russian \section cmake_module_Code Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP)
//! \endcode

View File

@@ -321,7 +321,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
PIString prev_namespace = cur_namespace, ccmn;
cur_namespace += pfc.takeCWord() + s_ns;
ccmn = pfc.takeRange('{', '}');
parseClass(0, ccmn);
parseClass(0, ccmn, true);
cur_namespace = prev_namespace;
continue;
}
@@ -340,7 +340,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
if (dind < 0 || find < dind) {pfc.cutLeft(6); continue;}
ccmn = pfc.left(dind) + s_bo + pfc.mid(dind).takeRange('{', '}') + s_bc;
pfc.remove(0, ccmn.size());
parseClass(0, ccmn);
parseClass(0, ccmn, false);
continue;
}
if (pfc.left(4) == s_enum) {
@@ -425,7 +425,7 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc)
}
PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) {
static const PIString s_ns = PIStringAscii("::");
static const PIString s_public = PIStringAscii("public");
static const PIString s_protected = PIStringAscii("protected");
@@ -436,22 +436,31 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
static const PIString s_enum = PIStringAscii("enum");
static const PIString s_friend = PIStringAscii("friend");
static const PIString s_typedef = PIStringAscii("typedef");
static const PIString s_namespace = PIStringAscii("namespace");
static const PIString s_template = PIStringAscii("template");
Visibility prev_vis = cur_def_vis;
int dind = fc.find('{'), find = fc.find(';'), end = 0;
if (dind < 0 && find < 0) return PIString();
if (dind < 0 || find < dind) return fc.left(find);
//piCout << "parse class <****\n" << fc.left(20) << "\n****>";
Entity * ce = parseClassDeclaration(fc.takeLeft(dind));
if (dind < 0 && find < 0) return;
if (dind < 0 || find < dind) {
fc.left(find);
return;
}
//piCout << "parse class <****\n" << fc << "\n****>";
Entity * ce = parent;
if (!is_namespace) {
ce = parseClassDeclaration(fc.takeLeft(dind));
fc.trim().cutLeft(1).cutRight(1).trim();
}
//piCout << "found class <****\n" << fc << "\n****>";
if (!ce) return PIString();
///if (!ce) return PIString();
if (ce) {
if (parent) parent->children << ce;
ce->parent_scope = parent;
}
int ps = -1;
bool def = false;
PIString prev_namespace = cur_namespace, stmp;
cur_namespace += ce->name + s_ns;
if (ce) cur_namespace += ce->name + s_ns;
//piCout << "parse class" << ce->name << "namespace" << cur_namespace;
//piCout << "\nparse class" << ce->name << "namespace" << cur_namespace;
while (!fc.isEmpty()) {
@@ -460,6 +469,14 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
if (cw == s_public ) {cur_def_vis = Public; fc.cutLeft(1); continue;}
if (cw == s_protected) {cur_def_vis = Protected; fc.cutLeft(1); continue;}
if (cw == s_private ) {cur_def_vis = Private; fc.cutLeft(1); continue;}
if (cw == s_namespace) {
PIString prev_namespace = cur_namespace, ccmn;
cur_namespace += fc.takeCWord() + s_ns;
ccmn = fc.takeRange('{', '}');
parseClass(ce, ccmn, true);
cur_namespace = prev_namespace;
continue;
}
if (cw == s_class || cw == s_struct || cw == s_union) {
if (isDeclaration(fc, 0, &end)) {
fc.cutLeft(end);
@@ -470,7 +487,7 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
stmp = fc.takeRange('{', '}');
fc.takeSymbol();
stmp = cw + ' ' + tmp + '{' + stmp + '}';
parseClass(ce, stmp);
parseClass(ce, stmp, false);
continue;
}
if (cw == s_enum) {
@@ -483,11 +500,13 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
}
if (cw == s_friend) {fc.cutLeft(fc.find(';') + 1); continue;}
if (cw == s_typedef) {
if (ce) {
ce->typedefs << parseTypedef(fc.takeLeft(fc.find(';')));
typedefs << ce->typedefs.back();
typedefs.back().first.insert(0, cur_namespace);
if (ce->typedefs.back().first.isEmpty())
ce->typedefs.pop_back();
}
fc.takeSymbol();
continue;
}
@@ -501,7 +520,7 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
}
def = !isDeclaration(fc, 0, &end);
tmp = (cw + fc.takeLeft(end)).trim();
if (!tmp.isEmpty())
if (!tmp.isEmpty() && ce)
parseMember(ce, tmp);
if (def) fc.takeRange('{', '}');
else fc.takeSymbol();
@@ -510,7 +529,6 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
}
cur_def_vis = prev_vis;
cur_namespace = prev_namespace;
return ce->name;
}

View File

@@ -151,7 +151,7 @@ private:
bool parseFileContent(PIString & fc, bool main);
bool parseDirective(PIString d);
Entity * parseClassDeclaration(const PIString & fc);
PIString parseClass(Entity * parent, PIString & fc);
void parseClass(Entity * parent, PIString & fc, bool is_namespace);
MetaMap parseMeta(PIString & fc);
bool parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta);
Typedef parseTypedef(PIString fc);

View File

@@ -32,7 +32,7 @@
//! \~english \section cmake_module_Compress Building with CMake
//! \~russian \section cmake_module_Compress Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP::Compress)
//! \endcode

View File

@@ -25,7 +25,7 @@
//! \~english \section cmake_module_Console Building with CMake
//! \~russian \section cmake_module_Console Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP::Console)
//! \endcode

View File

@@ -323,12 +323,18 @@ void PIKbdListener::readKeyboard() {
for (int i = 0; i < PRIVATE->ret; ++i)
PICout(0) << PICoutManipulators::Hex << int(((uchar * )&rc)[i]) << ' ';
PICout(0) << "\n";
std::cout << PRIVATE->ret << " chars ";
for (int i = 0; i < PRIVATE->ret; ++i)
cout << "'" << (char)(rc[i]) << "' ";
cout << endl;*/
std::cout << "'" << (char)(rc[i]) << "' " << (int)(uchar)(rc[i]);
std::cout << std::endl;*/
if (rc[0] == 0) {piMSleep(10); return;}
if (PRIVATE->ret < 0 || PRIVATE->ret > 7) {piMSleep(10); return;}
if (PRIVATE->ret == 1) ke.key = PIChar::fromConsole(rc[0]).unicode16Code();
if (PRIVATE->ret == 1) {
if (rc[0] == 8)
ke.key = Backspace;
else
ke.key = PIChar::fromConsole(rc[0]).unicode16Code();
}
int mod(0);
// 2 - shift 1
// 3 - alt 2

View File

@@ -0,0 +1,34 @@
/*
PIP - Platform Independent Primitives
Base macros for generic containers
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "picontainers.h"
const ssize_t minAlloc = 64;
ssize_t _PIContainerConstantsBase::calcMinCountPoT(ssize_t szof) {
ssize_t ret = 0, elc = 1;
while (elc * szof < minAlloc) {
elc *= 2;
++ret;
}
//printf("calcMinCount sizeof = %d, min_count = %d, pot = %d\n", szof, elc, ret);
return ret;
}

View File

@@ -63,6 +63,18 @@ private:
};
class PIP_EXPORT _PIContainerConstantsBase {
public:
static ssize_t calcMinCountPoT(ssize_t szof);
};
template<typename T>
class _PIContainerConstants {
public:
static ssize_t minCountPoT() {static ssize_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T)); return ret;}
};
//! \brief
//! \~english Template reverse wrapper over any container
//! \~russian Шаблонная функция обертки любого контейнера для обратного доступа через итераторы
@@ -165,8 +177,8 @@ template <typename C> _PIReverseWrapper<C> PIReverseWrap(const C & c) {return _P
//! \~russian Порядок обхода для функции изменения размерности reshape().
//! \~ \sa \a PIVector::reshape(), \a PIDeque::reshape()
enum ReshapeOrder {
ReshapeByRow,
ReshapeByColumn
ReshapeByRow /*! \~english Traversing elements by line, just as they stay in memory \~russian Обход элементов построчно, так же как они находятся в памяти */,
ReshapeByColumn /*! \~english Traversing elements by column \~russian Обход элементов по столбцам */,
};
#endif // PICONTAINERS_H

View File

@@ -58,7 +58,7 @@
//! This number is called the item's index.
//! So the first item has index 0, the last has index `size() - 1`.
//! A set of various convenient functions is also available for the array,
//! for example: \a indexOf, \a contains(), \a entries(), \a isEmpty(), \a isNotEmpty(),
//! for example: \a indexOf(), \a contains(), \a entries(), \a isEmpty(), \a isNotEmpty(),
//! \a every(), \a any(), \a forEach(), \a indexWhere(), \a getRange(), \a sort(),
//! \a map(), \a reduce(), \a filter(), \a flatten(), \a reshape() and others.
//!
@@ -91,7 +91,7 @@
//! первый элемент массива имеет индекс, равный `0`,
//! а индекс последнего элемента равен `size() - 1`.
//! Также для массива доступен набор различных удобных функций,
//! например: \a indexOf, \a contains(), \a entries(), \a isEmpty(), \a isNotEmpty(),
//! например: \a indexOf(), \a contains(), \a entries(), \a isEmpty(), \a isNotEmpty(),
//! \a every(), \a any(), \a forEach(), \a indexWhere(), \a getRange(), \a sort(),
//! \a map(), \a reduce(), \a filter(), \a flatten(), \a reshape() и другие.
//!
@@ -118,15 +118,19 @@ template <typename T>
class PIDeque {
public:
typedef bool (*CompareFunc)(const T & , const T & );
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
//! \~\brief
//! \~english Constructs an empty array.
//! \~russian Создает пустой массив.
inline PIDeque(): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
}
//! \~\brief
//! \~english Copy constructor.
//! \~russian Копирующий конструктор.
inline PIDeque(const PIDeque<T> & other): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
@@ -135,7 +139,6 @@ public:
newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size);
}
//! \~\brief
//! \~english Contructs array from
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
//! \~russian Создает массив из
@@ -151,7 +154,6 @@ public:
newT(pid_data, init_list.begin(), init_list.size());
}
//! \~\brief
//! \~english Contructs array from raw `data`.
//! This constructor reserve `size` and copy from `data` pointer.
//! \~russian Создает массив из указателя на данные `data` и размер `size`.
@@ -162,7 +164,6 @@ public:
newT(pid_data + pid_start, data, pid_size);
}
//! \~\brief
//! \~english Contructs array with size `size` filled elements `e`.
//! \~russian Создает массив из `size` элементов заполненных `e`.
inline PIDeque(size_t pid_size, const T & e = T()): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
@@ -170,7 +171,6 @@ public:
resize(pid_size, e);
}
//! \~\brief
//! \~english Contructs array with size `size` and elements created by function `f(size_t i)`.
//! \~russian Создает массив из `size` элементов созданных функцией `f(size_t i)`.
//! \~\details
@@ -189,7 +189,6 @@ public:
resize(piv_size, f);
}
//! \~\brief
//! \~english Move constructor.
//! \~russian Перемещающий конструктор.
inline PIDeque(PIDeque<T> && other): pid_data(other.pid_data), pid_size(other.pid_size), pid_rsize(other.pid_rsize), pid_start(other.pid_start) {
@@ -205,7 +204,6 @@ public:
_reset();
}
//! \~\brief
//! \~english Assign operator.
//! \~russian Оператор присваивания.
inline PIDeque<T> & operator =(const PIDeque<T> & other) {
@@ -216,7 +214,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Assign move operator.
//! \~russian Оператор перемещающего присваивания.
inline PIDeque<T> & operator =(PIDeque<T> && other) {
@@ -248,8 +245,8 @@ public:
++pos;
return *this;
}
inline iterator & operator ++(int) {
const auto tmp = *this;
inline iterator operator ++(int) {
auto tmp = *this;
++*this;
return tmp;
}
@@ -257,8 +254,8 @@ public:
--pos;
return *this;
}
inline iterator & operator --(int) {
const auto tmp = *this;
inline iterator operator --(int) {
auto tmp = *this;
--*this;
return tmp;
}
@@ -335,8 +332,8 @@ public:
++pos;
return *this;
}
inline const_iterator & operator ++(int) {
const auto tmp = *this;
inline const_iterator operator ++(int) {
auto tmp = *this;
++*this;
return tmp;
}
@@ -344,8 +341,8 @@ public:
--pos;
return *this;
}
inline const_iterator & operator --(int) {
const auto tmp = *this;
inline const_iterator operator --(int) {
auto tmp = *this;
--*this;
return tmp;
}
@@ -424,8 +421,8 @@ public:
--pos;
return *this;
}
inline reverse_iterator & operator ++(int) {
const auto tmp = *this;
inline reverse_iterator operator ++(int) {
auto tmp = *this;
--*this;
return tmp;
}
@@ -433,8 +430,8 @@ public:
++pos;
return *this;
}
inline reverse_iterator & operator --(int) {
const auto tmp = *this;
inline reverse_iterator operator --(int) {
auto tmp = *this;
++*this;
return tmp;
}
@@ -510,8 +507,8 @@ public:
--pos;
return *this;
}
inline const_reverse_iterator & operator ++(int) {
const auto tmp = *this;
inline const_reverse_iterator operator ++(int) {
auto tmp = *this;
--*this;
return tmp;
}
@@ -519,8 +516,8 @@ public:
++pos;
return *this;
}
inline const_reverse_iterator & operator --(int) {
const auto tmp = *this;
inline const_reverse_iterator operator --(int) {
auto tmp = *this;
++*this;
return tmp;
}
@@ -576,7 +573,6 @@ public:
};
//! \~\brief
//! \~english Iterator to the first element.
//! \~russian Итератор на первый элемент.
//! \~\details ![begin, end](doc/images/pivector_begin.png)
@@ -587,7 +583,6 @@ public:
//! \~\sa \a end(), \a rbegin(), \a rend()
inline iterator begin() {return iterator(this, 0);}
//! \~\brief
//! \~english Iterator to the element following the last element.
//! \~russian Итератор на элемент, следующий за последним элементом.
//! \~\details ![begin, end](doc/images/pivector_begin.png)
@@ -603,7 +598,6 @@ public:
inline const_iterator begin() const {return const_iterator(this, 0); }
inline const_iterator end() const {return const_iterator(this, pid_size);}
//! \~\brief
//! \~english Returns a reverse iterator to the first element of the reversed array.
//! \~russian Обратный итератор на первый элемент.
//! \~\details ![rbegin, rend](doc/images/pivector_rbegin.png)
@@ -617,8 +611,7 @@ public:
//! \~\sa \a rend(), \a begin(), \a end()
inline reverse_iterator rbegin() {return reverse_iterator(this, pid_size - 1);}
//! \~\brief
//! \~english Returns a reverse iterator to the element
//! \~english Returns a reverse iterator to the element.
//! following the last element of the reversed array.
//! \~russian Обратный итератор на элемент, следующий за последним элементом.
//! \~\details ![rbegin, rend](doc/images/pivector_rbegin.png)
@@ -636,25 +629,21 @@ public:
inline const_reverse_iterator rbegin() const {return const_reverse_iterator(this, pid_size - 1);}
inline const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
//! \~\brief
//! \~english Number of elements in the container.
//! \~russian Количество элементов массива.
//! \~\sa \a size_s(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline size_t size() const {return pid_size;}
//! \~\brief
//! \~english Number of elements in the container as signed value.
//! \~russian Количество элементов массива в виде знакового числа.
//! \~\sa \a size(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline ssize_t size_s() const {return pid_size;}
//! \~\brief
//! \~english Same as \a size().
//! \~russian Синоним \a size().
//! \~\sa \a size(), \a size_s(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline size_t length() const {return pid_size;}
//! \~\brief
//! \~english Number of elements that the container has currently allocated space for.
//! \~russian Количество элементов, для которого сейчас выделена память контейнером.
//! \~\details
@@ -665,7 +654,6 @@ public:
inline size_t _start() const {return pid_start;}
//! \~\brief
//! \~english Checks if the container has no elements.
//! \~russian Проверяет пуст ли контейнер.
//! \~\return
@@ -674,7 +662,6 @@ public:
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline bool isEmpty() const {return (pid_size == 0);}
//! \~\brief
//! \~english Checks if the container has elements.
//! \~russian Проверяет не пуст ли контейнер.
//! \~\return
@@ -683,7 +670,6 @@ public:
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline bool isNotEmpty() const {return (pid_size > 0);}
//! \~\brief
//! \~english Tests whether at least one element in the array
//! passes the test implemented by the provided function `test`.
//! \~russian Проверяет, удовлетворяет ли какой-либо элемент массива условию,
@@ -701,7 +687,7 @@ public:
//! piCout << v.any([](int e){return e % 2 == 0;}); // true
//! piCout << v.any([](int e){return e == 3;}); // false
//! \endcode
//! \~\sa \a every(), \a contains(), \a etries(), \a forEach()
//! \~\sa \a every(), \a contains(), \a entries(), \a forEach()
inline bool any(std::function<bool(const T & e)> test) const {
for (ssize_t i = pid_start; i < pid_start + (ssize_t)pid_size; ++i) {
if (test(pid_data[i])) return true;
@@ -709,7 +695,6 @@ public:
return false;
}
//! \~\brief
//! \~english Tests whether all elements in the array passes the test
//! implemented by the provided function `test`.
//! \~russian Проверяет, удовлетворяют ли все элементы массива условию,
@@ -735,7 +720,6 @@ public:
return true;
}
//! \brief
//! \~english Full access to element by `index`.
//! \~russian Полный доступ к элементу по индексу `index`.
//! \~\details
@@ -755,7 +739,6 @@ public:
inline T & operator [](size_t index) {return pid_data[pid_start + index];}
inline const T & operator [](size_t index) const {return pid_data[pid_start + index];}
//! \brief
//! \~english Read only access to element by `index`.
//! \~russian Доступ исключительно на чтение к элементу по индексу `index`.
//! \~\details
@@ -767,7 +750,6 @@ public:
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
inline const T & at(size_t index) const {return pid_data[pid_start + index];}
//! \brief
//! \~english Last element.
//! \~russian Последний элемент массива.
//! \~\details
@@ -780,7 +762,6 @@ public:
inline T & back() {return pid_data[pid_start + pid_size - 1];}
inline const T & back() const {return pid_data[pid_start + pid_size - 1];}
//! \brief
//! \~english Last element.
//! \~russian Первый элемент массива.
//! \~\details
@@ -793,7 +774,6 @@ public:
inline T & front() {return pid_data[pid_start];}
inline const T & front() const {return pid_data[pid_start];}
//! \brief
//! \~english Compare operator with array `v`.
//! \~russian Оператор сравнения с массивом `v`.
inline bool operator ==(const PIDeque<T> & v) const {
@@ -804,12 +784,10 @@ public:
return true;
}
//! \brief
//! \~english Compare operator with array `v`.
//! \~russian Оператор сравнения с массивом `v`.
inline bool operator !=(const PIDeque<T> & v) const {return !(*this == v);}
//! \~\brief
//! \~english Tests if element `e` exists in the array.
//! \~russian Проверяет наличие элемента `e` в массиве.
//! \~\details
@@ -841,7 +819,7 @@ public:
//! otherwise it returns **false**.
//! \~russian **true** если элемент `e` присутствует в массиве,
//! в остальных случаях **false**.
//! \~\sa \a every(), \a any(), \a etries(), \a forEach()
//! \~\sa \a every(), \a any(), \a entries(), \a forEach()
inline bool contains(const T & e, ssize_t start = 0) const {
if (start < 0) {
start = pid_size + start;
@@ -853,7 +831,6 @@ public:
return false;
}
//! \~\brief
//! \~english Count elements equal `e` in the array.
//! \~russian Подсчитывает количество элементов, совпадающих с элементом `e` в массиве.
//! \~\details
@@ -879,7 +856,7 @@ public:
//! piCout << v.entries(2, -4); // 2
//! \endcode
//! \~\sa \a every(), \a any(), \a contains(), \a forEach(), \a indexOf()
inline int etries(const T & e, size_t start = 0) const {
inline int entries(const T & e, size_t start = 0) const {
int ec = 0;
if (start < 0) {
start = pid_size + start;
@@ -891,7 +868,6 @@ public:
return ec;
}
//! \~\brief
//! \~english Count elements in the array passes the test implemented by the provided function `test`.
//! \~russian Подсчитывает количество элементов в массиве,
//! проходящих по условию, заданному в передаваемой функции `test`.
@@ -914,7 +890,7 @@ public:
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
//! \~\sa \a every(), \a any(), \a contains(), \a forEach(), \a indexWhere()
inline int etries(std::function<bool(const T & e)> test, size_t start = 0) const {
inline int entries(std::function<bool(const T & e)> test, size_t start = 0) const {
int ec = 0;
if (start < 0) {
start = pid_size + start;
@@ -926,7 +902,6 @@ public:
return ec;
}
//! \~\brief
//! \~english Returns the first index at which a given element `e`
//! can be found in the array, or `-1` if it is not present.
//! \~russian Возвращает первый индекс, по которому данный элемент `e`
@@ -969,7 +944,6 @@ public:
return -1;
}
//! \~\brief
//! \~english Returns the first index passes the test implemented by the provided function `test`,
//! or `-1` if it is not present.
//! can be found in the array, or `-1` if it is not present.
@@ -1011,7 +985,6 @@ public:
return -1;
}
//! \~\brief
//! \~english Returns the last index at which a given element `e`
//! can be found in the array, or `-1` if it is not present.
//! \~russian Возвращает последний индекс, по которому данный элемент `e`
@@ -1057,7 +1030,6 @@ public:
return -1;
}
//! \~\brief
//! \~english Returns the last index passes the test implemented by the provided function `test`,
//! or `-1` if it is not present.
//! \~russian Возвращает последний индекс элемента проходящего по условию,
@@ -1094,7 +1066,6 @@ public:
return -1;
}
//! \~\brief
//! \~english Pointer to array
//! \~russian Указатель на память массива
//! \~\details
@@ -1110,7 +1081,6 @@ public:
//! \endcode
inline T * data(size_t index = 0) {return &(pid_data[pid_start + index]);}
//! \~\brief
//! \~english Read only pointer to array
//! \~russian Указатель на память массива только для чтения.
//! \~\details
@@ -1130,7 +1100,6 @@ public:
//! \endcode
inline const T * data(size_t index = 0) const {return &(pid_data[pid_start + index]);}
//! \~\brief
//! \~english Creates sub-array of this array.
//! \~russian Создает подмассив, то есть кусок из текущего массива.
//! \~english
@@ -1153,7 +1122,6 @@ public:
return PIDeque(&(pid_data[pid_start + index]), count);
}
//! \~\brief
//! \~english Clear array, remove all elements.
//! \~russian Очищает массив, удаляет все элементы.
//! \~\details
@@ -1178,7 +1146,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Assigns element 'e' to all items in the array.
//! \~russian Заполняет весь массив копиями элемента 'e'.
//! \~\details
@@ -1197,7 +1164,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Assigns result of function 'f(size_t i)' to all items in the array.
//! \~russian Заполняет весь массив результатом вызова функции 'f(size_t i)'.
//! \~\details
@@ -1216,13 +1182,11 @@ public:
return *this;
}
//! \~\brief
//! \~english Same as \a fill().
//! \~russian Тоже самое что и \a fill().
//! \~\sa \a fill(), \a resize()
inline PIDeque<T> & assign(const T & e = T()) {return fill(e);}
//! \~\brief
//! \~english First does `resize(new_size)` then `fill(e)`.
//! \~russian Сначала делает `resize(new_size)`, затем `fill(e)`.
//! \~\sa \a fill(), \a resize()
@@ -1241,7 +1205,6 @@ public:
return fill(e);
}
//! \~\brief
//! \~english Sets size of the array, new elements are copied from `e`.
//! \~russian Устанавливает размер массива, новые элементы копируются из `e`.
//! \~\details
@@ -1272,7 +1235,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Sets size of the array, new elements created by function `f(size_t i)`.
//! \~russian Устанавливает размер массива, новые элементы создаются функцией `f(size_t i)`.
//! \~\details
@@ -1321,7 +1283,6 @@ public:
newT(dst, src, size);
}
//! \~\brief
//! \~english Attempts to allocate memory for at least `new_size` elements.
//! \~russian Резервируется память под как минимум `new_size` элементов.
//! \~\details
@@ -1344,7 +1305,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Inserts value `e` at `index` position in the array.
//! \~russian Вставляет значение `e` в позицию `index` в массиве.
//! \~\details
@@ -1376,7 +1336,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Inserts value `e` at `index` position in the array.
//! \~russian Вставляет значение `e` в позицию `index` в массиве.
//! \~\details
@@ -1403,7 +1362,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Inserts array `v` at `index` position in the array.
//! \~russian Вставляет массив `v` в позицию `index` в массиве.
//! \~\details
@@ -1435,7 +1393,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Inserts the given elements at `index` position in the array.
//! \~russian Вставляет элементы в позицию `index` в массиве.
//! \~\details
@@ -1464,7 +1421,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Removes `count` elements from the middle of the array, starting at `index` position.
//! \~russian Удаляет элементы из массива, начиная с позиции `index` в количестве `count`.
//! \~\details
@@ -1496,7 +1452,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Swaps array `v` other with this array.
//! \~russian Меняет местами массив `v` с этим массивом.
//! \~\details
@@ -1509,7 +1464,6 @@ public:
piSwap<ssize_t>(pid_start, other.pid_start);
}
//! \~\brief
//! \~english Sorts the elements in non-descending order.
//! \~russian Сортировка элементов в порядке возрастания.
//! \~\details
@@ -1532,7 +1486,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Sorts the elements in non-descending order.
//! \~russian Сортировка элементов в порядке возрастания.
//! \~\details
@@ -1572,7 +1525,6 @@ public:
}
//! \~\brief
//! \~english Reverses this array.
//! \~russian Обращает порядок следования элементов этого массива.
//! \~\details
@@ -1597,7 +1549,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Returns reversed array.
//! \~russian Возвращает перевернутый массив.
//! \~\details
@@ -1611,7 +1562,6 @@ public:
return ret.reverse();
}
//! \~\brief
//! \~english Increases or decreases the size of the array by `add_size` elements.
//! \~russian Увеличивает или уменьшает размер массива на `add_size` элементов.
//! \~\details
@@ -1629,7 +1579,6 @@ public:
return *this;
}
//! \brief
//! \~english Remove no more than one element equal `e`.
//! \~russian Удаляет первый элемент, который равен элементу `e`.
//! \~\details
@@ -1649,7 +1598,6 @@ public:
return *this;
}
//! \brief
//! \~english Remove all elements equal `e`.
//! \~russian Удаляет все элементы, равные элементу `e`.
//! \~\details
@@ -1669,7 +1617,6 @@ public:
return *this;
}
//! \brief
//! \~english Remove all elements in the array
//! passes the test implemented by the provided function `test`.
//! \~russian Удаляет все элементы, удовлетворяющие условию,
@@ -1691,7 +1638,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
@@ -1723,7 +1669,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
@@ -1737,7 +1682,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given elements to the end of the array.
//! \~russian Добавляет элементы в конец массива.
//! \~\details
@@ -1755,7 +1699,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given array `v` to the end of the array.
//! \~russian Добавляет массив `v` в конец массива.
//! \~\details
@@ -1775,7 +1718,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
@@ -1802,7 +1744,6 @@ public:
//! \~\sa \a prepend(), \a push_front(), \a push_back(), \a insert()
inline PIDeque<T> & append(const T & e) {return push_back(e);}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
@@ -1811,7 +1752,6 @@ public:
//! \~\sa \a append()
inline PIDeque<T> & append(T && e) {return push_back(std::move(e));}
//! \brief
//! \~english Appends the given elements to the end of the array.
//! \~russian Добавляет элементы в конец массива.
//! \~\details
@@ -1824,7 +1764,6 @@ public:
//! \~\sa \a append()
inline PIDeque<T> & append(std::initializer_list<T> init_list) {return push_back(init_list);}
//! \brief
//! \~english Appends the given array `v` to the end of the array.
//! \~russian Добавляет массив `v` в конец массива.
//! \~\details
@@ -1838,7 +1777,6 @@ public:
//! \~\sa \a append()
inline PIDeque<T> & append(const PIDeque<T> & v) {return push_back(v);}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
@@ -1850,7 +1788,6 @@ public:
//! \~\sa \a append()
inline PIDeque<T> & operator <<(const T & e) {return push_back(e);}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
@@ -1862,7 +1799,6 @@ public:
//! \~\sa \a append()
inline PIDeque<T> & operator <<(T && e) {return push_back(std::move(e));}
//! \brief
//! \~english Appends the given array `v` to the end of the array.
//! \~russian Добавляет массив `v` в конец массива.
//! \~\details
@@ -1874,7 +1810,6 @@ public:
//! \~\sa \a append(), \a push_back()
inline PIDeque<T> & operator <<(const PIDeque<T> & v) {return append(v);}
//! \brief
//! \~english Appends the given element `e` to the begin of the array.
//! \~russian Добавляет элемент `e` в начало массива.
//! \~\details
@@ -1904,7 +1839,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given element `e` to the begin of the array.
//! \~russian Добавляет элемент `e` в начало массива.
//! \~\details
@@ -1916,7 +1850,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given array `v` to the begin of the array.
//! \~russian Добавляет массив `v` в начало массива.
//! \~\details
@@ -1933,7 +1866,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given elements to the begin of the array.
//! \~russian Добавляет элементы в начало массива.
//! \~\details
@@ -1949,7 +1881,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given element `e` to the begin of the array.
//! \~russian Добавляет элемент `e` в начало массива.
//! \~\details
@@ -1976,7 +1907,6 @@ public:
//! \~\sa \a push_back(), \a append(), \a prepend(), \a insert()
inline PIDeque<T> & prepend(const T & e) {return push_front(e);}
//! \brief
//! \~english Appends the given element `e` to the begin of the array.
//! \~russian Добавляет элемент `e` в начало массива.
//! \~\details
@@ -1985,7 +1915,6 @@ public:
//! \~\sa \a prepend()
inline PIDeque<T> & prepend(T && e) {return push_front(std::move(e));}
//! \brief
//! \~english Appends the given array `v` to the begin of the array.
//! \~russian Добавляет массив `v` в начало массива.
//! \~\details
@@ -1999,7 +1928,6 @@ public:
//! \~\sa \a prepend()
inline PIDeque<T> & prepend(const PIDeque<T> & v) {return push_front(v);}
//! \brief
//! \~english Appends the given elements to the begin of the array.
//! \~russian Добавляет элементы в начало массива.
//! \~\details
@@ -2012,7 +1940,6 @@ public:
//! \~\sa \a append()
inline PIDeque<T> & prepend(std::initializer_list<T> init_list) {return prepend(init_list);}
//! \brief
//! \~english Remove one element from the end of the array.
//! \~russian Удаляет один элемент с конца массива.
//! \~\details
@@ -2032,7 +1959,6 @@ public:
return *this;
}
//! \brief
//! \~english Remove one element from the begining of the array.
//! \~russian Удаляет один элемент с начала массива.
//! \~\details
@@ -2054,7 +1980,6 @@ public:
return *this;
}
//! \brief
//! \~english Remove one element from the end of the array and return it.
//! \~russian Удаляет один элемент с начала массива и возвращает его.
//! \~\details
@@ -2070,7 +1995,6 @@ public:
return e;
}
//! \brief
//! \~english Remove one element from the begining of the array and return it.
//! \~russian Удаляет один элемент с конца массива и возвращает его.
//! \~\details
@@ -2086,7 +2010,6 @@ public:
return e;
}
//! \brief
//! \~english Returns an array converted to another type.
//! \~russian Возвращает конвертированный в другой тип массив.
//! \~\details
@@ -2105,7 +2028,6 @@ public:
return ret;
}
//! \brief
//! \~english Returns a new array with all elements
//! that pass the test implemented by the provided function `test`.
//! \~russian Возвращает новый массив со всеми элементами,
@@ -2125,7 +2047,6 @@ public:
return ret;
}
//! \brief
//! \~english Execute function `void f(const T & e)` for every element in array.
//! \~russian Выполняет функцию `void f(const T & e)` для каждого элемента массива.
//! \~\details
@@ -2146,7 +2067,6 @@ public:
}
}
//! \brief
//! \~english Execute function `void f(T & e)` for every element in array.
//! \~russian Выполняет функцию `void f(T & e)` для каждого элемента массива.
//! \~\details
@@ -2167,7 +2087,6 @@ public:
return *this;
}
//! \brief
//! \~english Сreates a new array populated with the results
//! of calling a provided function `ST f(const T & e)` on every element in the calling array.
//! \~russian Создаёт новый массив с результатом вызова указанной функции
@@ -2194,7 +2113,6 @@ public:
return ret;
}
//! \brief
//! \~english Applies the function `ST f(const T & e, const ST & acc)`
//! to each element of the array (from left to right), returns one value.
//! \~russian Применяет функцию `ST f(const T & e, const ST & acc)`
@@ -2245,7 +2163,6 @@ public:
return ret;
}
//! \brief
//! \~english Changes the dimension of the array, creates a two-dimensional array from a one-dimensional array.
//! \~russian Изменяет размерность массива, из одномерного массива создает двухмерный.
//! \~\details
@@ -2291,7 +2208,6 @@ public:
return ret;
}
//! \brief
//! \~english Changes the dimension of the array, creates a one-dimensional array from a two-dimensional array.
//! \~russian Изменяет размерность массива, из двухмерный массива создает одномерный.
//! \~\details
@@ -2331,7 +2247,6 @@ public:
return ret;
}
//! \brief
//! \~english Changes the dimension of the two-dimensional array.
//! \~russian Изменяет размерность двухмерного массива.
//! \~\details
@@ -2365,10 +2280,9 @@ private:
if (pid_rsize + pid_rsize >= size_t(s) && pid_rsize < size_t(s)) {
return pid_rsize + pid_rsize;
}
ssize_t t = 0, s_ = s - 1;
while (s_ >> t) {
ssize_t t = _PIContainerConstants<T>::minCountPoT(), s_ = s - 1;
while (s_ >> t)
++t;
}
return (1 << t);
}
template<typename T1 = T, typename std::enable_if<

View File

@@ -30,41 +30,6 @@
#include "pipair.h"
template<class T>
void piQuickSort(T * a, ssize_t N) {
if (N < 1) return;
if (N < 46) {
T tmp;
ssize_t i,j;
for(i=1; i<=N; i++) {
tmp = a[i];
j = i-1;
while(tmp<a[j] && j>=0) {
a[j+1] = a[j];
j = j-1;
}
a[j+1] = tmp;
}
} else {
ssize_t i = 0, j = N;
T & p(a[N >> 1]);
do {
while (a[i] < p) i++;
while (a[j] > p) j--;
if (i <= j) {
if (i != j) {
//piCout << "swap" << i << j << a[i] << a[j];
piSwap<T>(a[i], a[j]);
}
i++; j--;
}
} while (i <= j);
if (j > 0) piQuickSort(a, j);
if (N > i) piQuickSort(a + i, N - i);
}
}
template <typename Key, typename T>
class PIMapIterator;
@@ -75,16 +40,19 @@ class PIMap {
template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIMap<Key1, T1> & v);
template <typename Key1, typename T1> friend class PIMapIterator;
public:
PIMap() {;}
PIMap() {}
PIMap(const PIMap<Key, T> & other) {*this = other;}
PIMap(PIMap<Key, T> && other) : pim_content(std::move(other.pim_content)), pim_index(std::move(other.pim_index)) {}
PIMap(PIMap<Key, T> && other) : pim_content(std::move(other.pim_content)) {}
PIMap(std::initializer_list<std::pair<Key, T>> init_list) {
for (auto i: init_list)
insert(std::get<0>(i), std::get<1>(i));
}
virtual ~PIMap() {;}
PIMap<Key, T> & operator =(const PIMap<Key, T> & other) {
if (this == &other) return *this;
clear();
pim_content = other.pim_content;
pim_index = other.pim_index;
return *this;
}
@@ -199,12 +167,15 @@ public:
T & operator [](const Key & key) {
bool f(false);
ssize_t i = _find(key, f);
if (f) return pim_content[pim_index[i].index];
pim_content.push_back(T());
pim_index.insert(i, MapIndex(key, pim_content.size() - 1));
return pim_content.back();
if (!f) pim_content.insert(i, PIPair<Key, T>(key, T()));
return pim_content[i].second;
}
const T operator [](const Key & key) const {
bool f(false);
ssize_t i = _find(key, f);
if (f) return pim_content[i].second;
return T();
}
const T operator [](const Key & key) const {bool f(false); ssize_t i = _find(key, f); if (f) return pim_content[pim_index[i].index]; return T();}
const T at(const Key & key) const {return (*this)[key];}
PIMap<Key, T> & operator <<(const PIMap<Key, T> & other) {
@@ -215,27 +186,26 @@ public:
#endif
assert(&other != this);
if (other.isEmpty()) return *this;
if (other.size() == 1) {insert(other.pim_index[0].key, other.pim_content[0]); return *this;}
if (other.size() == 2) {insert(other.pim_index[0].key, other.pim_content[0]); insert(other.pim_index[1].key, other.pim_content[1]); return *this;}
for (int i = 0; i < other.pim_index.size_s(); ++i)
insert(other.pim_index[i].key, other.pim_content[other.pim_index[i].index]);
// if (other.size() == 1) {insert(other.pim_index[0].key, other.pim_content[0]); return *this;}
// if (other.size() == 2) {insert(other.pim_index[0].key, other.pim_content[0]); insert(other.pim_index[1].key, other.pim_content[1]); return *this;}
for (int i = 0; i < other.pim_content.size_s(); ++i)
insert(other.pim_content[i].first, other.pim_content[i].second);
return *this;
}
bool operator ==(const PIMap<Key, T> & t) const {return (pim_content == t.pim_content && pim_index == t.pim_index);}
bool operator !=(const PIMap<Key, T> & t) const {return (pim_content != t.pim_content || pim_index != t.pim_index);}
bool operator ==(const PIMap<Key, T> & t) const {return (pim_content == t.pim_content);}
bool operator !=(const PIMap<Key, T> & t) const {return (pim_content != t.pim_content);}
bool contains(const Key & key) const {bool f(false); _find(key, f); return f;}
PIMap<Key, T> & reserve(size_t new_size) {pim_content.reserve(new_size); pim_index.reserve(new_size); return *this;}
PIMap<Key, T> & reserve(size_t new_size) {pim_content.reserve(new_size);return *this;}
PIMap<Key, T> & removeOne(const Key & key) {bool f(false); ssize_t i = _find(key, f); if (f) _remove(i); return *this;}
PIMap<Key, T> & remove(const Key & key) {return removeOne(key);}
PIMap<Key, T> & erase(const Key & key) {return removeOne(key);}
PIMap<Key, T> & clear() {pim_content.clear(); pim_index.clear(); return *this;}
PIMap<Key, T> & clear() {pim_content.clear(); return *this;}
void swap(PIMap<Key, T> & other) {
pim_content.swap(other.pim_content);
pim_index.swap(other.pim_index);
}
PIMap<Key, T> & insert(const Key & key, const T & value) {
@@ -243,10 +213,9 @@ public:
ssize_t i = _find(key, f);
//piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value;
if (f) {
pim_content[pim_index[i].index] = value;
pim_content[i].second = value;
} else {
pim_content.push_back(value);
pim_index.insert(i, MapIndex(key, pim_content.size() - 1));
pim_content.insert(i, PIPair<Key, T>(key, value));
}
return *this;
}
@@ -255,20 +224,34 @@ public:
ssize_t i = _find(key, f);
//piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value;
if (f) {
pim_content[pim_index[i].index] = std::move(value);
pim_content[i].second = std::move(value);
} else {
pim_content.push_back(std::move(value));
pim_index.insert(i, MapIndex(key, pim_content.size() - 1));
// pim_content.push_back(std::move(value));
// pim_index.insert(i, MapIndex(key, pim_content.size() - 1));
pim_content.insert(i, PIPair<Key, T>(key, std::move(value)));
}
return *this;
}
const T value(const Key & key, const T & default_ = T()) const {bool f(false); ssize_t i = _find(key, f); if (!f) return default_; return pim_content[pim_index[i].index];}
PIVector<T> values() const {return pim_content;}
Key key(const T & value_, const Key & default_ = Key()) const {for (int i = 0; i < pim_index.size_s(); ++i) if (pim_content[pim_index[i].index] == value_) return pim_index[i].key; return default_;}
const T value(const Key & key, const T & default_ = T()) const {
bool f(false);
ssize_t i = _find(key, f);
if (!f) return default_;
return pim_content[i].second;
}
PIVector<T> values() const {
PIVector<T> ret;
for (size_t i = 0; i < pim_content.size(); ++i) ret << pim_content[i].second;
return ret;
}
Key key(const T & value_, const Key & default_ = Key()) const {
for (int i = 0; i < pim_content.size_s(); ++i)
if (pim_content[i].second == value_)
return pim_content[i].first;
return default_;
}
PIVector<Key> keys() const {
PIVector<Key> ret;
for (int i = 0; i < pim_index.size_s(); ++i)
ret << pim_index[i].key;
for (size_t i = 0; i < pim_content.size(); ++i) ret << pim_content[i].first;
return ret;
}
@@ -276,66 +259,53 @@ public:
piCout << "PIMap" << size() << "entries" << PICoutManipulators::NewLine << "content:";
for (size_t i = 0; i < pim_content.size(); ++i)
piCout << PICoutManipulators::Tab << i << ":" << pim_content[i];
piCout << "index:";
for (size_t i = 0; i < pim_index.size(); ++i)
piCout << PICoutManipulators::Tab << i << ":" << pim_index[i].key << "->" << pim_index[i].index;
// piCout << "index:";
// for (size_t i = 0; i < pim_index.size(); ++i)
// piCout << PICoutManipulators::Tab << i << ":" << pim_index[i].key << "->" << pim_index[i].index;
}
protected:
struct MapIndex {
MapIndex(Key k = Key(), size_t i = 0): key(k), index(i) {;}
Key key;
size_t index;
bool operator ==(const MapIndex & s) const {return key == s.key;}
bool operator !=(const MapIndex & s) const {return key != s.key;}
bool operator <(const MapIndex & s) const {return key < s.key;}
bool operator >(const MapIndex & s) const {return key > s.key;}
};
template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
// struct MapIndex {
// MapIndex(Key k = Key(), size_t i = 0): key(k), index(i) {;}
// Key key;
// size_t index;
// bool operator ==(const MapIndex & s) const {return key == s.key;}
// bool operator !=(const MapIndex & s) const {return key != s.key;}
// bool operator <(const MapIndex & s) const {return key < s.key;}
// bool operator >(const MapIndex & s) const {return key > s.key;}
// };
// template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
// template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
ssize_t binarySearch(ssize_t first, ssize_t last, const Key & key, bool & found) const {
ssize_t mid;
while (first <= last) {
mid = (first + last) / 2;
if (key > pim_index[mid].key) first = mid + 1;
else if (key < pim_index[mid].key) last = mid - 1;
if (key > pim_content[mid].first) first = mid + 1;
else if (key < pim_content[mid].first) last = mid - 1;
else {found = true; return mid;}
}
found = false;
return first;
}
void _sort() {piQuickSort<MapIndex>(pim_index.data(), pim_index.size_s() - 1);}
ssize_t _find(const Key & k, bool & found) const {
if (pim_index.isEmpty()) {
if (pim_content.isEmpty()) {
found = false;
return 0;
}
return binarySearch(0, pim_index.size_s() - 1, k, found);
return binarySearch(0, pim_content.size_s() - 1, k, found);
}
void _remove(ssize_t index) {
//if (index >= pim_index.size()) return;
size_t ci = pim_index[index].index, bi = pim_index.size() - 1;
pim_index.remove(index);
for (size_t i = 0; i < pim_index.size(); ++i)
if (pim_index[i].index == bi) {
pim_index[i].index = ci;
break;
}
piSwap<T>(pim_content[ci], pim_content.back());
pim_content.resize(pim_index.size());
pim_content.remove(index);
}
const value_type _pair(ssize_t index) const {
if (index < 0 || index >= pim_index.size_s())
return value_type();
//piCout << "_pair" << index << pim_index[index].index;
return value_type(pim_index[index].key, pim_content[pim_index[index].index]);
if (index < 0 || index >= pim_content.size_s()) return value_type();
return pim_content[index];
}
Key & _key(ssize_t index) {return pim_index[index].key;}
T & _value(ssize_t index) {return pim_content[pim_index[index].index];}
Key & _key(ssize_t index) {return pim_content[index].first;}
T & _value(ssize_t index) {return pim_content[index].second;}
PIVector<T> pim_content;
PIDeque<MapIndex> pim_index;
PIDeque<PIPair<Key, T>> pim_content;
};

View File

@@ -1,8 +1,17 @@
/*! \file pipair.h
* \brief pair
*
* This file declare PIPair
*/
//! \addtogroup Containers
//! \{
//! \file pipair.h
//! \brief
//! \~english Declares \a PIPair
//! \~russian Объявление \a PIPair
//! \~\authors
//! \~english
//! Ivan Pelipenko peri4ko@yandex.ru;
//! Andrey Bychkov work.a.b@yandex.ru;
//! \~russian
//! Иван Пелипенко peri4ko@yandex.ru;
//! Андрей Бычков work.a.b@yandex.ru;
//! \~\}
/*
PIP - Platform Independent Primitives
pair
@@ -27,30 +36,109 @@
#include "picout.h"
class PICout;
//! \addtogroup Containers
//! \{
//! \class PIPair
//! \brief
//! \~english Class template that provides a way to store two heterogeneous objects as a single unit.
//! \~russian Класс, который позволяет хранить два разнородных объекта как единое целое.
//! \~\}
//! \details
//! \~english
//! \~russian
//! \~\sa \a PIMap
template<typename Type0, typename Type1>
class PIPair {
public:
PIPair() {first = Type0(); second = Type1();}
PIPair(std::tuple<Type0, Type1> tuple) {first = std::get<0>(tuple); second = std::get<1>(tuple);}
PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;}
//! \~english Constructs an empty PIPair.
//! \~russian Создает пустой PIPair.
PIPair() : first(), second() {}
//! \~english Constructs PIPair from [std::tuple](https://en.cppreference.com/w/cpp/utility/tuple).
//! \~russian Создает PIPair из [std::tuple](https://ru.cppreference.com/w/cpp/utility/tuple).
PIPair(std::tuple<Type0, Type1> tuple) {
first = std::get<0>(tuple);
second = std::get<1>(tuple);
}
//! \~english Constructs PIPair from values `value0` and `value1`.
//! \~russian Создает PIPair из `value0` и `value1`.
PIPair(const Type0 & value0, const Type1 & value1) {
first = value0;
second = value1;
}
//! \~english Move constructor.
//! \~russian Перемещающий конструктор.
PIPair(Type0 && value0, Type1 && value1) {
first = std::move(value0);
second = std::move(value1);
}
//! \~english First element.
//! \~russian Первый элемент.
Type0 first;
//! \~english Second element.
//! \~russian Второй элемент.
Type1 second;
};
//! \~english Compare operator with PIPair.
//! \~russian Оператор сравнения с PIPair.
template<typename Type0, typename Type1>
inline bool operator <(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return value0.first < value1.first;}
inline bool operator ==(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {
return (value0.first == value1.first) && (value0.second == value1.second);
}
//! \~english Compare operator with PIPair.
//! \~russian Оператор сравнения с PIPair.
template<typename Type0, typename Type1>
inline bool operator ==(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return (value0.first == value1.first) && (value0.second == value1.second);}
template<typename Type0, typename Type1>
inline bool operator !=(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return (value0.first != value1.first) || (value0.second != value1.second);}
inline bool operator !=(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {
return (value0.first != value1.first) || (value0.second != value1.second);
}
#ifdef PIP_STD_IOSTREAM
template<typename Type0, typename Type1>
inline std::ostream & operator <<(std::ostream & s, const PIPair<Type0, Type1> & v) {s << "(" << v.first << ", " << v.second << ")"; return s;}
inline std::ostream & operator <<(std::ostream & s, const PIPair<Type0, Type1> & v) {
s << "(" << v.first << ", " << v.second << ")";
return s;
}
#endif
//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
template<typename Type0, typename Type1>
inline PICout operator <<(PICout s, const PIPair<Type0, Type1> & v) {s.space(); s.setControl(0, true); s << "(" << v.first << ", " << v.second << ")"; s.restoreControl(); return s;}
inline PICout operator <<(PICout s, const PIPair<Type0, Type1> & v) {
s.space();
s.setControl(0, true);
s << "(" << v.first << ", " << v.second << ")";
s.restoreControl();
return s;
}
//! \~english Creates \a PIPair object, deducing the target type from the types of arguments.
//! \~russian Создает \a PIPair выводя типы из аргументов.
//! \~\details
//! \~\code
//! auto p = createPIPair(1, 'a');
//! piCout << p; // (1, a)
//! \endcode
template< class T1, class T2 >
PIPair<T1,T2> createPIPair(const T1 & f, const T2 & s) {
return PIPair<T1,T2>(f, s);
}
//! \~english Creates \a PIPair object, deducing the target type from the types of arguments.
//! \~russian Создает \a PIPair выводя типы из аргументов.
//! \sa \a createPIPair()
template< class T1, class T2 >
PIPair<T1,T2> createPIPair(T1 && f, T2 && s) {
return PIPair<T1,T2>(std::move(f), std::move(s));
}
#endif // PIPAIR_H

View File

@@ -1,4 +1,4 @@
/*! \file pideque.h
/*! \file piqueue.h
* \brief Queue container
*
* This file declare PIQueue

View File

@@ -58,7 +58,7 @@
//! This number is called the item's index.
//! So the first item has index 0, the last has index `size() - 1`.
//! A set of various convenient functions is also available for the array,
//! for example: \a indexOf, \a contains(), \a entries(), \a isEmpty(), \a isNotEmpty(),
//! for example: \a indexOf(), \a contains(), \a entries(), \a isEmpty(), \a isNotEmpty(),
//! \a every(), \a any(), \a forEach(), \a indexWhere(), \a getRange(), \a sort(),
//! \a map(), \a reduce(), \a filter(), \a flatten(), \a reshape() and others.
//!
@@ -90,7 +90,7 @@
//! первый элемент массива имеет индекс, равный `0`,
//! а индекс последнего элемента равен `size() - 1`.
//! Также для массива доступен набор различных удобных функций,
//! например: \a indexOf, \a contains(), \a entries(), \a isEmpty(), \a isNotEmpty(),
//! например: \a indexOf(), \a contains(), \a entries(), \a isEmpty(), \a isNotEmpty(),
//! \a every(), \a any(), \a forEach(), \a indexWhere(), \a getRange(), \a sort(),
//! \a map(), \a reduce(), \a filter(), \a flatten(), \a reshape() и другие.
//!
@@ -113,20 +113,24 @@
//! - Вставка и удаление элементов в конце — амортизированная постоянная 𝓞(1)
//! - Вставка и удаление элементов — линейная по расстоянию до конца массива 𝓞(n)
//!
//! \~\sa \a PIDeueue, \a PIMap
//! \~\sa \a PIDeque, \a PIMap
template <typename T>
class PIVector {
public:
typedef bool (*CompareFunc)(const T & , const T & );
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
//! \~\brief
//! \~english Constructs an empty array.
//! \~russian Создает пустой массив.
inline PIVector(): piv_data(0), piv_size(0), piv_rsize(0) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
}
//! \~\brief
//! \~english Contructs array from raw `data`.
//! This constructor reserve `size` and copy from `data` pointer.
//! \~russian Создает массив из указателя на данные `data` и размер `size`.
@@ -137,7 +141,6 @@ public:
newT(piv_data, data, piv_size);
}
//! \~\brief
//! \~english Copy constructor.
//! \~russian Копирующий конструктор.
inline PIVector(const PIVector<T> & v): piv_data(0), piv_size(0), piv_rsize(0) {
@@ -146,7 +149,6 @@ public:
newT(piv_data, v.piv_data, piv_size);
}
//! \~\brief
//! \~english Contructs array from
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
//! \~russian Создает массив из
@@ -162,7 +164,6 @@ public:
newT(piv_data, init_list.begin(), init_list.size());
}
//! \~\brief
//! \~english Contructs array with size `size` filled elements `e`.
//! \~russian Создает массив из `size` элементов заполненных `e`.
inline PIVector(size_t size, const T & e = T()): piv_data(0), piv_size(0), piv_rsize(0) {
@@ -170,7 +171,6 @@ public:
resize(size, e);
}
//! \~\brief
//! \~english Contructs array with size `size` and elements created by function `f(size_t i)`.
//! \~russian Создает массив из `size` элементов созданных функцией `f(size_t i)`.
//! \~\details
@@ -189,7 +189,6 @@ public:
resize(size, f);
}
//! \~\brief
//! \~english Move constructor.
//! \~russian Перемещающий конструктор.
inline PIVector(PIVector<T> && v): piv_data(v.piv_data), piv_size(v.piv_size), piv_rsize(v.piv_rsize) {
@@ -205,7 +204,6 @@ public:
_reset();
}
//! \~\brief
//! \~english Assign operator.
//! \~russian Оператор присваивания.
inline PIVector<T> & operator =(const PIVector<T> & v) {
@@ -217,7 +215,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Assign move operator.
//! \~russian Оператор перемещающего присваивания.
inline PIVector<T> & operator =(PIVector<T> && v) {
@@ -249,8 +246,8 @@ public:
++pos;
return *this;
}
inline iterator & operator ++(int) {
const auto tmp = *this;
inline iterator operator ++(int) {
auto tmp = *this;
++*this;
return tmp;
}
@@ -258,8 +255,8 @@ public:
--pos;
return *this;
}
inline iterator & operator --(int) {
const auto tmp = *this;
inline iterator operator --(int) {
auto tmp = *this;
--*this;
return tmp;
}
@@ -336,8 +333,8 @@ public:
++pos;
return *this;
}
inline const_iterator & operator ++(int) {
const auto tmp = *this;
inline const_iterator operator ++(int) {
auto tmp = *this;
++*this;
return tmp;
}
@@ -345,8 +342,8 @@ public:
--pos;
return *this;
}
inline const_iterator & operator --(int) {
const auto tmp = *this;
inline const_iterator operator --(int) {
auto tmp = *this;
--*this;
return tmp;
}
@@ -425,8 +422,8 @@ public:
--pos;
return *this;
}
inline reverse_iterator & operator ++(int) {
const auto tmp = *this;
inline reverse_iterator operator ++(int) {
auto tmp = *this;
--*this;
return tmp;
}
@@ -434,8 +431,8 @@ public:
++pos;
return *this;
}
inline reverse_iterator & operator --(int) {
const auto tmp = *this;
inline reverse_iterator operator --(int) {
auto tmp = *this;
++*this;
return tmp;
}
@@ -511,8 +508,8 @@ public:
--pos;
return *this;
}
inline const_reverse_iterator & operator ++(int) {
const auto tmp = *this;
inline const_reverse_iterator operator ++(int) {
auto tmp = *this;
--*this;
return tmp;
}
@@ -520,8 +517,8 @@ public:
++pos;
return *this;
}
inline const_reverse_iterator & operator --(int) {
const auto tmp = *this;
inline const_reverse_iterator operator --(int) {
auto tmp = *this;
++*this;
return tmp;
}
@@ -576,7 +573,6 @@ public:
}
};
//! \~\brief
//! \~english Iterator to the first element.
//! \~russian Итератор на первый элемент.
//! \~\details ![begin, end](doc/images/pivector_begin.png)
@@ -587,7 +583,6 @@ public:
//! \~\sa \a end(), \a rbegin(), \a rend()
inline iterator begin() {return iterator(this, 0);}
//! \~\brief
//! \~english Iterator to the element following the last element.
//! \~russian Итератор на элемент, следующий за последним элементом.
//! \~\details ![begin, end](doc/images/pivector_begin.png)
@@ -603,7 +598,6 @@ public:
inline const_iterator begin() const {return const_iterator(this, 0);}
inline const_iterator end() const {return const_iterator(this, piv_size);}
//! \~\brief
//! \~english Returns a reverse iterator to the first element of the reversed array.
//! \~russian Обратный итератор на первый элемент.
//! \~\details ![rbegin, rend](doc/images/pivector_rbegin.png)
@@ -617,7 +611,6 @@ public:
//! \~\sa \a rend(), \a begin(), \a end()
inline reverse_iterator rbegin() {return reverse_iterator(this, piv_size - 1);}
//! \~\brief
//! \~english Returns a reverse iterator to the element
//! following the last element of the reversed array.
//! \~russian Обратный итератор на элемент, следующий за последним элементом.
@@ -636,25 +629,21 @@ public:
inline const_reverse_iterator rbegin() const {return const_reverse_iterator(this, piv_size - 1);}
inline const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
//! \~\brief
//! \~english Number of elements in the container.
//! \~russian Количество элементов массива.
//! \~\sa \a size_s(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline size_t size() const {return piv_size;}
//! \~\brief
//! \~english Number of elements in the container as signed value.
//! \~russian Количество элементов массива в виде знакового числа.
//! \~\sa \a size(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline ssize_t size_s() const {return piv_size;}
//! \~\brief
//! \~english Same as \a size().
//! \~russian Синоним \a size().
//! \~\sa \a size(), \a size_s(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline size_t length() const {return piv_size;}
//! \~\brief
//! \~english Number of elements that the container has currently allocated space for.
//! \~russian Количество элементов, для которого сейчас выделена память контейнером.
//! \~\details
@@ -663,7 +652,6 @@ public:
//! \~\sa \a reserve(), \a size(), \a size_s()
inline size_t capacity() const {return piv_rsize;}
//! \~\brief
//! \~english Checks if the container has no elements.
//! \~russian Проверяет пуст ли контейнер.
//! \~\return
@@ -672,7 +660,6 @@ public:
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline bool isEmpty() const {return (piv_size == 0);}
//! \~\brief
//! \~english Checks if the container has elements.
//! \~russian Проверяет не пуст ли контейнер.
//! \~\return
@@ -681,7 +668,6 @@ public:
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline bool isNotEmpty() const {return (piv_size > 0);}
//! \~\brief
//! \~english Tests whether at least one element in the array
//! passes the test implemented by the provided function `test`.
//! \~russian Проверяет, удовлетворяет ли какой-либо элемент массива условию,
@@ -699,7 +685,7 @@ public:
//! piCout << v.any([](int e){return e % 2 == 0;}); // true
//! piCout << v.any([](int e){return e == 3;}); // false
//! \endcode
//! \~\sa \a every(), \a contains(), \a etries(), \a forEach()
//! \~\sa \a every(), \a contains(), \a entries(), \a forEach()
inline bool any(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < piv_size; ++i) {
if (test(piv_data[i])) return true;
@@ -707,7 +693,6 @@ public:
return false;
}
//! \~\brief
//! \~english Tests whether all elements in the array passes the test
//! implemented by the provided function `test`.
//! \~russian Проверяет, удовлетворяют ли все элементы массива условию,
@@ -733,7 +718,6 @@ public:
return true;
}
//! \brief
//! \~english Full access to element by `index`.
//! \~russian Полный доступ к элементу по индексу `index`.
//! \~\details
@@ -753,7 +737,6 @@ public:
inline T & operator [](size_t index) {return piv_data[index];}
inline const T & operator [](size_t index) const {return piv_data[index];}
//! \brief
//! \~english Read only access to element by `index`.
//! \~russian Доступ исключительно на чтение к элементу по индексу `index`.
//! \~\details
@@ -765,7 +748,6 @@ public:
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
inline const T & at(size_t index) const {return piv_data[index];}
//! \brief
//! \~english Last element.
//! \~russian Последний элемент массива.
//! \~\details
@@ -778,7 +760,6 @@ public:
inline T & back() {return piv_data[piv_size - 1];}
inline const T & back() const {return piv_data[piv_size - 1];}
//! \brief
//! \~english Last element.
//! \~russian Первый элемент массива.
//! \~\details
@@ -791,7 +772,6 @@ public:
inline T & front() {return piv_data[0];}
inline const T & front() const {return piv_data[0];}
//! \brief
//! \~english Compare operator with array `v`.
//! \~russian Оператор сравнения с массивом `v`.
inline bool operator ==(const PIVector<T> & v) const {
@@ -802,12 +782,10 @@ public:
return true;
}
//! \brief
//! \~english Compare operator with array `v`.
//! \~russian Оператор сравнения с массивом `v`.
inline bool operator !=(const PIVector<T> & v) const {return !(*this == v);}
//! \~\brief
//! \~english Tests if element `e` exists in the array.
//! \~russian Проверяет наличие элемента `e` в массиве.
//! \~\details
@@ -839,7 +817,7 @@ public:
//! otherwise it returns **false**.
//! \~russian **true** если элемент `e` присутствует в массиве,
//! в остальных случаях **false**.
//! \~\sa \a every(), \a any(), \a etries(), \a forEach()
//! \~\sa \a every(), \a any(), \a entries(), \a forEach()
inline bool contains(const T & e, ssize_t start = 0) const {
if (start < 0) {
start = piv_size + start;
@@ -851,7 +829,6 @@ public:
return false;
}
//! \~\brief
//! \~english Count elements equal `e` in the array.
//! \~russian Подсчитывает количество элементов, совпадающих с элементом `e` в массиве.
//! \~\details
@@ -889,7 +866,6 @@ public:
return ec;
}
//! \~\brief
//! \~english Count elements in the array passes the test implemented by the provided function `test`.
//! \~russian Подсчитывает количество элементов в массиве,
//! проходящих по условию, заданному в передаваемой функции `test`.
@@ -924,7 +900,6 @@ public:
return ec;
}
//! \~\brief
//! \~english Returns the first index at which a given element `e`
//! can be found in the array, or `-1` if it is not present.
//! \~russian Возвращает первый индекс, по которому данный элемент `e`
@@ -965,7 +940,6 @@ public:
return -1;
}
//! \~\brief
//! \~english Returns the first index passes the test implemented by the provided function `test`,
//! or `-1` if it is not present.
//! can be found in the array, or `-1` if it is not present.
@@ -1005,7 +979,6 @@ public:
return -1;
}
//! \~\brief
//! \~english Returns the last index at which a given element `e`
//! can be found in the array, or `-1` if it is not present.
//! \~russian Возвращает последний индекс, по которому данный элемент `e`
@@ -1049,7 +1022,6 @@ public:
return -1;
}
//! \~\brief
//! \~english Returns the last index passes the test implemented by the provided function `test`,
//! or `-1` if it is not present.
//! \~russian Возвращает последний индекс элемента проходящего по условию,
@@ -1084,7 +1056,6 @@ public:
return -1;
}
//! \~\brief
//! \~english Pointer to array
//! \~russian Указатель на память массива
//! \~\details
@@ -1100,7 +1071,6 @@ public:
//! \endcode
inline T * data(size_t index = 0) {return &(piv_data[index]);}
//! \~\brief
//! \~english Read only pointer to array
//! \~russian Указатель на память массива только для чтения.
//! \~\details
@@ -1120,7 +1090,6 @@ public:
//! \endcode
inline const T * data(size_t index = 0) const {return &(piv_data[index]);}
//! \~\brief
//! \~english Creates sub-array of this array.
//! \~russian Создает подмассив, то есть кусок из текущего массива.
//! \~english
@@ -1143,7 +1112,6 @@ public:
return PIVector(&(piv_data[index]), count);
}
//! \~\brief
//! \~english Clear array, remove all elements.
//! \~russian Очищает массив, удаляет все элементы.
//! \~\details
@@ -1167,7 +1135,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Assigns element 'e' to all items in the array.
//! \~russian Заполняет весь массив копиями элемента 'e'.
//! \~\details
@@ -1186,7 +1153,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Assigns result of function 'f(size_t i)' to all items in the array.
//! \~russian Заполняет весь массив результатом вызова функции 'f(size_t i)'.
//! \~\details
@@ -1205,13 +1171,11 @@ public:
return *this;
}
//! \~\brief
//! \~english Same as \a fill().
//! \~russian Тоже самое что и \a fill().
//! \~\sa \a fill(), \a resize()
inline PIVector<T> & assign(const T & e = T()) {return fill(e);}
//! \~\brief
//! \~english First does `resize(new_size)` then `fill(e)`.
//! \~russian Сначала делает `resize(new_size)`, затем `fill(e)`.
//! \~\sa \a fill(), \a resize()
@@ -1230,7 +1194,6 @@ public:
return fill(f);
}
//! \~\brief
//! \~english Sets size of the array, new elements are copied from `e`.
//! \~russian Устанавливает размер массива, новые элементы копируются из `e`.
//! \~\details
@@ -1259,7 +1222,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Sets size of the array, new elements created by function `f(size_t i)`.
//! \~russian Устанавливает размер массива, новые элементы создаются функцией `f(size_t i)`.
//! \~\details
@@ -1306,7 +1268,6 @@ public:
newT(dst, src, size);
}
//! \~\brief
//! \~english Attempts to allocate memory for at least `new_size` elements.
//! \~russian Резервируется память под как минимум `new_size` элементов.
//! \~\details
@@ -1329,7 +1290,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Inserts value `e` at `index` position in the array.
//! \~russian Вставляет значение `e` в позицию `index` в массиве.
//! \~\details
@@ -1352,7 +1312,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Inserts value `e` at `index` position in the array.
//! \~russian Вставляет значение `e` в позицию `index` в массиве.
//! \~\details
@@ -1370,7 +1329,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Inserts array `v` at `index` position in the array.
//! \~russian Вставляет массив `v` в позицию `index` в массиве.
//! \~\details
@@ -1394,7 +1352,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Inserts the given elements at `index` position in the array.
//! \~russian Вставляет элементы в позицию `index` в массиве.
//! \~\details
@@ -1415,7 +1372,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Removes `count` elements from the middle of the array, starting at `index` position.
//! \~russian Удаляет элементы из массива, начиная с позиции `index` в количестве `count`.
//! \~\details
@@ -1438,7 +1394,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Swaps array `v` other with this array.
//! \~russian Меняет местами массив `v` с этим массивом.
//! \~\details
@@ -1450,7 +1405,6 @@ public:
piSwap<size_t>(piv_rsize, v.piv_rsize);
}
//! \~\brief
//! \~english Sorts the elements in non-descending order.
//! \~russian Сортировка элементов в порядке возрастания.
//! \~\details
@@ -1473,7 +1427,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Sorts the elements in non-descending order.
//! \~russian Сортировка элементов в порядке возрастания.
//! \~\details
@@ -1512,7 +1465,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Reverses this array.
//! \~russian Обращает порядок следования элементов этого массива.
//! \~\details
@@ -1537,7 +1489,6 @@ public:
return *this;
}
//! \~\brief
//! \~english Returns reversed array.
//! \~russian Возвращает перевернутый массив.
//! \~\details
@@ -1551,7 +1502,6 @@ public:
return ret.reverse();
}
//! \~\brief
//! \~english Increases or decreases the size of the array by `add_size` elements.
//! \~russian Увеличивает или уменьшает размер массива на `add_size` элементов.
//! \~\details
@@ -1569,7 +1519,6 @@ public:
return *this;
}
//! \brief
//! \~english Remove no more than one element equal `e`.
//! \~russian Удаляет первый элемент, который равен элементу `e`.
//! \~\details
@@ -1589,7 +1538,6 @@ public:
return *this;
}
//! \brief
//! \~english Remove all elements equal `e`.
//! \~russian Удаляет все элементы, равные элементу `e`.
//! \~\details
@@ -1609,7 +1557,6 @@ public:
return *this;
}
//! \brief
//! \~english Remove all elements in the array
//! passes the test implemented by the provided function `test`.
//! \~russian Удаляет все элементы, удовлетворяющие условию,
@@ -1631,7 +1578,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
@@ -1663,7 +1609,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
@@ -1677,7 +1622,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given elements to the end of the array.
//! \~russian Добавляет элементы в конец массива.
//! \~\details
@@ -1695,7 +1639,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given array `v` to the end of the array.
//! \~russian Добавляет массив `v` в конец массива.
//! \~\details
@@ -1715,7 +1658,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
@@ -1743,7 +1685,6 @@ public:
//! \~\sa \a prepend(), \a push_front(), \a push_back(), \a insert()
inline PIVector<T> & append(const T & e) {return push_back(e);}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
@@ -1752,7 +1693,6 @@ public:
//! \~\sa \a append()
inline PIVector<T> & append(T && e) {return push_back(std::move(e));}
//! \brief
//! \~english Appends the given elements to the end of the array.
//! \~russian Добавляет элементы в конец массива.
//! \~\details
@@ -1765,7 +1705,6 @@ public:
//! \~\sa \a append()
inline PIVector<T> & append(std::initializer_list<T> init_list) {return push_back(init_list);}
//! \brief
//! \~english Appends the given array `v` to the end of the array.
//! \~russian Добавляет массив `v` в конец массива.
//! \~\details
@@ -1779,7 +1718,6 @@ public:
//! \~\sa \a append()
inline PIVector<T> & append(const PIVector<T> & v) {return push_back(v);}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
@@ -1791,7 +1729,6 @@ public:
//! \~\sa \a append()
inline PIVector<T> & operator <<(const T & e) {return push_back(e);}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
@@ -1803,7 +1740,6 @@ public:
//! \~\sa \a append()
inline PIVector<T> & operator <<(T && e) {return push_back(std::move(e));}
//! \brief
//! \~english Appends the given array `v` to the end of the array.
//! \~russian Добавляет массив `v` в конец массива.
//! \~\details
@@ -1815,7 +1751,6 @@ public:
//! \~\sa \a append()
inline PIVector<T> & operator <<(const PIVector<T> & v) {return push_back(v);}
//! \brief
//! \~english Appends the given element `e` to the begin of the array.
//! \~russian Добавляет элемент `e` в начало массива.
//! \~\details
@@ -1837,7 +1772,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given element `e` to the begin of the array.
//! \~russian Добавляет элемент `e` в начало массива.
//! \~\details
@@ -1849,7 +1783,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given array `v` to the begin of the array.
//! \~russian Добавляет массив `v` в начало массива.
//! \~\details
@@ -1866,7 +1799,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given elements to the begin of the array.
//! \~russian Добавляет элементы в начало массива.
//! \~\details
@@ -1882,7 +1814,6 @@ public:
return *this;
}
//! \brief
//! \~english Appends the given element `e` to the begin of the array.
//! \~russian Добавляет элемент `e` в начало массива.
//! \~\details
@@ -1901,7 +1832,6 @@ public:
//! \~\sa \a append(), \a push_back(), \a push_front(), \a insert()
inline PIVector<T> & prepend(const T & e) {return push_front(e);}
//! \brief
//! \~english Appends the given element `e` to the begin of the array.
//! \~russian Добавляет элемент `e` в начало массива.
//! \~\details
@@ -1910,7 +1840,6 @@ public:
//! \~\sa \a prepend()
inline PIVector<T> & prepend(T && e) {return push_front(std::move(e));}
//! \brief
//! \~english Appends the given array `v` to the begin of the array.
//! \~russian Добавляет массив `v` в начало массива.
//! \~\details
@@ -1924,7 +1853,6 @@ public:
//! \~\sa \a prepend()
inline PIVector<T> & prepend(const PIVector<T> & v) {return push_front(v);}
//! \brief
//! \~english Appends the given elements to the begin of the array.
//! \~russian Добавляет элементы в начало массива.
//! \~\details
@@ -1937,7 +1865,6 @@ public:
//! \~\sa \a append()
inline PIVector<T> & prepend(std::initializer_list<T> init_list) {return prepend(init_list);}
//! \brief
//! \~english Remove one element from the end of the array.
//! \~russian Удаляет один элемент с конца массива.
//! \~\details
@@ -1957,7 +1884,6 @@ public:
return *this;
}
//! \brief
//! \~english Remove one element from the begining of the array.
//! \~russian Удаляет один элемент с начала массива.
//! \~\details
@@ -1979,7 +1905,6 @@ public:
return *this;
}
//! \brief
//! \~english Remove one element from the end of the array and return it.
//! \~russian Удаляет один элемент с начала массива и возвращает его.
//! \~\details
@@ -1995,7 +1920,6 @@ public:
return e;
}
//! \brief
//! \~english Remove one element from the begining of the array and return it.
//! \~russian Удаляет один элемент с конца массива и возвращает его.
//! \~\details
@@ -2011,7 +1935,6 @@ public:
return e;
}
//! \brief
//! \~english Returns an array converted to another type.
//! \~russian Возвращает конвертированный в другой тип массив.
//! \~\details
@@ -2030,7 +1953,6 @@ public:
return ret;
}
//! \brief
//! \~english Returns a new array with all elements
//! that pass the test implemented by the provided function `test`.
//! \~russian Возвращает новый массив со всеми элементами,
@@ -2050,7 +1972,6 @@ public:
return ret;
}
//! \brief
//! \~english Execute function `void f(const T & e)` for every element in array.
//! \~russian Выполняет функцию `void f(const T & e)` для каждого элемента массива.
//! \~\details
@@ -2071,7 +1992,6 @@ public:
}
}
//! \brief
//! \~english Execute function `void f(T & e)` for every element in array.
//! \~russian Выполняет функцию `void f(T & e)` для каждого элемента массива.
//! \~\details
@@ -2092,7 +2012,6 @@ public:
return *this;
}
//! \brief
//! \~english Сreates a new array populated with the results
//! of calling a provided function `ST f(const T & e)` on every element in the calling array.
//! \~russian Создаёт новый массив с результатом вызова указанной функции
@@ -2119,7 +2038,6 @@ public:
return ret;
}
//! \brief
//! \~english Applies the function `ST f(const T & e, const ST & acc)`
//! to each element of the array (from left to right), returns one value.
//! \~russian Применяет функцию `ST f(const T & e, const ST & acc)`
@@ -2170,7 +2088,6 @@ public:
return ret;
}
//! \brief
//! \~english Changes the dimension of the array, creates a two-dimensional array from a one-dimensional array.
//! \~russian Изменяет размерность массива, из одномерного массива создает двухмерный.
//! \~\details
@@ -2216,7 +2133,6 @@ public:
return ret;
}
//! \brief
//! \~english Changes the dimension of the array, creates a one-dimensional array from a two-dimensional array.
//! \~russian Изменяет размерность массива, из двухмерный массива создает одномерный.
//! \~\details
@@ -2256,7 +2172,6 @@ public:
return ret;
}
//! \brief
//! \~english Changes the dimension of the two-dimensional array.
//! \~russian Изменяет размерность двухмерного массива.
//! \~\details
@@ -2290,8 +2205,9 @@ private:
if (piv_rsize + piv_rsize >= s && piv_rsize < s) {
return piv_rsize + piv_rsize;
}
ssize_t t = 0, s_ = s - 1;
while (s_ >> t) ++t;
ssize_t t = _PIContainerConstants<T>::minCountPoT(), s_ = s - 1;
while (s_ >> t)
++t;
return (1 << t);
}
template<typename T1 = T, typename std::enable_if<

View File

@@ -246,6 +246,10 @@
extern char ** environ;
#endif
#ifndef NO_UNUSED
# define NO_UNUSED(x) (void)x
#endif
#ifndef assert
# define assert(x)
# define assertm(exp, msg)
@@ -387,12 +391,12 @@
//! \~\brief
//! \~english Macro used for infinite wait
//! \~russian Макрос для бесконечного ожидания
#define FOREVER_WAIT FOREVER piMinSleep;
#define FOREVER_WAIT FOREVER piMinSleep();
//! \~\brief
//! \~english Macro used for infinite wait
//! \~russian Макрос для бесконечного ожидания
#define WAIT_FOREVER FOREVER piMinSleep;
#define WAIT_FOREVER FOREVER piMinSleep();
//! \~\brief

View File

@@ -21,14 +21,7 @@
#include "pistringlist.h"
#include <iostream>
//! \addtogroup Core
//! \{
//! \class PIByteArray pibytearray.h
//!
//! \~\brief
//! \~english The %PIByteArray class provides an array of bytes
//! \~russian Класс %PIByteArray представляет собой массив байтов
//!
//! \~\details
//! \~english
//! %PIByteArray used to store raw bytes.
@@ -98,7 +91,6 @@
//! метов \a append().
//! \~\snippet pibytearray.cpp 3
//!
//! \}
static const uchar base64Table[64] = {

View File

@@ -36,6 +36,10 @@ class PIString;
class PIByteArray;
//! \ingroup Core
//! \~\brief
//! \~english The %PIByteArray class provides an array of bytes.
//! \~russian Класс %PIByteArray представляет собой массив байтов.
class PIP_EXPORT PIByteArray: public PIDeque<uchar>
{
public:
@@ -268,8 +272,8 @@ inline PIByteArray::StreamRef operator <<(PIByteArray & s, const T & v) {
PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v);
//! \relatesalso PIByteArray
//! \~english Store operator, see \ref PIByteArray_sec1 for details
//! \~russian Оператор сохранения, подробнее в \ref PIByteArray_sec1
//! \~english Store operator
//! \~russian Оператор сохранения
inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v) {
int os = s.size_s();
if (v.s > 0) {
@@ -402,8 +406,8 @@ inline PIByteArray::StreamRef operator >>(PIByteArray & s, T & v) {
PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIByteArray & v);
//! \relatesalso PIByteArray
//! \~english Restore operator, see \ref PIByteArray_sec1 for details
//! \~russian Оператор извлечения, подробнее в \ref PIByteArray_sec1
//! \~english Restore operator
//! \~russian Оператор извлечения
inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) {
if (s.size_s() < v.s) {
printf("error with RawData %d < %d\n", (int)s.size_s(), v.s);
@@ -626,9 +630,9 @@ inline PIByteArray & operator >>(PIByteArray & s, PIVector2D<T> & v) {
//! \~russian Оператор сохранения
template <typename Key, typename T>
inline PIByteArray & operator <<(PIByteArray & s, const PIMap<Key, T> & v) {
s << int(v.pim_index.size_s());
for (uint i = 0; i < v.size(); ++i)
s << int(v.pim_index[i].index) << v.pim_index[i].key;
// s << int(v.pim_index.size_s());
// for (uint i = 0; i < v.size(); ++i)
// s << int(v.pim_index[i].index) << v.pim_index[i].key;
s << v.pim_content;
return s;
}
@@ -643,17 +647,17 @@ inline PIByteArray & operator >>(PIByteArray & s, PIMap<Key, T> & v) {
printf("error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
assert(s.size_s() >= 4);
}
int sz; s >> sz; v.pim_index.resize(sz);
int ind = 0;
for (int i = 0; i < sz; ++i) {
s >> ind >> v.pim_index[i].key;
v.pim_index[i].index = ind;
}
// int sz; s >> sz; v.pim_index.resize(sz);
// int ind = 0;
// for (int i = 0; i < sz; ++i) {
// s >> ind >> v.pim_index[i].key;
// v.pim_index[i].index = ind;
// }
s >> v.pim_content;
if (v.pim_content.size_s() != v.pim_index.size_s()) {
piCout << "Warning: loaded invalid PIMap, clear";
v.clear();
}
// if (v.pim_content.size_s() != v.pim_index.size_s()) {
// piCout << "Warning: loaded invalid PIMap, clear";
// v.clear();
// }
return s;
}

View File

@@ -18,7 +18,7 @@
*/
#include "piincludes_p.h"
#include "pibytearray.h"
#include "pistring.h"
#ifdef PIP_ICU
# define U_NOEXCEPT
# include "unicode/ucnv.h"
@@ -35,21 +35,8 @@ char * __utf8name__ = 0;
# include <ctype.h>
#endif
#include <wchar.h>
#ifdef ANDROID
# if __ANDROID_API__ < 21
# define wctomb(s, wc) wcrtomb(s, wc, NULL)
# define mbtowc(pwc, s, n) mbrtowc(pwc, s, n, NULL)
# endif
#endif
//! \addtogroup Core
//! \{
//! \class PIChar pichar.h
//!
//! \~\brief
//! \~english %PIChar represents a single character
//! \~russian %PIChar представляет собой один символ строки
//!
//! \~\details
//! \~english
//! This class is wrapper around UTF16.
@@ -59,7 +46,6 @@ char * __utf8name__ = 0;
//! %PIChar хранит один сивол в UTF16. Имеет много контрукторов, геттеров в различные
//! кодировки (системную, консольную, UTF8) и информационных функций.
//!
//! \}
ushort charFromCodepage(const char * c, int size, const char * codepage, int * taken = 0) {
@@ -86,10 +72,12 @@ ushort charFromCodepage(const char * c, int size, const char * codepage, int * t
if (taken) *taken = ret;
return buffer;
# else
wchar_t wc(0);
mbtowc(0, 0, 0); // reset mbtowc
ret = mbtowc(&wc, c, size);
mbstate_t state;
memset(&state, 0, sizeof(state));
wchar_t wc;
ret = mbrtowc(&wc, c, size, &state);
//printf("mbtowc = %d\n", ret);
//piCout << errorString();
if (ret < 1) return 0;
return ushort(wc);
# endif
@@ -389,13 +377,7 @@ PICout operator <<(PICout s, const PIChar & v) {
#ifdef WINDOWS
s << v.toSystem();
#else
{
char tc[8];
wctomb(0, 0);
int sz = wctomb(tc, v.ch);
for (int b = 0; b < sz; ++b)
s << tc[b];
}
s << PIString(v);
#endif
}
s.restoreControl();

View File

@@ -32,6 +32,10 @@ extern PIP_EXPORT char * __syslocname__;
extern PIP_EXPORT char * __sysoemname__;
extern PIP_EXPORT char * __utf8name__;
//! \ingroup Core
//! \~\brief
//! \~english %PIChar represents a single character.
//! \~russian %PIChar представляет собой один символ строки.
class PIP_EXPORT PIChar
{
friend class PIString;
@@ -61,6 +65,10 @@ public:
//! \~russian Оператор присваивания
PIChar & operator =(const char v) {ch = v; return *this;}
//! \~english Copy operator
//! \~russian Оператор присваивания
PIChar & operator =(const wchar_t v) {ch = v; return *this;}
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator ==(const PIChar & o) const;

View File

@@ -19,13 +19,8 @@
#include "pichunkstream.h"
//! \addtogroup Core
//! \{
//! \class PIChunkStream pichunkstream.h
//! \brief
//! \~english Class for binary de/serialization
//! \~russian Класс для бинарной де/сериализации
//!
//! \details
//! \~english \section PIChunkStream_sec0 Synopsis
//! \~russian \section PIChunkStream_sec0 Краткий обзор
//! \~english
@@ -89,7 +84,6 @@
//! \~russian ... и десериализовать:
//! \~\snippet pichunkstream.cpp read_new
//!
//! \}
void PIChunkStream::setSource(const PIByteArray & data) {

View File

@@ -29,6 +29,10 @@
#include "pibytearray.h"
//! \ingroup Core
//! \~\brief
//! \~english Class for binary de/serialization.
//! \~russian Класс для бинарной де/сериализации.
class PIP_EXPORT PIChunkStream
{
public:

View File

@@ -21,13 +21,8 @@
#include "pisysteminfo.h"
//! \addtogroup Core
//! \{
//! \class PICLI picli.h
//! \~\brief
//! \~english Command-Line parser
//! \~russian Парсер командной строки
//!
//! \details
//! \~english \section PICLI_sec0 Synopsis
//! \~russian \section PICLI_sec0 Краткий обзор
//! \~english
@@ -43,7 +38,7 @@
//! а также получить их значения при помощи \a argumentValue().
//!
//! \~english \section PICLI_sec1 Example
//! \~russian \section PICLI_sec0 Пример
//! \~russian \section PICLI_sec1 Пример
//! \~\code
//! int main(int argc, char ** argv) {
//! PICLI cli(argc, argv);
@@ -66,12 +61,10 @@
//! a.out --debug -c --value 10
//! \endcode
//!
//! /}
PICLI::PICLI(int argc, char * argv[]) {
setName("CLI");
needParse = true;
needParse = debug_ = true;
_prefix_short = "-";
_prefix_full = "--";
_count_opt = 0;

View File

@@ -26,11 +26,15 @@
#ifndef PICLI_H
#define PICLI_H
#include "piobject.h"
#include "pistringlist.h"
#include "piset.h"
class PIP_EXPORT PICLI: public PIObject
//! \ingroup Core
//! \~\brief
//! \~english Command-Line parser.
//! \~russian Парсер командной строки.
class PIP_EXPORT PICLI
{
PIOBJECT_SUBCLASS(PICLI, PIObject)
public:
//! \~english Constructor
@@ -94,6 +98,11 @@ public:
void setMandatoryArgumentsCount(const int count) {_count_mand = count; needParse = true;}
void setOptionalArgumentsCount(const int count) {_count_opt = count; needParse = true;}
bool debug() const {return debug_;}
void setDebug(bool debug) {debug_ = debug;}
PIConstChars className() const {return "PICLI";}
PIString name() const {return PIStringAscii("CLI");}
private:
struct Argument {
Argument() {has_value = found = false;}
@@ -112,7 +121,7 @@ private:
PISet<PIString> keys_full, keys_short;
PIVector<Argument> _args;
int _count_mand, _count_opt;
bool needParse;
bool needParse, debug_;
};

View File

@@ -20,13 +20,7 @@
#include "picollection.h"
//! \addtogroup Core
//! \{
//! \~\class PICollection picollection.h
//! \~\brief
//! \~english Helper to collect and retrieve classes to groups
//! \~russian Помощник для создания и получения классов в группы
//!
//! \~\details
//! \~english \section PICollection_sec0 Synopsis
//! \~russian \section PICollection_sec0 Краткий обзор
@@ -41,7 +35,6 @@
//! объектов в глобальные группы. Затем можно получить их список в любом месте программы.
//! \~\snippet picollection.cpp main
//!
//! \}
PIStringList PICollection::groups() {

View File

@@ -100,6 +100,10 @@
#endif
//! \ingroup Core
//! \~\brief
//! \~english Helper to collect and retrieve classes to groups.
//! \~russian Помощник для создания и получения классов в группы.
class PIP_EXPORT PICollection
{
friend class __PICollectionInitializer;

View File

@@ -0,0 +1,164 @@
/*
PIP - Platform Independent Primitives
C-String class
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piconstchars.h"
#include "pistring.h"
//! \~\class PIConstChars piconstchars.h
//! \~\details
//! \~english \section PIConstChars_sec0 Synopsis
//! \~russian \section PIConstChars_sec0 Краткий обзор
//! \~english
//! This is wrapper around \c const char * string. %PIConstChars doesn`t
//! copy string, just save pointer and size.
//!
//! Provides API similar to string, with information and compare methods.
//!
//! Used to more handly works with ordinary C-strings.
//!
//! \~russian
//! Это обертка вокруг \c const char * строки. %PIConstChars не скопирует
//! строку, а хранит только указатель и размер.
//!
//! Предоставляет API схожий с обычной строкой, с методами сравнения и информационными.
//!
//! Используется для более удобной работы с обычными C-строками.
//!
bool PIConstChars::startsWith(const PIConstChars & str) const {
if (size() < str.size()) return false;
return str == left(str.size());
}
bool PIConstChars::startsWith(const char c) const {
if (size() < 1) return false;
return str[0] == c;
}
bool PIConstChars::endsWith(const PIConstChars & str) const {
if (size() < str.size()) return false;
return str == right(str.size());
}
bool PIConstChars::endsWith(const char c) const {
if (size() < 1) return false;
return str[len - 1] == c;
}
PIConstChars PIConstChars::mid(const int start, const int len) const {
int s = start, l = len;
if (l == 0 || s >= (int)size() || isEmpty()) return PIConstChars("");
if (s < 0) {
l += s;
s = 0;
}
if (l < 0) {
return PIConstChars(str + s, (int)size() - s);
} else {
if (l > (int)size() - s)
l = (int)size() - s;
return PIConstChars(str + s, l);
}
return PIConstChars("");
}
PIConstChars PIConstChars::left(const int l) const {
if (l <= 0) return PIConstChars("");
return mid(0, l);
}
PIConstChars PIConstChars::right(const int l) const {
if (l <= 0) return PIConstChars("");
return mid((int)size() - l, l);
}
PIConstChars & PIConstChars::cutLeft(const int l) {
if (l <= 0) return *this;
if (l >= (int)size())
*this = PIConstChars("");
else {
str += l;
len -= l;
}
return *this;
}
PIConstChars & PIConstChars::cutRight(const int l) {
if (l <= 0) return *this;
if (l >= (int)size())
*this = PIConstChars("");
else {
len -= l;
}
return *this;
}
PIConstChars PIConstChars::takeLeft(const int len) {
PIConstChars ret(left(len));
cutLeft(len);
return ret;
}
PIConstChars PIConstChars::takeRight(const int len) {
PIConstChars ret(right(len));
cutRight(len);
return ret;
}
PIConstChars & PIConstChars::trim() {
if (isEmpty()) return *this;
int st = -1, fn = 0;
for (int i = 0; i < (int)len; ++i) {
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12) && at(i) != uchar(0)) {
st = i;
break;
}
}
if (st < 0) {
*this = PIConstChars("");
return *this;
}
for (int i = (int)len - 1; i >= 0; --i) {
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12) && at(i) != uchar(0)) {
fn = i;
break;
}
}
if (fn < (int)len - 1) cutRight((int)len - fn - 1);
if (st > 0) cutLeft(st);
return *this;
}
PIString PIConstChars::toString() const {
if (isEmpty()) return PIString();
return PIString::fromAscii(str, len);
}

View File

@@ -0,0 +1,262 @@
/*! \file piconstchars.h
* \ingroup Core
* \brief
* \~english C-String class
* \~russian Класс C-строки
*/
/*
PIP - Platform Independent Primitives
C-String class
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/>.
*/
#ifndef PICONSTCHARS_H
#define PICONSTCHARS_H
#include "picout.h"
//! \ingroup Core
//! \~\brief
//! \~english C-String class.
//! \~russian Класс C-строки.
class PIP_EXPORT PIConstChars {
public:
//! \~english Contructs an null string.
//! \~russian Создает нулевую строку.
PIConstChars() {}
//! \~english Contructs string from C-string "string".
//! \~russian Создает строку из C-строки "string".
PIConstChars(const char * string) {
str = string;
len = strlen(string);
}
//! \~english Contructs string from "size" characters of buffer "data".
//! \~russian Создает строку из "size" символов массива "data".
PIConstChars(const char * data, size_t size) {
str = data;
len = size;
}
//! \~english Contructs a copy of string.
//! \~russian Создает копию строки.
PIConstChars(const PIConstChars & o) {
str = o.str;
len = o.len;
}
//! \~english Read-only access to character by `index`.
//! \~russian Доступ на чтение к символу по индексу `index`.
inline char operator [](size_t index) const {return str[index];}
//! \~english Read-only access to character by `index`.
//! \~russian Доступ на чтение к символу по индексу `index`.
inline char at(size_t index) const {return str[index];}
//! \~english Returns \c char * string pointer.
//! \~russian Возвращает \c char * указатель строки.
inline const char * data() const {return str;}
//! \~english Returns \c true if string doesn`t have any data.
//! \~russian Возвращает \c true если строка не имеет данных.
inline bool isNull() const {return !str;}
//! \~english Returns \c true if string is empty, i.e. length = 0, or null.
//! \~russian Возвращает \c true если строка пустая, т.е. длина = 0, или нулевая.
inline bool isEmpty() const {return len == 0;}
//! \~english Returns \c true if string is not empty, i.e. length > 0.
//! \~russian Возвращает \c true если строка непустая, т.е. длина > 0.
inline bool isNotEmpty() const {return len > 0;}
//! \~english Returns characters length of string.
//! \~russian Возвращает длину строки в символах.
inline size_t length() const {return len;}
//! \~english Returns characters length of string.
//! \~russian Возвращает длину строки в символах.
inline size_t size() const {return len;}
//! \~english Returns characters length of string.
//! \~russian Возвращает длину строки в символах.
inline ssize_t size_s() const {return len;}
//! \~english Returns if string starts with "str".
//! \~russian Возвращает начинается ли строка со "str".
bool startsWith(const PIConstChars & str) const;
//! \~english Returns if string starts with "c".
//! \~russian Возвращает начинается ли строка с "c".
bool startsWith(const char c) const;
//! \~english Returns if string ends with "str".
//! \~russian Возвращает оканчивается ли строка на "str".
bool endsWith(const PIConstChars & str) const;
//! \~english Returns if string ends with "c".
//! \~russian Возвращает оканчивается ли строка "c".
bool endsWith(const char c) const;
//! \~english Returns part of string from character at index "start" and maximum length "len".
//! \~russian Возвращает подстроку от символа "start" и максимальной длиной "len".
//! \~\sa \a left(), \a right()
PIConstChars mid(const int start, const int len = -1) const;
//! \~english Returns part of string from start and maximum length "len".
//! \~russian Возвращает подстроку от начала и максимальной длиной "len".
//! \~\sa \a mid(), \a right()
PIConstChars left(const int len) const;
//! \~english Returns part of string at end and maximum length "len".
//! \~russian Возвращает подстроку максимальной длиной "len" и до конца.
//! \~\sa \a mid(), \a left()
PIConstChars right(const int len) const;
//! \~english Remove part of string from start and maximum length "len" and return this string.
//! \~russian Удаляет часть строки от начала и максимальной длины "len", возвращает эту строку.
//! \~\sa \a cutRight()
PIConstChars & cutLeft(const int len);
//! \~english Remove part of string at end and maximum length "len" and return this string.
//! \~russian Удаляет часть строки максимальной длины "len" от конца, возвращает эту строку.
//! \~\sa \a cutLeft()
PIConstChars & cutRight(const int len);
//! \~english Take a part from the begin of string with maximum length "len" and return it.
//! \~russian Извлекает часть строки от начала максимальной длины "len" и возвращает её.
//! \~\sa \a takeRight()
PIConstChars takeLeft(const int len);
//! \~english Take a part from the end of string with maximum length "len" and return it.
//! \~russian Извлекает часть строки с конца максимальной длины "len" и возвращает её.
//! \~\sa \a takeLeft()
PIConstChars takeRight(const int len);
//! \~english Remove spaces at the start and at the end of string and return this string.
//! \~russian Удаляет пробельные символы с начала и конца строки и возвращает эту строку.
//! \~\sa \a trimmed()
PIConstChars & trim();
//! \~english Returns copy of this string without spaces at the start and at the end.
//! \~russian Возвращает копию этой строки без пробельных символов с начала и конца.
//! \~\sa \a trim()
PIConstChars trimmed() const {return PIConstChars(*this).trim();}
//! \~english Returns as PIString.
//! \~russian Возвращает как PIString.
PIString toString() const;
//! \~english Assign operator.
//! \~russian Оператор присваивания.
inline PIConstChars & operator =(const PIConstChars & s) {
if (this == &s) return *this;
len = s.len;
str = s.str;
return *this;
}
//! \~english Assign move operator.
//! \~russian Оператор перемещающего присваивания.
inline PIConstChars & operator =(PIConstChars && s) {
swap(s);
return *this;
}
//! \~english Assign operator.
//! \~russian Оператор присваивания.
inline PIConstChars & operator =(const char * s) {
str = s;
len = strlen(s);
return *this;
}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
inline bool operator ==(const PIConstChars & s) const {
if (isNull() && s.isNull()) return true;
if (isNull() xor s.isNull()) return false;
if (size() != s.size()) return false;
return strcmp(str, s.str) == 0;
}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
inline bool operator !=(const PIConstChars & s) const {return !(*this == s);}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
inline bool operator <(const PIConstChars & s) const {
if ( isNull() && s.isNull()) return false;
if ( isNull() && !s.isNull()) return true ;
if (!isNull() && s.isNull()) return false;
if (size() == s.size())
return strcmp(str, s.str) < 0;
return size() < s.size();
}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
inline bool operator >(const PIConstChars & s) const {
if ( isNull() && s.isNull()) return false;
if ( isNull() && !s.isNull()) return false;
if (!isNull() && s.isNull()) return true ;
if (size() == s.size())
return strcmp(str, s.str) > 0;
return size() > s.size();
}
//! \~english Returns hash of string content.
//! \~russian Возвращает хэш содержимого строки.
inline uint hash() const {
if (isEmpty()) return 0;
return piHashData((const uchar *)str, len);
}
inline void swap(PIConstChars& v) {
piSwap<const char *>(str, v.str);
piSwap<size_t>(len, v.len);
}
private:
const char * str = nullptr;
size_t len = 0;
};
//! \relatesalso PICout
//! \~english Output operator to \a PICout.
//! \~russian Оператор вывода в \a PICout.
inline PICout operator <<(PICout s, const PIConstChars & v) {
s.space();
if (v.isNull())
s.write("(null)");
else {
s.quote();
s.write(v.data(), v.size());
s.quote();
}
return s;
}
template<> inline uint piHash(const PIConstChars & s) {return s.hash();}
#endif // PICONSTCHARS_H

View File

@@ -25,7 +25,7 @@
//! \~english \section cmake_module_Core Building with CMake
//! \~russian \section cmake_module_Core Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP)
//! \endcode

View File

@@ -22,6 +22,10 @@
#include "pistack.h"
#include "piobject.h"
#include "pistring_std.h"
#ifdef HAS_LOCALE
# include <locale>
# include <codecvt>
#endif
#ifdef WINDOWS
# include <windows.h>
# include <wingdi.h>
@@ -30,13 +34,8 @@
#endif
//! \addtogroup Core
//! \{
//! \~\class PICout picout.h
//! \~\brief
//! \~english Universal output to console class
//! \~russian Универсальный вывод в консоль
//!
//! \~\details
//! \~english \section PICout_sec0 Synopsis
//! \~russian \section PICout_sec0 Краткий обзор
//! \~english
@@ -75,7 +74,6 @@
//! \~russian \section PICout_ex1 Создание своего оператора вывода
//! \~\snippet picout.cpp own
//!
//! \}
//! \addtogroup Core
@@ -85,8 +83,8 @@
//! \~english Class for emit notifications of PICout
//! \~russian Класс для посылки событий от PICout
//!
//! \~english \section PICout_sec0 Synopsis
//! \~russian \section PICout_sec0 Краткий обзор
//! \~english \section PICoutNotifier_sec0 Synopsis
//! \~russian \section PICoutNotifier_sec0 Краткий обзор
//! \~english
//! This class used as PICout events emitter. When
//! PICout constructs with external PIString* buffer
@@ -333,7 +331,7 @@ PICout PICout::operator <<(const PIFlags<PICoutManipulators::PICoutFormat> & v)
if (!act_) return *this; \
space(); \
if (cnb_ == 10) PICOUTTOTARGET(v) \
else writePIString(PIString::fromNumber(v, cnb_)); \
else write(PIString::fromNumber(v, cnb_)); \
return *this; \
}
@@ -366,7 +364,7 @@ PICout PICout::operator <<(const float v) {if (!act_) return *this; space(); PIC
PICout PICout::operator <<(const double v) {if (!act_) return *this; space(); PICOUTTOTARGET(v) return *this;}
PICout PICout::operator <<(const void * v) {if (!act_) return *this; space(); PICOUTTOTARGET("0x") writePIString(PIString::fromNumber(ullong(v), 16)); return *this;}
PICout PICout::operator <<(const void * v) {if (!act_) return *this; space(); PICOUTTOTARGET("0x") write(PIString::fromNumber(ullong(v), 16)); return *this;}
PICout PICout::operator <<(const PIObject * v) {
if (!act_) return *this;
@@ -375,9 +373,9 @@ PICout PICout::operator <<(const PIObject * v) {
else {
PICOUTTOTARGET(v->className())
PICOUTTOTARGET("*(0x")
writePIString(PIString::fromNumber(ullong(v), 16));
write(PIString::fromNumber(ullong(v), 16));
PICOUTTOTARGET(", \"")
writePIString(v->name());
write(v->name());
PICOUTTOTARGET("\")")
}
return *this;
@@ -522,8 +520,14 @@ PICout & PICout::newLine() {
}
PICout & PICout::write(const char * str) {
if (!act_ || !str) return *this;
return write(str, strlen(str));
}
PICout & PICout::write(const char * str, int len) {
if (!act_) return *this;
if (!act_ || !str) return *this;
if (buffer_) {
buffer_->append(PIString(str, len));
} else {
@@ -534,20 +538,29 @@ PICout & PICout::write(const char * str, int len) {
}
PICout & PICout::writePIString(const PIString & s) {
PICout & PICout::write(const PIString & s) {
if (!act_) return *this;
if (buffer_) {
buffer_->append(s);
} else {
if (PICout::isOutputDeviceActive(PICout::StdOut)) {
for (const PIChar & c: s) std::wcout.put(c.toWChar());
}
if (PICout::isOutputDeviceActive(PICout::StdOut))
stdoutPIString(s);
if (PICout::isOutputDeviceActive(PICout::Buffer)) PICout::__string__().append(s);
}
return *this;
}
void PICout::stdoutPIString(const PIString & s) {
#ifdef HAS_LOCALE
std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> utf8conv;
std::cout << utf8conv.to_bytes((char16_t*)&(const_cast<PIString&>(s).front()), (char16_t*)&(const_cast<PIString&>(s).front()) + s.size());
#else
for (PIChar c: s) std::wcout.put(c.toWChar());
#endif
}
void PICout::init() {
#ifdef WINDOWS
if (__Private__::hOut == 0) {

View File

@@ -125,6 +125,10 @@ namespace PICoutManipulators {
//! \ingroup Core
//! \~\brief
//! \~english Universal output to console class.
//! \~russian Универсальный вывод в консоль.
class PIP_EXPORT PICout {
public:
@@ -283,13 +287,21 @@ public:
//! \~russian Условно добавляет новую строку
PICout & newLine();
//! \~english Write raw data
//! \~russian Пишет сырые символы
PICout & write(const char * str);
//! \~english Write raw data
//! \~russian Пишет сырые символы
PICout & write(const char * str, int len);
//! \~english Write raw \a PIString
//! \~russian Пишет сырой \a PIString
PICout & writePIString(const PIString & s);
PICout & write(const PIString & s);
//! \~english Output \a PIString to stdout
//! \~russian Вывод \a PIString в stdout
static void stdoutPIString(const PIString & s);
//! \~english Set output device to \a PICout::Buffer and if "clear" clear it
//! \~russian Устанавливает устройство вывода на \a PICout::Buffer и если "clear" то очищает его

View File

@@ -35,20 +35,12 @@
//! \addtogroup Core
//! \{
//!
//! \~\class PITime pidatetime.h
//! \brief
//! \~english Calendar time
//! \~russian Календарное время
//!
//! \~\class PIDate pidatetime.h
//! \brief
//! \~english Calendar date
//! \~russian Календарная дата
//!
//! \~\class PIDateTime pidatetime.h
//! \brief
//! \~english Calendar date and time
//! \~russian Календарное дата и время
//!
//! \}

View File

@@ -30,6 +30,10 @@
#include "pisystemtime.h"
//! \ingroup Core
//! \~\brief
//! \~english Calendar time.
//! \~russian Календарное время.
class PIP_EXPORT PITime {
public:
//! \~english Construct %PITime from hours, minutes, seconds and milliseconds
@@ -102,6 +106,10 @@ PIP_EXPORT PICout operator <<(PICout s, const PITime & v);
//! \ingroup Core
//! \~\brief
//! \~english Calendar date.
//! \~russian Календарная дата.
class PIP_EXPORT PIDate {
public:
//! \~english Construct %PIDate from year, month and day
@@ -162,6 +170,10 @@ PIP_EXPORT PICout operator <<(PICout s, const PIDate & v);
//! \ingroup Core
//! \~\brief
//! \~english Calendar date and time.
//! \~russian Календарное дата и время.
class PIP_EXPORT PIDateTime {
public:
//! \~english Construct null %PIDateTime

View File

@@ -64,10 +64,16 @@ void errorClear() {
PIString errorString() {
#ifdef WINDOWS
char * msg;
char * msg = nullptr;
int err = GetLastError();
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL);
return "code " + PIString::fromNumber(err) + " - " + PIString(msg);
PIString ret = PIStringAscii("code ") + PIString::fromNumber(err) + PIStringAscii(" - ");
if (msg) {
ret += PIString::fromSystem(msg).trim();
LocalFree(msg);
} else
ret += '?';
return ret;
#else
int e = errno;
return PIString("code ") + PIString::fromNumber(e) + " - " + PIString(strerror(e));
@@ -88,237 +94,3 @@ void randomize() {
int randomi() {
return rand();
}
/*! \~english \mainpage What is PIP
* \~russian \mainpage Что такое PIP
*
* \~english
* PIP - Platform-Independent Primitives - is crossplatform library for C++ developers.
* It is wrap around STL and pure C++. This library can help developers write non-GUI
* projects much more quickly, efficiently and customizable than on pure C++.
* Library contains many classes, some of them are pure abstract, some classes
* can be used as they are, some classes should be inherited to new classes.
* PIP provide classes:
* * direct output to console (\a PICout)
* * containers (\a PIVector, \a PIList, \a PIMap, \a PIStack)
* * byte array (\a PIByteArray)
* * string (\a PIString, \a PIStringList)
* * base object (events and handlers) (\a PIObject)
* * multithreading
* * thread (\a PIThread)
* * executor (\a PIThreadPoolExecutor)
* * blocking dequeue (\a PIBlockingDequeue)
* * timer (\a PITimer)
* * tiling console (with widgets) (\a PIScreen)
* * simple text rows
* * scroll bar
* * list
* * button
* * buttons group
* * check box
* * progress bar
* * PICout output
* * text input
* * I/O devices
* * base class (\a PIIODevice)
* * file (\a PIFile)
* * serial port (\a PISerial)
* * ethernet (\a PIEthernet)
* * USB (\a PIUSB)
* * packets extractor (\a PIPacketExtractor)
* * binary log (\a PIBinaryLog)
* * complex I/O point (\a PIConnection)
* * Run-time libraries
* * abstract (\a PILibrary)
* * plugin (\a PIPluginLoader)
* * connection quality diagnotic (\a PIDiagnostics)
* * command-line arguments parser (\a PICLI)
* * math evaluator (\a PIEvaluator)
* * peering net node (\a PIPeer)
* * process (\a PIProcess)
* * state machine (\a PIStateMachine)
* \n \n Basic using of PIP described at page \ref using_basic
*
* \~russian
* PIP - Platform-Independent Primitives - кроссплатформенная библиотека для разработчиков на C++.
* It is wrap around STL and pure C++. This library can help developers write non-GUI
* projects much more quickly, efficiently and customizable than on pure C++.
* PIP предоставляет следующие классы:
* * общение с консолью (\a PICout)
* * контейнеры (\a PIVector, \a PIList, \a PIMap, \a PIStack)
* * байтовый массив (\a PIByteArray)
* * строка (\a PIString, \a PIStringList)
* * базовый объект (события и обработчики) (\a PIObject)
* * многопоточность
* * поток (\a PIThread)
* * исполнитель (\a PIThreadPoolExecutor)
* * блокирующая очередь (\a PIBlockingDequeue)
* * таймер (\a PITimer)
* * тайлинговая консоль (с виджетами) (\a PIScreen)
* * простой вывод строк
* * скроллбар
* * лист
* * кнопка
* * группа кнопок
* * галочка
* * прогрессбар
* * вывод PICout
* * текстовый ввод
* * устройства ввода/вывода
* * базовый класс (\a PIIODevice)
* * файл (\a PIFile)
* * последовательный порт (\a PISerial)
* * ethernet (\a PIEthernet)
* * USB (\a PIUSB)
* * packets extractor (\a PIPacketExtractor)
* * бинарный логфайл (\a PIBinaryLog)
* * сложное составное устройство (\a PIConnection)
* * поддержка библиотек времени выполнения
* * базовая функциональность (\a PILibrary)
* * плагин (\a PIPluginLoader)
* * диагностика качества связи (\a PIDiagnostics)
* * парсер аргументов командной строки (\a PICLI)
* * вычислитель (\a PIEvaluator)
* * пиринговая сеть (\a PIPeer)
* * процесс (\a PIProcess)
* * машина состояний (\a PIStateMachine)
* \n \n Базовое использование PIP описано на странице \ref using_basic
*/
/*! \~english \page using_basic Getting started
* \~russian \page using_basic Простые начала
*
* \~english
* Many novice programmers are solved many common task with system integrity: output to console,
* keyboard buttons press detecting, working with serial ports, ethernet or files, and many other.
* These tasks can solve this library, and code, based only on PIP will be compile and work
* similar on many systems: Windows, any Linux, Red Hat, FreeBSD, MacOS X and QNX.
* Typical application on PIP looks like this: \n
*
* \~russian
* Многие начинающие программисты решают общие задачи взаимодействия с операционной системой:
* вывод в консоль, определение нажатия клавиш, работа с последовательными портами, сетью или файлами,
* и многое другое. Эти задачи решены в библиотеке, и код, основанный на PIP будет компилироваться
* и работать одинаково на многих системах: Windows, любой Linux, Red Hat, FreeBSD, MacOS X и QNX.
* Типовое приложение на PIP выглядит примерно так: \n
*
\code{.cpp}
#include <pip.h>
// declare key press handler
void key_event(char key, void * );
PIConsole console(false, key_event); // don`t start now, key handler is "key_event"
// some vars
int i = 2, j = 3;
// implicit key press handler
void key_event(char key, void * ) {
switch (key) {
case '-':
i--;
break;
case '+':
i++;
break;
case '(':
j--;
break;
case ')':
j++;
break;
};
};
class MainClass: public PITimer {
PIOBJECT(MainClass)
public:
MainClass() {}
protected:
void tick(void * data, int delimiter) {
piCout << "timer tick";
// timer tick
}
};
MainClass main_class;
int main(int argc, char * argv[]) {
// enabling auto-detection of exit button press, by default 'Q' (shift+q)
console.enableExitCapture();
// if we want to parse command-line arguments
PICLI cli(argc, argv);
cli.addArgument("console"); // "-c" or "--console"
cli.addArgument("debug"); // "-d" or "--debug"
// enabling or disabling global debug flag
piDebug = cli.hasArgument("debug");
// configure console
console.addTab("first tab", '1');
console.addString("PIP console", 1, PIConsole::Bold);
console.addVariable("int var (i)", &i, 1);
console.addVariable("int green var (j)", &j, 1, PIConsole::Green);
console.addString("'-' - i--", 2);
console.addString("'+' - i++", 2);
console.addString("'(' - j--", 2);
console.addString("')' - j++", 2);
console.addTab("second tab", '2');
console.addString("col 1", 1);
console.addString("col 2", 2);
console.addString("col 3", 3);
console.setTab("first tab");
// start output to console if "console" argument exists
if (cli.hasArgument("console"))
console.start();
// start main class, e.g. 40 Hz
main_class.start(25.);
// wait for 'Q' press, independently if console is started or not
console.waitForFinish();
return 0;
};
\endcode
*
* \~english
* This code demonstrates simple interactive configurable program, which can be started with console
* display or not, and with debug or not. \b MainClass is central class that also can be inherited from
* \a PIThread and reimplement \a run() function.
* \n Many PIP classes has events and event handlers, which can be connected one to another.
* Details you can see at \a PIObject reference page (\ref PIObject_sec0).
* \n To configure your program from file use \a PIConfig.
* \n If you want more information see \ref using_advanced
*
* \~russian
* Этот код демонстрирует простую конфигурируемую программу, которая может быть запущена с
* This code demonstrates simple interactive configurable program, which can be started with console
* display or not, and with debug or not. \b MainClass is central class that also can be inherited from
* \a PIThread and reimplement \a run() function.
* \n Many PIP classes has events and event handlers, which can be connected one to another.
* Details you can see at \a PIObject reference page (\ref PIObject_sec0).
* \n To configure your program from file use \a PIConfig.
*/
/*! \page using_advanced Advanced using
* Sorry, creativity crysis xD
*/
/*
* \~english
* \~russian
*/

View File

@@ -152,12 +152,16 @@ PIInit::PIInit() {
}
# endif //WINDOWS
# ifdef HAS_LOCALE
//cout << "has locale" << endl;
//std::cout << "has locale" << std::endl;
if (currentLocale_t != 0) {
freelocale(currentLocale_t);
currentLocale_t = 0;
}
currentLocale_t = newlocale(LC_ALL, setlocale(LC_ALL, ""), 0);
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");
@@ -212,9 +216,6 @@ PIInit::PIInit() {
if (gethostname(cbuff, 1023) == 0) {
sinfo->hostname = cbuff;
}
// std::ios_base::sync_with_stdio(false);
// std::locale utf8( std::locale(), new std::codecvt_utf8<wchar_t> );
// std::wcout.imbue(utf8);
#ifdef WINDOWS
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);

View File

@@ -26,13 +26,7 @@
#endif
//! \addtogroup Core
//! \{
//! \~\class PIObject piobject.h
//! \~\brief
//! \~english This is base class for any classes which use events -> handlers mechanism
//! \~russian Этот класс является базовым для использования механизма события -> обработчики
//!
//! \~\details
//! \~english \section PIObject_sec0 Events and Event handlers
//! \~russian \section PIObject_sec0 События и Обработчики событий
@@ -98,16 +92,12 @@
//! handler A: event to event
//! event to lambda
//! \endcode
//! \}
//!
//! \addtogroup Core
//! \{
//! \~\class PIObject::Connection piobject.h
//! \~\brief
//! \~english Helper class for obtain info about if connection successful and disconnect single connection
//! \~russian Вспомогательный класс для получения информации об успешности соединения и возможности его разрыва
//! \}
//! \~\details
//!
PIObject::__MetaFunc::__MetaFunc() {
@@ -206,15 +196,6 @@ PIObject::~PIObject() {
}
PIMap<PIString, PIVariant> PIObject::properties() const {
PIMap<PIString, PIVariant> ret;
piForeachC (PropertyHash p, properties_)
ret[p.second.first] = p.second.second;
return ret;
}
bool PIObject::execute(const PIString & method, const PIVector<PIVariantSimple> & vl) {
@@ -259,7 +240,7 @@ PIStringList PIObject::scopeList() const {
PIMutexLocker ml(__meta_mutex());
const PIVector<const char *> & scope(__meta_data()[classNameID()].scope_list);
for (const char * c: scope)
ret = PIStringAscii(c);
ret << PIStringAscii(c);
return ret;
}
@@ -693,9 +674,12 @@ void PIObject::dump(const PIString & line_prefix) const {
PICout(PICoutManipulators::AddNewLine) << line_prefix << " properties {";
PICout(PICoutManipulators::AddNewLine) << line_prefix << " count: " << properties_.size_s();
//printf("dump %d properties\n", properties_.size());
piForeachC (PropertyHash p, properties_)
if (p.first != PIString("name").hash())
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << p.second.first << ": " << p.second.second;
const char * o_name = "name";
auto it = properties_.makeIterator();
while (it.next()) {
if (it.key() != piHashData((const uchar *)o_name, strlen(o_name)))
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << it.key() << ": " << it.value();
}
//printf("dump %d properties ok\n", properties_.size());
PICout(PICoutManipulators::AddNewLine) << line_prefix << " }";
PICout(PICoutManipulators::AddNewLine) << line_prefix << " methods {";
@@ -710,7 +694,7 @@ void PIObject::dump(const PIString & line_prefix) const {
PICout(PICoutManipulators::AddNewLine) << line_prefix << " connections {";
PICout(PICoutManipulators::AddNewLine) << line_prefix << " count: " << connections.size_s();
//printf("dump %d connections\n",connections.size());
piForeachC (Connection & c, connections) {
for (const Connection & c : connections) {
PIObject * dst = c.dest_o;
__MetaFunc ef = methodEH(c.signal);
PIString src(c.event);
@@ -733,7 +717,7 @@ void PIObject::dump(const PIString & line_prefix) const {
#ifndef MICRO_PIP
void dumpApplication() {
void dumpApplication(bool with_objects) {
PIMutexLocker _ml(PIObject::mutexObjects());
//printf("dump application ...\n");
PIDateTime cd = PIDateTime::current();
@@ -751,22 +735,24 @@ void dumpApplication() {
PICout(PICoutManipulators::AddNewLine) << " uptime: " << PITime::fromSystemTime(cd.toSystemTime() - pi->execDateTime.toSystemTime()).toString();
PICout(PICoutManipulators::AddNewLine) << " PIObjects {";
PICout(PICoutManipulators::AddNewLine) << " count: " << PIObject::objects().size_s();
piForeachC (PIObject * o, PIObject::objects())
if (with_objects) {
for (const PIObject * o: PIObject::objects())
o->dump(" ");
}
PICout(PICoutManipulators::AddNewLine) << " }";
PICout(PICoutManipulators::AddNewLine) << "}";
//printf("dump application done\n");
}
bool dumpApplicationToFile(const PIString & path) {
bool dumpApplicationToFile(const PIString & path, bool with_objects) {
PIFile f(path + "_tmp");
f.setName("__S__DumpFile");
f.clear();
if (!f.open(PIIODevice::WriteOnly)) return false;
bool ba = PICout::isBufferActive();
PICout::setBufferActive(true, true);
dumpApplication();
dumpApplication(with_objects);
f << PICout::buffer();
f.close();
PICout::setBufferActive(ba, true);

View File

@@ -36,10 +36,14 @@
typedef void (*Handler)(void * );
//! \ingroup Core
//! \~\brief
//! \~english This is base class for any classes which use events -> handlers mechanism.
//! \~russian Этот класс является базовым для использования механизма события -> обработчики.
class PIP_EXPORT PIObject {
#ifndef MICRO_PIP
friend class PIObjectManager;
friend void dumpApplication();
friend void dumpApplication(bool);
friend class PIIntrospection;
#endif
typedef PIObject __PIObject__;
@@ -53,6 +57,10 @@ public:
virtual ~PIObject();
//! \ingroup Core
//! \~\brief
//! \~english Helper class for obtain info about if connection successful and disconnect single connection.
//! \~russian Вспомогательный класс для получения информации об успешности соединения и возможности его разрыва.
class PIP_EXPORT Connection {
friend class PIObject;
Connection(void * sl, void * si, const PIString & e = PIString(),
@@ -98,7 +106,7 @@ public:
PIObject * destinationObject() const {return dest_o;}
//! \~english Returns performer object or "nullptr" if this is non-queued connection
//! \~russian Возвращает объект-приемник или "nullptr" если это соединение не отложенное
//! \~russian Возвращает объект-исполнитель или "nullptr" если это соединение не отложенное
PIObject * performerObject() const {return performer;}
//! \~english Disconnect this %Connection, returns if operation successful
@@ -113,7 +121,7 @@ public:
//! \~english Returns object name
//! \~russian Возвращает имя объекта
PIString name() const {return property(PIStringAscii("name")).toString();}
PIString name() const {return property("name").toString();}
//! \~english Returns object class name
//! \~russian Возвращает имя класса объекта
@@ -121,7 +129,6 @@ public:
virtual uint classNameID() const {static uint ret = PIStringAscii("PIObject").hash(); return ret;}
static const PIString __classNameS() {return PIStringAscii("PIObject");}
static const char * __classNameCC() {return "PIObject";}
static uint __classNameIDS() {static uint ret = PIStringAscii("PIObject").hash(); return ret;}
@@ -132,40 +139,28 @@ public:
//! \~english Return if \a piCoutObj of this object is active
//! \~russian Возвращает включен ли вывод \a piCoutObj для этого объекта
bool debug() const {return property(PIStringAscii("debug")).toBool();}
bool debug() const {return property("debug").toBool();}
//! \~english Set object name
//! \~russian Устанавливает имя объекта
void setName(const PIString & name) {setProperty(PIStringAscii("name"), name);}
void setName(const char * name) {setName(PIStringAscii(name));}
void setName(const PIString & name) {setProperty("name", name);}
//! \~english Set object \a piCoutObj active
//! \~russian Включает или отключает вывод \a piCoutObj для этого объекта
void setDebug(bool debug) {setProperty(PIStringAscii("debug"), debug);}
//! \~english Returns properties of the object
//! \~russian Возвращает словарь свойств объекта
PIMap<PIString, PIVariant> properties() const;
//! \~english Returns properties count of the object
//! \~russian Возвращает количество свойств объекта
int propertiesCount() const {return properties_.size_s();}
void setDebug(bool debug) {setProperty("debug", debug);}
//! \~english Returns property with name "name"
//! \~russian Возвращает свойство объекта по имени "name"
PIVariant property(const PIString & name) const {return properties_.value(name.hash(), Property(PIString(), PIVariant())).second;}
PIVariant property(const char * name) const {return property(PIStringAscii(name));}
PIVariant property(const char * name) const {return properties_.value(piHashData((const uchar *)name, strlen(name)));}
//! \~english Set property with name "name" to "value". If there is no such property in object it will be added
//! \~russian Устанавливает у объекта свойство по имени "name" в "value". Если такого свойства нет, оно добавляется
void setProperty(const PIString & name, const PIVariant & value) {properties_[name.hash()] = Property(name, value); propertyChanged(name);}
void setProperty(const char * name, const PIVariant & value) {setProperty(PIStringAscii(name), value);}
void setProperty(const char * name, const PIVariant & value) {properties_[piHashData((const uchar *)name, strlen(name))] = value; propertyChanged(name);}
//! \~english Returns if property with name "name" exists
//! \~russian Возвращает присутствует ли свойство по имени "name"
bool isPropertyExists(const PIString & name) const {return properties_.contains(name.hash());}
bool isPropertyExists(const char * name) const {return isPropertyExists(PIStringAscii(name));}
bool isPropertyExists(const char * name) const {return properties_.contains(piHashData((const uchar *)name, strlen(name)));}
void setThreadSafe(bool yes) {thread_safe_ = yes;}
bool isThreadSafe() const {return thread_safe_;}
@@ -521,7 +516,7 @@ protected:
//! \~english Virtual function executes after property with name "name" has been changed
//! \~russian Виртуальная функция, вызывается после изменения любого свойства.
virtual void propertyChanged(const PIString & name) {}
virtual void propertyChanged(const char * name) {}
EVENT1(deleted, PIObject *, o)
@@ -570,9 +565,6 @@ private:
PRIVATE_DECLARATION(PIP_EXPORT)
};
typedef PIPair<PIString, PIVariant> Property;
typedef PIPair<uint, PIPair<PIString, PIVariant> > PropertyHash;
bool findSuitableMethodV(const PIString & method, int args, int & ret_args, __MetaFunc & ret);
PIVector<__MetaFunc> findEH(const PIString & name) const;
__MetaFunc methodEH(const void * addr) const;
@@ -592,7 +584,7 @@ private:
PIVector<Connection> connections;
PIMap<uint, PIPair<PIString, PIVariant> > properties_;
PIMap<uint, PIVariant> properties_;
PISet<PIObject * > connectors;
PIVector<__QueuedEvent> events_queue;
PIMutex mutex_, mutex_connect, mutex_queue;
@@ -603,8 +595,8 @@ private:
};
#ifndef MICRO_PIP
PIP_EXPORT void dumpApplication();
PIP_EXPORT bool dumpApplicationToFile(const PIString & path);
PIP_EXPORT void dumpApplication(bool with_objects = true);
PIP_EXPORT bool dumpApplicationToFile(const PIString & path, bool with_objects = true);
#endif
#endif // PIOBJECT_H

View File

@@ -392,7 +392,6 @@
protected: \
typedef name __PIObject__; \
public: \
static const PIString __classNameS() {static PIString ret = PIStringAscii(#name); return ret;} \
static const char * __classNameCC() {return #name;} \
static uint __classNameIDS() {static uint ret = PIStringAscii(#name).hash(); return ret;} \
virtual const char * className() const {return #name;} \

View File

@@ -20,13 +20,7 @@
#include "pipropertystorage.h"
//! \addtogroup Core
//! \{
//! \~\class PIPropertyStorage pipropertystorage.h
//! \~\brief
//! \~english This class provides key-value properties storage
//! \~russian Этот класс предоставляет ключ-значение хранение свойств
//!
//! \~\details
//! \~english \section PIPropertyStorage_sec0 Synopsis
//! \~russian \section PIPropertyStorage_sec0 Краткий обзор
@@ -45,35 +39,12 @@
//! \~russian Пример:
//! \~\code{.cpp}
//! \endcode
//! \}
//!
//! \addtogroup Core
//! \{
//! \~\class PIPropertyStorage::Property pipropertystorage.h
//! \~\brief
//! \~english PIPropertyStorage element
//! \~russian Элемент PIPropertyStorage
//!
//! \~\details
//! \~english \section PIPropertyStorage_sec0 Synopsis
//! \~russian \section PIPropertyStorage_sec0 Краткий обзор
//!
//! \~english
//! Key-value storage, based on PIVector with PIPropertyStorage::Property elements. Each element in vector
//! contains unique name. You can access property by name with \a propertyValueByName() or \a propertyByName().
//! You can add or replace property by \a addProperty(const Property&) or \a addProperty(const PIString&, const PIVariant&, const PIString&, int).
//!
//! \~russian
//! Хранилище свойств ключ-значние, основанный на PIVector с элементами PIPropertyStorage::Property.
//! Каждый элемент имеет уникальное имя. Доступ к свойствам через \a propertyValueByName() или \a propertyByName().
//! Добавление и перезапись свойств через \a addProperty(const Property&) или \a addProperty(const PIString&, const PIVariant&, const PIString&, int).
//!
//! \~english Example:
//! \~russian Пример:
//! \~\code{.cpp}
//! \endcode
//! \}
bool PIPropertyStorage::isPropertyExists(const PIString & _name) const {

View File

@@ -29,6 +29,10 @@
#include "pivariant.h"
//! \ingroup Core
//! \~\brief
//! \~english This class provides key-value properties storage.
//! \~russian Этот класс предоставляет ключ-значение хранение свойств.
class PIP_EXPORT PIPropertyStorage {
public:
@@ -36,6 +40,10 @@ public:
//! \~russian Создает пустой %PIPropertyStorage
PIPropertyStorage() {}
//! \ingroup Core
//! \~\brief
//! \~english PIPropertyStorage element.
//! \~russian Элемент PIPropertyStorage.
struct PIP_EXPORT Property {
//! \~english Contructs %PIPropertyStorage::Property with name "n", comment "c", value "v" and flags "f"
@@ -257,8 +265,6 @@ public:
//! \~russian Возвращает свойство с именем "name" как константу
const Property operator[](const PIString & name) const;
static Property parsePropertyLine(PIString l);
protected:
PIVector<Property> props;

View File

@@ -27,21 +27,11 @@
#ifdef WINDOWS
# include <stringapiset.h>
#endif
#include <wchar.h>
#ifdef ANDROID
# if __ANDROID_API__ < 21
# define wctomb(s, wc) wcrtomb(s, wc, NULL)
# define mbtowc(pwc, s, n) mbrtowc(pwc, s, n, NULL)
# endif
#endif
#include <string>
#include <locale>
#include <codecvt>
//! \addtogroup Core
//! \{
//! \class PIString pistring.h
//! \brief
//! \~english String class
//! \~russian Класс строки
//!
//! \~\details
//! \~english \section PIString_sec0 Synopsis
//! \~russian \section PIString_sec0 Краткий обзор
@@ -58,16 +48,15 @@
//! создана из множества типов и преобразована в несколько типов.
//! Имеет множество методов для манипуляций.
//!
//! \}
const char PIString::toBaseN[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
const char PIString::toBaseN[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^'};
const int PIString::fromBaseN[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
const char PIString::fromBaseN[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
@@ -89,11 +78,7 @@ const float PIString::ElideCenter = .5f;
const float PIString::ElideRight = 1.f;
#ifndef CC_VC
# define pisprintf(f, v) char ch[256]; memset(ch, 0, 256); sprintf(ch, f, v); return PIString(ch);
#else
# define pisprintf(f, v) char ch[256]; memset(ch, 0, 256); sprintf_s(ch, 256, f, v); return PIString(ch);
#endif
#define pisprintf(f, v) char ch[256]; memset(ch, 0, 256); snprintf(ch, 256, f, v); return PIStringAscii(ch);
PIString PIString::itos(const int num) {pisprintf("%d", num);}
PIString PIString::ltos(const long num) {pisprintf("%ld", num);}
@@ -101,16 +86,10 @@ PIString PIString::lltos(const llong num) {pisprintf("%lld", num);}
PIString PIString::uitos(const uint num) {pisprintf("%u", num);}
PIString PIString::ultos(const ulong num) {pisprintf("%lu", num);}
PIString PIString::ulltos(const ullong num) {pisprintf("%llu", num);}
PIString PIString::ftos(const float num, char format, int precision) {
char f[8] = "%.";
int wr = sprintf(&(f[2]), "%d", precision);
f[2 + wr] = format;
f[3 + wr] = 0;
pisprintf(f, num);
}
PIString PIString::dtos(const double num, char format, int precision) {
char f[8] = "%.";
int wr = sprintf(&(f[2]), "%d", precision);
int wr = snprintf(&(f[2]), 4, "%d", precision);
if (wr > 4) wr = 4;
f[2 + wr] = format;
f[3 + wr] = 0;
pisprintf(f, num);
@@ -121,7 +100,7 @@ PIString PIString::dtos(const double num, char format, int precision) {
PIString PIString::fromNumberBaseS(const llong value, int base, bool * ok) {
if (value == 0LL) return PIString('0');
if (base < 2 || base > 40) {
if ((base < 2) || (base > 40)) {
if (ok != 0) *ok = false;
return PIString();
}
@@ -143,7 +122,7 @@ PIString PIString::fromNumberBaseS(const llong value, int base, bool * ok) {
PIString PIString::fromNumberBaseU(const ullong value, int base, bool * ok) {
if (value == 0ULL) return PIString('0');
if (base < 2 || base > 40) {
if ((base < 2) || (base > 40)) {
if (ok != 0) *ok = false;
return PIString();
}
@@ -174,7 +153,7 @@ llong PIString::toNumberBase(const PIString & value, int base, bool * ok) {
} else {
base = 10;
}
} else if (base < 2 || base > 40) {
} else if ((base < 2) || (base > 40)) {
if (ok != 0) *ok = false;
return 0;
}
@@ -182,7 +161,7 @@ llong PIString::toNumberBase(const PIString & value, int base, bool * ok) {
PIVector<int> digits;
llong ret = 0, m = 1;
bool neg = false;
int cs;
char cs;
for (int i = 0; i < v.size_s(); ++i) {
if (v[i] == PIChar('-')) {
neg = !neg;
@@ -205,116 +184,87 @@ llong PIString::toNumberBase(const PIString & value, int base, bool * ok) {
void PIString::appendFromChars(const char * c, int s, const char * codepage) {
if (s <= 0) return;
int sz;
// piCout << "appendFromChars";
if (s == 0) return;
int old_sz = size_s();
if (s == -1) s = strlen(c);
#ifdef PIP_ICU
UErrorCode e((UErrorCode)0);
UConverter * cc = ucnv_open(codepage, &e);
if (cc) {
UChar * ucs = new UChar[s];
memset(ucs, 0, s * sizeof(UChar));
d.enlarge(s);
e = (UErrorCode)0;
sz = ucnv_toUChars(cc, ucs, s, c, s, &e);
//printf("appendFromChars %d -> %d\n", s, sz);
//printf("PIString %d -> %d\n", c[0], ucs[0]);
reserve(size_s() + sz);
for (int i = 0; i < sz; ++i) {
push_back(PIChar((ushort)ucs[i]));
}
delete[] ucs;
int sz = ucnv_toUChars(cc, (UChar*)(d.data(old_sz)), s, c, s, &e);
d.resize(old_sz+sz);
ucnv_close(cc);
return;
}
#else
# ifdef WINDOWS
sz = MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, s, 0, 0);
int sz = MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, s, 0, 0);
if (sz <= 0) return;
int old_sz = size_s();
enlarge(sz);
MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, s, (LPWSTR)PIDeque<PIChar>::data(old_sz), sz);
return;
//printf("request %d\n", sz);
d.enlarge(sz);
MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, s, (LPWSTR)d.data(old_sz), sz);
# else
wchar_t wc;
mbtowc(0,0,0); // reset mbtowc
//qDebug() << "FromChars ...";
while (s>0) {
//qDebug() << "0" << s;
sz = mbtowc(&wc, c, s);
//qDebug() << "1" << sz;
if (sz < 1) break;
push_back(PIChar(wc));
c += sz; s -= sz;
//qDebug() << "2" << c;
}
//qDebug() << "FromChars done" << size();
std::wstring_convert<std::codecvt_utf8<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());
# endif
#endif
}
PIString PIString::fromConsole(const char * s) {
int l = 0;
while (s[l] != '\0') ++l;
PIString ret;
if (l > 0) ret.appendFromChars(s, l, __sysoemname__);
if (!s) return ret;
if (s[0] != '\0') ret.appendFromChars(s, -1, __sysoemname__);
return ret;
}
PIString PIString::fromSystem(const char * s) {
int l = 0;
while (s[l] != '\0') ++l;
PIString ret;
if (l > 0) ret.appendFromChars(s, l, __syslocname__);
if (!s) return ret;
if (s[0] != '\0') ret.appendFromChars(s, -1, __syslocname__);
return ret;
}
PIString PIString::fromUTF8(const char * s) {
int l = 0;
while (s[l] != '\0') ++l;
PIString ret;
if (l > 0) ret.appendFromChars(s, l, __utf8name__);
if (!s) return ret;
if (s[0] != '\0') ret.appendFromChars(s, -1, __utf8name__);
return ret;
}
PIString PIString::fromUTF8(const PIByteArray & ba) {
PIString ret;
if (ba.isEmpty()) return ret;
ret.appendFromChars((const char*)ba.data(), ba.size(), __utf8name__);
if (ba.isNotEmpty()) ret.appendFromChars((const char*)ba.data(), ba.size(), __utf8name__);
return ret;
}
PIString PIString::fromAscii(const char * s) {
PIString ret;
int l = 0;
while (s[l] != '\0') {
ret.push_back(PIChar(s[l]));
++l;
}
return ret;
return fromAscii(s, strlen(s));
}
PIString PIString::fromAscii(const char * s, int len) {
PIString ret;
ret.reserve(len);
ret.resize(len);
for (int l = 0; l < len; ++l) {
ret.push_back(PIChar(s[l]));
ret[l] = s[l];
}
return ret;
}
PIString PIString::fromCodepage(const char * s, const char * c) {
int l = 0;
while (s[l] != '\0') ++l;
PIString ret;
if (l > 0) ret.appendFromChars(s, l
if (s[0] > '\0') ret.appendFromChars(s, -1
#ifdef PIP_ICU
, c
#else
@@ -348,72 +298,56 @@ PIString PIString::readableSize(llong bytes) {
void PIString::buildData(const char * cp) const {
data_.clear();
int sz = 0;
deleteData();
#ifdef PIP_ICU
UErrorCode e((UErrorCode)0);
UConverter * cc = ucnv_open(cp, &e);
if (cc) {
char uc[8];
data_.reserve(size_s());
for (int i = 0; i < size_s(); ++i) {
if (at(i).isAscii()) {
data_.push_back(uchar(at(i).unicode16Code()));
} else {
e = (UErrorCode)0;
sz = ucnv_fromUChars(cc, uc, 8, (const UChar*)(PIDeque<PIChar>::data(i)), 1, &e);
for (int j = 0; j < sz; ++j) {
data_.push_back(uc[j]);
}
}
}
const size_t len = MB_CUR_MAX*size()+1;
data_ = (char *)malloc(len);
int sz = ucnv_fromUChars(cc, data_, len, (const UChar*)(d.data()), d.size_s(), &e);
ucnv_close(cc);
data_.push_back('\0');
data_[sz] = '\0';
return;
}
#else
# ifdef WINDOWS
sz = WideCharToMultiByte((uint)(uintptr_t)cp, 0, (LPCWCH)PIDeque<PIChar>::data(), PIDeque<PIChar>::size_s(), 0, 0, NULL, NULL);
//printf("WideCharToMultiByte %d %d\n", (uint)(uintptr_t)cp, sz);
int sz = WideCharToMultiByte((uint)(uintptr_t)cp, 0, (LPCWCH)d.data(), d.size_s(), 0, 0, NULL, NULL);
if (sz <= 0) {
//printf("WideCharToMultiByte erro %d\n", GetLastError());
data_.push_back(uchar('\0'));
data_ = (char *)malloc(1);
data_[0] = '\0';
return;
}
data_.resize(sz);
WideCharToMultiByte((uint)(uintptr_t)cp, 0, (LPCWCH)PIDeque<PIChar>::data(), PIDeque<PIChar>::size_s(), (LPSTR)data_.data(), data_.size_s(), NULL, NULL);
data_.push_back(uchar('\0'));
data_ = (char *)malloc(sz+1);
WideCharToMultiByte((uint)(uintptr_t)cp, 0, (LPCWCH)d.data(), d.size_s(), (LPSTR)data_, sz, NULL, NULL);
data_[sz] = '\0';
return;
# else
wchar_t wc;
char tc[8];
wctomb(0, 0);
for (int i = 0; i < size_s(); ++i) {
if (at(i).isAscii()) {
data_.push_back(uchar(at(i).toAscii()));
continue;
}
wc = at(i).toWChar();
sz = wctomb(tc, wc);
for (int b = 0; b < sz; ++b) {
data_.push_back(uchar(tc[b]));
}
}
data_.push_back(uchar('\0'));
std::wstring_convert<std::codecvt_utf8<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());
# endif
#endif
}
void PIString::deleteData() const {
if (!data_) return;
free(data_);
data_ = nullptr;
}
void PIString::trimsubstr(int &st, int &fn) const {
for (int i = 0; i < length(); ++i) {
for (int i = 0; i < d.size_s(); ++i) {
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12) && at(i) != uchar(0)) {
st = i;
break;
}
}
if (st < 0) return;
for (int i = length() - 1; i >= 0; --i) {
for (int i = d.size_s() - 1; i >= 0; --i) {
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12) && at(i) != uchar(0)) {
fn = i;
break;
@@ -423,19 +357,19 @@ void PIString::trimsubstr(int &st, int &fn) const {
uint PIString::hash() const {
return piHashData((const uchar*)PIDeque<PIChar>::data(), size() * sizeof(PIChar));
return piHashData((const uchar*)d.data(), d.size() * sizeof(PIChar));
}
PIByteArray PIString::toUTF8() const {
if (isEmpty()) return data_.resized(0);
if (isEmpty()) return PIByteArray();
buildData(__utf8name__);
return data_.resized(data_.size_s() - 1);
return PIByteArray(data_, strlen(data_));
}
PIByteArray PIString::toCharset(const char * c) const {
if (isEmpty()) return data_.resized(0);
if (isEmpty()) return PIByteArray();
buildData(
#ifdef PIP_ICU
c
@@ -445,63 +379,67 @@ PIByteArray PIString::toCharset(const char * c) const {
# endif
#endif
);
return data_.resized(data_.size_s() - 1);
return PIByteArray(data_, strlen(data_));
}
PIString & PIString::operator +=(const char * str) {
if (!str) return *this;
int l = 0;
while (str[l] != '\0') ++l;
appendFromChars(str, l, __syslocname__);
appendFromChars(str, -1, __syslocname__);
return *this;
}
PIString::~PIString() {
deleteData();
}
PIString & PIString::operator +=(const wchar_t * str) {
if (!str) return *this;
int i = -1;
while (str[++i]) {
push_back(PIChar(str[i]));
d.push_back(PIChar(str[i]));
}
return *this;
}
PIString & PIString::operator +=(const PIString & str) {
PIDeque<PIChar>::append(*(const PIDeque<PIChar>*)&str);
d.append(str.d);
return *this;
}
PIString & PIString::operator +=(const PIConstChars & str) {
if (!str.isEmpty()) {
size_t os = d.size();
d.enlarge(str.size());
for (size_t l = 0; l < d.size(); ++l) {
d[os + l] = str[l];
}
}
return *this;
}
bool PIString::operator ==(const PIString & str) const {
uint l = str.size();
if (size() != l) return false;
for (uint i = 0; i < l; ++i) {
if (str[i] != at(i)) return false;
}
return true;
return d == str.d;
}
bool PIString::operator !=(const PIString & str) const {
uint l = str.size();
if (size() != l) return true;
for (uint i = 0; i < l; ++i) {
if (str[i] != at(i)) return true;
}
return false;
return d != str.d;
}
bool PIString::operator <(const PIString & str) const {
uint l = str.size();
size_t l = str.size();
if (size() < l) return true;
if (size() > l) return false;
for (uint i = 0; i < l; ++i) {
if (at(i) == str[i]) continue;
if (at(i) < str[i]) return true;
for (size_t i = 0; i < l; ++i) {
if (at(i) == str.at(i)) continue;
if (at(i) < str.at(i)) return true;
else return false;
}
return false;
@@ -509,12 +447,12 @@ bool PIString::operator <(const PIString & str) const {
bool PIString::operator >(const PIString & str) const {
uint l = str.size();
size_t l = str.size();
if (size() < l) return false;
if (size() > l) return true;
for (uint i = 0; i < l; ++i) {
if (at(i) == str[i]) continue;
if (at(i) < str[i]) return false;
for (size_t i = 0; i < l; ++i) {
if (at(i) == str.at(i)) continue;
if (at(i) < str.at(i)) return false;
else return true;
}
return false;
@@ -545,10 +483,10 @@ PIString PIString::mid(const int start, const int len) const {
s = 0;
}
if (l < 0) {
return PIString(&(at(s)), size_s() - s);
return PIString(d.data(s), size_s() - s);
} else {
if (l > length() - s) l = length() - s;
return PIString(&(at(s)), l);
return PIString(d.data(s), l);
}
return PIString();
}
@@ -573,10 +511,10 @@ PIString & PIString::cutMid(const int start, const int len) {
s = 0;
}
if (l < 0) {
remove(s, size() - s);
d.remove(s, size() - s);
} else {
if (l > length() - s) l = length() - s;
remove(s, l);
d.remove(s, l);
}
return *this;
}
@@ -625,10 +563,10 @@ PIString PIString::trimmed() const {
PIString & PIString::replace(int from, int count, const PIString & with) {
count = piMini(count, length() - from);
if (count == with.size_s()) {
memcpy(PIDeque<PIChar>::data(from), static_cast<PIDeque<PIChar>>(with).data(), count * sizeof(PIChar));
memcpy(d.data(from), with.d.data(), count * sizeof(PIChar));
} else {
remove(from, count);
PIDeque<PIChar>::insert(from, with);
d.remove(from, count);
d.insert(from, with.d);
}
return *this;
}
@@ -680,9 +618,9 @@ PIString & PIString::replaceAll(const PIString & what, const PIString & with) {
}
}
if (!match) continue;
if (dl > 0) PIDeque<PIChar>::insert(i, PIDeque<PIChar>((size_t)dl));
if (dl < 0) PIDeque<PIChar>::remove(i, -dl);
memcpy(PIDeque<PIChar>::data(i), &(with.at(0)), with.length() * sizeof(PIChar));
if (dl > 0) d.insert(i, PIDeque<PIChar>((size_t)dl));
if (dl < 0) d.remove(i, -dl);
memcpy(d.data(i), with.d.data(), with.size() * sizeof(PIChar));
}
}
return *this;
@@ -708,8 +646,8 @@ PIString & PIString::replaceAll(const PIString & what, const char with) {
}
}
if (!match) continue;
if (dl > 0) PIDeque<PIChar>::remove(i, dl);
(*this)[i] = PIChar(with);
if (dl > 0) d.remove(i, dl);
d[i] = PIChar(with);
}
return *this;
}
@@ -725,7 +663,7 @@ PIString & PIString::replaceAll(const PIString & what, const char with) {
PIString & PIString::replaceAll(const char what, const char with) {
int l = length();
for (int i = 0; i < l; ++i) {
if (at(i) == what) (*this)[i] = with;
if (at(i) == what) d[i] = with;
}
return *this;
}
@@ -737,13 +675,13 @@ PIString & PIString::removeAll(const PIString & str) {
for (int i = 0; i < length() - l + 1; ++i) {
bool match = true;
for (int j = 0; j < l; ++j) {
if (at(j + i) != str[j]) {
if (d.at(j + i) != str.at(j)) {
match = false;
break;
}
}
if (!match) continue;
PIDeque<PIChar>::remove(i, l);
d.remove(i, l);
i -= l;
}
return *this;
@@ -751,7 +689,7 @@ PIString & PIString::removeAll(const PIString & str) {
PIString & PIString::insert(int index, const PIString & str) {
PIDeque<PIChar>::insert(index, *((const PIDeque<PIChar>*)&str));
d.insert(index, str.d);
return *this;
}
@@ -766,8 +704,8 @@ PIString & PIString::elide(int size, float pos) {
pos = piClampf(pos, 0.f, 1.f);
int ns = size - 2;
int ls = piRoundf(ns * pos);
remove(ls, length() - ns);
insert(ls, s_dotdot);
d.remove(ls, length() - ns);
d.insert(ls, s_dotdot.d);
return *this;
}
@@ -853,6 +791,14 @@ int PIString::findLast(const char c, const int start) const {
return -1;
}
int PIString::findLast(PIChar c, const int start) const
{
for (int i = length() - 1; i >= start; --i) {
if (at(i) == c) return i;
}
return -1;
}
//! \~\details
//! \~\code
@@ -902,14 +848,14 @@ int PIString::findWord(const PIString & word, const int start) const {
bool ok = true;
PIChar c;
if (f > 0) {
c = (*this)[f - 1];
c = at(f - 1);
if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) {
ok = false;
continue;
}
}
if (f + wl < tl) {
c = (*this)[f + wl];
c = at(f + wl);
if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) {
ok = false;
continue;
@@ -936,14 +882,14 @@ int PIString::findCWord(const PIString & word, const int start) const {
bool ok = true;
PIChar c;
if (f > 0) {
c = (*this)[f - 1];
c = at(f - 1);
if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r' || (c != '_' && !c.isAlpha() && !c.isDigit()))) {
ok = false;
continue;
}
}
if (f + wl < tl) {
c = (*this)[f + wl];
c = at(f + wl);
if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r' || (c != '_' && !c.isAlpha() && !c.isDigit()))) {
ok = false;
continue;
@@ -1356,93 +1302,80 @@ PIString PIString::inBrackets(const PIChar start, const PIChar end) const {
}
//! \~\details
//! \~english It`s equivalent length of char sequence returned by function \a data() - 1, without terminating null-char
//! \~russian Эквивалентно длине данных, возвращаемых \a data() - 1, без завершающего нулевого байта
//! \~\code
//! piCout << PIString("0123456789").lengthAscii(); // 10
//! piCout << PIString("№1").lengthAscii(); // 3
//! \endcode
//! \~\sa \a data()
int PIString::lengthAscii() const {
buildData(__syslocname__);
return data_.size_s() - 1;
}
//! \~\details
//! \~english
//! This function fill internal buffer by sequence
//! of chars. Minimum length of this buffer is count
//! of symbols. Returned pointer is valid until next
//! execution of this function
//! This function fill internal buffer by sequence of chars.
//! Length of this buffer is count of symbols + end byte '\0'.
//! Returned pointer is valid until next execution of this function.
//! \~russian
//! Этот метод заполняет внутренный байтовый буфер. Минимальный размер
//! этого буфера равен количеству символов строки. Возвращаемый указатель
//! действителен до следующего вызова этого метода
//! Этот метод заполняет внутренный байтовый буфер. Размер
//! этого буфера равен количеству символов строки + завершающий байт '\0'.
//! Возвращаемый указатель действителен до следующего вызова этого метода.
//! \~\code
//! piCout << PIString("0123456789").data(); // 0123456789
//! piCout << PIString("№1").data(); // №1
//! \endcode
//! \~\sa \a dataConsole(), \a dataUTF8()
const char * PIString::data() const {
if (isEmpty()) return "";
buildData(__syslocname__);
return (const char *)(data_.data());
return data_;
}
//! \~\details
//! \~english
//! This function fill internal buffer by sequence
//! of chars. Minimum length of this buffer is count
//! of symbols. Returned pointer is valid until next
//! execution of this function
//! \~russian
//! Этот метод заполняет внутренный байтовый буфер. Минимальный размер
//! этого буфера равен количеству символов строки. Возвращаемый указатель
//! действителен до следующего вызова этого метода
//! \~\sa \a data(), \a dataUTF8()
const char * PIString::dataConsole() const {
buildData(__sysoemname__ );
return (const char *)(data_.data());
}
//! \~\details
//! \~english
//! This function fill internal buffer by sequence
//! of chars. Minimum length of this buffer is count
//! of symbols. Returned pointer is valid until next
//! execution of this function
//! \~russian
//! Этот метод заполняет внутренный байтовый буфер. Минимальный размер
//! этого буфера равен количеству символов строки. Возвращаемый указатель
//! действителен до следующего вызова этого метода
//! \~\sa \a data(), \a dataConsole()
const char * PIString::dataUTF8() const {
buildData(__utf8name__);
return (const char *)(data_.data());
}
//! \~\details
//! \~english
//! This function fill internal buffer by sequence
//! of chars. Length of this buffer is count
//! of symbols. Returned pointer is valid until next
//! execution of this function
//! This function fill internal buffer by sequence of chars.
//! Length of this buffer is count of symbols + end byte '\0'.
//! Returned pointer is valid until next execution of this function.
//! \~russian
//! Этот метод заполняет внутренный байтовый буфер. Размер
//! этого буфера равен количеству символов строки. Возвращаемый указатель
//! действителен до следующего вызова этого метода
//! этого буфера равен количеству символов строки + завершающий байт '\0'.
//! Возвращаемый указатель действителен до следующего вызова этого метода.
//! \~\sa \a data(), \a dataUTF8()
const char * PIString::dataConsole() const {
if (isEmpty()) return "";
buildData(__sysoemname__ );
return data_;
}
//! \~\details
//! \~english
//! This function fill internal buffer by sequence of chars.
//! Length of this buffer is count of symbols + end byte '\0'.
//! Returned pointer is valid until next execution of this function.
//! \~russian
//! Этот метод заполняет внутренный байтовый буфер. Размер
//! этого буфера равен количеству символов строки + завершающий байт '\0'.
//! Возвращаемый указатель действителен до следующего вызова этого метода.
//! \~\sa \a data(), \a dataConsole()
const char * PIString::dataUTF8() const {
if (isEmpty()) return "";
buildData(__utf8name__);
return data_;
}
//! \~\details
//! \~english
//! This function fill internal buffer by sequence of chars.
//! Length of this buffer is count of symbols + end byte '\0'.
//! Returned pointer is valid until next execution of this function.
//! \~russian
//! Этот метод заполняет внутренный байтовый буфер. Размер
//! этого буфера равен количеству символов строки + завершающий байт '\0'.
//! Возвращаемый указатель действителен до следующего вызова этого метода.
//! \~\sa \a dataConsole(), \a dataUTF8()
const char * PIString::dataAscii() const {
data_.clear();
if (isEmpty()) return "";
deleteData();
data_ = (char*)malloc(size()+1);
for (int i = 0; i < size_s(); ++i) {
data_.push_back(uchar(at(i).ch));
data_[i] = uchar(at(i).ch);
}
data_.push_back(uchar('\0'));
return (const char *)data_.data();
data_[size()] = '\0';
return data_;
}
@@ -1450,7 +1383,7 @@ PIString PIString::toUpperCase() const {
PIString str(*this);
int l = str.size();
for (int i = 0; i < l; ++i) {
str[i] = str[i].toUpper();
str.d[i] = str.d[i].toUpper();
}
return str;
}
@@ -1460,7 +1393,7 @@ PIString PIString::toLowerCase() const {
PIString str(*this);
int l = str.size();
for (int i = 0; i < l; ++i) {
str[i] = str[i].toLower();
str.d[i] = str.d[i].toLower();
}
return str;
}
@@ -1729,7 +1662,7 @@ PIString versionNormalize(const PIString & v) {
PICout operator <<(PICout s, const PIString & v) {
s.space();
s.quote();
s.writePIString(v);
s.write(v);
s.quote();
return s;
}

View File

@@ -27,56 +27,75 @@
#define PISTRING_H
#include "pibytearray.h"
#include "piconstchars.h"
#define PIStringAscii PIString::fromAscii
class PIStringList;
class PIP_EXPORT PIString: public PIDeque<PIChar>
//! \ingroup Core
//! \~\brief
//! \~english String class.
//! \~russian Класс строки.
class PIP_EXPORT PIString
{
friend PIByteArray & operator >>(PIByteArray & s, PIString & v);
friend PIByteArray & operator <<(PIByteArray & s, const PIString & v);
public:
//! \~english Contructs an empty string
//! \~russian Создает пустую строку
PIString(): PIDeque<PIChar>() {}
typedef PIDeque<PIChar>::iterator iterator;
typedef PIDeque<PIChar>::const_iterator const_iterator;
typedef PIDeque<PIChar>::reverse_iterator reverse_iterator;
typedef PIDeque<PIChar>::const_reverse_iterator const_reverse_iterator;
typedef PIChar value_type;
typedef PIChar* pointer;
typedef const PIChar* const_pointer;
typedef PIChar& reference;
typedef const PIChar& const_reference;
typedef size_t size_type;
//! \~english Value for elide at left
//! \~russian Значение для пропуска слева
//! \~english Contructs an empty string.
//! \~russian Создает пустую строку.
PIString() {}
//! \~english Value for elide at left.
//! \~russian Значение для пропуска слева.
static const float ElideLeft ;
//! \~english Value for elide at center
//! \~russian Значение для пропуска в середине
//! \~english Value for elide at center.
//! \~russian Значение для пропуска в середине.
static const float ElideCenter;
//! \~english Value for elide at right
//! \~russian Значение для пропуска справа
//! \~english Value for elide at right.
//! \~russian Значение для пропуска справа.
static const float ElideRight ;
PIString & operator +=(const PIChar & c) {PIDeque<PIChar>::push_back(c); return *this;}
PIString & operator +=(const char c) {PIDeque<PIChar>::push_back(PIChar(c)); return *this;}
PIString & operator +=(const PIChar & c) {d.push_back(c); return *this;}
PIString & operator +=(const char c) {d.push_back(PIChar(c)); return *this;}
PIString & operator +=(const char * str);
PIString & operator +=(const wchar_t * str);
PIString & operator +=(const PIByteArray & ba) {appendFromChars((const char * )ba.data(), ba.size_s(), __utf8name__); return *this;}
PIString & operator +=(const PIString & str);
PIString & operator +=(const PIConstChars & str);
//! \~english Contructs a copy of string
//! \~russian Создает копию строки
PIString(const PIString & o): PIDeque<PIChar>(o) {}
//! \~english Contructs a copy of string.
//! \~russian Создает копию строки.
PIString(const PIString & o) {d = o.d;}
PIString(PIString && o): PIDeque<PIChar>(std::move(o)) {}
//! \~english Move constructor.
//! \~russian Перемещающий конструктор.
PIString(PIString && o): d(std::move(o.d)) {piSwap(data_, o.data_);}
//! \~english Contructs string with single character "c".
//! \~russian Создает строку из одного символа "c".
PIString(const PIChar c) {*this += c;}
//! \~english Contructs string with single symbol "c"
//! \~russian Создает строку из одного символа "c"
PIString(const PIChar c): PIDeque<PIChar>() {*this += c;}
//! \~english Contructs string with single character "c".
//! \~russian Создает строку из одного символа "c".
PIString(const char c) {*this += PIChar(c);}
//! \~english Contructs string with single symbol "c"
//! \~russian Создает строку из одного символа "c"
PIString(const char c): PIDeque<PIChar>() {*this += PIChar(c);}
//! \~english Contructs string from C-string "str" (system codepage)
//! \~russian Создает строку из C-строки "str" (кодировка системы)
//! \~english Contructs string from C-string "str" (system codepage).
//! \~russian Создает строку из C-строки "str" (кодировка системы).
//! \~\details
//! \~english
//! "str" should be null-terminated\n
@@ -85,10 +104,10 @@ public:
//! \~\code
//! PIString s("string");
//! \endcode
PIString(const char * str): PIDeque<PIChar>() {*this += str;}
PIString(const char * str) {*this += str;}
//! \~english Contructs string from \c wchar_t C-string "str"
//! \~russian Создает строку из \c wchar_t C-строки "str"
//! \~english Contructs string from \c wchar_t C-string "str".
//! \~russian Создает строку из \c wchar_t C-строки "str".
//! \~\details
//! \~english
//! "str" should be null-terminated
@@ -97,123 +116,134 @@ public:
//! \~\code
//! PIString s(L"string");
//! \endcode
PIString(const wchar_t * str): PIDeque<PIChar>() {*this += str;}
PIString(const wchar_t * str) {*this += str;}
//! \~english Contructs string from byte array "ba" (as UTF-8)
//! \~russian Создает строку из байтового массива "ba" (как UTF-8)
PIString(const PIByteArray & ba): PIDeque<PIChar>() {*this += ba;}
//! \~english Contructs string from byte array "ba" (as UTF-8).
//! \~russian Создает строку из байтового массива "ba" (как UTF-8).
PIString(const PIByteArray & ba) {*this += ba;}
//! \~english Contructs string from "len" characters of buffer "str"
//! \~russian Создает строку из "len" символов массива "str"
PIString(const PIChar * str, const int len): PIDeque<PIChar>(str, size_t(len)) {}
//! \~english Contructs string from "len" characters of buffer "str".
//! \~russian Создает строку из "len" символов массива "str".
PIString(const PIChar * str, const int len): d(str, size_t(len)) {}
//! \~english Contructs string from "len" characters of buffer "str" (system codepage)
//! \~russian Создает строку из "len" символов массива "str" (кодировка системы)
//! \~english Contructs string from "len" characters of buffer "str" (system codepage).
//! \~russian Создает строку из "len" символов массива "str" (кодировка системы).
//! \~\details
//! \~\code
//! PIString s("string", 3); // s = "str"
//! \endcode
PIString(const char * str, const int len): PIDeque<PIChar>() {appendFromChars(str, len);}
PIString(const char * str, const int len) {appendFromChars(str, len);}
//! \~english Contructs string as sequence of characters "c" of buffer with length "len"
//! \~russian Создает строку как последовательность длиной "len" символа "c"
//! \~english Contructs string as sequence of characters "c" of buffer with length "len".
//! \~russian Создает строку как последовательность длиной "len" символа "c".
//! \~\details
//! \~\code
//! PIString s(5, 'p'); // s = "ppppp"
//! \endcode
PIString(const int len, const char c): PIDeque<PIChar>() {for (int i = 0; i < len; ++i) PIDeque<PIChar>::push_back(PIChar(c));}
PIString(const int len, const char c) {for (int i = 0; i < len; ++i) d.push_back(PIChar(c));}
//! \~english Contructs string as sequence of symbols "c" of buffer with length "len"
//! \~russian Создает строку как последовательность длиной "len" символа "c"
//! \~english Contructs string as sequence of characters "c" of buffer with length "len".
//! \~russian Создает строку как последовательность длиной "len" символа "c".
//! \~\details
//! \~\code
//! PIString s(5, "№"); // s = "№№№№№"
//! \endcode
PIString(const int len, const PIChar c): PIDeque<PIChar>() {for (int i = 0; i < len; ++i) PIDeque<PIChar>::push_back(c);}
PIString(const int len, const PIChar c) {for (int i = 0; i < len; ++i) d.push_back(c);}
~PIString() {}
PIString(const PIConstChars & c) {*this += c;}
~PIString();
//! \~english Assign operator
//! \~russian Оператор присваивания
PIString & operator =(const PIString & o) {if (this == &o) return *this; clear(); *this += o; return *this;}
//! \~english Assign operator.
//! \~russian Оператор присваивания.
PIString & operator =(const PIString & o) {if (this == &o) return *this; d = o.d; return *this;}
PIString & operator =(PIString && o) {swap(o); return *this;}
//! \~english Assign move operator.
//! \~russian Оператор перемещающего присваивания.
PIString & operator =(PIString && o) {d.swap(o.d); piSwap(data_, o.data_); return *this;}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Assign operator.
//! \~russian Оператор присваивания.
PIString & operator =(const PIConstChars & o) {d.clear(); *this += o; return *this;}
//! \~english Assign operator.
//! \~russian Оператор присваивания.
PIString & operator =(const char * o) {d.clear(); *this += o; return *this;}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator ==(const PIString & str) const;
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator ==(const PIChar c) const {if (size_s() != 1) return false; return at(0) == c;}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator ==(const PIChar c) const {if (d.size() != 1) return false; return d.at(0) == c;}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator ==(const char * str) const {return *this == PIString(str);}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator !=(const PIString & str) const;
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator !=(const PIChar c) const {if (size_s() != 1) return true; return at(0) != c;}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator !=(const PIChar c) const {if (d.size() != 1) return true; return d.at(0) != c;}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator !=(const char * str) const {return *this != PIString(str);}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator <(const PIString & str) const;
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator <(const PIChar c) const {if (size_s() != 1) return size_s() < 1; return at(0) < c;}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator <(const PIChar c) const {if (d.size() != 1) return d.size() < 1; return d.at(0) < c;}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator <(const char * str) const {return *this < PIString(str);}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator >(const PIString & str) const;
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator >(const PIChar c) const {if (size_s() != 1) return size_s() > 1; return at(0) > c;}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator >(const PIChar c) const {if (d.size() != 1) return d.size() > 1; return d.at(0) > c;}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator >(const char * str) const {return *this > PIString(str);}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator <=(const PIString & str) const {return !(*this > str);}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator <=(const PIChar c) const {return !(*this > c);}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator <=(const char * str) const {return *this <= PIString(str);}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator >=(const PIString & str) const {return !(*this < str);}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator >=(const PIChar c) const {return !(*this < c);}
//! \~english Compare operator
//! \~russian Оператор сравнения
//! \~english Compare operator.
//! \~russian Оператор сравнения.
bool operator >=(const char * str) const {return *this >= PIString(str);}
//! \~english Append string "str" at the end of string
//! \~russian Добавляет в конец строку "str"
//! \~english Append string "str" at the end of string.
//! \~russian Добавляет в конец строку "str".
//! \~\details
//! \~\code
//! PIString s("this"), s1(" is"), s2(" string");
@@ -221,26 +251,26 @@ public:
//! \endcode
PIString & operator <<(const PIString & str) {*this += str; return *this;}
//! \~english Append symbol "c" at the end of string
//! \~russian Добавляет в конец символ "c"
//! \~english Append character "c" at the end of string.
//! \~russian Добавляет в конец символ "c".
//! \~\details
//! \~\code
//! PIString s("stri");
//! s << PIChar('n') << PIChar('g'); // s = "string"
//! \endcode
PIString & operator <<(const PIChar c) {*this += c; return *this;}
PIString & operator <<(const PIChar c) {d.append(c); return *this;}
//! \~english Append symbol `c` at the end of string
//! \~russian Добавляет в конец символ `c`
//! \~english Append character `c` at the end of string.
//! \~russian Добавляет в конец символ `c`.
//! \~\details
//! \~\code
//! PIString s("stri");
//! s << 'n' << 'g'; // s = "string"
//! \endcode
PIString & operator <<(const char c) {*this += PIChar(c); return *this;}
PIString & operator <<(const char c) {d.append(PIChar(c)); return *this;}
//! \~english Append С-string "str" at the end of string
//! \~russian Добавляет в конец C-строку "str"
//! \~english Append С-string "str" at the end of string.
//! \~russian Добавляет в конец C-строку "str".
//! \~\details
//! \~\code
//! PIString s("this");
@@ -248,8 +278,8 @@ public:
//! \endcode
PIString & operator <<(const char * str) {*this += str; return *this;}
//! \~english Append \c wchar_t C-string "str" at the end of string
//! \~russian Добавляет в конец \c wchar_t C-строку "str"
//! \~english Append \c wchar_t C-string "str" at the end of string.
//! \~russian Добавляет в конец \c wchar_t C-строку "str".
//! \~\details
//! \~\code
//! PIString s;
@@ -257,8 +287,10 @@ public:
//! \endcode
PIString & operator <<(const wchar_t * str) {*this += str; return *this;}
//! \~english Append string representation of "num" at the end of string
//! \~russian Добавляет в конец строковое представление "num"
PIString & operator <<(const PIConstChars & str) {*this += str; return *this;}
//! \~english Append string representation of "num" at the end of string.
//! \~russian Добавляет в конец строковое представление "num".
//! \~\details
//! \~\code
//! PIString s("ten - ");
@@ -267,8 +299,8 @@ public:
PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;}
PIString & operator <<(const uint & num) {*this += PIString::fromNumber(num); return *this;}
//! \~english Append string representation of "num" at the end of string
//! \~russian Добавляет в конец строковое представление "num"
//! \~english Append string representation of "num" at the end of string.
//! \~russian Добавляет в конец строковое представление "num".
//! \~\details
//! \~\code
//! PIString s("ten - ");
@@ -280,8 +312,8 @@ public:
PIString & operator <<(const llong & num) {*this += PIString::fromNumber(num); return *this;}
PIString & operator <<(const ullong & num) {*this += PIString::fromNumber(num); return *this;}
//! \~english Append string representation of "num" at the end of string
//! \~russian Добавляет в конец строковое представление "num"
//! \~english Append string representation of "num" at the end of string.
//! \~russian Добавляет в конец строковое представление "num".
//! \~\details
//! \~\code
//! PIString s("1/10 - ");
@@ -289,8 +321,8 @@ public:
//! \endcode
PIString & operator <<(const float & num) {*this += PIString::fromNumber(num); return *this;}
//! \~english Append string representation of "num" at the end of string
//! \~russian Добавляет в конец строковое представление "num"
//! \~english Append string representation of "num" at the end of string.
//! \~russian Добавляет в конец строковое представление "num".
//! \~\details
//! \~\code
//! PIString s("1/10 - ");
@@ -298,82 +330,186 @@ public:
//! \endcode
PIString & operator <<(const double & num) {*this += PIString::fromNumber(num); return *this;}
//! \~english Iterator to the first element.
//! \~russian Итератор на первый элемент.
//! \~\details
//! \~\return \ref stl_iterators
//! \~\sa \a end(), \a rbegin(), \a rend()
inline iterator begin() {return d.begin();}
//! \~english Insert string "str" at the begin of string
//! \~russian Вставляет "str" в начало строки
//! \~english Iterator to the element following the last element.
//! \~russian Итератор на элемент, следующий за последним элементом.
//! \~\details
//! \~\return \ref stl_iterators
//! \~\sa \a begin(), \a rbegin(), \a rend()
inline iterator end() {return d.end();}
inline const_iterator begin() const {return d.begin();}
inline const_iterator end() const {return d.end();}
//! \~english Returns a reverse iterator to the first element of the reversed array.
//! \~russian Обратный итератор на первый элемент.
//! \~\details
//! \~english It corresponds to the last element of the non-reversed array.
//! \~russian Итератор для прохода массива в обратном порядке.
//! Указывает на последний элемент.
//! \~\return \ref stl_iterators
//! \~\sa \a rend(), \a begin(), \a end()
inline reverse_iterator rbegin() {return d.rbegin();}
//! \~english Returns a reverse iterator to the element.
//! following the last element of the reversed array.
//! \~russian Обратный итератор на элемент, следующий за последним элементом.
//! \~\details
//! \~english It corresponds to the element preceding the first element of the non-reversed array.
//! \~russian Итератор для прохода массива в обратном порядке.
//! Указывает на элемент, предшествующий первому элементу.
//! \~\return \ref stl_iterators
//! \~\sa \a rbegin(), \a begin(), \a end()
inline reverse_iterator rend() {return d.rend();}
inline const_reverse_iterator rbegin() const {return d.rbegin();}
inline const_reverse_iterator rend() const {return d.rend();}
//! \~english Full access to character by `index`.
//! \~russian Полный доступ к символу по индексу `index`.
//! \~\details
//! \~english Сharacter index starts from `0`.
//! Сharacter index must be in range from `0` to `size()-1`.
//! Otherwise will be undefined behavior.
//! \~russian Индекс элемента считается от `0`.
//! Индекс символа должен лежать в пределах от `0` до `size()-1`.
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
inline PIChar & operator [](size_t index) {return d[index];}
inline PIChar operator [](size_t index) const {return d[index];}
//! \~english Read only access to character by `index`.
//! \~russian Доступ исключительно на чтение к символу по индексу `index`.
//! \~\details
//! \~english Сharacter index starts from `0`.
//! Сharacter index must be in range from `0` to `size()-1`.
//! Otherwise will be undefined behavior.
//! \~russian Индекс символа считается от `0`.
//! Индекс символа должен лежать в пределах от `0` до `size()-1`.
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
inline const PIChar at(size_t index) const {return d.at(index);}
//! \~english Returns the last character of the string.
//! \~russian Возвращает последний символ строки.
inline PIChar & back() {return d.back();}
inline PIChar back() const {return d.back();}
inline PIChar & front() {return d.front();}
inline PIChar front() const {return d.front();}
//! \~english Sets size of the string, new characters are copied from `c`.
//! \~russian Устанавливает размер строки, новые символы копируются из `c`.
//! \~\details
//! \~english If `new_size` is greater than the current \a size(),
//! characters are added to the end; the new characters are initialized from `c`.
//! If `new_size` is less than the current \a size(), characters are removed from the end.
//! \~russian Если `new_size` больше чем текущий размер строки \a size(),
//! новые символы добавляются в конец строки и создаются из `с`.
//! Если `new_size` меньше чем текущий размер строки \a size(),
//! лишние символы удаляются с конца строки.
//! \~\sa \a size(), \a clear()
inline PIString & resize(size_t new_size, PIChar c = PIChar()) {d.resize(new_size, c); return *this;}
//! \~english Delete one character at the end of string.
//! \~russian Удаляет один символ с конца строки.
inline PIString & pop_back() {d.pop_back(); return *this;}
//! \~english Delete one character at the benig of string.
//! \~russian Удаляет один символ с начала строки.
inline PIString & pop_front() {d.pop_front(); return *this;}
//! \~english Removes `count` characters from the string, starting at `index` position.
//! \~russian Удаляет символы из строки, начиная с позиции `index` в количестве `count`.
inline PIString & remove(size_t index, size_t count = 1) {d.remove(index, count); return *this;}
//! \~english Assigns character 'c' to all string characters.
//! \~russian Заполняет всю строку символами `c`.
inline PIString & fill(PIChar c = PIChar()) {d.fill(c); return *this;}
//! \~english Insert string "str" at the begin of string.
//! \~russian Вставляет "str" в начало строки.
PIString & prepend(const char * str) {insert(0, str); return *this;}
//! \~english Insert string "str" at the begin of string
//! \~russian Вставляет "str" в начало строки
PIString & prepend(const PIString & str) {insert(0, str); return *this;}
//! \~english Insert string "str" at the begin of string.
//! \~russian Вставляет "str" в начало строки.
PIString & prepend(const PIString & str) {d.prepend(str.d); return *this;}
//! \~english Insert symbol `c` at the begin of string
//! \~russian Вставляет символ `c` в начало строки
PIString & prepend(const PIChar c) {PIDeque<PIChar>::prepend(c); return *this;}
//! \~english Insert character `c` at the begin of string.
//! \~russian Вставляет символ `c` в начало строки.
PIString & prepend(const PIChar c) {d.prepend(c); return *this;}
//! \~english Insert symbol `c` at the begin of string
//! \~russian Вставляет символ `c` в начало строки
PIString & prepend(const char c) {PIDeque<PIChar>::prepend(PIChar(c)); return *this;}
//! \~english Insert character `c` at the begin of string.
//! \~russian Вставляет символ `c` в начало строки.
PIString & prepend(const char c) {d.prepend(PIChar(c)); return *this;}
//! \~english Insert string "str" at the begin of string
//! \~russian Вставляет "str" в начало строки
//! \~english Insert string "str" at the begin of string.
//! \~russian Вставляет "str" в начало строки.
PIString & push_front(const char * str) {insert(0, str); return *this;}
//! \~english Insert string "str" at the begin of string
//! \~russian Вставляет "str" в начало строки
PIString & push_front(const PIString & str) {insert(0, str); return *this;}
//! \~english Insert string "str" at the begin of string.
//! \~russian Вставляет "str" в начало строки.
PIString & push_front(const PIString & str) {d.push_front(str.d); return *this;}
//! \~english Insert symbol `c` at the begin of string
//! \~russian Вставляет символ `c` в начало строки
PIString & push_front(const PIChar c) {PIDeque<PIChar>::push_front(c); return *this;}
//! \~english Insert character `c` at the begin of string.
//! \~russian Вставляет символ `c` в начало строки.
PIString & push_front(const PIChar c) {d.push_front(c); return *this;}
//! \~english Insert symbol `c` at the begin of string
//! \~russian Вставляет символ `c` в начало строки
PIString & push_front(const char c) {PIDeque<PIChar>::push_front(PIChar(c)); return *this;}
//! \~english Insert character `c` at the begin of string.
//! \~russian Вставляет символ `c` в начало строки.
PIString & push_front(const char c) {d.push_front(PIChar(c)); return *this;}
//! \~english Insert string "str" at the end of string
//! \~russian Вставляет "str" в конец строки
//! \~english Insert string "str" at the end of string.
//! \~russian Вставляет "str" в конец строки.
PIString & append(const char * str) {*this += str; return *this;}
//! \~english Insert string "str" at the end of string
//! \~russian Вставляет "str" в конец строки
PIString & append(const PIString & str) {*this += str; return *this;}
//! \~english Insert string "str" at the end of string.
//! \~russian Вставляет "str" в конец строки.
PIString & append(const PIString & str) {d.append(str.d); return *this;}
//! \~english Insert symbol `c` at the end of string
//! \~russian Вставляет символ `c` в конец строки
PIString & append(const PIChar c) {PIDeque<PIChar>::append(c); return *this;}
PIString & append(const PIConstChars & str) {*this += str; return *this;}
//! \~english Insert symbol `c` at the end of string
//! \~russian Вставляет символ `c` в конец строки
PIString & append(const char c) {PIDeque<PIChar>::append(PIChar(c)); return *this;}
//! \~english Insert character `c` at the end of string.
//! \~russian Вставляет символ `c` в конец строки.
PIString & append(const PIChar c) {d.append(c); return *this;}
//! \~english Insert string "str" at the end of string
//! \~russian Вставляет "str" в конец строки
//! \~english Insert character `c` at the end of string.
//! \~russian Вставляет символ `c` в конец строки.
PIString & append(const char c) {d.append(PIChar(c)); return *this;}
//! \~english Insert string "str" at the end of string.
//! \~russian Вставляет "str" в конец строки.
PIString & push_back(const char * str) {*this += str; return *this;}
//! \~english Insert string "str" at the end of string
//! \~russian Вставляет "str" в конец строки
PIString & push_back(const PIString & str) {*this += str; return *this;}
//! \~english Insert string "str" at the end of string.
//! \~russian Вставляет "str" в конец строки.
PIString & push_back(const PIString & str) {d.push_back(str.d); return *this;}
//! \~english Insert symbol `c` at the end of string
//! \~russian Вставляет символ `c` в конец строки
PIString & push_back(const PIChar c) {PIDeque<PIChar>::push_back(c); return *this;}
PIString & push_back(const PIConstChars & str) {*this += str; return *this;}
//! \~english Insert symbol `c` at the end of string
//! \~russian Вставляет символ `c` в конец строки
PIString & push_back(const char c) {PIDeque<PIChar>::push_back(PIChar(c)); return *this;}
//! \~english Insert character `c` at the end of string.
//! \~russian Вставляет символ `c` в конец строки.
PIString & push_back(const PIChar c) {d.push_back(c); return *this;}
//! \~english Insert character `c` at the end of string.
//! \~russian Вставляет символ `c` в конец строки.
PIString & push_back(const char c) {d.push_back(PIChar(c)); return *this;}
//! \~english Returns part of string from symbol at index "start" and maximum length "len"
//! \~russian Возвращает подстроку от символа "start" и максимальной длиной "len"
//! \~english Returns part of string from character at index "start" and maximum length "len".
//! \~russian Возвращает подстроку от символа "start" и максимальной длиной "len".
PIString mid(const int start, const int len = -1) const;
//! \~english Synonym of \a mid()
//! \~russian Аналог \a mid()
//! \~english Synonym of \a mid().
//! \~russian Аналог \a mid().
PIString subString(const int start, const int len = -1) const {return mid(start, len);}
//! \~english Returns part of string from start and maximum length "len"
//! \~russian Возвращает подстроку от начала и максимальной длиной "len"
//! \~english Returns part of string from start and maximum length "len".
//! \~russian Возвращает подстроку от начала и максимальной длиной "len".
//! \~\details
//! \~\code
//! PIString s("0123456789");
@@ -385,8 +521,8 @@ public:
//! \~\sa \a mid(), \a right()
PIString left(const int len) const {return len <= 0 ? PIString() : mid(0, len);}
//! \~english Returns part of string at end and maximum length "len"
//! \~russian Возвращает подстроку максимальной длиной "len" и до конца
//! \~english Returns part of string at end and maximum length "len".
//! \~russian Возвращает подстроку максимальной длиной "len" и до конца.
//! \~\details
//! \~\code
//! PIString s("0123456789");
@@ -398,12 +534,12 @@ public:
//! \~\sa \a mid(), \a left()
PIString right(const int len) const {return len <= 0 ? PIString() : mid(size() - len, len);}
//! \~english Remove part of string from symbol as index "start" and maximum length "len" and return this string
//! \~russian Удаляет часть строки от символа "start" и максимальной длины "len", возвращает эту строку
//! \~english Remove part of string from character as index "start" and maximum length "len" and return this string.
//! \~russian Удаляет часть строки от символа "start" и максимальной длины "len", возвращает эту строку.
PIString & cutMid(const int start, const int len);
//! \~english Remove part of string from start and maximum length "len" and return this string
//! \~russian Удаляет часть строки от начала и максимальной длины "len", возвращает эту строку
//! \~english Remove part of string from start and maximum length "len" and return this string.
//! \~russian Удаляет часть строки от начала и максимальной длины "len", возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s("0123456789");
@@ -417,8 +553,8 @@ public:
//! \~\sa \a cutMid(), \a cutRight()
PIString & cutLeft(const int len) {return len <= 0 ? *this : cutMid(0, len);}
//! \~english Remove part of string at end and maximum length "len" and return this string
//! \~russian Удаляет часть строки максимальной длины "len" от конца, возвращает эту строку
//! \~english Remove part of string at end and maximum length "len" and return this string.
//! \~russian Удаляет часть строки максимальной длины "len" от конца, возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s("0123456789");
@@ -432,12 +568,12 @@ public:
//! \~\sa \a cutMid(), \a cutLeft()
PIString & cutRight(const int len) {return len <= 0 ? *this : cutMid(size() - len, len);}
//! \~english Remove spaces at the start and at the end of string and return this string
//! \~russian Удаляет пробельные символы с начала и конца строки и возвращает эту строку
//! \~english Remove spaces at the start and at the end of string and return this string.
//! \~russian Удаляет пробельные символы с начала и конца строки и возвращает эту строку.
PIString & trim();
//! \~english Returns copy of this string without spaces at the start and at the end
//! \~russian Возвращает копию этой строки без пробельных символов с начала и конца
//! \~english Returns copy of this string without spaces at the start and at the end.
//! \~russian Возвращает копию этой строки без пробельных символов с начала и конца.
//! \~\details
//! \~\code
//! PIString s(" \t string \n");
@@ -447,12 +583,12 @@ public:
//! \~\sa \a trim()
PIString trimmed() const;
//! \~english Replace part of string from index "from" and maximum length "len" with string "with" and return this string
//! \~russian Заменяет часть строки от символа "from" и максимальной длины "len" строкой "with", возвращает эту строку
//! \~english Replace part of string from index "from" and maximum length "len" with string "with" and return this string.
//! \~russian Заменяет часть строки от символа "from" и максимальной длины "len" строкой "with", возвращает эту строку.
PIString & replace(const int from, const int count, const PIString & with);
//! \~english Replace part copy of this string from index "from" and maximum length "len" with string "with"
//! \~russian Заменяет часть копии этой строки от символа "from" и максимальной длины "len" строкой "with"
//! \~english Replace part copy of this string from index "from" and maximum length "len" with string "with".
//! \~russian Заменяет часть копии этой строки от символа "from" и максимальной длины "len" строкой "with".
//! \~\details
//! \~\code
//! PIString s("0123456789");
@@ -462,15 +598,15 @@ public:
//! \~\sa \a replace(), \a replaceAll()
PIString replaced(const int from, const int count, const PIString & with) const {PIString str(*this); str.replace(from, count, with); return str;}
//! \~english Replace first founded substring "what" with string "with" and return this string
//! \~russian Заменяет первую найденную подстроку "what" строкой "with", возвращает эту строку
//! \~english Replace first founded substring "what" with string "with" and return this string.
//! \~russian Заменяет первую найденную подстроку "what" строкой "with", возвращает эту строку.
PIString & replace(const PIString & what, const PIString & with, bool * ok = 0);
//! \~english Replace in string copy first founded substring "what" with string "with"
//! \~russian Заменяет в копии строки первую найденную подстроку "what" строкой "with"
//! \~english Replace in string copy first founded substring "what" with string "with".
//! \~russian Заменяет в копии строки первую найденную подстроку "what" строкой "with".
//! \~\details
//! \~english If "ok" is not null, it set to "true" if something was replaced
//! \~russian Если "ok" не null, то устанавливает в "true" если замена произведена
//! \~english If "ok" is not null, it set to "true" if something was replaced.
//! \~russian Если "ok" не null, то устанавливает в "true" если замена произведена.
//! \~\code
//! PIString s("pip string");
//! bool ok;
@@ -480,43 +616,43 @@ public:
//! \~\sa \a replaced(), \a replaceAll()
PIString replaced(const PIString & what, const PIString & with, bool * ok = 0) const {PIString str(*this); str.replace(what, with, ok); return str;}
//! \~english Replace all founded substrings "what" with strings "with" and return this string
//! \~russian Заменяет все найденные подстроки "what" строками "with", возвращает эту строку
//! \~english Replace all founded substrings "what" with strings "with" and return this string.
//! \~russian Заменяет все найденные подстроки "what" строками "with", возвращает эту строку.
PIString & replaceAll(const PIString & what, const PIString & with);
//! \~english Replace all founded substrings "what" with symbols "with" and return this string
//! \~russian Заменяет все найденные подстроки "what" символами "with", возвращает эту строку
//! \~english Replace all founded substrings "what" with characters "with" and return this string.
//! \~russian Заменяет все найденные подстроки "what" символами "with", возвращает эту строку.
PIString & replaceAll(const PIString & what, const char with);
//! \~english Replace all founded symbols "what" with symbols "with" and return this string
//! \~russian Заменяет все найденные символы "what" символами "with", возвращает эту строку
//! \~english Replace all founded characters "what" with characters "with" and return this string.
//! \~russian Заменяет все найденные символы "what" символами "with", возвращает эту строку.
PIString & replaceAll(const char what, const char with);
//! \~english Replace all founded substrings "what" with strings "with" in string copy
//! \~russian Заменяет в копии строки все найденные подстроки "what" строками "with"
//! \~english Replace all founded substrings "what" with strings "with" in string copy.
//! \~russian Заменяет в копии строки все найденные подстроки "what" строками "with".
//! \~\sa \a replaceAll()
PIString replacedAll(const PIString & what, const PIString & with) const {PIString str(*this); str.replaceAll(what, with); return str;}
//! \~english Replace all founded substrings "what" with symbols "with" in string copy
//! \~russian Заменяет в копии строки все найденные подстроки "what" символами "with"
//! \~english Replace all founded substrings "what" with characters "with" in string copy.
//! \~russian Заменяет в копии строки все найденные подстроки "what" символами "with".
//! \~\sa \a replaceAll()
PIString replacedAll(const PIString & what, const char with) const {PIString str(*this); str.replaceAll(what, with); return str;}
//! \~english Replace all founded symbols "what" with symbols "with" in string copy
//! \~russian Заменяет в копии строки все найденные символы "what" символами "with"
//! \~english Replace all founded characters "what" with characters "with" in string copy.
//! \~russian Заменяет в копии строки все найденные символы "what" символами "with".
//! \~\sa \a replaceAll()
PIString replacedAll(const char what, const char with) const {PIString str(*this); str.replaceAll(what, with); return str;}
//! \~english Remove all founded substrings "what" and return this string
//! \~russian Удаляет все найденные подстроки "what", возвращает эту строку
//! \~english Remove all founded substrings "what" and return this string.
//! \~russian Удаляет все найденные подстроки "what", возвращает эту строку.
PIString & removeAll(const PIString & str);
//! \~english Remove all founded symbols "what" and return this string
//! \~russian Удаляет все найденные символы "what", возвращает эту строку
PIString & removeAll(char c) {PIDeque<PIChar>::removeAll(PIChar(c)); return *this;}
//! \~english Remove all founded characters "what" and return this string.
//! \~russian Удаляет все найденные символы "what", возвращает эту строку.
PIString & removeAll(char c) {d.removeAll(PIChar(c)); return *this;}
//! \~english Repeat content of string "times" times and return this string
//! \~russian Повторяет содержимое строки "times" раз и возвращает эту строку
//! \~english Repeat content of string "times" times and return this string.
//! \~russian Повторяет содержимое строки "times" раз и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s(" :-) ");
@@ -526,8 +662,8 @@ public:
//! \~\sa \a repeated()
PIString & repeat(int times) {PIString ss(*this); times--; piForTimes (times) *this += ss; return *this;}
//! \~english Returns repeated "times" times string
//! \~russian Возвращает повторённую "times" раз строку
//! \~english Returns repeated "times" times string.
//! \~russian Возвращает повторённую "times" раз строку.
//! \~\details
//! \~\code
//! PIString s(" :-) ");
@@ -537,18 +673,18 @@ public:
//! \~\sa \a repeat()
PIString repeated(int times) const {PIString ss(*this); return ss.repeat(times);}
//! \~english Insert symbol "c" after index "index" and return this string
//! \~russian Вставляет символ "c" после позиции "index" и возвращает эту строку
//! \~english Insert character "c" after index "index" and return this string.
//! \~russian Вставляет символ "c" после позиции "index" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s("pp");
//! s.insert(1, "i");
//! piCout << s; // s = "pip"
//! \endcode
PIString & insert(const int index, const PIChar c) {PIDeque<PIChar>::insert(index, c); return *this;}
PIString & insert(const int index, const PIChar c) {d.insert(index, c); return *this;}
//! \~english Insert symbol "c" after index "index" and return this string
//! \~russian Вставляет символ "c" после позиции "index" и возвращает эту строку
//! \~english Insert character "c" after index "index" and return this string.
//! \~russian Вставляет символ "c" после позиции "index" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s("pp");
@@ -557,8 +693,8 @@ public:
//! \endcode
PIString & insert(const int index, const char c) {return insert(index, PIChar(c));}
//! \~english Insert string "str" after index "index" and return this string
//! \~russian Вставляет строку "str" после позиции "index" и возвращает эту строку
//! \~english Insert string "str" after index "index" and return this string.
//! \~russian Вставляет строку "str" после позиции "index" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s("stg");
@@ -567,8 +703,8 @@ public:
//! \endcode
PIString & insert(const int index, const PIString & str);
//! \~english Insert string "str" after index "index" and return this string
//! \~russian Вставляет строку "str" после позиции "index" и возвращает эту строку
//! \~english Insert string "str" after index "index" and return this string.
//! \~russian Вставляет строку "str" после позиции "index" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s("stg");
@@ -577,8 +713,8 @@ public:
//! \endcode
PIString & insert(const int index, const char * c) {return insert(index, PIString(c));}
//! \~english Enlarge string to length "len" by addition symbols "c" at the end, and return this string
//! \~russian Увеличивает длину строки до "len" добавлением символов "c" в конец и возвращает эту строку
//! \~english Enlarge string to length "len" by addition characters "c" at the end, and return this string.
//! \~russian Увеличивает длину строки до "len" добавлением символов "c" в конец и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s("str");
@@ -588,10 +724,10 @@ public:
//! piCout << s; // s = "str___"
//! \endcode
//! \~\sa \a expandLeftTo(), \a expandedRightTo(), \a expandedLeftTo()
PIString & expandRightTo(const int len, const PIChar c) {if (len > length()) resize(len, c); return *this;}
PIString & expandRightTo(const int len, const PIChar c) {if (len > d.size_s()) d.resize(len, c); return *this;}
//! \~english Enlarge string to length "len" by addition symbols "c" at the begin, and return this string
//! \~russian Увеличивает длину строки до "len" добавлением символов "c" в начало и возвращает эту строку
//! \~english Enlarge string to length "len" by addition characters "c" at the begin, and return this string.
//! \~russian Увеличивает длину строки до "len" добавлением символов "c" в начало и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s("str");
@@ -601,10 +737,10 @@ public:
//! piCout << s; // s = "___str"
//! \endcode
//! \~\sa \a expandRightTo(), \a expandedRightTo(), \a expandedLeftTo()
PIString & expandLeftTo(const int len, const PIChar c) {if (len > length()) insert(0, PIString(len - length(), c)); return *this;}
PIString & expandLeftTo(const int len, const PIChar c) {if (len > d.size_s()) insert(0, PIString(len - d.size_s(), c)); return *this;}
//! \~english Enlarge copy of this string to length "len" by addition symbols "c" at the end
//! \~russian Увеличивает длину копии этой строки до "len" добавлением символов "c" в конец
//! \~english Enlarge copy of this string to length "len" by addition characters "c" at the end.
//! \~russian Увеличивает длину копии этой строки до "len" добавлением символов "c" в конец.
//! \~\details
//! \~\code
//! PIString s("str");
@@ -614,8 +750,8 @@ public:
//! \~\sa \a expandRightTo(), \a expandLeftTo(), \a expandedLeftTo()
PIString expandedRightTo(const int len, const PIChar c) const {return PIString(*this).expandRightTo(len, c);}
//! \~english Enlarge copy of this string to length "len" by addition symbols "c" at the begin
//! \~russian Увеличивает длину копии этой строки до "len" добавлением символов "c" в начало
//! \~english Enlarge copy of this string to length "len" by addition characters "c" at the begin.
//! \~russian Увеличивает длину копии этой строки до "len" добавлением символов "c" в начало.
//! \~\details
//! \~\code
//! PIString s("str");
@@ -625,8 +761,8 @@ public:
//! \~\sa \a expandRightTo(), \a expandLeftTo(), \a expandedRightTo()
PIString expandedLeftTo(const int len, const PIChar c) const {return PIString(*this).expandLeftTo(len, c);}
//! \~english Add "c" symbols at the beginning and end, and return this string
//! \~russian Добавляет символ "c" в начало и конец и возвращает эту строку
//! \~english Add "c" characters at the beginning and end, and return this string.
//! \~russian Добавляет символ "c" в начало и конец и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s("str");
@@ -634,10 +770,10 @@ public:
//! piCout << s; // s = ""str""
//! \endcode
//! \~\sa \a quoted()
PIString & quote(PIChar c = PIChar('"')) {insert(0, c); *this += c; return *this;}
PIString & quote(PIChar c = PIChar('"')) {d.prepend(c); d.append(c); return *this;}
//! \~english Returns quoted copy of this string
//! \~russian Возвращает копию строки с добавленным в начало и конец символом "c"
//! \~english Returns quoted copy of this string.
//! \~russian Возвращает копию строки с добавленным в начало и конец символом "c".
//! \~\details
//! \~\code
//! PIString s("str");
@@ -647,8 +783,8 @@ public:
//! \~\sa \a quote()
PIString quoted(PIChar c = PIChar('"')) {return PIString(*this).quote(c);}
//! \~english Reverse string and return this string
//! \~russian Разворачивает и возвращает эту строку
//! \~english Reverse string and return this string.
//! \~russian Разворачивает и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s("0123456789");
@@ -656,10 +792,10 @@ public:
//! piCout << s; // s = "9876543210"
//! \endcode
//! \~\sa \a reversed()
PIString & reverse() {PIDeque<PIChar>::reverse(); return *this;}
PIString & reverse() {d.reverse(); return *this;}
//! \~english Reverse copy of this string
//! \~russian Разворачивает копию этой строки
//! \~english Reverse copy of this string.
//! \~russian Разворачивает копию этой строки.
//! \~\details
//! \~\code
//! PIString s("0123456789");
@@ -669,13 +805,13 @@ public:
//! \~\sa \a reverse()
PIString reversed() const {PIString ret(*this); return ret.reverse();}
//! \~english Fit string to maximum size "size" by inserting ".." at position "pos" and return this string
//! \~russian Уменьшает строку до размера "size", вставляя ".." в положение "pos" и возвращает эту строку
//! \~english Fit string to maximum size "size" by inserting ".." at position "pos" and return this string.
//! \~russian Уменьшает строку до размера "size", вставляя ".." в положение "pos" и возвращает эту строку.
//! \~\sa \a elided()
PIString & elide(int size, float pos = ElideCenter);
//! \~english Fit copy of this string to maximum size "size" by inserting ".." at position "pos"
//! \~russian Уменьшает копию этой строки до размера "size", вставляя ".." в положение "pos"
//! \~english Fit copy of this string to maximum size "size" by inserting ".." at position "pos".
//! \~russian Уменьшает копию этой строки до размера "size", вставляя ".." в положение "pos".
//! \~\details
//! \~\code
//! piCout << PIString("123456789ABCDEF").elided(8, PIString::ElideLeft); // ..ABCDEF
@@ -687,8 +823,8 @@ public:
PIString elided(int size, float pos = ElideCenter) const {PIString str(*this); str.elide(size, pos); return str;}
//! \~english Take a part of string from symbol at index "start" and maximum length "len" and return it
//! \~russian Извлекает часть строки от символа "start" максимальной длины "len" и возвращает её
//! \~english Take a part of string from character at index "start" and maximum length "len" and return it.
//! \~russian Извлекает часть строки от символа "start" максимальной длины "len" и возвращает её.
//! \~\details
//! \~\code
//! PIString s("0123456789");
@@ -698,8 +834,8 @@ public:
//! \~\sa \a takeLeft, \a takeRight()
PIString takeMid(const int start, const int len = -1) {PIString ret(mid(start, len)); cutMid(start, len); return ret;}
//! \~english Take a part from the begin of string with maximum length "len" and return it
//! \~russian Извлекает часть строки от начала максимальной длины "len" и возвращает её
//! \~english Take a part from the begin of string with maximum length "len" and return it.
//! \~russian Извлекает часть строки от начала максимальной длины "len" и возвращает её.
//! \~\details
//! \~\code
//! PIString s("0123456789");
@@ -709,8 +845,8 @@ public:
//! \~\sa \a takeMid(), \a takeRight()
PIString takeLeft(const int len) {PIString ret(left(len)); cutLeft(len); return ret;}
//! \~english Take a part from the end of string with maximum length "len" and return it
//! \~russian Извлекает часть строки с конца максимальной длины "len" и возвращает её
//! \~english Take a part from the end of string with maximum length "len" and return it.
//! \~russian Извлекает часть строки с конца максимальной длины "len" и возвращает её.
//! \~\details
//! \~\code
//! PIString s("0123456789");
@@ -720,73 +856,69 @@ public:
//! \~\sa \a takeMid(), \a takeLeft()
PIString takeRight(const int len) {PIString ret(right(len)); cutRight(len); return ret;}
//! \~english Take a symbol from the begin of this string and return it
//! \~russian Извлекает символ с начала строки и возвращает его как строку
//! \~english Take a character from the begin of this string and return it.
//! \~russian Извлекает символ с начала строки и возвращает его как строку.
PIString takeSymbol();
//! \~english Take a word from the begin of this string and return it
//! \~russian Извлекает слово с начала строки и возвращает его
//! \~english Take a word from the begin of this string and return it.
//! \~russian Извлекает слово с начала строки и возвращает его.
PIString takeWord();
//! \~english Take a word with letters, numbers and '_' symbols from the begin of this string and return it
//! \~russian Извлекает слово из букв, цифр и симолов '_' с начала строки и возвращает его
//! \~english Take a word with letters, numbers and '_' characters from the begin of this string and return it.
//! \~russian Извлекает слово из букв, цифр и симолов '_' с начала строки и возвращает его.
PIString takeCWord();
//! \~english Take a line from the begin of this string and return it
//! \~russian Извлекает строку текста (до новой строки) с начала строки и возвращает её
//! \~english Take a line from the begin of this string and return it.
//! \~russian Извлекает строку текста (до новой строки) с начала строки и возвращает её.
PIString takeLine();
//! \~english Take a number with C-format from the begin of this string and return it
//! \~russian Извлекает число в C-формате с начала строки и возвращает его как строку
//! \~english Take a number with C-format from the begin of this string and return it.
//! \~russian Извлекает число в C-формате с начала строки и возвращает его как строку.
PIString takeNumber();
//! \~english Take a range between "start" and "end" symbols from the begin of this string and return it
//! \~russian Извлекает диапазон между символами "start" и "end" с начала строки и возвращает его
//! \~english Take a range between "start" and "end" characters from the begin of this string and return it.
//! \~russian Извлекает диапазон между символами "start" и "end" с начала строки и возвращает его.
PIString takeRange(const PIChar start, const PIChar end, const PIChar shield = '\\');
//! \~english Returns string in brackets "start" and "end" symbols from the beginning
//! \~russian Возвращает строку между символами "start" и "end" с начала строки
//! \~english Returns string in brackets "start" and "end" characters from the beginning.
//! \~russian Возвращает строку между символами "start" и "end" с начала строки.
PIString inBrackets(const PIChar start, const PIChar end) const;
//! \~english Returns bytes count of this string in system codepage
//! \~russian Возвращает объем строки в системной кодировке
int lengthAscii() const;
//! \~english Returns \c char * representation of this string in system codepage
//! \~russian Возвращает \c char * представление строки в системной кодировке
//! \~english Returns \c char * representation of this string in system codepage.
//! \~russian Возвращает \c char * представление строки в системной кодировке.
const char * data() const;
//! \~english Returns \c char * representation of this string in terminal codepage
//! \~russian Возвращает \c char * представление строки в кодировке консоли
//! \~english Returns \c char * representation of this string in terminal codepage.
//! \~russian Возвращает \c char * представление строки в кодировке консоли.
const char * dataConsole() const;
//! \~english Returns \c char * representation of this string in UTF-8
//! \~russian Возвращает \c char * представление строки в кодировке UTF-8
//! \~english Returns \c char * representation of this string in UTF-8.
//! \~russian Возвращает \c char * представление строки в кодировке UTF-8.
const char * dataUTF8() const;
//! \~english Returns \c char * representation of this string in ASCII
//! \~russian Возвращает \c char * представление строки в кодировке ASCII
//! \~english Returns \c char * representation of this string in ASCII.
//! \~russian Возвращает \c char * представление строки в кодировке ASCII.
const char * dataAscii() const;
//! \~english Returns hash
//! \~russian Возвращает хэш
//! \~english Returns hash of string
//! \~russian Возвращает хэш строки
uint hash() const;
//! \~english Returns \a PIByteArray contains \a data() of this string without terminating null-char
//! \~russian Возвращает \a PIByteArray содержащий \a data() строки без завершающего нулевого байта
PIByteArray toByteArray() const {buildData(__utf8name__); return data_.resized(data_.size_s() - 1);}
//! \~english Same as \a toUTF8().
//! \~russian Тоже самое, что \a toUTF8().
PIByteArray toByteArray() const {return toUTF8();}
//! \~english Returns \a PIByteArray contains \a dataUTF8() of this string without terminating null-char
//! \~russian Возвращает \a PIByteArray содержащий \a dataUTF8() строки без завершающего нулевого байта
//! \~english Returns \a PIByteArray contains \a dataUTF8() of this string without terminating null-char.
//! \~russian Возвращает \a PIByteArray содержащий \a dataUTF8() строки без завершающего нулевого байта.
PIByteArray toUTF8() const;
//! \~english Returns \a PIByteArray contains custom charset representation of this string without terminating null-char
//! \~russian Возвращает \a PIByteArray содержащий строку в указанной кодировке без завершающего нулевого байта
//! \~english Returns \a PIByteArray contains custom charset representation of this string without terminating null-char.
//! \~russian Возвращает \a PIByteArray содержащий строку в указанной кодировке без завершающего нулевого байта.
PIByteArray toCharset(const char * c) const;
//! \~english Split string with delimiter "delim" to \a PIStringList
//! \~russian Разделяет строку в \a PIStringList через разделитель "delim"
//! \~english Split string with delimiter "delim" to \a PIStringList.
//! \~russian Разделяет строку в \a PIStringList через разделитель "delim".
//! \~\details
//! \~\code
//! PIString s("1 2 3");
@@ -795,40 +927,45 @@ public:
PIStringList split(const PIString & delim) const;
//! \~english Convert each symbol in copied string to upper case
//! \~russian Преобразует каждый символ в скопированной строке в верхний регистр
//! \~english Convert each character in copied string to upper case.
//! \~russian Преобразует каждый символ в скопированной строке в верхний регистр.
PIString toUpperCase() const;
//! \~english Convert each symbol in copied string to lower case
//! \~russian Преобразует каждый символ в скопированной строке в нижний регистр
//! \~english Convert each character in copied string to lower case.
//! \~russian Преобразует каждый символ в скопированной строке в нижний регистр.
PIString toLowerCase() const;
// TODO: doxygen
PIString toNativeDecimalPoints() const;
//! \~english Returns if string contains symbol "c"
//! \~russian Возвращает содержит ли строка символ "c"
bool contains(const char c) const {return PIDeque<PIChar>::contains(PIChar(c));}
//! \~english Returns if string contains character "c".
//! \~russian Возвращает содержит ли строка символ "c".
bool contains(const char c) const {return d.contains(PIChar(c));}
//! \~english Returns if string contains substring "str"
//! \~russian Возвращает содержит ли строка подстроку "str"
//! \~english Returns if string contains substring "str".
//! \~russian Возвращает содержит ли строка подстроку "str".
bool contains(const char * str) const {return contains(PIString(str));}
//! \~english Returns if string contains substring "str"
//! \~russian Возвращает содержит ли строка подстроку "str"
//! \~english Returns if string contains substring "str".
//! \~russian Возвращает содержит ли строка подстроку "str".
bool contains(const PIString & str) const {return find(str) >= 0;}
//! \~english Search symbol "c" from symbol at index "start" and return first occur position
//! \~russian Ищет символ "c" от символа "start" и возвращает первое вхождение
//! \~english Search character "c" from character at index "start" and return first occur position.
//! \~russian Ищет символ "c" от символа "start" и возвращает первое вхождение.
int find(const char c, const int start = 0) const;
//! \~english Search substring "str" from symbol at index "start" and return first occur position
//! \~russian Ищет подстроку "str" от символа "start" и возвращает первое вхождение
//! \~english Search character "c" from character at index "start" and return first occur position.
//! \~russian Ищет символ "c" от символа "start" и возвращает первое вхождение.
int find(PIChar c, const int start = 0) const {return d.indexOf(c, start);}
//! \~english Search substring "str" from character at index "start" and return first occur position.
//! \~russian Ищет подстроку "str" от символа "start" и возвращает первое вхождение.
int find(const PIString & str, const int start = 0) const;
//! \~english Search substring "str" from symbol at index "start" and return first occur position
//! \~russian Ищет подстроку "str" от символа "start" и возвращает первое вхождение
//! \~english Search substring "str" from character at index "start" and return first occur position.
//! \~russian Ищет подстроку "str" от символа "start" и возвращает первое вхождение.
//! \~\details
//! \~\code
//! PIString s("012345012345");
@@ -840,12 +977,12 @@ public:
//! \~\sa \a findAny(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
int find(const char * str, const int start = 0) const {return find(PIString(str), start);}
//! \~english Search any symbol of "str" from symbol at index "start" and return first occur position
//! \~russian Ищет любой символ строки "str" от симола "start" и возвращает первое вхождение
//! \~english Search any character of "str" from character at index "start" and return first occur position.
//! \~russian Ищет любой символ строки "str" от симола "start" и возвращает первое вхождение.
int findAny(const PIString & str, const int start = 0) const;
//! \~english Search any symbol of "str" from symbol at index "start" and return first occur position
//! \~russian Ищет любой символ строки "str" от симола "start" и возвращает первое вхождение
//! \~english Search any character of "str" from character at index "start" and return first occur position.
//! \~russian Ищет любой символ строки "str" от симола "start" и возвращает первое вхождение.
//! \~\details
//! \~\code
//! piCout << PIString("1.str").findAny(".,:"); // 1
@@ -855,16 +992,20 @@ public:
//! \~\sa \a find(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
int findAny(const char * str, const int start = 0) const {return findAny(PIString(str), start);}
//! \~english Search symbol "c" from symbol at index "start" and return last occur position
//! \~russian Ищет символ "c" от символа "start" и возвращает последнее вхождение
//! \~english Search character "c" from character at index "start" and return last occur position.
//! \~russian Ищет символ "c" от символа "start" и возвращает последнее вхождение.
int findLast(const char c, const int start = 0) const;
//! \~english Search substring "str" from symbol at index "start" and return last occur position
//! \~russian Ищет подстроку "str" от символа "start" и возвращает последнее вхождение
//! \~english Search character "c" from character at index "start" and return last occur position.
//! \~russian Ищет символ "c" от символа "start" и возвращает последнее вхождение.
int findLast(PIChar c, const int start = 0) const;
//! \~english Search substring "str" from character at index "start" and return last occur position.
//! \~russian Ищет подстроку "str" от символа "start" и возвращает последнее вхождение.
int findLast(const PIString & str, const int start = 0) const;
//! \~english Search substring "str" from symbol at index "start" and return last occur position
//! \~russian Ищет подстроку "str" от символа "start" и возвращает последнее вхождение
//! \~english Search substring "str" from character at index "start" and return last occur position.
//! \~russian Ищет подстроку "str" от символа "start" и возвращает последнее вхождение.
//! \~\details
//! \~\code
//! PIString s("012345012345");
@@ -876,12 +1017,12 @@ public:
//! \~\sa \a find(), \a findAny(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
int findLast(const char * str, const int start = 0) const {return findLast(PIString(str), start);}
//! \~english Search any symbol of "str" from symbol at index "start" and return last occur position
//! \~russian Ищет любой символ строки "str" от символа "start" и возвращает последнее вхождение
//! \~english Search any character of "str" from character at index "start" and return last occur position.
//! \~russian Ищет любой символ строки "str" от символа "start" и возвращает последнее вхождение.
int findAnyLast(const PIString & str, const int start = 0) const;
//! \~english Search any symbol of "str" from symbol at index "start" and return last occur position
//! \~russian Ищет любой символ строки "str" от символа "start" и возвращает последнее вхождение
//! \~english Search any character of "str" from character at index "start" and return last occur position.
//! \~russian Ищет любой символ строки "str" от символа "start" и возвращает последнее вхождение.
//! \~\details
//! \~\code
//! piCout << PIString(".str.0").findAnyLast(".,:"); // 4
@@ -891,20 +1032,20 @@ public:
//! \~\sa \a find(), \a findAny(), \a findLast(), \a findWord(), \a findCWord(), \a findRange()
int findAnyLast(const char * str, const int start = 0) const {return findAnyLast(PIString(str), start);}
//! \~english Search word "word" from symbol at index "start" and return first occur position
//! \~russian Ищет слово "word" от симола "start" и возвращает первое вхождение
//! \~english Search word "word" from character at index "start" and return first occur position.
//! \~russian Ищет слово "word" от симола "start" и возвращает первое вхождение.
int findWord(const PIString & word, const int start = 0) const;
//! \~english Search C-word "word" from symbol at index "start" and return first occur position
//! \~russian Ищет C-слово "word" от симола "start" и возвращает первое вхождение
//! \~english Search C-word "word" from character at index "start" and return first occur position.
//! \~russian Ищет C-слово "word" от симола "start" и возвращает первое вхождение.
int findCWord(const PIString & word, const int start = 0) const;
//! \~english Search range start between "start" and "end" symbols at index "start_index" and return first occur position
//! \~russian Ищет начало диапазона между символами "start" и "end" от симола "start" и возвращает первое вхождение
//! \~english Search range start between "start" and "end" characters at index "start_index" and return first occur position.
//! \~russian Ищет начало диапазона между символами "start" и "end" от симола "start" и возвращает первое вхождение.
int findRange(const PIChar start, const PIChar end, const PIChar shield = '\\', const int start_index = 0, int * len = 0) const;
//! \~english Returns number of occurrences of symbol "c"
//! \~russian Возвращает число вхождений символа "c"
//! \~english Returns number of occurrences of character "c".
//! \~russian Возвращает число вхождений символа "c".
//! \~\details
//! \~\code
//! piCout << PIString(".str.0").entries("."); // 2
@@ -912,8 +1053,8 @@ public:
//! \endcode
int entries(const PIChar c) const;
//! \~english Returns number of occurrences of symbol "c"
//! \~russian Возвращает число вхождений символа "c"
//! \~english Returns number of occurrences of character "c".
//! \~russian Возвращает число вхождений символа "c".
//! \~\details
//! \~\code
//! piCout << PIString(".str.0").entries('.'); // 2
@@ -921,40 +1062,56 @@ public:
//! \endcode
int entries(char c) const {return entries(PIChar(c));}
//! \~english Returns if string starts with "str"
//! \~russian Возвращает начинается ли строка со "str"
//! \~english Returns if string starts with "str".
//! \~russian Возвращает начинается ли строка со "str".
bool startsWith(const PIString & str) const;
//! \~english Returns if string ends with "str"
//! \~russian Возвращает оканчивается ли строка на "str"
//! \~english Returns if string ends with "str".
//! \~russian Возвращает оканчивается ли строка на "str".
bool endsWith(const PIString & str) const;
//! \~english Returns symbols length of string
//! \~russian Возвращает длину строки в символах
int length() const {return size();}
//! \~english Returns characters length of string.
//! \~russian Возвращает длину строки в символах.
int length() const {return d.size_s();}
//! \~english Returns \c true if string is empty, i.e. length = 0
//! \~russian Возвращает \c true если строка пустая, т.е. длина = 0
bool isEmpty() const {return (size() == 0 || *this == "");}
//! \~english Returns characters length of string.
//! \~russian Возвращает длину строки в символах.
size_t size() const {return d.size();}
//! \~english Returns \c true if string is not empty, i.e. length > 0
//! \~russian Возвращает \c true если строка непустая, т.е. длина > 0
//! \~english Returns characters length of string.
//! \~russian Возвращает длину строки в символах.
ssize_t size_s() const {return d.size_s();}
//! \~english Returns \c true if string is empty, i.e. length = 0.
//! \~russian Возвращает \c true если строка пустая, т.е. длина = 0.
bool isEmpty() const {if (d.isEmpty()) return true; if (d.at(0) == PIChar()) return true; return false;}
//! \~english Returns \c true if string is not empty, i.e. length > 0.
//! \~russian Возвращает \c true если строка непустая, т.е. длина > 0.
bool isNotEmpty() const {return !isEmpty();}
//! \~english Clear string, will be empty string.
//! \~russian Очищает строку, строка становится пустой.
//! \~\details
//! \~\note
//! \~english Reserved memory will not be released.
//! \~russian Зарезервированная память не освободится.
//! \~\sa \a resize()
void clear() {d.clear();}
//! \~english Returns \c true if string equal "true", "yes", "on" or positive not null numeric value
//! \~russian Возвращает \c true если строка равна "true", "yes", "on" или числу > 0
//! \~english Returns \c true if string equal "true", "yes", "on" or positive not null numeric value.
//! \~russian Возвращает \c true если строка равна "true", "yes", "on" или числу > 0.
bool toBool() const;
//! \~english Returns \c char numeric value of string
//! \~russian Возвращает \c char числовое значение строки
//! \~english Returns \c char numeric value of string.
//! \~russian Возвращает \c char числовое значение строки.
char toChar() const;
//! \~english Returns \c short numeric value of string in base "base"
//! \~russian Возвращает \c short числовое значение строки по основанию "base"
//! \~english Returns \c short numeric value of string in base "base".
//! \~russian Возвращает \c short числовое значение строки по основанию "base".
//! \~\details
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
//! \~\code
//! piCout << PIString("123").toShort(); // 123
//! piCout << PIString("123").toShort(16); // 291
@@ -963,11 +1120,11 @@ public:
//! \endcode
short toShort(int base = -1, bool * ok = 0) const {return short(toNumberBase(*this, base, ok));}
//! \~english Returns \c ushort numeric value of string in base "base"
//! \~russian Возвращает \c ushort числовое значение строки по основанию "base"
//! \~english Returns \c ushort numeric value of string in base "base".
//! \~russian Возвращает \c ushort числовое значение строки по основанию "base".
//! \~\details
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
//! \~\code
//! piCout << PIString("123").toUShort(); // 123
//! piCout << PIString("123").toUShort(16); // 291
@@ -976,11 +1133,11 @@ public:
//! \endcode
ushort toUShort(int base = -1, bool * ok = 0) const {return ushort(toNumberBase(*this, base, ok));}
//! \~english Returns \c int numeric value of string in base "base"
//! \~russian Возвращает \c int числовое значение строки по основанию "base"
//! \~english Returns \c int numeric value of string in base "base".
//! \~russian Возвращает \c int числовое значение строки по основанию "base".
//! \~\details
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
//! \~\code
//! piCout << PIString("123").toInt(); // 123
//! piCout << PIString("123").toInt(16); // 291
@@ -989,11 +1146,11 @@ public:
//! \endcode
int toInt(int base = -1, bool * ok = 0) const {return int(toNumberBase(*this, base, ok));}
//! \~english Returns \c uint numeric value of string in base "base"
//! \~russian Возвращает \c uint числовое значение строки по основанию "base"
//! \~english Returns \c uint numeric value of string in base "base".
//! \~russian Возвращает \c uint числовое значение строки по основанию "base".
//! \~\details
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
//! \~\code
//! piCout << PIString("123").toUInt(); // 123
//! piCout << PIString("123").toUInt(16); // 291
@@ -1002,11 +1159,11 @@ public:
//! \endcode
uint toUInt(int base = -1, bool * ok = 0) const {return uint(toNumberBase(*this, base, ok));}
//! \~english Returns \c long numeric value of string in base "base"
//! \~russian Возвращает \c long числовое значение строки по основанию "base"
//! \~english Returns \c long numeric value of string in base "base".
//! \~russian Возвращает \c long числовое значение строки по основанию "base".
//! \~\details
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
//! \~\code
//! piCout << PIString("123").toLong(); // 123
//! piCout << PIString("123").toLong(16); // 291
@@ -1015,11 +1172,11 @@ public:
//! \endcode
long toLong(int base = -1, bool * ok = 0) const {return long(toNumberBase(*this, base, ok));}
//! \~english Returns \c ulong numeric value of string in base "base"
//! \~russian Возвращает \c ulong числовое значение строки по основанию "base"
//! \~english Returns \c ulong numeric value of string in base "base".
//! \~russian Возвращает \c ulong числовое значение строки по основанию "base".
//! \~\details
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
//! \~\code
//! piCout << PIString("123").toULong(); // 123
//! piCout << PIString("123").toULong(16); // 291
@@ -1028,11 +1185,11 @@ public:
//! \endcode
ulong toULong(int base = -1, bool * ok = 0) const {return ulong(toNumberBase(*this, base, ok));}
//! \~english Returns \c llong numeric value of string in base "base"
//! \~russian Возвращает \c llong числовое значение строки по основанию "base"
//! \~english Returns \c llong numeric value of string in base "base".
//! \~russian Возвращает \c llong числовое значение строки по основанию "base".
//! \~\details
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
//! \~\code
//! piCout << PIString("123").toLLong(); // 123
//! piCout << PIString("123").toLLong(16); // 291
@@ -1041,11 +1198,11 @@ public:
//! \endcode
llong toLLong(int base = -1, bool * ok = 0) const {return toNumberBase(*this, base, ok);}
//! \~english Returns \c ullong numeric value of string in base "base"
//! \~russian Возвращает \c ullong числовое значение строки по основанию "base"
//! \~english Returns \c ullong numeric value of string in base "base".
//! \~russian Возвращает \c ullong числовое значение строки по основанию "base".
//! \~\details
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10
//! \~english If "base" < 0 then base automatically select 16 if string start with "0x", therwise 10.
//! \~russian Если "base" < 0 тогда основание автоматически принимается 16 если строка начинается с "0x", иначе 10.
//! \~\code
//! piCout << PIString("123").toULLong(); // 123
//! piCout << PIString("123").toULLong(16); // 291
@@ -1054,8 +1211,8 @@ public:
//! \endcode
ullong toULLong(int base = -1, bool * ok = 0) const {return ullong(toNumberBase(*this, base, ok));}
//! \~english Returns \c float numeric value of string
//! \~russian Возвращает \c float числовое значение строки
//! \~english Returns \c float numeric value of string.
//! \~russian Возвращает \c float числовое значение строки.
//! \~\details
//! \~\code
//! piCout << PIString("123").toFloat(); // 123
@@ -1064,8 +1221,8 @@ public:
//! \endcode
float toFloat() const;
//! \~english Returns \c double numeric value of string
//! \~russian Возвращает \c double числовое значение строки
//! \~english Returns \c double numeric value of string.
//! \~russian Возвращает \c double числовое значение строки.
//! \~\details
//! \~\code
//! piCout << PIString("123").toDouble(); // 123
@@ -1074,8 +1231,8 @@ public:
//! \endcode
double toDouble() const;
//! \~english Returns \c ldouble numeric value of string
//! \~russian Возвращает \c ldouble числовое значение строки
//! \~english Returns \c ldouble numeric value of string.
//! \~russian Возвращает \c ldouble числовое значение строки.
//! \~\details
//! \~\code
//! piCout << PIString("123").toLDouble(); // 123
@@ -1084,8 +1241,8 @@ public:
//! \endcode
ldouble toLDouble() const;
//! \~english Set string content to text representation of "value" in base "base" and return this string
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку
//! \~english Set string content to text representation of "value" in base "base" and return this string.
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s;
@@ -1094,10 +1251,10 @@ public:
//! s.setNumber(123, 16);
//! piCout << s; // 7B
//! \endcode
PIString & setNumber(const short value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
PIString & setNumber(const short value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
//! \~english Set string content to text representation of "value" in base "base" and return this string
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку
//! \~english Set string content to text representation of "value" in base "base" and return this string.
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s;
@@ -1106,10 +1263,10 @@ public:
//! s.setNumber(123, 16);
//! piCout << s; // 7B
//! \endcode
PIString & setNumber(const ushort value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
PIString & setNumber(const ushort value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
//! \~english Set string content to text representation of "value" in base "base" and return this string
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку
//! \~english Set string content to text representation of "value" in base "base" and return this string.
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s;
@@ -1118,10 +1275,10 @@ public:
//! s.setNumber(123, 16);
//! piCout << s; // 7B
//! \endcode
PIString & setNumber(const int value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
PIString & setNumber(const int value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
//! \~english Set string content to text representation of "value" in base "base" and return this string
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку
//! \~english Set string content to text representation of "value" in base "base" and return this string.
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s;
@@ -1130,10 +1287,10 @@ public:
//! s.setNumber(123, 16);
//! piCout << s; // 7B
//! \endcode
PIString & setNumber(const uint value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
PIString & setNumber(const uint value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
//! \~english Set string content to text representation of "value" in base "base" and return this string
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку
//! \~english Set string content to text representation of "value" in base "base" and return this string.
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s;
@@ -1142,10 +1299,10 @@ public:
//! s.setNumber(123, 16);
//! piCout << s; // 7B
//! \endcode
PIString & setNumber(const long value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
PIString & setNumber(const long value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
//! \~english Set string content to text representation of "value" in base "base" and return this string
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку
//! \~english Set string content to text representation of "value" in base "base" and return this string.
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s;
@@ -1154,10 +1311,10 @@ public:
//! s.setNumber(123, 16);
//! piCout << s; // 7B
//! \endcode
PIString & setNumber(const ulong value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
PIString & setNumber(const ulong value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
//! \~english Set string content to text representation of "value" in base "base" and return this string
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку
//! \~english Set string content to text representation of "value" in base "base" and return this string.
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s;
@@ -1166,10 +1323,10 @@ public:
//! s.setNumber(123, 16);
//! piCout << s; // 7B
//! \endcode
PIString & setNumber(const llong & value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
PIString & setNumber(const llong & value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
//! \~english Set string content to text representation of "value" in base "base" and return this string
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку
//! \~english Set string content to text representation of "value" in base "base" and return this string.
//! \~russian Устанавливает содержимое строки в текстовое представление "value" по основанию "base" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s;
@@ -1178,10 +1335,10 @@ public:
//! s.setNumber(123, 16);
//! piCout << s; // 7B
//! \endcode
PIString & setNumber(const ullong & value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;}
PIString & setNumber(const ullong & value, int base = 10, bool * ok = 0) {*this = PIString::fromNumber(value, base, ok); return *this;}
//! \~english Set string content to text representation of "value" with format "format" and precision "precision" and return this string
//! \~russian Устанавливает содержимое строки в текстовое представление "value" в формате "format" и точностью "precision" и возвращает эту строку
//! \~english Set string content to text representation of "value" with format "format" and precision "precision" and return this string.
//! \~russian Устанавливает содержимое строки в текстовое представление "value" в формате "format" и точностью "precision" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s;
@@ -1196,10 +1353,10 @@ public:
//! s.setNumber(123456789., 'f', 0);
//! piCout << s; // 123456789
//! \endcode
PIString & setNumber(const float value, char format = 'f', int precision = 8) {clear(); *this += PIString::fromNumber(value, format, precision); return *this;}
PIString & setNumber(const float value, char format = 'f', int precision = 8) {*this = PIString::fromNumber(value, format, precision); return *this;}
//! \~english Set string content to text representation of "value" with format "format" and precision "precision" and return this string
//! \~russian Устанавливает содержимое строки в текстовое представление "value" в формате "format" и точностью "precision" и возвращает эту строку
//! \~english Set string content to text representation of "value" with format "format" and precision "precision" and return this string.
//! \~russian Устанавливает содержимое строки в текстовое представление "value" в формате "format" и точностью "precision" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s;
@@ -1214,10 +1371,10 @@ public:
//! s.setNumber(123456789., 'f', 0);
//! piCout << s; // 123456789
//! \endcode
PIString & setNumber(const double & value, char format = 'f', int precision = 8) {clear(); *this += PIString::fromNumber(value, format, precision); return *this;}
PIString & setNumber(const double & value, char format = 'f', int precision = 8) {*this = PIString::fromNumber(value, format, precision); return *this;}
//! \~english Set string content to text representation of "value" with format "format" and precision "precision" and return this string
//! \~russian Устанавливает содержимое строки в текстовое представление "value" в формате "format" и точностью "precision" и возвращает эту строку
//! \~english Set string content to text representation of "value" with format "format" and precision "precision" and return this string.
//! \~russian Устанавливает содержимое строки в текстовое представление "value" в формате "format" и точностью "precision" и возвращает эту строку.
//! \~\details
//! \~\code
//! PIString s;
@@ -1232,15 +1389,15 @@ public:
//! s.setNumber(123456789., 'f', 0);
//! piCout << s; // 123456789
//! \endcode
PIString & setNumber(const ldouble & value, char format = 'f', int precision = 8) {clear(); *this += PIString::fromNumber(value, format, precision); return *this;}
PIString & setNumber(const ldouble & value, char format = 'f', int precision = 8) {*this = PIString::fromNumber(value, format, precision); return *this;}
//! \~english Set string content to human readable size in B/kB/MB/GB/TB/PB
//! \~russian Устанавливает содержимое в строку с читаемым размером B/kB/MB/GB/TB/PB
//! \~english Set string content to human readable size in B/kB/MB/GB/TB/PB.
//! \~russian Устанавливает содержимое в строку с читаемым размером B/kB/MB/GB/TB/PB.
//! \~\sa PIString::readableSize()
PIString & setReadableSize(llong bytes);
//! \~english Returns string contains numeric representation of "value" in base "base"
//! \~russian Возвращает строковое представление числа "value" по основанию "base"
//! \~english Returns string contains numeric representation of "value" in base "base".
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
//! \~\details
//! \~\code
//! piCout << PIString::fromNumber(123); // 123
@@ -1248,8 +1405,8 @@ public:
//! \endcode
static PIString fromNumber(const short value, int base = 10, bool * ok = 0) {return fromNumberBaseS(llong(value), base, ok);}
//! \~english Returns string contains numeric representation of "value" in base "base"
//! \~russian Возвращает строковое представление числа "value" по основанию "base"
//! \~english Returns string contains numeric representation of "value" in base "base".
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
//! \~\details
//! \~\code
//! piCout << PIString::fromNumber(123); // 123
@@ -1257,8 +1414,8 @@ public:
//! \endcode
static PIString fromNumber(const ushort value, int base = 10, bool * ok = 0) {return fromNumberBaseU(ullong(value), base, ok);}
//! \~english Returns string contains numeric representation of "value" in base "base"
//! \~russian Возвращает строковое представление числа "value" по основанию "base"
//! \~english Returns string contains numeric representation of "value" in base "base".
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
//! \~\details
//! \~\code
//! piCout << PIString::fromNumber(123); // 123
@@ -1266,8 +1423,8 @@ public:
//! \endcode
static PIString fromNumber(const int value, int base = 10, bool * ok = 0) {return fromNumberBaseS(llong(value), base, ok);}
//! \~english Returns string contains numeric representation of "value" in base "base"
//! \~russian Возвращает строковое представление числа "value" по основанию "base"
//! \~english Returns string contains numeric representation of "value" in base "base".
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
//! \~\details
//! \~\code
//! piCout << PIString::fromNumber(123); // 123
@@ -1275,8 +1432,8 @@ public:
//! \endcode
static PIString fromNumber(const uint value, int base = 10, bool * ok = 0) {return fromNumberBaseU(ullong(value), base, ok);}
//! \~english Returns string contains numeric representation of "value" in base "base"
//! \~russian Возвращает строковое представление числа "value" по основанию "base"
//! \~english Returns string contains numeric representation of "value" in base "base".
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
//! \~\details
//! \~\code
//! piCout << PIString::fromNumber(123); // 123
@@ -1284,8 +1441,8 @@ public:
//! \endcode
static PIString fromNumber(const long value, int base = 10, bool * ok = 0) {return fromNumberBaseS(llong(value), base, ok);}
//! \~english Returns string contains numeric representation of "value" in base "base"
//! \~russian Возвращает строковое представление числа "value" по основанию "base"
//! \~english Returns string contains numeric representation of "value" in base "base".
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
//! \~\details
//! \~\code
//! piCout << PIString::fromNumber(123); // 123
@@ -1293,8 +1450,8 @@ public:
//! \endcode
static PIString fromNumber(const ulong value, int base = 10, bool * ok = 0) {return fromNumberBaseU(ullong(value), base, ok);}
//! \~english Returns string contains numeric representation of "value" in base "base"
//! \~russian Возвращает строковое представление числа "value" по основанию "base"
//! \~english Returns string contains numeric representation of "value" in base "base".
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
//! \~\details
//! \~\code
//! piCout << PIString::fromNumber(123); // 123
@@ -1302,8 +1459,8 @@ public:
//! \endcode
static PIString fromNumber(const llong & value, int base = 10, bool * ok = 0) {return fromNumberBaseS(value, base, ok);}
//! \~english Returns string contains numeric representation of "value" in base "base"
//! \~russian Возвращает строковое представление числа "value" по основанию "base"
//! \~english Returns string contains numeric representation of "value" in base "base".
//! \~russian Возвращает строковое представление числа "value" по основанию "base".
//! \~\details
//! \~\code
//! piCout << PIString::fromNumber(123); // 123
@@ -1311,8 +1468,8 @@ public:
//! \endcode
static PIString fromNumber(const ullong & value, int base = 10, bool * ok = 0) {return fromNumberBaseU(value, base, ok);}
//! \~english Returns string contains numeric representation of "value" with format "format" and precision "precision"
//! \~russian Возвращает строковое представление числа "value" в формате "format" и точностью "precision"
//! \~english Returns string contains numeric representation of "value" with format "format" and precision "precision".
//! \~russian Возвращает строковое представление числа "value" в формате "format" и точностью "precision".
//! \~\details
//! \~\code
//! piCout << PIString::fromNumber(12.3); // 12.30000000
@@ -1321,10 +1478,10 @@ public:
//! piCout << PIString::fromNumber(123456789., 'g', 2); // 1.2e+08
//! piCout << PIString::fromNumber(123456789., 'f', 0); // 123456789
//! \endcode
static PIString fromNumber(const float value, char format = 'f', int precision = 8) {return ftos(value, format, precision);}
static PIString fromNumber(const float value, char format = 'f', int precision = 8) {return dtos(value, format, precision);}
//! \~english Returns string contains numeric representation of "value" with format "format" and precision "precision"
//! \~russian Возвращает строковое представление числа "value" в формате "format" и точностью "precision"
//! \~english Returns string contains numeric representation of "value" with format "format" and precision "precision".
//! \~russian Возвращает строковое представление числа "value" в формате "format" и точностью "precision".
//! \~\details
//! \~\code
//! piCout << PIString::fromNumber(12.3); // 12.30000000
@@ -1335,8 +1492,8 @@ public:
//! \endcode
static PIString fromNumber(const double & value, char format = 'f', int precision = 8) {return dtos(value, format, precision);}
//! \~english Returns string contains numeric representation of "value" with format "format" and precision "precision"
//! \~russian Возвращает строковое представление числа "value" в формате "format" и точностью "precision"
//! \~english Returns string contains numeric representation of "value" with format "format" and precision "precision".
//! \~russian Возвращает строковое представление числа "value" в формате "format" и точностью "precision".
//! \~\details
//! \~\code
//! piCout << PIString::fromNumber(12.3); // 12.30000000
@@ -1349,44 +1506,54 @@ public:
//! \~english Returns "true" or "false"
//! \~russian Возвращает "true" или "false"
static PIString fromBool(const bool value) {return PIString(value ? "true" : "false");}
static PIString fromBool(const bool value) {return PIString(value ? PIStringAscii("true") : PIStringAscii("false"));}
//! \~english Returns string constructed from terminal codepage
//! \~russian Возвращает строку созданную из кодировки консоли
//! \~english Returns string constructed from terminal codepage.
//! \~russian Возвращает строку созданную из кодировки консоли.
static PIString fromConsole(const char * s);
//! \~english Returns string constructed from system codepage
//! \~russian Возвращает строку созданную из кодировки системы
//! \~english Returns string constructed from system codepage.
//! \~russian Возвращает строку созданную из кодировки системы.
static PIString fromSystem(const char * s);
//! \~english Returns string constructed from UTF-8
//! \~russian Возвращает строку созданную из UTF-8
//! \~english Returns string constructed from UTF-8.
//! \~russian Возвращает строку созданную из UTF-8.
static PIString fromUTF8(const char * s);
//! \~english Returns string constructed from UTF-8
//! \~russian Возвращает строку созданную из UTF-8
//! \~english Returns string constructed from UTF-8.
//! \~russian Возвращает строку созданную из UTF-8.
static PIString fromUTF8(const PIByteArray & utf);
//! \~english Returns string constructed from ASCII
//! \~russian Возвращает строку созданную из ASCII
//! \~english Returns string constructed from ASCII.
//! \~russian Возвращает строку созданную из ASCII.
static PIString fromAscii(const char * s);
//! \~english Returns string constructed from "len" chars ASCII
//! \~russian Возвращает строку созданную из "len" символов ASCII
//! \~english Returns string constructed from "len" chars ASCII.
//! \~russian Возвращает строку созданную из "len" символов ASCII.
static PIString fromAscii(const char * s, int len);
//! \~english Returns string constructed from "cp" codepage
//! \~russian Возвращает строку созданную из кодировки "cp"
//! \~english Returns string constructed from "cp" codepage.
//! \~russian Возвращает строку созданную из кодировки "cp".
static PIString fromCodepage(const char * s, const char * cp);
//! \~english Returns string contains human readable size in B/kB/MB/GB/TB/PB
//! \~russian Возвращает строку с читаемым размером B/kB/MB/GB/TB/PB
//! \~english Returns string contains human readable size in B/kB/MB/GB/TB/PB.
//! \~russian Возвращает строку с читаемым размером B/kB/MB/GB/TB/PB.
//! \~\sa PIString::setReadableSize()
static PIString readableSize(llong bytes);
//! \~english Swaps string `str` other with this string.
//! \~russian Меняет строку `str` с этой строкой.
//! \~\details
//! \~english This operation is very fast and never fails.
//! \~russian Эта операция выполняется мгновенно без копирования памяти и никогда не дает сбоев.
void swap(PIString & str) {
d.swap(str.d);
piSwap(data_, str.data_);
}
private:
static const char toBaseN[];
static const int fromBaseN[];
static const char fromBaseN[];
static PIString itos(const int num);
static PIString ltos(const long num);
@@ -1394,71 +1561,72 @@ private:
static PIString uitos(const uint num);
static PIString ultos(const ulong num);
static PIString ulltos(const ullong num);
static PIString ftos(const float num, char format = 'f', int precision = 8);
static PIString dtos(const double num, char format = 'f', int precision = 8);
static PIString fromNumberBaseS(const llong value, int base = 10, bool * ok = 0);
static PIString fromNumberBaseU(const ullong value, int base = 10, bool * ok = 0);
static llong toNumberBase(const PIString & value, int base = -1, bool * ok = 0);
void appendFromChars(const char * c, int s, const char * cp = __syslocname__);
void buildData(const char * cp = __syslocname__) const;
void deleteData() const;
void trimsubstr(int &st, int &fn) const;
mutable PIByteArray data_;
PIDeque<PIChar> d;
mutable char * data_ = nullptr;
};
//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
//! \~english Output operator to \a PICout.
//! \~russian Оператор вывода в \a PICout.
PIP_EXPORT PICout operator <<(PICout s, const PIString & v);
//! \relatesalso PIByteArray
//! \~english Store operator
//! \~russian Оператор сохранения
inline PIByteArray & operator <<(PIByteArray & s, const PIString & v) {s << *(PIDeque<PIChar>*)&v; return s;}
//! \~english Store operator.
//! \~russian Оператор сохранения.
inline PIByteArray & operator <<(PIByteArray & s, const PIString & v) {s << v.d; return s;}
//! \relatesalso PIByteArray
//! \~english Restore operator
//! \~russian Оператор извлечения
inline PIByteArray & operator >>(PIByteArray & s, PIString & v) {v.clear(); s >> *(PIDeque<PIChar>*)&v; return s;}
//! \~english Restore operator.
//! \~russian Оператор извлечения.
inline PIByteArray & operator >>(PIByteArray & s, PIString & v) {v.d.clear(); s >> v.d; return s;}
//! \~english Returns concatenated string
//! \~russian Возвращает соединение строк
//! \~english Returns concatenated string.
//! \~russian Возвращает соединение строк.
inline PIString operator +(const PIString & str, const PIString & f) {PIString s(str); s += f; return s;}
//! \~english Returns concatenated string
//! \~russian Возвращает соединение строк
//! \~english Returns concatenated string.
//! \~russian Возвращает соединение строк.
inline PIString operator +(const PIString & f, const char * str) {PIString s(f); s += str; return s;}
//! \~english Returns concatenated string
//! \~russian Возвращает соединение строк
//! \~english Returns concatenated string.
//! \~russian Возвращает соединение строк.
inline PIString operator +(const char * str, const PIString & f) {return PIString(str) + f;}
//! \~english Returns concatenated string
//! \~russian Возвращает соединение строк
//! \~english Returns concatenated string.
//! \~russian Возвращает соединение строк.
inline PIString operator +(const char c, const PIString & f) {return PIChar(c) + f;}
//! \~english Returns concatenated string
//! \~russian Возвращает соединение строк
//! \~english Returns concatenated string.
//! \~russian Возвращает соединение строк.
inline PIString operator +(const PIString & f, const char c) {return f + PIChar(c);}
//! \relatesalso PIString
//! \~english Compare two version strings in free notation and returns 0, -1 or 1
//! \~russian Сравнивает две строки с версиями в произвольной форме и возвращает 0, -1 или 1
//! \~english Compare two version strings in free notation and returns 0, -1 or 1.
//! \~russian Сравнивает две строки с версиями в произвольной форме и возвращает 0, -1 или 1.
int PIP_EXPORT versionCompare(const PIString & v0, const PIString & v1, int components = 6);
//! \relatesalso PIString
//! \~english Converts version string in free notation to classic view
//! \~russian Преобразует строку с версией в произвольной форме к классическому виду
//! \~english Converts version string in free notation to classic view.
//! \~russian Преобразует строку с версией в произвольной форме к классическому виду.
PIString PIP_EXPORT versionNormalize(const PIString & v);
//! \~english Returns hash of string
//! \~russian Возвращает хэш строки
template<> inline uint piHash(const PIString & s) {return s.hash();}
template<> inline void piSwap(PIString & f, PIString & s) {f.swap(s);}
template<> inline void piSwap(PIString & f, PIString & s) {
f.swap(s);
}
#endif // PISTRING_H

View File

@@ -20,16 +20,9 @@
#include "pistringlist.h"
//! \addtogroup Core
//! \{
//! \~\class PIStringList pistringlist.h
//! \~\brief
//! \~english Based on \a PIDeque<PIString> strings list
//! \~russian Основанный на \a PIDeque<PIString> массив строк
//!
//! \~\details
//!
//! \}
//! \details

View File

@@ -29,6 +29,10 @@
#include "pistring.h"
//! \ingroup Core
//! \~\brief
//! \~english Based on \a PIDeque<PIString> strings list.
//! \~russian Основанный на \a PIDeque<PIString> массив строк.
class PIP_EXPORT PIStringList: public PIDeque<PIString>
{
public:

View File

@@ -45,13 +45,8 @@
#endif
//! \addtogroup Core
//! \{
//! \class PISystemTime pisystemtime.h
//! \brief
//! \~english System time with nanosecond precision
//! \~russian Системное время с точностью до наносекунд
//!
//! \details
//! \~english \section PISystemTime_sec0 Synopsis
//! \~russian \section PISystemTime_sec0 Краткий обзор
//! \~english
@@ -72,16 +67,10 @@
//! \~russian \section PISystemTime_sec1 Пример
//! \~\snippet pitimer.cpp system_time
//!
//! \}
//! \addtogroup Core
//! \{
//! \class PITimeMeasurer pisystemtime.h
//! \brief
//! \~english Time measurements
//! \~russian Измерение времени
//!
//! \details
//! \~english \section PITimeMeasurer_sec0 Usage
//! \~russian \section PITimeMeasurer_sec0 Использование
//! \~english
@@ -96,7 +85,6 @@
//! Эти методы возвращают нано, микро, милли и секунды с приставками
//! "n", "u", "m" и "s".
//!
//! \}

View File

@@ -30,6 +30,10 @@
#include "pistring.h"
//! \ingroup Core
//! \~\brief
//! \~english System time with nanosecond precision.
//! \~russian Системное время с точностью до наносекунд.
class PIP_EXPORT PISystemTime {
public:
@@ -187,6 +191,10 @@ inline PICout operator <<(PICout s, const PISystemTime & v) {s.space(); s.setCon
//! \ingroup Core
//! \~\brief
//! \~english Time measurements.
//! \~russian Измерение времени.
class PIP_EXPORT PITimeMeasurer {
public:
PITimeMeasurer();

View File

@@ -21,7 +21,6 @@
/** \class PIVariant
* \brief Variant type
* \details
* \section PIVariant_sec0 Synopsis
* This class provides general type that can contains all standard types, some

View File

@@ -27,6 +27,7 @@
#define PIVARIANT_H
#include "pivarianttypes.h"
#include "piconstchars.h"
#include "pitime.h"
#include "pigeometry.h"
#include "pimathmatrix.h"
@@ -200,6 +201,9 @@ classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(c
#endif
//! \ingroup Core
//! \~\brief
//! \~english Variant type.
class PIP_EXPORT PIVariant {
friend PICout operator <<(PICout s, const PIVariant & v);
friend PIByteArray & operator <<(PIByteArray & s, const PIVariant & v);
@@ -801,7 +805,10 @@ inline PIByteArray & operator >>(PIByteArray & s, PIVariant & v) {
inline PICout operator <<(PICout s, const PIVariant & v) {
s.space(); s.setControl(0, true);
s << "PIVariant(" << v.typeName() << ", " << v.toString() << ")";
s << "PIVariant(" << v.typeName();
if (v.isValid())
s << ", " << v.toString();
s << ")";
s.restoreControl(); return s;
}

View File

@@ -25,7 +25,7 @@
//! \~english \section cmake_module_Crypt Building with CMake
//! \~russian \section cmake_module_Crypt Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP::Crypt)
//! \endcode

View File

@@ -25,7 +25,7 @@
//! \~english \section cmake_module_Geo Building with CMake
//! \~russian \section cmake_module_Geo Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP)
//! \endcode

View File

@@ -25,7 +25,7 @@
//! \~english \section cmake_module_Introspection Building with CMake
//! \~russian \section cmake_module_Introspection Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP)
//! \endcode

View File

@@ -66,7 +66,7 @@ PIVector<PIIntrospection::ObjectInfo> PIIntrospection::getObjects() {
for (int i = 0; i < ao.size_s(); ++i) {
ret[i].classname = PIStringAscii(ao[i]->className());
ret[i].name = ao[i]->name();
ret[i].properties = ao[i]->properties();
//ret[i].properties = ao[i]->properties();
ret[i].parents = ao[i]->scopeList();
ao[i]->mutex_queue.lock();
ret[i].queued_events = ao[i]->events_queue.size_s();

View File

@@ -791,7 +791,7 @@ void PIBinaryLog::configureFromVariantDevice(const PIPropertyStorage & d) {
}
void PIBinaryLog::propertyChanged(const PIString &s) {
void PIBinaryLog::propertyChanged(const char * s) {
default_id = property("defaultID").toInt();
rapid_start = property("rapidStart").toBool();
play_mode = (PlayMode)property("playMode").toInt();

View File

@@ -31,7 +31,7 @@
class PIP_EXPORT PIBinaryLog: public PIIODevice
{
PIIODEVICE(PIBinaryLog)
PIIODEVICE(PIBinaryLog, "binlog")
public:
explicit PIBinaryLog();
virtual ~PIBinaryLog();
@@ -288,7 +288,6 @@ public:
static bool cutBinLog(const BinLogInfo & src, const PIString & dst, int from, int to);
protected:
PIString fullPathPrefix() const {return PIStringAscii("binlog");}
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);
PIPropertyStorage constructVariantDevice() const;
@@ -297,7 +296,7 @@ protected:
int writeDevice(const void * data, int size) {return writeBinLog(default_id, data, size);}
bool openDevice();
bool closeDevice();
void propertyChanged(const PIString &);
void propertyChanged(const char * s);
bool threadedRead(uchar *readed, int size);
void threadedReadTerminated() {pausemutex.unlock();}
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Reliable;}

View File

@@ -31,7 +31,7 @@
class PIP_EXPORT PICAN: public PIIODevice
{
PIIODEVICE(PICAN)
PIIODEVICE(PICAN, "can")
public:
explicit PICAN(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
virtual ~PICAN();
@@ -45,7 +45,6 @@ protected:
bool closeDevice();
int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size);
PIString fullPathPrefix() const {return PIStringAscii("can");}
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);
PIPropertyStorage constructVariantDevice() const;

View File

@@ -45,17 +45,16 @@ extern "C" {
# include <sys/stat.h>
#endif
/*! \class PIDir
* \brief Local directory
*
* \section PIDir_sec0 Synopsis
* This class provide access to local file. You can manipulate
* binary content or use this class as text stream. To binary
* access there are function \a read(), \a write(), and many
* \a writeBinary() functions. For write variables to file in
* their text representation threr are many "<<" operators.
*
*/
//! \class PIDir pidir.h
//! \details
//! \~english \section PIDir_sec0 Synopsis
//! \~russian \section PIDir_sec0 Краткий обзор
//! \~english
//! This class provide access to local directory.
//!
//! \~russian
//!
PIDir::PIDir(const PIString & dir) {
@@ -115,6 +114,15 @@ PIString PIDir::absolutePath() const {
}
//! \details
//! \~english
//! This function remove repeatedly separators and
//! resolve ".." in path. E.g. "/home/.//user/src/../.." will
//! become "/home". \n Returns reference to this %PIDir
//! \~russian
//! Этот метод удаляет повторяющиеся разделители и разрешает
//! "..". Например, путь "/home/.//user/src/../.." станет "/home". \n
//! Возвращает ссылку на этот %PIDir
PIDir & PIDir::cleanPath() {
PIString p(path_);
if (p.isEmpty()) {
@@ -236,6 +244,14 @@ bool PIDir::make(bool withParents) {
}
bool PIDir::rename(const PIString & new_name) {
if (!PIDir::rename(path(), new_name))
return false;
setDir(new_name);
return true;
}
#ifdef WINDOWS
bool sort_compare(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {
return strcoll(v0.path.data(), v1.path.data()) < 0;
@@ -243,6 +259,20 @@ bool sort_compare(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {
#endif
//! \~\details
//! \~english
//! Scan this directory and returns all directories
//! and files in one list, sorted alphabetically. This list
//! contains also "." and ".." members. There are absolute
//! pathes in returned list.
//! \attention This function doesn`t scan content of inner
//! directories!
//! \~russian
//! Читает директорию и возвращает все директории и файлы
//! одним списком, сортированным по алфавиту. Список содержит
//! также "." и "..". Возвращаются абсолютные пути.
//! \attention Этот метод не читает содержимое директорий
//! рекурсивно!
PIVector<PIFile::FileInfo> PIDir::entries() {
PIVector<PIFile::FileInfo> l;
if (!isExists()) return l;
@@ -322,6 +352,18 @@ PIVector<PIFile::FileInfo> PIDir::entries() {
}
//! \~\details
//! \~english
//! Scan this directory recursively and returns all
//! directories and files in one list, sorted alphabetically.
//! This list doesn`t contains "." and ".." members. There
//! are absolute pathes in returned list, and
//! files placed after directories in this list.
//! \~russian
//! Читает директорию рекурсивно и возвращает все директории и файлы
//! одним списком, сортированным по алфавиту. Список не содержит
//! "." и "..". Возвращаются абсолютные пути, причём файлы
//! располагаются после директорий.
PIVector<PIFile::FileInfo> PIDir::allEntries() {
PIVector<PIFile::FileInfo> ret;
PIVector<PIFile::FileInfo> dirs;

View File

@@ -29,93 +29,146 @@
#include "pifile.h"
//! \ingroup IO
//! \~\brief
//! \~english Local directory.
//! \~russian Локальная директория.
class PIP_EXPORT PIDir
{
public:
//! Constructs directory with path "path"
//! \~english Constructs directory with path "dir"
//! \~russian Создает директорию с путём "dir"
PIDir(const PIString & dir = PIString());
//! Constructs directory with "file" directory path "path"
//! \~english Constructs directory with "file" directory path
//! \~russian Создает директорию с путём директории файла "file"
PIDir(const PIFile & file);
//! Returns if this directory is exists
//! \~english Returns if this directory exists
//! \~russian Возвращает существует ли эта директория
bool isExists() const {return PIDir::isExists(path());}
//! Returns if path of this directory is absolute
//! \~english Returns if path of this directory is absolute
//! \~russian Возвращает абсолютный ли путь у директории
bool isAbsolute() const;
//! Returns if path of this directory is relative
//! \~english Returns if path of this directory is relative
//! \~russian Возвращает относительный ли путь у директории
bool isRelative() const {return !isAbsolute();}
//! Returns path of current reading directory. This path
//! valid only while \a allEntries functions
//! \~english Returns path of current reading directory. This path valid only while \a allEntries() functions
//! \~russian Возвращает путь текущей директории чтения. Этот путь действителен только во время выполнения метода \a allEntries()
const PIString & scanDir() const {return scan_;}
//! Returns path of this directory
//! \~english Returns path of this directory
//! \~russian Возвращает путь директории
PIString path() const;
//! Returns absolute path of this directory
//! \~english Returns absolute path of this directory
//! \~russian Возвращает абсолютный путь директории
PIString absolutePath() const;
/** \brief Simplify path of this directory
* \details This function remove repeatedly separators and
* resolve ".." in path. E.g. "/home/.//peri4/src/../.." will
* become "/home" \n This function returns reference to this %PIDir */
//! \~english Simplify path of this directory
//! \~russian Упрощает путь директории
PIDir & cleanPath();
//! Returns %PIDir with simplified path of this directory
//! \~english Returns %PIDir with simplified path of this directory
//! \~russian Возвращает %PIDir с упрощённым путём директории
PIDir cleanedPath() const {PIDir d(path()); d.cleanPath(); return d;}
//! Returns relative to this directory path "path"
//! \~english Returns relative to this directory path "path"
//! \~russian Возвращает путь "path" относительно этой директории
PIString relative(const PIString & path) const;
//! Set this directory path to simplified "path"
//! \~english Set this directory path to simplified "path"
//! \~russian Устанавливает путь директории упрощённым "path"
PIDir & setDir(const PIString & path);
//! Set this directory path as current for application
//! \~english Set this directory path as current for application
//! \~russian Устанавливает путь директории текущим путём приложения
bool setCurrent() {return PIDir::setCurrent(path());}
/** \brief Returns this directory content
* \details Scan this directory and returns all directories
* and files in one list, sorted alphabetically. This list
* contains also "." and ".." members. There are absolute
* pathes in returned list.
* \attention This function doesn`t scan content of inner
* directories! */
//! \~english Returns this directory content
//! \~russian Возвращает содержимое этой директории
PIVector<PIFile::FileInfo> entries();
/** \brief Returns all this directory content
* \details Scan this directory recursively and returns all
* directories and files in one list, sorted alphabetically.
* This list doesn`t contains "." and ".." members. There
* are absolute pathes in returned list, and
* files placed after directories in this list */
//! \~english Returns this directory content recursively
//! \~russian Возвращает содержимое этой директории рекурсивно
PIVector<PIFile::FileInfo> allEntries();
//! \~english Make this directory, recursively if "withParents"
//! \~russian Создаёт эту директорию, рекурсивно если "withParents"
bool make(bool withParents = true);
//! \~english Remove this directory
//! \~russian Удаляет эту директорию
bool remove() {return PIDir::remove(path());}
bool rename(const PIString & new_name) {if (!PIDir::rename(path(), new_name)) return false; setDir(new_name); return true;}
//! \~english Rename this directory
//! \~russian Переименовывает эту директорию
bool rename(const PIString & new_name);
//! \~english Change this directory to relative path "path"
//! \~russian Изменяет директорию на относительный путь "path"
PIDir & cd(const PIString & path);
//! \~english Change this directory to parent
//! \~russian Изменяет директорию на родительскую
PIDir & up() {return cd("..");}
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator ==(const PIDir & d) const;
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator !=(const PIDir & d) const {return !((*this) == d);}
static const PIChar separator;
//! \~english Returns current directory for application
//! \~russian Возвращает текущую директорию приложения
static PIDir current();
//! \~english Returns user home directory
//! \~russian Возвращает домашнюю директорию пользователя
static PIDir home();
//! \~english Returns temporary directory
//! \~russian Возвращает временную директорию
static PIDir temporary();
//! \~english Returns directory "path" content recursively
//! \~russian Возвращает содержимое директории "path" рекурсивно
static PIVector<PIFile::FileInfo> allEntries(const PIString & path);
//! \~english Returns if directory "path" exists
//! \~russian Возвращает существует ли эта директория
static bool isExists(const PIString & path);
//! \~english Make directory "path", recursively if "withParents"
//! \~russian Создаёт директорию "path", рекурсивно если "withParents"
static bool make(const PIString & path, bool withParents = true);
//! \~english Remove directory "path"
//! \~russian Удаляет директорию "path"
static bool remove(const PIString & path) {return removeDir(path);}
//! \~english Rename directory "path"
//! \~russian Переименовывает директорию "path"
static bool rename(const PIString & path, const PIString & new_name) {return PIDir::renameDir(path, new_name);}
//! \~english Set path "path" as current for application
//! \~russian Устанавливает путь "path" текущим путём приложения
static bool setCurrent(const PIString & path);
//! \~english Set directory "dir" path as current for application
//! \~russian Устанавливает путь директории "dir" текущим путём приложения
static bool setCurrent(const PIDir & dir) {return setCurrent(dir.path());}
private:
@@ -133,6 +186,9 @@ inline bool operator >(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1
inline bool operator ==(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {return (v0.path == v1.path);}
inline bool operator !=(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {return (v0.path != v1.path);}
//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
inline PICout operator <<(PICout s, const PIDir & v) {s.setControl(0, true); s << "PIDir(\"" << v.path() << "\")"; s.restoreControl(); return s;}

View File

@@ -21,6 +21,7 @@
#include "piconfig.h"
#include "pisysteminfo.h"
#include "pipropertystorage.h"
#include "piconstchars.h"
#ifdef QNX
# include <net/if.h>
# include <net/if_dl.h>
@@ -919,10 +920,11 @@ bool PIEthernet::configureDevice(const void * e_main, const void * e_parent) {
}
void PIEthernet::propertyChanged(const PIString & name) {
if (name.endsWith("Timeout")) applyTimeouts();
if (name == "TTL") applyOptInt(IPPROTO_IP, IP_TTL, TTL());
if (name == "MulticastTTL") applyOptInt(IPPROTO_IP, IP_MULTICAST_TTL, multicastTTL());
void PIEthernet::propertyChanged(const char * name) {
PIConstChars pn(name);
if (pn.endsWith("Timeout")) applyTimeouts();
if (pn == "TTL") applyOptInt(IPPROTO_IP, IP_TTL, TTL());
if (pn == "MulticastTTL") applyOptInt(IPPROTO_IP, IP_MULTICAST_TTL, multicastTTL());
}
@@ -1001,24 +1003,23 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
ci.index = -1;
ci.mtu = 1500;
#ifdef WINDOWS
PIP_ADAPTER_INFO pAdapterInfo, pAdapter = 0;
int ret = 0;
ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO);
pAdapterInfo = (IP_ADAPTER_INFO * ) HeapAlloc(GetProcessHeap(), 0, (sizeof (IP_ADAPTER_INFO)));
if (pAdapterInfo == 0) {
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersinfo";
PIP_ADAPTER_INFO pAdapterInfo = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO));
if (!pAdapterInfo) {
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersInfo";
return il;
}
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
pAdapterInfo = (IP_ADAPTER_INFO *) HeapAlloc(GetProcessHeap(), 0, (ulOutBufLen));
if (pAdapterInfo == 0) {
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersinfo";
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
pAdapterInfo = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(), 0, ulOutBufLen);
if (!pAdapterInfo) {
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersInfo";
return il;
}
}
if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
pAdapter = pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
while (pAdapter) {
ci.name = PIString(pAdapter->AdapterName);
ci.index = pAdapter->Index;
@@ -1031,8 +1032,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
IP_ADDR_STRING * as = &(pAdapter->IpAddressList);
while (as) {
// piCout << "[pAdapter]" << ci.name << PIString(as->IpAddress.String);
ci.address = PIString(as->IpAddress.String);
ci.netmask = PIString(as->IpMask.String);
ci.address = PIStringAscii(as->IpAddress.String);
ci.netmask = PIStringAscii(as->IpMask.String);
if (ci.address == "0.0.0.0") {
as = as->Next;
continue;
@@ -1053,7 +1054,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
}
}
if (pAdapterInfo)
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
#else
#ifdef MICRO_PIP
#else
@@ -1213,10 +1214,16 @@ int PIEthernet::ethErrorCore() {
PIString PIEthernet::ethErrorString() {
#ifdef WINDOWS
char * msg;
char * msg = nullptr;
int err = WSAGetLastError();
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL);
return "code " + PIString::fromNumber(err) + " - " + PIString(msg);
PIString ret = PIStringAscii("code ") + PIString::fromNumber(err) + PIStringAscii(" - ");
if (msg) {
ret += PIString::fromSystem(msg).trim();
LocalFree(msg);
} else
ret += '?';
return ret;
#else
return errorString();
#endif

View File

@@ -38,7 +38,7 @@ class
class PIP_EXPORT PIEthernet: public PIIODevice
{
PIIODEVICE(PIEthernet)
PIIODEVICE(PIEthernet, "eth")
friend class PIPeer;
public:
@@ -201,44 +201,44 @@ public:
//! Set parameters to "parameters_". You should to reopen %PIEthernet to apply them
void setParameters(PIFlags<PIEthernet::Parameters> parameters_) {setProperty(PIStringAscii("parameters"), (int)parameters_);}
void setParameters(PIFlags<PIEthernet::Parameters> parameters_) {setProperty("parameters", (int)parameters_);}
//! Set parameter "parameter" to state "on". You should to reopen %PIEthernet to apply this
void setParameter(PIEthernet::Parameters parameter, bool on = true);
//! Returns if parameter "parameter" is set
bool isParameterSet(PIEthernet::Parameters parameter) const {return ((PIFlags<PIEthernet::Parameters>)(property(PIStringAscii("parameters")).toInt()))[parameter];}
bool isParameterSet(PIEthernet::Parameters parameter) const {return ((PIFlags<PIEthernet::Parameters>)(property("parameters").toInt()))[parameter];}
//! Returns parameters
PIFlags<PIEthernet::Parameters> parameters() const {return (PIFlags<PIEthernet::Parameters>)(property(PIStringAscii("parameters")).toInt());}
PIFlags<PIEthernet::Parameters> parameters() const {return (PIFlags<PIEthernet::Parameters>)(property("parameters").toInt());}
//! Returns %PIEthernet type
Type type() const {return (Type)(property(PIStringAscii("type")).toInt());}
Type type() const {return (Type)(property("type").toInt());}
//! Returns read timeout
double readTimeout() const {return property(PIStringAscii("readTimeout")).toDouble();}
double readTimeout() const {return property("readTimeout").toDouble();}
//! Returns write timeout
double writeTimeout() const {return property(PIStringAscii("writeTimeout")).toDouble();}
double writeTimeout() const {return property("writeTimeout").toDouble();}
//! Set timeout for read
void setReadTimeout(double ms) {setProperty(PIStringAscii("readTimeout"), ms);}
void setReadTimeout(double ms) {setProperty("readTimeout", ms);}
//! Set timeout for write
void setWriteTimeout(double ms) {setProperty(PIStringAscii("writeTimeout"), ms);}
void setWriteTimeout(double ms) {setProperty("writeTimeout", ms);}
//! Returns TTL (Time To Live)
int TTL() const {return property(PIStringAscii("TTL")).toInt();}
int TTL() const {return property("TTL").toInt();}
//! Returns multicast TTL (Time To Live)
int multicastTTL() const {return property(PIStringAscii("MulticastTTL")).toInt();}
int multicastTTL() const {return property("MulticastTTL").toInt();}
//! Set TTL (Time To Live), default is 64
void setTTL(int ttl) {setProperty(PIStringAscii("TTL"), ttl);}
void setTTL(int ttl) {setProperty("TTL", ttl);}
//! Set multicast TTL (Time To Live), default is 1
void setMulticastTTL(int ttl) {setProperty(PIStringAscii("MulticastTTL"), ttl);}
void setMulticastTTL(int ttl) {setProperty("MulticastTTL", ttl);}
//! Join to multicast group with address "group". Use only for UDP
@@ -462,9 +462,8 @@ public:
protected:
explicit PIEthernet(int sock, PIString ip_port);
void propertyChanged(const PIString & name);
void propertyChanged(const char * name);
PIString fullPathPrefix() const {return PIStringAscii("eth");}
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);
PIPropertyStorage constructVariantDevice() const;
@@ -499,7 +498,7 @@ protected:
private:
EVENT_HANDLER1(void, clientDeleted, PIObject *, o);
static void server_func(void * eth);
void setType(Type t, bool reopen = true) {setProperty(PIStringAscii("type"), (int)t); if (reopen && isOpened()) {closeDevice(); init(); openDevice();}}
void setType(Type t, bool reopen = true) {setProperty("type", (int)t); if (reopen && isOpened()) {closeDevice(); init(); openDevice();}}
static int ethErrorCore();
static PIString ethErrorString();

View File

@@ -69,25 +69,44 @@
# define _stat_link_ lstat64
#endif
/*! \class PIFile
* \brief Local file
*
* \section PIFile_sec0 Synopsis
* This class provide access to local file. You can manipulate
* binary content or use this class as text stream. To binary
* access there are function \a read(), \a write(), and many
* \a writeBinary() functions. For write variables to file in
* their text representation threr are many "<<" operators.
*
* \section PIFile_sec1 Position
* Each opened file has a read/write position - logical position
* in the file content you read from or you write to. You can
* find out current position with function \a pos(). Function
* \a seek(llong position) move position to position "position",
* \a seekToBegin() move position to the begin of file,
* \a seekToEnd() move position to the end of file.
*
*/
//! \class PIFile pifile.h
//! \details
//! \~english \section PIFile_sec0 Synopsis
//! \~russian \section PIFile_sec0 Краткий обзор
//! \~english
//!
//! This class provide access to local file. You can manipulate
//! binary content or use this class as text stream. To binary
//! access there are function \a read(), \a write(), and many
//! \a writeBinary() functions. For write and read variables to file in
//! their text representation there are many "<<" and ">>" operators.
//!
//! \~russian
//! Этот класс предоставляет доступ к локальному файлу. Можно
//! работать на байтовом уровне, либо использовать его как
//! текстовый поток. Для байтового доступа используются методы
//! \a read(), \a write(), и много \a writeBinary() методов.
//! Для записи и чтения переменных в текстовом представлении
//! используются операторы "<<" и ">>".
//!
//! \~english \section PIFile_sec1 Position
//! \~russian \section PIFile_sec1 Позиция
//! \~english
//! Each opened file has a read/write position - logical position
//! in the file content you read from or you write to. You can
//! find out current position with function \a pos(). Function
//! \a seek(llong position) move position to position "position",
//! \a seekToBegin() move position to the begin of file,
//! \a seekToEnd() move position to the end of file.
//!
//! \~russian
//! Каждый файл имеет позицию чтения/записи - логическое положение
//! в содержимом файла, откуда производится чтение или запись.
//! Узнать текущую позицию можно с помощью метода \a pos().
//! Метод \a seek(llong position) перемещает позицию на указанную,
//! \a seekToBegin() перемещает её в начало файла, а \a seekToEnd() - в конец.
//!
REGISTER_DEVICE(PIFile)
@@ -614,7 +633,7 @@ int PIFile::writeDevice(const void * data, int max_size) {
PIFile &PIFile::operator <<(const PIString & v) {
if (canWrite() && PRIVATE->fd != 0)
if (canWrite() && v.isNotEmpty() && PRIVATE->fd != 0)
*this << v.toCharset(defaultCharset());
return *this;
}

View File

@@ -30,30 +30,62 @@
#include "pipropertystorage.h"
//! \ingroup IO
//! \~\brief
//! \~english Local file.
//! \~russian Локальный файл.
class PIP_EXPORT PIFile: public PIIODevice
{
PIIODEVICE(PIFile)
PIIODEVICE(PIFile, "file")
public:
//! Constructs an empty file
//! \~english Constructs file with empty path
//! \~russian Создает файл с пустым путём
explicit PIFile();
//! \~english Constructs a file with path "path" and open mode "mode". Open if "path" is not empty
//! \~russian Создает файл с путём "path" и режимом открытия "mode". Открывает если "path" не пустой
explicit PIFile(const PIString & path, DeviceMode mode = ReadWrite);
virtual ~PIFile();
//! \ingroup IO
//! \~\brief
//! \~english Local file or directory information.
//! \~russian Информация о локальном файле или директории.
struct PIP_EXPORT FileInfo {
//! \~english Constructs %FileInfo with path "path_". No information gathered
//! \~russian Создает %FileInfo с путём "path_". Информация не собирается
FileInfo(const PIString & path_ = PIString()) {path = path_; size = 0; id_group = id_user = 0;}
//! \~english Type flags
//! \~russian Флаги типа
enum Flag {
File = 0x01,
Dir = 0x02,
Dot = 0x04,
DotDot = 0x08,
SymbolicLink = 0x10,
Hidden = 0x20
File /*! \~english File \~russian Файл */ = 0x01,
Dir /*! \~english Directory \~russian Директория */ = 0x02,
Dot /*! \~english '.', current directory \~russian '.', текущая директория */ = 0x04,
DotDot /*! \~english '..', parent directory \~russian '..', родительская директория */ = 0x08,
SymbolicLink /*! \~english Symbolic link \~russian Символическая ссылка */ = 0x10,
Hidden /*! \~english Hidden \~russian Скрытый */ = 0x20
};
typedef PIFlags<FileInfo::Flag> Flags;
//! \ingroup IO
//! \~\brief
//! \~english Local file or directory permissions.
//! \~russian Разрешения локального файла или директории.
struct PIP_EXPORT Permissions {
Permissions(uchar r = 0): raw(r) {}
Permissions(bool r, bool w, bool e): raw(0) {read = r; write = w; exec = e;}
//! \~english Returns as string (from "---" to "rwx")
//! \~russian Возвращает как строку (от "---" до "rwx")
PIString toString() const {return PIString(read ? "r" : "-") + PIString(write ? "w" : "-") + PIString(exec ? "x" : "-");}
//! \~english Convertion to \c int
//! \~russian Преобразование в \c int
operator int() const {return raw;}
Permissions & operator =(int v) {raw = v; return *this;}
union {
@@ -66,175 +98,321 @@ public:
};
};
//! \~english Path
//! \~russian Путь
PIString path;
//! \~english File size
//! \~russian Размер файла
llong size;
//! \~english Last access time
//! \~russian Время последнего доступа
PIDateTime time_access;
//! \~english Last modification time
//! \~russian Время последнего изменения
PIDateTime time_modification;
//! \~english Flags
//! \~russian Флаги
Flags flags;
//! \~english User ID
//! \~russian ID пользователя
uint id_user;
//! \~english Group ID
//! \~russian ID группы
uint id_group;
//! \~english Permissions for user
//! \~russian Разрешения для пользователя
Permissions perm_user;
//! \~english Permissions for group
//! \~russian Разрешения для группы
Permissions perm_group;
//! \~english Permissions for other
//! \~russian Разрешения для остальных
Permissions perm_other;
//! \~english Returns name, without directory
//! \~russian Возвращает имя, без директории
PIString name() const;
//! \~english Returns base name, without directory and extension
//! \~russian Возвращает базовое имя, без директории и расширения
PIString baseName() const;
//! \~english Returns extension
//! \~russian Возвращает расширение
PIString extension() const;
//! \~english Returns directory
//! \~russian Возвращает директорию
PIString dir() const;
//! \~english Returns if it`s directory
//! \~russian Возвращает директория ли это
bool isDir() const {return flags[Dir];}
//! \~english Returns if it`s file
//! \~russian Возвращает файл ли это
bool isFile() const {return flags[File];}
//! \~english Returns if it`s symbolic link
//! \~russian Возвращает символическая ссылка ли это
bool isSymbolicLink() const {return flags[SymbolicLink];}
//! \~english Returns if Hidden flag set
//! \~russian Возвращает установлен ли флаг Hidden
bool isHidden() const {return flags[Hidden];}
};
//! Constructs a file with path "path" and open mode "mode"
//! If "path" is not empty then open file
explicit PIFile(const PIString & path, DeviceMode mode = ReadWrite);
//! Open temporary file with open mode "mode"
//! \~english Open temporary file with open mode "mode"
//! \~russian Открывает временный файл с режимом открытия "mode"
bool openTemporary(PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
virtual ~PIFile();
//! Immediate write all buffered data to disk
//! \~english Immediate write all buffered data to disk
//! \~russian Немедленно записывает все буферизированные данные на диск
void flush();
//! Move read/write position to "position"
//! \~english Move read/write position to "position"
//! \~russian Перемещает позицию чтения/записи на "position"
void seek(llong position);
//! Move read/write position to the begin of the file
//! \~english Move read/write position to the begin of the file
//! \~russian Перемещает позицию чтения/записи на начало файла
void seekToBegin();
//! Move read/write position to the end of the file
//! \~english Move read/write position to the end of the file
//! \~russian Перемещает позицию чтения/записи на конец файла
void seekToEnd();
//! Move read/write position to text line number "line"
//! \~english Move read/write position to text line number "line" beginning
//! \~russian Перемещает позицию чтения/записи на начало текстовой строки номер "line"
void seekToLine(llong line);
//! Skip "bytes" bytes (move position next to "bytes" bytes)
//! \~english Skip "bytes" bytes (move position next to "bytes" bytes)
//! \~russian Пропускает "bytes" байт (перемещает позицию на "bytes" байт вперёд)
void skip(llong bytes);
//! Read one char and return it
//! \~english Read one char and return it
//! \~russian Читает один байт и возвращает его
char readChar();
//! Read one text line and return it
//! \~english Read one text line and return it
//! \~russian Читает одну текстовую строку и возвращает её
PIString readLine();
//! Read all file content to "data" and return readed bytes count. Position leaved unchanged
//! \~english Read all file content to "data" and return readed bytes count. Position leaved unchanged
//! \~russian Читает всё содержимое файла в "data" и возвращает количество прочитанных байт. Позиция остаётся неизменной
llong readAll(void * data);
//! Read all file content to byte array and return it. Position leaved unchanged
//! \~english Read all file content to byte array and return it. Position leaved unchanged
//! \~russian Читает всё содержимое файла и возвращает его как массив байтов. Позиция остаётся неизменной
PIByteArray readAll(bool forceRead = false);
//! Set file path to "path" and reopen file if need
//! \~english Set file path to "path" and reopen file if need
//! \~russian Устанавливает путь файла на "path" и переоткрывает его при необходимости
void setPath(const PIString & path);
//! Returns file size
//! \~english Returns file size in bytes
//! \~russian Возвращает размер файла в байтах
llong size() const;
//! Returns read/write position
//! \~english Returns read/write position
//! \~russian Возвращает позицию чтения/записи
llong pos() const;
//! Returns if position is at the end of file
//! \~english Returns if position is at the end of file
//! \~russian Возвращает достигнут ли конец файла
bool isEnd() const;
//! Returns if file is empty
//! \~english Returns if file is empty
//! \~russian Возвращает пустой ли файл
bool isEmpty() const {return (size() <= 0);}
//! Returns FileInfo of current file
//! \~english Returns \a PIFile::FileInfo of current file
//! \~russian Возвращает \a PIFile::FileInfo текущего файла
FileInfo fileInfo() const {return fileInfo(path());}
//! Returns float numbers write precision
//! \~english Returns float numbers write precision
//! \~russian Возвращает точность записи чисел с плавающей точкой
int precision() const {return prec_;}
//! Set float numbers write precision to "prec_" digits
//! \~english Set float numbers write precision to "prec_" digits
//! \~russian Устанавливает точность записи чисел с плавающей точкой
void setPrecision(int prec);
//! \~english Write size and content of "v" (serialize)
//! \~russian Пишет в файл размер и содержимое "v" (сериализация)
PIFile & put(const PIByteArray & v);
//! \~english Read size of byte array and it content (deserialize)
//! \~russian Читает из файла размер байтового массива и его содержимое (десериализация)
PIByteArray get();
//! Write to file binary content of "v"
//! \~english Write to file binary content of "v"
//! \~russian Пишет в файл байтовое содержимое "v"
PIFile & writeBinary(const char v) {write(&v, sizeof(v)); return *this;}
//! Write to file binary content of "v"
//! \~english Write to file binary content of "v"
//! \~russian Пишет в файл байтовое содержимое "v"
PIFile & writeBinary(const short v) {write(&v, sizeof(v)); return *this;}
//! Write to file binary content of "v"
//! \~english Write to file binary content of "v"
//! \~russian Пишет в файл байтовое содержимое "v"
PIFile & writeBinary(const int v) {write(&v, sizeof(v)); return *this;}
//! Write to file binary content of "v"
//! \~english Write to file binary content of "v"
//! \~russian Пишет в файл байтовое содержимое "v"
PIFile & writeBinary(const long v) {write(&v, sizeof(v)); return *this;}
//! Write to file binary content of "v"
//! \~english Write to file binary content of "v"
//! \~russian Пишет в файл байтовое содержимое "v"
PIFile & writeBinary(const llong v) {write(&v, sizeof(v)); return *this;}
//! Write to file binary content of "v"
//! \~english Write to file binary content of "v"
//! \~russian Пишет в файл байтовое содержимое "v"
PIFile & writeBinary(const uchar v) {write(&v, sizeof(v)); return *this;}
//! Write to file binary content of "v"
//! \~english Write to file binary content of "v"
//! \~russian Пишет в файл байтовое содержимое "v"
PIFile & writeBinary(const ushort v) {write(&v, sizeof(v)); return *this;}
//! Write to file binary content of "v"
//! \~english Write to file binary content of "v"
//! \~russian Пишет в файл байтовое содержимое "v"
PIFile & writeBinary(const uint v) {write(&v, sizeof(v)); return *this;}
//! Write to file binary content of "v"
//! \~english Write to file binary content of "v"
//! \~russian Пишет в файл байтовое содержимое "v"
PIFile & writeBinary(const ulong v) {write(&v, sizeof(v)); return *this;}
//! Write to file binary content of "v"
//! \~english Write to file binary content of "v"
//! \~russian Пишет в файл байтовое содержимое "v"
PIFile & writeBinary(const ullong v) {write(&v, sizeof(v)); return *this;}
//! Write to file binary content of "v"
//! \~english Write to file binary content of "v"
//! \~russian Пишет в файл байтовое содержимое "v"
PIFile & writeBinary(const float v) {write(&v, sizeof(v)); return *this;}
//! Write to file binary content of "v"
//! \~english Write to file binary content of "v"
//! \~russian Пишет в файл байтовое содержимое "v"
PIFile & writeBinary(const double v) {write(&v, sizeof(v)); return *this;}
//! Write to file text representation of "v"
//! \~english Write to file text representation of "v"
//! \~russian Пишет в файл текстовое представление "v"
PIFile & operator <<(const char v);
//! Write to file string "v"
//! \~english Write to file string "v"
//! \~russian Пишет в файл строку "v"
PIFile & operator <<(const PIString & v);
//! Write to file text representation of "v"
//! \~english Write to file text representation of "v"
//! \~russian Пишет в файл текстовое представление "v"
PIFile & operator <<(const PIByteArray & v);
//! Write to file text representation of "v"
//! \~english Write to file text representation of "v"
//! \~russian Пишет в файл текстовое представление "v"
PIFile & operator <<(short v);
//! Write to file text representation of "v"
//! \~english Write to file text representation of "v"
//! \~russian Пишет в файл текстовое представление "v"
PIFile & operator <<(int v);
//! Write to file text representation of "v"
//! \~english Write to file text representation of "v"
//! \~russian Пишет в файл текстовое представление "v"
PIFile & operator <<(long v);
//! Write to file text representation of "v"
//! \~english Write to file text representation of "v"
//! \~russian Пишет в файл текстовое представление "v"
PIFile & operator <<(llong v);
//! Write to file text representation of "v"
//! \~english Write to file text representation of "v"
//! \~russian Пишет в файл текстовое представление "v"
PIFile & operator <<(uchar v);
//! Write to file text representation of "v"
//! \~english Write to file text representation of "v"
//! \~russian Пишет в файл текстовое представление "v"
PIFile & operator <<(ushort v);
//! Write to file text representation of "v"
//! \~english Write to file text representation of "v"
//! \~russian Пишет в файл текстовое представление "v"
PIFile & operator <<(uint v);
//! Write to file text representation of "v"
//! \~english Write to file text representation of "v"
//! \~russian Пишет в файл текстовое представление "v"
PIFile & operator <<(ulong v);
//! Write to file text representation of "v"
//! \~english Write to file text representation of "v"
//! \~russian Пишет в файл текстовое представление "v"
PIFile & operator <<(ullong v);
//! Write to file text representation of "v" with precision \a precision()
//! \~english Write to file text representation of "v" with precision \a precision()
//! \~russian Пишет в файл текстовое представление "v" с точностью \a precision()
PIFile & operator <<(float v);
//! Write to file text representation of "v" with precision \a precision()
//! \~english Write to file text representation of "v" with precision \a precision()
//! \~russian Пишет в файл текстовое представление "v" с точностью \a precision()
PIFile & operator <<(double v);
//! Read from file text representation of "v"
//! \~english Read from file text representation of "v"
//! \~russian Читает из файла текстовое представление "v"
PIFile & operator >>(char & v);
//! Read from file text representation of "v"
//! \~english Read from file text representation of "v"
//! \~russian Читает из файла текстовое представление "v"
PIFile & operator >>(short & v);
//! Read from file text representation of "v"
//! \~english Read from file text representation of "v"
//! \~russian Читает из файла текстовое представление "v"
PIFile & operator >>(int & v);
//! Read from file text representation of "v"
//! \~english Read from file text representation of "v"
//! \~russian Читает из файла текстовое представление "v"
PIFile & operator >>(long & v);
//! Read from file text representation of "v"
//! \~english Read from file text representation of "v"
//! \~russian Читает из файла текстовое представление "v"
PIFile & operator >>(llong & v);
//! Read from file text representation of "v"
//! \~english Read from file text representation of "v"
//! \~russian Читает из файла текстовое представление "v"
PIFile & operator >>(uchar & v);
//! Read from file text representation of "v"
//! \~english Read from file text representation of "v"
//! \~russian Читает из файла текстовое представление "v"
PIFile & operator >>(ushort & v);
//! Read from file text representation of "v"
//! \~english Read from file text representation of "v"
//! \~russian Читает из файла текстовое представление "v"
PIFile & operator >>(uint & v);
//! Read from file text representation of "v"
//! \~english Read from file text representation of "v"
//! \~russian Читает из файла текстовое представление "v"
PIFile & operator >>(ulong & v);
//! Read from file text representation of "v"
//! \~english Read from file text representation of "v"
//! \~russian Читает из файла текстовое представление "v"
PIFile & operator >>(ullong & v);
//! Read from file text representation of "v"
//! \~english Read from file text representation of "v"
//! \~russian Читает из файла текстовое представление "v"
PIFile & operator >>(float & v);
//! Read from file text representation of "v"
//! \~english Read from file text representation of "v"
//! \~russian Читает из файла текстовое представление "v"
PIFile & operator >>(double & v);
EVENT_HANDLER(void, clear);
@@ -242,44 +420,56 @@ public:
EVENT_HANDLER1(void, resize, llong, new_size) {resize(new_size, 0);}
EVENT_HANDLER2(void, resize, llong, new_size, uchar, fill);
//!
//! \~english
//! \~russian
static const char * defaultCharset();
//!
//! \~english
//! \~russian
static void setDefaultCharset(const char * c);
//! Returns if file with path "path" does exists
//! \~english Returns if file with path "path" exists
//! \~russian Возвращает существует ли файл с путём "path"
static bool isExists(const PIString & path);
//! Remove file with path "path" and returns if remove was successful
//! \~english Remove file with path "path" and returns if remove successful
//! \~russian Удаляет файл с путём "path" и возвращает успешность операции
static bool remove(const PIString & path);
//! Rename file with path "from" to path "to" and returns if rename was successful
//! \~english Rename file with path "from" to path "to" and returns if rename successful
//! \~russian Переименовывает файл с путём "path" на "to" и возвращает успешность операции
static bool rename(const PIString & from, const PIString & to);
//! Returns FileInfo of file or dir with path "path"
//! \~english Returns \a PIFile::FileInfo of file or dir with path "path"
//! \~russian Возвращает \a PIFile::FileInfo файла или директории с путём "path"
static FileInfo fileInfo(const PIString & path);
//! Apply "info" parameters to file or dir with path "path"
//! \~english Apply "info" parameters to file or dir with path "path"
//! \~russian Применяет параметры "info" к файлу или директории с путём "path"
static bool applyFileInfo(const PIString & path, const FileInfo & info);
//! Apply "info" parameters to file or dir with path "info".path
//! \~english Apply "info" parameters to file or dir with path "info".path
//! \~russian Применяет параметры "info" к файлу или директории с путём "info".path
static bool applyFileInfo(const FileInfo & info) {return applyFileInfo(info.path, info);}
//! \handlers
//! \{
//! \fn void clear()
//! \brief Clear content of file
//! \~english Clear content of file
//! \~russian Очищает содержимое файла
//! \fn void resize(llong new_size)
//! \brief Resize file to "new_size" with "fill" filling
//! \~english Resize file to "new_size" with null-byte fill
//! \~russian Изменяет размер файла на "new_size" с заполнением нулевыми байтами
//! \fn void resize(llong new_size, uchar fill)
//! \brief Resize file to "new_size" with "fill" filling
//! \~english Resize file to "new_size" with "fill" fill
//! \~russian Изменяет размер файла на "new_size" с заполнением байтами "fill"
//! \fn void remove()
//! \brief Remove file
//! \~english Remove file
//! \~russian Удаляет файл
//! \}
//! \ioparams
@@ -289,7 +479,6 @@ public:
//! \}
protected:
PIString fullPathPrefix() const {return PIStringAscii("file");}
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);
PIPropertyStorage constructVariantDevice() const;
@@ -311,6 +500,10 @@ private:
};
//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
inline PICout operator <<(PICout s, const PIFile::FileInfo & v) {
s.setControl(0, true);
s << "FileInfo(\"" << v.path << "\", " << PIString::readableSize(v.size) << ", "
@@ -322,9 +515,17 @@ inline PICout operator <<(PICout s, const PIFile::FileInfo & v) {
}
//! \relatesalso PIByteArray
//! \~english Store operator
//! \~russian Оператор сохранения
inline PIByteArray & operator <<(PIByteArray & s, const PIFile::FileInfo & v) {s << v.path << v.size << v.time_access << v.time_modification <<
(int)v.flags << v.id_user << v.id_group << v.perm_user.raw << v.perm_group.raw << v.perm_other.raw; return s;}
//! \relatesalso PIByteArray
//! \~english Restore operator
//! \~russian Оператор извлечения
inline PIByteArray & operator >>(PIByteArray & s, PIFile::FileInfo & v) {s >> v.path >> v.size >> v.time_access >> v.time_modification >>
*(int*)(&(v.flags)) >> v.id_user >> v.id_group >> v.perm_user.raw >> v.perm_group.raw >> v.perm_other.raw; return s;}
#endif // PIFILE_H

View File

@@ -28,25 +28,40 @@
#endif
/*! \class PIGPIO
* \brief GPIO support
*
* \section PIGPIO_sec0 Synopsis
* This class provide initialize, get/set and watch functions for GPIO.
*
* Currently supported only \"/sys/class/gpio\" mechanism on Linux.
*
* This class should be used with \a PIGPIO::instance() singleton.
*
*
*
* \section PIGPIO_sec1 API
* There are several function to directly read or write pin states.
*
* Also you can start %PIGPIO as thread to watch pin states and receive
* \a pinChanged() event.
*
*/
//! \class PIGPIO pigpio.h
//! \~english \section PIGPIO_sec0 Synopsis
//! \~russian \section PIGPIO_sec0 Краткий обзор
//! \~english
//! This class provide initialize, get/set and watch functions for GPIO.
//!
//! This class should be used with \a PIGPIO::instance() singleton.
//!
//! Currently supported only "/sys/class/gpio" mechanism on Linux.
//!
//!
//! \~russian
//! Этот класс предоставляет инициализацию, установку, чтение и наблюдение
//! за GPIO.
//!
//! Этот класс используется только через синглтон \a PIGPIO::instance().
//!
//! Сейчас поддерживается только "/sys/class/gpio" для Linux.
//!
//!
//! \~\section PIGPIO_sec1 API
//! \~english
//! There are several function to directly read or write pin states.
//!
//! Also you can start %PIGPIO as thread to watch pin states and receive
//! \a pinChanged() event.
//!
//!
//! \~russian
//! Имеется несколько методов для прямой записи и чтения состояний пинов.
//!
//! Также можно запустить %PIGPIO как поток для наблюдения за пинами и
//! принимать события \a pinChanged().
//!
PIGPIO::PIGPIO(): PIThread() {
@@ -155,20 +170,26 @@ void PIGPIO::begin() {
void PIGPIO::run() {
PIMutexLocker ml(mutex);
if (watch_state.isEmpty()) return;
PIVector<int> ids = watch_state.keys();
for(int i = 0; i < ids.size_s(); i++) {
GPIOData & g(gpio_[ids[i]]);
if (g.num != -1 && !g.name.isEmpty()) {
mutex.lock();
if (watch_state.isEmpty()) {
mutex.unlock();
return;
}
PIVector<PIPair<int, bool>> changed;
auto it = watch_state.makeIterator();
while (it.next()) {
GPIOData & g(gpio_[it.key()]);
if (g.num == -1 || g.name.isEmpty()) continue;
bool v = getPinState(g.num);
//piCoutObj << "*** pin state ***" << ids[i] << "=" << v;
if (watch_state[g.num] != v) {
watch_state[g.num] = v;
pinChanged(g.num, v);
}
changed.push_back({g.num, v});
}
}
mutex.unlock();
for (const auto & i: changed)
pinChanged(i.first, i.second);
}
@@ -199,6 +220,7 @@ void PIGPIO::initPin(int gpio_num, Direction dir) {
}
g.dir = dir;
int ret = 0;
NO_UNUSED(ret);
switch(dir) {
case In:
ret = system(("echo in >> /sys/class/gpio/" + g.name + "/direction").dataAscii());
@@ -218,6 +240,7 @@ void PIGPIO::pinSet(int gpio_num, bool value) {
PIMutexLocker ml(mutex);
GPIOData & g(gpio_[gpio_num]);
int ret = 0;
NO_UNUSED(ret);
if (g.fd != -1) {
if (value) ret = ::write(g.fd, "1", 1);
else ret = ::write(g.fd, "0", 1);
@@ -233,6 +256,14 @@ bool PIGPIO::pinState(int gpio_num) {
}
//! \~\details
//! \~english
//! This function doesn`t affect thread state!
//! Pins watching starts only with \a PIThread::start() function
//!
//! \~russian
//! Этот метод не меняет состояние потока наблюдения!
//! Наблюдение за пинами начинается методом \a PIThread::start()
void PIGPIO::pinBeginWatch(int gpio_num) {
PIMutexLocker ml(mutex);
GPIOData & g(gpio_[gpio_num]);
@@ -246,12 +277,28 @@ void PIGPIO::pinBeginWatch(int gpio_num) {
}
//! \~\details
//! \~english
//! This function doesn`t affect thread state!
//! Pins watching starts only with \a PIThread::start() function
//!
//! \~russian
//! Этот метод не меняет состояние потока наблюдения!
//! Наблюдение за пинами начинается методом \a PIThread::start()
void PIGPIO::pinEndWatch(int gpio_num) {
PIMutexLocker ml(mutex);
watch_state.remove(gpio_num);
}
//! \~\details
//! \~english
//! This function doesn`t affect thread state!
//! Pins watching starts only with \a PIThread::start() function
//!
//! \~russian
//! Этот метод не меняет состояние потока наблюдения!
//! Наблюдение за пинами начинается методом \a PIThread::start()
void PIGPIO::clearWatch() {
PIMutexLocker ml(mutex);
watch_state.clear();
@@ -259,5 +306,5 @@ void PIGPIO::clearWatch() {
#ifdef __GNUC__
# pragma GCC diagnostic pop
//# pragma GCC diagnostic pop
#endif

View File

@@ -29,50 +29,57 @@
#include "pithread.h"
//! \ingroup IO
//! \~\brief
//! \~english GPIO support.
//! \~russian Поддержка GPIO.
class PIP_EXPORT PIGPIO: public PIThread
{
PIOBJECT_SUBCLASS(PIGPIO, PIThread)
public:
PIGPIO();
virtual ~PIGPIO();
//! \brief Work mode for pin
//! \~english Work mode for pin
//! \~russian Режим работы пина
enum Direction {
In /** Input direction (read) */,
Out /** Output direction (write) */
In /** \~english Input direction (read) \~russian Входной (чтение) */,
Out /** \~english Output direction (write) \~russian Выходной (запись) */
};
//! \brief Returns singleton object of %PIGPIO
//! \~english Returns singleton object of %PIGPIO
//! \~russian Возвращает синглтон объекта %PIGPIO
static PIGPIO * instance();
//! \brief Initialize pin \"gpio_num\" for \"dir\" mode
//! \~english Initialize pin "gpio_num" for "dir" mode
//! \~russian Инициализирует пин "gpio_num" для режима работы "dir"
void initPin(int gpio_num, Direction dir = PIGPIO::In);
//! \brief Set pin \"gpio_num\" value to \"value\"
//! \~english Set pin "gpio_num" value to "value"
//! \~russian Устанавливает значение пина "gpio_num" в "value"
void pinSet (int gpio_num, bool value);
//! \brief Set pin \"gpio_num\" value to \b true
//! \~english Set pin "gpio_num" value to \b true
//! \~russian Устанавливает значение пина "gpio_num" в \b true
void pinHigh (int gpio_num) {pinSet(gpio_num, true );}
//! \brief Set pin \"gpio_num\" value to \b false
//! \~english Set pin "gpio_num" value to \b false
//! \~russian Устанавливает значение пина "gpio_num" в \b false
void pinLow (int gpio_num) {pinSet(gpio_num, false);}
//! \brief Returns pin \"gpio_num\" state
//!
//! \~english Returns pin "gpio_num" state
//! \~russian Возвращает значение пина "gpio_num"
bool pinState(int gpio_num);
//! \brief Starts watch for pin \"gpio_num\".
//! \details Pins watching starts only with \a PIThread::start() function!
//! This function doesn`t affect thread state
//! \~english Starts watch for pin "gpio_num"
//! \~russian Начинает наблюдение за пином "gpio_num"
void pinBeginWatch(int gpio_num);
//! \brief End watch for pin \"gpio_num\".
//! \details Pins watching starts only with \a PIThread::start() function!
//! This function doesn`t affect thread state
//! \~english End watch for pin "gpio_num"
//! \~russian Заканчивает наблюдение за пином "gpio_num"
void pinEndWatch (int gpio_num);
//! \brief End watch for all pins.
//! \details Pins watching starts only with \a PIThread::start() function!
//! This function doesn`t affect thread state
//! \~english End watch for all pins
//! \~russian Заканчивает наблюдение за всеми пинами
void clearWatch();
EVENT2(pinChanged, int, gpio_num, bool, new_value)
@@ -81,13 +88,20 @@ public:
//! \{
//! \fn void pinChanged(int gpio_num, bool new_value)
//! \brief Raise on pin \"gpio_num\" state changes to \"new_value\"
//! \details Important! This event will be raised only with started
//! thread.
//! \~english Raise on pin "gpio_num" state changes to "new_value"
//! \~russian Вызывается по смене состояния пина "gpio_num" на "new_value"
//! \~\details
//! \~\warning
//! \~english This event raised only when thread started.
//! \~russian Это событие вызывается только при запущенном потоке.
//! \}
private:
PIGPIO();
virtual ~PIGPIO();
NO_COPY_CLASS(PIGPIO)
struct PIP_EXPORT GPIOData {
GPIOData() {dir = PIGPIO::In; num = fd = -1;}
PIString name;

View File

@@ -20,12 +20,15 @@
#include "piiobytearray.h"
/*! \class PIIOByteArray
* \brief PIIODevice wrapper around PIByteArray
*
* \section PIIOByteArray_sec0 Synopsis
* This class sllow you to use PIByteArray as PIIODevice and pass it to, e.g. PIConfig
*/
//! \class PIIOByteArray piiobytearray.h
//! \details
//! \~english
//! This class allow you to use PIByteArray as PIIODevice, e.g. to pass it to PIConfig.
//!
//! \~russian
//! Этот класс позволяет использовать PIByteArray в качестве PIIODevice, например,
//! для передачи в PIConfig.
//!
PIIOByteArray::PIIOByteArray(PIByteArray *buffer, PIIODevice::DeviceMode mode) {

View File

@@ -29,44 +29,59 @@
#include "piiodevice.h"
//! \ingroup IO
//! \~\brief
//! \~english PIIODevice wrapper around PIByteArray
//! \~russian Обёртка PIIODevice вокруг PIByteArray
class PIP_EXPORT PIIOByteArray: public PIIODevice
{
PIIODEVICE(PIIOByteArray)
PIIODEVICE(PIIOByteArray, "")
public:
//! Contructs %PIIOByteArray with \"buffer\" content and \"mode\" open mode
//! \~english Contructs %PIIOByteArray with "buffer" content and "mode" open mode
//! \~russian Создает %PIIOByteArray с содержимым "buffer" и режимом открытия "mode"
explicit PIIOByteArray(PIByteArray * buffer = 0, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
//! Contructs %PIIOByteArray with \"buffer\" content only for read
//! \~english Contructs %PIIOByteArray with "buffer" content only for read
//! \~russian Создает %PIIOByteArray с содержимым "buffer" только для чтения
explicit PIIOByteArray(const PIByteArray & buffer);
//! Returns content
//! \~english Returns content
//! \~russian Возвращает содержимое
PIByteArray * byteArray() const {return data_;}
//! Clear content buffer
//! \~english Clear content buffer
//! \~russian Очищает содержимое буфера
void clear() {if (data_) data_->clear(); pos = 0;}
//! Open \"buffer\" content with \"mode\" open mode
//! \~english Open "buffer" content with "mode" open mode
//! \~russian Открывает содержимое "buffer" с режимом открытия "mode"
bool open(PIByteArray * buffer, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
//! Open \"buffer\" content only for read
//! \~english Open "buffer" content only for read
//! \~russian Открывает содержимое "buffer" только для чтения
bool open(const PIByteArray & buffer);
//! Returns if position is at the end of content
//! \~english Returns if position is at the end of content
//! \~russian Возвращает в конце содержимого ли позиция
bool isEnd() const {if (!data_) return true; return pos >= data_->size_s();}
//! Move read/write position to \"position\"
//! \~english Move read/write position to "position"
//! \~russian Перемещает позицию чтения/записи на "position"
void seek(llong position) {pos = position;}
//! Move read/write position to the begin of the string
//! \~english Move read/write position to the beginning of the buffer
//! \~russian Перемещает позицию чтения/записи на начало буфера
void seekToBegin() {if (data_) pos = 0;}
//! Move read/write position to the end of the string
//! \~english Move read/write position to the end of the buffer
//! \~russian Перемещает позицию чтения/записи на конец буфера
void seekToEnd() {if (data_) pos = data_->size_s();}
//! Insert data \"ba\" into content at current position
//! \~english Insert data "ba" into content at current position
//! \~russian Вставляет данные "ba" в содержимое буфера в текущую позицию
int writeByteArray(const PIByteArray & ba);
protected:

View File

@@ -23,13 +23,7 @@
#include "pipropertystorage.h"
//! \addtogroup IO
//! \{
//! \class PIIODevice piiodevice.h
//! \brief
//! \~english Base class for input/output classes
//! \~russian Базовый класс утройств ввода/вывода
//!
//! \~\details
//! \section PIIODevice_sec0 Synopsis
//! This class provide open/close logic, threaded read/write and virtual input/output
@@ -84,11 +78,10 @@
//!
//! \section PIIODevice_sec7 Creating devices by unambiguous string
//! There are some virtual functions to describe child class without its declaration.
//! \n \a fullPathPrefix() should returns unique prefix of device
//! \n \a constructFullPath() should returns full unambiguous string, contains prefix and all device parameters
//! \n \a configureFromFullPath() provide configuring device from full unambiguous string without prefix and "://"
//! \n Macro PIIODEVICE should be used instead of PIOBJECT
//! \n Macro REGISTER_DEVICE should be used after definition of class, i.e. at the last line of *.cpp file
//! \n Macro REGISTER_DEVICE should be used after declaration of class, i.e. at the last line of *.h file
//! \n \n If custom I/O device corresponds there rules, it can be returned by function \a createFromFullPath().
//! \n Each PIP I/O device has custom unambiguous string description:
//! * PIFile: "file://<path>"
@@ -117,7 +110,6 @@
//! \section PIIODevice_ex0 Example
//! \snippet piiodevice.cpp 0
//!
//! \}
PIMutex PIIODevice::nfp_mutex;
@@ -131,9 +123,6 @@ PIIODevice::PIIODevice(): PIThread() {
}
/*! \brief Constructs a PIIODevice with path and mode
* \param path path to device
* \param type mode for open */
PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode mode): PIThread() {
mode_ = mode;
_init();
@@ -160,6 +149,34 @@ bool PIIODevice::setOption(PIIODevice::DeviceOption o, bool yes) {
}
//! \~\details
//! \~english
//! Set external static function of threaded read that will be executed
//! at every successful threaded read. Function should have format
//! "bool func(void * data, uchar * readed, int size)"
//! \~russian
//! Устанавливает внешний статический метод, который будет вызван
//! после каждого успешного потокового чтения. Метод должен быть
//! в формате "bool func(void * data, uchar * readed, int size)"
void PIIODevice::setThreadedReadSlot(ReadRetFunc func) {
ret_func_ = func;
}
//! \~\details
//! \~english
//! Default size is 4096 bytes. If your device can read at single read
//! more than 4096 bytes you should use this function to adjust buffer size
//! \~russian
//! По умолчанию 4096 байт. Если устройство за одно чтение может читать
//! более 4096 байт, необходимо использовать этот метод для установки
//! нужного размера буфера
void PIIODevice::setThreadedReadBufferSize(int new_size) {
threaded_read_buffer_size = new_size;
threadedReadBufferSizeChanged();
}
bool stopThread(PIThread * t, bool hard) {
#ifdef MICRO_PIP
t->stop(true);
@@ -265,15 +282,12 @@ void PIIODevice::write_func() {
}
PIIODevice * PIIODevice::newDeviceByPrefix(const PIString & prefix) {
if (prefix.isEmpty()) return 0;
PIVector<const PIObject * > rd(PICollection::groupElements("__PIIODevices__"));
piForeachC (PIObject * d, rd) {
if (prefix == ((const PIIODevice * )d)->fullPathPrefix()) {
return ((const PIIODevice * )d)->copy();
}
}
return 0;
PIIODevice * PIIODevice::newDeviceByPrefix(const char * prefix) {
if (!prefix) return nullptr;
auto fi = fabrics().value(prefix);
if (fi.fabricator)
return fi.fabricator();
return nullptr;
}
@@ -427,7 +441,7 @@ bool PIIODevice::configure(const PIString & config_file, const PIString & sectio
PIString PIIODevice::constructFullPath() const {
return fullPathPrefix() + "://" + constructFullPathDevice() + fullPathOptions();
return fullPathPrefix().toString() + PIStringAscii("://") + constructFullPathDevice() + fullPathOptions();
}
@@ -462,23 +476,23 @@ void PIIODevice::configureFromVariant(const PIVariantTypes::IODevice & d) {
void PIIODevice::splitFullPath(PIString fpwm, PIString * full_path, DeviceMode * mode, DeviceOptions * opts) {
int dm = 0;
DeviceOptions op = 0;
if (fpwm.find("(") > 0 && fpwm.find(")") > 0) {
PIString dms(fpwm.right(fpwm.length() - fpwm.findLast("(")).takeRange("(", ")").trim().toLowerCase().removeAll(' '));
if (fpwm.find('(') > 0 && fpwm.find(')') > 0) {
PIString dms(fpwm.right(fpwm.length() - fpwm.findLast('(')).takeRange('(', ')').trim().toLowerCase().removeAll(' '));
PIStringList opts(dms.split(","));
piForeachC (PIString & o, opts) {
//piCout << dms;
if (o == "r" || o == "ro" || o == "read" || o == "readonly")
if (o == PIStringAscii("r") || o == PIStringAscii("ro") || o == PIStringAscii("read") || o == PIStringAscii("readonly"))
dm |= ReadOnly;
if (o == "w" || o == "wo" || o == "write" || o == "writeonly")
if (o == PIStringAscii("w") || o == PIStringAscii("wo") || o == PIStringAscii("write") || o == PIStringAscii("writeonly"))
dm |= WriteOnly;
if (o == "br" || o == "blockr" || o == "blockread" || o == "blockingread")
if (o == PIStringAscii("br") || o == PIStringAscii("blockr") || o == PIStringAscii("blockread") || o == PIStringAscii("blockingread"))
op |= BlockingRead;
if (o == "bw" || o == "blockw" || o == "blockwrite" || o == "blockingwrite")
if (o == PIStringAscii("bw") || o == PIStringAscii("blockw") || o == PIStringAscii("blockwrite") || o == PIStringAscii("blockingwrite"))
op |= BlockingWrite;
if (o == "brw" || o == "bwr" || o == "blockrw" || o == "blockwr" || o == "blockreadrite" || o == "blockingreadwrite")
if (o == PIStringAscii("brw") || o == PIStringAscii("bwr") || o == PIStringAscii("blockrw") || o == PIStringAscii("blockwr") || o == PIStringAscii("blockreadrite") || o == PIStringAscii("blockingreadwrite"))
op |= BlockingRead | BlockingWrite;
}
fpwm.cutRight(fpwm.length() - fpwm.findLast("(")).trim();
fpwm.cutRight(fpwm.length() - fpwm.findLast('(')).trim();
}
if (dm == 0) dm = ReadWrite;
if (full_path) *full_path = fpwm;
@@ -489,14 +503,33 @@ void PIIODevice::splitFullPath(PIString fpwm, PIString * full_path, DeviceMode *
PIStringList PIIODevice::availablePrefixes() {
PIStringList ret;
PIVector<const PIObject * > rd(PICollection::groupElements("__PIIODevices__"));
piForeachC (PIObject * d, rd) {
ret << ((const PIIODevice * )d)->fullPathPrefix();
}
for (const auto & i: fabrics())
ret << i.second.prefix.toString();
return ret;
}
PIStringList PIIODevice::availableClasses() {
PIStringList ret;
for (const auto & i: fabrics())
ret << i.second.classname.toString();
return ret;
}
void PIIODevice::registerDevice(PIConstChars prefix, PIConstChars classname, PIIODevice * (*fabric)()) {
if (prefix.isEmpty()) return;
//printf("registerDevice %s %d %d\n", prefix, p.isEmpty(), fabrics().size());
if (!fabrics().contains(prefix)) {
FabricInfo fi;
fi.prefix = prefix;
fi.classname = classname;
fi.fabricator = fabric;
fabrics()[prefix] = fi;
}
}
PIString PIIODevice::fullPathOptions() const {
if (mode_ == ReadWrite && options_ == 0) return PIString();
PIString ret(" (");
@@ -509,10 +542,17 @@ PIString PIIODevice::fullPathOptions() const {
}
//! \~\details
//! \~english
//! To function \a configureFromFullPath() "full_path" passed without \a fullPathPrefix() and "://".
//! See \ref PIIODevice_sec7
//! \~russian
//! В метод \a configureFromFullPath() "full_path" передается без \a fullPathPrefix() и "://".
//! См. \ref PIIODevice_sec7
PIIODevice * PIIODevice::createFromFullPath(const PIString & full_path) {
PIString prefix = full_path.left(full_path.find(":"));
PIIODevice * nd = newDeviceByPrefix(prefix);
if (!nd) return 0;
PIIODevice * nd = newDeviceByPrefix(prefix.dataAscii());
if (!nd) return nullptr;
nd->configureFromFullPath(full_path.mid(prefix.length() + 3));
cacheFullPath(full_path, nd);
return nd;
@@ -520,8 +560,8 @@ PIIODevice * PIIODevice::createFromFullPath(const PIString & full_path) {
PIIODevice * PIIODevice::createFromVariant(const PIVariantTypes::IODevice & d) {
PIIODevice * nd = newDeviceByPrefix(d.prefix);
if (!nd) return 0;
PIIODevice * nd = newDeviceByPrefix(d.prefix.dataAscii());
if (!nd) return nullptr;
nd->configureFromVariant(d);
return nd;
}
@@ -550,6 +590,12 @@ void PIIODevice::cacheFullPath(const PIString & full_path, const PIIODevice * d)
}
PIMap<PIConstChars, PIIODevice::FabricInfo> & PIIODevice::fabrics() {
static PIMap<PIConstChars, FabricInfo> ret;
return ret;
}
bool PIIODevice::threadedRead(uchar *readed, int size) {
// piCout << "iodevice threaded read";
if (ret_func_ != 0) return ret_func_(ret_data_, readed, size);

View File

@@ -27,7 +27,6 @@
#define PIIODEVICE_H
#include "piinit.h"
#include "picollection.h"
#include "pitimer.h"
#include "piqueue.h"
@@ -38,20 +37,46 @@ typedef bool (*ReadRetFunc)(void * , uchar * , int );
#ifdef DOXYGEN
//! \relatesalso PIIODevice \brief Use this macro to enable automatic creation instances of your class with \a createFromFullPath() function
//! \relatesalso PIIODevice
//! \brief
//! \~english Enable device instances creation with \a PIIODevice::createFromFullPath() function.
//! \~russian Включить создание экземпляров устройства с помощью метода \a PIIODevice::createFromFullPath().
//! \~\details
//! \~english This macro may be placed in cpp or header file, but preferred place is header
//! \~russian Этот макрос может быть расположен в cpp или заголовочном файле, но предпочтительнее распологать в заголовочном
# define REGISTER_DEVICE(class)
//! \relatesalso PIIODevice \brief Use this macro instead of PIOBJECT when describe your own PIIODevice
# define PIIODEVICE(class)
//! \relatesalso PIIODevice
//! \brief
//! \~english Use this macro instead of PIOBJECT when describe your own PIIODevice.
//! \~russian Используйте этот макрос вместо PIOBJECT при объявлении своего PIIODevice.
//! \~\param "prefix"
//! \~english Unique device prefix in quotes, may be ""
//! \~russian Уникальный префикс устройства в кавычках, может быть ""
# define PIIODEVICE(class, "prefix")
#else
# define REGISTER_DEVICE(name) ADD_NEW_TO_COLLECTION_WITH_NAME(__PIIODevices__, name, __S__collection_##name##__)
# define PIIODEVICE(name) PIOBJECT_SUBCLASS(name, PIIODevice) PIIODevice * copy() const {return new name();}
# define REGISTER_DEVICE(name) \
STATIC_INITIALIZER_BEGIN \
PIIODevice::registerDevice(name::fullPathPrefixS(), #name, []()->PIIODevice*{return new name();});\
STATIC_INITIALIZER_END
# define PIIODEVICE(name, prefix) \
PIOBJECT_SUBCLASS(name, PIIODevice) \
PIIODevice * copy() const {return new name();} \
public: \
virtual PIConstChars fullPathPrefix() const {return prefix;} \
static PIConstChars fullPathPrefixS() {return prefix;} \
private:
#endif
//! \ingroup IO
//! \~\brief
//! \~english Base class for input/output devices.
//! \~russian Базовый класс утройств ввода/вывода.
class PIP_EXPORT PIIODevice: public PIThread
{
PIOBJECT_SUBCLASS(PIIODevice, PIThread)
@@ -59,207 +84,271 @@ class PIP_EXPORT PIIODevice: public PIThread
public:
NO_COPY_CLASS(PIIODevice)
//! Constructs a empty PIIODevice
//! \~english Constructs a empty %PIIODevice
//! \~russian Создает пустой %PIIODevice
explicit PIIODevice();
//! \brief Open modes for PIIODevice
//! \~english Open modes for PIIODevice
//! \~russian Режимы открытия для PIIODevice
enum DeviceMode {
ReadOnly /*! Device can only read */ = 0x01,
WriteOnly /*! Device can only write */ = 0x02,
ReadWrite /*! Device can both read and write */ = 0x03
ReadOnly /*! \~english Device can only read \~russian Устройство может только читать */ = 0x01,
WriteOnly /*! \~english Device can only write \~russian Устройство может только писать */ = 0x02,
ReadWrite /*! \~english Device can both read and write \~russian Устройство может читать и писать */ = 0x03
};
//! \brief Options for PIIODevice, works with some devices
//! \~english Options for PIIODevice, works with some devices
//! \~russian Опции для PIIODevice, работает для некоторых устройств
enum DeviceOption {
BlockingRead /*! \a read block until data is received, default off */ = 0x01,
BlockingWrite /*! \a write block until data is sent, default off */ = 0x02
BlockingRead /*! \~english \a read() block until data is received, default off \~russian \a read() блокируется, пока данные не поступят, по умолчанию выключено */ = 0x01,
BlockingWrite /*! \~english \a write() block until data is sent, default off \~russian \a write() блокируется, пока данные не запишутся, по умолчанию выключено */ = 0x02
};
//! \brief Characteristics of PIIODevice subclass
//! \~english Characteristics of PIIODevice channel
//! \~russian Характеристики канала PIIODevice
enum DeviceInfoFlag {
Sequential /*! Continuous bytestream without datagrams */ = 0x01,
Reliable /*! Channel without data errors / corruptions */ = 0x02
Sequential /*! \~english Continuous bytestream without packets \~russian Непрерывный поток байт, без пакетирования */ = 0x01,
Reliable /*! \~english Channel without data errors or corruptions \~russian Канал без ошибок или повреждений данных */ = 0x02
};
struct FabricInfo {
PIConstChars prefix;
PIConstChars classname;
PIIODevice*(*fabricator)() = nullptr;
};
typedef PIFlags<DeviceOption> DeviceOptions;
typedef PIFlags<DeviceInfoFlag> DeviceInfoFlags;
//! \~english Constructs %PIIODevice with path "path" and open mode "mode"
//! \~russian Создает %PIIODevice с путём "path" и режимом открытия "mode"
explicit PIIODevice(const PIString & path, DeviceMode mode = ReadWrite);
virtual ~PIIODevice();
//! Current open mode of device
//! \~english Returns current open mode of device
//! \~russian Возвращает текущий режим открытия устройства
DeviceMode mode() const {return mode_;}
//! Set open mode of device
//! \~english Set open mode of device. Don`t reopen device
//! \~russian Устанавливает режим открытия устройства. Не переоткрывает устройство
void setMode(DeviceMode m) {mode_ = m;}
//! Current device options
//! \~english Returns current device options
//! \~russian Возвращает текущие опции устройства
DeviceOptions options() const {return options_;}
//! Current device option "o" state
//! \~english Returns current device option "o" state
//! \~russian Возвращает текущее состояние опции "o"
bool isOptionSet(DeviceOption o) const {return options_[o];}
//! Set device options
//! \~english Set device options
//! \~russian Устанавливает опции устройства
void setOptions(DeviceOptions o);
//! Set device option "o" to "yes" and return previous state
//! \~english Set device option "o" to "yes" and returns previous state
//! \~russian Устанавливает опцию "o" устройства в "yes" и возвращает предыдущее состояние опции
bool setOption(DeviceOption o, bool yes = true);
//! Returns device characteristic flags
//! \~english Returns device characteristic flags
//! \~russian Возвращает характеристики канала
DeviceInfoFlags infoFlags() const {return deviceInfoFlags();}
//! Current path of device
PIString path() const {return property(PIStringAscii("path")).toString();}
//! \~english Returns current path of device
//! \~russian Возвращает текущий путь устройства
PIString path() const {return property("path").toString();}
//! Set path of device
void setPath(const PIString & path) {setProperty(PIStringAscii("path"), path);}
//! \~english Set path of device. Don`t reopen device
//! \~russian Устанавливает путь устройства. Не переоткрывает устройство
void setPath(const PIString & path) {setProperty("path", path);}
//! Return \b true if mode is ReadOnly or ReadWrite
//! \~english Returns if mode is ReadOnly or ReadWrite
//! \~russian Возвращает равен ли режим открытия ReadOnly или ReadWrite
bool isReadable() const {return (mode_ & ReadOnly);}
//! Return \b true if mode is WriteOnly or ReadWrite
//! \~english Returns if mode is WriteOnly or ReadWrite
//! \~russian Возвращает равен ли режим открытия WriteOnly или ReadWrite
bool isWriteable() const {return (mode_ & WriteOnly);}
//! Return \b true if device is successfully opened
//! \~english Returns if device is successfully opened
//! \~russian Возвращает успешно ли открыто устройство
bool isOpened() const {return opened_;}
//! Return \b true if device is closed
//! \~english Returns if device is closed
//! \~russian Возвращает закрыто ли устройство
bool isClosed() const {return !opened_;}
//! Return \b true if device can read \b now
//! \~english Returns if device can read \b now
//! \~russian Возвращает может ли устройство читать \b сейчас
virtual bool canRead() const {return opened_ && (mode_ & ReadOnly);}
//! Return \b true if device can write \b now
//! \~english Returns if device can write \b now
//! \~russian Возвращает может ли устройство писать \b сейчас
virtual bool canWrite() const {return opened_ && (mode_ & WriteOnly);}
//! Set execution of \a open enabled while threaded read on closed device
void setReopenEnabled(bool yes = true) {setProperty(PIStringAscii("reopenEnabled"), yes);}
//! \~english Set calling of \a open() enabled while threaded read on closed device
//! \~russian Устанавливает возможность вызова \a open() при потоковом чтении на закрытом устройстве
void setReopenEnabled(bool yes = true) {setProperty("reopenEnabled", yes);}
//! Set timeout in milliseconds between \a open tryings if reopen is enabled
void setReopenTimeout(int msecs) {setProperty(PIStringAscii("reopenTimeout"), msecs);}
//!
//! \~english Set timeout in milliseconds between \a open() tryings if reopen is enabled
//! \~russian Устанавливает задержку в миллисекундах между вызовами \a open() если переоткрытие активно
void setReopenTimeout(int msecs) {setProperty("reopenTimeout", msecs);}
//! \~english Returns reopen enable
//! \~russian Возвращает активно ли переоткрытие
bool isReopenEnabled() const {return property("reopenEnabled").toBool();}
//! \~english Returns reopen timeout in milliseconds
//! \~russian Возвращает задержку переоткрытия в миллисекундах
int reopenTimeout() {return property("reopenTimeout").toInt();}
//! Return reopen enable
bool isReopenEnabled() const {return property(PIStringAscii("reopenEnabled")).toBool();}
//! \~english Set threaded read callback
//! \~russian Устанавливает callback потокового чтения
void setThreadedReadSlot(ReadRetFunc func);
//! Return reopen timeout
int reopenTimeout() {return property(PIStringAscii("reopenTimeout")).toInt();}
/** \brief Set "threaded read slot"
* \details Set external static function of threaded read that will be executed
* at every successful threaded read. Function should have format
* "bool func(void * data, uchar * readed, int size)" */
void setThreadedReadSlot(ReadRetFunc func) {ret_func_ = func;}
//! Set custom data that will be passed to "threaded read slot"
//! \~english Set custom data that will be passed to threaded read callback
//! \~russian Устанавливает произвольный указатель, который будет передан в callback потокового чтения
void setThreadedReadData(void * d) {ret_data_ = d;}
/** \brief Set size of threaded read buffer
* \details Default size is 4096 bytes. If your device can read at single read
* more than 4096 bytes you should use this function to adjust buffer size */
void setThreadedReadBufferSize(int new_size) {threaded_read_buffer_size = new_size; threadedReadBufferSizeChanged();}
//! \~english Set size of threaded read buffer
//! \~russian Устанавливает размер буфера потокового чтения
void setThreadedReadBufferSize(int new_size);
//! Return size of threaded read buffer
//! \~english Returns size of threaded read buffer
//! \~russian Возвращает размер буфера потокового чтения
int threadedReadBufferSize() const {return threaded_read_buffer_size;}
//! Return content of threaded read buffer
//! \~english Returns content of threaded read buffer
//! \~russian Возвращает содержимое буфера потокового чтения
const uchar * threadedReadBuffer() const {return buffer_tr.data();}
//! Return custom data that will be passed to "threaded read slot"
//! \~english Returns custom data that will be passed to threaded read callback
//! \~russian Возвращает произвольный указатель, который будет передан в callback потокового чтения
void * threadedReadData() const {return ret_data_;}
//! Return \b true if threaded read is started
//! \~english Returns if threaded read is started
//! \~russian Возвращает запущен ли поток чтения
bool isThreadedRead() const {return isRunning();}
//! Start threaded read
//! \~english Start threaded read
//! \~russian Запускает потоковое чтение
void startThreadedRead() {if (!isRunning()) PIThread::start();}
//! Start threaded read and assign "threaded read slot" to "func"
//! \~english Start threaded read and assign threaded read callback to "func"
//! \~russian Запускает потоковое чтение и устанавливает callback потокового чтения в "func"
void startThreadedRead(ReadRetFunc func) {ret_func_ = func; startThreadedRead();}
//! Stop threaded read. Hard stop terminate thread, otherwise wait fo 10 seconds
//! \~english Stop threaded read. Hard stop terminate thread, otherwise wait fo 10 seconds
//! \~russian Останавливает потоковое чтение. Жесткая остановка убивает поток, иначе ожидает 10 секунд
void stopThreadedRead(bool hard = true);
//! Return \b true if threaded write is started
//! \~english Returns if threaded write is started
//! \~russian Возвращает запущен ли поток записи
bool isThreadedWrite() const {return write_thread.isRunning();}
//! Start threaded write
//! \~english Start threaded write
//! \~russian Запускает потоковую запись
void startThreadedWrite() {if (!write_thread.isRunning()) write_thread.startOnce();}
//! Stop threaded write. Hard stop terminate thread, otherwise wait fo 10 seconds
//! \~english Stop threaded write. Hard stop terminate thread, otherwise wait fo 10 seconds
//! \~russian Останавливает потоковую запись. Жесткая остановка убивает поток, иначе ожидает 10 секунд
void stopThreadedWrite(bool hard = true);
//! Clear threaded write task queue
//! \~english Clear threaded write task queue
//! \~russian Очищает очередь потоковой записи
void clearThreadedWriteQueue();
//! Start both threaded read and threaded write
//! \~english Start both threaded read and threaded write
//! \~russian Запускает потоковое чтение и запись
void start();
//! Stop both threaded read and threaded write. Hard stop terminate threads, otherwise wait fo 10 seconds
//! \~english Stop both threaded read and threaded write. Hard stop terminate threads, otherwise wait fo 10 seconds
//! \~russian Останавливает потоковое чтение и запись. Жесткая остановка убивает потоки, иначе ожидает 10 секунд
void stop(bool hard = true);
//! Read from device maximum "max_size" bytes to "read_to"
//! \~english Read from device maximum "max_size" bytes to "read_to"
//! \~russian Читает из устройства не более "max_size" байт в "read_to"
int read(void * read_to, int max_size) {return readDevice(read_to, max_size);}
//! Read from device maximum "max_size" bytes and return them as PIByteArray
//! \~english Read from device maximum "max_size" bytes and returns them as PIByteArray
//! \~russian Читает из устройства не более "max_size" байт и возвращает данные как PIByteArray
PIByteArray read(int max_size);
//! Write maximum "max_size" bytes of "data" to device
//! \~english Write maximum "max_size" bytes of "data" to device
//! \~russian Пишет в устройство не более "max_size" байт из "data"
int write(const void * data, int max_size) {return writeDevice(data, max_size);}
//! Read from device for "timeout_ms" milliseconds and return readed data as PIByteArray. Timeout should to be greater than 0
//! \~english Read from device for "timeout_ms" milliseconds and return readed data as PIByteArray.
//! Timeout should to be greater than 0
//! \~russian Читает из устройства в течении "timeout_ms" миллисекунд и возвращает данные как PIByteArray.
//! Таймаут должен быть больше 0
PIByteArray readForTime(double timeout_ms);
//! Add task to threaded write queue and return task ID
//! \~english Add task to threaded write queue and return task ID
//! \~russian Добавляет данные в очередь на потоковую запись и возвращает ID задания
ullong writeThreaded(const void * data, int max_size) {return writeThreaded(PIByteArray(data, uint(max_size)));}
//! Add task to threaded write queue and return task ID
//! \~english Add task to threaded write queue and return task ID
//! \~russian Добавляет данные в очередь на потоковую запись и возвращает ID задания
ullong writeThreaded(const PIByteArray & data);
//! Configure device from section "section" of file "config_file", if "parent_section" parent section also will be read
//! \~english Configure device from section "section" of file "config_file", if "parent_section" parent section also will be read
//! \~russian
bool configure(const PIString & config_file, const PIString & section, bool parent_section = false);
//! Reimplement to construct full unambiguous string prefix. \ref PIIODevice_sec7
virtual PIString fullPathPrefix() const {return PIString();}
//! \~english Returns full unambiguous string prefix. \ref PIIODevice_sec7
//! \~russian Возвращает префикс устройства. \ref PIIODevice_sec7
virtual PIConstChars fullPathPrefix() const {return "";}
//! Returns full unambiguous string, describes this device, \a fullPathPrefix() + "://"
static PIConstChars fullPathPrefixS() {return "";}
//! \~english Returns full unambiguous string, describes this device, \a fullPathPrefix() + "://" + ...
//! \~russian Возвращает строку полного описания для этого устройства, \a fullPathPrefix() + "://" + ...
PIString constructFullPath() const;
//! Configure device with parameters of full unambiguous string
//! \~english Configure device with parameters of full unambiguous string
//! \~russian Настраивает устройство из параметров строки полного описания
void configureFromFullPath(const PIString & full_path);
//! Returns PIVariantTypes::IODevice, describes this device
//! \~english Returns PIVariantTypes::IODevice, describes this device
//! \~russian Возвращает PIVariantTypes::IODevice, описывающий это устройство
PIVariantTypes::IODevice constructVariant() const;
//! Configure device from PIVariantTypes::IODevice
//! \~english Configure device from PIVariantTypes::IODevice
//! \~russian Настраивает устройство из PIVariantTypes::IODevice
void configureFromVariant(const PIVariantTypes::IODevice & d);
//! \brief Try to determine suitable device, create new one, configure it with \a configureFromFullPath() and returns it.
//! \details To function \a configureFromFullPath() "full_path" passed without \a fullPathPrefix() + "://".
//! See \ref PIIODevice_sec7
//! \~english Try to create new device by prefix, configure it with \a configureFromFullPath() and returns it.
//! \~russian Пытается создать новое устройство по префиксу, настраивает с помощью \a configureFromFullPath() и возвращает его
static PIIODevice * createFromFullPath(const PIString & full_path);
//! \brief Try to determine suitable device, create new one, configure it with \a configureFromVariant() and returns it.
//! \details To function \a configureFromFullPath() "full_path" passed without \a fullPathPrefix() + "://".
//! See \ref PIIODevice_sec7
//! \~english Try to create new device by prefix, configure it with \a configureFromVariant() and returns it.
//! \~russian Пытается создать новое устройство по префиксу, настраивает с помощью \a configureFromVariant() и возвращает его
static PIIODevice * createFromVariant(const PIVariantTypes::IODevice & d);
static PIString normalizeFullPath(const PIString & full_path);
static void splitFullPath(PIString fpwm, PIString * full_path, DeviceMode * mode = 0, DeviceOptions * opts = 0);
//! Returns fullPath prefixes of all registered devices
//! \~english Returns fullPath prefixes of all registered devices
//! \~russian Возвращает префиксы всех зарегистрированных устройств
static PIStringList availablePrefixes();
//! \~english Returns class names of all registered devices
//! \~russian Возвращает имена классов всех зарегистрированных устройств
static PIStringList availableClasses();
static void registerDevice(PIConstChars prefix, PIConstChars classname, PIIODevice*(*fabric)());
EVENT_HANDLER(bool, open);
EVENT_HANDLER1(bool, open, const PIString &, _path);
@@ -279,114 +368,152 @@ public:
//! \{
//! \fn bool open()
//! \brief Open device
//! \~english Open device
//! \~russian Открывает устройство
//! \fn bool open(const PIString & path)
//! \brief Open device with path "path"
//! \~english Open device with path "path"
//! \~russian Открывает устройство с путём "path"
//! \fn bool open(const DeviceMode & mode)
//! \brief Open device with mode "mode"
//! \~english Open device with mode "mode"
//! \~russian Открывает устройство с режимом открытия "mode"
//! \fn bool open(const PIString & path, const DeviceMode & mode)
//! \brief Open device with path "path" and mode "mode"
//! \~english Open device with path "path" and mode "mode"
//! \~russian Открывает устройство с путём "path" и режимом открытия "mode"
//! \fn bool close()
//! \brief Close device
//! \~english Close device
//! \~russian Закрывает устройство
//! \fn int write(PIByteArray data)
//! \brief Write "data" to device
//! \~english Write "data" to device
//! \~russian Пишет "data" в устройство
//! \}
//! \vhandlers
//! \{
//! \fn void flush()
//! \brief Immediate write all buffers
//! \~english Immediate write all buffers
//! \~russian Немедленно записать все буферизированные данные
//! \}
//! \events
//! \{
//! \fn void opened()
//! \brief Raise if succesfull open
//! \~english Raise if succesfull open
//! \~russian Вызывается при успешном открытии
//! \fn void closed()
//! \brief Raise if succesfull close
//! \~english Raise if succesfull close
//! \~russian Вызывается при успешном закрытии
//! \fn void threadedReadEvent(uchar * readed, int size)
//! \brief Raise if read thread succesfull read some data
//! \~english Raise if read thread succesfull read some data
//! \~russian Вызывается при успешном потоковом чтении данных
//! \fn void threadedWriteEvent(ullong id, int written_size)
//! \brief Raise if write thread successfull write some data of task with ID "id"
//! \~english Raise if write thread successfull write some data of task with ID "id"
//! \~russian Вызывается при успешной потоковой записи данных с ID задания "id"
//! \}
//! \ioparams
//! \{
#ifdef DOXYGEN
//! \brief setReopenEnabled, default "true"
//! \~english setReopenEnabled, default "true"
//! \~russian setReopenEnabled, по умолчанию "true"
bool reopenEnabled;
//! \brief setReopenTimeout in ms, default 1000
//! \~english setReopenTimeout in milliseconds, default 1000
//! \~russian setReopenTimeout в миллисекундах, по умолчанию 1000
int reopenTimeout;
//! \brief setThreadedReadBufferSize in bytes, default 4096
//! \~english setThreadedReadBufferSize in bytes, default 4096
//! \~russian setThreadedReadBufferSize в байтах, по умолчанию 4096
int threadedReadBufferSize;
#endif
//! \}
protected:
//! Function executed before first \a openDevice() or from constructor
//! \~english Function executed before first \a openDevice() or from constructor
//! \~russian Метод вызывается перед первым \a openDevice() или из конструктора
virtual bool init() {return true;}
//! Reimplement to configure device from entries "e_main" and "e_parent", cast arguments to \a PIConfig::Entry*
//! \~english Reimplement to configure device from entries "e_main" and "e_parent", cast arguments to \a PIConfig::Entry*
//! \~russian
virtual bool configureDevice(const void * e_main, const void * e_parent = 0) {return true;}
//! Reimplement to open device, return value will be set to "opened_" variable; don't call this function in subclass, use open()
//! \~english Reimplement to open device, return value will be set to "opened_" variable.
//! Don't call this function in subclass, use \a open()!
//! \~russian Переопределите для открытия устройства, возвращаемое значение будет установлено в
//! переменную "opened_". Не используйте напрямую, только через \a open()!
virtual bool openDevice() = 0; // use path_, type_, opened_, init_ variables
//! Reimplement to close device, inverse return value will be set to "opened_" variable
//! \~english Reimplement to close device, inverse return value will be set to "opened_" variable
//! \~russian Переопределите для закрытия устройства, обратное возвращаемое значение будет установлено в переменную "opened_"
virtual bool closeDevice() {return true;} // use path_, type_, opened_, init_ variables
//! Reimplement this function to read from your device
//! \~english Reimplement this function to read from your device
//! \~russian Переопределите для чтения данных из устройства
virtual int readDevice(void * read_to, int max_size) {piCoutObj << "\"read\" is not implemented!"; return -2;}
//! Reimplement this function to write to your device
//! \~english Reimplement this function to write to your device
//! \~russian Переопределите для записи данных в устройство
virtual int writeDevice(const void * data, int max_size) {piCoutObj << "\"write\" is not implemented!"; return -2;}
//! Function executed when thread read some data, default implementation execute external slot "ret_func_"
//! \~english Function executed when thread read some data, default implementation execute external callback "ret_func_"
//! \~russian Метод вызывается после каждого успешного потокового чтения, по умолчанию вызывает callback "ret_func_"
virtual bool threadedRead(uchar * readed, int size);
//! Reimplement to construct full unambiguous string, describes this device. Default implementation returns \a path()
//! \~english Reimplement to construct full unambiguous string, describes this device.
//! Default implementation returns \a path()
//! \~russian Переопределите для создания строки полного описания устройства.
//! По умолчанию возвращает \a path()
virtual PIString constructFullPathDevice() const {return path();}
//! Reimplement to configure your device with parameters of full unambiguous string. Default implementation does nothing
//! \~english Reimplement to configure your device with parameters of full unambiguous string.
//! Default implementation call \a setPath()
//! \~russian Переопределите для настройки устройства из строки полного описания.
//! По умолчанию вызывает \a setPath()
virtual void configureFromFullPathDevice(const PIString & full_path) {setPath(full_path);}
//! Reimplement to construct device properties.
//! \~english Reimplement to construct device properties.
//! Default implementation return PIPropertyStorage with \"path\" entry
//! \~russian Переопределите для создания свойств устройства.
//! По умолчанию возвращает PIPropertyStorage со свойством \"path\"
virtual PIPropertyStorage constructVariantDevice() const;
//! Reimplement to configure your device from PIPropertyStorage. Options and mode already applied.
//! \~english Reimplement to configure your device from PIPropertyStorage. Options and mode already applied.
//! Default implementation apply \"path\" entry
//! \~russian Переопределите для настройки устройства из PIPropertyStorage. Опции и режим уже применены.
//! По умолчанию устанавливает свойство \"path\"
virtual void configureFromVariantDevice(const PIPropertyStorage & d);
//! Reimplement to apply new device options
//! \~english Reimplement to apply new device options
//! \~russian Переопределите для применения новых опций устройства
virtual void optionsChanged() {;}
//! Reimplement to return correct \a DeviceInfoFlags. Default implementation returns 0
//! \~english Reimplement to return correct \a DeviceInfoFlags. Default implementation returns 0
//! \~russian Переопределите для возврата правильных \a DeviceInfoFlags. По умолчанию возвращает 0
virtual DeviceInfoFlags deviceInfoFlags() const {return 0;}
//! Reimplement to apply new \a threadedReadBufferSize()
//! \~english Reimplement to apply new \a threadedReadBufferSize()
//! \~russian Переопределите для применения нового \a threadedReadBufferSize()
virtual void threadedReadBufferSizeChanged() {;}
//! Invoked after hard read thread stop
//! \~english Invoked after hard read thread stop
//! \~russian Вызывается после жесткой остановки потока чтения
virtual void threadedReadTerminated() {;}
//! Invoked after hard write thread stop
//! \~english Invoked after hard write thread stop
//! \~russian Вызывается после жесткой остановки потока записи
virtual void threadedWriteTerminated() {;}
static PIIODevice * newDeviceByPrefix(const PIString & prefix);
static PIIODevice * newDeviceByPrefix(const char * prefix);
void terminate();
@@ -408,6 +535,7 @@ private:
void run();
void end() {terminate();}
static void cacheFullPath(const PIString & full_path, const PIIODevice * d);
static PIMap<PIConstChars, FabricInfo> & fabrics();
PITimer timer;
PITimeMeasurer tm;

View File

@@ -25,7 +25,7 @@
//! \~english \section cmake_module_IO Building with CMake
//! \~russian \section cmake_module_IO Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP)
//! \endcode

View File

@@ -20,12 +20,15 @@
#include "piiostring.h"
/*! \class PIIOString
* \brief PIIODevice wrapper around PIString
*
* \section PIIOString_sec0 Synopsis
* This class allow you to use PIString as PIIODevice and pass it to, e.g. PIConfig
*/
//! \class PIIOString piiostring.h
//! \details
//! \~english
//! This class allow you to use PIString as PIIODevice, e.g. to pass it to PIConfig.
//!
//! \~russian
//! Этот класс позволяет использовать PIString в качестве PIIODevice, например,
//! для передачи в PIConfig.
//!
PIIOString::PIIOString(PIString * string, PIIODevice::DeviceMode mode) {
@@ -67,8 +70,9 @@ int PIIOString::readDevice(void * read_to, int max_size) {
PIString rs = str->mid(pos, max_size);
pos += max_size;
if (pos > str->size_s()) pos = str->size_s();
int ret = rs.lengthAscii();
memcpy(read_to, rs.data(), rs.lengthAscii());
const char * cc = rs.data();
int ret = strlen(cc);
memcpy(read_to, cc, ret);
return ret;
}
@@ -81,7 +85,7 @@ int PIIOString::writeDevice(const void * data, int max_size) {
if (rs.size_s() > max_size) rs.resize(max_size);
str->insert(pos, rs);
pos += rs.size_s();
return rs.lengthAscii();
return strlen((const char *)data);
}
@@ -90,7 +94,7 @@ int PIIOString::writeString(const PIString & string) {
if (pos > str->size_s()) pos = str->size_s();
str->insert(pos, string);
pos += string.size_s();
return string.lengthAscii();
return string.size_s();
}

View File

@@ -29,47 +29,63 @@
#include "piiodevice.h"
//! \ingroup IO
//! \~\brief
//! \~english PIIODevice wrapper around PIString.
//! \~russian Обёртка PIIODevice вокруг PIString.
class PIP_EXPORT PIIOString: public PIIODevice
{
PIIODEVICE(PIIOString)
PIIODEVICE(PIIOString, "")
public:
//! Contructs %PIIOString with \"string\" content and \"mode\" open mode
//! \~english Contructs %PIIOString with "string" content and "mode" open mode
//! \~russian Создает %PIIOString с содержимым "string" и режимом открытия "mode"
explicit PIIOString(PIString * string = 0, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
//! Contructs %PIIOString with \"string\" content only for read
//! \~english Contructs %PIIOString with "string" content only for read
//! \~russian Создает %PIIOString с содержимым "string" только для чтения
explicit PIIOString(const PIString & string);
//! Returns content
//! \~english Returns content
//! \~russian Возвращает содержимое
PIString * string() const {return str;}
//! Clear content string
//! \~english Clear content string
//! \~russian Очищает содержимое строки
void clear() {if (str) str->clear(); pos = 0;}
//! Open \"string\" content with \"mode\" open mode
//! \~english Open "string" content with "mode" open mode
//! \~russian Открывает содержимое "string" с режимом открытия "mode"
bool open(PIString * string, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
//! Open \"string\" content only for read
//! \~english Open "string" content only for read
//! \~russian Открывает содержимое "string" только для чтения
bool open(const PIString & string);
//! Returns if position is at the end of content
//! \~english Returns if position is at the end of content
//! \~russian Возвращает в конце содержимого ли позиция
bool isEnd() const {if (!str) return true; return pos >= str->size_s();}
//! Move read/write position to \"position\"
//! \~english Move read/write position to "position"
//! \~russian Перемещает позицию чтения/записи на "position"
void seek(llong position) {pos = position;}
//! Move read/write position to the begin of the string
//! \~english Move read/write position to the beginning of the string
//! \~russian Перемещает позицию чтения/записи на начало строки
void seekToBegin() {if (str) pos = 0;}
//! Move read/write position to the end of the string
//! \~english Move read/write position to the end of the string
//! \~russian Перемещает позицию чтения/записи на конец строки
void seekToEnd() {if (str) pos = str->size_s();}
//! Read one text line and return it
//! \~english Read one text line and return it
//! \~russian Читает одну строку и возвращает её
PIString readLine();
//! Insert string \"string\" into content at current position
//! \~english Insert string "string" into content at current position
//! \~russian Вставляет строку "string" в содержимое буфера в текущую позицию
int writeString(const PIString & string);
protected:

View File

@@ -31,7 +31,7 @@
class PIP_EXPORT PIPeer: public PIIODevice
{
PIIODEVICE(PIPeer)
PIIODEVICE(PIPeer, "peer")
private:
class PeerData;
@@ -168,7 +168,6 @@ private:
bool openDevice();
bool closeDevice();
PIString fullPathPrefix() const {return PIStringAscii("peer");}
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString &full_path);
PIPropertyStorage constructVariantDevice() const;

View File

@@ -137,21 +137,33 @@
#endif
/*! \class PISerial
* \brief Serial device
*
* \section PISerial_sec0 Synopsis
* This class provide access to serial device, e.g. COM port. It can read,
* write, wait for write. There are several read and write functions.
*
* \section PISerial_sec1 FullPath
* Since version 1.16.0 you can use as \a path DeviceInfo::id() USB identifier.
* \code
* PISerial * s = new PISerial("0403:6001");
* PIIODevice * d = PIIODevice::createFromFullPath("ser://0403:6001:115200");
* \endcode
*
*/
//! \class PISerial piserial.h
//! \details
//! \~english \section PISerial_sec0 Synopsis
//! \~russian \section PISerial_sec0 Краткий обзор
//! \~english
//! This class provide access to serial device, e.g. COM port. It can read,
//! write, wait for write. There are several read and write functions.
//!
//! \~russian
//! Этот класс предоставляет доступ к последовательному порту, например, COM-порт.
//!
//! \~english \section PISerial_sec1 FullPath
//! \~russian \section PISerial_sec1 Строка полного описания
//! \~english
//! Since version 1.16.0 you can use as \a path \a PISerial::DeviceInfo::id() USB identifier
//! for USB devices.
//!
//! \~russian
//! Начиная с версии 1.16.0 можно в качестве \a path использовать \a PISerial::DeviceInfo::id()
//! USB идентификатор для USB устройств.
//!
//! \~\code
//! PISerial * s = new PISerial("0403:6001");
//! PIIODevice * d = PIIODevice::createFromFullPath("ser://0403:6001:115200");
//! \endcode
//!
REGISTER_DEVICE(PISerial)
@@ -289,6 +301,16 @@ bool PISerial::isRNG() const {return isBit(TIOCM_RNG, "RNG");}
bool PISerial::isDSR() const {return isBit(TIOCM_DSR, "DSR");}
//! \~\details
//! \~english
//! If enabled, sends a continuous stream of zero bits.
//! Returns if state changed successfully.
//! \note The serial port has to be open before using this method
//!
//! \~russian
//! Если включено, отсылается непрерывный поток нулей.
//! Возвращает успешна ли смена состояния.
//! \note Порт должен быть открыт перед использованием этого метода
bool PISerial::setBreak(bool enabled) {
if (fd < 0) {
piCoutObj << "sendBreak error: \"" << path() << "\" is not opened!";
@@ -416,14 +438,24 @@ int PISerial::convertSpeed(PISerial::Speed speed) {
}
/** \brief Advanced read function
* \details Read to pointer "read_to" no more than "max_size" and no longer
* than "timeout_ms" milliseconds. If "timeout_ms" < 0 function will be
* wait forever until "max_size" will be readed. If size <= 0 function
* immediate returns \b false. For read data with unknown size use function
* \a readData().
* \returns \b True if readed bytes count = "max_size", else \b false
* \sa \a readData() */
//! \details
//! \~english
//! Read to pointer "read_to" no more than "max_size" and no longer
//! than "timeout_ms" milliseconds.\n
//! If "timeout_ms" < 0 function will be wait forever until "max_size" will be readed.\n
//! If "size" <= 0 function immediate returns \b false.\n
//! For read data with unknown size use function \a readData().
//! \returns If readed bytes count = "max_size"
//!
//! \~russian
//! Читает в указатель "read_to" не более "max_size" байт и не дольше
//! чем "timeout_ms" миллисекунд.\n
//! Если "timeout_ms" < 0 метод ожидает бесконечно, пока не будет прочитано "max_size" байт.\n
//! Если "size" <= 0, то метод немедленно возвращает \b false.\n
//! Для чтения данных неизвестного размера используется метод \a readData().
//! \returns Если количество прочитанных байт = "max_size"
//!
//! \sa \a readString(), \a readData()
bool PISerial::read(void * data, int size, double timeout_ms) {
if (data == 0 || size <= 0) return false;
int ret, all = 0;
@@ -454,15 +486,25 @@ bool PISerial::read(void * data, int size, double timeout_ms) {
}
/** \brief Advanced read function
* \details Read all or no more than "size" and no longer than
* "timeout_ms" milliseconds. If "timeout_ms" < 0 function will be
* wait forever until "size" will be readed. If "size" <= 0
* function will be read all until "timeout_ms" elaped. \n If size <= 0
* and "timeout_ms" <= 0 function immediate returns empty string.
* \n This function similar to \a readData() but returns data as string.
* \sa \a readData() */
PIString PISerial::read(int size, double timeout_ms) {
//! \details
//! \~english
//! Read all or no more than "size" bytes and no longer than "timeout_ms" milliseconds.\n
//! If "timeout_ms" < 0 function will be wait forever until "max_size" will be readed.\n
//! If "size" <= 0 function will be read all until "timeout_ms" elaped.\n
//! If "size" <= 0 and "timeout_ms" <= 0 function immediate returns empty string.\n
//! This function similar to \a readData() but returns data as string.
//! \returns If readed bytes count = "max_size"
//!
//! \~russian
//! Читает всё или не более "size" байт и не дольше чем "timeout_ms" миллисекунд.\n
//! Если "timeout_ms" < 0 метод ожидает бесконечно, пока не будет прочитано "max_size" байт.\n
//! Если "size" <= 0, то читает всё в течении "timeout_ms" миллисекунд.\n
//! Если "size" <= 0 и "timeout_ms" <= 0, то метод немедленно возвращает пустую строку.\n
//! Этот метод аналогичен \a readData(), но возвращает строку.
//! \returns Если количество прочитанных байт = "max_size"
//!
//! \sa \a readData()
PIString PISerial::readString(int size, double timeout_ms) {
PIString str;
if (size <= 0 && timeout_ms <= 0.) return str;
int ret, all = 0;
@@ -506,14 +548,24 @@ PIString PISerial::read(int size, double timeout_ms) {
}
/** \brief Advanced read function
* \details Read all or no more than "size" and no longer than
* "timeout_ms" milliseconds. If "timeout_ms" < 0 function will be
* wait forever until "size" will be readed. If "size" <= 0
* function will be read all until "timeout_ms" elaped. \n If size <= 0
* and "timeout_ms" <= 0 function immediate returns empty byte array.
* \n This function similar to \a read() but returns data as byte array.
* \sa \a read() */
//! \details
//! \~english
//! Read all or no more than "size" bytes and no longer than "timeout_ms" milliseconds.\n
//! If "timeout_ms" < 0 function will be wait forever until "max_size" will be readed.\n
//! If "size" <= 0 function will be read all until "timeout_ms" elaped.\n
//! If "size" <= 0 and "timeout_ms" <= 0 function immediate returns empty string.\n
//! This function similar to \a readString() but returns data as byte array.
//! \returns If readed bytes count = "max_size"
//!
//! \~russian
//! Читает всё или не более "size" байт и не дольше чем "timeout_ms" миллисекунд.\n
//! Если "timeout_ms" < 0 метод ожидает бесконечно, пока не будет прочитано "max_size" байт.\n
//! Если "size" <= 0, то читает всё в течении "timeout_ms" миллисекунд.\n
//! Если "size" <= 0 и "timeout_ms" <= 0, то метод немедленно возвращает пустую строку.\n
//! Этот метод аналогичен \a readString(), но возвращает массив байт.
//! \returns Если количество прочитанных байт = "max_size"
//!
//! \sa \a readString()
PIByteArray PISerial::readData(int size, double timeout_ms) {
PIByteArray str;
if (size <= 0 && timeout_ms <= 0.) return str;
@@ -722,11 +774,20 @@ void PISerial::setTimeouts() {
}
/** \brief Basic read function
* \details Read to pointer "read_to" no more than "max_size". If read is
* set to blocking this function will be wait at least one byte.
* \returns Readed bytes count
* \sa \a readData() */
//! \details
//! \~english
//! Read to pointer "read_to" no more than "max_size".
//! If \a PIIODevice::BlockingRead option set this function
//! will be wait at least one byte.
//! \returns Readed bytes count, -1 for error
//!
//! \~russian
//! Читает в указатель "read_to" не более "max_size" байт.
//! Если установлена опция \a PIIODevice::BlockingRead,
//! то этот метод ожидает хотя бы одного байта.
//! \returns Количество прочитанных байт, -1 при ошибке
//!
//! \~\sa \a readData(), \a readString()
int PISerial::readDevice(void * read_to, int max_size) {
#ifdef WINDOWS
if (!canRead()) return -1;

View File

@@ -29,22 +29,32 @@
#include "pitimer.h"
#include "piiodevice.h"
//! \ingroup IO
//! \~\brief
//! \~english Serial device.
//! \~russian Последовательный порт.
class PIP_EXPORT PISerial: public PIIODevice
{
PIIODEVICE(PISerial)
PIIODEVICE(PISerial, "ser")
public:
//! Contructs an empty %PISerial
//! \~english Contructs an empty %PISerial
//! \~russian Создает пустой %PISerial
explicit PISerial();
//! \brief Parameters of PISerial
virtual ~PISerial();
//! \~english Parameters of PISerial
//! \~russian Параметры PISerial
enum Parameters {
ParityControl /*! Enable parity check and generate */ = 0x1,
ParityOdd /*! Parity is odd instead of even */ = 0x2,
TwoStopBits /*! Two stop bits instead of one */ = 0x4
ParityControl /*! \~english Enable parity check and generate \~russian Включить генерацию и проверку контроля чётности */ = 0x1,
ParityOdd /*! \~english Parity is odd instead of even \~russian Нечётный контроль чётности вместо чётного */ = 0x2,
TwoStopBits /*! \~english Two stop bits instead of one \~russian Два стоповых бита вместо одного */ = 0x4
};
//! \brief Speed of PISerial
//! \~english Speed of PISerial
//! \~russian Скорость PISerial
enum Speed {
S50 /*! 50 baud */ = 50,
S75 /*! 75 baud */ = 75,
@@ -75,72 +85,93 @@ public:
S4000000 /*! 4000000 baud */ = 4000000
};
//! \brief Information about serial device
//! \ingroup IO
//! \~\brief
//! \~english Information about serial device
//! \~russian Информация о последовательном устройстве
struct PIP_EXPORT DeviceInfo {
DeviceInfo();
//! \brief String representation of USB ID in format \"xxxx:xxxx\"
//! \~english Returns string representation of USB ID in format "xxxx:xxxx" (vID:pID)
//! \~russian Возвращает строковое представление USB ID в формате "xxxx:xxxx" (vID:pID)
PIString id() const;
//! \brief USB Vendor ID
//! \~english USB Vendor ID
//! \~russian USB Vendor ID
uint vID;
//! \brief USB Product ID
//! \~english USB Product ID
//! \~russian USB Product ID
uint pID;
//! \brief Path to device, e.g. "COM2" or "/dev/ttyUSB0"
//! \~english Path to device, e.g. "COM2" or "/dev/ttyUSB0"
//! \~russian Путь к устройству, например "COM2" или "/dev/ttyUSB0"
PIString path;
//! \brief Device description
//! \~english Device description
//! \~russian Описание устройства
PIString description;
//! \brief Device manufacturer
//! \~english Device manufacturer
//! \~russian Описание производителя
PIString manufacturer;
};
//! Contructs %PISerial with device name "device", speed "speed" and parameters "params"
//! \~english Contructs %PISerial with device name "device", speed "speed" and parameters "params"
//! \~russian Создает %PISerial с именем устройства "device", скоростью "speed" и параметрами "params"
explicit PISerial(const PIString & device, PISerial::Speed speed = S115200, PIFlags<PISerial::Parameters> params = 0);
virtual ~PISerial();
//! Set both input and output speed to "speed"
//! \~english Set both input and output speed to "speed"
//! \~russian Устанавливает скорости приема и передачи в "speed"
void setSpeed(PISerial::Speed speed) {setProperty("outSpeed", (int)speed); setProperty("inSpeed", (int)speed); applySettings();}
//! Set output speed to "speed"
//! \~english Set output speed to "speed"
//! \~russian Устанавливает скорость передачи в "speed"
void setOutSpeed(PISerial::Speed speed) {setProperty("outSpeed", (int)speed); applySettings();}
//! Set input speed to "speed"
//! \~english Set input speed to "speed"
//! \~russian Устанавливает скорость приема в "speed"
void setInSpeed(PISerial::Speed speed) {setProperty("inSpeed", (int)speed); applySettings();}
//! Set device name to "dev"
//! \~english Set device name to "dev"
//! \~russian Устанавливает имя устройства в "dev"
void setDevice(const PIString & dev) {setPath(dev); if (isOpened()) {close(); open();};}
//! Set parameters to "parameters_"
//! \~english Set parameters to "parameters_"
//! \~russian Устанавливает параметры в "parameters_"
void setParameters(PIFlags<PISerial::Parameters> parameters_) {setProperty("parameters", (int)parameters_); applySettings();}
//! Set parameter "parameter" to "on" state
//! \~english Set parameter "parameter" to "on" state
//! \~russian Устанавливает параметр "parameter" в "on"
void setParameter(PISerial::Parameters parameter, bool on = true);
//! Returns if parameter "parameter" is set
//! \~english Returns if parameter "parameter" is set
//! \~russian Возвращает установлен ли параметр "parameter"
bool isParameterSet(PISerial::Parameters parameter) const;
//! Returns parameters
//! \~english Returns parameters
//! \~russian Возвращает параметры
PIFlags<PISerial::Parameters> parameters() const {return (PIFlags<Parameters>)(property("parameters").toInt());}
//! Set data bits count. Valid range is from 5 to 8, befault is 8
//! \~english Set data bits count. Valid range is from 5 to 8, befault is 8
//! \~russian Устанавливает количество бит данных. Разрешены значения от 5 до 8, по умолчанию 8
void setDataBitsCount(int bits) {setProperty("dataBitsCount", bits); applySettings();}
//! Returns data bits count
//! \~english Returns data bits count
//! \~russian Возвращает количество бит данных
int dataBitsCount() const {return property("dataBitsCount").toInt();}
//! Set pin number "number" to logic level "on". Valid numbers are 4 (DTR) and 7 (RTS)
//! \~english Set pin number "number" to logic level "on". Valid numbers are 4 (DTR) and 7 (RTS)
//! \~russian Устанавливает пин с номером "number" в логический уровень "on". Разрешены номера 4 (DTR) и 7 (RTS)
bool setPin(int number, bool on);
//! Returns pin number "number" logic level. Valid numbers range is from 1 to 9
//! \~english Returns pin number "number" logic level. Valid numbers range is from 1 to 9
//! \~russian Возвращает логический уровень пина с номером "number". Разрешены номера от 1 до 9
bool isPin(int number) const;
bool setLE(bool on); // useless function, just formally
@@ -163,75 +194,94 @@ public:
bool isRNG() const;
bool isDSR() const;
//! Switch transmission line in break if enabled.
//! i.e. sends a continuous stream of zero bits.
//! If successful, returns true; otherwise returns false.
//! The serial port has to be open before trying to send a break duration; otherwise returns false
//! \~english Switch transmission line in break
//! \~russian Переключает состояние передачи в break
bool setBreak(bool enabled);
void setVTime(int t) {vtime = t; applySettings();}
//! Returns device name
//! \~english Returns device name
//! \~russian Возвращает имя устройства
PIString device() const {return path();}
//! Returns output speed
//! \~english Returns output speed
//! \~russian Возвращает скорость передачи
PISerial::Speed outSpeed() const {return (PISerial::Speed)(property("outSpeed").toInt());}
//! Returns input speed
//! \~english Returns input speed
//! \~russian Возвращает скорость приема
PISerial::Speed inSpeed() const {return (PISerial::Speed)(property("inSpeed").toInt());}
int VTime() const {return vtime;}
//! Discard all buffered input and output data
//! \~english Discard all buffered input and output data
//! \~russian Откидывает все буферизированные данные для передачи и приема
void flush();
int read(void * read_to, int max_size) {return readDevice(read_to, max_size);}
//! \~english Read from device no more "max_size" bytes into "read_to" with "timeout_ms" timeout
//! \~russian Читает из устройства не более "max_size" байт в "read_to" с таймаутом "timeout_ms"
bool read(void * read_to, int max_size, double timeout_ms);
PIString read(int size = -1, double timeout_ms = 1000.);
//! \~english Read from device for "timeout_ms" timeout or for "size" bytes
//! \~russian Читает из устройства в течении таймаута "timeout_ms" или до "size" байт
PIString readString(int size = -1, double timeout_ms = 1000.);
//! \~english Read from device for "timeout_ms" timeout or for "size" bytes
//! \~russian Читает из устройства в течении таймаута "timeout_ms" или до "size" байт
PIByteArray readData(int size = -1, double timeout_ms = 1000.);
//! \brief Write to device data "data" with maximum size "size" and wait for data written if "wait" is \b true.
//! \returns \b true if sended bytes count = "size"
//! \~english Write to device data "data" with maximum size "size". Returns if sended bytes count = "size"
//! \~russian Пишет в порт не более "size" байт данных "data". Возвращает если количество записанных байт = "size"
bool send(const void * data, int size);
//! \brief Write to device byte array "data"
//! \returns \b true if sended bytes count = size of string
//! \~english Write to device byte array "data". Returns if sended bytes count = size of "data"
//! \~russian Пишет в порт байтовый массив "data". Возвращает если количество записанных байт = размер "data"
bool send(const PIByteArray & data) {return send(data.data(), data.size_s());}
//! \brief Returns all available speeds for serial devices
//! \~english Returns all available speeds for serial devices
//! \~russian Возвращает все возможные скорости для устройств
static PIVector<int> availableSpeeds();
//! \brief Returns all available system devices path. If "test" each device will be tried to open
//! \~english Returns all available system devices path. If "test" each device will be tried to open
//! \~russian Возвращает пути всех доступных устройств в системе. Если "test", то каждое устройство будет опробовано на открытие
static PIStringList availableDevices(bool test = false);
//! \brief Returns all available system devices. If "test" each device will be tried to open
//! \~english Returns all available system devices. If "test" each device will be tried to open
//! \~russian Возвращает все доступные устройства в системе. Если "test", то каждое устройство будет опробовано на открытие
static PIVector<DeviceInfo> availableDevicesInfo(bool test = false);
//! \ioparams
//! \{
#ifdef DOXYGEN
//! \brief device, default ""
//! \~english device, default ""
//! \~russian устройство, по умолчанию ""
string device;
//! \brief input/output speed, default 115200
//! \~english input/output speed, default 115200
//! \~russian скорость чтения/записи, по умолчанию 115200
int speed;
//! \brief dataBitsCount, default 8
//! \~english dataBitsCount, default 8
//! \~russian количесво бит данных, по умолчанию 8
int dataBitsCount;
//! \brief parityControl, default false
//! \~english parityControl, default false
//! \~russian контроль четности, по умолчанию false
bool parityControl;
//! \brief parityOdd, default false
//! \~english parityOdd, default false
//! \~russian нечётный контроль четности, по умолчанию false
bool parityOdd;
//! \brief twoStopBits, default false
//! \~english twoStopBits, default false
//! \~russian два стоповых бита, по умолчанию false
bool twoStopBits;
#endif
//! \}
protected:
PIString fullPathPrefix() const {return PIStringAscii("ser");}
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);
PIPropertyStorage constructVariantDevice() const;
@@ -239,6 +289,9 @@ protected:
bool configureDevice(const void * e_main, const void * e_parent = 0);
void optionsChanged();
void threadedReadBufferSizeChanged();
//! \~english Basic read function
//! \~russian Базовое чтение
int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size);
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Sequential;}
@@ -264,14 +317,30 @@ protected:
};
//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
inline PICout operator <<(PICout s, const PISerial::DeviceInfo & v) {
s << v.path << " (" << v.id() << ", \"" << v.manufacturer << "\", \"" << v.description << "\")";
return s;
}
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator ==(const PISerial::DeviceInfo & v0, const PISerial::DeviceInfo & v1) {return v0.path == v1.path;}
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator !=(const PISerial::DeviceInfo & v0, const PISerial::DeviceInfo & v1) {return v0.path != v1.path;}
//! \relatesalso PIByteArray
//! \~english Store operator
//! \~russian Оператор сохранения
inline PIByteArray & operator <<(PIByteArray & s, const PISerial::DeviceInfo & v) {s << v.vID << v.pID << v.path << v.description << v.manufacturer; return s;}
//! \relatesalso PIByteArray
//! \~english Restore operator
//! \~russian Оператор извлечения
inline PIByteArray & operator >>(PIByteArray & s, PISerial::DeviceInfo & v) {s >> v.vID >> v.pID >> v.path >> v.description >> v.manufacturer; return s;}

View File

@@ -40,25 +40,24 @@
#endif
/*! \class PISharedMemory
* \brief Shared memory
*
* \section PISharedMemory_sec0 Synopsis
* This class provide access to local file. You can manipulate
* binary content or use this class as text stream. To binary
* access there are function \a read(), \a write(), and many
* \a writeBinary() functions. For write variables to file in
* their text representation threr are many "<<" operators.
*
* \section PISharedMemory_sec1 Position
* Each opened file has a read/write position - logical position
* in the file content you read from or you write to. You can
* find out current position with function \a pos(). Function
* \a seek(llong position) move position to position "position",
* \a seekToBegin() move position to the begin of file,
* \a seekToEnd() move position to the end of file.
*
*/
//! \class PISharedMemory pisharedmemory.h
//! \details
//! \~english
//!
//!
//! \~russian
//! Разделяемая память используется как единое хранилище данных,
//! доступное различным процессам по имени. При первом открытии
//! объекта разделяемой памяти выделяется \a size() байт, по умолчанию
//! 65 Кб. Все процессы должны использовать один и тот же \a size()
//! во избежании ошибок.
//!
//! У объекта разделяемой памяти нету позиции чтения/записи,
//! каждый вызов \a read() или \a write() обращается
//! к началу памяти. Для работы с конкретным участком памяти
//! используются перегруженные методы с указанием "offset".
//!
REGISTER_DEVICE(PISharedMemory)

View File

@@ -29,54 +29,70 @@
#include "piiodevice.h"
//! \ingroup IO
//! \~\brief
//! \~english Shared memory.
//! \~russian Разделяемая память.
class PIP_EXPORT PISharedMemory: public PIIODevice
{
PIIODEVICE(PISharedMemory)
PIIODEVICE(PISharedMemory, "shm")
public:
//! \~english Constructs empty %PISharedMemory
//! \~russian Создает пустой %PISharedMemory
explicit PISharedMemory();
//! Constructs a shared memory object with name "shm_name", size "size" and open mode "mode"
//! \~english Constructs a shared memory object with name "shm_name", size "size" and open mode "mode"
//! \~russian Создает объект разделяемой памяти с именем "shm_name", размером "size" и режимом открытия "mode"
explicit PISharedMemory(const PIString & shm_name, int size, DeviceMode mode = ReadWrite);
virtual ~PISharedMemory();
//! Read all shared memory object content to byte array and return it
//! \~english Read all shared memory content and return it as byte array
//! \~russian Читает всю разделяемую память и возвращает её как байтовый массив
PIByteArray readAll();
//! Returns shared memory object size
//! \~english Returns shared memory size
//! \~russian Возвращает размер разделяемой памяти
llong size() const;
//! Set shared memory object size
//! \~english Set shared memory size
//! \~russian Устанавливает размер разделяемой памяти
void setSize(llong s);
//! Returns if shared memory object is empty
//! \~english Returns if shared memory object is empty (by size)
//! \~russian Возвращает пустой ли объект разделяемой памяти (по размеру)
bool isEmpty() const {return (size() <= 0);}
//! Read from shared memory object to "read_to" no more than "max_size" and return readed bytes count
//! \~english Read from shared memory to "read_to" no more than "max_size" and return readed bytes count
//! \~russian Читает из разделяемой памяти в "read_to" не более "max_size" и возвращает количество прочитанных байт
int read(void * read_to, int max_size);
//! Read from shared memory object to "read_to" no more than "max_size" and return readed bytes count
//! \~english Read from shared memory started from "offset" to "read_to" no more than "max_size" and return readed bytes count
//! \~russian Читает из разделяемой памяти с начала "offset" в "read_to" не более "max_size" и возвращает количество прочитанных байт
int read(void * read_to, int max_size, int offset);
//! Write to shared memory object "data" with size "max_size" and return written bytes count
//! \~english Write to shared memory "data" with size "max_size" and return written bytes count
//! \~russian Пишет в разделяемую память "data" размером "max_size" и возвращает количество записанных байт
int write(const void * data, int max_size);
//! Write to shared memory object "data" with size "max_size" and return written bytes count
//! \~english Write to shared memory started from "offset" "data" with size "max_size" and return written bytes count
//! \~russian Пишет в разделяемую память с начала "offset" "data" размером "max_size" и возвращает количество записанных
int write(const void * data, int max_size, int offset);
//! Write "data" to shared memory object
//! \~english Write "data" to shared memory
//! \~russian Пишет в разделяемую память "data"
int write(const PIByteArray & data) {return write(data.data(), data.size_s());}
//! Write "data" to shared memory object
//! \~english Write "data" to shared memory
//! \~russian Пишет в разделяемую память "data"
int write(const PIByteArray & data, int offset) {return write(data.data(), data.size_s(), offset);}
protected:
bool openDevice();
bool closeDevice();
PIString fullPathPrefix() const {return PIStringAscii("shm");}
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);
PIPropertyStorage constructVariantDevice() const;

View File

@@ -31,7 +31,7 @@
class PIP_EXPORT PISPI: public PIIODevice
{
PIIODEVICE(PISPI)
PIIODEVICE(PISPI, "spi")
public:
explicit PISPI(const PIString & path = PIString(), uint speed_hz = 1000000, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
virtual ~PISPI();
@@ -67,7 +67,6 @@ protected:
int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size);
PIString fullPathPrefix() const {return PIStringAscii("spi");}
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);
PIPropertyStorage constructVariantDevice() const;

View File

@@ -20,15 +20,21 @@
#include "pitransparentdevice.h"
/*! \class PITransparentDevice
* \brief PIIODevice that pass write to read
*
* \section PITransparentDevice_sec0 Synopsis
* This class pass all data from \a write() function to \a read().
* %PITransparentDevice contains internal queue and works in
* packets mode. If you write 3 different packets into this device,
* read will return this 3 packets.
*/
//! \class PITransparentDevice pitransparentdevice.h
//! \details
//! \~english
//! This class pass all data from \a write() function to \a read().
//! %PITransparentDevice contains internal queue and works in
//! packets mode. If you write 3 different packets into this device,
//! read will return this 3 packets.
//!
//! \~russian
//! Этот класс транслирует все данные с метода \a write() на метод
//! \a read(). %PITransparentDevice содержит внутреннюю очередь и работает
//! в пакетном режиме. Если запишется 3 различных пакета в устройство,
//! то чтение вернет по очереди эти 3 пакета.
//!
REGISTER_DEVICE(PITransparentDevice)

View File

@@ -29,12 +29,17 @@
#include "piiodevice.h"
//! \ingroup IO
//! \~\brief
//! \~english PIIODevice that pass write to read.
//! \~russian PIIODevice который транслирует запись на чтение.
class PIP_EXPORT PITransparentDevice: public PIIODevice
{
PIIODEVICE(PITransparentDevice)
PIIODEVICE(PITransparentDevice, "tr")
public:
//! Contructs empty %PITransparentDevice
//! \~english Contructs empty %PITransparentDevice
//! \~russian Создает пустой %PITransparentDevice
explicit PITransparentDevice();
virtual ~PITransparentDevice();
@@ -44,7 +49,6 @@ protected:
bool closeDevice();
int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size);
PIString fullPathPrefix() const {return PIStringAscii("tr");}
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Reliable;}
PIMutex que_mutex;

View File

@@ -31,7 +31,7 @@
//! \~english \section cmake_module_USB Building with CMake
//! \~russian \section cmake_module_USB Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP::USB)
//! \endcode
@@ -63,7 +63,7 @@ struct usb_dev_handle;
class PIP_EXPORT PIUSB: public PIIODevice
{
PIIODEVICE(PIUSB)
PIIODEVICE(PIUSB, "usb")
public:
explicit PIUSB(ushort vid = 0, ushort pid = 0);
virtual ~PIUSB();
@@ -160,7 +160,6 @@ public:
void flush();
protected:
PIString fullPathPrefix() const {return PIStringAscii("usb");}
bool configureDevice(const void * e_main, const void * e_parent = 0);
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);

View File

@@ -225,7 +225,7 @@ PIDiagnostics::Entry PIDiagnostics::calcHistory(PIQueue<Entry> & hist, int & cnt
}
void PIDiagnostics::propertyChanged(const PIString &) {
void PIDiagnostics::propertyChanged(const char *) {
float disct = property("disconnectTimeout").toFloat();
changeDisconnectTimeout(disct);
}

View File

@@ -140,7 +140,7 @@ private:
void tick(void *, int);
Entry calcHistory(PIQueue<Entry> & hist, int & cnt);
void propertyChanged(const PIString &);
void propertyChanged(const char *);
void changeDisconnectTimeout(float disct);
PIQueue<Entry> history_rec, history_send;

View File

@@ -25,7 +25,7 @@
//! \~english \section cmake_module_IO_Utils Building with CMake
//! \~russian \section cmake_module_IO_Utils Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP::IOUtils)
//! \endcode

View File

@@ -107,7 +107,7 @@ void PIPacketExtractor::construct() {
}
void PIPacketExtractor::propertyChanged(const PIString &) {
void PIPacketExtractor::propertyChanged(const char *) {
packetSize_ = property("packetSize").toInt();
mode_ = (SplitMode)(property("splitMode").toInt());
dataSize = property("payloadSize").toInt();

View File

@@ -33,7 +33,7 @@ typedef bool (*PacketExtractorCheckFunc)(void * , uchar * , uchar * , int );
class PIP_EXPORT PIPacketExtractor: public PIIODevice
{
PIIODEVICE(PIPacketExtractor)
PIIODEVICE(PIPacketExtractor, "pckext")
friend class PIConnection;
public:
@@ -161,11 +161,10 @@ protected:
private:
void construct();
void propertyChanged(const PIString & );
void propertyChanged(const char *);
int readDevice(void * read_to, int max_size) {if (dev == 0) return -1; return dev->read(read_to, max_size);}
int writeDevice(const void * data, int max_size) {if (dev == 0) return -1; return dev->write(data, max_size);}
bool threadedRead(uchar * readed, int size);
PIString fullPathPrefix() const {return PIStringAscii("pckext");}
PIString constructFullPathDevice() const;
bool openDevice() {if (dev == 0) return false; return dev->open();}
bool closeDevice() {if (dev == 0) return false; return dev->close();}

View File

@@ -31,7 +31,7 @@
//! \~english \section cmake_module_Lua Building with CMake
//! \~russian \section cmake_module_Lua Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP::Lua)
//! \endcode

View File

@@ -32,7 +32,7 @@
//! \~english \section cmake_module_FFTW Building with CMake
//! \~russian \section cmake_module_FFTW Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP::FFTW)
//! \endcode

View File

@@ -1,4 +1,4 @@
/*! \file pirect.h
/*! \file piline.h
* \ingroup Math
* \brief
* \~english Two-dimensional line class

View File

@@ -25,7 +25,7 @@
//! \~english \section cmake_module_Math Building with CMake
//! \~russian \section cmake_module_Math Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP)
//! \endcode

View File

@@ -31,7 +31,7 @@
//! \~english \section cmake_module_OpenCL Building with CMake
//! \~russian \section cmake_module_OpenCL Сборка с использованием CMake
//!
//! \code
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP::OpenCL)
//! \endcode

Some files were not shown because too many files have changed in this diff Show More