WIP: Pi Pico support #193
@@ -0,0 +1,165 @@
|
||||
# PIP Codebase Guide for AGENTS
|
||||
|
||||
## Build Commands
|
||||
|
||||
### Basic Build
|
||||
```bash
|
||||
# Configure with CMake (release build)
|
||||
cmake -B build
|
||||
|
||||
# Build the project
|
||||
cmake --build build -j16
|
||||
|
||||
# Install (default system location)
|
||||
cmake --build build --target install -j16
|
||||
|
||||
# Local install (bin/lib/include in build directory)
|
||||
cmake -B build -DLOCAL=ON
|
||||
```
|
||||
|
||||
### With Tests
|
||||
```bash
|
||||
cmake -B build -DTESTS=ON -DTESTS_RUN=ON
|
||||
cmake --build build -j16
|
||||
cd build && ctest
|
||||
```
|
||||
|
||||
### Build Only
|
||||
```bash
|
||||
cmake --build build -j16
|
||||
```
|
||||
|
||||
### Run Single Test
|
||||
```bash
|
||||
# After building with TESTS=ON
|
||||
./build/tests/math/pip_math_test --gtest_filter="Vector2DTest.defaultConstructor*"
|
||||
# Or use ctest
|
||||
ctest -R math -V
|
||||
# List all tests
|
||||
ctest -N
|
||||
```
|
||||
|
||||
### Build Options
|
||||
- `TESTS=ON` - Build tests (requires Google Test)
|
||||
- `COVERAGE=ON` - Build with coverage instrumentation
|
||||
- `ICU=ON` - Enable ICU support for string conversion
|
||||
- `STD_IOSTREAM=ON` - Enable std::iostream operators
|
||||
- `INTROSPECTION=ON` - Build with introspection support
|
||||
- `PIP_BUILD_*` - Enable/disable modules (e.g., `PIP_BUILD_CRYPT=OFF`)
|
||||
|
||||
### Code Generation Tools
|
||||
- `pip_cmg` - Code model generator (auto-generates code from comments)
|
||||
- `pip_rc` - Resources compiler (embeds resources into C++ code)
|
||||
- `pip_tr` - Translation tool (compiles .btf translation files)
|
||||
|
||||
### Linting & Formatting
|
||||
- **clang-format**: Run `clang-format -i <file>` or `find . -name "*.cpp" -o -name "*.h" | xargs clang-format -i`
|
||||
- **Format config**: `.clang-format` (ColumnLimit: 140, IndentWidth: 4, BraceWrapping: Attach)
|
||||
- **Includes sorting**: Enabled (CaseSensitive, SortIncludes: true)
|
||||
- **Macro blocks**: `PRIVATE_DEFINITION_START/END`, `STATIC_INITIALIZER_BEGIN/END`, `DECLARE_UNIT_CLASS_BEGIN/END`
|
||||
- **No Cursor/Copilot rules** found in this repository
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
### General
|
||||
- **Language Standard**: C++11 (CMAKE_CXX_STANDARD 11)
|
||||
- **File Encoding**: UTF-8
|
||||
- **Line Endings**: Unix (LF)
|
||||
- **Column Limit**: 140 characters
|
||||
|
||||
### Naming Conventions
|
||||
- **Classes**: `PascalCase` (e.g., `PIObject`, `PIString`)
|
||||
- **Functions/Methods**: `camelCase` (e.g., `toString()`, `isEmpty()`)
|
||||
- **Variables**: `camelCase` (e.g., `rowCount`, `isReady`)
|
||||
- **Constants**: `kPrefixCamelCase` (e.g., `kMaxSize`)
|
||||
- **Macros**: `UPPER_CASE` (e.g., `PIP_EXPORT`, `NO_COPY_CLASS`)
|
||||
- **Types**: `PascalCase` with `p` prefix for internal/private (e.g., `PIString_p.h`)
|
||||
|
||||
### File Naming
|
||||
- Headers: `pi<name>.h` (e.g., `piobject.h`, `pistring.h`)
|
||||
- Private headers: `pi<name>_p.h` (e.g., `piobject_p.h`)
|
||||
- Test files: `test<name>.cpp` (e.g., `testpivector2d.cpp`)
|
||||
|
||||
### Comments & Documentation
|
||||
- Use Doxygen-style comments for all public APIs
|
||||
- Include `\~english` and `\~russian` translations
|
||||
- Group related classes/modules with `//! \defgroup`
|
||||
- Use `\ingroup` to assign files to groups
|
||||
- Example:
|
||||
```cpp
|
||||
//! \file piobject.h
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Base object
|
||||
//! \~russian Базовый класс
|
||||
```
|
||||
|
||||
### Includes
|
||||
- Order: System headers → PIP headers → Local headers
|
||||
- Sort alphabetically within groups
|
||||
- Use `#pragma once` or include guards
|
||||
- PIP includes use `#include "pi<name>.h"`
|
||||
|
||||
### Formatting (clang-format)
|
||||
- **Indentation**: 4 spaces (no tabs for code)
|
||||
- **Braces**: Attach style (`if (x) {`)
|
||||
- **Pointers/References**: `Type* ptr`, `Type& ref`
|
||||
- **Templates**: Always break before `>` in nested templates
|
||||
- **Empty Lines**: Max 2 consecutive empty lines
|
||||
- **Namespace**: No indentation (`Namespace { ... }`)
|
||||
|
||||
### Error Handling
|
||||
- Use `PIString` for error messages
|
||||
- Return bool for success/failure
|
||||
- Use `assert()` for debug-only checks
|
||||
- Avoid exceptions (RTTI disabled in some builds)
|
||||
|
||||
### Memory Management
|
||||
- Prefer stack allocation
|
||||
- Use `NO_COPY_CLASS(MyClass)` to disable copy
|
||||
- Implement proper move semantics when needed
|
||||
- Use `std::unique_ptr`/`std::shared_ptr` sparingly
|
||||
|
||||
### Macros
|
||||
- PIMETA(...) - Add metadata for code model generator
|
||||
- PIP_EXPORT - Export/import symbols for DLLs
|
||||
- NO_COPY_CLASS - Disable copy constructor and operator=
|
||||
- PRIVATE_DECLARATION - Private implementation macro
|
||||
|
||||
## Testing
|
||||
- Framework: Google Test (fetched automatically when TESTS=ON)
|
||||
- Test files: `tests/<module>/test<name>.cpp`
|
||||
- Use `pip_test(module)` macro in `tests/CMakeLists.txt`
|
||||
- Test discovery via `gtest_discover_tests()`
|
||||
|
||||
### Running Tests
|
||||
```bash
|
||||
# Run all tests
|
||||
ctest
|
||||
|
||||
# Run specific test suite
|
||||
ctest -R math -V
|
||||
|
||||
# List all available tests
|
||||
ctest -N
|
||||
|
||||
# Run single test with gtest filter
|
||||
./build/tests/math/pip_math_test --gtest_filter="Vector2DTest.defaultConstructor*"
|
||||
```
|
||||
|
||||
## Module Structure
|
||||
```
|
||||
libs/
|
||||
├── main/ # Core modules
|
||||
│ ├── core/ # Base types, PIObject, PIString
|
||||
│ ├── thread/ # Threading primitives
|
||||
│ ├── math/ # Math functions, vectors, matrices
|
||||
│ └── ...
|
||||
└── <module>/ # Feature modules (fftw, crypt, compress, etc.)
|
||||
```
|
||||
|
||||
## Additional Notes
|
||||
- Project uses custom CMake macros from `cmake/` directory
|
||||
- Version format: `MAJOR.MINOR.REVISION` (e.g., 5.6.0)
|
||||
- All files have LGPL license header
|
||||
- Support for multiple platforms: Windows, Linux, QNX, Android, Apple
|
||||
+146
-100
@@ -3,6 +3,9 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
||||
if (POLICY CMP0177)
|
||||
cmake_policy(SET CMP0177 OLD)
|
||||
endif()
|
||||
if(DEFINED PICO_SDK_PATH)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
endif()
|
||||
project(PIP)
|
||||
set(PIP_MAJOR 5)
|
||||
set(PIP_MINOR 8)
|
||||
@@ -70,6 +73,13 @@ option(INTROSPECTION "Build with introspection" OFF)
|
||||
option(TESTS "Build tests" OFF)
|
||||
option(TESTS_RUN "Run tests before install step" OFF)
|
||||
option(COVERAGE "Build project with coverage info" OFF)
|
||||
option(PIP_HAS_FILESYSTEM "Enable filesystem support" ON)
|
||||
option(PIP_HAS_THREADS "Enable threading support" ON)
|
||||
option(PIP_HAS_SOCKET "Enable socket/network support" ON)
|
||||
option(PIP_HAS_PROCESS "Enable process management" ON)
|
||||
option(PIP_HAS_DYNLIB "Enable dynamic library loading" ON)
|
||||
option(PIP_HAS_FFT "Enable FFT support" ON)
|
||||
option(PIP_HAS_SERIAL "Enable serial port support" ON)
|
||||
option(PIP_FFTW_F "Support fftw module for float" ON)
|
||||
option(PIP_FFTW_L "Support fftw module for long double" ON)
|
||||
option(PIP_FFTW_Q "Support fftw module for quad double" OFF)
|
||||
@@ -218,6 +228,67 @@ foreach(F ${PIP_FOLDERS})
|
||||
endif()
|
||||
endforeach(F)
|
||||
|
||||
if(DEFINED PICO_BOARD)
|
||||
add_definitions(-DPICO_SDK)
|
||||
add_definitions(-DPIP_EMBEDDED)
|
||||
set(PIP_HAS_FILESYSTEM OFF CACHE BOOL "" FORCE)
|
||||
if(NOT DEFINED PICO_FREERTOS)
|
||||
set(PIP_HAS_THREADS OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
if(NOT DEFINED PICO_LWIP)
|
||||
set(PIP_HAS_SOCKET OFF CACHE BOOL "" FORCE)
|
||||
set(PIP_BUILD_MQTT_CLIENT OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
set(PIP_HAS_PROCESS OFF CACHE BOOL "" FORCE)
|
||||
set(PIP_HAS_DYNLIB OFF CACHE BOOL "" FORCE)
|
||||
set(PIP_HAS_FFT OFF CACHE BOOL "" FORCE)
|
||||
set(PIP_HAS_SERIAL OFF CACHE BOOL "" FORCE)
|
||||
set(PIP_BUILD_CONSOLE OFF CACHE BOOL "" FORCE)
|
||||
message(STATUS "Building PIP for Pi Pico SDK ${PICO_SDK_VERSION_STRING}")
|
||||
endif()
|
||||
|
||||
if(PIP_FREERTOS)
|
||||
add_definitions(-DPIP_FREERTOS)
|
||||
add_definitions(-DPIP_EMBEDDED)
|
||||
set(PIP_HAS_FILESYSTEM OFF CACHE BOOL "" FORCE)
|
||||
if(NOT DEFINED LWIP)
|
||||
set(PIP_HAS_SOCKET OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
set(PIP_HAS_PROCESS OFF CACHE BOOL "" FORCE)
|
||||
set(PIP_HAS_DYNLIB OFF CACHE BOOL "" FORCE)
|
||||
set(PIP_HAS_FFT OFF CACHE BOOL "" FORCE)
|
||||
set(PIP_HAS_SERIAL OFF CACHE BOOL "" FORCE)
|
||||
set(PIP_BUILD_CONSOLE OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
if(DEFINED ANDROID_PLATFORM)
|
||||
set(PIP_HAS_PROCESS OFF CACHE BOOL "" FORCE)
|
||||
set(PIP_HAS_DYNLIB OFF CACHE BOOL "" FORCE)
|
||||
set(PIP_HAS_FFT OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
if(PIP_HAS_FILESYSTEM)
|
||||
add_definitions(-DPIP_HAS_FILESYSTEM)
|
||||
endif()
|
||||
if(PIP_HAS_THREADS)
|
||||
add_definitions(-DPIP_HAS_THREADS)
|
||||
endif()
|
||||
if(PIP_HAS_SOCKET)
|
||||
add_definitions(-DPIP_HAS_SOCKET)
|
||||
endif()
|
||||
if(PIP_HAS_PROCESS)
|
||||
add_definitions(-DPIP_HAS_PROCESS)
|
||||
endif()
|
||||
if(PIP_HAS_DYNLIB)
|
||||
add_definitions(-DPIP_HAS_DYNLIB)
|
||||
endif()
|
||||
if(PIP_HAS_FFT)
|
||||
add_definitions(-DPIP_HAS_FFT)
|
||||
endif()
|
||||
if(PIP_HAS_SERIAL)
|
||||
add_definitions(-DPIP_HAS_SERIAL)
|
||||
endif()
|
||||
|
||||
if (TESTS)
|
||||
set(PIP_ROOT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
if (TESTS_RUN)
|
||||
@@ -226,12 +297,6 @@ if (TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if(PIP_FREERTOS)
|
||||
add_definitions(-DPIP_FREERTOS)
|
||||
set(ICU OFF)
|
||||
set(LOCAL ON)
|
||||
endif()
|
||||
|
||||
# Check Bessel functions
|
||||
set(CMAKE_REQUIRED_INCLUDES math.h)
|
||||
set(CMAKE_REQUIRED_LIBRARIES m)
|
||||
@@ -334,34 +399,28 @@ if ((NOT DEFINED SHSTKPROJECT) AND (DEFINED ANDROID_PLATFORM))
|
||||
#message("${ANDROID_NDK}/sysroot/usr/include")
|
||||
endif()
|
||||
|
||||
if(NOT PIP_FREERTOS)
|
||||
if(WIN32)
|
||||
if(${C_COMPILER} STREQUAL "cl.exe")
|
||||
else()
|
||||
list(APPEND LIBS_MAIN ws2_32 iphlpapi psapi cfgmgr32 setupapi hid)
|
||||
endif()
|
||||
if(WIN32)
|
||||
if(${C_COMPILER} STREQUAL "cl.exe")
|
||||
else()
|
||||
list(APPEND LIBS_MAIN dl)
|
||||
if(DEFINED ENV{QNX_HOST})
|
||||
list(APPEND LIBS_MAIN socket)
|
||||
else()
|
||||
if (NOT DEFINED ANDROID_PLATFORM)
|
||||
list(APPEND LIBS_MAIN pthread util)
|
||||
if (NOT APPLE)
|
||||
list(APPEND LIBS_MAIN rt)
|
||||
endif()
|
||||
list(APPEND LIBS_MAIN ws2_32 iphlpapi psapi cfgmgr32 setupapi hid)
|
||||
endif()
|
||||
else()
|
||||
list(APPEND LIBS_MAIN dl)
|
||||
if(DEFINED ENV{QNX_HOST})
|
||||
list(APPEND LIBS_MAIN socket)
|
||||
else()
|
||||
if (NOT DEFINED ANDROID_PLATFORM)
|
||||
list(APPEND LIBS_MAIN pthread util)
|
||||
if (NOT APPLE)
|
||||
list(APPEND LIBS_MAIN rt)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
set(PIP_LIBS)
|
||||
if(PIP_FREERTOS)
|
||||
set(PIP_LIBS ${LIBS_MAIN})
|
||||
else()
|
||||
foreach(LIB_ ${LIBS_MAIN})
|
||||
pip_find_lib(${LIB_})
|
||||
endforeach()
|
||||
endif()
|
||||
foreach(LIB_ ${LIBS_MAIN})
|
||||
pip_find_lib(${LIB_})
|
||||
endforeach()
|
||||
if(WIN32)
|
||||
add_definitions(-DPSAPI_VERSION=1)
|
||||
if(${C_COMPILER} STREQUAL "cl.exe")
|
||||
@@ -372,11 +431,11 @@ else()
|
||||
if (NOT DEFINED ANDROID_PLATFORM)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
|
||||
endif()
|
||||
if(DEFINED ENV{QNX_HOST} OR PIP_FREERTOS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-32")
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
if(DEFINED ENV{QNX_HOST})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-32")
|
||||
endif()
|
||||
|
||||
set(PCRE2_BUILD_PCRE2_8 OFF CACHE BOOL "" FORCE)
|
||||
set(PCRE2_BUILD_PCRE2_16 ON CACHE BOOL "" FORCE)
|
||||
@@ -414,9 +473,7 @@ endif()
|
||||
|
||||
|
||||
if (NOT CROSSTOOLS)
|
||||
if (NOT PIP_FREERTOS)
|
||||
|
||||
if (PIP_BUILD_CONSOLE)
|
||||
if (PIP_BUILD_CONSOLE)
|
||||
pip_module(console "" "PIP console support" "" "" "")
|
||||
endif()
|
||||
|
||||
@@ -547,6 +604,9 @@ if (NOT CROSSTOOLS)
|
||||
else()
|
||||
target_compile_definitions(pip_lua PRIVATE LUA_USE_POSIX)
|
||||
endif()
|
||||
if(DEFINED PICO_SDK_PATH)
|
||||
target_compile_definitions(pip_lua PRIVATE LUA_32BITS)
|
||||
endif()
|
||||
list(APPEND HDR_DIRS "${PIP_3PL_DIR}/LuaBridge")
|
||||
list(APPEND HDRS ${_lua_src_hdr})
|
||||
endif()
|
||||
@@ -640,52 +700,36 @@ if (NOT CROSSTOOLS)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
if (PIP_BUILD_CRYPT)
|
||||
pip_module(crypt "" "PIP crypt support" "" "" "")
|
||||
endif()
|
||||
|
||||
if (PIP_BUILD_COMPRESS)
|
||||
pip_module(compress "" "PIP compression support" "" "" "")
|
||||
endif()
|
||||
|
||||
if (PIP_BUILD_IO_UTILS)
|
||||
pip_module(io_utils "pip_crypt" "PIP I/O support" "" "" " (+crypt)")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
endif()
|
||||
|
||||
string(REPLACE ";" "," PIP_EXPORTS_STR "${PIP_EXPORTS}")
|
||||
target_compile_definitions(pip PRIVATE "PICODE_DEFINES=\"${PIP_EXPORTS_STR}\"")
|
||||
|
||||
|
||||
if(NOT PIP_FREERTOS)
|
||||
|
||||
# Auxiliary
|
||||
if (NOT CROSSTOOLS)
|
||||
add_subdirectory("utils/piterminal")
|
||||
endif()
|
||||
if (NOT CROSSTOOLS AND NOT DEFINED PICO_SDK_PATH)
|
||||
add_subdirectory("utils/piterminal")
|
||||
endif()
|
||||
|
||||
# Utils
|
||||
add_subdirectory("utils/code_model_generator")
|
||||
add_subdirectory("utils/resources_compiler")
|
||||
add_subdirectory("utils/deploy_tool")
|
||||
add_subdirectory("utils/qt_support")
|
||||
add_subdirectory("utils/translator")
|
||||
add_subdirectory("utils/value_tree_translator")
|
||||
if(PIP_UTILS AND (NOT CROSSTOOLS))
|
||||
add_subdirectory("utils/system_calib")
|
||||
add_subdirectory("utils/udp_file_transfer")
|
||||
if(sodium_FOUND)
|
||||
add_subdirectory("utils/system_daemon")
|
||||
add_subdirectory("utils/crypt_tool")
|
||||
add_subdirectory("utils/cloud_dispatcher")
|
||||
endif()
|
||||
if(NOT DEFINED PICO_SDK_PATH)
|
||||
add_subdirectory("utils/code_model_generator")
|
||||
add_subdirectory("utils/resources_compiler")
|
||||
add_subdirectory("utils/deploy_tool")
|
||||
add_subdirectory("utils/qt_support")
|
||||
endif()
|
||||
if(NOT DEFINED PICO_SDK_PATH)
|
||||
add_subdirectory("utils/translator")
|
||||
add_subdirectory("utils/value_tree_translator")
|
||||
endif()
|
||||
if(PIP_UTILS AND (NOT CROSSTOOLS) AND (NOT DEFINED PICO_SDK_PATH))
|
||||
add_subdirectory("utils/system_calib")
|
||||
add_subdirectory("utils/udp_file_transfer")
|
||||
if(sodium_FOUND)
|
||||
add_subdirectory("utils/system_daemon")
|
||||
add_subdirectory("utils/crypt_tool")
|
||||
add_subdirectory("utils/cloud_dispatcher")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
@@ -739,20 +783,18 @@ if(NOT LOCAL)
|
||||
install(TARGETS ${PIP_MODULES} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
|
||||
endif()
|
||||
else()
|
||||
if(NOT PIP_FREERTOS)
|
||||
if(WIN32)
|
||||
install(TARGETS ${PIP_MODULES} RUNTIME DESTINATION bin)
|
||||
install(TARGETS ${PIP_MODULES} ARCHIVE DESTINATION lib)
|
||||
else()
|
||||
install(TARGETS ${PIP_MODULES} DESTINATION lib)
|
||||
endif()
|
||||
install(FILES ${HDRS} DESTINATION include/pip)
|
||||
if(PIP_LANG)
|
||||
install(FILES ${PIP_LANG} DESTINATION share/pip/lang)
|
||||
endif()
|
||||
if(HDR_DIRS)
|
||||
install(DIRECTORY ${HDR_DIRS} DESTINATION include/pip)
|
||||
endif()
|
||||
if(WIN32)
|
||||
install(TARGETS ${PIP_MODULES} RUNTIME DESTINATION bin)
|
||||
install(TARGETS ${PIP_MODULES} ARCHIVE DESTINATION lib)
|
||||
else()
|
||||
install(TARGETS ${PIP_MODULES} DESTINATION lib)
|
||||
endif()
|
||||
install(FILES ${HDRS} DESTINATION include/pip)
|
||||
if(PIP_LANG)
|
||||
install(FILES ${PIP_LANG} DESTINATION share/pip/lang)
|
||||
endif()
|
||||
if(HDR_DIRS)
|
||||
install(DIRECTORY ${HDR_DIRS} DESTINATION include/pip)
|
||||
endif()
|
||||
endif()
|
||||
file(GLOB CMAKES "cmake/*.cmake" "cmake/*.in")
|
||||
@@ -767,7 +809,7 @@ endif()
|
||||
#
|
||||
# Build Documentation
|
||||
#
|
||||
if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
|
||||
if (NOT CROSSTOOLS)
|
||||
include(PIPDocumentation)
|
||||
find_package(Doxygen)
|
||||
if(DOXYGEN_FOUND)
|
||||
@@ -836,9 +878,7 @@ message(" Type : ${CMAKE_BUILD_TYPE}")
|
||||
if (NOT LOCAL)
|
||||
message(" Install: \"${CMAKE_INSTALL_PREFIX}\"")
|
||||
else()
|
||||
if(NOT PIP_FREERTOS)
|
||||
message(" Install: local \"bin\", \"lib\" and \"include\"")
|
||||
endif()
|
||||
message(" Install: local \"bin\", \"lib\" and \"include\"")
|
||||
endif()
|
||||
message("")
|
||||
message(" Options:")
|
||||
@@ -846,6 +886,14 @@ message(" std::iostream: ${PIP_STD_IOSTREAM}")
|
||||
message(" ICU strings : ${PIP_ICU}")
|
||||
message(" Introspection: ${PIP_INTROSPECTION}")
|
||||
message(" Coverage : ${PIP_COVERAGE}")
|
||||
message(" Feature flags:")
|
||||
message(" PIP_HAS_FILESYSTEM: ${PIP_HAS_FILESYSTEM}")
|
||||
message(" PIP_HAS_THREADS : ${PIP_HAS_THREADS}")
|
||||
message(" PIP_HAS_SOCKET : ${PIP_HAS_SOCKET}")
|
||||
message(" PIP_HAS_PROCESS : ${PIP_HAS_PROCESS}")
|
||||
message(" PIP_HAS_DYNLIB : ${PIP_HAS_DYNLIB}")
|
||||
message(" PIP_HAS_FFT : ${PIP_HAS_FFT}")
|
||||
message(" PIP_HAS_SERIAL : ${PIP_HAS_SERIAL}")
|
||||
if(INTROSPECTION)
|
||||
message(STATUS " Warning: Introspection reduces the performance!")
|
||||
endif()
|
||||
@@ -872,17 +920,15 @@ message(" Utilites:")
|
||||
foreach(_util ${PIP_UTILS_LIST})
|
||||
message(" * ${_util}")
|
||||
endforeach()
|
||||
if(NOT PIP_FREERTOS)
|
||||
message("")
|
||||
message(" Using libraries:")
|
||||
foreach(LIB_ ${LIBS_STATUS})
|
||||
if (NOT TARGET ${LIB_})
|
||||
if(${LIB_}_FOUND)
|
||||
message(" ${LIB_} -> ${${LIB_}_LIBRARIES}")
|
||||
else()
|
||||
message(" ${LIB_} not found, may fail")
|
||||
endif()
|
||||
message("")
|
||||
message(" Using libraries:")
|
||||
foreach(LIB_ ${LIBS_STATUS})
|
||||
if (NOT TARGET ${LIB_})
|
||||
if(${LIB_}_FOUND)
|
||||
message(" ${LIB_} -> ${${LIB_}_LIBRARIES}")
|
||||
else()
|
||||
message(" ${LIB_} not found, may fail")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
message("-----------------------")
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ if (NOT BUILDING_PIP)
|
||||
find_library(PTHREAD_LIBRARY pthread)
|
||||
find_library(UTIL_LIBRARY util)
|
||||
set(_PIP_ADD_LIBS_ ${PTHREAD_LIBRARY} ${UTIL_LIBRARY})
|
||||
if((NOT DEFINED ENV{QNX_HOST}) AND (NOT APPLE) AND (NOT PIP_FREERTOS))
|
||||
if((NOT DEFINED ENV{QNX_HOST}) AND (NOT APPLE) AND (NOT PIP_EMBEDDED))
|
||||
find_library(RT_LIBRARY rt)
|
||||
list(APPEND _PIP_ADD_LIBS_ ${RT_LIBRARY})
|
||||
endif()
|
||||
|
||||
@@ -17,6 +17,7 @@ list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/thread")
|
||||
set(COMPONENT_PRIV_REQUIRES pthread lwip freertos vfs spi_flash libsodium)
|
||||
register_component()
|
||||
set(PIP_FREERTOS ON)
|
||||
set(PIP_MICRO ON)
|
||||
set(LIB OFF)
|
||||
set(INCLUDE_DIRS ${IDF_INCLUDE_DIRECTORIES})
|
||||
list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/newlib/platform_include)
|
||||
|
||||
@@ -79,7 +79,7 @@ void PIScreen::SystemConsole::begin() {
|
||||
GetConsoleMode(PRIVATE->hOut, &PRIVATE->smode);
|
||||
GetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo);
|
||||
#else
|
||||
# ifdef MICRO_PIP
|
||||
# ifdef PIP_EMBEDDED
|
||||
w = 80;
|
||||
h = 24;
|
||||
# else
|
||||
@@ -120,7 +120,7 @@ void PIScreen::SystemConsole::prepare() {
|
||||
w = PRIVATE->csbi.srWindow.Right - PRIVATE->csbi.srWindow.Left + 1;
|
||||
h = PRIVATE->csbi.srWindow.Bottom - PRIVATE->csbi.srWindow.Top + 1;
|
||||
#else
|
||||
# ifndef MICRO_PIP
|
||||
# ifndef PIP_EMBEDDED
|
||||
winsize ws;
|
||||
ioctl(0, TIOCGWINSZ, &ws);
|
||||
w = ws.ws_col;
|
||||
|
||||
@@ -20,74 +20,74 @@
|
||||
#include "piscreendrawer.h"
|
||||
|
||||
// comment for use ascii instead of unicode symbols
|
||||
#define USE_UNICODE
|
||||
# define USE_UNICODE
|
||||
|
||||
using namespace PIScreenTypes;
|
||||
|
||||
|
||||
PIScreenDrawer::PIScreenDrawer(PIVector<PIVector<Cell>> & c): cells(c) {
|
||||
arts_[LineVertical] =
|
||||
#ifdef USE_UNICODE
|
||||
# ifdef USE_UNICODE
|
||||
PIChar::fromUTF8("│");
|
||||
#else
|
||||
# else
|
||||
PIChar('|');
|
||||
#endif
|
||||
# endif
|
||||
|
||||
arts_[LineHorizontal] =
|
||||
#ifdef USE_UNICODE
|
||||
# ifdef USE_UNICODE
|
||||
PIChar::fromUTF8("─");
|
||||
#else
|
||||
# else
|
||||
PIChar('-');
|
||||
#endif
|
||||
# endif
|
||||
|
||||
arts_[Cross] =
|
||||
#ifdef USE_UNICODE
|
||||
# ifdef USE_UNICODE
|
||||
PIChar::fromUTF8("┼");
|
||||
#else
|
||||
# else
|
||||
PIChar('+');
|
||||
#endif
|
||||
# endif
|
||||
|
||||
arts_[CornerTopLeft] =
|
||||
#ifdef USE_UNICODE
|
||||
# ifdef USE_UNICODE
|
||||
PIChar::fromUTF8("┌");
|
||||
#else
|
||||
# else
|
||||
PIChar('+');
|
||||
#endif
|
||||
# endif
|
||||
|
||||
arts_[CornerTopRight] =
|
||||
#ifdef USE_UNICODE
|
||||
# ifdef USE_UNICODE
|
||||
PIChar::fromUTF8("┐");
|
||||
#else
|
||||
# else
|
||||
PIChar('+');
|
||||
#endif
|
||||
# endif
|
||||
|
||||
arts_[CornerBottomLeft] =
|
||||
#ifdef USE_UNICODE
|
||||
# ifdef USE_UNICODE
|
||||
PIChar::fromUTF8("└");
|
||||
#else
|
||||
# else
|
||||
PIChar('+');
|
||||
#endif
|
||||
# endif
|
||||
|
||||
arts_[CornerBottomRight] =
|
||||
#ifdef USE_UNICODE
|
||||
# ifdef USE_UNICODE
|
||||
PIChar::fromUTF8("┘");
|
||||
#else
|
||||
# else
|
||||
PIChar('+');
|
||||
#endif
|
||||
# endif
|
||||
|
||||
arts_[Unchecked] =
|
||||
#ifdef USE_UNICODE
|
||||
# ifdef USE_UNICODE
|
||||
PIChar::fromUTF8("☐");
|
||||
#else
|
||||
# else
|
||||
PIChar('O');
|
||||
#endif
|
||||
# endif
|
||||
|
||||
arts_[Checked] =
|
||||
#ifdef USE_UNICODE
|
||||
# ifdef USE_UNICODE
|
||||
PIChar::fromUTF8("☑");
|
||||
#else
|
||||
# else
|
||||
PIChar('0');
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
#include "piincludes_p.h"
|
||||
#include "piliterals_time.h"
|
||||
#include "pisharedmemory.h"
|
||||
#ifndef MICRO_PIP
|
||||
|
||||
|
||||
#ifdef PIP_HAS_PROCESS
|
||||
# ifdef WINDOWS
|
||||
# include <windows.h>
|
||||
# include <wingdi.h>
|
||||
@@ -346,8 +348,8 @@ void PITerminal::getCursor(int & x, int & y) {
|
||||
int sz = 0;
|
||||
PRIVATE->shm->read(&sz, 4);
|
||||
# else
|
||||
x = PRIVATE->cur_x;
|
||||
y = PRIVATE->cur_y;
|
||||
x = PRIVATE->cur_x;
|
||||
y = PRIVATE->cur_y;
|
||||
# endif
|
||||
}
|
||||
|
||||
@@ -934,7 +936,7 @@ void PITerminal::destroy() {
|
||||
}
|
||||
if (PRIVATE->pipe != INVALID_HANDLE_VALUE) CloseHandle(PRIVATE->pipe);
|
||||
if (PRIVATE->hConBuf != INVALID_HANDLE_VALUE) CloseHandle(PRIVATE->hConBuf);
|
||||
// piCout << "destroy" << size_y;
|
||||
// piCout << "destroy" << size_y;
|
||||
# else
|
||||
# ifdef HAS_FORKPTY
|
||||
if (PRIVATE->pid != 0) kill(PRIVATE->pid, SIGKILL);
|
||||
@@ -977,4 +979,6 @@ bool PITerminal::resize(int cols, int rows) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // MICRO_PIP
|
||||
#endif // PIP_HAS_PROCESS
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#include "piliterals_time.h"
|
||||
|
||||
#ifdef PIP_HAS_SOCKET
|
||||
|
||||
/** \class PIBroadcast
|
||||
* \brief Broadcast for all interfaces, including loopback
|
||||
*
|
||||
@@ -43,7 +45,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define MULTICAST_TTL 4
|
||||
# define MULTICAST_TTL 4
|
||||
|
||||
|
||||
PIBroadcast::PIBroadcast(bool send_only): PIThread(), PIEthUtilBase() {
|
||||
@@ -205,8 +207,8 @@ void PIBroadcast::initAll(PIVector<PINetworkAddress> al) {
|
||||
|
||||
void PIBroadcast::send(const PIByteArray & data) {
|
||||
/*if (!isRunning()) {
|
||||
reinit();
|
||||
PIThread::start(3000);
|
||||
reinit();
|
||||
PIThread::start(3000);
|
||||
}*/
|
||||
PIByteArray cd = cryptData(data);
|
||||
if (cd.isEmpty()) return;
|
||||
@@ -268,3 +270,5 @@ void PIBroadcast::run() {
|
||||
if (ac || r) reinit();
|
||||
if (ac) addressesChanged();
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_SOCKET
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "piethutilbase.h"
|
||||
|
||||
#ifdef PIP_HAS_SOCKET
|
||||
|
||||
#include "pitranslator.h"
|
||||
#ifdef PIP_CRYPT
|
||||
# include "picrypt.h"
|
||||
@@ -129,3 +131,5 @@ size_t PIEthUtilBase::cryptSizeAddition() {
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_SOCKET
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "piethernet.h"
|
||||
#include "piliterals.h"
|
||||
|
||||
#ifdef PIP_HAS_SOCKET
|
||||
|
||||
|
||||
/** \class PIPackedTCP pipackedtcp.h
|
||||
* \brief
|
||||
@@ -197,3 +199,5 @@ bool PIPackedTCP::closeDevice() {
|
||||
}
|
||||
return eth->close();
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_SOCKET
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "piiodevice.h"
|
||||
#include "pitranslator.h"
|
||||
|
||||
#ifdef PIP_HAS_SOCKET
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
@@ -175,3 +177,5 @@ void PIStreamPacker::assignDevice(PIIODevice * dev) {
|
||||
uint PIStreamPacker::sizeCryptedSize() {
|
||||
return sizeof(int) + (crypt_size ? cryptSizeAddition() : 0);
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_SOCKET
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
High-level log
|
||||
High-level log
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "piliterals_time.h"
|
||||
#include "pitime.h"
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
# ifdef PIP_HAS_FILESYSTEM
|
||||
|
||||
//! \class PILog pilog.h
|
||||
//! \details
|
||||
@@ -124,12 +126,12 @@ PIStringList PILog::readAllLogs() const {
|
||||
auto it = names.makeIterator();
|
||||
bool was_own = false;
|
||||
auto readFile = [&ret](PIFile * f) {
|
||||
PIIOTextStream ts(f);
|
||||
PIString line;
|
||||
while (!ts.isEnd()) {
|
||||
line = ts.readLine().trim();
|
||||
if (line.isNotEmpty()) ret << line;
|
||||
}
|
||||
PIIOTextStream ts(f);
|
||||
PIString line;
|
||||
while (!ts.isEnd()) {
|
||||
line = ts.readLine().trim();
|
||||
if (line.isNotEmpty()) ret << line;
|
||||
}
|
||||
};
|
||||
while (it.next()) {
|
||||
PIFile * f = nullptr;
|
||||
@@ -203,8 +205,8 @@ void PILog::newFile() {
|
||||
PIString aname = log_name;
|
||||
if (aname.isNotEmpty()) aname += "__";
|
||||
log_file.open(log_dir + "/" + aname + PIDateTime::current().toString("yyyy_MM_dd__hh_mm_ss") + ".log." +
|
||||
PIString::fromNumber(++part_number),
|
||||
PIIODevice::ReadWrite);
|
||||
PIString::fromNumber(++part_number),
|
||||
PIIODevice::ReadWrite);
|
||||
}
|
||||
|
||||
|
||||
@@ -245,3 +247,6 @@ void PILog::run() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# endif // PIP_HAS_FILESYSTEM
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
#include "piiostream.h"
|
||||
#include "pithread.h"
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
# ifdef PIP_HAS_FILESYSTEM
|
||||
|
||||
//! \~\ingroup Application
|
||||
//! \~\brief
|
||||
//! \~english High-level log
|
||||
@@ -184,4 +187,7 @@ private:
|
||||
int part_number = -1, cout_id = -1;
|
||||
};
|
||||
|
||||
#endif
|
||||
# endif // PIP_HAS_FILESYSTEM
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
#endif // PIlog_H
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "pisharedmemory.h"
|
||||
#include "pitime.h"
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
//! \class PISingleApplication pisingleapplication.h
|
||||
//! \~\details
|
||||
@@ -64,7 +65,7 @@
|
||||
//!
|
||||
|
||||
|
||||
#define SHM_SIZE 32_KiB
|
||||
# define SHM_SIZE 32_KiB
|
||||
|
||||
|
||||
PISingleApplication::PISingleApplication(const PIString & app_name): PIThread() {
|
||||
@@ -152,3 +153,5 @@ void PISingleApplication::waitFirst() const {
|
||||
while (!started)
|
||||
piMSleep(50);
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
class PISharedMemory;
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
//! \~\ingroup Application
|
||||
//! \~\brief
|
||||
//! \~english Single-instance application control.
|
||||
@@ -92,4 +94,5 @@ private:
|
||||
int sacnt;
|
||||
};
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
#endif // PISINGLEAPPLICATION_H
|
||||
|
||||
@@ -40,6 +40,7 @@ struct kqueue_id_t;
|
||||
# include "esp_heap_caps.h"
|
||||
#endif
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
void PISystemMonitor::ProcessStats::makeStrings() {
|
||||
physical_memsize_readable.setReadableSize(physical_memsize);
|
||||
@@ -50,43 +51,43 @@ void PISystemMonitor::ProcessStats::makeStrings() {
|
||||
}
|
||||
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
# ifdef PIP_HAS_PROCESS
|
||||
PRIVATE_DEFINITION_START(PISystemMonitor)
|
||||
# ifndef WINDOWS
|
||||
# ifdef MAC_OS
|
||||
# ifndef WINDOWS
|
||||
# ifdef MAC_OS
|
||||
PISystemTime
|
||||
# else
|
||||
# else
|
||||
llong
|
||||
# endif
|
||||
# endif
|
||||
cpu_u_cur,
|
||||
cpu_u_prev, cpu_s_cur, cpu_s_prev;
|
||||
PIString proc_dir;
|
||||
PIFile file, filem;
|
||||
# else
|
||||
# else
|
||||
HANDLE hProc;
|
||||
PROCESS_MEMORY_COUNTERS mem_cnt;
|
||||
PISystemTime tm_kernel, tm_user;
|
||||
PITimeMeasurer tm;
|
||||
# endif
|
||||
# endif
|
||||
PRIVATE_DEFINITION_END(PISystemMonitor)
|
||||
#endif
|
||||
# endif // PIP_HAS_PROCESS
|
||||
|
||||
|
||||
PISystemMonitor::PISystemMonitor(): PIThread() {
|
||||
pID_ = cycle = 0;
|
||||
cpu_count = PISystemInfo::instance()->processorsCount;
|
||||
#ifndef MICRO_PIP
|
||||
# ifndef WINDOWS
|
||||
# ifdef QNX
|
||||
# ifdef PIP_HAS_PROCESS
|
||||
# ifndef WINDOWS
|
||||
# ifdef QNX
|
||||
page_size = 4096;
|
||||
# else
|
||||
# else
|
||||
page_size = getpagesize();
|
||||
# endif
|
||||
# else
|
||||
# endif
|
||||
# else
|
||||
PRIVATE->hProc = 0;
|
||||
PRIVATE->mem_cnt.cb = sizeof(PRIVATE->mem_cnt);
|
||||
# endif
|
||||
#endif
|
||||
# endif
|
||||
# endif // PIP_HAS_PROCESS
|
||||
setName("system_monitor"_a);
|
||||
}
|
||||
|
||||
@@ -96,14 +97,14 @@ PISystemMonitor::~PISystemMonitor() {
|
||||
}
|
||||
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
# ifdef PIP_HAS_PROCESS
|
||||
bool PISystemMonitor::startOnProcess(int pID, PISystemTime interval) {
|
||||
stop();
|
||||
pID_ = pID;
|
||||
Pool::instance()->add(this);
|
||||
cycle = -1;
|
||||
# ifndef WINDOWS
|
||||
# ifndef MAC_OS
|
||||
# ifndef WINDOWS
|
||||
# ifndef MAC_OS
|
||||
PRIVATE->proc_dir = PIStringAscii("/proc/") + PIString::fromNumber(pID_) + PIStringAscii("/");
|
||||
PRIVATE->file.open(PRIVATE->proc_dir + "stat", PIIODevice::ReadOnly);
|
||||
PRIVATE->filem.open(PRIVATE->proc_dir + "statm", PIIODevice::ReadOnly);
|
||||
@@ -111,27 +112,27 @@ bool PISystemMonitor::startOnProcess(int pID, PISystemTime interval) {
|
||||
piCoutObj << "Can`t find process with ID = %1!"_tr("PISystemMonitor").arg(pID_);
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
# else
|
||||
# endif
|
||||
# else
|
||||
PRIVATE->hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pID_);
|
||||
if (PRIVATE->hProc == 0) {
|
||||
piCoutObj << "Can`t open process with ID = %1, %2!"_tr("PISystemMonitor").arg(pID_).arg(errorString());
|
||||
return false;
|
||||
}
|
||||
PRIVATE->tm.reset();
|
||||
# endif
|
||||
# endif
|
||||
return start(interval);
|
||||
}
|
||||
#endif
|
||||
# endif // PIP_HAS_PROCESS
|
||||
|
||||
|
||||
bool PISystemMonitor::startOnSelf(PISystemTime interval) {
|
||||
#ifndef MICRO_PIP
|
||||
# ifdef PIP_HAS_PROCESS
|
||||
bool ret = startOnProcess(PIProcess::currentPID(), interval);
|
||||
cycle = -1;
|
||||
#else
|
||||
# else
|
||||
bool ret = start(interval);
|
||||
#endif
|
||||
# endif // PIP_HAS_PROCESS
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -153,12 +154,12 @@ void PISystemMonitor::setStatistic(const PISystemMonitor::ProcessStats & s) {
|
||||
|
||||
void PISystemMonitor::stop() {
|
||||
PIThread::stopAndWait();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
if (PRIVATE->hProc != 0) {
|
||||
CloseHandle(PRIVATE->hProc);
|
||||
PRIVATE->hProc = 0;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
Pool::instance()->remove(this);
|
||||
}
|
||||
|
||||
@@ -169,15 +170,17 @@ PISystemMonitor::ProcessStats PISystemMonitor::statistic() const {
|
||||
}
|
||||
|
||||
|
||||
#ifdef MAC_OS
|
||||
# ifdef MAC_OS
|
||||
PISystemTime uint64toST(uint64_t v) {
|
||||
return PISystemTime(((uint *)&(v))[1], ((uint *)&(v))[0]);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
void PISystemMonitor::run() {
|
||||
cur_tm.clear();
|
||||
tbid.clear();
|
||||
ProcessStats tstat;
|
||||
tstat.ID = pID_;
|
||||
__PIThreadCollection * pitc = __PIThreadCollection::instance();
|
||||
pitc->lock();
|
||||
PIVector<PIThread *> tv = pitc->threads();
|
||||
@@ -185,16 +188,14 @@ void PISystemMonitor::run() {
|
||||
if (t->isPIObject()) tbid[t->tid()] = t->name();
|
||||
pitc->unlock();
|
||||
// piCout << tbid.keys().toType<uint>();
|
||||
ProcessStats tstat;
|
||||
tstat.ID = pID_;
|
||||
#ifdef MICRO_PIP
|
||||
# ifdef FREERTOS
|
||||
for (auto * t: tv)
|
||||
if (t->isPIObject()) gatherThread(t->tid());
|
||||
#else
|
||||
# ifndef WINDOWS
|
||||
# else // FREERTOS
|
||||
# ifndef WINDOWS
|
||||
double delay_ms = delay_.toMilliseconds();
|
||||
tbid[pID_] = "main";
|
||||
# ifdef MAC_OS
|
||||
# ifdef MAC_OS
|
||||
rusage_info_current ru;
|
||||
proc_pid_rusage(pID_, RUSAGE_INFO_CURRENT, (rusage_info_t *)&ru);
|
||||
// piCout << PISystemTime(((uint*)&(ru.ri_user_time))[1], ((uint*)&(ru.ri_user_time))[0]);
|
||||
@@ -210,7 +211,7 @@ void PISystemMonitor::run() {
|
||||
tstat.cpu_load_user = 100.f * (PRIVATE->cpu_u_cur - PRIVATE->cpu_u_prev).toMilliseconds() / delay_ms;
|
||||
cycle = 0;
|
||||
// piCout << (PRIVATE->cpu_u_cur - PRIVATE->cpu_u_prev).toMilliseconds() / delay_ms;
|
||||
# else
|
||||
# else // MAC_OS
|
||||
PRIVATE->file.seekToBegin();
|
||||
PIString str = PIString::fromAscii(PRIVATE->file.readAll());
|
||||
int si = str.find('(') + 1, fi = 0, cc = 1;
|
||||
@@ -264,8 +265,8 @@ void PISystemMonitor::run() {
|
||||
if (i.flags[PIFile::FileInfo::Dot] || i.flags[PIFile::FileInfo::DotDot]) continue;
|
||||
gatherThread(i.name().toInt());
|
||||
}
|
||||
# endif
|
||||
# else
|
||||
# endif // MAC_OS
|
||||
# else // WINDOWS
|
||||
if (GetProcessMemoryInfo(PRIVATE->hProc, &PRIVATE->mem_cnt, sizeof(PRIVATE->mem_cnt)) != 0) {
|
||||
tstat.physical_memsize = PRIVATE->mem_cnt.WorkingSetSize;
|
||||
}
|
||||
@@ -315,8 +316,8 @@ void PISystemMonitor::run() {
|
||||
tstat.cpu_load_user = 0.f;
|
||||
}
|
||||
PRIVATE->tm.reset();
|
||||
# endif
|
||||
#endif
|
||||
# endif // WINDOWS
|
||||
# endif // FREERTOS
|
||||
|
||||
tstat.cpu_load_system = piClampf(tstat.cpu_load_system, 0.f, 100.f);
|
||||
tstat.cpu_load_user = piClampf(tstat.cpu_load_user, 0.f, 100.f);
|
||||
@@ -349,11 +350,11 @@ void PISystemMonitor::gatherThread(llong id) {
|
||||
PISystemMonitor::ThreadStats ts;
|
||||
if (id == 0) return;
|
||||
ts.id = id;
|
||||
#ifdef MICRO_PIP
|
||||
# ifndef PIP_HAS_PROCESS
|
||||
ts.name = tbid.value(id, "<PIThread>");
|
||||
#else
|
||||
# else
|
||||
ts.name = tbid.value(id, "<non-PIThread>");
|
||||
# ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
PIFile f(PRIVATE->proc_dir + "task/" + PIString::fromNumber(id) + "/stat");
|
||||
// piCout << f.path();
|
||||
if (!f.open(PIIODevice::ReadOnly)) return;
|
||||
@@ -373,7 +374,7 @@ void PISystemMonitor::gatherThread(llong id) {
|
||||
// piCout << sl[0] << sl[12] << sl[13];
|
||||
ts.user_time = PISystemTime::fromMilliseconds(sl[12].toInt() * 10.);
|
||||
ts.kernel_time = PISystemTime::fromMilliseconds(sl[13].toInt() * 10.);
|
||||
# else
|
||||
# else
|
||||
PISystemTime ct = PISystemTime::current();
|
||||
FILETIME times[4];
|
||||
HANDLE thdl = OpenThread(THREAD_QUERY_INFORMATION, FALSE, DWORD(id));
|
||||
@@ -391,8 +392,8 @@ void PISystemMonitor::gatherThread(llong id) {
|
||||
ts.work_time = ct - ts.created.toSystemTime();
|
||||
ts.kernel_time = FILETIME2PISystemTime(times[2]);
|
||||
ts.user_time = FILETIME2PISystemTime(times[3]);
|
||||
# endif
|
||||
#endif
|
||||
# endif
|
||||
# endif // PIP_HAS_PROCESS
|
||||
cur_tm[id] = ts;
|
||||
}
|
||||
|
||||
@@ -404,34 +405,34 @@ float PISystemMonitor::calcThreadUsage(PISystemTime & t_new, PISystemTime & t_ol
|
||||
|
||||
|
||||
ullong PISystemMonitor::totalRAM() {
|
||||
#ifdef ESP_PLATFORM
|
||||
# ifdef ESP_PLATFORM
|
||||
multi_heap_info_t heap_info;
|
||||
piZeroMemory(heap_info);
|
||||
heap_caps_get_info(&heap_info, MALLOC_CAP_8BIT);
|
||||
return heap_info.total_allocated_bytes + heap_info.total_free_bytes;
|
||||
#endif
|
||||
# endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ullong PISystemMonitor::freeRAM() {
|
||||
#ifdef ESP_PLATFORM
|
||||
# ifdef ESP_PLATFORM
|
||||
multi_heap_info_t heap_info;
|
||||
piZeroMemory(heap_info);
|
||||
heap_caps_get_info(&heap_info, MALLOC_CAP_8BIT);
|
||||
return heap_info.total_free_bytes;
|
||||
#endif
|
||||
# endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ullong PISystemMonitor::usedRAM() {
|
||||
#ifdef ESP_PLATFORM
|
||||
# ifdef ESP_PLATFORM
|
||||
multi_heap_info_t heap_info;
|
||||
piZeroMemory(heap_info);
|
||||
heap_caps_get_info(&heap_info, MALLOC_CAP_8BIT);
|
||||
return heap_info.total_allocated_bytes;
|
||||
#endif
|
||||
# endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -458,3 +459,5 @@ void PISystemMonitor::Pool::remove(PISystemMonitor * sm) {
|
||||
PIMutexLocker _ml(mutex);
|
||||
sysmons.remove(sm->pID());
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "pifile.h"
|
||||
#include "pithread.h"
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
//! \~\ingroup Application
|
||||
//! \~\brief
|
||||
@@ -51,7 +52,7 @@ public:
|
||||
//! \~russian Останавливает мониторинг и отсоединяет объект от текущей цели.
|
||||
~PISystemMonitor();
|
||||
|
||||
#pragma pack(push, 1)
|
||||
# pragma pack(push, 1)
|
||||
//! \~\ingroup Application
|
||||
//! \~\brief
|
||||
//! \~english Process statistics (fixed-size fields).
|
||||
@@ -155,7 +156,7 @@ public:
|
||||
//! \~russian Дата и время создания
|
||||
PIDateTime created;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
# pragma pack(pop)
|
||||
|
||||
//! \~\ingroup Application
|
||||
//! \~\brief
|
||||
@@ -205,12 +206,12 @@ public:
|
||||
PIString name;
|
||||
};
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
# ifdef PIP_HAS_PROCESS
|
||||
|
||||
//! \~english Starts monitoring the process with PID "pID" using the given update interval.
|
||||
//! \~russian Запускает мониторинг процесса с PID "pID" с указанным интервалом обновления.
|
||||
bool startOnProcess(int pID, PISystemTime interval = PISystemTime::fromSeconds(1.));
|
||||
#endif
|
||||
# endif // PIP_HAS_PROCESS
|
||||
|
||||
//! \~english Starts monitoring the current application process.
|
||||
//! \~russian Запускает мониторинг текущего процесса приложения.
|
||||
@@ -271,9 +272,9 @@ private:
|
||||
PIMap<llong, PIString> tbid;
|
||||
mutable PIMutex stat_mutex;
|
||||
int pID_, page_size, cpu_count, cycle;
|
||||
#ifndef MICRO_PIP
|
||||
# ifdef PIP_HAS_PROCESS
|
||||
PRIVATE_DECLARATION(PIP_EXPORT)
|
||||
#endif
|
||||
# endif // PIP_HAS_PROCESS
|
||||
|
||||
class PIP_EXPORT Pool {
|
||||
friend class PISystemMonitor;
|
||||
@@ -337,4 +338,5 @@ BINARY_STREAM_READ(PISystemMonitor::ThreadStats) {
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
#endif // PISYSTEMMONITOR_H
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Translation support
|
||||
Translation support
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "pitranslator_p.h"
|
||||
#include "pivaluetree_conversions.h"
|
||||
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
|
||||
//! \class PITranslator pitranslator.h
|
||||
//! \details
|
||||
@@ -64,9 +65,9 @@ void PITranslator::loadLang(const PIString & short_lang, PIString dir) {
|
||||
auto vt = PIValueTreeConversions::fromText(getBuiltinConfig());
|
||||
auto lang = vt.child(short_lang.toLowerCase().trim());
|
||||
for (const auto & cn: lang.children()) {
|
||||
auto c = s->PRIVATEWB->content.createContext(cn.name());
|
||||
for (const auto & s: cn.children())
|
||||
c->add(s.name(), s.value().toString());
|
||||
auto c = s->PRIVATEWB->content.createContext(cn.name());
|
||||
for (const auto & s: cn.children())
|
||||
c->add(s.name(), s.value().toString());
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -114,3 +115,5 @@ PITranslator * PITranslator::instance() {
|
||||
static PITranslator ret;
|
||||
return &ret;
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
@@ -153,6 +153,7 @@ bool PICodeParser::isEnum(const PIString & name) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
bool PICodeParser::parseFileInternal(const PIString & file, bool follow_includes) {
|
||||
if (proc_files[file]) return true;
|
||||
with_includes = follow_includes;
|
||||
@@ -178,6 +179,7 @@ bool PICodeParser::parseFileInternal(const PIString & file, bool follow_includes
|
||||
piCout << "parsing" << f.path() << "done";
|
||||
return ret;
|
||||
}
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
|
||||
void PICodeParser::clear() {
|
||||
|
||||
@@ -18,9 +18,11 @@
|
||||
*/
|
||||
#include "pikbdlistener.h"
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "piliterals.h"
|
||||
#include "piwaitevent_p.h"
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
# include "piincludes_p.h"
|
||||
# include "piliterals.h"
|
||||
# include "piwaitevent_p.h"
|
||||
// clang-format off
|
||||
#ifndef WINDOWS
|
||||
# include <termios.h>
|
||||
@@ -49,7 +51,7 @@ bool PIKbdListener::exiting;
|
||||
PIKbdListener * PIKbdListener::_object = 0;
|
||||
|
||||
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
// unix
|
||||
const PIKbdListener::EscSeq PIKbdListener::esc_seq[] = {
|
||||
{"OA", PIKbdListener::UpArrow, 0, 0, 1},
|
||||
@@ -130,22 +132,22 @@ void setupTerminal(bool on) {
|
||||
printf(on ? "h" : "l");
|
||||
fflush(0);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
|
||||
PRIVATE_DEFINITION_START(PIKbdListener)
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
void *hIn, *hOut;
|
||||
DWORD smode, tmode;
|
||||
CONSOLE_SCREEN_BUFFER_INFO sbi;
|
||||
#else
|
||||
# else
|
||||
struct termios sterm, tterm;
|
||||
#endif
|
||||
#ifdef WINDOWS
|
||||
# endif
|
||||
# ifdef WINDOWS
|
||||
DWORD
|
||||
#else
|
||||
# else
|
||||
int
|
||||
#endif
|
||||
# endif
|
||||
ret;
|
||||
PIWaitEvent event;
|
||||
PRIVATE_DEFINITION_END(PIKbdListener)
|
||||
@@ -154,13 +156,13 @@ PRIVATE_DEFINITION_END(PIKbdListener)
|
||||
PIKbdListener::PIKbdListener(KBFunc slot, void * _d, bool startNow): PIThread() {
|
||||
setName("keyboard_listener"_a);
|
||||
_object = this;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
PRIVATE->hIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
PRIVATE->hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
GetConsoleMode(PRIVATE->hIn, &PRIVATE->smode);
|
||||
#else
|
||||
# else
|
||||
tcgetattr(0, &PRIVATE->sterm);
|
||||
#endif
|
||||
# endif
|
||||
ret_func = slot;
|
||||
kbddata_ = _d;
|
||||
dbl_interval = 400;
|
||||
@@ -178,10 +180,10 @@ PIKbdListener::~PIKbdListener() {
|
||||
|
||||
|
||||
void PIKbdListener::begin() {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
GetConsoleMode(PRIVATE->hIn, &PRIVATE->tmode);
|
||||
SetConsoleMode(PRIVATE->hIn, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS);
|
||||
#else
|
||||
# else
|
||||
struct termios term;
|
||||
tcgetattr(0, &term);
|
||||
term.c_lflag &= ~(ECHO | ICANON);
|
||||
@@ -189,11 +191,11 @@ void PIKbdListener::begin() {
|
||||
PRIVATE->tterm = term;
|
||||
tcsetattr(0, TCSANOW, &term);
|
||||
setupTerminal(true);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
PIKbdListener::KeyModifiers getModifiers(DWORD v, bool * shift = 0) {
|
||||
PIKbdListener::KeyModifiers ret;
|
||||
bool ctrl = v & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED);
|
||||
@@ -214,7 +216,7 @@ PIKbdListener::MouseButtons getButtons(DWORD v) {
|
||||
if (v & FROM_LEFT_2ND_BUTTON_PRESSED) ret |= PIKbdListener::MouseMiddle;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
|
||||
void PIKbdListener::readKeyboard() {
|
||||
@@ -222,7 +224,7 @@ void PIKbdListener::readKeyboard() {
|
||||
ke.modifiers = 0;
|
||||
char rc[8];
|
||||
piZeroMemory(rc, 8);
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
INPUT_RECORD ir;
|
||||
ReadConsoleInput(PRIVATE->hIn, &ir, 1, &(PRIVATE->ret));
|
||||
switch (ir.EventType) {
|
||||
@@ -406,7 +408,7 @@ void PIKbdListener::readKeyboard() {
|
||||
} break;
|
||||
default: piMSleep(10); return;
|
||||
}
|
||||
#else
|
||||
# else
|
||||
tcsetattr(0, TCSANOW, &PRIVATE->tterm);
|
||||
if (!PRIVATE->event.wait(0)) return;
|
||||
PRIVATE->ret = read(0, rc, 8);
|
||||
@@ -533,7 +535,7 @@ void PIKbdListener::readKeyboard() {
|
||||
cout << endl;*/
|
||||
}
|
||||
if (ke.key == 0 && PRIVATE->ret > 1) ke.key = PIChar::fromSystem(rc).unicode16Code();
|
||||
#endif
|
||||
# endif
|
||||
if ((rc[0] == '\n' || rc[0] == '\r') && PRIVATE->ret == 1) ke.key = Return;
|
||||
if (exit_enabled && ke.key == exit_key) {
|
||||
PIKbdListener::exiting = true;
|
||||
@@ -560,30 +562,32 @@ bool PIKbdListener::stopAndWait(PISystemTime timeout) {
|
||||
|
||||
void PIKbdListener::end() {
|
||||
// cout << "list end" << endl;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
SetConsoleMode(PRIVATE->hIn, PRIVATE->smode);
|
||||
#else
|
||||
# else
|
||||
tcsetattr(0, TCSANOW, &PRIVATE->sterm);
|
||||
setupTerminal(false);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void PIKbdListener::setActive(bool yes) {
|
||||
is_active = yes;
|
||||
if (is_active) {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
SetConsoleMode(PRIVATE->hIn, PRIVATE->tmode);
|
||||
#else
|
||||
# else
|
||||
tcsetattr(0, TCSANOW, &PRIVATE->tterm);
|
||||
setupTerminal(true);
|
||||
#endif
|
||||
# endif
|
||||
} else {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
SetConsoleMode(PRIVATE->hIn, PRIVATE->smode);
|
||||
#else
|
||||
# else
|
||||
tcsetattr(0, TCSANOW, &PRIVATE->sterm);
|
||||
setupTerminal(false);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
@@ -25,18 +25,22 @@
|
||||
#ifndef PIKBDLISTENER_H
|
||||
#define PIKBDLISTENER_H
|
||||
|
||||
#include "pithread.h"
|
||||
#include "pitime.h"
|
||||
#include "pibase.h"
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
# include "pithread.h"
|
||||
# include "pitime.h"
|
||||
|
||||
//! \relatesalso PIKbdListener
|
||||
//! \~\brief
|
||||
//! \~english Waits until the active listener captures the configured exit key and then stops it.
|
||||
//! \~russian Ожидает, пока активный слушатель перехватит настроенную клавишу выхода, и затем останавливает его.
|
||||
#define WAIT_FOR_EXIT \
|
||||
while (!PIKbdListener::exiting) \
|
||||
piMSleep(PIP_MIN_MSLEEP * 5); \
|
||||
if (PIKbdListener::instance()) { \
|
||||
if (!PIKbdListener::instance()->stopAndWait(PISystemTime::fromSeconds(1))) PIKbdListener::instance()->terminate(); \
|
||||
# define WAIT_FOR_EXIT \
|
||||
while (!PIKbdListener::exiting) \
|
||||
piMSleep(PIP_MIN_MSLEEP * 5); \
|
||||
if (PIKbdListener::instance()) { \
|
||||
if (!PIKbdListener::instance()->stopAndWait(PISystemTime::fromSeconds(1))) PIKbdListener::instance()->terminate(); \
|
||||
}
|
||||
|
||||
|
||||
@@ -303,7 +307,7 @@ private:
|
||||
void run() override { readKeyboard(); }
|
||||
void end() override;
|
||||
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
struct PIP_EXPORT EscSeq {
|
||||
const char * seq;
|
||||
int key;
|
||||
@@ -323,7 +327,7 @@ private:
|
||||
};
|
||||
|
||||
static const EscSeq esc_seq[];
|
||||
#endif
|
||||
# endif
|
||||
|
||||
PRIVATE_DECLARATION(PIP_EXPORT)
|
||||
KBFunc ret_func;
|
||||
@@ -377,4 +381,5 @@ REGISTER_PIVARIANTSIMPLE(PIKbdListener::KeyEvent)
|
||||
REGISTER_PIVARIANTSIMPLE(PIKbdListener::MouseEvent)
|
||||
REGISTER_PIVARIANTSIMPLE(PIKbdListener::WheelEvent)
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
#endif // PIKBDLISTENER_H
|
||||
|
||||
@@ -177,14 +177,14 @@ private:
|
||||
void showCursor();
|
||||
void clearScreen();
|
||||
void clearScreenLower();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
void getWinCurCoord();
|
||||
void clearLine();
|
||||
void newLine();
|
||||
ushort attributes(const PIScreenTypes::Cell & c);
|
||||
#else
|
||||
# else
|
||||
PIString formatString(const PIScreenTypes::Cell & c);
|
||||
#endif
|
||||
# endif
|
||||
PRIVATE_DECLARATION(PIP_CONSOLE_EXPORT)
|
||||
int width, height, pwidth, pheight;
|
||||
int mouse_x, mouse_y;
|
||||
|
||||
@@ -163,8 +163,10 @@ public:
|
||||
bool visible;
|
||||
|
||||
protected:
|
||||
//! \~english Returns the preferred tile size in \a w and \a h. The base implementation derives it from visible children, spacing, and margins.
|
||||
//! \~russian Возвращает предпочтительный размер тайла в \a w и \a h. Базовая реализация вычисляет его по видимым дочерним тайлам, интервалам и отступам.
|
||||
//! \~english Returns the preferred tile size in \a w and \a h. The base implementation derives it from visible children, spacing, and
|
||||
//! margins.
|
||||
//! \~russian Возвращает предпочтительный размер тайла в \a w и \a h. Базовая реализация вычисляет его по видимым дочерним тайлам,
|
||||
//! интервалам и отступам.
|
||||
virtual void sizeHint(int & w, int & h) const;
|
||||
|
||||
//! \~english Called after the tile size changes to \a w by \a h during layout.
|
||||
@@ -208,7 +210,8 @@ protected:
|
||||
void layout();
|
||||
|
||||
//! \~english Returns whether this tile should participate in automatic layout. Tiles with policy \a PIScreenTypes::Ignore are skipped.
|
||||
//! \~russian Возвращает, должен ли тайл участвовать в автоматической компоновке. Тайлы с политикой \a PIScreenTypes::Ignore пропускаются.
|
||||
//! \~russian Возвращает, должен ли тайл участвовать в автоматической компоновке. Тайлы с политикой \a PIScreenTypes::Ignore
|
||||
//! пропускаются.
|
||||
bool needLayout() { return size_policy != PIScreenTypes::Ignore; }
|
||||
|
||||
//! \~english Owned direct child tiles.
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
|
||||
//! \~english Macro is defined when PIP is building for embedded systems
|
||||
//! \~russian Макрос объявлен когда PIP собирается для встраиваемых систем
|
||||
# define MICRO_PIP
|
||||
# define PIP_EMBEDDED
|
||||
|
||||
//! \~english Macro is defined when compiler is Visual Studio
|
||||
//! \~russian Макрос объявлен когда компилятор Visual Studio
|
||||
@@ -168,9 +168,6 @@
|
||||
//! \~russian Макрос для подавления предупреждения компилятора о неиспользуемой переменной
|
||||
# define NO_UNUSED(x)
|
||||
|
||||
# undef MICRO_PIP
|
||||
# undef FREERTOS
|
||||
|
||||
#endif // DOXYGEN
|
||||
|
||||
#ifdef WINDOWS
|
||||
@@ -223,10 +220,49 @@ extern char ** environ;
|
||||
# define assertm(exp, msg) assert(((void)msg, exp))
|
||||
# endif
|
||||
|
||||
# ifdef MICRO_PIP
|
||||
# define __PIP_TYPENAME__(T) "?"
|
||||
# ifndef __has_feature
|
||||
# define __has_feature(x) 0 // Default to 0 if the compiler doesn't support it
|
||||
# endif
|
||||
|
||||
# if defined(__cpp_rtti) || defined(__GXX_RTTI) || defined(_CPPRTTI) || (__has_feature(cxx_rtti))
|
||||
# define PIP_HAS_RTTI 1
|
||||
# else
|
||||
# define PIP_HAS_RTTI 0
|
||||
# endif
|
||||
|
||||
# if PIP_HAS_RTTI
|
||||
# define __PIP_TYPENAME__(T) typeid(T).name()
|
||||
# else
|
||||
template<typename T>
|
||||
inline const char * __pip_typename__() {
|
||||
static_assert(false, "this type must declare typename via __PIP_TYPENAME_DECLARE");
|
||||
return "?";
|
||||
}
|
||||
|
||||
# define __PIP_TYPENAME_DECLARE(T, NAME) \
|
||||
template<> \
|
||||
inline const char * __pip_typename__<T>() { \
|
||||
return NAME; \
|
||||
}
|
||||
|
||||
__PIP_TYPENAME_DECLARE(bool, "bool")
|
||||
__PIP_TYPENAME_DECLARE(char, "char")
|
||||
__PIP_TYPENAME_DECLARE(signed char, "signed char")
|
||||
__PIP_TYPENAME_DECLARE(unsigned char, "unsigned char")
|
||||
__PIP_TYPENAME_DECLARE(short, "short")
|
||||
__PIP_TYPENAME_DECLARE(unsigned short, "unsigned short")
|
||||
__PIP_TYPENAME_DECLARE(int, "int")
|
||||
__PIP_TYPENAME_DECLARE(unsigned int, "unsigned int")
|
||||
__PIP_TYPENAME_DECLARE(long, "long")
|
||||
__PIP_TYPENAME_DECLARE(unsigned long, "unsigned long")
|
||||
__PIP_TYPENAME_DECLARE(long long, "long long")
|
||||
__PIP_TYPENAME_DECLARE(unsigned long long, "unsigned long long")
|
||||
__PIP_TYPENAME_DECLARE(float, "float")
|
||||
__PIP_TYPENAME_DECLARE(double, "double")
|
||||
__PIP_TYPENAME_DECLARE(long double, "long double")
|
||||
__PIP_TYPENAME_DECLARE(void, "void")
|
||||
|
||||
# define __PIP_TYPENAME__(T) __pip_typename__<T>()
|
||||
# endif
|
||||
|
||||
# ifdef CC_GCC
|
||||
@@ -390,21 +426,6 @@ typedef long long ssize_t;
|
||||
_PIP_ADD_COUNTER(_pip_initializer_);
|
||||
|
||||
|
||||
//! \~english Minimal sleep in milliseconds for internal PIP using
|
||||
//! \~russian Минимальное значание задержки в милисекундах для внутреннего использования в библиотеке PIP
|
||||
//! \~\details
|
||||
//! \~english Using in \a piMinSleep(), \a PIThread, \a PITimer::Pool. By default 1ms.
|
||||
//! \~russian Используется в \a piMinSleep(), \a PIThread, \a PITimer::Pool. По умолчанию равна 1мс.
|
||||
//! \~\sa PIP_MIN_MSLEEP
|
||||
#ifndef PIP_MIN_MSLEEP
|
||||
# ifndef MICRO_PIP
|
||||
# define PIP_MIN_MSLEEP 1.
|
||||
# else
|
||||
# define PIP_MIN_MSLEEP 10.
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
//! \~english Macro used for infinite loop
|
||||
//! \~russian Макрос для бесконечного цикла
|
||||
//! \~\details
|
||||
@@ -427,5 +448,18 @@ typedef long long ssize_t;
|
||||
//! \~\sa FOREVER_WAIT
|
||||
#define WAIT_FOREVER FOREVER piMinSleep();
|
||||
|
||||
//! \~english Minimal sleep in milliseconds for internal PIP using
|
||||
//! \~russian Минимальное значание задержки в милисекундах для внутреннего использования в библиотеке PIP
|
||||
//! \~\details
|
||||
//! \~english Using in \a piMinSleep(), \a PIThread, \a PITimer::Pool. By default 1ms.
|
||||
//! \~russian Используется в \a piMinSleep(), \a PIThread, \a PITimer::Pool. По умолчанию равна 1мс.
|
||||
//! \~\sa PIP_MIN_MSLEEP
|
||||
#ifndef PIP_MIN_MSLEEP
|
||||
# ifdef PIP_EMBEDDED
|
||||
# define PIP_MIN_MSLEEP 10.
|
||||
# else
|
||||
# define PIP_MIN_MSLEEP 1.
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif // PIBASE_MACROS_H
|
||||
|
||||
+28
-26
@@ -367,7 +367,7 @@ void PICout::stdoutPIString(const PIString & str, PICoutStdStream s) {
|
||||
#ifdef HAS_LOCALE
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf8conv;
|
||||
getStdStream(s) << utf8conv.to_bytes((char16_t *)&(const_cast<PIString &>(str).front()),
|
||||
(char16_t *)&(const_cast<PIString &>(str).front()) + str.size());
|
||||
(char16_t *)&(const_cast<PIString &>(str).front()) + str.size());
|
||||
#else
|
||||
for (PIChar c: str)
|
||||
getStdWStream(s).put(c.toWChar());
|
||||
@@ -409,32 +409,32 @@ void PICout::writeChar(char c) {
|
||||
}
|
||||
|
||||
|
||||
#define PIINTCOUT(v) \
|
||||
{ \
|
||||
if (!actve_) return *this; \
|
||||
space(); \
|
||||
if (int_base_ == 10) { \
|
||||
if (buffer_) { \
|
||||
(*buffer_) += PIString::fromNumber(v); \
|
||||
} else { \
|
||||
if (isOutputDeviceActive(Console)) getStdStream(stream_) << (v); \
|
||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIString::fromNumber(v); \
|
||||
} \
|
||||
} else \
|
||||
write(PIString::fromNumber(v, int_base_)); \
|
||||
return *this; \
|
||||
}
|
||||
#define PIINTCOUT(v) \
|
||||
{ \
|
||||
if (!actve_) return *this; \
|
||||
space(); \
|
||||
if (int_base_ == 10) { \
|
||||
if (buffer_) { \
|
||||
(*buffer_) += PIString::fromNumber(v); \
|
||||
} else { \
|
||||
if (isOutputDeviceActive(Console)) getStdStream(stream_) << (v); \
|
||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIString::fromNumber(v); \
|
||||
} \
|
||||
} else \
|
||||
write(PIString::fromNumber(v, int_base_)); \
|
||||
return *this; \
|
||||
}
|
||||
|
||||
#define PIFLOATCOUT(v) \
|
||||
{ \
|
||||
if (buffer_) { \
|
||||
(*buffer_) += PIString::fromNumber(v, 'g'); \
|
||||
} else { \
|
||||
if (isOutputDeviceActive(Console)) getStdStream(stream_) << (v); \
|
||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIString::fromNumber(v, 'g'); \
|
||||
} \
|
||||
} \
|
||||
return *this;
|
||||
#define PIFLOATCOUT(v) \
|
||||
{ \
|
||||
if (buffer_) { \
|
||||
(*buffer_) += PIString::fromNumber(v, 'g'); \
|
||||
} else { \
|
||||
if (isOutputDeviceActive(Console)) getStdStream(stream_) << (v); \
|
||||
if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIString::fromNumber(v, 'g'); \
|
||||
} \
|
||||
} \
|
||||
return *this;
|
||||
|
||||
|
||||
PICout & PICout::operator<<(const PIString & v) {
|
||||
@@ -709,6 +709,7 @@ void PICout::applyFormat(PICoutFormat f) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
PIString PICout::getBuffer() {
|
||||
PIMutexLocker ml(PICout::__mutex__());
|
||||
PIString ret = PICout::__string__();
|
||||
@@ -728,6 +729,7 @@ void PICout::clearBuffer() {
|
||||
PIMutexLocker ml(PICout::__mutex__());
|
||||
PICout::__string__().clear();
|
||||
}
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
|
||||
bool PICout::setOutputDevice(PICout::OutputDevice d, bool on) {
|
||||
|
||||
@@ -41,9 +41,9 @@ class PIString;
|
||||
class PIByteArray;
|
||||
template<typename P>
|
||||
class PIBinaryStream;
|
||||
#ifndef MICRO_PIP
|
||||
#ifndef _PIP_INIT_STUB_
|
||||
class PIInit;
|
||||
#endif
|
||||
#endif // _PIP_INIT_STUB_
|
||||
class PIChar;
|
||||
class PICout;
|
||||
class PIWaitEvent;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "piinit.h"
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#ifndef MICRO_PIP
|
||||
#ifndef _PIP_INIT_STUB_
|
||||
|
||||
# include "pidir.h"
|
||||
# include "piobject.h"
|
||||
@@ -251,7 +251,7 @@ PIInit::PIInit() {
|
||||
PIStringAscii("FreeBSD");
|
||||
# elif defined(FREERTOS)
|
||||
PIStringAscii("FreeRTOS");
|
||||
# elif defined(MICRO_PIP)
|
||||
# elif defined(_PIP_INIT_STUB_)
|
||||
PIStringAscii("MicroPIP");
|
||||
# else
|
||||
uns.sysname;
|
||||
@@ -395,4 +395,4 @@ __PIInit_Initializer__::~__PIInit_Initializer__() {
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MICRO_PIP
|
||||
#endif // _PIP_INIT_STUB_
|
||||
|
||||
+33
-2
@@ -31,13 +31,19 @@
|
||||
|
||||
#include "pibase.h"
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
// PIInit stub: enabled for embedded or when core features are missing
|
||||
#if defined(PIP_EMBEDDED) || (!defined(PIP_HAS_THREADS) && !defined(PIP_HAS_FILESYSTEM))
|
||||
# define _PIP_INIT_STUB_
|
||||
#endif
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
# include "piincludes.h"
|
||||
|
||||
|
||||
class PIFile;
|
||||
class PIStringList;
|
||||
class PIInit;
|
||||
|
||||
class PIP_EXPORT __PIInit_Initializer__ {
|
||||
public:
|
||||
@@ -49,6 +55,31 @@ public:
|
||||
|
||||
static __PIInit_Initializer__ __piinit_initializer__;
|
||||
|
||||
# ifdef _PIP_INIT_STUB_
|
||||
# ifndef PIINIT_MICRO_STUB_DEFINED
|
||||
# define PIINIT_MICRO_STUB_DEFINED
|
||||
|
||||
int __PIInit_Initializer__::count_ = 0;
|
||||
PIInit * __PIInit_Initializer__::__instance__ = nullptr;
|
||||
|
||||
__PIInit_Initializer__::__PIInit_Initializer__() {
|
||||
count_++;
|
||||
if (count_ > 1) return;
|
||||
__instance__ = nullptr;
|
||||
}
|
||||
|
||||
__PIInit_Initializer__::~__PIInit_Initializer__() {
|
||||
count_--;
|
||||
if (count_ > 0) return;
|
||||
if (__instance__ != nullptr) {
|
||||
__instance__ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
# endif
|
||||
# endif
|
||||
|
||||
|
||||
//! \~\ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Library initialization singleton and build information access point.
|
||||
@@ -96,5 +127,5 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif // MICRO_PIP
|
||||
#endif // PIP_HAS_THREADS
|
||||
#endif // PIINIT_H
|
||||
|
||||
@@ -19,12 +19,13 @@
|
||||
|
||||
#include "piobject.h"
|
||||
|
||||
#include "piconditionvar.h"
|
||||
#include "pithread.h"
|
||||
#ifndef MICRO_PIP
|
||||
#include "pitime.h"
|
||||
#ifdef PIP_HAS_THREADS
|
||||
# include "piconditionvar.h"
|
||||
# include "pifile.h"
|
||||
# include "piiostream.h"
|
||||
# include "pisysteminfo.h"
|
||||
# include "pithread.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -463,7 +464,7 @@ void PIObject::piDisconnect(PIObject * src, const PIString & sig) {
|
||||
src->connections.remove(i);
|
||||
i--;
|
||||
if (dest) {
|
||||
#if !defined(ANDROID) && !defined(MAC_OS) && !defined(MICRO_PIP)
|
||||
#if !defined(ANDROID) && !defined(MAC_OS) && defined(PIP_HAS_THREADS)
|
||||
PIMutexLocker _mld(dest->mutex_connect, src != dest);
|
||||
#endif
|
||||
dest->updateConnectors();
|
||||
@@ -481,7 +482,7 @@ void PIObject::piDisconnectAll() {
|
||||
// piCout << "disconnect"<< src << o;
|
||||
if (!o || (o == this)) continue;
|
||||
if (!o->isPIObject()) continue;
|
||||
#if !defined(ANDROID) && !defined(MAC_OS) && !defined(MICRO_PIP)
|
||||
#if !defined(ANDROID) && !defined(MAC_OS) && defined(PIP_HAS_THREADS)
|
||||
PIMutexLocker _mld(o->mutex_connect, this != o);
|
||||
#endif
|
||||
PIVector<Connection> & oc(o->connections);
|
||||
@@ -569,9 +570,11 @@ void PIObject::callQueuedEvents() {
|
||||
//! При первом вызове стартует фоновый поток для удаления объектов.
|
||||
//! Каждый объект из очереди удаляется только когда выйдет из всех
|
||||
//! событий и обработок.
|
||||
#ifdef PIP_HAS_THREADS
|
||||
void PIObject::deleteLater() {
|
||||
Deleter::instance()->post(this);
|
||||
}
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
|
||||
bool PIObject::findSuitableMethodV(const PIString & method, int args, int & ret_args, PIObject::__MetaFunc & ret) {
|
||||
@@ -721,8 +724,7 @@ void PIObject::dump(const PIString & line_prefix) const {
|
||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << src << " -> " << dst->className() << " (" << c.dest
|
||||
<< ", \"" << dst->name() << "\")::" << hf_fn;
|
||||
} else {
|
||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << src << " -> "
|
||||
<< "[lambda]";
|
||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << src << " -> " << "[lambda]";
|
||||
}
|
||||
}
|
||||
// printf("dump %d connections ok\n",connections.size());
|
||||
@@ -731,7 +733,7 @@ void PIObject::dump(const PIString & line_prefix) const {
|
||||
}
|
||||
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
#ifdef PIP_HAS_THREADS
|
||||
void dumpApplication(bool with_objects) {
|
||||
PIMutexLocker _ml(PIObject::mutexObjects());
|
||||
// printf("dump application ...\n");
|
||||
@@ -834,7 +836,7 @@ bool PIObject::Connection::disconnect() const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
PRIVATE_DEFINITION_START(PIObject::Deleter)
|
||||
PIThread thread;
|
||||
PIConditionVariable cond_var;
|
||||
@@ -898,3 +900,4 @@ void PIObject::Deleter::deleteObject(PIObject * o) {
|
||||
}
|
||||
// piCout << "[Deleter] delete" << (uintptr_t)o << "done";
|
||||
}
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
//! требует явного опустошения очереди через \a callQueuedEvents() или
|
||||
//! \a maybeCallQueuedEvents().
|
||||
class PIP_EXPORT PIObject {
|
||||
#ifndef MICRO_PIP
|
||||
#ifndef PIP_INTROSPECTION
|
||||
friend class PIObjectManager;
|
||||
friend PIP_EXPORT void dumpApplication(bool);
|
||||
friend class PIIntrospection;
|
||||
@@ -796,6 +796,7 @@ private:
|
||||
PIVector<PIVariantSimple> values;
|
||||
};
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
class Deleter {
|
||||
public:
|
||||
Deleter();
|
||||
@@ -807,6 +808,7 @@ private:
|
||||
void deleteObject(PIObject * o);
|
||||
PRIVATE_DECLARATION(PIP_EXPORT)
|
||||
};
|
||||
#endif
|
||||
|
||||
bool findSuitableMethodV(const PIString & method, int args, int & ret_args, __MetaFunc & ret);
|
||||
PIVector<__MetaFunc> findEH(const PIString & name) const;
|
||||
@@ -830,13 +832,13 @@ private:
|
||||
PIMap<uint, PIVariant> properties_;
|
||||
PISet<PIObject *> connectors;
|
||||
PIVector<__QueuedEvent> events_queue;
|
||||
PIMutex mutex_, mutex_connect, mutex_queue;
|
||||
PIObject * emitter_;
|
||||
bool thread_safe_, proc_event_queue;
|
||||
std::atomic_int in_event_cnt;
|
||||
PIMutex mutex_, mutex_connect, mutex_queue;
|
||||
bool thread_safe_ = false, proc_event_queue = false;
|
||||
};
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
//! \~english Dumps application-level %PIObject diagnostics.
|
||||
//! \~russian Выводит диагностическую информацию уровня приложения для %PIObject.
|
||||
|
||||
@@ -18,18 +18,19 @@
|
||||
*/
|
||||
|
||||
#include "piwaitevent_p.h"
|
||||
#ifdef WINDOWS
|
||||
#ifdef PIP_HAS_THREADS
|
||||
# ifdef WINDOWS
|
||||
// # ifdef _WIN32_WINNT
|
||||
// # undef _WIN32_WINNT
|
||||
// # define _WIN32_WINNT 0x0600
|
||||
// # endif
|
||||
# include <synchapi.h>
|
||||
#else
|
||||
# include <errno.h>
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
#include "pistring.h"
|
||||
# include <synchapi.h>
|
||||
# else
|
||||
# include <errno.h>
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# endif
|
||||
# include "pistring.h"
|
||||
|
||||
|
||||
PIWaitEvent::~PIWaitEvent() {
|
||||
@@ -39,12 +40,12 @@ PIWaitEvent::~PIWaitEvent() {
|
||||
|
||||
void PIWaitEvent::create() {
|
||||
destroy();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
event = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
if (!event) {
|
||||
piCout << "Error with CreateEventA:" << errorString();
|
||||
}
|
||||
#else
|
||||
# else
|
||||
for (int i = 0; i < 3; ++i)
|
||||
piZeroMemory(fds[i]);
|
||||
if (::pipe(pipe_fd) < 0) {
|
||||
@@ -53,34 +54,34 @@ void PIWaitEvent::create() {
|
||||
fcntl(pipe_fd[ReadEnd], F_SETFL, O_NONBLOCK);
|
||||
fcntl(pipe_fd[WriteEnd], F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void PIWaitEvent::destroy() {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
if (event) {
|
||||
CloseHandle(event);
|
||||
event = NULL;
|
||||
}
|
||||
#else
|
||||
# else
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (pipe_fd[i] != -1) {
|
||||
::close(pipe_fd[i]);
|
||||
pipe_fd[i] = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
bool PIWaitEvent::wait(int fd, CheckRole role) {
|
||||
if (!isCreate()) return false;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
DWORD ret = WaitForSingleObjectEx(event, INFINITE, TRUE);
|
||||
ResetEvent(event);
|
||||
if (ret == WAIT_IO_COMPLETION || ret == WAIT_FAILED) return false;
|
||||
#else
|
||||
# else
|
||||
if (fd == -1) return false;
|
||||
int nfds = piMaxi(pipe_fd[ReadEnd], fd) + 1;
|
||||
int fd_index = role;
|
||||
@@ -98,18 +99,18 @@ bool PIWaitEvent::wait(int fd, CheckRole role) {
|
||||
if (errno == EBADF || errno == EINTR) return false;
|
||||
if (FD_ISSET(fd, &(fds[CheckExeption]))) return true;
|
||||
return FD_ISSET(fd, &(fds[fd_index]));
|
||||
#endif
|
||||
# endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIWaitEvent::sleep(int us) {
|
||||
if (!isCreate()) return false;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
DWORD ret = WaitForSingleObjectEx(event, us / 1000, TRUE);
|
||||
ResetEvent(event);
|
||||
return ret == WAIT_TIMEOUT;
|
||||
#else
|
||||
# else
|
||||
int nfds = pipe_fd[ReadEnd] + 1;
|
||||
FD_ZERO(&(fds[CheckRead]));
|
||||
FD_SET(pipe_fd[ReadEnd], &(fds[CheckRead]));
|
||||
@@ -121,34 +122,36 @@ bool PIWaitEvent::sleep(int us) {
|
||||
while (::read(pipe_fd[ReadEnd], &buf, sizeof(buf)) > 0)
|
||||
;
|
||||
return ret == 0;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void PIWaitEvent::interrupt() {
|
||||
if (!isCreate()) return;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
SetEvent(event);
|
||||
#else
|
||||
# else
|
||||
auto _r = ::write(pipe_fd[WriteEnd], "", 1);
|
||||
NO_UNUSED(_r);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
bool PIWaitEvent::isCreate() const {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
return event;
|
||||
#else
|
||||
# else
|
||||
return pipe_fd[ReadEnd] != -1;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void * PIWaitEvent::getEvent() const {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
return event;
|
||||
#else
|
||||
# else
|
||||
return nullptr;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
#ifndef PIWAITEVENT_P_H
|
||||
#define PIWAITEVENT_P_H
|
||||
|
||||
#include "pibase.h"
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
# include "pibase.h"
|
||||
// clang-format off
|
||||
#ifdef WINDOWS
|
||||
# include <stdarg.h>
|
||||
@@ -52,17 +54,18 @@ public:
|
||||
void * getEvent() const; // WINDOWS only
|
||||
|
||||
private:
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
void * event = nullptr;
|
||||
#else
|
||||
# else
|
||||
int pipe_fd[2] = {-1, -1};
|
||||
fd_set fds[3];
|
||||
enum {
|
||||
ReadEnd = 0,
|
||||
WriteEnd = 1
|
||||
};
|
||||
#endif
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
#endif // PIWAITEVENT_P_H
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
enum CoordinateSystem {
|
||||
Unknown = 0 /** \~english Unknown coordinate system \~russian Неизвестная система координат */,
|
||||
Geodetic /** \~english Geodetic latitude, longitude and height above the ellipsoid \~russian Геодезическая широта, долгота и высота
|
||||
над эллипсоидом */
|
||||
над эллипсоидом */
|
||||
,
|
||||
Geocentric /** \~english Geocentric latitude, longitude and radius \~russian Геоцентрическая широта, долгота и радиус */,
|
||||
Cartesian /** \~english Earth-centered Earth-fixed Cartesian coordinates \~russian Декартовы координаты ECEF */,
|
||||
@@ -381,4 +381,9 @@ inline PIGeoPosition operator*(const PIGeoPosition & left, const int & scale) {
|
||||
return operator*(double(scale), left);
|
||||
}
|
||||
|
||||
|
||||
#if !PIP_HAS_RTTI
|
||||
__PIP_TYPENAME_DECLARE(PIGeoPosition, "PIGeoPosition")
|
||||
#endif
|
||||
|
||||
#endif // PIGEOPOSITION_H
|
||||
|
||||
@@ -19,10 +19,12 @@
|
||||
|
||||
#include "piintrospection_server_p.h"
|
||||
|
||||
#include "pichunkstream.h"
|
||||
#include "piinit.h"
|
||||
#include "piobject.h"
|
||||
#include "pisysteminfo.h"
|
||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
|
||||
# include "pichunkstream.h"
|
||||
# include "piinit.h"
|
||||
# include "piobject.h"
|
||||
# include "pisysteminfo.h"
|
||||
|
||||
|
||||
const uint PIIntrospection::sign = 0x0F1C2B3A;
|
||||
@@ -111,9 +113,9 @@ PIByteArray PIIntrospection::packContainers() {
|
||||
PIByteArray ret;
|
||||
PIVector<PIIntrospectionContainers::TypeInfo> data;
|
||||
PIIntrospectionContainers * p = 0;
|
||||
#ifdef PIP_INTROSPECTION
|
||||
# ifdef PIP_INTROSPECTION
|
||||
p = PIINTROSPECTION_CONTAINERS->p;
|
||||
#endif
|
||||
# endif
|
||||
if (p) {
|
||||
data = p->getInfo();
|
||||
}
|
||||
@@ -131,9 +133,9 @@ void PIIntrospection::unpackContainers(PIByteArray & ba, PIVector<PIIntrospectio
|
||||
PIByteArray PIIntrospection::packThreads() {
|
||||
PIByteArray ret;
|
||||
PIIntrospectionThreads * p = 0;
|
||||
#ifdef PIP_INTROSPECTION
|
||||
# ifdef PIP_INTROSPECTION
|
||||
p = PIINTROSPECTION_THREADS->p;
|
||||
#endif
|
||||
# endif
|
||||
if (p) {
|
||||
p->mutex.lock();
|
||||
PIMap<PIThread *, PIIntrospectionThreads::ThreadInfo> & tm(p->threads);
|
||||
@@ -170,3 +172,5 @@ void PIIntrospection::unpackObjects(PIByteArray & ba, PIVector<PIIntrospection::
|
||||
objects.clear();
|
||||
ba >> objects;
|
||||
}
|
||||
|
||||
#endif // #if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "piintrospection_threads_p.h"
|
||||
#include "pisystemmonitor.h"
|
||||
|
||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
|
||||
class PIP_EXPORT PIIntrospection {
|
||||
public:
|
||||
@@ -168,4 +169,5 @@ BINARY_STREAM_READ(PIIntrospection::ObjectInfo) {
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif // #if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
#endif // PIINTROSPECTION_SERVER_P_H
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "piintrospection_threads_p.h"
|
||||
|
||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
|
||||
PIIntrospectionThreads::ThreadInfo::ThreadInfo() {
|
||||
id = delay = 0;
|
||||
@@ -78,3 +79,5 @@ void PIIntrospectionThreads::threadRunDone(PIThread * t, ullong us) {
|
||||
ThreadInfo & ti(threads[t]);
|
||||
ti.run_us = (ti.run_us * 0.8) + (us * 0.2); /// WARNING
|
||||
}
|
||||
|
||||
#endif // #if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
#ifndef PIINTROSPECTION_THREADS_P_H
|
||||
#define PIINTROSPECTION_THREADS_P_H
|
||||
|
||||
#include "pibase.h"
|
||||
|
||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
|
||||
#include "pimap.h"
|
||||
#include "pithread.h"
|
||||
|
||||
@@ -68,4 +72,5 @@ BINARY_STREAM_READ(PIIntrospectionThreads::ThreadInfo) {
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif // #if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
#endif // PIINTROSPECTION_THREADS_P_H
|
||||
|
||||
@@ -23,10 +23,12 @@
|
||||
#include "piliterals_bytes.h"
|
||||
#include "piliterals_time.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "pitime.h"
|
||||
#include "pitranslator.h"
|
||||
|
||||
#define PIBINARYLOG_VERSION_OLD 0x31
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
# include "pitime.h"
|
||||
# include "pitranslator.h"
|
||||
|
||||
# define PIBINARYLOG_VERSION_OLD 0x31
|
||||
|
||||
/*! \class PIBinaryLog
|
||||
* \brief Class for read and write binary data to logfile, and playback this data in realtime, or custom speed
|
||||
@@ -52,17 +54,17 @@
|
||||
|
||||
static const uchar binlog_sig[] = {'B', 'I', 'N', 'L', 'O', 'G'};
|
||||
|
||||
#define PIBINARYLOG_VERSION 0x32
|
||||
#define PIBINARYLOG_SIGNATURE_SIZE sizeof(binlog_sig)
|
||||
# define PIBINARYLOG_VERSION 0x32
|
||||
# define PIBINARYLOG_SIGNATURE_SIZE sizeof(binlog_sig)
|
||||
|
||||
REGISTER_DEVICE(PIBinaryLog)
|
||||
|
||||
PIBinaryLog::PIBinaryLog() {
|
||||
#ifdef MICRO_PIP
|
||||
# ifndef PIP_HAS_THREADS
|
||||
setThreadedReadBufferSize(512);
|
||||
#else
|
||||
# else
|
||||
setThreadedReadBufferSize(64_KiB);
|
||||
#endif
|
||||
# endif // PIP_HAS_THREADS
|
||||
is_started = is_indexed = is_pause = false;
|
||||
create_index_on_fly = false;
|
||||
current_index = -1;
|
||||
@@ -1008,3 +1010,5 @@ void PIBinaryLog::CompleteIndex::makeIndexPos() {
|
||||
for (uint i = 0; i < index.size(); i++)
|
||||
index_pos[index[i].pos] = i;
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "pichunkstream.h"
|
||||
#include "pifile.h"
|
||||
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
|
||||
//! \~english Class for writing and reading binary data to/from log files, with support for playback in different modes.
|
||||
//! \~russian Класс для записи и чтения бинарных данных в/из файлов логов с поддержкой воспроизведения в различных режимах.
|
||||
//! \~\details
|
||||
@@ -79,7 +81,7 @@ public:
|
||||
,
|
||||
};
|
||||
|
||||
#pragma pack(push, 8)
|
||||
# pragma pack(push, 8)
|
||||
|
||||
//! \~english Statistics for records sharing the same record ID.
|
||||
//! \~russian Статистика по записям с одинаковым идентификатором.
|
||||
@@ -141,7 +143,7 @@ public:
|
||||
PISystemTime timestamp;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
# pragma pack(pop)
|
||||
|
||||
//! \~english Summary information about a log file and its indexed record types.
|
||||
//! \~russian Сводная информация о файле лога и его индексированных типах записей.
|
||||
@@ -591,7 +593,7 @@ public:
|
||||
//! \~russian Возвращает пользовательский заголовок, сохраненный в текущем открытом логе.
|
||||
PIByteArray getHeader() const;
|
||||
|
||||
#ifdef DOXYGEN
|
||||
# ifdef DOXYGEN
|
||||
//! \~english Reads one message using \a filterID when it is not empty.
|
||||
//! \~russian Читает одно сообщение, используя \a filterID, если он не пуст.
|
||||
int read(void * read_to, int max_size);
|
||||
@@ -599,7 +601,7 @@ public:
|
||||
//! \~english Writes one record using \a defaultID().
|
||||
//! \~russian Записывает одну запись, используя \a defaultID().
|
||||
int write(const void * data, int size);
|
||||
#endif
|
||||
# endif
|
||||
|
||||
//! \~english Optional list of record IDs accepted by \a read() and threaded playback.
|
||||
//! \~russian Необязательный список идентификаторов записей, допустимых для \a read() и потокового воспроизведения.
|
||||
@@ -991,4 +993,5 @@ inline PICout operator<<(PICout s, const PIBinaryLog::BinLogInfo & bi) {
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
#endif // PIBINARYLOG_H
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "pipropertystorage.h"
|
||||
#include "piwaitevent_p.h"
|
||||
#if !defined(WINDOWS) && !defined(MAC_OS) && !defined(MICRO_PIP)
|
||||
#if !defined(WINDOWS) && !defined(MAC_OS) && defined(PIP_HAS_SOCKET)
|
||||
# define PIP_CAN
|
||||
#endif
|
||||
#ifdef PIP_CAN
|
||||
@@ -40,25 +40,29 @@
|
||||
|
||||
REGISTER_DEVICE(PICAN)
|
||||
|
||||
|
||||
#ifdef PIP_CAN
|
||||
PRIVATE_DEFINITION_START(PICAN)
|
||||
PIWaitEvent event;
|
||||
PRIVATE_DEFINITION_END(PICAN)
|
||||
|
||||
#endif
|
||||
|
||||
PICAN::PICAN(const PIString & path, PIIODevice::DeviceMode mode): PIIODevice(path, mode) {
|
||||
setThreadedReadBufferSize(256);
|
||||
setPath(path);
|
||||
#ifdef PIP_CAN
|
||||
can_id = 0;
|
||||
sock = -1;
|
||||
PRIVATE->event.create();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PICAN::~PICAN() {
|
||||
stopAndWait();
|
||||
close();
|
||||
#ifdef PIP_CAN
|
||||
PRIVATE->event.destroy();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +184,9 @@ int PICAN::readedCANID() const {
|
||||
|
||||
|
||||
void PICAN::interrupt() {
|
||||
#ifdef PIP_CAN
|
||||
PRIVATE->event.interrupt();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -288,6 +288,7 @@ PIConfig::PIConfig(PIIODevice * device, PIIODevice::DeviceMode mode) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
PIConfig::PIConfig(const PIString & path, PIStringList dirs) {
|
||||
_init();
|
||||
internal = true;
|
||||
@@ -311,6 +312,7 @@ PIConfig::PIConfig(const PIString & path, PIStringList dirs) {
|
||||
_setupDev();
|
||||
parse();
|
||||
}
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
|
||||
PIConfig::~PIConfig() {
|
||||
@@ -319,6 +321,7 @@ PIConfig::~PIConfig() {
|
||||
}
|
||||
|
||||
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
bool PIConfig::open(const PIString & path, PIIODevice::DeviceMode mode) {
|
||||
_destroy();
|
||||
incdirs << PIFile::fileInfo(path).dir();
|
||||
@@ -329,6 +332,7 @@ bool PIConfig::open(const PIString & path, PIIODevice::DeviceMode mode) {
|
||||
parse();
|
||||
return dev->isOpened();
|
||||
}
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
|
||||
bool PIConfig::open(PIString * string, PIIODevice::DeviceMode mode) {
|
||||
@@ -347,7 +351,9 @@ bool PIConfig::open(PIIODevice * device, PIIODevice::DeviceMode mode) {
|
||||
dev = device;
|
||||
if (dev) {
|
||||
dev->open(mode);
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
if (dev->isTypeOf<PIFile>()) incdirs << PIFile::fileInfo(((PIFile *)dev)->path()).dir();
|
||||
#endif
|
||||
}
|
||||
_setupDev();
|
||||
parse();
|
||||
@@ -383,10 +389,12 @@ void PIConfig::_setupDev() {
|
||||
|
||||
void PIConfig::_clearDev() {
|
||||
if (!dev) return;
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
if (PIString(dev->className()) == "PIFile") {
|
||||
((PIFile *)dev)->clear();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (PIString(dev->className()) == "PIIOString") {
|
||||
((PIIOString *)dev)->clear();
|
||||
((PIIOString *)dev)->setMode(PIIODevice::WriteOnly);
|
||||
@@ -397,9 +405,11 @@ void PIConfig::_clearDev() {
|
||||
|
||||
void PIConfig::_flushDev() {
|
||||
if (!dev) return;
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
if (PIString(dev->className()) == "PIFile") {
|
||||
((PIFile *)dev)->flush();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -411,10 +421,12 @@ bool PIConfig::_isEndDev() {
|
||||
|
||||
void PIConfig::_seekToBeginDev() {
|
||||
if (!dev) return;
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
if (PIString(dev->className()) == "PIFile") {
|
||||
((PIFile *)dev)->seekToBegin();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (PIString(dev->className()) == "PIIOString") {
|
||||
((PIIOString *)dev)->seekToBegin();
|
||||
((PIIOString *)dev)->setMode(PIIODevice::ReadOnly);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
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/>.
|
||||
*/
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
#include "pidir.h"
|
||||
|
||||
#include "piincludes_p.h"
|
||||
@@ -611,3 +612,4 @@ void PIDir::CurrentDirOverrider::save(const PIFile::FileInfo & info) {
|
||||
else
|
||||
PIDir::setCurrent(PIDir::current().path() + PIDir::separator + p);
|
||||
}
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "piregularexpression.h"
|
||||
|
||||
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
//! \~\ingroup IO
|
||||
//! \~\brief
|
||||
//! \~english Local directory.
|
||||
@@ -217,8 +218,10 @@ private:
|
||||
|
||||
PIString path_, scan_;
|
||||
};
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
inline bool operator<(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {
|
||||
return (v0.path < v1.path);
|
||||
}
|
||||
@@ -242,6 +245,7 @@ inline PICout operator<<(PICout s, const PIDir & v) {
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
|
||||
#endif // PIDIR_H
|
||||
|
||||
+176
-173
@@ -18,64 +18,65 @@
|
||||
*/
|
||||
#include "piethernet.h"
|
||||
|
||||
#include "piconfig.h"
|
||||
#include "piconstchars.h"
|
||||
#include "piincludes_p.h"
|
||||
#include "piliterals.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "pisysteminfo.h"
|
||||
#include "pitranslator.h"
|
||||
// clang-format off
|
||||
#ifdef QNX
|
||||
# include <arpa/inet.h>
|
||||
# include <fcntl.h>
|
||||
# include <hw/nicinfo.h>
|
||||
# include <ifaddrs.h>
|
||||
# include <net/if.h>
|
||||
# include <net/if_dl.h>
|
||||
# include <netdb.h>
|
||||
# include <netinet/in.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/time.h>
|
||||
# include <sys/types.h>
|
||||
# ifdef BLACKBERRY
|
||||
# include <netinet/in.h>
|
||||
# else
|
||||
# include <sys/dcmd_io-net.h>
|
||||
# endif
|
||||
# define ip_mreqn ip_mreq
|
||||
# define imr_address imr_interface
|
||||
#else
|
||||
# ifdef WINDOWS
|
||||
# include <io.h>
|
||||
# include <winsock2.h>
|
||||
# include <iphlpapi.h>
|
||||
# include <psapi.h>
|
||||
# include <ws2tcpip.h>
|
||||
# define ip_mreqn ip_mreq
|
||||
# define imr_address imr_interface
|
||||
# else
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <netinet/in.h>
|
||||
# include <netinet/tcp.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netdb.h>
|
||||
# include <net/if.h>
|
||||
# if !defined(ANDROID) && !defined(LWIP)
|
||||
# include <ifaddrs.h>
|
||||
# endif
|
||||
# ifdef LWIP
|
||||
# include <lwip/sockets.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
// clang-format on
|
||||
#include "piwaitevent_p.h"
|
||||
#ifdef PIP_HAS_SOCKET
|
||||
|
||||
#include <errno.h>
|
||||
# include "piconfig.h"
|
||||
# include "piconstchars.h"
|
||||
# include "piincludes_p.h"
|
||||
# include "piliterals.h"
|
||||
# include "pipropertystorage.h"
|
||||
# include "pisysteminfo.h"
|
||||
# include "pitranslator.h"
|
||||
|
||||
# ifdef QNX
|
||||
# include <arpa/inet.h>
|
||||
# include <fcntl.h>
|
||||
# include <hw/nicinfo.h>
|
||||
# include <ifaddrs.h>
|
||||
# include <net/if.h>
|
||||
# include <net/if_dl.h>
|
||||
# include <netdb.h>
|
||||
# include <netinet/in.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/time.h>
|
||||
# include <sys/types.h>
|
||||
# ifdef BLACKBERRY
|
||||
# include <netinet/in.h>
|
||||
# else
|
||||
# include <sys/dcmd_io-net.h>
|
||||
# endif
|
||||
# define ip_mreqn ip_mreq
|
||||
# define imr_address imr_interface
|
||||
# else
|
||||
# ifdef WINDOWS
|
||||
# include <io.h>
|
||||
# include <iphlpapi.h>
|
||||
# include <psapi.h>
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
# define ip_mreqn ip_mreq
|
||||
# define imr_address imr_interface
|
||||
# else
|
||||
# include <arpa/inet.h>
|
||||
# include <fcntl.h>
|
||||
# include <net/if.h>
|
||||
# include <netdb.h>
|
||||
# include <netinet/in.h>
|
||||
# include <netinet/tcp.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/socket.h>
|
||||
# if !defined(ANDROID) && !defined(LWIP)
|
||||
# include <ifaddrs.h>
|
||||
# endif
|
||||
# ifdef LWIP
|
||||
# include <lwip/sockets.h>
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# include "piwaitevent_p.h"
|
||||
|
||||
# include <errno.h>
|
||||
|
||||
|
||||
/** \class PIEthernet piethernet.h
|
||||
@@ -100,7 +101,7 @@
|
||||
*
|
||||
* */
|
||||
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
PIString getSockAddr(sockaddr * s) {
|
||||
if (!s) return PIString();
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
@@ -108,7 +109,7 @@ PIString getSockAddr(sockaddr * s) {
|
||||
const char * r = inet_ntop(AF_INET, &((sockaddr_in *)s)->sin_addr, buf, sizeof(buf));
|
||||
return r ? PIStringAscii(r) : PIString();
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
|
||||
REGISTER_DEVICE(PIEthernet)
|
||||
@@ -200,11 +201,11 @@ void PIEthernet::construct() {
|
||||
setMulticastTTL(1);
|
||||
server_thread_.setData(this);
|
||||
server_thread_.setName("_S.tcpserver"_a);
|
||||
#ifdef MICRO_PIP
|
||||
# ifdef LWIP
|
||||
setThreadedReadBufferSize(512);
|
||||
#else
|
||||
# else
|
||||
setThreadedReadBufferSize(64_KiB);
|
||||
#endif
|
||||
# endif
|
||||
// setPriority(piHigh);
|
||||
}
|
||||
|
||||
@@ -308,9 +309,9 @@ bool PIEthernet::openDevice() {
|
||||
PRIVATE->addr_.sin_addr.s_addr = INADDR_ANY;
|
||||
else
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
#ifdef QNX
|
||||
# ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
#endif
|
||||
# endif
|
||||
// piCout << "bind to" << (params[PIEthernet::Broadcast] ? "255.255.255.255" : ip_) << ":" << port_ << " ...";
|
||||
int tries = 0;
|
||||
while ((bind(sock, (sockaddr *)&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == -1) && (tries < 2)) {
|
||||
@@ -384,13 +385,13 @@ void PIEthernet::applyBuffers() {
|
||||
void PIEthernet::applyTimeout(int fd, int opt, PISystemTime tm) {
|
||||
if (fd == 0) return;
|
||||
// piCoutObj << "setReadIsBlocking" << yes;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
DWORD _tm = tm.toMilliseconds();
|
||||
#else
|
||||
# else
|
||||
timeval _tm;
|
||||
_tm.tv_sec = tm.seconds;
|
||||
_tm.tv_usec = tm.nanoseconds / 1000;
|
||||
#endif
|
||||
# endif
|
||||
ethSetsockopt(fd, SOL_SOCKET, opt, &_tm, sizeof(_tm));
|
||||
}
|
||||
|
||||
@@ -415,30 +416,30 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
return true;
|
||||
}
|
||||
addr_r.set(path());
|
||||
#ifndef LWIP
|
||||
# ifndef LWIP
|
||||
struct ip_mreqn mreq;
|
||||
#else
|
||||
# else
|
||||
struct ip_mreq mreq;
|
||||
#endif
|
||||
# endif
|
||||
piZeroMemory(mreq);
|
||||
#ifdef LINUX
|
||||
# ifdef LINUX
|
||||
// mreq.imr_address.s_addr = INADDR_ANY;
|
||||
/*PIEthernet::InterfaceList il = interfaces();
|
||||
const PIEthernet::Interface * ci = il.getByAddress(addr_r.ipString());
|
||||
if (ci != 0) mreq.imr_ifindex = ci->index;*/
|
||||
#endif
|
||||
# endif
|
||||
if (params[PIEthernet::Broadcast])
|
||||
#ifndef LWIP
|
||||
# ifndef LWIP
|
||||
mreq.imr_address.s_addr = INADDR_ANY;
|
||||
#else
|
||||
# else
|
||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||
#endif
|
||||
# endif
|
||||
else
|
||||
#ifndef LWIP
|
||||
# ifndef LWIP
|
||||
mreq.imr_address.s_addr = addr_r.ip();
|
||||
#else
|
||||
# else
|
||||
mreq.imr_interface.s_addr = addr_r.ip();
|
||||
#endif
|
||||
# endif
|
||||
|
||||
// piCout << "join group" << group << "ip" << ip_ << "with index" << mreq.imr_ifindex << "socket" << sock;
|
||||
mreq.imr_multiaddr.s_addr = inet_addr(group.dataAscii());
|
||||
@@ -461,24 +462,24 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
||||
return false;
|
||||
}
|
||||
addr_r.set(path());
|
||||
#ifndef LWIP
|
||||
# ifndef LWIP
|
||||
struct ip_mreqn mreq;
|
||||
#else
|
||||
# else
|
||||
struct ip_mreq mreq;
|
||||
#endif
|
||||
# endif
|
||||
piZeroMemory(mreq);
|
||||
if (params[PIEthernet::Broadcast])
|
||||
#ifndef LWIP
|
||||
# ifndef LWIP
|
||||
mreq.imr_address.s_addr = INADDR_ANY;
|
||||
#else
|
||||
# else
|
||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||
#endif
|
||||
# endif
|
||||
else
|
||||
#ifndef LWIP
|
||||
# ifndef LWIP
|
||||
mreq.imr_address.s_addr = addr_r.ip();
|
||||
#else
|
||||
# else
|
||||
mreq.imr_interface.s_addr = addr_r.ip();
|
||||
#endif
|
||||
# endif
|
||||
mreq.imr_multiaddr.s_addr = inet_addr(group.dataAscii());
|
||||
if (ethSetsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) {
|
||||
piCoutObj << "Can`t leave multicast group" << group << "," << ethErrorString();
|
||||
@@ -502,9 +503,9 @@ bool PIEthernet::connect(bool threaded) {
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
# ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
#endif
|
||||
# endif
|
||||
connecting_ = true;
|
||||
connected_ = connectTCP();
|
||||
connecting_ = false;
|
||||
@@ -540,9 +541,9 @@ bool PIEthernet::listen(bool threaded) {
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
# ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
#endif
|
||||
# endif
|
||||
opened_ = false;
|
||||
int tries = 0;
|
||||
while ((bind(sock, (sockaddr *)&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == -1) && (tries < 2)) {
|
||||
@@ -666,9 +667,9 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
# ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
#endif
|
||||
# endif
|
||||
// piCoutObj << "connect to " << path() << "...";
|
||||
connected_ = connectTCP();
|
||||
// piCoutObj << "connect to " << path() << connected_;
|
||||
@@ -683,7 +684,7 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
}
|
||||
if (!connected_) return -1;
|
||||
errorClear();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
{
|
||||
long wr = waitForEvent(PRIVATE->event, FD_READ | FD_CLOSE);
|
||||
switch (wr) {
|
||||
@@ -699,34 +700,34 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
# else
|
||||
if (PRIVATE->event.wait(sock)) {
|
||||
errorClear();
|
||||
rs = ethRecv(sock, read_to, max_size);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
// piCoutObj << "readed" << rs;
|
||||
if (rs <= 0) {
|
||||
lerr = ethErrorCore();
|
||||
// piCoutObj << "readed" << rs << "error" << lerr;
|
||||
|
||||
// async normal returns
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
if (lerr == WSAEWOULDBLOCK) {
|
||||
#else
|
||||
# else
|
||||
if (lerr == EWOULDBLOCK || lerr == EAGAIN || lerr == EINTR) {
|
||||
#endif
|
||||
# endif
|
||||
// piCoutObj << "Ignore would_block" << lerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// if no disconnect on timeout
|
||||
if (!params[DisonnectOnTimeout]) {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
if (lerr == WSAETIMEDOUT) {
|
||||
#else
|
||||
# else
|
||||
if (lerr == ETIMEDOUT) {
|
||||
#endif
|
||||
# endif
|
||||
// piCoutObj << "Ignore read timeout";
|
||||
return -1;
|
||||
}
|
||||
@@ -750,7 +751,7 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
case UDP: {
|
||||
piZeroMemory(PRIVATE->raddr_);
|
||||
// piCoutObj << "read from" << path() << "...";
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
long wr = waitForEvent(PRIVATE->event, FD_READ | FD_CLOSE);
|
||||
switch (wr) {
|
||||
case FD_READ:
|
||||
@@ -763,9 +764,9 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
#else
|
||||
# else
|
||||
rs = ethRecvfrom(sock, read_to, max_size, 0, (sockaddr *)&PRIVATE->raddr_);
|
||||
#endif
|
||||
# endif
|
||||
// piCoutObj << "read from" << path() << rs << "bytes";
|
||||
if (rs > 0) {
|
||||
addr_lr.set(uint(PRIVATE->raddr_.sin_addr.s_addr), ntohs(PRIVATE->raddr_.sin_port));
|
||||
@@ -798,11 +799,11 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
return ethSendto(sock_s,
|
||||
data,
|
||||
max_size,
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
isOptionSet(BlockingWrite) ? 0 : MSG_DONTWAIT
|
||||
#else
|
||||
# else
|
||||
0
|
||||
#endif
|
||||
# endif
|
||||
,
|
||||
(sockaddr *)&PRIVATE->saddr_,
|
||||
sizeof(PRIVATE->saddr_));
|
||||
@@ -814,9 +815,9 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
# ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
#endif
|
||||
# endif
|
||||
// piCoutObj << "connect to " << ip << ":" << port_;
|
||||
connected_ = connectTCP();
|
||||
if (!connected_) piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
@@ -852,11 +853,11 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
int sr = ::send(sock, remain_data, remain_size, 0);
|
||||
if (sr < 0) {
|
||||
int err = ethErrorCore();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
if (err == WSAEWOULDBLOCK) {
|
||||
#else
|
||||
# else
|
||||
if (err == EAGAIN || err == EWOULDBLOCK) {
|
||||
#endif
|
||||
# endif
|
||||
piMinSleep();
|
||||
// piCoutObj << "wait for write";
|
||||
continue;
|
||||
@@ -916,30 +917,30 @@ void PIEthernet::server_func(void * eth) {
|
||||
}
|
||||
sockaddr_in client_addr;
|
||||
socklen_t slen = sizeof(client_addr);
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
long wr = ce->waitForEvent(ce->PRIVATEWB->event, FD_ACCEPT | FD_CLOSE);
|
||||
if (wr != FD_ACCEPT) {
|
||||
piMSleep(10);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
# else
|
||||
if (!ce->PRIVATEWB->event.wait(ce->sock)) {
|
||||
piMSleep(10);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
// piCout << "server" << "accept ...";
|
||||
int s = accept(ce->sock, (sockaddr *)&client_addr, &slen);
|
||||
// piCout << "server" << "accept done" << ethErrorString();
|
||||
if (s == -1) {
|
||||
int lerr = ethErrorCore();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
if (lerr == WSAETIMEDOUT) {
|
||||
#elif defined(ANDROID)
|
||||
# elif defined(ANDROID)
|
||||
if ((lerr == EAGAIN || lerr == EINTR)) {
|
||||
#else
|
||||
# else
|
||||
if (lerr == EAGAIN) {
|
||||
#endif
|
||||
# endif
|
||||
piMSleep(10);
|
||||
return;
|
||||
}
|
||||
@@ -975,7 +976,7 @@ void PIEthernet::setType(Type t, bool reopen) {
|
||||
bool PIEthernet::connectTCP() {
|
||||
::connect(sock, (sockaddr *)&(PRIVATE->addr_), sizeof(PRIVATE->addr_));
|
||||
// piCout << errorString();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
long wr = waitForEvent(PRIVATE->event, FD_CONNECT | FD_CLOSE);
|
||||
switch (wr) {
|
||||
case FD_CONNECT:
|
||||
@@ -983,7 +984,7 @@ bool PIEthernet::connectTCP() {
|
||||
return ethIsWriteable(sock);
|
||||
default: break;
|
||||
}
|
||||
#else
|
||||
# else
|
||||
if (PRIVATE->event.wait(sock, PIWaitEvent::CheckWrite)) {
|
||||
if (ethIsWriteable(sock))
|
||||
return true;
|
||||
@@ -992,12 +993,12 @@ bool PIEthernet::connectTCP() {
|
||||
init();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
long PIEthernet::waitForEvent(PIWaitEvent & event, long mask) {
|
||||
if (!event.isCreate() || sock < 0) return 0;
|
||||
if (WSAEventSelect(sock, event.getEvent(), mask) == SOCKET_ERROR) {
|
||||
@@ -1014,7 +1015,7 @@ long PIEthernet::waitForEvent(PIWaitEvent & event, long mask) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
|
||||
bool PIEthernet::configureDevice(const void * e_main, const void * e_parent) {
|
||||
@@ -1124,7 +1125,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
Interface ci;
|
||||
ci.index = -1;
|
||||
ci.mtu = 1500;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
int ret = 0;
|
||||
ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||
PIP_ADAPTER_INFO pAdapterInfo = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO));
|
||||
@@ -1175,10 +1176,10 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
}
|
||||
}
|
||||
if (pAdapterInfo) HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
#else
|
||||
# ifdef MICRO_PIP
|
||||
# else
|
||||
# ifdef ANDROID
|
||||
# ifdef LWIP
|
||||
# else
|
||||
# ifdef ANDROID
|
||||
struct ifconf ifc;
|
||||
int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
if (s == -1) {
|
||||
@@ -1215,7 +1216,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
}
|
||||
delete[] ifc.ifc_buf;
|
||||
::close(s);
|
||||
# else
|
||||
# else
|
||||
struct ifaddrs *ret, *cif = 0;
|
||||
int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
if (getifaddrs(&ret) == 0) {
|
||||
@@ -1233,8 +1234,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
ci.address = getSockAddr(cif->ifa_addr);
|
||||
ci.netmask = getSockAddr(cif->ifa_netmask);
|
||||
ci.mac.clear();
|
||||
# ifdef QNX
|
||||
# ifndef BLACKBERRY
|
||||
# ifdef QNX
|
||||
# ifndef BLACKBERRY
|
||||
int fd = ::open((PIString("/dev/io-net/") + ci.name).dataAscii(), O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
nic_config_t nic;
|
||||
@@ -1242,9 +1243,9 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
::close(fd);
|
||||
ci.mac = macFromBytes(PIByteArray(nic.permanent_address, 6));
|
||||
}
|
||||
# endif
|
||||
# else
|
||||
# ifdef MAC_OS
|
||||
# endif
|
||||
# else
|
||||
# ifdef MAC_OS
|
||||
PIString req = PISystemInfo::instance()->ifconfigPath + " " + ci.name + " | grep ether";
|
||||
FILE * fp = popen(req.dataAscii(), "r");
|
||||
if (fp != 0) {
|
||||
@@ -1255,7 +1256,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
}
|
||||
pclose(fp);
|
||||
}
|
||||
# else
|
||||
# else
|
||||
if (s != -1) {
|
||||
struct ifreq ir;
|
||||
memset(&ir, 0, sizeof(ir));
|
||||
@@ -1267,8 +1268,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
ci.mtu = ir.ifr_mtu;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
ci.flags = 0;
|
||||
if (cif->ifa_flags & IFF_UP) ci.flags |= PIEthernet::ifActive;
|
||||
if (cif->ifa_flags & IFF_RUNNING) ci.flags |= PIEthernet::ifRunning;
|
||||
@@ -1289,18 +1290,18 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
piCout << "[PIEthernet]"
|
||||
<< "Can`t get interfaces: %1"_tr("PIEthernet").arg(errorString());
|
||||
if (s != -1) ::close(s);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
return il;
|
||||
}
|
||||
|
||||
|
||||
PINetworkAddress PIEthernet::interfaceAddress(const PIString & interface_) {
|
||||
#if defined(WINDOWS) || defined(MICRO_PIP)
|
||||
# if defined(WINDOWS) || defined(LWIP)
|
||||
piCout << "[PIEthernet] Not implemented, use \"PIEthernet::allAddresses\" or \"PIEthernet::interfaces\" instead";
|
||||
return PINetworkAddress();
|
||||
#else
|
||||
# else
|
||||
struct ifreq ifr;
|
||||
piZeroMemory(ifr);
|
||||
strncpy(ifr.ifr_name, interface_.dataAscii(), sizeof(ifr.ifr_name));
|
||||
@@ -1311,7 +1312,7 @@ PINetworkAddress PIEthernet::interfaceAddress(const PIString & interface_) {
|
||||
}
|
||||
struct sockaddr_in * sa = (struct sockaddr_in *)&ifr.ifr_addr;
|
||||
return PINetworkAddress(uint(sa->sin_addr.s_addr));
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1334,16 +1335,16 @@ PIVector<PINetworkAddress> PIEthernet::allAddresses() {
|
||||
// System wrap
|
||||
|
||||
int PIEthernet::ethErrorCore() {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
return WSAGetLastError();
|
||||
#else
|
||||
# else
|
||||
return errno;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
PIString PIEthernet::ethErrorString() {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
char * msg = nullptr;
|
||||
int err = WSAGetLastError();
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
@@ -1360,18 +1361,18 @@ PIString PIEthernet::ethErrorString() {
|
||||
} else
|
||||
ret += '?';
|
||||
return ret;
|
||||
#else
|
||||
# else
|
||||
return errorString();
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
int PIEthernet::ethRecv(int sock, void * buf, int size, int flags) {
|
||||
if (sock < 0) return -1;
|
||||
return recv(sock,
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
(char *)
|
||||
#endif
|
||||
# endif
|
||||
buf,
|
||||
size,
|
||||
flags);
|
||||
@@ -1380,29 +1381,29 @@ int PIEthernet::ethRecv(int sock, void * buf, int size, int flags) {
|
||||
|
||||
int PIEthernet::ethRecvfrom(int sock, void * buf, int size, int flags, sockaddr * addr) {
|
||||
if (sock < 0) return -1;
|
||||
#ifdef QNX
|
||||
# ifdef QNX
|
||||
return recv(sock, buf, size, flags);
|
||||
#else
|
||||
# else
|
||||
socklen_t len = sizeof(sockaddr);
|
||||
return recvfrom(sock,
|
||||
# ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
(char *)
|
||||
# endif
|
||||
# endif
|
||||
buf,
|
||||
size,
|
||||
flags,
|
||||
addr,
|
||||
&len);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
int PIEthernet::ethSendto(int sock, const void * buf, int size, int flags, sockaddr * addr, int addr_len) {
|
||||
if (sock < 0) return -1;
|
||||
return sendto(sock,
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
(const char *)
|
||||
#endif
|
||||
# endif
|
||||
buf,
|
||||
size,
|
||||
flags,
|
||||
@@ -1416,13 +1417,13 @@ void PIEthernet::ethClosesocket(int sock, bool shutdown) {
|
||||
if (sock < 0) return;
|
||||
if (shutdown)
|
||||
::shutdown(sock,
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
SD_BOTH);
|
||||
closesocket(sock);
|
||||
#else
|
||||
# else
|
||||
SHUT_RDWR);
|
||||
::close(sock);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1431,9 +1432,9 @@ int PIEthernet::ethSetsockopt(int sock, int level, int optname, const void * opt
|
||||
auto ret = setsockopt(sock,
|
||||
level,
|
||||
optname,
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
(char *)
|
||||
#endif
|
||||
# endif
|
||||
optval,
|
||||
optlen);
|
||||
if (ret != 0) piCout << "setsockopt error:" << ethErrorString();
|
||||
@@ -1443,11 +1444,11 @@ int PIEthernet::ethSetsockopt(int sock, int level, int optname, const void * opt
|
||||
|
||||
int PIEthernet::ethSetsockoptInt(int sock, int level, int optname, int value) {
|
||||
if (sock < 0) return -1;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
DWORD
|
||||
#else
|
||||
# else
|
||||
int
|
||||
#endif
|
||||
# endif
|
||||
so = value;
|
||||
return ethSetsockopt(sock, level, optname, &so, sizeof(so));
|
||||
}
|
||||
@@ -1455,11 +1456,11 @@ int PIEthernet::ethSetsockoptInt(int sock, int level, int optname, int value) {
|
||||
|
||||
int PIEthernet::ethSetsockoptBool(int sock, int level, int optname, bool value) {
|
||||
if (sock < 0) return -1;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
BOOL
|
||||
#else
|
||||
# else
|
||||
int
|
||||
#endif
|
||||
# endif
|
||||
so = (value ? 1 : 0);
|
||||
return ethSetsockopt(sock, level, optname, &so, sizeof(so));
|
||||
}
|
||||
@@ -1467,12 +1468,12 @@ int PIEthernet::ethSetsockoptBool(int sock, int level, int optname, bool value)
|
||||
|
||||
void PIEthernet::ethNonblocking(int sock) {
|
||||
if (sock < 0) return;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
u_long mode = 1;
|
||||
ioctlsocket(sock, FIONBIO, &mode);
|
||||
#else
|
||||
# else
|
||||
fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1488,7 +1489,7 @@ bool PIEthernet::ethIsWriteable(int sock) {
|
||||
timeout.tv_sec = timeout.tv_usec = 0;
|
||||
::select(fds, nullptr, &fd_test, nullptr, &timeout);
|
||||
return FD_ISSET(sock, &fd_test);*/
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
fd_set fd_test;
|
||||
FD_ZERO(&fd_test);
|
||||
FD_SET(sock, &fd_test);
|
||||
@@ -1496,10 +1497,12 @@ bool PIEthernet::ethIsWriteable(int sock) {
|
||||
timeout.tv_sec = timeout.tv_usec = 0;
|
||||
::select(0, nullptr, &fd_test, nullptr, &timeout);
|
||||
return FD_ISSET(sock, &fd_test);
|
||||
#else
|
||||
# else
|
||||
int ret = 0;
|
||||
socklen_t len = sizeof(ret);
|
||||
getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&ret, &len);
|
||||
return ret == 0;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_SOCKET
|
||||
|
||||
@@ -28,11 +28,13 @@
|
||||
#include "piiodevice.h"
|
||||
#include "pinetworkaddress.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#ifdef PIP_HAS_SOCKET
|
||||
|
||||
# ifdef ANDROID
|
||||
struct
|
||||
#else
|
||||
# else
|
||||
class
|
||||
#endif
|
||||
# endif
|
||||
sockaddr;
|
||||
|
||||
//! \~\ingroup IO
|
||||
@@ -593,7 +595,7 @@ public:
|
||||
//! \}
|
||||
//! \ioparams
|
||||
//! \{
|
||||
#ifdef DOXYGEN
|
||||
# ifdef DOXYGEN
|
||||
|
||||
//! \~english Read IP address, default ""
|
||||
//! \~russian IP-адрес чтения, по умолчанию ""
|
||||
@@ -623,7 +625,7 @@ public:
|
||||
//! \~russian TTL multicast-пакетов, по умолчанию 1
|
||||
int multicastTTL;
|
||||
|
||||
#endif
|
||||
# endif
|
||||
//! \}
|
||||
|
||||
protected:
|
||||
@@ -676,9 +678,9 @@ private:
|
||||
static void server_func(void * eth);
|
||||
void setType(Type t, bool reopen = true);
|
||||
bool connectTCP();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
long waitForEvent(PIWaitEvent & event, long mask);
|
||||
#endif
|
||||
# endif
|
||||
|
||||
static int ethErrorCore();
|
||||
static PIString ethErrorString();
|
||||
@@ -703,4 +705,5 @@ inline bool operator!=(const PIEthernet::Interface & v0, const PIEthernet::Inter
|
||||
return (v0.name != v1.name || v0.address != v1.address || v0.netmask != v1.netmask);
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_SOCKET
|
||||
#endif // PIETHERNET_H
|
||||
|
||||
@@ -17,61 +17,62 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pifile.h"
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
# include "pifile.h"
|
||||
|
||||
#include "pidir.h"
|
||||
#include "piincludes_p.h"
|
||||
#include "piiostream.h"
|
||||
#include "piliterals_bytes.h"
|
||||
#include "pitime_win.h"
|
||||
#include "pitranslator.h"
|
||||
#ifdef WINDOWS
|
||||
# undef S_IFDIR
|
||||
# undef S_IFREG
|
||||
# undef S_IFLNK
|
||||
# undef S_IFBLK
|
||||
# undef S_IFCHR
|
||||
# undef S_IFSOCK
|
||||
# define S_IFDIR 0x01
|
||||
# define S_IFREG 0x02
|
||||
# define S_IFLNK 0x04
|
||||
# define S_IFBLK 0x08
|
||||
# define S_IFCHR 0x10
|
||||
# define S_IFSOCK 0x20
|
||||
#else
|
||||
# include <fcntl.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/time.h>
|
||||
# include <utime.h>
|
||||
#endif
|
||||
#define S_IFHDN 0x40
|
||||
#if defined(QNX) || defined(ANDROID) || defined(FREERTOS)
|
||||
# define _fopen_call_ fopen
|
||||
# define _fseek_call_ fseek
|
||||
# define _ftell_call_ ftell
|
||||
# define _stat_struct_ struct stat
|
||||
# define _stat_call_ stat
|
||||
# define _stat_link_ lstat
|
||||
#else
|
||||
# if defined(MAC_OS)
|
||||
# define _fopen_call_ fopen
|
||||
# define _fseek_call_ fseek
|
||||
# define _ftell_call_ ftell
|
||||
# include "pidir.h"
|
||||
# include "piincludes_p.h"
|
||||
# include "piiostream.h"
|
||||
# include "piliterals_bytes.h"
|
||||
# include "pitime_win.h"
|
||||
# include "pitranslator.h"
|
||||
# ifdef WINDOWS
|
||||
# undef S_IFDIR
|
||||
# undef S_IFREG
|
||||
# undef S_IFLNK
|
||||
# undef S_IFBLK
|
||||
# undef S_IFCHR
|
||||
# undef S_IFSOCK
|
||||
# define S_IFDIR 0x01
|
||||
# define S_IFREG 0x02
|
||||
# define S_IFLNK 0x04
|
||||
# define S_IFBLK 0x08
|
||||
# define S_IFCHR 0x10
|
||||
# define S_IFSOCK 0x20
|
||||
# else
|
||||
# ifdef CC_GCC
|
||||
# define _fopen_call_ fopen64
|
||||
# define _fseek_call_ fseeko64
|
||||
# define _ftell_call_ ftello64
|
||||
# else
|
||||
# include <fcntl.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/time.h>
|
||||
# include <utime.h>
|
||||
# endif
|
||||
# define S_IFHDN 0x40
|
||||
# if defined(QNX) || defined(ANDROID) || !defined(PIP_HAS_FILESYSTEM)
|
||||
# define _fopen_call_ fopen
|
||||
# define _fseek_call_ fseek
|
||||
# define _ftell_call_ ftell
|
||||
# define _stat_struct_ struct stat
|
||||
# define _stat_call_ stat
|
||||
# define _stat_link_ lstat
|
||||
# else
|
||||
# if defined(MAC_OS)
|
||||
# define _fopen_call_ fopen
|
||||
# define _fseek_call_ fseek
|
||||
# define _ftell_call_ ftell
|
||||
# else
|
||||
# ifdef CC_GCC
|
||||
# define _fopen_call_ fopen64
|
||||
# define _fseek_call_ fseeko64
|
||||
# define _ftell_call_ ftello64
|
||||
# else
|
||||
# define _fopen_call_ fopen
|
||||
# define _fseek_call_ fseek
|
||||
# define _ftell_call_ ftell
|
||||
# endif
|
||||
# endif
|
||||
# define _stat_struct_ struct stat64
|
||||
# define _stat_call_ stat64
|
||||
# define _stat_link_ lstat64
|
||||
# endif
|
||||
# define _stat_struct_ struct stat64
|
||||
# define _stat_call_ stat64
|
||||
# define _stat_link_ lstat64
|
||||
#endif
|
||||
|
||||
|
||||
//! \class PIFile pifile.h
|
||||
@@ -175,18 +176,18 @@ PIFile::PIFile(const PIString & path, PIIODevice::DeviceMode mode): PIIODevice(p
|
||||
|
||||
bool PIFile::openTemporary(PIIODevice::DeviceMode mode) {
|
||||
PIString tp;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
tp = PIDir::temporary().path() + PIDir::separator + "file" + PIString::fromNumber(randomi());
|
||||
while (isExists(tp)) {
|
||||
tp += PIString::fromNumber(randomi() % 10);
|
||||
}
|
||||
#else
|
||||
# else
|
||||
char template_rc[] = "/tmp/pifile_tmp_XXXXXX";
|
||||
int fd = mkstemp(template_rc);
|
||||
if (fd == -1) return false;
|
||||
::close(fd);
|
||||
tp = template_rc;
|
||||
#endif
|
||||
# endif
|
||||
return open(tp, mode);
|
||||
}
|
||||
|
||||
@@ -212,9 +213,9 @@ bool PIFile::openDevice() {
|
||||
bool opened = (PRIVATE->fd != 0);
|
||||
if (opened) {
|
||||
fdi = fileno(PRIVATE->fd);
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
fcntl(fdi, F_SETFL, O_NONBLOCK);
|
||||
#endif
|
||||
# endif
|
||||
if (mode_ == PIIODevice::ReadOnly) {
|
||||
_fseek_call_(PRIVATE->fd, 0, SEEK_END);
|
||||
_size = _ftell_call_(PRIVATE->fd);
|
||||
@@ -306,11 +307,11 @@ bool PIFile::isExists(const PIString & path) {
|
||||
|
||||
|
||||
bool PIFile::remove(const PIString & path) {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
if (PIDir::isExists(path))
|
||||
return RemoveDirectoryA(path.data()) > 0;
|
||||
else
|
||||
#endif
|
||||
# endif
|
||||
return ::remove(path.data()) == 0;
|
||||
}
|
||||
|
||||
@@ -478,7 +479,7 @@ PIFile::FileInfo PIFile::fileInfo(const PIString & path) {
|
||||
ret.path = path.replacedAll("\\", PIDir::separator);
|
||||
PIString n = ret.name();
|
||||
// piCout << "open" << path;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
DWORD attr = GetFileAttributesA((LPCSTR)(path.data()));
|
||||
if (attr == 0xFFFFFFFF) return ret;
|
||||
HANDLE hFile = 0;
|
||||
@@ -510,37 +511,37 @@ PIFile::FileInfo PIFile::fileInfo(const PIString & path) {
|
||||
ret.time_modification = FILETIME2PIDateTime(fi.ftLastWriteTime);
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
#else
|
||||
# else
|
||||
_stat_struct_ fs;
|
||||
piZeroMemory(fs);
|
||||
_stat_call_(path.data(), &fs);
|
||||
int mode = fs.st_mode;
|
||||
ret.size = fs.st_size;
|
||||
ret.id_user = fs.st_uid;
|
||||
ret.id_group = fs.st_gid;
|
||||
# ifdef ANDROID
|
||||
int mode = fs.st_mode;
|
||||
ret.size = fs.st_size;
|
||||
ret.id_user = fs.st_uid;
|
||||
ret.id_group = fs.st_gid;
|
||||
# ifdef ANDROID
|
||||
ret.time_access = PIDateTime::fromSystemTime(PISystemTime(fs.st_atime, fs.st_atime_nsec));
|
||||
ret.time_modification = PIDateTime::fromSystemTime(PISystemTime(fs.st_mtime, fs.st_mtime_nsec));
|
||||
# else
|
||||
# if defined(QNX) || defined(FREERTOS)
|
||||
# else
|
||||
# if defined(QNX) || defined(FREERTOS)
|
||||
ret.time_access = PIDateTime::fromSecondSinceEpoch(fs.st_atime);
|
||||
ret.time_modification = PIDateTime::fromSecondSinceEpoch(fs.st_mtime);
|
||||
# else
|
||||
# ifdef MAC_OS
|
||||
# define ATIME st_atimespec
|
||||
# define MTIME st_ctimespec
|
||||
# else
|
||||
# define ATIME st_atim
|
||||
# define MTIME st_mtim
|
||||
# endif
|
||||
# ifdef MAC_OS
|
||||
# define ATIME st_atimespec
|
||||
# define MTIME st_ctimespec
|
||||
# else
|
||||
# define ATIME st_atim
|
||||
# define MTIME st_mtim
|
||||
# endif
|
||||
ret.time_access = PIDateTime::fromSystemTime(PISystemTime(fs.ATIME.tv_sec, fs.ATIME.tv_nsec));
|
||||
ret.time_modification = PIDateTime::fromSystemTime(PISystemTime(fs.MTIME.tv_sec, fs.MTIME.tv_nsec));
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# ifndef MICRO_PIP
|
||||
ret.perm_user = FileInfo::Permissions((mode & S_IRUSR) == S_IRUSR, (mode & S_IWUSR) == S_IWUSR, (mode & S_IXUSR) == S_IXUSR);
|
||||
ret.perm_group = FileInfo::Permissions((mode & S_IRGRP) == S_IRGRP, (mode & S_IWGRP) == S_IWGRP, (mode & S_IXGRP) == S_IXGRP);
|
||||
ret.perm_other = FileInfo::Permissions((mode & S_IROTH) == S_IROTH, (mode & S_IWOTH) == S_IWOTH, (mode & S_IXOTH) == S_IXOTH);
|
||||
# ifdef PIP_HAS_FILESYSTEM
|
||||
ret.perm_user = FileInfo::Permissions((mode & S_IRUSR) == S_IRUSR, (mode & S_IWUSR) == S_IWUSR, (mode & S_IXUSR) == S_IXUSR);
|
||||
ret.perm_group = FileInfo::Permissions((mode & S_IRGRP) == S_IRGRP, (mode & S_IWGRP) == S_IWGRP, (mode & S_IXGRP) == S_IXGRP);
|
||||
ret.perm_other = FileInfo::Permissions((mode & S_IROTH) == S_IROTH, (mode & S_IWOTH) == S_IWOTH, (mode & S_IXOTH) == S_IXOTH);
|
||||
piZeroMemory(fs);
|
||||
_stat_link_(path.data(), &fs);
|
||||
mode &= ~S_IFLNK;
|
||||
@@ -550,8 +551,8 @@ PIFile::FileInfo PIFile::fileInfo(const PIString & path) {
|
||||
if ((mode & S_IFREG) == S_IFREG) ret.flags |= FileInfo::File;
|
||||
if ((mode & S_IFLNK) == S_IFLNK) ret.flags |= FileInfo::SymbolicLink;
|
||||
if ((mode & S_IFHDN) == S_IFHDN) ret.flags |= FileInfo::Hidden;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
if (n == ".") ret.flags = FileInfo::Dir | FileInfo::Dot;
|
||||
if (n == "..") ret.flags = FileInfo::Dir | FileInfo::DotDot;
|
||||
return ret;
|
||||
@@ -562,7 +563,7 @@ bool PIFile::applyFileInfo(const PIString & path, const PIFile::FileInfo & info)
|
||||
if (path.isEmpty()) return false;
|
||||
PIString fp(path);
|
||||
if (fp.endsWith(PIDir::separator)) fp.pop_back();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
DWORD attr = GetFileAttributesA((LPCSTR)(path.data()));
|
||||
if (attr == 0xFFFFFFFF) return false;
|
||||
attr &= ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
|
||||
@@ -590,7 +591,7 @@ bool PIFile::applyFileInfo(const PIString & path, const PIFile::FileInfo & info)
|
||||
return false;
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
#else
|
||||
# else
|
||||
int mode(0);
|
||||
if (info.perm_user.read) mode |= S_IRUSR;
|
||||
if (info.perm_user.write) mode |= S_IWUSR;
|
||||
@@ -617,7 +618,7 @@ bool PIFile::applyFileInfo(const PIString & path, const PIFile::FileInfo & info)
|
||||
if (utimes(fp.data(), tm) != 0) {
|
||||
piCout << "[PIFile] applyFileInfo: \"utimes\" error:" << errorString();
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -635,3 +636,4 @@ int PIFile::writeAll(const PIString & path, const PIByteArray & data) {
|
||||
f.clear();
|
||||
return f.write(data.data(), data.size_s());
|
||||
}
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "pipropertystorage.h"
|
||||
|
||||
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
//! \~\ingroup IO
|
||||
//! \~\brief
|
||||
//! \~english Local file.
|
||||
@@ -361,8 +362,10 @@ private:
|
||||
llong _size = -1;
|
||||
PIString prec_str;
|
||||
};
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
//! \relatesalso PICout
|
||||
//! \~english Output operator to \a PICout.
|
||||
//! \~russian Оператор вывода в \a PICout.
|
||||
@@ -395,5 +398,6 @@ BINARY_STREAM_READ(PIFile::FileInfo) {
|
||||
v.perm_group.raw >> v.perm_other.raw;
|
||||
return s;
|
||||
}
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
#endif // PIFILE_H
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#endif
|
||||
#include "piliterals.h"
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
//! \class PIGPIO pigpio.h
|
||||
//! \~english \section PIGPIO_sec0 Synopsis
|
||||
@@ -74,7 +75,7 @@ PIGPIO::~PIGPIO() {
|
||||
stop();
|
||||
waitForFinish(100_ms);
|
||||
PIMutexLocker ml(mutex);
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
# ifdef GPIO_SYS_CLASS
|
||||
PIVector<int> ids = gpio_.keys();
|
||||
for (int i = 0; i < ids.size_s(); i++) {
|
||||
GPIOData & g(gpio_[ids[i]]);
|
||||
@@ -84,7 +85,7 @@ PIGPIO::~PIGPIO() {
|
||||
}
|
||||
}
|
||||
gpio_.clear();
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +101,7 @@ PIString PIGPIO::GPIOName(int gpio_num) {
|
||||
|
||||
|
||||
void PIGPIO::exportGPIO(int gpio_num) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
# ifdef GPIO_SYS_CLASS
|
||||
PIString valfile = "/sys/class/gpio/" + GPIOName(gpio_num) + "/value";
|
||||
int fd = ::open(valfile.dataAscii(), O_RDONLY);
|
||||
if (fd != -1) {
|
||||
@@ -120,12 +121,12 @@ void PIGPIO::exportGPIO(int gpio_num) {
|
||||
piMSleep(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void PIGPIO::openGPIO(GPIOData & g) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
# ifdef GPIO_SYS_CLASS
|
||||
if (g.fd != -1) {
|
||||
::close(g.fd);
|
||||
g.fd = -1;
|
||||
@@ -133,12 +134,12 @@ void PIGPIO::openGPIO(GPIOData & g) {
|
||||
PIString fp = "/sys/class/gpio/" + g.name + "/value";
|
||||
g.fd = ::open(fp.dataAscii(), O_RDWR);
|
||||
// piCoutObj << "initGPIO" << g.num << ":" << fp << g.fd << errorString();
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
bool PIGPIO::getPinState(int gpio_num) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
# ifdef GPIO_SYS_CLASS
|
||||
GPIOData & g(gpio_[gpio_num]);
|
||||
char r = 0;
|
||||
int ret = 0;
|
||||
@@ -151,7 +152,7 @@ bool PIGPIO::getPinState(int gpio_num) {
|
||||
}
|
||||
}
|
||||
// piCoutObj << "pinState" << gpio_num << ":" << ret << (int)r << errorString();
|
||||
#endif
|
||||
# endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -201,9 +202,9 @@ void PIGPIO::end() {
|
||||
for (int i = 0; i < ids.size_s(); i++) {
|
||||
GPIOData & g(gpio_[ids[i]]);
|
||||
if (g.fd != -1) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
# ifdef GPIO_SYS_CLASS
|
||||
::close(g.fd);
|
||||
#endif
|
||||
# endif
|
||||
g.fd = -1;
|
||||
}
|
||||
}
|
||||
@@ -211,7 +212,7 @@ void PIGPIO::end() {
|
||||
|
||||
|
||||
void PIGPIO::initPin(int gpio_num, Direction dir) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
# ifdef GPIO_SYS_CLASS
|
||||
PIMutexLocker ml(mutex);
|
||||
GPIOData & g(gpio_[gpio_num]);
|
||||
if (g.num == -1) {
|
||||
@@ -228,12 +229,12 @@ void PIGPIO::initPin(int gpio_num, Direction dir) {
|
||||
default: break;
|
||||
}
|
||||
openGPIO(g);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void PIGPIO::pinSet(int gpio_num, bool value) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
# ifdef GPIO_SYS_CLASS
|
||||
PIMutexLocker ml(mutex);
|
||||
GPIOData & g(gpio_[gpio_num]);
|
||||
int ret = 0;
|
||||
@@ -245,7 +246,7 @@ void PIGPIO::pinSet(int gpio_num, bool value) {
|
||||
ret = ::write(g.fd, "0", 1);
|
||||
}
|
||||
// piCoutObj << "pinSet" << gpio_num << ":" << ret << errorString();
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -267,9 +268,9 @@ void PIGPIO::pinBeginWatch(int gpio_num) {
|
||||
PIMutexLocker ml(mutex);
|
||||
GPIOData & g(gpio_[gpio_num]);
|
||||
if (g.fd != -1) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
# ifdef GPIO_SYS_CLASS
|
||||
::close(g.fd);
|
||||
#endif
|
||||
# endif
|
||||
g.fd = -1;
|
||||
}
|
||||
watch_state.insert(gpio_num, false);
|
||||
@@ -304,6 +305,8 @@ void PIGPIO::clearWatch() {
|
||||
}
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __GNUC__
|
||||
// # pragma GCC diagnostic pop
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "pithread.h"
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
//! \~\ingroup IO
|
||||
//! \~\brief
|
||||
@@ -143,5 +144,6 @@ private:
|
||||
PIMutex mutex;
|
||||
};
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
#endif // PIDIR_H
|
||||
#endif // PIGPIO_H
|
||||
|
||||
@@ -117,7 +117,9 @@
|
||||
//!
|
||||
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
PIMutex PIIODevice::nfp_mutex;
|
||||
#endif
|
||||
PIMap<PIString, PIString> PIIODevice::nfp_cache;
|
||||
|
||||
|
||||
@@ -138,6 +140,7 @@ PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode mode): PIOb
|
||||
PIIODevice::~PIIODevice() {
|
||||
destroying = true;
|
||||
stopAndWait();
|
||||
(void)destroying;
|
||||
}
|
||||
|
||||
|
||||
@@ -195,6 +198,7 @@ void PIIODevice::setThreadedReadBufferSize(int new_size) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
bool PIIODevice::isThreadedRead() const {
|
||||
return read_thread.isRunning();
|
||||
}
|
||||
@@ -216,16 +220,12 @@ void PIIODevice::startThreadedRead(ReadRetFunc func) {
|
||||
|
||||
void PIIODevice::stopThreadedRead() {
|
||||
if (!isThreadedRead()) return;
|
||||
#ifdef MICRO_PIP
|
||||
read_thread.stop();
|
||||
#else
|
||||
read_thread.stop();
|
||||
if (!destroying) {
|
||||
interrupt();
|
||||
} else {
|
||||
piCoutObj << "Error: Device is running after destructor!"_tr("PIIODevice");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -248,56 +248,80 @@ bool PIIODevice::waitThreadedReadFinished(PISystemTime timeout) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool PIIODevice::isThreadedWrite() const {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
return write_thread.isRunning();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::startThreadedWrite() {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
if (!write_thread.isRunning()) write_thread.startOnce();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::stopThreadedWrite() {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
if (!write_thread.isRunning()) return;
|
||||
write_thread.stop();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::terminateThreadedWrite() {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
write_thread.terminate();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIIODevice::waitThreadedWriteFinished(PISystemTime timeout) {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
return write_thread.waitForFinish(timeout);
|
||||
#else
|
||||
(void)timeout;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::clearThreadedWriteQueue() {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
write_thread.lock();
|
||||
write_queue.clear();
|
||||
write_thread.unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::start() {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
startThreadedRead();
|
||||
#endif
|
||||
startThreadedWrite();
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::stop() {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
stopThreadedRead();
|
||||
#endif
|
||||
stopThreadedWrite();
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::stopAndWait(PISystemTime timeout) {
|
||||
stop();
|
||||
#ifdef PIP_HAS_THREADS
|
||||
waitThreadedReadFinished(timeout);
|
||||
#endif
|
||||
waitThreadedWriteFinished(timeout);
|
||||
}
|
||||
|
||||
@@ -333,11 +357,10 @@ void PIIODevice::_init() {
|
||||
setOptions(0);
|
||||
setReopenEnabled(true);
|
||||
setReopenTimeout(1_s);
|
||||
#ifdef MICRO_PIP
|
||||
#ifndef PIP_HAS_THREADS
|
||||
threaded_read_buffer_size = 512;
|
||||
#else
|
||||
threaded_read_buffer_size = 4_KiB;
|
||||
#endif
|
||||
read_thread.setName("_S.PIIODev.read");
|
||||
write_thread.setName("_S.PIIODev.write");
|
||||
CONNECT(void, &write_thread, started, this, write_func);
|
||||
@@ -345,9 +368,11 @@ void PIIODevice::_init() {
|
||||
if (!isOpened()) open();
|
||||
});
|
||||
read_thread.setSlot([this](void *) { read_func(); });
|
||||
#endif // PIP_HAS_THREADS
|
||||
}
|
||||
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
void PIIODevice::write_func() {
|
||||
while (!write_thread.isStopping()) {
|
||||
while (!write_queue.isEmpty()) {
|
||||
@@ -362,15 +387,6 @@ void PIIODevice::write_func() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PIIODevice * PIIODevice::newDeviceByPrefix(const char * prefix) {
|
||||
if (!prefix) return nullptr;
|
||||
auto fi = fabrics().value(prefix);
|
||||
if (fi.fabricator) return fi.fabricator();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::read_func() {
|
||||
if (!isReadable()) {
|
||||
read_thread.stop();
|
||||
@@ -391,13 +407,20 @@ void PIIODevice::read_func() {
|
||||
if (read_thread.isStopping()) return;
|
||||
if (readed_ <= 0) {
|
||||
piMSleep(threaded_read_timeout_ms);
|
||||
// cout << readed_ << ", " << errno << ", " << errorString() << endl;
|
||||
return;
|
||||
}
|
||||
// piCoutObj << "readed" << readed_;// << ", " << errno << ", " << errorString();
|
||||
threadedRead(buffer_tr.data(), readed_);
|
||||
threadedReadEvent(buffer_tr.data(), readed_);
|
||||
}
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
|
||||
PIIODevice * PIIODevice::newDeviceByPrefix(const char * prefix) {
|
||||
if (!prefix) return nullptr;
|
||||
auto fi = fabrics().value(prefix);
|
||||
if (fi.fabricator) return fi.fabricator();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PIIODevice::readForTime(PISystemTime timeout) {
|
||||
@@ -420,6 +443,7 @@ PIByteArray PIIODevice::readForTime(PISystemTime timeout) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
ullong PIIODevice::writeThreaded(const PIByteArray & data) {
|
||||
write_thread.lock();
|
||||
write_queue.enqueue(PIPair<PIByteArray, ullong>(data, tri));
|
||||
@@ -427,6 +451,7 @@ ullong PIIODevice::writeThreaded(const PIByteArray & data) {
|
||||
write_thread.unlock();
|
||||
return tri - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool PIIODevice::open() {
|
||||
@@ -543,7 +568,7 @@ void PIIODevice::splitFullPath(PIString fpwm, PIString * full_path, DeviceMode *
|
||||
if (o == "br"_a || o == "blockr"_a || o == "blockread"_a || o == "blockingread"_a) op |= BlockingRead;
|
||||
if (o == "bw"_a || o == "blockw"_a || o == "blockwrite"_a || o == "blockingwrite"_a) op |= BlockingWrite;
|
||||
if (o == "brw"_a || o == "bwr"_a || o == "blockrw"_a || o == "blockwr"_a || o == "blockreadrite"_a ||
|
||||
o == "blockingreadwrite"_a)
|
||||
o == "blockingreadwrite"_a)
|
||||
op |= BlockingRead | BlockingWrite;
|
||||
}
|
||||
fpwm.cutRight(fpwm.length() - fpwm.findLast('(')).trim();
|
||||
@@ -638,15 +663,20 @@ PIIODevice * PIIODevice::createFromVariant(const PIVariantTypes::IODevice & d) {
|
||||
|
||||
|
||||
PIString PIIODevice::normalizeFullPath(const PIString & full_path) {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
nfp_mutex.lock();
|
||||
#endif
|
||||
PIString ret = nfp_cache.value(full_path);
|
||||
if (!ret.isEmpty()) {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
nfp_mutex.unlock();
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#ifdef PIP_HAS_THREADS
|
||||
nfp_mutex.unlock();
|
||||
#endif
|
||||
PIIODevice * d = createFromFullPath(full_path);
|
||||
// piCout << "normalizeFullPath" << d;
|
||||
if (d == 0) return PIString();
|
||||
ret = d->constructFullPath();
|
||||
delete d;
|
||||
@@ -655,7 +685,9 @@ PIString PIIODevice::normalizeFullPath(const PIString & full_path) {
|
||||
|
||||
|
||||
void PIIODevice::cacheFullPath(const PIString & full_path, const PIIODevice * d) {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
PIMutexLocker nfp_ml(nfp_mutex);
|
||||
#endif
|
||||
nfp_cache[full_path] = d->constructFullPath();
|
||||
}
|
||||
|
||||
|
||||
@@ -59,26 +59,20 @@ typedef std::function<bool(const uchar *, int, void *)> ReadRetFunc;
|
||||
|
||||
#else
|
||||
|
||||
# define REGISTER_DEVICE(name) \
|
||||
STATIC_INITIALIZER_BEGIN \
|
||||
PIIODevice::registerDevice(name::fullPathPrefixS(), #name, []() -> PIIODevice * { return new name(); }); \
|
||||
STATIC_INITIALIZER_END
|
||||
# define REGISTER_DEVICE(name) \
|
||||
STATIC_INITIALIZER_BEGIN \
|
||||
PIIODevice::registerDevice(name::fullPathPrefixS(), #name, []() -> PIIODevice * { return new name(); }); \
|
||||
STATIC_INITIALIZER_END
|
||||
|
||||
# define PIIODEVICE(name, prefix) \
|
||||
PIOBJECT_SUBCLASS(name, PIIODevice) \
|
||||
PIIODevice * copy() const override { \
|
||||
return new name(); \
|
||||
} \
|
||||
\
|
||||
public: \
|
||||
PIConstChars fullPathPrefix() const override { \
|
||||
return prefix; \
|
||||
} \
|
||||
static PIConstChars fullPathPrefixS() { \
|
||||
return prefix; \
|
||||
} \
|
||||
\
|
||||
private:
|
||||
# define PIIODEVICE(name, prefix) \
|
||||
PIOBJECT_SUBCLASS(name, PIIODevice) \
|
||||
PIIODevice * copy() const override { return new name(); } \
|
||||
\
|
||||
public: \
|
||||
PIConstChars fullPathPrefix() const override { return prefix; } \
|
||||
static PIConstChars fullPathPrefixS() { return prefix; } \
|
||||
\
|
||||
private:
|
||||
|
||||
|
||||
#endif
|
||||
@@ -248,7 +242,7 @@ public:
|
||||
//! \~russian Возвращает пользовательские данные, передаваемые в callback потокового чтения.
|
||||
void * threadedReadData() const { return ret_data_; }
|
||||
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
//! \~english Returns whether threaded read is running.
|
||||
//! \~russian Возвращает, запущено ли потоковое чтение.
|
||||
bool isThreadedRead() const;
|
||||
@@ -279,6 +273,7 @@ public:
|
||||
//! \~english Waits until threaded read finishes or "timeout" expires.
|
||||
//! \~russian Ожидает завершения потокового чтения, но не дольше "timeout".
|
||||
bool waitThreadedReadFinished(PISystemTime timeout = {});
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
|
||||
//! \~english Returns delay between unsuccessful threaded read attempts in milliseconds.
|
||||
@@ -367,6 +362,7 @@ public:
|
||||
PIByteArray readForTime(PISystemTime timeout);
|
||||
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
//! \~english Queues "data" for threaded write and returns task ID.
|
||||
//! \~russian Помещает "data" в очередь потоковой записи и возвращает ID задания.
|
||||
ullong writeThreaded(const void * data, ssize_t max_size) { return writeThreaded(PIByteArray(data, uint(max_size))); }
|
||||
@@ -374,6 +370,7 @@ public:
|
||||
//! \~english Queues byte array "data" for threaded write and returns task ID.
|
||||
//! \~russian Помещает массив байт "data" в очередь потоковой записи и возвращает ID задания.
|
||||
ullong writeThreaded(const PIByteArray & data);
|
||||
#endif
|
||||
|
||||
|
||||
//! \~english Configures the device from section "section" of file "config_file".
|
||||
@@ -611,16 +608,18 @@ private:
|
||||
static PIMap<PIConstChars, FabricInfo> & fabrics();
|
||||
|
||||
PITimeMeasurer tm, reopen_tm;
|
||||
PIThread read_thread, write_thread;
|
||||
PIByteArray buffer_in, buffer_tr;
|
||||
PIQueue<PIPair<PIByteArray, ullong>> write_queue;
|
||||
PISystemTime reopen_timeout;
|
||||
ullong tri = 0;
|
||||
uint threaded_read_buffer_size, threaded_read_timeout_ms = 10;
|
||||
bool reopen_enabled = true, destroying = false;
|
||||
|
||||
static PIMutex nfp_mutex;
|
||||
static PIMap<PIString, PIString> nfp_cache;
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
PIThread read_thread, write_thread;
|
||||
PIQueue<PIPair<PIByteArray, ullong>> write_queue;
|
||||
static PIMutex nfp_mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // PIIODEVICE_H
|
||||
|
||||
@@ -23,20 +23,22 @@
|
||||
#include "pidatatransfer.h"
|
||||
#include "piliterals_time.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "pitime.h"
|
||||
|
||||
#define _PIPEER_MSG_SIZE 4000
|
||||
#define _PIPEER_MSG_TTL 100
|
||||
#define _PIPEER_MULTICAST_TTL 4
|
||||
#define _PIPEER_MULTICAST_IP "232.13.3.12"
|
||||
#define _PIPEER_LOOPBACK_PORT_S 13313
|
||||
#define _PIPEER_LOOPBACK_PORT_E (13313 + 32)
|
||||
#define _PIPEER_MULTICAST_PORT 13360
|
||||
#define _PIPEER_TCP_PORT _PIPEER_MULTICAST_PORT
|
||||
#define _PIPEER_BROADCAST_PORT 13361
|
||||
#define _PIPEER_TRAFFIC_PORT_S 13400
|
||||
#define _PIPEER_TRAFFIC_PORT_E 14000
|
||||
#define _PIPEER_PING_TIMEOUT 5.0
|
||||
#ifdef PIP_HAS_SOCKET
|
||||
# include "pitime.h"
|
||||
|
||||
# define _PIPEER_MSG_SIZE 4000
|
||||
# define _PIPEER_MSG_TTL 100
|
||||
# define _PIPEER_MULTICAST_TTL 4
|
||||
# define _PIPEER_MULTICAST_IP "232.13.3.12"
|
||||
# define _PIPEER_LOOPBACK_PORT_S 13313
|
||||
# define _PIPEER_LOOPBACK_PORT_E (13313 + 32)
|
||||
# define _PIPEER_MULTICAST_PORT 13360
|
||||
# define _PIPEER_TCP_PORT _PIPEER_MULTICAST_PORT
|
||||
# define _PIPEER_BROADCAST_PORT 13361
|
||||
# define _PIPEER_TRAFFIC_PORT_S 13400
|
||||
# define _PIPEER_TRAFFIC_PORT_E 14000
|
||||
# define _PIPEER_PING_TIMEOUT 5.0
|
||||
|
||||
class PIPeer::PeerData: public PIObject {
|
||||
PIOBJECT_SUBCLASS(PeerData, PIObject);
|
||||
@@ -893,11 +895,11 @@ void PIPeer::pingNeighbours() {
|
||||
|
||||
bool PIPeer::openDevice() {
|
||||
PIConfig conf(
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
"/etc/pip.conf"
|
||||
#else
|
||||
# else
|
||||
"pip.conf"
|
||||
#endif
|
||||
# endif
|
||||
,
|
||||
PIIODevice::ReadOnly);
|
||||
server_ip = conf.getValue("peer_server_ip", "").toString();
|
||||
@@ -1176,3 +1178,5 @@ bool PIPeer::hasPeer(const PIString & name) {
|
||||
if (i.name == name) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_SOCKET
|
||||
|
||||
@@ -34,10 +34,11 @@
|
||||
//! \~russian Именованный сетевой пир, построенный поверх %PIIODevice.
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! The class discovers peers, routes packets by peer name and can expose a trusted-peer stream through inherited \a read() and \a write().
|
||||
//! The class discovers peers, routes packets by peer name and can expose a trusted-peer stream through inherited \a read() и \a write().
|
||||
//! \~russian
|
||||
//! Класс обнаруживает пиры, маршрутизирует пакеты по имени пира и может предоставлять поток trusted-peer через унаследованные \a read() и
|
||||
//! \a write().
|
||||
#ifdef PIP_HAS_SOCKET
|
||||
class PIP_EXPORT PIPeer: public PIIODevice {
|
||||
PIIODEVICE(PIPeer, "peer");
|
||||
|
||||
@@ -436,6 +437,6 @@ BINARY_STREAM_READ(PIPeer::PeerInfo) {
|
||||
s >> v.name >> v.addresses >> v.dist >> v.neighbours >> v.cnt >> v.time;
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_SOCKET
|
||||
|
||||
#endif // PIPEER_H
|
||||
|
||||
+186
-185
@@ -19,38 +19,37 @@
|
||||
|
||||
#include "piserial.h"
|
||||
|
||||
#include "piconfig.h"
|
||||
#include "pidir.h"
|
||||
#include "piincludes_p.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "pitime.h"
|
||||
#include "pitranslator.h"
|
||||
#include "piwaitevent_p.h"
|
||||
#ifdef PIP_HAS_SERIAL
|
||||
|
||||
#include <errno.h>
|
||||
# include "piconfig.h"
|
||||
# include "pidir.h"
|
||||
# include "piincludes_p.h"
|
||||
# include "pipropertystorage.h"
|
||||
# include "pitime.h"
|
||||
# include "pitranslator.h"
|
||||
# include "piwaitevent_p.h"
|
||||
|
||||
#if defined(MICRO_PIP)
|
||||
# define PISERIAL_NO_PINS
|
||||
#endif
|
||||
#if defined(PISERIAL_NO_PINS) || defined(WINDOWS)
|
||||
# define TIOCM_LE 1
|
||||
# define TIOCM_DTR 4
|
||||
# define TIOCM_RTS 7
|
||||
# define TIOCM_CTS 8
|
||||
# define TIOCM_ST 3
|
||||
# define TIOCM_SR 2
|
||||
# define TIOCM_CAR 1
|
||||
# define TIOCM_RNG 9
|
||||
# define TIOCM_DSR 6
|
||||
#endif
|
||||
#ifdef WINDOWS
|
||||
# ifndef INITGUID
|
||||
# define INITGUID
|
||||
# include <guiddef.h>
|
||||
# undef INITGUID
|
||||
# else
|
||||
# include <guiddef.h>
|
||||
# include <errno.h>
|
||||
|
||||
# if defined(PISERIAL_NO_PINS) || defined(WINDOWS)
|
||||
# define TIOCM_LE 1
|
||||
# define TIOCM_DTR 4
|
||||
# define TIOCM_RTS 7
|
||||
# define TIOCM_CTS 8
|
||||
# define TIOCM_ST 3
|
||||
# define TIOCM_SR 2
|
||||
# define TIOCM_CAR 1
|
||||
# define TIOCM_RNG 9
|
||||
# define TIOCM_DSR 6
|
||||
# endif
|
||||
# ifdef WINDOWS
|
||||
# ifndef INITGUID
|
||||
# define INITGUID
|
||||
# include <guiddef.h>
|
||||
# undef INITGUID
|
||||
# else
|
||||
# include <guiddef.h>
|
||||
# endif
|
||||
// clang-format off
|
||||
# include <ntddmodm.h>
|
||||
# include <winreg.h>
|
||||
@@ -59,89 +58,89 @@
|
||||
# include <cfgmgr32.h>
|
||||
# include <setupapi.h>
|
||||
// clang-format on
|
||||
# define B50 50
|
||||
# define B75 75
|
||||
# define B110 110
|
||||
# define B300 300
|
||||
# define B600 600
|
||||
# define B1200 1200
|
||||
# define B2400 2400
|
||||
# define B4800 4800
|
||||
# define B9600 9600
|
||||
# define B14400 14400
|
||||
# define B19200 19200
|
||||
# define B38400 38400
|
||||
# define B57600 57600
|
||||
# define B115200 115200
|
||||
# define B230400 230400
|
||||
# define B460800 460800
|
||||
# define B500000 500000
|
||||
# define B576000 576000
|
||||
# define B921600 921600
|
||||
# define B1000000 1000000
|
||||
# define B1152000 1152000
|
||||
# define B1500000 1500000
|
||||
# define B2000000 2000000
|
||||
# define B2500000 2500000
|
||||
# define B3000000 3000000
|
||||
# define B3500000 3500000
|
||||
# define B4000000 4000000
|
||||
#else
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <termios.h>
|
||||
# ifndef B50
|
||||
# define B50 0000001
|
||||
# define B50 50
|
||||
# define B75 75
|
||||
# define B110 110
|
||||
# define B300 300
|
||||
# define B600 600
|
||||
# define B1200 1200
|
||||
# define B2400 2400
|
||||
# define B4800 4800
|
||||
# define B9600 9600
|
||||
# define B14400 14400
|
||||
# define B19200 19200
|
||||
# define B38400 38400
|
||||
# define B57600 57600
|
||||
# define B115200 115200
|
||||
# define B230400 230400
|
||||
# define B460800 460800
|
||||
# define B500000 500000
|
||||
# define B576000 576000
|
||||
# define B921600 921600
|
||||
# define B1000000 1000000
|
||||
# define B1152000 1152000
|
||||
# define B1500000 1500000
|
||||
# define B2000000 2000000
|
||||
# define B2500000 2500000
|
||||
# define B3000000 3000000
|
||||
# define B3500000 3500000
|
||||
# define B4000000 4000000
|
||||
# else
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <termios.h>
|
||||
# ifndef B50
|
||||
# define B50 0000001
|
||||
# endif
|
||||
# ifndef B75
|
||||
# define B75 0000002
|
||||
# endif
|
||||
# ifndef B230400
|
||||
# define B230400 0010003
|
||||
# endif
|
||||
# ifndef B460800
|
||||
# define B460800 0010004
|
||||
# endif
|
||||
# ifndef B500000
|
||||
# define B500000 0010005
|
||||
# endif
|
||||
# ifndef B576000
|
||||
# define B576000 0010006
|
||||
# endif
|
||||
# ifndef B921600
|
||||
# define B921600 0010007
|
||||
# endif
|
||||
# ifndef B1000000
|
||||
# define B1000000 0010010
|
||||
# endif
|
||||
# ifndef B1152000
|
||||
# define B1152000 0010011
|
||||
# endif
|
||||
# ifndef B1500000
|
||||
# define B1500000 0010012
|
||||
# endif
|
||||
# ifndef B2000000
|
||||
# define B2000000 0010013
|
||||
# endif
|
||||
# ifndef B2500000
|
||||
# define B2500000 0010014
|
||||
# endif
|
||||
# ifndef B3000000
|
||||
# define B3000000 0010015
|
||||
# endif
|
||||
# ifndef B3500000
|
||||
# define B3500000 0010016
|
||||
# endif
|
||||
# ifndef B4000000
|
||||
# define B4000000 0010017
|
||||
# endif
|
||||
# endif
|
||||
# ifndef B75
|
||||
# define B75 0000002
|
||||
# ifndef CRTSCTS
|
||||
# define CRTSCTS 020000000000
|
||||
# endif
|
||||
# ifndef B230400
|
||||
# define B230400 0010003
|
||||
# ifdef LINUX
|
||||
# include <linux/serial.h>
|
||||
# endif
|
||||
# ifndef B460800
|
||||
# define B460800 0010004
|
||||
# endif
|
||||
# ifndef B500000
|
||||
# define B500000 0010005
|
||||
# endif
|
||||
# ifndef B576000
|
||||
# define B576000 0010006
|
||||
# endif
|
||||
# ifndef B921600
|
||||
# define B921600 0010007
|
||||
# endif
|
||||
# ifndef B1000000
|
||||
# define B1000000 0010010
|
||||
# endif
|
||||
# ifndef B1152000
|
||||
# define B1152000 0010011
|
||||
# endif
|
||||
# ifndef B1500000
|
||||
# define B1500000 0010012
|
||||
# endif
|
||||
# ifndef B2000000
|
||||
# define B2000000 0010013
|
||||
# endif
|
||||
# ifndef B2500000
|
||||
# define B2500000 0010014
|
||||
# endif
|
||||
# ifndef B3000000
|
||||
# define B3000000 0010015
|
||||
# endif
|
||||
# ifndef B3500000
|
||||
# define B3500000 0010016
|
||||
# endif
|
||||
# ifndef B4000000
|
||||
# define B4000000 0010017
|
||||
# endif
|
||||
#endif
|
||||
#ifndef CRTSCTS
|
||||
# define CRTSCTS 020000000000
|
||||
#endif
|
||||
#ifdef LINUX
|
||||
# include <linux/serial.h>
|
||||
#endif
|
||||
|
||||
|
||||
//! \class PISerial piserial.h
|
||||
@@ -177,16 +176,16 @@ REGISTER_DEVICE(PISerial)
|
||||
|
||||
PRIVATE_DEFINITION_START(PISerial)
|
||||
PIWaitEvent event;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
PIWaitEvent event_write;
|
||||
DCB desc, sdesc;
|
||||
HANDLE hCom = nullptr;
|
||||
DWORD readed = 0, mask = 0;
|
||||
OVERLAPPED overlap, overlap_write;
|
||||
#else
|
||||
# else
|
||||
termios desc, sdesc;
|
||||
uint readed = 0;
|
||||
#endif
|
||||
# endif
|
||||
PRIVATE_DEFINITION_END(PISerial)
|
||||
|
||||
|
||||
@@ -214,9 +213,9 @@ PISerial::~PISerial() {
|
||||
stopAndWait();
|
||||
close();
|
||||
PRIVATE->event.destroy();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
PRIVATE->event_write.destroy();
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -347,7 +346,7 @@ bool PISerial::setBreak(bool enabled) {
|
||||
piCoutObj << "sendBreak error: \"" << path() << "\" is not opened!";
|
||||
return false;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
if (enabled) {
|
||||
if (!SetCommBreak(PRIVATE->hCom)) {
|
||||
piCoutObj << "setBreak error: " << errorString();
|
||||
@@ -363,14 +362,14 @@ bool PISerial::setBreak(bool enabled) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
# else
|
||||
if (ioctl(fd, enabled ? TIOCSBRK : TIOCCBRK) < 0) {
|
||||
piCoutObj << "setBreak error: " << errorString();
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -380,8 +379,8 @@ bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
||||
piCoutObj << "setBit" << bname << " error: \"" << path() << "\" is not opened!";
|
||||
return false;
|
||||
}
|
||||
#ifndef PISERIAL_NO_PINS
|
||||
# ifdef WINDOWS
|
||||
# ifndef PISERIAL_NO_PINS
|
||||
# ifdef WINDOWS
|
||||
static int bit_map_on[] = {0, 0, 0, 0, SETDTR, 0, 0, SETRTS, 0, 0, 0};
|
||||
static int bit_map_off[] = {0, 0, 0, 0, CLRDTR, 0, 0, CLRRTS, 0, 0, 0};
|
||||
int action = (on ? bit_map_on : bit_map_off)[bit];
|
||||
@@ -392,14 +391,14 @@ bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
# else
|
||||
# else
|
||||
if (ioctl(fd, on ? TIOCMBIS : TIOCMBIC, &bit) < 0) {
|
||||
piCoutObj << "setBit" << bname << " error: " << errorString();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
piCoutObj << "setBit" << bname << " doesn`t implemented, sorry :-(";
|
||||
return false;
|
||||
}
|
||||
@@ -410,23 +409,23 @@ bool PISerial::isBit(int bit, const PIString & bname) const {
|
||||
piCoutObj << "isBit" << bname << " error: \"" << path() << "\" is not opened!";
|
||||
return false;
|
||||
}
|
||||
#ifndef PISERIAL_NO_PINS
|
||||
# ifdef WINDOWS
|
||||
# else
|
||||
# ifndef PISERIAL_NO_PINS
|
||||
# ifdef WINDOWS
|
||||
# else
|
||||
int ret = 0;
|
||||
if (ioctl(fd, TIOCMGET, &ret) < 0) piCoutObj << "isBit" << bname << " error: " << errorString();
|
||||
return ret & bit;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
piCoutObj << "isBit" << bname << " doesn`t implemented, sorry :-(";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PISerial::flush() {
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
if (fd != -1) tcflush(fd, TCIOFLUSH);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -441,9 +440,9 @@ int PISerial::convertSpeed(PISerial::Speed speed) {
|
||||
case S2400: return B2400;
|
||||
case S4800: return B4800;
|
||||
case S9600: return B9600;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
case S14400: return B14400;
|
||||
#endif
|
||||
# endif
|
||||
case S19200: return B19200;
|
||||
case S38400: return B38400;
|
||||
case S57600: return B57600;
|
||||
@@ -463,13 +462,13 @@ int PISerial::convertSpeed(PISerial::Speed speed) {
|
||||
case S4000000: return B4000000;
|
||||
default: break;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
piCoutObj << "Warning: Custom speed %1"_tr("PISerial").arg((int)speed);
|
||||
return (int)speed;
|
||||
#else
|
||||
# else
|
||||
piCoutObj << "Warning: Unknown speed %1, using 115200"_tr("PISerial").arg((int)speed);
|
||||
return B115200;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -675,9 +674,9 @@ bool PISerial::send(const void * data, int size) {
|
||||
void PISerial::interrupt() {
|
||||
// piCoutObj << "interrupt";
|
||||
PRIVATE->event.interrupt();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
PRIVATE->event_write.interrupt();
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -699,7 +698,7 @@ bool PISerial::openDevice() {
|
||||
}
|
||||
}
|
||||
if (p.isEmpty()) return false;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
DWORD ds = 0, sm = 0;
|
||||
if (isReadable()) {
|
||||
ds |= GENERIC_READ;
|
||||
@@ -717,7 +716,7 @@ bool PISerial::openDevice() {
|
||||
return false;
|
||||
}
|
||||
fd = 0;
|
||||
#else
|
||||
# else
|
||||
int om = 0;
|
||||
switch (mode()) {
|
||||
case PIIODevice::ReadOnly: om = O_RDONLY; break;
|
||||
@@ -732,12 +731,12 @@ bool PISerial::openDevice() {
|
||||
tcgetattr(fd, &PRIVATE->desc);
|
||||
PRIVATE->sdesc = PRIVATE->desc;
|
||||
// piCoutObj << "Initialized " << p;
|
||||
#endif
|
||||
# endif
|
||||
applySettings();
|
||||
PRIVATE->event.create();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
PRIVATE->event_write.create();
|
||||
#endif
|
||||
# endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -748,28 +747,28 @@ bool PISerial::closeDevice() {
|
||||
stopThreadedRead();
|
||||
}
|
||||
if (fd != -1) {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
SetCommState(PRIVATE->hCom, &PRIVATE->sdesc);
|
||||
SetCommMask(PRIVATE->hCom, PRIVATE->mask);
|
||||
// piCoutObj << "close" <<
|
||||
CloseHandle(PRIVATE->hCom);
|
||||
PRIVATE->hCom = 0;
|
||||
#else
|
||||
# else
|
||||
tcsetattr(fd, TCSANOW, &PRIVATE->sdesc);
|
||||
::close(fd);
|
||||
#endif
|
||||
# endif
|
||||
fd = -1;
|
||||
}
|
||||
PRIVATE->event.destroy();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
PRIVATE->event_write.destroy();
|
||||
#endif
|
||||
# endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PISerial::applySettings() {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
if (fd == -1) return;
|
||||
setTimeouts();
|
||||
GetCommMask(PRIVATE->hCom, &PRIVATE->mask);
|
||||
@@ -795,7 +794,7 @@ void PISerial::applySettings() {
|
||||
piCoutObj << "Unable to set comm state for \"%1\""_tr("PISerial").arg(path());
|
||||
return;
|
||||
}
|
||||
#else
|
||||
# else
|
||||
if (fd == -1) return;
|
||||
tcgetattr(fd, &PRIVATE->desc);
|
||||
PRIVATE->desc.c_oflag = PRIVATE->desc.c_lflag = PRIVATE->desc.c_cflag = 0;
|
||||
@@ -829,12 +828,12 @@ void PISerial::applySettings() {
|
||||
piCoutObj << "Can`t set attributes for \"%1\""_tr("PISerial").arg(path());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void PISerial::setTimeouts() {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
COMMTIMEOUTS times;
|
||||
if (isOptionSet(BlockingRead)) {
|
||||
times.ReadIntervalTimeout = MAXDWORD;
|
||||
@@ -848,9 +847,9 @@ void PISerial::setTimeouts() {
|
||||
times.WriteTotalTimeoutConstant = isOptionSet(BlockingWrite) ? 0 : 1;
|
||||
times.WriteTotalTimeoutMultiplier = 0;
|
||||
if (SetCommTimeouts(PRIVATE->hCom, ×) == -1) piCoutObj << "Unable to set timeouts for \"" << path() << "\"";
|
||||
#else
|
||||
# else
|
||||
fcntl(fd, F_SETFL, isOptionSet(BlockingRead) ? 0 : O_NONBLOCK);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -869,7 +868,7 @@ void PISerial::setTimeouts() {
|
||||
//!
|
||||
//! \~\sa \a readData(), \a readString()
|
||||
ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
if (!canRead()) return -1;
|
||||
if (sending) return -1;
|
||||
// piCoutObj << "read ..." << PRIVATE->hCom << max_size;
|
||||
@@ -899,7 +898,7 @@ ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) {
|
||||
return -1;
|
||||
// piCoutObj << "read" << (PRIVATE->readed) << errorString();
|
||||
return PRIVATE->readed;
|
||||
#else
|
||||
# else
|
||||
if (!canRead()) return -1;
|
||||
if (isOptionSet(PIIODevice::BlockingRead)) {
|
||||
if (!PRIVATE->event.wait(fd)) return -1;
|
||||
@@ -914,7 +913,7 @@ ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) {
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -923,7 +922,7 @@ ssize_t PISerial::writeDevice(const void * data, ssize_t max_size) {
|
||||
// piCoutObj << "Can`t write to uninitialized COM";
|
||||
return -1;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
DWORD wrote(0);
|
||||
// piCoutObj << "send ..." << max_size;// << ": " << PIString((char*)data, max_size);
|
||||
sending = true;
|
||||
@@ -935,11 +934,11 @@ ssize_t PISerial::writeDevice(const void * data, ssize_t max_size) {
|
||||
}
|
||||
sending = false;
|
||||
// piCoutObj << "send ok" << wrote;// << " bytes in " << path();
|
||||
#else
|
||||
# else
|
||||
ssize_t wrote;
|
||||
wrote = ::write(fd, data, max_size);
|
||||
if (isOptionSet(BlockingWrite)) tcdrain(fd);
|
||||
#endif
|
||||
# endif
|
||||
return (ssize_t)wrote;
|
||||
// piCoutObj << "Error while sending";
|
||||
}
|
||||
@@ -1064,9 +1063,9 @@ void PISerial::configureFromVariantDevice(const PIPropertyStorage & d) {
|
||||
PIVector<int> PISerial::availableSpeeds() {
|
||||
PIVector<int> spds;
|
||||
spds << 50 << 75 << 110 << 300 << 600 << 1200 << 2400 << 4800 << 9600 <<
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
14400 <<
|
||||
#endif
|
||||
# endif
|
||||
19200 << 38400 << 57600 << 115200 << 230400 << 460800 << 500000 << 576000 << 921600 << 1000000 << 1152000 << 1500000 << 2000000
|
||||
<< 2500000 << 3000000 << 3500000 << 4000000;
|
||||
return spds;
|
||||
@@ -1082,7 +1081,7 @@ PIStringList PISerial::availableDevices(bool test) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
PIString devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData) {
|
||||
PIString ret;
|
||||
const HKEY key = SetupDiOpenDevRegKey(deviceInfoSet, deviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
|
||||
@@ -1150,13 +1149,13 @@ bool parseID(PIString str, PISerial::DeviceInfo & di) {
|
||||
if (i > 0) di.pID = str.mid(i + 4, 4).toInt(16);
|
||||
return (di.vID > 0) && (di.pID > 0);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
|
||||
PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
PIVector<DeviceInfo> ret;
|
||||
DeviceInfo di;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
static const GUID guids[] = {GUID_DEVINTERFACE_MODEM, GUID_DEVINTERFACE_COMPORT};
|
||||
static const int guids_cnt = sizeof(guids) / sizeof(GUID);
|
||||
for (int i = 0; i < guids_cnt; ++i) {
|
||||
@@ -1185,12 +1184,12 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(dis);
|
||||
}
|
||||
#else
|
||||
# ifndef ANDROID
|
||||
# else
|
||||
# ifndef ANDROID
|
||||
PIStringList prefixes;
|
||||
# ifdef QNX
|
||||
# ifdef QNX
|
||||
prefixes << "ser";
|
||||
# else
|
||||
# else
|
||||
prefixes << "ttyS"
|
||||
<< "ttyO"
|
||||
<< "ttyUSB"
|
||||
@@ -1201,14 +1200,14 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
<< "ttyAMA"
|
||||
<< "rfcomm"
|
||||
<< "ircomm";
|
||||
# ifdef FREE_BSD
|
||||
# ifdef FREE_BSD
|
||||
prefixes << "cu";
|
||||
# endif
|
||||
# ifdef MAC_OS
|
||||
# endif
|
||||
# ifdef MAC_OS
|
||||
prefixes.clear();
|
||||
prefixes << "cu."
|
||||
<< "tty.";
|
||||
# endif
|
||||
# endif
|
||||
PIFile file_prefixes("/proc/tty/drivers", PIIODevice::ReadOnly);
|
||||
if (file_prefixes.open()) {
|
||||
PIString fc = PIString::fromAscii(file_prefixes.readAll()), line, cpref;
|
||||
@@ -1229,18 +1228,18 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
}
|
||||
prefixes.removeDuplicates();
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
PIDir dir("/dev");
|
||||
PIVector<PIFile::FileInfo> de = dir.entries();
|
||||
# ifdef LINUX
|
||||
# ifdef LINUX
|
||||
char linkbuf[1024];
|
||||
# endif
|
||||
# endif
|
||||
for (const auto & e: de) { // TODO changes in FileInfo
|
||||
for (const auto & p: prefixes) {
|
||||
if (e.name().startsWith(p)) {
|
||||
di = DeviceInfo();
|
||||
di.path = e.path;
|
||||
# ifdef LINUX
|
||||
# ifdef LINUX
|
||||
ssize_t lsz = readlink(("/sys/class/tty/" + e.name()).dataAscii(), linkbuf, 1024);
|
||||
if (lsz > 0) {
|
||||
PIString fpath = "/sys/class/tty/" + PIString(linkbuf, lsz) + "/";
|
||||
@@ -1256,16 +1255,16 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
if (di.pID > 0) break;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
ret << di;
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
if (test) {
|
||||
for (int i = 0; i < ret.size_s(); ++i) {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
void * hComm = CreateFileA(ret[i].path.dataAscii(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
@@ -1274,21 +1273,21 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
|
||||
0);
|
||||
if (hComm == INVALID_HANDLE_VALUE) {
|
||||
#else
|
||||
# else
|
||||
int fd = ::open(ret[i].path.dataAscii(), O_NOCTTY | O_RDONLY);
|
||||
if (fd == -1) {
|
||||
#endif
|
||||
# endif
|
||||
ret.remove(i);
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
bool rok = true;
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
int void_ = 0;
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
if (::read(fd, &void_, 1) == -1) rok = errno != EIO;
|
||||
|
||||
#endif
|
||||
# endif
|
||||
if (!rok) {
|
||||
ret.remove(i);
|
||||
--i;
|
||||
@@ -1299,11 +1298,11 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
CloseHandle(hComm);
|
||||
#else
|
||||
# else
|
||||
::close(fd);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@@ -1317,12 +1316,14 @@ void PISerial::optionsChanged() {
|
||||
|
||||
void PISerial::threadedReadBufferSizeChanged() {
|
||||
if (!isOpened()) return;
|
||||
#if defined(LINUX)
|
||||
# if defined(LINUX)
|
||||
serial_struct ss;
|
||||
ioctl(fd, TIOCGSERIAL, &ss);
|
||||
// piCoutObj << "b" << ss.xmit_fifo_size;
|
||||
ss.xmit_fifo_size = piMaxi(threadedReadBufferSize(), 4096);
|
||||
ioctl(fd, TIOCSSERIAL, &ss);
|
||||
// piCoutObj << "a" << ss.xmit_fifo_size;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_SERIAL
|
||||
|
||||
@@ -43,11 +43,11 @@ REGISTER_DEVICE(PISPI)
|
||||
|
||||
|
||||
PISPI::PISPI(const PIString & path, uint speed, PIIODevice::DeviceMode mode): PIIODevice(path, mode) {
|
||||
#ifdef MICRO_PIP
|
||||
#ifndef PIP_HAS_THREADS
|
||||
setThreadedReadBufferSize(512);
|
||||
#else
|
||||
setThreadedReadBufferSize(1024);
|
||||
#endif
|
||||
#endif // PIP_HAS_THREADS
|
||||
setPath(path);
|
||||
setSpeed(speed);
|
||||
setBits(8);
|
||||
|
||||
@@ -27,7 +27,12 @@
|
||||
const uint PIBaseTransfer::signature = 0x54424950;
|
||||
|
||||
|
||||
PIBaseTransfer::PIBaseTransfer(): crc(standardCRC_16()), diag(false) {
|
||||
PIBaseTransfer::PIBaseTransfer()
|
||||
: crc(standardCRC_16())
|
||||
#ifdef PIP_HAS_THREADS
|
||||
, diag(false)
|
||||
#endif
|
||||
{
|
||||
header.sig = signature;
|
||||
crc_enabled = true;
|
||||
header.session_id = 0;
|
||||
@@ -39,12 +44,14 @@ PIBaseTransfer::PIBaseTransfer(): crc(standardCRC_16()), diag(false) {
|
||||
send_queue = 0;
|
||||
send_up = 0;
|
||||
timeout_ = 10.;
|
||||
#ifdef PIP_HAS_THREADS
|
||||
diag.setDisconnectTimeout(PISystemTime::fromSeconds(timeout_ / 10.));
|
||||
diag.setName("PIBaseTransfer");
|
||||
diag.start(20_Hz);
|
||||
#endif
|
||||
packets_count = 10;
|
||||
#ifdef MICRO_PIP
|
||||
setPacketSize(512);
|
||||
#ifdef PIP_EMBEDDED
|
||||
setPacketSize(1024);
|
||||
#else
|
||||
setPacketSize(4096);
|
||||
#endif
|
||||
@@ -53,7 +60,9 @@ PIBaseTransfer::PIBaseTransfer(): crc(standardCRC_16()), diag(false) {
|
||||
|
||||
|
||||
PIBaseTransfer::~PIBaseTransfer() {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
diag.stopAndWait();
|
||||
#endif
|
||||
break_ = true;
|
||||
}
|
||||
|
||||
@@ -85,14 +94,18 @@ void PIBaseTransfer::setPause(bool pause_) {
|
||||
|
||||
void PIBaseTransfer::setTimeout(double sec) {
|
||||
timeout_ = sec;
|
||||
#ifdef PIP_HAS_THREADS
|
||||
diag.setDisconnectTimeout(PISystemTime::fromSeconds(sec));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PIBaseTransfer::received(PIByteArray data) {
|
||||
packet_header_size = sizeof(PacketHeader) + customHeader().size();
|
||||
if (data.size() < sizeof(PacketHeader)) {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
diag.received(data.size(), false);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
PacketHeader h;
|
||||
@@ -100,10 +113,14 @@ void PIBaseTransfer::received(PIByteArray data) {
|
||||
PacketType pt = (PacketType)h.type;
|
||||
if (!h.check_sig()) {
|
||||
piCoutObj << "invalid packet signature"_tr("PIBaseTransfer");
|
||||
#ifdef PIP_HAS_THREADS
|
||||
diag.received(data.size(), false);
|
||||
#endif
|
||||
return;
|
||||
} else
|
||||
#ifdef PIP_HAS_THREADS
|
||||
diag.received(data.size(), true);
|
||||
#endif
|
||||
// piCoutObj << "receive" << h.session_id << h.type << h.id;
|
||||
switch (pt) {
|
||||
case pt_Unknown: break;
|
||||
@@ -178,7 +195,9 @@ void PIBaseTransfer::received(PIByteArray data) {
|
||||
replies.resize(sr.packets + 1);
|
||||
replies.fill(pt_Unknown);
|
||||
pm_string.resize(replies.size(), '-');
|
||||
#ifdef PIP_HAS_THREADS
|
||||
diag.reset();
|
||||
#endif
|
||||
is_receiving = true;
|
||||
break_ = false;
|
||||
mutex_send.lock();
|
||||
@@ -290,7 +309,9 @@ bool PIBaseTransfer::send_process() {
|
||||
mutex_session.lock();
|
||||
packet_header_size = sizeof(PacketHeader) + customHeader().size();
|
||||
break_ = false;
|
||||
#ifdef PIP_HAS_THREADS
|
||||
diag.reset();
|
||||
#endif
|
||||
sendStarted();
|
||||
is_sending = true;
|
||||
int session_size = session.size();
|
||||
@@ -338,7 +359,9 @@ bool PIBaseTransfer::send_process() {
|
||||
}
|
||||
stm.reset();
|
||||
ba = build_packet(i);
|
||||
#ifdef PIP_HAS_THREADS
|
||||
diag.sended(ba.size_s());
|
||||
#endif
|
||||
sendRequest(ba);
|
||||
pm_string[i + 1] = '+';
|
||||
mutex_send.lock();
|
||||
@@ -391,7 +414,9 @@ bool PIBaseTransfer::send_process() {
|
||||
continue;
|
||||
}
|
||||
ba = build_packet(chk - 1);
|
||||
#ifdef PIP_HAS_THREADS
|
||||
diag.sended(ba.size_s());
|
||||
#endif
|
||||
sendRequest(ba);
|
||||
pm_string[chk] = '+';
|
||||
mutex_send.lock();
|
||||
@@ -496,7 +521,9 @@ void PIBaseTransfer::sendReply(PacketType reply) {
|
||||
header.type = reply;
|
||||
PIByteArray ba;
|
||||
ba << header;
|
||||
#ifdef PIP_HAS_THREADS
|
||||
if (is_sending || is_receiving) diag.sended(ba.size_s());
|
||||
#endif
|
||||
sendRequest(ba);
|
||||
}
|
||||
|
||||
@@ -515,7 +542,9 @@ bool PIBaseTransfer::getStartRequest() {
|
||||
state_string = "send request";
|
||||
PITimeMeasurer tm;
|
||||
while (tm.elapsed_s() < timeout_) {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
diag.sended(ba.size_s());
|
||||
#endif
|
||||
sendRequest(ba);
|
||||
if (break_) return false;
|
||||
// piCoutObj << replies[0];
|
||||
|
||||
@@ -161,12 +161,14 @@ public:
|
||||
//! \~russian Возвращает число байтов, уже обработанных в текущей сессии.
|
||||
llong bytesCur() const { return bytes_cur; }
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
//! \~english Get diagnostics object
|
||||
//! \~russian Получить объект диагностики
|
||||
//! \~\return
|
||||
//! \~english Diagnostic object reference
|
||||
//! \~russian Ссылка на объект диагностики
|
||||
const PIDiagnostics & diagnostic() { return diag; }
|
||||
#endif
|
||||
|
||||
//! \~english Returns the packet signature constant used by the protocol.
|
||||
//! \~russian Возвращает константу сигнатуры пакета, используемую протоколом.
|
||||
@@ -346,7 +348,9 @@ private:
|
||||
CRC_16 crc;
|
||||
int send_queue;
|
||||
int send_up;
|
||||
#ifdef PIP_HAS_THREADS
|
||||
PIDiagnostics diag;
|
||||
#endif
|
||||
PIMutex mutex_session;
|
||||
PIMutex mutex_send;
|
||||
PIMutex mutex_header;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
//! \~\brief
|
||||
//! \~english Multi-channel sender and receiver over multicast, broadcast and loopback endpoints.
|
||||
//! \~russian Многоканальный отправитель и приемник через multicast-, broadcast- и loopback-конечные точки.
|
||||
#ifdef PIP_HAS_SOCKET
|
||||
class PIP_IO_UTILS_EXPORT PIBroadcast
|
||||
: public PIThread
|
||||
, public PIEthUtilBase {
|
||||
@@ -182,5 +183,6 @@ private:
|
||||
int lo_pcnt;
|
||||
bool _started, _send_only, _reinit;
|
||||
};
|
||||
#endif // PIP_HAS_SOCKET
|
||||
|
||||
#endif // PIBROADCAST_H
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
#include "piiostream.h"
|
||||
#include "piliterals_time.h"
|
||||
#include "pitime.h"
|
||||
#include "pitranslator.h"
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
# include "pitranslator.h"
|
||||
|
||||
/** \class PIConnection
|
||||
* \brief Complex Input/Output point
|
||||
@@ -1309,3 +1311,5 @@ __DevicePoolContainer__::__DevicePoolContainer__() {
|
||||
inited_ = true;
|
||||
__device_pool__ = new PIConnection::DevicePool();
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
@@ -379,6 +379,7 @@ public:
|
||||
bool isEmpty() const { return device_modes.isEmpty(); }
|
||||
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
//! \~english Returns diagnostics object for device or filter "full_path_name".
|
||||
//! \~russian Возвращает объект диагностики для устройства или фильтра "full_path_name".
|
||||
PIDiagnostics * diagnostic(const PIString & full_path_name) const;
|
||||
@@ -386,6 +387,7 @@ public:
|
||||
//! \~english Returns diagnostics object associated with device or filter "dev".
|
||||
//! \~russian Возвращает объект диагностики, связанный с устройством или фильтром "dev".
|
||||
PIDiagnostics * diagnostic(const PIIODevice * dev) const { return diags_.value(const_cast<PIIODevice *>(dev), 0); }
|
||||
#endif
|
||||
|
||||
//! \~english Writes "data" to device resolved by full path "full_path".
|
||||
//! \~russian Записывает "data" в устройство, найденное по полному пути "full_path".
|
||||
@@ -415,6 +417,7 @@ public:
|
||||
//! \~russian Возвращает, работает ли общий пул устройств в режиме имитации.
|
||||
static bool isFakeMode();
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
class PIP_EXPORT DevicePool: public PIThread {
|
||||
PIOBJECT_SUBCLASS(DevicePool, PIThread);
|
||||
friend void __DevicePool_threadReadDP(void * ddp);
|
||||
@@ -456,6 +459,7 @@ public:
|
||||
PIMap<PIString, DeviceData *> devices;
|
||||
bool fake;
|
||||
};
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
|
||||
//! \events
|
||||
@@ -471,10 +475,12 @@ public:
|
||||
//! \~russian Генерируется, когда фильтр "from" выдает пакет.
|
||||
EVENT2(packetReceivedEvent, const PIString &, from, const PIByteArray &, data);
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
//! \fn void qualityChanged(const PIIODevice * device, PIDiagnostics::Quality new_quality, PIDiagnostics::Quality old_quality)
|
||||
//! \~english Emitted when diagnostics quality of "device" changes.
|
||||
//! \~russian Генерируется при изменении качества диагностики устройства "device".
|
||||
EVENT3(qualityChanged, const PIIODevice *, dev, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality);
|
||||
#endif
|
||||
|
||||
//! \}
|
||||
|
||||
@@ -496,7 +502,9 @@ private:
|
||||
void rawReceived(PIIODevice * dev, const PIString & from, const PIByteArray & data);
|
||||
void unboundExtractor(PIPacketExtractor * pe);
|
||||
EVENT_HANDLER2(void, packetExtractorReceived, const uchar *, data, int, size);
|
||||
#ifdef PIP_HAS_THREADS
|
||||
EVENT_HANDLER2(void, diagQualityChanged, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality);
|
||||
#endif
|
||||
|
||||
PIString devPath(const PIIODevice * d) const;
|
||||
PIString devFPath(const PIIODevice * d) const;
|
||||
@@ -509,6 +517,7 @@ private:
|
||||
PIVector<PIIODevice *> devices;
|
||||
};
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
class PIP_EXPORT Sender: public PITimer {
|
||||
PIOBJECT_SUBCLASS(Sender, PIObject);
|
||||
|
||||
@@ -521,18 +530,24 @@ private:
|
||||
PISystemTime int_;
|
||||
void tick(int) override;
|
||||
};
|
||||
#endif
|
||||
|
||||
PIMap<PIString, Extractor *> extractors;
|
||||
#ifdef PIP_HAS_THREADS
|
||||
PIMap<PIString, Sender *> senders;
|
||||
#endif
|
||||
PIMap<PIString, PIIODevice *> device_names;
|
||||
PIMap<PIIODevice *, PIIODevice::DeviceMode> device_modes;
|
||||
PIMap<PIIODevice *, PIVector<PIPacketExtractor *>> bounded_extractors;
|
||||
PIMap<PIIODevice *, PIVector<PIIODevice *>> channels_;
|
||||
#ifdef PIP_HAS_THREADS
|
||||
PIMap<PIIODevice *, PIDiagnostics *> diags_;
|
||||
#endif
|
||||
|
||||
static PIVector<PIConnection *> _connections;
|
||||
};
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
void __DevicePool_threadReadDP(void * ddp);
|
||||
|
||||
extern PIP_EXPORT PIConnection::DevicePool * __device_pool__;
|
||||
@@ -544,6 +559,7 @@ public:
|
||||
};
|
||||
|
||||
static __DevicePoolContainer__ __device_pool_container__;
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
|
||||
#endif // PICONNECTION_H
|
||||
|
||||
@@ -19,8 +19,10 @@
|
||||
|
||||
#include "pidiagnostics.h"
|
||||
|
||||
#include "piliterals_time.h"
|
||||
#include "pitranslator.h"
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
# include "piliterals_time.h"
|
||||
# include "pitranslator.h"
|
||||
|
||||
|
||||
/** \class PIDiagnostics
|
||||
@@ -250,3 +252,5 @@ void PIDiagnostics::changeDisconnectTimeout(PISystemTime disct) {
|
||||
// piCoutObj << hist_size << disconn_ << interval();
|
||||
mutex_state.unlock();
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "pitimer.h"
|
||||
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
//! \~\ingroup IO-Utils
|
||||
//! \brief
|
||||
//! \~english Connection diagnostics for packet frequency, throughput and receive quality
|
||||
@@ -56,7 +57,7 @@ public:
|
||||
enum Quality {
|
||||
Unknown = 1 /** \~english No receive history yet \~russian История приема еще отсутствует */,
|
||||
Failure = 2 /** \~english No correct packets in the recent window \~russian В недавнем окне нет корректных пакетов */,
|
||||
Bad = 3 /** \~english Correct packets are at most 20 percent \~russian Корректных пакетов не более 20 процентов */,
|
||||
Bad = 3 /** \~english Correct packets are at most 20 percent \~russian Корректных пакетов не более 20 процентов */,
|
||||
Average =
|
||||
4 /** \~english Correct packets are above 20 and up to 80 percent \~russian Корректных пакетов больше 20 и до 80 процентов */
|
||||
,
|
||||
@@ -235,5 +236,6 @@ inline bool operator!=(const PIDiagnostics::Entry & f, const PIDiagnostics::Entr
|
||||
inline bool operator<(const PIDiagnostics::Entry & f, const PIDiagnostics::Entry & s) {
|
||||
return f.bytes_ok < s.bytes_ok;
|
||||
}
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
#endif // PIDIAGNOSTICS_H
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#ifndef PIETHUTILBASE_H
|
||||
#define PIETHUTILBASE_H
|
||||
#ifdef PIP_HAS_SOCKET
|
||||
|
||||
#include "pibytearray.h"
|
||||
#include "pip_io_utils_export.h"
|
||||
@@ -96,4 +97,5 @@ private:
|
||||
bool _crypt;
|
||||
};
|
||||
|
||||
#endif // PIP_HAS_SOCKET
|
||||
#endif // PIETHUTILBASE_H
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "pifiletransfer.h"
|
||||
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
const char PIFileTransfer::sign[] = {'P', 'F', 'T'};
|
||||
|
||||
PIFileTransfer::PIFileTransfer() {
|
||||
@@ -339,3 +340,5 @@ void PIFileTransfer::send_finished(bool ok) {
|
||||
work_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
#include "pibasetransfer.h"
|
||||
#include "pidir.h"
|
||||
|
||||
#define __PIFILETRANSFER_VERSION 2
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
# define __PIFILETRANSFER_VERSION 2
|
||||
|
||||
|
||||
//! \~\ingroup IO-Utils
|
||||
@@ -70,7 +71,7 @@ public:
|
||||
PIString dest_path;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
# pragma pack(push, 1)
|
||||
|
||||
//! \~english Custom packet header used by the file-transfer protocol.
|
||||
//! \~russian Пользовательский заголовок пакета, используемый протоколом передачи файлов.
|
||||
@@ -104,7 +105,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
# pragma pack(pop)
|
||||
|
||||
|
||||
//! \~english Sends one file-system entry identified by "file".
|
||||
@@ -262,4 +263,6 @@ inline PICout operator<<(PICout s, const PIFileTransfer::PFTFileInfo & v) {
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
#endif // PIFILETRANSFER_H
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#ifndef pipackedtcp_H
|
||||
#define pipackedtcp_H
|
||||
#ifdef PIP_HAS_SOCKET
|
||||
|
||||
#include "piiodevice.h"
|
||||
#include "pinetworkaddress.h"
|
||||
@@ -122,4 +123,6 @@ private:
|
||||
|
||||
REGISTER_DEVICE(PIPackedTCP)
|
||||
|
||||
#endif // PIP_HAS_SOCKET
|
||||
|
||||
#endif
|
||||
|
||||
@@ -98,8 +98,8 @@ void PIPacketExtractor::construct() {
|
||||
func_payload = nullptr;
|
||||
setPayloadSize(0);
|
||||
setTimeout(100_ms);
|
||||
#ifdef MICRO_PIP
|
||||
setThreadedReadBufferSize(512);
|
||||
#ifdef PIP_EMBEDDED
|
||||
setThreadedReadBufferSize(16_KiB);
|
||||
#else
|
||||
setThreadedReadBufferSize(64_KiB);
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#ifndef PISTREAMPACKER_H
|
||||
#define PISTREAMPACKER_H
|
||||
#ifdef PIP_HAS_SOCKET
|
||||
|
||||
#include "piethutilbase.h"
|
||||
#include "piobject.h"
|
||||
@@ -200,4 +201,5 @@ private:
|
||||
mutable PIMutex prog_s_mutex, prog_r_mutex;
|
||||
};
|
||||
|
||||
#endif // PIP_HAS_SOCKET
|
||||
#endif // PISTREAMPACKER_H
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "pifft.h"
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
#ifdef PIP_HAS_FFT
|
||||
|
||||
PIFFT_double::PIFFT_double() {}
|
||||
|
||||
@@ -1961,4 +1961,4 @@ void PIFFT_float::ftbase_ffttwcalc(PIVector<float> * a, int aoffset, int n1, int
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MICRO_PIP
|
||||
#endif // PIP_HAS_FFT
|
||||
|
||||
+13
-13
@@ -59,7 +59,7 @@
|
||||
|
||||
#include "pimathcomplex.h"
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
#ifdef PIP_HAS_FFT
|
||||
|
||||
# include "pip_fftw_export.h"
|
||||
|
||||
@@ -225,17 +225,17 @@ typedef PIFFT_float PIFFTf;
|
||||
|
||||
# ifndef CC_VC
|
||||
|
||||
# define _PIFFTW_H(type) \
|
||||
class PIP_FFTW_EXPORT _PIFFTW_P_##type##_ { \
|
||||
public: \
|
||||
_PIFFTW_P_##type##_(); \
|
||||
~_PIFFTW_P_##type##_(); \
|
||||
const PIVector<complex<type>> & calcFFT(const PIVector<complex<type>> & in); \
|
||||
const PIVector<complex<type>> & calcFFTR(const PIVector<type> & in); \
|
||||
const PIVector<complex<type>> & calcFFTI(const PIVector<complex<type>> & in); \
|
||||
void preparePlan(int size, int op); \
|
||||
void * impl; \
|
||||
};
|
||||
# define _PIFFTW_H(type) \
|
||||
class PIP_FFTW_EXPORT _PIFFTW_P_##type##_ { \
|
||||
public: \
|
||||
_PIFFTW_P_##type##_(); \
|
||||
~_PIFFTW_P_##type##_(); \
|
||||
const PIVector<complex<type>> & calcFFT(const PIVector<complex<type>> & in); \
|
||||
const PIVector<complex<type>> & calcFFTR(const PIVector<type> & in); \
|
||||
const PIVector<complex<type>> & calcFFTI(const PIVector<complex<type>> & in); \
|
||||
void preparePlan(int size, int op); \
|
||||
void * impl; \
|
||||
};
|
||||
_PIFFTW_H(float)
|
||||
_PIFFTW_H(double)
|
||||
_PIFFTW_H(ldouble)
|
||||
@@ -384,6 +384,6 @@ typedef PIFFTW<ldouble> PIFFTWld;
|
||||
|
||||
# endif
|
||||
|
||||
#endif // MICRO_PIP
|
||||
#endif // PIP_HAS_FFT
|
||||
|
||||
#endif // PIFFT_H
|
||||
|
||||
@@ -210,4 +210,12 @@ typedef PILine<float> PILinef;
|
||||
//! \~russian Псевдоним отрезка с координатами типа `double`.
|
||||
typedef PILine<double> PILined;
|
||||
|
||||
|
||||
#if !PIP_HAS_RTTI
|
||||
__PIP_TYPENAME_DECLARE(PILined, "PILined")
|
||||
__PIP_TYPENAME_DECLARE(PILinei, "PILinei")
|
||||
__PIP_TYPENAME_DECLARE(PILinef, "PILinef")
|
||||
__PIP_TYPENAME_DECLARE(PILineu, "PILineu")
|
||||
#endif
|
||||
|
||||
#endif // PILINE_H
|
||||
|
||||
@@ -186,4 +186,11 @@ inline bool PIMathFloatNullCompare(const T v) {
|
||||
return (abs(v) < float(1E-200));
|
||||
}
|
||||
|
||||
|
||||
#if !PIP_HAS_RTTI
|
||||
__PIP_TYPENAME_DECLARE(complexf, "complexf")
|
||||
__PIP_TYPENAME_DECLARE(complexd, "complexd")
|
||||
__PIP_TYPENAME_DECLARE(complexld, "complexld")
|
||||
#endif
|
||||
|
||||
#endif // PIMATHCOMPLEX_H
|
||||
|
||||
@@ -1652,6 +1652,12 @@ PIMathMatrix<complex<T>> hermitian(const PIMathMatrix<complex<T>> & m) {
|
||||
return ret.transposed();
|
||||
}
|
||||
|
||||
|
||||
#if !PIP_HAS_RTTI
|
||||
__PIP_TYPENAME_DECLARE(PIMathMatrixd, "PIMathMatrixd")
|
||||
__PIP_TYPENAME_DECLARE(PIMathMatrixi, "PIMathMatrixi")
|
||||
#endif
|
||||
|
||||
#undef PIMM_FOR
|
||||
#undef PIMM_FOR_A
|
||||
#undef PIMM_FOR_C
|
||||
|
||||
@@ -909,4 +909,10 @@ typedef PIMathVector<int> PIMathVectori;
|
||||
//! \~russian Динамический вектор из \c double.
|
||||
typedef PIMathVector<double> PIMathVectord;
|
||||
|
||||
|
||||
#if !PIP_HAS_RTTI
|
||||
__PIP_TYPENAME_DECLARE(PIMathVectord, "PIMathVectord")
|
||||
__PIP_TYPENAME_DECLARE(PIMathVectori, "PIMathVectori")
|
||||
#endif
|
||||
|
||||
#endif // PIMATHVECTOR_H
|
||||
|
||||
@@ -286,4 +286,12 @@ typedef PIPoint<float> PIPointf;
|
||||
//! \~russian Псевдоним точки с координатами типа `double`.
|
||||
typedef PIPoint<double> PIPointd;
|
||||
|
||||
|
||||
#if !PIP_HAS_RTTI
|
||||
__PIP_TYPENAME_DECLARE(PIPointd, "PIPointd")
|
||||
__PIP_TYPENAME_DECLARE(PIPointi, "PIPointi")
|
||||
__PIP_TYPENAME_DECLARE(PIPointf, "PIPointf")
|
||||
__PIP_TYPENAME_DECLARE(PIPointu, "PIPointu")
|
||||
#endif
|
||||
|
||||
#endif // PIPOINT_H
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//! \~russian Класс прямоугольника для 2D геометрии
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Rect class for 2D geometry
|
||||
Rect class for 2D geometry
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -444,4 +444,12 @@ typedef PIRect<float> PIRectf;
|
||||
//! \~russian Псевдоним прямоугольника с координатами типа `double`.
|
||||
typedef PIRect<double> PIRectd;
|
||||
|
||||
|
||||
#if !PIP_HAS_RTTI
|
||||
__PIP_TYPENAME_DECLARE(PIRectd, "PIRectd")
|
||||
__PIP_TYPENAME_DECLARE(PIRecti, "PIRecti")
|
||||
__PIP_TYPENAME_DECLARE(PIRectf, "PIRectf")
|
||||
__PIP_TYPENAME_DECLARE(PIRectu, "PIRectu")
|
||||
#endif
|
||||
|
||||
#endif // PIRECT_H
|
||||
|
||||
@@ -4,27 +4,28 @@
|
||||
//! \~english
|
||||
//! \~russian
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
MQTT common types
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
MQTT common types
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is 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.
|
||||
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/>.
|
||||
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 pimqtttypes_h
|
||||
#define pimqtttypes_h
|
||||
|
||||
#include "pibinarystream.h"
|
||||
#include "pip_export.h"
|
||||
#include "pistringlist.h"
|
||||
|
||||
@@ -159,7 +160,26 @@ public:
|
||||
//! \~russian Возвращает ID сообщения.
|
||||
MessageMutable & setID(int id);
|
||||
};
|
||||
template<typename P>
|
||||
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const MessageConst & v) {
|
||||
s << v.topic() << v.pathArguments() << v.payload() << v.properties() << static_cast<int>(v.qos()) << v.ID() << v.isDuplicate();
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename P>
|
||||
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, MessageMutable & v) {
|
||||
PIString topic;
|
||||
PIMap<PIString, PIString> path_args;
|
||||
PIByteArray payload;
|
||||
PIMap<int, PIString> props;
|
||||
int qos_val, msg_id;
|
||||
bool is_dup;
|
||||
s >> topic >> path_args >> payload >> props >> qos_val >> msg_id >> is_dup;
|
||||
v.setTopic(topic).setPayload(payload).setQos(static_cast<QoS>(qos_val)).setID(msg_id).setDuplicate(is_dup);
|
||||
v.pathArguments() = path_args;
|
||||
v.properties() = props;
|
||||
return s;
|
||||
}
|
||||
|
||||
}; // namespace PIMQTT
|
||||
|
||||
|
||||
+12
-5
@@ -78,7 +78,7 @@
|
||||
//! \~\brief
|
||||
//! \~english Defined for reduced embedded PIP builds.
|
||||
//! \~russian Определяется для облегченных встраиваемых сборок PIP.
|
||||
# define MICRO_PIP
|
||||
# define PIP_EMBEDDED
|
||||
|
||||
//! \~\ingroup Core
|
||||
//! \~\brief
|
||||
@@ -153,8 +153,13 @@
|
||||
#ifdef PIP_FREERTOS
|
||||
# define FREERTOS
|
||||
#endif
|
||||
#if defined(FREERTOS) || defined(PLATFORMIO)
|
||||
# define MICRO_PIP
|
||||
#ifdef PICO_SDK
|
||||
# define PISERIAL_NO_PINS
|
||||
#endif
|
||||
#ifdef FREERTOS
|
||||
# ifndef PISERIAL_NO_PINS
|
||||
# define PISERIAL_NO_PINS
|
||||
# endif
|
||||
#endif
|
||||
#ifndef WINDOWS
|
||||
# ifndef QNX
|
||||
@@ -162,8 +167,10 @@
|
||||
# ifndef MAC_OS
|
||||
# ifndef ANDROID
|
||||
# ifndef BLACKBERRY
|
||||
# ifndef MICRO_PIP
|
||||
# define LINUX
|
||||
# ifndef FREERTOS
|
||||
# ifndef PICO_SDK
|
||||
# define LINUX
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
|
||||
@@ -43,11 +43,15 @@ PIString mask(const PIString & str) {
|
||||
}
|
||||
|
||||
PIString overrideFile(PIString path) {
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
if (path.isEmpty()) return {};
|
||||
PIFile::FileInfo fi(path);
|
||||
auto ext = fi.extension();
|
||||
path.insert(path.size_s() - ext.size_s() - (ext.isEmpty() ? 0 : 1), ".override");
|
||||
return path;
|
||||
#else
|
||||
return path;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -138,7 +142,9 @@ PIValueTree PIValueTreeConversions::fromText(PIIODevice * device) {
|
||||
PIMap<PIString, PIString> substitutions;
|
||||
if (!device) return ret;
|
||||
PIString base_path;
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
if (device->isTypeOf<PIFile>()) base_path = PIFile::FileInfo(device->path()).dir().replaceAll('\\', '/');
|
||||
#endif
|
||||
PIIOTextStream ts(device);
|
||||
PIString line, comm;
|
||||
PIVariant value;
|
||||
@@ -211,10 +217,12 @@ PIValueTree PIValueTreeConversions::fromText(PIIODevice * device) {
|
||||
line.cutLeft(1).trim();
|
||||
if (path.front() == "include") {
|
||||
PIString include = line.trimmed();
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
if (!PIFile::FileInfo(include).isAbsolute()) {
|
||||
include = base_path + "/" + include.replaceAll('\\', '/');
|
||||
include.replaceAll("//", '/');
|
||||
}
|
||||
#endif
|
||||
PIValueTree inc_vt = PIValueTreeConversions::fromTextFile(include);
|
||||
inc_vt.forEachRecursive(
|
||||
[&substitutions](const PIValueTree & v, const PIString & fn) { substitutions[fn] = v.value().toString(); });
|
||||
@@ -345,6 +353,9 @@ PIValueTree PIValueTreeConversions::fromText(const PIString & str) {
|
||||
|
||||
|
||||
PIValueTree PIValueTreeConversions::fromJSONFile(const PIString & path) {
|
||||
#ifndef PIP_HAS_FILESYSTEM
|
||||
return PIValueTree();
|
||||
#else
|
||||
auto ret = PIValueTreeConversions::fromJSON(PIJSON::fromJSON(PIString::fromUTF8(PIFile::readAll(path))));
|
||||
auto ofp = overrideFile(path);
|
||||
if (PIFile::isExists(ofp)) {
|
||||
@@ -352,10 +363,14 @@ PIValueTree PIValueTreeConversions::fromJSONFile(const PIString & path) {
|
||||
ret.merge(override_vt);
|
||||
}
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PIValueTree PIValueTreeConversions::fromTextFile(const PIString & path) {
|
||||
#ifndef PIP_HAS_FILESYSTEM
|
||||
return PIValueTree();
|
||||
#else
|
||||
PIFile f(path, PIIODevice::ReadOnly);
|
||||
auto ret = PIValueTreeConversions::fromText(&f);
|
||||
auto ofp = overrideFile(path);
|
||||
@@ -365,18 +380,27 @@ PIValueTree PIValueTreeConversions::fromTextFile(const PIString & path) {
|
||||
ret.merge(override_vt);
|
||||
}
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIValueTreeConversions::toJSONFile(const PIString & path, const PIValueTree & root, Options options) {
|
||||
#ifndef PIP_HAS_FILESYSTEM
|
||||
return false;
|
||||
#else
|
||||
auto d = toJSON(root, options).toJSON(PIJSON::Tree).toUTF8();
|
||||
int written = PIFile::writeAll(path, d);
|
||||
return written == d.size_s();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIValueTreeConversions::toTextFile(const PIString & path, const PIValueTree & root, Options options) {
|
||||
#ifndef PIP_HAS_FILESYSTEM
|
||||
return false;
|
||||
#else
|
||||
auto d = toText(root, options).toUTF8();
|
||||
int written = PIFile::writeAll(path, d);
|
||||
return written == d.size_s();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -41,7 +41,11 @@ template<typename... Args>
|
||||
class Function: public FunctionBase {
|
||||
public:
|
||||
uint formatHash() override {
|
||||
#if defined(__GXX_RTTI__) || defined(__RTTI__)
|
||||
static uint ret = PIConstChars(typeid(std::function<void(Args...)>).name()).hash();
|
||||
#else
|
||||
static uint ret = 0;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
std::function<bool(Args...)> func;
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
State machine
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
State machine
|
||||
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 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.
|
||||
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/>.
|
||||
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 "pistatemachine_transition.h"
|
||||
@@ -99,24 +99,32 @@ void PITransitionBase::trigger() {
|
||||
|
||||
PITransitionTimeout::PITransitionTimeout(PIStateBase * source, PIStateBase * target, PISystemTime timeout)
|
||||
: PITransitionBase(source, target, 0) {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
timer.setInterval(timeout);
|
||||
timer.setSlot([this] {
|
||||
trigger();
|
||||
timer.stop();
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PITransitionTimeout::~PITransitionTimeout() {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
timer.stopAndWait();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PITransitionTimeout::enabled() {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
timer.start();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PITransitionTimeout::disabled() {
|
||||
#ifdef PIP_HAS_THREADS
|
||||
timer.stop();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
//! \~russian Объявляет переходы, используемые в PIStateMachine
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
State machine transition
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
State machine transition
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
@@ -142,7 +142,9 @@ private:
|
||||
void enabled() override;
|
||||
void disabled() override;
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
PITimer timer;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,18 +2,29 @@
|
||||
|
||||
#include "piliterals_string.h"
|
||||
#include "piliterals_time.h"
|
||||
#ifndef WINDOWS
|
||||
# include "pidir.h"
|
||||
# include "pifile.h"
|
||||
# include "piiostream.h"
|
||||
|
||||
# include <fcntl.h>
|
||||
# include <linux/input-event-codes.h>
|
||||
# include <linux/input.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/time.h>
|
||||
# include <unistd.h>
|
||||
#else
|
||||
#ifdef PIP_HAS_THREADS
|
||||
# ifndef WINDOWS
|
||||
# include "pidir.h"
|
||||
# include "pifile.h"
|
||||
# include "piiostream.h"
|
||||
|
||||
# ifdef LINUX
|
||||
# include <fcntl.h>
|
||||
# include <linux/input-event-codes.h>
|
||||
# include <linux/input.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/time.h>
|
||||
# include <unistd.h>
|
||||
# else
|
||||
// Stubs for embedded/non-Linux builds
|
||||
# define EV_SYN 0
|
||||
# define EV_KEY 1
|
||||
# define EV_REL 2
|
||||
# define EV_ABS 3
|
||||
# define EVIOCGABS(_v) 0
|
||||
# endif
|
||||
# else
|
||||
// clang-format off
|
||||
# undef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0600
|
||||
@@ -23,7 +34,7 @@ extern "C" {
|
||||
# include <hidsdi.h>
|
||||
}
|
||||
// clang-format on
|
||||
#endif
|
||||
# endif
|
||||
|
||||
|
||||
bool PIHIDeviceInfo::match(const PIString & str) const {
|
||||
@@ -70,14 +81,14 @@ PICout operator<<(PICout s, const PIHIDeviceInfo & v) {
|
||||
|
||||
|
||||
PRIVATE_DEFINITION_START(PIHIDevice)
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
PIFile file;
|
||||
bool is_js = false;
|
||||
#else
|
||||
# else
|
||||
PIByteArray buffer;
|
||||
HANDLE deviceHandle = nullptr;
|
||||
PHIDP_PREPARSED_DATA preparsed = nullptr;
|
||||
#endif
|
||||
# endif
|
||||
PRIVATE_DEFINITION_END(PIHIDevice)
|
||||
|
||||
|
||||
@@ -86,11 +97,11 @@ PIHIDevice::~PIHIDevice() {
|
||||
}
|
||||
|
||||
bool PIHIDevice::isOpened() const {
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
return PRIVATE->file.isOpened();
|
||||
#else
|
||||
# else
|
||||
return PRIVATE->deviceHandle;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -101,21 +112,21 @@ bool PIHIDevice::open(const PIHIDeviceInfo & device) {
|
||||
di = device;
|
||||
di.prepare();
|
||||
if (device.isNull()) return false;
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
if (!PRIVATE->file.open(di.path, PIIODevice::ReadOnly)) {
|
||||
piCout << "PIHIDevice::open" << di.path << "error:" << errorString();
|
||||
return false;
|
||||
}
|
||||
PRIVATE->is_js = PIFile::FileInfo(di.path).name().startsWith("js"_a);
|
||||
return true;
|
||||
#else
|
||||
# else
|
||||
PRIVATE->deviceHandle = CreateFileA(di.path.dataAscii(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
nullptr);
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
nullptr);
|
||||
if (PRIVATE->deviceHandle == INVALID_HANDLE_VALUE) {
|
||||
piCoutObj << "PIHIDevice::open" << di.path << "error:" << errorString();
|
||||
PRIVATE->deviceHandle = nullptr;
|
||||
@@ -127,7 +138,7 @@ bool PIHIDevice::open(const PIHIDeviceInfo & device) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -138,9 +149,9 @@ bool PIHIDevice::open() {
|
||||
|
||||
void PIHIDevice::close() {
|
||||
stop();
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
PRIVATE->file.close();
|
||||
#else
|
||||
# else
|
||||
if (PRIVATE->deviceHandle) {
|
||||
CloseHandle(PRIVATE->deviceHandle);
|
||||
PRIVATE->deviceHandle = nullptr;
|
||||
@@ -149,34 +160,34 @@ void PIHIDevice::close() {
|
||||
HidD_FreePreparsedData(PRIVATE->preparsed);
|
||||
PRIVATE->preparsed = nullptr;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void PIHIDevice::start() {
|
||||
if (!isOpened()) return;
|
||||
PIThread::start(200_Hz);
|
||||
#ifndef WINDOWS
|
||||
#else
|
||||
#endif
|
||||
# ifndef WINDOWS
|
||||
# else
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void PIHIDevice::stop() {
|
||||
PIThread::stop();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
if (PRIVATE->deviceHandle) {
|
||||
CancelIoEx(PRIVATE->deviceHandle, nullptr);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
if (!waitForFinish(1000_ms)) terminate();
|
||||
}
|
||||
|
||||
|
||||
void PIHIDevice::run() {
|
||||
Event e;
|
||||
#ifndef WINDOWS
|
||||
# pragma pack(push, 1)
|
||||
# ifndef WINDOWS
|
||||
# pragma pack(push, 1)
|
||||
struct input_event {
|
||||
struct timeval time;
|
||||
ushort type;
|
||||
@@ -189,7 +200,7 @@ void PIHIDevice::run() {
|
||||
uchar type; /* event type */
|
||||
uchar number; /* axis/button number */
|
||||
};
|
||||
# pragma pack(pop)
|
||||
# pragma pack(pop)
|
||||
if (PRIVATE->is_js) {
|
||||
js_event ie;
|
||||
while (PRIVATE->file.read(&ie, sizeof(ie)) == sizeof(ie)) {
|
||||
@@ -244,7 +255,7 @@ void PIHIDevice::run() {
|
||||
if (!ok) continue;
|
||||
}
|
||||
}
|
||||
#else
|
||||
# else
|
||||
PRIVATE->buffer.resize(di.input_report_size).fill(0);
|
||||
DWORD readed = 0;
|
||||
// piCout << "read" << PRIVATE->deviceHandle << PRIVATE->buffer.size();
|
||||
@@ -284,7 +295,7 @@ void PIHIDevice::run() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
auto ait = cur_axes.makeIterator();
|
||||
e.type = Event::tAxisMove;
|
||||
@@ -324,7 +335,7 @@ double PIHIDevice::procDeadZone(double in) {
|
||||
PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
PIVector<PIHIDeviceInfo> ret;
|
||||
|
||||
#ifndef WINDOWS
|
||||
# ifndef WINDOWS
|
||||
|
||||
auto readFile = [](const PIString & path) {
|
||||
auto ba = PIFile::readAll(path);
|
||||
@@ -370,11 +381,11 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
}
|
||||
/*bool dev_found = false;
|
||||
for (const auto & d: devs) {
|
||||
if (d.startsWith("js"_a)) {
|
||||
dev.path = "/dev/input/"_a + d;
|
||||
dev_found = true;
|
||||
break;
|
||||
}
|
||||
if (d.startsWith("js"_a)) {
|
||||
dev.path = "/dev/input/"_a + d;
|
||||
dev_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!dev_found) {*/
|
||||
// search for event<N> dir
|
||||
@@ -399,6 +410,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
ullong bits = readFile(hd_i.path + file).toULLong(16);
|
||||
// piCout<< PICoutManipulators::Bin << abs;
|
||||
if (bits > 0) {
|
||||
# ifdef LINUX
|
||||
int fd = ::open(dev.path.dataAscii(), O_RDONLY);
|
||||
if (fd < 0) {
|
||||
// piCout << "Warning: can`t open" << dev.path << errorString();
|
||||
@@ -423,6 +435,19 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
}
|
||||
}
|
||||
if (fd >= 0) ::close(fd);
|
||||
# else
|
||||
// Stub implementation for non-Linux builds
|
||||
PIHIDeviceInfo::AxisInfo ai;
|
||||
ai.is_relative = is_relative;
|
||||
ai.min = 0;
|
||||
ai.max = 1024;
|
||||
for (int bit = 0; bit < 64; ++bit) {
|
||||
if (checkBit(bits, bit, PIString::fromNumber(bit))) {
|
||||
ai.data_index = bit;
|
||||
ret << ai;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
@@ -473,7 +498,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
# else
|
||||
|
||||
GUID guid;
|
||||
HidD_GetHidGuid(&guid);
|
||||
@@ -495,23 +520,23 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
PIScopeExitCall exit_call([&deviceInterfaceDetailData]() { delete[] reinterpret_cast<BYTE *>(deviceInterfaceDetailData); });
|
||||
deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet,
|
||||
&deviceInterfaceData,
|
||||
deviceInterfaceDetailData,
|
||||
requiredSize,
|
||||
nullptr,
|
||||
nullptr)) {
|
||||
&deviceInterfaceData,
|
||||
deviceInterfaceDetailData,
|
||||
requiredSize,
|
||||
nullptr,
|
||||
nullptr)) {
|
||||
piCout << "SetupDiGetDeviceInterfaceDetail error:" << errorString();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (try_open) {
|
||||
auto test_f = CreateFileA(deviceInterfaceDetailData->DevicePath,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
nullptr);
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
nullptr);
|
||||
if (test_f == INVALID_HANDLE_VALUE) continue;
|
||||
CloseHandle(test_f);
|
||||
}
|
||||
@@ -634,7 +659,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoSet);
|
||||
|
||||
#endif
|
||||
# endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -648,3 +673,5 @@ PIHIDeviceInfo PIHIDevice::findDevice(const PIString & name) {
|
||||
}
|
||||
return PIHIDeviceInfo();
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
@@ -169,6 +169,7 @@ PIP_EXPORT PICout operator<<(PICout s, const PIHIDeviceInfo & v);
|
||||
//! \~english Provides access to HID (Human Interface Device) devices such as game controllers, joysticks, and other input devices.
|
||||
//! \~russian Предоставляет доступ к HID (Human Interface Device) устройствам, таким как геймконтроллеры, джойстики и другие устройства
|
||||
//! ввода.
|
||||
#ifdef PIP_HAS_THREADS
|
||||
class PIP_EXPORT PIHIDevice: public PIThread {
|
||||
PIOBJECT_SUBCLASS(PIHIDevice, PIThread)
|
||||
|
||||
@@ -188,7 +189,7 @@ public:
|
||||
tNone /** \~english Empty event \~russian Пустое событие */,
|
||||
tButton /** \~english Button state change \~russian Изменение состояния кнопки */,
|
||||
tAxisMove /** \~english Axis value change or relative axis delta \~russian Изменение значения оси или дельта относительной оси
|
||||
*/
|
||||
*/
|
||||
,
|
||||
};
|
||||
|
||||
@@ -270,6 +271,7 @@ private:
|
||||
PIMap<int, int> prev_buttons, cur_buttons;
|
||||
float dead_zone = 0.f;
|
||||
};
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
#ifdef PIP_HAS_DYNLIB
|
||||
|
||||
# include "pilibrary.h"
|
||||
|
||||
@@ -233,4 +233,4 @@ void PILibrary::getLastError() {
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif // MICRO_PIP
|
||||
#endif // PIP_HAS_DYNLIB
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef PILIBRARY_H
|
||||
#define PILIBRARY_H
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
#ifdef PIP_HAS_DYNLIB
|
||||
|
||||
# include "pistring.h"
|
||||
|
||||
@@ -82,5 +82,5 @@ private:
|
||||
PIString libpath, liberror;
|
||||
};
|
||||
|
||||
#endif // MICRO_PIP
|
||||
#endif // PIP_HAS_DYNLIB
|
||||
#endif // PILIBRARY_H
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
#ifdef PIP_HAS_DYNLIB
|
||||
|
||||
# include "piplugin.h"
|
||||
|
||||
@@ -493,4 +493,4 @@ PIString PIPluginLoader::libExtension() {
|
||||
}
|
||||
|
||||
|
||||
#endif // MICRO_PIP
|
||||
#endif // PIP_HAS_DYNLIB
|
||||
|
||||
+21
-23
@@ -28,7 +28,7 @@
|
||||
#ifndef PIPLUGIN_H
|
||||
#define PIPLUGIN_H
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
#ifdef PIP_HAS_DYNLIB
|
||||
|
||||
# include "pilibrary.h"
|
||||
# include "pistringlist.h"
|
||||
@@ -96,30 +96,28 @@
|
||||
# define __PIP_PLUGIN_STATIC_MERGE_FUNC__ pip_merge_static
|
||||
# define __PIP_PLUGIN_LOADER_VERSION__ 2
|
||||
|
||||
# define PIP_PLUGIN_SET_USER_VERSION(v) \
|
||||
STATIC_INITIALIZER_BEGIN \
|
||||
PIPluginInfo * pi = PIPluginInfoStorage::instance()->currentInfo(); \
|
||||
if (pi) pi->setUserVersion(v); \
|
||||
STATIC_INITIALIZER_END
|
||||
# define PIP_PLUGIN_SET_USER_VERSION(v) \
|
||||
STATIC_INITIALIZER_BEGIN \
|
||||
PIPluginInfo * pi = PIPluginInfoStorage::instance()->currentInfo(); \
|
||||
if (pi) pi->setUserVersion(v); \
|
||||
STATIC_INITIALIZER_END
|
||||
|
||||
# define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) \
|
||||
STATIC_INITIALIZER_BEGIN \
|
||||
PIPluginInfo * pi = PIPluginInfoStorage::instance()->currentInfo(); \
|
||||
if (pi) pi->setStaticSection(type, ptr); \
|
||||
STATIC_INITIALIZER_END
|
||||
# define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) \
|
||||
STATIC_INITIALIZER_BEGIN \
|
||||
PIPluginInfo * pi = PIPluginInfoStorage::instance()->currentInfo(); \
|
||||
if (pi) pi->setStaticSection(type, ptr); \
|
||||
STATIC_INITIALIZER_END
|
||||
|
||||
# define PIP_PLUGIN \
|
||||
extern "C" { \
|
||||
PIP_PLUGIN_EXPORT int __PIP_PLUGIN_LOADER_VERSION_FUNC__() { \
|
||||
return __PIP_PLUGIN_LOADER_VERSION__; \
|
||||
} \
|
||||
}
|
||||
# define PIP_PLUGIN \
|
||||
extern "C" { \
|
||||
PIP_PLUGIN_EXPORT int __PIP_PLUGIN_LOADER_VERSION_FUNC__() { return __PIP_PLUGIN_LOADER_VERSION__; } \
|
||||
}
|
||||
|
||||
# define PIP_PLUGIN_STATIC_SECTION_MERGE \
|
||||
extern "C" { \
|
||||
PIP_PLUGIN_EXPORT void __PIP_PLUGIN_STATIC_MERGE_FUNC__(int type, void * from, void * to); \
|
||||
} \
|
||||
void __PIP_PLUGIN_STATIC_MERGE_FUNC__(int type, void * from, void * to)
|
||||
# define PIP_PLUGIN_STATIC_SECTION_MERGE \
|
||||
extern "C" { \
|
||||
PIP_PLUGIN_EXPORT void __PIP_PLUGIN_STATIC_MERGE_FUNC__(int type, void * from, void * to); \
|
||||
} \
|
||||
void __PIP_PLUGIN_STATIC_MERGE_FUNC__(int type, void * from, void * to)
|
||||
|
||||
|
||||
# endif
|
||||
@@ -300,5 +298,5 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif // MICRO_PIP
|
||||
#endif // PIP_HAS_DYNLIB
|
||||
#endif // PIPLUGIN_H
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "pitime.h"
|
||||
#ifndef MICRO_PIP
|
||||
#ifdef PIP_HAS_PROCESS
|
||||
|
||||
# include "piincludes_p.h"
|
||||
# include "piliterals_bytes.h"
|
||||
@@ -516,4 +516,4 @@ PIString PIProcess::getEnvironmentVariable(const PIString & variable) {
|
||||
return PIString();
|
||||
}
|
||||
|
||||
#endif // MICRO_PIP
|
||||
#endif // PIP_HAS_PROCESS
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef PIPROCESS_H
|
||||
#define PIPROCESS_H
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
#ifdef PIP_HAS_PROCESS
|
||||
|
||||
# include "pithread.h"
|
||||
|
||||
@@ -258,5 +258,5 @@ private:
|
||||
std::atomic_bool exec_finished;
|
||||
};
|
||||
|
||||
#endif // MICRO_PIP
|
||||
#endif // PIP_HAS_PROCESS
|
||||
#endif // PIPROCESS_H
|
||||
|
||||
@@ -207,11 +207,19 @@ PIVector<PISystemInfo::MountInfo> PISystemInfo::mountInfo(bool ignore_cache) {
|
||||
PIString confDir() {
|
||||
return
|
||||
#ifdef WINDOWS
|
||||
# ifdef PIP_HAS_FILESYSTEM
|
||||
PIDir::home().path() + "/AppData/Local"
|
||||
# else
|
||||
""
|
||||
# endif
|
||||
#elif defined(ANDROID)
|
||||
""
|
||||
#else
|
||||
# ifdef PIP_HAS_FILESYSTEM
|
||||
PIDir::home().path() + "/.config"
|
||||
# else
|
||||
""
|
||||
# endif
|
||||
#endif
|
||||
;
|
||||
}
|
||||
@@ -234,11 +242,13 @@ PIString PISystemInfo::machineKey() {
|
||||
PISystemInfo * si = instance();
|
||||
PIByteArray salt;
|
||||
PIString conf = confDir() + "/.pip_machine_salt";
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
if (PIFile::isExists(conf)) salt = PIFile::readAll(conf);
|
||||
if (salt.size_s() != SALT_SIZE) {
|
||||
salt = generateSalt();
|
||||
PIFile::writeAll(conf, salt);
|
||||
}
|
||||
#endif
|
||||
ret = si->OS_name + "_" + si->architecture + "_" + si->hostname + "_" + salt.toHex();
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
|
||||
#include "pisystemtests.h"
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
#ifdef PIP_HAS_FILESYSTEM
|
||||
# include "piconfig.h"
|
||||
#endif
|
||||
#endif // PIP_HAS_FILESYSTEM
|
||||
|
||||
|
||||
namespace PISystemTests {
|
||||
@@ -35,10 +35,10 @@ PISystemTestReader pisystestreader;
|
||||
|
||||
|
||||
PISystemTests::PISystemTestReader::PISystemTestReader() {
|
||||
#if !defined(WINDOWS) && !defined(MICRO_PIP)
|
||||
#if !defined(WINDOWS) && defined(PIP_HAS_FILESYSTEM)
|
||||
PIConfig conf(PIStringAscii("/etc/pip.conf"), PIIODevice::ReadOnly);
|
||||
time_resolution_ns = conf.getValue(PIStringAscii("time_resolution_ns"), 1).toLong();
|
||||
time_elapsed_ns = conf.getValue(PIStringAscii("time_elapsed_ns"), 0).toLong();
|
||||
usleep_offset_us = conf.getValue(PIStringAscii("usleep_offset_us"), 60).toLong();
|
||||
#endif
|
||||
#endif // !WINDOWS && PIP_HAS_FILESYSTEM
|
||||
}
|
||||
|
||||
@@ -270,4 +270,9 @@ inline bool operator<=(ushort v, const PIChar & c) {
|
||||
return (PIChar(v) <= c);
|
||||
}
|
||||
|
||||
|
||||
#if !PIP_HAS_RTTI
|
||||
__PIP_TYPENAME_DECLARE(PIChar, "PIChar")
|
||||
#endif
|
||||
|
||||
#endif // PICHAR_H
|
||||
|
||||
@@ -2052,4 +2052,8 @@ inline PIString piStringify(const T & v) {
|
||||
}
|
||||
|
||||
|
||||
#if !PIP_HAS_RTTI
|
||||
__PIP_TYPENAME_DECLARE(PIString, "PIString")
|
||||
#endif
|
||||
|
||||
#endif // PISTRING_H
|
||||
|
||||
@@ -216,4 +216,9 @@ inline PICout operator<<(PICout s, const PIStringList & v) {
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
#if !PIP_HAS_RTTI
|
||||
__PIP_TYPENAME_DECLARE(PIStringList, "PIStringList")
|
||||
#endif
|
||||
|
||||
#endif // PISTRINGLIST_H
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
# define _WIN32_WINNT 0x0600
|
||||
#endif
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
#include "piconditionvar.h"
|
||||
#include "piincludes_p.h"
|
||||
#ifdef WINDOWS
|
||||
@@ -177,3 +178,4 @@ void PIConditionVariable::notifyAll() {
|
||||
pthread_cond_broadcast(&PRIVATE->nativeHandle);
|
||||
#endif
|
||||
}
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
//! \~english Condition variable for waiting and notification between threads
|
||||
//! \~russian Переменная условия для ожидания и уведомления между потоками
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Condition variable for waiting and notification between threads
|
||||
Stephan Fomenko
|
||||
PIP - Platform Independent Primitives
|
||||
Condition variable for waiting and notification between threads
|
||||
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 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.
|
||||
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/>.
|
||||
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 PICONDITIONVAR_H
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "pimutex.h"
|
||||
#include "pisystemtime.h"
|
||||
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
//! \~\ingroup Thread
|
||||
//! \~\brief
|
||||
//! \~english Condition variable used together with external %PIMutex.
|
||||
@@ -106,7 +108,7 @@ public:
|
||||
//! \param condition вызываемый объект или функция, не принимающая аргументов и возвращающая значение, которое может быть оценено как
|
||||
//! bool. Вызывается повторно, пока не примет значение true
|
||||
//!
|
||||
virtual void wait(PIMutex & lk, std::function<bool ()> condition);
|
||||
virtual void wait(PIMutex & lk, std::function<bool()> condition);
|
||||
|
||||
|
||||
//! \~english Waits for at most \a timeout and returns \c true if awakened before it expires.
|
||||
@@ -173,5 +175,18 @@ private:
|
||||
PRIVATE_DECLARATION(PIP_EXPORT)
|
||||
};
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
#ifndef PIP_HAS_THREADS
|
||||
class PIConditionVariable {
|
||||
public:
|
||||
void wait(PIMutex &) {}
|
||||
void wait(PIMutex &, std::function<bool()>) {}
|
||||
bool waitFor(PIMutex &, PISystemTime) { return false; }
|
||||
bool waitFor(PIMutex &, PISystemTime, std::function<bool()>) { return false; }
|
||||
void notifyOne() {}
|
||||
void notifyAll() {}
|
||||
};
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
#endif // PICONDITIONVAR_H
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
//! \}
|
||||
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
#include "pimutex.h"
|
||||
|
||||
#include "piincludes_p.h"
|
||||
@@ -228,3 +229,4 @@ void PIMutex::destroy() {
|
||||
pthread_mutex_destroy(&(PRIVATE->mutex));
|
||||
#endif
|
||||
}
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "piinit.h"
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
//! \~\ingroup Thread
|
||||
//! \~\brief
|
||||
//! \~english Mutex for mutual exclusion between threads.
|
||||
@@ -93,5 +94,29 @@ private:
|
||||
bool cond;
|
||||
};
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
#ifndef PIP_HAS_THREADS
|
||||
//! \~\ingroup Thread
|
||||
//! \~\brief
|
||||
//! \~english Dummy mutex for builds without threading support.
|
||||
//! \~russian Заглушка мьютекса для сборки без поддержки потоков.
|
||||
class PIMutex {
|
||||
public:
|
||||
void lock() {}
|
||||
void unlock() {}
|
||||
bool tryLock() { return true; }
|
||||
void * handle() { return nullptr; }
|
||||
};
|
||||
|
||||
//! \~\ingroup Thread
|
||||
//! \~\brief
|
||||
//! \~english Dummy mutex locker for builds without threading support.
|
||||
//! \~russian Заглушка блокировщика для сборки без поддержки потоков.
|
||||
class PIMutexLocker {
|
||||
public:
|
||||
PIMutexLocker(PIMutex &, bool = true) {}
|
||||
};
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
#endif // PIMUTEX_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
PIReadWriteLock, PIReadLocker, PIWriteLocker
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIReadWriteLock, PIReadLocker, PIWriteLocker
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
@@ -151,6 +151,8 @@
|
||||
|
||||
#include "pireadwritelock.h"
|
||||
|
||||
#ifdef PIP_HAS_THREADS
|
||||
|
||||
|
||||
PIReadWriteLock::PIReadWriteLock() {}
|
||||
|
||||
@@ -232,3 +234,5 @@ void PIReadWriteLock::unlockRead() {
|
||||
--reading;
|
||||
var.notifyAll();
|
||||
}
|
||||
|
||||
#endif // PIP_HAS_THREADS
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user