work in progress; simple easyGet worked!!!

This commit is contained in:
Marty Kraimer
2015-02-27 15:04:56 -05:00
commit f677e1a091
34 changed files with 5540 additions and 0 deletions

8
.hgflow Normal file
View File

@ -0,0 +1,8 @@
[branchname]
master = master
develop = default
feature = feature/
release = release/
hotfix = hotfix/
support = support/

11
.hgignore Normal file
View File

@ -0,0 +1,11 @@
^QtC-
bin/
lib/
doc/
include/
db/
dbd/
documentation/html
envPaths
configure/.*\.local
/O\..*

2303
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

78
LICENSE Normal file
View File

@ -0,0 +1,78 @@
Copyright (c) 2008 Martin R. Kraimer
Copyright (c) 2006 The University of Chicago, as Operator of Argonne
National Laboratory.
Copyright (c) 2006 Deutsches Elektronen-Synchrotron,
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
Copyright (c) 2007 Control System Laboratory,
(COSYLAB) Ljubljana Slovenia
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
________________________________________________________________________
This software is in part copyrighted by the University of Chicago (UofC)
In no event shall UofC be liable to any party for direct, indirect,
special, incidental, or consequential damages arising out of the use of
this software, its documentation, or any derivatives thereof, even if
UofC has been advised of the possibility of such damage.
UofC specifically disclaims any warranties, including, but not limited
to, the implied warranties of merchantability, fitness for a particular
purpose, and non-infringement. This software is provided on an "as is"
basis, and UofC has no obligation to provide maintenance, support,
updates, enhancements, or modifications.
________________________________________________________________________
This software is in part copyrighted by the BERLINER SPEICHERRING
GESELLSCHAFT FUER SYNCHROTRONSTRAHLUNG M.B.H. (BESSY), BERLIN, GERMANY.
In no event shall BESSY be liable to any party for direct, indirect,
special, incidental, or consequential damages arising out of the use of
this software, its documentation, or any derivatives thereof, even if
BESSY has been advised of the possibility of such damage.
BESSY specifically disclaims any warranties, including, but not limited
to, the implied warranties of merchantability, fitness for a particular
purpose, and non-infringement. This software is provided on an "as is"
basis, and BESSY has no obligation to provide maintenance, support,
updates, enhancements, or modifications.
________________________________________________________________________
This software is in part copyrighted by the Deutsches Elektronen-Synchroton,
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
In no event shall DESY be liable to any party for direct, indirect,
special, incidental, or consequential damages arising out of the use of
this software, its documentation, or any derivatives thereof, even if
DESY has been advised of the possibility of such damage.
DESY specifically disclaims any warranties, including, but not limited
to, the implied warranties of merchantability, fitness for a particular
purpose, and non-infringement. This software is provided on an "as is"
basis, and DESY has no obligation to provide maintenance, support,
updates, enhancements, or modifications.
________________________________________________________________________

20
Makefile Normal file
View File

@ -0,0 +1,20 @@
#Makefile at top of application tree
TOP = .
include $(TOP)/configure/CONFIG
DIRS := $(DIRS) $(filter-out $(DIRS), configure)
DIRS := $(DIRS) $(filter-out $(DIRS), src)
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), example)
define DIR_template
$(1)_DEPEND_DIRS = configure
endef
$(foreach dir, $(filter-out configure,$(DIRS)),$(eval $(call DIR_template,$(dir))))
define EMB_template
$(1)_DEPEND_DIRS = src
endef
$(foreach dir, $(EMBEDDED_TOPS),$(eval $(call EMB_template,$(dir))))
include $(TOP)/configure/RULES_TOP

29
configure/CONFIG Normal file
View File

@ -0,0 +1,29 @@
# CONFIG - Load build configuration data
#
# Do not make changes to this file!
# Allow user to override where the build rules come from
RULES = $(EPICS_BASE)
# RELEASE files point to other application tops
include $(TOP)/configure/RELEASE
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
ifdef T_A
-include $(TOP)/configure/RELEASE.Common.$(T_A)
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
endif
CONFIG = $(RULES)/configure
include $(CONFIG)/CONFIG
# Override the Base definition:
INSTALL_LOCATION = $(TOP)
# CONFIG_SITE files contain other build configuration settings
include $(TOP)/configure/CONFIG_SITE
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
ifdef T_A
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
endif

27
configure/CONFIG_SITE Normal file
View File

@ -0,0 +1,27 @@
# CONFIG_SITE
# Make any application-specific changes to the EPICS build
# configuration variables in this file.
#
# Host/target specific settings can be specified in files named
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
# CONFIG_SITE.Common.$(T_A)
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
# CHECK_RELEASE controls the consistency checking of the support
# applications pointed to by the RELEASE* files.
# Normally CHECK_RELEASE should be set to YES.
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking but
# continue building anyway if conflicts are found.
#CHECK_RELEASE = YES
# To install files into a location other than $(TOP) define
# INSTALL_LOCATION here.
#INSTALL_LOCATION=</path/name/to/install/top>
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/../CONFIG_SITE.local
-include $(TOP)/configure/CONFIG_SITE.local

View File

@ -0,0 +1,7 @@
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
EPICS_BASE=/home/install/epics/base
PVCOMMON=/home/hg/pvCommonCPP
PVDATA=/home/hg/pvDataCPP
PVACCESS=/home/hg/pvAccessCPP

9
configure/Makefile Normal file
View File

@ -0,0 +1,9 @@
TOP=..
include $(TOP)/configure/CONFIG
TARGETS = $(CONFIG_TARGETS)
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
include $(TOP)/configure/RULES

28
configure/RELEASE Normal file
View File

@ -0,0 +1,28 @@
# easyPVACPP RELEASE - Location of external support modules
#
# IF YOU CHANGE this file or any file it includes you must
# subsequently do a "gnumake rebuild" in the application's
# top level directory.
#
# The build process does not check dependencies against files
# that are outside this application, thus you should also do a
# "gnumake rebuild" in the top level directory after EPICS_BASE
# or any other external module pointed to below is rebuilt.
#
# Host- or target-specific settings can be given in files named
# RELEASE.$(EPICS_HOST_ARCH).Common
# RELEASE.Common.$(T_A)
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
# EPICS V4 Developers: Do not edit the locations in this file!
#
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
# PVASRV = /path/to/epics/pvaSrvCPP
# PVACCESS = /path/to/epics/pvAccessCPP
# PVDATA = /path/to/epics/pvDataCPP
# PVCOMMON = /path/to/epics/pvCommonCPP
# EPICS_BASE = /path/to/epics/base
-include $(TOP)/../RELEASE.local
-include $(TOP)/configure/RELEASE.local

6
configure/RULES Normal file
View File

@ -0,0 +1,6 @@
# RULES
include $(CONFIG)/RULES
# Library should be rebuilt because LIBOBJS may have changed.
$(LIBNAME): ../Makefile

2
configure/RULES.ioc Normal file
View File

@ -0,0 +1,2 @@
#RULES.ioc
include $(CONFIG)/RULES.ioc

2
configure/RULES_DIRS Normal file
View File

@ -0,0 +1,2 @@
#RULES_DIRS
include $(CONFIG)/RULES_DIRS

16
configure/RULES_TOP Normal file
View File

@ -0,0 +1,16 @@
#RULES_TOP
include $(CONFIG)/RULES_TOP
EMTOPACTIONS += cvsclean realuninstall
distclean: emtop_distclean
emtopDistcleanTargets += $(foreach dir, $(EMBEDDED_TOPS), \
$(dir)$(DIVIDER)emtop_dummy_action)
$(emtopDistcleanTargets) :
$(MAKE) -C $(dirPart) $(EMTOPACTIONS)
emtop_distclean : $(emtopDistcleanTargets)
.PHONY : $(emtopDistcleanTargets)

295
documentation/easyPVA.html Normal file
View File

