diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..da8eb4f1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+doc
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index af00ddae..e5e3945d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,15 +1,50 @@
project(pip)
cmake_minimum_required(VERSION 2.6)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR} .)
+#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
include(CheckFunctionExists)
-set(VERSION "0.0400")
+
+# Version
+file(READ "src/piversion.h" VERSION_OFFSET LIMIT 4 OFFSET 3)
+file(READ "src/piversion.h" VERSION_MAJOR LIMIT 1 OFFSET ${VERSION_OFFSET})
+file(READ "src/piversion.h" VERSION_OFFSET LIMIT 4 OFFSET 7)
+file(READ "src/piversion.h" VERSION_MINOR LIMIT 1 OFFSET ${VERSION_OFFSET})
+file(READ "src/piversion.h" VERSION_OFFSET LIMIT 4 OFFSET 11)
+file(READ "src/piversion.h" VERSION_REVISION LIMIT 1 OFFSET ${VERSION_OFFSET})
+file(STRINGS "src/piversion.h" VERSION_SUFFIX REGEX "\".*\"")
+string(REGEX MATCH "\".*\"" VERSION_SUFFIX ${VERSION_SUFFIX})
+string(LENGTH ${VERSION_SUFFIX} SL)
+math(EXPR SL '${SL}-2')
+string(SUBSTRING ${VERSION_SUFFIX} 1 ${SL} VERSION_SUFFIX)
+string(LENGTH ${VERSION_MAJOR} SL)
+math(EXPR SL '${SL}-1')
+string(SUBSTRING ${VERSION_MAJOR} 0 ${SL} VERSION_MAJOR)
+string(LENGTH ${VERSION_MINOR} SL)
+math(EXPR SL '${SL}-1')
+string(SUBSTRING ${VERSION_MINOR} 0 ${SL} VERSION_MINOR)
+string(LENGTH ${VERSION_REVISION} SL)
+math(EXPR SL '${SL}-1')
+string(SUBSTRING ${VERSION_REVISION} 0 ${SL} VERSION_REVISION)
+set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}")
set(SOVERSION ${VERSION})
+message(STATUS "Building PIP version ${VERSION}${VERSION_SUFFIX}")
+file(WRITE "src/pip_version_str.h" "#define __PIP_VERSION_STR__ \"${VERSION}${VERSION_SUFFIX}\"\n")
set(CMAKE_BUILD_TYPE "Release")
set(LIBS)
-file(GLOB HDRS "pi*.h")
-file(GLOB CPPS "pi*.cpp")
+# Sources
+set(PIP_FOLDERS "." "code" "containers" "core" "io" "math" "system" "thread")
+include_directories("src")
+foreach(F ${PIP_FOLDERS})
+ include_directories("src/${F}")
+ file(GLOB HS "src/${F}/*.h")
+ file(GLOB CS "src/${F}/*.cpp")
+ list(APPEND HDRS ${HS})
+ list(APPEND CPPS ${CS})
+endforeach(F)
+
# Check Bessel functions
set(CMAKE_REQUIRED_INCLUDES math.h)
set(CMAKE_REQUIRED_LIBRARIES m)
@@ -19,23 +54,41 @@ CHECK_FUNCTION_EXISTS(jn PIP_MATH_JN)
CHECK_FUNCTION_EXISTS(y0 PIP_MATH_Y0)
CHECK_FUNCTION_EXISTS(y1 PIP_MATH_Y1)
CHECK_FUNCTION_EXISTS(yn PIP_MATH_YN)
-if (DEFINED PIP_MATH_J0)
- add_definitions("-DPIP_MATH_J0")
+if (PIP_MATH_J0)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPIP_MATH_J0")
endif ()
-if (DEFINED PIP_MATH_J1)
- add_definitions("-DPIP_MATH_J1")
+if (PIP_MATH_J1)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPIP_MATH_J1")
endif ()
-if (DEFINED PIP_MATH_JN)
- add_definitions("-DPIP_MATH_JN")
+if (PIP_MATH_JN)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPIP_MATH_JN")
endif ()
-if (DEFINED PIP_MATH_Y0)
- add_definitions("-DPIP_MATH_Y0")
+if (PIP_MATH_Y0)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPIP_MATH_Y0")
endif ()
-if (DEFINED PIP_MATH_Y1)
- add_definitions("-DPIP_MATH_Y1")
+if (PIP_MATH_Y1)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPIP_MATH_Y1")
endif ()
-if (DEFINED PIP_MATH_YN)
- add_definitions("-DPIP_MATH_YN")
+if (PIP_MATH_YN)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPIP_MATH_YN")
+endif ()
+
+
+# Check if RT timers exists
+set(CMAKE_REQUIRED_INCLUDES time.h)
+if (DEFINED ENV{QNX_HOST})
+ set(CMAKE_REQUIRED_LIBRARIES )
+else ()
+ set(CMAKE_REQUIRED_LIBRARIES rt)
+endif ()
+CHECK_FUNCTION_EXISTS(timer_create PIP_TIMER_RT_0)
+CHECK_FUNCTION_EXISTS(timer_settime PIP_TIMER_RT_1)
+CHECK_FUNCTION_EXISTS(timer_delete PIP_TIMER_RT_2)
+if (PIP_TIMER_RT_0 AND PIP_TIMER_RT_1 AND PIP_TIMER_RT_2)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPIP_TIMER_RT")
+ message(STATUS "Available timers: Thread, ThreadRT, Pool")
+else ()
+ message(STATUS "Available timers: Thread, Pool")
endif ()
@@ -43,85 +96,94 @@ endif ()
if (DEFINED USB)
message(STATUS "Building with USB support")
unset(USB)
- add_definitions("-DPIP_USB")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPIP_USB")
list(APPEND LIBS usb)
else ()
message(STATUS "Building without USB support")
endif ()
-# Check if STL containers is on (to enable use "-DPIP_CONTAINERS_STL=" argument of cmake)
-if (DEFINED PIP_CONTAINERS_STL)
+# Check if STL containers is on (to enable use "-DSTL=" argument of cmake)
+if (DEFINED STL)
message(STATUS "Building with STL containers")
- unset(PIP_CONTAINERS_STL)
- add_definitions("-DPIP_CONTAINERS_STL")
+ unset(STL)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPIP_CONTAINERS_STL")
else ()
message(STATUS "Building with PIP containers")
endif ()
+# Add library
if (${WIN32})
- list(APPEND LIBS ws2_32 Iphlpapi)
- execute_process(COMMAND "make_rc_win.bat" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
- list(APPEND CPPS "pip_resource_win.o")
+ list(APPEND LIBS ws2_32 Iphlpapi Psapi)
+ #execute_process(COMMAND "make_rc_win.bat" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_QUIET)
+ #list(APPEND CPPS "pip_resource_win.o")
+ list(APPEND CPPS "pip_resource_win.rc")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPSAPI_VERSION=1")
add_library(pip SHARED ${CPPS})
if (${CMAKE_C_COMPILER} STREQUAL "cl")
include(GenerateExportHeader)
generate_export_header(pip)
- add_definitions("/O2 /Ob2 /Ot")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2 /Ob2 /Ot")
+ #set(${CMAKE_C_FLAGS} "/O2 /Ob2 /Ot")
else ()
- add_definitions("-O2")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
+ #set(${CMAKE_CXX_FLAGS} "-O2")
endif ()
else ()
- add_definitions("-O2")
+ set(${CMAKE_CXX_FLAGS} "-O2")
if (DEFINED ENV{QNX_HOST})
list(APPEND LIBS socket)
- add_definitions("-ftemplate-depth-32")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-32")
add_library(pip STATIC ${CPPS})
else ()
list(APPEND LIBS pthread)
if (NOT APPLE)
list(APPEND LIBS rt)
endif()
- add_definitions("-Wall")
- add_definitions("-g3")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
+ #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
add_library(pip SHARED ${CPPS})
endif ()
endif ()
target_link_libraries(pip ${LIBS})
#install(TARGETS pip DESTINATION bin)
-
+set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}")
# Test program
-find_package(Qt4 REQUIRED)
-include_directories(${QT_INCLUDES})
+#find_package(Qt4 REQUIRED)
+#include_directories(${QT_INCLUDES})
add_executable(pip_test "main.cpp")
-target_link_libraries(pip_test pip ${QT_QTCORE_LIBRARY})
+target_link_libraries(pip_test pip)# ${QT_QTCORE_LIBRARY})
#target_link_libraries(pip_test pip)
-add_subdirectory(system_test)
-add_subdirectory(remote_console)
-add_subdirectory(code_model_generator)
-
+# Install
+# Check if system or local install will be used (to system install use "-DLIB=" argument of cmake)
if (DEFINED LIB)
- unset(LIB)
+ set(LIB 1)
if (${WIN32})
- get_filename_component(MGWDIR ${CMAKE_C_COMPILER} PATH)
- find_path(MGWINCLUDE windows.h HINTS ${MGWDIR}/include)
- file(RELATIVE_PATH MGWINCLUDE "${MGWDIR}" ${MGWINCLUDE})
- get_filename_component(MGWINCLUDE ${MGWINCLUDE} PATH)
- string(SUBSTRING ${MGWINCLUDE} 1 -1 MGWINCLUDE)
- message(STATUS "MGWINCLUDE = ${MGWINCLUDE}/include")
- set(CMAKE_INSTALL_PREFIX ${MGWDIR}/..)
- install(FILES ${HDRS} DESTINATION ${MGWINCLUDE}/include/pip)
- install(TARGETS pip DESTINATION ${MGWINCLUDE}/lib)
+ find_package(MinGW REQUIRED)
+ set(CMAKE_INSTALL_PREFIX ${MINGW_DIR})
+ install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip)
+ install(TARGETS pip DESTINATION ${MINGW_LIB})
else ()
set(CMAKE_INSTALL_PREFIX /usr)
- install(TARGETS pip DESTINATION lib)
- install(FILES ${HDRS} DESTINATION include/pip)
+ install(FILES ${HDRS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip)
+ install(TARGETS pip DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endif ()
+ message(STATUS "Install to system \"${CMAKE_INSTALL_PREFIX}\"")
+ # Precompiled header
+ #add_custom_target(pip_pch ALL COMMAND ${CMAKE_CXX_COMPILER} -O2 -fPIC -g3 ${CMAKE_INSTALL_PREFIX}/include/pip/pip.h DEPENDS pip SOURCES ${HDRS})
+ #list(APPEND HDRS "pip.h.gch")
install(FILES "FindPIP.cmake" DESTINATION ${CMAKE_ROOT}/Modules)
else ()
- install(TARGETS pip DESTINATION bin)
+ install(TARGETS pip DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
+ message(STATUS "Install to local \"bin\"")
endif ()
+
+# Utils
+add_subdirectory("utils/system_test")
+add_subdirectory("utils/remote_console")
+add_subdirectory("utils/code_model_generator")
+add_subdirectory("utils/system_daemon")
diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user
new file mode 100644
index 00000000..9b254f4d
--- /dev/null
+++ b/CMakeLists.txt.user
@@ -0,0 +1,222 @@
+
+
+
+
+
+ EnvironmentId
+ {948faa78-0b50-402e-a285-1bca3b08de64}
+
+
+ ProjectExplorer.Project.ActiveTarget
+ 0
+
+
+ ProjectExplorer.Project.EditorSettings
+
+ true
+ false
+ false
+
+ Cpp
+
+ CppGlobal
+
+
+
+ QmlJS
+
+ QmlJSGlobal
+
+
+ 2
+ UTF-8
+ false
+ 4
+ false
+ 80
+ true
+ true
+ 1
+ true
+ false
+ 0
+ true
+ 0
+ 8
+ true
+ 1
+ true
+ true
+ true
+ false
+
+
+
+ ProjectExplorer.Project.PluginSettings
+
+
+
+ ProjectExplorer.Project.Target.0
+
+ DesktopBuild
+ DesktopBuild
+ {3c749452-9483-442d-b011-933a1b5dac10}
+ 0
+ 0
+ 0
+
+ false
+ C:/libs/pip
+
+
+ -j8
+
+ false
+ true
+ Сборка
+
+ CMakeProjectManager.MakeStep
+
+ 1
+ Сборка
+
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ clean
+
+ true
+ true
+ Сборка
+
+ CMakeProjectManager.MakeStep
+
+ 1
+ Очистка
+
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ all
+
+ CMakeProjectManager.CMakeBuildConfiguration
+
+ 1
+
+
+ 0
+ Установка
+
+ ProjectExplorer.BuildSteps.Deploy
+
+ 1
+ Локальная установка
+
+ ProjectExplorer.DefaultDeployConfiguration
+
+ 1
+
+
+ pip_test
+
+ false
+
+ 2
+
+ pip_test
+
+ CMakeProjectManager.CMakeRunConfiguration.pip_test
+ 3768
+ false
+ true
+ false
+ false
+ true
+
+
+ pip_system_test
+
+ false
+
+ 2
+
+ pip_system_test
+
+ CMakeProjectManager.CMakeRunConfiguration.pip_system_test
+ 3768
+ false
+ true
+ false
+ false
+ true
+
+
+ pip_remote_console
+
+ false
+
+ 2
+
+ pip_remote_console
+
+ CMakeProjectManager.CMakeRunConfiguration.pip_remote_console
+ 3768
+ false
+ true
+ false
+ false
+ true
+
+
+ pip_cmg
+
+ false
+
+ 2
+
+ pip_cmg
+
+ CMakeProjectManager.CMakeRunConfiguration.pip_cmg
+ 3768
+ false
+ true
+ false
+ false
+ true
+
+
+ pisd
+
+ true
+
+ 2
+
+ pisd
+
+ CMakeProjectManager.CMakeRunConfiguration.pisd
+ 3768
+ false
+ true
+ false
+ false
+ true
+
+ 5
+
+
+
+ ProjectExplorer.Project.TargetCount
+ 1
+
+
+ ProjectExplorer.Project.Updater.FileVersion
+ 16
+
+
+ Version
+ 16
+
+
diff --git a/Doxyfile b/Doxyfile
index baaafbaa..2c6d54c5 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -1,4 +1,4 @@
-# Doxyfile 1.8.6
+# Doxyfile 1.8.8
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -38,7 +38,7 @@ PROJECT_NAME = PIP
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 0.4.0
+PROJECT_NUMBER = 0.4.1_alpha3
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -70,6 +70,14 @@ OUTPUT_DIRECTORY = doc
CREATE_SUBDIRS = NO
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
@@ -274,9 +282,12 @@ OPTIMIZE_OUTPUT_VHDL = NO
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
-# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
-# (default is Fortran), use: inc=Fortran f=C.
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
#
# Note For files without extension you can use no_extension as a placeholder.
#
@@ -532,7 +543,7 @@ FORCE_LOCAL_INCLUDES = NO
# documentation for inline members.
# The default value is: YES.
-INLINE_INFO = YES
+INLINE_INFO = NO
# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
# (detailed) documentation of file and class members alphabetically by member
@@ -682,8 +693,7 @@ LAYOUT_FILE =
# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
# For LaTeX the style of the bibliography can be controlled using
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
-# search path. Do not use file names with spaces, bibtex cannot handle them. See
-# also \cite for info how to create references.
+# search path. See also \cite for info how to create references.
CITE_BIB_FILES =
@@ -756,7 +766,7 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
-INPUT = .
+INPUT = src
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -777,45 +787,17 @@ INPUT_ENCODING = UTF-8
# *.qsf, *.as and *.js.
FILE_PATTERNS = *.c \
- *.cc \
- *.cxx \
*.cpp \
*.c++ \
- *.d \
- *.java \
- *.ii \
- *.ixx \
- *.ipp \
- *.i++ \
- *.inl \
*.h \
- *.hh \
- *.hxx \
*.hpp \
*.h++ \
- *.idl \
- *.odl \
- *.cs \
- *.php \
- *.php3 \
- *.inc \
- *.m \
- *.markdown \
- *.md \
- *.mm \
- *.dox \
- *.py \
- *.f90 \
- *.f \
- *.for \
- *.vhd \
- *.vhdl
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
# The default value is: NO.
-RECURSIVE = NO
+RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a
@@ -1013,6 +995,25 @@ USE_HTAGS = NO
VERBATIM_HEADERS = NO
+# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS =
+
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
@@ -1105,13 +1106,15 @@ HTML_FOOTER =
HTML_STYLESHEET =
-# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
-# defined cascading style sheet that is included after the standard style sheets
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
# created by doxygen. Using this option one can overrule certain style aspects.
# This is preferred over using HTML_STYLESHEET since it does not replace the
# standard style sheet and is therefor more robust against future updates.
-# Doxygen will copy the style sheet file to the output directory. For an example
-# see the documentation.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra stylesheet files is of importance (e.g. the last
+# stylesheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET =
@@ -1276,7 +1279,8 @@ GENERATE_CHI = NO
CHM_INDEX_ENCODING =
# The BINARY_TOC flag controls whether a binary table of contents is generated (
-# YES) or a normal table of contents ( NO) in the .chm file.
+# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
@@ -1516,11 +1520,11 @@ SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using Javascript. There
-# are two flavours of web server based searching depending on the
-# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
-# searching and an index file used by the script. When EXTERNAL_SEARCH is
-# enabled the indexing and searching needs to be provided by external tools. See
-# the section "External Indexing and Searching" for details.
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
# The default value is: NO.
# This tag requires that the tag SEARCHENGINE is set to YES.
@@ -1648,17 +1652,19 @@ EXTRA_PACKAGES =
#
# Note: Only use a user-defined header if you know what you are doing! The
# following commands have a special meaning inside the header: $title,
-# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
-# replace them by respectively the title of the page, the current date and time,
-# only the current date, the version number of doxygen, the project name (see
-# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string,
+# for the replacement values of the other commands the user is refered to
+# HTML_HEADER.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HEADER =
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
# generated LaTeX document. The footer should contain everything after the last
-# chapter. If it is left blank doxygen will generate a standard footer.
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
#
# Note: Only use a user-defined footer if you know what you are doing!
# This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -1682,7 +1688,7 @@ LATEX_EXTRA_FILES =
PDF_HYPERLINKS = YES
-# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
# the PDF file directly from the LaTeX files. Set this option to YES to get a
# higher quality PDF documentation.
# The default value is: YES.
@@ -1808,6 +1814,13 @@ MAN_OUTPUT = man
MAN_EXTENSION = .3
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR =
+
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
# will generate one additional man file for each entity documented in the real
# man page(s). These additional files only source the real man page, but without
@@ -1835,18 +1848,6 @@ GENERATE_XML = NO
XML_OUTPUT = xml
-# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
-# validating XML parser to check the syntax of the XML files.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
-# validating XML parser to check the syntax of the XML files.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_DTD =
-
# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
# listings (including syntax highlighting and cross-referencing information) to
# the XML output. Note that enabling this will significantly increase the size
@@ -1874,6 +1875,15 @@ GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
@@ -1956,14 +1966,20 @@ EXPAND_ONLY_PREDEF = NO
# The default value is: YES.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-SEARCH_INCLUDES = NO
+SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by the
# preprocessor.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
-INCLUDE_PATH =
+INCLUDE_PATH = src/code \
+ src/containers \
+ src/core \
+ src/io \
+ src/math \
+ src/system \
+ src/thread
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -1994,9 +2010,9 @@ PREDEFINED = DOXYGEN \
EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
-# remove all refrences to function-like macros that are alone on a line, have an
-# all uppercase name, and do not end with a semicolon. Such function macros are
-# typically used for boiler-plate code, and will confuse the parser if not
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
# removed.
# The default value is: YES.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
@@ -2016,7 +2032,7 @@ SKIP_FUNCTION_MACROS = NO
# where loc1 and loc2 can be relative or absolute paths or URLs. See the
# section "Linking to external documentation" for more information about the use
# of tag files.
-# Note: Each tag file must have an unique name (where the name does NOT include
+# Note: Each tag file must have a unique name (where the name does NOT include
# the path). If a tag file is not located in the directory in which doxygen is
# run, you must also specify the path to the tagfile here.
@@ -2094,7 +2110,7 @@ HIDE_UNDOC_RELATIONS = YES
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# Bell Labs. The other options in this section have no effect if this option is
# set to NO
-# The default value is: NO.
+# The default value is: YES.
HAVE_DOT = YES
@@ -2108,7 +2124,7 @@ HAVE_DOT = YES
DOT_NUM_THREADS = 8
-# When you want a differently looking font n the dot files that doxygen
+# When you want a differently looking font in the dot files that doxygen
# generates you can specify the font name using DOT_FONTNAME. You need to make
# sure dot is able to find the font, which can be done by putting it in a
# standard location or by setting the DOTFONTPATH environment variable or by
@@ -2246,7 +2262,9 @@ DIRECTORY_GRAPH = YES
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
# to make the SVG files visible in IE 9+ (other browsers do not have this
# requirement).
-# Possible values are: png, jpg, gif and svg.
+# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
+# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
+# gif:cairo:gd, gif:gd, gif:gd:gd and svg.
# The default value is: png.
# This tag requires that the tag HAVE_DOT is set to YES.
@@ -2289,6 +2307,15 @@ MSCFILE_DIRS =
DIAFILE_DIRS =
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+PLANTUML_JAR_PATH =
+
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
# that will be shown in the graph. If the number of nodes in a graph becomes
# larger than this value, doxygen will truncate the graph, which is visualized
diff --git a/FindPIP.cmake b/FindPIP.cmake
index 401e5f81..0347577f 100644
--- a/FindPIP.cmake
+++ b/FindPIP.cmake
@@ -1,14 +1,8 @@
if (${WIN32})
- get_filename_component(MGWDIR ${CMAKE_C_COMPILER} PATH)
- find_path(MGWINCLUDE windows.h HINTS ${MGWDIR}/include)
- get_filename_component(MGWINCLUDE ${MGWINCLUDE} PATH)
- #file(RELATIVE_PATH MGWINCLUDE "${MGWDIR}" ${MGWINCLUDE})
- #string(SUBSTRING ${MGWINCLUDE} 1 -1 MGWINCLUDE)
- #message(STATUS "MGWINCLUDE = ${MGWINCLUDE}/include")
- #get_filename_component(MGWDIR ${CMAKE_C_COMPILER} PATH)
- find_library(PIP_LIBRARY pip ${MGWINCLUDE}/lib)
- set(PIP_INCLUDES ${MGWINCLUDE}/include/pip)
- set(PIP_CMG ${MGWDIR}/pip_cmg.exe)
+ find_package(MinGW REQUIRED)
+ find_library(PIP_LIBRARY pip ${MINGW_LIB})
+ set(PIP_INCLUDES ${MINGW_INCLUDE}/pip)
+ set(PIP_CMG ${MINGW_BIN}/pip_cmg.exe)
else ()
find_library(PIP_LIBRARY pip /usr/lib/)
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
@@ -53,7 +47,7 @@ macro (pip_code_model SRC RESULT)
endif ()
if (NEED_PARSE)
message(STATUS "Creating code model based on \"${SRC}\", please wait ... ")
- execute_process(COMMAND ${PIP_CMG} -qP -o ${PROJECT_NAME}_ccm -I${PIP_INCLUDES} ${SRC} OUTPUT_VARIABLE CMG_OUT)
+ execute_process(COMMAND ${PIP_CMG} -qPEs -o ${PROJECT_NAME}_ccm -I${PIP_INCLUDES} ${SRC} OUTPUT_VARIABLE CMG_OUT)
message(STATUS "Creating code model done, to use it include \"${PROJECT_NAME}_ccm.h\"")
string(REPLACE "\n" ";" CMG_LIST ${CMG_OUT})
string(REPLACE "\n" " " CMG_LIST_S ${CMG_OUT})
diff --git a/clean b/clean
index 81218f4e..8d1dc6eb 100644
--- a/clean
+++ b/clean
@@ -2,15 +2,18 @@
VERBOSE=1 make clean
rm -rvf ./CMakeFiles
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
-cd system_test
+cd utils/system_test
+VERBOSE=1 make clean
rm -rvf ./CMakeFiles
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
-cd ..
-cd remote_console
+cd ../../
+cd utils/remote_console
+VERBOSE=1 make clean
rm -rvf ./CMakeFiles
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
-cd ..
-cd code_model_generator
+cd ../../
+cd utils/code_model_generator
+VERBOSE=1 make clean
rm -rvf ./CMakeFiles
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
-cd ..
+cd ../../
diff --git a/clean.bat b/clean.bat
index 9e0579b0..703d6aa1 100644
--- a/clean.bat
+++ b/clean.bat
@@ -2,13 +2,21 @@
del /q /f /s CMakeFiles
rmdir /q /s CMakeFiles
del /q /f CMakeCache.txt Makefile cmake_install.cmake install_manifest.txt *~ *cxx moc_* *.o *.exe *.a *.dll *.lib core
-cd system_test
+cd utils\system_test
del /q /f /s CMakeFiles
rmdir /q /s CMakeFiles
del /q /f CMakeCache.txt Makefile cmake_install.cmake install_manifest.txt *~ *cxx moc_* *.o *.exe *.a *.dll *.lib core
cd ..
-cd remote_console
+cd ..
+cd utils\remote_console
del /q /f /s CMakeFiles
rmdir /q /s CMakeFiles
del /q /f CMakeCache.txt Makefile cmake_install.cmake install_manifest.txt *~ *cxx moc_* *.o *.exe *.a *.dll *.lib core
cd ..
+cd ..
+cd utils\code_model_generator
+del /q /f /s CMakeFiles
+rmdir /q /s CMakeFiles
+del /q /f CMakeCache.txt Makefile cmake_install.cmake install_manifest.txt *~ *cxx moc_* *.o *.exe *.a *.dll *.lib core
+cd ..
+cd ..
diff --git a/main.cpp b/main.cpp
index b5adc277..67f01f74 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,188 +1,129 @@
-/*
- PIP - Platform Independent Primitives
- Test program
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-//#define PIP_DEBUG
-/*#include "pip.h"
-
-
-class ElementA: public PIObject {
- PIOBJECT(ElementA)
- // ...
-};
-ADD_NEW_TO_COLLECTION(ab_group, ElementA)
-
-class ElementB: public PIObject {
- PIOBJECT(ElementB)
- // ...
-};
-ADD_NEW_TO_COLLECTION(ab_group, ElementB)
-
-class ElementC: public PIObject {
- PIOBJECT(ElementC)
- // ...
-};
-ADD_NEW_TO_COLLECTION(c_group, ElementC)
-
-class ElementD: public PIObject {
- PIOBJECT(ElementD)
- // ...
-};
-*/
#include "pip.h"
-#include "pivariant.h"
-
-
-
-
-#include "picodeparser.h"
-#include "pidir.h"
-#include "piconnection.h"
-#include
-
-bool readed(void*, uchar * data, int size) {
- piCout << Hex << "readed" << PIByteArray(data, size);
- //piCout << PIString((char*)data, size);
- return true;
-}
-
-class A: public PIObject {
- PIOBJECT(A)
+class Ob: public PIObject {
+ PIOBJECT(Ob)
public:
- EVENT_HANDLER2(void, cr, const PIString &, from, const PIByteArray &, data) {
- piCout << "A readed" << from << Hex << data;
+ Ob() {
+ sft.setName("sft");
+ sft.setDirectory(sft.directory().cd("..\\"));
+ piCout << "Send File Transfer DIrectory" << sft.directory().absolutePath();
+ CONNECTU(&sft, sendRequest, this, ssend);
+
+ rft.setName("rft");
+ rft.setDirectory(rft.directory().cd("..\\1"));
+ piCout << "Receive File Transfer DIrectory" << rft.directory().absolutePath();
+ CONNECTU(&rft, sendRequest, this, rsend);
}
- EVENT_HANDLER2(void, per, uchar *, data, int, size) {
- piCout << "A readed" << size << ":\"" << PIString((const char *)data, size) << "\"" << NewLine;
- //piCout << "A readed \"";
+
+ void startsend() {
+ PIDir dir = PIDir::current();
+ dir.cd("..\\");
+ piCout << dir.absolutePath();
+ PIVector des = dir.allEntries();
+ piCout << "all entries" << des.size();
+ PIDir::DirEntry sde;
+ piForeachC(PIDir::DirEntry de, des) {
+ //piCout << (de.isDir() ? "dir:" : "file") << de.name << de.size;
+ if (de.name == "0") sde = de;
+ }
+ //sft.setPacketSize(64096);
+ sft.send(sde);
}
+
+private:
+ EVENT_HANDLER1(void, ssend, PIByteArray &, data) {
+// piCout << "[sender]" << sft.stateString() << ". datasize =" << data.size()
+// << "(" << PIString::readableSize(sft.bytesFileCur()) << "/" << PIString::readableSize(sft.bytesFileAll()) << ", "
+// << PIString::readableSize(sft.bytesTotalCur()) << "/" << PIString::readableSize(sft.bytesTotalAll()) << ")";
+ if(rand()%100 != 90) rft.received(data);
+ }
+
+ EVENT_HANDLER1(void, rsend, PIByteArray &, data) {
+// piCout << "[receiver]" << rft.stateString() << ". datasize =" << data.size()
+// << "(" << PIString::readableSize(rft.bytesFileCur()) << "/" << PIString::readableSize(rft.bytesFileAll()) << ", "
+// << PIString::readableSize(rft.bytesTotalCur()) << "/" << PIString::readableSize(rft.bytesTotalAll()) << ")";
+ if(rand()%100 != 90) sft.received(data);
+ }
+
+ PIFileTransfer sft;
+ PIFileTransfer rft;
};
-class TC: public PIConnection {
+
+class UDPFileTransfer: public PITimer {
+ PIOBJECT_SUBCLASS(UDPFileTransfer, PITimer)
public:
- TC() {
- PIPacketExtractor * pe = addFilter("h&f", addDevice("file://piiodevice.h", PIIODevice::ReadOnly, false), PIPacketExtractor::HeaderAndFooter);
- pe->setHeader(PIString("//!").toByteArray());
- pe->setFooter(PIString("\n").toByteArray());
- pe = addFilter(" h ", "file://piiodevice.h", PIPacketExtractor::Header);
- addChannel(pe, addDevice("file://out.txt", PIIODevice::WriteOnly));
- pe->setHeader(PIString("PI").toByteArray());
- pe->setPayloadSize(3);
- startAllThreadedReads();
+ UDPFileTransfer(const PIString &src_ip_port, const PIString &dst_ip_port) {
+ eth.setReadAddress(src_ip_port);
+ eth.setSendAddress(dst_ip_port);
+ //ft.setPacketSize(65000);
+ CONNECTU(&ft, sendRequest, this, ftsend);
+ CONNECTU(&ft, startSend, this, ftevent);
+ CONNECTU(&ft, finishSend, this, ftevent);
+ CONNECTU(&ft, startReceive, this, ftevent);
+ CONNECTU(&ft, finishReceive, this, ftevent);
+ CONNECTU(ð, threadedReadEvent, this, received);
+ start(50);
+ eth.open();
+ eth.startThreadedRead();
}
- virtual void dataReceived(const PIString & from, const PIByteArray & data) {
- piCout << "dataReceived" << from << (data.size());
+
+ void startSend(const PIString &file) {
+ ft.send(file);
}
- virtual void packetReceived(const PIString & from, const PIByteArray & data) {
- piCout << "packetReceived" << from << (data.size()) << PIString(data);
+
+ PIFileTransfer ft;
+
+private:
+ PIEthernet eth;
+
+ void tick(void *, int) {
+ if (ft.isSending() || ft.isReceiving()) ftevent();
}
- virtual bool filterValidatePayload(const PIString & filter_name, uchar * rec, int size) {
- //piCout << "filterValidatePayload" << filter_name << PIString((char*)rec, size);
- if (filter_name == " h ") return PIString((char*)rec, size) == "IOD";
- return false;
+
+ EVENT_HANDLER(void, ftevent) {
+ piCout << ft.stateString()
+ << "(" << PIString::readableSize(ft.bytesFileCur()) << "/" << PIString::readableSize(ft.bytesFileAll()) << ", "
+ << PIString::readableSize(ft.bytesTotalCur()) << "/" << PIString::readableSize(ft.bytesTotalAll()) << ")";
+ }
+
+ EVENT_HANDLER1(void, ftsend, PIByteArray &, data) {
+ eth.send(data);
+ }
+
+ EVENT_HANDLER2(void, received, uchar * , readed, int, size) {
+ PIByteArray ba(readed, size);
+ ft.received(ba);
}
};
int main (int argc, char * argv[]) {
- /*A a_;
- PIFile file("piiodevice.h", PIIODevice::ReadOnly);
- PIByteArray header = PIString("PI").toByteArray();
- PIByteArray footer = PIString("}").toByteArray();
- PIPacketExtractor pe(&file);
- //pe.setPacketData(header.data(), header.size_s(), 10);
- pe.setSplitMode(PIPacketExtractor::Footer);
- pe.setHeader(header);
- pe.setFooter(footer);
- pe.setPayloadSize(3);
- pe.setThreadedReadBufferSize(40);
- //pe.setBufferSize(256);
- //pe.setPacketData(0, 0, 20);
- CONNECT2(void, uchar * , int , &pe, packetReceived, &a_, per)
- pe.startThreadedRead();
- piMSleep(500);*/
-
- TC tc;
- piMSleep(500);
- piCout << tc.makeConfig();
- return 0;
-
- /*tm = PISystemTime::current();
- for (int i = 0; i < 10000000; ++i) {
- ql.append(i*10);
- ql.prepend(i*10 + 1);
+ if (!(argc == 3 || argc == 4)) {
+ piCout << "UDPFileTransfer";
+ piCout << "USE: piptest [src_ip_port] [dst_ip_port] {filename}";
+ return 0;
}
- piCout << (PISystemTime::current() - tm).toMicroseconds();
- */
- //tm = PISystemTime::current();
- /*for (int i = 0; i < 100000000; ++i) {
- pl.append(i*10);
- pl.prepend(i*10 + 1);
- }*/
- //PICodeParser cd_;
- //cd.includeDirectory("../qpicalculator");
- //cd_.parseFile("piincludes.h");
- //piCout << (PISystemTime::current() - tm).toMilliseconds();
- /*piCout << NewLine;
- piForeachCA (i, pl)
- piCout << i;
-
- pl.remove(1, 2).prepend(111).prepend(222);
- pl.remove(1, 1);
- piCout << NewLine;
- piForeachCA (i, pl)
- piCout << i;*/
- /*piCout << NewLine;
- for (int i = 0; i < pl.size_s(); ++i)
- piCout << pl[i];
- */
-
- /*PIEthernet eth(PIEthernet::UDP);
- eth.setReadAddress("192.168.0.30:4001");
- eth.setSendAddress("192.168.0.50:4001");
- eth.startThreadedRead(readed);
- piCout << "Connected";
- //eth.send(PIString("This is test string!\n").toByteArray());
- FOREVER_WAIT*/
-
- if (argc < 2) return 0;
- PICodeParser cd;
- //cd.includeDirectory("../qpicalculator");
- cd.parseFile(argv[1]);
- piForeachC (PICodeParser::Enum & e, cd.enums)
- piCout << e.name << e.members;
-
-
- //piCout << v.toType();
- //piCout << v.toType().toType();
- //PIFile::remove("ki");
- /*PIConfig conf("protocols_commod.conf");
- piCout << conf.allTree();
- conf.setValue("rmd.123", 456);*/
-
- /*PITimer tm;
- piCout << tm.debug() << tm.properties();
- tm.setDebug(false);
- piCout << tm.debug() << tm.properties();
- tm.setDebug(true);
- piCout << tm.debug() << tm.properties();*/
-
- //PIObject * ser = (PIObject * )PIIODevice::createFromFullPath("file://OM2:38400:7");
- //piCout << ser << NewLine << ser->properties();
+ PIKbdListener kbd;
+ kbd.enableExitCapture();
+ PIString src = argv[1];
+ PIString dst = argv[2];
+ UDPFileTransfer f(src, dst);
+ piCout << "work directory" << f.ft.directory().absolutePath() << ", listen on" << src << ",send to" << dst;
+ if (argc == 4) {
+ PIString file = argv[3];
+ piCout << "send file" << file;
+ f.startSend(file);
+ return 0;
+ } else {
+ piCout << "wait for receiving";
+ }
+ WAIT_FOR_EXIT
+ return 0;
+// Ob o;
+// ft.setPacketSize(65536);
+// PITimeMeasurer tm;
+// o.startsend();
+// piCout << tm.elapsed_s();
+// return 0;
}
-
diff --git a/main_.cpp b/main_.cpp
new file mode 100644
index 00000000..557171f9
--- /dev/null
+++ b/main_.cpp
@@ -0,0 +1,294 @@
+/*
+ PIP - Platform Independent Primitives
+ Test program
+ Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+//#define PIP_DEBUG
+#include "pip.h"
+//#include "pivariant.h"
+//#include "picodeparser.h"
+//#include "pidir.h"
+#include "piconnection.h"
+//#include
+
+PIMutex mutex;
+PIDeque deq;
+
+void timerE(void * t, int d) {
+ //PIMutexLocker l(mutex);
+ /*if (d == 1)
+ deq.push_back(int(t));
+ else
+ deq.push_front(int(t));*/
+ //printf("%d\n", deq.size());
+ piCout << "tick" << (int)t << d;
+}
+
+
+
+class A: public PIObject {
+ PIOBJECT(A)
+public:
+ A() {}
+ EVENT_HANDLER1(void, handlerA1, PIString, s) {piCout << "handlerA1 s" << s;}
+ EVENT_HANDLER1(void, handlerA1, float, f) {piCout << "handlerA1 f" << f;}
+ //uchar _[0x10];
+};
+
+
+class B: public PIObject {
+ PIOBJECT(B)
+public:
+ B() {}
+ EVENT1(eventB1, float, f);
+ EVENT1(eventB2, PIString, s);
+ //uchar _[0x20];
+};
+
+
+class C: public A, public B {
+public:
+ C() {}
+};
+
+int main (int argc, char * argv[]) {
+ PIFile f("test.txt");
+ f.clear();
+ f << "1234566789\n";
+ piCout << f.size();
+ f.close();
+ piCout << f.size();
+
+ /*CONNECTU(&b, eventB1, &a, handlerA1)
+ CONNECTU(&b, eventB2, &a, handlerA1)
+ a.dump();
+ b.dump();
+ b.eventB1(0.33);
+ b.eventB2("str");*/
+
+
+
+ //conf.dump();
+ /*PIObject * t_o = &timer, * a_o = &a, * b_o = &b;
+ CONNECTU(t_o, tickEvent, a_o, handlerT)
+ CONNECTU(b_o, eventB1, &a, handlerA1)
+ CONNECTU(&b, eventB2, a_o, hAAA)
+ a_o->dump("* ");
+ b_o->dump("# ");
+ //dumpApplication();
+ b.eventB(10, "str");
+ b.eventB1(10.5);
+ b.eventB2("test");*/
+
+ /*PIKbdListener kbd;
+ PITimer timer(timerE);
+ timer.start(100);
+ kbd.enableExitCapture();
+ WAIT_FOR_EXIT*/
+
+ /*
+ PIMathVectorT3d v(1., -2., 3.);
+ PIMathMatrixT33d m0;
+ m0.setCol(0, v.normalized());
+ m0.setCol(1, PIMathVectorT3d(v[1], -v[0], 0.).normalized());
+ m0.setCol(2, m0.col(1) * m0.col(0));
+
+ piCout << m0.determinant();
+ //m0.setRow(1, PIMathVectorT3d(1., 2., 3.));
+ //piCout << m0 << NewLine << NewLine << m0.;
+ //PIMathMatrixT33d m0_(-1., 2., 3., 4., -5., 6., 7., 8., -9.);
+ //PIMathMatrixT33d m1_(10., 2., 30., 4., 50., 6., 70., 8., 90.);
+ //piCout << m0_.determinant() << m1_.determinant();
+ */
+
+ /*
+ PITimer::TimerImplementation ti_ = PITimer::ThreadRT;
+ PITimer t_(timerE, 0, ti_);
+ t_.setData((void*)0x10);
+ t_.start(100);
+ piSleep(1);
+ piCout << "end";
+ t_.stop();
+ piCout << "end 1";
+ t_.waitForFinish();
+ piCout << "end 2";
+ */
+
+ /*
+ PIVector timers;
+ int tc = PIString(argv[1]).toInt();
+ piCout << "create ...";
+ for (int i = 0; i < tc; ++i) {
+ PITimer * t = new PITimer(timerE, 0, PITimer::Thread);
+ t->setData((void*)i);
+ //t->dump();
+ timers << t;
+ if (i > 10) t->addDelimiter(i / 10);
+ t->start(100);
+ }
+ piCout << "create ok";
+ piSleep(1);
+ dumpApplication();
+ piCout << "delete ...";
+ piForeach (PITimer * t, timers)
+ t->stop();
+ piForeach (PITimer * t, timers)
+ delete t;
+ piCout << "delete ok";
+ */
+
+ /*
+ PIConsole console(false);
+ PISystemMonitor mon;
+ console.addVariable("", &mon);
+ mon.startOnSelf();
+ console.enableExitCapture();
+ console.start();
+ console.waitForFinish();
+ return 0;
+ */
+
+ /*PITimeMeasurer tm_;
+ piCout << PIIODevice::normalizeFullPath("ser:///dev/ttyS1");
+ piCout << tm_.elapsed_u();
+ tm_.reset();
+ piCout << PIIODevice::normalizeFullPath("ser:///dev/ttyS2");
+ piCout << tm_.elapsed_u();
+ tm_.reset();
+ piCout << PIIODevice::normalizeFullPath("ser:///dev/ttyS3");
+ piCout << tm_.elapsed_u();
+ tm_.reset();
+ piCout << PIIODevice::normalizeFullPath("ser:///dev/ttyS1");
+ piCout << tm_.elapsed_u();
+ tm_.reset();*/
+ //msleep(6000000);
+
+ /*A a_;
+ PIFile file("piiodevice.h", PIIODevice::ReadOnly);
+ PIByteArray header = PIString("PI").toByteArray();
+ PIByteArray footer = PIString("}").toByteArray();
+ PIPacketExtractor pe(&file);
+ //pe.setPacketData(header.data(), header.size_s(), 10);
+ pe.setSplitMode(PIPacketExtractor::Footer);
+ pe.setHeader(header);
+ pe.setFooter(footer);
+ pe.setPayloadSize(3);
+ pe.setThreadedReadBufferSize(40);
+ //pe.setBufferSize(256);
+ //pe.setPacketData(0, 0, 20);
+ CONNECT2(void, uchar * , int , &pe, packetReceived, &a_, per)
+ pe.startThreadedRead();
+ piMSleep(500);*/
+
+ /*TC tc;
+ piMSleep(2000);
+ //piCout << tc.diagnostic("file://piiodevice.h")->receiveBytesPerSec();
+ piCout << tc.makeConfig();*/
+
+ /*PITimer timer;
+ piForTimes (50) {
+ piUSleep(10);
+ piCout << PISystemTime::current() << timer.elapsed_u();
+ }
+ piCout << NewLine;
+ piForTimes (50) {
+ piUSleep(100);
+ piCout << PISystemTime::current(true) << timer.elapsed_u();
+ }*/
+
+ /*PIConsole console;
+ PIEthernet eth(PIEthernet::TCP_Client);
+ eth.connect("192.168.20:5006");
+ eth.startThreadedRead(readed);
+ console.enableExitCapture();
+ console.start();
+ console.waitForFinish();*/
+
+ /*PIBinaryLog log_;
+ GPS_Data gps;
+ log_.open("log_gps__2014_07_03__11_22_18", PIIODevice::ReadOnly);
+ while (!log_.isEnd()) {
+ log_.read(&gps, sizeof(gps));
+ printf("%f %f\n", gps.lat, gps.lng);
+ }*/
+ return 0;
+
+ /*tm = PISystemTime::current();
+ for (int i = 0; i < 10000000; ++i) {
+ ql.append(i*10);
+ ql.prepend(i*10 + 1);
+ }
+ piCout << (PISystemTime::current() - tm).toMicroseconds();
+ */
+ //tm = PISystemTime::current();
+ /*for (int i = 0; i < 100000000; ++i) {
+ pl.append(i*10);
+ pl.prepend(i*10 + 1);
+ }*/
+ //PICodeParser cd_;
+ //cd.includeDirectory("../qpicalculator");
+ //cd_.parseFile("piincludes.h");
+ //piCout << (PISystemTime::current() - tm).toMilliseconds();
+ /*piCout << NewLine;
+ piForeachCA (i, pl)
+ piCout << i;
+
+ pl.remove(1, 2).prepend(111).prepend(222);
+ pl.remove(1, 1);
+ piCout << NewLine;
+ piForeachCA (i, pl)
+ piCout << i;*/
+ /*piCout << NewLine;
+ for (int i = 0; i < pl.size_s(); ++i)
+ piCout << pl[i];
+ */
+
+ /*PIEthernet eth(PIEthernet::UDP);
+ eth.setReadAddress("192.168.0.30:4001");
+ eth.setSendAddress("192.168.0.50:4001");
+ eth.startThreadedRead(readed);
+ piCout << "Connected";
+ //eth.send(PIString("This is test string!\n").toByteArray());
+ FOREVER_WAIT*/
+
+ /*
+ if (argc < 2) return 0;
+ PICodeParser cd;
+ //cd.includeDirectory("../qpicalculator");
+ cd.parseFile(argv[1]);
+ piForeachC (PICodeParser::Enum & e, cd.enums)
+ piCout << e.name << e.members;
+ */
+
+ //piCout << v.toType();
+ //piCout << v.toType().toType();
+ //PIFile::remove("ki");
+ /*PIConfig conf("protocols_commod.conf");
+ piCout << conf.allTree();
+ conf.setValue("rmd.123", 456);*/
+
+ /*PITimer tm;
+ piCout << tm.debug() << tm.properties();
+ tm.setDebug(false);
+ piCout << tm.debug() << tm.properties();
+ tm.setDebug(true);
+ piCout << tm.debug() << tm.properties();*/
+
+ //PIObject * ser = (PIObject * )PIIODevice::createFromFullPath("file://OM2:38400:7");
+ //piCout << ser << NewLine << ser->properties();
+}
+
+
diff --git a/main_tcp_server.cpp b/main_tcp_server.cpp
new file mode 100644
index 00000000..7cfb4162
--- /dev/null
+++ b/main_tcp_server.cpp
@@ -0,0 +1,93 @@
+#include "pip.h"
+
+class Client: public PIObject {
+ PIOBJECT(Client);
+public:
+ Client(PIEthernet * eth_) {
+ eth = eth_;
+ eth->startThreadedRead();
+ CONNECTU(eth, threadedReadEvent, this, readed);
+ CONNECTU(eth, disconnected, this, disconnected);
+ piCoutObj << uint(eth) << "client connected";
+ }
+ ~Client() {}
+ EVENT_HANDLER2(void, readed, uchar * , data, int, size) {
+ PIByteArray ba(data, size)
+ piCoutObj << uint(eth) << "readed" << size << "bytes" << Hex << ba;
+ eth->write(ba);
+ }
+ EVENT_HANDLER1(void, disconnected, bool, withError) {
+ piCoutObj << uint(eth) << "client disconnected";
+ disconnect(this);
+ }
+ void send() {
+ PIByteArray ba;
+ ba << uchar(0) << uchar(1) << uchar(2);
+ piCoutObj << uint(eth) << "client send" << ba;
+ eth->write(ba);
+ }
+ PIEthernet * eth;
+
+ EVENT1(disconnect, Client *, client)
+};
+
+class Server: public PIObject {
+ PIOBJECT(Server);
+public:
+ Server(int port) {
+ eth = new PIEthernet(PIEthernet::TCP_Server);
+ eth->setParameter(PIEthernet::ReuseAddress);
+ CONNECTU(eth, newConnection, this, newConnection);
+ PIString path = "0.0.0.0:" + PIString::fromNumber(port);
+ eth->listen(path, true);
+ piCoutObj << uint(eth) << "server started" << path;
+ }
+ ~Server() {
+ eth->close();
+ piCoutObj << uint(eth) << "server stoped";
+ delete eth;
+ }
+ EVENT_HANDLER1(void, newConnection, PIEthernet * , cl) {
+ piCoutObj << uint(eth) << "add client";
+ Client * client = new Client(cl);
+ CONNECTU(client, disconnect, this, disconnect);
+ clients.push_back(client);
+ }
+ EVENT_HANDLER1(void, disconnect, Client *, client) {
+ piCoutObj << uint(eth) << "remove client";
+ delete client;
+ clients.removeOne(client);
+ }
+ PIEthernet * eth;
+ PIVector clients;
+ void send() {
+ for (int i=0; isend();
+ }
+ }
+};
+
+Server sl(10001);
+Server s2(10002);
+
+
+void keyEvent(char key, void*) {
+ switch (key) {
+ case '1': sl.send(); break;
+ case '2': s2.send(); break;
+ };
+};
+
+void timerEvent(void * , int) {
+ //sl.send();
+};
+
+PITimer timer(timerEvent);
+
+int main(int argc, char * argv[]) {
+ timer.start(1000.);
+ PIKbdListener kbd(keyEvent);
+ kbd.enableExitCapture();
+ WAIT_FOR_EXIT;
+ return 0;
+}
diff --git a/make.sh b/make.sh
deleted file mode 100644
index 64fcb2ab..00000000
--- a/make.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#! /bin/sh
-cmake ./
-make $@
diff --git a/make_lib.bat b/make_lib.bat
index 83908120..afe1db57 100644
--- a/make_lib.bat
+++ b/make_lib.bat
@@ -1 +1 @@
-cmake_mgw -DLIB= && make install
+cmake_mgw -DLIB= && make install %*
diff --git a/make_rc_win.bat b/make_rc_win.bat
deleted file mode 100644
index f6c1b22a..00000000
--- a/make_rc_win.bat
+++ /dev/null
@@ -1 +0,0 @@
-windres -i pip_resource_win.rc -o pip_resource_win.o --include-dir=.
\ No newline at end of file
diff --git a/pibinarylog.cpp b/pibinarylog.cpp
deleted file mode 100644
index 8746a45e..00000000
--- a/pibinarylog.cpp
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- PIP - Platform Independent Primitives
- Class for write binary data to logfile, and read or playback this data
- Copyright (C) 2014 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 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#include "pibinarylog.h"
-
-
-/*! \class PIBinaryLog
- * \brief Class for read and write binary data to logfile, and playback this data in realtime
- *
- * \section PIBinaryLog_sec0 Synopsis
- * Binary Log is a file with simle header, where you can read and write some binary data.
- * Any written data include special header with ID, size and timestamp.
- * This header provides separation different messages from the one file by choosing different IDs.
- * With \a filterID or special functions, like \a readBinLog() you can choose IDs what you want to read.
- * With function \a writeBinLog() or \a setDefaultID() you can choose ID that mark you data.
- * By default ID = 1, and \a filterID is empty, that mean you read any ID without filtering.
- * ThreadedRead provide you playback data, with delay that you write data.
- * You can choose realtime playbak or variable speed play back by set \a PlayMode.
- *
- * \section PIBinaryLog_sec1 Basic usage
- * This class provide all functions of \a PIIODevice, such \a open(), \a close(),
- * \a read() ,\a write(), and threaded read/write.
- * function \a setLogDir() need to set directory for BinLog files
- * function \a createNewFile() need to create new binlog file
- * function \a restart() need start from the begining of binlog file
- *
- */
-
-REGISTER_DEVICE(PIBinaryLog);
-
-
-PIBinaryLog::PIBinaryLog() {
- binlog_sig[0] = 'B';
- binlog_sig[1] = 'I';
- binlog_sig[2] = 'N';
- binlog_sig[3] = 'L';
- binlog_sig[4] = 'O';
- binlog_sig[5] = 'G';
- setThreadedReadBufferSize(65536);
- is_started = false;
- setPlaySpeed(1.f);
- setDefaultID(1);
- setPlayMode(PlayVariableSpeed);
- setLogDir(PIString());
- setFilePrefix(PIString());
- setRapidStart(false);
-}
-
-
-bool PIBinaryLog::openDevice() {
- lastrecord.timestamp = PISystemTime();
- lastrecord.id = 0;
- is_started = false;
- is_thread_ok = true;
- if (mode_ == ReadWrite) {
- piCoutObj << "Error: ReadWrite mode not supported, use WriteOnly or ReadOnly";
- return false;
- }
- if (!file.open(path(), mode_))
- return false;
- setName(path());
- if (mode_ == WriteOnly) {
- file.resize(0);
- if (!writeFileHeader()) {
- piCoutObj << "Error: Can't write binlog file header";
- return false;
- }
- is_started = true;
- }
- if (mode_ == ReadOnly) {
- if (file.isEmpty()) {
- piCoutObj << "Error: File is null";
- fileError();
- return false;
- }
- if (!checkFileHeader()) {
- fileError();
- return false;
- }
- if (isEmpty()) piCoutObj << "Error: Empty BinLog file";
- // startlogtime = PISystemTime::current();
- play_time = 0;
- // nextrecord = readsRecord();
- if (!rapidStart()) is_started = true;
- }
- startlogtime = PISystemTime::current();
- return true;
-}
-
-
-bool PIBinaryLog::closeDevice() {
- if (canWrite() && isEmpty()) {
- file.remove();
- return true;
- }
- return file.close();
-}
-
-
-bool PIBinaryLog::threadedRead(uchar *readed, int size) {
- is_thread_ok = false;
- PISystemTime pt;
- double delay;
- switch (playMode()) {
- case PlayRealTime:
- pt = PISystemTime::current() - startlogtime;
-// if (real_speedX > 0)
-// for (int i=0; i pt)
- (lastrecord.timestamp - pt).sleep();
- } else {
- startlogtime = PISystemTime::current() - lastrecord.timestamp;
- is_started = true;
- }
- // int delay = piRoundd(lastread_timestamp.toMilliseconds() - (PISystemTime::current() - startlogtime).toMilliseconds());
- break;
- case PlayVariableSpeed:
- delay = lastrecord.timestamp.toMilliseconds() - play_time;
- delay /= playSpeed();
- if (is_started) {
- if (delay > 0)
- PISystemTime::fromMilliseconds(delay).sleep();
- } else is_started = true;
- play_time = lastrecord.timestamp.toMilliseconds();
- break;
- default:
- return false;
- }
- bool res = PIIODevice::threadedRead(readed, size);
- is_thread_ok = true;
- return res;
-}
-
-
-PIString PIBinaryLog::createNewFile() {
- if (!file.close()) return PIString();
- if (open(logDir() + "/" + filePrefix() + PIDateTime::current().toString("yyyy_MM_dd__hh_mm_ss.binlog"), PIIODevice::WriteOnly))
- return file.path();
- piCoutObj << "Can't create new file, maybe LogDir is invalid.";
- return PIString();
-}
-
-
-int PIBinaryLog::writeBinLog(int id, const void *data, int size) {
- if (size <= 0 || !canWrite()) return -1;
- PIByteArray logdata;
- logdata << id << size << (PISystemTime::current() - startlogtime) << PIByteArray::RawData(data, size);
- int res = file.write(logdata.data(), logdata.size());
- file.flush();
- if (res > 0) return size;
- else return res;
-}
-
-
-PIByteArray PIBinaryLog::readBinLog(int id) {
- if (!canRead()) return PIByteArray();
- BinLogRecord br = readRecord();
- if (br.id == -1) {
- piCoutObj << "End of BinLog file";
- fileEnd();
- return PIByteArray();
- }
- if (id == 0 && br.id > 0) return br.data;
- while (br.id != id && !isEnd()) br = readRecord();
- if (br.id == -1) {
- piCoutObj << "End of BinLog file";
- fileEnd();
- return PIByteArray();
- }
- if (br.id == id) return br.data;
- piCoutObj << "Can't find record with id =" << id;
- return PIByteArray();
-}
-
-
-int PIBinaryLog::readBinLog(int id, void *read_to, int max_size) {
- if (max_size <= 0 || read_to == 0) return -1;
- PIByteArray ba = readBinLog(id);
- if (ba.isEmpty()) return -1;
- int sz = piMini(max_size, ba.size());
- memcpy(read_to, ba.data(), sz);
- return sz;
-}
-
-
-
-int PIBinaryLog::read(void *read_to, int max_size) {
- // piCoutObj << "read";
- if (lastrecord.id == -1 || isEnd()) return 0;
- if(!is_thread_ok && lastrecord.id > 0) return lastrecord.data.size();
- if (!canRead()) return -1;
- if (max_size <= 0 || read_to == 0) return -1;
- BinLogRecord br;
- br.id = 0;
- if (filterID.isEmpty()) br = readRecord();
- else {
- while (!filterID.contains(br.id) && !isEnd()) br = readRecord();
- }
- if (br.id == -1) {
- fileEnd();
- piCoutObj << "End of BinLog file";
- //stopThreadedRead();
- return 0;
- }
- if (br.id <= 0) {
- piCoutObj << "Read record error";
- return -1;
- }
- int sz = piMini(max_size, br.data.size());
- memcpy(read_to, br.data.data(), sz);
- return sz;
-}
-
-
-void PIBinaryLog::restart() {
- bool th = isRunning();
- if (th) stopThreadedRead();
- if (!canRead()) return;
- lastrecord.timestamp = PISystemTime();
- lastrecord.id = 0;
- is_thread_ok = true;
- if (rapidStart()) is_started = false;
- else is_started = true;
- play_time = 0;
- file.seekToBegin();
- checkFileHeader();
- startlogtime = PISystemTime::current();
- if (th) startThreadedRead();
-}
-
-
-bool PIBinaryLog::writeFileHeader() {
- if (file.write(&binlog_sig, PIBINARYLOG_SIGNATURE_SIZE) <= 0) return false;
- uchar version = PIBINARYLOG_VERSION;
- if (file.write(&version, 1) <= 0) return false;
- file.flush();
- return true;
-}
-
-
-bool PIBinaryLog::checkFileHeader() {
- uchar read_sig[PIBINARYLOG_SIGNATURE_SIZE];
- for (int i=0; i PIBINARYLOG_VERSION)
- piCoutObj << "BinLogFile has too newest version";
- return false;
-}
-
-
-PIBinaryLog::BinLogRecord PIBinaryLog::readRecord() {
- // piCoutObj << "readRecord";
- PIByteArray ba;
- BinLogRecord br;
- lastrecord.id = 0;
- lastrecord.data.clear();
- lastrecord.timestamp = PISystemTime();
- ba.resize(sizeof(BinLogRecord) - sizeof(PIByteArray));
- if(file.read(ba.data(), ba.size_s()) > 0) {
- ba >> br.id >> br.size >> br.timestamp;
- // piCoutObj << "read" << br.id << br.size << br.timestamp;
- } else {
- br.id = -1;
- return br;
- }
- if (br.id > 0 && br.size > 0) {
- ba.resize(br.size);
- if(file.read(ba.data(), ba.size_s()) > 0) br.data = ba;
- else br.id = 0;
- } else br.id = 0;
- lastrecord = br;
- if (br.id == 0) fileError();
- return br;
-}
-
-
-PIString PIBinaryLog::constructFullPath() const {
- PIString ret(fullPathPrefix() + "://");
- ret << logDir() << ":" << filePrefix() << ":" << defaultID();
- return ret;
-}
-
-
-void PIBinaryLog::configureFromFullPath(const PIString & full_path) {
- PIStringList pl = full_path.split(":");
- for (int i = 0; i < pl.size_s(); ++i) {
- PIString p(pl[i]);
- switch (i) {
- case 0: setLogDir(p); break;
- case 1: setFilePrefix(p); break;
- case 2: setDefaultID(p.toInt()); break;
- }
- }
-}
-
diff --git a/pibinarylog.h b/pibinarylog.h
deleted file mode 100644
index 9958fb41..00000000
--- a/pibinarylog.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*! \file pibinarylog.h
- * \brief Binary log
-*/
-/*
- PIP - Platform Independent Primitives
- Class for write binary data to logfile, and read or playback this data
- Copyright (C) 2014 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 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#ifndef PIBINARYLOG_H
-#define PIBINARYLOG_H
-
-#include "pifile.h"
-
-#define PIBINARYLOG_VERSION 0x31
-#define PIBINARYLOG_SIGNATURE_SIZE 6
-
-
-class PIBinaryLog: public PIIODevice
-{
- PIIODEVICE(PIBinaryLog)
-public:
- PIBinaryLog();
- ~PIBinaryLog() {closeDevice();}
-
- //! \brief Play modes for \a PIBinaryLog
- enum PlayMode {
- PlayRealTime /*! Play in system real time */ ,
- PlayVariableSpeed /*! Play in software time with speed, set by \a setSpeed. Set by default */
- };
-
-
- //! Current \a PlayMode
- PlayMode playMode() const {return (PlayMode)(property("playMode").toInt());}
-
- //! Current directory where billogs wiil be saved
- PIString logDir() const {return property("logDir").toString();}
-
- //! Returns current file prefix
- PIString filePrefix() const {return property("filePrefix").toString();}
-
- //! Current LogDir, returns directory where billogs wiil be saved
- int defaultID() const {return property("defaultID").toInt();}
-
- //! Returns current play speed
- float playSpeed() const {return property("playSpeed").toFloat();}
-
- //! Returns if rapid start enabled
- bool rapidStart() const {return property("rapidStart").toBool();}
-
-
- //! Set \a PlayMode
- void setPlayMode(PlayMode mode) {setProperty("playMode", (int)mode);}
-
- //! Set path to directory where binlogs will be saved
- void setLogDir(const PIString & path) {setProperty("logDir", path);}
-
- //! Set file prefix, used to
- void setFilePrefix(const PIString & prefix) {setProperty("filePrefix", prefix);}
-
- //! Set defaultID, used in \a write function
- void setDefaultID(int id) {setProperty("defaultID", id);}
-
- //! If enabled BinLog \a ThreadedRead starts without delay for first record, e.g. first record will be readed immediately
- void setRapidStart(bool enabled) {setProperty("rapidStart", enabled);}
-
-// /** \brief Set play speed multiplyer, used only in \a PlayMode = \a PlayRealTime default value 1x.
-// * If "speedX" > 0 than it use as speed increase by X times, else as speed decrease by X times.
-// * While is running this function does nothing and returns false. If "speedX" is set, returns true.*/
-// bool setRealSpeedX(int speedX) {if (speedX == 0 || isRunning()) return false; real_speedX = speedX; return true;}
-// //! Returns current play speed multiplyer
-// float realSpeedX() const {return real_speedX;}
- //! Set play speed, used only if \a playMode = \a PlayVariableSpeed, default value 1.0
- void setPlaySpeed(float speed) {setProperty("playSpeed", speed);}
-
-
- //! Write one record to BinLog file, with ID = id, id must be greather than 0
- int writeBinLog(int id, PIByteArray data) {return writeBinLog(id, data.data(), data.size_s());}
-
- int writeBinLog(int id, const void * data, int size);
-
- //! Read one record from BinLog file, with ID = id, if id = 0 than any id will be readed
- PIByteArray readBinLog(int id = 0);
-
- int readBinLog(int id, void * read_to, int max_size);
-
- //! Return true, if position at the end of BinLog file
- bool isEnd() {if (!opened_) return true; return file.isEnd();}
-
- //! Returns if BinLog file is empty
- bool isEmpty() {return (file.size() <= PIBINARYLOG_SIGNATURE_SIZE + 1);}
-
- int lastReadedID() const {return lastrecord.id;}
-
- //! Read one message from binlog file, with ID contains in "filterID" or any ID, if "filterID" is empty
- int read(void *read_to, int max_size);
-
- //! Write one record to BinLog file, with ID = "defaultID"
- int write(const void * data, int size) {return writeBinLog(defaultID(), data, size);}
-
- //! Array of ID, that BinLog can read from binlog file, when use \a read function, or in \a ThreadedRead
- PIVector filterID;
-
- //! Go to begin of BinLog file
- void restart();
-
- PIString constructFullPath() const;
-
- //! \handlers
- //! \{
-
- //! \fn PIString createNewFile()
- //! \brief Open device
-
- //! \}
- //! \events
- //! \{
-
- //! \fn void fileEnd()
- //! \brief Create new binlog file in \a logDir, if successful returns filename, else returns empty string.
- //! Filename is like \a filePrefix + "yyyy_MM_dd__hh_mm_ss.binlog"
-
- //! \fn void fileError()
- //! \brief Raise on file creation error
-
- //! \}
-
- EVENT_HANDLER(PIString, createNewFile);
- EVENT(fileEnd)
- EVENT(fileError)
-
-protected:
- PIString fullPathPrefix() const {return "binlog";}
- void configureFromFullPath(const PIString & full_path);
- bool openDevice();
- bool closeDevice();
- bool threadedRead(uchar *readed, int size);
-
-private:
- struct BinLogRecord {
- int id;
- int size;
- PISystemTime timestamp;
- PIByteArray data;
- };
-
- bool writeFileHeader();
- bool checkFileHeader();
- BinLogRecord readRecord();
-
- PIFile file;
- BinLogRecord lastrecord;
- PISystemTime startlogtime;
- //BinLogRecord nextrecord;
- double play_time; //milliseconds
- //int real_speedX; // in X
- bool is_started, is_thread_ok;
- uchar binlog_sig[PIBINARYLOG_SIGNATURE_SIZE];
-
-};
-
-#endif // PIBINARYLOG_H
diff --git a/pibitarray.h b/pibitarray.h
deleted file mode 100644
index 2c874f0e..00000000
--- a/pibitarray.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- PIP - Platform Independent Primitives
- Bit array
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#ifndef PIBITARRAY_H
-#define PIBITARRAY_H
-
-#include "picontainers.h"
-
-class PIP_EXPORT PIBitArray {
-public:
- PIBitArray(const int & size = 0) {resize(size);}
- PIBitArray(uchar val) {resize(sizeof(val) * 8); data_[0] = val;}
- PIBitArray(ushort val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
- PIBitArray(uint val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
- PIBitArray(ulong val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
- PIBitArray(ullong val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
- PIBitArray(uchar * bytes, uint size) {resize(size * 8); memcpy(data(), bytes, size);}
-
- uint bitSize() const {return size_;}
- uint byteSize() const {return bytesInBits(size_);}
- PIBitArray & resize(const uint & size) {size_ = size; data_.resize(bytesInBits(size_)); return *this;}
-
- PIBitArray & clearBit(const uint & index) {data_[index / 8] &= ~(1 << (index % 8)); return *this;}
- PIBitArray & setBit(const uint & index) {data_[index / 8] |= (1 << (index % 8)); return *this;}
- PIBitArray & writeBit(const uint & index, const bool & value) {if (value) setBit(index); else clearBit(index); return *this;}
- PIBitArray & writeBit(const uint & index, const uchar & value) {return writeBit(index, value > 0);}
-
- PIBitArray & push_back(const bool & value) {resize(size_ + 1); writeBit(size_ - 1, value); return *this;}
- PIBitArray & push_back(const uchar & value) {return push_back(value > 0);}
- PIBitArray & insert(const uint & index, const bool & value) {
- resize(size_ + 1);
- uint fi = byteSize() - 1, si = index / 8, ti = index % 8;
- uchar c = data_[si];
- for (uint i = fi; i > si; --i) {
- data_[i] <<= 1;
- if ((0x80 & data_[i - 1]) == 0x80) data_[i] |= 1;
- else data_[i] &= 0xFE;}
- data_[si] &= (0xFF >> (7 - ti));
- data_[si] |= ((c << 1) & (0xFF << (ti)));
- if (value) data_[si] |= (1 << ti);
- else data_[si] &= ~(1 << ti);
- return *this;}
- PIBitArray & insert(const uint & index, const uchar & value) {return insert(index, value > 0);}
- PIBitArray & push_front(const bool & value) {return insert(0, value);}
- PIBitArray & push_front(const uchar & value) {return push_front(value > 0);}
- PIBitArray & pop_back() {return resize(size_ - 1);}
- PIBitArray & pop_front() {
- if (size_ == 0) return *this;
- uint fi = byteSize() - 1;
- for (uint i = 0; i < fi; ++i) {
- data_[i] >>= 1;
- if ((1 & data_[i + 1]) == 1) data_[i] |= 0x80;
- else data_[i] &= 0x7F;}
- data_[fi] >>= 1;
- resize(size_ - 1);
- return *this;}
- PIBitArray & append(const PIBitArray & ba) {for (uint i = 0; i < ba.bitSize(); ++i) push_back(ba[i]); return *this;}
-
- uchar * data() {return data_.data();}
- uchar toUChar() {if (size_ == 0) return 0; return data_[0];}
- ushort toUShort() {ushort t = 0; memcpy(&t, data(), piMin(byteSize(), sizeof(t))); return t;}
- uint toUInt() {uint t = 0; memcpy(&t, data(), piMin(byteSize(), sizeof(t))); return t;}
- ulong toULong() {ulong t = 0; memcpy(&t, data(), piMin(byteSize(), sizeof(t))); return t;}
- ullong toULLong() {ullong t = 0; memcpy(&t, data(), piMin(byteSize(), sizeof(t))); return t;}
-
- bool at(const uint & index) const {return (1 & (data_[index / 8] >> (index % 8))) == 1 ? true : false;}
- bool operator [](const uint & index) const {return at(index);}
- void operator +=(const PIBitArray & ba) {append(ba);}
- bool operator ==(const PIBitArray & ba) const {if (bitSize() != ba.bitSize()) return false; for (uint i = 0; i < bitSize(); ++i) if (at(i) != ba[i]) return false; return true;}
- bool operator !=(const PIBitArray & ba) const {return !(*this == ba);}
- void operator =(const uchar & val) {resize(sizeof(val) * 8); data_[0] = val;}
- void operator =(const ushort & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
- void operator =(const uint & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
- void operator =(const ulong & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
- void operator =(const ullong & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
-
-private:
- uint bytesInBits(const uint & bits) const {return (bits + 7) / 8;}
-
- PIVector data_;
- uint size_;
-
-};
-
-inline std::ostream & operator <<(std::ostream & s, const PIBitArray & ba) {for (uint i = 0; i < ba.bitSize(); ++i) {s << ba[i]; if (i % 8 == 7) s << ' ';} return s;}
-inline PICout operator <<(PICout s, const PIBitArray & ba) {s.space(); s.setControl(0, true); for (uint i = 0; i < ba.bitSize(); ++i) {s << ba[i]; if (i % 8 == 7) s << ' ';} s.restoreControl(); return s;}
-
-#endif // PIBITARRAY_H
diff --git a/pibytearray.cpp b/pibytearray.cpp
deleted file mode 100644
index 679afde4..00000000
--- a/pibytearray.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- PIP - Platform Independent Primitives
- Byte array
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#include "pibytearray.h"
-#include "pistring.h"
-
-/*! \class PIByteArray
- * \brief Byte array
- * \details This class based on PIDeque and provide some handle function
- * to manipulate it.
- *
- * \section PIByteArray_sec0 Usage
- * %PIByteArray can be used to store custom data and manipulate it. There are many
- * stream operators to store/restore common types to byte array. Store operators
- * places data at the end of array, restore operators takes data from the beginning
- * of array.
- * In addition there are Base 64 convertions and checksums:
- * * plain 8-bit
- * * plain 32-bit
- *
- * One of the major usage of %PIByteArray is stream functions. You can form binary
- * packet from many types (also dynamic types, e.g. PIVector) with one line:
- * \snippet pibytearray.cpp 0
- *
- * Or you can descibe stream operator of your own type and store/restore vectors of
- * your type:
- * \snippet pibytearray.cpp 1
- *
- * For store/restore custom data blocks there is PIByteArray::RawData class. Stream
- * operators of this class simply store/restore data block to/from byte array.
- * \snippet pibytearray.cpp 2
- *
- * \section PIByteArray_sec1 Attention
- * Stream operator of %PIByteArray store byte array as vector, not simply append
- * content of byte array. This operators useful to transmit custom data as %PIByteArray
- * packed into parent byte array, e.g. to form packet from %PIByteArray.
- * To append one byte array to another use funtion \a append().
- * \snippet pibytearray.cpp 3
- *
- *
- */
-
-
-#pragma pack(push, 1)
-
-const char PIByteArray::base64Table[64] = {
-0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
-0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
-0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
-0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
-0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
-0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
-0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33,
-0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f};
-
-const char PIByteArray::base64InvTable[256] = {
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x3F,
-0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
-0x3C, 0x3D, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6,
-0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE,
-0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
-0x17, 0x18, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
-0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
-0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
-0x31, 0x32, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
-
-#pragma pack(pop)
-
-
-int PIHuffman::nodeCompare(const void * f, const void * s) {
- return (reinterpret_cast(const_cast(s))->freq -
- reinterpret_cast(const_cast(f))->freq);
-}
-
-
-PIDeque PIHuffman::compress(const PIDeque & src) {
- calcFrequencies(src);
- return src;
-}
-
-
-void PIHuffman::calcFrequencies(const PIDeque & src) {
- nodes.resize(256);
- for (int i = 0; i < 256; ++i) {
- nodes[i].parent = nodes[i].right = nodes[i].left = 0;
- nodes[i].freq = 0;
- nodes[i].word.resize(1);
- nodes[i].word[0] = static_cast(i);
- }
- for (int i = 0; i < src.size_s(); ++i)
- nodes[src[i]].freq++;
- std::qsort(nodes.data(), 256, sizeof(node), nodeCompare);
- for (int i = 255; i >= 0; --i)
- if (nodes[i].freq > 0 && i < 255)
- {nodes.remove(i + 1, 255 - i); break;}
- for (int i = 0; i < nodes.size_s(); ++i)
- cout << string((char*)nodes[i].word.data(), 1) << ": " << nodes[i].freq << endl;
-}
-
-
-PIHuffman PIByteArray::huffman;
-
-PIByteArray & PIByteArray::convertToBase64() {
- base64HelpStruct hs;
- PIByteArray t;
- if (size() == 0) return *this;
- int sz = (size_s() / 3) * 3;
- for (int i = 0; i < sz; ++i) {
- hs.byte.byte0 = hs.byte.byte1 = hs.byte.byte2 = 0;
- hs.byte.byte0 = at(i);
- hs.byte.byte1 = at(++i);
- hs.byte.byte2 = at(++i);
- t.push_back(base64Table[hs.ascii.ascii0]);
- t.push_back(base64Table[hs.ascii.ascii1]);
- t.push_back(base64Table[hs.ascii.ascii2]);
- t.push_back(base64Table[hs.ascii.ascii3]);
- }
- hs.byte.byte0 = hs.byte.byte1 = hs.byte.byte2 = 0; sz = size() % 3;
- switch (sz) {
- case 1:
- hs.byte.byte0 = back();
- t.push_back(base64Table[hs.ascii.ascii0]);
- t.push_back(base64Table[hs.ascii.ascii1]);
- t.push_back('=');
- t.push_back('=');
- break;
- case 2:
- hs.byte.byte0 = at(size() - 2); hs.byte.byte1 = back();
- t.push_back(base64Table[hs.ascii.ascii0]);
- t.push_back(base64Table[hs.ascii.ascii1]);
- t.push_back(base64Table[hs.ascii.ascii2]);
- t.push_back('=');
- break;
- default: break;
- }
- *this = t;
- return *this;
-}
-
-
-PIByteArray & PIByteArray::convertFromBase64() {
- base64HelpStruct hs;
- PIByteArray t;
- uint sz = size();
- if (sz == 0) return *this;
- for (uint i = 0; i < sz; ++i) {
- hs.byte.byte0 = hs.byte.byte1 = hs.byte.byte2 = 0;
- hs.ascii.ascii0 = base64InvTable[at(i)];
- hs.ascii.ascii1 = base64InvTable[at(++i)];
- hs.ascii.ascii2 = base64InvTable[at(++i)];
- hs.ascii.ascii3 = base64InvTable[at(++i)];
- t.push_back(hs.byte.byte0);
- t.push_back(hs.byte.byte1);
- t.push_back(hs.byte.byte2);
- }
- if (back() == '=') t.pop_back();
- if (sz > 1) if (at(sz - 2) == '=') t.pop_back();
- *this = t;
- return *this;
-}
-
-
-PIByteArray & PIByteArray::compressRLE(uchar threshold) {
- PIByteArray t;
- uchar fb, clen, mlen = 255 - threshold;
- for (uint i = 0; i < size();) {
- fb = at(i);
- clen = 1;
- while (at(++i) == fb) {
- ++clen;
- if (clen == mlen)
- break;
- }
- if (clen > 1) {
- t.push_back(threshold + clen);
- t.push_back(fb);
- continue;
- }
- if (fb >= threshold) {
- t.push_back(threshold + 1);
- t.push_back(fb);
- } else
- t.push_back(fb);
- }
- *this = t;
- return *this;
-}
-
-
-PIByteArray & PIByteArray::decompressRLE(uchar threshold) {
- PIByteArray t;
- uchar fb, clen;
- for (uint i = 0; i < size(); ++i) {
- fb = at(i);
- if (fb >= threshold) {
- clen = fb - threshold;
- fb = at(++i);
- for (uint j = 0; j < clen; ++j)
- t.push_back(fb);
- continue;
- } else
- t.push_back(fb);
- }
- *this = t;
- return *this;
-}
-
-
-uchar PIByteArray::checksumPlain8() const {
- uchar c = 0;
- int sz = size_s();
- for (int i = 0; i < sz; ++i)
- c += at(i);
- c = ~(c + 1);
- return c;
-}
-
-
-uint PIByteArray::checksumPlain32() const {
- uint c = 0;
- int sz = size_s();
- for (int i = 0; i < sz; ++i)
- c += at(i) * (i + 1);
- c = ~(c + 1);
- return c;
-}
-
-
-PIString PIByteArray::toString(int base) const {
- PIString ret;
- int sz = size_s();
- for (int i = 0; i < sz; ++i) {
- if (i > 0) ret += " ";
- if (base == 2) ret += "b";
- if (base == 8) ret += "0";
- if (base == 16) ret += "0x";
- ret += PIString::fromNumber(at(i), base);
- }
- return ret;
-}
-
-
-PIByteArray PIByteArray::fromString(PIString str) {
- PIByteArray ret;
- if (str.trim().isEmpty()) return ret;
- str.replaceAll("\n", " ").replaceAll("\t", " ").replaceAll(" ", " ");
- PIStringList bl(str.split(" "));
- bool ok(false);
- piForeachC (PIString & b, bl) {
- int bv = b.toInt(-1, &ok);
- if (ok) ret << uchar(bv);
- }
- return ret;
-}
diff --git a/pibytearray.h b/pibytearray.h
deleted file mode 100644
index 92e1acf7..00000000
--- a/pibytearray.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/*! \file pibytearray.h
- * \brief Byte array
-*/
-/*
- PIP - Platform Independent Primitives
- Byte array
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#ifndef PIBYTEARRAY_H
-#define PIBYTEARRAY_H
-
-#ifdef DOXYGEN
-//! This macro allow stream template operators for write and read any type from byte array. Use it with attention!
-# define PIP_BYTEARRAY_STREAM_ANY_TYPE
-#endif
-
-#include "pibitarray.h"
-
-class PIString;
-class PIByteArray;
-
-class PIHuffman {
-public:
- PIDeque compress(const PIDeque & src);
-
-private:
- struct node {
- int freq;
- PIDeque word;
- PIBitArray path;
- node * parent;
- node * right;
- node * left;
- };
- static int nodeCompare(const void * f, const void * s);
- void calcFrequencies(const PIDeque & src);
- PIVector nodes;
-};
-
-class PIP_EXPORT PIByteArray: public PIDeque
-{
-public:
-
- //! Constructs an empty byte array
- PIByteArray() {;}
-
- //! Constructs 0-filled byte array with size "size"
- PIByteArray(const uint size) {resize(size);}
-
- //! Constructs byte array from data "data" and size "size"
- PIByteArray(const void * data, const uint size): PIDeque((const uchar*)data, size_t(size)) {/*for (uint i = 0; i < size; ++i) push_back(((uchar * )data)[i]);*/}
-
-
- //! Help struct to store/restore custom blocks of data to/from PIByteArray
- struct RawData {
- friend PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v);
- friend PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v);
- public:
- //! Constructs data block
- RawData(void * data = 0, int size = 0) {d = data; s = size;}
- //! Constructs data block
- RawData(const void * data, const int size) {d = const_cast(data); s = size;}
- RawData & operator =(const RawData & o) {d = o.d; s = o.s; return *this;}
- private:
- void * d;
- int s;
- };
-
- //! Return resized byte array
- PIByteArray resized(int new_size) const {PIByteArray tv(*this); tv.resize(new_size); return tv;}
-
- //! Convert data to Base 64 and return this byte array
- PIByteArray & convertToBase64();
-
- //! Convert data from Base 64 and return this byte array
- PIByteArray & convertFromBase64();
-
- //! Return converted to Base 64 data
- PIByteArray toBase64() const {PIByteArray ba(*this); ba.convertToBase64(); return ba;}
-
- //! Return converted from Base 64 data
- PIByteArray fromBase64() const {PIByteArray ba(*this); ba.convertFromBase64(); return ba;}
-
- PIByteArray & compressRLE(uchar threshold = 192);
- PIByteArray & decompressRLE(uchar threshold = 192);
- PIByteArray compressedRLE(uchar threshold = 192) {PIByteArray ba(*this); ba.compressRLE(threshold); return ba;}
- PIByteArray decompressedRLE(uchar threshold = 192) {PIByteArray ba(*this); ba.decompressRLE(threshold); return ba;}
-
- PIByteArray & compressHuffman() {*this = huffman.compress(*this); return *this;}
-
- PIString toString(int base = 16) const;
-
- //! Add to the end data "data" with size "size"
- PIByteArray & append(const void * data_, int size_) {uint ps = size(); enlarge(size_); memcpy(data(ps), data_, size_); return *this;}
-
- //! Add to the end byte array "data"
- PIByteArray & append(const PIByteArray & data_) {uint ps = size(); enlarge(data_.size_s()); memcpy(data(ps), data_.data(), data_.size()); return *this;}
- /*PIByteArray & operator <<(short v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}
- PIByteArray & operator <<(ushort v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}
- PIByteArray & operator <<(int v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}
- PIByteArray & operator <<(uint v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}
- PIByteArray & operator <<(llong v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}
- PIByteArray & operator <<(ullong v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}*/
- //PIByteArray & operator <<(const PIByteArray & v) {for (uint i = 0; i < v.size(); ++i) push_back(v[i]); return *this;}
-
- //! Returns plain 8-bit checksum
- uchar checksumPlain8() const;
-
- //! Returns plain 32-bit checksum
- uint checksumPlain32() const;
-
- void operator =(const PIDeque & d) {resize(d.size()); memcpy(data(), d.data(), d.size());}
-
- static PIByteArray fromString(PIString str);
-
-private:
- union base64HelpStruct {
- base64HelpStruct() {memset(this, 0, sizeof(base64HelpStruct));}
- struct {
- uchar ascii0: 6;
- uchar ascii1: 6;
- uchar ascii2: 6;
- uchar ascii3: 6;
- } ascii;
- struct {
- uchar byte0;
- uchar byte1;
- uchar byte2;
- } byte;
- };
-
- static const char base64Table[64];
- static const char base64InvTable[256];
- static PIHuffman huffman;
-
-};
-
-inline bool operator <(const PIByteArray & v0, const PIByteArray & v1) {if (v0.size() == v1.size()) {for (uint i = 0; i < v0.size(); ++i) if (v0[i] != v1[i]) return v0[i] < v1[i]; return false;} return v0.size() < v1.size();}
-//! \relatesalso PIByteArray \brief Output to std::ostream operator
-inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba) {s << "{"; for (uint i = 0; i < ba.size(); ++i) {s << ba[i]; if (i < ba.size() - 1) s << ", ";} s << "}"; return s;}
-
-//! \relatesalso PIByteArray \brief Output to PICout operator
-inline PICout operator <<(PICout s, const PIByteArray & ba) {s.space(); s.setControl(0, true); s << "{"; for (uint i = 0; i < ba.size(); ++i) {s << ba[i]; if (i < ba.size() - 1) s << ", ";} s << "}"; s.restoreControl(); return s;}
-
-#define PBA_OPERATOR_TO int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v));
-
-//! \relatesalso PIByteArray \brief Store operator
-inline PIByteArray & operator <<(PIByteArray & s, uchar v) {s.push_back(v); return s;}
-//! \relatesalso PIByteArray \brief Store operator
-inline PIByteArray & operator <<(PIByteArray & s, const short v) {PBA_OPERATOR_TO return s;}
-//! \relatesalso PIByteArray \brief Store operator
-inline PIByteArray & operator <<(PIByteArray & s, const int v) {PBA_OPERATOR_TO return s;}
-//! \relatesalso PIByteArray \brief Store operator
-inline PIByteArray & operator <<(PIByteArray & s, const long & v) {PBA_OPERATOR_TO return s;}
-//! \relatesalso PIByteArray \brief Store operator
-inline PIByteArray & operator <<(PIByteArray & s, const llong & v) {PBA_OPERATOR_TO return s;}
-//! \relatesalso PIByteArray \brief Store operator
-inline PIByteArray & operator <<(PIByteArray & s, const ushort v) {PBA_OPERATOR_TO return s;}
-//! \relatesalso PIByteArray \brief Store operator
-inline PIByteArray & operator <<(PIByteArray & s, const uint v) {PBA_OPERATOR_TO return s;}
-//! \relatesalso PIByteArray \brief Store operator
-inline PIByteArray & operator <<(PIByteArray & s, const ulong & v) {PBA_OPERATOR_TO return s;}
-//! \relatesalso PIByteArray \brief Store operator
-inline PIByteArray & operator <<(PIByteArray & s, const ullong & v) {PBA_OPERATOR_TO return s;}
-//! \relatesalso PIByteArray \brief Store operator
-inline PIByteArray & operator <<(PIByteArray & s, const float v) {PBA_OPERATOR_TO return s;}
-//! \relatesalso PIByteArray \brief Store operator
-inline PIByteArray & operator <<(PIByteArray & s, const double & v) {PBA_OPERATOR_TO return s;}
-//! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details
-inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v) {s << v.size_s(); int os = s.size_s(); s.enlarge(v.size_s()); if (v.size_s() > 0) memcpy(s.data(os), v.data(), v.size()); return s;}
-//! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details
-inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v) {int os = s.size_s(); s.enlarge(v.s); if (v.s > 0) memcpy(s.data(os), v.d, v.s); return s;}
-//! \relatesalso PIByteArray \brief Store operator
-template
-inline PIByteArray & operator <<(PIByteArray & s, const PIPair & v) {s << v.first << v.second; return s;}
-//! \relatesalso PIByteArray \brief Store operator
-template
-inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
-//! \relatesalso PIByteArray \brief Store operator
-template
-inline PIByteArray & operator <<(PIByteArray & s, const PIList & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
-//! \relatesalso PIByteArray \brief Store operator
-template
-inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
-#ifdef PIP_BYTEARRAY_STREAM_ANY_TYPE
-template
-inline PIByteArray & operator <<(PIByteArray & s, const T & v) {PBA_OPERATOR_TO return s;}
-#endif
-
-#undef PBA_OPERATOR_TO
-#define PBA_OPERATOR_FROM memcpy(&v, s.data(), sizeof(v)); s.remove(0, sizeof(v));
-
-//! \relatesalso PIByteArray \brief Restore operator
-inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= 1u); v = s.take_front(); return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-inline PIByteArray & operator >>(PIByteArray & s, short & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-inline PIByteArray & operator >>(PIByteArray & s, int & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-inline PIByteArray & operator >>(PIByteArray & s, long & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-inline PIByteArray & operator >>(PIByteArray & s, llong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-inline PIByteArray & operator >>(PIByteArray & s, ushort & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-inline PIByteArray & operator >>(PIByteArray & s, uint & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-inline PIByteArray & operator >>(PIByteArray & s, ulong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-inline PIByteArray & operator >>(PIByteArray & s, ullong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-inline PIByteArray & operator >>(PIByteArray & s, float & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-inline PIByteArray & operator >>(PIByteArray & s, double & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
-//! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details
-inline PIByteArray & operator >>(PIByteArray & s, PIByteArray & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); if (sz > 0) memcpy(v.data(), s.data(), v.size()); s.remove(0, v.size()); return s;}
-//! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details
-inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) {assert(s.size_s() >= v.s); if (v.s > 0) memcpy(v.d, s.data(), v.s); s.remove(0, v.s); return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-template
-inline PIByteArray & operator >>(PIByteArray & s, PIPair & v) {s >> v.first >> v.second; return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-template
-inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-template
-inline PIByteArray & operator >>(PIByteArray & s, PIList & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
-//! \relatesalso PIByteArray \brief Restore operator
-template
-inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
-// //! \relatesalso PIByteArray \brief Restore operator
-//template
-//inline PIByteArray & operator >>(PIByteArray & s, PIMap & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
-#ifdef PIP_BYTEARRAY_STREAM_ANY_TYPE
-template
-inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
-#endif
-
-
-#undef PBA_OPERATOR_FROM
-
-//! \relatesalso PIByteArray \brief Byte arrays compare operator
-inline bool operator ==(PIByteArray & f, PIByteArray & s) {if (f.size_s() != s.size_s()) return false; for (int i = 0; i < f.size_s(); ++i) if (f[i] != s[i]) return false; return true;}
-//! \relatesalso PIByteArray \brief Byte arrays compare operator
-inline bool operator !=(PIByteArray & f, PIByteArray & s) {if (f.size_s() != s.size_s()) return true; for (int i = 0; i < f.size_s(); ++i) if (f[i] != s[i]) return true; return false;}
-
-#endif // PIBYTEARRAY_H
diff --git a/pichar.h b/pichar.h
deleted file mode 100644
index c0cd81ea..00000000
--- a/pichar.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*! \file pichar.h
- * \brief Unicode char
-*/
-/*
- PIP - Platform Independent Primitives
- Unicode char
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#ifndef PICHAR_H
-#define PICHAR_H
-
-#include "pibytearray.h"
-/*! \brief Unicode char
- * \details This class is wrapper around \c "uint".
- * There are many contructors and information functions
- */
-class PIP_EXPORT PIChar
-{
- friend class PIString;
- friend PIByteArray & operator <<(PIByteArray & s, const PIChar & v);
- friend PIByteArray & operator >>(PIByteArray & s, PIChar & v);
-public:
- //! Contructs ascii symbol
- PIChar(const char c) {ch = c; ch &= 0xFF;}
-
- //! Contructs 2-bytes symbol
- PIChar(const short c) {ch = c; ch &= 0xFFFF;}
-
- //! Contructs 4-bytes symbol
- PIChar(const int c) {ch = c;}
-
- //! Contructs ascii symbol
- PIChar(const uchar c) {ch = c; ch &= 0xFF;}
-
- //! Contructs 2-bytes symbol
- PIChar(const ushort c) {ch = c; ch &= 0xFFFF;}
-
- //! Default constructor. Contructs 4-bytes symbol
- PIChar(const uint c = 0) {ch = c;}
-
- //! Contructs symbol from no more than 4 bytes of string
- PIChar(const char * c) {ch = *reinterpret_cast(c);}
-
- //inline operator const int() {return static_cast(ch);}
- //inline operator const char() {return toAscii();}
-
- //! Copy operator
- PIChar & operator =(const char v) {ch = v; return *this;}
- /*inline PIChar & operator =(const short v) {ch = v; return *this;}
- inline PIChar & operator =(const int v) {ch = v; return *this;}
- inline PIChar & operator =(const uchar v) {ch = v; return *this;}
- inline PIChar & operator =(const ushort v) {ch = v; return *this;}
- inline PIChar & operator =(const uint v) {ch = v; return *this;}*/
-
- //! Compare operator
- bool operator ==(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) == 0;}
- /*inline bool operator ==(const PIChar & o) const {if (o.isAscii() ^ isAscii()) return false;
- if (isAscii()) return (o.toAscii() == toAscii());
- return (o.toInt() == toInt());}
- inline bool operator ==(const char o) const {return (PIChar(o) == *this);}
- inline bool operator ==(const short o) const {return (PIChar(o) == *this);}
- inline bool operator ==(const int o) const {return (PIChar(o) == *this);}
- inline bool operator ==(const uchar o) const {return (PIChar(o) == *this);}
- inline bool operator ==(const ushort o) const {return (PIChar(o) == *this);}
- inline bool operator ==(const uint o) const {return (PIChar(o) == *this);}*/
-
- //! Compare operator
- bool operator !=(const PIChar & o) const {return !(o == *this);}
- /*inline bool operator !=(const char o) const {return (PIChar(o) != *this);}
- inline bool operator !=(const short o) const {return (PIChar(o) != *this);}
- inline bool operator !=(const int o) const {return (PIChar(o) != *this);}
- inline bool operator !=(const uchar o) const {return (PIChar(o) != *this);}
- inline bool operator !=(const ushort o) const {return (PIChar(o) != *this);}
- inline bool operator !=(const uint o) const {return (PIChar(o) != *this);}*/
-
- //! Compare operator
- bool operator >(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) < 0;}
-
- //! Compare operator
- bool operator <(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) > 0;}
-
- //! Compare operator
- bool operator >=(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) <= 0;}
-
- //! Compare operator
- bool operator <=(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) >= 0;}
-
- //! Return \b true if symbol is digit ('0' to '9')
- bool isDigit() const {return isdigit(ch) != 0;}
-
- //! Return \b true if symbol is HEX digit ('0' to '9', 'a' to 'f', 'A' to 'F')
- bool isHex() const {return isxdigit(ch) != 0;}
-
- //! Return \b true if symbol is drawable (without space)
- bool isGraphical() const {return isgraph(ch) != 0;}
-
- //! Return \b true if symbol is control byte (< 32 or 127)
- bool isControl() const {return iscntrl(ch) != 0;}
-
- //! Return \b true if symbol is in lower case
- bool isLower() const {return islower(ch) != 0;}
-
- //! Return \b true if symbol is in upper case
- bool isUpper() const {return isupper(ch) != 0;}
-
- //! Return \b true if symbol is printable (with space)
- bool isPrint() const {return isprint(ch) != 0;}
-
- //! Return \b true if symbol is space or tab
- bool isSpace() const {return isspace(ch) != 0;}
-
- //! Return \b true if symbol is alphabetical letter
- bool isAlpha() const {return isalpha(ch) != 0;}
-
- //! Return \b true if symbol is ascii (< 128)
- bool isAscii() const {return isascii(ch) != 0;}
-
- int toInt() const {return int(ch);}
- const wchar_t * toWCharPtr() const {return reinterpret_cast(&ch);}
-
- //! Return as "char * " string
- const char * toCharPtr() const {return reinterpret_cast(&ch);}
-
- wchar_t toWChar() const {return wchar_t(ch);}
- char toAscii() const {return ch % 256;}
- int unicode16Code() const {wchar_t wc; if (mbtowc(&wc, toCharPtr(), 4) > 0) return wc; return 0;}
-//#ifdef WINDOWS
-// inline PIChar toUpper() const __attribute__ ((optimize(0))) {return PIChar(toupper(ch));}
-// inline PIChar toLower() const __attribute__ ((optimize(0))) {return PIChar(tolower(ch));}
-//#else
-
- //! Return symbol in upper case
- PIChar toUpper() const {return PIChar(toupper(ch));}
-
- //! Return symbol in lower case
- PIChar toLower() const {return PIChar(tolower(ch));}
-//#endif
-
-private:
- uint ch;
-
-};
-
-__PICONTAINERS_SIMPLE_TYPE__(PIChar)
-
-//! Output operator to \c std::ostream
-inline std::ostream & operator <<(std::ostream & s, const PIChar & v) {s << v.toCharPtr(); return s;}
-
-//! Output operator to \a PICout
-inline PICout operator <<(PICout s, const PIChar & v) {s.space(); s.setControl(0, true); s << v.toCharPtr(); s.restoreControl(); return s;}
-
-
-//! Write operator to \c PIByteArray
-inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {s << uint(v.ch); return s;}
-
-//! Read operator from \c PIByteArray
-inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {uint i; s >> i; v.ch = wchar_t(i); return s;}
-
-
-//! Compare operator
-inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);}
-
-//! Compare operator
-inline bool operator >(const char v, const PIChar & c) {return (PIChar(v) > c);}
-
-//! Compare operator
-inline bool operator <(const char v, const PIChar & c) {return (PIChar(v) < c);}
-
-//! Compare operator
-inline bool operator >=(const char v, const PIChar & c) {return (PIChar(v) >= c);}
-
-//! Compare operator
-inline bool operator <=(const char v, const PIChar & c) {return (PIChar(v) <= c);}
-
-
-//! Compare operator
-inline bool operator ==(const char * v, const PIChar & c) {return (PIChar(v) == c);}
-
-//! Compare operator
-inline bool operator >(const char * v, const PIChar & c) {return (PIChar(v) > c);}
-
-//! Compare operator
-inline bool operator <(const char * v, const PIChar & c) {return (PIChar(v) < c);}
-
-//! Compare operator
-inline bool operator >=(const char * v, const PIChar & c) {return (PIChar(v) >= c);}
-
-//! Compare operator
-inline bool operator <=(const char * v, const PIChar & c) {return (PIChar(v) <= c);}
-
-
-//! Compare operator
-inline bool operator ==(const int v, const PIChar & c) {return (PIChar(v) == c);}
-
-//! Compare operator
-inline bool operator >(const int v, const PIChar & c) {return (PIChar(v) > c);}
-
-//! Compare operator
-inline bool operator <(const int v, const PIChar & c) {return (PIChar(v) < c);}
-
-//! Compare operator
-inline bool operator >=(const int v, const PIChar & c) {return (PIChar(v) >= c);}
-
-//! Compare operator
-inline bool operator <=(const int v, const PIChar & c) {return (PIChar(v) <= c);}
-
-#endif // PICHAR_H
diff --git a/picli.cpp b/picli.cpp
deleted file mode 100644
index eeeae750..00000000
--- a/picli.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- PIP - Platform Independent Primitives
- Command-Line Parser
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#include "picli.h"
-
-
-/*! \class PICLI
- * \brief Command-line arguments parser
- *
- * \section PICLI_sec0 Synopsis
- * This class provide handy parsing of command-line arguments. First you should add
- * arguments to PICLI with function \a addArgument(). Then you can check if there
- * is some argument in application command-line with function \a hasArgument();
- * \section PICLI_sec1 Example
- * \snippet picli.cpp main
- */
-
-
-PICLI::PICLI(int argc, char * argv[]) {
- needParse = true;
- _prefix_short = "-";
- _prefix_full = "--";
- _count_opt = 0;
- _count_mand = 0;
- for (int i = 0; i < argc; ++i)
- _args_raw << argv[i];
-}
-
-
-void PICLI::parse() {
- if (!needParse) return;
- PIString cra, full;
- Argument * last = 0;
- for (int i = 1; i < _args_raw.size_s(); ++i) {
- cra = _args_raw[i];
- if (cra.left(2) == _prefix_full) {
- last = 0;
- full = cra.right(cra.length() - 2);
- piForeach (Argument & a, _args) {
- if (a.full_key == full) {
- a.found = true;
- last = &a;
- break;
- }
- }
- } else {
- if (cra.left(1) == _prefix_short) {
- last = 0;
- for (int j = 1; j < cra.length(); ++j) {
- bool found = false;
- piForeach (Argument & a, _args) {
- if (a.short_key == cra[j]) {
- a.found = true;
- last = &a;
- found = true;
- break;
- }
- }
- if (!found) break;
- }
- } else {
- if (last == 0 ? true : !last->has_value) {
- if (_args_mand.size_s() < _count_mand) {
- _args_mand << cra;
- continue;
- }
- if (_args_opt.size_s() < _count_opt || _count_opt < 0) {
- _args_opt << cra;
- continue;
- }
- piCoutObj << "[PICli] Arguments overflow, \"" << cra << "\" ignored";
- }
- if (last == 0 ? false : last->has_value) {
- last->value = cra;
- last = 0;
- }
- }
- }
- }
- needParse = false;
-}
diff --git a/picli.h b/picli.h
deleted file mode 100644
index ce58d5f8..00000000
--- a/picli.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*! \file picli.h
- * \brief Command-Line parser
-*/
-/*
- PIP - Platform Independent Primitives
- Command-Line Parser
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#ifndef PICLI_H
-#define PICLI_H
-
-#include "piobject.h"
-
-class PIP_EXPORT PICLI: public PIObject
-{
- PIOBJECT(PICLI)
-public:
-
- //! Constructor
- PICLI(int argc, char * argv[]);
-
-
- //! Add argument with name "name", short key = name first letter, full key = name
- void addArgument(const PIString & name, bool value = false) {_args << Argument(name, name[0], name, value); needParse = true;}
-
- //! Add argument with name "name", short key = "shortKey", full key = name
- void addArgument(const PIString & name, const PIChar & shortKey, bool value = false) {_args << Argument(name, shortKey, name, value); needParse = true;}
-
- //! Add argument with name "name", short key = "shortKey", full key = name
- void addArgument(const PIString & name, const char * shortKey, bool value = false) {_args << Argument(name, PIChar(shortKey), name, value); needParse = true;}
-
- //! Add argument with name "name", short key = "shortKey", full key = "fullKey"
- void addArgument(const PIString & name, const PIChar & shortKey, const PIString & fullKey, bool value = false) {_args << Argument(name, shortKey, fullKey, value); needParse = true;}
-
- //! Add argument with name "name", short key = "shortKey", full key = "fullKey"
- void addArgument(const PIString & name, const char * shortKey, const PIString & fullKey, bool value = false) {_args << Argument(name, PIChar(shortKey), fullKey, value); needParse = true;}
-
-
- //! Returns unparsed command-line argument by index "index". Index 0 is program execute command.
- PIString rawArgument(int index) {parse(); return _args_raw[index];}
- PIString mandatoryArgument(int index) {parse(); return _args_mand[index];}
- PIString optionalArgument(int index) {parse(); return _args_opt[index];}
-
- //! Returns unparsed command-line arguments
- const PIStringList & rawArguments() {parse(); return _args_raw;}
- const PIStringList & mandatoryArguments() {parse(); return _args_mand;}
- const PIStringList & optionalArguments() {parse(); return _args_opt;}
-
- //! Returns program execute command without arguments
- PIString programCommand() {parse(); return _args_raw.size() > 0 ? _args_raw.front() : PIString();}
- bool hasArgument(const PIString & name) {parse(); piForeach (Argument & i, _args) if (i.name == name && i.found) return true; return false;}
- PIString argumentValue(const PIString & name) {parse(); piForeach (Argument &i, _args) if (i.name == name && i.found) return i.value; return PIString();}
- PIString argumentShortKey(const PIString & name) {piForeach (Argument &i, _args) if (i.name == name) return i.short_key; return PIString();}
- PIString argumentFullKey(const PIString & name) {piForeach (Argument &i, _args) if (i.name == name) return i.full_key; return PIString();}
-
- const PIString & shortKeyPrefix() const {return _prefix_short;}
- const PIString & fullKeyPrefix() const {return _prefix_full;}
- int mandatoryArgumentsCount() const {return _count_mand;}
- int optionalArgumentsCount() const {return _count_opt;}
- void setShortKeyPrefix(const PIString & prefix) {_prefix_short = prefix; needParse = true;}
- void setFullKeyPrefix(const PIString & prefix) {_prefix_full = prefix; needParse = true;}
- void setMandatoryArgumentsCount(const int count) {_count_mand = count; needParse = true;}
- void setOptionalArgumentsCount(const int count) {_count_opt = count; needParse = true;}
-
-private:
- struct Argument {
- Argument() {has_value = found = false;}
- Argument(const PIString & n, const PIChar & s, const PIString & f, bool v) {name = n; short_key = s; full_key = f; has_value = v; found = false;}
- PIString name;
- PIChar short_key;
- PIString full_key;
- PIString value;
- bool has_value, found;
- };
-
- void parse();
-
- PIString _prefix_short, _prefix_full;
- PIStringList _args_raw, _args_mand, _args_opt;
- PISet keys_full, keys_short;
- PIVector _args;
- int _count_mand, _count_opt;
- bool needParse;
-
-};
-
-#endif // PICLI_H
diff --git a/picodec.cpp b/picodec.cpp
deleted file mode 100644
index cecb3d32..00000000
--- a/picodec.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- PIP - Platform Independent Primitives
- Text codings coder, based on "iconv"
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#include "picodec.h"
-
-
-PIStringList PICodec::availableCodecs() {
- exec("/usr/bin/iconv", "-l");
- waitForFinish();
- PIString str(readOutput());
- str.cutLeft(str.find("\n "));
- str.replaceAll("\n", "");
- return str.split("//");
-}
-
-
-PIByteArray PICodec::exec_iconv(const PIString & from, const PIString & to, const PIByteArray & str) {
- tf.open();
- tf.clear();
- tf << str;
- tf.close();
- exec("/usr/bin/iconv", ("-f=" + from), ("-t=" + to), tf.path());
- waitForFinish();
- return readOutput();
-}
diff --git a/picodec.h b/picodec.h
deleted file mode 100644
index 81517b48..00000000
--- a/picodec.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- PIP - Platform Independent Primitives
- Text codings coder, based on "iconv"
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#ifndef PICODEC_H
-#define PICODEC_H
-
-#include "piprocess.h"
-
-class PIP_EXPORT PICodec: private PIProcess
-{
-public:
- PICodec(): PIProcess() {setGrabOutput(true); tf = PIFile::openTemporary(PIIODevice::ReadWrite); tf.open();}
- PICodec(const PIString & from, const PIString & to): PIProcess() {setCodings(from, to); tf = PIFile::openTemporary(PIIODevice::ReadWrite);}
- ~PICodec() {tf.remove();}
-
- void setFromCoding(const PIString & from) {c_from = from;}
- void setToCoding(const PIString & to) {c_to = to;}
- void setCodings(const PIString & from, const PIString & to) {c_from = from; c_to = to;}
-
- PIStringList availableCodecs();
- PIString encode(PIString & str) {return PIString(exec_iconv(c_from, c_to, str.toByteArray()));}
- PIString encode(const PIByteArray & str) {return PIString(exec_iconv(c_from, c_to, str));}
- PIString decode(PIString & str) {return PIString(exec_iconv(c_to, c_from, str.toByteArray()));}
- PIString decode(const PIByteArray & str) {return PIString(exec_iconv(c_to, c_from, str));}
-
-private:
- PIByteArray exec_iconv(const PIString & from, const PIString & to, const PIByteArray & str);
-
- PIString c_from, c_to;
- PIFile tf;
-
-};
-
-#endif // PICODEC_H
diff --git a/picodeinfo.cpp b/picodeinfo.cpp
deleted file mode 100644
index ef2801b3..00000000
--- a/picodeinfo.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- PIP - Platform Independent Primitives
- C++ code info structs
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#include "picodeinfo.h"
-
-
-PIString PICodeInfo::EnumInfo::memberName(int value_) const {
- piForeachC (PICodeInfo::EnumeratorInfo & e, members)
- if (e.value == value_)
- return e.name;
- return PIString();
-}
-
-
-int PICodeInfo::EnumInfo::memberValue(const PIString & name_) const {
- piForeachC (PICodeInfo::EnumeratorInfo & e, members)
- if (e.name == name_)
- return e.value;
- return -1;
-}
-
-
-PIMap * PICodeInfo::classesInfo;
-PIMap * PICodeInfo::enumsInfo;
-
-bool __PICodeInfoInitializer__::_inited_ = false;
diff --git a/picodeinfo.h b/picodeinfo.h
deleted file mode 100644
index c303941c..00000000
--- a/picodeinfo.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*! \file picodeinfo.h
- * \brief C++ code info structs
-*/
-/*
- PIP - Platform Independent Primitives
- C++ code info structs
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-
-#ifndef PICODEINFO_H
-#define PICODEINFO_H
-
-#include "pistring.h"
-
-namespace PICodeInfo {
-
-enum TypeFlag {NoFlag, Const = 0x01, Static = 0x02, Mutable = 0x04, Volatile = 0x08, Inline = 0x10, Virtual = 0x20};
-
-typedef PIFlags TypeFlags;
-
-struct TypeInfo {
- TypeInfo(const PIString & n = PIString(), const PIString & t = PIString(), PICodeInfo::TypeFlags f = 0) {name = n; type = t; flags = f;}
- PIString name;
- PIString type;
- PICodeInfo::TypeFlags flags;
-};
-
-struct FunctionInfo {
- PIString name;
- TypeInfo return_type;
- PIVector arguments;
-};
-
-struct ClassInfo {
- PIString name;
- PIStringList parents;
- PIVector variables;
- PIVector functions;
-};
-
-struct EnumeratorInfo {
- EnumeratorInfo(const PIString & n = PIString(), int v = 0) {name = n; value = v;}
- PIString name;
- int value;
-};
-
-struct EnumInfo {
- PIString memberName(int value) const;
- int memberValue(const PIString & name) const;
- PIString name;
- PIVector members;
-};
-
-
-inline PICout operator <<(PICout s, const PICodeInfo::TypeInfo & v) {
- if (v.flags[Inline]) s << "inline ";
- if (v.flags[Virtual]) s << "virtual ";
- if (v.flags[Mutable]) s << "mutable ";
- if (v.flags[Volatile]) s << "volatile ";
- if (v.flags[Static]) s << "static ";
- if (v.flags[Const]) s << "const ";
- s << v.type;
- if (!v.name.isEmpty())
- s << " " << v.name;
- return s;
-}
-
-inline PICout operator <<(PICout s, const PICodeInfo::EnumeratorInfo & v) {s << v.name << " = " << v.value; return s;}
-
-inline PICout operator <<(PICout s, const PICodeInfo::ClassInfo & v) {
- s.setControl(0, true);
- s << "class " << v.name;
- if (!v.parents.isEmpty()) {
- s << ": ";
- bool first = true;
- piForeachC (PIString & i, v.parents) {
- if (first) first = false;
- else s << ", ";
- s << i;
- }
- }
- s << " {\n";
- piForeachC (FunctionInfo & i, v.functions) {
- s << Tab << i.return_type << " " << i.name << "(";
- bool fa = true;
- piForeachC (TypeInfo & a, i.arguments) {
- if (fa) fa = false;
- else s << ", ";
- s << a;
- }
- s << ");\n";
- }
- if (!v.functions.isEmpty() && !v.variables.isEmpty())
- s << "\n";
- piForeachC (TypeInfo & i, v.variables) {
- s << Tab << i << ";\n";
- }
- s << "}\n";
- s.restoreControl();
- return s;
-}
-
-inline PICout operator <<(PICout s, const PICodeInfo::EnumInfo & v) {
- s.setControl(0, true);
- s << "enum " << v.name << " {\n";
- piForeachC (EnumeratorInfo & i, v.members) {
- bool f = true;
- if (f) f = false;
- else s << ", ";
- s << Tab << i << "\n";
- }
- s << "}\n";
- s.restoreControl();
- return s;
-}
-
-extern PIMap * classesInfo;
-extern PIMap * enumsInfo;
-
-}
-
-class __PICodeInfoInitializer__ {
-public:
- __PICodeInfoInitializer__() {
- if (_inited_) return;
- _inited_ = true;
- PICodeInfo::classesInfo = new PIMap;
- PICodeInfo::enumsInfo = new PIMap;
- }
- static bool _inited_;
-};
-
-static __PICodeInfoInitializer__ __picodeinfoinitializer__;
-
-#endif // PICODEINFO_H
diff --git a/picodeparser.cpp b/picodeparser.cpp
deleted file mode 100644
index 04644f15..00000000
--- a/picodeparser.cpp
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
- PIP - Platform Independent Primitives
- C++ code parser
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#include "picodeparser.h"
-
-
-
-PIString PICodeParser::Macro::expand(const PIStringList & arg_vals, bool * ok) const {
- if (args.size() != arg_vals.size()) {
- piCout << ("Error: in expansion of macro \"" + name + "(" + args.join(", ") + ")\": expect")
- << args.size() << "arguments but takes" << arg_vals.size() << "!";
- if (ok != 0) *ok = false;
- return PIString();
- }
- PIString ret = value;
- for (int i = 0; i < args.size_s(); ++i) {
- const PIString & an(args[i]), av(arg_vals[i]);
- int ind(-1);
- while ((ind = ret.find(an, ind + 1)) >= 0) {
- PIChar ppc(0), pc(0), nc(0);
- if (ind > 1) ppc = ret[ind - 2];
- if (ind > 0) pc = ret[ind - 1];
- if (ind + an.size_s() < ret.size_s()) nc = ret[ind + an.size_s()];
- if (ppc != '#' && pc == '#' && !_isCChar(nc)) { // to chars
- ind--;
- ret.replace(ind, an.size_s() + 1, "\"" + av + "\"");
- ind -= an.size_s() - av.size_s() - 1;
- continue;
- }
- if (_isCChar(pc) || _isCChar(nc)) continue;
- ret.replace(ind, an.size_s(), av);
- ind -= an.size_s() - av.size_s();
- }
- }
- ret.replaceAll("##", "");
- if (ok != 0) *ok = true;
- return ret;
-}
-
-
-
-PICodeParser::PICodeParser() {
- macros_iter = 32;
- clear();
- includes << "";
-}
-
-
-void PICodeParser::parseFile(const PIString & file) {
- clear();
- parseFileInternal(file);
- /*piCout << "\n\nDefines:";
- piForeachC (Define & m, defines)
- piCout << "define" << m.first << m.second;
- piCout << "\n\nMacros:";
- piForeachC (Macro & m, macros)
- piCout << "Macro:" << m.name << m.args << m.value;
- piCout << "\n\nClasses:";
- piForeachC (Entity * c, entities)
- piCout << "class" << c->name << c->parents;
- piCout << "\n\nEnums:";
- piForeachC (Enum & c, enums)
- piCout << "enum" << c.name << c.members;
- piCout << "\n\nTypedefs:";
- piForeachC (Typedef & c, typedefs)
- piCout << "typedef" << c;*/
-}
-
-
-void PICodeParser::parseFiles(const PIStringList & files) {
- clear();
- piForeachC (PIString & f, files)
- parseFileInternal(f);
- /*piCout << "\n\nDefines:";
- piForeachC (Define & m, defines)
- piCout << "define" << m.first << m.second;
- piCout << "\n\nMacros:";
- piForeachC (Macro & m, macros)
- piCout << "Macro:" << m.name << m.args << m.value;
- piCout << "\n\nClasses:";
- piForeachC (Entity * c, entities)
- piCout << "class" << c->name << c->parents;
- piCout << "\n\nEnums:";
- piForeachC (Enum & c, enums)
- piCout << "enum" << c.name << c.members;
- piCout << "\n\nTypedefs:";
- piForeachC (Typedef & c, typedefs)
- piCout << "typedef" << c;*/
-}
-
-
-bool PICodeParser::isEnum(const PIString & name) {
- piForeachC (Enum & e, enums)
- if (e.name == name)
- return true;
- return false;
-}
-
-
-bool PICodeParser::parseFileInternal(const PIString & file) {
- if (proc_files[file]) return true;
- proc_files << file;
- cur_file = file;
- PIFile f(file, PIIODevice::ReadOnly);
- int ii = 0;
- while (!f.isOpened() && ii < (includes.size_s() - 1)) {
- f.setPath(includes[++ii] + "/" + file);
- //piCout << "try" << f.path();
- f.open(PIIODevice::ReadOnly);
- }
- if (!f.isOpened()) {
- //piCout << ("Error: can`t open file \"" + file + "\"!");
- return false;
- }
- PIString fc = f.readAll();
- piCout << "parsing" << f.path() << "...";
- bool ret = parseFileContent(fc);
- piCout << "parsing" << f.path() << "done";
- return ret;
-}
-
-
-void PICodeParser::clear() {
- piForeach (Entity * i, entities) delete i;
- defines.clear();
- macros.clear();
- enums.clear();
- typedefs.clear();
- entities.clear();
- proc_files.clear();
- cur_namespace.clear();
- evaluator.clearCustomVariables();
- defines << Define("PICODE", "") << custom_defines;
-}
-
-
-bool PICodeParser::parseFileContent(PIString & fc) {
- bool mlc = false, cc = false;
- int mls = 0, ole = -1, /*ccs = 0,*/ end = 0;
- char c = 0, pc = 0;
- PIString pfc, line, ccmn, tmp;
- PIMap cchars;
-
- /// Remove comments, join multiline "*" and replace "*" to $n (cchars)
- fc.replaceAll("\r\n", "\n");
- fc.replaceAll("\r", "\n");
- for (int i = 0; i < fc.size_s() - 1; ++i) {
- if (i > 0) pc = c;
- c = fc[i].toAscii();
- if (c == '"' && !mlc && pc != '\'') {
- if (i > 0) if (fc[i - 1] == '\\') continue;
- cc = !cc;
- /*if (cc) ccs = i;
- if (!cc) {
- ccmn = "$" + PIString::fromNumber(cchars.size());
- cchars[ccmn] = fc.mid(ccs, i - ccs + 1);
- fc.replace(ccs, i - ccs + 1, ccmn);
- i = ccs - 1 + ccmn.size_s();
- }*/
- continue;
- }
- if (i > 0)
- if (c == '\\' && fc[i - 1].toAscii() != '\\') {
- fc.cutMid(i, 2);
- --i;
- continue;
- }
- if (cc) continue;
- if (fc.mid(i, 2) == "/*") {mlc = true; mls = i; ++i; continue;}
- if (fc.mid(i, 2) == "*/" && mlc) {mlc = false; fc.cutMid(mls, i - mls + 2); i = mls - 1; continue;}
- if (fc.mid(i, 2) == "//" && !mlc) {ole = fc.find('\n', i); fc.cutMid(i, ole < 0 ? -1 : ole - i); --i; continue;}
- }
- //piCout << fc;
- pfc = procMacros(fc);
-
- bool replaced = true;
- int replaced_cnt = 0;
- while (replaced) {
- //piCout << "MACRO iter" << replaced_cnt;
- if (replaced_cnt >= macros_iter) {
- piCout << "Error: recursive macros detected!";
- break;//return false;
- }
- replaced_cnt++;
- replaced = false;
- piForeachC (Define & d, defines) {
- int ind(-1);
- while ((ind = pfc.find(d.first, ind + 1)) >= 0) {
- PIChar pc(0), nc(0);
- if (ind > 0) pc = pfc[ind - 1];
- if (ind + d.first.size_s() < pfc.size_s()) nc = pfc[ind + d.first.size_s()];
- if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue;
- pfc.replace(ind, d.first.size_s(), d.second);
- ind -= d.first.size_s() - d.second.size_s();
- replaced = true;
- }
- }
- piForeachC (Macro & m, macros) {
- int ind(-1);
- while ((ind = pfc.find(m.name, ind + 1)) >= 0) {
- PIChar pc(0), nc(0);
- if (ind > 0) pc = pfc[ind - 1];
- if (ind + m.name.size_s() < pfc.size_s()) nc = pfc[ind + m.name.size_s()];
- if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue;
- PIString ret, range; bool ok(false);
- range = pfc.mid(ind + m.name.size_s()).takeRange("(", ")");
- ret = m.expand(range.split(",").trim(), &ok);
- if (!ok) return false;
- int rlen = pfc.find(range, ind + m.name.size_s()) + range.size_s() + 1 - ind;
- pfc.replace(ind, rlen, ret);
- ind -= rlen - ret.size_s();
- replaced = true;
- }
- }
- }
-
- //piCout << NewLine << "file" << cur_file << pfc;
- for (int i = 0; i < pfc.size_s() - 5; ++i) {
- if (pfc.mid(i, 8) == "template") {
- pfc.cutLeft(i + 8);
- pfc.takeRange("<", ">");
- bool def = !isDeclaration(pfc, 0, &end);
- pfc.cutLeft(end);
- if (def) pfc.takeRange("{", "}");
- else pfc.takeSymbol();
- i = 0;
- continue;
- }
- if (pfc.mid(i, 5) == "class" || pfc.mid(i, 6) == "struct") {
- int dind = pfc.find("{", i), find = pfc.find(";", i);
- if (dind < 0 && find < 0) {pfc.cutLeft(i + 6); i = 0; continue;}
- if (dind < 0 || find < dind) {pfc.cutLeft(i + 6); i = 0; continue;}
- ccmn = pfc.mid(i, dind - i) + "{\n" + pfc.mid(dind).takeRange('{', '}') + "\n}\n";
- pfc.remove(i, ccmn.size());
- parseClass(ccmn);
- i = 0;
- continue;
- }
- if (pfc.mid(i, 4) == "enum") {
- pfc.cutLeft(i + 4);
- tmp = pfc.takeCWord();
- parseEnum(cur_namespace + tmp, pfc.takeRange("{", "}"));
- pfc.takeSymbol();
- i = 0;
- continue;
- }
- if (pfc.mid(i, 7) == "typedef") {
- pfc.cutLeft(i + 7);
- typedefs << parseTypedef(pfc.takeLeft(pfc.find(";")));
- if (typedefs.back().first.isEmpty()) typedefs.pop_back();
- pfc.takeSymbol();
- i = 0;
- continue;
- }
- }
-
- return true;
-}
-
-
-PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) {
- PIString cd = fc.trimmed().removeAll('\n').replaceAll("\t", " ").replaceAll(" ", " "), pn;
- //piCout << "found class <****\n" << cd << "\n****>";
- int ind = cd.find(":");
- PIVector parents;
- if (ind > 0) {
- PIStringList pl = cd.takeMid(ind + 1).trim().split(",");
- cd.cutRight(1);
- Entity * pe = 0;
- piForeachC (PIString & p, pl) {
- if (p.contains(" ")) pn = p.mid(p.find(" ") + 1);
- else pn = p;
- pe = findEntityByName(pn);
- if (pe == 0) ;//{piCout << "Error: can`t find" << pn;}
- else parents << pe;
- }
- }
- bool is_class = cd.left(5) == "class";
- cur_def_vis = (is_class ? Private : Public);
- PIString cn = cd.mid(6).trim();
- if (cn.isEmpty()) return 0;
- Entity * e = new Entity();
- e->name = cur_namespace + cn;
- e->type = (is_class ? "class" : "struct");
- e->parents = parents;
- e->file = cur_file;
- entities << e;
- return e;
-}
-
-
-PIString PICodeParser::parseClass(PIString & fc) {
- Visibility prev_vis = cur_def_vis;
- int dind = fc.find("{"), find = fc.find(";"), end = 0;
- if (dind < 0 && find < 0) return PIString();
- if (dind < 0 || find < dind) return fc.left(find);
- Entity * ce = parseClassDeclaration(fc.takeLeft(dind));
- fc.trim().cutLeft(1).cutRight(1).trim();
- //piCout << "found class <****\n" << fc << "\n****>";
- if (!ce) return PIString();
- int ps = -1;
- bool def = false;
- PIString prev_namespace = cur_namespace, stmp;
- cur_namespace = ce->name + "::";
- //piCout << "parse class" << ce->name << "namespace" << cur_namespace;
- //piCout << "\nparse class" << ce->name << "namespace" << cur_namespace;
- while (!fc.isEmpty()) {
- PIString cw = fc.takeCWord(), tmp;
- //piCout << "\ntaked word" << cw;
- if (cw == "public") {cur_def_vis = Public; fc.cutLeft(1); continue;}
- if (cw == "protected") {cur_def_vis = Protected; fc.cutLeft(1); continue;}
- if (cw == "private") {cur_def_vis = Private; fc.cutLeft(1); continue;}
- if (cw == "class") {if (isDeclaration(fc, 0, &end)) {fc.cutLeft(end); fc.takeSymbol(); continue;} tmp = fc.takeLeft(fc.find("{")); stmp = fc.takeRange("{", "}"); fc.takeSymbol(); stmp = "class " + tmp + "{" + stmp + "}"; parseClass(stmp); continue;}
- if (cw == "struct") {if (isDeclaration(fc, 0, &end)) {fc.cutLeft(end); fc.takeSymbol(); continue;} tmp = fc.takeLeft(fc.find("{")); stmp = fc.takeRange("{", "}"); fc.takeSymbol(); stmp = "struct " + tmp + "{" + stmp + "}"; parseClass(stmp); continue;}
- if (cw == "enum") {tmp = fc.takeCWord(); parseEnum(cur_namespace + tmp, fc.takeRange("{", "}")); fc.takeSymbol(); continue;}
- if (cw == "friend") {fc.cutLeft(fc.find(";") + 1); continue;}
- if (cw == "typedef") {ce->typedefs << parseTypedef(fc.takeLeft(fc.find(";"))); typedefs << ce->typedefs.back(); typedefs.back().first.insert(0, cur_namespace); if (ce->typedefs.back().first.isEmpty()) ce->typedefs.pop_back(); fc.takeSymbol(); continue;}
- if (cw == "template") {
- fc.takeRange("<", ">");
- def = !isDeclaration(fc, 0, &end);
- fc.cutLeft(end);
- if (def) fc.takeRange("{", "}");
- else fc.takeSymbol();
- continue;
- }
- def = !isDeclaration(fc, 0, &end);
- tmp = (cw + fc.takeLeft(end)).trim();
- if (!tmp.isEmpty())
- parseMember(ce, tmp);
- if (def) fc.takeRange("{", "}");
- else fc.takeSymbol();
- if (ps == fc.size_s()) {/*cur_namespace = prev_namespace;*/ fc.cutLeft(1);/*return false*/;}
- ps = fc.size_s();
- }
- cur_def_vis = prev_vis;
- cur_namespace = prev_namespace;
- return ce->name;
-}
-
-
-bool PICodeParser::parseEnum(const PIString & name, PIString fc) {
- //piCout << "enum" << name << fc;
- Enum e(name);
- PIStringList vl(fc.split(","));
- PIString vn;
- int cv = -1, ind = 0;
- piForeachC (PIString & v, vl) {
- vn = v; ind = v.find("=");
- if (ind > 0) {cv = v.right(v.size_s() - ind - 1).toInt(); vn = v.left(ind);}
- if (ind < 0) ++cv;
- e.members << Enumerator(vn.trim(), cv);
- }
- enums << e;
- return true;
-}
-
-
-PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) {
- //piCout << "parse typedef" << fc;
- Typedef td;
- fc.replaceAll("\t", " ");
-
- if (fc.contains("(")) {
- int start = fc.find("("), end = fc.find(")");
- td.first = fc.takeMid(start + 1, end - start - 1).trim();
- if (td.first.left(1) == "*") {td.first.cutLeft(1).trim(); fc.insert(start + 1, "*");}
- td.second = fc.trim();
- } else {
- td.first = fc.takeMid(fc.findLast(" ")).trim();
- td.second = fc.trim();
- }
- //piCout << "found typedef" << td;
- return td;
-}
-
-
-bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
- if (fc.trim().isEmpty()) return true;
- if (fc.find("operator") >= 0) return true;
- tmp_temp.clear();
- //piCout << "parse member" << fc;
- int ts = fc.find("<"), te = 0;
- PIString ctemp, crepl;
- while (ts >= 0) {
- ctemp = fc.mid(ts).takeRange("<", ">");
- if (ctemp.isEmpty()) {te = ts + 1; ts = fc.find("<", te); continue;}
- crepl = "$" + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, "0");
- fc.replace(ts, ctemp.size_s() + 2, crepl);
- tmp_temp[crepl] = "<" + ctemp + ">";
- ts = fc.find("<", te);
- }
- fc.replaceAll("\n", " ").replaceAll("\t", " ").replaceAll(" ", " ").replaceAll(", ", ",");
- PIStringList tl, al;
- Member me;
- //piCout << fc;
- if (fc.contains("(")) {
- fc.cutRight(fc.size_s() - fc.findLast(")") - 1);
- te = fc.find("(");
- //piCout << fc;
- for (ts = te - 1; ts >= 0; --ts)
- if (!_isCChar(fc[ts]) && !(fc[ts].isDigit())) break;
- //piCout << "takeMid" << ts + 1 << te - ts - 1;
- me.name = fc.takeMid(ts + 1, te - ts - 1);
- if (me.name == parent->name) return true;
- me.arguments_full = fc.takeMid(ts + 2).cutRight(1).split(",");
- me.type = fc.cutRight(1).trim();
- me.visibility = cur_def_vis;
- if (me.type.find("inline ") >= 0) {
- me.attributes |= Inline;
- me.type.removeAll("inline ");
- }
- if (me.type.find("static ") >= 0) {
- me.attributes |= Static;
- me.type.removeAll("static ");
- }
- if (me.type.find("virtual ") >= 0) {
- me.attributes |= Virtual;
- me.type.removeAll("virtual ");
- }
- normalizeEntityNamespace(me.type);
- int i = 0;
- piForeach (PIString & a, me.arguments_full)
- if ((i = a.find("=")) > 0)
- a.cutRight(a.size_s() - i).trim();
- me.arguments_type = me.arguments_full;
- piForeach (PIString & a, me.arguments_type) {
- crepl.clear();
- if (a.contains("["))
- crepl = a.takeMid(a.find("["), a.findLast("]") - a.find("[") + 1);
- for (ts = a.size_s() - 1; ts >= 0; --ts)
- if (!_isCChar(a[ts]) && !(a[ts].isDigit())) break;
- a.cutRight(a.size_s() - ts - 1);
- normalizeEntityNamespace(a);
- a += crepl;
- a.trim();
- }
- restoreTmpTemp(&me);
- //piCout << "func" << me.type << me.name << me.arguments_full << me.arguments_type;
- parent->functions << me;
- } else {
- tl = fc.split(",");
- bool vn = true;
- ctemp = tl.front();
- for (ts = ctemp.size_s() - 1; ts > 0; --ts) {
- if (vn) {if (!_isCChar(ctemp[ts]) && !ctemp[ts].isDigit() && ctemp[ts] != '[' && ctemp[ts] != ']') vn = false;}
- else {if (_isCChar(ctemp[ts]) || ctemp[ts].isDigit()) break;}
- }
- me.type = ctemp.takeLeft(ts + 1);
- me.visibility = cur_def_vis;
- restoreTmpTemp(&me);
- PIString type = " " + me.type;
- if (type.find(" const ") >= 0) {
- me.attributes |= Const;
- type.replaceAll(" const ", " ");
- }
- if (type.find(" static ") >= 0) {
- me.attributes |= Static;
- type.replaceAll(" static ", " ");
- }
- if (type.find(" mutable ") >= 0) {
- me.attributes |= Mutable;
- type.replaceAll(" mutable ", " ");
- }
- if (type.find(" volatile ") >= 0) {
- me.attributes |= Volatile;
- type.replaceAll(" volatile ", " ");
- }
- type.trim();
- normalizeEntityNamespace(type);
- tl[0] = ctemp.trim();
- piForeachC (PIString & v, tl) {
- crepl.clear();
- me.name = v.trimmed();
- me.type = type;
- if (me.name.isEmpty()) continue;
- if (me.name.contains("["))
- crepl = me.name.takeMid(me.name.find("["), me.name.findLast("]") - me.name.find("[") + 1);
- while (!me.name.isEmpty()) {
- if (me.name.front() == "*" || me.name.front() == "&") {
- me.type += me.name.takeLeft(1);
- me.name.trim();
- } else break;
- }
- me.is_type_ptr = (me.type.right(1) == "]" || me.type.right(1) == "*");
- me.type += crepl;
- //piCout << "var" << me.type << me.name << me.is_const << me.is_static;
- parent->members << me;
- }
- }
- //piCout << "parse member" << fc;
- return true;
-}
-
-
-void PICodeParser::normalizeEntityNamespace(PIString & n) {
- PIString suff, pref;
- for (int i = n.size_s() - 1; i > 0; --i)
- if (_isCChar(n[i]) || n[i].isDigit()) {
- suff = n.right(n.size_s() - i - 1);
- n.cutRight(suff.size_s());
- break;
- }
- n.push_front(" ");
- if (n.find(" static ") >= 0) {n.replaceAll(" static ", ""); pref += "static ";}
- if (n.find(" const ") >= 0) {n.replaceAll(" const ", ""); pref += "const ";}
- if (n.find(" mutable ") >= 0) {n.replaceAll(" mutable ", ""); pref += "mutable ";}
- if (n.find(" volatile ") >= 0) {n.replaceAll(" volatile ", ""); pref += "volatile ";}
- n.trim();
- int f = 0;
- piForeachC (Entity * e, entities) {
- if (e->name == n) {
- n = (pref + n + suff).trim();
- return;
- }
- if ((f = e->name.find(n)) >= 0)
- if (e->name.mid(f - 1, 1) == ":")
- if (e->name.find(cur_namespace) >= 0) {
- n = pref + e->name + suff;
- return;
- }
- }
- piForeachC (Enum & e, enums)
- if ((f = e.name.find(n)) >= 0)
- if (e.name.mid(f - 1, 1) == ":")
- if (e.name.find(cur_namespace) >= 0) {
- //piCout << "change" << n << "to" << e.name + suff;
- n = pref + e.name + suff;
- return;
- }
- piForeachC (Typedef & e, typedefs)
- if ((f = e.first.find(n)) >= 0)
- if (e.first.mid(f - 1, 1) == ":")
- if (e.first.find(cur_namespace) >= 0) {
- //piCout << "change" << n << "to" << e.name + suff;
- n = pref + e.first + suff;
- return;
- }
- n = (pref + n + suff).trim();
-}
-
-
-void PICodeParser::restoreTmpTemp(Member * e) {
- int i = 0;
- piForeach (PIString & a, e->arguments_full) {
- while ((i = a.find("$")) >= 0)
- a.replace(i, 4, tmp_temp[a.mid(i, 4)]);
- }
- piForeach (PIString & a, e->arguments_type) {
- while ((i = a.find("$")) >= 0)
- a.replace(i, 4, tmp_temp[a.mid(i, 4)]);
- }
- while ((i = e->type.find("$")) >= 0)
- e->type.replace(i, 4, tmp_temp[e->type.mid(i, 4)]);
-}
-
-
-bool PICodeParser::macroCondition(const PIString & mif, PIString mifcond) {
- //piCout << "macroCondition" << mif << mifcond;
- if (mif == "ifdef") return isDefineExists(mifcond);
- if (mif == "ifndef") return !isDefineExists(mifcond);
- if (mif == "if" || mif == "elif") {
- mifcond.removeAll(" ").removeAll("\t");
- return procMacrosCond(mifcond) > 0.;
- }
- return false;
-}
-
-
-double PICodeParser::procMacrosCond(PIString fc) {
- bool neg = false, first = true, br = false;
- double ret = 0., brv = 0.;
- int oper = 0, ps = -1;
- char cc, nc;
- PIString ce;
- fc.removeAll("defined");
- //piCout << "procMacrosCond" << fc;
- while (!fc.isEmpty()) {
- cc = fc[0].toAscii();
- nc = (fc.size() > 1 ? fc[1].toAscii() : 0);
- if (cc == '!') {neg = true; fc.pop_front(); continue;}
- if (cc == '(') {br = true; brv = procMacrosCond(fc.takeRange('(', ')'));}
- if (cc == '&' && nc == '&') {fc.remove(0, 2); oper = 1; continue;}
- if (cc == '|' && nc == '|') {fc.remove(0, 2); oper = 2; continue;}
- if (!br) {
- ce = fc.takeCWord();
- if (ce.isEmpty()) ce = fc.takeNumber();
- }
- if (first) {
- first = false;
- ret = br ? brv : defineValue(ce);
- if (neg) ret = -ret;
- } else {
- //piCout << "oper" << oper << "with" << ce;
- if (!br) brv = defineValue(ce);
- switch (oper) {
- case 1: ret = ret && (neg ? -brv : brv); break;
- case 2: ret = ret || (neg ? -brv : brv); break;
- }
- }
- if (ps == fc.size_s()) fc.cutLeft(1);
- ps = fc.size_s();
- br = neg = false;
- }
- //piCout << "return" << ret;
- return ret;
-}
-
-
-bool PICodeParser::isDefineExists(const PIString & dn) {
- piForeachC (Define & d, defines) {
- if (d.first == dn)
- return true;
- }
- return false;
-}
-
-
-double PICodeParser::defineValue(const PIString & dn) {
- piForeachC (Define & d, defines) {
- if (d.first == dn)
- return d.second.isEmpty() ? 1. : d.second.toDouble();
- }
- return dn.toDouble();
-}
-
-
-PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) {
- piForeach (Entity * e, entities)
- if (e->name == en)
- return e;
- return 0;
-}
-
-
-bool PICodeParser::isDeclaration(const PIString & fc, int start, int * end) {
- int dind = fc.find("{", start), find = fc.find(";", start);
- //piCout << "isDeclaration" << dind << find;
- if (dind < 0 && find < 0) {if (end) *end = -1; return true;}
- if (dind < 0 || find < dind) {if (end) *end = find; return true;}
- if (end) *end = dind;
- return false;
-}
-
-
-PIString PICodeParser::procMacros(PIString fc) {
- if (fc.isEmpty()) return PIString();
- int ifcnt = 0;
- bool grab = false, skip = false, cond_ok = false;
- PIString pfc, nfc, line, mif, mifcond;
- //piCout << "procMacros\n<******" << fc << "\n******>";
- fc += "\n";
- while (!fc.isEmpty()) {
- line = fc.takeLine().trimmed();
- if (line.left(1) == "#") {
- mifcond = line.mid(1);
- mif = mifcond.takeCWord();
- //piCout << "mif mifcond" << mif << mifcond << ifcnt;
- if (skip || grab) {
- if (mif.left(2) == "if") ifcnt++;
- if (mif.left(5) == "endif") {
- if (ifcnt > 0) ifcnt--;
- else {
- //piCout << "main endif" << skip << grab;
- if (grab) pfc << procMacros(nfc);
- skip = grab = false;
- continue;
- }
- }
- if (mif.left(4) == "elif" && ifcnt == 0) {
- //piCout << "main elif" << skip << grab << cond_ok;
- if (cond_ok) {
- if (grab) {
- pfc << procMacros(nfc);
- skip = true; grab = false;
- }
- continue;
- }
- if (skip) {
- //piCout << "check elif" << skip << grab << cond_ok;
- if (!macroCondition(mif, mifcond.trimmed())) continue;
- //piCout << "check elif ok";
- skip = false; grab = cond_ok = true;
- continue;
- }
- continue;
- }
- if (mif.left(4) == "else" && ifcnt == 0) {
- //piCout << "main else" << skip << grab;
- if (grab) pfc << procMacros(nfc);
- if (skip && !cond_ok) {skip = false; grab = true;}
- else {skip = true; grab = false;}
- continue;
- }
- if (grab) nfc << line << "\n";
- continue;
- }
- if (mif.left(2) == "if") {
- //piCout << "main if";
- skip = grab = cond_ok = false;
- if (macroCondition(mif, mifcond.trimmed())) grab = cond_ok = true;
- else skip = true;
- ifcnt = 0;
- nfc.clear();
- } else {
- if (!parseDirective(line.cutLeft(1).trim()))
- ;//return false; /// WARNING
- }
- } else {
- if (grab) nfc << line << "\n";
- else if (!skip) pfc << line << "\n";
- }
- }
- return pfc;
-}
-
-
-bool PICodeParser::parseDirective(PIString d) {
- if (d.isEmpty()) return true;
- PIString dname = d.takeCWord();
- //piCout << "parseDirective" << d;
- if (dname == "include") {
- d.replaceAll("<", "\"").replaceAll(">", "\"");
- PIString cf = cur_file;
- bool ret = parseFileInternal(d.takeRange("\"", "\""));
- cur_file = cf;
- return ret;
- }
- if (dname == "define") {
- PIString mname = d.takeCWord();
- if (d.left(1) == "(") { // macro
- PIStringList args = d.takeRange("(", ")").split(",").trim();
- macros << Macro(mname, d.trim(), args);
- } else { // define
- defines << Define(mname, d.trim());
- evaluator.setVariable(mname, complexd_1);
- }
- return true;
- }
- if (dname == "undef") {
- PIString mname = d.takeCWord();
- for (int i = 0; i < defines.size_s(); ++i)
- if (defines[i].first == mname) {defines.remove(i); --i;}
- return true;
- }
- return true;
-}
diff --git a/picodeparser.h b/picodeparser.h
deleted file mode 100644
index 9ed6b1cd..00000000
--- a/picodeparser.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*! \file picodeparser.h
- * \brief C++ code parser
-*/
-/*
- PIP - Platform Independent Primitives
- C++ code parser
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-
-#ifndef PICODEPARSER_H
-#define PICODEPARSER_H
-
-#include "pifile.h"
-#include "pievaluator.h"
-
-inline bool _isCChar(const PIChar & c) {return (c.isAlpha() || (c.toAscii() == '_'));}
-inline bool _isCChar(const PIString & c) {if (c.isEmpty()) return false; return _isCChar(c[0]);}
-
-class PIP_EXPORT PICodeParser {
-public:
- PICodeParser();
-
- enum PIP_EXPORT Visibility {Global, Public, Protected, Private};
- enum PIP_EXPORT Attribute {NoAttributes = 0x0, Const = 0x01, Static = 0x02, Mutable = 0x04, Volatile = 0x08, Inline = 0x10, Virtual = 0x20};
-
- typedef PIFlags Attributes;
- typedef PIPair Define;
- typedef PIPair Typedef;
- typedef PIPair Enumerator;
-
- struct PIP_EXPORT Macro {
- Macro(const PIString & n = PIString(), const PIString & v = PIString(), const PIStringList & a = PIStringList()) {
- name = n;
- value = v;
- args = a;
- }
- PIString expand(const PIStringList & arg_vals, bool * ok = 0) const;
- PIString name;
- PIString value;
- PIStringList args;
- };
-
- struct PIP_EXPORT Member {
- Member() {
- visibility = Global;
- size = 0;
- is_type_ptr = false;
- attributes = NoAttributes;
- }
- PIString type;
- PIString name;
- PIStringList arguments_full;
- PIStringList arguments_type;
- Visibility visibility;
- Attributes attributes;
- bool is_type_ptr;
- int size;
- };
-
- struct PIP_EXPORT Entity {
- Entity() {
- visibility = Global;
- size = 0;
- }
- PIString type;
- PIString name;
- PIString file;
- Visibility visibility;
- int size;
- PIVector parents;
- //PIVector children;
- PIVector functions;
- PIVector members;
- PIVector typedefs;
- };
-
- struct PIP_EXPORT Enum {
- Enum(const PIString & n = PIString()) {
- name = n;
- }
- PIString name;
- PIVector members;
- };
-
- void parseFile(const PIString & file);
- void parseFiles(const PIStringList & files);
-
- void includeDirectory(const PIString & dir) {includes << dir;}
- void addDefine(const PIString & def_name, const PIString & def_value) {custom_defines << Define(def_name, def_value);}
- bool isEnum(const PIString & name);
- Entity * findEntityByName(const PIString & en);
-
- int macrosSubstitutionMaxIterations() const {return macros_iter;}
- void setMacrosSubstitutionMaxIterations(int value) {macros_iter = value;}
-
- PIVector defines, custom_defines;
- PIVector macros;
- PIVector enums;
- PIVector typedefs;
- PIVector entities;
-
-private:
- void clear();
- bool parseFileInternal(const PIString & file);
- bool parseFileContent(PIString & fc);
- bool parseDirective(PIString d);
- Entity * parseClassDeclaration(const PIString & fc);
- PIString parseClass(PIString & fc);
- bool parseEnum(const PIString & name, PIString fc);
- Typedef parseTypedef(PIString fc);
- bool parseMember(Entity * parent, PIString & fc);
- void restoreTmpTemp(Member * e);
- bool macroCondition(const PIString & mif, PIString mifcond);
- bool isDefineExists(const PIString & dn);
- double defineValue(const PIString & dn);
- PIString procMacros(PIString fc);
- double procMacrosCond(PIString fc);
- bool isDeclaration(const PIString & fc, int start, int * end);
- void normalizeEntityNamespace(PIString & n);
-
- int macros_iter;
- PIEvaluator evaluator;
- //PIVector tree;
- PISet proc_files;
- PIString cur_file;
- PIStringList includes;
- Entity root_;
- Visibility cur_def_vis;
- PIString cur_namespace;
- PIMap tmp_temp;
-
-};
-
-#endif // PICODEPARSER_H
diff --git a/picollection.cpp b/picollection.cpp
deleted file mode 100644
index ad64b690..00000000
--- a/picollection.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#include "picollection.h"
-
-
-/** \class PICollection
- * \brief Interface to discover element groups
- * \details
- * \section PICollection_sec0 Synopsis
- * This class has only static functions so no need to create instance of the
- * %PICollection. This class provide macros to add some classes or existing
- * objects to global collection and access to them from any place of the code.
- * \snippet picollection.cpp main
- * */
-
-
-PIStringList PICollection::groups() {
- PIStringList sl;
- piForeachC (Group & g, *_groups)
- sl << g.name;
- return sl;
-}
-
-
-PIVector PICollection::groupElements(const PIString & group) {
- piForeachC (Group & g, *_groups)
- if (g.name == group)
- return g.elements;
- return PIVector();
-}
-
-
-void PICollection::addToGroup(const PIString & group, const PIObject * element) {
- //piCout << "add to" << group << element;
- PIString n = element->className();
- piForeach (Group & g, *_groups)
- if (g.name == group) {
- for (int i = 0; i < g.elements.size_s(); ++i)
- if (PIString(g.elements[i]->className()) == n)
- return;
- g.elements << element;
- //piCout << "new group" << group << ", ok";
- return;
- }
- *_groups << Group(group);
- _groups->back().elements << element;
- //piCout << "new group" << group << ", ok";
-}
-
-bool __PICollectionInitializer::_inited_(false);
-PIVector * PICollection::_groups;
diff --git a/picollection.h b/picollection.h
deleted file mode 100644
index b9f0488e..00000000
--- a/picollection.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*! \file picollection.h
- * \brief Custom elements collection
-*/
-/*
- PIP - Platform Independent Primitives
- Peer - named I/O ethernet node, forming self-organized peering network
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#ifndef PICOLLECTION_H
-#define PICOLLECTION_H
-
-#include "piobject.h"
-
-#ifdef DOXYGEN
-
-/** \brief Add existing element "object" in group with name "group"
- * \relatesalso PICollection
- * \details If there is no group with name "group" it will be created.
- * Only one element of the class "object" can be in group "group". If
- * this is already exists nothing be happens. \n "object" should to
- * be pointer to object based on PIObject. */
-# define ADD_TO_COLLECTION(group, object)
-
-/** \brief Add new element of class "class" in group with name "group"
- * \relatesalso PICollection
- * \details If there is no group with name "group" it will be created.
- * Only one element of the class "class" can be in group "group". If
- * this is already exists nothing be happens. \n "class" should to
- * be name of the any class based on PIObject. */
-# define ADD_NEW_TO_COLLECTION(group, class)
-
-#else
-# define ADD_TO_COLLECTION(group, object) static PICollection::CollectionAdder __##group##_##__LINE__##_##adder##__(#group, object);
-# define ADD_NEW_TO_COLLECTION(group, class) static PICollection::CollectionAdder __##group##_##class##_##adder##__(#group, new class());
-#endif
-
-class PIP_EXPORT PICollection
-{
- friend class __PICollectionInitializer;
-public:
- PICollection() {;}
-
- //! \brief Returns all existing groups by their names
- static PIStringList groups();
-
- //! \brief Returns all elements of group "group"
- static PIVector groupElements(const PIString & group);
-
- static void addToGroup(const PIString & group, const PIObject * element);
-
- class CollectionAdder {
- public:
- CollectionAdder(const PIString & group, const PIObject * element) {PICollection::addToGroup(group, element);}
- };
-
-protected:
- struct Group {
- Group(const PIString & name_ = PIString()) {name = name_;}
- //~Group() {piCout << "delete group" << name << this; piForeach (const PIObject * o, elements) delete o; elements.clear();}
- PIString name;
- PIVector elements;
- };
-
- static PIVector * _groups;
-
-};
-
-class PIP_EXPORT __PICollectionInitializer {
-public:
- __PICollectionInitializer() {
- if (_inited_) return;
- _inited_ = true;
- PICollection::_groups = new PIVector();
- }
- static bool _inited_;
-};
-
-static __PICollectionInitializer __picollectioninitializer;
-
-#endif // PICOLLECTION_H
diff --git a/piconfig.cpp b/piconfig.cpp
deleted file mode 100644
index 15cd1d48..00000000
--- a/piconfig.cpp
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- PIP - Platform Independent Primitives
- Config parser
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#include "piconfig.h"
-
-/*! \class PIConfig
- * \brief Configuration file
- * \details This class provide handle access to configuration file.
- *
- * \section PIConfig_sec0 Synopsis
- * PIConfig reads configuration file and create internal dendritic
- * representation of all entries of this file. You can easily read
- * some values and write new.
- * \image html piconfig.png
- *
- * %PIConfig supports also INI-style files with sections "[section]".
- * In this case line with section name interpret as prefix to the next
- * lines. For example, these configs are equal:
- * \code
- * ser.device = /dev/ttyS0
- * ser.speed = 115200
- * debug = true
- * \endcode
- * \code
- * [ser]
- * device = /dev/ttyS0
- * speed = 115200
- * []
- * debug = true
- * \endcode
- *
- * \section PIConfig_sec1 Concepts
- * Each node of internal tree has type PIConfig::Entry. %PIConfig
- * has one root element \a rootEntry(). Any entry of configuration file is a
- * child of this element.
- *
- */
-
-/*! \class PIConfig::Entry
- * \brief %Entry of configuration file
- * \details This class is node of internal PIConfig tree.
- * %Entry provide access to elements of PIConfig. Each entry has
- * children or next properties:
- * * name
- * * value
- * * type
- * * comment
- *
- * Each property is a PIString. These properties forms from text line with
- * format: \code{.cpp} = # \endcode
- * Type and comment are optional fields. Type is a single letter immediately
- * after comment symbol "#". \n \n
- * %Entry has many implicit convertions to common types: boolean, integers,
- * float, double, PIString, PIStringList. \n \n
- * Generally there is no need to create instance of %PIConfig::Entry manually,
- * it returns by functions \a getValue() of \a PIConfig, \a PIConfig::Entry or
- * \a PIConfig::Branch. If there is no suitable entry to return, reference to
- * internal instance of %PIConfig::Entry with "default" value will be returned.
- * \snippet piconfig.cpp PIConfig::Entry
- *
-*/
-
-/*! \class PIConfig::Branch
- * \brief %Branch is a list of entries of configuration file
- * \details %Branch provides some features to get entries lists.
- * \snippet piconfig.cpp PIConfig::Branch
- *
-*/
-
-
-PIConfig::Entry PIConfig::Branch::_empty;
-PIConfig::Entry PIConfig::Entry::_empty;
-
-
-PIConfig::Branch PIConfig::Branch::allLeaves() {
- Branch b;
- b.delim = delim;
- piForeach (Entry * i, *this) {
- if (i->isLeaf()) b << i;
- else allLeaves(b, i);
- }
- return b;
-}
-
-
-PIConfig::Entry & PIConfig::Branch::getValue(const PIString & vname, const PIString & def, bool * exist) {
- if (vname.isEmpty()) {
- _empty.clear();
- _empty.delim = delim;
- if (exist != 0) *exist = false;
- return _empty;
- }
- PIStringList tree = vname.split(delim);
- PIString name = tree.front();
- tree.pop_front();
- Entry * ce = 0;
- piForeach (Entry * i, *this)
- if (i->_name == name) {
- ce = i;
- break;
- }
- if (ce == 0) {
- _empty._name = vname;
- _empty._value = def;
- _empty.delim = delim;
- if (exist != 0) *exist = false;
- return _empty;
- }
- piForeach (PIString & i, tree) {
- ce = ce->findChild(i);
- if (ce == 0) {
- _empty._name = vname;
- _empty._value = def;
- _empty.delim = delim;
- if (exist != 0) *exist = false;
- return _empty;
- }
- }
- if (exist != 0) *exist = true;
- return *ce;
-}
-
-
-PIConfig::Branch PIConfig::Branch::getValues(const PIString & name) {
- Branch b;
- b.delim = delim;
- piForeach (Entry * i, *this) {
- if (i->isLeaf()) {
- if (i->_name.find(name) >= 0)
- b << i;
- } else {
- piForeach (Entry * j, i->_children)
- if (j->_name.find(name) >= 0)
- b << j;
- }
- }
- return b;
-}
-
-
-PIConfig::Branch PIConfig::Branch::getLeaves() {
- Branch b;
- b.delim = delim;
- piForeach (Entry * i, *this)
- if (i->isLeaf())
- b << i;
- return b;
-}
-
-
-PIConfig::Branch PIConfig::Branch::getBranches() {
- Branch b;
- b.delim = delim;
- piForeach (Entry * i, *this)
- if (!i->isLeaf())
- b << i;
- return b;
-}
-
-
-PIConfig::Branch & PIConfig::Branch::filter(const PIString & f) {
- for (int i = 0; i < size_s(); ++i) {
- if (at(i)->_name.find(f) < 0) {
- remove(i);
- --i;
- }
- }
- return *this;
-}
-
-
-bool PIConfig::Branch::entryExists(const Entry * e, const PIString & name) const {
- if (e->_children.isEmpty()) {
- if (e->_name == name) return true;
- else return false;
- }
- piForeachC (Entry * i, e->_children)
- if (entryExists(i, name)) return true;
- return false;
-}
-
-
-PIConfig::Entry & PIConfig::Entry::getValue(const PIString & vname, const PIString & def, bool * exist) {
- PIStringList tree = vname.split(delim);
- Entry * ce = this;
- piForeach (PIString & i, tree) {
- ce = ce->findChild(i);
- if (ce == 0) {
- _empty._name = vname;
- _empty._value = def;
- _empty.delim = delim;
- if (exist != 0) *exist = false;
- return _empty;
- }
- }
- if (exist != 0) *exist = true;
- return *ce;
-}
-
-
-PIConfig::Branch PIConfig::Entry::getValues(const PIString & vname) {
- Branch b;
- b.delim = delim;
- piForeach (Entry * i, _children)
- if (i->_name.find(vname) >= 0)
- b << i;
- return b;
-};
-
-
-bool PIConfig::Entry::entryExists(const Entry * e, const PIString & name) const {
- if (e->_children.isEmpty()) {
- if (e->_name == name) return true;
- else return false;
- }
- piForeachC (Entry * i, e->_children)
- if (entryExists(i, name)) return true;
- return false;
-}
-
-
-PIConfig::PIConfig(const PIString & path, PIIODevice::DeviceMode mode): PIFile(path, mode) {
- delim = ".";
- root.delim = delim;
- empty.delim = delim;
- empty._parent = 0;
- if (!isOpened())
- open(path, mode);
- parse();
-}
-
-
-PIConfig::Entry & PIConfig::getValue(const PIString & vname, const PIString & def, bool * exist) {
- PIStringList tree = vname.split(delim);
- Entry * ce = &root;
- piForeach (PIString & i, tree) {
- ce = ce->findChild(i);
- if (ce == 0) {
- if (exist != 0) *exist = false;
- empty._name = vname;
- empty._value = def;
- empty.delim = delim;
- return empty;
- }
- }
- if (exist != 0) *exist = true;
- return *ce;
-}
-
-
-PIConfig::Branch PIConfig::getValues(const PIString & vname) {
- Branch b;
- b.delim = delim;
- piForeach (Entry * i, root._children)
- if (i->_name.find(vname) >= 0)
- b << i;
- return b;
-};
-
-
-void PIConfig::addEntry(const PIString & name, const PIString & value, const PIString & type, bool write) {
- if (getValue(name)._parent != 0)
- return;
- bool toRoot = false;
- PIStringList tree = name.split(delim);
- PIString ename = tree.back();
- tree.pop_back();
- Entry * te, * ce, * entry = &root;
- if (tree.isEmpty()) toRoot = true;
- piForeach (PIString & i, tree) {
- te = entry->findChild(i);
- if (te == 0) {
- ce = new Entry();
- ce->delim = delim;
- ce->_tab = entry->_tab;
- ce->_line = entry->_line;
- ce->_name = i;
- ce->_parent = entry;
- entry->_children << ce;
- entry = ce;
- } else entry = te;
- }
- PIConfig::Branch ch = entry->_children;
- ch.sort(PIConfig::Entry::compare);
- te = (entry->isLeaf() ? 0 : ch.back());
- ce = new Entry();
- ce->delim = delim;
- ce->_name = ename;
- ce->_value = value;
- ce->_type = type;
- if (te == 0) {
- ce->_tab = entry->_tab;
- if (toRoot) ce->_line = other.size_s() - 1;
- else ce->_line = entry->_line;
- } else {
- ce->_tab = te->_tab;
- if (toRoot) ce->_line = other.size_s() - 1;
- else {
- ch = entry->_parent->_children;
- ch.sort(PIConfig::Entry::compare);
- ce->_line = ch.back()->_line + 1;
- }
- }
- ce->_parent = entry;
- entry->_children << ce;
- other.insert(ce->_line, "");
- Branch b = allLeaves();
- bool found = false;
- for (int i = 0; i < b.size_s(); ++i) {
- if (found) {
- b[i]->_line++;
- continue;
- }
- if (b[i] == ce) {
- found = true;
- if (i > 0)
- if (b[i - 1]->_line == b[i]->_line)
- b[i - 1]->_line++;
- }
- }
- if (write) writeAll();
-}
-
-
-void PIConfig::setValue(const PIString & name, const PIString & value, const PIString & type, bool write) {
- Entry & e(getValue(name));
- if (&e == &empty) {
- addEntry(name, value, type, write);
- return;
- }
- e._value = value;
- e._type = type;
- if (write) writeAll();
-}
-
-
-int PIConfig::entryIndex(const PIString & name) {
- PIStringList tree = name.split(delim);
- Entry * ce = &root;
- piForeach (PIString & i, tree) {
- ce = ce->findChild(i);
- if (ce == 0)
- return -1;
- }
- Branch b = allLeaves();
- return allLeaves().indexOf(ce);
-}
-
-
-void PIConfig::setValue(uint number, const PIString & value, bool write) {
- Entry & e(entryByIndex(number));
- if (&e == &empty) return;
- e._value = value;
- if (write) writeAll();
-}
-
-
-void PIConfig::setName(uint number, const PIString & name, bool write) {
- Entry & e(entryByIndex(number));
- if (&e == &empty) return;
- e._name = name;
- if (write) writeAll();
-}
-
-
-void PIConfig::setType(uint number, const PIString & type, bool write) {
- Entry & e(entryByIndex(number));
- if (&e == &empty) return;
- e._type = type;
- if (write) writeAll();
-}
-
-
-void PIConfig::setComment(uint number, const PIString & comment, bool write) {
- Entry & e(entryByIndex(number));
- if (&e == &empty) return;
- e._comment = comment;
- if (write) writeAll();
-}
-
-
-void PIConfig::removeEntry(const PIString & name, bool write) {
- Entry & e(getValue(name));
- if (&e == &empty) return;
- Branch b = allLeaves();
- removeEntry(b, &e);
- if (write) writeAll();
-}
-
-
-void PIConfig::removeEntry(uint number, bool write) {
- Entry & e(entryByIndex(number));
- if (&e == &empty) return;
- Branch b = allLeaves();
- removeEntry(b, &e);
- if (write) writeAll();
-}
-
-
-void PIConfig::removeEntry(Branch & b, PIConfig::Entry * e) {
- bool leaf = true;
- if (e->isLeaf()) other.remove(e->_line);
- if (!e->isLeaf() && !e->_value.isEmpty()) {
- e->_value.clear();
- leaf = false;
- } else {
- int cc = e->_children.size_s();
- piForTimes (cc)
- removeEntry(b, e->_children.back());
- }
- bool found = false;
- for (int i = 0; i < b.size_s(); ++i) {
- if (found) {
- b[i]->_line--;
- continue;
- }
- if (b[i] == e) found = true;
- }
- if (!leaf) return;
- e->_parent->_children.removeOne(e);
- b.removeOne(e);
- delete e;
-}
-
-
-PIString PIConfig::getPrefixFromLine(PIString line, bool * exists) {
- line.trim();
- if (line.left(1) == "#") {if (exists) *exists = false; return PIString();}
- int ci = line.find("#");
- if (ci >= 0) line.cutRight(line.size() - ci);
- if (line.find("=") >= 0) {if (exists) *exists = false; return PIString();}
- if (line.find("[") >= 0 && line.find("]") >= 0) {
- if (exists) *exists = true;
- return line.takeRange('[', ']').trim();
- }
- if (exists) *exists = false;
- return PIString();
-}
-
-
-void PIConfig::writeAll() {
- //cout << this << " write < " << size() << endl;
- PIFile::clear();
- //*this << "1234567894132456798\n"; return;
- //writeEntry(&root);
- buildFullNames(&root);
- Branch b = allLeaves();
- PIString prefix, tprefix;
- bool isPrefix;
- //for (int i = 0; i < b.size_s(); ++i)
- // cout << b[i]->_name << " = " << b[i]->_value << endl;
- int j = 0;
- for (int i = 0; i < other.size_s(); ++i) {
- //cout << j << endl;
- if (j >= 0 && j < b.size_s()) {
- if (b[j]->_line == i) {
- b[j]->buildLine();
- *this << (b[j]->_all).cutLeft(prefix.size()) << '\n';
- //cout << this << " " << b[j]->_all << endl;
- ++j;
- } else {
- *this << other[i];
- tprefix = getPrefixFromLine(other[i], &isPrefix);
- if (isPrefix) {
- prefix = tprefix;
- if (!prefix.isEmpty())
- prefix += delim;
- }
- if (i < other.size_s() - 1) *this << '\n';
- //cout << this << " " << other[i] << endl;
- }
- } else {
- *this << other[i];
- tprefix = getPrefixFromLine(other[i], &isPrefix);
- if (isPrefix) {
- prefix = tprefix;
- if (!prefix.isEmpty())
- prefix += delim;
- }
- if (i < other.size_s() - 1) *this << '\n';
- //cout << this << " " << other[i] << endl;
- }
- }
- flush();
- readAll();
- //cout << this << " write > " << size() << endl;
-}
-
-
-void PIConfig::readAll() {
- root.deleteBranch();
- root.clear();
- parse();
-}
-
-
-bool PIConfig::entryExists(const Entry * e, const PIString & name) const {
- if (e->_children.isEmpty()) {
- if (e->_name == name) return true;
- else return false;
- }
- piForeachC (Entry * i, e->_children)
- if (entryExists(i, name)) return true;
- return false;
-}
-
-
-void PIConfig::parse() {
- PIString src, str, tab, comm, all, name, type, prefix, tprefix;
- PIStringList tree;
- Entry * entry, * te, * ce;
- int ind, sind;
- bool isNew, isPrefix;
- if (!isOpened()) return;
- seekToBegin();
- other.clear();
- lines = centry = 0;
- while (!isEnd()) {
- other.push_back(PIString());
- src = str = readLine();
- tprefix = getPrefixFromLine(src, &isPrefix);
- if (isPrefix) {
- prefix = tprefix;
- if (!prefix.isEmpty())
- prefix += delim;
- }
- tab = str.left(str.find(str.trimmed().left(1)));
- str.trim();
- //cout << endl << str << endl << endl;
- all = str;
- ind = str.find('=');
- if ((ind > 0) && !(str[0] == '#')) {
- sind = str.find('#');
- if (sind > 0) {
- comm = str.right(str.length() - sind - 1).trimmed();
- if (comm.length() > 0) type = comm[0];
- else type = "s";
- comm = comm.right(comm.length() - 1).trimmed();
- str = str.left(sind);
- } else {
- type = "s";
- comm = "";
- }
- //name = str.left(ind).trimmed();
- tree = (prefix + str.left(ind).trimmed()).split(delim);
- name = tree.back();
- tree.pop_back();
- entry = &root;
- piForeachC (PIString & i, tree) {
- te = entry->findChild(i);
- if (te == 0) {
- ce = new Entry();
- ce->delim = delim;
- ce->_tab = tab;
- ce->_line = lines;
- ce->_name = i;
- ce->_parent = entry;
- entry->_children << ce;
- entry = ce;
- } else entry = te;
- }
- isNew = false;
- ce = entry->findChild(name);
- if (ce == 0) {
- ce = new Entry();
- isNew = true;
- }
- ce->delim = delim;
- ce->_tab = tab;
- ce->_name = name;
- ce->_value = str.right(str.length() - ind - 1).trimmed();
- ce->_type = type;
- ce->_comment = comm;
- ce->_line = lines;
- ce->_all = all;
- if (isNew) {
- ce->_parent = entry;
- entry->_children << ce;
- }
- } else other.back() = src;
- lines++;
- }
- setEntryDelim(&root, delim);
- buildFullNames(&root);
-}
diff --git a/piconfig.h b/piconfig.h
deleted file mode 100644
index 951bbd6a..00000000
--- a/piconfig.h
+++ /dev/null
@@ -1,502 +0,0 @@
-/*! \file piconfig.h
- * \brief Configuration file
-*/
-/*
- PIP - Platform Independent Primitives
- Config parser
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#ifndef PICONFIG_H
-#define PICONFIG_H
-
-#include "pifile.h"
-
-#define PICONFIG_GET_VALUE \
- Entry & getValue(const PIString & vname, const char * def, bool * exists = 0) {return getValue(vname, PIString(def), exists);} \
- Entry & getValue(const PIString & vname, const PIStringList & def, bool * exists = 0) {return getValue(vname, def.join("%|%"), exists);} \
- Entry & getValue(const PIString & vname, const bool def, bool * exists = 0) {return getValue(vname, PIString::fromBool(def), exists);} \
- Entry & getValue(const PIString & vname, const short def, bool * exists = 0) {return getValue(vname, itos(def), exists);} \
- Entry & getValue(const PIString & vname, const int def, bool * exists = 0) {return getValue(vname, itos(def), exists);} \
- Entry & getValue(const PIString & vname, const long def, bool * exists = 0) {return getValue(vname, ltos(def), exists);} \
- Entry & getValue(const PIString & vname, const uchar def, bool * exists = 0) {return getValue(vname, uitos(def), exists);} \
- Entry & getValue(const PIString & vname, const ushort def, bool * exists = 0) {return getValue(vname, uitos(def), exists);} \
- Entry & getValue(const PIString & vname, const uint def, bool * exists = 0) {return getValue(vname, uitos(def), exists);} \
- Entry & getValue(const PIString & vname, const ulong def, bool * exists = 0) {return getValue(vname, ultos(def), exists);} \
- Entry & getValue(const PIString & vname, const float def, bool * exists = 0) {return getValue(vname, ftos(def), exists);} \
- Entry & getValue(const PIString & vname, const double def, bool * exists = 0) {return getValue(vname, dtos(def), exists);} \
- \
- Entry & getValue(const PIString & vname, const char * def, bool * exists = 0) const {return getValue(vname, PIString(def), exists);} \
- Entry & getValue(const PIString & vname, const PIStringList & def, bool * exists = 0) const {return getValue(vname, def.join("%|%"), exists);} \
- Entry & getValue(const PIString & vname, const bool def, bool * exists = 0) const {return getValue(vname, PIString::fromBool(def), exists);} \
- Entry & getValue(const PIString & vname, const short def, bool * exists = 0) const {return getValue(vname, itos(def), exists);} \
- Entry & getValue(const PIString & vname, const int def, bool * exists = 0) const {return getValue(vname, itos(def), exists);} \
- Entry & getValue(const PIString & vname, const long def, bool * exists = 0) const {return getValue(vname, ltos(def), exists);} \
- Entry & getValue(const PIString & vname, const uchar def, bool * exists = 0) const {return getValue(vname, uitos(def), exists);} \
- Entry & getValue(const PIString & vname, const ushort def, bool * exists = 0) const {return getValue(vname, uitos(def), exists);} \
- Entry & getValue(const PIString & vname, const uint def, bool * exists = 0) const {return getValue(vname, uitos(def), exists);} \
- Entry & getValue(const PIString & vname, const ulong def, bool * exists = 0) const {return getValue(vname, ultos(def), exists);} \
- Entry & getValue(const PIString & vname, const float def, bool * exists = 0) const {return getValue(vname, ftos(def), exists);} \
- Entry & getValue(const PIString & vname, const double def, bool * exists = 0) const {return getValue(vname, dtos(def), exists);}
-
-class PIP_EXPORT PIConfig: public PIFile
-{
- friend class Entry;
- friend class Branch;
-public:
-
- //! Contructs and read configuration file at path "path" in mode "mode"
- PIConfig(const PIString & path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
-
- ~PIConfig() {root.deleteBranch(); close();}
-
- class Entry;
-
-
- class PIP_EXPORT Branch: public PIVector {
- friend class PIConfig;
- friend class Entry;
- friend std::ostream & operator <<(std::ostream & s, const Branch & v);
- friend PICout operator <<(PICout s, const Branch & v);
- public:
- Branch() {;}
-
- Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0);
- Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0) const {return const_cast(this)->getValue(vname, def, exists);}
- PICONFIG_GET_VALUE
-
- Branch allLeaves();
- Branch getValues(const PIString & name);
- Branch getLeaves();
- Branch getBranches();
- Branch & filter(const PIString & f);
- bool isEntryExists(const PIString & name) const {piForeachC (Entry * i, *this) if (entryExists(i, name)) return true; return false;}
- int indexOf(const Entry * e) {for (int i = 0; i < size_s(); ++i) if (at(i) == e) return i; return -1;}
-
- //void clear() {piForeach (Entry * i, *this) delete i; PIVector::clear();}
-
- private:
- bool entryExists(const Entry * e, const PIString & name) const;
- void allLeaves(Branch & b, Entry * e) {piForeach (Entry * i, e->_children) {if (i->isLeaf()) b << i; else allLeaves(b, i);}}
- void coutt(std::ostream & s, const PIString & p) const {piForeachC (Entry * i, *this) i->coutt(s, p);}
- void piCoutt(PICout s, const PIString & p) const {piForeachC (Entry * i, *this) i->piCoutt(s, p);}
-
- static Entry _empty;
- PIString delim;
-
- };
-
-
- class PIP_EXPORT Entry {
- friend class PIConfig;
- friend class Branch;
- public:
- Entry() {_parent = 0;}
-
- //! Returns parent entry, or 0 if there is no parent (root of default value)
- Entry * parent() const {return _parent;}
-
- //! Returns children count
- int childCount() const {return _children.size_s();}
-
- //! Returns children as \a PIConfig::Branch
- Branch & children() const {_children.delim = delim; return _children;}
-
- //! Returns child at index "index"
- Entry * child(const int index) const {return _children[index];}
-
- //! Returns first child with name "name"
- Entry * findChild(const PIString & name) {piForeach (Entry * i, _children) if (i->_name == name) return i; return 0;}
-
- //! Returns first child with name "name"
- const Entry * findChild(const PIString & name) const {piForeachC (Entry * i, _children) if (i->_name == name) return i; return 0;}
-
- //! Returns \b true if there is no children
- bool isLeaf() const {return _children.isEmpty();}
-
-
- //! Returns name
- const PIString & name() const {return _name;}
-
- //! Returns value
- const PIString & value() const {return _value;}
-
- //! Returns type
- const PIString & type() const {return _type;}
-
- //! Returns comment
- const PIString & comment() const {return _comment;}
-
- /** \brief Returns full name, i.e. name as it looks in file
- * \details In case of default entry full name always is empty
- * \snippet piconfig.cpp fullName */
- const PIString & fullName() const {return _full_name;}
-
- //! Set name to "value" and returns this
- Entry & setName(const PIString & value) {_name = value; return *this;}
-
- //! Set type to "value" and returns this
- Entry & setType(const PIString & value) {_type = value; return *this;}
-
- //! Set comment to "value" and returns this
- Entry & setComment(const PIString & value) {_comment = value; return *this;}
-
- //! Set value to "value" and returns this
- Entry & setValue(const PIString & value) {_value = value; return *this;}
-
- //! Set value to "value" and returns this. Type is set to "l"
- Entry & setValue(const PIStringList & value) {setValue(value.join("%|%")); setType("l"); return *this;}
-
- //! Set value to "value" and returns this. Type is set to "s"
- Entry & setValue(const char * value) {setValue(PIString(value)); setType("s"); return *this;}
-
- //! Set value to "value" and returns this. Type is set to "b"
- Entry & setValue(const bool value) {setValue(btos(value)); setType("b"); return *this;}
-
- //! Set value to "value" and returns this. Type is set to "s"
- Entry & setValue(const char value) {setValue(PIString(1, value)); setType("s"); return *this;}
-
- //! Set value to "value" and returns this. Type is set to "n"
- Entry & setValue(const short value) {setValue(itos(value)); setType("n"); return *this;}
-
- //! Set value to "value" and returns this. Type is set to "n"
- Entry & setValue(const int value) {setValue(itos(value)); setType("n"); return *this;}
-
- //! Set value to "value" and returns this. Type is set to "n"
- Entry & setValue(const long value) {setValue(ltos(value)); setType("n"); return *this;}
-
- //! Set value to "value" and returns this. Type is set to "n"
- Entry & setValue(const uchar value) {setValue(uitos(value)); setType("n"); return *this;}
-
- //! Set value to "value" and returns this. Type is set to "n"
- Entry & setValue(const ushort value) {setValue(uitos(value)); setType("n"); return *this;}
-
- //! Set value to "value" and returns this. Type is set to "n"
- Entry & setValue(const uint value) {setValue(uitos(value)); setType("n"); return *this;}
-
- //! Set value to "value" and returns this. Type is set to "n"
- Entry & setValue(const ulong value) {setValue(ultos(value)); setType("n"); return *this;}
-
- //! Set value to "value" and returns this. Type is set to "f"
- Entry & setValue(const float value) {setValue(ftos(value)); setType("f"); return *this;}
-
- //! Set value to "value" and returns this. Type is set to "f"
- Entry & setValue(const double value) {setValue(dtos(value)); setType("f"); return *this;}
-
-
- /** \brief Returns entry with name "vname" and default value "def"
- * \details If there is no suitable entry found, reference to default internal entry with
- * value = "def" will be returned, and if "exists" not null it will be set to \b false */
- Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0);
- Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0) const {return const_cast(this)->getValue(vname, def, exists);}
- PICONFIG_GET_VALUE
-
- //! \fn Entry & getValue(const PIString & vname, const char * def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const char * def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const PIStringList & def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const bool def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const short def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const int def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const long def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const uchar def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const ushort def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const uint def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const ulong def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const float def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const double def, bool * exists = 0)
- //! \brief Returns entry with name "vname" and default value "def"
-
-
- //! Find all entries with names with substrings "vname" and returns them as \a PIConfig::Branch
- Branch getValues(const PIString & vname);
-
-
- //! If there is no children returns if name == "name". Else returns if any child has name == "name"
- bool isEntryExists(const PIString & name) const {return entryExists(this, name);}
-
-
- //! Convertion to boolean
- operator bool() {return _value.toBool();}
-
- //! Convertion to char
- operator char() {return (_value.isEmpty() ? 0 : _value[0].toAscii());}
-
- //! Convertion to short
- operator short() {return _value.toShort();}
-
- //! Convertion to int
- operator int() {return _value.toInt();}
-
- //! Convertion to long
- operator long() {return _value.toLong();}
-
- //! Convertion to uchar
- operator uchar() {return _value.toInt();}
-
- //! Convertion to ushort
- operator ushort() {return _value.toShort();}
-
- //! Convertion to uint
- operator uint() {return _value.toInt();}
-
- //! Convertion to ulong
- operator ulong() {return _value.toLong();}
-
- //! Convertion to float
- operator float() {return _value.toFloat();}
-
- //! Convertion to double
- operator double() {return _value.toDouble();}
-
- //! Convertion to PIString
- operator PIString() {return _value;}
-
- //! Convertion to PIStringList
- operator PIStringList() {return _value.split("%|%");}
-
- private:
- typedef PIConfig::Entry * EntryPtr;
- static int compare(const EntryPtr * f, const EntryPtr * s) {return (*f)->_line == (*s)->_line ? 0 : (*f)->_line < (*s)->_line ? -1 : 1;}
- bool entryExists(const Entry * e, const PIString & name) const;
- void buildLine() {_all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment;}
- void clear() {_children.clear(); _name = _value = _type = _comment = _all = PIString(); _line = 0; _parent = 0;}
- void coutt(std::ostream & s, const PIString & p) const {PIString nl = p + " "; if (!_value.isEmpty()) s << p << _name << " = " << _value << endl; else cout << p << _name << endl; piForeachC (Entry * i, _children) i->coutt(s, nl);}
- void piCoutt(PICout s, const PIString & p) const {PIString nl = p + " "; if (!_value.isEmpty()) s << p << _name << " = " << _value << NewLine; else cout << p << _name << endl; piForeachC (Entry * i, _children) i->piCoutt(s, nl);}
- void deleteBranch() {piForeach (Entry * i, _children) {i->deleteBranch(); delete i;}}
-
- static Entry _empty;
- Entry * _parent;
- mutable Branch _children;
- PIString _tab;
- PIString _name;
- PIString _value;
- PIString _type;
- PIString _comment;
- PIString _all;
- PIString _full_name;
- PIString delim;
- int _line;
- };
-
-
- //! Returns top-level entry with name "vname", if doesn`t exists return entry with value "def" and set *exist to false
- Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0);
- Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0) const {return const_cast(this)->getValue(vname, def, exists);}
-
- PICONFIG_GET_VALUE
-
- //! \fn Entry & getValue(const PIString & vname, const char * def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const char * def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const PIStringList & def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const bool def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const short def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const int def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const long def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const uchar def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const ushort def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const uint def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const ulong def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const float def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
- //! \fn Entry & getValue(const PIString & vname, const double def, bool * exists = 0)
- //! \brief Returns top-level entry with name "vname" and default value "def"
-
-
- //! Returns top-level entries with names with substrings "vname"
- Branch getValues(const PIString & vname);
-
-
- //! Set top-level entry with name "name" value to "value", type to "type" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const PIString & value, const PIString & type = "s", bool write = true);
-
- //! Set top-level entry with name "name" value to "value", type to "l" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const PIStringList & value, bool write = true) {setValue(name, value.join("%|%"), "l", write);}
-
- //! Set top-level entry with name "name" value to "value", type to "s" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const char * value, bool write = true) {setValue(name, PIString(value), "s", write);}
-
- //! Set top-level entry with name "name" value to "value", type to "b" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const bool value, bool write = true) {setValue(name, btos(value), "b", write);}
-
- //! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const short value, bool write = true) {setValue(name, itos(value), "n", write);}
-
- //! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const int value, bool write = true) {setValue(name, itos(value), "n", write);}
-
- //! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const long value, bool write = true) {setValue(name, ltos(value), "n", write);}
-
- //! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const uchar value, bool write = true) {setValue(name, uitos(value), "n", write);}
-
- //! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const ushort value, bool write = true) {setValue(name, uitos(value), "n", write);}
-
- //! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const uint value, bool write = true) {setValue(name, uitos(value), "n", write);}
-
- //! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const ulong value, bool write = true) {setValue(name, ultos(value), "n", write);}
-
- //! Set top-level entry with name "name" value to "value", type to "f" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const float value, bool write = true) {setValue(name, ftos(value), "f", write);}
-
- //! Set top-level entry with name "name" value to "value", type to "f" and if "write" immediate write to file. Add new entry if there is no suitable exists
- void setValue(const PIString & name, const double value, bool write = true) {setValue(name, dtos(value), "f", write);}
-
- //! Returns root entry
- Entry & rootEntry() {return root;}
-
- //! Returns top-level entries count
- int entriesCount() const {return childCount(&root);}
-
- //! Returns if top-level entry with name "name" exists
- bool isEntryExists(const PIString & name) const {return entryExists(&root, name);}
-
- //! Returns all top-level entries
- Branch allTree() {Branch b; piForeach (Entry * i, root._children) b << i; b.delim = delim; return b;}
-
- //! Returns all entries without children
- Branch allLeaves() {Branch b; allLeaves(b, &root); b.sort(Entry::compare); b.delim = delim; return b;}
-
- int entryIndex(const PIString & name);
-
- PIString getName(uint number) {return entryByIndex(number)._name;}
- PIString getValue(uint number) {return entryByIndex(number)._value;}
- PIChar getType(uint number) {return entryByIndex(number)._type[0];}
- PIString getComment(uint number) {return entryByIndex(number)._comment;}
-
- void addEntry(const PIString & name, const PIString & value, const PIString & type = "s", bool write = true);
- void setName(uint number, const PIString & name, bool write = true);
- void setValue(uint number, const PIString & value, bool write = true);
- void setType(uint number, const PIString & type, bool write = true);
- void setComment(uint number, const PIString & comment, bool write = true);
-
- void removeEntry(const PIString & name, bool write = true);
- void removeEntry(uint number, bool write = true);
-
- //! Remove all tree and file content
- void clear() {PIFile::clear(); parse();}
-
- //! Parse file and build internal tree
- void readAll();
-
- //! Write all internal tree to file
- void writeAll();
-
- //! Returns current tree delimiter, default "."
- const PIString & delimiter() const {return delim;}
-
- //! Set current tree delimiter
- void setDelimiter(const PIString & d) {delim = d; setEntryDelim(&root, d); readAll();}
-
-private:
- int childCount(const Entry * e) const {int c = 0; piForeachC (Entry * i, e->_children) c += childCount(i); c += e->_children.size_s(); return c;}
- bool entryExists(const Entry * e, const PIString & name) const;
- void buildFullNames(Entry * e) {piForeach (Entry * i, e->_children) {if (e != &root) i->_full_name = e->_full_name + delim + i->_name; else i->_full_name = i->_name; buildFullNames(i);}}
- void allLeaves(Branch & b, Entry * e) {piForeach (Entry * i, e->_children) {if ((!i->_value.isEmpty() && !i->isLeaf()) || i->isLeaf()) b << i; allLeaves(b, i);}}
- void setEntryDelim(Entry * e, const PIString & d) {piForeach (Entry * i, e->_children) setEntryDelim(i, d); e->delim = d;}
- Entry & entryByIndex(const int index) {Branch b = allLeaves(); if (index < 0 || index >= b.size_s()) return empty; return *(b[index]);}
- void removeEntry(Branch & b, Entry * e);
- void deleteEntry(Entry * e) {piForeach (Entry * i, e->_children) deleteEntry(i); delete e;}
- PIString getPrefixFromLine(PIString line, bool * exists);
- void parse();
-
- int centry;
- PIString delim;
- Entry root, empty;
- uint lines;
- PIStringList other;
-
-};
-
-
-inline std::ostream & operator <<(std::ostream & s, const PIConfig::Branch & v) {v.coutt(s, ""); return s;}
-inline std::ostream & operator <<(std::ostream & s, const PIConfig::Entry & v) {s << v.value(); return s;}
-inline PICout operator <<(PICout s, const PIConfig::Branch & v) {s.setControl(0, true); v.piCoutt(s, ""); s.restoreControl(); return s;}
-inline PICout operator <<(PICout s, const PIConfig::Entry & v) {s << v.value(); return s;}
-
-
-/** \relatesalso PIConfig \relatesalso PIIODevice
- * \brief Service function. useful for configuring devices
- * \details Function takes entry name "name", default value "def" and two
- * \a PIConfig::Entry sections: "em" and their parent "ep". If there is no
- * parent ep = 0. If "ep" is not null and entry "name" exists in "ep" function
- * returns this value. Else returns value of entry "name" in section "em" or
- * "def" if entry doesn`t exists. \n This function useful to read settings
- * from configuration file in implementation \a PIIODevice::configureDevice() function */
-template
-T readDeviceSetting(const PIString & name, const T & def, const PIConfig::Entry * em, const PIConfig::Entry * ep) {
- if (ep != 0) {
- T ret;
- bool ex;
- ret = ep->getValue(name, def, &ex);
- if (!ex) ret = em->getValue(name, def);
- return ret;
- }
- return em->getValue(name, def);
-
-}
-
-#endif // PICONFIG_H
diff --git a/piconnection.cpp b/piconnection.cpp
deleted file mode 100644
index fcc3d2f3..00000000
--- a/piconnection.cpp
+++ /dev/null
@@ -1,764 +0,0 @@
-/*
- PIP - Platform Independent Primitives
- Complex I/O point
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#include "piconnection.h"
-#include "piconfig.h"
-
-/** \class PIConnection
- * \brief Complex Input/Output point
- *
- * \section PIConnection_synopsis Synopsis
- * %PIConnection provides abstract layer over physical devices,
- * filtering and connecting data streams. Each %PIConnection
- * works through Device Pool, so several %PIConnections can
- * read from single physical device. General scheme:
- * \image html piconnection.png
- *
- * \section PIConnection_pool Device pool concept
- * Device pool is static object, single for each application, which
- * contains unique devices. Each %PIConnection works with real devices
- * through Device pool. Each device has assosiated thread for read
- * and it can be started or stopped with %PIConnection functions
- * \a startThreadedRead() and \a stopThreadedRead().
- *
- * \section PIConnection_config Configuration
- * You can create %PIConnection from config file section or configure
- * it later with function \a configureFromConfig(). Devices describes
- * with its full pathes, for details see \ref PIIODevice_sec7. Example:
- * \image html piconnection_conf.png
- *
-*/
-
-
-PIVector PIConnection::_connections;
-
-
-PIConnection::PIConnection(): PIObject() {
- _connections << this;
-}
-
-
-PIConnection::PIConnection(const PIString & config, const PIString & name_): PIObject(name_) {
- _connections << this;
- configureFromConfig(config, name_);
-}
-
-
-PIConnection::~PIConnection() {
- __device_pool__->unboundConnection(this);
- removeAllFilters();
- _connections.removeAll(this);
-}
-
-
-bool PIConnection::configureFromConfig(const PIString & conf_path, const PIString & name_) {
- PIConfig conf(conf_path, PIIODevice::ReadOnly);
- if (!conf.isOpened()) return false;
- __device_pool__->unboundConnection(this);
- removeAllChannels();
- removeAllFilters();
- removeAllDevices();
- setName(name_);
- PIConfig::Entry ce(conf.getValue(name_));
- PIConfig::Branch db(ce.getValue("device").children()), fb(ce.getValue("filter").children()), cb(ce.getValue("channel").children());
- PIStringList dev_list(ce.getValue("device").value());
- piForeachC (PIConfig::Entry * e, db)
- dev_list << e->value();
- dev_list.removeStrings("");
- piForeachC (PIString & s, dev_list) {
- PIString fn(s);
- PIIODevice::DeviceMode dm = PIIODevice::ReadWrite;
- if (fn.find("(") > 0 && fn.find(")") > 0) {
- PIString dms(fn.right(fn.length() - fn.find("(")).takeRange("(", ")").trim().toLowerCase().removeAll(" "));
- //piCout << dms;
- if (dms == "r" || dms == "ro" || dms == "read" || dms == "readonly")
- dm = PIIODevice::ReadOnly;
- if (dms == "w" || dms == "wo" || dms == "write" || dms == "writeonly")
- dm = PIIODevice::WriteOnly;
- fn.cutRight(fn.length() - fn.find("(") + 1).trim();
- }
- //piCout << fn;
- PIIODevice * dev = addDevice(fn, dm);
- if (dev) dev->setName(name_ + ".device." + s);
- }
- piForeachC (PIConfig::Entry * e, fb) {
- PIPacketExtractor::SplitMode sm = PIPacketExtractor::None;
- PIString sms(e->getValue("splitMode").value());
- int smi = sms.toInt();
- if (smi >= 1 && smi <= 5) sm = (PIPacketExtractor::SplitMode)smi;
- else {
- sms = sms.trim().toLowerCase();
- if (sms.find("header") >= 0 && sms.find("footer") >= 0)
- sm = PIPacketExtractor::HeaderAndFooter;
- else {
- if (sms.find("header") >= 0)
- sm = PIPacketExtractor::Header;
- else {
- if (sms.find("footer") >= 0)
- sm = PIPacketExtractor::Footer;
- else {
- if (sms.find("time") >= 0)
- sm = PIPacketExtractor::Timeout;
- else {
- if (sms.find("size") >= 0)
- sm = PIPacketExtractor::Size;
- }
- }
- }
- }
- }
- PIStringList devs(e->value());
- PIConfig::Branch db(e->getValue("device").children());
- piForeachC (PIConfig::Entry * e2, db)
- devs << e2->value();
- devs.removeStrings("");
- if (devs.isEmpty()) continue;
- PIPacketExtractor * pe = addFilter(e->name(), devs.front(), sm);
- if (pe == 0) continue;
- for (int i = 1; i < devs.size_s(); ++i)
- addFilter(e->name(), devs[i], sm);
- pe->setPayloadSize(e->getValue("payloadSize", pe->payloadSize()));
- pe->setPacketSize(e->getValue("packetSize", pe->packetSize()));
- pe->setTimeout(e->getValue("timeout", pe->timeout()));
- pe->setHeader(PIByteArray::fromString(e->getValue("header", "").value()));
- pe->setFooter(PIByteArray::fromString(e->getValue("footer", "").value()));
- }
- piForeachC (PIConfig::Entry * e, cb) {
- PIString f(e->getValue("from").value()), t(e->getValue("to").value());
- addChannel(f, t);
- }
- return true;
-}
-
-
-PIString PIConnection::makeConfig() const {
- PIString ret;
- ret << "[" << name() << "]\n";
- PIVector devs(boundedDevices());
- int dn(0);
- piForeachC (PIIODevice * d, devs) {
- ret << "device." << dn << " = " << d->constructFullPath(); ++dn;
- if (d->mode() == PIIODevice::ReadOnly) ret << " (ro)";
- if (d->mode() == PIIODevice::WriteOnly) ret << " (wo)";
- ret << "\n";
- }
- piForeachC (PEPair & f, extractors) {
- if (f.second == 0) continue;
- if (f.second->extractor == 0) continue;
- PIString prefix = "filter." + f.first;
- for (int i = 0; i < f.second->devices.size_s(); ++i)
- ret << prefix << ".device." << i << " = " << f.second->devices[i]->constructFullPath() << "\n";
- ret << prefix << ".splitMode = ";
- switch (f.second->extractor->splitMode()) {
- case PIPacketExtractor::None: ret << "none"; break;
- case PIPacketExtractor::Header: ret << "header"; break;
- case PIPacketExtractor::Footer: ret << "footer"; break;
- case PIPacketExtractor::HeaderAndFooter: ret << "header & footer"; break;
- case PIPacketExtractor::Size: ret << "size"; break;
- case PIPacketExtractor::Timeout: ret << "timeout"; break;
- }
- ret << "\n";
- ret << prefix << ".payloadSize = " << f.second->extractor->payloadSize() << "\n";
- ret << prefix << ".packetSize = " << f.second->extractor->packetSize() << "\n";
- ret << prefix << ".timeout = " << f.second->extractor->timeout() << "\n";
- ret << prefix << ".header = " << f.second->extractor->header().toString() << "\n";
- ret << prefix << ".footer = " << f.second->extractor->footer().toString() << "\n";
- }
- dn = 0;
- piForeachC (CPair & c, channels_) {
- piForeachC (PIIODevice * d, c.second) {
- PIString prefix = "channel." + PIString::fromNumber(dn); ++dn;
- ret << prefix << ".from = " << devPath(c.first) << "\n";
- ret << prefix << ".to = " << devPath(d) << "\n";
- }
- }
- ret << "[]\n";
- return ret;
-}
-
-
-PIIODevice * PIConnection::addDevice(const PIString & full_path, PIIODevice::DeviceMode mode, bool start) {
- PIIODevice * dev = __device_pool__->addDevice(this, full_path, mode, start);
- if (dev) {
- dev->setName(name() + ".device." + full_path);
- device_modes[dev] = mode;
- }
- return dev;
-}
-
-
-bool PIConnection::removeDevice(const PIString & full_path) {
- PIIODevice * dev = __device_pool__->device(full_path);
- if (dev == 0) return false;
- device_modes.remove(dev);
- piForeachC (PEPair & i, extractors) {
- if (i.second == 0) continue;
- i.second->devices.removeAll(dev);
- }
- bounded_extractors.remove(dev);
- channels_.remove(dev);
- for (PIMap >::iterator it = channels_.begin(); it != channels_.end(); ++it)
- it.value().removeAll(dev);
- return __device_pool__->removeDevice(this, full_path);
-}
-
-
-void PIConnection::removeAllDevices() {
- PIVector bdevs(__device_pool__->boundedDevices(this));
- piForeach (PIIODevice * d, bdevs) {
- channels_.remove(d);
- for (PIMap >::iterator it = channels_.begin(); it != channels_.end(); ++it)
- it.value().removeAll(d);
- }
- __device_pool__->unboundConnection(this);
- device_modes.clear();
- bounded_extractors.clear();
- piForeachC (PEPair & i, extractors) {
- if (i.second == 0) continue;
- i.second->devices.clear();
- }
-}
-
-
-PIIODevice * PIConnection::device(const PIString & full_path) const {
- DevicePool::DeviceData * dd = __device_pool__->devices.value(full_path);
- if (dd == 0) return 0;
- if (dd->dev == 0) return 0;
- if (!dd->listeners.contains(const_cast(this))) return 0;
- return dd->dev;
-}
-
-
-PIVector PIConnection::boundedDevices() const {
- return __device_pool__->boundedDevices(this);
-}
-
-
-PIPacketExtractor * PIConnection::addFilter(const PIString & name_, const PIString & full_path, PIPacketExtractor::SplitMode mode) {
- Extractor * e = extractors.value(name_);
- PIIODevice * dev = __device_pool__->device(full_path);
- if (dev == 0) {
- piCoutObj << "\"addPacketExtractor\" error: no such device \"" << full_path << "\"!";
- return 0;
- }
- if (e == 0) {
- e = new Extractor();
- extractors[name_] = e;
- }
- if (e->extractor == 0) {
- e->extractor = new PIPacketExtractor(0, mode);
- e->extractor->setName(name_);
- e->extractor->setThreadedReadData(new PIPair(this, name_));
- e->extractor->setHeaderCheckSlot(filterValidateHeaderS);
- e->extractor->setFooterCheckSlot(filterValidateFooterS);
- e->extractor->setPayloadCheckSlot(filterValidatePayloadS);
- CONNECT2(void, uchar * , int, e->extractor, packetReceived, this, packetExtractorReceived)
- }
- if (!e->devices.contains(dev)) {
- bounded_extractors[dev] << e->extractor;
- e->devices << dev;
- }
- return e->extractor;
-}
-
-
-PIPacketExtractor * PIConnection::addFilter(const PIString & name_, const PIIODevice * dev, PIPacketExtractor::SplitMode mode) {
- if (dev == 0) return 0;
- PIString fp;
- if (dev->isPropertyExists("__fullPath__")) fp = dev->property("__fullPath__").toString();
- fp = dev->constructFullPath();
- return addFilter(name_, fp, mode);
-}
-
-
-bool PIConnection::removeFilter(const PIString & name_, const PIString & full_path) {
- Extractor * p = extractors.value(name_);
- if (p == 0) return false;
- bool ret = false;
- for (int i = 0; i < p->devices.size_s(); ++i) {
- if (p->devices[i]->property("__fullPath__").toString() == full_path) {
- bounded_extractors[p->devices[i]].removeAll(p->extractor);
- p->devices.remove(i);
- --i;
- ret = true;
- }
- }
- if (p->devices.isEmpty()) {
- unboundExtractor(p->extractor);
- delete p;
- }
- return ret;
-}
-
-
-bool PIConnection::removeFilter(const PIString & name, const PIIODevice * dev) {
- if (dev == 0) return false;
- return removeFilter(name, dev->property("__fullPath__").toString());
-}
-
-
-bool PIConnection::removeFilter(const PIString & name_) {
- Extractor * p = extractors.value(name_);
- if (p == 0) return false;
- unboundExtractor(p->extractor);
- delete p;
- return true;
-}
-
-
-void PIConnection::removeAllFilters() {
- piForeachC (PEPair & i, extractors) {
- if (i.second == 0) continue;
- channels_.remove(i.second->extractor);
- for (PIMap >::iterator it = channels_.begin(); it != channels_.end(); ++it)
- it.value().removeAll(i.second->extractor);
- delete i.second;
- }
- extractors.clear();
- bounded_extractors.clear();
-}
-
-
-PIVector PIConnection::filters() const {
- PIVector ret;
- piForeachC (PEPair & i, extractors)
- if (i.second != 0)
- if (i.second->extractor != 0) ret << i.second->extractor;
- return ret;
-}
-
-
-PIStringList PIConnection::filterNames() const {
- PIStringList ret;
- piForeachC (PEPair & i, extractors)
- if (i.second != 0)
- if (i.second->extractor != 0) ret << i.first;
- return ret;
-}
-
-
-PIPacketExtractor * PIConnection::filter(const PIString & name) const {
- piForeachC (PEPair & i, extractors)
- if (i.second != 0)
- if (i.second->extractor != 0 && i.first == name)
- return i.second->extractor;
- return 0;
-}
-
-
-PIVector PIConnection::filterBoundedDevices(const PIString & name_) const {
- PIVector ret;
- Extractor * p = extractors.value(name_);
- if (p == 0) return ret;
- return p->devices;
-}
-
-
-bool PIConnection::addChannel(const PIString & name0, const PIString & name1) {
- //piCout << "addChannel" << name0 << name1;
- if (name0.isEmpty() || name1.isEmpty()) return false;
- PIIODevice * dev0 = device(name0), * dev1 = device(name1);
- PIPacketExtractor * pe0(0), * pe1(0);
- if (extractors.value(name0) != 0) pe0 = extractors.value(name0)->extractor;
- if (extractors.value(name1) != 0) pe1 = extractors.value(name1)->extractor;
- if (pe0 != 0) dev0 = pe0;
- if (pe1 != 0) dev1 = pe1;
- if (dev0 == 0 || dev1 == 0) {
- if (dev0 == 0) piCoutObj << "\"addChannel\" error: no such device \"" << name0 << "\"!";
- if (dev1 == 0) piCoutObj << "\"addChannel\" error: no such device \"" << name1 << "\"!";
- return false;
- }
- if (!channels_[dev0].contains(dev1))
- channels_[dev0] << dev1;
- return true;
-}
-
-
-bool PIConnection::removeChannel(const PIString & name0, const PIString & name1) {
- PIIODevice * dev0 = device(name0), * dev1 = device(name1);
- PIPacketExtractor * pe0(0), * pe1(0);
- if (extractors.value(name0) != 0) pe0 = extractors.value(name0)->extractor;
- if (extractors.value(name1) != 0) pe1 = extractors.value(name1)->extractor;
- if (pe0 != 0) dev0 = pe0;
- if (pe1 != 0) dev1 = pe1;
- if (dev0 == 0 || dev1 == 0) return false;
- channels_[dev0].removeAll(dev1);
- return true;
-}
-
-
-bool PIConnection::removeChannel(const PIString & name0) {
- PIIODevice * dev0 = device(name0);
- PIPacketExtractor * pe0(0);
- if (extractors.value(name0) != 0) pe0 = extractors.value(name0)->extractor;
- if (pe0 != 0) dev0 = pe0;
- if (dev0 == 0) return false;
- channels_.remove(dev0);
- for (PIMap >::iterator it = channels_.begin(); it != channels_.end(); ++it)
- it.value().removeAll(dev0);
- return true;
-}
-
-
-void PIConnection::removeAllChannels() {
- channels_.clear();
-}
-
-
-PIString PIConnection::devPath(const PIIODevice * d) const {
- if (d == 0) return PIString();
- if (strcmp(d->className(), "PIPacketExtractor") == 0) return d->name();
- return d->constructFullPath();
-}
-
-
-PIString PIConnection::devFPath(const PIIODevice * d) const {
- if (d == 0) return PIString();
- if (d->isPropertyExists("__fullPath__")) return d->property("__fullPath__").toString();
- return d->name();
-}
-
-
-PIVector > PIConnection::channels() const {
- PIVector > ret;
- piForeachC (CPair & i, channels_) {
- PIString fp0(devFPath(i.first));
- piForeachC (PIIODevice * d, i.second)
- ret << PIPair(fp0, devFPath(d));
- }
- return ret;
-}
-
-
-void PIConnection::startThreadedRead(const PIString & full_path) {
- DevicePool::DeviceData * dd = __device_pool__->devices.value(full_path, 0);
- if (dd == 0) return;
- if (dd->dev == 0) return;
- if (dd->started || dd->dev->mode() == PIIODevice::WriteOnly) return;
- dd->rthread->start();
- dd->started = true;
-}
-
-
-void PIConnection::startAllThreadedReads() {
- piForeachC (DevicePool::DDPair & d, __device_pool__->devices)
- startThreadedRead(d.first);
-}
-
-
-void PIConnection::stopThreadedRead(const PIString & full_path) {
- DevicePool::DeviceData * dd = __device_pool__->devices.value(full_path, 0);
- if (dd == 0) return;
- if (dd->dev == 0) return;
- if (!dd->started || dd->dev->mode() == PIIODevice::WriteOnly) return;
- dd->rthread->stop();
- dd->started = false;
-}
-
-
-void PIConnection::stopAllThreadedReads() {
- piForeachC (DevicePool::DDPair & d, __device_pool__->devices)
- stopThreadedRead(d.first);
-}
-
-
-int PIConnection::write(const PIString & full_path, const PIByteArray & data) {
- PIIODevice * dev = __device_pool__->device(full_path);
- if (dev == 0) {
- piCoutObj << "Null Device!";
- return -1;
- }
- if (!dev->canWrite()) {
- piCoutObj << "Device \"" << full_path << "\" can`t write!";
- return -1;
- }
- return dev->write(data);
-}
-
-
-PIVector< PIConnection * > PIConnection::allConnections() {
- return _connections;
-}
-
-
-PIVector< PIIODevice * > PIConnection::allDevices() {
- return __device_pool__->boundedDevices();
-}
-
-
-
-PIIODevice * PIConnection::DevicePool::addDevice(PIConnection * parent, const PIString & fp, PIIODevice::DeviceMode mode, bool start) {
- DeviceData * dd = devices[fp];
- int pmode(0);
- bool need_start = false;
- if (dd == 0) {
- dd = new DeviceData();
- devices[fp] = dd;
- }
- if (dd->dev == 0) {
- //piCout << "new device" << fp;
- dd->dev = PIIODevice::createFromFullPath(fp);
- if (dd->dev == 0) {
- piCoutObj << "Error: can`t create device \"" << fp << "\"!"; //:" << errorString();
- return 0;
- }
- dd->dev->setProperty("__fullPath__", fp);
- } else
- pmode = dd->dev->mode();
- if (!dd->listeners.contains(parent))
- dd->listeners << parent;
- if (pmode == mode || pmode == PIIODevice::ReadWrite)
- return dd->dev;
- if ((mode & PIIODevice::ReadOnly) > 0) {
- if (dd->rthread != 0) {
- delete dd->rthread;
- dd->rthread = 0;
- dd->started = false;
- }
- dd->rthread = new PIThread(dd, threadReadDP);
- need_start = true;
- pmode |= PIIODevice::ReadOnly;
- }
- if ((mode & PIIODevice::WriteOnly) > 0)
- pmode |= PIIODevice::WriteOnly;
- dd->dev->close();
- dd->dev->open((PIIODevice::DeviceMode)pmode);
- if (need_start && start) {
- dd->rthread->start();
- dd->started = true;
- }
- return dd->dev;
-}
-
-
-bool PIConnection::DevicePool::removeDevice(PIConnection * parent, const PIString & fp) {
- DeviceData * dd = devices.value(fp);
- if (dd == 0)
- return false;
- if (dd->dev == 0)
- return false;
- bool ok = dd->listeners.contains(parent);
- dd->listeners.removeAll(parent);
- if (dd->listeners.isEmpty()) {
- delete dd;
- devices.remove(fp);
- }
- return ok;
-}
-
-
-void PIConnection::DevicePool::unboundConnection(PIConnection * parent) {
- PIStringList rem;
- piForeachC (DDPair & i, devices) {
- if (i.second == 0) {
- rem << i.first;
- continue;
- }
- i.second->listeners.removeAll(parent);
- if (i.second->listeners.isEmpty())
- rem << i.first;
- }
- piForeachC (PIString & i, rem) {
- DeviceData * dd = devices.value(i);
- if (dd == 0)
- continue;
- delete dd;
- devices.remove(i);
- }
-}
-
-
-PIIODevice * PIConnection::DevicePool::device(const PIString & fp) const {
- DeviceData * dd = devices.value(fp);
- if (dd == 0) return 0;
- return dd->dev;
-}
-
-
-PIVector PIConnection::DevicePool::boundedConnections() const {
- PIVector ret;
- piForeachC (DDPair & i, devices) {
- if (i.second == 0)
- continue;
- ret << i.second->listeners;
- }
- for (int i = 0; i < ret.size_s(); ++i)
- for (int j = i + 1; j < ret.size_s(); ++j)
- if (ret[i] == ret[j]) {
- ret.remove(j);
- --j;
- }
- return ret;
-}
-
-
-PIVector< PIIODevice * > PIConnection::DevicePool::boundedDevices() const {
- PIVector ret;
- piForeachC (DDPair & i, devices) {
- if (i.second == 0) continue;
- if (i.second->dev == 0) continue;
- ret << i.second->dev;
- }
- return ret;
-}
-
-
-PIVector PIConnection::DevicePool::boundedDevices(const PIConnection * parent) const {
- PIVector ret;
- piForeachC (DDPair & i, devices) {
- if (i.second == 0) continue;
- if (i.second->dev == 0) continue;
- if (i.second->listeners.contains(const_cast(parent)))
- ret << i.second->dev;
- }
- return ret;
-}
-
-
-PIConnection::DevicePool::DeviceData::~DeviceData() {
- if (rthread != 0) {
- rthread->stop();
- delete rthread;
- rthread = 0;
- }
- if (dev != 0) {
- delete dev;
- dev = 0;
- }
-}
-
-
-void PIConnection::DevicePool::threadReadDP(void * ddp) {
- DeviceData * dd((DeviceData * )ddp);
- if (dd->dev == 0) {piMSleep(100); return;}
- PIByteArray ba;
- ba = dd->dev->read(dd->dev->threadedReadBufferSize());
- if (ba.isEmpty()) {piMSleep(10); return;}
- //piCout << "Readed from" << dd->dev->path() << Hex << ba;
- __device_pool__->deviceReaded(dd, ba);
-}
-
-
-void PIConnection::DevicePool::deviceReaded(PIConnection::DevicePool::DeviceData * dd, const PIByteArray & data) {
- PIString from = dd->dev->property("__fullPath__").toString();
- piForeach (PIConnection * ld, dd->listeners)
- ld->rawReceived(dd->dev, from, data);
-}
-
-
-bool PIConnection::filterValidateHeaderS(void * c, uchar * src, uchar * rec, int size) {
- PIPair * p((PIPair * )c);
- return p->first->filterValidateHeader(p->second, src, rec, size);
-}
-
-
-bool PIConnection::filterValidateFooterS(void * c, uchar * src, uchar * rec, int size) {
- PIPair * p((PIPair * )c);
- return p->first->filterValidateFooter(p->second, src, rec, size);
-}
-
-
-bool PIConnection::filterValidatePayloadS(void * c, uchar * rec, int size) {
- PIPair * p((PIPair * )c);
- return p->first->filterValidatePayload(p->second, rec, size);
-}
-
-
-void PIConnection::rawReceived(PIIODevice * dev, const PIString & from, const PIByteArray & data) {
- dataReceived(from, data);
- dataReceivedEvent(from, data);
- PIVector be(bounded_extractors.value(dev));
- //piCout << be;
- piForeach (PIPacketExtractor * i, be)
- i->threadedRead(const_cast(data.data()), data.size_s());
- PIVector chd(channels_.value(dev));
- piForeach (PIIODevice * d, chd)
- d->write(data);
-}
-
-
-bool PIConnection::filterValidateHeader(const PIString & filter_name, uchar * src, uchar * rec, int size) {
- for (int i = 0; i < size; ++i)
- if (src[i] != rec[i])
- return false;
- return true;
-}
-
-
-bool PIConnection::filterValidateFooter(const PIString & filter_name, uchar * src, uchar * rec, int size) {
- for (int i = 0; i < size; ++i)
- if (src[i] != rec[i])
- return false;
- return true;
-}
-
-
-bool PIConnection::filterValidatePayload(const PIString & filter_name, uchar * rec, int size) {
- return true;
-}
-
-
-PIConnection::Extractor::~Extractor() {
- if (extractor != 0) {
- if (extractor->threadedReadData() != 0)
- delete (PIPair * )(extractor->threadedReadData());
- delete extractor;
- extractor = 0;
- }
-}
-
-
-void PIConnection::unboundExtractor(PIPacketExtractor * pe) {
- if (pe == 0) return;
- channels_.remove(pe);
- for (PIMap >::iterator it = channels_.begin(); it != channels_.end(); ++it)
- it.value().removeAll(pe);
- PIVector k = bounded_extractors.keys();
- piForeach (PIIODevice * i, k) {
- PIVector & be(bounded_extractors[i]);
- be.removeAll(pe);
- if (be.isEmpty())
- bounded_extractors.remove(i);
- }
- extractors.remove(pe->name());
-}
-
-
-void PIConnection::packetExtractorReceived(uchar * data, int size) {
- PIString from(emitter() == 0 ? "" : emitter()->name());
- packetReceived(from, PIByteArray(data, size));
- packetReceivedEvent(from, PIByteArray(data, size));
- PIIODevice * cd = (PIIODevice * )emitter();
- if (cd == 0) return;
- PIVector chd(channels_.value(cd));
- piForeach (PIIODevice * d, chd)
- d->write(data, size);
-}
-
-
-
-PIConnection::DevicePool * __device_pool__;
-
-bool __DevicePoolContainer__::inited_(false);
-
-__DevicePoolContainer__::__DevicePoolContainer__() {
- if (inited_) return;
- inited_ = true;
- __device_pool__ = new PIConnection::DevicePool();
-}
diff --git a/piconnection.h b/piconnection.h
deleted file mode 100644
index c00f85da..00000000
--- a/piconnection.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/*! \file piconnection.h
- * \brief Complex I/O point
-*/
-/*
- PIP - Platform Independent Primitives
- Complex I/O point
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#ifndef PICONNECTION_H
-#define PICONNECTION_H
-
-#include "pipacketextractor.h"
-
-
-class PIP_EXPORT PIConnection: public PIObject
-{
- PIOBJECT(PIConnection)
-public:
-
- //! Constructs an empty connection
- PIConnection();
-
- //! Constructs connection and configure it from config file "config" from section "name"
- PIConnection(const PIString & config, const PIString & name);
-
- ~PIConnection();
-
-
- /*! \brief Configure connection from config file "config" from section "name". Returns if configuration was successful
- * \details \b Warning: all devices, filters and channels removed before configure! */
- bool configureFromConfig(const PIString & config, const PIString & name);
-
- //! Returns config file section of current connection configuration
- PIString makeConfig() const;
-
-
- /*! \brief Add device with full path "full_path", open mode "mode" to Device pool and connection
- * \details Returns pointer to device or null if device can not be created. If "start" is true,
- * read thread is started immediately. Else, you can start read thread with functions \a startThreadedRead()
- * or \a startAllThreadedReads(). By default, read thread doesn`t start */
- PIIODevice * addDevice(const PIString & full_path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite, bool start = false);
-
- /*! \brief Remove device with full path "full_path" from connection
- * \details Returns if device was removed. If there is no connection bounded to this device,
- * it will be removed from Device pool */
- bool removeDevice(const PIString & full_path);
-
- /*! \brief Remove all device from connection
- * \details If there is no connection bounded to there devices, they removed from Device pool */
- void removeAllDevices();
-
- //! Returns device with full path "full_path" or null if there is no such device
- PIIODevice * device(const PIString & full_path) const;
-
- //! Returns all devices bounded to this connection
- PIVector boundedDevices() const;
-
-
- /*! \brief Add filter with name "name" to device with full path "full_path"
- * \details If there is no filter with name "name", connection create new with split mode "mode" and bound
- * to it device "full_path". If filter with name "name" already exists, device "full_path" add to this filter.
- * \b Attention! "mode" is altual olny if new filter was created!
- * This function returns PIPacketExtractor * assosiated with this filter */
- PIPacketExtractor * addFilter(const PIString & name, const PIString & full_path, PIPacketExtractor::SplitMode mode = PIPacketExtractor::None);
-
- //! Add filter with name "name" to device "dev"
- PIPacketExtractor * addFilter(const PIString & name, const PIIODevice * dev, PIPacketExtractor::SplitMode mode = PIPacketExtractor::None);
-
- /*! \brief Remove from filter with name "name" device with full path "full_path"
- * \details If there is no devices bounded to this filter, it will be removed. Returns
- * if device was removed */
- bool removeFilter(const PIString & name, const PIString & full_path);
-
- //! Remove from filter with name "name" device "dev"
- bool removeFilter(const PIString & name, const PIIODevice * dev);
-
- //! Remove filter with name "name". Returns if filter was removed
- bool removeFilter(const PIString & name);
-
- //! Remove all filters from connection
- void removeAllFilters();
-
-
- //! Returns all filters of connection
- PIVector filters() const;
-
- //! Returns all filter names of connection
- PIStringList filterNames() const;
-
- //! Returns PIPacketExtractor * assosiated with filter "name" or null if there is no such filter
- PIPacketExtractor * filter(const PIString & name) const;
-
- //! Returns all devices bounded to filter "name"
- PIVector filterBoundedDevices(const PIString & name) const;
-
-
- /*! \brief Add to connection channel from "name_from" to "name_to"
- * \details "name_from" and "name_to" can be full pathes of devices or filter names.
- * Returns \b false if there if no such device or filter, else create channel and returns \b true */
- bool addChannel(const PIString & name_from, const PIString & name_to);
-
- //! Add to connection channel from "name_from" to "dev_to"
- bool addChannel(const PIString & name_from, const PIIODevice * dev_to) {return addChannel(name_from, devFPath(dev_to));}
-
- //! Add to connection channel from "dev_from" to "name_to"
- bool addChannel(const PIIODevice * dev_from, const PIString & name_to) {return addChannel(devFPath(dev_from), name_to);}
-
- //! Add to connection channel from "dev_from" to "dev_to"
- bool addChannel(const PIIODevice * dev_from, const PIIODevice * dev_to) {return addChannel(devFPath(dev_from), devFPath(dev_to));}
-
- /*! \brief Remove from connection channel from "name_from" to "name_to"
- * \details "name_from" and "name_to" can be full pathes of devices or filter names.
- * Returns \b false if there if no such device or filter, else remove channel and returns \b true */
- bool removeChannel(const PIString & name_from, const PIString & name_to);
-
- //! Remove from connection channel from "name_from" to "dev_to"
- bool removeChannel(const PIString & name_from, const PIIODevice * dev_to) {return removeChannel(name_from, devFPath(dev_to));}
-
- //! Remove from connection channel from "dev_from" to "name_to"
- bool removeChannel(const PIIODevice * dev_from, const PIString & name_to) {return removeChannel(devFPath(dev_from), name_to);}
-
- //! Remove from connection channel from "dev_from" to "dev_to"
- bool removeChannel(const PIIODevice * dev_from, const PIIODevice * dev_to) {return removeChannel(devFPath(dev_from), devFPath(dev_to));}
-
- /*! \brief Remove from connection all channels from "name_from"
- * \details "name_from" can be full path of device or filter name.
- * Returns \b false if there if no such device or filter, else remove channels and returns \b true */
- bool removeChannel(const PIString & name_from);
-
- //! Remove from connection all channels from "dev_from"
- bool removeChannel(const PIIODevice * dev_from) {return removeChannel(devFPath(dev_from));}
-
- //! Remove from connection all channels
- void removeAllChannels();
-
- //! Returns all channels of this connection as full pathes or filter names pair array (from, to)
- PIVector > channels() const;
-
-
- //! Start read thread of device with full path "full_path"
- void startThreadedRead(const PIString & full_path);
-
- //! Start read thread of device "dev"
- void startThreadedRead(const PIIODevice * dev) {startThreadedRead(devFPath(dev));}
-
- //! Start read threads of all Device pool device
- void startAllThreadedReads();
-
- //! Stop read thread of device with full path "full_path"
- void stopThreadedRead(const PIString & full_path);
-
- //! Stop read thread of device "dev"
- void stopThreadedRead(const PIIODevice * dev) {stopThreadedRead(devFPath(dev));}
-
- //! Stop read threads of all Device pool device
- void stopAllThreadedReads();
-
-
- //! Returns if there is no devices in this connection
- bool isEmpty() const {return device_modes.isEmpty();}
-
-
- //! Write data "data" to device with full path "full_path" and returns result of \a write() function of device
- int write(const PIString & full_path, const PIByteArray & data);
-
-
- //! Returns all connections in application
- static PIVector allConnections();
-
- //! Returns all devices in Device pool
- static PIVector allDevices();
-
- class DevicePool: public PIObject {
- PIOBJECT(DevicePool)
- friend class PIConnection;
- public:
- DevicePool(): PIObject("PIConnection::DevicePool") {}
-
- PIIODevice * addDevice(PIConnection * parent, const PIString & fp, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite, bool start = true);
- bool removeDevice(PIConnection * parent, const PIString & fp);
- void unboundConnection(PIConnection * parent);
- PIIODevice * device(const PIString & fp) const;
- PIVector boundedConnections() const;
- PIVector boundedDevices() const;
- PIVector boundedDevices(const PIConnection * parent) const;
-
- protected:
- struct DeviceData {
- DeviceData(): dev(0), rthread(0), started(false) {}
- ~DeviceData();
- PIIODevice * dev;
- PIThread * rthread;
- bool started;
- PIVector listeners;
- };
-
- static void threadReadDP(void * ddp);
- void deviceReaded(DeviceData * dd, const PIByteArray & data);
-
- typedef PIMap::value_type DDPair;
- PIMap devices;
- };
-
- EVENT2(dataReceivedEvent, const PIString &, from, const PIByteArray &, data)
- EVENT2(packetReceivedEvent, const PIString &, from, const PIByteArray &, data)
-
-//! \events
-//! \{
-
- //! \fn void dataReceivedEvent(const PIString & from, const PIByteArray & data)
- //! \brief Raise on data received from device with full path "from"
-
- //! \fn void packetReceivedEvent(const PIString & from, const PIByteArray & data)
- //! \brief Raise on packet received from filter with name "from"
-
-//! \}
-
-protected:
-
- //! Executes on data received from device with full path "from"
- virtual void dataReceived(const PIString & from, const PIByteArray & data) {}
-
- //! Executes on packet received from filter with name "from"
- virtual void packetReceived(const PIString & from, const PIByteArray & data) {}
-
- //! Validate header "rec" with source header "src" and size "size", executes from filter "filter_name"
- virtual bool filterValidateHeader(const PIString & filter_name, uchar * src, uchar * rec, int size);
-
- //! Validate footer "rec" with source footer "src" and size "size", executes from filter "filter_name"
- virtual bool filterValidateFooter(const PIString & filter_name, uchar * src, uchar * rec, int size);
-
- //! Validate payload "rec" with size "size", executes from filter "filter_name"
- virtual bool filterValidatePayload(const PIString & filter_name, uchar * rec, int size);
-
-private:
- static bool filterValidateHeaderS(void * c, uchar * src, uchar * rec, int size);
- static bool filterValidateFooterS(void * c, uchar * src, uchar * rec, int size);
- static bool filterValidatePayloadS(void * c, uchar * rec, int size);
- void rawReceived(PIIODevice * dev, const PIString & from, const PIByteArray & data);
- void unboundExtractor(PIPacketExtractor * pe);
- EVENT_HANDLER2(void, packetExtractorReceived, uchar * , data, int, size);
-
- PIString devPath(const PIIODevice * d) const;
- PIString devFPath(const PIIODevice * d) const;
-
- struct Extractor {
- Extractor(): extractor(0) {}
- ~Extractor();
- PIPacketExtractor * extractor;
- PIVector devices;
- };
-
- typedef PIMap::value_type PEPair;
- typedef PIMap >::value_type BEPair;
- typedef PIMap >::value_type CPair;
- PIMap extractors;
- PIMap device_modes;
- PIMap > bounded_extractors;
- PIMap > channels_;
-
- static PIVector _connections;
-
-};
-
-
-extern PIConnection::DevicePool * __device_pool__;
-
-class __DevicePoolContainer__ {
-public:
- __DevicePoolContainer__();
- static bool inited_;
-};
-
-static __DevicePoolContainer__ __device_pool_container__;
-
-
-#endif // PICONNECTION_H
diff --git a/piconsole.cpp b/piconsole.cpp
deleted file mode 100644
index b5526dae..00000000
--- a/piconsole.cpp
+++ /dev/null
@@ -1,1011 +0,0 @@
-/*
- PIP - Platform Independent Primitives
- Console output/input
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#include "piconsole.h"
-#include "pipeer.h"
-
-
-/** \class PIConsole
- * \brief Console output class
- * \details
- * \section PIConsole_sec0 Synopsis
- * This class provides output to console with automatic alignment and update.
- * It supports tabs, keyboard listening, formats and colors.
- *
- * \section PIConsole_sec1 Layout
- * %PIConsole works with variable pointers. You should add your variables with
- * functions \a addVariable() which receives label name, pointer to variable
- * and optional column and format. Columns count is dynamically increased if
- * new column used. E.g. if you add variable to empty tab to column 3, columns
- * count will be increased to 3, but two firsts columns will be empty. Each column
- * filled from top to bottom, but you can add just string with function
- * \a addString() or add empty line with function \a addEmptyLine(). Layout scheme:
- * \image html piconsole_layout.png
- *
- * \section PIConsole_sec2 Keyboard usage
- * %PIConsole should to be single in application. %PIConsole aggregate PIKbdListener
- * which grab keyboard and automatic switch tabs by theirs bind keys. If there is no
- * tab binded to pressed key external function "slot" will be called
- *
- **/
-
-
-extern PIMutex __PICout_mutex__;
-
-
-PIConsole::PIConsole(bool startNow, KBFunc slot): PIThread() {
- setPriority(piLow);
- needLockRun(true);
- ret_func = slot;
- num_format = systime_format = 0;
- vid = 0;
- cur_tab = width = height = pwidth = pheight = max_y = 0;
- def_align = Nothing;
-#ifdef WINDOWS
- ulcoord.X = 0;
- hOut = GetStdHandle(STD_OUTPUT_HANDLE);
- GetConsoleScreenBufferInfo(hOut, &sbi);
- dattr = sbi.wAttributes;
- width = sbi.srWindow.Right - sbi.srWindow.Left;
- height = sbi.srWindow.Bottom - sbi.srWindow.Top;
- ulcoord.Y = sbi.srWindow.Top;
- GetConsoleMode(hOut, &smode);
- GetConsoleCursorInfo(hOut, &curinfo);
-#endif
- tabs.reserve(16);
- addTab("main");
- listener = new PIKbdListener(key_event, this);
- peer = 0;
- server_mode = false;
- state = Disconnected;
- peer_timer.addDelimiter(20);
- CONNECT2(void, void * , int, &peer_timer, timeout, this, peerTimer);
- if (startNow) start();
-}
-
-
-PIConsole::~PIConsole() {
- stopPeer();
- if (isRunning())
- stop();
- clearTabs(false);
- delete listener;
-#ifdef WINDOWS
- SetConsoleMode(hOut, smode);
- SetConsoleTextAttribute(hOut, dattr);
-#endif
-}
-
-
-int PIConsole::addTab(const PIString & name, char bind_key) {
- if (isRunning()) lock();
- tabs.push_back(Tab(name, bind_key));
- cur_tab = tabs.size() - 1;
- if (isRunning()) unlock();
- return tabs.size();
-}
-
-
-void PIConsole::removeTab(uint index) {
- if (index >= tabs.size()) return;
- if (isRunning()) lock();
- tabs.remove(index);
- if (cur_tab >= tabs.size()) cur_tab = tabs.size() - 1;
- if (isRunning()) unlock();
-}
-
-
-void PIConsole::removeTab(const PIString & name) {
- uint index = tabs.size() + 1;
- for (uint i = 0; i < tabs.size(); ++i) {
- if (tabs[i].name == name) {
- index = i;
- break;
- }
- }
- removeTab(index);
-}
-
-
-bool PIConsole::setTab(uint index) {
- if (index >= tabs.size())
- return false;
- if (!isRunning()) {
- cur_tab = index;
- return true;
- }
- lock();
- __PICout_mutex__.lock();
- cur_tab = index;
- clearScreen();
- fillLabels();
- __PICout_mutex__.unlock();
- unlock();
- return true;
-}
-
-
-bool PIConsole::setTab(const PIString & name) {
- uint index = tabs.size() + 1;
- for (uint i = 0; i < tabs.size(); ++i) {
- if (tabs[i].name == name) {
- index = i;
- break;
- }
- }
- return setTab(index);
-}
-
-
-bool PIConsole::setTabBindKey(uint index, char bind_key) {
- if (index >= tabs.size())
- return false;
- tabs[index].key = bind_key;
- return true;
-}
-
-
-bool PIConsole::setTabBindKey(const PIString & name, char bind_key) {
- uint index =tabs.size() + 1;
- for (uint i = 0; i < tabs.size(); ++i) {
- if (tabs[i].name == name) {
- index = i;
- break;
- }
- }
- return setTabBindKey(index, bind_key);
-}
-
-
-void PIConsole::key_event(char key, void * t) {
- PIConsole * p = (PIConsole * )t;
- int ct = p->cur_tab;
- if (key == char(PIKbdListener::LeftArrow)) {
- do {
- ct--;
- if (ct < 0) return;
- } while (p->tabs[ct].key == 0);
- p->setTab(ct);
- return;
- }
- if (key == char(PIKbdListener::RightArrow)) {
- do {
- ct++;
- if (ct >= p->tabs.size_s()) return;
- } while (p->tabs[ct].key == 0);
- p->setTab(ct);
- return;
- }
- for (uint i = 0; i < p->tabsCount(); ++i) {
- if (p->tabs[i].key == key) {
- p->setTab(i);
- return;
- }
- }
- if (p->ret_func != 0) p->ret_func(key, t);
- p->keyPressed(key, t);
-}
-
-
-void PIConsole::stop(bool clear) {
- PIThread::stop(true);
- if (clear) clearScreen();
- moveTo(0, max_y + 4);
- showCursor();
- couts(fstr(Normal));
-#ifdef WINDOWS
- SetConsoleMode(hOut, smode);
- SetConsoleTextAttribute(hOut, dattr);
-#endif
- fflush(0);
-}
-
-
-PIString PIConsole::fstr(PIFlags f) {
- num_format = systime_format = 0;
- if (f[PIConsole::Dec]) num_format = 0;
- if (f[PIConsole::Hex]) num_format = 1;
- if (f[PIConsole::Oct]) num_format = 2;
- if (f[PIConsole::Bin]) num_format = 4;
- if (f[PIConsole::Scientific]) num_format = 3;
- if (f[PIConsole::SystemTimeSplit]) systime_format = 0;
- if (f[PIConsole::SystemTimeSeconds]) systime_format = 1;
-
-#ifdef WINDOWS
- WORD attr = 0;
-
- if (f[PIConsole::Inverse]) {
- if (f[PIConsole::Red]) attr |= BACKGROUND_RED;
- if (f[PIConsole::Green]) attr |= BACKGROUND_GREEN;
- if (f[PIConsole::Blue]) attr |= BACKGROUND_BLUE;
- if (f[PIConsole::Yellow]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN);
- if (f[PIConsole::Magenta]) attr |= (BACKGROUND_RED | BACKGROUND_BLUE);
- if (f[PIConsole::Cyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE);
- if (f[PIConsole::White]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
- if (f[PIConsole::BackRed]) attr |= FOREGROUND_RED;
- if (f[PIConsole::BackGreen]) attr |= FOREGROUND_GREEN;
- if (f[PIConsole::BackBlue]) attr |= FOREGROUND_BLUE;
- if (f[PIConsole::BackYellow]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN);
- if (f[PIConsole::BackMagenta]) attr |= (FOREGROUND_RED | FOREGROUND_BLUE);
- if (f[PIConsole::BackCyan]) attr |= (FOREGROUND_GREEN | FOREGROUND_BLUE);
- if (f[PIConsole::BackWhite]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
- if ((attr & BACKGROUND_RED) + (attr & BACKGROUND_GREEN) + (attr & BACKGROUND_BLUE) == 0)
- attr |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
- } else {
- if (f[PIConsole::Red]) attr |= FOREGROUND_RED;
- if (f[PIConsole::Green]) attr |= FOREGROUND_GREEN;
- if (f[PIConsole::Blue]) attr |= FOREGROUND_BLUE;
- if (f[PIConsole::Yellow]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN);
- if (f[PIConsole::Magenta]) attr |= (FOREGROUND_RED | FOREGROUND_BLUE);
- if (f[PIConsole::Cyan]) attr |= (FOREGROUND_GREEN | FOREGROUND_BLUE);
- if (f[PIConsole::White]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
- if (f[PIConsole::BackRed]) attr |= BACKGROUND_RED;
- if (f[PIConsole::BackGreen]) attr |= BACKGROUND_GREEN;
- if (f[PIConsole::BackBlue]) attr |= BACKGROUND_BLUE;
- if (f[PIConsole::BackYellow]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN);
- if (f[PIConsole::BackMagenta]) attr |= (BACKGROUND_RED | BACKGROUND_BLUE);
- if (f[PIConsole::BackCyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE);
- if (f[PIConsole::BackWhite]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
- if ((attr & FOREGROUND_RED) + (attr & FOREGROUND_GREEN) + (attr & FOREGROUND_BLUE) == 0)
- attr |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
- }
- if (f[PIConsole::Bold]) attr |= FOREGROUND_INTENSITY;
- if (f[PIConsole::Underline]) attr |= COMMON_LVB_UNDERSCORE;
-
- SetConsoleTextAttribute(hOut, attr);
- return PIString();
-#else
- PIString ts("\e[0");
-
- if (f[PIConsole::Bold]) ts += ";1";
- if (f[PIConsole::Faint]) ts += ";2";
- if (f[PIConsole::Italic]) ts += ";3";
- if (f[PIConsole::Underline]) ts += ";4";
- if (f[PIConsole::Blink]) ts += ";5";
- if (f[PIConsole::Inverse]) ts += ";7";
-
- if (f[PIConsole::Black]) ts += ";30";
- if (f[PIConsole::Red]) ts += ";31";
- if (f[PIConsole::Green]) ts += ";32";
- if (f[PIConsole::Yellow]) ts += ";33";
- if (f[PIConsole::Blue]) ts += ";34";
- if (f[PIConsole::Magenta]) ts += ";35";
- if (f[PIConsole::Cyan]) ts += ";36";
- if (f[PIConsole::White]) ts += ";37";
-
- if (f[PIConsole::BackBlack]) ts += ";40";
- if (f[PIConsole::BackRed]) ts += ";41";
- if (f[PIConsole::BackGreen]) ts += ";42";
- if (f[PIConsole::BackYellow]) ts += ";43";
- if (f[PIConsole::BackBlue]) ts += ";44";
- if (f[PIConsole::BackMagenta]) ts += ";45";
- if (f[PIConsole::BackCyan]) ts += ";46";
- if (f[PIConsole::BackWhite]) ts += ";47";
-
- return ts + "m";
-#endif
-}
-
-
-inline int PIConsole::couts(const PIString & v) {return printf("%s", v.data());}
-inline int PIConsole::couts(const char * v) {return printf("%s", v);}
-inline int PIConsole::couts(const bool v) {return (v ? printf("true") : printf("false"));}
-inline int PIConsole::couts(const char v) {return printf("%c", v);}
-inline int PIConsole::couts(const short v) {
- switch (num_format) {case (1): return printf("0x%.4hX", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 2)); break; default: return printf("%hd", v); break;}
-}
-inline int PIConsole::couts(const int v) {
- switch (num_format) {case (1): return printf("0x%.8X", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 4)); break; default: return printf("%d", v); break;}
-}
-inline int PIConsole::couts(const long v) {
- switch (num_format) {case (1): return printf("0x%.16lX", v); break; case (2): return printf("%lo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%ld", v); break;}
-}
-inline int PIConsole::couts(const llong v) {
- switch (num_format) {case (1): return printf("0x%.16llX", v); break; case (2): return printf("%llo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%lld", v); break;}
-}
-inline int PIConsole::couts(const uchar v) {
- switch (num_format) {case (1): return printf("0x%.2X", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 1)); break; default: return printf("%u", v); break;}
-}
-inline int PIConsole::couts(const ushort v) {
- switch (num_format) {case (1): return printf("0x%.4hX", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 2)); break; default: return printf("%hu", v); break;}
-}
-inline int PIConsole::couts(const uint v) {
- switch (num_format) {case (1): return printf("0x%.8X", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 4)); break; default: return printf("%u", v); break;}
-}
-inline int PIConsole::couts(const ulong v) {
- switch (num_format) {case (1): return printf("0x%.16lX", v); break; case (2): return printf("%lo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%lu", v); break;}
-}
-inline int PIConsole::couts(const ullong v) {
- switch (num_format) {case (1): return printf("0x%.16llX", v); break; case (2): return printf("%llo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%llu", v); break;}
-}
-inline int PIConsole::couts(const float v) {
- switch (num_format) {case (3): return printf("%e", v); break; default: return printf("%.5g", v); break;}
-}
-inline int PIConsole::couts(const double v) {
- switch (num_format) {case (3): return printf("%le", v); break; default: return printf("%.5lg", v); break;}
-}
-inline int PIConsole::couts(const PISystemTime & v) {
- switch (systime_format) {case (1): return printf("%.6lg", v.toSeconds()); break;
- default: return couts(v.seconds) + printf(" s, ") + couts(v.nanoseconds) + printf(" ns"); break;}
-}
-
-
-void PIConsole::begin() {
-#ifdef WINDOWS
- SetConsoleMode(hOut, ENABLE_WRAP_AT_EOL_OUTPUT);
-#endif
- max_y = 0;
- __PICout_mutex__.lock();
- clearScreen();
- hideCursor();
- fillLabels();
- __PICout_mutex__.unlock();
-}
-
-
-void PIConsole::run() {
- uint cx, clen = 0;
- int j;
-#ifdef WINDOWS
- GetConsoleScreenBufferInfo(hOut, &sbi);
- width = sbi.srWindow.Right - sbi.srWindow.Left;
- height = sbi.srWindow.Bottom - sbi.srWindow.Top;
-#else
- winsize ws;
- ioctl(0, TIOCGWINSZ, &ws);
- width = ws.ws_col;
- height = ws.ws_row;
-#endif
- //fflush(0); return;
- __PICout_mutex__.lock();
- if (pwidth != width || pheight != height) {
- clearScreen();
- fillLabels();
- }
- pwidth = width;
- pheight = height;
- col_cnt = columns().size();
- col_wid = (col_cnt > 0) ? width / col_cnt : width;
- for (uint i = 0; i < col_cnt; ++i) {
- PIVector & cvars(tabs[cur_tab].columns[i].variables);
- cx = col_wid * i;
- toUpperLeft();
- if (max_y < cvars.size()) max_y = cvars.size();
- j = 0;
- piForeachC (Variable & tv, cvars) {
- if (j > height - 3) continue;
- j++;
- moveRight(cx);
- if (tv.type == 15) {
- newLine();
- continue;
- }
- moveRight(tv.offset);
- const void * ptr = 0;
- if (tv.remote) {
- if (tv.type == 0) {
- rstr.clear();
- rba = tv.rdata;
- rba >> rstr;
- rstr.trim();
- ptr = &rstr;
- } else
- ptr = tv.rdata.data();
- } else
- ptr = tv.ptr;
- switch (tv.type) {
- case 0: clen = printValue(ptr != 0 ? *(const PIString*)ptr : PIString(), tv.format); break;
- case 1: clen = printValue(ptr != 0 ? *(const bool*)ptr : false, tv.format); break;
- case 2: clen = printValue(ptr != 0 ? *(const int*)ptr : 0, tv.format); break;
- case 3: clen = printValue(ptr != 0 ? *(const long*)ptr : 0l, tv.format); break;
- case 4: clen = printValue(ptr != 0 ? *(const char*)ptr : char(0), tv.format); break;
- case 5: clen = printValue(ptr != 0 ? *(const float*)ptr : 0.f, tv.format); break;
- case 6: clen = printValue(ptr != 0 ? *(const double*)ptr : 0., tv.format); break;
- case 7: clen = printValue(ptr != 0 ? *(const short*)ptr : short(0), tv.format); break;
- case 8: clen = printValue(ptr != 0 ? *(const uint*)ptr : 0u, tv.format); break;
- case 9: clen = printValue(ptr != 0 ? *(const ulong*)ptr : 0ul, tv.format); break;
- case 10: clen = printValue(ptr != 0 ? *(const ushort*)ptr : ushort(0), tv.format); break;
- case 11: clen = printValue(ptr != 0 ? *(const uchar*)ptr : uchar(0), tv.format); break;
- case 12: clen = printValue(ptr != 0 ? *(const llong*)ptr : 0l, tv.format); break;
- case 13: clen = printValue(ptr != 0 ? *(const ullong*)ptr: 0ull, tv.format); break;
- case 20: clen = printValue(ptr != 0 ? *(const PISystemTime*)ptr: PISystemTime(), tv.format); break;
- case 14: clen = printValue(bitsValue(ptr, tv.bitFrom, tv.bitCount), tv.format); break;
- }
- if (clen + tv.offset < (uint)col_wid) {
- PIString ts = PIString(
-#if defined(QNX) || defined(FREE_BSD)
- col_wid - clen - tv.offset - 1, ' ');
-#else
- col_wid - clen - tv.offset, ' ');
-#endif
- printf("%s", ts.data());
- }
- newLine();
- }
- }
-#ifdef WINDOWS
- moveTo(0, max_y + 1);
-#else
- moveTo(0, max_y + 2);
-#endif
- fflush(0);
- __PICout_mutex__.unlock();
-}
-
-
-void PIConsole::fillLabels() {
- if (!isRunning()) return;
- uint cx, cy, mx = 0, dx;
-#ifdef WINDOWS
- GetConsoleScreenBufferInfo(hOut, &sbi);
- width = sbi.srWindow.Right - sbi.srWindow.Left;
- height = sbi.srWindow.Bottom - sbi.srWindow.Top;
-#else
- winsize ws;
- ioctl(0, TIOCGWINSZ, &ws);
- width = ws.ws_col;
- height = ws.ws_row;
-#endif
- max_y = 0;
- col_cnt = columns().size();
- col_wid = (col_cnt > 0) ? width / col_cnt : width;
- for (uint i = 0; i < col_cnt; ++i) {
- Column & ccol(tabs[cur_tab].columns[i]);
- PIVector & cvars(ccol.variables);
- if (ccol.alignment != Nothing) {
- mx = 0;
- piForeachC (Variable & j, cvars)
- if (!j.isEmpty())
- if (mx < j.name.size())
- mx = j.name.size();
- mx += 2;
- }
- cx = col_wid * i;
- cy = 1;
- toUpperLeft();
- for (uint j = 0; j < cvars.size(); ++j) {
- if (int(j) > height - 3) continue;
- if (max_y < j) max_y = j;
- moveRight(cx);
- Variable & tv(cvars[j]);
- cvars[j].nx = cx;
- cvars[j].ny = cy;
- if (tv.name.isEmpty()) {
- cvars[j].offset = 0;
- clearLine();
- newLine();
- cy++;
- continue;
- }
- clearLine();
- //piCout << tv.name << tv.type << tv.ptr;
- if (tv.type == 15) {
- cvars[j].offset = cvars[j].name.length();
- cvars[j].nx += cvars[j].offset;
- printLine(tv.name, cx, tv.format);
- newLine();
- cy++;
- continue;
- }
- if (!tv.isEmpty()) {
- switch (ccol.alignment) {
- case Nothing:
- cvars[j].offset = (tv.name + ": ").length();
- cvars[j].nx += cvars[j].offset;
- printValue(tv.name + ": ", tv.format);
- break;
- case Left:
- cvars[j].offset = mx;
- cvars[j].nx += cvars[j].offset;
- printValue(tv.name + ": ", tv.format);
- break;
- case Right:
- cvars[j].offset = mx;
- cvars[j].nx += cvars[j].offset;
- dx = mx - (tv.name + ": ").length();
- moveRight(dx);
- printValue(tv.name + ": ", tv.format);
- moveLeft(dx);
- break;
- }
- }
- newLine();
- cy++;
- }
- }
-#ifdef WINDOWS
- moveTo(0, max_y + 1);
-#else
- moveTo(0, max_y + 2);
-#endif
- if (!tabs[cur_tab].status.isEmpty()) {
- printValue(tabs[cur_tab].status);
- newLine();
- }
- status();
- //fflush(0);
-}
-
-
-void PIConsole::status() {
- Tab * ctab;
- //clearLine();
- for (uint i = 0; i < tabsCount(); ++i) {
- ctab = &tabs[i];
- if (ctab->key == 0) continue;
- printValue(ctab->key, PIConsole::White | PIConsole::Bold);
- if (i == cur_tab)
- printValue(ctab->name + " ", PIConsole::BackYellow | PIConsole::Black);
- else
- printValue(ctab->name + " ", PIConsole::Cyan | PIConsole::Inverse);
- printValue(" ");
- }
- newLine();
-}
-
-
-int PIConsole::bitsValue(const void * src, int offset, int count) const {
- int ret = 0, stbyte = offset / 8, cbit = offset - stbyte * 8;
- char cbyte = reinterpret_cast(src)[stbyte];
- for (int i = 0; i < count; i++) {
- ret |= ((cbyte >> cbit & 1) << i);
- cbit++;
- if (cbit == 8) {
- cbit = 0;
- stbyte++;
- cbyte = reinterpret_cast(src)[stbyte];
- }
- }
- return ret;
-}
-
-
-const char * PIConsole::toBin(const void * d, int s) {
- binstr.clear();
- uchar cc, b;
- for (int i = 0; i < s; ++i) {
- cc = ((const uchar *)d)[i];
- b = 1;
- for (int j = 0; j < 8; ++j) {
- binstr << (cc & b ? "1" : "0");
- b <<= 1;
- }
- if (i < s - 1) binstr << " ";
- }
- binstr.reverse();
- return binstr.data();
-}
-
-
-#define ADD_VAR_BODY vid++; tv.id = vid; tv.name = name; tv.bitFrom = tv.bitCount = 0; tv.format = format; tv.remote = false; checkColumn(col);
-
-void PIConsole::addString(const PIString & name, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 15; tv.size = 0; tv.ptr = 0; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const PIString * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 0; tv.size = 0; tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const bool * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 1; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const int * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 2; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const long * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 3; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const char * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 4; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const float * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 5; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const double * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 6; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const short * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 7; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const uint * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 8; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const ulong * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 9; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const ushort * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 10; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const uchar * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 11; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const llong * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 12; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const ullong * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 13; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-void PIConsole::addVariable(const PIString & name, const PISystemTime * ptr, int col, PIFlags format) {
- ADD_VAR_BODY tv.type = 20; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
-/** \brief Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- * \details This function add to column "column" next lines:
- * * "protocol "
- * * "Rec - receiverDeviceName": \a PIProtocol::receiverDeviceState
- * * "Send - senderDeviceName": \a PIProtocol::senderDeviceState
- * * "Received count": \a PIProtocol::receiveCount
- * * "Invalid count": \a PIProtocol::wrongCount
- * * "Missed count": \a PIProtocol::missedCount
- * * "Sended count": \a PIProtocol::sendCount
- * * "Immediate Frequency, Hz": \a PIProtocol::immediateFrequency
- * * "Integral Frequency, Hz": \a PIProtocol::integralFrequency
- * * "Receive speed": \a PIProtocol::receiveSpeed
- * * "Send speed": \a PIProtocol::sendSpeed
- * * "Receiver history size": \a PIProtocol::receiverHistorySize
- * * "Sender history size": \a PIProtocol::senderHistorySize
- * * "Disconnect Timeout, s": \a PIProtocol::disconnectTimeout
- * * "Quality": \a PIProtocol::quality
- * */
-void PIConsole::addVariable(const PIString & name, const PIProtocol * ptr, int col, PIFlags format) {
- addString("protocol " + name, col, format | PIConsole::Bold);
- addVariable("Rec - " + ptr->receiverDeviceName(), ptr->receiverDeviceState_ptr(), col, format);
- addVariable("Send - " + ptr->senderDeviceName(), ptr->senderDeviceState_ptr(), col, format);
- addVariable("Received count", ptr->receiveCount_ptr(), col, format);
- addVariable("Invalid count", ptr->wrongCount_ptr(), col, format);
- addVariable("Missed count", ptr->missedCount_ptr(), col, format);
- addVariable("Sended count", ptr->sendCount_ptr(), col, format);
- addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), col, format);
- addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), col, format);
- addVariable("Receive speed", ptr->receiveSpeed_ptr(), col, format);
- addVariable("Send speed", ptr->sendSpeed_ptr(), col, format);
- addVariable("Receiver history size", ptr->receiverHistorySize_ptr(), col, format);
- addVariable("Sender history size", ptr->senderHistorySize_ptr(), col, format);
- addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), col, format);
- addVariable("Quality", ptr->quality_ptr(), col, format);
-}
-/** \brief Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- * \details This function add to column "column" next lines:
- * * " diagnostics"
- * * "Received count": \a PIDiagnostics::receiveCount
- * * "Invalid count": \a PIDiagnostics::wrongCount
- * * "Sended count": \a PIDiagnostics::sendCount
- * * "Immediate Frequency, Hz": \a PIDiagnostics::immediateFrequency
- * * "Integral Frequency, Hz": \a PIDiagnostics::integralFrequency
- * * "Receive speed": \a PIDiagnostics::receiveSpeed
- * * "Send speed": \a PIDiagnostics::sendSpeed
- * * "Quality": \a PIDiagnostics::quality
- * */
-void PIConsole::addVariable(const PIString & name, const PIDiagnostics * ptr, int col, PIFlags format) {
- addString(name + " diagnostics", col, format | PIConsole::Bold);
- addVariable("Received count", ptr->receiveCount_ptr(), col, format);
- addVariable("Invalid count", ptr->wrongCount_ptr(), col, format);
- addVariable("Sended count", ptr->sendCount_ptr(), col, format);
- addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), col, format);
- addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), col, format);
- addVariable("Receive speed", ptr->receiveSpeed_ptr(), col, format);
- addVariable("Send speed", ptr->sendSpeed_ptr(), col, format);
- addVariable("Quality", ptr->quality_ptr(), col, format);
-}
-void PIConsole::addVariable(const PIString & name, const PISystemMonitor * ptr, int col, PIFlags format) {
- addString("monitor " + name, col, format | PIConsole::Bold);
- addVariable("state", &(ptr->statistic().state), col, format);
- addVariable("threads", &(ptr->statistic().threads), col, format);
- addVariable("priority", &(ptr->statistic().priority), col, format);
- addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), col, format);
- addVariable("memory shared", &(ptr->statistic().share_memsize_readable), col, format);
- addVariable("cpu load", &(ptr->statistic().cpu_load_user), col, format);
-}
-void PIConsole::addBitVariable(const PIString & name, const void * ptr, int fromBit, int bitCount, int col, PIFlags format) {
- vid++; tv.id = vid; tv.size = sizeof(ullong); tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.ptr = ptr; tv.format = format;
- checkColumn(col); column(col).push_back(tv);}
-void PIConsole::addEmptyLine(int col, uint count) {
- tv.id = 0; tv.size = 0; tv.name = ""; tv.type = 0; tv.ptr = 0; tv.format = Normal;
- for (uint i = 0; i < count; ++i) {
- checkColumn(col);
- column(col).push_back(tv);
- }
-}
-
-
-PIString PIConsole::getString(int x, int y) {
- bool run = isRunning();
- if (run) PIThread::stop(true);
- listener->setActive(false);
- msleep(50);
-#ifdef WINDOWS
- moveTo(x - 1, y - 1);
-#else
- moveTo(x, y);
-#endif
- showCursor();
- PIByteArray ba(4096);
-#ifdef CC_VC
- int ret = scanf_s(" %s", ba.data());
-#else
- int ret = scanf(" %s", ba.data());
-#endif
- listener->setActive(true);
- if (run) start();
- if (ret >= 1) return PIString(ba);
- else return PIString();
-}
-
-
-PIString PIConsole::getString(const PIString & name) {
- piForeachC (Column & i, tabs[cur_tab].columns)
- piForeachC (Variable & j, i.variables)
- if (j.name == name)
- return getString(j.nx + 1, j.ny);
- return PIString();
-}
-
-
-#define PRINT_VAR_BODY couts(fstr(format)); int ret = couts(value); couts(fstr(PIConsole::Dec)); return ret;
-
-inline void PIConsole::printLine(const PIString & value, int dx, PIFlags format) {
- int i = width - value.length() - dx;
-#if defined(QNX) || defined(FREE_BSD)
- --i;
-#endif
- PIString ts = fstr(format);
- couts(ts);
- if (i >= 0) ts = value + PIString(i, ' ');
- else ts = value.left(value.size() + i);
- couts(ts);
- couts(fstr(Dec));
-}
-inline int PIConsole::printValue(const PIString & value, PIFlags format) {
- couts(fstr(format));
- int ret = couts(value);
- fstr(PIConsole::Dec);
- return ret;
-}
-inline int PIConsole::printValue(const char * value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const bool value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const int value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const long value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const llong value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const float value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const double value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const char value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const short value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const uchar value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const ushort value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const uint value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const ulong value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const ullong value, PIFlags format) {PRINT_VAR_BODY}
-inline int PIConsole::printValue(const PISystemTime & value, PIFlags format) {PRINT_VAR_BODY}
-
-
-
-void PIConsole::startServer(const PIString & name) {
- stopPeer();
- server_mode = true;
- peer = new PIPeer("_rcs_:" + name);
- CONNECT2(void, const PIString & , const PIByteArray &, peer, dataReceivedEvent, this, peerReceived);
- CONNECT1(void, const PIString & , peer, peerDisconnectedEvent, this, peerDisconnectedEvent);
- peer_timer.start(50.);
- serverSendInfo();
-}
-
-
-void PIConsole::stopPeer() {
- remote_clients.clear();
- peer_timer.stop();
- if (peer != 0) delete peer;
- peer = 0;
- state = Disconnected;
-}
-
-
-PIStringList PIConsole::clients() const {
- PIStringList sl;
- if (peer == 0) return sl;
- piForeachC (PIPeer::PeerInfo & i, peer->allPeers()) {
- if (i.name.left(6) != "_rcc_:") continue;
- sl << i.name.right(i.name.length() - 6);
- }
- return sl;
-}
-
-
-void PIConsole::listenServers() {
- stopPeer();
- server_mode = false;
- server_name.clear();
- srand(PISystemTime::current().nanoseconds);
- peer = new PIPeer("_rcc_:" + PIDateTime::current().toString("hhmmssddMMyy_") + PIString::fromNumber(rand()));
- CONNECT2(void, const PIString & , const PIByteArray &, peer, dataReceivedEvent, this, peerReceived);
- peer_timer.start(100.);
-}
-
-
-PIStringList PIConsole::availableServers() const {
- PIStringList sl;
- if (peer == 0) return sl;
- piForeachC (PIPeer::PeerInfo & i, peer->allPeers()) {
- if (i.name.left(6) != "_rcs_:") continue;
- sl << i.name.right(i.name.length() - 6);
- }
- return sl;
-}
-
-
-void PIConsole::connectToServer(const PIString & name) {
- if (peer == 0) listenServers();
- server_name = name;
-}
-
-
-void PIConsole::disconnect() {
- stopPeer();
-}
-
-
-void PIConsole::serverSendInfo() {
- if (peer == 0) return;
- PIByteArray ba;
- ba << int(0xAA);
- peer->sendToAll(ba);
-}
-
-
-void PIConsole::serverSendData() {
- if (peer == 0) return;
- PIByteArray ba;
- PIVector content;
- piForeach (Tab & t, tabs)
- piForeach (Column & c, t.columns)
- piForeach (Variable & v, c.variables)
- if (!v.isEmpty() && v.id > 0) {
- VariableContent vc;
- vc.id = v.id;
- v.writeData(vc.rdata);
- content << vc;
- }
- piForeach (RemoteClient & rc, remote_clients) {
- ba.clear();
- switch (rc.state) {
- case FetchingData:
- ba << int(0xCC) << tabs;
- //piCout << "server send const data" << rc.name << ba.size_s();
- break;
- case Committing:
- ba << int(0xDD);
- break;
- case Connected:
- ba << int(0xEE) << content;
- //piCout << "send data" << ba.size();
- break;
- default: break;
- }
- if (!ba.isEmpty())
- peer->send(rc.name, ba);
- }
-}
-
-
-PIConsole::RemoteClient & PIConsole::remoteClient(const PIString & fname) {
- piForeach (RemoteClient & i, remote_clients)
- if (i.name == fname)
- return i;
- remote_clients << RemoteClient(fname);
- return remote_clients.back();
-}
-
-
-void PIConsole::peerReceived(const PIString & from, const PIByteArray & data) {
- int type;
- PIByteArray ba(data);
- ba >> type;
- //piCout << "rec packet from" << from << "type" << PICoutManipulators::Hex << type;
- if (server_mode) {
- if (from.left(5) != "_rcc_") return;
- //PIString rcn = from.right(from.length() - 6);
- RemoteClient & rc(remoteClient(from));
- switch (type) {
- case 0xBB: // fetch const data request
- //piCout << "fetch data request from" << from << rc.state;
- if (rc.state != Connected)
- rc.state = FetchingData;
- break;
- case 0xCC: // const data commit
- //piCout << "commit from" << from;
- if (rc.state != Connected)
- rc.state = Connected;
- break;
- default: break;
- }
- } else {
- PIVector content;
- PIMap vids;
- if (from.left(5) != "_rcs_") return;
- PIString rcn = from.right(from.length() - 6);
- switch (type) {
- case 0xAA: // new server
- //piCout << "new server" << rcn;
- break;
- case 0xCC: // const data
- //piCout << "received const data";
- state = Committing;
- ba >> tabs;
- cur_tab = tabs.isEmpty() ? -1 : 0;
- piForeach (Tab & t, tabs)
- piForeach (Column & c, t.columns)
- piForeach (Variable & v, c.variables)
- v.remote = true;
- break;
- case 0xDD: // const data commit
- //piCout << "received commit";
- state = Connected;
- break;
- case 0xEE: // dynamic data
- //piCout << "received data" << ba.size_s();
- piForeach (Tab & t, tabs)
- piForeach (Column & c, t.columns)
- piForeach (Variable & v, c.variables)
- if (!v.isEmpty() && v.id > 0)
- vids[v.id] = &v;
- ba >> content;
- piForeach (VariableContent & vc, content) {
- if (vc.id <= 0) continue;
- Variable * v = vids.at(vc.id);
- if (v == 0) continue;
- //piCout << "read" << v->name << vc.rdata.size_s();
- v->rdata = vc.rdata;
- }
- break;
- default: break;
- }
- }
-}
-
-
-void PIConsole::peerTimer(void * data, int delim) {
- if (peer == 0) return;
- //piCout << "timer" << delim;
- if (server_mode) {
- if (delim == 20)
- serverSendInfo();
- else
- serverSendData();
- } else {
- if (delim != 1 || server_name.isEmpty()) return;
- const PIPeer::PeerInfo * p = peer->getPeerByName("_rcs_:" + server_name);
- if (p == 0) return;
- PIByteArray ba;
- switch (state) {
- case Disconnected:
- peer_timer.reset();
- ba << int(0xBB);
- //piCout << "send to" << server_name << "fetch request disc";
- peer->send(p, ba);
- state = FetchingData;
- break;
- case FetchingData:
- if (peer_timer.elapsed_s() < 3.)
- return;
- peer_timer.reset();
- ba << int(0xBB);
- //piCout << "send to" << server_name << "fetch request fd";
- peer->send(p, ba);
- break;
- case Committing:
- peer_timer.reset();
- ba << int(0xCC);
- //piCout << "send to" << server_name << "committing";
- state = Connected;
- peer->send(p, ba);
- break;
- default: break;
- };
- }
-}
-
-
-void PIConsole::peerDisconnectedEvent(const PIString & name) {
- for (int i = 0; i < remote_clients.size_s(); ++i)
- if (remote_clients[i].name == name) {
- remote_clients.remove(i);
- --i;
- }
-}
diff --git a/piconsole.h b/piconsole.h
deleted file mode 100644
index 429fdd53..00000000
--- a/piconsole.h
+++ /dev/null
@@ -1,489 +0,0 @@
-/*! \file piconsole.h
- * \brief Console output class
-*/
-/*
- PIP - Platform Independent Primitives
- Console output/input
- Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#ifndef PICONSOLE_H
-#define PICONSOLE_H
-
-#include "pikbdlistener.h"
-#include "piprotocol.h"
-#include "pidiagnostics.h"
-#include "pisystemmonitor.h"
-#ifndef WINDOWS
-# include
-# include
-#else
-# define COMMON_LVB_UNDERSCORE 0x8000
-#endif
-
-class PIPeer;
-
-class PIP_EXPORT PIConsole: public PIThread
-{
- PIOBJECT(PIConsole)
-public:
-
- //! Constructs %PIConsole with key handler "slot" and if "startNow" start it
- PIConsole(bool startNow = true, KBFunc slot = 0);
-
- ~PIConsole();
-
-
- //! Variables output format
- enum Format {
- Normal /** Default console format */ = 0x01,
- Bold /** Bold text */ = 0x02,
- Faint = 0x04,
- Italic = 0x08,
- Underline /** Underlined text */ = 0x10,
- Blink /** Blinked text */ = 0x20,
- Inverse /** Swap text and background colors */ = 0x40,
- Black /** Black text */ = 0x100,
- Red /** Red text */ = 0x200,
- Green /** Green text */ = 0x400,
- Yellow /** Yellow text */ = 0x800,
- Blue /** Blue text */ = 0x1000,
- Magenta /** Magenta text */ = 0x2000,
- Cyan /** Cyan text */ = 0x4000,
- White /** White text */ = 0x8000,
- BackBlack /** Black background */ = 0x10000,
- BackRed /** Red background */ = 0x20000,
- BackGreen /** Green background */ = 0x40000,
- BackYellow /** Yellow background */ = 0x80000,
- BackBlue /** Blue background */ = 0x100000,
- BackMagenta /** Magenta background */ = 0x200000,
- BackCyan /** Cyan background */ = 0x400000,
- BackWhite /** White background */ = 0x800000,
- Dec /** Decimal base for integers */ = 0x1000000,
- Hex /** Hexadecimal base for integers */ = 0x2000000,
- Oct /** Octal base for integers */ = 0x4000000,
- Bin /** Binary base for integers */ = 0x8000000,
- Scientific /** Scientific representation of floats */ = 0x10000000,
- SystemTimeSplit /** PISystemTime split representation (* s, * ns) */ = 0x20000000,
- SystemTimeSeconds /** PISystemTime seconds representation (*.* s) */ = 0x40000000
- };
-
- //! Column labels alignment
- enum Alignment {
- Nothing /** No alignment */ ,
- Left /** Labels align left and variables align left */ ,
- Right /** Labels align right and variables align left */
- };
-
- //! Add to current tab to column "column" string "name" with format "format"
- void addString(const PIString & name, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const PIString * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const char * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const bool * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const short * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const int * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const long * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const llong * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const uchar * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const ushort * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const uint * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const ulong * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const ullong * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const float * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const double * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
- void addVariable(const PIString & name, const PISystemTime * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- void addVariable(const PIString & name, const PIProtocol * ptr, int column = 1, PIFlags format = PIConsole::Normal);
- void addVariable(const PIString & name, const PIDiagnostics * ptr, int column = 1, PIFlags format = PIConsole::Normal);
- void addVariable(const PIString & name, const PISystemMonitor * ptr, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" bits field with label "name", pointer "ptr" and format "format"
- void addBitVariable(const PIString & name, const void * ptr, int fromBit, int bitsCount, int column = 1, PIFlags format = PIConsole::Normal);
-
- //! Add to current tab to column "column" "count" empty lines
- void addEmptyLine(int column = 1, uint count = 1);
-
- PIString getString(int x, int y);
- short getShort(int x, int y) {return getString(x, y).toShort();}
- int getInt(int x, int y) {return getString(x, y).toInt();}
- float getFloat(int x, int y) {return getString(x, y).toFloat();}
- double getDouble(int x, int y) {return getString(x, y).toDouble();}
- PIString getString(const PIString & name);
- short getShort(const PIString & name) {return getString(name).toShort();}
- int getInt(const PIString & name) {return getString(name).toInt();}
- float getFloat(const PIString & name) {return getString(name).toFloat();}
- double getDouble(const PIString & name) {return getString(name).toDouble();}
-
-
- //! Returns tabs count
- uint tabsCount() const {return tabs.size();}
-
- //! Returns current tab name
- PIString currentTab() const {return tabs[cur_tab].name;}
-
- //! Add new tab with name "name", bind key "bind_key" and returns this tab index
- int addTab(const PIString & name, char bind_key = 0);
-
- //! Remove tab with index "index"
- void removeTab(uint index);
-
- //! Remove tab with name "name"
- void removeTab(const PIString & name);
-
- //! Set current tab to tab with index "index", returns if tab exists
- bool setTab(uint index);
-
- //! Set current tab to tab with name "name", returns if tab exists
- bool setTab(const PIString & name);
-
- //! Set tab with index "index" bind key to "bind_key", returns if tab exists
- bool setTabBindKey(uint index, char bind_key);
-
- //! Set tab with name "name" bind key to "bind_key", returns if tab exists
- bool setTabBindKey(const PIString & name, char bind_key);
-
- //! Remove all tabs and if "clearScreen" clear the screen
- void clearTabs(bool clearScreen = true) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} tabs.clear();}
-
-
- //! Set custom status text of current tab to "str"
- void addCustomStatus(const PIString & str) {tabs[cur_tab].status = str;}
-
- //! Clear custom status text of current tab
- void clearCustomStatus() {tabs[cur_tab].status.clear();}
-
- //! Returns default alignment
- Alignment defaultAlignment() const {return def_align;}
-
- //! Set default alignment to "align"
- void setDefaultAlignment(Alignment align) {def_align = align;}
-
- //! Set column "col" alignment to "align"
- void setColumnAlignment(int col, Alignment align) {if (col < 0 || col >= columns().size_s()) return; column(col).alignment = align;}
-
- //! Set all columns of all tabs alignment to "align"
- void setColumnAlignmentToAll(Alignment align) {piForeach (Tab & i, tabs) piForeach (Column & j, i.columns) j.alignment = align; fillLabels();}
- PIString fstr(PIFlags f);
-
-
- //! Directly call function from \a PIKbdListener
- void enableExitCapture(char key = 'Q') {listener->enableExitCapture(key);}
-
- //! Directly call function from \a PIKbdListener
- void disableExitCapture() {listener->disableExitCapture();}
-
- //! Directly call function from \a PIKbdListener
- bool exitCaptured() const {return listener->exitCaptured();}
-
- //! Directly call function from \a PIKbdListener
- char exitKey() const {return listener->exitKey();}
-
- // Server functions
- void startServer(const PIString & name);
- void stopPeer();
- bool isServerStarted() const {return peer != 0;}
- PIStringList clients() const;
-
- // Client functions
- void listenServers();
- PIStringList availableServers() const;
- PIString selectedServer() const {return server_name;}
- void connectToServer(const PIString & name);
- void disconnect();
- bool isConnected() const {return state == Connected;}
-
-#ifdef WINDOWS
- void toUpperLeft() {SetConsoleCursorPosition(hOut, ulcoord);}
- void moveRight(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(n));}
- void moveLeft(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(-n));}
- void moveTo(int x = 0, int y = 0) {ccoord.X = x; ccoord.Y = ulcoord.Y + y; SetConsoleCursorPosition(hOut, ccoord);}
- void clearScreen() {toUpperLeft(); FillConsoleOutputAttribute(hOut, dattr, width * (height + 1), ulcoord, &written);
- FillConsoleOutputCharacter(hOut, ' ', width * (height + 1), ulcoord, &written);}
- void clearScreenLower() {getWinCurCoord(); FillConsoleOutputAttribute(hOut, dattr, width * height - width * ccoord.Y + ccoord.X, ccoord, &written);
- FillConsoleOutputCharacter(hOut, ' ', width * height - width * ccoord.Y + ccoord.X, ccoord, &written);}
- void clearLine() {getWinCurCoord(); FillConsoleOutputAttribute(hOut, dattr, width - ccoord.X, ccoord, &written);
- FillConsoleOutputCharacter(hOut, ' ', width - ccoord.X, ccoord, &written);}
- void newLine() {getWinCurCoord(); ccoord.X = 0; ccoord.Y++; SetConsoleCursorPosition(hOut, ccoord);}
- void hideCursor() {curinfo.bVisible = false; SetConsoleCursorInfo(hOut, &curinfo);}
- void showCursor() {curinfo.bVisible = true; SetConsoleCursorInfo(hOut, &curinfo);}
-#else
- void toUpperLeft() {printf("\e[H");}
- void moveRight(int n = 1) {if (n > 0) printf("\e[%dC", n);}
- void moveLeft(int n = 1) {if (n > 0) printf("\e[%dD", n);}
- void moveTo(int x = 0, int y = 0) {printf("\e[%d;%dH", y, x);}
- void clearScreen() {printf("\e[H\e[J");}
- void clearScreenLower() {printf("\e[J");}
- void clearLine() {printf("\e[K");}
- void newLine() {printf("\eE");}
- void hideCursor() {printf("\e[?25l");}
- void showCursor() {printf("\e[?25h");}
-#endif
-
- EVENT_HANDLER0(void, clearVariables) {clearVariables(true);}
- EVENT_HANDLER1(void, clearVariables, bool, clearScreen) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} columns().clear();}
-
- EVENT_HANDLER0(void, waitForFinish) {WAIT_FOR_EXIT}
- EVENT_HANDLER0(void, start) {start(false);}
- EVENT_HANDLER1(void, start, bool, wait) {PIThread::start(40); if (wait) waitForFinish();}
- EVENT_HANDLER0(void, stop) {stop(false);}
- EVENT_HANDLER1(void, stop, bool, clear);
-
- EVENT2(keyPressed, char, key, void * , data)
-
-//! \handlers
-//! \{
-
- //! \fn void waitForFinish()
- //! \brief block until finished (exit key will be pressed)
-
- //! \fn void clearVariables(bool clearScreen = true)
- //! \brief Remove all columns at current tab and if "clearScreen" clear the screen
-
- //! \fn void start(bool wait = false)
- //! \brief Start console output and if "wait" block until finished (exit key will be pressed)
-
- //! \fn void stop(bool clear = false)
- //! \brief Stop console output and if "clear" clear the screen
-
-//! \}
-//! \events
-//! \{
-
- //! \fn void keyPressed(char key, void * data)
- //! \brief Raise on key "key" pressed, "data" is pointer to %PIConsole object
-
-//! \}
-
-private:
-#ifdef WINDOWS
- void getWinCurCoord() {GetConsoleScreenBufferInfo(hOut, &csbi); ccoord = csbi.dwCursorPosition;}
- COORD & getWinCoord(int dx = 0, int dy = 0) {getWinCurCoord(); ccoord.X += dx; ccoord.Y += dy; return ccoord;}
-#endif
-
- void begin();
- void run();
- void fillLabels();
- void status();
- void checkColumn(uint col) {while (columns().size() < col) columns().push_back(Column(def_align));}
- int bitsValue(const void * src, int offset, int count) const;
- const char * toBin(const void * d, int s);
- inline void printLine(const PIString & str, int dx = 0, PIFlags format = PIConsole::Normal);
- inline int printValue(const PIString & str, PIFlags format = PIConsole::Normal);
- inline int printValue(const char * str, PIFlags format = PIConsole::Normal);
- inline int printValue(const bool value, PIFlags format = PIConsole::Normal);
- inline int printValue(const int value, PIFlags format = PIConsole::Normal);
- inline int printValue(const long value, PIFlags format = PIConsole::Normal);
- inline int printValue(const llong value, PIFlags format = PIConsole::Normal);
- inline int printValue(const float value, PIFlags format = PIConsole::Normal);
- inline int printValue(const double value, PIFlags format = PIConsole::Normal);
- inline int printValue(const char value, PIFlags format = PIConsole::Normal);
- inline int printValue(const short value, PIFlags format = PIConsole::Normal);
- inline int printValue(const uchar value, PIFlags format = PIConsole::Normal);
- inline int printValue(const ushort value, PIFlags format = PIConsole::Normal);
- inline int printValue(const uint value, PIFlags