Compare commits
139 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcaac0163a | ||
|
|
f9d27b2d74 | ||
|
|
2bc01a482e | ||
|
|
392cc7426d | ||
|
|
dd955ea81e | ||
|
|
a0a19bcfd9 | ||
|
|
16b46448c0 | ||
|
|
e5947aa0a2 | ||
|
|
3c30598a56 | ||
|
|
85673cadad | ||
|
|
db0d1e8f9e | ||
|
|
99f9e0429f | ||
|
|
3dc852e2b7 | ||
|
|
d9c3dfcf26 | ||
|
|
38f7d6bea1 | ||
|
|
4f38e7904d | ||
|
|
ad03935c5b | ||
|
|
5574452b08 | ||
|
|
649cd6800d | ||
|
|
05a7a6923f | ||
|
|
f5226f23dc | ||
|
|
e1fdcfcab0 | ||
|
|
5ec16a1772 | ||
|
|
ba64c6a6a5 | ||
|
|
ed9a707f14 | ||
|
|
6ec5fb6ef9 | ||
|
|
ddab44823f | ||
|
|
d54060576a | ||
|
|
e8a9beec07 | ||
|
|
84304d9b4e | ||
|
|
b62cb22818 | ||
|
|
1e6fb17e92 | ||
|
|
bc2622f70a | ||
|
|
da81f8db83 | ||
|
|
7c58eae97e | ||
|
|
0b3e1c9fd1 | ||
|
|
59afc5335a | ||
|
|
399a39a20a | ||
|
|
000dde0454 | ||
|
|
5076057d8d | ||
|
|
fd60732a8c | ||
|
|
002a465705 | ||
|
|
28186f0e3d | ||
|
|
fc037cf6dc | ||
|
|
5ddcc70993 | ||
|
|
dc93316856 | ||
|
|
b40eca79cf | ||
|
|
f6f5539f7b | ||
|
|
0d66034092 | ||
|
|
1de2666993 | ||
|
|
7d0b6d86ea | ||
|
|
bef1a86b8b | ||
|
|
8f66d21cca | ||
|
|
f4b7bdbdf0 | ||
|
|
5f8922e349 | ||
|
|
5b7c6ea4d8 | ||
|
|
08f8b56740 | ||
|
|
b52fc4fce8 | ||
|
|
b976d918d5 | ||
|
|
c7a58af787 | ||
|
|
b1143fea9e | ||
|
|
efa9dff1d4 | ||
|
|
3b9f8a26c0 | ||
|
|
f64329e661 | ||
|
|
8b9a8e7050 | ||
|
|
5381a0c294 | ||
|
|
36b8e60152 | ||
|
|
f226c7ac96 | ||
|
|
2f54b89227 | ||
|
|
ec02b9f7ee | ||
|
|
efff7f5041 | ||
|
|
8c292eeebc | ||
|
|
25e8c65bb0 | ||
|
|
f47b059a5b | ||
|
|
16d8284131 | ||
|
|
ef4a9d6b4b | ||
|
|
8ec19d25f1 | ||
|
|
2d3b415c00 | ||
|
|
177a048220 | ||
|
|
acd986c19d | ||
|
|
3cb954aefa | ||
|
|
bffeca57a8 | ||
|
|
e8a04138b0 | ||
|
|
9f5aec1609 | ||
|
|
8dadad8101 | ||
|
|
9cc7c65df6 | ||
|
|
518718357c | ||
|
|
1ae93ddaed | ||
|
|
99bf23e8fa | ||
|
|
b5846433bf | ||
|
|
8760d5e314 | ||
|
|
a25a89fadc | ||
|
|
49312d62d5 | ||
|
|
42fb15211a | ||
|
|
86ee0c5295 | ||
|
|
1fca4d5757 | ||
|
|
95e9b394c4 | ||
|
|
3c5e4a1db5 | ||
|
|
70b30ade1a | ||
|
|
c9d4f6aa02 | ||
|
|
198a6a691f | ||
|
|
acc87079d6 | ||
|
|
2ede54033e | ||
|
|
6be30cd104 | ||
|
|
4ee19f4dd1 | ||
|
|
08eb138d02 | ||
|
|
3765a0567c | ||
|
|
b06c13c5d8 | ||
|
|
dbc5c434cb | ||
|
|
9c7cd05437 | ||
|
|
6a187d274e | ||
|
|
0d21cb267a | ||
|
|
eba5aa6c8b | ||
|
|
7465da3217 | ||
|
|
ddee226a49 | ||
|
|
76546d22b4 | ||
|
|
63eb1aa703 | ||
|
|
89396a7455 | ||
|
|
f1aca7e20f | ||
|
|
f2bbec36ef | ||
|
|
887b453bac | ||
|
|
131c2fc31a | ||
|
|
594aa52a20 | ||
|
|
eef8bd4fba | ||
|
|
8058a389d7 | ||
|
|
52ab0ff37b | ||
|
|
9df8d3cb2a | ||
|
|
f27e741eca | ||
|
|
53c89e5a73 | ||
|
|
1fdcfb7ad1 | ||
|
|
379a132cd7 | ||
|
|
5b46b9ebed | ||
|
|
c0cb48e97e | ||
|
|
072113ab4a | ||
|
|
7f521bdc3c | ||
|
|
fdeda9dc97 | ||
|
|
327371151a | ||
|
|
d7555b9c6c | ||
|
|
479e3ab603 |
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
bin/
|
||||
include/
|
||||
lib/
|
||||
db/
|
||||
dbd/
|
||||
configure/*.local
|
||||
html/
|
||||
**/O.*
|
||||
**/**/O.*
|
||||
20
.hgignore
20
.hgignore
@@ -1,20 +0,0 @@
|
||||
QtC*
|
||||
|
||||
syntax: glob
|
||||
.DS_Store
|
||||
./bin
|
||||
./include
|
||||
./lib
|
||||
./doc
|
||||
./db
|
||||
./dbd
|
||||
./envPaths
|
||||
./documentation/html
|
||||
./O.*
|
||||
./*.pyc
|
||||
./*.so
|
||||
./documentation/html
|
||||
./RELEASE.local
|
||||
./CONFIG_SITE.local
|
||||
|
||||
syntax: regexp
|
||||
31
COPYRIGHT
Normal file
31
COPYRIGHT
Normal file
@@ -0,0 +1,31 @@
|
||||
This software is in part copyrighted by the various organizations and
|
||||
individuals listed below. Permission to use it is set out in the file
|
||||
LICENSE that accompanies the software.
|
||||
|
||||
In no event shall any copyright holder be liable to any party for
|
||||
direct, indirect, special, incidental, or consequential damages arising
|
||||
out of the use of this software, its documentation, or any derivatives
|
||||
thereof, even if they have been advised of the possibility of such
|
||||
damage.
|
||||
|
||||
The copyright holders specifically disclaim any warranties, including,
|
||||
but not limited to, the implied warranties of merchantability, fitness
|
||||
for a particular purpose, and non-infringement. This software is
|
||||
provided on an "as is" basis, and the copyright holders have no
|
||||
obligation either collectively or individually to provide maintenance,
|
||||
support, updates, enhancements, or modifications.
|
||||
|
||||
Copyright (c) 2006 - 2015 All rights reserved
|
||||
|
||||
Martin R. Kraimer
|
||||
The University of Chicago, as Operator of Argonne National Laboratory.
|
||||
Deutsches Elektronen-Synchroton, Member of the Helmholtz Association,
|
||||
(DESY), HAMBURG, GERMANY,
|
||||
BERLINER SPEICHERRING GESELLSCHAFT FUER SYNCHROTRONSTRAHLUNG M.B.H.
|
||||
(BESSY), BERLIN, GERMANY.
|
||||
COSYLAB (Control System Laboratory), Ljubljana, Slovenia.
|
||||
Brookhaven Science Associates, as Operator of Brookhaven
|
||||
National Laboratory.
|
||||
Diamond Light Source Ltd., Didcot, United Kingdom.
|
||||
|
||||
|
||||
114
LICENSE
Normal file
114
LICENSE
Normal file
@@ -0,0 +1,114 @@
|
||||
|
||||
Copyright (c) 2006-2015 Martin R. Kraimer
|
||||
Copyright (c) 2006 The University of Chicago, as Operator of Argonne
|
||||
National Laboratory.
|
||||
Copyright (c) 2006 Deutsches Elektronen-Synchrotron,
|
||||
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
|
||||
Copyright (c) 2007-2015 Control System Laboratory,
|
||||
(COSYLAB) Ljubljana Slovenia
|
||||
Copyright (c) 2010-2015 Brookhaven Science Associates, as Operator of Brookhaven
|
||||
National Laboratory
|
||||
Copyright (c) 2011-2015 Diamond Light Source Limited,
|
||||
(DLS) Didcot, United Kingdom
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
This software is in part copyrighted by the University of Chicago (UofC)
|
||||
|
||||
In no event shall UofC be liable to any party for direct, indirect,
|
||||
special, incidental, or consequential damages arising out of the use of
|
||||
this software, its documentation, or any derivatives thereof, even if
|
||||
UofC has been advised of the possibility of such damage.
|
||||
|
||||
UofC specifically disclaims any warranties, including, but not limited
|
||||
to, the implied warranties of merchantability, fitness for a particular
|
||||
purpose, and non-infringement. This software is provided on an "as is"
|
||||
basis, and UofC has no obligation to provide maintenance, support,
|
||||
updates, enhancements, or modifications.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
This software is in part copyrighted by the BERLINER SPEICHERRING
|
||||
GESELLSCHAFT FUER SYNCHROTRONSTRAHLUNG M.B.H. (BESSY), BERLIN, GERMANY.
|
||||
|
||||
In no event shall BESSY be liable to any party for direct, indirect,
|
||||
special, incidental, or consequential damages arising out of the use of
|
||||
this software, its documentation, or any derivatives thereof, even if
|
||||
BESSY has been advised of the possibility of such damage.
|
||||
|
||||
BESSY specifically disclaims any warranties, including, but not limited
|
||||
to, the implied warranties of merchantability, fitness for a particular
|
||||
purpose, and non-infringement. This software is provided on an "as is"
|
||||
basis, and BESSY has no obligation to provide maintenance, support,
|
||||
updates, enhancements, or modifications.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
This software is in part copyrighted by the Deutsches Elektronen-Synchroton,
|
||||
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
|
||||
|
||||
In no event shall DESY be liable to any party for direct, indirect,
|
||||
special, incidental, or consequential damages arising out of the use of
|
||||
this software, its documentation, or any derivatives thereof, even if
|
||||
DESY has been advised of the possibility of such damage.
|
||||
|
||||
DESY specifically disclaims any warranties, including, but not limited
|
||||
to, the implied warranties of merchantability, fitness for a particular
|
||||
purpose, and non-infringement. This software is provided on an "as is"
|
||||
basis, and DESY has no obligation to provide maintenance, support,
|
||||
updates, enhancements, or modifications.
|
||||
|
||||
______________________________________________________________________
|
||||
|
||||
This software is in part copyrighted by the Brookhaven
|
||||
National Laboratory (BNL).
|
||||
|
||||
In no event shall BNL be liable to any party for direct, indirect,
|
||||
special, incidental, or consequential damages arising out of the use of
|
||||
this software, its documentation, or any derivatives thereof, even if
|
||||
BNL has been advised of the possibility of such damage.
|
||||
|
||||
BNL specifically disclaims any warranties, including, but not limited
|
||||
to, the implied warranties of merchantability, fitness for a particular
|
||||
purpose, and non-infringement. This software is provided on an "as is"
|
||||
basis, and BNL has no obligation to provide maintenance, support,
|
||||
updates, enhancements, or modifications.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
This software is in part copyrighted by Diamond Light Source Limited (DLS)
|
||||
|
||||
In no event shall DLS be liable to any party for direct, indirect,
|
||||
special, incidental, or consequential damages arising out of the use of
|
||||
this software, its documentation, or any derivatives thereof, even if
|
||||
DLS has been advised of the possibility of such damage.
|
||||
|
||||
DLS specifically disclaims any warranties, including, but not limited
|
||||
to, the implied warranties of merchantability, fitness for a particular
|
||||
purpose, and non-infringement. This software is provided on an "as is"
|
||||
basis, and DLS has no obligation to provide maintenance, support,
|
||||
updates, enhancements, or modifications.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
@@ -32,6 +32,6 @@ endif
|
||||
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
|
||||
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
|
||||
|
||||
-include $(TOP)/../CONFIG_SITE.local
|
||||
-include $(TOP)/configure/CONFIG_SITE.local
|
||||
-include $(TOP)/../CONFIG.local
|
||||
|
||||
|
||||
@@ -28,4 +28,5 @@ TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
||||
#CAPFAST_TEMPLATES=
|
||||
#SCH2EDIF_PATH=
|
||||
|
||||
-include $(TOP)/../RELEASE.local
|
||||
-include $(TOP)/configure/RELEASE.local
|
||||
|
||||
4
documentation/RELEASE_NOTES.html
Normal file
4
documentation/RELEASE_NOTES.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<h1>Release 4.0 IN DEVELOPMENT</h1>
|
||||
<p>This is the first release of normativeTypesCPP that is part of an official
|
||||
EPICS V4 release.
|
||||
It is a major rewrite of the previous versions of normativeTypesCPP.</p>
|
||||
7
documentation/RELEASE_NOTES.md
Normal file
7
documentation/RELEASE_NOTES.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Release 4.0 IN DEVELOPMENT
|
||||
===========
|
||||
|
||||
This is the first release of normativeTypesCPP that is part of an official
|
||||
EPICS V4 release.
|
||||
It is a major rewrite of the previous versions of normativeTypesCPP.
|
||||
|
||||
22
documentation/TODO.html
Normal file
22
documentation/TODO.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<h1>TODO</h1>
|
||||
<h2>NTScalarArray</h2>
|
||||
<p>NTScalarArrayBuilder::arrayValue</p>
|
||||
<p>Should this be:</p>
|
||||
<p>NTScalarArrayBuilder::value</p>
|
||||
<p>This makes NTScalarArray consistent with other NTTypes.</p>
|
||||
<h2>NTNameValue</h2>
|
||||
<p>This does not have a value field like all the other NTTypes.
|
||||
Perhaps instead of</p>
|
||||
<pre><code>NTNameValue
|
||||
string[] name
|
||||
string[] value
|
||||
</code></pre>
|
||||
<p>It should be</p>
|
||||
<pre><code>NTNameValue
|
||||
value
|
||||
string[] name
|
||||
string[] value
|
||||
</code></pre>
|
||||
<h2>NTTable</h2>
|
||||
<p>Should lables be label?
|
||||
Compare with name,value from NTNameValue.</p>
|
||||
37
documentation/TODO.md
Normal file
37
documentation/TODO.md
Normal file
@@ -0,0 +1,37 @@
|
||||
TODO
|
||||
===========
|
||||
|
||||
NTScalarArray
|
||||
------------
|
||||
|
||||
NTScalarArrayBuilder::arrayValue
|
||||
|
||||
Should this be:
|
||||
|
||||
NTScalarArrayBuilder::value
|
||||
|
||||
This makes NTScalarArray consistent with other NTTypes.
|
||||
|
||||
|
||||
NTNameValue
|
||||
------------
|
||||
|
||||
This does not have a value field like all the other NTTypes.
|
||||
Perhaps instead of
|
||||
|
||||
NTNameValue
|
||||
string[] name
|
||||
string[] value
|
||||
|
||||
It should be
|
||||
|
||||
NTNameValue
|
||||
value
|
||||
string[] name
|
||||
string[] value
|
||||
|
||||
NTTable
|
||||
----------
|
||||
|
||||
Should lables be label?
|
||||
Compare with name,value from NTNameValue.
|
||||
File diff suppressed because it is too large
Load Diff
289
documentation/ntCPP_20140723.html
Normal file
289
documentation/ntCPP_20140723.html
Normal file
@@ -0,0 +1,289 @@
|
||||
<?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 pvDataCPP</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 pvDataCPP</h1>
|
||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
||||
|
||||
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 23-July-2014</h2>
|
||||
|
||||
<dl>
|
||||
<dt>Latest version:</dt>
|
||||
<dd><a
|
||||
href="ntCPP.html">ntCPP.html</a>
|
||||
</dd>
|
||||
<dt>This version:</dt>
|
||||
<dd><a
|
||||
href="ntCPP_20140723.html">ntCPP_20140723.html</a>
|
||||
</dd>
|
||||
<dt>Previous version:</dt>
|
||||
<dd>None</dd>
|
||||
<dt>Editors:</dt>
|
||||
<dd>Marty Kraimer, BNL</dd>
|
||||
<dd>Michael Davidsaver, BNL</dd>
|
||||
<dd>Matej Sekoranja, CosyLab</dd>
|
||||
</dl>
|
||||
|
||||
<p class="copyright">This product is made available subject to acceptance of the <a
|
||||
href="http://epics-pvdata.sourceforge.net/LICENSE.html">EPICS open source
|
||||
license.</a></p>
|
||||
<hr />
|
||||
</div>
|
||||
<h2 class="nocount">Abstract</h2>
|
||||
|
||||
<p>EPICS Version 4 provides efficient
|
||||
storage, access, and communication, of memory resident structured data.
|
||||
pvData is the storage compoment.
|
||||
pvDataCPP is the C++ implementation of pvData.
|
||||
It is one part of the set of related products in the EPICS
|
||||
V4 control system programming environment:<br />
|
||||
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
|
||||
</p>
|
||||
|
||||
|
||||
<h2 class="nocount">Status of this Document</h2>
|
||||
|
||||
<p>For now this is a working copy so it is not the same as "This version" shown above.</p>
|
||||
|
||||
<p>This is the 23-July-2014 version of the C++ implementation of pvData.
|
||||
</p>
|
||||
|
||||
<p>RELEASE_NOTES.md provides changes since the last release.
|
||||
TODO.md describes things to do before the next release.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<div id="toc">
|
||||
<h2 class="nocount" style="page-break-before: always">Table of Contents</h2>
|
||||
</div>
|
||||
<div id="contents" class="contents">
|
||||
|
||||
<body>
|
||||
<h1 style="text-align: center">EPICS normative type C++ implementation
|
||||
</h1>
|
||||
|
||||
<h2 class="nocount" id="L50">Draft, 4-Nov-2012</h2>
|
||||
<dl>
|
||||
<dt>This version:</dt>
|
||||
<dd><a href="http://epics-pvdata.hg.sourceforge.net/hgweb/epics-pvdata/normativeTypesCPP/raw-file/tip/documentation/ntCPP.html">ntCPP.html</a></dd>
|
||||
<dt>Editors:</dt>
|
||||
<dd>Matej Sekoranja, CosyLab<br>
|
||||
Marty Kraimer, BNL
|
||||
</dd>
|
||||
</dl>
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
<p>This section describes the C++ implemmentation of normative types. Two (2) helper classes are implemented,
|
||||
ntNameValue and NTTable respectively. </p>
|
||||
|
||||
<h3>Normative Type Fields.</h3>
|
||||
|
||||
<p>These are helper classes for creating standard fields for normative types.
|
||||
There is a single instance of this class, which is obtained via NTField::get().
|
||||
</p>
|
||||
<pre>class NTField: NoDefaultMethods {
|
||||
public:
|
||||
static NTFieldPtr get();
|
||||
~NTField() {}
|
||||
|
||||
PVStructurePtr createEnumerated(StringArray const & choices);
|
||||
PVStructurePtr createTimeStamp();
|
||||
PVStructurePtr createAlarm();
|
||||
PVStructurePtr createDisplay();
|
||||
PVStructurePtr createAlarmLimit();
|
||||
PVStructurePtr createControl();
|
||||
|
||||
PVStructureArrayPtr createEnumeratedArray();
|
||||
PVStructureArrayPtr createTimeStampArray();
|
||||
PVStructureArrayPtr createAlarmArray();
|
||||
};</pre>
|
||||
|
||||
<p>where</p>
|
||||
<dl>
|
||||
<dt>createEnumerated</dt>
|
||||
<dd>Create an introspection interface for an enumerated structure.</dd>
|
||||
<dt>createTimeStamp</dt>
|
||||
<dd>Create an interspection interface for a timeStamp structure.</dd>
|
||||
<dt>createAlarm</dt>
|
||||
<dd>Create an interspection interface for an alarm structure.</dd>
|
||||
<dt>createDisplay</dt>
|
||||
<dd>Create an introsepecion interface for a display structure.</dd>
|
||||
<dt>createAlarmLimit</dt>
|
||||
<dd>Create an introspection interface for an alarm limit structure.</dd>
|
||||
<dt>createControl</dt>
|
||||
<dd>Create an introspection interface for a control structure.</dd>
|
||||
<dt>createEnumeratedArray</dt>
|
||||
<dd>Create an introspection interface for an structureArray of enumerated
|
||||
structures.</dd>
|
||||
<dt>createTimeStampArray</dt>
|
||||
<dd>Create an introspection interface for an structureArray of timeStamp
|
||||
structures.</dd>
|
||||
<dt>createAlarmArray</dt>
|
||||
<dd>Create an introspection interface for an structureArray of alarm
|
||||
structures.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>NTNameValue</h3>
|
||||
|
||||
<p>These are helper classes for NTNameValue</p>
|
||||
<pre>class NTNameValue : private NoDefaultMethods
|
||||
{
|
||||
public:
|
||||
static bool isNTNameValue(PVStructurePtr const & pvStructure);
|
||||
static NTNameValuePtr create(
|
||||
bool hasFunction,bool hasTimeStamp, bool hasAlarm);
|
||||
static NTNameValuePtr create(
|
||||
PVStructurePtr const & pvStructure);
|
||||
~NTNameValue();
|
||||
PVStringPtr getFunction();
|
||||
void attachTimeStamp(PVTimeStamp &pvTimeStamp);
|
||||
void attachAlarm(PVAlarm &pvAlarm);
|
||||
PVStructurePtr getPVStructure();
|
||||
PVStructurePtr getTimeStamp();
|
||||
PVStructurePtr getAlarm();
|
||||
PVStringArrayPtr getNames();
|
||||
PVStringArrayPtr getValues();
|
||||
};</pre>
|
||||
|
||||
<p>where</p>
|
||||
<dl>
|
||||
<dt>isNTNameValue</dt>
|
||||
<dd>Is the structure a NTNameValue structure?</dd>
|
||||
<dt>create</dt>
|
||||
<dd>Create an NTNameValue that has the associated fields.</dd>
|
||||
<dt>~NTNameValue</dt>
|
||||
<dd>The destructor.</dd>
|
||||
<dt>getFunction</dt>
|
||||
<dd>Get the function field. This can be null.</dd>
|
||||
<dt>attachTimeStamp</dt>
|
||||
<dd>The timeStamp field of the NTNameValue is atttached to the
|
||||
pvTimeStamp.</dd>
|
||||
<dt>attachAlarm</dt>
|
||||
<dd>The alarm field of the NTNameValue is atttached to the alarm.</dd>
|
||||
<dt>getPVStructure</dt>
|
||||
<dd>Get the pvStructure that this NTNameValue contains.</dd>
|
||||
<dt>getTimeStamp</dt>
|
||||
<dd>Get the timeStamp field.</dd>
|
||||
<dt>getAlarm</dt>
|
||||
<dd>Get the alarm field.</dd>
|
||||
<dt>getNames</dt>
|
||||
<dd>Get the names field.</dd>
|
||||
<dt>getValues</dt>
|
||||
<dd>Get the values field.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>NTTable</h3>
|
||||
|
||||
<p>These are helper classes for NTTable</p>
|
||||
<pre>class NTTable: private NoDefaultMethods
|
||||
{
|
||||
public:
|
||||
static bool isNTTable(PVStructurePtr const & pvStructure);
|
||||
static PVStructure::shared_pointer create(
|
||||
bool hasFunction,bool hasTimeStamp, bool hasAlarm,
|
||||
int numberValues,
|
||||
FieldConstPtrArray valueFields);
|
||||
static NTTablePtr create(
|
||||
bool hasFunction,bool hasTimeStamp, bool hasAlarm,
|
||||
StringArray const & valueNames,
|
||||
FieldConstPtrArray const &valueFields);
|
||||
static NTTablePtr clone(PVStructurePtr const &);
|
||||
~NTTable();
|
||||
PVStringPtr getFunction();
|
||||
void attachTimeStamp(PVTimeStamp &pvTimeStamp);
|
||||
void attachAlarm(PVAlarm &pvAlarm);
|
||||
PVStructurePtr getPVStructure();
|
||||
PVStructurePtr getTimeStamp();
|
||||
PVStructurePtr getAlarm();
|
||||
PVStringArrayPtr getLabel();
|
||||
size_t getNumberValues();
|
||||
FieldConstPtr getField(int index);
|
||||
PVFieldPtr getPVField(int index);
|
||||
};</pre>
|
||||
|
||||
<p>where</p>
|
||||
<dl>
|
||||
<dt>isNTTable</dt>
|
||||
<dd>y</dd>
|
||||
<dt>create</dt>
|
||||
<dd>Create an NTTable that has the associated fields.</dd>
|
||||
<dt>~NTTable</dt>
|
||||
<dd>The destructor.</dd>
|
||||
<dt>getFunction</dt>
|
||||
<dd>Get the function field. This can be null.</dd>
|
||||
<dt>attachTimeStamp</dt>
|
||||
<dd>The timeStamp field of the NTTable is atttached to the pvTimeStamp.</dd>
|
||||
<dt>attachAlarm</dt>
|
||||
<dd>The alarm field of the NTTable is atttached to the alarm.</dd>
|
||||
<dt>getPVStructure</dt>
|
||||
<dd>Get the pvStructure that this NTTable contains.</dd>
|
||||
<dt>getTimeStamp</dt>
|
||||
<dd>Get the timeStamp field.</dd>
|
||||
<dt>getAlarm</dt>
|
||||
<dd>Get the alarm field.</dd>
|
||||
<dt>getLabel</dt>
|
||||
<dd>Get the label field.</dd>
|
||||
<dt>getNumberValues</dt>
|
||||
<dd>Get the number of value fields.</dd>
|
||||
<dt>getField</dt>
|
||||
<dd>Get the introspection interface for the specified field.</dd>
|
||||
<dt>getPVField</dt>
|
||||
<dd>Get the data field for the specified field.</dd>
|
||||
</dl>
|
||||
|
||||
<h2>MTMultiChannel</h2>
|
||||
<pre>
|
||||
structure NTMultiChannel
|
||||
union_t[] value
|
||||
string[] channelName
|
||||
time_t timeStamp :opt // time when data collected
|
||||
alarm_t alarm :opt // alarm associated with data collection
|
||||
int[] severity :opt // alarm severity for each value
|
||||
int[] status :opt // alarm status for each value
|
||||
string[] message :opt // alarm message for each value
|
||||
long[] secondsPastEpoch :opt // seconds for each value.
|
||||
int[] nanoseconds :opt // nanoseconds for each value
|
||||
string descriptor :opt // descriptor data
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1473
documentation/ntCPP_20140919.html
Normal file
1473
documentation/ntCPP_20140919.html
Normal file
File diff suppressed because it is too large
Load Diff
1490
documentation/ntCPP_20141009.html
Normal file
1490
documentation/ntCPP_20141009.html
Normal file
File diff suppressed because it is too large
Load Diff
67
jenkins/cloudbees_build
Normal file
67
jenkins/cloudbees_build
Normal file
@@ -0,0 +1,67 @@
|
||||
# normativeTypes C++ implementation
|
||||
# Jenkins @ Cloudbees build script
|
||||
#
|
||||
# Jenkins invokes scripts with the "-ex" option. So the build is considered a failure
|
||||
# if any of the commands exits with a non-zero exit code.
|
||||
#
|
||||
# Author: Ralph Lange <ralph.lange@gmx.de>
|
||||
# Copyright (C) 2013 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
|
||||
# Copyright (C) 2014-2015 ITER Organization.
|
||||
# All rights reserved. Use is subject to license terms.
|
||||
|
||||
###########################################
|
||||
# Determine EPICS Base version
|
||||
|
||||
DEFAULT_BASE=3.14.12.5
|
||||
|
||||
BASE=${1:-${DEFAULT_BASE}}
|
||||
USE_MB=${2:-"MB_NO"}
|
||||
|
||||
# Dependent module branches (empty = master)
|
||||
PVCOMMON_BRANCH="Release-4.1-"
|
||||
PVDATA_BRANCH="Release-5.0-"
|
||||
|
||||
###########################################
|
||||
# Fetch and unpack dependencies
|
||||
|
||||
export STUFF=/tmp/stuff
|
||||
|
||||
rm -fr ${STUFF}
|
||||
mkdir -p ${STUFF}
|
||||
cd ${STUFF}
|
||||
|
||||
wget -nv https://openepics.ci.cloudbees.com/job/Base-${BASE}_Build/lastSuccessfulBuild/artifact/base-${BASE}.CB-dist.tar.gz
|
||||
wget -nv https://openepics.ci.cloudbees.com/job/pvDataCPP_${PVDATA_BRANCH}Build/BASE=${BASE},USE_MB=MB_NO/lastSuccessfulBuild/artifact/pvData.CB-dist.tar.gz
|
||||
tar -xzf base-${BASE}.CB-dist.tar.gz
|
||||
tar -xzf pvData.CB-dist.tar.gz
|
||||
|
||||
if [ "${USE_MB}" = "MB_YES" ]; then
|
||||
wget -nv https://openepics.ci.cloudbees.com/job/pvCommonCPP_${PVCOMMON_BRANCH}Build/BASE=${BASE},USE_MB=MB_YES/lastSuccessfulBuild/artifact/pvCommon.CB-dist.tar.gz
|
||||
tar -xzf pvCommon.CB-dist.tar.gz
|
||||
fi
|
||||
|
||||
###########################################
|
||||
# Build
|
||||
|
||||
cd ${WORKSPACE}
|
||||
|
||||
export EPICS_BASE=${STUFF}
|
||||
export EPICS_HOST_ARCH=$(${EPICS_BASE}/startup/EpicsHostArch)
|
||||
export LD_LIBRARY_PATH=${EPICS_BASE}/lib/${EPICS_HOST_ARCH}
|
||||
export PATH=${STUFF}/bin:${PATH}
|
||||
|
||||
cat > configure/RELEASE.local << EOF
|
||||
EPICS_BASE=${EPICS_BASE}
|
||||
EOF
|
||||
|
||||
make distclean all
|
||||
|
||||
###########################################
|
||||
# Test
|
||||
|
||||
make runtests
|
||||
|
||||
###########################################
|
||||
# Create distribution
|
||||
|
||||
tar --exclude=test* -czf normativeTypes.CB-dist.tar.gz lib include
|
||||
51
jenkins/cloudbees_doc
Normal file
51
jenkins/cloudbees_doc
Normal file
@@ -0,0 +1,51 @@
|
||||
# normativeTypes C++ implementation
|
||||
# Jenkins @ Cloudbees documentation generation and deployment
|
||||
#
|
||||
# Jenkins invokes scripts with the "-ex" option. So the build is considered a failure
|
||||
# if any of the commands exits with a non-zero exit code.
|
||||
#
|
||||
# Author: Ralph Lange <ralph.lange@gmx.de>
|
||||
# Copyright (C) 2013 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
|
||||
# Copyright (C) 2014-2015 ITER Organization.
|
||||
# All rights reserved. Use is subject to license terms.
|
||||
|
||||
###########################################
|
||||
# Set EPICS Base version and upload target
|
||||
|
||||
BASE=3.15.2
|
||||
PUBLISH=${1:-DONT}
|
||||
|
||||
###########################################
|
||||
# Fetch and unpack dependencies
|
||||
|
||||
export STUFF=/tmp/stuff
|
||||
|
||||
rm -fr ${STUFF}
|
||||
mkdir -p ${STUFF}
|
||||
cd ${STUFF}
|
||||
|
||||
wget -nv https://openepics.ci.cloudbees.com/job/Doxygen-1.8.3_Build/lastSuccessfulBuild/artifact/doxygen-1.8.3.CB-dist.tar.gz
|
||||
tar -xzf doxygen-1.8.3.CB-dist.tar.gz
|
||||
|
||||
###########################################
|
||||
# Generate
|
||||
|
||||
cd ${WORKSPACE}
|
||||
|
||||
wget -nv https://openepics.ci.cloudbees.com/job/normativeTypesCPP_Build/BASE=${BASE},USE_MB=MB_NO/lastSuccessfulBuild/artifact/normativeTypes.CB-dist.tar.gz
|
||||
tar -xzf normativeTypes.CB-dist.tar.gz
|
||||
|
||||
export PATH=${STUFF}/bin:${PATH}
|
||||
|
||||
doxygen
|
||||
|
||||
###########################################
|
||||
# Publish
|
||||
|
||||
if [ "${PUBLISH}" != "DONT" ]; then
|
||||
# Upload explicit dummy to ensure target directory exists
|
||||
echo "Created by CloudBees Jenkins upload job. Should be deleted as part of the job." > DUMMY
|
||||
rsync -q -e ssh DUMMY epics-jenkins@web.sourceforge.net:/home/project-web/epics-pvdata/htdocs/docbuild/normativeTypesCPP/${PUBLISH}/DUMMY
|
||||
|
||||
rsync -aqP --delete -e ssh documentation epics-jenkins@web.sourceforge.net:/home/project-web/epics-pvdata/htdocs/docbuild/normativeTypesCPP/${PUBLISH}/
|
||||
fi
|
||||
36
src/Makefile
36
src/Makefile
@@ -1,20 +1,52 @@
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
SRC = $(TOP)/src/
|
||||
SRC = $(TOP)/src
|
||||
|
||||
SRC_DIRS += $(SRC)/nt
|
||||
|
||||
INC += nt.h
|
||||
INC += ntutils.h
|
||||
INC += ntid.h
|
||||
INC += ntfield.h
|
||||
INC += ntscalar.h
|
||||
INC += ntscalarArray.h
|
||||
INC += ntnameValue.h
|
||||
INC += nttable.h
|
||||
INC += ntmultiChannel.h
|
||||
INC += ntscalarMultiChannel.h
|
||||
INC += ntndarray.h
|
||||
INC += ntmatrix.h
|
||||
INC += ntenum.h
|
||||
INC += ntunion.h
|
||||
INC += ntaggregate.h
|
||||
INC += ntattribute.h
|
||||
INC += ntcontinuum.h
|
||||
INC += nthistogram.h
|
||||
INC += nturi.h
|
||||
INC += ntndarrayAttribute.h
|
||||
|
||||
LIBSRCS += ntutils.cpp
|
||||
LIBSRCS += ntid.cpp
|
||||
LIBSRCS += ntfield.cpp
|
||||
LIBSRCS += ntscalar.cpp
|
||||
LIBSRCS += ntscalarArray.cpp
|
||||
LIBSRCS += ntnameValue.cpp
|
||||
LIBSRCS += nttable.cpp
|
||||
LIBSRCS += ntmultiChannel.cpp
|
||||
LIBSRCS += ntscalarMultiChannel.cpp
|
||||
LIBSRCS += ntndarray.cpp
|
||||
LIBSRCS += ntmatrix.cpp
|
||||
LIBSRCS += ntenum.cpp
|
||||
LIBSRCS += ntunion.cpp
|
||||
LIBSRCS += ntaggregate.cpp
|
||||
LIBSRCS += ntattribute.cpp
|
||||
LIBSRCS += ntcontinuum.cpp
|
||||
LIBSRCS += nthistogram.cpp
|
||||
LIBSRCS += nturi.cpp
|
||||
LIBSRCS += ntndarrayAttribute.cpp
|
||||
|
||||
LIBRARY=nt
|
||||
LIBRARY = nt
|
||||
|
||||
nt_LIBS += pvData Com
|
||||
|
||||
|
||||
25
src/nt/nt.h
25
src/nt/nt.h
@@ -1,15 +1,38 @@
|
||||
/* nt.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NT_H
|
||||
#define NT_H
|
||||
|
||||
/*
|
||||
* Include all the normative types here.
|
||||
*/
|
||||
#include <pv/ntfield.h>
|
||||
#include <pv/ntscalar.h>
|
||||
#include <pv/ntscalarArray.h>
|
||||
#include <pv/ntnameValue.h>
|
||||
#include <pv/nttable.h>
|
||||
#include <pv/ntndarray.h>
|
||||
#include <pv/ntmultiChannel.h>
|
||||
#include <pv/ntscalarMultiChannel.h>
|
||||
#include <pv/ntmatrix.h>
|
||||
#include <pv/ntenum.h>
|
||||
#include <pv/ntunion.h>
|
||||
#include <pv/ntaggregate.h>
|
||||
#include <pv/ntattribute.h>
|
||||
#include <pv/ntcontinuum.h>
|
||||
#include <pv/nthistogram.h>
|
||||
#include <pv/nturi.h>
|
||||
#include <pv/ntndarrayAttribute.h>
|
||||
|
||||
#endif /* NT_H */
|
||||
|
||||
/** @page Overview Documentation
|
||||
*
|
||||
* <a href = "ntCPP.html">ntCPP.html</a>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
376
src/nt/ntaggregate.cpp
Normal file
376
src/nt/ntaggregate.cpp
Normal file
@@ -0,0 +1,376 @@
|
||||
/* ntaggregate.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntaggregate.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
StructureConstPtr NTAggregateBuilder::createStructure()
|
||||
{
|
||||
FieldBuilderPtr builder =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId(NTAggregate::URI)->
|
||||
add("value", pvDouble)->
|
||||
add("N", pvLong);
|
||||
|
||||
if (dispersion)
|
||||
builder->add("dispersion", pvDouble);
|
||||
|
||||
if (first)
|
||||
builder->add("first", pvDouble);
|
||||
|
||||
if (firstTimeStamp)
|
||||
builder->add("firstTimeStamp", ntField->createTimeStamp());
|
||||
|
||||
if (last)
|
||||
builder->add("last" , pvDouble);
|
||||
|
||||
if (lastTimeStamp)
|
||||
builder->add("lastTimeStamp", ntField->createTimeStamp());
|
||||
|
||||
if (max)
|
||||
builder->add("max", pvDouble);
|
||||
|
||||
if (min)
|
||||
builder->add("min", pvDouble);
|
||||
|
||||
if (descriptor)
|
||||
builder->add("descriptor", pvString);
|
||||
|
||||
if (alarm)
|
||||
builder->add("alarm", ntField->createAlarm());
|
||||
|
||||
if (timeStamp)
|
||||
builder->add("timeStamp", ntField->createTimeStamp());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTAggregateBuilder::shared_pointer NTAggregateBuilder::addDispersion()
|
||||
{
|
||||
dispersion = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTAggregateBuilder::shared_pointer NTAggregateBuilder::addFirst()
|
||||
{
|
||||
first = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTAggregateBuilder::shared_pointer NTAggregateBuilder::addFirstTimeStamp()
|
||||
{
|
||||
firstTimeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTAggregateBuilder::shared_pointer NTAggregateBuilder::addLast()
|
||||
{
|
||||
last = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTAggregateBuilder::shared_pointer NTAggregateBuilder::addLastTimeStamp()
|
||||
{
|
||||
lastTimeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTAggregateBuilder::shared_pointer NTAggregateBuilder::addMax()
|
||||
{
|
||||
max = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTAggregateBuilder::shared_pointer NTAggregateBuilder::addMin()
|
||||
{
|
||||
min = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTAggregateBuilder::shared_pointer NTAggregateBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTAggregateBuilder::shared_pointer NTAggregateBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTAggregateBuilder::shared_pointer NTAggregateBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
PVStructurePtr NTAggregateBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTAggregatePtr NTAggregateBuilder::create()
|
||||
{
|
||||
return NTAggregatePtr(new NTAggregate(createPVStructure()));
|
||||
}
|
||||
|
||||
NTAggregateBuilder::NTAggregateBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTAggregateBuilder::reset()
|
||||
{
|
||||
dispersion = false;
|
||||
first = false;
|
||||
firstTimeStamp = false;
|
||||
last = false;
|
||||
lastTimeStamp = false;
|
||||
max = false;
|
||||
min = false;
|
||||
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
}
|
||||
|
||||
NTAggregateBuilder::shared_pointer NTAggregateBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const std::string NTAggregate::URI("epics:nt/NTAggregate:1.0");
|
||||
|
||||
NTAggregate::shared_pointer NTAggregate::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTAggregate::shared_pointer NTAggregate::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTAggregate(structure));
|
||||
}
|
||||
|
||||
bool NTAggregate::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTAggregate::isCompatible(StructureConstPtr const &structure)
|
||||
{
|
||||
if (structure.get() == 0) return false;
|
||||
|
||||
ScalarConstPtr valueField = structure->getField<Scalar>("value");
|
||||
if (valueField.get() == 0 || valueField->getScalarType() != pvDouble)
|
||||
return false;
|
||||
|
||||
ScalarConstPtr nField = structure->getField<Scalar>("N");
|
||||
if (nField.get() == 0 || nField->getScalarType() != pvLong)
|
||||
return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("dispersion");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr dispersionField = structure->getField<Scalar>("dispersion");
|
||||
if (!dispersionField.get() || dispersionField->getScalarType() != pvDouble)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("first");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr firstField = structure->getField<Scalar>("first");
|
||||
if (!firstField.get() || firstField->getScalarType() != pvDouble)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("firstTimeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("last");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr lastField = structure->getField<Scalar>("last");
|
||||
if (!lastField.get() || lastField->getScalarType() != pvDouble)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("lastTimeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("max");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr maxField = structure->getField<Scalar>("max");
|
||||
if (!maxField.get() || maxField->getScalarType() != pvDouble)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("min");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr minField = structure->getField<Scalar>("min");
|
||||
if (!minField.get() || minField->getScalarType() != pvDouble)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NTAggregate::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(!pvStructure) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTAggregate::isValid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NTAggregateBuilderPtr NTAggregate::createBuilder()
|
||||
{
|
||||
return NTAggregateBuilderPtr(new detail::NTAggregateBuilder());
|
||||
}
|
||||
|
||||
bool NTAggregate::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTAggregate::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStructurePtr NTAggregate::getPVStructure() const
|
||||
{
|
||||
return pvNTAggregate;
|
||||
}
|
||||
|
||||
PVStringPtr NTAggregate::getDescriptor() const
|
||||
{
|
||||
return pvNTAggregate->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
PVStructurePtr NTAggregate::getTimeStamp() const
|
||||
{
|
||||
return pvNTAggregate->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVStructurePtr NTAggregate::getAlarm() const
|
||||
{
|
||||
return pvNTAggregate->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
PVDoublePtr NTAggregate::getValue() const
|
||||
{
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
PVLongPtr NTAggregate::getN() const
|
||||
{
|
||||
return pvNTAggregate->getSubField<PVLong>("N");
|
||||
}
|
||||
|
||||
PVDoublePtr NTAggregate::getDispersion() const
|
||||
{
|
||||
return pvNTAggregate->getSubField<PVDouble>("dispersion");
|
||||
}
|
||||
|
||||
PVDoublePtr NTAggregate::getFirst() const
|
||||
{
|
||||
return pvNTAggregate->getSubField<PVDouble>("first");
|
||||
}
|
||||
|
||||
PVStructurePtr NTAggregate::getFirstTimeStamp() const
|
||||
{
|
||||
return pvNTAggregate->getSubField<PVStructure>("firstTimeStamp");
|
||||
}
|
||||
|
||||
PVDoublePtr NTAggregate::getLast() const
|
||||
{
|
||||
return pvNTAggregate->getSubField<PVDouble>("last");
|
||||
}
|
||||
|
||||
PVStructurePtr NTAggregate::getLastTimeStamp() const
|
||||
{
|
||||
return pvNTAggregate->getSubField<PVStructure>("lastTimeStamp");
|
||||
}
|
||||
|
||||
PVDoublePtr NTAggregate::getMax() const
|
||||
{
|
||||
return pvNTAggregate->getSubField<PVDouble>("max");
|
||||
}
|
||||
|
||||
PVDoublePtr NTAggregate::getMin() const
|
||||
{
|
||||
return pvNTAggregate->getSubField<PVDouble>("min");
|
||||
}
|
||||
|
||||
NTAggregate::NTAggregate(PVStructurePtr const & pvStructure) :
|
||||
pvNTAggregate(pvStructure), pvValue(pvNTAggregate->getSubField<PVDouble>("value"))
|
||||
{}
|
||||
|
||||
|
||||
}}
|
||||
345
src/nt/ntaggregate.h
Normal file
345
src/nt/ntaggregate.h
Normal file
@@ -0,0 +1,345 @@
|
||||
/* ntaggregate.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTAGGREGATE_H
|
||||
#define NTAGGREGATE_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntaggregateEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#ifdef ntaggregateEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntaggregateEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTAggregate;
|
||||
typedef std::tr1::shared_ptr<NTAggregate> NTAggregatePtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTAggregate.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTAggregateBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTAggregateBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTAggregateBuilder);
|
||||
|
||||
/**
|
||||
* Add dispersion field to the NTAggregate.
|
||||
* @return this instance of <b>NTAggregateBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDispersion();
|
||||
|
||||
/**
|
||||
* Add first field to the NTAggregate.
|
||||
* @return this instance of <b>NTAggregateBuilder</b>.
|
||||
*/
|
||||
shared_pointer addFirst();
|
||||
|
||||
/**
|
||||
* Add firstTimeStamp field to the NTAggregate.
|
||||
* @return this instance of <b>NTAggregateBuilder</b>.
|
||||
*/
|
||||
shared_pointer addFirstTimeStamp();
|
||||
|
||||
/**
|
||||
* Add last field to the NTAggregate.
|
||||
* @return this instance of <b>NTAggregateBuilder</b>.
|
||||
*/
|
||||
shared_pointer addLast();
|
||||
|
||||
/**
|
||||
* Add lastTimeStamp field to the NTAggregate.
|
||||
* @return this instance of <b>NTAggregateBuilder</b>.
|
||||
*/
|
||||
shared_pointer addLastTimeStamp();
|
||||
|
||||
/**
|
||||
* Add max field to the NTAggregate.
|
||||
* @return this instance of <b>NTAggregateBuilder</b>.
|
||||
*/
|
||||
shared_pointer addMax();
|
||||
|
||||
/**
|
||||
* Add min field to the NTAggregate.
|
||||
* @return this instance of <b>NTAggregateBuilder</b>.
|
||||
*/
|
||||
shared_pointer addMin();
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTAggregate.
|
||||
* @return this instance of <b>NTAggregateBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTAggregate.
|
||||
* @return this instance of <b>NTAggregateBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTAggregate.
|
||||
* @return this instance of <b>NTAggregateBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTAggregate.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTAggregate.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>PVStructure</b>.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTAggregate</b> instance.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>NTAggregate</b>.
|
||||
*/
|
||||
NTAggregatePtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTAggregateBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
private:
|
||||
NTAggregateBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
bool dispersion;
|
||||
bool first;
|
||||
bool firstTimeStamp;
|
||||
bool last;
|
||||
bool lastTimeStamp;
|
||||
bool max;
|
||||
bool min;
|
||||
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTAggregate;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTAggregateBuilder> NTAggregateBuilderPtr;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTAggregate
|
||||
*
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTAggregate
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTAggregate);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTAggregate.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTAggregate.
|
||||
* @return NTAggregate instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTAggregate without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTAggregate.
|
||||
* @return NTAggregate instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTAggregate.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTAggregate.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTAggregate.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTAggregate.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTAggregate.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTAggregate.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTAggregate.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTAggregate.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTAggregate.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTAggregate
|
||||
* @return (false,true) if (is not, is) a valid NTAggregate.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTAggregate builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTAggregateBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTAggregate() {}
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the value field.
|
||||
* @return The PVDouble for the value.
|
||||
*/
|
||||
epics::pvData::PVDoublePtr getValue() const;
|
||||
|
||||
/**
|
||||
* Get the N field.
|
||||
* @return The PVLong for the N field.
|
||||
*/
|
||||
epics::pvData::PVLongPtr getN() const;
|
||||
|
||||
/**
|
||||
* Get the dispersion field.
|
||||
* @return The PVDouble for the dispersion which may be null
|
||||
*/
|
||||
epics::pvData::PVDoublePtr getDispersion() const;
|
||||
|
||||
/**
|
||||
* Get the first field.
|
||||
* @return The PVDouble for the first field which may be null
|
||||
*/
|
||||
epics::pvData::PVDoublePtr getFirst() const;
|
||||
|
||||
/**
|
||||
* Get the firstTimeStamp field.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getFirstTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the last field.
|
||||
* @return The PVDouble for the last field which may be null
|
||||
*/
|
||||
epics::pvData::PVDoublePtr getLast() const;
|
||||
|
||||
/**
|
||||
* Get the lastTimeStamp field.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getLastTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the max field.
|
||||
* @return The PVDouble for the max field which may be null
|
||||
*/
|
||||
epics::pvData::PVDoublePtr getMax() const;
|
||||
|
||||
/**
|
||||
* Get the min field.
|
||||
* @return The PVDouble for the max field which may be null
|
||||
*/
|
||||
epics::pvData::PVDoublePtr getMin() const;
|
||||
|
||||
private:
|
||||
NTAggregate(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTAggregate;
|
||||
epics::pvData::PVDoublePtr pvValue;
|
||||
|
||||
friend class detail::NTAggregateBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTAGGREGATE_H */
|
||||
246
src/nt/ntattribute.cpp
Normal file
246
src/nt/ntattribute.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
/* ntattribute.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntattribute.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
StructureConstPtr NTAttributeBuilder::createStructure()
|
||||
{
|
||||
FieldBuilderPtr builder =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId(NTAttribute::URI)->
|
||||
add("name", pvString)->
|
||||
add("value", getFieldCreate()->createVariantUnion());
|
||||
|
||||
if (tags)
|
||||
builder->addArray("tags", pvString);
|
||||
|
||||
if (descriptor)
|
||||
builder->add("descriptor", pvString);
|
||||
|
||||
if (alarm)
|
||||
builder->add("alarm", ntField->createAlarm());
|
||||
|
||||
if (timeStamp)
|
||||
builder->add("timeStamp", ntField->createTimeStamp());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTAttributeBuilder::shared_pointer NTAttributeBuilder::addTags()
|
||||
{
|
||||
tags = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTAttributeBuilder::shared_pointer NTAttributeBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTAttributeBuilder::shared_pointer NTAttributeBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTAttributeBuilder::shared_pointer NTAttributeBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
PVStructurePtr NTAttributeBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTAttributePtr NTAttributeBuilder::create()
|
||||
{
|
||||
return NTAttributePtr(new NTAttribute(createPVStructure()));
|
||||
}
|
||||
|
||||
NTAttributeBuilder::NTAttributeBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTAttributeBuilder::reset()
|
||||
{
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
}
|
||||
|
||||
NTAttributeBuilder::shared_pointer NTAttributeBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string NTAttribute::URI("epics:nt/NTAttribute:1.0");
|
||||
|
||||
NTAttribute::shared_pointer NTAttribute::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTAttribute::shared_pointer NTAttribute::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTAttribute(structure));
|
||||
}
|
||||
|
||||
bool NTAttribute::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTAttribute::isCompatible(StructureConstPtr const & structure)
|
||||
{
|
||||
if (structure.get() == 0) return false;
|
||||
|
||||
ScalarConstPtr nameField = structure->getField<Scalar>("name");
|
||||
if (nameField.get() == 0 || nameField->getScalarType() != pvString)
|
||||
return false;
|
||||
|
||||
UnionConstPtr valueField = structure->getField<Union>("value");
|
||||
if (valueField.get() == 0 || !valueField->isVariant())
|
||||
return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("tags");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr tagsField = structure->getField<ScalarArray>("tags");
|
||||
if (tagsField.get() == 0 || tagsField->getElementType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NTAttribute::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(!pvStructure) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTAttribute::isValid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NTAttributeBuilderPtr NTAttribute::createBuilder()
|
||||
{
|
||||
return NTAttributeBuilderPtr(new detail::NTAttributeBuilder());
|
||||
}
|
||||
|
||||
bool NTAttribute::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTAttribute::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStructurePtr NTAttribute::getPVStructure() const
|
||||
{
|
||||
return pvNTAttribute;
|
||||
}
|
||||
|
||||
PVStringPtr NTAttribute::getDescriptor() const
|
||||
{
|
||||
return pvNTAttribute->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
PVStructurePtr NTAttribute::getTimeStamp() const
|
||||
{
|
||||
return pvNTAttribute->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVStructurePtr NTAttribute::getAlarm() const
|
||||
{
|
||||
return pvNTAttribute->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
|
||||
PVStringPtr NTAttribute::getName() const
|
||||
{
|
||||
return pvNTAttribute->getSubField<PVString>("name");
|
||||
}
|
||||
|
||||
PVUnionPtr NTAttribute::getValue() const
|
||||
{
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
PVStringArrayPtr NTAttribute::getTags() const
|
||||
{
|
||||
return pvNTAttribute->getSubField<PVStringArray>("tags");
|
||||
}
|
||||
|
||||
NTAttribute::NTAttribute(PVStructurePtr const & pvStructure) :
|
||||
pvNTAttribute(pvStructure), pvValue(pvNTAttribute->getSubField<PVUnion>("value"))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
267
src/nt/ntattribute.h
Normal file
267
src/nt/ntattribute.h
Normal file
@@ -0,0 +1,267 @@
|
||||
/* ntattribute.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTATTRIBUTE_H
|
||||
#define NTATTRIBUTE_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntattributeEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#ifdef ntattributeEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntattributeEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTAttribute;
|
||||
typedef std::tr1::shared_ptr<NTAttribute> NTAttributePtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTAttribute.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTAttributeBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTAttributeBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTAttributeBuilder);
|
||||
|
||||
/**
|
||||
* Add tags field to the NTAttribute.
|
||||
* @return this instance of <b>NTAttributeBuilder</b>.
|
||||
*/
|
||||
virtual shared_pointer addTags();
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTAttribute.
|
||||
* @return this instance of <b>NTAttributeBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTAttribute.
|
||||
* @return this instance of <b>NTAttributeBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTAttribute.
|
||||
* @return this instance of <b>NTAttributeBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTAttribute.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTAttribute.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>PVStructure</b>.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTAttribute</b> instance.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>NTAttribute</b>.
|
||||
*/
|
||||
NTAttributePtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTAttributeBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
protected://private:
|
||||
NTAttributeBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
bool tags;
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTAttribute;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTAttributeBuilder> NTAttributeBuilderPtr;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTAttribute
|
||||
*
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTAttribute
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTAttribute);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTAttribute.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTAttribute.
|
||||
* @return NTAttribute instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTAttribute without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTAttribute.
|
||||
* @return NTAttribute instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTAttribute.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTAttribute.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTAttribute.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTAttribute.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTAttribute.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTAttribute.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTAttribute.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTAttribute.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTAttribute.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTAttribute
|
||||
* @return (false,true) if (is not, is) a valid NTAttribute.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTAttribute builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTAttributeBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTAttribute() {}
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the name field.
|
||||
* @return The PVString for the name.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getName() const;
|
||||
|
||||
/**
|
||||
* Get the value field.
|
||||
* @return The PVUnion for the values.
|
||||
*/
|
||||
epics::pvData::PVUnionPtr getValue() const;
|
||||
|
||||
/**
|
||||
* Get the tags field.
|
||||
* @return The PVStringArray for the tags, which may be null.
|
||||
*/
|
||||
epics::pvData::PVStringArrayPtr getTags() const;
|
||||
|
||||
private:
|
||||
NTAttribute(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTAttribute;
|
||||
epics::pvData::PVUnionPtr pvValue;
|
||||
|
||||
friend class detail::NTAttributeBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTATTRIBUTE_H */
|
||||
234
src/nt/ntcontinuum.cpp
Normal file
234
src/nt/ntcontinuum.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
/* ntcontinuum.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntcontinuum.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
StructureConstPtr NTContinuumBuilder::createStructure()
|
||||
{
|
||||
FieldBuilderPtr builder =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId(NTContinuum::URI)->
|
||||
addArray("base", pvDouble)->
|
||||
addArray("value", pvDouble)->
|
||||
addArray("units", pvString);
|
||||
|
||||
if (descriptor)
|
||||
builder->add("descriptor", pvString);
|
||||
|
||||
if (alarm)
|
||||
builder->add("alarm", ntField->createAlarm());
|
||||
|
||||
if (timeStamp)
|
||||
builder->add("timeStamp", ntField->createTimeStamp());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTContinuumBuilder::shared_pointer NTContinuumBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTContinuumBuilder::shared_pointer NTContinuumBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTContinuumBuilder::shared_pointer NTContinuumBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
|
||||
PVStructurePtr NTContinuumBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTContinuumPtr NTContinuumBuilder::create()
|
||||
{
|
||||
return NTContinuumPtr(new NTContinuum(createPVStructure()));
|
||||
}
|
||||
|
||||
NTContinuumBuilder::NTContinuumBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTContinuumBuilder::reset()
|
||||
{
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
}
|
||||
|
||||
NTContinuumBuilder::shared_pointer NTContinuumBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string NTContinuum::URI("epics:nt/NTContinuum:1.0");
|
||||
|
||||
NTContinuum::shared_pointer NTContinuum::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTContinuum::shared_pointer NTContinuum::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTContinuum(structure));
|
||||
}
|
||||
|
||||
bool NTContinuum::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTContinuum::isCompatible(StructureConstPtr const & structure)
|
||||
{
|
||||
if (structure.get() == 0) return false;
|
||||
|
||||
ScalarArrayConstPtr baseField = structure->getField<ScalarArray>("base");
|
||||
if (baseField.get() == 0 || baseField->getElementType() != pvDouble)
|
||||
return false;
|
||||
|
||||
ScalarArrayConstPtr valueField = structure->getField<ScalarArray>("value");
|
||||
if (valueField.get() == 0 || valueField->getElementType() != pvDouble)
|
||||
return false;
|
||||
|
||||
ScalarArrayConstPtr unitsField = structure->getField<ScalarArray>("units");
|
||||
if (unitsField.get() == 0 || unitsField->getElementType() != pvString)
|
||||
return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NTContinuum::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(!pvStructure) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTContinuum::isValid()
|
||||
{
|
||||
return ((getUnits()->getLength()-1)*getBase()->getLength() ==
|
||||
getValue()->getLength());
|
||||
}
|
||||
|
||||
NTContinuumBuilderPtr NTContinuum::createBuilder()
|
||||
{
|
||||
return NTContinuumBuilderPtr(new detail::NTContinuumBuilder());
|
||||
}
|
||||
|
||||
bool NTContinuum::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTContinuum::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStructurePtr NTContinuum::getPVStructure() const
|
||||
{
|
||||
return pvNTContinuum;
|
||||
}
|
||||
|
||||
PVStringPtr NTContinuum::getDescriptor() const
|
||||
{
|
||||
return pvNTContinuum->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
PVStructurePtr NTContinuum::getTimeStamp() const
|
||||
{
|
||||
return pvNTContinuum->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVStructurePtr NTContinuum::getAlarm() const
|
||||
{
|
||||
return pvNTContinuum->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
PVDoubleArrayPtr NTContinuum::getBase() const
|
||||
{
|
||||
return pvNTContinuum->getSubField<PVDoubleArray>("base");
|
||||
}
|
||||
|
||||
PVDoubleArrayPtr NTContinuum::getValue() const
|
||||
{
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
PVStringArrayPtr NTContinuum::getUnits() const
|
||||
{
|
||||
return pvNTContinuum->getSubField<PVStringArray>("units");
|
||||
}
|
||||
|
||||
NTContinuum::NTContinuum(PVStructurePtr const & pvStructure) :
|
||||
pvNTContinuum(pvStructure),
|
||||
pvValue(pvNTContinuum->getSubField<PVDoubleArray>("value"))
|
||||
{}
|
||||
|
||||
|
||||
}}
|
||||
262
src/nt/ntcontinuum.h
Normal file
262
src/nt/ntcontinuum.h
Normal file
@@ -0,0 +1,262 @@
|
||||
/* ntcontinuum.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTCONTINUUM_H
|
||||
#define NTCONTINUUM_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntcontinuumEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#ifdef ntcontinuumEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntcontinuumEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTContinuum;
|
||||
typedef std::tr1::shared_ptr<NTContinuum> NTContinuumPtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTContinuum.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTContinuumBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTContinuumBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTContinuumBuilder);
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTContinuum.
|
||||
* @return this instance of <b>NTContinuumBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTContinuum.
|
||||
* @return this instance of <b>NTContinuumBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTContinuum.
|
||||
* @return this instance of <b>NTContinuumBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTContinuum.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTContinuum.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>PVStructure</b>.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTContinuum</b> instance.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>NTContinuum</b>.
|
||||
*/
|
||||
NTContinuumPtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTContinuumBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
private:
|
||||
NTContinuumBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
bool dim;
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTContinuum;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTContinuumBuilder> NTContinuumBuilderPtr;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTContinuum
|
||||
*
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTContinuum
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTContinuum);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTContinuum.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTContinuum.
|
||||
* @return NTContinuum instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTContinuum without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTContinuum.
|
||||
* @return NTContinuum instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTContinuum.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTContinuum.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTContinuum.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTContinuum.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTContinuum.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTContinuum.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTContinuum.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTContinuum.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTContinuum.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTContinuum
|
||||
* @return (false,true) if (is not, is) a valid NTContinuum.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTContinuum builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTContinuumBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTContinuum() {}
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the base field.
|
||||
* @return The PVDoubleArray for the base.
|
||||
*/
|
||||
epics::pvData::PVDoubleArrayPtr getBase() const;
|
||||
|
||||
/**
|
||||
* Get the value field.
|
||||
* @return The PVDoubleArray for the values.
|
||||
*/
|
||||
epics::pvData::PVDoubleArrayPtr getValue() const;
|
||||
|
||||
/**
|
||||
* Get the units field.
|
||||
* @return The PVStringArray for the units.
|
||||
*/
|
||||
epics::pvData::PVStringArrayPtr getUnits() const;
|
||||
|
||||
private:
|
||||
NTContinuum(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTContinuum;
|
||||
epics::pvData::PVDoubleArrayPtr pvValue;
|
||||
|
||||
friend class detail::NTContinuumBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTCONTINUUM_H */
|
||||
213
src/nt/ntenum.cpp
Normal file
213
src/nt/ntenum.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/* ntenum.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntenum.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
StructureConstPtr NTEnumBuilder::createStructure()
|
||||
{
|
||||
FieldBuilderPtr builder =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId(NTEnum::URI)->
|
||||
add("value", ntField->createEnumerated());
|
||||
|
||||
if (descriptor)
|
||||
builder->add("descriptor", pvString);
|
||||
|
||||
if (alarm)
|
||||
builder->add("alarm", ntField->createAlarm());
|
||||
|
||||
if (timeStamp)
|
||||
builder->add("timeStamp", ntField->createTimeStamp());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTEnumBuilder::shared_pointer NTEnumBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTEnumBuilder::shared_pointer NTEnumBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTEnumBuilder::shared_pointer NTEnumBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
PVStructurePtr NTEnumBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTEnumPtr NTEnumBuilder::create()
|
||||
{
|
||||
return NTEnumPtr(new NTEnum(createPVStructure()));
|
||||
}
|
||||
|
||||
NTEnumBuilder::NTEnumBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTEnumBuilder::reset()
|
||||
{
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
}
|
||||
|
||||
NTEnumBuilder::shared_pointer NTEnumBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const std::string NTEnum::URI("epics:nt/NTEnum:1.0");
|
||||
|
||||
NTEnum::shared_pointer NTEnum::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTEnum::shared_pointer NTEnum::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTEnum(structure));
|
||||
}
|
||||
|
||||
bool NTEnum::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTEnum::isCompatible(StructureConstPtr const &structure)
|
||||
{
|
||||
if (structure.get() == 0) return false;
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
FieldConstPtr valueField = structure->getField("value");
|
||||
if (!valueField.get() || !ntField->isEnumerated(valueField))
|
||||
return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NTEnum::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(!pvStructure) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTEnum::isValid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NTEnumBuilderPtr NTEnum::createBuilder()
|
||||
{
|
||||
return NTEnumBuilderPtr(new detail::NTEnumBuilder());
|
||||
}
|
||||
|
||||
bool NTEnum::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTEnum::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStructurePtr NTEnum::getPVStructure() const
|
||||
{
|
||||
return pvNTEnum;
|
||||
}
|
||||
|
||||
PVStringPtr NTEnum::getDescriptor() const
|
||||
{
|
||||
return pvNTEnum->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
PVStructurePtr NTEnum::getTimeStamp() const
|
||||
{
|
||||
return pvNTEnum->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVStructurePtr NTEnum::getAlarm() const
|
||||
{
|
||||
return pvNTEnum->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
PVStructurePtr NTEnum::getValue() const
|
||||
{
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
NTEnum::NTEnum(PVStructurePtr const & pvStructure) :
|
||||
pvNTEnum(pvStructure), pvValue(pvNTEnum->getSubField<PVStructure>("value"))
|
||||
{}
|
||||
|
||||
|
||||
}}
|
||||
248
src/nt/ntenum.h
Normal file
248
src/nt/ntenum.h
Normal file
@@ -0,0 +1,248 @@
|
||||
/* ntenum.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTENUM_H
|
||||
#define NTENUM_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntenumEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#ifdef ntenumEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntenumEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTEnum;
|
||||
typedef std::tr1::shared_ptr<NTEnum> NTEnumPtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTEnum.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTEnumBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTEnumBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTEnumBuilder);
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTEnum.
|
||||
* @return this instance of <b>NTEnumBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTEnum.
|
||||
* @return this instance of <b>NTEnumBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTEnum.
|
||||
* @return this instance of <b>NTEnumBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTEnum.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTEnum.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>PVStructure</b>.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTEnum</b> instance.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>NTEnum</b>.
|
||||
*/
|
||||
NTEnumPtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTEnumBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
private:
|
||||
NTEnumBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTEnum;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTEnumBuilder> NTEnumBuilderPtr;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTEnum
|
||||
*
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTEnum
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTEnum);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTEnum.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTEnum.
|
||||
* @return NTEnum instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTEnum without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTEnum.
|
||||
* @return NTEnum instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTEnum.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTEnum.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTEnum.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTEnum.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTEnum.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTEnum.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTEnum.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTEnum.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTEnum.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTEnum
|
||||
* @return (false,true) if (is not, is) a valid NTEnum.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTEnum builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTEnumBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTEnum() {}
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the value field.
|
||||
* @return The PVStructure for the values.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getValue() const;
|
||||
|
||||
private:
|
||||
NTEnum(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTEnum;
|
||||
epics::pvData::PVStructurePtr pvValue;
|
||||
|
||||
friend class detail::NTEnumBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTENUM_H */
|
||||
@@ -1,16 +1,19 @@
|
||||
/* ntfield.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <pv/lock.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace nt {
|
||||
|
||||
NTFieldPtr NTField::get()
|
||||
{
|
||||
@@ -64,7 +67,7 @@ bool NTField::isTimeStamp(FieldConstPtr const & field)
|
||||
ScalarConstPtr s = static_pointer_cast<const Scalar>(f);
|
||||
if(s->getScalarType()!=pvLong) return false;
|
||||
f = fields[1];
|
||||
if(names[1].compare("nanoSeconds")!=0) return false;
|
||||
if(names[1].compare("nanoseconds")!=0) return false;
|
||||
if(f->getType()!=scalar) return false;
|
||||
s = static_pointer_cast<const Scalar>(f);
|
||||
if(s->getScalarType()!=pvInt) return false;
|
||||
@@ -154,15 +157,23 @@ bool NTField::isAlarmLimit(FieldConstPtr const & field)
|
||||
f = fields[1];
|
||||
if(names[1].compare("lowAlarmLimit")!=0) return false;
|
||||
if(f->getType()!=scalar) return false;
|
||||
s = static_pointer_cast<const Scalar>(f);
|
||||
if(s->getScalarType()!=pvDouble) return false;
|
||||
f = fields[2];
|
||||
if(names[2].compare("lowWarningLimit")!=0) return false;
|
||||
if(f->getType()!=scalar) return false;
|
||||
s = static_pointer_cast<const Scalar>(f);
|
||||
if(s->getScalarType()!=pvDouble) return false;
|
||||
f = fields[3];
|
||||
if(names[3].compare("highWarningLimit")!=0) return false;
|
||||
if(f->getType()!=scalar) return false;
|
||||
s = static_pointer_cast<const Scalar>(f);
|
||||
if(s->getScalarType()!=pvDouble) return false;
|
||||
f = fields[4];
|
||||
if(names[4].compare("highAlarmLimit")!=0) return false;
|
||||
if(f->getType()!=scalar) return false;
|
||||
s = static_pointer_cast<const Scalar>(f);
|
||||
if(s->getScalarType()!=pvDouble) return false;
|
||||
f = fields[5];
|
||||
if(names[5].compare("lowAlarmSeverity")!=0) return false;
|
||||
if(f->getType()!=scalar) return false;
|
||||
@@ -184,7 +195,7 @@ bool NTField::isAlarmLimit(FieldConstPtr const & field)
|
||||
s = static_pointer_cast<const Scalar>(f);
|
||||
if(s->getScalarType()!=pvInt) return false;
|
||||
f = fields[9];
|
||||
if(names[9].compare("hystersis")!=0) return false;
|
||||
if(names[9].compare("hysteresis")!=0) return false;
|
||||
if(f->getType()!=scalar) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -235,11 +246,6 @@ StructureConstPtr NTField::createDisplay()
|
||||
return standardField->display();
|
||||
}
|
||||
|
||||
StructureConstPtr NTField::createAlarmLimit()
|
||||
{
|
||||
return standardField->doubleAlarm();
|
||||
}
|
||||
|
||||
StructureConstPtr NTField::createControl()
|
||||
{
|
||||
return standardField->control();
|
||||
@@ -306,12 +312,6 @@ PVStructurePtr PVNTField::createDisplay()
|
||||
return pvDataCreate->createPVStructure(display);
|
||||
}
|
||||
|
||||
PVStructurePtr PVNTField::createAlarmLimit()
|
||||
{
|
||||
StructureConstPtr structure = NTField::get()->createAlarmLimit();
|
||||
return pvDataCreate->createPVStructure(structure);
|
||||
}
|
||||
|
||||
|
||||
PVStructurePtr PVNTField::createControl()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* ntfield.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTFIELD_H
|
||||
@@ -9,21 +9,27 @@
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntfieldEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/alarm.h>
|
||||
#include <pv/pvAlarm.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/sharedVector.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
/**
|
||||
* Convenience Class for introspection fields of a Normative Type
|
||||
* @author mrk
|
||||
*
|
||||
*/
|
||||
#ifdef ntfieldEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntfieldEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
typedef std::tr1::shared_ptr<epics::pvData::StringArray> StringArrayPtr;
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTField;
|
||||
typedef std::tr1::shared_ptr<NTField> NTFieldPtr;
|
||||
@@ -31,7 +37,13 @@ typedef std::tr1::shared_ptr<NTField> NTFieldPtr;
|
||||
class PVNTField;
|
||||
typedef std::tr1::shared_ptr<PVNTField> PVNTFieldPtr;
|
||||
|
||||
class NTField {
|
||||
/**
|
||||
* @brief Convenience Class for introspection fields of a Normative Type
|
||||
*
|
||||
* @author mrk
|
||||
*
|
||||
*/
|
||||
class epicsShareClass NTField {
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTField);
|
||||
/**
|
||||
@@ -48,96 +60,92 @@ public:
|
||||
* @param field The field to test.
|
||||
* @return (false,true) if field (is not,is) an enumerated structure.
|
||||
*/
|
||||
bool isEnumerated(FieldConstPtr const & field);
|
||||
bool isEnumerated(epics::pvData::FieldConstPtr const & field);
|
||||
/**
|
||||
* Is field a timeStamp structure.
|
||||
* @param field The field to test.
|
||||
* @return (false,true) if field (is not,is) a timeStamp structure.
|
||||
*/
|
||||
bool isTimeStamp(FieldConstPtr const & field);
|
||||
bool isTimeStamp(epics::pvData::FieldConstPtr const & field);
|
||||
/**
|
||||
* Is field an alarm structure.
|
||||
* @param field The field to test.
|
||||
* @return (false,true) if field (is not,is) an alarm structure.
|
||||
*/
|
||||
bool isAlarm(FieldConstPtr const & field);
|
||||
bool isAlarm(epics::pvData::FieldConstPtr const & field);
|
||||
/**
|
||||
* Is field a display structure.
|
||||
* @param field The field to test.
|
||||
* @return (false,true) if field (is not,is) a display structure.
|
||||
*/
|
||||
bool isDisplay(FieldConstPtr const & field);
|
||||
bool isDisplay(epics::pvData::FieldConstPtr const & field);
|
||||
/**
|
||||
* Is field an alarmLimit structure.
|
||||
* @param field The field to test.
|
||||
* @return (false,true) if field (is not,is) an alarmLimit structure.
|
||||
*/
|
||||
bool isAlarmLimit(FieldConstPtr const & field);
|
||||
bool isAlarmLimit(epics::pvData::FieldConstPtr const & field);
|
||||
/**
|
||||
* Is field a control structure.
|
||||
* @param field The field to test.
|
||||
* @return (false,true) if field (is not,is) a control structure.
|
||||
*/
|
||||
bool isControl(FieldConstPtr const & field);
|
||||
bool isControl(epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
/**
|
||||
* Create an enumerated structure.
|
||||
* @return an enumerated structure.
|
||||
*/
|
||||
StructureConstPtr createEnumerated();
|
||||
epics::pvData::StructureConstPtr createEnumerated();
|
||||
/**
|
||||
* Create a timeStamp structure.
|
||||
* @return a timeStamp structure.
|
||||
*/
|
||||
StructureConstPtr createTimeStamp();
|
||||
epics::pvData::StructureConstPtr createTimeStamp();
|
||||
/**
|
||||
* Create an alarm structure.
|
||||
* @return an alarm structure.
|
||||
*/
|
||||
StructureConstPtr createAlarm();
|
||||
epics::pvData::StructureConstPtr createAlarm();
|
||||
/**
|
||||
* Create a display structure.
|
||||
* @return a displayalarm structure.
|
||||
*/
|
||||
StructureConstPtr createDisplay();
|
||||
/**
|
||||
* Create an alarmLimit structure.
|
||||
* @return an alarmLimit structure.
|
||||
*/
|
||||
StructureConstPtr createAlarmLimit();
|
||||
epics::pvData::StructureConstPtr createDisplay();
|
||||
/**
|
||||
* Create a control structure.
|
||||
* @return a control structure.
|
||||
*/
|
||||
StructureConstPtr createControl();
|
||||
epics::pvData::StructureConstPtr createControl();
|
||||
|
||||
/**
|
||||
* Create an array of enumerated structures.
|
||||
* @return an array of enumerated structures.
|
||||
*/
|
||||
StructureArrayConstPtr createEnumeratedArray();
|
||||
epics::pvData::StructureArrayConstPtr createEnumeratedArray();
|
||||
/**
|
||||
* Create an array of timeStamp structures.
|
||||
* @return an array of timeStamp structures.
|
||||
*/
|
||||
StructureArrayConstPtr createTimeStampArray();
|
||||
epics::pvData::StructureArrayConstPtr createTimeStampArray();
|
||||
/**
|
||||
* Create an array of alarm structures.
|
||||
* @return an array of alarm structures.
|
||||
*/
|
||||
StructureArrayConstPtr createAlarmArray();
|
||||
epics::pvData::StructureArrayConstPtr createAlarmArray();
|
||||
private:
|
||||
NTField();
|
||||
FieldCreatePtr fieldCreate;
|
||||
StandardFieldPtr standardField;
|
||||
epics::pvData::FieldCreatePtr fieldCreate;
|
||||
epics::pvData::StandardFieldPtr standardField;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convenience Class for data fields of a Normative Type
|
||||
* @brief Convenience Class for data fields of a Normative Type
|
||||
*
|
||||
* @author mrk
|
||||
*
|
||||
*/
|
||||
class PVNTField {
|
||||
class epicsShareClass PVNTField {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVNTField);
|
||||
/**
|
||||
@@ -154,56 +162,57 @@ public:
|
||||
* @param choices The array of choices.
|
||||
* @return an enumerated PVStructure..
|
||||
*/
|
||||
PVStructurePtr createEnumerated(
|
||||
StringArray const & choices);
|
||||
epics::pvData::PVStructurePtr createEnumerated(
|
||||
epics::pvData::StringArray const & choices);
|
||||
/**
|
||||
* Create a timeStamp PVStructure.
|
||||
* @return a timeStamp PVStructure..
|
||||
*/
|
||||
PVStructurePtr createTimeStamp();
|
||||
epics::pvData::PVStructurePtr createTimeStamp();
|
||||
/**
|
||||
* Create an alarm PVStructure.
|
||||
* @return an alarm PVStructure..
|
||||
*/
|
||||
PVStructurePtr createAlarm();
|
||||
epics::pvData::PVStructurePtr createAlarm();
|
||||
/**
|
||||
* Create a display PVStructure.
|
||||
* @return a display PVStructure..
|
||||
*/
|
||||
PVStructurePtr createDisplay();
|
||||
epics::pvData::PVStructurePtr createDisplay();
|
||||
/**
|
||||
* Create an alarmLimit PVStructure.
|
||||
* @return an alarmLimit PVStructure..
|
||||
*/
|
||||
PVStructurePtr createAlarmLimit();
|
||||
epics::pvData::PVStructurePtr createAlarmLimit();
|
||||
/**
|
||||
* Create a control PVStructure.
|
||||
* @return a control PVStructure..
|
||||
*/
|
||||
PVStructurePtr createControl();
|
||||
epics::pvData::PVStructurePtr createControl();
|
||||
|
||||
/**
|
||||
* Create an enumerated PVStructureArray.
|
||||
* @return an enumerated PVStructureArray..
|
||||
*/
|
||||
PVStructureArrayPtr createEnumeratedArray();
|
||||
epics::pvData::PVStructureArrayPtr createEnumeratedArray();
|
||||
/**
|
||||
* Create a timeStamp PVStructureArray.
|
||||
* @return a timeStamp PVStructureArray
|
||||
*/
|
||||
PVStructureArrayPtr createTimeStampArray();
|
||||
epics::pvData::PVStructureArrayPtr createTimeStampArray();
|
||||
/**
|
||||
* Create an alarm PVStructureArray.
|
||||
* @return an alarm PVStructureArray..
|
||||
*/
|
||||
PVStructureArrayPtr createAlarmArray();
|
||||
epics::pvData::PVStructureArrayPtr createAlarmArray();
|
||||
private:
|
||||
PVNTField();
|
||||
PVDataCreatePtr pvDataCreate;
|
||||
StandardFieldPtr standardField;
|
||||
StandardPVFieldPtr standardPVField;
|
||||
epics::pvData::PVDataCreatePtr pvDataCreate;
|
||||
epics::pvData::StandardFieldPtr standardField;
|
||||
epics::pvData::StandardPVFieldPtr standardPVField;
|
||||
NTFieldPtr ntstructureField;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* NTFIELD_H */
|
||||
|
||||
238
src/nt/nthistogram.cpp
Normal file
238
src/nt/nthistogram.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/* ntcontinuum.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/nthistogram.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
NTHistogramBuilder::shared_pointer NTHistogramBuilder::value(
|
||||
epics::pvData::ScalarType scalarType
|
||||
)
|
||||
{
|
||||
valueType = scalarType;
|
||||
valueTypeSet = true;
|
||||
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
StructureConstPtr NTHistogramBuilder::createStructure()
|
||||
{
|
||||
if (!valueTypeSet)
|
||||
throw std::runtime_error("value array element type not set");
|
||||
|
||||
FieldBuilderPtr builder =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId(NTHistogram::URI)->
|
||||
addArray("ranges", pvDouble)->
|
||||
addArray("value", valueType);
|
||||
|
||||
if (descriptor)
|
||||
builder->add("descriptor", pvString);
|
||||
|
||||
if (alarm)
|
||||
builder->add("alarm", ntField->createAlarm());
|
||||
|
||||
if (timeStamp)
|
||||
builder->add("timeStamp", ntField->createTimeStamp());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTHistogramBuilder::shared_pointer NTHistogramBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTHistogramBuilder::shared_pointer NTHistogramBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTHistogramBuilder::shared_pointer NTHistogramBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
|
||||
PVStructurePtr NTHistogramBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTHistogramPtr NTHistogramBuilder::create()
|
||||
{
|
||||
return NTHistogramPtr(new NTHistogram(createPVStructure()));
|
||||
}
|
||||
|
||||
NTHistogramBuilder::NTHistogramBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTHistogramBuilder::reset()
|
||||
{
|
||||
valueTypeSet = false;
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
}
|
||||
|
||||
NTHistogramBuilder::shared_pointer NTHistogramBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string NTHistogram::URI("epics:nt/NTHistogram:1.0");
|
||||
|
||||
NTHistogram::shared_pointer NTHistogram::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTHistogram::shared_pointer NTHistogram::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTHistogram(structure));
|
||||
}
|
||||
|
||||
bool NTHistogram::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTHistogram::isCompatible(StructureConstPtr const &structure)
|
||||
{
|
||||
if(!structure.get()) return false;
|
||||
|
||||
ScalarArrayConstPtr rangesField = structure->getField<ScalarArray>("ranges");
|
||||
if(!rangesField.get() || rangesField->getElementType() != pvDouble) return false;
|
||||
|
||||
ScalarArrayConstPtr valueField = structure->getField<ScalarArray>("value");
|
||||
if(!valueField.get()) return false;
|
||||
|
||||
ScalarType scalarType = valueField->getElementType();
|
||||
if (scalarType != pvShort &&
|
||||
scalarType != pvInt &&
|
||||
scalarType != pvLong)
|
||||
return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("descriptor");
|
||||
if(field)
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NTHistogram::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(!pvStructure.get()) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTHistogram::isValid()
|
||||
{
|
||||
return (getValue()->getLength()+1 == getRanges()->getLength());
|
||||
}
|
||||
|
||||
NTHistogramBuilderPtr NTHistogram::createBuilder()
|
||||
{
|
||||
return NTHistogramBuilderPtr(new detail::NTHistogramBuilder());
|
||||
}
|
||||
|
||||
bool NTHistogram::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTHistogram::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStructurePtr NTHistogram::getPVStructure() const
|
||||
{
|
||||
return pvNTHistogram;
|
||||
}
|
||||
|
||||
PVStringPtr NTHistogram::getDescriptor() const
|
||||
{
|
||||
return pvNTHistogram->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
PVStructurePtr NTHistogram::getTimeStamp() const
|
||||
{
|
||||
return pvNTHistogram->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVStructurePtr NTHistogram::getAlarm() const
|
||||
{
|
||||
return pvNTHistogram->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
PVDoubleArrayPtr NTHistogram::getRanges() const
|
||||
{
|
||||
return pvNTHistogram->getSubField<PVDoubleArray>("ranges");
|
||||
}
|
||||
|
||||
PVScalarArrayPtr NTHistogram::getValue() const
|
||||
{
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
NTHistogram::NTHistogram(PVStructurePtr const & pvStructure) :
|
||||
pvNTHistogram(pvStructure),
|
||||
pvValue(pvNTHistogram->getSubField<PVScalarArray>("value"))
|
||||
{}
|
||||
|
||||
|
||||
}}
|
||||
277
src/nt/nthistogram.h
Normal file
277
src/nt/nthistogram.h
Normal file
@@ -0,0 +1,277 @@
|
||||
/* nthistogram.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTHISTOGRAM_H
|
||||
#define NTHISTOGRAM_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define nthistogramEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#ifdef nthistogramEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef nthistogramEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTHistogram;
|
||||
typedef std::tr1::shared_ptr<NTHistogram> NTHistogramPtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTHistogram.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTHistogramBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTHistogramBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTHistogramBuilder);
|
||||
|
||||
/**
|
||||
* Set a scalar type of value field array.
|
||||
* @param scalarType the value type.
|
||||
* @return this instance of <b>NTHistogramBuilder</b>.
|
||||
*/
|
||||
shared_pointer value(epics::pvData::ScalarType scalarType);
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTHistogram.
|
||||
* @return this instance of <b>NTHistogramBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTHistogram.
|
||||
* @return this instance of <b>NTHistogramBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTHistogram.
|
||||
* @return this instance of <b>NTHistogramBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTHistogram.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTHistogram.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>PVStructure</b>.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTHistogram</b> instance.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>NTHistogram</b>.
|
||||
*/
|
||||
NTHistogramPtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTHistogramBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
private:
|
||||
NTHistogramBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
bool valueTypeSet;
|
||||
epics::pvData::ScalarType valueType;
|
||||
|
||||
bool dim;
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTHistogram;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTHistogramBuilder> NTHistogramBuilderPtr;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTHistogram
|
||||
*
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTHistogram
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTHistogram);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTHistogram.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTHistogram.
|
||||
* @return NTHistogram instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTHistogram without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTHistogram.
|
||||
* @return NTHistogram instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTHistogram.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTHistogram.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTHistogram.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTHistogram.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTHistogram.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTHistogram.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTHistogram.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTHistogram.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTHistogram.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTHistogram
|
||||
* @return (false,true) if (is not, is) a valid NTHistogram.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTHistogram builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTHistogramBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTHistogram() {}
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the base field.
|
||||
* @return The PVDoubleArray for the base.
|
||||
*/
|
||||
epics::pvData::PVDoubleArrayPtr getRanges() const;
|
||||
|
||||
/**
|
||||
* Get the value field.
|
||||
* @return The PVScalarArray for the values.
|
||||
*/
|
||||
epics::pvData::PVScalarArrayPtr getValue() const;
|
||||
|
||||
/**
|
||||
* Get the value field of a specified type (e.g. PVIntArray).
|
||||
* @return The <PVT> field for the values.
|
||||
*/
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getValue() const
|
||||
{
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(pvValue);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
NTHistogram(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTHistogram;
|
||||
epics::pvData::PVScalarArrayPtr pvValue;
|
||||
|
||||
friend class detail::NTHistogramBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTHISTOGRAM_H */
|
||||
190
src/nt/ntid.cpp
Normal file
190
src/nt/ntid.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <pv/ntid.h>
|
||||
#include <pv/typeCast.h>
|
||||
|
||||
namespace epics {
|
||||
|
||||
namespace nt {
|
||||
|
||||
const static std::string BAD_NAME = "?";
|
||||
|
||||
NTID::NTID(const std::string & id)
|
||||
: fullName(id),
|
||||
qualifiedName(BAD_NAME),
|
||||
namespaceStr(BAD_NAME),
|
||||
name(BAD_NAME),
|
||||
version(BAD_NAME),
|
||||
nsSepIndex(std::string::npos),
|
||||
versionSepIndex(std::string::npos),
|
||||
nsQualified(false),
|
||||
hasVersion(false),
|
||||
endMajorIndex(0),
|
||||
majorVersionStr(BAD_NAME),
|
||||
majorVersionParsed(false),
|
||||
hasMajor(false),
|
||||
majorVersion(0),
|
||||
|
||||
endMinorIndex(0),
|
||||
minorVersionStr(BAD_NAME),
|
||||
minorVersionParsed(false),
|
||||
hasMinor(false),
|
||||
minorVersion(0)
|
||||
{
|
||||
nsSepIndex = id.find('/');
|
||||
nsQualified = nsSepIndex != std::string::npos;
|
||||
size_t startIndex = nsQualified ? nsSepIndex+1 : 0;
|
||||
versionSepIndex = id.find(':', startIndex);
|
||||
hasVersion = versionSepIndex != std::string::npos;
|
||||
}
|
||||
|
||||
std::string NTID::getFullName() { return fullName; }
|
||||
|
||||
std::string NTID::getQualifiedName()
|
||||
{
|
||||
if (qualifiedName == BAD_NAME)
|
||||
{
|
||||
qualifiedName = hasVersion ?
|
||||
fullName.substr(0, versionSepIndex) : fullName;
|
||||
}
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
|
||||
std::string NTID::getNamespace()
|
||||
{
|
||||
if (namespaceStr == BAD_NAME)
|
||||
{
|
||||
namespaceStr = nsQualified ?
|
||||
fullName.substr(0, nsSepIndex) : "";
|
||||
}
|
||||
return namespaceStr;
|
||||
}
|
||||
|
||||
std::string NTID::getName()
|
||||
{
|
||||
if (name == BAD_NAME)
|
||||
{
|
||||
if (hasVersion)
|
||||
{
|
||||
size_t startIndex = nsQualified ? nsSepIndex+1 : 0;
|
||||
name = fullName.substr(startIndex, versionSepIndex);
|
||||
}
|
||||
else if (nsQualified)
|
||||
{
|
||||
name = fullName.substr(nsSepIndex+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = fullName;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
std::string NTID::getVersion()
|
||||
{
|
||||
if (version == BAD_NAME)
|
||||
{
|
||||
version = (hasVersion) ? fullName.substr(versionSepIndex+1) : "";
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
std::string NTID::getMajorVersionString()
|
||||
{
|
||||
if (majorVersionStr == BAD_NAME)
|
||||
{
|
||||
if (hasVersion)
|
||||
{
|
||||
endMajorIndex = fullName.find('.', versionSepIndex+1);
|
||||
majorVersionStr = (endMajorIndex != std::string::npos)
|
||||
? fullName.substr(versionSepIndex+1, endMajorIndex-(versionSepIndex+1)) :
|
||||
fullName.substr(versionSepIndex+1);
|
||||
}
|
||||
else
|
||||
majorVersionStr = "";
|
||||
}
|
||||
return majorVersionStr;
|
||||
}
|
||||
|
||||
|
||||
bool NTID::hasMajorVersion()
|
||||
{
|
||||
if (hasVersion && !majorVersionParsed)
|
||||
{
|
||||
try {
|
||||
using pvData::detail::parseToPOD;
|
||||
uint32_t mv;
|
||||
parseToPOD(getMajorVersionString(), &mv);
|
||||
majorVersion = static_cast<int>(mv);
|
||||
hasMajor = true;
|
||||
} catch (...) {}
|
||||
majorVersionParsed = true;
|
||||
}
|
||||
return hasMajor;
|
||||
}
|
||||
|
||||
|
||||
int NTID::getMajorVersion()
|
||||
{
|
||||
// call hasMajorVersion() to calculate values
|
||||
hasMajorVersion();
|
||||
return majorVersion;
|
||||
}
|
||||
|
||||
|
||||
std::string NTID::getMinorVersionString()
|
||||
{
|
||||
// call hasMinorVersion() to calculate start of minor
|
||||
getMajorVersionString();
|
||||
if (minorVersionStr == BAD_NAME)
|
||||
{
|
||||
if (hasVersion && endMajorIndex != std::string::npos)
|
||||
{
|
||||
endMinorIndex = fullName.find('.', endMajorIndex+1);
|
||||
minorVersionStr = (endMinorIndex != std::string::npos)
|
||||
? fullName.substr(endMajorIndex+1, endMinorIndex-(endMajorIndex+1)) :
|
||||
fullName.substr(endMajorIndex+1);
|
||||
}
|
||||
else
|
||||
minorVersionStr = "";
|
||||
}
|
||||
return minorVersionStr;
|
||||
}
|
||||
|
||||
|
||||
bool NTID::hasMinorVersion()
|
||||
{
|
||||
if (hasVersion && !minorVersionParsed)
|
||||
{
|
||||
try {
|
||||
using pvData::detail::parseToPOD;
|
||||
uint32_t mv;
|
||||
parseToPOD(getMinorVersionString(), &mv);
|
||||
minorVersion = static_cast<int>(mv);
|
||||
hasMinor = true;
|
||||
} catch (...) {}
|
||||
minorVersionParsed = true;
|
||||
}
|
||||
return hasMinor;
|
||||
}
|
||||
|
||||
|
||||
int NTID::getMinorVersion()
|
||||
{
|
||||
// call hasMinorVersion() to calculate values
|
||||
hasMinorVersion();
|
||||
return minorVersion;
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
|
||||
147
src/nt/ntid.h
Normal file
147
src/nt/ntid.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTID_H
|
||||
#define NTID_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace epics {
|
||||
|
||||
namespace nt {
|
||||
|
||||
/**
|
||||
* Utility class for parsing an ID following the NT type ID conventions
|
||||
*
|
||||
* An NT type ID will be of the from epics:nt/<type-name>:<Major>.<Minor>,
|
||||
* e.g. epics:nt/NTNDArray:1.2
|
||||
* @author dgh
|
||||
*/
|
||||
class NTID
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Creates an NTID from the specified type ID
|
||||
*
|
||||
* @param id The the id to be parsed.
|
||||
* @return NTNDArray instance on success, null otherwise.
|
||||
*/
|
||||
NTID(const std::string &id);
|
||||
/**
|
||||
* Get the full name of the id, i.e. the original ID
|
||||
*
|
||||
* For example above returns "epics:nt/NTNDArray:1.2"
|
||||
* @return the full name
|
||||
*/
|
||||
std::string getFullName();
|
||||
|
||||
/**
|
||||
* Get the fully qualified name including namespaces, but excluding version numbers
|
||||
*
|
||||
* For example above return "epics:nt/NTNDArray"
|
||||
* @return the fully qualified name
|
||||
*/
|
||||
std::string getQualifiedName();
|
||||
|
||||
/**
|
||||
* Get the namespace
|
||||
*
|
||||
* For example above return "epics:nt"
|
||||
* @return the namespace
|
||||
*/
|
||||
std::string getNamespace();
|
||||
|
||||
/**
|
||||
* Get the unqualified name, without namespace or version
|
||||
*
|
||||
* For example above return "NTNDArray"
|
||||
* @return the unqualified name
|
||||
*/
|
||||
std::string getName();
|
||||
|
||||
/**
|
||||
* Get the unqualified name, without namespace or version
|
||||
*
|
||||
* For example above return "NTNDArray"
|
||||
* @return the unqualified name
|
||||
*/
|
||||
std::string getVersion();
|
||||
|
||||
/**
|
||||
* Get the Major version as a string
|
||||
*
|
||||
* For example above return "1"
|
||||
* @return the Major string
|
||||
*/
|
||||
std::string getMajorVersionString();
|
||||
|
||||
/**
|
||||
* Does the ID contain a major version and is it a number
|
||||
*
|
||||
* @return true if it contains a major version number
|
||||
*/
|
||||
bool hasMajorVersion();
|
||||
|
||||
/**
|
||||
* Get the Major version as an integer
|
||||
*
|
||||
* For example above return 1
|
||||
* @return the Major string
|
||||
*/
|
||||
int getMajorVersion();
|
||||
|
||||
/**
|
||||
* Get the Major version as a string
|
||||
*
|
||||
* For example above return "1"
|
||||
* @return the Major string
|
||||
*/
|
||||
std::string getMinorVersionString();
|
||||
|
||||
/**
|
||||
* Does the ID contain a minor version and is it a number
|
||||
*
|
||||
* @return true if it contains a minor version number
|
||||
*/
|
||||
bool hasMinorVersion();
|
||||
|
||||
/**
|
||||
* Get the Minor version as an integer
|
||||
*
|
||||
* For example above return 1
|
||||
* @return the Minor string
|
||||
*/
|
||||
int getMinorVersion();
|
||||
|
||||
private:
|
||||
std::string fullName;
|
||||
std::string qualifiedName;
|
||||
std::string namespaceStr;
|
||||
std::string name;
|
||||
std::string version;
|
||||
|
||||
size_t nsSepIndex;
|
||||
size_t versionSepIndex;
|
||||
bool nsQualified;
|
||||
bool hasVersion;
|
||||
|
||||
size_t endMajorIndex;
|
||||
std::string majorVersionStr;
|
||||
bool majorVersionParsed;
|
||||
bool hasMajor;
|
||||
int majorVersion;
|
||||
|
||||
size_t endMinorIndex;
|
||||
std::string minorVersionStr;
|
||||
bool minorVersionParsed;
|
||||
bool hasMinor;
|
||||
int minorVersion;
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
283
src/nt/ntmatrix.cpp
Normal file
283
src/nt/ntmatrix.cpp
Normal file
@@ -0,0 +1,283 @@
|
||||
/* ntmatrix.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntmatrix.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
StructureConstPtr NTMatrixBuilder::createStructure()
|
||||
{
|
||||
FieldBuilderPtr builder =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId(NTMatrix::URI)->
|
||||
addArray("value", pvDouble);
|
||||
|
||||
if (dim)
|
||||
builder->addArray("dim", pvInt);
|
||||
|
||||
if (descriptor)
|
||||
builder->add("descriptor", pvString);
|
||||
|
||||
if (alarm)
|
||||
builder->add("alarm", ntField->createAlarm());
|
||||
|
||||
if (timeStamp)
|
||||
builder->add("timeStamp", ntField->createTimeStamp());
|
||||
|
||||
if (display)
|
||||
builder->add("display", ntField->createDisplay());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTMatrixBuilder::shared_pointer NTMatrixBuilder::addDim()
|
||||
{
|
||||
dim = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMatrixBuilder::shared_pointer NTMatrixBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMatrixBuilder::shared_pointer NTMatrixBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMatrixBuilder::shared_pointer NTMatrixBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMatrixBuilder::shared_pointer NTMatrixBuilder::addDisplay()
|
||||
{
|
||||
display = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
PVStructurePtr NTMatrixBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTMatrixPtr NTMatrixBuilder::create()
|
||||
{
|
||||
return NTMatrixPtr(new NTMatrix(createPVStructure()));
|
||||
}
|
||||
|
||||
NTMatrixBuilder::NTMatrixBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTMatrixBuilder::reset()
|
||||
{
|
||||
dim = false;
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
display = false;
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
}
|
||||
|
||||
NTMatrixBuilder::shared_pointer NTMatrixBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string NTMatrix::URI("epics:nt/NTMatrix:1.0");
|
||||
|
||||
NTMatrix::shared_pointer NTMatrix::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTMatrix::shared_pointer NTMatrix::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTMatrix(structure));
|
||||
}
|
||||
|
||||
bool NTMatrix::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTMatrix::isCompatible(StructureConstPtr const & structure)
|
||||
{
|
||||
if (structure.get() == 0) return false;
|
||||
|
||||
ScalarArrayConstPtr valueField = structure->getField<ScalarArray>("value");
|
||||
if (valueField.get() == 0 || valueField->getElementType() != pvDouble)
|
||||
return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("dim");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr dimField = structure->getField<ScalarArray>("dim");
|
||||
if (dimField.get() == 0 || dimField->getElementType() != pvInt)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("display");
|
||||
if (field.get() && !ntField->isDisplay(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NTMatrix::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(!pvStructure) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTMatrix::isValid()
|
||||
{
|
||||
int valueLength = getValue()->getLength();
|
||||
if (valueLength == 0)
|
||||
return false;
|
||||
|
||||
PVIntArrayPtr pvDim = getDim();
|
||||
if (pvDim.get())
|
||||
{
|
||||
int length = pvDim->getLength();
|
||||
if (length != 1 && length !=2)
|
||||
return false;
|
||||
|
||||
PVIntArray::const_svector data = pvDim->view();
|
||||
int expectedLength = 1;
|
||||
for (PVIntArray::const_svector::const_iterator it = data.begin();
|
||||
it != data.end(); ++it)
|
||||
{
|
||||
expectedLength *= *it;
|
||||
}
|
||||
if (expectedLength != valueLength)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NTMatrixBuilderPtr NTMatrix::createBuilder()
|
||||
{
|
||||
return NTMatrixBuilderPtr(new detail::NTMatrixBuilder());
|
||||
}
|
||||
|
||||
bool NTMatrix::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTMatrix::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTMatrix::attachDisplay(PVDisplay &pvDisplay) const
|
||||
{
|
||||
PVStructurePtr dp = getDisplay();
|
||||
if (dp)
|
||||
return pvDisplay.attach(dp);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStructurePtr NTMatrix::getPVStructure() const
|
||||
{
|
||||
return pvNTMatrix;
|
||||
}
|
||||
|
||||
PVStringPtr NTMatrix::getDescriptor() const
|
||||
{
|
||||
return pvNTMatrix->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
PVStructurePtr NTMatrix::getTimeStamp() const
|
||||
{
|
||||
return pvNTMatrix->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVStructurePtr NTMatrix::getAlarm() const
|
||||
{
|
||||
return pvNTMatrix->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
PVStructurePtr NTMatrix::getDisplay() const
|
||||
{
|
||||
return pvNTMatrix->getSubField<PVStructure>("display");
|
||||
}
|
||||
|
||||
PVDoubleArrayPtr NTMatrix::getValue() const
|
||||
{
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
PVIntArrayPtr NTMatrix::getDim() const
|
||||
{
|
||||
return pvNTMatrix->getSubField<PVIntArray>("dim");
|
||||
}
|
||||
|
||||
NTMatrix::NTMatrix(PVStructurePtr const & pvStructure) :
|
||||
pvNTMatrix(pvStructure),
|
||||
pvValue(pvNTMatrix->getSubField<PVDoubleArray>("value"))
|
||||
{}
|
||||
|
||||
|
||||
}}
|
||||
285
src/nt/ntmatrix.h
Normal file
285
src/nt/ntmatrix.h
Normal file
@@ -0,0 +1,285 @@
|
||||
/* ntmatrix.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTMATRIX_H
|
||||
#define NTMATRIX_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntmatrixEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/pvDisplay.h>
|
||||
|
||||
#ifdef ntmatrixEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntmatrixEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTMatrix;
|
||||
typedef std::tr1::shared_ptr<NTMatrix> NTMatrixPtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTMatrix.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTMatrixBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTMatrixBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTMatrixBuilder);
|
||||
|
||||
/**
|
||||
* Add dimensionfield to the NTMatrix.
|
||||
* @return this instance of <b>NTMatrixBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDim();
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTMatrix.
|
||||
* @return this instance of <b>NTMatrixBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTMatrix.
|
||||
* @return this instance of <b>NTMatrixBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTMatrix.
|
||||
* @return this instance of <b>NTMatrixBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Add display structure to the NTMatrix.
|
||||
* @return this instance of <b>NTMatrixBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDisplay();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTMatrix.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTMatrix.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>PVStructure</b>.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTMatrix</b> instance.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>NTMatrix</b>.
|
||||
*/
|
||||
NTMatrixPtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTMatrixBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
private:
|
||||
NTMatrixBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
bool dim;
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
bool display;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTMatrix;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTMatrixBuilder> NTMatrixBuilderPtr;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTMatrix
|
||||
*
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTMatrix
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTMatrix);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTMatrix.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTMatrix.
|
||||
* @return NTMatrix instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTMatrix without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTMatrix.
|
||||
* @return NTMatrix instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTMatrix.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTMatrix.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTMatrix.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTMatrix.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTMatrix.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTMatrix.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTMatrix.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTMatrix.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTMatrix.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTMatrix
|
||||
* @return (false,true) if (is not, is) a valid NTMatrix.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTMatrix builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTMatrixBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTMatrix() {}
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Attach an pvDisplay.
|
||||
* @param pvDisplay The pvDisplay that will be attached.
|
||||
* Does nothing if no display.
|
||||
* @return true if the operation was successfull (i.e. this instance has a display field), otherwise false.
|
||||
*/
|
||||
bool attachDisplay(epics::pvData::PVDisplay &pvDisplay) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the display.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getDisplay() const;
|
||||
|
||||
/**
|
||||
* Get the value field.
|
||||
* @return The PVDoubleArray for the values.
|
||||
*/
|
||||
epics::pvData::PVDoubleArrayPtr getValue() const;
|
||||
|
||||
/**
|
||||
* Get the dim field.
|
||||
* @return The PVIntArray for the dim which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getDim() const;
|
||||
|
||||
private:
|
||||
NTMatrix(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTMatrix;
|
||||
epics::pvData::PVDoubleArrayPtr pvValue;
|
||||
|
||||
friend class detail::NTMatrixBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTMATRIX_H */
|
||||
381
src/nt/ntmultiChannel.cpp
Normal file
381
src/nt/ntmultiChannel.cpp
Normal file
@@ -0,0 +1,381 @@
|
||||
/* ntmultiChannel.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntmultiChannel.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::value(UnionConstPtr valuePtr)
|
||||
{
|
||||
valueType = valuePtr;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
|
||||
NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addSeverity()
|
||||
{
|
||||
severity = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addStatus()
|
||||
{
|
||||
status = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addMessage()
|
||||
{
|
||||
message = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addSecondsPastEpoch()
|
||||
{
|
||||
secondsPastEpoch = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addNanoseconds()
|
||||
{
|
||||
nanoseconds = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addUserTag()
|
||||
{
|
||||
userTag = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addIsConnected()
|
||||
{
|
||||
isConnected = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
StructureConstPtr NTMultiChannelBuilder::createStructure()
|
||||
{
|
||||
StandardFieldPtr standardField = getStandardField();
|
||||
size_t nfields = 2;
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
nfields += extraCount;
|
||||
if(descriptor) ++nfields;
|
||||
if(alarm) ++nfields;
|
||||
if(timeStamp) ++nfields;
|
||||
if(severity) ++nfields;
|
||||
if(status) ++nfields;
|
||||
if(message) ++nfields;
|
||||
if(secondsPastEpoch) ++nfields;
|
||||
if(nanoseconds) ++nfields;
|
||||
if(userTag) ++nfields;
|
||||
if(isConnected) ++nfields;
|
||||
FieldConstPtrArray fields(nfields);
|
||||
StringArray names(nfields);
|
||||
size_t ind = 0;
|
||||
names[ind] = "value";
|
||||
if(valueType) {
|
||||
fields[ind++] = fieldCreate->createUnionArray(valueType);
|
||||
} else {
|
||||
fields[ind++] = fieldCreate->createVariantUnionArray();
|
||||
}
|
||||
names[ind] = "channelName";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvString);
|
||||
if(descriptor) {
|
||||
names[ind] = "descriptor";
|
||||
fields[ind++] = fieldCreate->createScalar(pvString);
|
||||
}
|
||||
if(alarm) {
|
||||
names[ind] = "alarm";
|
||||
fields[ind++] = standardField->alarm();
|
||||
}
|
||||
if(timeStamp) {
|
||||
names[ind] = "timeStamp";
|
||||
fields[ind++] = standardField->timeStamp();
|
||||
}
|
||||
if(severity) {
|
||||
names[ind] = "severity";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvInt);
|
||||
}
|
||||
if(status) {
|
||||
names[ind] = "status";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvInt);
|
||||
}
|
||||
if(message) {
|
||||
names[ind] = "message";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvString);
|
||||
}
|
||||
if(secondsPastEpoch) {
|
||||
names[ind] = "secondsPastEpoch";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvLong);
|
||||
}
|
||||
if(nanoseconds) {
|
||||
names[ind] = "nanoseconds";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvInt);
|
||||
}
|
||||
if(userTag) {
|
||||
names[ind] = "userTag";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvInt);
|
||||
}
|
||||
if(isConnected) {
|
||||
names[ind] = "isConnected";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvBoolean);
|
||||
}
|
||||
for (size_t i = 0; i< extraCount; i++) {
|
||||
names[ind] = extraFieldNames[i];
|
||||
fields[ind++] = extraFields[i];
|
||||
}
|
||||
|
||||
StructureConstPtr st = fieldCreate->createStructure(NTMultiChannel::URI,names,fields);
|
||||
reset();
|
||||
return st;
|
||||
}
|
||||
|
||||
PVStructurePtr NTMultiChannelBuilder::createPVStructure()
|
||||
{
|
||||
return pvDataCreate->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTMultiChannelPtr NTMultiChannelBuilder::create()
|
||||
{
|
||||
return NTMultiChannelPtr(new NTMultiChannel(createPVStructure()));
|
||||
}
|
||||
|
||||
NTMultiChannelBuilder::NTMultiChannelBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTMultiChannelBuilder::reset()
|
||||
{
|
||||
valueType.reset();
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
severity = false;
|
||||
status = false;
|
||||
message = false;
|
||||
secondsPastEpoch = false;
|
||||
nanoseconds = false;
|
||||
userTag = false;
|
||||
isConnected = false;
|
||||
}
|
||||
|
||||
|
||||
NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string NTMultiChannel::URI("epics:nt/NTMultiChannel:1.0");
|
||||
|
||||
NTMultiChannel::shared_pointer NTMultiChannel::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTMultiChannel::shared_pointer NTMultiChannel::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTMultiChannel(structure));
|
||||
}
|
||||
|
||||
bool NTMultiChannel::is_a(StructureConstPtr const &structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
|
||||
bool NTMultiChannel::isCompatible(StructureConstPtr const & structure)
|
||||
{
|
||||
if (!structure.get()) return false;
|
||||
|
||||
UnionArrayConstPtr valueField = structure->getField<UnionArray>("value");
|
||||
if (!valueField.get()) return false;
|
||||
|
||||
ScalarArrayConstPtr channelNameField = structure->getField<ScalarArray>(
|
||||
"channelName");
|
||||
if (!channelNameField.get()) return false;
|
||||
if (channelNameField->getElementType() != pvString) return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("severity");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr severityField = structure->getField<ScalarArray>("severity");
|
||||
if (!severityField.get() || severityField->getElementType() != pvInt)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("status");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr statusField = structure->getField<ScalarArray>("status");
|
||||
if (!statusField.get() || statusField->getElementType() != pvInt)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("message");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr messageField = structure->getField<ScalarArray>("message");
|
||||
if (!messageField.get() || messageField->getElementType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("secondsPastEpoch");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr secondsPastEpochField = structure->getField<ScalarArray>("secondsPastEpoch");
|
||||
if (!secondsPastEpochField.get() || secondsPastEpochField->getElementType() != pvLong)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("nanoseconds");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr nanosecondsField = structure->getField<ScalarArray>("nanoseconds");
|
||||
if (!nanosecondsField.get() || nanosecondsField->getElementType() != pvInt)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("userTag");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr userTagField = structure->getField<ScalarArray>("userTag");
|
||||
if (!userTagField.get() || userTagField->getElementType() != pvInt)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NTMultiChannel::isCompatible(PVStructurePtr const &pvStructure)
|
||||
{
|
||||
if(!pvStructure.get()) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
|
||||
bool NTMultiChannel::isValid()
|
||||
{
|
||||
size_t valueLength = getValue()->getLength();
|
||||
if (getChannelName()->getLength() != valueLength) return false;
|
||||
|
||||
PVScalarArrayPtr arrayFields[] = {
|
||||
getSeverity(), getStatus(), getMessage(),
|
||||
getSecondsPastEpoch(), getNanoseconds(), getUserTag()
|
||||
};
|
||||
size_t N = sizeof(arrayFields)/sizeof(arrayFields[0]);
|
||||
|
||||
PVScalarArrayPtr arrayField;
|
||||
for (PVScalarArrayPtr * pa = arrayFields; pa != arrayFields+N; ++pa)
|
||||
{
|
||||
arrayField = *pa;
|
||||
if (arrayField.get() && arrayField->getLength() != valueLength)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
NTMultiChannelBuilderPtr NTMultiChannel::createBuilder()
|
||||
{
|
||||
return NTMultiChannelBuilderPtr(new detail::NTMultiChannelBuilder());
|
||||
}
|
||||
|
||||
NTMultiChannel::NTMultiChannel(PVStructurePtr const & pvStructure)
|
||||
: pvNTMultiChannel(pvStructure),
|
||||
pvTimeStamp(pvStructure->getSubField<PVStructure>("timeStamp")),
|
||||
pvAlarm(pvStructure->getSubField<PVStructure>("alarm")),
|
||||
pvValue(pvStructure->getSubField<PVUnionArray>("value")),
|
||||
pvChannelName(pvStructure->getSubField<PVStringArray>("channelName")),
|
||||
pvIsConnected(pvStructure->getSubField<PVBooleanArray>("isConnected")),
|
||||
pvSeverity(pvStructure->getSubField<PVIntArray>("severity")),
|
||||
pvStatus(pvStructure->getSubField<PVIntArray>("status")),
|
||||
pvMessage(pvStructure->getSubField<PVStringArray>("message")),
|
||||
pvSecondsPastEpoch(pvStructure->getSubField<PVLongArray>("secondsPastEpoch")),
|
||||
pvNanoseconds(pvStructure->getSubField<PVIntArray>("nanoseconds")),
|
||||
pvUserTag(pvStructure->getSubField<PVIntArray>("userTag")),
|
||||
pvDescriptor(pvStructure->getSubField<PVString>("descriptor"))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool NTMultiChannel::attachTimeStamp(PVTimeStamp &pv) const
|
||||
{
|
||||
if (pvTimeStamp)
|
||||
return pv.attach(pvTimeStamp);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTMultiChannel::attachAlarm(PVAlarm &pv) const
|
||||
{
|
||||
if (pvAlarm)
|
||||
return pv.attach(pvAlarm);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}}
|
||||
353
src/nt/ntmultiChannel.h
Normal file
353
src/nt/ntmultiChannel.h
Normal file
@@ -0,0 +1,353 @@
|
||||
/* ntmultiChannel.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTMULTICHANNEL_H
|
||||
#define NTMULTICHANNEL_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntmultiChannelEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/pvDisplay.h>
|
||||
#include <pv/pvControl.h>
|
||||
|
||||
#ifdef ntmultiChannelEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntmultiChannelEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
|
||||
class NTMultiChannel;
|
||||
typedef std::tr1::shared_ptr<NTMultiChannel> NTMultiChannelPtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTMultiChannel.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author mse
|
||||
*/
|
||||
class epicsShareClass NTMultiChannelBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTMultiChannelBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTMultiChannelBuilder);
|
||||
/**
|
||||
* specify the union for the value field.
|
||||
* If this is not called then a variantUnion is the default.
|
||||
* @return this instance of <b>NTMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer value(epics::pvData::UnionConstPtr valuePtr);
|
||||
/**
|
||||
* Add descriptor field to the NTMultiChannel.
|
||||
* @return this instance of <b>NTMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
/**
|
||||
* Add alarm structure to the NTMultiChannel.
|
||||
* @return this instance of <b>NTMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
/**
|
||||
* Add timeStamp structure to the NTMultiChannel.
|
||||
* @return this instance of <b>NTMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
/**
|
||||
* Add severity array to the NTMultiChannel.
|
||||
* @return this instance of <b>NTMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addSeverity();
|
||||
/**
|
||||
* Add status array to the NTMultiChannel.
|
||||
* @return this instance of <b>NTMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addStatus();
|
||||
/**
|
||||
* Add message array to the NTMultiChannel.
|
||||
* @return this instance of <b>NTMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addMessage();
|
||||
/**
|
||||
* Add secondsPastEpoch array to the NTMultiChannel.
|
||||
* @return this instance of <b>NTMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addSecondsPastEpoch();
|
||||
/**
|
||||
* Add nanoseconds array to the NTMultiChannel.
|
||||
* @return this instance of <b>NTMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addNanoseconds();
|
||||
/**
|
||||
* Add userTag array to the NTMultiChannel.
|
||||
* @return this instance of <b>NTMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addUserTag();
|
||||
/**
|
||||
* Add isConnected array to the NTMultiChannel.
|
||||
* @return this instance of <b>NTMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addIsConnected();
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTMultiChannel.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTMultiChannel.
|
||||
* This resets this instance state and allows new {@code instance to be created.}
|
||||
* @return a new instance of a <b>PVStructure</b>
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
/**
|
||||
* Create a <b>NTMultiChannel</b> instance.
|
||||
* This resets this instance state and allows new {@code instance to be created.}
|
||||
* @return a new instance of a <b>NTMultiChannel</b>
|
||||
*/
|
||||
NTMultiChannelPtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of a <b>NTMultiChannelBuilder</b>
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
private:
|
||||
NTMultiChannelBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
epics::pvData::UnionConstPtr valueType;
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
bool severity;
|
||||
bool status;
|
||||
bool message;
|
||||
bool secondsPastEpoch;
|
||||
bool nanoseconds;
|
||||
bool userTag;
|
||||
bool isConnected;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTMultiChannel;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTMultiChannelBuilder> NTMultiChannelBuilderPtr;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTMultiChannel
|
||||
*
|
||||
* @author mrk
|
||||
*
|
||||
*/
|
||||
class epicsShareClass NTMultiChannel
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTMultiChannel);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTMultiChannel.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTMultiChannel.
|
||||
* @return NTMultiChannel instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTMultiChannel without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTMultiChannel.
|
||||
* @return NTMultiChannel instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTMultiChannel.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTMultiChannel.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTMultiChannel.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTMultiChannel.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTMultiChannel.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTMultiChannel.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTMultiChannel.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTMultiChannel.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTMultiChannel.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTMultiChannel
|
||||
* @return (false,true) if (is not, is) a valid NTMultiChannel.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTMultiChannelBuilder instance
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTMultiChannelBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~NTMultiChannel() {}
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance
|
||||
has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
/**
|
||||
* Attach a pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const
|
||||
{return pvNTMultiChannel;}
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const
|
||||
{return pvTimeStamp;}
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const
|
||||
{return pvAlarm;}
|
||||
/**
|
||||
* Get the value of each channel.
|
||||
* @return PVUnionArrayPtr
|
||||
*/
|
||||
epics::pvData::PVUnionArrayPtr getValue() const
|
||||
{return pvValue;}
|
||||
/**
|
||||
* Get the channelName of each channel.
|
||||
* @return PVStringArrayPtr
|
||||
*/
|
||||
epics::pvData::PVStringArrayPtr getChannelName() const
|
||||
{ return pvChannelName;};
|
||||
/**
|
||||
* Get the connection state of each channel.
|
||||
* @return PVBooleanArrayPtr
|
||||
*/
|
||||
epics::pvData::PVBooleanArrayPtr getIsConnected() const
|
||||
{ return pvIsConnected;};
|
||||
/**
|
||||
* Get the severity of each channel.
|
||||
* @return PVIntArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getSeverity() const
|
||||
{return pvSeverity;}
|
||||
/**
|
||||
* Get the status of each channel.
|
||||
* @return PVIntArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getStatus() const
|
||||
{return pvStatus;}
|
||||
/**
|
||||
* Get the message of each chnnel.
|
||||
* @return PVStringArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStringArrayPtr getMessage() const
|
||||
{return pvMessage;}
|
||||
/**
|
||||
* Get the secondsPastEpoch of each channel.
|
||||
* @return PVLongArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVLongArrayPtr getSecondsPastEpoch() const
|
||||
{return pvSecondsPastEpoch;}
|
||||
/**
|
||||
* Get the nanoseconds of each channel.
|
||||
* @return PVIntArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getNanoseconds() const
|
||||
{return pvNanoseconds;}
|
||||
/**
|
||||
* Get the userTag of each channel.
|
||||
* @return PVIntArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getUserTag() const
|
||||
{return pvUserTag;}
|
||||
/**
|
||||
* Get the descriptor.
|
||||
* @return PVStringPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const
|
||||
{return pvDescriptor;}
|
||||
private:
|
||||
NTMultiChannel(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTMultiChannel;
|
||||
epics::pvData::PVStructurePtr pvTimeStamp;
|
||||
epics::pvData::PVStructurePtr pvAlarm;
|
||||
epics::pvData::PVUnionArrayPtr pvValue;
|
||||
epics::pvData::PVStringArrayPtr pvChannelName;
|
||||
epics::pvData::PVBooleanArrayPtr pvIsConnected;
|
||||
epics::pvData::PVIntArrayPtr pvSeverity;
|
||||
epics::pvData::PVIntArrayPtr pvStatus;
|
||||
epics::pvData::PVStringArrayPtr pvMessage;
|
||||
epics::pvData::PVLongArrayPtr pvSecondsPastEpoch;
|
||||
epics::pvData::PVIntArrayPtr pvNanoseconds;
|
||||
epics::pvData::PVIntArrayPtr pvUserTag;
|
||||
epics::pvData::PVStringPtr pvDescriptor;
|
||||
friend class detail::NTMultiChannelBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTMULTICHANNEL_H */
|
||||
@@ -1,110 +1,234 @@
|
||||
/* ntnameValue.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntnameValue.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
namespace epics { namespace nt {
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
bool NTNameValue::isNTNameValue(PVStructurePtr const & pvStructure)
|
||||
namespace detail {
|
||||
|
||||
|
||||
NTNameValueBuilder::shared_pointer NTNameValueBuilder::value(
|
||||
epics::pvData::ScalarType scalarType
|
||||
)
|
||||
{
|
||||
PVFieldPtr pvField = pvStructure->getSubField("names");
|
||||
if(pvField.get()==NULL) return false;
|
||||
FieldConstPtr field = pvField->getField();
|
||||
if(field->getType()!=scalarArray) return false;
|
||||
ScalarArrayConstPtr pscalarArray =
|
||||
static_pointer_cast<const ScalarArray>(field);
|
||||
if(pscalarArray->getElementType()!=pvString) return false;
|
||||
pvField = pvStructure->getSubField("values");
|
||||
if(pvField==0) return false;
|
||||
field = pvField->getField();
|
||||
if(field->getType()!=scalarArray) return false;
|
||||
pscalarArray = static_pointer_cast<const ScalarArray>(field);
|
||||
if(pscalarArray->getElementType()!=pvString) return false;
|
||||
valueType = scalarType;
|
||||
valueTypeSet = true;
|
||||
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
StructureConstPtr NTNameValueBuilder::createStructure()
|
||||
{
|
||||
if (!valueTypeSet)
|
||||
throw std::runtime_error("value type not set");
|
||||
|
||||
FieldBuilderPtr builder =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId(NTNameValue::URI)->
|
||||
addArray("name", pvString)->
|
||||
addArray("value", valueType);
|
||||
|
||||
if (descriptor)
|
||||
builder->add("descriptor", pvString);
|
||||
|
||||
if (alarm)
|
||||
builder->add("alarm", ntField->createAlarm());
|
||||
|
||||
if (timeStamp)
|
||||
builder->add("timeStamp", ntField->createTimeStamp());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTNameValueBuilder::shared_pointer NTNameValueBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTNameValueBuilder::shared_pointer NTNameValueBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTNameValueBuilder::shared_pointer NTNameValueBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
PVStructurePtr NTNameValueBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTNameValuePtr NTNameValueBuilder::create()
|
||||
{
|
||||
return NTNameValuePtr(new NTNameValue(createPVStructure()));
|
||||
}
|
||||
|
||||
NTNameValueBuilder::NTNameValueBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTNameValueBuilder::reset()
|
||||
{
|
||||
valueTypeSet = false;
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
}
|
||||
|
||||
NTNameValueBuilder::shared_pointer NTNameValueBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const std::string NTNameValue::URI("epics:nt/NTNameValue:1.0");
|
||||
|
||||
NTNameValue::shared_pointer NTNameValue::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTNameValue::shared_pointer NTNameValue::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTNameValue(structure));
|
||||
}
|
||||
|
||||
bool NTNameValue::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTNameValue::isCompatible(StructureConstPtr const & structure)
|
||||
{
|
||||
if (structure.get() == 0) return false;
|
||||
|
||||
ScalarArrayConstPtr nameField = structure->getField<ScalarArray>("name");
|
||||
if (nameField.get() == 0 || nameField->getElementType() != pvString)
|
||||
return false;
|
||||
|
||||
ScalarArrayConstPtr valueField = structure->getField<ScalarArray>("value");
|
||||
if (valueField.get() == 0)
|
||||
return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NTNameValuePtr NTNameValue::create(
|
||||
bool hasFunction,bool hasTimeStamp, bool hasAlarm)
|
||||
bool NTNameValue::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
StandardFieldPtr standardField = getStandardField();
|
||||
size_t nfields = 2;
|
||||
if(hasFunction) nfields++;
|
||||
if(hasTimeStamp) nfields++;
|
||||
if(hasAlarm) nfields++;
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
FieldConstPtrArray fields;
|
||||
StringArray names;
|
||||
fields.resize(nfields);
|
||||
names.resize(nfields);
|
||||
names[0] = "names";
|
||||
fields[0] = fieldCreate->createScalarArray(pvString);
|
||||
names[1] = "values";
|
||||
fields[1] = fieldCreate->createScalarArray(pvString);
|
||||
size_t ind = 2;
|
||||
if(hasFunction) {
|
||||
names[ind] = "function";
|
||||
fields[ind++] = fieldCreate->createScalar(pvString);
|
||||
}
|
||||
if(hasTimeStamp) {
|
||||
names[ind] = "timeStamp";
|
||||
fields[ind++] = standardField->timeStamp();
|
||||
}
|
||||
if(hasAlarm) {
|
||||
names[ind] = "alarm";
|
||||
fields[ind++] = standardField->alarm();
|
||||
}
|
||||
StructureConstPtr st = fieldCreate->createStructure(names,fields);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(st);
|
||||
return NTNameValuePtr(new NTNameValue(pvStructure));
|
||||
if(!pvStructure) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
NTNameValuePtr NTNameValue::create(
|
||||
PVStructurePtr const & pvStructure)
|
||||
bool NTNameValue::isValid()
|
||||
{
|
||||
return NTNameValuePtr(new NTNameValue(pvStructure));
|
||||
return (getValue<PVScalarArray>()->getLength() == getName()->getLength());
|
||||
}
|
||||
|
||||
NTNameValue::NTNameValue(PVStructure::shared_pointer const & pvStructure)
|
||||
: pvNTNameValue(pvStructure)
|
||||
NTNameValueBuilderPtr NTNameValue::createBuilder()
|
||||
{
|
||||
NTFieldPtr ntfield = NTField::get();
|
||||
PVScalarArrayPtr pvArray =
|
||||
pvStructure->getScalarArrayField("names",pvString);
|
||||
pvNames = static_pointer_cast<PVStringArray>(pvArray);
|
||||
pvArray = pvStructure->getScalarArrayField("values",pvString);
|
||||
pvValues = static_pointer_cast<PVStringArray>(pvArray);
|
||||
PVFieldPtr pvField = pvStructure->getSubField("function");
|
||||
if(pvField.get()!=NULL) {
|
||||
pvFunction = pvStructure->getStringField("function");
|
||||
}
|
||||
pvField = pvStructure->getSubField("timeStamp");
|
||||
if(pvField.get()!=NULL && ntfield->isTimeStamp(pvField->getField())) {
|
||||
pvTimeStamp = static_pointer_cast<PVStructure>(pvField);
|
||||
}
|
||||
pvField = pvStructure->getSubField("alarm");
|
||||
if(pvField.get()!=NULL && ntfield->isAlarm(pvField->getField())) {
|
||||
pvAlarm = static_pointer_cast<PVStructure>(pvField);
|
||||
}
|
||||
return NTNameValueBuilderPtr(new detail::NTNameValueBuilder());
|
||||
}
|
||||
|
||||
|
||||
void NTNameValue::attachTimeStamp(PVTimeStamp &pv)
|
||||
bool NTNameValue::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
if(pvTimeStamp.get()==NULL) return;
|
||||
pv.attach(pvTimeStamp);
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void NTNameValue::attachAlarm(PVAlarm &pv)
|
||||
bool NTNameValue::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
if(pvAlarm.get()==NULL) return;
|
||||
pv.attach(pvAlarm);
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStructurePtr NTNameValue::getPVStructure() const
|
||||
{
|
||||
return pvNTNameValue;
|
||||
}
|
||||
|
||||
PVStringPtr NTNameValue::getDescriptor() const
|
||||
{
|
||||
return pvNTNameValue->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
PVStructurePtr NTNameValue::getTimeStamp() const
|
||||
{
|
||||
return pvNTNameValue->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVStructurePtr NTNameValue::getAlarm() const
|
||||
{
|
||||
return pvNTNameValue->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
PVStringArrayPtr NTNameValue::getName() const
|
||||
{
|
||||
return pvNTNameValue->getSubField<PVStringArray>("name");
|
||||
}
|
||||
|
||||
PVFieldPtr NTNameValue::getValue() const
|
||||
{
|
||||
return pvNTNameValue->getSubField("value");
|
||||
}
|
||||
|
||||
NTNameValue::NTNameValue(PVStructurePtr const & pvStructure) :
|
||||
pvNTNameValue(pvStructure)
|
||||
{}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,100 +1,277 @@
|
||||
/* ntnameValue.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTNAMEVALUE_H
|
||||
#define NTNAMEVALUE_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntnameValueEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/pvDisplay.h>
|
||||
#include <pv/pvControl.h>
|
||||
|
||||
#ifdef ntnameValueEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntnameValueEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
#include <shareLib.h>
|
||||
|
||||
/**
|
||||
* Convenience Class for NTNameValue
|
||||
* @author mrk
|
||||
*
|
||||
*/
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTNameValue;
|
||||
typedef std::tr1::shared_ptr<NTNameValue> NTNameValuePtr;
|
||||
|
||||
class NTNameValue
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTNameValue.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author mse
|
||||
*/
|
||||
class epicsShareClass NTNameValueBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTNameValueBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTNameValueBuilder);
|
||||
|
||||
/**
|
||||
* Set a value array <b>Scalar</b> type.
|
||||
* @param scalarType value array scalar array.
|
||||
* @return this instance of <b>NTTableBuilder</b>.
|
||||
*/
|
||||
shared_pointer value(epics::pvData::ScalarType scalarType);
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTNameValue.
|
||||
* @return this instance of <b>NTTableBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTNameValue.
|
||||
* @return this instance of <b>NTTableBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTNameValue.
|
||||
* @return this instance of <b>NTTableBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTNameValue.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTNameValue.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>PVStructure</b>
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTNameValue</b> instance.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>NTNameValue</b>
|
||||
*/
|
||||
NTNameValuePtr create();
|
||||
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTTableBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
private:
|
||||
NTNameValueBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
bool valueTypeSet;
|
||||
epics::pvData::ScalarType valueType;
|
||||
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTNameValue;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTNameValueBuilder> NTNameValueBuilderPtr;
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTNameValue
|
||||
*
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass NTNameValue
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTNameValue);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Is the pvStructure an NTNameValue.
|
||||
* @param pvStructure The pvStructure to test.
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTNameValue.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTNameValue.
|
||||
* @return NTNameValue instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTNameValue without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTNameValue.
|
||||
* @return NTNameValue instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTNameValue.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTNameValue.
|
||||
*/
|
||||
static bool isNTNameValue(PVStructurePtr const & pvStructure);
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Create an NTNameValue pvStructure.
|
||||
* @param hasFunction Create a PVString field named function.
|
||||
* @param hasTimeStamp Create a timeStamp structure field.
|
||||
* @param hasAlarm Create an alarm structure field.
|
||||
* @return NTNameValuePtr
|
||||
* Is the structure an NTNameValue.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTNameValue.
|
||||
*/
|
||||
static NTNameValuePtr create(
|
||||
bool hasFunction,bool hasTimeStamp, bool hasAlarm);
|
||||
static NTNameValuePtr create(
|
||||
PVStructurePtr const & pvStructure);
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
* Is the Structure compatible with NTNameValue.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTNameValue.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTNameValue.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTNameValue.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTNameValue.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTNameValue
|
||||
* @return (false,true) if (is not, is) a valid NTNameValue.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTNameValue builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTNameValueBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTNameValue() {}
|
||||
/**
|
||||
* Get the function field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
PVStringPtr getFunction() {return pvFunction;}
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp
|
||||
*/
|
||||
void attachTimeStamp(PVTimeStamp &pvTimeStamp);
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
void attachAlarm(PVAlarm &pvAlarm);
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
PVStructurePtr getPVStructure(){return pvNTNameValue;}
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
PVStructurePtr getTimeStamp(){return pvTimeStamp;}
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
PVStructurePtr getAlarm() {return pvAlarm;}
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the string array on names.
|
||||
* @return The array of names.
|
||||
* Get the name array field.
|
||||
* @return The PVStringArray for the name.
|
||||
*/
|
||||
PVStringArrayPtr getNames() {return pvNames;}
|
||||
epics::pvData::PVStringArrayPtr getName() const;
|
||||
|
||||
/**
|
||||
* Get the string array on values.
|
||||
* @return The array of values.
|
||||
* Get the value array field.
|
||||
* @return The PVField for the value.
|
||||
*/
|
||||
PVStringArrayPtr getValues() {return pvValues;}
|
||||
epics::pvData::PVFieldPtr getValue() const;
|
||||
|
||||
/**
|
||||
* Get the value array field of a specified type (e.g. PVDoubleArray).
|
||||
* @return The <PVT> array for the value.
|
||||
*/
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getValue() const
|
||||
{
|
||||
epics::pvData::PVFieldPtr pvField = getValue();
|
||||
if (pvField.get())
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(pvField);
|
||||
else
|
||||
return std::tr1::shared_ptr<PVT>();
|
||||
}
|
||||
|
||||
private:
|
||||
NTNameValue(PVStructurePtr const & pvStructure);
|
||||
PVStructurePtr pvNTNameValue;
|
||||
PVStringPtr pvFunction;
|
||||
PVStructurePtr pvTimeStamp;
|
||||
PVStructurePtr pvAlarm;
|
||||
PVStringArrayPtr pvNames;
|
||||
PVStringArrayPtr pvValues;
|
||||
NTNameValue(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTNameValue;
|
||||
friend class detail::NTNameValueBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
580
src/nt/ntndarray.cpp
Normal file
580
src/nt/ntndarray.cpp
Normal file
@@ -0,0 +1,580 @@
|
||||
/* ntndarray.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntndarray.h>
|
||||
#include <pv/ntndarrayAttribute.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
|
||||
static Mutex mutex;
|
||||
|
||||
StructureConstPtr NTNDArrayBuilder::createStructure()
|
||||
{
|
||||
enum
|
||||
{
|
||||
DISCRIPTOR_INDEX,
|
||||
TIMESTAMP_INDEX,
|
||||
ALARM_INDEX,
|
||||
DISPLAY_INDEX
|
||||
};
|
||||
|
||||
const size_t NUMBER_OF_INDICES = DISPLAY_INDEX+1;
|
||||
const size_t NUMBER_OF_STRUCTURES = 1 << NUMBER_OF_INDICES;
|
||||
|
||||
Lock xx(mutex);
|
||||
|
||||
static StructureConstPtr ntndarrayStruc[NUMBER_OF_STRUCTURES];
|
||||
static UnionConstPtr valueType;
|
||||
static StructureConstPtr codecStruc;
|
||||
static StructureConstPtr dimensionStruc;
|
||||
static StructureConstPtr attributeStruc;
|
||||
|
||||
StructureConstPtr returnedStruc;
|
||||
|
||||
size_t index = 0;
|
||||
if (descriptor) index |= 1 << DISCRIPTOR_INDEX;
|
||||
if (timeStamp) index |= 1 << TIMESTAMP_INDEX;
|
||||
if (alarm) index |= 1 << ALARM_INDEX;
|
||||
if (display) index |= 1 << DISPLAY_INDEX;
|
||||
|
||||
bool isExtended = !extraFieldNames.empty();
|
||||
|
||||
if (isExtended || !ntndarrayStruc[index])
|
||||
{
|
||||
StandardFieldPtr standardField = getStandardField();
|
||||
FieldBuilderPtr fb = fieldCreate->createFieldBuilder();
|
||||
|
||||
if (!valueType)
|
||||
{
|
||||
for (int i = pvBoolean; i < pvString; ++i)
|
||||
{
|
||||
ScalarType st = static_cast<ScalarType>(i);
|
||||
fb->addArray(std::string(ScalarTypeFunc::name(st)) + "Value", st);
|
||||
}
|
||||
valueType = fb->createUnion();
|
||||
}
|
||||
|
||||
if (!codecStruc)
|
||||
{
|
||||
codecStruc = fb->setId("codec_t")->
|
||||
add("name", pvString)->
|
||||
add("parameters", fieldCreate->createVariantUnion())->
|
||||
createStructure();
|
||||
}
|
||||
|
||||
if (!dimensionStruc)
|
||||
{
|
||||
dimensionStruc = fb->setId("dimension_t")->
|
||||
add("size", pvInt)->
|
||||
add("offset", pvInt)->
|
||||
add("fullSize", pvInt)->
|
||||
add("binning", pvInt)->
|
||||
add("reverse", pvBoolean)->
|
||||
createStructure();
|
||||
}
|
||||
|
||||
if (!attributeStruc)
|
||||
{
|
||||
attributeStruc = NTNDArrayAttribute::createBuilder()->createStructure();
|
||||
}
|
||||
|
||||
fb->setId(NTNDArray::URI)->
|
||||
add("value", valueType)->
|
||||
add("codec", codecStruc)->
|
||||
add("compressedSize", pvLong)->
|
||||
add("uncompressedSize", pvLong)->
|
||||
addArray("dimension", dimensionStruc)->
|
||||
add("uniqueId", pvInt)->
|
||||
add("dataTimeStamp", standardField->timeStamp())->
|
||||
addArray("attribute", attributeStruc);
|
||||
|
||||
if (descriptor)
|
||||
fb->add("descriptor", pvString);
|
||||
|
||||
if (alarm)
|
||||
fb->add("alarm", standardField->alarm());
|
||||
|
||||
if (timeStamp)
|
||||
fb->add("timeStamp", standardField->timeStamp());
|
||||
|
||||
if (display)
|
||||
fb->add("display", standardField->display());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
fb->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
returnedStruc = fb->createStructure();
|
||||
|
||||
if (!isExtended)
|
||||
ntndarrayStruc[index] = returnedStruc;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ntndarrayStruc[index];
|
||||
}
|
||||
|
||||
return returnedStruc;
|
||||
}
|
||||
|
||||
NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::addDisplay()
|
||||
{
|
||||
display = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
PVStructurePtr NTNDArrayBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTNDArrayPtr NTNDArrayBuilder::create()
|
||||
{
|
||||
return NTNDArrayPtr(new NTNDArray(createPVStructure()));
|
||||
}
|
||||
|
||||
NTNDArrayBuilder::NTNDArrayBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTNDArrayBuilder::reset()
|
||||
{
|
||||
descriptor = false;
|
||||
timeStamp = false;
|
||||
alarm = false;
|
||||
display = false;
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
}
|
||||
|
||||
NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const std::string NTNDArray::URI("epics:nt/NTNDArray:1.0");
|
||||
const std::string ntAttrStr("epics:nt/NTAttribute:1.0");
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
|
||||
class NTValueType
|
||||
{
|
||||
public:
|
||||
static bool isCompatible(UnionConstPtr const &u)
|
||||
{
|
||||
if(!u.get()) return false;
|
||||
|
||||
if (u->getID() != Union::defaultId()) return false;
|
||||
if (u->isVariant()) return false;
|
||||
|
||||
for (int i = pvBoolean; i != pvString; ++i)
|
||||
{
|
||||
ScalarType scalarType = static_cast<ScalarType>(i);
|
||||
std::string name(ScalarTypeFunc::name(scalarType));
|
||||
name += "Value";
|
||||
ScalarArrayConstPtr scalarField = u->getField<ScalarArray>(name);
|
||||
if (scalarField.get() == 0 ||
|
||||
scalarField->getElementType() != scalarType)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class NTCodec
|
||||
{
|
||||
public:
|
||||
static bool isCompatible(StructureConstPtr const &structure)
|
||||
{
|
||||
if(!structure.get()) return false;
|
||||
|
||||
if (structure->getID() != "codec_t") return false;
|
||||
|
||||
ScalarConstPtr scalarField = structure->getField<Scalar>("name");
|
||||
if (scalarField.get() == 0 || scalarField->getScalarType() != pvString)
|
||||
return false;
|
||||
|
||||
UnionConstPtr paramField = structure->getField<Union>("parameters");
|
||||
if (paramField.get() == 0 || !paramField->isVariant())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class NTDimension
|
||||
{
|
||||
public:
|
||||
static bool isCompatible(StructureConstPtr const &structure)
|
||||
{
|
||||
if(!structure.get()) return false;
|
||||
|
||||
if (structure->getID() != "dimension_t") return false;
|
||||
|
||||
ScalarConstPtr scalarField = structure->getField<Scalar>("size");
|
||||
if (scalarField.get() == 0 || scalarField->getScalarType() != pvInt)
|
||||
return false;
|
||||
|
||||
scalarField = structure->getField<Scalar>("offset");
|
||||
if (scalarField.get() == 0 || scalarField->getScalarType() != pvInt)
|
||||
return false;
|
||||
|
||||
scalarField = structure->getField<Scalar>("fullSize");
|
||||
if (scalarField.get() == 0 || scalarField->getScalarType() != pvInt)
|
||||
return false;
|
||||
|
||||
scalarField = structure->getField<Scalar>("binning");
|
||||
if (scalarField.get() == 0 || scalarField->getScalarType() != pvInt)
|
||||
return false;
|
||||
|
||||
scalarField = structure->getField<Scalar>("reverse");
|
||||
if (scalarField.get() == 0 || scalarField->getScalarType() != pvBoolean)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
NTNDArray::shared_pointer NTNDArray::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTNDArray::shared_pointer NTNDArray::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTNDArray(structure));
|
||||
}
|
||||
|
||||
bool NTNDArray::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTNDArray::isCompatible(StructureConstPtr const &structure)
|
||||
{
|
||||
if(!structure.get()) return false;
|
||||
|
||||
UnionConstPtr valueField = structure->getField<Union>("value");
|
||||
if(!NTValueType::isCompatible(valueField)) return false;
|
||||
|
||||
StructureConstPtr codecField = structure->getField<Structure>("codec");
|
||||
if(!NTCodec::isCompatible(codecField)) return false;
|
||||
|
||||
ScalarConstPtr compressedSizeField = structure->getField<Scalar>("compressedSize");
|
||||
if (compressedSizeField.get() == 0)
|
||||
return false;
|
||||
|
||||
if (compressedSizeField->getScalarType() != pvLong)
|
||||
return false;
|
||||
|
||||
|
||||
ScalarConstPtr uncompressedSizeField = structure->getField<Scalar>("uncompressedSize");
|
||||
if (uncompressedSizeField.get() == 0)
|
||||
return false;
|
||||
|
||||
if (uncompressedSizeField->getScalarType() != pvLong)
|
||||
return false;
|
||||
|
||||
StructureArrayConstPtr dimensionField = structure->getField<StructureArray>("dimension");
|
||||
if (dimensionField.get() == 0)
|
||||
return false;
|
||||
StructureConstPtr dimElementStruc = dimensionField->getStructure();
|
||||
|
||||
if(!NTDimension::isCompatible(dimElementStruc))
|
||||
return false;
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
StructureConstPtr dataTimeStampField = structure->getField<Structure>(
|
||||
"dataTimeStamp");
|
||||
if (dataTimeStampField.get() == 0 || !ntField->isTimeStamp(dataTimeStampField))
|
||||
return false;
|
||||
|
||||
|
||||
ScalarConstPtr uniqueIdField = structure->getField<Scalar>("uniqueId");
|
||||
if (uniqueIdField.get() == 0)
|
||||
return false;
|
||||
|
||||
if (uniqueIdField->getScalarType() != pvInt)
|
||||
return false;
|
||||
|
||||
|
||||
StructureArrayConstPtr attributeField = structure->getField<StructureArray>( "attribute");
|
||||
|
||||
StructureConstPtr attributeElementStruc = attributeField->getStructure();
|
||||
|
||||
if (!NTNDArrayAttribute::isCompatible(attributeElementStruc))
|
||||
return false;
|
||||
|
||||
|
||||
FieldConstPtr field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("display");
|
||||
if (field.get() && !ntField->isDisplay(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NTNDArray::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(!pvStructure.get()) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
|
||||
bool NTNDArray::isValid()
|
||||
{
|
||||
int64 valueSize = getValueSize();
|
||||
int64 compressedSize = getCompressedDataSize()->get();
|
||||
if (valueSize != compressedSize)
|
||||
return false;
|
||||
|
||||
long expectedUncompressed = getExpectedUncompressedSize();
|
||||
long uncompressedSize = getUncompressedDataSize()->get();
|
||||
if (uncompressedSize != expectedUncompressed)
|
||||
return false;
|
||||
|
||||
std::string codecName = getCodec()->getSubField<PVString>("name")->get();
|
||||
if (codecName == "" && valueSize < uncompressedSize)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int64 NTNDArray::getExpectedUncompressedSize()
|
||||
{
|
||||
int64 size = 0;
|
||||
PVStructureArrayPtr pvDim = getDimension();
|
||||
|
||||
if (pvDim->getLength() != 0)
|
||||
{
|
||||
PVStructureArray::const_svector data = pvDim->view();
|
||||
size = getValueTypeSize();
|
||||
for (PVStructureArray::const_svector::const_iterator it = data.begin();
|
||||
it != data.end(); ++it )
|
||||
{
|
||||
PVStructurePtr dim = *it;
|
||||
size *= dim->getSubField<PVInt>("size")->get();
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int64 NTNDArray::getValueSize()
|
||||
{
|
||||
int64 size = 0;
|
||||
PVScalarArrayPtr storedValue = getValue()->get<PVScalarArray>();
|
||||
if (!storedValue.get())
|
||||
{
|
||||
size = storedValue->getLength()*getValueTypeSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int64 NTNDArray::getValueTypeSize()
|
||||
{
|
||||
int64 typeSize = 0;
|
||||
PVScalarArrayPtr storedValue = getValue()->get<PVScalarArray>();
|
||||
if (storedValue.get())
|
||||
{
|
||||
switch (storedValue->getScalarArray()->getElementType())
|
||||
{
|
||||
case pvBoolean:
|
||||
case pvByte:
|
||||
case pvUByte:
|
||||
typeSize = 1;
|
||||
break;
|
||||
|
||||
case pvShort:
|
||||
case pvUShort:
|
||||
typeSize = 2;
|
||||
break;
|
||||
|
||||
case pvInt:
|
||||
case pvUInt:
|
||||
case pvFloat:
|
||||
typeSize = 4;
|
||||
break;
|
||||
|
||||
case pvLong:
|
||||
case pvULong:
|
||||
case pvDouble:
|
||||
typeSize = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return typeSize;
|
||||
}
|
||||
|
||||
NTNDArrayBuilderPtr NTNDArray::createBuilder()
|
||||
{
|
||||
return NTNDArrayBuilderPtr(new detail::NTNDArrayBuilder());
|
||||
}
|
||||
|
||||
|
||||
bool NTNDArray::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTNDArray::attachDataTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
PVStructurePtr ts = getDataTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTNDArray::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStructurePtr NTNDArray::getPVStructure() const
|
||||
{
|
||||
return pvNTNDArray;
|
||||
}
|
||||
|
||||
PVUnionPtr NTNDArray::getValue() const
|
||||
{
|
||||
return pvNTNDArray->getSubField<PVUnion>("value");
|
||||
}
|
||||
|
||||
PVStructurePtr NTNDArray::getCodec() const
|
||||
{
|
||||
return pvNTNDArray->getSubField<PVStructure>("codec");
|
||||
}
|
||||
|
||||
PVLongPtr NTNDArray::getCompressedDataSize() const
|
||||
{
|
||||
return pvNTNDArray->getSubField<PVLong>("compressedSize");
|
||||
}
|
||||
|
||||
PVLongPtr NTNDArray::getUncompressedDataSize() const
|
||||
{
|
||||
return pvNTNDArray->getSubField<PVLong>("uncompressedSize");
|
||||
}
|
||||
|
||||
PVStructureArrayPtr NTNDArray::getDimension() const
|
||||
{
|
||||
return pvNTNDArray->getSubField<PVStructureArray>("dimension");
|
||||
}
|
||||
|
||||
PVIntPtr NTNDArray::getUniqueId() const
|
||||
{
|
||||
return pvNTNDArray->getSubField<PVInt>("uniqueId");
|
||||
}
|
||||
|
||||
PVStructurePtr NTNDArray::getDataTimeStamp() const
|
||||
{
|
||||
return pvNTNDArray->getSubField<PVStructure>("dataTimeStamp");
|
||||
}
|
||||
|
||||
PVStructureArrayPtr NTNDArray::getAttribute() const
|
||||
{
|
||||
return pvNTNDArray->getSubField<PVStructureArray>("attribute");
|
||||
}
|
||||
|
||||
PVStringPtr NTNDArray::getDescriptor() const
|
||||
{
|
||||
return pvNTNDArray->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
PVStructurePtr NTNDArray::getTimeStamp() const
|
||||
{
|
||||
return pvNTNDArray->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVStructurePtr NTNDArray::getAlarm() const
|
||||
{
|
||||
return pvNTNDArray->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
PVStructurePtr NTNDArray::getDisplay() const
|
||||
{
|
||||
return pvNTNDArray->getSubField<PVStructure>("display");
|
||||
}
|
||||
|
||||
|
||||
NTNDArray::NTNDArray(PVStructurePtr const & pvStructure) :
|
||||
pvNTNDArray(pvStructure)
|
||||
{}
|
||||
|
||||
|
||||
}}
|
||||
319
src/nt/ntndarray.h
Normal file
319
src/nt/ntndarray.h
Normal file
@@ -0,0 +1,319 @@
|
||||
/* ntndarray.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTNDARRAY_H
|
||||
#define NTNDARRAY_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntscalarArrayEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/pvDisplay.h>
|
||||
#include <pv/pvControl.h>
|
||||
|
||||
#ifdef ntscalarArrayEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntscalarArrayEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTNDArray;
|
||||
typedef std::tr1::shared_ptr<NTNDArray> NTNDArrayPtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTNDArray.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author mse
|
||||
*/
|
||||
class epicsShareClass NTNDArrayBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTNDArrayBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTNDArrayBuilder);
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTNDArray.
|
||||
* @return this instance of <b>NTNDArrayBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTNDArray.
|
||||
* @return this instance of <b>NTNDArrayBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTNDArray.
|
||||
* @return this instance of <b>NTNDArrayBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Add display structure to the NTNDArray.
|
||||
* @return this instance of <b>NTNDArrayBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDisplay();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTNDArray.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTNDArray.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>PVStructure</b>
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTNDArray</b> instance.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>NTNDArray</b>
|
||||
*/
|
||||
NTNDArrayPtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of a <b>NTArrayBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
private:
|
||||
NTNDArrayBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
bool descriptor;
|
||||
bool timeStamp;
|
||||
bool alarm;
|
||||
bool display;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTNDArray;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTNDArrayBuilder> NTNDArrayBuilderPtr;
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTNDArray
|
||||
*
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTNDArray
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTNDArray);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTNDArray.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTNDArray.
|
||||
* @return NTNDArray instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTNDArray without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTNDArray.
|
||||
* @return NTNDArray instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTNDArray.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTNDArray.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTNDArray.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTNDArray.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTNDArray.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTNDArray.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTNDArray.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTNDArray.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTNDArray.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTNDArray
|
||||
* @return (false,true) if (is not, is) a valid NTNDArray.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTNDArrayBuilder instance
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTNDArrayBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTNDArray() {}
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp to timeStamp field.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp to dataTimeStamp field.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachDataTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the value field.
|
||||
* @return The PVField for the values.
|
||||
*/
|
||||
epics::pvData::PVUnionPtr getValue() const;
|
||||
|
||||
/**
|
||||
* Get the codec field.
|
||||
* @return the PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getCodec() const;
|
||||
|
||||
/**
|
||||
* Get the compressedDataSize field.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVLongPtr getCompressedDataSize() const;
|
||||
|
||||
/**
|
||||
* Get the uncompressedDataSize field.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVLongPtr getUncompressedDataSize() const;
|
||||
|
||||
/**
|
||||
* Get the dimension field.
|
||||
* @return the PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructureArrayPtr getDimension() const;
|
||||
|
||||
/**
|
||||
* Get the uniqueId field.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVIntPtr getUniqueId() const;
|
||||
|
||||
/**
|
||||
* Get the data timeStamp field.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getDataTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the attribute field.
|
||||
* @return the PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructureArrayPtr getAttribute() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp field.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm field.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the display field.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getDisplay() const;
|
||||
|
||||
private:
|
||||
NTNDArray(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
epics::pvData::int64 getExpectedUncompressedSize();
|
||||
epics::pvData::int64 getValueSize();
|
||||
epics::pvData::int64 getValueTypeSize();
|
||||
|
||||
epics::pvData::PVStructurePtr pvNTNDArray;
|
||||
|
||||
friend class detail::NTNDArrayBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTNDARRAY_H */
|
||||
237
src/nt/ntndarrayAttribute.cpp
Normal file
237
src/nt/ntndarrayAttribute.cpp
Normal file
@@ -0,0 +1,237 @@
|
||||
/* ntndarrayAttribute.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntndarrayAttribute.h>
|
||||
#include <pv/ntattribute.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
StructureConstPtr NTNDArrayAttributeBuilder::createStructure()
|
||||
{
|
||||
FieldBuilderPtr builder =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId(NTNDArrayAttribute::URI)->
|
||||
add("name", pvString)->
|
||||
add("value", getFieldCreate()->createVariantUnion());
|
||||
|
||||
if (tags)
|
||||
builder->addArray("tags", pvString);
|
||||
|
||||
builder->add("descriptor", pvString);
|
||||
|
||||
builder->add("sourceType", pvInt);
|
||||
|
||||
builder->add("source", pvString);
|
||||
|
||||
if (alarm)
|
||||
builder->add("alarm", ntField->createAlarm());
|
||||
|
||||
if (timeStamp)
|
||||
builder->add("timeStamp", ntField->createTimeStamp());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTNDArrayAttributeBuilder::shared_pointer NTNDArrayAttributeBuilder::addTags()
|
||||
{
|
||||
tags = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTNDArrayAttributeBuilder::shared_pointer NTNDArrayAttributeBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTNDArrayAttributeBuilder::shared_pointer NTNDArrayAttributeBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTNDArrayAttributeBuilder::shared_pointer NTNDArrayAttributeBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
PVStructurePtr NTNDArrayAttributeBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTNDArrayAttributePtr NTNDArrayAttributeBuilder::create()
|
||||
{
|
||||
return NTNDArrayAttributePtr(new NTNDArrayAttribute(createPVStructure()));
|
||||
}
|
||||
|
||||
NTNDArrayAttributeBuilder::NTNDArrayAttributeBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTNDArrayAttributeBuilder::reset()
|
||||
{
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
}
|
||||
|
||||
NTNDArrayAttributeBuilder::shared_pointer NTNDArrayAttributeBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string NTNDArrayAttribute::URI("epics:nt/NTAttribute:1.0");
|
||||
|
||||
NTNDArrayAttribute::shared_pointer NTNDArrayAttribute::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTNDArrayAttribute::shared_pointer NTNDArrayAttribute::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTNDArrayAttribute(structure));
|
||||
}
|
||||
|
||||
bool NTNDArrayAttribute::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTNDArrayAttribute::isCompatible(StructureConstPtr const & structure)
|
||||
{
|
||||
if (!NTAttribute::isCompatible(structure)) return false;
|
||||
|
||||
// descriptor required field for attibute in an ndarray
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (descriptorField.get() == 0 || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
|
||||
ScalarConstPtr sourcedTypeField = structure->getField<Scalar>("sourceType");
|
||||
if (sourcedTypeField.get() == 0 || sourcedTypeField->getScalarType() != pvInt)
|
||||
return false;
|
||||
|
||||
ScalarConstPtr sourcedField = structure->getField<Scalar>("source");
|
||||
if (sourcedField.get() == 0 || sourcedField->getScalarType() != pvString)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NTNDArrayAttribute::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(!pvStructure) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTNDArrayAttribute::isValid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NTNDArrayAttributeBuilderPtr NTNDArrayAttribute::createBuilder()
|
||||
{
|
||||
return NTNDArrayAttributeBuilderPtr(new detail::NTNDArrayAttributeBuilder());
|
||||
}
|
||||
|
||||
bool NTNDArrayAttribute::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTNDArrayAttribute::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStructurePtr NTNDArrayAttribute::getPVStructure() const
|
||||
{
|
||||
return pvNTNDArrayAttribute;
|
||||
}
|
||||
|
||||
PVStringPtr NTNDArrayAttribute::getDescriptor() const
|
||||
{
|
||||
return pvNTNDArrayAttribute->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
PVStructurePtr NTNDArrayAttribute::getTimeStamp() const
|
||||
{
|
||||
return pvNTNDArrayAttribute->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVStructurePtr NTNDArrayAttribute::getAlarm() const
|
||||
{
|
||||
return pvNTNDArrayAttribute->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
|
||||
PVStringPtr NTNDArrayAttribute::getName() const
|
||||
{
|
||||
return pvNTNDArrayAttribute->getSubField<PVString>("name");
|
||||
}
|
||||
|
||||
PVUnionPtr NTNDArrayAttribute::getValue() const
|
||||
{
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
PVStringArrayPtr NTNDArrayAttribute::getTags() const
|
||||
{
|
||||
return pvNTNDArrayAttribute->getSubField<PVStringArray>("tags");
|
||||
}
|
||||
|
||||
PVIntPtr NTNDArrayAttribute::getSourceType() const
|
||||
{
|
||||
return pvNTNDArrayAttribute->getSubField<PVInt>("sourceType");
|
||||
}
|
||||
|
||||
PVStringPtr NTNDArrayAttribute::getSource() const
|
||||
{
|
||||
return pvNTNDArrayAttribute->getSubField<PVString>("source");
|
||||
}
|
||||
|
||||
NTNDArrayAttribute::NTNDArrayAttribute(PVStructurePtr const & pvStructure) :
|
||||
pvNTNDArrayAttribute(pvStructure), pvValue(pvNTNDArrayAttribute->getSubField<PVUnion>("value"))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
279
src/nt/ntndarrayAttribute.h
Normal file
279
src/nt/ntndarrayAttribute.h
Normal file
@@ -0,0 +1,279 @@
|
||||
/* ntndarrayAttribute.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTNDARRAYATTRIBUTE_H
|
||||
#define NTNDARRAYATTRIBUTE_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntndarrayAttributeEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#ifdef ntndarrayAttributeEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntndarrayAttributeEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTNDArrayAttribute;
|
||||
typedef std::tr1::shared_ptr<NTNDArrayAttribute> NTNDArrayAttributePtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTAttribute extended as required by NTNDArray
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTNDArrayAttributeBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTNDArrayAttributeBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTNDArrayAttributeBuilder);
|
||||
|
||||
/**
|
||||
* Add tags field to the NTNDArrayAttribute.
|
||||
* @return this instance of <b>NTNDArrayAttributeBuilder</b>.
|
||||
*/
|
||||
virtual shared_pointer addTags();
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTNDArrayAttribute.
|
||||
* @return this instance of <b>NTNDArrayAttributeBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTNDArrayAttribute.
|
||||
* @return this instance of <b>NTNDArrayAttributeBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTNDArrayAttribute.
|
||||
* @return this instance of <b>NTNDArrayAttributeBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTNDArrayAttribute.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTNDArrayAttribute.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>PVStructure</b>.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTNDArrayAttribute</b> instance.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>NTNDArrayAttribute</b>.
|
||||
*/
|
||||
NTNDArrayAttributePtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTNDArrayAttributeBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
protected://private:
|
||||
NTNDArrayAttributeBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
bool tags;
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTNDArrayAttribute;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTNDArrayAttributeBuilder> NTNDArrayAttributeBuilderPtr;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @briVIntPtref Convenience Class for NTNDArrayAttribute
|
||||
*
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTNDArrayAttribute
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTNDArrayAttribute);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTNDArrayAttribute.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTNDArrayAttribute.
|
||||
* @return NTNDArrayAttribute instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTNDArrayAttribute without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTNDArrayAttribute.
|
||||
* @return NTNDArrayAttribute instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTNDArrayAttribute.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTNDArrayAttribute.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTNDArrayAttribute.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTNDArrayAttribute.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTNDArrayAttribute.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTNDArrayAttribute.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTNDArrayAttribute.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTNDArrayAttribute.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTNDArrayAttribute.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTNDArrayAttribute
|
||||
* @return (false,true) if (is not, is) a valid NTNDArrayAttribute.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTNDArrayAttribute builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTNDArrayAttributeBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTNDArrayAttribute() {}
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the name field.
|
||||
* @return The PVString for the name.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getName() const;
|
||||
|
||||
/**
|
||||
* Get the value field.
|
||||
* @return The PVUnion for the values.
|
||||
*/
|
||||
epics::pvData::PVUnionPtr getValue() const;
|
||||
|
||||
/**
|
||||
* Get the tags field.
|
||||
* @return The PVStringArray for the tags, which may be null.
|
||||
*/
|
||||
epics::pvData::PVStringArrayPtr getTags() const;
|
||||
|
||||
/**
|
||||
* Get the sourceType field.
|
||||
* @return The PVInt for the sourceType field.
|
||||
*/
|
||||
epics::pvData::PVIntPtr getSourceType() const;
|
||||
|
||||
/**
|
||||
* Get the source field.
|
||||
* @return The PVString for the source field, which may be null.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getSource() const;
|
||||
|
||||
private:
|
||||
NTNDArrayAttribute(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTNDArrayAttribute;
|
||||
epics::pvData::PVUnionPtr pvValue;
|
||||
|
||||
friend class detail::NTNDArrayAttributeBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTNDARRAYATTRIBUTE_H */
|
||||
280
src/nt/ntscalar.cpp
Normal file
280
src/nt/ntscalar.cpp
Normal file
@@ -0,0 +1,280 @@
|
||||
/* ntscalar.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntscalar.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
NTScalarBuilder::shared_pointer NTScalarBuilder::value(
|
||||
epics::pvData::ScalarType scalarType
|
||||
)
|
||||
{
|
||||
valueType = scalarType;
|
||||
valueTypeSet = true;
|
||||
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
StructureConstPtr NTScalarBuilder::createStructure()
|
||||
{
|
||||
if (!valueTypeSet)
|
||||
throw std::runtime_error("value type not set");
|
||||
|
||||
FieldBuilderPtr builder =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId(NTScalar::URI)->
|
||||
add("value", valueType);
|
||||
|
||||
if (descriptor)
|
||||
builder->add("descriptor", pvString);
|
||||
|
||||
if (alarm)
|
||||
builder->add("alarm", ntField->createAlarm());
|
||||
|
||||
if (timeStamp)
|
||||
builder->add("timeStamp", ntField->createTimeStamp());
|
||||
|
||||
if (display)
|
||||
builder->add("display", ntField->createDisplay());
|
||||
|
||||
if (control)
|
||||
builder->add("control", ntField->createControl());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTScalarBuilder::shared_pointer NTScalarBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarBuilder::shared_pointer NTScalarBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarBuilder::shared_pointer NTScalarBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarBuilder::shared_pointer NTScalarBuilder::addDisplay()
|
||||
{
|
||||
display = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarBuilder::shared_pointer NTScalarBuilder::addControl()
|
||||
{
|
||||
control = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalarBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTScalarPtr NTScalarBuilder::create()
|
||||
{
|
||||
return NTScalarPtr(new NTScalar(createPVStructure()));
|
||||
}
|
||||
|
||||
NTScalarBuilder::NTScalarBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTScalarBuilder::reset()
|
||||
{
|
||||
valueTypeSet = false;
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
display = false;
|
||||
control = false;
|
||||
}
|
||||
|
||||
NTScalarBuilder::shared_pointer NTScalarBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const std::string NTScalar::URI("epics:nt/NTScalar:1.0");
|
||||
|
||||
NTScalar::shared_pointer NTScalar::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTScalar::shared_pointer NTScalar::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTScalar(structure));
|
||||
}
|
||||
|
||||
bool NTScalar::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTScalar::isCompatible(StructureConstPtr const &structure)
|
||||
{
|
||||
if (structure.get() == 0) return false;
|
||||
|
||||
ScalarConstPtr valueField = structure->getField<Scalar>("value");
|
||||
if (valueField.get() == 0)
|
||||
return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("display");
|
||||
if (field.get() && !ntField->isDisplay(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("control");
|
||||
if (field.get() && !ntField->isControl(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NTScalar::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(!pvStructure) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTScalar::isValid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NTScalarBuilderPtr NTScalar::createBuilder()
|
||||
{
|
||||
return NTScalarBuilderPtr(new detail::NTScalarBuilder());
|
||||
}
|
||||
|
||||
bool NTScalar::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTScalar::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTScalar::attachDisplay(PVDisplay &pvDisplay) const
|
||||
{
|
||||
PVStructurePtr dp = getDisplay();
|
||||
if (dp)
|
||||
return pvDisplay.attach(dp);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTScalar::attachControl(PVControl &pvControl) const
|
||||
{
|
||||
PVStructurePtr ctrl = getControl();
|
||||
if (ctrl)
|
||||
return pvControl.attach(ctrl);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalar::getPVStructure() const
|
||||
{
|
||||
return pvNTScalar;
|
||||
}
|
||||
|
||||
PVStringPtr NTScalar::getDescriptor() const
|
||||
{
|
||||
return pvNTScalar->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalar::getTimeStamp() const
|
||||
{
|
||||
return pvNTScalar->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalar::getAlarm() const
|
||||
{
|
||||
return pvNTScalar->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalar::getDisplay() const
|
||||
{
|
||||
return pvNTScalar->getSubField<PVStructure>("display");
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalar::getControl() const
|
||||
{
|
||||
return pvNTScalar->getSubField<PVStructure>("control");
|
||||
}
|
||||
|
||||
PVFieldPtr NTScalar::getValue() const
|
||||
{
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
NTScalar::NTScalar(PVStructurePtr const & pvStructure) :
|
||||
pvNTScalar(pvStructure), pvValue(pvNTScalar->getSubField("value"))
|
||||
{}
|
||||
|
||||
|
||||
}}
|
||||
313
src/nt/ntscalar.h
Normal file
313
src/nt/ntscalar.h
Normal file
@@ -0,0 +1,313 @@
|
||||
/* ntscalar.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTSCALAR_H
|
||||
#define NTSCALAR_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntscalarEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/pvDisplay.h>
|
||||
#include <pv/pvControl.h>
|
||||
|
||||
#ifdef ntscalarEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntscalarEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTScalar;
|
||||
typedef std::tr1::shared_ptr<NTScalar> NTScalarPtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTScalar.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author mse
|
||||
*/
|
||||
class epicsShareClass NTScalarBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTScalarBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTScalarBuilder);
|
||||
|
||||
/**
|
||||
* Set a value type of a NTScalar.
|
||||
* @param scalarType the value type.
|
||||
* @return this instance of <b>NTScalarBuilder</b>.
|
||||
*/
|
||||
shared_pointer value(epics::pvData::ScalarType scalarType);
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTScalar.
|
||||
* @return this instance of <b>NTScalarBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTScalar.
|
||||
* @return this instance of <b>NTScalarBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTScalar.
|
||||
* @return this instance of <b>NTScalarBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Add display structure to the NTScalar.
|
||||
* @return this instance of <b>NTScalarBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDisplay();
|
||||
|
||||
/**
|
||||
* Add control structure to the NTScalar.
|
||||
* @return this instance of <b>NTScalarBuilder</b>.
|
||||
*/
|
||||
shared_pointer addControl();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTScalar.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTScalar.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>PVStructure</b>.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTScalar</b> instance.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>NTScalar</b>.
|
||||
*/
|
||||
NTScalarPtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTScalarBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
private:
|
||||
NTScalarBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
bool valueTypeSet;
|
||||
epics::pvData::ScalarType valueType;
|
||||
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
bool display;
|
||||
bool control;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTScalar;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTScalarBuilder> NTScalarBuilderPtr;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTScalar
|
||||
*
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass NTScalar
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTScalar);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTScalar.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTScalar.
|
||||
* @return NTScalar instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTMultiChannel without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTScalar.
|
||||
* @return NTScalar instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTScalar.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalar.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTScalar.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalar.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTScalar.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalar.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTScalar.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalar.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTScalar.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTScalar
|
||||
* @return (false,true) if (is not, is) a valid NTScalar.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTScalar builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTScalarBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTScalar() {}
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Attach an pvDisplay.
|
||||
* @param pvDisplay The pvDisplay that will be attached.
|
||||
* Does nothing if no display.
|
||||
* @return true if the operation was successfull (i.e. this instance has a display field), otherwise false.
|
||||
*/
|
||||
bool attachDisplay(epics::pvData::PVDisplay &pvDisplay) const;
|
||||
|
||||
/**
|
||||
* Attach an pvControl.
|
||||
* @param pvControl The pvControl that will be attached.
|
||||
* Does nothing if no control.
|
||||
* @return true if the operation was successfull (i.e. this instance has a control field), otherwise false.
|
||||
*/
|
||||
bool attachControl(epics::pvData::PVControl &pvControl) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the display.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getDisplay() const;
|
||||
|
||||
/**
|
||||
* Get the control.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getControl() const;
|
||||
|
||||
/**
|
||||
* Get the value field.
|
||||
* @return The PVField for the values.
|
||||
*/
|
||||
epics::pvData::PVFieldPtr getValue() const;
|
||||
|
||||
/**
|
||||
* Get the value field of a specified type (e.g. PVDouble).
|
||||
* @return The <PVT> field for the values.
|
||||
*/
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getValue() const
|
||||
{
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(pvValue);
|
||||
}
|
||||
|
||||
private:
|
||||
NTScalar(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTScalar;
|
||||
epics::pvData::PVFieldPtr pvValue;
|
||||
|
||||
friend class detail::NTScalarBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTSCALAR_H */
|
||||
278
src/nt/ntscalarArray.cpp
Normal file
278
src/nt/ntscalarArray.cpp
Normal file
@@ -0,0 +1,278 @@
|
||||
/* ntscalarArray.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntscalarArray.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
NTScalarArrayBuilder::shared_pointer NTScalarArrayBuilder::arrayValue(
|
||||
epics::pvData::ScalarType elementType
|
||||
)
|
||||
{
|
||||
valueType = elementType;
|
||||
valueTypeSet = true;
|
||||
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
StructureConstPtr NTScalarArrayBuilder::createStructure()
|
||||
{
|
||||
if (!valueTypeSet)
|
||||
throw std::runtime_error("value array element type not set");
|
||||
|
||||
FieldBuilderPtr builder =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId(NTScalarArray::URI)->
|
||||
addArray("value", valueType);
|
||||
|
||||
if (descriptor)
|
||||
builder->add("descriptor", pvString);
|
||||
|
||||
if (alarm)
|
||||
builder->add("alarm", ntField->createAlarm());
|
||||
|
||||
if (timeStamp)
|
||||
builder->add("timeStamp", ntField->createTimeStamp());
|
||||
|
||||
if (display)
|
||||
builder->add("display", ntField->createDisplay());
|
||||
|
||||
if (control)
|
||||
builder->add("control", ntField->createControl());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTScalarArrayBuilder::shared_pointer NTScalarArrayBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarArrayBuilder::shared_pointer NTScalarArrayBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarArrayBuilder::shared_pointer NTScalarArrayBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarArrayBuilder::shared_pointer NTScalarArrayBuilder::addDisplay()
|
||||
{
|
||||
display = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarArrayBuilder::shared_pointer NTScalarArrayBuilder::addControl()
|
||||
{
|
||||
control = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalarArrayBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTScalarArrayPtr NTScalarArrayBuilder::create()
|
||||
{
|
||||
return NTScalarArrayPtr(new NTScalarArray(createPVStructure()));
|
||||
}
|
||||
|
||||
NTScalarArrayBuilder::NTScalarArrayBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTScalarArrayBuilder::reset()
|
||||
{
|
||||
valueTypeSet = false;
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
display = false;
|
||||
control = false;
|
||||
}
|
||||
|
||||
NTScalarArrayBuilder::shared_pointer NTScalarArrayBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string NTScalarArray::URI("epics:nt/NTScalarArray:1.0");
|
||||
|
||||
NTScalarArray::shared_pointer NTScalarArray::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTScalarArray::shared_pointer NTScalarArray::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTScalarArray(structure));
|
||||
}
|
||||
|
||||
bool NTScalarArray::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTScalarArray::isCompatible(StructureConstPtr const & structure)
|
||||
{
|
||||
if (structure.get() == 0) return false;
|
||||
|
||||
ScalarArrayConstPtr valueField = structure->getField<ScalarArray>("value");
|
||||
if (valueField.get() == 0)
|
||||
return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("display");
|
||||
if (field.get() && !ntField->isDisplay(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("control");
|
||||
if (field.get() && !ntField->isControl(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NTScalarArray::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(!pvStructure) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTScalarArray::isValid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NTScalarArrayBuilderPtr NTScalarArray::createBuilder()
|
||||
{
|
||||
return NTScalarArrayBuilderPtr(new detail::NTScalarArrayBuilder());
|
||||
}
|
||||
|
||||
bool NTScalarArray::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTScalarArray::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTScalarArray::attachDisplay(PVDisplay &pvDisplay) const
|
||||
{
|
||||
PVStructurePtr dp = getDisplay();
|
||||
if (dp)
|
||||
return pvDisplay.attach(dp);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTScalarArray::attachControl(PVControl &pvControl) const
|
||||
{
|
||||
PVStructurePtr ctrl = getControl();
|
||||
if (ctrl)
|
||||
return pvControl.attach(ctrl);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalarArray::getPVStructure() const
|
||||
{
|
||||
return pvNTScalarArray;
|
||||
}
|
||||
|
||||
PVStringPtr NTScalarArray::getDescriptor() const
|
||||
{
|
||||
return pvNTScalarArray->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalarArray::getTimeStamp() const
|
||||
{
|
||||
return pvNTScalarArray->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalarArray::getAlarm() const
|
||||
{
|
||||
return pvNTScalarArray->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalarArray::getDisplay() const
|
||||
{
|
||||
return pvNTScalarArray->getSubField<PVStructure>("display");
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalarArray::getControl() const
|
||||
{
|
||||
return pvNTScalarArray->getSubField<PVStructure>("control");
|
||||
}
|
||||
|
||||
PVFieldPtr NTScalarArray::getValue() const
|
||||
{
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
NTScalarArray::NTScalarArray(PVStructurePtr const & pvStructure) :
|
||||
pvNTScalarArray(pvStructure), pvValue(pvNTScalarArray->getSubField("value"))
|
||||
{}
|
||||
|
||||
|
||||
}}
|
||||
314
src/nt/ntscalarArray.h
Normal file
314
src/nt/ntscalarArray.h
Normal file
@@ -0,0 +1,314 @@
|
||||
/* ntscalarArray.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTSCALARARRAY_H
|
||||
#define NTSCALARARRAY_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntscalarArrayEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/pvDisplay.h>
|
||||
#include <pv/pvControl.h>
|
||||
|
||||
#ifdef ntscalarArrayEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntscalarArrayEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTScalarArray;
|
||||
typedef std::tr1::shared_ptr<NTScalarArray> NTScalarArrayPtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTScalarArray.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author mse
|
||||
*/
|
||||
class epicsShareClass NTScalarArrayBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTScalarArrayBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTScalarArrayBuilder);
|
||||
|
||||
/**
|
||||
* Set a value type of a NTScalarArray.
|
||||
* @param elementType the value array element type.
|
||||
* @return this instance of <b>NTScalarArrayBuilder</b>.
|
||||
*/
|
||||
shared_pointer arrayValue(epics::pvData::ScalarType elementType);
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTScalarArray.
|
||||
* @return this instance of <b>NTScalarArrayBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTScalarArray.
|
||||
* @return this instance of <b>NTScalarArrayBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTScalarArray.
|
||||
* @return this instance of <b>NTScalarArrayBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Add display structure to the NTScalarArray.
|
||||
* @return this instance of <b>NTScalarArrayBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDisplay();
|
||||
|
||||
/**
|
||||
* Add control structure to the NTScalarArray.
|
||||
* @return this instance of <b>NTScalarArrayBuilder</b>.
|
||||
*/
|
||||
shared_pointer addControl();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTScalarArray.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTScalarArray.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>PVStructure</b>.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTScalarArray</b> instance.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>NTScalarArray</b>.
|
||||
*/
|
||||
NTScalarArrayPtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTScalarArrayBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
private:
|
||||
NTScalarArrayBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
bool valueTypeSet;
|
||||
epics::pvData::ScalarType valueType;
|
||||
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
bool display;
|
||||
bool control;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTScalarArray;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTScalarArrayBuilder> NTScalarArrayBuilderPtr;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTScalarArray
|
||||
*
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass NTScalarArray
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTScalarArray);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTScalarArray.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTScalarArray.
|
||||
* @return NTScalarArray instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTMatrix without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTScalarArray.
|
||||
* @return NTScalarArray instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTScalarArray.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalarArray.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTScalarArray.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalarArray.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTScalarArray.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalarArray.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTScalarArray.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalarArray.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTScalarArray.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTScalarArray
|
||||
* @return (false,true) if (is not, is) a valid NTScalarArray.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTScalarArray builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTScalarArrayBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTScalarArray() {}
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Attach an pvDisplay.
|
||||
* @param pvDisplay The pvDisplay that will be attached.
|
||||
* Does nothing if no display.
|
||||
* @return true if the operation was successfull (i.e. this instance has a display field), otherwise false.
|
||||
*/
|
||||
bool attachDisplay(epics::pvData::PVDisplay &pvDisplay) const;
|
||||
|
||||
/**
|
||||
* Attach an pvControl.
|
||||
* @param pvControl The pvControl that will be attached.
|
||||
* Does nothing if no control.
|
||||
* @return true if the operation was successfull (i.e. this instance has a control field), otherwise false.
|
||||
*/
|
||||
bool attachControl(epics::pvData::PVControl &pvControl) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the display.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getDisplay() const;
|
||||
|
||||
/**
|
||||
* Get the control.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getControl() const;
|
||||
|
||||
/**
|
||||
* Get the value field.
|
||||
* @return The PVField for the values.
|
||||
*/
|
||||
epics::pvData::PVFieldPtr getValue() const;
|
||||
|
||||
/**
|
||||
* Get the value field of a specified type (e.g. PVDoubleArray).
|
||||
* @return The <PVT> field for the values.
|
||||
*/
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getValue() const
|
||||
{
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(pvValue);
|
||||
}
|
||||
|
||||
private:
|
||||
NTScalarArray(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTScalarArray;
|
||||
epics::pvData::PVFieldPtr pvValue;
|
||||
|
||||
friend class detail::NTScalarArrayBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTSCALARARRAY_H */
|
||||
377
src/nt/ntscalarMultiChannel.cpp
Normal file
377
src/nt/ntscalarMultiChannel.cpp
Normal file
@@ -0,0 +1,377 @@
|
||||
/* ntscalarMultiChannel.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntscalarMultiChannel.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::value(ScalarType scalarType)
|
||||
{
|
||||
valueType = scalarType;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addSeverity()
|
||||
{
|
||||
severity = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addStatus()
|
||||
{
|
||||
status = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addMessage()
|
||||
{
|
||||
message = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addSecondsPastEpoch()
|
||||
{
|
||||
secondsPastEpoch = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addNanoseconds()
|
||||
{
|
||||
nanoseconds = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addUserTag()
|
||||
{
|
||||
userTag = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addIsConnected()
|
||||
{
|
||||
isConnected = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
StructureConstPtr NTScalarMultiChannelBuilder::createStructure()
|
||||
{
|
||||
StandardFieldPtr standardField = getStandardField();
|
||||
size_t nfields = 2;
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
nfields += extraCount;
|
||||
if(descriptor) ++nfields;
|
||||
if(alarm) ++nfields;
|
||||
if(timeStamp) ++nfields;
|
||||
if(severity) ++nfields;
|
||||
if(status) ++nfields;
|
||||
if(message) ++nfields;
|
||||
if(secondsPastEpoch) ++nfields;
|
||||
if(nanoseconds) ++nfields;
|
||||
if(userTag) ++nfields;
|
||||
if(isConnected) ++nfields;
|
||||
FieldConstPtrArray fields(nfields);
|
||||
StringArray names(nfields);
|
||||
size_t ind = 0;
|
||||
names[ind] = "value";
|
||||
fields[ind++] = fieldCreate->createScalarArray(valueType);
|
||||
names[ind] = "channelName";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvString);
|
||||
if(descriptor) {
|
||||
names[ind] = "descriptor";
|
||||
fields[ind++] = fieldCreate->createScalar(pvString);
|
||||
}
|
||||
if(alarm) {
|
||||
names[ind] = "alarm";
|
||||
fields[ind++] = standardField->alarm();
|
||||
}
|
||||
if(timeStamp) {
|
||||
names[ind] = "timeStamp";
|
||||
fields[ind++] = standardField->timeStamp();
|
||||
}
|
||||
if(severity) {
|
||||
names[ind] = "severity";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvInt);
|
||||
}
|
||||
if(status) {
|
||||
names[ind] = "status";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvInt);
|
||||
}
|
||||
if(message) {
|
||||
names[ind] = "message";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvString);
|
||||
}
|
||||
if(secondsPastEpoch) {
|
||||
names[ind] = "secondsPastEpoch";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvLong);
|
||||
}
|
||||
if(nanoseconds) {
|
||||
names[ind] = "nanoseconds";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvInt);
|
||||
}
|
||||
if(userTag) {
|
||||
names[ind] = "userTag";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvInt);
|
||||
}
|
||||
if(isConnected) {
|
||||
names[ind] = "isConnected";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvBoolean);
|
||||
}
|
||||
for (size_t i = 0; i< extraCount; i++) {
|
||||
names[ind] = extraFieldNames[i];
|
||||
fields[ind++] = extraFields[i];
|
||||
}
|
||||
|
||||
StructureConstPtr st = fieldCreate->createStructure(NTScalarMultiChannel::URI,names,fields);
|
||||
reset();
|
||||
return st;
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalarMultiChannelBuilder::createPVStructure()
|
||||
{
|
||||
return pvDataCreate->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTScalarMultiChannelPtr NTScalarMultiChannelBuilder::create()
|
||||
{
|
||||
return NTScalarMultiChannelPtr(new NTScalarMultiChannel(createPVStructure()));
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::NTScalarMultiChannelBuilder()
|
||||
: valueType(pvDouble)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTScalarMultiChannelBuilder::reset()
|
||||
{
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
valueType = pvDouble;
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
severity = false;
|
||||
status = false;
|
||||
message = false;
|
||||
secondsPastEpoch = false;
|
||||
nanoseconds = false;
|
||||
userTag = false;
|
||||
isConnected = false;
|
||||
}
|
||||
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string NTScalarMultiChannel::URI("epics:nt/NTScalarMultiChannel:1.0");
|
||||
|
||||
NTScalarMultiChannel::shared_pointer NTScalarMultiChannel::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTScalarMultiChannel::shared_pointer NTScalarMultiChannel::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTScalarMultiChannel(structure));
|
||||
}
|
||||
|
||||
bool NTScalarMultiChannel::is_a(StructureConstPtr const &structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
|
||||
bool NTScalarMultiChannel::isCompatible(StructureConstPtr const & structure)
|
||||
{
|
||||
if (!structure.get()) return false;
|
||||
|
||||
ScalarArrayConstPtr valueField = structure->getField<ScalarArray>("value");
|
||||
if (!valueField.get()) return false;
|
||||
|
||||
ScalarArrayConstPtr channelNameField = structure->getField<ScalarArray>(
|
||||
"channelName");
|
||||
if (!channelNameField.get()) return false;
|
||||
if (channelNameField->getElementType() != pvString) return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("severity");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr severityField = structure->getField<ScalarArray>("severity");
|
||||
if (!severityField.get() || severityField->getElementType() != pvInt)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("status");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr statusField = structure->getField<ScalarArray>("status");
|
||||
if (!statusField.get() || statusField->getElementType() != pvInt)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("message");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr messageField = structure->getField<ScalarArray>("message");
|
||||
if (!messageField.get() || messageField->getElementType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("secondsPastEpoch");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr secondsPastEpochField = structure->getField<ScalarArray>("secondsPastEpoch");
|
||||
if (!secondsPastEpochField.get() || secondsPastEpochField->getElementType() != pvLong)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("nanoseconds");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr nanosecondsField = structure->getField<ScalarArray>("nanoseconds");
|
||||
if (!nanosecondsField.get() || nanosecondsField->getElementType() != pvInt)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("userTag");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarArrayConstPtr userTagField = structure->getField<ScalarArray>("userTag");
|
||||
if (!userTagField.get() || userTagField->getElementType() != pvInt)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NTScalarMultiChannel::isCompatible(PVStructurePtr const &pvStructure)
|
||||
{
|
||||
if(!pvStructure.get()) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTScalarMultiChannel::isValid()
|
||||
{
|
||||
size_t valueLength = getValue()->getLength();
|
||||
if (getChannelName()->getLength() != valueLength) return false;
|
||||
|
||||
PVScalarArrayPtr arrayFields[] = {
|
||||
getSeverity(), getStatus(), getMessage(),
|
||||
getSecondsPastEpoch(), getNanoseconds(), getUserTag()
|
||||
};
|
||||
size_t N = sizeof(arrayFields)/sizeof(arrayFields[0]);
|
||||
|
||||
PVScalarArrayPtr arrayField;
|
||||
for (PVScalarArrayPtr * pa = arrayFields; pa != arrayFields+N; ++pa)
|
||||
{
|
||||
arrayField = *pa;
|
||||
if (arrayField.get() && arrayField->getLength() != valueLength)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilderPtr NTScalarMultiChannel::createBuilder()
|
||||
{
|
||||
return NTScalarMultiChannelBuilderPtr(new detail::NTScalarMultiChannelBuilder());
|
||||
}
|
||||
|
||||
|
||||
NTScalarMultiChannel::NTScalarMultiChannel(PVStructurePtr const & pvStructure)
|
||||
: pvNTScalarMultiChannel(pvStructure),
|
||||
pvTimeStamp(pvStructure->getSubField<PVStructure>("timeStamp")),
|
||||
pvAlarm(pvStructure->getSubField<PVStructure>("alarm")),
|
||||
pvValue(pvStructure->getSubField<PVScalarArray>("value")),
|
||||
pvChannelName(pvStructure->getSubField<PVStringArray>("channelName")),
|
||||
pvIsConnected(pvStructure->getSubField<PVBooleanArray>("isConnected")),
|
||||
pvSeverity(pvStructure->getSubField<PVIntArray>("severity")),
|
||||
pvStatus(pvStructure->getSubField<PVIntArray>("status")),
|
||||
pvMessage(pvStructure->getSubField<PVStringArray>("message")),
|
||||
pvSecondsPastEpoch(pvStructure->getSubField<PVLongArray>("secondsPastEpoch")),
|
||||
pvNanoseconds(pvStructure->getSubField<PVIntArray>("nanoseconds")),
|
||||
pvUserTag(pvStructure->getSubField<PVIntArray>("userTag")),
|
||||
pvDescriptor(pvStructure->getSubField<PVString>("descriptor"))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool NTScalarMultiChannel::attachTimeStamp(PVTimeStamp &pv) const
|
||||
{
|
||||
if (pvTimeStamp)
|
||||
return pv.attach(pvTimeStamp);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTScalarMultiChannel::attachAlarm(PVAlarm &pv) const
|
||||
{
|
||||
if (pvAlarm)
|
||||
return pv.attach(pvAlarm);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}}
|
||||
362
src/nt/ntscalarMultiChannel.h
Normal file
362
src/nt/ntscalarMultiChannel.h
Normal file
@@ -0,0 +1,362 @@
|
||||
/* ntscalarMultiChannel.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTSCALARMULTICHANNEL_H
|
||||
#define NTSCALARMULTICHANNEL_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntscalarMultiChannelEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/pvDisplay.h>
|
||||
#include <pv/pvControl.h>
|
||||
|
||||
#ifdef ntscalarMultiChannelEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntscalarMultiChannelEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
|
||||
class NTScalarMultiChannel;
|
||||
typedef std::tr1::shared_ptr<NTScalarMultiChannel> NTScalarMultiChannelPtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTScalarMultiChannel.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author dgh
|
||||
* @author mse
|
||||
*/
|
||||
class epicsShareClass NTScalarMultiChannelBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTScalarMultiChannelBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTScalarMultiChannelBuilder);
|
||||
/**
|
||||
* specify the scalar type for the value field.
|
||||
* If this is not called then pvDouble is the default.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer value(epics::pvData::ScalarType scalarType);
|
||||
/**
|
||||
* Add descriptor field to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
/**
|
||||
* Add alarm structure to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
/**
|
||||
* Add timeStamp structure to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
/**
|
||||
* Add severity array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addSeverity();
|
||||
/**
|
||||
* Add status array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addStatus();
|
||||
/**
|
||||
* Add message array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addMessage();
|
||||
/**
|
||||
* Add secondsPastEpoch array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addSecondsPastEpoch();
|
||||
/**
|
||||
* Add nanoseconds array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addNanoseconds();
|
||||
/**
|
||||
* Add userTag array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addUserTag();
|
||||
/**
|
||||
* Add isConnected array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addIsConnected();
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTScalarMultiChannel.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTScalarMultiChannel.
|
||||
* This resets this instance state and allows new {@code instance to be created.}
|
||||
* @return a new instance of a <b>PVStructure</b>
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
/**
|
||||
* Create a <b>NTScalarMultiChannel</b> instance.
|
||||
* This resets this instance state and allows new {@code instance to be created.}
|
||||
* @return a new instance of a <b>NTScalarMultiChannel</b>
|
||||
*/
|
||||
NTScalarMultiChannelPtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of a <b>NTScalarMultiChannelBuilder</b>
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
private:
|
||||
NTScalarMultiChannelBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
epics::pvData::ScalarType valueType;
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
bool severity;
|
||||
bool status;
|
||||
bool message;
|
||||
bool secondsPastEpoch;
|
||||
bool nanoseconds;
|
||||
bool userTag;
|
||||
bool isConnected;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTScalarMultiChannel;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTScalarMultiChannelBuilder> NTScalarMultiChannelBuilderPtr;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTScalarMultiChannel
|
||||
* @author dgh
|
||||
* @author mrk
|
||||
*
|
||||
*/
|
||||
class epicsShareClass NTScalarMultiChannel
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTScalarMultiChannel);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTScalarMultiChannel.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTScalarMultiChannel.
|
||||
* @return NTScalarMultiChannel instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTScalarMultiChannel without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTScalarMultiChannel.
|
||||
* @return NTScalarMultiChannel instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTScalarMultiChannel.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalarMultiChannel.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTScalarMultiChannel.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalarMultiChannel.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTScalarMultiChannel.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalarMultiChannel.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTScalarMultiChannel.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalarMultiChannel.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTScalarMultiChannel.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTScalarMultiChannel
|
||||
* @return (false,true) if (is not, is) a valid NTScalarMultiChannel.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTScalarMultiChannelBuilder instance
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTScalarMultiChannelBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~NTScalarMultiChannel() {}
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
/**
|
||||
* Attach a pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const
|
||||
{return pvNTScalarMultiChannel;}
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const
|
||||
{return pvTimeStamp;}
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const
|
||||
{return pvAlarm;}
|
||||
/**
|
||||
* Get the value of each channel.
|
||||
* @return PVScalarArrayPtr
|
||||
*/
|
||||
epics::pvData::PVScalarArrayPtr getValue() const
|
||||
{return pvValue;}
|
||||
/**
|
||||
* Get the value field of a specified type (e.g. PVDoubleArray).
|
||||
* @return The <PVT> field for the values.
|
||||
*/
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getValue() const
|
||||
{
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(pvValue);
|
||||
}
|
||||
/**
|
||||
* Get the channelName of each channel.
|
||||
* @return PVStringArrayPtr
|
||||
*/
|
||||
epics::pvData::PVStringArrayPtr getChannelName() const
|
||||
{ return pvChannelName;};
|
||||
/**
|
||||
* Get the connection state of each channel.
|
||||
* @return PVBooleanArrayPtr
|
||||
*/
|
||||
epics::pvData::PVBooleanArrayPtr getIsConnected() const
|
||||
{ return pvIsConnected;};
|
||||
/**
|
||||
* Get the severity of each channel.
|
||||
* @return PVIntArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getSeverity() const
|
||||
{return pvSeverity;}
|
||||
/**
|
||||
* Get the status of each channel.
|
||||
* @return PVIntArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getStatus() const
|
||||
{return pvStatus;}
|
||||
/**
|
||||
* Get the message of each chnnel.
|
||||
* @return PVStringArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStringArrayPtr getMessage() const
|
||||
{return pvMessage;}
|
||||
/**
|
||||
* Get the secondsPastEpoch of each channel.
|
||||
* @return PVLongArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVLongArrayPtr getSecondsPastEpoch() const
|
||||
{return pvSecondsPastEpoch;}
|
||||
/**
|
||||
* Get the nanoseconds of each channel.
|
||||
* @return PVIntArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getNanoseconds() const
|
||||
{return pvNanoseconds;}
|
||||
/**
|
||||
* Get the userTag of each channel.
|
||||
* @return PVIntArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getUserTag() const
|
||||
{return pvUserTag;}
|
||||
/**
|
||||
* Get the descriptor.
|
||||
* @return PVStringPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const
|
||||
{return pvDescriptor;}
|
||||
private:
|
||||
NTScalarMultiChannel(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTScalarMultiChannel;
|
||||
epics::pvData::PVStructurePtr pvTimeStamp;
|
||||
epics::pvData::PVStructurePtr pvAlarm;
|
||||
epics::pvData::PVScalarArrayPtr pvValue;
|
||||
epics::pvData::PVStringArrayPtr pvChannelName;
|
||||
epics::pvData::PVBooleanArrayPtr pvIsConnected;
|
||||
epics::pvData::PVIntArrayPtr pvSeverity;
|
||||
epics::pvData::PVIntArrayPtr pvStatus;
|
||||
epics::pvData::PVStringArrayPtr pvMessage;
|
||||
epics::pvData::PVLongArrayPtr pvSecondsPastEpoch;
|
||||
epics::pvData::PVIntArrayPtr pvNanoseconds;
|
||||
epics::pvData::PVIntArrayPtr pvUserTag;
|
||||
epics::pvData::PVStringPtr pvDescriptor;
|
||||
friend class detail::NTScalarMultiChannelBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTSCALARMULTICHANNEL_H */
|
||||
@@ -1,151 +1,282 @@
|
||||
/* nttable.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/nttable.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
namespace epics { namespace nt {
|
||||
|
||||
bool NTTable::isNTTable(PVStructurePtr const & pvStructure)
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
NTTableBuilder::shared_pointer NTTableBuilder::addColumn(
|
||||
std::string const & name, epics::pvData::ScalarType scalarType
|
||||
)
|
||||
{
|
||||
NTFieldPtr ntfield = NTField::get();
|
||||
PVStringArrayPtr pvLabel = static_pointer_cast<PVStringArray>
|
||||
(pvStructure->getScalarArrayField("label",pvString));
|
||||
if(pvLabel.get()==NULL) return false;
|
||||
size_t nfields = pvLabel->getLength();
|
||||
size_t nextra = 1; // label is 1 field
|
||||
PVFieldPtr pvField = pvStructure->getSubField("function");
|
||||
if(pvField.get()!=NULL
|
||||
&& pvStructure->getStringField("function").get()!=NULL) nextra++;
|
||||
pvField = pvStructure->getSubField("timeStamp");
|
||||
if(pvField!=0 && ntfield->isTimeStamp(pvField->getField())) {
|
||||
nextra++;
|
||||
}
|
||||
pvField = pvStructure->getSubField("alarm");
|
||||
if(pvField.get()!=NULL && ntfield->isAlarm(pvField->getField())) {
|
||||
nextra++;
|
||||
}
|
||||
if(nfields!=(pvStructure->getStructure()->getNumberFields()-nextra)) {
|
||||
if (std::find(columnNames.begin(), columnNames.end(), name) != columnNames.end())
|
||||
throw std::runtime_error("duplicate column name");
|
||||
|
||||
columnNames.push_back(name);
|
||||
types.push_back(scalarType);
|
||||
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
StructureConstPtr NTTableBuilder::createStructure()
|
||||
{
|
||||
FieldBuilderPtr builder = getFieldCreate()->createFieldBuilder();
|
||||
|
||||
FieldBuilderPtr nestedBuilder =
|
||||
builder->
|
||||
setId(NTTable::URI)->
|
||||
addArray("labels", pvString)->
|
||||
addNestedStructure("value");
|
||||
|
||||
vector<string>::size_type len = columnNames.size();
|
||||
for (vector<string>::size_type i = 0; i < len; i++)
|
||||
nestedBuilder->addArray(columnNames[i], types[i]);
|
||||
|
||||
builder = nestedBuilder->endNested();
|
||||
|
||||
if (descriptor)
|
||||
builder->add("descriptor", pvString);
|
||||
|
||||
if (alarm)
|
||||
builder->add("alarm", ntField->createAlarm());
|
||||
|
||||
if (timeStamp)
|
||||
builder->add("timeStamp", ntField->createTimeStamp());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTTableBuilder::shared_pointer NTTableBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTTableBuilder::shared_pointer NTTableBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTTableBuilder::shared_pointer NTTableBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
PVStructurePtr NTTableBuilder::createPVStructure()
|
||||
{
|
||||
// fill in labels with default values (the column names)
|
||||
size_t len = columnNames.size();
|
||||
shared_vector<string> l(len);
|
||||
for(size_t i=0; i<len; ++i) l[i] = columnNames[i];
|
||||
PVStructurePtr s = getPVDataCreate()->createPVStructure(createStructure());
|
||||
s->getSubField<PVStringArray>("labels")->replace(freeze(l));
|
||||
return s;
|
||||
}
|
||||
|
||||
NTTablePtr NTTableBuilder::create()
|
||||
{
|
||||
return NTTablePtr(new NTTable(createPVStructure()));
|
||||
}
|
||||
|
||||
NTTableBuilder::NTTableBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTTableBuilder::reset()
|
||||
{
|
||||
columnNames.clear();
|
||||
types.clear();
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
}
|
||||
|
||||
NTTableBuilder::shared_pointer NTTableBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const std::string NTTable::URI("epics:nt/NTTable:1.0");
|
||||
|
||||
NTTable::shared_pointer NTTable::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTTable::shared_pointer NTTable::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTTable(structure));
|
||||
}
|
||||
|
||||
bool NTTable::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTTable::isCompatible(StructureConstPtr const & structure)
|
||||
{
|
||||
if (!structure.get()) return false;
|
||||
|
||||
StructureConstPtr valueField = structure->getField<Structure>("value");
|
||||
if (!valueField.get())
|
||||
return false;
|
||||
|
||||
FieldConstPtrArray const & fields = valueField->getFields();
|
||||
for (FieldConstPtrArray::const_iterator it = fields.begin();
|
||||
it != fields.end(); ++it)
|
||||
{
|
||||
if ((*it)->getType() != scalarArray) return false;
|
||||
}
|
||||
FieldConstPtrArray fields = pvStructure->getStructure()->getFields();
|
||||
for(size_t i=0; i<nfields; i++) {
|
||||
FieldConstPtr field = fields[i+nextra];
|
||||
Type type = field->getType();
|
||||
if(type!=scalarArray && type!=structureArray) return false;
|
||||
|
||||
ScalarArrayConstPtr labelsField = structure->getField<ScalarArray>("labels");
|
||||
if (!labelsField.get() || labelsField->getElementType() != pvString)
|
||||
return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NTTablePtr NTTable::create(
|
||||
bool hasFunction,bool hasTimeStamp, bool hasAlarm,
|
||||
StringArray const & valueNames,
|
||||
FieldConstPtrArray const &valueFields)
|
||||
bool NTTable::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
StandardFieldPtr standardField = getStandardField();
|
||||
size_t nfields = 1;
|
||||
if(hasFunction) nfields++;
|
||||
if(hasTimeStamp) nfields++;
|
||||
if(hasAlarm) nfields++;
|
||||
nfields += valueFields.size();
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
FieldConstPtrArray fields;
|
||||
StringArray names;
|
||||
fields.resize(nfields);
|
||||
names.resize(nfields);
|
||||
size_t ind = 0;
|
||||
if(hasFunction) {
|
||||
names[ind] = "function";
|
||||
fields[ind++] = fieldCreate->createScalar(pvString);
|
||||
if(!pvStructure) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTTable::isValid()
|
||||
{
|
||||
PVFieldPtrArray const & columns = pvValue->getPVFields();
|
||||
|
||||
if (getLabels()->getLength() != columns.size()) return false;
|
||||
bool first = true;
|
||||
int length = 0;
|
||||
for (PVFieldPtrArray::const_iterator it = columns.begin();
|
||||
it != columns.end();++it)
|
||||
{
|
||||
PVScalarArrayPtr column = std::tr1::dynamic_pointer_cast<PVScalarArray>(*it);
|
||||
if (!column.get()) return false;
|
||||
int colLength = column->getLength();
|
||||
if (first)
|
||||
{
|
||||
length = colLength;
|
||||
first = false;
|
||||
}
|
||||
else if (length != colLength)
|
||||
return false;
|
||||
}
|
||||
if(hasTimeStamp) {
|
||||
names[ind] = "timeStamp";
|
||||
fields[ind++] = standardField->timeStamp();
|
||||
}
|
||||
if(hasAlarm) {
|
||||
names[ind] = "alarm";
|
||||
fields[ind++] = standardField->alarm();
|
||||
}
|
||||
names[ind] = "label";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvString);
|
||||
size_t numberValues = valueNames.size();
|
||||
for(size_t i=0; i<numberValues ; i++) {
|
||||
names[ind] = valueNames[i];
|
||||
fields[ind++] = valueFields[i];
|
||||
}
|
||||
StructureConstPtr st = fieldCreate->createStructure(names,fields);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(st);
|
||||
PVStringArrayPtr pvLabel = static_pointer_cast<PVStringArray>
|
||||
(pvStructure->getScalarArrayField("label",pvString));
|
||||
pvLabel->put(0,numberValues,valueNames,0);
|
||||
return NTTablePtr(new NTTable(pvStructure));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NTTablePtr NTTable::clone(PVStructurePtr const & pv)
|
||||
|
||||
NTTableBuilderPtr NTTable::createBuilder()
|
||||
{
|
||||
PVStructurePtr pvStructure = getPVDataCreate()->createPVStructure(pv);
|
||||
return NTTablePtr(new NTTable(pvStructure));
|
||||
return NTTableBuilderPtr(new detail::NTTableBuilder());
|
||||
}
|
||||
|
||||
NTTable::NTTable(PVStructurePtr const & pvStructure)
|
||||
: pvNTTable(pvStructure),
|
||||
offsetFields(1)
|
||||
bool NTTable::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
NTFieldPtr ntfield = NTField::get();
|
||||
PVScalarArrayPtr pvScalarArray
|
||||
= pvStructure->getScalarArrayField("label",pvString);
|
||||
pvLabel = static_pointer_cast<PVStringArray>(pvScalarArray);
|
||||
PVFieldPtr pvField = pvStructure->getSubField("function");
|
||||
if(pvField.get()!=NULL) {
|
||||
offsetFields++;
|
||||
pvFunction = pvStructure->getStringField("function");
|
||||
}
|
||||
pvField = pvStructure->getSubField("timeStamp");
|
||||
if(pvField.get()!=NULL && ntfield->isTimeStamp(pvField->getField())) {
|
||||
offsetFields++;
|
||||
pvTimeStamp = static_pointer_cast<PVStructure>(pvField);
|
||||
}
|
||||
pvField = pvStructure->getSubField("alarm");
|
||||
if(pvField.get()!=NULL && ntfield->isAlarm(pvField->getField())) {
|
||||
offsetFields++;
|
||||
pvAlarm = static_pointer_cast<PVStructure>(pvField);
|
||||
}
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void NTTable::attachTimeStamp(PVTimeStamp &pv)
|
||||
bool NTTable::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
if(pvTimeStamp.get()==NULL) return;
|
||||
pv.attach(pvTimeStamp);
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void NTTable::attachAlarm(PVAlarm &pv)
|
||||
PVStructurePtr NTTable::getPVStructure() const
|
||||
{
|
||||
if(pvAlarm.get()==NULL) return;
|
||||
pv.attach(pvAlarm);
|
||||
return pvNTTable;
|
||||
}
|
||||
|
||||
size_t NTTable::getNumberValues()
|
||||
PVStringPtr NTTable::getDescriptor() const
|
||||
{
|
||||
return pvLabel->getLength();
|
||||
return pvNTTable->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
FieldConstPtr NTTable::getField(size_t index)
|
||||
PVStructurePtr NTTable::getTimeStamp() const
|
||||
{
|
||||
FieldConstPtrArray fields = pvNTTable->getStructure()->getFields();
|
||||
return fields[index + offsetFields];
|
||||
return pvNTTable->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVFieldPtr NTTable::getPVField(size_t index)
|
||||
PVStructurePtr NTTable::getAlarm() const
|
||||
{
|
||||
PVFieldPtrArray pvFields = pvNTTable->getPVFields();
|
||||
return pvFields[index+offsetFields];
|
||||
return pvNTTable->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
PVStringArrayPtr NTTable::getLabels() const
|
||||
{
|
||||
return pvNTTable->getSubField<PVStringArray>("labels");
|
||||
}
|
||||
|
||||
StringArray const & NTTable::getColumnNames() const
|
||||
{
|
||||
return pvNTTable->getStructure()->getFieldNames();
|
||||
}
|
||||
|
||||
PVFieldPtr NTTable::getColumn(std::string const & columnName) const
|
||||
{
|
||||
return pvValue->getSubField(columnName);
|
||||
}
|
||||
|
||||
NTTable::NTTable(PVStructurePtr const & pvStructure) :
|
||||
pvNTTable(pvStructure), pvValue(pvNTTable->getSubField<PVStructure>("value"))
|
||||
{}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
298
src/nt/nttable.h
298
src/nt/nttable.h
@@ -1,115 +1,295 @@
|
||||
/* nttable.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTTABLE_H
|
||||
#define NTTABLE_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define nttableEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/pvDisplay.h>
|
||||
#include <pv/pvControl.h>
|
||||
|
||||
#ifdef nttableEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef nttableEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
#include <shareLib.h>
|
||||
|
||||
/**
|
||||
* Convenience Class for NTTable
|
||||
* @author mrk
|
||||
*
|
||||
*/
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTTable;
|
||||
typedef std::tr1::shared_ptr<NTTable> NTTablePtr;
|
||||
|
||||
class NTTable
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTTable.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author mse
|
||||
*/
|
||||
class epicsShareClass NTTableBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTTableBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTTableBuilder);
|
||||
|
||||
/**
|
||||
* Add a column of given <b>Scalar</b> type.
|
||||
* @param name name of the column.
|
||||
* @param elementType column type, a scalar array.
|
||||
* @return this instance of <b>NTTableBuilder</b>.
|
||||
*/
|
||||
shared_pointer addColumn(std::string const & name, epics::pvData::ScalarType elementType);
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTTable.
|
||||
* @return this instance of <b>NTTableBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTTable.
|
||||
* @return this instance of <b>NTTableBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTTable.
|
||||
* @return this instance of <b>NTTableBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTTable.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTTable.
|
||||
* The returned PVStructure will have labels equal to the column names.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>PVStructure</b>.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTTable</b> instance.
|
||||
* The returned NTTable will wrap a PVStructure which will have
|
||||
* labels equal to the column names.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>NTTable</b>.
|
||||
*/
|
||||
NTTablePtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTTableBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
private:
|
||||
NTTableBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
std::vector<std::string> columnNames;
|
||||
std::vector<epics::pvData::ScalarType> types;
|
||||
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTTable;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTTableBuilder> NTTableBuilderPtr;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTTable
|
||||
*
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass NTTable
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTTable);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Is the pvStructure an NTTable.
|
||||
* @param pvStructure The pvStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTNameValuePair.
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTTable.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTTable.
|
||||
* @return NTTable instance on success, nullptr otherwise.
|
||||
*/
|
||||
static bool isNTTable(PVStructurePtr const &pvStructure);
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Create an NTTable pvStructure.
|
||||
* @param hasFunction Create a PVString field named function.
|
||||
* @param hasTimeStamp Create a timeStamp structure field.
|
||||
* @param hasAlarm Create an alarm structure field.
|
||||
* @param numberValues The number of fields that follow the label field.
|
||||
* @param valueFields The fields that follow the label field.
|
||||
* @return an NTTablePtr
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTMultiChannel without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTTable.
|
||||
* @return NTTable instance.
|
||||
*/
|
||||
static NTTablePtr create(
|
||||
bool hasFunction,bool hasTimeStamp, bool hasAlarm,
|
||||
StringArray const & valueNames,
|
||||
FieldConstPtrArray const &valueFields);
|
||||
static NTTablePtr clone(PVStructurePtr const &);
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
* Is the structure an NTTable.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTTable.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTTable.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTTable.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTTable.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTTable.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTTable.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTTable.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTTable.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTTable
|
||||
* @return (false,true) if (is not, is) a valid NTTable.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTTable builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTTableBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTTable() {}
|
||||
/**
|
||||
* Get the function field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
PVStringPtr getFunction() {return pvFunction;}
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
void attachTimeStamp(PVTimeStamp &pvTimeStamp);
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
void attachAlarm(PVAlarm &pvAlarm);
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
PVStructurePtr getPVStructure(){return pvNTTable;}
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
PVStructurePtr getTimeStamp(){return pvTimeStamp;}
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
PVStructurePtr getAlarm() {return pvAlarm;}
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the label field.
|
||||
* @return The pvStringArray for the label.
|
||||
* Get the labels field.
|
||||
* @return The pvStringArray for the labels.
|
||||
*/
|
||||
PVStringArrayPtr getLabel() {return pvLabel;}
|
||||
epics::pvData::PVStringArrayPtr getLabels() const;
|
||||
|
||||
/**
|
||||
* Get the the number of fields that follow the label field.
|
||||
* @return The number of fields.
|
||||
* Get the column names for the table.
|
||||
* For each name, calling getColumn should return the column, which should not be null.
|
||||
* @return The column names.
|
||||
*/
|
||||
size_t getNumberValues();
|
||||
epics::pvData::StringArray const & getColumnNames() const;
|
||||
|
||||
/**
|
||||
* Get the Field for a field that follows the label field.
|
||||
* @param index The index of the field desired.
|
||||
* @return The FieldConstPtr for the field.
|
||||
*/
|
||||
FieldConstPtr getField(size_t index);
|
||||
/**
|
||||
* Get the PVField for a field that follows the label field.
|
||||
* @param index The index of the field desired.
|
||||
* Get the PVField (column) for a field that follows the label field.
|
||||
* @param columnName The name of the column.
|
||||
* @return The PVFieldPtr for the field.
|
||||
*/
|
||||
PVFieldPtr getPVField(size_t index);
|
||||
epics::pvData::PVFieldPtr getColumn(std::string const & columnName) const;
|
||||
|
||||
/**
|
||||
* Get the PVField (column) for a field that follows the label field of a specified type (e.g. PVDoubleArray).
|
||||
* @param columnName The name of the column.
|
||||
* @return The <PVT> field.
|
||||
*/
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getColumn(std::string const & columnName) const
|
||||
{
|
||||
epics::pvData::PVFieldPtr pvField = getColumn(columnName);
|
||||
if (pvField.get())
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(pvField);
|
||||
else
|
||||
return std::tr1::shared_ptr<PVT>();
|
||||
}
|
||||
|
||||
private:
|
||||
NTTable(PVStructurePtr const & pvStructure);
|
||||
PVStructurePtr pvNTTable;
|
||||
PVStringPtr pvFunction;
|
||||
PVStructurePtr pvTimeStamp;
|
||||
PVStructurePtr pvAlarm;
|
||||
PVStringArrayPtr pvLabel;
|
||||
size_t offsetFields;
|
||||
NTTable(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTTable;
|
||||
epics::pvData::PVStructurePtr pvValue;
|
||||
friend class detail::NTTableBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
213
src/nt/ntunion.cpp
Normal file
213
src/nt/ntunion.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/* ntunion.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntunion.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
StructureConstPtr NTUnionBuilder::createStructure()
|
||||
{
|
||||
FieldBuilderPtr builder =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId(NTUnion::URI)->
|
||||
add("value", valueType);
|
||||
|
||||
if (descriptor)
|
||||
builder->add("descriptor", pvString);
|
||||
|
||||
if (alarm)
|
||||
builder->add("alarm", ntField->createAlarm());
|
||||
|
||||
if (timeStamp)
|
||||
builder->add("timeStamp", ntField->createTimeStamp());
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTUnionBuilder::shared_pointer NTUnionBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTUnionBuilder::shared_pointer NTUnionBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTUnionBuilder::shared_pointer NTUnionBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
PVStructurePtr NTUnionBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTUnionPtr NTUnionBuilder::create()
|
||||
{
|
||||
return NTUnionPtr(new NTUnion(createPVStructure()));
|
||||
}
|
||||
|
||||
NTUnionBuilder::NTUnionBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTUnionBuilder::reset()
|
||||
{
|
||||
valueType = getFieldCreate()->createVariantUnion();
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
}
|
||||
|
||||
NTUnionBuilder::shared_pointer NTUnionBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const std::string NTUnion::URI("epics:nt/NTUnion:1.0");
|
||||
|
||||
NTUnion::shared_pointer NTUnion::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTUnion::shared_pointer NTUnion::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTUnion(structure));
|
||||
}
|
||||
|
||||
bool NTUnion::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTUnion::isCompatible(StructureConstPtr const &structure)
|
||||
{
|
||||
if (structure.get() == 0) return false;
|
||||
|
||||
UnionConstPtr valueField = structure->getField<Union>("value");
|
||||
if (valueField.get() == 0)
|
||||
return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("descriptor");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
|
||||
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
NTFieldPtr ntField = NTField::get();
|
||||
|
||||
field = structure->getField("alarm");
|
||||
if (field.get() && !ntField->isAlarm(field))
|
||||
return false;
|
||||
|
||||
field = structure->getField("timeStamp");
|
||||
if (field.get() && !ntField->isTimeStamp(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NTUnion::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(!pvStructure) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTUnion::isValid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NTUnionBuilderPtr NTUnion::createBuilder()
|
||||
{
|
||||
return NTUnionBuilderPtr(new detail::NTUnionBuilder());
|
||||
}
|
||||
|
||||
bool NTUnion::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
|
||||
{
|
||||
PVStructurePtr ts = getTimeStamp();
|
||||
if (ts)
|
||||
return pvTimeStamp.attach(ts);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NTUnion::attachAlarm(PVAlarm &pvAlarm) const
|
||||
{
|
||||
PVStructurePtr al = getAlarm();
|
||||
if (al)
|
||||
return pvAlarm.attach(al);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStructurePtr NTUnion::getPVStructure() const
|
||||
{
|
||||
return pvNTUnion;
|
||||
}
|
||||
|
||||
PVStringPtr NTUnion::getDescriptor() const
|
||||
{
|
||||
return pvNTUnion->getSubField<PVString>("descriptor");
|
||||
}
|
||||
|
||||
PVStructurePtr NTUnion::getTimeStamp() const
|
||||
{
|
||||
return pvNTUnion->getSubField<PVStructure>("timeStamp");
|
||||
}
|
||||
|
||||
PVStructurePtr NTUnion::getAlarm() const
|
||||
{
|
||||
return pvNTUnion->getSubField<PVStructure>("alarm");
|
||||
}
|
||||
|
||||
PVUnionPtr NTUnion::getValue() const
|
||||
{
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
NTUnion::NTUnion(PVStructurePtr const & pvStructure) :
|
||||
pvNTUnion(pvStructure), pvValue(pvNTUnion->getSubField<PVUnion>("value"))
|
||||
{}
|
||||
|
||||
|
||||
}}
|
||||
250
src/nt/ntunion.h
Normal file
250
src/nt/ntunion.h
Normal file
@@ -0,0 +1,250 @@
|
||||
/* ntunion.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTUNION_H
|
||||
#define NTUNION_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntunionEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#ifdef ntunionEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntunionEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTUnion;
|
||||
typedef std::tr1::shared_ptr<NTUnion> NTUnionPtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTUnion.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTUnionBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTUnionBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTUnionBuilder);
|
||||
|
||||
/**
|
||||
* Add descriptor field to the NTUnion.
|
||||
* @return this instance of <b>NTUnionBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
|
||||
/**
|
||||
* Add alarm structure to the NTUnion.
|
||||
* @return this instance of <b>NTUnionBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
|
||||
/**
|
||||
* Add timeStamp structure to the NTUnion.
|
||||
* @return this instance of <b>NTUnionBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTUnion.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTUnion.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>PVStructure</b>.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTUnion</b> instance.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>NTUnion</b>.
|
||||
*/
|
||||
NTUnionPtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTUnionBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
private:
|
||||
NTUnionBuilder();
|
||||
|
||||
epics::pvData::UnionConstPtr valueType;
|
||||
|
||||
void reset();
|
||||
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTUnion;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTUnionBuilder> NTUnionBuilderPtr;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTUnion
|
||||
*
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTUnion
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTUnion);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTUnion.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTUnion.
|
||||
* @return NTUnion instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTUnion without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTUnion.
|
||||
* @return NTUnion instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTUnion.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTUnion.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTUnion.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTUnion.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTUnion.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTUnion.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTUnion.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTUnion.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTUnion.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTUnion
|
||||
* @return (false,true) if (is not, is) a valid NTUnion.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTUnion builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTUnionBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTUnion() {}
|
||||
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
|
||||
/**
|
||||
* Attach an pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm.
|
||||
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
|
||||
*/
|
||||
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the descriptor field.
|
||||
* @return The pvString or null if no function field.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const;
|
||||
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const;
|
||||
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const;
|
||||
|
||||
/**
|
||||
* Get the value field.
|
||||
* @return The PVUnion for the values.
|
||||
*/
|
||||
epics::pvData::PVUnionPtr getValue() const;
|
||||
|
||||
private:
|
||||
NTUnion(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTUnion;
|
||||
epics::pvData::PVUnionPtr pvValue;
|
||||
|
||||
friend class detail::NTUnionBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTUNION_H */
|
||||
249
src/nt/nturi.cpp
Normal file
249
src/nt/nturi.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
/* nturi.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/nturi.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
NTURIBuilder::shared_pointer NTURIBuilder::addQueryString(std::string const & name)
|
||||
{
|
||||
if (std::find(queryFieldNames.begin(), queryFieldNames.end(), name) != queryFieldNames.end())
|
||||
throw std::runtime_error("duplicate query field name");
|
||||
|
||||
queryFieldNames.push_back(name);
|
||||
queryTypes.push_back(pvString);
|
||||
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTURIBuilder::shared_pointer NTURIBuilder::addQueryDouble(std::string const & name)
|
||||
{
|
||||
if (std::find(queryFieldNames.begin(), queryFieldNames.end(), name) != queryFieldNames.end())
|
||||
throw std::runtime_error("duplicate query field name");
|
||||
|
||||
queryFieldNames.push_back(name);
|
||||
queryTypes.push_back(pvDouble);
|
||||
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTURIBuilder::shared_pointer NTURIBuilder::addQueryInt(std::string const & name)
|
||||
{
|
||||
if (std::find(queryFieldNames.begin(), queryFieldNames.end(), name) != queryFieldNames.end())
|
||||
throw std::runtime_error("duplicate query field name");
|
||||
|
||||
queryFieldNames.push_back(name);
|
||||
queryTypes.push_back(pvInt);
|
||||
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
StructureConstPtr NTURIBuilder::createStructure()
|
||||
{
|
||||
FieldBuilderPtr builder = getFieldCreate()->
|
||||
createFieldBuilder()->
|
||||
setId(NTURI::URI)->
|
||||
add("scheme", pvString);
|
||||
|
||||
if (authority)
|
||||
builder->add("authority", pvString);
|
||||
|
||||
builder->add("path", pvString);
|
||||
|
||||
if (!queryFieldNames.empty())
|
||||
{
|
||||
FieldBuilderPtr nestedBuilder = builder->
|
||||
addNestedStructure("query");
|
||||
|
||||
vector<string>::size_type len = queryFieldNames.size();
|
||||
for (vector<string>::size_type i = 0; i < len; i++)
|
||||
nestedBuilder->add(queryFieldNames[i], queryTypes[i]);
|
||||
|
||||
builder = nestedBuilder->endNested();
|
||||
}
|
||||
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
for (size_t i = 0; i< extraCount; i++)
|
||||
builder->add(extraFieldNames[i], extraFields[i]);
|
||||
|
||||
StructureConstPtr s = builder->createStructure();
|
||||
|
||||
reset();
|
||||
return s;
|
||||
}
|
||||
|
||||
NTURIBuilder::shared_pointer NTURIBuilder::addAuthority()
|
||||
{
|
||||
authority = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
PVStructurePtr NTURIBuilder::createPVStructure()
|
||||
{
|
||||
return getPVDataCreate()->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTURIPtr NTURIBuilder::create()
|
||||
{
|
||||
return NTURIPtr(new NTURI(createPVStructure()));
|
||||
}
|
||||
|
||||
NTURIBuilder::NTURIBuilder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTURIBuilder::reset()
|
||||
{
|
||||
queryFieldNames.clear();
|
||||
queryTypes.clear();
|
||||
authority = false;
|
||||
}
|
||||
|
||||
NTURIBuilder::shared_pointer NTURIBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field);
|
||||
extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string NTURI::URI("epics:nt/NTURI:1.0");
|
||||
|
||||
NTURI::shared_pointer NTURI::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTURI::shared_pointer NTURI::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTURI(structure));
|
||||
}
|
||||
|
||||
bool NTURI::is_a(StructureConstPtr const & structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTURI::isCompatible(StructureConstPtr const & structure)
|
||||
{
|
||||
if (!structure.get()) return false;
|
||||
|
||||
ScalarConstPtr schemeField = structure->getField<Scalar>("scheme");
|
||||
if (schemeField.get() == 0 || schemeField->getScalarType() != pvString)
|
||||
return false;
|
||||
|
||||
ScalarConstPtr pathField = structure->getField<Scalar>("path");
|
||||
if (pathField.get() == 0 || pathField->getScalarType() != pvString)
|
||||
return false;
|
||||
|
||||
FieldConstPtr field = structure->getField("authority");
|
||||
if (field.get())
|
||||
{
|
||||
ScalarConstPtr authorityField = structure->getField<Scalar>("authority");
|
||||
if (!authorityField.get() || authorityField->getScalarType() != pvString)
|
||||
return false;
|
||||
}
|
||||
|
||||
field = structure->getField("query");
|
||||
if (field.get())
|
||||
{
|
||||
StructureConstPtr queryField = structure->getField<Structure>("query");
|
||||
if (!queryField.get())
|
||||
return false;
|
||||
|
||||
FieldConstPtrArray const & fields = queryField->getFields();
|
||||
for (FieldConstPtrArray::const_iterator it = fields.begin();
|
||||
it != fields.end(); ++it)
|
||||
{
|
||||
if ((*it)->getType() != scalar) return false;
|
||||
ScalarType scalarType = std::tr1::dynamic_pointer_cast<const Scalar>(
|
||||
(*it))->getScalarType();
|
||||
if (scalarType != pvString &&
|
||||
scalarType != pvInt &&
|
||||
scalarType != pvDouble) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NTURI::isCompatible(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(!pvStructure) return false;
|
||||
|
||||
return isCompatible(pvStructure->getStructure());
|
||||
}
|
||||
|
||||
bool NTURI::isValid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NTURIBuilderPtr NTURI::createBuilder()
|
||||
{
|
||||
return NTURIBuilderPtr(new detail::NTURIBuilder());
|
||||
}
|
||||
|
||||
|
||||
PVStructurePtr NTURI::getPVStructure() const
|
||||
{
|
||||
return pvNTURI;
|
||||
}
|
||||
|
||||
|
||||
PVStringPtr NTURI::getScheme() const
|
||||
{
|
||||
return pvNTURI->getSubField<PVString>("scheme");
|
||||
}
|
||||
|
||||
PVStringPtr NTURI::getAuthority() const
|
||||
{
|
||||
return pvNTURI->getSubField<PVString>("authority");
|
||||
}
|
||||
|
||||
PVStringPtr NTURI::getPath() const
|
||||
{
|
||||
return pvNTURI->getSubField<PVString>("path");
|
||||
}
|
||||
|
||||
PVStructurePtr NTURI::getQuery() const
|
||||
{
|
||||
return pvNTURI->getSubField<PVStructure>("query");
|
||||
}
|
||||
|
||||
StringArray const & NTURI::getQueryNames() const
|
||||
{
|
||||
return pvNTURI->getSubField<PVStructure>("query")->getStructure()->getFieldNames();
|
||||
}
|
||||
|
||||
PVFieldPtr NTURI::getQueryField(std::string const & name) const
|
||||
{
|
||||
return pvNTURI->getSubField("query." + name);
|
||||
}
|
||||
|
||||
NTURI::NTURI(PVStructurePtr const & pvStructure) :
|
||||
pvNTURI(pvStructure)
|
||||
{}
|
||||
|
||||
|
||||
}}
|
||||
279
src/nt/nturi.h
Normal file
279
src/nt/nturi.h
Normal file
@@ -0,0 +1,279 @@
|
||||
/* nturi.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTURI_H
|
||||
#define NTURI_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define nturiEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#ifdef nturiEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef nturiEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
class NTURI;
|
||||
typedef std::tr1::shared_ptr<NTURI> NTURIPtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTURI.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTURIBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTURIBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTURIBuilder);
|
||||
|
||||
/**
|
||||
* Add authority field to the NTURI.
|
||||
* @return this instance of <b>NTURIBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAuthority();
|
||||
|
||||
/**
|
||||
* Add extra <b>Scalar</b> of ScalarType pvString
|
||||
* to the query field of the type.
|
||||
* @param name name of the field.
|
||||
* @return this instance of <b>NTURIBuilder</b>.
|
||||
*/
|
||||
shared_pointer addQueryString(std::string const & name);
|
||||
|
||||
/**
|
||||
* Add extra <b>Scalar</b> of ScalarType pvDouble
|
||||
* to the query field of the type.
|
||||
* @param name name of the field.
|
||||
* @return this instance of <b>NTURIBuilder</b>.
|
||||
*/
|
||||
shared_pointer addQueryDouble(std::string const & name);
|
||||
|
||||
/**
|
||||
* Add extra <b>Scalar</b> of ScalarType pvInt
|
||||
* to the query field of the type.
|
||||
* @param name name of the field.
|
||||
* @return this instance of <b>NTURIBuilder</b>.
|
||||
*/
|
||||
shared_pointer addQueryInt(std::string const & name);
|
||||
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTURI.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTURI.
|
||||
* The returned PVStructure will have labels equal to the column names.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>PVStructure</b>.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
|
||||
/**
|
||||
* Create a <b>NTURI</b> instance.
|
||||
* The returned NTURI will wrap a PVStructure which will have
|
||||
* labels equal to the column names.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of <b>NTURI</b>.
|
||||
*/
|
||||
NTURIPtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of <b>NTURIBuilder</b>.
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
private:
|
||||
NTURIBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
std::vector<std::string> queryFieldNames;
|
||||
std::vector<epics::pvData::ScalarType> queryTypes;
|
||||
|
||||
bool authority;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTURI;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTURIBuilder> NTURIBuilderPtr;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTURI
|
||||
*
|
||||
* @author dgh
|
||||
*/
|
||||
class epicsShareClass NTURI
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTURI);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTURI.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* This method will nullptr if the structure is nullptr.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTURI.
|
||||
* @return NTURI instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTMultiChannel without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTURI.
|
||||
* @return NTURI instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTURI.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTURI.
|
||||
*/
|
||||
static bool is_a(epics::pvData::StructureConstPtr const & structure);
|
||||
|
||||
/**
|
||||
* Is the structure an NTURI.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTURI.
|
||||
*/
|
||||
static bool is_a(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
|
||||
/**
|
||||
* Is the Structure compatible with NTURI.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param structure The Structure to test.
|
||||
* @return (false,true) if (is not, is) an NTURI.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
|
||||
/**
|
||||
* Is the PVStructure compatible with NTURI.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The PVStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTURI.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
|
||||
/**
|
||||
* Checks if the specified structure is a valid NTURI.
|
||||
*
|
||||
* Checks whether the wrapped structure is valid with respect to this
|
||||
* version of NTURI
|
||||
* @return (false,true) if (is not, is) a valid NTURI.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Create a NTURI builder instance.
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTURIBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~NTURI() {}
|
||||
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const;
|
||||
|
||||
/**
|
||||
* Get the scheme field.
|
||||
* @return The PVString for the scheme.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getScheme() const;
|
||||
|
||||
/**
|
||||
* Get the authority field.
|
||||
* @return The PVString for the authority.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getAuthority() const;
|
||||
|
||||
/**
|
||||
* Get the path field.
|
||||
* @return The PVString for the path.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getPath() const;
|
||||
|
||||
/**
|
||||
* Get the query field.
|
||||
* @return The PVStructure for the query.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getQuery() const;
|
||||
|
||||
/**
|
||||
* Get the names of the query fields for the URI.
|
||||
* For each name, calling getQueryField should return
|
||||
* the query field, which should not be null.
|
||||
* @return The query field names.
|
||||
*/
|
||||
epics::pvData::StringArray const & getQueryNames() const;
|
||||
|
||||
/**
|
||||
* Get the PVField (column) for a field that follows the label field.
|
||||
* @param columnName The name of the column.
|
||||
* @return The PVFieldPtr for the field.
|
||||
*/
|
||||
epics::pvData::PVFieldPtr getQueryField(std::string const & columnName) const;
|
||||
|
||||
/**
|
||||
* Get the PVField (column) for a field that follows the label field of a specified type (e.g. PVDoubleArray).
|
||||
* @param columnName The name of the column.
|
||||
* @return The <PVT> field.
|
||||
*/
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getQueryField(std::string const & columnName) const
|
||||
{
|
||||
epics::pvData::PVFieldPtr pvField = getQueryField(columnName);
|
||||
if (pvField.get())
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(pvField);
|
||||
else
|
||||
return std::tr1::shared_ptr<PVT>();
|
||||
}
|
||||
|
||||
private:
|
||||
NTURI(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTURI;
|
||||
friend class detail::NTURIBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTURI_H */
|
||||
28
src/nt/ntutils.cpp
Normal file
28
src/nt/ntutils.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/* ntutils.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
bool NTUtils::is_a(const std::string &u1, const std::string &u2)
|
||||
{
|
||||
// remove minor for the u1
|
||||
size_t pos1 = u1.find_last_of('.');
|
||||
std::string su1 = (pos1 == string::npos) ? u1 : u1.substr(0, pos1);
|
||||
|
||||
// remove minor for the u2
|
||||
size_t pos2 = u2.find_last_of('.');
|
||||
std::string su2 = (pos2 == string::npos) ? u2 : u2.substr(0, pos2);
|
||||
|
||||
return su2 == su1;
|
||||
}
|
||||
|
||||
}}
|
||||
40
src/nt/ntutils.h
Normal file
40
src/nt/ntutils.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* ntutils.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef NTUTILS_H
|
||||
#define NTUTILS_H
|
||||
|
||||
#include <string>
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
/**
|
||||
* @brief Utility methods for NT types.
|
||||
*
|
||||
* @author mse
|
||||
*/
|
||||
class epicsShareClass NTUtils {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Checks whether NT types are compatible by checking their IDs,
|
||||
* i.e. their names and major version must match.
|
||||
* @param u1 the first uri.
|
||||
* @param u2 the second uri.
|
||||
* @return true of URIs are compatible, false otherwise.
|
||||
*/
|
||||
static bool is_a(const std::string &u1, const std::string &u2);
|
||||
|
||||
private:
|
||||
// disable object creation
|
||||
NTUtils() {}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* NTUTILS_H */
|
||||
|
||||
@@ -2,17 +2,77 @@ TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PROD_HOST += ntfieldTest
|
||||
PROD_LIBS += nt pvData Com
|
||||
|
||||
TESTPROD_HOST += ntfieldTest
|
||||
ntfieldTest_SRCS += ntfieldTest.cpp
|
||||
ntfieldTest_LIBS += nt pvData Com
|
||||
TESTS += ntfieldTest
|
||||
|
||||
PROD_HOST += ntnameValueTest
|
||||
TESTPROD_HOST += ntscalarTest
|
||||
ntscalarTest_SRCS += ntscalarTest.cpp
|
||||
TESTS += ntscalarTest
|
||||
|
||||
TESTPROD_HOST += ntscalarArrayTest
|
||||
ntscalarArrayTest_SRCS += ntscalarArrayTest.cpp
|
||||
TESTS += ntscalarArrayTest
|
||||
|
||||
TESTPROD_HOST += ntnameValueTest
|
||||
ntnameValueTest_SRCS += ntnameValueTest.cpp
|
||||
ntnameValueTest_LIBS += nt pvData Com
|
||||
TESTS += ntnameValueTest
|
||||
|
||||
PROD_HOST += nttableTest
|
||||
nttableTest_SRCS += nttableTest.cpp
|
||||
nttableTest_LIBS += nt pvData Com
|
||||
TESTPROD_HOST += ntmultiChannelTest
|
||||
ntmultiChannelTest_SRCS += ntmultiChannelTest.cpp
|
||||
TESTS += ntmultiChannelTest
|
||||
|
||||
TESTPROD_HOST += ntscalarMultiChannelTest
|
||||
ntscalarMultiChannelTest_SRCS += ntscalarMultiChannelTest.cpp
|
||||
TESTS += ntscalarMultiChannelTest
|
||||
|
||||
TESTPROD_HOST += nttableTest
|
||||
nttableTest_SRCS = nttableTest.cpp
|
||||
TESTS += nttableTest
|
||||
|
||||
TESTPROD_HOST += ntndarrayTest
|
||||
ntndarrayTest_SRCS = ntndarrayTest.cpp
|
||||
TESTS += ntndarrayTest
|
||||
|
||||
TESTPROD_HOST += ntmatrixTest
|
||||
ntmatrixTest_SRCS = ntmatrixTest.cpp
|
||||
TESTS += ntmatrixTest
|
||||
|
||||
TESTPROD_HOST += ntenumTest
|
||||
ntenumTest_SRCS = ntenumTest.cpp
|
||||
TESTS += ntenumTest
|
||||
|
||||
TESTPROD_HOST += ntunionTest
|
||||
ntunionTest_SRCS = ntunionTest.cpp
|
||||
TESTS += ntunionTest
|
||||
|
||||
TESTPROD_HOST += ntaggregateTest
|
||||
ntaggregateTest_SRCS = ntaggregateTest.cpp
|
||||
TESTS += ntaggregateTest
|
||||
|
||||
TESTPROD_HOST += ntattributeTest
|
||||
ntattributeTest_SRCS = ntattributeTest.cpp
|
||||
TESTS += ntattributeTest
|
||||
|
||||
TESTPROD_HOST += ntndarrayAttributeTest
|
||||
ntndarrayAttributeTest_SRCS = ntndarrayAttributeTest.cpp
|
||||
TESTS += ntndarrayAttributeTest
|
||||
|
||||
TESTPROD_HOST += ntcontinuumTest
|
||||
ntattributeTest_SRCS = ntcontinuumTest.cpp
|
||||
TESTS += ntcontinuumTest
|
||||
|
||||
TESTPROD_HOST += nthistogramTest
|
||||
ntattributeTest_SRCS = nthistogramTest.cpp
|
||||
TESTS += nthistogramTest
|
||||
|
||||
TESTPROD_HOST += ntutilsTest
|
||||
ntutilsTest_SRCS = ntutilsTest.cpp
|
||||
TESTS += ntutilsTest
|
||||
|
||||
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
|
||||
175
test/nt/ntaggregateTest.cpp
Normal file
175
test/nt/ntaggregateTest.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static StandardFieldPtr standardField = getStandardField();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
void test_builder()
|
||||
{
|
||||
testDiag("test_builder");
|
||||
|
||||
NTAggregateBuilderPtr builder = NTAggregate::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("valueAlarm",standardField->doubleAlarm()) ->
|
||||
add("extra",fieldCreate->createScalarArray(pvString)) ->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTAggregate::is_a(structure));
|
||||
testOk1(structure->getID() == NTAggregate::URI);
|
||||
testOk1(structure->getNumberFields() == 7);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
|
||||
ScalarConstPtr valueField = structure->getField<Scalar>("value");
|
||||
testOk(valueField.get() != 0, "value is scalar");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void test_ntaggregate()
|
||||
{
|
||||
testDiag("test_ntaggregate");
|
||||
|
||||
NTAggregateBuilderPtr builder = NTAggregate::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTAggregatePtr ntAggregate = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("valueAlarm",standardField->intAlarm()) ->
|
||||
create();
|
||||
testOk1(ntAggregate.get() != 0);
|
||||
|
||||
testOk1(ntAggregate->getPVStructure().get() != 0);
|
||||
testOk1(ntAggregate->getValue().get() != 0);
|
||||
testOk1(ntAggregate->getDescriptor().get() != 0);
|
||||
testOk1(ntAggregate->getAlarm().get() != 0);
|
||||
testOk1(ntAggregate->getTimeStamp().get() != 0);
|
||||
|
||||
//
|
||||
// example how to set a value
|
||||
//
|
||||
ntAggregate->getValue()->put(1.0);
|
||||
|
||||
//
|
||||
// example how to get a value
|
||||
//
|
||||
double value = ntAggregate->getValue()->get();
|
||||
testOk1(value == 1.0);
|
||||
|
||||
//
|
||||
// timeStamp ops
|
||||
//
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (ntAggregate->attachTimeStamp(pvTimeStamp))
|
||||
{
|
||||
testPass("timeStamp attach");
|
||||
|
||||
// example how to set current time
|
||||
TimeStamp ts;
|
||||
ts.getCurrent();
|
||||
pvTimeStamp.set(ts);
|
||||
|
||||
// example how to get EPICS time
|
||||
TimeStamp ts2;
|
||||
pvTimeStamp.get(ts2);
|
||||
testOk1(ts2.getEpicsSecondsPastEpoch() != 0);
|
||||
}
|
||||
else
|
||||
testFail("timeStamp attach fail");
|
||||
|
||||
//
|
||||
// alarm ops
|
||||
//
|
||||
PVAlarm pvAlarm;
|
||||
if (ntAggregate->attachAlarm(pvAlarm))
|
||||
{
|
||||
testPass("alarm attach");
|
||||
|
||||
// example how to set an alarm
|
||||
Alarm alarm;
|
||||
alarm.setStatus(deviceStatus);
|
||||
alarm.setSeverity(minorAlarm);
|
||||
alarm.setMessage("simulation alarm");
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
else
|
||||
testFail("alarm attach fail");
|
||||
|
||||
//
|
||||
// set descriptor
|
||||
//
|
||||
ntAggregate->getDescriptor()->put("This is a test NTAggregate");
|
||||
|
||||
// dump ntAggregate
|
||||
std::cout << *ntAggregate->getPVStructure() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTAggregatePtr nullPtr = NTAggregate::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTAggregate::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTAggregateBuilderPtr builder = NTAggregate::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
testOk1(NTAggregate::isCompatible(pvStructure)==true);
|
||||
NTAggregatePtr ptr = NTAggregate::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTAggregate::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testNTAggregate) {
|
||||
testPlan(28);
|
||||
test_builder();
|
||||
test_ntaggregate();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
176
test/nt/ntattributeTest.cpp
Normal file
176
test/nt/ntattributeTest.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
*/
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static StandardFieldPtr standardField = getStandardField();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
void test_builder()
|
||||
{
|
||||
testDiag("test_builder");
|
||||
|
||||
NTAttributeBuilderPtr builder = NTAttribute::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
addTags()->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("extra",fieldCreate->createScalar(pvString)) ->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTAttribute::is_a(structure));
|
||||
testOk1(structure->getID() == NTAttribute::URI);
|
||||
testOk1(structure->getNumberFields() == 7);
|
||||
testOk1(structure->getField("name").get() != 0);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("tags").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
|
||||
ScalarConstPtr nameField = structure->getField<Scalar>("name");
|
||||
testOk(nameField.get() != 0 && nameField->getScalarType() == pvString,
|
||||
"name is string");
|
||||
|
||||
UnionConstPtr valueField = structure->getField<Union>("value");
|
||||
testOk(valueField.get() != 0, "value is enum");
|
||||
|
||||
ScalarArrayConstPtr tagsField = structure->getField<ScalarArray>("tags");
|
||||
testOk(tagsField.get() != 0 && tagsField->getElementType() == pvString,
|
||||
"tags is string[]");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void test_ntattribute()
|
||||
{
|
||||
testDiag("test_ntattribute");
|
||||
|
||||
NTAttributeBuilderPtr builder = NTAttribute::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTAttributePtr ntAttribute = builder->
|
||||
addTags()->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
create();
|
||||
testOk1(ntAttribute.get() != 0);
|
||||
|
||||
testOk1(ntAttribute->getPVStructure().get() != 0);
|
||||
testOk1(ntAttribute->getName().get() != 0);
|
||||
testOk1(ntAttribute->getValue().get() != 0);
|
||||
testOk1(ntAttribute->getTags().get() != 0);
|
||||
testOk1(ntAttribute->getDescriptor().get() != 0);
|
||||
testOk1(ntAttribute->getAlarm().get() != 0);
|
||||
testOk1(ntAttribute->getTimeStamp().get() != 0);
|
||||
|
||||
//
|
||||
// timeStamp ops
|
||||
//
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (ntAttribute->attachTimeStamp(pvTimeStamp))
|
||||
{
|
||||
testPass("timeStamp attach");
|
||||
|
||||
// example how to set current time
|
||||
TimeStamp ts;
|
||||
ts.getCurrent();
|
||||
pvTimeStamp.set(ts);
|
||||
|
||||
// example how to get EPICS time
|
||||
TimeStamp ts2;
|
||||
pvTimeStamp.get(ts2);
|
||||
testOk1(ts2.getEpicsSecondsPastEpoch() != 0);
|
||||
}
|
||||
else
|
||||
testFail("timeStamp attach fail");
|
||||
|
||||
//
|
||||
// alarm ops
|
||||
//
|
||||
PVAlarm pvAlarm;
|
||||
if (ntAttribute->attachAlarm(pvAlarm))
|
||||
{
|
||||
testPass("alarm attach");
|
||||
|
||||
// example how to set an alarm
|
||||
Alarm alarm;
|
||||
alarm.setStatus(deviceStatus);
|
||||
alarm.setSeverity(minorAlarm);
|
||||
alarm.setMessage("simulation alarm");
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
else
|
||||
testFail("alarm attach fail");
|
||||
|
||||
//
|
||||
// set descriptor
|
||||
//
|
||||
ntAttribute->getDescriptor()->put("This is a test NTAttribute");
|
||||
|
||||
// dump ntAttribute
|
||||
std::cout << *ntAttribute->getPVStructure() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTAttributePtr nullPtr = NTAttribute::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTAttribute::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTAttributeBuilderPtr builder = NTAttribute::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
testOk1(NTAttribute::isCompatible(pvStructure)==true);
|
||||
NTAttributePtr ptr = NTAttribute::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTAttribute::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testNTAttribute) {
|
||||
testPlan(33);
|
||||
test_builder();
|
||||
test_ntattribute();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
276
test/nt/ntcontinuumTest.cpp
Normal file
276
test/nt/ntcontinuumTest.cpp
Normal file
@@ -0,0 +1,276 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
void test_builder()
|
||||
{
|
||||
testDiag("test_builder");
|
||||
|
||||
NTContinuumBuilderPtr builder = NTContinuum::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTContinuum::is_a(structure));
|
||||
testOk1(structure->getID() == NTContinuum::URI);
|
||||
testOk1(structure->getNumberFields() == 8);
|
||||
testOk1(structure->getField("base").get() != 0);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("units").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
|
||||
testOk(dynamic_pointer_cast<const ScalarArray>(structure->getField("base")).get() != 0 &&
|
||||
dynamic_pointer_cast<const ScalarArray>(structure->getField("base"))->getElementType() == pvDouble, "base array element type");
|
||||
|
||||
testOk(dynamic_pointer_cast<const ScalarArray>(structure->getField("value")).get() != 0 &&
|
||||
dynamic_pointer_cast<const ScalarArray>(structure->getField("value"))->getElementType() == pvDouble, "value array element type");
|
||||
|
||||
testOk(dynamic_pointer_cast<const ScalarArray>(structure->getField("units")).get() != 0 &&
|
||||
dynamic_pointer_cast<const ScalarArray>(structure->getField("units"))->getElementType() == pvString, "units array element type");
|
||||
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
}
|
||||
|
||||
void test_ntcontinuum()
|
||||
{
|
||||
testDiag("test_ntcontinuum");
|
||||
|
||||
NTContinuumBuilderPtr builder = NTContinuum::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTContinuumPtr ntContinuum = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
create();
|
||||
testOk1(ntContinuum.get() != 0);
|
||||
|
||||
testOk1(ntContinuum->getPVStructure().get() != 0);
|
||||
testOk1(ntContinuum->getDescriptor().get() != 0);
|
||||
testOk1(ntContinuum->getAlarm().get() != 0);
|
||||
testOk1(ntContinuum->getTimeStamp().get() != 0);
|
||||
testOk1(ntContinuum->getBase().get() != 0);
|
||||
testOk1(ntContinuum->getValue().get() != 0);
|
||||
//
|
||||
// example how to set base
|
||||
//
|
||||
PVDoubleArray::svector newBase;
|
||||
newBase.push_back(1.0);
|
||||
newBase.push_back(2.0);
|
||||
|
||||
PVDoubleArrayPtr pvBaseField = ntContinuum->getBase();
|
||||
pvBaseField->replace(freeze(newBase));
|
||||
|
||||
//
|
||||
// example how to get bases
|
||||
//
|
||||
PVDoubleArray::const_svector base(pvBaseField->view());
|
||||
|
||||
testOk1(base.size() == 2);
|
||||
testOk1(base[0] == 1.0);
|
||||
testOk1(base[1] == 2.0);
|
||||
|
||||
//
|
||||
// example how to set values
|
||||
//
|
||||
PVDoubleArray::svector newValue;
|
||||
newValue.push_back(1.0);
|
||||
newValue.push_back(2.0);
|
||||
newValue.push_back(10.0);
|
||||
newValue.push_back(20.0);
|
||||
newValue.push_back(100.0);
|
||||
newValue.push_back(200.0);
|
||||
|
||||
PVDoubleArrayPtr pvValueField = ntContinuum->getValue();
|
||||
pvValueField->replace(freeze(newValue));
|
||||
|
||||
//
|
||||
// example how to get values
|
||||
//
|
||||
PVDoubleArray::const_svector value(pvValueField->view());
|
||||
|
||||
testOk1(value.size() == 6);
|
||||
testOk1(value[0] == 1.0);
|
||||
testOk1(value[1] == 2.0);
|
||||
testOk1(value[2] == 10.0);
|
||||
testOk1(value[3] == 20.0);
|
||||
testOk1(value[4] == 100.0);
|
||||
testOk1(value[5] == 200.0);
|
||||
|
||||
//
|
||||
// example how to set units
|
||||
//
|
||||
PVStringArray::svector newUnits;
|
||||
newUnits.push_back("s");
|
||||
newUnits.push_back("ms");
|
||||
newUnits.push_back("us");
|
||||
newUnits.push_back("s");
|
||||
|
||||
PVStringArrayPtr pvUnitsField = ntContinuum->getUnits();
|
||||
pvUnitsField->replace(freeze(newUnits));
|
||||
|
||||
//
|
||||
// example how to get units
|
||||
//
|
||||
PVStringArray::const_svector units(pvUnitsField->view());
|
||||
|
||||
testOk1(units.size() == 4);
|
||||
testOk1(units[0] == "s");
|
||||
testOk1(units[1] == "ms");
|
||||
testOk1(units[2] == "us");
|
||||
testOk1(units[3] == "s");
|
||||
|
||||
//
|
||||
// test isValid
|
||||
//
|
||||
testOk1(ntContinuum->isValid());
|
||||
//
|
||||
// timeStamp ops
|
||||
//
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (ntContinuum->attachTimeStamp(pvTimeStamp))
|
||||
{
|
||||
testPass("timeStamp attach");
|
||||
|
||||
// example how to set current time
|
||||
TimeStamp ts;
|
||||
ts.getCurrent();
|
||||
pvTimeStamp.set(ts);
|
||||
|
||||
// example how to get EPICS time
|
||||
TimeStamp ts2;
|
||||
pvTimeStamp.get(ts2);
|
||||
testOk1(ts2.getEpicsSecondsPastEpoch() != 0);
|
||||
}
|
||||
else
|
||||
testFail("timeStamp attach fail");
|
||||
|
||||
//
|
||||
// alarm ops
|
||||
//
|
||||
PVAlarm pvAlarm;
|
||||
if (ntContinuum->attachAlarm(pvAlarm))
|
||||
{
|
||||
testPass("alarm attach");
|
||||
|
||||
// example how to set an alarm
|
||||
Alarm alarm;
|
||||
alarm.setStatus(deviceStatus);
|
||||
alarm.setSeverity(minorAlarm);
|
||||
alarm.setMessage("simulation alarm");
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
else
|
||||
testFail("alarm attach fail");
|
||||
|
||||
//
|
||||
// set descriptor
|
||||
//
|
||||
ntContinuum->getDescriptor()->put("This is a test NTContinuum");
|
||||
|
||||
// dump NTContinuum
|
||||
std::cout << *ntContinuum->getPVStructure() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTContinuumPtr nullPtr = NTContinuum::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTContinuum::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTContinuumBuilderPtr builder = NTContinuum::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
testOk1(NTContinuum::isCompatible(pvStructure)==true);
|
||||
NTContinuumPtr ptr = NTContinuum::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTContinuum::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
void test_extra()
|
||||
{
|
||||
testDiag("test_extra");
|
||||
|
||||
NTContinuumBuilderPtr builder = NTContinuum::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
addTimeStamp()->
|
||||
add("function", getFieldCreate()->createScalar(pvString))->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTContinuum::is_a(structure));
|
||||
testOk1(structure->getID() == NTContinuum::URI);
|
||||
testOk1(structure->getNumberFields() == 5);
|
||||
testOk1(structure->getField("base").get() != 0);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("units").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
testOk1(structure->getField("function").get() != 0);
|
||||
|
||||
testOk(dynamic_pointer_cast<const Scalar>(structure->getField("function")).get() != 0 &&
|
||||
dynamic_pointer_cast<const Scalar>(structure->getField("function"))->getScalarType() == pvString, "function type");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
}
|
||||
|
||||
|
||||
MAIN(testNTContinuum) {
|
||||
testPlan(59);
|
||||
test_builder();
|
||||
test_ntcontinuum();
|
||||
test_wrap();
|
||||
test_extra();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
188
test/nt/ntenumTest.cpp
Normal file
188
test/nt/ntenumTest.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static StandardFieldPtr standardField = getStandardField();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
void test_builder()
|
||||
{
|
||||
testDiag("test_builder");
|
||||
|
||||
NTEnumBuilderPtr builder = NTEnum::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("valueAlarm",standardField->doubleAlarm()) ->
|
||||
add("extra",fieldCreate->createScalarArray(pvString)) ->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTEnum::is_a(structure));
|
||||
testOk1(structure->getID() == NTEnum::URI);
|
||||
testOk1(structure->getNumberFields() == 6);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
|
||||
FieldConstPtr valueField = structure->getField("value");
|
||||
testOk(valueField.get() != 0 &&
|
||||
ntField->isEnumerated(valueField), "value is enum");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void test_ntenum()
|
||||
{
|
||||
testDiag("test_ntenum");
|
||||
|
||||
NTEnumBuilderPtr builder = NTEnum::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTEnumPtr ntEnum = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("valueAlarm",standardField->intAlarm()) ->
|
||||
create();
|
||||
testOk1(ntEnum.get() != 0);
|
||||
|
||||
testOk1(ntEnum->getPVStructure().get() != 0);
|
||||
testOk1(ntEnum->getValue().get() != 0);
|
||||
testOk1(ntEnum->getDescriptor().get() != 0);
|
||||
testOk1(ntEnum->getAlarm().get() != 0);
|
||||
testOk1(ntEnum->getTimeStamp().get() != 0);
|
||||
|
||||
//
|
||||
// example how to set a value
|
||||
//
|
||||
PVStructurePtr pvValue = ntEnum->getValue();
|
||||
//PVStringArray pvChoices = pvValue->getSubField<PVStringArray>("choices");
|
||||
PVStringArray::svector choices(2);
|
||||
choices[0] = "Off";
|
||||
choices[1] = "On";
|
||||
pvValue->getSubField<PVStringArray>("choices")->replace(freeze(choices));
|
||||
pvValue->getSubField<PVInt>("index")->put(1);
|
||||
|
||||
//
|
||||
// example how to get a value
|
||||
//
|
||||
int32 value = ntEnum->getValue()->getSubField<PVInt>("index")->get();
|
||||
testOk1(value == 1);
|
||||
|
||||
PVStringArrayPtr pvChoices = ntEnum->getValue()->getSubField<PVStringArray>("choices");
|
||||
std::string choice0 = pvChoices->view()[0];
|
||||
std::string choice1 = pvChoices->view()[1];
|
||||
testOk1(choice0 == "Off");
|
||||
testOk1(choice1 == "On");
|
||||
|
||||
//
|
||||
// timeStamp ops
|
||||
//
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (ntEnum->attachTimeStamp(pvTimeStamp))
|
||||
{
|
||||
testPass("timeStamp attach");
|
||||
|
||||
// example how to set current time
|
||||
TimeStamp ts;
|
||||
ts.getCurrent();
|
||||
pvTimeStamp.set(ts);
|
||||
|
||||
// example how to get EPICS time
|
||||
TimeStamp ts2;
|
||||
pvTimeStamp.get(ts2);
|
||||
testOk1(ts2.getEpicsSecondsPastEpoch() != 0);
|
||||
}
|
||||
else
|
||||
testFail("timeStamp attach fail");
|
||||
|
||||
//
|
||||
// alarm ops
|
||||
//
|
||||
PVAlarm pvAlarm;
|
||||
if (ntEnum->attachAlarm(pvAlarm))
|
||||
{
|
||||
testPass("alarm attach");
|
||||
|
||||
// example how to set an alarm
|
||||
Alarm alarm;
|
||||
alarm.setStatus(deviceStatus);
|
||||
alarm.setSeverity(minorAlarm);
|
||||
alarm.setMessage("simulation alarm");
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
else
|
||||
testFail("alarm attach fail");
|
||||
|
||||
//
|
||||
// set descriptor
|
||||
//
|
||||
ntEnum->getDescriptor()->put("This is a test NTEnum");
|
||||
|
||||
// dump ntEnum
|
||||
std::cout << *ntEnum->getPVStructure() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTEnumPtr nullPtr = NTEnum::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTEnum::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTEnumBuilderPtr builder = NTEnum::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
testOk1(NTEnum::isCompatible(pvStructure)==true);
|
||||
NTEnumPtr ptr = NTEnum::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTEnum::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testNTEnum) {
|
||||
testPlan(30);
|
||||
test_builder();
|
||||
test_ntenum();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/*
|
||||
@@ -10,20 +10,16 @@
|
||||
* Author: Marty Kraimer
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <list>
|
||||
|
||||
#include <epicsAssert.h>
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
@@ -31,65 +27,50 @@ static StandardFieldPtr standardField = getStandardField();
|
||||
static StandardPVFieldPtr standardPVField = getStandardPVField();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
static PVNTFieldPtr pvntField = PVNTField::get();
|
||||
static String builder;
|
||||
|
||||
static void testNTField(FILE * fd)
|
||||
void testNTField()
|
||||
{
|
||||
testDiag("testNTField");
|
||||
|
||||
StructureConstPtr structureConstPtr = ntField->createEnumerated();
|
||||
builder.clear();
|
||||
structureConstPtr->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(ntField->isEnumerated(structureConstPtr));
|
||||
cout << *structureConstPtr << endl;
|
||||
testOk1(ntField->isEnumerated(structureConstPtr));
|
||||
|
||||
structureConstPtr = ntField->createTimeStamp();
|
||||
builder.clear();
|
||||
structureConstPtr->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(ntField->isTimeStamp(structureConstPtr));
|
||||
cout << *structureConstPtr << endl;
|
||||
testOk1(ntField->isTimeStamp(structureConstPtr));
|
||||
|
||||
structureConstPtr = ntField->createAlarm();
|
||||
builder.clear();
|
||||
structureConstPtr->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(ntField->isAlarm(structureConstPtr));
|
||||
cout << *structureConstPtr << endl;
|
||||
testOk1(ntField->isAlarm(structureConstPtr));
|
||||
|
||||
structureConstPtr = ntField->createDisplay();
|
||||
builder.clear();
|
||||
structureConstPtr->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(ntField->isDisplay(structureConstPtr));
|
||||
cout << *structureConstPtr << endl;
|
||||
testOk1(ntField->isDisplay(structureConstPtr));
|
||||
|
||||
structureConstPtr = ntField->createAlarmLimit();
|
||||
builder.clear();
|
||||
structureConstPtr->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(ntField->isAlarmLimit(structureConstPtr));
|
||||
structureConstPtr = standardField->doubleAlarm();
|
||||
cout << *structureConstPtr << endl;
|
||||
testOk1(ntField->isAlarmLimit(structureConstPtr));
|
||||
|
||||
structureConstPtr = ntField->createControl();
|
||||
builder.clear();
|
||||
structureConstPtr->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(ntField->isControl(structureConstPtr));
|
||||
cout << *structureConstPtr << endl;
|
||||
testOk1(ntField->isControl(structureConstPtr));
|
||||
|
||||
StructureArrayConstPtr structureArrayConstPtr
|
||||
= ntField->createEnumeratedArray();
|
||||
builder.clear();
|
||||
structureArrayConstPtr->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
cout << *structureConstPtr << endl;
|
||||
|
||||
structureArrayConstPtr = ntField->createTimeStampArray();
|
||||
builder.clear();
|
||||
structureArrayConstPtr->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
cout << *structureConstPtr << endl;
|
||||
|
||||
structureArrayConstPtr = ntField->createAlarmArray();
|
||||
builder.clear();
|
||||
structureArrayConstPtr->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
cout << *structureConstPtr << endl;
|
||||
}
|
||||
|
||||
static void testPVNTField(FILE * fd)
|
||||
void testPVNTField()
|
||||
{
|
||||
testDiag("testPVNTField");
|
||||
|
||||
StringArray choices;
|
||||
choices.resize(3);
|
||||
choices[0] = "one";
|
||||
@@ -97,73 +78,44 @@ static void testPVNTField(FILE * fd)
|
||||
choices[2] = "three";
|
||||
PVStructurePtr pvStructure = PVStructurePtr(
|
||||
pvntField->createEnumerated(choices));
|
||||
builder.clear();
|
||||
pvStructure->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(ntField->isEnumerated(pvStructure->getStructure()));
|
||||
cout << *pvStructure << endl;
|
||||
testOk1(ntField->isEnumerated(pvStructure->getStructure()));
|
||||
|
||||
pvStructure = PVStructurePtr(pvntField->createTimeStamp());
|
||||
builder.clear();
|
||||
pvStructure->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(ntField->isTimeStamp(pvStructure->getStructure()));
|
||||
cout << *pvStructure << endl;
|
||||
testOk1(ntField->isTimeStamp(pvStructure->getStructure()));
|
||||
|
||||
pvStructure = PVStructurePtr(pvntField->createAlarm());
|
||||
builder.clear();
|
||||
pvStructure->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(ntField->isAlarm(pvStructure->getStructure()));
|
||||
cout << *pvStructure << endl;
|
||||
testOk1(ntField->isAlarm(pvStructure->getStructure()));
|
||||
|
||||
pvStructure = PVStructurePtr(pvntField->createDisplay());
|
||||
builder.clear();
|
||||
pvStructure->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(ntField->isDisplay(pvStructure->getStructure()));
|
||||
cout << *pvStructure << endl;
|
||||
testOk1(ntField->isDisplay(pvStructure->getStructure()));
|
||||
|
||||
pvStructure = PVStructurePtr(pvntField->createAlarmLimit());
|
||||
builder.clear();
|
||||
pvStructure->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(ntField->isAlarmLimit(pvStructure->getStructure()));
|
||||
pvStructure = PVStructurePtr(pvDataCreate->createPVStructure(standardField->doubleAlarm()));
|
||||
cout << *pvStructure << endl;
|
||||
testOk1(ntField->isAlarmLimit(pvStructure->getStructure()));
|
||||
|
||||
PVStructureArrayPtr pvStructureArray = PVStructureArrayPtr(
|
||||
pvntField->createEnumeratedArray());
|
||||
builder.clear();
|
||||
pvStructureArray->toString(&builder);
|
||||
fprintf(fd,"\n%s\n",builder.c_str());
|
||||
builder.clear();
|
||||
pvStructureArray->getStructureArray()->getStructure()->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
cout << *pvStructure << endl;
|
||||
cout << *pvStructureArray->getStructureArray()->getStructure();
|
||||
|
||||
pvStructureArray = PVStructureArrayPtr(
|
||||
pvntField->createTimeStampArray());
|
||||
builder.clear();
|
||||
pvStructureArray->toString(&builder);
|
||||
fprintf(fd,"\n%s\n",builder.c_str());
|
||||
builder.clear();
|
||||
pvStructureArray->getStructureArray()->getStructure()->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
cout << *pvStructure << endl;
|
||||
cout << *pvStructureArray->getStructureArray()->getStructure();
|
||||
|
||||
pvStructureArray = PVStructureArrayPtr(
|
||||
pvntField->createAlarmArray());
|
||||
builder.clear();
|
||||
pvStructureArray->toString(&builder);
|
||||
fprintf(fd,"\n%s\n",builder.c_str());
|
||||
builder.clear();
|
||||
pvStructureArray->getStructureArray()->getStructure()->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
cout << *pvStructure << endl;
|
||||
cout << *pvStructureArray->getStructureArray()->getStructure();
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
char *fileName = 0;
|
||||
if(argc>1) fileName = argv[1];
|
||||
FILE * fd = stdout;
|
||||
if(fileName!=0 && fileName[0]!=0) {
|
||||
fd = fopen(fileName,"w+");
|
||||
}
|
||||
testNTField(fd);
|
||||
testPVNTField(fd);
|
||||
return(0);
|
||||
MAIN(testNTField) {
|
||||
testPlan(11);
|
||||
testNTField();
|
||||
testPVNTField();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
261
test/nt/nthistogramTest.cpp
Normal file
261
test/nt/nthistogramTest.cpp
Normal file
@@ -0,0 +1,261 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
void test_builder()
|
||||
{
|
||||
testDiag("test_builder");
|
||||
|
||||
NTHistogramBuilderPtr builder = NTHistogram::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
value(pvLong)->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTHistogram::is_a(structure));
|
||||
testOk1(structure->getID() == NTHistogram::URI);
|
||||
testOk1(structure->getNumberFields() == 7);
|
||||
testOk1(structure->getField("ranges").get() != 0);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
|
||||
testOk(dynamic_pointer_cast<const ScalarArray>(structure->getField("ranges")).get() != 0 &&
|
||||
dynamic_pointer_cast<const ScalarArray>(structure->getField("ranges"))->getElementType() == pvDouble, "ranges array element type");
|
||||
|
||||
testOk(dynamic_pointer_cast<const ScalarArray>(structure->getField("value")).get() != 0 &&
|
||||
dynamic_pointer_cast<const ScalarArray>(structure->getField("value"))->getElementType() == pvLong, "value array element type");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
|
||||
// no value set
|
||||
try
|
||||
{
|
||||
structure = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
createStructure();
|
||||
testFail("no value type set");
|
||||
} catch (std::runtime_error &) {
|
||||
testPass("no value type set");
|
||||
}
|
||||
}
|
||||
|
||||
void test_nthistogram()
|
||||
{
|
||||
testDiag("test_nthistogram");
|
||||
|
||||
NTHistogramBuilderPtr builder = NTHistogram::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTHistogramPtr ntHistogram = builder->
|
||||
value(pvInt)->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
create();
|
||||
testOk1(ntHistogram.get() != 0);
|
||||
|
||||
testOk1(ntHistogram->getPVStructure().get() != 0);
|
||||
testOk1(ntHistogram->getDescriptor().get() != 0);
|
||||
testOk1(ntHistogram->getAlarm().get() != 0);
|
||||
testOk1(ntHistogram->getTimeStamp().get() != 0);
|
||||
testOk1(ntHistogram->getRanges().get() != 0);
|
||||
testOk1(ntHistogram->getValue().get() != 0);
|
||||
testOk1(ntHistogram->getValue<PVIntArray>().get() != 0);
|
||||
//
|
||||
// example how to set ranges
|
||||
//
|
||||
PVDoubleArray::svector newRanges;
|
||||
newRanges.push_back(-100.0);
|
||||
newRanges.push_back(0.0);
|
||||
newRanges.push_back(100.0);
|
||||
|
||||
PVDoubleArrayPtr pvRangesField = ntHistogram->getRanges();
|
||||
pvRangesField->replace(freeze(newRanges));
|
||||
|
||||
//
|
||||
// example how to get ranges
|
||||
//
|
||||
PVDoubleArray::const_svector ranges(pvRangesField->view());
|
||||
|
||||
testOk1(ranges.size() == 3);
|
||||
testOk1(ranges[0] == -100.0);
|
||||
testOk1(ranges[1] == 0.0);
|
||||
testOk1(ranges[2] == 100.0);
|
||||
|
||||
//
|
||||
// example how to set value
|
||||
//
|
||||
PVIntArray::svector newValue;
|
||||
newValue.push_back(1);
|
||||
newValue.push_back(2);
|
||||
|
||||
PVIntArrayPtr pvValueField = ntHistogram->getValue<PVIntArray>();
|
||||
pvValueField->replace(freeze(newValue));
|
||||
|
||||
//
|
||||
// example how to get values for each bin
|
||||
//
|
||||
PVIntArray::const_svector value(pvValueField->view());
|
||||
|
||||
testOk1(value.size() == 2);
|
||||
testOk1(value[0] == 1);
|
||||
testOk1(value[1] == 2);
|
||||
|
||||
//
|
||||
// test isValid
|
||||
//
|
||||
testOk1(ntHistogram->isValid());
|
||||
//
|
||||
// timeStamp ops
|
||||
//
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (ntHistogram->attachTimeStamp(pvTimeStamp))
|
||||
{
|
||||
testPass("timeStamp attach");
|
||||
|
||||
// example how to set current time
|
||||
TimeStamp ts;
|
||||
ts.getCurrent();
|
||||
pvTimeStamp.set(ts);
|
||||
|
||||
// example how to get EPICS time
|
||||
TimeStamp ts2;
|
||||
pvTimeStamp.get(ts2);
|
||||
testOk1(ts2.getEpicsSecondsPastEpoch() != 0);
|
||||
}
|
||||
else
|
||||
testFail("timeStamp attach fail");
|
||||
|
||||
//
|
||||
// alarm ops
|
||||
//
|
||||
PVAlarm pvAlarm;
|
||||
if (ntHistogram->attachAlarm(pvAlarm))
|
||||
{
|
||||
testPass("alarm attach");
|
||||
|
||||
// example how to set an alarm
|
||||
Alarm alarm;
|
||||
alarm.setStatus(deviceStatus);
|
||||
alarm.setSeverity(minorAlarm);
|
||||
alarm.setMessage("simulation alarm");
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
else
|
||||
testFail("alarm attach fail");
|
||||
|
||||
//
|
||||
// set descriptor
|
||||
//
|
||||
ntHistogram->getDescriptor()->put("This is a test NTHistogram");
|
||||
|
||||
// dump NTHistogram
|
||||
std::cout << *ntHistogram->getPVStructure() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTHistogramPtr nullPtr = NTHistogram::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTHistogram::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTHistogramBuilderPtr builder = NTHistogram::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
value(pvInt)->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
testOk1(NTHistogram::isCompatible(pvStructure)==true);
|
||||
NTHistogramPtr ptr = NTHistogram::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTHistogram::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
void test_extra()
|
||||
{
|
||||
testDiag("test_extra");
|
||||
|
||||
NTHistogramBuilderPtr builder = NTHistogram::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
value(pvInt)->
|
||||
addTimeStamp()->
|
||||
add("function", getFieldCreate()->createScalar(pvString))->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTHistogram::is_a(structure));
|
||||
testOk1(structure->getID() == NTHistogram::URI);
|
||||
testOk1(structure->getNumberFields() == 4);
|
||||
testOk1(structure->getField("ranges").get() != 0);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
testOk1(structure->getField("function").get() != 0);
|
||||
|
||||
testOk(dynamic_pointer_cast<const Scalar>(structure->getField("function")).get() != 0 &&
|
||||
dynamic_pointer_cast<const Scalar>(structure->getField("function"))->getScalarType() == pvString, "function type");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
}
|
||||
|
||||
|
||||
MAIN(testNTHistogram) {
|
||||
testPlan(50);
|
||||
test_builder();
|
||||
test_nthistogram();
|
||||
test_wrap();
|
||||
test_extra();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
211
test/nt/ntmatrixTest.cpp
Normal file
211
test/nt/ntmatrixTest.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
void test_builder()
|
||||
{
|
||||
testDiag("test_builder");
|
||||
|
||||
NTMatrixBuilderPtr builder = NTMatrix::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
//arrayValue(pvDouble)->
|
||||
addDim()->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addDisplay()->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTMatrix::is_a(structure));
|
||||
testOk1(structure->getID() == NTMatrix::URI);
|
||||
testOk1(structure->getNumberFields() == 8);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("dim").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
testOk1(structure->getField("display").get() != 0);
|
||||
|
||||
testOk(dynamic_pointer_cast<const ScalarArray>(structure->getField("value")).get() != 0 &&
|
||||
dynamic_pointer_cast<const ScalarArray>(structure->getField("value"))->getElementType() == pvDouble, "value type");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
}
|
||||
|
||||
void test_ntmatrix()
|
||||
{
|
||||
testDiag("test_ntmatrix");
|
||||
|
||||
NTMatrixBuilderPtr builder = NTMatrix::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTMatrixPtr ntScalarArray = builder->
|
||||
//arrayValue(pvInt)->
|
||||
addDim()->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addDisplay()->
|
||||
create();
|
||||
testOk1(ntScalarArray.get() != 0);
|
||||
|
||||
testOk1(ntScalarArray->getPVStructure().get() != 0);
|
||||
testOk1(ntScalarArray->getValue().get() != 0);
|
||||
testOk1(ntScalarArray->getDim().get() != 0);
|
||||
testOk1(ntScalarArray->getDescriptor().get() != 0);
|
||||
testOk1(ntScalarArray->getAlarm().get() != 0);
|
||||
testOk1(ntScalarArray->getTimeStamp().get() != 0);
|
||||
testOk1(ntScalarArray->getDisplay().get() != 0);
|
||||
|
||||
//
|
||||
// example how to set values
|
||||
//
|
||||
PVDoubleArray::svector newValues;
|
||||
newValues.push_back(1.0);
|
||||
newValues.push_back(2.0);
|
||||
newValues.push_back(8.0);
|
||||
|
||||
PVDoubleArrayPtr pvValueField = ntScalarArray->getValue();
|
||||
pvValueField->replace(freeze(newValues));
|
||||
|
||||
//
|
||||
// example how to get values
|
||||
//
|
||||
PVDoubleArray::const_svector values(pvValueField->view());
|
||||
|
||||
testOk1(values.size() == 3);
|
||||
testOk1(values[0] == 1.0);
|
||||
testOk1(values[1] == 2.0);
|
||||
testOk1(values[2] == 8.0);
|
||||
|
||||
//
|
||||
// timeStamp ops
|
||||
//
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (ntScalarArray->attachTimeStamp(pvTimeStamp))
|
||||
{
|
||||
testPass("timeStamp attach");
|
||||
|
||||
// example how to set current time
|
||||
TimeStamp ts;
|
||||
ts.getCurrent();
|
||||
pvTimeStamp.set(ts);
|
||||
|
||||
// example how to get EPICS time
|
||||
TimeStamp ts2;
|
||||
pvTimeStamp.get(ts2);
|
||||
testOk1(ts2.getEpicsSecondsPastEpoch() != 0);
|
||||
}
|
||||
else
|
||||
testFail("timeStamp attach fail");
|
||||
|
||||
//
|
||||
// alarm ops
|
||||
//
|
||||
PVAlarm pvAlarm;
|
||||
if (ntScalarArray->attachAlarm(pvAlarm))
|
||||
{
|
||||
testPass("alarm attach");
|
||||
|
||||
// example how to set an alarm
|
||||
Alarm alarm;
|
||||
alarm.setStatus(deviceStatus);
|
||||
alarm.setSeverity(minorAlarm);
|
||||
alarm.setMessage("simulation alarm");
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
else
|
||||
testFail("alarm attach fail");
|
||||
|
||||
//
|
||||
// display ops
|
||||
//
|
||||
PVDisplay pvDisplay;
|
||||
if (ntScalarArray->attachDisplay(pvDisplay))
|
||||
{
|
||||
testPass("display attach");
|
||||
|
||||
// example how to set an display
|
||||
Display display;
|
||||
display.setLow(-15);
|
||||
display.setHigh(15);
|
||||
display.setDescription("This is a test scalar array");
|
||||
display.setFormat("%d");
|
||||
display.setUnits("A");
|
||||
pvDisplay.set(display);
|
||||
}
|
||||
else
|
||||
testFail("display attach fail");
|
||||
|
||||
//
|
||||
// set descriptor
|
||||
//
|
||||
ntScalarArray->getDescriptor()->put("This is a test NTMatrix");
|
||||
|
||||
// dump ntScalarArray
|
||||
std::cout << *ntScalarArray->getPVStructure() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTMatrixPtr nullPtr = NTMatrix::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTMatrix::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTMatrixBuilderPtr builder = NTMatrix::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
testOk1(NTMatrix::isCompatible(pvStructure)==true);
|
||||
NTMatrixPtr ptr = NTMatrix::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTMatrix::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testNTMatrix) {
|
||||
testPlan(36);
|
||||
test_builder();
|
||||
test_ntmatrix();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
194
test/nt/ntmultiChannelTest.cpp
Normal file
194
test/nt/ntmultiChannelTest.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/*
|
||||
* ntmutiChannelTest.cpp
|
||||
*
|
||||
* Created on: 2014.08
|
||||
* Author: Marty Kraimer
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
|
||||
#include <pv/nt.h>
|
||||
#include <pv/sharedVector.h>
|
||||
#include <pv/ntmultiChannel.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::nt;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::vector;
|
||||
|
||||
static bool debug = false;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
static PVNTFieldPtr pvntField = PVNTField::get();
|
||||
|
||||
static void test()
|
||||
{
|
||||
NTMultiChannelBuilderPtr builder = NTMultiChannel::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTMultiChannelPtr multiChannel = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addSeverity() ->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
create();
|
||||
testOk1(multiChannel.get() != 0);
|
||||
|
||||
PVStructurePtr pvStructure = multiChannel->getPVStructure();
|
||||
testOk1(pvStructure.get()!=NULL);
|
||||
testOk1(NTMultiChannel::is_a(pvStructure->getStructure()));
|
||||
size_t nchan = 3;
|
||||
shared_vector<string> names(nchan);
|
||||
names[0] = "channel 0";
|
||||
names[1] = "channel 1";
|
||||
names[2] = "channel 2";
|
||||
shared_vector<const string> channelNames(freeze(names));
|
||||
PVStringArrayPtr pvChannelName = multiChannel->getChannelName();
|
||||
pvChannelName->replace(channelNames);
|
||||
if(debug) {cout << *pvStructure << endl;}
|
||||
UnionConstPtr unionPtr =
|
||||
fieldCreate->createFieldBuilder()->
|
||||
add("doubleValue", pvDouble)->
|
||||
add("intValue", pvInt)->
|
||||
createUnion();
|
||||
multiChannel = builder->
|
||||
value(unionPtr) ->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addSeverity() ->
|
||||
addIsConnected() ->
|
||||
create();
|
||||
testOk1(multiChannel.get() != 0);
|
||||
pvStructure = multiChannel->getPVStructure();
|
||||
if(debug) {cout << *pvStructure << endl;}
|
||||
pvChannelName = multiChannel->getChannelName();
|
||||
pvChannelName->replace(channelNames);
|
||||
PVUnionArrayPtr pvValue = multiChannel->getValue();
|
||||
shared_vector<PVUnionPtr> unions(nchan);
|
||||
unions[0] = pvDataCreate->createPVUnion(unionPtr);
|
||||
unions[1] = pvDataCreate->createPVUnion(unionPtr);
|
||||
unions[2] = pvDataCreate->createPVUnion(unionPtr);
|
||||
unions[0]->select("doubleValue");
|
||||
unions[1]->select("intValue");
|
||||
unions[2]->select("intValue");
|
||||
PVDoublePtr pvDouble = unions[0]->get<PVDouble>();
|
||||
pvDouble->put(1.235);
|
||||
PVIntPtr pvInt = unions[1]->get<PVInt>();
|
||||
pvInt->put(5);
|
||||
pvInt = unions[2]->get<PVInt>();
|
||||
pvInt->put(7);
|
||||
pvValue->replace(freeze(unions));
|
||||
shared_vector<int32> severities(nchan);
|
||||
severities[0] = 0;
|
||||
severities[1] = 1;
|
||||
severities[2] = 2;
|
||||
PVIntArrayPtr pvSeverity = multiChannel->getSeverity();
|
||||
pvSeverity->replace(freeze(severities));
|
||||
if(debug) {cout << *pvStructure << endl;}
|
||||
PVBooleanArrayPtr pvIsConnected = multiChannel->getIsConnected();
|
||||
shared_vector<const epics::pvData::boolean> isConnected = pvIsConnected->view();
|
||||
multiChannel = builder->
|
||||
value(unionPtr) ->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addSeverity() ->
|
||||
addStatus() ->
|
||||
addMessage() ->
|
||||
addSecondsPastEpoch() ->
|
||||
addNanoseconds() ->
|
||||
addUserTag() ->
|
||||
addIsConnected() ->
|
||||
create();
|
||||
testOk1(multiChannel.get() != 0);
|
||||
pvStructure = multiChannel->getPVStructure();
|
||||
if(debug) {cout << *pvStructure << endl;}
|
||||
testOk1(NTMultiChannel::isCompatible(pvStructure)==true);
|
||||
PVStructurePtr pvTimeStamp = multiChannel->getTimeStamp();
|
||||
testOk1(pvTimeStamp.get() !=0);
|
||||
PVStructurePtr pvAlarm = multiChannel->getAlarm();
|
||||
testOk1(pvAlarm.get() !=0);
|
||||
pvValue = multiChannel->getValue();
|
||||
testOk1(pvValue.get() !=0);
|
||||
pvChannelName = multiChannel->getChannelName();
|
||||
testOk1(pvChannelName.get() !=0);
|
||||
pvIsConnected = multiChannel->getIsConnected();
|
||||
testOk1(pvIsConnected.get() !=0);
|
||||
pvSeverity = multiChannel->getSeverity();
|
||||
testOk1(pvSeverity.get() !=0);
|
||||
PVIntArrayPtr pvStatus = multiChannel->getStatus();
|
||||
testOk1(pvStatus.get() !=0);
|
||||
PVStringArrayPtr pvMessage = multiChannel->getMessage();
|
||||
testOk1(pvMessage.get() !=0);
|
||||
PVLongArrayPtr pvSecondsPastEpoch = multiChannel->getSecondsPastEpoch();
|
||||
testOk1(pvSecondsPastEpoch.get() !=0);
|
||||
PVIntArrayPtr pvNanoseconds = multiChannel->getNanoseconds();
|
||||
testOk1(pvNanoseconds.get() !=0);
|
||||
PVIntArrayPtr pvUserTag = multiChannel->getUserTag();
|
||||
testOk1(pvUserTag.get() !=0);
|
||||
PVStringPtr pvDescriptor = multiChannel->getDescriptor();
|
||||
testOk1(pvDescriptor.get() !=0);
|
||||
}
|
||||
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTMultiChannelPtr nullPtr = NTMultiChannel::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTMultiChannel::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTMultiChannelBuilderPtr builder = NTMultiChannel::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
NTMultiChannelPtr ptr = NTMultiChannel::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
builder = NTMultiChannel::createBuilder();
|
||||
ptr = NTMultiChannel::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testCreateRequest)
|
||||
{
|
||||
testPlan(25);
|
||||
test();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -1,87 +1,256 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/*
|
||||
* ntnameValueTest.cpp
|
||||
*
|
||||
* Created on: 2011.11
|
||||
* Author: Marty Kraimer
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <list>
|
||||
|
||||
#include <epicsAssert.h>
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
static PVNTFieldPtr pvntField = PVNTField::get();
|
||||
static String builder;
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
static void test(FILE * fd)
|
||||
void test_builder()
|
||||
{
|
||||
NTNameValuePtr ntNameValue = NTNameValue::create(true,true,true);
|
||||
PVStructurePtr pvStructure = ntNameValue->getPVStructure();
|
||||
builder.clear();
|
||||
pvStructure->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
builder.clear();
|
||||
pvStructure->getStructure()->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
PVStringArrayPtr names = ntNameValue->getNames();
|
||||
PVStringArrayPtr values = ntNameValue->getValues();
|
||||
size_t n = 2;
|
||||
StringArray name;
|
||||
StringArray value;
|
||||
name.resize(n);
|
||||
value.resize(n);
|
||||
name[0] = "name 0";
|
||||
name[1] = "name 1";
|
||||
value[0] = "value 0";
|
||||
value[1] = "value 1";
|
||||
names->put(0,n,name,0);
|
||||
values->put(0,n,value,0);
|
||||
PVStringPtr function = ntNameValue->getFunction();
|
||||
function->put("test");
|
||||
PVAlarm pvAlarm;
|
||||
ntNameValue->attachAlarm(pvAlarm);
|
||||
Alarm alarm;
|
||||
alarm.setMessage("test alarm");
|
||||
alarm.setSeverity(majorAlarm);
|
||||
alarm.setStatus(clientStatus);
|
||||
pvAlarm.set(alarm);
|
||||
PVTimeStamp pvTimeStamp;
|
||||
ntNameValue->attachTimeStamp(pvTimeStamp);
|
||||
TimeStamp timeStamp(1000,1000,10);
|
||||
pvTimeStamp.set(timeStamp);
|
||||
builder.clear();
|
||||
pvStructure->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(NTNameValue::isNTNameValue(pvStructure));
|
||||
}
|
||||
testDiag("test_builder");
|
||||
|
||||
NTNameValueBuilderPtr builder = NTNameValue::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
char *fileName = 0;
|
||||
if(argc>1) fileName = argv[1];
|
||||
FILE * fd = stdout;
|
||||
if(fileName!=0 && fileName[0]!=0) {
|
||||
fd = fopen(fileName,"w+");
|
||||
StructureConstPtr structure = builder->
|
||||
value(pvDouble)->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTNameValue::is_a(structure));
|
||||
testOk1(structure->getID() == NTNameValue::URI);
|
||||
testOk1(structure->getNumberFields() == 7);
|
||||
testOk1(structure->getField("name").get() != 0);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
|
||||
testOk(dynamic_pointer_cast<const ScalarArray>(structure->getField("value")).get() != 0 &&
|
||||
dynamic_pointer_cast<const ScalarArray>(structure->getField("value"))->getElementType() == pvDouble, "value array element type");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
|
||||
// no value set
|
||||
try
|
||||
{
|
||||
structure = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
createStructure();
|
||||
testFail("no value type set");
|
||||
} catch (std::runtime_error &) {
|
||||
testPass("no value type set");
|
||||
}
|
||||
test(fd);
|
||||
return(0);
|
||||
}
|
||||
|
||||
void test_ntnameValue()
|
||||
{
|
||||
testDiag("test_ntnameValue");
|
||||
|
||||
NTNameValueBuilderPtr builder = NTNameValue::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTNameValuePtr ntNameValue = builder->
|
||||
value(pvInt)->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
create();
|
||||
testOk1(ntNameValue.get() != 0);
|
||||
|
||||
testOk1(ntNameValue->getPVStructure().get() != 0);
|
||||
testOk1(ntNameValue->getDescriptor().get() != 0);
|
||||
testOk1(ntNameValue->getAlarm().get() != 0);
|
||||
testOk1(ntNameValue->getTimeStamp().get() != 0);
|
||||
testOk1(ntNameValue->getName().get() != 0);
|
||||
testOk1(ntNameValue->getValue().get() != 0);
|
||||
|
||||
//
|
||||
// example how to set name
|
||||
//
|
||||
PVStringArray::svector newName;
|
||||
newName.push_back("name1");
|
||||
newName.push_back("name2");
|
||||
newName.push_back("name3");
|
||||
|
||||
PVStringArrayPtr pvNameField = ntNameValue->getName();
|
||||
pvNameField->replace(freeze(newName));
|
||||
|
||||
//
|
||||
// example how to get name
|
||||
//
|
||||
PVStringArray::const_svector name(pvNameField->view());
|
||||
|
||||
testOk1(name.size() == 3);
|
||||
testOk1(name[0] == "name1");
|
||||
testOk1(name[1] == "name2");
|
||||
testOk1(name[2] == "name3");
|
||||
|
||||
//
|
||||
// example how to set value
|
||||
//
|
||||
PVIntArray::svector newValue;
|
||||
newValue.push_back(1);
|
||||
newValue.push_back(2);
|
||||
newValue.push_back(8);
|
||||
|
||||
PVIntArrayPtr pvValueField = ntNameValue->getValue<PVIntArray>();
|
||||
pvValueField->replace(freeze(newValue));
|
||||
|
||||
//
|
||||
// example how to get column value
|
||||
//
|
||||
PVIntArray::const_svector value(pvValueField->view());
|
||||
|
||||
testOk1(value.size() == 3);
|
||||
testOk1(value[0] == 1);
|
||||
testOk1(value[1] == 2);
|
||||
testOk1(value[2] == 8);
|
||||
|
||||
//
|
||||
// timeStamp ops
|
||||
//
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (ntNameValue->attachTimeStamp(pvTimeStamp))
|
||||
{
|
||||
testPass("timeStamp attach");
|
||||
|
||||
// example how to set current time
|
||||
TimeStamp ts;
|
||||
ts.getCurrent();
|
||||
pvTimeStamp.set(ts);
|
||||
|
||||
// example how to get EPICS time
|
||||
TimeStamp ts2;
|
||||
pvTimeStamp.get(ts2);
|
||||
testOk1(ts2.getEpicsSecondsPastEpoch() != 0);
|
||||
}
|
||||
else
|
||||
testFail("timeStamp attach fail");
|
||||
|
||||
//
|
||||
// alarm ops
|
||||
//
|
||||
PVAlarm pvAlarm;
|
||||
if (ntNameValue->attachAlarm(pvAlarm))
|
||||
{
|
||||
testPass("alarm attach");
|
||||
|
||||
// example how to set an alarm
|
||||
Alarm alarm;
|
||||
alarm.setStatus(deviceStatus);
|
||||
alarm.setSeverity(minorAlarm);
|
||||
alarm.setMessage("simulation alarm");
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
else
|
||||
testFail("alarm attach fail");
|
||||
|
||||
//
|
||||
// set descriptor
|
||||
//
|
||||
ntNameValue->getDescriptor()->put("This is a test NTNameValue");
|
||||
|
||||
// dump NTNameValue
|
||||
std::cout << *ntNameValue->getPVStructure() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTNameValuePtr nullPtr = NTNameValue::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTNameValue::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTNameValueBuilderPtr builder = NTNameValue::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
value(pvString)->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
testOk1(NTNameValue::isCompatible(pvStructure)==true);
|
||||
NTNameValuePtr ptr = NTNameValue::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTNameValue::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
void test_extra()
|
||||
{
|
||||
testDiag("test_extra");
|
||||
|
||||
NTNameValueBuilderPtr builder = NTNameValue::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
value(pvDouble)->
|
||||
addTimeStamp()->
|
||||
add("function", getFieldCreate()->createScalar(pvString))->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTNameValue::is_a(structure));
|
||||
testOk1(structure->getID() == NTNameValue::URI);
|
||||
testOk1(structure->getNumberFields() == 4);
|
||||
testOk1(structure->getField("name").get() != 0);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
testOk1(structure->getField("function").get() != 0);
|
||||
|
||||
testOk(dynamic_pointer_cast<const Scalar>(structure->getField("function")).get() != 0 &&
|
||||
dynamic_pointer_cast<const Scalar>(structure->getField("function"))->getScalarType() == pvString, "function type");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
}
|
||||
|
||||
|
||||
MAIN(testNTNameValue) {
|
||||
testPlan(48);
|
||||
test_builder();
|
||||
test_ntnameValue();
|
||||
test_wrap();
|
||||
test_extra();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
|
||||
178
test/nt/ntndarrayAttributeTest.cpp
Normal file
178
test/nt/ntndarrayAttributeTest.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
*/
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static StandardFieldPtr standardField = getStandardField();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
void test_builder()
|
||||
{
|
||||
testDiag("test_builder");
|
||||
|
||||
NTNDArrayAttributeBuilderPtr builder = NTNDArrayAttribute::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
addTags()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("extra",fieldCreate->createScalar(pvString)) ->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTNDArrayAttribute::is_a(structure));
|
||||
testOk1(structure->getID() == NTNDArrayAttribute::URI);
|
||||
testOk1(structure->getNumberFields() == 9);
|
||||
testOk1(structure->getField("name").get() != 0);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("tags").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
testOk1(structure->getField("sourceType").get() != 0);
|
||||
testOk1(structure->getField("source").get() != 0);
|
||||
|
||||
ScalarConstPtr nameField = structure->getField<Scalar>("name");
|
||||
testOk(nameField.get() != 0 && nameField->getScalarType() == pvString,
|
||||
"name is string");
|
||||
|
||||
UnionConstPtr valueField = structure->getField<Union>("value");
|
||||
testOk(valueField.get() != 0, "value is enum");
|
||||
|
||||
ScalarArrayConstPtr tagsField = structure->getField<ScalarArray>("tags");
|
||||
testOk(tagsField.get() != 0 && tagsField->getElementType() == pvString,
|
||||
"tags is string[]");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void test_ntndarrayAttribute()
|
||||
{
|
||||
testDiag("test_ntndarrayAttribute");
|
||||
|
||||
NTNDArrayAttributeBuilderPtr builder = NTNDArrayAttribute::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTNDArrayAttributePtr ntNDArrayAttribute = builder->
|
||||
addTags()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
create();
|
||||
testOk1(ntNDArrayAttribute.get() != 0);
|
||||
|
||||
testOk1(ntNDArrayAttribute->getPVStructure().get() != 0);
|
||||
testOk1(ntNDArrayAttribute->getName().get() != 0);
|
||||
testOk1(ntNDArrayAttribute->getValue().get() != 0);
|
||||
testOk1(ntNDArrayAttribute->getTags().get() != 0);
|
||||
testOk1(ntNDArrayAttribute->getDescriptor().get() != 0);
|
||||
testOk1(ntNDArrayAttribute->getAlarm().get() != 0);
|
||||
testOk1(ntNDArrayAttribute->getTimeStamp().get() != 0);
|
||||
testOk1(ntNDArrayAttribute->getSourceType().get() != 0);
|
||||
testOk1(ntNDArrayAttribute->getSource().get() != 0);
|
||||
|
||||
//
|
||||
// timeStamp ops
|
||||
//
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (ntNDArrayAttribute->attachTimeStamp(pvTimeStamp))
|
||||
{
|
||||
testPass("timeStamp attach");
|
||||
|
||||
// example how to set current time
|
||||
TimeStamp ts;
|
||||
ts.getCurrent();
|
||||
pvTimeStamp.set(ts);
|
||||
|
||||
// example how to get EPICS time
|
||||
TimeStamp ts2;
|
||||
pvTimeStamp.get(ts2);
|
||||
testOk1(ts2.getEpicsSecondsPastEpoch() != 0);
|
||||
}
|
||||
else
|
||||
testFail("timeStamp attach fail");
|
||||
|
||||
//
|
||||
// alarm ops
|
||||
//
|
||||
PVAlarm pvAlarm;
|
||||
if (ntNDArrayAttribute->attachAlarm(pvAlarm))
|
||||
{
|
||||
testPass("alarm attach");
|
||||
|
||||
// example how to set an alarm
|
||||
Alarm alarm;
|
||||
alarm.setStatus(deviceStatus);
|
||||
alarm.setSeverity(minorAlarm);
|
||||
alarm.setMessage("simulation alarm");
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
else
|
||||
testFail("alarm attach fail");
|
||||
|
||||
//
|
||||
// set descriptor
|
||||
//
|
||||
ntNDArrayAttribute->getDescriptor()->put("This is a test NTNDArrayAttribute");
|
||||
|
||||
// dump ntNDArrayAttribute
|
||||
std::cout << *ntNDArrayAttribute->getPVStructure() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTNDArrayAttributePtr nullPtr = NTNDArrayAttribute::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTNDArrayAttribute::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTNDArrayAttributeBuilderPtr builder = NTNDArrayAttribute::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
testOk1(NTNDArrayAttribute::isCompatible(pvStructure)==true);
|
||||
NTNDArrayAttributePtr ptr = NTNDArrayAttribute::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTNDArrayAttribute::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testNTNDArrayAttribute) {
|
||||
testPlan(37);
|
||||
test_builder();
|
||||
test_ntndarrayAttribute();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
125
test/nt/ntndarrayTest.cpp
Normal file
125
test/nt/ntndarrayTest.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
void test_builder(bool extraFields)
|
||||
{
|
||||
testDiag("test_builder");
|
||||
|
||||
NTNDArrayBuilderPtr builder = NTNDArray::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
builder->addDescriptor()->
|
||||
addTimeStamp()->
|
||||
addAlarm()->
|
||||
addDisplay();
|
||||
|
||||
if (extraFields)
|
||||
{
|
||||
builder->add("extra1",fieldCreate->createScalar(pvString))->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString));
|
||||
}
|
||||
|
||||
StructureConstPtr structure = builder->createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTNDArray::is_a(structure));
|
||||
testOk1(structure->getID() == NTNDArray::URI);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("compressedSize").get() != 0);
|
||||
testOk1(structure->getField("uncompressedSize").get() != 0);
|
||||
testOk1(structure->getField("codec").get() != 0);
|
||||
testOk1(structure->getField("dimension").get() != 0);
|
||||
testOk1(structure->getField("uniqueId").get() != 0);
|
||||
testOk1(structure->getField("dataTimeStamp").get() != 0);
|
||||
testOk1(structure->getField("attribute").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
testOk1(structure->getField("display").get() != 0);
|
||||
if (extraFields)
|
||||
{
|
||||
testOk1(structure->getField("extra1").get() != 0);
|
||||
testOk1(structure->getField("extra2").get() != 0);
|
||||
}
|
||||
std::cout << *structure << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void test_all()
|
||||
{
|
||||
testDiag("test_builder");
|
||||
|
||||
NTNDArrayBuilderPtr builder = NTNDArray::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
addDescriptor()->
|
||||
addTimeStamp()->
|
||||
addAlarm()->
|
||||
addDisplay()->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
createPVStructure();
|
||||
std::cout << *pvStructure << std::endl;
|
||||
testOk1(NTNDArray::isCompatible(pvStructure)==true);
|
||||
}
|
||||
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTNDArrayPtr nullPtr = NTNDArray::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTNDArray::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTNDArrayBuilderPtr builder = NTNDArray::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
testOk1(NTNDArray::isCompatible(pvStructure)==true);
|
||||
|
||||
NTNDArrayPtr ptr = NTNDArray::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTNDArray::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testNTNDArray) {
|
||||
testPlan(59);
|
||||
test_builder(true);
|
||||
test_builder(false);
|
||||
test_builder(false); // called twice to test caching
|
||||
test_all();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
245
test/nt/ntscalarArrayTest.cpp
Normal file
245
test/nt/ntscalarArrayTest.cpp
Normal file
@@ -0,0 +1,245 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
void test_builder()
|
||||
{
|
||||
testDiag("test_builder");
|
||||
|
||||
NTScalarArrayBuilderPtr builder = NTScalarArray::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
arrayValue(pvDouble)->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addDisplay()->
|
||||
addControl()->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTScalarArray::is_a(structure));
|
||||
testOk1(structure->getID() == NTScalarArray::URI);
|
||||
testOk1(structure->getNumberFields() == 8);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
testOk1(structure->getField("display").get() != 0);
|
||||
testOk1(structure->getField("control").get() != 0);
|
||||
|
||||
testOk(dynamic_pointer_cast<const ScalarArray>(structure->getField("value")).get() != 0 &&
|
||||
dynamic_pointer_cast<const ScalarArray>(structure->getField("value"))->getElementType() == pvDouble, "value type");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
|
||||
// no value set
|
||||
try
|
||||
{
|
||||
structure = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addDisplay()->
|
||||
addControl()->
|
||||
createStructure();
|
||||
testFail("no value type set");
|
||||
} catch (std::runtime_error &) {
|
||||
testPass("no value type set");
|
||||
}
|
||||
}
|
||||
|
||||
void test_ntscalarArray()
|
||||
{
|
||||
testDiag("test_ntscalarArray");
|
||||
|
||||
NTScalarArrayBuilderPtr builder = NTScalarArray::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTScalarArrayPtr ntScalarArray = builder->
|
||||
arrayValue(pvInt)->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addDisplay()->
|
||||
addControl()->
|
||||
create();
|
||||
testOk1(ntScalarArray.get() != 0);
|
||||
|
||||
testOk1(ntScalarArray->getPVStructure().get() != 0);
|
||||
testOk1(ntScalarArray->getValue().get() != 0);
|
||||
testOk1(ntScalarArray->getDescriptor().get() != 0);
|
||||
testOk1(ntScalarArray->getAlarm().get() != 0);
|
||||
testOk1(ntScalarArray->getTimeStamp().get() != 0);
|
||||
testOk1(ntScalarArray->getDisplay().get() != 0);
|
||||
testOk1(ntScalarArray->getControl().get() != 0);
|
||||
|
||||
//
|
||||
// example how to set values
|
||||
//
|
||||
PVIntArray::svector newValues;
|
||||
newValues.push_back(1);
|
||||
newValues.push_back(2);
|
||||
newValues.push_back(8);
|
||||
|
||||
PVIntArrayPtr pvValueField = ntScalarArray->getValue<PVIntArray>();
|
||||
pvValueField->replace(freeze(newValues));
|
||||
|
||||
//
|
||||
// example how to get values
|
||||
//
|
||||
PVIntArray::const_svector values(pvValueField->view());
|
||||
|
||||
testOk1(values.size() == 3);
|
||||
testOk1(values[0] == 1);
|
||||
testOk1(values[1] == 2);
|
||||
testOk1(values[2] == 8);
|
||||
|
||||
//
|
||||
// timeStamp ops
|
||||
//
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (ntScalarArray->attachTimeStamp(pvTimeStamp))
|
||||
{
|
||||
testPass("timeStamp attach");
|
||||
|
||||
// example how to set current time
|
||||
TimeStamp ts;
|
||||
ts.getCurrent();
|
||||
pvTimeStamp.set(ts);
|
||||
|
||||
// example how to get EPICS time
|
||||
TimeStamp ts2;
|
||||
pvTimeStamp.get(ts2);
|
||||
testOk1(ts2.getEpicsSecondsPastEpoch() != 0);
|
||||
}
|
||||
else
|
||||
testFail("timeStamp attach fail");
|
||||
|
||||
//
|
||||
// alarm ops
|
||||
//
|
||||
PVAlarm pvAlarm;
|
||||
if (ntScalarArray->attachAlarm(pvAlarm))
|
||||
{
|
||||
testPass("alarm attach");
|
||||
|
||||
// example how to set an alarm
|
||||
Alarm alarm;
|
||||
alarm.setStatus(deviceStatus);
|
||||
alarm.setSeverity(minorAlarm);
|
||||
alarm.setMessage("simulation alarm");
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
else
|
||||
testFail("alarm attach fail");
|
||||
|
||||
//
|
||||
// display ops
|
||||
//
|
||||
PVDisplay pvDisplay;
|
||||
if (ntScalarArray->attachDisplay(pvDisplay))
|
||||
{
|
||||
testPass("display attach");
|
||||
|
||||
// example how to set an display
|
||||
Display display;
|
||||
display.setLow(-15);
|
||||
display.setHigh(15);
|
||||
display.setDescription("This is a test scalar array");
|
||||
display.setFormat("%d");
|
||||
display.setUnits("A");
|
||||
pvDisplay.set(display);
|
||||
}
|
||||
else
|
||||
testFail("display attach fail");
|
||||
|
||||
//
|
||||
// control ops
|
||||
//
|
||||
PVControl pvControl;
|
||||
if (ntScalarArray->attachControl(pvControl))
|
||||
{
|
||||
testPass("control attach");
|
||||
|
||||
// example how to set an control
|
||||
Control control;
|
||||
control.setLow(-10);
|
||||
control.setHigh(10);
|
||||
control.setMinStep(1);
|
||||
pvControl.set(control);
|
||||
}
|
||||
else
|
||||
testFail("control attach fail");
|
||||
|
||||
//
|
||||
// set descriptor
|
||||
//
|
||||
ntScalarArray->getDescriptor()->put("This is a test NTScalarArray");
|
||||
|
||||
// dump ntScalarArray
|
||||
std::cout << *ntScalarArray->getPVStructure() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTScalarArrayPtr nullPtr = NTScalarArray::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTScalarArray::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTScalarArrayBuilderPtr builder = NTScalarArray::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
arrayValue(pvDouble)->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
testOk1(NTScalarArray::isCompatible(pvStructure)==true);
|
||||
NTScalarArrayPtr ptr = NTScalarArray::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTScalarArray::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testNTScalarArray) {
|
||||
testPlan(38);
|
||||
test_builder();
|
||||
test_ntscalarArray();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
181
test/nt/ntscalarMultiChannelTest.cpp
Normal file
181
test/nt/ntscalarMultiChannelTest.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/*
|
||||
* ntscalarMultiChannelTest.cpp
|
||||
*
|
||||
* Created on: 2015.08
|
||||
* Authors: Marty Kraimer, Dave Hickin
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
|
||||
#include <pv/nt.h>
|
||||
#include <pv/sharedVector.h>
|
||||
#include <pv/ntscalarMultiChannel.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::nt;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::vector;
|
||||
|
||||
static bool debug = false;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
static PVNTFieldPtr pvntField = PVNTField::get();
|
||||
|
||||
static void test()
|
||||
{
|
||||
NTScalarMultiChannelBuilderPtr builder = NTScalarMultiChannel::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTScalarMultiChannelPtr multiChannel = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addSeverity() ->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
create();
|
||||
testOk1(multiChannel.get() != 0);
|
||||
|
||||
PVStructurePtr pvStructure = multiChannel->getPVStructure();
|
||||
testOk1(pvStructure.get()!=NULL);
|
||||
testOk1(NTScalarMultiChannel::is_a(pvStructure->getStructure()));
|
||||
size_t nchan = 3;
|
||||
shared_vector<string> names(nchan);
|
||||
names[0] = "channel 0";
|
||||
names[1] = "channel 1";
|
||||
names[2] = "channel 2";
|
||||
shared_vector<const string> channelNames(freeze(names));
|
||||
PVStringArrayPtr pvChannelName = multiChannel->getChannelName();
|
||||
pvChannelName->replace(channelNames);
|
||||
if(debug) {cout << *pvStructure << endl;}
|
||||
multiChannel = builder->
|
||||
value(pvDouble) ->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addSeverity() ->
|
||||
addIsConnected() ->
|
||||
create();
|
||||
testOk1(multiChannel.get() != 0);
|
||||
pvStructure = multiChannel->getPVStructure();
|
||||
if(debug) {cout << *pvStructure << endl;}
|
||||
pvChannelName = multiChannel->getChannelName();
|
||||
pvChannelName->replace(channelNames);
|
||||
PVDoubleArrayPtr pvValue = multiChannel->getValue<PVDoubleArray>();
|
||||
PVDoubleArray::svector doubles(nchan);
|
||||
doubles.resize(nchan);
|
||||
doubles[0] = 3.14159;
|
||||
doubles[1] = 2.71828;
|
||||
doubles[2] = 137.036;
|
||||
pvValue->replace(freeze(doubles));
|
||||
shared_vector<int32> severities(nchan);
|
||||
severities[0] = 0;
|
||||
severities[1] = 1;
|
||||
severities[2] = 2;
|
||||
PVIntArrayPtr pvSeverity = multiChannel->getSeverity();
|
||||
pvSeverity->replace(freeze(severities));
|
||||
if(debug) {cout << *pvStructure << endl;}
|
||||
PVBooleanArrayPtr pvIsConnected = multiChannel->getIsConnected();
|
||||
shared_vector<const epics::pvData::boolean> isConnected = pvIsConnected->view();
|
||||
multiChannel = builder->
|
||||
value(pvDouble) ->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addSeverity() ->
|
||||
addStatus() ->
|
||||
addMessage() ->
|
||||
addSecondsPastEpoch() ->
|
||||
addNanoseconds() ->
|
||||
addUserTag() ->
|
||||
addIsConnected() ->
|
||||
create();
|
||||
testOk1(multiChannel.get() != 0);
|
||||
pvStructure = multiChannel->getPVStructure();
|
||||
if(debug) {cout << *pvStructure << endl;}
|
||||
testOk1(NTScalarMultiChannel::isCompatible(pvStructure)==true);
|
||||
PVStructurePtr pvTimeStamp = multiChannel->getTimeStamp();
|
||||
testOk1(pvTimeStamp.get() !=0);
|
||||
PVStructurePtr pvAlarm = multiChannel->getAlarm();
|
||||
testOk1(pvAlarm.get() !=0);
|
||||
pvValue = multiChannel->getValue<PVDoubleArray>();
|
||||
testOk1(pvValue.get() !=0);
|
||||
pvChannelName = multiChannel->getChannelName();
|
||||
testOk1(pvChannelName.get() !=0);
|
||||
pvIsConnected = multiChannel->getIsConnected();
|
||||
testOk1(pvIsConnected.get() !=0);
|
||||
pvSeverity = multiChannel->getSeverity();
|
||||
testOk1(pvSeverity.get() !=0);
|
||||
PVIntArrayPtr pvStatus = multiChannel->getStatus();
|
||||
testOk1(pvStatus.get() !=0);
|
||||
PVStringArrayPtr pvMessage = multiChannel->getMessage();
|
||||
testOk1(pvMessage.get() !=0);
|
||||
PVLongArrayPtr pvSecondsPastEpoch = multiChannel->getSecondsPastEpoch();
|
||||
testOk1(pvSecondsPastEpoch.get() !=0);
|
||||
PVIntArrayPtr pvNanoseconds = multiChannel->getNanoseconds();
|
||||
testOk1(pvNanoseconds.get() !=0);
|
||||
PVIntArrayPtr pvUserTag = multiChannel->getUserTag();
|
||||
testOk1(pvUserTag.get() !=0);
|
||||
PVStringPtr pvDescriptor = multiChannel->getDescriptor();
|
||||
testOk1(pvDescriptor.get() !=0);
|
||||
}
|
||||
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTScalarMultiChannelPtr nullPtr = NTScalarMultiChannel::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTScalarMultiChannel::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTScalarMultiChannelBuilderPtr builder = NTScalarMultiChannel::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
NTScalarMultiChannelPtr ptr = NTScalarMultiChannel::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
builder = NTScalarMultiChannel::createBuilder();
|
||||
ptr = NTScalarMultiChannel::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testCreateRequest)
|
||||
{
|
||||
testPlan(25);
|
||||
test();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
236
test/nt/ntscalarTest.cpp
Normal file
236
test/nt/ntscalarTest.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static StandardFieldPtr standardField = getStandardField();
|
||||
void test_builder()
|
||||
{
|
||||
testDiag("test_builder");
|
||||
|
||||
NTScalarBuilderPtr builder = NTScalar::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
value(pvDouble)->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addDisplay()->
|
||||
addControl()->
|
||||
add("valueAlarm",standardField->doubleAlarm()) ->
|
||||
add("extra",fieldCreate->createScalarArray(pvString)) ->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTScalar::is_a(structure));
|
||||
testOk1(structure->getID() == NTScalar::URI);
|
||||
testOk1(structure->getNumberFields() == 8);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
testOk1(structure->getField("display").get() != 0);
|
||||
testOk1(structure->getField("control").get() != 0);
|
||||
|
||||
testOk(dynamic_pointer_cast<const Scalar>(structure->getField("value")).get() != 0 &&
|
||||
dynamic_pointer_cast<const Scalar>(structure->getField("value"))->getScalarType() == pvDouble, "value type");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
|
||||
// no value set
|
||||
try
|
||||
{
|
||||
structure = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addDisplay()->
|
||||
addControl()->
|
||||
createStructure();
|
||||
testFail("no value type set");
|
||||
} catch (std::runtime_error &) {
|
||||
testPass("no value type set");
|
||||
}
|
||||
}
|
||||
|
||||
void test_ntscalar()
|
||||
{
|
||||
testDiag("test_ntscalar");
|
||||
|
||||
NTScalarBuilderPtr builder = NTScalar::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTScalarPtr ntScalar = builder->
|
||||
value(pvInt)->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addDisplay()->
|
||||
addControl()->
|
||||
add("valueAlarm",standardField->intAlarm()) ->
|
||||
create();
|
||||
testOk1(ntScalar.get() != 0);
|
||||
|
||||
testOk1(ntScalar->getPVStructure().get() != 0);
|
||||
testOk1(ntScalar->getValue().get() != 0);
|
||||
testOk1(ntScalar->getDescriptor().get() != 0);
|
||||
testOk1(ntScalar->getAlarm().get() != 0);
|
||||
testOk1(ntScalar->getTimeStamp().get() != 0);
|
||||
testOk1(ntScalar->getDisplay().get() != 0);
|
||||
testOk1(ntScalar->getControl().get() != 0);
|
||||
|
||||
//
|
||||
// example how to set a value
|
||||
//
|
||||
ntScalar->getValue<PVInt>()->put(12);
|
||||
|
||||
//
|
||||
// example how to get a value
|
||||
//
|
||||
int32 value = ntScalar->getValue<PVInt>()->get();
|
||||
testOk1(value == 12);
|
||||
|
||||
//
|
||||
// timeStamp ops
|
||||
//
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (ntScalar->attachTimeStamp(pvTimeStamp))
|
||||
{
|
||||
testPass("timeStamp attach");
|
||||
|
||||
// example how to set current time
|
||||
TimeStamp ts;
|
||||
ts.getCurrent();
|
||||
pvTimeStamp.set(ts);
|
||||
|
||||
// example how to get EPICS time
|
||||
TimeStamp ts2;
|
||||
pvTimeStamp.get(ts2);
|
||||
testOk1(ts2.getEpicsSecondsPastEpoch() != 0);
|
||||
}
|
||||
else
|
||||
testFail("timeStamp attach fail");
|
||||
|
||||
//
|
||||
// alarm ops
|
||||
//
|
||||
PVAlarm pvAlarm;
|
||||
if (ntScalar->attachAlarm(pvAlarm))
|
||||
{
|
||||
testPass("alarm attach");
|
||||
|
||||
// example how to set an alarm
|
||||
Alarm alarm;
|
||||
alarm.setStatus(deviceStatus);
|
||||
alarm.setSeverity(minorAlarm);
|
||||
alarm.setMessage("simulation alarm");
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
else
|
||||
testFail("alarm attach fail");
|
||||
|
||||
//
|
||||
// display ops
|
||||
//
|
||||
PVDisplay pvDisplay;
|
||||
if (ntScalar->attachDisplay(pvDisplay))
|
||||
{
|
||||
testPass("display attach");
|
||||
|
||||
// example how to set an display
|
||||
Display display;
|
||||
display.setLow(-15);
|
||||
display.setHigh(15);
|
||||
display.setDescription("This is a test scalar");
|
||||
display.setFormat("%d");
|
||||
display.setUnits("A");
|
||||
pvDisplay.set(display);
|
||||
}
|
||||
else
|
||||
testFail("display attach fail");
|
||||
|
||||
//
|
||||
// control ops
|
||||
//
|
||||
PVControl pvControl;
|
||||
if (ntScalar->attachControl(pvControl))
|
||||
{
|
||||
testPass("control attach");
|
||||
|
||||
// example how to set an control
|
||||
Control control;
|
||||
control.setLow(-10);
|
||||
control.setHigh(10);
|
||||
control.setMinStep(1);
|
||||
pvControl.set(control);
|
||||
}
|
||||
else
|
||||
testFail("control attach fail");
|
||||
|
||||
//
|
||||
// set descriptor
|
||||
//
|
||||
ntScalar->getDescriptor()->put("This is a test NTScalar");
|
||||
|
||||
// dump ntScalar
|
||||
std::cout << *ntScalar->getPVStructure() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTScalarPtr nullPtr = NTScalar::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTScalar::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTScalarBuilderPtr builder = NTScalar::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
value(pvDouble)->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
testOk1(NTScalar::isCompatible(pvStructure)==true);
|
||||
NTScalarPtr ptr = NTScalar::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTScalar::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testNTScalar) {
|
||||
testPlan(35);
|
||||
test_builder();
|
||||
test_ntscalar();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,107 +1,247 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/*
|
||||
* nttableTest.cpp
|
||||
*
|
||||
* Created on: 2011.11
|
||||
* Author: Marty Kraimer
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <list>
|
||||
|
||||
#include <epicsAssert.h>
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
static PVNTFieldPtr pvntField = PVNTField::get();
|
||||
static String builder;
|
||||
|
||||
static void test(FILE * fd)
|
||||
void test_builder()
|
||||
{
|
||||
size_t n = 2;
|
||||
FieldConstPtrArray fields(n);
|
||||
StringArray names(n);
|
||||
names[0] = "position";
|
||||
names[1] = "alarms";
|
||||
fields[0] = fieldCreate->createScalarArray(pvDouble);
|
||||
fields[1] = ntField->createAlarmArray();
|
||||
NTTablePtr ntTable = NTTable::create(
|
||||
true,true,true,names,fields);
|
||||
PVStructurePtr pvStructure = ntTable->getPVStructure();
|
||||
builder.clear();
|
||||
pvStructure->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
builder.clear();
|
||||
pvStructure->getStructure()->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
PVDoubleArrayPtr pvPositions
|
||||
= static_pointer_cast<PVDoubleArray>(ntTable->getPVField(0));
|
||||
DoubleArray positions(2);
|
||||
positions[0] = 1.0;
|
||||
positions[1] = 2.0;
|
||||
pvPositions->put(0,2,positions,0);
|
||||
PVStructureArrayPtr pvAlarms
|
||||
= static_pointer_cast<PVStructureArray>(ntTable->getPVField(1));
|
||||
testDiag("test_builder");
|
||||
|
||||
NTTableBuilderPtr builder = NTTable::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
addColumn("column0", pvDouble)->
|
||||
addColumn("column1", pvString)->
|
||||
addColumn("column2", pvInt)->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTTable::is_a(structure));
|
||||
testOk1(structure->getID() == NTTable::URI);
|
||||
testOk1(structure->getNumberFields() == 7);
|
||||
testOk1(structure->getField("labels").get() != 0);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
testOk1(structure->getField("extra1").get() != 0);
|
||||
testOk1(structure->getField("extra2").get() != 0);
|
||||
|
||||
StructureConstPtr s = dynamic_pointer_cast<const Structure>(structure->getField("value"));
|
||||
#define TEST_COLUMN(name, type) \
|
||||
testOk(s.get() != 0 && \
|
||||
s->getField(name).get() != 0 && \
|
||||
dynamic_pointer_cast<const ScalarArray>(s->getField(name)).get() != 0 && \
|
||||
dynamic_pointer_cast<const ScalarArray>(s->getField(name))->getElementType() == type, \
|
||||
name " check");
|
||||
TEST_COLUMN("column0", pvDouble);
|
||||
TEST_COLUMN("column1", pvString);
|
||||
TEST_COLUMN("column2", pvInt);
|
||||
#undef TEST_COLUMN
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
|
||||
// duplicate test
|
||||
try
|
||||
{
|
||||
structure = builder->
|
||||
addColumn("column0", pvDouble)->
|
||||
addColumn("column0", pvString)->
|
||||
createStructure();
|
||||
testFail("duplicate column name");
|
||||
} catch (std::runtime_error &) {
|
||||
testPass("duplicate column name");
|
||||
}
|
||||
}
|
||||
|
||||
void test_labels()
|
||||
{
|
||||
testDiag("test_labels");
|
||||
|
||||
NTTableBuilderPtr builder = NTTable::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
addColumn("column0", pvDouble)->
|
||||
addColumn("column1", pvString)->
|
||||
addColumn("column2", pvInt)->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
testOk1(NTTable::isCompatible(pvStructure)==true);
|
||||
std::cout << *pvStructure << std::endl;
|
||||
|
||||
PVStringArrayPtr labels = pvStructure->getSubField<PVStringArray>("labels");
|
||||
testOk1(labels.get() != 0);
|
||||
testOk1(labels->getLength() == 3);
|
||||
|
||||
PVStringArray::const_svector l(labels->view());
|
||||
testOk1(l[0] == "column0");
|
||||
testOk1(l[1] == "column1");
|
||||
testOk1(l[2] == "column2");
|
||||
}
|
||||
|
||||
void test_nttable()
|
||||
{
|
||||
testDiag("test_nttable");
|
||||
|
||||
NTTableBuilderPtr builder = NTTable::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTTablePtr ntTable = builder->
|
||||
addColumn("column0", pvDouble)->
|
||||
addColumn("column1", pvString)->
|
||||
addColumn("column2", pvInt)->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
create();
|
||||
testOk1(ntTable.get() != 0);
|
||||
|
||||
testOk1(ntTable->getPVStructure().get() != 0);
|
||||
testOk1(ntTable->getDescriptor().get() != 0);
|
||||
testOk1(ntTable->getAlarm().get() != 0);
|
||||
testOk1(ntTable->getTimeStamp().get() != 0);
|
||||
testOk1(ntTable->getLabels().get() != 0);
|
||||
|
||||
testOk1(ntTable->getColumn<PVDoubleArray>("column0").get() != 0);
|
||||
testOk1(ntTable->getColumn<PVStringArray>("column1").get() != 0);
|
||||
testOk1(ntTable->getColumn<PVIntArray>("column2").get() != 0);
|
||||
|
||||
testOk1(ntTable->getColumn("invalid").get() == 0);
|
||||
|
||||
//
|
||||
// example how to set column values
|
||||
//
|
||||
PVIntArray::svector newValues;
|
||||
newValues.push_back(1);
|
||||
newValues.push_back(2);
|
||||
newValues.push_back(8);
|
||||
|
||||
PVIntArrayPtr intColumn = ntTable->getColumn<PVIntArray>("column2");
|
||||
intColumn->replace(freeze(newValues));
|
||||
|
||||
//
|
||||
// example how to get column values
|
||||
//
|
||||
PVIntArray::const_svector values(intColumn->view());
|
||||
|
||||
testOk1(values.size() == 3);
|
||||
testOk1(values[0] == 1);
|
||||
testOk1(values[1] == 2);
|
||||
testOk1(values[2] == 8);
|
||||
|
||||
//
|
||||
// timeStamp ops
|
||||
//
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (ntTable->attachTimeStamp(pvTimeStamp))
|
||||
{
|
||||
testPass("timeStamp attach");
|
||||
|
||||
// example how to set current time
|
||||
TimeStamp ts;
|
||||
ts.getCurrent();
|
||||
pvTimeStamp.set(ts);
|
||||
|
||||
// example how to get EPICS time
|
||||
TimeStamp ts2;
|
||||
pvTimeStamp.get(ts2);
|
||||
testOk1(ts2.getEpicsSecondsPastEpoch() != 0);
|
||||
}
|
||||
else
|
||||
testFail("timeStamp attach fail");
|
||||
|
||||
//
|
||||
// alarm ops
|
||||
//
|
||||
PVAlarm pvAlarm;
|
||||
Alarm alarm;
|
||||
PVStructurePtrArray palarms(n);
|
||||
for(size_t i=0; i<n; i++) {
|
||||
palarms[i] = pvntField->createAlarm();
|
||||
pvAlarm.attach(palarms[i]);
|
||||
alarm.setMessage("test");
|
||||
alarm.setSeverity(majorAlarm);
|
||||
alarm.setStatus(clientStatus);
|
||||
if (ntTable->attachAlarm(pvAlarm))
|
||||
{
|
||||
testPass("alarm attach");
|
||||
|
||||
// example how to set an alarm
|
||||
Alarm alarm;
|
||||
alarm.setStatus(deviceStatus);
|
||||
alarm.setSeverity(minorAlarm);
|
||||
alarm.setMessage("simulation alarm");
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
pvAlarms->put(0,n,palarms,0);
|
||||
StringArray labels(n);
|
||||
labels[0] = pvPositions->getFieldName();
|
||||
labels[1] = pvAlarms->getFieldName();
|
||||
PVStringArrayPtr label = ntTable->getLabel();
|
||||
label->put(0,n,labels,0);
|
||||
PVStringPtr function = ntTable->getFunction();
|
||||
function->put("test");
|
||||
ntTable->attachAlarm(pvAlarm);
|
||||
alarm.setMessage("test alarm");
|
||||
alarm.setSeverity(majorAlarm);
|
||||
alarm.setStatus(clientStatus);
|
||||
pvAlarm.set(alarm);
|
||||
PVTimeStamp pvTimeStamp;
|
||||
ntTable->attachTimeStamp(pvTimeStamp);
|
||||
TimeStamp timeStamp(1000,1000,10);
|
||||
pvTimeStamp.set(timeStamp);
|
||||
builder.clear();
|
||||
pvStructure->toString(&builder);
|
||||
fprintf(fd,"%s\n",builder.c_str());
|
||||
assert(NTTable::isNTTable(pvStructure));
|
||||
else
|
||||
testFail("alarm attach fail");
|
||||
|
||||
//
|
||||
// set descriptor
|
||||
//
|
||||
ntTable->getDescriptor()->put("This is a test NTTable");
|
||||
|
||||
// dump NTTable
|
||||
std::cout << *ntTable->getPVStructure() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
void test_wrap()
|
||||
{
|
||||
char *fileName = 0;
|
||||
if(argc>1) fileName = argv[1];
|
||||
FILE * fd = stdout;
|
||||
if(fileName!=0 && fileName[0]!=0) {
|
||||
fd = fopen(fileName,"w+");
|
||||
}
|
||||
test(fd);
|
||||
return(0);
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTTablePtr nullPtr = NTTable::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTTable::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTTableBuilderPtr builder = NTTable::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
addColumn("column0", pvDouble)->
|
||||
addColumn("column1", pvString)->
|
||||
addColumn("column2", pvInt)->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
NTTablePtr ptr = NTTable::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTTable::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testNTTable) {
|
||||
testPlan(48);
|
||||
test_builder();
|
||||
test_labels();
|
||||
test_nttable();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
|
||||
167
test/nt/ntunionTest.cpp
Normal file
167
test/nt/ntunionTest.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/nt.h>
|
||||
|
||||
|
||||
using namespace epics::nt;
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static StandardFieldPtr standardField = getStandardField();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
void test_builder()
|
||||
{
|
||||
testDiag("test_builder");
|
||||
|
||||
NTUnionBuilderPtr builder = NTUnion::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
StructureConstPtr structure = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
add("valueAlarm",standardField->doubleAlarm()) ->
|
||||
add("extra",fieldCreate->createScalarArray(pvString)) ->
|
||||
createStructure();
|
||||
testOk1(structure.get() != 0);
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
testOk1(NTUnion::is_a(structure));
|
||||
testOk1(structure->getID() == NTUnion::URI);
|
||||
testOk1(structure->getNumberFields() == 6);
|
||||
testOk1(structure->getField("value").get() != 0);
|
||||
testOk1(structure->getField("descriptor").get() != 0);
|
||||
testOk1(structure->getField("alarm").get() != 0);
|
||||
testOk1(structure->getField("timeStamp").get() != 0);
|
||||
|
||||
UnionConstPtr valueField = structure->getField<Union>("value");
|
||||
testOk(valueField.get() != 0, "value is enum");
|
||||
|
||||
std::cout << *structure << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void test_ntunion()
|
||||
{
|
||||
testDiag("test_ntunion");
|
||||
|
||||
NTUnionBuilderPtr builder = NTUnion::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTUnionPtr ntUnion = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
create();
|
||||
testOk1(ntUnion.get() != 0);
|
||||
|
||||
testOk1(ntUnion->getPVStructure().get() != 0);
|
||||
testOk1(ntUnion->getValue().get() != 0);
|
||||
testOk1(ntUnion->getDescriptor().get() != 0);
|
||||
testOk1(ntUnion->getAlarm().get() != 0);
|
||||
testOk1(ntUnion->getTimeStamp().get() != 0);
|
||||
|
||||
// TODO
|
||||
// 1. Variant union example.
|
||||
// 2. set the union value.
|
||||
|
||||
//
|
||||
// timeStamp ops
|
||||
//
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (ntUnion->attachTimeStamp(pvTimeStamp))
|
||||
{
|
||||
testPass("timeStamp attach");
|
||||
|
||||
// example how to set current time
|
||||
TimeStamp ts;
|
||||
ts.getCurrent();
|
||||
pvTimeStamp.set(ts);
|
||||
|
||||
// example how to get EPICS time
|
||||
TimeStamp ts2;
|
||||
pvTimeStamp.get(ts2);
|
||||
testOk1(ts2.getEpicsSecondsPastEpoch() != 0);
|
||||
}
|
||||
else
|
||||
testFail("timeStamp attach fail");
|
||||
|
||||
//
|
||||
// alarm ops
|
||||
//
|
||||
PVAlarm pvAlarm;
|
||||
if (ntUnion->attachAlarm(pvAlarm))
|
||||
{
|
||||
testPass("alarm attach");
|
||||
|
||||
// example how to set an alarm
|
||||
Alarm alarm;
|
||||
alarm.setStatus(deviceStatus);
|
||||
alarm.setSeverity(minorAlarm);
|
||||
alarm.setMessage("simulation alarm");
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
else
|
||||
testFail("alarm attach fail");
|
||||
|
||||
//
|
||||
// set descriptor
|
||||
//
|
||||
ntUnion->getDescriptor()->put("This is a test NTUnion");
|
||||
|
||||
// dump ntUnion
|
||||
std::cout << *ntUnion->getPVStructure() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTUnionPtr nullPtr = NTUnion::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTUnion::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTUnionBuilderPtr builder = NTUnion::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
testOk1(NTUnion::isCompatible(pvStructure)==true);
|
||||
NTUnionPtr ptr = NTUnion::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
ptr = NTUnion::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testNTUnion) {
|
||||
testPlan(27);
|
||||
test_builder();
|
||||
test_ntunion();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
38
test/nt/ntutilsTest.cpp
Normal file
38
test/nt/ntutilsTest.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* This software is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
|
||||
using namespace epics::nt;
|
||||
|
||||
void test_is_a()
|
||||
{
|
||||
testDiag("test_is_a");
|
||||
|
||||
testOk1(NTUtils::is_a("epics:nt/NTTable:1.0", "epics:nt/NTTable:1.0"));
|
||||
testOk1(NTUtils::is_a("epics:nt/NTTable:2.0", "epics:nt/NTTable:2.0"));
|
||||
testOk1(NTUtils::is_a("epics:nt/NTTable:1.0", "epics:nt/NTTable:1.1"));
|
||||
testOk1(NTUtils::is_a("epics:nt/NTTable:1.1", "epics:nt/NTTable:1.0"));
|
||||
|
||||
testOk1(!NTUtils::is_a("epics:nt/NTTable:1.0", "epics:nt/NTTable:2.0"));
|
||||
testOk1(!NTUtils::is_a("epics:nt/NTTable:2.0", "epics:nt/NTTable:1.0"));
|
||||
testOk1(!NTUtils::is_a("epics:nt/NTTable:1.3", "epics:nt/NTTable:2.3"));
|
||||
testOk1(!NTUtils::is_a("epics:nt/NTTable:1.0", "epics:nt/NTTable:11.0"));
|
||||
testOk1(!NTUtils::is_a("epics:nt/NTTable:11.0", "epics:nt/NTTable:1.0"));
|
||||
testOk1(!NTUtils::is_a("epics:nt/NTTable:1.0", "epics:nt/NTMatrix:1.0"));
|
||||
}
|
||||
|
||||
MAIN(testNTUtils) {
|
||||
testPlan(10);
|
||||
test_is_a();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user