@ -0,0 +1,295 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>EPICS easyPVA</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
body { margin-right: 10% }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript" src="http://epics-pvdata.sourceforge.net/script/tocgen.js"></script>
</head>
<body>
<div class="head">
<h1>EPICS easyPVA</h1>
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
<h2 class="nocount">EPICS V4 Working Group, Working Draft,
19-Feb-2015</h2>
<dl>
<dt>This version:</dt>
<dd><a
href="easyPVA.html">easyPVA.html
</a> </dd>
<dt>Latest version:</dt>
<dd>none</dd>
<dt>Previous version:</dt>
<dd>none</dd>
<dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd>
<dd>Matej Sekoranja, Cosylab</dd>
</dl>
<h2 class="nocount">Abstract</h2>
<p>EasyPVA (Easy PVAccess) is a software library that provides to an EPICS client programmer, a friendly
client side programming interface to the data of an EPICS based control system. It is intended
for such uses as rapid development of ad hoc programs by controls engineers, or to provide
scientists a way to directly develop analytical applications.</p>
<p>Specifically, easyPVA provides an easy interface for pvAccess, which is the
software support for high speed controls network communications used in EPICS version 4.
PvAccess provides a callback based interface, which can be hard to use.
EasyPVA provides an interface that does not require callbacks even for monitors.
</p>
<p>
EasyChannel provides many "convenience" methods to directly get and put
scalar and scalarArray data types.
Additional methods provide access to the full features of pvAccess.
</p>
<p>
EasyMultiChannel provides access to data from multiple channels as long
as each channel has a top level field named <b>value</b>.
EasyMultiChannel provides two ways to access data from multiple channels:
The first is as an NTMultiChannel. The second is as a double array.
The double array can be used if the value field of every channel is a numeric scalar.
There is code for NTMultiChannel that helps with access to more complicated data types.
</p>
<p>EasyPVA will become part of pvAccess when it is ready. </p>
<!-- last para of Abstract is boilerplate reference to EPICS -->
<p>For more information about EPICS generally, please refer to the home page of the <a
href="http://www.aps.anl.gov/epics/">Experimental Physics and Industrial
Control System</a>.</p>
<h2 class="nocount">Status of this Document and of the EasyPVA Software</h2>
<p>Under development</p>
</div> <!-- head -->
<div id="toc">
<h2 class="nocount">Table of Contents</h2>
</div>
<!-- Place what you would like in the Table of Contents, inside the contents div -->
<div id="contents" class="contents">
<hr />
<h2>Introduction</h2>
<p>EasyPVA is a synchronous API for accessing PVData via PVAccess. It provides
an interface to many of the features provided by pvData and pvAccess.</p>
<p>The EasyPVA API has the following features:</p>
<ol>
<li>Makes common requests easy to program</li>
<li>Provides full access to the pvAccess API for more demanding
applications</li>
<li>Allows efficient client side programs.</li>
</ol>
<p>The following describes the CPP version of EasyPVA.</p>
<p>This is the overview for EasyPVACPP. JavaDoc documentation is available at <a
href="./html/index.html">doxygenDoc</a></p>
<h3>Initialization</h3>
<p>A client obtains the interface to EasyPVA via the call:</p>
<pre>EasyPVA easy = EasyPVAFactory.get();</pre>
<p>The client can make this call many times, but an instance of the EastPVA interface object is
only created in the first call. This first call also
starts the PVAccess client factory.</p>
<h3>EasyPVA Overview</h3>
<p>EasyPVA creates interfaces to one of the following:</p>
<dl>
<dt>EasyChannel</dt>
<dd>This creates an interface for accessing a single channel.<br />
There are two methods for creating an EasyChannel,
with the difference being that the second
specifiers the name of the provider.
The other assumes that the provider is "pva" (pvAccess).
</dd>
<dt>EasyMultiChannel</dt>
<dd>This creates an interface for accessing a set of channels.<br />
There are multiple methods for creating an EasyMultiChannel.
The provider can be supplied or use a default of "pva".
A union for the UnionArray for accessing the value fields of each channel
can be provided or a default of variant union will be used.
</dd>
</dl>
<p>There are additional methods that allows the client to:</p>
<ol>
<li>Control how error messages are handled.</li>
<li>Control when get/put commands are sent the channel or channels.</li>
</ol>
<h3>EasyChannel Overview</h3>
<p>This interface creates Easy support for each PVAccess::Channel create
method:</p>
<dl>
<dt>EasyField</dt>
<dd>This gets the introspection interface from a channel. The
implementation provides full access to the features of
Channel::getField.</dd>
<dt>EasyProcess</dt>
<dd>This is used to process a channel. The implementation provides full
access to the features of ChannelProcess.</dd>
<dt>EasyGet</dt>
<dd>This is used to get values from a channel. The implementation allows
full access to all the features of ChannelGet. By default it asks for the
fields value, alarm, and timeStamp. If the channel has a value field then
EasyGet provides convenience methods for a scalar value and for an array
value. </dd>
<dt>EasyPut</dt>
<dd>This is used to get the current value of a channel and to put values to
a channel. The implementation allows full access to all the features of
ChannelPut. By default it asks for the field value, alarm, and timeStamp.
If the channel has a value field then EasyPut provides convenience
methods for a scalar value and for an array value. </dd>
<dt>EasyRPC</dt>
<dd>This is an interface to ChannelRPC.
The implementation allows full access to all the features of ChannelRPC.
</dd>
<dt>EasyPutGet</dt>
<dd>This is an interface to ChannelPutGet. Details TBD.</dd>
<dt>EasyMonitor</dt>
<dd>This is an interface to Monitor.
The implementation allows full access to all the features of pvAccess Monitor.
</dd>
<dt>EasyArray</dt>
<dd>This is an interface to ChannelArray. Details TBD.</dd>
<dt>EasyProcess</dt>
<dd>This is an interface to ChannelProcess. Details TBD.</dd>
</dl>
<h3>EasyMultiChannel Overview</h3>
<p>This interface creates Easy support for accessing a set of channels.
The only requirement of the channels is that each must have a top level field named value.
</p>
<dl>
<dt>EasyMultiGet</dt>
<dd>This is used to get values from a a set of channels.
The result can either be an NTMultiChannel structure or a <b>double[]</b> array.
The createGet method determines the result type.
</dd>
<dt>EasyMultiPut</dt>
<dd>This is used to get and put values from/to a set of channels.
The data supplied can either be an NTMultiChannel structure or a <b>double[]</b> array.
The createPut method determines the type.
</dd>
<dt>EasyMonitor</dt>
<dd>This is used to monitor values from a set of channels.
Each event can either be an NTMultiChannel structure or a <b>double[]</b> array.
The createMonitor method determines the data type.
</dd>
</dl>
<h2>shell</h2>
<p>Directory <b>shell</b> has the following files:</p>
<dl>
<dt>exampleDatabaseEasyPVA.zip</dt>
<dd>
When unzipped this is used to create an example IOC database.
The database has the record used by the examples are tests that come with easyPVAJava.
It uses pvDatabaseCPP to build the database.
After unzipping the file:
<pre>
cd configure
cp ExampleRELEASE.local RELEASE.local
edit RELEASE.local
cd ..
make
cd iocBoot/exampleDatabase
../../bin/&lt;arch:&gt;/exampleDatabase st.cmd
</pre>
You now have a running database.
</dd>
<dt>source</dt>
<dd>
This file creates the <b>CLASSPATH</b> required
to run the examples and tests.
You have to edit it for your environment.
</dd>
<dt>rpcServiceExample</dt>
<dd>
This starts the RPCServiceExample.
This is required by ExampleEasyRPC.
</dd>
<dt>exampleGet</dt>
<dd>
This runs ExampleGet.
</dd>
<dt>exampleGetDouble</dt>
<dd>
This runs ExampleGetDouble
</dd>
<dt>doublePut</dt>
<dd>
This runs DoublePut.
</dd>
<dt>doubleArrayPut</dt>
<dd>
This runs DoubleArrayPut
</dd>
<dt>exampleMonitor</dt>
<dd>
This runs ExampleMonitor
</dd>
<dt>exampleMonitorCallback</dt>
<dd>
This runs ExampleMonitorCallback
</dd>
<dt>exampleMultiMonitor</dt>
<dd>
This runs ExampleMultiMonitor.
It and polls every few seconds for monitor events.
It gets data as NTMultiChannel.
</dd>
<dt>exampleMultiMonitorDouble</dt>
<dd>
This runs ExampleMultiMonitorDouble.
It has an event listener for new events.
It gets data as an array of doubles.
</dd>
</dl>
<h3>Examples</h3>
<p>These are examples in package <b>org.epics.pvaccess.easyPVA.example</b>
See the source code for each example.
In order to run the examples exampleDatabaseEasyPVA must be running.
</p>
<p>There is a shell command to run each example,</p>
<h3>Tests</h3>
<p>A test directory has a number of tests for easyPVAJava.
In order to run the tests both exampleDatabaseEasyPVA and rpcServiceExample
must be running.
For now these tests are being run as eclipse unit tests.
The tests also provide examples of using EasyPVA.
</p>
</div> <!-- class="contents" -->
</body>
</html>

13
example/Makefile Normal file
View File

@ -0,0 +1,13 @@
# Makefile at top of application tree
TOP = .
include $(TOP)/configure/CONFIG
DIRS += configure
DIRS += src
src_DEPEND_DIRS = configure
include $(TOP)/configure/RULES_TOP

29
example/configure/CONFIG Normal file
View File

@ -0,0 +1,29 @@
# CONFIG - Load build configuration data
#
# Do not make changes to this file!
# Allow user to override where the build rules come from
RULES = $(EPICS_BASE)
# RELEASE files point to other application tops
include $(TOP)/configure/RELEASE
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
ifdef T_A
-include $(TOP)/configure/RELEASE.Common.$(T_A)
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
endif
CONFIG = $(RULES)/configure
include $(CONFIG)/CONFIG
# Override the Base definition:
INSTALL_LOCATION = $(TOP)
# CONFIG_SITE files contain other build configuration settings
include $(TOP)/configure/CONFIG_SITE
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
ifdef T_A
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
endif

View File

@ -0,0 +1,27 @@
# CONFIG_SITE
# Make any application-specific changes to the EPICS build
# configuration variables in this file.
#
# Host/target specific settings can be specified in files named
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
# CONFIG_SITE.Common.$(T_A)
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
# CHECK_RELEASE controls the consistency checking of the support
# applications pointed to by the RELEASE* files.
# Normally CHECK_RELEASE should be set to YES.
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking but
# continue building anyway if conflicts are found.
CHECK_RELEASE = WARN
# To install files into a location other than $(TOP) define
# INSTALL_LOCATION here.
#INSTALL_LOCATION=</path/name/to/install/top>
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/../../CONFIG_SITE.local
-include $(TOP)/../configure/CONFIG_SITE.local

View File

@ -0,0 +1,7 @@
EPICS_BASE=/home/install/epics/base
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
EPICSV4HOME=/home/hg
PVCOMMON=${EPICSV4HOME}/pvCommonCPP
PVDATA=${EPICSV4HOME}/pvDataCPP
PVACCESS=${EPICSV4HOME}/pvAccessCPP
EASYPVA==${EPICSV4HOME}/easyPVACPP

View File

@ -0,0 +1,8 @@
TOP=..
include $(TOP)/configure/CONFIG
TARGETS = $(CONFIG_TARGETS)
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
include $(TOP)/configure/RULES

41
example/configure/RELEASE Normal file
View File

@ -0,0 +1,41 @@
# pvDatabaseCPP/example RELEASE - Location of external support modules
#
# IF YOU CHANGE this file or any file it includes you must
# subsequently do a "gnumake rebuild" in the application's
# top level directory.
#
# The build process does not check dependencies against files
# that are outside this application, thus you should also do a
# "gnumake rebuild" in the top level directory after EPICS_BASE
# or any other external module pointed to below is rebuilt.
#
# Host- or target-specific settings can be given in files named
# RELEASE.$(EPICS_HOST_ARCH).Common
# RELEASE.Common.$(T_A)
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
# EPICS V4 Developers: Do not edit the locations in this file!
#
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
# PVASRV = /path/to/epics/pvaSrvCPP
# PVACCESS = /path/to/epics/pvAccessCPP
# PVDATA = /path/to/epics/pvDataCPP
# PVCOMMON = /path/to/epics/pvCommonCPP
# EPICS_BASE = /path/to/epics/base
# If this example is built in a directory under pvDatabaseCPP,
# use the following definitions:
EASYPVA = $(TOP)/..
-include $(TOP)/../configure/RELEASE.local
-include $(TOP)/../../RELEASE.local
# If you copied this example from pvDatabaseCPP to be built as a
# standalone TOP, adjust and use the following definitions:
#EASYPVA = /path/to/epics/easyPVACPP
#-include $(TOP)/../RELEASE.local
#-include $(TOP)/configure/RELEASE.local

