REVERT: Merge pull request #4 from mrkraimer/default

merged
(reverted from commit 9869e611ea)
This commit is contained in:
Ralph Lange
2015-06-12 16:12:10 +02:00
parent 5d93ff584f
commit be9d267626
68 changed files with 29 additions and 9398 deletions

13
.gitignore vendored
View File

@ -1,13 +0,0 @@
QtC-
bin/
lib/
doc/
include/
db/
dbd/
documentation/html
documentation/*.tag
envPaths
configure/*.local
!configure/ExampleRELEASE.local
**/O.*

View File

@ -908,8 +908,7 @@ HTML_STYLESHEET =
# files. In the HTML_STYLESHEET file, use the file name only. Also note that # files. In the HTML_STYLESHEET file, use the file name only. Also note that
# the files will be copied as-is; there are no commands or markers available. # the files will be copied as-is; there are no commands or markers available.
HTML_EXTRA_FILES = documentation/pvAccessOverview.html HTML_EXTRA_FILES =
HTML_EXTRA_FILES = documentation/pvaOverview.html
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
# Doxygen will adjust the colors in the style sheet and background images # Doxygen will adjust the colors in the style sheet and background images

View File

@ -2,25 +2,16 @@
TOP = . TOP = .
include $(TOP)/configure/CONFIG include $(TOP)/configure/CONFIG
DIRS := $(DIRS) $(filter-out $(DIRS), configure)
DIRS := $(DIRS) $(filter-out $(DIRS), src)
DIRS := $(DIRS) $(filter-out $(DIRS), pvaSrc)
DIRS := $(DIRS) $(filter-out $(DIRS), pvtoolsSrc)
DIRS := $(DIRS) $(filter-out $(DIRS), testApp)
DIRS := $(DIRS) $(filter-out $(DIRS), pvaExample)
DIRS := $(DIRS) $(filter-out $(DIRS), pvaTest)
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), pvaExample) DIRS := configure
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), pvaTest)
define DIR_template DIRS += src
$(1)_DEPEND_DIRS = configure src_DEPEND_DIRS = configure
endef
$(foreach dir, $(filter-out configure,$(DIRS)),$(eval $(call DIR_template,$(dir))))
define EMB_template DIRS += pvtoolsSrc
$(1)_DEPEND_DIRS = src pvaSrc pvtoolsSrc_DEPEND_DIRS = src
endef
$(foreach dir, $(EMBEDDED_TOPS),$(eval $(call EMB_template,$(dir)))) DIRS += testApp
testApp_DEPEND_DIRS = src
include $(TOP)/configure/RULES_TOP include $(TOP)/configure/RULES_TOP

View File

@ -1,7 +0,0 @@
EPICS_BASE=/home/install/epics/base
EPICS4_DIR=/home/epicsv4
PVCOMMON=${EPICS4_DIR}/pvCommonCPP
PVDATA=${EPICS4_DIR}/pvDataCPP

View File

@ -38,7 +38,7 @@
<h1>EPICS pvAccessCPP</h1> <h1>EPICS pvAccessCPP</h1>
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. --> <!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 05-June-2011</h2> <h2 class="nocount" id="L50">EPICS v4 Working Group, Working Draft, 09-July-2011</h2>
<dl> <dl>
<dt>Latest version:</dt> <dt>Latest version:</dt>
<dd><a <dd><a
@ -46,11 +46,11 @@
</a></dd> </a></dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href="pvAccessCPP_20150505.html">pvAccessCPP_20150505.html href="pvAccessCPP_20140709.html">pvAccessCPP_20140709.html
</a></dd> </a></dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href="pvAccessCPP_20140709.html">pvAccessCPP_20140709.html href="pvAccessCPP_20111220.html">pvAccessCPP_20111220.html
</a></dd> </a></dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL<br /> <dd>Marty Kraimer, BNL<br />
@ -59,77 +59,40 @@
<hr /> <hr />
<h2 class="nocount">Abstract</h2> <h2 class="nocount">Abstract</h2>
<p>pvAccessCPP is the C++ implementation of pvAccess, <p>pvAccessCPP is the C++ implementation of pvAccess, which is one of a related
which is network support for transporting structured data as defined by pvData. set of products:</br >
</p>
<p>
pvAccess is one of a related
set of products:
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a> <a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
</p> </p>
<h2 class="nocount">Status of this Document</h2> <h2 class="nocount">Status of this Document</h2>
<p>This is the 05-June-2011 version of the C++ implementation of pvAccess. The <p>This is the 09-July-2011 version of the C++ implementation of pvAccess. The
code is a complete implementation of pvAccess.</p> code is a complete implementation of pvAccess as currently defined. This
overview is NOT written.</p>
</div> </div>
<div id="toc"> <div id="toc">
<h2 class="nocount">Table of Contents</h2> <h2 class="nocount" style="page-break-before: always">Table of Contents</h2>
</div> </div>
<!-- Place what you would like in the Table of Contents, inside the contents div -->
<div id="contents" class="contents"> <div id="contents" class="contents">
<h2 id="L88">Introduction</h2>
<hr /> <hr />
<h2>Preface</h2> <p>This product is available via an <a
<p>This document describes the pvAccess Application Program Interface (API). href="http://epics-pvdata.sourceforge.net/LICENSE.html">open source
The reader is assumed to have a basic understanding of EPICS V4 as described in:</p> license</a></p>
<a
href="http://epics-pvdata.sourceforge.net/informative/developerGuide/developerGuide.html">
EPICS V4 Developer's Guide
</a>
<p>The pvAccess API is callback based and uses Status to report problem to the
client, which means that it can be complex to use.
If your primary interest is client access then, instead of reading this document,
read:</p>
<a
href="pva.html">
EPICS pva
</a>
<p>If your primary interest is implementing pvAccess services then,
before reading this documement read:</p>
<a
href="http://epics-pvdata.sourceforge.net/docbuild/pvDatabaseCPP/tip/documentation/pvDatabaseCPP.html">
pvDatabaseCPP
</a>
<p>This overview for pvAccessCPP. Doxygen documentation is available at <a
href="./html/index.html">doxygenDoc</a></p>
<p><b>THIS IS NOT WRITTEN</b> For now please consult pvAccessJava.html.
In addition look at the Doxygen documentation for this project.</p>
<h2>Introduction</h2>
<p>This product is available via an
<a
href="http://epics-pvdata.sourceforge.net/LICENSE.html">open source license
</a>
</p>
<p>
A user overview is available via
<a
href="./pvAccessOverview.html">pvAccessOverview.html
</a>
</p>
<p>
Doxygen documentation is available at
<a
href="./html/index.html">doxygenDoc
</a>
<h2>???</h2>
<p>Matej decide what else should go in this document</p>
</div> </div>
</body> </body>

View File

