16 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
71 changed files with 2404 additions and 1346 deletions

View File

@@ -8,9 +8,46 @@ set(pip_SUFFIX )
set(pip_COMPANY SHS) set(pip_COMPANY SHS)
set(pip_DOMAIN org.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") if ("x${CMAKE_MODULE_PATH}" STREQUAL "x")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
endif() 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_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
include(CheckFunctionExists) include(CheckFunctionExists)
include(PIPMacros) include(PIPMacros)
@@ -579,7 +616,7 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
foreach(F ${PIP_MAIN_FOLDERS}) foreach(F ${PIP_MAIN_FOLDERS})
list(APPEND DOXY_INPUT "\"${F}\"") list(APPEND DOXY_INPUT "\"${F}\"")
endforeach(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_INCLUDE_PATH "${PIP_INCLUDES}")
string(REPLACE ";" " " DOXY_DEFINES "${DOXY_DEFINES}") string(REPLACE ";" " " DOXY_DEFINES "${DOXY_DEFINES}")
add_documentation(doc doc/Doxyfile.in) add_documentation(doc doc/Doxyfile.in)

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

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

View File

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

View File

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

View File

@@ -246,6 +246,10 @@
extern char ** environ; extern char ** environ;
#endif #endif
#ifndef NO_UNUSED
# define NO_UNUSED(x) (void)x
#endif
#ifndef assert #ifndef assert
# define assert(x) # define assert(x)
# define assertm(exp, msg) # define assertm(exp, msg)

View File

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

View File

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

View File

@@ -36,14 +36,7 @@ char * __utf8name__ = 0;
#endif #endif
#include <wchar.h> #include <wchar.h>
//! \addtogroup Core
//! \{
//! \class PIChar pichar.h //! \class PIChar pichar.h
//!
//! \~\brief
//! \~english %PIChar represents a single character
//! \~russian %PIChar представляет собой один символ строки
//!
//! \~\details //! \~\details
//! \~english //! \~english
//! This class is wrapper around UTF16. //! This class is wrapper around UTF16.
@@ -53,7 +46,6 @@ char * __utf8name__ = 0;
//! %PIChar хранит один сивол в UTF16. Имеет много контрукторов, геттеров в различные //! %PIChar хранит один сивол в UTF16. Имеет много контрукторов, геттеров в различные
//! кодировки (системную, консольную, UTF8) и информационных функций. //! кодировки (системную, консольную, UTF8) и информационных функций.
//! //!
//! \}
ushort charFromCodepage(const char * c, int size, const char * codepage, int * taken = 0) { ushort charFromCodepage(const char * c, int size, const char * codepage, int * taken = 0) {

View File

@@ -32,6 +32,10 @@ extern PIP_EXPORT char * __syslocname__;
extern PIP_EXPORT char * __sysoemname__; extern PIP_EXPORT char * __sysoemname__;
extern PIP_EXPORT char * __utf8name__; extern PIP_EXPORT char * __utf8name__;
//! \ingroup Core
//! \~\brief
//! \~english %PIChar represents a single character.
//! \~russian %PIChar представляет собой один символ строки.
class PIP_EXPORT PIChar class PIP_EXPORT PIChar
{ {
friend class PIString; friend class PIString;

View File

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

View File

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

View File

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

View File

@@ -26,11 +26,15 @@
#ifndef PICLI_H #ifndef PICLI_H
#define 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: public:
//! \~english Constructor //! \~english Constructor
@@ -94,6 +98,11 @@ public:
void setMandatoryArgumentsCount(const int count) {_count_mand = count; needParse = true;} void setMandatoryArgumentsCount(const int count) {_count_mand = count; needParse = true;}
void setOptionalArgumentsCount(const int count) {_count_opt = 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: private:
struct Argument { struct Argument {
Argument() {has_value = found = false;} Argument() {has_value = found = false;}
@@ -112,7 +121,7 @@ private:
PISet<PIString> keys_full, keys_short; PISet<PIString> keys_full, keys_short;
PIVector<Argument> _args; PIVector<Argument> _args;
int _count_mand, _count_opt; int _count_mand, _count_opt;
bool needParse; bool needParse, debug_;
}; };

View File

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

View File

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

View File

@@ -20,15 +20,10 @@
#include "pistring.h" #include "pistring.h"
//! \addtogroup Core
//! \{
//! \~\class PIConstChars piconstchars.h //! \~\class PIConstChars piconstchars.h
//! \~\brief //! \~\details
//! \~english C-String class //! \~english \section PIConstChars_sec0 Synopsis
//! \~russian Класс C-строки //! \~russian \section PIConstChars_sec0 Краткий обзор
//!
//! \~english \section PICout_sec0 Synopsis
//! \~russian \section PICout_sec0 Краткий обзор
//! \~english //! \~english
//! This is wrapper around \c const char * string. %PIConstChars doesn`t //! This is wrapper around \c const char * string. %PIConstChars doesn`t
//! copy string, just save pointer and size. //! copy string, just save pointer and size.
@@ -45,7 +40,6 @@
//! //!
//! Используется для более удобной работы с обычными C-строками. //! Используется для более удобной работы с обычными C-строками.
//! //!
//! \}
bool PIConstChars::startsWith(const PIConstChars & str) const { bool PIConstChars::startsWith(const PIConstChars & str) const {
@@ -54,12 +48,24 @@ bool PIConstChars::startsWith(const PIConstChars & str) const {
} }
bool PIConstChars::startsWith(const char c) const {
if (size() < 1) return false;
return str[0] == c;
}
bool PIConstChars::endsWith(const PIConstChars & str) const { bool PIConstChars::endsWith(const PIConstChars & str) const {
if (size() < str.size()) return false; if (size() < str.size()) return false;
return str == right(str.size()); 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 { PIConstChars PIConstChars::mid(const int start, const int len) const {
int s = start, l = len; int s = start, l = len;
if (l == 0 || s >= (int)size() || isEmpty()) return PIConstChars(""); if (l == 0 || s >= (int)size() || isEmpty()) return PIConstChars("");

View File

@@ -29,6 +29,10 @@
#include "picout.h" #include "picout.h"
//! \ingroup Core
//! \~\brief
//! \~english C-String class.
//! \~russian Класс C-строки.
class PIP_EXPORT PIConstChars { class PIP_EXPORT PIConstChars {
public: public:
@@ -98,10 +102,18 @@ public:
//! \~russian Возвращает начинается ли строка со "str". //! \~russian Возвращает начинается ли строка со "str".
bool startsWith(const PIConstChars & str) const; 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". //! \~english Returns if string ends with "str".
//! \~russian Возвращает оканчивается ли строка на "str". //! \~russian Возвращает оканчивается ли строка на "str".
bool endsWith(const PIConstChars & str) const; 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". //! \~english Returns part of string from character at index "start" and maximum length "len".
//! \~russian Возвращает подстроку от символа "start" и максимальной длиной "len". //! \~russian Возвращает подстроку от символа "start" и максимальной длиной "len".
//! \~\sa \a left(), \a right() //! \~\sa \a left(), \a right()

View File

@@ -34,13 +34,8 @@
#endif #endif
//! \addtogroup Core
//! \{
//! \~\class PICout picout.h //! \~\class PICout picout.h
//! \~\brief //! \~\details
//! \~english Universal output to console class
//! \~russian Универсальный вывод в консоль
//!
//! \~english \section PICout_sec0 Synopsis //! \~english \section PICout_sec0 Synopsis
//! \~russian \section PICout_sec0 Краткий обзор //! \~russian \section PICout_sec0 Краткий обзор
//! \~english //! \~english
@@ -79,7 +74,6 @@
//! \~russian \section PICout_ex1 Создание своего оператора вывода //! \~russian \section PICout_ex1 Создание своего оператора вывода
//! \~\snippet picout.cpp own //! \~\snippet picout.cpp own
//! //!
//! \}
//! \addtogroup Core //! \addtogroup Core
@@ -337,7 +331,7 @@ PICout PICout::operator <<(const PIFlags<PICoutManipulators::PICoutFormat> & v)
if (!act_) return *this; \ if (!act_) return *this; \
space(); \ space(); \
if (cnb_ == 10) PICOUTTOTARGET(v) \ if (cnb_ == 10) PICOUTTOTARGET(v) \
else writePIString(PIString::fromNumber(v, cnb_)); \ else write(PIString::fromNumber(v, cnb_)); \
return *this; \ return *this; \
} }
@@ -370,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 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) { PICout PICout::operator <<(const PIObject * v) {
if (!act_) return *this; if (!act_) return *this;
@@ -379,9 +373,9 @@ PICout PICout::operator <<(const PIObject * v) {
else { else {
PICOUTTOTARGET(v->className()) PICOUTTOTARGET(v->className())
PICOUTTOTARGET("*(0x") PICOUTTOTARGET("*(0x")
writePIString(PIString::fromNumber(ullong(v), 16)); write(PIString::fromNumber(ullong(v), 16));
PICOUTTOTARGET(", \"") PICOUTTOTARGET(", \"")
writePIString(v->name()); write(v->name());
PICOUTTOTARGET("\")") PICOUTTOTARGET("\")")
} }
return *this; return *this;
@@ -544,7 +538,7 @@ 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 (!act_) return *this;
if (buffer_) { if (buffer_) {
buffer_->append(s); buffer_->append(s);

View File

@@ -125,6 +125,10 @@ namespace PICoutManipulators {
//! \ingroup Core
//! \~\brief
//! \~english Universal output to console class.
//! \~russian Универсальный вывод в консоль.
class PIP_EXPORT PICout { class PIP_EXPORT PICout {
public: public:
@@ -293,7 +297,7 @@ public:
//! \~english Write raw \a PIString //! \~english Write raw \a PIString
//! \~russian Пишет сырой \a PIString //! \~russian Пишет сырой \a PIString
PICout & writePIString(const PIString & s); PICout & write(const PIString & s);
//! \~english Output \a PIString to stdout //! \~english Output \a PIString to stdout
//! \~russian Вывод \a PIString в stdout //! \~russian Вывод \a PIString в stdout

View File

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

View File

@@ -30,6 +30,10 @@
#include "pisystemtime.h" #include "pisystemtime.h"
//! \ingroup Core
//! \~\brief
//! \~english Calendar time.
//! \~russian Календарное время.
class PIP_EXPORT PITime { class PIP_EXPORT PITime {
public: public:
//! \~english Construct %PITime from hours, minutes, seconds and milliseconds //! \~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 { class PIP_EXPORT PIDate {
public: public:
//! \~english Construct %PIDate from year, month and day //! \~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 { class PIP_EXPORT PIDateTime {
public: public:
//! \~english Construct null %PIDateTime //! \~english Construct null %PIDateTime

View File

@@ -94,237 +94,3 @@ void randomize() {
int randomi() { int randomi() {
return rand(); 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

@@ -26,13 +26,7 @@
#endif #endif
//! \addtogroup Core
//! \{
//! \~\class PIObject piobject.h //! \~\class PIObject piobject.h
//! \~\brief
//! \~english This is base class for any classes which use events -> handlers mechanism
//! \~russian Этот класс является базовым для использования механизма события -> обработчики
//!
//! \~\details //! \~\details
//! \~english \section PIObject_sec0 Events and Event handlers //! \~english \section PIObject_sec0 Events and Event handlers
//! \~russian \section PIObject_sec0 События и Обработчики событий //! \~russian \section PIObject_sec0 События и Обработчики событий
@@ -98,16 +92,12 @@
//! handler A: event to event //! handler A: event to event
//! event to lambda //! event to lambda
//! \endcode //! \endcode
//! \} //!
//! \addtogroup Core
//! \{
//! \~\class PIObject::Connection piobject.h //! \~\class PIObject::Connection piobject.h
//! \~\brief //! \~\details
//! \~english Helper class for obtain info about if connection successful and disconnect single connection //!
//! \~russian Вспомогательный класс для получения информации об успешности соединения и возможности его разрыва
//! \}
PIObject::__MetaFunc::__MetaFunc() { PIObject::__MetaFunc::__MetaFunc() {

View File

@@ -36,6 +36,10 @@
typedef void (*Handler)(void * ); 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 { class PIP_EXPORT PIObject {
#ifndef MICRO_PIP #ifndef MICRO_PIP
friend class PIObjectManager; friend class PIObjectManager;
@@ -53,6 +57,10 @@ public:
virtual ~PIObject(); virtual ~PIObject();
//! \ingroup Core
//! \~\brief
//! \~english Helper class for obtain info about if connection successful and disconnect single connection.
//! \~russian Вспомогательный класс для получения информации об успешности соединения и возможности его разрыва.
class PIP_EXPORT Connection { class PIP_EXPORT Connection {
friend class PIObject; friend class PIObject;
Connection(void * sl, void * si, const PIString & e = PIString(), Connection(void * sl, void * si, const PIString & e = PIString(),

View File

@@ -20,13 +20,7 @@
#include "pipropertystorage.h" #include "pipropertystorage.h"
//! \addtogroup Core
//! \{
//! \~\class PIPropertyStorage pipropertystorage.h //! \~\class PIPropertyStorage pipropertystorage.h
//! \~\brief
//! \~english This class provides key-value properties storage
//! \~russian Этот класс предоставляет ключ-значение хранение свойств
//!
//! \~\details //! \~\details
//! \~english \section PIPropertyStorage_sec0 Synopsis //! \~english \section PIPropertyStorage_sec0 Synopsis
//! \~russian \section PIPropertyStorage_sec0 Краткий обзор //! \~russian \section PIPropertyStorage_sec0 Краткий обзор
@@ -45,35 +39,12 @@
//! \~russian Пример: //! \~russian Пример:
//! \~\code{.cpp} //! \~\code{.cpp}
//! \endcode //! \endcode
//! \} //!
//! \addtogroup Core
//! \{
//! \~\class PIPropertyStorage::Property pipropertystorage.h //! \~\class PIPropertyStorage::Property pipropertystorage.h
//! \~\brief
//! \~english PIPropertyStorage element
//! \~russian Элемент PIPropertyStorage
//!
//! \~\details //! \~\details
//! \~english \section PIPropertyStorage_sec1 Synopsis
//! \~russian \section PIPropertyStorage_sec1 Краткий обзор
//! //!
//! \~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 { bool PIPropertyStorage::isPropertyExists(const PIString & _name) const {

View File

@@ -29,6 +29,10 @@
#include "pivariant.h" #include "pivariant.h"
//! \ingroup Core
//! \~\brief
//! \~english This class provides key-value properties storage.
//! \~russian Этот класс предоставляет ключ-значение хранение свойств.
class PIP_EXPORT PIPropertyStorage { class PIP_EXPORT PIPropertyStorage {
public: public:
@@ -36,6 +40,10 @@ public:
//! \~russian Создает пустой %PIPropertyStorage //! \~russian Создает пустой %PIPropertyStorage
PIPropertyStorage() {} PIPropertyStorage() {}
//! \ingroup Core
//! \~\brief
//! \~english PIPropertyStorage element.
//! \~russian Элемент PIPropertyStorage.
struct PIP_EXPORT Property { struct PIP_EXPORT Property {
//! \~english Contructs %PIPropertyStorage::Property with name "n", comment "c", value "v" and flags "f" //! \~english Contructs %PIPropertyStorage::Property with name "n", comment "c", value "v" and flags "f"

View File

@@ -31,13 +31,7 @@
#include <locale> #include <locale>
#include <codecvt> #include <codecvt>
//! \addtogroup Core
//! \{
//! \class PIString pistring.h //! \class PIString pistring.h
//! \brief
//! \~english String class
//! \~russian Класс строки
//!
//! \~\details //! \~\details
//! \~english \section PIString_sec0 Synopsis //! \~english \section PIString_sec0 Synopsis
//! \~russian \section PIString_sec0 Краткий обзор //! \~russian \section PIString_sec0 Краткий обзор
@@ -54,7 +48,6 @@
//! создана из множества типов и преобразована в несколько типов. //! создана из множества типов и преобразована в несколько типов.
//! Имеет множество методов для манипуляций. //! Имеет множество методов для манипуляций.
//! //!
//! \}
@@ -1669,7 +1662,7 @@ PIString versionNormalize(const PIString & v) {
PICout operator <<(PICout s, const PIString & v) { PICout operator <<(PICout s, const PIString & v) {
s.space(); s.space();
s.quote(); s.quote();
s.writePIString(v); s.write(v);
s.quote(); s.quote();
return s; return s;
} }

View File

@@ -34,6 +34,10 @@
class PIStringList; class PIStringList;
//! \ingroup Core
//! \~\brief
//! \~english String class.
//! \~russian Класс строки.
class PIP_EXPORT PIString class PIP_EXPORT PIString
{ {
friend PIByteArray & operator >>(PIByteArray & s, PIString & v); friend PIByteArray & operator >>(PIByteArray & s, PIString & v);

View File

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

View File

@@ -29,6 +29,10 @@
#include "pistring.h" #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> class PIP_EXPORT PIStringList: public PIDeque<PIString>
{ {
public: public:

View File

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

View File

@@ -30,6 +30,10 @@
#include "pistring.h" #include "pistring.h"
//! \ingroup Core
//! \~\brief
//! \~english System time with nanosecond precision.
//! \~russian Системное время с точностью до наносекунд.
class PIP_EXPORT PISystemTime { class PIP_EXPORT PISystemTime {
public: 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 { class PIP_EXPORT PITimeMeasurer {
public: public:
PITimeMeasurer(); PITimeMeasurer();

View File

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

View File

@@ -201,6 +201,9 @@ classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(c
#endif #endif
//! \ingroup Core
//! \~\brief
//! \~english Variant type.
class PIP_EXPORT PIVariant { class PIP_EXPORT PIVariant {
friend PICout operator <<(PICout s, const PIVariant & v); friend PICout operator <<(PICout s, const PIVariant & v);
friend PIByteArray & operator <<(PIByteArray & s, const PIVariant & v); friend PIByteArray & operator <<(PIByteArray & s, const PIVariant & v);

View File

@@ -45,17 +45,16 @@ extern "C" {
# include <sys/stat.h> # include <sys/stat.h>
#endif #endif
/*! \class PIDir
* \brief Local directory //! \class PIDir pidir.h
* //! \details
* \section PIDir_sec0 Synopsis //! \~english \section PIDir_sec0 Synopsis
* This class provide access to local file. You can manipulate //! \~russian \section PIDir_sec0 Краткий обзор
* binary content or use this class as text stream. To binary //! \~english
* access there are function \a read(), \a write(), and many //! This class provide access to local directory.
* \a writeBinary() functions. For write variables to file in //!
* their text representation threr are many "<<" operators. //! \~russian
* //!
*/
PIDir::PIDir(const PIString & dir) { 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() { PIDir & PIDir::cleanPath() {
PIString p(path_); PIString p(path_);
if (p.isEmpty()) { 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 #ifdef WINDOWS
bool sort_compare(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) { bool sort_compare(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {
return strcoll(v0.path.data(), v1.path.data()) < 0; 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 #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> PIDir::entries() {
PIVector<PIFile::FileInfo> l; PIVector<PIFile::FileInfo> l;
if (!isExists()) return 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> PIDir::allEntries() {
PIVector<PIFile::FileInfo> ret; PIVector<PIFile::FileInfo> ret;
PIVector<PIFile::FileInfo> dirs; PIVector<PIFile::FileInfo> dirs;

View File

@@ -29,93 +29,146 @@
#include "pifile.h" #include "pifile.h"
//! \ingroup IO
//! \~\brief
//! \~english Local directory.
//! \~russian Локальная директория.
class PIP_EXPORT PIDir class PIP_EXPORT PIDir
{ {
public: public:
//! Constructs directory with path "path" //! \~english Constructs directory with path "dir"
//! \~russian Создает директорию с путём "dir"
PIDir(const PIString & dir = PIString()); 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); PIDir(const PIFile & file);
//! Returns if this directory is exists //! \~english Returns if this directory exists
//! \~russian Возвращает существует ли эта директория
bool isExists() const {return PIDir::isExists(path());} 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; 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();} bool isRelative() const {return !isAbsolute();}
//! Returns path of current reading directory. This path //! \~english Returns path of current reading directory. This path valid only while \a allEntries() functions
//! valid only while \a allEntries functions //! \~russian Возвращает путь текущей директории чтения. Этот путь действителен только во время выполнения метода \a allEntries()
const PIString & scanDir() const {return scan_;} const PIString & scanDir() const {return scan_;}
//! Returns path of this directory //! \~english Returns path of this directory
//! \~russian Возвращает путь директории
PIString path() const; PIString path() const;
//! Returns absolute path of this directory //! \~english Returns absolute path of this directory
//! \~russian Возвращает абсолютный путь директории
PIString absolutePath() const; PIString absolutePath() const;
/** \brief Simplify path of this directory //! \~english Simplify path of this directory
* \details This function remove repeatedly separators and //! \~russian Упрощает путь директории
* resolve ".." in path. E.g. "/home/.//peri4/src/../.." will
* become "/home" \n This function returns reference to this %PIDir */
PIDir & cleanPath(); 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;} 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; 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); 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());} bool setCurrent() {return PIDir::setCurrent(path());}
/** \brief Returns this directory content //! \~english Returns this directory content
* \details Scan this directory and returns all directories //! \~russian Возвращает содержимое этой директории
* 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! */
PIVector<PIFile::FileInfo> entries(); PIVector<PIFile::FileInfo> entries();
/** \brief Returns all this directory content //! \~english Returns this directory content recursively
* \details Scan this directory recursively and returns all //! \~russian Возвращает содержимое этой директории рекурсивно
* 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 */
PIVector<PIFile::FileInfo> allEntries(); PIVector<PIFile::FileInfo> allEntries();
//! \~english Make this directory, recursively if "withParents"
//! \~russian Создаёт эту директорию, рекурсивно если "withParents"
bool make(bool withParents = true); bool make(bool withParents = true);
//! \~english Remove this directory
//! \~russian Удаляет эту директорию
bool remove() {return PIDir::remove(path());} 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); PIDir & cd(const PIString & path);
//! \~english Change this directory to parent
//! \~russian Изменяет директорию на родительскую
PIDir & up() {return cd("..");} PIDir & up() {return cd("..");}
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator ==(const PIDir & d) const; bool operator ==(const PIDir & d) const;
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator !=(const PIDir & d) const {return !((*this) == d);} bool operator !=(const PIDir & d) const {return !((*this) == d);}
static const PIChar separator; static const PIChar separator;
//! \~english Returns current directory for application
//! \~russian Возвращает текущую директорию приложения
static PIDir current(); static PIDir current();
//! \~english Returns user home directory
//! \~russian Возвращает домашнюю директорию пользователя
static PIDir home(); static PIDir home();
//! \~english Returns temporary directory
//! \~russian Возвращает временную директорию
static PIDir temporary(); static PIDir temporary();
//! \~english Returns directory "path" content recursively
//! \~russian Возвращает содержимое директории "path" рекурсивно
static PIVector<PIFile::FileInfo> allEntries(const PIString & path); static PIVector<PIFile::FileInfo> allEntries(const PIString & path);
//! \~english Returns if directory "path" exists
//! \~russian Возвращает существует ли эта директория
static bool isExists(const PIString & path); 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); static bool make(const PIString & path, bool withParents = true);
//! \~english Remove directory "path"
//! \~russian Удаляет директорию "path"
static bool remove(const PIString & path) {return removeDir(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);} 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); 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());} static bool setCurrent(const PIDir & dir) {return setCurrent(dir.path());}
private: 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);}
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;} inline PICout operator <<(PICout s, const PIDir & v) {s.setControl(0, true); s << "PIDir(\"" << v.path() << "\")"; s.restoreControl(); return s;}

View File

@@ -69,25 +69,44 @@
# define _stat_link_ lstat64 # define _stat_link_ lstat64
#endif #endif
/*! \class PIFile
* \brief Local file //! \class PIFile pifile.h
* //! \details
* \section PIFile_sec0 Synopsis //! \~english \section PIFile_sec0 Synopsis
* This class provide access to local file. You can manipulate //! \~russian \section PIFile_sec0 Краткий обзор
* binary content or use this class as text stream. To binary //! \~english
* access there are function \a read(), \a write(), and many //!
* \a writeBinary() functions. For write variables to file in //! This class provide access to local file. You can manipulate
* their text representation threr are many "<<" operators. //! binary content or use this class as text stream. To binary
* //! access there are function \a read(), \a write(), and many
* \section PIFile_sec1 Position //! \a writeBinary() functions. For write and read variables to file in
* Each opened file has a read/write position - logical position //! their text representation there are many "<<" and ">>" operators.
* in the file content you read from or you write to. You can //!
* find out current position with function \a pos(). Function //! \~russian
* \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. //! текстовый поток. Для байтового доступа используются методы
* //! \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) REGISTER_DEVICE(PIFile)

View File

@@ -30,30 +30,62 @@
#include "pipropertystorage.h" #include "pipropertystorage.h"
//! \ingroup IO
//! \~\brief
//! \~english Local file.
//! \~russian Локальный файл.
class PIP_EXPORT PIFile: public PIIODevice class PIP_EXPORT PIFile: public PIIODevice
{ {
PIIODEVICE(PIFile, "file") PIIODEVICE(PIFile, "file")
public: public:
//! Constructs an empty file //! \~english Constructs file with empty path
//! \~russian Создает файл с пустым путём
explicit PIFile(); 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 { 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;} FileInfo(const PIString & path_ = PIString()) {path = path_; size = 0; id_group = id_user = 0;}
//! \~english Type flags
//! \~russian Флаги типа
enum Flag { enum Flag {
File = 0x01, File /*! \~english File \~russian Файл */ = 0x01,
Dir = 0x02, Dir /*! \~english Directory \~russian Директория */ = 0x02,
Dot = 0x04, Dot /*! \~english '.', current directory \~russian '.', текущая директория */ = 0x04,
DotDot = 0x08, DotDot /*! \~english '..', parent directory \~russian '..', родительская директория */ = 0x08,
SymbolicLink = 0x10, SymbolicLink /*! \~english Symbolic link \~russian Символическая ссылка */ = 0x10,
Hidden = 0x20 Hidden /*! \~english Hidden \~russian Скрытый */ = 0x20
}; };
typedef PIFlags<FileInfo::Flag> Flags; typedef PIFlags<FileInfo::Flag> Flags;
//! \ingroup IO
//! \~\brief
//! \~english Local file or directory permissions.
//! \~russian Разрешения локального файла или директории.
struct PIP_EXPORT Permissions { struct PIP_EXPORT Permissions {
Permissions(uchar r = 0): raw(r) {} Permissions(uchar r = 0): raw(r) {}
Permissions(bool r, bool w, bool e): raw(0) {read = r; write = w; exec = e;} 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" : "-");} 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;} operator int() const {return raw;}
Permissions & operator =(int v) {raw = v; return *this;} Permissions & operator =(int v) {raw = v; return *this;}
union { union {
@@ -66,175 +98,321 @@ public:
}; };
}; };
//! \~english Path
//! \~russian Путь
PIString path; PIString path;
//! \~english File size
//! \~russian Размер файла
llong size; llong size;
//! \~english Last access time
//! \~russian Время последнего доступа
PIDateTime time_access; PIDateTime time_access;
//! \~english Last modification time
//! \~russian Время последнего изменения
PIDateTime time_modification; PIDateTime time_modification;
//! \~english Flags
//! \~russian Флаги
Flags flags; Flags flags;
//! \~english User ID
//! \~russian ID пользователя
uint id_user; uint id_user;
//! \~english Group ID
//! \~russian ID группы
uint id_group; uint id_group;
//! \~english Permissions for user
//! \~russian Разрешения для пользователя
Permissions perm_user; Permissions perm_user;
//! \~english Permissions for group
//! \~russian Разрешения для группы
Permissions perm_group; Permissions perm_group;
//! \~english Permissions for other
//! \~russian Разрешения для остальных
Permissions perm_other; Permissions perm_other;
//! \~english Returns name, without directory
//! \~russian Возвращает имя, без директории
PIString name() const; PIString name() const;
//! \~english Returns base name, without directory and extension
//! \~russian Возвращает базовое имя, без директории и расширения
PIString baseName() const; PIString baseName() const;
//! \~english Returns extension
//! \~russian Возвращает расширение
PIString extension() const; PIString extension() const;
//! \~english Returns directory
//! \~russian Возвращает директорию
PIString dir() const; PIString dir() const;
//! \~english Returns if it`s directory
//! \~russian Возвращает директория ли это
bool isDir() const {return flags[Dir];} bool isDir() const {return flags[Dir];}
//! \~english Returns if it`s file
//! \~russian Возвращает файл ли это
bool isFile() const {return flags[File];} bool isFile() const {return flags[File];}
//! \~english Returns if it`s symbolic link
//! \~russian Возвращает символическая ссылка ли это
bool isSymbolicLink() const {return flags[SymbolicLink];} bool isSymbolicLink() const {return flags[SymbolicLink];}
//! \~english Returns if Hidden flag set
//! \~russian Возвращает установлен ли флаг Hidden
bool isHidden() const {return flags[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); 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(); void flush();
//! Move read/write position to "position" //! \~english Move read/write position to "position"
//! \~russian Перемещает позицию чтения/записи на "position"
void seek(llong 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(); 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(); 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); 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); void skip(llong bytes);
//! Read one char and return it //! \~english Read one char and return it
//! \~russian Читает один байт и возвращает его
char readChar(); char readChar();
//! Read one text line and return it //! \~english Read one text line and return it
//! \~russian Читает одну текстовую строку и возвращает её
PIString readLine(); 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); 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); 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); void setPath(const PIString & path);
//! Returns file size //! \~english Returns file size in bytes
//! \~russian Возвращает размер файла в байтах
llong size() const; llong size() const;
//! Returns read/write position //! \~english Returns read/write position
//! \~russian Возвращает позицию чтения/записи
llong pos() const; 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; bool isEnd() const;
//! Returns if file is empty //! \~english Returns if file is empty
//! \~russian Возвращает пустой ли файл
bool isEmpty() const {return (size() <= 0);} 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());} FileInfo fileInfo() const {return fileInfo(path());}
//! Returns float numbers write precision //! \~english Returns float numbers write precision
//! \~russian Возвращает точность записи чисел с плавающей точкой
int precision() const {return prec_;} 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); void setPrecision(int prec);
//! \~english Write size and content of "v" (serialize)
//! \~russian Пишет в файл размер и содержимое "v" (сериализация)
PIFile & put(const PIByteArray & v); PIFile & put(const PIByteArray & v);
//! \~english Read size of byte array and it content (deserialize)
//! \~russian Читает из файла размер байтового массива и его содержимое (десериализация)
PIByteArray get(); 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;} 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;} 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;} 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;} 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;} 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;} 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;} 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;} 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;} 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;} 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;} 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;} 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); PIFile & operator <<(const char v);
//! Write to file string "v"
//! \~english Write to file string "v"
//! \~russian Пишет в файл строку "v"
PIFile & operator <<(const PIString & 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); PIFile & operator >>(double & v);
EVENT_HANDLER(void, clear); EVENT_HANDLER(void, clear);
@@ -242,44 +420,56 @@ public:
EVENT_HANDLER1(void, resize, llong, new_size) {resize(new_size, 0);} EVENT_HANDLER1(void, resize, llong, new_size) {resize(new_size, 0);}
EVENT_HANDLER2(void, resize, llong, new_size, uchar, fill); EVENT_HANDLER2(void, resize, llong, new_size, uchar, fill);
//! //! \~english
//! \~russian
static const char * defaultCharset(); static const char * defaultCharset();
//! //! \~english
//! \~russian
static void setDefaultCharset(const char * c); 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); 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); 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); 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); 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); 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);} static bool applyFileInfo(const FileInfo & info) {return applyFileInfo(info.path, info);}
//! \handlers //! \handlers
//! \{ //! \{
//! \fn void clear() //! \fn void clear()
//! \brief Clear content of file //! \~english Clear content of file
//! \~russian Очищает содержимое файла
//! \fn void resize(llong new_size) //! \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) //! \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() //! \fn void remove()
//! \brief Remove file //! \~english Remove file
//! \~russian Удаляет файл
//! \} //! \}
//! \ioparams //! \ioparams
@@ -310,6 +500,10 @@ private:
}; };
//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
inline PICout operator <<(PICout s, const PIFile::FileInfo & v) { inline PICout operator <<(PICout s, const PIFile::FileInfo & v) {
s.setControl(0, true); s.setControl(0, true);
s << "FileInfo(\"" << v.path << "\", " << PIString::readableSize(v.size) << ", " s << "FileInfo(\"" << v.path << "\", " << PIString::readableSize(v.size) << ", "
@@ -321,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 << 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;} (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 >> 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;} *(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 #endif // PIFILE_H

View File

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

View File

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

View File

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

View File

@@ -29,44 +29,59 @@
#include "piiodevice.h" #include "piiodevice.h"
//! \ingroup IO
//! \~\brief
//! \~english PIIODevice wrapper around PIByteArray
//! \~russian Обёртка PIIODevice вокруг PIByteArray
class PIP_EXPORT PIIOByteArray: public PIIODevice class PIP_EXPORT PIIOByteArray: public PIIODevice
{ {
PIIODEVICE(PIIOByteArray, "") PIIODEVICE(PIIOByteArray, "")
public: 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); 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); explicit PIIOByteArray(const PIByteArray & buffer);
//! Returns content //! \~english Returns content
//! \~russian Возвращает содержимое
PIByteArray * byteArray() const {return data_;} PIByteArray * byteArray() const {return data_;}
//! Clear content buffer //! \~english Clear content buffer
//! \~russian Очищает содержимое буфера
void clear() {if (data_) data_->clear(); pos = 0;} 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); 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); 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();} 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;} 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;} 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();} 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); int writeByteArray(const PIByteArray & ba);
protected: protected:

View File

@@ -23,13 +23,7 @@
#include "pipropertystorage.h" #include "pipropertystorage.h"
//! \addtogroup IO
//! \{
//! \class PIIODevice piiodevice.h //! \class PIIODevice piiodevice.h
//! \brief
//! \~english Base class for input/output classes
//! \~russian Базовый класс утройств ввода/вывода
//!
//! \~\details //! \~\details
//! \section PIIODevice_sec0 Synopsis //! \section PIIODevice_sec0 Synopsis
//! This class provide open/close logic, threaded read/write and virtual input/output //! This class provide open/close logic, threaded read/write and virtual input/output
@@ -87,7 +81,7 @@
//! \n \a constructFullPath() should returns full unambiguous string, contains prefix and all device parameters //! \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 \a configureFromFullPath() provide configuring device from full unambiguous string without prefix and "://"
//! \n Macro PIIODEVICE should be used instead of PIOBJECT //! \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 \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: //! \n Each PIP I/O device has custom unambiguous string description:
//! * PIFile: "file://<path>" //! * PIFile: "file://<path>"
@@ -116,7 +110,6 @@
//! \section PIIODevice_ex0 Example //! \section PIIODevice_ex0 Example
//! \snippet piiodevice.cpp 0 //! \snippet piiodevice.cpp 0
//! //!
//! \}
PIMutex PIIODevice::nfp_mutex; PIMutex PIIODevice::nfp_mutex;
@@ -130,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() { PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode mode): PIThread() {
mode_ = mode; mode_ = mode;
_init(); _init();
@@ -159,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) { bool stopThread(PIThread * t, bool hard) {
#ifdef MICRO_PIP #ifdef MICRO_PIP
t->stop(true); t->stop(true);
@@ -423,7 +441,7 @@ bool PIIODevice::configure(const PIString & config_file, const PIString & sectio
PIString PIIODevice::constructFullPath() const { PIString PIIODevice::constructFullPath() const {
return PIStringAscii(fullPathPrefix()) + PIStringAscii("://") + constructFullPathDevice() + fullPathOptions(); return fullPathPrefix().toString() + PIStringAscii("://") + constructFullPathDevice() + fullPathOptions();
} }
@@ -499,16 +517,15 @@ PIStringList PIIODevice::availableClasses() {
} }
void PIIODevice::registerDevice(const char * prefix, const char * classname, PIIODevice * (*fabric)()) { void PIIODevice::registerDevice(PIConstChars prefix, PIConstChars classname, PIIODevice * (*fabric)()) {
PIConstChars p(prefix); if (prefix.isEmpty()) return;
if (p.isEmpty()) return;
//printf("registerDevice %s %d %d\n", prefix, p.isEmpty(), fabrics().size()); //printf("registerDevice %s %d %d\n", prefix, p.isEmpty(), fabrics().size());
if (!fabrics().contains(p)) { if (!fabrics().contains(prefix)) {
FabricInfo fi; FabricInfo fi;
fi.prefix = prefix; fi.prefix = prefix;
fi.classname = classname; fi.classname = classname;
fi.fabricator = fabric; fi.fabricator = fabric;
fabrics()[p] = fi; fabrics()[prefix] = fi;
} }
} }
@@ -525,6 +542,13 @@ 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) { PIIODevice * PIIODevice::createFromFullPath(const PIString & full_path) {
PIString prefix = full_path.left(full_path.find(":")); PIString prefix = full_path.left(full_path.find(":"));
PIIODevice * nd = newDeviceByPrefix(prefix.dataAscii()); PIIODevice * nd = newDeviceByPrefix(prefix.dataAscii());

View File

@@ -37,10 +37,22 @@ typedef bool (*ReadRetFunc)(void * , uchar * , int );
#ifdef DOXYGEN #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) # define REGISTER_DEVICE(class)
//! \relatesalso PIIODevice \brief Use this macro instead of PIOBJECT when describe your own PIIODevice //! \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") # define PIIODEVICE(class, "prefix")
#else #else
@@ -54,13 +66,17 @@ typedef bool (*ReadRetFunc)(void * , uchar * , int );
PIOBJECT_SUBCLASS(name, PIIODevice) \ PIOBJECT_SUBCLASS(name, PIIODevice) \
PIIODevice * copy() const {return new name();} \ PIIODevice * copy() const {return new name();} \
public: \ public: \
virtual const char * fullPathPrefix() const {return prefix;} \ virtual PIConstChars fullPathPrefix() const {return prefix;} \
static const char * fullPathPrefixS() {return prefix;} \ static PIConstChars fullPathPrefixS() {return prefix;} \
private: private:
#endif #endif
//! \ingroup IO
//! \~\brief
//! \~english Base class for input/output devices.
//! \~russian Базовый класс утройств ввода/вывода.
class PIP_EXPORT PIIODevice: public PIThread class PIP_EXPORT PIIODevice: public PIThread
{ {
PIOBJECT_SUBCLASS(PIIODevice, PIThread) PIOBJECT_SUBCLASS(PIIODevice, PIThread)
@@ -68,26 +84,30 @@ class PIP_EXPORT PIIODevice: public PIThread
public: public:
NO_COPY_CLASS(PIIODevice) NO_COPY_CLASS(PIIODevice)
//! Constructs a empty PIIODevice //! \~english Constructs a empty %PIIODevice
//! \~russian Создает пустой %PIIODevice
explicit PIIODevice(); explicit PIIODevice();
//! \brief Open modes for PIIODevice //! \~english Open modes for PIIODevice
//! \~russian Режимы открытия для PIIODevice
enum DeviceMode { enum DeviceMode {
ReadOnly /*! Device can only read */ = 0x01, ReadOnly /*! \~english Device can only read \~russian Устройство может только читать */ = 0x01,
WriteOnly /*! Device can only write */ = 0x02, WriteOnly /*! \~english Device can only write \~russian Устройство может только писать */ = 0x02,
ReadWrite /*! Device can both read and write */ = 0x03 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 { enum DeviceOption {
BlockingRead /*! \a read block until data is received, default off */ = 0x01, BlockingRead /*! \~english \a read() block until data is received, default off \~russian \a read() блокируется, пока данные не поступят, по умолчанию выключено */ = 0x01,
BlockingWrite /*! \a write block until data is sent, default off */ = 0x02 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 { enum DeviceInfoFlag {
Sequential /*! Continuous bytestream without datagrams */ = 0x01, Sequential /*! \~english Continuous bytestream without packets \~russian Непрерывный поток байт, без пакетирования */ = 0x01,
Reliable /*! Channel without data errors / corruptions */ = 0x02 Reliable /*! \~english Channel without data errors or corruptions \~russian Канал без ошибок или повреждений данных */ = 0x02
}; };
struct FabricInfo { struct FabricInfo {
@@ -99,188 +119,235 @@ public:
typedef PIFlags<DeviceOption> DeviceOptions; typedef PIFlags<DeviceOption> DeviceOptions;
typedef PIFlags<DeviceInfoFlag> DeviceInfoFlags; 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); explicit PIIODevice(const PIString & path, DeviceMode mode = ReadWrite);
virtual ~PIIODevice(); virtual ~PIIODevice();
//! Current open mode of device //! \~english Returns current open mode of device
//! \~russian Возвращает текущий режим открытия устройства
DeviceMode mode() const {return mode_;} 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;} void setMode(DeviceMode m) {mode_ = m;}
//! Current device options //! \~english Returns current device options
//! \~russian Возвращает текущие опции устройства
DeviceOptions options() const {return options_;} 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];} bool isOptionSet(DeviceOption o) const {return options_[o];}
//! Set device options //! \~english Set device options
//! \~russian Устанавливает опции устройства
void setOptions(DeviceOptions o); 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); bool setOption(DeviceOption o, bool yes = true);
//! Returns device characteristic flags //! \~english Returns device characteristic flags
//! \~russian Возвращает характеристики канала
DeviceInfoFlags infoFlags() const {return deviceInfoFlags();} DeviceInfoFlags infoFlags() const {return deviceInfoFlags();}
//! Current path of device //! \~english Returns current path of device
//! \~russian Возвращает текущий путь устройства
PIString path() const {return property("path").toString();} PIString path() const {return property("path").toString();}
//! Set path of device //! \~english Set path of device. Don`t reopen device
//! \~russian Устанавливает путь устройства. Не переоткрывает устройство
void setPath(const PIString & path) {setProperty("path", path);} 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);} 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);} 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_;} bool isOpened() const {return opened_;}
//! Return \b true if device is closed //! \~english Returns if device is closed
//! \~russian Возвращает закрыто ли устройство
bool isClosed() const {return !opened_;} 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);} 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);} virtual bool canWrite() const {return opened_ && (mode_ & WriteOnly);}
//! Set execution of \a open enabled while threaded read on closed device //! \~english Set calling of \a open() enabled while threaded read on closed device
//! \~russian Устанавливает возможность вызова \a open() при потоковом чтении на закрытом устройстве
void setReopenEnabled(bool yes = true) {setProperty("reopenEnabled", yes);} void setReopenEnabled(bool yes = true) {setProperty("reopenEnabled", yes);}
//! Set timeout in milliseconds between \a open tryings if reopen is enabled //!
//! \~english Set timeout in milliseconds between \a open() tryings if reopen is enabled
//! \~russian Устанавливает задержку в миллисекундах между вызовами \a open() если переоткрытие активно
void setReopenTimeout(int msecs) {setProperty("reopenTimeout", msecs);} void setReopenTimeout(int msecs) {setProperty("reopenTimeout", msecs);}
//! \~english Returns reopen enable
//! Return reopen enable //! \~russian Возвращает активно ли переоткрытие
bool isReopenEnabled() const {return property("reopenEnabled").toBool();} bool isReopenEnabled() const {return property("reopenEnabled").toBool();}
//! Return reopen timeout //! \~english Returns reopen timeout in milliseconds
//! \~russian Возвращает задержку переоткрытия в миллисекундах
int reopenTimeout() {return property("reopenTimeout").toInt();} int reopenTimeout() {return property("reopenTimeout").toInt();}
/** \brief Set "threaded read slot" //! \~english Set threaded read callback
* \details Set external static function of threaded read that will be executed //! \~russian Устанавливает callback потокового чтения
* at every successful threaded read. Function should have format void setThreadedReadSlot(ReadRetFunc func);
* "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;} void setThreadedReadData(void * d) {ret_data_ = d;}
/** \brief Set size of threaded read buffer //! \~english Set size of threaded read buffer
* \details Default size is 4096 bytes. If your device can read at single read //! \~russian Устанавливает размер буфера потокового чтения
* more than 4096 bytes you should use this function to adjust buffer size */ void setThreadedReadBufferSize(int new_size);
void setThreadedReadBufferSize(int new_size) {threaded_read_buffer_size = new_size; threadedReadBufferSizeChanged();}
//! Return size of threaded read buffer //! \~english Returns size of threaded read buffer
//! \~russian Возвращает размер буфера потокового чтения
int threadedReadBufferSize() const {return threaded_read_buffer_size;} 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();} 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_;} 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();} bool isThreadedRead() const {return isRunning();}
//! Start threaded read //! \~english Start threaded read
//! \~russian Запускает потоковое чтение
void startThreadedRead() {if (!isRunning()) PIThread::start();} 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();} 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); 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();} bool isThreadedWrite() const {return write_thread.isRunning();}
//! Start threaded write //! \~english Start threaded write
//! \~russian Запускает потоковую запись
void startThreadedWrite() {if (!write_thread.isRunning()) write_thread.startOnce();} 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); void stopThreadedWrite(bool hard = true);
//! Clear threaded write task queue //! \~english Clear threaded write task queue
//! \~russian Очищает очередь потоковой записи
void clearThreadedWriteQueue(); void clearThreadedWriteQueue();
//! Start both threaded read and threaded write //! \~english Start both threaded read and threaded write
//! \~russian Запускает потоковое чтение и запись
void start(); 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); 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);} 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); 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);} 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); 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)));} 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); 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); bool configure(const PIString & config_file, const PIString & section, bool parent_section = false);
//! Returns full unambiguous string prefix. \ref PIIODevice_sec7 //! \~english Returns full unambiguous string prefix. \ref PIIODevice_sec7
virtual const char * fullPathPrefix() const {return "";} //! \~russian Возвращает префикс устройства. \ref PIIODevice_sec7
virtual PIConstChars fullPathPrefix() const {return "";}
static const char * fullPathPrefixS() {return "";} static PIConstChars fullPathPrefixS() {return "";}
//! Returns full unambiguous string, describes this device, \a fullPathPrefix() + "://" //! \~english Returns full unambiguous string, describes this device, \a fullPathPrefix() + "://" + ...
//! \~russian Возвращает строку полного описания для этого устройства, \a fullPathPrefix() + "://" + ...
PIString constructFullPath() const; 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); 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; PIVariantTypes::IODevice constructVariant() const;
//! Configure device from PIVariantTypes::IODevice //! \~english Configure device from PIVariantTypes::IODevice
//! \~russian Настраивает устройство из PIVariantTypes::IODevice
void configureFromVariant(const PIVariantTypes::IODevice & d); void configureFromVariant(const PIVariantTypes::IODevice & d);
//! \brief Try to determine suitable device, create new one, configure it with \a configureFromFullPath() and returns it. //! \~english Try to create new device by prefix, configure it with \a configureFromFullPath() and returns it.
//! \details To function \a configureFromFullPath() "full_path" passed without \a fullPathPrefix() + "://". //! \~russian Пытается создать новое устройство по префиксу, настраивает с помощью \a configureFromFullPath() и возвращает его
//! See \ref PIIODevice_sec7
static PIIODevice * createFromFullPath(const PIString & full_path); static PIIODevice * createFromFullPath(const PIString & full_path);
//! \brief Try to determine suitable device, create new one, configure it with \a configureFromVariant() and returns it. //! \~english Try to create new device by prefix, configure it with \a configureFromVariant() and returns it.
//! \details To function \a configureFromFullPath() "full_path" passed without \a fullPathPrefix() + "://". //! \~russian Пытается создать новое устройство по префиксу, настраивает с помощью \a configureFromVariant() и возвращает его
//! See \ref PIIODevice_sec7
static PIIODevice * createFromVariant(const PIVariantTypes::IODevice & d); static PIIODevice * createFromVariant(const PIVariantTypes::IODevice & d);
static PIString normalizeFullPath(const PIString & full_path); static PIString normalizeFullPath(const PIString & full_path);
static void splitFullPath(PIString fpwm, PIString * full_path, DeviceMode * mode = 0, DeviceOptions * opts = 0); 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(); static PIStringList availablePrefixes();
//! Returns class names of all registered devices //! \~english Returns class names of all registered devices
//! \~russian Возвращает имена классов всех зарегистрированных устройств
static PIStringList availableClasses(); static PIStringList availableClasses();
static void registerDevice(const char * prefix, const char * classname, PIIODevice*(*fabric)()); static void registerDevice(PIConstChars prefix, PIConstChars classname, PIIODevice*(*fabric)());
EVENT_HANDLER(bool, open); EVENT_HANDLER(bool, open);
@@ -301,111 +368,149 @@ public:
//! \{ //! \{
//! \fn bool open() //! \fn bool open()
//! \brief Open device //! \~english Open device
//! \~russian Открывает устройство
//! \fn bool open(const PIString & path) //! \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) //! \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) //! \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() //! \fn bool close()
//! \brief Close device //! \~english Close device
//! \~russian Закрывает устройство
//! \fn int write(PIByteArray data) //! \fn int write(PIByteArray data)
//! \brief Write "data" to device //! \~english Write "data" to device
//! \~russian Пишет "data" в устройство
//! \} //! \}
//! \vhandlers //! \vhandlers
//! \{ //! \{
//! \fn void flush() //! \fn void flush()
//! \brief Immediate write all buffers //! \~english Immediate write all buffers
//! \~russian Немедленно записать все буферизированные данные
//! \} //! \}
//! \events //! \events
//! \{ //! \{
//! \fn void opened() //! \fn void opened()
//! \brief Raise if succesfull open //! \~english Raise if succesfull open
//! \~russian Вызывается при успешном открытии
//! \fn void closed() //! \fn void closed()
//! \brief Raise if succesfull close //! \~english Raise if succesfull close
//! \~russian Вызывается при успешном закрытии
//! \fn void threadedReadEvent(uchar * readed, int size) //! \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) //! \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 //! \ioparams
//! \{ //! \{
#ifdef DOXYGEN #ifdef DOXYGEN
//! \brief setReopenEnabled, default "true" //! \~english setReopenEnabled, default "true"
//! \~russian setReopenEnabled, по умолчанию "true"
bool reopenEnabled; bool reopenEnabled;
//! \brief setReopenTimeout in ms, default 1000 //! \~english setReopenTimeout in milliseconds, default 1000
//! \~russian setReopenTimeout в миллисекундах, по умолчанию 1000
int reopenTimeout; int reopenTimeout;
//! \brief setThreadedReadBufferSize in bytes, default 4096 //! \~english setThreadedReadBufferSize in bytes, default 4096
//! \~russian setThreadedReadBufferSize в байтах, по умолчанию 4096
int threadedReadBufferSize; int threadedReadBufferSize;
#endif #endif
//! \} //! \}
protected: 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;} 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;} 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 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 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;} 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;} 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); 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();} 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);} 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 //! Default implementation return PIPropertyStorage with \"path\" entry
//! \~russian Переопределите для создания свойств устройства.
//! По умолчанию возвращает PIPropertyStorage со свойством \"path\"
virtual PIPropertyStorage constructVariantDevice() const; 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 //! Default implementation apply \"path\" entry
//! \~russian Переопределите для настройки устройства из PIPropertyStorage. Опции и режим уже применены.
//! По умолчанию устанавливает свойство \"path\"
virtual void configureFromVariantDevice(const PIPropertyStorage & d); virtual void configureFromVariantDevice(const PIPropertyStorage & d);
//! Reimplement to apply new device options //! \~english Reimplement to apply new device options
//! \~russian Переопределите для применения новых опций устройства
virtual void optionsChanged() {;} 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;} 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() {;} virtual void threadedReadBufferSizeChanged() {;}
//! Invoked after hard read thread stop //! \~english Invoked after hard read thread stop
//! \~russian Вызывается после жесткой остановки потока чтения
virtual void threadedReadTerminated() {;} virtual void threadedReadTerminated() {;}
//! Invoked after hard write thread stop //! \~english Invoked after hard write thread stop
//! \~russian Вызывается после жесткой остановки потока записи
virtual void threadedWriteTerminated() {;} virtual void threadedWriteTerminated() {;}
static PIIODevice * newDeviceByPrefix(const char * prefix); static PIIODevice * newDeviceByPrefix(const char * prefix);