6
example/configure/RULES Normal file
View File

@ -0,0 +1,6 @@
# RULES
include $(CONFIG)/RULES
# Library should be rebuilt because LIBOBJS may have changed.
$(LIBNAME): ../Makefile

View File

@ -0,0 +1,2 @@
#RULES.ioc
include $(CONFIG)/RULES.ioc

View File

@ -0,0 +1,2 @@
#RULES_DIRS
include $(CONFIG)/RULES_DIRS

View File

@ -0,0 +1,3 @@
#RULES_TOP
include $(CONFIG)/RULES_TOP

27
example/src/Makefile Normal file
View File

@ -0,0 +1,27 @@
TOP=..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
PROD_HOST += exampleEasyPVStructure
exampleEasyPVStructure_SRCS += exampleEasyPVStructure.cpp
exampleEasyPVStructure_LIBS += easyPVA
exampleEasyPVStructure_LIBS += pvAccess
exampleEasyPVStructure_LIBS += pvData
exampleEasyPVStructure_LIBS += Com
PROD_HOST += exampleEasyGet
exampleEasyGet_SRCS += exampleEasyGet.cpp
exampleEasyGet_LIBS += easyPVA
exampleEasyGet_LIBS += pvAccess
exampleEasyGet_LIBS += pvData
exampleEasyGet_LIBS += Com
#===========================
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE

View File

@ -0,0 +1,49 @@
/*exampleEasyGet.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
/* Author: Marty Kraimer */
#include <iostream>
#include <pv/easyPVA.h>
#include <pv/clientFactory.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::easyPVA;
int main(int argc,char *argv[])
{
ClientFactory::start();
EasyPVAPtr easyPVA = EasyPVA::create();
double value;
try {
cout << "short way\n";
value = easyPVA->createChannel("exampleDouble")->createGet()->getDouble();
cout << "as double " << value << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
try {
cout << "long way\n";
EasyChannelPtr easyChannel = easyPVA->createChannel("exampleDouble");
easyChannel->connect(2.0);
EasyGetPtr easyGet = easyChannel->createGet();
value = easyGet->getDouble();
cout << "as double " << value << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
cout << "done\n";
ClientFactory::stop();
return 0;
}

View File

@ -0,0 +1,69 @@
/*exampleEasyPVStructure.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
/* Author: Marty Kraimer */
#include <iostream>
#include <pv/easyPVA.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::easyPVA;
int main(int argc,char *argv[])
{
EasyPVAPtr easyPVA = EasyPVA::create();
StandardPVFieldPtr standardPVField = getStandardPVField();
EasyPVStructurePtr easyStruct = easyPVA->createEasyPVStructure();
PVStructurePtr pvStructure = standardPVField->scalar(pvDouble,"alarm,timeStamp");
easyStruct->setPVStructure(pvStructure);
cout << easyStruct->getPVStructure() << endl;
cout << "as double " << easyStruct->getDouble() << endl;
cout << "as float " << easyStruct->getFloat() << endl;
try {
cout << "as ubyte " << easyStruct->getUByte() << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
pvStructure = standardPVField->scalar(pvInt,"alarm,timeStamp");
easyStruct->setPVStructure(pvStructure);
cout << easyStruct->getPVStructure() << endl;
cout << "as double " << easyStruct->getDouble() << endl;
cout << "as float " << easyStruct->getFloat() << endl;
cout << "as int " << easyStruct->getInt() << endl;
cout << "as uint " << easyStruct->getUInt() << endl;
cout << "as long " << easyStruct->getLong() << endl;
cout << "as ulong " << easyStruct->getULong() << endl;
try {
cout << "as byte " << easyStruct->getByte() << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
try {
cout << "as ubyte " << easyStruct->getUByte() << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
try {
cout << "as short " << easyStruct->getShort() << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
try {
cout << "as ushort " << easyStruct->getUShort() << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
return 0;
}

22
src/Makefile Normal file
View File

@ -0,0 +1,22 @@
# This is a Makefile fragment, see ../Makefile
TOP = ..
include $(TOP)/configure/CONFIG
LIBRARY += easyPVA
INC += easyPVA.h
LIBSRCS += easyPVA.cpp
LIBSRCS += easyPVStructure.cpp
LIBSRCS += easyChannel.cpp
LIBSRCS += easyGet.cpp
#LIBSRCS += easyPut.cpp
#LIBSRCS += easyMonitor.cpp
#LIBSRCS += easyRPC.cpp
easyPVA_LIBS += pvAccess pvData Com
easyPVA_LIBS += $(EPICS_BASE_IOC_LIBS)
include $(TOP)/configure/RULES

420
src/easyChannel.cpp Normal file
View File

@ -0,0 +1,420 @@
/* easyChannel.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.02
*/
#define epicsExportSharedSymbols
#include <sstream>
#include <pv/event.h>
#include <pv/lock.h>
#include <pv/easyPVA.h>
#include <pv/createRequest.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
class epicsShareClass EasyChannelImpl :
public EasyChannel,
public std::tr1::enable_shared_from_this<EasyChannelImpl>
{
public:
EasyChannelImpl(
EasyPVAPtr const &pva,
string const & channelName,
string const & providerName);
~EasyChannelImpl();
// from EasyChannel
void channelCreated(const Status& status, Channel::shared_pointer const & channel);
void channelStateChange(
Channel::shared_pointer const & channel,
Channel::ConnectionState connectionState);
tr1::shared_ptr<Channel> getChannel();
string getRequesterName();
void message(
string const & message,
MessageType messageType);
virtual void destroy();
virtual string getChannelName();
virtual void connect(double timeout);
virtual void issueConnect();
virtual Status waitConnect(double timeout);
virtual EasyFieldPtr createField();
virtual EasyFieldPtr createField(string const & subField);
virtual EasyProcessPtr createProcess();
virtual EasyProcessPtr createProcess(string const & request);
virtual EasyProcessPtr createProcess(PVStructurePtr const & pvRequest);
virtual EasyGetPtr createGet();
virtual EasyGetPtr createGet(string const & request);
virtual EasyGetPtr createGet(PVStructurePtr const & pvRequest);
virtual EasyPutPtr createPut();
virtual EasyPutPtr createPut(string const & request);
virtual EasyPutPtr createPut(PVStructurePtr const & pvRequest);
virtual EasyPutGetPtr createPutGet();
virtual EasyPutGetPtr createPutGet(string const & request);
virtual EasyPutGetPtr createPutGet(PVStructurePtr const & pvRequest);
virtual EasyRPCPtr createRPC();
virtual EasyRPCPtr createRPC(string const & request);
virtual EasyRPCPtr createRPC(PVStructurePtr const & pvRequest);
virtual EasyArrayPtr createArray();
virtual EasyArrayPtr createArray(string const & request);
virtual EasyArrayPtr createArray(PVStructurePtr const & pvRequest);
virtual EasyMonitorPtr createMonitor();
virtual EasyMonitorPtr createMonitor(string const & request);
virtual EasyMonitorPtr createMonitor(PVStructurePtr const & pvRequest);
EasyChannelPtr getPtrSelf()
{
return shared_from_this();
}
private:
enum ConnectState {connectIdle,connectActive,notConnected,connected};
EasyPVAPtr easyPVA;
string channelName;
string providerName;
ConnectState connectState;
bool isDestroyed;
CreateRequest::shared_pointer createRequest;
Status channelConnectStatus;
Mutex mutex;
Event waitForConnect;
Channel::shared_pointer channel;
ChannelRequester::shared_pointer channelRequester;
};
namespace easyChannel {
class ChannelRequesterImpl : public ChannelRequester
{
EasyChannelImpl *easyChannel;
public:
ChannelRequesterImpl(EasyChannelImpl *easyChannel)
: easyChannel(easyChannel) {}
virtual void channelCreated(
const Status& status,
Channel::shared_pointer const & channel)
{ easyChannel->channelCreated(status,channel); }
virtual void channelStateChange(
Channel::shared_pointer const & channel,
Channel::ConnectionState connectionState)
{easyChannel->channelStateChange(channel,connectionState);}
virtual tr1::shared_ptr<Channel> getChannel() {return easyChannel->getChannel();}
virtual string getRequesterName()
{return easyChannel->getRequesterName();}
virtual void message(
string const & message,
MessageType messageType)
{ easyChannel->message(message,messageType); }
virtual void destroy() {easyChannel->destroy();}
};
} //end namespace easyChannel`
using namespace epics::easyPVA::easyChannel;
EasyChannelImpl::EasyChannelImpl(
EasyPVAPtr const &easyPVA,
string const & channelName,
string const & providerName)
: easyPVA(easyPVA),
channelName(channelName),
providerName(providerName),
connectState(connectIdle),
isDestroyed(false),
createRequest(CreateRequest::create())
{}
EasyChannelImpl::~EasyChannelImpl()
{
destroy();
}
void EasyChannelImpl::channelCreated(const Status& status, Channel::shared_pointer const & channel)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
channelConnectStatus = status;
this->channel = channel;
}
void EasyChannelImpl::channelStateChange(
Channel::shared_pointer const & channel,
Channel::ConnectionState connectionState)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
bool waitingForConnect = false;
if(connectState==connectActive) waitingForConnect = true;
if(connectionState!=Channel::CONNECTED) {
string mess(channelName + " connection state " + Channel::ConnectionStateNames[connectionState]);
message(mess,errorMessage);
channelConnectStatus = Status(Status::STATUSTYPE_ERROR,mess);
connectState = notConnected;
} else {
connectState = connected;
}
if(waitingForConnect) waitForConnect.signal();
}
tr1::shared_ptr<Channel> EasyChannelImpl::getChannel()
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
return channel;
}
string EasyChannelImpl::getRequesterName()
{
return easyPVA->getRequesterName();
}
void EasyChannelImpl::message(
string const & message,
MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
easyPVA->message(message, messageType);
}
void EasyChannelImpl::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(channel) channel->destroy();
channel.reset();
}
string EasyChannelImpl::getChannelName()
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
return channelName;
}
void EasyChannelImpl::connect(double timeout)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
issueConnect();
Status status = waitConnect(timeout);
if(status.isOK()) return;
stringstream ss;
ss << "channel " << getChannelName() << " EasyChannel::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyChannelImpl::issueConnect()
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
if(connectState!=connectIdle) {
throw std::runtime_error("easyChannel already connected");
}
channelRequester = ChannelRequester::shared_pointer(new ChannelRequesterImpl(this));
connectState = connectActive;
ChannelProviderRegistry::shared_pointer reg = getChannelProviderRegistry();
ChannelProvider::shared_pointer provider = reg->getProvider(providerName);
channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT);
}
Status EasyChannelImpl::waitConnect(double timeout)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
waitForConnect.wait(timeout);
if(connectState==connected) return Status::Ok;
return Status(Status::STATUSTYPE_ERROR,channelConnectStatus.getMessage());
}
EasyFieldPtr EasyChannelImpl::createField()
{
return createField("");
}
EasyFieldPtr EasyChannelImpl::createField(string const & subField)
{
throw std::runtime_error("EasyChannel::createField not implemented");
}
EasyProcessPtr EasyChannelImpl::createProcess()
{
return createProcess("");
}
EasyProcessPtr EasyChannelImpl::createProcess(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createProcess invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createProcess(pvRequest);
}
EasyProcessPtr EasyChannelImpl::createProcess(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createProcess not implemented");
}
EasyGetPtr EasyChannelImpl::createGet()
{
return EasyChannelImpl::createGet("value,alarm.timeStamp");
}
EasyGetPtr EasyChannelImpl::createGet(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createGet invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createGet(pvRequest);
}
EasyGetPtr EasyChannelImpl::createGet(PVStructurePtr const & pvRequest)
{
if(connectState!=connected) connect(5.0);
if(connectState!=connected) throw std::runtime_error("EasyChannel::creatGet not connected");
return EasyGetFactory::createEasyGet(easyPVA,getPtrSelf(),channel,pvRequest);
}
EasyPutPtr EasyChannelImpl::createPut()
{
return createPut("value");
}
EasyPutPtr EasyChannelImpl::createPut(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createPut invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createPut(pvRequest);
}
EasyPutPtr EasyChannelImpl::createPut(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createPut not implemented");
}
EasyPutGetPtr EasyChannelImpl::createPutGet()
{
return createPutGet("putField(argument)getField(result)");
}
EasyPutGetPtr EasyChannelImpl::createPutGet(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createPutGet invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createPutGet(pvRequest);
}
EasyPutGetPtr EasyChannelImpl::createPutGet(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createPutGet not implemented");
}
EasyRPCPtr EasyChannelImpl::createRPC()
{
return createRPC("");
}
EasyRPCPtr EasyChannelImpl::createRPC(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createRPC invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createRPC(pvRequest);
}
EasyRPCPtr EasyChannelImpl::createRPC(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createRPC not implemented");
}
EasyArrayPtr EasyChannelImpl::createArray()
{
return createArray("value");
}
EasyArrayPtr EasyChannelImpl::createArray(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createArray invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createArray(pvRequest);
}
EasyArrayPtr EasyChannelImpl::createArray(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createArray not implemented");
}
EasyMonitorPtr EasyChannelImpl::createMonitor()
{
return createMonitor("value,alarm,timeStamp");
}
EasyMonitorPtr EasyChannelImpl::createMonitor(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createMonitor invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createMonitor(pvRequest);
}
EasyMonitorPtr EasyChannelImpl::createMonitor(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createMonitor not implemented");
}
EasyChannelPtr EasyChannelFactory::createEasyChannel(
EasyPVAPtr const &easyPVA,
string const & channelName)
{
return EasyChannelFactory::createEasyChannel(easyPVA,channelName,"pva");
}
EasyChannelPtr EasyChannelFactory::createEasyChannel(
EasyPVAPtr const &easyPVA,
string const & channelName,
string const & providerName)
{
EasyChannelPtr channel(new EasyChannelImpl(easyPVA,channelName,providerName));
return channel;
}
}}