@ -1,136 +0,0 @@
<?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 pvAccessCPP</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 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</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 pvAccessCPP</h1>
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 05-June-2011</h2>
<dl>
<dt>Latest version:</dt>
<dd><a
href="pvAccessCPP.html">pvAccessCPP.html
</a></dd>
<dt>This version:</dt>
<dd><a
href="pvAccessCPP_20150505.html">pvAccessCPP_20150505.html
</a></dd>
<dt>Previous version:</dt>
<dd><a
href="pvAccessCPP_20140709.html">pvAccessCPP_20140709.html
</a></dd>
<dt>Editors:</dt>
<dd>Marty Kraimer, BNL<br />
Matej Sekoranja, CosyLab</dd>
</dl>
<hr />
<h2 class="nocount">Abstract</h2>
<p>pvAccessCPP is the C++ implementation of pvAccess,
which is network support for transporting structured data as defined by pvData.
</p>
<p>
pvAccess is one of a related
set of products:
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
</p>
<h2 class="nocount">Status of this Document</h2>
<p>This is the 05-June-2011 version of the C++ implementation of pvAccess. The
code is a complete implementation of pvAccess.</p>
</div>
<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>Preface</h2>
<p>This document describes the pvAccess Application Program Interface (API).
The reader is assumed to have a basic understanding of EPICS V4 as described in:</p>
<a
href="http://epics-pvdata.sourceforge.net/informative/developerGuide/developerGuide.html">
EPICS V4 Developer's Guide
</a>
<p>The pvAccess API is callback based and uses Status to report problem to the
client, which means that it can be complex to use.
If your primary interest is client access then, instead of reading this document,
read:</p>
<a
href="pva.html">
EPICS pva
</a>
<p>If your primary interest is implementing pvAccess services then,
before reading this documement read:</p>
<a
href="http://epics-pvdata.sourceforge.net/docbuild/pvDatabaseCPP/tip/documentation/pvDatabaseCPP.html">
pvDatabaseCPP
</a>
<h2>Introduction</h2>
<p>This product is available via an
<a
href="http://epics-pvdata.sourceforge.net/LICENSE.html">open source license
</a>
</p>
<p>
A user overview is available via
<a
href="./pvAccessOverview.html">pvAccessOverview.html
</a>
</p>
<p>
Doxygen documentation is available at
<a
href="./html/index.html">doxygenDoc
</a>
<h2>???</h2>
<p>Matej decide what else should go in this document</p>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -1,202 +0,0 @@
<?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 pva</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 pva</h1>
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
<h2 class="nocount">EPICS V4 Working Group, Working Draft,
29-May-2015</h2>
<dl>
<dt>This version:</dt>
<dd><a
href="pva.html">pva.html
</a> </dd>
<dt>Latest version:</dt>
<dd><a
href="pva_20150529.html">pva_20150529.html</a>
</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>Pva (Pva 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, pva provides a synchronous 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.
Pva provides an interface that does not require callbacks even for monitors.
</p>
<p>
PvaChannel 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>
PvaMultiChannel provides access to data from multiple channels.
It can be used directly by a client or via PvaMultiDouble or PvaNTMultiChannel.
PvaMultiDouble allows the client to get and put data to multiple channels.
But each channel must have a value field that is a numeric scalar.
PvaNTMultiChannel allows the client to get and put data to multiple channels.
Each channel must have a value field.
The data for the channels is presented via normative type NTMultiChannel.
</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 Pva Software</h2>
<p>PvaCPP is ready for use.</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>Pva 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>This document describes the layout of the source files in this project.</p>
<p>
A user overview is available via
<a
href="./pvaOverview.html">pvaOverview.html
</a>
</p>
<p>
Doxygen documentation is available at
<a
href="./html/index.html">doxygenDoc
</a>
</p>
<h2>Example and Test Database</h2>
<p>The examples and tests require that an example pvAccess server is runnimg.
This distribution has a file <b>exampleDatabasePva.zip</b>.
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 pvaJava.
It uses pvDatabaseCPP to build the database.
</p>
<p>
After unzipping the file:
</p>
<pre>
cd configure
cp ExampleRELEASE.local RELEASE.local
edit RELEASE.local
cd ..
make
cd iocBoot/exampleDatabase
../../bin/&lt;arch:&gt;/exampleDatabase st.cmd
</pre>
<h2>Testing</h2>
<p>The tests will fail unless the example database is running.</p>
<p>Once it is running:</p>
<pre>
make runtests
</pre>
<h2>Examples</h2>
<p>Examples are in directory <b>pvaExample/src</b>.
An example of how to run them is:</p>
<pre>
mrk&gt; pwd
/home/epicsv4/pvAccessCPP/pvaExample
mrk&gt; bin/linux-x86_64/examplePvaGet
</pre>
<p>The following is a brief description of each example.
In order to understand each example it
helps to also look at the source for the example.</p>
<h2>examplePvaGet</h2>
<p>This has a number of examples:</p>
<dl>
<dt>exampleDouble</dt>
<dd>
This shows two methods for getting data from a channel that has a numeric
scalar value field.
</dd>
<dt>exampleDoubleArray</dt>
<dd>
This shows two methods for getting data from a channel that has a
double array value field.
</dd>
<dt>exampleCADouble</dt>
<dd>
This is like exampleDouble except it uses provider <b>ca</b>.
</dd>
<dt>exampleCADoubleArray</dt>
<dd>
This is like exampleDoubleArray except it uses provider <b>ca</b>.
</dd>
<dt>examplePowerSupply</dt>
<dd>
This is an example of getting data from a channel that does not
have a value field.
</dd>
</dl>
<h2>examplePvaMonitor</h2>
<p>This is an example of creating a monitor on a channel.
It monitors a channel that models a powerSupply, i. e. it is not a "standard" record.
It does not have a value field.
</p>
<p>After starting the example a change can be made to the powerSupply by issuing:</p>
<pre>
pvput -r "power.value,voltage.value" examplePowerSupply 6 6
</pre>
<h2>examplePvaPut</h2>
<p>This example gets and puts to channel exampleDouble.</p>
<h2>examplePvaProcess</h2>
<p>This example makes a process request to channel exampleDouble.</p>
<h2>helloWorldPutGet</h2>
<p>This is an example of issuing a channelPutGet.</p>
<h2>examplePvaMultiDouble</h2>
<p>This is an example of issuing gets and puts to multiple channels where each
channel has a numeric scalar value field.</p>
<h2>examplePvaNTMultiChannel</h2>
<p>This is an example of using NDMultiChannel to obtain data from multiple channels.
</p>
<h2>helloWorldRPC</h2>
<p>This is an example of issuing a channelRPC request.
It does <b>not</b> use pva.</p>
</div> <!-- class="contents" -->
</body>
</html>

View File

@ -1,321 +0,0 @@
<?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>pva C++ Overview</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>Pva C++ Overview</h1>
</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>Pva is a synchronous API for accessing PVData via PVAccess.
It also provides a number of convenience methods.
It allows the client to request access without checking for failure,
but throws an exception if a request fails.
A client can also check for failues and thus prevent exceptions.</p>
<p>The Pva API has the following features:</p>
<ol>
<li>Provides a synchronous API rather than the callback API provided by pvAccess.</li>
<li>Makes common requests pva.</li>
<li>Provides full access to the pvAccess API for more demanding
applications</li>
<li>Allows efficient client side programs.</li>
<li>Takes care of most object resource management problems.</li>
</ol>
<p>Simple examples of using pva:</p>
<pre>
// pvaGet
PvaPtr pva = Pva::create();
double value = pva-&gt;channel("exampleDouble")-&gt;get()-&gt;getData()-&gt;getDouble();
// pvaPut
PvaChannelPtr channel = pva-&gt;channel("exampleDouble");
PvaPutPtr put = channel-&gt;put();
PvaPutDataPtr putData = put-&gt;getData();
putData-&gt;putDouble(3.0); put-&gt;put();
// pvaMonitor
PvaMonitorPtr monitor = pva-&gt;channel("examplePowerSupply")-&gt;monitor("");
PvaMonitorDataPtr pvaData = monitor-&gt;getData();
while(true) {
monitor-&gt;waitEvent();
cout &lt;&lt; "changed\n";
pvaData-&gt;showChanged(cout);
cout &lt;&lt; "overrun\n";
pvaData-&gt;showOverrun(cout);
monitor-&gt;releaseEvent();
}
// pvaProcess
PvaChannelPtr channel = pva-&gt;channel("exampleDouble");
PvaProcessPtr process = channel-&gt;createProcess();
process-&gt;process();
</pre>
<p><b>pvaExample</b> includes a number of examples.</p>
<p>pva does <b>not</b> provide support for:</p>
<dl>
<dt>ChannelArray</dt>
<dd>TBD</dd>
<dt>ChannelRPC</dt>
<dd>pvAccess itself already provides a synchronous interface.
The examples include helloWorldRPC, which is an example of using channelRP.
</dd>
</dl>
<h2>Pva</h2>
<p>An instance of Pva is obtained via the call:</p>
<pre>
PvaPtr pva = Pva::create();
</pre>
<p>Pva has methods to create instances of <b>PvaChannel</b>.
The client can specify the provider name or use the default provider.
The client can manage it's own channels or can let pva cache channels.
An example of using the cached method is:</p>
<pre>
PvaChannelPtr pvaChannel = pva-&gt;channel("exampleDouble");
</pre>
<p>This will attempt to connect to channel exampleDouble.
Since the client did not specify a timeout an exception wll be thrown if
the connection request fails.
The client will block until the connection is made or an exception is thrown.
If the request succeeds, pva caches the pvaChannel so that if the
client makes another request for the same channel the cached object is
returned to the client.
</p>
<p>An example of using a non cached method is:</p>
<pre>
PvaChannelPtr pvaChannel = pva-&gt;createChannel("exampleDouble");
</pre>
<p>This will create an PvaChannel and return it to the client.
The client must itself connect.
This is useful if the client wants to connect to multiple channels in parallel.
</p>
<h2>PvaChannel - Wrapper For Single Channel</h2>
<h3>PvaChannel</h3>
<p>This provides methods for connecting to a channel and for creating instances of
PvaField, PvaProcess, ..., PvaPutGet.</p>
<p>Connection must be made before any create method is called or
an exception is raised.
The following is a synchronous connection request:</p>
<pre>
pvaChannel-&gt;connect(5.0); // BLOCKS AND THROWS IF NO CONNECT
</pre>
<p>This blocks until then connection is made or until timout occurs.
An exception is raised if the connection request fails.
</p>
<p>The same request can be made without blocking and without exceptions.</p>
<pre>
pvaChannel-&gt;issueConnect(); // DOES NOT BLOCK
.....
Status status =pvaChannel-&gt;waitConnect(5.0); // BLOCKS DOES NOT THROW
if(!status.isOK()) {
// failure do something
}
</pre>
<p>Once the channel is connected other Pva objects can be created.
For example:</p>
<pre>
PvaGetPtr pvaGet = pvaChannel-&gt;get(); // DOES BLOCK
</pre>
<p>This is a caching request.
If the client already has made an identical request the client will receive the
cached object.
If a new pvaGet is created than it is connected before it is returned to the client.
</p>
<p>The client can also managed it's own objects:</p>
<pre>
PvaGetPtr pvaGet = pvaChannel-&gt;createGet(); // DOES NOT BLOCK
</pre>
<p>The client must connect the pvaGet.</p>
<h3>PvaGetData</h3>
<p>This provides the data returned by pvaGet and pvaPutGet.
It is obtained via:</p>
<pre>
PvaGetDataPtr pvaData = pvaGet-&gt;getData();
</pre>
<p>It provides methods to get everything returned by channelGet.
In addition there are methods that make it easier to handle a value
field that is a scalar or a scalarArray.
Also for a scalar that is a double or a scalarArray with element type double.
</p>
<p>An example is:</p>
<pre>
double value = pvaData-&gt;getDouble();
</pre>
<p>It also keeps a bitSet showing which fields have changed since the last channelGet or channelPutGet.</p>
<h3>PvaMonitorData</h3>
<p>To the client this looks identical to PvaGetData except that
it provides two BitSets: changedBitSet and overrrunBitSet.
It is used by pvaMonitor.
</p>
<h3>PvaPutData</h3>
<p>This is used to provided data for pvaPut and pvaPutGet.
It has many of the same methods as pvaGetData.
It does not have a bitSet.
It also has put methods like:</p>
<pre>
void pvaData-&gt;putDouble(5.0);
</pre>
<h3>PvaGet</h3>
<p>This provides methods to connect to channelGet and to issue get request.
To connect via a single synchronous call:</p>
<pre>
eastGet-&gt;connect(); // BLOCKS AND CAN THROW
</pre>
<p>This can also be done in two steps:</p>
<pre>
pvaGet-&gt;issueConnect(); // DOES NOT BLOCK
...
Status status = pvaGet-&gt;waitConnect(); // BLOCKS AND DOES NOT HROW
</pre>
<p>Once connected gets are issued via either:</p>
<pre>
void pvaGet-&gt;get(); // BLOCKS AND CAN THROW
</pre>
or
<pre>
pvaGet-&gt;issueGet(); // DOES NOT BLOCK
...
Status status = pvaGet-&gt;waitGet(); // BLOCKS AND DOES NOT THROW
</pre>
<h3>PvaPut</h3>
<p>This is similar to pvaGet except that it wraps channelPut instead of channelGet.
</p>
<p>Once connected puts are issued via either:</p>
<pre>
void pvaPut-&gt;put(); // BLOCKS AND CAN THROW
</pre>
or
<pre>
pvaPut-&gt;issuePut(); // DOES NOT BLOCK
...
Status status = pvaPut-&gt;waitPut(); // BLOCKS AND DOES NOT THROW
</pre>
<h3>PvaMonitor</h3>
<p>Connecting is similar to pvaGet and pvaPut.
The other methods are:</p>
<dl>
<dt>start</dt>
<dd>Starts monitoring</dd>
<dt>stop</dt>
<dd>Stops monitoring</dd>
<dt>poll</dt>
<dd>polls for a monitorEvent.
The data is avalable via pvaMonitorData.
</dd>
<dt>releaseEvent</dt>
<dd>Release the data from the last poll.
Note that this must be called before another poll is requested.
</dd>
<dt>waitEvent</dt>
<dd>Block until a monitorEvent is available.
If true is returned a poll has already been issued.
</dd>
<dt>setRequester</dt>
<dd>A client callback is registered to receive notice of monitorEvents.</dd>
</dl>
<h3>PvaProcess</h3>
<p>Connecting is similar to pvaGet.
It has methods:</p>
<dl>
<dt>process</dt>
<dd>call issueProcess and waitProcess.</dd>
<dt>issueProcess</dt>
<dd>call channelProcess-&gt;process() and return immediately.
</dd>
<dt>waitProcess</dt>
<dd>Wait for process to complete.</dd>
</dl>
<h3>PvaPutGet</h3>
<p>Connecting is similar to pvaGet.
It has methods:</p>
<dl>
<dt>putGet</dt>
<dd>calls issuePutGet and waitPutGet.
throws an exception if not successfull.
</dd>
<dt>issuePutGet</dt>
<dd>
Calls channel-&gt;putGet() and returns.
</dd>
<dt>waitPutGet</dt>
<dd>
Waits until putGet completes and returns status.
</dd>
<dt>getGet,issueGetGet, and waitGetGet</dt>
<dd>Gets the data for the get part of channelPutGet.</dd>
<dt>getPut,issueGetPut,and waitGetPut</dt>
<dd>Gets the data for the put part of channelPutGet.</dd>
<dt>getPutData</dt>
<dd>
Returns the PvaData for the put part of channelPutGet.
</dd>
<dt>getGetData</dt>
<dd>
Returns the PvaData for the get part of channelPutGet.
</dd>
</dl>
<p>Look at javaDoc for details.</p>
<h2>PvaMultiChannel - Wrapper For Multiple Channels</h2>
<h3>PvaMultiChannel</h3>
<p>This provides methods for connecting to multiple channels.
A client can either use PvaMultiChannel directly or use PvaMultiDouble or PvaNTMultiChannel.
But both impose restrictions on what can be accessed.
</p>
<h3>PvaMultiDouble</h3>
<p>This provides support for gets and puts to the value field of multiple channels.
Each channel must have a value field that is a numeric scalar.
The client always sees the data as a PVDoubleArray.
All channels must connect.
If any problems occur an exception is thrown.
</p>
<h3>PvaNTMultiChannel</h3>
<p>This provides support for gets and puts to the value field of multiple channels.
Each channel must have a value field.
The client always sees the data as a NTMultiChannel, which is one
of the types provided by normativeTypesCPP.
All channels must connect.
If any problems occur an exception is thrown.
</p>
</div> <!-- class="contents" -->
</body>
</html>

View File

@ -1,202 +0,0 @@
<?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 pva</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 pva</h1>
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
<h2 class="nocount">EPICS V4 Working Group, Working Draft,
29-May-2015</h2>
<dl>
<dt>This version:</dt>
<dd><a
href="pva.html">pva.html
</a> </dd>
<dt>Latest version:</dt>
<dd><a
href="pva_20150529.html">pva_20150529.html</a>
</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>Pva (Pva 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, pva provides a synchronous 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.
Pva provides an interface that does not require callbacks even for monitors.
</p>
<p>
PvaChannel 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>
PvaMultiChannel provides access to data from multiple channels.
It can be used directly by a client or via PvaMultiDouble or PvaNTMultiChannel.
PvaMultiDouble allows the client to get and put data to multiple channels.
But each channel must have a value field that is a numeric scalar.
PvaNTMultiChannel allows the client to get and put data to multiple channels.
Each channel must have a value field.
The data for the channels is presented via normative type NTMultiChannel.
</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 Pva Software</h2>
<p>PvaCPP is ready for use.</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>Pva 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>This document describes the layout of the source files in this project.</p>
<p>
A user overview is available via
<a
href="./pvaOverview.html">pvaOverview.html
</a>
</p>
<p>
Doxygen documentation is available at
<a
href="./html/index.html">doxygenDoc
</a>
</p>
<h2>Example and Test Database</h2>
<p>The examples and tests require that an example pvAccess server is runnimg.
This distribution has a file <b>exampleDatabasePva.zip</b>.
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 pvaJava.
It uses pvDatabaseCPP to build the database.
</p>
<p>
After unzipping the file:
</p>
<pre>
cd configure
cp ExampleRELEASE.local RELEASE.local
edit RELEASE.local
cd ..
make
cd iocBoot/exampleDatabase
../../bin/&lt;arch:&gt;/exampleDatabase st.cmd
</pre>
<h2>Testing</h2>
<p>The tests will fail unless the example database is running.</p>
<p>Once it is running:</p>
<pre>
make runtests
</pre>
<h2>Examples</h2>
<p>Examples are in directory <b>pvaExample/src</b>.
An example of how to run them is:</p>
<pre>
mrk&gt; pwd
/home/epicsv4/pvAccessCPP/pvaExample
mrk&gt; bin/linux-x86_64/examplePvaGet
</pre>
<p>The following is a brief description of each example.
In order to understand each example it
helps to also look at the source for the example.</p>
<h2>examplePvaGet</h2>
<p>This has a number of examples:</p>
<dl>
<dt>exampleDouble</dt>
<dd>
This shows two methods for getting data from a channel that has a numeric
scalar value field.
</dd>
<dt>exampleDoubleArray</dt>
<dd>
This shows two methods for getting data from a channel that has a
double array value field.
</dd>
<dt>exampleCADouble</dt>
<dd>
This is like exampleDouble except it uses provider <b>ca</b>.
</dd>
<dt>exampleCADoubleArray</dt>
<dd>
This is like exampleDoubleArray except it uses provider <b>ca</b>.
</dd>
<dt>examplePowerSupply</dt>
<dd>
This is an example of getting data from a channel that does not
have a value field.
</dd>
</dl>
<h2>examplePvaMonitor</h2>
<p>This is an example of creating a monitor on a channel.
It monitors a channel that models a powerSupply, i. e. it is not a "standard" record.
It does not have a value field.
</p>
<p>After starting the example a change can be made to the powerSupply by issuing:</p>
<pre>
pvput -r "power.value,voltage.value" examplePowerSupply 6 6
</pre>
<h2>examplePvaPut</h2>
<p>This example gets and puts to channel exampleDouble.</p>
<h2>examplePvaProcess</h2>
<p>This example makes a process request to channel exampleDouble.</p>
<h2>helloWorldPutGet</h2>
<p>This is an example of issuing a channelPutGet.</p>
<h2>examplePvaMultiDouble</h2>
<p>This is an example of issuing gets and puts to multiple channels where each
channel has a numeric scalar value field.</p>
<h2>examplePvaNTMultiChannel</h2>
<p>This is an example of using NDMultiChannel to obtain data from multiple channels.
</p>
<h2>helloWorldRPC</h2>
<p>This is an example of issuing a channelRPC request.
It does <b>not</b> use pva.</p>
</div> <!-- class="contents" -->
</body>
</html>

Binary file not shown.

View File

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

View File

@ -1,29 +0,0 @@
# 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

@ -1,27 +0,0 @@
# 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

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

View File

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

View File

@ -1,41 +0,0 @@
# 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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,72 +0,0 @@
TOP=..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
PROD_HOST += examplePvaProcess
examplePvaProcess_SRCS += examplePvaProcess.cpp
examplePvaProcess_LIBS += pva
examplePvaProcess_LIBS += pvAccess
examplePvaProcess_LIBS += pvData
examplePvaProcess_LIBS += Com
PROD_HOST += examplePvaGet
examplePvaGet_SRCS += examplePvaGet.cpp
examplePvaGet_LIBS += pva
examplePvaGet_LIBS += pvAccess
examplePvaGet_LIBS += pvData
examplePvaGet_LIBS += Com
PROD_HOST += examplePvaPut
examplePvaPut_SRCS += examplePvaPut.cpp
examplePvaPut_LIBS += pva
examplePvaPut_LIBS += pvAccess
examplePvaPut_LIBS += pvData
examplePvaPut_LIBS += Com
PROD_HOST += examplePvaMonitor
examplePvaMonitor_SRCS += examplePvaMonitor.cpp
examplePvaMonitor_LIBS += pva
examplePvaMonitor_LIBS += pvAccess
examplePvaMonitor_LIBS += pvData
examplePvaMonitor_LIBS += Com
PROD_HOST += examplePvaMultiDouble
examplePvaMultiDouble_SRCS += examplePvaMultiDouble.cpp
examplePvaMultiDouble_LIBS += pva
examplePvaMultiDouble_LIBS += pvAccess
examplePvaMultiDouble_LIBS += pvData
examplePvaMultiDouble_LIBS += Com
PROD_HOST += examplePvaNTMultiChannel
examplePvaNTMultiChannel_SRCS += examplePvaNTMultiChannel.cpp
examplePvaNTMultiChannel_LIBS += pva
examplePvaNTMultiChannel_LIBS += pvAccess
examplePvaNTMultiChannel_LIBS += nt
examplePvaNTMultiChannel_LIBS += pvData
examplePvaNTMultiChannel_LIBS += Com
PROD_HOST += helloWorldRPC
helloWorldRPC_SRCS += helloWorldRPC.cpp
helloWorldRPC_LIBS += pva
helloWorldRPC_LIBS += pvAccess
helloWorldRPC_LIBS += nt
helloWorldRPC_LIBS += pvData
helloWorldRPC_LIBS += Com
PROD_HOST += helloWorldPutGet
helloWorldPutGet_SRCS += helloWorldPutGet.cpp
helloWorldPutGet_LIBS += pva
helloWorldPutGet_LIBS += pvAccess
helloWorldPutGet_LIBS += nt
helloWorldPutGet_LIBS += pvData
helloWorldPutGet_LIBS += Com
#===========================
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE

View File

@ -1,146 +0,0 @@
/*examplePvaGet.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/pva.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
static void exampleDouble(PvaPtr const &pva)
{
cout << "example double scalar\n";
double value;
try {
cout << "short way\n";
value = pva->channel("exampleDouble")->get()->getData()->getDouble();
cout << "as double " << value << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
cout << "long way\n";
PvaChannelPtr pvaChannel = pva->createChannel("exampleDouble");
pvaChannel->issueConnect();
Status status = pvaChannel->waitConnect(2.0);
if(!status.isOK()) {cout << " connect failed\n"; return;}
PvaGetPtr pvaGet = pvaChannel->createGet();
pvaGet->issueConnect();
status = pvaGet->waitConnect();
if(!status.isOK()) {cout << " createGet failed\n"; return;}
PvaGetDataPtr pvaData = pvaGet->getData();
value = pvaData->getDouble();
cout << "as double " << value << endl;
}
static void exampleDoubleArray(PvaPtr const &pva)
{
cout << "example double array\n";
shared_vector<const double> value;
try {
cout << "short way\n";
value = pva->channel("exampleDoubleArray")->get()->getData()->getDoubleArray();
cout << "as doubleArray " << value << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
try {
cout << "long way\n";
PvaChannelPtr pvaChannel = pva->createChannel("exampleDoubleArray");
pvaChannel->connect(2.0);
PvaGetPtr pvaGet = pvaChannel->createGet();
PvaGetDataPtr pvaData = pvaGet->getData();
value = pvaData->getDoubleArray();
cout << "as doubleArray " << value << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
}
static void examplePowerSupply(PvaPtr const &pva)
{
cout << "example powerSupply\n";
PVStructurePtr pvStructure;
try {
cout << "short way\n";
pvStructure = pva->channel("examplePowerSupply")->
get("field()")->getData()->getPVStructure();
cout << pvStructure << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
}
static void exampleCADouble(PvaPtr const &pva)
{
cout << "example double scalar\n";
double value;
try {
cout << "short way\n";
value = pva->channel("double00","ca",5.0)->get()->getData()->getDouble();
cout << "as double " << value << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
cout << "long way\n";
PvaChannelPtr pvaChannel = pva->createChannel("double00","ca");
pvaChannel->issueConnect();
Status status = pvaChannel->waitConnect(2.0);
if(!status.isOK()) {cout << " connect failed\n"; return;}
PvaGetPtr pvaGet = pvaChannel->createGet();
pvaGet->issueConnect();
status = pvaGet->waitConnect();
if(!status.isOK()) {cout << " createGet failed\n"; return;}
PvaGetDataPtr pvaData = pvaGet->getData();
value = pvaData->getDouble();
cout << "as double " << value << endl;
}
static void exampleCADoubleArray(PvaPtr const &pva)
{
cout << "example double array\n";
shared_vector<const double> value;
try {
cout << "short way\n";
value = pva->channel("doubleArray","ca",5.0)->get()->getData()->getDoubleArray();
cout << "as doubleArray " << value << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
try {
cout << "long way\n";
PvaChannelPtr pvaChannel = pva->createChannel("doubleArray","ca");
pvaChannel->connect(2.0);
PvaGetPtr pvaGet = pvaChannel->createGet();
PvaGetDataPtr pvaData = pvaGet->getData();
value = pvaData->getDoubleArray();
cout << "as doubleArray " << value << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
}
int main(int argc,char *argv[])
{
PvaPtr pva = Pva::create();
exampleDouble(pva);
exampleDoubleArray(pva);
examplePowerSupply(pva);
exampleCADouble(pva);
exampleCADoubleArray(pva);
cout << "done\n";
return 0;
}

View File

@ -1,46 +0,0 @@
/*monitorPowerSupply.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 <epicsThread.h>
#include <iostream>
#include <pv/pva.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
static void exampleMonitor(PvaPtr const &pva)
{
PvaMonitorPtr monitor = pva->channel("examplePowerSupply")->monitor("");
PvaMonitorDataPtr pvaData = monitor->getData();
while(true) {
monitor->waitEvent();
cout << "changed\n";
pvaData->showChanged(cout);
cout << "overrun\n";
pvaData->showOverrun(cout);
monitor->releaseEvent();
}
}
int main(int argc,char *argv[])
{
PvaPtr pva = Pva::create();
exampleMonitor(pva);
cout << "done\n";
return 0;
}

View File

@ -1,84 +0,0 @@
/*examplePvaMultiDouble.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/pvaMultiDouble.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
static void example(PvaPtr const &pva)
{
cout << "example multiDouble\n";
size_t num = 5;
shared_vector<string> channelNames(num);
channelNames[0] = "exampleDouble01";
channelNames[1] = "exampleDouble02";
channelNames[2] = "exampleDouble03";
channelNames[3] = "exampleDouble04";
channelNames[4] = "exampleDouble05";
PVStringArrayPtr pvNames =
getPVDataCreate()->createPVScalarArray<PVStringArray>();
pvNames->replace(freeze(channelNames));
PvaMultiDoublePtr multiDouble(PvaMultiDouble::create(pva,pvNames));
try {
shared_vector<double> data = multiDouble->get();
cout << "initial " << data << endl;
for(size_t i=0; i<num; ++i) data[i] = data[i] + 1.1;
multiDouble->put(data);
data = multiDouble->get();
cout << "final " << data << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
}
static void exampleCA(PvaPtr const &pva)
{
cout << "example multiDouble\n";
size_t num = 5;
shared_vector<string> channelNames(num);
channelNames[0] = "double01";
channelNames[1] = "double02";
channelNames[2] = "double03";
channelNames[3] = "double04";
channelNames[4] = "double05";
PVStringArrayPtr pvNames =
getPVDataCreate()->createPVScalarArray<PVStringArray>();
pvNames->replace(freeze(channelNames));
PvaMultiDoublePtr multiDouble(PvaMultiDouble::create(pva,pvNames,5.0,"ca"));
try {
shared_vector<double> data = multiDouble->get();
cout << "initial " << data << endl;
for(size_t i=0; i<num; ++i) data[i] = data[i] + 1.1;
multiDouble->put(data);
data = multiDouble->get();
cout << "final " << data << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
}
int main(int argc,char *argv[])
{
PvaPtr pva = Pva::create();
example(pva);
exampleCA(pva);
return 0;
}

View File

@ -1,101 +0,0 @@
/*examplePvaNTMultiChannel.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/pvaNTMultiChannel.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
using namespace epics::nt;
static void example(PvaPtr const &pva)
{
cout << "example ntMultiChannel\n";
size_t num = 5;
shared_vector<string> channelNames(num);
channelNames[0] = "exampleDouble";
channelNames[1] = "exampleDoubleArray";
channelNames[2] = "exampleString";
channelNames[3] = "exampleBoolean";
channelNames[4] = "exampleEnum";
PVStringArrayPtr pvNames =
getPVDataCreate()->createPVScalarArray<PVStringArray>();
pvNames->replace(freeze(channelNames));
NTMultiChannelBuilderPtr builder = NTMultiChannel::createBuilder();
StructureConstPtr structure = builder->
addTimeStamp()->
addSeverity() ->
addStatus() ->
addMessage() ->
addSecondsPastEpoch() ->
addNanoseconds() ->
addUserTag() ->
createStructure();
PvaNTMultiChannelPtr multi = PvaNTMultiChannel::create(
pva,pvNames,structure);
try {
NTMultiChannelPtr nt = multi->get();
cout << "initial\n" << nt->getPVStructure() << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
}
static void exampleCA(PvaPtr const &pva)
{
cout << "example ntMultiChannel\n";
size_t num = 5;
shared_vector<string> channelNames(num);
channelNames[0] = "double00";
channelNames[1] = "doubleArray";
channelNames[2] = "string00";
channelNames[3] = "mbbiwierd";
channelNames[4] = "enum01";
PVStringArrayPtr pvNames =
getPVDataCreate()->createPVScalarArray<PVStringArray>();
pvNames->replace(freeze(channelNames));
NTMultiChannelBuilderPtr builder = NTMultiChannel::createBuilder();
StructureConstPtr structure = builder->
addTimeStamp()->
addSeverity() ->
addStatus() ->
addMessage() ->
addSecondsPastEpoch() ->
addNanoseconds() ->
addUserTag() ->
createStructure();
PvaNTMultiChannelPtr multi = PvaNTMultiChannel::create(
pva,pvNames,structure,5.0,"ca");
try {
NTMultiChannelPtr nt = multi->get();
cout << "initial\n" << nt->getPVStructure() << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
}
int main(int argc,char *argv[])
{
PvaPtr pva = Pva::create();
example(pva);
exampleCA(pva);
return 0;
}

View File

@ -1,44 +0,0 @@
/*examplePvaProcess.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/pva.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
static void exampleProcess(PvaPtr const &pva)
{
cout << "example process\n";
PvaChannelPtr channel = pva->channel("exampleDouble");
PvaProcessPtr process = channel->createProcess();
try {
process->process();
cout << channel->get("field()")->getData()->showChanged(cout) << endl;
process->process();
cout << channel->get("field()")->getData()->showChanged(cout) << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
}
int main(int argc,char *argv[])
{
PvaPtr pva = Pva::create();
exampleProcess(pva);
return 0;
}

View File

@ -1,45 +0,0 @@
/*examplePvaPut.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/pva.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
static void examplePut(PvaPtr const &pva)
{
cout << "example put\n";
PvaChannelPtr channel = pva->channel("exampleDouble");
PvaPutPtr put = channel->put();
PvaPutDataPtr putData = put->getData();
try {
putData->putDouble(3.0); put->put();
cout << channel->get("field()")->getData()->showChanged(cout) << endl;
putData->putDouble(4.0); put->put();
cout << channel->get("field()")->getData()->showChanged(cout) << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
}
int main(int argc,char *argv[])
{
PvaPtr pva = Pva::create();
examplePut(pva);
return 0;
}

View File

@ -1,48 +0,0 @@
/*helloWorldPutGet.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/pva.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
static void example(PvaPtr const &pva)
{
cout << "helloWorldPutGet\n";
try {
PvaChannelPtr channel = pva->channel("exampleHello");
PvaPutGetPtr putGet = channel->createPutGet();
putGet->connect();
PvaPutDataPtr putData = putGet->getPutData();
PVStructurePtr arg = putData->getPVStructure();
PVStringPtr pvValue = arg->getSubField<PVString>("argument.value");
pvValue->put("World");
putGet->putGet();
PvaGetDataPtr getData = putGet->getGetData();
cout << getData->getPVStructure() << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
}
int main(int argc,char *argv[])
{
PvaPtr pva = Pva::create();
example(pva);
return 0;
}

View File

@ -1,77 +0,0 @@
/*exampleChannelRPC.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/pvData.h>
#include <pv/pvAccess.h>
#include <pv/rpcClient.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
static FieldCreatePtr fieldCreate = getFieldCreate();
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
static void exampleSimple()
{
StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
add("value",pvString)->
createStructure();
PVStructurePtr pvRequest = pvDataCreate->createPVStructure(topStructure);
PVStringPtr pvArgument = pvRequest->getSubField<PVString>("value");
pvArgument->put("World");
cout << "example channeRPC simple\n";
try {
PVStructurePtr pvResult =
RPCClient::sendRequest("exampleHelloRPC", pvRequest);
cout << "result\n" << pvResult << endl;
} catch (RPCRequestException &e) {
cout << e.what() << endl;
}
}
void exampleMore()
{
StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
add("value",pvString)->
createStructure();
PVStructurePtr pvRequest = pvDataCreate->createPVStructure(topStructure);
PVStringPtr pvArgument = pvRequest->getSubField<PVString>("value");
pvArgument->put("World");
cout << "example channeRPC more\n";
try {
RPCClient::shared_pointer client = RPCClient::create("exampleHelloRPC");
client->issueConnect();
if (client->waitConnect())
{
client->issueRequest(pvRequest);
PVStructure::shared_pointer result = client->waitResponse();
std::cout << *result << std::endl;
}
else {
cout << "waitConnect timeout\n";
return;
}
} catch (RPCRequestException &e) {
cout << e.what() << endl;
}
}
int main(int argc,char *argv[])
{
exampleSimple();
exampleMore();
return 0;
}

View File

@ -1,34 +0,0 @@
# This is a Makefile fragment, see ../Makefile
TOP = ..
include $(TOP)/configure/CONFIG
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I$(INSTALL_LOCATION)/include
LIBRARY += pva
INC += pva.h
INC += pvaMultiDouble.h
INC += pvaNTMultiChannel.h
LIBSRCS += pva.cpp
LIBSRCS += pvaPutData.cpp
LIBSRCS += pvaGetData.cpp
LIBSRCS += pvaMonitorData.cpp
LIBSRCS += pvaChannel.cpp
LIBSRCS += pvaProcess.cpp
LIBSRCS += pvaGet.cpp
LIBSRCS += pvaPut.cpp
LIBSRCS += pvaMonitor.cpp
LIBSRCS += pvaPutGet.cpp
LIBSRCS += pvaMultiChannel.cpp
LIBSRCS += pvaMultiDouble.cpp
LIBSRCS += pvaNTMultiChannel.cpp
#LIBSRCS += pvaRPC.cpp
pva_LIBS += pvAccess pvData nt Com
pva_LIBS += $(EPICS_BASE_IOC_LIBS)
include $(TOP)/configure/RULES

View File

@ -1,199 +0,0 @@
/* pva.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 <map>
#include <pv/pva.h>
#include <pv/createRequest.h>
#include <pv/clientFactory.h>
#include <pv/caProvider.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvAccess::ca;
using namespace std;
namespace epics { namespace pva {
static FieldCreatePtr fieldCreate = getFieldCreate();
static const string pvaName = "pva";
static const string defaultProvider = "pva";
static UnionConstPtr variantUnion = fieldCreate->createVariantUnion();
namespace pvaPvt {
static size_t numberPva = 0;
static bool firstTime = true;
static Mutex mutex;
class StartStopClientFactory {
public:
static void PvaBeingConstructed()
{
bool saveFirst = false;
{
Lock xx(mutex);
++numberPva;
saveFirst = firstTime;
firstTime = false;
}
if(saveFirst) {
ClientFactory::start();
CAClientFactory::start();
}
}
static void PvaBeingDestroyed() {
size_t numLeft = 0;
{
Lock xx(mutex);
--numberPva;
numLeft = numberPva;
}
if(numLeft<=0) {
ClientFactory::stop();
CAClientFactory::stop();
}
}
};
} // namespace pvaPvt
class PvaChannelCache
{
public:
PvaChannelCache(){}
~PvaChannelCache(){
destroy();
}
void destroy() {
pvaChannelMap.clear();
}
PvaChannelPtr getChannel(string const & channelName);
void addChannel(PvaChannelPtr const & pvaChannel);
void removeChannel(string const & channelName);
private:
map<string,PvaChannelPtr> pvaChannelMap;
};
PvaChannelPtr PvaChannelCache::getChannel(string const & channelName)
{
map<string,PvaChannelPtr>::iterator iter = pvaChannelMap.find(channelName);
if(iter!=pvaChannelMap.end()) return iter->second;
return PvaChannelPtr();
}
void PvaChannelCache::addChannel(PvaChannelPtr const & pvaChannel)
{
pvaChannelMap.insert(std::pair<string,PvaChannelPtr>(
pvaChannel->getChannelName(),pvaChannel));
}
void PvaChannelCache::removeChannel(string const & channelName)
{
map<string,PvaChannelPtr>::iterator iter = pvaChannelMap.find(channelName);
if(iter!=pvaChannelMap.end()) pvaChannelMap.erase(iter);
}
using namespace epics::pva::pvaPvt;
PvaPtr Pva::create()
{
PvaPtr xx(new Pva());
StartStopClientFactory::PvaBeingConstructed();
return xx;
}
PVStructurePtr Pva::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;
}
Pva::Pva()
: pvaChannelCache(new PvaChannelCache()),
isDestroyed(false)
{
}
Pva::~Pva() {
destroy();
}
void Pva::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
pvaChannelCache.reset();
channelList.clear();
multiChannelList.clear();
StartStopClientFactory::PvaBeingDestroyed();
}
string Pva:: getRequesterName()
{
static string name("pva");
return name;
}
void Pva::message(
string const & message,
MessageType messageType)
{
cout << getMessageTypeName(messageType) << " " << message << endl;
}
PvaChannelPtr Pva::channel(
std::string const & channelName,
std::string const & providerName,
double timeOut)
{
PvaChannelPtr pvaChannel = pvaChannelCache->getChannel(channelName);
if(pvaChannel) return pvaChannel;
pvaChannel = createChannel(channelName,providerName);
pvaChannel->connect(timeOut);
pvaChannelCache->addChannel(pvaChannel);
return pvaChannel;
}
PvaChannelPtr Pva::createChannel(string const & channelName)
{
return PvaChannel::create(getPtrSelf(),channelName);
}
PvaChannelPtr Pva::createChannel(string const & channelName, string const & providerName)
{
return PvaChannel::create(getPtrSelf(),channelName,providerName);
}
PvaMultiChannelPtr Pva::createMultiChannel(
epics::pvData::PVStringArrayPtr const & channelNames)
{
return createMultiChannel(channelNames,"pva");
}
PvaMultiChannelPtr Pva::createMultiChannel(
epics::pvData::PVStringArrayPtr const & channelNames,
std::string const & providerName)
{
return PvaMultiChannel::create(getPtrSelf(),channelNames,providerName);
}
}}

File diff suppressed because it is too large Load Diff

View File

@ -1,495 +0,0 @@
/* pvaChannel.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 <map>
#include <sstream>
#include <pv/event.h>
#include <pv/lock.h>
#include <pv/pva.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 pva {
class PvaGetCache
{
public:
PvaGetCache(){}
~PvaGetCache();
void destroy() {
pvaGetMap.clear();
}
PvaGetPtr getGet(string const & request);
void addGet(string const & request,PvaGetPtr const & pvaGet);
private:
map<string,PvaGetPtr> pvaGetMap;
};
PvaGetCache::~PvaGetCache()
{
destroy();
}
PvaGetPtr PvaGetCache::getGet(string const & request)
{
map<string,PvaGetPtr>::iterator iter = pvaGetMap.find(request);
if(iter!=pvaGetMap.end()) return iter->second;
return PvaGetPtr();
}
void PvaGetCache::addGet(string const & request,PvaGetPtr const & pvaGet)
{
pvaGetMap.insert(std::pair<string,PvaGetPtr>(
request,pvaGet));
}
class PvaPutCache
{
public:
PvaPutCache(){}
~PvaPutCache();
void destroy() {
pvaPutMap.clear();
}
PvaPutPtr getPut(string const & request);
void addPut(string const & request,PvaPutPtr const & pvaPut);
private:
map<string,PvaPutPtr> pvaPutMap;
};
PvaPutCache::~PvaPutCache()
{
destroy();
}
PvaPutPtr PvaPutCache::getPut(string const & request)
{
map<string,PvaPutPtr>::iterator iter = pvaPutMap.find(request);
if(iter!=pvaPutMap.end()) return iter->second;
return PvaPutPtr();
}
void PvaPutCache::addPut(string const & request,PvaPutPtr const & pvaPut)
{
pvaPutMap.insert(std::pair<string,PvaPutPtr>(
request,pvaPut));
}
class ChannelRequesterImpl : public ChannelRequester
{
PvaChannel *pvaChannel;
public:
ChannelRequesterImpl(PvaChannel *pvaChannel)
: pvaChannel(pvaChannel) {}
void channelCreated(
const Status& status,
Channel::shared_pointer const & channel)
{ pvaChannel->channelCreated(status,channel); }
void channelStateChange(
Channel::shared_pointer const & channel,
Channel::ConnectionState connectionState)
{pvaChannel->channelStateChange(channel,connectionState);}
tr1::shared_ptr<Channel> getChannel() {return pvaChannel->getChannel();}
string getRequesterName()
{return pvaChannel->getRequesterName();}
void message(
string const & message,
MessageType messageType)
{ pvaChannel->message(message,messageType); }
void destroy() {pvaChannel->destroy();}
};
PvaChannel::PvaChannel(
PvaPtr const &pva,
string const & channelName,
string const & providerName)
: pva(pva),
channelName(channelName),
providerName(providerName),
connectState(connectIdle),
isDestroyed(false),
createRequest(CreateRequest::create()),
pvaGetCache(new PvaGetCache()),
pvaPutCache(new PvaPutCache())
{}
PvaChannel::~PvaChannel()
{
destroy();
}
void PvaChannel::channelCreated(const Status& status, Channel::shared_pointer const & channel)
{
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
if(status.isOK()) {
this->channel = channel;
return;
}
cout << "PvaChannel::channelCreated status " << status.getMessage() << " why??\n";
}
void PvaChannel::channelStateChange(
Channel::shared_pointer const & channel,
Channel::ConnectionState connectionState)
{
if(isDestroyed) return;
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();
}
string PvaChannel::getRequesterName()
{
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("Pva was destroyed");
return yyy->getRequesterName();
}
void PvaChannel::message(
string const & message,
MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("Pva was destroyed");
yyy->message(message, messageType);
}
void PvaChannel::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(channel) channel->destroy();
channel.reset();
pvaGetCache.reset();
pvaPutCache.reset();
}
string PvaChannel::getChannelName()
{
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
return channelName;
}
Channel::shared_pointer PvaChannel::getChannel()
{
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
return channel;
}
void PvaChannel::connect(double timeout)
{
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
issueConnect();
Status status = waitConnect(timeout);
if(status.isOK()) return;
stringstream ss;
ss << "channel " << getChannelName() << " PvaChannel::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaChannel::issueConnect()
{
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
if(connectState!=connectIdle) {
throw std::runtime_error("pvaChannel already connected");
}
channelRequester = ChannelRequester::shared_pointer(new ChannelRequesterImpl(this));
channelConnectStatus = Status(
Status::STATUSTYPE_ERROR,
getChannelName() + " createChannel failed");
connectState = connectActive;
ChannelProviderRegistry::shared_pointer reg = getChannelProviderRegistry();
ChannelProvider::shared_pointer provider = reg->getProvider(providerName);
if(!provider) {
throw std::runtime_error(getChannelName() + " provider " + providerName + " not registered");
}
channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT);
if(!channel) {
throw std::runtime_error(channelConnectStatus.getMessage());
}
}
Status PvaChannel::waitConnect(double timeout)
{
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
waitForConnect.wait(timeout);
if(connectState==connected) return Status::Ok;
return Status(Status::STATUSTYPE_ERROR,channelConnectStatus.getMessage());
}
PvaFieldPtr PvaChannel::createField()
{
return createField("");
}
PvaFieldPtr PvaChannel::createField(string const & subField)
{
throw std::runtime_error("PvaChannel::createField not implemented");
}
PvaProcessPtr PvaChannel::createProcess()
{
return createProcess("");
}
PvaProcessPtr PvaChannel::createProcess(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " PvaChannel::createProcess invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createProcess(pvRequest);
}
PvaProcessPtr PvaChannel::createProcess(PVStructurePtr const & pvRequest)
{
if(connectState!=connected) connect(5.0);
if(connectState!=connected) throw std::runtime_error("PvaChannel::creatProcess not connected");
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("Pva was destroyed");
return PvaProcess::create(yyy,getPtrSelf(),channel,pvRequest);
}
PvaGetPtr PvaChannel::get() {return get("value,alarm,timeStamp");}
PvaGetPtr PvaChannel::get(string const & request)
{
PvaGetPtr pvaGet = pvaGetCache->getGet(request);
if(pvaGet) return pvaGet;
pvaGet = createGet(request);
pvaGet->connect();
pvaGetCache->addGet(request,pvaGet);
return pvaGet;
}
PvaGetPtr PvaChannel::createGet()
{
return PvaChannel::createGet("value,alarm,timeStamp");
}
PvaGetPtr PvaChannel::createGet(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " PvaChannel::createGet invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createGet(pvRequest);
}
PvaGetPtr PvaChannel::createGet(PVStructurePtr const & pvRequest)
{
if(connectState!=connected) connect(5.0);
if(connectState!=connected) throw std::runtime_error("PvaChannel::creatGet not connected");
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("Pva was destroyed");
return PvaGet::create(yyy,getPtrSelf(),channel,pvRequest);
}
PvaPutPtr PvaChannel::put() {return put("value");}
PvaPutPtr PvaChannel::put(string const & request)
{
PvaPutPtr pvaPut = pvaPutCache->getPut(request);
if(pvaPut) return pvaPut;
pvaPut = createPut(request);
pvaPut->connect();
pvaPut->get();
pvaPutCache->addPut(request,pvaPut);
return pvaPut;
}
PvaPutPtr PvaChannel::createPut()
{
return createPut("value");
}
PvaPutPtr PvaChannel::createPut(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " PvaChannel::createPut invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createPut(pvRequest);
}
PvaPutPtr PvaChannel::createPut(PVStructurePtr const & pvRequest)
{
if(connectState!=connected) connect(5.0);
if(connectState!=connected) throw std::runtime_error("PvaChannel::creatPut not connected");
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("Pva was destroyed");
return PvaPut::create(yyy,getPtrSelf(),channel,pvRequest);
}
PvaPutGetPtr PvaChannel::createPutGet()
{
return createPutGet("putField(argument)getField(result)");
}
PvaPutGetPtr PvaChannel::createPutGet(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " PvaChannel::createPutGet invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createPutGet(pvRequest);
}
PvaPutGetPtr PvaChannel::createPutGet(PVStructurePtr const & pvRequest)
{
if(connectState!=connected) connect(5.0);
if(connectState!=connected) throw std::runtime_error("PvaChannel::creatPutGet not connected");
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("Pva was destroyed");
return PvaPutGet::create(yyy,getPtrSelf(),channel,pvRequest);
}
PvaRPCPtr PvaChannel::createRPC()
{
return createRPC("");
}
PvaRPCPtr PvaChannel::createRPC(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " PvaChannel::createRPC invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createRPC(pvRequest);
}
PvaRPCPtr PvaChannel::createRPC(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("PvaChannel::createRPC not implemented");
}
PvaArrayPtr PvaChannel::createArray()
{
return createArray("value");
}
PvaArrayPtr PvaChannel::createArray(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " PvaChannel::createArray invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createArray(pvRequest);
}
PvaArrayPtr PvaChannel::createArray(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("PvaChannel::createArray not implemented");
}
PvaMonitorPtr PvaChannel::monitor() {return monitor("value,alarm,timeStamp");}
PvaMonitorPtr PvaChannel::monitor(string const & request)
{
PvaMonitorPtr pvaMonitor = createMonitor(request);
pvaMonitor->connect();
pvaMonitor->start();
return pvaMonitor;
}
PvaMonitorPtr PvaChannel::monitor(PvaMonitorRequesterPtr const & pvaMonitorRequester)
{ return monitor("value,alarm,timeStamp",pvaMonitorRequester);
}
PvaMonitorPtr PvaChannel::monitor(string const & request,
PvaMonitorRequesterPtr const & pvaMonitorRequester)
{
PvaMonitorPtr pvaMonitor = createMonitor(request);
pvaMonitor->connect();
pvaMonitor->setRequester(pvaMonitorRequester);
pvaMonitor->start();
return pvaMonitor;
}
PvaMonitorPtr PvaChannel::createMonitor()
{
return createMonitor("value,alarm,timeStamp");
}
PvaMonitorPtr PvaChannel::createMonitor(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " PvaChannel::createMonitor invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createMonitor(pvRequest);
}
PvaMonitorPtr PvaChannel::createMonitor(PVStructurePtr const & pvRequest)
{
if(connectState!=connected) connect(5.0);
if(connectState!=connected) throw std::runtime_error("PvaChannel::createMonitor not connected");
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("Pva was destroyed");
return PvaMonitor::create(yyy,getPtrSelf(),channel,pvRequest);
}
PvaChannelPtr PvaChannel::create(
PvaPtr const &pva,
string const & channelName,
string const & providerName)
{
PvaChannelPtr channel(new PvaChannel(pva,channelName,providerName));
return channel;
}
}}

View File

@ -1,230 +0,0 @@
/* pvaGet.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/pva.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pva {
class ChannelGetRequesterImpl : public ChannelGetRequester
{
PvaGet * pvaGet;
public:
ChannelGetRequesterImpl(PvaGet * pvaGet)
: pvaGet(pvaGet) {}
string getRequesterName()
{return pvaGet->getRequesterName();}
void message(string const & message,MessageType messageType)
{pvaGet->message(message,messageType);}
void channelGetConnect(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const & structure)
{pvaGet->channelGetConnect(status,channelGet,structure);}
void getDone(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet)
{pvaGet->getDone(status,channelGet,pvStructure,bitSet);}
};
PvaGet::PvaGet(
PvaPtr const &pva,
PvaChannelPtr const & pvaChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
: pva(pva),
pvaChannel(pvaChannel),
channel(channel),
pvRequest(pvRequest),
isDestroyed(false),
connectState(connectIdle),
getState(getIdle)
{
}
PvaGet::~PvaGet()
{
destroy();
}
void PvaGet::checkGetState()
{
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
if(connectState==connectIdle) connect();
if(getState==getIdle) get();
}
// from ChannelGetRequester
string PvaGet::getRequesterName()
{
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("pva was destroyed");
return yyy->getRequesterName();
}
void PvaGet::message(string const & message,MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("pva was destroyed");
yyy->message(message, messageType);
}
void PvaGet::channelGetConnect(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const & structure)
{
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
channelGetConnectStatus = status;
this->channelGet = channelGet;
if(status.isOK()) {
pvaData = PvaGetData::create(structure);
pvaData->setMessagePrefix(channel->getChannelName());
}
waitForConnect.signal();
}
void PvaGet::getDone(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet)
{
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
channelGetStatus = status;
if(status.isOK()) {
pvaData->setData(pvStructure,bitSet);
}
waitForGet.signal();
}
// from PvaGet
void PvaGet::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(channelGet) channelGet->destroy();
channelGet.reset();
}
void PvaGet::connect()
{
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaGet::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaGet::issueConnect()
{
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
if(connectState!=connectIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " pvaGet already connected ";
throw std::runtime_error(ss.str());
}
getRequester = ChannelGetRequester::shared_pointer(new ChannelGetRequesterImpl(this));
connectState = connectActive;
channelGet = channel->createChannelGet(getRequester,pvRequest);
}
Status PvaGet::waitConnect()
{
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
if(connectState!=connectActive) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " pvaGet illegal connect state ";
throw std::runtime_error(ss.str());
}
waitForConnect.wait();
if(channelGetConnectStatus.isOK()){
connectState = connected;
return Status::Ok;
}
connectState = connectIdle;
return Status(Status::STATUSTYPE_ERROR,channelGetConnectStatus.getMessage());
}
void PvaGet::get()
{
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
issueGet();
Status status = waitGet();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaGet::get " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaGet::issueGet()
{
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
if(connectState==connectIdle) connect();
if(getState!=getIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaGet::issueGet get aleady active ";
throw std::runtime_error(ss.str());
}
getState = getActive;
channelGet->get();
}
Status PvaGet::waitGet()
{
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
if(getState!=getActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaGet::waitGet llegal get state";
throw std::runtime_error(ss.str());
}
waitForGet.wait();
getState = getIdle;
if(channelGetStatus.isOK()) {
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetStatus.getMessage());
}
PvaGetDataPtr PvaGet::getData()
{
checkGetState();
return pvaData;
}
PvaGetPtr PvaGet::create(
PvaPtr const &pva,
PvaChannelPtr const & pvaChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
{
PvaGetPtr epv(new PvaGet(pva,pvaChannel,channel,pvRequest));
return epv;
}
}}

View File

@ -1,200 +0,0 @@
/* pvaGetData.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/pva.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 pva {
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
static ConvertPtr convert = getConvert();
static string noStructure("no pvStructure ");
static string noValue("no value field");
static string noScalar("value is not a scalar");
static string notCompatibleScalar("value is not a compatible scalar");
static string noArray("value is not an array");
static string noScalarArray("value is not a scalarArray");
static string notDoubleArray("value is not a doubleArray");
static string notStringArray("value is not a stringArray");
PvaGetDataPtr PvaGetData::create(StructureConstPtr const & structure)
{
PvaGetDataPtr epv(new PvaGetData(structure));
return epv;
}
PvaGetData::PvaGetData(StructureConstPtr const & structure)
: structure(structure)
{}
void PvaGetData::checkValue()
{
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void PvaGetData::setMessagePrefix(std::string const & value)
{
messagePrefix = value + " ";
}
StructureConstPtr PvaGetData::getStructure()
{return structure;}
PVStructurePtr PvaGetData::getPVStructure()
{
if(pvStructure) return pvStructure;
throw std::runtime_error(messagePrefix + noStructure);
}
BitSetPtr PvaGetData::getBitSet()
{
if(bitSet)return bitSet;
throw std::runtime_error(messagePrefix + noStructure);
}
std::ostream & PvaGetData::showChanged(std::ostream & out)
{
if(!bitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t nextSet = bitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = bitSet->nextSetBit(nextSet+1);
}
return out;
}
void PvaGetData::setData(
PVStructurePtr const & pvStructureFrom,
BitSetPtr const & bitSetFrom)
{
pvStructure = pvStructureFrom;
bitSet = bitSetFrom;
pvValue = pvStructure->getSubField("value");
}
bool PvaGetData::hasValue()
{
if(!pvValue) return false;
return true;
}
bool PvaGetData::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool PvaGetData::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr PvaGetData::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr PvaGetData::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalar);
}
return pv;
}
PVArrayPtr PvaGetData::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noArray);
}
return pv;
}
PVScalarArrayPtr PvaGetData::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalarArray);
}
return pv;
}
double PvaGetData::getDouble()
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(messagePrefix + notCompatibleScalar);
}
return convert->toDouble(pvScalar);
}
string PvaGetData::getString()
{
PVScalarPtr pvScalar = getScalarValue();
return convert->toString(pvScalar);
}
shared_vector<const double> PvaGetData::getDoubleArray()
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
}
return pv->view();
}
shared_vector<const string> PvaGetData::getStringArray()
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
}
return pv->view();
}
}}

View File

@ -1,250 +0,0 @@
/* pvaMonitor.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.03
*/
#define epicsExportSharedSymbols
#include <sstream>
#include <pv/event.h>
#include <pv/pva.h>
#include <pv/bitSetUtil.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pva {
class ChannelMonitorRequester : public MonitorRequester
{
PvaMonitor * pvaMonitor;
public:
ChannelMonitorRequester(PvaMonitor * pvaMonitor)
: pvaMonitor(pvaMonitor) {}
string getRequesterName()
{return pvaMonitor->getRequesterName();}
void message(string const & message,MessageType messageType)
{pvaMonitor->message(message,messageType);}
void monitorConnect(
const Status& status,
Monitor::shared_pointer const & monitor,
StructureConstPtr const & structure)
{pvaMonitor->monitorConnect(status,monitor,structure);}
void monitorEvent(MonitorPtr const & monitor)
{
pvaMonitor->monitorEvent(monitor);
}
void unlisten(MonitorPtr const & monitor)
{pvaMonitor->unlisten();}
};
PvaMonitor::PvaMonitor(
PvaPtr const &pva,
PvaChannelPtr const & pvaChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
: pva(pva),
pvaChannel(pvaChannel),
channel(channel),
pvRequest(pvRequest),
isDestroyed(false),
connectState(connectIdle),
userPoll(false),
userWait(false)
{
}
PvaMonitor::~PvaMonitor()
{
destroy();
}
void PvaMonitor::checkMonitorState()
{
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
if(connectState==connectIdle) connect();
if(connectState==connected) start();
}
// from MonitorRequester
string PvaMonitor::getRequesterName()
{
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("pva was destroyed");
return yyy->getRequesterName();
}
void PvaMonitor::message(string const & message,MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("pva was destroyed");
yyy->message(message, messageType);
}
void PvaMonitor::monitorConnect(
const Status& status,
Monitor::shared_pointer const & monitor,
StructureConstPtr const & structure)
{
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
connectStatus = status;
this->monitor = monitor;
if(status.isOK()) {
pvaData = PvaMonitorData::create(structure);
pvaData->setMessagePrefix(channel->getChannelName());
}
waitForConnect.signal();
}
void PvaMonitor::monitorEvent(MonitorPtr const & monitor)
{
PvaMonitorRequesterPtr req = pvaMonitorRequester.lock();
if(req) req->event(getPtrSelf());
if(userWait) waitForEvent.signal();
}
void PvaMonitor::unlisten()
{
destroy();
}
// from PvaMonitor
void PvaMonitor::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(monitor) monitor->destroy();
monitor.reset();
}
void PvaMonitor::connect()
{
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaMonitor::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaMonitor::issueConnect()
{
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
if(connectState!=connectIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " pvaMonitor already connected ";
throw std::runtime_error(ss.str());
}
monitorRequester = ChannelMonitorRequester::shared_pointer(new ChannelMonitorRequester(this));
connectState = connectActive;
monitor = channel->createMonitor(monitorRequester,pvRequest);
}
Status PvaMonitor::waitConnect()
{
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
if(connectState!=connectActive) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " pvaMonitor illegal connect state ";
throw std::runtime_error(ss.str());
}
waitForConnect.wait();
if(connectStatus.isOK()){
connectState = connected;
return Status::Ok;
}
connectState = connectIdle;
return Status(Status::STATUSTYPE_ERROR,connectStatus.getMessage());
}
void PvaMonitor::setRequester(PvaMonitorRequesterPtr const & pvaMonitorrRequester)
{
this->pvaMonitorRequester = pvaMonitorrRequester;
}
void PvaMonitor::start()
{
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
if(connectState==monitorStarted) return;
if(connectState==connectIdle) connect();
if(connectState!=connected) throw std::runtime_error("PvaMonitor::start illegal state");
connectState = monitorStarted;
monitor->start();
}
void PvaMonitor::stop()
{
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
if(connectState!=monitorStarted) return;
connectState = connected;
monitor->stop();
}
bool PvaMonitor::poll()
{
checkMonitorState();
if(connectState!=monitorStarted) throw std::runtime_error("PvaMonitor::poll illegal state");
if(userPoll) throw std::runtime_error("PvaMonitor::poll did not release last");
monitorElement = monitor->poll();
if(!monitorElement) return false;
userPoll = true;
pvaData->setData(monitorElement);
return true;
}
bool PvaMonitor::waitEvent(double secondsToWait)
{
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
if(connectState!=monitorStarted) throw std::runtime_error("PvaMonitor::poll illegal state");
if(poll()) return true;
userWait = true;
if(secondsToWait==0.0) {
waitForEvent.wait();
} else {
waitForEvent.wait(secondsToWait);
}
userWait = false;
return poll();
}
void PvaMonitor::releaseEvent()
{
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
if(connectState!=monitorStarted) throw std::runtime_error("PvaMonitor::poll illegal state");
if(!userPoll) throw std::runtime_error("PvaMonitor::releaseEvent did not call poll");
userPoll = false;
monitor->release(monitorElement);
}
PvaMonitorDataPtr PvaMonitor::getData()
{
checkMonitorState();
return pvaData;
}
PvaMonitorPtr PvaMonitor::create(
PvaPtr const &pva,
PvaChannelPtr const & pvaChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
{
PvaMonitorPtr epv(new PvaMonitor(pva,pvaChannel,channel,pvRequest));
return epv;
}
}}

View File

@ -1,226 +0,0 @@
/* pvaMonitorData.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/pva.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 pva {
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
static StructureConstPtr nullStructure;
static PVStructurePtr nullPVStructure;
static ConvertPtr convert = getConvert();
static string noStructure("no pvStructure ");
static string noValue("no value field");
static string noScalar("value is not a scalar");
static string notCompatibleScalar("value is not a compatible scalar");
static string noArray("value is not an array");
static string noScalarArray("value is not a scalarArray");
static string notDoubleArray("value is not a doubleArray");
static string notStringArray("value is not a stringArray");
PvaMonitorDataPtr PvaMonitorData::create(StructureConstPtr const & structure)
{
PvaMonitorDataPtr epv(new PvaMonitorData(structure));
return epv;
}
PvaMonitorData::PvaMonitorData(StructureConstPtr const & structure)
: structure(structure)
{}
void PvaMonitorData::checkValue()
{
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void PvaMonitorData::setMessagePrefix(std::string const & value)
{
messagePrefix = value + " ";
}
StructureConstPtr PvaMonitorData::getStructure()
{return structure;}
PVStructurePtr PvaMonitorData::getPVStructure()
{
if(pvStructure) return pvStructure;
throw std::runtime_error(messagePrefix + noStructure);
}
BitSetPtr PvaMonitorData::getChangedBitSet()
{
if(!changedBitSet) throw std::runtime_error(messagePrefix + noStructure);
return changedBitSet;
}
BitSetPtr PvaMonitorData::getOverrunBitSet()
{
if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure);
return overrunBitSet;
}
std::ostream & PvaMonitorData::showChanged(std::ostream & out)
{
if(!changedBitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t nextSet = changedBitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = changedBitSet->nextSetBit(nextSet+1);
}
return out;
}
std::ostream & PvaMonitorData::showOverrun(std::ostream & out)
{
if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t nextSet = overrunBitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = overrunBitSet->nextSetBit(nextSet+1);
}
return out;
}
void PvaMonitorData::setData(MonitorElementPtr const & monitorElement)
{
pvStructure = monitorElement->pvStructurePtr;
changedBitSet = monitorElement->changedBitSet;
overrunBitSet = monitorElement->overrunBitSet;
pvValue = pvStructure->getSubField("value");
}
bool PvaMonitorData::hasValue()
{
if(!pvValue) return false;
return true;
}
bool PvaMonitorData::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool PvaMonitorData::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr PvaMonitorData::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr PvaMonitorData::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalar);
}
return pv;
}
PVArrayPtr PvaMonitorData::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noArray);
}
return pv;
}
PVScalarArrayPtr PvaMonitorData::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalarArray);
}
return pv;
}
double PvaMonitorData::getDouble()
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(messagePrefix + notCompatibleScalar);
}
return convert->toDouble(pvScalar);
}
string PvaMonitorData::getString()
{
PVScalarPtr pvScalar = getScalarValue();
return convert->toString(pvScalar);
}
shared_vector<const double> PvaMonitorData::getDoubleArray()
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
}
return pv->view();
}
shared_vector<const string> PvaMonitorData::getStringArray()
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
}
return pv->view();
}
}}

View File

@ -1,165 +0,0 @@
/* pvaMultiChannel.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 <map>
#include <sstream>
#include <pv/event.h>
#include <pv/lock.h>
#include <pv/pva.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 pva {
PvaMultiChannel::PvaMultiChannel(
PvaPtr const &pva,
PVStringArrayPtr const & channelName,
string const & providerName)
: pva(pva),
channelName(channelName),
providerName(providerName),
numChannel(channelName->getLength()),
isConnected(getPVDataCreate()->createPVScalarArray<PVBooleanArray>()),
isDestroyed(false)
{
}
PvaMultiChannel::~PvaMultiChannel()
{
destroy();
}
void PvaMultiChannel::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
pvaChannelArray.reset();
}
PVStringArrayPtr PvaMultiChannel::getChannelNames()
{
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
return channelName;
}
Status PvaMultiChannel::connect(double timeout,size_t maxNotConnected)
{
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
if(pvaChannelArray) throw std::runtime_error("pvaMultiChannel already connected");
PvaPtr pva = this->pva.lock();
if(!pva) return Status(Status::STATUSTYPE_ERROR,"pva is gone");
shared_vector<PvaChannelPtr> pvaChannel(numChannel,PvaChannelPtr());
PVStringArray::const_svector channelNames = channelName->view();
shared_vector<boolean> isConnected(numChannel,false);
for(size_t i=0; i< numChannel; ++i) {
pvaChannel[i] = pva->createChannel(channelNames[i],providerName);
pvaChannel[i]->issueConnect();
}
Status returnStatus = Status::Ok;
Status status = Status::Ok;
size_t numBad = 0;
for(size_t i=0; i< numChannel; ++i) {
if(numBad==0) {
status = pvaChannel[i]->waitConnect(timeout);
} else {
status = pvaChannel[i]->waitConnect(.001);
}
if(status.isOK()) {
++numConnected;
isConnected[i] = true;
continue;
}
if(returnStatus.isOK()) returnStatus = status;
++numBad;
if(numBad>maxNotConnected) break;
}
pvaChannelArray = PvaChannelArrayPtr(new PvaChannelArray(freeze(pvaChannel)));
this->isConnected->replace(freeze(isConnected));
return numBad>maxNotConnected ? returnStatus : Status::Ok;
}
bool PvaMultiChannel::allConnected()
{
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
if(!pvaChannelArray) throw std::runtime_error("pvaMultiChannel not connected");
if(numConnected==numChannel) return true;
return (numConnected==numChannel) ? true : false;
}
bool PvaMultiChannel::connectionChange()
{
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
if(!pvaChannelArray) throw std::runtime_error("pvaMultiChannel not connected");
if(numConnected==numChannel) return true;
PVBooleanArray::const_svector isConnected = this->isConnected->view();
shared_vector<const PvaChannelPtr> channels = *pvaChannelArray.get();
for(size_t i=0; i<numChannel; ++i) {
const PvaChannelPtr pvaChannel = channels[i];
Channel::shared_pointer channel = pvaChannel->getChannel();
Channel::ConnectionState stateNow = channel->getConnectionState();
bool connectedNow = stateNow==Channel::CONNECTED ? true : false;
if(connectedNow!=isConnected[i]) return true;
}
return false;
}
PVBooleanArrayPtr PvaMultiChannel::getIsConnected()
{
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
if(!pvaChannelArray) throw std::runtime_error("pvaMultiChannel not connected");
if(!connectionChange()) return isConnected;
shared_vector<boolean> isConnected(numChannel,false);
shared_vector<const PvaChannelPtr> channels = *pvaChannelArray.get();
for(size_t i=0; i<numChannel; ++i) {
const PvaChannelPtr pvaChannel = channels[i];
Channel::shared_pointer channel = pvaChannel->getChannel();
Channel::ConnectionState stateNow = channel->getConnectionState();
if(stateNow==Channel::CONNECTED) isConnected[i] = true;
}
this->isConnected->replace(freeze(isConnected));
return this->isConnected;
}
PvaChannelArrayWPtr PvaMultiChannel::getPvaChannelArray()
{
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
if(!pvaChannelArray) throw std::runtime_error("pvaMultiChannel not connected");
return pvaChannelArray;
}
Pva::weak_pointer PvaMultiChannel::getPva()
{
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
return pva;
}
PvaMultiChannelPtr PvaMultiChannel::create(
PvaPtr const &pva,
PVStringArrayPtr const & channelNames,
string const & providerName)
{
PvaMultiChannelPtr channel(new PvaMultiChannel(pva,channelNames,providerName));
return channel;
}
}}

View File

@ -1,139 +0,0 @@
/* pvaMultiDouble.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.03
*/
#define epicsExportSharedSymbols
#include <pv/pvaMultiDouble.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pva {
PvaMultiDoublePtr PvaMultiDouble::create(
PvaPtr const & pva,
PVStringArrayPtr const & channelName,
double timeout,
std::string const & providerName)
{
PvaMultiChannelPtr pvaMultiChannel(
PvaMultiChannel::create(pva,channelName,providerName));
Status status = pvaMultiChannel->connect(timeout,0);
if(!status.isOK()) throw std::runtime_error(status.getMessage());
return PvaMultiDoublePtr(new PvaMultiDouble(pvaMultiChannel));
}
PvaMultiDouble::PvaMultiDouble(PvaMultiChannelPtr const &pvaMultiChannel)
:
pvaMultiChannel(pvaMultiChannel)
{}
PvaMultiDouble::~PvaMultiDouble()
{
}
void PvaMultiDouble::createGet()
{
PvaChannelArrayPtr pvaChannelArray = pvaMultiChannel->getPvaChannelArray().lock();
if(!pvaChannelArray) throw std::runtime_error("pvaChannelArray is gone");
shared_vector<const PvaChannelPtr> pvaChannels = *pvaChannelArray;
size_t numChannel = pvaChannels.size();
pvaGet = std::vector<PvaGetPtr>(numChannel,PvaGetPtr());
bool allOK = true;
string message;
for(size_t i=0; i<numChannel; ++i)
{
pvaGet[i] = pvaChannels[i]->createGet("value");
pvaGet[i]->issueConnect();
}
for(size_t i=0; i<numChannel; ++i)
{
Status status = pvaGet[i]->waitConnect();
if(!status.isOK()) {
message = "connect status " + status.getMessage();
allOK = false;
break;
}
}
if(!allOK) throw std::runtime_error(message);
}
void PvaMultiDouble::createPut()
{
PvaChannelArrayPtr pvaChannelArray = pvaMultiChannel->getPvaChannelArray().lock();
if(!pvaChannelArray) throw std::runtime_error("pvaChannelArray is gone");
shared_vector<const PvaChannelPtr> pvaChannels = *pvaChannelArray;
size_t numChannel = pvaChannels.size();
pvaPut = std::vector<PvaPutPtr>(numChannel,PvaPutPtr());
bool allOK = true;
string message;
for(size_t i=0; i<numChannel; ++i)
{
pvaPut[i] = pvaChannels[i]->createPut("value");
pvaPut[i]->issueConnect();
}
for(size_t i=0; i<numChannel; ++i)
{
Status status = pvaPut[i]->waitConnect();
if(!status.isOK()) {
message = "connect status " + status.getMessage();
allOK = false;
break;
}
}
if(!allOK) throw std::runtime_error(message);
}
epics::pvData::shared_vector<double> PvaMultiDouble::get()
{
if(pvaGet.empty()) createGet();
shared_vector<const string> channelNames = pvaMultiChannel->getChannelNames()->view();
size_t numChannel = channelNames.size();
epics::pvData::shared_vector<double> data(channelNames.size());
for(size_t i=0; i<numChannel; ++i)
{
pvaGet[i]->issueGet();
}
for(size_t i=0; i<numChannel; ++i)
{
Status status = pvaGet[i]->waitGet();
if(!status.isOK()) {
string message = channelNames[i] + " " + status.getMessage();
throw std::runtime_error(message);
}
data[i] = pvaGet[i]->getData()->getDouble();
}
return data;
}
void PvaMultiDouble::put(shared_vector<double> const &value)
{
if(pvaPut.empty()) createPut();
shared_vector<const string> channelNames = pvaMultiChannel->getChannelNames()->view();
size_t numChannel = channelNames.size();
for(size_t i=0; i<numChannel; ++i)
{
pvaPut[i]->getData()->putDouble(value[i]);
pvaPut[i]->issuePut();
}
for(size_t i=0; i<numChannel; ++i)
{
Status status = pvaPut[i]->waitPut();
if(!status.isOK()) {
string message = channelNames[i] + " " + status.getMessage();
throw std::runtime_error(message);
}
}
}
}}

