Commit a8acebb0 by Heitbrink, David A

Initial version of this lib

parents
## 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
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
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/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.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
*.appxbundle
*.appxupload
# 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/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- Backup*.rdl
# 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/
# CodeRush personal settings
.cr/personal
# 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
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
\ No newline at end of file
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
/* NADS_publisher.cxx
A publication of data of type TypeChar
This file is derived from code automatically generated by the rtiddsgen
command:
rtiddsgen -language C++11 -example <arch> NADS.idl
Example publication of type TypeChar automatically generated by
'rtiddsgen'. To test them follow these steps:
(1) Compile this file and the example subscription.
(2) Start the subscription on the same domain used for RTI Data Distribution
Service with the command
objs/<arch>/NADS_subscriber <domain_id> <sample_count>
(3) Start the publication on the same domain used for RTI Data Distribution
Service with the command
objs/<arch>/NADS_publisher <domain_id> <sample_count>
(4) [Optional] Specify the list of discovery initial peers and
multicast receive addresses via an environment variable or a file
(in the current working directory) called NDDS_DISCOVERY_PEERS.
You can run any number of publishers and subscribers programs, and can
add and remove them dynamically from the domain.
Example:
To run the example application on domain <domain_id>:
On Unix:
objs/<arch>/NADS_publisher <domain_id>
objs/<arch>/NADS_subscriber <domain_id>
On Windows:
objs\<arch>\NADS_publisher <domain_id>
objs\<arch>\NADS_subscriber <domain_id>
*/
#include <iostream>
#include <dds/pub/ddspub.hpp>
#include <rti/util/util.hpp> // for sleep()
#include "NADS.hpp"
void publisher_main(int domain_id, int sample_count)
{
// Create a DomainParticipant with default Qos
dds::domain::DomainParticipant participant (domain_id);
// Create a Topic -- and automatically register the type
dds::topic::Topic<TypeChar> topic (participant, "Example TypeChar");
// Create a DataWriter with default Qos (Publisher created in-line)
dds::pub::DataWriter<TypeChar> writer(dds::pub::Publisher(participant), topic);
TypeChar sample;
for (int count = 0; count < sample_count || sample_count == 0; count++) {
// Modify the data to be written here
std::cout << "Writing TypeChar, count " << count << std::endl;
writer.write(sample);
rti::util::sleep(dds::core::Duration(4));
}
}
int main(int argc, char *argv[])
{
int domain_id = 0;
int sample_count = 0; // infinite loop
if (argc >= 2) {
domain_id = atoi(argv[1]);
}
if (argc >= 3) {
sample_count = atoi(argv[2]);
}
// To turn on additional logging, include <rti/config/Logger.hpp> and
// uncomment the following line:
// rti::config::Logger::instance().verbosity(rti::config::Verbosity::STATUS_ALL);
try {
publisher_main(domain_id, sample_count);
} catch (const std::exception& ex) {
// This will catch DDS exceptions
std::cerr << "Exception in publisher_main(): " << ex.what() << std::endl;
return -1;
}
// RTI Connext provides a finalize_participant_factory() method
// if you want to release memory used by the participant factory singleton.
// Uncomment the following line to release the singleton:
//
// dds::domain::DomainParticipant::finalize_participant_factory();
return 0;
}
/* NADS_subscriber.cxx
A subscription example
This file is derived from code automatically generated by the rtiddsgen
command:
rtiddsgen -language C++11 -example <arch> NADS.idl
Example subscription of type TypeChar automatically generated by
'rtiddsgen'. To test them, follow these steps:
(1) Compile this file and the example publication.
(2) Start the subscription on the same domain used for RTI Data Distribution
Service with the command
objs/<arch>/NADS_subscriber <domain_id> <sample_count>
(3) Start the publication on the same domain used for RTI Data Distribution
Service with the command
objs/<arch>/NADS_publisher <domain_id> <sample_count>
(4) [Optional] Specify the list of discovery initial peers and
multicast receive addresses via an environment variable or a file
(in the current working directory) called NDDS_DISCOVERY_PEERS.
You can run any number of publishers and subscribers programs, and can
add and remove them dynamically from the domain.
Example:
To run the example application on domain <domain_id>:
On UNIX systems:
objs/<arch>/NADS_publisher <domain_id>
objs/<arch>/NADS_subscriber <domain_id>
On Windows systems:
objs\<arch>\NADS_publisher <domain_id>
objs\<arch>\NADS_subscriber <domain_id>
*/
#include <algorithm>
#include <iostream>
#include <dds/sub/ddssub.hpp>
#include <dds/core/ddscore.hpp>
// Or simply include <dds/dds.hpp>
#include "NADS.hpp"
int subscriber_main(int domain_id, int sample_count)
{
// Create a DomainParticipant with default Qos
dds::domain::DomainParticipant participant(domain_id);
// Create a Topic -- and automatically register the type
dds::topic::Topic<TypeChar> topic(participant, "Example TypeChar");
// Create a DataReader with default Qos (Subscriber created in-line)
dds::sub::DataReader<TypeChar> reader(dds::sub::Subscriber(participant), topic);
// Create a ReadCondition for any data on this reader and associate a handler
int count = 0;
dds::sub::cond::ReadCondition read_condition(
reader,
dds::sub::status::DataState::any(),
[&reader, &count]()
{
// Take all samples
dds::sub::LoanedSamples<TypeChar> samples = reader.take();
for (auto sample : samples){
if (sample.info().valid()){
count++;
std::cout << sample.data() << std::endl;
}
}
} // The LoanedSamples destructor returns the loan
);
// Create a WaitSet and attach the ReadCondition
dds::core::cond::WaitSet waitset;
waitset += read_condition;
while (count < sample_count || sample_count == 0) {
// Dispatch will call the handlers associated to the WaitSet conditions
// when they activate
std::cout << "TypeChar subscriber sleeping for 4 sec..." << std::endl;
waitset.dispatch(dds::core::Duration(4)); // Wait up to 4s each time
}
return 1;
}
int main(int argc, char *argv[])
{
int domain_id = 0;
int sample_count = 0; // infinite loop
if (argc >= 2) {
domain_id = atoi(argv[1]);
}
if (argc >= 3) {
sample_count = atoi(argv[2]);
}
// To turn on additional logging, include <rti/config/Logger.hpp> and
// uncomment the following line:
// rti::config::Logger::instance().verbosity(rti::config::Verbosity::STATUS_ALL);
try {
subscriber_main(domain_id, sample_count);
} catch (const std::exception& ex) {
// This will catch DDS exceptions
std::cerr << "Exception in subscriber_main(): " << ex.what() << std::endl;
return -1;
}
// RTI Connext provides a finalize_participant_factory() method
// if you want to release memory used by the participant factory singleton.
// Uncomment the following line to release the singleton:
//
// dds::domain::DomainParticipant::finalize_participant_factory();
return 0;
}
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{FCE83303-FBAE-4E08-B252-A7A7EFFF60F6}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>NadsDDSLib</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)lib\</OutDir>
<TargetName>$(ProjectName)_64ds</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)lib</OutDir>
<TargetName>$(ProjectName)_32ds</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)lib</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)lib</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>RTI_WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>.\;.\src;.\include;$(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>RTI_WIN32;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>.\;.\src;.\include;$(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>RTI_WIN32;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>.\;.\src;.\include;$(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>RTI_WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>.\;.\src;.\include;$(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="apex_memmove.h" />
<ClInclude Include="include\NadsDDSLib\NadsDDSLib.h" />
<ClInclude Include="NADS.hpp" />
<ClInclude Include="NADSPlugin.hpp" />
<ClInclude Include="src\GenericSubscriber.h" />
<ClInclude Include="src\nadsddsimpl.h" />
<ClInclude Include="src\value_as_string.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="apex_memmove.cpp" />
<ClCompile Include="NADS.cxx" />
<ClCompile Include="NADSPlugin.cxx" />
<ClCompile Include="NADS_publisher.cxx" />
<ClCompile Include="NADS_subscriber.cxx" />
<ClCompile Include="src\GenericSubscriber.cpp" />
<ClCompile Include="src\nadsddsimpl.cpp" />
<ClCompile Include="src\nadsddslib.cpp" />
<ClCompile Include="src\value_as_string.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\NadsDDSLib\NadsDDSLib.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\nadsddsimpl.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="apex_memmove.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="NADS.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="NADSPlugin.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\GenericSubscriber.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\value_as_string.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\nadsddsimpl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="apex_memmove.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NADS_publisher.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NADS_subscriber.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NADSPlugin.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\nadsddslib.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NADS.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\GenericSubscriber.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\value_as_string.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
\ No newline at end of file
This diff is collapsed. Click to expand it.
#ifndef __APEX_MEMMOVE_H__
#define __APEX_MEMMOVE_H__
// apex_memmove written by Trevor Herselman in 2014
// FORCE `CDECL` calling convention on 32-bit builds on our function pointers, because we need it to match the original `std::memmove` definition; in-case the user specified a different default function calling convention! (I specified __fastcall as my default calling convention and got errors! So I needed to add this!)
#if !defined(__x86_64__) && !defined(_M_X64) && (defined(__i386) || defined(_M_IX86)) && (defined(_MSC_VER) || defined(__GNUC__))
#if defined(_MSC_VER)
#define APEXCALL __cdecl // 32-bit on Visual Studio
#else
#define APEXCALL __attribute__((__cdecl__)) // 32-bit on GCC / LLVM (Clang)
#endif
#else
#define APEXCALL // 64-bit - __fastcall is default on 64-bit!
#endif
#ifdef __cplusplus
#include <cstddef> // for `size_t`
namespace apex
{
extern void *(APEXCALL *memcpy)( void *dst, const void *src, size_t size );
extern void *(APEXCALL *memmove)( void *dst, const void *src, size_t size );
}
#define apex_memcpy apex::memcpy
#define apex_memmove apex::memmove
#else
#include <stddef.h> // ANSI/ISO C - for `size_t`
extern void *(APEXCALL *apex_memcpy)( void *dst, const void *src, size_t size );
extern void *(APEXCALL *apex_memmove)( void *dst, const void *src, size_t size );
#endif // __cplusplus
#endif // __APEX_MEMMOVE_H__
\ No newline at end of file
#pragma once
#include<string>
#include<memory>
#include<map>
#include<vector>
//////////////////////////////////////////////////////////////////////////////////////////////////
///
///
///
///
///
///
///
///
///
///
///
namespace NADSDDS {
using namespace std;
class CellRoot;
class CFloatPub;
class CCharPub;
class CDoublePub;
class CIntPub;
class CShortPub;
typedef unique_ptr< CellRoot> TPubPtr;
typedef unique_ptr< CFloatPub> TFloatPubPtr ;
typedef unique_ptr< CCharPub> TCharPubPtr;
typedef unique_ptr< CDoublePub> TDoublePubPtr;
typedef unique_ptr< CIntPub> TIntPubPtr;
typedef unique_ptr< CShortPub> TShortPubPtr;
class CellRoot {
public:
CellRoot(int id) :_eid(id), _itemCount(0), _period(-1) {
}
virtual void* Raw() = 0;
virtual void Send() = 0;
virtual int& eid() = 0;
int _eid;
std::string _name;
size_t _itemCount;
size_t _sizeInBytes;
int _period;
};
class CellInRoot {
public:
CellInRoot(const std::string& name) :_name(name),_eid(-1), _itemCount(0), _period(-1) {
}
virtual void* Raw() = 0;
virtual int eid() = 0;
int _eid;
std::string _name;
size_t _itemCount;
size_t _sizeInBytes;
int _period;
};
template<class T> class BufferedCellRoot: public CellInRoot {
public:
BufferedCellRoot(std::string name) : CellInRoot(name) {}
vector<T>& operator()() {
return _buffer;
}
virtual bool Swap() = 0;
vector<T>& GetBuff() { return _buffer; }
virtual void* Raw() { return _buffer.data(); }
protected:
vector<T> _buffer;
};
class CSubscription {
public:
typedef unique_ptr<CSubscription> TRef;
TRef MakeSubscription(const std::string&, int EID, size_t count, char cellType);
virtual const char* asChar() { return nullptr; };
virtual const double* asDouble() { return nullptr; };
virtual const float* asFloat() { return nullptr; };
virtual const int* asInt() { return nullptr; };
virtual const short* asShort() { return nullptr; };
virtual void SwapBuffer() = 0;
protected:
virtual CellInRoot* GetCell() = 0;
};
class CFloatSubscription : public CSubscription {
public:
typedef unique_ptr<BufferedCellRoot<float>> TSubref;
CFloatSubscription(TSubref&& sub) :_subsription(std::move(sub)) {};
virtual const float* asFloat() override { return _subsription->GetBuff().data(); };
std::vector<float>& operator()() { return _subsription->GetBuff(); };
virtual void SwapBuffer() override { _subsription->Swap(); };
protected:
virtual CellInRoot* GetCell() override { return _subsription.get(); };
private:
TSubref _subsription;
};
//class CDoubleSubscrition : public CSubscription {
//public:
// CDoubleSubscrition();
// std::vector<double>& operator()() { return _val->GetBuff(); };;
//private:
// unique_ptr<BufferedCellRoot<double>> _val;
//};
//class CIntSubscription : public CSubscription {
//public:
// CIntSubscription();
// std::vector<int>& operator()() { return _val->GetBuff(); };
//private:
// unique_ptr<BufferedCellRoot<int>> _val;
//};
//class CCharSubscription : public CSubscription {
//public:
// CCharSubscription();
// std::vector<char>& operator()() { return _val->GetBuff(); };
//private:
// unique_ptr<BufferedCellRoot<char>> _val;
//};
//class CShortSubscription : public CSubscription {
//public:
// CShortSubscription();
// std::vector<short>& operator()() { return _val->GetBuff(); };
//private:
// unique_ptr<BufferedCellRoot<short>> _val;
//};
class CPublication{
public:
typedef unique_ptr<CPublication> TRef;
TRef MakePublication(const std::string&, int EID, size_t count, char cellType);
virtual char* asChar();
virtual double* asDouble();
virtual float* asFloat();
virtual int* asInt();
virtual short* asShort();
void* Raw();
const std::string& Name();
int EID();
size_t SizeInBytes();
size_t Count();
void Publish();
protected:
virtual CellRoot* GetPub() = 0;
CPublication() {};
};
class DoublePublication :public CPublication {
public:
DoublePublication(TDoublePubPtr&&);
virtual double* asDouble()override;
DoublePublication& operator= (double);
double& operator[] (size_t);
private:
virtual CellRoot* GetPub() override;
TDoublePubPtr _ref;
};
class FloatPublication :public CPublication {
public:
FloatPublication(TFloatPubPtr&&);
virtual float* asFloat() override;
FloatPublication& operator= (float);
float& operator[] (size_t);
private:
virtual CellRoot* GetPub() override;
TFloatPubPtr _ref;
};
class ShortPublication :public CPublication {
public:
ShortPublication(TShortPubPtr&&);
virtual short* asShort() override;
ShortPublication& operator= (short);
short& operator[] (size_t);
private:
virtual CellRoot* GetPub() override;
TShortPubPtr _ref;
};
class IntPublication :public CPublication {
public:
IntPublication(TIntPubPtr&&);
virtual int* asInt() override;
IntPublication& operator= (int);
int& operator[] (size_t);
private:
virtual CellRoot* GetPub() override;
TIntPubPtr _ref;
};
class CharPublication :public CPublication {
public:
CharPublication(TCharPubPtr&&);
virtual char* asChar() override;
CharPublication& operator= (const std::string&);
char& operator[] (size_t);
private:
virtual CellRoot* GetPub() override;
TCharPubPtr _ref;
};
}
\ No newline at end of file
/*
/ (c) Copyright 2018, Real-Time Innovations, All rights reserved. /
/ /
/ RTI grants Licensee a license to use, modify, compile, and create /
/ derivative works of the software solely for use with RTI Connext DDS. /
/ Licensee may redistribute copies of the software provided that all such /
/ copies are subject to this license. The software is provided "as is", with /
/ no warranty of any type, including any warranty for fitness for any purpose. /
/ RTI is under no obligation to maintain or support the software. RTI shall /
/ not be liable for any incidental or consequential damages arising out of the /
/ use or inability to use the software. /
*/
#include "GenericSubscriber.h"
#include "value_as_string.h"
#include <dds/topic/BuiltinTopic.hpp>
#include <optional>
#include <rti/config/Version.hpp>
#include <rti/core/ListenerBinder.hpp>
#include <rti/topic/PrintFormat.hpp>
#include <rti/topic/rtitopic.hpp>
using namespace dds::core;
using namespace dds::core::status;
using namespace dds::domain;
using namespace dds::topic;
using namespace dds::sub;
using namespace dds::pub;
using kind = xtypes::TypeKind_def;
namespace NADSDDS {
/**
* @brief GenericSubscriber class. Can be instantiated with only a participant or
* with a participant and a type. If instantiated without a type then DDS pro is
* assumed and the type will be discovered.
*
*/
class GenericSubscriber::GenericSubscriberImpl : public NoOpDataReaderListener<xtypes::DynamicData>
{
private:
using GenericTopic = Topic<xtypes::DynamicData>;
using GenericReader = DataReader<xtypes::DynamicData>;
using TopicName = std::string;
using TopicType = optional<xtypes::DynamicType>;
using TopicAndType = std::tuple<TopicName, TopicType>;
using TopicAndTypeList = std::vector<TopicAndType>;
using TopicColumnName = std::string;
using TopicColumnType = xtypes::DynamicType;
using TopicColumnKey = bool;
using TopicColumnOptional = bool;
using TopicColumn = std::tuple<TopicColumnName, TopicColumnType, TopicColumnKey, TopicColumnOptional>;
using TopicColumnList = std::vector<TopicColumn>;
GenericSubscriberImpl(const GenericSubscriberImpl&) = delete; // non construction-copyable
GenericSubscriberImpl& operator=(const GenericSubscriberImpl&) = delete; // non copyable
// class used to gather topics from default publisher
class MyReaderListener : public NoOpDataReaderListener<PublicationBuiltinTopicData> {
public:
explicit MyReaderListener(TopicAndTypeList& topics) :m_topics(topics)
{
}
// incoming data on the builtin topic reader
void on_data_available(DataReader<PublicationBuiltinTopicData>& rdr) override
{
LoanedSamples<PublicationBuiltinTopicData> samples = rdr.take();
for (auto& sample : samples) {
if (sample.info().valid()) {
m_topics.emplace_back(sample.data().topic_name(), sample.data()->type());
}
}
}
private:
TopicAndTypeList & m_topics;
};
// wait until the list of topics has been populated
void wait_for_discovery() const
{
while (m_discovered_topics.empty()) {
rti::util::sleep(Duration::from_secs(poll_seconds));
}
}
template<typename Funct>
void process_members(const xtypes::StructType& record, Funct func) const
{
for (auto& member : record.members()) {
func(member);
}
}
// get all of the columns (i.e. members) of the topic type
void get_topic_columns(const TopicType& topic_type)
{
if (!m_columns.empty()) {
return;
}
auto& record = static_cast<const xtypes::StructType&>(topic_type.get());
if (xtypes::is_extensible(record) && record.has_parent()) {
// get the base members since this is an extensible type
process_members(record.parent(),
[this](const xtypes::Member& member) {
m_columns.emplace_back(member.name(), member.type(),
member.is_key(), member.is_optional());
});
}
process_members(record,
[this](const xtypes::Member& member) {
m_columns.emplace_back(member.name(), member.type(),
member.is_key(), member.is_optional());
});
}
std::string padding(size_t size, const char c)
{
return std::string(size, c);
}
// incoming data from the topic we subscribed to
void on_data_available(DataReader<xtypes::DynamicData>& rdr) override
{
LoanedSamples<xtypes::DynamicData> samples = rdr.take();
for (auto& sample : samples) {
if (sample.info().valid()) {
for (auto& column : m_columns) {
int column_width = (std::get<1>(column).kind() == kind::SEQUENCE_TYPE ||
std::get<1>(column).kind() == kind::AGGREGATION_TYPE ||
std::get<1>(column).kind() == kind::STRUCTURE_TYPE) ? data_row_agg_width :
data_row_sim_width;
std::cout << padding(column_width - data_row_width_off, ' ')
<< std::setw(column_width)
<< value_as_string(sample.data(), std::get<0>(column));
}
std::cout << std::endl;
}
}
}
// print out header based on discovered topic type members
void header(const TopicType& topic_type)
{
get_topic_columns(topic_type);
std::cout << " ";
for (auto& column : m_columns) {
int column_width = (std::get<1>(column).kind() == kind::SEQUENCE_TYPE ||
std::get<1>(column).kind() == kind::AGGREGATION_TYPE ||
std::get<1>(column).kind() == kind::STRUCTURE_TYPE) ? hdr_row_agg_width :
hdr_row_sim_width;
std::cout << std::setw(column_width)
<< std::get<0>(column)
<< padding(column_width - hdr_row_width_off, ' ') << "|";
}
std::cout << std::endl;
}
public:
GenericSubscriberImpl(DomainParticipant& participant, bool verbose) : m_participant(participant),
m_ear(m_discovered_topics),
m_verbose(verbose)
{
std::vector<DataReader<PublicationBuiltinTopicData>> rdr_list;
// locate the built-in subscriber for the topic names
find<DataReader<PublicationBuiltinTopicData>>(builtin_subscriber(m_participant),
dds::topic::publication_topic_name(),
std::back_inserter(rdr_list));
// attach listener to all readers
for (auto& rdr : rdr_list) {
rdr.listener(&m_ear.value(), StatusMask::data_available());
}
// only now that we have our listeners attached are we ready to enable the participant
m_participant.enable();
}
GenericSubscriberImpl(DomainParticipant& participant,
const xtypes::StructType& topic_type,
bool verbose) : m_topic_type(topic_type),
m_participant(participant),
m_verbose(verbose)
{
m_participant.enable();
}
void list_topics(TTopics & in)
{
wait_for_discovery();
std::cout << "Number of topics discovered: " << m_discovered_topics.size() << std::endl;
for (auto topic : m_discovered_topics) {
if (std::get<1>(topic)) {
in.push_back(TNameTypePair(
std::get<0>(topic),
std::get<1>(topic).get().name()));
}
else {
in.push_back(TNameTypePair(
std::get<0>(topic),
string("unkown")));
}
}
}
void receive(const TopicName& topic_name)
{
TopicType topic_type;
if (m_ear) {
wait_for_discovery();
for (auto topic : m_discovered_topics) {
if (std::get<0>(topic) == topic_name) {
if ((topic_type = std::get<1>(topic))) {
std::cout << "Enabling subscribing on topic " << topic_name
<< " which is of type " << topic_type.get().name() << std::endl;
break; // only support subscribing to a single topic
}
}
}
if (!topic_type) {
throw TopicNotFound(topic_name);
}
}
else {
topic_type = m_topic_type;
}
GenericReader reader(Subscriber(m_participant),
GenericTopic(m_participant, topic_name, topic_type.get()));
if (reader.is_nil()) {
throw ReaderNotCreated();
}
auto scoped_listener = rti::core::bind_listener(reader, this,
dds::core::status::StatusMask::data_available());
// display headers
header(topic_type);
// while there are writers available collect and display data
while (true) {
rti::util::sleep(Duration::from_secs(poll_seconds));
}
}
private:
TopicAndTypeList m_discovered_topics;
TopicType m_topic_type;
DomainParticipant& m_participant;
std::optional<MyReaderListener> m_ear = std::nullopt;
bool m_verbose;
TopicColumnList m_columns;
static const int poll_seconds = 1;
static const uint8_t data_row_agg_width = 33;
static const uint8_t data_row_sim_width = 16;
static const uint8_t hdr_row_agg_width = 30;
static const uint8_t hdr_row_sim_width = 15;
static const uint8_t data_row_width_off = 14;
static const uint8_t hdr_row_width_off = 8;
};
GenericSubscriber::GenericSubscriber(DomainParticipant& participant, bool verbose)
: impl(std::make_unique<GenericSubscriberImpl>(participant, verbose))
{
}
GenericSubscriber::GenericSubscriber(DomainParticipant& participant, const xtypes::StructType& topic_type,
bool verbose)
: impl(std::make_unique<GenericSubscriberImpl>(participant, topic_type, verbose))
{
}
GenericSubscriber::~GenericSubscriber() = default;
void GenericSubscriber::list_topics(TTopics& in)
{
impl->list_topics(in);
}
void GenericSubscriber::receive(const std::string& topic_name)
{
impl->receive(topic_name);
}
}
\ No newline at end of file
/********************************************************************************/
/* (c) Copyright 2018, Real-Time Innovations, All rights reserved. */
/* */
/* RTI grants Licensee a license to use, modify, compile, and create */
/* derivative works of the software solely for use with RTI Connext DDS. */
/* Licensee may redistribute copies of the software provided that all such */
/* copies are subject to this license. The software is provided "as is", with */
/* no warranty of any type, including any warranty for fitness for any purpose. */
/* RTI is under no obligation to maintain or support the software. RTI shall */
/* not be liable for any incidental or consequential damages arising out of the */
/* use or inability to use the software. */
/********************************************************************************/
#ifndef __GENERIC_SUBSCRIBER__
#define __GENERIC_SUBSCRIBER__
#include <dds/dds.hpp>
#include <string>
namespace NADSDDS {
/**
* A GenericSubscriber requires the factory to be configured to
* create entities in a disabled state prior to instantiation.
* It will not function otherwise.
*/
class GenericSubscriber {
public:
/**
* @brief Exception thrown when client supplied topic name can not be found in domain
*
*/
class TopicNotFound : std::exception
{
public:
/**
* @brief Construct a new Topic Not Found object
*
* @param topic_name name of the topic that was not found
*/
TopicNotFound(const std::string& topic_name) : m_topic_name(topic_name)
{
}
/**
* @brief Retrieve a const char* pointing to the name of the topic that was not found
*
* @return const char*
*/
const char* what(void) const noexcept override
{
return m_topic_name.c_str();
}
private:
std::string m_topic_name;
};
/**
* @brief Exception thrown when a reader cannot be created for the specified topic
*
*/
class ReaderNotCreated : std::exception
{
public:
/**
* @brief Construct a new Reader Not Created object
*
*/
ReaderNotCreated()
{
}
};
/**
* @brief Construct a new Generic Subscriber Impl object
*
* @param participant participant under which the subscriber will be created
* @param verbose enable verbose logging
*/
GenericSubscriber(dds::domain::DomainParticipant& participant,
bool verbose);
/**
* @brief Construct a new Generic Subscriber Impl object
*
* @param participant participant under which the subscriber will be created
* @param topic_type datatype (for the topic name which will be supplied to receive)
* @param verbose enable verbose logging
*/
GenericSubscriber(dds::domain::DomainParticipant& participant,
const dds::core::xtypes::StructType& topic_type,
bool verbose);
/**
* Subscriber destructor
*/
~GenericSubscriber();
/**
* @brief list topics available in participants domain
*
*
*/
typedef std::pair<std::string, std::string> TNameTypePair;
typedef std::vector<TNameTypePair> TTopics;
void list_topics(TTopics&);
/**
* @brief begin receiving data
*
* @param topic_name topic on which to receive data
*/
void receive(const std::string& topic_name);
private:
class GenericSubscriberImpl;
std::unique_ptr<GenericSubscriberImpl> impl{};
};
}
#endif
\ No newline at end of file
#include "stdafx.h"
#include "nadsddsimpl.h"
using namespace std;
namespace NADSDDS {
DDSDomainRepo::TRef DDSDomainRepo::DDSDomainRepo::_self;
dds::domain::DomainParticipant&
DDSDomainRepo::GetDomain(int id) {
if (!_self) {
auto ptr = new DDSDomainRepo();
_self = TRef(ptr);
}
auto itr = _self->_DomainRefs.find(id);
if (itr == _self->_DomainRefs.end())
{
_self->_DomainRefs[id] = make_unique<dds::domain::DomainParticipant>(id);
return *(_self->_DomainRefs[id]);
}
return *(itr->second);
}
DDSDomainRepo::DDSDomainRepo() {
};
DDSTopicInfo::TRef DDSTopicInfo::_self;
DDSTopicInfo* DDSTopicInfo::Get() {
if (!_self) {
auto ptr = new DDSTopicInfo();
_self = TRef(ptr);
}
return _self.get();
}
void DDSTopicInfo::Refresh() {
DDSTopicInfo::Get()->RefreshImpl();
}
void DDSTopicInfo::RefreshImpl() {
dds::domain::qos::DomainParticipantQos participant_qos = dds::core::QosProvider::Default().participant_qos();
dds::domain::qos::DomainParticipantFactoryQos qos;
qos << dds::core::policy::EntityFactory::ManuallyEnable();
dds::domain::DomainParticipant::participant_factory_qos(qos);
//DomainParticipant participant(0, participant_qos);
//DDSDomainRepo::GetDomain(0)
GenericSubscriber subscriber(DDSDomainRepo::GetDomain(0), false);
//GenericSubscriber subscriber(participant, false);
GenericSubscriber::TTopics topics;
subscriber.list_topics(topics);
_info.clear();
for (auto& itr : topics) {
if (itr.second == "TypeInt") {
_info.push_back(std::make_tuple(itr.first,'i'));
}
if (itr.second == "TypeChar") {
_info.push_back(std::make_tuple(itr.first, 'c'));
}
if (itr.second == "TypeFloat") {
_info.push_back(std::make_tuple(itr.first, 'f'));
}
if (itr.second == "TypeShort") {
_info.push_back(std::make_tuple(itr.first, 's'));
}
if (itr.second == "TypeDouble") {
_info.push_back(std::make_tuple(itr.first, 'd'));
}
}
}
const DDSTopicInfo::TTypeVect& DDSTopicInfo::GetTopics() {
return DDSTopicInfo::Get()->_info;
}
DDSTopicInfo::DDSTopicInfo() {}
std::unique_ptr<CStatePriv> CStatePriv::_Ref;
CStatePriv & CStatePriv::Get() {
if (!_Ref) {
_Ref = std::make_unique<CStatePriv>();
}
return *_Ref.get();
}
void CStatePriv::Register(CStatePriv::TCBRef reg) {
_Cbs.push_back(reg);
}
void CStatePriv::Frame(int frameNum) {
for (auto cb : _Cbs) {
auto sp = cb.lock();
if (sp) {
sp->OnFrame(frameNum);
}
}
RemovedExpired<TCBVec, TCBWRef>(_Cbs);
}
int CStatePriv::GetFrame() {
return _frame;
}
int CStatePriv::GetState() {
_StateSub->Swap();
auto& buff = _StateSub->GetBuff();
if (buff.size() > 0)
return buff[0];
return -1;
}
CStatePriv::CStatePriv() {
_newFrameCb = make_shared<CStatePriv::OnNewFrame>(this);
_FrameSub = std::make_unique<DataStream<TypeInt>>("Frame", &DDSDomainRepo::GetDomain(0), _newFrameCb);
_StateSub = std::make_unique<TIntSubscription>("StateMode");
_StateSub->Register();
}
}
\ No newline at end of file
#pragma once
#ifndef NO_AUTOLINK_NADS_DDS_LIB
#define NO_AUTOLINK_NADS_DDS_LIB
#endif
#include <memory>
#include <string>
#include <dds/sub/ddssub.hpp>
#include <dds/core/ddscore.hpp>
#include <dds/dds.hpp>
#include <dds/pub/ddspub.hpp>
#include <rti/sub/SampleIterator.hpp>
#include <rti/util/util.hpp> // for sleep()
#include "NADS.hpp"
#include "ndds\dds_cpp\dds_cpp_domain.h"
#include "NadsDDSLib\NadsDDSLib.h"
#include "GenericSubscriber.h"
#include <thread>
#include <mutex>
namespace NADSDDS {
using namespace std;
using namespace dds::all;
template<class T> class CellPub : public CellRoot {
public:
CellPub(std::string name, dds::domain::DomainParticipant& dm, size_t size, int id) :
CellRoot(id), topic(dm, name)
{
writer = make_unique<dds::pub::DataWriter<T>>(dds::pub::Publisher(dm), topic);
data.data().resize(size);
data.eid() = _eid;
_itemCount = size;
_sizeInBytes = size * sizeof(T);
}
virtual void Send() override {
auto ptr = writer.get();
ptr->write(data);
}
virtual void* Raw() override {
return (void*)data.data().data();
}
virtual int& eid() override {
return data.eid();
}
unique_ptr< dds::pub::DataWriter<T> > writer;
dds::topic::Topic<T> topic;
T data;
};
//<singleton for holding domain participants
class DDSDomainRepo {
public:
static dds::domain::DomainParticipant& GetDomain(int id);
private:
typedef unique_ptr<DDSDomainRepo> TRef;
typedef unique_ptr<dds::domain::DomainParticipant> TDomainRef;
std::map<int, TDomainRef> _DomainRefs;
static TRef _self;
DDSDomainRepo();
};
class DDSTopicInfo {
public:
typedef std::tuple<std::string, char> TTypeInfo;
typedef std::vector<TTypeInfo> TTypeVect;
static void Refresh();
static const TTypeVect& GetTopics();
private:
DDSTopicInfo();
void RefreshImpl();
static DDSTopicInfo* Get();
TTypeVect _info;
typedef unique_ptr<DDSTopicInfo> TRef;
static TRef _self;
};
//class CFloatPub : public CellPub<TypeFloat> {};
class CFloatPub {
public:
typedef unique_ptr<CellPub<TypeFloat>> TRef;
CFloatPub(TRef &&in) :_ref(std::move(in)) {};
CFloatPub(CFloatPub &&in) :_ref(std::move(in._ref)) {}
TRef _ref;
CellPub<TypeFloat>* get() { return _ref.get(); }
CellPub<TypeFloat>* operator->() { return _ref.get(); }
};
class CDoublePub {
public:
typedef unique_ptr<CellPub<TypeDouble>> TRef;
CDoublePub(TRef &&in) :_ref(std::move(in)) {};
CDoublePub(CDoublePub &&in) :_ref(std::move(in._ref)) {}
TRef _ref;
CellPub<TypeDouble>* get() { return _ref.get(); }
CellPub<TypeDouble>* operator->() { return _ref.get(); }
};
class CCharPub {
public:
typedef unique_ptr<CellPub<TypeChar>> TRef;
CCharPub(TRef &&in) :_ref(std::move(in)) {};
CCharPub(CCharPub &&in) :_ref(std::move(in._ref)) {}
TRef _ref;
CellPub<TypeChar>* get() { return _ref.get(); }
CellPub<TypeChar>* operator->() { return _ref.get(); }
CellPub<TypeChar>& operator*() const { return *_ref.get(); }
CellPub<TypeChar>* operator()() { return _ref.get(); }
};
class CIntPub {
public:
typedef unique_ptr<CellPub<TypeInt>> TRef;
CIntPub(TRef &&in):_ref(std::move(in)) {};
CIntPub(CIntPub &&in ):_ref(std::move(in._ref)){}
TRef _ref;
CellPub<TypeInt>* get() { return _ref.get(); }
CellPub<TypeInt>* operator->() { return _ref.get(); }
};
class CShortPub {
public:
typedef unique_ptr<CellPub<TypeShort>> TRef;
CShortPub(TRef &&in) :_ref(std::move(in)) {};
CShortPub(CShortPub &&in) :_ref(std::move(in._ref)) {}
operator CellPub<TypeShort>* () { return _ref.get(); }
CellPub<TypeShort>* operator()() { return _ref.get(); }
TRef _ref;
CellPub<TypeShort>* get() { return _ref.get(); }
CellPub<TypeShort>* operator->() { return _ref.get(); }
};
template < class T> class OnNewData {
public:
OnNewData() {};
virtual void NewData(const T&) = 0;
};
typedef std::shared_ptr<OnNewData<TypeInt>> TIntCB;
typedef std::shared_ptr<OnNewData<TypeChar>> TCharCB;
typedef std::shared_ptr<OnNewData<TypeShort>> TShortCB;
typedef std::shared_ptr<OnNewData<TypeFloat>> TFloatCB;
typedef std::shared_ptr<OnNewData<TypeDouble>> TDoubleCB;
template < class T> class DataListener : public dds::sub::NoOpDataReaderListener<T> {
public:
typedef std::shared_ptr<OnNewData<T>> TCbRef;
DataListener(TCbRef ref) :_cb(ref) {};
void on_data_available(dds::sub::DataReader<T>& reader) {
dds::sub::LoanedSamples<T> samples = reader.take();
rti::sub::SampleIterator<T> it;// = dds::sub::LoanedSamples<T>::iterator
for (rti::sub::SampleIterator<T> sample_it = samples.begin(); sample_it != samples.end(); sample_it++) {
if (sample_it->info().valid()) {
_sample = sample_it->data();
_hasData = true;
}
}
if (_cb)
_cb->NewData(_sample);
}
bool HasData() { return _hasData; }
const T& GetCurrVal() { return _sample; }
private:
T _sample;
bool _hasData;
TCbRef _cb;
};
class StreamBase {
public:
StreamBase(dds::domain::DomainParticipant* dom, const std::string& topicName) :_dom(dom), _topicName(topicName) {};
protected:
dds::domain::DomainParticipant* _dom;
std::string _topicName;
};
template <class T> class DataStream : public StreamBase {
public:
typedef std::shared_ptr<OnNewData<T>> TCbRef;
DataStream(const std::string &topicName, dds::domain::DomainParticipant* dom, TCbRef ref) :StreamBase(dom, topicName), _listener(ref)
{
_topic = new dds::topic::Topic<T>(*_dom, topicName);
_reader = new dds::sub::DataReader<T>(
dds::sub::Subscriber(*_dom),
*_topic,
dds::core::QosProvider::Default().datareader_qos(),
&_listener,
dds::core::status::StatusMask::data_available());
}
~DataStream() {};
private:
std::string _subject;
dds::sub::DataReader<T>* _reader;
dds::topic::Topic<T>* _topic;
DataListener<T> _listener;
};
//BufferedCellRoot: public CellRoot{
// public:
// BufferedCellRoot(int id) : CellRoot(id) {}
template <class T, class Y> class CellSubsScription : public BufferedCellRoot<T>{
public:
class CB : public OnNewData<Y> {
public:
CB():OnNewData<Y>(),_hasNewData(false){}
virtual void NewData(const Y& valIn) override {
lock_guard<std::mutex> lock(_mutex);
_buffer = valIn;
_hasNewData = true;
}
void GetData(std::vector<T>& valIn) {
lock_guard<std::mutex> lock(_mutex);
size_t bufferSize = _buffer.data().size();
if (valIn.size() != bufferSize){
valIn.resize(bufferSize);
}
for (size_t i = 0; i < bufferSize; i++) {
valIn[i] = _buffer.data()[i];
}
_hasNewData = false;
}
bool HasNewData() {
return _hasNewData;
}
std::string _name;
protected:
volatile bool _hasNewData;
std::mutex _mutex;
Y _buffer;
};
typedef
CellSubsScription(const std::string& name) :BufferedCellRoot<T>(name) {}
void Register(){
_cb = make_shared<CB>();
_cb->_name = BufferedCellRoot<T>::_name;
_dataStream = make_unique<DataStream<Y>>(BufferedCellRoot<T>::_name, &DDSDomainRepo::GetDomain(0), _cb);
}
virtual bool Swap() override {
if (_cb && _cb->HasNewData()) {
_cb->GetData(BufferedCellRoot<T>::_buffer);
BufferedCellRoot<T>::_sizeInBytes = sizeof(T) * BufferedCellRoot<T>::_buffer.size();
return true;
}
return false;
}
virtual int eid() override {
return _streamBuffer.eid();
}
protected:
Y _streamBuffer;
unique_ptr<DataStream<Y>> _dataStream;
shared_ptr<CB> _cb;
};
typedef CellSubsScription<float, TypeFloat> TFloatSubscription;
typedef CellSubsScription<double,TypeDouble> TDoubleSubscription;
typedef CellSubsScription<int, TypeInt> TIntSubscription;
typedef CellSubsScription<short, TypeShort> TShortSubscription;
typedef CellSubsScription<char, TypeChar> TCharSubscription;
typedef std::unique_ptr<TFloatSubscription> TFloatSubscriptionRef;
typedef std::unique_ptr<TDoubleSubscription>TDoubleSubscriptionRef;
typedef std::unique_ptr<TIntSubscription> TIntSubscriptionRef;
typedef std::unique_ptr<TShortSubscription> TShortSubscriptionRef;
typedef std::unique_ptr<TCharSubscription> TCharSubscriptionRef;
/////////////////////////////////////////////////////////
///\brief
/// remove expired weak pointers from vector
///\remark
/// use:
/// typedef weak_ptr<MyClass> TWeak
/// typedef vector<TWeak> TVecs;
/// TVecs vector;
/// RemovedExpired<TVecs,TWeak>(vector);
////////////////////////////////////////////////////////
template<class TVec, class TWp>
void RemovedExpired(TVec &vec) {
vec.erase(
std::remove_if(
vec.begin(),
vec.end(),
[](TWp cb) {return cb.expired(); }),
vec.end());
}
class CStatePriv {
public:
static CStatePriv & Get();
class Callback {
public:
Callback() {};
virtual void OnFrame(int num) = 0;
};
typedef std::shared_ptr<Callback> TCBRef;
typedef std::weak_ptr<Callback> TCBWRef;
CStatePriv();
int GetFrame();
int GetState();
void Register(TCBRef);
protected:
static std::unique_ptr<CStatePriv> _Ref;
void Frame(int frameNumber);
class OnNewFrame : public OnNewData<TypeInt> {
public:
OnNewFrame(CStatePriv* par):_par(par){}
virtual void NewData(const TypeInt& val) override {
_par->Frame(val.data()[0]);
}
CStatePriv* _par;
};
std::unique_ptr<DataStream<TypeInt>> _FrameSub;
TIntSubscriptionRef _StateSub;
typedef std::vector<TCBWRef> TCBVec;
std::shared_ptr<OnNewFrame> _newFrameCb;
TCBVec _Cbs;
int _frame;
};
}
#include "stdafx.h"
#include <NadsDDSLib\NadsDDSLib.h>
#include <nadsddsimpl.h>
namespace NADSDDS {
CPublication::TRef
CPublication::MakePublication(const std::string& name, int EID, size_t count, char cellType) {
CPublication::TRef ret;
switch (cellType)
{
case 'c':{
unique_ptr<CCharPub> ptr = make_unique<CCharPub>(CCharPub::TRef(new CellPub<TypeChar>(name, DDSDomainRepo::GetDomain(0), count, EID)));
return make_unique<CharPublication>(unique_ptr< CCharPub>(std::move(ptr)));
};
case 'f': {
unique_ptr<CFloatPub> ptr = make_unique<CFloatPub>(CFloatPub::TRef(new CellPub<TypeFloat>(name, DDSDomainRepo::GetDomain(0), count, EID)));
return make_unique<FloatPublication>(unique_ptr<CFloatPub>(std::move(ptr)));
};
case 'd': {
unique_ptr<CDoublePub> ptr = make_unique<CDoublePub>(make_unique<CellPub<TypeDouble>>(name, DDSDomainRepo::GetDomain(0), count, EID));
return make_unique<DoublePublication>(unique_ptr<CDoublePub>(std::move(ptr)));
};
case 's': {
unique_ptr<CShortPub> ptr = make_unique<CShortPub>(make_unique<CellPub<TypeShort>>(name, DDSDomainRepo::GetDomain(0), count, EID));
return make_unique<ShortPublication>(unique_ptr<CShortPub>(std::move(ptr)));
};
case 'i': {
unique_ptr<CIntPub> ptr = make_unique<CIntPub>(make_unique<CellPub<TypeInt>>(name, DDSDomainRepo::GetDomain(0), count, EID));
return make_unique<IntPublication>(unique_ptr<CIntPub>(std::move(ptr)));
};
default:
return ret;
break;
}
}
char* CPublication::asChar() { return nullptr; };
double* CPublication::asDouble() { return nullptr; };
float* CPublication::asFloat() { return nullptr; };
int* CPublication::asInt() { return nullptr; };
short* CPublication::asShort() { return nullptr; };
const std::string& CPublication::Name() { return GetPub()->_name;};
int CPublication::EID() {
return GetPub()->eid();
}
void* CPublication::Raw() {
auto ptr = GetPub();
return ptr->Raw();
}
size_t CPublication::SizeInBytes() {
return GetPub()->_sizeInBytes;
}
size_t CPublication::Count() {
return GetPub()->_itemCount;
}
DoublePublication::DoublePublication(TDoublePubPtr&& ptr) :_ref(std::move(ptr)) {}
double* DoublePublication::asDouble() {
return (double*)_ref->get()->Raw();
}
void DoublePublication::Publish() {
(_ref)->get()->Send();
}
DoublePublication& DoublePublication::operator= (double val) {
TypeDouble &dval = _ref->get()->data;
dval.data()[0] = val;
return *this;
}
double& DoublePublication::operator[] (size_t index) {
static double nothing=0;
TypeDouble &dval = _ref->get()->data;
if (dval.data().size() > index) {
return dval.data()[index];
}
return nothing;
}
CellRoot* DoublePublication::GetPub() {
return _ref->get();
}
FloatPublication::FloatPublication(TFloatPubPtr&& ptr) :_ref(std::move(ptr)) {}
float* FloatPublication::asFloat() {
return (float*)_ref->get()->Raw();
}
FloatPublication& FloatPublication::operator= (float val) {
auto &dval = _ref->get()->data;
dval.data()[0] = val;
return *this;
}
float& FloatPublication::operator[] (size_t index) {
static float nothing = 0;
auto &dval = _ref->get()->data;
if (dval.data().size() > index) {
return dval.data()[index];
}
return nothing;
}
CellRoot* FloatPublication::GetPub() {
return _ref->get();
}
void FloatPublication::Publish() {
(_ref)->get()->Send();
}
ShortPublication::ShortPublication(TShortPubPtr&& ptr) :_ref(std::move(ptr)) {}
short* ShortPublication::asShort() {
return (short*)_ref->get()->Raw();
}
ShortPublication& ShortPublication::operator= (short val) {
auto &dval = _ref->get()->data;
dval.data()[0] = val;
return *this;
}
short& ShortPublication::operator[] (size_t index) {
static short nothing = 0;
auto &dval = _ref->get()->data;
if (dval.data().size() > index) {
return dval.data()[index];
}
return nothing;
}
CellRoot* ShortPublication::GetPub() {
return (CellPub<TypeShort>*)_ref.get();
}
void ShortPublication::Publish() {
(_ref)->get()->Send();
}
IntPublication::IntPublication(TIntPubPtr&& ptr) :_ref(std::move(ptr)) {}
int* IntPublication::asInt() {
return (int*)_ref->get()->Raw();
}
IntPublication& IntPublication::operator= (int val) {
auto &dval = _ref->get()->data;
dval.data()[0] = val;
return *this;
}
int& IntPublication::operator[] (size_t index) {
static int nothing = 0;
auto &dval = _ref->get()->data;
if (dval.data().size() > index) {
return dval.data()[index];
}
return nothing;
}
CellRoot* IntPublication::GetPub() {
return _ref->get();
}
void IntPublication::Publish() {
(_ref)->get()->Send();
}
CharPublication::CharPublication(TCharPubPtr&& ptr) :_ref(std::move(ptr)) {}
char* CharPublication::asChar() {
return (char*)_ref->_ref->Raw();
}
CharPublication& CharPublication::operator= (const std::string& str) {
auto &dval = _ref->get()->data;
dval.data() = str;
return *this;
}
char& CharPublication::operator[] (size_t index) {
static char nothing = 0;
auto &dval = _ref->_ref->data;
if (dval.data().size() > index) {
return dval.data()[index];
}
return nothing;
}
CellRoot* CharPublication::GetPub() {
return _ref->_ref.get();
}
void CharPublication::Publish() {
(_ref)->get()->Send();
}
size_t CSubscription::GetSizeInByes() {
return GetCell()->_sizeInBytes;
}
void* CSubscription::GetRaw() {
return GetCell()->Raw();
}
CSubscription::TRef
CSubscription::MakeSubscription(const std::string& name, char cellType) {
CSubscription::TRef ret;
switch (cellType)
{
case 'c': {
TCharSubscriptionRef ptr = make_unique<TCharSubscription>(name);
ptr->Register();
return CSubscription::TRef(new CCharSubscription(std::move(ptr)));
};
case 'f': {
TFloatSubscriptionRef ptr = make_unique<TFloatSubscription>(name);
ptr->Register();
return CSubscription::TRef(new CFloatSubscription(std::move(ptr)));
};
case 'd': {
TDoubleSubscriptionRef ptr = make_unique<TDoubleSubscription>(name);
ptr->Register();
return CSubscription::TRef(new CDoubleSubscription(std::move(ptr)));
};
case 's': {
TShortSubscriptionRef ptr = make_unique<TShortSubscription>(name);
ptr->Register();
return CSubscription::TRef(new CShortSubscription(std::move(ptr)));
};
case 'i': {
TIntSubscriptionRef ptr = make_unique<TIntSubscription>(name);
ptr->Register();
return CSubscription::TRef(new CIntSubscription(std::move(ptr)));
};
default:
return ret;
break;
}
}
class CBPriv : public CStatePriv::Callback {
public:
CBPriv(CState* par) :_par(par) {};
CState* _par;
void OnFrame(int num) {
_par->NewFrame(num);
}
~CBPriv() {};
};
void CState::NewFrame(int frame) {
for (auto cb : _Cbs) {
auto sp = cb.lock();
if (sp) {
sp->OnFrame(frame);
}
}
RemovedExpired<TCBWRefs, TCBWRef>(_Cbs);
}
int CState::GetFrame() {
return CStatePriv::Get().GetFrame();
}
int CState::GetState() {
return CStatePriv::Get().GetState();
}
void CState::Register(TCBRef ref) {
_Cbs.push_back(ref);
if (!_privCB) {
_privCB = make_shared<CBPriv>(this);
CStatePriv::Get().Register(_privCB);
}
}
CState::CState() {
}
CState::~CState() {
}
namespace Info {
void GetCellInfo(TCellInfoVec& cells) {
DDSTopicInfo::Refresh();
cells = DDSTopicInfo::GetTopics();
}
}
}
\ No newline at end of file
/*
/ (c) Copyright 2018, Real-Time Innovations, All rights reserved. /
/ /
/ RTI grants Licensee a license to use, modify, compile, and create /
/ derivative works of the software solely for use with RTI Connext DDS. /
/ Licensee may redistribute copies of the software provided that all such /
/ copies are subject to this license. The software is provided "as is", with /
/ no warranty of any type, including any warranty for fitness for any purpose. /
/ RTI is under no obligation to maintain or support the software. RTI shall /
/ not be liable for any incidental or consequential damages arising out of the /
/ use or inability to use the software. /
*/
#include "transform_xml.h"
#include <fstream>
#include <sstream>
#include <algorithm>
#include <xml/parser>
#include <xml/serializer>
using namespace xml;
struct MatchPathSeparator
{
bool operator()( char ch ) const
{
return ch == '\\' || ch == '/';
}
};
static std::string basename(std::string const& pathname )
{
return std::string(std::find_if(pathname.rbegin(), pathname.rend(), MatchPathSeparator()).base(),
pathname.end() );
}
std::string transform_xml(std::string& filename)
{
bool transforming=false;
int depth=0;
std::ifstream ifs;
ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit);
ifs.open (filename, std::ifstream::in | std::ifstream::binary);
// Configure the parser to receive attributes as events as well
// as to receive prefix-namespace mappings (namespace declarations
// in XML terminology).
//
parser p(ifs,
filename,
parser::receive_default |
parser::receive_attributes_event |
parser::receive_namespace_decls);
std::stringstream type_definition;
serializer s(type_definition, "typedef", 1);
s.xml_decl();
for (parser::event_type e (p.next ()); e != parser::eof; e = p.next ())
{
switch (e)
{
case parser::start_element:
{
if(p.qname().string() == "type_library") {
return filename;
}
if(p.qname().string() == "types") {
qname transformed_qname("dds");
s.start_element(transformed_qname);
s.namespace_decl("http://www.w3.org/2001/XMLSchema-instance", "xsi");
transforming=true;
} else {
s.start_element(p.qname());
if(transforming) {
++depth;
}
}
break;
}
case parser::end_element:
{
if(transforming && depth == 0) {
s.end_element();
transforming=false;
} else if(transforming) {
depth=std::max(0,--depth);
}
s.end_element();
break;
}
case parser::start_namespace_decl:
{
break;
}
case parser::end_namespace_decl:
{
// There is nothing in XML that indicates the end of namespace
// declaration since it is scope-based.
//
break;
}
case parser::start_attribute:
{
s.start_attribute(p.qname());
break;
}
case parser::end_attribute:
{
s.end_attribute();
if(transforming && depth == 0) {
s.start_element("type_library");
s.start_attribute("name");
s.characters("MyTypes");
s.end_attribute();
depth=1;
}
break;
}
case parser::characters:
{
s.characters(p.value());
break;
}
}
}
s.end_element();
std::string fullpath = "/tmp/" + basename(filename);
std::ofstream file(fullpath);
file << type_definition.str();
file.close();
return fullpath;
}
/********************************************************************************/
/* (c) Copyright 2018, Real-Time Innovations, All rights reserved. */
/* */
/* RTI grants Licensee a license to use, modify, compile, and create */
/* derivative works of the software solely for use with RTI Connext DDS. */
/* Licensee may redistribute copies of the software provided that all such */
/* copies are subject to this license. The software is provided "as is", with */
/* no warranty of any type, including any warranty for fitness for any purpose. */
/* RTI is under no obligation to maintain or support the software. RTI shall */
/* not be liable for any incidental or consequential damages arising out of the */
/* use or inability to use the software. */
/********************************************************************************/
#ifndef _TRANSFORM_XML_H_INCLUDED
#define _TRANSFORM_XML_H_INCLUDED
#include <string>
/**
* @brief transform an XML representation of a datatype as emitted by
* "rtiddsgen -convertToXml" to an XML format compatible with the modern C++
* QosProvider constructor argument
*
* @param filename full path to the file containing an rtiddsgen XML datatype representation
* @return std::string full path to a converted file suitable for passing to QosProvider
* constructor
*/
std::string transform_xml(std::string& filename);
#endif
/*
/ (c) Copyright 2018, Real-Time Innovations, All rights reserved. /
/ /
/ RTI grants Licensee a license to use, modify, compile, and create /
/ derivative works of the software solely for use with RTI Connext DDS. /
/ Licensee may redistribute copies of the software provided that all such /
/ copies are subject to this license. The software is provided "as is", with /
/ no warranty of any type, including any warranty for fitness for any purpose. /
/ RTI is under no obligation to maintain or support the software. RTI shall /
/ not be liable for any incidental or consequential damages arising out of the /
/ use or inability to use the software. /
*/
#include "value_as_string.h"
#include <sstream>
#include <string>
using namespace dds::core;
static std::string do_text_conversion(const rti::core::xtypes::DynamicDataMemberInfo& info,
uint32_t member_index,
const xtypes::DynamicData& data,
bool add_name);
static std::string decode_sequence(const xtypes::DynamicData& data)
{
std::stringstream buffer;
int num_members = data.member_count();
for(int32_t i = 1; i <= num_members; ++i) {
buffer << " " << do_text_conversion(data.member_info(i), i, data, true);
}
return buffer.str();
}
static std::string do_text_conversion(const rti::core::xtypes::DynamicDataMemberInfo& info,
uint32_t member_index,
const xtypes::DynamicData& data,
bool add_name)
{
std::stringstream buffer;
std::string name=(add_name && (info.member_name().c_str() != nullptr))?(info.member_name().to_std_string()+"="):"";
switch(info.member_kind().underlying()) {
case xtypes::TypeKind_def::BOOLEAN_TYPE:
buffer << name << data.value<bool>(member_index);
return buffer.str();
case xtypes::TypeKind_def::UINT_8_TYPE:
buffer << name << static_cast<uint32_t>(data.value<uint8_t>(member_index));
return buffer.str();
case xtypes::TypeKind_def::INT_16_TYPE:
buffer << name << data.value<int16_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::UINT_16_TYPE:
buffer << name << data.value<uint16_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::INT_32_TYPE:
buffer << name << data.value<int32_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::UINT_32_TYPE:
buffer << name << data.value<uint32_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::INT_64_TYPE:
buffer << name << data.value<int64_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::UINT_64_TYPE:
buffer << name << data.value<uint64_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::FLOAT_32_TYPE:
buffer << name << data.value<float>(member_index);
return buffer.str();
case xtypes::TypeKind_def::FLOAT_64_TYPE:
buffer << name << data.value<double>(member_index);
return buffer.str();
case xtypes::TypeKind_def::FLOAT_128_TYPE:
buffer << name << "Unsupported Floating point type";
return buffer.str();
case xtypes::TypeKind_def::CHAR_8_TYPE:
buffer << name << data.value<char>(member_index);
return buffer.str();
case xtypes::TypeKind_def::ENUMERATION_TYPE:
buffer << name << data.value<uint32_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::STRING_TYPE:
buffer << name << data.value<std::string>(member_index);
return buffer.str();
case xtypes::TypeKind_def::WSTRING_TYPE:
return std::string();
case xtypes::TypeKind_def::ARRAY_TYPE:
return std::string();
case xtypes::TypeKind_def::UNION_TYPE:
case xtypes::TypeKind_def::STRUCTURE_TYPE:
case xtypes::TypeKind_def::SEQUENCE_TYPE:
return decode_sequence(data.value<xtypes::DynamicData>(member_index));
default:
return std::string();
}
}
// represent given dynamic data value as a string
std::string value_as_string(const xtypes::DynamicData& data, const std::string& member_name)
{
return do_text_conversion(data.member_info(member_name),
data.member_info(member_name).member_index(),
data,
false);
}
/********************************************************************************/
/* (c) Copyright 2018, Real-Time Innovations, All rights reserved. */
/* */
/* RTI grants Licensee a license to use, modify, compile, and create */
/* derivative works of the software solely for use with RTI Connext DDS. */
/* Licensee may redistribute copies of the software provided that all such */
/* copies are subject to this license. The software is provided "as is", with */
/* no warranty of any type, including any warranty for fitness for any purpose. */
/* RTI is under no obligation to maintain or support the software. RTI shall */
/* not be liable for any incidental or consequential damages arising out of the */
/* use or inability to use the software. */
/********************************************************************************/
#ifndef _VALUE_AS_STRING_H_
#define _VALUE_AS_STRING_H_
#include <dds/dds.hpp>
#include <string>
/**
* @brief for a given member of a dynamic datatype return a std::string
* representation of its value
*
* @param data dynamic datatype to which the member belongs
* @param member_name name of the member
* @return std::string string representation of members value
*/
std::string value_as_string(const dds::core::xtypes::DynamicData& data,
const std::string& member_name);
#endif
\ No newline at end of file
File added
File added
File added
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment