From f0f3204834b75d17c76c7b0cf7b6ff3999e2bfdc Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:12:38 +0100 Subject: [PATCH 01/41] C++11 Conversion: Converted Fanuc, Fake and Test projects to CMake * Started converting the whole system to CMake for ease of multi-platform support and configuration (easier to locate required 3rd party libraries) * Added CppUnit GIT sub-module and CMake scripts to compile it under Windows * Added CMake scripts for configuring FOCAS2 for consumption by the Fanuc adapter --- .gitignore | 325 ++++++++++ .gitmodules | 3 + CMakeLists.txt | 40 ++ cmake/CppUnit.cmake | 32 + {test/CMake => cmake}/FindCppUnit.cmake | 0 {test/CMake => cmake}/LibFindMacros.cmake | 0 cmake/adapter_fanuc.cmake | 129 ++++ cmake/msvc_xp_support.cmake | 45 ++ cmake/osx_no_app_or_frameworks.cmake | 9 + cmake/vs_set_working_directory.cmake | 16 + cppunit | 1 + cppunit_make/CMakeLists.txt | 60 ++ fake/CMakeLists.txt | 49 ++ fanuc/CMakeLists.txt | 95 +++ fanuc/fanuc.sln | 38 -- fanuc/fanuc.vcproj | 751 ---------------------- fanuc/fanuc.vcxproj | 381 ----------- 17 files changed, 804 insertions(+), 1170 deletions(-) create mode 100644 .gitmodules create mode 100644 CMakeLists.txt create mode 100644 cmake/CppUnit.cmake rename {test/CMake => cmake}/FindCppUnit.cmake (100%) rename {test/CMake => cmake}/LibFindMacros.cmake (100%) create mode 100644 cmake/adapter_fanuc.cmake create mode 100644 cmake/msvc_xp_support.cmake create mode 100644 cmake/osx_no_app_or_frameworks.cmake create mode 100644 cmake/vs_set_working_directory.cmake create mode 160000 cppunit create mode 100644 cppunit_make/CMakeLists.txt create mode 100644 fake/CMakeLists.txt create mode 100644 fanuc/CMakeLists.txt delete mode 100644 fanuc/fanuc.sln delete mode 100644 fanuc/fanuc.vcproj delete mode 100644 fanuc/fanuc.vcxproj diff --git a/.gitignore b/.gitignore index a100be6..193d43b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,328 @@ build *.vcproj CMakeFiles *.dir + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..74f4530 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "cppunit"] + path = cppunit + url = http://anongit.freedesktop.org/git/libreoffice/cppunit diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..eb951ee --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.7 FATAL_ERROR) #This minimum version is to support Visual Studio 2017 and C++ feature checking + +project(adapters) + +# All of the C++ code and CppUnit require C++ 11 features to compile. +# We will define these properties by default for each CMake target to be created. +set_property(GLOBAL PROPERTY CXX_STANDARD 11) +set_property(GLOBAL PROPERTY CXX_STANDARD_REQUIRED ON) + +# By default only generate 2 configurations (Debug and Release) for simplicity. +# The user can change this option if required for the additional ones such as 'RelWithDebInfo'. +set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE) +if(DEFINED CMAKE_BUILD_TYPE) + set_property( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES} ) +endif() + +# Add our './cmake' sub-folder to the lists searched when calling functions +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") + +# Setup compiler options for Windows, OSX, Linux (each file guards against usage on an inappropriate platform) +if(MSVC) + # Default winver to Vista and Later + set(WINVER "0x0600" CACHE STRING "Windows Target Version: 0x0400 - 95 & NT 4.0, 0x0500 - 2000, 0x0501 - XP, 0x0600 - Vista, 0x0601 - 7, 0x0602 - 8") +endif() +include(cmake/osx_no_app_or_frameworks.cmake) +include(cmake/msvc_xp_support.cmake) +include(cmake/vs_set_working_directory.cmake) +include(cmake/adapter_fanuc.cmake) + +# Add our dependency projects +set(MSVC_SHARED_RT ON) # Use shared runtime libraries for Microsoft compiles +include(cmake/CppUnit.cmake) + +# Add our projects +if(${BUILD_FANUC}) # This is conditional as it requires the externally specified FOCAS-2 libraries to be purchased + add_subdirectory(fanuc) +endif() + +add_subdirectory(fake) +add_subdirectory(test) \ No newline at end of file diff --git a/cmake/CppUnit.cmake b/cmake/CppUnit.cmake new file mode 100644 index 0000000..5744e5d --- /dev/null +++ b/cmake/CppUnit.cmake @@ -0,0 +1,32 @@ +# This module allows the addition of CppUnit to a target +# Depending on or compiler this is either via our sub-module or searching +# for a package on the system + +if(MSVC) + add_subdirectory(${CMAKE_SOURCE_DIR}/cppunit_make "${CMAKE_BINARY_DIR}/cppunit") +endif(MSVC) + +################################################################################# +# # +# Functions # +# # +################################################################################# + +function(AddCppUnitSupport projectTarget) + + if(WIN32) + # For Windows we compile our own version of CppUnit from our Git submodule source + # Define a dependency between the targets and link them. + set(CPPUNIT_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/cppunit/include) + set(CPPUNIT_LIBRARY cppunit) + + add_dependencies(${projectTarget} cppunit) + elseif(UNIX) + # We will use the system's installed packages; which we have to look for. + find_package(CppUnit REQUIRED) + endif() + + target_include_directories(${projectTarget} PRIVATE ${CPPUNIT_INCLUDE_DIR}) + target_link_libraries(${projectTarget} PRIVATE ${CPPUNIT_LIBRARY}) + +endfunction() \ No newline at end of file diff --git a/test/CMake/FindCppUnit.cmake b/cmake/FindCppUnit.cmake similarity index 100% rename from test/CMake/FindCppUnit.cmake rename to cmake/FindCppUnit.cmake diff --git a/test/CMake/LibFindMacros.cmake b/cmake/LibFindMacros.cmake similarity index 100% rename from test/CMake/LibFindMacros.cmake rename to cmake/LibFindMacros.cmake diff --git a/cmake/adapter_fanuc.cmake b/cmake/adapter_fanuc.cmake new file mode 100644 index 0000000..479797f --- /dev/null +++ b/cmake/adapter_fanuc.cmake @@ -0,0 +1,129 @@ +option(BUILD_FANUC "Build the FOCAS-2 Fanuc Adapter" OFF) + +# If we do not have a cache entry for the FOCAS directory, create one now +# and default its value relative to the project root +if(NOT DEFINED FOCAS2_DIR) + set(FOCAS2_DIR "${CMAKE_SOURCE_DIR}/../FOCAS2" CACHE PATH "Path to the top-level Fanuc FOCAS2 directory") +endif() + +# Define a drop-list of FANUC controls that can be targeted +if(NOT DEFINED FANUC_CONTROL) + set(FANUC_CONTROL "FS16/18/21, 0i-B, 0i-C, 16i/18i-W, PMi" CACHE STRING "Control to target within the FOCAS-2 library, affects maximum number of axis") +endif() + +# Constrain this list in the UI +# |-----------------------------------------------|---------------|-------------------| +# | Value | MAX_AXIS | Compile Symbol | +# |-----------------------------------------------|---------------|-------------------| +# | FS16/18/21, 0i-B, 0i-C, 16i/18i-W, PMi (8) | 8 | - | +# | FS0i-A (4) | 4 | FS0ID | +# | FS0i-D (32) | 32 | FS0IDD | +# | FS0i-F (32) | 32 | FS30D | +# | FS15-B (10) | 10 | FS15BD | +# | FS15-B Multi axes (15) | 15 | M_AXIS1 | +# | FS15-B/15i Multi axes (24) | 24 | M_AXIS2 | +# | FS30i/31i/32i/35i (32) | 32 | FS30D | +# | PMi-A (32) | 32 | FS30D | +# | PM (6) | 32 | PMD | +# |-----------------------------------------------|---------------|-------------------| +# +set_property(CACHE FANUC_CONTROL PROPERTY STRINGS + "FS16/18/21, 0i-B, 0i-C, 16i/18i-W, PMi (8)" + "FS0i-A (4)" + "FS0i-D (32)" + "FS0i-F (32)" + "FS15-B (10)" + "FS15-B Multi axes (15)" + "FS15-B/15i Multi axes (24)" + "FS30i/31i/32i/35i (32)" + "PMi-A (32)" + "PM (6)" + ) + +# Perform global checks if the user has chosen to build the Fanuc adapter +if(${BUILD_FANUC}) + if(NOT EXISTS ${FOCAS2_DIR}) + message(WARNING "The FOCAS2 directory '${FOCAS2_DIR}' does not exists. Skipping Fanuc adapter generation") + set(BUILD_FANUC OFF) + endif() +endif() + +# FANUC only supports Windows for 64-bit compilations +if( ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") AND UNIX) + message(WARNING "FOCAS2 only supports 32-bit compilations when targeting Linux. Skipping Fanuc adapter generation") + set(BUILD_FANUC OFF) +endif() + +# Fanuc include directories are based upon architecture and platform +# Default to 32-bit systems +set(FANUC_INC_BASE_DIR ${FOCAS2_DIR}/Fwlib) +if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + # 64-bit system + set(FANUC_INC_BASE_DIR ${FOCAS2_DIR}/Fwlib64) +endif() +set(FANUC_INC_CTRL_DIR ${FANUC_INC_BASE_DIR}/e1) # This header is suitable for all controls if compilation definitions are set + +# These properties are different for Linux +if(UNIX AND (CMAKE_SYSTEM_NAME MATCHES Linux) ) + set(FANUC_INC_BASE_DIR ${FOCAS2_DIR}/Fwlib/Linux) + set(FANUC_INC_CTRL_DIR ${FANUC_INC_BASE_DIR}) +endif() + +################################################################################# +# # +# Functions # +# # +################################################################################# +function(AddFocas2Support projectTarget) + + # Add compile definitions based upon the current value of FANUC_CONTROL + if(${FANUC_CONTROL} STREQUAL "FS0i-A (4)") + target_compile_definitions(${projectTarget} PRIVATE FS0ID) + elseif(${FANUC_CONTROL} STREQUAL "FS0i-D (32)") + target_compile_definitions(${projectTarget} PRIVATE FS0IDD) + elseif(${FANUC_CONTROL} STREQUAL "FS0i-F (32)") + target_compile_definitions(${projectTarget} PRIVATE FS30D) + elseif(${FANUC_CONTROL} STREQUAL "FS15-B (10)") + target_compile_definitions(${projectTarget} PRIVATE FS15BD) + elseif(${FANUC_CONTROL} STREQUAL "FS15-B Multi axes (15)") + target_compile_definitions(${projectTarget} PRIVATE M_AXIS1) + elseif(${FANUC_CONTROL} STREQUAL "FS15-B/15i Multi axes (24)") + target_compile_definitions(${projectTarget} PRIVATE M_AXIS2) + elseif(${FANUC_CONTROL} STREQUAL "FS30i/31i/32i/35i (32)") + target_compile_definitions(${projectTarget} PRIVATE FS30D) + elseif(${FANUC_CONTROL} STREQUAL "PMi-A (32)") + target_compile_definitions(${projectTarget} PRIVATE FS30D) + elseif(${FANUC_CONTROL} STREQUAL "PM (6)") + target_compile_definitions(${projectTarget} PRIVATE PMD) + endif() + + # Target the correct link libraries + if(WIN32) + if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + target_link_libraries(${projectTarget} + PRIVATE ${FANUC_INC_BASE_DIR}/Fwlib64.lib + ) + else() + target_link_libraries(${projectTarget} + PRIVATE ${FANUC_INC_BASE_DIR}/Fwlib32.lib + ) + endif() + elseif(UNIX) + if(CMAKE_SYSTEM_PROCESSOR EQUAL "arm") + target_link_libraries(${projectTarget} + PRIVATE ${FANUC_INC_BASE_DIR}/arm/libfwlib32.so.1.0.1 + ) + else() + target_link_libraries(${projectTarget} + PRIVATE ${FANUC_INC_BASE_DIR}/x86/libfwlib32.so.1.0.2 + ) + endif() + endif() + + # Add include directories + target_include_directories(${projectTarget} + PRIVATE ${FANUC_INC_BASE_DIR} + PRIVATE ${FANUC_INC_CTRL_DIR} + ) + +endfunction() diff --git a/cmake/msvc_xp_support.cmake b/cmake/msvc_xp_support.cmake new file mode 100644 index 0000000..99cbe21 --- /dev/null +++ b/cmake/msvc_xp_support.cmake @@ -0,0 +1,45 @@ +# If we are using a XP compatable toolset (specified with the '-T' argument to cmake.exe) then +# we may need to make some changes to the way projects are compiled. + +# Force CMake to show the toolset generator option. This will allow a user to specify a toolset not available in the GUI (Option is now available from CMake v3.5.1). +# Values could be something like: +# - v120_xp (Visual Studio 2013 targeted for XP) +# - v140_xp (Visual Studio 2015 targeted for XP) +# - v141_xp (Visual Studio 2017 targeted for XP) +# - v120 (Normal Visual Studio 2013) +# - v140 (Normal Visual Studio 2015) +# - v141 (Normal isual Studio 2017) +set(CMAKE_GENERATOR_TOOLSET ${CMAKE_GENERATOR_TOOLSET} CACHE string "Use to target a toolset not available in the CMake GUI list of options, e.g. 'v141_xp'" FORCE) + + +################################################################################# +# # +# Functions # +# # +################################################################################# + +function(AddMsvcXPSupport projectTarget) + if (CMAKE_GENERATOR_TOOLSET MATCHES "v[0-9]*_xp") + message(STATUS "Visual Studio XP compliant generator toolkit specified for target ${projectTarget}") + + # Define compiler flags for the target to prevent use of Windows APIs that are not XP compliant + target_compile_definitions(${projectTarget} + PRIVATE WINVER=0x502 + PRIVATE _WIN32_WINNT=0x502) + + # From Visual Studio 2015 and later, the compiler initialises static variables + # in a thread-safe manner. This can cause issues when running under Windows XP + # from a C# host application or anything dynamically loading a module. + # So to be extra safe we will disable this behaviour for shared libraries. + # https://docs.microsoft.com/en-us/cpp/build/reference/zc-threadsafeinit-thread-safe-local-static-initialization + # https://support.microsoft.com/en-gb/help/118816/prb-calling-loadlibrary-to-load-a-dll-that-has-static-tls + # https://msdn.microsoft.com/en-us/library/windows/desktop/6yh4a9k1(v=vs.140).aspx + # https://blogs.msdn.microsoft.com/oldnewthing/20101122-00/?p=12233/#10095505 + if(MSVC_VERSION GREATER 1700) + get_target_property(target_type ${projectTarget} TYPE) + if(target_type STREQUAL "SHARED_LIBRARY") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:threadSafeInit- ") + endif() + endif() + endif() +endfunction() \ No newline at end of file diff --git a/cmake/osx_no_app_or_frameworks.cmake b/cmake/osx_no_app_or_frameworks.cmake new file mode 100644 index 0000000..42ebe15 --- /dev/null +++ b/cmake/osx_no_app_or_frameworks.cmake @@ -0,0 +1,9 @@ +# Change how CMake find_* commands choose between OS X Application Bundles and unix-style package components. +# We will always prefer packages +# +set(CMAKE_FIND_APPBUNDLE NEVER) + +# Change how CMake find_* commands choose between OS X frameworks and unix-style package components. +# We will always prefer packages +# +set(CMAKE_FIND_FRAMEWORK NEVER FORCE) diff --git a/cmake/vs_set_working_directory.cmake b/cmake/vs_set_working_directory.cmake new file mode 100644 index 0000000..fa59966 --- /dev/null +++ b/cmake/vs_set_working_directory.cmake @@ -0,0 +1,16 @@ +# By default Visual Studio sets its 'working directory' for debugging to the MSBuild property $(ProjectDir). +# Some targets may require a specific working folder (for example to locate files or libraries). +# This CMake module contains a function that can set the 'working directory'. +# + +################################################################################# +# # +# Functions # +# # +################################################################################# + +function(SetVisualStudioWorkingDirectory projectTarget workingDirectory) + if(MSVC) + set_target_properties(${projectTarget} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${workingDirectory}) + endif() +endfunction() \ No newline at end of file diff --git a/cppunit b/cppunit new file mode 160000 index 0000000..b8a9398 --- /dev/null +++ b/cppunit @@ -0,0 +1 @@ +Subproject commit b8a9398b3352c6560af646e1492aae4bf2bd3101 diff --git a/cppunit_make/CMakeLists.txt b/cppunit_make/CMakeLists.txt new file mode 100644 index 0000000..47b978d --- /dev/null +++ b/cppunit_make/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required(VERSION 2.6) + +project(cppunit) + +set(CPPUNIT_SRC_DIR ../cppunit/src/cppunit) +set(CPPUNIT_INCLUDE_DIRS ../cppunit/include) + +file(GLOB internal_headers ${CPPUNIT_SRC_DIR}/A-Za-z_]*.h) +file(GLOB install_headers ${CPPUNIT_INCLUDE_DIRS}/A-Za-z_]/*.h) +file(GLOB sources ${CPPUNIT_SRC_DIR}/[A-Za-z_]*.cpp) +list(REMOVE_ITEM sources ${CPPUNIT_SRC_DIR}/UnixDynamicLibraryManager.cpp) + +include_directories(${CPPUNIT_INCLUDE_DIRS} ${CPPUNIT_SRC_DIR}) + +add_library(cppunit ${sources} ${headers}) + +# correct library names +set_target_properties(cppunit PROPERTIES + DEBUG_POSTFIX "d" + RELEASE_POSTFIX "" + MINSIZEREL_POSTFIX "" + RELWITHDEBINFO_POSTFIX "" +) + +if(MSVC) + ### General stuff + # a) Change MSVC runtime library settings (/MD[d], /MT[d], /ML[d] (single-threaded until VS 2003)) + # plus set lib suffix for later use and project label accordingly + # see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx + # http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=VS.71).aspx + set(LIB_RT_SUFFIX "md") # CMake defaults to /MD for MSVC + set(LIB_RT_OPTION "/MD") + # + + if(NOT MSVC_SHARED_RT) # User wants to have static runtime libraries (/MT, /ML) + if(MSVC_STHREADED_RT) # User wants to have old single-threaded static runtime libraries + set(LIB_RT_SUFFIX "ml") + set(LIB_RT_OPTION "/ML") + if(NOT ${MSVC_VERSION} LESS 1400) + message(FATAL_ERROR "Single-threaded static runtime libraries (/ML) only available until VS .NET 2003 (7.1).") + endif() + else() + set(LIB_RT_SUFFIX "mt") + set(LIB_RT_OPTION "/MT") + endif() + + # correct linker options + foreach(flag_var CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + foreach(config_name "" DEBUG RELEASE MINSIZEREL RELWITHDEBINFO) + set(var_name "${flag_var}") + if(NOT "${config_name}" STREQUAL "") + set(var_name "${var_name}_${config_name}") + endif() + string(REPLACE "/MD" "${LIB_RT_OPTION}" ${var_name} "${${var_name}}") + endforeach() + endforeach() + endif() +endif(MSVC) + + diff --git a/fake/CMakeLists.txt b/fake/CMakeLists.txt new file mode 100644 index 0000000..479c069 --- /dev/null +++ b/fake/CMakeLists.txt @@ -0,0 +1,49 @@ +set(FAKE_HEADERS + fake_adapter.hpp +) + +set(FAKE_SOURCES + fake.cpp + fake_adapter.cpp +) + +set(ADDITIONAL_HEADERS + ${CMAKE_SOURCE_DIR}/src/adapter.hpp + ${CMAKE_SOURCE_DIR}/src/client.hpp + ${CMAKE_SOURCE_DIR}/src/condition.hpp + ${CMAKE_SOURCE_DIR}/src/device_datum.hpp + ${CMAKE_SOURCE_DIR}/src/server.hpp + ${CMAKE_SOURCE_DIR}/src/service.hpp + ${CMAKE_SOURCE_DIR}/src/string_buffer.hpp +) + +set(ADDITIONAL_SOURCES + ${CMAKE_SOURCE_DIR}/src/adapter.cpp + ${CMAKE_SOURCE_DIR}/src/client.cpp + ${CMAKE_SOURCE_DIR}/src/condition.cpp + ${CMAKE_SOURCE_DIR}/src/device_datum.cpp + ${CMAKE_SOURCE_DIR}/src/logger.cpp + ${CMAKE_SOURCE_DIR}/src/server.cpp + ${CMAKE_SOURCE_DIR}/src/service.cpp + ${CMAKE_SOURCE_DIR}/src/string_buffer.cpp +) + +add_executable(fake_adapter + ${FAKE_HEADERS} + ${FAKE_SOURCES} + ${ADDITIONAL_HEADERS} + ${ADDITIONAL_SOURCES} +) + +target_include_directories(fake_adapter + PRIVATE ${CMAKE_SOURCE_DIR}/src +) + + +if(WIN32) + target_link_libraries(fake_adapter + PRIVATE wsock32.lib + ) +endif() + +AddMsvcXPSupport(fake_adapter) #This will only apply if an XP compatible toolset has been selected in CMake \ No newline at end of file diff --git a/fanuc/CMakeLists.txt b/fanuc/CMakeLists.txt new file mode 100644 index 0000000..95bb56f --- /dev/null +++ b/fanuc/CMakeLists.txt @@ -0,0 +1,95 @@ +set(FANUC_HEADERS + fanuc_adapter.hpp + fanuc_axis.hpp + fanuc_path.hpp +) + +set(FANUC_SOURCES + fanuc_adapter.cpp + fanuc_axis.cpp + fanuc_path.cpp + FanucAdapter.cpp +) + +set(MIN_INI_HEADERS + ${CMAKE_SOURCE_DIR}/minIni_07/minIni.h +) + +set(MIN_INI_SOURCES + ${CMAKE_SOURCE_DIR}/minIni_07/minIni.c +) + +set(ADDITIONAL_HEADERS + ${CMAKE_SOURCE_DIR}/src/adapter.cpp + ${CMAKE_SOURCE_DIR}/src/client.cpp + ${CMAKE_SOURCE_DIR}/src/condition.cpp + ${CMAKE_SOURCE_DIR}/src/device_datum.cpp + ${CMAKE_SOURCE_DIR}/src/logger.cpp + ${CMAKE_SOURCE_DIR}/src/server.cpp + ${CMAKE_SOURCE_DIR}/src/service.cpp + ${CMAKE_SOURCE_DIR}/src/string_array.cpp + ${CMAKE_SOURCE_DIR}/src/string_buffer.cpp +) + +set(ADDITIONAL_SOURCES + ${CMAKE_SOURCE_DIR}/src/adapter.hpp + ${CMAKE_SOURCE_DIR}/src/client.hpp + ${CMAKE_SOURCE_DIR}/src/condition.hpp + ${CMAKE_SOURCE_DIR}/src/device_datum.hpp + ${CMAKE_SOURCE_DIR}/src/internal.hpp + ${CMAKE_SOURCE_DIR}/src/logger.hpp + ${CMAKE_SOURCE_DIR}/src/server.hpp + ${CMAKE_SOURCE_DIR}/src/service.hpp + ${CMAKE_SOURCE_DIR}/src/string_array.hpp + ${CMAKE_SOURCE_DIR}/src/string_buffer.hpp +) + +set(CONFIGURATION_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/adapter.ini + ${CMAKE_CURRENT_SOURCE_DIR}/fanuc.xml +) + +# Allow better viewing and grouping of files in Visual Studio by defining source groups +source_group("Headers Files" FILES ${FANUC_HEADERS}) +source_group("Headers Files\\adapter" FILES ${ADDITIONAL_HEADERS}) +source_group("Headers Files\\Min Ini" FILES ${MIN_INI_HEADERS}) +source_group("Source Files" FILES ${FANUC_SOURCES}) +source_group("Source Files\\adapter" FILES ${ADDITIONAL_SOURCES}) +source_group("Source Files\\Min Ini" FILES ${MIN_INI_SOURCES}) +source_group("Configuration" FILES ${CONFIGURATION_FILES}) + + +add_executable(fanuc + ${FANUC_HEADERS} + ${FANUC_SOURCES} + ${MIN_INI_HEADERS} + ${MIN_INI_SOURCES} + ${ADDITIONAL_HEADERS} + ${ADDITIONAL_SOURCES} +) + +target_include_directories(fanuc + PRIVATE ${CMAKE_SOURCE_DIR}/minIni_07 + PRIVATE ${CMAKE_SOURCE_DIR}/src +) + +target_compile_definitions(fanuc + PRIVATE INI_ANSIONLY +) + +if(WIN32) + target_link_libraries(fanuc + PRIVATE wsock32.lib + ) +endif() + +AddFocas2Support(fanuc) +AddMsvcXPSupport(fanuc) #This will only apply if an XP compatible toolset has been selected in CMake + +# Copy the ini file and devices XML to our output directory +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/adapter.ini DESTINATION ./Debug/) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/adapter.ini DESTINATION ./Release/) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/fanuc.xml DESTINATION ./Debug/) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/fanuc.xml DESTINATION ./Release/) + +SetVisualStudioWorkingDirectory(fanuc "\$\(OutDir\)") # Set the working directory for debugging to the MSBuild property $(OutDir) diff --git a/fanuc/fanuc.sln b/fanuc/fanuc.sln deleted file mode 100644 index edb0bbc..0000000 --- a/fanuc/fanuc.sln +++ /dev/null @@ -1,38 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fanuc", "fanuc.vcxproj", "{E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - Release0i|Win32 = Release0i|Win32 - Release0id|Win32 = Release0id|Win32 - Release15i|Win32 = Release15i|Win32 - Release16i|Win32 = Release16i|Win32 - Release18i|Win32 = Release18i|Win32 - Release30i|Win32 = Release30i|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Debug|Win32.ActiveCfg = Debug|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Debug|Win32.Build.0 = Debug|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release|Win32.ActiveCfg = Release|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release|Win32.Build.0 = Release|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release0i|Win32.ActiveCfg = Release0i|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release0i|Win32.Build.0 = Release0i|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release0id|Win32.ActiveCfg = Release0id|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release0id|Win32.Build.0 = Release0id|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release15i|Win32.ActiveCfg = Release15i|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release15i|Win32.Build.0 = Release15i|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release16i|Win32.ActiveCfg = Release16i|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release16i|Win32.Build.0 = Release16i|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release18i|Win32.ActiveCfg = Release18i|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release18i|Win32.Build.0 = Release18i|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release30i|Win32.ActiveCfg = Release30i|Win32 - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43}.Release30i|Win32.Build.0 = Release30i|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/fanuc/fanuc.vcproj b/fanuc/fanuc.vcproj deleted file mode 100644 index 322c231..0000000 --- a/fanuc/fanuc.vcproj +++ /dev/null @@ -1,751 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/fanuc/fanuc.vcxproj b/fanuc/fanuc.vcxproj deleted file mode 100644 index 21ca7e8..0000000 --- a/fanuc/fanuc.vcxproj +++ /dev/null @@ -1,381 +0,0 @@ - - - - - Debug - Win32 - - - Release0id - Win32 - - - Release0i - Win32 - - - Release15i - Win32 - - - Release16i - Win32 - - - Release18i - Win32 - - - Release30i - Win32 - - - Release - Win32 - - - - {E8B3DF32-37B5-4FDB-9C95-B5F978E61D43} - fanuc - Win32Proj - - - - Application - Unicode - true - - - Application - Unicode - true - - - Application - Unicode - true - - - Application - Unicode - true - - - Application - Unicode - true - - - Application - Unicode - true - - - Application - Unicode - true - - - Application - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - false - - - - Disabled - ..\src;..\Fwlib;..\Fwlib\e1;..\minIni_07;%(AdditionalIncludeDirectories) - INI_ANSIONLY;DEBUG;FS30D;WIN32 - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - - - ..\Fwlib\Fwlib32.lib;wsock32.lib;..\Fwlib\fwlib30i.lib;%(AdditionalDependencies) - true - Console - MachineX86 - - - - - MaxSpeed - true - ..\src;..\Fwlib;..\Fwlib\e1;..\minIni_07;%(AdditionalIncludeDirectories) - FS0IDD;WIN32;INI_ANSIONLY - MultiThreaded - true - - - Level3 - ProgramDatabase - - - ..\Fwlib\Fwlib32.lib;wsock32.lib;%(AdditionalDependencies) - true - Console - true - true - MachineX86 - - - - - MaxSpeed - true - ..\src;..\Fwlib;..\Fwlib\e1;..\minIni_07;%(AdditionalIncludeDirectories) - FS0ID;WIN32;INI_ANSIONLY - MultiThreaded - true - - - Level3 - ProgramDatabase - - - ..\Fwlib\Fwlib32.lib;wsock32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName)_0i.exe - true - Console - true - true - MachineX86 - - - - - MaxSpeed - true - ..\src;..\Fwlib;..\Fwlib\e1;..\minIni_07;%(AdditionalIncludeDirectories) - FS16D;WIN32;INI_ANSIONLY - MultiThreaded - true - - - Level3 - ProgramDatabase - - - ..\Fwlib\Fwlib32.lib;wsock32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName)_16i.exe - true - Console - true - true - MachineX86 - - - - - MaxSpeed - true - ..\src;..\Fwlib;..\Fwlib\e1;..\minIni_07;%(AdditionalIncludeDirectories) - FS30D;WIN32;INI_ANSIONLY - MultiThreaded - true - - - Level3 - ProgramDatabase - - - ..\Fwlib\Fwlib32.lib;wsock32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName)_30i.exe - true - Console - true - true - MachineX86 - - - - - MaxSpeed - true - ..\src;..\Fwlib;..\Fwlib\e1;..\minIni_07;%(AdditionalIncludeDirectories) - FS15D;WIN32;INI_ANSIONLY - MultiThreaded - true - - - Level3 - ProgramDatabase - - - ..\Fwlib\Fwlib32.lib;wsock32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName)_15i.exe - true - Console - true - true - MachineX86 - - - - - MaxSpeed - true - ..\src;..\Fwlib;..\Fwlib\e1;..\minIni_07;%(AdditionalIncludeDirectories) - FS0IDD;WIN32;INI_ANSIONLY - MultiThreaded - true - - - Level3 - ProgramDatabase - - - ..\Fwlib\Fwlib32.lib;wsock32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName)_0id.exe - true - Console - true - true - MachineX86 - - - - - MaxSpeed - true - ..\src;..\Fwlib;..\Fwlib\e1;..\minIni_07;%(AdditionalIncludeDirectories) - FS18D;WIN32;INI_ANSIONLY - MultiThreaded - true - - - Level3 - ProgramDatabase - - - ..\Fwlib\Fwlib32.lib;wsock32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName)_18i.exe - true - Console - true - true - MachineX86 - - - - - - - - - - INI_ANSIONLY;DEBUG;FS30D;WIN32 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 434b3570ae9b8ae6f08269f7c58e8c1e8fce6365 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:12:48 +0100 Subject: [PATCH 02/41] C++11 Conversion: Updated / Added copyright headers to files * Added or updated the copyright header block. * Removed Unicode characters * Converted to C++ style comments --- fake/fake.cpp | 72 +-- fake/fake_adapter.cpp | 196 ++++---- fake/fake_adapter.hpp | 79 ++-- fanuc/fanuc_adapter.cpp | 623 +++++++++++++------------ fanuc/fanuc_adapter.hpp | 170 +++---- fanuc/fanuc_axis.cpp | 69 ++- fanuc/fanuc_axis.hpp | 90 ++-- fanuc/fanuc_path.cpp | 518 ++++++++++----------- fanuc/fanuc_path.hpp | 158 +++---- src/adapter.cpp | 349 +++++++------- src/adapter.hpp | 209 +++++---- src/axis.hpp | 150 +++--- src/client.cpp | 125 +++-- src/client.hpp | 97 ++-- src/component.hpp | 103 +++-- src/condition.cpp | 243 +++++----- src/condition.hpp | 168 +++---- src/configuration.cpp | 113 +++-- src/configuration.hpp | 215 +++++---- src/cutting_tool.cpp | 115 +++-- src/cutting_tool.hpp | 126 +++-- src/device_datum.cpp | 885 ++++++++++++++++++------------------ src/device_datum.hpp | 548 +++++++++++----------- src/internal.hpp | 100 ++-- src/logger.cpp | 139 +++--- src/logger.hpp | 76 +++- src/serial.cpp | 361 ++++++++------- src/serial.hpp | 210 +++++---- src/server.cpp | 571 ++++++++++++----------- src/server.hpp | 140 +++--- src/service.cpp | 512 +++++++++++---------- src/service.hpp | 80 +++- src/string_array.cpp | 155 ++++--- src/string_array.hpp | 118 ++--- src/string_buffer.cpp | 183 ++++---- src/string_buffer.hpp | 90 ++-- src/threading.hpp | 208 ++++----- src/time_series.cpp | 185 ++++---- src/time_series.hpp | 98 ++-- test/CMakeLists.txt | 77 ++-- test/condition_test.cpp | 276 +++++------ test/condition_test.hpp | 120 ++--- test/configuration_test.cpp | 126 ++--- test/configuration_test.hpp | 104 ++--- test/device_datum_test.cpp | 246 +++++----- test/device_datum_test.hpp | 108 ++--- test/test.cpp | 85 ++-- test/time_series_test.cpp | 135 +++--- test/time_series_test.hpp | 102 ++--- 49 files changed, 5184 insertions(+), 4842 deletions(-) diff --git a/fake/fake.cpp b/fake/fake.cpp index ed0dd11..0bd1bfb 100644 --- a/fake/fake.cpp +++ b/fake/fake.cpp @@ -1,35 +1,35 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// #include "internal.hpp" #include "fake_adapter.hpp" @@ -37,10 +37,10 @@ #include "string_buffer.hpp" int main(int aArgc, const char *aArgv[]) -{ +{ /* Construct the adapter and start the server */ - FakeAdapter *adapter = new FakeAdapter(7878); - adapter->setName("Fake MTConnect Adapter"); - return adapter->main(aArgc, aArgv); + FakeAdapter *adapter = new FakeAdapter(7878); + adapter->setName("Fake MTConnect Adapter"); + return adapter->main(aArgc, aArgv); } diff --git a/fake/fake_adapter.cpp b/fake/fake_adapter.cpp index 15031d4..ef5b7c0 100644 --- a/fake/fake_adapter.cpp +++ b/fake/fake_adapter.cpp @@ -1,122 +1,122 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - -#include "internal.hpp" -#include "fake_adapter.hpp" - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include "internal.hpp" +#include "fake_adapter.hpp" + FakeAdapter::FakeAdapter(int aPort) : Adapter(aPort, 1000), mAvailability("avail"), mSystem("system"), mPos("pos"), - mExecution("exec") -{ - addDatum(mAvailability); - addDatum(mSystem); - addDatum(mPos); - addDatum(mExecution); -} - -FakeAdapter::~FakeAdapter() -{ -} - + mExecution("exec") +{ + addDatum(mAvailability); + addDatum(mSystem); + addDatum(mPos); + addDatum(mExecution); +} + +FakeAdapter::~FakeAdapter() +{ +} + void FakeAdapter::initialize(int aArgc, const char *aArgv[]) -{ +{ MTConnectService::initialize(aArgc, aArgv); if (aArgc > 1) { mPort = atoi(aArgv[1]); } -} - -void FakeAdapter::start() -{ - startServer(); +} + +void FakeAdapter::start() +{ + startServer(); } void FakeAdapter::stop() { - stopServer(); + stopServer(); } static int count = 0; void FakeAdapter::gatherDeviceData() { - mAvailability.available(); + mAvailability.available(); - printf("Count: %d\n", count); - mPos.setValue(count); - switch (count % 6) - { - case 0: - mExecution.setValue(Execution::eREADY); - printf("Add 0\n"); - mSystem.add(Condition::eFAULT, "Fault 1", "0"); - break; + printf("Count: %d\n", count); + mPos.setValue(count); + switch (count % 6) + { + case 0: + mExecution.setValue(Execution::eREADY); + printf("Add 0\n"); + mSystem.add(Condition::eFAULT, "Fault 1", "0"); + break; - case 1: - mExecution.setValue(Execution::eACTIVE); - printf("Add 0, 1\n"); - mSystem.add(Condition::eFAULT, "Fault 1", "0"); - mSystem.add(Condition::eFAULT, "Fault 2", "1"); - break; + case 1: + mExecution.setValue(Execution::eACTIVE); + printf("Add 0, 1\n"); + mSystem.add(Condition::eFAULT, "Fault 1", "0"); + mSystem.add(Condition::eFAULT, "Fault 2", "1"); + break; - case 2: - printf("Add 0, 1, 2\n"); - mSystem.add(Condition::eFAULT, "Fault 1", "0"); - mSystem.add(Condition::eFAULT, "Fault 2", "1"); - mSystem.add(Condition::eFAULT, "Fault 3", "2"); - break; + case 2: + printf("Add 0, 1, 2\n"); + mSystem.add(Condition::eFAULT, "Fault 1", "0"); + mSystem.add(Condition::eFAULT, "Fault 2", "1"); + mSystem.add(Condition::eFAULT, "Fault 3", "2"); + break; - case 3: - printf("Add 1, 3\n"); - mSystem.add(Condition::eFAULT, "Fault 2", "1"); - mSystem.add(Condition::eFAULT, "Fault 4", "3"); - break; - - case 4: - mExecution.setValue(Execution::eSTOPPED); - printf("Stay the same\n"); - mSystem.add(Condition::eFAULT, "Fault 2", "1"); - mSystem.add(Condition::eFAULT, "Fault 4", "3"); - break; - + case 3: + printf("Add 1, 3\n"); + mSystem.add(Condition::eFAULT, "Fault 2", "1"); + mSystem.add(Condition::eFAULT, "Fault 4", "3"); + break; - case 5: - // Clear all - printf("Clear\n"); - mAvailability.unavailable(); - break; - } - - count++; + case 4: + mExecution.setValue(Execution::eSTOPPED); + printf("Stay the same\n"); + mSystem.add(Condition::eFAULT, "Fault 2", "1"); + mSystem.add(Condition::eFAULT, "Fault 4", "3"); + break; + + + case 5: + // Clear all + printf("Clear\n"); + mAvailability.unavailable(); + break; + } + + count++; } diff --git a/fake/fake_adapter.hpp b/fake/fake_adapter.hpp index 1995663..58d4f83 100644 --- a/fake/fake_adapter.hpp +++ b/fake/fake_adapter.hpp @@ -1,38 +1,35 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - -#ifndef FAKE_ADAPTER_HPP -#define FAKE_ADAPTER_HPP +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// #include "adapter.hpp" #include "device_datum.hpp" @@ -45,14 +42,14 @@ class FakeAdapter : public Adapter, public MTConnectService /* Define all the data values here */ /* Events */ - Availability mAvailability; - Condition mSystem; - Sample mPos; - Execution mExecution; - + Availability mAvailability; + Condition mSystem; + Sample mPos; + Execution mExecution; + public: FakeAdapter(int aPort); - ~FakeAdapter(); + ~FakeAdapter(); virtual void initialize(int aArgc, const char *aArgv[]); virtual void start(); diff --git a/fanuc/fanuc_adapter.cpp b/fanuc/fanuc_adapter.cpp index 97ce697..562e5e1 100644 --- a/fanuc/fanuc_adapter.cpp +++ b/fanuc/fanuc_adapter.cpp @@ -1,142 +1,141 @@ -/* - * Copyright Copyright 2012, System Insights, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "internal.hpp" -#include "fanuc_adapter.hpp" +// +// Copyright Copyright 2012, System Insights, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include +#include "fanuc_adapter.hpp" #include "minIni.h" -#include - +#include + FanucAdapter::FanucAdapter(int aPort) : Adapter(aPort), mAvail("avail"), mMessage("message"), mPartCount("part_count"), mMacroSampleCount(0), mMacroPathCount(0), mPMCCount(0) -{ +{ /* Alarms */ - addDatum(mMessage); - + addDatum(mMessage); + /* Controller */ - addDatum(mAvail); - addDatum(mPartCount); - - mConfigured = mConnected = false; - mAvail.unavailable(); -} - -FanucAdapter::~FanucAdapter() -{ + addDatum(mAvail); + addDatum(mPartCount); + + mConfigured = mConnected = false; + mAvail.unavailable(); +} + +FanucAdapter::~FanucAdapter() +{ size_t i; for (i = 0; i < mPaths.size(); i++) delete mPaths[i]; - mPaths.clear(); - - disconnect(); -} - + mPaths.clear(); + + disconnect(); +} + void FanucAdapter::initialize(int aArgc, const char *aArgv[]) { MTConnectService::initialize(aArgc, aArgv); const char *iniFile = "adapter.ini"; - + printf("Arguments: %d\n", aArgc); if (aArgc > 1) { strncpy(mDeviceIP, aArgv[0], MAX_HOST_LEN - 1); mDeviceIP[MAX_HOST_LEN - 1] = '\0'; mDevicePort = atoi(aArgv[1]); - + mPort = 7878; if (aArgc > 2) mPort = atoi(aArgv[2]); - } - else - { + } + else + { mDevicePort = 8193; strcpy(mDeviceIP, "localhost"); mPort = 7878; if (aArgc > 0) iniFile = aArgv[0]; printf("Ini File: %s\n", iniFile); - } - + } + FILE *fp = fopen(iniFile, "r"); printf("FP = %d, %x\n", errno, fp); if (fp != 0) fclose(fp); - - configMacrosAndPMC(iniFile); -} - -void FanucAdapter::start() -{ - startServer(); -} - -void FanucAdapter::stop() -{ - stopServer(); -} - -void FanucAdapter::innerGatherDeviceData() -{ - try - { - if (!mConnected) - connect(); - else - { - getPathData(); - getMessages(); - getMacros(); - getPMC(); - getCounts(); - } - } - catch (...) - { - gLogger->error("Unhandled exception occurred during gathering device data, disconnecting."); - disconnect(); - } -} - -void FanucAdapter::gatherDeviceData() -{ + + configMacrosAndPMC(iniFile); +} + +void FanucAdapter::start() +{ + startServer(); +} + +void FanucAdapter::stop() +{ + stopServer(); +} + +void FanucAdapter::innerGatherDeviceData() +{ + try + { + if (!mConnected) + connect(); + else + { + getPathData(); + getMessages(); + getMacros(); + getPMC(); + getCounts(); + } + } + catch (...) + { + gLogger->error("Unhandled exception occurred during gathering device data, disconnecting."); + disconnect(); + } +} + +void FanucAdapter::gatherDeviceData() +{ __try { - innerGatherDeviceData(); - } - + innerGatherDeviceData(); + } + __except(EXCEPTION_EXECUTE_HANDLER) { - gLogger->error("Unhandled structured exception occurred during gathering device data, disconnecting."); - disconnect(); - } -} - -void FanucAdapter::disconnect() -{ - if (mConnected) - { + gLogger->error("Unhandled structured exception occurred during gathering device data, disconnecting."); + disconnect(); + } +} + +void FanucAdapter::disconnect() +{ + if (mConnected) + { printf("Machine has disconnected. Releasing Resources\n"); - cnc_freelibhndl(mFlibhndl); - mConnected = false; - unavailable(); - } -} - - + cnc_freelibhndl(mFlibhndl); + mConnected = false; + unavailable(); + } +} + + void FanucAdapter::configMacrosAndPMC(const char *aIniFile) -{ - // Read adapter configuration +{ + // Read adapter configuration mPort = ini_getl("adapter", "port", mPort, aIniFile); ini_gets("adapter", "service", "MTConnect Fanuc Adapter", mName, SERVICE_NAME_LEN, aIniFile); @@ -151,45 +150,45 @@ void FanucAdapter::configMacrosAndPMC(const char *aIniFile) if (!mAllowDNC) printf("Disabling retrieval of program header\n"); - - // Read adapter.ini to get additional macro variables and - // PMC registers + + // Read adapter.ini to get additional macro variables and + // PMC registers char name[100]; int idx; - const static char *sDigits = "0123456789"; - - mMacroMin = 99999; - mMacroMax = 0; - - // First look for macro variables + const static char *sDigits = "0123456789"; + + mMacroMin = 99999; + mMacroMax = 0; + + // First look for macro variables for (idx = 0; ini_getkey("macros", idx, name, sizeof(name), aIniFile) > 0 && idx < MAX_MACROS; - idx++) - { + idx++) + { char numbers[256]; ini_gets("macros", name, "", numbers, 256, aIniFile); - if (numbers[0] == '[') - { - // We have a path macro. + if (numbers[0] == '[') + { + // We have a path macro. int x, y, z; - char *cp = numbers + 1, *n; - x = strtol(cp, &n, 10); - if (cp == n) - continue; - cp = n; - y = strtol(cp, &n, 10); - if (cp == n) - continue; - cp = n; - z = strtol(cp, &n, 10); - if (cp == n) - continue; - + char *cp = numbers + 1, *n; + x = strtol(cp, &n, 10); + if (cp == n) + continue; + cp = n; + y = strtol(cp, &n, 10); + if (cp == n) + continue; + cp = n; + z = strtol(cp, &n, 10); + if (cp == n) + continue; + int i = mMacroPathCount++; - mMacroPath[i] = new MacroPathPosition(name, x, y, z); - addDatum(*mMacroPath[i]); - + mMacroPath[i] = new MacroPathPosition(name, x, y, z); + addDatum(*mMacroPath[i]); + printf("Adding path macro '%s' at location %d %d %d\n", name, x, y, z); if (x > mMacroMax) mMacroMax = x; @@ -198,239 +197,239 @@ void FanucAdapter::configMacrosAndPMC(const char *aIniFile) if (y < mMacroMin) mMacroMin = y; if (z > mMacroMax) mMacroMax = z; if (z < mMacroMin) mMacroMin = z; - } - else - { + } + else + { char *cp = numbers, *n; long v = strtol(cp, &n, 10); - if (cp == n) - continue; + if (cp == n) + continue; int i = mMacroSampleCount++; - mMacroSample[i] = new MacroSample(name, v); - addDatum(*mMacroSample[i]); - + mMacroSample[i] = new MacroSample(name, v); + addDatum(*mMacroSample[i]); + printf("Adding sample macro '%s' at location %d\n", name, v); - + if (v > mMacroMax) mMacroMax = v; if (v < mMacroMin) mMacroMin = v; - } + } - } - + } + for (idx = 0; ini_getkey("pmc", idx, name, sizeof(name), aIniFile) > 0 && idx < MAX_PMC; idx++) - { + { long v = ini_getl("pmc", name, 0, aIniFile); mPMCVariable[idx] = new IntEvent(name); mPMCAddress[idx] = v; - + addDatum(*mPMCVariable[idx]); - + printf("Adding pmc '%s' at location %d\n", name, v); - } + } mPMCCount = idx; -} - -void FanucAdapter::configure() -{ - if (mConfigured || !mConnected) - return; - +} + +void FanucAdapter::configure() +{ + if (mConfigured || !mConnected) + return; + int ret; - gLogger->info("Configuring...\n"); - + gLogger->info("Configuring...\n"); + short path; ret = cnc_getpath(mFlibhndl, &path, &mMaxPath); - if (ret != EW_OK) - { - gLogger->error("Cannot find number of paths: %d", ret); - mMaxPath = 1; - path = 1; - } - + if (ret != EW_OK) + { + gLogger->error("Cannot find number of paths: %d", ret); + mMaxPath = 1; + path = 1; + } + for (int i = 1; i <= mMaxPath; i++) - { + { FanucPath *path = new FanucPath(this, i); if (!path->configure(mFlibhndl)) - { + { gLogger->error("Could not configure path: %d", i); - exit(1); - } - + exit(1); + } + path->allowDNC(mAllowDNC); mPaths.push_back(path); - } - - gLogger->info("Current path: %d, maximum paths: %d", path, mMaxPath); - - mConfigured = true; -} - -void FanucAdapter::connect() -{ - if (mConnected) - return; - + } + + gLogger->info("Current path: %d, maximum paths: %d", path, mMaxPath); + + mConfigured = true; +} + +void FanucAdapter::connect() +{ + if (mConnected) + return; + printf("Connecting to Machine at %s and port %d\n", mDeviceIP, mDevicePort); short ret = ::cnc_allclibhndl3(mDeviceIP, mDevicePort, 10, &mFlibhndl); printf("Result: %d\n", ret); - if (ret == EW_OK) - { - mAvail.available(); - mConnected = true; + if (ret == EW_OK) + { + mAvail.available(); + mConnected = true; if (!mConfigured) configure(); - - // Resets conditions to normal. - initializeDeviceDatum(); - } - else - { - mConnected = false; - unavailable(); + + // Resets conditions to normal. + initializeDeviceDatum(); + } + else + { + mConnected = false; + unavailable(); Sleep(5000); - } -} - -void FanucAdapter::reconnect() -{ - if (mConnected) - { - cnc_freelibhndl(mFlibhndl); - mConnected = false; - - connect(); - } -} - -void FanucAdapter::getMacros() -{ - if (!mConnected) - return; - - if (mMacroSampleCount == 0 && mMacroPathCount == 0) - return; - - // For now we assume they are close in range. If this proves to not - // be true, we will have to get more creative. + } +} + +void FanucAdapter::reconnect() +{ + if (mConnected) + { + cnc_freelibhndl(mFlibhndl); + mConnected = false; + + connect(); + } +} + +void FanucAdapter::getMacros() +{ + if (!mConnected) + return; + + if (mMacroSampleCount == 0 && mMacroPathCount == 0) + return; + + // For now we assume they are close in range. If this proves to not + // be true, we will have to get more creative. IODBMR *macros = new IODBMR[mMacroMax - mMacroMin]; short ret = cnc_rdmacror(mFlibhndl, mMacroMin, mMacroMax, - sizeof(IODBMR) * (mMacroMax - mMacroMin + 1), - macros); - + sizeof(IODBMR) * (mMacroMax - mMacroMin + 1), + macros); + if (ret == EW_OK) { for (int i = 0; i < mMacroSampleCount; i++) - { + { int off = mMacroSample[i]->getNumber() - mMacroMin; - if (macros->data[off].mcr_val != 0 || macros->data[off].dec_val != -1) - { - mMacroSample[i]->setValue(((double) macros->data[off].mcr_val) / - pow(10.0, macros->data[off].dec_val)); + if (macros->data[off].mcr_val != 0 || macros->data[off].dec_val != -1) + { + mMacroSample[i]->setValue(((double) macros->data[off].mcr_val) / + pow(10.0, macros->data[off].dec_val)); } else { - mMacroSample[i]->unavailable(); - } - } + mMacroSample[i]->unavailable(); + } + } for (int i = 0; i < mMacroPathCount; i++) - { + { int x = mMacroPath[i]->getX() - mMacroMin; int y = mMacroPath[i]->getY() - mMacroMin; int z = mMacroPath[i]->getZ() - mMacroMin; - - if ((macros->data[x].mcr_val != 0 || macros->data[x].dec_val != -1) && - (macros->data[y].mcr_val != 0 || macros->data[y].dec_val != -1) && - (macros->data[z].mcr_val != 0 || macros->data[z].dec_val != -1)) - { - mMacroPath[i]->setValue(((double) macros->data[x].mcr_val) / - pow(10.0, macros->data[x].dec_val), - ((double) macros->data[y].mcr_val) / - pow(10.0, macros->data[y].dec_val), - ((double) macros->data[z].mcr_val) / - pow(10.0, macros->data[z].dec_val)); + + if ((macros->data[x].mcr_val != 0 || macros->data[x].dec_val != -1) && + (macros->data[y].mcr_val != 0 || macros->data[y].dec_val != -1) && + (macros->data[z].mcr_val != 0 || macros->data[z].dec_val != -1)) + { + mMacroPath[i]->setValue(((double) macros->data[x].mcr_val) / + pow(10.0, macros->data[x].dec_val), + ((double) macros->data[y].mcr_val) / + pow(10.0, macros->data[y].dec_val), + ((double) macros->data[z].mcr_val) / + pow(10.0, macros->data[z].dec_val)); } else { - mMacroSample[i]->unavailable(); - } - } - } - else + mMacroSample[i]->unavailable(); + } + } + } + else { printf("Could not read macro variables: %d\n", ret); } - - delete[] macros; -} - -void FanucAdapter::getPMC() -{ - if (!mConnected) - return; - - for (int i = 0; i < mPMCCount; i++) - { - IODBPMC buf; + + delete[] macros; +} + +void FanucAdapter::getPMC() +{ + if (!mConnected) + return; + + for (int i = 0; i < mPMCCount; i++) + { + IODBPMC buf; short ret = pmc_rdpmcrng(mFlibhndl, 0 /* G */, 0 /* byte */, mPMCAddress[i], mPMCAddress[i], 8 + 1, - &buf); - if (ret == EW_OK) - { - if (buf.u.cdata[0] < 0) - mPMCVariable[i]->setValue(-buf.u.cdata[0] - 1); - else - mPMCVariable[i]->setValue(buf.u.cdata[0]); - } - else - { + &buf); + if (ret == EW_OK) + { + if (buf.u.cdata[0] < 0) + mPMCVariable[i]->setValue(-buf.u.cdata[0] - 1); + else + mPMCVariable[i]->setValue(buf.u.cdata[0]); + } + else + { printf("Could not retrieve PMC data at %d for %s: %d\n", mPMCAddress[i], mPMCVariable[i]->getName(), ret); - } - } -} - -void FanucAdapter::getMessages() -{ - if (!mConnected) - return; - - OPMSG messages[6]; + } + } +} + +void FanucAdapter::getMessages() +{ + if (!mConnected) + return; + + OPMSG messages[6]; int ret = cnc_rdopmsg(mFlibhndl, 0, 6 + 256, messages); - if (ret == EW_OK && messages->datano != -1) - { + if (ret == EW_OK && messages->datano != -1) + { char buf[32]; sprintf(buf, "%04", messages->datano); - mMessage.setValue(messages->data, buf); - } -} - -void FanucAdapter::getCounts() -{ - if (!mConnected) - return; - - // Should just be a parameter read - IODBPSD buf; + mMessage.setValue(messages->data, buf); + } +} + +void FanucAdapter::getCounts() +{ + if (!mConnected) + return; + + // Should just be a parameter read + IODBPSD buf; short ret = cnc_rdparam(mFlibhndl, 6711, 0, 8, &buf); - if (ret == EW_OK) - { - mPartCount.setValue(buf.u.ldata); - } -} - -void FanucAdapter::getPathData() -{ - if (!mConnected) - return; - - int i; - for (i = mMaxPath - 1; i >= 0; i--) + if (ret == EW_OK) { - if (!mPaths[i]->gatherData(mFlibhndl)) - { - disconnect(); - break; - } + mPartCount.setValue(buf.u.ldata); } - if (mConnected && i > 0) - cnc_setpath(mFlibhndl, 0); -} +} + +void FanucAdapter::getPathData() +{ + if (!mConnected) + return; + + int i; + for (i = mMaxPath - 1; i >= 0; i--) + { + if (!mPaths[i]->gatherData(mFlibhndl)) + { + disconnect(); + break; + } + } + if (mConnected && i > 0) + cnc_setpath(mFlibhndl, 0); +} diff --git a/fanuc/fanuc_adapter.hpp b/fanuc/fanuc_adapter.hpp index 6640e92..65e3135 100644 --- a/fanuc/fanuc_adapter.hpp +++ b/fanuc/fanuc_adapter.hpp @@ -1,18 +1,3 @@ -/* - * Copyright Copyright 2012, System Insights, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ #ifndef FANUC_ADAPTER_HPP #define FANUC_ADAPTER_HPP @@ -23,104 +8,119 @@ #include "service.hpp" #include "fanuc_path.hpp" #include "Fwlib32.h" -#include - +// +// Copyright Copyright 2012, System Insights, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include + #define MAX_MACROS 32 #define MAX_PMC 32 const int MAX_HOST_LEN = 64; - -class MacroSample : public Sample -{ -protected: - int mNumber; - -public: - MacroSample(const char *aName, int aNum) : + +class MacroSample : public Sample +{ +protected: + int mNumber; + +public: + MacroSample(const char *aName, int aNum) : Sample(aName), mNumber(aNum) {} int getNumber() { return mNumber; } -}; - -class MacroPathPosition : public PathPosition -{ -protected: +}; + +class MacroPathPosition : public PathPosition +{ +protected: int mX; int mY; int mZ; - -public: + +public: MacroPathPosition(const char *aName, int aX, int aY, int aZ) : PathPosition(aName), mX(aX), mY(aY), mZ(aZ) {} int getX() { return mX; } int getY() { return mY; } int getZ() { return mZ; } -}; - +}; + /* * Provides a connection to the data available from the FANUC Focus library. */ -class FanucAdapter : public Adapter, public MTConnectService -{ -protected: +class FanucAdapter : public Adapter, public MTConnectService +{ +protected: /* Define all the data values here */ - short mMaxPath; - std::vector mPaths; - - + short mMaxPath; + std::vector mPaths; + + /* Conditions */ - + /* Events */ - Message mMessage; - - Availability mAvail; - IntEvent mPartCount; - + Message mMessage; + + Availability mAvail; + IntEvent mPartCount; + /* Macro variables */ - MacroSample *mMacroSample[MAX_MACROS]; - MacroPathPosition *mMacroPath[MAX_MACROS]; - int mMacroMin; - int mMacroMax; - int mMacroSampleCount; - int mMacroPathCount; - + MacroSample *mMacroSample[MAX_MACROS]; + MacroPathPosition *mMacroPath[MAX_MACROS]; + int mMacroMin; + int mMacroMax; + int mMacroSampleCount; + int mMacroPathCount; + /* Macro variables */ - IntEvent *mPMCVariable[MAX_PMC]; - int mPMCAddress[MAX_PMC]; - int mPMCCount; - - unsigned short mFlibhndl; - bool mConnected, mConfigured; + IntEvent *mPMCVariable[MAX_PMC]; + int mPMCAddress[MAX_PMC]; + int mPMCCount; + + unsigned short mFlibhndl; + bool mConnected, mConfigured; bool mAllowDNC; - int mDevicePort; + int mDevicePort; char mDeviceIP[MAX_HOST_LEN]; - -protected: - void connect(); - void configure(); + +protected: + void connect(); + void configure(); void configMacrosAndPMC(const char *aIniFile); - - void reconnect(); - void disconnect(); - void getMessages(); - - void getPathData(); - - void getMacros(); - void getPMC(); - - void getCounts(); - - void innerGatherDeviceData(); - -public: + + void reconnect(); + void disconnect(); + void getMessages(); + + void getPathData(); + + void getMacros(); + void getPMC(); + + void getCounts(); + + void innerGatherDeviceData(); + +public: FanucAdapter(int aServerPort); - ~FanucAdapter(); - - // For Service + ~FanucAdapter(); + + // For Service virtual void initialize(int aArgc, const char *aArgv[]); virtual void start(); virtual void stop(); - + virtual void gatherDeviceData(); -}; +}; #endif diff --git a/fanuc/fanuc_axis.cpp b/fanuc/fanuc_axis.cpp index 3bfe83d..c4cfb8c 100644 --- a/fanuc/fanuc_axis.cpp +++ b/fanuc/fanuc_axis.cpp @@ -1,29 +1,28 @@ -/* - * Copyright Copyright 2012, System Insights, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "internal.hpp" +// +// Copyright Copyright 2012, System Insights, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "internal.hpp" #include "Fwlib32.h" -#include "fanuc_path.hpp" +#include "fanuc_path.hpp" #include "logger.hpp" - -using namespace std; - + +using namespace std; + FanucAxis::FanucAxis(Adapter *anAdapter, string aPrefix, int aIndex) : mIndex(aIndex), mDivisor(1.0) -{ +{ mActual.setName((aPrefix + "act").c_str()); anAdapter->addDatum(mActual); mLoad.setName((aPrefix + "load").c_str()); @@ -34,32 +33,32 @@ FanucAxis::FanucAxis(Adapter *anAdapter, string aPrefix, int aIndex) anAdapter->addDatum(mOverheat); mServo.setName((aPrefix + "servo").c_str()); anAdapter->addDatum(mServo); -} - +} + bool FanucAxis::gatherData(ODBDY2 *aDynamic, ODBSVLOAD *aLoads) -{ +{ mActual.setValue(aDynamic->pos.faxis.machine[mIndex] / mDivisor); mLoad.setValue(aLoads[mIndex].svload.data / pow((long double) 10.0, (long double) aLoads[mIndex].svload.dec)); - return true; -} - + return true; +} + FanucSpindle::FanucSpindle(Adapter *anAdapter, string aPrefix, int aIndex) : mIndex(aIndex) -{ +{ mSpeed.setName((aPrefix + "speed").c_str()); anAdapter->addDatum(mSpeed); mLoad.setName((aPrefix + "load").c_str()); anAdapter->addDatum(mLoad); mServo.setName((aPrefix + "servo").c_str()); anAdapter->addDatum(mServo); -} - +} + bool FanucSpindle::gatherData(ODBSPLOAD *aLoads, ODBACT2 *aSpeeds) -{ +{ mLoad.setValue(aLoads[mIndex].spload.data / pow((long double) 10.0, (long double) aLoads[mIndex].spload.dec)); - mSpeed.setValue(aSpeeds->data[mIndex]); - return true; -} + mSpeed.setValue(aSpeeds->data[mIndex]); + return true; +} diff --git a/fanuc/fanuc_axis.hpp b/fanuc/fanuc_axis.hpp index 49e074d..0842805 100644 --- a/fanuc/fanuc_axis.hpp +++ b/fanuc/fanuc_axis.hpp @@ -1,60 +1,60 @@ -/* - * Copyright Copyright 2012, System Insights, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ #include "device_datum.hpp" #include "condition.hpp" #include "adapter.hpp" -#include +// +// Copyright Copyright 2012, System Insights, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include #include "Fwlib32.h" - -class FanucAxis -{ -public: + +class FanucAxis +{ +public: FanucAxis(Adapter *anAdapter, std::string aPrefix, int anIndex); - ~FanucAxis() {} - + ~FanucAxis() {} + bool gatherData(ODBDY2 *aDynamic, ODBSVLOAD *aLoads); - -public: - int mIndex; + +public: + int mIndex; - Sample mActual; - Sample mLoad; + Sample mActual; + Sample mLoad; - double mDivisor; + double mDivisor; - Condition mTravel; - Condition mOverheat; - Condition mServo; -}; - -class FanucSpindle -{ -public: + Condition mTravel; + Condition mOverheat; + Condition mServo; +}; + +class FanucSpindle +{ +public: FanucSpindle(Adapter *anAdapter, std::string aPrefix, int anIndex); - ~FanucSpindle() {} - + ~FanucSpindle() {} + bool gatherData(ODBSPLOAD *aLoads, ODBACT2 *aSpeeds); - -public: - int mIndex; + +public: + int mIndex; - Sample mSpeed; - Sample mLoad; + Sample mSpeed; + Sample mLoad; - Condition mServo; -}; + Condition mServo; +}; diff --git a/fanuc/fanuc_path.cpp b/fanuc/fanuc_path.cpp index 5c3ae1f..ba130b0 100644 --- a/fanuc/fanuc_path.cpp +++ b/fanuc/fanuc_path.cpp @@ -1,18 +1,18 @@ -/* - * Copyright Copyright 2012, System Insights, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// +// Copyright Copyright 2012, System Insights, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// #include "internal.hpp" #include "Fwlib32.h" @@ -60,8 +60,8 @@ FanucPath::FanucPath(Adapter *anAdapter, short aPathNumber) addDatum(mExecution, "execution", number); addDatum(mCommandedFeedrate, "f_command", number); - // Only track estop on the first path. Should be the same for all - // paths, only one estop per machine. + // Only track estop on the first path. Should be the same for all + // paths, only one estop per machine. if (aPathNumber == 1) addDatum(mEStop, "estop", number); } @@ -71,38 +71,38 @@ FanucPath::~FanucPath() size_t i; for (i = 0; i < mAxes.size(); i++) delete mAxes[i]; - mAxes.clear(); + mAxes.clear(); i; for (i = 0; i < mSpindles.size(); i++) delete mSpindles[i]; - mSpindles.clear(); + mSpindles.clear(); } bool FanucPath::configure(unsigned short aFlibhndl) { int ret = cnc_setpath(aFlibhndl, mPathNumber); - if (ret != EW_OK) - { - gLogger->error("Could not cnc_setpath: %d"); - return false; - } + if (ret != EW_OK) + { + gLogger->error("Could not cnc_setpath: %d"); + return false; + } - gLogger->info("Configuration for path %d:", mPathNumber); + gLogger->info("Configuration for path %d:", mPathNumber); - // Get system info for this path: + // Get system info for this path: ODBSYS sysinfo; ret = cnc_sysinfo(aFlibhndl, &sysinfo); - if (ret == EW_OK) - { - gLogger->info(" Max Axis: %d", sysinfo.max_axis); - gLogger->info(" CNC Type: %c%c", sysinfo.cnc_type[0], sysinfo.cnc_type[1]); - gLogger->info(" MT Type: %c%c", sysinfo.mt_type[0], sysinfo.mt_type[1]); + if (ret == EW_OK) + { + gLogger->info(" Max Axis: %d", sysinfo.max_axis); + gLogger->info(" CNC Type: %c%c", sysinfo.cnc_type[0], sysinfo.cnc_type[1]); + gLogger->info(" MT Type: %c%c", sysinfo.mt_type[0], sysinfo.mt_type[1]); gLogger->info(" Series: %c%c", sysinfo.series[0], sysinfo.series[1], sysinfo.series[2], sysinfo.series[3]); gLogger->info(" Version: %c%c", sysinfo.version[0], sysinfo.version[1], sysinfo.version[2], sysinfo.version[3]); - gLogger->info(" Axes: %c%c", sysinfo.axes[0], sysinfo.axes[1]); - } + gLogger->info(" Axes: %c%c", sysinfo.axes[0], sysinfo.axes[1]); + } return configureAxes(aFlibhndl) && @@ -115,24 +115,24 @@ bool FanucPath::configureSpindles(unsigned short aFlibhndl) mSpindleCount = MAX_SPINDLE; short ret = cnc_rdspdlname(aFlibhndl, &mSpindleCount, spindles); if (ret == EW_OK) - { + { int i = 0; for (i = 0; i < mSpindleCount; i++) - { + { gLogger->info("Spindle %d : %c%c%c", i, spindles[i].name, spindles[i].suff1, spindles[i].suff2); char name[12]; int j = 0; name[j++] = spindles[i].name; if (spindles[i].suff1 > 0) name[j++] = spindles[i].suff1; - if (mPathNumber > 1) + if (mPathNumber > 1) name[j++] = mPathNumber + '0'; name[j] = '\0'; mSpindles.push_back(new FanucSpindle(mAdapter, name, i)); - } - - return true; + } + + return true; } else { @@ -143,41 +143,41 @@ bool FanucPath::configureSpindles(unsigned short aFlibhndl) bool FanucPath::configureAxes(unsigned short aFlibhndl) { - const int num = 1; - short types[num] = { 1 /* actual position */ }; - short len = MAX_AXIS; + const int num = 1; + short types[num] = { 1 /* actual position */ }; + short len = MAX_AXIS; ODBAXDT axisData[MAX_AXIS * num]; short ret = cnc_rdaxisdata(aFlibhndl, 1 /* Position Value */, (short*) types, num, &len, axisData); - bool hasAxisData = ret == EW_OK; - if (!hasAxisData) + bool hasAxisData = ret == EW_OK; + if (!hasAxisData) { - gLogger->error("cnc_rdaxisdata returned %d for path %d", ret, mPathNumber); + gLogger->error("cnc_rdaxisdata returned %d for path %d", ret, mPathNumber); } ODBAXISNAME axes[MAX_AXIS]; - mAxisCount = MAX_AXIS; + mAxisCount = MAX_AXIS; ret = cnc_rdaxisname(aFlibhndl, &mAxisCount, axes); if (ret == EW_OK) - { + { int i = 0; - string activeAxes; + string activeAxes; for (i = 0; i < mAxisCount; i++) - { - bool add = true; - gLogger->info("Axis %d : %c%c", i, axes[i].name, axes[i].suff); - if (hasAxisData) - { - gLogger->info("Axis %s #%d - actual (unit %d flag 0x%X)", + { + bool add = true; + gLogger->info("Axis %d : %c%c", i, axes[i].name, axes[i].suff); + if (hasAxisData) + { + gLogger->info("Axis %s #%d - actual (unit %d flag 0x%X)", axisData[i].name, i, axisData[i].unit, axisData[i].flag); - // Skip this axis if it isn't displayed - if ((axisData[i].flag & 0x01) == 0) - { - gLogger->info(" This is an non-display axis, skipping"); - add = false; - } - - switch (axisData[i].unit) - { + // Skip this axis if it isn't displayed + if ((axisData[i].flag & 0x01) == 0) + { + gLogger->info(" This is an non-display axis, skipping"); + add = false; + } + + switch (axisData[i].unit) + { case 0: gLogger->info(" Units: mm"); break; case 1: gLogger->info(" Units: inch"); break; case 2: gLogger->info(" Units: degree"); break; @@ -188,14 +188,14 @@ bool FanucPath::configureAxes(unsigned short aFlibhndl) case 7: gLogger->info(" Units: inch/round"); break; case 8: gLogger->info(" Units: %%"); break; case 9: gLogger->info(" Units: Ampere"); break; - } - } + } + } if (add) { - if (mAxes.size() > 0) - activeAxes += " "; - + if (mAxes.size() > 0) + activeAxes += " "; + char name[12]; int j = 0; name[j++] = axes[i].name; @@ -206,17 +206,17 @@ bool FanucPath::configureAxes(unsigned short aFlibhndl) activeAxes += name; FanucAxis *axis = new FanucAxis(mAdapter, name, i); - mAxes.push_back(axis); + mAxes.push_back(axis); if (axes[i].name == 'X' && (axes[i].suff == 0 || mXAxis == NULL)) - mXAxis = axis; + mXAxis = axis; else if (axes[i].name == 'Y' && (axes[i].suff == 0 || mYAxis == NULL)) - mYAxis = axis; + mYAxis = axis; else if (axes[i].name == 'Z' && (axes[i].suff == 0 || mZAxis == NULL)) - mZAxis = axis; + mZAxis = axis; } - } - mActiveAxes.setValue(activeAxes.c_str()); + } + mActiveAxes.setValue(activeAxes.c_str()); } else { @@ -232,23 +232,23 @@ bool FanucPath::configureAxes(unsigned short aFlibhndl) mAxes[i]->mDivisor = pow((long double) 10.0, (long double) inprec[i]); } else - { - gLogger->error("Failed to get axis scale: %d\n", ret); - return false; - } + { + gLogger->error("Failed to get axis scale: %d\n", ret); + return false; + } - return true; + return true; } bool FanucPath::gatherData(unsigned short aFlibhndl) { int ret; ret = cnc_setpath(aFlibhndl, mPathNumber); - if (ret != EW_OK) - { - gLogger->error("Cannot set path to: %d, %d", ret); - return false; - } + if (ret != EW_OK) + { + gLogger->error("Cannot set path to: %d, %d", ret); + return false; + } return getProgramInfo(aFlibhndl) && getStatus(aFlibhndl) && @@ -261,30 +261,30 @@ bool FanucPath::getProgramInfo(unsigned short aFlibhndl) { int ret; char buf[1024]; - unsigned short len = sizeof(buf); + unsigned short len = sizeof(buf); short num; ret = cnc_rdexecprog(aFlibhndl, (unsigned short*) &len, &num, buf); - if (ret == EW_OK) - { + if (ret == EW_OK) + { buf[len] = '\0'; for (int i = 0; i < len; i++) - { - if (buf[i] == '\n') - { - buf[i] = '\0'; - break; - } - } + { + if (buf[i] == '\n') + { + buf[i] = '\0'; + break; + } + } - mBlock.setValue(buf); + mBlock.setValue(buf); - return true; - } - else - { - gLogger->error("Cannot cnc_rdexecprog for path %d: %d", mPathNumber, ret); - return false; - } + return true; + } + else + { + gLogger->error("Cannot cnc_rdexecprog for path %d: %d", mPathNumber, ret); + return false; + } } bool FanucPath::getStatus(unsigned short aFlibhndl) @@ -293,35 +293,35 @@ bool FanucPath::getStatus(unsigned short aFlibhndl) memset(&status, 0, sizeof(status)); int ret = cnc_statinfo(aFlibhndl, &status); if (ret == EW_OK) - { - if (status.run == 3 || status.run == 4) // STaRT - mExecution.setValue(Execution::eACTIVE); - else - { - if (status.run == 2 || status.motion == 2 || status.mstb != 0) // HOLD or motion is Wait - mExecution.setValue(Execution::eINTERRUPTED); - else if (status.run == 0) // STOP - mExecution.setValue(Execution::eSTOPPED); - else - mExecution.setValue(Execution::eREADY); - } - - // This will take care of JOG - if (status.aut == 5 || status.aut == 6) - mMode.setValue(ControllerMode::eMANUAL); - else if (status.aut == 0 ||status.aut == 3) // MDI and EDIT - mMode.setValue(ControllerMode::eMANUAL_DATA_INPUT); - else // Otherwise AUTOMATIC - mMode.setValue(ControllerMode::eAUTOMATIC); - - if (mPathNumber == 1) - { - if (status.emergency == 1) - mEStop.setValue(EmergencyStop::eTRIGGERED); - else - mEStop.setValue(EmergencyStop::eARMED); - } - return true; + { + if (status.run == 3 || status.run == 4) // STaRT + mExecution.setValue(Execution::eACTIVE); + else + { + if (status.run == 2 || status.motion == 2 || status.mstb != 0) // HOLD or motion is Wait + mExecution.setValue(Execution::eINTERRUPTED); + else if (status.run == 0) // STOP + mExecution.setValue(Execution::eSTOPPED); + else + mExecution.setValue(Execution::eREADY); + } + + // This will take care of JOG + if (status.aut == 5 || status.aut == 6) + mMode.setValue(ControllerMode::eMANUAL); + else if (status.aut == 0 ||status.aut == 3) // MDI and EDIT + mMode.setValue(ControllerMode::eMANUAL_DATA_INPUT); + else // Otherwise AUTOMATIC + mMode.setValue(ControllerMode::eAUTOMATIC); + + if (mPathNumber == 1) + { + if (status.emergency == 1) + mEStop.setValue(EmergencyStop::eTRIGGERED); + else + mEStop.setValue(EmergencyStop::eARMED); + } + return true; } else { @@ -332,46 +332,46 @@ bool FanucPath::getStatus(unsigned short aFlibhndl) bool FanucPath::getToolData(unsigned short aFlibhndl) { - if (mToolManagementEnabled) - { + if (mToolManagementEnabled) + { ODBTLIFE4 toolId2; short ret = cnc_toolnum(aFlibhndl, 0, 0, &toolId2); ODBTLIFE3 toolId; ret = cnc_rdntool(aFlibhndl, 0, &toolId); - if (ret == EW_OK && toolId.data != 0) - { - mToolId.setValue(toolId.data); - mToolGroup.setValue(toolId.datano); - } - else - { - gLogger->warning("Cannot cnc_rdntool for path %d: %d", mPathNumber, ret); - mToolManagementEnabled = false; - gLogger->warning("Trying modal tool number", mPathNumber, ret); - mUseModalToolData = true; - } - } - - if (mUseModalToolData) - { + if (ret == EW_OK && toolId.data != 0) + { + mToolId.setValue(toolId.data); + mToolGroup.setValue(toolId.datano); + } + else + { + gLogger->warning("Cannot cnc_rdntool for path %d: %d", mPathNumber, ret); + mToolManagementEnabled = false; + gLogger->warning("Trying modal tool number", mPathNumber, ret); + mUseModalToolData = true; + } + } + + if (mUseModalToolData) + { ODBMDL command; short ret = cnc_modal(aFlibhndl, 108, 1, &command); - if (ret == EW_OK) - { - //gLogger->debug("cnc_modal returned: datano %d and type %d: %d %X %X", - // command.datano, command.type, command.modal.aux.aux_data, command.modal.aux.flag1, - // command.modal.aux.flag2); - mToolId.setValue(command.modal.aux.aux_data); - } - else - { - gLogger->warning("cnc_modal failed for T on path %d: %d", mPathNumber, ret); - mUseModalToolData = false; - } - } - - return true; + if (ret == EW_OK) + { + //gLogger->debug("cnc_modal returned: datano %d and type %d: %d %X %X", + // command.datano, command.type, command.modal.aux.aux_data, command.modal.aux.flag1, + // command.modal.aux.flag2); + mToolId.setValue(command.modal.aux.aux_data); + } + else + { + gLogger->warning("cnc_modal failed for T on path %d: %d", mPathNumber, ret); + mUseModalToolData = false; + } + } + + return true; } bool FanucPath::getHeader(unsigned short aFlibhndl, int aProg) @@ -426,8 +426,8 @@ bool FanucPath::getHeader(unsigned short aFlibhndl, int aProg) bool FanucPath::getAxisData(unsigned short aFlibhndl) { - if (mAxisCount <= 0) - return true; + if (mAxisCount <= 0) + return true; short ret; @@ -436,147 +436,147 @@ bool FanucPath::getAxisData(unsigned short aFlibhndl) ODBDY2 dyn; memset(&dyn, 0xEF, sizeof(dyn)); ret = cnc_rddynamic2(aFlibhndl, ALL_AXES, sizeof(dyn), &dyn); - if (ret != EW_OK) - { - gLogger->error("Cannot get the rddynamic2 data for path %d: %d", mPathNumber, ret); - return false; - } + if (ret != EW_OK) + { + gLogger->error("Cannot get the rddynamic2 data for path %d: %d", mPathNumber, ret); + return false; + } - mLine.setValue(dyn.seqnum); + mLine.setValue(dyn.seqnum); ODBSVLOAD axLoad[MAX_AXIS]; - short num = MAX_AXIS; + short num = MAX_AXIS; ret = cnc_rdsvmeter(aFlibhndl, &num, axLoad); - if (ret != EW_OK) - { - gLogger->error("cnc_rdsvmeter failed for path %d: %d", mPathNumber, ret); - return false; - } + if (ret != EW_OK) + { + gLogger->error("cnc_rdsvmeter failed for path %d: %d", mPathNumber, ret); + return false; + } char buf[32]; if (dyn.prgnum != mProgramNum) getHeader(aFlibhndl, dyn.prgnum); - mProgramNum = dyn.prgnum; - sprintf(buf, "%d.%d", dyn.prgmnum, dyn.prgnum); - mProgramName.setValue(buf); + mProgramNum = dyn.prgnum; + sprintf(buf, "%d.%d", dyn.prgmnum, dyn.prgnum); + mProgramName.setValue(buf); - // Update all the axes + // Update all the axes vector::iterator axis; for (axis = mAxes.begin(); axis != mAxes.end(); axis++) { (*axis)->gatherData(&dyn, axLoad); } - mPathFeedrate.setValue(dyn.actf); - - // Get the modal feed for this path + mPathFeedrate.setValue(dyn.actf); + + // Get the modal feed for this path ODBMDL command; ret = cnc_modal(aFlibhndl, 103, 1, &command); - if (ret == EW_OK) + if (ret == EW_OK) { - mCommandedFeedrate.setValue(command.modal.aux.aux_data); + mCommandedFeedrate.setValue(command.modal.aux.aux_data); } - double x = 0.0, y = 0.0, z = 0.0; + double x = 0.0, y = 0.0, z = 0.0; if (mXAxis != NULL) - x = dyn.pos.faxis.absolute[mXAxis->mIndex] / mXAxis->mDivisor; + x = dyn.pos.faxis.absolute[mXAxis->mIndex] / mXAxis->mDivisor; if (mYAxis != NULL) - y = dyn.pos.faxis.absolute[mYAxis->mIndex] / mYAxis->mDivisor; + y = dyn.pos.faxis.absolute[mYAxis->mIndex] / mYAxis->mDivisor; if (mZAxis != NULL) - z = dyn.pos.faxis.absolute[mZAxis->mIndex] / mZAxis->mDivisor; - - mPathPosition.setValue(x, y, z); + z = dyn.pos.faxis.absolute[mZAxis->mIndex] / mZAxis->mDivisor; + + mPathPosition.setValue(x, y, z); getCondition(aFlibhndl, dyn.alarm); - return true; + return true; } bool FanucPath::getSpindleData(unsigned short aFlibhndl) { - if (mSpindleCount <= 0) - return true; + if (mSpindleCount <= 0) + return true; - // Handle spindle data... + // Handle spindle data... ODBACT2 speeds; int ret = cnc_acts2(aFlibhndl, ALL_SPINDLES, &speeds); - if (ret != EW_OK) - { - gLogger->error("cnc_acts2 failed: %d for path number: %d", ret, mPathNumber); - return false; - } - + if (ret != EW_OK) + { + gLogger->error("cnc_acts2 failed: %d for path number: %d", ret, mPathNumber); + return false; + } + ODBSPLOAD spLoad[MAX_SPINDLE]; - short num = MAX_SPINDLE; + short num = MAX_SPINDLE; ret = cnc_rdspmeter(aFlibhndl, 0, &num, spLoad); - if (ret != EW_OK) - { - gLogger->error("cnc_rdspmeter failed: %d", ret); - return false; - } - - if (num > mSpindleCount) - { - gLogger->error("spindle load has more spindles than names: %d > %d\n", - num, mSpindleCount); - return false; - } - - // Update all the axes + if (ret != EW_OK) + { + gLogger->error("cnc_rdspmeter failed: %d", ret); + return false; + } + + if (num > mSpindleCount) + { + gLogger->error("spindle load has more spindles than names: %d > %d\n", + num, mSpindleCount); + return false; + } + + // Update all the axes vector::iterator spindle; for (spindle = mSpindles.begin(); spindle != mSpindles.end(); spindle++) { (*spindle)->gatherData(spLoad, &speeds); } - - return true; + + return true; } Condition *FanucPath::translateAlarmNo(long aNum, int aAxis) { switch(aNum) - { - case 0: // Parameter Switch Off - return &mLogic; + { + case 0: // Parameter Switch Off + return &mLogic; - case 2: // I/O - case 7: // Data I/O - return &mComms; + case 2: // I/O + case 7: // Data I/O + return &mComms; - case 4: // Overtravel + case 4: // Overtravel if (aAxis > 0) return &(mAxes[aAxis - 1]->mTravel); - else - return &mSystem; + else + return &mSystem; - case 5: // Overheat + case 5: // Overheat if (aAxis > 0) return &(mAxes[aAxis - 1]->mOverheat); - else - return &mSystem; + else + return &mSystem; - case 6: // Servo + case 6: // Servo if (aAxis > 0) return &(mAxes[aAxis - 1]->mServo); - else - return &mServo; + else + return &mServo; - case 12: // Background P/S - case 3: // Forground P/S - case 8: // Macro - return &mMotion; + case 12: // Background P/S + case 3: // Forground P/S + case 8: // Macro + return &mMotion; - case 9: // Spindle - return &(mSpindles[0]->mServo); - - case 19: // PMC - return &mLogic; - - default: // 10, 11, 13, 15. - return &mSystem; - } + case 9: // Spindle + return &(mSpindles[0]->mServo); + + case 19: // PMC + return &mLogic; + + default: // 10, 11, 13, 15. + return &mSystem; + } return NULL; } @@ -586,30 +586,30 @@ void FanucPath::getCondition(unsigned short aFlibhndl, long aAlarm) if (aAlarm != 0) { for (int i = 0; i < 31; i++) - { + { if (aAlarm & (0x1 << i)) - { + { ODBALMMSG2 alarms[MAX_AXIS]; - short num = MAX_AXIS; + short num = MAX_AXIS; short ret = cnc_rdalmmsg2(aFlibhndl, i, &num, alarms); - if (ret != EW_OK) - continue; + if (ret != EW_OK) + continue; for (int j = 0; j < num; j++) - { + { ODBALMMSG2 &alarm = alarms[j]; char num[16]; Condition *cond = translateAlarmNo(i, alarm.axis); if (cond == NULL) - continue; + continue; sprintf(num, "%d", alarm.alm_no); cond->add(Condition::eFAULT, alarm.alm_msg, num); } - } - } - } + } + } + } } - + diff --git a/fanuc/fanuc_path.hpp b/fanuc/fanuc_path.hpp index 971df36..6753fba 100644 --- a/fanuc/fanuc_path.hpp +++ b/fanuc/fanuc_path.hpp @@ -1,46 +1,46 @@ -/* - * Copyright Copyright 2012, System Insights, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "device_datum.hpp" -#include "condition.hpp" -#include "adapter.hpp" -#include "fanuc_axis.hpp" -#include - -class StaticEvent : public Event -{ -public: +// +// Copyright Copyright 2012, System Insights, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "device_datum.hpp" +#include "condition.hpp" +#include "adapter.hpp" +#include "fanuc_axis.hpp" +#include + +class StaticEvent : public Event +{ +public: StaticEvent(const char *aName = "") : Event(aName) {} virtual bool unavailable() { return false; - } -}; - -class FanucPath -{ -public: + } +}; + +class FanucPath +{ +public: FanucPath(Adapter *anAdapter, short aPathNumber); - ~FanucPath(); - + ~FanucPath(); + void allowDNC(const bool aAllow) { mAllowDNC = aAllow; } bool configure(unsigned short mFlibhndl); bool gatherData(unsigned short mFlibhndl); - -protected: + +protected: bool configureAxes(unsigned short mFlibhndl); bool configureSpindles(unsigned short mFlibhndl); @@ -50,52 +50,52 @@ class FanucPath bool getHeader(unsigned short aFlibhndl, int aProg); bool getAxisData(unsigned short aFlibhndl); bool getSpindleData(unsigned short aFlibhndl); - + void getCondition(unsigned short aFlibhndl, long aAlarm); Condition *translateAlarmNo(long aNum, int aAxis); - - + + void addDatum(DeviceDatum &aDatum, const char *aName, const char *aSuffix); - -protected: + +protected: bool mConfigured; - Adapter *mAdapter; - - short mPathNumber; - - // Path specific data items - Execution mExecution; - IntEvent mToolId; - IntEvent mToolGroup; - Event mProgramName; - Event mProgramComment; - IntEvent mLine; - Event mBlock; - StaticEvent mActiveAxes; - ControllerMode mMode; - EmergencyStop mEStop; - - Sample mPathFeedrate; - PathPosition mPathPosition; - Sample mCommandedFeedrate; - - int mProgramNum; - short mSpindleCount; - short mAxisCount; - - bool mToolManagementEnabled; - bool mUseModalToolData; + Adapter *mAdapter; + + short mPathNumber; + + // Path specific data items + Execution mExecution; + IntEvent mToolId; + IntEvent mToolGroup; + Event mProgramName; + Event mProgramComment; + IntEvent mLine; + Event mBlock; + StaticEvent mActiveAxes; + ControllerMode mMode; + EmergencyStop mEStop; + + Sample mPathFeedrate; + PathPosition mPathPosition; + Sample mCommandedFeedrate; + + int mProgramNum; + short mSpindleCount; + short mAxisCount; + + bool mToolManagementEnabled; + bool mUseModalToolData; bool mAllowDNC; - - // Path related conditions - Condition mServo; - Condition mComms; - Condition mLogic; - Condition mMotion; - Condition mSystem; - - FanucAxis *mXAxis, *mYAxis, *mZAxis; - - std::vector mAxes; - std::vector mSpindles; -}; + + // Path related conditions + Condition mServo; + Condition mComms; + Condition mLogic; + Condition mMotion; + Condition mSystem; + + FanucAxis *mXAxis, *mYAxis, *mZAxis; + + std::vector mAxes; + std::vector mSpindles; +}; diff --git a/src/adapter.cpp b/src/adapter.cpp index f729a46..319ac62 100755 --- a/src/adapter.cpp +++ b/src/adapter.cpp @@ -1,36 +1,35 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// #include "internal.hpp" #include "adapter.hpp" #include "device_datum.hpp" @@ -54,9 +53,9 @@ Adapter::Adapter(int aPort, int aScanDelay) Adapter::~Adapter() { - mRunning = false; - if (mServer) - delete mServer; + mRunning = false; + if (mServer) + delete mServer; delete[] mDeviceData; } @@ -69,11 +68,11 @@ void Adapter::addDatum(DeviceDatum &aValue) DeviceDatum** devData = new DeviceDatum*[mMaxDatum * 2]; memcpy(devData, mDeviceData, sizeof(DeviceDatum*) * mMaxDatum); delete[] mDeviceData; - + mDeviceData = devData; mMaxDatum *= 2; } - + mDeviceData[mNumDeviceData++] = &aValue; mDeviceData[mNumDeviceData] = 0; } @@ -85,7 +84,7 @@ void Adapter::sleepMs(int aMs) #else Sleep(aMs); #endif - + } #if THREADED @@ -95,41 +94,41 @@ void Adapter::sleepMs(int aMs) static int ServerThread(void *aArg) { Adapter *adapter = (Adapter*) aArg; - adapter->serverThread(); - return 0; + adapter->serverThread(); + return 0; } -bool Adapter::startServerThread() +bool Adapter::startServerThread() { if (gLogger == NULL) gLogger = new Logger(); - - mServer = new Server(mPort, mHeartbeatFrequency); - mRunning = true; - mServerThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) &ServerThread, this, 0, 0); + mServer = new Server(mPort, mHeartbeatFrequency); + mRunning = true; + + mServerThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) &ServerThread, this, 0, 0); if (mServerThread == NULL) { - fprintf(stderr, "Cannot create server thread"); + fprintf(stderr, "Cannot create server thread"); delete mServer; - return false; + return false; } else { Sleep(10); - } - - return true; + } + + return true; } int Adapter::waitUntilDone() { - int ret = 1; + int ret = 1; if (mServerThread != 0) { DWORD res = WaitForSingleObject(mServerThread, INFINITE); - if (res == WAIT_OBJECT_0) - { - if (GetExitCodeThread(mServerThread, &res)) - ret = res; - } - } - return ret; + if (res == WAIT_OBJECT_0) + { + if (GetExitCodeThread(mServerThread, &res)) + ret = res; + } + } + return ret; } #else @@ -137,39 +136,39 @@ int Adapter::waitUntilDone() static void *ServerThread(void *aArg) { Adapter *adapter = (Adapter*) aArg; - adapter->serverThread(); + adapter->serverThread(); - static int res = 0; - return &res; + static int res = 0; + return &res; } -bool Adapter::startServerThread() +bool Adapter::startServerThread() { if (gLogger == NULL) gLogger = new Logger(); - - mServer = new Server(mPort, mHeartbeatFrequency); - mRunning = true; + + mServer = new Server(mPort, mHeartbeatFrequency); + mRunning = true; int res = pthread_create(&mServerThread, NULL, ::ServerThread, this); if (res != 0) { - fprintf(stderr, "Cannot create server thread"); + fprintf(stderr, "Cannot create server thread"); delete mServer; - return false; - } - - return true; + return false; + } + + return true; } int Adapter::waitUntilDone() { - int ret = 1; + int ret = 1; if (mServerThread != 0) { int *value; int res = pthread_join(mServerThread, (void**) &value); if (res != 0) ret = *value; - } - return ret; + } + return ret; } #endif @@ -180,13 +179,13 @@ int Adapter::waitUntilDone() void Adapter::serverThread() { while (mRunning) { - connectToClients(); - readFromClients(); + connectToClients(); + readFromClients(); - periodicWork(); - - sleepMs(mScanDelay); - } + periodicWork(); + + sleepMs(mScanDelay); + } } #endif @@ -194,9 +193,9 @@ void Adapter::serverThread() /* * Reads from clients, either blocking or polling. */ -void Adapter::readFromClients() +void Adapter::readFromClients() { - mServer->readFromClients(); + mServer->readFromClients(); } /* @@ -208,9 +207,9 @@ void Adapter::connectToClients() /* Check if we have any new clients */ Client *client = mServer->connectToClients(); if (client != NULL) - sendInitialData(client); + sendInitialData(client); } - + /* * This is the main loop of the application. Once the server is started and * the application runs forever until it is killed. The process follows this flow: @@ -225,43 +224,43 @@ void Adapter::connectToClients() * Sleep for a few millies and repeat. */ void Adapter::startServer() -{ +{ if (gLogger == NULL) gLogger = new Logger(); - - mServer = new Server(mPort, mHeartbeatFrequency); - mRunning = true; - + + mServer = new Server(mPort, mHeartbeatFrequency); + mRunning = true; + /* Process untill stopped */ - while (mRunning) - { + while (mRunning) + { /* Check if we have any new clients */ - connectToClients(); - + connectToClients(); + /* Read and all data from the clients */ - readFromClients(); - + readFromClients(); + /* Don't bother getting data if we don't have anyone to read it */ - if (mServer->numClients() > 0) + if (mServer->numClients() > 0) + { + MTCAutoLock lock(mGatherLock); + + begin(); + mBuffer.timestamp(); + gatherDeviceData(); + prepare(); + sendChangedData(); + mBuffer.reset(); + cleanup(); + } + else if (mServer->hasClients()) { - MTCAutoLock lock(mGatherLock); - - begin(); - mBuffer.timestamp(); - gatherDeviceData(); - prepare(); - sendChangedData(); - mBuffer.reset(); - cleanup(); + clientsDisconnected(); } - else if (mServer->hasClients()) - { - clientsDisconnected(); - } - - sleepMs(mScanDelay); - } - - delete mServer; + + sleepMs(mScanDelay); + } + + delete mServer; mServer = NULL; } @@ -270,7 +269,7 @@ void Adapter::begin() for (int i = 0; i < mNumDeviceData; i++) { DeviceDatum *value = mDeviceData[i]; - value->begin(); + value->begin(); } } @@ -279,7 +278,7 @@ void Adapter::prepare() for (int i = 0; i < mNumDeviceData; i++) { DeviceDatum *value = mDeviceData[i]; - value->prepare(); + value->prepare(); } } @@ -288,80 +287,80 @@ void Adapter::cleanup() for (int i = 0; i < mNumDeviceData; i++) { DeviceDatum *value = mDeviceData[i]; - value->cleanup(); + value->cleanup(); } } void Adapter::beginGather(const char *aTs, bool aSweep) { - mGatherLock.lock(); + mGatherLock.lock(); if (aSweep) begin(); - - mBuffer.reset(); + + mBuffer.reset(); if (aTs != NULL) mBuffer.setTimestamp(aTs); - else - mBuffer.timestamp(); + else + mBuffer.timestamp(); } void Adapter::completeGather() { - prepare(); - sendChangedData(); - cleanup(); - - mGatherLock.unlock(); + prepare(); + sendChangedData(); + cleanup(); + + mGatherLock.unlock(); } void Adapter::stopServer() -{ - mRunning = false; +{ + mRunning = false; } /* Send a single value to the buffer. */ void Adapter::sendDatum(DeviceDatum *aValue) { if (aValue->requiresFlush()) - sendBuffer(); + sendBuffer(); aValue->append(mBuffer); if (aValue->requiresFlush()) - sendBuffer(); + sendBuffer(); } /* Send the buffer to the clients. Only sends if there is something in the buffer. */ void Adapter::sendBuffer() { if (mServer != 0 && mBuffer.length() > 0) - { - mBuffer.append("\n"); + { + mBuffer.append("\n"); if (mInitializeClient != NULL) - mServer->sendToClient(mInitializeClient, mBuffer); - else - mServer->sendToClients(mBuffer); - mBuffer.reset(); - } + mServer->sendToClient(mInitializeClient, mBuffer); + else + mServer->sendToClients(mBuffer); + mBuffer.reset(); + } } /* Send the initial values to a client */ void Adapter::sendInitialData(Client *aClient) { - MTCAutoLock lock(mGatherLock); + MTCAutoLock lock(mGatherLock); mInitializeClient = aClient; - mDisableFlush = true; - mBuffer.timestamp(); - gatherDeviceData(); - + mDisableFlush = true; + mBuffer.timestamp(); + gatherDeviceData(); + for (int i = 0; i < mNumDeviceData; i++) - { + { DeviceDatum *value = mDeviceData[i]; if (value->hasInitialValue()) - sendDatum(value); - } - sendBuffer(); + sendDatum(value); + } + sendBuffer(); - mDisableFlush = false; + mDisableFlush = false; mInitializeClient = NULL; } @@ -369,28 +368,28 @@ void Adapter::sendInitialData(Client *aClient) void Adapter::sendChangedData() { for (int i = 0; i < mNumDeviceData; i++) - { + { DeviceDatum *value = mDeviceData[i]; if (value->changed()) - sendDatum(value); - } - sendBuffer(); + sendDatum(value); + } + sendBuffer(); } void Adapter::flush() { if (!mDisableFlush) { - sendChangedData(); - mBuffer.reset(); - mBuffer.timestamp(); + sendChangedData(); + mBuffer.reset(); + mBuffer.timestamp(); } } void Adapter::clientsDisconnected() { /* Do nothing for now ... */ - gLogger->info("All clients have disconnected"); + gLogger->info("All clients have disconnected"); } void Adapter::unavailable() @@ -398,9 +397,9 @@ void Adapter::unavailable() for (int i = 0; i < mNumDeviceData; i++) { DeviceDatum *value = mDeviceData[i]; - value->unavailable(); + value->unavailable(); } - flush(); + flush(); } void Adapter::initializeDeviceDatum() @@ -408,40 +407,40 @@ void Adapter::initializeDeviceDatum() for (int i = 0; i < mNumDeviceData; i++) { DeviceDatum *value = mDeviceData[i]; - value->initialize(); + value->initialize(); } - flush(); + flush(); } void Adapter::addAsset(const char *aId, const char *aType, const char *aData) { - sendBuffer(); - mBuffer.timestamp(); + sendBuffer(); + mBuffer.timestamp(); - mBuffer.append("|@ASSET@|"); + mBuffer.append("|@ASSET@|"); mBuffer.append(aId); - mBuffer.append("|"); + mBuffer.append("|"); mBuffer.append(aType); - mBuffer.append("|--multiline--ABCD\n"); + mBuffer.append("|--multiline--ABCD\n"); mBuffer.append(aData); - mBuffer.append("\n--multiline--ABCD"); - - sendBuffer(); - mBuffer.timestamp(); + mBuffer.append("\n--multiline--ABCD"); + + sendBuffer(); + mBuffer.timestamp(); } void Adapter::updateAsset(const char *aId, const char *aData) { - sendBuffer(); - mBuffer.timestamp(); + sendBuffer(); + mBuffer.timestamp(); - mBuffer.append("|@UPDATE_ASSET@|"); + mBuffer.append("|@UPDATE_ASSET@|"); mBuffer.append(aId); - mBuffer.append("|"); + mBuffer.append("|"); mBuffer.append(aData); - sendBuffer(); - mBuffer.timestamp(); + sendBuffer(); + mBuffer.timestamp(); } void Adapter::addAsset(CuttingTool *aTool) diff --git a/src/adapter.hpp b/src/adapter.hpp index 700a416..456a1f1 100644 --- a/src/adapter.hpp +++ b/src/adapter.hpp @@ -1,48 +1,47 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ #ifndef ADAPTER_HPP #define ADAPTER_HPP - -#include "server.hpp" -#include "string_buffer.hpp" -#include "threading.hpp" - -class DeviceDatum; -class CuttingTool; - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include "server.hpp" +#include "string_buffer.hpp" +#include "threading.hpp" + +class DeviceDatum; +class CuttingTool; + const int INITIAL_MAX_DEVICE_DATA = 128; - + /* * Abstract adapter that manages all the data values and writing them * to the clients. @@ -50,9 +49,9 @@ const int INITIAL_MAX_DEVICE_DATA = 128; * Subclasses of this class will add the data values and interact with the * vendor specifc API. This class provides all the common functionality. */ -class Adapter -{ -protected: +class Adapter +{ +protected: Server *mServer; /* The socket server */ StringBuffer mBuffer; /* A string buffer to hold the string we * write to the streams */ @@ -64,100 +63,100 @@ class Adapter bool mDisableFlush; /* Used for initial data collection */ int mHeartbeatFrequency; /* The frequency (ms) to heartbeat * server. Responds to Ping. Default 10 sec */ - bool mRunning; + bool mRunning; Client *mInitializeClient; /* If we are sending initial data to a client */ - -#ifdef THREADED + +#ifdef THREADED #ifdef WIN32 - HANDLE mServerThread; + HANDLE mServerThread; #else - pthread_t mServerThread; -#endif + pthread_t mServerThread; #endif - MTCMutex mGatherLock; - -protected: +#endif + MTCMutex mGatherLock; + +protected: void sleepMs(int aMs); - + /* Internal buffer sending methods */ - void sendBuffer(); + void sendBuffer(); void sendDatum(DeviceDatum *aValue); virtual void sendInitialData(Client *aClient); - virtual void sendChangedData(); - virtual void flush(); - void timestamp() { mBuffer.timestamp(); } - virtual void unavailable(); - virtual void initializeDeviceDatum(); - + virtual void sendChangedData(); + virtual void flush(); + void timestamp() { mBuffer.timestamp(); } + virtual void unavailable(); + virtual void initializeDeviceDatum(); + virtual void addAsset(const char *aId, const char *aType, const char *aData); virtual void updateAsset(const char *aId, const char *aData); virtual void addAsset(CuttingTool *aTool); virtual void updateAsset(CuttingTool *aTool); - -public: + +public: Adapter(int aPort, int aScanDelay = 100); - ~Adapter(); - - void readFromClients(); - void connectToClients(); - + ~Adapter(); + + void readFromClients(); + void connectToClients(); + /* Start the server and never return */ -#ifdef THREADED - bool startServerThread(); - void serverThread(); - int waitUntilDone(); - - // allow for subclasses to do some work when threaded - virtual void periodicWork() {} -#endif - - void startServer(); +#ifdef THREADED + bool startServerThread(); + void serverThread(); + int waitUntilDone(); + + // allow for subclasses to do some work when threaded + virtual void periodicWork() {} +#endif + + void startServer(); void addDatum(DeviceDatum &aValue); - + /* Stop server */ - virtual void stopServer(); - + virtual void stopServer(); + /* Pure virtual method to get the data from the device. */ - virtual void gatherDeviceData() = 0; - virtual void begin(); - virtual void prepare(); - virtual void cleanup(); - + virtual void gatherDeviceData() = 0; + virtual void begin(); + virtual void prepare(); + virtual void cleanup(); + /* For multithreaded async gathering */ virtual void beginGather(const char *aTs = NULL, bool aSweep = true); - virtual void completeGather(); - + virtual void completeGather(); + /* Overload this method to handle situation when all clients disconnect */ - virtual void clientsDisconnected(); -}; - + virtual void clientsDisconnected(); +}; + class AutoGather { -public: +public: AutoGather(Adapter *anAdapter = NULL, const char *aTs = NULL, bool aSweep = true) : mAdapter(anAdapter) { if (mAdapter != NULL) mAdapter->beginGather(aTs, aSweep); - } - + } + void begin(Adapter *anAdapter, const char *aTs = NULL, bool aSweep = true) { mAdapter = anAdapter; if (mAdapter != NULL) mAdapter->beginGather(aTs, aSweep); - } - + } + void complete() { if (mAdapter != NULL) - mAdapter->completeGather(); + mAdapter->completeGather(); mAdapter = NULL; - } - + } + ~AutoGather() { if (mAdapter != NULL) - mAdapter->completeGather(); - } - -protected: - Adapter *mAdapter; -}; + mAdapter->completeGather(); + } + +protected: + Adapter *mAdapter; +}; #endif diff --git a/src/axis.hpp b/src/axis.hpp index 57dc904..21934b5 100644 --- a/src/axis.hpp +++ b/src/axis.hpp @@ -1,92 +1,92 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ #ifndef AXIS_HPP #define AXIS_HPP - -#include "component.hpp" -#include "device_datum.hpp" -#include - -// An abstract axis type. -class Axis : public Component -{ -public: +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include "component.hpp" +#include "device_datum.hpp" +#include + +// An abstract axis type. +class Axis : public Component +{ +public: enum Type { - LINEAR, - ROTARY - }; - + LINEAR, + ROTARY + }; + enum Units { - INCH, - MM - }; - + INCH, + MM + }; + enum Mode { - INDEX, - SPINDLE, - CONTOUR - }; - -protected: - Sample mLoad; - int mNumber; - - Mode mMode; - Type mType; - Units mUnits; - + INDEX, + SPINDLE, + CONTOUR + }; + +protected: + Sample mLoad; + int mNumber; + + Mode mMode; + Type mType; + Units mUnits; + string mName; -public: +public: Axis(Adapter *anAdapter, std::string aName, Component *aParent = NULL); - + Mode getMode() const { return mMode; } Type getType() const { return mType; } Units getUnits() const { return mUnits; } const std::string &getName() { return mName; } - + virtual bool gatherData(void *aArg) = 0; -}; - -class Linear : public Axis -{ -protected: - Sample mActualPosition; - Sample mCommandedPosition; - -public: +}; + +class Linear : public Axis +{ +protected: + Sample mActualPosition; + Sample mCommandedPosition; + +public: Linear(Adapter *anAdapter, std::string aName, Component *aParent = NULL); }; - + #endif // AXIS_HPP diff --git a/src/client.cpp b/src/client.cpp index 8189a77..7741b8d 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -1,74 +1,73 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - -#include "internal.hpp" -#include "client.hpp" -#include "server.hpp" - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include "internal.hpp" +#include "client.hpp" +#include "server.hpp" + /* Instance methods */ Client::Client(SOCKET aSocket) -{ +{ mSocket = aSocket; - mHeartbeats = false; -} - -Client::~Client() -{ - ::shutdown(mSocket, SHUT_RDWR); - ::closesocket(mSocket); -} - + mHeartbeats = false; +} + +Client::~Client() +{ + ::shutdown(mSocket, SHUT_RDWR); + ::closesocket(mSocket); +} + int Client::write(const char *aString) -{ - int res; - MTCAutoLock lock(mWriteLock); - +{ + int res; + MTCAutoLock lock(mWriteLock); + try { res = ::send(mSocket, aString, (int) strlen(aString), 0); - } + } catch(...) { - res = -1; - } - - return res; -} - + res = -1; + } + + return res; +} + int Client::read(char *aBuffer, int aMaxLen) -{ +{ int len = recv(mSocket, aBuffer, aMaxLen, 0); - if (len >= 0) + if (len >= 0) aBuffer[len] = 0; - - return len; -} + + return len; +} diff --git a/src/client.hpp b/src/client.hpp index 4217047..3626af0 100755 --- a/src/client.hpp +++ b/src/client.hpp @@ -1,63 +1,64 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + + #ifndef CLIENT_HPP #define CLIENT_HPP - + #include "threading.hpp" /* * A wrapper around a client socket. An adapter is capable of managing * multiple sockets. */ -class Client -{ +class Client +{ /* Instance Variables */ -protected: - SOCKET mSocket; - MTCMutex mWriteLock; - +protected: + SOCKET mSocket; + MTCMutex mWriteLock; + /* class methods */ -public: - bool mHeartbeats; - unsigned int mLastHeartbeat; - +public: + bool mHeartbeats; + unsigned int mLastHeartbeat; + /* Instance methods */ -public: - Client(SOCKET aSocket); - ~Client(); +public: + Client(SOCKET aSocket); + ~Client(); int write(const char *aString); int read(char *aBuffer, int aLen); SOCKET socket() { return mSocket; } }; - + #endif diff --git a/src/component.hpp b/src/component.hpp index 1f8f9f1..30c7a6d 100644 --- a/src/component.hpp +++ b/src/component.hpp @@ -1,61 +1,60 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - #ifndef COMPONENT_HPP #define COMPONENT_HPP - -#include "internal.hpp" -#include - -class Adapter; - -// An abstract class representing an MTConnect Component. Subclasses -// of Component will create the most common data items and conditions -// for that component. Additional data items can be added for each -// specific implementation -class Component -{ -protected: - Adapter *mAdapter; - std::string mName; +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include "internal.hpp" +#include + +class Adapter; + +// An abstract class representing an MTConnect Component. Subclasses +// of Component will create the most common data items and conditions +// for that component. Additional data items can be added for each +// specific implementation +class Component +{ +protected: + Adapter *mAdapter; + std::string mName; Component *aParent; - -public: + +public: Component(Adapter *anAdapter, std::string aName, Component *aParent = NULL); virtual ~Component(); virtual void initialize(); virtual void gatherData(void *aContext) = 0; }; - + #endif // COMPONENT_HPP - + diff --git a/src/condition.cpp b/src/condition.cpp index dd85beb..97ab71c 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -1,4 +1,35 @@ - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// #include "internal.hpp" #include "condition.hpp" #include "string_buffer.hpp" @@ -11,13 +42,13 @@ Condition::Condition(const char *aName, bool aSimple) : mActiveSize = mInitialActiveListSize; mActiveCount = 0; mActiveList = new ActiveCondition*[mActiveSize]; - mHasValue = true; - unavailable(); + mHasValue = true; + unavailable(); } Condition::~Condition() { - removeAll(); + removeAll(); delete[] mActiveList; } @@ -30,12 +61,12 @@ void Condition::removeAll() bool Condition::requiresFlush() { - return true; + return true; } bool Condition::unavailable() { - return add(eUNAVAILABLE); + return add(eUNAVAILABLE); } char *Condition::toString(char *aBuffer, int aMaxLen) @@ -49,21 +80,21 @@ void Condition::begin() for (int i = 0; i < mActiveCount; i++) { mActiveList[i]->clear(); } - } - mPrepared = false; - mBegun = true; - mChanged = false; + } + mPrepared = false; + mBegun = true; + mChanged = false; } void Condition::cleanup() { - mBegun = false; - mPrepared = false; + mBegun = false; + mPrepared = false; } void Condition::initialize() { - normal(); + normal(); } void Condition::append(StringBuffer &aStringBuffer, char *aBuffer, @@ -71,11 +102,11 @@ void Condition::append(StringBuffer &aStringBuffer, char *aBuffer, { if (!aFirst) aStringBuffer.newline(); - else + else aFirst = false; char *cp = aBuffer + strlen(aBuffer); - + aCond->toString(cp, aMaxLen); appendText(aBuffer, (char*) aCond->getText(), aMaxLen); aStringBuffer.append(aBuffer); @@ -85,74 +116,74 @@ void Condition::prepare() { if (mBegun) { - bool marked = false; + bool marked = false; - // Check to see if we have no marked conditions + // Check to see if we have no marked conditions for (int i = 0; !marked && i < mActiveCount; i++) - { + { if (mActiveList[i]->isPlaceHolder() || mActiveList[i]->isMarked()) - marked = true; - } + marked = true; + } - if (!marked) - normal(); - - // Sweep old conditions + if (!marked) + normal(); + + // Sweep old conditions for (int i = mActiveCount - 1; i >= 0; i--) { ActiveCondition *cond = mActiveList[i]; if (!cond->isPlaceHolder() && !cond->isMarked()) - { + { cond->setValue(eNORMAL, "", cond->getNativeCode()); } - + if (cond->hasChanged()) { - mChanged = true; - } + mChanged = true; + } } - mPrepared = true; + mPrepared = true; } } bool Condition::append(StringBuffer &aBuffer) { - if (!mBegun) - { + if (!mBegun) + { char buffer[1024]; - bool first = true; - buffer[0] = '|'; - strcpy(buffer + 1, mName); + bool first = true; + buffer[0] = '|'; + strcpy(buffer + 1, mName); char *cp = buffer + strlen(buffer); int max = 1024 - strlen(buffer); for (int i = 0; i < mActiveCount; i++) - { - *cp = '\0'; + { + *cp = '\0'; append(aBuffer, buffer, mActiveList[i], first, max); - } + } } else if (mBegun && mPrepared) { char buffer[1024]; - bool first = true; - buffer[0] = '|'; - strcpy(buffer + 1, mName); + bool first = true; + buffer[0] = '|'; + strcpy(buffer + 1, mName); char *cp = buffer + strlen(buffer); int max = 1024 - strlen(buffer); - - // Sweep old conditions + + // Sweep old conditions for (int i = mActiveCount - 1; i >= 0; i--) - { + { ActiveCondition *cond = mActiveList[i]; if (cond->hasChanged()) { - *cp = '\0'; + *cp = '\0'; append(aBuffer, buffer, cond, first, max); - } - + } + // Remove stale conditions since they have now been generated. if (!cond->isPlaceHolder() && !cond->isMarked()) removeAt(i); - } - } - - return mChanged; + } + } + + return mChanged; } bool Condition::isActive(const char *aNativeCode) @@ -170,74 +201,74 @@ bool Condition::add(ELevels aLevel, const char *aText, const char *aCode, { ActiveCondition *cond = NULL; bool res; - // First check for a unassociated normal or a unavailable. + // First check for a unassociated normal or a unavailable. if ((aLevel == eNORMAL || aLevel == eUNAVAILABLE) && aCode[0] == '\0') - { - // See if we are already in this state. + { + // See if we are already in this state. if (mActiveCount == 1 && mActiveList[0]->getNativeCode()[0] == '\0' && mActiveList[0]->getLevel() == aLevel) - { - mActiveList[0]->mark(); - res = false; - } - else - { - // Clear all existing conditions and add one with this state. - removeAll(); + { + mActiveList[0]->mark(); + res = false; + } + else + { + // Clear all existing conditions and add one with this state. + removeAll(); cond = new ActiveCondition(aLevel); add(cond); - res = mChanged = true; - } - } - else - { + res = mChanged = true; + } + } + else + { if (mActiveCount == 1 && - (mActiveList[0]->getLevel() == eNORMAL || - mActiveList[0]->getLevel() == eUNAVAILABLE)) - { - removeAll(); - } - - // We have a code specific condition or a ab-normal + (mActiveList[0]->getLevel() == eNORMAL || + mActiveList[0]->getLevel() == eUNAVAILABLE)) + { + removeAll(); + } + + // We have a code specific condition or a ab-normal int i; for (i = 0; i < mActiveCount; i++) if (strcmp(aCode, mActiveList[i]->getNativeCode()) == 0) break; - + if (i < mActiveCount) - { + { res = mChanged = mActiveList[i]->setValue(aLevel, aText, aCode, aQualifier, aSeverity); mActiveList[i]->mark(); - } - else - { - // New condition + } + else + { + // New condition cond = new ActiveCondition(aLevel, aText, aCode, aQualifier, aSeverity); add(cond); - res = mChanged = true; - } - } - - return res; + res = mChanged = true; + } + } + + return res; } void Condition::remove(const char *aCode) { - // We have a code specific condition or a ab-normal + // We have a code specific condition or a ab-normal int i; for (i = 0; i < mActiveCount; i++) { if (strcmp(aCode, mActiveList[i]->getNativeCode()) == 0) { if (mActiveCount == 1) - normal(); + normal(); else { mActiveList[i]->setValue(eNORMAL, "", aCode); mActiveList[i]->clear(); } mChanged = true; break; - } - } + } + } } @@ -251,7 +282,7 @@ void Condition::add(ActiveCondition *aCond) mActiveList = newList; mActiveSize *= 2; } - + mActiveList[mActiveCount++] = aCond; } @@ -264,7 +295,7 @@ bool Condition::removeAt(int i) mActiveCount--; memmove(mActiveList + i, mActiveList + i + 1, sizeof(ActiveCondition*) * (mActiveCount - i)); - + return true; } @@ -278,11 +309,11 @@ char *Condition::ActiveCondition::toString(char *aBuffer, int aMaxLen) case eWARNING: text = "WARNING"; break; case eFAULT: text = "FAULT"; break; default: text = ""; break; - } + } snprintf(aBuffer, aMaxLen, "|%s|%s|%s|%s|", text, mNativeCode, mNativeSeverity, mQualifier); - mChanged = false; + mChanged = false; return aBuffer; } @@ -290,31 +321,31 @@ bool Condition::ActiveCondition::setValue(ELevels aLevel, const char *aText, con const char *aQualifier, const char *aSeverity) { if ((aLevel == eNORMAL || aLevel == eUNAVAILABLE) && aCode[0] == '\0') - mPlaceHolder = true; - + mPlaceHolder = true; + if (mLevel != aLevel || strncmp(aCode, mNativeCode, EVENT_VALUE_LEN) != 0 || strncmp(aQualifier, mQualifier, EVENT_VALUE_LEN) != 0 || strncmp(aSeverity, mNativeSeverity, EVENT_VALUE_LEN) != 0 || strncmp(aText, mText, EVENT_VALUE_LEN) != 0) - { + { mLevel = aLevel; - + strncpy(mNativeCode, aCode, EVENT_VALUE_LEN); - mNativeCode[EVENT_VALUE_LEN - 1] = '\0'; - + mNativeCode[EVENT_VALUE_LEN - 1] = '\0'; + strncpy(mQualifier, aQualifier, EVENT_VALUE_LEN); - mQualifier[EVENT_VALUE_LEN - 1] = '\0'; + mQualifier[EVENT_VALUE_LEN - 1] = '\0'; strncpy(mNativeSeverity, aSeverity, EVENT_VALUE_LEN); - mNativeSeverity[EVENT_VALUE_LEN - 1] = '\0'; + mNativeSeverity[EVENT_VALUE_LEN - 1] = '\0'; strncpy(mText, aText, EVENT_VALUE_LEN); - mText[EVENT_VALUE_LEN - 1] = '\0'; - - mChanged = true; - } - - return mChanged; + mText[EVENT_VALUE_LEN - 1] = '\0'; + + mChanged = true; + } + + return mChanged; } diff --git a/src/condition.hpp b/src/condition.hpp index 04faa4d..db59ab8 100644 --- a/src/condition.hpp +++ b/src/condition.hpp @@ -1,68 +1,68 @@ -/* - * Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the AMT nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED - * BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" - * AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR - * RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS - * (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR - * WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT - * LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, - * MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - - * LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT - * PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS - * OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, - * CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, - * WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF - * THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT - * SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. - */ #ifndef CONDITION_LIST #define CONDITION_LIST - -// The conditon items -#include "device_datum.hpp" - - -class Condition : public DeviceDatum -{ -public: +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +// The conditon items +#include "device_datum.hpp" + + +class Condition : public DeviceDatum +{ +public: enum ELevels { - eUNAVAILABLE, - eNORMAL, - eWARNING, - eFAULT - }; - -protected: - class ActiveCondition - { - protected: - ELevels mLevel; - char mText[EVENT_VALUE_LEN]; - char mNativeCode[EVENT_VALUE_LEN]; - char mNativeSeverity[EVENT_VALUE_LEN]; - char mQualifier[EVENT_VALUE_LEN]; - - bool mChanged; - bool mMarked; - bool mPlaceHolder; - - public: + eUNAVAILABLE, + eNORMAL, + eWARNING, + eFAULT + }; + +protected: + class ActiveCondition + { + protected: + ELevels mLevel; + char mText[EVENT_VALUE_LEN]; + char mNativeCode[EVENT_VALUE_LEN]; + char mNativeSeverity[EVENT_VALUE_LEN]; + char mQualifier[EVENT_VALUE_LEN]; + + bool mChanged; + bool mMarked; + bool mPlaceHolder; + + public: ActiveCondition() : mChanged(true), mMarked(true), mPlaceHolder(false) { mNativeCode[0] = mNativeSeverity[0] = mText[0] = mQualifier[0] = 0; @@ -70,58 +70,58 @@ class Condition : public DeviceDatum ActiveCondition(ELevels aLevel, const char *aText = "", const char *aCode = "", const char *aQualifier = "", const char *aSeverity = "") : mChanged(true), mMarked(true), mPlaceHolder(false) - { + { setValue(aLevel, aText, aCode, aQualifier, aSeverity); - } - + } + bool setValue(ELevels aLevel, const char *aText = "", const char *aCode = "", const char *aQualifier = "", const char *aSeverity = ""); char *toString(char *aBuffer, int aMaxLen); bool hasChanged() { return mChanged; } - + ELevels getLevel() { return mLevel; } const char *getText() { return mText; } const char *getNativeCode() { return mNativeCode; } const char *getNativeSeverity() { return mNativeSeverity; } const char *getQualifier() { return mQualifier; } - + void clear() { mMarked = false; } void mark() { mMarked = true; } bool isMarked() { return mMarked; } bool isPlaceHolder() { return mPlaceHolder; } - }; - -protected: + }; + +protected: ActiveCondition **mActiveList; int mActiveSize; int mActiveCount; - static const int mInitialActiveListSize = 16; - - bool mBegun; - bool mPrepared; - bool mSimple; - + static const int mInitialActiveListSize = 16; + + bool mBegun; + bool mPrepared; + bool mSimple; + void add(ActiveCondition *aCondition); bool removeAt(int i); - + void append(StringBuffer &aStringBuffer, char *aBuffer, ActiveCondition *aCond, bool &aFirst, int aMaxLen); - -public: + +public: Condition(const char *aName = "", bool aSimple = false); - virtual ~Condition(); + virtual ~Condition(); virtual char *toString(char *aBuffer, int aMaxLen); virtual bool requiresFlush(); virtual bool unavailable(); virtual bool append(StringBuffer &aBuffer); - + bool add(ELevels aLevel, const char *aText = "", const char *aCode = "", const char *aQualifier = "", const char *aSeverity = ""); void remove(const char *aCode); - - void removeAll(); + + void removeAll(); bool normal() { return add(eNORMAL); } bool isActive(const char *aNativeCode); void setSimple() { mSimple = true; } @@ -130,6 +130,6 @@ class Condition : public DeviceDatum virtual void prepare(); virtual void cleanup(); virtual void initialize(); -}; - +}; + #endif diff --git a/src/configuration.cpp b/src/configuration.cpp index 182791a..bfdaff9 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -1,81 +1,80 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - -#include "configuration.hpp" -#include "yaml.h" - -using namespace std; - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include "configuration.hpp" +#include "yaml.h" + +using namespace std; + Configuration::Configuration() : mPort(7878), mScanDelay(1000), mTimeout(10000) -{ -} - +{ +} + void Configuration::parse(istream &aStream, int aPort, int aDelay, int aTimeout, const char *aService) -{ +{ YAML::Parser parser(aStream); - YAML::Node doc; - parser.GetNextDocument(doc); + YAML::Node doc; + parser.GetNextDocument(doc); parse(doc, aPort, aDelay, aTimeout, aService); -} - +} + void Configuration::parse(YAML::Node &aDoc, int aPort, int aDelay, int aTimeout, const char *aService) -{ +{ if (aDoc.FindValue("adapter") != NULL) - { + { const YAML::Node &adapter = aDoc["adapter"]; SET_WITH_DEFAULT(adapter, "port", mPort, aPort); SET_WITH_DEFAULT(adapter, "scanDelay", mScanDelay, aDelay); SET_WITH_DEFAULT(adapter, "timeout", mTimeout, aTimeout); SET_WITH_DEFAULT(adapter, "service", mServiceName, aService); - } - else - { + } + else + { mPort = aPort; mScanDelay = aDelay; mTimeout = aTimeout; mServiceName = aService; - } -} - + } +} + Configuration::~Configuration() { } - + RegisterSet *Configuration::getRegisters(string &aName) -{ +{ return mRegisters[aName]; -} +} diff --git a/src/configuration.hpp b/src/configuration.hpp index 579c417..d32b2a1 100644 --- a/src/configuration.hpp +++ b/src/configuration.hpp @@ -1,50 +1,49 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ #ifndef CONFIGURATION_HPP #define CONFIGURATION_HPP - -#include -#include -#include -#include - -class DeviceDatum; +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include +#include +#include +#include + +class DeviceDatum; namespace YAML { - class Parser; - class Node; -} - + class Parser; + class Node; +} + #define SET_WITH_DEFAULT(node, key, value, def) \ if (node.FindValue(key) != NULL) \ node[key] >> value; \ @@ -54,91 +53,91 @@ namespace YAML { #define SET_IF_PRESENT(node, key, value) \ if (node.FindValue(key) != NULL) \ node[key] >> value; - -// A register represents a PLC/PMC register as an accessible unit. The -// value of the register will manifest as a typed value or a -// conditional that will map to an event and be represented by a -// state. -class Register -{ -public: - enum EType - { - FLOAT_64, - FLOAT_32, - INTEGER_32, - INTEGER_16, - INTEGER_8, - BOOL, - BIT, - CONDITION, - TEXT - }; - + +// A register represents a PLC/PMC register as an accessible unit. The +// value of the register will manifest as a typed value or a +// conditional that will map to an event and be represented by a +// state. +class Register +{ +public: + enum EType + { + FLOAT_64, + FLOAT_32, + INTEGER_32, + INTEGER_16, + INTEGER_8, + BOOL, + BIT, + CONDITION, + TEXT + }; + Register(EType aType, int aOffset, bool aTimeSeries = false) { mType = aType; mOffset = aOffset; mTimeseries = aTimeSeries; - } + } ~Register(); - + Register(Register &aRegister) { mType = aRegister.mType; mOffset = aRegister.mOffset; mTimeseries = aRegister.mTimeseries; - } - -protected: - EType mType; - int mOffset; - bool mTimeseries; - double mScaler; - int mScalerOffset; - int mCount; - - DeviceDatum *mDatum; -}; - -class RegisterSet -{ + } + +protected: + EType mType; + int mOffset; + bool mTimeseries; + double mScaler; + int mScalerOffset; + int mCount; + + DeviceDatum *mDatum; +}; + +class RegisterSet +{ void addRegister(Register &aRegister) { mRegisters.push_back(&aRegister); } - -protected: - int mAddress; - int mLength; - int mCount; - + +protected: + int mAddress; + int mLength; + int mCount; + std::vector mRegisters; -}; - -class Configuration -{ -public: - Configuration(); - virtual ~Configuration(); - +}; + +class Configuration +{ +public: + Configuration(); + virtual ~Configuration(); + virtual void parse(std::istream &aStream, int aPort = 7878, int aDelay = 1000, int aTimeout = 10000, const char *aService = "MTConnect Adapter"); - + int getPort() const { return mPort; } int getScanDelay() const { return mScanDelay; } int getTimeout() const { return mTimeout; } const std::string &getServiceName() const { return mServiceName; } - + void setPort(int aPort) { mPort = aPort; } - + RegisterSet *getRegisters(std::string &aName); - -protected: + +protected: virtual void parse(YAML::Node &aDoc, int aPort, int aDelay, int aTimeout, const char *aService); - -protected: - int mPort; - int mScanDelay; - int mTimeout; - std::string mServiceName; + +protected: + int mPort; + int mScanDelay; + int mTimeout; + std::string mServiceName; std::map mRegisters; -}; - +}; + #endif diff --git a/src/cutting_tool.cpp b/src/cutting_tool.cpp index 7f6ebdf..24e287b 100644 --- a/src/cutting_tool.cpp +++ b/src/cutting_tool.cpp @@ -1,4 +1,35 @@ - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// #include "internal.hpp" #include "cutting_tool.hpp" #include @@ -7,67 +38,67 @@ using namespace std; string encodeForXml( const string &aSrc ) { - ostringstream ret; + ostringstream ret; for( string::const_iterator iter = aSrc.begin(); iter != aSrc.end(); iter++ ) - { + { unsigned char c = (unsigned char)*iter; switch( c ) - { + { case '&': ret << "&"; break; case '<': ret << "<"; break; case '>': ret << ">"; break; case '"': ret << """; break; case '\'': ret << "'"; break; - default: + default: if ( c<32 || c>127 ) { - ret << "&#" << (unsigned int)c << ";"; + ret << "&#" << (unsigned int)c << ";"; } - else + else { - ret << c; - } - } + ret << c; + } + } } - return ret.str(); + return ret.str(); } std::string CuttingToolProperty::toXML() { - ostringstream xml; - xml << '<' << mName; - + ostringstream xml; + xml << '<' << mName; + map::iterator iter; for (iter = mAttributes.begin(); iter != mAttributes.end(); iter++) { xml << ' ' << iter->first << "=\"" << encodeForXml(iter->second) << '"'; } if (!mValue.empty()) { - xml << '>' << encodeForXml(mValue) << "' << encodeForXml(mValue) << "'; - xml << '>'; - - return xml.str(); + return xml.str(); } std::string CuttingToolStatus::toXML() { - ostringstream xml; - xml << '<' << mName << '>'; + ostringstream xml; + xml << '<' << mName << '>'; vector::iterator iter; for (iter = mStatus.begin(); iter != mStatus.end(); iter++) { xml << "" << *iter << ""; } - - xml << "'; - - return xml.str(); + + xml << "'; + + return xml.str(); } static char *doubleToString(double aDouble, char *aBuffer) @@ -81,15 +112,15 @@ CuttingToolMeasurement::CuttingToolMeasurement(std::string aName, std::string aC std::string aNativeUnits, std::string aUnits) : CuttingToolProperty(aName) { - char buffer[80]; + char buffer[80]; mAttributes["code"] = aCode; - + if (aNominal != CT_NO_VALUE) mAttributes["nominal"] = doubleToString(aNominal, buffer); if (aMin != CT_NO_VALUE) mAttributes["minimum"] = doubleToString(aMin, buffer); if (aMax != CT_NO_VALUE) mAttributes["maximum"] = doubleToString(aMax, buffer); if (!aNativeUnits.empty()) mAttributes["nativeUnits"] = aNativeUnits; if (!aNativeUnits.empty()) mAttributes["units"] = aUnits; - + if (aValue != CT_NO_VALUE) mValue = doubleToString(aValue, buffer); } @@ -101,32 +132,32 @@ CuttingTool::CuttingTool(std::string &aAssetId, int aToolNumber, std::string &aD string CuttingTool::toString() { - // Agent takes care of reordering the properties, so we can cheat... - std::ostringstream xml; - - // Open tag... + // Agent takes care of reordering the properties, so we can cheat... + std::ostringstream xml; + + // Open tag... xml << ""; - xml << "" << mDescription << ""; - xml << ""; + xml << "" << mDescription << ""; + xml << ""; - // Properties + // Properties vector::iterator prop; for (prop = mProperties.begin(); prop != mProperties.end(); prop++) { xml << prop->toXML(); } - xml << ""; + xml << ""; vector::iterator measure; for (measure = mMeasurements.begin(); measure != mMeasurements.end(); measure++) { xml << measure->toXML(); } - xml << ""; - - // Items... - xml << ""; - - return xml.str(); + xml << ""; + + // Items... + xml << ""; + + return xml.str(); } \ No newline at end of file diff --git a/src/cutting_tool.hpp b/src/cutting_tool.hpp index 08c13c4..82d1f4f 100644 --- a/src/cutting_tool.hpp +++ b/src/cutting_tool.hpp @@ -2,11 +2,43 @@ #ifndef CUTTING_TOOL_HPP #define CUTTING_TOOL_HPP -#include -#include -#include -#include - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include +#include +#include +#include + class CuttingToolProperty { public: CuttingToolProperty(const std::string &aName, std::map &aAttributes, const std::string &aValue) @@ -20,35 +52,35 @@ class CuttingToolProperty { CuttingToolProperty(const CuttingToolProperty &aProp) : mName(aProp.mName), mAttributes(aProp.mAttributes), mValue(aProp.mValue) {} - + virtual std::string toXML(); - -public: - std::string mName; - std::map mAttributes; - std::string mValue; -}; - + +public: + std::string mName; + std::map mAttributes; + std::string mValue; +}; + class CuttingToolStatus : public CuttingToolProperty { -public: +public: CuttingToolStatus(std::vector &aStatus) : CuttingToolProperty("CutterStatus"), mStatus(aStatus) { } - + CuttingToolStatus(const CuttingToolStatus &aStatus) : CuttingToolProperty(aStatus), mStatus(aStatus.mStatus) {} - + virtual std::string toXML(); - -public: - std::vector mStatus; -}; - -static const double CT_NO_VALUE = DBL_MAX; - + +public: + std::vector mStatus; +}; + +static const double CT_NO_VALUE = DBL_MAX; + class CuttingToolMeasurement : public CuttingToolProperty { -public: +public: CuttingToolMeasurement(std::string aName, std::string aCode, double aValue, double aNominal = CT_NO_VALUE, double aMin = CT_NO_VALUE, double aMax = CT_NO_VALUE, std::string aNativeUnits = "", @@ -57,36 +89,36 @@ class CuttingToolMeasurement : public CuttingToolProperty { CuttingToolMeasurement(const CuttingToolMeasurement &aMeasure) : CuttingToolProperty(aMeasure) {} -}; - +}; + class CuttingItem { -public: - std::vector mProperties; - std::vector mMeasurements; -}; - +public: + std::vector mProperties; + std::vector mMeasurements; +}; + class CuttingTool { -public: +public: CuttingTool(std::string &aAssetId, int aToolNumber, std::string &aDescription, CuttingToolStatus &aStatus); - + void add(CuttingToolProperty &aProp) { mProperties.push_back(aProp); } void add(CuttingToolMeasurement &aProp) { mMeasurements.push_back(aProp); } - - virtual std::string toString(); - + + virtual std::string toString(); + const std::string &getAssetId() const { return mAssetId; } - int getToolNumber() const { return mToolNumber; } - + int getToolNumber() const { return mToolNumber; } + bool isValid() const { return !mAssetId.empty(); } - -protected: - CuttingToolStatus mStatus; - std::vector mProperties; - std::vector mMeasurements; - std::string mAssetId; - int mToolNumber; - std::string mDescription; -}; + +protected: + CuttingToolStatus mStatus; + std::vector mProperties; + std::vector mMeasurements; + std::string mAssetId; + int mToolNumber; + std::string mDescription; +}; #endif \ No newline at end of file diff --git a/src/device_datum.cpp b/src/device_datum.cpp index 6e6c6be..8f06463 100755 --- a/src/device_datum.cpp +++ b/src/device_datum.cpp @@ -1,296 +1,295 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - -#include "internal.hpp" -#include "device_datum.hpp" -#include "string_buffer.hpp" - -static const char *sUnavailable = "UNAVAILABLE"; - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include "internal.hpp" +#include "device_datum.hpp" +#include "string_buffer.hpp" + +static const char *sUnavailable = "UNAVAILABLE"; + /* * Data value methods. */ DeviceDatum::DeviceDatum(const char *aName) -{ +{ strncpy(mName, aName, NAME_LEN); - mName[NAME_LEN - 1] = '\0'; - strcpy(mOrigName, mName); - mChanged = false; - mHasValue = false; -} - - -DeviceDatum::~DeviceDatum() -{ -} - + mName[NAME_LEN - 1] = '\0'; + strcpy(mOrigName, mName); + mChanged = false; + mHasValue = false; +} + + +DeviceDatum::~DeviceDatum() +{ +} + bool DeviceDatum::prefixName(const char *aName) -{ - // Check for overflow. +{ + // Check for overflow. int len = strlen(aName); - if (strlen(mOrigName) + len >= (size_t) NAME_LEN) - return false; - + if (strlen(mOrigName) + len >= (size_t) NAME_LEN) + return false; + strcpy(mName, aName); - mName[len++] = ':'; - strcpy(mName + len, mOrigName); - - // Make sure the whole thing is terminated - mName[NAME_LEN - 1] = '\0'; - - return true; -} - + mName[len++] = ':'; + strcpy(mName + len, mOrigName); + + // Make sure the whole thing is terminated + mName[NAME_LEN - 1] = '\0'; + + return true; +} + void DeviceDatum::setName(const char *aName) -{ +{ strncpy(mName, aName, NAME_LEN); - mName[NAME_LEN - 1] = '\0'; - strcpy(mOrigName, mName); -} - + mName[NAME_LEN - 1] = '\0'; + strcpy(mOrigName, mName); +} + void DeviceDatum::setNativeUnits(const char *aUnits) -{ +{ strncpy(mNativeUnits, aUnits, UNITS_LEN); - mNativeUnits[UNITS_LEN - 1] = '\0'; -} - + mNativeUnits[UNITS_LEN - 1] = '\0'; +} + bool DeviceDatum::append(StringBuffer &aBuffer) -{ - char buffer[1024]; +{ + char buffer[1024]; aBuffer.append(toString(buffer, 1024)); - mChanged = false; - return mChanged; -} - + mChanged = false; + return mChanged; +} + bool DeviceDatum::hasInitialValue() -{ - return mHasValue; -} - +{ + return mHasValue; +} + bool DeviceDatum::requiresFlush() -{ - return false; -} - -// Append text to the buffer and remove all and characters. +{ + return false; +} + +// Append text to the buffer and remove all and characters. void DeviceDatum::appendText(char *aBuffer, char *aValue, int aMaxLen) -{ +{ size_t len = strlen(aBuffer); char *cp = aValue, *dp = aBuffer + len; for (size_t i = len; i < (size_t) aMaxLen && *cp != '\0'; i++) - { - if (*cp == '\n' || *cp == '\r') - *dp = ' '; - else - *dp = *cp; + { + if (*cp == '\n' || *cp == '\r') + *dp = ' '; + else + *dp = *cp; dp++; cp++; - } - *dp = '\0'; -} - + } + *dp = '\0'; +} + /* * Event methods */ Event::Event(const char* aName) : DeviceDatum(aName) -{ +{ mValue[0] = 0; -} - +} + bool Event::setValue(const char *aValue) -{ +{ if (strncmp(aValue, mValue, EVENT_VALUE_LEN) != 0 || !mHasValue) - { - mChanged = true; + { + mChanged = true; strncpy(mValue, aValue, EVENT_VALUE_LEN); - mValue[EVENT_VALUE_LEN - 1] = '\0'; - mHasValue = true; - } - return mChanged; -} - + mValue[EVENT_VALUE_LEN - 1] = '\0'; + mHasValue = true; + } + return mChanged; +} + char *Event::toString(char *aBuffer, int aMaxLen) -{ +{ snprintf(aBuffer, aMaxLen, "|%s|", mName); appendText(aBuffer, mValue, aMaxLen); return aBuffer; -} - -bool Event::unavailable() -{ - return setValue(sUnavailable); -} - +} + +bool Event::unavailable() +{ + return setValue(sUnavailable); +} + /* * IntEvent methods */ IntEvent::IntEvent(const char *aName) : DeviceDatum(aName) -{ +{ mValue = 0; mUnavailable = false; -} - +} + bool IntEvent::setValue(int aValue) -{ +{ if (aValue != mValue || !mHasValue || mUnavailable) - { - mChanged = true; + { + mChanged = true; mValue = aValue; - mHasValue = true; - mUnavailable = false; - } - - return mChanged; -} - + mHasValue = true; + mUnavailable = false; + } + + return mChanged; +} + char *IntEvent::toString(char *aBuffer, int aMaxLen) -{ - if (mUnavailable) +{ + if (mUnavailable) snprintf(aBuffer, aMaxLen, "|%s|UNAVAILABLE", mName); - else + else snprintf(aBuffer, aMaxLen, "|%s|%d", mName, mValue); - + return aBuffer; -} - -bool IntEvent::unavailable() -{ - if (!mUnavailable) - { - mChanged = true; - mUnavailable = true; - } - - return mChanged; -} - +} + +bool IntEvent::unavailable() +{ + if (!mUnavailable) + { + mChanged = true; + mUnavailable = true; + } + + return mChanged; +} + /* * Sample methods */ Sample::Sample(const char *aName, double aEpsilon) : DeviceDatum(aName), mEpsilon(aEpsilon) -{ +{ mValue = 0.0; mUnavailable = false; -} - +} + bool Sample::setValue(double aValue) -{ +{ if (fabs(aValue - mValue) > mEpsilon || !mHasValue || mUnavailable) - { - mChanged = true; + { + mChanged = true; mValue = aValue; - mHasValue = true; - mUnavailable = false; - } - return mChanged; -} - + mHasValue = true; + mUnavailable = false; + } + return mChanged; +} + char *Sample::toString(char *aBuffer, int aMaxLen) -{ - if (mUnavailable) +{ + if (mUnavailable) snprintf(aBuffer, aMaxLen, "|%s|UNAVAILABLE", mName); - else + else snprintf(aBuffer, aMaxLen, "|%s|%.10g", mName, mValue); return aBuffer; -} - -bool Sample::unavailable() -{ - if (!mUnavailable) - { - mChanged = true; - mUnavailable = true; - mHasValue = true; - } - - return mChanged; -} - - +} + +bool Sample::unavailable() +{ + if (!mUnavailable) + { + mChanged = true; + mUnavailable = true; + mHasValue = true; + } + + return mChanged; +} + + /* Power */ bool PowerState::setValue(enum EPowerState aState) -{ +{ if (mState != aState || !mHasValue) - { + { mState = aState; - mChanged = true; - mHasValue = true; - } - return mChanged; -} - + mChanged = true; + mHasValue = true; + } + return mChanged; +} + char *PowerState::toString(char *aBuffer, int aMaxLen) -{ +{ const char *text; switch(mState) - { + { case eUNAVAILABLE: text = sUnavailable; break; case eON: text = "ON"; break; case eOFF: text = "OFF"; break; default: text = ""; break; - } + } snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); return aBuffer; -} - -bool PowerState::unavailable() -{ - return setValue(eUNAVAILABLE); -} - +} + +bool PowerState::unavailable() +{ + return setValue(eUNAVAILABLE); +} + /* Execution */ - + bool Execution::setValue(enum EExecutionState aState) -{ +{ if (mState != aState || !mHasValue) - { + { mState = aState; - mChanged = true; - mHasValue = true; - } - - return mChanged; -} - + mChanged = true; + mHasValue = true; + } + + return mChanged; +} + char *Execution::toString(char *aBuffer, int aMaxLen) -{ +{ const char *text; switch(mState) - { + { case eUNAVAILABLE: text = sUnavailable; break; case eACTIVE: text = "ACTIVE"; break; case eREADY: text = "READY"; break; @@ -298,379 +297,379 @@ char *Execution::toString(char *aBuffer, int aMaxLen) case eSTOPPED: text = "STOPPED"; break; case eFEED_HOLD: text = "FEED_HOLD"; break; default: text = ""; break; - } + } snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); return aBuffer; -} - -bool Execution::unavailable() -{ - return setValue(eUNAVAILABLE); -} - +} + +bool Execution::unavailable() +{ + return setValue(eUNAVAILABLE); +} + /* ControllerMode */ - + char *ControllerMode::toString(char *aBuffer, int aMaxLen) -{ +{ const char *text; switch(mMode) - { + { case eUNAVAILABLE: text = sUnavailable; break; case eSEMI_AUTOMATIC: text = "SEMI_AUTOMATIC"; break; case eAUTOMATIC: text = "AUTOMATIC"; break; case eMANUAL: text = "MANUAL"; break; case eMANUAL_DATA_INPUT: text = "MANUAL_DATA_INPUT"; break; default: text = ""; break; - } + } snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); return aBuffer; -} - +} + bool ControllerMode::setValue(enum EMode aMode) -{ +{ if (mMode != aMode || !mHasValue) - { + { mMode = aMode; - mChanged = true; - mHasValue = true; - } - - return mChanged; -} - -bool ControllerMode::unavailable() -{ - return setValue(eUNAVAILABLE); -} - + mChanged = true; + mHasValue = true; + } + + return mChanged; +} + +bool ControllerMode::unavailable() +{ + return setValue(eUNAVAILABLE); +} + /* Direction */ - + char *Direction::toString(char *aBuffer, int aMaxLen) -{ +{ const char *text; switch(mDirection) - { + { case eUNAVAILABLE: text = sUnavailable; break; case eCLOCKWISE: text = "CLOCKWISE"; break; case eCOUNTER_CLOCKWISE: text = "COUNTER_CLOCKWISE"; break; default: text = ""; break; - } + } snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); return aBuffer; -} - +} + bool Direction::setValue(enum ERotationDirection aDirection) -{ +{ if (mDirection != aDirection || !mHasValue) - { + { mDirection = aDirection; - mChanged = true; - mHasValue = true; - } - - return mChanged; -} - -bool Direction::unavailable() -{ - return setValue(eUNAVAILABLE); -} - + mChanged = true; + mHasValue = true; + } + + return mChanged; +} + +bool Direction::unavailable() +{ + return setValue(eUNAVAILABLE); +} + /* Emergency Stop */ - + char *EmergencyStop::toString(char *aBuffer, int aMaxLen) -{ +{ const char *text; switch(mValue) - { + { case eUNAVAILABLE: text = sUnavailable; break; case eTRIGGERED: text = "TRIGGERED"; break; case eARMED: text = "ARMED"; break; default: text = ""; break; - } + } snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); return aBuffer; -} - +} + bool EmergencyStop::setValue(enum EValues aValue) -{ +{ if (mValue != aValue || !mHasValue) - { + { mValue = aValue; - mChanged = true; - mHasValue = true; - } - - return mChanged; -} - -bool EmergencyStop::unavailable() -{ - return setValue(eUNAVAILABLE); -} - + mChanged = true; + mHasValue = true; + } + + return mChanged; +} + +bool EmergencyStop::unavailable() +{ + return setValue(eUNAVAILABLE); +} + /* Axis Coupling */ - + char *AxisCoupling::toString(char *aBuffer, int aMaxLen) -{ +{ const char *text; switch(mValue) - { + { case eUNAVAILABLE: text = sUnavailable; break; case eTANDEM: text = "TANDEM"; break; case eSYNCHRONOUS: text = "SYNCHRONOUS"; break; case eMASTER: text = "MASTER"; break; case eSLAVE: text = "SLAVE"; break; default: text = ""; break; - } + } snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); return aBuffer; -} - +} + bool AxisCoupling::setValue(enum EValues aValue) -{ +{ if (mValue != aValue || !mHasValue) - { + { mValue = aValue; - mChanged = true; - mHasValue = true; - } - return mChanged; -} - -bool AxisCoupling::unavailable() -{ - return setValue(eUNAVAILABLE); -} - + mChanged = true; + mHasValue = true; + } + return mChanged; +} + +bool AxisCoupling::unavailable() +{ + return setValue(eUNAVAILABLE); +} + /* Door State */ - + char *DoorState::toString(char *aBuffer, int aMaxLen) -{ +{ const char *text; switch(mValue) - { + { case eUNAVAILABLE: text = sUnavailable; break; case eOPEN: text = "CLOSED"; break; case eCLOSED: text = "OPEN"; break; default: text = ""; break; - } + } snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); return aBuffer; -} - +} + bool DoorState::setValue(enum EValues aValue) -{ +{ if (mValue != aValue || !mHasValue) - { + { mValue = aValue; - mChanged = true; - mHasValue = true; - } - return mChanged; -} - -bool DoorState::unavailable() -{ - return setValue(eUNAVAILABLE); -} - + mChanged = true; + mHasValue = true; + } + return mChanged; +} + +bool DoorState::unavailable() +{ + return setValue(eUNAVAILABLE); +} + // Path Mode - + char *PathMode::toString(char *aBuffer, int aMaxLen) -{ +{ const char *text; switch(mValue) - { + { case eUNAVAILABLE: text = sUnavailable; break; case eINDEPENDENT: text = "INDEPENDENT"; break; case eSYNCHRONOUS: text = "SYNCHRONOUS"; break; case eMIRROR: text = "MIRROR"; break; default: text = ""; break; - } + } snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); return aBuffer; -} - +} + bool PathMode::setValue(enum EValues aValue) -{ +{ if (mValue != aValue || !mHasValue) - { + { mValue = aValue; - mChanged = true; - mHasValue = true; - } - return mChanged; -} - -bool PathMode::unavailable() -{ - return setValue(eUNAVAILABLE); -} - + mChanged = true; + mHasValue = true; + } + return mChanged; +} + +bool PathMode::unavailable() +{ + return setValue(eUNAVAILABLE); +} + // Rotary Mode - + char *RotaryMode::toString(char *aBuffer, int aMaxLen) -{ +{ const char *text; switch(mValue) - { + { case eUNAVAILABLE: text = sUnavailable; break; case eSPINDLE: text = "SPINDLE"; break; case eINDEX: text = "INDEX"; break; case eCONTOUR: text = "CONTOUR"; break; default: text = ""; break; - } + } snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); return aBuffer; -} - +} + bool RotaryMode::setValue(enum EValues aValue) -{ +{ if (mValue != aValue || !mHasValue) - { + { mValue = aValue; - mChanged = true; - mHasValue = true; - } - return mChanged; -} - -bool RotaryMode::unavailable() -{ - return setValue(eUNAVAILABLE); -} - - + mChanged = true; + mHasValue = true; + } + return mChanged; +} + +bool RotaryMode::unavailable() +{ + return setValue(eUNAVAILABLE); +} + + // Message - + Message::Message(const char *aName) : DeviceDatum(aName) -{ +{ mNativeCode[0] = 0; -} - +} + char *Message::toString(char *aBuffer, int aMaxLen) -{ +{ snprintf(aBuffer, aMaxLen, "|%s|%s|", mName, mNativeCode); appendText(aBuffer, mText, aMaxLen); return aBuffer; -} - +} + bool Message::setValue(const char *aText, const char *aCode) -{ - if (!mHasValue || +{ + if (!mHasValue || strncmp(aCode, mNativeCode, EVENT_VALUE_LEN) != 0 || strncmp(aText, mText, EVENT_VALUE_LEN) != 0) - - { + + { strncpy(mNativeCode, aCode, EVENT_VALUE_LEN); - mNativeCode[EVENT_VALUE_LEN - 1] = '\0'; - + mNativeCode[EVENT_VALUE_LEN - 1] = '\0'; + strncpy(mText, aText, EVENT_VALUE_LEN); - mText[EVENT_VALUE_LEN - 1] = '\0'; - - mChanged = true; - mHasValue = true; - } - - return mChanged; -} - + mText[EVENT_VALUE_LEN - 1] = '\0'; + + mChanged = true; + mHasValue = true; + } + + return mChanged; +} + bool Message::requiresFlush() { return true; } - -bool Message::unavailable() -{ - return setValue(sUnavailable); -} - + +bool Message::unavailable() +{ + return setValue(sUnavailable); +} + /* * PathPosition methods */ PathPosition::PathPosition(const char *aName, double aEpsilon) : DeviceDatum(aName), mEpsilon(aEpsilon) -{ +{ mX = mY = mZ = 0.0; mUnavailable = false; -} - +} + bool PathPosition::setValue(double aX, double aY, double aZ) -{ - if (!mHasValue || +{ + if (!mHasValue || fabs(aX - mX) > mEpsilon || fabs(aY - mY) > mEpsilon || fabs(aZ - mZ) > mEpsilon || - mUnavailable) - { - mChanged = true; + mUnavailable) + { + mChanged = true; mX = aX; mY = aY; mZ = aZ; - mHasValue = true; - mUnavailable = false; - } - return mChanged; -} - + mHasValue = true; + mUnavailable = false; + } + return mChanged; +} + char *PathPosition::toString(char *aBuffer, int aMaxLen) -{ - if (mUnavailable) +{ + if (mUnavailable) snprintf(aBuffer, aMaxLen, "|%s|UNAVAILABLE", mName); - else + else snprintf(aBuffer, aMaxLen, "|%s|%.10f %0.10f %0.10f", mName, mX, mY, mZ); return aBuffer; -} - -bool PathPosition::unavailable() -{ - if (!mUnavailable) - { - mChanged = true; - mUnavailable = true; - } - - return mChanged; -} - +} + +bool PathPosition::unavailable() +{ + if (!mUnavailable) + { + mChanged = true; + mUnavailable = true; + } + + return mChanged; +} + /* * Availability methods */ - + Availability::Availability(const char *aName) : DeviceDatum(aName) -{ - mHasValue = true; +{ + mHasValue = true; mUnavailable = false; -} - +} + char *Availability::toString(char *aBuffer, int aMaxLen) -{ - if (mUnavailable) +{ + if (mUnavailable) snprintf(aBuffer, aMaxLen, "|%s|UNAVAILABLE", mName); - else + else snprintf(aBuffer, aMaxLen, "|%s|AVAILABLE", mName); return aBuffer; -} - -bool Availability::unavailable() -{ - if (!mUnavailable) - { - mChanged = true; - mUnavailable = true; - } - - return mChanged; -} - -bool Availability::available() -{ - if (mUnavailable) - { - mChanged = true; - mUnavailable = false; - } - - return mChanged; -} +} + +bool Availability::unavailable() +{ + if (!mUnavailable) + { + mChanged = true; + mUnavailable = true; + } + + return mChanged; +} + +bool Availability::available() +{ + if (mUnavailable) + { + mChanged = true; + mUnavailable = false; + } + + return mChanged; +} diff --git a/src/device_datum.hpp b/src/device_datum.hpp index 161d731..7442e25 100644 --- a/src/device_datum.hpp +++ b/src/device_datum.hpp @@ -1,85 +1,85 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ #ifndef DEVICE_DATUM_HPP #define DEVICE_DATUM_HPP /* Forward class definitions */ -class StringBuffer; - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +class StringBuffer; + /* Some constants for field lengths */ -const int NAME_LEN = 32; -const int CODE_LEN = 32; -const int UNITS_LEN = 32; -const int NATIVE_CODE_LEN = 32; -const int SEVERITY_LEN = 32; -const int STATE_LEN = 32; -const int DESCRIPTION_LEN = 512; -const int EVENT_VALUE_LEN = 512; - +const int NAME_LEN = 32; +const int CODE_LEN = 32; +const int UNITS_LEN = 32; +const int NATIVE_CODE_LEN = 32; +const int SEVERITY_LEN = 32; +const int STATE_LEN = 32; +const int DESCRIPTION_LEN = 512; +const int EVENT_VALUE_LEN = 512; + /* * An abstract data value that knows its name and tracks when it has changed. * * The data value will be set in the subclasses. */ class DeviceDatum { -protected: +protected: /* The name of the Data Value */ - char mName[NAME_LEN]; - char mOrigName[NAME_LEN]; - char mNativeUnits[UNITS_LEN]; - + char mName[NAME_LEN]; + char mOrigName[NAME_LEN]; + char mNativeUnits[UNITS_LEN]; + /* A changed flag to indicated that the value has changed since last append. */ - bool mChanged; - + bool mChanged; + /* Has this data value been initialized? */ - bool mHasValue; - -protected: + bool mHasValue; + +protected: void appendText(char *aBuffer, char *aValue, int aMaxLen); - -public: - // The name will be supplied later... + +public: + // The name will be supplied later... DeviceDatum(const char *aName = ""); - - virtual ~DeviceDatum(); - + + virtual ~DeviceDatum(); + virtual bool changed() { return mChanged; } void reset() { mChanged = false; } - + const char *getNativeUnits() { return mNativeUnits; } void setNativeUnits(const char *aNativeUnits); - + bool prefixName(const char *aPrefix); bool hasValue() const { return mHasValue; } char *getName() { return mName; } @@ -88,303 +88,303 @@ class DeviceDatum { virtual bool append(StringBuffer &aBuffer); virtual bool hasInitialValue(); virtual bool requiresFlush(); - - virtual bool unavailable() = 0; - virtual void begin() { } - virtual void prepare() { } - virtual void cleanup() { } - virtual void initialize() { } -}; - + + virtual bool unavailable() = 0; + virtual void begin() { } + virtual void prepare() { } + virtual void cleanup() { } + virtual void initialize() { } +}; + /* * An event is a data value with a string value. */ -class Event : public DeviceDatum -{ -protected: - char mValue[EVENT_VALUE_LEN]; - -public: +class Event : public DeviceDatum +{ +protected: + char mValue[EVENT_VALUE_LEN]; + +public: Event(const char *aName = ""); bool setValue(const char *aValue); const char *getValue() { return mValue; } virtual char *toString(char *aBuffer, int aMaxLen); - + virtual bool unavailable(); -}; - +}; + /* * An int event is an event with an integer value. This can be used * for line number events. */ -class IntEvent : public DeviceDatum -{ -protected: - int mValue; - bool mUnavailable; - -public: +class IntEvent : public DeviceDatum +{ +protected: + int mValue; + bool mUnavailable; + +public: IntEvent(const char *aName = ""); bool setValue(int aValue); int getValue() { return mValue; } virtual char *toString(char *aBuffer, int aMaxLen); - + virtual bool unavailable(); -}; - +}; + /* * A sample event is used for floating point samples. */ - -class Sample : public DeviceDatum -{ -protected: - double mValue; - bool mUnavailable; - double mEpsilon; - -public: + +class Sample : public DeviceDatum +{ +protected: + double mValue; + bool mUnavailable; + double mEpsilon; + +public: Sample(const char *aName = "", double aEpsilon = 0.000001); bool setValue(double aValue); double getValue() { return mValue; } virtual char *toString(char *aBuffer, int aMaxLen); - + virtual bool unavailable(); -}; - +}; + /* Power status data value */ - -class PowerState : public DeviceDatum -{ -public: + +class PowerState : public DeviceDatum +{ +public: enum EPowerState { - eUNAVAILABLE, - eON, - eOFF, - }; - -protected: - EPowerState mState; - -public: + eUNAVAILABLE, + eON, + eOFF, + }; + +protected: + EPowerState mState; + +public: PowerState(const char *aName = "") : DeviceDatum(aName) { } bool setValue(enum EPowerState aState); EPowerState getValue() { return mState; } virtual char *toString(char *aBuffer, int aMaxLen); - + virtual bool unavailable(); -}; - +}; + /* Executaion state */ - -class Execution : public DeviceDatum -{ -public: + +class Execution : public DeviceDatum +{ +public: enum EExecutionState { - eUNAVAILABLE, - eREADY, - eINTERRUPTED, - eSTOPPED, - eACTIVE, - eFEED_HOLD - }; - -protected: - EExecutionState mState; - -public: + eUNAVAILABLE, + eREADY, + eINTERRUPTED, + eSTOPPED, + eACTIVE, + eFEED_HOLD + }; + +protected: + EExecutionState mState; + +public: Execution(const char *aName = "") : DeviceDatum(aName) { } bool setValue(enum EExecutionState aState); EExecutionState getValue() { return mState; } virtual char *toString(char *aBuffer, int aMaxLen); - + virtual bool unavailable(); -}; - +}; + /* ControllerMode */ - -class ControllerMode : public DeviceDatum -{ -public: + +class ControllerMode : public DeviceDatum +{ +public: enum EMode { - eUNAVAILABLE, - eAUTOMATIC, - eMANUAL, - eMANUAL_DATA_INPUT, - eSEMI_AUTOMATIC - }; - -protected: - EMode mMode; - -public: + eUNAVAILABLE, + eAUTOMATIC, + eMANUAL, + eMANUAL_DATA_INPUT, + eSEMI_AUTOMATIC + }; + +protected: + EMode mMode; + +public: ControllerMode(const char *aName = "") : DeviceDatum(aName) { } bool setValue(enum EMode aState); EMode getValue() { return mMode; } virtual char *toString(char *aBuffer, int aMaxLen); - + virtual bool unavailable(); }; - - + + /* Direction */ - -class Direction : public DeviceDatum -{ -public: + +class Direction : public DeviceDatum +{ +public: enum ERotationDirection { - eUNAVAILABLE, - eCLOCKWISE, - eCOUNTER_CLOCKWISE - }; - -protected: - ERotationDirection mDirection; - -public: + eUNAVAILABLE, + eCLOCKWISE, + eCOUNTER_CLOCKWISE + }; + +protected: + ERotationDirection mDirection; + +public: Direction(const char *aName = "") : DeviceDatum(aName) { } bool setValue(enum ERotationDirection aDirection); ERotationDirection getValue() { return mDirection; } virtual char *toString(char *aBuffer, int aMaxLen); - + virtual bool unavailable(); }; - + // Version 1.1 - + /* Emergency Stop */ - -class EmergencyStop : public DeviceDatum -{ -public: + +class EmergencyStop : public DeviceDatum +{ +public: enum EValues { - eUNAVAILABLE, - eTRIGGERED, - eARMED - }; - -protected: - EValues mValue; - -public: + eUNAVAILABLE, + eTRIGGERED, + eARMED + }; + +protected: + EValues mValue; + +public: EmergencyStop(const char *aName = "") : DeviceDatum(aName) { } bool setValue(enum EValues aValue); EValues getValue() { return mValue; } virtual char *toString(char *aBuffer, int aMaxLen); - + virtual bool unavailable(); -}; - - -class AxisCoupling : public DeviceDatum -{ -public: +}; + + +class AxisCoupling : public DeviceDatum +{ +public: enum EValues { - eUNAVAILABLE, - eTANDEM, - eSYNCHRONOUS, - eMASTER, - eSLAVE - }; - -protected: - EValues mValue; - -public: + eUNAVAILABLE, + eTANDEM, + eSYNCHRONOUS, + eMASTER, + eSLAVE + }; + +protected: + EValues mValue; + +public: AxisCoupling(const char *aName = "") : DeviceDatum(aName) { } bool setValue(enum EValues aValue); EValues getValue() { return mValue; } virtual char *toString(char *aBuffer, int aMaxLen); - + virtual bool unavailable(); -}; - -class DoorState : public DeviceDatum -{ -public: +}; + +class DoorState : public DeviceDatum +{ +public: enum EValues { - eUNAVAILABLE, - eOPEN, - eCLOSED - }; - -protected: - EValues mValue; - -public: + eUNAVAILABLE, + eOPEN, + eCLOSED + }; + +protected: + EValues mValue; + +public: DoorState(const char *aName = "") : DeviceDatum(aName) { } bool setValue(enum EValues aValue); EValues getValue() { return mValue; } virtual char *toString(char *aBuffer, int aMaxLen); - + virtual bool unavailable(); -}; - -class PathMode : public DeviceDatum -{ -public: +}; + +class PathMode : public DeviceDatum +{ +public: enum EValues { - eUNAVAILABLE, - eINDEPENDENT, - eSYNCHRONOUS, - eMIRROR - }; - -protected: - EValues mValue; - -public: + eUNAVAILABLE, + eINDEPENDENT, + eSYNCHRONOUS, + eMIRROR + }; + +protected: + EValues mValue; + +public: PathMode(const char *aName = "") : DeviceDatum(aName) { } bool setValue(enum EValues aValue); EValues getValue() { return mValue; } virtual char *toString(char *aBuffer, int aMaxLen); - + virtual bool unavailable(); -}; - -class RotaryMode : public DeviceDatum -{ -public: +}; + +class RotaryMode : public DeviceDatum +{ +public: enum EValues { - eUNAVAILABLE, - eSPINDLE, - eINDEX, - eCONTOUR - }; - -protected: - EValues mValue; - -public: + eUNAVAILABLE, + eSPINDLE, + eINDEX, + eCONTOUR + }; + +protected: + EValues mValue; + +public: RotaryMode(const char *aName = "") : DeviceDatum(aName) { } bool setValue(enum EValues aValue); EValues getValue() { return mValue; } virtual char *toString(char *aBuffer, int aMaxLen); - + virtual bool unavailable(); -}; - +}; + class Message : public DeviceDatum { - char mText[EVENT_VALUE_LEN]; - char mNativeCode[EVENT_VALUE_LEN]; - -public: + char mText[EVENT_VALUE_LEN]; + char mNativeCode[EVENT_VALUE_LEN]; + +public: Message(const char *aName = ""); bool setValue(const char *aText, const char *aCode = ""); virtual char *toString(char *aBuffer, int aMaxLen); const char *getNativeCode() { return mNativeCode; } - + virtual bool requiresFlush(); virtual bool unavailable(); -}; - +}; + class PathPosition : public DeviceDatum { -protected: - double mX, mY, mZ; - bool mUnavailable; - double mEpsilon; - -public: +protected: + double mX, mY, mZ; + bool mUnavailable; + double mEpsilon; + +public: PathPosition(const char *aName = "", double aEpsilon = 0.000001); bool setValue(double aX, double aY, double aZ); double getX() { return mX; } @@ -393,18 +393,18 @@ class PathPosition : public DeviceDatum { virtual char *toString(char *aBuffer, int aMaxLen); virtual bool unavailable(); -}; - -class Availability : public DeviceDatum -{ -protected: - bool mUnavailable; - -public: +}; + +class Availability : public DeviceDatum +{ +protected: + bool mUnavailable; + +public: Availability(const char *aName = ""); virtual char *toString(char *aBuffer, int aMaxLen); - bool available(); + bool available(); virtual bool unavailable(); -}; - +}; + #endif diff --git a/src/internal.hpp b/src/internal.hpp index e059230..c7fbbb7 100755 --- a/src/internal.hpp +++ b/src/internal.hpp @@ -1,68 +1,68 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ #ifndef MTC_INTERNAL_HPP #define MTC_INTERNAL_HPP - -#ifdef WIN32 +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#ifdef WIN32 #define _CRT_SECURE_NO_DEPRECATE 1 - + /* Windows specific include files and types */ #include "winsock2.h" #ifndef AFX #include "windows.h" #endif #include "errno.h" - + #define SHUT_RDWR SD_BOTH typedef int socklen_t; #define snprintf _snprintf #define strdup _strdup #define stricmp _stricmp #define strdup _strdup - + /* Internal types */ typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned __int64 uint64_t; - + #define UINT16_MAX 0xFFFF - + #define sleep(t) Sleep(t * 1000) #define usleep(t) Sleep(t / 1000) - -#else /* WIN32 */ - + +#else /* WIN32 */ + /* Unix specifc include files */ #include #include @@ -77,19 +77,19 @@ typedef unsigned __int64 uint64_t; #include #include #include - + typedef struct sockaddr_in SOCKADDR_IN; typedef struct sockaddr SOCKADDR; #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 #define SOCKET int #define closesocket close - -#endif /* WIN32 */ - -#include -#include -#include -#include + +#endif /* WIN32 */ + +#include +#include +#include +#include #endif diff --git a/src/logger.cpp b/src/logger.cpp index 597978a..b88a2bb 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -1,83 +1,114 @@ - -#include "internal.hpp" -#include "logger.hpp" - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include "internal.hpp" +#include "logger.hpp" + Logger *gLogger = NULL; - + void Logger::error(const char *aFormat, ...) -{ - char buffer[LOGGER_BUFFER_SIZE]; - char ts[32]; - va_list args; +{ + char buffer[LOGGER_BUFFER_SIZE]; + char ts[32]; + va_list args; va_start (args, aFormat); fprintf(mFile, "%s - Error: %s\n", timestamp(ts), format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); - fflush(mFile); + fflush(mFile); va_end (args); -} - +} + void Logger::warning(const char *aFormat, ...) -{ +{ if (mLogLevel > eWARNING) return; - - char buffer[LOGGER_BUFFER_SIZE]; - char ts[32]; - va_list args; + + char buffer[LOGGER_BUFFER_SIZE]; + char ts[32]; + va_list args; va_start (args, aFormat); fprintf(mFile, "%s - Warning: %s\n", timestamp(ts), format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); - fflush(mFile); + fflush(mFile); va_end (args); -} - +} + void Logger::info(const char *aFormat, ...) -{ +{ if (mLogLevel > eINFO) return; - - char buffer[LOGGER_BUFFER_SIZE]; - char ts[32]; - va_list args; + + char buffer[LOGGER_BUFFER_SIZE]; + char ts[32]; + va_list args; va_start (args, aFormat); fprintf(mFile, "%s - Info: %s\n", timestamp(ts), format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); - fflush(mFile); + fflush(mFile); va_end (args); -} - +} + void Logger::debug(const char *aFormat, ...) -{ +{ if (mLogLevel > eDEBUG) return; - - char buffer[LOGGER_BUFFER_SIZE]; - char ts[32]; - va_list args; + + char buffer[LOGGER_BUFFER_SIZE]; + char ts[32]; + va_list args; va_start (args, aFormat); fprintf(mFile, "%s - Debug: %s\n", timestamp(ts), format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); - fflush(mFile); + fflush(mFile); va_end (args); -} - - +} + + const char *Logger::format(char *aBuffer, int aLen, const char *aFormat, va_list args) -{ +{ vsprintf(aBuffer, aFormat, args); aBuffer[aLen - 1] = '\0'; return aBuffer; -} - +} + const char *Logger::timestamp(char *aBuffer) -{ -#ifdef WIN32 - SYSTEMTIME st; - GetSystemTime(&st); +{ +#ifdef WIN32 + SYSTEMTIME st; + GetSystemTime(&st); sprintf(aBuffer, "%4d-%02d-%02dT%02d:%02d:%02d.%03dZ", st.wYear, st.wMonth, st.wDay, st.wHour, - st.wMinute, st.wSecond, st.wMilliseconds); -#else - struct timeval tv; - struct timezone tz; - - gettimeofday(&tv, &tz); - + st.wMinute, st.wSecond, st.wMilliseconds); +#else + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + strftime(aBuffer, 64, "%Y-%m-%dT%H:%M:%S", gmtime(&tv.tv_sec)); sprintf(aBuffer + strlen(aBuffer), ".%06dZ", tv.tv_usec); -#endif - +#endif + return aBuffer; -} +} diff --git a/src/logger.hpp b/src/logger.hpp index 08f77ee..69cad9e 100644 --- a/src/logger.hpp +++ b/src/logger.hpp @@ -1,38 +1,70 @@ #ifndef LOGGER_HPP #define LOGGER_HPP - -#include -#include - -#define LOGGER_BUFFER_SIZE 1024 - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include +#include + +#define LOGGER_BUFFER_SIZE 1024 + class Logger { -public: +public: enum LogLevel { - eDEBUG, - eINFO, - eWARNING, - eERROR - }; - + eDEBUG, + eINFO, + eWARNING, + eERROR + }; + Logger(FILE *aFile = stderr) : mFile(aFile) { mLogLevel = eINFO; } void setLogLevel(LogLevel aLevel) { mLogLevel = aLevel; } LogLevel getLogLevel() { return mLogLevel; } - + virtual void error(const char *aFormat, ...); virtual void warning(const char *aFormat, ...); virtual void info(const char *aFormat, ...); virtual void debug(const char *aFormat, ...); - -protected: + +protected: const char *format(char *aBuffer, int aLen, const char *aFormat, va_list args); const char *timestamp(char *aBuffer); - - LogLevel mLogLevel; - FILE *mFile; -}; - -extern Logger *gLogger; + + LogLevel mLogLevel; + FILE *mFile; +}; + +extern Logger *gLogger; #endif diff --git a/src/serial.cpp b/src/serial.cpp index b560cd2..369595e 100644 --- a/src/serial.cpp +++ b/src/serial.cpp @@ -1,182 +1,213 @@ - -#include "internal.hpp" -#include "serial.hpp" -#include "logger.hpp" - -#include - -Serial::SerialError::SerialError(const char *aMessage) -{ - strncpy(mMessage, aMessage, 1023); - mMessage[1023] = '\0'; -} - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include "internal.hpp" +#include "serial.hpp" +#include "logger.hpp" + +#include + +Serial::SerialError::SerialError(const char *aMessage) +{ + strncpy(mMessage, aMessage, 1023); + mMessage[1023] = '\0'; +} + Serial::Serial(const char *aDevice, int aBaud, const char *aParity, int aDataBit, - int aStopBit) -{ - mBaud = aBaud; - strncpy(mDevice, aDevice, sizeof(mDevice) - 1); - mParity[sizeof(mDevice) - 1] = '\0'; - strncpy(mParity, aParity, sizeof(mParity) - 1); - mParity[sizeof(mParity) - 1] = '\0'; - mDataBit = aDataBit; - mStopBit = aStopBit; - mFlow = eNONE; - -#ifdef WIN32 - mFd = INVALID_HANDLE_VALUE; -#else - mFd = -1; -#endif - - mConnected = false; -} - -Serial::~Serial() -{ - disconnect(); -} - -int Serial::readUntil(const char *aUntil, char *aBuffer, int aLength) -{ - if (!mConnected) - { - gLogger->error("Trying to read when not connected"); - return -1; - } - - gLogger->debug("Reading upto %d bytes or '%c' we get a match", aLength, aUntil); - - int len = 0, count = 0; - char *cp = aBuffer; - const char *match = aUntil; - do - { - int ret = read(cp, 1); - if (ret == -1) + int aStopBit) +{ + mBaud = aBaud; + strncpy(mDevice, aDevice, sizeof(mDevice) - 1); + mParity[sizeof(mDevice) - 1] = '\0'; + strncpy(mParity, aParity, sizeof(mParity) - 1); + mParity[sizeof(mParity) - 1] = '\0'; + mDataBit = aDataBit; + mStopBit = aStopBit; + mFlow = eNONE; + +#ifdef WIN32 + mFd = INVALID_HANDLE_VALUE; +#else + mFd = -1; +#endif + + mConnected = false; +} + +Serial::~Serial() +{ + disconnect(); +} + +int Serial::readUntil(const char *aUntil, char *aBuffer, int aLength) +{ + if (!mConnected) + { + gLogger->error("Trying to read when not connected"); + return -1; + } + + gLogger->debug("Reading upto %d bytes or '%c' we get a match", aLength, aUntil); + + int len = 0, count = 0; + char *cp = aBuffer; + const char *match = aUntil; + do + { + int ret = read(cp, 1); + if (ret == -1) { - throw SerialError("Couldn't read"); - } - if (ret == 0) - { - usleep(10 * 1000); // 10 msec - if (count++ > 10) - { - gLogger->info("Read timed out\n"); - return -1; - } - } - else - { - count = 0; - - //printf("Received: %d == match: %d\n", *cp, *match); - if (*match == *cp) - match++; - else - match = aUntil; - - // See if we can match the beginnig of the string again. - if (*match == *cp) - match++; - //printf("Match now: %d\n", *match); - cp++; - len++; + throw SerialError("Couldn't read"); } + if (ret == 0) + { + usleep(10 * 1000); // 10 msec + if (count++ > 10) + { + gLogger->info("Read timed out\n"); + return -1; + } + } + else + { + count = 0; + + //printf("Received: %d == match: %d\n", *cp, *match); + if (*match == *cp) + match++; + else + match = aUntil; + + // See if we can match the beginnig of the string again. + if (*match == *cp) + match++; + //printf("Match now: %d\n", *match); + cp++; + len++; + } } while (len <= aLength && *match != '\0'); - - *cp = '\0'; - - gLogger->debug("Read returned: %d - '%s'", len, aBuffer); - - return len; -} - -int Serial::write(const char *aBuffer) -{ - gLogger->debug("Writing '%s'\n", aBuffer); - - int ret = write(aBuffer, (int) strlen(aBuffer)); - if (ret < 0) - throw SerialError("Couldn't write"); - - gLogger->debug("Write returned: %d\n", ret); - - return ret; -} - -bool Serial::flushInput() -{ - char buffer[2]; - int ret; - do - { - ret = read(buffer, 1); - if (ret < 0) - throw SerialError("Couldn't read"); + + *cp = '\0'; + + gLogger->debug("Read returned: %d - '%s'", len, aBuffer); + + return len; +} + +int Serial::write(const char *aBuffer) +{ + gLogger->debug("Writing '%s'\n", aBuffer); + + int ret = write(aBuffer, (int) strlen(aBuffer)); + if (ret < 0) + throw SerialError("Couldn't write"); + + gLogger->debug("Write returned: %d\n", ret); + + return ret; +} + +bool Serial::flushInput() +{ + char buffer[2]; + int ret; + do + { + ret = read(buffer, 1); + if (ret < 0) + throw SerialError("Couldn't read"); } while (ret > 0); - -#ifdef WIN32 - DWORD errors; - COMSTAT stat; - ClearCommError(mFd, &errors, &stat); -#else - tcflush(mFd, TCIFLUSH); -#endif - - return true; -} - -int Serial::readFully(char *aBuffer, int len, uint32_t timeout) -{ - int consumed = 0; - uint64_t start = getTimestamp(); + +#ifdef WIN32 + DWORD errors; + COMSTAT stat; + ClearCommError(mFd, &errors, &stat); +#else + tcflush(mFd, TCIFLUSH); +#endif + + return true; +} + +int Serial::readFully(char *aBuffer, int len, uint32_t timeout) +{ + int consumed = 0; + uint64_t start = getTimestamp(); while (consumed < len && (getTimestamp() - start) < timeout) { - int res = wait(100); + int res = wait(100); if (res > 0) { - int cnt = read(aBuffer + consumed, len - consumed); + int cnt = read(aBuffer + consumed, len - consumed); if (cnt < 0) { - gLogger->debug("Read returned: %d\n", res); - return -1; - } - consumed += cnt; + gLogger->debug("Read returned: %d\n", res); + return -1; + } + consumed += cnt; } else if (res < 0) { - gLogger->debug("Wait returned: %d\n", res); - return res; - } - } - - return consumed; -} - -int Serial::writeFully(const char *aBuffer, int len, uint32_t timeout) -{ - int written = 0; - - uint64_t start = getTimestamp(); + gLogger->debug("Wait returned: %d\n", res); + return res; + } + } + + return consumed; +} + +int Serial::writeFully(const char *aBuffer, int len, uint32_t timeout) +{ + int written = 0; + + uint64_t start = getTimestamp(); while (written < len && (getTimestamp() - start) < timeout) { - int res = wait(100, Serial::WRITE); + int res = wait(100, Serial::WRITE); if (res > 0) { - int cnt = write(aBuffer + written, len - written); + int cnt = write(aBuffer + written, len - written); if (cnt > 0) { - written += cnt; + written += cnt; } else { - gLogger->debug("Write returned: %d\n", res); - return -1; - } + gLogger->debug("Write returned: %d\n", res); + return -1; + } } else if (res < 0) { - gLogger->debug("Wait returned: %d\n", res); - return res; - } - } - - return written; -} - -#ifdef WIN32 + gLogger->debug("Wait returned: %d\n", res); + return res; + } + } + + return written; +} + +#ifdef WIN32 #include "serial.win32.inc" -#else +#else #include "serial.unix.inc" -#endif - +#endif + diff --git a/src/serial.hpp b/src/serial.hpp index 9f6244d..687a787 100644 --- a/src/serial.hpp +++ b/src/serial.hpp @@ -3,28 +3,60 @@ #define SERIAL_HPP class Serial { -public: - class SerialError - { - private: - char mMessage[1024]; - - public: - SerialError(const char *aMessage); - const char *message() const { return mMessage; } - }; - -protected: +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +public: + class SerialError + { + private: + char mMessage[1024]; + + public: + SerialError(const char *aMessage); + const char *message() const { return mMessage; } + }; + +protected: /* Descriptor (tty or socket) */ -#ifdef WIN32 - HANDLE mFd; -#else - int mFd; -#endif - +#ifdef WIN32 + HANDLE mFd; +#else + int mFd; +#endif + /* TCP port */ - int mPort; - + int mPort; + /* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*" on Mac OS X for KeySpan USB<->Serial adapters this string had to be made bigger on OS X as the directory+file name @@ -32,88 +64,88 @@ class Serial { OS X does support 256 byte file names. May become a problem in the future. */ -#ifdef __APPLE_CC__ - char mDevice[64]; -#else - char mDevice[16]; -#endif - +#ifdef __APPLE_CC__ + char mDevice[64]; +#else + char mDevice[16]; +#endif + /* Bauds: 9600, 19200, 57600, 115200, etc */ - int mBaud; - + int mBaud; + /* Data bit */ - unsigned char mDataBit; - + unsigned char mDataBit; + /* Stop bit */ - unsigned char mStopBit; - + unsigned char mStopBit; + /* Parity: "even", "odd", "none" */ - char mParity[5]; - bool mErrorHandling; - + char mParity[5]; + bool mErrorHandling; + enum FlowControl { - eSOFT, - eHARD, - eNONE - }; - FlowControl mFlow; - -#ifndef WIN32 + eSOFT, + eHARD, + eNONE + }; + FlowControl mFlow; + +#ifndef WIN32 /* Save old termios settings */ - struct termios mOldTios; -#endif - - bool mConnected; - -public: + struct termios mOldTios; +#endif + + bool mConnected; + +public: enum WaitMode { READ, WRITE - }; - - Serial(const char *aDevice, + }; + + Serial(const char *aDevice, int aBaud, const char *aParity, int aDataBit, - int aStopBit); - ~Serial(); - + int aStopBit); + ~Serial(); + bool connected() { return mConnected; } bool available() { return mConnected; } - - bool connect(); - bool disconnect(); - - int wait(int aTimeout, WaitMode mode = READ); - static uint64_t getTimestamp(); - - // Raw internal read - int read(char *aBuffer, int len); - - int readUntil(const char *aUntil, char *aBuffer, int aLength); + + bool connect(); + bool disconnect(); + + int wait(int aTimeout, WaitMode mode = READ); + static uint64_t getTimestamp(); + + // Raw internal read + int read(char *aBuffer, int len); + + int readUntil(const char *aUntil, char *aBuffer, int aLength); int read(char &c) { - char buffer[2]; - int ret = read(buffer, 1); - c = buffer[0]; - return ret; - } + char buffer[2]; + int ret = read(buffer, 1); + c = buffer[0]; + return ret; + } int read(unsigned char &b) { - char c; - int ret = read(c); - b = (unsigned char) c; - return ret; - } - - int readFully(char *aBuffer, int len, uint32_t timeout = 1000); - - // Raw internal write - int write(const char *aBuffer, int len); - int writeFully(const char *aBuffer, int len, uint32_t timeout = 1000); - - // Write cover methods - int write(const char *aBuffer); + char c; + int ret = read(c); + b = (unsigned char) c; + return ret; + } + + int readFully(char *aBuffer, int len, uint32_t timeout = 1000); + + // Raw internal write + int write(const char *aBuffer, int len); + int writeFully(const char *aBuffer, int len, uint32_t timeout = 1000); + + // Write cover methods + int write(const char *aBuffer); int print(char c) { char b[2]; b[0] = c; return write(b, 1); } - - bool flushInput(); - bool flush(); - bool printCommStatus(); -}; + + bool flushInput(); + bool flush(); + bool printCommStatus(); +}; #endif diff --git a/src/server.cpp b/src/server.cpp index 676e055..0fc5025 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,321 +1,320 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - -#include "internal.hpp" -#include "server.hpp" -#include "client.hpp" -#include "logger.hpp" - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include "internal.hpp" +#include "server.hpp" +#include "client.hpp" +#include "logger.hpp" + /* Constants */ -const int READ_BUFFER_LEN = 8092; - +const int READ_BUFFER_LEN = 8092; + /* Create the server and bind to the port */ -Server::Server(int aPort, int aHeartbeatFreq) -{ - mNumClients = 0; - mPort = aPort; - mTimeout = aHeartbeatFreq * 2; - - SOCKADDR_IN t; - -#ifndef WIN32 - signal(SIGPIPE, SIG_IGN); -#else - WSADATA w; - int iResult = WSAStartup(MAKEWORD(2, 2), &w); - +Server::Server(int aPort, int aHeartbeatFreq) +{ + mNumClients = 0; + mPort = aPort; + mTimeout = aHeartbeatFreq * 2; + + SOCKADDR_IN t; + +#ifndef WIN32 + signal(SIGPIPE, SIG_IGN); +#else + WSADATA w; + int iResult = WSAStartup(MAKEWORD(2, 2), &w); + if (iResult != NO_ERROR) { - gLogger->error("Error at WSAStartup()\n"); - exit(1); - } -#endif - - mSocket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - + gLogger->error("Error at WSAStartup()\n"); + exit(1); + } +#endif + + mSocket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (mSocket == INVALID_SOCKET) { - gLogger->error("Error at socket().", stderr); - delete this; - exit(1); - } - - t.sin_family = AF_INET; - t.sin_port = htons(aPort); - t.sin_addr.s_addr = htonl(INADDR_ANY); - + gLogger->error("Error at socket().", stderr); + delete this; + exit(1); + } + + t.sin_family = AF_INET; + t.sin_port = htons(aPort); + t.sin_addr.s_addr = htonl(INADDR_ANY); + if (::bind(mSocket, (SOCKADDR *)&t, sizeof(t)) == SOCKET_ERROR) { - gLogger->error("Failed to bind on port %d", aPort); - delete this; - exit(1); - } - + gLogger->error("Failed to bind on port %d", aPort); + delete this; + exit(1); + } + if (listen(mSocket, 4) == SOCKET_ERROR) { - gLogger->error("Error listening."); - delete this; - exit(1); - } - - // Default to a 10 second heartbeat - sprintf(mPong, "* PONG %d\n", aHeartbeatFreq); - - gLogger->info("Server started, waiting on port %d", aPort); -} - -Server::~Server() -{ - for (int i = 0; i < mNumClients; i++) - { - Client *client = mClients[i]; - delete client; - } - - ::shutdown(mSocket, SHUT_RDWR); - -#ifdef WINDOWS - WSACleanup(); -#endif -} - -void Server::readFromClients() -{ - MTCAutoLock lock(mListLock); - - fd_set rset; - FD_ZERO(&rset); - int nfds = 0; - for (int i = 0; i < mNumClients; i++) - { - Client *client = mClients[i]; - FD_SET(client->socket(), &rset); -#ifndef WIN32 - if (client->socket() > nfds) - nfds = client->socket(); -#endif - } -#ifdef WIN32 - nfds = mNumClients; -#else - nfds++; -#endif - - struct timeval timeout; - ::memset(&timeout, 0, sizeof(timeout)); - - if (::select(nfds, &rset, 0, 0, &timeout) > 0) - { - char buffer[READ_BUFFER_LEN]; - int len; - + gLogger->error("Error listening."); + delete this; + exit(1); + } + + // Default to a 10 second heartbeat + sprintf(mPong, "* PONG %d\n", aHeartbeatFreq); + + gLogger->info("Server started, waiting on port %d", aPort); +} + +Server::~Server() +{ + for (int i = 0; i < mNumClients; i++) + { + Client *client = mClients[i]; + delete client; + } + + ::shutdown(mSocket, SHUT_RDWR); + +#ifdef WINDOWS + WSACleanup(); +#endif +} + +void Server::readFromClients() +{ + MTCAutoLock lock(mListLock); + + fd_set rset; + FD_ZERO(&rset); + int nfds = 0; + for (int i = 0; i < mNumClients; i++) + { + Client *client = mClients[i]; + FD_SET(client->socket(), &rset); +#ifndef WIN32 + if (client->socket() > nfds) + nfds = client->socket(); +#endif + } +#ifdef WIN32 + nfds = mNumClients; +#else + nfds++; +#endif + + struct timeval timeout; + ::memset(&timeout, 0, sizeof(timeout)); + + if (::select(nfds, &rset, 0, 0, &timeout) > 0) + { + char buffer[READ_BUFFER_LEN]; + int len; + /* Since clients can be removed, we need to iterate backwards */ - for (int i = mNumClients - 1; i >= 0; i--) - { - Client *client = mClients[i]; - if (FD_ISSET(client->socket(), &rset)) - { - len = client->read(buffer, READ_BUFFER_LEN); - if (len > 0) - { - // Check for heartbeat - if (strncmp(buffer, "* PING", 6) == 0) - { - if (!client->mHeartbeats) - client->mHeartbeats = true; - client->mLastHeartbeat = getTimestamp(); - client->write(mPong); - } - else - printf("Received: %s", buffer); - } - else - removeClientInternal(client); - } - } - - } - - // Check heartbeats - for (int i = mNumClients - 1; i >= 0; i--) - { - Client *client = mClients[i]; - unsigned int now = getTimestamp(); - if (client->mHeartbeats) - { - if (deltaTimestamp(now, client->mLastHeartbeat) > (unsigned int) mTimeout) - { - gLogger->warning("Client has not sent heartbeat in over %d ms, disconnecting", - mTimeout); - removeClientInternal(client); - } - } - } -} - + for (int i = mNumClients - 1; i >= 0; i--) + { + Client *client = mClients[i]; + if (FD_ISSET(client->socket(), &rset)) + { + len = client->read(buffer, READ_BUFFER_LEN); + if (len > 0) + { + // Check for heartbeat + if (strncmp(buffer, "* PING", 6) == 0) + { + if (!client->mHeartbeats) + client->mHeartbeats = true; + client->mLastHeartbeat = getTimestamp(); + client->write(mPong); + } + else + printf("Received: %s", buffer); + } + else + removeClientInternal(client); + } + } + + } + + // Check heartbeats + for (int i = mNumClients - 1; i >= 0; i--) + { + Client *client = mClients[i]; + unsigned int now = getTimestamp(); + if (client->mHeartbeats) + { + if (deltaTimestamp(now, client->mLastHeartbeat) > (unsigned int) mTimeout) + { + gLogger->warning("Client has not sent heartbeat in over %d ms, disconnecting", + mTimeout); + removeClientInternal(client); + } + } + } +} + void Server::sendToClient(Client *aClient, const char *aString) -{ +{ if (aClient->write(aString) < 0) removeClient(aClient); -} - +} + void Server::sendToClients(const char *aString) -{ - MTCAutoLock lock(mListLock); - - for (int i = mNumClients - 1; i >= 0; i--) - { +{ + MTCAutoLock lock(mListLock); + + for (int i = mNumClients - 1; i >= 0; i--) + { if (mClients[i]->write(aString) < 0) - removeClientInternal(mClients[i]); - } -} - -Client *Server::connectToClients() -{ - fd_set rset; - FD_ZERO(&rset); - FD_SET(mSocket, &rset); -#ifdef WIN32 - int nfds = 1; -#else - int nfds = mSocket + 1; -#endif - - struct timeval timeout; - ::memset(&timeout, 0, sizeof(timeout)); - + removeClientInternal(mClients[i]); + } +} + +Client *Server::connectToClients() +{ + fd_set rset; + FD_ZERO(&rset); + FD_SET(mSocket, &rset); +#ifdef WIN32 + int nfds = 1; +#else + int nfds = mSocket + 1; +#endif + + struct timeval timeout; + ::memset(&timeout, 0, sizeof(timeout)); + Client *client = NULL; - bool added = false; - - if (::select(nfds, &rset, 0, 0, &timeout) > 0) - { - SOCKADDR_IN addr; - socklen_t len = sizeof(addr); - memset(&addr, 0, sizeof(addr)); - + bool added = false; + + if (::select(nfds, &rset, 0, 0, &timeout) > 0) + { + SOCKADDR_IN addr; + socklen_t len = sizeof(addr); + memset(&addr, 0, sizeof(addr)); + SOCKET socket = ::accept(mSocket, (SOCKADDR*) &addr, &len); if (socket == INVALID_SOCKET) { - gLogger->error("Error at accept()."); - return 0; - } - gLogger->info("Connected to: %s on port %d", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); - - int flag = 1; + gLogger->error("Error at accept()."); + return 0; + } + gLogger->info("Connected to: %s on port %d", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + + int flag = 1; ::setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (const char*) &flag, sizeof(int)); - - client = addClient(new Client(socket)); - added = true; - } - - return client; -} - - + + client = addClient(new Client(socket)); + added = true; + } + + return client; +} + + void Server::removeClientInternal(Client *aClient) -{ - int pos = 0; - for (pos = 0; pos < mNumClients; pos++) - { +{ + int pos = 0; + for (pos = 0; pos < mNumClients; pos++) + { if (mClients[pos] == aClient) - break; - } - - if (pos < mNumClients) - { - mNumClients--; - if (pos < mNumClients) - { + break; + } + + if (pos < mNumClients) + { + mNumClients--; + if (pos < mNumClients) + { /* Shift the array left to remove the item */ - memmove(mClients + pos, - mClients + (pos + 1), + memmove(mClients + pos, + mClients + (pos + 1), (mNumClients - pos) * sizeof(Client*)); - } + } delete aClient; mClients[mNumClients + 1] = 0; - } -} - + } +} + /* Removes a client from the client list. * Because the client can be removed during list iteration, lists * should always be iterated from last to first. */ void Server::removeClient(Client *aClient) -{ - MTCAutoLock lock(mListLock); +{ + MTCAutoLock lock(mListLock); removeClientInternal(aClient); -} - +} + Client *Server::addClient(Client *aClient) -{ - MTCAutoLock lock(mListLock); - - if (mNumClients < MAX_CLIENTS) - { +{ + MTCAutoLock lock(mListLock); + + if (mNumClients < MAX_CLIENTS) + { mClients[mNumClients] = aClient; - mNumClients++; - } - else - { + mNumClients++; + } + else + { delete aClient; aClient = NULL; - } - + } + return aClient; -} - -unsigned int Server::getTimestamp() -{ -#ifdef WIN32 - return GetTickCount(); -#else - timeval curtime; - gettimeofday(&curtime, 0); - - unsigned long ts = (unsigned long) curtime.tv_sec; - // Allow to truncate - ts *= 1000; - ts += curtime.tv_usec / 1000; - - return ts; -#endif -} - -unsigned int Server::deltaTimestamp(unsigned int a, unsigned int b) -{ - // Assume we are doing a - b where a should be larger, if it is not - // we have a wrap-around - unsigned int res; +} + +unsigned int Server::getTimestamp() +{ +#ifdef WIN32 + return GetTickCount(); +#else + timeval curtime; + gettimeofday(&curtime, 0); + + unsigned long ts = (unsigned long) curtime.tv_sec; + // Allow to truncate + ts *= 1000; + ts += curtime.tv_usec / 1000; + + return ts; +#endif +} + +unsigned int Server::deltaTimestamp(unsigned int a, unsigned int b) +{ + // Assume we are doing a - b where a should be larger, if it is not + // we have a wrap-around + unsigned int res; if ( a >= b ) - res = a - b; - else // b > a, Compute the distance from the end: - res = a + (0xFFFFFFFF - b); - return res; -} - + res = a - b; + else // b > a, Compute the distance from the end: + res = a + (0xFFFFFFFF - b); + return res; +} + diff --git a/src/server.hpp b/src/server.hpp index 3afc802..77e98e1 100755 --- a/src/server.hpp +++ b/src/server.hpp @@ -1,87 +1,87 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ #ifndef SERVER_HPP #define SERVER_HPP - -#include "threading.hpp" - -class Client; - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include "threading.hpp" + +class Client; + /* Some constants */ -const int MAX_CLIENTS = 64; - +const int MAX_CLIENTS = 64; + /* A socket server abstraction */ -class Server -{ -protected: - SOCKET mSocket; - Client *mClients[MAX_CLIENTS + 1]; - int mNumClients; - int mPort; - char mPong[32]; - int mTimeout; - - MTCMutex mListLock; - -protected: - // Assumes the mutex is already locked. +class Server +{ +protected: + SOCKET mSocket; + Client *mClients[MAX_CLIENTS + 1]; + int mNumClients; + int mPort; + char mPong[32]; + int mTimeout; + + MTCMutex mListLock; + +protected: + // Assumes the mutex is already locked. void removeClientInternal(Client *aClient); - - // Locks the mutex. + + // Locks the mutex. void removeClient(Client *aClient); Client *addClient(Client *aClient); - unsigned int getTimestamp(); - unsigned int deltaTimestamp(unsigned int, unsigned int); - -public: - Server(int aPort, int aHeartbeatFreq); - ~Server(); - - // Returns the new client. + unsigned int getTimestamp(); + unsigned int deltaTimestamp(unsigned int, unsigned int); + +public: + Server(int aPort, int aHeartbeatFreq); + ~Server(); + + // Returns the new client. Client *connectToClients(); /* Client factory */ - + /* I/O methods */ void readFromClients(); /* discard data on read side of sockets */ void sendToClients(const char *aString); void sendToClient(Client *aClient, const char *aString); - - /* Getters */ - int numClients() { return mNumClients; } - bool hasClients() { return mNumClients > 0; } - -}; + + /* Getters */ + int numClients() { return mNumClients; } + bool hasClients() { return mNumClients > 0; } + +}; #endif diff --git a/src/service.cpp b/src/service.cpp index 0a008ef..b0d5e2b 100644 --- a/src/service.cpp +++ b/src/service.cpp @@ -1,3 +1,35 @@ +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// #include "service.hpp" #include "string.h" @@ -9,19 +41,19 @@ MTConnectService::MTConnectService() : void MTConnectService::setName(const char *aName) { strncpy(mName, aName, 78); - mName[79] = '\0'; + mName[79] = '\0'; } void MTConnectService::initialize(int aArgc, const char *aArgv[]) { if (gLogger == NULL) { - if (mIsService) - gLogger = new ServiceLogger(); - else - gLogger = new Logger(); - } - if (mDebug) - gLogger->setLogLevel(Logger::eDEBUG); + if (mIsService) + gLogger = new ServiceLogger(); + else + gLogger = new Logger(); + } + if (mDebug) + gLogger->setLogLevel(Logger::eDEBUG); } #ifdef WIN32 @@ -31,12 +63,12 @@ void MTConnectService::initialize(int aArgc, const char *aArgv[]) #pragma comment(lib, "advapi32.lib") -#define SVC_ERROR ((DWORD)0xC0000001L) -#define SVC_WARNING ((DWORD)0x90000001L) -#define SVC_INFO ((DWORD)0x50000001L) +#define SVC_ERROR ((DWORD)0xC0000001L) +#define SVC_WARNING ((DWORD)0x90000001L) +#define SVC_INFO ((DWORD)0x50000001L) -SERVICE_STATUS gSvcStatus; -SERVICE_STATUS_HANDLE gSvcStatusHandle; +SERVICE_STATUS gSvcStatus; +SERVICE_STATUS_HANDLE gSvcStatusHandle; VOID WINAPI SvcCtrlHandler( DWORD ); VOID WINAPI SvcMain( DWORD, LPTSTR * ); @@ -50,66 +82,66 @@ MTConnectService *gService = NULL; // -// Purpose: +// Purpose: // Entry point for the process // // Parameters: // None -// +// // Return value: // None // -int MTConnectService::main(int argc, const char *argv[]) -{ - // If command-line parameter is "install", install the service. - // Otherwise, the service is probably being started by the SCM. +int MTConnectService::main(int argc, const char *argv[]) +{ + // If command-line parameter is "install", install the service. + // Otherwise, the service is probably being started by the SCM. if(argc > 1) { if (stricmp( argv[1], "debug") == 0 ) { - mDebug = true; + mDebug = true; } - initialize(argc - 2, argv + 2); + initialize(argc - 2, argv + 2); if (stricmp( argv[1], "install") == 0 ) - { - install(argc - 2, argv + 2); - return 0; + { + install(argc - 2, argv + 2); + return 0; } else if (stricmp( argv[1], "remove") == 0 ) { - remove(); - return 0; + remove(); + return 0; } else if (stricmp( argv[1], "debug") == 0) { - gLogger->setLogLevel(Logger::eDEBUG); - start(); - return 0; + gLogger->setLogLevel(Logger::eDEBUG); + start(); + return 0; } else if (stricmp( argv[1], "run") == 0) { - start(); - return 0; - } - } - - mIsService = true; - SERVICE_TABLE_ENTRY DispatchTable[] = - { - { mName, (LPSERVICE_MAIN_FUNCTION) SvcMain }, + start(); + return 0; + } + } + + mIsService = true; + SERVICE_TABLE_ENTRY DispatchTable[] = + { + { mName, (LPSERVICE_MAIN_FUNCTION) SvcMain }, { NULL, NULL } - }; + }; - gService = this; + gService = this; if (!StartServiceCtrlDispatcher( DispatchTable )) { - SvcReportEvent("StartServiceCtrlDispatcher"); + SvcReportEvent("StartServiceCtrlDispatcher"); } - return 0; -} + return 0; +} // -// Purpose: +// Purpose: // Installs a service in the SCM database // // Parameters: // None -// +// // Return value: // None // @@ -120,57 +152,57 @@ void MTConnectService::install(int argc, const char *argv[]) char szPath[MAX_PATH]; if( !GetModuleFileName( NULL, szPath, MAX_PATH ) ) - { - printf("Cannot install service (%d)\n", GetLastError()); - return; - } + { + printf("Cannot install service (%d)\n", GetLastError()); + return; + } - // Get a handle to the SCM database. + // Get a handle to the SCM database. schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database - SC_MANAGER_ALL_ACCESS); // full access rights + SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) - { - printf("OpenSCManager failed (%d)\n", GetLastError()); - return; - } + { + printf("OpenSCManager failed (%d)\n", GetLastError()); + return; + } schService = OpenService(schSCManager, mName, SC_MANAGER_ALL_ACCESS); if (schService != NULL) { if (! ChangeServiceConfig( - schService, // handle of service - SERVICE_WIN32_OWN_PROCESS | - SERVICE_INTERACTIVE_PROCESS, // service type: no change - SERVICE_AUTO_START, // service start type - SERVICE_NO_CHANGE, // error control: no change - szPath, // binary path: no change + schService, // handle of service + SERVICE_WIN32_OWN_PROCESS | + SERVICE_INTERACTIVE_PROCESS, // service type: no change + SERVICE_AUTO_START, // service start type + SERVICE_NO_CHANGE, // error control: no change + szPath, // binary path: no change NULL, // load order group: no change NULL, // tag ID: no change NULL, // dependencies: no change NULL, // account name: no change NULL, // password: no change NULL) ) // display name: no change - { - printf("ChangeServiceConfig failed (%d)\n", GetLastError()); - } + { + printf("ChangeServiceConfig failed (%d)\n", GetLastError()); + } else printf("Service updated successfully.\n"); } else { - // Create the service + // Create the service schService = CreateService( - schSCManager, // SCM database - mName, // name of service - mName, // service name to display - SERVICE_ALL_ACCESS, // desired access - SERVICE_WIN32_OWN_PROCESS | - SERVICE_INTERACTIVE_PROCESS, // service type - SERVICE_AUTO_START, // start type - SERVICE_ERROR_NORMAL, // error control type - szPath, // path to service's binary + schSCManager, // SCM database + mName, // name of service + mName, // service name to display + SERVICE_ALL_ACCESS, // desired access + SERVICE_WIN32_OWN_PROCESS | + SERVICE_INTERACTIVE_PROCESS, // service type + SERVICE_AUTO_START, // start type + SERVICE_ERROR_NORMAL, // error control type + szPath, // path to service's binary NULL, // no load ordering group NULL, // no tag identifier NULL, // no dependencies @@ -178,67 +210,67 @@ void MTConnectService::install(int argc, const char *argv[]) NULL); // no password if (schService == NULL) - { - printf("CreateService failed (%d)\n", GetLastError()); - CloseServiceHandle(schSCManager); - return; - } + { + printf("CreateService failed (%d)\n", GetLastError()); + CloseServiceHandle(schSCManager); + return; + } else printf("Service installed successfully\n"); - } + } CloseServiceHandle(schService); CloseServiceHandle(schSCManager); HKEY software; LONG res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE", &software); - if (res != ERROR_SUCCESS) - { - printf("Could not open software key: %d\n", res); - return; - } + if (res != ERROR_SUCCESS) + { + printf("Could not open software key: %d\n", res); + return; + } HKEY mtc; res = RegOpenKey(software, "MTConnect", &mtc); - if (res != ERROR_SUCCESS) - { - //printf("Could not open MTConnect, creating: %d\n", res); + if (res != ERROR_SUCCESS) + { + //printf("Could not open MTConnect, creating: %d\n", res); res = RegCreateKey(software, "MTConnect", &mtc); - if (res != ERROR_SUCCESS) - { - RegCloseKey(software); - printf("Could not create MTConnect: %d\n", res); - return; - } - } - RegCloseKey(software); - - // Create Service Key + if (res != ERROR_SUCCESS) + { + RegCloseKey(software); + printf("Could not create MTConnect: %d\n", res); + return; + } + } + RegCloseKey(software); + + // Create Service Key HKEY adapter; res = RegOpenKey(mtc, mName, &adapter); - if (res != ERROR_SUCCESS) - { - //printf("Could not open %s, creating: %d\n", mName, res); + if (res != ERROR_SUCCESS) + { + //printf("Could not open %s, creating: %d\n", mName, res); res = RegCreateKey(mtc, mName, &adapter); - if (res != ERROR_SUCCESS) - { - RegCloseKey(mtc); - printf("Could not create %s: %d\n", mName, res); - return; - } - } - RegCloseKey(mtc); + if (res != ERROR_SUCCESS) + { + RegCloseKey(mtc); + printf("Could not create %s: %d\n", mName, res); + return; + } + } + RegCloseKey(mtc); char arguments[2048]; - // TODO: create registry entries for arguments to be passed in later to create the adapter multi_sz - int d = 0; + // TODO: create registry entries for arguments to be passed in later to create the adapter multi_sz + int d = 0; for (int i = 0; i < argc; i++) { - strcpy(arguments + d, argv[i]); - d += strlen(arguments + d) + 1; - } + strcpy(arguments + d, argv[i]); + d += strlen(arguments + d) + 1; + } - arguments[d] = '\0'; + arguments[d] = '\0'; RegSetValueEx(adapter, "Arguments", 0, REG_MULTI_SZ, (const BYTE*) arguments, d); - RegCloseKey(adapter); + RegCloseKey(adapter); } void MTConnectService::remove() @@ -248,28 +280,28 @@ void MTConnectService::remove() manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (manager == NULL) { - printf("Could not open Service Control Manager"); - return; - } + printf("Could not open Service Control Manager"); + return; + } service = ::OpenService(manager, mName, SERVICE_ALL_ACCESS); - CloseServiceHandle(manager); + CloseServiceHandle(manager); if (service == NULL) { - printf("Could not open Service "); - return; - } - + printf("Could not open Service "); + return; + } + if(::DeleteService(service) == 0) { - printf("Could delete service %s\n", mName); + printf("Could delete service %s\n", mName); } else { - printf("Successfully removed service %s\n", mName); + printf("Successfully removed service %s\n", mName); } - - ::CloseServiceHandle(service); + + ::CloseServiceHandle(service); } // -// Purpose: +// Purpose: // Entry point for the service // // Parameters: @@ -277,55 +309,55 @@ void MTConnectService::remove() // lpszArgv - Array of strings. The first string is the name of // the service and subsequent strings are passed by the process // that called the StartService function to start the service. -// +// // Return value: // None. // VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv ) { - // Register the handler function for the service + // Register the handler function for the service char path[MAX_PATH]; if( !GetModuleFileName(NULL, path, MAX_PATH ) ) - { - printf("Cannot get path of executable (%d)\n", GetLastError()); - return; - } + { + printf("Cannot get path of executable (%d)\n", GetLastError()); + return; + } char *cp = strrchr(path, '\\'); if (cp != NULL) - { - *cp = '\0'; + { + *cp = '\0'; SetCurrentDirectory(path); - } + } - gService->setName(lpszArgv[0]); + gService->setName(lpszArgv[0]); gSvcStatusHandle = RegisterServiceCtrlHandler( - gService->name(), - SvcCtrlHandler); + gService->name(), + SvcCtrlHandler); if( !gSvcStatusHandle ) - { - SvcReportEvent("RegisterServiceCtrlHandler"); - return; - } + { + SvcReportEvent("RegisterServiceCtrlHandler"); + return; + } - // These SERVICE_STATUS members remain as set here + // These SERVICE_STATUS members remain as set here - gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - gSvcStatus.dwServiceSpecificExitCode = 0; + gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + gSvcStatus.dwServiceSpecificExitCode = 0; - // Report initial status to the SCM + // Report initial status to the SCM ReportSvcStatus( SERVICE_START_PENDING, NO_ERROR, 10000 ); - // Perform service-specific initialization and work. - Sleep(20000); + // Perform service-specific initialization and work. + Sleep(20000); SvcInit( dwArgc, lpszArgv ); } // -// Purpose: +// Purpose: // The service code // // Parameters: @@ -333,147 +365,147 @@ VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv ) // lpszArgv - Array of strings. The first string is the name of // the service and subsequent strings are passed by the process // that called the StartService function to start the service. -// +// // Return value: // None // VOID SvcInit( DWORD dwArgc, LPTSTR *lpszArgv) { - // Get the real arguments from the registry + // Get the real arguments from the registry char key[1024]; - snprintf(key, 1022, "SOFTWARE\\MTConnect\\%s", gService->name()); - key[1023] = '\0'; + snprintf(key, 1022, "SOFTWARE\\MTConnect\\%s", gService->name()); + key[1023] = '\0'; HKEY adapter; LONG res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &adapter); - if (res != ERROR_SUCCESS) - { - SvcReportEvent("RegOpenKey: Could not open Adapter"); + if (res != ERROR_SUCCESS) + { + SvcReportEvent("RegOpenKey: Could not open Adapter"); ReportSvcStatus( SERVICE_STOPPED, 1, 0 ); - return; - } + return; + } char *argp[64]; BYTE arguments[2048]; DWORD len = 2047, type, argc = 0; res = RegQueryValueEx(adapter, "Arguments", 0, &type, (BYTE*) arguments, &len); - if (res == ERROR_SUCCESS) - { + if (res == ERROR_SUCCESS) + { DWORD i = 0; while (i < len) { argp[argc] = (char*) arguments + i; i += strlen((char*) arguments + i) + 1; - argc++; - } - argp[argc] = 0; + argc++; + } + argp[argc] = 0; } else { - SvcReportEvent("RegOpenKey: Could not get Arguments"); - RegCloseKey(adapter); + SvcReportEvent("RegOpenKey: Could not get Arguments"); + RegCloseKey(adapter); ReportSvcStatus( SERVICE_STOPPED, 1, 0 ); - return; - } + return; + } gService->initialize(argc, (const char**) argp); - // TO_DO: Declare and set any required variables. - // Be sure to periodically call ReportSvcStatus() with - // SERVICE_START_PENDING. If initialization fails, call - // ReportSvcStatus with SERVICE_STOPPED. + // TO_DO: Declare and set any required variables. + // Be sure to periodically call ReportSvcStatus() with + // SERVICE_START_PENDING. If initialization fails, call + // ReportSvcStatus with SERVICE_STOPPED. - // Create an event. The control handler function, SvcCtrlHandler, - // signals this event when it receives the stop control code. + // Create an event. The control handler function, SvcCtrlHandler, + // signals this event when it receives the stop control code. - // Report running status when initialization is complete. + // Report running status when initialization is complete. ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 ); - // TO_DO: Perform work until service stops. - gService->start(); + // TO_DO: Perform work until service stops. + gService->start(); ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 ); } // -// Purpose: +// Purpose: // Sets the current service status and reports it to the SCM. // // Parameters: // dwCurrentState - The current state (see SERVICE_STATUS) // dwWin32ExitCode - The system error code -// dwWaitHint - Estimated time for pending operation, +// dwWaitHint - Estimated time for pending operation, // in milliseconds -// +// // Return value: // None // VOID ReportSvcStatus( DWORD dwCurrentState, - DWORD dwWin32ExitCode, - DWORD dwWaitHint) + DWORD dwWin32ExitCode, + DWORD dwWaitHint) { static DWORD dwCheckPoint = 1; - // Fill in the SERVICE_STATUS structure. + // Fill in the SERVICE_STATUS structure. - gSvcStatus.dwCurrentState = dwCurrentState; - gSvcStatus.dwWin32ExitCode = dwWin32ExitCode; - gSvcStatus.dwWaitHint = dwWaitHint; + gSvcStatus.dwCurrentState = dwCurrentState; + gSvcStatus.dwWin32ExitCode = dwWin32ExitCode; + gSvcStatus.dwWaitHint = dwWaitHint; - if (dwCurrentState == SERVICE_START_PENDING) - gSvcStatus.dwControlsAccepted = 0; - else - gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + if (dwCurrentState == SERVICE_START_PENDING) + gSvcStatus.dwControlsAccepted = 0; + else + gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; if ( (dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED) ) - gSvcStatus.dwCheckPoint = 0; - else - gSvcStatus.dwCheckPoint = dwCheckPoint++; + gSvcStatus.dwCheckPoint = 0; + else + gSvcStatus.dwCheckPoint = dwCheckPoint++; - // Report the status of the service to the SCM. + // Report the status of the service to the SCM. SetServiceStatus( gSvcStatusHandle, &gSvcStatus ); } // -// Purpose: +// Purpose: // Called by SCM whenever a control code is sent to the service // using the ControlService function. // // Parameters: // dwCtrl - control code -// +// // Return value: // None // VOID WINAPI SvcCtrlHandler( DWORD dwCtrl ) { - // Handle the requested control code. + // Handle the requested control code. switch(dwCtrl) - { - case SERVICE_CONTROL_STOP: + { + case SERVICE_CONTROL_STOP: ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); if (gService != NULL) - gService->stop(); + gService->stop(); ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0); - return; + return; - case SERVICE_CONTROL_INTERROGATE: - break; + case SERVICE_CONTROL_INTERROGATE: + break; - default: - break; - } + default: + break; + } } // -// Purpose: +// Purpose: // Logs messages to the event log // // Parameters: // szFunction - name of function that failed -// +// // Return value: // None // @@ -481,7 +513,7 @@ VOID WINAPI SvcCtrlHandler( DWORD dwCtrl ) // The service must have an entry in the Application event log. // VOID SvcReportEvent(LPTSTR szFunction) -{ +{ HANDLE hEventSource; LPCTSTR lpszStrings[2]; char Buffer[80]; @@ -489,24 +521,24 @@ VOID SvcReportEvent(LPTSTR szFunction) hEventSource = RegisterEventSource(NULL, gService->name()); if( NULL != hEventSource ) - { + { sprintf(Buffer, "%-60s failed with %d", szFunction, GetLastError()); - lpszStrings[0] = gService->name(); - lpszStrings[1] = Buffer; + lpszStrings[0] = gService->name(); + lpszStrings[1] = Buffer; ReportEvent(hEventSource, // event log handle - EVENTLOG_ERROR_TYPE, // event type - 0, // event category - SVC_ERROR, // event identifier + EVENTLOG_ERROR_TYPE, // event type + 0, // event category + SVC_ERROR, // event identifier NULL, // no security identifier - 2, // size of lpszStrings array + 2, // size of lpszStrings array 0, // no binary data - lpszStrings, // array of strings + lpszStrings, // array of strings NULL); // no binary data - DeregisterEventSource(hEventSource); - } + DeregisterEventSource(hEventSource); + } } VOID SvcLogEvent(WORD aType, DWORD aId, LPSTR aText) @@ -517,30 +549,30 @@ VOID SvcLogEvent(WORD aType, DWORD aId, LPSTR aText) hEventSource = RegisterEventSource(NULL, gService->name()); if( NULL != hEventSource ) - { - lpszStrings[0] = gService->name(); - lpszStrings[1] = "\n\n"; + { + lpszStrings[0] = gService->name(); + lpszStrings[1] = "\n\n"; lpszStrings[2] = aText; ReportEvent(hEventSource, // event log handle aType, // event type - 0, // event category + 0, // event category aId, // event identifier NULL, // no security identifier - 3, // size of lpszStrings array - 0, // no binary data - lpszStrings, // array of strings + 3, // size of lpszStrings array + 0, // no binary data + lpszStrings, // array of strings NULL); // no binary data - DeregisterEventSource(hEventSource); - } + DeregisterEventSource(hEventSource); + } } void ServiceLogger::error(const char *aFormat, ...) { char buffer[LOGGER_BUFFER_SIZE]; - va_list args; + va_list args; va_start (args, aFormat); SvcLogEvent(EVENTLOG_ERROR_TYPE, SVC_ERROR, (LPSTR) format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); va_end (args); @@ -549,7 +581,7 @@ void ServiceLogger::error(const char *aFormat, ...) void ServiceLogger::warning(const char *aFormat, ...) { char buffer[LOGGER_BUFFER_SIZE]; - va_list args; + va_list args; va_start (args, aFormat); SvcLogEvent(EVENTLOG_WARNING_TYPE, SVC_WARNING, (LPSTR) format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); va_end (args); @@ -558,7 +590,7 @@ void ServiceLogger::warning(const char *aFormat, ...) void ServiceLogger::info(const char *aFormat, ...) { char buffer[LOGGER_BUFFER_SIZE]; - va_list args; + va_list args; va_start (args, aFormat); SvcLogEvent(EVENTLOG_INFORMATION_TYPE, SVC_INFO, (LPSTR) format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); va_end (args); @@ -566,17 +598,17 @@ void ServiceLogger::info(const char *aFormat, ...) void ServiceLogger::debug(const char *aFormat, ...) { - // Debug service logging is not supported + // Debug service logging is not supported } #else -int MTConnectService::main(int argc, const char *argv[]) -{ - initialize(argc - 1, argv + 1); - start(); - return 0; -} +int MTConnectService::main(int argc, const char *argv[]) +{ + initialize(argc - 1, argv + 1); + start(); + return 0; +} void MTConnectService::install(int argc, const char *argv[]) { diff --git a/src/service.hpp b/src/service.hpp index 1409f1d..f2cdbea 100644 --- a/src/service.hpp +++ b/src/service.hpp @@ -1,41 +1,73 @@ #ifndef SERVICE_HPP #define SERVICE_HPP - -#include "logger.hpp" - -#define SERVICE_NAME_LEN 80 - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include "logger.hpp" + +#define SERVICE_NAME_LEN 80 + class MTConnectService { -public: - MTConnectService(); +public: + MTConnectService(); virtual int main(int aArgc, const char *aArgv[]); virtual void initialize(int aArgc, const char *aArgv[]) = 0; - + void setName(const char *aName); - virtual void stop() = 0; - virtual void start() = 0; + virtual void stop() = 0; + virtual void start() = 0; const char *name() { return mName; } - -protected: - char mName[SERVICE_NAME_LEN]; - bool mIsService; - bool mDebug; - - void install(int argc, const char *argv[]); - void remove(); -}; - -#ifdef WIN32 + +protected: + char mName[SERVICE_NAME_LEN]; + bool mIsService; + bool mDebug; + + void install(int argc, const char *argv[]); + void remove(); +}; + +#ifdef WIN32 class ServiceLogger : public Logger { public: virtual void error(const char *aFormat, ...); virtual void warning(const char *aFormat, ...); virtual void info(const char *aFormat, ...); virtual void debug(const char *aFormat, ...); - + protected: }; -#else +#else class ServiceLogger : public Logger {}; #endif -#endif +#endif diff --git a/src/string_array.cpp b/src/string_array.cpp index 1ef1ed2..8e37e19 100644 --- a/src/string_array.cpp +++ b/src/string_array.cpp @@ -1,79 +1,110 @@ - -#include "internal.hpp" -#include "string_array.hpp" - -#define BLOCK_SIZE 256 - -StringArray::StringArray() -{ - mLength = 0; - mSize = BLOCK_SIZE; +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include "internal.hpp" +#include "string_array.hpp" + +#define BLOCK_SIZE 256 + +StringArray::StringArray() +{ + mLength = 0; + mSize = BLOCK_SIZE; mArray = (char **) malloc(sizeof(char*) * mSize); - mArray[mLength = 0]; -} - -StringArray::~StringArray() -{ - clear(); - free(mArray); -} - -void StringArray::clear() -{ - for (int i = 0; i < mLength; i++) - free(mArray[i]); - mLength = 0; -} - + mArray[mLength = 0]; +} + +StringArray::~StringArray() +{ + clear(); + free(mArray); +} + +void StringArray::clear() +{ + for (int i = 0; i < mLength; i++) + free(mArray[i]); + mLength = 0; +} + void StringArray::append(const char *aString) -{ +{ char *dup = strdup(aString); if (dup == 0) - { - perror("StringArray::append"); - exit(2); - } - - if (mLength >= mSize - 1) - { - mSize += BLOCK_SIZE; + { + perror("StringArray::append"); + exit(2); + } + + if (mLength >= mSize - 1) + { + mSize += BLOCK_SIZE; mArray = (char**) realloc(mArray, mSize * sizeof(char*)); if (mArray == 0) - { - perror("StringArray::append"); - exit(2); - } - } - - mArray[mLength++] = dup; -} - + { + perror("StringArray::append"); + exit(2); + } + } + + mArray[mLength++] = dup; +} + int StringArray::readFile(const char *aFileName) -{ - // First clear out existing contents - clear(); - - // Parse file. +{ + // First clear out existing contents + clear(); + + // Parse file. FILE *file = fopen(aFileName, "r"); if (file == 0) { printf("Could not open file: %s\n", aFileName); } - else - { + else + { printf("Parsing file: %s\n", aFileName); char buffer[1024]; - while (fgets(buffer, 1024, file) != 0) - { - int last = strlen(buffer) - 1; - if (last > 0 && buffer[last] == '\n') - buffer[last] = 0; - append(buffer); - } - } - return mLength; -} - + while (fgets(buffer, 1024, file) != 0) + { + int last = strlen(buffer) - 1; + if (last > 0 && buffer[last] == '\n') + buffer[last] = 0; + append(buffer); + } + } + return mLength; +} + diff --git a/src/string_array.hpp b/src/string_array.hpp index 5fd990c..307704b 100755 --- a/src/string_array.hpp +++ b/src/string_array.hpp @@ -1,36 +1,36 @@ - -/* -* Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + #ifndef STRING_ARRAY_HPP #define STRING_ARRAY_HPP @@ -40,39 +40,39 @@ * exceeded. Used for storing the program codes */ -class StringArray -{ -protected: - char **mArray; - int mLength; - int mSize; - -public: - StringArray(); - ~StringArray(); - +class StringArray +{ +protected: + char **mArray; + int mLength; + int mSize; + +public: + StringArray(); + ~StringArray(); + int length() { return mLength; } - - // Copies the string when it is appended + + // Copies the string when it is appended void append(const char *aString); - void clear(); - - // Getters + void clear(); + + // Getters const char *stringAt(int index); const char *operator[](int index) { return stringAt(index); } - - // File Handler method, should be another class... - // Returns file size. + + // File Handler method, should be another class... + // Returns file size. int readFile(const char *aFileName); -}; - +}; + inline const char *StringArray::stringAt(int index) -{ - if (index >= 0 && index < mLength) - return mArray[index]; - else +{ + if (index >= 0 && index < mLength) + return mArray[index]; + else return 0; -} +} #endif diff --git a/src/string_buffer.cpp b/src/string_buffer.cpp index e582230..0135e35 100755 --- a/src/string_buffer.cpp +++ b/src/string_buffer.cpp @@ -1,41 +1,40 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - -#include "internal.hpp" -#include "string_buffer.hpp" - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include "internal.hpp" +#include "string_buffer.hpp" + StringBuffer::StringBuffer(const char *aString) -{ +{ mLength = mSize = 0; mTimestamp[0] = 0; if (aString != 0) @@ -46,76 +45,76 @@ StringBuffer::StringBuffer(const char *aString) { mBuffer = 0; } -} - -StringBuffer::~StringBuffer() -{ +} + +StringBuffer::~StringBuffer() +{ if (mBuffer != 0) - free(mBuffer); -} - + free(mBuffer); +} + const char *StringBuffer::append(const char* aString) -{ +{ /* Include additional length for timestamp */ size_t len = strlen(aString); size_t totalLength = mLength + len; size_t tsLen = strlen(mTimestamp); if (mLength == 0) - totalLength += tsLen; - if (totalLength >= mSize) - { + totalLength += tsLen; + if (totalLength >= mSize) + { size_t newLen = ((totalLength / 1024) + 1) * 1024; char *newBuffer = (char*) malloc(newLen); - memcpy(newBuffer, mBuffer, mLength); - - free(mBuffer); - mBuffer = newBuffer; - mSize = newLen; - } - + memcpy(newBuffer, mBuffer, mLength); + + free(mBuffer); + mBuffer = newBuffer; + mSize = newLen; + } + if (mLength == 0 && tsLen > 0) - { - strcpy(mBuffer, mTimestamp); - mLength += tsLen; - } - + { + strcpy(mBuffer, mTimestamp); + mLength += tsLen; + } + strcpy(mBuffer + mLength, aString); - mLength += len; - - return mBuffer; -} - -void StringBuffer::newline() -{ - append("\n"); - append(mTimestamp); -} - -void StringBuffer::reset() -{ + mLength += len; + + return mBuffer; +} + +void StringBuffer::newline() +{ + append("\n"); + append(mTimestamp); +} + +void StringBuffer::reset() +{ if (mBuffer != 0) - { - mBuffer[0] = 0; + { + mBuffer[0] = 0; mLength = 0; - } -} - -void StringBuffer::timestamp() -{ -#ifdef WIN32 - SYSTEMTIME st; - GetSystemTime(&st); + } +} + +void StringBuffer::timestamp() +{ +#ifdef WIN32 + SYSTEMTIME st; + GetSystemTime(&st); sprintf(mTimestamp, "%4d-%02d-%02dT%02d:%02d:%02d.%03dZ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); -#else - struct timeval tv; - struct timezone tz; - - gettimeofday(&tv, &tz); - +#else + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + strftime(mTimestamp, 64, "%Y-%m-%dT%H:%M:%S", gmtime(&tv.tv_sec)); - sprintf(mTimestamp + strlen(mTimestamp), ".%06dZ", tv.tv_usec); -#endif -} + sprintf(mTimestamp + strlen(mTimestamp), ".%06dZ", tv.tv_usec); +#endif +} diff --git a/src/string_buffer.hpp b/src/string_buffer.hpp index 0ec5292..84fd47e 100755 --- a/src/string_buffer.hpp +++ b/src/string_buffer.hpp @@ -1,36 +1,36 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + #ifndef STRING_BUFFER_HPP #define STRING_BUFFER_HPP @@ -41,26 +41,26 @@ * * Currently allocating in 1k increments. */ -class StringBuffer -{ -protected: +class StringBuffer +{ +protected: char *mBuffer; /* A resizable character buffer */ size_t mSize; /* The allocated size of the string */ size_t mLength; /* The length of the string */ - char mTimestamp[64]; - -public: + char mTimestamp[64]; + +public: StringBuffer(const char *aString = 0); - ~StringBuffer(); - + ~StringBuffer(); + operator const char *() { return mBuffer; } const char *append(const char *aString); const char* operator<<(const char *aString) { return append(aString); } - void reset(); - void timestamp(); + void reset(); + void timestamp(); void setTimestamp(const char *aTs) { strcpy(mTimestamp, aTs); } size_t length() { return mLength; } - void newline(); -}; + void newline(); +}; #endif diff --git a/src/threading.hpp b/src/threading.hpp index 65d946b..cefb805 100644 --- a/src/threading.hpp +++ b/src/threading.hpp @@ -1,119 +1,119 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ #ifndef THREADING_HPP #define THREADING_HPP - -#ifdef THREADED - -#ifndef WIN32 +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#ifdef THREADED + +#ifndef WIN32 #include -#endif - -class MTCMutex -{ -public: +#endif + +class MTCMutex +{ +public: MTCMutex() { -#ifdef WIN32 - InitializeCriticalSection(&mLock); -#else - pthread_mutex_init(&mLock, NULL); -#endif - } - +#ifdef WIN32 + InitializeCriticalSection(&mLock); +#else + pthread_mutex_init(&mLock, NULL); +#endif + } + ~MTCMutex() { -#ifdef WIN32 - DeleteCriticalSection(&mLock); -#else - pthread_mutex_destroy(&mLock); -#endif - } - +#ifdef WIN32 + DeleteCriticalSection(&mLock); +#else + pthread_mutex_destroy(&mLock); +#endif + } + void lock() { -#ifdef WIN32 - EnterCriticalSection(&mLock); -#else - pthread_mutex_lock(&mLock); -#endif - } - +#ifdef WIN32 + EnterCriticalSection(&mLock); +#else + pthread_mutex_lock(&mLock); +#endif + } + void unlock() { -#ifdef WIN32 - LeaveCriticalSection(&mLock); -#else - pthread_mutex_unlock(&mLock); -#endif - } - -protected: -#ifdef WIN32 - CRITICAL_SECTION mLock; -#else - pthread_mutex_t mLock; -#endif - -private: +#ifdef WIN32 + LeaveCriticalSection(&mLock); +#else + pthread_mutex_unlock(&mLock); +#endif + } + +protected: +#ifdef WIN32 + CRITICAL_SECTION mLock; +#else + pthread_mutex_t mLock; +#endif + +private: MTCMutex(const MTCMutex& aMutex) { - // No copy constructor is possible - } -}; - -#else // Not threaded - -class MTCMutex -{ -public: - void lock() {} - void unlock() {} -}; - -#endif - + // No copy constructor is possible + } +}; + +#else // Not threaded + +class MTCMutex +{ +public: + void lock() {} + void unlock() {} +}; + +#endif + class MTCAutoLock { -public: +public: MTCAutoLock(MTCMutex &aMutex) : mMutex(&aMutex) { - mMutex->lock(); - } - + mMutex->lock(); + } + ~MTCAutoLock() { - mMutex->unlock(); - } - -protected: - MTCMutex *mMutex; - -private: + mMutex->unlock(); + } + +protected: + MTCMutex *mMutex; + +private: MTCAutoLock() : mMutex(NULL) {} -}; +}; #endif \ No newline at end of file diff --git a/src/time_series.cpp b/src/time_series.cpp index 2380c6c..9512ecc 100644 --- a/src/time_series.cpp +++ b/src/time_series.cpp @@ -1,115 +1,114 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - -#include "internal.hpp" -#include "time_series.hpp" -#include "string_buffer.hpp" - -using namespace std; - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include "internal.hpp" +#include "time_series.hpp" +#include "string_buffer.hpp" + +using namespace std; + /* * TimeSeries methods */ TimeSeries::TimeSeries(const char *aName, float aEpsilon, float aRate) : DeviceDatum(aName), mEpsilon(aEpsilon), mRate(aRate) -{ +{ mUnavailable = false; -} - +} + void TimeSeries::addValue(float aValue) -{ +{ mValues.push_back(aValue); - - mChanged = true; - mHasValue = true; - mUnavailable = false; -} - + + mChanged = true; + mHasValue = true; + mUnavailable = false; +} + bool TimeSeries::setValue(std::vector aValues) -{ +{ mValues = aValues; - - mChanged = true; - mHasValue = true; - mUnavailable = false; - - return true; -} - + + mChanged = true; + mHasValue = true; + mUnavailable = false; + + return true; +} + bool TimeSeries::append(StringBuffer &aStringBuffer) -{ +{ char buffer[1024]; - if (mUnavailable) - { + if (mUnavailable) + { snprintf(buffer, 1023, "|%s|0||UNAVAILABLE", mName); aStringBuffer.append(buffer); - } - else - { - if (mRate > 0) + } + else + { + if (mRate > 0) snprintf(buffer, 1023, "|%s|%d|%g|", mName, (int) mValues.size(), mRate); - else + else snprintf(buffer, 1023, "|%s|%d||", mName, (int) mValues.size()); aStringBuffer.append(buffer); for (size_t i = 0; i < mValues.size(); i++) - { - snprintf(buffer, 1023, "%.10g ", mValues[i]); + { + snprintf(buffer, 1023, "%.10g ", mValues[i]); aStringBuffer.append(buffer); - } - } - - mChanged = false; - return true; -} - + } + } + + mChanged = false; + return true; +} + char *TimeSeries::toString(char *aBuffer, int aMaxLen) -{ +{ return aBuffer; -} - -bool TimeSeries::unavailable() -{ - if (!mUnavailable) - { - mChanged = true; - mUnavailable = true; - mHasValue = true; - } - - return mChanged; -} - +} + +bool TimeSeries::unavailable() +{ + if (!mUnavailable) + { + mChanged = true; + mUnavailable = true; + mHasValue = true; + } + + return mChanged; +} + bool TimeSeries::requiresFlush() -{ - return true; -} +{ + return true; +} diff --git a/src/time_series.hpp b/src/time_series.hpp index 62544ef..7b0f162 100644 --- a/src/time_series.hpp +++ b/src/time_series.hpp @@ -1,58 +1,58 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ #ifndef TIME_SERIES_HPP #define TIME_SERIES_HPP - -#include "device_datum.hpp" -#include - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include "device_datum.hpp" +#include + /* * A time series of samples */ -class TimeSeries : public DeviceDatum -{ -protected: - std::vector mValues; - bool mUnavailable; - float mEpsilon; - float mRate; - -public: +class TimeSeries : public DeviceDatum +{ +protected: + std::vector mValues; + bool mUnavailable; + float mEpsilon; + float mRate; + +public: TimeSeries(const char *aName, float aEpsilon = 0.000001, float aRate = -1.0); - + bool setValue(std::vector aValues); void addValue(float aValue); std::vector &getValues() { return mValues; } @@ -60,12 +60,12 @@ class TimeSeries : public DeviceDatum void clear() { mValues.clear(); } float getRate() { return mRate; } void setRate(float aRate) { mRate = aRate; } - + virtual char *toString(char *aBuffer, int aMaxLen); virtual bool unavailable(); virtual bool requiresFlush(); virtual bool append(StringBuffer &aBuffer); }; - - + + #endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a8bedf1..19da26b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,44 +1,55 @@ -# The name of our project is "HELLO". CMakeLists files in this project can -# refer to the root source directory of the project as ${HELLO_SOURCE_DIR} and -# to the root binary directory of the project as ${HELLO_BINARY_DIR}. -cmake_minimum_required (VERSION 2.6) - -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}") - -set(CMAKE_BUILD_TYPE DEBUG) -set(CMAKE_FIND_FRAMEWORK NEVER FORCE) -set(CMAKE_FIND_APPBUNDLE NEVER) - -if(WIN32) - set(CPPUNIT_INCLUDE_DIR ../win32/cppunit-1.12.1/include) - file(GLOB CPPUNIT_LIBRARY ../win32/cppunit-1.12.1/lib/cppunitd.lib) -endif(WIN32) - if(UNIX) - execute_process(COMMAND uname OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CMAKE_SYSTEM_NAME) - if(CMAKE_SYSTEM_NAME MATCHES Linux) - set(LINUX_LIBRARIES pthread) - endif(CMAKE_SYSTEM_NAME MATCHES Linux) + execute_process(COMMAND uname OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CMAKE_SYSTEM_NAME) + if(CMAKE_SYSTEM_NAME MATCHES Linux) + set(LINUX_LIBRARIES pthread) + endif(CMAKE_SYSTEM_NAME MATCHES Linux) endif(UNIX) -set(YAML_CPP_SOURCE_DIR ../yaml/src) -set(YAML_CPP_INCLUDE_DIR ../yaml/include) -set(ADAPTER_CPP_SOURCE_DIR ../src) -set(ADAPTER_CPP_INCLUDE_DIR ../src) +set(YAML_CPP_SOURCE_DIR ${CMAKE_SOURCE_DIR}/yaml/src) +set(YAML_CPP_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/yaml/include) +set(ADAPTER_CPP_SOURCE_DIR ${CMAKE_SOURCE_DIR}/src) +set(ADAPTER_CPP_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/src) file(GLOB yaml_sources ${YAML_CPP_SOURCE_DIR}/[a-z]*.cpp) +file(GLOB yaml_headers ${YAML_CPP_SOURCE_DIR}/[a-z]*.h) file(GLOB adapter_sources ${ADAPTER_CPP_SOURCE_DIR}/[a-z_]*.cpp) +file(GLOB adapter_headers ${ADAPTER_CPP_SOURCE_DIR}/[a-z_]*.hpp) file(GLOB test_sources [a-zA-Z_]*.cpp [a-z]*.c) file(GLOB headers [a-z_]*.hpp) -include_directories(${YAML_CPP_SOURCE_DIR} ${YAML_CPP_INCLUDE_DIR} ${ADAPTER_CPP_INCLUDE_DIR}) - -project (test) +# Allow better viewing and grouping of files in Visual Studio by defining source groups +source_group("Headers Files" FILES ${headers}) +source_group("Headers Files\\adapter" FILES ${adapter_headers}) +source_group("Headers Files\\YAML" FILES ${yaml_headers}) +source_group("Source Files" FILES ${test_sources}) +source_group("Source Files\\adapter" FILES ${adapter_sources}) +source_group("Source Files\\YAML" FILES ${yaml_sources}) + + +add_executable(test + ${yaml_sources} + ${yaml_headers} + ${adapter_sources} + ${adapter_headers} + ${test_sources} + ${headers} + ) + +target_include_directories(test + PRIVATE ${YAML_CPP_SOURCE_DIR} + PRIVATE ${YAML_CPP_INCLUDE_DIR} + PRIVATE ${ADAPTER_CPP_INCLUDE_DIR} + ) + +target_link_libraries(test + PRIVATE ${LINUX_LIBRARIES} + ) -find_package(CppUnit REQUIRED) - -add_definitions() -include_directories(${CPPUNIT_INCLUDE_DIR}) +if(WIN32) + target_link_libraries(test + PRIVATE wsock32.lib + ) +endif() -add_executable(test ${yaml_sources} ${adapter_sources} ${test_sources}) -target_link_libraries(test ${CPPUNIT_LIBRARY} ${LINUX_LIBRARIES}) +AddMsvcXPSupport(fanuc) #This will only apply if an XP compatible toolset has been selected in CMake +AddCppUnitSupport(test) diff --git a/test/condition_test.cpp b/test/condition_test.cpp index 28f973b..7fdf29d 100644 --- a/test/condition_test.cpp +++ b/test/condition_test.cpp @@ -1,147 +1,147 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - -#include "condition_test.hpp" -#include "string_buffer.hpp" -#include - -using namespace std; - -CPPUNIT_TEST_SUITE_REGISTRATION(ConditionTest); - -void ConditionTest::setUp() -{ -} - -void ConditionTest::tearDown() -{ -} - -void ConditionTest::testInitial() -{ - Condition cond("Test"); - StringBuffer buffer; - - CPPUNIT_ASSERT_EQUAL(string("Test"), string(cond.getName())); - - CPPUNIT_ASSERT(cond.changed()); - CPPUNIT_ASSERT(cond.hasInitialValue()); - CPPUNIT_ASSERT(cond.requiresFlush()); - - cond.append(buffer); +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include "condition_test.hpp" +#include "string_buffer.hpp" +#include + +using namespace std; + +CPPUNIT_TEST_SUITE_REGISTRATION(ConditionTest); + +void ConditionTest::setUp() +{ +} + +void ConditionTest::tearDown() +{ +} + +void ConditionTest::testInitial() +{ + Condition cond("Test"); + StringBuffer buffer; + + CPPUNIT_ASSERT_EQUAL(string("Test"), string(cond.getName())); + + CPPUNIT_ASSERT(cond.changed()); + CPPUNIT_ASSERT(cond.hasInitialValue()); + CPPUNIT_ASSERT(cond.requiresFlush()); + + cond.append(buffer); CPPUNIT_ASSERT_EQUAL(string("|Test|UNAVAILABLE||||"), string((const char*) buffer)); -} - -void ConditionTest::testInitialNormal() -{ - Condition cond("Test"); - StringBuffer buffer; - - CPPUNIT_ASSERT(cond.normal()); - - cond.append(buffer); +} + +void ConditionTest::testInitialNormal() +{ + Condition cond("Test"); + StringBuffer buffer; + + CPPUNIT_ASSERT(cond.normal()); + + cond.append(buffer); CPPUNIT_ASSERT_EQUAL(string("|Test|NORMAL||||"), string((const char*) buffer)); -} - -void ConditionTest::testAdd() -{ - Condition cond("Test"); - StringBuffer buffer; - - cond.begin(); - CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); - CPPUNIT_ASSERT(cond.append(buffer)); +} + +void ConditionTest::testAdd() +{ + Condition cond("Test"); + StringBuffer buffer; + + cond.begin(); + CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); + CPPUNIT_ASSERT(cond.append(buffer)); CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|123|1|HIGH|A Fault"), string((const char*) buffer)); - cond.cleanup(); -} - -void ConditionTest::testActive() -{ - Condition cond("Test"); - StringBuffer buffer; - - cond.begin(); - CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); - CPPUNIT_ASSERT(cond.append(buffer)); + cond.cleanup(); +} + +void ConditionTest::testActive() +{ + Condition cond("Test"); + StringBuffer buffer; + + cond.begin(); + CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); + CPPUNIT_ASSERT(cond.append(buffer)); CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|123|1|HIGH|A Fault"), string((const char*) buffer)); - - CPPUNIT_ASSERT(cond.isActive("123")); - CPPUNIT_ASSERT(!cond.isActive("1234")); - cond.cleanup(); -} - -void ConditionTest::testCleanup() -{ - Condition cond("Test"); - StringBuffer buffer; - - cond.begin(); - CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); - CPPUNIT_ASSERT(cond.append(buffer)); + + CPPUNIT_ASSERT(cond.isActive("123")); + CPPUNIT_ASSERT(!cond.isActive("1234")); + cond.cleanup(); +} + +void ConditionTest::testCleanup() +{ + Condition cond("Test"); + StringBuffer buffer; + + cond.begin(); + CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); + CPPUNIT_ASSERT(cond.append(buffer)); CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|123|1|HIGH|A Fault"), string((const char*) buffer)); - cond.cleanup(); - - buffer.reset(); - - cond.begin(); - cond.append(buffer); + cond.cleanup(); + + buffer.reset(); + + cond.begin(); + cond.append(buffer); CPPUNIT_ASSERT_EQUAL(string("|Test|NORMAL||||"), string((const char*) buffer)); - cond.cleanup(); - - buffer.reset(); - - cond.begin(); - CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); - CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "Another Fault", "124", "HIGH", "1")); - CPPUNIT_ASSERT(cond.append(buffer)); - CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|124|1|HIGH|Another Fault\n" - "|Test|FAULT|123|1|HIGH|A Fault"), + cond.cleanup(); + + buffer.reset(); + + cond.begin(); + CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); + CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "Another Fault", "124", "HIGH", "1")); + CPPUNIT_ASSERT(cond.append(buffer)); + CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|124|1|HIGH|Another Fault\n" + "|Test|FAULT|123|1|HIGH|A Fault"), string((const char*) buffer)); - - CPPUNIT_ASSERT(cond.isActive("123")); - CPPUNIT_ASSERT(cond.isActive("124")); - cond.cleanup(); - - buffer.reset(); - - cond.begin(); - CPPUNIT_ASSERT(!cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); + + CPPUNIT_ASSERT(cond.isActive("123")); + CPPUNIT_ASSERT(cond.isActive("124")); + cond.cleanup(); + + buffer.reset(); + + cond.begin(); + CPPUNIT_ASSERT(!cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); - cond.append(buffer); + cond.append(buffer); CPPUNIT_ASSERT_EQUAL(string("|Test|NORMAL|124|||"), string((const char*) buffer)); - cond.cleanup(); - - CPPUNIT_ASSERT(cond.isActive("123")); - CPPUNIT_ASSERT(!cond.isActive("124")); -} - + cond.cleanup(); + + CPPUNIT_ASSERT(cond.isActive("123")); + CPPUNIT_ASSERT(!cond.isActive("124")); +} + diff --git a/test/condition_test.hpp b/test/condition_test.hpp index 01700df..368c0af 100644 --- a/test/condition_test.hpp +++ b/test/condition_test.hpp @@ -1,65 +1,65 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ #ifndef CONDITION_TEST_HPP #define CONDITION_TEST_HPP - -#include -#include - -#include "condition.hpp" - -class ConditionTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(ConditionTest); - CPPUNIT_TEST(testInitial); - CPPUNIT_TEST(testInitialNormal); - CPPUNIT_TEST(testAdd); - CPPUNIT_TEST(testActive); - CPPUNIT_TEST(testCleanup); - CPPUNIT_TEST_SUITE_END(); - -protected: - void testInitial(); - void testInitialNormal(); - void testAdd(); - void testActive(); - void testCleanup(); - -public: - void setUp(); - void tearDown(); -}; - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include +#include + +#include "condition.hpp" + +class ConditionTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(ConditionTest); + CPPUNIT_TEST(testInitial); + CPPUNIT_TEST(testInitialNormal); + CPPUNIT_TEST(testAdd); + CPPUNIT_TEST(testActive); + CPPUNIT_TEST(testCleanup); + CPPUNIT_TEST_SUITE_END(); + +protected: + void testInitial(); + void testInitialNormal(); + void testAdd(); + void testActive(); + void testCleanup(); + +public: + void setUp(); + void tearDown(); +}; + #endif diff --git a/test/configuration_test.cpp b/test/configuration_test.cpp index 288225a..95a1d96 100644 --- a/test/configuration_test.cpp +++ b/test/configuration_test.cpp @@ -1,64 +1,64 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - -#include "configuration_test.hpp" -#include -#include - -using namespace std; - -CPPUNIT_TEST_SUITE_REGISTRATION(ConfigurationTest); - -void ConfigurationTest::setUp() -{ -} - -void ConfigurationTest::tearDown() -{ -} - -void ConfigurationTest::testConstructor() -{ - string config = - "adapter:\n" - " port: 7878\n" - " scanDelay: 100\n" - " timeout: 10000\n"; - - istringstream str(config); +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include "configuration_test.hpp" +#include +#include + +using namespace std; + +CPPUNIT_TEST_SUITE_REGISTRATION(ConfigurationTest); + +void ConfigurationTest::setUp() +{ +} + +void ConfigurationTest::tearDown() +{ +} + +void ConfigurationTest::testConstructor() +{ + string config = + "adapter:\n" + " port: 7878\n" + " scanDelay: 100\n" + " timeout: 10000\n"; + + istringstream str(config); Configuration cfg(str); - - CPPUNIT_ASSERT_EQUAL(cfg.getPort(), 7878); - CPPUNIT_ASSERT_EQUAL(cfg.getScanDelay(), 100); - CPPUNIT_ASSERT_EQUAL(cfg.getTimeout(), 10000); -} + + CPPUNIT_ASSERT_EQUAL(cfg.getPort(), 7878); + CPPUNIT_ASSERT_EQUAL(cfg.getScanDelay(), 100); + CPPUNIT_ASSERT_EQUAL(cfg.getTimeout(), 10000); +} diff --git a/test/configuration_test.hpp b/test/configuration_test.hpp index 751db6b..b7a11a8 100644 --- a/test/configuration_test.hpp +++ b/test/configuration_test.hpp @@ -1,57 +1,57 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ #ifndef CONFIGURATION_TEST_HPP #define CONFIGURATION_TEST_HPP - -#include -#include - -#include "configuration.hpp" - -class ConfigurationTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(ConfigurationTest); - CPPUNIT_TEST(testConstructor); - CPPUNIT_TEST_SUITE_END(); - -protected: - void testConstructor(); - -public: - void setUp(); - void tearDown(); -}; - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include +#include + +#include "configuration.hpp" + +class ConfigurationTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(ConfigurationTest); + CPPUNIT_TEST(testConstructor); + CPPUNIT_TEST_SUITE_END(); + +protected: + void testConstructor(); + +public: + void setUp(); + void tearDown(); +}; + #endif diff --git a/test/device_datum_test.cpp b/test/device_datum_test.cpp index e46ec3f..014cade 100644 --- a/test/device_datum_test.cpp +++ b/test/device_datum_test.cpp @@ -1,123 +1,123 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - -#include "device_datum_test.hpp" -#include - -using namespace std; - -CPPUNIT_TEST_SUITE_REGISTRATION(DeviceDatumTest); - -void DeviceDatumTest::setUp() -{ -} - -void DeviceDatumTest::tearDown() -{ -} - -void DeviceDatumTest::testEvent() -{ - Event event("Test"); - char buffer[256]; - - CPPUNIT_ASSERT_EQUAL(string("Test"), string(event.getName())); - - CPPUNIT_ASSERT(!event.changed()); - CPPUNIT_ASSERT(!event.hasInitialValue()); - CPPUNIT_ASSERT_EQUAL(string(""), string(event.getValue())); - - event.unavailable(); - CPPUNIT_ASSERT(event.changed()); - CPPUNIT_ASSERT(event.hasInitialValue()); - - CPPUNIT_ASSERT(event.toString(buffer, 255) != 0); - CPPUNIT_ASSERT_EQUAL(string("|Test|UNAVAILABLE"), string(buffer)); - - event.reset(); - CPPUNIT_ASSERT(!event.changed()); - CPPUNIT_ASSERT(event.hasInitialValue()); - - CPPUNIT_ASSERT(event.setValue("Hello")); - CPPUNIT_ASSERT(event.changed()); - CPPUNIT_ASSERT(event.toString(buffer, 255) != 0); - CPPUNIT_ASSERT_EQUAL(string("|Test|Hello"), string(buffer)); - CPPUNIT_ASSERT_EQUAL(string("Hello"), string(event.getValue())); - - event.reset(); - CPPUNIT_ASSERT(!event.changed()); - - CPPUNIT_ASSERT(!event.setValue("Hello")); -} - -void DeviceDatumTest::testSample() -{ - Sample sample("Test"); - char buffer[256]; - - CPPUNIT_ASSERT_EQUAL(0, strcmp(sample.getName(), "Test")); - - CPPUNIT_ASSERT(!sample.changed()); - CPPUNIT_ASSERT(!sample.hasInitialValue()); - CPPUNIT_ASSERT_EQUAL(0.0, sample.getValue()); - - sample.unavailable(); - CPPUNIT_ASSERT(sample.changed()); - CPPUNIT_ASSERT(sample.hasInitialValue()); - - CPPUNIT_ASSERT(sample.toString(buffer, 255) != 0); - CPPUNIT_ASSERT_EQUAL(string("|Test|UNAVAILABLE"), string(buffer)); - - CPPUNIT_ASSERT(sample.setValue(1.234567)); - CPPUNIT_ASSERT(sample.changed()); - CPPUNIT_ASSERT(sample.hasInitialValue()); - - CPPUNIT_ASSERT(sample.toString(buffer, 255) != 0); - CPPUNIT_ASSERT_EQUAL(string("|Test|1.234567"), string(buffer)); - - CPPUNIT_ASSERT(sample.setValue(1.234568)); - CPPUNIT_ASSERT(sample.changed()); - CPPUNIT_ASSERT(sample.hasInitialValue()); - - CPPUNIT_ASSERT(sample.toString(buffer, 255) != 0); - CPPUNIT_ASSERT_EQUAL(string("|Test|1.234568"), string(buffer)); - - sample.reset(); - - // Check epsilon change does not change value. - CPPUNIT_ASSERT(!sample.setValue(1.2345681)); - CPPUNIT_ASSERT(!sample.changed()); - - CPPUNIT_ASSERT(sample.toString(buffer, 255) != 0); - CPPUNIT_ASSERT_EQUAL(string("|Test|1.234568"), string(buffer)); -} +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include "device_datum_test.hpp" +#include + +using namespace std; + +CPPUNIT_TEST_SUITE_REGISTRATION(DeviceDatumTest); + +void DeviceDatumTest::setUp() +{ +} + +void DeviceDatumTest::tearDown() +{ +} + +void DeviceDatumTest::testEvent() +{ + Event event("Test"); + char buffer[256]; + + CPPUNIT_ASSERT_EQUAL(string("Test"), string(event.getName())); + + CPPUNIT_ASSERT(!event.changed()); + CPPUNIT_ASSERT(!event.hasInitialValue()); + CPPUNIT_ASSERT_EQUAL(string(""), string(event.getValue())); + + event.unavailable(); + CPPUNIT_ASSERT(event.changed()); + CPPUNIT_ASSERT(event.hasInitialValue()); + + CPPUNIT_ASSERT(event.toString(buffer, 255) != 0); + CPPUNIT_ASSERT_EQUAL(string("|Test|UNAVAILABLE"), string(buffer)); + + event.reset(); + CPPUNIT_ASSERT(!event.changed()); + CPPUNIT_ASSERT(event.hasInitialValue()); + + CPPUNIT_ASSERT(event.setValue("Hello")); + CPPUNIT_ASSERT(event.changed()); + CPPUNIT_ASSERT(event.toString(buffer, 255) != 0); + CPPUNIT_ASSERT_EQUAL(string("|Test|Hello"), string(buffer)); + CPPUNIT_ASSERT_EQUAL(string("Hello"), string(event.getValue())); + + event.reset(); + CPPUNIT_ASSERT(!event.changed()); + + CPPUNIT_ASSERT(!event.setValue("Hello")); +} + +void DeviceDatumTest::testSample() +{ + Sample sample("Test"); + char buffer[256]; + + CPPUNIT_ASSERT_EQUAL(0, strcmp(sample.getName(), "Test")); + + CPPUNIT_ASSERT(!sample.changed()); + CPPUNIT_ASSERT(!sample.hasInitialValue()); + CPPUNIT_ASSERT_EQUAL(0.0, sample.getValue()); + + sample.unavailable(); + CPPUNIT_ASSERT(sample.changed()); + CPPUNIT_ASSERT(sample.hasInitialValue()); + + CPPUNIT_ASSERT(sample.toString(buffer, 255) != 0); + CPPUNIT_ASSERT_EQUAL(string("|Test|UNAVAILABLE"), string(buffer)); + + CPPUNIT_ASSERT(sample.setValue(1.234567)); + CPPUNIT_ASSERT(sample.changed()); + CPPUNIT_ASSERT(sample.hasInitialValue()); + + CPPUNIT_ASSERT(sample.toString(buffer, 255) != 0); + CPPUNIT_ASSERT_EQUAL(string("|Test|1.234567"), string(buffer)); + + CPPUNIT_ASSERT(sample.setValue(1.234568)); + CPPUNIT_ASSERT(sample.changed()); + CPPUNIT_ASSERT(sample.hasInitialValue()); + + CPPUNIT_ASSERT(sample.toString(buffer, 255) != 0); + CPPUNIT_ASSERT_EQUAL(string("|Test|1.234568"), string(buffer)); + + sample.reset(); + + // Check epsilon change does not change value. + CPPUNIT_ASSERT(!sample.setValue(1.2345681)); + CPPUNIT_ASSERT(!sample.changed()); + + CPPUNIT_ASSERT(sample.toString(buffer, 255) != 0); + CPPUNIT_ASSERT_EQUAL(string("|Test|1.234568"), string(buffer)); +} diff --git a/test/device_datum_test.hpp b/test/device_datum_test.hpp index d095074..2a9df8f 100644 --- a/test/device_datum_test.hpp +++ b/test/device_datum_test.hpp @@ -1,59 +1,59 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ #ifndef DEVICE_DATUM_TEST_HPP #define DEVICE_DATUM_TEST_HPP - -#include -#include - -#include "device_datum.hpp" - -class DeviceDatumTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(DeviceDatumTest); - CPPUNIT_TEST(testEvent); - CPPUNIT_TEST(testSample); - CPPUNIT_TEST_SUITE_END(); - -protected: - void testEvent(); - void testSample(); - -public: - void setUp(); - void tearDown(); -}; - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include +#include + +#include "device_datum.hpp" + +class DeviceDatumTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(DeviceDatumTest); + CPPUNIT_TEST(testEvent); + CPPUNIT_TEST(testSample); + CPPUNIT_TEST_SUITE_END(); + +protected: + void testEvent(); + void testSample(); + +public: + void setUp(); + void tearDown(); +}; + #endif diff --git a/test/test.cpp b/test/test.cpp index 9c3d346..79d331a 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,35 +1,66 @@ - - -#include -#include -#include -#include -#include -#include - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include +#include +#include +#include +#include +#include + int main (int argc, char* argv[]) -{ - // informs test-listener about testresults - CPPUNIT_NS :: TestResult testresult; - - // register listener for collecting the test-results - CPPUNIT_NS :: TestResultCollector collectedresults; +{ + // informs test-listener about testresults + CPPUNIT_NS :: TestResult testresult; + + // register listener for collecting the test-results + CPPUNIT_NS :: TestResultCollector collectedresults; testresult.addListener (&collectedresults); - - // register listener for per-test progress output - CPPUNIT_NS :: BriefTestProgressListener progress; + + // register listener for per-test progress output + CPPUNIT_NS :: BriefTestProgressListener progress; testresult.addListener (&progress); - - // insert test-suite at test-runner by registry - CPPUNIT_NS :: TestRunner testrunner; + + // insert test-suite at test-runner by registry + CPPUNIT_NS :: TestRunner testrunner; testrunner.addTest (CPPUNIT_NS :: TestFactoryRegistry :: getRegistry ().makeTest ()); testrunner.run (testresult); - - // output results in compiler-format + + // output results in compiler-format CPPUNIT_NS :: CompilerOutputter compileroutputter (&collectedresults, std::cerr); compileroutputter.write (); - - // return 0 if tests were successful + + // return 0 if tests were successful return collectedresults.wasSuccessful () ? 0 : 1; -} - +} + diff --git a/test/time_series_test.cpp b/test/time_series_test.cpp index ee9cef7..ac8900a 100644 --- a/test/time_series_test.cpp +++ b/test/time_series_test.cpp @@ -1,78 +1,77 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ - -#include "time_series_test.hpp" -#include "string_buffer.hpp" -#include - -using namespace std; - -CPPUNIT_TEST_SUITE_REGISTRATION(TimeSeriesTest); - -void TimeSeriesTest::setUp() -{ -} - -void TimeSeriesTest::tearDown() -{ -} - -void TimeSeriesTest::testTimeSeries() -{ - StringBuffer buffer; - TimeSeries series("test"); - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// +#include "time_series_test.hpp" +#include "string_buffer.hpp" +#include + +using namespace std; + +CPPUNIT_TEST_SUITE_REGISTRATION(TimeSeriesTest); + +void TimeSeriesTest::setUp() +{ +} + +void TimeSeriesTest::tearDown() +{ +} + +void TimeSeriesTest::testTimeSeries() +{ + StringBuffer buffer; + TimeSeries series("test"); + for (int i = 0; i < 5; i++) series.addValue((double) i); - - series.append(buffer); + + series.append(buffer); CPPUNIT_ASSERT_EQUAL(string("|test|5||0 1 2 3 4 "), string((const char*) buffer)); - - series.clear(); - buffer.reset(); - - series.append(buffer); + + series.clear(); + buffer.reset(); + + series.append(buffer); CPPUNIT_ASSERT_EQUAL(string("|test|0||"), string((const char*) buffer)); - - buffer.reset(); - + + buffer.reset(); + series.addValue(2.0); series.addValue(4.0); - series.setRate(42000); - - series.append(buffer); + series.setRate(42000); + + series.append(buffer); CPPUNIT_ASSERT_EQUAL(string("|test|2|42000|2 4 "), string((const char*) buffer)); -} +} diff --git a/test/time_series_test.hpp b/test/time_series_test.hpp index eeb8fb8..ac05d65 100644 --- a/test/time_series_test.hpp +++ b/test/time_series_test.hpp @@ -1,56 +1,56 @@ -/* -* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the AMT nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED -* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" -* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR -* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS -* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR -* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT -* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, -* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - -* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT -* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS -* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, -* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, -* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF -* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT -* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -*/ #ifndef DEVICE_DATUM_TEST_HPP #define DEVICE_DATUM_TEST_HPP - -#include -#include - -#include "time_series.hpp" - -class TimeSeriesTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(TimeSeriesTest); - CPPUNIT_TEST(testTimeSeries); - CPPUNIT_TEST_SUITE_END(); - -protected: - void testTimeSeries(); - +// +// Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the AMT nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED +// BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS" +// AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR +// RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS +// (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR +// WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT +// LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT +// PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS +// OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL, +// CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES, +// WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF +// THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT +// SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. +// + +#include +#include + +#include "time_series.hpp" + +class TimeSeriesTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(TimeSeriesTest); + CPPUNIT_TEST(testTimeSeries); + CPPUNIT_TEST_SUITE_END(); + +protected: + void testTimeSeries(); + public: - void setUp(); - void tearDown(); -}; - + void setUp(); + void tearDown(); +}; + #endif From 2551716b59b00b0370c8ba3ad396a6d5cacf29de Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:12:58 +0100 Subject: [PATCH 03/41] C++11 Conversion: Updated to use "#pragma once" include guard --- fake/fake_adapter.hpp | 3 +-- fanuc/fanuc_adapter.hpp | 6 +----- fanuc/fanuc_axis.hpp | 2 ++ fanuc/fanuc_path.hpp | 1 + src/adapter.hpp | 6 +----- src/axis.hpp | 5 +---- src/client.hpp | 4 +--- src/component.hpp | 4 +--- src/condition.hpp | 5 +---- src/configuration.hpp | 5 +---- src/cutting_tool.hpp | 7 +------ src/device_datum.hpp | 5 +---- src/internal.hpp | 5 +---- src/logger.hpp | 6 +----- src/serial.hpp | 6 +----- src/server.hpp | 6 +----- src/service.hpp | 4 +--- src/string_array.hpp | 9 +-------- src/string_buffer.hpp | 5 +---- src/threading.hpp | 6 +----- src/time_series.hpp | 5 +---- test/condition_test.hpp | 6 +----- test/configuration_test.hpp | 6 +----- test/device_datum_test.hpp | 6 +----- test/time_series_test.hpp | 5 +---- 25 files changed, 26 insertions(+), 102 deletions(-) diff --git a/fake/fake_adapter.hpp b/fake/fake_adapter.hpp index 58d4f83..e4f018b 100644 --- a/fake/fake_adapter.hpp +++ b/fake/fake_adapter.hpp @@ -30,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include "adapter.hpp" #include "device_datum.hpp" @@ -57,5 +58,3 @@ class FakeAdapter : public Adapter, public MTConnectService virtual void gatherDeviceData(); }; -#endif - diff --git a/fanuc/fanuc_adapter.hpp b/fanuc/fanuc_adapter.hpp index 65e3135..be279a3 100644 --- a/fanuc/fanuc_adapter.hpp +++ b/fanuc/fanuc_adapter.hpp @@ -1,6 +1,3 @@ - -#ifndef FANUC_ADAPTER_HPP -#define FANUC_ADAPTER_HPP #include "adapter.hpp" #include "condition.hpp" @@ -23,6 +20,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // +#pragma once #include #define MAX_MACROS 32 @@ -122,5 +120,3 @@ class FanucAdapter : public Adapter, public MTConnectService virtual void gatherDeviceData(); }; - -#endif diff --git a/fanuc/fanuc_axis.hpp b/fanuc/fanuc_axis.hpp index 0842805..e673ff6 100644 --- a/fanuc/fanuc_axis.hpp +++ b/fanuc/fanuc_axis.hpp @@ -18,6 +18,8 @@ // See the License for the specific language governing permissions and // limitations under the License. // +#pragma once + #include #include "Fwlib32.h" diff --git a/fanuc/fanuc_path.hpp b/fanuc/fanuc_path.hpp index 6753fba..ab98450 100644 --- a/fanuc/fanuc_path.hpp +++ b/fanuc/fanuc_path.hpp @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // +#pragma once #include "device_datum.hpp" #include "condition.hpp" diff --git a/src/adapter.hpp b/src/adapter.hpp index 456a1f1..4c13818 100644 --- a/src/adapter.hpp +++ b/src/adapter.hpp @@ -1,6 +1,3 @@ - -#ifndef ADAPTER_HPP -#define ADAPTER_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include "server.hpp" #include "string_buffer.hpp" #include "threading.hpp" @@ -158,5 +156,3 @@ class AutoGather { protected: Adapter *mAdapter; }; - -#endif diff --git a/src/axis.hpp b/src/axis.hpp index 21934b5..d3b3db1 100644 --- a/src/axis.hpp +++ b/src/axis.hpp @@ -1,6 +1,3 @@ - -#ifndef AXIS_HPP -#define AXIS_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include "component.hpp" #include "device_datum.hpp" @@ -89,4 +87,3 @@ class Linear : public Axis Linear(Adapter *anAdapter, std::string aName, Component *aParent = NULL); }; -#endif // AXIS_HPP diff --git a/src/client.hpp b/src/client.hpp index 3626af0..4f8be40 100755 --- a/src/client.hpp +++ b/src/client.hpp @@ -30,10 +30,9 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once -#ifndef CLIENT_HPP -#define CLIENT_HPP #include "threading.hpp" /* @@ -61,4 +60,3 @@ class Client SOCKET socket() { return mSocket; } }; -#endif diff --git a/src/component.hpp b/src/component.hpp index 30c7a6d..38067d1 100644 --- a/src/component.hpp +++ b/src/component.hpp @@ -1,5 +1,3 @@ -#ifndef COMPONENT_HPP -#define COMPONENT_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -32,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include "internal.hpp" #include @@ -56,5 +55,4 @@ class Component virtual void gatherData(void *aContext) = 0; }; -#endif // COMPONENT_HPP diff --git a/src/condition.hpp b/src/condition.hpp index db59ab8..8f1b6c8 100644 --- a/src/condition.hpp +++ b/src/condition.hpp @@ -1,6 +1,3 @@ - -#ifndef CONDITION_LIST -#define CONDITION_LIST // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once // The conditon items #include "device_datum.hpp" @@ -132,4 +130,3 @@ class Condition : public DeviceDatum virtual void initialize(); }; -#endif diff --git a/src/configuration.hpp b/src/configuration.hpp index d32b2a1..05c18e6 100644 --- a/src/configuration.hpp +++ b/src/configuration.hpp @@ -1,6 +1,3 @@ - -#ifndef CONFIGURATION_HPP -#define CONFIGURATION_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include #include #include @@ -140,4 +138,3 @@ class Configuration std::map mRegisters; }; -#endif diff --git a/src/cutting_tool.hpp b/src/cutting_tool.hpp index 82d1f4f..904c347 100644 --- a/src/cutting_tool.hpp +++ b/src/cutting_tool.hpp @@ -1,7 +1,3 @@ - -#ifndef CUTTING_TOOL_HPP -#define CUTTING_TOOL_HPP - // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -34,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include #include #include @@ -120,5 +117,3 @@ class CuttingTool { int mToolNumber; std::string mDescription; }; - -#endif \ No newline at end of file diff --git a/src/device_datum.hpp b/src/device_datum.hpp index 7442e25..5ee291f 100644 --- a/src/device_datum.hpp +++ b/src/device_datum.hpp @@ -1,7 +1,4 @@ -#ifndef DEVICE_DATUM_HPP -#define DEVICE_DATUM_HPP - /* Forward class definitions */ // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") @@ -35,6 +32,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once class StringBuffer; /* Some constants for field lengths */ @@ -407,4 +405,3 @@ class Availability : public DeviceDatum virtual bool unavailable(); }; -#endif diff --git a/src/internal.hpp b/src/internal.hpp index c7fbbb7..d94da9d 100755 --- a/src/internal.hpp +++ b/src/internal.hpp @@ -1,5 +1,3 @@ -#ifndef MTC_INTERNAL_HPP -#define MTC_INTERNAL_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -32,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #ifdef WIN32 #define _CRT_SECURE_NO_DEPRECATE 1 @@ -91,5 +90,3 @@ typedef struct sockaddr SOCKADDR; #include #include #include - -#endif diff --git a/src/logger.hpp b/src/logger.hpp index 69cad9e..313030c 100644 --- a/src/logger.hpp +++ b/src/logger.hpp @@ -1,6 +1,3 @@ - -#ifndef LOGGER_HPP -#define LOGGER_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include #include @@ -66,5 +64,3 @@ class Logger { }; extern Logger *gLogger; - -#endif diff --git a/src/serial.hpp b/src/serial.hpp index 687a787..6f23335 100644 --- a/src/serial.hpp +++ b/src/serial.hpp @@ -1,7 +1,4 @@ -#ifndef SERIAL_HPP -#define SERIAL_HPP - class Serial { // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") @@ -35,6 +32,7 @@ class Serial { // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once public: class SerialError { @@ -147,5 +145,3 @@ class Serial { bool flush(); bool printCommStatus(); }; - -#endif diff --git a/src/server.hpp b/src/server.hpp index 77e98e1..7ad2da5 100755 --- a/src/server.hpp +++ b/src/server.hpp @@ -1,6 +1,3 @@ - -#ifndef SERVER_HPP -#define SERVER_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include "threading.hpp" @@ -83,5 +81,3 @@ class Server bool hasClients() { return mNumClients > 0; } }; - -#endif diff --git a/src/service.hpp b/src/service.hpp index f2cdbea..d1f97c1 100644 --- a/src/service.hpp +++ b/src/service.hpp @@ -1,5 +1,3 @@ -#ifndef SERVICE_HPP -#define SERVICE_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -32,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include "logger.hpp" @@ -69,5 +68,4 @@ class ServiceLogger : public Logger { }; #else class ServiceLogger : public Logger {}; -#endif #endif diff --git a/src/string_array.hpp b/src/string_array.hpp index 307704b..4afe5bb 100755 --- a/src/string_array.hpp +++ b/src/string_array.hpp @@ -30,11 +30,9 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once -#ifndef STRING_ARRAY_HPP -#define STRING_ARRAY_HPP - /* * A string array that atomaticially resizes when the size is * exceeded. Used for storing the program codes @@ -73,8 +71,3 @@ inline const char *StringArray::stringAt(int index) else return 0; } - -#endif - - - diff --git a/src/string_buffer.hpp b/src/string_buffer.hpp index 84fd47e..f4306f8 100755 --- a/src/string_buffer.hpp +++ b/src/string_buffer.hpp @@ -30,9 +30,8 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once -#ifndef STRING_BUFFER_HPP -#define STRING_BUFFER_HPP /* * A simple extensible string that can be appended to. The memory will be reused @@ -62,5 +61,3 @@ class StringBuffer size_t length() { return mLength; } void newline(); }; - -#endif diff --git a/src/threading.hpp b/src/threading.hpp index cefb805..f908cc9 100644 --- a/src/threading.hpp +++ b/src/threading.hpp @@ -1,6 +1,3 @@ - -#ifndef THREADING_HPP -#define THREADING_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #ifdef THREADED @@ -115,5 +113,3 @@ class MTCAutoLock { private: MTCAutoLock() : mMutex(NULL) {} }; - -#endif \ No newline at end of file diff --git a/src/time_series.hpp b/src/time_series.hpp index 7b0f162..a8395dc 100644 --- a/src/time_series.hpp +++ b/src/time_series.hpp @@ -1,6 +1,3 @@ - -#ifndef TIME_SERIES_HPP -#define TIME_SERIES_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include "device_datum.hpp" #include @@ -68,4 +66,3 @@ class TimeSeries : public DeviceDatum }; -#endif diff --git a/test/condition_test.hpp b/test/condition_test.hpp index 368c0af..51f8eff 100644 --- a/test/condition_test.hpp +++ b/test/condition_test.hpp @@ -1,6 +1,3 @@ - -#ifndef CONDITION_TEST_HPP -#define CONDITION_TEST_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include #include @@ -61,5 +59,3 @@ class ConditionTest : public CppUnit::TestFixture void tearDown(); }; -#endif - diff --git a/test/configuration_test.hpp b/test/configuration_test.hpp index b7a11a8..61f5ab1 100644 --- a/test/configuration_test.hpp +++ b/test/configuration_test.hpp @@ -1,6 +1,3 @@ - -#ifndef CONFIGURATION_TEST_HPP -#define CONFIGURATION_TEST_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include #include @@ -53,5 +51,3 @@ class ConfigurationTest : public CppUnit::TestFixture void tearDown(); }; -#endif - diff --git a/test/device_datum_test.hpp b/test/device_datum_test.hpp index 2a9df8f..3ef45a0 100644 --- a/test/device_datum_test.hpp +++ b/test/device_datum_test.hpp @@ -1,6 +1,3 @@ - -#ifndef DEVICE_DATUM_TEST_HPP -#define DEVICE_DATUM_TEST_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include #include @@ -55,5 +53,3 @@ class DeviceDatumTest : public CppUnit::TestFixture void tearDown(); }; -#endif - diff --git a/test/time_series_test.hpp b/test/time_series_test.hpp index ac05d65..8ddb0fb 100644 --- a/test/time_series_test.hpp +++ b/test/time_series_test.hpp @@ -1,6 +1,3 @@ - -#ifndef DEVICE_DATUM_TEST_HPP -#define DEVICE_DATUM_TEST_HPP // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +30,7 @@ // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // +#pragma once #include #include @@ -53,4 +51,3 @@ class TimeSeriesTest : public CppUnit::TestFixture void tearDown(); }; -#endif From bff63245ff73f0dfc7707c1f28de2c3da122dabf Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:13:10 +0100 Subject: [PATCH 04/41] BUG FIX: Fixed broken CppUnit tests for Condition data item --- test/condition_test.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/condition_test.cpp b/test/condition_test.cpp index 7fdf29d..8400b93 100644 --- a/test/condition_test.cpp +++ b/test/condition_test.cpp @@ -80,6 +80,7 @@ void ConditionTest::testAdd() cond.begin(); CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); + cond.prepare(); CPPUNIT_ASSERT(cond.append(buffer)); CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|123|1|HIGH|A Fault"), string((const char*) buffer)); cond.cleanup(); @@ -92,6 +93,7 @@ void ConditionTest::testActive() cond.begin(); CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); + cond.prepare(); CPPUNIT_ASSERT(cond.append(buffer)); CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|123|1|HIGH|A Fault"), string((const char*) buffer)); @@ -107,6 +109,7 @@ void ConditionTest::testCleanup() cond.begin(); CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); + cond.prepare(); CPPUNIT_ASSERT(cond.append(buffer)); CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|123|1|HIGH|A Fault"), string((const char*) buffer)); cond.cleanup(); @@ -114,6 +117,7 @@ void ConditionTest::testCleanup() buffer.reset(); cond.begin(); + cond.prepare(); cond.append(buffer); CPPUNIT_ASSERT_EQUAL(string("|Test|NORMAL||||"), string((const char*) buffer)); cond.cleanup(); @@ -123,6 +127,7 @@ void ConditionTest::testCleanup() cond.begin(); CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "Another Fault", "124", "HIGH", "1")); + cond.prepare(); CPPUNIT_ASSERT(cond.append(buffer)); CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|124|1|HIGH|Another Fault\n" "|Test|FAULT|123|1|HIGH|A Fault"), @@ -137,6 +142,7 @@ void ConditionTest::testCleanup() cond.begin(); CPPUNIT_ASSERT(!cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); + cond.prepare(); cond.append(buffer); CPPUNIT_ASSERT_EQUAL(string("|Test|NORMAL|124|||"), string((const char*) buffer)); cond.cleanup(); From bd073f491b3f3e5afe04f8370d742839d6a59369 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:13:18 +0100 Subject: [PATCH 05/41] BUG FIX: Fixed compile error for 'test' project --- test/configuration_test.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/configuration_test.cpp b/test/configuration_test.cpp index 95a1d96..44ebdfd 100644 --- a/test/configuration_test.cpp +++ b/test/configuration_test.cpp @@ -39,14 +39,17 @@ using namespace std; CPPUNIT_TEST_SUITE_REGISTRATION(ConfigurationTest); + void ConfigurationTest::setUp() { } + void ConfigurationTest::tearDown() { } + void ConfigurationTest::testConstructor() { string config = @@ -56,7 +59,8 @@ void ConfigurationTest::testConstructor() " timeout: 10000\n"; istringstream str(config); - Configuration cfg(str); + Configuration cfg; + cfg.parse(str); CPPUNIT_ASSERT_EQUAL(cfg.getPort(), 7878); CPPUNIT_ASSERT_EQUAL(cfg.getScanDelay(), 100); From 9711ae5a79ae83982a874813f50e9e653cc2339e Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:13:27 +0100 Subject: [PATCH 06/41] C++11 Conversion: Added missing header file includes for 'test' project --- test/condition_test.hpp | 1 + test/configuration_test.hpp | 1 + test/device_datum_test.hpp | 1 + test/time_series_test.hpp | 1 + 4 files changed, 4 insertions(+) diff --git a/test/condition_test.hpp b/test/condition_test.hpp index 51f8eff..d44f917 100644 --- a/test/condition_test.hpp +++ b/test/condition_test.hpp @@ -33,6 +33,7 @@ #pragma once #include +#include #include #include "condition.hpp" diff --git a/test/configuration_test.hpp b/test/configuration_test.hpp index 61f5ab1..02df597 100644 --- a/test/configuration_test.hpp +++ b/test/configuration_test.hpp @@ -33,6 +33,7 @@ #pragma once #include +#include #include #include "configuration.hpp" diff --git a/test/device_datum_test.hpp b/test/device_datum_test.hpp index 3ef45a0..a6b626e 100644 --- a/test/device_datum_test.hpp +++ b/test/device_datum_test.hpp @@ -33,6 +33,7 @@ #pragma once #include +#include #include #include "device_datum.hpp" diff --git a/test/time_series_test.hpp b/test/time_series_test.hpp index 8ddb0fb..00a30c9 100644 --- a/test/time_series_test.hpp +++ b/test/time_series_test.hpp @@ -33,6 +33,7 @@ #pragma once #include +#include #include #include "time_series.hpp" From bc8bb846bb3d842478281154dee8e7f4613f0cb4 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:13:39 +0100 Subject: [PATCH 07/41] C++11 Conversion: Whitespace and layout changes for 'test' project --- test/condition_test.cpp | 24 +++++++++++++++--------- test/device_datum_test.cpp | 4 ++++ test/test.cpp | 17 +++++++++-------- test/time_series_test.cpp | 18 ++++++++++++------ test/time_series_test.hpp | 2 +- 5 files changed, 41 insertions(+), 24 deletions(-) diff --git a/test/condition_test.cpp b/test/condition_test.cpp index 8400b93..4920abc 100644 --- a/test/condition_test.cpp +++ b/test/condition_test.cpp @@ -39,14 +39,17 @@ using namespace std; CPPUNIT_TEST_SUITE_REGISTRATION(ConditionTest); + void ConditionTest::setUp() { } + void ConditionTest::tearDown() { } + void ConditionTest::testInitial() { Condition cond("Test"); @@ -59,9 +62,10 @@ void ConditionTest::testInitial() CPPUNIT_ASSERT(cond.requiresFlush()); cond.append(buffer); - CPPUNIT_ASSERT_EQUAL(string("|Test|UNAVAILABLE||||"), string((const char*) buffer)); + CPPUNIT_ASSERT_EQUAL(string("|Test|UNAVAILABLE||||"), string((const char *) buffer)); } + void ConditionTest::testInitialNormal() { Condition cond("Test"); @@ -70,9 +74,10 @@ void ConditionTest::testInitialNormal() CPPUNIT_ASSERT(cond.normal()); cond.append(buffer); - CPPUNIT_ASSERT_EQUAL(string("|Test|NORMAL||||"), string((const char*) buffer)); + CPPUNIT_ASSERT_EQUAL(string("|Test|NORMAL||||"), string((const char *) buffer)); } + void ConditionTest::testAdd() { Condition cond("Test"); @@ -82,10 +87,11 @@ void ConditionTest::testAdd() CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); cond.prepare(); CPPUNIT_ASSERT(cond.append(buffer)); - CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|123|1|HIGH|A Fault"), string((const char*) buffer)); + CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|123|1|HIGH|A Fault"), string((const char *) buffer)); cond.cleanup(); } + void ConditionTest::testActive() { Condition cond("Test"); @@ -95,13 +101,14 @@ void ConditionTest::testActive() CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); cond.prepare(); CPPUNIT_ASSERT(cond.append(buffer)); - CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|123|1|HIGH|A Fault"), string((const char*) buffer)); + CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|123|1|HIGH|A Fault"), string((const char *) buffer)); CPPUNIT_ASSERT(cond.isActive("123")); CPPUNIT_ASSERT(!cond.isActive("1234")); cond.cleanup(); } + void ConditionTest::testCleanup() { Condition cond("Test"); @@ -111,7 +118,7 @@ void ConditionTest::testCleanup() CPPUNIT_ASSERT(cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); cond.prepare(); CPPUNIT_ASSERT(cond.append(buffer)); - CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|123|1|HIGH|A Fault"), string((const char*) buffer)); + CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|123|1|HIGH|A Fault"), string((const char *) buffer)); cond.cleanup(); buffer.reset(); @@ -119,7 +126,7 @@ void ConditionTest::testCleanup() cond.begin(); cond.prepare(); cond.append(buffer); - CPPUNIT_ASSERT_EQUAL(string("|Test|NORMAL||||"), string((const char*) buffer)); + CPPUNIT_ASSERT_EQUAL(string("|Test|NORMAL||||"), string((const char *) buffer)); cond.cleanup(); buffer.reset(); @@ -131,7 +138,7 @@ void ConditionTest::testCleanup() CPPUNIT_ASSERT(cond.append(buffer)); CPPUNIT_ASSERT_EQUAL(string("|Test|FAULT|124|1|HIGH|Another Fault\n" "|Test|FAULT|123|1|HIGH|A Fault"), - string((const char*) buffer)); + string((const char *) buffer)); CPPUNIT_ASSERT(cond.isActive("123")); CPPUNIT_ASSERT(cond.isActive("124")); @@ -141,10 +148,9 @@ void ConditionTest::testCleanup() cond.begin(); CPPUNIT_ASSERT(!cond.add(Condition::eFAULT, "A Fault", "123", "HIGH", "1")); - cond.prepare(); cond.append(buffer); - CPPUNIT_ASSERT_EQUAL(string("|Test|NORMAL|124|||"), string((const char*) buffer)); + CPPUNIT_ASSERT_EQUAL(string("|Test|NORMAL|124|||"), string((const char *) buffer)); cond.cleanup(); CPPUNIT_ASSERT(cond.isActive("123")); diff --git a/test/device_datum_test.cpp b/test/device_datum_test.cpp index 014cade..0a7cd0c 100644 --- a/test/device_datum_test.cpp +++ b/test/device_datum_test.cpp @@ -38,14 +38,17 @@ using namespace std; CPPUNIT_TEST_SUITE_REGISTRATION(DeviceDatumTest); + void DeviceDatumTest::setUp() { } + void DeviceDatumTest::tearDown() { } + void DeviceDatumTest::testEvent() { Event event("Test"); @@ -80,6 +83,7 @@ void DeviceDatumTest::testEvent() CPPUNIT_ASSERT(!event.setValue("Hello")); } + void DeviceDatumTest::testSample() { Sample sample("Test"); diff --git a/test/test.cpp b/test/test.cpp index 79d331a..571019a 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -38,29 +38,30 @@ #include #include -int main (int argc, char* argv[]) + +int main(int argc, char *argv[]) { // informs test-listener about testresults CPPUNIT_NS :: TestResult testresult; // register listener for collecting the test-results CPPUNIT_NS :: TestResultCollector collectedresults; - testresult.addListener (&collectedresults); + testresult.addListener(&collectedresults); // register listener for per-test progress output CPPUNIT_NS :: BriefTestProgressListener progress; - testresult.addListener (&progress); + testresult.addListener(&progress); // insert test-suite at test-runner by registry CPPUNIT_NS :: TestRunner testrunner; - testrunner.addTest (CPPUNIT_NS :: TestFactoryRegistry :: getRegistry ().makeTest ()); - testrunner.run (testresult); + testrunner.addTest(CPPUNIT_NS :: TestFactoryRegistry :: getRegistry().makeTest()); + testrunner.run(testresult); // output results in compiler-format - CPPUNIT_NS :: CompilerOutputter compileroutputter (&collectedresults, std::cerr); - compileroutputter.write (); + CPPUNIT_NS :: CompilerOutputter compileroutputter(&collectedresults, std::cerr); + compileroutputter.write(); // return 0 if tests were successful - return collectedresults.wasSuccessful () ? 0 : 1; + return collectedresults.wasSuccessful() ? 0 : 1; } diff --git a/test/time_series_test.cpp b/test/time_series_test.cpp index ac8900a..774afa8 100644 --- a/test/time_series_test.cpp +++ b/test/time_series_test.cpp @@ -38,14 +38,17 @@ using namespace std; CPPUNIT_TEST_SUITE_REGISTRATION(TimeSeriesTest); + void TimeSeriesTest::setUp() { } + void TimeSeriesTest::tearDown() { } + void TimeSeriesTest::testTimeSeries() { StringBuffer buffer; @@ -55,15 +58,17 @@ void TimeSeriesTest::testTimeSeries() series.addValue((double) i); series.append(buffer); - CPPUNIT_ASSERT_EQUAL(string("|test|5||0 1 2 3 4 "), - string((const char*) buffer)); + CPPUNIT_ASSERT_EQUAL( + string("|test|5||0 1 2 3 4 "), + string((const char *) buffer)); series.clear(); buffer.reset(); series.append(buffer); - CPPUNIT_ASSERT_EQUAL(string("|test|0||"), - string((const char*) buffer)); + CPPUNIT_ASSERT_EQUAL( + string("|test|0||"), + string((const char *) buffer)); buffer.reset(); @@ -72,6 +77,7 @@ void TimeSeriesTest::testTimeSeries() series.setRate(42000); series.append(buffer); - CPPUNIT_ASSERT_EQUAL(string("|test|2|42000|2 4 "), - string((const char*) buffer)); + CPPUNIT_ASSERT_EQUAL( + string("|test|2|42000|2 4 "), + string((const char *) buffer)); } diff --git a/test/time_series_test.hpp b/test/time_series_test.hpp index 00a30c9..4942cf8 100644 --- a/test/time_series_test.hpp +++ b/test/time_series_test.hpp @@ -47,7 +47,7 @@ class TimeSeriesTest : public CppUnit::TestFixture protected: void testTimeSeries(); -public: + public: void setUp(); void tearDown(); }; From f61627baea96ae1ccef0d09b8948db7e35260d52 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:13:48 +0100 Subject: [PATCH 08/41] C++11 Conversion: C++11 changes for 'test' project * Use of 'auto' keyword * Use literal identifiers to prevent narrowing of types during compilation * Fixed truncation issue in a test --- test/time_series_test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/time_series_test.cpp b/test/time_series_test.cpp index 774afa8..0c9aaad 100644 --- a/test/time_series_test.cpp +++ b/test/time_series_test.cpp @@ -54,8 +54,8 @@ void TimeSeriesTest::testTimeSeries() StringBuffer buffer; TimeSeries series("test"); - for (int i = 0; i < 5; i++) - series.addValue((double) i); + for (auto i = 0.0f; i < 5.0f; i++) + series.addValue(i); series.append(buffer); CPPUNIT_ASSERT_EQUAL( @@ -72,8 +72,8 @@ void TimeSeriesTest::testTimeSeries() buffer.reset(); - series.addValue(2.0); - series.addValue(4.0); + series.addValue(2.0f); + series.addValue(4.0f); series.setRate(42000); series.append(buffer); From 995a04bd4301de1760004a2c8191154d83f5733f Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:14:01 +0100 Subject: [PATCH 09/41] C++11 Conversion: Whitespace and comment conversion in 'fake' adapter project --- fake/fake.cpp | 3 ++- fake/fake_adapter.cpp | 24 ++++++++++++++++-------- fake/fake_adapter.hpp | 6 ++---- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/fake/fake.cpp b/fake/fake.cpp index 0bd1bfb..9222acb 100644 --- a/fake/fake.cpp +++ b/fake/fake.cpp @@ -36,9 +36,10 @@ #include "server.hpp" #include "string_buffer.hpp" + int main(int aArgc, const char *aArgv[]) { - /* Construct the adapter and start the server */ + // Construct the adapter and start the server FakeAdapter *adapter = new FakeAdapter(7878); adapter->setName("Fake MTConnect Adapter"); return adapter->main(aArgc, aArgv); diff --git a/fake/fake_adapter.cpp b/fake/fake_adapter.cpp index ef5b7c0..6b3c1a7 100644 --- a/fake/fake_adapter.cpp +++ b/fake/fake_adapter.cpp @@ -34,9 +34,11 @@ #include "internal.hpp" #include "fake_adapter.hpp" -FakeAdapter::FakeAdapter(int aPort) - : Adapter(aPort, 1000), - mAvailability("avail"), mSystem("system"), mPos("pos"), +FakeAdapter::FakeAdapter(int aPort) : + Adapter(aPort, 1000), + mAvailability("avail"), + mSystem("system"), + mPos("pos"), mExecution("exec") { addDatum(mAvailability); @@ -45,28 +47,33 @@ FakeAdapter::FakeAdapter(int aPort) addDatum(mExecution); } + FakeAdapter::~FakeAdapter() { } -void FakeAdapter::initialize(int aArgc, const char *aArgv[]) + +void FakeAdapter::initialize(int argc, const char *argv[]) { - MTConnectService::initialize(aArgc, aArgv); - if (aArgc > 1) { - mPort = atoi(aArgv[1]); - } + MTConnectService::initialize(argc, argv); + + if (argc > 1) + mPort = atoi(argv[1]); } + void FakeAdapter::start() { startServer(); } + void FakeAdapter::stop() { stopServer(); } + static int count = 0; void FakeAdapter::gatherDeviceData() { @@ -74,6 +81,7 @@ void FakeAdapter::gatherDeviceData() printf("Count: %d\n", count); mPos.setValue(count); + switch (count % 6) { case 0: diff --git a/fake/fake_adapter.hpp b/fake/fake_adapter.hpp index e4f018b..9833c6f 100644 --- a/fake/fake_adapter.hpp +++ b/fake/fake_adapter.hpp @@ -40,16 +40,14 @@ class FakeAdapter : public Adapter, public MTConnectService { protected: - /* Define all the data values here */ - - /* Events */ + // Events Availability mAvailability; Condition mSystem; Sample mPos; Execution mExecution; public: - FakeAdapter(int aPort); + FakeAdapter(int port); ~FakeAdapter(); virtual void initialize(int aArgc, const char *aArgv[]); From 11554ad1d1ac721a450d830fd85db00d5e0f7511 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:14:17 +0100 Subject: [PATCH 10/41] C++11 Conversion: Conversion of core 'Adapter' class * C++ conversion using 'auto', 'nullptr' keywords * Use of std::vector as a container for items to simplify memory management * Use of std::chrono and std::thread for cross platform sleep functionality --- src/adapter.cpp | 304 ++++++++++++++++++++++++++---------------------- src/adapter.hpp | 111 +++++++++--------- 2 files changed, 220 insertions(+), 195 deletions(-) diff --git a/src/adapter.cpp b/src/adapter.cpp index 319ac62..6c23d1d 100755 --- a/src/adapter.cpp +++ b/src/adapter.cpp @@ -32,96 +32,103 @@ // #include "internal.hpp" #include "adapter.hpp" +#include +#include #include "device_datum.hpp" #include "cutting_tool.hpp" #include "logger.hpp" -Adapter::Adapter(int aPort, int aScanDelay) - : mNumDeviceData(0), mInitializeClient(NULL) + +Adapter::Adapter(int port, int scanDelayMs) : + mServer(nullptr), + mScanDelay{scanDelayMs}, + mPort(port), + mDisableFlush(false), + mHeartbeatFrequency(10000), + mRunning(false), + mInitializeClient(nullptr) { - mScanDelay = aScanDelay; - mServer = 0; - mPort = aPort; - mHeartbeatFrequency = 10000; - mMaxDatum = INITIAL_MAX_DEVICE_DATA; - mRunning = false; - mDeviceData = new DeviceDatum*[mMaxDatum]; + #ifdef THREADED - mServerThread = 0; + mServerThread = nullptr; #endif + + mDeviceData.reserve(INITIAL_MAX_DEVICE_DATA); } + Adapter::~Adapter() { mRunning = false; if (mServer) + { delete mServer; + mServer = nullptr; + } - delete[] mDeviceData; + for(auto value : mDeviceData) + delete value; + mDeviceData.clear(); } -/* Add a data value to the list of data values */ -void Adapter::addDatum(DeviceDatum &aValue) -{ - if (mNumDeviceData >= mMaxDatum - 1) - { - DeviceDatum** devData = new DeviceDatum*[mMaxDatum * 2]; - memcpy(devData, mDeviceData, sizeof(DeviceDatum*) * mMaxDatum); - delete[] mDeviceData; - mDeviceData = devData; - mMaxDatum *= 2; - } +// Add a data value to the list of data values +void Adapter::addDatum(DeviceDatum &value) +{ + // If we are approaching our capacity then resize + if(mDeviceData.size() == mDeviceData.capacity()) + mDeviceData.reserve(mDeviceData.capacity() * 2u); - mDeviceData[mNumDeviceData++] = &aValue; - mDeviceData[mNumDeviceData] = 0; + mDeviceData.push_back(&value); } -void Adapter::sleepMs(int aMs) -{ -#ifndef WIN32 - usleep(aMs * 1000); -#else - Sleep(aMs); -#endif +void Adapter::sleepMs(std::chrono::milliseconds ms) +{ + std::this_thread::sleep_for(ms); } #if THREADED #ifdef WIN32 -static int ServerThread(void *aArg) +static int ServerThread(void *arg) { - Adapter *adapter = (Adapter*) aArg; + auto adapter = (Adapter*)arg; adapter->serverThread(); return 0; } bool Adapter::startServerThread() { - if (gLogger == NULL) gLogger = new Logger(); + if (!gLogger) + gLogger = new Logger(); mServer = new Server(mPort, mHeartbeatFrequency); mRunning = true; mServerThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) &ServerThread, this, 0, 0); - if (mServerThread == NULL) { + if (!mServerThread) + { fprintf(stderr, "Cannot create server thread"); - delete mServer; + delete mServer; mServer = nullptr; return false; - } else { - Sleep(10); + } + else + { + sleepMs(10ms); } return true; } + int Adapter::waitUntilDone() { int ret = 1; - if (mServerThread != 0) { - DWORD res = WaitForSingleObject(mServerThread, INFINITE); + if (mServerThread != 0) + { + auto res = WaitForSingleObject(mServerThread, INFINITE); if (res == WAIT_OBJECT_0) { if (GetExitCodeThread(mServerThread, &res)) @@ -133,9 +140,9 @@ int Adapter::waitUntilDone() #else -static void *ServerThread(void *aArg) +static void *ServerThread(void *arg) { - Adapter *adapter = (Adapter*) aArg; + auto adapter = (Adapter*)arg; adapter->serverThread(); static int res = 0; @@ -145,40 +152,46 @@ static void *ServerThread(void *aArg) bool Adapter::startServerThread() { - if (gLogger == NULL) gLogger = new Logger(); + if (!gLogger) + gLogger = new Logger(); mServer = new Server(mPort, mHeartbeatFrequency); mRunning = true; - int res = pthread_create(&mServerThread, NULL, ::ServerThread, this); - if (res != 0) { + auto res = pthread_create(&mServerThread, nullptr, ::ServerThread, this); + if (res != 0) + { fprintf(stderr, "Cannot create server thread"); - delete mServer; + delete mServer; mServer = nullptr; return false; } return true; } + int Adapter::waitUntilDone() { int ret = 1; - if (mServerThread != 0) { - int *value; - int res = pthread_join(mServerThread, (void**) &value); - if (res != 0) ret = *value; + if (mServerThread != 0) + { + int *value(nullptr); + auto res = pthread_join(mServerThread, (void**) &value); + if (res != 0) + ret = *value; } return ret; } #endif -/* Poll every second for activity. We could do blocking but it complicates - * list management and locking. May refactor this when we have more time. - */ +// Poll every second for activity. We could do blocking but it complicates +// list management and locking. May refactor this when we have more time. +// void Adapter::serverThread() { - while (mRunning) { + while (mRunning) + { connectToClients(); readFromClients(); @@ -190,56 +203,59 @@ void Adapter::serverThread() #endif -/* - * Reads from clients, either blocking or polling. - */ + +// +// Reads from clients, either blocking or polling. +// void Adapter::readFromClients() { mServer->readFromClients(); } -/* - * Checks for new client connections, either blocking or polling. - */ +// +// Checks for new client connections, either blocking or polling. +// void Adapter::connectToClients() { - /* Check if we have any new clients */ - Client *client = mServer->connectToClients(); - if (client != NULL) + // Check if we have any new clients + auto client = mServer->connectToClients(); + if (client) sendInitialData(client); } -/* - * This is the main loop of the application. Once the server is started and - * the application runs forever until it is killed. The process follows this flow: - * See if any new clients have arrived. - * If new clients are present, sent the initial values to them. - * Read from the clients any data that is currently in the socket to keep anyone from - * blocking. - * If we have at least one client: - * Timestamp the buffer - * gather data from the API - * send the data values that have changed to the clients - * Sleep for a few millies and repeat. - */ + +// +// This is the main loop of the application. Once the server is started and +// the application runs forever until it is killed. The process follows this flow: +// See if any new clients have arrived. +// If new clients are present, sent the initial values to them. +// Read from the clients any data that is currently in the socket to keep anyone from +// blocking. +// If we have at least one client: +// Timestamp the buffer +// gather data from the API +// send the data values that have changed to the clients +// Sleep for a few millies and repeat. +// void Adapter::startServer() { - if (gLogger == NULL) gLogger = new Logger(); + if (!gLogger) + gLogger = new Logger(); mServer = new Server(mPort, mHeartbeatFrequency); mRunning = true; - /* Process untill stopped */ + // Process untill stopped while (mRunning) { - /* Check if we have any new clients */ + // Check if we have any new clients connectToClients(); - /* Read and all data from the clients */ + // Read and all data from the clients readFromClients(); - /* Don't bother getting data if we don't have anyone to read it */ + // Don't bother getting data if we don't have anyone to read it if (mServer->numClients() > 0) { MTCAutoLock lock(mGatherLock); @@ -253,57 +269,52 @@ void Adapter::startServer() cleanup(); } else if (mServer->hasClients()) - { clientsDisconnected(); - } sleepMs(mScanDelay); } delete mServer; - mServer = NULL; + mServer = nullptr; } + void Adapter::begin() { - for (int i = 0; i < mNumDeviceData; i++) - { - DeviceDatum *value = mDeviceData[i]; + for(auto value : mDeviceData) value->begin(); - } } + void Adapter::prepare() { - for (int i = 0; i < mNumDeviceData; i++) - { - DeviceDatum *value = mDeviceData[i]; + for(auto value : mDeviceData) value->prepare(); - } } + void Adapter::cleanup() { - for (int i = 0; i < mNumDeviceData; i++) - { - DeviceDatum *value = mDeviceData[i]; + for(auto value : mDeviceData) value->cleanup(); - } } -void Adapter::beginGather(const char *aTs, bool aSweep) + +void Adapter::beginGather(const char *timestamp, bool sweep) { mGatherLock.lock(); - if (aSweep) begin(); + if (sweep) + begin(); mBuffer.reset(); - if (aTs != NULL) - mBuffer.setTimestamp(aTs); + if (timestamp) + mBuffer.setTimestamp(timestamp); else mBuffer.timestamp(); } + void Adapter::completeGather() { prepare(); @@ -313,28 +324,31 @@ void Adapter::completeGather() mGatherLock.unlock(); } + void Adapter::stopServer() { mRunning = false; } -/* Send a single value to the buffer. */ -void Adapter::sendDatum(DeviceDatum *aValue) + +// Send a single value to the buffer. +void Adapter::sendDatum(DeviceDatum *value) { - if (aValue->requiresFlush()) + if (value->requiresFlush()) sendBuffer(); - aValue->append(mBuffer); - if (aValue->requiresFlush()) + value->append(mBuffer); + if (value->requiresFlush()) sendBuffer(); } -/* Send the buffer to the clients. Only sends if there is something in the buffer. */ + +// Send the buffer to the clients. Only sends if there is something in the buffer. void Adapter::sendBuffer() { - if (mServer != 0 && mBuffer.length() > 0) + if (mServer && mBuffer.length()) { mBuffer.append("\n"); - if (mInitializeClient != NULL) + if (mInitializeClient) mServer->sendToClient(mInitializeClient, mBuffer); else mServer->sendToClients(mBuffer); @@ -342,114 +356,120 @@ void Adapter::sendBuffer() } } -/* Send the initial values to a client */ -void Adapter::sendInitialData(Client *aClient) + +// Send the initial values to a client +void Adapter::sendInitialData(Client *client) { MTCAutoLock lock(mGatherLock); - mInitializeClient = aClient; + mInitializeClient = client; mDisableFlush = true; mBuffer.timestamp(); gatherDeviceData(); - for (int i = 0; i < mNumDeviceData; i++) + for(auto value : mDeviceData) { - DeviceDatum *value = mDeviceData[i]; - if (value->hasInitialValue()) + if(value->hasInitialValue()) sendDatum(value); } + sendBuffer(); mDisableFlush = false; - mInitializeClient = NULL; + mInitializeClient = nullptr; } -/* Send the values that have changed to the clients */ + +// Send the values that have changed to the clients void Adapter::sendChangedData() { - for (int i = 0; i < mNumDeviceData; i++) + for(auto value : mDeviceData) { - DeviceDatum *value = mDeviceData[i]; - if (value->changed()) + if(value->changed()) sendDatum(value); } + sendBuffer(); } + void Adapter::flush() { - if (!mDisableFlush) - { + if (mDisableFlush) + return; + sendChangedData(); mBuffer.reset(); mBuffer.timestamp(); - } } + void Adapter::clientsDisconnected() { - /* Do nothing for now ... */ + // Do nothing for now ... gLogger->info("All clients have disconnected"); } + void Adapter::unavailable() { - for (int i = 0; i < mNumDeviceData; i++) - { - DeviceDatum *value = mDeviceData[i]; + for(auto value : mDeviceData) value->unavailable(); - } + flush(); } + void Adapter::initializeDeviceDatum() { - for (int i = 0; i < mNumDeviceData; i++) - { - DeviceDatum *value = mDeviceData[i]; + for(auto value : mDeviceData) value->initialize(); - } + flush(); } -void Adapter::addAsset(const char *aId, const char *aType, const char *aData) + +void Adapter::addAsset(const char *id, const char *type, const char *data) { sendBuffer(); mBuffer.timestamp(); mBuffer.append("|@ASSET@|"); - mBuffer.append(aId); + mBuffer.append(id); mBuffer.append("|"); - mBuffer.append(aType); + mBuffer.append(type); mBuffer.append("|--multiline--ABCD\n"); - mBuffer.append(aData); + mBuffer.append(data); mBuffer.append("\n--multiline--ABCD"); sendBuffer(); mBuffer.timestamp(); } -void Adapter::updateAsset(const char *aId, const char *aData) + +void Adapter::updateAsset(const char *id, const char *data) { sendBuffer(); mBuffer.timestamp(); mBuffer.append("|@UPDATE_ASSET@|"); - mBuffer.append(aId); + mBuffer.append(id); mBuffer.append("|"); - mBuffer.append(aData); + mBuffer.append(data); sendBuffer(); mBuffer.timestamp(); } -void Adapter::addAsset(CuttingTool *aTool) + +void Adapter::addAsset(CuttingTool *tool) { - addAsset(aTool->getAssetId().c_str(), "CuttingTool", aTool->toString().c_str()); + addAsset(tool->getAssetId().c_str(), "CuttingTool", tool->toString().c_str()); } -void Adapter::updateAsset(CuttingTool *aTool) + +void Adapter::updateAsset(CuttingTool *tool) { - updateAsset(aTool->getAssetId().c_str(), aTool->toString().c_str()); + updateAsset(tool->getAssetId().c_str(), tool->toString().c_str()); } diff --git a/src/adapter.hpp b/src/adapter.hpp index 4c13818..d219613 100644 --- a/src/adapter.hpp +++ b/src/adapter.hpp @@ -31,6 +31,9 @@ // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // #pragma once + +#include +#include #include "server.hpp" #include "string_buffer.hpp" #include "threading.hpp" @@ -38,67 +41,63 @@ class DeviceDatum; class CuttingTool; -const int INITIAL_MAX_DEVICE_DATA = 128; +constexpr size_t INITIAL_MAX_DEVICE_DATA = 128u; -/* - * Abstract adapter that manages all the data values and writing them - * to the clients. - * - * Subclasses of this class will add the data values and interact with the - * vendor specifc API. This class provides all the common functionality. - */ +// +// Abstract adapter that manages all the data values and writing them +// to the clients. +// +// Subclasses of this class will add the data values and interact with the +// vendor specifc API. This class provides all the common functionality. +// class Adapter { protected: - Server *mServer; /* The socket server */ - StringBuffer mBuffer; /* A string buffer to hold the string we - * write to the streams */ - int mMaxDatum; /* The max number of device datums */ - DeviceDatum **mDeviceData; /* A 0 terminated array of data value objects */ - int mScanDelay; /* How long to sleep (in ms) between scans */ - int mNumDeviceData; /* The number of data values */ - int mPort; /* The server port we bind to */ - bool mDisableFlush; /* Used for initial data collection */ - int mHeartbeatFrequency; /* The frequency (ms) to heartbeat - * server. Responds to Ping. Default 10 sec */ + Server *mServer; // The socket server + StringBuffer mBuffer; // A string buffer to hold the string we write to the streams + std::vector mDeviceData; + std::chrono::milliseconds mScanDelay; // How long to sleep (in ms) between scans + int mPort; // The server port we bind to + bool mDisableFlush; // Used for initial data collection + int mHeartbeatFrequency; // The frequency (ms) to heartbeat server. Responds to Ping. Default 10 sec bool mRunning; - Client *mInitializeClient; /* If we are sending initial data to a client */ + Client *mInitializeClient; // If we are sending initial data to a client #ifdef THREADED -#ifdef WIN32 + #ifdef WIN32 HANDLE mServerThread; -#else + #else pthread_t mServerThread; -#endif + #endif #endif MTCMutex mGatherLock; protected: - void sleepMs(int aMs); + void sleepMs(std::chrono::milliseconds ms); - /* Internal buffer sending methods */ + // Internal buffer sending methods void sendBuffer(); - void sendDatum(DeviceDatum *aValue); - virtual void sendInitialData(Client *aClient); + void sendDatum(DeviceDatum *value); + virtual void sendInitialData(Client *client); virtual void sendChangedData(); virtual void flush(); void timestamp() { mBuffer.timestamp(); } virtual void unavailable(); virtual void initializeDeviceDatum(); - virtual void addAsset(const char *aId, const char *aType, const char *aData); - virtual void updateAsset(const char *aId, const char *aData); - virtual void addAsset(CuttingTool *aTool); - virtual void updateAsset(CuttingTool *aTool); + virtual void addAsset(const char *id, const char *type, const char *data); + virtual void updateAsset(const char *id, const char *data); + virtual void addAsset(CuttingTool *tool); + virtual void updateAsset(CuttingTool *tool); public: - Adapter(int aPort, int aScanDelay = 100); + Adapter(int port, int scanDelayMs = 100); ~Adapter(); void readFromClients(); void connectToClients(); - /* Start the server and never return */ + // Start the server and never return #ifdef THREADED bool startServerThread(); void serverThread(); @@ -109,47 +108,53 @@ class Adapter #endif void startServer(); - void addDatum(DeviceDatum &aValue); + void addDatum(DeviceDatum &value); - /* Stop server */ + // Stop server virtual void stopServer(); - /* Pure virtual method to get the data from the device. */ + // Pure virtual method to get the data from the device. virtual void gatherDeviceData() = 0; virtual void begin(); virtual void prepare(); virtual void cleanup(); - /* For multithreaded async gathering */ - virtual void beginGather(const char *aTs = NULL, bool aSweep = true); + // For multithreaded async gathering + virtual void beginGather(const char *timestamp = nullptr, bool sweep = true); virtual void completeGather(); - /* Overload this method to handle situation when all clients disconnect */ + // Overload this method to handle situation when all clients disconnect virtual void clientsDisconnected(); }; -class AutoGather { + +class AutoGather +{ public: - AutoGather(Adapter *anAdapter = NULL, const char *aTs = NULL, bool aSweep = true) - : mAdapter(anAdapter) { - if (mAdapter != NULL) - mAdapter->beginGather(aTs, aSweep); + AutoGather(Adapter *adapter = nullptr, const char *timestamp = nullptr, bool sweep = true) + : mAdapter(adapter) + { + if (mAdapter) + mAdapter->beginGather(timestamp, sweep); } - void begin(Adapter *anAdapter, const char *aTs = NULL, bool aSweep = true) { - mAdapter = anAdapter; - if (mAdapter != NULL) - mAdapter->beginGather(aTs, aSweep); + void begin(Adapter *adapter, const char *timestamp = nullptr, bool sweep = true) + { + mAdapter = adapter; + if (mAdapter) + mAdapter->beginGather(timestamp, sweep); } - void complete() { - if (mAdapter != NULL) + void complete() + { + if (mAdapter) mAdapter->completeGather(); - mAdapter = NULL; + mAdapter = nullptr; } - ~AutoGather() { - if (mAdapter != NULL) + ~AutoGather() + { + if (mAdapter) mAdapter->completeGather(); } From cebf37feca01c1db7f879548c8b222d745b77f47 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:14:31 +0100 Subject: [PATCH 11/41] C++11 Conversion: C++ conversions in 'axis.hpp' * Added missing implementation methods * Removed local variable that was masking derived class member * Implemented missing pure virtual function in a derived class --- src/axis.hpp | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/axis.hpp b/src/axis.hpp index d3b3db1..addf90b 100644 --- a/src/axis.hpp +++ b/src/axis.hpp @@ -40,17 +40,20 @@ class Axis : public Component { public: - enum Type { + enum Type + { LINEAR, ROTARY }; - enum Units { + enum Units + { INCH, MM }; - enum Mode { + enum Mode + { INDEX, SPINDLE, CONTOUR @@ -64,19 +67,27 @@ class Axis : public Component Type mType; Units mUnits; - string mName; - public: - Axis(Adapter *anAdapter, std::string aName, Component *aParent = NULL); + Axis(Adapter *adapter, std::string name, Component *parent = nullptr) : + Component(adapter, name, parent), + mNumber(0), + mMode(INDEX), + mType(LINEAR), + mUnits(MM) + { + } - Mode getMode() const { return mMode; } - Type getType() const { return mType; } - Units getUnits() const { return mUnits; } - const std::string &getName() { return mName; } + Mode getMode() const { + return mMode; } + Type getType() const { + return mType; } + Units getUnits() const { + return mUnits; } - virtual bool gatherData(void *aArg) = 0; + virtual void gatherData(void *context) = 0; }; + class Linear : public Axis { protected: @@ -84,6 +95,13 @@ class Linear : public Axis Sample mCommandedPosition; public: - Linear(Adapter *anAdapter, std::string aName, Component *aParent = NULL); -}; + Linear(Adapter *adapter, std::string name, Component *parent = nullptr) : + Axis(adapter, name, parent) + { + mType = LINEAR; + } + void gatherData(void *) override + { + } +}; From cb2fce360dacd98eebf84b8aecc6875feb0a97bc Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:14:41 +0100 Subject: [PATCH 12/41] BUG FIX: Not all Fanuc NC system information was being printed --- fanuc/fanuc_path.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fanuc/fanuc_path.cpp b/fanuc/fanuc_path.cpp index ba130b0..e18862f 100644 --- a/fanuc/fanuc_path.cpp +++ b/fanuc/fanuc_path.cpp @@ -99,8 +99,8 @@ bool FanucPath::configure(unsigned short aFlibhndl) gLogger->info(" Max Axis: %d", sysinfo.max_axis); gLogger->info(" CNC Type: %c%c", sysinfo.cnc_type[0], sysinfo.cnc_type[1]); gLogger->info(" MT Type: %c%c", sysinfo.mt_type[0], sysinfo.mt_type[1]); - gLogger->info(" Series: %c%c", sysinfo.series[0], sysinfo.series[1], sysinfo.series[2], sysinfo.series[3]); - gLogger->info(" Version: %c%c", sysinfo.version[0], sysinfo.version[1], sysinfo.version[2], sysinfo.version[3]); + gLogger->info(" Series: %c%c%c%c", sysinfo.series[0], sysinfo.series[1], sysinfo.series[2], sysinfo.series[3]); + gLogger->info(" Version: %c%c%c%c", sysinfo.version[0], sysinfo.version[1], sysinfo.version[2], sysinfo.version[3]); gLogger->info(" Axes: %c%c", sysinfo.axes[0], sysinfo.axes[1]); } @@ -133,7 +133,7 @@ bool FanucPath::configureSpindles(unsigned short aFlibhndl) } return true; - } +} else { gLogger->error("Failed to get splindle names: %d", ret); @@ -322,7 +322,7 @@ bool FanucPath::getStatus(unsigned short aFlibhndl) mEStop.setValue(EmergencyStop::eARMED); } return true; - } +} else { gLogger->error("Cannot cnc_statinfo for path %d: %d", mPathNumber, ret); @@ -584,7 +584,7 @@ Condition *FanucPath::translateAlarmNo(long aNum, int aAxis) void FanucPath::getCondition(unsigned short aFlibhndl, long aAlarm) { if (aAlarm != 0) - { +{ for (int i = 0; i < 31; i++) { if (aAlarm & (0x1 << i)) From 2c194e33131d6a9489012dff1ab67e0e9943c38c Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:14:51 +0100 Subject: [PATCH 13/41] C++11 Conversion: Conversion of the 'fanuc' adapter * Removed 'allowDNC' functionality as this never worked * Fixed subtle bug when character buffers we not initialized correctly (show when NC had an alarm condition) * Added ability to connect to a NC using HSSB * Use of auto, nullptr keywords * Loop iteration improvements * Removed most 'printf' with 'std::cout' for improved reliability * const correctness changes --- fanuc/fanuc_adapter.cpp | 329 ++++++++++++++++---------- fanuc/fanuc_adapter.hpp | 87 ++++--- fanuc/fanuc_axis.cpp | 64 ++--- fanuc/fanuc_axis.hpp | 25 +- fanuc/fanuc_path.cpp | 506 +++++++++++++++++++--------------------- fanuc/fanuc_path.hpp | 43 ++-- 6 files changed, 552 insertions(+), 502 deletions(-) diff --git a/fanuc/fanuc_adapter.cpp b/fanuc/fanuc_adapter.cpp index 562e5e1..1564492 100644 --- a/fanuc/fanuc_adapter.cpp +++ b/fanuc/fanuc_adapter.cpp @@ -15,17 +15,48 @@ // #include #include "fanuc_adapter.hpp" -#include "minIni.h" #include +#include +#include +#include +#include +#include + +constexpr int DEF_SERVICE_PORT = 7878; +constexpr int DEF_FOCAS2_PORT = 8193; + +// C++11 helper function for obtaining a statically defined array's item count +template +constexpr std::size_t countof(T const (&)[N]) noexcept +{ + return N; +} + -FanucAdapter::FanucAdapter(int aPort) - : Adapter(aPort), mAvail("avail"), mMessage("message"), mPartCount("part_count"), - mMacroSampleCount(0), mMacroPathCount(0), mPMCCount(0) +FanucAdapter::FanucAdapter(int aPort) : + Adapter(aPort), + mMaxPath(0), + mMessage("message"), + mAvail("avail"), + mPartCount("part_count"), + mMacroSample{0}, + mMacroPath{0}, + mMacroMin(99999), + mMacroMax(0), + mMacroSampleCount(0), + mMacroPathCount(0), + mPMCVariable{0}, + mPMCAddress{0}, + mPMCCount(0), + mFlibhndl(0), + mConnected(false), + mDevicePort(DEF_FOCAS2_PORT), + mDeviceIP{"localhost"} { - /* Alarms */ + // Alarms addDatum(mMessage); - /* Controller */ + // Controller addDatum(mAvail); addDatum(mPartCount); @@ -33,60 +64,65 @@ FanucAdapter::FanucAdapter(int aPort) mAvail.unavailable(); } + FanucAdapter::~FanucAdapter() { - size_t i; - - for (i = 0; i < mPaths.size(); i++) - delete mPaths[i]; + for (auto path : mPaths) + delete path; mPaths.clear(); disconnect(); } -void FanucAdapter::initialize(int aArgc, const char *aArgv[]) -{ - MTConnectService::initialize(aArgc, aArgv); - - const char *iniFile = "adapter.ini"; - - printf("Arguments: %d\n", aArgc); - if (aArgc > 1) { - strncpy(mDeviceIP, aArgv[0], MAX_HOST_LEN - 1); - mDeviceIP[MAX_HOST_LEN - 1] = '\0'; - mDevicePort = atoi(aArgv[1]); - - mPort = 7878; - if (aArgc > 2) - mPort = atoi(aArgv[2]); + +void FanucAdapter::initialize(int argc, const char *argv[]) +{ + MTConnectService::initialize(argc, argv); + + auto iniFile = "adapter.ini"; + std::cout << "Arguments: " << argc << std::endl; + if (argc > 1) + { + strncpy(mDeviceIP, argv[0], countof(mDeviceIP) - 1); + mDevicePort = atoi(argv[1]); + mPort = DEF_SERVICE_PORT; + if (argc > 2) + mPort = atoi(argv[2]); } else { - mDevicePort = 8193; - strcpy(mDeviceIP, "localhost"); - mPort = 7878; - if (aArgc > 0) - iniFile = aArgv[0]; - printf("Ini File: %s\n", iniFile); + mDevicePort = DEF_FOCAS2_PORT; + strncpy(mDeviceIP, "localhost", countof(mDeviceIP) - 1); + mPort = DEF_SERVICE_PORT; + if (argc > 0) + iniFile = argv[0]; + std::cout << "Ini File: " << iniFile << std::endl; } - FILE *fp = fopen(iniFile, "r"); - printf("FP = %d, %x\n", errno, fp); - if (fp != 0) fclose(fp); + auto fp = fopen(iniFile, "r"); + std::cout << "FP = " << errno << ", " << fp << std::endl; + if(fp) + { + fclose(fp); + fp = nullptr; + } configMacrosAndPMC(iniFile); } + void FanucAdapter::start() { startServer(); } + void FanucAdapter::stop() { stopServer(); } + void FanucAdapter::innerGatherDeviceData() { try @@ -109,69 +145,69 @@ void FanucAdapter::innerGatherDeviceData() } } + void FanucAdapter::gatherDeviceData() { - __try { + __try + { innerGatherDeviceData(); } - __except(EXCEPTION_EXECUTE_HANDLER) { + __except(EXCEPTION_EXECUTE_HANDLER) + { gLogger->error("Unhandled structured exception occurred during gathering device data, disconnecting."); disconnect(); } } + void FanucAdapter::disconnect() { if (mConnected) { - printf("Machine has disconnected. Releasing Resources\n"); + std::cout << "Machine has disconnected. Releasing Resources" << std::endl; cnc_freelibhndl(mFlibhndl); + mFlibhndl = 0; mConnected = false; unavailable(); } } -void FanucAdapter::configMacrosAndPMC(const char *aIniFile) +void FanucAdapter::configMacrosAndPMC(const char *iniFile) { // Read adapter configuration - mPort = ini_getl("adapter", "port", mPort, aIniFile); - ini_gets("adapter", "service", "MTConnect Fanuc Adapter", mName, - SERVICE_NAME_LEN, aIniFile); - mScanDelay = ini_getl("adapter", "scanDelay", mScanDelay, aIniFile); - - ini_gets("focus", "host", mDeviceIP, mDeviceIP, MAX_HOST_LEN, aIniFile); - mDevicePort = ini_getl("focus", "port", mDevicePort, aIniFile); - - char dnc[8]; - ini_gets("focus", "dnc", "yes", dnc, 8, aIniFile); - mAllowDNC = _strnicmp(dnc, "no", 2) != 0; - - if (!mAllowDNC) - printf("Disabling retrieval of program header\n"); + mPort = ini_getl("adapter", "port", mPort, iniFile); + ini_gets("adapter", + "service", + "MTConnect Fanuc Adapter", + mName, + SERVICE_NAME_LEN, + iniFile); + mScanDelay = std::chrono::milliseconds{ ini_getl("adapter", "scanDelay", 100, iniFile) }; + + ini_gets("focus", "host", mDeviceIP, mDeviceIP, countof(mDeviceIP), iniFile); + mDevicePort = ini_getl("focus", "port", mDevicePort, iniFile); // Read adapter.ini to get additional macro variables and // PMC registers - char name[100]; - int idx; + char name[100] = {0}; const static char *sDigits = "0123456789"; mMacroMin = 99999; mMacroMax = 0; // First look for macro variables - for (idx = 0; - ini_getkey("macros", idx, name, sizeof(name), aIniFile) > 0 && - idx < MAX_MACROS; + for (int idx = 0; + ini_getkey("macros", idx, name, countof(name), iniFile) > 0 && idx < MAX_MACROS; idx++) { - char numbers[256]; - ini_gets("macros", name, "", numbers, 256, aIniFile); + char numbers[256] = {0}; + ini_gets("macros", name, "", numbers, countof(numbers), iniFile); if (numbers[0] == '[') { // We have a path macro. - int x, y, z; + int x(0), y(0), z(0); char *cp = numbers + 1, *n; x = strtol(cp, &n, 10); if (cp == n) @@ -185,64 +221,72 @@ void FanucAdapter::configMacrosAndPMC(const char *aIniFile) if (cp == n) continue; - int i = mMacroPathCount++; + auto i = mMacroPathCount++; mMacroPath[i] = new MacroPathPosition(name, x, y, z); addDatum(*mMacroPath[i]); - printf("Adding path macro '%s' at location %d %d %d\n", name, x, y, z); - - if (x > mMacroMax) mMacroMax = x; - if (x < mMacroMin) mMacroMin = x; - if (y > mMacroMax) mMacroMax = y; - if (y < mMacroMin) mMacroMin = y; - if (z > mMacroMax) mMacroMax = z; - if (z < mMacroMin) mMacroMin = z; + std::cout << "Adding path macro '" << name << "' at location" + << x << " " << y << " " << z << std::endl; + + if (x > mMacroMax) + mMacroMax = x; + if (x < mMacroMin) + mMacroMin = x; + if (y > mMacroMax) + mMacroMax = y; + if (y < mMacroMin) + mMacroMin = y; + if (z > mMacroMax) + mMacroMax = z; + if (z < mMacroMin) + mMacroMin = z; } else { - char *cp = numbers, *n; - long v = strtol(cp, &n, 10); + char *cp = numbers, *n(nullptr); + auto v = strtol(cp, &n, 10); if (cp == n) continue; - int i = mMacroSampleCount++; + auto i = mMacroSampleCount++; mMacroSample[i] = new MacroSample(name, v); addDatum(*mMacroSample[i]); - printf("Adding sample macro '%s' at location %d\n", name, v); + std::cout << "Adding sample macro '" << name << "' at location " << v << std::endl; - if (v > mMacroMax) mMacroMax = v; - if (v < mMacroMin) mMacroMin = v; + if (v > mMacroMax) + mMacroMax = v; + if (v < mMacroMin) + mMacroMin = v; } - - } - for (idx = 0; - ini_getkey("pmc", idx, name, sizeof(name), aIniFile) > 0 && - idx < MAX_PMC; - idx++) + auto pmcIdx = 0; + for (pmcIdx = 0; + ini_getkey("pmc", pmcIdx, name, countof(name), iniFile) > 0 && pmcIdx < MAX_PMC; + pmcIdx++) { - long v = ini_getl("pmc", name, 0, aIniFile); - mPMCVariable[idx] = new IntEvent(name); - mPMCAddress[idx] = v; + auto v = ini_getl("pmc", name, 0, iniFile); + mPMCVariable[pmcIdx] = new IntEvent(name); + mPMCAddress[pmcIdx] = v; - addDatum(*mPMCVariable[idx]); + addDatum(*mPMCVariable[pmcIdx]); - printf("Adding pmc '%s' at location %d\n", name, v); + std::cout << "Adding pmc '" << name << "' at location " << v << std::endl; } - mPMCCount = idx; + + mPMCCount = pmcIdx; } + void FanucAdapter::configure() { if (mConfigured || !mConnected) return; - int ret; gLogger->info("Configuring...\n"); - short path; - ret = cnc_getpath(mFlibhndl, &path, &mMaxPath); + short path(0); + auto ret = cnc_getpath(mFlibhndl, &path, &mMaxPath); if (ret != EW_OK) { gLogger->error("Cannot find number of paths: %d", ret); @@ -250,17 +294,16 @@ void FanucAdapter::configure() path = 1; } - for (int i = 1; i <= mMaxPath; i++) + for (auto pathNum = 1; pathNum <= mMaxPath; pathNum++) { - FanucPath *path = new FanucPath(this, i); - if (!path->configure(mFlibhndl)) + auto fanucPath = new FanucPath(this, pathNum); + if (!fanucPath->configure(mFlibhndl)) { - gLogger->error("Could not configure path: %d", i); + gLogger->error("Could not configure path: %d", pathNum); exit(1); } - path->allowDNC(mAllowDNC); - mPaths.push_back(path); + mPaths.push_back(fanucPath); } gLogger->info("Current path: %d, maximum paths: %d", path, mMaxPath); @@ -268,19 +311,37 @@ void FanucAdapter::configure() mConfigured = true; } + void FanucAdapter::connect() { if (mConnected) return; - printf("Connecting to Machine at %s and port %d\n", mDeviceIP, mDevicePort); - short ret = ::cnc_allclibhndl3(mDeviceIP, mDevicePort, 10, &mFlibhndl); - printf("Result: %d\n", ret); + std::cout << "Connecting to Machine at " << mDeviceIP << " and port " << mDevicePort << std::endl; + + // If the device IP has been passed in the form HSSB_{1-9} then we should + // connect via HSSB + std::regex hssbRegEx("HSSB_([0-9])"); + std::cmatch matches; + short ret = 0; + if(std::regex_search(mDeviceIP, matches, hssbRegEx)) + { + auto res = matches[1].str(); + int hssbAddress = std::strtol(res.c_str(), nullptr, 0); + ret = ::cnc_allclibhndl2(hssbAddress, &mFlibhndl); + } + else + { + ret = ::cnc_allclibhndl3(mDeviceIP, mDevicePort, 10, &mFlibhndl); + } + + std::cout << "Result: " << ret <getNumber() - mMacroMin; + for (auto i = 0; i < mMacroSampleCount; i++) + { + auto off = mMacroSample[i]->getNumber() - mMacroMin; if (macros->data[off].mcr_val != 0 || macros->data[off].dec_val != -1) { mMacroSample[i]->setValue(((double) macros->data[off].mcr_val) / pow(10.0, macros->data[off].dec_val)); - } else { + } + else + { mMacroSample[i]->unavailable(); } } - for (int i = 0; i < mMacroPathCount; i++) + for (auto i = 0; i < mMacroPathCount; i++) { - int x = mMacroPath[i]->getX() - mMacroMin; - int y = mMacroPath[i]->getY() - mMacroMin; - int z = mMacroPath[i]->getZ() - mMacroMin; + auto x = mMacroPath[i]->getX() - mMacroMin; + auto y = mMacroPath[i]->getY() - mMacroMin; + auto z = mMacroPath[i]->getZ() - mMacroMin; if ((macros->data[x].mcr_val != 0 || macros->data[x].dec_val != -1) && (macros->data[y].mcr_val != 0 || macros->data[y].dec_val != -1) && @@ -347,19 +414,20 @@ void FanucAdapter::getMacros() pow(10.0, macros->data[y].dec_val), ((double) macros->data[z].mcr_val) / pow(10.0, macros->data[z].dec_val)); - } else { + } + else + { mMacroSample[i]->unavailable(); } } } else - { - printf("Could not read macro variables: %d\n", ret); - } + std::cout << "Could not read macro variables: " << ret << std::endl; delete[] macros; } + void FanucAdapter::getPMC() { if (!mConnected) @@ -368,8 +436,13 @@ void FanucAdapter::getPMC() for (int i = 0; i < mPMCCount; i++) { IODBPMC buf; - short ret = pmc_rdpmcrng(mFlibhndl, 0 /* G */, 0 /* byte */, - mPMCAddress[i], mPMCAddress[i], 8 + 1, + auto ret = pmc_rdpmcrng( + mFlibhndl, + 0, // G + 0, // byte + mPMCAddress[i], + mPMCAddress[i], + 8 + 1, &buf); if (ret == EW_OK) { @@ -380,27 +453,31 @@ void FanucAdapter::getPMC() } else { - printf("Could not retrieve PMC data at %d for %s: %d\n", - mPMCAddress[i], mPMCVariable[i]->getName(), ret); + std::cout << "Could not retrieve PMC data at " << mPMCAddress[i] + << " for " << mPMCVariable[i]->getName() + << ": " << ret + << std::endl; } } } + void FanucAdapter::getMessages() { if (!mConnected) return; OPMSG messages[6]; - int ret = cnc_rdopmsg(mFlibhndl, 0, 6 + 256, messages); + auto ret = cnc_rdopmsg(mFlibhndl, 0, 6 + 256, messages); if (ret == EW_OK && messages->datano != -1) { - char buf[32]; - sprintf(buf, "%04", messages->datano); + char buf[32] = {0}; + sprintf(buf, "%04d", messages->datano); mMessage.setValue(messages->data, buf); } } + void FanucAdapter::getCounts() { if (!mConnected) @@ -408,13 +485,12 @@ void FanucAdapter::getCounts() // Should just be a parameter read IODBPSD buf; - short ret = cnc_rdparam(mFlibhndl, 6711, 0, 8, &buf); + auto ret = cnc_rdparam(mFlibhndl, 6711, 0, 8, &buf); if (ret == EW_OK) - { mPartCount.setValue(buf.u.ldata); - } } + void FanucAdapter::getPathData() { if (!mConnected) @@ -432,4 +508,3 @@ void FanucAdapter::getPathData() if (mConnected && i > 0) cnc_setpath(mFlibhndl, 0); } - diff --git a/fanuc/fanuc_adapter.hpp b/fanuc/fanuc_adapter.hpp index be279a3..84948a2 100644 --- a/fanuc/fanuc_adapter.hpp +++ b/fanuc/fanuc_adapter.hpp @@ -1,10 +1,3 @@ - -#include "adapter.hpp" -#include "condition.hpp" -#include "device_datum.hpp" -#include "service.hpp" -#include "fanuc_path.hpp" -#include "Fwlib32.h" // // Copyright Copyright 2012, System Insights, Inc. // @@ -22,10 +15,17 @@ // #pragma once #include +#include +#include +#include +#include +#include +#include "fanuc_path.hpp" + + +constexpr int MAX_MACROS = 32; +constexpr int MAX_PMC = 32; -#define MAX_MACROS 32 -#define MAX_PMC 32 -const int MAX_HOST_LEN = 64; class MacroSample : public Sample { @@ -34,45 +34,61 @@ class MacroSample : public Sample public: MacroSample(const char *aName, int aNum) : - Sample(aName), mNumber(aNum) {} - int getNumber() { return mNumber; } + Sample(aName), + mNumber(aNum) + { + } + + int getNumber() { + return mNumber; } }; + class MacroPathPosition : public PathPosition { protected: - int mX; - int mY; - int mZ; + int m_X; + int m_Y; + int m_Z; public: - MacroPathPosition(const char *aName, int aX, int aY, int aZ) : - PathPosition(aName), mX(aX), mY(aY), mZ(aZ) {} - int getX() { return mX; } - int getY() { return mY; } - int getZ() { return mZ; } + MacroPathPosition(const char *name, int X, int Y, int Z) : + PathPosition(name), + m_X(X), + m_Y(Y), + m_Z(Z) + { + } + + int getX() { + return m_X; } + int getY() { + return m_Y; } + int getZ() { + return m_Z; } }; -/* - * Provides a connection to the data available from the FANUC Focus library. - */ + +// +// Provides a connection to the data available from the FANUC Focus library. +// class FanucAdapter : public Adapter, public MTConnectService { protected: - /* Define all the data values here */ + // Define all the data values here short mMaxPath; std::vector mPaths; - /* Conditions */ + // Conditions - /* Events */ + // Events Message mMessage; Availability mAvail; IntEvent mPartCount; - /* Macro variables */ + // Macro variables MacroSample *mMacroSample[MAX_MACROS]; MacroPathPosition *mMacroPath[MAX_MACROS]; int mMacroMin; @@ -80,21 +96,20 @@ class FanucAdapter : public Adapter, public MTConnectService int mMacroSampleCount; int mMacroPathCount; - /* Macro variables */ + // Macro variables IntEvent *mPMCVariable[MAX_PMC]; int mPMCAddress[MAX_PMC]; int mPMCCount; unsigned short mFlibhndl; bool mConnected, mConfigured; - bool mAllowDNC; int mDevicePort; - char mDeviceIP[MAX_HOST_LEN]; + char mDeviceIP[64]; protected: void connect(); void configure(); - void configMacrosAndPMC(const char *aIniFile); + void configMacrosAndPMC(const char *iniFile); void reconnect(); void disconnect(); @@ -110,13 +125,13 @@ class FanucAdapter : public Adapter, public MTConnectService void innerGatherDeviceData(); public: - FanucAdapter(int aServerPort); + FanucAdapter(int serverPort); ~FanucAdapter(); // For Service - virtual void initialize(int aArgc, const char *aArgv[]); - virtual void start(); - virtual void stop(); + void initialize(int argc, const char *argv[]) final; + void start() final; + void stop() final; - virtual void gatherDeviceData(); + void gatherDeviceData() final; }; diff --git a/fanuc/fanuc_axis.cpp b/fanuc/fanuc_axis.cpp index c4cfb8c..62aff6f 100644 --- a/fanuc/fanuc_axis.cpp +++ b/fanuc/fanuc_axis.cpp @@ -14,51 +14,55 @@ // limitations under the License. // #include "internal.hpp" -#include "Fwlib32.h" +#include "fanuc_axis.hpp" +#include #include "fanuc_path.hpp" -#include "logger.hpp" using namespace std; -FanucAxis::FanucAxis(Adapter *anAdapter, string aPrefix, int aIndex) - : mIndex(aIndex), mDivisor(1.0) + +FanucAxis::FanucAxis(Adapter *adapter, string prefix, int index) : + mIndex(index), + mDivisor(1.0) { - mActual.setName((aPrefix + "act").c_str()); - anAdapter->addDatum(mActual); - mLoad.setName((aPrefix + "load").c_str()); - anAdapter->addDatum(mLoad); - mTravel.setName((aPrefix + "travel").c_str()); - anAdapter->addDatum(mTravel); - mOverheat.setName((aPrefix + "overheat").c_str()); - anAdapter->addDatum(mOverheat); - mServo.setName((aPrefix + "servo").c_str()); - anAdapter->addDatum(mServo); + mActual.setName((prefix + "act").c_str()); + adapter->addDatum(mActual); + mLoad.setName((prefix + "load").c_str()); + adapter->addDatum(mLoad); + mTravel.setName((prefix + "travel").c_str()); + adapter->addDatum(mTravel); + mOverheat.setName((prefix + "overheat").c_str()); + adapter->addDatum(mOverheat); + mServo.setName((prefix + "servo").c_str()); + adapter->addDatum(mServo); } -bool FanucAxis::gatherData(ODBDY2 *aDynamic, ODBSVLOAD *aLoads) + +bool FanucAxis::gatherData(ODBDY2 *dynamic, ODBSVLOAD *loads) { - mActual.setValue(aDynamic->pos.faxis.machine[mIndex] / mDivisor); - mLoad.setValue(aLoads[mIndex].svload.data / - pow((long double) 10.0, (long double) aLoads[mIndex].svload.dec)); + mActual.setValue(dynamic->pos.faxis.machine[mIndex] / mDivisor); + mLoad.setValue(loads[mIndex].svload.data / + pow((long double) 10.0, (long double) loads[mIndex].svload.dec)); return true; } -FanucSpindle::FanucSpindle(Adapter *anAdapter, string aPrefix, int aIndex) - : mIndex(aIndex) + +FanucSpindle::FanucSpindle(Adapter *adapter, string prefix, int index) : + mIndex(index) { - mSpeed.setName((aPrefix + "speed").c_str()); - anAdapter->addDatum(mSpeed); - mLoad.setName((aPrefix + "load").c_str()); - anAdapter->addDatum(mLoad); - mServo.setName((aPrefix + "servo").c_str()); - anAdapter->addDatum(mServo); + mSpeed.setName((prefix + "speed").c_str()); + adapter->addDatum(mSpeed); + mLoad.setName((prefix + "load").c_str()); + adapter->addDatum(mLoad); + mServo.setName((prefix + "servo").c_str()); + adapter->addDatum(mServo); } -bool FanucSpindle::gatherData(ODBSPLOAD *aLoads, ODBACT2 *aSpeeds) + +bool FanucSpindle::gatherData(ODBSPLOAD *loads, ODBACT2 *aSpeeds) { - mLoad.setValue(aLoads[mIndex].spload.data / - pow((long double) 10.0, (long double) aLoads[mIndex].spload.dec)); + mLoad.setValue(loads[mIndex].spload.data / + pow((long double) 10.0, (long double) loads[mIndex].spload.dec)); mSpeed.setValue(aSpeeds->data[mIndex]); return true; } - diff --git a/fanuc/fanuc_axis.hpp b/fanuc/fanuc_axis.hpp index e673ff6..2b5df73 100644 --- a/fanuc/fanuc_axis.hpp +++ b/fanuc/fanuc_axis.hpp @@ -1,8 +1,3 @@ - - -#include "device_datum.hpp" -#include "condition.hpp" -#include "adapter.hpp" // // Copyright Copyright 2012, System Insights, Inc. // @@ -21,42 +16,42 @@ #pragma once #include -#include "Fwlib32.h" +#include +#include +#include +#include + class FanucAxis { public: - FanucAxis(Adapter *anAdapter, std::string aPrefix, int anIndex); + FanucAxis(Adapter *adapter, std::string prefix, int index); ~FanucAxis() {} - bool gatherData(ODBDY2 *aDynamic, ODBSVLOAD *aLoads); + bool gatherData(ODBDY2 *dynamic, ODBSVLOAD *loads); public: int mIndex; - Sample mActual; Sample mLoad; - double mDivisor; - Condition mTravel; Condition mOverheat; Condition mServo; }; + class FanucSpindle { public: - FanucSpindle(Adapter *anAdapter, std::string aPrefix, int anIndex); + FanucSpindle(Adapter *adapter, std::string prefix, int index); ~FanucSpindle() {} - bool gatherData(ODBSPLOAD *aLoads, ODBACT2 *aSpeeds); + bool gatherData(ODBSPLOAD *loads, ODBACT2 *speeds); public: int mIndex; - Sample mSpeed; Sample mLoad; - Condition mServo; }; diff --git a/fanuc/fanuc_path.cpp b/fanuc/fanuc_path.cpp index e18862f..5fea1f3 100644 --- a/fanuc/fanuc_path.cpp +++ b/fanuc/fanuc_path.cpp @@ -15,74 +15,86 @@ // #include "internal.hpp" -#include "Fwlib32.h" #include "fanuc_path.hpp" -#include "logger.hpp" - #include +#include +#include using namespace std; -void FanucPath::addDatum(DeviceDatum &aDatum, const char *aName, const char *aSuffix) +// C++11 helper function for obtaining a statically defined array's item count +template +constexpr std::size_t countof(T const (&)[N]) noexcept +{ + return N; +} + + +void FanucPath::addDatum(DeviceDatum &datum, const char *name, const char *suffix) { - char name[32]; - strcpy(name, aName); strcat(name, aSuffix); - aDatum.setName(name); - mAdapter->addDatum(aDatum); + std::string datumName(name); + datumName.append(suffix); + datum.setName(datumName.c_str()); + mAdapter->addDatum(datum); } -FanucPath::FanucPath(Adapter *anAdapter, short aPathNumber) - : mAdapter(anAdapter), mPathNumber(aPathNumber), mXAxis(NULL), mYAxis(NULL), - mZAxis(NULL), mToolManagementEnabled(true), mUseModalToolData(false), - mAllowDNC(true) + +FanucPath::FanucPath(Adapter *adapter, short pathNumber) : + mAdapter(adapter), + mPathNumber(pathNumber), + mProgramNum(-1), + mSpindleCount(0), + mAxisCount(0), + mToolManagementEnabled(true), + mUseModalToolData(false), + mXAxis(nullptr), + mYAxis(nullptr), + mZAxis(nullptr) { - char number[2]; - if (aPathNumber > 1) - sprintf(number, "%d", aPathNumber); - else - number[0] = '\0'; - - addDatum(mToolId, "tool_id", number); - addDatum(mToolGroup, "tool_group", number); - addDatum(mProgramName, "program", number); - addDatum(mProgramComment, "program_comment", number); - addDatum(mLine, "line", number); - addDatum(mBlock, "block", number); - addDatum(mPathFeedrate, "path_feedrate", number); - addDatum(mPathPosition, "path_position", number); - addDatum(mActiveAxes, "active_axes", number); - addDatum(mMode, "mode", number); - addDatum(mServo, "servo", number); - addDatum(mComms, "comms", number); - addDatum(mLogic, "logic", number); - addDatum(mMotion, "motion", number); - addDatum(mSystem, "system", number); - addDatum(mExecution, "execution", number); - addDatum(mCommandedFeedrate, "f_command", number); + auto pathNumAsString = std::to_string(pathNumber); + if(pathNumber <= 1) + pathNumAsString.clear(); + + addDatum(mToolId, "tool_id", pathNumAsString.c_str()); + addDatum(mToolGroup, "tool_group", pathNumAsString.c_str()); + addDatum(mProgramName, "program", pathNumAsString.c_str()); + addDatum(mProgramComment, "program_comment", pathNumAsString.c_str()); + addDatum(mLine, "line", pathNumAsString.c_str()); + addDatum(mBlock, "block", pathNumAsString.c_str()); + addDatum(mPathFeedrate, "path_feedrate", pathNumAsString.c_str()); + addDatum(mPathPosition, "path_position", pathNumAsString.c_str()); + addDatum(mActiveAxes, "active_axes", pathNumAsString.c_str()); + addDatum(mMode, "mode", pathNumAsString.c_str()); + addDatum(mServo, "servo", pathNumAsString.c_str()); + addDatum(mComms, "comms", pathNumAsString.c_str()); + addDatum(mLogic, "logic", pathNumAsString.c_str()); + addDatum(mMotion, "motion", pathNumAsString.c_str()); + addDatum(mSystem, "system", pathNumAsString.c_str()); + addDatum(mExecution, "execution", pathNumAsString.c_str()); + addDatum(mCommandedFeedrate, "f_command", pathNumAsString.c_str()); // Only track estop on the first path. Should be the same for all // paths, only one estop per machine. - if (aPathNumber == 1) - addDatum(mEStop, "estop", number); + if (pathNumber == 1) + addDatum(mEStop, "estop", pathNumAsString.c_str()); } + FanucPath::~FanucPath() { - size_t i; - for (i = 0; i < mAxes.size(); i++) - delete mAxes[i]; + for (auto axis : mAxes) + delete axis; mAxes.clear(); - i; - for (i = 0; i < mSpindles.size(); i++) - delete mSpindles[i]; + for (auto spindle : mSpindles) + delete spindle; mSpindles.clear(); } -bool FanucPath::configure(unsigned short aFlibhndl) +bool FanucPath::configure(unsigned short flibhndl) { - int ret = cnc_setpath(aFlibhndl, mPathNumber); + auto ret = cnc_setpath(flibhndl, mPathNumber); if (ret != EW_OK) { gLogger->error("Could not cnc_setpath: %d"); @@ -92,8 +104,8 @@ bool FanucPath::configure(unsigned short aFlibhndl) gLogger->info("Configuration for path %d:", mPathNumber); // Get system info for this path: - ODBSYS sysinfo; - ret = cnc_sysinfo(aFlibhndl, &sysinfo); + ODBSYS sysinfo = {0}; + ret = cnc_sysinfo(flibhndl, &sysinfo); if (ret == EW_OK) { gLogger->info(" Max Axis: %d", sysinfo.max_axis); @@ -105,70 +117,77 @@ bool FanucPath::configure(unsigned short aFlibhndl) } - return configureAxes(aFlibhndl) && - configureSpindles(aFlibhndl); + return configureAxes(flibhndl) && configureSpindles(flibhndl); } -bool FanucPath::configureSpindles(unsigned short aFlibhndl) + +bool FanucPath::configureSpindles(unsigned short flibhndl) { - ODBSPDLNAME spindles[MAX_SPINDLE]; - mSpindleCount = MAX_SPINDLE; - short ret = cnc_rdspdlname(aFlibhndl, &mSpindleCount, spindles); - if (ret == EW_OK) + ODBSPDLNAME spindles[MAX_SPINDLE] = {0}; + mSpindleCount = static_cast(countof(spindles)); + short ret = cnc_rdspdlname(flibhndl, &mSpindleCount, spindles); + if (ret != EW_OK) { - int i = 0; - for (i = 0; i < mSpindleCount; i++) + gLogger->error("Failed to get splindle names: %d", ret); + return false; + } + + + for (auto i = 0; i < mSpindleCount; i++) { - gLogger->info("Spindle %d : %c%c%c", i, spindles[i].name, spindles[i].suff1, spindles[i].suff2); - char name[12]; - int j = 0; - name[j++] = spindles[i].name; - if (spindles[i].suff1 > 0) - name[j++] = spindles[i].suff1; + const auto &spindle = spindles[i]; + gLogger->info("Spindle %d : %c%c%c%c", i, spindle.name, spindle.suff1, spindle.suff2, spindle.suff3); + std::string name = {spindle.name, spindle.suff1}; if (mPathNumber > 1) - name[j++] = mPathNumber + '0'; - name[j] = '\0'; + name.append(std::to_string(mPathNumber)); - mSpindles.push_back(new FanucSpindle(mAdapter, name, i)); + mSpindles.push_back(new FanucSpindle(mAdapter, name.c_str(), i)); } return true; } - else - { - gLogger->error("Failed to get splindle names: %d", ret); - return false; - } -} -bool FanucPath::configureAxes(unsigned short aFlibhndl) + +bool FanucPath::configureAxes(unsigned short flibhndl) { const int num = 1; short types[num] = { 1 /* actual position */ }; short len = MAX_AXIS; - ODBAXDT axisData[MAX_AXIS * num]; - short ret = cnc_rdaxisdata(aFlibhndl, 1 /* Position Value */, (short*) types, num, &len, axisData); + ODBAXDT axisData[MAX_AXIS * num] = {0}; + auto ret = cnc_rdaxisdata( + flibhndl, + 1, // Position Value + types, + num, + &len, + axisData); + bool hasAxisData = ret == EW_OK; if (!hasAxisData) - { gLogger->error("cnc_rdaxisdata returned %d for path %d", ret, mPathNumber); - } - ODBAXISNAME axes[MAX_AXIS]; + ODBAXISNAME axes[MAX_AXIS] = {0}; mAxisCount = MAX_AXIS; - ret = cnc_rdaxisname(aFlibhndl, &mAxisCount, axes); - if (ret == EW_OK) + ret = cnc_rdaxisname(flibhndl, &mAxisCount, axes); + if (ret != EW_OK) { - int i = 0; + gLogger->error("Failed to get axis names: %d\n", ret); + exit(999); + } + string activeAxes; - for (i = 0; i < mAxisCount; i++) + for (auto i = 0; i < mAxisCount; i++) { bool add = true; gLogger->info("Axis %d : %c%c", i, axes[i].name, axes[i].suff); if (hasAxisData) { gLogger->info("Axis %s #%d - actual (unit %d flag 0x%X)", - axisData[i].name, i, axisData[i].unit, axisData[i].flag); + axisData[i].name, + i, + axisData[i].unit, + axisData[i].flag); + // Skip this axis if it isn't displayed if ((axisData[i].flag & 0x01) == 0) { @@ -178,96 +197,103 @@ bool FanucPath::configureAxes(unsigned short aFlibhndl) switch (axisData[i].unit) { - case 0: gLogger->info(" Units: mm"); break; - case 1: gLogger->info(" Units: inch"); break; - case 2: gLogger->info(" Units: degree"); break; - case 3: gLogger->info(" Units: mm/minute"); break; - case 4: gLogger->info(" Units: inch/minute"); break; - case 5: gLogger->info(" Units: rpm"); break; - case 6: gLogger->info(" Units: mm/round"); break; - case 7: gLogger->info(" Units: inch/round"); break; - case 8: gLogger->info(" Units: %%"); break; - case 9: gLogger->info(" Units: Ampere"); break; + case 0: + gLogger->info(" Units: mm"); + break; + case 1: + gLogger->info(" Units: inch"); + break; + case 2: + gLogger->info(" Units: degree"); + break; + case 3: + gLogger->info(" Units: mm/minute"); + break; + case 4: + gLogger->info(" Units: inch/minute"); + break; + case 5: + gLogger->info(" Units: rpm"); + break; + case 6: + gLogger->info(" Units: mm/round"); + break; + case 7: + gLogger->info(" Units: inch/round"); + break; + case 8: + gLogger->info(" Units: %%"); + break; + case 9: + gLogger->info(" Units: Ampere"); + break; } } - if (add) - { + if (!add) + continue; + if (mAxes.size() > 0) activeAxes += " "; - char name[12]; - int j = 0; - name[j++] = axes[i].name; - if (axes[i].suff > 0) - name[j++] = axes[i].suff; - name[j] = '\0'; - - activeAxes += name; + std::string axisName = {axes[i].name, axes[i].suff}; + activeAxes.append(axisName.c_str()); - FanucAxis *axis = new FanucAxis(mAdapter, name, i); + auto axis = new FanucAxis(mAdapter, axisName.c_str(), i); mAxes.push_back(axis); - if (axes[i].name == 'X' && (axes[i].suff == 0 || mXAxis == NULL)) + if (axes[i].name == 'X' && (!axes[i].suff || mXAxis == nullptr)) mXAxis = axis; - else if (axes[i].name == 'Y' && (axes[i].suff == 0 || mYAxis == NULL)) + else if (axes[i].name == 'Y' && (!axes[i].suff || mYAxis == nullptr)) mYAxis = axis; - else if (axes[i].name == 'Z' && (axes[i].suff == 0 || mZAxis == NULL)) + else if (axes[i].name == 'Z' && (!axes[i].suff || mZAxis == nullptr)) mZAxis = axis; - } + } mActiveAxes.setValue(activeAxes.c_str()); - } - else - { - gLogger->error("Failed to get axis names: %d\n", ret); - exit(999); - } - - short count, inprec[MAX_AXIS], outprec[MAX_AXIS]; - ret = cnc_getfigure(aFlibhndl, 0, &count, inprec, outprec); - if (ret == EW_OK) - { - for (size_t i = 0; i < mAxes.size(); i++) - mAxes[i]->mDivisor = pow((long double) 10.0, (long double) inprec[i]); - } - else + + + short count, inprec[MAX_AXIS] = {0}, outprec[MAX_AXIS] = {0}; + ret = cnc_getfigure(flibhndl, 0, &count, inprec, outprec); + if (ret != EW_OK) { gLogger->error("Failed to get axis scale: %d\n", ret); return false; } + for (auto i = 0u; i < mAxes.size(); i++) + mAxes[i]->mDivisor = pow((long double) 10.0, (long double) inprec[i]); + return true; } -bool FanucPath::gatherData(unsigned short aFlibhndl) + +bool FanucPath::gatherData(unsigned short flibhndl) { - int ret; - ret = cnc_setpath(aFlibhndl, mPathNumber); + auto ret = cnc_setpath(flibhndl, mPathNumber); if (ret != EW_OK) { gLogger->error("Cannot set path to: %d, %d", ret); return false; } - return getProgramInfo(aFlibhndl) && - getStatus(aFlibhndl) && - getAxisData(aFlibhndl) && - getSpindleData(aFlibhndl) && - getToolData(aFlibhndl); + return getProgramInfo(flibhndl) && + getStatus(flibhndl) && + getAxisData(flibhndl) && + getSpindleData(flibhndl) && + getToolData(flibhndl); } -bool FanucPath::getProgramInfo(unsigned short aFlibhndl) + +bool FanucPath::getProgramInfo(unsigned short flibhndl) { - int ret; - char buf[1024]; + char buf[1024] = {0}; unsigned short len = sizeof(buf); - short num; - ret = cnc_rdexecprog(aFlibhndl, (unsigned short*) &len, &num, buf); + short num(0); + auto ret = cnc_rdexecprog(flibhndl, (unsigned short*) &len, &num, buf); if (ret == EW_OK) { - buf[len] = '\0'; - for (int i = 0; i < len; i++) + for (auto i = 0; i < len; i++) { if (buf[i] == '\n') { @@ -275,9 +301,7 @@ bool FanucPath::getProgramInfo(unsigned short aFlibhndl) break; } } - mBlock.setValue(buf); - return true; } else @@ -287,13 +311,17 @@ bool FanucPath::getProgramInfo(unsigned short aFlibhndl) } } -bool FanucPath::getStatus(unsigned short aFlibhndl) + +bool FanucPath::getStatus(unsigned short flibhndl) { - ODBST status; - memset(&status, 0, sizeof(status)); - int ret = cnc_statinfo(aFlibhndl, &status); - if (ret == EW_OK) + ODBST status = {0}; + auto ret = cnc_statinfo(flibhndl, &status); + if (ret != EW_OK) { + gLogger->error("Cannot cnc_statinfo for path %d: %d", mPathNumber, ret); + return false; + } + if (status.run == 3 || status.run == 4) // STaRT mExecution.setValue(Execution::eACTIVE); else @@ -322,23 +350,19 @@ bool FanucPath::getStatus(unsigned short aFlibhndl) mEStop.setValue(EmergencyStop::eARMED); } return true; -} - else - { - gLogger->error("Cannot cnc_statinfo for path %d: %d", mPathNumber, ret); - return false; - } + } -bool FanucPath::getToolData(unsigned short aFlibhndl) + +bool FanucPath::getToolData(unsigned short flibhndl) { if (mToolManagementEnabled) { - ODBTLIFE4 toolId2; - short ret = cnc_toolnum(aFlibhndl, 0, 0, &toolId2); + ODBTLIFE4 toolId2 = {0}; + auto ret = cnc_toolnum(flibhndl, 0, 0, &toolId2); - ODBTLIFE3 toolId; - ret = cnc_rdntool(aFlibhndl, 0, &toolId); + ODBTLIFE3 toolId = {0}; + ret = cnc_rdntool(flibhndl, 0, &toolId); if (ret == EW_OK && toolId.data != 0) { mToolId.setValue(toolId.data); @@ -355,8 +379,8 @@ bool FanucPath::getToolData(unsigned short aFlibhndl) if (mUseModalToolData) { - ODBMDL command; - short ret = cnc_modal(aFlibhndl, 108, 1, &command); + ODBMDL command {0}; + auto ret = cnc_modal(flibhndl, 108, 1, &command); if (ret == EW_OK) { //gLogger->debug("cnc_modal returned: datano %d and type %d: %d %X %X", @@ -374,68 +398,14 @@ bool FanucPath::getToolData(unsigned short aFlibhndl) return true; } -bool FanucPath::getHeader(unsigned short aFlibhndl, int aProg) -{ - /* This is not needed since we're getting the codes from - macros now. */ - if (!mAllowDNC) - return true; - - char program[2048]; - short ret = cnc_upstart(aFlibhndl, aProg); - if (ret == EW_OK) - { - // One for the \0 terminator - long len = sizeof(program) - 1; - do - { - ret = cnc_upload3(aFlibhndl, &len, program); - if (ret == EW_OK) - { - bool nl = false; - program[len] = '\0'; - int lineCount = 0; - for (char *cp = program; *cp != '\0' && lineCount < 5; ++cp) - { - //printf("%d ", *cp); - // When we get a new line, check for the first empty line - // following with only spaces, ; or carriage returns. If - // a new line follows, then terminate the header and set the - // program comment. - if (*cp == '\n') - { - char f = *(cp + 1); - if (lineCount > 0 && f != '(') - { - *cp = '\0'; - break; - } - *cp = ' '; - lineCount++; - } - } - //printf("\n"); - mProgramComment.setValue(program); - } - } while (ret == EW_BUFFER); - } - cnc_upend3(aFlibhndl); - - return true; -} -bool FanucPath::getAxisData(unsigned short aFlibhndl) +bool FanucPath::getAxisData(unsigned short flibhndl) { if (mAxisCount <= 0) return true; - short ret; - - int maxAxes = MAX_AXIS; - - ODBDY2 dyn; - memset(&dyn, 0xEF, sizeof(dyn)); - ret = cnc_rddynamic2(aFlibhndl, ALL_AXES, sizeof(dyn), &dyn); + ODBDY2 dyn = {0}; + auto ret = cnc_rddynamic2(flibhndl, ALL_AXES, sizeof(dyn), &dyn); if (ret != EW_OK) { gLogger->error("Cannot get the rddynamic2 data for path %d: %d", mPathNumber, ret); @@ -444,73 +414,64 @@ bool FanucPath::getAxisData(unsigned short aFlibhndl) mLine.setValue(dyn.seqnum); - ODBSVLOAD axLoad[MAX_AXIS]; + ODBSVLOAD axLoad[MAX_AXIS] = {0}; short num = MAX_AXIS; - ret = cnc_rdsvmeter(aFlibhndl, &num, axLoad); + ret = cnc_rdsvmeter(flibhndl, &num, axLoad); if (ret != EW_OK) { gLogger->error("cnc_rdsvmeter failed for path %d: %d", mPathNumber, ret); return false; } - char buf[32]; - if (dyn.prgnum != mProgramNum) - getHeader(aFlibhndl, dyn.prgnum); - + char buf[32] = {0}; mProgramNum = dyn.prgnum; sprintf(buf, "%d.%d", dyn.prgmnum, dyn.prgnum); mProgramName.setValue(buf); // Update all the axes - vector::iterator axis; - for (axis = mAxes.begin(); axis != mAxes.end(); axis++) - { - (*axis)->gatherData(&dyn, axLoad); - } + for (auto axis : mAxes) + axis->gatherData(&dyn, axLoad); mPathFeedrate.setValue(dyn.actf); // Get the modal feed for this path - ODBMDL command; - ret = cnc_modal(aFlibhndl, 103, 1, &command); + ODBMDL command = {0}; + ret = cnc_modal(flibhndl, 103, 1, &command); if (ret == EW_OK) - { mCommandedFeedrate.setValue(command.modal.aux.aux_data); - } double x = 0.0, y = 0.0, z = 0.0; - if (mXAxis != NULL) + if (mXAxis) x = dyn.pos.faxis.absolute[mXAxis->mIndex] / mXAxis->mDivisor; - if (mYAxis != NULL) + if (mYAxis) y = dyn.pos.faxis.absolute[mYAxis->mIndex] / mYAxis->mDivisor; - if (mZAxis != NULL) + if (mZAxis) z = dyn.pos.faxis.absolute[mZAxis->mIndex] / mZAxis->mDivisor; mPathPosition.setValue(x, y, z); - getCondition(aFlibhndl, dyn.alarm); - - + getCondition(flibhndl, dyn.alarm); return true; } -bool FanucPath::getSpindleData(unsigned short aFlibhndl) + +bool FanucPath::getSpindleData(unsigned short flibhndl) { if (mSpindleCount <= 0) return true; // Handle spindle data... - ODBACT2 speeds; - int ret = cnc_acts2(aFlibhndl, ALL_SPINDLES, &speeds); + ODBACT2 speeds = {0}; + auto ret = cnc_acts2(flibhndl, ALL_SPINDLES, &speeds); if (ret != EW_OK) { gLogger->error("cnc_acts2 failed: %d for path number: %d", ret, mPathNumber); return false; } - ODBSPLOAD spLoad[MAX_SPINDLE]; + ODBSPLOAD spLoad[MAX_SPINDLE] = {0}; short num = MAX_SPINDLE; - ret = cnc_rdspmeter(aFlibhndl, 0, &num, spLoad); + ret = cnc_rdspmeter(flibhndl, 0, &num, spLoad); if (ret != EW_OK) { gLogger->error("cnc_rdspmeter failed: %d", ret); @@ -525,18 +486,16 @@ bool FanucPath::getSpindleData(unsigned short aFlibhndl) } // Update all the axes - vector::iterator spindle; - for (spindle = mSpindles.begin(); spindle != mSpindles.end(); spindle++) - { - (*spindle)->gatherData(spLoad, &speeds); - } + for (auto spindle : mSpindles) + spindle->gatherData(spLoad, &speeds); return true; } -Condition *FanucPath::translateAlarmNo(long aNum, int aAxis) + +Condition *FanucPath::translateAlarmNo(long num, int axis) { - switch(aNum) + switch(num) { case 0: // Parameter Switch Off return &mLogic; @@ -546,20 +505,20 @@ Condition *FanucPath::translateAlarmNo(long aNum, int aAxis) return &mComms; case 4: // Overtravel - if (aAxis > 0) - return &(mAxes[aAxis - 1]->mTravel); + if (axis > 0) + return &(mAxes[axis - 1]->mTravel); else return &mSystem; case 5: // Overheat - if (aAxis > 0) - return &(mAxes[aAxis - 1]->mOverheat); + if (axis > 0) + return &(mAxes[axis - 1]->mOverheat); else return &mSystem; case 6: // Servo - if (aAxis > 0) - return &(mAxes[aAxis - 1]->mServo); + if (axis > 0) + return &(mAxes[axis - 1]->mServo); else return &mServo; @@ -578,38 +537,41 @@ Condition *FanucPath::translateAlarmNo(long aNum, int aAxis) return &mSystem; } - return NULL; + return nullptr; } -void FanucPath::getCondition(unsigned short aFlibhndl, long aAlarm) -{ - if (aAlarm != 0) + +void FanucPath::getCondition(unsigned short flibhndl, long alarm) { - for (int i = 0; i < 31; i++) + if (!alarm) + return; + + // Check each bit in turn, if any are set then get the associated error information + // Only the first 20 bits are used. + for (auto i = 0; i < 20; i++) { - if (aAlarm & (0x1 << i)) + if (alarm & (0x1 << i)) { - ODBALMMSG2 alarms[MAX_AXIS]; + ODBALMMSG2 alarms[MAX_AXIS] = {0}; short num = MAX_AXIS; - - short ret = cnc_rdalmmsg2(aFlibhndl, i, &num, alarms); + auto ret = cnc_rdalmmsg2(flibhndl, i, &num, alarms); if (ret != EW_OK) continue; - for (int j = 0; j < num; j++) + for (auto j = 0; j < num; j++) { - ODBALMMSG2 &alarm = alarms[j]; - char num[16]; - - Condition *cond = translateAlarmNo(i, alarm.axis); - if (cond == NULL) + auto const &focasAlarm = alarms[j]; + auto condition = translateAlarmNo(i, focasAlarm.axis); + if (!condition) continue; - - sprintf(num, "%d", alarm.alm_no); - cond->add(Condition::eFAULT, alarm.alm_msg, num); - } + std::string alarmMessage(focasAlarm.alm_msg, focasAlarm.msg_len); + condition->add( + Condition::eFAULT, + alarmMessage.c_str(), + std::to_string(focasAlarm.alm_no).c_str()); } } } + } diff --git a/fanuc/fanuc_path.hpp b/fanuc/fanuc_path.hpp index ab98450..2e664b6 100644 --- a/fanuc/fanuc_path.hpp +++ b/fanuc/fanuc_path.hpp @@ -21,45 +21,45 @@ #include "fanuc_axis.hpp" #include + class StaticEvent : public Event { public: - StaticEvent(const char *aName = "") : Event(aName) {} - - virtual bool unavailable() { - return false; + StaticEvent(const char *name = "") : + Event(name) + { } + + bool unavailable() override { + return false; } }; + class FanucPath { public: - FanucPath(Adapter *anAdapter, short aPathNumber); + FanucPath(Adapter *adapter, short pathNumber); ~FanucPath(); - void allowDNC(const bool aAllow) { mAllowDNC = aAllow; } - bool configure(unsigned short mFlibhndl); - bool gatherData(unsigned short mFlibhndl); + bool configure(unsigned short flibhndl); + bool gatherData(unsigned short flibhndl); protected: - bool configureAxes(unsigned short mFlibhndl); - bool configureSpindles(unsigned short mFlibhndl); - - bool getToolData(unsigned short aFlibhndl); - bool getProgramInfo(unsigned short mFlibhndl); - bool getStatus(unsigned short mFlibhndl); - bool getHeader(unsigned short aFlibhndl, int aProg); - bool getAxisData(unsigned short aFlibhndl); - bool getSpindleData(unsigned short aFlibhndl); + bool configureAxes(unsigned short flibhndl); + bool configureSpindles(unsigned short flibhndl); - void getCondition(unsigned short aFlibhndl, long aAlarm); - Condition *translateAlarmNo(long aNum, int aAxis); + bool getToolData(unsigned short flibhndl); + bool getProgramInfo(unsigned short flibhndl); + bool getStatus(unsigned short flibhndl); + bool getAxisData(unsigned short flibhndl); + bool getSpindleData(unsigned short flibhndl); + void getCondition(unsigned short flibhndl, long alarm); + Condition *translateAlarmNo(long num, int axis); - void addDatum(DeviceDatum &aDatum, const char *aName, const char *aSuffix); + void addDatum(DeviceDatum &datum, const char *name, const char *suffix); protected: - bool mConfigured; Adapter *mAdapter; short mPathNumber; @@ -86,7 +86,6 @@ class FanucPath bool mToolManagementEnabled; bool mUseModalToolData; - bool mAllowDNC; // Path related conditions Condition mServo; From b225759b444f378f5cb047a2a8ac001f832b4a8d Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:15:03 +0100 Subject: [PATCH 14/41] C++11 Conversion: Conversion of 'DeviceDatum' and derived classes --- src/condition.cpp | 324 ++++++++++++--------- src/condition.hpp | 146 ++++++---- src/configuration.cpp | 81 ++++-- src/configuration.hpp | 82 +++--- src/device_datum.cpp | 648 +++++++++++++++++++++++++++--------------- src/device_datum.hpp | 365 +++++++++++++++--------- 6 files changed, 1037 insertions(+), 609 deletions(-) diff --git a/src/condition.cpp b/src/condition.cpp index 97ab71c..9de3f56 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -32,182 +32,225 @@ // #include "internal.hpp" #include "condition.hpp" +#include #include "string_buffer.hpp" // Condition -Condition::Condition(const char *aName, bool aSimple) : - DeviceDatum(aName), mBegun(false), mSimple(aSimple) + +Condition::Condition(const char *name, bool simple) : + DeviceDatum(name), + mBegun(false), + mPrepared(false), + mSimple(simple) { - mActiveSize = mInitialActiveListSize; - mActiveCount = 0; - mActiveList = new ActiveCondition*[mActiveSize]; + mActiveList.reserve(mInitialActiveListSize); mHasValue = true; unavailable(); } + Condition::~Condition() { removeAll(); - delete[] mActiveList; } + void Condition::removeAll() { - for (int i = 0; i < mActiveCount; i++) - delete mActiveList[i]; - mActiveCount = 0; + for(auto condition : mActiveList) + delete condition; + mActiveList.clear(); } -bool Condition::requiresFlush() + +bool Condition::requiresFlush() const { return true; } + bool Condition::unavailable() { return add(eUNAVAILABLE); } -char *Condition::toString(char *aBuffer, int aMaxLen) + +char *Condition::toString(char *, int ) { - return NULL; + return nullptr; } + void Condition::begin() { - if (!mSimple) { - for (int i = 0; i < mActiveCount; i++) { - mActiveList[i]->clear(); - } + if (!mSimple) + { + for(auto condition : mActiveList) + condition->clear(); } + mPrepared = false; mBegun = true; mChanged = false; } + void Condition::cleanup() { mBegun = false; mPrepared = false; } + void Condition::initialize() { normal(); } -void Condition::append(StringBuffer &aStringBuffer, char *aBuffer, - ActiveCondition *aCond, bool &aFirst, int aMaxLen) + +void Condition::append( + StringBuffer &stringBuffer, + char *buffer, + ActiveCondition *condition, + bool &first, + int maxLen) { - if (!aFirst) - aStringBuffer.newline(); + if (!first) + stringBuffer.newline(); else - aFirst = false; + first = false; - char *cp = aBuffer + strlen(aBuffer); + auto cp = buffer + strlen(buffer); + condition->toString(cp, maxLen); - aCond->toString(cp, aMaxLen); - appendText(aBuffer, (char*) aCond->getText(), aMaxLen); - aStringBuffer.append(aBuffer); + appendText(buffer, const_cast(condition->getText()), maxLen); + stringBuffer.append(buffer); } + void Condition::prepare() { - if (mBegun) - { + if (!mBegun) + return; + bool marked = false; // Check to see if we have no marked conditions - for (int i = 0; !marked && i < mActiveCount; i++) + for(auto condition : mActiveList) + { + if (condition->isPlaceHolder() || condition->isMarked()) { - if (mActiveList[i]->isPlaceHolder() || mActiveList[i]->isMarked()) marked = true; + break; + } } if (!marked) normal(); // Sweep old conditions - for (int i = mActiveCount - 1; i >= 0; i--) - { - ActiveCondition *cond = mActiveList[i]; - if (!cond->isPlaceHolder() && !cond->isMarked()) + for(auto conditionIter = mActiveList.crbegin();conditionIter != mActiveList.crend(); conditionIter++) { - cond->setValue(eNORMAL, "", cond->getNativeCode()); - } + auto condition = *conditionIter; + if (!condition->isPlaceHolder() && !condition->isMarked()) + condition->setValue(eNORMAL, "", condition->getNativeCode()); - if (cond->hasChanged()) { + if (condition->hasChanged()) mChanged = true; } - } + mPrepared = true; - } } -bool Condition::append(StringBuffer &aBuffer) + +bool Condition::append(StringBuffer &stringBuffer) { if (!mBegun) { - char buffer[1024]; + char buffer[1024] = {0}; bool first = true; buffer[0] = '|'; strcpy(buffer + 1, mName); - char *cp = buffer + strlen(buffer); - int max = 1024 - strlen(buffer); - for (int i = 0; i < mActiveCount; i++) + auto cp = buffer + strlen(buffer); + auto max = 1024u - strlen(buffer); + + for(auto condition : mActiveList) { *cp = '\0'; - append(aBuffer, buffer, mActiveList[i], first, max); + append(stringBuffer, buffer, condition, first, max); } - } else if (mBegun && mPrepared) { - char buffer[1024]; + } + else if (mBegun && mPrepared) + { + char buffer[1024] {0}; bool first = true; buffer[0] = '|'; strcpy(buffer + 1, mName); - char *cp = buffer + strlen(buffer); - int max = 1024 - strlen(buffer); + auto cp = buffer + strlen(buffer); + auto max = 1024u - strlen(buffer); // Sweep old conditions - for (int i = mActiveCount - 1; i >= 0; i--) + // Update any that have changed + for(auto conditionIter = mActiveList.crbegin(); conditionIter != mActiveList.crend(); conditionIter++) + { + auto condition = *conditionIter; + if(condition->hasChanged()) { - ActiveCondition *cond = mActiveList[i]; - if (cond->hasChanged()) { *cp = '\0'; - append(aBuffer, buffer, cond, first, max); + append(stringBuffer, buffer, condition, first, max); + } } - // Remove stale conditions since they have now been generated. - if (!cond->isPlaceHolder() && !cond->isMarked()) - removeAt(i); + // Update our container to move items to be deleted to the end + auto removeRange = std::remove_if(mActiveList.begin(), mActiveList.end(), [](ActiveCondition *condition) + { + if( !condition->isPlaceHolder() && !condition->isMarked() ) + { + delete condition; condition = nullptr; + return true; } + else + return false; + }); + + // Remove items from the container if required + if(removeRange != mActiveList.end()) + mActiveList.erase(removeRange); } return mChanged; } -bool Condition::isActive(const char *aNativeCode) + +bool Condition::isActive(const char *nativeCode) const { - for (int i = 0; i < mActiveCount; i++) { - if (strcmp(aNativeCode, mActiveList[i]->getNativeCode()) == 0) - return true; - } + auto findPos = std::find_if(mActiveList.cbegin(), mActiveList.cend(), [nativeCode](const ActiveCondition *condition) + { + return !strcmp(nativeCode, condition->getNativeCode()); + }); - return false; + return findPos != mActiveList.cend(); } -bool Condition::add(ELevels aLevel, const char *aText, const char *aCode, - const char *aQualifier, const char *aSeverity) + +bool Condition::add( + ELevels level, + const char *text, + const char *code, + const char *qualifier, + const char *severity) { - ActiveCondition *cond = NULL; - bool res; + bool res(false); + // First check for a unassociated normal or a unavailable. - if ((aLevel == eNORMAL || aLevel == eUNAVAILABLE) && - aCode[0] == '\0') + if ((level == eNORMAL || level == eUNAVAILABLE) && + code[0] == '\0') { // See if we are already in this state. - if (mActiveCount == 1 && mActiveList[0]->getNativeCode()[0] == '\0' && - mActiveList[0]->getLevel() == aLevel) + if (mActiveList.size() == 1u && + mActiveList[0]->getNativeCode()[0] == '\0' && + mActiveList[0]->getLevel() == level) { mActiveList[0]->mark(); res = false; @@ -216,14 +259,13 @@ bool Condition::add(ELevels aLevel, const char *aText, const char *aCode, { // Clear all existing conditions and add one with this state. removeAll(); - cond = new ActiveCondition(aLevel); - add(cond); + add( new ActiveCondition(level) ); res = mChanged = true; } } else { - if (mActiveCount == 1 && + if (mActiveList.size() == 1u && (mActiveList[0]->getLevel() == eNORMAL || mActiveList[0]->getLevel() == eUNAVAILABLE)) { @@ -231,21 +273,21 @@ bool Condition::add(ELevels aLevel, const char *aText, const char *aCode, } // We have a code specific condition or a ab-normal - int i; - for (i = 0; i < mActiveCount; i++) - if (strcmp(aCode, mActiveList[i]->getNativeCode()) == 0) - break; + auto conditionPos = std::find_if(mActiveList.cbegin(), mActiveList.cend(), [code](ActiveCondition* condition) + { + return !strcmp(code, condition->getNativeCode()); + }); - if (i < mActiveCount) + if(conditionPos != mActiveList.cend()) { - res = mChanged = mActiveList[i]->setValue(aLevel, aText, aCode, aQualifier, aSeverity); - mActiveList[i]->mark(); + auto condition = *conditionPos; + res = mChanged = condition->setValue(level, text, code, qualifier, severity); + condition->mark(); } else { // New condition - cond = new ActiveCondition(aLevel, aText, aCode, aQualifier, aSeverity); - add(cond); + add( new ActiveCondition(level, text, code, qualifier, severity) ); res = mChanged = true; } } @@ -253,94 +295,100 @@ bool Condition::add(ELevels aLevel, const char *aText, const char *aCode, return res; } -void Condition::remove(const char *aCode) + +void Condition::remove(const char *code) { // We have a code specific condition or a ab-normal - int i; - for (i = 0; i < mActiveCount; i++) { - if (strcmp(aCode, mActiveList[i]->getNativeCode()) == 0) { - if (mActiveCount == 1) + auto conditionPos = std::find_if(mActiveList.cbegin(), mActiveList.cend(), [code](ActiveCondition* condition) + { + return !strcmp(code, condition->getNativeCode()); + }); + + if(conditionPos != mActiveList.cend()) + { + if(mActiveList.size() == 1u) normal(); - else { - mActiveList[i]->setValue(eNORMAL, "", aCode); - mActiveList[i]->clear(); - } - mChanged = true; - break; + else + { + (*conditionPos)->setValue(eNORMAL, "", code); + (*conditionPos)->clear(); } } } -void Condition::add(ActiveCondition *aCond) +void Condition::add(ActiveCondition *condition) { - if (mActiveCount >= mActiveSize) - { - ActiveCondition **newList = new ActiveCondition*[mActiveSize * 2]; - memcpy(newList, mActiveList, sizeof(ActiveCondition*) * mActiveSize); - delete mActiveList; - mActiveList = newList; - mActiveSize *= 2; - } - - mActiveList[mActiveCount++] = aCond; + // If we are approaching our capacity then resize + if(mActiveList.size() == mActiveList.capacity()) + mActiveList.reserve(mActiveList.capacity() * 2u); + + mActiveList.push_back(condition); } -bool Condition::removeAt(int i) + +char *Condition::ActiveCondition::toString(char *buffer, int aMaxLen) { - if (i < 0 || i >= mActiveCount) - return false; + const char *text = nullptr; - delete mActiveList[i]; - mActiveCount--; - memmove(mActiveList + i, mActiveList + i + 1, - sizeof(ActiveCondition*) * (mActiveCount - i)); + switch (mLevel) + { + case eUNAVAILABLE: + text = "UNAVAILABLE"; + break; - return true; -} + case eNORMAL: + text = "NORMAL"; + break; -char *Condition::ActiveCondition::toString(char *aBuffer, int aMaxLen) -{ - const char *text; - switch(mLevel) - { - case eUNAVAILABLE: text = "UNAVAILABLE"; break; - case eNORMAL: text = "NORMAL"; break; - case eWARNING: text = "WARNING"; break; - case eFAULT: text = "FAULT"; break; - default: text = ""; break; + case eWARNING: + text = "WARNING"; + break; + + case eFAULT: + text = "FAULT"; + break; + + default: + text = ""; + break; } - snprintf(aBuffer, aMaxLen, "|%s|%s|%s|%s|", text, mNativeCode, mNativeSeverity, - mQualifier); + + snprintf(buffer, aMaxLen, "|%s|%s|%s|%s|", text, mNativeCode, mNativeSeverity, mQualifier); mChanged = false; - return aBuffer; + return buffer; } -bool Condition::ActiveCondition::setValue(ELevels aLevel, const char *aText, const char *aCode, - const char *aQualifier, const char *aSeverity) + +bool Condition::ActiveCondition::setValue( + ELevels level, + const char *text, + const char *code, + const char *qualifier, + const char *severity) { - if ((aLevel == eNORMAL || aLevel == eUNAVAILABLE) && aCode[0] == '\0') + if ((level == eNORMAL || level == eUNAVAILABLE) && code[0] == '\0') mPlaceHolder = true; - if (mLevel != aLevel || - strncmp(aCode, mNativeCode, EVENT_VALUE_LEN) != 0 || - strncmp(aQualifier, mQualifier, EVENT_VALUE_LEN) != 0 || - strncmp(aSeverity, mNativeSeverity, EVENT_VALUE_LEN) != 0 || - strncmp(aText, mText, EVENT_VALUE_LEN) != 0) + if (mLevel != level || + strncmp(code, mNativeCode, EVENT_VALUE_LEN) || + strncmp(qualifier, mQualifier, EVENT_VALUE_LEN) || + strncmp(severity, mNativeSeverity, EVENT_VALUE_LEN) || + strncmp(text, mText, EVENT_VALUE_LEN)) { - mLevel = aLevel; + mLevel = level; - strncpy(mNativeCode, aCode, EVENT_VALUE_LEN); + strncpy(mNativeCode, code, EVENT_VALUE_LEN); mNativeCode[EVENT_VALUE_LEN - 1] = '\0'; - strncpy(mQualifier, aQualifier, EVENT_VALUE_LEN); + strncpy(mQualifier, qualifier, EVENT_VALUE_LEN); mQualifier[EVENT_VALUE_LEN - 1] = '\0'; - strncpy(mNativeSeverity, aSeverity, EVENT_VALUE_LEN); + strncpy(mNativeSeverity, severity, EVENT_VALUE_LEN); mNativeSeverity[EVENT_VALUE_LEN - 1] = '\0'; - strncpy(mText, aText, EVENT_VALUE_LEN); + strncpy(mText, text, EVENT_VALUE_LEN); mText[EVENT_VALUE_LEN - 1] = '\0'; mChanged = true; diff --git a/src/condition.hpp b/src/condition.hpp index 8f1b6c8..2525bc1 100644 --- a/src/condition.hpp +++ b/src/condition.hpp @@ -32,6 +32,8 @@ // #pragma once +#include + // The conditon items #include "device_datum.hpp" @@ -39,7 +41,8 @@ class Condition : public DeviceDatum { public: - enum ELevels { + enum ELevels + { eUNAVAILABLE, eNORMAL, eWARNING, @@ -61,72 +64,117 @@ class Condition : public DeviceDatum bool mPlaceHolder; public: - ActiveCondition() : mChanged(true), mMarked(true), mPlaceHolder(false) { - mNativeCode[0] = mNativeSeverity[0] = mText[0] = - mQualifier[0] = 0; - } - ActiveCondition(ELevels aLevel, const char *aText = "", const char *aCode = "", - const char *aQualifier = "", const char *aSeverity = "") - : mChanged(true), mMarked(true), mPlaceHolder(false) + ActiveCondition() : + mLevel(eUNAVAILABLE), + mText{0}, + mNativeCode{0}, + mNativeSeverity{0}, + mQualifier{0}, + mChanged(true), + mMarked(true), + mPlaceHolder(false) + { + } + + ActiveCondition( + ELevels level, + const char *text = "", + const char *code = "", + const char *qualifier = "", + const char *severity = "") + : + mText{0}, + mNativeCode{0}, + mNativeSeverity{0}, + mQualifier{0}, + mChanged(true), + mMarked(true), + mPlaceHolder(false) { - setValue(aLevel, aText, aCode, aQualifier, aSeverity); + setValue(level, text, code, qualifier, severity); } - bool setValue(ELevels aLevel, const char *aText = "", const char *aCode = "", - const char *aQualifier = "", const char *aSeverity = ""); - - char *toString(char *aBuffer, int aMaxLen); - bool hasChanged() { return mChanged; } - - ELevels getLevel() { return mLevel; } - const char *getText() { return mText; } - const char *getNativeCode() { return mNativeCode; } - const char *getNativeSeverity() { return mNativeSeverity; } - const char *getQualifier() { return mQualifier; } - - void clear() { mMarked = false; } - void mark() { mMarked = true; } - bool isMarked() { return mMarked; } - bool isPlaceHolder() { return mPlaceHolder; } + ~ActiveCondition() + { + } + + bool setValue( + ELevels level, + const char *text = "", + const char *code = "", + const char *qualifier = "", + const char *severity = ""); + + char *toString(char *bBuffer, int maxLen); + bool hasChanged() const { + return mChanged; } + + ELevels getLevel() const { + return mLevel; } + const char *getText() const { + return mText; } + const char *getNativeCode() const { + return mNativeCode; } + const char *getNativeSeverity() const { + return mNativeSeverity; } + const char *getQualifier() const { + return mQualifier; } + + void clear() { + mMarked = false; } + void mark() { + mMarked = true; } + bool isMarked() const { + return mMarked; } + bool isPlaceHolder() const { + return mPlaceHolder; } }; protected: - ActiveCondition **mActiveList; - int mActiveSize; - int mActiveCount; + std::vector mActiveList; static const int mInitialActiveListSize = 16; bool mBegun; bool mPrepared; bool mSimple; - void add(ActiveCondition *aCondition); - bool removeAt(int i); + void add(ActiveCondition *condition); - void append(StringBuffer &aStringBuffer, char *aBuffer, ActiveCondition *aCond, - bool &aFirst, int aMaxLen); + void append( + StringBuffer &stringBuffer, + char *buffer, + ActiveCondition *cond, + bool &first, + int maxLen); public: - Condition(const char *aName = "", bool aSimple = false); + Condition(const char *name = "", bool simple = false); virtual ~Condition(); - virtual char *toString(char *aBuffer, int aMaxLen); - - virtual bool requiresFlush(); - virtual bool unavailable(); - virtual bool append(StringBuffer &aBuffer); - bool add(ELevels aLevel, const char *aText = "", const char *aCode = "", - const char *aQualifier = "", const char *aSeverity = ""); - void remove(const char *aCode); + bool add( + ELevels level, + const char *text = "", + const char *code = "", + const char *qualifier = "", + const char *severity = ""); + void remove(const char *code); void removeAll(); - bool normal() { return add(eNORMAL); } - bool isActive(const char *aNativeCode); - void setSimple() { mSimple = true; } - - virtual void begin(); - virtual void prepare(); - virtual void cleanup(); - virtual void initialize(); + bool normal() { + return add(eNORMAL); } + bool isActive(const char *nativeCode) const; + void setSimple() { + mSimple = true; } + +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool requiresFlush() const override; + bool unavailable() override; + bool append(StringBuffer &buffer) override; + void begin() override; + void prepare() override; + void cleanup() override; + void initialize() override; }; diff --git a/src/configuration.cpp b/src/configuration.cpp index bfdaff9..f3116ad 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -35,46 +35,79 @@ using namespace std; -Configuration::Configuration() - : mPort(7878), mScanDelay(1000), mTimeout(10000) +template +void set_with_default(const YAML::Node &node, const char *key, T& value, V def) +{ + if (node.FindValue(key) != nullptr) + node[key] >> value; + else + value = def; +} + +template +void set_if_present(const YAML::Node &node, const char *key, T& value) +{ + if (node.FindValue(key) != nullptr) + node[key] >> value; +} + + +Configuration::Configuration() : + mPort(7878), + mScanDelay(1000), + mTimeout(10000) { } -void Configuration::parse(istream &aStream, int aPort, int aDelay, int aTimeout, const char *aService) + +Configuration::~Configuration() { - YAML::Parser parser(aStream); +} + + +void Configuration::parse( + istream &stream, + int port, + int delay, + int timeout, + const char *service) +{ + YAML::Parser parser(stream); YAML::Node doc; parser.GetNextDocument(doc); - parse(doc, aPort, aDelay, aTimeout, aService); + parse(doc, port, delay, timeout, service); } -void Configuration::parse(YAML::Node &aDoc, int aPort, int aDelay, int aTimeout, const char *aService) + +void Configuration::parse( + YAML::Node &doc, + int port, + int delay, + int timeout, + const char *service) { - if (aDoc.FindValue("adapter") != NULL) + if (doc.FindValue("adapter")) { - const YAML::Node &adapter = aDoc["adapter"]; - SET_WITH_DEFAULT(adapter, "port", mPort, aPort); - SET_WITH_DEFAULT(adapter, "scanDelay", mScanDelay, aDelay); - SET_WITH_DEFAULT(adapter, "timeout", mTimeout, aTimeout); - SET_WITH_DEFAULT(adapter, "service", mServiceName, aService); + const YAML::Node &adapter = doc["adapter"]; + set_with_default(adapter, "port", mPort, port); + set_with_default(adapter, "scanDelay", mScanDelay, delay); + set_with_default(adapter, "timeout", mTimeout, timeout); + set_with_default(adapter, "service", mServiceName, service); } else { - mPort = aPort; - mScanDelay = aDelay; - mTimeout = aTimeout; - mServiceName = aService; + mPort = port; + mScanDelay = delay; + mTimeout = timeout; + mServiceName = service; } } -Configuration::~Configuration() -{ -} -RegisterSet *Configuration::getRegisters(string &aName) +RegisterSet *Configuration::getRegisters(string &aName) const { - return mRegisters[aName]; + auto regPos = mRegisters.find(aName); + if(regPos != mRegisters.cend()) + return regPos->second; + return nullptr; } - - - diff --git a/src/configuration.hpp b/src/configuration.hpp index 05c18e6..23fb816 100644 --- a/src/configuration.hpp +++ b/src/configuration.hpp @@ -36,21 +36,14 @@ #include #include +// Forward Declarations class DeviceDatum; -namespace YAML { +namespace YAML +{ class Parser; class Node; } -#define SET_WITH_DEFAULT(node, key, value, def) \ - if (node.FindValue(key) != NULL) \ - node[key] >> value; \ - else \ - value = def - -#define SET_IF_PRESENT(node, key, value) \ - if (node.FindValue(key) != NULL) \ - node[key] >> value; // A register represents a PLC/PMC register as an accessible unit. The // value of the register will manifest as a typed value or a @@ -72,17 +65,26 @@ class Register TEXT }; - Register(EType aType, int aOffset, bool aTimeSeries = false) { - mType = aType; - mOffset = aOffset; - mTimeseries = aTimeSeries; + Register(EType type, int offset, bool timeSeries = false) : + mType(type), + mOffset(offset), + mTimeseries(timeSeries), + mScaler(0.0), + mScalerOffset(0), + mCount(0), + mDatum(nullptr) + { } - ~Register(); - Register(Register &aRegister) { - mType = aRegister.mType; - mOffset = aRegister.mOffset; - mTimeseries = aRegister.mTimeseries; + Register(Register &anotherRegister) : + mType(anotherRegister.mType), + mOffset(anotherRegister.mOffset), + mTimeseries(anotherRegister.mTimeseries), + mScaler(0.0), + mScalerOffset(0), + mCount(0), + mDatum(nullptr) + { } protected: @@ -96,45 +98,61 @@ class Register DeviceDatum *mDatum; }; + class RegisterSet { - void addRegister(Register &aRegister) { mRegisters.push_back(&aRegister); } + void addRegister(Register &newRegister) { + mRegisters.push_back(&newRegister); } protected: int mAddress; int mLength; int mCount; - std::vector mRegisters; + std::vector mRegisters; }; + class Configuration { public: Configuration(); virtual ~Configuration(); - virtual void parse(std::istream &aStream, int aPort = 7878, int aDelay = 1000, - int aTimeout = 10000, const char *aService = "MTConnect Adapter"); + virtual void parse( + std::istream &stream, + int port = 7878, + int delay = 1000, + int timeout = 10000, + const char *service = "MTConnect Adapter"); - int getPort() const { return mPort; } - int getScanDelay() const { return mScanDelay; } - int getTimeout() const { return mTimeout; } - const std::string &getServiceName() const { return mServiceName; } + int getPort() const { + return mPort; } + int getScanDelay() const { + return mScanDelay; } + int getTimeout() const { + return mTimeout; } + const std::string &getServiceName() const { + return mServiceName; } - void setPort(int aPort) { mPort = aPort; } + void setPort(int aPort) { + mPort = aPort; } - RegisterSet *getRegisters(std::string &aName); + RegisterSet *getRegisters(std::string &name) const; protected: - virtual void parse(YAML::Node &aDoc, int aPort, int aDelay, int aTimeout, const char *aService); + virtual void parse( + YAML::Node &aDoc, + int aPort, + int aDelay, + int aTimeout, + const char *aService); protected: int mPort; int mScanDelay; int mTimeout; std::string mServiceName; - - std::map mRegisters; + std::map mRegisters; }; diff --git a/src/device_datum.cpp b/src/device_datum.cpp index 8f06463..74ea9af 100755 --- a/src/device_datum.cpp +++ b/src/device_datum.cpp @@ -36,12 +36,10 @@ static const char *sUnavailable = "UNAVAILABLE"; -/* - * Data value methods. - */ -DeviceDatum::DeviceDatum(const char *aName) + +DeviceDatum::DeviceDatum(const char *name) { - strncpy(mName, aName, NAME_LEN); + strncpy(mName, name, NAME_LEN); mName[NAME_LEN - 1] = '\0'; strcpy(mOrigName, mName); mChanged = false; @@ -53,119 +51,131 @@ DeviceDatum::~DeviceDatum() { } -bool DeviceDatum::prefixName(const char *aName) + +bool DeviceDatum::prefixName(const char *name) { // Check for overflow. - int len = strlen(aName); + auto len = strlen(name); if (strlen(mOrigName) + len >= (size_t) NAME_LEN) return false; - strcpy(mName, aName); + strcpy(mName, name); mName[len++] = ':'; strcpy(mName + len, mOrigName); // Make sure the whole thing is terminated mName[NAME_LEN - 1] = '\0'; - return true; } -void DeviceDatum::setName(const char *aName) + +void DeviceDatum::setName(const char *name) { - strncpy(mName, aName, NAME_LEN); + strncpy(mName, name, NAME_LEN); mName[NAME_LEN - 1] = '\0'; strcpy(mOrigName, mName); } -void DeviceDatum::setNativeUnits(const char *aUnits) + +void DeviceDatum::setNativeUnits(const char *units) { - strncpy(mNativeUnits, aUnits, UNITS_LEN); + strncpy(mNativeUnits, units, UNITS_LEN); mNativeUnits[UNITS_LEN - 1] = '\0'; } -bool DeviceDatum::append(StringBuffer &aBuffer) + +bool DeviceDatum::append(StringBuffer &stringBuffer) { char buffer[1024]; - aBuffer.append(toString(buffer, 1024)); + stringBuffer.append(toString(buffer, 1024)); mChanged = false; return mChanged; } -bool DeviceDatum::hasInitialValue() + +bool DeviceDatum::hasInitialValue() const { return mHasValue; } -bool DeviceDatum::requiresFlush() + +bool DeviceDatum::requiresFlush() const { return false; } + // Append text to the buffer and remove all and characters. -void DeviceDatum::appendText(char *aBuffer, char *aValue, int aMaxLen) +void DeviceDatum::appendText(char *buffer, char *value, int maxLen) { - size_t len = strlen(aBuffer); - char *cp = aValue, *dp = aBuffer + len; - for (size_t i = len; i < (size_t) aMaxLen && *cp != '\0'; i++) + auto len = strlen(buffer); + auto cp = value; + auto dp = buffer + len; + + for (auto i = len; i < (size_t)maxLen && *cp != '\0'; i++) { if (*cp == '\n' || *cp == '\r') *dp = ' '; else *dp = *cp; - dp++; cp++; + + dp++; + cp++; } + *dp = '\0'; } -/* - * Event methods - */ -Event::Event(const char* aName) : - DeviceDatum(aName) + +Event::Event(const char *name) : + DeviceDatum(name), + mValue{0} { - mValue[0] = 0; } -bool Event::setValue(const char *aValue) + +bool Event::setValue(const char *value) { - if (strncmp(aValue, mValue, EVENT_VALUE_LEN) != 0 || !mHasValue) + if (strncmp(value, mValue, EVENT_VALUE_LEN) != 0 || !mHasValue) { mChanged = true; - strncpy(mValue, aValue, EVENT_VALUE_LEN); + strncpy(mValue, value, EVENT_VALUE_LEN); mValue[EVENT_VALUE_LEN - 1] = '\0'; mHasValue = true; } + return mChanged; } -char *Event::toString(char *aBuffer, int aMaxLen) + +char *Event::toString(char *buffer, int maxLen) { - snprintf(aBuffer, aMaxLen, "|%s|", mName); - appendText(aBuffer, mValue, aMaxLen); - return aBuffer; + snprintf(buffer, maxLen, "|%s|", mName); + appendText(buffer, mValue, maxLen); + return buffer; } + bool Event::unavailable() { return setValue(sUnavailable); } -/* - * IntEvent methods - */ -IntEvent::IntEvent(const char *aName) - : DeviceDatum(aName) + +IntEvent::IntEvent(const char *name) : + DeviceDatum(name), + mValue{0}, + mUnavailable(false) { - mValue = 0; - mUnavailable = false; } -bool IntEvent::setValue(int aValue) + +bool IntEvent::setValue(int value) { - if (aValue != mValue || !mHasValue || mUnavailable) + if (value != mValue || !mHasValue || mUnavailable) { mChanged = true; - mValue = aValue; + mValue = value; mHasValue = true; mUnavailable = false; } @@ -173,16 +183,18 @@ bool IntEvent::setValue(int aValue) return mChanged; } -char *IntEvent::toString(char *aBuffer, int aMaxLen) + +char *IntEvent::toString(char *buffer, int maxLen) { if (mUnavailable) - snprintf(aBuffer, aMaxLen, "|%s|UNAVAILABLE", mName); + snprintf(buffer, maxLen, "|%s|UNAVAILABLE", mName); else - snprintf(aBuffer, aMaxLen, "|%s|%d", mName, mValue); + snprintf(buffer, maxLen, "|%s|%d", mName, mValue); - return aBuffer; + return buffer; } + bool IntEvent::unavailable() { if (!mUnavailable) @@ -194,38 +206,43 @@ bool IntEvent::unavailable() return mChanged; } -/* - * Sample methods - */ -Sample::Sample(const char *aName, double aEpsilon) - : DeviceDatum(aName), mEpsilon(aEpsilon) + +Sample::Sample(const char *name, double epsilon) : + DeviceDatum(name), + mValue(0.0), + mUnavailable(false), + mEpsilon(epsilon) { - mValue = 0.0; - mUnavailable = false; } -bool Sample::setValue(double aValue) + +bool Sample::setValue(double value) { - if (fabs(aValue - mValue) > mEpsilon || !mHasValue || - mUnavailable) + if (fabs(value - mValue) > mEpsilon || + !mHasValue || + mUnavailable ) { mChanged = true; - mValue = aValue; + mValue = value; mHasValue = true; mUnavailable = false; } + return mChanged; } -char *Sample::toString(char *aBuffer, int aMaxLen) + +char *Sample::toString(char *buffer, int maxLen) { if (mUnavailable) - snprintf(aBuffer, aMaxLen, "|%s|UNAVAILABLE", mName); + snprintf(buffer, maxLen, "|%s|UNAVAILABLE", mName); else - snprintf(aBuffer, aMaxLen, "|%s|%.10g", mName, mValue); - return aBuffer; + snprintf(buffer, maxLen, "|%s|%.10g", mName, mValue); + + return buffer; } + bool Sample::unavailable() { if (!mUnavailable) @@ -239,45 +256,58 @@ bool Sample::unavailable() } -/* Power */ - -bool PowerState::setValue(enum EPowerState aState) +bool PowerState::setValue(enum EPowerState state) { - if (mState != aState || !mHasValue) + if (mState != state || !mHasValue) { - mState = aState; + mState = state; mChanged = true; mHasValue = true; } + return mChanged; } -char *PowerState::toString(char *aBuffer, int aMaxLen) + +char *PowerState::toString(char *buffer, int maxLen) { - const char *text; - switch(mState) + const char *text(nullptr); + + switch (mState) { - case eUNAVAILABLE: text = sUnavailable; break; - case eON: text = "ON"; break; - case eOFF: text = "OFF"; break; - default: text = ""; break; + case eUNAVAILABLE: + text = sUnavailable; + break; + + case eON: + text = "ON"; + break; + + case eOFF: + text = "OFF"; + break; + + default: + text = ""; + break; } - snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); - return aBuffer; + + snprintf(buffer, maxLen, "|%s|%s", mName, text); + return buffer; } + bool PowerState::unavailable() { return setValue(eUNAVAILABLE); } -/* Execution */ -bool Execution::setValue(enum EExecutionState aState) +bool Execution::setValue(enum EExecutionState state) { - if (mState != aState || !mHasValue) + if (mState != state || !mHasValue) { - mState = aState; + mState = state; mChanged = true; mHasValue = true; } @@ -285,51 +315,94 @@ bool Execution::setValue(enum EExecutionState aState) return mChanged; } -char *Execution::toString(char *aBuffer, int aMaxLen) + +char *Execution::toString(char *buffer, int maxLen) { - const char *text; - switch(mState) + const char *text(nullptr); + + switch (mState) { - case eUNAVAILABLE: text = sUnavailable; break; - case eACTIVE: text = "ACTIVE"; break; - case eREADY: text = "READY"; break; - case eINTERRUPTED: text = "INTERRUPTED"; break; - case eSTOPPED: text = "STOPPED"; break; - case eFEED_HOLD: text = "FEED_HOLD"; break; - default: text = ""; break; + case eUNAVAILABLE: + text = sUnavailable; + break; + + case eACTIVE: + text = "ACTIVE"; + break; + + case eREADY: + text = "READY"; + break; + + case eINTERRUPTED: + text = "INTERRUPTED"; + break; + + case eSTOPPED: + text = "STOPPED"; + break; + + case eFEED_HOLD: + text = "FEED_HOLD"; + break; + + default: + text = ""; + break; } - snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); - return aBuffer; + + snprintf(buffer, maxLen, "|%s|%s", mName, text); + return buffer; } + bool Execution::unavailable() { return setValue(eUNAVAILABLE); } -/* ControllerMode */ -char *ControllerMode::toString(char *aBuffer, int aMaxLen) +char *ControllerMode::toString(char *buffer, int maxLen) { - const char *text; - switch(mMode) + const char *text(nullptr); + + switch (mMode) { - case eUNAVAILABLE: text = sUnavailable; break; - case eSEMI_AUTOMATIC: text = "SEMI_AUTOMATIC"; break; - case eAUTOMATIC: text = "AUTOMATIC"; break; - case eMANUAL: text = "MANUAL"; break; - case eMANUAL_DATA_INPUT: text = "MANUAL_DATA_INPUT"; break; - default: text = ""; break; + case eUNAVAILABLE: + text = sUnavailable; + break; + + case eSEMI_AUTOMATIC: + text = "SEMI_AUTOMATIC"; + break; + + case eAUTOMATIC: + text = "AUTOMATIC"; + break; + + case eMANUAL: + text = "MANUAL"; + break; + + case eMANUAL_DATA_INPUT: + text = "MANUAL_DATA_INPUT"; + break; + + default: + text = ""; + break; } - snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); - return aBuffer; + + snprintf(buffer, maxLen, "|%s|%s", mName, text); + return buffer; } -bool ControllerMode::setValue(enum EMode aMode) + +bool ControllerMode::setValue(enum EMode mode) { - if (mMode != aMode || !mHasValue) + if (mMode != mode || !mHasValue) { - mMode = aMode; + mMode = mode; mChanged = true; mHasValue = true; } @@ -337,32 +410,46 @@ bool ControllerMode::setValue(enum EMode aMode) return mChanged; } + bool ControllerMode::unavailable() { return setValue(eUNAVAILABLE); } -/* Direction */ -char *Direction::toString(char *aBuffer, int aMaxLen) +char *Direction::toString(char *buffer, int maxLen) { - const char *text; - switch(mDirection) + const char *text(nullptr); + + switch (mDirection) { - case eUNAVAILABLE: text = sUnavailable; break; - case eCLOCKWISE: text = "CLOCKWISE"; break; - case eCOUNTER_CLOCKWISE: text = "COUNTER_CLOCKWISE"; break; - default: text = ""; break; + case eUNAVAILABLE: + text = sUnavailable; + break; + + case eCLOCKWISE: + text = "CLOCKWISE"; + break; + + case eCOUNTER_CLOCKWISE: + text = "COUNTER_CLOCKWISE"; + break; + + default: + text = ""; + break; } - snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); - return aBuffer; + + snprintf(buffer, maxLen, "|%s|%s", mName, text); + return buffer; } -bool Direction::setValue(enum ERotationDirection aDirection) + +bool Direction::setValue(enum ERotationDirection direction) { - if (mDirection != aDirection || !mHasValue) + if (mDirection != direction || !mHasValue) { - mDirection = aDirection; + mDirection = direction; mChanged = true; mHasValue = true; } @@ -370,32 +457,46 @@ bool Direction::setValue(enum ERotationDirection aDirection) return mChanged; } + bool Direction::unavailable() { return setValue(eUNAVAILABLE); } -/* Emergency Stop */ -char *EmergencyStop::toString(char *aBuffer, int aMaxLen) +char *EmergencyStop::toString(char *buffer, int maxLen) { - const char *text; - switch(mValue) + const char *text(nullptr); + + switch (mValue) { - case eUNAVAILABLE: text = sUnavailable; break; - case eTRIGGERED: text = "TRIGGERED"; break; - case eARMED: text = "ARMED"; break; - default: text = ""; break; + case eUNAVAILABLE: + text = sUnavailable; + break; + + case eTRIGGERED: + text = "TRIGGERED"; + break; + + case eARMED: + text = "ARMED"; + break; + + default: + text = ""; + break; } - snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); - return aBuffer; + + snprintf(buffer, maxLen, "|%s|%s", mName, text); + return buffer; } -bool EmergencyStop::setValue(enum EValues aValue) + +bool EmergencyStop::setValue(enum EValues value) { - if (mValue != aValue || !mHasValue) + if (mValue != value || !mHasValue) { - mValue = aValue; + mValue = value; mChanged = true; mHasValue = true; } @@ -403,170 +504,244 @@ bool EmergencyStop::setValue(enum EValues aValue) return mChanged; } + bool EmergencyStop::unavailable() { return setValue(eUNAVAILABLE); } -/* Axis Coupling */ -char *AxisCoupling::toString(char *aBuffer, int aMaxLen) +char *AxisCoupling::toString(char *buffer, int maxLen) { - const char *text; - switch(mValue) + const char *text(nullptr); + + switch (mValue) { - case eUNAVAILABLE: text = sUnavailable; break; - case eTANDEM: text = "TANDEM"; break; - case eSYNCHRONOUS: text = "SYNCHRONOUS"; break; - case eMASTER: text = "MASTER"; break; - case eSLAVE: text = "SLAVE"; break; - default: text = ""; break; + case eUNAVAILABLE: + text = sUnavailable; + break; + + case eTANDEM: + text = "TANDEM"; + break; + + case eSYNCHRONOUS: + text = "SYNCHRONOUS"; + break; + + case eMASTER: + text = "MASTER"; + break; + + case eSLAVE: + text = "SLAVE"; + break; + + default: + text = ""; + break; } - snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); - return aBuffer; + + snprintf(buffer, maxLen, "|%s|%s", mName, text); + return buffer; } -bool AxisCoupling::setValue(enum EValues aValue) + +bool AxisCoupling::setValue(enum EValues value) { - if (mValue != aValue || !mHasValue) + if (mValue != value || !mHasValue) { - mValue = aValue; + mValue = value; mChanged = true; mHasValue = true; } + return mChanged; } + bool AxisCoupling::unavailable() { return setValue(eUNAVAILABLE); } -/* Door State */ -char *DoorState::toString(char *aBuffer, int aMaxLen) +char *DoorState::toString(char *buffer, int maxLen) { - const char *text; - switch(mValue) + const char *text(nullptr); + + switch (mValue) { - case eUNAVAILABLE: text = sUnavailable; break; - case eOPEN: text = "CLOSED"; break; - case eCLOSED: text = "OPEN"; break; - default: text = ""; break; + case eUNAVAILABLE: + text = sUnavailable; + break; + + case eOPEN: + text = "CLOSED"; + break; + + case eCLOSED: + text = "OPEN"; + break; + + default: + text = ""; + break; } - snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); - return aBuffer; + + snprintf(buffer, maxLen, "|%s|%s", mName, text); + return buffer; } -bool DoorState::setValue(enum EValues aValue) + +bool DoorState::setValue(enum EValues value) { - if (mValue != aValue || !mHasValue) + if (mValue != value || !mHasValue) { - mValue = aValue; + mValue = value; mChanged = true; mHasValue = true; } + return mChanged; } + bool DoorState::unavailable() { return setValue(eUNAVAILABLE); } -// Path Mode -char *PathMode::toString(char *aBuffer, int aMaxLen) +char *PathMode::toString(char *buffer, int maxLen) { - const char *text; - switch(mValue) + const char *text(nullptr); + + switch (mValue) { - case eUNAVAILABLE: text = sUnavailable; break; - case eINDEPENDENT: text = "INDEPENDENT"; break; - case eSYNCHRONOUS: text = "SYNCHRONOUS"; break; - case eMIRROR: text = "MIRROR"; break; - default: text = ""; break; + case eUNAVAILABLE: + text = sUnavailable; + break; + + case eINDEPENDENT: + text = "INDEPENDENT"; + break; + + case eSYNCHRONOUS: + text = "SYNCHRONOUS"; + break; + + case eMIRROR: + text = "MIRROR"; + break; + + default: + text = ""; + break; } - snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); - return aBuffer; + + snprintf(buffer, maxLen, "|%s|%s", mName, text); + return buffer; } -bool PathMode::setValue(enum EValues aValue) + +bool PathMode::setValue(enum EValues value) { - if (mValue != aValue || !mHasValue) + if (mValue != value || !mHasValue) { - mValue = aValue; + mValue = value; mChanged = true; mHasValue = true; } + return mChanged; } + bool PathMode::unavailable() { return setValue(eUNAVAILABLE); } -// Rotary Mode -char *RotaryMode::toString(char *aBuffer, int aMaxLen) +char *RotaryMode::toString(char *buffer, int maxLen) { - const char *text; - switch(mValue) + const char *text(nullptr); + + switch (mValue) { - case eUNAVAILABLE: text = sUnavailable; break; - case eSPINDLE: text = "SPINDLE"; break; - case eINDEX: text = "INDEX"; break; - case eCONTOUR: text = "CONTOUR"; break; - default: text = ""; break; + case eUNAVAILABLE: + text = sUnavailable; + break; + + case eSPINDLE: + text = "SPINDLE"; + break; + + case eINDEX: + text = "INDEX"; + break; + + case eCONTOUR: + text = "CONTOUR"; + break; + + default: + text = ""; + break; } - snprintf(aBuffer, aMaxLen, "|%s|%s", mName, text); - return aBuffer; + + snprintf(buffer, maxLen, "|%s|%s", mName, text); + return buffer; } -bool RotaryMode::setValue(enum EValues aValue) + +bool RotaryMode::setValue(enum EValues value) { - if (mValue != aValue || !mHasValue) + if (mValue != value || !mHasValue) { - mValue = aValue; + mValue = value; mChanged = true; mHasValue = true; } + return mChanged; } + bool RotaryMode::unavailable() { return setValue(eUNAVAILABLE); } -// Message -Message::Message(const char *aName) : - DeviceDatum(aName) +Message::Message(const char *name) : + DeviceDatum(name), + mNativeCode{0} { - mNativeCode[0] = 0; } -char *Message::toString(char *aBuffer, int aMaxLen) + +char *Message::toString(char *buffer, int maxLen) { - snprintf(aBuffer, aMaxLen, "|%s|%s|", mName, mNativeCode); - appendText(aBuffer, mText, aMaxLen); - return aBuffer; + snprintf(buffer, maxLen, "|%s|%s|", mName, mNativeCode); + appendText(buffer, mText, maxLen); + return buffer; } - bool Message::setValue(const char *aText, const char *aCode) + +bool Message::setValue(const char *text, const char *code) { if (!mHasValue || - strncmp(aCode, mNativeCode, EVENT_VALUE_LEN) != 0 || - strncmp(aText, mText, EVENT_VALUE_LEN) != 0) + strncmp(code, mNativeCode, EVENT_VALUE_LEN) || + strncmp(text, mText, EVENT_VALUE_LEN) ) { - strncpy(mNativeCode, aCode, EVENT_VALUE_LEN); + strncpy(mNativeCode, code, EVENT_VALUE_LEN); mNativeCode[EVENT_VALUE_LEN - 1] = '\0'; - strncpy(mText, aText, EVENT_VALUE_LEN); + strncpy(mText, text, EVENT_VALUE_LEN); mText[EVENT_VALUE_LEN - 1] = '\0'; mChanged = true; @@ -576,51 +751,55 @@ char *Message::toString(char *aBuffer, int aMaxLen) return mChanged; } -bool Message::requiresFlush() -{ - return true; -} bool Message::unavailable() { return setValue(sUnavailable); } -/* - * PathPosition methods - */ -PathPosition::PathPosition(const char *aName, double aEpsilon) - : DeviceDatum(aName), mEpsilon(aEpsilon) + +PathPosition::PathPosition(const char *name, double epsilon) + : DeviceDatum(name), + mX(0.0), + mY(0.0), + mZ(0.0), + mUnavailable(false), + mEpsilon(epsilon) { - mX = mY = mZ = 0.0; - mUnavailable = false; } -bool PathPosition::setValue(double aX, double aY, double aZ) + +bool PathPosition::setValue(double x, double y, double z) { if (!mHasValue || - fabs(aX - mX) > mEpsilon || - fabs(aY - mY) > mEpsilon || - fabs(aZ - mZ) > mEpsilon || + fabs(x- mX) > mEpsilon || + fabs(y - mY) > mEpsilon || + fabs(z - mZ) > mEpsilon || mUnavailable) { mChanged = true; - mX = aX; mY = aY; mZ = aZ; + mX = x; + mY = y; + mZ = z; mHasValue = true; mUnavailable = false; } + return mChanged; } -char *PathPosition::toString(char *aBuffer, int aMaxLen) + +char *PathPosition::toString(char *buffer, int maxLen) { if (mUnavailable) - snprintf(aBuffer, aMaxLen, "|%s|UNAVAILABLE", mName); + snprintf(buffer, maxLen, "|%s|UNAVAILABLE", mName); else - snprintf(aBuffer, aMaxLen, "|%s|%.10f %0.10f %0.10f", mName, mX, mY, mZ); - return aBuffer; + snprintf(buffer, maxLen, "|%s|%.10f %0.10f %0.10f", mName, mX, mY, mZ); + + return buffer; } + bool PathPosition::unavailable() { if (!mUnavailable) @@ -632,26 +811,26 @@ bool PathPosition::unavailable() return mChanged; } -/* - * Availability methods - */ -Availability::Availability(const char *aName) - : DeviceDatum(aName) +Availability::Availability(const char *name) : + DeviceDatum(name), + mUnavailable(false) { mHasValue = true; - mUnavailable = false; } -char *Availability::toString(char *aBuffer, int aMaxLen) + +char *Availability::toString(char *buffer, int maxLen) { if (mUnavailable) - snprintf(aBuffer, aMaxLen, "|%s|UNAVAILABLE", mName); + snprintf(buffer, maxLen, "|%s|UNAVAILABLE", mName); else - snprintf(aBuffer, aMaxLen, "|%s|AVAILABLE", mName); - return aBuffer; + snprintf(buffer, maxLen, "|%s|AVAILABLE", mName); + + return buffer; } + bool Availability::unavailable() { if (!mUnavailable) @@ -663,6 +842,7 @@ bool Availability::unavailable() return mChanged; } + bool Availability::available() { if (mUnavailable) diff --git a/src/device_datum.hpp b/src/device_datum.hpp index 5ee291f..0c6a30f 100644 --- a/src/device_datum.hpp +++ b/src/device_datum.hpp @@ -1,5 +1,3 @@ - -/* Forward class definitions */ // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,9 +31,11 @@ // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // #pragma once + +// Forward declarations class StringBuffer; -/* Some constants for field lengths */ +// Some constants for field lengths const int NAME_LEN = 32; const int CODE_LEN = 32; const int UNITS_LEN = 32; @@ -45,76 +45,92 @@ const int STATE_LEN = 32; const int DESCRIPTION_LEN = 512; const int EVENT_VALUE_LEN = 512; -/* - * An abstract data value that knows its name and tracks when it has changed. - * - * The data value will be set in the subclasses. - */ -class DeviceDatum { +// +// An abstract data value that knows its name and tracks when it has changed. +// +// The data value will be set in the subclasses. +// +class DeviceDatum +{ protected: - /* The name of the Data Value */ + // The name of the Data Value char mName[NAME_LEN]; char mOrigName[NAME_LEN]; char mNativeUnits[UNITS_LEN]; - /* A changed flag to indicated that the value has changed since last append. */ + // A changed flag to indicated that the value has changed since last append. bool mChanged; - /* Has this data value been initialized? */ + // Has this data value been initialized? bool mHasValue; protected: - void appendText(char *aBuffer, char *aValue, int aMaxLen); + void appendText(char *buffer, char *value, int maxLen); public: // The name will be supplied later... - DeviceDatum(const char *aName = ""); + DeviceDatum(const char *name = ""); virtual ~DeviceDatum(); - virtual bool changed() { return mChanged; } - void reset() { mChanged = false; } + void reset() { + mChanged = false; } - const char *getNativeUnits() { return mNativeUnits; } - void setNativeUnits(const char *aNativeUnits); + const char *getNativeUnits() const { + return mNativeUnits; } + void setNativeUnits(const char *nativeUnits); - bool prefixName(const char *aPrefix); - bool hasValue() const { return mHasValue; } - char *getName() { return mName; } - void setName(const char *aName = ""); - virtual char *toString(char *aBuffer, int aMaxLen) = 0; - virtual bool append(StringBuffer &aBuffer); - virtual bool hasInitialValue(); - virtual bool requiresFlush(); + bool prefixName(const char *prefix); + bool hasValue() const { + return mHasValue; } + const char *getName() const { + return mName; } + void setName(const char *name = ""); +// Pure virtual and overridable methods +public: + virtual char *toString(char *buffer, int maxLen) = 0; virtual bool unavailable() = 0; + + virtual bool changed() const { + return mChanged; } + virtual bool append(StringBuffer &buffer); + virtual bool hasInitialValue() const ; + virtual bool requiresFlush() const; + virtual void begin() { } virtual void prepare() { } virtual void cleanup() { } virtual void initialize() { } }; -/* - * An event is a data value with a string value. - */ + +// +// An event is a data value with a string value. +// class Event : public DeviceDatum { protected: char mValue[EVENT_VALUE_LEN]; public: - Event(const char *aName = ""); - bool setValue(const char *aValue); - const char *getValue() { return mValue; } - virtual char *toString(char *aBuffer, int aMaxLen); + Event(const char *name = ""); + + bool setValue(const char *value); + const char *getValue() const { + return mValue; } - virtual bool unavailable(); +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; }; -/* - * An int event is an event with an integer value. This can be used - * for line number events. - */ + +// +// An int event is an event with an integer value. This can be used +// for line number events. +// class IntEvent : public DeviceDatum { protected: @@ -122,18 +138,22 @@ class IntEvent : public DeviceDatum bool mUnavailable; public: - IntEvent(const char *aName = ""); - bool setValue(int aValue); - int getValue() { return mValue; } - virtual char *toString(char *aBuffer, int aMaxLen); + IntEvent(const char *name = ""); + + bool setValue(int value); + int getValue() const { + return mValue; } - virtual bool unavailable(); +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; }; -/* - * A sample event is used for floating point samples. - */ +// +// A sample event is used for floating point samples. +// class Sample : public DeviceDatum { protected: @@ -142,20 +162,24 @@ class Sample : public DeviceDatum double mEpsilon; public: - Sample(const char *aName = "", double aEpsilon = 0.000001); - bool setValue(double aValue); - double getValue() { return mValue; } - virtual char *toString(char *aBuffer, int aMaxLen); + Sample(const char *name = "", double aEpsilon = 0.000001); - virtual bool unavailable(); + bool setValue(double value); + double getValue() const { + return mValue; } + +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; }; -/* Power status data value */ class PowerState : public DeviceDatum { public: - enum EPowerState { + enum EPowerState + { eUNAVAILABLE, eON, eOFF, @@ -165,20 +189,23 @@ class PowerState : public DeviceDatum EPowerState mState; public: - PowerState(const char *aName = "") : DeviceDatum(aName) { } - bool setValue(enum EPowerState aState); - EPowerState getValue() { return mState; } - virtual char *toString(char *aBuffer, int aMaxLen); + PowerState(const char *name = "") : DeviceDatum(name) { } + bool setValue(enum EPowerState state); + EPowerState getValue() const { + return mState; } - virtual bool unavailable(); +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; }; -/* Executaion state */ class Execution : public DeviceDatum { public: - enum EExecutionState { + enum EExecutionState + { eUNAVAILABLE, eREADY, eINTERRUPTED, @@ -191,20 +218,27 @@ class Execution : public DeviceDatum EExecutionState mState; public: - Execution(const char *aName = "") : DeviceDatum(aName) { } - bool setValue(enum EExecutionState aState); - EExecutionState getValue() { return mState; } - virtual char *toString(char *aBuffer, int aMaxLen); + Execution(const char *name = "") : + DeviceDatum(name) + { + } - virtual bool unavailable(); + bool setValue(enum EExecutionState state); + EExecutionState getValue() const { + return mState; } + +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; }; -/* ControllerMode */ class ControllerMode : public DeviceDatum { public: - enum EMode { + enum EMode + { eUNAVAILABLE, eAUTOMATIC, eMANUAL, @@ -216,21 +250,27 @@ class ControllerMode : public DeviceDatum EMode mMode; public: - ControllerMode(const char *aName = "") : DeviceDatum(aName) { } - bool setValue(enum EMode aState); - EMode getValue() { return mMode; } - virtual char *toString(char *aBuffer, int aMaxLen); + ControllerMode(const char *name = "") : + DeviceDatum(name) + { + } - virtual bool unavailable(); -}; + bool setValue(enum EMode state); + EMode getValue() const { + return mMode; } +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; +}; -/* Direction */ class Direction : public DeviceDatum { public: - enum ERotationDirection { + enum ERotationDirection + { eUNAVAILABLE, eCLOCKWISE, eCOUNTER_CLOCKWISE @@ -240,22 +280,27 @@ class Direction : public DeviceDatum ERotationDirection mDirection; public: - Direction(const char *aName = "") : DeviceDatum(aName) { } - bool setValue(enum ERotationDirection aDirection); - ERotationDirection getValue() { return mDirection; } - virtual char *toString(char *aBuffer, int aMaxLen); + Direction(const char *name = "") : + DeviceDatum(name) + { + } - virtual bool unavailable(); -}; + bool setValue(enum ERotationDirection direction); + ERotationDirection getValue() const { + return mDirection; } -// Version 1.1 +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; +}; -/* Emergency Stop */ class EmergencyStop : public DeviceDatum { public: - enum EValues { + enum EValues + { eUNAVAILABLE, eTRIGGERED, eARMED @@ -265,19 +310,27 @@ class EmergencyStop : public DeviceDatum EValues mValue; public: - EmergencyStop(const char *aName = "") : DeviceDatum(aName) { } - bool setValue(enum EValues aValue); - EValues getValue() { return mValue; } - virtual char *toString(char *aBuffer, int aMaxLen); + EmergencyStop(const char *name = "") : + DeviceDatum(name) + { + } + + bool setValue(enum EValues value); + EValues getValue() const { + return mValue; } - virtual bool unavailable(); +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; }; class AxisCoupling : public DeviceDatum { public: - enum EValues { + enum EValues + { eUNAVAILABLE, eTANDEM, eSYNCHRONOUS, @@ -289,18 +342,27 @@ class AxisCoupling : public DeviceDatum EValues mValue; public: - AxisCoupling(const char *aName = "") : DeviceDatum(aName) { } - bool setValue(enum EValues aValue); - EValues getValue() { return mValue; } - virtual char *toString(char *aBuffer, int aMaxLen); + AxisCoupling(const char *name = "") : + DeviceDatum(name) + { + } + + bool setValue(enum EValues value); + EValues getValue() const { + return mValue; } - virtual bool unavailable(); +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; }; + class DoorState : public DeviceDatum { public: - enum EValues { + enum EValues + { eUNAVAILABLE, eOPEN, eCLOSED @@ -310,18 +372,27 @@ class DoorState : public DeviceDatum EValues mValue; public: - DoorState(const char *aName = "") : DeviceDatum(aName) { } - bool setValue(enum EValues aValue); - EValues getValue() { return mValue; } - virtual char *toString(char *aBuffer, int aMaxLen); + DoorState(const char *name = "") : + DeviceDatum(name) + { + } + + bool setValue(enum EValues value); + EValues getValue() const { + return mValue; } - virtual bool unavailable(); +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; }; + class PathMode : public DeviceDatum { public: - enum EValues { + enum EValues + { eUNAVAILABLE, eINDEPENDENT, eSYNCHRONOUS, @@ -332,18 +403,27 @@ class PathMode : public DeviceDatum EValues mValue; public: - PathMode(const char *aName = "") : DeviceDatum(aName) { } - bool setValue(enum EValues aValue); - EValues getValue() { return mValue; } - virtual char *toString(char *aBuffer, int aMaxLen); + PathMode(const char *name = "") : + DeviceDatum(name) + { + } + + bool setValue(enum EValues value); + EValues getValue() const { + return mValue; } - virtual bool unavailable(); +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; }; + class RotaryMode : public DeviceDatum { public: - enum EValues { + enum EValues + { eUNAVAILABLE, eSPINDLE, eINDEX, @@ -354,54 +434,75 @@ class RotaryMode : public DeviceDatum EValues mValue; public: - RotaryMode(const char *aName = "") : DeviceDatum(aName) { } - bool setValue(enum EValues aValue); - EValues getValue() { return mValue; } - virtual char *toString(char *aBuffer, int aMaxLen); + RotaryMode(const char *name = "") : DeviceDatum(name) { } + bool setValue(enum EValues value); + EValues getValue() const { + return mValue; } - virtual bool unavailable(); +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; }; -class Message : public DeviceDatum { + +class Message : public DeviceDatum +{ char mText[EVENT_VALUE_LEN]; char mNativeCode[EVENT_VALUE_LEN]; public: - Message(const char *aName = ""); - bool setValue(const char *aText, const char *aCode = ""); - virtual char *toString(char *aBuffer, int aMaxLen); - const char *getNativeCode() { return mNativeCode; } + Message(const char *name = ""); + + bool setValue(const char *text, const char *code = ""); + const char *getNativeCode() const { + return mNativeCode; } - virtual bool requiresFlush(); - virtual bool unavailable(); +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; + bool requiresFlush() const override { + return true; } }; -class PathPosition : public DeviceDatum { + +class PathPosition : public DeviceDatum +{ protected: double mX, mY, mZ; bool mUnavailable; double mEpsilon; public: - PathPosition(const char *aName = "", double aEpsilon = 0.000001); - bool setValue(double aX, double aY, double aZ); - double getX() { return mX; } - double getY() { return mY; } - double getZ() { return mZ; } - virtual char *toString(char *aBuffer, int aMaxLen); - - virtual bool unavailable(); + PathPosition(const char *name = "", double aEpsilon = 0.000001); + bool setValue(double x, double y, double z); + double getX() const { + return mX; } + double getY() const { + return mY; } + double getZ() const { + return mZ; } + +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; }; + class Availability : public DeviceDatum { protected: bool mUnavailable; public: - Availability(const char *aName = ""); - virtual char *toString(char *aBuffer, int aMaxLen); + Availability(const char *name = ""); bool available(); - virtual bool unavailable(); + +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; }; From 6364e46fad8ac4e3e715b1dce7eaf983a3f22680 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:15:14 +0100 Subject: [PATCH 15/41] C++11 Conversion: Conversion of 'core' classes --- src/client.cpp | 27 ++-- src/client.hpp | 25 +-- src/component.hpp | 20 ++- src/cutting_tool.cpp | 146 +++++++++++------- src/cutting_tool.hpp | 119 ++++++++++----- src/internal.hpp | 86 ++++++----- src/logger.cpp | 74 +++++---- src/logger.hpp | 31 ++-- src/serial.cpp | 71 ++++++--- src/serial.hpp | 65 +++++--- src/server.cpp | 98 +++++++----- src/server.hpp | 21 ++- src/service.cpp | 347 +++++++++++++++++++++++------------------- src/service.hpp | 34 +++-- src/string_array.cpp | 44 +++--- src/string_array.hpp | 27 ++-- src/string_buffer.cpp | 75 +++++---- src/string_buffer.hpp | 37 ++--- src/threading.hpp | 32 ++-- src/time_series.cpp | 50 +++--- src/time_series.hpp | 43 +++--- 21 files changed, 879 insertions(+), 593 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 7741b8d..1438c51 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -34,40 +34,45 @@ #include "client.hpp" #include "server.hpp" -/* Instance methods */ -Client::Client(SOCKET aSocket) + + +Client::Client(SOCKET socket) { - mSocket = aSocket; + mSocket = socket; mHeartbeats = false; } + Client::~Client() { ::shutdown(mSocket, SHUT_RDWR); ::closesocket(mSocket); } -int Client::write(const char *aString) + +int Client::write(const char *string) { int res; MTCAutoLock lock(mWriteLock); - try { - res = ::send(mSocket, aString, (int) strlen(aString), 0); + try + { + res = ::send(mSocket, string, (int) strlen(string), 0); } - - catch(...) { + catch(...) + { res = -1; } return res; } -int Client::read(char *aBuffer, int aMaxLen) + +int Client::read(char *buffer, int maxLen) { - int len = recv(mSocket, aBuffer, aMaxLen, 0); + int len = recv(mSocket, buffer, maxLen, 0); if (len >= 0) - aBuffer[len] = 0; + buffer[len] = 0; return len; } diff --git a/src/client.hpp b/src/client.hpp index 4f8be40..e9a9b77 100755 --- a/src/client.hpp +++ b/src/client.hpp @@ -32,31 +32,32 @@ // #pragma once +#include "threading.hpp" -#include "threading.hpp" -/* - * A wrapper around a client socket. An adapter is capable of managing - * multiple sockets. - */ +// +// A wrapper around a client socket. An adapter is capable of managing +// multiple sockets. +// class Client { - /* Instance Variables */ +// Instance Variables protected: SOCKET mSocket; MTCMutex mWriteLock; - /* class methods */ +// class methods public: bool mHeartbeats; unsigned int mLastHeartbeat; - /* Instance methods */ +// Instance methods public: Client(SOCKET aSocket); ~Client(); - int write(const char *aString); - int read(char *aBuffer, int aLen); - SOCKET socket() { return mSocket; } -}; + int write(const char *string); + int read(char *buffer, int len); + SOCKET socket() { + return mSocket; } +}; diff --git a/src/component.hpp b/src/component.hpp index 38067d1..3e5708f 100644 --- a/src/component.hpp +++ b/src/component.hpp @@ -46,13 +46,21 @@ class Component protected: Adapter *mAdapter; std::string mName; - Component *aParent; + Component *mParent; public: - Component(Adapter *anAdapter, std::string aName, Component *aParent = NULL); - virtual ~Component(); - virtual void initialize(); - virtual void gatherData(void *aContext) = 0; -}; + Component(Adapter *adapter, std::string name, Component *parent = nullptr) : + mAdapter(adapter), + mName(name), + mParent(parent) + { + } + const std::string &getName() const { + return mName; } + + virtual ~Component(){} + virtual void initialize(){} + virtual void gatherData(void *context) = 0; +}; diff --git a/src/cutting_tool.cpp b/src/cutting_tool.cpp index 24e287b..bebc908 100644 --- a/src/cutting_tool.cpp +++ b/src/cutting_tool.cpp @@ -36,124 +36,156 @@ using namespace std; -string encodeForXml( const string &aSrc ) +string encodeForXml(const string &source) { ostringstream ret; - for( string::const_iterator iter = aSrc.begin(); iter != aSrc.end(); iter++ ) + for (auto iter = source.cbegin(); iter != source.cend(); iter++) { - unsigned char c = (unsigned char)*iter; + unsigned char c = (unsigned char) * iter; - switch( c ) + switch (c) { - case '&': ret << "&"; break; - case '<': ret << "<"; break; - case '>': ret << ">"; break; - case '"': ret << """; break; - case '\'': ret << "'"; break; + case '&': + ret << "&"; + break; + + case '<': + ret << "<"; + break; + + case '>': + ret << ">"; + break; + + case '"': + ret << """; + break; + + case '\'': + ret << "'"; + break; default: - if ( c<32 || c>127 ) - { + if (c < 32 || c > 127) ret << "&#" << (unsigned int)c << ";"; - } else - { ret << c; } } - } return ret.str(); } -std::string CuttingToolProperty::toXML() + +std::string CuttingToolProperty::toXML() const { ostringstream xml; xml << '<' << mName; - map::iterator iter; - for (iter = mAttributes.begin(); iter != mAttributes.end(); iter++) { - xml << ' ' << iter->first << "=\"" << encodeForXml(iter->second) << '"'; - } - if (!mValue.empty()) { + for(auto const &mapPair : mAttributes) + xml << ' ' << mapPair.first << "=\"" << encodeForXml(mapPair.second) << '"'; + + if (!mValue.empty()) xml << '>' << encodeForXml(mValue) << "'; - return xml.str(); } -std::string CuttingToolStatus::toXML() + +std::string CuttingToolStatus::toXML() const { ostringstream xml; xml << '<' << mName << '>'; - vector::iterator iter; - for (iter = mStatus.begin(); iter != mStatus.end(); iter++) { - xml << "" << *iter << ""; - } + + for (auto const &status : mStatus) + xml << "" << status << ""; xml << "'; return xml.str(); } -static char *doubleToString(double aDouble, char *aBuffer) + +static char *doubleToString(double value, char *buffer) { - sprintf(aBuffer, "%.10g", aDouble); - return aBuffer; + sprintf(buffer, "%.10g", value); + return buffer; } -CuttingToolMeasurement::CuttingToolMeasurement(std::string aName, std::string aCode, - double aValue, double aNominal, double aMin, double aMax, - std::string aNativeUnits, std::string aUnits) - : CuttingToolProperty(aName) + +CuttingToolMeasurement::CuttingToolMeasurement( + std::string name, + std::string code, + double value, + double nominal, + double min, + double max, + std::string nativeUnits, + std::string units) + : + CuttingToolProperty(name) { char buffer[80]; - mAttributes["code"] = aCode; + mAttributes["code"] = code; + + if (nominal != CT_NO_VALUE) + mAttributes["nominal"] = doubleToString(nominal, buffer); + + if (min != CT_NO_VALUE) + mAttributes["minimum"] = doubleToString(min, buffer); + + if (max != CT_NO_VALUE) + mAttributes["maximum"] = doubleToString(max, buffer); + + if (!nativeUnits.empty()) + mAttributes["nativeUnits"] = nativeUnits; - if (aNominal != CT_NO_VALUE) mAttributes["nominal"] = doubleToString(aNominal, buffer); - if (aMin != CT_NO_VALUE) mAttributes["minimum"] = doubleToString(aMin, buffer); - if (aMax != CT_NO_VALUE) mAttributes["maximum"] = doubleToString(aMax, buffer); - if (!aNativeUnits.empty()) mAttributes["nativeUnits"] = aNativeUnits; - if (!aNativeUnits.empty()) mAttributes["units"] = aUnits; + if (!units.empty()) + mAttributes["units"] = units; - if (aValue != CT_NO_VALUE) mValue = doubleToString(aValue, buffer); + if (value != CT_NO_VALUE) + mValue = doubleToString(value, buffer); } -CuttingTool::CuttingTool(std::string &aAssetId, int aToolNumber, std::string &aDescription, CuttingToolStatus &aStatus) - : mAssetId(encodeForXml(aAssetId)), mToolNumber(aToolNumber), mDescription(encodeForXml(aDescription)), - mStatus(aStatus) + +CuttingTool::CuttingTool( + std::string &assetId, + int toolNumber, + std::string &description, + CuttingToolStatus &status) + : + mAssetId(encodeForXml(assetId)), + mToolNumber(toolNumber), + mDescription(encodeForXml(description)), + mStatus(status) { } + string CuttingTool::toString() { // Agent takes care of reordering the properties, so we can cheat... std::ostringstream xml; // Open tag... - xml << ""; + xml << ""; xml << "" << mDescription << ""; xml << ""; // Properties - vector::iterator prop; - for (prop = mProperties.begin(); prop != mProperties.end(); prop++) { - xml << prop->toXML(); - } + for (auto const &prop : mProperties) + xml << prop.toXML(); xml << ""; - - vector::iterator measure; - for (measure = mMeasurements.begin(); measure != mMeasurements.end(); measure++) { - xml << measure->toXML(); - } - + for (auto const &measure : mMeasurements) + xml << measure.toXML(); xml << ""; // Items... diff --git a/src/cutting_tool.hpp b/src/cutting_tool.hpp index 904c347..3d0fbb0 100644 --- a/src/cutting_tool.hpp +++ b/src/cutting_tool.hpp @@ -36,21 +36,34 @@ #include #include -class CuttingToolProperty { -public: - CuttingToolProperty(const std::string &aName, std::map &aAttributes, const std::string &aValue) - : mName(aName), mAttributes(aAttributes), mValue(aValue) - {} - - CuttingToolProperty(std::string aName) - : mName(aName) - {} - - CuttingToolProperty(const CuttingToolProperty &aProp) - : mName(aProp.mName), mAttributes(aProp.mAttributes), mValue(aProp.mValue) - {} - - virtual std::string toXML(); + +class CuttingToolProperty +{ +public: + CuttingToolProperty( + const std::string &aName, + std::map &aAttributes, + const std::string &aValue) + : + mName(aName), + mAttributes(aAttributes), + mValue(aValue) + { + } + + CuttingToolProperty(std::string aName) : + mName(aName) + { + } + + CuttingToolProperty(const CuttingToolProperty &aProp) : + mName(aProp.mName), + mAttributes(aProp.mAttributes), + mValue(aProp.mValue) + { + } + + virtual std::string toXML() const; public: std::string mName; @@ -58,56 +71,82 @@ class CuttingToolProperty { std::string mValue; }; -class CuttingToolStatus : public CuttingToolProperty { + +class CuttingToolStatus : public CuttingToolProperty +{ public: - CuttingToolStatus(std::vector &aStatus) - : CuttingToolProperty("CutterStatus"), mStatus(aStatus) - { } + CuttingToolStatus(std::vector &status) : + CuttingToolProperty("CutterStatus"), + mStatus(status) + { + } - CuttingToolStatus(const CuttingToolStatus &aStatus) - : CuttingToolProperty(aStatus), mStatus(aStatus.mStatus) - {} + CuttingToolStatus(const CuttingToolStatus &status) : + CuttingToolProperty(status), + mStatus(status.mStatus) + { + } - virtual std::string toXML(); + std::string toXML() const override; public: std::vector mStatus; }; + static const double CT_NO_VALUE = DBL_MAX; -class CuttingToolMeasurement : public CuttingToolProperty { + +class CuttingToolMeasurement : public CuttingToolProperty +{ public: - CuttingToolMeasurement(std::string aName, std::string aCode, double aValue, double aNominal = CT_NO_VALUE, - double aMin = CT_NO_VALUE, double aMax = CT_NO_VALUE, - std::string aNativeUnits = "", - std::string aUnits = ""); - - CuttingToolMeasurement(const CuttingToolMeasurement &aMeasure) - : CuttingToolProperty(aMeasure) - {} + CuttingToolMeasurement( + std::string name, + std::string code, + double value, + double nominal = CT_NO_VALUE, + double min = CT_NO_VALUE, + double max = CT_NO_VALUE, + std::string nativeUnits = "", + std::string units = ""); + + CuttingToolMeasurement(const CuttingToolMeasurement &measurement) : + CuttingToolProperty(measurement) + { + } }; -class CuttingItem { + +class CuttingItem +{ public: std::vector mProperties; std::vector mMeasurements; }; -class CuttingTool { + +class CuttingTool +{ public: - CuttingTool(std::string &aAssetId, int aToolNumber, std::string &aDescription, - CuttingToolStatus &aStatus); + CuttingTool( + std::string &aAssetId, + int aToolNumber, + std::string &aDescription, + CuttingToolStatus &status); - void add(CuttingToolProperty &aProp) { mProperties.push_back(aProp); } - void add(CuttingToolMeasurement &aProp) { mMeasurements.push_back(aProp); } + void add(CuttingToolProperty &aProp) { + mProperties.push_back(aProp); } + void add(CuttingToolMeasurement &aProp) { + mMeasurements.push_back(aProp); } virtual std::string toString(); - const std::string &getAssetId() const { return mAssetId; } + const std::string &getAssetId() const { + return mAssetId; } int getToolNumber() const { return mToolNumber; } - bool isValid() const { return !mAssetId.empty(); } + bool isValid() const { + return !mAssetId.empty(); } protected: CuttingToolStatus mStatus; diff --git a/src/internal.hpp b/src/internal.hpp index d94da9d..91a1304 100755 --- a/src/internal.hpp +++ b/src/internal.hpp @@ -33,56 +33,60 @@ #pragma once #ifdef WIN32 -#define _CRT_SECURE_NO_DEPRECATE 1 + #define _CRT_SECURE_NO_DEPRECATE 1 -/* Windows specific include files and types */ -#include "winsock2.h" -#ifndef AFX -#include "windows.h" -#endif -#include "errno.h" + /* Windows specific include files and types */ + #include "winsock2.h" + #ifndef AFX + #include "windows.h" + #endif + #include "errno.h" -#define SHUT_RDWR SD_BOTH -typedef int socklen_t; -#define snprintf _snprintf -#define strdup _strdup -#define stricmp _stricmp -#define strdup _strdup + #define SHUT_RDWR SD_BOTH + typedef int socklen_t; + #if _MSC_VER < 1900 + #define snprintf _snprintf + #endif + #define strdup _strdup + #define stricmp _stricmp + #define strdup _strdup -/* Internal types */ -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned __int64 uint64_t; + /* Internal types */ + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + typedef unsigned __int64 uint64_t; -#define UINT16_MAX 0xFFFF + #if _MSC_VER < 1900 + #define UINT16_MAX 0xFFFF + #endif -#define sleep(t) Sleep(t * 1000) -#define usleep(t) Sleep(t / 1000) + #define sleep(t) Sleep(t * 1000) + #define usleep(t) Sleep(t / 1000) #else /* WIN32 */ -/* Unix specifc include files */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + /* Unix specifc include files */ + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include -typedef struct sockaddr_in SOCKADDR_IN; -typedef struct sockaddr SOCKADDR; -#define INVALID_SOCKET -1 -#define SOCKET_ERROR -1 -#define SOCKET int -#define closesocket close + typedef struct sockaddr_in SOCKADDR_IN; + typedef struct sockaddr SOCKADDR; + #define INVALID_SOCKET -1 + #define SOCKET_ERROR -1 + #define SOCKET int + #define closesocket close #endif /* WIN32 */ diff --git a/src/logger.cpp b/src/logger.cpp index b88a2bb..58091f7 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -33,72 +33,88 @@ #include "internal.hpp" #include "logger.hpp" -Logger *gLogger = NULL; +Logger *gLogger = nullptr; -void Logger::error(const char *aFormat, ...) + +void Logger::error(const char *inputformat, ...) { char buffer[LOGGER_BUFFER_SIZE]; char ts[32]; va_list args; - va_start (args, aFormat); - fprintf(mFile, "%s - Error: %s\n", timestamp(ts), format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); + va_start(args, inputformat); + fprintf(mFile, "%s - Error: %s\n", + timestamp(ts), + format(buffer, LOGGER_BUFFER_SIZE, inputformat, args)); fflush(mFile); - va_end (args); + va_end(args); } -void Logger::warning(const char *aFormat, ...) + +void Logger::warning(const char *inputformat, ...) { - if (mLogLevel > eWARNING) return; + if (mLogLevel > eWARNING) + return; char buffer[LOGGER_BUFFER_SIZE]; char ts[32]; va_list args; - va_start (args, aFormat); - fprintf(mFile, "%s - Warning: %s\n", timestamp(ts), format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); + va_start(args, inputformat); + fprintf(mFile, "%s - Warning: %s\n", + timestamp(ts), + format(buffer, LOGGER_BUFFER_SIZE, inputformat, args)); fflush(mFile); - va_end (args); + va_end(args); } -void Logger::info(const char *aFormat, ...) + +void Logger::info(const char *inputformat, ...) { - if (mLogLevel > eINFO) return; + if (mLogLevel > eINFO) + return; char buffer[LOGGER_BUFFER_SIZE]; char ts[32]; va_list args; - va_start (args, aFormat); - fprintf(mFile, "%s - Info: %s\n", timestamp(ts), format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); + va_start(args, inputformat); + fprintf(mFile, "%s - Info: %s\n", + timestamp(ts), + format(buffer, LOGGER_BUFFER_SIZE, inputformat, args)); fflush(mFile); - va_end (args); + va_end(args); } -void Logger::debug(const char *aFormat, ...) + +void Logger::debug(const char *inputformat, ...) { - if (mLogLevel > eDEBUG) return; + if (mLogLevel > eDEBUG) + return; char buffer[LOGGER_BUFFER_SIZE]; char ts[32]; va_list args; - va_start (args, aFormat); - fprintf(mFile, "%s - Debug: %s\n", timestamp(ts), format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); + va_start(args, inputformat); + fprintf(mFile, "%s - Debug: %s\n", + timestamp(ts), + format(buffer, LOGGER_BUFFER_SIZE, inputformat, args)); fflush(mFile); - va_end (args); + va_end(args); } -const char *Logger::format(char *aBuffer, int aLen, const char *aFormat, va_list args) +const char *Logger::format(char *buffer, int aLen, const char *inputformat, va_list args) { - vsprintf(aBuffer, aFormat, args); - aBuffer[aLen - 1] = '\0'; - return aBuffer; + vsprintf(buffer, inputformat, args); + buffer[aLen - 1] = '\0'; + return buffer; } -const char *Logger::timestamp(char *aBuffer) + +const char *Logger::timestamp(char *buffer) { #ifdef WIN32 SYSTEMTIME st; GetSystemTime(&st); - sprintf(aBuffer, "%4d-%02d-%02dT%02d:%02d:%02d.%03dZ", st.wYear, st.wMonth, st.wDay, st.wHour, + sprintf(buffer, "%4d-%02d-%02dT%02d:%02d:%02d.%03dZ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); #else struct timeval tv; @@ -106,9 +122,9 @@ const char *Logger::timestamp(char *aBuffer) gettimeofday(&tv, &tz); - strftime(aBuffer, 64, "%Y-%m-%dT%H:%M:%S", gmtime(&tv.tv_sec)); - sprintf(aBuffer + strlen(aBuffer), ".%06dZ", tv.tv_usec); + strftime(buffer, 64, "%Y-%m-%dT%H:%M:%S", gmtime(&tv.tv_sec)); + sprintf(buffer + strlen(buffer), ".%06dZ", tv.tv_usec); #endif - return aBuffer; + return buffer; } diff --git a/src/logger.hpp b/src/logger.hpp index 313030c..983a801 100644 --- a/src/logger.hpp +++ b/src/logger.hpp @@ -37,27 +37,36 @@ #define LOGGER_BUFFER_SIZE 1024 -class Logger { +class Logger +{ public: - enum LogLevel { + enum LogLevel + { eDEBUG, eINFO, eWARNING, eERROR }; - Logger(FILE *aFile = stderr) : mFile(aFile) { mLogLevel = eINFO; } - void setLogLevel(LogLevel aLevel) { mLogLevel = aLevel; } - LogLevel getLogLevel() { return mLogLevel; } + Logger(FILE *aFile = stderr) : + mFile(aFile), + mLogLevel(eINFO) + { + } - virtual void error(const char *aFormat, ...); - virtual void warning(const char *aFormat, ...); - virtual void info(const char *aFormat, ...); - virtual void debug(const char *aFormat, ...); + void setLogLevel(LogLevel aLevel) { + mLogLevel = aLevel; } + LogLevel getLogLevel() const { + return mLogLevel; } + + virtual void error(const char *format, ...); + virtual void warning(const char *format, ...); + virtual void info(const char *format, ...); + virtual void debug(const char *format, ...); protected: - const char *format(char *aBuffer, int aLen, const char *aFormat, va_list args); - const char *timestamp(char *aBuffer); + const char *format(char *buffer, int aLen, const char *format, va_list args); + const char *timestamp(char *buffer); LogLevel mLogLevel; FILE *mFile; diff --git a/src/serial.cpp b/src/serial.cpp index 369595e..0136d4f 100644 --- a/src/serial.cpp +++ b/src/serial.cpp @@ -36,14 +36,19 @@ #include + Serial::SerialError::SerialError(const char *aMessage) { strncpy(mMessage, aMessage, 1023); mMessage[1023] = '\0'; } -Serial::Serial(const char *aDevice, - int aBaud, const char *aParity, int aDataBit, + +Serial::Serial( + const char *aDevice, + int aBaud, + const char *aParity, + int aDataBit, int aStopBit) { mBaud = aBaud; @@ -64,11 +69,13 @@ Serial::Serial(const char *aDevice, mConnected = false; } + Serial::~Serial() { disconnect(); } + int Serial::readUntil(const char *aUntil, char *aBuffer, int aLength) { if (!mConnected) @@ -82,16 +89,18 @@ int Serial::readUntil(const char *aUntil, char *aBuffer, int aLength) int len = 0, count = 0; char *cp = aBuffer; const char *match = aUntil; + do { int ret = read(cp, 1); + if (ret == -1) - { throw SerialError("Couldn't read"); - } + if (ret == 0) { usleep(10 * 1000); // 10 msec + if (count++ > 10) { gLogger->info("Read timed out\n"); @@ -111,11 +120,13 @@ int Serial::readUntil(const char *aUntil, char *aBuffer, int aLength) // See if we can match the beginnig of the string again. if (*match == *cp) match++; + //printf("Match now: %d\n", *match); cp++; len++; } - } while (len <= aLength && *match != '\0'); + } + while (len <= aLength && *match != '\0'); *cp = '\0'; @@ -124,11 +135,13 @@ int Serial::readUntil(const char *aUntil, char *aBuffer, int aLength) return len; } + int Serial::write(const char *aBuffer) { gLogger->debug("Writing '%s'\n", aBuffer); int ret = write(aBuffer, (int) strlen(aBuffer)); + if (ret < 0) throw SerialError("Couldn't write"); @@ -137,16 +150,20 @@ int Serial::write(const char *aBuffer) return ret; } + bool Serial::flushInput() { char buffer[2]; int ret; + do { ret = read(buffer, 1); + if (ret < 0) throw SerialError("Couldn't read"); - } while (ret > 0); + } + while (ret > 0); #ifdef WIN32 DWORD errors; @@ -159,20 +176,30 @@ bool Serial::flushInput() return true; } + int Serial::readFully(char *aBuffer, int len, uint32_t timeout) { int consumed = 0; uint64_t start = getTimestamp(); - while (consumed < len && (getTimestamp() - start) < timeout) { + + while (consumed < len && (getTimestamp() - start) < timeout) + { int res = wait(100); - if (res > 0) { + + if (res > 0) + { int cnt = read(aBuffer + consumed, len - consumed); - if (cnt < 0) { + + if (cnt < 0) + { gLogger->debug("Read returned: %d\n", res); return -1; } + consumed += cnt; - } else if (res < 0) { + } + else if (res < 0) + { gLogger->debug("Wait returned: %d\n", res); return res; } @@ -181,22 +208,31 @@ int Serial::readFully(char *aBuffer, int len, uint32_t timeout) return consumed; } + int Serial::writeFully(const char *aBuffer, int len, uint32_t timeout) { int written = 0; uint64_t start = getTimestamp(); - while (written < len && (getTimestamp() - start) < timeout) { + + while (written < len && (getTimestamp() - start) < timeout) + { int res = wait(100, Serial::WRITE); - if (res > 0) { + + if (res > 0) + { int cnt = write(aBuffer + written, len - written); - if (cnt > 0) { + + if (cnt > 0) written += cnt; - } else { + else + { gLogger->debug("Write returned: %d\n", res); return -1; } - } else if (res < 0) { + } + else if (res < 0) + { gLogger->debug("Wait returned: %d\n", res); return res; } @@ -205,9 +241,10 @@ int Serial::writeFully(const char *aBuffer, int len, uint32_t timeout) return written; } + #ifdef WIN32 -#include "serial.win32.inc" + #include "serial.win32.inc" #else -#include "serial.unix.inc" + #include "serial.unix.inc" #endif diff --git a/src/serial.hpp b/src/serial.hpp index 6f23335..19463e5 100644 --- a/src/serial.hpp +++ b/src/serial.hpp @@ -1,5 +1,3 @@ - -class Serial { // // Copyright (c) 2008, AMT - The Association For Manufacturing Technology ("AMT") // All rights reserved. @@ -33,6 +31,10 @@ class Serial { // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // #pragma once + + +class Serial +{ public: class SerialError { @@ -45,43 +47,43 @@ class Serial { }; protected: - /* Descriptor (tty or socket) */ + // Descriptor (tty or socket) #ifdef WIN32 HANDLE mFd; #else int mFd; #endif - /* TCP port */ + // TCP port int mPort; - /* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*" - on Mac OS X for KeySpan USB<->Serial adapters this string - had to be made bigger on OS X as the directory+file name - was bigger than 19 bytes. Making it 67 bytes for now, but - OS X does support 256 byte file names. May become a problem - in the future. */ - + // Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*" + // on Mac OS X for KeySpan USB<->Serial adapters this string + // had to be made bigger on OS X as the directory+file name + // was bigger than 19 bytes. Making it 67 bytes for now, but + // OS X does support 256 byte file names. May become a problem + // in the future. #ifdef __APPLE_CC__ char mDevice[64]; #else char mDevice[16]; #endif - /* Bauds: 9600, 19200, 57600, 115200, etc */ + // Bauds: 9600, 19200, 57600, 115200, etc int mBaud; - /* Data bit */ + // Data bit unsigned char mDataBit; - /* Stop bit */ + // Stop bit unsigned char mStopBit; - /* Parity: "even", "odd", "none" */ + // Parity: "even", "odd", "none" char mParity[5]; bool mErrorHandling; - enum FlowControl { + enum FlowControl + { eSOFT, eHARD, eNONE @@ -89,24 +91,30 @@ class Serial { FlowControl mFlow; #ifndef WIN32 - /* Save old termios settings */ + // Save old termios settings struct termios mOldTios; #endif bool mConnected; public: - enum WaitMode { - READ, WRITE + enum WaitMode + { + READ, + WRITE }; Serial(const char *aDevice, - int aBaud, const char *aParity, int aDataBit, + int aBaud, + const char *aParity, + int aDataBit, int aStopBit); ~Serial(); - bool connected() { return mConnected; } - bool available() { return mConnected; } + bool connected() const { + return mConnected; } + bool available() const { + return mConnected; } bool connect(); bool disconnect(); @@ -118,13 +126,15 @@ class Serial { int read(char *aBuffer, int len); int readUntil(const char *aUntil, char *aBuffer, int aLength); - int read(char &c) { + int read(char &c) + { char buffer[2]; int ret = read(buffer, 1); c = buffer[0]; return ret; } - int read(unsigned char &b) { + int read(unsigned char &b) + { char c; int ret = read(c); b = (unsigned char) c; @@ -139,7 +149,12 @@ class Serial { // Write cover methods int write(const char *aBuffer); - int print(char c) { char b[2]; b[0] = c; return write(b, 1); } + int print(char c) + { + char b[2]; + b[0] = c; + return write(b, 1); + } bool flushInput(); bool flush(); diff --git a/src/server.cpp b/src/server.cpp index 0fc5025..568fca6 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -35,10 +35,9 @@ #include "client.hpp" #include "logger.hpp" -/* Constants */ const int READ_BUFFER_LEN = 8092; -/* Create the server and bind to the port */ +// Create the server and bind to the port Server::Server(int aPort, int aHeartbeatFreq) { mNumClients = 0; @@ -53,15 +52,18 @@ Server::Server(int aPort, int aHeartbeatFreq) WSADATA w; int iResult = WSAStartup(MAKEWORD(2, 2), &w); - if (iResult != NO_ERROR) { + if (iResult != NO_ERROR) + { gLogger->error("Error at WSAStartup()\n"); exit(1); } + #endif mSocket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (mSocket == INVALID_SOCKET) { + if (mSocket == INVALID_SOCKET) + { gLogger->error("Error at socket().", stderr); delete this; exit(1); @@ -71,13 +73,15 @@ Server::Server(int aPort, int aHeartbeatFreq) t.sin_port = htons(aPort); t.sin_addr.s_addr = htonl(INADDR_ANY); - if (::bind(mSocket, (SOCKADDR *)&t, sizeof(t)) == SOCKET_ERROR) { + if (::bind(mSocket, (SOCKADDR *)&t, sizeof(t)) == SOCKET_ERROR) + { gLogger->error("Failed to bind on port %d", aPort); delete this; exit(1); } - if (listen(mSocket, 4) == SOCKET_ERROR) { + if (listen(mSocket, 4) == SOCKET_ERROR) + { gLogger->error("Error listening."); delete this; exit(1); @@ -89,6 +93,7 @@ Server::Server(int aPort, int aHeartbeatFreq) gLogger->info("Server started, waiting on port %d", aPort); } + Server::~Server() { for (int i = 0; i < mNumClients; i++) @@ -104,6 +109,7 @@ Server::~Server() #endif } + void Server::readFromClients() { MTCAutoLock lock(mListLock); @@ -111,15 +117,19 @@ void Server::readFromClients() fd_set rset; FD_ZERO(&rset); int nfds = 0; + for (int i = 0; i < mNumClients; i++) { Client *client = mClients[i]; FD_SET(client->socket(), &rset); #ifndef WIN32 + if (client->socket() > nfds) nfds = client->socket(); + #endif } + #ifdef WIN32 nfds = mNumClients; #else @@ -134,13 +144,15 @@ void Server::readFromClients() char buffer[READ_BUFFER_LEN]; int len; - /* Since clients can be removed, we need to iterate backwards */ + // Since clients can be removed, we need to iterate backwards for (int i = mNumClients - 1; i >= 0; i--) { Client *client = mClients[i]; + if (FD_ISSET(client->socket(), &rset)) { len = client->read(buffer, READ_BUFFER_LEN); + if (len > 0) { // Check for heartbeat @@ -148,6 +160,7 @@ void Server::readFromClients() { if (!client->mHeartbeats) client->mHeartbeats = true; + client->mLastHeartbeat = getTimestamp(); client->write(mPong); } @@ -166,6 +179,7 @@ void Server::readFromClients() { Client *client = mClients[i]; unsigned int now = getTimestamp(); + if (client->mHeartbeats) { if (deltaTimestamp(now, client->mLastHeartbeat) > (unsigned int) mTimeout) @@ -178,23 +192,26 @@ void Server::readFromClients() } } -void Server::sendToClient(Client *aClient, const char *aString) + +void Server::sendToClient(Client *client, const char *string) { - if (aClient->write(aString) < 0) - removeClient(aClient); + if (client->write(string) < 0) + removeClient(client); } -void Server::sendToClients(const char *aString) + +void Server::sendToClients(const char *string) { MTCAutoLock lock(mListLock); for (int i = mNumClients - 1; i >= 0; i--) { - if (mClients[i]->write(aString) < 0) + if (mClients[i]->write(string) < 0) removeClientInternal(mClients[i]); } } + Client *Server::connectToClients() { fd_set rset; @@ -209,7 +226,7 @@ Client *Server::connectToClients() struct timeval timeout; ::memset(&timeout, 0, sizeof(timeout)); - Client *client = NULL; + Client *client = nullptr; bool added = false; if (::select(nfds, &rset, 0, 0, &timeout) > 0) @@ -218,15 +235,18 @@ Client *Server::connectToClients() socklen_t len = sizeof(addr); memset(&addr, 0, sizeof(addr)); - SOCKET socket = ::accept(mSocket, (SOCKADDR*) &addr, &len); - if (socket == INVALID_SOCKET) { + SOCKET socket = ::accept(mSocket, (SOCKADDR *) &addr, &len); + + if (socket == INVALID_SOCKET) + { gLogger->error("Error at accept()."); return 0; } + gLogger->info("Connected to: %s on port %d", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); int flag = 1; - ::setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (const char*) &flag, sizeof(int)); + ::setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (const char *) &flag, sizeof(int)); client = addClient(new Client(socket)); added = true; @@ -236,59 +256,64 @@ Client *Server::connectToClients() } -void Server::removeClientInternal(Client *aClient) +void Server::removeClientInternal(Client *client) { int pos = 0; + for (pos = 0; pos < mNumClients; pos++) { - if (mClients[pos] == aClient) + if (mClients[pos] == client) break; } if (pos < mNumClients) { mNumClients--; + if (pos < mNumClients) { - /* Shift the array left to remove the item */ + // Shift the array left to remove the item memmove(mClients + pos, mClients + (pos + 1), - (mNumClients - pos) * sizeof(Client*)); + (mNumClients - pos) * sizeof(Client *)); } - delete aClient; - mClients[mNumClients + 1] = 0; + + delete client; client = nullptr; + mClients[mNumClients + 1] = nullptr; } } -/* Removes a client from the client list. -* Because the client can be removed during list iteration, lists -* should always be iterated from last to first. -*/ -void Server::removeClient(Client *aClient) + +// Removes a client from the client list. +// Because the client can be removed during list iteration, lists +// should always be iterated from last to first. +// +void Server::removeClient(Client *client) { MTCAutoLock lock(mListLock); - - removeClientInternal(aClient); + removeClientInternal(client); } -Client *Server::addClient(Client *aClient) + +Client *Server::addClient(Client *client) { MTCAutoLock lock(mListLock); if (mNumClients < MAX_CLIENTS) { - mClients[mNumClients] = aClient; + mClients[mNumClients] = client; mNumClients++; } else { - delete aClient; - aClient = NULL; + delete client; + client = nullptr; } - return aClient; + return client; } + unsigned int Server::getTimestamp() { #ifdef WIN32 @@ -306,15 +331,18 @@ unsigned int Server::getTimestamp() #endif } + unsigned int Server::deltaTimestamp(unsigned int a, unsigned int b) { // Assume we are doing a - b where a should be larger, if it is not // we have a wrap-around unsigned int res; - if ( a >= b ) + + if (a >= b) res = a - b; else // b > a, Compute the distance from the end: res = a + (0xFFFFFFFF - b); + return res; } diff --git a/src/server.hpp b/src/server.hpp index 7ad2da5..4be5794 100755 --- a/src/server.hpp +++ b/src/server.hpp @@ -36,10 +36,9 @@ class Client; -/* Some constants */ const int MAX_CLIENTS = 64; -/* A socket server abstraction */ +// A socket server abstraction class Server { protected: @@ -54,12 +53,11 @@ class Server protected: // Assumes the mutex is already locked. - void removeClientInternal(Client *aClient); + void removeClientInternal(Client *client); // Locks the mutex. - void removeClient(Client *aClient); - - Client *addClient(Client *aClient); + void removeClient(Client *client); + Client *addClient(Client *client); unsigned int getTimestamp(); unsigned int deltaTimestamp(unsigned int, unsigned int); @@ -68,13 +66,12 @@ class Server ~Server(); // Returns the new client. - Client *connectToClients(); /* Client factory */ + Client *connectToClients(); // Client factory - /* I/O methods */ - void readFromClients(); /* discard data on read side of - sockets */ - void sendToClients(const char *aString); - void sendToClient(Client *aClient, const char *aString); + // I/O methods + void readFromClients(); // discard data on read side of sockets + void sendToClients(const char *string); + void sendToClient(Client *client, const char *string); /* Getters */ int numClients() { return mNumClients; } diff --git a/src/service.cpp b/src/service.cpp index b0d5e2b..3cb05da 100644 --- a/src/service.cpp +++ b/src/service.cpp @@ -33,25 +33,30 @@ #include "service.hpp" #include "string.h" + MTConnectService::MTConnectService() : - mIsService(false), mDebug(false) + mName{0}, + mIsService(false), + mDebug(false) { } -void MTConnectService::setName(const char *aName) +void MTConnectService::setName(const char *name) { - strncpy(mName, aName, 78); + strncpy(mName, name, 78); mName[79] = '\0'; } void MTConnectService::initialize(int aArgc, const char *aArgv[]) { - if (gLogger == NULL) { + if (!gLogger) + { if (mIsService) gLogger = new ServiceLogger(); else gLogger = new Logger(); } + if (mDebug) gLogger->setLogLevel(Logger::eDEBUG); } @@ -70,14 +75,14 @@ void MTConnectService::initialize(int aArgc, const char *aArgv[]) SERVICE_STATUS gSvcStatus; SERVICE_STATUS_HANDLE gSvcStatusHandle; -VOID WINAPI SvcCtrlHandler( DWORD ); -VOID WINAPI SvcMain( DWORD, LPTSTR * ); +VOID WINAPI SvcCtrlHandler(DWORD); +VOID WINAPI SvcMain(DWORD, LPTSTR *); -VOID ReportSvcStatus( DWORD, DWORD, DWORD ); -VOID SvcInit( DWORD, LPTSTR * ); -VOID SvcReportEvent( LPTSTR ); +VOID ReportSvcStatus(DWORD, DWORD, DWORD); +VOID SvcInit(DWORD, LPTSTR *); +VOID SvcReportEvent(LPTSTR); -MTConnectService *gService = NULL; +MTConnectService *gService = nullptr; @@ -96,23 +101,31 @@ int MTConnectService::main(int argc, const char *argv[]) // If command-line parameter is "install", install the service. // Otherwise, the service is probably being started by the SCM. - if(argc > 1) { - if (stricmp( argv[1], "debug") == 0 ) { + if (argc > 1) + { + if (!stricmp(argv[1], "debug")) mDebug = true; - } + initialize(argc - 2, argv + 2); - if (stricmp( argv[1], "install") == 0 ) + + if (!stricmp(argv[1], "install")) { install(argc - 2, argv + 2); return 0; - } else if (stricmp( argv[1], "remove") == 0 ) { + } + else if (!stricmp(argv[1], "remove")) + { remove(); return 0; - } else if (stricmp( argv[1], "debug") == 0) { + } + else if (!stricmp(argv[1], "debug")) + { gLogger->setLogLevel(Logger::eDEBUG); start(); return 0; - } else if (stricmp( argv[1], "run") == 0) { + } + else if (!stricmp(argv[1], "run")) + { start(); return 0; } @@ -122,15 +135,13 @@ int MTConnectService::main(int argc, const char *argv[]) SERVICE_TABLE_ENTRY DispatchTable[] = { { mName, (LPSERVICE_MAIN_FUNCTION) SvcMain }, - { NULL, NULL } + { nullptr, nullptr } }; gService = this; - if (!StartServiceCtrlDispatcher( DispatchTable )) - { + if (!StartServiceCtrlDispatcherA(DispatchTable)) SvcReportEvent("StartServiceCtrlDispatcher"); - } return 0; } @@ -147,53 +158,51 @@ int MTConnectService::main(int argc, const char *argv[]) // void MTConnectService::install(int argc, const char *argv[]) { - SC_HANDLE schSCManager; - SC_HANDLE schService; - char szPath[MAX_PATH]; - - if( !GetModuleFileName( NULL, szPath, MAX_PATH ) ) + char szPath[MAX_PATH] = {0}; + if (!GetModuleFileNameA(nullptr, szPath, MAX_PATH)) { printf("Cannot install service (%d)\n", GetLastError()); return; } // Get a handle to the SCM database. - - schSCManager = OpenSCManager( - NULL, // local computer - NULL, // ServicesActive database + auto schSCManager = OpenSCManagerA( + nullptr, // local computer + nullptr, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights - if (NULL == schSCManager) + if (!schSCManager) { printf("OpenSCManager failed (%d)\n", GetLastError()); return; } - schService = OpenService(schSCManager, mName, SC_MANAGER_ALL_ACCESS); - if (schService != NULL) { - if (! ChangeServiceConfig( + auto schService = OpenServiceA(schSCManager, mName, SC_MANAGER_ALL_ACCESS); + if (schService) + { + if (! ChangeServiceConfigA( schService, // handle of service SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // service type: no change SERVICE_AUTO_START, // service start type SERVICE_NO_CHANGE, // error control: no change szPath, // binary path: no change - NULL, // load order group: no change - NULL, // tag ID: no change - NULL, // dependencies: no change - NULL, // account name: no change - NULL, // password: no change - NULL) ) // display name: no change + nullptr, // load order group: no change + nullptr, // tag ID: no change + nullptr, // dependencies: no change + nullptr, // account name: no change + nullptr, // password: no change + nullptr) ) // display name: no change { printf("ChangeServiceConfig failed (%d)\n", GetLastError()); } - else printf("Service updated successfully.\n"); - } else { - + else + printf("Service updated successfully.\n"); + } + else + { // Create the service - - schService = CreateService( + schService = CreateServiceA( schSCManager, // SCM database mName, // name of service mName, // service name to display @@ -203,38 +212,39 @@ void MTConnectService::install(int argc, const char *argv[]) SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type szPath, // path to service's binary - NULL, // no load ordering group - NULL, // no tag identifier - NULL, // no dependencies - NULL, // LocalSystem account - NULL); // no password + nullptr, // no load ordering group + nullptr, // no tag identifier + nullptr, // no dependencies + nullptr, // LocalSystem account + nullptr); // no password - if (schService == NULL) + if (!schService) { printf("CreateService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } - else printf("Service installed successfully\n"); + else + printf("Service installed successfully\n"); } - CloseServiceHandle(schService); - CloseServiceHandle(schSCManager); + CloseServiceHandle(schService); schService = nullptr; + CloseServiceHandle(schSCManager); schSCManager = nullptr; - HKEY software; - LONG res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE", &software); + HKEY software(nullptr); + auto res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE", &software); if (res != ERROR_SUCCESS) { printf("Could not open software key: %d\n", res); return; } - HKEY mtc; - res = RegOpenKey(software, "MTConnect", &mtc); + HKEY mtc(nullptr); + res = RegOpenKeyA(software, "MTConnect", &mtc); if (res != ERROR_SUCCESS) { //printf("Could not open MTConnect, creating: %d\n", res); - res = RegCreateKey(software, "MTConnect", &mtc); + res = RegCreateKeyA(software, "MTConnect", &mtc); if (res != ERROR_SUCCESS) { RegCloseKey(software); @@ -242,15 +252,16 @@ void MTConnectService::install(int argc, const char *argv[]) return; } } + RegCloseKey(software); // Create Service Key - HKEY adapter; - res = RegOpenKey(mtc, mName, &adapter); + HKEY adapter(nullptr); + res = RegOpenKeyA(mtc, mName, &adapter); if (res != ERROR_SUCCESS) { //printf("Could not open %s, creating: %d\n", mName, res); - res = RegCreateKey(mtc, mName, &adapter); + res = RegCreateKeyA(mtc, mName, &adapter); if (res != ERROR_SUCCESS) { RegCloseKey(mtc); @@ -258,43 +269,46 @@ void MTConnectService::install(int argc, const char *argv[]) return; } } + RegCloseKey(mtc); - char arguments[2048]; + char arguments[2048] = {0}; // TODO: create registry entries for arguments to be passed in later to create the adapter multi_sz int d = 0; - for (int i = 0; i < argc; i++) { + for (int i = 0; i < argc; i++) + { strcpy(arguments + d, argv[i]); d += strlen(arguments + d) + 1; } arguments[d] = '\0'; - RegSetValueEx(adapter, "Arguments", 0, REG_MULTI_SZ, (const BYTE*) arguments, d); + RegSetValueExA(adapter, "Arguments", 0, REG_MULTI_SZ, (const BYTE *) arguments, d); RegCloseKey(adapter); } + void MTConnectService::remove() { - SC_HANDLE manager; - SC_HANDLE service; - manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - - if (manager == NULL) { + auto manager = OpenSCManagerA(nullptr, nullptr, SC_MANAGER_ALL_ACCESS); + if (!manager) + { printf("Could not open Service Control Manager"); return; } - service = ::OpenService(manager, mName, SERVICE_ALL_ACCESS); + + auto service = ::OpenServiceA(manager, mName, SERVICE_ALL_ACCESS); CloseServiceHandle(manager); - if (service == NULL) { + + if (!service) + { printf("Could not open Service "); return; } - if(::DeleteService(service) == 0) { + if (!::DeleteService(service)) printf("Could delete service %s\n", mName); - } else { + else printf("Successfully removed service %s\n", mName); - } ::CloseServiceHandle(service); } @@ -313,49 +327,49 @@ void MTConnectService::remove() // Return value: // None. // -VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv ) +VOID WINAPI SvcMain(DWORD dwArgc, LPTSTR *lpszArgv) { // Register the handler function for the service - char path[MAX_PATH]; - if( !GetModuleFileName(NULL, path, MAX_PATH ) ) + char path[MAX_PATH] = {0}; + + if (!GetModuleFileNameA(nullptr, path, MAX_PATH)) { printf("Cannot get path of executable (%d)\n", GetLastError()); return; } - char *cp = strrchr(path, '\\'); - if (cp != NULL) + auto cp = strrchr(path, '\\'); + if (cp != nullptr) { *cp = '\0'; - SetCurrentDirectory(path); + SetCurrentDirectoryA(path); } gService->setName(lpszArgv[0]); - gSvcStatusHandle = RegisterServiceCtrlHandler( + gSvcStatusHandle = RegisterServiceCtrlHandlerA( gService->name(), SvcCtrlHandler); - if( !gSvcStatusHandle ) + if (!gSvcStatusHandle) { SvcReportEvent("RegisterServiceCtrlHandler"); return; } // These SERVICE_STATUS members remain as set here - gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; gSvcStatus.dwServiceSpecificExitCode = 0; // Report initial status to the SCM - - ReportSvcStatus( SERVICE_START_PENDING, NO_ERROR, 10000 ); + ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 10000ul); // Perform service-specific initialization and work. Sleep(20000); - SvcInit( dwArgc, lpszArgv ); + SvcInit(dwArgc, lpszArgv); } + // // Purpose: // The service code @@ -369,43 +383,47 @@ VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv ) // Return value: // None // -VOID SvcInit( DWORD dwArgc, LPTSTR *lpszArgv) +VOID SvcInit(DWORD dwArgc, LPTSTR *lpszArgv) { // Get the real arguments from the registry - char key[1024]; + char key[1024] = {0}; snprintf(key, 1022, "SOFTWARE\\MTConnect\\%s", gService->name()); key[1023] = '\0'; - HKEY adapter; - LONG res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &adapter); + HKEY adapter(nullptr); + auto res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &adapter); if (res != ERROR_SUCCESS) { SvcReportEvent("RegOpenKey: Could not open Adapter"); - ReportSvcStatus( SERVICE_STOPPED, 1, 0 ); + ReportSvcStatus(SERVICE_STOPPED, 1ul, 0ul); return; } - char *argp[64]; - BYTE arguments[2048]; - DWORD len = 2047, type, argc = 0; - res = RegQueryValueEx(adapter, "Arguments", 0, &type, (BYTE*) arguments, &len); + char *argp[64] = {0}; + BYTE arguments[2048] = {0}; + DWORD len = 2047ul, type, argc = 0ul; + res = RegQueryValueExA(adapter, "Arguments", 0, &type, (BYTE *) arguments, &len); if (res == ERROR_SUCCESS) { - DWORD i = 0; - while (i < len) { - argp[argc] = (char*) arguments + i; - i += strlen((char*) arguments + i) + 1; + DWORD i = 0ul; + while (i < len) + { + argp[argc] = (char *) arguments + i; + i += strlen((char *) arguments + i) + 1ul; argc++; } + argp[argc] = 0; - } else { + } + else + { SvcReportEvent("RegOpenKey: Could not get Arguments"); RegCloseKey(adapter); - ReportSvcStatus( SERVICE_STOPPED, 1, 0 ); + ReportSvcStatus(SERVICE_STOPPED, 1ul, 0ul); return; } - gService->initialize(argc, (const char**) argp); + gService->initialize(argc, (const char **) argp); // TO_DO: Declare and set any required variables. // Be sure to periodically call ReportSvcStatus() with @@ -416,15 +434,14 @@ VOID SvcInit( DWORD dwArgc, LPTSTR *lpszArgv) // signals this event when it receives the stop control code. // Report running status when initialization is complete. - - ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 ); + ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0ul); // TO_DO: Perform work until service stops. gService->start(); - - ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 ); + ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0ul); } + // // Purpose: // Sets the current service status and reports it to the SCM. @@ -438,11 +455,12 @@ VOID SvcInit( DWORD dwArgc, LPTSTR *lpszArgv) // Return value: // None // -VOID ReportSvcStatus( DWORD dwCurrentState, +VOID ReportSvcStatus( + DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) { - static DWORD dwCheckPoint = 1; + static DWORD dwCheckPoint = 1ul; // Fill in the SERVICE_STATUS structure. @@ -455,16 +473,19 @@ VOID ReportSvcStatus( DWORD dwCurrentState, else gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; - if ( (dwCurrentState == SERVICE_RUNNING) || - (dwCurrentState == SERVICE_STOPPED) ) + if (dwCurrentState == SERVICE_RUNNING || + dwCurrentState == SERVICE_STOPPED ) + { gSvcStatus.dwCheckPoint = 0; + } else gSvcStatus.dwCheckPoint = dwCheckPoint++; // Report the status of the service to the SCM. - SetServiceStatus( gSvcStatusHandle, &gSvcStatus ); + SetServiceStatus(gSvcStatusHandle, &gSvcStatus); } + // // Purpose: // Called by SCM whenever a control code is sent to the service @@ -476,17 +497,19 @@ VOID ReportSvcStatus( DWORD dwCurrentState, // Return value: // None // -VOID WINAPI SvcCtrlHandler( DWORD dwCtrl ) +VOID WINAPI SvcCtrlHandler(DWORD dwCtrl) { // Handle the requested control code. - switch(dwCtrl) + switch (dwCtrl) { case SERVICE_CONTROL_STOP: - ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); - if (gService != NULL) + ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0ul); + + if (gService) gService->stop(); - ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0); + + ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0ul); return; @@ -499,6 +522,7 @@ VOID WINAPI SvcCtrlHandler( DWORD dwCtrl ) } + // // Purpose: // Logs messages to the event log @@ -512,91 +536,102 @@ VOID WINAPI SvcCtrlHandler( DWORD dwCtrl ) // Remarks: // The service must have an entry in the Application event log. // -VOID SvcReportEvent(LPTSTR szFunction) +VOID SvcReportEvent(LPTSTR functionName) { - HANDLE hEventSource; - LPCTSTR lpszStrings[2]; - char Buffer[80]; + HANDLE hEventSource(nullptr); + LPCTSTR lpszStrings[2] = {nullptr, nullptr}; + char Buffer[80] = {0}; - hEventSource = RegisterEventSource(NULL, gService->name()); + hEventSource = RegisterEventSourceA(nullptr, gService->name()); - if( NULL != hEventSource ) + if (hEventSource) { - sprintf(Buffer, "%-60s failed with %d", szFunction, GetLastError()); + sprintf(Buffer, "%-60s failed with %d", functionName, GetLastError()); lpszStrings[0] = gService->name(); lpszStrings[1] = Buffer; - ReportEvent(hEventSource, // event log handle + ReportEventA(hEventSource, // event log handle EVENTLOG_ERROR_TYPE, // event type 0, // event category SVC_ERROR, // event identifier - NULL, // no security identifier + nullptr, // no security identifier 2, // size of lpszStrings array - 0, // no binary data + 0ul, // no binary data lpszStrings, // array of strings - NULL); // no binary data + nullptr); // no binary data DeregisterEventSource(hEventSource); } } -VOID SvcLogEvent(WORD aType, DWORD aId, LPSTR aText) -{ - HANDLE hEventSource; - LPCTSTR lpszStrings[3]; - hEventSource = RegisterEventSource(NULL, gService->name()); +VOID SvcLogEvent(WORD type, DWORD id, LPSTR text) +{ + HANDLE hEventSource(nullptr); + LPCTSTR lpszStrings[3] = {nullptr}; - if( NULL != hEventSource ) + hEventSource = RegisterEventSourceA(nullptr, gService->name()); + if (hEventSource) { lpszStrings[0] = gService->name(); lpszStrings[1] = "\n\n"; - lpszStrings[2] = aText; + lpszStrings[2] = text; - ReportEvent(hEventSource, // event log handle - aType, // event type + ReportEventA(hEventSource, // event log handle + type, // event type 0, // event category - aId, // event identifier - NULL, // no security identifier + id, // event identifier + nullptr, // no security identifier 3, // size of lpszStrings array 0, // no binary data lpszStrings, // array of strings - NULL); // no binary data + nullptr); // no binary data DeregisterEventSource(hEventSource); } } -void ServiceLogger::error(const char *aFormat, ...) +void ServiceLogger::error(const char *inputFormat, ...) { - char buffer[LOGGER_BUFFER_SIZE]; + char buffer[LOGGER_BUFFER_SIZE] = {0}; va_list args; - va_start (args, aFormat); - SvcLogEvent(EVENTLOG_ERROR_TYPE, SVC_ERROR, (LPSTR) format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); - va_end (args); + va_start(args, inputFormat); + SvcLogEvent( + EVENTLOG_ERROR_TYPE, + SVC_ERROR, + (LPSTR)format(buffer, LOGGER_BUFFER_SIZE, inputFormat, args)); + va_end(args); } -void ServiceLogger::warning(const char *aFormat, ...) + +void ServiceLogger::warning(const char *inputFormat, ...) { - char buffer[LOGGER_BUFFER_SIZE]; + char buffer[LOGGER_BUFFER_SIZE] = {0}; va_list args; - va_start (args, aFormat); - SvcLogEvent(EVENTLOG_WARNING_TYPE, SVC_WARNING, (LPSTR) format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); - va_end (args); + va_start(args, inputFormat); + SvcLogEvent( + EVENTLOG_WARNING_TYPE, + SVC_WARNING, (LPSTR)format(buffer, LOGGER_BUFFER_SIZE, inputFormat, args)); + va_end(args); } -void ServiceLogger::info(const char *aFormat, ...) + +void ServiceLogger::info(const char *inputFormat, ...) { - char buffer[LOGGER_BUFFER_SIZE]; + char buffer[LOGGER_BUFFER_SIZE] = {0}; va_list args; - va_start (args, aFormat); - SvcLogEvent(EVENTLOG_INFORMATION_TYPE, SVC_INFO, (LPSTR) format(buffer, LOGGER_BUFFER_SIZE, aFormat, args)); - va_end (args); + va_start(args, inputFormat); + SvcLogEvent( + EVENTLOG_INFORMATION_TYPE, + SVC_INFO, + (LPSTR) format(buffer, LOGGER_BUFFER_SIZE, inputFormat, args)); + va_end(args); } -void ServiceLogger::debug(const char *aFormat, ...) + +void ServiceLogger::debug(const char *inputFormat, ...) { // Debug service logging is not supported } diff --git a/src/service.hpp b/src/service.hpp index d1f97c1..6f193a7 100644 --- a/src/service.hpp +++ b/src/service.hpp @@ -36,16 +36,20 @@ #define SERVICE_NAME_LEN 80 -class MTConnectService { + +class MTConnectService +{ public: MTConnectService(); - virtual int main(int aArgc, const char *aArgv[]); - virtual void initialize(int aArgc, const char *aArgv[]) = 0; - void setName(const char *aName); + virtual int main(int argc, const char *argv[]); + virtual void initialize(int argc, const char *argv[]) = 0; virtual void stop() = 0; virtual void start() = 0; - const char *name() { return mName; } + + void setName(const char *name); + const char *name() const { + return mName; } protected: char mName[SERVICE_NAME_LEN]; @@ -56,16 +60,18 @@ class MTConnectService { void remove(); }; + #ifdef WIN32 -class ServiceLogger : public Logger { -public: - virtual void error(const char *aFormat, ...); - virtual void warning(const char *aFormat, ...); - virtual void info(const char *aFormat, ...); - virtual void debug(const char *aFormat, ...); + class ServiceLogger : public Logger + { + public: + void error(const char *inputFormat, ...) override; + void warning(const char *inputFormat, ...) override; + void info(const char *inputFormat, ...) override; + void debug(const char *inputFormat, ...) override; -protected: -}; + protected: + }; #else -class ServiceLogger : public Logger {}; + class ServiceLogger : public Logger {}; #endif diff --git a/src/string_array.cpp b/src/string_array.cpp index 8e37e19..b95e5d6 100644 --- a/src/string_array.cpp +++ b/src/string_array.cpp @@ -35,31 +35,38 @@ #define BLOCK_SIZE 256 + StringArray::StringArray() { mLength = 0; mSize = BLOCK_SIZE; - mArray = (char **) malloc(sizeof(char*) * mSize); + mArray = (char **) malloc(sizeof(char *) * mSize); mArray[mLength = 0]; } + StringArray::~StringArray() { clear(); free(mArray); + mArray = nullptr; } + void StringArray::clear() { for (int i = 0; i < mLength; i++) free(mArray[i]); + mLength = 0; } -void StringArray::append(const char *aString) + +void StringArray::append(const char *string) { - char *dup = strdup(aString); - if (dup == 0) + char *dup = strdup(string); + + if (!dup) { perror("StringArray::append"); exit(2); @@ -68,8 +75,9 @@ void StringArray::append(const char *aString) if (mLength >= mSize - 1) { mSize += BLOCK_SIZE; - mArray = (char**) realloc(mArray, mSize * sizeof(char*)); - if (mArray == 0) + mArray = (char **) realloc(mArray, mSize * sizeof(char *)); + + if (!mArray) { perror("StringArray::append"); exit(2); @@ -79,33 +87,33 @@ void StringArray::append(const char *aString) mArray[mLength++] = dup; } -int StringArray::readFile(const char *aFileName) + +int StringArray::readFile(const char *fileName) { // First clear out existing contents clear(); // Parse file. - FILE *file = fopen(aFileName, "r"); - if (file == 0) - { - printf("Could not open file: %s\n", aFileName); - } + auto file = fopen(fileName, "r"); + + if (!file) + printf("Could not open file: %s\n", fileName); else { - printf("Parsing file: %s\n", aFileName); - char buffer[1024]; + printf("Parsing file: %s\n", fileName); + char buffer[1024] = {0}; + while (fgets(buffer, 1024, file) != 0) { int last = strlen(buffer) - 1; + if (last > 0 && buffer[last] == '\n') buffer[last] = 0; + append(buffer); } } + return mLength; } - - - - diff --git a/src/string_array.hpp b/src/string_array.hpp index 4afe5bb..db85b7e 100755 --- a/src/string_array.hpp +++ b/src/string_array.hpp @@ -32,12 +32,10 @@ // #pragma once - -/* - * A string array that atomaticially resizes when the size is - * exceeded. Used for storing the program codes - */ - +// +// A string array that atomaticially resizes when the size is +// exceeded. Used for storing the program codes +// class StringArray { protected: @@ -49,25 +47,28 @@ class StringArray StringArray(); ~StringArray(); - int length() { return mLength; } + int length() const { + return mLength; } // Copies the string when it is appended - void append(const char *aString); + void append(const char *string); void clear(); // Getters - const char *stringAt(int index); - const char *operator[](int index) { return stringAt(index); } + const char *stringAt(int index) const; + const char *operator[](int index) const { + return stringAt(index); } // File Handler method, should be another class... // Returns file size. - int readFile(const char *aFileName); + int readFile(const char *fileName); }; -inline const char *StringArray::stringAt(int index) + +inline const char *StringArray::stringAt(int index) const { if (index >= 0 && index < mLength) return mArray[index]; else - return 0; + return nullptr; } diff --git a/src/string_buffer.cpp b/src/string_buffer.cpp index 0135e35..78c2dfa 100755 --- a/src/string_buffer.cpp +++ b/src/string_buffer.cpp @@ -33,38 +33,42 @@ #include "internal.hpp" #include "string_buffer.hpp" -StringBuffer::StringBuffer(const char *aString) + +StringBuffer::StringBuffer(const char *string) : + mBuffer(nullptr), + mSize(0u), + mLength(0u), + mTimestamp{0} { - mLength = mSize = 0; - mTimestamp[0] = 0; - if (aString != 0) - { - append(aString); - } - else - { - mBuffer = 0; - } + if (string) + append(string); } + StringBuffer::~StringBuffer() { - if (mBuffer != 0) + if (mBuffer) + { free(mBuffer); + mBuffer = nullptr; + } } -const char *StringBuffer::append(const char* aString) + +const char *StringBuffer::append(const char *string) { - /* Include additional length for timestamp */ - size_t len = strlen(aString); - size_t totalLength = mLength + len; - size_t tsLen = strlen(mTimestamp); - if (mLength == 0) + // Include additional length for timestamp + auto len = strlen(string); + auto totalLength = mLength + len; + auto tsLen = strlen(mTimestamp); + + if (!mLength) totalLength += tsLen; + if (totalLength >= mSize) { - size_t newLen = ((totalLength / 1024) + 1) * 1024; - char *newBuffer = (char*) malloc(newLen); + auto newLen = ((totalLength / 1024u) + 1u) * 1024u; + auto newBuffer = (char *) malloc(newLen); memcpy(newBuffer, mBuffer, mLength); free(mBuffer); @@ -72,49 +76,62 @@ const char *StringBuffer::append(const char* aString) mSize = newLen; } - if (mLength == 0 && tsLen > 0) + if (!mLength && tsLen > 0) { strcpy(mBuffer, mTimestamp); mLength += tsLen; } - strcpy(mBuffer + mLength, aString); + strcpy(mBuffer + mLength, string); mLength += len; return mBuffer; } + void StringBuffer::newline() { append("\n"); append(mTimestamp); } + void StringBuffer::reset() { - if (mBuffer != 0) + if (mBuffer) { mBuffer[0] = 0; - mLength = 0; + mLength = 0u; } } + void StringBuffer::timestamp() { #ifdef WIN32 SYSTEMTIME st; GetSystemTime(&st); - sprintf(mTimestamp, "%4d-%02d-%02dT%02d:%02d:%02d.%03dZ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); + sprintf( + mTimestamp, + "%4d-%02d-%02dT%02d:%02d:%02d.%03dZ", + st.wYear, + st.wMonth, + st.wDay, + st.wHour, + st.wMinute, + st.wSecond, + st.wMilliseconds); #else struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); - strftime(mTimestamp, 64, "%Y-%m-%dT%H:%M:%S", gmtime(&tv.tv_sec)); + strftime( + mTimestamp, + 64, + "%Y-%m-%dT%H:%M:%S", + gmtime(&tv.tv_sec)); sprintf(mTimestamp + strlen(mTimestamp), ".%06dZ", tv.tv_usec); #endif } - - - diff --git a/src/string_buffer.hpp b/src/string_buffer.hpp index f4306f8..9ac90a7 100755 --- a/src/string_buffer.hpp +++ b/src/string_buffer.hpp @@ -32,32 +32,35 @@ // #pragma once - -/* - * A simple extensible string that can be appended to. The memory will be reused - * since it maintains its length. The string buffer also supports setting a timestamp - * that will be prepended to the string once some data is appended. - * - * Currently allocating in 1k increments. - */ +// +// A simple extensible string that can be appended to. The memory will be reused +// since it maintains its length. The string buffer also supports setting a timestamp +// that will be prepended to the string once some data is appended. +// +// Currently allocating in 1k increments. +// class StringBuffer { protected: - char *mBuffer; /* A resizable character buffer */ - size_t mSize; /* The allocated size of the string */ - size_t mLength; /* The length of the string */ + char *mBuffer; // A resizable character buffer + size_t mSize; // The allocated size of the string + size_t mLength; // The length of the string char mTimestamp[64]; public: - StringBuffer(const char *aString = 0); + StringBuffer(const char *string = nullptr); ~StringBuffer(); - operator const char *() { return mBuffer; } - const char *append(const char *aString); - const char* operator<<(const char *aString) { return append(aString); } + operator const char *() const { + return mBuffer; } + const char *append(const char *string); + const char *operator<<(const char *string) { + return append(string); } void reset(); void timestamp(); - void setTimestamp(const char *aTs) { strcpy(mTimestamp, aTs); } - size_t length() { return mLength; } + void setTimestamp(const char *timestamp) { + strcpy_s(mTimestamp, timestamp); } + size_t length() const { + return mLength; } void newline(); }; diff --git a/src/threading.hpp b/src/threading.hpp index f908cc9..ec522be 100644 --- a/src/threading.hpp +++ b/src/threading.hpp @@ -35,13 +35,14 @@ #ifdef THREADED #ifndef WIN32 -#include + #include #endif class MTCMutex { public: - MTCMutex() { + MTCMutex() + { #ifdef WIN32 InitializeCriticalSection(&mLock); #else @@ -49,7 +50,8 @@ class MTCMutex #endif } - ~MTCMutex() { + ~MTCMutex() + { #ifdef WIN32 DeleteCriticalSection(&mLock); #else @@ -57,7 +59,8 @@ class MTCMutex #endif } - void lock() { + void lock() + { #ifdef WIN32 EnterCriticalSection(&mLock); #else @@ -65,7 +68,8 @@ class MTCMutex #endif } - void unlock() { + void unlock() + { #ifdef WIN32 LeaveCriticalSection(&mLock); #else @@ -81,7 +85,8 @@ class MTCMutex #endif private: - MTCMutex(const MTCMutex& aMutex) { + MTCMutex(const MTCMutex& aMutex) + { // No copy constructor is possible } }; @@ -97,13 +102,17 @@ class MTCMutex #endif -class MTCAutoLock { +class MTCAutoLock +{ public: - MTCAutoLock(MTCMutex &aMutex) : mMutex(&aMutex) { + MTCAutoLock(MTCMutex &aMutex) : + mMutex(&aMutex) + { mMutex->lock(); } - ~MTCAutoLock() { + ~MTCAutoLock() + { mMutex->unlock(); } @@ -111,5 +120,8 @@ class MTCAutoLock { MTCMutex *mMutex; private: - MTCAutoLock() : mMutex(NULL) {} + MTCAutoLock() : + mMutex(nullptr) + { + } }; diff --git a/src/time_series.cpp b/src/time_series.cpp index 9512ecc..659aa9b 100644 --- a/src/time_series.cpp +++ b/src/time_series.cpp @@ -36,27 +36,29 @@ using namespace std; -/* - * TimeSeries methods - */ -TimeSeries::TimeSeries(const char *aName, float aEpsilon, float aRate) - : DeviceDatum(aName), mEpsilon(aEpsilon), mRate(aRate) + +TimeSeries::TimeSeries(const char *name, float epsilon, float rate) : + DeviceDatum(name), + mUnavailable(false), + mEpsilon(epsilon), + mRate(rate) { - mUnavailable = false; } -void TimeSeries::addValue(float aValue) + +void TimeSeries::addValue(float value) { - mValues.push_back(aValue); + mValues.push_back(value); mChanged = true; mHasValue = true; mUnavailable = false; } -bool TimeSeries::setValue(std::vector aValues) + +bool TimeSeries::setValue(std::vector values) { - mValues = aValues; + mValues = values; mChanged = true; mHasValue = true; @@ -65,25 +67,26 @@ bool TimeSeries::setValue(std::vector aValues) return true; } -bool TimeSeries::append(StringBuffer &aStringBuffer) + +bool TimeSeries::append(StringBuffer &stringBuffer) { - char buffer[1024]; + char buffer[1024] = {0}; if (mUnavailable) { - snprintf(buffer, 1023, "|%s|0||UNAVAILABLE", mName); - aStringBuffer.append(buffer); + snprintf(buffer, 1023u, "|%s|0||UNAVAILABLE", mName); + stringBuffer.append(buffer); } else { if (mRate > 0) - snprintf(buffer, 1023, "|%s|%d|%g|", mName, (int) mValues.size(), mRate); + snprintf(buffer, 1023u, "|%s|%d|%g|", mName, (int) mValues.size(), mRate); else - snprintf(buffer, 1023, "|%s|%d||", mName, (int) mValues.size()); - aStringBuffer.append(buffer); - for (size_t i = 0; i < mValues.size(); i++) + snprintf(buffer, 1023u, "|%s|%d||", mName, (int) mValues.size()); + stringBuffer.append(buffer); + for (auto i = 0u; i < mValues.size(); i++) { snprintf(buffer, 1023, "%.10g ", mValues[i]); - aStringBuffer.append(buffer); + stringBuffer.append(buffer); } } @@ -91,11 +94,13 @@ bool TimeSeries::append(StringBuffer &aStringBuffer) return true; } -char *TimeSeries::toString(char *aBuffer, int aMaxLen) + +char *TimeSeries::toString(char *buffer, int maxLen) { - return aBuffer; + return buffer; } + bool TimeSeries::unavailable() { if (!mUnavailable) @@ -108,7 +113,8 @@ bool TimeSeries::unavailable() return mChanged; } -bool TimeSeries::requiresFlush() + +bool TimeSeries::requiresFlush() const { return true; } diff --git a/src/time_series.hpp b/src/time_series.hpp index a8395dc..e218608 100644 --- a/src/time_series.hpp +++ b/src/time_series.hpp @@ -35,10 +35,9 @@ #include "device_datum.hpp" #include -/* - * A time series of samples - */ - +// +// A time series of samples +// class TimeSeries : public DeviceDatum { protected: @@ -48,21 +47,29 @@ class TimeSeries : public DeviceDatum float mRate; public: - TimeSeries(const char *aName, float aEpsilon = 0.000001, - float aRate = -1.0); + TimeSeries(const char *mame, float epsilon = 0.000001, float rate = -1.0); - bool setValue(std::vector aValues); - void addValue(float aValue); - std::vector &getValues() { return mValues; } - int getCount() { return mValues.size(); } - void clear() { mValues.clear(); } - float getRate() { return mRate; } - void setRate(float aRate) { mRate = aRate; } + bool setValue(std::vector values); + void addValue(float value); - virtual char *toString(char *aBuffer, int aMaxLen); - virtual bool unavailable(); - virtual bool requiresFlush(); - virtual bool append(StringBuffer &aBuffer); -}; + std::vector &getValues() { + return mValues; } + const std::vector &getValues() const { + return mValues; } + int getCount() const { + return mValues.size(); } + void clear() { + mValues.clear(); } + float getRate() const { + return mRate; } + void setRate(float rate) { + mRate = rate; } +// Overrides from DeviceDatum +public: + char *toString(char *buffer, int maxLen) override; + bool unavailable() override; + bool requiresFlush() const override; + bool append(StringBuffer &buffer) override; +}; From 3a7cd1eb8d32ddef066f2867ce795eed6940b9a8 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:15:25 +0100 Subject: [PATCH 16/41] BUG FIX: Fixed reading of macro variables in the Fanuc adapter * The incorrect amount of memory was being allocated, replaced using std::vector to make memory management neater --- fanuc/fanuc_adapter.cpp | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/fanuc/fanuc_adapter.cpp b/fanuc/fanuc_adapter.cpp index 1564492..3dea230 100644 --- a/fanuc/fanuc_adapter.cpp +++ b/fanuc/fanuc_adapter.cpp @@ -376,22 +376,27 @@ void FanucAdapter::getMacros() // For now we assume they are close in range. If this proves to not // be true, we will have to get more creative. - auto macros = new IODBMR[mMacroMax - mMacroMin]; - short ret = cnc_rdmacror(mFlibhndl, + std::vector rawData; + auto count = (mMacroMax - mMacroMin) + 1; + rawData.resize(count); + + short ret = cnc_rdmacror( + mFlibhndl, mMacroMin, mMacroMax, - sizeof(IODBMR) * (mMacroMax - mMacroMin + 1), - macros); + sizeof(IODBMR) * count, + &rawData[0]); if (ret == EW_OK) { for (auto i = 0; i < mMacroSampleCount; i++) { auto off = mMacroSample[i]->getNumber() - mMacroMin; - if (macros->data[off].mcr_val != 0 || macros->data[off].dec_val != -1) + auto const &variableData = rawData[0].data[off]; + if (variableData.mcr_val != 0 || variableData.dec_val != -1) { - mMacroSample[i]->setValue(((double) macros->data[off].mcr_val) / - pow(10.0, macros->data[off].dec_val)); + mMacroSample[i]->setValue(((double) variableData.mcr_val) / + pow(10.0, variableData.dec_val)); } else { @@ -404,16 +409,16 @@ void FanucAdapter::getMacros() auto y = mMacroPath[i]->getY() - mMacroMin; auto z = mMacroPath[i]->getZ() - mMacroMin; - if ((macros->data[x].mcr_val != 0 || macros->data[x].dec_val != -1) && - (macros->data[y].mcr_val != 0 || macros->data[y].dec_val != -1) && - (macros->data[z].mcr_val != 0 || macros->data[z].dec_val != -1)) + if ((rawData[0].data[x].mcr_val != 0 || rawData[0].data[x].dec_val != -1) && + (rawData[0].data[y].mcr_val != 0 || rawData[0].data[y].dec_val != -1) && + (rawData[0].data[z].mcr_val != 0 || rawData[0].data[z].dec_val != -1)) { - mMacroPath[i]->setValue(((double) macros->data[x].mcr_val) / - pow(10.0, macros->data[x].dec_val), - ((double) macros->data[y].mcr_val) / - pow(10.0, macros->data[y].dec_val), - ((double) macros->data[z].mcr_val) / - pow(10.0, macros->data[z].dec_val)); + mMacroPath[i]->setValue(((double) rawData[0].data[x].mcr_val) / + pow(10.0, rawData[0].data[x].dec_val), + ((double) rawData[0].data[y].mcr_val) / + pow(10.0, rawData[0].data[y].dec_val), + ((double) rawData[0].data[z].mcr_val) / + pow(10.0, rawData[0].data[z].dec_val)); } else { @@ -423,8 +428,6 @@ void FanucAdapter::getMacros() } else std::cout << "Could not read macro variables: " << ret << std::endl; - - delete[] macros; } From 7f0339c053f40fb6738ea578b802a450f906f190 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:15:36 +0100 Subject: [PATCH 17/41] BUG FIX: Fixed typo in Fanuc adapter that incorrect set wrong variable as 'unavailable' --- fanuc/fanuc_adapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fanuc/fanuc_adapter.cpp b/fanuc/fanuc_adapter.cpp index 3dea230..8eccc37 100644 --- a/fanuc/fanuc_adapter.cpp +++ b/fanuc/fanuc_adapter.cpp @@ -422,7 +422,7 @@ void FanucAdapter::getMacros() } else { - mMacroSample[i]->unavailable(); + mMacroPath[i]->unavailable(); } } } From 5aee991a959922287391ab203027a97b66f16aaf Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:15:49 +0100 Subject: [PATCH 18/41] C++11 Conversion: Improved memory storage for paths in the Fanuc adapter * Converted from raw pointers to std::unique_ptr --- fanuc/fanuc_adapter.cpp | 29 ++++++++++++++--------------- fanuc/fanuc_adapter.hpp | 4 ++-- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/fanuc/fanuc_adapter.cpp b/fanuc/fanuc_adapter.cpp index 8eccc37..a762c03 100644 --- a/fanuc/fanuc_adapter.cpp +++ b/fanuc/fanuc_adapter.cpp @@ -35,7 +35,6 @@ constexpr std::size_t countof(T const (&)[N]) noexcept FanucAdapter::FanucAdapter(int aPort) : Adapter(aPort), - mMaxPath(0), mMessage("message"), mAvail("avail"), mPartCount("part_count"), @@ -67,8 +66,8 @@ FanucAdapter::FanucAdapter(int aPort) : FanucAdapter::~FanucAdapter() { - for (auto path : mPaths) - delete path; + for (auto &path : mPaths) + path.release(); mPaths.clear(); disconnect(); @@ -285,28 +284,28 @@ void FanucAdapter::configure() gLogger->info("Configuring...\n"); - short path(0); - auto ret = cnc_getpath(mFlibhndl, &path, &mMaxPath); + short path(0), maxNumPaths(0); + auto ret = cnc_getpath(mFlibhndl, &path, &maxNumPaths); if (ret != EW_OK) { gLogger->error("Cannot find number of paths: %d", ret); - mMaxPath = 1; + maxNumPaths = 1; path = 1; } - for (auto pathNum = 1; pathNum <= mMaxPath; pathNum++) + for (auto pathNum = 1; pathNum <= maxNumPaths; pathNum++) { - auto fanucPath = new FanucPath(this, pathNum); + auto fanucPath = std::make_unique(this, pathNum); if (!fanucPath->configure(mFlibhndl)) { gLogger->error("Could not configure path: %d", pathNum); exit(1); } - mPaths.push_back(fanucPath); + mPaths.push_back(std::move(fanucPath)); } - gLogger->info("Current path: %d, maximum paths: %d", path, mMaxPath); + gLogger->info("Current path: %d, maximum paths: %d", path, maxNumPaths); mConfigured = true; } @@ -487,7 +486,7 @@ void FanucAdapter::getCounts() return; // Should just be a parameter read - IODBPSD buf; + IODBPSD buf = {0}; auto ret = cnc_rdparam(mFlibhndl, 6711, 0, 8, &buf); if (ret == EW_OK) mPartCount.setValue(buf.u.ldata); @@ -499,15 +498,15 @@ void FanucAdapter::getPathData() if (!mConnected) return; - int i; - for (i = mMaxPath - 1; i >= 0; i--) + for(auto &path : mPaths) { - if (!mPaths[i]->gatherData(mFlibhndl)) + if(!path->gatherData(mFlibhndl)) { disconnect(); break; } } - if (mConnected && i > 0) + + if (mConnected && mPaths.size() > 0) cnc_setpath(mFlibhndl, 0); } diff --git a/fanuc/fanuc_adapter.hpp b/fanuc/fanuc_adapter.hpp index 84948a2..7ddc51c 100644 --- a/fanuc/fanuc_adapter.hpp +++ b/fanuc/fanuc_adapter.hpp @@ -15,6 +15,7 @@ // #pragma once #include +#include #include #include #include @@ -76,8 +77,7 @@ class FanucAdapter : public Adapter, public MTConnectService { protected: // Define all the data values here - short mMaxPath; - std::vector mPaths; + std::vector> mPaths; // Conditions From ea456c2494cd46b4d3818d2421bf1c95c7f033a6 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:16:01 +0100 Subject: [PATCH 19/41] C++11 Conversion: Improved memory storage for macro variables in the Fanuc adapter * Use of std::vector for memory management --- fanuc/fanuc_adapter.cpp | 48 ++++++++++++++++++----------------------- fanuc/fanuc_adapter.hpp | 8 +++---- 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/fanuc/fanuc_adapter.cpp b/fanuc/fanuc_adapter.cpp index a762c03..0d5034b 100644 --- a/fanuc/fanuc_adapter.cpp +++ b/fanuc/fanuc_adapter.cpp @@ -38,12 +38,8 @@ FanucAdapter::FanucAdapter(int aPort) : mMessage("message"), mAvail("avail"), mPartCount("part_count"), - mMacroSample{0}, - mMacroPath{0}, mMacroMin(99999), mMacroMax(0), - mMacroSampleCount(0), - mMacroPathCount(0), mPMCVariable{0}, mPMCAddress{0}, mPMCCount(0), @@ -220,9 +216,9 @@ void FanucAdapter::configMacrosAndPMC(const char *iniFile) if (cp == n) continue; - auto i = mMacroPathCount++; - mMacroPath[i] = new MacroPathPosition(name, x, y, z); - addDatum(*mMacroPath[i]); + auto macroPathPos = new MacroPathPosition(name, x, y, z); + mMacroPathPositions.push_back(macroPathPos); + addDatum(*macroPathPos); std::cout << "Adding path macro '" << name << "' at location" << x << " " << y << " " << z << std::endl; @@ -246,9 +242,9 @@ void FanucAdapter::configMacrosAndPMC(const char *iniFile) auto v = strtol(cp, &n, 10); if (cp == n) continue; - auto i = mMacroSampleCount++; - mMacroSample[i] = new MacroSample(name, v); - addDatum(*mMacroSample[i]); + auto macroSample = new MacroSample(name, v); + mMacroSamples.push_back(macroSample); + addDatum(*macroSample); std::cout << "Adding sample macro '" << name << "' at location " << v << std::endl; @@ -370,7 +366,7 @@ void FanucAdapter::getMacros() if (!mConnected) return; - if (mMacroSampleCount == 0 && mMacroPathCount == 0) + if (mMacroSamples.size() == 0 && mMacroPathPositions.size() == 0) return; // For now we assume they are close in range. If this proves to not @@ -388,40 +384,38 @@ void FanucAdapter::getMacros() if (ret == EW_OK) { - for (auto i = 0; i < mMacroSampleCount; i++) + for (auto macroSample : mMacroSamples) { - auto off = mMacroSample[i]->getNumber() - mMacroMin; + auto off = macroSample->getNumber() - mMacroMin; auto const &variableData = rawData[0].data[off]; if (variableData.mcr_val != 0 || variableData.dec_val != -1) { - mMacroSample[i]->setValue(((double) variableData.mcr_val) / - pow(10.0, variableData.dec_val)); + macroSample->setValue( + ((double) variableData.mcr_val) / pow(10.0, variableData.dec_val)); } else { - mMacroSample[i]->unavailable(); + macroSample->unavailable(); } } - for (auto i = 0; i < mMacroPathCount; i++) + for (auto macroPathPos : mMacroPathPositions) { - auto x = mMacroPath[i]->getX() - mMacroMin; - auto y = mMacroPath[i]->getY() - mMacroMin; - auto z = mMacroPath[i]->getZ() - mMacroMin; + auto x = macroPathPos->getX() - mMacroMin; + auto y = macroPathPos->getY() - mMacroMin; + auto z = macroPathPos->getZ() - mMacroMin; if ((rawData[0].data[x].mcr_val != 0 || rawData[0].data[x].dec_val != -1) && (rawData[0].data[y].mcr_val != 0 || rawData[0].data[y].dec_val != -1) && (rawData[0].data[z].mcr_val != 0 || rawData[0].data[z].dec_val != -1)) { - mMacroPath[i]->setValue(((double) rawData[0].data[x].mcr_val) / - pow(10.0, rawData[0].data[x].dec_val), - ((double) rawData[0].data[y].mcr_val) / - pow(10.0, rawData[0].data[y].dec_val), - ((double) rawData[0].data[z].mcr_val) / - pow(10.0, rawData[0].data[z].dec_val)); + macroPathPos->setValue( + ((double) rawData[0].data[x].mcr_val) / pow(10.0, rawData[0].data[x].dec_val), + ((double) rawData[0].data[y].mcr_val) / pow(10.0, rawData[0].data[y].dec_val), + ((double) rawData[0].data[z].mcr_val) / pow(10.0, rawData[0].data[z].dec_val)); } else { - mMacroPath[i]->unavailable(); + macroPathPos->unavailable(); } } } diff --git a/fanuc/fanuc_adapter.hpp b/fanuc/fanuc_adapter.hpp index 7ddc51c..2f13a97 100644 --- a/fanuc/fanuc_adapter.hpp +++ b/fanuc/fanuc_adapter.hpp @@ -24,7 +24,7 @@ #include "fanuc_path.hpp" -constexpr int MAX_MACROS = 32; +constexpr int MAX_MACROS = 256; // Max number of entries in the ini file constexpr int MAX_PMC = 32; @@ -89,12 +89,10 @@ class FanucAdapter : public Adapter, public MTConnectService IntEvent mPartCount; // Macro variables - MacroSample *mMacroSample[MAX_MACROS]; - MacroPathPosition *mMacroPath[MAX_MACROS]; + std::vector mMacroSamples; + std::vector mMacroPathPositions; int mMacroMin; int mMacroMax; - int mMacroSampleCount; - int mMacroPathCount; // Macro variables IntEvent *mPMCVariable[MAX_PMC]; From bc0eb220822e00dc5ccf83d11d32f4714440f122 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:16:14 +0100 Subject: [PATCH 20/41] C++11 Conversion: Improved memory storage for PMC variables in the Fanuc adapter * Use of std::vector for memory management --- fanuc/fanuc_adapter.cpp | 32 +++++++++++++------------------- fanuc/fanuc_adapter.hpp | 23 +++++++++++++++++++---- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/fanuc/fanuc_adapter.cpp b/fanuc/fanuc_adapter.cpp index 0d5034b..5f0c064 100644 --- a/fanuc/fanuc_adapter.cpp +++ b/fanuc/fanuc_adapter.cpp @@ -40,9 +40,6 @@ FanucAdapter::FanucAdapter(int aPort) : mPartCount("part_count"), mMacroMin(99999), mMacroMax(0), - mPMCVariable{0}, - mPMCAddress{0}, - mPMCCount(0), mFlibhndl(0), mConnected(false), mDevicePort(DEF_FOCAS2_PORT), @@ -260,16 +257,13 @@ void FanucAdapter::configMacrosAndPMC(const char *iniFile) ini_getkey("pmc", pmcIdx, name, countof(name), iniFile) > 0 && pmcIdx < MAX_PMC; pmcIdx++) { - auto v = ini_getl("pmc", name, 0, iniFile); - mPMCVariable[pmcIdx] = new IntEvent(name); - mPMCAddress[pmcIdx] = v; + auto pmcAddress = ini_getl("pmc", name, 0, iniFile); + auto pmcVar = new PmcVariable(name, pmcAddress); + mPMCVariables.push_back(pmcVar); + addDatum(*pmcVar); - addDatum(*mPMCVariable[pmcIdx]); - - std::cout << "Adding pmc '" << name << "' at location " << v << std::endl; + std::cout << "Adding pmc '" << name << "' at location " << pmcAddress << std::endl; } - - mPMCCount = pmcIdx; } @@ -429,28 +423,28 @@ void FanucAdapter::getPMC() if (!mConnected) return; - for (int i = 0; i < mPMCCount; i++) + IODBPMC buf = {0}; + for(auto pcmVariable : mPMCVariables) { - IODBPMC buf; auto ret = pmc_rdpmcrng( mFlibhndl, 0, // G 0, // byte - mPMCAddress[i], - mPMCAddress[i], + pcmVariable->getAddress(), + pcmVariable->getAddress(), 8 + 1, &buf); if (ret == EW_OK) { if (buf.u.cdata[0] < 0) - mPMCVariable[i]->setValue(-buf.u.cdata[0] - 1); + pcmVariable->setValue(-buf.u.cdata[0] - 1); else - mPMCVariable[i]->setValue(buf.u.cdata[0]); + pcmVariable->setValue(buf.u.cdata[0]); } else { - std::cout << "Could not retrieve PMC data at " << mPMCAddress[i] - << " for " << mPMCVariable[i]->getName() + std::cout << "Could not retrieve PMC data at " << pcmVariable->getAddress() + << " for " << pcmVariable->getName() << ": " << ret << std::endl; } diff --git a/fanuc/fanuc_adapter.hpp b/fanuc/fanuc_adapter.hpp index 2f13a97..06b5e3c 100644 --- a/fanuc/fanuc_adapter.hpp +++ b/fanuc/fanuc_adapter.hpp @@ -70,6 +70,23 @@ class MacroPathPosition : public PathPosition }; +class PmcVariable : public IntEvent +{ +protected: + int mAddress; + +public: + PmcVariable(const char *name, int address) : + IntEvent(name), + mAddress(address) + { + } + + int getAddress() const { + return mAddress; } +}; + + // // Provides a connection to the data available from the FANUC Focus library. // @@ -94,10 +111,8 @@ class FanucAdapter : public Adapter, public MTConnectService int mMacroMin; int mMacroMax; - // Macro variables - IntEvent *mPMCVariable[MAX_PMC]; - int mPMCAddress[MAX_PMC]; - int mPMCCount; + // PMC variables + std::vector mPMCVariables; unsigned short mFlibhndl; bool mConnected, mConfigured; From 8c10837d89554089d765dac5ae98d29f117e02be Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:16:29 +0100 Subject: [PATCH 21/41] C++11 Conversion: Improved obtaining of macro variable data in the Fanuc adapter * Used inline helper function for converting from signed binary format into a decimal value * Created references within loops to avoid multiple address lookups. --- fanuc/fanuc_adapter.cpp | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/fanuc/fanuc_adapter.cpp b/fanuc/fanuc_adapter.cpp index 5f0c064..956555c 100644 --- a/fanuc/fanuc_adapter.cpp +++ b/fanuc/fanuc_adapter.cpp @@ -33,6 +33,13 @@ constexpr std::size_t countof(T const (&)[N]) noexcept } +// The Focas API returns decimal numbers with signed binary format. +inline double convert_bin_to_dec(long numeric, short exponent) +{ + return pow(10.0, -exponent) * numeric; +} + + FanucAdapter::FanucAdapter(int aPort) : Adapter(aPort), mMessage("message"), @@ -217,7 +224,7 @@ void FanucAdapter::configMacrosAndPMC(const char *iniFile) mMacroPathPositions.push_back(macroPathPos); addDatum(*macroPathPos); - std::cout << "Adding path macro '" << name << "' at location" + std::cout << "Adding path macro '" << name << "' at location " << x << " " << y << " " << z << std::endl; if (x > mMacroMax) @@ -367,7 +374,7 @@ void FanucAdapter::getMacros() // be true, we will have to get more creative. std::vector rawData; auto count = (mMacroMax - mMacroMin) + 1; - rawData.resize(count); + rawData.resize(count, {0}); short ret = cnc_rdmacror( mFlibhndl, @@ -380,12 +387,11 @@ void FanucAdapter::getMacros() { for (auto macroSample : mMacroSamples) { - auto off = macroSample->getNumber() - mMacroMin; - auto const &variableData = rawData[0].data[off]; + auto const &variableData = rawData[0].data[macroSample->getNumber() - mMacroMin]; if (variableData.mcr_val != 0 || variableData.dec_val != -1) { macroSample->setValue( - ((double) variableData.mcr_val) / pow(10.0, variableData.dec_val)); + convert_bin_to_dec(variableData.mcr_val, variableData.dec_val)); } else { @@ -394,18 +400,18 @@ void FanucAdapter::getMacros() } for (auto macroPathPos : mMacroPathPositions) { - auto x = macroPathPos->getX() - mMacroMin; - auto y = macroPathPos->getY() - mMacroMin; - auto z = macroPathPos->getZ() - mMacroMin; + auto const &xData = rawData[0].data[macroPathPos->getX() - mMacroMin]; + auto const &yData = rawData[0].data[macroPathPos->getY() - mMacroMin]; + auto const &zData = rawData[0].data[macroPathPos->getZ() - mMacroMin]; - if ((rawData[0].data[x].mcr_val != 0 || rawData[0].data[x].dec_val != -1) && - (rawData[0].data[y].mcr_val != 0 || rawData[0].data[y].dec_val != -1) && - (rawData[0].data[z].mcr_val != 0 || rawData[0].data[z].dec_val != -1)) + if ((xData.mcr_val != 0 || xData.dec_val != -1) && + (yData.mcr_val != 0 || yData.dec_val != -1) && + (zData.mcr_val != 0 || zData.dec_val != -1)) { macroPathPos->setValue( - ((double) rawData[0].data[x].mcr_val) / pow(10.0, rawData[0].data[x].dec_val), - ((double) rawData[0].data[y].mcr_val) / pow(10.0, rawData[0].data[y].dec_val), - ((double) rawData[0].data[z].mcr_val) / pow(10.0, rawData[0].data[z].dec_val)); + convert_bin_to_dec(xData.mcr_val, xData.dec_val), + convert_bin_to_dec(yData.mcr_val, yData.dec_val), + convert_bin_to_dec(zData.mcr_val, zData.dec_val) ); } else { From 0a24cc4af0abb4de1a5e0bcab416c9522e43b0a1 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:16:40 +0100 Subject: [PATCH 22/41] C++11 Conversion: const correctness and buffer initialization fixes in Fanuc adapter --- fanuc/fanuc_adapter.cpp | 8 ++++---- fanuc/fanuc_adapter.hpp | 8 ++++---- fanuc/fanuc_axis.cpp | 8 ++++---- fanuc/fanuc_axis.hpp | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/fanuc/fanuc_adapter.cpp b/fanuc/fanuc_adapter.cpp index 956555c..887de46 100644 --- a/fanuc/fanuc_adapter.cpp +++ b/fanuc/fanuc_adapter.cpp @@ -385,7 +385,7 @@ void FanucAdapter::getMacros() if (ret == EW_OK) { - for (auto macroSample : mMacroSamples) + for (const auto macroSample : mMacroSamples) { auto const &variableData = rawData[0].data[macroSample->getNumber() - mMacroMin]; if (variableData.mcr_val != 0 || variableData.dec_val != -1) @@ -398,7 +398,7 @@ void FanucAdapter::getMacros() macroSample->unavailable(); } } - for (auto macroPathPos : mMacroPathPositions) + for (const auto macroPathPos : mMacroPathPositions) { auto const &xData = rawData[0].data[macroPathPos->getX() - mMacroMin]; auto const &yData = rawData[0].data[macroPathPos->getY() - mMacroMin]; @@ -430,7 +430,7 @@ void FanucAdapter::getPMC() return; IODBPMC buf = {0}; - for(auto pcmVariable : mPMCVariables) + for(const auto pcmVariable : mPMCVariables) { auto ret = pmc_rdpmcrng( mFlibhndl, @@ -463,7 +463,7 @@ void FanucAdapter::getMessages() if (!mConnected) return; - OPMSG messages[6]; + OPMSG messages[6] = {0}; auto ret = cnc_rdopmsg(mFlibhndl, 0, 6 + 256, messages); if (ret == EW_OK && messages->datano != -1) { diff --git a/fanuc/fanuc_adapter.hpp b/fanuc/fanuc_adapter.hpp index 06b5e3c..96e189a 100644 --- a/fanuc/fanuc_adapter.hpp +++ b/fanuc/fanuc_adapter.hpp @@ -40,7 +40,7 @@ class MacroSample : public Sample { } - int getNumber() { + int getNumber() const { return mNumber; } }; @@ -61,11 +61,11 @@ class MacroPathPosition : public PathPosition { } - int getX() { + int getX() const { return m_X; } - int getY() { + int getY() const { return m_Y; } - int getZ() { + int getZ() const { return m_Z; } }; diff --git a/fanuc/fanuc_axis.cpp b/fanuc/fanuc_axis.cpp index 62aff6f..8e9bfb9 100644 --- a/fanuc/fanuc_axis.cpp +++ b/fanuc/fanuc_axis.cpp @@ -21,7 +21,7 @@ using namespace std; -FanucAxis::FanucAxis(Adapter *adapter, string prefix, int index) : +FanucAxis::FanucAxis(Adapter *adapter, string const &prefix, int index) : mIndex(index), mDivisor(1.0) { @@ -38,7 +38,7 @@ FanucAxis::FanucAxis(Adapter *adapter, string prefix, int index) : } -bool FanucAxis::gatherData(ODBDY2 *dynamic, ODBSVLOAD *loads) +bool FanucAxis::gatherData(const ODBDY2 *dynamic, const ODBSVLOAD *loads) { mActual.setValue(dynamic->pos.faxis.machine[mIndex] / mDivisor); mLoad.setValue(loads[mIndex].svload.data / @@ -47,7 +47,7 @@ bool FanucAxis::gatherData(ODBDY2 *dynamic, ODBSVLOAD *loads) } -FanucSpindle::FanucSpindle(Adapter *adapter, string prefix, int index) : +FanucSpindle::FanucSpindle(Adapter *adapter, string const &prefix, int index) : mIndex(index) { mSpeed.setName((prefix + "speed").c_str()); @@ -59,7 +59,7 @@ FanucSpindle::FanucSpindle(Adapter *adapter, string prefix, int index) : } -bool FanucSpindle::gatherData(ODBSPLOAD *loads, ODBACT2 *aSpeeds) +bool FanucSpindle::gatherData(const ODBSPLOAD *loads, const ODBACT2 *aSpeeds) { mLoad.setValue(loads[mIndex].spload.data / pow((long double) 10.0, (long double) loads[mIndex].spload.dec)); diff --git a/fanuc/fanuc_axis.hpp b/fanuc/fanuc_axis.hpp index 2b5df73..02cf61f 100644 --- a/fanuc/fanuc_axis.hpp +++ b/fanuc/fanuc_axis.hpp @@ -25,10 +25,10 @@ class FanucAxis { public: - FanucAxis(Adapter *adapter, std::string prefix, int index); + FanucAxis(Adapter *adapter, std::string const &prefix, int index); ~FanucAxis() {} - bool gatherData(ODBDY2 *dynamic, ODBSVLOAD *loads); + bool gatherData(const ODBDY2 *dynamic, const ODBSVLOAD *loads); public: int mIndex; @@ -44,10 +44,10 @@ class FanucAxis class FanucSpindle { public: - FanucSpindle(Adapter *adapter, std::string prefix, int index); + FanucSpindle(Adapter *adapter, std::string const &prefix, int index); ~FanucSpindle() {} - bool gatherData(ODBSPLOAD *loads, ODBACT2 *speeds); + bool gatherData(const ODBSPLOAD *loads, const ODBACT2 *speeds); public: int mIndex; From 16c51412e9d7f8c1406621eac784524d2f54cf13 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:16:52 +0100 Subject: [PATCH 23/41] C++11 Conversion: Small refactor to Fanuc adapter to move common code for conversion of double data * Moved conversion function for signed binary to decimal into a helper header file * Modified Axis methods to use helper file * Changed a loop to perform less dereferencing --- fanuc/CMakeLists.txt | 11 +++++++++-- fanuc/fanuc_adapter.cpp | 9 +-------- fanuc/fanuc_axis.cpp | 7 +++---- fanuc/fanuc_helpers.hpp | 24 ++++++++++++++++++++++++ fanuc/fanuc_path.cpp | 4 ++-- 5 files changed, 39 insertions(+), 16 deletions(-) create mode 100644 fanuc/fanuc_helpers.hpp diff --git a/fanuc/CMakeLists.txt b/fanuc/CMakeLists.txt index 95bb56f..777ad71 100644 --- a/fanuc/CMakeLists.txt +++ b/fanuc/CMakeLists.txt @@ -1,6 +1,7 @@ set(FANUC_HEADERS fanuc_adapter.hpp fanuc_axis.hpp + fanuc_helpers.hpp fanuc_path.hpp ) @@ -19,7 +20,7 @@ set(MIN_INI_SOURCES ${CMAKE_SOURCE_DIR}/minIni_07/minIni.c ) -set(ADDITIONAL_HEADERS +set(ADDITIONAL_SOURCES ${CMAKE_SOURCE_DIR}/src/adapter.cpp ${CMAKE_SOURCE_DIR}/src/client.cpp ${CMAKE_SOURCE_DIR}/src/condition.cpp @@ -31,7 +32,7 @@ set(ADDITIONAL_HEADERS ${CMAKE_SOURCE_DIR}/src/string_buffer.cpp ) -set(ADDITIONAL_SOURCES +set(ADDITIONAL_HEADERS ${CMAKE_SOURCE_DIR}/src/adapter.hpp ${CMAKE_SOURCE_DIR}/src/client.hpp ${CMAKE_SOURCE_DIR}/src/condition.hpp @@ -68,6 +69,12 @@ add_executable(fanuc ${ADDITIONAL_SOURCES} ) +# Add our auxilliary configurations files to the target for Visual Studio, otherwise +# they do not show up in the UI +if(MSVC) + target_sources(fanuc PRIVATE ${CONFIGURATION_FILES}) +endif() + target_include_directories(fanuc PRIVATE ${CMAKE_SOURCE_DIR}/minIni_07 PRIVATE ${CMAKE_SOURCE_DIR}/src diff --git a/fanuc/fanuc_adapter.cpp b/fanuc/fanuc_adapter.cpp index 887de46..cf75f76 100644 --- a/fanuc/fanuc_adapter.cpp +++ b/fanuc/fanuc_adapter.cpp @@ -21,6 +21,7 @@ #include #include #include +#include "fanuc_helpers.hpp" constexpr int DEF_SERVICE_PORT = 7878; constexpr int DEF_FOCAS2_PORT = 8193; @@ -32,14 +33,6 @@ constexpr std::size_t countof(T const (&)[N]) noexcept return N; } - -// The Focas API returns decimal numbers with signed binary format. -inline double convert_bin_to_dec(long numeric, short exponent) -{ - return pow(10.0, -exponent) * numeric; -} - - FanucAdapter::FanucAdapter(int aPort) : Adapter(aPort), mMessage("message"), diff --git a/fanuc/fanuc_axis.cpp b/fanuc/fanuc_axis.cpp index 8e9bfb9..e6e3c54 100644 --- a/fanuc/fanuc_axis.cpp +++ b/fanuc/fanuc_axis.cpp @@ -17,6 +17,7 @@ #include "fanuc_axis.hpp" #include #include "fanuc_path.hpp" +#include "fanuc_helpers.hpp" using namespace std; @@ -41,8 +42,7 @@ FanucAxis::FanucAxis(Adapter *adapter, string const &prefix, int index) : bool FanucAxis::gatherData(const ODBDY2 *dynamic, const ODBSVLOAD *loads) { mActual.setValue(dynamic->pos.faxis.machine[mIndex] / mDivisor); - mLoad.setValue(loads[mIndex].svload.data / - pow((long double) 10.0, (long double) loads[mIndex].svload.dec)); + mLoad.setValue( convert_bin_to_dec(loads[mIndex].svload.data, loads[mIndex].svload.dec) ); return true; } @@ -61,8 +61,7 @@ FanucSpindle::FanucSpindle(Adapter *adapter, string const &prefix, int index) : bool FanucSpindle::gatherData(const ODBSPLOAD *loads, const ODBACT2 *aSpeeds) { - mLoad.setValue(loads[mIndex].spload.data / - pow((long double) 10.0, (long double) loads[mIndex].spload.dec)); + mLoad.setValue( convert_bin_to_dec(loads[mIndex].spload.data, loads[mIndex].spload.dec) ); mSpeed.setValue(aSpeeds->data[mIndex]); return true; } diff --git a/fanuc/fanuc_helpers.hpp b/fanuc/fanuc_helpers.hpp new file mode 100644 index 0000000..7fe87a1 --- /dev/null +++ b/fanuc/fanuc_helpers.hpp @@ -0,0 +1,24 @@ +// +// Copyright Copyright 2012, System Insights, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#pragma once + +#include + +// The Focas API returns decimal numbers with signed binary format. +inline double convert_bin_to_dec(long numeric, short exponent) +{ + return pow(10.0, -exponent) * numeric; +} \ No newline at end of file diff --git a/fanuc/fanuc_path.cpp b/fanuc/fanuc_path.cpp index 5fea1f3..685e27b 100644 --- a/fanuc/fanuc_path.cpp +++ b/fanuc/fanuc_path.cpp @@ -261,8 +261,8 @@ bool FanucPath::configureAxes(unsigned short flibhndl) return false; } - for (auto i = 0u; i < mAxes.size(); i++) - mAxes[i]->mDivisor = pow((long double) 10.0, (long double) inprec[i]); + for(const auto axis : mAxes) + axis->mDivisor = pow((long double) 10.0, (long double) inprec[axis->mIndex]); return true; } From d4ea242ba051ed54ee81b81cdc0327d17773567d Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:17:15 +0100 Subject: [PATCH 24/41] C++11 Conversion: Minor tweaks to the Fanuc adapter * Changed default configuration ini file to add sample values for Macro variables * Converted to std::unique_ptr for main adapter object to clean-up better if the process is ended --- fanuc/FanucAdapter.cpp | 42 ++++++++++++++++++++++-------------------- fanuc/adapter.ini | 6 +++++- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/fanuc/FanucAdapter.cpp b/fanuc/FanucAdapter.cpp index b4f3b03..2f701f8 100755 --- a/fanuc/FanucAdapter.cpp +++ b/fanuc/FanucAdapter.cpp @@ -1,26 +1,28 @@ -/* - * Copyright Copyright 2012, System Insights, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - +// +// Copyright Copyright 2012, System Insights, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + #include "internal.hpp" +#include #include "fanuc_adapter.hpp" #include "server.hpp" #include "string_buffer.hpp" -int main(int aArgc, const char *aArgv[]) -{ - FanucAdapter *adapter = new FanucAdapter(7878); - return adapter->main(aArgc, aArgv); + +int main(int argc, const char *argv[]) +{ + auto adapter = std::make_unique(7878); + return adapter->main(argc, argv); } diff --git a/fanuc/adapter.ini b/fanuc/adapter.ini index 942c92b..94d74b8 100644 --- a/fanuc/adapter.ini +++ b/fanuc/adapter.ini @@ -3,9 +3,13 @@ port = 7878 service = MTC Focus 1 [focus] -host = 10.211.55.5 +host = HSSB_9 [macros] +Macro500=500 +Macro501=501 +Macro502=502 +MacroPos=[500 501 502] [pmc] SspeedOvr = 30 From cd040b141f7f1daeb2532ae9e7118d76dae5c364 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:19:41 +0100 Subject: [PATCH 25/41] C++11 Conversion: Conversion of 'fake' adapter project * Use of 'final' keyword to signify that a method should be an overload of a base class and that no classes can override its implementation * Made the line endings consistent --- fake/fake.cpp | 32 +++++------ fake/fake_adapter.cpp | 128 +++++++++++++++++++++--------------------- fake/fake_adapter.hpp | 54 +++++++++--------- 3 files changed, 107 insertions(+), 107 deletions(-) diff --git a/fake/fake.cpp b/fake/fake.cpp index 9222acb..30d88b3 100644 --- a/fake/fake.cpp +++ b/fake/fake.cpp @@ -29,19 +29,19 @@ // WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -// - -#include "internal.hpp" -#include "fake_adapter.hpp" -#include "server.hpp" -#include "string_buffer.hpp" - - -int main(int aArgc, const char *aArgv[]) -{ - // Construct the adapter and start the server - FakeAdapter *adapter = new FakeAdapter(7878); - adapter->setName("Fake MTConnect Adapter"); - return adapter->main(aArgc, aArgv); -} - +// + +#include "internal.hpp" +#include "fake_adapter.hpp" +#include "server.hpp" +#include "string_buffer.hpp" + + +int main(int aArgc, const char *aArgv[]) +{ + // Construct the adapter and start the server + FakeAdapter *adapter = new FakeAdapter(7878); + adapter->setName("Fake MTConnect Adapter"); + return adapter->main(aArgc, aArgv); +} + diff --git a/fake/fake_adapter.cpp b/fake/fake_adapter.cpp index 6b3c1a7..d599c37 100644 --- a/fake/fake_adapter.cpp +++ b/fake/fake_adapter.cpp @@ -64,67 +64,67 @@ void FakeAdapter::initialize(int argc, const char *argv[]) void FakeAdapter::start() { - startServer(); -} - - -void FakeAdapter::stop() -{ - stopServer(); -} - - -static int count = 0; -void FakeAdapter::gatherDeviceData() -{ - mAvailability.available(); - - printf("Count: %d\n", count); - mPos.setValue(count); - - switch (count % 6) - { - case 0: - mExecution.setValue(Execution::eREADY); - printf("Add 0\n"); - mSystem.add(Condition::eFAULT, "Fault 1", "0"); - break; - - case 1: - mExecution.setValue(Execution::eACTIVE); - printf("Add 0, 1\n"); - mSystem.add(Condition::eFAULT, "Fault 1", "0"); - mSystem.add(Condition::eFAULT, "Fault 2", "1"); - break; - - case 2: - printf("Add 0, 1, 2\n"); - mSystem.add(Condition::eFAULT, "Fault 1", "0"); - mSystem.add(Condition::eFAULT, "Fault 2", "1"); - mSystem.add(Condition::eFAULT, "Fault 3", "2"); - break; - - case 3: - printf("Add 1, 3\n"); - mSystem.add(Condition::eFAULT, "Fault 2", "1"); - mSystem.add(Condition::eFAULT, "Fault 4", "3"); - break; - - case 4: - mExecution.setValue(Execution::eSTOPPED); - printf("Stay the same\n"); - mSystem.add(Condition::eFAULT, "Fault 2", "1"); - mSystem.add(Condition::eFAULT, "Fault 4", "3"); - break; - - - case 5: - // Clear all - printf("Clear\n"); - mAvailability.unavailable(); - break; - } - - count++; -} - + startServer(); +} + + +void FakeAdapter::stop() +{ + stopServer(); +} + + +static int count = 0; +void FakeAdapter::gatherDeviceData() +{ + mAvailability.available(); + + printf("Count: %d\n", count); + mPos.setValue(count); + + switch (count % 6) + { + case 0: + mExecution.setValue(Execution::eREADY); + printf("Add 0\n"); + mSystem.add(Condition::eFAULT, "Fault 1", "0"); + break; + + case 1: + mExecution.setValue(Execution::eACTIVE); + printf("Add 0, 1\n"); + mSystem.add(Condition::eFAULT, "Fault 1", "0"); + mSystem.add(Condition::eFAULT, "Fault 2", "1"); + break; + + case 2: + printf("Add 0, 1, 2\n"); + mSystem.add(Condition::eFAULT, "Fault 1", "0"); + mSystem.add(Condition::eFAULT, "Fault 2", "1"); + mSystem.add(Condition::eFAULT, "Fault 3", "2"); + break; + + case 3: + printf("Add 1, 3\n"); + mSystem.add(Condition::eFAULT, "Fault 2", "1"); + mSystem.add(Condition::eFAULT, "Fault 4", "3"); + break; + + case 4: + mExecution.setValue(Execution::eSTOPPED); + printf("Stay the same\n"); + mSystem.add(Condition::eFAULT, "Fault 2", "1"); + mSystem.add(Condition::eFAULT, "Fault 4", "3"); + break; + + + case 5: + // Clear all + printf("Clear\n"); + mAvailability.unavailable(); + break; + } + + count++; +} + diff --git a/fake/fake_adapter.hpp b/fake/fake_adapter.hpp index 9833c6f..1193773 100644 --- a/fake/fake_adapter.hpp +++ b/fake/fake_adapter.hpp @@ -29,30 +29,30 @@ // WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF // THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. -// -#pragma once - -#include "adapter.hpp" -#include "device_datum.hpp" -#include "service.hpp" -#include "condition.hpp" - -class FakeAdapter : public Adapter, public MTConnectService -{ -protected: - // Events - Availability mAvailability; - Condition mSystem; - Sample mPos; - Execution mExecution; - -public: - FakeAdapter(int port); - ~FakeAdapter(); - - virtual void initialize(int aArgc, const char *aArgv[]); - virtual void start(); - virtual void stop(); - virtual void gatherDeviceData(); -}; - +// +#pragma once + +#include "adapter.hpp" +#include "device_datum.hpp" +#include "service.hpp" +#include "condition.hpp" + +class FakeAdapter : public Adapter, public MTConnectService +{ +protected: + // Events + Availability mAvailability; + Condition mSystem; + Sample mPos; + Execution mExecution; + +public: + FakeAdapter(int port); + ~FakeAdapter(); + + void initialize(int argc, const char *argv[]) final; + void start() final; + void stop() final; + void gatherDeviceData() final; +}; + From 22fc37fd927c2cbe44a436fd52b4fee9eb95ad59 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:20:16 +0100 Subject: [PATCH 26/41] C++11 Conversion: Removed raw pointer from Adapter class and replaced with std::unique_ptr --- src/adapter.cpp | 19 +++++++------------ src/adapter.hpp | 15 ++++++++------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/adapter.cpp b/src/adapter.cpp index 6c23d1d..b6a2cdb 100755 --- a/src/adapter.cpp +++ b/src/adapter.cpp @@ -60,11 +60,7 @@ Adapter::Adapter(int port, int scanDelayMs) : Adapter::~Adapter() { mRunning = false; - if (mServer) - { - delete mServer; - mServer = nullptr; - } + mServer.reset(); for(auto value : mDeviceData) delete value; @@ -104,14 +100,14 @@ bool Adapter::startServerThread() if (!gLogger) gLogger = new Logger(); - mServer = new Server(mPort, mHeartbeatFrequency); + mServer = std::make_unique(mPort, mHeartbeatFrequency); mRunning = true; mServerThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) &ServerThread, this, 0, 0); if (!mServerThread) { fprintf(stderr, "Cannot create server thread"); - delete mServer; mServer = nullptr; + mServer.reset(); return false; } else @@ -155,14 +151,14 @@ bool Adapter::startServerThread() if (!gLogger) gLogger = new Logger(); - mServer = new Server(mPort, mHeartbeatFrequency); + mServer = std::make_unique(mPort, mHeartbeatFrequency); mRunning = true; auto res = pthread_create(&mServerThread, nullptr, ::ServerThread, this); if (res != 0) { fprintf(stderr, "Cannot create server thread"); - delete mServer; mServer = nullptr; + mServer.reset(); return false; } @@ -243,7 +239,7 @@ void Adapter::startServer() if (!gLogger) gLogger = new Logger(); - mServer = new Server(mPort, mHeartbeatFrequency); + mServer = std::make_unique(mPort, mHeartbeatFrequency); mRunning = true; // Process untill stopped @@ -274,8 +270,7 @@ void Adapter::startServer() sleepMs(mScanDelay); } - delete mServer; - mServer = nullptr; + mServer.reset(); } diff --git a/src/adapter.hpp b/src/adapter.hpp index d219613..8643331 100644 --- a/src/adapter.hpp +++ b/src/adapter.hpp @@ -34,6 +34,7 @@ #include #include +#include #include "server.hpp" #include "string_buffer.hpp" #include "threading.hpp" @@ -53,15 +54,15 @@ constexpr size_t INITIAL_MAX_DEVICE_DATA = 128u; class Adapter { protected: - Server *mServer; // The socket server - StringBuffer mBuffer; // A string buffer to hold the string we write to the streams + std::unique_ptr mServer; // The socket server + StringBuffer mBuffer; // A string buffer to hold the string we write to the streams std::vector mDeviceData; - std::chrono::milliseconds mScanDelay; // How long to sleep (in ms) between scans - int mPort; // The server port we bind to - bool mDisableFlush; // Used for initial data collection - int mHeartbeatFrequency; // The frequency (ms) to heartbeat server. Responds to Ping. Default 10 sec + std::chrono::milliseconds mScanDelay; // How long to sleep (in ms) between scans + int mPort; // The server port we bind to + bool mDisableFlush; // Used for initial data collection + int mHeartbeatFrequency; // The frequency (ms) to heartbeat server. Responds to Ping. Default 10 sec bool mRunning; - Client *mInitializeClient; // If we are sending initial data to a client + Client *mInitializeClient; // If we are sending initial data to a client #ifdef THREADED #ifdef WIN32 From 04fe8c83a378dac0e3fb5168ae4d5bae62634e6c Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:20:28 +0100 Subject: [PATCH 27/41] C++11 Conversion: Replaced MTCMutex with std::mutex --- fanuc/fanuc.xml | 27 --------------------------- src/adapter.cpp | 6 +++--- src/adapter.hpp | 6 ++++-- src/client.cpp | 2 +- src/client.hpp | 4 ++-- src/server.cpp | 8 ++++---- src/server.hpp | 4 ++-- src/threading.hpp | 33 +++++---------------------------- 8 files changed, 21 insertions(+), 69 deletions(-) diff --git a/fanuc/fanuc.xml b/fanuc/fanuc.xml index e5143fb..e032138 100644 --- a/fanuc/fanuc.xml +++ b/fanuc/fanuc.xml @@ -36,33 +36,6 @@ - - - - - - - - - - INDEX - - - - - - - - - - - SPINDLE - - - - - - diff --git a/src/adapter.cpp b/src/adapter.cpp index b6a2cdb..f41ea1d 100755 --- a/src/adapter.cpp +++ b/src/adapter.cpp @@ -112,7 +112,7 @@ bool Adapter::startServerThread() } else { - sleepMs(10ms); + sleepMs(std::chrono::milliseconds(10)); } return true; @@ -254,7 +254,7 @@ void Adapter::startServer() // Don't bother getting data if we don't have anyone to read it if (mServer->numClients() > 0) { - MTCAutoLock lock(mGatherLock); + std::lock_guard lock(mGatherLock); begin(); mBuffer.timestamp(); @@ -355,7 +355,7 @@ void Adapter::sendBuffer() // Send the initial values to a client void Adapter::sendInitialData(Client *client) { - MTCAutoLock lock(mGatherLock); + std::lock_guard lock(mGatherLock); mInitializeClient = client; mDisableFlush = true; diff --git a/src/adapter.hpp b/src/adapter.hpp index 8643331..3d666a3 100644 --- a/src/adapter.hpp +++ b/src/adapter.hpp @@ -35,9 +35,11 @@ #include #include #include +#include +#include #include "server.hpp" #include "string_buffer.hpp" -#include "threading.hpp" + class DeviceDatum; class CuttingTool; @@ -71,7 +73,7 @@ class Adapter pthread_t mServerThread; #endif #endif - MTCMutex mGatherLock; + std::mutex mGatherLock; protected: void sleepMs(std::chrono::milliseconds ms); diff --git a/src/client.cpp b/src/client.cpp index 1438c51..8dacabd 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -53,7 +53,7 @@ Client::~Client() int Client::write(const char *string) { int res; - MTCAutoLock lock(mWriteLock); + std::lock_guard lock(mWriteLock); try { diff --git a/src/client.hpp b/src/client.hpp index e9a9b77..e6f8880 100755 --- a/src/client.hpp +++ b/src/client.hpp @@ -32,7 +32,7 @@ // #pragma once -#include "threading.hpp" +#include // @@ -44,7 +44,7 @@ class Client // Instance Variables protected: SOCKET mSocket; - MTCMutex mWriteLock; + std::mutex mWriteLock; // class methods public: diff --git a/src/server.cpp b/src/server.cpp index 568fca6..1bf4f65 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -112,7 +112,7 @@ Server::~Server() void Server::readFromClients() { - MTCAutoLock lock(mListLock); + std::lock_guard lock(mListLock); fd_set rset; FD_ZERO(&rset); @@ -202,7 +202,7 @@ void Server::sendToClient(Client *client, const char *string) void Server::sendToClients(const char *string) { - MTCAutoLock lock(mListLock); + std::lock_guard lock(mListLock); for (int i = mNumClients - 1; i >= 0; i--) { @@ -290,14 +290,14 @@ void Server::removeClientInternal(Client *client) // void Server::removeClient(Client *client) { - MTCAutoLock lock(mListLock); + std::lock_guard lock(mListLock); removeClientInternal(client); } Client *Server::addClient(Client *client) { - MTCAutoLock lock(mListLock); + std::lock_guard lock(mListLock); if (mNumClients < MAX_CLIENTS) { diff --git a/src/server.hpp b/src/server.hpp index 4be5794..3061e86 100755 --- a/src/server.hpp +++ b/src/server.hpp @@ -32,7 +32,7 @@ // #pragma once -#include "threading.hpp" +#include class Client; @@ -49,7 +49,7 @@ class Server char mPong[32]; int mTimeout; - MTCMutex mListLock; + std::mutex mListLock; protected: // Assumes the mutex is already locked. diff --git a/src/threading.hpp b/src/threading.hpp index ec522be..1dc8cbb 100644 --- a/src/threading.hpp +++ b/src/threading.hpp @@ -34,55 +34,32 @@ #ifdef THREADED -#ifndef WIN32 - #include -#endif +#include + class MTCMutex { public: MTCMutex() { -#ifdef WIN32 - InitializeCriticalSection(&mLock); -#else - pthread_mutex_init(&mLock, NULL); -#endif } ~MTCMutex() { -#ifdef WIN32 - DeleteCriticalSection(&mLock); -#else - pthread_mutex_destroy(&mLock); -#endif } void lock() { -#ifdef WIN32 - EnterCriticalSection(&mLock); -#else - pthread_mutex_lock(&mLock); -#endif + m_Mutex.lock(); } void unlock() { -#ifdef WIN32 - LeaveCriticalSection(&mLock); -#else - pthread_mutex_unlock(&mLock); -#endif + m_Mutex.unlock(); } protected: -#ifdef WIN32 - CRITICAL_SECTION mLock; -#else - pthread_mutex_t mLock; -#endif + std::mutex m_Mutex; private: MTCMutex(const MTCMutex& aMutex) From a784923a8ccc2a841604d4bf35ad9bf7d0f7243e Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:20:40 +0100 Subject: [PATCH 28/41] C++11 Conversion: Updated to remove deprecated function 'inet_ntoa' * Replaced with inet_ntop (InetNtop on Windows) and hard-coded for IPv4 address lookup --- fake/CMakeLists.txt | 1 + fanuc/CMakeLists.txt | 1 + src/internal.hpp | 11 +++++++---- src/server.cpp | 4 +++- test/CMakeLists.txt | 1 + 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/fake/CMakeLists.txt b/fake/CMakeLists.txt index 479c069..113b8d0 100644 --- a/fake/CMakeLists.txt +++ b/fake/CMakeLists.txt @@ -43,6 +43,7 @@ target_include_directories(fake_adapter if(WIN32) target_link_libraries(fake_adapter PRIVATE wsock32.lib + PRIVATE Ws2_32.lib ) endif() diff --git a/fanuc/CMakeLists.txt b/fanuc/CMakeLists.txt index 777ad71..3ff1a64 100644 --- a/fanuc/CMakeLists.txt +++ b/fanuc/CMakeLists.txt @@ -87,6 +87,7 @@ target_compile_definitions(fanuc if(WIN32) target_link_libraries(fanuc PRIVATE wsock32.lib + PRIVATE Ws2_32.lib ) endif() diff --git a/src/internal.hpp b/src/internal.hpp index 91a1304..64c4a38 100755 --- a/src/internal.hpp +++ b/src/internal.hpp @@ -35,12 +35,15 @@ #ifdef WIN32 #define _CRT_SECURE_NO_DEPRECATE 1 - /* Windows specific include files and types */ - #include "winsock2.h" + // Windows specific include files and types + #include + #include #ifndef AFX - #include "windows.h" + #include #endif - #include "errno.h" + #include + + #define inet_ntop InetNtop #define SHUT_RDWR SD_BOTH typedef int socklen_t; diff --git a/src/server.cpp b/src/server.cpp index 1bf4f65..b7175f5 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -243,7 +243,9 @@ Client *Server::connectToClients() return 0; } - gLogger->info("Connected to: %s on port %d", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + char targetNameBuffer[INET_ADDRSTRLEN] = {0}; + auto targetName = inet_ntop(AF_INET, &addr.sin_addr, targetNameBuffer, sizeof(targetNameBuffer)); + gLogger->info("Connected to: %s on port %d", targetName, ntohs(addr.sin_port)); int flag = 1; ::setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (const char *) &flag, sizeof(int)); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 19da26b..6c93570 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -48,6 +48,7 @@ target_link_libraries(test if(WIN32) target_link_libraries(test PRIVATE wsock32.lib + PRIVATE Ws2_32.lib ) endif() From fd20e0202c8ab2ef6ab11bffc7160c64e986e22d Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:20:50 +0100 Subject: [PATCH 29/41] C++11 Conversion: Removed build warnings related to unsecure printf family functions --- src/service.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/service.cpp b/src/service.cpp index 3cb05da..a6eacd0 100644 --- a/src/service.cpp +++ b/src/service.cpp @@ -43,8 +43,7 @@ MTConnectService::MTConnectService() : void MTConnectService::setName(const char *name) { - strncpy(mName, name, 78); - mName[79] = '\0'; + strncpy_s(mName, sizeof(mName), name, sizeof(mName) - 1); } void MTConnectService::initialize(int aArgc, const char *aArgv[]) @@ -277,7 +276,7 @@ void MTConnectService::install(int argc, const char *argv[]) int d = 0; for (int i = 0; i < argc; i++) { - strcpy(arguments + d, argv[i]); + strcpy_s(arguments + d, 2048 - d, argv[i]); d += strlen(arguments + d) + 1; } @@ -546,7 +545,7 @@ VOID SvcReportEvent(LPTSTR functionName) if (hEventSource) { - sprintf(Buffer, "%-60s failed with %d", functionName, GetLastError()); + snprintf(Buffer, _countof(Buffer), "%-60s failed with %d", functionName, GetLastError()); lpszStrings[0] = gService->name(); lpszStrings[1] = Buffer; From a0262dc95335fe53bdb6e94ef669282e2de0361a Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:21:01 +0100 Subject: [PATCH 30/41] C++11 Conversion: Updated to the latest version of minIni --- minIni_07/LICENSE | 13 + minIni_07/README.md | 170 ++++++++++ minIni_07/minGlue-FatFs.h | 45 +-- minIni_07/minGlue-ccs.h | 64 ++++ minIni_07/minGlue-efsl.h | 40 ++- minIni_07/minGlue-ffs.h | 26 ++ minIni_07/minGlue-mdd.h | 58 ++++ minIni_07/minGlue-stdio.h | 45 +-- minIni_07/minGlue.h | 47 ++- minIni_07/minIni.c | 656 ++++++++++++++++++++++++++++---------- minIni_07/minIni.h | 141 ++++++-- minIni_07/test.c | 70 +++- minIni_07/test.ini | 4 +- minIni_07/test2.cc | 80 +++++ minIni_07/testplain.ini | 3 + minIni_07/wxMinIni.h | 152 +++++---- 16 files changed, 1243 insertions(+), 371 deletions(-) create mode 100644 minIni_07/README.md create mode 100644 minIni_07/minGlue-ccs.h create mode 100644 minIni_07/minGlue-ffs.h create mode 100644 minIni_07/minGlue-mdd.h create mode 100644 minIni_07/test2.cc create mode 100644 minIni_07/testplain.ini diff --git a/minIni_07/LICENSE b/minIni_07/LICENSE index 68c771a..cbf8eb4 100644 --- a/minIni_07/LICENSE +++ b/minIni_07/LICENSE @@ -3,6 +3,19 @@ Version 2.0, January 2004 http://www.apache.org/licenses/ + + EXCEPTION TO THE APACHE 2.0 LICENSE + + As a special exception to the Apache License 2.0 (and referring to the + definitions in Section 1 of this license), you may link, statically or + dynamically, the "Work" to other modules to produce an executable file + containing portions of the "Work", and distribute that executable file + in "Object" form under the terms of your choice, without any of the + additional requirements listed in Section 4 of the Apache License 2.0. + This exception applies only to redistributions in "Object" form (not + "Source" form) and only if no modifications have been made to the "Work". + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. diff --git a/minIni_07/README.md b/minIni_07/README.md new file mode 100644 index 0000000..9f30a01 --- /dev/null +++ b/minIni_07/README.md @@ -0,0 +1,170 @@ +# minIni +minIni is a portable and configurable library for reading and writing ".INI" files. At 830 lines of commented source +code +(version 1.2), minIni truly is a "mini" INI file parser, especially considering its features. + +The library does not require the file I/O functions from the standard C/C++ library, but instead lets you configure +the file I/O interface to use via macros. minIni uses limited stack space and does not use dynamic memory (malloc and +friends) at all. + +Some minor variations on standard INI files are supported too, notably minIni supports INI files that lack sections. + + +# Acknowledgement + +minIni is derived from an earlier INI file parser (which I wrote) for desktop systems. + +In turn, that earlier parser was a re-write of the code from the article "Multiplatform .INI Files" by Joseph J. Graf +in the March 1994 issue of Dr. Dobb's Journal. In other words, minIni has its roots in the work of Joseph Graf (even +though the code has been almost completely re-written). + + +# Features + +minIni is a programmer's library to read and write "INI" files in embedded systems. minIni takes little resources, +can be configured for various kinds of file I/O libraries and provides functionality for reading, writing and +deleting keys from an INI file. + +Although the main feature of minIni is that it is small and minimal, it has a few other features: + + * minIni supports reading keys that are outside a section, and it thereby supports configuration files that do not use sections (but that are otherwise compatible with INI files). + * You may use a colon to separate key and value; the colon is equivalent to the equal sign. That is, the strings "Name: Value" and "Name=Value" have the same meaning. + * The hash character ("#") is an alternative for the semicolon to start a comment. Trailing comments (i.e. behind a key/value pair on a line) are allowed. + * Leading and trailing white space around key names and values is ignored. + * When writing a value that contains a comment character (";" or "#"), that value will automatically be put between double quotes; when reading the value, these quotes are removed. When a double-quote itself appears in the setting, these characters are escaped. + * Section and key enumeration are supported. + * You can optionally set the line termination (for text files) that minIni will use. (This is a compile-time setting, not a run-time setting.) + * Since writing speed is much lower than reading speed in Flash memory (SD/MMC cards, USB memory sticks), minIni minimizes "file writes" at the expense of double "file reads". + * The memory footprint is deterministic. There is no dynamic memory allocation. + +## INI file reading paradigms + +There are two approaches to reading settings from an INI file. One way is to call a function, such as +GetProfileString() for every section and key that you need. This is especially convenient if there is a large +INI file, but you only need a few settings from that file at any time —especially if the INI file can also +change while your program runs. This is the approach that the Microsoft Windows API uses. + +The above procedure is quite inefficient, however, when you need to retrieve quite a few settings in a row from +the INI file —especially if the INI file is not cached in memory (which it isn't, in minIni). A different approach +to getting settings from an INI file is to call a "parsing" function and let that function call the application +back with the section and key names plus the associated data. XML parsing libraries often use this approach; see +for example the Expat library. + +minIni supports both approaches. For reading a single setting, use functions like ini_gets(). For the callback +approach, implement a callback and call ini_browse(). See the minIni manual for details. + + +# INI file syntax + +INI files are best known from Microsoft Windows, but they are also used with applications that run on other +platforms (although their file extension is sometimes ".cfg" instead of ".ini"). + +INI files have a simple syntax with name/value pairs in a plain text file. The name must be unique (per section) +and the value must fit on a single line. INI files are commonly separated into sections —in minIni, this is +optional. A section is a name between square brackets, like "[Network]" in the example below. + +``` +[Network] +hostname=My Computer +address=dhcp +dns = 192.168.1.1 +``` + +In the API and in this documentation, the "name" for a setting is denoted as the key for the setting. The key +and the value are separated by an equal sign ("="). minIni supports the colon (":") as an alternative to the +equal sign for the key/value delimiter. + +Leading a trailing spaces around values or key names are removed. If you need to include leading and/or trailing +spaces in a value, put the value between double quotes. The ini_gets() function (from the minIni library, see the +minIni manual) strips off the double quotes from the returned value. Function ini_puts() adds double quotes if +the value to write contains trailing white space (or special characters). + +minIni ignores spaces around the "=" or ":" delimiters, but it does not ignore spaces between the brackets in a +section name. In other words, it is best not to put spaces behind the opening bracket "[" or before the closing +bracket "]" of a section name. + +Comments in the INI must start with a semicolon (";") or a hash character ("#"), and run to the end of the line. +A comment can be a line of its own, or it may follow a key/value pair (the "#" character and trailing comments +are extensions of minIni). + +For more details on the format, please see http://en.wikipedia.org/wiki/INI_file. + + +# Adapting minIni to a file system + +The minIni library must be configured for a platform with the help of a so- called "glue file". This glue file +contains macros (and possibly functions) that map file reading and writing functions used by the minIni library +to those provided by the operating system. The glue file must be called "minGlue.h". + +To get you started, the minIni distribution comes with the following example glue files: + + * a glue file that maps to the standard C/C++ library (specifically the file I/O functions from the "stdio" package), + * a glue file for Microchip's "Memory Disk Drive File System Library" (see http://www.microchip.com/), + * a glue file for the FAT library provided with the CCS PIC compiler (see http://www.ccsinfo.com/) + * a glue file for the EFS Library (EFSL, http://www.efsl.be/), + * and a glue file for the FatFs and Petit-FatFs libraries (http://elm-chan.org/fsw/ff/00index_e.html). + +The minIni library does not rely on the availability of a standard C library, because embedded operating systems +may have limited support for file I/O. Even on full operating systems, separating the file I/O from the INI format +parsing carries advantages, because it allows you to cache the INI file and thereby enhance performance. + +The glue file must specify the type that identifies a file, whether it is a handle or a pointer. For the standard +C/C++ file I/O library, this would be: + +```C +#define INI_FILETYPE FILE* +``` + +If you are not using the standard C/C++ file I/O library, chances are that you need a different handle or +"structure" to identify the storage than the ubiquitous "FILE*" type. For example, the glue file for the FatFs +library uses the following declaration: + +```C +#define INI_FILETYPE FIL +``` + +The minIni functions declare variables of this INI_FILETYPE type and pass these variables to sub-functions +(including the glue interface functions) by reference. + +For "write support", another type that must be defined is for variables that hold the "current position" in a +file. For the standard C/C++ I/O library, this is "fpos_t". + +Another item that needs to be configured is the buffer size. The functions in the minIni library allocate this +buffer on the stack, so the buffer size is directly related to the stack usage. In addition, the buffer size +determines the maximum line length that is supported in the INI file and the maximum path name length for the +temporary file. For example, minGlue.h could contain the definition: + +```C +#define INI_BUFFERSIZE 512 +``` + +The above macro limits the line length of the INI files supported by minIni to 512 characters. + +The temporary file is only used when writing to INI files. The minIni routines copy/change the INI file to a +temporary file and then rename that temporary file to the original file. This approach uses the least amount of +memory. The path name of the temporary file is the same as the input file, but with the last character set to a +tilde ("~"). + +Below is an example of a glue file (this is the one that maps to the C/C++ "stdio" library). + +```C +#include + +#define INI_FILETYPE FILE* +#define ini_openread(filename,file) ((*(file) = fopen((filename),"r")) != NULL) +#define ini_openwrite(filename,file) ((*(file) = fopen((filename),"w")) != NULL) +#define ini_close(file) (fclose(*(file)) == 0) +#define ini_read(buffer,size,file) (fgets((buffer),(size),*(file)) != NULL) +#define ini_write(buffer,file) (fputs((buffer),*(file)) >= 0) +#define ini_rename(source,dest) (rename((source), (dest)) == 0) +#define ini_remove(filename) (remove(filename) == 0) + +#define INI_FILEPOS fpos_t +#define ini_tell(file,pos) (fgetpos(*(file), (pos)) == 0) +#define ini_seek(file,pos) (fsetpos(*(file), (pos)) == 0) +``` + +As you can see, a glue file is mostly a set of macros that wraps one function definition around another. + +The glue file may contain more settings, for support of rational numbers, to explicitly set the line termination +character(s), or to disable write support (for example). See the manual that comes with the archive for the details. diff --git a/minIni_07/minGlue-FatFs.h b/minIni_07/minGlue-FatFs.h index 3c14e4e..250ed59 100644 --- a/minIni_07/minGlue-FatFs.h +++ b/minIni_07/minGlue-FatFs.h @@ -1,19 +1,12 @@ -/* Glue functions for the minIni library, based on the FatFs and Tiny-FatFs +/* Glue functions for the minIni library, based on the FatFs and Petit-FatFs * libraries, see http://elm-chan.org/fsw/ff/00index_e.html * - * Copyright (c) ITB CompuPhase, 2008-2009 + * By CompuPhase, 2008-2012 + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * (The FatFs and Petit-FatFs libraries are copyright by ChaN and licensed at + * its own terms.) */ #define INI_BUFFERSIZE 256 /* maximum line length, maximum path length */ @@ -22,13 +15,23 @@ * to enable the "string functions" fgets() and fputs(). */ #include "ff.h" /* include tff.h for Tiny-FatFs */ + #define INI_FILETYPE FIL +#define ini_openread(filename,file) (f_open((file), (filename), FA_READ+FA_OPEN_EXISTING) == FR_OK) +#define ini_openwrite(filename,file) (f_open((file), (filename), FA_WRITE+FA_CREATE_ALWAYS) == FR_OK) +#define ini_close(file) (f_close(file) == FR_OK) +#define ini_read(buffer,size,file) f_gets((buffer), (size),(file)) +#define ini_write(buffer,file) f_puts((buffer), (file)) +#define ini_remove(filename) (f_unlink(filename) == FR_OK) + +#define INI_FILEPOS DWORD +#define ini_tell(file,pos) (*(pos) = f_tell((file))) +#define ini_seek(file,pos) (f_lseek((file), *(pos)) == FR_OK) -#define ini_openread(filename,file) (f_open((file),(filename),FA_READ+FA_OPEN_EXISTING) == 0) -#define ini_openwrite(filename,file) (f_open((file),(filename),FA_WRITE+FA_CREATE_ALWAYS) == 0) -#define ini_close(file) f_close(file) -#define ini_read(buffer,size,file) fgets((buffer),(size),(file)) -#define ini_write(buffer,file) fputs((buffer),(file)) -#define ini_rename(source,dest) f_rename((source),(dest)) -#define ini_remove(filename) f_unlink(filename) -#define ini_rewind(file) f_lseek((file),0) +static int ini_rename(TCHAR *source, const TCHAR *dest) +{ + /* Function f_rename() does not allow drive letters in the destination file */ + char *drive = strchr(dest, ':'); + drive = (drive == NULL) ? dest : drive + 1; + return (f_rename(source, drive) == FR_OK); +} diff --git a/minIni_07/minGlue-ccs.h b/minIni_07/minGlue-ccs.h new file mode 100644 index 0000000..a8e19f1 --- /dev/null +++ b/minIni_07/minGlue-ccs.h @@ -0,0 +1,64 @@ +/* minIni glue functions for FAT library by CCS, Inc. (as provided with their + * PIC MCU compiler) + * + * By CompuPhase, 2011-2012 + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. + * + * (The FAT library is copyright (c) 2007 Custom Computer Services, and + * licensed at its own terms.) + */ + +#define INI_BUFFERSIZE 256 /* maximum line length, maximum path length */ + +#ifndef FAT_PIC_C + #error FAT library must be included before this module +#endif +#define const /* keyword not supported by CCS */ + +#define INI_FILETYPE FILE +#define ini_openread(filename,file) (fatopen((filename), "r", (file)) == GOODEC) +#define ini_openwrite(filename,file) (fatopen((filename), "w", (file)) == GOODEC) +#define ini_close(file) (fatclose((file)) == 0) +#define ini_read(buffer,size,file) (fatgets((buffer), (size), (file)) != NULL) +#define ini_write(buffer,file) (fatputs((buffer), (file)) == GOODEC) +#define ini_remove(filename) (rm_file((filename)) == 0) + +#define INI_FILEPOS fatpos_t +#define ini_tell(file,pos) (fatgetpos((file), (pos)) == 0) +#define ini_seek(file,pos) (fatsetpos((file), (pos)) == 0) + +#ifndef INI_READONLY +/* CCS FAT library lacks a rename function, so instead we copy the file to the + * new name and delete the old file + */ +static int ini_rename(char *source, char *dest) +{ + FILE fr, fw; + int n; + + if (fatopen(source, "r", &fr) != GOODEC) + return 0; + if (rm_file(dest) != 0) + return 0; + if (fatopen(dest, "w", &fw) != GOODEC) + return 0; + + /* With some "insider knowledge", we can save some memory: the "source" + * parameter holds a filename that was built from the "dest" parameter. It + * was built in a local buffer with the size INI_BUFFERSIZE. We can reuse + * this buffer for copying the file. + */ + while (n=fatread(source, 1, INI_BUFFERSIZE, &fr)) + fatwrite(source, 1, n, &fw); + + fatclose(&fr); + fatclose(&fw); + + /* Now we need to delete the source file. However, we have garbled the buffer + * that held the filename of the source. So we need to build it again. + */ + ini_tempname(source, dest, INI_BUFFERSIZE); + return rm_file(source) == 0; +} +#endif diff --git a/minIni_07/minGlue-efsl.h b/minIni_07/minGlue-efsl.h index ebb587a..69d598d 100644 --- a/minIni_07/minGlue-efsl.h +++ b/minIni_07/minGlue-efsl.h @@ -1,38 +1,33 @@ /* Glue functions for the minIni library, based on the EFS Library, see * http://www.efsl.be/ * - * Copyright (c) ITB CompuPhase, 2008-2009 + * By CompuPhase, 2008-2012 + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * (EFSL is copyright 2005-2006 Lennart Ysboodt and Michael De Nil, and + * licensed under the GPL with an exception clause for static linking.) */ #define INI_BUFFERSIZE 256 /* maximum line length, maximum path length */ - -#include "efs.h" -#define INI_FILETYPE EmbeddedFile #define INI_LINETERM "\r\n" /* set line termination explicitly */ - +#include "efs.h" extern EmbeddedFileSystem g_efs; -#define ini_openread(filename,file) (file_fopen((file),&g_efs.myFs,(char*)(filename),'r') == 0) -#define ini_openwrite(filename,file) (file_fopen((file),&g_efs.myFs,(char*)(filename),'w') == 0) +#define INI_FILETYPE EmbeddedFile +#define ini_openread(filename,file) (file_fopen((file), &g_efs.myFs, (char*)(filename), 'r') == 0) +#define ini_openwrite(filename,file) (file_fopen((file), &g_efs.myFs, (char*)(filename), 'w') == 0) #define ini_close(file) file_fclose(file) -#define ini_read(buffer,size,file) (file_read((file),(size),(buffer)) > 0) -#define ini_write(buffer,file) file_write((file),strlen(buffer),(char*)(buffer)) -#define ini_remove(filename) rmfile(&g_efs.myFs,(char*)(filename)) -#define ini_rewind(file) file_setpos(*(file),0) +#define ini_read(buffer,size,file) (file_read((file), (size), (buffer)) > 0) +#define ini_write(buffer,file) (file_write((file), strlen(buffer), (char*)(buffer)) > 0) +#define ini_remove(filename) rmfile(&g_efs.myFs, (char*)(filename)) + +#define INI_FILEPOS euint32 +#define ini_tell(file,pos) (*(pos) = (file)->FilePtr)) +#define ini_seek(file,pos) file_setpos((file), (*pos)) +#if ! defined INI_READONLY /* EFSL lacks a rename function, so instead we copy the file to the new name * and delete the old file */ @@ -65,3 +60,4 @@ static int ini_rename(char *source, const char *dest) ini_tempname(source, dest, INI_BUFFERSIZE); return rmfile(&g_efs.myFs, source) == 0; } +#endif diff --git a/minIni_07/minGlue-ffs.h b/minIni_07/minGlue-ffs.h new file mode 100644 index 0000000..5dadace --- /dev/null +++ b/minIni_07/minGlue-ffs.h @@ -0,0 +1,26 @@ +/* Glue functions for the minIni library, based on the "FAT Filing System" + * library by embedded-code.com + * + * By CompuPhase, 2008-2012 + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. + * + * (The "FAT Filing System" library itself is copyright embedded-code.com, and + * licensed at its own terms.) + */ + +#define INI_BUFFERSIZE 256 /* maximum line length, maximum path length */ +#include + +#define INI_FILETYPE FFS_FILE* +#define ini_openread(filename,file) ((*(file) = ffs_fopen((filename),"r")) != NULL) +#define ini_openwrite(filename,file) ((*(file) = ffs_fopen((filename),"w")) != NULL) +#define ini_close(file) (ffs_fclose(*(file)) == 0) +#define ini_read(buffer,size,file) (ffs_fgets((buffer),(size),*(file)) != NULL) +#define ini_write(buffer,file) (ffs_fputs((buffer),*(file)) >= 0) +#define ini_rename(source,dest) (ffs_rename((source), (dest)) == 0) +#define ini_remove(filename) (ffs_remove(filename) == 0) + +#define INI_FILEPOS long +#define ini_tell(file,pos) (ffs_fgetpos(*(file), (pos)) == 0) +#define ini_seek(file,pos) (ffs_fsetpos(*(file), (pos)) == 0) diff --git a/minIni_07/minGlue-mdd.h b/minIni_07/minGlue-mdd.h new file mode 100644 index 0000000..2f75d6f --- /dev/null +++ b/minIni_07/minGlue-mdd.h @@ -0,0 +1,58 @@ +/* minIni glue functions for Microchip's "Memory Disk Drive" file system + * library, as presented in Microchip application note AN1045. + * + * By CompuPhase, 2011-2014 + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. + * + * (The "Microchip Memory Disk Drive File System" is copyright (c) Microchip + * Technology Incorporated, and licensed at its own terms.) + */ + +#define INI_BUFFERSIZE 256 /* maximum line length, maximum path length */ + +#include "MDD File System\fsio.h" +#include + +#define INI_FILETYPE FSFILE* +#define ini_openread(filename,file) ((*(file) = FSfopen((filename),FS_READ)) != NULL) +#define ini_openwrite(filename,file) ((*(file) = FSfopen((filename),FS_WRITE)) != NULL) +#define ini_openrewrite(filename,file) ((*(file) = fopen((filename),FS_READPLUS)) != NULL) +#define ini_close(file) (FSfclose(*(file)) == 0) +#define ini_write(buffer,file) (FSfwrite((buffer), 1, strlen(buffer), (*file)) > 0) +#define ini_remove(filename) (FSremove((filename)) == 0) + +#define INI_FILEPOS long int +#define ini_tell(file,pos) (*(pos) = FSftell(*(file))) +#define ini_seek(file,pos) (FSfseek(*(file), *(pos), SEEK_SET) == 0) + +/* Since the Memory Disk Drive file system library reads only blocks of files, + * the function to read a text line does so by "over-reading" a block of the + * of the maximum size and truncating it behind the end-of-line. + */ +static int ini_read(char *buffer, int size, INI_FILETYPE *file) +{ + size_t numread = size; + char *eol; + + if ((numread = FSfread(buffer, 1, size, *file)) == 0) + return 0; /* at EOF */ + if ((eol = strchr(buffer, '\n')) == NULL) + eol = strchr(buffer, '\r'); + if (eol != NULL) { + /* terminate the buffer */ + *++eol = '\0'; + /* "unread" the data that was read too much */ + FSfseek(*file, - (int)(numread - (size_t)(eol - buffer)), SEEK_CUR); + } /* if */ + return 1; +} + +#ifndef INI_READONLY +static int ini_rename(const char *source, const char *dest) +{ + FSFILE* ftmp = FSfopen((source), FS_READ); + FSrename((dest), ftmp); + return FSfclose(ftmp) == 0; +} +#endif diff --git a/minIni_07/minGlue-stdio.h b/minIni_07/minGlue-stdio.h index 8388564..735635b 100644 --- a/minIni_07/minGlue-stdio.h +++ b/minIni_07/minGlue-stdio.h @@ -3,28 +3,29 @@ * Or better said: this file contains macros that maps the function interface * used by minIni to the standard C/C++ file I/O functions. * - * Copyright (c) ITB CompuPhase, 2008-2009 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * By CompuPhase, 2008-2014 + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. */ -/* map required file I/O to the standard C library */ +/* map required file I/O types and functions to the standard C library */ #include -#define ini_openread(filename,file) ((*(file) = fopen((filename),"rt")) != NULL) -#define ini_openwrite(filename,file) ((*(file) = fopen((filename),"wt")) != NULL) -#define ini_close(file) fclose(*(file)) -#define ini_read(buffer,size,file) fgets((buffer),(size),*(file)) -#define ini_write(buffer,file) fputs((buffer),*(file)) -#define ini_rename(source,dest) rename((source),(dest)) -#define ini_remove(filename) remove(filename) -#define ini_rewind(file) rewind(*(file)) + +#define INI_FILETYPE FILE* +#define ini_openread(filename,file) ((*(file) = fopen((filename),"rb")) != NULL) +#define ini_openwrite(filename,file) ((*(file) = fopen((filename),"wb")) != NULL) +#define ini_openrewrite(filename,file) ((*(file) = fopen((filename),"r+b")) != NULL) +#define ini_close(file) (fclose(*(file)) == 0) +#define ini_read(buffer,size,file) (fgets((buffer),(size),*(file)) != NULL) +#define ini_write(buffer,file) (fputs((buffer),*(file)) >= 0) +#define ini_rename(source,dest) (rename((source), (dest)) == 0) +#define ini_remove(filename) (remove(filename) == 0) + +#define INI_FILEPOS long int +#define ini_tell(file,pos) (*(pos) = ftell(*(file))) +#define ini_seek(file,pos) (fseek(*(file), *(pos), SEEK_SET) == 0) + +/* for floating-point support, define additional types and functions */ +#define INI_REAL float +#define ini_ftoa(string,value) sprintf((string),"%f",(value)) +#define ini_atof(string) (INI_REAL)strtod((string),NULL) diff --git a/minIni_07/minGlue.h b/minIni_07/minGlue.h index 8b86b8c..2d47d90 100644 --- a/minIni_07/minGlue.h +++ b/minIni_07/minGlue.h @@ -3,30 +3,29 @@ * Or better said: this file contains macros that maps the function interface * used by minIni to the standard C/C++ file I/O functions. * - * Copyright (c) ITB CompuPhase, 2008-2009 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Version: $Id: minGlue.h 24 2009-05-06 08:01:53Z thiadmer.riemersma $ + * By CompuPhase, 2008-2014 + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. */ -/* map required file I/O to the standard C library */ +/* map required file I/O types and functions to the standard C library */ #include -#define ini_openread(filename,file) ((*(file) = fopen((filename),"rt")) != NULL) -#define ini_openwrite(filename,file) ((*(file) = fopen((filename),"wt")) != NULL) -#define ini_close(file) fclose(*(file)) -#define ini_read(buffer,size,file) fgets((buffer),(size),*(file)) -#define ini_write(buffer,file) fputs((buffer),*(file)) -#define ini_rename(source,dest) rename((source),(dest)) -#define ini_remove(filename) remove(filename) -#define ini_rewind(file) rewind(*(file)) + +#define INI_FILETYPE FILE* +#define ini_openread(filename,file) ((*(file) = fopen((filename),"rb")) != NULL) +#define ini_openwrite(filename,file) ((*(file) = fopen((filename),"wb")) != NULL) +#define ini_openrewrite(filename,file) ((*(file) = fopen((filename),"r+b")) != NULL) +#define ini_close(file) (fclose(*(file)) == 0) +#define ini_read(buffer,size,file) (fgets((buffer),(size),*(file)) != NULL) +#define ini_write(buffer,file) (fputs((buffer),*(file)) >= 0) +#define ini_rename(source,dest) (rename((source), (dest)) == 0) +#define ini_remove(filename) (remove(filename) == 0) + +#define INI_FILEPOS long int +#define ini_tell(file,pos) (*(pos) = ftell(*(file))) +#define ini_seek(file,pos) (fseek(*(file), *(pos), SEEK_SET) == 0) + +/* for floating-point support, define additional types and functions */ +#define INI_REAL float +#define ini_ftoa(string,value) sprintf((string),"%f",(value)) +#define ini_atof(string) (INI_REAL)strtod((string),NULL) diff --git a/minIni_07/minIni.c b/minIni_07/minIni.c index bdf2ae6..fd199cb 100644 --- a/minIni_07/minIni.c +++ b/minIni_07/minIni.c @@ -3,7 +3,7 @@ * These routines are in part based on the article "Multiplatform .INI Files" * by Joseph J. Graf in the March 1994 issue of Dr. Dobb's Journal. * - * Copyright (c) ITB CompuPhase, 2008-2009 + * Copyright (c) CompuPhase, 2008-2017 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy @@ -17,10 +17,10 @@ * License for the specific language governing permissions and limitations * under the License. * - * Version: $Id: minIni.c 24 2009-05-06 08:01:53Z thiadmer.riemersma $ + * Version: $Id: minIni.c 53 2015-01-18 13:35:11Z thiadmer.riemersma@gmail.com $ */ -#if (defined _UNICODE || defined __UNICODE__ || defined UNICODE) && !defined MININI_ANSI +#if (defined _UNICODE || defined __UNICODE__ || defined UNICODE) && !defined INI_ANSIONLY # if !defined UNICODE /* for Windows */ # define UNICODE # endif @@ -29,6 +29,7 @@ # endif #endif +#define MININI_IMPLEMENTATION #include "minIni.h" #if defined NDEBUG #define assert(e) @@ -36,10 +37,11 @@ #include #endif -#if !defined __T +#if !defined __T || defined INI_ANSIONLY + #include #include #include - /* definition of TCHAR already in minIni.h */ + #define TCHAR char #define __T(s) s #define _tcscat strcat #define _tcschr strchr @@ -47,10 +49,13 @@ #define _tcscpy strcpy #define _tcsicmp stricmp #define _tcslen strlen - #define _tcsncpy strncpy + #define _tcsncmp strncmp #define _tcsnicmp strnicmp #define _tcsrchr strrchr #define _tcstol strtol + #define _tcstod strtod + #define _totupper toupper + #define _stprintf sprintf #define _tfgets fgets #define _tfputs fputs #define _tfopen fopen @@ -60,32 +65,63 @@ #if defined __linux || defined __linux__ #define __LINUX__ -#endif -#if defined FREEBSD && !defined __FreeBSD__ +#elif defined FREEBSD && !defined __FreeBSD__ #define __FreeBSD__ +#elif defined(_MSC_VER) + #pragma warning(disable: 4996) /* for Microsoft Visual C/C++ */ #endif -#if !defined strnicmp - #if defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__ +#if !defined strnicmp && !defined PORTABLE_STRNICMP + #if defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__ #define strnicmp strncasecmp #endif #endif +#if !defined _totupper + #define _totupper toupper +#endif #if !defined INI_LINETERM - #define INI_LINETERM __T("\n") + #if defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__ + #define INI_LINETERM __T("\n") + #else + #define INI_LINETERM __T("\r\n") + #endif #endif #if !defined INI_FILETYPE - #define INI_FILETYPE FILE* + #error Missing definition for INI_FILETYPE. #endif #if !defined sizearray #define sizearray(a) (sizeof(a) / sizeof((a)[0])) #endif +enum quote_option { + QUOTE_NONE, + QUOTE_ENQUOTE, + QUOTE_DEQUOTE, +}; + +#if defined PORTABLE_STRNICMP +int strnicmp(const TCHAR *s1, const TCHAR *s2, size_t n) +{ + while (n-- != 0 && (*s1 || *s2)) { + register int c1, c2; + c1 = *s1++; + if ('a' <= c1 && c1 <= 'z') + c1 += ('A' - 'a'); + c2 = *s2++; + if ('a' <= c2 && c2 <= 'z') + c2 += ('A' - 'a'); + if (c1 != c2) + return c1 - c2; + } /* while */ + return 0; +} +#endif /* PORTABLE_STRNICMP */ static TCHAR *skipleading(const TCHAR *str) { assert(str != NULL); - while (*str != '\0' && *str <= ' ') + while ('\0' < *str && *str <= ' ') str++; return (TCHAR *)str; } @@ -94,7 +130,7 @@ static TCHAR *skiptrailing(const TCHAR *str, const TCHAR *base) { assert(str != NULL); assert(base != NULL); - while (str > base && *(str-1) <= ' ') + while (str > base && '\0' < *(str-1) && *(str-1) <= ' ') str--; return (TCHAR *)str; } @@ -103,45 +139,120 @@ static TCHAR *striptrailing(TCHAR *str) { TCHAR *ptr = skiptrailing(_tcschr(str, '\0'), str); assert(ptr != NULL); - *ptr='\0'; + *ptr = '\0'; return str; } -static TCHAR *save_strncpy(TCHAR *dest, const TCHAR *source, size_t maxlen) +static TCHAR *ini_strncpy(TCHAR *dest, const TCHAR *source, size_t maxlen, enum quote_option option) { + size_t d, s; + assert(maxlen>0); - _tcsncpy(dest,source,maxlen); - dest[maxlen-1]='\0'; + assert(source != NULL && dest != NULL); + assert((dest < source || (dest == source && option != QUOTE_ENQUOTE)) || dest > source + strlen(source)); + if (option == QUOTE_ENQUOTE && maxlen < 3) + option = QUOTE_NONE; /* cannot store two quotes and a terminating zero in less than 3 characters */ + + switch (option) { + case QUOTE_NONE: + for (d = 0; d < maxlen - 1 && source[d] != '\0'; d++) + dest[d] = source[d]; + assert(d < maxlen); + dest[d] = '\0'; + break; + case QUOTE_ENQUOTE: + d = 0; + dest[d++] = '"'; + for (s = 0; source[s] != '\0' && d < maxlen - 2; s++, d++) { + if (source[s] == '"') { + if (d >= maxlen - 3) + break; /* no space to store the escape character plus the one that follows it */ + dest[d++] = '\\'; + } /* if */ + dest[d] = source[s]; + } /* for */ + dest[d++] = '"'; + dest[d] = '\0'; + break; + case QUOTE_DEQUOTE: + for (d = s = 0; source[s] != '\0' && d < maxlen - 1; s++, d++) { + if ((source[s] == '"' || source[s] == '\\') && source[s + 1] == '"') + s++; + dest[d] = source[s]; + } /* for */ + dest[d] = '\0'; + break; + default: + assert(0); + } /* switch */ + return dest; } +static TCHAR *cleanstring(TCHAR *string, enum quote_option *quotes) +{ + int isstring; + TCHAR *ep; + + assert(string != NULL); + assert(quotes != NULL); + + /* Remove a trailing comment */ + isstring = 0; + for (ep = string; *ep != '\0' && ((*ep != ';' && *ep != '#') || isstring); ep++) { + if (*ep == '"') { + if (*(ep + 1) == '"') + ep++; /* skip "" (both quotes) */ + else + isstring = !isstring; /* single quote, toggle isstring */ + } else if (*ep == '\\' && *(ep + 1) == '"') { + ep++; /* skip \" (both quotes */ + } /* if */ + } /* for */ + assert(ep != NULL && (*ep == '\0' || *ep == ';' || *ep == '#')); + *ep = '\0'; /* terminate at a comment */ + striptrailing(string); + /* Remove double quotes surrounding a value */ + *quotes = QUOTE_NONE; + if (*string == '"' && (ep = _tcschr(string, '\0')) != NULL && *(ep - 1) == '"') { + string++; + *--ep = '\0'; + *quotes = QUOTE_DEQUOTE; /* this is a string, so remove escaped characters */ + } /* if */ + return string; +} + static int getkeystring(INI_FILETYPE *fp, const TCHAR *Section, const TCHAR *Key, - int idxSection, int idxKey, TCHAR *Buffer, int BufferSize) + int idxSection, int idxKey, TCHAR *Buffer, int BufferSize, + INI_FILEPOS *mark) { TCHAR *sp, *ep; int len, idx; + enum quote_option quotes; TCHAR LocalBuffer[INI_BUFFERSIZE]; assert(fp != NULL); /* Move through file 1 line at a time until a section is matched or EOF. If * parameter Section is NULL, only look at keys above the first section. If - * idxSection is postive, copy the relevant section name. + * idxSection is positive, copy the relevant section name. */ - len = (Section != NULL) ? _tcslen(Section) : 0; + len = (Section != NULL) ? (int)_tcslen(Section) : 0; if (len > 0 || idxSection >= 0) { + assert(idxSection >= 0 || Section != NULL); idx = -1; do { if (!ini_read(LocalBuffer, INI_BUFFERSIZE, fp)) return 0; sp = skipleading(LocalBuffer); - ep = _tcschr(sp, ']'); - } while (*sp != '[' || ep == NULL || (((int)(ep-sp-1) != len || _tcsnicmp(sp+1,Section,len) != 0) && ++idx != idxSection)); + ep = _tcsrchr(sp, ']'); + } while (*sp != '[' || ep == NULL || + (((int)(ep-sp-1) != len || Section == NULL || _tcsnicmp(sp+1,Section,len) != 0) && ++idx != idxSection)); if (idxSection >= 0) { if (idx == idxSection) { assert(ep != NULL); assert(*ep == ']'); *ep = '\0'; - save_strncpy(Buffer, sp + 1, BufferSize); + ini_strncpy(Buffer, sp + 1, BufferSize, QUOTE_NONE); return 1; } /* if */ return 0; /* no more section found */ @@ -155,20 +266,23 @@ static int getkeystring(INI_FILETYPE *fp, const TCHAR *Section, const TCHAR *Key len = (Key != NULL) ? (int)_tcslen(Key) : 0; idx = -1; do { + if (mark != NULL) + ini_tell(fp, mark); /* optionally keep the mark to the start of the line */ if (!ini_read(LocalBuffer,INI_BUFFERSIZE,fp) || *(sp = skipleading(LocalBuffer)) == '[') return 0; sp = skipleading(LocalBuffer); - ep = _tcschr(sp, '='); /* Parse out the equal sign */ + ep = _tcschr(sp, '='); /* Parse out the equal sign */ if (ep == NULL) ep = _tcschr(sp, ':'); - } while (*sp == ';' || *sp == '#' || ep == NULL || (((int)(skiptrailing(ep,sp)-sp) != len || _tcsnicmp(sp,Key,len) != 0) && ++idx != idxKey)); + } while (*sp == ';' || *sp == '#' || ep == NULL + || ((len == 0 || (int)(skiptrailing(ep,sp)-sp) != len || _tcsnicmp(sp,Key,len) != 0) && ++idx != idxKey)); if (idxKey >= 0) { if (idx == idxKey) { assert(ep != NULL); assert(*ep == '=' || *ep == ':'); *ep = '\0'; striptrailing(sp); - save_strncpy(Buffer, sp, BufferSize); + ini_strncpy(Buffer, sp, BufferSize, QUOTE_NONE); return 1; } /* if */ return 0; /* no more key found (in this section) */ @@ -178,13 +292,8 @@ static int getkeystring(INI_FILETYPE *fp, const TCHAR *Section, const TCHAR *Key assert(ep != NULL); assert(*ep == '=' || *ep == ':'); sp = skipleading(ep + 1); - striptrailing(sp); - /* Remove double quotes surrounding a value */ - if (*sp == '"' && (ep = _tcschr(sp, '\0')) != NULL && *(ep - 1) == '"') { - sp++; - *--ep = '\0'; - } /* if */ - save_strncpy(Buffer, sp, BufferSize); + sp = cleanstring(sp, "es); /* Remove a trailing comment */ + ini_strncpy(Buffer, sp, BufferSize, quotes); return 1; } @@ -207,12 +316,12 @@ int ini_gets(const TCHAR *Section, const TCHAR *Key, const TCHAR *DefValue, if (Buffer == NULL || BufferSize <= 0 || Key == NULL) return 0; if (ini_openread(Filename, &fp)) { - ok = getkeystring(&fp, Section, Key, -1, -1, Buffer, BufferSize); - ini_close(&fp); + ok = getkeystring(&fp, Section, Key, -1, -1, Buffer, BufferSize, NULL); + (void)ini_close(&fp); } /* if */ if (!ok) - save_strncpy(Buffer, DefValue, BufferSize); - return _tcslen(Buffer); + ini_strncpy(Buffer, (DefValue != NULL) ? DefValue : __T(""), BufferSize, QUOTE_NONE); + return (int)_tcslen(Buffer); } /** ini_getl() @@ -225,9 +334,64 @@ int ini_gets(const TCHAR *Section, const TCHAR *Key, const TCHAR *DefValue, */ long ini_getl(const TCHAR *Section, const TCHAR *Key, long DefValue, const TCHAR *Filename) { - TCHAR buff[64]; - int len = ini_gets(Section, Key, __T(""), buff, sizearray(buff), Filename); - return (len == 0) ? DefValue : _tcstol(buff,NULL,10); + TCHAR LocalBuffer[64]; + int len = ini_gets(Section, Key, __T(""), LocalBuffer, sizearray(LocalBuffer), Filename); + return (len == 0) ? DefValue + : ((len >= 2 && _totupper((int)LocalBuffer[1]) == 'X') ? _tcstol(LocalBuffer, NULL, 16) + : _tcstol(LocalBuffer, NULL, 10)); +} + +#if defined INI_REAL +/** ini_getf() + * \param Section the name of the section to search for + * \param Key the name of the entry to find the value of + * \param DefValue the default value in the event of a failed read + * \param Filename the name of the .ini file to read from + * + * \return the value located at Key + */ +INI_REAL ini_getf(const TCHAR *Section, const TCHAR *Key, INI_REAL DefValue, const TCHAR *Filename) +{ + TCHAR LocalBuffer[64]; + int len = ini_gets(Section, Key, __T(""), LocalBuffer, sizearray(LocalBuffer), Filename); + return (len == 0) ? DefValue : ini_atof(LocalBuffer); +} +#endif + +/** ini_getbool() + * \param Section the name of the section to search for + * \param Key the name of the entry to find the value of + * \param DefValue default value in the event of a failed read; it should + * zero (0) or one (1). + * \param Filename the name and full path of the .ini file to read from + * + * A true boolean is found if one of the following is matched: + * - A string starting with 'y' or 'Y' + * - A string starting with 't' or 'T' + * - A string starting with '1' + * + * A false boolean is found if one of the following is matched: + * - A string starting with 'n' or 'N' + * - A string starting with 'f' or 'F' + * - A string starting with '0' + * + * \return the true/false flag as interpreted at Key + */ +int ini_getbool(const TCHAR *Section, const TCHAR *Key, int DefValue, const TCHAR *Filename) +{ + TCHAR LocalBuffer[2] = __T(""); + int ret; + + ini_gets(Section, Key, __T(""), LocalBuffer, sizearray(LocalBuffer), Filename); + LocalBuffer[0] = (TCHAR)_totupper((int)LocalBuffer[0]); + if (LocalBuffer[0] == 'Y' || LocalBuffer[0] == '1' || LocalBuffer[0] == 'T') + ret = 1; + else if (LocalBuffer[0] == 'N' || LocalBuffer[0] == '0' || LocalBuffer[0] == 'F') + ret = 0; + else + ret = DefValue; + + return(ret); } /** ini_getsection() @@ -246,12 +410,12 @@ int ini_getsection(int idx, TCHAR *Buffer, int BufferSize, const TCHAR *Filenam if (Buffer == NULL || BufferSize <= 0 || idx < 0) return 0; if (ini_openread(Filename, &fp)) { - ok = getkeystring(&fp, NULL, NULL, idx, -1, Buffer, BufferSize); - ini_close(&fp); + ok = getkeystring(&fp, NULL, NULL, idx, -1, Buffer, BufferSize, NULL); + (void)ini_close(&fp); } /* if */ if (!ok) *Buffer = '\0'; - return _tcslen(Buffer); + return (int)_tcslen(Buffer); } /** ini_getkey() @@ -272,54 +436,185 @@ int ini_getkey(const TCHAR *Section, int idx, TCHAR *Buffer, int BufferSize, co if (Buffer == NULL || BufferSize <= 0 || idx < 0) return 0; if (ini_openread(Filename, &fp)) { - ok = getkeystring(&fp, Section, NULL, -1, idx, Buffer, BufferSize); - ini_close(&fp); + ok = getkeystring(&fp, Section, NULL, -1, idx, Buffer, BufferSize, NULL); + (void)ini_close(&fp); } /* if */ if (!ok) *Buffer = '\0'; - return _tcslen(Buffer); + return (int)_tcslen(Buffer); } +#if !defined INI_NOBROWSE +/** ini_browse() + * \param Callback a pointer to a function that will be called for every + * setting in the INI file. + * \param UserData arbitrary data, which the function passes on the + * \c Callback function + * \param Filename the name and full path of the .ini file to read from + * + * \return 1 on success, 0 on failure (INI file not found) + * + * \note The \c Callback function must return 1 to continue + * browsing through the INI file, or 0 to stop. Even when the + * callback stops the browsing, this function will return 1 + * (for success). + */ +int ini_browse(INI_CALLBACK Callback, void *UserData, const TCHAR *Filename) +{ + TCHAR LocalBuffer[INI_BUFFERSIZE]; + int lenSec, lenKey; + enum quote_option quotes; + INI_FILETYPE fp; + + if (Callback == NULL) + return 0; + if (!ini_openread(Filename, &fp)) + return 0; + + LocalBuffer[0] = '\0'; /* copy an empty section in the buffer */ + lenSec = (int)_tcslen(LocalBuffer) + 1; + for ( ;; ) { + TCHAR *sp, *ep; + if (!ini_read(LocalBuffer + lenSec, INI_BUFFERSIZE - lenSec, &fp)) + break; + sp = skipleading(LocalBuffer + lenSec); + /* ignore empty strings and comments */ + if (*sp == '\0' || *sp == ';' || *sp == '#') + continue; + /* see whether we reached a new section */ + ep = _tcsrchr(sp, ']'); + if (*sp == '[' && ep != NULL) { + *ep = '\0'; + ini_strncpy(LocalBuffer, sp + 1, INI_BUFFERSIZE, QUOTE_NONE); + lenSec = (int)_tcslen(LocalBuffer) + 1; + continue; + } /* if */ + /* not a new section, test for a key/value pair */ + ep = _tcschr(sp, '='); /* test for the equal sign or colon */ + if (ep == NULL) + ep = _tcschr(sp, ':'); + if (ep == NULL) + continue; /* invalid line, ignore */ + *ep++ = '\0'; /* split the key from the value */ + striptrailing(sp); + ini_strncpy(LocalBuffer + lenSec, sp, INI_BUFFERSIZE - lenSec, QUOTE_NONE); + lenKey = (int)_tcslen(LocalBuffer + lenSec) + 1; + /* clean up the value */ + sp = skipleading(ep); + sp = cleanstring(sp, "es); /* Remove a trailing comment */ + ini_strncpy(LocalBuffer + lenSec + lenKey, sp, INI_BUFFERSIZE - lenSec - lenKey, quotes); + /* call the callback */ + if (!Callback(LocalBuffer, LocalBuffer + lenSec, LocalBuffer + lenSec + lenKey, UserData)) + break; + } /* for */ + + (void)ini_close(&fp); + return 1; +} +#endif /* INI_NOBROWSE */ + #if ! defined INI_READONLY static void ini_tempname(TCHAR *dest, const TCHAR *source, int maxlength) { TCHAR *p; - save_strncpy(dest, source, maxlength); + ini_strncpy(dest, source, maxlength, QUOTE_NONE); p = _tcsrchr(dest, '\0'); assert(p != NULL); *(p - 1) = '~'; } -static void writesection(TCHAR *LocalBuffer, const TCHAR *Section, INI_FILETYPE *fp) +static enum quote_option check_enquote(const TCHAR *Value) { - TCHAR *p; + const TCHAR *p; + + /* run through the value, if it has trailing spaces, or '"', ';' or '#' + * characters, enquote it + */ + assert(Value != NULL); + for (p = Value; *p != '\0' && *p != '"' && *p != ';' && *p != '#'; p++) + /* nothing */; + return (*p != '\0' || (p > Value && *(p - 1) == ' ')) ? QUOTE_ENQUOTE : QUOTE_NONE; +} +static void writesection(TCHAR *LocalBuffer, const TCHAR *Section, INI_FILETYPE *fp) +{ if (Section != NULL && _tcslen(Section) > 0) { + TCHAR *p; LocalBuffer[0] = '['; - save_strncpy(LocalBuffer + 1, Section, INI_BUFFERSIZE - 4); /* -1 for '[', -1 for ']', -2 for '\r\n' */ + ini_strncpy(LocalBuffer + 1, Section, INI_BUFFERSIZE - 4, QUOTE_NONE); /* -1 for '[', -1 for ']', -2 for '\r\n' */ p = _tcsrchr(LocalBuffer, '\0'); assert(p != NULL); *p++ = ']'; _tcscpy(p, INI_LINETERM); /* copy line terminator (typically "\n") */ - ini_write(LocalBuffer, fp); + if (fp != NULL) + (void)ini_write(LocalBuffer, fp); } /* if */ } static void writekey(TCHAR *LocalBuffer, const TCHAR *Key, const TCHAR *Value, INI_FILETYPE *fp) { TCHAR *p; - - save_strncpy(LocalBuffer, Key, INI_BUFFERSIZE - 3); /* -1 for '=', -2 for '\r\n' */ + enum quote_option option = check_enquote(Value); + ini_strncpy(LocalBuffer, Key, INI_BUFFERSIZE - 3, QUOTE_NONE); /* -1 for '=', -2 for '\r\n' */ p = _tcsrchr(LocalBuffer, '\0'); assert(p != NULL); *p++ = '='; - save_strncpy(p, Value, INI_BUFFERSIZE - (p - LocalBuffer) - 2); /* -2 for '\r\n' */ + ini_strncpy(p, Value, INI_BUFFERSIZE - (p - LocalBuffer) - 2, option); /* -2 for '\r\n' */ p = _tcsrchr(LocalBuffer, '\0'); assert(p != NULL); _tcscpy(p, INI_LINETERM); /* copy line terminator (typically "\n") */ - ini_write(LocalBuffer, fp); + if (fp != NULL) + (void)ini_write(LocalBuffer, fp); +} + +static int cache_accum(const TCHAR *string, int *size, int max) +{ + int len = (int)_tcslen(string); + if (*size + len >= max) + return 0; + *size += len; + return 1; +} + +static int cache_flush(TCHAR *buffer, int *size, + INI_FILETYPE *rfp, INI_FILETYPE *wfp, INI_FILEPOS *mark) +{ + int terminator_len = (int)_tcslen(INI_LINETERM); + int pos = 0; + + (void)ini_seek(rfp, mark); + assert(buffer != NULL); + buffer[0] = '\0'; + assert(size != NULL); + assert(*size <= INI_BUFFERSIZE); + while (pos < *size) { + (void)ini_read(buffer + pos, INI_BUFFERSIZE - pos, rfp); + while (pos < *size && buffer[pos] != '\0') + pos++; /* cannot use _tcslen() because buffer may not be zero-terminated */ + } /* while */ + if (buffer[0] != '\0') { + assert(pos > 0 && pos <= INI_BUFFERSIZE); + if (pos == INI_BUFFERSIZE) + pos--; + buffer[pos] = '\0'; /* force zero-termination (may be left unterminated in the above while loop) */ + (void)ini_write(buffer, wfp); + } + ini_tell(rfp, mark); /* update mark */ + *size = 0; + /* return whether the buffer ended with a line termination */ + return (pos > terminator_len) && (_tcscmp(buffer + pos - terminator_len, INI_LINETERM) == 0); +} + +static int close_rename(INI_FILETYPE *rfp, INI_FILETYPE *wfp, const TCHAR *filename, TCHAR *buffer) +{ + (void)ini_close(rfp); + (void)ini_close(wfp); + (void)ini_remove(filename); + (void)ini_tempname(buffer, filename, INI_BUFFERSIZE); + (void)ini_rename(buffer, filename); + return 1; } /** ini_puts() @@ -334,35 +629,66 @@ int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const T { INI_FILETYPE rfp; INI_FILETYPE wfp; + INI_FILEPOS mark; + INI_FILEPOS head, tail; TCHAR *sp, *ep; TCHAR LocalBuffer[INI_BUFFERSIZE]; - int len, match, count; + int len, match, flag, cachelen; - assert(Filename!=NULL); + assert(Filename != NULL); if (!ini_openread(Filename, &rfp)) { /* If the .ini file doesn't exist, make a new file */ - if (Key!=NULL && Value!=NULL) { + if (Key != NULL && Value != NULL) { if (!ini_openwrite(Filename, &wfp)) return 0; writesection(LocalBuffer, Section, &wfp); writekey(LocalBuffer, Key, Value, &wfp); - ini_close(&wfp); + (void)ini_close(&wfp); } /* if */ return 1; } /* if */ /* If parameters Key and Value are valid (so this is not an "erase" request) - * and the setting already exists and it already has the correct value, do - * nothing. This early bail-out avoids rewriting the INI file for no reason. + * and the setting already exists, there are two short-cuts to avoid rewriting + * the INI file. */ - if (Key!=NULL && Value!=NULL) { - match = getkeystring(&rfp, Section, Key, -1, -1, LocalBuffer, sizearray(LocalBuffer)); - if (match && _tcscmp(LocalBuffer,Value)==0) { - ini_close(&rfp); - return 1; + if (Key != NULL && Value != NULL) { + ini_tell(&rfp, &mark); + match = getkeystring(&rfp, Section, Key, -1, -1, LocalBuffer, sizearray(LocalBuffer), &head); + if (match) { + /* if the current setting is identical to the one to write, there is + * nothing to do. + */ + if (_tcscmp(LocalBuffer,Value) == 0) { + (void)ini_close(&rfp); + return 1; + } /* if */ + /* if the new setting has the same length as the current setting, and the + * glue file permits file read/write access, we can modify in place. + */ + #if defined ini_openrewrite + /* we already have the start of the (raw) line, get the end too */ + ini_tell(&rfp, &tail); + /* create new buffer (without writing it to file) */ + writekey(LocalBuffer, Key, Value, NULL); + if (_tcslen(LocalBuffer) == (size_t)(tail - head)) { + /* length matches, close the file & re-open for read/write, then + * write at the correct position + */ + (void)ini_close(&rfp); + if (!ini_openrewrite(Filename, &wfp)) + return 0; + (void)ini_seek(&wfp, &head); + (void)ini_write(LocalBuffer, &wfp); + (void)ini_close(&wfp); + return 1; + } /* if */ + #endif } /* if */ - /* key not found, or different value -> proceed (but rewind the input file first) */ - ini_rewind(&rfp); + /* key not found, or different value & length -> proceed (but rewind the + * input file first) + */ + (void)ini_seek(&rfp, &mark); } /* if */ /* Get a temporary file name to copy to. Use the existing name, but with @@ -370,122 +696,120 @@ int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const T */ ini_tempname(LocalBuffer, Filename, INI_BUFFERSIZE); if (!ini_openwrite(LocalBuffer, &wfp)) { - ini_close(&rfp); + (void)ini_close(&rfp); return 0; } /* if */ + (void)ini_tell(&rfp, &mark); + cachelen = 0; /* Move through the file one line at a time until a section is * matched or until EOF. Copy to temp file as it is read. */ - count = 0; - len = (Section != NULL) ? _tcslen(Section) : 0; + len = (Section != NULL) ? (int)_tcslen(Section) : 0; if (len > 0) { do { if (!ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) { /* Failed to find section, so add one to the end */ + flag = cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); if (Key!=NULL && Value!=NULL) { - ini_write(INI_LINETERM, &wfp); /* force a new line (there may not have been one) behind the last line of the INI file */ - writesection(LocalBuffer, Section, &wfp); - writekey(LocalBuffer, Key, Value, &wfp); + if (!flag) + (void)ini_write(INI_LINETERM, &wfp); /* force a new line behind the last line of the INI file */ + writesection(LocalBuffer, Section, &wfp); + writekey(LocalBuffer, Key, Value, &wfp); } /* if */ - /* Clean up and rename */ - ini_close(&rfp); - ini_close(&wfp); - ini_remove(Filename); - ini_tempname(LocalBuffer, Filename, INI_BUFFERSIZE); - ini_rename(LocalBuffer, Filename); - return 1; + return close_rename(&rfp, &wfp, Filename, LocalBuffer); /* clean up and rename */ } /* if */ /* Copy the line from source to dest, but not if this is the section that * we are looking for and this section must be removed */ sp = skipleading(LocalBuffer); - ep = _tcschr(sp, ']'); + ep = _tcsrchr(sp, ']'); match = (*sp == '[' && ep != NULL && (int)(ep-sp-1) == len && _tcsnicmp(sp + 1,Section,len) == 0); - if (!match || Key!=NULL) { - /* Remove blank lines, but insert a blank line (possibly one that was - * removed on the previous iteration) before a new section. This creates - * "neat" INI files. - */ - if (_tcslen(sp) > 0) { - if (*sp == '[' && count > 0) - ini_write(INI_LINETERM, &wfp); - ini_write(sp, &wfp); - count++; + if (!match || Key != NULL) { + if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) { + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE); } /* if */ } /* if */ } while (!match); } /* if */ + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + /* when deleting a section, the section head that was just found has not been + * copied to the output file, but because this line was not "accumulated" in + * the cache, the position in the input file was reset to the point just + * before the section; this must now be skipped (again) + */ + if (Key == NULL) { + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + (void)ini_tell(&rfp, &mark); + } /* if */ /* Now that the section has been found, find the entry. Stop searching * upon leaving the section's area. Copy the file as it is read * and create an entry if one is not found. */ - len = (Key!=NULL) ? _tcslen(Key) : 0; + len = (Key != NULL) ? (int)_tcslen(Key) : 0; for( ;; ) { if (!ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) { /* EOF without an entry so make one */ + flag = cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); if (Key!=NULL && Value!=NULL) { - ini_write(INI_LINETERM, &wfp); /* force a new line (there may not have been one) behind the last line of the INI file */ - writekey(LocalBuffer, Key, Value, &wfp); + if (!flag) + (void)ini_write(INI_LINETERM, &wfp); /* force a new line behind the last line of the INI file */ + writekey(LocalBuffer, Key, Value, &wfp); } /* if */ - /* Clean up and rename */ - ini_close(&rfp); - ini_close(&wfp); - ini_remove(Filename); - ini_tempname(LocalBuffer, Filename, INI_BUFFERSIZE); - ini_rename(LocalBuffer, Filename); - return 1; + return close_rename(&rfp, &wfp, Filename, LocalBuffer); /* clean up and rename */ } /* if */ sp = skipleading(LocalBuffer); ep = _tcschr(sp, '='); /* Parse out the equal sign */ if (ep == NULL) ep = _tcschr(sp, ':'); - match = (ep != NULL && (int)(ep-sp) == len && _tcsnicmp(sp,Key,len) == 0); - if ((Key!=NULL && match) || *sp == '[') + match = (ep != NULL && len > 0 && (int)(skiptrailing(ep,sp)-sp) == len && _tcsnicmp(sp,Key,len) == 0); + if ((Key != NULL && match) || *sp == '[') break; /* found the key, or found a new section */ - /* in the section that we re-write, do not copy empty lines */ - if (Key!=NULL && _tcslen(sp) > 0) - ini_write(sp, &wfp); - } /* for */ - if (*sp == '[') { - /* found start of new section, the key was not in the specified - * section, so we add it just before the new section - */ - if (Key!=NULL && Value!=NULL) { - /* We cannot use "writekey()" here, because we need to preserve the - * contents of LocalBuffer. - */ - ini_write(Key, &wfp); - ini_write("=", &wfp); - ini_write(Value, &wfp); - ini_write(INI_LINETERM INI_LINETERM, &wfp); /* put a blank line between the current and the next section */ + /* copy other keys in the section */ + if (Key == NULL) { + (void)ini_tell(&rfp, &mark); /* we are deleting the entire section, so update the read position */ + } else { + if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) { + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE); + } /* if */ } /* if */ - /* write the new section header that we read previously */ - ini_write(sp, &wfp); + } /* for */ + /* the key was found, or we just dropped on the next section (meaning that it + * wasn't found); in both cases we need to write the key, but in the latter + * case, we also need to write the line starting the new section after writing + * the key + */ + flag = (*sp == '['); + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + if (Key != NULL && Value != NULL) + writekey(LocalBuffer, Key, Value, &wfp); + /* cache_flush() reset the "read pointer" to the start of the line with the + * previous key or the new section; read it again (because writekey() destroyed + * the buffer) + */ + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + if (flag) { + /* the new section heading needs to be copied to the output file */ + cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE); } else { - /* We found the key; ignore the line just read (with the key and - * the current value) and write the key with the new value. - */ - if (Key!=NULL && Value!=NULL) - writekey(LocalBuffer, Key, Value, &wfp); + /* forget the old key line */ + (void)ini_tell(&rfp, &mark); } /* if */ - /* Copy the rest of the INI file (removing empty lines, except before a section) */ + /* Copy the rest of the INI file */ while (ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) { - sp = skipleading(LocalBuffer); - if (_tcslen(sp) > 0) { - if (*sp == '[') - ini_write(INI_LINETERM, &wfp); - ini_write(sp, &wfp); + if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) { + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE); } /* if */ } /* while */ - /* Clean up and rename */ - ini_close(&rfp); - ini_close(&wfp); - ini_remove(Filename); - ini_tempname(LocalBuffer, Filename, INI_BUFFERSIZE); - ini_rename(LocalBuffer, Filename); - return 1; + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + return close_rename(&rfp, &wfp, Filename, LocalBuffer); /* clean up and rename */ } /* Ansi C "itoa" based on Kernighan & Ritchie's "Ansi C" book. */ @@ -493,11 +817,9 @@ int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const T static void strreverse(TCHAR *str) { - TCHAR t; int i, j; - - for (i = 0, j = _tcslen(str) - 1; i < j; i++, j--) { - t = str[i]; + for (i = 0, j = (int)_tcslen(str) - 1; i < j; i++, j--) { + TCHAR t = str[i]; str[i] = str[j]; str[j] = t; } /* for */ @@ -507,11 +829,10 @@ static void long2str(long value, TCHAR *str) { int i = 0; long sign = value; - int n; /* generate digits in reverse order */ do { - n = (int)(value % 10); /* get next lowest digit */ + int n = (int)(value % 10); /* get next lowest digit */ str[i++] = (TCHAR)(ABS(n) + '0'); /* handle case of negative digit */ } while (value /= 10); /* delete the lowest digit */ if (sign < 0) @@ -523,7 +844,7 @@ static void long2str(long value, TCHAR *str) /** ini_putl() * \param Section the name of the section to write the value in - * \param Key the name of the entry to write, or NULL to erase all keys in the section + * \param Key the name of the entry to write * \param Value the value to write * \param Filename the name and full path of the .ini file to write to * @@ -531,28 +852,25 @@ static void long2str(long value, TCHAR *str) */ int ini_putl(const TCHAR *Section, const TCHAR *Key, long Value, const TCHAR *Filename) { - TCHAR str[32]; - long2str(Value, str); - return ini_puts(Section, Key, str, Filename); + TCHAR LocalBuffer[32]; + long2str(Value, LocalBuffer); + return ini_puts(Section, Key, LocalBuffer, Filename); } -#endif /* !INI_READONLY */ - -#if defined PORTABLE_STRNICMP -int strnicmp(const TCHAR *s1, const TCHAR *s2, size_t n) +#if defined INI_REAL +/** ini_putf() + * \param Section the name of the section to write the value in + * \param Key the name of the entry to write + * \param Value the value to write + * \param Filename the name and full path of the .ini file to write to + * + * \return 1 if successful, otherwise 0 + */ +int ini_putf(const TCHAR *Section, const TCHAR *Key, INI_REAL Value, const TCHAR *Filename) { - register unsigned TCHAR c1, c2; - - while (n-- != 0 && (*s1 || *s2)) { - c1 = *(const unsigned TCHAR *)s1++; - if ('a' <= c1 && c1 <= 'z') - c1 += ('A' - 'a'); - c2 = *(const unsigned TCHAR *)s2++; - if ('a' <= c2 && c2 <= 'z') - c2 += ('A' - 'a'); - if (c1 != c2) - return c1 - c2; - } /* while */ - return 0; + TCHAR LocalBuffer[64]; + ini_ftoa(LocalBuffer, Value); + return ini_puts(Section, Key, LocalBuffer, Filename); } -#endif /* PORTABLE_STRNICMP */ +#endif /* INI_REAL */ +#endif /* !INI_READONLY */ diff --git a/minIni_07/minIni.h b/minIni_07/minIni.h index 7ad254d..ff0753c 100644 --- a/minIni_07/minIni.h +++ b/minIni_07/minIni.h @@ -1,6 +1,6 @@ /* minIni - Multi-Platform INI file parser, suitable for embedded systems * - * Copyright (c) ITB CompuPhase, 2008-2009 + * Copyright (c) CompuPhase, 2008-2017 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy @@ -14,7 +14,7 @@ * License for the specific language governing permissions and limitations * under the License. * - * Version: $Id: minIni.h 24 2009-05-06 08:01:53Z thiadmer.riemersma $ + * Version: $Id: minIni.h 53 2015-01-18 13:35:11Z thiadmer.riemersma@gmail.com $ */ #ifndef MININI_H #define MININI_H @@ -23,8 +23,10 @@ #if (defined _UNICODE || defined __UNICODE__ || defined UNICODE) && !defined INI_ANSIONLY #include -#elif !defined __T - typedef char TCHAR; + #define mTCHAR TCHAR +#else + /* force TCHAR to be "char", but only for minIni */ + #define mTCHAR char #endif #if !defined INI_BUFFERSIZE @@ -35,52 +37,121 @@ extern "C" { #endif -long ini_getl(const TCHAR *Section, const TCHAR *Key, long DefValue, const TCHAR *Filename); -int ini_gets(const TCHAR *Section, const TCHAR *Key, const TCHAR *DefValue, TCHAR *Buffer, int BufferSize, const TCHAR *Filename); -int ini_putl(const TCHAR *Section, const TCHAR *Key, long Value, const TCHAR *Filename); -int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const TCHAR *Filename); -int ini_getsection(int idx, TCHAR *Buffer, int BufferSize, const TCHAR *Filename); -int ini_getkey(const TCHAR *Section, int idx, TCHAR *Buffer, int BufferSize, const TCHAR *Filename); +int ini_getbool(const mTCHAR *Section, const mTCHAR *Key, int DefValue, const mTCHAR *Filename); +long ini_getl(const mTCHAR *Section, const mTCHAR *Key, long DefValue, const mTCHAR *Filename); +int ini_gets(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *DefValue, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename); +int ini_getsection(int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename); +int ini_getkey(const mTCHAR *Section, int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename); + +#if defined INI_REAL +INI_REAL ini_getf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL DefValue, const mTCHAR *Filename); +#endif + +#if !defined INI_READONLY +int ini_putl(const mTCHAR *Section, const mTCHAR *Key, long Value, const mTCHAR *Filename); +int ini_puts(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, const mTCHAR *Filename); +#if defined INI_REAL +int ini_putf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL Value, const mTCHAR *Filename); +#endif +#endif /* INI_READONLY */ + +#if !defined INI_NOBROWSE +typedef int (*INI_CALLBACK)(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, void *UserData); +int ini_browse(INI_CALLBACK Callback, void *UserData, const mTCHAR *Filename); +#endif /* INI_NOBROWSE */ #if defined __cplusplus } #endif -#ifdef NOT_DEF + #if defined __cplusplus -#include -/* The C++ class in minIni.h was contributed by Steven Van Ingelgem. */ -class minIni -{ -public: - minIni(const std::string& filename) : iniFilename(filename) - { } +#if defined __WXWINDOWS__ + #include "wxMinIni.h" +#else + #include + + /* The C++ class in minIni.h was contributed by Steven Van Ingelgem. */ + class minIni + { + public: + minIni(const std::string& filename) : iniFilename(filename) + { } + + bool getbool(const std::string& Section, const std::string& Key, bool DefValue=false) const + { return ini_getbool(Section.c_str(), Key.c_str(), int(DefValue), iniFilename.c_str()) != 0; } + + long getl(const std::string& Section, const std::string& Key, long DefValue=0) const + { return ini_getl(Section.c_str(), Key.c_str(), DefValue, iniFilename.c_str()); } + + int geti(const std::string& Section, const std::string& Key, int DefValue=0) const + { return static_cast(this->getl(Section, Key, long(DefValue))); } + + std::string gets(const std::string& Section, const std::string& Key, const std::string& DefValue="") const + { + char buffer[INI_BUFFERSIZE]; + ini_gets(Section.c_str(), Key.c_str(), DefValue.c_str(), buffer, INI_BUFFERSIZE, iniFilename.c_str()); + return buffer; + } + + std::string getsection(int idx) const + { + char buffer[INI_BUFFERSIZE]; + ini_getsection(idx, buffer, INI_BUFFERSIZE, iniFilename.c_str()); + return buffer; + } + + std::string getkey(const std::string& Section, int idx) const + { + char buffer[INI_BUFFERSIZE]; + ini_getkey(Section.c_str(), idx, buffer, INI_BUFFERSIZE, iniFilename.c_str()); + return buffer; + } + +#if defined INI_REAL + INI_REAL getf(const std::string& Section, const std::string& Key, INI_REAL DefValue=0) const + { return ini_getf(Section.c_str(), Key.c_str(), DefValue, iniFilename.c_str()); } +#endif + +#if ! defined INI_READONLY + bool put(const std::string& Section, const std::string& Key, long Value) + { return ini_putl(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; } + + bool put(const std::string& Section, const std::string& Key, int Value) + { return ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()) != 0; } - long getl(const std::string& Section, const std::string& Key, long DefValue=0) const - { return ini_getl(Section.c_str(), Key.c_str(), DefValue, iniFilename.c_str()); } + bool put(const std::string& Section, const std::string& Key, bool Value) + { return ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()) != 0; } - long geti(const std::string& Section, const std::string& Key, int DefValue=0) const - { return reinterpret_cast( this->getl(Section, Key, DefValue) ); } + bool put(const std::string& Section, const std::string& Key, const std::string& Value) + { return ini_puts(Section.c_str(), Key.c_str(), Value.c_str(), iniFilename.c_str()) != 0; } - std::string gets(const std::string& Section, const std::string& Key, const std::string& DefValue="") const - { - char buffer[INI_BUFFERSIZE]; - ini_gets(Section.c_str(), Key.c_str(), DefValue.c_str(), buffer, INI_BUFFERSIZE, iniFilename.c_str()); - return buffer; - } + bool put(const std::string& Section, const std::string& Key, const char* Value) + { return ini_puts(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; } + +#if defined INI_REAL + bool put(const std::string& Section, const std::string& Key, INI_REAL Value) + { return ini_putf(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; } +#endif - bool put(const std::string& Section, const std::string& Key, long Value) const - { return ini_putl(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()); } + bool del(const std::string& Section, const std::string& Key) + { return ini_puts(Section.c_str(), Key.c_str(), 0, iniFilename.c_str()) != 0; } - bool put(const std::string& Section, const std::string& Key, const std::string& Value) const - { return ini_puts(Section.c_str(), Key.c_str(), Value.c_str(), iniFilename.c_str()); } + bool del(const std::string& Section) + { return ini_puts(Section.c_str(), 0, 0, iniFilename.c_str()) != 0; } +#endif + +#if !defined INI_NOBROWSE + bool browse(INI_CALLBACK Callback, void *UserData) const + { return ini_browse(Callback, UserData, iniFilename.c_str()) != 0; } +#endif -private: + private: std::string iniFilename; -}; + }; +#endif /* __WXWINDOWS__ */ #endif /* __cplusplus */ -#endif /* NOT_DEF */ #endif /* MININI_H */ diff --git a/minIni_07/test.c b/minIni_07/test.c index 5e2001b..7722efd 100644 --- a/minIni_07/test.c +++ b/minIni_07/test.c @@ -1,6 +1,6 @@ /* Simple test program * - * wcl386 -wx -d2 -q test.c minini.c + * gcc -o test test.c minIni.c */ #include #include @@ -10,6 +10,14 @@ #define sizearray(a) (sizeof(a) / sizeof((a)[0])) const char inifile[] = "test.ini"; +const char inifile2[] = "testplain.ini"; + +int Callback(const char *section, const char *key, const char *value, void *userdata) +{ + (void)userdata; /* this parameter is not used in this example */ + printf(" [%s]\t%s=%s\n", section, key, value); + return 1; +} int main(void) { @@ -19,12 +27,18 @@ int main(void) char section[50]; /* string reading */ - n = ini_gets("first", "string", "aap", str, sizearray(str), inifile); + n = ini_gets("first", "string", "dummy", str, sizearray(str), inifile); assert(n==4 && strcmp(str,"noot")==0); - n = ini_gets("second", "string", "aap", str, sizearray(str), inifile); + n = ini_gets("second", "string", "dummy", str, sizearray(str), inifile); assert(n==4 && strcmp(str,"mies")==0); - n = ini_gets("first", "dummy", "aap", str, sizearray(str), inifile); - assert(n==3 && strcmp(str,"aap")==0); + n = ini_gets("first", "undefined", "dummy", str, sizearray(str), inifile); + assert(n==5 && strcmp(str,"dummy")==0); + /* ----- */ + n = ini_gets("", "string", "dummy", str, sizearray(str), inifile2); + assert(n==4 && strcmp(str,"noot")==0); + n = ini_gets(NULL, "string", "dummy", str, sizearray(str), inifile2); + assert(n==4 && strcmp(str,"noot")==0); + /* ----- */ printf("1. String reading tests passed\n"); /* value reading */ @@ -32,36 +46,60 @@ int main(void) assert(n==1); n = ini_getl("second", "val", -1, inifile); assert(n==2); - n = ini_getl("first", "dummy", -1, inifile); + n = ini_getl("first", "undefined", -1, inifile); assert(n==-1); + /* ----- */ + n = ini_getl(NULL, "val", -1, inifile2); + assert(n==1); + /* ----- */ printf("2. Value reading tests passed\n"); /* string writing */ - n = ini_puts("first", "alt", "correct", inifile); + n = ini_puts("first", "alt", "flagged as \"correct\"", inifile); assert(n==1); - n = ini_gets("first", "alt", "aap", str, sizearray(str), inifile); - assert(n==7 && strcmp(str,"correct")==0); + n = ini_gets("first", "alt", "dummy", str, sizearray(str), inifile); + assert(n==20 && strcmp(str,"flagged as \"correct\"")==0); /* ----- */ n = ini_puts("second", "alt", "correct", inifile); assert(n==1); - n = ini_gets("second", "alt", "aap", str, sizearray(str), inifile); + n = ini_gets("second", "alt", "dummy", str, sizearray(str), inifile); assert(n==7 && strcmp(str,"correct")==0); /* ----- */ - n = ini_puts("third", "alt", "correct", inifile); + n = ini_puts("third", "test", "correct", inifile); assert(n==1); - n = ini_gets("third", "alt", "aap", str, sizearray(str), inifile); + n = ini_gets("third", "test", "dummy", str, sizearray(str), inifile); + assert(n==7 && strcmp(str,"correct")==0); + /* ----- */ + n = ini_puts("second", "alt", "overwrite", inifile); + assert(n==1); + n = ini_gets("second", "alt", "dummy", str, sizearray(str), inifile); + assert(n==9 && strcmp(str,"overwrite")==0); + /* ----- */ + n = ini_puts("second", "alt", "123456789", inifile); + assert(n==1); + n = ini_gets("second", "alt", "dummy", str, sizearray(str), inifile); + assert(n==9 && strcmp(str,"123456789")==0); + /* ----- */ + n = ini_puts(NULL, "alt", "correct", inifile2); + assert(n==1); + n = ini_gets(NULL, "alt", "dummy", str, sizearray(str), inifile2); assert(n==7 && strcmp(str,"correct")==0); /* ----- */ printf("3. String writing tests passed\n"); /* section/key enumeration */ + printf("4. Section/key enumeration, file structure follows\n"); for (s = 0; ini_getsection(s, section, sizearray(section), inifile) > 0; s++) { - printf("[%s]\n", section); + printf(" [%s]\n", section); for (k = 0; ini_getkey(section, k, str, sizearray(str), inifile) > 0; k++) { printf("\t%s\n", str); } /* for */ } /* for */ - + + /* browsing through the file */ + printf("5. browse through all settings, file field list follows\n"); + ini_browse(Callback, NULL, inifile); + /* string deletion */ n = ini_puts("first", "alt", NULL, inifile); assert(n==1); @@ -69,6 +107,10 @@ int main(void) assert(n==1); n = ini_puts("third", NULL, NULL, inifile); assert(n==1); + /* ----- */ + n = ini_puts(NULL, "alt", NULL, inifile2); + assert(n==1); + printf("6. String deletion tests passed\n"); return 0; } diff --git a/minIni_07/test.ini b/minIni_07/test.ini index b215a0a..3c22632 100644 --- a/minIni_07/test.ini +++ b/minIni_07/test.ini @@ -1,8 +1,8 @@ [First] -String=noot +String=noot # trailing commment Val=1 [Second] Val = 2 -String = mies #comment=3 +String = mies diff --git a/minIni_07/test2.cc b/minIni_07/test2.cc new file mode 100644 index 0000000..4e19b31 --- /dev/null +++ b/minIni_07/test2.cc @@ -0,0 +1,80 @@ +/* + gcc -o minIni.o -c minIni.c + g++ -o test2.o -c test2.cc + g++ -o test2 test2.o minIni.o + ./test2 +*/ + + +#include +#include +#include +using namespace std ; + +#include "minIni.h" + +int main(void) +{ + minIni ini("test.ini"); + string s; + + /* string reading */ + s = ini.gets( "first", "string" , "aap" ); + assert(s == "noot"); + s = ini.gets( "second", "string" , "aap" ); + assert(s == "mies"); + s = ini.gets( "first", "dummy" , "aap" ); + assert(s == "aap"); + cout << "1. String reading tests passed" << endl ; + + + /* value reading */ + long n; + n = ini.getl("first", "val", -1 ); + assert(n==1); + n = ini.getl("second", "val", -1); + assert(n==2); + n = ini.getl("first", "dummy", -1); + assert(n==-1); + cout << "2. Value reading tests passed" << endl ; + + + /* string writing */ + bool b; + b = ini.put("first", "alt", "flagged as \"correct\""); + assert(b); + s = ini.gets("first", "alt", "aap"); + assert(s=="flagged as \"correct\""); + + b = ini.put("second", "alt", "correct"); + assert(b); + s = ini.gets("second", "alt", "aap"); + assert(s=="correct"); + + b = ini.put("third", "alt", "correct"); + assert(b); + s = ini.gets("third", "alt", "aap" ); + assert(s=="correct"); + cout << "3. String writing tests passed" << endl; + + /* section/key enumeration */ + cout << "4. section/key enumeration; file contents follows" << endl; + string section; + for (int is = 0; section = ini.getsection(is), section.length() > 0; is++) { + cout << " [" << section.c_str() << "]" << endl; + for (int ik = 0; s = ini.getkey(section, ik), s.length() > 0; ik++) { + cout << "\t" << s.c_str() << endl; + } + } + + /* string deletion */ + b = ini.del("first", "alt"); + assert(b); + b = ini.del("second", "alt"); + assert(b); + b = ini.del("third"); + assert(b); + cout << "5. string deletion passed " << endl; + + return 0; +} diff --git a/minIni_07/testplain.ini b/minIni_07/testplain.ini new file mode 100644 index 0000000..53df5ca --- /dev/null +++ b/minIni_07/testplain.ini @@ -0,0 +1,3 @@ +String=noot # trailing commment +#comment=3 +Val=1 diff --git a/minIni_07/wxMinIni.h b/minIni_07/wxMinIni.h index 51609f9..e59a74e 100644 --- a/minIni_07/wxMinIni.h +++ b/minIni_07/wxMinIni.h @@ -1,73 +1,101 @@ +/* minIni - Multi-Platform INI file parser, wxWidgets interface + * + * Copyright (c) CompuPhase, 2008-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Version: $Id: wxMinIni.h 44 2012-01-04 15:52:56Z thiadmer.riemersma@gmail.com $ + */ #ifndef WXMININI_H #define WXMININI_H #include -#include "minini.h" - -#if defined __linux || defined __linux__ || defined __LINUX__ \ - || defined FREEBSD || defined __FreeBSD__ || defined __OpenBSD__ - #define DIRSEP_CHAR '/' - #define DIRSEP_STR "/" -#else - #define DIRSEP_CHAR '\\' - #define DIRSEP_STR "\\" -#endif +#include "minIni.h" -class minIni { +class minIni +{ public: - minIni(const wxString& name, const wxString& path=wxT("")) - { - if (path.Len() > 0) - iniFilename = path; - else - iniFilename = wxGetCwd(); - int len = iniFilename.Len(); - if (len > 0 && iniFilename[len] != DIRSEP_CHAR) - iniFilename += wxT(DIRSEP_STR); - iniFilename += name; - } - - long getl(const wxString& Section, const wxString& Key, long DefValue=0, const wxString& Filename=wxT("")) - { - wxString name = Filename.Len() > 0 ? Filename : iniFilename; - return ini_getl(Section.utf8_str(), Key.utf8_str(), DefValue, name.utf8_str()); - } - - int geti(const wxString& Section, const wxString& Key, int DefValue=0, const wxString& Filename=wxT("")) - { - wxString name = Filename.Len() > 0 ? Filename : iniFilename; - return (int)ini_getl(Section.utf8_str(), Key.utf8_str(), DefValue, name.utf8_str()); - } - - wxString gets(const wxString& Section, const wxString& Key, const wxString& DefValue=wxT(""), const wxString& Filename=wxT("")) - { - wxString name = Filename.Len() > 0 ? Filename : iniFilename; - char buffer[INI_BUFFERSIZE]; - ini_gets(Section.utf8_str(), Key.utf8_str(), DefValue.utf8_str(), buffer, INI_BUFFERSIZE, name.utf8_str()); - wxString result = wxString::FromUTF8(buffer); - return result; - } - - bool put(const wxString& Section, const wxString& Key, long Value, const wxString& Filename=wxT("")) - { - wxString name = Filename.Len() > 0 ? Filename : iniFilename; - return ini_putl(Section.utf8_str(), Key.utf8_str(), Value, name.utf8_str()); - } - - bool put(const wxString& Section, const wxString& Key, int Value, const wxString& Filename=wxT("")) - { - wxString name = Filename.Len() > 0 ? Filename : iniFilename; - return ini_putl(Section.utf8_str(), Key.utf8_str(), Value, name.utf8_str()); - } - - bool put(const wxString& Section, const wxString& Key, const wxString& Value, const wxString& Filename=wxT("")) - { - wxString name = Filename.Len() > 0 ? Filename : iniFilename; - return ini_puts(Section.utf8_str(), Key.utf8_str(), Value.utf8_str(), name.utf8_str()); - } + minIni(const wxString& filename) : iniFilename(filename) + { } + + bool getbool(const wxString& Section, const wxString& Key, bool DefValue=false) const + { return ini_getbool(Section.utf8_str(), Key.utf8_str(), int(DefValue), iniFilename.utf8_str()) != 0; } + + long getl(const wxString& Section, const wxString& Key, long DefValue=0) const + { return ini_getl(Section.utf8_str(), Key.utf8_str(), DefValue, iniFilename.utf8_str()); } + + int geti(const wxString& Section, const wxString& Key, int DefValue=0) const + { return static_cast(ini_getl(Section.utf8_str(), Key.utf8_str(), (long)DefValue, iniFilename.utf8_str())); } + + wxString gets(const wxString& Section, const wxString& Key, const wxString& DefValue=wxT("")) const + { + char buffer[INI_BUFFERSIZE]; + ini_gets(Section.utf8_str(), Key.utf8_str(), DefValue.utf8_str(), buffer, INI_BUFFERSIZE, iniFilename.utf8_str()); + wxString result = wxString::FromUTF8(buffer); + return result; + } + + wxString getsection(int idx) const + { + char buffer[INI_BUFFERSIZE]; + ini_getsection(idx, buffer, INI_BUFFERSIZE, iniFilename.utf8_str()); + wxString result = wxString::FromUTF8(buffer); + return result; + } + + wxString getkey(const wxString& Section, int idx) const + { + char buffer[INI_BUFFERSIZE]; + ini_getkey(Section.utf8_str(), idx, buffer, INI_BUFFERSIZE, iniFilename.utf8_str()); + wxString result = wxString::FromUTF8(buffer); + return result; + } + +#if defined INI_REAL + INI_REAL getf(const wxString& Section, wxString& Key, INI_REAL DefValue=0) const + { return ini_getf(Section.utf8_str(), Key.utf8_str(), DefValue, iniFilename.utf8_str()); } +#endif + +#if ! defined INI_READONLY + bool put(const wxString& Section, const wxString& Key, long Value) const + { return ini_putl(Section.utf8_str(), Key.utf8_str(), Value, iniFilename.utf8_str()) != 0; } + + bool put(const wxString& Section, const wxString& Key, int Value) const + { return ini_putl(Section.utf8_str(), Key.utf8_str(), (long)Value, iniFilename.utf8_str()) != 0; } + + bool put(const wxString& Section, const wxString& Key, bool Value) const + { return ini_putl(Section.utf8_str(), Key.utf8_str(), (long)Value, iniFilename.utf8_str()) != 0; } + + bool put(const wxString& Section, const wxString& Key, const wxString& Value) const + { return ini_puts(Section.utf8_str(), Key.utf8_str(), Value.utf8_str(), iniFilename.utf8_str()) != 0; } + + bool put(const wxString& Section, const wxString& Key, const char* Value) const + { return ini_puts(Section.utf8_str(), Key.utf8_str(), Value, iniFilename.utf8_str()) != 0; } + +#if defined INI_REAL + bool put(const wxString& Section, const wxString& Key, INI_REAL Value) const + { return ini_putf(Section.utf8_str(), Key.utf8_str(), Value, iniFilename.utf8_str()) != 0; } +#endif + + bool del(const wxString& Section, const wxString& Key) const + { return ini_puts(Section.utf8_str(), Key.utf8_str(), 0, iniFilename.utf8_str()) != 0; } + + bool del(const wxString& Section) const + { return ini_puts(Section.utf8_str(), 0, 0, iniFilename.utf8_str()) != 0; } +#endif private: - wxString iniFilename; + wxString iniFilename; }; #endif /* WXMININI_H */ From d18c7f66e337d2fe84f2f2e09b76df0d2af642c2 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 12:21:12 +0100 Subject: [PATCH 31/41] C++11 Conversion: Minor const correctness changes --- src/axis.hpp | 4 ++-- src/component.hpp | 2 +- src/condition.hpp | 2 +- src/device_datum.hpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/axis.hpp b/src/axis.hpp index addf90b..6e725e7 100644 --- a/src/axis.hpp +++ b/src/axis.hpp @@ -68,7 +68,7 @@ class Axis : public Component Units mUnits; public: - Axis(Adapter *adapter, std::string name, Component *parent = nullptr) : + Axis(Adapter *adapter, const std::string &name, Component *parent = nullptr) : Component(adapter, name, parent), mNumber(0), mMode(INDEX), @@ -95,7 +95,7 @@ class Linear : public Axis Sample mCommandedPosition; public: - Linear(Adapter *adapter, std::string name, Component *parent = nullptr) : + Linear(Adapter *adapter, const std::string &name, Component *parent = nullptr) : Axis(adapter, name, parent) { mType = LINEAR; diff --git a/src/component.hpp b/src/component.hpp index 3e5708f..7a991e5 100644 --- a/src/component.hpp +++ b/src/component.hpp @@ -49,7 +49,7 @@ class Component Component *mParent; public: - Component(Adapter *adapter, std::string name, Component *parent = nullptr) : + Component(Adapter *adapter, const std::string &name, Component *parent = nullptr) : mAdapter(adapter), mName(name), mParent(parent) diff --git a/src/condition.hpp b/src/condition.hpp index 2525bc1..b56db6e 100644 --- a/src/condition.hpp +++ b/src/condition.hpp @@ -140,7 +140,7 @@ class Condition : public DeviceDatum void add(ActiveCondition *condition); - void append( + static void append( StringBuffer &stringBuffer, char *buffer, ActiveCondition *cond, diff --git a/src/device_datum.hpp b/src/device_datum.hpp index 0c6a30f..8b39808 100644 --- a/src/device_datum.hpp +++ b/src/device_datum.hpp @@ -65,7 +65,7 @@ class DeviceDatum bool mHasValue; protected: - void appendText(char *buffer, char *value, int maxLen); + static void appendText(char *buffer, char *value, int maxLen); public: // The name will be supplied later... From d021b7baf36cbd5c9e7bc9e93419b998982dd96e Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 23 Apr 2018 13:56:22 +0100 Subject: [PATCH 32/41] Added device items for macro variables --- fanuc/fanuc.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fanuc/fanuc.xml b/fanuc/fanuc.xml index e032138..7b73fe6 100644 --- a/fanuc/fanuc.xml +++ b/fanuc/fanuc.xml @@ -7,6 +7,10 @@ + + + + From f4bb80ff5dd536d18085a4acc4879478222748f9 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Wed, 25 Apr 2018 09:27:11 +0100 Subject: [PATCH 33/41] Added a ClangFormat file so that a consistent style may be applied to the code base --- _clang-format | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 _clang-format diff --git a/_clang-format b/_clang-format new file mode 100644 index 0000000..8dcb295 --- /dev/null +++ b/_clang-format @@ -0,0 +1,32 @@ +--- +AccessModifierOffset: '-4' +AlignAfterOpenBracket: AlwaysBreak +AllowShortBlocksOnASingleLine: 'false' +AllowShortCaseLabelsOnASingleLine: 'false' +AllowShortIfStatementsOnASingleLine: 'false' +AllowShortLoopsOnASingleLine: 'false' +BinPackParameters: 'false' +BreakBeforeBraces: Allman +BreakConstructorInitializersBeforeComma: 'true' +ColumnLimit: '0' +Cpp11BracedListStyle: 'true' +IndentCaseLabels: 'false' +IndentWidth: '4' +KeepEmptyLinesAtTheStartOfBlocks: 'true' +Language: Cpp +MaxEmptyLinesToKeep: '2' +NamespaceIndentation: None +PointerAlignment: Right +SortIncludes: 'false' +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: 'false' +SpacesBeforeTrailingComments: '1' +SpacesInAngles: 'true' +SpacesInContainerLiterals: 'false' +SpacesInParentheses: 'true' +SpacesInSquareBrackets: 'false' +Standard: Cpp11 +TabWidth: '4' +UseTab: Always + +... From 5a11b40e072c589e744a2052788b1c5fef3450b3 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Fri, 27 Apr 2018 11:27:19 +0100 Subject: [PATCH 34/41] Added Howard Hinnant's Date library as a submodule * This is a header only ilibrary which builds upon . It adds some new duration types, and new time_point types. It also adds "field" types such as year_month_day which is a struct {year, month, day}. And it provides convenient means to convert between the "field" types and the time_point types. --- .gitmodules | 3 +++ date | 1 + 2 files changed, 4 insertions(+) create mode 160000 date diff --git a/.gitmodules b/.gitmodules index 74f4530..2d1f1ae 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "cppunit"] path = cppunit url = http://anongit.freedesktop.org/git/libreoffice/cppunit +[submodule "date"] + path = date + url = https://github.com/HowardHinnant/date.git diff --git a/date b/date new file mode 160000 index 0000000..a91ceef --- /dev/null +++ b/date @@ -0,0 +1 @@ +Subproject commit a91ceefb4e594648540cc0a3c00611cd962989f9 From fdffb6c2aa519c16b7c281f63d9d36515f9d6574 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 30 Apr 2018 07:46:36 +0100 Subject: [PATCH 35/41] Use of std::chrono and date functions when dealing with time/duration/dates * Converted old integer timeout/period values to std::chrono::milliseconds * Use 'Date' library functions for converting a std::chrono::time_point into an ISO 8601 formatted string_buffer (now platform independent code) --- CMakeLists.txt | 1 + cmake/Date.cmake | 12 +++++++++ fake/CMakeLists.txt | 3 ++- fanuc/CMakeLists.txt | 1 + src/adapter.cpp | 2 +- src/adapter.hpp | 2 +- src/client.hpp | 3 ++- src/logger.cpp | 42 ++++++++++++------------------- src/logger.hpp | 3 ++- src/server.cpp | 57 +++++++++---------------------------------- src/server.hpp | 7 +++--- src/string_buffer.cpp | 45 ++++++++++------------------------ src/string_buffer.hpp | 6 +++-- test/CMakeLists.txt | 3 ++- 14 files changed, 72 insertions(+), 115 deletions(-) create mode 100644 cmake/Date.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index eb951ee..d703ac9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ endif() include(cmake/osx_no_app_or_frameworks.cmake) include(cmake/msvc_xp_support.cmake) include(cmake/vs_set_working_directory.cmake) +include(cmake/date.cmake) include(cmake/adapter_fanuc.cmake) # Add our dependency projects diff --git a/cmake/Date.cmake b/cmake/Date.cmake new file mode 100644 index 0000000..f1a6f66 --- /dev/null +++ b/cmake/Date.cmake @@ -0,0 +1,12 @@ +# This module allows the addition of Date to a target + +################################################################################# +# # +# Functions # +# # +################################################################################# + +function(AddDateSupport projectTarget) + # Only support the header-only implementation of date, so just add an include path to the target + target_include_directories(${projectTarget} PRIVATE ${CMAKE_SOURCE_DIR}/date/include) +endfunction() \ No newline at end of file diff --git a/fake/CMakeLists.txt b/fake/CMakeLists.txt index 113b8d0..0d9ac3e 100644 --- a/fake/CMakeLists.txt +++ b/fake/CMakeLists.txt @@ -47,4 +47,5 @@ if(WIN32) ) endif() -AddMsvcXPSupport(fake_adapter) #This will only apply if an XP compatible toolset has been selected in CMake \ No newline at end of file +AddMsvcXPSupport(fake_adapter) #This will only apply if an XP compatible toolset has been selected in CMake +AddDateSupport(fake_adapter) \ No newline at end of file diff --git a/fanuc/CMakeLists.txt b/fanuc/CMakeLists.txt index 3ff1a64..e4f17be 100644 --- a/fanuc/CMakeLists.txt +++ b/fanuc/CMakeLists.txt @@ -93,6 +93,7 @@ endif() AddFocas2Support(fanuc) AddMsvcXPSupport(fanuc) #This will only apply if an XP compatible toolset has been selected in CMake +AddDateSupport(fanuc) # Copy the ini file and devices XML to our output directory file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/adapter.ini DESTINATION ./Debug/) diff --git a/src/adapter.cpp b/src/adapter.cpp index f41ea1d..9d5e0a7 100755 --- a/src/adapter.cpp +++ b/src/adapter.cpp @@ -44,7 +44,7 @@ Adapter::Adapter(int port, int scanDelayMs) : mScanDelay{scanDelayMs}, mPort(port), mDisableFlush(false), - mHeartbeatFrequency(10000), + mHeartbeatFrequency{10000}, mRunning(false), mInitializeClient(nullptr) { diff --git a/src/adapter.hpp b/src/adapter.hpp index 3d666a3..34c331b 100644 --- a/src/adapter.hpp +++ b/src/adapter.hpp @@ -62,7 +62,7 @@ class Adapter std::chrono::milliseconds mScanDelay; // How long to sleep (in ms) between scans int mPort; // The server port we bind to bool mDisableFlush; // Used for initial data collection - int mHeartbeatFrequency; // The frequency (ms) to heartbeat server. Responds to Ping. Default 10 sec + std::chrono::milliseconds mHeartbeatFrequency; // The frequency (ms) to heartbeat server. Responds to Ping. Default 10 sec bool mRunning; Client *mInitializeClient; // If we are sending initial data to a client diff --git a/src/client.hpp b/src/client.hpp index e6f8880..8d7bc7a 100755 --- a/src/client.hpp +++ b/src/client.hpp @@ -33,6 +33,7 @@ #pragma once #include +#include // @@ -49,7 +50,7 @@ class Client // class methods public: bool mHeartbeats; - unsigned int mLastHeartbeat; + std::chrono::time_point mLastHeartbeat; // Instance methods public: diff --git a/src/logger.cpp b/src/logger.cpp index 58091f7..9836859 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -32,6 +32,14 @@ // #include "internal.hpp" #include "logger.hpp" +#ifdef min + #undef min +#endif +#ifdef max + #undef max +#endif +#include +#include Logger *gLogger = nullptr; @@ -39,11 +47,10 @@ Logger *gLogger = nullptr; void Logger::error(const char *inputformat, ...) { char buffer[LOGGER_BUFFER_SIZE]; - char ts[32]; va_list args; va_start(args, inputformat); fprintf(mFile, "%s - Error: %s\n", - timestamp(ts), + timestamp().c_str(), format(buffer, LOGGER_BUFFER_SIZE, inputformat, args)); fflush(mFile); va_end(args); @@ -56,11 +63,10 @@ void Logger::warning(const char *inputformat, ...) return; char buffer[LOGGER_BUFFER_SIZE]; - char ts[32]; va_list args; va_start(args, inputformat); fprintf(mFile, "%s - Warning: %s\n", - timestamp(ts), + timestamp().c_str(), format(buffer, LOGGER_BUFFER_SIZE, inputformat, args)); fflush(mFile); va_end(args); @@ -73,11 +79,10 @@ void Logger::info(const char *inputformat, ...) return; char buffer[LOGGER_BUFFER_SIZE]; - char ts[32]; va_list args; va_start(args, inputformat); fprintf(mFile, "%s - Info: %s\n", - timestamp(ts), + timestamp().c_str(), format(buffer, LOGGER_BUFFER_SIZE, inputformat, args)); fflush(mFile); va_end(args); @@ -90,11 +95,10 @@ void Logger::debug(const char *inputformat, ...) return; char buffer[LOGGER_BUFFER_SIZE]; - char ts[32]; va_list args; va_start(args, inputformat); fprintf(mFile, "%s - Debug: %s\n", - timestamp(ts), + timestamp().c_str(), format(buffer, LOGGER_BUFFER_SIZE, inputformat, args)); fflush(mFile); va_end(args); @@ -109,22 +113,8 @@ const char *Logger::format(char *buffer, int aLen, const char *inputformat, va_l } -const char *Logger::timestamp(char *buffer) +std::string Logger::timestamp() { -#ifdef WIN32 - SYSTEMTIME st; - GetSystemTime(&st); - sprintf(buffer, "%4d-%02d-%02dT%02d:%02d:%02d.%03dZ", st.wYear, st.wMonth, st.wDay, st.wHour, - st.wMinute, st.wSecond, st.wMilliseconds); -#else - struct timeval tv; - struct timezone tz; - - gettimeofday(&tv, &tz); - - strftime(buffer, 64, "%Y-%m-%dT%H:%M:%S", gmtime(&tv.tv_sec)); - sprintf(buffer + strlen(buffer), ".%06dZ", tv.tv_usec); -#endif - - return buffer; -} + return date::format("%FT%TZ", + std::chrono::time_point_cast(std::chrono::system_clock::now())); +} \ No newline at end of file diff --git a/src/logger.hpp b/src/logger.hpp index 983a801..1c24f75 100644 --- a/src/logger.hpp +++ b/src/logger.hpp @@ -34,6 +34,7 @@ #include #include +#include #define LOGGER_BUFFER_SIZE 1024 @@ -66,7 +67,7 @@ class Logger protected: const char *format(char *buffer, int aLen, const char *format, va_list args); - const char *timestamp(char *buffer); + std::string timestamp(); LogLevel mLogLevel; FILE *mFile; diff --git a/src/server.cpp b/src/server.cpp index b7175f5..bf46f20 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -34,15 +34,16 @@ #include "server.hpp" #include "client.hpp" #include "logger.hpp" +#include const int READ_BUFFER_LEN = 8092; // Create the server and bind to the port -Server::Server(int aPort, int aHeartbeatFreq) +Server::Server(int port, std::chrono::milliseconds heartbeatFreq) { mNumClients = 0; - mPort = aPort; - mTimeout = aHeartbeatFreq * 2; + mPort = port; + mTimeout = heartbeatFreq * 2; SOCKADDR_IN t; @@ -70,12 +71,12 @@ Server::Server(int aPort, int aHeartbeatFreq) } t.sin_family = AF_INET; - t.sin_port = htons(aPort); + t.sin_port = htons(port); t.sin_addr.s_addr = htonl(INADDR_ANY); if (::bind(mSocket, (SOCKADDR *)&t, sizeof(t)) == SOCKET_ERROR) { - gLogger->error("Failed to bind on port %d", aPort); + gLogger->error("Failed to bind on port %d", port); delete this; exit(1); } @@ -88,9 +89,9 @@ Server::Server(int aPort, int aHeartbeatFreq) } // Default to a 10 second heartbeat - sprintf(mPong, "* PONG %d\n", aHeartbeatFreq); + sprintf(mPong, "* PONG %I64d\n", heartbeatFreq.count()); - gLogger->info("Server started, waiting on port %d", aPort); + gLogger->info("Server started, waiting on port %d", port); } @@ -161,7 +162,7 @@ void Server::readFromClients() if (!client->mHeartbeats) client->mHeartbeats = true; - client->mLastHeartbeat = getTimestamp(); + client->mLastHeartbeat = std::chrono::system_clock::now(); client->write(mPong); } else @@ -177,12 +178,12 @@ void Server::readFromClients() // Check heartbeats for (int i = mNumClients - 1; i >= 0; i--) { - Client *client = mClients[i]; - unsigned int now = getTimestamp(); + auto client = mClients[i]; + auto now = std::chrono::system_clock::now(); if (client->mHeartbeats) { - if (deltaTimestamp(now, client->mLastHeartbeat) > (unsigned int) mTimeout) + if(now - client->mLastHeartbeat >mTimeout) { gLogger->warning("Client has not sent heartbeat in over %d ms, disconnecting", mTimeout); @@ -314,37 +315,3 @@ Client *Server::addClient(Client *client) return client; } - - -unsigned int Server::getTimestamp() -{ -#ifdef WIN32 - return GetTickCount(); -#else - timeval curtime; - gettimeofday(&curtime, 0); - - unsigned long ts = (unsigned long) curtime.tv_sec; - // Allow to truncate - ts *= 1000; - ts += curtime.tv_usec / 1000; - - return ts; -#endif -} - - -unsigned int Server::deltaTimestamp(unsigned int a, unsigned int b) -{ - // Assume we are doing a - b where a should be larger, if it is not - // we have a wrap-around - unsigned int res; - - if (a >= b) - res = a - b; - else // b > a, Compute the distance from the end: - res = a + (0xFFFFFFFF - b); - - return res; -} - diff --git a/src/server.hpp b/src/server.hpp index 3061e86..28f20b9 100755 --- a/src/server.hpp +++ b/src/server.hpp @@ -33,6 +33,7 @@ #pragma once #include +#include class Client; @@ -47,7 +48,7 @@ class Server int mNumClients; int mPort; char mPong[32]; - int mTimeout; + std::chrono::milliseconds mTimeout; std::mutex mListLock; @@ -58,11 +59,9 @@ class Server // Locks the mutex. void removeClient(Client *client); Client *addClient(Client *client); - unsigned int getTimestamp(); - unsigned int deltaTimestamp(unsigned int, unsigned int); public: - Server(int aPort, int aHeartbeatFreq); + Server(int port, std::chrono::milliseconds heartbeatFreq); ~Server(); // Returns the new client. diff --git a/src/string_buffer.cpp b/src/string_buffer.cpp index 78c2dfa..12388f7 100755 --- a/src/string_buffer.cpp +++ b/src/string_buffer.cpp @@ -32,13 +32,18 @@ // #include "internal.hpp" #include "string_buffer.hpp" - +#ifdef min + #undef min +#endif +#ifdef max + #undef max +#endif +#include StringBuffer::StringBuffer(const char *string) : mBuffer(nullptr), mSize(0u), - mLength(0u), - mTimestamp{0} + mLength(0u) { if (string) append(string); @@ -60,7 +65,7 @@ const char *StringBuffer::append(const char *string) // Include additional length for timestamp auto len = strlen(string); auto totalLength = mLength + len; - auto tsLen = strlen(mTimestamp); + auto tsLen = mTimestamp.size(); if (!mLength) totalLength += tsLen; @@ -78,7 +83,7 @@ const char *StringBuffer::append(const char *string) if (!mLength && tsLen > 0) { - strcpy(mBuffer, mTimestamp); + strcpy(mBuffer, mTimestamp.c_str()); mLength += tsLen; } @@ -92,7 +97,7 @@ const char *StringBuffer::append(const char *string) void StringBuffer::newline() { append("\n"); - append(mTimestamp); + append(mTimestamp.c_str()); } @@ -108,30 +113,6 @@ void StringBuffer::reset() void StringBuffer::timestamp() { -#ifdef WIN32 - SYSTEMTIME st; - GetSystemTime(&st); - sprintf( - mTimestamp, - "%4d-%02d-%02dT%02d:%02d:%02d.%03dZ", - st.wYear, - st.wMonth, - st.wDay, - st.wHour, - st.wMinute, - st.wSecond, - st.wMilliseconds); -#else - struct timeval tv; - struct timezone tz; - - gettimeofday(&tv, &tz); - - strftime( - mTimestamp, - 64, - "%Y-%m-%dT%H:%M:%S", - gmtime(&tv.tv_sec)); - sprintf(mTimestamp + strlen(mTimestamp), ".%06dZ", tv.tv_usec); -#endif + mTimestamp = date::format("%FT%TZ", + std::chrono::time_point_cast(std::chrono::system_clock::now())); } diff --git a/src/string_buffer.hpp b/src/string_buffer.hpp index 9ac90a7..9b04966 100755 --- a/src/string_buffer.hpp +++ b/src/string_buffer.hpp @@ -31,6 +31,7 @@ // SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. // #pragma once +#include // // A simple extensible string that can be appended to. The memory will be reused @@ -45,7 +46,8 @@ class StringBuffer char *mBuffer; // A resizable character buffer size_t mSize; // The allocated size of the string size_t mLength; // The length of the string - char mTimestamp[64]; + std::string mTimestamp; + public: StringBuffer(const char *string = nullptr); @@ -59,7 +61,7 @@ class StringBuffer void reset(); void timestamp(); void setTimestamp(const char *timestamp) { - strcpy_s(mTimestamp, timestamp); } + mTimestamp = timestamp; } size_t length() const { return mLength; } void newline(); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6c93570..2c90f62 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -52,5 +52,6 @@ if(WIN32) ) endif() -AddMsvcXPSupport(fanuc) #This will only apply if an XP compatible toolset has been selected in CMake +AddMsvcXPSupport(test) #This will only apply if an XP compatible toolset has been selected in CMake AddCppUnitSupport(test) +AddDateSupport(test) From d68fa47a5c81945c26d37a744366fee327fd5c4a Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Mon, 30 Apr 2018 07:47:23 +0100 Subject: [PATCH 36/41] BUG FIX: Fixed cleanup of Windows sockets * Typo in pre-processor definition prevented cleanup of sockets on Windows machines --- src/server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server.cpp b/src/server.cpp index bf46f20..51a9798 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -105,7 +105,7 @@ Server::~Server() ::shutdown(mSocket, SHUT_RDWR); -#ifdef WINDOWS +#ifdef _WINDOWS WSACleanup(); #endif } From 648e531b1e93d81c7937a04796cae25b0a102e4b Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Thu, 25 Oct 2018 13:37:03 +0100 Subject: [PATCH 37/41] Update clone URL for CppUnit * Clone URL is no longer accessible through HTTP, must be HTTPS --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 2d1f1ae..f1398bb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "cppunit"] path = cppunit - url = http://anongit.freedesktop.org/git/libreoffice/cppunit + url = https://anongit.freedesktop.org/git/libreoffice/cppunit [submodule "date"] path = date url = https://github.com/HowardHinnant/date.git From d14a43c55fcc966e38f0a22b62bf4bda7063ee66 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Thu, 13 Jun 2019 14:17:14 +0100 Subject: [PATCH 38/41] Fix for Visual Studio 2019 --- yaml/src/scanner.cpp | 1 + yaml/src/tag.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/yaml/src/scanner.cpp b/yaml/src/scanner.cpp index 33052c2..b78bc2e 100644 --- a/yaml/src/scanner.cpp +++ b/yaml/src/scanner.cpp @@ -4,6 +4,7 @@ #include "exp.h" #include #include +#include namespace YAML { diff --git a/yaml/src/tag.cpp b/yaml/src/tag.cpp index 694a4f3..e62c23e 100644 --- a/yaml/src/tag.cpp +++ b/yaml/src/tag.cpp @@ -2,6 +2,7 @@ #include "token.h" #include "parserstate.h" #include +#include namespace YAML { From 369b9e05cae92ff13169dadb1cfa2d16c8c07ff6 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Wed, 14 Aug 2019 14:53:13 +0100 Subject: [PATCH 39/41] Fixes for Visual Studio 2019 --- yaml/src/stream.cpp | 2 +- yaml/src/token.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/yaml/src/stream.cpp b/yaml/src/stream.cpp index 0d1426a..570a50a 100644 --- a/yaml/src/stream.cpp +++ b/yaml/src/stream.cpp @@ -1,5 +1,5 @@ #include "stream.h" -#include +#include #include "exp.h" #ifndef YAML_PREFETCH_SIZE diff --git a/yaml/src/token.h b/yaml/src/token.h index cf7c0fe..f5f5e6a 100644 --- a/yaml/src/token.h +++ b/yaml/src/token.h @@ -5,6 +5,7 @@ #include "mark.h" +#include #include #include #include From 0f2405fbdbb9a06c40e3beae50ef742ae5ab214c Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Wed, 14 Aug 2019 14:54:21 +0100 Subject: [PATCH 40/41] Update to devices.xml for feedrate and spindle overrides --- fanuc/fanuc.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fanuc/fanuc.xml b/fanuc/fanuc.xml index 7b73fe6..b3a52ca 100644 --- a/fanuc/fanuc.xml +++ b/fanuc/fanuc.xml @@ -62,10 +62,11 @@ + + - From 9863ad2ac719ee6e01381dc31acff2c947bada46 Mon Sep 17 00:00:00 2001 From: Matt Powley Date: Tue, 12 Nov 2024 10:20:26 +0000 Subject: [PATCH 41/41] WIP --- fanuc/adapter.ini | 2 +- fanuc/fanuc.xml | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/fanuc/adapter.ini b/fanuc/adapter.ini index 94d74b8..3b22ae5 100644 --- a/fanuc/adapter.ini +++ b/fanuc/adapter.ini @@ -9,7 +9,7 @@ host = HSSB_9 Macro500=500 Macro501=501 Macro502=502 -MacroPos=[500 501 502] +#MacroPos=[500 501 502] [pmc] SspeedOvr = 30 diff --git a/fanuc/fanuc.xml b/fanuc/fanuc.xml index b3a52ca..24718da 100644 --- a/fanuc/fanuc.xml +++ b/fanuc/fanuc.xml @@ -7,10 +7,14 @@ - + + + + + @@ -63,10 +67,14 @@ - + + + + +