View File

@ -1,81 +0,0 @@
/* pvaMultiDouble.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 PVAMULTIDOUBLE_H
#define PVAMULTIDOUBLE_H
#ifdef epicsExportSharedSymbols
# define pvaEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include <pv/pva.h>
namespace epics { namespace pva {
class PvaMultiDouble;
typedef std::tr1::shared_ptr<PvaMultiDouble> PvaMultiDoublePtr;
/**
* @brief Support for multiple channels where each channel has a value field that is a scalar double.
* If any problems arise an exception is thrown.
*
* @author mrk
*/
class epicsShareClass PvaMultiDouble
{
public:
POINTER_DEFINITIONS(PvaMultiDouble);
/**
* @brief Create a PvaMultiDouble.
* @param &pva Interface to Pva
* @param channelName PVStringArray of channelNames.
* @param timeout The timeout in seconds for connecting.
* @param providerName The name of the channelProvider for each channel.
* @return The interface to PvaMultiDouble.
*/
static PvaMultiDoublePtr create(
PvaPtr const & pva,
epics::pvData::PVStringArrayPtr const & channelName,
double timeout = 5.0,
std::string const & providerName = "pva");
/**
* @brief destructor
*/
~PvaMultiDouble();
/**
* @brief destroy any resources used.
*/
void destroy();
/**
* @brief get the value of all the channels.
* @return The data.
*/
epics::pvData::shared_vector<double> get();
/**
* @brief put a new value to each channel.
* @param value The data.
*/
void put(epics::pvData::shared_vector<double> const &value);
PvaMultiChannelPtr getPvaMultiChannel();
private:
PvaMultiDouble(
PvaMultiChannelPtr const & channelName);
void createGet();
void createPut();
PvaMultiChannelPtr pvaMultiChannel;
std::vector<PvaGetPtr> pvaGet;
std::vector<PvaPutPtr> pvaPut;
};
}}
#endif // PVAMULTIDOUBLE_H