View File

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

View File

@@ -29,47 +29,63 @@
#include "piiodevice.h" #include "piiodevice.h"
//! \ingroup IO
//! \~\brief
//! \~english PIIODevice wrapper around PIString.
//! \~russian Обёртка PIIODevice вокруг PIString.
class PIP_EXPORT PIIOString: public PIIODevice class PIP_EXPORT PIIOString: public PIIODevice
{ {
PIIODEVICE(PIIOString, "") PIIODEVICE(PIIOString, "")
public: 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); 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); explicit PIIOString(const PIString & string);
//! Returns content //! \~english Returns content
//! \~russian Возвращает содержимое
PIString * string() const {return str;} PIString * string() const {return str;}
//! Clear content string //! \~english Clear content string
//! \~russian Очищает содержимое строки
void clear() {if (str) str->clear(); pos = 0;} 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); 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); 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();} 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;} 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;} 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();} 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(); 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); int writeString(const PIString & string);
protected: protected:

View File

@@ -137,21 +137,33 @@
#endif #endif
/*! \class PISerial //! \class PISerial piserial.h
* \brief Serial device //! \details
* //! \~english \section PISerial_sec0 Synopsis
* \section PISerial_sec0 Synopsis //! \~russian \section PISerial_sec0 Краткий обзор
* This class provide access to serial device, e.g. COM port. It can read, //! \~english
* write, wait for write. There are several read and write functions. //! 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. //! \~russian
* \code //! Этот класс предоставляет доступ к последовательному порту, например, COM-порт.
* PISerial * s = new PISerial("0403:6001"); //!
* PIIODevice * d = PIIODevice::createFromFullPath("ser://0403:6001:115200"); //! \~english \section PISerial_sec1 FullPath
* \endcode //! \~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) 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");} 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) { bool PISerial::setBreak(bool enabled) {
if (fd < 0) { if (fd < 0) {
piCoutObj << "sendBreak error: \"" << path() << "\" is not opened!"; piCoutObj << "sendBreak error: \"" << path() << "\" is not opened!";
@@ -416,14 +438,24 @@ int PISerial::convertSpeed(PISerial::Speed speed) {
} }
/** \brief Advanced read function //! \details
* \details Read to pointer "read_to" no more than "max_size" and no longer //! \~english
* than "timeout_ms" milliseconds. If "timeout_ms" < 0 function will be //! Read to pointer "read_to" no more than "max_size" and no longer
* wait forever until "max_size" will be readed. If size <= 0 function //! than "timeout_ms" milliseconds.\n
* immediate returns \b false. For read data with unknown size use function //! If "timeout_ms" < 0 function will be wait forever until "max_size" will be readed.\n
* \a readData(). //! If "size" <= 0 function immediate returns \b false.\n
* \returns \b True if readed bytes count = "max_size", else \b false //! For read data with unknown size use function \a readData().
* \sa \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) { bool PISerial::read(void * data, int size, double timeout_ms) {
if (data == 0 || size <= 0) return false; if (data == 0 || size <= 0) return false;
int ret, all = 0; int ret, all = 0;
@@ -454,15 +486,25 @@ bool PISerial::read(void * data, int size, double timeout_ms) {
} }
/** \brief Advanced read function //! \details
* \details Read all or no more than "size" and no longer than //! \~english
* "timeout_ms" milliseconds. If "timeout_ms" < 0 function will be //! Read all or no more than "size" bytes and no longer than "timeout_ms" milliseconds.\n
* wait forever until "size" will be readed. If "size" <= 0 //! If "timeout_ms" < 0 function will be wait forever until "max_size" will be readed.\n
* function will be read all until "timeout_ms" elaped. \n If size <= 0 //! If "size" <= 0 function will be read all until "timeout_ms" elaped.\n
* and "timeout_ms" <= 0 function immediate returns empty string. //! If "size" <= 0 and "timeout_ms" <= 0 function immediate returns empty string.\n
* \n This function similar to \a readData() but returns data as string. //! This function similar to \a readData() but returns data as string.
* \sa \a readData() */ //! \returns If readed bytes count = "max_size"
PIString PISerial::read(int size, double timeout_ms) { //!
//! \~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; PIString str;
if (size <= 0 && timeout_ms <= 0.) return str; if (size <= 0 && timeout_ms <= 0.) return str;
int ret, all = 0; int ret, all = 0;
@@ -506,14 +548,24 @@ PIString PISerial::read(int size, double timeout_ms) {
} }
/** \brief Advanced read function //! \details
* \details Read all or no more than "size" and no longer than //! \~english
* "timeout_ms" milliseconds. If "timeout_ms" < 0 function will be //! Read all or no more than "size" bytes and no longer than "timeout_ms" milliseconds.\n
* wait forever until "size" will be readed. If "size" <= 0 //! If "timeout_ms" < 0 function will be wait forever until "max_size" will be readed.\n
* function will be read all until "timeout_ms" elaped. \n If size <= 0 //! If "size" <= 0 function will be read all until "timeout_ms" elaped.\n
* and "timeout_ms" <= 0 function immediate returns empty byte array. //! If "size" <= 0 and "timeout_ms" <= 0 function immediate returns empty string.\n
* \n This function similar to \a read() but returns data as byte array. //! This function similar to \a readString() but returns data as byte array.
* \sa \a read() */ //! \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 PISerial::readData(int size, double timeout_ms) {
PIByteArray str; PIByteArray str;
if (size <= 0 && timeout_ms <= 0.) return str; if (size <= 0 && timeout_ms <= 0.) return str;
@@ -722,11 +774,20 @@ void PISerial::setTimeouts() {
} }
/** \brief Basic read function //! \details
* \details Read to pointer "read_to" no more than "max_size". If read is //! \~english
* set to blocking this function will be wait at least one byte. //! Read to pointer "read_to" no more than "max_size".
* \returns Readed bytes count //! If \a PIIODevice::BlockingRead option set this function
* \sa \a readData() */ //! 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) { int PISerial::readDevice(void * read_to, int max_size) {
#ifdef WINDOWS #ifdef WINDOWS
if (!canRead()) return -1; if (!canRead()) return -1;

