Compare commits
102 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95065787e6 | ||
|
|
fda9144505 | ||
|
|
ad4525317d | ||
|
|
acd19c10d0 | ||
|
|
0c2c6a4173 | ||
|
|
94781061cf | ||
|
|
fff9884b4c | ||
|
|
8c92f5035b | ||
|
|
cdb79f8a22 | ||
|
|
7fc3f50ae9 | ||
|
|
05d41f81e4 | ||
|
|
d400e8eaf5 | ||
|
|
fdc289d888 | ||
|
|
0a2243e033 | ||
|
|
9d877d764f | ||
|
|
f5df29cf34 | ||
|
|
8008823ea5 | ||
|
|
6515de4bc0 | ||
|
|
8c5f535b79 | ||
|
|
de2fac122c | ||
|
|
7707da0b45 | ||
|
|
036186fc12 | ||
|
|
d3853bd4e9 | ||
|
|
7253bac48a | ||
|
|
973fbeeba5 | ||
|
|
f22cefba97 | ||
|
|
a5abc37b17 | ||
|
|
b95fa7be56 | ||
|
|
f6cf87a52d | ||
|
|
51f36b2281 | ||
|
|
ddebd494c6 | ||
|
|
d0a8d2b1cd | ||
|
|
1731a0daf6 | ||
|
|
3487b3ee9e | ||
|
|
5834efb709 | ||
|
|
52bc6d060d | ||
|
|
35ca5f3aed | ||
|
|
ac2b6ea8db | ||
|
|
9827caa3e3 | ||
|
|
ebe2d6196c | ||
|
|
e4689dd3f8 | ||
|
|
1dba611b8e | ||
|
|
97cbea6f4d | ||
|
|
d9963b0631 | ||
|
|
8418303ce2 | ||
|
|
40952df965 | ||
|
|
4f2c51c480 | ||
|
|
fd31a0d6b0 | ||
|
|
9ad725a272 | ||
|
|
2b6172ba63 | ||
|
|
c521f9299d | ||
|
|
1e646f8df1 | ||
|
|
b5a436c1b7 | ||
|
|
4f25c7a3ea | ||
|
|
eadb8ff65b | ||
|
|
6a80e941a0 | ||
|
|
7fc9b42b3a | ||
|
|
0d857999bf | ||
|
|
8ba71b048e | ||
|
|
e07f6c1703 | ||
|
|
e4f38121d2 | ||
|
|
255ee3f151 | ||
|
|
e72dbaabe1 | ||
|
|
b39662450f | ||
|
|
98da0c0bec | ||
|
|
45dde325fd | ||
|
|
2967a8f798 | ||
|
|
d4bdc73948 | ||
|
|
37c2f6bb17 | ||
|
|
a8e4d749e3 | ||
|
|
3df16ee449 | ||
|
|
332c2f959b | ||
|
|
a1b89c9a3b | ||
|
|
d6921fdac0 | ||
|
|
4cb3c22221 | ||
|
|
cc1536b6e1 | ||
|
|
92a178cbf9 | ||
|
|
fbebce0a49 | ||
|
|
b13bb9819a | ||
|
|
bb505b8ed9 | ||
|
|
cf030bc711 | ||
|
|
6cb95c5cfc | ||
|
|
a277a4fdd5 | ||
|
|
388799d39d | ||
|
|
4acf7edf95 | ||
|
|
e39346d51e | ||
|
|
5ae6de4f1d | ||
|
|
e0f1427af7 | ||
|
|
69297bdb58 | ||
|
|
0fa2f2c2ff | ||
|
|
9efce46fff | ||
|
|
c356ecb402 | ||
|
|
4c6887e7ec | ||
|
|
6d338cab15 | ||
|
|
354fdd412f | ||
|
|
f3f6141e6a | ||
|
|
f2b43b704c | ||
|
|
de1478d7ba | ||
|
|
b9592eeb8c | ||
|
|
6a62f9c082 | ||
|
|
2e4a8b2e23 | ||
|
|
c5112ffa11 |
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
bin/
|
||||
lib/
|
||||
doc/
|
||||
include/
|
||||
db/
|
||||
dbd/
|
||||
documentation/html
|
||||
documentation/*.tag
|
||||
envPaths
|
||||
configure/*.local
|
||||
configure/RELEASE.*
|
||||
configure/CONFIG_SITE.*
|
||||
!configure/ExampleRELEASE.local
|
||||
**/O.*
|
||||
QtC-*
|
||||
8
.hgflow
8
.hgflow
@@ -1,8 +0,0 @@
|
||||
[branchname]
|
||||
master = master
|
||||
develop = default
|
||||
feature = feature/
|
||||
release = release/
|
||||
hotfix = hotfix/
|
||||
support = support/
|
||||
|
||||
12
.hgignore
12
.hgignore
@@ -1,12 +0,0 @@
|
||||
QtC-
|
||||
bin/
|
||||
lib/
|
||||
doc/
|
||||
include/
|
||||
db/
|
||||
dbd/
|
||||
documentation/html
|
||||
documentation/*.tag
|
||||
envPaths
|
||||
configure/.*\.local
|
||||
/O\..*
|
||||
18
.hgtags
18
.hgtags
@@ -1,18 +0,0 @@
|
||||
459f10877e5628241704f31437b4cbd342df0798 test1
|
||||
6e8a22d01e824702088195c08bf50bfb6f293de5 1.0-BETA
|
||||
d29d84f4c3f389f2accd497185b106c8541f95c9 1.1-SNAPSHOT
|
||||
a29729ca0ecd60b66f2d997031d97911377e44a7 marchtest
|
||||
9c59737f56e71aef641b70d0f72aa768fd7f8414 1.0.1-BETA
|
||||
4559c3de0cb4e3420e26272817f58bab005063ec 1.1-BETA
|
||||
d70c5ad29163306f50979a95b5aebbe9a93cfe76 2.0-BETA
|
||||
4cecd4b200f88ab57bbb81978c45df2a67bbece1 3.0-pre1
|
||||
4cecd4b200f88ab57bbb81978c45df2a67bbece1 3.0.0
|
||||
2a289ff41e2ed3a0247877306c2db7b266f3b6b8 3.0.1
|
||||
58092712d092ee521d1e1c8fa596a67f7d113ee9 3.0.2
|
||||
40b681ffc5cd609320e3f8ffc8eb6aa3bfdfbf19 before_merge_changesAfter3_0_2
|
||||
260f35b9c6cad113f242c83c89be9cdac802f610 3.1.0
|
||||
1348c22b125861ecb9da95b23f20314b167ee155 4.0.0
|
||||
1348c22b125861ecb9da95b23f20314b167ee155 4.0.0
|
||||
9c62aaa83b9db6ad69740a6bb46d6529e0e60b78 4.0.0
|
||||
9c62aaa83b9db6ad69740a6bb46d6529e0e60b78 4.0.0
|
||||
f9f187685032ebf4b108c759be196fda055c9e42 4.0.0
|
||||
35
COPYRIGHT
35
COPYRIGHT
@@ -1,12 +1,31 @@
|
||||
/****************************************************
|
||||
Copyright (c) 2008 All rights reserved
|
||||
Copyright (c) 2008 Martin R. Kraimer
|
||||
Copyright (c) 2006 The University of Chicago, as Operator of Argonne
|
||||
National Laboratory.
|
||||
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)
|
||||
(Cosylab) Ljubljana Slovenia
|
||||
*************************************************** */
|
||||
COSYLAB (Control System Laboratory), Ljubljana, Slovenia.
|
||||
Brookhaven Science Associates, as Operator of Brookhaven
|
||||
National Laboratory.
|
||||
Diamond Light Source Ltd., Didcot, United Kingdom.
|
||||
|
||||
|
||||
|
||||
42
LICENSE
42
LICENSE
@@ -1,12 +1,15 @@
|
||||
|
||||
Copyright (c) 2008 Martin R. Kraimer
|
||||
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 Control System Laboratory,
|
||||
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
|
||||
@@ -75,4 +78,37 @@ 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.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
|
||||
82
README.html
82
README.html
@@ -1,82 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||
<title>EPICS pvData C++</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1 style="text-align: center">EPICS pvData C++<br />
|
||||
Overview<br />
|
||||
2010.08.10</h1>
|
||||
CONTENTS
|
||||
<hr />
|
||||
|
||||
<h2 style="text-align: center">Introduction</h2>
|
||||
<hr />
|
||||
|
||||
<p>This project has the begining of the C++ implementation of pvData. The
|
||||
following is done:</p>
|
||||
<dl>
|
||||
<dt>introspection interfaces</dt>
|
||||
<dd>The introspection interfaces for clients are described.</dd>
|
||||
<dt>introspection implementation</dt>
|
||||
<dd>The following have been implemented: Type, ScalarType, Field,
|
||||
Scalar</dd>
|
||||
<dt>test</dt>
|
||||
<dd>A test of Scalar.</dd>
|
||||
<dt>As mentioned below there are problems with the current
|
||||
implementation.</dt>
|
||||
</dl>
|
||||
<hr />
|
||||
|
||||
<h2 style="text-align: center">Building</h2>
|
||||
<hr />
|
||||
|
||||
<p>The project is structured as an epics base client application. Edit
|
||||
configure/RELEASE so that it references your EPICS base and then just
|
||||
type:</p>
|
||||
<pre> make</pre>
|
||||
|
||||
<p>At the top. Then execute the test in the bin directory.</p>
|
||||
|
||||
<p>pvDataApp has the following sub directories:</p>
|
||||
<dl>
|
||||
<dt>pv</dt>
|
||||
<dd>pvData.h has the interface descriptions for client code.</dd>
|
||||
<dt>factory</dt>
|
||||
<dd>FieldCreateFactory.cpp has the current implementation</dd>
|
||||
<dt>test</dt>
|
||||
<dd>Has a test for the current implementation.</dd>
|
||||
</dl>
|
||||
<hr />
|
||||
|
||||
<h2 style="text-align: center">Questions about Classes</h2>
|
||||
<hr />
|
||||
|
||||
<p>The pure virtual classes defined in pvData.h now work. But there are still
|
||||
some things that are not so nice. Amoung these are:</p>
|
||||
<ul>
|
||||
<li>In FieldCreateFactory.cpp look for "WHY DO I". It asks why the derived
|
||||
class must also define methods defined in the base class. If it does not
|
||||
then a compilation error occurs. WHY??? </li>
|
||||
<li>The toString methods have an argument of "std::string &buf" instead
|
||||
of "std::string *". Does this seem correct?</li>
|
||||
<li>Can arguments and return descriptions be defined better?</li>
|
||||
<li>Is const present everywhere it should be? Remember that introspection
|
||||
classes are immutable.</li>
|
||||
<li>The code is NOT thread safe. When we decide for sure what thread/lock
|
||||
support to choose I will fix this.</li>
|
||||
</ul>
|
||||
|
||||
<p>HELP WILL BE GREATLY APPRECIATED. because I am still coming up to speed
|
||||
with c++</p>
|
||||
<hr />
|
||||
|
||||
<h2 style="text-align: center">Garbage Collection</h2>
|
||||
<hr />
|
||||
<p>Not yet implemented. Lets get class structure correct first.</p>
|
||||
</body>
|
||||
</html>
|
||||
58
README.md
Normal file
58
README.md
Normal file
@@ -0,0 +1,58 @@
|
||||
pvaDataCPP
|
||||
==========
|
||||
|
||||
pvDataCPP is a set of data types and utilities that form part of the EPICS V4
|
||||
project.
|
||||
|
||||
|
||||
Further Info
|
||||
------------
|
||||
|
||||
Consult the documents in the documentation directory, in particular
|
||||
|
||||
* pvDataCPP.html
|
||||
* RELEASE_NOTES.md
|
||||
|
||||
Also see the [EPICS Version 4 website](http://epics-pvdata.sourceforge.net)
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
The pvDataCPP requires recent versions of the following software:
|
||||
|
||||
1. EPICS Base (v3.14.12.3 or later)
|
||||
2. EPICS4 pvCommonCPP (4.1.0 or later)
|
||||
|
||||
(pvCommonCPP may not be needed depending on host/compiler.)
|
||||
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
Building uses the make utility and the EPICS base build system.
|
||||
|
||||
The build system needs the location of the prerequisites, e.g. by placing the
|
||||
lines of the form
|
||||
|
||||
PVCOMMON = /home/install/epicsV4/pvCommonCPP
|
||||
EPICS_BASE = /home/install/epics/base
|
||||
|
||||
pointing to the locations in a file called RELEASE.local
|
||||
in the configure directory or the parent directory of pvDataCPP.
|
||||
|
||||
With this in place, to build type make
|
||||
|
||||
make
|
||||
|
||||
To perform a clean build type
|
||||
|
||||
make clean uninstall
|
||||
|
||||
To run the unit tests type
|
||||
|
||||
make runtests
|
||||
|
||||
For more information on the EPICS build system consult the
|
||||
[Application Development guide](http://www.aps.anl.gov/epics/base/R3-14/12-docs/AppDevGuide.pdf).
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ CHECK_RELEASE = YES
|
||||
# INSTALL_LOCATION here.
|
||||
#INSTALL_LOCATION=</path/name/to/install/top>
|
||||
|
||||
-include $(TOP)/../CONFIG_SITE.local
|
||||
-include $(TOP)/configure/CONFIG_SITE.local
|
||||
-include $(TOP)/../CONFIG.local
|
||||
|
||||
ifdef WITH_COVERAGE
|
||||
USR_CPPFLAGS += --coverage
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
# PVCOMMON = /home/install/epicsV4/pvCommonCPP
|
||||
# EPICS_BASE = /home/install/epics/base
|
||||
|
||||
-include $(TOP)/configure/RELEASE.local
|
||||
-include $(TOP)/../RELEASE.local
|
||||
-include $(TOP)/configure/RELEASE.local
|
||||
|
||||
@@ -1,5 +1,179 @@
|
||||
<h1>Release 4.0 IN DEVELOPMENT</h1>
|
||||
<h1>Release 5.0.4</h1>
|
||||
|
||||
<p>The changes since release 5.0.3 are:</p>
|
||||
|
||||
<ul>
|
||||
<li>Fixed bitset serialization (issue #24)</li>
|
||||
<li>Fixed truncation in BitSet::or_and (issue #27)</li>
|
||||
</ul>
|
||||
|
||||
<h2>Fixed bitset serialization (issue #24)</h2>
|
||||
|
||||
<p>C++ bitset serialization was not consistent with the C++ deserialization and
|
||||
Java code in some instances (depending on the endianness of the serializer and deserializer) when the number of bits was 56-63 modulo 64. C++ serialization
|
||||
has been fixed.</p>
|
||||
|
||||
<p>Fix exposed issue in deserialization on 32-bit platforms which
|
||||
has also been corrected. </p>
|
||||
|
||||
<h2>Fixed truncation in BitSet::or_and (issue #27)</h2>
|
||||
|
||||
<p>If n, n1 and n2 words are used to store the values of the bitsets bitset,
|
||||
bitset1 and bitset2 respectively then max(n, min(n1,n2)) words are needed
|
||||
to store bitset.or_(bitset1, bitset2).</p>
|
||||
|
||||
<p>Previously min(n1,n2) words were used and the result would be truncated in
|
||||
some instances. This has been fixed.</p>
|
||||
|
||||
<h1>Release 5.0.3</h1>
|
||||
|
||||
<p>The only change since release 5.0.2 is:</p>
|
||||
|
||||
<h2>Fixed buffer overflow in PVUnion::serialize() (issue #20)</h2>
|
||||
|
||||
<p>A PVUnion whose stored value was null was serialized without checking
|
||||
whether the buffer had sufficient capacity. This has been fixed by calling
|
||||
ensureBuffer().</p>
|
||||
|
||||
<h1>Release 5.0.2</h1>
|
||||
|
||||
<p>The main changes since release 4.0.3 are:</p>
|
||||
|
||||
<ul>
|
||||
<li>Deprecated getXXXField() methods have been removed from PVStructure</li>
|
||||
<li>Convert copy methods and equals operators (re)moved</li>
|
||||
<li>Convert::copyUnion now always copies between subfields.</li>
|
||||
<li>New method getSubFieldT, like getSubField except it throws an exception</li>
|
||||
<li>findSubField method removed from PVStructure</li>
|
||||
<li>New stream operators for Field and PVField are provided</li>
|
||||
<li>New template versions of Structure::getField</li>
|
||||
<li>Fixes for static initialisation order issues</li>
|
||||
<li>CreateRequest prevents a possible SEGFAULT</li>
|
||||
</ul>
|
||||
|
||||
<h2>Deprecated getXXXField methods have been removed from PVStructure</h2>
|
||||
|
||||
<p>The following methods have been removed from PVStructure</p>
|
||||
|
||||
<ul>
|
||||
<li>getBooleanField</li>
|
||||
<li>getByteField, getShortField, getIntField, getLongField</li>
|
||||
<li>getUByteField, getUShortField, getUIntField, getULongField</li>
|
||||
<li>getStringField</li>
|
||||
<li>getStructureField, getUnionField</li>
|
||||
<li>getScalarArrayField, getStructureArrayField, getUnionArrayField</li>
|
||||
</ul>
|
||||
|
||||
<p>Use template getSubField instead, e.g. use</p>
|
||||
|
||||
<pre><code>getSubField< PVInt >(fieldName)
|
||||
</code></pre>
|
||||
|
||||
<p>in place of</p>
|
||||
|
||||
<pre><code>getIntField(fieldName)
|
||||
</code></pre>
|
||||
|
||||
<h2>Convert copy methods and equals operators</h2>
|
||||
|
||||
<p>Convert copy methods where moved and replaced with methods
|
||||
on PVField classes, i.e.</p>
|
||||
|
||||
<pre><code>PVField::copy(const PVField& from)
|
||||
</code></pre>
|
||||
|
||||
<p>Methods</p>
|
||||
|
||||
<pre><code>PVField::copyUnchecked(const PVField& from)
|
||||
</code></pre>
|
||||
|
||||
<p>were added to allow unchecked copies, to gain performance
|
||||
where checked are not needed (anymore).</p>
|
||||
|
||||
<p>In addition:
|
||||
- isCompatibleXXX methods were removed in favour of Field::operator==.
|
||||
- equals methods were remove in favour of PVField::operator==.
|
||||
- operator== methods where moved to pvIntrospect.h and pvData.h</p>
|
||||
|
||||
<h2>Convert::copyUnion</h2>
|
||||
|
||||
<p>Before this method, depending on types for to and from,
|
||||
sometimes did a shallow copy, i.e. just made to shared_ptr for to
|
||||
share the same data as from.
|
||||
Now it always copies between the subfield of to and from.</p>
|
||||
|
||||
<h2>New method getSubFieldT, like getSubField except it throws an exception</h2>
|
||||
|
||||
<p>PVStructure has a new template member</p>
|
||||
|
||||
<pre><code>getSubFieldT(std::string const &fieldName)
|
||||
</code></pre>
|
||||
|
||||
<p>that is like <b>getSubField</b> except that it throws a runtime_error
|
||||
instead of returning null.</p>
|
||||
|
||||
<h2>findSubField method removed from PVStructure</h2>
|
||||
|
||||
<p>This was mainly used in the implementation of getSubField. With a change to
|
||||
the latter, findSubField was removed.</p>
|
||||
|
||||
<h2>New stream operators</h2>
|
||||
|
||||
<p>New steam operators are available for Field and PVField.
|
||||
Before to print a Field (or any extension) or a PVField (or any extension)
|
||||
it was necessary to have code like:</p>
|
||||
|
||||
<pre><code> void print(StructureConstPtr struc, PVStructurePtr pv)
|
||||
{
|
||||
if(struc) {
|
||||
cout << *struc << endl;
|
||||
} else {
|
||||
cout << "nullptr\n"
|
||||
}
|
||||
if(pv) {
|
||||
cout << *.struc << endl;
|
||||
} else {
|
||||
cout << "nullptr\n"
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<p>Now it can be done as follows:</p>
|
||||
|
||||
<pre><code> void print(StructureConstPtr struc, PVStructurePtr pv)
|
||||
{
|
||||
cout << struc << endl;
|
||||
cout << pv << endl;
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<h2>New template version of Structure::getField</h2>
|
||||
|
||||
<p>A new template getField method has been added to Structure</p>
|
||||
|
||||
<p>template<typename FT >
|
||||
std::tr1::shared_ptr< const FT > getField(std::string const &fieldName) const </p>
|
||||
|
||||
<p>Can be used, for example, as follows:</p>
|
||||
|
||||
<pre><code>StructurePtr tsStruc = struc->getField<Structure>("timeStamp");
|
||||
</code></pre>
|
||||
|
||||
<h2>Fixes for static initialisation order issues</h2>
|
||||
|
||||
<p>Certain static builds (in particular Windows builds) of applications using
|
||||
pvData had issues due to PVStructure::DEFAULT_ID being used before being initialised. This has been fixed.</p>
|
||||
|
||||
<h2>CreateRequest change</h2>
|
||||
|
||||
<p>createRequest could cause a SEGFAULT if passed a bad argument.
|
||||
This has been changed so the it returns a null pvStructure
|
||||
and provides an error.</p>
|
||||
|
||||
<h1>Release 4.0.3</h1>
|
||||
|
||||
<p>The main changes since release 3.0.2 are:</p>
|
||||
|
||||
<ul>
|
||||
<li>array semantics now enforce Copy On Write.</li>
|
||||
<li>String no longer defined.</li>
|
||||
@@ -9,21 +183,31 @@
|
||||
<li>copy is new.</li>
|
||||
<li>monitorPlugin is new.</li>
|
||||
</ul>
|
||||
|
||||
<h2>New Semantics for Arrays</h2>
|
||||
|
||||
<p>PVScalarArray, PVStructureArray, and PVUnionArray all enforce COW (Copy On Write) Semantics.
|
||||
In order to limit memory usage the storage for raw data is managed via a new shared_vector facility.
|
||||
In order to limit memory usage the storage for raw data is managed via a new shared<em>vector facility.
|
||||
This allows multiple instances of array data to use the shared raw data.
|
||||
COW is implemented via shared_vectors of const data, i. e. data that can not be modified.</p>
|
||||
COW is implemented via shared</em>vectors of const data, i. e. data that can not be modified.</p>
|
||||
|
||||
<h2>String no longer defined</h2>
|
||||
|
||||
<p>This is replaced by std::string.</p>
|
||||
|
||||
<h2>timeStamp and valueAlarm name changes</h2>
|
||||
|
||||
<p>In timeStamp nanoSeconds is changed to nanoseconds.</p>
|
||||
<p>In valueAlarm hystersis is changed to hysteresis</p>
|
||||
|
||||
<p>In valueAlarm hysteresis is changed to hysteresis</p>
|
||||
|
||||
<h2>toString replaced by stream I/O</h2>
|
||||
|
||||
<p>pvData.h and pvIntrospect no longer defines toString
|
||||
Instead they have stream support.
|
||||
pvIntrospect uses method dump and pvData uses dumpValue.
|
||||
For example:</p>
|
||||
|
||||
<pre><code> PVDoublePtr pvValue;
|
||||
String buffer;
|
||||
pvValue->toString(&buffer);
|
||||
@@ -32,27 +216,40 @@ For example:</p>
|
||||
pvValue->getField()->toString(&buffer);
|
||||
cout << buffer << evdl;
|
||||
</code></pre>
|
||||
|
||||
<p>is replaced by</p>
|
||||
|
||||
<pre><code> PVDoublePtr pvValue;
|
||||
cout << *pvValue << endl
|
||||
cout << *pvValue->getField() << endl;
|
||||
</code></pre>
|
||||
|
||||
<h2>union is a new basic type.</h2>
|
||||
|
||||
<p>There are two new basic types: union_t and unionArray.</p>
|
||||
|
||||
<p>A union is like a structure that has a single subfield.
|
||||
There are two flavors:</p>
|
||||
|
||||
<ul>
|
||||
<li><b>varient union</b> The field can have any type.</li>
|
||||
<li><b>variant union</b> The field can have any type.</li>
|
||||
<li><b>union</b> The field can any of specified set of types.</li>
|
||||
</ul>
|
||||
|
||||
<p>The field type can be dynamically changed.</p>
|
||||
<h2>copy</h2>
|
||||
|
||||
<h2>copy </h2>
|
||||
|
||||
<p>This consists of createRequest and pvCopy.
|
||||
createRequest was moved from pvAccess to here.
|
||||
pvCopy is moved from pvDatabaseCPP and now depends
|
||||
only on pvData, i. e. it no longer has any knowledge of PVRecord.</p>
|
||||
only on pvData, i.e. it no longer has any knowledge of PVRecord.</p>
|
||||
|
||||
<h2>monitorPlugin</h2>
|
||||
|
||||
<p>This is for is for use by code that implements pvAccess monitors.
|
||||
This is prototype and is subject to debate.</p>
|
||||
|
||||
<h1>Release 3.0.2</h1>
|
||||
|
||||
<p>This was the starting point for RELEASE_NOTES</p>
|
||||
|
||||
@@ -1,5 +1,191 @@
|
||||
Release 4.0 IN DEVELOPMENT
|
||||
===========
|
||||
Release 5.0.4
|
||||
=============
|
||||
|
||||
The changes since release 5.0.3 are:
|
||||
|
||||
* Fixed bitset serialization (issue #24)
|
||||
* Fixed truncation in BitSet::or_and (issue #27)
|
||||
|
||||
Fixed bitset serialization (issue #24)
|
||||
--------------------------------------
|
||||
|
||||
C++ bitset serialization was not consistent with the C++ deserialization and
|
||||
Java code in some instances (depending on the endianness of the serializer and
|
||||
deserializer) when the number of bits was 56-63 modulo 64. C++ serialization
|
||||
has been fixed.
|
||||
|
||||
Fix exposed issue in deserialization on 32-bit platforms which
|
||||
has also been corrected.
|
||||
|
||||
Fixed truncation in BitSet::or_and (issue #27)
|
||||
----------------------------------------------
|
||||
|
||||
If n, n1 and n2 words are used to store the values of the bitsets bitset,
|
||||
bitset1 and bitset2 respectively then max(n, min(n1,n2)) words are needed
|
||||
to store bitset.or_(bitset1, bitset2).
|
||||
|
||||
Previously min(n1,n2) words were used and the result would be truncated in
|
||||
some instances. This has been fixed.
|
||||
|
||||
|
||||
Release 5.0.3
|
||||
=============
|
||||
|
||||
The only change since release 5.0.2 is:
|
||||
|
||||
Fixed buffer overflow in PVUnion::serialize() (issue #20)
|
||||
---------------------------------------------------------
|
||||
|
||||
A PVUnion whose stored value was null was serialized without checking
|
||||
whether the buffer had sufficient capacity. This has been fixed by calling
|
||||
ensureBuffer().
|
||||
|
||||
|
||||
Release 5.0.2
|
||||
=============
|
||||
|
||||
The main changes since release 4.0.3 are:
|
||||
|
||||
* Deprecated getXXXField() methods have been removed from PVStructure
|
||||
* Convert copy methods and equals operators (re)moved
|
||||
* Convert::copyUnion now always copies between subfields.
|
||||
* New method getSubFieldT, like getSubField except it throws an exception
|
||||
* findSubField method removed from PVStructure
|
||||
* New stream operators for Field and PVField are provided
|
||||
* New template versions of Structure::getField
|
||||
* Fixes for static initialisation order issues
|
||||
* CreateRequest prevents a possible SEGFAULT
|
||||
|
||||
|
||||
Deprecated getXXXField methods have been removed from PVStructure
|
||||
-----------------------------------------------------------------
|
||||
|
||||
The following methods have been removed from PVStructure
|
||||
|
||||
* getBooleanField
|
||||
* getByteField, getShortField, getIntField, getLongField
|
||||
* getUByteField, getUShortField, getUIntField, getULongField
|
||||
* getStringField
|
||||
* getStructureField, getUnionField
|
||||
* getScalarArrayField, getStructureArrayField, getUnionArrayField
|
||||
|
||||
Use template getSubField instead, e.g. use
|
||||
|
||||
getSubField< PVInt >(fieldName)
|
||||
|
||||
in place of
|
||||
|
||||
getIntField(fieldName)
|
||||
|
||||
|
||||
Convert copy methods and equals operators
|
||||
-----------------------------------------
|
||||
|
||||
Convert copy methods where moved and replaced with methods
|
||||
on PVField classes, i.e.
|
||||
|
||||
PVField::copy(const PVField& from)
|
||||
|
||||
Methods
|
||||
|
||||
PVField::copyUnchecked(const PVField& from)
|
||||
|
||||
were added to allow unchecked copies, to gain performance
|
||||
where checked are not needed (anymore).
|
||||
|
||||
In addition:
|
||||
- isCompatibleXXX methods were removed in favour of Field::operator==.
|
||||
- equals methods were remove in favour of PVField::operator==.
|
||||
- operator== methods where moved to pvIntrospect.h and pvData.h
|
||||
|
||||
|
||||
Convert::copyUnion
|
||||
-----------------
|
||||
|
||||
Before this method, depending on types for to and from,
|
||||
sometimes did a shallow copy, i.e. just made to shared_ptr for to
|
||||
share the same data as from.
|
||||
Now it always copies between the subfield of to and from.
|
||||
|
||||
|
||||
New method getSubFieldT, like getSubField except it throws an exception
|
||||
--------------------
|
||||
|
||||
PVStructure has a new template member
|
||||
|
||||
getSubFieldT(std::string const &fieldName)
|
||||
|
||||
that is like <b>getSubField</b> except that it throws a runtime_error
|
||||
instead of returning null.
|
||||
|
||||
|
||||
findSubField method removed from PVStructure
|
||||
--------------------------------------------
|
||||
|
||||
This was mainly used in the implementation of getSubField. With a change to
|
||||
the latter, findSubField was removed.
|
||||
|
||||
|
||||
New stream operators
|
||||
--------------------
|
||||
|
||||
New steam operators are available for Field and PVField.
|
||||
Before to print a Field (or any extension) or a PVField (or any extension)
|
||||
it was necessary to have code like:
|
||||
|
||||
void print(StructureConstPtr struc, PVStructurePtr pv)
|
||||
{
|
||||
if(struc) {
|
||||
cout << *struc << endl;
|
||||
} else {
|
||||
cout << "nullptr\n"
|
||||
}
|
||||
if(pv) {
|
||||
cout << *.struc << endl;
|
||||
} else {
|
||||
cout << "nullptr\n"
|
||||
}
|
||||
}
|
||||
|
||||
Now it can be done as follows:
|
||||
|
||||
void print(StructureConstPtr struc, PVStructurePtr pv)
|
||||
{
|
||||
cout << struc << endl;
|
||||
cout << pv << endl;
|
||||
}
|
||||
|
||||
|
||||
New template version of Structure::getField
|
||||
--------------------------------------------
|
||||
|
||||
A new template getField method has been added to Structure
|
||||
|
||||
template<typename FT >
|
||||
std::tr1::shared_ptr< const FT > getField(std::string const &fieldName) const
|
||||
|
||||
Can be used, for example, as follows:
|
||||
|
||||
StructurePtr tsStruc = struc->getField<Structure>("timeStamp");
|
||||
|
||||
|
||||
Fixes for static initialisation order issues
|
||||
--------------------------------------------
|
||||
|
||||
Certain static builds (in particular Windows builds) of applications using
|
||||
pvData had issues due to PVStructure::DEFAULT_ID being used before being initialised. This has been fixed.
|
||||
|
||||
|
||||
CreateRequest change
|
||||
--------------------
|
||||
|
||||
createRequest could cause a SEGFAULT if passed a bad argument.
|
||||
This has been changed so the it returns a null pvStructure
|
||||
and provides an error.
|
||||
|
||||
|
||||
Release 4.0.3
|
||||
=============
|
||||
|
||||
The main changes since release 3.0.2 are:
|
||||
|
||||
@@ -31,7 +217,7 @@ timeStamp and valueAlarm name changes
|
||||
|
||||
In timeStamp nanoSeconds is changed to nanoseconds.
|
||||
|
||||
In valueAlarm hystersis is changed to hysteresis
|
||||
In valueAlarm hysteresis is changed to hysteresis
|
||||
|
||||
|
||||
toString replaced by stream I/O
|
||||
@@ -65,7 +251,7 @@ There are two new basic types: union_t and unionArray.
|
||||
A union is like a structure that has a single subfield.
|
||||
There are two flavors:
|
||||
|
||||
* <b>varient union</b> The field can have any type.
|
||||
* <b>variant union</b> The field can have any type.
|
||||
* <b>union</b> The field can any of specified set of types.
|
||||
|
||||
The field type can be dynamically changed.
|
||||
@@ -76,7 +262,7 @@ copy
|
||||
This consists of createRequest and pvCopy.
|
||||
createRequest was moved from pvAccess to here.
|
||||
pvCopy is moved from pvDatabaseCPP and now depends
|
||||
only on pvData, i. e. it no longer has any knowledge of PVRecord.
|
||||
only on pvData, i.e. it no longer has any knowledge of PVRecord.
|
||||
|
||||
monitorPlugin
|
||||
-------------
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<h1>TODO</h1>
|
||||
<h2>printer</h2>
|
||||
<p>pv/printer.h is not used.</p>
|
||||
<h2>doxygen</h2>
|
||||
<p>There is a lot of public code that does not have doxygen tags.</p>
|
||||
<h2>postMonitor: PVUnion, PVUnionArray, and PVStructureArray</h2>
|
||||
<p>PVUnion, PVUnionArray, and PVStructureArray all have elements
|
||||
that are treated like a top level field.</p>
|
||||
<p>Currently if a subField of any of these is changed postMonitor is not called for the field itself.</p>
|
||||
<p>David asked if this could be changed so that it is called.
|
||||
Marty thinks this may not be a good idea.</p>
|
||||
<h2>valueAlarm</h2>
|
||||
<p>normativeTypes.html describes valueAlarm only for a value field that has type
|
||||
double.
|
||||
The implementation also supports all the numeric scalar types.</p>
|
||||
<h2>monitorPlugin</h2>
|
||||
<p>A debate is on-going about what semantics should be.</p>
|
||||
@@ -1,29 +1,11 @@
|
||||
TODO
|
||||
===========
|
||||
|
||||
printer
|
||||
------------
|
||||
|
||||
pv/printer.h is not used.
|
||||
|
||||
doxygen
|
||||
-------
|
||||
|
||||
There is a lot of public code that does not have doxygen tags.
|
||||
|
||||
|
||||
postMonitor: PVUnion, PVUnionArray, and PVStructureArray
|
||||
--------
|
||||
|
||||
PVUnion, PVUnionArray, and PVStructureArray all have elements
|
||||
that are treated like a top level field.
|
||||
|
||||
Currently if a subField of any of these is changed postMonitor is not called for the field itself.
|
||||
|
||||
David asked if this could be changed so that it is called.
|
||||
Marty thinks this may not be a good idea.
|
||||
|
||||
|
||||
valueAlarm
|
||||
---------
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<h1>EPICS pvDataCPP</h1>
|
||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
||||
|
||||
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 10-Nov-2014</h2>
|
||||
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 23-June-2015</h2>
|
||||
|
||||
<dl>
|
||||
<dt>Latest version:</dt>
|
||||
@@ -46,11 +46,11 @@
|
||||
</dd>
|
||||
<dt>This version:</dt>
|
||||
<dd><a
|
||||
href="pvDataCPP_20141110.html">pvDataCPP_20141110.html</a>
|
||||
href="pvDataCPP_20150623.html">pvDataCPP_20150623.html</a>
|
||||
</dd>
|
||||
<dt>Previous version:</dt>
|
||||
<dd><a
|
||||
href="pvDataCPP_20140723.html">pvDataCPP_20140723.html</a>
|
||||
href="pvDataCPP_20141110.html">pvDataCPP_20141110.html</a>
|
||||
</dd>
|
||||
<dt>Editors:</dt>
|
||||
<dd>Marty Kraimer, BNL</dd>
|
||||
@@ -79,7 +79,7 @@ V4 control system programming environment:<br />
|
||||
|
||||
<h2 class="nocount">Status of this Document</h2>
|
||||
|
||||
<p>This is the 10-Nov-2014 version of the C++ implementation of pvData.
|
||||
<p>This is the 23-June-2015 version of the C++ implementation of pvData.
|
||||
</p>
|
||||
|
||||
<p>RELEASE_NOTES.md provides changes since the last release.
|
||||
@@ -2309,6 +2309,16 @@ public:
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getSubField(std::size_t fieldOffset) const
|
||||
|
||||
PVFieldPtr getSubFieldT(std::string const &fieldName) const;
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getSubFieldT(std::string const &fieldName) const
|
||||
|
||||
PVFieldPtr getSubFieldT(std::size_t fieldOffset) const;
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getSubFieldT(std::size_t fieldOffset) const
|
||||
|
||||
virtual void serialize(
|
||||
ByteBuffer *pbuffer,SerializableControl *pflusher) const ;
|
||||
virtual void deserialize(
|
||||
@@ -2329,7 +2339,7 @@ public:
|
||||
<dt>getPVFields</dt>
|
||||
<dd>Returns the array of subfields. The set of subfields must all have
|
||||
different field names.</dd>
|
||||
<dt>getSubField(std::string fieldName)</dt>
|
||||
<dt>getSubField(std::string const &fieldName)</dt>
|
||||
<dd>
|
||||
Get a subField of a field.d
|
||||
A non-null result is
|
||||
@@ -2344,9 +2354,13 @@ public:
|
||||
<dd>Get the field located a fieldOffset, where fieldOffset is relative to
|
||||
the top level structure. This returns null if the specified field is not
|
||||
located within this PVStructure.
|
||||
<br />
|
||||
<b>Note</b> The template version replaces getBooleanField, etc.<br/>
|
||||
</dd>
|
||||
<dt>getSubFieldT(std::string const &fieldName)</dt>
|
||||
<dd>Like getSubField except that it throws std::runtime_error if
|
||||
the field does not exists or has the wrong type.</dd>
|
||||
<dt>getSubFieldT(int fieldOffset)</dt>
|
||||
<dd>Like getSubField except that it throws std::runtime_error if
|
||||
the field does not exists or has the wrong type.</dd>
|
||||
<dt>dumpValue</dt>
|
||||
<dd>Method for streams I/O.</dd>
|
||||
</dl>
|
||||
@@ -2662,12 +2676,6 @@ objects:</p>
|
||||
</dl>
|
||||
<h3>convert.h</h3>
|
||||
|
||||
<p>NOTE about copying immutable array fields. If an entire immutable array
|
||||
field is copied to another array that has the same elementType, both offsets
|
||||
are 0, and the length is the length of the source array, then the shareData
|
||||
method of the target array is called and the target array is set immutable.
|
||||
Thus the source and target share the same primitive array.</p>
|
||||
|
||||
<p>This section describes the supported conversions between data types.</p>
|
||||
<ul>
|
||||
<li>All supported types can be converted to a string. If you ask for a 100
|
||||
@@ -2681,12 +2689,6 @@ Thus the source and target share the same primitive array.</p>
|
||||
<li>Either is a string</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Copy between PVArrays that satisfy one of the following.
|
||||
<ul>
|
||||
<li>Both have the same type.</li>
|
||||
<li>Either is a string.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Conversions between numeric scalar types.</li>
|
||||
<li>Conversion between compatible structures.</li>
|
||||
<li>A utility method the returns the full field name of a field</li>
|
||||
|
||||
5480
documentation/pvDataCPP_20150623.html
Normal file
5480
documentation/pvDataCPP_20150623.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,10 +4,19 @@
|
||||
# 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>
|
||||
# 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"}
|
||||
|
||||
###########################################
|
||||
# Fetch and unpack dependencies
|
||||
|
||||
@@ -17,10 +26,8 @@ rm -fr ${STUFF}
|
||||
mkdir -p ${STUFF}
|
||||
cd ${STUFF}
|
||||
|
||||
wget -nv https://openepics.ci.cloudbees.com/job/Base-3.14.12.3_Build/lastSuccessfulBuild/artifact/baseR3.14.12.3.CB-dist.tar.gz
|
||||
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 baseR3.14.12.3.CB-dist.tar.gz
|
||||
tar -xzf doxygen-1.8.3.CB-dist.tar.gz
|
||||
wget -nv https://openepics.ci.cloudbees.com/job/Base-${BASE}_Build/lastSuccessfulBuild/artifact/base-${BASE}.CB-dist.tar.gz
|
||||
tar -xzf base-${BASE}.CB-dist.tar.gz
|
||||
|
||||
###########################################
|
||||
# Build
|
||||
@@ -37,20 +44,13 @@ EPICS_BASE=${EPICS_BASE}
|
||||
EOF
|
||||
|
||||
make distclean all
|
||||
doxygen
|
||||
|
||||
###########################################
|
||||
# Test
|
||||
|
||||
# EPICS Test Harness tests
|
||||
make runtests
|
||||
|
||||
###########################################
|
||||
# Create distribution
|
||||
|
||||
tar czf pvData.CB-dist.tar.gz lib include COPYRIGHT LICENSE
|
||||
|
||||
###########################################
|
||||
# Publish documentation
|
||||
|
||||
rsync -aP --delete -e ssh documentation epics-jenkins@web.sourceforge.net:/home/project-web/epics-pvdata/htdocs/docbuild/pvDataCPP/tip
|
||||
|
||||
51
jenkins/cloudbees_doc
Normal file
51
jenkins/cloudbees_doc
Normal file
@@ -0,0 +1,51 @@
|
||||
# pvData 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/pvDataCPP_Build/BASE=${BASE},USE_MB=MB_NO/lastSuccessfulBuild/artifact/pvData.CB-dist.tar.gz
|
||||
tar -xzf pvData.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/pvDataCPP/${PUBLISH}/
|
||||
|
||||
rsync -aqP --delete -e ssh documentation epics-jenkins@web.sourceforge.net:/home/project-web/epics-pvdata/htdocs/docbuild/pvDataCPP/${PUBLISH}/
|
||||
fi
|
||||
@@ -1,20 +0,0 @@
|
||||
# pvData C++ implementation
|
||||
# Jenkins @ Cloudbees hgweb sync 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
|
||||
# All rights reserved. Use is subject to license terms.
|
||||
|
||||
###########################################
|
||||
# Fetch complete repo
|
||||
|
||||
rm -fr hgweb
|
||||
hg clone -U http://hg.code.sf.net/p/epics-pvdata/pvDataCPP hgweb
|
||||
|
||||
###########################################
|
||||
# Sync into SF webspace
|
||||
|
||||
rsync -aqP --delete --exclude=\.hg/hgrc -e ssh hgweb/.hg epics-jenkins@web.sourceforge.net:/home/project-web/epics-pvdata/repos/pvDataCPP
|
||||
@@ -1 +0,0 @@
|
||||
// ADD PREDEFINED MACROS HERE!
|
||||
@@ -1 +0,0 @@
|
||||
[General]
|
||||
491
pvDataCPP.files
491
pvDataCPP.files
@@ -1,491 +0,0 @@
|
||||
configure/CONFIG
|
||||
configure/CONFIG_SITE
|
||||
configure/RELEASE
|
||||
configure/RELEASE.local
|
||||
configure/RULES
|
||||
configure/RULES.ioc
|
||||
configure/RULES_DIRS
|
||||
configure/RULES_TOP
|
||||
documentation/pvDataCPP.html
|
||||
documentation/pvDataCPP_20120927.html
|
||||
documentation/pvDataCPP_20121001.html
|
||||
documentation/pvDataCPP_20121026.html
|
||||
documentation/pvDataCPP_20121212.html
|
||||
jenkins/cloudbees_build
|
||||
pvDataApp/factory/Compare.cpp
|
||||
pvDataApp/factory/Convert.cpp
|
||||
pvDataApp/factory/factory.h
|
||||
pvDataApp/factory/FieldCreateFactory.cpp
|
||||
pvDataApp/factory/PVArray.cpp
|
||||
pvDataApp/factory/PVAuxInfoImpl.cpp
|
||||
pvDataApp/factory/PVDataCreateFactory.cpp
|
||||
pvDataApp/factory/PVDataCreateFactory.cpp.orig
|
||||
pvDataApp/factory/PVField.cpp
|
||||
pvDataApp/factory/PVScalar.cpp
|
||||
pvDataApp/factory/PVScalarArray.cpp
|
||||
pvDataApp/factory/PVStructure.cpp
|
||||
pvDataApp/factory/PVStructureArray.cpp
|
||||
pvDataApp/factory/StandardField.cpp
|
||||
pvDataApp/factory/StandardPVField.cpp
|
||||
pvDataApp/factory/TypeFunc.cpp
|
||||
pvDataApp/misc/bitSet.cpp
|
||||
pvDataApp/misc/bitSet.h
|
||||
pvDataApp/misc/byteBuffer.cpp
|
||||
pvDataApp/misc/byteBuffer.h
|
||||
pvDataApp/misc/destroyable.h
|
||||
pvDataApp/misc/epicsException.cpp
|
||||
pvDataApp/misc/epicsException.h
|
||||
pvDataApp/misc/event.cpp
|
||||
pvDataApp/misc/event.h
|
||||
pvDataApp/misc/executor.cpp
|
||||
pvDataApp/misc/executor.h
|
||||
pvDataApp/misc/localStaticLock.cpp
|
||||
pvDataApp/misc/localStaticLock.h
|
||||
pvDataApp/misc/localStaticLock.h.orig
|
||||
pvDataApp/misc/lock.h
|
||||
pvDataApp/misc/messageQueue.cpp
|
||||
pvDataApp/misc/messageQueue.h
|
||||
pvDataApp/misc/noDefaultMethods.h
|
||||
pvDataApp/misc/queue.h
|
||||
pvDataApp/misc/requester.cpp
|
||||
pvDataApp/misc/requester.h
|
||||
pvDataApp/misc/requester.h.orig
|
||||
pvDataApp/misc/serialize.h
|
||||
pvDataApp/misc/serializeHelper.cpp
|
||||
pvDataApp/misc/serializeHelper.h
|
||||
pvDataApp/misc/sharedPtr.h
|
||||
pvDataApp/misc/status.cpp
|
||||
pvDataApp/misc/status.h
|
||||
pvDataApp/misc/thread.h
|
||||
pvDataApp/misc/timeFunction.cpp
|
||||
pvDataApp/misc/timeFunction.h
|
||||
pvDataApp/misc/timer.cpp
|
||||
pvDataApp/misc/timer.h
|
||||
pvDataApp/monitor/monitor.h
|
||||
pvDataApp/property/alarm.cpp
|
||||
pvDataApp/property/alarm.h
|
||||
pvDataApp/property/alarm.h.orig
|
||||
pvDataApp/property/control.h
|
||||
pvDataApp/property/display.h
|
||||
pvDataApp/property/pvAlarm.cpp
|
||||
pvDataApp/property/pvAlarm.h
|
||||
pvDataApp/property/pvControl.cpp
|
||||
pvDataApp/property/pvControl.h
|
||||
pvDataApp/property/pvDisplay.cpp
|
||||
pvDataApp/property/pvDisplay.h
|
||||
pvDataApp/property/pvEnumerated.cpp
|
||||
pvDataApp/property/pvEnumerated.h
|
||||
pvDataApp/property/pvTimeStamp.cpp
|
||||
pvDataApp/property/pvTimeStamp.h
|
||||
pvDataApp/property/timeStamp.cpp
|
||||
pvDataApp/property/timeStamp.h
|
||||
pvDataApp/property/timeStamp.h.orig
|
||||
pvDataApp/pv/convert.h
|
||||
pvDataApp/pv/pvData.h
|
||||
pvDataApp/pv/pvIntrospect.h
|
||||
pvDataApp/pv/pvType.h
|
||||
pvDataApp/pv/standardField.h
|
||||
pvDataApp/pv/standardPVField.h
|
||||
pvDataApp/pvMisc/bitSetUtil.cpp
|
||||
pvDataApp/pvMisc/bitSetUtil.h
|
||||
testApp/capi/testc.cpp
|
||||
testApp/capi/testc.py
|
||||
testApp/misc/testBaseException.cpp
|
||||
testApp/misc/testBitSet.cpp
|
||||
testApp/misc/testByteBuffer.cpp
|
||||
testApp/misc/testByteOrder.cpp
|
||||
testApp/misc/testMessageQueue.cpp
|
||||
testApp/misc/testQueue.cpp
|
||||
testApp/misc/testSerialization.cpp
|
||||
testApp/misc/testThread.cpp
|
||||
testApp/misc/testTimer.cpp
|
||||
testApp/misc/testTimeStamp.cpp
|
||||
testApp/monitor/testMonitor.cpp
|
||||
testApp/property/testProperty.cpp
|
||||
testApp/pv/testConvert.cpp
|
||||
testApp/pv/testIntrospect.cpp
|
||||
testApp/pv/testOperators.cpp
|
||||
testApp/pv/testPVAppend.cpp
|
||||
testApp/pv/testPVAuxInfo.cpp
|
||||
testApp/pv/testPVData.cpp
|
||||
testApp/pv/testPVScalarArray.cpp
|
||||
testApp/pv/testPVStructureArray.cpp
|
||||
testApp/pv/testPVType.cpp
|
||||
testApp/pv/testStandardField.cpp
|
||||
testApp/pv/testStandardPVField.cpp
|
||||
COPYRIGHT
|
||||
Doxyfile
|
||||
LICENSE
|
||||
README.html
|
||||
src/copy/createRequest.cpp
|
||||
src/copy/createRequest.h
|
||||
src/copy/pvCopy.cpp
|
||||
src/copy/pvCopy.h
|
||||
src/factory/Compare.cpp
|
||||
src/factory/Convert.cpp
|
||||
src/factory/factory.h
|
||||
src/factory/FieldCreateFactory.cpp
|
||||
src/factory/printer.cpp
|
||||
src/factory/PVArray.cpp
|
||||
src/factory/PVDataCreateFactory.cpp
|
||||
src/factory/PVField.cpp
|
||||
src/factory/PVScalar.cpp
|
||||
src/factory/PVScalarArray.cpp
|
||||
src/factory/PVStructure.cpp
|
||||
src/factory/PVStructureArray.cpp
|
||||
src/factory/pvSubArrayCopy.cpp
|
||||
src/factory/PVUnion.cpp
|
||||
src/factory/PVUnionArray.cpp
|
||||
src/factory/StandardField.cpp
|
||||
src/factory/StandardPVField.cpp
|
||||
src/factory/TypeFunc.cpp
|
||||
src/misc/bitSet.cpp
|
||||
src/misc/bitSet.h
|
||||
src/misc/byteBuffer.cpp
|
||||
src/misc/byteBuffer.h
|
||||
src/misc/current_function.h
|
||||
src/misc/destroyable.h
|
||||
src/misc/epicsException.cpp
|
||||
src/misc/epicsException.h
|
||||
src/misc/event.cpp
|
||||
src/misc/event.h
|
||||
src/misc/executor.cpp
|
||||
src/misc/executor.h
|
||||
src/misc/localStaticLock.cpp
|
||||
src/misc/localStaticLock.h
|
||||
src/misc/lock.h
|
||||
src/misc/messageQueue.cpp
|
||||
src/misc/messageQueue.h
|
||||
src/misc/noDefaultMethods.h
|
||||
src/misc/parseToPOD.cpp
|
||||
src/misc/queue.h
|
||||
src/misc/requester.cpp
|
||||
src/misc/requester.h
|
||||
src/misc/serialize.h
|
||||
src/misc/serializeHelper.cpp
|
||||
src/misc/serializeHelper.h
|
||||
src/misc/sharedPtr.h
|
||||
src/misc/sharedVector.h
|
||||
src/misc/status.cpp
|
||||
src/misc/status.h
|
||||
src/misc/templateMeta.h
|
||||
src/misc/thread.h
|
||||
src/misc/timeFunction.cpp
|
||||
src/misc/timeFunction.h
|
||||
src/misc/timer.cpp
|
||||
src/misc/timer.h
|
||||
src/misc/typeCast.cpp
|
||||
src/misc/typeCast.h
|
||||
src/monitor/monitor.cpp
|
||||
src/monitor/monitor.h
|
||||
src/monitor/monitorPlugin.cpp
|
||||
src/monitor/monitorPlugin.h
|
||||
src/property/alarm.cpp
|
||||
src/property/alarm.h
|
||||
src/property/control.h
|
||||
src/property/display.h
|
||||
src/property/pvAlarm.cpp
|
||||
src/property/pvAlarm.h
|
||||
src/property/pvControl.cpp
|
||||
src/property/pvControl.h
|
||||
src/property/pvDisplay.cpp
|
||||
src/property/pvDisplay.h
|
||||
src/property/pvEnumerated.cpp
|
||||
src/property/pvEnumerated.h
|
||||
src/property/pvTimeStamp.cpp
|
||||
src/property/pvTimeStamp.h
|
||||
src/property/timeStamp.cpp
|
||||
src/property/timeStamp.h
|
||||
src/pv/convert.h
|
||||
src/pv/printer.h
|
||||
src/pv/pvData.h
|
||||
src/pv/pvIntrospect.h
|
||||
src/pv/pvSubArrayCopy.h
|
||||
src/pv/pvType.h
|
||||
src/pv/standardField.h
|
||||
src/pv/standardPVField.h
|
||||
src/pvMisc/bitSetUtil.cpp
|
||||
src/pvMisc/bitSetUtil.h
|
||||
testApp/copy/testCreateRequest.cpp
|
||||
testApp/copy/testPVCopy.cpp
|
||||
testApp/misc/testBaseException.cpp
|
||||
testApp/misc/testBitSet.cpp
|
||||
testApp/misc/testByteBuffer.cpp
|
||||
testApp/misc/testByteOrder.cpp
|
||||
testApp/misc/testMessageQueue.cpp
|
||||
testApp/misc/testOverrunBitSet.cpp
|
||||
testApp/misc/testQueue.cpp
|
||||
testApp/misc/testSerialization.cpp
|
||||
testApp/misc/testSharedVector.cpp
|
||||
testApp/misc/testThread.cpp
|
||||
testApp/misc/testTimer.cpp
|
||||
testApp/misc/testTimeStamp.cpp
|
||||
testApp/misc/testTypeCast.cpp
|
||||
testApp/property/testProperty.cpp
|
||||
testApp/pv/testBitSetUtil.cpp
|
||||
testApp/pv/testConvert.cpp
|
||||
testApp/pv/testFieldBuilder.cpp
|
||||
testApp/pv/testIntrospect.cpp
|
||||
testApp/pv/testOperators.cpp
|
||||
testApp/pv/testPVData.cpp
|
||||
testApp/pv/testPVScalarArray.cpp
|
||||
testApp/pv/testPVStructureArray.cpp
|
||||
testApp/pv/testPVType.cpp
|
||||
testApp/pv/testStandardField.cpp
|
||||
testApp/pv/testStandardPVField.cpp
|
||||
src/factory/printer.cpp
|
||||
configure/O.darwin-x86/Makefile
|
||||
configure/Makefile
|
||||
include/pv/alarm.h
|
||||
include/pv/bitSet.h
|
||||
include/pv/bitSetUtil.h
|
||||
include/pv/byteBuffer.h
|
||||
include/pv/control.h
|
||||
include/pv/convert.h
|
||||
include/pv/createRequest.h
|
||||
include/pv/current_function.h
|
||||
include/pv/destroyable.h
|
||||
include/pv/display.h
|
||||
include/pv/epicsException.h
|
||||
include/pv/event.h
|
||||
include/pv/executor.h
|
||||
include/pv/factory.h
|
||||
include/pv/localStaticLock.h
|
||||
include/pv/lock.h
|
||||
include/pv/messageQueue.h
|
||||
include/pv/monitor.h
|
||||
include/pv/monitorPlugin.h
|
||||
include/pv/noDefaultMethods.h
|
||||
include/pv/printer.h
|
||||
include/pv/pvAlarm.h
|
||||
include/pv/pvControl.h
|
||||
include/pv/pvCopy.h
|
||||
include/pv/pvData.h
|
||||
include/pv/pvDisplay.h
|
||||
include/pv/pvEnumerated.h
|
||||
include/pv/pvIntrospect.h
|
||||
include/pv/pvSubArrayCopy.h
|
||||
include/pv/pvTimeStamp.h
|
||||
include/pv/pvType.h
|
||||
include/pv/queue.h
|
||||
include/pv/requester.h
|
||||
include/pv/serialize.h
|
||||
include/pv/serializeHelper.h
|
||||
include/pv/sharedPtr.h
|
||||
include/pv/sharedVector.h
|
||||
include/pv/standardField.h
|
||||
include/pv/standardPVField.h
|
||||
include/pv/status.h
|
||||
include/pv/templateMeta.h
|
||||
include/pv/thread.h
|
||||
include/pv/timeFunction.h
|
||||
include/pv/timer.h
|
||||
include/pv/timeStamp.h
|
||||
include/pv/typeCast.h
|
||||
src/copy/createRequest.cpp
|
||||
src/copy/createRequest.h
|
||||
src/copy/Makefile
|
||||
src/copy/pvCopy.cpp
|
||||
src/copy/pvCopy.h
|
||||
src/factory/Compare.cpp
|
||||
src/factory/Convert.cpp
|
||||
src/factory/factory.h
|
||||
src/factory/FieldCreateFactory.cpp
|
||||
src/factory/Makefile
|
||||
src/factory/printer.cpp
|
||||
src/factory/PVArray.cpp
|
||||
src/factory/PVDataCreateFactory.cpp
|
||||
src/factory/PVField.cpp
|
||||
src/factory/PVScalar.cpp
|
||||
src/factory/PVScalarArray.cpp
|
||||
src/factory/PVStructure.cpp
|
||||
src/factory/PVStructureArray.cpp
|
||||
src/factory/pvSubArrayCopy.cpp
|
||||
src/factory/PVUnion.cpp
|
||||
src/factory/PVUnionArray.cpp
|
||||
src/factory/StandardField.cpp
|
||||
src/factory/StandardPVField.cpp
|
||||
src/factory/TypeFunc.cpp
|
||||
src/misc/bitSet.cpp
|
||||
src/misc/bitSet.h
|
||||
src/misc/byteBuffer.cpp
|
||||
src/misc/byteBuffer.h
|
||||
src/misc/current_function.h
|
||||
src/misc/destroyable.h
|
||||
src/misc/epicsException.cpp
|
||||
src/misc/epicsException.h
|
||||
src/misc/event.cpp
|
||||
src/misc/event.h
|
||||
src/misc/executor.cpp
|
||||
src/misc/executor.h
|
||||
src/misc/localStaticLock.cpp
|
||||
src/misc/localStaticLock.h
|
||||
src/misc/lock.h
|
||||
src/misc/Makefile
|
||||
src/misc/messageQueue.cpp
|
||||
src/misc/messageQueue.h
|
||||
src/misc/noDefaultMethods.h
|
||||
src/misc/parseToPOD.cpp
|
||||
src/misc/queue.h
|
||||
src/misc/requester.cpp
|
||||
src/misc/requester.h
|
||||
src/misc/serialize.h
|
||||
src/misc/serializeHelper.cpp
|
||||
src/misc/serializeHelper.h
|
||||
src/misc/sharedPtr.h
|
||||
src/misc/sharedVector.h
|
||||
src/misc/status.cpp
|
||||
src/misc/status.h
|
||||
src/misc/templateMeta.h
|
||||
src/misc/thread.h
|
||||
src/misc/timeFunction.cpp
|
||||
src/misc/timeFunction.h
|
||||
src/misc/timer.cpp
|
||||
src/misc/timer.h
|
||||
src/misc/typeCast.cpp
|
||||
src/misc/typeCast.h
|
||||
src/monitor/Makefile
|
||||
src/monitor/monitor.cpp
|
||||
src/monitor/monitor.h
|
||||
src/monitor/monitorPlugin.cpp
|
||||
src/monitor/monitorPlugin.h
|
||||
src/O.darwin-x86/Makefile
|
||||
src/property/alarm.cpp
|
||||
src/property/alarm.h
|
||||
src/property/control.h
|
||||
src/property/display.h
|
||||
src/property/Makefile
|
||||
src/property/pvAlarm.cpp
|
||||
src/property/pvAlarm.h
|
||||
src/property/pvControl.cpp
|
||||
src/property/pvControl.h
|
||||
src/property/pvDisplay.cpp
|
||||
src/property/pvDisplay.h
|
||||
src/property/pvEnumerated.cpp
|
||||
src/property/pvEnumerated.h
|
||||
src/property/pvTimeStamp.cpp
|
||||
src/property/pvTimeStamp.h
|
||||
src/property/timeStamp.cpp
|
||||
src/property/timeStamp.h
|
||||
src/pv/convert.h
|
||||
src/pv/Makefile
|
||||
src/pv/printer.h
|
||||
src/pv/pvData.h
|
||||
src/pv/pvIntrospect.h
|
||||
src/pv/pvSubArrayCopy.h
|
||||
src/pv/pvType.h
|
||||
src/pv/standardField.h
|
||||
src/pv/standardPVField.h
|
||||
src/pvMisc/bitSetUtil.cpp
|
||||
src/pvMisc/bitSetUtil.h
|
||||
src/pvMisc/Makefile
|
||||
src/Makefile
|
||||
testApp/copy/epicsRunPVDataTests.c
|
||||
testApp/copy/Makefile
|
||||
testApp/copy/testCreateRequest.cpp
|
||||
testApp/copy/testPVCopy.cpp
|
||||
testApp/misc/epicsRunPVDataTests.c
|
||||
testApp/misc/Makefile
|
||||
testApp/misc/testBaseException.cpp
|
||||
testApp/misc/testBitSet.cpp
|
||||
testApp/misc/testByteBuffer.cpp
|
||||
testApp/misc/testByteOrder.cpp
|
||||
testApp/misc/testMessageQueue.cpp
|
||||
testApp/misc/testOverrunBitSet.cpp
|
||||
testApp/misc/testQueue.cpp
|
||||
testApp/misc/testSerialization.cpp
|
||||
testApp/misc/testSharedVector.cpp
|
||||
testApp/misc/testThread.cpp
|
||||
testApp/misc/testTimer.cpp
|
||||
testApp/misc/testTimeStamp.cpp
|
||||
testApp/misc/testTypeCast.cpp
|
||||
testApp/property/epicsRunPVDataTests.c
|
||||
testApp/property/Makefile
|
||||
testApp/property/testProperty.cpp
|
||||
testApp/pv/epicsRunPVDataTests.c
|
||||
testApp/pv/Makefile
|
||||
testApp/pv/testBitSetUtil.cpp
|
||||
testApp/pv/testConvert.cpp
|
||||
testApp/pv/testFieldBuilder.cpp
|
||||
testApp/pv/testIntrospect.cpp
|
||||
testApp/pv/testOperators.cpp
|
||||
testApp/pv/testPVData.cpp
|
||||
testApp/pv/testPVScalarArray.cpp
|
||||
testApp/pv/testPVStructureArray.cpp
|
||||
testApp/pv/testPVType.cpp
|
||||
testApp/pv/testPVUnion.cpp
|
||||
testApp/pv/testStandardField.cpp
|
||||
testApp/pv/testStandardPVField.cpp
|
||||
testApp/Makefile
|
||||
Makefile
|
||||
testApp/copy/epicsRunPVDataTests.c
|
||||
testApp/copy/Makefile
|
||||
testApp/copy/testCreateRequest.cpp
|
||||
testApp/copy/testPVCopy.cpp
|
||||
testApp/misc/epicsRunPVDataTests.c
|
||||
testApp/misc/Makefile
|
||||
testApp/misc/testBaseException.cpp
|
||||
testApp/misc/testBitSet.cpp
|
||||
testApp/misc/testByteBuffer.cpp
|
||||
testApp/misc/testByteOrder.cpp
|
||||
testApp/misc/testMessageQueue.cpp
|
||||
testApp/misc/testOverrunBitSet.cpp
|
||||
testApp/misc/testQueue.cpp
|
||||
testApp/misc/testSerialization.cpp
|
||||
testApp/misc/testSharedVector.cpp
|
||||
testApp/misc/testThread.cpp
|
||||
testApp/misc/testTimer.cpp
|
||||
testApp/misc/testTimeStamp.cpp
|
||||
testApp/misc/testTypeCast.cpp
|
||||
testApp/O.darwin-x86/Makefile
|
||||
testApp/property/epicsRunPVDataTests.c
|
||||
testApp/property/Makefile
|
||||
testApp/property/testProperty.cpp
|
||||
testApp/pv/epicsRunPVDataTests.c
|
||||
testApp/pv/Makefile
|
||||
testApp/pv/testBitSetUtil.cpp
|
||||
testApp/pv/testConvert.cpp
|
||||
testApp/pv/testFieldBuilder.cpp
|
||||
testApp/pv/testIntrospect.cpp
|
||||
testApp/pv/testOperators.cpp
|
||||
testApp/pv/testPVData.cpp
|
||||
testApp/pv/testPVScalarArray.cpp
|
||||
testApp/pv/testPVStructureArray.cpp
|
||||
testApp/pv/testPVType.cpp
|
||||
testApp/pv/testPVUnion.cpp
|
||||
testApp/pv/testStandardField.cpp
|
||||
testApp/pv/testStandardPVField.cpp
|
||||
testApp/Makefile
|
||||
testApp/pvDataAllTests.c
|
||||
testApp/copy/testCreateRequest.cpp
|
||||
testApp/copy/testPVCopy.cpp
|
||||
testApp/misc/testBaseException.cpp
|
||||
testApp/misc/testBitSet.cpp
|
||||
testApp/misc/testByteBuffer.cpp
|
||||
testApp/misc/testByteOrder.cpp
|
||||
testApp/misc/testMessageQueue.cpp
|
||||
testApp/misc/testOverrunBitSet.cpp
|
||||
testApp/misc/testQueue.cpp
|
||||
testApp/misc/testSerialization.cpp
|
||||
testApp/misc/testSharedVector.cpp
|
||||
testApp/misc/testThread.cpp
|
||||
testApp/misc/testTimer.cpp
|
||||
testApp/misc/testTimeStamp.cpp
|
||||
testApp/misc/testTypeCast.cpp
|
||||
testApp/property/testProperty.cpp
|
||||
testApp/pv/testBitSetUtil.cpp
|
||||
testApp/pv/testConvert.cpp
|
||||
testApp/pv/testFieldBuilder.cpp
|
||||
testApp/pv/testIntrospect.cpp
|
||||
testApp/pv/testOperators.cpp
|
||||
testApp/pv/testPVData.cpp
|
||||
testApp/pv/testPVScalarArray.cpp
|
||||
testApp/pv/testPVStructureArray.cpp
|
||||
testApp/pv/testPVType.cpp
|
||||
testApp/pv/testPVUnion.cpp
|
||||
testApp/pv/testStandardField.cpp
|
||||
testApp/pv/testStandardPVField.cpp
|
||||
testApp/pvDataAllTests.c
|
||||
testApp/rtemsConfig.c
|
||||
testApp/rtemsNetworking.h
|
||||
testApp/rtemsTestHarness.c
|
||||
@@ -1,11 +0,0 @@
|
||||
/home/msekoranja/epicsV4/pvDataCPP/pvDataApp/factory
|
||||
/home/msekoranja/epicsV4/pvDataCPP/pvDataApp/misc
|
||||
/home/msekoranja/epicsV4/pvDataCPP/pvDataApp/monitor
|
||||
/home/msekoranja/epicsV4/pvDataCPP/pvDataApp/property
|
||||
/home/msekoranja/epicsV4/pvDataCPP/pvDataApp/pv
|
||||
/home/msekoranja/epicsV4/pvDataCPP/pvDataApp/pvMisc
|
||||
testApp/pv
|
||||
testApp/copy
|
||||
testApp/misc
|
||||
testApp
|
||||
testApp/property
|
||||
@@ -322,149 +322,157 @@ public:
|
||||
virtual PVStructurePtr createRequest(
|
||||
string const & crequest)
|
||||
{
|
||||
string request = crequest;
|
||||
if (!request.empty()) removeBlanks(request);
|
||||
if (request.empty())
|
||||
{
|
||||
return pvDataCreate->createPVStructure(fieldCreate->createStructure());
|
||||
}
|
||||
size_t offsetRecord = request.find("record[");
|
||||
size_t offsetField = request.find("field(");
|
||||
size_t offsetPutField = request.find("putField(");
|
||||
size_t offsetGetField = request.find("getField(");
|
||||
if(offsetRecord==string::npos
|
||||
&& offsetField==string::npos
|
||||
&& offsetPutField==string::npos
|
||||
&& offsetGetField==string::npos)
|
||||
{
|
||||
request = "field(" + request + ")";
|
||||
offsetField = request.find("field(");
|
||||
}
|
||||
int numParan = 0;
|
||||
int numBrace = 0;
|
||||
int numBracket = 0;
|
||||
for(size_t i=0; i< request.length() ; ++i) {
|
||||
char chr = request[i];
|
||||
if(chr=='(') numParan++;
|
||||
if(chr==')') numParan--;
|
||||
if(chr=='{') numBrace++;
|
||||
if(chr=='}') numBrace--;
|
||||
if(chr=='[') numBracket++;
|
||||
if(chr==']') numBracket--;
|
||||
}
|
||||
if(numParan!=0) {
|
||||
ostringstream oss;
|
||||
oss << "mismatched () " << numParan;
|
||||
message = oss.str();
|
||||
return PVStructurePtr();
|
||||
}
|
||||
if(numBrace!=0) {
|
||||
ostringstream oss;
|
||||
oss << "mismatched {} " << numBrace;
|
||||
message = oss.str();
|
||||
return PVStructurePtr();
|
||||
}
|
||||
if(numBracket!=0) {
|
||||
ostringstream oss;
|
||||
oss << "mismatched [] " << numBracket;
|
||||
message = oss.str();
|
||||
return PVStructurePtr();
|
||||
}
|
||||
vector<Node> top;
|
||||
try {
|
||||
if(offsetRecord!=string::npos) {
|
||||
fullFieldName = "record";
|
||||
size_t openBracket = request.find('[', offsetRecord);
|
||||
size_t closeBracket = request.find(']', openBracket);
|
||||
if(closeBracket==string::npos) {
|
||||
message = request.substr(offsetRecord) +
|
||||
"record[ does not have matching ]";
|
||||
return PVStructurePtr();
|
||||
string request = crequest;
|
||||
if (!request.empty()) removeBlanks(request);
|
||||
if (request.empty())
|
||||
{
|
||||
return pvDataCreate->createPVStructure(fieldCreate->createStructure());
|
||||
}
|
||||
size_t offsetRecord = request.find("record[");
|
||||
size_t offsetField = request.find("field(");
|
||||
size_t offsetPutField = request.find("putField(");
|
||||
size_t offsetGetField = request.find("getField(");
|
||||
if(offsetRecord==string::npos
|
||||
&& offsetField==string::npos
|
||||
&& offsetPutField==string::npos
|
||||
&& offsetGetField==string::npos)
|
||||
{
|
||||
request = "field(" + request + ")";
|
||||
offsetField = request.find("field(");
|
||||
}
|
||||
int numParan = 0;
|
||||
int numBrace = 0;
|
||||
int numBracket = 0;
|
||||
for(size_t i=0; i< request.length() ; ++i) {
|
||||
char chr = request[i];
|
||||
if(chr=='(') numParan++;
|
||||
if(chr==')') numParan--;
|
||||
if(chr=='{') numBrace++;
|
||||
if(chr=='}') numBrace--;
|
||||
if(chr=='[') numBracket++;
|
||||
if(chr==']') numBracket--;
|
||||
}
|
||||
if(numParan!=0) {
|
||||
ostringstream oss;
|
||||
oss << "mismatched () " << numParan;
|
||||
message = oss.str();
|
||||
return PVStructurePtr();
|
||||
}
|
||||
if(numBrace!=0) {
|
||||
ostringstream oss;
|
||||
oss << "mismatched {} " << numBrace;
|
||||
message = oss.str();
|
||||
return PVStructurePtr();
|
||||
}
|
||||
if(numBracket!=0) {
|
||||
ostringstream oss;
|
||||
oss << "mismatched [] " << numBracket;
|
||||
message = oss.str();
|
||||
return PVStructurePtr();
|
||||
}
|
||||
vector<Node> top;
|
||||
try {
|
||||
if(offsetRecord!=string::npos) {
|
||||
fullFieldName = "record";
|
||||
size_t openBracket = request.find('[', offsetRecord);
|
||||
size_t closeBracket = request.find(']', openBracket);
|
||||
if(closeBracket==string::npos) {
|
||||
message = request.substr(offsetRecord) +
|
||||
"record[ does not have matching ]";
|
||||
return PVStructurePtr();
|
||||
}
|
||||
if(closeBracket-openBracket > 3) {
|
||||
Node node("record");
|
||||
Node optNode = createRequestOptions(
|
||||
request.substr(openBracket+1,closeBracket-openBracket-1));
|
||||
node.nodes.push_back(optNode);
|
||||
top.push_back(node);
|
||||
}
|
||||
}
|
||||
if(closeBracket-openBracket > 3) {
|
||||
Node node("record");
|
||||
Node optNode = createRequestOptions(
|
||||
request.substr(openBracket+1,closeBracket-openBracket-1));
|
||||
node.nodes.push_back(optNode);
|
||||
if(offsetField!=string::npos) {
|
||||
fullFieldName = "field";
|
||||
Node node("field");
|
||||
size_t openParan = request.find('(', offsetField);
|
||||
size_t closeParan = request.find(')', openParan);
|
||||
if(closeParan==string::npos) {
|
||||
message = request.substr(offsetField)
|
||||
+ " field( does not have matching )";
|
||||
return PVStructurePtr();
|
||||
}
|
||||
if(closeParan>openParan+1) {
|
||||
createSubNode(node,request.substr(openParan+1,closeParan-openParan-1));
|
||||
}
|
||||
top.push_back(node);
|
||||
}
|
||||
if(offsetGetField!=string::npos) {
|
||||
fullFieldName = "getField";
|
||||
Node node("getField");
|
||||
size_t openParan = request.find('(', offsetGetField);
|
||||
size_t closeParan = request.find(')', openParan);
|
||||
if(closeParan==string::npos) {
|
||||
message = request.substr(offsetField)
|
||||
+ " getField( does not have matching )";
|
||||
return PVStructurePtr();
|
||||
}
|
||||
if(closeParan>openParan+1) {
|
||||
createSubNode(node,request.substr(openParan+1,closeParan-openParan-1));
|
||||
}
|
||||
top.push_back(node);
|
||||
}
|
||||
if(offsetPutField!=string::npos) {
|
||||
fullFieldName = "putField";
|
||||
Node node("putField");
|
||||
size_t openParan = request.find('(', offsetPutField);
|
||||
size_t closeParan = request.find(')', openParan);
|
||||
if(closeParan==string::npos) {
|
||||
message = request.substr(offsetField)
|
||||
+ " putField( does not have matching )";
|
||||
return PVStructurePtr();
|
||||
}
|
||||
if(closeParan>openParan+1) {
|
||||
createSubNode(node,request.substr(openParan+1,closeParan-openParan-1));
|
||||
}
|
||||
top.push_back(node);
|
||||
}
|
||||
} catch (std::exception &e) {
|
||||
string xxx = e.what();
|
||||
message = "while creating Structure exception " + xxx;
|
||||
return PVStructurePtr();
|
||||
}
|
||||
if(offsetField!=string::npos) {
|
||||
fullFieldName = "field";
|
||||
Node node("field");
|
||||
size_t openParan = request.find('(', offsetField);
|
||||
size_t closeParan = request.find(')', openParan);
|
||||
if(closeParan==string::npos) {
|
||||
message = request.substr(offsetField)
|
||||
+ " field( does not have matching )";
|
||||
return PVStructurePtr();
|
||||
size_t num = top.size();
|
||||
StringArray names(num);
|
||||
FieldConstPtrArray fields(num);
|
||||
for(size_t i=0; i<num; ++i) {
|
||||
Node node = top[i];
|
||||
names[i] = node.name;
|
||||
vector<Node> subNode = node.nodes;
|
||||
if(subNode.empty()) {
|
||||
fields[i] = fieldCreate->createStructure();
|
||||
} else {
|
||||
fields[i] = createSubStructure(subNode);
|
||||
}
|
||||
if(closeParan>openParan+1) {
|
||||
createSubNode(node,request.substr(openParan+1,closeParan-openParan-1));
|
||||
}
|
||||
top.push_back(node);
|
||||
}
|
||||
if(offsetGetField!=string::npos) {
|
||||
fullFieldName = "getField";
|
||||
Node node("getField");
|
||||
size_t openParan = request.find('(', offsetGetField);
|
||||
size_t closeParan = request.find(')', openParan);
|
||||
if(closeParan==string::npos) {
|
||||
message = request.substr(offsetField)
|
||||
+ " getField( does not have matching )";
|
||||
return PVStructurePtr();
|
||||
}
|
||||
if(closeParan>openParan+1) {
|
||||
createSubNode(node,request.substr(openParan+1,closeParan-openParan-1));
|
||||
}
|
||||
top.push_back(node);
|
||||
}
|
||||
if(offsetPutField!=string::npos) {
|
||||
fullFieldName = "putField";
|
||||
Node node("putField");
|
||||
size_t openParan = request.find('(', offsetPutField);
|
||||
size_t closeParan = request.find(')', openParan);
|
||||
if(closeParan==string::npos) {
|
||||
message = request.substr(offsetField)
|
||||
+ " putField( does not have matching )";
|
||||
return PVStructurePtr();
|
||||
}
|
||||
if(closeParan>openParan+1) {
|
||||
createSubNode(node,request.substr(openParan+1,closeParan-openParan-1));
|
||||
}
|
||||
top.push_back(node);
|
||||
StructureConstPtr structure = fieldCreate->createStructure(names, fields);
|
||||
if(!structure) throw std::invalid_argument("bad request " + crequest);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(structure);
|
||||
for(size_t i=0; i<optionList.size(); ++i) {
|
||||
OptionPair pair = optionList[i];
|
||||
string name = pair.name;
|
||||
string value = pair.value;
|
||||
PVStringPtr pvField = pvStructure->getSubField<PVString>(name);
|
||||
if(!pvField) throw std::invalid_argument("bad request " + crequest);
|
||||
pvField->put(value);
|
||||
}
|
||||
optionList.clear();
|
||||
return pvStructure;
|
||||
} catch (std::exception &e) {
|
||||
string xxx = e.what();
|
||||
message = "while creating Structure exception " + xxx;
|
||||
return PVStructurePtr();
|
||||
message = e.what();
|
||||
return PVStructurePtr();
|
||||
}
|
||||
size_t num = top.size();
|
||||
StringArray names(num);
|
||||
FieldConstPtrArray fields(num);
|
||||
for(size_t i=0; i<num; ++i) {
|
||||
Node node = top[i];
|
||||
names[i] = node.name;
|
||||
vector<Node> subNode = node.nodes;
|
||||
if(subNode.empty()) {
|
||||
fields[i] = fieldCreate->createStructure();
|
||||
} else {
|
||||
fields[i] = createSubStructure(subNode);
|
||||
}
|
||||
}
|
||||
StructureConstPtr structure = fieldCreate->createStructure(names, fields);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(structure);
|
||||
for(size_t i=0; i<optionList.size(); ++i) {
|
||||
OptionPair pair = optionList[i];
|
||||
string name = pair.name;
|
||||
string value = pair.value;
|
||||
PVStringPtr pvField = pvStructure->getSubField<PVString>(name);
|
||||
pvField->put(value);
|
||||
}
|
||||
optionList.clear();
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
CreateRequest::shared_pointer CreateRequest::create()
|
||||
|
||||
@@ -18,7 +18,12 @@
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/**
|
||||
* Class to create pvRequest structures to pass to pvAccess Channel methods.
|
||||
* @brief Create pvRequest structure for Channel methods.
|
||||
*
|
||||
* Many methods of the Channel class of pvAccess have an
|
||||
* argument <b>PVStructurePtr const * pvRequest</b>.
|
||||
* This class provides a method that creates a valid pvRequest.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass CreateRequest {
|
||||
public:
|
||||
@@ -33,7 +38,6 @@ class epicsShareClass CreateRequest {
|
||||
* Create a request structure for the create calls in Channel.
|
||||
* See the package overview documentation for details.
|
||||
* @param request The field request. See the package overview documentation for details.
|
||||
* @param requester The requester;
|
||||
* @return The request PVStructure if a valid request was given.
|
||||
* If a NULL PVStructure is returned then getMessage will return
|
||||
* the reason.
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <pv/thread.h>
|
||||
|
||||
#include <pv/pvCopy.h>
|
||||
#include <pv/convert.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
@@ -29,6 +28,18 @@ using std::endl;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/**
|
||||
* Convenience method for implementing dump.
|
||||
* It generates a newline and inserts blanks at the beginning of the newline.
|
||||
* @param builder The std::string * being constructed.
|
||||
* @param indentLevel Indent level, Each level is four spaces.
|
||||
*/
|
||||
static void newLine(string *buffer, int indentLevel)
|
||||
{
|
||||
*buffer += "\n";
|
||||
*buffer += string(indentLevel*4, ' ');
|
||||
}
|
||||
|
||||
static PVCopyPtr NULLPVCopy;
|
||||
static FieldConstPtr NULLField;
|
||||
static StructureConstPtr NULLStructure;
|
||||
@@ -67,11 +78,11 @@ PVCopyPtr PVCopy::create(
|
||||
PVStructurePtr pvStructure(pvRequest);
|
||||
if(structureName.size()>0) {
|
||||
if(pvRequest->getStructure()->getNumberFields()>0) {
|
||||
pvStructure = pvRequest->getStructureField(structureName);
|
||||
pvStructure = pvRequest->getSubField<PVStructure>(structureName);
|
||||
if(!pvStructure) return NULLPVCopy;
|
||||
}
|
||||
} else if(pvStructure->getSubField("field")) {
|
||||
pvStructure = pvRequest->getStructureField("field");
|
||||
pvStructure = pvRequest->getSubField<PVStructure>("field");
|
||||
}
|
||||
PVCopyPtr pvCopy = PVCopyPtr(new PVCopy(pvMaster));
|
||||
bool result = pvCopy->init(pvStructure);
|
||||
@@ -243,10 +254,9 @@ void PVCopy::updateCopySetBitSet(
|
||||
updateSubFieldSetBitSet(copyPVField,pvMasterField,bitSet);
|
||||
return;
|
||||
}
|
||||
ConvertPtr convert = getConvert();
|
||||
bool isEqual = convert->equals(copyPVField,pvField);
|
||||
bool isEqual = (*copyPVField == *pvField);
|
||||
if(!isEqual) {
|
||||
convert->copy(pvField, copyPVField);
|
||||
copyPVField->copyUnchecked(*pvField);
|
||||
bitSet->set(copyPVField->getFieldOffset());
|
||||
}
|
||||
}
|
||||
@@ -292,7 +302,7 @@ string PVCopy::dump()
|
||||
|
||||
void PVCopy::dump(string *builder,CopyNodePtr const &node,int indentLevel)
|
||||
{
|
||||
getConvert()->newLine(builder,indentLevel);
|
||||
newLine(builder,indentLevel);
|
||||
std::stringstream ss;
|
||||
ss << (node->isStructure ? "structureNode" : "masterNode");
|
||||
ss << " structureOffset " << node->structureOffset;
|
||||
@@ -300,14 +310,14 @@ void PVCopy::dump(string *builder,CopyNodePtr const &node,int indentLevel)
|
||||
*builder += ss.str();
|
||||
PVStructurePtr options = node->options;
|
||||
if(options) {
|
||||
getConvert()->newLine(builder,indentLevel +1);
|
||||
newLine(builder,indentLevel +1);
|
||||
|
||||
// TODO !!! ugly
|
||||
std::ostringstream oss;
|
||||
oss << *options;
|
||||
*builder += oss.str();
|
||||
|
||||
getConvert()->newLine(builder,indentLevel);
|
||||
newLine(builder,indentLevel);
|
||||
}
|
||||
if(!node->isStructure) {
|
||||
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(node);
|
||||
@@ -320,7 +330,7 @@ void PVCopy::dump(string *builder,CopyNodePtr const &node,int indentLevel)
|
||||
CopyNodePtrArrayPtr nodes = structureNode->nodes;
|
||||
for(size_t i=0; i<nodes->size(); ++i) {
|
||||
if((*nodes)[i].get()==NULL) {
|
||||
getConvert()->newLine(builder,indentLevel +1);
|
||||
newLine(builder,indentLevel +1);
|
||||
ss.str("");
|
||||
ss << "node[" << i << "] is null";
|
||||
*builder += ss.str();
|
||||
@@ -339,7 +349,7 @@ bool PVCopy::init(epics::pvData::PVStructurePtr const &pvRequest)
|
||||
if(len==0) entireMaster = true;
|
||||
PVStructurePtr pvOptions;
|
||||
if(len==1 && pvRequest->getSubField("_options")) {
|
||||
pvOptions = pvRequest->getStructureField("_options");
|
||||
pvOptions = pvRequest->getSubField<PVStructure>("_options");
|
||||
}
|
||||
if(entireMaster) {
|
||||
structure = pvMasterStructure->getStructure();
|
||||
@@ -499,17 +509,16 @@ void PVCopy::updateSubFieldSetBitSet(
|
||||
FieldConstPtr field = pvCopy->getField();
|
||||
Type type = field->getType();
|
||||
if(type!=epics::pvData::structure) {
|
||||
ConvertPtr convert = getConvert();
|
||||
bool isEqual = convert->equals(pvCopy,pvMaster);
|
||||
bool isEqual = (*pvCopy == *pvMaster);
|
||||
if(isEqual) {
|
||||
if(type==structureArray) {
|
||||
// always act as though a change occurred.
|
||||
// Note that array elements are shared.
|
||||
bitSet->set(pvCopy->getFieldOffset());
|
||||
bitSet->set(pvCopy->getFieldOffset());
|
||||
}
|
||||
}
|
||||
if(isEqual) return;
|
||||
convert->copy(pvMaster, pvCopy);
|
||||
pvCopy->copyUnchecked(*pvMaster);
|
||||
bitSet->set(pvCopy->getFieldOffset());
|
||||
return;
|
||||
}
|
||||
@@ -574,7 +583,6 @@ void PVCopy::updateSubFieldFromBitSet(
|
||||
if(nextSet==string::npos) return;
|
||||
if(nextSet>=pvCopy->getNextFieldOffset()) return;
|
||||
}
|
||||
ConvertPtr convert = getConvert();
|
||||
if(pvCopy->getField()->getType()==epics::pvData::structure) {
|
||||
PVStructurePtr pvCopyStructure =
|
||||
static_pointer_cast<PVStructure>(pvCopy);
|
||||
@@ -595,9 +603,9 @@ void PVCopy::updateSubFieldFromBitSet(
|
||||
}
|
||||
} else {
|
||||
if(toCopy) {
|
||||
convert->copy(pvMasterField, pvCopy);
|
||||
pvCopy->copyUnchecked(*pvMasterField);
|
||||
} else {
|
||||
convert->copy(pvCopy, pvMasterField);
|
||||
pvMasterField->copyUnchecked(*pvCopy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ class PVCopyTraverseMasterCallback;
|
||||
typedef std::tr1::shared_ptr<PVCopyTraverseMasterCallback> PVCopyTraverseMasterCallbackPtr;
|
||||
|
||||
/**
|
||||
* Callback for traversing master structure
|
||||
* @brief Callback for traversing master structure
|
||||
*
|
||||
* Must be implemented by code that creates pvCopy.
|
||||
*/
|
||||
class epicsShareClass PVCopyTraverseMasterCallback
|
||||
@@ -53,6 +54,8 @@ typedef std::tr1::shared_ptr<CopyStructureNode> CopyStructureNodePtr;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Support for subset of fields in a pvStructure.
|
||||
*
|
||||
* Class that manages one or more PVStructures that holds an arbitrary subset of the fields
|
||||
* in another PVStructure called master.
|
||||
*/
|
||||
@@ -63,8 +66,8 @@ public:
|
||||
POINTER_DEFINITIONS(PVCopy);
|
||||
/**
|
||||
* Create a new pvCopy
|
||||
* @param pvMaster The top level sructure for which a copy of
|
||||
* an arbritary subset of the fields in master will be created and managed.
|
||||
* @param pvMaster The top-level structure for which a copy of
|
||||
* an arbitrary subset of the fields in master will be created and managed.
|
||||
* @param pvRequest Selects the set of subfields desired and options for each field.
|
||||
* @param structureName The name for the top level of any PVStructure created.
|
||||
*/
|
||||
@@ -75,8 +78,8 @@ public:
|
||||
virtual ~PVCopy(){}
|
||||
virtual void destroy();
|
||||
/**
|
||||
* Get the top level structure of master
|
||||
* @returns The master top level structure.
|
||||
* Get the top-level structure of master
|
||||
* @returns The master top-level structure.
|
||||
* This should not be modified.
|
||||
*/
|
||||
PVStructurePtr getPVMaster();
|
||||
@@ -94,7 +97,7 @@ public:
|
||||
StructureConstPtr getStructure();
|
||||
/**
|
||||
* Create a copy instance. Monitors keep a queue of monitor elements.
|
||||
* Since each element needs a PVStructure, multiple top level structures will be created.
|
||||
* Since each element needs a PVStructure, multiple top-level structures will be created.
|
||||
*/
|
||||
PVStructurePtr createPVStructure();
|
||||
/**
|
||||
@@ -113,15 +116,15 @@ public:
|
||||
PVStructurePtr const &masterPVStructure,
|
||||
PVFieldPtr const &masterPVField);
|
||||
/**
|
||||
* Given a offset in the copy get the corresponding field in pvMaster.
|
||||
* @param offset The offset in the copy.
|
||||
* Given an offset in the copy get the corresponding field in pvMaster.
|
||||
* @param structureOffset The offset in the copy.
|
||||
*/
|
||||
PVFieldPtr getMasterPVField(std::size_t structureOffset);
|
||||
/**
|
||||
* Initialize the fields in copyPVStructure by giving each field
|
||||
* the value from the corresponding field in pvMaster.
|
||||
* bitSet will be set to show that all fields are changed.
|
||||
* @param copyPVStructure A copy top level structure.
|
||||
* @param copyPVStructure A copy top-level structure.
|
||||
* @param bitSet A bitSet for copyPVStructure.
|
||||
*/
|
||||
void initCopy(
|
||||
@@ -130,7 +133,7 @@ public:
|
||||
/**
|
||||
* Set all fields in copyPVStructure to the value of the corresponding field in pvMaster.
|
||||
* Each field that is changed has it's corresponding bit set in bitSet.
|
||||
* @param copyPVStructure A copy top level structure.
|
||||
* @param copyPVStructure A copy top-level structure.
|
||||
* @param bitSet A bitSet for copyPVStructure.
|
||||
*/
|
||||
void updateCopySetBitSet(
|
||||
@@ -138,8 +141,8 @@ public:
|
||||
BitSetPtr const &bitSet);
|
||||
/**
|
||||
* For each set bit in bitSet
|
||||
* set the field in copyPVStructure to the value of the corrseponding field in pvMaster.
|
||||
* @param copyPVStructure A copy top level structure.
|
||||
* set the field in copyPVStructure to the value of the corresponding field in pvMaster.
|
||||
* @param copyPVStructure A copy top-level structure.
|
||||
* @param bitSet A bitSet for copyPVStructure.
|
||||
*/
|
||||
void updateCopyFromBitSet(
|
||||
@@ -147,8 +150,8 @@ public:
|
||||
BitSetPtr const &bitSet);
|
||||
/**
|
||||
* For each set bit in bitSet
|
||||
* set the field in pvMaster to the value of the corrseponding field in copyPVStructure
|
||||
* @param copyPVStructure A copy top level structure.
|
||||
* set the field in pvMaster to the value of the corresponding field in copyPVStructure
|
||||
* @param copyPVStructure A copy top-level structure.
|
||||
* @param bitSet A bitSet for copyPVStructure.
|
||||
*/
|
||||
void updateMaster(
|
||||
@@ -156,7 +159,7 @@ public:
|
||||
BitSetPtr const &bitSet);
|
||||
/**
|
||||
* Get the options for the field at the specified offset.
|
||||
* @param offset the offset in copy.
|
||||
* @param fieldOffset the offset in copy.
|
||||
* @returns A NULL is returned if no options were specified for the field.
|
||||
* If options were specified,PVStructurePtr is a structures
|
||||
* with a set of PVString subfields that specify name,value pairs.s
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
#include <sstream>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/convert.h>
|
||||
#include <pv/pvData.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
// Introspection object comparision
|
||||
// Introspection object comparison
|
||||
|
||||
/** Field equality conditions:
|
||||
* 1) same instance
|
||||
@@ -62,7 +62,7 @@ bool operator==(const Field& a, const Field& b)
|
||||
return A==B;
|
||||
}
|
||||
default:
|
||||
throw std::logic_error("Invalid Field type in comparision");
|
||||
throw std::logic_error("Invalid Field type in comparison");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,14 +91,14 @@ bool operator==(const Structure& a, const Structure& b)
|
||||
return false;
|
||||
|
||||
// std::equals does not work, since FieldConstPtrArray is an array of shared_pointers
|
||||
FieldConstPtrArray af = a.getFields();
|
||||
FieldConstPtrArray bf = b.getFields();
|
||||
FieldConstPtrArray const & af = a.getFields();
|
||||
FieldConstPtrArray const & bf = b.getFields();
|
||||
for (size_t i = 0; i < nflds; i++)
|
||||
if (*(af[i].get()) != *(bf[i].get()))
|
||||
return false;
|
||||
|
||||
StringArray an = a.getFieldNames();
|
||||
StringArray bn = b.getFieldNames();
|
||||
StringArray const & an = a.getFieldNames();
|
||||
StringArray const & bn = b.getFieldNames();
|
||||
return std::equal( an.begin(), an.end(), bn.begin() );
|
||||
}
|
||||
|
||||
@@ -118,14 +118,14 @@ bool operator==(const Union& a, const Union& b)
|
||||
return false;
|
||||
|
||||
// std::equals does not work, since FieldConstPtrArray is an array of shared_pointers
|
||||
FieldConstPtrArray af = a.getFields();
|
||||
FieldConstPtrArray bf = b.getFields();
|
||||
FieldConstPtrArray const & af = a.getFields();
|
||||
FieldConstPtrArray const & bf = b.getFields();
|
||||
for (size_t i = 0; i < nflds; i++)
|
||||
if (*(af[i].get()) != *(bf[i].get()))
|
||||
return false;
|
||||
|
||||
StringArray an = a.getFieldNames();
|
||||
StringArray bn = b.getFieldNames();
|
||||
StringArray const & an = a.getFieldNames();
|
||||
StringArray const & bn = b.getFieldNames();
|
||||
return std::equal( an.begin(), an.end(), bn.begin() );
|
||||
}
|
||||
|
||||
|
||||
@@ -52,9 +52,6 @@ void Convert::getString(string *buf,PVField const *pvField,int /*indentLevel*/)
|
||||
std::ostringstream strm;
|
||||
pvField->dumpValue(strm);
|
||||
strm << std::endl;
|
||||
// PrinterPlain p;
|
||||
// p.setStream(strm);
|
||||
// p.print(*pvField);
|
||||
strm.str().swap(*buf);
|
||||
}
|
||||
|
||||
@@ -152,371 +149,6 @@ size_t Convert::toStringArray(PVScalarArrayPtr const & pv,
|
||||
return data.size();
|
||||
}
|
||||
|
||||
bool Convert::isCopyCompatible(FieldConstPtr const &from, FieldConstPtr const &to)
|
||||
{
|
||||
if(from->getType()!=to->getType()) return false;
|
||||
switch(from->getType()) {
|
||||
case scalar:
|
||||
{
|
||||
ScalarConstPtr xxx = static_pointer_cast<const Scalar>(from);
|
||||
ScalarConstPtr yyy = static_pointer_cast<const Scalar>(to);
|
||||
return isCopyScalarCompatible(xxx,yyy);
|
||||
}
|
||||
case scalarArray:
|
||||
{
|
||||
ScalarArrayConstPtr xxx = static_pointer_cast<const ScalarArray>(from);
|
||||
ScalarArrayConstPtr yyy = static_pointer_cast<const ScalarArray>(to);
|
||||
return isCopyScalarArrayCompatible(xxx,yyy);
|
||||
}
|
||||
case structure:
|
||||
{
|
||||
StructureConstPtr xxx = static_pointer_cast<const Structure>(from);
|
||||
StructureConstPtr yyy = static_pointer_cast<const Structure>(to);
|
||||
return isCopyStructureCompatible(xxx,yyy);
|
||||
}
|
||||
case structureArray:
|
||||
{
|
||||
StructureArrayConstPtr xxx = static_pointer_cast<const StructureArray>(from);
|
||||
StructureArrayConstPtr yyy = static_pointer_cast<const StructureArray>(to);
|
||||
return isCopyStructureArrayCompatible(xxx,yyy);
|
||||
}
|
||||
case union_:
|
||||
{
|
||||
UnionConstPtr xxx = static_pointer_cast<const Union>(from);
|
||||
UnionConstPtr yyy = static_pointer_cast<const Union>(to);
|
||||
return isCopyUnionCompatible(xxx,yyy);
|
||||
}
|
||||
case unionArray:
|
||||
{
|
||||
UnionArrayConstPtr xxx = static_pointer_cast<const UnionArray>(from);
|
||||
UnionArrayConstPtr yyy = static_pointer_cast<const UnionArray>(to);
|
||||
return isCopyUnionArrayCompatible(xxx,yyy);
|
||||
}
|
||||
}
|
||||
string message("Convert::isCopyCompatible should never get here");
|
||||
throw std::logic_error(message);
|
||||
}
|
||||
|
||||
void Convert::copy(PVFieldPtr const & from, PVFieldPtr const & to)
|
||||
{
|
||||
switch(from->getField()->getType()) {
|
||||
case scalar:
|
||||
{
|
||||
PVScalarPtr xxx = static_pointer_cast<PVScalar>(from);
|
||||
PVScalarPtr yyy = static_pointer_cast<PVScalar>(to);
|
||||
copyScalar(xxx,yyy);
|
||||
return;
|
||||
}
|
||||
case scalarArray:
|
||||
{
|
||||
PVScalarArrayPtr fromArray = static_pointer_cast<PVScalarArray>(from);
|
||||
PVScalarArrayPtr toArray = static_pointer_cast<PVScalarArray>(to);
|
||||
toArray->assign(*fromArray.get());
|
||||
return;
|
||||
}
|
||||
case structure:
|
||||
{
|
||||
PVStructurePtr xxx = static_pointer_cast<PVStructure>(from);
|
||||
PVStructurePtr yyy = static_pointer_cast<PVStructure>(to);
|
||||
copyStructure(xxx,yyy);
|
||||
return;
|
||||
}
|
||||
case structureArray: {
|
||||
PVStructureArrayPtr fromArray = static_pointer_cast<PVStructureArray>(from);
|
||||
PVStructureArrayPtr toArray = static_pointer_cast<PVStructureArray>(to);
|
||||
copyStructureArray(fromArray,toArray);
|
||||
return;
|
||||
}
|
||||
case union_:
|
||||
{
|
||||
PVUnionPtr xxx = static_pointer_cast<PVUnion>(from);
|
||||
PVUnionPtr yyy = static_pointer_cast<PVUnion>(to);
|
||||
copyUnion(xxx,yyy);
|
||||
return;
|
||||
}
|
||||
case unionArray: {
|
||||
PVUnionArrayPtr fromArray = static_pointer_cast<PVUnionArray>(from);
|
||||
PVUnionArrayPtr toArray = static_pointer_cast<PVUnionArray>(to);
|
||||
copyUnionArray(fromArray,toArray);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Convert::isCopyScalarCompatible(
|
||||
ScalarConstPtr const & fromField, ScalarConstPtr const & toField)
|
||||
{
|
||||
ScalarType fromScalarType = fromField->getScalarType();
|
||||
ScalarType toScalarType = toField->getScalarType();
|
||||
if(fromScalarType==toScalarType) return true;
|
||||
if(ScalarTypeFunc::isNumeric(fromScalarType)
|
||||
&& ScalarTypeFunc::isNumeric(toScalarType)) return true;
|
||||
if(fromScalarType==pvString) return true;
|
||||
if(toScalarType==pvString) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Convert::copyScalar(PVScalarPtr const & from, PVScalarPtr const & to)
|
||||
{
|
||||
if(to->isImmutable()) {
|
||||
if(from==to) return;
|
||||
string message("Convert.copyScalar destination is immutable");
|
||||
throw std::invalid_argument(message);
|
||||
}
|
||||
to->assign(*from.get());
|
||||
}
|
||||
|
||||
bool Convert::isCopyScalarArrayCompatible(ScalarArrayConstPtr const &fromArray,
|
||||
ScalarArrayConstPtr const &toArray)
|
||||
{
|
||||
ScalarType fromType = fromArray->getElementType();
|
||||
ScalarType toType = toArray->getElementType();
|
||||
if(fromType==toType) return true;
|
||||
if(ScalarTypeFunc::isNumeric(fromType)
|
||||
&& ScalarTypeFunc::isNumeric(toType)) return true;
|
||||
if(toType==pvString) return true;
|
||||
if(fromType==pvString) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Convert::isCopyStructureCompatible(
|
||||
StructureConstPtr const &fromStruct, StructureConstPtr const &toStruct)
|
||||
{
|
||||
FieldConstPtrArray fromFields = fromStruct->getFields();
|
||||
FieldConstPtrArray toFields = toStruct->getFields();
|
||||
size_t length = fromStruct->getNumberFields();
|
||||
if(length!=toStruct->getNumberFields()) return false;
|
||||
for(size_t i=0; i<length; i++) {
|
||||
FieldConstPtr from = fromFields[i];
|
||||
FieldConstPtr to = toFields[i];
|
||||
Type fromType = from->getType();
|
||||
Type toType = to->getType();
|
||||
if(fromType!=toType) return false;
|
||||
switch(fromType) {
|
||||
case scalar:
|
||||
{
|
||||
ScalarConstPtr xxx = static_pointer_cast<const Scalar>(from);
|
||||
ScalarConstPtr yyy = static_pointer_cast<const Scalar>(to);
|
||||
if(!isCopyScalarCompatible(xxx,yyy)) return false;
|
||||
}
|
||||
break;
|
||||
case scalarArray:
|
||||
{
|
||||
ScalarArrayConstPtr xxx = static_pointer_cast<const ScalarArray>(from);
|
||||
ScalarArrayConstPtr yyy = static_pointer_cast<const ScalarArray>(to);
|
||||
if(!isCopyScalarArrayCompatible(xxx,yyy)) return false;
|
||||
}
|
||||
break;
|
||||
case structure:
|
||||
{
|
||||
StructureConstPtr xxx = static_pointer_cast<const Structure>(from);
|
||||
StructureConstPtr yyy = static_pointer_cast<const Structure>(to);
|
||||
if(!isCopyStructureCompatible(xxx,yyy)) return false;
|
||||
}
|
||||
break;
|
||||
case structureArray:
|
||||
{
|
||||
StructureArrayConstPtr xxx = static_pointer_cast<const StructureArray>(from);
|
||||
StructureArrayConstPtr yyy = static_pointer_cast<const StructureArray>(to);
|
||||
if(!isCopyStructureArrayCompatible(xxx,yyy)) return false;
|
||||
}
|
||||
case union_:
|
||||
{
|
||||
UnionConstPtr xxx = static_pointer_cast<const Union>(from);
|
||||
UnionConstPtr yyy = static_pointer_cast<const Union>(to);
|
||||
if(!isCopyUnionCompatible(xxx,yyy)) return false;
|
||||
}
|
||||
break;
|
||||
case unionArray:
|
||||
{
|
||||
UnionArrayConstPtr xxx = static_pointer_cast<const UnionArray>(from);
|
||||
UnionArrayConstPtr yyy = static_pointer_cast<const UnionArray>(to);
|
||||
if(!isCopyUnionArrayCompatible(xxx,yyy)) return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Convert::copyStructure(PVStructurePtr const & from, PVStructurePtr const & to)
|
||||
{
|
||||
if(to->isImmutable()) {
|
||||
if(from==to) return;
|
||||
throw std::invalid_argument("Convert.copyStructure destination is immutable");
|
||||
}
|
||||
if(from==to) return;
|
||||
PVFieldPtrArray const & fromDatas = from->getPVFields();
|
||||
PVFieldPtrArray const & toDatas = to->getPVFields();
|
||||
if(from->getStructure()->getNumberFields()
|
||||
!= to->getStructure()->getNumberFields()) {
|
||||
string message("Convert.copyStructure Illegal copyStructure");
|
||||
throw std::invalid_argument(message);
|
||||
}
|
||||
size_t numberFields = from->getStructure()->getNumberFields();
|
||||
if(numberFields>=2) {
|
||||
string name0 = fromDatas[0]->getFieldName();
|
||||
string name1 = fromDatas[1]->getFieldName();
|
||||
// look for enumerated structure and copy choices first
|
||||
if(name0.compare("index")==0 && name1.compare("choices")==0) {
|
||||
FieldConstPtr fieldIndex = fromDatas[0]->getField();
|
||||
FieldConstPtr fieldChoices = fromDatas[1]->getField();
|
||||
if(fieldIndex->getType()==scalar
|
||||
&& fieldChoices->getType()==scalarArray) {
|
||||
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(fromDatas[0]);
|
||||
PVScalarArrayPtr pvArray =
|
||||
static_pointer_cast<PVScalarArray>(fromDatas[1]);
|
||||
if((pvScalar->getScalar()->getScalarType()==pvInt)
|
||||
&& (pvArray->getScalarArray()->getElementType()==pvString)) {
|
||||
PVScalarArrayPtr toArray =
|
||||
static_pointer_cast<PVScalarArray>(toDatas[1]);
|
||||
toArray->assign(*pvArray.get());
|
||||
PVScalarPtr toScalar = static_pointer_cast<PVScalar>(toDatas[0]);
|
||||
copyScalar(pvScalar,toScalar);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(size_t i=0; i < numberFields; i++) {
|
||||
PVFieldPtr fromData = fromDatas[i];
|
||||
PVFieldPtr toData = toDatas[i];
|
||||
Type fromType = fromData->getField()->getType();
|
||||
Type toType = toData->getField()->getType();
|
||||
if(fromType!=toType) {
|
||||
string message("Convert.copyStructure Illegal copyStructure");
|
||||
throw std::invalid_argument(message);
|
||||
}
|
||||
if(toData->isImmutable()) {
|
||||
if(fromData==toData) return;
|
||||
throw std::invalid_argument("Convert.copyStructure destination is immutable");
|
||||
}
|
||||
switch(fromType) {
|
||||
case scalar:
|
||||
{
|
||||
PVScalarPtr xxx = static_pointer_cast<PVScalar>(fromData);
|
||||
PVScalarPtr yyy = static_pointer_cast<PVScalar>(toData);
|
||||
copyScalar(xxx,yyy);
|
||||
break;
|
||||
}
|
||||
case scalarArray:
|
||||
{
|
||||
PVScalarArrayPtr fromArray = static_pointer_cast<PVScalarArray>(fromData);
|
||||
PVScalarArrayPtr toArray = static_pointer_cast<PVScalarArray>(toData);
|
||||
toArray->assign(*fromArray.get());
|
||||
break;
|
||||
}
|
||||
case structure:
|
||||
{
|
||||
PVStructurePtr xxx = static_pointer_cast<PVStructure>(fromData);
|
||||
PVStructurePtr yyy = static_pointer_cast<PVStructure>(toData);
|
||||
copyStructure(xxx,yyy);
|
||||
break;
|
||||
}
|
||||
case structureArray:
|
||||
{
|
||||
PVStructureArrayPtr fromArray =
|
||||
static_pointer_cast<PVStructureArray>(fromData);
|
||||
PVStructureArrayPtr toArray =
|
||||
static_pointer_cast<PVStructureArray>(toData);
|
||||
copyStructureArray(fromArray,toArray);
|
||||
break;
|
||||
}
|
||||
case union_:
|
||||
{
|
||||
PVUnionPtr xxx = static_pointer_cast<PVUnion>(fromData);
|
||||
PVUnionPtr yyy = static_pointer_cast<PVUnion>(toData);
|
||||
copyUnion(xxx,yyy);
|
||||
break;
|
||||
}
|
||||
case unionArray:
|
||||
{
|
||||
PVUnionArrayPtr fromArray =
|
||||
static_pointer_cast<PVUnionArray>(fromData);
|
||||
PVUnionArrayPtr toArray =
|
||||
static_pointer_cast<PVUnionArray>(toData);
|
||||
copyUnionArray(fromArray,toArray);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Convert::isCopyUnionCompatible(
|
||||
UnionConstPtr const &from, UnionConstPtr const &to)
|
||||
{
|
||||
return *(from.get()) == *(to.get());
|
||||
}
|
||||
|
||||
void Convert::copyUnion(PVUnionPtr const & from, PVUnionPtr const & to)
|
||||
{
|
||||
if(to->isImmutable()) {
|
||||
if(from==to) return;
|
||||
throw std::invalid_argument("Convert.copyUnion destination is immutable");
|
||||
}
|
||||
if(from==to) return;
|
||||
if(!isCopyUnionCompatible(from->getUnion(), to->getUnion())) {
|
||||
throw std::invalid_argument("Illegal copyUnion");
|
||||
}
|
||||
|
||||
PVFieldPtr fromValue = from->get();
|
||||
if (from->getUnion()->isVariant())
|
||||
{
|
||||
to->set(from->get());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fromValue.get() == 0)
|
||||
to->select(PVUnion::UNDEFINED_INDEX);
|
||||
else
|
||||
to->set(from->getSelectedIndex(),from->get());
|
||||
}
|
||||
}
|
||||
|
||||
bool Convert::isCopyStructureArrayCompatible(
|
||||
StructureArrayConstPtr const &from, StructureArrayConstPtr const &to)
|
||||
{
|
||||
StructureConstPtr xxx = from->getStructure();
|
||||
StructureConstPtr yyy = to->getStructure();
|
||||
return isCopyStructureCompatible(xxx,yyy);
|
||||
}
|
||||
|
||||
void Convert::copyStructureArray(
|
||||
PVStructureArrayPtr const & from, PVStructureArrayPtr const & to)
|
||||
{
|
||||
if(from==to) {
|
||||
return;
|
||||
} else if(to->isImmutable()) {
|
||||
throw std::invalid_argument("Convert.copyStructureArray destination is immutable");
|
||||
}
|
||||
to->replace(from->view());
|
||||
}
|
||||
|
||||
bool Convert::isCopyUnionArrayCompatible(
|
||||
UnionArrayConstPtr const &from, UnionArrayConstPtr const &to)
|
||||
{
|
||||
UnionConstPtr xxx = from->getUnion();
|
||||
UnionConstPtr yyy = to->getUnion();
|
||||
return isCopyUnionCompatible(xxx,yyy);
|
||||
}
|
||||
|
||||
void Convert::copyUnionArray(
|
||||
PVUnionArrayPtr const & from, PVUnionArrayPtr const & to)
|
||||
{
|
||||
if(from==to) {
|
||||
return;
|
||||
} else if(to->isImmutable()) {
|
||||
throw std::invalid_argument("Convert.copyUnionArray destination is immutable");
|
||||
}
|
||||
to->replace(from->view());
|
||||
}
|
||||
|
||||
void Convert::newLine(string *buffer, int indentLevel)
|
||||
{
|
||||
*buffer += "\n";
|
||||
*buffer += string(indentLevel*4, ' ');
|
||||
}
|
||||
|
||||
ConvertPtr Convert::getConvert()
|
||||
{
|
||||
static ConvertPtr convert;
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
@@ -52,7 +51,7 @@ Scalar::Scalar(ScalarType scalarType)
|
||||
: Field(scalar),scalarType(scalarType)
|
||||
{
|
||||
if(scalarType<0 || scalarType>MAX_SCALAR_TYPE)
|
||||
throw std::invalid_argument("Can't construct Scalar from invalid ScalarType");
|
||||
THROW_EXCEPTION2(std::invalid_argument, "Can't construct Scalar from invalid ScalarType");
|
||||
}
|
||||
|
||||
Scalar::~Scalar(){}
|
||||
@@ -137,7 +136,7 @@ BoundedString::BoundedString(std::size_t maxStringLength) :
|
||||
Scalar(pvString), maxLength(maxStringLength)
|
||||
{
|
||||
if (maxLength == 0)
|
||||
throw std::invalid_argument("maxLength == 0");
|
||||
THROW_EXCEPTION2(std::invalid_argument, "maxLength == 0");
|
||||
}
|
||||
|
||||
BoundedString::~BoundedString() {}
|
||||
@@ -400,7 +399,13 @@ void UnionArray::deserialize(ByteBuffer* /*buffer*/, DeserializableControl* /*co
|
||||
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
|
||||
}
|
||||
|
||||
string Structure::DEFAULT_ID = "structure";
|
||||
const string Structure::DEFAULT_ID = Structure::defaultId();
|
||||
|
||||
const string & Structure::defaultId()
|
||||
{
|
||||
static const string id = "structure";
|
||||
return id;
|
||||
}
|
||||
|
||||
Structure::Structure (
|
||||
StringArray const & fieldNames,
|
||||
@@ -412,27 +417,27 @@ Structure::Structure (
|
||||
id(inid)
|
||||
{
|
||||
if(inid.empty()) {
|
||||
throw std::invalid_argument("id is empty");
|
||||
THROW_EXCEPTION2(std::invalid_argument, "Can't construct Structure, id is empty string");
|
||||
}
|
||||
if(fieldNames.size()!=fields.size()) {
|
||||
throw std::invalid_argument("fieldNames.size()!=fields.size()");
|
||||
THROW_EXCEPTION2(std::invalid_argument, "Can't construct Structure, fieldNames.size()!=fields.size()");
|
||||
}
|
||||
size_t number = fields.size();
|
||||
for(size_t i=0; i<number; i++) {
|
||||
const string& name = fieldNames[i];
|
||||
if(name.empty()) {
|
||||
throw std::invalid_argument("fieldNames has a zero length string");
|
||||
THROW_EXCEPTION2(std::invalid_argument, "Can't construct Structure, empty string in fieldNames");
|
||||
}
|
||||
if(fields[i].get()==NULL)
|
||||
throw std::invalid_argument("Can't construct Structure with NULL Field");
|
||||
THROW_EXCEPTION2(std::invalid_argument, "Can't construct Structure, NULL in fields");
|
||||
// look for duplicates
|
||||
for(size_t j=i+1; j<number; j++) {
|
||||
string otherName = fieldNames[j];
|
||||
int result = name.compare(otherName);
|
||||
if(result==0) {
|
||||
string message("duplicate fieldName ");
|
||||
string message("Can't construct Structure, duplicate fieldName ");
|
||||
message += name;
|
||||
throw std::invalid_argument(message);
|
||||
THROW_EXCEPTION2(std::invalid_argument, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -497,7 +502,9 @@ void Structure::dumpFields(std::ostream& o) const
|
||||
case structureArray:
|
||||
{
|
||||
format::indent_scope s(o);
|
||||
o << *pfield;
|
||||
Field const *xxx = pfield.get();
|
||||
StructureArray const *pstructureArray = static_cast<StructureArray const*>(xxx);
|
||||
o << *pstructureArray->getStructure();
|
||||
break;
|
||||
}
|
||||
case union_:
|
||||
@@ -511,7 +518,9 @@ void Structure::dumpFields(std::ostream& o) const
|
||||
case unionArray:
|
||||
{
|
||||
format::indent_scope s(o);
|
||||
o << *pfield;
|
||||
Field const *xxx = pfield.get();
|
||||
UnionArray const *punionArray = static_cast<UnionArray const*>(xxx);
|
||||
o << *punionArray->getUnion();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -528,20 +537,30 @@ void Structure::deserialize(ByteBuffer* /*buffer*/, DeserializableControl* /*con
|
||||
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
|
||||
}
|
||||
|
||||
string Union::DEFAULT_ID = "union";
|
||||
const string Union::DEFAULT_ID = Union::defaultId();
|
||||
|
||||
#define UNION_ANY_ID "any"
|
||||
string Union::ANY_ID = UNION_ANY_ID;
|
||||
const string & Union::defaultId()
|
||||
{
|
||||
static const string id = "union";
|
||||
return id;
|
||||
}
|
||||
|
||||
const string Union::ANY_ID = Union::anyId();
|
||||
|
||||
const string & Union::anyId()
|
||||
{
|
||||
static const string id = "any";
|
||||
return id;
|
||||
}
|
||||
|
||||
Union::Union ()
|
||||
: Field(union_),
|
||||
fieldNames(),
|
||||
fields(),
|
||||
id(UNION_ANY_ID)
|
||||
id(anyId())
|
||||
{
|
||||
}
|
||||
|
||||
#undef UNION_ANY_ID
|
||||
|
||||
Union::Union (
|
||||
StringArray const & fieldNames,
|
||||
@@ -553,31 +572,31 @@ Union::Union (
|
||||
id(inid)
|
||||
{
|
||||
if(inid.empty()) {
|
||||
throw std::invalid_argument("id is empty");
|
||||
THROW_EXCEPTION2(std::invalid_argument, "Can't construct Union, id is empty string");
|
||||
}
|
||||
if(fieldNames.size()!=fields.size()) {
|
||||
throw std::invalid_argument("fieldNames.size()!=fields.size()");
|
||||
THROW_EXCEPTION2(std::invalid_argument, "Can't construct Union, fieldNames.size()!=fields.size()");
|
||||
}
|
||||
if(fields.size()==0 && inid!=ANY_ID) {
|
||||
throw std::invalid_argument("no fields but id is different than " + ANY_ID);
|
||||
THROW_EXCEPTION2(std::invalid_argument, "Can't construct Union, no fields only allowed when id = " + ANY_ID);
|
||||
}
|
||||
|
||||
size_t number = fields.size();
|
||||
for(size_t i=0; i<number; i++) {
|
||||
const string& name = fieldNames[i];
|
||||
if(name.empty()) {
|
||||
throw std::invalid_argument("fieldNames has a zero length string");
|
||||
THROW_EXCEPTION2(std::invalid_argument, "Can't construct Union, empty string in fieldNames");
|
||||
}
|
||||
if(fields[i].get()==NULL)
|
||||
throw std::invalid_argument("Can't construct Union with NULL Field");
|
||||
THROW_EXCEPTION2(std::invalid_argument, "Can't construct Union, NULL in fields");
|
||||
// look for duplicates
|
||||
for(size_t j=i+1; j<number; j++) {
|
||||
string otherName = fieldNames[j];
|
||||
int result = name.compare(otherName);
|
||||
if(result==0) {
|
||||
string message("duplicate fieldName ");
|
||||
string message("Can't construct Union, duplicate fieldName ");
|
||||
message += name;
|
||||
throw std::invalid_argument(message);
|
||||
THROW_EXCEPTION2(std::invalid_argument, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -759,7 +778,7 @@ FieldBuilderPtr FieldBuilder::addArray(string const & name, FieldConstPtr const
|
||||
case scalar:
|
||||
|
||||
if (std::tr1::dynamic_pointer_cast<const BoundedString>(element).get())
|
||||
throw std::invalid_argument("bounded string arrays are not supported");
|
||||
THROW_EXCEPTION2(std::invalid_argument, "bounded string arrays are not supported");
|
||||
|
||||
fields.push_back(fieldCreate->createScalarArray(static_pointer_cast<const Scalar>(element)->getScalarType()));
|
||||
break;
|
||||
@@ -767,7 +786,7 @@ FieldBuilderPtr FieldBuilder::addArray(string const & name, FieldConstPtr const
|
||||
default:
|
||||
std::ostringstream msg("unsupported array element type: ");
|
||||
msg << element->getType();
|
||||
throw std::invalid_argument(msg.str());
|
||||
THROW_EXCEPTION2(std::invalid_argument, msg.str());
|
||||
}
|
||||
|
||||
fieldNames.push_back(name);
|
||||
@@ -796,7 +815,7 @@ FieldConstPtr FieldBuilder::createFieldInternal(Type type)
|
||||
{
|
||||
std::ostringstream msg("unsupported type: ");
|
||||
msg << type;
|
||||
throw std::invalid_argument(msg.str());
|
||||
THROW_EXCEPTION2(std::invalid_argument, msg.str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -804,7 +823,7 @@ FieldConstPtr FieldBuilder::createFieldInternal(Type type)
|
||||
StructureConstPtr FieldBuilder::createStructure()
|
||||
{
|
||||
if (parentBuilder.get())
|
||||
throw std::runtime_error("createStructure() called in nested FieldBuilder");
|
||||
THROW_EXCEPTION2(std::runtime_error, "createStructure() called in nested FieldBuilder");
|
||||
|
||||
StructureConstPtr field(static_pointer_cast<const Structure>(createFieldInternal(structure)));
|
||||
reset();
|
||||
@@ -814,7 +833,7 @@ StructureConstPtr FieldBuilder::createStructure()
|
||||
UnionConstPtr FieldBuilder::createUnion()
|
||||
{
|
||||
if (parentBuilder.get())
|
||||
throw std::runtime_error("createUnion() called in nested FieldBuilder");
|
||||
THROW_EXCEPTION2(std::runtime_error, "createUnion() called in nested FieldBuilder");
|
||||
|
||||
UnionConstPtr field(static_pointer_cast<const Union>(createFieldInternal(union_)));
|
||||
reset();
|
||||
@@ -846,7 +865,7 @@ FieldBuilderPtr FieldBuilder::addNestedUnionArray(string const & name)
|
||||
FieldBuilderPtr FieldBuilder::endNested()
|
||||
{
|
||||
if (!parentBuilder.get())
|
||||
throw std::runtime_error("this method can only be called to create nested fields");
|
||||
THROW_EXCEPTION2(std::runtime_error, "this method can only be called to create nested fields");
|
||||
|
||||
FieldConstPtr nestedField = createFieldInternal(nestedClassToBuild);
|
||||
if (nestedArray)
|
||||
@@ -865,8 +884,11 @@ FieldBuilderPtr FieldCreate::createFieldBuilder() const
|
||||
|
||||
ScalarConstPtr FieldCreate::createScalar(ScalarType scalarType) const
|
||||
{
|
||||
if(scalarType<0 || scalarType>MAX_SCALAR_TYPE)
|
||||
throw std::invalid_argument("Can't construct Scalar from invalid ScalarType");
|
||||
if(scalarType<0 || scalarType>MAX_SCALAR_TYPE) {
|
||||
std::ostringstream strm("Can't construct Scalar from invalid ScalarType ");
|
||||
strm << scalarType;
|
||||
THROW_EXCEPTION2(std::invalid_argument, strm.str());
|
||||
}
|
||||
|
||||
return scalars[scalarType];
|
||||
}
|
||||
@@ -881,16 +903,22 @@ BoundedStringConstPtr FieldCreate::createBoundedString(std::size_t maxLength) co
|
||||
|
||||
ScalarArrayConstPtr FieldCreate::createScalarArray(ScalarType elementType) const
|
||||
{
|
||||
if(elementType<0 || elementType>MAX_SCALAR_TYPE)
|
||||
throw std::invalid_argument("Can't construct ScalarArray from invalid ScalarType");
|
||||
if(elementType<0 || elementType>MAX_SCALAR_TYPE) {
|
||||
std::ostringstream strm("Can't construct ScalarArray from invalid ScalarType ");
|
||||
strm << elementType;
|
||||
THROW_EXCEPTION2(std::invalid_argument, strm.str());
|
||||
}
|
||||
|
||||
return scalarArrays[elementType];
|
||||
}
|
||||
|
||||
ScalarArrayConstPtr FieldCreate::createFixedScalarArray(ScalarType elementType, size_t size) const
|
||||
{
|
||||
if(elementType<0 || elementType>MAX_SCALAR_TYPE)
|
||||
throw std::invalid_argument("Can't construct ScalarArray from invalid ScalarType");
|
||||
if(elementType<0 || elementType>MAX_SCALAR_TYPE) {
|
||||
std::ostringstream strm("Can't construct fixed ScalarArray from invalid ScalarType ");
|
||||
strm << elementType;
|
||||
THROW_EXCEPTION2(std::invalid_argument, strm.str());
|
||||
}
|
||||
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<ScalarArray> s(new FixedScalarArray(elementType, size), Field::Deleter());
|
||||
@@ -900,8 +928,11 @@ ScalarArrayConstPtr FieldCreate::createFixedScalarArray(ScalarType elementType,
|
||||
|
||||
ScalarArrayConstPtr FieldCreate::createBoundedScalarArray(ScalarType elementType, size_t size) const
|
||||
{
|
||||
if(elementType<0 || elementType>MAX_SCALAR_TYPE)
|
||||
throw std::invalid_argument("Can't construct ScalarArray from invalid ScalarType");
|
||||
if(elementType<0 || elementType>MAX_SCALAR_TYPE) {
|
||||
std::ostringstream strm("Can't construct bounded ScalarArray from invalid ScalarType ");
|
||||
strm << elementType;
|
||||
THROW_EXCEPTION2(std::invalid_argument, strm.str());
|
||||
}
|
||||
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<ScalarArray> s(new BoundedScalarArray(elementType, size), Field::Deleter());
|
||||
@@ -989,8 +1020,8 @@ StructureConstPtr FieldCreate::appendField(
|
||||
string const & fieldName,
|
||||
FieldConstPtr const & field) const
|
||||
{
|
||||
StringArray oldNames = structure->getFieldNames();
|
||||
FieldConstPtrArray oldFields = structure->getFields();
|
||||
StringArray const & oldNames = structure->getFieldNames();
|
||||
FieldConstPtrArray const & oldFields = structure->getFields();
|
||||
size_t oldLen = oldNames.size();
|
||||
StringArray newNames(oldLen+1);
|
||||
FieldConstPtrArray newFields(oldLen+1);
|
||||
@@ -1008,8 +1039,8 @@ StructureConstPtr FieldCreate::appendFields(
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const
|
||||
{
|
||||
StringArray oldNames = structure->getFieldNames();
|
||||
FieldConstPtrArray oldFields = structure->getFields();
|
||||
StringArray const & oldNames = structure->getFieldNames();
|
||||
FieldConstPtrArray const & oldFields = structure->getFields();
|
||||
size_t oldLen = oldNames.size();
|
||||
size_t extra = fieldNames.size();
|
||||
StringArray newNames(oldLen+extra);
|
||||
@@ -1230,3 +1261,12 @@ FieldCreatePtr getFieldCreate() {
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
namespace std{
|
||||
std::ostream& operator<<(std::ostream& o, const epics::pvData::Field *ptr)
|
||||
{
|
||||
if(ptr) return o << *ptr;
|
||||
return o << "nullptr";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
@@ -527,7 +526,7 @@ PVFieldPtr PVDataCreate::createPVField(PVFieldPtr const & fieldToClone)
|
||||
PVStructurePtr pvStructure
|
||||
= static_pointer_cast<PVStructure>(fieldToClone);
|
||||
StringArray const & fieldNames = pvStructure->getStructure()->getFieldNames();
|
||||
PVFieldPtrArray pvFieldPtrArray = pvStructure->getPVFields();
|
||||
PVFieldPtrArray const & pvFieldPtrArray = pvStructure->getPVFields();
|
||||
return createPVStructure(fieldNames,pvFieldPtrArray);
|
||||
}
|
||||
case structureArray:
|
||||
@@ -537,7 +536,7 @@ PVFieldPtr PVDataCreate::createPVField(PVFieldPtr const & fieldToClone)
|
||||
StructureArrayConstPtr structureArray = from->getStructureArray();
|
||||
PVStructureArrayPtr to = createPVStructureArray(
|
||||
structureArray);
|
||||
getConvert()->copyStructureArray(from, to);
|
||||
to->copyUnchecked(*from);
|
||||
return to;
|
||||
}
|
||||
case union_:
|
||||
@@ -552,7 +551,7 @@ PVFieldPtr PVDataCreate::createPVField(PVFieldPtr const & fieldToClone)
|
||||
= static_pointer_cast<PVUnionArray>(fieldToClone);
|
||||
UnionArrayConstPtr unionArray = from->getUnionArray();
|
||||
PVUnionArrayPtr to = createPVUnionArray(unionArray);
|
||||
getConvert()->copyUnionArray(from, to);
|
||||
to->copyUnchecked(*from);
|
||||
return to;
|
||||
}
|
||||
}
|
||||
@@ -602,7 +601,7 @@ PVScalarPtr PVDataCreate::createPVScalar(PVScalarPtr const & scalarToClone)
|
||||
{
|
||||
ScalarType scalarType = scalarToClone->getScalar()->getScalarType();
|
||||
PVScalarPtr pvScalar = createPVScalar(scalarType);
|
||||
getConvert()->copyScalar(scalarToClone, pvScalar);
|
||||
pvScalar->copyUnchecked(*scalarToClone);
|
||||
return pvScalar;
|
||||
}
|
||||
|
||||
@@ -712,7 +711,7 @@ PVStructurePtr PVDataCreate::createPVStructure(PVStructurePtr const & structToCl
|
||||
}
|
||||
StructureConstPtr structure = structToClone->getStructure();
|
||||
PVStructurePtr pvStructure(new PVStructure(structure));
|
||||
getConvert()->copyStructure(structToClone,pvStructure);
|
||||
pvStructure->copyUnchecked(*structToClone);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
@@ -741,3 +740,12 @@ PVDataCreatePtr getPVDataCreate() {
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
namespace std{
|
||||
std::ostream& operator<<(std::ostream& o, const epics::pvData::PVField *ptr)
|
||||
{
|
||||
if(ptr) return o << *ptr;
|
||||
return o << "nullptr";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/convert.h>
|
||||
|
||||
using std::tr1::const_pointer_cast;
|
||||
using std::size_t;
|
||||
@@ -121,7 +120,7 @@ void PVField::computeOffset(const PVField * pvField) {
|
||||
}
|
||||
size_t offset = 0;
|
||||
size_t nextOffset = 1;
|
||||
PVFieldPtrArray pvFields = pvTop->getPVFields();
|
||||
const PVFieldPtrArray & pvFields = pvTop->getPVFields();
|
||||
for(size_t i=0; i < pvTop->getStructure()->getNumberFields(); i++) {
|
||||
offset = nextOffset;
|
||||
PVField *pvField = pvFields[i].get();
|
||||
@@ -153,7 +152,7 @@ void PVField::computeOffset(const PVField * pvField,size_t offset) {
|
||||
size_t beginOffset = offset;
|
||||
size_t nextOffset = offset + 1;
|
||||
const PVStructure *pvStructure = static_cast<const PVStructure *>(pvField);
|
||||
const PVFieldPtrArray pvFields = pvStructure->getPVFields();
|
||||
const PVFieldPtrArray & pvFields = pvStructure->getPVFields();
|
||||
for(size_t i=0; i < pvStructure->getStructure()->getNumberFields(); i++) {
|
||||
offset = nextOffset;
|
||||
PVField *pvSubField = pvFields[i].get();
|
||||
@@ -180,4 +179,117 @@ void PVField::computeOffset(const PVField * pvField,size_t offset) {
|
||||
xxx->nextFieldOffset = nextOffset;
|
||||
}
|
||||
|
||||
void PVField::copy(const PVField& from)
|
||||
{
|
||||
if(isImmutable())
|
||||
throw std::invalid_argument("destination is immutable");
|
||||
|
||||
if (getField()->getType() != from.getField()->getType())
|
||||
throw std::invalid_argument("field types do not match");
|
||||
|
||||
switch(getField()->getType())
|
||||
{
|
||||
case scalar:
|
||||
{
|
||||
const PVScalar* fromS = static_cast<const PVScalar*>(&from);
|
||||
PVScalar* toS = static_cast<PVScalar*>(this);
|
||||
toS->copy(*fromS);
|
||||
break;
|
||||
}
|
||||
case scalarArray:
|
||||
{
|
||||
const PVScalarArray* fromS = static_cast<const PVScalarArray*>(&from);
|
||||
PVScalarArray* toS = static_cast<PVScalarArray*>(this);
|
||||
toS->copy(*fromS);
|
||||
break;
|
||||
}
|
||||
case structure:
|
||||
{
|
||||
const PVStructure* fromS = static_cast<const PVStructure*>(&from);
|
||||
PVStructure* toS = static_cast<PVStructure*>(this);
|
||||
toS->copy(*fromS);
|
||||
break;
|
||||
}
|
||||
case structureArray:
|
||||
{
|
||||
const PVStructureArray* fromS = static_cast<const PVStructureArray*>(&from);
|
||||
PVStructureArray* toS = static_cast<PVStructureArray*>(this);
|
||||
toS->copy(*fromS);
|
||||
break;
|
||||
}
|
||||
case union_:
|
||||
{
|
||||
const PVUnion* fromS = static_cast<const PVUnion*>(&from);
|
||||
PVUnion* toS = static_cast<PVUnion*>(this);
|
||||
toS->copy(*fromS);
|
||||
break;
|
||||
}
|
||||
case unionArray:
|
||||
{
|
||||
const PVUnionArray* fromS = static_cast<const PVUnionArray*>(&from);
|
||||
PVUnionArray* toS = static_cast<PVUnionArray*>(this);
|
||||
toS->copy(*fromS);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw std::logic_error("PVField::copy unknown type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PVField::copyUnchecked(const PVField& from)
|
||||
{
|
||||
switch(getField()->getType())
|
||||
{
|
||||
case scalar:
|
||||
{
|
||||
const PVScalar* fromS = static_cast<const PVScalar*>(&from);
|
||||
PVScalar* toS = static_cast<PVScalar*>(this);
|
||||
toS->copyUnchecked(*fromS);
|
||||
break;
|
||||
}
|
||||
case scalarArray:
|
||||
{
|
||||
const PVScalarArray* fromS = static_cast<const PVScalarArray*>(&from);
|
||||
PVScalarArray* toS = static_cast<PVScalarArray*>(this);
|
||||
toS->copyUnchecked(*fromS);
|
||||
break;
|
||||
}
|
||||
case structure:
|
||||
{
|
||||
const PVStructure* fromS = static_cast<const PVStructure*>(&from);
|
||||
PVStructure* toS = static_cast<PVStructure*>(this);
|
||||
toS->copyUnchecked(*fromS);
|
||||
break;
|
||||
}
|
||||
case structureArray:
|
||||
{
|
||||
const PVStructureArray* fromS = static_cast<const PVStructureArray*>(&from);
|
||||
PVStructureArray* toS = static_cast<PVStructureArray*>(this);
|
||||
toS->copyUnchecked(*fromS);
|
||||
break;
|
||||
}
|
||||
case union_:
|
||||
{
|
||||
const PVUnion* fromS = static_cast<const PVUnion*>(&from);
|
||||
PVUnion* toS = static_cast<PVUnion*>(this);
|
||||
toS->copyUnchecked(*fromS);
|
||||
break;
|
||||
}
|
||||
case unionArray:
|
||||
{
|
||||
const PVUnionArray* fromS = static_cast<const PVUnionArray*>(&from);
|
||||
PVUnionArray* toS = static_cast<PVUnionArray*>(this);
|
||||
toS->copyUnchecked(*fromS);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw std::logic_error("PVField::copy unknown type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/bitSet.h>
|
||||
|
||||
@@ -45,18 +44,14 @@ PVUnionPtr PVStructure::nullPVUnion;
|
||||
PVUnionArrayPtr PVStructure::nullPVUnionArray;
|
||||
PVScalarArrayPtr PVStructure::nullPVScalarArray;
|
||||
|
||||
static PVFieldPtr findSubField(
|
||||
string const &fieldName,
|
||||
const PVStructure *pvStructure);
|
||||
|
||||
PVStructure::PVStructure(StructureConstPtr const & structurePtr)
|
||||
: PVField(structurePtr),
|
||||
structurePtr(structurePtr),
|
||||
extendsStructureName("")
|
||||
{
|
||||
size_t numberFields = structurePtr->getNumberFields();
|
||||
FieldConstPtrArray fields = structurePtr->getFields();
|
||||
StringArray fieldNames = structurePtr->getFieldNames();
|
||||
FieldConstPtrArray const & fields = structurePtr->getFields();
|
||||
StringArray const & fieldNames = structurePtr->getFieldNames();
|
||||
// PVFieldPtrArray * xxx = const_cast<PVFieldPtrArray *>(&pvFields);
|
||||
pvFields.reserve(numberFields);
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
@@ -76,7 +71,7 @@ PVStructure::PVStructure(StructureConstPtr const & structurePtr,
|
||||
extendsStructureName("")
|
||||
{
|
||||
size_t numberFields = structurePtr->getNumberFields();
|
||||
StringArray fieldNames = structurePtr->getFieldNames();
|
||||
StringArray const & fieldNames = structurePtr->getFieldNames();
|
||||
pvFields.reserve(numberFields);
|
||||
for(size_t i=0; i<numberFields; i++) {
|
||||
pvFields.push_back(pvs[i]);
|
||||
@@ -112,7 +107,11 @@ const PVFieldPtrArray & PVStructure::getPVFields() const
|
||||
|
||||
PVFieldPtr PVStructure::getSubField(string const &fieldName) const
|
||||
{
|
||||
return findSubField(fieldName,this);
|
||||
PVField * field = getSubFieldImpl(fieldName.c_str(), false);
|
||||
if (field)
|
||||
return field->shared_from_this();
|
||||
else
|
||||
return PVFieldPtr();
|
||||
}
|
||||
|
||||
|
||||
@@ -135,107 +134,111 @@ PVFieldPtr PVStructure::getSubField(size_t fieldOffset) const
|
||||
throw std::logic_error("PVStructure.getSubField: Logic error");
|
||||
}
|
||||
|
||||
|
||||
PVBooleanPtr PVStructure::getBooleanField(string const &fieldName)
|
||||
PVFieldPtr PVStructure::getSubFieldT(std::size_t fieldOffset) const
|
||||
{
|
||||
return getSubField<PVBoolean>(fieldName);
|
||||
}
|
||||
|
||||
PVBytePtr PVStructure::getByteField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVByte>(fieldName);
|
||||
}
|
||||
|
||||
PVShortPtr PVStructure::getShortField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVShort>(fieldName);
|
||||
}
|
||||
|
||||
PVIntPtr PVStructure::getIntField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVInt>(fieldName);
|
||||
}
|
||||
|
||||
PVLongPtr PVStructure::getLongField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVLong>(fieldName);
|
||||
}
|
||||
|
||||
PVUBytePtr PVStructure::getUByteField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVUByte>(fieldName);
|
||||
}
|
||||
|
||||
PVUShortPtr PVStructure::getUShortField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVUShort>(fieldName);
|
||||
}
|
||||
|
||||
PVUIntPtr PVStructure::getUIntField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVUInt>(fieldName);
|
||||
}
|
||||
|
||||
PVULongPtr PVStructure::getULongField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVULong>(fieldName);
|
||||
}
|
||||
|
||||
PVFloatPtr PVStructure::getFloatField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVFloat>(fieldName);
|
||||
}
|
||||
|
||||
PVDoublePtr PVStructure::getDoubleField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVDouble>(fieldName);
|
||||
}
|
||||
|
||||
PVStringPtr PVStructure::getStringField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVString>(fieldName);
|
||||
}
|
||||
|
||||
PVStructurePtr PVStructure::getStructureField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVStructure>(fieldName);
|
||||
}
|
||||
|
||||
PVUnionPtr PVStructure::getUnionField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVUnion>(fieldName);
|
||||
}
|
||||
|
||||
PVScalarArrayPtr PVStructure::getScalarArrayField(
|
||||
string const &fieldName,ScalarType elementType)
|
||||
{
|
||||
PVFieldPtr pvField = findSubField(fieldName,this);
|
||||
if(pvField.get()==NULL) {
|
||||
return nullPVScalarArray;
|
||||
PVFieldPtr pvField = getSubField(fieldOffset);
|
||||
if (pvField.get())
|
||||
return pvField;
|
||||
else
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field with offset "
|
||||
<< fieldOffset << "(Invalid offset)" ;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
FieldConstPtr field = pvField->getField();
|
||||
Type type = field->getType();
|
||||
if(type!=scalarArray) {
|
||||
return nullPVScalarArray;
|
||||
}
|
||||
ScalarArrayConstPtr pscalarArray
|
||||
= static_pointer_cast<const ScalarArray>(pvField->getField());
|
||||
if(pscalarArray->getElementType()!=elementType) {
|
||||
return nullPVScalarArray;
|
||||
}
|
||||
return std::tr1::static_pointer_cast<PVScalarArray>(pvField);
|
||||
}
|
||||
|
||||
PVStructureArrayPtr PVStructure::getStructureArrayField(
|
||||
string const &fieldName)
|
||||
PVField* PVStructure::getSubFieldImpl(const char *name, bool throws) const
|
||||
{
|
||||
return getSubField<PVStructureArray>(fieldName);
|
||||
}
|
||||
const PVStructure *parent = this;
|
||||
if(!name)
|
||||
{
|
||||
if (throws)
|
||||
throw std::invalid_argument("Failed to get field: (Field name is NULL string)");
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
const char *fullName = name;
|
||||
while(true) {
|
||||
const char *sep=name;
|
||||
while(*sep!='\0' && *sep!='.' && *sep!=' ') sep++;
|
||||
if(*sep==' ')
|
||||
{
|
||||
if (throws)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field: " << fullName
|
||||
<< " (No spaces allowed in field name)";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
size_t N = sep-name;
|
||||
if(N==0)
|
||||
{
|
||||
if (throws)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field: " << fullName
|
||||
<< " (Zero-length field name encountered)";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PVUnionArrayPtr PVStructure::getUnionArrayField(
|
||||
string const &fieldName)
|
||||
{
|
||||
return getSubField<PVUnionArray>(fieldName);
|
||||
const PVFieldPtrArray& pvFields = parent->getPVFields();
|
||||
|
||||
PVField *child = NULL;
|
||||
|
||||
for(size_t i=0, n=pvFields.size(); i!=n; i++) {
|
||||
const PVFieldPtr& fld = pvFields[i];
|
||||
const std::string& fname = fld->getFieldName();
|
||||
|
||||
if(fname.size()==N && memcmp(name, fname.c_str(), N)==0) {
|
||||
child = fld.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!child)
|
||||
{
|
||||
if (throws)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field: " << fullName << " ("
|
||||
<< std::string(fullName, sep) << " not found)";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(*sep) {
|
||||
// this is not the requested leaf
|
||||
parent = dynamic_cast<PVStructure*>(child);
|
||||
if(!parent)
|
||||
{
|
||||
if (throws)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field: " << fullName
|
||||
<< " (" << std::string(fullName, sep)
|
||||
<< " is not a structure)";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
child = NULL;
|
||||
name = sep+1; // skip past '.'
|
||||
// loop around to new parent
|
||||
|
||||
} else {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -328,37 +331,6 @@ void PVStructure::deserialize(ByteBuffer *pbuffer,
|
||||
}
|
||||
}
|
||||
|
||||
static PVFieldPtr findSubField(
|
||||
string const & fieldName,
|
||||
PVStructure const *pvStructure)
|
||||
{
|
||||
if( fieldName.length()<1) return PVFieldPtr();
|
||||
string::size_type index = fieldName.find('.');
|
||||
string name = fieldName;
|
||||
string restOfName = string();
|
||||
if(index>0) {
|
||||
name = fieldName.substr(0, index);
|
||||
if(fieldName.length()>index) {
|
||||
restOfName = fieldName.substr(index+1);
|
||||
}
|
||||
}
|
||||
PVFieldPtrArray pvFields = pvStructure->getPVFields();
|
||||
PVFieldPtr pvField;
|
||||
size_t numFields = pvStructure->getStructure()->getNumberFields();
|
||||
for(size_t i=0; i<numFields; i++) {
|
||||
pvField = pvFields[i];
|
||||
size_t result = pvField->getFieldName().compare(name);
|
||||
if(result==0) {
|
||||
if(restOfName.length()==0) return pvFields[i];
|
||||
if(pvField->getField()->getType()!=structure) return PVFieldPtr();
|
||||
PVStructurePtr pvStructure =
|
||||
std::tr1::static_pointer_cast<PVStructure>(pvField);
|
||||
return findSubField(restOfName,pvStructure.get());
|
||||
}
|
||||
}
|
||||
return PVFieldPtr();
|
||||
}
|
||||
|
||||
std::ostream& PVStructure::dumpValue(std::ostream& o) const
|
||||
{
|
||||
o << format::indent() << getStructure()->getID() << ' ' << getFieldName();
|
||||
@@ -382,4 +354,79 @@ std::ostream& PVStructure::dumpValue(std::ostream& o) const
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
void PVStructure::copy(const PVStructure& from)
|
||||
{
|
||||
if(isImmutable())
|
||||
throw std::invalid_argument("destination is immutable");
|
||||
|
||||
if(*getStructure() != *from.getStructure())
|
||||
throw std::invalid_argument("structure definitions do not match");
|
||||
|
||||
copyUnchecked(from);
|
||||
}
|
||||
|
||||
void PVStructure::copyUnchecked(const PVStructure& from)
|
||||
{
|
||||
if (this == &from)
|
||||
return;
|
||||
|
||||
PVFieldPtrArray const & fromPVFields = from.getPVFields();
|
||||
PVFieldPtrArray const & toPVFields = getPVFields();
|
||||
|
||||
size_t fieldsSize = fromPVFields.size();
|
||||
for(size_t i = 0; i<fieldsSize; i++) {
|
||||
toPVFields[i]->copyUnchecked(*fromPVFields[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void PVStructure::copyUnchecked(const PVStructure& from, const BitSet& maskBitSet, bool inverse)
|
||||
{
|
||||
if (this == &from)
|
||||
return;
|
||||
|
||||
size_t numberFields = from.getNumberFields();
|
||||
size_t offset = from.getFieldOffset();
|
||||
int32 next = inverse ?
|
||||
maskBitSet.nextClearBit(static_cast<uint32>(offset)) :
|
||||
maskBitSet.nextSetBit(static_cast<uint32>(offset));
|
||||
|
||||
// no more changes or no changes in this structure
|
||||
if(next<0||next>=static_cast<int32>(offset+numberFields)) return;
|
||||
|
||||
// entire structure
|
||||
if(static_cast<int32>(offset)==next) {
|
||||
copyUnchecked(from);
|
||||
return;
|
||||
}
|
||||
|
||||
PVFieldPtrArray const & fromPVFields = from.getPVFields();
|
||||
PVFieldPtrArray const & toPVFields = getPVFields();
|
||||
|
||||
size_t fieldsSize = fromPVFields.size();
|
||||
for(size_t i = 0; i<fieldsSize; i++) {
|
||||
PVFieldPtr pvField = fromPVFields[i];
|
||||
offset = pvField->getFieldOffset();
|
||||
int32 inumberFields = static_cast<int32>(pvField->getNumberFields());
|
||||
next = inverse ?
|
||||
maskBitSet.nextClearBit(static_cast<uint32>(offset)) :
|
||||
maskBitSet.nextSetBit(static_cast<uint32>(offset));
|
||||
|
||||
// no more changes
|
||||
if(next<0) return;
|
||||
// no change in this pvField
|
||||
if(next>=static_cast<int32>(offset+inumberFields)) continue;
|
||||
|
||||
// serialize field or fields
|
||||
if(inumberFields==1) {
|
||||
toPVFields[i]->copyUnchecked(*pvField);
|
||||
} else {
|
||||
PVStructure::shared_pointer fromPVStructure = std::tr1::static_pointer_cast<PVStructure>(pvField);
|
||||
PVStructure::shared_pointer toPVStructure = std::tr1::static_pointer_cast<PVStructure>(toPVFields[i]);
|
||||
toPVStructure->copyUnchecked(*fromPVStructure, maskBitSet, inverse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
@@ -179,7 +178,7 @@ void PVStructureArray::deserialize(ByteBuffer *pbuffer,
|
||||
data[i].reset();
|
||||
}
|
||||
else {
|
||||
if(data[i].get()==NULL) {
|
||||
if(data[i].get()==NULL || !data[i].unique()) {
|
||||
data[i] = pvDataCreate->createPVStructure(structure);
|
||||
}
|
||||
data[i]->deserialize(pbuffer, pcontrol);
|
||||
@@ -242,4 +241,23 @@ std::ostream& PVStructureArray::dumpValue(std::ostream& o, std::size_t index) co
|
||||
return o;
|
||||
}
|
||||
|
||||
void PVStructureArray::copy(const PVStructureArray& from)
|
||||
{
|
||||
if(isImmutable())
|
||||
throw std::invalid_argument("destination is immutable");
|
||||
|
||||
if(*getStructureArray() != *from.getStructureArray())
|
||||
throw std::invalid_argument("structureArray definitions do not match");
|
||||
|
||||
copyUnchecked(from);
|
||||
}
|
||||
|
||||
void PVStructureArray::copyUnchecked(const PVStructureArray& from)
|
||||
{
|
||||
if (this == &from)
|
||||
return;
|
||||
|
||||
replace(from.view());
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
@@ -29,6 +28,8 @@ namespace epics { namespace pvData {
|
||||
#define PVUNION_UNDEFINED_INDEX -1
|
||||
int32 PVUnion::UNDEFINED_INDEX = PVUNION_UNDEFINED_INDEX;
|
||||
|
||||
PVDataCreatePtr PVUnion::pvDataCreate(getPVDataCreate());
|
||||
|
||||
PVUnion::PVUnion(UnionConstPtr const & unionPtr)
|
||||
: PVField(unionPtr),
|
||||
unionPtr(unionPtr),
|
||||
@@ -87,7 +88,7 @@ PVFieldPtr PVUnion::select(int32 index)
|
||||
|
||||
FieldConstPtr field = unionPtr->getField(index);
|
||||
selector = index;
|
||||
value = getPVDataCreate()->createPVField(field);
|
||||
value = pvDataCreate->createPVField(field);
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -144,10 +145,10 @@ void PVUnion::serialize(ByteBuffer *pbuffer, SerializableControl *pflusher) cons
|
||||
if (variant)
|
||||
{
|
||||
// write introspection data
|
||||
if (value.get() == 0)
|
||||
if (value.get() == 0) {
|
||||
pflusher->ensureBuffer(1);
|
||||
pbuffer->put((int8)-1);
|
||||
else
|
||||
{
|
||||
}else {
|
||||
pflusher->cachedSerialize(value->getField(), pbuffer);
|
||||
value->serialize(pbuffer, pflusher);
|
||||
}
|
||||
@@ -171,7 +172,7 @@ void PVUnion::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol)
|
||||
{
|
||||
// try to reuse existing field instance
|
||||
if (!value.get() || *value->getField() != *field)
|
||||
value = getPVDataCreate()->createPVField(field);
|
||||
value = pvDataCreate->createPVField(field);
|
||||
value->deserialize(pbuffer, pcontrol);
|
||||
}
|
||||
else
|
||||
@@ -188,7 +189,7 @@ void PVUnion::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol)
|
||||
FieldConstPtr field = unionPtr->getField(selector);
|
||||
// try to reuse existing field instance
|
||||
if (!value.get() || *value->getField() != *field)
|
||||
value = getPVDataCreate()->createPVField(field);
|
||||
value = pvDataCreate->createPVField(field);
|
||||
}
|
||||
value->deserialize(pbuffer, pcontrol);
|
||||
}
|
||||
@@ -217,4 +218,57 @@ std::ostream& PVUnion::dumpValue(std::ostream& o) const
|
||||
return o;
|
||||
}
|
||||
|
||||
void PVUnion::copy(const PVUnion& from)
|
||||
{
|
||||
if(isImmutable())
|
||||
throw std::invalid_argument("destination is immutable");
|
||||
|
||||
if(*getUnion() != *from.getUnion())
|
||||
throw std::invalid_argument("union definitions do not match");
|
||||
|
||||
copyUnchecked(from);
|
||||
}
|
||||
|
||||
void PVUnion::copyUnchecked(const PVUnion& from)
|
||||
{
|
||||
|
||||
PVFieldPtr fromValue = from.get();
|
||||
if (from.getUnion()->isVariant())
|
||||
{
|
||||
if (fromValue.get() == 0)
|
||||
{
|
||||
set(PVField::shared_pointer());
|
||||
}
|
||||
else
|
||||
{
|
||||
PVFieldPtr toValue = get();
|
||||
if (toValue.get() == 0 || *toValue->getField() != *fromValue->getField())
|
||||
{
|
||||
toValue = pvDataCreate->createPVField(fromValue->getField());
|
||||
toValue->copyUnchecked(*fromValue);
|
||||
set(toValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
toValue->copyUnchecked(*fromValue);
|
||||
postPut();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fromValue.get() == 0)
|
||||
{
|
||||
select(PVUnion::UNDEFINED_INDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
select(from.getSelectedIndex())->copyUnchecked(*fromValue);
|
||||
}
|
||||
postPut();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
@@ -178,7 +177,7 @@ void PVUnionArray::deserialize(ByteBuffer *pbuffer,
|
||||
data[i].reset();
|
||||
}
|
||||
else {
|
||||
if(data[i].get()==NULL) {
|
||||
if(data[i].get()==NULL || !data[i].unique()) {
|
||||
data[i] = pvDataCreate->createPVUnion(punion);
|
||||
}
|
||||
data[i]->deserialize(pbuffer, pcontrol);
|
||||
@@ -241,4 +240,24 @@ std::ostream& PVUnionArray::dumpValue(std::ostream& o, std::size_t index) const
|
||||
return o;
|
||||
}
|
||||
|
||||
void PVUnionArray::copy(const PVUnionArray& from)
|
||||
{
|
||||
if(isImmutable())
|
||||
throw std::invalid_argument("destination is immutable");
|
||||
|
||||
if(*getUnionArray() != *from.getUnionArray())
|
||||
throw std::invalid_argument("unionArray definitions do not match");
|
||||
|
||||
copyUnchecked(from);
|
||||
}
|
||||
|
||||
void PVUnionArray::copyUnchecked(const PVUnionArray& from)
|
||||
{
|
||||
if (this == &from)
|
||||
return;
|
||||
|
||||
replace(from.view());
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -89,9 +89,9 @@ StructureConstPtr StandardField::createProperties(string id,FieldConstPtr field,
|
||||
}
|
||||
if(type==structure) {
|
||||
StructureConstPtr structurePtr = static_pointer_cast<const Structure>(field);
|
||||
StringArray names = structurePtr->getFieldNames();
|
||||
StringArray const & names = structurePtr->getFieldNames();
|
||||
if(names.size()==2) {
|
||||
FieldConstPtrArray fields = structurePtr->getFields();
|
||||
FieldConstPtrArray const & fields = structurePtr->getFields();
|
||||
FieldConstPtr first = fields[0];
|
||||
FieldConstPtr second = fields[1];
|
||||
string nameFirst = names[0];
|
||||
@@ -554,7 +554,7 @@ StructureConstPtr StandardField::enumerated()
|
||||
fields[0] = fieldCreate->createScalar(pvInt);
|
||||
fields[1] = fieldCreate->createScalarArray(pvString);
|
||||
return fieldCreate->createStructure("enum_t",names,fields);
|
||||
// NOTE: if this method is used to get NTEnum wihtout properties the ID will be wrong!
|
||||
// NOTE: if this method is used to get NTEnum without properties the ID will be wrong!
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::enumerated(string const &properties)
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
|
||||
@@ -67,11 +66,9 @@ PVStructurePtr StandardPVField::enumerated(StringArray const &choices)
|
||||
{
|
||||
StructureConstPtr field = standardField->enumerated();
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
|
||||
PVScalarArrayPtr pvScalarArray = pvStructure->getScalarArrayField(
|
||||
"choices",pvString);
|
||||
PVStringArray::svector cdata(choices.size());
|
||||
std::copy(choices.begin(), choices.end(), cdata.begin());
|
||||
static_cast<PVStringArray&>(*pvScalarArray).replace(freeze(cdata));
|
||||
pvStructure->getSubField<PVStringArray>("choices")->replace(freeze(cdata));
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
@@ -80,11 +77,9 @@ PVStructurePtr StandardPVField::enumerated(
|
||||
{
|
||||
StructureConstPtr field = standardField->enumerated(properties);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
|
||||
PVScalarArrayPtr pvScalarArray = pvStructure->getScalarArrayField(
|
||||
"value.choices",pvString);
|
||||
PVStringArray::svector cdata(choices.size());
|
||||
std::copy(choices.begin(), choices.end(), cdata.begin());
|
||||
static_cast<PVStringArray&>(*pvScalarArray).replace(freeze(cdata));
|
||||
pvStructure->getSubField<PVStringArray>("value.choices")->replace(freeze(cdata));
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,20 +8,10 @@
|
||||
#include <deque>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/printer.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace {
|
||||
|
||||
void indentN(std::ostream& strm, size_t N)
|
||||
{
|
||||
while(N--)
|
||||
strm.put(' ');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
namespace format
|
||||
@@ -52,246 +42,4 @@ namespace format
|
||||
}
|
||||
};
|
||||
|
||||
PrinterBase::PrinterBase()
|
||||
:strm(NULL)
|
||||
{}
|
||||
|
||||
PrinterBase::~PrinterBase() {}
|
||||
|
||||
void PrinterBase::setStream(std::ostream& s)
|
||||
{
|
||||
strm = &s;
|
||||
}
|
||||
|
||||
void PrinterBase::clearStream()
|
||||
{
|
||||
strm = NULL;
|
||||
}
|
||||
|
||||
void PrinterBase::print(const PVField& pv)
|
||||
{
|
||||
if(!strm)
|
||||
throw std::runtime_error("No stream set for PV Printer");
|
||||
impl_print(pv);
|
||||
}
|
||||
|
||||
void PrinterBase::beginStructure(const PVStructure&) {}
|
||||
void PrinterBase::endStructure(const PVStructure&) {}
|
||||
|
||||
void PrinterBase::beginStructureArray(const PVStructureArray&) {}
|
||||
void PrinterBase::endStructureArray(const PVStructureArray&) {}
|
||||
|
||||
void PrinterBase::beginUnion(const PVUnion&) {}
|
||||
void PrinterBase::endUnion(const PVUnion&) {}
|
||||
|
||||
void PrinterBase::beginUnionArray(const PVUnionArray&) {}
|
||||
void PrinterBase::endUnionArray(const PVUnionArray&) {}
|
||||
|
||||
void PrinterBase::encodeScalar(const PVScalar&) {}
|
||||
|
||||
void PrinterBase::encodeArray(const PVScalarArray&) {}
|
||||
|
||||
void PrinterBase::encodeNull() {}
|
||||
|
||||
void PrinterBase::impl_print(const PVField& pv)
|
||||
{
|
||||
static const PVField* marker = (const PVField*)▮
|
||||
|
||||
/* Depth first recursive iteration.
|
||||
* Each PV to be printed is appended to the todo queue.
|
||||
* The last child of a structure is followed by a NULL.
|
||||
* As the tree is walked structures and structarrays
|
||||
* are appended to the inprog queue.
|
||||
*/
|
||||
std::deque<const PVField*> todo, inprog;
|
||||
|
||||
todo.push_back(&pv);
|
||||
|
||||
while(!todo.empty()) {
|
||||
const PVField *next = todo.front();
|
||||
todo.pop_front();
|
||||
|
||||
if(next==marker) {
|
||||
// finished with a structure or structarray,
|
||||
// now we fall back to its parent.
|
||||
assert(!inprog.empty());
|
||||
switch(inprog.back()->getField()->getType()) {
|
||||
case structure:
|
||||
endStructure(*static_cast<const PVStructure *>(inprog.back()));
|
||||
break;
|
||||
|
||||
case structureArray:
|
||||
endStructureArray(*static_cast<const PVStructureArray *>(inprog.back()));
|
||||
break;
|
||||
|
||||
case union_:
|
||||
endUnion(*static_cast<const PVUnion *>(inprog.back()));
|
||||
break;
|
||||
|
||||
case unionArray:
|
||||
endUnionArray(*static_cast<const PVUnionArray *>(inprog.back()));
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false); // oops!
|
||||
return;
|
||||
}
|
||||
inprog.pop_back();
|
||||
|
||||
} else {
|
||||
// real field
|
||||
|
||||
if(!next) {
|
||||
// NULL entry in a structure array
|
||||
encodeNull();
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(next->getField()->getType()) {
|
||||
case scalar:
|
||||
encodeScalar(*static_cast<const PVScalar*>(next));
|
||||
break;
|
||||
case scalarArray:
|
||||
encodeArray(*static_cast<const PVScalarArray*>(next));
|
||||
break;
|
||||
case structure: {
|
||||
const PVStructure &fld = *static_cast<const PVStructure*>(next);
|
||||
const PVFieldPtrArray& vals = fld.getPVFields();
|
||||
|
||||
inprog.push_back(next);
|
||||
|
||||
beginStructure(fld);
|
||||
for(size_t i=0, nfld=fld.getStructure()->getNumberFields(); i<nfld; i++)
|
||||
todo.push_back(vals[i].get());
|
||||
|
||||
todo.push_back(marker);
|
||||
break;
|
||||
}
|
||||
case structureArray: {
|
||||
const PVStructureArray &fld = *static_cast<const PVStructureArray*>(next);
|
||||
PVStructureArray::const_svector vals(fld.view());
|
||||
|
||||
inprog.push_back(next);
|
||||
|
||||
beginStructureArray(fld);
|
||||
for(PVStructureArray::const_svector::const_iterator it=vals.begin();
|
||||
it!=vals.end(); ++it)
|
||||
{
|
||||
todo.push_back(it->get());
|
||||
}
|
||||
|
||||
todo.push_back(marker);
|
||||
break;
|
||||
}
|
||||
case union_: {
|
||||
const PVUnion &fld = *static_cast<const PVUnion*>(next);
|
||||
|
||||
inprog.push_back(next);
|
||||
|
||||
beginUnion(fld);
|
||||
PVFieldPtr val = fld.get();
|
||||
if (val.get()) // TODO print "(none)" ?
|
||||
todo.push_back(val.get());
|
||||
|
||||
todo.push_back(marker);
|
||||
break;
|
||||
}
|
||||
case unionArray: {
|
||||
const PVUnionArray &fld = *static_cast<const PVUnionArray*>(next);
|
||||
PVUnionArray::const_svector vals(fld.view());
|
||||
|
||||
inprog.push_back(next);
|
||||
|
||||
beginUnionArray(fld);
|
||||
for(PVUnionArray::const_svector::const_iterator it=vals.begin();
|
||||
it!=vals.end(); ++it)
|
||||
{
|
||||
todo.push_back(it->get());
|
||||
}
|
||||
|
||||
todo.push_back(marker);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PrinterPlain::PrinterPlain()
|
||||
:PrinterBase()
|
||||
,ilvl(0)
|
||||
{}
|
||||
|
||||
PrinterPlain::~PrinterPlain() {}
|
||||
|
||||
void PrinterPlain::beginStructure(const PVStructure& pv)
|
||||
{
|
||||
indentN(S(), ilvl);
|
||||
S() << pv.getStructure()->getID() << " " << pv.getFieldName();
|
||||
S() << std::endl;
|
||||
ilvl++;
|
||||
}
|
||||
|
||||
void PrinterPlain::endStructure(const PVStructure&) {ilvl--;}
|
||||
|
||||
void PrinterPlain::beginStructureArray(const PVStructureArray& pv)
|
||||
{
|
||||
indentN(S(), ilvl);
|
||||
S() << pv.getStructureArray()->getID() << " "
|
||||
<< pv.getFieldName() << "[] ";
|
||||
ilvl++;
|
||||
}
|
||||
|
||||
void PrinterPlain::endStructureArray(const PVStructureArray&) {ilvl--;}
|
||||
|
||||
void PrinterPlain::beginUnion(const PVUnion& pv)
|
||||
{
|
||||
indentN(S(), ilvl);
|
||||
S() << pv.getUnion()->getID() << " " << pv.getFieldName() << std::endl;
|
||||
ilvl++;
|
||||
}
|
||||
|
||||
void PrinterPlain::endUnion(const PVUnion&) {ilvl--;}
|
||||
|
||||
void PrinterPlain::beginUnionArray(const PVUnionArray& pv)
|
||||
{
|
||||
indentN(S(), ilvl);
|
||||
S() << pv.getUnionArray()->getID() << " "
|
||||
<< pv.getFieldName() << "[] ";
|
||||
ilvl++;
|
||||
}
|
||||
|
||||
void PrinterPlain::endUnionArray(const PVUnionArray&) {ilvl--;}
|
||||
|
||||
void PrinterPlain::encodeScalar(const PVScalar& pv)
|
||||
{
|
||||
indentN(S(), ilvl);
|
||||
S() << pv.getScalar()->getID() << " "
|
||||
<< pv.getFieldName() << " "
|
||||
<< pv.getAs<string>() << std::endl;
|
||||
}
|
||||
|
||||
void PrinterPlain::encodeArray(const PVScalarArray& pv)
|
||||
{
|
||||
indentN(S(), ilvl);
|
||||
shared_vector<const string> temp;
|
||||
pv.getAs<string>(temp);
|
||||
|
||||
S() << pv.getScalarArray()->getID() << " "
|
||||
<< pv.getFieldName() << " [";
|
||||
for(size_t i=0, len=pv.getLength(); i<len; i++) {
|
||||
S() << temp[i];
|
||||
if(i!=len-1)
|
||||
S().put(',');
|
||||
}
|
||||
S() << "]" << std::endl;
|
||||
}
|
||||
|
||||
void PrinterPlain::encodeNull()
|
||||
{
|
||||
indentN(S(), ilvl);
|
||||
S() << "NULL" << std::endl;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -22,7 +22,6 @@ INC += status.h
|
||||
INC += sharedPtr.h
|
||||
INC += localStaticLock.h
|
||||
INC += typeCast.h
|
||||
INC += printer.h
|
||||
INC += sharedVector.h
|
||||
INC += templateMeta.h
|
||||
INC += current_function.h
|
||||
|
||||
@@ -279,7 +279,8 @@ namespace epics { namespace pvData {
|
||||
uint32 inUse = (set1.wordsInUse < set2.wordsInUse) ? set1.wordsInUse : set2.wordsInUse;
|
||||
|
||||
ensureCapacity(inUse);
|
||||
wordsInUse = inUse;
|
||||
if(inUse>wordsInUse)
|
||||
wordsInUse = inUse;
|
||||
|
||||
// Perform logical AND on words in common
|
||||
for (uint32 i = 0; i < inUse; i++)
|
||||
@@ -322,12 +323,14 @@ namespace epics { namespace pvData {
|
||||
|
||||
SerializeHelper::writeSize(len, buffer, flusher);
|
||||
flusher->ensureBuffer(len);
|
||||
|
||||
for (uint32 i = 0; i < n - 1; i++)
|
||||
|
||||
n = len / 8;
|
||||
for (uint32 i = 0; i < n; i++)
|
||||
buffer->putLong(words[i]);
|
||||
|
||||
for (uint64 x = words[n - 1]; x != 0; x >>= 8)
|
||||
buffer->putByte((int8) (x & 0xff));
|
||||
|
||||
if (n < wordsInUse)
|
||||
for (uint64 x = words[wordsInUse - 1]; x != 0; x >>= 8)
|
||||
buffer->putByte((int8) (x & 0xff));
|
||||
}
|
||||
|
||||
void BitSet::deserialize(ByteBuffer* buffer, DeserializableControl* control) {
|
||||
@@ -356,7 +359,7 @@ namespace epics { namespace pvData {
|
||||
words[j] = 0;
|
||||
|
||||
for (uint32 remaining = (bytes - longs * 8), j = 0; j < remaining; j++)
|
||||
words[i] |= (buffer->getByte() & 0xffL) << (8 * j);
|
||||
words[i] |= (buffer->getByte() & 0xffLL) << (8 * j);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -24,16 +24,18 @@ namespace epics { namespace pvData {
|
||||
typedef std::tr1::shared_ptr<BitSet> BitSetPtr;
|
||||
|
||||
/**
|
||||
* @brief A vector of bits.
|
||||
*
|
||||
* This class implements a vector of bits that grows as needed. Each
|
||||
* component of the bit set has a {@code bool} value. The
|
||||
* bits of a {@code BitSet} are indexed by nonnegative integers.
|
||||
* Individual indexed bits can be examined, set, or cleared. One
|
||||
* {@code BitSet} may be used to modify the contents of another
|
||||
* {@code BitSet} through logical AND, logical inclusive OR, and
|
||||
* logical exclusive OR operations.
|
||||
* component of the bit set has a @c bool value. The bits of a
|
||||
* @c BitSet are indexed by nonnegative integers. Individual
|
||||
* indexed bits can be examined, set, or cleared. One @c BitSet may
|
||||
* be used to modify the contents of another @c BitSet through
|
||||
* logical AND, logical inclusive OR, and logical exclusive OR
|
||||
* operations.
|
||||
*
|
||||
* <p>By default, all bits in the set initially have the value
|
||||
* {@code false}.
|
||||
* @c false.
|
||||
*
|
||||
* <p>Every bit set has a current size, which is the number of bits
|
||||
* of space currently in use by the bit set. Note that the size is
|
||||
@@ -41,8 +43,8 @@ namespace epics { namespace pvData {
|
||||
* implementation. The length of a bit set relates to logical length
|
||||
* of a bit set and is defined independently of implementation.
|
||||
*
|
||||
* <p>A {@code BitSet} is not safe for multithreaded use without
|
||||
* external synchronization.
|
||||
* <p>A @c BitSet is not safe for multithreaded use without external
|
||||
* synchronization.
|
||||
*
|
||||
* Based on Java implementation.
|
||||
*/
|
||||
@@ -51,14 +53,14 @@ namespace epics { namespace pvData {
|
||||
POINTER_DEFINITIONS(BitSet);
|
||||
static BitSetPtr create(uint32 nbits);
|
||||
/**
|
||||
* Creates a new bit set. All bits are initially {@code false}.
|
||||
* Creates a new bit set. All bits are initially @c false.
|
||||
*/
|
||||
BitSet();
|
||||
|
||||
/**
|
||||
* Creates a bit set whose initial size is large enough to explicitly
|
||||
* represent bits with indices in the range {@code 0} through
|
||||
* {@code nbits-1}. All bits are initially {@code false}.
|
||||
* represent bits with indices in the range @c 0 through
|
||||
* @c nbits-1. All bits are initially @c false.
|
||||
*
|
||||
* @param nbits the initial size of the bit set
|
||||
*/
|
||||
@@ -78,14 +80,14 @@ namespace epics { namespace pvData {
|
||||
void flip(uint32 bitIndex);
|
||||
|
||||
/**
|
||||
* Sets the bit at the specified index to {@code true}.
|
||||
* Sets the bit at the specified index to @c true.
|
||||
*
|
||||
* @param bitIndex a bit index
|
||||
*/
|
||||
void set(uint32 bitIndex);
|
||||
|
||||
/**
|
||||
* Sets the bit specified by the index to {@code false}.
|
||||
* Sets the bit specified by the index to @c false.
|
||||
*
|
||||
* @param bitIndex the index of the bit to be cleared
|
||||
*/
|
||||
@@ -101,9 +103,8 @@ namespace epics { namespace pvData {
|
||||
|
||||
/**
|
||||
* Returns the value of the bit with the specified index. The value
|
||||
* is {@code true} if the bit with the index {@code bitIndex}
|
||||
* is currently set in this {@code BitSet}; otherwise, the result
|
||||
* is {@code false}.
|
||||
* is @c true if the bit with the index @c bitIndex is currently
|
||||
* set in this @c BitSet; otherwise, the result is @c false.
|
||||
*
|
||||
* @param bitIndex the bit index
|
||||
* @return the value of the bit with the specified index
|
||||
@@ -111,16 +112,16 @@ namespace epics { namespace pvData {
|
||||
bool get(uint32 bitIndex) const;
|
||||
|
||||
/**
|
||||
* Sets all of the bits in this BitSet to {@code false}.
|
||||
* Sets all of the bits in this BitSet to @c false.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Returns the index of the first bit that is set to {@code true}
|
||||
* that occurs on or after the specified starting index. If no such
|
||||
* bit exists then {@code -1} is returned.
|
||||
* Returns the index of the first bit that is set to @c true that
|
||||
* occurs on or after the specified starting index. If no such bit
|
||||
* exists then @c -1 is returned.
|
||||
*
|
||||
* <p>To iterate over the {@code true} bits in a {@code BitSet},
|
||||
* <p>To iterate over the @c true bits in a @c BitSet,
|
||||
* use the following loop:
|
||||
*
|
||||
* <pre> {@code
|
||||
@@ -129,13 +130,13 @@ namespace epics { namespace pvData {
|
||||
* }}</pre>
|
||||
*
|
||||
* @param fromIndex the index to start checking from (inclusive)
|
||||
* @return the index of the next set bit, or {@code -1} if there
|
||||
* @return the index of the next set bit, or @c -1 if there
|
||||
* is no such bit
|
||||
*/
|
||||
int32 nextSetBit(uint32 fromIndex) const;
|
||||
|
||||
/**
|
||||
* Returns the index of the first bit that is set to {@code false}
|
||||
* Returns the index of the first bit that is set to @c false
|
||||
* that occurs on or after the specified starting index.
|
||||
*
|
||||
* @param fromIndex the index to start checking from (inclusive)
|
||||
@@ -144,23 +145,23 @@ namespace epics { namespace pvData {
|
||||
int32 nextClearBit(uint32 fromIndex) const;
|
||||
|
||||
/**
|
||||
* Returns true if this {@code BitSet} contains no bits that are set
|
||||
* to {@code true}.
|
||||
* Returns true if this @c BitSet contains no bits that are set
|
||||
* to @c true.
|
||||
*
|
||||
* @return indicating whether this {@code BitSet} is empty
|
||||
* @return indicating whether this @c BitSet is empty
|
||||
*/
|
||||
bool isEmpty() const;
|
||||
|
||||
/**
|
||||
* Returns the number of bits set to {@code true} in this {@code BitSet}.
|
||||
* Returns the number of bits set to @c true in this @c BitSet.
|
||||
*
|
||||
* @return the number of bits set to {@code true} in this {@code BitSet}
|
||||
* @return the number of bits set to @c true in this @c BitSet
|
||||
*/
|
||||
uint32 cardinality() const;
|
||||
|
||||
/**
|
||||
* Returns the number of bits of space actually in use by this
|
||||
* {@code BitSet} to represent bit values.
|
||||
* @c BitSet to represent bit values.
|
||||
* The maximum element in the set is the size - 1st element.
|
||||
*
|
||||
* @return the number of bits currently in this bit set
|
||||
@@ -170,9 +171,9 @@ namespace epics { namespace pvData {
|
||||
/**
|
||||
* Performs a logical <b>AND</b> of this target bit set with the
|
||||
* argument bit set. This bit set is modified so that each bit in it
|
||||
* has the value {@code true} if and only if it both initially
|
||||
* had the value {@code true} and the corresponding bit in the
|
||||
* bit set argument also had the value {@code true}.
|
||||
* has the value @c true if and only if it both initially
|
||||
* had the value @c true and the corresponding bit in the
|
||||
* bit set argument also had the value @c true.
|
||||
*
|
||||
* @param set a bit set
|
||||
*/
|
||||
@@ -181,9 +182,9 @@ namespace epics { namespace pvData {
|
||||
/**
|
||||
* Performs a logical <b>OR</b> of this bit set with the bit set
|
||||
* argument. This bit set is modified so that a bit in it has the
|
||||
* value {@code true} if and only if it either already had the
|
||||
* value {@code true} or the corresponding bit in the bit set
|
||||
* argument has the value {@code true}.
|
||||
* value @c true if and only if it either already had the
|
||||
* value @c true or the corresponding bit in the bit set
|
||||
* argument has the value @c true.
|
||||
*
|
||||
* @param set a bit set
|
||||
*/
|
||||
@@ -192,13 +193,13 @@ namespace epics { namespace pvData {
|
||||
/**
|
||||
* Performs a logical <b>XOR</b> of this bit set with the bit set
|
||||
* argument. This bit set is modified so that a bit in it has the
|
||||
* value {@code true} if and only if one of the following
|
||||
* value @c true if and only if one of the following
|
||||
* statements holds:
|
||||
* <ul>
|
||||
* <li>The bit initially has the value {@code true}, and the
|
||||
* corresponding bit in the argument has the value {@code false}.
|
||||
* <li>The bit initially has the value {@code false}, and the
|
||||
* corresponding bit in the argument has the value {@code true}.
|
||||
* <li>The bit initially has the value @c true, and the
|
||||
* corresponding bit in the argument has the value @c false.
|
||||
* <li>The bit initially has the value @c false, and the
|
||||
* corresponding bit in the argument has the value @c true.
|
||||
* </ul>
|
||||
*
|
||||
* @param set a bit set
|
||||
@@ -206,7 +207,7 @@ namespace epics { namespace pvData {
|
||||
BitSet& operator^=(const BitSet& set);
|
||||
|
||||
/**
|
||||
* Assigment operator.
|
||||
* Assignment operator.
|
||||
*/
|
||||
BitSet& operator=(const BitSet &set);
|
||||
|
||||
|
||||
@@ -144,6 +144,24 @@ inline int64 swap(int64 val)
|
||||
return swap64(val);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint16 swap(uint16 val)
|
||||
{
|
||||
return swap16(val);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint32 swap(uint32 val)
|
||||
{
|
||||
return swap32(val);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint64 swap(uint64 val)
|
||||
{
|
||||
return swap64(val);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline float swap(float val)
|
||||
{
|
||||
@@ -188,8 +206,9 @@ inline double swap(double val)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This class implements {@code Bytebuffer} that is like the {@code java.nio.ByteBuffer}.
|
||||
* <p>A {@code BitSet} is not safe for multithreaded use without
|
||||
* @brief This class implements a Bytebuffer that is like the java.nio.ByteBuffer.
|
||||
*
|
||||
* <p>A @c BitSet is not safe for multithreaded use without
|
||||
* external synchronization.
|
||||
*
|
||||
* Based on Java implementation.
|
||||
@@ -354,7 +373,7 @@ public:
|
||||
template<typename T>
|
||||
inline void put(std::size_t index, T value);
|
||||
/**
|
||||
* Get the new object from the byte buffer. The item MUST have type {@code T}.
|
||||
* Get the new object from the byte buffer. The item MUST have type @c T.
|
||||
* The position is adjusted based on the type.
|
||||
*
|
||||
* @return The object.
|
||||
@@ -368,7 +387,7 @@ public:
|
||||
#endif
|
||||
/**
|
||||
* Get the new object from the byte buffer at the specified index.
|
||||
* The item MUST have type {@code T}.
|
||||
* The item MUST have type @c T.
|
||||
* The position is adjusted based on the type.
|
||||
*
|
||||
* @param index The location in the byte buffer.
|
||||
@@ -380,9 +399,9 @@ public:
|
||||
* Put a sub-array of bytes into the byte buffer.
|
||||
* The position is increased by the count.
|
||||
*
|
||||
* @param src The source array.
|
||||
* @param offset The starting position within src.
|
||||
* @param count The number of bytes to put into the byte buffer,
|
||||
* @param src The source array.
|
||||
* @param src_offset The starting position within src.
|
||||
* @param count The number of bytes to put into the byte buffer,
|
||||
*/
|
||||
inline void put(const char* src, std::size_t src_offset, std::size_t count) {
|
||||
//if(count>getRemaining()) THROW_BASE_EXCEPTION("buffer overflow");
|
||||
@@ -393,9 +412,9 @@ public:
|
||||
* Get a sub-array of bytes from the byte buffer.
|
||||
* The position is increased by the count.
|
||||
*
|
||||
* @param dest The destination array.
|
||||
* @param offset The starting position within src.
|
||||
* @param count The number of bytes to put into the byte buffer,
|
||||
* @param dest The destination array.
|
||||
* @param dest_offset The starting position within src.
|
||||
* @param count The number of bytes to put into the byte buffer.
|
||||
*/
|
||||
inline void get(char* dest, std::size_t dest_offset, std::size_t count) {
|
||||
//if(count>getRemaining()) THROW_BASE_EXCEPTION("buffer overflow");
|
||||
@@ -403,7 +422,7 @@ public:
|
||||
_position += count;
|
||||
}
|
||||
/**
|
||||
* Put an array of type {@code T} into the byte buffer.
|
||||
* Put an array of type @c T into the byte buffer.
|
||||
* The position is adjusted.
|
||||
*
|
||||
* @param values The input array.
|
||||
@@ -412,7 +431,7 @@ public:
|
||||
template<typename T>
|
||||
inline void putArray(const T* values, std::size_t count);
|
||||
/**
|
||||
* Get an array of type {@code T} from the byte buffer.
|
||||
* Get an array of type @c T from the byte buffer.
|
||||
* The position is adjusted.
|
||||
*
|
||||
* @param values The destination array.
|
||||
@@ -618,7 +637,7 @@ public:
|
||||
/**
|
||||
* Get a boolean value from the byte buffer at the specified index.
|
||||
*
|
||||
* @param double The offset in the byte buffer.
|
||||
* @param index The offset in the byte buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
inline double getDouble (std::size_t index) { return get<double>(index); }
|
||||
@@ -695,7 +714,7 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this check and branching does not always payoff
|
||||
// NOTE: this check and branching does not always pay off
|
||||
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
|
||||
{
|
||||
*((T*)_position) = value;
|
||||
@@ -738,12 +757,12 @@ private:
|
||||
|
||||
if (UNALIGNED_ACCESS)
|
||||
{
|
||||
// NOTE: some CPU handle unaligned access preety good (e.g. x86)
|
||||
// NOTE: some CPU handle unaligned access pretty good (e.g. x86)
|
||||
*((T*)(_buffer + index)) = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this check and branching does not always payoff
|
||||
// NOTE: this check and branching does not always pay off
|
||||
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
|
||||
{
|
||||
*((T*)(_buffer + index)) = value;
|
||||
@@ -786,13 +805,13 @@ private:
|
||||
|
||||
if (UNALIGNED_ACCESS)
|
||||
{
|
||||
// NOTE: some CPU handle unaligned access preety good (e.g. x86)
|
||||
// NOTE: some CPU handle unaligned access pretty good (e.g. x86)
|
||||
value = *((T*)_position);
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this check and branching does not always payoff
|
||||
// NOTE: this check and branching does not always pay off
|
||||
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
|
||||
{
|
||||
value = *((T*)_position);
|
||||
@@ -838,12 +857,12 @@ private:
|
||||
|
||||
if (UNALIGNED_ACCESS)
|
||||
{
|
||||
// NOTE: some CPU handle unaligned access preety good (e.g. x86)
|
||||
// NOTE: some CPU handle unaligned access pretty good (e.g. x86)
|
||||
value = *((T*)(_buffer + index));
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this check and branching does not always payoff
|
||||
// NOTE: this check and branching does not always pay off
|
||||
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
|
||||
{
|
||||
value = *((T*)(_buffer + index));
|
||||
@@ -890,7 +909,7 @@ private:
|
||||
memcpy(_position, values, n);
|
||||
_position += n;
|
||||
|
||||
// ... so that we can be fast changing endianess
|
||||
// ... so that we can be fast changing endianness
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
for (std::size_t i = 0; i < count; i++)
|
||||
@@ -918,7 +937,7 @@ private:
|
||||
memcpy(values, _position, n);
|
||||
_position += n;
|
||||
|
||||
// ... so that we can be fast changing endianess
|
||||
// ... so that we can be fast changing endianness
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
for (std::size_t i = 0; i < count; i++)
|
||||
|
||||
@@ -18,7 +18,8 @@ namespace epics { namespace pvData {
|
||||
|
||||
|
||||
/**
|
||||
* Instance declaring destroy method.
|
||||
* @brief Instance declaring destroy method.
|
||||
*
|
||||
* @author mse
|
||||
*/
|
||||
class epicsShareClass Destroyable {
|
||||
|
||||
@@ -202,13 +202,26 @@ do { \
|
||||
#define THROW_EXCEPTION2(E,A) do{throw (E)(A);}while(0)
|
||||
|
||||
#endif // THROW_EXCEPTION_COMPAT
|
||||
|
||||
/**
|
||||
* @brief Base for pvData exceptions.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass BaseException : public std::logic_error {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
explicit BaseException(const std::string msg) : std::logic_error(msg) {}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~BaseException() throw(){};
|
||||
|
||||
/**
|
||||
*
|
||||
* Reason for excepton.
|
||||
*/
|
||||
virtual const char* what() const throw();
|
||||
|
||||
private:
|
||||
|
||||
@@ -38,8 +38,7 @@ Event::~Event() {
|
||||
|
||||
|
||||
Event::Event(bool full)
|
||||
: id(epicsEventCreate(full?epicsEventFull : epicsEventEmpty)),
|
||||
alreadyOn("already on list")
|
||||
: id(epicsEventCreate(full?epicsEventFull : epicsEventEmpty))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -35,18 +35,44 @@ namespace epics { namespace pvData {
|
||||
class Event;
|
||||
typedef std::tr1::shared_ptr<Event> EventPtr;
|
||||
|
||||
/**
|
||||
* @brief C++ wrapper for epicsEvent from EPICS base.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass Event {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Event);
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
explicit Event(bool = false);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Event();
|
||||
/**
|
||||
* Signal the event i.e. ensures that the next or current call to wait completes.
|
||||
*/
|
||||
void signal();
|
||||
/**
|
||||
* wait
|
||||
* @return (false,true) if (some error, event signaled).
|
||||
* The next wait or tryWait will clear signal.
|
||||
*/
|
||||
bool wait (); /* blocks until full */
|
||||
/**
|
||||
* wait for up to timeOut seconds.
|
||||
* @param timeOut max number of seconds to wait
|
||||
* @return (false, true) if (timeout or error, event signaled).
|
||||
*/
|
||||
bool wait ( double timeOut ); /* false if empty at time out */
|
||||
/**
|
||||
* See if a signal has been called.
|
||||
* @return (false, true) if (timeout or error, event signaled).
|
||||
*/
|
||||
bool tryWait (); /* false if empty */
|
||||
private:
|
||||
epicsEventId id;
|
||||
std::string alreadyOn;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -27,22 +27,56 @@ class Executor;
|
||||
typedef std::tr1::shared_ptr<Command> CommandPtr;
|
||||
typedef std::tr1::shared_ptr<Executor> ExecutorPtr;
|
||||
|
||||
/**
|
||||
* @brief A command to be called by Executor
|
||||
*
|
||||
*/
|
||||
class epicsShareClass Command {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Command);
|
||||
/**
|
||||
*
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~Command(){}
|
||||
/**
|
||||
*
|
||||
* The command that is executed.
|
||||
*/
|
||||
virtual void command() = 0;
|
||||
private:
|
||||
CommandPtr next;
|
||||
friend class Executor;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A class that executes commands.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass Executor : public Runnable{
|
||||
public:
|
||||
POINTER_DEFINITIONS(Executor);
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param threadName name for the executor thread.
|
||||
* @param priority The thread priority.
|
||||
*/
|
||||
Executor(std::string const & threadName,ThreadPriority priority);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Executor();
|
||||
void execute(CommandPtr const &node);
|
||||
/**
|
||||
*
|
||||
* Request to execute a command.
|
||||
* @param command A shared pointer to the command instance.
|
||||
*/
|
||||
void execute(CommandPtr const &command);
|
||||
/**
|
||||
*
|
||||
* The thread run method.
|
||||
*/
|
||||
virtual void run();
|
||||
private:
|
||||
CommandPtr head;
|
||||
|
||||
@@ -38,12 +38,30 @@ namespace epics { namespace pvData {
|
||||
|
||||
typedef epicsMutex Mutex;
|
||||
|
||||
/**
|
||||
* @brief A lock for multithreading
|
||||
*
|
||||
* This is based on item 14 of
|
||||
* * Effective C++, Third Edition, Scott Meyers
|
||||
*/
|
||||
class epicsShareClass Lock : private NoDefaultMethods {
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param m The mutex for the facility being locked.
|
||||
*/
|
||||
explicit Lock(Mutex &m)
|
||||
: mutexPtr(m), locked(true)
|
||||
{ mutexPtr.lock();}
|
||||
/**
|
||||
* Destructor
|
||||
* Note that destructor does an automatic unlock.
|
||||
*/
|
||||
~Lock(){unlock();}
|
||||
/**
|
||||
* Take the lock
|
||||
* Recursive locks are supported but each lock must be matched with an unlock.
|
||||
*/
|
||||
void lock()
|
||||
{
|
||||
if(!locked)
|
||||
@@ -52,6 +70,9 @@ public:
|
||||
locked = true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* release the lock.
|
||||
*/
|
||||
void unlock()
|
||||
{
|
||||
if(locked)
|
||||
@@ -60,6 +81,10 @@ public:
|
||||
locked=false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* If lock is not held take the lock.
|
||||
* @return (false,true) if caller (does not have, has) the lock.
|
||||
*/
|
||||
bool tryLock()
|
||||
{
|
||||
if(locked) return true;
|
||||
@@ -69,6 +94,10 @@ public:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* See if caller has the lock,
|
||||
* @return (false,true) if caller (does not have, has) the lock.
|
||||
*/
|
||||
bool ownsLock() const{return locked;}
|
||||
private:
|
||||
Mutex &mutexPtr;
|
||||
|
||||
@@ -28,10 +28,26 @@ typedef std::tr1::shared_ptr<MessageNode> MessageNodePtr;
|
||||
typedef std::vector<MessageNodePtr> MessageNodePtrArray;
|
||||
typedef std::tr1::shared_ptr<MessageQueue> MessageQueuePtr;
|
||||
|
||||
/**
|
||||
* @brief A node that can be put on a MessageQueue.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass MessageNode {
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
MessageNode();
|
||||
/**
|
||||
*
|
||||
* Get the message value.
|
||||
* @return The message value.
|
||||
*/
|
||||
std::string getMessage() const;
|
||||
/**
|
||||
* Get the message type.
|
||||
* @return The message type which is defined in Requester.
|
||||
*/
|
||||
MessageType getMessageType() const;
|
||||
private:
|
||||
std::string message;
|
||||
@@ -39,19 +55,65 @@ private:
|
||||
friend class MessageQueue;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A bounded queue for messages.
|
||||
*
|
||||
*
|
||||
*/
|
||||
class epicsShareClass MessageQueue : public Queue<MessageNode> {
|
||||
public:
|
||||
POINTER_DEFINITIONS(MessageQueue);
|
||||
/**
|
||||
* Factory method to create a MessageQueue.
|
||||
* @param size The number of MessageNodes in the queue.
|
||||
* @return shared_ptr to MessageQueue.
|
||||
*/
|
||||
static MessageQueuePtr create(int size);
|
||||
/**
|
||||
* Constructor
|
||||
* @param nodeArray an array of shared_ptr to MessageNodes,
|
||||
*/
|
||||
MessageQueue(MessageNodePtrArray &nodeArray);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~MessageQueue();
|
||||
/**
|
||||
* get the next MessageNode of the queue.
|
||||
* @return A shared_ptr to the MessageNode.
|
||||
* This will be a null pointer if queue is empty.
|
||||
* If get is successful then release for this MessageNode
|
||||
* must be called before another get can be issued.
|
||||
*/
|
||||
MessageNodePtr &get();
|
||||
// must call release before next get
|
||||
/**
|
||||
* Release the MessageNode that was returned by the previous call to get.
|
||||
*/
|
||||
void release();
|
||||
// return (false,true) if message (was not, was) put into queue
|
||||
/**
|
||||
*
|
||||
* put a message into the message queue
|
||||
* @param message The message string.
|
||||
* @param messageType The message type as defined in Requester,
|
||||
* @param replaceLast If true and queue is full then replace.
|
||||
* @return (false,true) if a message (was not, was) put in queiue.
|
||||
*/
|
||||
bool put(std::string message,MessageType messageType,bool replaceLast);
|
||||
/**
|
||||
* Is queue empty?
|
||||
* @return (false,true) if (is not, is) empty.
|
||||
*/
|
||||
bool isEmpty() ;
|
||||
/**
|
||||
* Is queue full?
|
||||
* @return (false,true) if (is not, is) full.
|
||||
*/
|
||||
bool isFull() ;
|
||||
/**
|
||||
*
|
||||
* Clear number of times queue was overrun and return the number
|
||||
* of times the queue was overrun.
|
||||
*/
|
||||
int getClearOverrun();
|
||||
private:
|
||||
MessageNodePtr nullNode;
|
||||
|
||||
@@ -17,17 +17,26 @@ namespace epics { namespace pvData {
|
||||
* Effective C++, Third Edition, Scott Meyers
|
||||
*/
|
||||
|
||||
|
||||
class epicsShareClass NoDefaultMethods {
|
||||
protected:
|
||||
// allow by derived objects
|
||||
/**
|
||||
* @brief Base class for not allowing default methods.
|
||||
*
|
||||
* Note that copy constructor a copy methods are declared private.
|
||||
*/
|
||||
class epicsShareClass NoDefaultMethods {
|
||||
protected:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
NoDefaultMethods(){};
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~NoDefaultMethods(){}
|
||||
private:
|
||||
// do not implment
|
||||
// do not implement
|
||||
NoDefaultMethods(const NoDefaultMethods&);
|
||||
NoDefaultMethods & operator=(const NoDefaultMethods &);
|
||||
};
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NO_DEFAULT_METHODS_H */
|
||||
|
||||
@@ -18,6 +18,12 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/**
|
||||
* @brief Template class for a bounded queue.
|
||||
*
|
||||
* An instance can make a queueElement be any class desired
|
||||
* but must create a std::vector of shared_ptr to queueElements.
|
||||
*/
|
||||
template <typename T>
|
||||
class Queue
|
||||
{
|
||||
@@ -25,15 +31,58 @@ public:
|
||||
POINTER_DEFINITIONS(Queue);
|
||||
typedef std::tr1::shared_ptr<T> queueElementPtr;
|
||||
typedef std::vector<queueElementPtr> queueElementPtrArray;
|
||||
Queue(queueElementPtrArray &);
|
||||
/**
|
||||
* Constructor
|
||||
* @param elementArray The vector of shared_ptr to queue elements.
|
||||
*/
|
||||
Queue(queueElementPtrArray & elementArray);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~Queue();
|
||||
/**
|
||||
* Clear the queue.
|
||||
*/
|
||||
void clear();
|
||||
/**
|
||||
* get the capacity of the queue, i. e. number of queue elements,
|
||||
* @return The capacity.
|
||||
*/
|
||||
int capacity();
|
||||
/**
|
||||
* Get the number of free elements in the queue.
|
||||
* @return The number.
|
||||
*/
|
||||
int getNumberFree();
|
||||
/**
|
||||
* Get the number of used elements in the queue.
|
||||
* This is the number that have been setUsed but not released.
|
||||
* @return The number.
|
||||
*/
|
||||
int getNumberUsed();
|
||||
/**
|
||||
* Get the next free element.
|
||||
* @return a shared_ptr to the queue element.
|
||||
* This is null if queue was full.
|
||||
*/
|
||||
queueElementPtr & getFree();
|
||||
/**
|
||||
* Set the element returned by getFree as used.
|
||||
* Until this is called getUsed will not return it.
|
||||
* @param element The element. It must be the element returned
|
||||
* by the most recent call to getUsed.
|
||||
*/
|
||||
void setUsed(queueElementPtr const &element);
|
||||
/**
|
||||
* Get the oldest used element;
|
||||
* @return a shared_ptr to the queue element.
|
||||
* This is null if no used element is available.`
|
||||
*/
|
||||
queueElementPtr & getUsed();
|
||||
/**
|
||||
* Release the element obtained by the most recent call to getUsed.
|
||||
* @param element The element.
|
||||
*/
|
||||
void releaseUsed(queueElementPtr const &element);
|
||||
private:
|
||||
queueElementPtr nullElement;
|
||||
|
||||
@@ -28,11 +28,43 @@ enum MessageType {
|
||||
|
||||
epicsShareExtern std::string getMessageTypeName(MessageType messageType);
|
||||
|
||||
/**
|
||||
* @brief Callback class for passing messages to a requester.
|
||||
*
|
||||
* This is used by many other classes and also extended by other classes.
|
||||
* The request is passed a message and a messageType.
|
||||
* A message is just a string and a messageType is:
|
||||
@code
|
||||
enum MessageType {
|
||||
infoMessage,warningMessage,errorMessage,fatalErrorMessage
|
||||
};
|
||||
@endcode
|
||||
*
|
||||
*/
|
||||
|
||||
class epicsShareClass Requester {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Requester);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~Requester(){}
|
||||
/**
|
||||
* The requester must have a name.
|
||||
* @return The requester's name.
|
||||
*/
|
||||
virtual std::string getRequesterName() = 0;
|
||||
/**
|
||||
*
|
||||
* A message for the requester.
|
||||
* @param message The message.
|
||||
* @param messageType The type of message:
|
||||
@code
|
||||
enum MessageType {
|
||||
infoMessage,warningMessage,errorMessage,fatalErrorMessage
|
||||
};
|
||||
@endcode
|
||||
*/
|
||||
virtual void message(std::string const & message,MessageType messageType) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -25,52 +25,184 @@ namespace epics { namespace pvData {
|
||||
class BitSet;
|
||||
class Field;
|
||||
|
||||
/**
|
||||
* @brief Callback class for serialization.
|
||||
*
|
||||
* This must be provided by code that calls serialize.
|
||||
*/
|
||||
class epicsShareClass SerializableControl {
|
||||
public:
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~SerializableControl(){}
|
||||
/**
|
||||
* Done with this buffer. Flush it.
|
||||
*/
|
||||
virtual void flushSerializeBuffer() =0;
|
||||
/**
|
||||
* Make sure buffer has at least size bytes remaining.
|
||||
* If not flush existing buffer and provide a new one.
|
||||
* @param size The number of bytes.
|
||||
*/
|
||||
virtual void ensureBuffer(std::size_t size) =0;
|
||||
/**
|
||||
* Add pad bytes to buffer.
|
||||
* @param alignment alignment required.
|
||||
*/
|
||||
virtual void alignBuffer(std::size_t alignment) =0;
|
||||
virtual bool directSerialize(ByteBuffer *existingBuffer, const char* toSerialize,
|
||||
std::size_t elementCount, std::size_t elementSize) = 0;
|
||||
virtual void cachedSerialize(std::tr1::shared_ptr<const Field> const & field, ByteBuffer* buffer) = 0;
|
||||
/**
|
||||
* method for serializing array data.
|
||||
* This should only be used for arrays of primitive types.
|
||||
* i. e. boolean,byte,...,double.
|
||||
* It can not be called for string, structure, or union arrays.
|
||||
* @param existingBuffer the existing buffer from the caller.
|
||||
* @param toSerialize location of data to be put into buffer.
|
||||
* @param elementCount number of elements.
|
||||
* @param elementSize element size.
|
||||
*/
|
||||
virtual bool directSerialize(
|
||||
ByteBuffer *existingBuffer,
|
||||
const char* toSerialize,
|
||||
std::size_t elementCount,
|
||||
std::size_t elementSize) = 0;
|
||||
/**
|
||||
* serialize via cache
|
||||
* @param field instance to be serialized
|
||||
* @param buffer buffer to be serialized to
|
||||
*/
|
||||
virtual void cachedSerialize(
|
||||
std::tr1::shared_ptr<const Field> const & field,
|
||||
ByteBuffer* buffer) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Callback class for deserialization.
|
||||
*
|
||||
* This must be provided by code that calls deserialize.
|
||||
*/
|
||||
class epicsShareClass DeserializableControl {
|
||||
public:
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~DeserializableControl(){}
|
||||
/**
|
||||
* Helper method.
|
||||
* Ensures specified size of bytes, provides it if necessary.
|
||||
* @param size The number of bytes.
|
||||
*/
|
||||
virtual void ensureData(std::size_t size) =0;
|
||||
/**
|
||||
* Align buffer.
|
||||
* Note that this takes care only current buffer alignment.
|
||||
* If streaming protocol is used,
|
||||
* care must be taken that entire stream is aligned.
|
||||
* @param alignment size in bytes, must be power of two.
|
||||
*/
|
||||
virtual void alignData(std::size_t alignment) =0;
|
||||
virtual bool directDeserialize(ByteBuffer *existingBuffer, char* deserializeTo,
|
||||
std::size_t elementCount, std::size_t elementSize) = 0;
|
||||
virtual std::tr1::shared_ptr<const Field> cachedDeserialize(ByteBuffer* buffer) = 0;
|
||||
/**
|
||||
* method for deserializing array data.
|
||||
* This should only be used for arrays of primitive types.
|
||||
* i. e. boolean,byte,...,double.
|
||||
* It can not be called for string, structure, or union arrays.
|
||||
* @param existingBuffer the existing buffer from the caller.
|
||||
* @param deserializeTo location of data.
|
||||
* @param elementCount number of elements.
|
||||
* @param elementSize element size.
|
||||
*/
|
||||
virtual bool directDeserialize(
|
||||
ByteBuffer *existingBuffer,
|
||||
char* deserializeTo,
|
||||
std::size_t elementCount,
|
||||
std::size_t elementSize) = 0;
|
||||
/**
|
||||
* deserialize via cache
|
||||
* @param buffer buffer to be deserialized from
|
||||
*/
|
||||
virtual std::tr1::shared_ptr<const Field> cachedDeserialize(
|
||||
ByteBuffer* buffer) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Base class for serialization.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass Serializable {
|
||||
public:
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~Serializable(){}
|
||||
/**
|
||||
* Serialize field into given buffer.
|
||||
* @param buffer serialization buffer.
|
||||
* @param flusher flush interface.
|
||||
*/
|
||||
virtual void serialize(ByteBuffer *buffer,
|
||||
SerializableControl *flusher) const = 0;
|
||||
/**
|
||||
* Deserialize buffer.
|
||||
* @param buffer serialization buffer.
|
||||
* @param flusher deserialization control.
|
||||
*/
|
||||
virtual void deserialize(ByteBuffer *buffer,
|
||||
DeserializableControl *flusher) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Class for serializing bitSets.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass BitSetSerializable {
|
||||
public:
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~BitSetSerializable(){}
|
||||
/**
|
||||
* Serialize field into given buffer.
|
||||
* @param buffer serialization buffer.
|
||||
* @param flusher flush interface.
|
||||
* @param bitSet The bitSet to serialize.
|
||||
*/
|
||||
virtual void serialize(ByteBuffer *buffer,
|
||||
SerializableControl *flusher,BitSet *bitSet) const = 0;
|
||||
/**
|
||||
* Deserialize buffer.
|
||||
* @param buffer serialization buffer.
|
||||
* @param flusher deserialization control.
|
||||
* @param bitSet The bitSet to deserialize.
|
||||
*/
|
||||
virtual void deserialize(ByteBuffer *buffer,
|
||||
DeserializableControl *flusher,BitSet *bitSet) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Class for serializing arrays.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass SerializableArray : public virtual Serializable {
|
||||
public:
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~SerializableArray(){}
|
||||
using Serializable::serialize;
|
||||
virtual void serialize(ByteBuffer *buffer,
|
||||
SerializableControl *flusher, std::size_t offset, std::size_t count) const = 0;
|
||||
/**
|
||||
* Serialize field into given buffer.
|
||||
* @param buffer serialization buffer.
|
||||
* @param flusher flush interface.
|
||||
* @param offset offset in elements.
|
||||
* @param count number of elements
|
||||
*/
|
||||
virtual void serialize(
|
||||
ByteBuffer *buffer,
|
||||
SerializableControl *flusher,
|
||||
std::size_t offset,
|
||||
std::size_t count) const = 0;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* serializeHelper.cpp
|
||||
*
|
||||
* Created on: Oct 22, 2010
|
||||
* Author: Miha vitorovic
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -23,23 +23,33 @@
|
||||
namespace epics {
|
||||
namespace pvData {
|
||||
|
||||
/**
|
||||
* @brief Serialization helper.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass SerializeHelper : public NoDefaultMethods {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Serialize array size.
|
||||
* Serialize the specified array size into the specified
|
||||
* buffer, flushing when necessary.
|
||||
* The specified SerializableControl manages any flushing
|
||||
* required.
|
||||
*
|
||||
* @param[in] s size to encode
|
||||
* @param[in] buffer serialization buffer
|
||||
* @param[in] flusher flusher
|
||||
* @param[in] flusher SerializableControl to manage the flushing
|
||||
*/
|
||||
static void writeSize(std::size_t s, ByteBuffer* buffer,
|
||||
SerializableControl* flusher);
|
||||
|
||||
/**
|
||||
* Deserialize array size.
|
||||
* The specified DeserializableControl ensures
|
||||
* sufficient bytes are available.
|
||||
*
|
||||
* @param[in] buffer deserialization buffer.
|
||||
* @param[in] control the DeserializableControl.
|
||||
* @returns array size.
|
||||
*/
|
||||
static std::size_t readSize(ByteBuffer* buffer,
|
||||
@@ -59,7 +69,7 @@ namespace epics {
|
||||
* std::string serialization helper method.
|
||||
*
|
||||
* @param[in] value std::string to serialize
|
||||
* @param[in] offset start of the substring in {@code value}
|
||||
* @param[in] offset start of the substring in value
|
||||
* @param[in] count the number of characters to write
|
||||
* @param[in] buffer serialization buffer
|
||||
* @param[in] flusher flusher
|
||||
|
||||
@@ -230,7 +230,7 @@ namespace detail {
|
||||
};
|
||||
}
|
||||
|
||||
/** @brief A holder for a contigious piece of memory.
|
||||
/** @brief A holder for a contiguous piece of memory.
|
||||
*
|
||||
* Data is shared, but offset and length are not.
|
||||
* This allows one vector to have access to only a
|
||||
@@ -427,7 +427,7 @@ public:
|
||||
* owner of the data array.
|
||||
*
|
||||
* If a copy is needed, memory is allocated with new[]. If this is
|
||||
* not desireable then do something like the following.
|
||||
* not desirable then do something like the following.
|
||||
@code
|
||||
shared_vector<E> original(...);
|
||||
|
||||
@@ -527,9 +527,12 @@ public:
|
||||
|
||||
};
|
||||
|
||||
//! Specialization for storing untyped pointers
|
||||
//! Does not allow access or iteration of contents
|
||||
//! other than as void* or const void*
|
||||
/**
|
||||
* @brief Specialization for storing untyped pointers.
|
||||
*
|
||||
* Does not allow access or iteration of contents
|
||||
* other than as void* or const void*
|
||||
*/
|
||||
template<typename E>
|
||||
class shared_vector<E, typename meta::is_void<E>::type >
|
||||
: public detail::shared_vector_base<E>
|
||||
@@ -861,7 +864,7 @@ std::ostream& operator<<(std::ostream& strm, const epics::pvData::shared_vector<
|
||||
* The copy constructor and assignment operator allow implicit
|
||||
* casting from type 'shared_vector<T>' to 'shared_vector<const T>'.
|
||||
*
|
||||
* To faciliate safe modification the methods unique() and
|
||||
* To facilitate safe modification the methods unique() and
|
||||
* make_unique() are provided.
|
||||
*
|
||||
* The slice() method selects a sub-set of the shared_vector.
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/**
|
||||
* Status.
|
||||
* @brief Status.
|
||||
*
|
||||
* This is a class for returning status to clients.
|
||||
* @author mse
|
||||
*/
|
||||
class epicsShareClass Status : public epics::pvData::Serializable {
|
||||
|
||||
@@ -47,9 +47,28 @@ typedef std::tr1::shared_ptr<epicsThread> EpicsThreadPtr;
|
||||
|
||||
typedef epicsThreadRunable Runnable;
|
||||
|
||||
/**
|
||||
* @brief C++ wrapper for epicsThread from EPICS base.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass Thread : public epicsThread, private NoDefaultMethods {
|
||||
public:
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructor
|
||||
* @param name thread name.
|
||||
* @param priority priority is one of:
|
||||
@code
|
||||
enum ThreadPriority {
|
||||
lowestPriority, lowerPriority, lowPriority,
|
||||
middlePriority,
|
||||
highPriority, higherPriority, highestPriority
|
||||
};
|
||||
@endcode
|
||||
* @param runnable this is a c function
|
||||
* @param stkcls stack size as specified by epicsThreadStackSizeClass
|
||||
*/
|
||||
Thread(std::string name,
|
||||
ThreadPriority priority,
|
||||
Runnable *runnable,
|
||||
@@ -62,6 +81,21 @@ public:
|
||||
this->start();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructor
|
||||
* @param runnable this is a c function
|
||||
* @name thread name.
|
||||
* @param stkcls stack size as specified by epicsThreadStackSizeClass
|
||||
* @param priority priority is one of:
|
||||
@code
|
||||
enum ThreadPriority {
|
||||
lowestPriority, lowerPriority, lowPriority,
|
||||
middlePriority,
|
||||
highPriority, higherPriority, highestPriority
|
||||
};
|
||||
@endcode
|
||||
*/
|
||||
Thread(Runnable &runnable,
|
||||
std::string name,
|
||||
unsigned int stksize,
|
||||
@@ -74,6 +108,9 @@ public:
|
||||
this->start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Thread()
|
||||
{
|
||||
this->exitWait();
|
||||
|
||||
@@ -21,19 +21,46 @@ class TimeFunction;
|
||||
typedef std::tr1::shared_ptr<TimeFunctionRequester> TimeFunctionRequesterPtr;
|
||||
typedef std::tr1::shared_ptr<TimeFunction> TimeFunctionPtr;
|
||||
|
||||
/**
|
||||
* @brief Class that must be implemented by timeFunction requester.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass TimeFunctionRequester {
|
||||
public:
|
||||
POINTER_DEFINITIONS(TimeFunctionRequester);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~TimeFunctionRequester(){}
|
||||
/**
|
||||
* function to be timed.
|
||||
* It will get called multiple times.
|
||||
*/
|
||||
virtual void function() = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Class for measuring time it takes to execute a function.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass TimeFunction {
|
||||
public:
|
||||
POINTER_DEFINITIONS(TimeFunction);
|
||||
/**
|
||||
* Constructor
|
||||
* @param requester The class that has a function method.
|
||||
*/
|
||||
TimeFunction(TimeFunctionRequesterPtr const & requester);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~TimeFunction();
|
||||
/**
|
||||
* Time the function.
|
||||
* @return the time in seconds to execute the function.
|
||||
* Note that the function may be called many times.
|
||||
*/
|
||||
double timeCall();
|
||||
private:
|
||||
TimeFunctionRequesterPtr requester;
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/convert.h>
|
||||
#include <pv/timer.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
@@ -32,12 +32,28 @@ class Timer;
|
||||
typedef std::tr1::shared_ptr<TimerCallback> TimerCallbackPtr;
|
||||
typedef std::tr1::shared_ptr<Timer> TimerPtr;
|
||||
|
||||
/**
|
||||
* @brief Class that must be implemented by code that makes Timer requests.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass TimerCallback {
|
||||
public:
|
||||
POINTER_DEFINITIONS(TimerCallback);
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
TimerCallback();
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~TimerCallback(){}
|
||||
/**
|
||||
* The method that is called when a timer expires.
|
||||
*/
|
||||
virtual void callback() = 0;
|
||||
/**
|
||||
* The timer has stopped.
|
||||
*/
|
||||
virtual void timerStopped() = 0;
|
||||
private:
|
||||
TimerCallbackPtr next;
|
||||
@@ -47,22 +63,60 @@ private:
|
||||
friend class Timer;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Support for delayed or periodic callback execution.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass Timer : public Runnable {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Timer);
|
||||
/**
|
||||
* Constructor
|
||||
* @param threadName name for the timer thread.
|
||||
* @param priority thread priority
|
||||
*/
|
||||
Timer(std::string threadName, ThreadPriority priority);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~Timer();
|
||||
/**
|
||||
* The thread run method. This is called automatically.
|
||||
*/
|
||||
virtual void run();
|
||||
/**
|
||||
* schedule a callback after a delay.
|
||||
* @param timerCallback the timerCallback instance.
|
||||
* @param delay number of seconds before calling callback.
|
||||
*/
|
||||
void scheduleAfterDelay(
|
||||
TimerCallbackPtr const &timerCallback,
|
||||
double delay);
|
||||
/**
|
||||
* schedule a periodic callback.`
|
||||
* @param timerCallback the timerCallback instance.
|
||||
* @param delay number of seconds before first callback.
|
||||
* @param period time in seconds between each callback.
|
||||
*/
|
||||
void schedulePeriodic(
|
||||
TimerCallbackPtr const &timerCallback,
|
||||
double delay,
|
||||
double period);
|
||||
/**
|
||||
* cancel a callback.
|
||||
* @param timerCallback the timerCallback to cancel.
|
||||
*/
|
||||
void cancel(TimerCallbackPtr const &timerCallback);
|
||||
/**
|
||||
* Is the callback scheduled to be called?
|
||||
* @param timerCallback the timerCallback.
|
||||
* @return (false,true) if (not, is) scheduled.
|
||||
*/
|
||||
bool isScheduled(TimerCallbackPtr const &timerCallback);
|
||||
|
||||
/**
|
||||
* show the elements in the timer queue.
|
||||
* @param o The output stream for the output
|
||||
*/
|
||||
void dump(std::ostream& o);
|
||||
|
||||
private:
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace detail {
|
||||
typedef T return_t;
|
||||
static FORCE_INLINE return_t op(const T& i) { return i; }
|
||||
};
|
||||
// trick std::ostream into treating char's as numbers
|
||||
// trick std::ostream into treating chars as numbers
|
||||
// by promoting char to int
|
||||
template<>
|
||||
struct print_convolute<int8> {
|
||||
@@ -142,7 +142,7 @@ namespace detail {
|
||||
* - float -> double
|
||||
*
|
||||
* Conversions where out of range inputs always produce
|
||||
* a defined result, but may not be reversable.
|
||||
* a defined result, but may not be reversible.
|
||||
*
|
||||
* - double -> float. When abs(value) is outside the range
|
||||
* [FLT_MIN, FLT_MAX] the value is clipped to FLT_MIN or FLT_MAX
|
||||
|
||||
@@ -30,6 +30,8 @@ typedef std::tr1::shared_ptr<Monitor> MonitorPtr;
|
||||
|
||||
|
||||
/**
|
||||
* @brief An element for a monitorQueue.
|
||||
*
|
||||
* Class instance representing monitor element.
|
||||
* @author mrk
|
||||
*/
|
||||
@@ -48,7 +50,9 @@ class epicsShareClass MonitorElement {
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface for Monitor.
|
||||
* @brief Monitor changes to fields of a pvStructure.
|
||||
*
|
||||
* This is used by pvAccess to implement monitors.
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass Monitor : public Destroyable{
|
||||
@@ -73,6 +77,7 @@ class epicsShareClass Monitor : public Destroyable{
|
||||
virtual MonitorElementPtr poll() = 0;
|
||||
/**
|
||||
* Release a MonitorElement that was returned by poll.
|
||||
* A poll() must be called after the release() to check the presence of any modified data.
|
||||
* @param monitorElement
|
||||
*/
|
||||
virtual void release(MonitorElementPtr const & monitorElement) = 0;
|
||||
@@ -80,6 +85,8 @@ class epicsShareClass Monitor : public Destroyable{
|
||||
|
||||
|
||||
/**
|
||||
* @brief Callback implemented by monitor clients.
|
||||
*
|
||||
* Requester for ChannelMonitor.
|
||||
* @author mrk
|
||||
*/
|
||||
|
||||
@@ -20,32 +20,25 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/**
|
||||
* typedef for a pointer to a MonitorPlugin
|
||||
*/
|
||||
class MonitorPlugin;
|
||||
typedef std::tr1::shared_ptr<MonitorPlugin> MonitorPluginPtr;
|
||||
|
||||
|
||||
/**
|
||||
* typedef for a pointer to a MonitorPluginCreator
|
||||
*/
|
||||
class MonitorPluginCreator;
|
||||
typedef std::tr1::shared_ptr<MonitorPluginCreator> MonitorPluginCreatorPtr;
|
||||
|
||||
|
||||
/**
|
||||
* typedef for a pointer to a MonitorPluginManager
|
||||
*/
|
||||
class MonitorPluginManager;
|
||||
typedef std::tr1::shared_ptr<MonitorPluginManager> MonitorPluginManagerPtr;
|
||||
|
||||
|
||||
/** A plugin for raising monitors;
|
||||
/**
|
||||
* @brief A plugin for raising monitors;
|
||||
*
|
||||
* This is for use by pvAccess servers that support monitors.
|
||||
* Since the interface has only a dependence on pvData it
|
||||
* can be used for other purposes.
|
||||
* A monitor is assumed to be associated with a field of a top level
|
||||
* A monitor is assumed to be associated with a field of a top-level
|
||||
* structure.
|
||||
*/
|
||||
class epicsShareClass MonitorPlugin
|
||||
@@ -60,8 +53,8 @@ public:
|
||||
/**
|
||||
* Should a monitor be raised?
|
||||
* @param pvField The field being monitored.
|
||||
* @param pvTop The top level sructure in which the field resides.
|
||||
* @param monitorElement The client data and bitSets.
|
||||
* @param pvTop The top-level structure in which the field resides.
|
||||
* @param monitorElement The client data and bitsets.
|
||||
* @returns true or false.
|
||||
* True is returned if the change to this field should cause a monitor.
|
||||
* False is returned in a change only to this field should not cause a
|
||||
@@ -73,9 +66,6 @@ public:
|
||||
MonitorElementPtr const &monitorElement) = 0;
|
||||
/**
|
||||
* A monitor will be sent to the client.
|
||||
* @param pvField The copy of the field being monitored.
|
||||
* The plugin can modify the data.
|
||||
* @param pvTop The top level sructure in which the field resides.
|
||||
* @param monitorElement The data for the client.
|
||||
* The plugin is allowed to change the data values.
|
||||
*/
|
||||
@@ -100,7 +90,9 @@ public:
|
||||
virtual void endGroupPut() {};
|
||||
};
|
||||
|
||||
/** A class that creates a plugin.
|
||||
/**
|
||||
* @brief A class that creates a plugin.
|
||||
*
|
||||
* Normlly a plugin is created for a single client.
|
||||
*/
|
||||
class epicsShareClass MonitorPluginCreator
|
||||
@@ -110,7 +102,7 @@ public:
|
||||
/**
|
||||
* Create a monitor plugin.
|
||||
* @param field The introspection interface for the field monitored.
|
||||
* @param top The introspsction interface for the client structure.
|
||||
* @param top The introspection interface for the client structure.
|
||||
* @param pvFieldOptions The options the client requested.
|
||||
* The structure has a set of PVString subfields.
|
||||
* The options are a set of name,value pairs.
|
||||
@@ -130,6 +122,8 @@ public:
|
||||
|
||||
|
||||
/**
|
||||
* @brief Manager for plugins.
|
||||
*
|
||||
* This manages a set of monitor plugins.
|
||||
* @author mrk
|
||||
*/
|
||||
|
||||
@@ -18,37 +18,129 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/** @brief enum definition of AlarmSeverity
|
||||
*
|
||||
* AlarmSeverity is:
|
||||
@code
|
||||
enum AlarmSeverity {
|
||||
noAlarm,minorAlarm,majorAlarm,invalidAlarm,undefinedAlarm
|
||||
};
|
||||
@endcode
|
||||
*
|
||||
*/
|
||||
enum AlarmSeverity {
|
||||
noAlarm,minorAlarm,majorAlarm,invalidAlarm,undefinedAlarm
|
||||
};
|
||||
|
||||
/** @brief enum definition of AlarmStatus
|
||||
*
|
||||
* AlarmStatus is:
|
||||
@code
|
||||
enum AlarmStatus {
|
||||
noStatus,deviceStatus,driverStatus,recordStatus,
|
||||
dbStatus,confStatus,undefinedStatus,clientStatus
|
||||
};
|
||||
@endcode
|
||||
*
|
||||
*/
|
||||
enum AlarmStatus {
|
||||
noStatus,deviceStatus,driverStatus,recordStatus,
|
||||
dbStatus,confStatus,undefinedStatus,clientStatus
|
||||
};
|
||||
|
||||
|
||||
/** @brief methods for AlarmSeverity
|
||||
*
|
||||
*/
|
||||
class epicsShareClass AlarmSeverityFunc {
|
||||
public:
|
||||
/**
|
||||
* Get the severity.
|
||||
* @param value Get the alarm severity corresponding to the integer value.
|
||||
* @return The severity.
|
||||
* @throw if severity value is out of range.
|
||||
*/
|
||||
static AlarmSeverity getSeverity(int value);
|
||||
/**
|
||||
* Get the array of severity names.
|
||||
* @return The array of severity names.
|
||||
*/
|
||||
static StringArrayPtr getSeverityNames();
|
||||
};
|
||||
|
||||
/** @brief methods for AlarmStatus
|
||||
*
|
||||
*/
|
||||
class epicsShareClass AlarmStatusFunc {
|
||||
public:
|
||||
/**
|
||||
* Get the status.
|
||||
* @param value Get the alarm status corresponding to the integer value.
|
||||
* @return The status.
|
||||
* @throw if status value is out of range.
|
||||
*/
|
||||
static AlarmStatus getStatus(int value);
|
||||
/**
|
||||
* Get the array of status names.
|
||||
* @return The array of status names.
|
||||
*/
|
||||
static StringArrayPtr getStatusNames();
|
||||
};
|
||||
|
||||
/** @brief Methods for manipulating alarm.
|
||||
*
|
||||
* An alarm structure has the following fields:
|
||||
@code
|
||||
structure
|
||||
int severity
|
||||
int status
|
||||
string message
|
||||
@endcode
|
||||
* This is a class that holds values corresponding to the fields in
|
||||
* an alarm structure.
|
||||
* It is meant to be used together with pvAlarm
|
||||
* which allows values to be copied between an alarm structure
|
||||
* and this class.
|
||||
* This class should not be extended.
|
||||
*/
|
||||
class epicsShareClass Alarm {
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Alarm() : severity(0),status(0), message(std::string("")) {}
|
||||
//default constructors and destructor are OK
|
||||
/**
|
||||
* get the current message.
|
||||
* @return The message.
|
||||
*/
|
||||
std::string getMessage() const {return message;}
|
||||
/**
|
||||
* set the current message.
|
||||
* @param value The new message value.
|
||||
*/
|
||||
void setMessage(std::string const &value) {message = value;}
|
||||
/**
|
||||
* get the current severity.
|
||||
* @return The severity.
|
||||
*/
|
||||
AlarmSeverity getSeverity() const;
|
||||
/**
|
||||
* set the current severity.
|
||||
* @param value The new severity.
|
||||
* @throw if severity value is out of range.
|
||||
*/
|
||||
void setSeverity(AlarmSeverity value) {severity = value;}
|
||||
/**
|
||||
* get the current status.
|
||||
* @return The status.
|
||||
*/
|
||||
AlarmStatus getStatus() const;
|
||||
/**
|
||||
* set the current status.
|
||||
* @param value The new status.
|
||||
* @throw if status value is out of range.
|
||||
*/
|
||||
void setStatus(AlarmStatus value) { status = value;}
|
||||
private:
|
||||
int32 severity;
|
||||
|
||||
@@ -14,15 +14,58 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/** @brief Methods for a control structure.
|
||||
*
|
||||
* An control structure has the following fields:
|
||||
@code
|
||||
structure
|
||||
double limitLow
|
||||
double limitHigh
|
||||
double minStep
|
||||
@endcode
|
||||
* This is a class that holds values corresponding to the fields in
|
||||
* a control structure.
|
||||
* It is meant to be used together with pvControl
|
||||
* which allows values to be copied between an control structure
|
||||
* and this class.
|
||||
* This class should not be extended.
|
||||
*/
|
||||
class epicsShareClass Control {
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Control() : low(0.0), high(0.0), minStep(0.0) {}
|
||||
//default constructors and destructor are OK
|
||||
/**
|
||||
* get limitLow
|
||||
* @return the current value.
|
||||
*/
|
||||
double getLow() const {return low;}
|
||||
/**
|
||||
* get limitHigh
|
||||
* @return the current value.
|
||||
*/
|
||||
double getHigh() const {return high;}
|
||||
/**
|
||||
* get minStep
|
||||
* @return the current value.
|
||||
*/
|
||||
double getMinStep() const {return minStep;}
|
||||
/**
|
||||
* set limitLow
|
||||
* @param value The new value.
|
||||
*/
|
||||
void setLow(double value) {low = value;}
|
||||
/**
|
||||
* set limitHigh
|
||||
* @param value The new value.
|
||||
*/
|
||||
void setHigh(double value) {high = value;}
|
||||
/**
|
||||
* set minStep
|
||||
* @param value The new value.
|
||||
*/
|
||||
void setMinStep(double value) {minStep = value;}
|
||||
private:
|
||||
double low;
|
||||
|
||||
@@ -19,21 +19,83 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/** @brief Methods for a display structure.
|
||||
*
|
||||
* An display structure has the following fields:
|
||||
@code
|
||||
structure
|
||||
double limitLow
|
||||
double limitHigh
|
||||
string description
|
||||
string format
|
||||
string units
|
||||
@endcode
|
||||
* This is a class that holds values corresponding to the fields in
|
||||
* a display structure.
|
||||
* It is meant to be used together with pvDisplay
|
||||
* which allows values to be copied between an display structure
|
||||
* and this class.
|
||||
* This class should not be extended.
|
||||
*/
|
||||
class epicsShareClass Display {
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Display()
|
||||
: description(std::string("")),format(std::string("")),units(std::string("")),
|
||||
low(0.0),high(0.0) {}
|
||||
//default constructors and destructor are OK
|
||||
/**
|
||||
* Get the current value of limitLow.
|
||||
* @return The current value.
|
||||
*/
|
||||
double getLow() const {return low;}
|
||||
/**
|
||||
* Get the current value of limitHigh.
|
||||
* @return The current value.
|
||||
*/
|
||||
double getHigh() const{ return high;}
|
||||
/**
|
||||
* Set limitLow to a new value.
|
||||
* @param value The value.
|
||||
*/
|
||||
void setLow(double value){low = value;}
|
||||
/**
|
||||
* Set limitHigh to a new value.
|
||||
* @param value The value.
|
||||
*/
|
||||
void setHigh(double value){high = value;}
|
||||
/**
|
||||
* Get the current value of description.
|
||||
* @return The current value.
|
||||
*/
|
||||
std::string getDescription() const {return description;}
|
||||
/**
|
||||
* Set description to a new value.
|
||||
* @param value The value.
|
||||
*/
|
||||
void setDescription(std::string const & value) {description = value;}
|
||||
/**
|
||||
* Get the current value of format.
|
||||
* @return The current value.
|
||||
*/
|
||||
std::string getFormat() const {return format;}
|
||||
/**
|
||||
* Set format to a new value.
|
||||
* @param value The value.
|
||||
* The rules for a valid syntax has not been specified.
|
||||
*/
|
||||
void setFormat(std::string const & value) {format = value;}
|
||||
/**
|
||||
* Get the current value of units.
|
||||
* @return The current value.
|
||||
*/
|
||||
std::string getUnits() const {return units;}
|
||||
/**
|
||||
* Set units to a new value.
|
||||
* @param value The value.
|
||||
*/
|
||||
void setUnits(std::string const & value) {units = value;}
|
||||
private:
|
||||
std::string description;
|
||||
|
||||
@@ -28,14 +28,14 @@ bool PVAlarm::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
if(pvField->getField()->getType()!=structure) return false;
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvSeverity = pvStructure->getIntField("severity");
|
||||
pvSeverity = pvStructure->getSubField<PVInt>("severity");
|
||||
if(pvSeverity.get()==NULL) return false;
|
||||
pvStatus = pvStructure->getIntField("status");
|
||||
pvStatus = pvStructure->getSubField<PVInt>("status");
|
||||
if(pvStatus.get()==NULL) {
|
||||
pvSeverity.reset();
|
||||
return false;
|
||||
}
|
||||
pvMessage = pvStructure->getStringField("message");
|
||||
pvMessage = pvStructure->getSubField<PVString>("message");
|
||||
if(pvMessage.get()==NULL) {
|
||||
pvSeverity.reset();
|
||||
pvStatus.reset();
|
||||
|
||||
@@ -20,18 +20,65 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/** @brief Methods for accessing an alarm structure.
|
||||
*
|
||||
* An alarm structure has the following fields:
|
||||
@code
|
||||
structure
|
||||
int severity
|
||||
int status
|
||||
string message
|
||||
@endcode
|
||||
* This class can be attached to an alarm structure field of any
|
||||
* PVData object.
|
||||
* The methods provide access to the fields in the attached structure,
|
||||
* via an instance of class Alarm.
|
||||
* This class should not be extended.
|
||||
*/
|
||||
class epicsShareClass PVAlarm {
|
||||
public:
|
||||
/**
|
||||
*
|
||||
* Constructor
|
||||
*/
|
||||
PVAlarm() {}
|
||||
//default constructors and destructor are OK
|
||||
//returns (false,true) if pvField(isNot, is valid enumerated structure
|
||||
//returns (false,true) if pvField(is not, is) a valid alarm structure
|
||||
//An automatic detach is issued if already attached.
|
||||
/*
|
||||
* Attach to a field of a PVData object.
|
||||
* @param pvField The pvField.
|
||||
* @return (false,true) if the pvField (is not, is) an alarm structure.
|
||||
*/
|
||||
/*
|
||||
* Attach to a field of a PVData object.
|
||||
* @param pvField The pvField.
|
||||
* @return (false,true) if the pvField (is not, is) an alarm structure.
|
||||
*/
|
||||
bool attach(PVFieldPtr const & pvField);
|
||||
/**
|
||||
* Detach for pvField.
|
||||
*/
|
||||
void detach();
|
||||
/**
|
||||
* Is the PVAlarm attached to a pvField?
|
||||
* @return (false,true) (is not,is) attached to a pvField.
|
||||
*/
|
||||
bool isAttached();
|
||||
// each of the following throws logic_error is not attached to PVField
|
||||
// set returns false if field is immutable
|
||||
/**
|
||||
* copy the alarm structure values to Alarm
|
||||
* @param alarm An instance of class Alarm
|
||||
* @throw If not attached to a pvField.
|
||||
*/
|
||||
void get(Alarm & alarm) const;
|
||||
/**
|
||||
* copy the values from Alarm to the alarm structure.
|
||||
* @param alarm An instance of class Alarm
|
||||
* @return (false,true) if pvField (immutable, mutable)
|
||||
* @throw If not attached to a pvField.
|
||||
*/
|
||||
bool set(Alarm const & alarm);
|
||||
private:
|
||||
PVIntPtr pvSeverity;
|
||||
|
||||
@@ -28,14 +28,14 @@ bool PVControl::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
if(pvField->getField()->getType()!=structure) return false;
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvLow = pvStructure->getDoubleField("limitLow");
|
||||
pvLow = pvStructure->getSubField<PVDouble>("limitLow");
|
||||
if(pvLow.get()==NULL) return false;
|
||||
pvHigh = pvStructure->getDoubleField("limitHigh");
|
||||
pvHigh = pvStructure->getSubField<PVDouble>("limitHigh");
|
||||
if(pvHigh.get()==NULL) {
|
||||
pvLow.reset();
|
||||
return false;
|
||||
}
|
||||
pvMinStep = pvStructure->getDoubleField("minStep");
|
||||
pvMinStep = pvStructure->getSubField<PVDouble>("minStep");
|
||||
if(pvMinStep.get()==NULL) {
|
||||
pvLow.reset();
|
||||
pvHigh.reset();
|
||||
|
||||
@@ -17,18 +17,60 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/** @brief Methods for accessing an control structure.
|
||||
*
|
||||
* An control structure has the following fields:
|
||||
@code
|
||||
structure
|
||||
double limitLow
|
||||
double limitHigh
|
||||
double minStep
|
||||
@endcode
|
||||
* This class can be attached to an control structure field of any
|
||||
* PVData object.
|
||||
* The methods provide access to the fields in the attached structure,
|
||||
* via an instance of class Control.
|
||||
* This class should not be extended.
|
||||
*/
|
||||
class epicsShareClass PVControl {
|
||||
public:
|
||||
/**
|
||||
*
|
||||
* Constructor
|
||||
*/
|
||||
PVControl(){}
|
||||
//default constructors and destructor are OK
|
||||
//returns (false,true) if pvField(isNot, is valid enumerated structure
|
||||
//returns (false,true) if pvField(is not, is) a valid control structure
|
||||
//An automatic detach is issued if already attached.
|
||||
/*
|
||||
* Attach to a field of a PVData object.
|
||||
* @param pvField The pvField.
|
||||
* @return (false,true) if the pvField (is not, is) an control structure.
|
||||
*/
|
||||
bool attach(PVFieldPtr const & pvField);
|
||||
/**
|
||||
* Detach for pvField.
|
||||
*/
|
||||
void detach();
|
||||
/**
|
||||
* Is the PVControl attached to a pvField?
|
||||
* @return (false,true) (is not,is) attached to a pvField.
|
||||
*/
|
||||
bool isAttached();
|
||||
// each of the following throws logic_error is not attached to PVField
|
||||
// each of the following throws logic_error if not attached to PVField
|
||||
// set returns false if field is immutable
|
||||
void get(Control &) const;
|
||||
/**
|
||||
* copy the control structure values to Control
|
||||
* @param control An instance of class Control
|
||||
* @throw If not attached to a pvField.
|
||||
*/
|
||||
void get(Control & control) const;
|
||||
/**
|
||||
* copy the values from Control to the control structure.
|
||||
* @param control An instance of class Control
|
||||
* @return (false,true) if pvField (immutable, mutable)
|
||||
* @throw If not attached to a pvField.
|
||||
*/
|
||||
bool set(Control const & control);
|
||||
private:
|
||||
PVDoublePtr pvLow;
|
||||
|
||||
@@ -28,24 +28,24 @@ bool PVDisplay::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
if(pvField->getField()->getType()!=structure) return false;
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvDescription = pvStructure->getStringField("description");
|
||||
pvDescription = pvStructure->getSubField<PVString>("description");
|
||||
if(pvDescription.get()==NULL) return false;
|
||||
pvFormat = pvStructure->getStringField("format");
|
||||
pvFormat = pvStructure->getSubField<PVString>("format");
|
||||
if(pvFormat.get()==NULL) {
|
||||
detach();
|
||||
return false;
|
||||
}
|
||||
pvUnits = pvStructure->getStringField("units");
|
||||
pvUnits = pvStructure->getSubField<PVString>("units");
|
||||
if(pvUnits.get()==NULL) {
|
||||
detach();
|
||||
return false;
|
||||
}
|
||||
pvLow = pvStructure->getDoubleField(string("limitLow"));
|
||||
pvLow = pvStructure->getSubField<PVDouble>(string("limitLow"));
|
||||
if(pvLow.get()==NULL) {
|
||||
detach();
|
||||
return false;
|
||||
}
|
||||
pvHigh = pvStructure->getDoubleField(string("limitHigh"));
|
||||
pvHigh = pvStructure->getSubField<PVDouble>(string("limitHigh"));
|
||||
if(pvHigh.get()==NULL) {
|
||||
detach();
|
||||
return false;
|
||||
|
||||
@@ -20,17 +20,61 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/** @brief Methods for accessing an display structure.
|
||||
*
|
||||
* A display structure has the following fields:
|
||||
@code
|
||||
structure
|
||||
double limitLow
|
||||
double limitHigh
|
||||
string description
|
||||
string format
|
||||
string units
|
||||
@endcode
|
||||
* This class can be attached to a display structure field of any
|
||||
* PVData object.
|
||||
* The methods provide access to the fields in the attached structure,
|
||||
* via an instance of class Display.
|
||||
* This class should not be extended.
|
||||
*/
|
||||
class epicsShareClass PVDisplay {
|
||||
public:
|
||||
/**
|
||||
*
|
||||
* Constructor
|
||||
*/
|
||||
PVDisplay() {}
|
||||
//default constructors and destructor are OK
|
||||
//An automatic detach is issued if already attached.
|
||||
/*
|
||||
* Attach to a field of a PVData object.
|
||||
* @param pvField The pvField.
|
||||
* @return (false,true) if the pvField (is not, is) an display structure.
|
||||
*/
|
||||
bool attach(PVFieldPtr const & pvField);
|
||||
/**
|
||||
* Detach for pvField.
|
||||
*/
|
||||
void detach();
|
||||
/**
|
||||
* Is the PVDisplay attached to a pvField?
|
||||
* @return (false,true) (is not,is) attached to a pvField.
|
||||
*/
|
||||
bool isAttached();
|
||||
// each of the following throws logic_error is not attached to PVField
|
||||
// each of the following throws logic_error if not attached to PVField
|
||||
// a set returns false if field is immutable
|
||||
void get(Display &) const;
|
||||
/**
|
||||
* copy the display structure values to Display
|
||||
* @param display An instance of class Display
|
||||
* @throw If not attached to a pvField.
|
||||
*/
|
||||
void get(Display & display) const;
|
||||
/**
|
||||
* copy the values from Display to the display structure.
|
||||
* @param display An instance of class Display
|
||||
* @return (false,true) if pvField (immutable, mutable)
|
||||
* @throw If not attached to a pvField.
|
||||
*/
|
||||
bool set(Display const & display);
|
||||
private:
|
||||
static std::string noDisplayFound;
|
||||
|
||||
@@ -28,15 +28,14 @@ bool PVEnumerated::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
if(pvField->getField()->getType()!=structure) return false;
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvIndex = pvStructure->getIntField("index");
|
||||
pvIndex = pvStructure->getSubField<PVInt>("index");
|
||||
if(pvIndex.get()==NULL) return false;
|
||||
PVScalarArrayPtr pvScalarArray = pvStructure->getScalarArrayField(
|
||||
"choices",pvString);
|
||||
if(pvScalarArray.get()==NULL) {
|
||||
PVStringArrayPtr pvStringArray = pvStructure->getSubField<PVStringArray>("choices");
|
||||
if(pvStringArray.get()==NULL) {
|
||||
pvIndex.reset();
|
||||
return false;
|
||||
}
|
||||
pvChoices = static_pointer_cast<PVStringArray>(pvScalarArray);
|
||||
pvChoices = pvStringArray;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -74,8 +73,12 @@ string PVEnumerated::getChoice()
|
||||
if(pvIndex.get()==NULL ) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
int index = pvIndex->get();
|
||||
size_t index = pvIndex->get();
|
||||
const PVStringArray::const_svector& data(pvChoices->view());
|
||||
if(/*index<0 ||*/ index>=data.size()) {
|
||||
string nullString;
|
||||
return nullString;
|
||||
}
|
||||
return data[index];
|
||||
}
|
||||
|
||||
|
||||
@@ -19,24 +19,89 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/** @brief Methods for accessing an enumerated structure.
|
||||
*
|
||||
* An enumerated structure has the following fields:
|
||||
@code
|
||||
structure
|
||||
int index
|
||||
string[] choices
|
||||
@endcode
|
||||
* This class can be attached to an enumerated structure field of any
|
||||
* PVData object.
|
||||
* The methods provide access to the fields in the attached structure.
|
||||
* This class should not be extended.
|
||||
*/
|
||||
class epicsShareClass PVEnumerated {
|
||||
public:
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
PVEnumerated() {}
|
||||
//default constructors and destructor are OK
|
||||
//This class should not be extended
|
||||
//returns (false,true) if pvField(isNot, is valid enumerated structure
|
||||
//returns (false,true) if pvField(is not, is) a valid enumerated structure
|
||||
//An automatic detach is issued if already attached.
|
||||
/*
|
||||
* Attach to a field of a PVData object.
|
||||
* @param pvField The pvField.
|
||||
* @return (false,true) if the pvField (is not, is) an enumerated structure.
|
||||
*/
|
||||
bool attach(PVFieldPtr const & pvField);
|
||||
/**
|
||||
* Detach for pvField.
|
||||
*/
|
||||
void detach();
|
||||
/**
|
||||
* Is the PVEnumerated attached to a pvField?
|
||||
* @return (false,true) (is not,is) attached to a pvField.
|
||||
*/
|
||||
bool isAttached();
|
||||
// each of the following throws logic_error is not attached to PVField
|
||||
// a set returns false if field is immutable
|
||||
/**
|
||||
* Set the index.
|
||||
* @param index The new index.
|
||||
* @throw if not attached.
|
||||
* The index will be changed even if it is out of range of size of choices.
|
||||
*/
|
||||
bool setIndex(int32 index);
|
||||
/**
|
||||
* Get the index.
|
||||
* @return The current index.
|
||||
* @throw if not attached.
|
||||
*/
|
||||
int32 getIndex();
|
||||
/**
|
||||
* Get the choice corresponding to current index.
|
||||
* @return The choice. If index is out of range a null string is returned.
|
||||
* @throw if not attached.
|
||||
*/
|
||||
std::string getChoice();
|
||||
/**
|
||||
* Can choices be changed?
|
||||
* @return (false,true) if choices (can not, can) be changed.
|
||||
* @throw if not attached.
|
||||
*/
|
||||
bool choicesMutable();
|
||||
/**
|
||||
* Get the choices.
|
||||
* @return The current index.
|
||||
* @throw if not attached.
|
||||
*/
|
||||
inline PVStringArray::const_svector getChoices(){return pvChoices->view();}
|
||||
/**
|
||||
* Get the size of the choices array.
|
||||
* @return The size.
|
||||
* @throw if not attached.
|
||||
*/
|
||||
int32 getNumberChoices();
|
||||
/**
|
||||
* Get the choices.
|
||||
* @param choices The new value for choices.`
|
||||
* @return (false,true) if choices (was not was) replaced.
|
||||
* @throw if not attached.
|
||||
*/
|
||||
bool setChoices(const StringArray & choices);
|
||||
private:
|
||||
static std::string notFound;
|
||||
|
||||
@@ -30,11 +30,11 @@ bool PVTimeStamp::attach(PVFieldPtr const & pvField)
|
||||
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
|
||||
PVStructure* pvStructure = xxx.get();
|
||||
while(true) {
|
||||
PVLongPtr pvLong = pvStructure->getLongField("secondsPastEpoch");
|
||||
PVLongPtr pvLong = pvStructure->getSubField<PVLong>("secondsPastEpoch");
|
||||
if(pvLong.get()!=NULL) {
|
||||
pvSecs = pvLong;
|
||||
pvNano = pvStructure->getIntField("nanoseconds");
|
||||
pvUserTag = pvStructure->getIntField("userTag");
|
||||
pvNano = pvStructure->getSubField<PVInt>("nanoseconds");
|
||||
pvUserTag = pvStructure->getSubField<PVInt>("userTag");
|
||||
}
|
||||
if(pvSecs.get()!=NULL
|
||||
&& pvNano.get()!=NULL
|
||||
|
||||
@@ -21,19 +21,61 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/** @brief Methods for accessing a timeStamp structure.
|
||||
*
|
||||
* A timeStamp structure has the following fields:
|
||||
@code
|
||||
structure
|
||||
long secondsPastEpoch
|
||||
int nanoseconds
|
||||
int userTag
|
||||
@endcode
|
||||
* This class can be attached to a timeStamp structure field of any
|
||||
* PVData object.
|
||||
* The methods provide access to the fields in the attached structure,
|
||||
* via an instance of class TimeStamp.
|
||||
* This class should not be extended.
|
||||
*/
|
||||
class epicsShareClass PVTimeStamp {
|
||||
public:
|
||||
/**
|
||||
*
|
||||
* Constructor
|
||||
*/
|
||||
PVTimeStamp(){}
|
||||
//default constructors and destructor are OK
|
||||
//This class should not be extended
|
||||
|
||||
//returns (false,true) if pvField(isNot, is valid timeStamp structure
|
||||
//returns (false,true) if pvField(is not, is) a valid timeStamp structure
|
||||
/*
|
||||
* Attach to a field of a PVData object.
|
||||
* @param pvField The pvField.
|
||||
* @return (false,true) if the pvField (is not, is) an timeStamp structure.
|
||||
*/
|
||||
bool attach(PVFieldPtr const & pvField);
|
||||
/**
|
||||
* Detach for pvField.
|
||||
*/
|
||||
void detach();
|
||||
/**
|
||||
* Is the PVTimeStamp attached to a pvField?
|
||||
* @return (false,true) (is not,is) attached to a pvField.
|
||||
*/
|
||||
bool isAttached();
|
||||
// following throw logic_error is not attached to PVField
|
||||
// a set returns false if field is immutable
|
||||
void get(TimeStamp &) const;
|
||||
// following throw logic_error if not attached to PVField
|
||||
// set returns false if field is immutable
|
||||
/**
|
||||
* copy the timeStamp structure values to TimeStamp
|
||||
* @param timeStamp An instance of class TimeStamp
|
||||
* @throw If not attached to a pvField.
|
||||
*/
|
||||
void get(TimeStamp & timeStamp) const;
|
||||
/**
|
||||
* copy the values from TimeStamp to the timeStamp structure.
|
||||
* @param timeStamp An instance of class TimeStamp
|
||||
* @return (false,true) if pvField (immutable, mutable)
|
||||
* @throw If not attached to a pvField.
|
||||
*/
|
||||
bool set(TimeStamp const & timeStamp);
|
||||
private:
|
||||
static std::string noTimeStamp;
|
||||
|
||||
@@ -35,43 +35,158 @@ epicsShareExtern int32 microSecPerSec;
|
||||
epicsShareExtern int32 nanoSecPerSec;
|
||||
epicsShareExtern int64 posixEpochAtEpicsEpoch;
|
||||
|
||||
/** @brief Methods for manipulating timeStamp.
|
||||
*
|
||||
* A timeStamp structure has the following fields:
|
||||
@code
|
||||
structure
|
||||
long secondsPastEpoch
|
||||
int nanoseconds
|
||||
int userTag
|
||||
@endcode
|
||||
* This is a class that holds values corresponding to the fields in
|
||||
* a timeStamp structure.
|
||||
* It is meant to be used together with pvTimeStamp
|
||||
* which allows values to be copied between an timeStamp structure
|
||||
* and this class.
|
||||
* This class should not be extended.
|
||||
*/
|
||||
class epicsShareClass TimeStamp {
|
||||
public:
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
TimeStamp()
|
||||
:secondsPastEpoch(0), nanoseconds(0), userTag(0) {}
|
||||
/**
|
||||
* Constructor
|
||||
* @param secondsPastEpoch seconds since 1970 UTC
|
||||
* @param nanoseconds nanoseconds since secondsPastEpoch
|
||||
* @param userTag application specific
|
||||
*/
|
||||
TimeStamp(int64 secondsPastEpoch,int32 nanoseconds = 0,int32 userTag = 0);
|
||||
//default constructors and destructor are OK
|
||||
//This class should not be extended
|
||||
/**
|
||||
* adjust secondsPastEpoch and nanoseconds so that
|
||||
* 0 <= nanoseconds < nanoSecPerSec
|
||||
*/
|
||||
void normalize();
|
||||
void fromTime_t(const time_t &);
|
||||
void toTime_t(time_t &) const;
|
||||
/**
|
||||
* Set timeStamp from standard C time
|
||||
* @param time time as returned by std::time
|
||||
*/
|
||||
void fromTime_t(const time_t & time);
|
||||
/**
|
||||
* Set time from timeStamp
|
||||
* @param time time as defined by std::time
|
||||
*/
|
||||
void toTime_t(time_t &time) const;
|
||||
/**
|
||||
* Get secondsPastEpoch.
|
||||
* @return The secondsPastEpoch.
|
||||
*/
|
||||
int64 getSecondsPastEpoch() const {return secondsPastEpoch;}
|
||||
/**
|
||||
* Get secondsPastEpoch for EPICS V3.
|
||||
* This is seconds since 1990 UTC.
|
||||
* @return The epics V3 secondsPastEpoch.
|
||||
*/
|
||||
int64 getEpicsSecondsPastEpoch() const {
|
||||
return secondsPastEpoch - posixEpochAtEpicsEpoch;
|
||||
}
|
||||
/**
|
||||
* Get nanoseconds.
|
||||
* @return nanoseconds within timeStamp.
|
||||
*/
|
||||
int32 getNanoseconds() const {return nanoseconds;}
|
||||
/**
|
||||
* Get userTag.
|
||||
* @return userTag.
|
||||
*/
|
||||
int32 getUserTag() const {return userTag;}
|
||||
/**
|
||||
* Set userTag.
|
||||
* @param userTag application specific.
|
||||
*/
|
||||
void setUserTag(int userTag) {this->userTag = userTag;}
|
||||
/**
|
||||
* Set time fields in timeStamp.
|
||||
* Result will be normalized.
|
||||
* @param secondsPastEpoch seconds part of timeStamp.
|
||||
* @param nanoseconds nanoseconds part of timeStamp.
|
||||
*/
|
||||
void put(int64 secondsPastEpoch,int32 nanoseconds = 0) {
|
||||
this->secondsPastEpoch = secondsPastEpoch;
|
||||
this->nanoseconds = nanoseconds;
|
||||
normalize();
|
||||
}
|
||||
/**
|
||||
* Set time fields in timeStamp.
|
||||
* @param milliseconds The number of milliseconds since the epoch.
|
||||
*/
|
||||
void put(int64 milliseconds);
|
||||
/**
|
||||
* Set the timeStamp to the current time.
|
||||
*/
|
||||
void getCurrent();
|
||||
/**
|
||||
* Convert the timeStamp to a double value that is seconds past epoch.
|
||||
* @return seconds past 1970 UTC
|
||||
*/
|
||||
double toSeconds() const ;
|
||||
/**
|
||||
* Standard C++ operator.
|
||||
*/
|
||||
bool operator==(TimeStamp const &) const;
|
||||
/**
|
||||
* Standard C++ operator.
|
||||
*/
|
||||
bool operator!=(TimeStamp const &) const;
|
||||
/**
|
||||
* Standard C++ operator.
|
||||
*/
|
||||
bool operator<=(TimeStamp const &) const;
|
||||
/**
|
||||
* Standard C++ operator.
|
||||
*/
|
||||
bool operator< (TimeStamp const &) const;
|
||||
/**
|
||||
* Standard C++ operator.
|
||||
*/
|
||||
bool operator>=(TimeStamp const &) const;
|
||||
/**
|
||||
* Standard C++ operator.
|
||||
*/
|
||||
bool operator> (TimeStamp const &) const;
|
||||
/**
|
||||
* Return a-b as a double value with units of seconds.
|
||||
* @param a first timeStamp
|
||||
* @param b second timeStamp
|
||||
* @return time difference in seconds.
|
||||
*/
|
||||
static double diff(TimeStamp const & a,TimeStamp const & b);
|
||||
/**
|
||||
* Standard C++ operator.
|
||||
*/
|
||||
TimeStamp & operator+=(int64 seconds);
|
||||
/**
|
||||
* Standard C++ operator.
|
||||
*/
|
||||
TimeStamp & operator-=(int64 seconds);
|
||||
/**
|
||||
* Standard C++ operator.
|
||||
*/
|
||||
TimeStamp & operator+=(double seconds);
|
||||
/**
|
||||
* Standard C++ operator.
|
||||
*/
|
||||
TimeStamp & operator-=(double seconds);
|
||||
int64 getMilliseconds(); // milliseconds since epoch
|
||||
/**
|
||||
* Get number of milliseconds past epoch.
|
||||
* @return milliseconds past epoch.
|
||||
*/
|
||||
int64 getMilliseconds();
|
||||
private:
|
||||
static int64 diffInt(TimeStamp const &left,TimeStamp const &right );
|
||||
int64 secondsPastEpoch;
|
||||
|
||||
237
src/pv/convert.h
237
src/pv/convert.h
@@ -22,40 +22,12 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
bool epicsShareExtern operator==(const PVField&, const PVField&);
|
||||
|
||||
static inline bool operator!=(const PVField& a, const PVField& b)
|
||||
{return !(a==b);}
|
||||
|
||||
|
||||
bool epicsShareExtern operator==(const Field&, const Field&);
|
||||
bool epicsShareExtern operator==(const Scalar&, const Scalar&);
|
||||
bool epicsShareExtern operator==(const ScalarArray&, const ScalarArray&);
|
||||
bool epicsShareExtern operator==(const Structure&, const Structure&);
|
||||
bool epicsShareExtern operator==(const StructureArray&, const StructureArray&);
|
||||
bool epicsShareExtern operator==(const Union&, const Union&);
|
||||
bool epicsShareExtern operator==(const UnionArray&, const UnionArray&);
|
||||
bool epicsShareExtern operator==(const BoundedString&, const BoundedString&);
|
||||
|
||||
static inline bool operator!=(const Field& a, const Field& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const Scalar& a, const Scalar& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const ScalarArray& a, const ScalarArray& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const Structure& a, const Structure& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const StructureArray& a, const StructureArray& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const Union& a, const Union& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const UnionArray& a, const UnionArray& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const BoundedString& a, const BoundedString& b)
|
||||
{return !(a==b);}
|
||||
|
||||
class Convert;
|
||||
typedef std::tr1::shared_ptr<Convert> ConvertPtr;
|
||||
|
||||
/**
|
||||
* @brief Conversion and Copy facility for pvData.
|
||||
*
|
||||
* Convert between numeric types, convert any field to a string,
|
||||
* or convert from a string to a scalar field.
|
||||
* <p>Numeric conversions are between scalar numeric types or between arrays of
|
||||
@@ -74,85 +46,45 @@ static inline bool operator!=(const BoundedString& a, const BoundedString& b)
|
||||
* A scalar field is a numeric field or pvBoolean or pvString.</p>
|
||||
* <p>All from methods put data into a PVField, e.g. from means where the PVField gets it's data.</p>
|
||||
*/
|
||||
|
||||
class Convert;
|
||||
typedef std::tr1::shared_ptr<Convert> ConvertPtr;
|
||||
|
||||
class epicsShareClass Convert {
|
||||
public:
|
||||
static ConvertPtr getConvert();
|
||||
/**
|
||||
* Get the full fieldName for the pvField.
|
||||
* @param builder The builder that will have the result.
|
||||
* @param pvField The pvField.
|
||||
*/
|
||||
void getFullName(std::string *buf,PVFieldPtr const & pvField)
|
||||
{
|
||||
*buf = pvField->getFullName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do fields have the same definition.
|
||||
*
|
||||
* @param First field
|
||||
* @param Second field
|
||||
* @return (false, true) if the fields (are not, are) the same.
|
||||
* Copy from a PVField to another PVField.
|
||||
* This calls one on copyScalar, copyArray, copyStructure.
|
||||
* The two arguments must be compatible.
|
||||
* @param from The source.
|
||||
* @param to The destination
|
||||
* @throws std::invalid_argument if the arguments are not compatible.
|
||||
* @deprecated use "to->copy[Unchecked](*from)" instead
|
||||
*/
|
||||
inline bool equals(PVFieldPtr const &a,PVFieldPtr const &b)
|
||||
{
|
||||
return *a==*b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do fields have the same definition.
|
||||
*
|
||||
* @param First field
|
||||
* @param Second field
|
||||
* @return (false, true) if the fields (are not, are) the same.
|
||||
*/
|
||||
inline bool equals(PVField &a,PVField &b)
|
||||
{
|
||||
return a==b;
|
||||
void copy(PVFieldPtr const & from, PVFieldPtr const & to) {
|
||||
to->copy(*from);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a PVField to a string.
|
||||
* @param buf buffer for the result
|
||||
* @param pv a PVField to convert to a string.
|
||||
* If a PVField is a structure or array be prepared for a very long string.
|
||||
* @param indentLevel indentation level
|
||||
*/
|
||||
inline void getString(std::string *buf,PVFieldPtr const & pvField,int indentLevel)
|
||||
{getString(buf, pvField.get(), indentLevel);}
|
||||
/**
|
||||
* Convert a PVField to a string.
|
||||
* param buf buffer for the result
|
||||
* @param pv The PVField to convert to a string.
|
||||
* If the PVField is a structure or array be prepared for a very long string.
|
||||
* @param buf string that will hold pvField converted to a string,
|
||||
* @param pvField The PVField to convert to a string.
|
||||
*/
|
||||
inline void getString(std::string * buf,PVFieldPtr const & pvField)
|
||||
{getString(buf, pvField.get(), 0);}
|
||||
/**
|
||||
* Convert a PVField to a string.
|
||||
* @param buf buffer for the result
|
||||
* @param pv a PVField to convert to a string.
|
||||
* If a PVField is a structure or array be prepared for a very long string.
|
||||
* @param buf string that will hold pvField converted to a string,
|
||||
* @param pvField The PVField to convert to a string.
|
||||
* @param indentLevel indentation level
|
||||
*/
|
||||
void getString(std::string * buf,PVField const * pvField,int indentLevel);
|
||||
/**
|
||||
* Convert a PVField to a string.
|
||||
* param buf buffer for the result
|
||||
* @param pv The PVField to convert to a string.
|
||||
* If the PVField is a structure or array be prepared for a very long string.
|
||||
*/
|
||||
inline void getString(std::string * buf,PVField const * pvField)
|
||||
{getString(buf, pvField, 0);}
|
||||
/**
|
||||
* Convert from an array of std::string to a PVScalar
|
||||
* Convert from an array of std::string to a PVStructure
|
||||
* @param pv The PV.
|
||||
* @param from The array of std::string value to convert and put into a PV.
|
||||
* @param fromStartIndex The first element if the array of strings.
|
||||
* @return The total number of fields that have been changed.
|
||||
* @throws std::logic_error if the array of std::string does not have a valid values.
|
||||
*/
|
||||
std::size_t fromString(
|
||||
@@ -212,129 +144,7 @@ public:
|
||||
StringArray & to,
|
||||
std::size_t toOffset);
|
||||
/**
|
||||
* Are from and to valid arguments to copy.
|
||||
* This first checks of both arguments have the same Type.
|
||||
* Then calls one of isCopyScalarCompatible,
|
||||
* isCopyArrayCompatible, or isCopyStructureCompatible.
|
||||
* @param from The source.
|
||||
* @param to The destination.
|
||||
* @return (false,true) is the arguments (are not, are) compatible.
|
||||
*/
|
||||
bool isCopyCompatible(FieldConstPtr const & from, FieldConstPtr const & to);
|
||||
/**
|
||||
* Copy from a PVField to another PVField.
|
||||
* This calls one on copyScalar, copyArray, copyStructure.
|
||||
* The two arguments must be compatible.
|
||||
* @param from The source.
|
||||
* @param to The destination
|
||||
* @throws std::invalid_argument if the arguments are not compatible.
|
||||
*/
|
||||
void copy(PVFieldPtr const & from, PVFieldPtr const & to);
|
||||
/**
|
||||
* Are from and to valid arguments to copyScalar.
|
||||
* false will be returned if either argument is not a scalar as defined by Type.isScalar().
|
||||
* If both are scalars the return value is true if any of the following are true.
|
||||
* <ul>
|
||||
* <li>Both arguments are numeric.</li>
|
||||
* <li>Both arguments have the same type.</li>
|
||||
* <li>Either argument is a string.</li>
|
||||
* </ul>
|
||||
* @param from The introspection interface for the from data.
|
||||
* @param to The introspection interface for the to data..
|
||||
* @return (false,true) If the arguments (are not, are) compatible.
|
||||
*/
|
||||
bool isCopyScalarCompatible(
|
||||
ScalarConstPtr const & from,
|
||||
ScalarConstPtr const & to);
|
||||
/**
|
||||
* Copy from a scalar pv to another scalar pv.
|
||||
* @param from the source.
|
||||
* @param to the destination.
|
||||
* @throws std::invalid_argument if the arguments are not compatible.
|
||||
*/
|
||||
void copyScalar(PVScalarPtr const & from, PVScalarPtr const & to);
|
||||
/**
|
||||
* Are from and to valid arguments to copyArray.
|
||||
* The results are like isCopyScalarCompatible except that the tests are made on the elementType.
|
||||
* @param from The from array.
|
||||
* @param to The to array.
|
||||
* @return (false,true) If the arguments (are not, are) compatible.
|
||||
*/
|
||||
bool isCopyScalarArrayCompatible(
|
||||
ScalarArrayConstPtr const & from,
|
||||
ScalarArrayConstPtr const & to);
|
||||
/**
|
||||
* Are from and to valid arguments for copyStructure.
|
||||
* They are only compatible if they have the same Structure description.
|
||||
* @param from from structure.
|
||||
* @param to structure.
|
||||
* @return (false,true) If the arguments (are not, are) compatible.
|
||||
*/
|
||||
bool isCopyStructureCompatible(
|
||||
StructureConstPtr const & from, StructureConstPtr const & to);
|
||||
/**
|
||||
* Copy from a structure pv to another structure pv.
|
||||
* NOTE: Only compatible nodes are copied. This means:
|
||||
* <ul>
|
||||
* <li>For scalar nodes this means that isCopyScalarCompatible is true.</li>
|
||||
* <li>For array nodes this means that isCopyArrayCompatible is true.</li>
|
||||
* <li>For structure nodes this means that isCopyStructureCompatible is true.</li>
|
||||
* <li>Link nodes are not copied.</li>
|
||||
* </ul>
|
||||
* @param from The source.
|
||||
* @param to The destination.
|
||||
* @throws std::invalid_argument if the arguments are not compatible.
|
||||
*/
|
||||
void copyStructure(PVStructurePtr const & from, PVStructurePtr const & to);
|
||||
/**
|
||||
* Are from and to valid for copyStructureArray.
|
||||
* @param from The from StructureArray.
|
||||
* @param to The to StructureArray.
|
||||
* @return (false,true) If the arguments (are not, are) compatible.
|
||||
*/
|
||||
bool isCopyStructureArrayCompatible(
|
||||
StructureArrayConstPtr const & from, StructureArrayConstPtr const & to);
|
||||
/**
|
||||
* Copy from a structure array to another structure array.
|
||||
* @param from The source array.
|
||||
* @param to The destination array.
|
||||
*/
|
||||
void copyStructureArray(
|
||||
PVStructureArrayPtr const & from, PVStructureArrayPtr const & to);
|
||||
/**
|
||||
* Are from and to valid arguments for copyUnion.
|
||||
* They are only compatible if they have the same Union description.
|
||||
* @param from from union.
|
||||
* @param to union.
|
||||
* @return (false,true) If the arguments (are not, are) compatible.
|
||||
*/
|
||||
bool isCopyUnionCompatible(
|
||||
UnionConstPtr const & from, UnionConstPtr const & to);
|
||||
/**
|
||||
* Copy from a union pv to another union pv.
|
||||
* NOTE: Only compatible nodes are copied.
|
||||
* @param from The source.
|
||||
* @param to The destination.
|
||||
* @throws std::invalid_argument if the arguments are not compatible.
|
||||
*/
|
||||
void copyUnion(PVUnionPtr const & from, PVUnionPtr const & to);
|
||||
/**
|
||||
* Are from and to valid for copyUnionArray.
|
||||
* @param from The from UnionArray.
|
||||
* @param to The to UnionArray.
|
||||
* @return (false,true) If the arguments (are not, are) compatible.
|
||||
*/
|
||||
bool isCopyUnionArrayCompatible(
|
||||
UnionArrayConstPtr const & from, UnionArrayConstPtr const & to);
|
||||
/**
|
||||
* Copy from a union array to another union array.
|
||||
* @param from The source array.
|
||||
* @param to The destination array.
|
||||
*/
|
||||
void copyUnionArray(
|
||||
PVUnionArrayPtr const & from, PVUnionArrayPtr const & to);
|
||||
/**
|
||||
* Convert a PV to a <byte>.
|
||||
* Convert a PV to a byte.
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
*/
|
||||
@@ -478,13 +288,6 @@ public:
|
||||
*/
|
||||
inline void fromDouble(PVScalarPtr const & pv, double from) { pv->putFrom<double>(from); }
|
||||
|
||||
/**
|
||||
* Convenience method for implementing dump.
|
||||
* It generates a newline and inserts blanks at the beginning of the newline.
|
||||
* @param builder The std::string * being constructed.
|
||||
* @param indentLevel Indent level, Each level is four spaces.
|
||||
*/
|
||||
void newLine(std::string * buf, int indentLevel);
|
||||
};
|
||||
|
||||
static inline ConvertPtr getConvert() { return Convert::getConvert(); }
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
#ifndef PRINTER_H
|
||||
#define PRINTER_H
|
||||
|
||||
#include <ostream>
|
||||
#include <shareLib.h>
|
||||
|
||||
#include "pvData.h"
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class PrinterBase
|
||||
{
|
||||
public:
|
||||
virtual void setStream(std::ostream&);
|
||||
virtual void clearStream();
|
||||
|
||||
virtual void print(const PVField&);
|
||||
|
||||
protected:
|
||||
PrinterBase();
|
||||
virtual ~PrinterBase()=0;
|
||||
|
||||
virtual void beginStructure(const PVStructure&);
|
||||
virtual void endStructure(const PVStructure&);
|
||||
|
||||
virtual void beginStructureArray(const PVStructureArray&);
|
||||
virtual void endStructureArray(const PVStructureArray&);
|
||||
|
||||
virtual void beginUnion(const PVUnion&);
|
||||
virtual void endUnion(const PVUnion&);
|
||||
|
||||
virtual void beginUnionArray(const PVUnionArray&);
|
||||
virtual void endUnionArray(const PVUnionArray&);
|
||||
|
||||
virtual void encodeScalar(const PVScalar&);
|
||||
virtual void encodeArray(const PVScalarArray&);
|
||||
virtual void encodeNull();
|
||||
|
||||
inline std::ostream& S() { return *strm; }
|
||||
|
||||
void impl_print(const PVField&);
|
||||
private:
|
||||
std::ostream *strm;
|
||||
};
|
||||
|
||||
class PrinterPlain : public PrinterBase
|
||||
{
|
||||
size_t ilvl;
|
||||
protected:
|
||||
virtual void beginStructure(const PVStructure&);
|
||||
virtual void endStructure(const PVStructure&);
|
||||
|
||||
virtual void beginStructureArray(const PVStructureArray&);
|
||||
virtual void endStructureArray(const PVStructureArray&);
|
||||
|
||||
virtual void beginUnion(const PVUnion&);
|
||||
virtual void endUnion(const PVUnion&);
|
||||
|
||||
virtual void beginUnionArray(const PVUnionArray&);
|
||||
virtual void endUnionArray(const PVUnionArray&);
|
||||
|
||||
virtual void encodeScalar(const PVScalar&);
|
||||
virtual void encodeArray(const PVScalarArray&);
|
||||
virtual void encodeNull();
|
||||
|
||||
public:
|
||||
PrinterPlain();
|
||||
virtual ~PrinterPlain();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // PRINTER_H
|
||||
480
src/pv/pvData.h
480
src/pv/pvData.h
@@ -33,6 +33,14 @@
|
||||
typedef class std::ios std::ios_base;
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !(defined(__vxworks) && !defined(_WRS_VXWORKS_MAJOR))
|
||||
#define USAGE_DEPRECATED __attribute__((deprecated))
|
||||
#define USAGE_ERROR(MSG) __attribute__((error(MSG)))
|
||||
#else
|
||||
#define USAGE_DEPRECATED
|
||||
#define USAGE_ERROR(MSG) { throw std::runtime_error(MSG); }
|
||||
#endif
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class PostHandler;
|
||||
@@ -122,7 +130,8 @@ class PVDataCreate;
|
||||
typedef std::tr1::shared_ptr<PVDataCreate> PVDataCreatePtr;
|
||||
|
||||
/**
|
||||
* This class is implemented by code that calls setPostHander
|
||||
* @brief This class is implemented by code that calls setPostHander
|
||||
*
|
||||
*/
|
||||
class epicsShareClass PostHandler
|
||||
{
|
||||
@@ -133,13 +142,14 @@ public:
|
||||
*/
|
||||
virtual ~PostHandler(){}
|
||||
/**
|
||||
* This is called evertime postPut is called for this field.
|
||||
* This is called every time postPut is called for this field.
|
||||
*/
|
||||
virtual void postPut() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* PVField is the base class for each PVData field.
|
||||
* @brief PVField is the base class for each PVData field.
|
||||
*
|
||||
* Each PVData field has an interface that extends PVField.
|
||||
*/
|
||||
class epicsShareClass PVField
|
||||
@@ -158,19 +168,19 @@ public:
|
||||
virtual ~PVField();
|
||||
/**
|
||||
* Get the fieldName for this field.
|
||||
* @return The name or empty string if top level field.
|
||||
* @return The name or empty string if top-level field.
|
||||
*/
|
||||
inline const std::string& getFieldName() const {return fieldName;}
|
||||
/**
|
||||
* Fully expand the name of this field using the
|
||||
* names of its parent fields with a dot '.' seperating
|
||||
* names of its parent fields with a dot '.' separating
|
||||
* each name.
|
||||
*/
|
||||
std::string getFullName() const;
|
||||
/**
|
||||
* Get offset of the PVField field within top level structure.
|
||||
* Get offset of the PVField field within top-level structure.
|
||||
* Every field within the PVStructure has a unique offset.
|
||||
* The top level structure has an offset of 0.
|
||||
* The top-level structure has an offset of 0.
|
||||
* The first field within the structure has offset equal to 1.
|
||||
* The other offsets are determined by recursively traversing each structure of the tree.
|
||||
* @return The offset.
|
||||
@@ -194,8 +204,8 @@ public:
|
||||
*/
|
||||
bool isImmutable() const;
|
||||
/**
|
||||
* Set the field to be immutable, i. e. it can no longer be modified.
|
||||
* This is permanent, i.e. once done the field can onot be made mutable.
|
||||
* Set the field to be immutable, i.e. it can no longer be modified.
|
||||
* This is permanent, i.e. once done the field cannot be made mutable.
|
||||
*/
|
||||
virtual void setImmutable();
|
||||
/**
|
||||
@@ -231,12 +241,15 @@ public:
|
||||
*/
|
||||
virtual std::ostream& dumpValue(std::ostream& o) const = 0;
|
||||
|
||||
void copy(const PVField& from);
|
||||
void copyUnchecked(const PVField& from);
|
||||
|
||||
protected:
|
||||
PVField::shared_pointer getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
PVField(FieldConstPtr field);
|
||||
explicit PVField(FieldConstPtr field);
|
||||
void setParentAndName(PVStructure *parent, std::string const & fieldName);
|
||||
private:
|
||||
static void computeOffset(const PVField *pvField);
|
||||
@@ -256,7 +269,8 @@ private:
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, const PVField& f);
|
||||
|
||||
/**
|
||||
* PVScalar is the base class for each scalar field.
|
||||
* @brief PVScalar is the base class for each scalar field.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass PVScalar : public PVField {
|
||||
// friend our child class(s) so that it
|
||||
@@ -317,12 +331,16 @@ public:
|
||||
|
||||
virtual void assign(const PVScalar&) = 0;
|
||||
|
||||
virtual void copy(const PVScalar& from) = 0;
|
||||
virtual void copyUnchecked(const PVScalar& from) = 0;
|
||||
|
||||
protected:
|
||||
PVScalar(ScalarConstPtr const & scalar);
|
||||
explicit PVScalar(ScalarConstPtr const & scalar);
|
||||
};
|
||||
|
||||
/**
|
||||
* Class that holds the data for each posssible scalar type.
|
||||
* @brief Class that holds the data for each possible scalar type.
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
class epicsShareClass PVScalarValue : public PVScalar {
|
||||
@@ -345,7 +363,7 @@ public:
|
||||
virtual T get() const = 0;
|
||||
/**
|
||||
* Put a new value into the PVScalar.
|
||||
* @param The value.
|
||||
* @param value The value.
|
||||
*/
|
||||
virtual void put(T value) = 0;
|
||||
|
||||
@@ -381,8 +399,27 @@ public:
|
||||
put(castUnsafe<T,T1>(val));
|
||||
}
|
||||
|
||||
virtual void assign(const PVScalar& scalar)
|
||||
{
|
||||
if(isImmutable())
|
||||
throw std::invalid_argument("destination is immutable");
|
||||
copyUnchecked(scalar);
|
||||
}
|
||||
virtual void copy(const PVScalar& from)
|
||||
{
|
||||
assign(from);
|
||||
}
|
||||
virtual void copyUnchecked(const PVScalar& from)
|
||||
{
|
||||
if(this==&from)
|
||||
return;
|
||||
T result;
|
||||
from.getAs((void*)&result, typeCode);
|
||||
put(result);
|
||||
}
|
||||
|
||||
protected:
|
||||
PVScalarValue(ScalarConstPtr const & scalar)
|
||||
explicit PVScalarValue(ScalarConstPtr const & scalar)
|
||||
: PVScalar(scalar) {}
|
||||
virtual void getAs(void * result, ScalarType rtype) const
|
||||
{
|
||||
@@ -395,16 +432,6 @@ protected:
|
||||
castUnsafeV(1, typeCode, (void*)&result, stype, src);
|
||||
put(result);
|
||||
}
|
||||
virtual void assign(const PVScalar& scalar)
|
||||
{
|
||||
if(this==&scalar)
|
||||
return;
|
||||
if(isImmutable())
|
||||
throw std::invalid_argument("Destination is immutable");
|
||||
T result;
|
||||
scalar.getAs((void*)&result, typeCode);
|
||||
put(result);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class PVDataCreate;
|
||||
@@ -437,7 +464,8 @@ typedef std::tr1::shared_ptr<PVFloat> PVFloatPtr;
|
||||
typedef std::tr1::shared_ptr<PVDouble> PVDoublePtr;
|
||||
|
||||
/**
|
||||
* PVString is special case, since it implements SerializableArray
|
||||
* @brief PVString is special case, since it implements SerializableArray
|
||||
*
|
||||
*/
|
||||
class epicsShareClass PVString : public PVScalarValue<std::string>, SerializableArray {
|
||||
public:
|
||||
@@ -446,14 +474,18 @@ public:
|
||||
*/
|
||||
virtual ~PVString() {}
|
||||
protected:
|
||||
PVString(ScalarConstPtr const & scalar)
|
||||
explicit PVString(ScalarConstPtr const & scalar)
|
||||
: PVScalarValue<std::string>(scalar) {}
|
||||
};
|
||||
typedef std::tr1::shared_ptr<PVString> PVStringPtr;
|
||||
|
||||
|
||||
/**
|
||||
* PVArray is the base class for all array types, i.e. the scalarArray types and structureArray.
|
||||
* @brief PVArray is the base class for all array types.
|
||||
*
|
||||
* The array types are unionArray, strucrtureArray and scalarArray.
|
||||
* There is a scalarArray type for each scalarType.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass PVArray : public PVField, public SerializableArray {
|
||||
public:
|
||||
@@ -472,8 +504,8 @@ public:
|
||||
*/
|
||||
virtual ArrayConstPtr getArray() const = 0;
|
||||
/**
|
||||
* Set the field to be immutable, i. e. it can no longer be modified.
|
||||
* This is permanent, i.e. once done the field can onot be made mutable.
|
||||
* Set the field to be immutable, i.e. it can no longer be modified.
|
||||
* This is permanent, i.e. once done the field cannot be made mutable.
|
||||
*/
|
||||
virtual void setImmutable();
|
||||
/**
|
||||
@@ -483,7 +515,7 @@ public:
|
||||
virtual std::size_t getLength() const = 0;
|
||||
/**
|
||||
* Set the array length.
|
||||
* @param The length.
|
||||
* @param length The length.
|
||||
*/
|
||||
virtual void setLength(std::size_t length) = 0;
|
||||
/**
|
||||
@@ -503,7 +535,7 @@ public:
|
||||
void setCapacityMutable(bool isMutable);
|
||||
/**
|
||||
* Set the array capacity.
|
||||
* @param The capacity.
|
||||
* @param capacity The capacity.
|
||||
*/
|
||||
virtual void setCapacity(std::size_t capacity) = 0;
|
||||
|
||||
@@ -511,7 +543,7 @@ public:
|
||||
virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const = 0;
|
||||
|
||||
protected:
|
||||
PVArray(FieldConstPtr const & field);
|
||||
explicit PVArray(FieldConstPtr const & field);
|
||||
void checkLength(size_t length);
|
||||
private:
|
||||
bool capacityMutable;
|
||||
@@ -520,9 +552,9 @@ private:
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(format::array_at_internal const& manip, const PVArray& array);
|
||||
|
||||
|
||||
/**
|
||||
* Base class for a scalarArray.
|
||||
* @brief Base class for a scalarArray.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass PVScalarArray : public PVArray {
|
||||
public:
|
||||
@@ -570,7 +602,7 @@ public:
|
||||
* A copy and element-wise conversion is performed unless
|
||||
* the element type of the PVScalarArray matches the
|
||||
* type of the provided data.
|
||||
* If the types do match then a new refernce to the provided
|
||||
* If the types do match then a new reference to the provided
|
||||
* data is kept.
|
||||
*
|
||||
* Calls postPut()
|
||||
@@ -588,22 +620,38 @@ public:
|
||||
* A copy and element-wise conversion is performed unless
|
||||
* the element type of the PVScalarArray matches the
|
||||
* type of the provided data.
|
||||
* If the types do match then a new refernce to the provided
|
||||
* If the types do match then a new reference to the provided
|
||||
* data is kept.
|
||||
*/
|
||||
void assign(PVScalarArray& pv) {
|
||||
void assign(const PVScalarArray& pv) {
|
||||
if (isImmutable())
|
||||
throw std::invalid_argument("destination is immutable");
|
||||
copyUnchecked(pv);
|
||||
}
|
||||
|
||||
void copy(const PVScalarArray& from) {
|
||||
assign(from);
|
||||
}
|
||||
|
||||
void copyUnchecked(const PVScalarArray& from) {
|
||||
if (this==&from)
|
||||
return;
|
||||
shared_vector<const void> temp;
|
||||
pv._getAsVoid(temp);
|
||||
from._getAsVoid(temp);
|
||||
_putFromVoid(temp);
|
||||
}
|
||||
|
||||
protected:
|
||||
PVScalarArray(ScalarArrayConstPtr const & scalarArray);
|
||||
explicit PVScalarArray(ScalarArrayConstPtr const & scalarArray);
|
||||
private:
|
||||
friend class PVDataCreate;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Data interface for a structure,
|
||||
*
|
||||
*/
|
||||
class epicsShareClass PVStructure : public PVField, public BitSetSerializable
|
||||
{
|
||||
public:
|
||||
@@ -615,8 +663,8 @@ public:
|
||||
typedef PVStructure & reference;
|
||||
typedef const PVStructure & const_reference;
|
||||
/**
|
||||
* Set the field to be immutable, i. e. it can no longer be modified.
|
||||
* This is permanent, i.e. once done the field can onot be made mutable.
|
||||
* Set the field to be immutable, i.e. it can no longer be modified.
|
||||
* This is permanent, i.e. once done the field cannot be made mutable.
|
||||
*/
|
||||
virtual void setImmutable();
|
||||
/**
|
||||
@@ -636,23 +684,42 @@ public:
|
||||
*/
|
||||
PVFieldPtr getSubField(std::string const &fieldName) const;
|
||||
|
||||
/**
|
||||
* Get a subfield with the specified name.
|
||||
* @param fieldName a '.' separated list of child field names (no whitespace allowed)
|
||||
* @returns A pointer to the sub-field or null if field does not exist or has a different type
|
||||
* @code
|
||||
* PVIntPtr ptr = pvStruct->getSubField<PVInt>("substruct.leaffield");
|
||||
* @endcode
|
||||
*/
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getSubField(std::string const &fieldName) const
|
||||
FORCE_INLINE std::tr1::shared_ptr<PVT> getSubField(std::string const &fieldName) const
|
||||
{
|
||||
PVFieldPtr pvField = getSubField(fieldName);
|
||||
if (pvField.get())
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(pvField);
|
||||
return this->getSubField<PVT>(fieldName.c_str());
|
||||
}
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getSubField(const char *name) const
|
||||
{
|
||||
PVField *raw = getSubFieldImpl(name, false);
|
||||
if (raw)
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(raw->shared_from_this());
|
||||
else
|
||||
return std::tr1::shared_ptr<PVT>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the subfield with the specified offset.
|
||||
* @param fieldOffset The offset.
|
||||
* @return Pointer to the field or null if field does not exist.
|
||||
*/
|
||||
PVFieldPtr getSubField(std::size_t fieldOffset) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get the subfield with the specified offset.
|
||||
* @param fieldOffset The offset.
|
||||
* @return Pointer to the field or null if field does not exist.
|
||||
*/
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getSubField(std::size_t fieldOffset) const
|
||||
{
|
||||
@@ -664,127 +731,51 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a boolean field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
* Get a subfield with the specified name.
|
||||
* @param fieldName a '.' separated list of child field names (no whitespace allowed)
|
||||
* @returns A reference to the sub-field (never NULL)
|
||||
* @throws std::runtime_error if the requested sub-field doesn't exist, or has a different type
|
||||
*/
|
||||
PVBooleanPtr getBooleanField(std::string const &fieldName) ;
|
||||
FORCE_INLINE PVFieldPtr getSubFieldT(std::string const &fieldName) const
|
||||
{
|
||||
return getSubFieldImpl(fieldName.c_str())->shared_from_this();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a byte field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
* Get a subfield with the specified name.
|
||||
* @param fieldName a '.' separated list of child field names (no whitespace allowed)
|
||||
* @returns A reference to the sub-field (never NULL)
|
||||
* @throws std::runtime_error if the requested sub-field doesn't exist, or has a different type
|
||||
* @code
|
||||
* PVIntPtr ptr = pvStruct->getSubFieldT<PVInt>("substruct.leaffield");
|
||||
* @endcode
|
||||
*/
|
||||
PVBytePtr getByteField(std::string const &fieldName) ;
|
||||
template<typename PVT>
|
||||
FORCE_INLINE std::tr1::shared_ptr<PVT> getSubFieldT(std::string const &fieldName) const
|
||||
{
|
||||
return this->getSubFieldT<PVT>(fieldName.c_str());
|
||||
}
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getSubFieldT(const char *name) const;
|
||||
|
||||
/**
|
||||
* Get a short field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
* Get the subfield with the specified offset.
|
||||
* @param fieldOffset The offset.
|
||||
* @returns A reference to the sub-field (never NULL)
|
||||
* @throws std::runtime_error if the requested sub-field doesn't exist
|
||||
*/
|
||||
PVShortPtr getShortField(std::string const &fieldName) ;
|
||||
PVFieldPtr getSubFieldT(std::size_t fieldOffset) const;
|
||||
|
||||
/**
|
||||
* Get a int field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
* Get the subfield with the specified offset.
|
||||
* @param fieldOffset The offset.
|
||||
* @returns A reference to the sub-field (never NULL)
|
||||
* @throws std::runtime_error if the requested sub-field doesn't exist, or has a different type
|
||||
*/
|
||||
PVIntPtr getIntField(std::string const &fieldName) ;
|
||||
/**
|
||||
* Get a long field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVLongPtr getLongField(std::string const &fieldName) ;
|
||||
/**
|
||||
* Get an unsigned byte field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVUBytePtr getUByteField(std::string const &fieldName) ;
|
||||
/**
|
||||
* Get an unsigned short field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVUShortPtr getUShortField(std::string const &fieldName) ;
|
||||
/**
|
||||
* Get an unsigned int field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVUIntPtr getUIntField(std::string const &fieldName) ;
|
||||
/**
|
||||
* Get an unsigned long field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVULongPtr getULongField(std::string const &fieldName) ;
|
||||
/**
|
||||
* Get a float field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVFloatPtr getFloatField(std::string const &fieldName) ;
|
||||
/**
|
||||
* Get a double field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVDoublePtr getDoubleField(std::string const &fieldName) ;
|
||||
/**
|
||||
* Get a string field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVStringPtr getStringField(std::string const &fieldName) ;
|
||||
|
||||
/**
|
||||
* Get a structure field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVStructurePtr getStructureField(std::string const &fieldName) ;
|
||||
/**
|
||||
* Get a union field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVUnionPtr getUnionField(std::string const &fieldName) ;
|
||||
/**
|
||||
* Get a scalarArray field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @param elementType The element type.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVScalarArrayPtr getScalarArrayField(
|
||||
std::string const &fieldName,ScalarType elementType) ;
|
||||
/**
|
||||
* Get a structureArray field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVStructureArrayPtr getStructureArrayField(std::string const &fieldName) ;
|
||||
/**
|
||||
* Get a unionArray field with the specified name.
|
||||
* No longer needed. Use templete version of getSubField
|
||||
* @param fieldName The name of the field to get.
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVUnionArrayPtr getUnionArrayField(std::string const &fieldName) ;
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getSubFieldT(std::size_t fieldOffset) const;
|
||||
|
||||
/**
|
||||
* Serialize.
|
||||
* @param pbuffer The byte buffer.
|
||||
@@ -819,7 +810,7 @@ public:
|
||||
* Constructor
|
||||
* @param structure The introspection interface.
|
||||
*/
|
||||
PVStructure(StructureConstPtr const & structure);
|
||||
explicit PVStructure(StructureConstPtr const & structure);
|
||||
/**
|
||||
* Constructor
|
||||
* @param structure The introspection interface.
|
||||
@@ -829,7 +820,14 @@ public:
|
||||
|
||||
virtual std::ostream& dumpValue(std::ostream& o) const;
|
||||
|
||||
void copy(const PVStructure& from);
|
||||
|
||||
void copyUnchecked(const PVStructure& from);
|
||||
void copyUnchecked(const PVStructure& from, const BitSet& maskBitSet, bool inverse = false);
|
||||
|
||||
private:
|
||||
PVField *getSubFieldImpl(const char *name, bool throws = true) const;
|
||||
|
||||
static PVFieldPtr nullPVField;
|
||||
static PVBooleanPtr nullPVBoolean;
|
||||
static PVBytePtr nullPVByte;
|
||||
@@ -856,8 +854,43 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> PVStructure::getSubFieldT(const char *name) const
|
||||
{
|
||||
std::tr1::shared_ptr<PVT> pvField = std::tr1::dynamic_pointer_cast<PVT>(
|
||||
getSubFieldImpl(name)->shared_from_this());
|
||||
|
||||
if (pvField.get())
|
||||
return pvField;
|
||||
else
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field: " << name << " (Field has wrong type)";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> PVStructure::getSubFieldT(std::size_t fieldOffset) const
|
||||
{
|
||||
std::tr1::shared_ptr<PVT> pvField = std::tr1::dynamic_pointer_cast<PVT>(
|
||||
getSubFieldT(fieldOffset));
|
||||
if (pvField.get())
|
||||
return pvField;
|
||||
else
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field with offset "
|
||||
<< fieldOffset << " (Field has wrong type)";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PVUnion has a single subfield which has a type specified by a union introspection interface.
|
||||
* @brief PVUnion has a single subfield.
|
||||
*
|
||||
* The type for the subfield is specified by a union introspection interface.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass PVUnion : public PVField
|
||||
{
|
||||
@@ -873,7 +906,7 @@ public:
|
||||
/**
|
||||
* Undefined index.
|
||||
* Default value upon PVUnion construction. Can be set by the user.
|
||||
* Corresponds to {@code null} value.
|
||||
* Corresponds to @c null value.
|
||||
*/
|
||||
static int32 UNDEFINED_INDEX;
|
||||
|
||||
@@ -884,8 +917,8 @@ public:
|
||||
UnionConstPtr getUnion() const;
|
||||
|
||||
/**
|
||||
* Get the {@code PVField} value stored in the field.
|
||||
* @return {@code PVField} value of field, {@code null} if {@code getSelectedIndex() == UNDEFINED_INDEX}.
|
||||
* Get the @c PVField value stored in the field.
|
||||
* @return @c PVField value of field, @c null if {@code getSelectedIndex() == UNDEFINED_INDEX}.
|
||||
*/
|
||||
PVFieldPtr get() const;
|
||||
|
||||
@@ -897,8 +930,8 @@ public:
|
||||
/**
|
||||
* Select field (set index) and get the field at the index.
|
||||
* @param index index of the field to select.
|
||||
* @return corresponding PVField (of undetermined value), {@code null} if {@code index == UNDEFINED_INDEX}.
|
||||
* @throws {@code std::invalid_argument} if index is invalid (out of range).
|
||||
* @return corresponding PVField (of undetermined value), @c null if {@code index == UNDEFINED_INDEX}.
|
||||
* @throws std::invalid_argument if index is invalid (out of range).
|
||||
*/
|
||||
PVFieldPtr select(int32 index);
|
||||
|
||||
@@ -911,7 +944,7 @@ public:
|
||||
* Select field (set index) and get the field by given name.
|
||||
* @param fieldName the name of the field to select.
|
||||
* @return corresponding PVField (of undetermined value).
|
||||
* @throws {@code std::invalid_argument} if field does not exist.
|
||||
* @throws std::invalid_argument if field does not exist.
|
||||
*/
|
||||
PVFieldPtr select(std::string const & fieldName);
|
||||
|
||||
@@ -933,27 +966,30 @@ public:
|
||||
std::string getSelectedFieldName() const;
|
||||
|
||||
/**
|
||||
* Set the {@code PVField} (by reference!) as selected field.
|
||||
* If a value is not a valid union field an {@code std::invalid_argument} exception is thrown.
|
||||
* Set the @c PVField (by reference!) as selected field.
|
||||
* If a value is not a valid union field an @c std::invalid_argument
|
||||
* exception is thrown.
|
||||
* @param value the field to set.
|
||||
*/
|
||||
void set(PVFieldPtr const & value);
|
||||
/**
|
||||
* Set the {@code PVField} (by reference!) as field at given index.
|
||||
* If a value is not a valid union field an {@code std::invalid_argument} exception is thrown.
|
||||
* Use {@code select(int)} to put by value.
|
||||
* Set the @c PVField (by reference!) as field at given index.
|
||||
* If a value is not a valid union field an @c std::invalid_argument
|
||||
* exception is thrown.
|
||||
* Use @c select(int32) to put by value.
|
||||
* @param index index of a field to put.
|
||||
* @param value the field to set.
|
||||
* @see #select(int)
|
||||
* @see #select(int32)
|
||||
*/
|
||||
void set(int32 index, PVFieldPtr const & value);
|
||||
/**
|
||||
* Set the {@code PVField} (by reference!) as field by given name.
|
||||
* If a value is not a valid union field an {@code std::invalid_argument} exception is thrown.
|
||||
* Use {@code select(std::string)} to put by value.
|
||||
* Set the @c PVField (by reference!) as field by given name.
|
||||
* If a value is not a valid union field an @c std::invalid_argument
|
||||
* exception is thrown.
|
||||
* Use @c select(std::string const &) to put by value.
|
||||
* @param fieldName Name of the field to put.
|
||||
* @param value the field to set.
|
||||
* @see #select(std::string)
|
||||
* @see #select(std::string const &)
|
||||
*/
|
||||
void set(std::string const & fieldName, PVFieldPtr const & value);
|
||||
|
||||
@@ -975,11 +1011,16 @@ public:
|
||||
* Constructor
|
||||
* @param punion The introspection interface.
|
||||
*/
|
||||
PVUnion(UnionConstPtr const & punion);
|
||||
explicit PVUnion(UnionConstPtr const & punion);
|
||||
|
||||
virtual std::ostream& dumpValue(std::ostream& o) const;
|
||||
|
||||
void copy(const PVUnion& from);
|
||||
void copyUnchecked(const PVUnion& from);
|
||||
|
||||
private:
|
||||
static PVDataCreatePtr pvDataCreate;
|
||||
|
||||
friend class PVDataCreate;
|
||||
UnionConstPtr unionPtr;
|
||||
|
||||
@@ -1018,11 +1059,11 @@ namespace detail {
|
||||
PVVectorStorage() : Base() {}
|
||||
|
||||
template<typename A>
|
||||
PVVectorStorage(A a) : Base(a) {}
|
||||
explicit PVVectorStorage(A a) : Base(a) {}
|
||||
public:
|
||||
virtual ~PVVectorStorage(){};
|
||||
|
||||
// Primative array manipulations
|
||||
// Primitive array manipulations
|
||||
|
||||
//! Fetch a read-only view of the current array data
|
||||
virtual const_svector view() const = 0;
|
||||
@@ -1064,6 +1105,13 @@ namespace detail {
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief template class for all extensions of PVArray.
|
||||
*
|
||||
* The direct extensions are pvBooleanArray, pvByteArray, ..., pvStringArray.
|
||||
* There are specializations for PVStringArray, PVStructureArray, and PVUnionArray.
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
class epicsShareClass PVValueArray : public detail::PVVectorStorage<T,PVScalarArray> {
|
||||
typedef detail::PVVectorStorage<T,PVScalarArray> base_t;
|
||||
@@ -1085,6 +1133,9 @@ public:
|
||||
*/
|
||||
virtual ~PVValueArray() {}
|
||||
|
||||
/**
|
||||
* Get introspection interface.
|
||||
*/
|
||||
virtual ArrayConstPtr getArray() const
|
||||
{
|
||||
return std::tr1::static_pointer_cast<const Array>(this->getField());
|
||||
@@ -1122,14 +1173,15 @@ protected:
|
||||
this->replace(shared_vector_convert<const T>(in));
|
||||
}
|
||||
|
||||
PVValueArray(ScalarArrayConstPtr const & scalar)
|
||||
explicit PVValueArray(ScalarArrayConstPtr const & scalar)
|
||||
: base_t(scalar) {}
|
||||
friend class PVDataCreate;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Data class for a structureArray
|
||||
* @brief Data class for a structureArray
|
||||
*
|
||||
*/
|
||||
template<>
|
||||
class epicsShareClass PVValueArray<PVStructurePtr> : public detail::PVVectorStorage<PVStructurePtr,PVArray>
|
||||
@@ -1211,8 +1263,11 @@ public:
|
||||
virtual std::ostream& dumpValue(std::ostream& o) const;
|
||||
virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const;
|
||||
|
||||
void copy(const PVStructureArray& from);
|
||||
void copyUnchecked(const PVStructureArray& from);
|
||||
|
||||
protected:
|
||||
PVValueArray(StructureArrayConstPtr const & structureArray)
|
||||
explicit PVValueArray(StructureArrayConstPtr const & structureArray)
|
||||
:base_t(structureArray)
|
||||
,structureArray(structureArray)
|
||||
{}
|
||||
@@ -1225,7 +1280,8 @@ private:
|
||||
|
||||
|
||||
/**
|
||||
* Data class for a unionArray
|
||||
* @brief Data class for a unionArray
|
||||
*
|
||||
*/
|
||||
template<>
|
||||
class epicsShareClass PVValueArray<PVUnionPtr> : public detail::PVVectorStorage<PVUnionPtr,PVArray>
|
||||
@@ -1307,8 +1363,11 @@ public:
|
||||
virtual std::ostream& dumpValue(std::ostream& o) const;
|
||||
virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const;
|
||||
|
||||
void copy(const PVUnionArray& from);
|
||||
void copyUnchecked(const PVUnionArray& from);
|
||||
|
||||
protected:
|
||||
PVValueArray(UnionArrayConstPtr const & unionArray)
|
||||
explicit PVValueArray(UnionArrayConstPtr const & unionArray)
|
||||
:base_t(unionArray)
|
||||
,unionArray(unionArray)
|
||||
{}
|
||||
@@ -1359,7 +1418,8 @@ typedef PVValueArray<std::string> PVStringArray;
|
||||
typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
|
||||
|
||||
/**
|
||||
* This is a singlton class for creating data instances.
|
||||
* @brief This is a singleton class for creating data instances.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass PVDataCreate {
|
||||
public:
|
||||
@@ -1390,7 +1450,7 @@ public:
|
||||
PVScalarPtr createPVScalar(ScalarConstPtr const & scalar);
|
||||
/**
|
||||
* Create an implementation of a scalar field. A Scalar introspection interface is created.
|
||||
* @param fieldType The field type.
|
||||
* @param scalarType The scalar type.
|
||||
* @return The PVScalar implementation.
|
||||
*/
|
||||
PVScalarPtr createPVScalar(ScalarType scalarType);
|
||||
@@ -1403,7 +1463,7 @@ public:
|
||||
PVScalarPtr createPVScalar(PVScalarPtr const & scalarToClone);
|
||||
/**
|
||||
* template version
|
||||
* @param PVT must ve a valid pvType
|
||||
* @tparam PVT must be a valid PVType
|
||||
* @return The PVScalar implementation.
|
||||
*/
|
||||
template<typename PVT>
|
||||
@@ -1435,7 +1495,7 @@ public:
|
||||
|
||||
/**
|
||||
* Create implementation for PVUnion.
|
||||
* @param union The introspection interface.
|
||||
* @param punion The introspection interface.
|
||||
* @return The PVUnion implementation
|
||||
*/
|
||||
PVUnionPtr createPVUnion(UnionConstPtr const & punion);
|
||||
@@ -1453,13 +1513,12 @@ public:
|
||||
|
||||
/**
|
||||
* Create an implementation of an array field reusing the Array introspection interface.
|
||||
* @param array The introspection interface.
|
||||
* @param scalarArray The introspection interface.
|
||||
* @return The PVScalarArray implementation.
|
||||
*/
|
||||
PVScalarArrayPtr createPVScalarArray(ScalarArrayConstPtr const & scalarArray);
|
||||
/**
|
||||
* Create an implementation for an array field. An Array introspection interface is created.
|
||||
* @param parent The parent interface.
|
||||
* @param elementType The element type.
|
||||
* @return The PVScalarArray implementation.
|
||||
*/
|
||||
@@ -1467,13 +1526,13 @@ public:
|
||||
/**
|
||||
* Create an implementation of an array field by cloning an existing PVArray.
|
||||
* The new PVArray will have the same value and auxInfo as the original.
|
||||
* @param arrayToClone The PVScalarArray to clone.
|
||||
* @param scalarArrayToClone The PVScalarArray to clone.
|
||||
* @return The PVScalarArray implementation.
|
||||
*/
|
||||
PVScalarArrayPtr createPVScalarArray(PVScalarArrayPtr const & scalarArrayToClone);
|
||||
/**
|
||||
* template version
|
||||
* @param PVT must ve a valid pvType
|
||||
* @tparam PVT must be a valid pvType
|
||||
* @return The PVScalarArray implementation.
|
||||
*/
|
||||
template<typename PVAT>
|
||||
@@ -1509,7 +1568,7 @@ public:
|
||||
PVUnionArrayPtr createPVUnionArray(UnionArrayConstPtr const & unionArray);
|
||||
/**
|
||||
* Create an implementation of an array with union elements.
|
||||
* @param punion The introspection interface tht is used to create UnionArrayConstPtr.
|
||||
* @param punion The introspection interface that is used to create UnionArrayConstPtr.
|
||||
* All elements share the same introspection interface.
|
||||
* @return The PVUnionArray implementation.
|
||||
*/
|
||||
@@ -1529,11 +1588,32 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the single class that implemnents PVDataCreate
|
||||
* @param The PVDataCreate factory.
|
||||
* Get the single class that implements PVDataCreate
|
||||
* @return The PVDataCreate factory.
|
||||
*/
|
||||
|
||||
epicsShareExtern PVDataCreatePtr getPVDataCreate();
|
||||
|
||||
bool epicsShareExtern operator==(const PVField&, const PVField&);
|
||||
|
||||
static inline bool operator!=(const PVField& a, const PVField& b)
|
||||
{return !(a==b);}
|
||||
|
||||
}}
|
||||
|
||||
/**
|
||||
* stream support for pvField
|
||||
*/
|
||||
namespace std{
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, const epics::pvData::PVField *ptr);
|
||||
}
|
||||
|
||||
#undef USAGE_DEPRECATED
|
||||
#undef USAGE_ERROR
|
||||
|
||||
#endif /* PVDATA_H */
|
||||
|
||||
/** @page Overview Documentation
|
||||
*
|
||||
* <a href = "pvDataCPP.html">pvData.html</a>
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -163,7 +163,8 @@ enum Type {
|
||||
};
|
||||
|
||||
/**
|
||||
* Convenience functions for Type.
|
||||
* @brief Convenience functions for Type.
|
||||
*
|
||||
*/
|
||||
namespace TypeFunc {
|
||||
/**
|
||||
@@ -182,51 +183,51 @@ epicsShareExtern std::ostream& operator<<(std::ostream& o, const Type& type);
|
||||
*/
|
||||
enum ScalarType {
|
||||
/**
|
||||
* The type is boolean, i. e. value can be {@code false} or {@code true}
|
||||
* The type is boolean, i.e. value can be @c false or @c true
|
||||
*/
|
||||
pvBoolean,
|
||||
/**
|
||||
* The type is byte, i. e. a 8 bit signed integer.
|
||||
* The type is byte, i.e. a 8 bit signed integer.
|
||||
*/
|
||||
pvByte,
|
||||
/**
|
||||
* The type is short, i. e. a 16 bit signed integer.
|
||||
* The type is short, i.e. a 16 bit signed integer.
|
||||
*/
|
||||
pvShort,
|
||||
/**
|
||||
* The type is int, i. e. a 32 bit signed integer.
|
||||
* The type is int, i.e. a 32 bit signed integer.
|
||||
*/
|
||||
pvInt,
|
||||
/**
|
||||
* The type is long, i. e. a 64 bit signed integer.
|
||||
* The type is long, i.e. a 64 bit signed integer.
|
||||
*/
|
||||
pvLong,
|
||||
/**
|
||||
* The type is unsigned byte, i. e. a 8 bit unsigned integer.
|
||||
* The type is unsigned byte, i.e. a 8 bit unsigned integer.
|
||||
*/
|
||||
pvUByte,
|
||||
/**
|
||||
* The type is unsigned short, i. e. a 16 bit unsigned integer.
|
||||
* The type is unsigned short, i.e. a 16 bit unsigned integer.
|
||||
*/
|
||||
pvUShort,
|
||||
/**
|
||||
* The type is unsigned int, i. e. a 32 bit unsigned integer.
|
||||
* The type is unsigned int, i.e. a 32 bit unsigned integer.
|
||||
*/
|
||||
pvUInt,
|
||||
/**
|
||||
* The type is unsigned long, i. e. a 64 bit unsigned integer.
|
||||
* The type is unsigned long, i.e. a 64 bit unsigned integer.
|
||||
*/
|
||||
pvULong,
|
||||
/**
|
||||
* The type is float, i. e. 32 bit IEEE floating point,
|
||||
* The type is float, i.e. 32 bit IEEE floating point,
|
||||
*/
|
||||
pvFloat,
|
||||
/**
|
||||
* The type is float, i. e. 64 bit IEEE floating point,
|
||||
* The type is float, i.e. 64 bit IEEE floating point,
|
||||
*/
|
||||
pvDouble,
|
||||
/**
|
||||
* The type is string, i. e. a UTF8 character string.
|
||||
* The type is string, i.e. a UTF8 character string.
|
||||
*/
|
||||
pvString
|
||||
};
|
||||
@@ -234,29 +235,30 @@ enum ScalarType {
|
||||
#define MAX_SCALAR_TYPE pvString
|
||||
|
||||
/**
|
||||
* Convenience functions for ScalarType.
|
||||
* @brief Convenience functions for ScalarType.
|
||||
*
|
||||
*/
|
||||
namespace ScalarTypeFunc {
|
||||
/**
|
||||
* Is the type an integer, i. e. is it one of byte,...ulong
|
||||
* Is the type an integer, i.e. is it one of byte,...ulong
|
||||
* @param scalarType The type.
|
||||
* @return (false,true) if the scalarType is an integer.
|
||||
*/
|
||||
epicsShareExtern bool isInteger(ScalarType scalarType);
|
||||
/**
|
||||
* Is the type an unsigned integer, i. e. is it one of ubyte,...ulong
|
||||
* Is the type an unsigned integer, i.e. is it one of ubyte,...ulong
|
||||
* @param scalarType The type.
|
||||
* @return (false,true) if the scalarType is an integer.
|
||||
*/
|
||||
epicsShareExtern bool isUInteger(ScalarType scalarType);
|
||||
/**
|
||||
* Is the type numeric, i. e. is it one of byte,...,double
|
||||
* Is the type numeric, i.e. is it one of byte,...,double
|
||||
* @param scalarType The type.
|
||||
* @return (false,true) if the scalarType is a numeric
|
||||
*/
|
||||
epicsShareExtern bool isNumeric(ScalarType scalarType);
|
||||
/**
|
||||
* Is the type primitive, i. e. not string
|
||||
* Is the type primitive, i.e. not string
|
||||
* @param scalarType The type.
|
||||
* @return (false,true) if the scalarType is primitive.
|
||||
*/
|
||||
@@ -283,7 +285,8 @@ epicsShareExtern std::ostream& operator<<(std::ostream& o, const ScalarType& sca
|
||||
|
||||
|
||||
/**
|
||||
* This class implements introspection object for field.
|
||||
* @brief This class implements introspection object for field.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass Field :
|
||||
virtual public Serializable,
|
||||
@@ -315,7 +318,7 @@ public:
|
||||
protected:
|
||||
/**
|
||||
* Constructor
|
||||
* @param fieldName The field type.
|
||||
* @param type The field type.
|
||||
*/
|
||||
Field(Type type);
|
||||
private:
|
||||
@@ -335,7 +338,8 @@ epicsShareExtern std::ostream& operator<<(std::ostream& o, const Field& field);
|
||||
|
||||
|
||||
/**
|
||||
* This class implements introspection object for Scalar.
|
||||
* @brief This class implements introspection object for Scalar.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass Scalar : public Field{
|
||||
public:
|
||||
@@ -372,7 +376,8 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements introspection object for BoundedString.
|
||||
* @brief This class implements introspection object for BoundedString.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass BoundedString : public Scalar{
|
||||
public:
|
||||
@@ -398,7 +403,8 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements introspection object for Array.
|
||||
* @brief This class implements introspection object for Array.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass Array : public Field{
|
||||
public:
|
||||
@@ -427,20 +433,15 @@ public:
|
||||
protected:
|
||||
/**
|
||||
* Constructor
|
||||
* @param fieldName The field type.
|
||||
* @param type The field type.
|
||||
*/
|
||||
Array(Type type);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class implements introspection object for scalar array.
|
||||
* @brief This class implements introspection object for scalar array.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass ScalarArray : public Array{
|
||||
public:
|
||||
@@ -484,7 +485,8 @@ private:
|
||||
|
||||
|
||||
/**
|
||||
* This class implements introspection object for bounded scalar array.
|
||||
* @brief This class implements introspection object for bounded scalar array.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass BoundedScalarArray : public ScalarArray{
|
||||
public:
|
||||
@@ -518,7 +520,8 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements introspection object for bounded scalar array.
|
||||
* @brief This class implements introspection object for bounded scalar array.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass FixedScalarArray : public ScalarArray{
|
||||
public:
|
||||
@@ -551,12 +554,9 @@ private:
|
||||
friend class FieldCreate;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class implements introspection object for a structureArray
|
||||
* @brief This class implements introspection object for a structureArray
|
||||
*
|
||||
*/
|
||||
class epicsShareClass StructureArray : public Array{
|
||||
public:
|
||||
@@ -597,7 +597,8 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements introspection object for a unionArray
|
||||
* @brief This class implements introspection object for a unionArray
|
||||
*
|
||||
*/
|
||||
class epicsShareClass UnionArray : public Array{
|
||||
public:
|
||||
@@ -625,7 +626,7 @@ public:
|
||||
protected:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param union The introspection interface for the elements.
|
||||
* @param _punion The introspection interface for the elements.
|
||||
*/
|
||||
UnionArray(UnionConstPtr const & _punion);
|
||||
/**
|
||||
@@ -638,7 +639,8 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements introspection object for a structure.
|
||||
* @brief This class implements introspection object for a structure.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass Structure : public Field {
|
||||
public:
|
||||
@@ -647,7 +649,13 @@ public:
|
||||
/**
|
||||
* Default structure ID.
|
||||
*/
|
||||
static std::string DEFAULT_ID;
|
||||
static const std::string DEFAULT_ID;
|
||||
|
||||
/**
|
||||
* Get the default structure ID.
|
||||
* @return The default structure ID.
|
||||
*/
|
||||
static const std::string & defaultId();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@@ -668,13 +676,35 @@ public:
|
||||
* This will hold a null pointer if the field is not in the structure.
|
||||
*/
|
||||
FieldConstPtr getField(std::string const &fieldName) const;
|
||||
|
||||
template<typename FT>
|
||||
std::tr1::shared_ptr<const FT> getField(std::string const &fieldName) const
|
||||
{
|
||||
FieldConstPtr field = getField(fieldName);
|
||||
if (field.get())
|
||||
return std::tr1::dynamic_pointer_cast<const FT>(field);
|
||||
else
|
||||
return std::tr1::shared_ptr<const FT>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the field for the specified fieldName.
|
||||
* @param fieldName The index of the field to get;
|
||||
* @param index The index of the field to get;
|
||||
* @return The introspection interface.
|
||||
* This will hold a null pointer if the field is not in the structure.
|
||||
*/
|
||||
FieldConstPtr getField(std::size_t index) const {return fields[index];}
|
||||
FieldConstPtr getField(std::size_t index) const {return fields.at(index);}
|
||||
|
||||
template<typename FT>
|
||||
std::tr1::shared_ptr<const FT> getField(std::size_t index) const
|
||||
{
|
||||
FieldConstPtr field = getField(index);
|
||||
if (field.get())
|
||||
return std::tr1::dynamic_pointer_cast<const FT>(field);
|
||||
else
|
||||
return std::tr1::shared_ptr<const FT>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the field index for the specified fieldName.
|
||||
* @return The introspection interface.
|
||||
@@ -696,7 +726,7 @@ public:
|
||||
* @param fieldIndex The index of the desired field.
|
||||
* @return The fieldName.
|
||||
*/
|
||||
std::string getFieldName(std::size_t fieldIndex) const {return fieldNames[fieldIndex];}
|
||||
std::string getFieldName(std::size_t fieldIndex) const {return fieldNames.at(fieldIndex);}
|
||||
|
||||
virtual std::string getID() const;
|
||||
|
||||
@@ -706,7 +736,7 @@ public:
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
|
||||
protected:
|
||||
Structure(StringArray const & fieldNames, FieldConstPtrArray const & fields, std::string const & id = DEFAULT_ID);
|
||||
Structure(StringArray const & fieldNames, FieldConstPtrArray const & fields, std::string const & id = defaultId());
|
||||
private:
|
||||
StringArray fieldNames;
|
||||
FieldConstPtrArray fields;
|
||||
@@ -719,7 +749,8 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements introspection object for a union.
|
||||
* @brief This class implements introspection object for a union.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass Union : public Field {
|
||||
public:
|
||||
@@ -728,12 +759,24 @@ public:
|
||||
/**
|
||||
* Default union ID.
|
||||
*/
|
||||
static std::string DEFAULT_ID;
|
||||
static const std::string DEFAULT_ID;
|
||||
|
||||
/**
|
||||
* Get the default union ID.
|
||||
* @return The default union ID.
|
||||
*/
|
||||
static const std::string & defaultId();
|
||||
|
||||
/**
|
||||
* Default variant union ID.
|
||||
*/
|
||||
static std::string ANY_ID;
|
||||
static const std::string ANY_ID;
|
||||
|
||||
/**
|
||||
* Get the default variant union ID.
|
||||
* @return The default variant union ID.
|
||||
*/
|
||||
static const std::string & anyId();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@@ -754,13 +797,35 @@ public:
|
||||
* This will hold a null pointer if the field is not in the union.
|
||||
*/
|
||||
FieldConstPtr getField(std::string const &fieldName) const;
|
||||
|
||||
template<typename FT>
|
||||
std::tr1::shared_ptr<const FT> getField(std::string const &fieldName) const
|
||||
{
|
||||
FieldConstPtr field = getField(fieldName);
|
||||
if (field.get())
|
||||
return std::tr1::dynamic_pointer_cast<const FT>(field);
|
||||
else
|
||||
return std::tr1::shared_ptr<const FT>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the field for the specified fieldName.
|
||||
* @param fieldName The index of the field to get;
|
||||
* @param index The index of the field to get;
|
||||
* @return The introspection interface.
|
||||
* This will hold a null pointer if the field is not in the union.
|
||||
*/
|
||||
FieldConstPtr getField(std::size_t index) const {return fields[index];}
|
||||
FieldConstPtr getField(std::size_t index) const {return fields.at(index);}
|
||||
|
||||
template<typename FT>
|
||||
std::tr1::shared_ptr<const FT> getField(std::size_t index) const
|
||||
{
|
||||
FieldConstPtr field = getField(index);
|
||||
if (field.get())
|
||||
return std::tr1::dynamic_pointer_cast<const FT>(field);
|
||||
else
|
||||
return std::tr1::shared_ptr<const FT>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the field index for the specified fieldName.
|
||||
* @return The introspection interface.
|
||||
@@ -782,7 +847,7 @@ public:
|
||||
* @param fieldIndex The index of the desired field.
|
||||
* @return The fieldName.
|
||||
*/
|
||||
std::string getFieldName(std::size_t fieldIndex) const {return fieldNames[fieldIndex];}
|
||||
std::string getFieldName(std::size_t fieldIndex) const {return fieldNames.at(fieldIndex);}
|
||||
/**
|
||||
* Check if this union is variant union (aka any type).
|
||||
* @return <code>true</code> if this union is variant union, otherwise <code>false</code>.
|
||||
@@ -798,7 +863,7 @@ public:
|
||||
|
||||
protected:
|
||||
Union();
|
||||
Union(StringArray const & fieldNames, FieldConstPtrArray const & fields, std::string const & id = DEFAULT_ID);
|
||||
Union(StringArray const & fieldNames, FieldConstPtrArray const & fields, std::string const & id = defaultId());
|
||||
private:
|
||||
StringArray fieldNames;
|
||||
FieldConstPtrArray fields;
|
||||
@@ -817,8 +882,9 @@ class FieldBuilder;
|
||||
typedef std::tr1::shared_ptr<FieldBuilder> FieldBuilderPtr;
|
||||
|
||||
/**
|
||||
* Interface for in-line creating of introspection interfaces.
|
||||
* One instance can be used to create multiple {@code Field} instances.
|
||||
* @brief Interface for in-line creating of introspection interfaces.
|
||||
*
|
||||
* One instance can be used to create multiple @c Field instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author mse
|
||||
*/
|
||||
@@ -829,127 +895,127 @@ public:
|
||||
/**
|
||||
* Set ID of an object to be created.
|
||||
* @param id id to be set.
|
||||
* @return this instance of a {@code FieldBuilder}.
|
||||
* @return this instance of a @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr setId(std::string const & id);
|
||||
|
||||
/**
|
||||
* Add a {@code Scalar}.
|
||||
* Add a @c Scalar.
|
||||
* @param name name of the array.
|
||||
* @param scalarType type of a scalar to add.
|
||||
* @return this instance of a {@code FieldBuilder}.
|
||||
* @return this instance of a @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr add(std::string const & name, ScalarType scalarType);
|
||||
|
||||
/**
|
||||
* Add a {@code BoundedString}.
|
||||
* Add a @c BoundedString.
|
||||
* @param name name of the array.
|
||||
* @param maxLength a string maximum length.
|
||||
* @return this instance of a {@code FieldBuilder}.
|
||||
* @return this instance of a @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr addBoundedString(std::string const & name, std::size_t maxLength);
|
||||
|
||||
/**
|
||||
* Add a {@code Field} (e.g. {@code Structure}, {@code Union}).
|
||||
* Add a @c Field (e.g. @c Structure, @c Union).
|
||||
* @param name name of the array.
|
||||
* @param field a field to add.
|
||||
* @return this instance of a {@code FieldBuilder}.
|
||||
* @return this instance of a @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr add(std::string const & name, FieldConstPtr const & field);
|
||||
|
||||
/**
|
||||
* Add variable size array of {@code Scalar} elements.
|
||||
* Add variable size array of @c Scalar elements.
|
||||
* @param name name of the array.
|
||||
* @param scalarType type of a scalar element.
|
||||
* @return this instance of a {@code FieldBuilder}.
|
||||
* @return this instance of a @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr addArray(std::string const & name, ScalarType scalarType);
|
||||
|
||||
/**
|
||||
* Add fixed-size array of {@code Scalar} elements.
|
||||
* Add fixed-size array of @c Scalar elements.
|
||||
* @param name name of the array.
|
||||
* @param scalarType type of a scalar element.
|
||||
* @param size Array fixed size.
|
||||
* @return this instance of a {@code FieldBuilder}.
|
||||
* @return this instance of a @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr addFixedArray(std::string const & name, ScalarType scalarType, std::size_t size);
|
||||
|
||||
/**
|
||||
* Add bounded-size array of {@code Scalar} elements.
|
||||
* Add bounded-size array of @c Scalar elements.
|
||||
* @param name name of the array.
|
||||
* @param scalarType type of a scalar element.
|
||||
* @param bound Array maximum capacity (size).
|
||||
* @return this instance of a {@code FieldBuilder}.
|
||||
* @return this instance of a @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr addBoundedArray(std::string const & name, ScalarType scalarType, std::size_t bound);
|
||||
|
||||
/**
|
||||
* Add array of {@code Field} elements.
|
||||
* Add array of @c Field elements.
|
||||
* @param name name of the array.
|
||||
* @param field a type of an array element.
|
||||
* @return this instance of a {@code FieldBuilder}.
|
||||
* @param element a type of an array element.
|
||||
* @return this instance of a @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr addArray(std::string const & name, FieldConstPtr const & element);
|
||||
|
||||
/**
|
||||
* Create a {@code Structure}.
|
||||
* This resets this instance state and allows new {@code Field} instance to be created.
|
||||
* @return a new instance of a {@code Structure}.
|
||||
* Create a @c Structure.
|
||||
* This resets this instance state and allows new @c Field instance to be created.
|
||||
* @return a new instance of a @c Structure.
|
||||
*/
|
||||
StructureConstPtr createStructure();
|
||||
|
||||
/**
|
||||
* Create an {@code Union}.
|
||||
* This resets this instance state and allows new {@code Field} instance to be created.
|
||||
* @return a new instance of an {@code Union}.
|
||||
* Create an @c Union.
|
||||
* This resets this instance state and allows new @c Field instance to be created.
|
||||
* @return a new instance of an @c Union.
|
||||
*/
|
||||
UnionConstPtr createUnion();
|
||||
|
||||
/**
|
||||
* Add new nested {@code Structure}.
|
||||
* {@code endNested()} method must be called
|
||||
* to complete creation of the nested {@code Structure}.
|
||||
* Add new nested @c Structure.
|
||||
* endNested() method must be called
|
||||
* to complete creation of the nested @c Structure.
|
||||
* @param name nested structure name.
|
||||
* @return a new instance of a {@code FieldBuilder} is returned.
|
||||
* @return a new instance of a @c FieldBuilder is returned.
|
||||
* @see #endNested()
|
||||
*/
|
||||
FieldBuilderPtr addNestedStructure(std::string const & name);
|
||||
|
||||
/**
|
||||
* Add new nested {@code Union}.
|
||||
* {@code endNested()} method must be called
|
||||
* to complete creation of the nested {@code Union}.
|
||||
* Add new nested @c Union.
|
||||
* endNested() method must be called
|
||||
* to complete creation of the nested @c Union.
|
||||
* @param name nested union name.
|
||||
* @return a new instance of a {@code FieldBuilder} is returned.
|
||||
* @return a new instance of a @c FieldBuilder is returned.
|
||||
* @see #endNested()
|
||||
*/
|
||||
FieldBuilderPtr addNestedUnion(std::string const & name);
|
||||
|
||||
/**
|
||||
* Add new nested {@code Structure[]}.
|
||||
* {@code endNested()} method must be called
|
||||
* to complete creation of the nested {@code Structure}.
|
||||
* Add new nested @c Structure[].
|
||||
* endNested() method must be called
|
||||
* to complete creation of the nested @c Structure.
|
||||
* @param name nested structure name.
|
||||
* @return a new instance of a {@code FieldBuilder} is returned.
|
||||
* @return a new instance of a @c FieldBuilder is returned.
|
||||
* @see #endNested()
|
||||
*/
|
||||
FieldBuilderPtr addNestedStructureArray(std::string const & name);
|
||||
|
||||
/**
|
||||
* Add new nested {@code Union[]}.
|
||||
* {@code endNested()} method must be called
|
||||
* to complete creation of the nested {@code Union}.
|
||||
* Add new nested @c Union[].
|
||||
* endNested() method must be called
|
||||
* to complete creation of the nested @c Union.
|
||||
* @param name nested union name.
|
||||
* @return a new instance of a {@code FieldBuilder} is returned.
|
||||
* @return a new instance of a @c FieldBuilder is returned.
|
||||
* @see #endNested()
|
||||
*/
|
||||
FieldBuilderPtr addNestedUnionArray(std::string const & name);
|
||||
|
||||
/**
|
||||
* Complete the creation of a nested object.
|
||||
* @see #addNestedStructure(std::string)
|
||||
* @see #addNestedUnion(std::string)
|
||||
* @return a previous (parent) {@code FieldBuilder}.
|
||||
* @see #addNestedStructure(std::string const & name)
|
||||
* @see #addNestedUnion(std::string const & name)
|
||||
* @return a previous (parent) @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr endNested();
|
||||
|
||||
@@ -981,114 +1047,113 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a singleton class for creating introspection interfaces.
|
||||
* @brief This is a singleton class for creating introspection interfaces.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass FieldCreate {
|
||||
public:
|
||||
static FieldCreatePtr getFieldCreate();
|
||||
/**
|
||||
* Create a new instance of in-line {@code Field} builder.
|
||||
* @return a new instance of a {@code FieldBuilder}.
|
||||
* Create a new instance of in-line @c Field builder.
|
||||
* @return a new instance of a @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr createFieldBuilder() const;
|
||||
/**
|
||||
* Create a {@code ScalarField}.
|
||||
* Create a @c ScalarField.
|
||||
* @param scalarType The scalar type.
|
||||
* @return a {@code Scalar} interface for the newly created object.
|
||||
* @throws An {@code IllegalArgumentException} if an illegal type is specified.
|
||||
* @return a @c Scalar interface for the newly created object.
|
||||
* @throws IllegalArgumentException if an illegal type is specified.
|
||||
*/
|
||||
ScalarConstPtr createScalar(ScalarType scalarType) const;
|
||||
/**
|
||||
* Create a {@code BoundedString}.
|
||||
* Create a @c BoundedString.
|
||||
* @param maxLength a string maximum length.
|
||||
* @return a {@code BoundedString} interface for the newly created object.
|
||||
* @throws An {@code IllegalArgumentException} if maxLength == 0.
|
||||
* @return a @c BoundedString interface for the newly created object.
|
||||
* @throws IllegalArgumentException if maxLength == 0.
|
||||
*/
|
||||
BoundedStringConstPtr createBoundedString(std::size_t maxLength) const;
|
||||
/**
|
||||
* Create an {@code Array} field, variable size array.
|
||||
* @param elementType The {@code scalarType} for array elements
|
||||
* @return An {@code Array} Interface for the newly created object.
|
||||
* Create an @c Array field, variable size array.
|
||||
* @param elementType The @c ScalarType for array elements
|
||||
* @return An @c Array Interface for the newly created object.
|
||||
*/
|
||||
ScalarArrayConstPtr createScalarArray(ScalarType elementType) const;
|
||||
/*
|
||||
* Create an {@code Array} field, fixed size array.
|
||||
* @param elementType The {@code scalarType} for array elements
|
||||
* Create an @c Array field, fixed size array.
|
||||
* @param elementType The @c ScalarType for array elements
|
||||
* @param size Fixed array size.
|
||||
* @return An {@code Array} Interface for the newly created object.
|
||||
* @return An @c Array Interface for the newly created object.
|
||||
*/
|
||||
ScalarArrayConstPtr createFixedScalarArray(ScalarType elementType, std::size_t size) const;
|
||||
/**
|
||||
* Create an {@code Array} field, bounded size array.
|
||||
* @param elementType The {@code scalarType} for array elements
|
||||
* @param size Array maximum capacity (bound).
|
||||
* @return An {@code Array} Interface for the newly created object.
|
||||
* Create an @c Array field, bounded size array.
|
||||
* @param elementType The @c ScalarType for array elements
|
||||
* @param bound Array maximum capacity.
|
||||
* @return An @c Array Interface for the newly created object.
|
||||
*/
|
||||
ScalarArrayConstPtr createBoundedScalarArray(ScalarType elementType, std::size_t bound) const;
|
||||
/**
|
||||
* Create an {@code Array} field that is has element type <i>Structure</i>
|
||||
* @param fieldName The field name
|
||||
* @param elementStructure The {@code Structure} for each array element.
|
||||
* @return An {@code Array} Interface for the newly created object.
|
||||
* Create an @c Array field that is has element type @c Structure
|
||||
* @param structure The @c Structure for each array element.
|
||||
* @return An @c Array Interface for the newly created object.
|
||||
*/
|
||||
StructureArrayConstPtr createStructureArray(StructureConstPtr const & structure) const;
|
||||
/**
|
||||
* Create a {@code Structure} field.
|
||||
* @return a {@code Structure} interface for the newly created object.
|
||||
* Create a @c Structure field.
|
||||
* @return a @c Structure interface for the newly created object.
|
||||
*/
|
||||
StructureConstPtr createStructure () const;
|
||||
/**
|
||||
* Create a {@code Structure} field.
|
||||
* @param fieldNames The array of {@code fieldNames} for the structure.
|
||||
* @param fields The array of {@code fields} for the structure.
|
||||
* @return a {@code Structure} interface for the newly created object.
|
||||
* Create a @c Structure field.
|
||||
* @param fieldNames the names of the fields for the structure.
|
||||
* @param fields The array of @c Field objects for the structure.
|
||||
* @return a @c Structure interface for the newly created object.
|
||||
*/
|
||||
StructureConstPtr createStructure (
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
/**
|
||||
* Create a {@code Structure} field with identification string.
|
||||
* Create a @c Structure field with identification string.
|
||||
* @param id The identification string for the structure.
|
||||
* @param fieldNames The array of {@code fieldNames} for the structure.
|
||||
* @param fields The array of {@code fields} for the structure.
|
||||
* @return a {@code Structure} interface for the newly created object.
|
||||
* @param fieldNames the names of the fields for the structure.
|
||||
* @param fields The array of @c Field objects for the structure.
|
||||
* @return a @c Structure interface for the newly created object.
|
||||
*/
|
||||
StructureConstPtr createStructure (
|
||||
std::string const & id,
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
/**
|
||||
* Create an {@code Array} field that is has element type <i>Union</i>
|
||||
* @param fieldName The field name
|
||||
* @param elementUnion The {@code Union} for each array element.
|
||||
* @return An {@code Array} Interface for the newly created object.
|
||||
* Create an @c Array field that is has element type @c Union
|
||||
* @param punion The @c Union for each array element.
|
||||
* @return An @c Array Interface for the newly created object.
|
||||
*/
|
||||
UnionArrayConstPtr createUnionArray(UnionConstPtr const & punion) const;
|
||||
/**
|
||||
* Create a variant {@code UnionArray} (aka any type) field.
|
||||
* @return a {@code UnionArray} interface for the newly created object.
|
||||
* Create a variant @c UnionArray (aka any type) field.
|
||||
* @return a @c UnionArray interface for the newly created object.
|
||||
*/
|
||||
UnionArrayConstPtr createVariantUnionArray() const;
|
||||
/**
|
||||
* Create a variant {@code Union} (aka any type) field.
|
||||
* @return a {@code Union} interface for the newly created object.
|
||||
* Create a variant @c Union (aka any type) field.
|
||||
* @return a @c Union interface for the newly created object.
|
||||
*/
|
||||
UnionConstPtr createVariantUnion() const;
|
||||
/**
|
||||
* Create a {@code Union} field.
|
||||
* @param fieldNames The array of {@code fieldNames} for the union.
|
||||
* @param fields The array of {@code fields} for the union.
|
||||
* @return a {@code Union} interface for the newly created object.
|
||||
* Create a @c Union field.
|
||||
* @param fieldNames the names of the fields for the union.
|
||||
* @param fields The @c Field for each fields for the union.
|
||||
* @return a @c Union interface for the newly created object.
|
||||
*/
|
||||
UnionConstPtr createUnion (
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
/**
|
||||
* Create a {@code Union} field with identification string.
|
||||
* Create a @c Union field with identification string.
|
||||
* @param id The identification string for the union.
|
||||
* @param fieldNames The array of {@code fieldNames} for the union.
|
||||
* @param fields The array of {@code fields} for the union.
|
||||
* @return a {@code Union} interface for the newly created object.
|
||||
* @param fieldNames the names of the fields for the union.
|
||||
* @param fields The array of @c Field objects for the union.
|
||||
* @return a @c Union interface for the newly created object.
|
||||
*/
|
||||
UnionConstPtr createUnion (
|
||||
std::string const & id,
|
||||
@@ -1099,7 +1164,7 @@ public:
|
||||
* @param structure The structure to which the field is appended.
|
||||
* @param fieldName The name of the field.
|
||||
* @param field The field.
|
||||
* @return a {@code Structure} interface for the newly created object.
|
||||
* @return a @c Structure interface for the newly created object.
|
||||
*/
|
||||
StructureConstPtr appendField(
|
||||
StructureConstPtr const & structure,
|
||||
@@ -1107,19 +1172,19 @@ public:
|
||||
/**
|
||||
* Append fields to a structure.
|
||||
* @param structure The structure to which the fields appended.
|
||||
* @param fieldName The names of the fields.
|
||||
* @param field The fields.
|
||||
* @return a {@code Structure} interface for the newly created object.
|
||||
* @param fieldNames The names of the fields.
|
||||
* @param fields The fields.
|
||||
* @return a @c Structure interface for the newly created object.
|
||||
*/
|
||||
StructureConstPtr appendFields(
|
||||
StructureConstPtr const & structure,
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
/**
|
||||
* Deserialize {@code Field} instance from given byte buffer.
|
||||
* @param buffer Buffer containing serialized {@code Field} instance.
|
||||
* Deserialize @c Field instance from given byte buffer.
|
||||
* @param buffer Buffer containing serialized @c Field instance.
|
||||
* @param control Deserialization control instance.
|
||||
* @return a deserialized {@code Field} instance.
|
||||
* @return a deserialized @c Field instance.
|
||||
*/
|
||||
FieldConstPtr deserialize(ByteBuffer* buffer, DeserializableControl* control) const;
|
||||
|
||||
@@ -1133,8 +1198,8 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the single class that implemnents FieldCreate,
|
||||
* @param The fieldCreate factory.
|
||||
* Get the single class that implements FieldCreate,
|
||||
* @return The fieldCreate factory.
|
||||
*/
|
||||
epicsShareExtern FieldCreatePtr getFieldCreate();
|
||||
|
||||
@@ -1179,14 +1244,26 @@ OP(pvDouble, double)
|
||||
OP(pvString, std::string)
|
||||
#undef OP
|
||||
|
||||
/**
|
||||
* @brief Hash a Scalar
|
||||
*
|
||||
*/
|
||||
struct ScalarHashFunction {
|
||||
size_t operator() (const Scalar& scalar) const { return scalar.getScalarType(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Hash a ScalarArray
|
||||
*
|
||||
*/
|
||||
struct ScalarArrayHashFunction {
|
||||
size_t operator() (const ScalarArray& scalarArray) const { return 0x10 | scalarArray.getElementType(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Hash a Structure
|
||||
*
|
||||
*/
|
||||
struct StructureHashFunction {
|
||||
size_t operator() (const Structure& /*structure*/) const { return 0; }
|
||||
// TODO hash
|
||||
@@ -1194,9 +1271,47 @@ struct StructureHashFunction {
|
||||
// return PRIME * Arrays.hashCode(fieldNames) + Arrays.hashCode(fields);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Hash a StructureArray
|
||||
*
|
||||
*/
|
||||
struct StructureArrayHashFunction {
|
||||
size_t operator() (const StructureArray& structureArray) const { StructureHashFunction shf; return (0x10 | shf(*(structureArray.getStructure()))); }
|
||||
};
|
||||
|
||||
bool epicsShareExtern operator==(const Field&, const Field&);
|
||||
bool epicsShareExtern operator==(const Scalar&, const Scalar&);
|
||||
bool epicsShareExtern operator==(const ScalarArray&, const ScalarArray&);
|
||||
bool epicsShareExtern operator==(const Structure&, const Structure&);
|
||||
bool epicsShareExtern operator==(const StructureArray&, const StructureArray&);
|
||||
bool epicsShareExtern operator==(const Union&, const Union&);
|
||||
bool epicsShareExtern operator==(const UnionArray&, const UnionArray&);
|
||||
bool epicsShareExtern operator==(const BoundedString&, const BoundedString&);
|
||||
|
||||
static inline bool operator!=(const Field& a, const Field& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const Scalar& a, const Scalar& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const ScalarArray& a, const ScalarArray& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const Structure& a, const Structure& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const StructureArray& a, const StructureArray& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const Union& a, const Union& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const UnionArray& a, const UnionArray& b)
|
||||
{return !(a==b);}
|
||||
static inline bool operator!=(const BoundedString& a, const BoundedString& b)
|
||||
{return !(a==b);}
|
||||
|
||||
}}
|
||||
|
||||
/**
|
||||
* stream support for Field
|
||||
*/
|
||||
namespace std{
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, const epics::pvData::Field *ptr);
|
||||
}
|
||||
|
||||
#endif /* PVINTROSPECT_H */
|
||||
|
||||
@@ -71,7 +71,7 @@ epicsShareExtern void copy(
|
||||
PVStructureArray & pvFrom,
|
||||
size_t fromOffset,
|
||||
size_t fromStride,
|
||||
PVStructureArray & pvToo,
|
||||
PVStructureArray & pvTo,
|
||||
size_t toOffset,
|
||||
size_t toStride,
|
||||
size_t count);
|
||||
@@ -91,7 +91,7 @@ epicsShareExtern void copy(
|
||||
PVArray & pvFrom,
|
||||
size_t fromOffset,
|
||||
size_t fromStride,
|
||||
PVArray & pvToo,
|
||||
PVArray & pvTo,
|
||||
size_t toOffset,
|
||||
size_t toStride,
|
||||
size_t count);
|
||||
@@ -111,7 +111,7 @@ epicsShareExtern void copy(
|
||||
PVArray::shared_pointer const & pvFrom,
|
||||
size_t fromOffset,
|
||||
size_t fromStride,
|
||||
PVArray::shared_pointer & pvToo,
|
||||
PVArray::shared_pointer & pvTo,
|
||||
size_t toOffset,
|
||||
size_t toStride,
|
||||
size_t count);
|
||||
|
||||
@@ -49,11 +49,11 @@ namespace detail {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a set of typdefs used by pvData.
|
||||
* This is a set of typedefs used by pvData.
|
||||
*/
|
||||
|
||||
/**
|
||||
* boolean, i.e. can only have the values {@code false} or {@code true}
|
||||
* boolean, i.e. can only have the values @c false or @c true
|
||||
*/
|
||||
typedef detail::pick_type<int8_t, signed char,
|
||||
detail::pick_type<uint8_t, char, unsigned char>::type
|
||||
|
||||
@@ -25,7 +25,8 @@ class StandardField;
|
||||
typedef std::tr1::shared_ptr<StandardField> StandardFieldPtr;
|
||||
|
||||
/**
|
||||
* Standard Fields is a class or creating or sharing Field objects for standard fields.
|
||||
* @brief Standard Fields is a class or creating or sharing Field objects for standard fields.
|
||||
*
|
||||
* For each type of standard object two methods are defined:s
|
||||
* one with no properties and with properties
|
||||
* The property field is a comma separated string of property names of the following:
|
||||
@@ -85,21 +86,21 @@ public:
|
||||
StructureConstPtr regUnion(
|
||||
UnionConstPtr const & punion,
|
||||
std::string const & properties);
|
||||
/** Create a structure that has a varient union value field.
|
||||
/** Create a structure that has a variant union value field.
|
||||
* @param properties A comma separated list of properties.
|
||||
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr variantUnion(std::string const & properties);
|
||||
/** Create a structure that has a scalarArray value field.
|
||||
* @param type The type.
|
||||
* @param elementType The element type.
|
||||
* @param properties A comma separated list of properties.
|
||||
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr scalarArray(ScalarType elementType, std::string const & properties);
|
||||
/** Create a structure that has a structureArray value field.
|
||||
* @param type The type.
|
||||
* @param structure The Structure introspection object for elements of the value field.
|
||||
* @param properties A comma separated list of properties.
|
||||
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
|
||||
* @return The const shared pointer to the structure.
|
||||
@@ -108,7 +109,7 @@ public:
|
||||
StructureConstPtr const & structure,
|
||||
std::string const & properties);
|
||||
/** Create a structure that has a unionArray value field.
|
||||
* @param type The type.
|
||||
* @param punion The Union introspection object for elements of the value field.
|
||||
* @param properties A comma separated list of properties.
|
||||
* This is some combination of "alarm,timeStamp,display,control".
|
||||
* @return The const shared pointer to the structure.
|
||||
@@ -117,7 +118,7 @@ public:
|
||||
UnionConstPtr const & punion,
|
||||
std::string const & properties);
|
||||
/** Create a structure that has an enumerated structure value field.
|
||||
* The id for the structure is "enum-t".
|
||||
* The id for the structure is "enum_t".
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr enumerated();
|
||||
|
||||
@@ -25,7 +25,8 @@ class StandardPVField;
|
||||
typedef std::tr1::shared_ptr<StandardPVField> StandardPVFieldPtr;
|
||||
|
||||
/**
|
||||
* StandardPVField is a class or creating standard data fields.
|
||||
* @brief StandardPVField is a class or creating standard data fields.
|
||||
*
|
||||
* Like class StandardField it has two forms of the methods which create a fields:
|
||||
* one without properties and one with properties.
|
||||
* The properties are some combination of alarm, timeStamp, control, display, and valueAlarm.
|
||||
@@ -53,7 +54,7 @@ public:
|
||||
PVStructurePtr scalar(ScalarType type,std::string const & properties);
|
||||
/**
|
||||
* Create a structure that has a scalar array value field.
|
||||
* @param type The type.
|
||||
* @param elementType The element scalar type.
|
||||
* @param properties A comma separated list of properties.
|
||||
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
|
||||
* @return The const shared pointer to the structure.
|
||||
@@ -61,7 +62,7 @@ public:
|
||||
PVStructurePtr scalarArray(ScalarType elementType, std::string const & properties);
|
||||
/**
|
||||
* Create a structure that has a structure array value field.
|
||||
* @param type The type.
|
||||
* @param structure The Structure introspection object for elements of the value field.
|
||||
* @param properties A comma separated list of properties.
|
||||
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
|
||||
* @return The const shared pointer to the structure.
|
||||
@@ -69,7 +70,7 @@ public:
|
||||
PVStructurePtr structureArray(StructureConstPtr const &structure,std::string const & properties);
|
||||
/**
|
||||
* Create a structure that has a union array value field.
|
||||
* @param type The type.
|
||||
* @param punion The Union introspection object for elements of the value field.
|
||||
* @param properties A comma separated list of properties.
|
||||
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
|
||||
* @return The const shared pointer to the structure.
|
||||
|
||||
@@ -18,8 +18,20 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/**
|
||||
* @brief Compress a bitSet.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass BitSetUtil : private NoDefaultMethods {
|
||||
public:
|
||||
/**
|
||||
* compress the bitSet for a pvStructure.
|
||||
* In all subfields of a structure have been modified then
|
||||
* the bit for the structure is set and all the subfield bits
|
||||
* are cleared.
|
||||
* @param bitSet this must be a valid bitSet for pvStructure.
|
||||
* @param pvStructure the structure.
|
||||
*/
|
||||
static bool compress(BitSetPtr const &bitSet,PVStructurePtr const &pvStructure);
|
||||
};
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ static void testCreateRequestInternal() {
|
||||
string request = "";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getStructure()->getNumberFields()==0);
|
||||
testPass("request %s",request.c_str());
|
||||
@@ -39,8 +39,8 @@ static void testCreateRequestInternal() {
|
||||
request = "record[]field()getField()putField()";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("putField").get()!=NULL);
|
||||
@@ -50,8 +50,8 @@ static void testCreateRequestInternal() {
|
||||
request = "record[a=b,x=y]field(a) putField(a),getField(a)";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("record._options.a");
|
||||
sval = pvString->get();
|
||||
@@ -67,8 +67,8 @@ static void testCreateRequestInternal() {
|
||||
request = "field(a.b[x=y])";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("field.a.b._options.x");
|
||||
sval = pvString->get();
|
||||
@@ -78,8 +78,8 @@ static void testCreateRequestInternal() {
|
||||
request = "field(a.b{c.d})";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.a.b.c.d").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
@@ -87,8 +87,8 @@ static void testCreateRequestInternal() {
|
||||
request = "field(a.b[x=y]{c.d})";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("field.a.b._options.x");
|
||||
sval = pvString->get();
|
||||
@@ -99,8 +99,8 @@ static void testCreateRequestInternal() {
|
||||
request = "field(a.b[x=y]{c.d[x=y]})";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("field.a.b._options.x");
|
||||
sval = pvString->get();
|
||||
@@ -113,8 +113,8 @@ static void testCreateRequestInternal() {
|
||||
request = "record[a=b,c=d] field(a.a[a=b]{a.a[a=b]},b.a[a=b]{a,b})";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("field.a.a._options.a");
|
||||
sval = pvString->get();
|
||||
@@ -133,8 +133,8 @@ static void testCreateRequestInternal() {
|
||||
request = "alarm,timeStamp,power.value";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.timeStamp").get()!=NULL);
|
||||
@@ -144,8 +144,8 @@ static void testCreateRequestInternal() {
|
||||
request = "record[process=true]field(alarm,timeStamp,power.value)";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("record._options.process");
|
||||
sval = pvString->get();
|
||||
@@ -158,8 +158,8 @@ static void testCreateRequestInternal() {
|
||||
request = "record[process=true]field(alarm,timeStamp[algorithm=onChange,causeMonitor=false],power{value,alarm})";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("record._options.process");
|
||||
sval = pvString->get();
|
||||
@@ -179,8 +179,8 @@ static void testCreateRequestInternal() {
|
||||
request = "record[int=2,float=3.14159]field(alarm,timeStamp[shareData=true],power.value)";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("record._options.int");
|
||||
sval = pvString->get();
|
||||
@@ -201,8 +201,8 @@ static void testCreateRequestInternal() {
|
||||
+ "current{value,alarm},voltage{value,alarm})";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("putField.power.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.alarm").get()!=NULL);
|
||||
@@ -221,8 +221,8 @@ static void testCreateRequestInternal() {
|
||||
+ "})";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.timeStamp").get()!=NULL);
|
||||
@@ -243,8 +243,8 @@ static void testCreateRequestInternal() {
|
||||
+ ")";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("putField.power.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.alarm").get()!=NULL);
|
||||
@@ -276,8 +276,8 @@ static void testCreateRequestInternal() {
|
||||
request = "a{b{c{d}}}";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest.get()==NULL) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.a.b.c.d").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
@@ -302,11 +302,27 @@ static void testCreateRequestInternal() {
|
||||
cout << "reason " << createRequest->getMessage() << endl;
|
||||
testOk1(pvRequest.get()==NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = "field(alarm.status,alarm.severity)";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
cout << endl << "Error Expected for next call!!" << endl;
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
cout << "reason " << createRequest->getMessage() << endl;
|
||||
testOk1(pvRequest.get()==NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = ":field(record[process=false]power.value)";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
cout << endl << "Error Expected for next call!!" << endl;
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
cout << "reason " << createRequest->getMessage() << endl;
|
||||
testOk1(pvRequest.get()==NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
}
|
||||
|
||||
MAIN(testCreateRequest)
|
||||
{
|
||||
testPlan(117);
|
||||
testPlan(121);
|
||||
testCreateRequestInternal();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -108,7 +108,6 @@ static void testPVScalar(
|
||||
}
|
||||
|
||||
static void testPVScalarArray(
|
||||
ScalarType scalarType,
|
||||
string const & valueNameMaster,
|
||||
string const & valueNameCopy,
|
||||
PVStructurePtr const & pvMaster,
|
||||
@@ -123,14 +122,14 @@ static void testPVScalarArray(
|
||||
shared_vector<double> values(n);
|
||||
shared_vector<const double> cvalues;
|
||||
|
||||
pvValueMaster = pvMaster->getScalarArrayField(valueNameMaster,scalarType);
|
||||
pvValueMaster = pvMaster->getSubField<PVScalarArray>(valueNameMaster);
|
||||
for(size_t i=0; i<n; i++) values[i] = i;
|
||||
const shared_vector<const double> xxx(freeze(values));
|
||||
pvValueMaster->putFrom(xxx);
|
||||
StructureConstPtr structure = pvCopy->getStructure();
|
||||
if(debug) { cout << "structure from copy" << endl << *structure << endl;}
|
||||
pvStructureCopy = pvCopy->createPVStructure();
|
||||
pvValueCopy = pvStructureCopy->getScalarArrayField(valueNameCopy,scalarType);
|
||||
pvValueCopy = pvStructureCopy->getSubField<PVScalarArray>(valueNameCopy);
|
||||
bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
|
||||
pvCopy->initCopy(pvStructureCopy, bitSet);
|
||||
if(debug) { cout << "after initCopy pvValueCopy " << *pvValueCopy << endl; }
|
||||
@@ -256,7 +255,7 @@ static void arrayTest()
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
testPVScalarArray(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
request = "";
|
||||
valueNameMaster = "value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
@@ -264,7 +263,7 @@ static void arrayTest()
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
testPVScalarArray(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
request = "alarm,timeStamp,value";
|
||||
valueNameMaster = "value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
@@ -272,7 +271,7 @@ static void arrayTest()
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
testPVScalarArray(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
}
|
||||
|
||||
static PVStructurePtr createPowerSupply()
|
||||
|
||||
@@ -7,6 +7,11 @@ testThread_SRCS += testThread.cpp
|
||||
testHarness_SRCS += testThread.cpp
|
||||
TESTS += testThread
|
||||
|
||||
TESTPROD_HOST += testEvent
|
||||
testEvent_SRCS += testEvent.cpp
|
||||
testHarness_SRCS += testEvent.cpp
|
||||
TESTS += testEvent
|
||||
|
||||
TESTPROD_HOST += testTimer
|
||||
testTimer_SRCS += testTimer.cpp
|
||||
testHarness_SRCS += testTimer.cpp
|
||||
|
||||
@@ -146,12 +146,19 @@ static void testOperators()
|
||||
b1.or_and(b2, b3);
|
||||
str = toString(b1);
|
||||
testOk1(str == "{2, 128}");
|
||||
|
||||
b1.clear(); b1.set(1);
|
||||
b2.clear();
|
||||
b3.clear(); b3.set(1);
|
||||
std::cout<<"# "<<toString(b3)<<" |= "<<toString(b1)<<" & "<<toString(b2)<<"\n";
|
||||
b3.or_and(b1, b2);
|
||||
testOk(toString(b3) == "{1}", "%s == {1}", toString(b3).c_str());
|
||||
}
|
||||
|
||||
|
||||
MAIN(testBitSet)
|
||||
{
|
||||
testPlan(29);
|
||||
testPlan(30);
|
||||
testGetSetClearFlip();
|
||||
testOperators();
|
||||
return testDone();
|
||||
|
||||
51
testApp/misc/testEvent.cpp
Normal file
51
testApp/misc/testEvent.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/event.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
|
||||
static void testBasicEvent()
|
||||
{
|
||||
testDiag("testBasicEvent");
|
||||
|
||||
Event e;
|
||||
|
||||
// 0 signals, 2 waits
|
||||
testOk1(!e.tryWait());
|
||||
testOk1(!e.tryWait());
|
||||
|
||||
// signal, wait, signal, wait
|
||||
e.signal();
|
||||
testOk1(e.tryWait());
|
||||
e.signal();
|
||||
testOk1(e.tryWait());
|
||||
|
||||
// 1 signal, 2 waits
|
||||
e.signal();
|
||||
testOk1(e.tryWait());
|
||||
testOk1(!e.tryWait());
|
||||
|
||||
// 2 signals, 2 waits
|
||||
e.signal();
|
||||
e.signal();
|
||||
testOk1(e.tryWait());
|
||||
testOk1(!e.tryWait());
|
||||
|
||||
// 0 signals, 1 wait
|
||||
testOk1(!e.tryWait());
|
||||
}
|
||||
|
||||
MAIN(testEvent)
|
||||
{
|
||||
testPlan(9);
|
||||
testBasicEvent();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -32,17 +32,17 @@ void test()
|
||||
string buffer;
|
||||
string properties("alarm,timeStamp,display");
|
||||
PVStructurePtr pvStructure = standardPVField->scalar(pvDouble,properties);
|
||||
PVDoublePtr pvValue = pvStructure->getDoubleField("value");
|
||||
PVDoublePtr pvValue = pvStructure->getSubField<PVDouble>("value");
|
||||
uint32 valueOffset = (uint32) pvValue->getFieldOffset();
|
||||
PVStructurePtr pvAlarm = pvStructure->getStructureField("alarm");
|
||||
PVIntPtr pvSeverity = pvAlarm->getIntField("severity");
|
||||
PVStringPtr pvMessage = pvAlarm->getStringField("message");
|
||||
PVStructurePtr pvAlarm = pvStructure->getSubField<PVStructure>("alarm");
|
||||
PVIntPtr pvSeverity = pvAlarm->getSubField<PVInt>("severity");
|
||||
PVStringPtr pvMessage = pvAlarm->getSubField<PVString>("message");
|
||||
uint32 severityOffset = (uint32) pvSeverity->getFieldOffset();
|
||||
uint32 messageOffset = (uint32) pvMessage->getFieldOffset();
|
||||
PVStructurePtr pvTimeStamp = pvStructure->getStructureField("timeStamp");
|
||||
PVLongPtr pvSeconds = pvTimeStamp->getLongField("secondsPastEpoch");
|
||||
PVIntPtr pvNanoseconds = pvTimeStamp->getIntField("nanoseconds");
|
||||
PVIntPtr pvUserTag = pvTimeStamp->getIntField("userTag");
|
||||
PVStructurePtr pvTimeStamp = pvStructure->getSubField<PVStructure>("timeStamp");
|
||||
PVLongPtr pvSeconds = pvTimeStamp->getSubField<PVLong>("secondsPastEpoch");
|
||||
PVIntPtr pvNanoseconds = pvTimeStamp->getSubField<PVInt>("nanoseconds");
|
||||
PVIntPtr pvUserTag = pvTimeStamp->getSubField<PVInt>("userTag");
|
||||
uint32 timeStampOffset = (uint32) pvTimeStamp->getFieldOffset();
|
||||
uint32 secondsOffset = (uint32) pvSeconds->getFieldOffset();
|
||||
uint32 nanosecondsOffset = (uint32) pvNanoseconds->getFieldOffset();
|
||||
|
||||
@@ -385,9 +385,9 @@ void testStructure() {
|
||||
|
||||
testDiag("\tSimple structure serialization");
|
||||
PVStructurePtr pvStructure = factory->createPVStructure(getStandardField()->timeStamp());
|
||||
pvStructure->getLongField("secondsPastEpoch")->put(123);
|
||||
pvStructure->getIntField("nanoseconds")->put(456);
|
||||
pvStructure->getIntField("userTag")->put(789);
|
||||
pvStructure->getSubField<PVLong>("secondsPastEpoch")->put(123);
|
||||
pvStructure->getSubField<PVInt>("nanoseconds")->put(456);
|
||||
pvStructure->getSubField<PVInt>("userTag")->put(789);
|
||||
|
||||
serializationTest(pvStructure);
|
||||
|
||||
|
||||
@@ -356,7 +356,7 @@ static void testPush()
|
||||
|
||||
static void testVoid()
|
||||
{
|
||||
testDiag("Test vecter cast to/from void");
|
||||
testDiag("Test vector cast to/from void");
|
||||
|
||||
epics::pvData::shared_vector<int32> typed(4);
|
||||
|
||||
@@ -497,8 +497,8 @@ static void testICE()
|
||||
|
||||
D = B; // create second const reference
|
||||
|
||||
// clears D, but reference to B refrence
|
||||
// to B remains, so a copy is made
|
||||
// clears D, but reference to B
|
||||
// remains, so a copy is made
|
||||
C = epics::pvData::thaw(D);
|
||||
|
||||
testOk1(B.unique());
|
||||
|
||||
@@ -35,7 +35,7 @@ void testTimeStampInternal()
|
||||
current.getCurrent();
|
||||
printf("current %lli %i milliSec %lli\n",
|
||||
(long long)current.getSecondsPastEpoch(),
|
||||
current.getNanoseconds(),
|
||||
(int)current.getNanoseconds(),
|
||||
(long long)current.getMilliseconds());
|
||||
time_t tt;
|
||||
current.toTime_t(tt);
|
||||
@@ -45,13 +45,13 @@ void testTimeStampInternal()
|
||||
"%4.4d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d %d isDst %s\n",
|
||||
ctm.tm_year+1900,ctm.tm_mon + 1,ctm.tm_mday,
|
||||
ctm.tm_hour,ctm.tm_min,ctm.tm_sec,
|
||||
current.getNanoseconds(),
|
||||
(int)current.getNanoseconds(),
|
||||
(ctm.tm_isdst==0) ? "false" : "true");
|
||||
tt = time(&tt);
|
||||
current.fromTime_t(tt);
|
||||
printf("fromTime_t\ncurrent %lli %i milliSec %lli\n",
|
||||
(long long)current.getSecondsPastEpoch(),
|
||||
current.getNanoseconds(),
|
||||
(int)current.getNanoseconds(),
|
||||
(long long)current.getMilliseconds());
|
||||
current.toTime_t(tt);
|
||||
memcpy(&ctm,localtime(&tt),sizeof(struct tm));
|
||||
@@ -59,7 +59,7 @@ void testTimeStampInternal()
|
||||
"%4.4d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d %d isDst %s\n",
|
||||
ctm.tm_year+1900,ctm.tm_mon + 1,ctm.tm_mday,
|
||||
ctm.tm_hour,ctm.tm_min,ctm.tm_sec,
|
||||
current.getNanoseconds(),
|
||||
(int)current.getNanoseconds(),
|
||||
(ctm.tm_isdst==0) ? "false" : "true");
|
||||
TimeStamp right;
|
||||
TimeStamp left;
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include <pv/requester.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/alarm.h>
|
||||
@@ -41,7 +40,6 @@ static FieldCreatePtr fieldCreate;
|
||||
static PVDataCreatePtr pvDataCreate;
|
||||
static StandardFieldPtr standardField;
|
||||
static StandardPVFieldPtr standardPVField;
|
||||
static ConvertPtr convert;
|
||||
static string alarmTimeStamp("alarm,timeStamp");
|
||||
static string allProperties("alarm,timeStamp,display,control");
|
||||
|
||||
@@ -131,9 +129,9 @@ static void testTimeStamp()
|
||||
"%4.4d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d %d nanoseconds isDst %s userTag %d\n",
|
||||
ctm.tm_year+1900,ctm.tm_mon + 1,ctm.tm_mday,
|
||||
ctm.tm_hour,ctm.tm_min,ctm.tm_sec,
|
||||
timeStamp.getNanoseconds(),
|
||||
(int)timeStamp.getNanoseconds(),
|
||||
(ctm.tm_isdst==0) ? "false" : "true",
|
||||
timeStamp.getUserTag());
|
||||
(int)timeStamp.getUserTag());
|
||||
}
|
||||
timeStamp.put(0,0);
|
||||
pvTimeStamp.set(timeStamp);
|
||||
@@ -217,14 +215,14 @@ static void testEnumerated()
|
||||
PVStringArray::const_svector choices = pvEnumerated.getChoices();
|
||||
int32 numChoices = pvEnumerated.getNumberChoices();
|
||||
if(debug) {
|
||||
printf("index %d choice %s choices",index,choice.c_str());
|
||||
printf("index %d choice %s choices",(int)index,choice.c_str());
|
||||
for(int i=0; i<numChoices; i++ ) printf(" %s",choices[i].c_str());
|
||||
printf("\n");
|
||||
}
|
||||
pvEnumerated.setIndex(2);
|
||||
index = pvEnumerated.getIndex();
|
||||
choice = pvEnumerated.getChoice();
|
||||
if(debug) printf("index %d choice %s\n",index,choice.c_str());
|
||||
if(debug) printf("index %d choice %s\n",(int)index,choice.c_str());
|
||||
printf("testEnumerated PASSED\n");
|
||||
}
|
||||
|
||||
@@ -236,7 +234,6 @@ MAIN(testProperty)
|
||||
pvDataCreate = getPVDataCreate();
|
||||
standardField = getStandardField();
|
||||
standardPVField = getStandardPVField();
|
||||
convert = getConvert();
|
||||
createRecords();
|
||||
testAlarm();
|
||||
testTimeStamp();
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include <pv/requester.h>
|
||||
#include <pv/bitSetUtil.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
|
||||
@@ -32,7 +31,6 @@ static FieldCreatePtr fieldCreate;
|
||||
static PVDataCreatePtr pvDataCreate;
|
||||
static StandardFieldPtr standardField;
|
||||
static StandardPVFieldPtr standardPVField;
|
||||
static ConvertPtr convert;
|
||||
|
||||
static void test()
|
||||
{
|
||||
@@ -175,7 +173,6 @@ MAIN(testBitSetUtil)
|
||||
pvDataCreate = getPVDataCreate();
|
||||
standardField = getStandardField();
|
||||
standardPVField = getStandardPVField();
|
||||
convert = getConvert();
|
||||
test();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user