Compare commits
51 Commits
concurrent
...
4d03ba1210
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d03ba1210 | ||
|
|
defbe3a4d7 | ||
|
|
2913fc284b | ||
|
|
3dd08bf944 | ||
|
|
fcf91a26b6 | ||
| a4b3edb3e1 | |||
| 6be22ac39f | |||
| 37de1ec099 | |||
| 32d060c8ce | |||
| 7065cbd9ee | |||
| c5f70f4e09 | |||
| 234d4e73be | |||
| e1f2c90790 | |||
| 93cf55d323 | |||
| 2ef0ca6946 | |||
| 73bfe03433 | |||
| 2a42d2a341 | |||
| 7f2c82dc69 | |||
| fa0475cac6 | |||
| cfebf8cf23 | |||
| 3965e54e38 | |||
| f033119a8b | |||
| 6b70045914 | |||
| cc580d9385 | |||
| 05607ccf0e | |||
| fec68299c1 | |||
| ccd6a9888f | |||
| c582d8ff46 | |||
| 9834ac177b | |||
| 31f0d88157 | |||
| e76a07a3f3 | |||
| 31a347250f | |||
| 294831df17 | |||
| e77d3a86a9 | |||
| 66010c83eb | |||
| 57a9ccb854 | |||
| 3ba6a7b0e8 | |||
| 8c3349d84a | |||
| dac318c624 | |||
| e08f805525 | |||
| 26742a1fc3 | |||
| 70a7363f76 | |||
| 8405b564a4 | |||
|
|
494b09847e | ||
|
|
f1951ee711 | ||
| c3257c7c50 | |||
|
|
13bafdc7c1 | ||
|
|
f71fbb0068 | ||
|
|
bb635f6c51 | ||
|
|
d8e47afe13 | ||
| dbb84885e3 |
@@ -1,10 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
||||
project(pip)
|
||||
set(_PIP_MAJOR 1)
|
||||
set(_PIP_MINOR 99)
|
||||
set(_PIP_REVISION 3)
|
||||
set(_PIP_SUFFIX _prebeta)
|
||||
set(_PIP_MAJOR 2)
|
||||
set(_PIP_MINOR 5)
|
||||
set(_PIP_REVISION 0)
|
||||
set(_PIP_SUFFIX _beta)
|
||||
set(_PIP_COMPANY SHS)
|
||||
set(_PIP_DOMAIN org.SHS)
|
||||
|
||||
@@ -66,10 +66,10 @@ macro(pip_module NAME LIBS LABEL INCLUDES MSG)
|
||||
set(HS)
|
||||
set(PHS)
|
||||
set(CRES)
|
||||
file(GLOB_RECURSE CPPS "lib/${NAME}/*.cpp")
|
||||
file(GLOB_RECURSE HS "lib/${NAME}/*.h")
|
||||
file(GLOB_RECURSE PHS "lib/${NAME}/*_p.h")
|
||||
file(GLOB_RECURSE RES "lib/${NAME}/*conf.h")
|
||||
file(GLOB_RECURSE CPPS "libs/${NAME}/*.cpp")
|
||||
file(GLOB_RECURSE HS "libs/${NAME}/*.h")
|
||||
file(GLOB_RECURSE PHS "libs/${NAME}/*_p.h")
|
||||
file(GLOB_RECURSE RES "libs/${NAME}/*conf.h")
|
||||
list(REMOVE_ITEM HS "${PHS}")
|
||||
list(APPEND HDRS ${HS})
|
||||
list(APPEND PHDRS ${PHS})
|
||||
@@ -112,8 +112,6 @@ macro(pip_module NAME LIBS LABEL INCLUDES MSG)
|
||||
if (NOT "${INCLUDES}" STREQUAL "")
|
||||
target_include_directories(${_target} PRIVATE ${INCLUDES})
|
||||
endif()
|
||||
generate_export_header(${_target})
|
||||
list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/${_target}_export.h")
|
||||
list(APPEND PIP_EXPORTS "${DEF_NAME}_EXPORT")
|
||||
target_link_libraries(${_target} ${LINK_LIBS})
|
||||
list(APPEND PIP_MODULES ${_target})
|
||||
@@ -210,8 +208,8 @@ get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME)
|
||||
|
||||
|
||||
# Main lib
|
||||
file(GLOB PIP_FOLDERS LIST_DIRECTORIES TRUE "${CMAKE_CURRENT_SOURCE_DIR}/lib/main/*")
|
||||
list(APPEND PIP_FOLDERS "${CMAKE_CURRENT_SOURCE_DIR}/lib/main")
|
||||
file(GLOB PIP_FOLDERS LIST_DIRECTORIES TRUE "${CMAKE_CURRENT_SOURCE_DIR}/libs/main/*")
|
||||
list(APPEND PIP_FOLDERS "${CMAKE_CURRENT_SOURCE_DIR}/libs/main")
|
||||
set(PIP_MAIN_FOLDERS)
|
||||
foreach(F ${PIP_FOLDERS})
|
||||
if (IS_DIRECTORY "${F}")
|
||||
@@ -384,6 +382,15 @@ set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
pip_module(main "${LIBS_MAIN}" "PIP main library" "" "")
|
||||
|
||||
generate_export_header(pip)
|
||||
list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/pip_export.h")
|
||||
foreach(_m ${PIP_SRC_MODULES})
|
||||
set_target_properties(pip PROPERTIES DEFINE_SYMBOL pip_${_m}_EXPORTS)
|
||||
generate_export_header(pip BASE_NAME "pip_${_m}")
|
||||
list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/pip_${_m}_export.h")
|
||||
endforeach()
|
||||
set_target_properties(pip PROPERTIES DEFINE_SYMBOL pip_EXPORTS)
|
||||
|
||||
|
||||
if (NOT CROSSTOOLS)
|
||||
if (NOT PIP_FREERTOS)
|
||||
@@ -462,7 +469,11 @@ if (NOT CROSSTOOLS)
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.7.0")
|
||||
target_link_libraries(_opencl_lib OpenCL)
|
||||
endif()
|
||||
pip_module(opencl "${_opencl_lib}" "PIP OpenCL support" "" " (${OpenCL_VERSION_STRING})")
|
||||
set(_opencl_inc "${OpenCL_INCLUDE_DIRS}")
|
||||
if(APPLE)
|
||||
set(_opencl_inc "${OpenCL_INCLUDE_DIRS}/Headers")
|
||||
endif()
|
||||
pip_module(opencl "${_opencl_lib}" "PIP OpenCL support" "${_opencl_inc}" " (${OpenCL_VERSION_STRING})")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -479,15 +490,15 @@ if (NOT CROSSTOOLS)
|
||||
endif()
|
||||
find_package(Lua QUIET)
|
||||
if (LUA_FOUND)
|
||||
pip_module(lua "LUA" "PIP Lua support" "${LUA_INCLUDE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd" " (${LUA_VERSION_STRING})")
|
||||
list(APPEND HDR_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd/LuaBridge")
|
||||
pip_module(lua "LUA" "PIP Lua support" "${LUA_INCLUDE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libs/lua/3rd" " (${LUA_VERSION_STRING})")
|
||||
list(APPEND HDR_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/libs/lua/3rd/LuaBridge")
|
||||
endif()
|
||||
|
||||
|
||||
# Test program
|
||||
if(PIP_UTILS)
|
||||
add_executable(pip_test "main.cpp")
|
||||
target_link_libraries(pip_test pip)
|
||||
target_link_libraries(pip_test pip pip_cloud)
|
||||
if (LUA_FOUND)
|
||||
target_link_libraries(pip_test pip_lua ${LUA_LIBRARIES})
|
||||
endif()
|
||||
@@ -524,7 +535,6 @@ if(LIB)
|
||||
if(WIN32)
|
||||
if(MINGW)
|
||||
if (NOT CROSSTOOLS)
|
||||
install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip)
|
||||
install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip)
|
||||
if(HDR_DIRS)
|
||||
install(DIRECTORY ${HDR_DIRS} DESTINATION ${MINGW_INCLUDE}/pip)
|
||||
@@ -612,7 +622,7 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
|
||||
set(DOXY_QHP_SECT_FILTER_ATTRS "\"PIP ${PIP_VERSION}\"")
|
||||
set(DOXY_EXAMPLE_PATH "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/examples\"")
|
||||
set(DOXY_IMAGE_PATH "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/images\"")
|
||||
set(DOXY_EXCLUDE "\"${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd\"")
|
||||
set(DOXY_EXCLUDE "\"${CMAKE_CURRENT_SOURCE_DIR}/libs/lua/3rd\"")
|
||||
if(DOXYGEN_DOT_EXECUTABLE)
|
||||
string(REPLACE "\\" "" _DOT_PATH "${DOXYGEN_DOT_PATH}")
|
||||
set(DOXY_DOT_PATH "\"${_DOT_PATH}\"")
|
||||
@@ -623,7 +633,7 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
|
||||
foreach(F ${PIP_MAIN_FOLDERS})
|
||||
list(APPEND DOXY_INPUT "\"${F}\"")
|
||||
endforeach(F)
|
||||
string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/lib\"")
|
||||
string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/libs\"")
|
||||
string(REPLACE ";" " " DOXY_INCLUDE_PATH "${DOXY_INPUT}")
|
||||
string(REPLACE ";" " " DOXY_DEFINES "${PIP_EXPORTS};DOXYGEN;PIOBJECT;PIOBJECT_SUBCLASS")
|
||||
add_documentation(doc doc/Doxyfile.in)
|
||||
@@ -632,6 +642,23 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
|
||||
endif()
|
||||
|
||||
|
||||
set(_max_len 0)
|
||||
foreach(_m ${PIP_SRC_MODULES})
|
||||
string(LENGTH "${_m}" _clen)
|
||||
if (_clen GREATER _max_len)
|
||||
set(_max_len ${_clen})
|
||||
endif()
|
||||
endforeach()
|
||||
macro(expand_to_length _out _str _len)
|
||||
set(${_out} "${_str}")
|
||||
while(TRUE)
|
||||
string(LENGTH "${${_out}}" _clen)
|
||||
if (_clen GREATER_EQUAL ${_len})
|
||||
break()
|
||||
endif()
|
||||
string(APPEND ${_out} " ")
|
||||
endwhile()
|
||||
endmacro()
|
||||
|
||||
list(REMOVE_ITEM LIBS_STATUS ${PIP_MODULES})
|
||||
message("----------PIP----------")
|
||||
@@ -657,7 +684,8 @@ endif()
|
||||
message("")
|
||||
message(" Modules:")
|
||||
foreach(_m ${PIP_SRC_MODULES})
|
||||
message(" ${_m}: ${PIP_MSG_${_m}}")
|
||||
expand_to_length(_m_e "${_m}" ${_max_len})
|
||||
message(" ${_m_e}: ${PIP_MSG_${_m}}")
|
||||
endforeach()
|
||||
message("")
|
||||
if (PIP_TESTS_LIST)
|
||||
|
||||
@@ -14,7 +14,9 @@ Create variable <target>_VERSION with full version name
|
||||
|
||||
If OUTPUT then generate header <file> with
|
||||
version macros - <target>_VERSION_<NAME>
|
||||
Also create macro <target>_VERSION_NAME with full string version
|
||||
Also create macro <target>_VERSION_NAME with full string version and
|
||||
macro <target>_MAKE_VERSION(major, minor, revision) that returns
|
||||
byte-packed integer version.
|
||||
Attention: macro <target>_VERSION is byte-packed integer version!
|
||||
|
||||
|
||||
@@ -165,11 +167,12 @@ set(_dt_delim "::")
|
||||
|
||||
|
||||
macro(set_version _T)
|
||||
set(_VERSION_ 1) # macro version
|
||||
set(_VERSION_ 2) # macro version
|
||||
set(_name)
|
||||
set(_is_name 1)
|
||||
set(_is_out 0)
|
||||
set(_out)
|
||||
#message("set_version \"${_T}\"")
|
||||
foreach(_i ${ARGN})
|
||||
if (_is_out)
|
||||
set(_is_out 0)
|
||||
@@ -177,13 +180,16 @@ macro(set_version _T)
|
||||
elseif ("x${_i}" STREQUAL "xOUTPUT")
|
||||
set(_is_out 1)
|
||||
elseif(_is_name)
|
||||
#message("set_version component \"${_i}\"")
|
||||
set(_is_name 0)
|
||||
if (_i IN_LIST __version_names)
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid version component \"${_i}\"!")
|
||||
endif()
|
||||
set(_name ${_i})
|
||||
set(${_T}_VERSION_${_name})
|
||||
else()
|
||||
#message("set_version value \"${_name}\" = \"${_i}\"")
|
||||
set(_is_name 1)
|
||||
set(${_T}_VERSION_${_name} ${_i})
|
||||
endif()
|
||||
@@ -239,7 +245,8 @@ macro(set_version _T)
|
||||
#define ${_TN}_VERSION_BUILD ${${_T}_VERSION_BUILD}
|
||||
#define ${_TN}_VERSION_SUFFIX \"${${_T}_VERSION_SUFFIX}\"
|
||||
#define ${_TN}_VERSION_NAME \"${${_T}_VERSION}\"
|
||||
#define ${_TN}_VERSION ((${_TN}_VERSION_MAJOR << 16) | (${_TN}_VERSION_MINOR << 8) | ${_TN}_VERSION_REVISION)
|
||||
#define ${_TN}_MAKE_VERSION(major, minor, revision) ((major << 16) | (minor << 8) | revision)
|
||||
#define ${_TN}_VERSION ${_TN}_MAKE_VERSION(${_TN}_VERSION_MAJOR, ${_TN}_VERSION_MINOR, ${_TN}_VERSION_REVISION)
|
||||
|
||||
|
||||
// Tools
|
||||
@@ -656,7 +663,8 @@ macro(deploy_target _T)
|
||||
set(_TARGET_OS "linux")
|
||||
endif()
|
||||
string(REPLACE "_" "-" _DEBNAME "${_T}")
|
||||
string(REPLACE "_" "-" _DEBVERSION "${${_T}_VERSION}${_build}+${_TARGET_OS}")
|
||||
set(_DEBVERSION "${${_T}_VERSION_MAJOR}.${${_T}_VERSION_MINOR}.${${_T}_VERSION_REVISION}${_build}${${_T}_VERSION_FULLSUFFIX}+${_TARGET_OS}")
|
||||
string(REPLACE "_" "-" _DEBVERSION "${_DEBVERSION}")
|
||||
string(TOLOWER "${_DEBNAME}" _DEBNAME)
|
||||
set(_DEB_ARCH)
|
||||
if("_${MY_ARCH}" STREQUAL "_arm64")
|
||||
|
||||
@@ -49,6 +49,9 @@ PIVector<char> vec(4u, 'p');
|
||||
piForeachC (char i, vec)
|
||||
cout << i << ", ";
|
||||
// p, p, p, p,
|
||||
|
||||
piCout << PIVector<int>({1, 2, 3});
|
||||
// 1, 2, 3
|
||||
//! [PIVector::PIVector]
|
||||
//! [PIVector::at_c]
|
||||
PIVector<int> vec;
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
PICloud Server
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piccloudserver.h"
|
||||
|
||||
|
||||
PICloudServer::PICloudServer() {
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*! \file piccloudserver.h
|
||||
* \brief PICloud Server
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
PICloud Server
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PICCLOUDSERVER_H
|
||||
#define PICCLOUDSERVER_H
|
||||
|
||||
#include "pip_cloud_export.h"
|
||||
#include "piiodevice.h"
|
||||
|
||||
|
||||
class PIP_CLOUD_EXPORT PICloudServer {
|
||||
public:
|
||||
//!
|
||||
explicit PICloudServer();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif // PICCLOUDSERVER_H
|
||||
@@ -1,200 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
|
||||
Stephan Fomenko
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIEXECUTOR_H
|
||||
#define PIEXECUTOR_H
|
||||
|
||||
#include "piblockingdequeue.h"
|
||||
#include <atomic>
|
||||
#include <future>
|
||||
|
||||
/**
|
||||
* @brief Wrapper for custom invoke operator available function types.
|
||||
* @note Source from: "Энтони Уильямс, Параллельное программирование на С++ в действии. Практика разработки многопоточных
|
||||
* программ. Пер. с англ. Слинкин А. А. - M.: ДМК Пресс, 2012 - 672c.: ил." (page 387)
|
||||
*/
|
||||
class FunctionWrapper {
|
||||
struct ImplBase {
|
||||
virtual void call() = 0;
|
||||
virtual ~ImplBase() = default;
|
||||
};
|
||||
|
||||
std::unique_ptr<ImplBase> impl;
|
||||
|
||||
template<typename F>
|
||||
struct ImplType: ImplBase {
|
||||
F f;
|
||||
explicit ImplType(F&& f): f(std::forward<F>(f)) {}
|
||||
void call() final { f(); }
|
||||
};
|
||||
public:
|
||||
template<typename F, typename = std::enable_if<!std::is_same<F, FunctionWrapper>::value> >
|
||||
explicit FunctionWrapper(F&& f): impl(new ImplType<F>(std::forward<F>(f))) {}
|
||||
|
||||
void operator()() { impl->call(); }
|
||||
|
||||
explicit operator bool() const noexcept { return static_cast<bool>(impl); }
|
||||
|
||||
FunctionWrapper() = default;
|
||||
FunctionWrapper(FunctionWrapper&& other) noexcept : impl(std::move(other.impl)) {}
|
||||
FunctionWrapper& operator=(FunctionWrapper&& other) noexcept {
|
||||
impl = std::move(other.impl);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FunctionWrapper(const FunctionWrapper& other) = delete;
|
||||
FunctionWrapper& operator=(const FunctionWrapper&) = delete;
|
||||
};
|
||||
|
||||
template <typename Thread_ = PIThread, typename Dequeue_ = PIBlockingDequeue<FunctionWrapper>>
|
||||
class PIThreadPoolExecutorTemplate {
|
||||
public:
|
||||
NO_COPY_CLASS(PIThreadPoolExecutorTemplate)
|
||||
explicit PIThreadPoolExecutorTemplate(size_t corePoolSize = 1) : isShutdown_(false) { makePool(corePoolSize); }
|
||||
|
||||
virtual ~PIThreadPoolExecutorTemplate() {
|
||||
shutdownNow();
|
||||
while (threadPool.size() > 0) delete threadPool.take_back();
|
||||
}
|
||||
|
||||
template<typename FunctionType>
|
||||
std::future<typename std::result_of<FunctionType()>::type> submit(FunctionType&& callable) {
|
||||
typedef typename std::result_of<FunctionType()>::type ResultType;
|
||||
|
||||
if (!isShutdown_) {
|
||||
std::packaged_task<ResultType()> callable_task(std::forward<FunctionType>(callable));
|
||||
auto future = callable_task.get_future();
|
||||
FunctionWrapper functionWrapper(callable_task);
|
||||
taskQueue.offer(std::move(functionWrapper));
|
||||
return future;
|
||||
} else {
|
||||
return std::future<ResultType>();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FunctionType>
|
||||
void execute(FunctionType&& runnable) {
|
||||
if (!isShutdown_) {
|
||||
FunctionWrapper function_wrapper(std::forward<FunctionType>(runnable));
|
||||
taskQueue.offer(std::move(function_wrapper));
|
||||
}
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
isShutdown_ = true;
|
||||
}
|
||||
|
||||
void shutdownNow() {
|
||||
isShutdown_ = true;
|
||||
for (size_t i = 0; i < threadPool.size(); ++i) threadPool[i]->stop();
|
||||
}
|
||||
|
||||
bool isShutdown() const {
|
||||
return isShutdown_;
|
||||
}
|
||||
|
||||
bool awaitTermination(int timeoutMs) {
|
||||
PITimeMeasurer measurer;
|
||||
for (size_t i = 0; i < threadPool.size(); ++i) {
|
||||
int dif = timeoutMs - (int)measurer.elapsed_m();
|
||||
if (dif < 0) return false;
|
||||
if (!threadPool[i]->waitForFinish(dif)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::atomic_bool isShutdown_;
|
||||
Dequeue_ taskQueue;
|
||||
PIVector<Thread_*> threadPool;
|
||||
|
||||
template<typename Function>
|
||||
PIThreadPoolExecutorTemplate(size_t corePoolSize, Function&& onBeforeStart) : isShutdown_(false) {
|
||||
makePool(corePoolSize, std::forward<Function>(onBeforeStart));
|
||||
}
|
||||
|
||||
void makePool(size_t corePoolSize, std::function<void(Thread_*)>&& onBeforeStart = [](Thread_*){}) {
|
||||
for (size_t i = 0; i < corePoolSize; ++i) {
|
||||
auto* thread = new Thread_([&, i](){
|
||||
auto runnable = taskQueue.poll(100);
|
||||
if (runnable) {
|
||||
runnable();
|
||||
}
|
||||
if (isShutdown_ && taskQueue.size() == 0) threadPool[i]->stop();
|
||||
});
|
||||
threadPool.push_back(thread);
|
||||
onBeforeStart(thread);
|
||||
thread->start();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef PIThreadPoolExecutorTemplate<> PIThreadPoolExecutor;
|
||||
|
||||
#ifdef DOXYGEN
|
||||
/**
|
||||
* @brief Thread pools address two different problems: they usually provide improved performance when executing large
|
||||
* numbers of asynchronous tasks, due to reduced per-task invocation overhead, and they provide a means of bounding and
|
||||
* managing the resources, including threads, consumed when executing a collection of tasks.
|
||||
*/
|
||||
class PIThreadPoolExecutor {
|
||||
public:
|
||||
explicit PIThreadPoolExecutor(size_t corePoolSize);
|
||||
|
||||
virtual ~PIThreadPoolExecutor();
|
||||
|
||||
/**
|
||||
* @brief Submits a Runnable task for execution and returns a Future representing that task. The Future's get method
|
||||
* will return null upon successful completion.
|
||||
*
|
||||
* @tparam FunctionType - custom type of function with operator() and return type
|
||||
* @tparam R - derived from FunctionType return type
|
||||
*
|
||||
* @param callable - the task to submit
|
||||
* @return a future representing pending completion of the task
|
||||
*/
|
||||
std::future<R> submit(FunctionType&& callable);
|
||||
|
||||
/**
|
||||
* @brief Executes the given task sometime in the future. The task execute in an existing pooled thread. If the task
|
||||
* cannot be submitted for execution, either because this executor has been shutdown or because its capacity has been
|
||||
* reached.
|
||||
*
|
||||
* @tparam FunctionType - custom type of function with operator() and return type
|
||||
*
|
||||
* @param runnable not empty function for thread pool execution
|
||||
*/
|
||||
void execute(FunctionType&& runnable);
|
||||
|
||||
/**
|
||||
* @brief Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be
|
||||
* accepted. Invocation has no additional effect if already shut down. This method does not wait for previously
|
||||
* submitted tasks to complete execution. Use awaitTermination to do that.
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
void shutdownNow();
|
||||
|
||||
bool isShutdown() const;
|
||||
|
||||
bool awaitTermination(int timeoutMs);
|
||||
};
|
||||
#endif //DOXYGEN
|
||||
|
||||
#endif //PIEXECUTOR_H
|
||||
@@ -17,24 +17,33 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piccloudclient.h"
|
||||
#include "picloudclient.h"
|
||||
|
||||
|
||||
PICloudClient::PICloudClient() {
|
||||
PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), eth(PIEthernet::TCP_Client) {
|
||||
}
|
||||
|
||||
|
||||
PICloudClient::~PICloudClient() {
|
||||
|
||||
stop();
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
bool PICloudClient::openDevice() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PICloudClient::closeDevice() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int PICloudClient::readDevice(void * read_to, int max_size) {
|
||||
return eth.read(read_to, max_size);
|
||||
}
|
||||
|
||||
|
||||
int PICloudClient::writeDevice(const void * data, int max_size) {
|
||||
return eth.write(data, max_size);
|
||||
}
|
||||
81
libs/cloud/picloudserver.cpp
Normal file
81
libs/cloud/picloudserver.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
PICloud Server
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "picloudserver.h"
|
||||
|
||||
|
||||
PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), eth(PIEthernet::TCP_Client) {
|
||||
}
|
||||
|
||||
|
||||
PICloudServer::~PICloudServer() {
|
||||
stop();
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
bool PICloudServer::openDevice() {
|
||||
piCout << "PICloudServer open device" << path();
|
||||
bool op = eth.connect(path(), false);
|
||||
if (op) {
|
||||
CONNECTL(ð, disconnected, [this](bool){opened_ = false;});
|
||||
CONNECTU(ð, threadedReadEvent, this, readed);
|
||||
eth.startThreadedRead();
|
||||
sendStart();
|
||||
return true;
|
||||
}
|
||||
eth.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PICloudServer::closeDevice() {
|
||||
return eth.close();
|
||||
}
|
||||
|
||||
|
||||
int PICloudServer::readDevice(void * read_to, int max_size) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int PICloudServer::writeDevice(const void * data, int max_size) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void PICloudServer::sendStart() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
PICloudServer::Client::Client(PICloudServer * srv) : server(srv) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool PICloudServer::Client::openDevice() {
|
||||
return server;
|
||||
}
|
||||
|
||||
|
||||
void PICloudServer::readed(uchar *data, int size) {
|
||||
|
||||
}
|
||||
@@ -17,12 +17,26 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piccloudtcp.h"
|
||||
#include "picloudtcp.h"
|
||||
#include "picrypt.h"
|
||||
#include "pichunkstream.h"
|
||||
|
||||
|
||||
const char hash_def_key[] = "_picrypt_";
|
||||
|
||||
|
||||
PICloudTCP::PICloudTCP() {
|
||||
PIByteArray & operator <<(PIByteArray & s, const PICloud::Header & v) {
|
||||
s << v.version << v.type << v.sname;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
PIByteArray & operator >>(PIByteArray & s, PICloud::Header & v) {
|
||||
s >> v.version >> v.type >> v.sname;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
PICloud::TCP::TCP() {
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*! \file piccloudclient.h
|
||||
/*! \file picloudclient.h
|
||||
* \brief PICloud Client
|
||||
*/
|
||||
/*
|
||||
@@ -20,13 +20,11 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PICCLOUDCLIENT_H
|
||||
#define PICCLOUDCLIENT_H
|
||||
#ifndef PICLOUDCLIENT_H
|
||||
#define PICLOUDCLIENT_H
|
||||
|
||||
#include "pip_cloud_export.h"
|
||||
#include "piiodevice.h"
|
||||
|
||||
class PIEthernet;
|
||||
#include "piethernet.h"
|
||||
|
||||
|
||||
class PIP_CLOUD_EXPORT PICloudClient : public PIIODevice
|
||||
@@ -34,7 +32,7 @@ class PIP_CLOUD_EXPORT PICloudClient : public PIIODevice
|
||||
PIIODEVICE(PICloudClient)
|
||||
public:
|
||||
//!
|
||||
explicit PICloudClient();
|
||||
explicit PICloudClient(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||
virtual ~PICloudClient();
|
||||
|
||||
protected:
|
||||
@@ -42,7 +40,10 @@ protected:
|
||||
bool closeDevice();
|
||||
|
||||
private:
|
||||
PIEthernet * eth;
|
||||
int readDevice(void * read_to, int max_size);
|
||||
int writeDevice(const void * data, int max_size);
|
||||
|
||||
PIEthernet eth;
|
||||
};
|
||||
|
||||
#endif // PICCLOUDCLIENT_H
|
||||
#endif // PICLOUDCLIENT_H
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef PICLOUDMODULE_H
|
||||
#define PICLOUDMODULE_H
|
||||
|
||||
#include "piccloudtcp.h"
|
||||
#include "piccloudclient.h"
|
||||
#include "piccloudserver.h"
|
||||
#include "picloudtcp.h"
|
||||
#include "picloudclient.h"
|
||||
#include "picloudserver.h"
|
||||
|
||||
#endif // PICLOUDMODULE_H
|
||||
65
libs/main/cloud/picloudserver.h
Normal file
65
libs/main/cloud/picloudserver.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*! \file picloudserver.h
|
||||
* \brief PICloud Server
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
PICloud Server
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PICLOUDSERVER_H
|
||||
#define PICLOUDSERVER_H
|
||||
|
||||
#include "pip_cloud_export.h"
|
||||
#include "piethernet.h"
|
||||
|
||||
|
||||
class PIP_CLOUD_EXPORT PICloudServer : public PIIODevice
|
||||
{
|
||||
PIIODEVICE(PICloudServer)
|
||||
public:
|
||||
//!
|
||||
explicit PICloudServer(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||
virtual ~PICloudServer();
|
||||
|
||||
class Client : public PIIODevice {
|
||||
PIIODEVICE(PICloudServer::Client)
|
||||
public:
|
||||
Client(PICloudServer * srv = nullptr);
|
||||
protected:
|
||||
bool openDevice();
|
||||
private:
|
||||
PICloudServer * server;
|
||||
};
|
||||
|
||||
EVENT1(newConnection, PICloudServer::Client * , client)
|
||||
|
||||
protected:
|
||||
bool openDevice();
|
||||
bool closeDevice();
|
||||
int readDevice(void * read_to, int max_size);
|
||||
int writeDevice(const void * data, int max_size);
|
||||
|
||||
private:
|
||||
EVENT_HANDLER2(void, readed, uchar * , data, int, size);
|
||||
void sendStart();
|
||||
|
||||
PIEthernet eth;
|
||||
PIVector<Client> clients;
|
||||
|
||||
};
|
||||
|
||||
#endif // PICLOUDSERVER_H
|
||||
@@ -1,4 +1,4 @@
|
||||
/*! \file piccloudtcp.h
|
||||
/*! \file picloudtcp.h
|
||||
* \brief PICloud TCP transport
|
||||
*/
|
||||
/*
|
||||
@@ -20,20 +20,45 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PICCLOUDTCP_H
|
||||
#define PICCLOUDTCP_H
|
||||
#ifndef PICLOUDTCP_H
|
||||
#define PICLOUDTCP_H
|
||||
|
||||
#include "pip_cloud_export.h"
|
||||
#include "pistring.h"
|
||||
|
||||
class PIP_CLOUD_EXPORT PICloudTCP {
|
||||
public:
|
||||
//!
|
||||
PICloudTCP();
|
||||
|
||||
namespace PICloud {
|
||||
|
||||
enum Version {
|
||||
Version_1 = 1,
|
||||
};
|
||||
|
||||
enum HeaderType {
|
||||
Server = 1,
|
||||
Client = 2,
|
||||
};
|
||||
|
||||
struct PIP_CLOUD_EXPORT Header {
|
||||
Header() {
|
||||
version = Version_1;
|
||||
}
|
||||
uchar version; // PICloud::Version
|
||||
uchar type; // PICloud::HeaderType
|
||||
PIString sname; // server name
|
||||
};
|
||||
|
||||
|
||||
class PIP_CLOUD_EXPORT TCP {
|
||||
public:
|
||||
TCP();
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif // PICCLOUDTCP_H
|
||||
}
|
||||
|
||||
PIP_CLOUD_EXPORT PIByteArray & operator <<(PIByteArray & s, const PICloud::Header & v);
|
||||
PIP_CLOUD_EXPORT PIByteArray & operator >>(PIByteArray & s, PICloud::Header & v);
|
||||
|
||||
#endif // PICLOUDTCP_H
|
||||
@@ -32,6 +32,10 @@
|
||||
* \brief Contructs vector with size "size" filled elements "value"
|
||||
* \details Example: \snippet picontainers.cpp PIVector::PIVector
|
||||
|
||||
* \fn PIVector::PIVector(std::initializer_list list);
|
||||
* \brief Contructs vector from C++11 initializer list
|
||||
* \details Example: \snippet picontainers.cpp PIVector::PIVector
|
||||
|
||||
* \fn const T & PIVector::at(size_t index) const;
|
||||
* \brief Read-only access to element by index "index"
|
||||
* \details Example: \snippet picontainers.cpp PIVector::at_c
|
||||
@@ -371,4 +375,7 @@
|
||||
* \fn bool PIMapIterator::next()
|
||||
* \brief Jump to next entry and return if new position is valid.
|
||||
|
||||
* \fn void PIMapIterator::reset()
|
||||
* \brief Reset iterator to initial position.
|
||||
|
||||
* */
|
||||
@@ -42,6 +42,8 @@
|
||||
#else
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include <string.h>
|
||||
#include <new>
|
||||
#ifndef PIP_MEMALIGN_BYTES
|
||||
@@ -39,6 +39,11 @@ public:
|
||||
alloc(other.pid_size, true);
|
||||
newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size);
|
||||
}
|
||||
inline PIDeque(std::initializer_list<T> init_list): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||
alloc(init_list.size(), true);
|
||||
newT(pid_data, init_list.begin(), init_list.size());
|
||||
}
|
||||
inline PIDeque(const T * data, size_t size): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||
alloc(size, true);
|
||||
@@ -49,6 +54,7 @@ public:
|
||||
resize(pid_size, f);
|
||||
}
|
||||
inline PIDeque(PIDeque<T> && other): pid_data(other.pid_data), pid_size(other.pid_size), pid_rsize(other.pid_rsize), pid_start(other.pid_start) {
|
||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||
other._reset();
|
||||
}
|
||||
inline virtual ~PIDeque() {
|
||||
@@ -364,6 +364,13 @@ public:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
inline void reset() {
|
||||
if (rev) {
|
||||
pos = m.size_s();
|
||||
} else {
|
||||
pos = -1;
|
||||
}
|
||||
}
|
||||
private:
|
||||
const MapType & m;
|
||||
ssize_t pos;
|
||||
@@ -44,11 +44,17 @@ public:
|
||||
alloc(other.piv_size);
|
||||
newT(piv_data, other.piv_data, piv_size);
|
||||
}
|
||||
inline PIVector(std::initializer_list<T> init_list): piv_data(0), piv_size(0), piv_rsize(0) {
|
||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||
alloc(init_list.size());
|
||||
newT(piv_data, init_list.begin(), init_list.size());
|
||||
}
|
||||
inline PIVector(size_t piv_size, const T & f = T()): piv_data(0), piv_size(0), piv_rsize(0) {
|
||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||
resize(piv_size, f);
|
||||
}
|
||||
inline PIVector(PIVector<T> && other): piv_data(other.piv_data), piv_size(other.piv_size), piv_rsize(other.piv_rsize) {
|
||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||
other._reset();
|
||||
}
|
||||
inline virtual ~PIVector() {
|
||||
@@ -292,13 +292,6 @@ template<> inline void piSwapBinary(const void *& f, const void *& s) {
|
||||
}
|
||||
}
|
||||
|
||||
template<> inline void piSwap(double & f, double & s) {piSwapBinary<double>(f, s);}
|
||||
template<> inline void piSwap(ldouble & f, ldouble & s) {piSwapBinary<ldouble>(f, s);}
|
||||
#ifdef ARCH_BITS_32
|
||||
template<> inline void piSwap(float & f, float & s) {piSwapBinary<float>(f, s);}
|
||||
template<> inline void piSwap(llong & f, llong & s) {piSwapBinary<llong>(f, s);}
|
||||
template<> inline void piSwap(ullong & f, ullong & s) {piSwapBinary<ullong>(f, s);}
|
||||
#endif
|
||||
|
||||
/*! \brief Function for compare two values without "=" by raw content
|
||||
* \details Example:\n \snippet piincludes.cpp compareBinary */
|
||||
@@ -454,20 +447,7 @@ template<> inline float piLetobe(const float & v) {
|
||||
return a.f;
|
||||
}
|
||||
|
||||
DEPRECATED inline ushort letobe_s(const ushort & v) {return (v << 8) | (v >> 8);}
|
||||
DEPRECATED inline uint letobe_i(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
|
||||
|
||||
#ifdef DOXYGEN
|
||||
|
||||
/// \deprecated \brief Use \a piLetobe() instead of this function
|
||||
ushort letobe_s(ushort v) {return (v << 8) | (v >> 8);}
|
||||
|
||||
/// \deprecated \brief Use \a piLetobe() instead of this function
|
||||
uint letobe_i(uint v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
|
||||
|
||||
#endif
|
||||
|
||||
/// \brief Generic hash function, impements murmur3/32 algorithm
|
||||
/// \brief Generic hash function, implements murmur3/32 algorithm
|
||||
inline uint piHashData(const uchar * data, uint len, uint seed = 0) {
|
||||
if (!data || len <= 0) return 0u;
|
||||
uint h = seed;
|
||||
@@ -396,8 +396,8 @@ PIByteArray & operator >>(PIByteArray & s, PIByteArray & v) {
|
||||
}
|
||||
v.resize(sz);
|
||||
if (sz > 0) {
|
||||
memcpy(v.data(), s.data(), v.size());
|
||||
s.remove(0, v.size());
|
||||
memcpy(v.data(), s.data(), sz);
|
||||
s.remove(0, sz);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@@ -80,11 +80,36 @@ int PIChunkStream::read() {
|
||||
}
|
||||
|
||||
|
||||
int PIChunkStream::peekVInt(Version version_, PIByteArray * data_, int pos, PIByteArray & hdr, uint & ret) {
|
||||
switch (version_) {
|
||||
case Version_1:
|
||||
memcpy(&ret, data_->data(pos), 4);
|
||||
return 4;
|
||||
case Version_2: {
|
||||
hdr.resize(4);
|
||||
hdr.fill(uchar(0));
|
||||
memcpy(hdr.data(), data_->data(pos), piMini(4, data_->size_s() - pos));
|
||||
uchar hsz = 0;
|
||||
ret = readVInt(hdr, &hsz);
|
||||
return hsz;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PIChunkStream::readAll() {
|
||||
data_map.clear();
|
||||
while (!atEnd()) {
|
||||
read();
|
||||
data_map[last_id] = last_data;
|
||||
if (!data_) return;
|
||||
int pos = 0, sz = data_->size_s();
|
||||
uint csz = 0, cid = 0;
|
||||
PIByteArray hdr;
|
||||
while (pos < sz) {
|
||||
pos += peekVInt((Version)version_, data_, pos, hdr, cid);
|
||||
pos += peekVInt((Version)version_, data_, pos, hdr, csz);
|
||||
data_map[cid] = PIPair<int, int>(pos, csz);
|
||||
pos += csz;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +136,7 @@ void PIChunkStream::_init() {
|
||||
}
|
||||
|
||||
|
||||
uint PIChunkStream::readVInt(PIByteArray & s) {
|
||||
uint PIChunkStream::readVInt(PIByteArray & s, uchar * bytes_cnt) {
|
||||
if (s.isEmpty()) return 0;
|
||||
uchar bytes[4]; s >> bytes[0];
|
||||
uchar abc = 0;
|
||||
@@ -122,6 +147,7 @@ uint PIChunkStream::readVInt(PIByteArray & s) {
|
||||
s >> bytes[abc + 1];
|
||||
} else break;
|
||||
}
|
||||
if (bytes_cnt) *bytes_cnt = (abc + 1);
|
||||
uint ret = 0;
|
||||
for (int i = 0; i <= abc; ++i) {
|
||||
ret += (bytes[i] << (8 * ((int)abc - i)));
|
||||
@@ -79,11 +79,11 @@ public:
|
||||
//! Returns stream version
|
||||
Version version() const {return (Version)version_;}
|
||||
|
||||
|
||||
|
||||
//! Read one chunk from stream and returns its ID
|
||||
int read();
|
||||
|
||||
//! Read all chunks from stream
|
||||
//! Read all chunks from stream. This function just index input data
|
||||
void readAll();
|
||||
|
||||
//! Returns last readed chunk ID
|
||||
@@ -100,7 +100,9 @@ public:
|
||||
//! Place value of chunk with id \"id\" into \"v\". You should call \a readAll() before using this function!
|
||||
template <typename T>
|
||||
const PIChunkStream & get(int id, T & v) const {
|
||||
PIByteArray ba = data_map.value(id);
|
||||
PIPair<int, int> pos = data_map.value(id);
|
||||
if (pos.first < 0 || pos.second == 0) return *this;
|
||||
PIByteArray ba(data_->data(pos.first), pos.second);
|
||||
if (!ba.isEmpty())
|
||||
ba >> v;
|
||||
return *this;
|
||||
@@ -109,13 +111,14 @@ public:
|
||||
private:
|
||||
void _init();
|
||||
|
||||
static uint readVInt(PIByteArray & s);
|
||||
static uint readVInt(PIByteArray & s, uchar * bytes = 0);
|
||||
static void writeVInt(PIByteArray & s, uint val);
|
||||
static int peekVInt(Version version_, PIByteArray * data_, int pos, PIByteArray & hdr, uint & ret);
|
||||
|
||||
int last_id;
|
||||
uchar version_;
|
||||
PIByteArray * data_, last_data, tmp_data;
|
||||
PIMap<int, PIByteArray> data_map;
|
||||
PIMap<int, PIPair<int, int>> data_map;
|
||||
|
||||
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c);
|
||||
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::ChunkConst<T> & c);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user