551
src/easyGet.cpp Normal file
View File

@ -0,0 +1,551 @@
/* easyGet.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.02
*/
#define epicsExportSharedSymbols
#include <sstream>
#include <pv/event.h>
#include <pv/lock.h>
#include <pv/easyPVA.h>
#include <pv/createRequest.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
class epicsShareClass EasyGetImpl :
public EasyGet,
public std::tr1::enable_shared_from_this<EasyGetImpl>
{
public:
EasyGetImpl(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest);
~EasyGetImpl();
// from ChannelGetRequester
string getRequesterName();
void message(string const & message,MessageType messageType);
void channelGetConnect(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const & structure);
void getDone(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet);
// from EasyGet
virtual void destroy();
virtual void connect();
virtual void issueConnect();
virtual Status waitConnect();
virtual void get();
virtual void issueGet();
virtual Status waitGet();
virtual BitSetPtr getBitSet();
// from EasyPVStructure
virtual void setMessagePrefix(std::string const & value);
virtual void setPVStructure(epics::pvData::PVStructurePtr const & pvStructure);
virtual Alarm getAlarm();
virtual TimeStamp getTimeStamp();
virtual bool hasValue();
virtual bool isValueScalar();
virtual bool isValueScalarArray();
virtual PVFieldPtr getValue();
virtual PVScalarPtr getScalarValue();
virtual std::tr1::shared_ptr<PVArray> getArrayValue();
virtual std::tr1::shared_ptr<PVScalarArray> getScalarArrayValue();
virtual bool getBoolean();
virtual int8 getByte();
virtual int16 getShort();
virtual int32 getInt();
virtual int64 getLong();
virtual uint8 getUByte();
virtual uint16 getUShort();
virtual uint32 getUInt();
virtual uint64 getULong();
virtual float getFloat();
virtual double getDouble();
virtual std::string getString();
virtual shared_vector<boolean> getBooleanArray();
virtual shared_vector<int8> getByteArray();
virtual shared_vector<int16> getShortArray();
virtual shared_vector<int32> getIntArray();
virtual shared_vector<int64> getLongArray();
virtual shared_vector<uint8> getUByteArray();
virtual shared_vector<uint16> getUShortArray();
virtual shared_vector<uint32> getUIntArray();
virtual shared_vector<uint64> getULongArray();
virtual shared_vector<float> getFloatArray();
virtual shared_vector<double> getDoubleArray();
virtual shared_vector<std::string> getStringArray();
virtual PVStructurePtr getPVStructure();
EasyGetPtr getPtrSelf()
{
return shared_from_this();
}
private:
enum GetConnectState {connectIdle,connectActive,connected};
EasyPVAPtr easyPVA;
EasyChannelPtr easyChannel;
Channel::shared_pointer channel;
ChannelGetRequester::shared_pointer getRequester;
PVStructurePtr pvRequest;
Mutex mutex;
Event waitForConnect;
Event waitForGet;
EasyPVStructurePtr easyPVStructure;
string messagePrefix;
bool isDestroyed;
Status channelGetConnectStatus;
Status channelGetStatus;
ChannelGet::shared_pointer channelGet;
BitSet::shared_pointer bitSet;
GetConnectState connectState;
enum GetState {getIdle,getActive,getComplete};
GetState getState;
bool getSuccess;
};
namespace easyGet {
class ChannelGetRequesterImpl : public ChannelGetRequester
{
EasyGetImpl * easyGet;
public:
ChannelGetRequesterImpl(EasyGetImpl * easyGet)
: easyGet(easyGet) {}
virtual string getRequesterName()
{return easyGet->getRequesterName();}
virtual void message(string const & message,MessageType messageType)
{easyGet->message(message,messageType);}
virtual void channelGetConnect(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const & structure)
{easyGet->channelGetConnect(status,channelGet,structure);}
virtual void getDone(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet)
{easyGet->getDone(status,channelGet,pvStructure,bitSet);}
};
} // namespace easyGet
using namespace epics::easyPVA::easyGet;
EasyGetImpl::EasyGetImpl(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
: easyPVA(pva),
easyChannel(easyChannel),
channel(channel),
pvRequest(pvRequest),
easyPVStructure(pva->createEasyPVStructure()),
isDestroyed(false),
connectState(connectIdle),
getState(getIdle)
{
easyPVStructure->setMessagePrefix("channel " + channel->getChannelName() + " EasyGet");
}
EasyGetImpl::~EasyGetImpl()
{
destroy();
}
// from ChannelGetRequester
string EasyGetImpl::getRequesterName()
{
return easyPVA->getRequesterName();
}
void EasyGetImpl::message(string const & message,MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
easyPVA->message(message, messageType);
}
void EasyGetImpl::channelGetConnect(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const & structure)
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
channelGetConnectStatus = status;
this->channelGet = channelGet;
if(status.isOK()) {
connectState = connected;
} else {
connectState = connectIdle;
}
waitForConnect.signal();
}
void EasyGetImpl::getDone(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet)
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
easyPVStructure->setPVStructure(pvStructure);
this->bitSet = bitSet;
channelGetStatus = status;
if(status.isOK()) {
getState = getComplete;
} else {
getState = getIdle;
}
waitForGet.signal();
}
// from EasyGet
void EasyGetImpl::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(channelGet) channelGet->destroy();
channelGet.reset();
}
void EasyGetImpl::connect()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyGet::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyGetImpl::issueConnect()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(connectState!=connectIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " easyGet already connected ";
throw std::runtime_error(ss.str());
}
getRequester = ChannelGetRequester::shared_pointer(new ChannelGetRequesterImpl(this));
connectState = connectActive;
channelGet = channel->createChannelGet(getRequester,pvRequest);
}
Status EasyGetImpl::waitConnect()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(connectState!=connectActive) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " easyGet illegal connect state ";
throw std::runtime_error(ss.str());
}
waitForConnect.wait();
if(connectState==connected) return Status::Ok;
return Status(Status::STATUSTYPE_ERROR,channelGetConnectStatus.getMessage());
}
void EasyGetImpl::get()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
issueGet();
Status status = waitGet();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyGet::get " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyGetImpl::issueGet()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(connectState==connectIdle) connect();
if(getState!=getIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyGet::issueGet get aleady active ";
throw std::runtime_error(ss.str());
}
getState = getActive;
channelGet->get();
}
Status EasyGetImpl::waitGet()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(getState!=getActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyGet::waitGet llegal get state";
throw std::runtime_error(ss.str());
}
waitForGet.wait();
if(getState==getComplete) {
getState = getIdle;
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetStatus.getMessage());
}
BitSetPtr EasyGetImpl::getBitSet()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return bitSet;
}
void EasyGetImpl::setMessagePrefix(string const & value)
{
messagePrefix = value;
if(value.size()>0) messagePrefix += " ";
}
void EasyGetImpl::setPVStructure(epics::pvData::PVStructurePtr const & pvStructure)
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
throw std::runtime_error("easyGet does not implement setPVStructure");
}
Alarm EasyGetImpl::getAlarm()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getAlarm();
}
TimeStamp EasyGetImpl::getTimeStamp()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getTimeStamp();
}
bool EasyGetImpl::hasValue()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->hasValue();
}
bool EasyGetImpl::isValueScalar()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->isValueScalar();
}
bool EasyGetImpl::isValueScalarArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->isValueScalarArray();
}
PVFieldPtr EasyGetImpl::getValue()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getValue();
}
PVScalarPtr EasyGetImpl::getScalarValue()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getScalarValue();
}
std::tr1::shared_ptr<PVArray> EasyGetImpl::getArrayValue()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getArrayValue();
}
std::tr1::shared_ptr<PVScalarArray> EasyGetImpl::getScalarArrayValue()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getScalarArrayValue();
}
bool EasyGetImpl::getBoolean()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getBoolean();
}
int8 EasyGetImpl::getByte()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getByte();
}
int16 EasyGetImpl::getShort()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getShort();
}
int32 EasyGetImpl::getInt()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getInt();
}
int64 EasyGetImpl::getLong()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getLong();
}
uint8 EasyGetImpl::getUByte()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getUByte();
}
uint16 EasyGetImpl::getUShort()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getUShort();
}
uint32 EasyGetImpl::getUInt()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getUInt();
}
uint64 EasyGetImpl::getULong()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getULong();
}
float EasyGetImpl::getFloat()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getFloat();
}
double EasyGetImpl::getDouble()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->isValueScalar();
}
std::string EasyGetImpl::getString()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getString();
}
shared_vector<boolean> EasyGetImpl::getBooleanArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getBooleanArray();
}
shared_vector<int8> EasyGetImpl::getByteArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getByteArray();
}
shared_vector<int16> EasyGetImpl::getShortArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getShortArray();
}
shared_vector<int32> EasyGetImpl::getIntArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getIntArray();
}
shared_vector<int64> EasyGetImpl::getLongArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getLongArray();
}
shared_vector<uint8> EasyGetImpl::getUByteArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getUByteArray();
}
shared_vector<uint16> EasyGetImpl::getUShortArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getUShortArray();
}
shared_vector<uint32> EasyGetImpl::getUIntArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getUIntArray();
}
shared_vector<uint64> EasyGetImpl::getULongArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getULongArray();
}
shared_vector<float> EasyGetImpl::getFloatArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getFloatArray();
}
shared_vector<double> EasyGetImpl::getDoubleArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getDoubleArray();
}
shared_vector<std::string> EasyGetImpl::getStringArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getStringArray();
}
PVStructurePtr EasyGetImpl::getPVStructure()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getPVStructure();
}
EasyGetPtr EasyGetFactory::createEasyGet(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
{
EasyGetPtr epv(new EasyGetImpl(pva,easyChannel,channel,pvRequest));
return epv;
}
}}