View File

@ -1,268 +0,0 @@
/* pvaNTMultiChannel.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.03
*/
#define epicsExportSharedSymbols
#include <pv/pvaNTMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::nt;
using namespace std;
namespace epics { namespace pva {
PvaNTMultiChannelPtr PvaNTMultiChannel::create(
PvaPtr const & pva,
PVStringArrayPtr const & channelName,
StructureConstPtr const &structure,
double timeout,
std::string const & providerName)
{
PvaMultiChannelPtr pvaMultiChannel(
PvaMultiChannel::create(pva,channelName,providerName));
Status status = pvaMultiChannel->connect(timeout,0);
if(!status.isOK()) throw std::runtime_error(status.getMessage());
if(!NTMultiChannel::is_a(structure)) throw std::runtime_error("structure is not valid");
PVStructurePtr pvStructure = getPVDataCreate()->createPVStructure(structure);
pvStructure->getSubField<PVStringArray>("channelName")->
replace(pvaMultiChannel->getChannelNames()->view());
pvStructure->getSubField<PVBooleanArray>("isConnected")->
replace(pvaMultiChannel->getIsConnected()->view());
NTMultiChannelPtr ntMultiChannel(NTMultiChannel::wrap(pvStructure));
return PvaNTMultiChannelPtr(new PvaNTMultiChannel(pvaMultiChannel,ntMultiChannel));
}
PvaNTMultiChannel::PvaNTMultiChannel(
PvaMultiChannelPtr const &pvaMultiChannel,
NTMultiChannelPtr const &ntMultiChannel)
:
pvaMultiChannel(pvaMultiChannel),
ntMultiChannel(ntMultiChannel),
pvUnionArray(ntMultiChannel->getPVStructure()->getSubField<PVUnionArray>("value")),
pvDataCreate(getPVDataCreate())
{}
PvaNTMultiChannel::~PvaNTMultiChannel()
{
}
void PvaNTMultiChannel::createGet()
{
PVStructurePtr pvStructure = ntMultiChannel->getPVStructure();
bool getAlarm = false;
if(pvStructure->getSubField("severity")) getAlarm = true;
if(pvStructure->getSubField("status")) getAlarm = true;
if(pvStructure->getSubField("severity")) getAlarm = true;
bool getTimeStamp = false;
if(pvStructure->getSubField("secondsPastEpoch")) getTimeStamp = true;
if(pvStructure->getSubField("nanoseconds")) getTimeStamp = true;
if(pvStructure->getSubField("userTag")) getTimeStamp = true;
string request = "value";
if(getAlarm) request += ",alarm";
if(getTimeStamp) request += ",timeStamp";
PvaChannelArrayPtr pvaChannelArray = pvaMultiChannel->getPvaChannelArray().lock();
if(!pvaChannelArray) throw std::runtime_error("pvaChannelArray is gone");
shared_vector<const PvaChannelPtr> pvaChannels = *pvaChannelArray;
size_t numChannel = pvaChannels.size();
pvaGet = std::vector<PvaGetPtr>(numChannel,PvaGetPtr());
bool allOK = true;
string message;
for(size_t i=0; i<numChannel; ++i)
{
pvaGet[i] = pvaChannels[i]->createGet(request);
pvaGet[i]->issueConnect();
}
for(size_t i=0; i<numChannel; ++i)
{
Status status = pvaGet[i]->waitConnect();
if(!status.isOK()) {
message = "connect status " + status.getMessage();
allOK = false;
break;
}
}
if(!allOK) throw std::runtime_error(message);
}
void PvaNTMultiChannel::createPut()
{
PvaChannelArrayPtr pvaChannelArray = pvaMultiChannel->getPvaChannelArray().lock();
if(!pvaChannelArray) throw std::runtime_error("pvaChannelArray is gone");
shared_vector<const PvaChannelPtr> pvaChannels = *pvaChannelArray;
size_t numChannel = pvaChannels.size();
pvaPut = std::vector<PvaPutPtr>(numChannel,PvaPutPtr());
bool allOK = true;
string message;
for(size_t i=0; i<numChannel; ++i)
{
pvaPut[i] = pvaChannels[i]->createPut("value");
pvaPut[i]->issueConnect();
}
for(size_t i=0; i<numChannel; ++i)
{
Status status = pvaPut[i]->waitConnect();
if(!status.isOK()) {
message = "connect status " + status.getMessage();
allOK = false;
break;
}
}
if(!allOK) throw std::runtime_error(message);
}
NTMultiChannelPtr PvaNTMultiChannel::get()
{
if(pvaGet.empty()) createGet();
PVStructurePtr pvStructure = ntMultiChannel->getPVStructure();
shared_vector<const string> channelNames = pvaMultiChannel->getChannelNames()->view();
size_t numChannel = channelNames.size();
bool severityExists = false;
bool statusExists = false;
bool messageExists = false;
bool secondsPastEpochExists = false;
bool nanosecondsExists = false;
bool userTagExists = false;
if(pvStructure->getSubField("severity")) {
severity.resize(numChannel);
severityExists = true;
}
if(pvStructure->getSubField("status")) {
status.resize(numChannel);
statusExists = true;
}
if(pvStructure->getSubField("message")) {
message.resize(numChannel);
messageExists = true;
}
if(pvStructure->getSubField("secondsPastEpoch")) {
secondsPastEpoch.resize(numChannel);
secondsPastEpochExists = true;
}
if(pvStructure->getSubField("nanoseconds")) {
nanoseconds.resize(numChannel);
nanosecondsExists = true;
}
if(pvStructure->getSubField("userTag")) {
userTag.resize(numChannel);
userTagExists = true;
}
shared_vector<PVUnionPtr> valueVector(numChannel);
for(size_t i=0; i<numChannel; ++i)
{
pvaGet[i]->issueGet();
}
for(size_t i=0; i<numChannel; ++i)
{
Status stat = pvaGet[i]->waitGet();
if(!stat.isOK()) {
string message = channelNames[i] + " " + stat.getMessage();
throw std::runtime_error(message);
}
PVStructurePtr pvStructure = pvaGet[i]->getData()->getPVStructure();
PVFieldPtr pvField = pvStructure->getSubField("value");
if(!pvField) {
string message = channelNames[i] + " no value field";
throw std::runtime_error(message);
}
UnionConstPtr u = pvUnionArray->getUnionArray()->getUnion();
if(u->isVariant()) {
PVUnionPtr pvUnion = pvDataCreate->createPVVariantUnion();
pvUnion->set(pvDataCreate->createPVField(pvField));
valueVector[i] = pvUnion;
} else {
PVUnionPtr pvUnion = pvDataCreate->createPVUnion(u);
pvUnion->set(pvField);
valueVector[i] = pvUnion;
}
pvField = pvStructure->getSubField("alarm");
if(pvField) {
if(pvAlarm.attach(pvField)) {
pvAlarm.get(alarm);
if(severityExists) severity[i] = alarm.getSeverity();
if(statusExists) status[i] = alarm.getStatus();
if(messageExists) message[i] = alarm.getMessage();
}
}
pvField = pvStructure->getSubField("timeStamp");
if(pvField) {
if(pvTimeStamp.attach(pvField)) {
pvTimeStamp.get(timeStamp);
if(secondsPastEpochExists) secondsPastEpoch[i] =
timeStamp.getSecondsPastEpoch();
if(nanosecondsExists) nanoseconds[i] =
timeStamp.getNanoseconds();
if(userTagExists) userTag[i] = timeStamp.getUserTag();
}
}
}
pvUnionArray->replace(freeze(valueVector));
if(severityExists) {
pvStructure->getSubField<PVIntArray>("severity")->replace(
freeze(severity));
}
if(statusExists) {
pvStructure->getSubField<PVIntArray>("status")->replace(
freeze(status));
}
if(messageExists) {
pvStructure->getSubField<PVStringArray>("message")->replace(freeze(message));
}
if(secondsPastEpochExists) {
pvStructure->getSubField<PVLongArray>("secondsPastEpoch")->replace(freeze(secondsPastEpoch));
}
if(nanosecondsExists) {
pvStructure->getSubField<PVIntArray>("nanoseconds")->replace(freeze(nanoseconds));
}
if(userTagExists) {
pvStructure->getSubField<PVIntArray>("userTag")->replace(freeze(userTag));
}
return ntMultiChannel;
}
void PvaNTMultiChannel::put(NTMultiChannelPtr const &value)
{
if(pvaPut.empty()) createPut();
shared_vector<const string> channelNames = pvaMultiChannel->getChannelNames()->view();
size_t numChannel = channelNames.size();
PVUnionArrayPtr pvValue = value->getPVStructure()->
getSubField<PVUnionArray>("value");
shared_vector<const PVUnionPtr> valueVector = pvValue->view();
for(size_t i=0; i<numChannel; ++i)
{
try {
PVFieldPtr pvFrom = valueVector[i]->get();
PVFieldPtr pvTo = pvaPut[i]->getData()->getValue();
Type typeFrom = pvFrom->getField()->getType();
Type typeTo = pvTo->getField()->getType();
if(typeFrom==typeTo) {
if(typeFrom==scalar || typeFrom==scalarArray) {
pvTo->copy(*pvFrom);
}
}
pvaPut[i]->issuePut();
} catch (std::exception e) {
string message = channelNames[i] + " " + e.what();
throw std::runtime_error(message);
}
}
for(size_t i=0; i<numChannel; ++i)
{
Status status = pvaPut[i]->waitPut();
if(!status.isOK()) {
string message = channelNames[i] + " " + status.getMessage();
throw std::runtime_error(message);
}
}
}
}}