View File

@@ -29,42 +29,52 @@
#include "pitimer.h" #include "pitimer.h"
#include "piiodevice.h" #include "piiodevice.h"
//! \ingroup IO
//! \~\brief
//! \~english Serial device.
//! \~russian Последовательный порт.
class PIP_EXPORT PISerial: public PIIODevice class PIP_EXPORT PISerial: public PIIODevice
{ {
PIIODEVICE(PISerial, "ser") PIIODEVICE(PISerial, "ser")
public: public:
//! Contructs an empty %PISerial //! \~english Contructs an empty %PISerial
//! \~russian Создает пустой %PISerial
explicit PISerial(); explicit PISerial();
//! \brief Parameters of PISerial virtual ~PISerial();
//! \~english Parameters of PISerial
//! \~russian Параметры PISerial
enum Parameters { enum Parameters {
ParityControl /*! Enable parity check and generate */ = 0x1, ParityControl /*! \~english Enable parity check and generate \~russian Включить генерацию и проверку контроля чётности */ = 0x1,
ParityOdd /*! Parity is odd instead of even */ = 0x2, ParityOdd /*! \~english Parity is odd instead of even \~russian Нечётный контроль чётности вместо чётного */ = 0x2,
TwoStopBits /*! Two stop bits instead of one */ = 0x4 TwoStopBits /*! \~english Two stop bits instead of one \~russian Два стоповых бита вместо одного */ = 0x4
}; };
//! \brief Speed of PISerial //! \~english Speed of PISerial
//! \~russian Скорость PISerial
enum Speed { enum Speed {
S50 /*! 50 baud */ = 50, S50 /*! 50 baud */ = 50,
S75 /*! 75 baud */ = 75, S75 /*! 75 baud */ = 75,
S110 /*! 110 baud */ = 110, S110 /*! 110 baud */ = 110,
S300 /*! 300 baud */ = 300, S300 /*! 300 baud */ = 300,
S600 /*! 600 baud */ = 600, S600 /*! 600 baud */ = 600,
S1200 /*! 1200 baud */ = 1200, S1200 /*! 1200 baud */ = 1200,
S2400 /*! 2400 baud */ = 2400, S2400 /*! 2400 baud */ = 2400,
S4800 /*! 4800 baud */ = 4800, S4800 /*! 4800 baud */ = 4800,
S9600 /*! 9600 baud */ = 9600, S9600 /*! 9600 baud */ = 9600,
S14400 /*! 14400 baud */ = 14400, S14400 /*! 14400 baud */ = 14400,
S19200 /*! 19200 baud */ = 19200, S19200 /*! 19200 baud */ = 19200,
S38400 /*! 38400 baud */ = 38400, S38400 /*! 38400 baud */ = 38400,
S57600 /*! 57600 baud */ = 57600, S57600 /*! 57600 baud */ = 57600,
S115200 /*! 115200 baud */ = 115200, S115200 /*! 115200 baud */ = 115200,
S230400 /*! 230400 baud */ = 230400, S230400 /*! 230400 baud */ = 230400,
S460800 /*! 460800 baud */ = 460800, S460800 /*! 460800 baud */ = 460800,
S500000 /*! 500000 baud */ = 500000, S500000 /*! 500000 baud */ = 500000,
S576000 /*! 576000 baud */ = 576000, S576000 /*! 576000 baud */ = 576000,
S921600 /*! 921600 baud */ = 921600, S921600 /*! 921600 baud */ = 921600,
S1000000 /*! 1000000 baud */ = 1000000, S1000000 /*! 1000000 baud */ = 1000000,
S1152000 /*! 1152000 baud */ = 1152000, S1152000 /*! 1152000 baud */ = 1152000,
S1500000 /*! 1500000 baud */ = 1500000, S1500000 /*! 1500000 baud */ = 1500000,
@@ -75,72 +85,93 @@ public:
S4000000 /*! 4000000 baud */ = 4000000 S4000000 /*! 4000000 baud */ = 4000000
}; };
//! \brief Information about serial device //! \ingroup IO
//! \~\brief
//! \~english Information about serial device
//! \~russian Информация о последовательном устройстве
struct PIP_EXPORT DeviceInfo { struct PIP_EXPORT DeviceInfo {
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; PIString id() const;
//! \brief USB Vendor ID //! \~english USB Vendor ID
//! \~russian USB Vendor ID
uint vID; uint vID;
//! \brief USB Product ID //! \~english USB Product ID
//! \~russian USB Product ID
uint pID; 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; PIString path;
//! \brief Device description //! \~english Device description
//! \~russian Описание устройства
PIString description; PIString description;
//! \brief Device manufacturer //! \~english Device manufacturer
//! \~russian Описание производителя
PIString manufacturer; 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); 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();} 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();} 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();} 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();};} 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();} 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); 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; bool isParameterSet(PISerial::Parameters parameter) const;
//! Returns parameters //! \~english Returns parameters
//! \~russian Возвращает параметры
PIFlags<PISerial::Parameters> parameters() const {return (PIFlags<Parameters>)(property("parameters").toInt());} 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();} 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();} 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); 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 isPin(int number) const;
bool setLE(bool on); // useless function, just formally bool setLE(bool on); // useless function, just formally
@@ -163,69 +194,89 @@ public:
bool isRNG() const; bool isRNG() const;
bool isDSR() const; bool isDSR() const;
//! Switch transmission line in break if enabled. //! \~english Switch transmission line in break
//! i.e. sends a continuous stream of zero bits. //! \~russian Переключает состояние передачи в break
//! If successful, returns true; otherwise returns false.
//! The serial port has to be open before trying to send a break duration; otherwise returns false
bool setBreak(bool enabled); bool setBreak(bool enabled);
void setVTime(int t) {vtime = t; applySettings();} void setVTime(int t) {vtime = t; applySettings();}
//! Returns device name //! \~english Returns device name
//! \~russian Возвращает имя устройства
PIString device() const {return path();} PIString device() const {return path();}
//! Returns output speed //! \~english Returns output speed
//! \~russian Возвращает скорость передачи
PISerial::Speed outSpeed() const {return (PISerial::Speed)(property("outSpeed").toInt());} 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());} PISerial::Speed inSpeed() const {return (PISerial::Speed)(property("inSpeed").toInt());}
int VTime() const {return vtime;} int VTime() const {return vtime;}
//! Discard all buffered input and output data //! \~english Discard all buffered input and output data
//! \~russian Откидывает все буферизированные данные для передачи и приема
void flush(); void flush();
int read(void * read_to, int max_size) {return readDevice(read_to, max_size);} int read(void * read_to, int max_size) {return readDevice(read_to, max_size);}
//! \~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); 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.); 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. //! \~english Write to device data "data" with maximum size "size". Returns if sended bytes count = "size"
//! \returns \b true if sended bytes count = "size" //! \~russian Пишет в порт не более "size" байт данных "data". Возвращает если количество записанных байт = "size"
bool send(const void * data, int size); bool send(const void * data, int size);
//! \brief Write to device byte array "data" //! \~english Write to device byte array "data". Returns if sended bytes count = size of "data"
//! \returns \b true if sended bytes count = size of string //! \~russian Пишет в порт байтовый массив "data". Возвращает если количество записанных байт = размер "data"
bool send(const PIByteArray & data) {return send(data.data(), data.size_s());} 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(); 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); 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); static PIVector<DeviceInfo> availableDevicesInfo(bool test = false);
//! \ioparams //! \ioparams
//! \{ //! \{
#ifdef DOXYGEN #ifdef DOXYGEN
//! \brief device, default "" //! \~english device, default ""
//! \~russian устройство, по умолчанию ""
string device; string device;
//! \brief input/output speed, default 115200 //! \~english input/output speed, default 115200
//! \~russian скорость чтения/записи, по умолчанию 115200
int speed; int speed;
//! \brief dataBitsCount, default 8 //! \~english dataBitsCount, default 8
//! \~russian количесво бит данных, по умолчанию 8
int dataBitsCount; int dataBitsCount;
//! \brief parityControl, default false //! \~english parityControl, default false
//! \~russian контроль четности, по умолчанию false
bool parityControl; bool parityControl;
//! \brief parityOdd, default false //! \~english parityOdd, default false
//! \~russian нечётный контроль четности, по умолчанию false
bool parityOdd; bool parityOdd;
//! \brief twoStopBits, default false //! \~english twoStopBits, default false
//! \~russian два стоповых бита, по умолчанию false
bool twoStopBits; bool twoStopBits;
#endif #endif
//! \} //! \}
@@ -238,6 +289,9 @@ protected:
bool configureDevice(const void * e_main, const void * e_parent = 0); bool configureDevice(const void * e_main, const void * e_parent = 0);
void optionsChanged(); void optionsChanged();
void threadedReadBufferSizeChanged(); void threadedReadBufferSizeChanged();
//! \~english Basic read function
//! \~russian Базовое чтение
int readDevice(void * read_to, int max_size); int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size); int writeDevice(const void * data, int max_size);
DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Sequential;} DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Sequential;}
@@ -263,14 +317,30 @@ protected:
}; };
//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
inline PICout operator <<(PICout s, const PISerial::DeviceInfo & v) { inline PICout operator <<(PICout s, const PISerial::DeviceInfo & v) {
s << v.path << " (" << v.id() << ", \"" << v.manufacturer << "\", \"" << v.description << "\")"; s << v.path << " (" << v.id() << ", \"" << v.manufacturer << "\", \"" << v.description << "\")";
return s; return s;
} }
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator ==(const PISerial::DeviceInfo & v0, const PISerial::DeviceInfo & v1) {return v0.path == v1.path;} 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;} 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;} 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;} 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 #endif
/*! \class PISharedMemory //! \class PISharedMemory pisharedmemory.h
* \brief Shared memory //! \details
* //! \~english
* \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 //! \~russian
* 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. //! объекта разделяемой памяти выделяется \a size() байт, по умолчанию
* //! 65 Кб. Все процессы должны использовать один и тот же \a size()
* \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 read() или \a write() обращается
* \a seek(llong position) move position to position "position", //! к началу памяти. Для работы с конкретным участком памяти
* \a seekToBegin() move position to the begin of file, //! используются перегруженные методы с указанием "offset".
* \a seekToEnd() move position to the end of file. //!
*
*/
REGISTER_DEVICE(PISharedMemory) REGISTER_DEVICE(PISharedMemory)

