work in progress; simple easyGet worked!!!
This commit is contained in:
8
.hgflow
Normal file
8
.hgflow
Normal file
@ -0,0 +1,8 @@
|
||||
[branchname]
|
||||
master = master
|
||||
develop = default
|
||||
feature = feature/
|
||||
release = release/
|
||||
hotfix = hotfix/
|
||||
support = support/
|
||||
|
11
.hgignore
Normal file
11
.hgignore
Normal file
@ -0,0 +1,11 @@
|
||||
^QtC-
|
||||
bin/
|
||||
lib/
|
||||
doc/
|
||||
include/
|
||||
db/
|
||||
dbd/
|
||||
documentation/html
|
||||
envPaths
|
||||
configure/.*\.local
|
||||
/O\..*
|
78
LICENSE
Normal file
78
LICENSE
Normal file
@ -0,0 +1,78 @@
|
||||
|
||||
Copyright (c) 2008 Martin R. Kraimer
|
||||
Copyright (c) 2006 The University of Chicago, as Operator of Argonne
|
||||
National Laboratory.
|
||||
Copyright (c) 2006 Deutsches Elektronen-Synchrotron,
|
||||
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
|
||||
Copyright (c) 2007 Control System Laboratory,
|
||||
(COSYLAB) Ljubljana Slovenia
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
This software is in part copyrighted by the University of Chicago (UofC)
|
||||
|
||||
In no event shall UofC be liable to any party for direct, indirect,
|
||||
special, incidental, or consequential damages arising out of the use of
|
||||
this software, its documentation, or any derivatives thereof, even if
|
||||
UofC has been advised of the possibility of such damage.
|
||||
|
||||
UofC specifically disclaims any warranties, including, but not limited
|
||||
to, the implied warranties of merchantability, fitness for a particular
|
||||
purpose, and non-infringement. This software is provided on an "as is"
|
||||
basis, and UofC has no obligation to provide maintenance, support,
|
||||
updates, enhancements, or modifications.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
This software is in part copyrighted by the BERLINER SPEICHERRING
|
||||
GESELLSCHAFT FUER SYNCHROTRONSTRAHLUNG M.B.H. (BESSY), BERLIN, GERMANY.
|
||||
|
||||
In no event shall BESSY be liable to any party for direct, indirect,
|
||||
special, incidental, or consequential damages arising out of the use of
|
||||
this software, its documentation, or any derivatives thereof, even if
|
||||
BESSY has been advised of the possibility of such damage.
|
||||
|
||||
BESSY specifically disclaims any warranties, including, but not limited
|
||||
to, the implied warranties of merchantability, fitness for a particular
|
||||
purpose, and non-infringement. This software is provided on an "as is"
|
||||
basis, and BESSY has no obligation to provide maintenance, support,
|
||||
updates, enhancements, or modifications.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
This software is in part copyrighted by the Deutsches Elektronen-Synchroton,
|
||||
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
|
||||
|
||||
In no event shall DESY be liable to any party for direct, indirect,
|
||||
special, incidental, or consequential damages arising out of the use of
|
||||
this software, its documentation, or any derivatives thereof, even if
|
||||
DESY has been advised of the possibility of such damage.
|
||||
|
||||
DESY specifically disclaims any warranties, including, but not limited
|
||||
to, the implied warranties of merchantability, fitness for a particular
|
||||
purpose, and non-infringement. This software is provided on an "as is"
|
||||
basis, and DESY has no obligation to provide maintenance, support,
|
||||
updates, enhancements, or modifications.
|
||||
________________________________________________________________________
|
20
Makefile
Normal file
20
Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
#Makefile at top of application tree
|
||||
TOP = .
|
||||
include $(TOP)/configure/CONFIG
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), configure)
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), src)
|
||||
|
||||
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), example)
|
||||
|
||||
define DIR_template
|
||||
$(1)_DEPEND_DIRS = configure
|
||||
endef
|
||||
$(foreach dir, $(filter-out configure,$(DIRS)),$(eval $(call DIR_template,$(dir))))
|
||||
|
||||
define EMB_template
|
||||
$(1)_DEPEND_DIRS = src
|
||||
endef
|
||||
$(foreach dir, $(EMBEDDED_TOPS),$(eval $(call EMB_template,$(dir))))
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES_TOP
|
29
configure/CONFIG
Normal file
29
configure/CONFIG
Normal file
@ -0,0 +1,29 @@
|
||||
# CONFIG - Load build configuration data
|
||||
#
|
||||
# Do not make changes to this file!
|
||||
|
||||
# Allow user to override where the build rules come from
|
||||
RULES = $(EPICS_BASE)
|
||||
|
||||
# RELEASE files point to other application tops
|
||||
include $(TOP)/configure/RELEASE
|
||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
|
||||
ifdef T_A
|
||||
-include $(TOP)/configure/RELEASE.Common.$(T_A)
|
||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
endif
|
||||
|
||||
CONFIG = $(RULES)/configure
|
||||
include $(CONFIG)/CONFIG
|
||||
|
||||
# Override the Base definition:
|
||||
INSTALL_LOCATION = $(TOP)
|
||||
|
||||
# CONFIG_SITE files contain other build configuration settings
|
||||
include $(TOP)/configure/CONFIG_SITE
|
||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
||||
ifdef T_A
|
||||
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
|
||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
endif
|
||||
|
27
configure/CONFIG_SITE
Normal file
27
configure/CONFIG_SITE
Normal file
@ -0,0 +1,27 @@
|
||||
# CONFIG_SITE
|
||||
|
||||
# Make any application-specific changes to the EPICS build
|
||||
# configuration variables in this file.
|
||||
#
|
||||
# Host/target specific settings can be specified in files named
|
||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
||||
# CONFIG_SITE.Common.$(T_A)
|
||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
# CHECK_RELEASE controls the consistency checking of the support
|
||||
# applications pointed to by the RELEASE* files.
|
||||
# Normally CHECK_RELEASE should be set to YES.
|
||||
# Set CHECK_RELEASE to NO to disable checking completely.
|
||||
# Set CHECK_RELEASE to WARN to perform consistency checking but
|
||||
# continue building anyway if conflicts are found.
|
||||
#CHECK_RELEASE = YES
|
||||
|
||||
# To install files into a location other than $(TOP) define
|
||||
# INSTALL_LOCATION here.
|
||||
#INSTALL_LOCATION=</path/name/to/install/top>
|
||||
|
||||
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
|
||||
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
|
||||
|
||||
-include $(TOP)/../CONFIG_SITE.local
|
||||
-include $(TOP)/configure/CONFIG_SITE.local
|
7
configure/ExampleRELEASE.local
Normal file
7
configure/ExampleRELEASE.local
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
||||
|
||||
EPICS_BASE=/home/install/epics/base
|
||||
PVCOMMON=/home/hg/pvCommonCPP
|
||||
PVDATA=/home/hg/pvDataCPP
|
||||
PVACCESS=/home/hg/pvAccessCPP
|
9
configure/Makefile
Normal file
9
configure/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
TOP=..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
TARGETS = $(CONFIG_TARGETS)
|
||||
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
28
configure/RELEASE
Normal file
28
configure/RELEASE
Normal file
@ -0,0 +1,28 @@
|
||||
# easyPVACPP RELEASE - Location of external support modules
|
||||
#
|
||||
# IF YOU CHANGE this file or any file it includes you must
|
||||
# subsequently do a "gnumake rebuild" in the application's
|
||||
# top level directory.
|
||||
#
|
||||
# The build process does not check dependencies against files
|
||||
# that are outside this application, thus you should also do a
|
||||
# "gnumake rebuild" in the top level directory after EPICS_BASE
|
||||
# or any other external module pointed to below is rebuilt.
|
||||
#
|
||||
# Host- or target-specific settings can be given in files named
|
||||
# RELEASE.$(EPICS_HOST_ARCH).Common
|
||||
# RELEASE.Common.$(T_A)
|
||||
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
# EPICS V4 Developers: Do not edit the locations in this file!
|
||||
#
|
||||
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
|
||||
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
|
||||
# PVASRV = /path/to/epics/pvaSrvCPP
|
||||
# PVACCESS = /path/to/epics/pvAccessCPP
|
||||
# PVDATA = /path/to/epics/pvDataCPP
|
||||
# PVCOMMON = /path/to/epics/pvCommonCPP
|
||||
# EPICS_BASE = /path/to/epics/base
|
||||
|
||||
-include $(TOP)/../RELEASE.local
|
||||
-include $(TOP)/configure/RELEASE.local
|
6
configure/RULES
Normal file
6
configure/RULES
Normal file
@ -0,0 +1,6 @@
|
||||
# RULES
|
||||
|
||||
include $(CONFIG)/RULES
|
||||
|
||||
# Library should be rebuilt because LIBOBJS may have changed.
|
||||
$(LIBNAME): ../Makefile
|
2
configure/RULES.ioc
Normal file
2
configure/RULES.ioc
Normal file
@ -0,0 +1,2 @@
|
||||
#RULES.ioc
|
||||
include $(CONFIG)/RULES.ioc
|
2
configure/RULES_DIRS
Normal file
2
configure/RULES_DIRS
Normal file
@ -0,0 +1,2 @@
|
||||
#RULES_DIRS
|
||||
include $(CONFIG)/RULES_DIRS
|
16
configure/RULES_TOP
Normal file
16
configure/RULES_TOP
Normal file
@ -0,0 +1,16 @@
|
||||
#RULES_TOP
|
||||
include $(CONFIG)/RULES_TOP
|
||||
|
||||
EMTOPACTIONS += cvsclean realuninstall
|
||||
|
||||
distclean: emtop_distclean
|
||||
|
||||
emtopDistcleanTargets += $(foreach dir, $(EMBEDDED_TOPS), \
|
||||
$(dir)$(DIVIDER)emtop_dummy_action)
|
||||
|
||||
$(emtopDistcleanTargets) :
|
||||
$(MAKE) -C $(dirPart) $(EMTOPACTIONS)
|
||||
|
||||
emtop_distclean : $(emtopDistcleanTargets)
|
||||
|
||||
.PHONY : $(emtopDistcleanTargets)
|
295
documentation/easyPVA.html
Normal file
295
documentation/easyPVA.html
Normal file
@ -0,0 +1,295 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||
<title>EPICS easyPVA</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||
<style type="text/css">
|
||||
/*<![CDATA[*/
|
||||
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||
table { margin-left: auto; margin-right: auto }
|
||||
.diagram { text-align: center; margin: 2.5em 0 }
|
||||
body { margin-right: 10% }
|
||||
/*]]>*/</style>
|
||||
|
||||
<!-- Script that generates the Table of Contents -->
|
||||
<script type="text/javascript" src="http://epics-pvdata.sourceforge.net/script/tocgen.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="head">
|
||||
<h1>EPICS easyPVA</h1>
|
||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
||||
<h2 class="nocount">EPICS V4 Working Group, Working Draft,
|
||||
19-Feb-2015</h2>
|
||||
<dl>
|
||||
<dt>This version:</dt>
|
||||
<dd><a
|
||||
href="easyPVA.html">easyPVA.html
|
||||
</a> </dd>
|
||||
<dt>Latest version:</dt>
|
||||
<dd>none</dd>
|
||||
<dt>Previous version:</dt>
|
||||
<dd>none</dd>
|
||||
<dt>Editors:</dt>
|
||||
<dd>Marty Kraimer, BNL</dd>
|
||||
<dd>Matej Sekoranja, Cosylab</dd>
|
||||
</dl>
|
||||
|
||||
<h2 class="nocount">Abstract</h2>
|
||||
|
||||
<p>EasyPVA (Easy PVAccess) is a software library that provides to an EPICS client programmer, a friendly
|
||||
client side programming interface to the data of an EPICS based control system. It is intended
|
||||
for such uses as rapid development of ad hoc programs by controls engineers, or to provide
|
||||
scientists a way to directly develop analytical applications.</p>
|
||||
|
||||
<p>Specifically, easyPVA provides an easy interface for pvAccess, which is the
|
||||
software support for high speed controls network communications used in EPICS version 4.
|
||||
PvAccess provides a callback based interface, which can be hard to use.
|
||||
EasyPVA provides an interface that does not require callbacks even for monitors.
|
||||
</p>
|
||||
<p>
|
||||
EasyChannel provides many "convenience" methods to directly get and put
|
||||
scalar and scalarArray data types.
|
||||
Additional methods provide access to the full features of pvAccess.
|
||||
</p>
|
||||
<p>
|
||||
EasyMultiChannel provides access to data from multiple channels as long
|
||||
as each channel has a top level field named <b>value</b>.
|
||||
EasyMultiChannel provides two ways to access data from multiple channels:
|
||||
The first is as an NTMultiChannel. The second is as a double array.
|
||||
The double array can be used if the value field of every channel is a numeric scalar.
|
||||
There is code for NTMultiChannel that helps with access to more complicated data types.
|
||||
</p>
|
||||
<p>EasyPVA will become part of pvAccess when it is ready. </p>
|
||||
|
||||
<!-- last para of Abstract is boilerplate reference to EPICS -->
|
||||
<p>For more information about EPICS generally, please refer to the home page of the <a
|
||||
href="http://www.aps.anl.gov/epics/">Experimental Physics and Industrial
|
||||
Control System</a>.</p>
|
||||
|
||||
|
||||
|
||||
<h2 class="nocount">Status of this Document and of the EasyPVA Software</h2>
|
||||
|
||||
<p>Under development</p>
|
||||
|
||||
</div> <!-- head -->
|
||||
|
||||
<div id="toc">
|
||||
<h2 class="nocount">Table of Contents</h2>
|
||||
</div>
|
||||
|
||||
<!-- Place what you would like in the Table of Contents, inside the contents div -->
|
||||
<div id="contents" class="contents">
|
||||
<hr />
|
||||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
<p>EasyPVA is a synchronous API for accessing PVData via PVAccess. It provides
|
||||
an interface to many of the features provided by pvData and pvAccess.</p>
|
||||
|
||||
<p>The EasyPVA API has the following features:</p>
|
||||
<ol>
|
||||
<li>Makes common requests easy to program</li>
|
||||
<li>Provides full access to the pvAccess API for more demanding
|
||||
applications</li>
|
||||
<li>Allows efficient client side programs.</li>
|
||||
</ol>
|
||||
|
||||
<p>The following describes the CPP version of EasyPVA.</p>
|
||||
|
||||
<p>This is the overview for EasyPVACPP. JavaDoc documentation is available at <a
|
||||
href="./html/index.html">doxygenDoc</a></p>
|
||||
|
||||
|
||||
<h3>Initialization</h3>
|
||||
|
||||
<p>A client obtains the interface to EasyPVA via the call:</p>
|
||||
<pre>EasyPVA easy = EasyPVAFactory.get();</pre>
|
||||
|
||||
<p>The client can make this call many times, but an instance of the EastPVA interface object is
|
||||
only created in the first call. This first call also
|
||||
starts the PVAccess client factory.</p>
|
||||
|
||||
<h3>EasyPVA Overview</h3>
|
||||
|
||||
<p>EasyPVA creates interfaces to one of the following:</p>
|
||||
<dl>
|
||||
<dt>EasyChannel</dt>
|
||||
<dd>This creates an interface for accessing a single channel.<br />
|
||||
There are two methods for creating an EasyChannel,
|
||||
with the difference being that the second
|
||||
specifiers the name of the provider.
|
||||
The other assumes that the provider is "pva" (pvAccess).
|
||||
</dd>
|
||||
<dt>EasyMultiChannel</dt>
|
||||
<dd>This creates an interface for accessing a set of channels.<br />
|
||||
There are multiple methods for creating an EasyMultiChannel.
|
||||
The provider can be supplied or use a default of "pva".
|
||||
A union for the UnionArray for accessing the value fields of each channel
|
||||
can be provided or a default of variant union will be used.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<p>There are additional methods that allows the client to:</p>
|
||||
<ol>
|
||||
<li>Control how error messages are handled.</li>
|
||||
<li>Control when get/put commands are sent the channel or channels.</li>
|
||||
</ol>
|
||||
|
||||
<h3>EasyChannel Overview</h3>
|
||||
|
||||
<p>This interface creates Easy support for each PVAccess::Channel create
|
||||
method:</p>
|
||||
<dl>
|
||||
<dt>EasyField</dt>
|
||||
<dd>This gets the introspection interface from a channel. The
|
||||
implementation provides full access to the features of
|
||||
Channel::getField.</dd>
|
||||
<dt>EasyProcess</dt>
|
||||
<dd>This is used to process a channel. The implementation provides full
|
||||
access to the features of ChannelProcess.</dd>
|
||||
<dt>EasyGet</dt>
|
||||
<dd>This is used to get values from a channel. The implementation allows
|
||||
full access to all the features of ChannelGet. By default it asks for the
|
||||
fields value, alarm, and timeStamp. If the channel has a value field then
|
||||
EasyGet provides convenience methods for a scalar value and for an array
|
||||
value. </dd>
|
||||
<dt>EasyPut</dt>
|
||||
<dd>This is used to get the current value of a channel and to put values to
|
||||
a channel. The implementation allows full access to all the features of
|
||||
ChannelPut. By default it asks for the field value, alarm, and timeStamp.
|
||||
If the channel has a value field then EasyPut provides convenience
|
||||
methods for a scalar value and for an array value. </dd>
|
||||
<dt>EasyRPC</dt>
|
||||
<dd>This is an interface to ChannelRPC.
|
||||
The implementation allows full access to all the features of ChannelRPC.
|
||||
</dd>
|
||||
<dt>EasyPutGet</dt>
|
||||
<dd>This is an interface to ChannelPutGet. Details TBD.</dd>
|
||||
<dt>EasyMonitor</dt>
|
||||
<dd>This is an interface to Monitor.
|
||||
The implementation allows full access to all the features of pvAccess Monitor.
|
||||
</dd>
|
||||
<dt>EasyArray</dt>
|
||||
<dd>This is an interface to ChannelArray. Details TBD.</dd>
|
||||
<dt>EasyProcess</dt>
|
||||
<dd>This is an interface to ChannelProcess. Details TBD.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>EasyMultiChannel Overview</h3>
|
||||
<p>This interface creates Easy support for accessing a set of channels.
|
||||
The only requirement of the channels is that each must have a top level field named value.
|
||||
</p>
|
||||
<dl>
|
||||
<dt>EasyMultiGet</dt>
|
||||
<dd>This is used to get values from a a set of channels.
|
||||
The result can either be an NTMultiChannel structure or a <b>double[]</b> array.
|
||||
The createGet method determines the result type.
|
||||
</dd>
|
||||
<dt>EasyMultiPut</dt>
|
||||
<dd>This is used to get and put values from/to a set of channels.
|
||||
The data supplied can either be an NTMultiChannel structure or a <b>double[]</b> array.
|
||||
The createPut method determines the type.
|
||||
</dd>
|
||||
<dt>EasyMonitor</dt>
|
||||
<dd>This is used to monitor values from a set of channels.
|
||||
Each event can either be an NTMultiChannel structure or a <b>double[]</b> array.
|
||||
The createMonitor method determines the data type.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2>shell</h2>
|
||||
<p>Directory <b>shell</b> has the following files:</p>
|
||||
<dl>
|
||||
<dt>exampleDatabaseEasyPVA.zip</dt>
|
||||
<dd>
|
||||
When unzipped this is used to create an example IOC database.
|
||||
The database has the record used by the examples are tests that come with easyPVAJava.
|
||||
It uses pvDatabaseCPP to build the database.
|
||||
After unzipping the file:
|
||||
<pre>
|
||||
cd configure
|
||||
cp ExampleRELEASE.local RELEASE.local
|
||||
edit RELEASE.local
|
||||
cd ..
|
||||
make
|
||||
cd iocBoot/exampleDatabase
|
||||
../../bin/<arch:>/exampleDatabase st.cmd
|
||||
</pre>
|
||||
You now have a running database.
|
||||
</dd>
|
||||
<dt>source</dt>
|
||||
<dd>
|
||||
This file creates the <b>CLASSPATH</b> required
|
||||
to run the examples and tests.
|
||||
You have to edit it for your environment.
|
||||
</dd>
|
||||
<dt>rpcServiceExample</dt>
|
||||
<dd>
|
||||
This starts the RPCServiceExample.
|
||||
This is required by ExampleEasyRPC.
|
||||
</dd>
|
||||
<dt>exampleGet</dt>
|
||||
<dd>
|
||||
This runs ExampleGet.
|
||||
</dd>
|
||||
<dt>exampleGetDouble</dt>
|
||||
<dd>
|
||||
This runs ExampleGetDouble
|
||||
</dd>
|
||||
<dt>doublePut</dt>
|
||||
<dd>
|
||||
This runs DoublePut.
|
||||
</dd>
|
||||
<dt>doubleArrayPut</dt>
|
||||
<dd>
|
||||
This runs DoubleArrayPut
|
||||
</dd>
|
||||
<dt>exampleMonitor</dt>
|
||||
<dd>
|
||||
This runs ExampleMonitor
|
||||
</dd>
|
||||
<dt>exampleMonitorCallback</dt>
|
||||
<dd>
|
||||
This runs ExampleMonitorCallback
|
||||
</dd>
|
||||
<dt>exampleMultiMonitor</dt>
|
||||
<dd>
|
||||
This runs ExampleMultiMonitor.
|
||||
It and polls every few seconds for monitor events.
|
||||
It gets data as NTMultiChannel.
|
||||
</dd>
|
||||
<dt>exampleMultiMonitorDouble</dt>
|
||||
<dd>
|
||||
This runs ExampleMultiMonitorDouble.
|
||||
It has an event listener for new events.
|
||||
It gets data as an array of doubles.
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Examples</h3>
|
||||
<p>These are examples in package <b>org.epics.pvaccess.easyPVA.example</b>
|
||||
See the source code for each example.
|
||||
In order to run the examples exampleDatabaseEasyPVA must be running.
|
||||
</p>
|
||||
<p>There is a shell command to run each example,</p>
|
||||
<h3>Tests</h3>
|
||||
<p>A test directory has a number of tests for easyPVAJava.
|
||||
In order to run the tests both exampleDatabaseEasyPVA and rpcServiceExample
|
||||
must be running.
|
||||
For now these tests are being run as eclipse unit tests.
|
||||
The tests also provide examples of using EasyPVA.
|
||||
</p>
|
||||
|
||||
</div> <!-- class="contents" -->
|
||||
</body>
|
||||
</html>
|
13
example/Makefile
Normal file
13
example/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
# Makefile at top of application tree
|
||||
|
||||
TOP = .
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
DIRS += configure
|
||||
|
||||
DIRS += src
|
||||
src_DEPEND_DIRS = configure
|
||||
|
||||
include $(TOP)/configure/RULES_TOP
|
||||
|
||||
|
29
example/configure/CONFIG
Normal file
29
example/configure/CONFIG
Normal file
@ -0,0 +1,29 @@
|
||||
# CONFIG - Load build configuration data
|
||||
#
|
||||
# Do not make changes to this file!
|
||||
|
||||
# Allow user to override where the build rules come from
|
||||
RULES = $(EPICS_BASE)
|
||||
|
||||
# RELEASE files point to other application tops
|
||||
include $(TOP)/configure/RELEASE
|
||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
|
||||
ifdef T_A
|
||||
-include $(TOP)/configure/RELEASE.Common.$(T_A)
|
||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
endif
|
||||
|
||||
CONFIG = $(RULES)/configure
|
||||
include $(CONFIG)/CONFIG
|
||||
|
||||
# Override the Base definition:
|
||||
INSTALL_LOCATION = $(TOP)
|
||||
|
||||
# CONFIG_SITE files contain other build configuration settings
|
||||
include $(TOP)/configure/CONFIG_SITE
|
||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
||||
ifdef T_A
|
||||
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
|
||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
endif
|
||||
|
27
example/configure/CONFIG_SITE
Normal file
27
example/configure/CONFIG_SITE
Normal file
@ -0,0 +1,27 @@
|
||||
# CONFIG_SITE
|
||||
|
||||
# Make any application-specific changes to the EPICS build
|
||||
# configuration variables in this file.
|
||||
#
|
||||
# Host/target specific settings can be specified in files named
|
||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
||||
# CONFIG_SITE.Common.$(T_A)
|
||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
# CHECK_RELEASE controls the consistency checking of the support
|
||||
# applications pointed to by the RELEASE* files.
|
||||
# Normally CHECK_RELEASE should be set to YES.
|
||||
# Set CHECK_RELEASE to NO to disable checking completely.
|
||||
# Set CHECK_RELEASE to WARN to perform consistency checking but
|
||||
# continue building anyway if conflicts are found.
|
||||
CHECK_RELEASE = WARN
|
||||
|
||||
# To install files into a location other than $(TOP) define
|
||||
# INSTALL_LOCATION here.
|
||||
#INSTALL_LOCATION=</path/name/to/install/top>
|
||||
|
||||
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
|
||||
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
|
||||
|
||||
-include $(TOP)/../../CONFIG_SITE.local
|
||||
-include $(TOP)/../configure/CONFIG_SITE.local
|
7
example/configure/ExampleRELEASE.local
Normal file
7
example/configure/ExampleRELEASE.local
Normal file
@ -0,0 +1,7 @@
|
||||
EPICS_BASE=/home/install/epics/base
|
||||
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
||||
EPICSV4HOME=/home/hg
|
||||
PVCOMMON=${EPICSV4HOME}/pvCommonCPP
|
||||
PVDATA=${EPICSV4HOME}/pvDataCPP
|
||||
PVACCESS=${EPICSV4HOME}/pvAccessCPP
|
||||
EASYPVA==${EPICSV4HOME}/easyPVACPP
|
8
example/configure/Makefile
Normal file
8
example/configure/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
TOP=..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
TARGETS = $(CONFIG_TARGETS)
|
||||
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
||||
|
||||
include $(TOP)/configure/RULES
|
41
example/configure/RELEASE
Normal file
41
example/configure/RELEASE
Normal file
@ -0,0 +1,41 @@
|
||||
# pvDatabaseCPP/example RELEASE - Location of external support modules
|
||||
#
|
||||
# IF YOU CHANGE this file or any file it includes you must
|
||||
# subsequently do a "gnumake rebuild" in the application's
|
||||
# top level directory.
|
||||
#
|
||||
# The build process does not check dependencies against files
|
||||
# that are outside this application, thus you should also do a
|
||||
# "gnumake rebuild" in the top level directory after EPICS_BASE
|
||||
# or any other external module pointed to below is rebuilt.
|
||||
#
|
||||
# Host- or target-specific settings can be given in files named
|
||||
# RELEASE.$(EPICS_HOST_ARCH).Common
|
||||
# RELEASE.Common.$(T_A)
|
||||
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
# EPICS V4 Developers: Do not edit the locations in this file!
|
||||
#
|
||||
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
|
||||
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
|
||||
# PVASRV = /path/to/epics/pvaSrvCPP
|
||||
# PVACCESS = /path/to/epics/pvAccessCPP
|
||||
# PVDATA = /path/to/epics/pvDataCPP
|
||||
# PVCOMMON = /path/to/epics/pvCommonCPP
|
||||
# EPICS_BASE = /path/to/epics/base
|
||||
|
||||
# If this example is built in a directory under pvDatabaseCPP,
|
||||
# use the following definitions:
|
||||
|
||||
EASYPVA = $(TOP)/..
|
||||
|
||||
-include $(TOP)/../configure/RELEASE.local
|
||||
-include $(TOP)/../../RELEASE.local
|
||||
|
||||
# If you copied this example from pvDatabaseCPP to be built as a
|
||||
# standalone TOP, adjust and use the following definitions:
|
||||
|
||||
#EASYPVA = /path/to/epics/easyPVACPP
|
||||
|
||||
#-include $(TOP)/../RELEASE.local
|
||||
#-include $(TOP)/configure/RELEASE.local
|
6
example/configure/RULES
Normal file
6
example/configure/RULES
Normal file
@ -0,0 +1,6 @@
|
||||
# RULES
|
||||
|
||||
include $(CONFIG)/RULES
|
||||
|
||||
# Library should be rebuilt because LIBOBJS may have changed.
|
||||
$(LIBNAME): ../Makefile
|
2
example/configure/RULES.ioc
Normal file
2
example/configure/RULES.ioc
Normal file
@ -0,0 +1,2 @@
|
||||
#RULES.ioc
|
||||
include $(CONFIG)/RULES.ioc
|
2
example/configure/RULES_DIRS
Normal file
2
example/configure/RULES_DIRS
Normal file
@ -0,0 +1,2 @@
|
||||
#RULES_DIRS
|
||||
include $(CONFIG)/RULES_DIRS
|
3
example/configure/RULES_TOP
Normal file
3
example/configure/RULES_TOP
Normal file
@ -0,0 +1,3 @@
|
||||
#RULES_TOP
|
||||
include $(CONFIG)/RULES_TOP
|
||||
|
27
example/src/Makefile
Normal file
27
example/src/Makefile
Normal file
@ -0,0 +1,27 @@
|
||||
TOP=..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
#----------------------------------------
|
||||
# ADD MACRO DEFINITIONS AFTER THIS LINE
|
||||
|
||||
|
||||
PROD_HOST += exampleEasyPVStructure
|
||||
exampleEasyPVStructure_SRCS += exampleEasyPVStructure.cpp
|
||||
exampleEasyPVStructure_LIBS += easyPVA
|
||||
exampleEasyPVStructure_LIBS += pvAccess
|
||||
exampleEasyPVStructure_LIBS += pvData
|
||||
exampleEasyPVStructure_LIBS += Com
|
||||
|
||||
PROD_HOST += exampleEasyGet
|
||||
exampleEasyGet_SRCS += exampleEasyGet.cpp
|
||||
exampleEasyGet_LIBS += easyPVA
|
||||
exampleEasyGet_LIBS += pvAccess
|
||||
exampleEasyGet_LIBS += pvData
|
||||
exampleEasyGet_LIBS += Com
|
||||
|
||||
#===========================
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
49
example/src/exampleEasyGet.cpp
Normal file
49
example/src/exampleEasyGet.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*exampleEasyGet.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <pv/easyPVA.h>
|
||||
#include <pv/clientFactory.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
ClientFactory::start();
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
|
||||
double value;
|
||||
try {
|
||||
cout << "short way\n";
|
||||
value = easyPVA->createChannel("exampleDouble")->createGet()->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "long way\n";
|
||||
EasyChannelPtr easyChannel = easyPVA->createChannel("exampleDouble");
|
||||
easyChannel->connect(2.0);
|
||||
EasyGetPtr easyGet = easyChannel->createGet();
|
||||
value = easyGet->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
cout << "done\n";
|
||||
ClientFactory::stop();
|
||||
return 0;
|
||||
}
|
69
example/src/exampleEasyPVStructure.cpp
Normal file
69
example/src/exampleEasyPVStructure.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/*exampleEasyPVStructure.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <pv/easyPVA.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
|
||||
StandardPVFieldPtr standardPVField = getStandardPVField();
|
||||
EasyPVStructurePtr easyStruct = easyPVA->createEasyPVStructure();
|
||||
PVStructurePtr pvStructure = standardPVField->scalar(pvDouble,"alarm,timeStamp");
|
||||
easyStruct->setPVStructure(pvStructure);
|
||||
cout << easyStruct->getPVStructure() << endl;
|
||||
cout << "as double " << easyStruct->getDouble() << endl;
|
||||
cout << "as float " << easyStruct->getFloat() << endl;
|
||||
try {
|
||||
cout << "as ubyte " << easyStruct->getUByte() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
pvStructure = standardPVField->scalar(pvInt,"alarm,timeStamp");
|
||||
easyStruct->setPVStructure(pvStructure);
|
||||
cout << easyStruct->getPVStructure() << endl;
|
||||
cout << "as double " << easyStruct->getDouble() << endl;
|
||||
cout << "as float " << easyStruct->getFloat() << endl;
|
||||
cout << "as int " << easyStruct->getInt() << endl;
|
||||
cout << "as uint " << easyStruct->getUInt() << endl;
|
||||
cout << "as long " << easyStruct->getLong() << endl;
|
||||
cout << "as ulong " << easyStruct->getULong() << endl;
|
||||
try {
|
||||
cout << "as byte " << easyStruct->getByte() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "as ubyte " << easyStruct->getUByte() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "as short " << easyStruct->getShort() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "as ushort " << easyStruct->getUShort() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
22
src/Makefile
Normal file
22
src/Makefile
Normal file
@ -0,0 +1,22 @@
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
LIBRARY += easyPVA
|
||||
|
||||
INC += easyPVA.h
|
||||
|
||||
LIBSRCS += easyPVA.cpp
|
||||
LIBSRCS += easyPVStructure.cpp
|
||||
LIBSRCS += easyChannel.cpp
|
||||
LIBSRCS += easyGet.cpp
|
||||
#LIBSRCS += easyPut.cpp
|
||||
#LIBSRCS += easyMonitor.cpp
|
||||
#LIBSRCS += easyRPC.cpp
|
||||
|
||||
easyPVA_LIBS += pvAccess pvData Com
|
||||
easyPVA_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
420
src/easyChannel.cpp
Normal file
420
src/easyChannel.cpp
Normal file
@ -0,0 +1,420 @@
|
||||
/* easyChannel.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2015.02
|
||||
*/
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <sstream>
|
||||
#include <pv/event.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/easyPVA.h>
|
||||
#include <pv/createRequest.h>
|
||||
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace easyPVA {
|
||||
|
||||
class epicsShareClass EasyChannelImpl :
|
||||
public EasyChannel,
|
||||
public std::tr1::enable_shared_from_this<EasyChannelImpl>
|
||||
{
|
||||
public:
|
||||
EasyChannelImpl(
|
||||
EasyPVAPtr const &pva,
|
||||
string const & channelName,
|
||||
string const & providerName);
|
||||
~EasyChannelImpl();
|
||||
// from EasyChannel
|
||||
void channelCreated(const Status& status, Channel::shared_pointer const & channel);
|
||||
void channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState);
|
||||
tr1::shared_ptr<Channel> getChannel();
|
||||
string getRequesterName();
|
||||
void message(
|
||||
string const & message,
|
||||
MessageType messageType);
|
||||
virtual void destroy();
|
||||
virtual string getChannelName();
|
||||
virtual void connect(double timeout);
|
||||
virtual void issueConnect();
|
||||
virtual Status waitConnect(double timeout);
|
||||
virtual EasyFieldPtr createField();
|
||||
virtual EasyFieldPtr createField(string const & subField);
|
||||
virtual EasyProcessPtr createProcess();
|
||||
virtual EasyProcessPtr createProcess(string const & request);
|
||||
virtual EasyProcessPtr createProcess(PVStructurePtr const & pvRequest);
|
||||
virtual EasyGetPtr createGet();
|
||||
virtual EasyGetPtr createGet(string const & request);
|
||||
virtual EasyGetPtr createGet(PVStructurePtr const & pvRequest);
|
||||
virtual EasyPutPtr createPut();
|
||||
virtual EasyPutPtr createPut(string const & request);
|
||||
virtual EasyPutPtr createPut(PVStructurePtr const & pvRequest);
|
||||
virtual EasyPutGetPtr createPutGet();
|
||||
virtual EasyPutGetPtr createPutGet(string const & request);
|
||||
virtual EasyPutGetPtr createPutGet(PVStructurePtr const & pvRequest);
|
||||
virtual EasyRPCPtr createRPC();
|
||||
virtual EasyRPCPtr createRPC(string const & request);
|
||||
virtual EasyRPCPtr createRPC(PVStructurePtr const & pvRequest);
|
||||
virtual EasyArrayPtr createArray();
|
||||
virtual EasyArrayPtr createArray(string const & request);
|
||||
virtual EasyArrayPtr createArray(PVStructurePtr const & pvRequest);
|
||||
virtual EasyMonitorPtr createMonitor();
|
||||
virtual EasyMonitorPtr createMonitor(string const & request);
|
||||
virtual EasyMonitorPtr createMonitor(PVStructurePtr const & pvRequest);
|
||||
|
||||
EasyChannelPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
private:
|
||||
enum ConnectState {connectIdle,connectActive,notConnected,connected};
|
||||
|
||||
EasyPVAPtr easyPVA;
|
||||
string channelName;
|
||||
string providerName;
|
||||
ConnectState connectState;
|
||||
bool isDestroyed;
|
||||
CreateRequest::shared_pointer createRequest;
|
||||
|
||||
Status channelConnectStatus;
|
||||
Mutex mutex;
|
||||
Event waitForConnect;
|
||||
Channel::shared_pointer channel;
|
||||
ChannelRequester::shared_pointer channelRequester;
|
||||
|
||||
};
|
||||
|
||||
namespace easyChannel {
|
||||
class ChannelRequesterImpl : public ChannelRequester
|
||||
{
|
||||
EasyChannelImpl *easyChannel;
|
||||
public:
|
||||
ChannelRequesterImpl(EasyChannelImpl *easyChannel)
|
||||
: easyChannel(easyChannel) {}
|
||||
virtual void channelCreated(
|
||||
const Status& status,
|
||||
Channel::shared_pointer const & channel)
|
||||
{ easyChannel->channelCreated(status,channel); }
|
||||
virtual void channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState)
|
||||
{easyChannel->channelStateChange(channel,connectionState);}
|
||||
virtual tr1::shared_ptr<Channel> getChannel() {return easyChannel->getChannel();}
|
||||
virtual string getRequesterName()
|
||||
{return easyChannel->getRequesterName();}
|
||||
virtual void message(
|
||||
string const & message,
|
||||
MessageType messageType)
|
||||
{ easyChannel->message(message,messageType); }
|
||||
virtual void destroy() {easyChannel->destroy();}
|
||||
};
|
||||
} //end namespace easyChannel`
|
||||
|
||||
using namespace epics::easyPVA::easyChannel;
|
||||
|
||||
EasyChannelImpl::EasyChannelImpl(
|
||||
EasyPVAPtr const &easyPVA,
|
||||
string const & channelName,
|
||||
string const & providerName)
|
||||
: easyPVA(easyPVA),
|
||||
channelName(channelName),
|
||||
providerName(providerName),
|
||||
connectState(connectIdle),
|
||||
isDestroyed(false),
|
||||
createRequest(CreateRequest::create())
|
||||
{}
|
||||
|
||||
EasyChannelImpl::~EasyChannelImpl()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void EasyChannelImpl::channelCreated(const Status& status, Channel::shared_pointer const & channel)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
channelConnectStatus = status;
|
||||
this->channel = channel;
|
||||
}
|
||||
|
||||
void EasyChannelImpl::channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
bool waitingForConnect = false;
|
||||
if(connectState==connectActive) waitingForConnect = true;
|
||||
if(connectionState!=Channel::CONNECTED) {
|
||||
string mess(channelName + " connection state " + Channel::ConnectionStateNames[connectionState]);
|
||||
message(mess,errorMessage);
|
||||
channelConnectStatus = Status(Status::STATUSTYPE_ERROR,mess);
|
||||
connectState = notConnected;
|
||||
} else {
|
||||
connectState = connected;
|
||||
}
|
||||
if(waitingForConnect) waitForConnect.signal();
|
||||
}
|
||||
|
||||
tr1::shared_ptr<Channel> EasyChannelImpl::getChannel()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
return channel;
|
||||
}
|
||||
|
||||
string EasyChannelImpl::getRequesterName()
|
||||
{
|
||||
return easyPVA->getRequesterName();
|
||||
}
|
||||
|
||||
void EasyChannelImpl::message(
|
||||
string const & message,
|
||||
MessageType messageType)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
easyPVA->message(message, messageType);
|
||||
}
|
||||
|
||||
void EasyChannelImpl::destroy()
|
||||
{
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
}
|
||||
if(channel) channel->destroy();
|
||||
channel.reset();
|
||||
}
|
||||
|
||||
string EasyChannelImpl::getChannelName()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
return channelName;
|
||||
}
|
||||
|
||||
void EasyChannelImpl::connect(double timeout)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
issueConnect();
|
||||
Status status = waitConnect(timeout);
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << getChannelName() << " EasyChannel::connect " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyChannelImpl::issueConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
if(connectState!=connectIdle) {
|
||||
throw std::runtime_error("easyChannel already connected");
|
||||
}
|
||||
channelRequester = ChannelRequester::shared_pointer(new ChannelRequesterImpl(this));
|
||||
|
||||
connectState = connectActive;
|
||||
ChannelProviderRegistry::shared_pointer reg = getChannelProviderRegistry();
|
||||
ChannelProvider::shared_pointer provider = reg->getProvider(providerName);
|
||||
channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT);
|
||||
}
|
||||
|
||||
Status EasyChannelImpl::waitConnect(double timeout)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
waitForConnect.wait(timeout);
|
||||
if(connectState==connected) return Status::Ok;
|
||||
return Status(Status::STATUSTYPE_ERROR,channelConnectStatus.getMessage());
|
||||
}
|
||||
|
||||
EasyFieldPtr EasyChannelImpl::createField()
|
||||
{
|
||||
return createField("");
|
||||
}
|
||||
|
||||
EasyFieldPtr EasyChannelImpl::createField(string const & subField)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createField not implemented");
|
||||
}
|
||||
|
||||
EasyProcessPtr EasyChannelImpl::createProcess()
|
||||
{
|
||||
return createProcess("");
|
||||
}
|
||||
|
||||
EasyProcessPtr EasyChannelImpl::createProcess(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
stringstream ss;
|
||||
ss << "channel " << getChannelName();
|
||||
ss << " EasyChannel::createProcess invalid pvRequest: " + createRequest->getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
return createProcess(pvRequest);
|
||||
}
|
||||
|
||||
EasyProcessPtr EasyChannelImpl::createProcess(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createProcess not implemented");
|
||||
}
|
||||
|
||||
EasyGetPtr EasyChannelImpl::createGet()
|
||||
{
|
||||
return EasyChannelImpl::createGet("value,alarm.timeStamp");
|
||||
}
|
||||
|
||||
EasyGetPtr EasyChannelImpl::createGet(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
stringstream ss;
|
||||
ss << "channel " << getChannelName();
|
||||
ss << " EasyChannel::createGet invalid pvRequest: " + createRequest->getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
return createGet(pvRequest);
|
||||
}
|
||||
|
||||
EasyGetPtr EasyChannelImpl::createGet(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
if(connectState!=connected) connect(5.0);
|
||||
if(connectState!=connected) throw std::runtime_error("EasyChannel::creatGet not connected");
|
||||
return EasyGetFactory::createEasyGet(easyPVA,getPtrSelf(),channel,pvRequest);
|
||||
}
|
||||
|
||||
EasyPutPtr EasyChannelImpl::createPut()
|
||||
{
|
||||
return createPut("value");
|
||||
}
|
||||
|
||||
EasyPutPtr EasyChannelImpl::createPut(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
stringstream ss;
|
||||
ss << "channel " << getChannelName();
|
||||
ss << " EasyChannel::createPut invalid pvRequest: " + createRequest->getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
return createPut(pvRequest);
|
||||
}
|
||||
|
||||
EasyPutPtr EasyChannelImpl::createPut(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createPut not implemented");
|
||||
}
|
||||
|
||||
EasyPutGetPtr EasyChannelImpl::createPutGet()
|
||||
{
|
||||
return createPutGet("putField(argument)getField(result)");
|
||||
}
|
||||
|
||||
EasyPutGetPtr EasyChannelImpl::createPutGet(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
stringstream ss;
|
||||
ss << "channel " << getChannelName();
|
||||
ss << " EasyChannel::createPutGet invalid pvRequest: " + createRequest->getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
return createPutGet(pvRequest);
|
||||
}
|
||||
|
||||
EasyPutGetPtr EasyChannelImpl::createPutGet(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createPutGet not implemented");
|
||||
}
|
||||
|
||||
EasyRPCPtr EasyChannelImpl::createRPC()
|
||||
{
|
||||
return createRPC("");
|
||||
}
|
||||
|
||||
EasyRPCPtr EasyChannelImpl::createRPC(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
stringstream ss;
|
||||
ss << "channel " << getChannelName();
|
||||
ss << " EasyChannel::createRPC invalid pvRequest: " + createRequest->getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
return createRPC(pvRequest);
|
||||
}
|
||||
|
||||
EasyRPCPtr EasyChannelImpl::createRPC(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createRPC not implemented");
|
||||
}
|
||||
|
||||
EasyArrayPtr EasyChannelImpl::createArray()
|
||||
{
|
||||
return createArray("value");
|
||||
}
|
||||
|
||||
EasyArrayPtr EasyChannelImpl::createArray(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
stringstream ss;
|
||||
ss << "channel " << getChannelName();
|
||||
ss << " EasyChannel::createArray invalid pvRequest: " + createRequest->getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
return createArray(pvRequest);
|
||||
}
|
||||
|
||||
EasyArrayPtr EasyChannelImpl::createArray(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createArray not implemented");
|
||||
}
|
||||
|
||||
EasyMonitorPtr EasyChannelImpl::createMonitor()
|
||||
{
|
||||
return createMonitor("value,alarm,timeStamp");
|
||||
}
|
||||
|
||||
EasyMonitorPtr EasyChannelImpl::createMonitor(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
stringstream ss;
|
||||
ss << "channel " << getChannelName();
|
||||
ss << " EasyChannel::createMonitor invalid pvRequest: " + createRequest->getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
return createMonitor(pvRequest);
|
||||
}
|
||||
|
||||
EasyMonitorPtr EasyChannelImpl::createMonitor(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createMonitor not implemented");
|
||||
}
|
||||
|
||||
|
||||
EasyChannelPtr EasyChannelFactory::createEasyChannel(
|
||||
EasyPVAPtr const &easyPVA,
|
||||
string const & channelName)
|
||||
{
|
||||
return EasyChannelFactory::createEasyChannel(easyPVA,channelName,"pva");
|
||||
}
|
||||
|
||||
EasyChannelPtr EasyChannelFactory::createEasyChannel(
|
||||
EasyPVAPtr const &easyPVA,
|
||||
string const & channelName,
|
||||
string const & providerName)
|
||||
{
|
||||
EasyChannelPtr channel(new EasyChannelImpl(easyPVA,channelName,providerName));
|
||||
return channel;
|
||||
}
|
||||
|
||||
}}
|
551
src/easyGet.cpp
Normal file
551
src/easyGet.cpp
Normal file
@ -0,0 +1,551 @@
|
||||
/* easyGet.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2015.02
|
||||
*/
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <sstream>
|
||||
#include <pv/event.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/easyPVA.h>
|
||||
#include <pv/createRequest.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace easyPVA {
|
||||
|
||||
|
||||
|
||||
class epicsShareClass EasyGetImpl :
|
||||
public EasyGet,
|
||||
public std::tr1::enable_shared_from_this<EasyGetImpl>
|
||||
{
|
||||
public:
|
||||
EasyGetImpl(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest);
|
||||
~EasyGetImpl();
|
||||
// from ChannelGetRequester
|
||||
string getRequesterName();
|
||||
void message(string const & message,MessageType messageType);
|
||||
void channelGetConnect(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
StructureConstPtr const & structure);
|
||||
void getDone(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
PVStructurePtr const & pvStructure,
|
||||
BitSetPtr const & bitSet);
|
||||
|
||||
// from EasyGet
|
||||
virtual void destroy();
|
||||
virtual void connect();
|
||||
virtual void issueConnect();
|
||||
virtual Status waitConnect();
|
||||
virtual void get();
|
||||
virtual void issueGet();
|
||||
virtual Status waitGet();
|
||||
virtual BitSetPtr getBitSet();
|
||||
// from EasyPVStructure
|
||||
virtual void setMessagePrefix(std::string const & value);
|
||||
virtual void setPVStructure(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
virtual Alarm getAlarm();
|
||||
virtual TimeStamp getTimeStamp();
|
||||
virtual bool hasValue();
|
||||
virtual bool isValueScalar();
|
||||
virtual bool isValueScalarArray();
|
||||
virtual PVFieldPtr getValue();
|
||||
virtual PVScalarPtr getScalarValue();
|
||||
virtual std::tr1::shared_ptr<PVArray> getArrayValue();
|
||||
virtual std::tr1::shared_ptr<PVScalarArray> getScalarArrayValue();
|
||||
virtual bool getBoolean();
|
||||
virtual int8 getByte();
|
||||
virtual int16 getShort();
|
||||
virtual int32 getInt();
|
||||
virtual int64 getLong();
|
||||
virtual uint8 getUByte();
|
||||
virtual uint16 getUShort();
|
||||
virtual uint32 getUInt();
|
||||
virtual uint64 getULong();
|
||||
virtual float getFloat();
|
||||
virtual double getDouble();
|
||||
virtual std::string getString();
|
||||
|
||||
virtual shared_vector<boolean> getBooleanArray();
|
||||
virtual shared_vector<int8> getByteArray();
|
||||
virtual shared_vector<int16> getShortArray();
|
||||
virtual shared_vector<int32> getIntArray();
|
||||
virtual shared_vector<int64> getLongArray();
|
||||
virtual shared_vector<uint8> getUByteArray();
|
||||
virtual shared_vector<uint16> getUShortArray();
|
||||
virtual shared_vector<uint32> getUIntArray();
|
||||
virtual shared_vector<uint64> getULongArray();
|
||||
virtual shared_vector<float> getFloatArray();
|
||||
virtual shared_vector<double> getDoubleArray();
|
||||
virtual shared_vector<std::string> getStringArray();
|
||||
virtual PVStructurePtr getPVStructure();
|
||||
EasyGetPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
private:
|
||||
enum GetConnectState {connectIdle,connectActive,connected};
|
||||
|
||||
EasyPVAPtr easyPVA;
|
||||
EasyChannelPtr easyChannel;
|
||||
Channel::shared_pointer channel;
|
||||
ChannelGetRequester::shared_pointer getRequester;
|
||||
PVStructurePtr pvRequest;
|
||||
Mutex mutex;
|
||||
Event waitForConnect;
|
||||
Event waitForGet;
|
||||
EasyPVStructurePtr easyPVStructure;
|
||||
string messagePrefix;
|
||||
|
||||
bool isDestroyed;
|
||||
Status channelGetConnectStatus;
|
||||
Status channelGetStatus;
|
||||
ChannelGet::shared_pointer channelGet;
|
||||
BitSet::shared_pointer bitSet;
|
||||
|
||||
GetConnectState connectState;
|
||||
|
||||
enum GetState {getIdle,getActive,getComplete};
|
||||
GetState getState;
|
||||
bool getSuccess;
|
||||
};
|
||||
|
||||
namespace easyGet {
|
||||
class ChannelGetRequesterImpl : public ChannelGetRequester
|
||||
{
|
||||
EasyGetImpl * easyGet;
|
||||
public:
|
||||
ChannelGetRequesterImpl(EasyGetImpl * easyGet)
|
||||
: easyGet(easyGet) {}
|
||||
virtual string getRequesterName()
|
||||
{return easyGet->getRequesterName();}
|
||||
virtual void message(string const & message,MessageType messageType)
|
||||
{easyGet->message(message,messageType);}
|
||||
virtual void channelGetConnect(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
StructureConstPtr const & structure)
|
||||
{easyGet->channelGetConnect(status,channelGet,structure);}
|
||||
virtual void getDone(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
PVStructurePtr const & pvStructure,
|
||||
BitSetPtr const & bitSet)
|
||||
{easyGet->getDone(status,channelGet,pvStructure,bitSet);}
|
||||
};
|
||||
} // namespace easyGet
|
||||
|
||||
using namespace epics::easyPVA::easyGet;
|
||||
|
||||
EasyGetImpl::EasyGetImpl(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest)
|
||||
: easyPVA(pva),
|
||||
easyChannel(easyChannel),
|
||||
channel(channel),
|
||||
pvRequest(pvRequest),
|
||||
easyPVStructure(pva->createEasyPVStructure()),
|
||||
isDestroyed(false),
|
||||
connectState(connectIdle),
|
||||
getState(getIdle)
|
||||
{
|
||||
easyPVStructure->setMessagePrefix("channel " + channel->getChannelName() + " EasyGet");
|
||||
}
|
||||
|
||||
EasyGetImpl::~EasyGetImpl()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
|
||||
// from ChannelGetRequester
|
||||
string EasyGetImpl::getRequesterName()
|
||||
{
|
||||
return easyPVA->getRequesterName();
|
||||
}
|
||||
|
||||
void EasyGetImpl::message(string const & message,MessageType messageType)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
easyPVA->message(message, messageType);
|
||||
}
|
||||
|
||||
void EasyGetImpl::channelGetConnect(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
StructureConstPtr const & structure)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
channelGetConnectStatus = status;
|
||||
this->channelGet = channelGet;
|
||||
if(status.isOK()) {
|
||||
connectState = connected;
|
||||
} else {
|
||||
connectState = connectIdle;
|
||||
}
|
||||
waitForConnect.signal();
|
||||
|
||||
}
|
||||
|
||||
void EasyGetImpl::getDone(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
PVStructurePtr const & pvStructure,
|
||||
BitSetPtr const & bitSet)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
easyPVStructure->setPVStructure(pvStructure);
|
||||
this->bitSet = bitSet;
|
||||
channelGetStatus = status;
|
||||
if(status.isOK()) {
|
||||
getState = getComplete;
|
||||
} else {
|
||||
getState = getIdle;
|
||||
}
|
||||
waitForGet.signal();
|
||||
}
|
||||
|
||||
|
||||
// from EasyGet
|
||||
void EasyGetImpl::destroy()
|
||||
{
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
}
|
||||
if(channelGet) channelGet->destroy();
|
||||
channelGet.reset();
|
||||
}
|
||||
|
||||
void EasyGetImpl::connect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
issueConnect();
|
||||
Status status = waitConnect();
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyGet::connect " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyGetImpl::issueConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
if(connectState!=connectIdle) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " easyGet already connected ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
getRequester = ChannelGetRequester::shared_pointer(new ChannelGetRequesterImpl(this));
|
||||
|
||||
connectState = connectActive;
|
||||
channelGet = channel->createChannelGet(getRequester,pvRequest);
|
||||
}
|
||||
|
||||
Status EasyGetImpl::waitConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
if(connectState!=connectActive) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " easyGet illegal connect state ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
waitForConnect.wait();
|
||||
if(connectState==connected) return Status::Ok;
|
||||
return Status(Status::STATUSTYPE_ERROR,channelGetConnectStatus.getMessage());
|
||||
}
|
||||
|
||||
void EasyGetImpl::get()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
issueGet();
|
||||
Status status = waitGet();
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyGet::get " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyGetImpl::issueGet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
if(connectState==connectIdle) connect();
|
||||
if(getState!=getIdle) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyGet::issueGet get aleady active ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
getState = getActive;
|
||||
channelGet->get();
|
||||
}
|
||||
|
||||
Status EasyGetImpl::waitGet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
if(getState!=getActive){
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyGet::waitGet llegal get state";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
waitForGet.wait();
|
||||
if(getState==getComplete) {
|
||||
getState = getIdle;
|
||||
return Status::Ok;
|
||||
}
|
||||
return Status(Status::STATUSTYPE_ERROR,channelGetStatus.getMessage());
|
||||
}
|
||||
|
||||
BitSetPtr EasyGetImpl::getBitSet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return bitSet;
|
||||
}
|
||||
|
||||
void EasyGetImpl::setMessagePrefix(string const & value)
|
||||
{
|
||||
messagePrefix = value;
|
||||
if(value.size()>0) messagePrefix += " ";
|
||||
}
|
||||
|
||||
void EasyGetImpl::setPVStructure(epics::pvData::PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
throw std::runtime_error("easyGet does not implement setPVStructure");
|
||||
}
|
||||
|
||||
Alarm EasyGetImpl::getAlarm()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getAlarm();
|
||||
}
|
||||
|
||||
TimeStamp EasyGetImpl::getTimeStamp()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getTimeStamp();
|
||||
}
|
||||
|
||||
bool EasyGetImpl::hasValue()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->hasValue();
|
||||
}
|
||||
|
||||
bool EasyGetImpl::isValueScalar()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->isValueScalar();
|
||||
}
|
||||
|
||||
bool EasyGetImpl::isValueScalarArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->isValueScalarArray();
|
||||
}
|
||||
|
||||
PVFieldPtr EasyGetImpl::getValue()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getValue();
|
||||
}
|
||||
|
||||
PVScalarPtr EasyGetImpl::getScalarValue()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getScalarValue();
|
||||
}
|
||||
|
||||
std::tr1::shared_ptr<PVArray> EasyGetImpl::getArrayValue()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getArrayValue();
|
||||
}
|
||||
|
||||
std::tr1::shared_ptr<PVScalarArray> EasyGetImpl::getScalarArrayValue()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getScalarArrayValue();
|
||||
}
|
||||
|
||||
bool EasyGetImpl::getBoolean()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getBoolean();
|
||||
}
|
||||
|
||||
int8 EasyGetImpl::getByte()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getByte();
|
||||
}
|
||||
|
||||
int16 EasyGetImpl::getShort()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getShort();
|
||||
}
|
||||
|
||||
int32 EasyGetImpl::getInt()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getInt();
|
||||
}
|
||||
|
||||
int64 EasyGetImpl::getLong()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getLong();
|
||||
}
|
||||
|
||||
uint8 EasyGetImpl::getUByte()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getUByte();
|
||||
}
|
||||
|
||||
uint16 EasyGetImpl::getUShort()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getUShort();
|
||||
}
|
||||
|
||||
uint32 EasyGetImpl::getUInt()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getUInt();
|
||||
}
|
||||
|
||||
uint64 EasyGetImpl::getULong()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getULong();
|
||||
}
|
||||
|
||||
float EasyGetImpl::getFloat()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getFloat();
|
||||
}
|
||||
|
||||
double EasyGetImpl::getDouble()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->isValueScalar();
|
||||
}
|
||||
|
||||
std::string EasyGetImpl::getString()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getString();
|
||||
}
|
||||
|
||||
|
||||
shared_vector<boolean> EasyGetImpl::getBooleanArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getBooleanArray();
|
||||
}
|
||||
|
||||
shared_vector<int8> EasyGetImpl::getByteArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getByteArray();
|
||||
}
|
||||
|
||||
shared_vector<int16> EasyGetImpl::getShortArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getShortArray();
|
||||
}
|
||||
|
||||
shared_vector<int32> EasyGetImpl::getIntArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getIntArray();
|
||||
}
|
||||
|
||||
shared_vector<int64> EasyGetImpl::getLongArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getLongArray();
|
||||
}
|
||||
|
||||
shared_vector<uint8> EasyGetImpl::getUByteArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getUByteArray();
|
||||
}
|
||||
|
||||
shared_vector<uint16> EasyGetImpl::getUShortArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getUShortArray();
|
||||
}
|
||||
|
||||
shared_vector<uint32> EasyGetImpl::getUIntArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getUIntArray();
|
||||
}
|
||||
|
||||
shared_vector<uint64> EasyGetImpl::getULongArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getULongArray();
|
||||
}
|
||||
|
||||
shared_vector<float> EasyGetImpl::getFloatArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getFloatArray();
|
||||
}
|
||||
|
||||
shared_vector<double> EasyGetImpl::getDoubleArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getDoubleArray();
|
||||
}
|
||||
|
||||
shared_vector<std::string> EasyGetImpl::getStringArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getStringArray();
|
||||
}
|
||||
|
||||
PVStructurePtr EasyGetImpl::getPVStructure()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->getPVStructure();
|
||||
}
|
||||
|
||||
EasyGetPtr EasyGetFactory::createEasyGet(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest)
|
||||
{
|
||||
EasyGetPtr epv(new EasyGetImpl(pva,easyChannel,channel,pvRequest));
|
||||
return epv;
|
||||
}
|
||||
|
||||
}}
|
105
src/easyPVA.cpp
Normal file
105
src/easyPVA.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/* easyPVA.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2015.02
|
||||
*/
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/easyPVA.h>
|
||||
#include <pv/createRequest.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace easyPVA {
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static const string easyPVAName = "easyPVA";
|
||||
static const string defaultProvider = "pva";
|
||||
static UnionConstPtr variantUnion = fieldCreate->createVariantUnion();
|
||||
|
||||
EasyPVAPtr EasyPVA::create()
|
||||
{
|
||||
EasyPVAPtr xx(new EasyPVA());
|
||||
return xx;
|
||||
}
|
||||
|
||||
PVStructurePtr EasyPVA::createRequest(string const &request)
|
||||
{
|
||||
CreateRequest::shared_pointer createRequest = CreateRequest::create();
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
throw std::invalid_argument("invalid pvRequest: " + createRequest->getMessage());
|
||||
}
|
||||
return pvRequest;
|
||||
}
|
||||
|
||||
EasyPVA::EasyPVA()
|
||||
: isDestroyed(false)
|
||||
{
|
||||
}
|
||||
|
||||
EasyPVA::~EasyPVA() {destroy();}
|
||||
|
||||
void EasyPVA::destroy()
|
||||
{
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
}
|
||||
std::list<EasyChannelPtr>::iterator channelIter;
|
||||
while(true) {
|
||||
channelIter = channelList.begin();
|
||||
if(channelIter==channelList.end()) break;
|
||||
channelList.erase(channelIter);
|
||||
(*channelIter)->destroy();
|
||||
}
|
||||
std::list<EasyMultiChannelPtr>::iterator multiChannelIter;
|
||||
#ifdef NOTDONE
|
||||
while(true) {
|
||||
multiChannelIter = multiChannelList.begin();
|
||||
if(multiChannelIter==multiChannelList.end()) break;
|
||||
multiChannelList.erase(multiChannelIter);
|
||||
(*multiChannelIter)->destroy();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
string EasyPVA:: getRequesterName()
|
||||
{
|
||||
static string name("easyPVA");
|
||||
return name;
|
||||
}
|
||||
|
||||
void EasyPVA::message(
|
||||
string const & message,
|
||||
MessageType messageType)
|
||||
{
|
||||
cout << getMessageTypeName(messageType) << " " << message << endl;
|
||||
}
|
||||
|
||||
EasyPVStructurePtr EasyPVA::createEasyPVStructure()
|
||||
{
|
||||
return EasyPVStructureFactory::createEasyPVStructure();
|
||||
}
|
||||
|
||||
EasyChannelPtr EasyPVA::createChannel(string const & channelName)
|
||||
{
|
||||
return EasyChannelFactory::createEasyChannel(getPtrSelf(),channelName);
|
||||
}
|
||||
|
||||
EasyChannelPtr EasyPVA::createChannel(string const & channelName, string const & providerName)
|
||||
{
|
||||
return EasyChannelFactory::createEasyChannel(getPtrSelf(),channelName,providerName);
|
||||
}
|
||||
|
||||
}}
|
||||
|
721
src/easyPVA.h
Normal file
721
src/easyPVA.h
Normal file
@ -0,0 +1,721 @@
|
||||
/* easyPVA.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2015.02
|
||||
*/
|
||||
#ifndef EASYPVA_H
|
||||
#define EASYPVA_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define easyPVAEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <list>
|
||||
#include <pv/requester.h>
|
||||
#include <pv/status.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvCopy.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/pvAlarm.h>
|
||||
#include <pv/alarm.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/createRequest.h>
|
||||
|
||||
#ifdef easyPVAEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef easyPVAEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
|
||||
namespace epics { namespace easyPVA {
|
||||
|
||||
class EasyPVA;
|
||||
typedef std::tr1::shared_ptr<EasyPVA> EasyPVAPtr;
|
||||
class EasyPVStructure;
|
||||
typedef std::tr1::shared_ptr<EasyPVStructure> EasyPVStructurePtr;
|
||||
class EasyChannel;
|
||||
typedef std::tr1::shared_ptr<EasyChannel> EasyChannelPtr;
|
||||
class EasyField;
|
||||
typedef std::tr1::shared_ptr<EasyField> EasyFieldPtr;
|
||||
class EasyProcess;
|
||||
typedef std::tr1::shared_ptr<EasyProcess> EasyProcessPtr;
|
||||
class EasyGet;
|
||||
typedef std::tr1::shared_ptr<EasyGet> EasyGetPtr;
|
||||
class EasyPut;
|
||||
typedef std::tr1::shared_ptr<EasyPut> EasyPutPtr;
|
||||
class EasyPutGet;
|
||||
typedef std::tr1::shared_ptr<EasyPutGet> EasyPutGetPtr;
|
||||
class EasyMonitor;
|
||||
typedef std::tr1::shared_ptr<EasyMonitor> EasyMonitorPtr;
|
||||
class EasyArray;
|
||||
typedef std::tr1::shared_ptr<EasyArray> EasyArrayPtr;
|
||||
class EasyRPC;
|
||||
typedef std::tr1::shared_ptr<EasyRPC> EasyRPCPtr;
|
||||
|
||||
class EasyMultiData;
|
||||
typedef std::tr1::shared_ptr<EasyMultiData> EasyMultiDataPtr;
|
||||
class EasyMultiChannel;
|
||||
typedef std::tr1::shared_ptr<EasyMultiChannel> EasyMultiChannelPtr;
|
||||
class EasyMultiGet;
|
||||
typedef std::tr1::shared_ptr<EasyMultiGet> EasyMultiGetPtr;
|
||||
class EasyMultiPut;
|
||||
typedef std::tr1::shared_ptr<EasyMultiPut> EasyMultiPutPtr;
|
||||
class EasyMultiMonitor;
|
||||
typedef std::tr1::shared_ptr<EasyMultiMonitor> EasyMultiMonitorPtr;
|
||||
|
||||
/**
|
||||
* @brief EasyPVA is an easy to use interface to pvAccess.
|
||||
*
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass EasyPVA :
|
||||
public epics::pvData::Requester,
|
||||
public std::tr1::enable_shared_from_this<EasyPVA>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(EasyPVA);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~EasyPVA();
|
||||
/**
|
||||
* @brief Create an instance of EasyPVA
|
||||
* @return shared_ptr to new instance.
|
||||
*/
|
||||
static EasyPVAPtr create();
|
||||
/** @brief get the requester name.
|
||||
* @return The name.
|
||||
*/
|
||||
virtual std::string getRequesterName();
|
||||
/**
|
||||
* @brief A new message.
|
||||
* If a requester is set then it is called otherwise message is displayed
|
||||
* on standard out.
|
||||
* @param message The message.
|
||||
* @param messageType The type.
|
||||
*/
|
||||
virtual void message(
|
||||
std::string const & message,
|
||||
epics::pvData::MessageType messageType);
|
||||
|
||||
/**
|
||||
* @brief Destroy all the channels and multiChannels.
|
||||
*/
|
||||
void destroy();
|
||||
/**
|
||||
* @brief Create a EasyPVStructure.
|
||||
* @return The interface to the EasyPVStructure.
|
||||
*/
|
||||
EasyPVStructurePtr createEasyPVStructure();
|
||||
/**
|
||||
* @brief Create an EasyChannel. The provider is pvAccess.
|
||||
* @param channelName The channelName.
|
||||
* @return The interface.
|
||||
*/
|
||||
EasyChannelPtr createChannel(std::string const & channelName);
|
||||
/**
|
||||
* @brief Create an EasyChannel with the specified provider.
|
||||
* @param channelName The channelName.
|
||||
* @param providerName The provider.
|
||||
* @return The interface or null if the provider does not exist.
|
||||
*/
|
||||
EasyChannelPtr createChannel(
|
||||
std::string const & channelName,
|
||||
std::string const & providerName);
|
||||
/**
|
||||
* @brief Create an EasyMultiChannel. The provider is pvAccess.
|
||||
* @param channelName The channelName array.
|
||||
* @return The interface.
|
||||
*/
|
||||
EasyMultiChannelPtr createMultiChannel(epics::pvData::StringArray const & channelName);
|
||||
/**
|
||||
* @brief Create an EasyMultiChannel with the specified provider.
|
||||
* @param channelName The channelName array.
|
||||
* @param providerName The provider.
|
||||
* @return The interface.
|
||||
*/
|
||||
EasyMultiChannelPtr createMultiChannel(
|
||||
epics::pvData::StringArray const & channelName,
|
||||
std::string const & providerName);
|
||||
/**
|
||||
* @brief Create an EasyMultiChannel with the specified provider.
|
||||
* @param channelName The channelName.
|
||||
* @param providerName The provider.
|
||||
* @param union The union interface for the value field of each channel.
|
||||
* @return The interface.
|
||||
*/
|
||||
EasyMultiChannelPtr createMultiChannel(
|
||||
epics::pvData::StringArray const & channelName,
|
||||
std::string const & providerName,
|
||||
epics::pvData::UnionConstPtr const & u);
|
||||
/**
|
||||
* @brief Set a requester.
|
||||
* The default is for EasyPVA to handle messages by printing to System.out.
|
||||
* @param requester The requester.
|
||||
*/
|
||||
void setRequester(epics::pvData::RequesterPtr const & requester);
|
||||
/**
|
||||
* @brief Clear the requester. EasyPVA will handle messages.
|
||||
*/
|
||||
void clearRequester();
|
||||
/**
|
||||
* @brief get shared pointer to this
|
||||
*/
|
||||
EasyPVAPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
private:
|
||||
EasyPVA();
|
||||
epics::pvData::PVStructurePtr createRequest(std::string const &request);
|
||||
|
||||
std::list<EasyChannelPtr> channelList;
|
||||
std::list<EasyMultiChannelPtr> multiChannelList;
|
||||
epics::pvData::RequesterPtr requester;
|
||||
bool isDestroyed;
|
||||
epics::pvData::Mutex mutex;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An easy to use alternative to directly calling the Channel methods of pvAccess.
|
||||
*
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass EasyChannel
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(EasyChannel);
|
||||
/**
|
||||
* @brief Destroy the pvAccess connection.
|
||||
*/
|
||||
virtual void destroy() = 0;
|
||||
/**
|
||||
* @brief Get the name of the channel to which EasyChannel is connected.
|
||||
* @return The channel name.
|
||||
*/
|
||||
virtual std::string getChannelName() = 0;
|
||||
/**
|
||||
* @brief Connect to the channel.
|
||||
* This calls issueConnect and waitConnect.
|
||||
* An exception is thrown if connect fails.
|
||||
* @param timeout The time to wait for connecting to the channel.
|
||||
*/
|
||||
virtual void connect(double timeout) = 0;
|
||||
/**
|
||||
* @brief Issue a connect request and return immediately.
|
||||
*/
|
||||
virtual void issueConnect() = 0;
|
||||
/**
|
||||
* @brief Wait until the connection completes or for timeout.
|
||||
* @param timeout The time in second to wait.
|
||||
* @return status.
|
||||
*/
|
||||
virtual epics::pvData::Status waitConnect(double timeout) = 0;
|
||||
/**
|
||||
* @brief Calls the next method with subField = "";
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyFieldPtr createField() = 0;
|
||||
/**
|
||||
* @brief Create an EasyField for the specified subField.
|
||||
* @param subField The syntax for subField is defined in package org.epics.pvdata.copy
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyFieldPtr createField(std::string const & subField) = 0;
|
||||
/**
|
||||
* @brief Calls the next method with request = "";
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyProcessPtr createProcess() = 0;
|
||||
/**
|
||||
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
|
||||
* @param request The request as described in package org.epics.pvdata.copy
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyProcessPtr createProcess(std::string const & request) = 0;
|
||||
/**
|
||||
* @brief Creates an EasyProcess.
|
||||
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyProcessPtr createProcess(epics::pvData::PVStructurePtr const & pvRequest) = 0;
|
||||
/**
|
||||
* @brief Call the next method with request = "field(value,alarm,timeStamp)"
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyGetPtr createGet() = 0;
|
||||
/**
|
||||
* @brief First call createRequest as implemented by pvDataJava and then call the next method.
|
||||
* @param request The request as described in package org.epics.pvdata.copy
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyGetPtr createGet(std::string const & request) = 0;
|
||||
/**
|
||||
* @brief Creates an EasyGet.
|
||||
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyGetPtr createGet(epics::pvData::PVStructurePtr const & pvRequest) = 0;
|
||||
/**
|
||||
* @brief Call the next method with request = "field(value)"
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyPutPtr createPut() = 0;
|
||||
/**
|
||||
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
|
||||
* @param request The request as described in package org.epics.pvdata.copy
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyPutPtr createPut(std::string const & request) = 0;
|
||||
/**
|
||||
* @brief Create an EasyPut.
|
||||
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyPutPtr createPut(epics::pvData::PVStructurePtr const & pvRequest) = 0;
|
||||
/**
|
||||
* @brief Call the next method with request = "record[process=true]putField(argument)getField(result)".
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyPutGetPtr createPutGet() = 0;
|
||||
/**
|
||||
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
|
||||
* @param request The request as described in package org.epics.pvdata.copy
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyPutGetPtr createPutGet(std::string const & request) = 0;
|
||||
/**
|
||||
* @brief Create an EasyPutGet.
|
||||
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyPutGetPtr createPutGet(epics::pvData::PVStructurePtr const & pvRequest) = 0;
|
||||
/**
|
||||
* @brief Call createRPC(PVStructure(null))
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyRPCPtr createRPC() = 0;
|
||||
/**
|
||||
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
|
||||
* @param request The request as described in package org.epics.pvdata.copy
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyRPCPtr createRPC(std::string const & request) = 0;
|
||||
/**
|
||||
* @brief Create an EasyRPC.
|
||||
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyRPCPtr createRPC(epics::pvData::PVStructurePtr const & pvRequest) = 0;
|
||||
/**
|
||||
* @brief Call the next method with request = "field(value)";
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyArrayPtr createArray() = 0;
|
||||
/**
|
||||
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
|
||||
* @param request The request as described in package org.epics.pvdata.copy
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyArrayPtr createArray(std::string const & request) = 0;
|
||||
/**
|
||||
* @brief Create an EasyArray.
|
||||
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyArrayPtr createArray(epics::pvData::PVStructurePtr const & pvRequest) = 0;
|
||||
/**
|
||||
* @brief Call the next method with request = "field(value.alarm,timeStamp)"
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyMonitorPtr createMonitor() = 0;
|
||||
/**
|
||||
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
|
||||
* @param request The request as described in package org.epics.pvdata.copy
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyMonitorPtr createMonitor(std::string const & request) = 0;
|
||||
/**
|
||||
* @brief Create an EasyMonitor.
|
||||
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyMonitorPtr createMonitor(epics::pvData::PVStructurePtr const & pvRequest) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This is a factory for creating an EasyChannel
|
||||
*
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass EasyChannelFactory
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create a EasyPVAStructure.
|
||||
* @param easyPVA Interface to EasyPVA
|
||||
* @param channelName The name of the channel.
|
||||
* @return The interface to the EasyPVAStructure.
|
||||
*/
|
||||
static EasyChannelPtr createEasyChannel(
|
||||
EasyPVAPtr const &easyPVA,
|
||||
std::string const & channelName);
|
||||
/**
|
||||
* @brief Create a EasyPVAStructure.
|
||||
* @param channelName The name of the channel.
|
||||
* @param providerName The name of the provider.
|
||||
* @return The interface to the EasyPVAStructure.
|
||||
*/
|
||||
static EasyChannelPtr createEasyChannel(
|
||||
EasyPVAPtr const &easyPVA,
|
||||
std::string const & channelName,
|
||||
std::string const & providerName);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This is a convenience wrapper for a PVStructure.
|
||||
*
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass EasyPVStructure
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(EasyPVStructure);
|
||||
/**
|
||||
* @brief Set a prefix to be added to any messages generated by EasyPVStructure.
|
||||
* @param value The prefix.
|
||||
*/
|
||||
virtual void setMessagePrefix(std::string const & value) = 0;
|
||||
/**
|
||||
* @brief Set the pvStructure on which the remaining methods operate.
|
||||
* @param pvStructure The structure.
|
||||
*/
|
||||
virtual void setPVStructure(epics::pvData::PVStructurePtr const & pvStructure) = 0;
|
||||
/**
|
||||
* @brief Get the top level pvStructure.
|
||||
* @return The pvStructure. An exception is thrown if pvStructure does not exist.
|
||||
*/
|
||||
virtual epics::pvData::PVStructurePtr getPVStructure() = 0;
|
||||
/**
|
||||
* @brief Get the alarm.
|
||||
* If the pvStructure as an alarm field it's values are returned.
|
||||
* If no then alarm shows that not alarm defined.
|
||||
* @return The alarm.
|
||||
*/
|
||||
virtual epics::pvData::Alarm getAlarm() = 0;
|
||||
/**
|
||||
* @brief Get the timeStamp.
|
||||
* If the pvStructure as a timeStamp field, it's values are returned.
|
||||
* If no then all fields are 0.
|
||||
* @return The timeStamp.
|
||||
*/
|
||||
virtual epics::pvData::TimeStamp getTimeStamp() = 0;
|
||||
/**
|
||||
* @brief Is there a top level field named value of the PVstructure returned by channelGet?
|
||||
* @return The answer.
|
||||
*/
|
||||
virtual bool hasValue() = 0;
|
||||
/**
|
||||
* @brief Is the value field a scalar?
|
||||
* @return The answer.
|
||||
*/
|
||||
virtual bool isValueScalar() = 0;
|
||||
/**
|
||||
* @brief Is the value field a scalar array?
|
||||
* @return The answer.
|
||||
*/
|
||||
virtual bool isValueScalarArray() = 0;
|
||||
/**
|
||||
* @brief Return the interface to the value field.
|
||||
* @return The interface. an excetion is thrown if a value field does not exist.
|
||||
*/
|
||||
virtual epics::pvData::PVFieldPtr getValue() = 0;
|
||||
/**
|
||||
* @brief Return the interface to a scalar value field.
|
||||
* @return The interface for a scalar value field.
|
||||
* An exception is thown if no scalar value field.
|
||||
*/
|
||||
virtual epics::pvData::PVScalarPtr getScalarValue() = 0;
|
||||
/**
|
||||
* @brief Return the interface to an array value field.
|
||||
* @return The interface.
|
||||
* An exception is thown if no array value field.
|
||||
*/
|
||||
virtual std::tr1::shared_ptr<epics::pvData::PVArray> getArrayValue() = 0;
|
||||
/**
|
||||
* @brief Return the interface to a scalar array value field.
|
||||
* @return Return the interface.
|
||||
* An exception is thown if no scalar array value field.
|
||||
*/
|
||||
virtual std::tr1::shared_ptr<epics::pvData::PVScalarArray> getScalarArrayValue() = 0;
|
||||
/**
|
||||
* @brief Get the boolean value. If value is not a boolean an exception is thrown
|
||||
* @return true or false.
|
||||
*/
|
||||
virtual bool getBoolean() = 0;
|
||||
/**
|
||||
* @brief Get the value as a byte.
|
||||
* If value is not a byte scalar an exception is thrown.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual epics::pvData::int8 getByte() = 0;
|
||||
/**
|
||||
* @brief Get the value as a short.
|
||||
* If value is not a numeric scalar an exception is thrown
|
||||
* @return The value.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
*/
|
||||
virtual epics::pvData::int16 getShort() = 0;
|
||||
/**
|
||||
* @brief Get the value as an int.
|
||||
* If value is not a numeric scalar an exception is thrown.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
*/
|
||||
virtual epics::pvData::int32 getInt() = 0;
|
||||
/**
|
||||
* @brief Get the value as a long.
|
||||
* If value is not a numeric scalar an exception is thrown.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
*/
|
||||
virtual epics::pvData::int64 getLong() = 0;
|
||||
/**
|
||||
* @brief Get the value as an unsigned byte.
|
||||
* If value is not a numeric scalar an exception is thrown.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
*/
|
||||
virtual epics::pvData::uint8 getUByte() = 0;
|
||||
/**
|
||||
* @brief Get the value as a short.
|
||||
* If value is not a numeric scalar an exception is thrown.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
*/
|
||||
virtual epics::pvData::uint16 getUShort() = 0;
|
||||
/**
|
||||
* @brief Get the value as an unsigned int.
|
||||
* @return If value is not a numeric scalar an exception is thrown
|
||||
*/
|
||||
virtual epics::pvData::uint32 getUInt() = 0;
|
||||
/**
|
||||
* @brief Get the value as an unsigned long.
|
||||
* If value is not a numeric scalar an exception is thrown.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
*/
|
||||
virtual epics::pvData::uint64 getULong() = 0;
|
||||
/**
|
||||
* @brief Get the value as a float.
|
||||
* If value is not a numeric scalar an exception is thrown.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual float getFloat() = 0;
|
||||
/**
|
||||
* @brief Get the value as a double.
|
||||
* If value is not a numeric scalar an exception is thrown.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual double getDouble() = 0;
|
||||
/**
|
||||
* @brief Get the value as a string.
|
||||
* If value is not a string an exception is thrown
|
||||
* @return The value.
|
||||
*/
|
||||
virtual std::string getString() = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the value as a boolean array.
|
||||
* If the value is not a boolean array an exception is thrown
|
||||
* @return The value.
|
||||
*/
|
||||
virtual epics::pvData::shared_vector<epics::pvData::boolean> getBooleanArray() = 0;
|
||||
/**
|
||||
* @brief Get the value as a byte array.
|
||||
* @return If the value is not a numeric array an exception is thrown
|
||||
*/
|
||||
virtual epics::pvData::shared_vector<epics::pvData::int8> getByteArray() = 0;
|
||||
/**
|
||||
* @brief Get the value as a short array.
|
||||
* If the value is not a numeric array an exception is thrown.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual epics::pvData::shared_vector<epics::pvData::int16> getShortArray() = 0;
|
||||
/**
|
||||
* @brief Get the value as an int array.
|
||||
* If the value is not a numeric array an exception is thrown.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual epics::pvData::shared_vector<epics::pvData::int32> getIntArray() = 0;
|
||||
/**
|
||||
* @brief Get the value as a long array.
|
||||
* If the value is not a numeric array an exception is thrown.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual epics::pvData::shared_vector<epics::pvData::int64> getLongArray() = 0;
|
||||
/**
|
||||
* @brief Get the value as an unsigned byte array.
|
||||
* If the value is not a numeric array an exception is thrown.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual epics::pvData::shared_vector<epics::pvData::uint8> getUByteArray() = 0;
|
||||
/**
|
||||
* @brief Get the value as an unsigned short array.
|
||||
* If the value is not a numeric array an exception is thrown.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual epics::pvData::shared_vector<epics::pvData::uint16> getUShortArray() = 0;
|
||||
/**
|
||||
* Get the value as an unsigned int array.
|
||||
* If the value is not a numeric array an exception is thrown.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual epics::pvData::shared_vector<epics::pvData::uint32> getUIntArray() = 0;
|
||||
/**
|
||||
* @brief Get the value as an unsigned long array.
|
||||
* If the value is not a numeric array an exception is thrown.
|
||||
* An exception is also thrown if the actualy type can cause an overflow.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual epics::pvData::shared_vector<epics::pvData::uint64> getULongArray() = 0;
|
||||
/**
|
||||
* @brief Get the value as a float array.
|
||||
* If the value is not a numeric array an exception is thrown.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual epics::pvData::shared_vector<float> getFloatArray() = 0;
|
||||
/**
|
||||
* @brief Get the value as a double array.
|
||||
* If the value is not a numeric array an exception is thrown.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual epics::pvData::shared_vector<double> getDoubleArray() = 0;
|
||||
/**
|
||||
* @brief Get the value as a string array.
|
||||
* If the value is not a string array an exception is thrown.
|
||||
* @return The value.
|
||||
*/
|
||||
virtual epics::pvData::shared_vector<std::string> getStringArray() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This is a factory for creating an EasyPVStructure
|
||||
*
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass EasyPVStructureFactory
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create a EasyPVAStructure.
|
||||
* @return The interface to the EasyPVAStructure.
|
||||
*/
|
||||
static EasyPVStructurePtr createEasyPVStructure();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief An easy to use alternative to ChannelGet.
|
||||
*
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass EasyGet :
|
||||
public EasyPVStructure
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(EasyGet);
|
||||
/**
|
||||
* @brief destructor
|
||||
*/
|
||||
virtual ~EasyGet(){}
|
||||
/**
|
||||
* @brief destroy an resources used.
|
||||
*/
|
||||
virtual void destroy() = 0;
|
||||
/**
|
||||
* @brief call issueConnect and then waitConnect.
|
||||
* An exception is thrown if connect fails.
|
||||
*/
|
||||
virtual void connect() = 0;
|
||||
/**
|
||||
* @brief create the channelGet connection to the channel.
|
||||
* This can only be called once.
|
||||
* An exception is thrown if connect fails.
|
||||
*/
|
||||
virtual void issueConnect() = 0;
|
||||
/**
|
||||
* @brief wait until the channelGet connection to the channel is complete.
|
||||
* @return status;
|
||||
*/
|
||||
virtual epics::pvData::Status waitConnect() = 0;
|
||||
/**
|
||||
* @brief Call issueGet and then waitGet.
|
||||
* An exception is thrown if get fails.
|
||||
*/
|
||||
virtual void get() = 0;
|
||||
/**
|
||||
* @brief Issue a get and return immediately.
|
||||
*/
|
||||
virtual void issueGet() = 0;
|
||||
/**
|
||||
* @brief Wait until get completes.
|
||||
* If failure getStatus can be called to get reason.
|
||||
* @return (false,true) means (failure,success)
|
||||
*/
|
||||
virtual epics::pvData::Status waitGet() = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the bitSet for the top level structure.
|
||||
* @return The bitSet.
|
||||
*/
|
||||
virtual epics::pvData::BitSetPtr getBitSet() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This is a factory for creating an EasyGet.
|
||||
*
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass EasyGetFactory
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create a EasyPVAStructure.
|
||||
* @param &easyPVA Interface to EasyPVA
|
||||
* @param easyChannel Interface to EasyChannel
|
||||
* @param channel Interface to Channel
|
||||
* @param pvRequest The request structure.
|
||||
* @return The interface to the EasyPVAStructure.
|
||||
*/
|
||||
static EasyGetPtr createEasyGet(
|
||||
EasyPVAPtr const &easyPVA,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
epics::pvAccess::Channel::shared_pointer const & channel,
|
||||
epics::pvData::PVStructurePtr const &pvRequest
|
||||
);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* EASYPVA_H */
|
||||
|
||||
/** @page Overview Documentation
|
||||
*
|
||||
* <a href = "easyPVA.html">easyPVA.html</a>
|
||||
*
|
||||
*/
|
||||
|
597
src/easyPVStructure.cpp
Normal file
597
src/easyPVStructure.cpp
Normal file
@ -0,0 +1,597 @@
|
||||
/* easyPVStructure.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2015.02
|
||||
*/
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
#include <sstream>
|
||||
#include <pv/easyPVA.h>
|
||||
#include <pv/createRequest.h>
|
||||
#include <pv/convert.h>
|
||||
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace easyPVA {
|
||||
|
||||
typedef std::tr1::shared_ptr<epics::pvData::PVArray> PVArrayPtr;
|
||||
static StructureConstPtr nullStructure;
|
||||
static PVStructurePtr nullPVStructure;
|
||||
static ConvertPtr convert = getConvert();
|
||||
static Status statusOK(Status::Ok);
|
||||
static Status statusDestroyed(Status::STATUSTYPE_ERROR,"was destroyed");
|
||||
static Status statusNoPVStructure(Status::STATUSTYPE_ERROR,"setPVStructure not called");
|
||||
static Status statusNoValue(Status::STATUSTYPE_ERROR,"no value field");
|
||||
static Status statusNoScalar(Status::STATUSTYPE_ERROR,"value is not a scalar");
|
||||
static Status statusMismatchedScalar(Status::STATUSTYPE_ERROR,"value is not a compatible scalar");
|
||||
static Status statusNoArray(Status::STATUSTYPE_ERROR,"value is not a array");
|
||||
static Status statusNoScalarArray(Status::STATUSTYPE_ERROR,"value is not a scalarArray");
|
||||
static Status statusMismatchedScalarArray(Status::STATUSTYPE_ERROR,"value is not a compatible scalarArray");
|
||||
static Status statusNoAlarm(Status::STATUSTYPE_ERROR,"no alarm field");
|
||||
static Status statusNoTimeStamp(Status::STATUSTYPE_ERROR,"no timeStamp field");
|
||||
|
||||
class epicsShareClass EasyPVStructureImpl :
|
||||
public EasyPVStructure,
|
||||
public std::tr1::enable_shared_from_this<EasyPVStructureImpl>
|
||||
{
|
||||
public:
|
||||
EasyPVStructureImpl();
|
||||
~EasyPVStructureImpl(){}
|
||||
virtual void setMessagePrefix(std::string const & value);
|
||||
virtual void setPVStructure(PVStructurePtr const & pvStructure);
|
||||
virtual PVStructurePtr getPVStructure();
|
||||
virtual Alarm getAlarm();
|
||||
virtual TimeStamp getTimeStamp();
|
||||
virtual bool hasValue();
|
||||
virtual bool isValueScalar();
|
||||
virtual bool isValueScalarArray() ;
|
||||
virtual PVFieldPtr getValue();
|
||||
virtual PVScalarPtr getScalarValue();
|
||||
virtual std::tr1::shared_ptr<PVArray> getArrayValue();
|
||||
virtual std::tr1::shared_ptr<PVScalarArray> getScalarArrayValue();
|
||||
virtual bool getBoolean();
|
||||
virtual int8 getByte();
|
||||
virtual int16 getShort();
|
||||
virtual int32 getInt();
|
||||
virtual int64 getLong();
|
||||
virtual uint8 getUByte();
|
||||
virtual uint16 getUShort();
|
||||
virtual uint32 getUInt();
|
||||
virtual uint64 getULong();
|
||||
virtual float getFloat();
|
||||
virtual double getDouble();
|
||||
virtual std::string getString();
|
||||
|
||||
virtual shared_vector<boolean> getBooleanArray();
|
||||
virtual shared_vector<int8> getByteArray();
|
||||
virtual shared_vector<int16> getShortArray();
|
||||
virtual shared_vector<int32> getIntArray();
|
||||
virtual shared_vector<int64> getLongArray();
|
||||
virtual shared_vector<uint8> getUByteArray();
|
||||
virtual shared_vector<uint16> getUShortArray();
|
||||
virtual shared_vector<uint32> getUIntArray();
|
||||
virtual shared_vector<uint64> getULongArray();
|
||||
virtual shared_vector<float> getFloatArray();
|
||||
virtual shared_vector<double> getDoubleArray();
|
||||
virtual shared_vector<string> getStringArray();
|
||||
|
||||
EasyPVStructurePtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
private:
|
||||
void checkPVStructure();
|
||||
void checkValue();
|
||||
bool checkOverflow(ScalarType source,ScalarType dest);
|
||||
PVScalarPtr checkScalar(ScalarType scalarType);
|
||||
PVScalarArrayPtr checkScalarArray(ScalarType elementType);
|
||||
|
||||
string messagePrefix;
|
||||
PVStructurePtr pvStructure;
|
||||
PVFieldPtr pvValue;
|
||||
PVAlarm pvAlarm;
|
||||
Alarm alarm;
|
||||
PVTimeStamp pvTimeStamp;
|
||||
TimeStamp timeStamp;
|
||||
};
|
||||
|
||||
EasyPVStructureImpl::EasyPVStructureImpl()
|
||||
{}
|
||||
|
||||
EasyPVStructurePtr EasyPVStructureFactory::createEasyPVStructure()
|
||||
{
|
||||
EasyPVStructurePtr epv(new EasyPVStructureImpl());
|
||||
return epv;
|
||||
}
|
||||
|
||||
void EasyPVStructureImpl::checkPVStructure()
|
||||
{
|
||||
if(pvStructure) return;
|
||||
throw std::runtime_error(messagePrefix + statusNoPVStructure.getMessage());
|
||||
|
||||
}
|
||||
|
||||
void EasyPVStructureImpl::checkValue()
|
||||
{
|
||||
if(pvValue) return;
|
||||
throw std::runtime_error(messagePrefix + statusNoValue.getMessage());
|
||||
}
|
||||
|
||||
bool EasyPVStructureImpl::checkOverflow(ScalarType source,ScalarType dest)
|
||||
{
|
||||
if(dest==pvFloat||dest==pvDouble) return true;
|
||||
if(!ScalarTypeFunc::isInteger(source) && !ScalarTypeFunc::isUInteger(source)) return false;
|
||||
if(ScalarTypeFunc::isUInteger(dest)) {
|
||||
if(ScalarTypeFunc::isUInteger(source)) {
|
||||
if(dest>=source) return true;
|
||||
return false;
|
||||
}
|
||||
if(ScalarTypeFunc::isInteger(source)) {
|
||||
if(dest>=(source+4)) return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(ScalarTypeFunc::isInteger(dest)) {
|
||||
if(ScalarTypeFunc::isUInteger(source)) {
|
||||
if(dest>(source-4)) return true;
|
||||
return false;
|
||||
}
|
||||
if(ScalarTypeFunc::isInteger(source)) {
|
||||
if(dest>=source) return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PVScalarPtr EasyPVStructureImpl::checkScalar(ScalarType scalarType)
|
||||
{
|
||||
checkPVStructure();
|
||||
checkValue();
|
||||
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + statusNoScalar.getMessage());
|
||||
}
|
||||
ScalarType type = pv->getScalar()->getScalarType();
|
||||
if((scalarType==pvBoolean && type==pvBoolean)
|
||||
|| (scalarType==pvString && type==pvString)) return pv;
|
||||
if((ScalarTypeFunc::isNumeric(type) && ScalarTypeFunc::isNumeric(scalarType))
|
||||
&& checkOverflow(type,scalarType)) return pv;
|
||||
stringstream ss;
|
||||
ss << messagePrefix << statusMismatchedScalar.getMessage();
|
||||
ss << " source " << type << " dest " << scalarType;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
PVScalarArrayPtr EasyPVStructureImpl::checkScalarArray(ScalarType elementType)
|
||||
{
|
||||
checkPVStructure();
|
||||
checkValue();
|
||||
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + statusNoScalarArray.getMessage());
|
||||
}
|
||||
ScalarType type = pv->getScalarArray()->getElementType();
|
||||
if((elementType==pvBoolean && type==pvBoolean)
|
||||
|| (elementType==pvBoolean && type==pvBoolean)) return pv;
|
||||
if((ScalarTypeFunc::isNumeric(type) && ScalarTypeFunc::isNumeric(elementType))
|
||||
&& checkOverflow(type,elementType)) return pv;
|
||||
throw std::runtime_error(messagePrefix + statusMismatchedScalarArray.getMessage());
|
||||
}
|
||||
|
||||
void EasyPVStructureImpl::setMessagePrefix(string const & value)
|
||||
{
|
||||
messagePrefix = value;
|
||||
if(value.size()>0) messagePrefix += " ";
|
||||
}
|
||||
|
||||
void EasyPVStructureImpl::setPVStructure(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
this->pvStructure = pvStructure;
|
||||
pvValue = pvStructure->getSubField("value");
|
||||
}
|
||||
|
||||
PVStructurePtr EasyPVStructureImpl::getPVStructure()
|
||||
{
|
||||
checkPVStructure();
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVFieldPtr EasyPVStructureImpl::getValue()
|
||||
{
|
||||
checkValue();
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
PVScalarPtr EasyPVStructureImpl::getScalarValue()
|
||||
{
|
||||
checkValue();
|
||||
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + statusNoScalar.getMessage());
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
PVArrayPtr EasyPVStructureImpl::getArrayValue()
|
||||
{
|
||||
checkValue();
|
||||
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + statusNoArray.getMessage());
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
PVScalarArrayPtr EasyPVStructureImpl::getScalarArrayValue()
|
||||
{
|
||||
checkValue();
|
||||
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + statusNoScalarArray.getMessage());
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
Alarm EasyPVStructureImpl::getAlarm()
|
||||
{
|
||||
Alarm alarm;
|
||||
alarm.setSeverity(undefinedAlarm);
|
||||
alarm.setStatus(undefinedStatus);
|
||||
alarm.setMessage("no alarm field");
|
||||
if(!pvStructure) return alarm;
|
||||
PVStructurePtr xxx = pvStructure->getSubField<PVStructure>("alarm");
|
||||
if(xxx) {
|
||||
pvAlarm.attach(xxx);
|
||||
if(pvAlarm.isAttached()) {
|
||||
pvAlarm.get(alarm);
|
||||
pvAlarm.detach();
|
||||
}
|
||||
}
|
||||
return alarm;;
|
||||
}
|
||||
|
||||
TimeStamp EasyPVStructureImpl::getTimeStamp()
|
||||
{
|
||||
TimeStamp timeStamp;
|
||||
if(!pvStructure) return timeStamp;
|
||||
PVStructurePtr xxx = pvStructure->getSubField<PVStructure>("timeStamp");
|
||||
if(xxx) {
|
||||
pvTimeStamp.attach(xxx);
|
||||
if(pvTimeStamp.isAttached()) {
|
||||
pvTimeStamp.get(timeStamp);
|
||||
pvTimeStamp.detach();
|
||||
}
|
||||
}
|
||||
return timeStamp;;
|
||||
}
|
||||
|
||||
bool EasyPVStructureImpl::hasValue()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EasyPVStructureImpl::isValueScalar()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
if(pvValue->getField()->getType()==scalar) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EasyPVStructureImpl::isValueScalarArray()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
if(pvValue->getField()->getType()==scalarArray) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EasyPVStructureImpl::getBoolean()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvBoolean);
|
||||
PVBooleanPtr pv = static_pointer_cast<PVBoolean>(pvScalar);
|
||||
return pv->get();
|
||||
}
|
||||
|
||||
int8 EasyPVStructureImpl::getByte()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvByte);
|
||||
return convert->toByte(pvScalar);
|
||||
}
|
||||
|
||||
uint8 EasyPVStructureImpl::getUByte()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvUByte);
|
||||
return convert->toUByte(pvScalar);
|
||||
}
|
||||
|
||||
int16 EasyPVStructureImpl::getShort()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvShort);
|
||||
return convert->toShort(pvScalar);
|
||||
}
|
||||
|
||||
uint16 EasyPVStructureImpl::getUShort()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvUShort);
|
||||
return convert->toUShort(pvScalar);
|
||||
}
|
||||
|
||||
int32 EasyPVStructureImpl::getInt()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvInt);
|
||||
return convert->toInt(pvScalar);
|
||||
}
|
||||
|
||||
uint32 EasyPVStructureImpl::getUInt()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvUInt);
|
||||
return convert->toUInt(pvScalar);
|
||||
}
|
||||
|
||||
int64 EasyPVStructureImpl::getLong()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvLong);
|
||||
return convert->toLong(pvScalar);
|
||||
}
|
||||
|
||||
uint64 EasyPVStructureImpl::getULong()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvULong);
|
||||
return convert->toULong(pvScalar);
|
||||
}
|
||||
|
||||
float EasyPVStructureImpl::getFloat()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvFloat);
|
||||
return convert->toFloat(pvScalar);
|
||||
}
|
||||
|
||||
double EasyPVStructureImpl::getDouble()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvDouble);
|
||||
return convert->toDouble(pvScalar);
|
||||
}
|
||||
|
||||
string EasyPVStructureImpl::getString()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvString);
|
||||
PVStringPtr pv = static_pointer_cast<PVString>(pvScalar);
|
||||
return pv->get();
|
||||
}
|
||||
|
||||
shared_vector<boolean> EasyPVStructureImpl::getBooleanArray()
|
||||
{
|
||||
checkScalarArray(pvBoolean);
|
||||
PVBooleanArrayPtr pv = static_pointer_cast<PVBooleanArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
shared_vector<T> copy(PVScalarArrayPtr const & pvScalarArray)
|
||||
{
|
||||
ScalarType elementType = pvScalarArray->getScalarArray()->getElementType();
|
||||
switch(elementType) {
|
||||
case pvBoolean :
|
||||
break;
|
||||
case pvByte :
|
||||
{
|
||||
PVByteArrayPtr pv = static_pointer_cast<PVByteArray>(pvScalarArray);
|
||||
shared_vector<int8> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,int8>(data);
|
||||
return to;
|
||||
}
|
||||
case pvShort :
|
||||
{
|
||||
PVShortArrayPtr pv = static_pointer_cast<PVShortArray>(pvScalarArray);
|
||||
shared_vector<int16> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,int16>(data);
|
||||
return to;
|
||||
}
|
||||
case pvInt :
|
||||
{
|
||||
PVIntArrayPtr pv = static_pointer_cast<PVIntArray>(pvScalarArray);
|
||||
shared_vector<int32> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,int32>(data);
|
||||
return to;
|
||||
}
|
||||
case pvLong :
|
||||
{
|
||||
PVLongArrayPtr pv = static_pointer_cast<PVLongArray>(pvScalarArray);
|
||||
shared_vector<int64> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,int64>(data);
|
||||
return to;
|
||||
}
|
||||
case pvUByte :
|
||||
{
|
||||
PVUByteArrayPtr pv = static_pointer_cast<PVUByteArray>(pvScalarArray);
|
||||
shared_vector<uint8> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,uint8>(data);
|
||||
return to;
|
||||
}
|
||||
case pvUShort :
|
||||
{
|
||||
PVUShortArrayPtr pv = static_pointer_cast<PVUShortArray>(pvScalarArray);
|
||||
shared_vector<uint16> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,uint16>(data);
|
||||
return to;
|
||||
}
|
||||
case pvUInt :
|
||||
{
|
||||
PVUIntArrayPtr pv = static_pointer_cast<PVUIntArray>(pvScalarArray);
|
||||
shared_vector<uint32> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,uint32>(data);
|
||||
return to;
|
||||
}
|
||||
case pvULong :
|
||||
{
|
||||
PVULongArrayPtr pv = static_pointer_cast<PVULongArray>(pvScalarArray);
|
||||
shared_vector<uint64> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,uint64>(data);
|
||||
return to;
|
||||
}
|
||||
case pvFloat :
|
||||
{
|
||||
PVFloatArrayPtr pv = static_pointer_cast<PVFloatArray>(pvScalarArray);
|
||||
shared_vector<float> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,float>(data);
|
||||
return to;
|
||||
}
|
||||
case pvDouble :
|
||||
{
|
||||
PVDoubleArrayPtr pv = static_pointer_cast<PVDoubleArray>(pvScalarArray);
|
||||
shared_vector<double> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,double>(data);
|
||||
return to;
|
||||
}
|
||||
case pvString :
|
||||
break;
|
||||
}
|
||||
return shared_vector<T>();
|
||||
}
|
||||
|
||||
shared_vector<int8> EasyPVStructureImpl::getByteArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvByte);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvByte) {
|
||||
PVByteArrayPtr pv = static_pointer_cast<PVByteArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<int8> xx = copy<int8>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<int16> EasyPVStructureImpl::getShortArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvShort);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvShort) {
|
||||
PVShortArrayPtr pv = static_pointer_cast<PVShortArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<int16> xx = copy<int16>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<int32> EasyPVStructureImpl::getIntArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvInt);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvInt) {
|
||||
PVIntArrayPtr pv = static_pointer_cast<PVIntArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<int32> xx = copy<int32>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<int64> EasyPVStructureImpl::getLongArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvLong);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvLong) {
|
||||
PVLongArrayPtr pv = static_pointer_cast<PVLongArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<int64> xx = copy<int64>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<uint8> EasyPVStructureImpl::getUByteArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvUByte);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvUByte) {
|
||||
PVUByteArrayPtr pv = static_pointer_cast<PVUByteArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<uint8> xx = copy<uint8>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<uint16> EasyPVStructureImpl::getUShortArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvUShort);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvUShort) {
|
||||
PVUShortArrayPtr pv = static_pointer_cast<PVUShortArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<uint16> xx = copy<uint16>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<uint32> EasyPVStructureImpl::getUIntArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvUInt);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvUInt) {
|
||||
PVUIntArrayPtr pv = static_pointer_cast<PVUIntArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<uint32> xx = copy<uint32>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<uint64> EasyPVStructureImpl::getULongArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvULong);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvULong) {
|
||||
PVULongArrayPtr pv = static_pointer_cast<PVULongArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<uint64> xx = copy<uint64>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<float> EasyPVStructureImpl::getFloatArray()
|
||||
{
|
||||
checkScalarArray(pvFloat);
|
||||
PVFloatArrayPtr pv = static_pointer_cast<PVFloatArray>(pvValue);
|
||||
return pv->reuse();
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvFloat);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvFloat) {
|
||||
PVFloatArrayPtr pv = static_pointer_cast<PVFloatArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<float> xx = copy<float>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<double> EasyPVStructureImpl::getDoubleArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvDouble);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvDouble) {
|
||||
PVDoubleArrayPtr pv = static_pointer_cast<PVDoubleArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<double> xx = copy<double>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<string> EasyPVStructureImpl::getStringArray()
|
||||
{
|
||||
checkScalarArray(pvString);
|
||||
PVStringArrayPtr pv = static_pointer_cast<PVStringArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
|
||||
|
||||
}}
|
Reference in New Issue
Block a user