View File

@ -1,103 +0,0 @@
/* pvaNTMultiChannel.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 PVANTMULTIChannel_H
#define PVANTMULTIChannel_H
#ifdef epicsExportSharedSymbols
# define pvaEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include <pv/pva.h>
namespace epics { namespace pva {
class PvaNTMultiChannel;
typedef std::tr1::shared_ptr<PvaNTMultiChannel> PvaNTMultiChannelPtr;
/**
* @brief Support for multiple channels where each channel has a value field that
* is a scalar, scalarArray, or enumerated structure.
* The data is provided via normativeType NTMultiChannel.
* If any problems arise an exception is thrown.
*
* @author mrk
*/
class epicsShareClass PvaNTMultiChannel
{
public:
POINTER_DEFINITIONS(PvaNTMultiChannel);
/**
* @brief Create a PvaNTMultiChannel.
* @param &pva Interface to Pva
* @param channelName PVStringArray of channelNames.
* @param structure valid NTMultiChannel structure.
* @param timeout Timeout for connecting.
* @param providerName The provider for each channel.
* @return The interface to PvaNTMultiChannel.
*/
static PvaNTMultiChannelPtr create(
PvaPtr const & pva,
epics::pvData::PVStringArrayPtr const & channelName,
epics::pvData::StructureConstPtr const & structure,
double timeout = 5.0,
std::string const & providerName = "pva");
/**
* @brief destructor
*/
~PvaNTMultiChannel();
/**
* @brief destroy any resources used.
*/
void destroy();
/**
* @brief get the value of all the channels.
* @return The data.
*/
epics::nt::NTMultiChannelPtr get();
/**
* @brief put a new value to each channel.
* @param value The data.
*/
void put(epics::nt::NTMultiChannelPtr const &value);
/**
* @brief Get the PvaMultiChannel.
* @return The interface.
*/
PvaMultiChannelPtr getPvaMultiChannel();
private:
PvaNTMultiChannel(
PvaMultiChannelPtr const & channelName,
epics::nt::NTMultiChannelPtr const &ntMultiChannel);
void createGet();
void createPut();
PvaMultiChannelPtr pvaMultiChannel;
epics::nt::NTMultiChannelPtr ntMultiChannel;
epics::pvData::PVUnionArrayPtr pvUnionArray;
epics::pvData::PVDataCreatePtr pvDataCreate;
std::vector<PvaGetPtr> pvaGet;
std::vector<PvaPutPtr> pvaPut;
epics::pvData::shared_vector<epics::pvData::int32> severity;
epics::pvData::shared_vector<epics::pvData::int32> status;
epics::pvData::shared_vector<std::string> message;
epics::pvData::shared_vector<epics::pvData::int64> secondsPastEpoch;
epics::pvData::shared_vector<epics::pvData::int32> nanoseconds;
epics::pvData::shared_vector<epics::pvData::int32> userTag;
epics::pvData::Alarm alarm;
epics::pvData::PVAlarm pvAlarm;
epics::pvData::TimeStamp timeStamp;;
epics::pvData::PVTimeStamp pvTimeStamp;
};
}}
#endif // PVANTMULTIChannel_H

View File

