work in progress; simple easyGet worked!!!
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
[branchname]
|
||||||
|
master = master
|
||||||
|
develop = default
|
||||||
|
feature = feature/
|
||||||
|
release = release/
|
||||||
|
hotfix = hotfix/
|
||||||
|
support = support/
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
^QtC-
|
||||||
|
bin/
|
||||||
|
lib/
|
||||||
|
doc/
|
||||||
|
include/
|
||||||
|
db/
|
||||||
|
dbd/
|
||||||
|
documentation/html
|
||||||
|
envPaths
|
||||||
|
configure/.*\.local
|
||||||
|
/O\..*
|
||||||
@@ -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.
|
||||||
|
________________________________________________________________________
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
TOP=..
|
||||||
|
|
||||||
|
include $(TOP)/configure/CONFIG
|
||||||
|
|
||||||
|
TARGETS = $(CONFIG_TARGETS)
|
||||||
|
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
||||||
|
|
||||||
|
include $(TOP)/configure/RULES
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# RULES
|
||||||
|
|
||||||
|
include $(CONFIG)/RULES
|
||||||
|
|
||||||
|
# Library should be rebuilt because LIBOBJS may have changed.
|
||||||
|
$(LIBNAME): ../Makefile
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
#RULES.ioc
|
||||||
|
include $(CONFIG)/RULES.ioc
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
#RULES_DIRS
|
||||||
|
include $(CONFIG)/RULES_DIRS
|
||||||
@@ -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)
|
||||||
@@ -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>
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
TOP=..
|
||||||
|
|
||||||
|
include $(TOP)/configure/CONFIG
|
||||||
|
|
||||||
|
TARGETS = $(CONFIG_TARGETS)
|
||||||
|
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
||||||
|
|
||||||
|
include $(TOP)/configure/RULES
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# RULES
|
||||||
|
|
||||||
|
include $(CONFIG)/RULES
|
||||||
|
|
||||||
|
# Library should be rebuilt because LIBOBJS may have changed.
|
||||||
|
$(LIBNAME): ../Makefile
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
#RULES.ioc
|
||||||
|
include $(CONFIG)/RULES.ioc
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
#RULES_DIRS
|
||||||
|
include $(CONFIG)/RULES_DIRS
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#RULES_TOP
|
||||||
|
include $(CONFIG)/RULES_TOP
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
@@ -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
@@ -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
@@ -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>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -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