105
src/easyPVA.cpp Normal file
View File

@ -0,0 +1,105 @@
/* easyPVA.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.02
*/
#define epicsExportSharedSymbols
#include <pv/easyPVA.h>
#include <pv/createRequest.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
static FieldCreatePtr fieldCreate = getFieldCreate();
static const string easyPVAName = "easyPVA";
static const string defaultProvider = "pva";
static UnionConstPtr variantUnion = fieldCreate->createVariantUnion();
EasyPVAPtr EasyPVA::create()
{
EasyPVAPtr xx(new EasyPVA());
return xx;
}
PVStructurePtr EasyPVA::createRequest(string const &request)
{
CreateRequest::shared_pointer createRequest = CreateRequest::create();
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
throw std::invalid_argument("invalid pvRequest: " + createRequest->getMessage());
}
return pvRequest;
}
EasyPVA::EasyPVA()
: isDestroyed(false)
{
}
EasyPVA::~EasyPVA() {destroy();}
void EasyPVA::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
std::list<EasyChannelPtr>::iterator channelIter;
while(true) {
channelIter = channelList.begin();
if(channelIter==channelList.end()) break;
channelList.erase(channelIter);
(*channelIter)->destroy();
}
std::list<EasyMultiChannelPtr>::iterator multiChannelIter;
#ifdef NOTDONE
while(true) {
multiChannelIter = multiChannelList.begin();
if(multiChannelIter==multiChannelList.end()) break;
multiChannelList.erase(multiChannelIter);
(*multiChannelIter)->destroy();
}
#endif
}
string EasyPVA:: getRequesterName()
{
static string name("easyPVA");
return name;
}
void EasyPVA::message(
string const & message,
MessageType messageType)
{
cout << getMessageTypeName(messageType) << " " << message << endl;
}
EasyPVStructurePtr EasyPVA::createEasyPVStructure()
{
return EasyPVStructureFactory::createEasyPVStructure();
}
EasyChannelPtr EasyPVA::createChannel(string const & channelName)
{
return EasyChannelFactory::createEasyChannel(getPtrSelf(),channelName);
}
EasyChannelPtr EasyPVA::createChannel(string const & channelName, string const & providerName)
{
return EasyChannelFactory::createEasyChannel(getPtrSelf(),channelName,providerName);
}
}}

721
src/easyPVA.h Normal file
View File