@ -1,212 +0,0 @@
/* pvaProcess.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/pva.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pva {
class ChannelProcessRequesterImpl : public ChannelProcessRequester
{
PvaProcess * pvaProcess;
public:
ChannelProcessRequesterImpl(PvaProcess * pvaProcess)
: pvaProcess(pvaProcess) {}
string getRequesterName()
{return pvaProcess->getRequesterName();}
void message(string const & message,MessageType messageType)
{pvaProcess->message(message,messageType);}
void channelProcessConnect(
const Status& status,
ChannelProcess::shared_pointer const & channelProcess)
{pvaProcess->channelProcessConnect(status,channelProcess);}
void processDone(
const Status& status,
ChannelProcess::shared_pointer const & channelProcess)
{pvaProcess->processDone(status,channelProcess);}
};
PvaProcess::PvaProcess(
PvaPtr const &pva,
PvaChannelPtr const & pvaChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
: pva(pva),
pvaChannel(pvaChannel),
channel(channel),
pvRequest(pvRequest),
isDestroyed(false),
connectState(connectIdle),
processState(processIdle)
{
}
PvaProcess::~PvaProcess()
{
destroy();
}
void PvaProcess::checkProcessState()
{
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
if(connectState==connectIdle) connect();
if(processState==processIdle) process();
}
// from ChannelProcessRequester
string PvaProcess::getRequesterName()
{
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("pva was destroyed");
return yyy->getRequesterName();
}
void PvaProcess::message(string const & message,MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("pva was destroyed");
yyy->message(message, messageType);
}
void PvaProcess::channelProcessConnect(
const Status& status,
ChannelProcess::shared_pointer const & channelProcess)
{
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
channelProcessConnectStatus = status;
this->channelProcess = channelProcess;
waitForConnect.signal();
}
void PvaProcess::processDone(
const Status& status,
ChannelProcess::shared_pointer const & channelProcess)
{
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
channelProcessStatus = status;
waitForProcess.signal();
}
// from PvaProcess
void PvaProcess::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(channelProcess) channelProcess->destroy();
channelProcess.reset();
}
void PvaProcess::connect()
{
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaProcess::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaProcess::issueConnect()
{
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
if(connectState!=connectIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " pvaProcess already connected ";
throw std::runtime_error(ss.str());
}
processRequester = ChannelProcessRequester::shared_pointer(new ChannelProcessRequesterImpl(this));
connectState = connectActive;
channelProcess = channel->createChannelProcess(processRequester,pvRequest);
}
Status PvaProcess::waitConnect()
{
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
if(connectState!=connectActive) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " pvaProcess illegal connect state ";
throw std::runtime_error(ss.str());
}
waitForConnect.wait();
if(channelProcessConnectStatus.isOK()){
connectState = connected;
return Status::Ok;
}
connectState = connectIdle;
return Status(Status::STATUSTYPE_ERROR,channelProcessConnectStatus.getMessage());
}
void PvaProcess::process()
{
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
issueProcess();
Status status = waitProcess();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaProcess::process " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaProcess::issueProcess()
{
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
if(connectState==connectIdle) connect();
if(processState!=processIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaProcess::issueProcess process aleady active ";
throw std::runtime_error(ss.str());
}
processState = processActive;
channelProcess->process();
}
Status PvaProcess::waitProcess()
{
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
if(processState!=processActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaProcess::waitProcess llegal process state";
throw std::runtime_error(ss.str());
}
waitForProcess.wait();
processState = processIdle;
if(channelProcessStatus.isOK()) {
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelProcessStatus.getMessage());
}
PvaProcessPtr PvaProcess::create(
PvaPtr const &pva,
PvaChannelPtr const & pvaChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
{
PvaProcessPtr epv(new PvaProcess(pva,pvaChannel,channel,pvRequest));
return epv;
}
}}

View File

@ -1,292 +0,0 @@
/* pvaPut.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/pva.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pva {
class ChannelPutRequesterImpl : public ChannelPutRequester
{
PvaPut * pvaPut;
public:
ChannelPutRequesterImpl(PvaPut * pvaPut)
: pvaPut(pvaPut) {}
string getRequesterName()
{return pvaPut->getRequesterName();}
void message(string const & message,MessageType messageType)
{pvaPut->message(message,messageType);}
void channelPutConnect(
const Status& status,
ChannelPut::shared_pointer const & channelPut,
StructureConstPtr const & structure)
{pvaPut->channelPutConnect(status,channelPut,structure);}
void getDone(
const Status& status,
ChannelPut::shared_pointer const & channelPut,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet)
{pvaPut->getDone(status,channelPut,pvStructure,bitSet);}
void putDone(
const Status& status,
ChannelPut::shared_pointer const & channelPut)
{pvaPut->putDone(status,channelPut);}
};
PvaPut::PvaPut(
PvaPtr const &pva,
PvaChannelPtr const & pvaChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
: pva(pva),
pvaChannel(pvaChannel),
channel(channel),
pvRequest(pvRequest),
isDestroyed(false),
connectState(connectIdle),
putState(putIdle)
{
}
PvaPut::~PvaPut()
{
destroy();
}
void PvaPut::checkPutState()
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
if(connectState==connectIdle){
connect();
get();
}
}
// from ChannelPutRequester
string PvaPut::getRequesterName()
{
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("pva was destroyed");
return yyy->getRequesterName();
}
void PvaPut::message(string const & message,MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("pva was destroyed");
yyy->message(message, messageType);
}
void PvaPut::channelPutConnect(
const Status& status,
ChannelPut::shared_pointer const & channelPut,
StructureConstPtr const & structure)
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
channelPutConnectStatus = status;
this->channelPut = channelPut;
if(status.isOK()) {
pvaData = PvaPutData::create(structure);
pvaData->setMessagePrefix(pvaChannel.lock()->getChannelName());
}
waitForConnect.signal();
}
void PvaPut::getDone(
const Status& status,
ChannelPut::shared_pointer const & channelPut,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet)
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
channelGetPutStatus = status;
if(status.isOK()) {
PVStructurePtr pvs = pvaData->getPVStructure();
pvs->copyUnchecked(*pvStructure,*bitSet);
BitSetPtr bs = pvaData->getBitSet();
bs->clear();
*bs |= *bitSet;
}
waitForGetPut.signal();
}
void PvaPut::putDone(
const Status& status,
ChannelPut::shared_pointer const & channelPut)
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
channelGetPutStatus = status;
waitForGetPut.signal();
}
// from PvaPut
void PvaPut::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(channelPut) channelPut->destroy();
channelPut.reset();
}
void PvaPut::connect()
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPut::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaPut::issueConnect()
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
if(connectState!=connectIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " pvaPut already connected ";
throw std::runtime_error(ss.str());
}
putRequester = ChannelPutRequester::shared_pointer(new ChannelPutRequesterImpl(this));
connectState = connectActive;
channelPut = channel->createChannelPut(putRequester,pvRequest);
}
Status PvaPut::waitConnect()
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
if(connectState!=connectActive) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " pvaPut illegal connect state ";
throw std::runtime_error(ss.str());
}
waitForConnect.wait();
if(channelPutConnectStatus.isOK()) {
connectState = connected;
return Status::Ok;
}
connectState = connectIdle;
return Status(Status::STATUSTYPE_ERROR,channelPutConnectStatus.getMessage());
}
void PvaPut::get()
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
issueGet();
Status status = waitGet();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPut::get " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaPut::issueGet()
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
if(connectState==connectIdle) connect();
if(putState!=putIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPut::issueGet get or put aleady active ";
throw std::runtime_error(ss.str());
}
putState = getActive;
pvaData->getBitSet()->clear();
channelPut->get();
}
Status PvaPut::waitGet()
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
if(putState!=getActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPut::waitGet llegal put state";
throw std::runtime_error(ss.str());
}
waitForGetPut.wait();
putState = putIdle;
if(channelGetPutStatus.isOK()) {
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetPutStatus.getMessage());
}
void PvaPut::put()
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
issuePut();
Status status = waitPut();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPut::put " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaPut::issuePut()
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
if(connectState==connectIdle) connect();
if(putState!=putIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPut::issueGet get or put aleady active ";
throw std::runtime_error(ss.str());
}
putState = putActive;
channelPut->put(pvaData->getPVStructure(),pvaData->getBitSet());
}
Status PvaPut::waitPut()
{
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
if(putState!=putActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPut::waitPut llegal put state";
throw std::runtime_error(ss.str());
}
waitForGetPut.wait();
putState = putIdle;
if(channelGetPutStatus.isOK()) {
pvaData->getBitSet()->clear();
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetPutStatus.getMessage());
}
PvaPutDataPtr PvaPut::getData()
{
checkPutState();
return pvaData;
}
PvaPutPtr PvaPut::create(
PvaPtr const &pva,
PvaChannelPtr const & pvaChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
{
PvaPutPtr epv(new PvaPut(pva,pvaChannel,channel,pvRequest));
return epv;
}
}}

View File

@ -1,267 +0,0 @@
/* easyPutData.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/pva.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 pva {
class PvaPostHandlerPvt: public PostHandler
{
PvaPutData * easyData;
size_t fieldNumber;
public:
PvaPostHandlerPvt(PvaPutData *easyData,size_t fieldNumber)
: easyData(easyData),fieldNumber(fieldNumber){}
void postPut() { easyData->postPut(fieldNumber);}
};
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
static ConvertPtr convert = getConvert();
static string noValue("no value field");
static string notScalar("value is not a scalar");
static string notCompatibleScalar("value is not a compatible scalar");
static string notArray("value is not an array");
static string notScalarArray("value is not a scalarArray");
static string notDoubleArray("value is not a doubleArray");
static string notStringArray("value is not a stringArray");
PvaPutDataPtr PvaPutData::create(StructureConstPtr const & structure)
{
PvaPutDataPtr epv(new PvaPutData(structure));
return epv;
}
PvaPutData::PvaPutData(StructureConstPtr const & structure)
: structure(structure),
pvStructure(getPVDataCreate()->createPVStructure(structure)),
bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())))
{
size_t nfields = pvStructure->getNumberFields();
postHandler.resize(nfields);
PVFieldPtr pvField;
for(size_t i =0; i<nfields; ++i)
{
postHandler[i] = PostHandlerPtr(new PvaPostHandlerPvt(this, i));
if(i==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(i);
}
pvField->setPostHandler(postHandler[i]);
}
pvValue = pvStructure->getSubField("value");
}
void PvaPutData::checkValue()
{
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void PvaPutData::postPut(size_t fieldNumber)
{
bitSet->set(fieldNumber);
}
void PvaPutData::setMessagePrefix(std::string const & value)
{
messagePrefix = value + " ";
}
StructureConstPtr PvaPutData::getStructure()
{return structure;}
PVStructurePtr PvaPutData::getPVStructure()
{return pvStructure;}
BitSetPtr PvaPutData::getBitSet()
{return bitSet;}
std::ostream & PvaPutData::showChanged(std::ostream & out)
{
size_t nextSet = bitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = bitSet->nextSetBit(nextSet+1);
}
return out;
}
bool PvaPutData::hasValue()
{
if(!pvValue) return false;
return true;
}
bool PvaPutData::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool PvaPutData::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr PvaPutData::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr PvaPutData::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notScalar);
}
return pv;
}
PVArrayPtr PvaPutData::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notArray);
}
return pv;
}
PVScalarArrayPtr PvaPutData::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notScalarArray);
}
return pv;
}
double PvaPutData::getDouble()
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(notCompatibleScalar);
}
return convert->toDouble(pvScalar);
}
string PvaPutData::getString()
{
PVScalarPtr pvScalar = getScalarValue();
return convert->toString(pvScalar);
}
shared_vector<const double> PvaPutData::getDoubleArray()
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
}
return pv->view();
}
shared_vector<const string> PvaPutData::getStringArray()
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
}
return pv->view();
}
void PvaPutData::putDouble(double value)
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
pvDouble->put(value);
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(messagePrefix + notCompatibleScalar);
}
convert->fromDouble(pvScalar,value);
}
void PvaPutData::putString(std::string const & value)
{
PVScalarPtr pvScalar = getScalarValue();
convert->fromString(pvScalar,value);
}
void PvaPutData::putDoubleArray(shared_vector<const double> const & value)
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
}
pv->replace(value);
}
void PvaPutData::putStringArray(shared_vector<const std::string> const & value)
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
}
pv->replace(value);
}
void PvaPutData::putStringArray(std::vector<std::string> const & value)
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notScalarArray);
}
convert->fromStringArray(pv,0,value.size(),value,0);
}
}}

View File

@ -1,378 +0,0 @@
/* pvaPutGet.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/pva.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pva {
class ChannelPutGetRequesterImpl : public ChannelPutGetRequester
{
PvaPutGet * pvaPutGet;
public:
ChannelPutGetRequesterImpl(PvaPutGet * pvaPutGet)
: pvaPutGet(pvaPutGet) {}
string getRequesterName()
{return pvaPutGet->getRequesterName();}
void message(string const & message,MessageType messageType)
{pvaPutGet->message(message,messageType);}
void channelPutGetConnect(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
epics::pvData::StructureConstPtr const & putStructure,
epics::pvData::StructureConstPtr const & getStructure)
{
pvaPutGet->channelPutGetConnect(status,channelPutGet,putStructure,getStructure);
}
void putGetDone(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
epics::pvData::PVStructurePtr const & getPVStructure,
epics::pvData::BitSetPtr const & getBitSet)
{
pvaPutGet->putGetDone(status,channelPutGet,getPVStructure,getBitSet);
}
void getPutDone(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
epics::pvData::PVStructurePtr const & putPVStructure,
epics::pvData::BitSet::shared_pointer const & putBitSet)
{
pvaPutGet->getPutDone(status,channelPutGet,putPVStructure,putBitSet);
}
void getGetDone(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
epics::pvData::PVStructurePtr const & getPVStructure,
epics::pvData::BitSet::shared_pointer const & getBitSet)
{
pvaPutGet->getGetDone(status,channelPutGet,getPVStructure,getBitSet);
}
};
PvaPutGet::PvaPutGet(
PvaPtr const &pva,
PvaChannelPtr const & pvaChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
: pva(pva),
pvaChannel(pvaChannel),
channel(channel),
pvRequest(pvRequest),
isDestroyed(false),
connectState(connectIdle),
putGetState(putGetIdle)
{
}
PvaPutGet::~PvaPutGet()
{
destroy();
}
void PvaPutGet::checkPutGetState()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
if(connectState==connectIdle){
connect();
getPut();
}
}
// from ChannelPutGetRequester
string PvaPutGet::getRequesterName()
{
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("pva was destroyed");
return yyy->getRequesterName();
}
void PvaPutGet::message(string const & message,MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
PvaPtr yyy = pva.lock();
if(!yyy) throw std::runtime_error("pva was destroyed");
yyy->message(message, messageType);
}
void PvaPutGet::channelPutGetConnect(
const Status& status,
ChannelPutGet::shared_pointer const & channelPutGet,
StructureConstPtr const & putStructure,
StructureConstPtr const & getStructure)
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
channelPutGetConnectStatus = status;
this->channelPutGet = channelPutGet;
if(status.isOK()) {
pvaPutData = PvaPutData::create(putStructure);
pvaPutData->setMessagePrefix(pvaChannel.lock()->getChannelName());
pvaGetData = PvaGetData::create(getStructure);
pvaGetData->setMessagePrefix(pvaChannel.lock()->getChannelName());
}
waitForConnect.signal();
}
void PvaPutGet::putGetDone(
const Status& status,
ChannelPutGet::shared_pointer const & channelPutGet,
PVStructurePtr const & getPVStructure,
BitSetPtr const & getBitSet)
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
channelPutGetStatus = status;
if(status.isOK()) {
pvaGetData->setData(getPVStructure,getBitSet);
}
waitForPutGet.signal();
}
void PvaPutGet::getPutDone(
const Status& status,
ChannelPutGet::shared_pointer const & channelPutGet,
PVStructurePtr const & putPVStructure,
BitSetPtr const & putBitSet)
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
channelGetPutGetStatus = status;
if(status.isOK()) {
PVStructurePtr pvs = pvaPutData->getPVStructure();
pvs->copyUnchecked(*putPVStructure,*putBitSet);
BitSetPtr bs = pvaPutData->getBitSet();
bs->clear();
*bs |= *putBitSet;
}
waitForPutGet.signal();
}
void PvaPutGet::getGetDone(
const Status& status,
ChannelPutGet::shared_pointer const & channelPutGet,
PVStructurePtr const & getPVStructure,
BitSetPtr const & getBitSet)
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
channelPutGetStatus = status;
if(status.isOK()) {
pvaGetData->setData(getPVStructure,getBitSet);
}
waitForPutGet.signal();
}
// from PvaPutGet
void PvaPutGet::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(channelPutGet) channelPutGet->destroy();
channelPutGet.reset();
}
void PvaPutGet::connect()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPutGet::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaPutGet::issueConnect()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
if(connectState!=connectIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " pvaPutGet already connected ";
throw std::runtime_error(ss.str());
}
putGetRequester = ChannelPutGetRequester::shared_pointer(new ChannelPutGetRequesterImpl(this));
connectState = connectActive;
channelPutGet = channel->createChannelPutGet(putGetRequester,pvRequest);
}
Status PvaPutGet::waitConnect()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
if(connectState!=connectActive) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " pvaPutGet illegal connect state ";
throw std::runtime_error(ss.str());
}
waitForConnect.wait();
if(channelPutGetConnectStatus.isOK()) {
connectState = connected;
return Status::Ok;
}
connectState = connectIdle;
return Status(Status::STATUSTYPE_ERROR,channelPutGetConnectStatus.getMessage());
}
void PvaPutGet::putGet()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
issuePutGet();
Status status = waitPutGet();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPutGet::putGet " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaPutGet::issuePutGet()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
if(connectState==connectIdle) connect();
if(putGetState!=putGetIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPutGet::issueGet get or put aleady active ";
throw std::runtime_error(ss.str());
}
putGetState = putGetActive;
channelPutGet->putGet(pvaPutData->getPVStructure(),pvaPutData->getBitSet());
}
Status PvaPutGet::waitPutGet()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
if(putGetState!=putGetActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPutGet::waitPutGet llegal put state";
throw std::runtime_error(ss.str());
}
waitForPutGet.wait();
putGetState = putGetIdle;
if(channelGetPutGetStatus.isOK()) {
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetPutGetStatus.getMessage());
}
void PvaPutGet::getGet()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
issueGetGet();
Status status = waitGetGet();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPutGet::getGet " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaPutGet::issueGetGet()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
if(connectState==connectIdle) connect();
if(putGetState!=putGetIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPutGet::issueGetGet aleady active ";
throw std::runtime_error(ss.str());
}
putGetState = putGetActive;
channelPutGet->getGet();
}
Status PvaPutGet::waitGetGet()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
if(putGetState!=putGetActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPutGet::waitGetGet illegal state";
throw std::runtime_error(ss.str());
}
waitForPutGet.wait();
putGetState = putGetIdle;
if(channelGetPutGetStatus.isOK()) {
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetPutGetStatus.getMessage());
}
void PvaPutGet::getPut()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
issueGetPut();
Status status = waitGetPut();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPutGet::getPut " << status.getMessage();
throw std::runtime_error(ss.str());
}
void PvaPutGet::issueGetPut()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
if(connectState==connectIdle) connect();
if(putGetState!=putGetIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPutGet::issueGetPut aleady active ";
throw std::runtime_error(ss.str());
}
putGetState = putGetActive;
channelPutGet->getPut();
}
Status PvaPutGet::waitGetPut()
{
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
if(putGetState!=putGetActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " PvaPutGet::waitGetPut illegal state";
throw std::runtime_error(ss.str());
}
waitForPutGet.wait();
putGetState = putGetIdle;
if(channelGetPutGetStatus.isOK()) {
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetPutGetStatus.getMessage());
}
PvaGetDataPtr PvaPutGet::getGetData()
{
checkPutGetState();
return pvaGetData;
}
PvaPutDataPtr PvaPutGet::getPutData()
{
checkPutGetState();
return pvaPutData;
}
PvaPutGetPtr PvaPutGet::create(
PvaPtr const &pva,
PvaChannelPtr const & pvaChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
{
PvaPutGetPtr epv(new PvaPutGet(pva,pvaChannel,channel,pvRequest));
return epv;
}
}}

View File

@ -1,120 +0,0 @@
make -C O.linux-x86_64 -f ../Makefile TOP=../.. T_A=linux-x86_64 install
make[1]: Entering directory `/home/epicsv4/pvAccessCPP/pvaSrc/O.linux-x86_64'
/usr/bin/g++ -c -D_POSIX_C_SOURCE=199506L -D_POSIX_THREADS -D_XOPEN_SOURCE=500 -g -ggdb -D_X86_64_ -DUNIX -D_BSD_SOURCE -Dlinux -D_REENTRANT -O3 -g -Wall -m64 -fPIC -MMD -I. -I../O.Common -I. -I.. -I../../include/pv/os/Linux -I../../include/pv -I/home/install/epics/base/include/os/Linux -I/home/install/epics/base/include -I/home/epicsv4/pvCommonCPP/include -I/home/epicsv4/pvDataCPP/include -I/home/epicsv4/pvAccessCPP/include -I/home/epicsv4/pvaSrv/include -I/home/epicsv4/normativeTypesCPP/include -I../../include ../pvaNTMultiChannel.cpp
In file included from ../pvaNTMultiChannel.cpp:13:0:
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:75:5: error: PVAMultiChannelPtr does not name a type
PVAMultiChannelPtr getPVAMultiChannel();
^
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:78:28: error: expected ) before const
PVAMultiChannelPtr const & channelName,
^
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:83:5: error: PVAMultiChannelPtr does not name a type
PVAMultiChannelPtr pvaMultiChannel;
^
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:87:17: error: PVAGetPtr was not declared in this scope
std::vector<PVAGetPtr> pvaGet;
^
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:87:26: error: template argument 1 is invalid
std::vector<PVAGetPtr> pvaGet;
^
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:87:26: error: template argument 2 is invalid
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:88:17: error: PVAPutPtr was not declared in this scope
std::vector<PVAPutPtr> pvaPut;
^
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:88:26: error: template argument 1 is invalid
std::vector<PVAPutPtr> pvaPut;
^
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:88:26: error: template argument 2 is invalid
../pvaNTMultiChannel.cpp: In static member function static epics::pva::PvaNTMultiChannelPtr epics::pva::PvaNTMultiChannel::create(const PvaPtr&, const PVStringArrayPtr&, const StructureConstPtr&, double, const string&):
../pvaNTMultiChannel.cpp:41:85: error: no matching function for call to epics::pva::PvaNTMultiChannel::PvaNTMultiChannel(epics::pva::PvaMultiChannelPtr&, epics::nt::NTMultiChannelPtr&)
return PvaNTMultiChannelPtr(new PvaNTMultiChannel(pvaMultiChannel,ntMultiChannel));
^
../pvaNTMultiChannel.cpp:41:85: note: candidates are:
In file included from ../pvaNTMultiChannel.cpp:13:0:
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:34:23: note: epics::pva::PvaNTMultiChannel::PvaNTMultiChannel()
class epicsShareClass PvaNTMultiChannel
^
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:34:23: note: candidate expects 0 arguments, 2 provided
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:34:23: note: epics::pva::PvaNTMultiChannel::PvaNTMultiChannel(const epics::pva::PvaNTMultiChannel&)
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:34:23: note: candidate expects 1 argument, 2 provided
../pvaNTMultiChannel.cpp: At global scope:
../pvaNTMultiChannel.cpp:44:1: error: prototype for epics::pva::PvaNTMultiChannel::PvaNTMultiChannel(const PvaMultiChannelPtr&, const NTMultiChannelPtr&) does not match any in class epics::pva::PvaNTMultiChannel
PvaNTMultiChannel::PvaNTMultiChannel(
^
In file included from ../pvaNTMultiChannel.cpp:13:0:
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:34:23: error: candidates are: epics::pva::PvaNTMultiChannel::PvaNTMultiChannel(const epics::pva::PvaNTMultiChannel&)
class epicsShareClass PvaNTMultiChannel
^
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:34:23: error: epics::pva::PvaNTMultiChannel::PvaNTMultiChannel()
../pvaNTMultiChannel.cpp: In member function void epics::pva::PvaNTMultiChannel::createGet():
../pvaNTMultiChannel.cpp:72:42: error: pvaMultiChannel was not declared in this scope
PvaChannelArrayPtr pvaChannelArray = pvaMultiChannel->getPvaChannelArray().lock();
^
../pvaNTMultiChannel.cpp:76:12: error: cannot convert std::vector<std::tr1::shared_ptr<epics::pva::PvaGet> > to int in assignment
pvaGet = std::vector<PvaGetPtr>(numChannel,PvaGetPtr());
^
../pvaNTMultiChannel.cpp:81:17: error: invalid types int[size_t {aka long unsigned int}] for array subscript
pvaGet[i] = pvaChannels[i]->createGet(request);
^
../pvaNTMultiChannel.cpp:82:17: error: invalid types int[size_t {aka long unsigned int}] for array subscript
pvaGet[i]->issueConnect();
^
../pvaNTMultiChannel.cpp:86:34: error: invalid types int[size_t {aka long unsigned int}] for array subscript
Status status = pvaGet[i]->waitConnect();
^
../pvaNTMultiChannel.cpp: In member function void epics::pva::PvaNTMultiChannel::createPut():
../pvaNTMultiChannel.cpp:99:42: error: pvaMultiChannel was not declared in this scope
PvaChannelArrayPtr pvaChannelArray = pvaMultiChannel->getPvaChannelArray().lock();
^
../pvaNTMultiChannel.cpp:103:12: error: cannot convert std::vector<std::tr1::shared_ptr<epics::pva::PvaPut> > to int in assignment
pvaPut = std::vector<PvaPutPtr>(numChannel,PvaPutPtr());
^
../pvaNTMultiChannel.cpp:108:17: error: invalid types int[size_t {aka long unsigned int}] for array subscript
pvaPut[i] = pvaChannels[i]->createPut("value");
^
../pvaNTMultiChannel.cpp:109:17: error: invalid types int[size_t {aka long unsigned int}] for array subscript
pvaPut[i]->issueConnect();
^
../pvaNTMultiChannel.cpp:113:34: error: invalid types int[size_t {aka long unsigned int}] for array subscript
Status status = pvaPut[i]->waitConnect();
^
../pvaNTMultiChannel.cpp: In member function epics::nt::NTMultiChannelPtr epics::pva::PvaNTMultiChannel::get():
../pvaNTMultiChannel.cpp:125:15: error: request for member empty in ((epics::pva::PvaNTMultiChannel*)this)->epics::pva::PvaNTMultiChannel::pvaGet, which is of non-class type int
if(pvaGet.empty()) createGet();
^
../pvaNTMultiChannel.cpp:127:48: error: pvaMultiChannel was not declared in this scope
shared_vector<const string> channelNames = pvaMultiChannel->getChannelNames()->view();
^
../pvaNTMultiChannel.cpp:162:17: error: invalid types int[size_t {aka long unsigned int}] for array subscript
pvaGet[i]->issueGet();
^
../pvaNTMultiChannel.cpp:166:31: error: invalid types int[size_t {aka long unsigned int}] for array subscript
Status stat = pvaGet[i]->waitGet();
^
../pvaNTMultiChannel.cpp:171:46: error: invalid types int[size_t {aka long unsigned int}] for array subscript
PVStructurePtr pvStructure = pvaGet[i]->getData()->getPVStructure();
^
../pvaNTMultiChannel.cpp: In member function void epics::pva::PvaNTMultiChannel::put(const NTMultiChannelPtr&):
../pvaNTMultiChannel.cpp:234:15: error: request for member empty in ((epics::pva::PvaNTMultiChannel*)this)->epics::pva::PvaNTMultiChannel::pvaPut, which is of non-class type int
if(pvaPut.empty()) createPut();
^
../pvaNTMultiChannel.cpp:235:48: error: pvaMultiChannel was not declared in this scope
shared_vector<const string> channelNames = pvaMultiChannel->getChannelNames()->view();
^
../pvaNTMultiChannel.cpp:244:39: error: invalid types int[size_t {aka long unsigned int}] for array subscript
PVFieldPtr pvTo = pvaPut[i]->getData()->getValue();
^
../pvaNTMultiChannel.cpp:252:21: error: invalid types int[size_t {aka long unsigned int}] for array subscript
pvaPut[i]->issuePut();
^
../pvaNTMultiChannel.cpp:260:33: error: invalid types int[size_t {aka long unsigned int}] for array subscript
Status status = pvaPut[i]->waitPut();
^
../pvaNTMultiChannel.cpp: In static member function static epics::pva::PvaNTMultiChannelPtr epics::pva::PvaNTMultiChannel::create(const PvaPtr&, const PVStringArrayPtr&, const StructureConstPtr&, double, const string&):
../pvaNTMultiChannel.cpp:42:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
make[1]: *** [pvaNTMultiChannel.o] Error 1
make[1]: Leaving directory `/home/epicsv4/pvAccessCPP/pvaSrc/O.linux-x86_64'
make: *** [install.linux-x86_64] Error 2

View File

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

View File

@ -1,29 +0,0 @@
# 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

@ -1,27 +0,0 @@
# 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

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

View File

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

View File

@ -1,41 +0,0 @@
# 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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,57 +0,0 @@
# Makefile for the pvAccess tests
TOP = ..
include $(TOP)/configure/CONFIG
TESTPROD_HOST += testPvaPutData
testPvaPutData_SRCS = testPvaPutData
testHarness_SRCS += testPvaPutData.cpp
TESTS += testPvaPutData
TESTPROD_HOST += testPvaGetData
testPvaGetData_SRCS = testPvaGetData
testHarness_SRCS += testPvaGetData.cpp
TESTS += testPvaGetData
TESTPROD_HOST += testPvaMonitorData
testPvaMonitorData_SRCS = testPvaMonitorData
testHarness_SRCS += testPvaMonitorData.cpp
TESTS += testPvaMonitorData
TESTPROD_HOST += testPvaPutGetMonitor
testPvaPutGetMonitor_SRCS = testPvaPutGetMonitor
testHarness_SRCS += testPvaPutGetMonitor.cpp
TESTS += testPvaPutGetMonitor
TESTPROD_HOST += testPvaPutGet
testPvaPutGet_SRCS = testPvaPutGet
testHarness_SRCS += testPvaPutGet.cpp
TESTS += testPvaPutGet
TESTPROD_HOST += testPvaMultiDouble
testPvaMultiDouble_SRCS = testPvaMultiDouble
testHarness_SRCS += testPvaMultiDouble.cpp
TESTS += testPvaMultiDouble
TESTPROD_HOST += testPvaNTMultiChannel
testPvaNTMultiChannel_SRCS = testPvaNTMultiChannel
testHarness_SRCS += testPvaNTMultiChannel.cpp
TESTS += testPvaNTMultiChannel
PROD_LIBS += pva pvAccess pvData nt Com
testHarness_SRCS += easyAllTests.c
PROD_vxWorks = vxTestHarness
vxTestHarness_SRCS += $(testHarness_SRCS)
TESTSPEC_vxWorks = vxTestHarness.$(MUNCH_SUFFIX); easyAllTests
PROD_RTEMS += rtemsTestHarness
rtemsTestHarness_SRCS += rtemsTestHarness.c rtemsConfig.c
rtemsTestHarness_SRCS += $(testHarness_SRCS)
TESTSPEC_RTEMS = rtemsTestHarness.$(MUNCH_SUFFIX); easyAllTests
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
include $(TOP)/configure/RULES

View File

@ -1,31 +0,0 @@
/*
* Run PvaPVA tests as a batch.
*
* Do *not* include performance measurements here, they don't help to
* prove functionality (which is the point of this convenience routine).
*/
#include <stdio.h>
#include <epicsThread.h>
#include <epicsUnitTest.h>
int testPvaGetData(void);
int testPvaPutData(void);
int testPvaMonitorData(void);
int testPvaPutGetMonitor(void);
int testPvaPutGet(void);
int testPvaMultiDouble(void);
int testPvaNTMultiChannel(void);
void easyAllTests(void)
{
testHarness();
runTest(testPvaGetData);
runTest(testPvaPutData);
runTest(testPvaMonitorData);
runTest(testPvaPutMonitor);
runTest(testPvaPut);
runTest(testPvaMultiDouble);
runTest(testPvaNTMultiChannel);
}