View File

@@ -29,47 +29,64 @@
#include "piiodevice.h" #include "piiodevice.h"
//! \ingroup IO
//! \~\brief
//! \~english Shared memory.
//! \~russian Разделяемая память.
class PIP_EXPORT PISharedMemory: public PIIODevice class PIP_EXPORT PISharedMemory: public PIIODevice
{ {
PIIODEVICE(PISharedMemory, "shm") PIIODEVICE(PISharedMemory, "shm")
public: public:
//! \~english Constructs empty %PISharedMemory
//! \~russian Создает пустой %PISharedMemory
explicit 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); explicit PISharedMemory(const PIString & shm_name, int size, DeviceMode mode = ReadWrite);
virtual ~PISharedMemory(); 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(); PIByteArray readAll();
//! Returns shared memory object size //! \~english Returns shared memory size
//! \~russian Возвращает размер разделяемой памяти
llong size() const; llong size() const;
//! Set shared memory object size //! \~english Set shared memory size
//! \~russian Устанавливает размер разделяемой памяти
void setSize(llong s); 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);} 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); 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); 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); 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); 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());} 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);} int write(const PIByteArray & data, int offset) {return write(data.data(), data.size_s(), offset);}

View File

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

View File

@@ -29,12 +29,17 @@
#include "piiodevice.h" #include "piiodevice.h"
//! \ingroup IO
//! \~\brief
//! \~english PIIODevice that pass write to read.
//! \~russian PIIODevice который транслирует запись на чтение.
class PIP_EXPORT PITransparentDevice: public PIIODevice class PIP_EXPORT PITransparentDevice: public PIIODevice
{ {
PIIODEVICE(PITransparentDevice, "tr") PIIODEVICE(PITransparentDevice, "tr")
public: public:
//! Contructs empty %PITransparentDevice //! \~english Contructs empty %PITransparentDevice
//! \~russian Создает пустой %PITransparentDevice
explicit PITransparentDevice(); explicit PITransparentDevice();
virtual ~PITransparentDevice(); virtual ~PITransparentDevice();

View File

@@ -26,14 +26,7 @@
#endif #endif
//! \addtogroup System
//! \{
//! \class PILibrary pilibrary.h //! \class PILibrary pilibrary.h
//!
//! \~\brief
//! \~english Run-time library
//! \~russian Run-time библиотека
//!
//! \~\details //! \~\details
//! \~english \section _sec0 Synopsis //! \~english \section _sec0 Synopsis
//! \~russian \section _sec0 Краткий обзор //! \~russian \section _sec0 Краткий обзор
@@ -126,7 +119,6 @@
//! // mul = 30 //! // mul = 30
//! \endcode //! \endcode
//! //!
//! \}
PRIVATE_DEFINITION_START(PILibrary) PRIVATE_DEFINITION_START(PILibrary)

View File

@@ -30,6 +30,10 @@
#include "pistring.h" #include "pistring.h"
//! \ingroup System
//! \~\brief
//! \~english Run-time library.
//! \~russian Run-time библиотека.
class PIP_EXPORT PILibrary { class PIP_EXPORT PILibrary {
public: public:

View File

@@ -24,14 +24,7 @@
#include "pidir.h" #include "pidir.h"
#include "piincludes_p.h" #include "piincludes_p.h"
//! \addtogroup System
//! \{
//! \class PIPluginLoader piplugin.h //! \class PIPluginLoader piplugin.h
//!
//! \brief
//! \~english Plugin loader
//! \~russian Загрузчик плагина
//!
//! \~\details //! \~\details
//! \~english \section PIPluginLoader_sec0 Synopsis //! \~english \section PIPluginLoader_sec0 Synopsis
//! \~russian \section PIPluginLoader_sec0 Краткий обзор //! \~russian \section PIPluginLoader_sec0 Краткий обзор
@@ -238,7 +231,6 @@
//! } //! }
//! \endcode //! \endcode
//! //!
//! \}
#define STR_WF(s) #s #define STR_WF(s) #s
#define STR(s) STR_WF(s) #define STR(s) STR_WF(s)

View File

@@ -156,6 +156,10 @@ private:
//! \ingroup System
//! \~\brief
//! \~english Plugin loader.
//! \~russian Загрузчик плагина.
class PIP_EXPORT PIPluginLoader { class PIP_EXPORT PIPluginLoader {
public: public:
typedef int(*FunctionLoaderVersion)(); typedef int(*FunctionLoaderVersion)();

View File

@@ -30,14 +30,7 @@
#endif #endif
//! \addtogroup System
//! \{
//! \class PIProcess piprocess.h //! \class PIProcess piprocess.h
//!
//! \~\brief
//! \~english External process
//! \~russian Внешний процесс
//!
//! \~\details //! \~\details
//! \~english //! \~english
//! This class able to start external executables, watch for them, //! This class able to start external executables, watch for them,
@@ -65,7 +58,6 @@
//! //!
//! \~russian //! \~russian
//! //!
//! \}
PRIVATE_DEFINITION_START(PIProcess) PRIVATE_DEFINITION_START(PIProcess)

View File

@@ -2,7 +2,7 @@
* \ingroup System * \ingroup System
* \~\brief * \~\brief
* \~english External process * \~english External process
* \~russian Внешний процесс * \~russian Внешний процесс
*/ */
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
@@ -32,6 +32,10 @@
#include "pifile.h" #include "pifile.h"
//! \ingroup System
//! \~\brief
//! \~english External process.
//! \~russian Внешний процесс.
class PIP_EXPORT PIProcess: public PIThread class PIP_EXPORT PIProcess: public PIThread
{ {
PIOBJECT_SUBCLASS(PIProcess, PIThread) PIOBJECT_SUBCLASS(PIProcess, PIThread)

View File

@@ -20,6 +20,46 @@
#include "pisingleapplication.h" #include "pisingleapplication.h"
#include "pisharedmemory.h" #include "pisharedmemory.h"
//! \class PISingleApplication pisingleapplication.h
//! \~\details
//! \~english
//!
//!
//! \~russian
//! Этот класс позволяет отслеживать повторный запуск приложения
//! и передавать сообщение первому запущеному.
//!
//! Видят друг друга %PISingleApplication с одинаковыми "app_name",
//! задаваемым в конструкторе.
//!
//! Если проверка \a isFirst() успешна, значит этот экземпляр
//! запущен первым, и можно соединиться к событию \a messageReceived().
//!
//! Если проверка провалена, значит этот экземпляр не первый,
//! и можно послать ему сообщение с помощью \a sendMessage(),
//! а затем выйти.
//!
//! \~\code
//! int main(int argc, char * argv[]) {
//! PISingleApplication sapp("myapp");
//! if (sapp.isFirst()) {
//! piCout << "I`m first, wait for another";
//! CONNECTL(&sapp, messageReceived, [](PIByteArray msg){
//! piCout << "Msg from another:" << PIString(msg);
//! });
//! } else {
//! piCout << "I`m not first, send and exit";
//! sapp.sendMessage(PIString("Hello!").toByteArray());
//! return 0;
//! }
//! WAIT_FOREVER
//! return 0;
//! }
//! \endcode
//!
#define SHM_SIZE 1024*32 #define SHM_SIZE 1024*32
@@ -49,10 +89,10 @@ bool PISingleApplication::isFirst() const {
void PISingleApplication::sendMessage(const PIByteArray & m) { void PISingleApplication::sendMessage(const PIByteArray & m) {
waitFirst(); waitFirst();
PIByteArray ba; PIByteArray ba;
int lm[2] = {0, 0}; int lm[3] = {0, 0, 0};
for (;;) { for (;;) {
shm->read(lm, 8); shm->read(lm, 12);
if (lm[1] == 0) break; if (lm[2] == 0) break;
piMSleep(10); piMSleep(10);
} }
ba << sacnt << sacnt << int(1) << m; ba << sacnt << sacnt << int(1) << m;
@@ -85,10 +125,12 @@ void PISingleApplication::run() {
int st_[2] = {sacnt, sacnt}; int st_[2] = {sacnt, sacnt};
shm->write(st_, 8); shm->write(st_, 8);
//piCoutObj << "write" << sacnt; //piCoutObj << "write" << sacnt;
readed = shm->readAll(); int ri[3] = {0, 0, 0};
int t1(0), t2(0), nm(0); const int hdr_sz = sizeof(int) * 3;
readed >> t1 >> t2 >> nm; shm->read(ri, hdr_sz);
if (nm != 0 && t1 == t2) { if (ri[2] != 0 && ri[0] == ri[1]) {
readed.resize(shm->size() - hdr_sz);
shm->read(readed.data(), readed.size(), hdr_sz);
PIByteArray msg; PIByteArray msg;
readed >> msg; readed >> msg;
if (!msg.isEmpty()) { if (!msg.isEmpty()) {

View File

@@ -1,3 +1,9 @@
/*! \file pisingleapplication.h
* \ingroup System
* \~\brief
* \~english Single-instance application control
* \~russian Контроль одного экземпляра приложения
*/
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Single application Single application
@@ -24,16 +30,46 @@
class PISharedMemory; class PISharedMemory;
//! \ingroup System
//! \~\brief
//! \~english Single-instance application control.
//! \~russian Контроль одного экземпляра приложения.
class PIP_EXPORT PISingleApplication: public PIThread { class PIP_EXPORT PISingleApplication: public PIThread {
PIOBJECT_SUBCLASS(PISingleApplication, PIThread) PIOBJECT_SUBCLASS(PISingleApplication, PIThread)
public: public:
//! \~english Construct %PISingleApplication with name "app_name"
//! \~russian Создает %PISingleApplication с именем "app_name"
PISingleApplication(const PIString & app_name = PIString()); PISingleApplication(const PIString & app_name = PIString());
~PISingleApplication(); ~PISingleApplication();
//! \~english Returns if this application instance is launched first
//! \~russian Возвращает первым ли был запущен этот экземпляр приложения
bool isFirst() const; bool isFirst() const;
EVENT_HANDLER1(void, sendMessage, const PIByteArray &, m); EVENT_HANDLER1(void, sendMessage, const PIByteArray &, m);
EVENT1(messageReceived, const PIByteArray &, m) EVENT1(messageReceived, PIByteArray, m)
//! \handlers
//! \{
//! \fn void sendMessage(const PIByteArray & m)
//! \brief
//! \~english Send message "m" to first launched application
//! \~russian Посылает сообщение "m" первому запущеному приложению
//! \}
//! \events
//! \{
//! \fn void messageReceived(PIByteArray m)
//! \brief
//! \~english Raise on first launched application receive message from another
//! \~russian Вызывается первым запущеным приложением по приему сообщения от других
//! \}
private: private:
void begin(); void begin();

View File

@@ -30,17 +30,6 @@
#define SALT_SIZE 8 #define SALT_SIZE 8
PISystemInfo::MountInfo::MountInfo() {
space_all = space_used = space_free = 0;
removable = false;
}
PISystemInfo::PISystemInfo() {
processorsCount = 1;
}
PISystemInfo * PISystemInfo::instance() { PISystemInfo * PISystemInfo::instance() {

View File

@@ -1,8 +1,8 @@
/*! \file pisysteminfo.h /*! \file pisysteminfo.h
* \ingroup System * \ingroup System
* \~\brief * \~\brief
* \~english System information * \~english System information
* \~russian Информация о системе * \~russian Информация о системе
*/ */
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
@@ -28,35 +28,121 @@
#include "pitime.h" #include "pitime.h"
//! \ingroup System
//! \~\brief
//! \~english Information about system.
//! \~russian Информация о системе.
class PIP_EXPORT PISystemInfo { class PIP_EXPORT PISystemInfo {
public: public:
PISystemInfo();
//! \ingroup System
//! \~\brief
//! \~english Mount point information.
//! \~russian Информация о точке монтирования.
struct PIP_EXPORT MountInfo { struct PIP_EXPORT MountInfo {
MountInfo();
//! \~english Absolute path to mount point
//! \~russian Абсолютный путь к точке монтирования
PIString mount_point; PIString mount_point;
//! \~english Device description
//! \~russian Описание устройства
PIString device; PIString device;
//! \~english Filesystem name
//! \~russian Имя файловой системы
PIString filesystem; PIString filesystem;
//! \~english Mount point label
//! \~russian Метка точки монтирования
PIString label; PIString label;
ullong space_all;
ullong space_used; //! \~english Total space in bytes
ullong space_free; //! \~russian Полный объем в байтах
bool removable; ullong space_all = 0;
//! \~english Used space in bytes
//! \~russian Занятый объем в байтах
ullong space_used = 0;
//! \~english Free space in bytes
//! \~russian Свободный объем в байтах
ullong space_free = 0;
//! \~english Is this device is removable
//! \~russian Является ли устройство съёмным
bool removable = false;
}; };
PIString ifconfigPath, execCommand, hostname, user, OS_name, OS_version, architecture; //! \~english Absolute path to "ifconfig" utility
//! \~russian Абсолютный путь к утилите "ifconfig"
PIString ifconfigPath;
//! \~english Application execution path (\c argv[0])
//! \~russian Путь вызова приложения (\c argv[0])
PIString execCommand;
//! \~english System hostname
//! \~russian Hostname системы
PIString hostname;
//! \~english Username that starts application
//! \~russian Имя пользователя, запустившего приложение
PIString user;
//! \~english System name (Windows, MacOS, ...)
//! \~russian Имя системы (Windows, MacOS, ...)
PIString OS_name;
//! \~english System version
//! \~russian Версия системы
PIString OS_version;
//! \~english System architecture (x86, x86_64, ...)
//! \~russian Архитектура системы (x86, x86_64, ...)
PIString architecture;
//! \~english Application start date and time
//! \~russian Дата и время запуска приложения
PIDateTime execDateTime; PIDateTime execDateTime;
int processorsCount;
//! \~english System logical processors count
//! \~russian Количество логических процессоров системы
int processorsCount = 1;
//! \~english Returns all mount points absolute pathes
//! \~russian Возвращает абсолютные пути всех точек монтирования
static PIStringList mountRoots(); static PIStringList mountRoots();
//! \~english Returns information of all mount points
//! \~russian Возвращает информацию о всех точках монтирования
static PIVector<MountInfo> mountInfo(bool ignore_cache = false); static PIVector<MountInfo> mountInfo(bool ignore_cache = false);
//! \~english Returns system unique key
//! \~russian Возвращает уникальный ключ системы
static PIString machineKey(); static PIString machineKey();
//! \~english Returns system unique key hash
//! \~russian Возвращает хэш уникального ключа системы
static uint machineID(); static uint machineID();
//! \~english Returns singleton of %PISystemInfo
//! \~russian Возвращает синглтон %PISystemInfo
static PISystemInfo * instance(); static PISystemInfo * instance();
private:
PISystemInfo() {}
NO_COPY_CLASS(PISystemInfo)
}; };
//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
inline PICout operator <<(PICout s, const PISystemInfo::MountInfo & v) { inline PICout operator <<(PICout s, const PISystemInfo::MountInfo & v) {
s.setControl(0, true); s.setControl(0, true);
s << "MountInfo(" << v.device << " mounted on \"" << v.mount_point << "\", type " << v.filesystem s << "MountInfo(" << v.device << " mounted on \"" << v.mount_point << "\", type " << v.filesystem

View File

@@ -37,13 +37,6 @@
#endif #endif
PISystemMonitor::ProcessStatsFixed::ProcessStatsFixed() {
ID = parent_ID = group_ID = session_ID = priority = threads = 0;
physical_memsize = resident_memsize = share_memsize = virtual_memsize = data_memsize = 0;
cpu_load_user = cpu_load_system = 0.f;
}
void PISystemMonitor::ProcessStats::makeStrings() { void PISystemMonitor::ProcessStats::makeStrings() {
physical_memsize_readable.setReadableSize(physical_memsize); physical_memsize_readable.setReadableSize(physical_memsize);
resident_memsize_readable.setReadableSize(resident_memsize); resident_memsize_readable.setReadableSize(resident_memsize);
@@ -53,12 +46,6 @@ void PISystemMonitor::ProcessStats::makeStrings() {
} }
PISystemMonitor::ThreadStatsFixed::ThreadStatsFixed() {
id = 0;
cpu_load_kernel = cpu_load_user = -1.f;
}
#ifndef MICRO_PIP #ifndef MICRO_PIP
PRIVATE_DEFINITION_START(PISystemMonitor) PRIVATE_DEFINITION_START(PISystemMonitor)
#ifndef WINDOWS #ifndef WINDOWS

View File

@@ -29,75 +29,220 @@
#include "pithread.h" #include "pithread.h"
#include "pifile.h" #include "pifile.h"
class PIP_EXPORT PISystemMonitor: public PIThread
{ //! \ingroup System
//! \~\brief
//! \~english Process monitoring.
//! \~russian Мониторинг процесса.
class PIP_EXPORT PISystemMonitor: public PIThread {
PIOBJECT_SUBCLASS(PISystemMonitor, PIThread) PIOBJECT_SUBCLASS(PISystemMonitor, PIThread)
friend class PIIntrospectionServer; friend class PIIntrospectionServer;
public: public:
//! \~english Constructs unassigned %PISystemMonitor
//! \~russian Создает непривязанный %PISystemMonitor
PISystemMonitor(); PISystemMonitor();
~PISystemMonitor(); ~PISystemMonitor();
#pragma pack(push, 1) #pragma pack(push, 1)
//! \ingroup System
//! \~\brief
//! \~english Process statistics (fixed-size fields).
//! \~russian Статистика процесса (фиксированные поля).
struct PIP_EXPORT ProcessStatsFixed { struct PIP_EXPORT ProcessStatsFixed {
ProcessStatsFixed();
int ID; //! \~english PID
int parent_ID; //! \~russian PID
int group_ID; int ID = 0;
int session_ID;
int priority; //! \~english Parent PID
int threads; //! \~russian PID родителя
ullong physical_memsize; int parent_ID = 0;
ullong resident_memsize;
ullong share_memsize; //! \~english Group ID
ullong virtual_memsize; //! \~russian ID группы
ullong data_memsize; int group_ID = 0;
ullong ram_total;
ullong ram_free; //! \~english Session ID
ullong ram_used; //! \~russian ID сессии
float cpu_load_system; int session_ID = 0;
float cpu_load_user;
//! \~english Priority
//! \~russian Приоритет
int priority = 0;
//! \~english Threads count
//! \~russian Количество потоков
int threads = 0;
//! \~english Physical memory in bytes
//! \~russian Физическая память в байтах
ullong physical_memsize = 0;
//! \~english Resident memory in bytes
//! \~russian Резидентная память в байтах
ullong resident_memsize = 0;
//! \~english Share memory in bytes
//! \~russian Разделяемая память в байтах
ullong share_memsize = 0;
//! \~english Virtual memory in bytes
//! \~russian Виртуальная память в байтах
ullong virtual_memsize = 0;
//! \~english Data memory in bytes
//! \~russian Память данных в байтах
ullong data_memsize = 0;
//! \~english
//! \~russian
ullong ram_total = 0;
//! \~english
//! \~russian
ullong ram_free = 0;
//! \~english
//! \~russian
ullong ram_used = 0;
//! \~english CPU load in kernel space
//! \~russian Загрузка CPU в пространстве ядра
float cpu_load_system = 0.f;
//! \~english CPU load in user space
//! \~russian Загрузка CPU в пространстве пользователя
float cpu_load_user = 0.f;
}; };
//! \ingroup System
//! \~\brief
//! \~english Thread statistics (fixed-size fields).
//! \~russian Статистика потока (фиксированные поля).
struct PIP_EXPORT ThreadStatsFixed { struct PIP_EXPORT ThreadStatsFixed {
ThreadStatsFixed();
llong id; //! \~english TID
//! \~russian TID
llong id = 0;
//! \~english Overall live time
//! \~russian Полное время жизни
PISystemTime work_time; PISystemTime work_time;
//! \~english Busy time in kernel space
//! \~russian Время работы в пространстве ядра
PISystemTime kernel_time; PISystemTime kernel_time;
//! \~english Busy time in user space
//! \~russian Время работы в пространстве пользователя
PISystemTime user_time; PISystemTime user_time;
float cpu_load_kernel;
float cpu_load_user; //! \~english CPU load in kernel space
//! \~russian Загрузка CPU в пространстве ядра
float cpu_load_kernel = -1.f;
//! \~english CPU load in user space
//! \~russian Загрузка CPU в пространстве пользователя
float cpu_load_user = -1.f;
//! \~english Date and time of creation
//! \~russian Дата и время создания
PIDateTime created; PIDateTime created;
}; };
#pragma pack(pop) #pragma pack(pop)
//! \ingroup System
//! \~\brief
//! \~english Process statistics.
//! \~russian Статистика процесса.
struct PIP_EXPORT ProcessStats: ProcessStatsFixed { struct PIP_EXPORT ProcessStats: ProcessStatsFixed {
//! \~english Fill human-readable fields
//! \~russian Заполнить читаемые поля
void makeStrings(); void makeStrings();
//! \~english Execution command
//! \~russian Команда запуска
PIString exec_name; PIString exec_name;
//! \~english State
//! \~russian Состояние
PIString state; PIString state;
//! \~english Human-readable physical memory
//! \~russian Физическая память в читаемом виде
PIString physical_memsize_readable; PIString physical_memsize_readable;
//! \~english Human-readable resident memory
//! \~russian Резидентная память в читаемом виде
PIString resident_memsize_readable; PIString resident_memsize_readable;
//! \~english Human-readable share memory
//! \~russian Разделяемая память в читаемом виде
PIString share_memsize_readable; PIString share_memsize_readable;
//! \~english Human-readable virtual memory
//! \~russian Виртуальная память в читаемом виде
PIString virtual_memsize_readable; PIString virtual_memsize_readable;
//! \~english Human-readable data memory
//! \~russian Память данных в читаемом виде
PIString data_memsize_readable; PIString data_memsize_readable;
}; };
//! \ingroup System
//! \~\brief
//! \~english Thread statistics.
//! \~russian Статистика потока.
struct PIP_EXPORT ThreadStats: ThreadStatsFixed { struct PIP_EXPORT ThreadStats: ThreadStatsFixed {
//! \~english Name
//! \~russian Имя
PIString name; PIString name;
}; };
#ifndef MICRO_PIP #ifndef MICRO_PIP
//! \~english Starts monitoring of process with PID "pID" and update interval "interval_ms" milliseconds
//! \~russian Начинает мониторинг процесса с PID "pID" и интервалом обновления "interval_ms" миллисекунд
bool startOnProcess(int pID, int interval_ms = 1000); bool startOnProcess(int pID, int interval_ms = 1000);
#endif #endif
//! \~english Starts monitoring of application process with update interval "interval_ms" milliseconds
//! \~russian Начинает мониторинг процесса приложения с интервалом обновления "interval_ms" миллисекунд
bool startOnSelf(int interval_ms = 1000); bool startOnSelf(int interval_ms = 1000);
//! \~english Stop monitoring
//! \~russian Останавливает мониторинг
void stop(); void stop();
//! \~english Returns monitoring process PID
//! \~russian Возвращает PID наблюдаемого процесса
int pID() const {return pID_;} int pID() const {return pID_;}
//! \~english Returns monitoring process statistics
//! \~russian Возвращает статистику наблюдаемого процесса
ProcessStats statistic() const; ProcessStats statistic() const;
//! \~english Returns monitoring process threads statistics
//! \~russian Возвращает статистику потоков наблюдаемого процесса
PIVector<ThreadStats> threadsStatistic() const; PIVector<ThreadStats> threadsStatistic() const;
void setStatistic(const ProcessStats & s); void setStatistic(const ProcessStats & s);
//! \~english
//! \~russian
static ullong totalRAM(); static ullong totalRAM();
//! \~english
//! \~russian
static ullong freeRAM(); static ullong freeRAM();
//! \~english
//! \~russian
static ullong usedRAM(); static ullong usedRAM();
@@ -131,6 +276,9 @@ private:
}; };
//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
inline PICout operator <<(PICout s, const PISystemMonitor::ThreadStats & v) { inline PICout operator <<(PICout s, const PISystemMonitor::ThreadStats & v) {
s.setControl(0, true); s.setControl(0, true);
s << "ThreadInfo(\"" << v.name << "\", created " << v.created s << "ThreadInfo(\"" << v.name << "\", created " << v.created
@@ -142,9 +290,25 @@ inline PICout operator <<(PICout s, const PISystemMonitor::ThreadStats & v) {
return s; return s;
} }
//! \relatesalso PIByteArray
//! \~english Store operator
//! \~russian Оператор сохранения
PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PISystemMonitor::ProcessStats & v); PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PISystemMonitor::ProcessStats & v);
//! \relatesalso PIByteArray
//! \~english Restore operator
//! \~russian Оператор извлечения
PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PISystemMonitor::ProcessStats & v); PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PISystemMonitor::ProcessStats & v);
//! \relatesalso PIByteArray
//! \~english Store operator
//! \~russian Оператор сохранения
PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PISystemMonitor::ThreadStats & v); PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PISystemMonitor::ThreadStats & v);
//! \relatesalso PIByteArray
//! \~english Restore operator
//! \~russian Оператор извлечения
PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PISystemMonitor::ThreadStats & v); PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PISystemMonitor::ThreadStats & v);
#endif // PISYSTEMMONITOR_H #endif // PISYSTEMMONITOR_H

410
main.cpp
View File

@@ -1,235 +1,241 @@
#include "pip.h" #include "pip.h"
static const char * smallstr = "abcdef";
static const char * bigstr = "zsxdcgfhvbncjdbasljcvavcjadnwnxudvbabdhjlavudvdaljsvclavjlasdhvcjhldsavhjldasvfjlhsavdjhavdjhvfjhldasvfjlasvfhjldasvfhjasvfdjdasfhvjldasvhfjlasvfhjlahsvdfhjfvfvdjalsvfjlhasdvfdjsalvfhhjldasvfdjhaldsvfhjdvsfjhlavfjhlavfladlsvfjlasdvfdhjlavfhjldasvfhjlavfhjldvfhjlalsdvfjlhvasfhjlvchjlavchjladvchjldladvschjlladscvjlhdcahjchjllcahjllvcdjladsvhldbcljadsbcjdhlsachjlvdsa hjlcldajc hljdascbhaldb cldhashd l cajlhs chdsbfhlbfdasdffadsfjkbfkjldsabflhbcldhsbhclabchljadsbchldahsbcladsbhclhabhasbclasbdhl";
PIKbdListener kbd(0, 0, false);
#include <iostream>
#include <codecvt>
using namespace PICoutManipulators;
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
/*PIVariant vi; const int repeat = 1000;
piCout << vi; const int no_repeat = 1;
vi = 1; const int small_cnt = 1000;
piCout << vi << vi.toString(); const int big_cnt = 100000;
vi = "string";
piCout << vi << vi.toStringList();
vi = PIStringList("2");
piCout << vi << vi.toInt();*/
/*auto cmp = [](const PIConstChars & c0, const PIConstChars & c1){
PICout(DefaultControls) << c0 << "==" << c1 << "->" << (c0 != c1);
};
PIConstChars s;
PICout(DefaultControls | AddQuotes) << s;
s = PIConstChars("str", 2);
PICout(DefaultControls | AddQuotes) << s;
cmp(PIConstChars(), PIConstChars());
cmp(PIConstChars("str"), PIConstChars());
cmp(PIConstChars(), PIConstChars("s_tr"));
cmp(PIConstChars("str1"), PIConstChars("str"));
cmp(PIConstChars("str"), PIConstChars("str2"));
cmp(PIConstChars("str"), PIConstChars("sTr"));
cmp(PIConstChars("str"), PIConstChars("str"));
cmp(PIConstChars("1a"), PIConstChars("1b"));
cmp(PIConstChars("1c"), PIConstChars("1b"));*/
/*PIMap<PIConstChars, int> map;
map[PIConstChars()] = 0;
map[PIConstChars()] = -1;
map["_2"] = 22;
map["1"] = 11;
map["__3"] = 33;
map["10"] = 10;
map[""] = 999;
piCout << map;
piCout << PIConstChars().toString();
piCout << PIConstChars("").toString();
piCout << PIConstChars("str").toString();
PIConstChars s = " 1 2 \t";
piCout << "trim:";
PICout(DefaultControls | AddQuotes) << s.trimmed();
PICout(DefaultControls | AddQuotes) << s;
PICout(DefaultControls | AddQuotes) << s.isEmpty();*/
/*piCout << PIIODevice::availablePrefixes();
auto * d = PIIODevice::createFromFullPath("ser://COM1");
piCout << "";
piCout << d;
d->dump();
d = PIIODevice::createFromFullPath("eth://udp:127.0.0.1:5000");
piCout << "";
piCout << d;
d->dump();*/
piCout << "";
dumpApplication();
return 0;
auto rstr = PIString::fromUTF8("ascii русский!");
/*for (PIChar c: rstr)
std::wcout << c.toWChar();
std::wcout << std::endl;*/
piCout << PIChar::fromUTF8("");
piCout << PICoutManipulators::Hex << (int)PIChar::fromUTF8("").toWChar();
piCout << rstr;
/*char rs[] = "й";
piCout << PIString(PIChar::fromUTF8(rs));
std::cout << sizeof(rs) << " chars ";
for (int i = 0; i < sizeof(rs); ++i)
std::cout << "'" << (char)(rs[i]) << "' " << (int)(uchar)(rs[i]);
std::cout << std::endl;
CONNECTL(&kbd, keyPressed, ([](PIKbdListener::KeyEvent k, void*){
;
piCout << k.key << PIChar((ushort)k.key);
}));
kbd.start();
WAIT_FOR_EXIT;*/
//return 0;
static const int cc = 1000000;
PITimeMeasurer tm; PITimeMeasurer tm;
int l = 0;
tm.reset();
for(int i=0; i<cc; ++i) {
PIString s(smallstr);
l = s.size();
}
piCout << l << "PIString()" << tm.elapsed_m();
tm.reset();
for(int i=0; i<cc; ++i) {
PIString s = smallstr;
l = s.size();
}
piCout << l << "PIString =" << tm.elapsed_m();
tm.reset();
for(int i=0; i<cc; ++i) {
PIString s = PIStringAscii(smallstr);
l = s.size();
}
piCout << l << "PIStringAscii" << tm.elapsed_m();
tm.reset();
for(int i=0; i<cc; ++i) {
PIString s;
s += smallstr;
s += "1";
l = s.size();
}
piCout << l << "PIString + PIString" << tm.elapsed_m();
tm.reset();
for(int i=0; i<cc; ++i) {
PIString s = PIStringAscii(smallstr) + "1";
l = s.size();
}
piCout << l << "PIStringAscii + PIString" << tm.elapsed_m();
tm.reset();
for(int i=0; i<cc; ++i) {
PIString s = PIString::fromUTF8(smallstr);
l = s.size();
}
piCout << l << "PIString::fromUTF8" << tm.elapsed_m();
tm.reset();
for(int i=0; i<cc; ++i) {
PIString s = PIString::fromSystem(smallstr);
l = s.size();
}
piCout << l << "PIString::fromSystem" << tm.elapsed_m();
tm.reset();
for(int i=0; i<cc; ++i) {
PIString s = PIString::fromAscii(smallstr);
l = s.size();
}
piCout << l << "PIString::fromAscii" << tm.elapsed_m();
tm.reset();
for(int i=0; i<cc; ++i) { PIStringList small_sl;
PIString s(bigstr); PIStringList big_sl;
l = s.size(); // {
// for (int i=0; i<small_cnt; ++i) small_sl << PIString::fromNumber(randomi())+PIString::fromNumber(i);
// for (int i=0; i<big_cnt; ++i) big_sl << PIString::fromNumber(randomi())+PIString::fromNumber(i);
// PIFile f;
// f.open("test.bin", PIIODevice::WriteOnly);
// PIByteArray slba;
// slba << small_sl;
// slba << big_sl;
// f.write(slba);
// f.close();
// return 0;
// }
{
PIFile f;
f.open("test.bin", PIIODevice::ReadOnly);
PIByteArray slba = f.readAll();
slba >> small_sl;
slba >> big_sl;
f.close();
} }
piCout << l << "PIString()" << tm.elapsed_m();
piCout << "map<int, int> insert...";
tm.reset(); tm.reset();
for(int i=0; i<cc; ++i) { for (int c=0; c<repeat; ++c) {
PIString s = bigstr; PIMap<int64_t, int64_t> m1;
l = s.size(); for (int i=0; i<small_cnt; ++i) {
m1.insert(i, i);
}
} }
piCout << l << "PIString =" << tm.elapsed_m(); piCout << "map<int, int> insert" << tm.elapsed_m();
piCout << "map<int, int> insert []...";
tm.reset(); tm.reset();
for(int i=0; i<cc; ++i) { for (int c=0; c<repeat; ++c) {
PIString s = PIStringAscii(bigstr); PIMap<int64_t, int64_t> m1;
l = s.size(); for (int i=0; i<small_cnt; ++i) {
m1[i] = i;
}
} }
piCout << l << "PIStringAscii" << tm.elapsed_m(); piCout << "map<int, int> insert []" << tm.elapsed_m();
piCout << "map<int, int> insert rnd...";
tm.reset(); tm.reset();
for(int i=0; i<cc; ++i) { for (int c=0; c<repeat; ++c) {
PIString s; PIMap<int64_t, int64_t> m1;
s += bigstr; for (int i=0; i<small_cnt; ++i) {
s += "1"; m1.insert(randomi(), i);
l = s.size(); }
} }
piCout << l << "PIString + PIString" << tm.elapsed_m(); piCout << "map<int, int> insert rnd" << tm.elapsed_m();
piCout << "map<int, int> insert rnd []...";
tm.reset(); tm.reset();
for(int i=0; i<cc; ++i) { for (int c=0; c<repeat; ++c) {
PIString s = PIStringAscii(bigstr) + "1"; PIMap<int64_t, int64_t> m1;
l = s.size(); for (int i=0; i<small_cnt; ++i) {
m1[randomi()] = i;
}
} }
piCout << l << "PIStringAscii + PIString" << tm.elapsed_m(); piCout << "map<int, int> insert rnd []" << tm.elapsed_m();
piCout << "bigmap<int, int> insert...";
tm.reset(); tm.reset();
for(int i=0; i<cc; ++i) { for (int c=0; c<no_repeat; ++c) {
PIString s = PIString::fromUTF8(bigstr); PIMap<int64_t, int64_t> m1;
l = s.size(); for (int i=0; i<big_cnt; ++i) {
m1.insert(i, i);
}
} }
piCout << l << "PIString::fromUTF8" << tm.elapsed_m(); piCout << "bigmap<int, int> insert" << tm.elapsed_m();
piCout << "bigmap<int, int> insert []...";
tm.reset(); tm.reset();
for(int i=0; i<cc; ++i) { for (int c=0; c<no_repeat; ++c) {
PIString s = PIString::fromSystem(bigstr); PIMap<int64_t, int64_t> m1;
l = s.size(); for (int i=0; i<big_cnt; ++i) {
m1[i] = i;
}
} }
piCout << l << "PIString::fromSystem" << tm.elapsed_m(); piCout << "bigmap<int, int> insert []" << tm.elapsed_m();
piCout << "bigmap<int, int> insert rnd...";
tm.reset(); tm.reset();
for(int i=0; i<cc; ++i) { for (int c=0; c<no_repeat; ++c) {
PIString s = PIString::fromAscii(bigstr); PIMap<int64_t, int64_t> m1;
l = s.size(); for (int i=0; i<big_cnt; ++i) {
m1.insert(randomi(), i);
}
} }
piCout << l << "PIString::fromAscii" << tm.elapsed_m(); piCout << "bigmap<int, int> insert rnd" << tm.elapsed_m();
PIString is = PIString::fromAscii(bigstr); piCout << "bigmap<int, int> insert rnd []...";
tm.reset(); tm.reset();
for(int i=0; i<cc; ++i) { for (int c=0; c<no_repeat; ++c) {
l = is.toByteArray().size(); PIMap<int64_t, int64_t> m1;
for (int i=0; i<big_cnt; ++i) {
m1[randomi()] = i;
}
} }
piCout << l << "PIString::toByteArray" << tm.elapsed_m(); piCout << "bigmap<int, int> insert rnd []" << tm.elapsed_m();
PIByteArray ba = is.toByteArray();
piCout << "map<PIString, int> insert...";
tm.reset(); tm.reset();
for(int i=0; i<cc; ++i) { for (int c=0; c<repeat; ++c) {
PIString s = PIString::fromUTF8(ba); PIMap<PIString, int> m1;
l = s.size(); for (int i=0; i<small_cnt; ++i) {
m1.insert(small_sl[i], i);
}
} }
piCout << l << "PIString::fromByteArray" << tm.elapsed_m(); piCout << "map<PIString, int> insert" << tm.elapsed_m();
piCout << "map<PIString, int> insert []...";
tm.reset(); tm.reset();
for(int i=0; i<cc; ++i) { for (int c=0; c<repeat; ++c) {
PIString s = PIString::fromNumber(ba.size()); PIMap<PIString, int> m1;
l = s.size(); for (int i=0; i<small_cnt; ++i) {
m1[small_sl[i]] = i;
}
} }
piCout << l << "PIString::fromNumber" << tm.elapsed_m(); piCout << "map<PIString, int> insert []" << tm.elapsed_m();
piCout << "bigmap<PIString, int> insert...";
tm.reset(); tm.reset();
for(int i=0; i<cc; ++i) { for (int c=0; c<no_repeat; ++c) {
PIString s = is; PIMap<PIString, int> m1;
l = s.size(); for (int i=0; i<big_cnt; ++i) {
m1.insert(big_sl[i], i);
}
} }
piCout << l << "PIString::assign empty" << tm.elapsed_m(); piCout << "bigmap<PIString, int> insert" << tm.elapsed_m();
PIString is2 = PIString::fromUTF8(ba); piCout << "bigmap<PIString, int> insert []...";
tm.reset(); tm.reset();
for(int i=0; i<cc; ++i) { for (int c=0; c<no_repeat; ++c) {
PIString s = is; PIMap<PIString, int> m1;
l = s.size(); for (int i=0; i<big_cnt; ++i) {
s = is2; m1[big_sl[i]] = i;
l += s.size(); }
} }
piCout << l << "PIString::assign non empty" << tm.elapsed_m(); piCout << "bigmap<PIString, int> insert []" << tm.elapsed_m();
PIMap<int, int> m1;
for (int i=0; i<big_cnt; ++i) m1.insert(i,i);
piCout << "map<int, int> interate...";
tm.reset();
for (int c=0; c<repeat; ++c) {
PIVector<int> v;
v.reserve(m1.size());
auto it = m1.makeIterator();
while (it.next()) v << it.value();
}
piCout << "map<int, int> interate" << tm.elapsed_m();
PIMap<PIString, int> m2;
for (int i=0; i<big_cnt; ++i) {
m2.insert(big_sl[i], i);
}
piCout << "map<PIString, int> interate...";
tm.reset();
for (int c=0; c<repeat; ++c) {
PIVector<int> v;
v.reserve(m2.size());
auto it = m2.makeIterator();
while (it.next()) v << it.value();
}
piCout << "map<PIString, int> interate" << tm.elapsed_m();
PIByteArray ba;
ba.resize(64*1024);
piCout << "map<int, PIByteArray> insert...";
PIMap<int, PIByteArray> m3;
m3.reserve(big_cnt);
tm.reset();
for (int i=0; i<big_cnt; ++i) m3.insert(i, ba);
piCout << "map<int, PIByteArray> insert" << tm.elapsed_m();
piCout << "map<int, PIByteArray> interate...";
tm.reset();
for (int c=0; c<repeat; ++c) {
PIVector<int> v;
v.reserve(m3.size());
auto it = m3.makeIterator();
while (it.next()) v << it.value().size();
}
piCout << "map<int, PIByteArray> interate" << tm.elapsed_m();
piCout << "map<PIString, PIByteArray> insert...";
PIMap<PIString, PIByteArray> m4;
m4.reserve(big_cnt);
tm.reset();
for (int i=0; i<big_cnt; ++i) {
m4.insert(big_sl[i], ba);
}
piCout << "map<PIString, PIByteArray> insert" << tm.elapsed_m();
piCout << "map<PIString, PIByteArray> interate...";
tm.reset();
for (int c=0; c<repeat; ++c) {
PIVector<int> v;
v.reserve(m4.size());
auto it = m4.makeIterator();
while (it.next()) v << it.value().size();
}
piCout << "map<PIString, PIByteArray> interate" << tm.elapsed_m();
piCout << "map<int, int> cointains...";
tm.reset();
for (int c=0; c<big_cnt; ++c) {
m1.contains(1023);
}
piCout << "map<int, int> contains" << tm.elapsed_m();
piCout << "map<int, int> cointains miss...";
tm.reset();
for (int c=0; c<big_cnt; ++c) {
m1.contains(-1);
}
piCout << "map<int, int> contains miss" << tm.elapsed_m();
piCout << "map<PIString, int> cointains...";
tm.reset();
for (int c=0; c<big_cnt; ++c) {
m2.contains(big_sl[1023]);
}
piCout << "map<PIString, int> contains" << tm.elapsed_m();
piCout << "map<PIString, int> cointains miss...";
PIString s = "dfcdsfas";
tm.reset();
for (int c=0; c<big_cnt; ++c) {
m2.contains(s);
}
piCout << "map<PIString, int> contains miss" << tm.elapsed_m();
return 0; return 0;
} }

View File

@@ -20,7 +20,7 @@ endif()
if (NOT DEFINED ANDROID_PLATFORM) if (NOT DEFINED ANDROID_PLATFORM)
deploy_target(${PROJECT_NAME} deploy_target(${PROJECT_NAME}
DEPLOY_DIR ${CMAKE_CURRENT_BINARY_DIR} DEPLOY_DIR ${CMAKE_CURRENT_BINARY_DIR}
DESTINATION ${ROOT_DIR}/release DESTINATION "${ROOT_DIR}/release"
DEB_ADD_SERVICE DEB_ADD_SERVICE
ADD_MANIFEST ADD_MANIFEST
) )

View File

@@ -419,18 +419,22 @@ void makeGetterValue(PIFile & f, const PICodeParser::Entity * e) {
} }
void writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool meta, bool enums, bool streams, bool texts, bool getters) { void writeModel(PICodeParser & parser, PICLI & cli, const PIString out, const PIStringList & files, bool meta, bool enums, bool streams, bool texts, bool getters) {
PIString defname = "CCM_" + PIString::fromNumber(out.hash()) + "_H"; PIString defname = "CCM_" + PIString::fromNumber(out.hash()) + "_H";
PISet<PIString> inc_files; PISet<PIString> inc_files;
piForeachC (PICodeParser::Entity * e, parser.entities) piForeachC (PICodeParser::Entity * e, parser.entities)
if (e->name.find("::") < 0 && !e->name.startsWith("_PI")) if (e->name.find("::") < 0 && !e->name.startsWith("_PI"))
inc_files << e->file; inc_files << e->file;
PIString inc_string;
PIVector<PIString> incf = inc_files.toVector(); PIVector<PIString> incf = inc_files.toVector();
for (auto & f: files) incf << f;
PIString inc_string;
piForeachC (PIString & i, incf) { piForeachC (PIString & i, incf) {
if ((i != parser.mainFile()) && (streams || texts || getters)) if ((i != parser.mainFile()) && (streams || texts || getters))
inc_string << "\n#include \"" << i << "\""; inc_string << "\n#include \"" << i << "\"";
} }
//piCout << parser.mainFile() << streams << texts << getters;
//piCout << incf;
//piCout << inc_string;
PIFile f(out + ".cpp"); PIFile f(out + ".cpp");
f.clear(); f.clear();
@@ -562,11 +566,12 @@ int main(int argc, char * argv[]) {
piCout << Cyan << Bold << "Parsing done"; piCout << Cyan << Bold << "Parsing done";
piCout << Cyan << Bold << "Writing code model ..."; piCout << Cyan << Bold << "Writing code model ...";
bool all = cli.hasArgument("All"); bool all = cli.hasArgument("All");
writeModel(parser, cli, cli.argumentValue("output"), cli.hasArgument("Metainfo") || all, writeModel(parser, cli, cli.argumentValue("output"), files,
cli.hasArgument("Enum") || all, cli.hasArgument("Metainfo") || all,
cli.hasArgument("Stream") || all, cli.hasArgument("Enum") || all,
cli.hasArgument("Text") || all, cli.hasArgument("Stream") || all,
cli.hasArgument("Getter") || all); cli.hasArgument("Text") || all,
cli.hasArgument("Getter") || all);
piCout << Cyan << Bold << "Writing done"; piCout << Cyan << Bold << "Writing done";
if (cli.hasArgument("print") || cli.hasArgument("Print")) { if (cli.hasArgument("print") || cli.hasArgument("Print")) {
bool womain = cli.hasArgument("print"); bool womain = cli.hasArgument("print");

View File

@@ -296,7 +296,7 @@ public:
if (e.key == PIKbdListener::Esc) menuRequest(); if (e.key == PIKbdListener::Esc) menuRequest();
//piCout << "key" << e.key; //piCout << "key" << e.key;
} }
EVENT_HANDLER1(void, messageFromApp, const PIByteArray & , m) { EVENT_HANDLER1(void, messageFromApp, PIByteArray, m) {
if (m[0] == 'k') PIKbdListener::exiting = true; if (m[0] == 'k') PIKbdListener::exiting = true;
} }
@@ -318,7 +318,7 @@ void usage() {
piCout << PICoutManipulators::Bold << "PIP System Daemon"; piCout << PICoutManipulators::Bold << "PIP System Daemon";
piCout << PICoutManipulators::Cyan << "Version" << PICoutManipulators::Bold << PIPVersion() << PICoutManipulators::NewLine; piCout << PICoutManipulators::Cyan << "Version" << PICoutManipulators::Bold << PIPVersion() << PICoutManipulators::NewLine;
piCout << PICoutManipulators::Green << PICoutManipulators::Bold << "Usage:" << PICoutManipulators::Default piCout << PICoutManipulators::Green << PICoutManipulators::Bold << "Usage:" << PICoutManipulators::Default
<< "\"pisd [-hdfk] [-n <name>] [-a <ip>]\"" << PICoutManipulators::NewLine; << "\"pisd [-1hdfk] [-n <name>] [-a <ip>]\"" << PICoutManipulators::NewLine;
piCout << PICoutManipulators::Green << PICoutManipulators::Bold << "Details:"; piCout << PICoutManipulators::Green << PICoutManipulators::Bold << "Details:";
piCout << "-h --help " << PICoutManipulators::Green << "- display this message and exit"; piCout << "-h --help " << PICoutManipulators::Green << "- display this message and exit";
piCout << "-d --daemon " << PICoutManipulators::Green << "- start as daemon"; piCout << "-d --daemon " << PICoutManipulators::Green << "- start as daemon";
@@ -332,7 +332,6 @@ void usage() {
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
sys_mon.startOnSelf(); sys_mon.startOnSelf();
PIINTROSPECTION_START(pisd)
//piDebug = false; //piDebug = false;
PICLI cli(argc, argv); PICLI cli(argc, argv);
cli.addArgument("help"); cli.addArgument("help");
@@ -355,14 +354,17 @@ int main(int argc, char * argv[]) {
if (cli.hasArgument("1")) { if (cli.hasArgument("1")) {
if (!sapp->isFirst()) { if (!sapp->isFirst()) {
piCout << "Another pisd is running, exit"; piCout << "Another pisd is running, exit";
delete sapp;
return 0; return 0;
} }
} }
if (cli.hasArgument("kill")) { if (cli.hasArgument("kill")) {
sapp->sendMessage(PIByteArray("k", 1)); sapp->sendMessage(PIByteArray("k", 1));
delete sapp;
return 0; return 0;
} }
} }
PIINTROSPECTION_START(pisd)
if (cli.hasArgument("daemon")) { if (cli.hasArgument("daemon")) {
PIStringList args; PIStringList args;
args << "-1" << "-s"; args << "-1" << "-s";