@ -0,0 +1,721 @@
/* easyPVA.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.02
*/
#ifndef EASYPVA_H
#define EASYPVA_H
#ifdef epicsExportSharedSymbols
# define easyPVAEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include <list>
#include <pv/requester.h>
#include <pv/status.h>
#include <pv/pvData.h>
#include <pv/pvCopy.h>
#include <pv/pvTimeStamp.h>
#include <pv/timeStamp.h>
#include <pv/pvAlarm.h>
#include <pv/alarm.h>
#include <pv/pvAccess.h>
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/createRequest.h>
#ifdef easyPVAEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef easyPVAEpicsExportSharedSymbols
#endif
#include <shareLib.h>
namespace epics { namespace easyPVA {
class EasyPVA;
typedef std::tr1::shared_ptr<EasyPVA> EasyPVAPtr;
class EasyPVStructure;
typedef std::tr1::shared_ptr<EasyPVStructure> EasyPVStructurePtr;
class EasyChannel;
typedef std::tr1::shared_ptr<EasyChannel> EasyChannelPtr;
class EasyField;
typedef std::tr1::shared_ptr<EasyField> EasyFieldPtr;
class EasyProcess;
typedef std::tr1::shared_ptr<EasyProcess> EasyProcessPtr;
class EasyGet;
typedef std::tr1::shared_ptr<EasyGet> EasyGetPtr;
class EasyPut;
typedef std::tr1::shared_ptr<EasyPut> EasyPutPtr;
class EasyPutGet;
typedef std::tr1::shared_ptr<EasyPutGet> EasyPutGetPtr;
class EasyMonitor;
typedef std::tr1::shared_ptr<EasyMonitor> EasyMonitorPtr;
class EasyArray;
typedef std::tr1::shared_ptr<EasyArray> EasyArrayPtr;
class EasyRPC;
typedef std::tr1::shared_ptr<EasyRPC> EasyRPCPtr;
class EasyMultiData;
typedef std::tr1::shared_ptr<EasyMultiData> EasyMultiDataPtr;
class EasyMultiChannel;
typedef std::tr1::shared_ptr<EasyMultiChannel> EasyMultiChannelPtr;
class EasyMultiGet;
typedef std::tr1::shared_ptr<EasyMultiGet> EasyMultiGetPtr;
class EasyMultiPut;
typedef std::tr1::shared_ptr<EasyMultiPut> EasyMultiPutPtr;
class EasyMultiMonitor;
typedef std::tr1::shared_ptr<EasyMultiMonitor> EasyMultiMonitorPtr;
/**
* @brief EasyPVA is an easy to use interface to pvAccess.
*
* @author mrk
*/
class epicsShareClass EasyPVA :
public epics::pvData::Requester,
public std::tr1::enable_shared_from_this<EasyPVA>
{
public:
POINTER_DEFINITIONS(EasyPVA);
/**
* Destructor
*/
~EasyPVA();
/**
* @brief Create an instance of EasyPVA
* @return shared_ptr to new instance.
*/
static EasyPVAPtr create();
/** @brief get the requester name.
* @return The name.
*/
virtual std::string getRequesterName();
/**
* @brief A new message.
* If a requester is set then it is called otherwise message is displayed
* on standard out.
* @param message The message.
* @param messageType The type.
*/
virtual void message(
std::string const & message,
epics::pvData::MessageType messageType);
/**
* @brief Destroy all the channels and multiChannels.
*/
void destroy();
/**
* @brief Create a EasyPVStructure.
* @return The interface to the EasyPVStructure.
*/
EasyPVStructurePtr createEasyPVStructure();
/**
* @brief Create an EasyChannel. The provider is pvAccess.
* @param channelName The channelName.
* @return The interface.
*/
EasyChannelPtr createChannel(std::string const & channelName);
/**
* @brief Create an EasyChannel with the specified provider.
* @param channelName The channelName.
* @param providerName The provider.
* @return The interface or null if the provider does not exist.
*/
EasyChannelPtr createChannel(
std::string const & channelName,
std::string const & providerName);
/**
* @brief Create an EasyMultiChannel. The provider is pvAccess.
* @param channelName The channelName array.
* @return The interface.
*/
EasyMultiChannelPtr createMultiChannel(epics::pvData::StringArray const & channelName);
/**
* @brief Create an EasyMultiChannel with the specified provider.
* @param channelName The channelName array.
* @param providerName The provider.
* @return The interface.
*/
EasyMultiChannelPtr createMultiChannel(
epics::pvData::StringArray const & channelName,
std::string const & providerName);
/**
* @brief Create an EasyMultiChannel with the specified provider.
* @param channelName The channelName.
* @param providerName The provider.
* @param union The union interface for the value field of each channel.
* @return The interface.
*/
EasyMultiChannelPtr createMultiChannel(
epics::pvData::StringArray const & channelName,
std::string const & providerName,
epics::pvData::UnionConstPtr const & u);
/**
* @brief Set a requester.
* The default is for EasyPVA to handle messages by printing to System.out.
* @param requester The requester.
*/
void setRequester(epics::pvData::RequesterPtr const & requester);
/**
* @brief Clear the requester. EasyPVA will handle messages.
*/
void clearRequester();
/**
* @brief get shared pointer to this
*/
EasyPVAPtr getPtrSelf()
{
return shared_from_this();
}
private:
EasyPVA();
epics::pvData::PVStructurePtr createRequest(std::string const &request);
std::list<EasyChannelPtr> channelList;
std::list<EasyMultiChannelPtr> multiChannelList;
epics::pvData::RequesterPtr requester;
bool isDestroyed;
epics::pvData::Mutex mutex;
};
/**
* @brief An easy to use alternative to directly calling the Channel methods of pvAccess.
*
* @author mrk
*/
class epicsShareClass EasyChannel
{
public:
POINTER_DEFINITIONS(EasyChannel);
/**
* @brief Destroy the pvAccess connection.
*/
virtual void destroy() = 0;
/**
* @brief Get the name of the channel to which EasyChannel is connected.
* @return The channel name.
*/
virtual std::string getChannelName() = 0;
/**
* @brief Connect to the channel.
* This calls issueConnect and waitConnect.
* An exception is thrown if connect fails.
* @param timeout The time to wait for connecting to the channel.
*/
virtual void connect(double timeout) = 0;
/**
* @brief Issue a connect request and return immediately.
*/
virtual void issueConnect() = 0;
/**
* @brief Wait until the connection completes or for timeout.
* @param timeout The time in second to wait.
* @return status.
*/
virtual epics::pvData::Status waitConnect(double timeout) = 0;
/**
* @brief Calls the next method with subField = "";
* @return The interface.
*/
virtual EasyFieldPtr createField() = 0;
/**
* @brief Create an EasyField for the specified subField.
* @param subField The syntax for subField is defined in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyFieldPtr createField(std::string const & subField) = 0;
/**
* @brief Calls the next method with request = "";
* @return The interface.
*/
virtual EasyProcessPtr createProcess() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyProcessPtr createProcess(std::string const & request) = 0;
/**
* @brief Creates an EasyProcess.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyProcessPtr createProcess(epics::pvData::PVStructurePtr const & pvRequest) = 0;
/**
* @brief Call the next method with request = "field(value,alarm,timeStamp)"
* @return The interface.
*/
virtual EasyGetPtr createGet() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then call the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyGetPtr createGet(std::string const & request) = 0;
/**
* @brief Creates an EasyGet.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyGetPtr createGet(epics::pvData::PVStructurePtr const & pvRequest) = 0;
/**
* @brief Call the next method with request = "field(value)"
* @return The interface.
*/
virtual EasyPutPtr createPut() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyPutPtr createPut(std::string const & request) = 0;
/**
* @brief Create an EasyPut.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyPutPtr createPut(epics::pvData::PVStructurePtr const & pvRequest) = 0;
/**
* @brief Call the next method with request = "record[process=true]putField(argument)getField(result)".
* @return The interface.
*/
virtual EasyPutGetPtr createPutGet() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyPutGetPtr createPutGet(std::string const & request) = 0;
/**
* @brief Create an EasyPutGet.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyPutGetPtr createPutGet(epics::pvData::PVStructurePtr const & pvRequest) = 0;
/**
* @brief Call createRPC(PVStructure(null))
* @return The interface.
*/
virtual EasyRPCPtr createRPC() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyRPCPtr createRPC(std::string const & request) = 0;
/**
* @brief Create an EasyRPC.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyRPCPtr createRPC(epics::pvData::PVStructurePtr const & pvRequest) = 0;
/**
* @brief Call the next method with request = "field(value)";
* @return The interface.
*/
virtual EasyArrayPtr createArray() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyArrayPtr createArray(std::string const & request) = 0;
/**
* @brief Create an EasyArray.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyArrayPtr createArray(epics::pvData::PVStructurePtr const & pvRequest) = 0;
/**
* @brief Call the next method with request = "field(value.alarm,timeStamp)"
* @return The interface.
*/
virtual EasyMonitorPtr createMonitor() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyMonitorPtr createMonitor(std::string const & request) = 0;
/**
* @brief Create an EasyMonitor.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyMonitorPtr createMonitor(epics::pvData::PVStructurePtr const & pvRequest) = 0;
};
/**
* @brief This is a factory for creating an EasyChannel
*
* @author mrk
*/
class epicsShareClass EasyChannelFactory
{
public:
/**
* @brief Create a EasyPVAStructure.
* @param easyPVA Interface to EasyPVA
* @param channelName The name of the channel.
* @return The interface to the EasyPVAStructure.
*/
static EasyChannelPtr createEasyChannel(
EasyPVAPtr const &easyPVA,
std::string const & channelName);
/**
* @brief Create a EasyPVAStructure.
* @param channelName The name of the channel.
* @param providerName The name of the provider.
* @return The interface to the EasyPVAStructure.
*/
static EasyChannelPtr createEasyChannel(
EasyPVAPtr const &easyPVA,
std::string const & channelName,
std::string const & providerName);
};
/**
* @brief This is a convenience wrapper for a PVStructure.
*
* @author mrk
*/
class epicsShareClass EasyPVStructure
{
public:
POINTER_DEFINITIONS(EasyPVStructure);
/**
* @brief Set a prefix to be added to any messages generated by EasyPVStructure.
* @param value The prefix.
*/
virtual void setMessagePrefix(std::string const & value) = 0;
/**
* @brief Set the pvStructure on which the remaining methods operate.
* @param pvStructure The structure.
*/
virtual void setPVStructure(epics::pvData::PVStructurePtr const & pvStructure) = 0;
/**
* @brief Get the top level pvStructure.
* @return The pvStructure. An exception is thrown if pvStructure does not exist.
*/
virtual epics::pvData::PVStructurePtr getPVStructure() = 0;
/**
* @brief Get the alarm.
* If the pvStructure as an alarm field it's values are returned.
* If no then alarm shows that not alarm defined.
* @return The alarm.
*/
virtual epics::pvData::Alarm getAlarm() = 0;
/**
* @brief Get the timeStamp.
* If the pvStructure as a timeStamp field, it's values are returned.
* If no then all fields are 0.
* @return The timeStamp.
*/
virtual epics::pvData::TimeStamp getTimeStamp() = 0;
/**
* @brief Is there a top level field named value of the PVstructure returned by channelGet?
* @return The answer.
*/
virtual bool hasValue() = 0;
/**
* @brief Is the value field a scalar?
* @return The answer.
*/
virtual bool isValueScalar() = 0;
/**
* @brief Is the value field a scalar array?
* @return The answer.
*/
virtual bool isValueScalarArray() = 0;
/**
* @brief Return the interface to the value field.
* @return The interface. an excetion is thrown if a value field does not exist.
*/
virtual epics::pvData::PVFieldPtr getValue() = 0;
/**
* @brief Return the interface to a scalar value field.
* @return The interface for a scalar value field.
* An exception is thown if no scalar value field.
*/
virtual epics::pvData::PVScalarPtr getScalarValue() = 0;
/**
* @brief Return the interface to an array value field.
* @return The interface.
* An exception is thown if no array value field.
*/
virtual std::tr1::shared_ptr<epics::pvData::PVArray> getArrayValue() = 0;
/**
* @brief Return the interface to a scalar array value field.
* @return Return the interface.
* An exception is thown if no scalar array value field.
*/
virtual std::tr1::shared_ptr<epics::pvData::PVScalarArray> getScalarArrayValue() = 0;
/**
* @brief Get the boolean value. If value is not a boolean an exception is thrown
* @return true or false.
*/
virtual bool getBoolean() = 0;
/**
* @brief Get the value as a byte.
* If value is not a byte scalar an exception is thrown.
* @return The value.
*/
virtual epics::pvData::int8 getByte() = 0;
/**
* @brief Get the value as a short.
* If value is not a numeric scalar an exception is thrown
* @return The value.
* An exception is also thrown if the actualy type can cause an overflow.
*/
virtual epics::pvData::int16 getShort() = 0;
/**
* @brief Get the value as an int.
* If value is not a numeric scalar an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
*/
virtual epics::pvData::int32 getInt() = 0;
/**
* @brief Get the value as a long.
* If value is not a numeric scalar an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
*/
virtual epics::pvData::int64 getLong() = 0;
/**
* @brief Get the value as an unsigned byte.
* If value is not a numeric scalar an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
*/
virtual epics::pvData::uint8 getUByte() = 0;
/**
* @brief Get the value as a short.
* If value is not a numeric scalar an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
*/
virtual epics::pvData::uint16 getUShort() = 0;
/**
* @brief Get the value as an unsigned int.
* @return If value is not a numeric scalar an exception is thrown
*/
virtual epics::pvData::uint32 getUInt() = 0;
/**
* @brief Get the value as an unsigned long.
* If value is not a numeric scalar an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
*/
virtual epics::pvData::uint64 getULong() = 0;
/**
* @brief Get the value as a float.
* If value is not a numeric scalar an exception is thrown.
* @return The value.
*/
virtual float getFloat() = 0;
/**
* @brief Get the value as a double.
* If value is not a numeric scalar an exception is thrown.
* @return The value.
*/
virtual double getDouble() = 0;
/**
* @brief Get the value as a string.
* If value is not a string an exception is thrown
* @return The value.
*/
virtual std::string getString() = 0;
/**
* @brief Get the value as a boolean array.
* If the value is not a boolean array an exception is thrown
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::boolean> getBooleanArray() = 0;
/**
* @brief Get the value as a byte array.
* @return If the value is not a numeric array an exception is thrown
*/
virtual epics::pvData::shared_vector<epics::pvData::int8> getByteArray() = 0;
/**
* @brief Get the value as a short array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::int16> getShortArray() = 0;
/**
* @brief Get the value as an int array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::int32> getIntArray() = 0;
/**
* @brief Get the value as a long array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::int64> getLongArray() = 0;
/**
* @brief Get the value as an unsigned byte array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::uint8> getUByteArray() = 0;
/**
* @brief Get the value as an unsigned short array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::uint16> getUShortArray() = 0;
/**
* Get the value as an unsigned int array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::uint32> getUIntArray() = 0;
/**
* @brief Get the value as an unsigned long array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::uint64> getULongArray() = 0;
/**
* @brief Get the value as a float array.
* If the value is not a numeric array an exception is thrown.
* @return The value.
*/
virtual epics::pvData::shared_vector<float> getFloatArray() = 0;
/**
* @brief Get the value as a double array.
* If the value is not a numeric array an exception is thrown.
* @return The value.
*/
virtual epics::pvData::shared_vector<double> getDoubleArray() = 0;
/**
* @brief Get the value as a string array.
* If the value is not a string array an exception is thrown.
* @return The value.
*/
virtual epics::pvData::shared_vector<std::string> getStringArray() = 0;
};
/**
* @brief This is a factory for creating an EasyPVStructure
*
* @author mrk
*/
class epicsShareClass EasyPVStructureFactory
{
public:
/**
* @brief Create a EasyPVAStructure.
* @return The interface to the EasyPVAStructure.
*/
static EasyPVStructurePtr createEasyPVStructure();
};
/**
* @brief An easy to use alternative to ChannelGet.
*
* @author mrk
*/
class epicsShareClass EasyGet :
public EasyPVStructure
{
public:
POINTER_DEFINITIONS(EasyGet);
/**
* @brief destructor
*/
virtual ~EasyGet(){}
/**
* @brief destroy an resources used.
*/
virtual void destroy() = 0;
/**
* @brief call issueConnect and then waitConnect.
* An exception is thrown if connect fails.
*/
virtual void connect() = 0;
/**
* @brief create the channelGet connection to the channel.
* This can only be called once.
* An exception is thrown if connect fails.
*/
virtual void issueConnect() = 0;
/**
* @brief wait until the channelGet connection to the channel is complete.
* @return status;
*/
virtual epics::pvData::Status waitConnect() = 0;
/**
* @brief Call issueGet and then waitGet.
* An exception is thrown if get fails.
*/
virtual void get() = 0;
/**
* @brief Issue a get and return immediately.
*/
virtual void issueGet() = 0;
/**
* @brief Wait until get completes.
* If failure getStatus can be called to get reason.
* @return (false,true) means (failure,success)
*/
virtual epics::pvData::Status waitGet() = 0;
/**
* @brief Get the bitSet for the top level structure.
* @return The bitSet.
*/
virtual epics::pvData::BitSetPtr getBitSet() = 0;
};
/**
* @brief This is a factory for creating an EasyGet.
*
* @author mrk
*/
class epicsShareClass EasyGetFactory
{
public:
/**
* @brief Create a EasyPVAStructure.
* @param &easyPVA Interface to EasyPVA
* @param easyChannel Interface to EasyChannel
* @param channel Interface to Channel
* @param pvRequest The request structure.
* @return The interface to the EasyPVAStructure.
*/
static EasyGetPtr createEasyGet(
EasyPVAPtr const &easyPVA,
EasyChannelPtr const & easyChannel,
epics::pvAccess::Channel::shared_pointer const & channel,
epics::pvData::PVStructurePtr const &pvRequest
);
};
}}
#endif /* EASYPVA_H */
/** @page Overview Documentation
*
* <a href = "easyPVA.html">easyPVA.html</a>
*
*/

597
src/easyPVStructure.cpp Normal file
View File

@ -0,0 +1,597 @@
/* easyPVStructure.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.02
*/
#define epicsExportSharedSymbols
#include <typeinfo>
#include <sstream>
#include <pv/easyPVA.h>
#include <pv/createRequest.h>
#include <pv/convert.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
typedef std::tr1::shared_ptr<epics::pvData::PVArray> PVArrayPtr;
static StructureConstPtr nullStructure;
static PVStructurePtr nullPVStructure;
static ConvertPtr convert = getConvert();
static Status statusOK(Status::Ok);
static Status statusDestroyed(Status::STATUSTYPE_ERROR,"was destroyed");
static Status statusNoPVStructure(Status::STATUSTYPE_ERROR,"setPVStructure not called");
static Status statusNoValue(Status::STATUSTYPE_ERROR,"no value field");
static Status statusNoScalar(Status::STATUSTYPE_ERROR,"value is not a scalar");
static Status statusMismatchedScalar(Status::STATUSTYPE_ERROR,"value is not a compatible scalar");
static Status statusNoArray(Status::STATUSTYPE_ERROR,"value is not a array");
static Status statusNoScalarArray(Status::STATUSTYPE_ERROR,"value is not a scalarArray");
static Status statusMismatchedScalarArray(Status::STATUSTYPE_ERROR,"value is not a compatible scalarArray");
static Status statusNoAlarm(Status::STATUSTYPE_ERROR,"no alarm field");
static Status statusNoTimeStamp(Status::STATUSTYPE_ERROR,"no timeStamp field");
class epicsShareClass EasyPVStructureImpl :
public EasyPVStructure,
public std::tr1::enable_shared_from_this<EasyPVStructureImpl>
{
public:
EasyPVStructureImpl();
~EasyPVStructureImpl(){}
virtual void setMessagePrefix(std::string const & value);
virtual void setPVStructure(PVStructurePtr const & pvStructure);
virtual PVStructurePtr getPVStructure();
virtual Alarm getAlarm();
virtual TimeStamp getTimeStamp();
virtual bool hasValue();
virtual bool isValueScalar();
virtual bool isValueScalarArray() ;
virtual PVFieldPtr getValue();
virtual PVScalarPtr getScalarValue();
virtual std::tr1::shared_ptr<PVArray> getArrayValue();
virtual std::tr1::shared_ptr<PVScalarArray> getScalarArrayValue();
virtual bool getBoolean();
virtual int8 getByte();
virtual int16 getShort();
virtual int32 getInt();
virtual int64 getLong();
virtual uint8 getUByte();
virtual uint16 getUShort();
virtual uint32 getUInt();
virtual uint64 getULong();
virtual float getFloat();
virtual double getDouble();
virtual std::string getString();
virtual shared_vector<boolean> getBooleanArray();
virtual shared_vector<int8> getByteArray();
virtual shared_vector<int16> getShortArray();
virtual shared_vector<int32> getIntArray();
virtual shared_vector<int64> getLongArray();
virtual shared_vector<uint8> getUByteArray();
virtual shared_vector<uint16> getUShortArray();
virtual shared_vector<uint32> getUIntArray();
virtual shared_vector<uint64> getULongArray();
virtual shared_vector<float> getFloatArray();
virtual shared_vector<double> getDoubleArray();
virtual shared_vector<string> getStringArray();
EasyPVStructurePtr getPtrSelf()
{
return shared_from_this();
}
private:
void checkPVStructure();
void checkValue();
bool checkOverflow(ScalarType source,ScalarType dest);
PVScalarPtr checkScalar(ScalarType scalarType);
PVScalarArrayPtr checkScalarArray(ScalarType elementType);
string messagePrefix;
PVStructurePtr pvStructure;
PVFieldPtr pvValue;
PVAlarm pvAlarm;
Alarm alarm;
PVTimeStamp pvTimeStamp;
TimeStamp timeStamp;
};
EasyPVStructureImpl::EasyPVStructureImpl()
{}
EasyPVStructurePtr EasyPVStructureFactory::createEasyPVStructure()
{
EasyPVStructurePtr epv(new EasyPVStructureImpl());
return epv;
}
void EasyPVStructureImpl::checkPVStructure()
{
if(pvStructure) return;
throw std::runtime_error(messagePrefix + statusNoPVStructure.getMessage());
}
void EasyPVStructureImpl::checkValue()
{
if(pvValue) return;
throw std::runtime_error(messagePrefix + statusNoValue.getMessage());
}
bool EasyPVStructureImpl::checkOverflow(ScalarType source,ScalarType dest)
{
if(dest==pvFloat||dest==pvDouble) return true;
if(!ScalarTypeFunc::isInteger(source) && !ScalarTypeFunc::isUInteger(source)) return false;
if(ScalarTypeFunc::isUInteger(dest)) {
if(ScalarTypeFunc::isUInteger(source)) {
if(dest>=source) return true;
return false;
}
if(ScalarTypeFunc::isInteger(source)) {
if(dest>=(source+4)) return true;
return false;
}
return false;
}
if(ScalarTypeFunc::isInteger(dest)) {
if(ScalarTypeFunc::isUInteger(source)) {
if(dest>(source-4)) return true;
return false;
}
if(ScalarTypeFunc::isInteger(source)) {
if(dest>=source) return true;
return false;
}
return false;
}
return false;
}
PVScalarPtr EasyPVStructureImpl::checkScalar(ScalarType scalarType)
{
checkPVStructure();
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + statusNoScalar.getMessage());
}
ScalarType type = pv->getScalar()->getScalarType();
if((scalarType==pvBoolean && type==pvBoolean)
|| (scalarType==pvString && type==pvString)) return pv;
if((ScalarTypeFunc::isNumeric(type) && ScalarTypeFunc::isNumeric(scalarType))
&& checkOverflow(type,scalarType)) return pv;
stringstream ss;
ss << messagePrefix << statusMismatchedScalar.getMessage();
ss << " source " << type << " dest " << scalarType;
throw std::runtime_error(ss.str());
}
PVScalarArrayPtr EasyPVStructureImpl::checkScalarArray(ScalarType elementType)
{
checkPVStructure();
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + statusNoScalarArray.getMessage());
}
ScalarType type = pv->getScalarArray()->getElementType();
if((elementType==pvBoolean && type==pvBoolean)
|| (elementType==pvBoolean && type==pvBoolean)) return pv;
if((ScalarTypeFunc::isNumeric(type) && ScalarTypeFunc::isNumeric(elementType))
&& checkOverflow(type,elementType)) return pv;
throw std::runtime_error(messagePrefix + statusMismatchedScalarArray.getMessage());
}
void EasyPVStructureImpl::setMessagePrefix(string const & value)
{
messagePrefix = value;
if(value.size()>0) messagePrefix += " ";
}
void EasyPVStructureImpl::setPVStructure(PVStructurePtr const & pvStructure)
{
this->pvStructure = pvStructure;
pvValue = pvStructure->getSubField("value");
}
PVStructurePtr EasyPVStructureImpl::getPVStructure()
{
checkPVStructure();
return pvStructure;
}
PVFieldPtr EasyPVStructureImpl::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr EasyPVStructureImpl::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + statusNoScalar.getMessage());
}
return pv;
}
PVArrayPtr EasyPVStructureImpl::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + statusNoArray.getMessage());
}
return pv;
}
PVScalarArrayPtr EasyPVStructureImpl::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + statusNoScalarArray.getMessage());
}
return pv;
}
Alarm EasyPVStructureImpl::getAlarm()
{
Alarm alarm;
alarm.setSeverity(undefinedAlarm);
alarm.setStatus(undefinedStatus);
alarm.setMessage("no alarm field");
if(!pvStructure) return alarm;
PVStructurePtr xxx = pvStructure->getSubField<PVStructure>("alarm");
if(xxx) {
pvAlarm.attach(xxx);
if(pvAlarm.isAttached()) {
pvAlarm.get(alarm);
pvAlarm.detach();
}
}
return alarm;;
}
TimeStamp EasyPVStructureImpl::getTimeStamp()
{
TimeStamp timeStamp;
if(!pvStructure) return timeStamp;
PVStructurePtr xxx = pvStructure->getSubField<PVStructure>("timeStamp");
if(xxx) {
pvTimeStamp.attach(xxx);
if(pvTimeStamp.isAttached()) {
pvTimeStamp.get(timeStamp);
pvTimeStamp.detach();
}
}
return timeStamp;;
}
bool EasyPVStructureImpl::hasValue()
{
if(!pvValue) return false;
return true;
}
bool EasyPVStructureImpl::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool EasyPVStructureImpl::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
bool EasyPVStructureImpl::getBoolean()
{
PVScalarPtr pvScalar = checkScalar(pvBoolean);
PVBooleanPtr pv = static_pointer_cast<PVBoolean>(pvScalar);
return pv->get();
}
int8 EasyPVStructureImpl::getByte()
{
PVScalarPtr pvScalar = checkScalar(pvByte);
return convert->toByte(pvScalar);
}
uint8 EasyPVStructureImpl::getUByte()
{
PVScalarPtr pvScalar = checkScalar(pvUByte);
return convert->toUByte(pvScalar);
}
int16 EasyPVStructureImpl::getShort()
{
PVScalarPtr pvScalar = checkScalar(pvShort);
return convert->toShort(pvScalar);
}
uint16 EasyPVStructureImpl::getUShort()
{
PVScalarPtr pvScalar = checkScalar(pvUShort);
return convert->toUShort(pvScalar);
}
int32 EasyPVStructureImpl::getInt()
{
PVScalarPtr pvScalar = checkScalar(pvInt);
return convert->toInt(pvScalar);
}
uint32 EasyPVStructureImpl::getUInt()
{
PVScalarPtr pvScalar = checkScalar(pvUInt);
return convert->toUInt(pvScalar);
}
int64 EasyPVStructureImpl::getLong()
{
PVScalarPtr pvScalar = checkScalar(pvLong);
return convert->toLong(pvScalar);
}
uint64 EasyPVStructureImpl::getULong()
{
PVScalarPtr pvScalar = checkScalar(pvULong);
return convert->toULong(pvScalar);
}
float EasyPVStructureImpl::getFloat()
{
PVScalarPtr pvScalar = checkScalar(pvFloat);
return convert->toFloat(pvScalar);
}
double EasyPVStructureImpl::getDouble()
{
PVScalarPtr pvScalar = checkScalar(pvDouble);
return convert->toDouble(pvScalar);
}
string EasyPVStructureImpl::getString()
{
PVScalarPtr pvScalar = checkScalar(pvString);
PVStringPtr pv = static_pointer_cast<PVString>(pvScalar);
return pv->get();
}
shared_vector<boolean> EasyPVStructureImpl::getBooleanArray()
{
checkScalarArray(pvBoolean);
PVBooleanArrayPtr pv = static_pointer_cast<PVBooleanArray>(pvValue);
return pv->reuse();
}
template <typename T>
shared_vector<T> copy(PVScalarArrayPtr const & pvScalarArray)
{
ScalarType elementType = pvScalarArray->getScalarArray()->getElementType();
switch(elementType) {
case pvBoolean :
break;
case pvByte :
{
PVByteArrayPtr pv = static_pointer_cast<PVByteArray>(pvScalarArray);
shared_vector<int8> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,int8>(data);
return to;
}
case pvShort :
{
PVShortArrayPtr pv = static_pointer_cast<PVShortArray>(pvScalarArray);
shared_vector<int16> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,int16>(data);
return to;
}
case pvInt :
{
PVIntArrayPtr pv = static_pointer_cast<PVIntArray>(pvScalarArray);
shared_vector<int32> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,int32>(data);
return to;
}
case pvLong :
{
PVLongArrayPtr pv = static_pointer_cast<PVLongArray>(pvScalarArray);
shared_vector<int64> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,int64>(data);
return to;
}
case pvUByte :
{
PVUByteArrayPtr pv = static_pointer_cast<PVUByteArray>(pvScalarArray);
shared_vector<uint8> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,uint8>(data);
return to;
}
case pvUShort :
{
PVUShortArrayPtr pv = static_pointer_cast<PVUShortArray>(pvScalarArray);
shared_vector<uint16> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,uint16>(data);
return to;
}
case pvUInt :
{
PVUIntArrayPtr pv = static_pointer_cast<PVUIntArray>(pvScalarArray);
shared_vector<uint32> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,uint32>(data);
return to;
}
case pvULong :
{
PVULongArrayPtr pv = static_pointer_cast<PVULongArray>(pvScalarArray);
shared_vector<uint64> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,uint64>(data);
return to;
}
case pvFloat :
{
PVFloatArrayPtr pv = static_pointer_cast<PVFloatArray>(pvScalarArray);
shared_vector<float> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,float>(data);
return to;
}
case pvDouble :
{
PVDoubleArrayPtr pv = static_pointer_cast<PVDoubleArray>(pvScalarArray);
shared_vector<double> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,double>(data);
return to;
}
case pvString :
break;
}
return shared_vector<T>();
}
shared_vector<int8> EasyPVStructureImpl::getByteArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvByte);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvByte) {
PVByteArrayPtr pv = static_pointer_cast<PVByteArray>(pvValue);
return pv->reuse();
}
shared_vector<int8> xx = copy<int8>(pvScalarArray);
return xx;
}
shared_vector<int16> EasyPVStructureImpl::getShortArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvShort);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvShort) {
PVShortArrayPtr pv = static_pointer_cast<PVShortArray>(pvValue);
return pv->reuse();
}
shared_vector<int16> xx = copy<int16>(pvScalarArray);
return xx;
}
shared_vector<int32> EasyPVStructureImpl::getIntArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvInt);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvInt) {
PVIntArrayPtr pv = static_pointer_cast<PVIntArray>(pvValue);
return pv->reuse();
}
shared_vector<int32> xx = copy<int32>(pvScalarArray);
return xx;
}
shared_vector<int64> EasyPVStructureImpl::getLongArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvLong);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvLong) {
PVLongArrayPtr pv = static_pointer_cast<PVLongArray>(pvValue);
return pv->reuse();
}
shared_vector<int64> xx = copy<int64>(pvScalarArray);
return xx;
}
shared_vector<uint8> EasyPVStructureImpl::getUByteArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvUByte);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvUByte) {
PVUByteArrayPtr pv = static_pointer_cast<PVUByteArray>(pvValue);
return pv->reuse();
}
shared_vector<uint8> xx = copy<uint8>(pvScalarArray);
return xx;
}
shared_vector<uint16> EasyPVStructureImpl::getUShortArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvUShort);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvUShort) {
PVUShortArrayPtr pv = static_pointer_cast<PVUShortArray>(pvValue);
return pv->reuse();
}
shared_vector<uint16> xx = copy<uint16>(pvScalarArray);
return xx;
}
shared_vector<uint32> EasyPVStructureImpl::getUIntArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvUInt);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvUInt) {
PVUIntArrayPtr pv = static_pointer_cast<PVUIntArray>(pvValue);
return pv->reuse();
}
shared_vector<uint32> xx = copy<uint32>(pvScalarArray);
return xx;
}
shared_vector<uint64> EasyPVStructureImpl::getULongArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvULong);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvULong) {
PVULongArrayPtr pv = static_pointer_cast<PVULongArray>(pvValue);
return pv->reuse();
}
shared_vector<uint64> xx = copy<uint64>(pvScalarArray);
return xx;
}
shared_vector<float> EasyPVStructureImpl::getFloatArray()
{
checkScalarArray(pvFloat);
PVFloatArrayPtr pv = static_pointer_cast<PVFloatArray>(pvValue);
return pv->reuse();
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvFloat);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvFloat) {
PVFloatArrayPtr pv = static_pointer_cast<PVFloatArray>(pvValue);
return pv->reuse();
}
shared_vector<float> xx = copy<float>(pvScalarArray);
return xx;
}
shared_vector<double> EasyPVStructureImpl::getDoubleArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvDouble);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvDouble) {
PVDoubleArrayPtr pv = static_pointer_cast<PVDoubleArray>(pvValue);
return pv->reuse();
}
shared_vector<double> xx = copy<double>(pvScalarArray);
return xx;
}
shared_vector<string> EasyPVStructureImpl::getStringArray()
{
checkScalarArray(pvString);
PVStringArrayPtr pv = static_pointer_cast<PVStringArray>(pvValue);
return pv->reuse();
}
}}