View File

@ -1,155 +0,0 @@
/*testPvaGetData.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 <epicsUnitTest.h>
#include <testMain.h>
#include <pv/pva.h>
#include <pv/bitSet.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
static PvaPtr pva = Pva::create();
static FieldCreatePtr fieldCreate = getFieldCreate();
static StandardFieldPtr standardField = getStandardField();
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
void testDouble()
{
cout << "\nstarting testDouble\n";
StructureConstPtr structure =
fieldCreate->createFieldBuilder()->
add("alarm",standardField->alarm()) ->
add("timeStamp",standardField->timeStamp()) ->
add("value",pvDouble) ->
createStructure();
PvaGetDataPtr pvaData = PvaGetData::create(structure);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(pvaData->getStructure());
BitSetPtr bitSet = BitSetPtr(new BitSet(pvStructure->getNumberFields()));
pvaData->setData(pvStructure,bitSet);
PVDoublePtr pvDouble = pvStructure->getSubField<PVDouble>("value");
size_t valueOffset = pvDouble->getFieldOffset();
BitSetPtr change = pvaData->getBitSet();
pvDouble->put(5.0);
change->set(pvDouble->getFieldOffset());
testOk(change->cardinality()==1,"num set bits 1");
testOk(change->get(valueOffset)==true,"value changed");
testOk(pvaData->hasValue()==true,"hasValue");
testOk(pvaData->isValueScalar()==true,"isValueScalar");
testOk(pvaData->isValueScalarArray()==false,"isValueScalarArray");
bool result;
result = false;
if(pvaData->getValue()) result = true;
testOk(result==true,"getValue");
result = false;
if(pvaData->getScalarValue()) result = true;
testOk(result==true,"getScalarValue");
try {
pvaData->getArrayValue();
} catch (std::runtime_error e) {
cout << "getArrayValue " << e.what() << endl;
}
try {
pvaData->getScalarArrayValue();
} catch (std::runtime_error e) {
cout << " getScalarArrayValue " << e.what() << endl;
}
cout << "as double " << pvaData->getDouble() << endl;
cout << "as string " << pvaData->getString() << endl;
try {
shared_vector<const double> value = pvaData->getDoubleArray();
} catch (std::runtime_error e) {
cout << " getDoubleArray " << e.what() << endl;
}
try {
shared_vector<const string> value = pvaData->getStringArray();
} catch (std::runtime_error e) {
cout << " getStringArray " << e.what() << endl;
}
}
void testDoubleArray()
{
cout << "\nstarting testDoubleArray\n";
StructureConstPtr structure =
fieldCreate->createFieldBuilder()->
add("alarm",standardField->alarm()) ->
add("timeStamp",standardField->timeStamp()) ->
addArray("value",pvDouble) ->
createStructure();
PvaGetDataPtr pvaData = PvaGetData::create(structure);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(pvaData->getStructure());
BitSetPtr bitSet = BitSetPtr(new BitSet(pvStructure->getNumberFields()));
pvaData->setData(pvStructure,bitSet);
PVDoubleArrayPtr pvalue = pvaData->getPVStructure()->getSubField<PVDoubleArray>("value");
BitSetPtr change = pvaData->getBitSet();
size_t valueOffset = pvalue->getFieldOffset();
size_t len = 5;
shared_vector<double> value(len);
for(size_t i=0; i<len; ++i) value[i] = i*10.0;
pvalue->replace(freeze(value));
change->set(valueOffset);
testOk(change->cardinality()==1,"num set bits 1");
testOk(change->get(valueOffset)==true,"value changed");
testOk(pvaData->hasValue()==true,"hasValue");
testOk(pvaData->isValueScalar()==false,"isValueScalar");
testOk(pvaData->isValueScalarArray()==true,"isValueScalarArray");
bool result;
result = false;
if(pvaData->getValue()) result = true;
testOk(result==true,"getValue");
result = false;
if(pvaData->getArrayValue()) result = true;
testOk(result==true,"getArrayValue");
result = false;
if(pvaData->getScalarArrayValue()) result = true;
testOk(result==true,"getScalarValue");
try {
pvaData->getScalarValue();
} catch (std::runtime_error e) {
cout << " getScalarValue " << e.what() << endl;
}
try {
cout << "as double " << pvaData->getDouble() << endl;
} catch (std::runtime_error e) {
cout << " getDouble " << e.what() << endl;
}
try {
string val = pvaData->getString();
} catch (std::runtime_error e) {
cout << " getString " << e.what() << endl;
}
cout << "as doubleArray " << pvaData->getDoubleArray() << endl;
try {
shared_vector<const string> value = pvaData->getStringArray();
} catch (std::runtime_error e) {
cout << " getStringArray " << e.what() << endl;
}
}
MAIN(testPvaGetData)
{
cout << "\nstarting testPvaGetData\n";
testPlan(15);
testDouble();
testDoubleArray();
return 0;
}

View File

@ -1,153 +0,0 @@
/*testPvaMonitorData.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 <epicsUnitTest.h>
#include <testMain.h>
#include <pv/pva.h>
#include <pv/bitSet.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
static PvaPtr pva = Pva::create();
static FieldCreatePtr fieldCreate = getFieldCreate();
static StandardFieldPtr standardField = getStandardField();
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
void testDouble()
{
cout << "\nstarting testDouble\n";
StructureConstPtr structure =
fieldCreate->createFieldBuilder()->
add("alarm",standardField->alarm()) ->
add("timeStamp",standardField->timeStamp()) ->
add("value",pvDouble) ->
createStructure();
PvaMonitorDataPtr pvaData = PvaMonitorData::create(structure);
MonitorElementPtr monitorElement(new MonitorElement(pvDataCreate->createPVStructure(pvaData->getStructure())));
pvaData->setData(monitorElement);
PVDoublePtr pvDouble = pvaData->getPVStructure()->getSubField<PVDouble>("value");
size_t valueOffset = pvDouble->getFieldOffset();
BitSetPtr change = pvaData->getChangedBitSet();
pvDouble->put(5.0);
change->set(pvDouble->getFieldOffset());
testOk(change->cardinality()==1,"num set bits 1");
testOk(change->get(valueOffset)==true,"value changed");
testOk(pvaData->hasValue()==true,"hasValue");
testOk(pvaData->isValueScalar()==true,"isValueScalar");
testOk(pvaData->isValueScalarArray()==false,"isValueScalarArray");
bool result;
result = false;
if(pvaData->getValue()) result = true;
testOk(result==true,"getValue");
result = false;
if(pvaData->getScalarValue()) result = true;
testOk(result==true,"getScalarValue");
try {
pvaData->getArrayValue();
} catch (std::runtime_error e) {
cout << "getArrayValue " << e.what() << endl;
}
try {
pvaData->getScalarArrayValue();
} catch (std::runtime_error e) {
cout << " getScalarArrayValue " << e.what() << endl;
}
cout << "as double " << pvaData->getDouble() << endl;
cout << "as string " << pvaData->getString() << endl;
try {
shared_vector<const double> value = pvaData->getDoubleArray();
} catch (std::runtime_error e) {
cout << " getDoubleArray " << e.what() << endl;
}
try {
shared_vector<const string> value = pvaData->getStringArray();
} catch (std::runtime_error e) {
cout << " getStringArray " << e.what() << endl;
}
}
void testDoubleArray()
{
cout << "\nstarting testDoubleArray\n";
StructureConstPtr structure =
fieldCreate->createFieldBuilder()->
add("alarm",standardField->alarm()) ->
add("timeStamp",standardField->timeStamp()) ->
addArray("value",pvDouble) ->
createStructure();
PvaMonitorDataPtr pvaData = PvaMonitorData::create(structure);
MonitorElementPtr monitorElement(new MonitorElement(pvDataCreate->createPVStructure(pvaData->getStructure())));
pvaData->setData(monitorElement);
PVDoubleArrayPtr pvalue = pvaData->getPVStructure()->getSubField<PVDoubleArray>("value");
BitSetPtr change = pvaData->getChangedBitSet();
size_t valueOffset = pvalue->getFieldOffset();
size_t len = 5;
shared_vector<double> value(len);
for(size_t i=0; i<len; ++i) value[i] = i*10.0;
pvalue->replace(freeze(value));
change->set(valueOffset);
testOk(change->cardinality()==1,"num set bits 1");
testOk(change->get(valueOffset)==true,"value changed");
testOk(pvaData->hasValue()==true,"hasValue");
testOk(pvaData->isValueScalar()==false,"isValueScalar");
testOk(pvaData->isValueScalarArray()==true,"isValueScalarArray");
bool result;
result = false;
if(pvaData->getValue()) result = true;
testOk(result==true,"getValue");
result = false;
if(pvaData->getArrayValue()) result = true;
testOk(result==true,"getArrayValue");
result = false;
if(pvaData->getScalarArrayValue()) result = true;
testOk(result==true,"getScalarValue");
try {
pvaData->getScalarValue();
} catch (std::runtime_error e) {
cout << " getScalarValue " << e.what() << endl;
}
try {
cout << "as double " << pvaData->getDouble() << endl;
} catch (std::runtime_error e) {
cout << " getDouble " << e.what() << endl;
}
try {
string val = pvaData->getString();
} catch (std::runtime_error e) {
cout << " getString " << e.what() << endl;
}
cout << "as doubleArray " << pvaData->getDoubleArray() << endl;
try {
shared_vector<const string> value = pvaData->getStringArray();
} catch (std::runtime_error e) {
cout << " getStringArray " << e.what() << endl;
}
}
MAIN(testPvaMonitorData)
{
cout << "\nstarting testPvaMonitorData\n";
testPlan(15);
testDouble();
testDoubleArray();
return 0;
}

View File

@ -1,156 +0,0 @@
/*testPvaMultiDouble.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/pvaMultiDouble.h>
#include <epicsUnitTest.h>
#include <testMain.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
static void testGood(PvaPtr const &pva)
{
bool isOk = true;
cout << "\nstarting testGood\n";
try {
PvaPtr pva(Pva::create());
size_t num = 5;
shared_vector<string> channelNames(num);
channelNames[0] = "exampleDouble01";
channelNames[1] = "exampleDouble02";
channelNames[2] = "exampleDouble03";
channelNames[3] = "exampleDouble04";
channelNames[4] = "exampleDouble05";
PVStringArrayPtr pvNames =
getPVDataCreate()->createPVScalarArray<PVStringArray>();
pvNames->replace(freeze(channelNames));
PvaMultiDoublePtr multiDouble(PvaMultiDouble::create(pva,pvNames));
shared_vector<double> data = multiDouble->get();
cout << "initial " << data << endl;
for(size_t i=0; i<num; ++i) data[i] = data[i] + 1.1;
multiDouble->put(data);
data = multiDouble->get();
cout << "final " << data << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
isOk = false;
}
testOk(isOk==true,"all channels double");
}
static void testGoodMixed(PvaPtr const &pva)
{
bool isOk = true;
cout << "\nstarting testGoodMixed\n";
try {
PvaPtr pva(Pva::create());
size_t num = 5;
shared_vector<string> channelNames(num);
channelNames[0] = "exampleByte";
channelNames[1] = "exampleShort";
channelNames[2] = "exampleInt";
channelNames[3] = "exampleFloat";
channelNames[4] = "exampleDouble";
PVStringArrayPtr pvNames =
getPVDataCreate()->createPVScalarArray<PVStringArray>();
pvNames->replace(freeze(channelNames));
PvaMultiDoublePtr multiDouble(PvaMultiDouble::create(pva,pvNames));
shared_vector<double> data = multiDouble->get();
cout << "initial " << data << endl;
for(size_t i=0; i<num; ++i) data[i] = data[i] + 1.1;
multiDouble->put(data);
data = multiDouble->get();
cout << "final " << data << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
isOk = false;
}
testOk(isOk==true,"channels mixed type");
}
static void testChannelNotExist(PvaPtr const &pva)
{
bool isOk = true;
cout << "\nstarting testChannelNotExist\n";
try {
PvaPtr pva(Pva::create());
size_t num = 5;
shared_vector<string> channelNames(num);
channelNames[0] = "exampleDouble01";
channelNames[1] = "exampleDouble02";
channelNames[2] = "exampleDouble03";
channelNames[3] = "NoneExistChannel";
channelNames[4] = "exampleDouble05";
PVStringArrayPtr pvNames =
getPVDataCreate()->createPVScalarArray<PVStringArray>();
pvNames->replace(freeze(channelNames));
PvaMultiDoublePtr multiDouble(PvaMultiDouble::create(pva,pvNames));
shared_vector<double> data = multiDouble->get();
cout << "initial " << data << endl;
for(size_t i=0; i<num; ++i) data[i] = data[i] + 1.1;
multiDouble->put(data);
data = multiDouble->get();
cout << "final " << data << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
isOk = false;
}
testOk(isOk==false,"channel not exist");
}
static void testNonNumeric(PvaPtr const &pva)
{
bool isOk = true;
cout << "\nstarting testNonNumeric\n";
try {
PvaPtr pva(Pva::create());
size_t num = 5;
shared_vector<string> channelNames(num);
channelNames[0] = "exampleDouble01";
channelNames[1] = "exampleDouble02";
channelNames[2] = "exampleDouble03";
channelNames[3] = "exampleDouble04";
channelNames[4] = "exampleDouble05Array";
PVStringArrayPtr pvNames =
getPVDataCreate()->createPVScalarArray<PVStringArray>();
pvNames->replace(freeze(channelNames));
PvaMultiDoublePtr multiDouble(PvaMultiDouble::create(pva,pvNames));
shared_vector<double> data = multiDouble->get();
cout << "initial " << data << endl;
for(size_t i=0; i<num; ++i) data[i] = data[i] + 1.1;
multiDouble->put(data);
data = multiDouble->get();
cout << "final " << data << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
isOk = false;
}
testOk(isOk==false,"channel not numeric");
}
MAIN(testPvaMultiDouble)
{
cout << "\nstarting testPvaMultiDouble\n";
testPlan(4);
PvaPtr pva = Pva::create();
testGood(pva);
testGoodMixed(pva);
testChannelNotExist(pva);
testNonNumeric(pva);
cout << "done\n";
return 0;
}

View File

@ -1,132 +0,0 @@
/*testPvaNTMultiChannel.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/pvaNTMultiChannel.h>
#include <epicsUnitTest.h>
#include <testMain.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
using namespace epics::nt;
using std::tr1::static_pointer_cast;
static void testGood(PvaPtr const &pva)
{
PVDataCreatePtr pvDataCreate(getPVDataCreate());
bool isOk = true;
cout << "\nstarting testGood\n";
try {
PvaPtr pva(Pva::create());
size_t num = 5;
shared_vector<string> channelNames(num);
channelNames[0] = "exampleDouble";
channelNames[1] = "exampleDoubleArray";
channelNames[2] = "exampleString";
channelNames[3] = "exampleBoolean";
channelNames[4] = "exampleEnum";
PVStringArrayPtr pvNames = pvDataCreate->
createPVScalarArray<PVStringArray>();
pvNames->replace(freeze(channelNames));
NTMultiChannelBuilderPtr builder = NTMultiChannel::createBuilder();
StructureConstPtr structure = builder->
addTimeStamp()->
addSeverity() ->
addStatus() ->
addMessage() ->
addSecondsPastEpoch() ->
addNanoseconds() ->
addUserTag() ->
createStructure();
PvaNTMultiChannelPtr multi = PvaNTMultiChannel::create(
pva,pvNames,structure);
NTMultiChannelPtr nt = multi->get();
for(size_t numtimes=0; numtimes<3; ++numtimes) {
PVUnionArrayPtr pvValue = nt->getPVStructure()->
getSubField<PVUnionArray>("value");
cout << "initial\n" << nt->getPVStructure() << endl;
shared_vector<PVUnionPtr> valueVector = pvValue->reuse();
for(size_t i=0; i<num; ++i)
{
PVFieldPtr pvField = valueVector[i]->get();
Type type = pvField->getField()->getType();
if(type==scalar) {
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(ScalarTypeFunc::isNumeric(scalarType)) {
double oldValue = pvScalar->getAs<double>();
oldValue++;
pvScalar->putFrom<double>(oldValue);
} else if(scalarType==pvString) {
PVStringPtr pv = static_pointer_cast<PVString>(pvField);
string val = pv->get();
val += " added";
pv->put(val);
} else if(scalarType==pvBoolean) {
PVBooleanPtr pv = static_pointer_cast<PVBoolean>(pvField);
bool val = pv->get();
pv->put(!val);
}
} else if(type==scalarArray) {
PVScalarArrayPtr pv =
static_pointer_cast<PVScalarArray>(pvField);
ScalarType scalarType = pv->getScalarArray()->getElementType();
if(scalarType==pvDouble) {
PVDoubleArrayPtr pvd = static_pointer_cast<PVDoubleArray>(pv);
shared_vector<double> valvec = pvd->reuse();
if(valvec.capacity()==0) {
valvec.resize(4);
for(size_t i=0; i<valvec.size(); ++i) valvec[i] = i;
}
for(size_t i=0; i<valvec.size(); ++i) valvec[i] = valvec[i] + 1.0;
pvd->replace(freeze(valvec));
}
} else if(type==epics::pvData::structure) {
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
PVIntPtr pv = pvStructure->getSubField<PVInt>("index");
if(pv) {
PVStringArrayPtr choices = pvStructure->getSubField<PVStringArray>("choices");
if(choices) {
int32 nchoices = choices->getLength();
int32 oldval = pv->get();
int32 newval = (oldval==nchoices) ? 0 : ++oldval;
pv->put(newval);
}
}
}
}
pvValue->replace(freeze(valueVector));
multi->put(nt);
nt = multi->get();
}
cout << "final\n" << nt->getPVStructure() << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
isOk = false;
}
testOk(isOk==true,"no problems");
}
MAIN(testPvaNTMultiChannel)
{
cout << "\nstarting testPvaNTMultiChannel\n";
testPlan(1);
PvaPtr pva = Pva::create();
testGood(pva);
cout << "done\n";
return 0;
}

View File

@ -1,229 +0,0 @@
/*testPvaPutData.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 <epicsUnitTest.h>
#include <testMain.h>
#include <pv/pva.h>
#include <pv/bitSet.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
static PvaPtr pva = Pva::create();
static FieldCreatePtr fieldCreate = getFieldCreate();
static StandardFieldPtr standardField = getStandardField();
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
static void testPostPut()
{
cout << "\nstarting testPostPut\n";
StructureConstPtr structure =
fieldCreate->createFieldBuilder()->
add("alarm",standardField->alarm()) ->
add("timeStamp",standardField->timeStamp()) ->
addNestedStructure("power") ->
add("value",pvDouble) ->
add("alarm",standardField->alarm()) ->
endNested()->
addNestedStructure("voltage") ->
add("value",pvDouble) ->
add("alarm",standardField->alarm()) ->
endNested()->
addNestedStructure("current") ->
add("value",pvDouble) ->
add("alarm",standardField->alarm()) ->
endNested()->
createStructure();
PvaPutDataPtr pvaData = PvaPutData::create(structure);
PVStructurePtr pvStructure = pvaData->getPVStructure();
BitSetPtr change = pvaData->getBitSet();
PVDoublePtr powerValue = pvStructure->getSubField<PVDouble>("power.value");
PVDoublePtr voltageValue = pvStructure->getSubField<PVDouble>("voltage.value");
PVDoublePtr currentValue = pvStructure->getSubField<PVDouble>("current.value");
size_t powerOffset = powerValue->getFieldOffset();
size_t voltageOffset = voltageValue->getFieldOffset();
size_t currentOffset = currentValue->getFieldOffset();
change->clear();
powerValue->put(1.0);
voltageValue->put(2.0);
currentValue->put(.5);
cout << "changed\n";
cout << pvaData->showChanged(cout) << endl;
testOk(change->cardinality()==3,"num set bits 3");
testOk(change->get(powerOffset)==true,"power changed");
testOk(change->get(voltageOffset)==true,"voltage changed");
testOk(change->get(currentOffset)==true,"current changed");
}
void testDouble()
{
cout << "\nstarting testDouble\n";
StructureConstPtr structure =
fieldCreate->createFieldBuilder()->
add("alarm",standardField->alarm()) ->
add("timeStamp",standardField->timeStamp()) ->
add("value",pvDouble) ->
createStructure();
PvaPutDataPtr pvaData = PvaPutData::create(structure);
PVDoublePtr pvDouble = pvaData->getPVStructure()->getSubField<PVDouble>("value");
pvDouble->put(5.0);
BitSetPtr change = pvaData->getBitSet();
size_t valueOffset = pvDouble->getFieldOffset();
testOk(change->cardinality()==1,"num set bits 1");
testOk(change->get(valueOffset)==true,"value changed");
testOk(pvaData->hasValue()==true,"hasValue");
testOk(pvaData->isValueScalar()==true,"isValueScalar");
testOk(pvaData->isValueScalarArray()==false,"isValueScalarArray");
bool result;
result = false;
if(pvaData->getValue()) result = true;
testOk(result==true,"getValue");
result = false;
if(pvaData->getScalarValue()) result = true;
testOk(result==true,"getScalarValue");
try {
pvaData->getArrayValue();
} catch (std::runtime_error e) {
cout << "getArrayValue " << e.what() << endl;
}
try {
pvaData->getScalarArrayValue();
} catch (std::runtime_error e) {
cout << " getScalarArrayValue " << e.what() << endl;
}
cout << "as double " << pvaData->getDouble() << endl;
cout << "as string " << pvaData->getString() << endl;
try {
shared_vector<const double> value = pvaData->getDoubleArray();
} catch (std::runtime_error e) {
cout << " getDoubleArray " << e.what() << endl;
}
try {
shared_vector<const string> value = pvaData->getStringArray();
} catch (std::runtime_error e) {
cout << " getStringArray " << e.what() << endl;
}
pvaData->putDouble(5.0);
pvaData->putString("1e5");
try {
size_t len = 2;
shared_vector<double> val(len);
for(size_t i=0; i<len; ++i) val[i] = (i+1)*10.0;
pvaData->putDoubleArray(freeze(val));
} catch (std::runtime_error e) {
cout << " putDoubleArray " << e.what() << endl;
}
try {
size_t len = 2;
shared_vector<string> val(len);
val[0] = "one"; val[1] = "two";
pvaData->putStringArray(freeze(val));
} catch (std::runtime_error e) {
cout << " putStringArray " << e.what() << endl;
}
}
void testDoubleArray()
{
cout << "\nstarting testDoubleArray\n";
StructureConstPtr structure =
fieldCreate->createFieldBuilder()->
add("alarm",standardField->alarm()) ->
add("timeStamp",standardField->timeStamp()) ->
addArray("value",pvDouble) ->
createStructure();
PvaPutDataPtr pvaData = PvaPutData::create(structure);
PVDoubleArrayPtr pvalue = pvaData->getPVStructure()->getSubField<PVDoubleArray>("value");
size_t len = 5;
shared_vector<double> value(len);
for(size_t i=0; i<len; ++i) value[i] = i*10.0;
pvalue->replace(freeze(value));
BitSetPtr change = pvaData->getBitSet();
size_t valueOffset = pvalue->getFieldOffset();
testOk(change->cardinality()==1,"num set bits 1");
testOk(change->get(valueOffset)==true,"value changed");
testOk(pvaData->hasValue()==true,"hasValue");
testOk(pvaData->isValueScalar()==false,"isValueScalar");
testOk(pvaData->isValueScalarArray()==true,"isValueScalarArray");
bool result;
result = false;
if(pvaData->getValue()) result = true;
testOk(result==true,"getValue");
result = false;
if(pvaData->getArrayValue()) result = true;
testOk(result==true,"getArrayValue");
result = false;
if(pvaData->getScalarArrayValue()) result = true;
testOk(result==true,"getScalarValue");
try {
pvaData->getScalarValue();
} catch (std::runtime_error e) {
cout << " getScalarValue " << e.what() << endl;
}
try {
cout << "as double " << pvaData->getDouble() << endl;
} catch (std::runtime_error e) {
cout << " getDouble " << e.what() << endl;
}
try {
string val = pvaData->getString();
} catch (std::runtime_error e) {
cout << " getString " << e.what() << endl;
}
cout << "as doubleArray " << pvaData->getDoubleArray() << endl;
try {
shared_vector<const string> value = pvaData->getStringArray();
} catch (std::runtime_error e) {
cout << " getStringArray " << e.what() << endl;
}
try {
pvaData->putDouble(5.0);
} catch (std::runtime_error e) {
cout << " putDouble " << e.what() << endl;
}
try {
pvaData->putString("1e5");
} catch (std::runtime_error e) {
cout << " putString " << e.what() << endl;
}
value = shared_vector<double>(len);
for(size_t i=0; i<len; ++i) value[i] = (i+1)* 2;
pvaData->putDoubleArray(freeze(value));
cout << "as doubleArray " << pvaData->getDoubleArray() << endl;
try {
size_t len = 2;
shared_vector<string> val(len);
val[0] = "one"; val[1] = "two";
pvaData->putStringArray(freeze(val));
cout << "as stringArray " << val << endl;
} catch (std::runtime_error e) {
cout << " putStringArray " << e.what() << endl;
}
}
MAIN(testPvaPutData)
{
cout << "\nstarting testPvaPutData\n";
testPlan(19);
testPostPut();
testDouble();
testDoubleArray();
return 0;
}

View File

@ -1,66 +0,0 @@
/*examplePvaPutGet.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/pva.h>
#include <epicsUnitTest.h>
#include <testMain.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
static void example(PvaPtr const &pva)
{
cout << "\nstarting channelPutGet example\n";
try {
PvaChannelPtr pvaChannel = pva->createChannel("examplePowerSupply");
pvaChannel->connect(2.0);
testOk(true==true,"connected");
PvaPutGetPtr putGet = pvaChannel->createPutGet(
"putField(power.value,voltage.value)getField()");
PvaPutDataPtr putData = putGet->getPutData();
testOk(true==true,"put connected");
PVStructurePtr pvStructure = putData->getPVStructure();
PVDoublePtr power = pvStructure->getSubField<PVDouble>("power.value");
PVDoublePtr voltage = pvStructure->getSubField<PVDouble>("voltage.value");
power->put(5.0);
voltage->put(5.0);
putGet->putGet();
PvaGetDataPtr getData = putGet->getGetData();
pvStructure = getData->getPVStructure();
BitSetPtr bitSet = getData->getBitSet();
cout << "changed " << getData->showChanged(cout) << endl;
cout << "bitSet " << *bitSet << endl;
power->put(6.0);
putGet->putGet();
pvStructure = getData->getPVStructure();
bitSet = getData->getBitSet();
cout << "changed " << getData->showChanged(cout) << endl;
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
}
MAIN(testPvaPutGet)
{
cout << "\nstarting testPvaPutGet\n";
testPlan(2);
PvaPtr pva = Pva::create();
example(pva);
cout << "done\n";
return 0;
}

View File

@ -1,89 +0,0 @@
/*testPvaPutGetMonitor.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/pva.h>
#include <epicsUnitTest.h>
#include <testMain.h>
using namespace std;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pva;
class MyMonitor : public PvaMonitorRequester
{
public:
MyMonitor() {}
virtual ~MyMonitor() {}
virtual void event(PvaMonitorPtr monitor)
{
while(true) {
if(!monitor->poll()) return;
PvaMonitorDataPtr pvaData = monitor->getData();
cout << "changed\n";
pvaData->showChanged(cout);
cout << "overrun\n";
pvaData->showOverrun(cout);
monitor->releaseEvent();
}
}
};
static void exampleDouble(PvaPtr const &pva)
{
cout << "\nstarting exampleDouble\n";
try {
cout << "long way\n";
PvaChannelPtr pvaChannel = pva->createChannel("exampleDouble");
pvaChannel->connect(2.0);
testOk(true==true,"connected");
PvaPutPtr put = pvaChannel->createPut();
PvaPutDataPtr putData = put->getData();
testOk(true==true,"put connected");
PvaGetPtr get = pvaChannel->createGet();
PvaGetDataPtr getData = get->getData();
testOk(true==true,"get connected");
PvaMonitorRequesterPtr requester(new MyMonitor());
PvaMonitorPtr monitor = pvaChannel->monitor(requester);
testOk(true==true,"monitor connected");
double out;
double in;
for(size_t i=0 ; i< 5; ++i) {
out = i;
putData->putDouble(out);
put->put();
get->get();
in = getData->getDouble();
cout << "out " << out << " in " << in << endl;
}
PvaProcessPtr process = pvaChannel->createProcess();
process->connect();
process->process();
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
}
MAIN(testPvaPutGetMonitor)
{
cout << "\nstarting testPvaPutGetMonitor\n";
testPlan(4);
PvaPtr pva = Pva::create();
exampleDouble(pva);
cout << "done\n";
return 0;
}

View File

@ -944,10 +944,3 @@ namespace pvAccess {
}} }}
#endif /* PVACCESS_H */ #endif /* PVACCESS_H */
/** @page Overview Documentation
*
*<a href = "pvAccessOverview.html">pvAccessOverview.html</a>
*
*/