Compare commits
88 Commits
before_mer
...
4.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a62f9c082 | ||
|
|
c5112ffa11 | ||
|
|
7b9fda4e81 | ||
|
|
278e531806 | ||
|
|
047de40642 | ||
|
|
4e671a1c21 | ||
|
|
f36c8ce280 | ||
|
|
e77f2c91d7 | ||
|
|
82b0d5ce5f | ||
|
|
6117035863 | ||
|
|
c86e31ad99 | ||
|
|
f506fe1c0e | ||
|
|
554dc06eda | ||
|
|
80e1dfd142 | ||
|
|
6db5cf60dc | ||
|
|
63d181a0ac | ||
|
|
73c4896cce | ||
|
|
5b1b5ab904 | ||
|
|
80a537bc4c | ||
|
|
2a8a1d3736 | ||
|
|
61fbfa0684 | ||
|
|
f06a6bfe7b | ||
|
|
587f81f511 | ||
|
|
435ca63d1b | ||
|
|
64bb660f44 | ||
|
|
8bf24de0b3 | ||
|
|
943ea633a4 | ||
|
|
b1d5f7d7e5 | ||
|
|
188b94ce19 | ||
|
|
515282abfe | ||
|
|
efbdb722e7 | ||
|
|
e980823294 | ||
|
|
3692f4fb3c | ||
|
|
3e645f3c79 | ||
|
|
6127763302 | ||
|
|
19a181b38f | ||
|
|
2818b0384c | ||
|
|
36faf8c2ea | ||
|
|
a208171250 | ||
|
|
b8a2b7cff6 | ||
|
|
2a08cbc1a0 | ||
|
|
62bc6c1fb1 | ||
|
|
1098650421 | ||
|
|
15d85c2f87 | ||
|
|
16fb3f0339 | ||
|
|
37f6dff065 | ||
|
|
baf8832fc9 | ||
|
|
b558e11ede | ||
|
|
103cdabff1 | ||
|
|
57e33c8f7d | ||
|
|
da0f65c2d3 | ||
|
|
6535c075f3 | ||
|
|
f3c0b9544c | ||
|
|
3609fd4745 | ||
|
|
622e140622 | ||
|
|
a4954c3825 | ||
|
|
b6e1b9c203 | ||
|
|
34a35c2658 | ||
|
|
90b7c9a17c | ||
|
|
c72297020b | ||
|
|
f07b601dce | ||
|
|
63c62a2aae | ||
|
|
6888a9d340 | ||
|
|
72bf9f76a3 | ||
|
|
c0c6213c7c | ||
|
|
652ef4bc82 | ||
|
|
c6eed12139 | ||
|
|
1132e25072 | ||
|
|
879e3a2b67 | ||
|
|
6ec207141f | ||
|
|
45c657ce79 | ||
|
|
888dc11c03 | ||
|
|
5e3159f800 | ||
|
|
570ec97eda | ||
|
|
09c75823e6 | ||
|
|
50c8c3b0bd | ||
|
|
3fb44312c7 | ||
|
|
67bdf2ab8b | ||
|
|
a56ed44e74 | ||
|
|
3c912c3812 | ||
|
|
0ceb87eee1 | ||
|
|
6510c10884 | ||
|
|
20345ab0dd | ||
|
|
d5dfb3de0c | ||
|
|
c2f22a4ad8 | ||
|
|
cb15a8676b | ||
|
|
34f2d7bc9a | ||
|
|
fb7f1b622b |
17
.hgignore
17
.hgignore
@@ -1,11 +1,12 @@
|
||||
^QtC-
|
||||
^bin/
|
||||
^lib/
|
||||
^doc/
|
||||
^include/
|
||||
^db/
|
||||
^dbd/
|
||||
^documentation/html
|
||||
QtC-
|
||||
bin/
|
||||
lib/
|
||||
doc/
|
||||
include/
|
||||
db/
|
||||
dbd/
|
||||
documentation/html
|
||||
documentation/*.tag
|
||||
envPaths
|
||||
configure/.*\.local
|
||||
/O\..*
|
||||
|
||||
8
.hgtags
8
.hgtags
@@ -9,3 +9,11 @@ d70c5ad29163306f50979a95b5aebbe9a93cfe76 2.0-BETA
|
||||
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
|
||||
b0d39d12d743b82038066955db6bb957b1f2f767 4.0.1
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -2,7 +2,7 @@
|
||||
Copyright (c) 2008 Martin R. Kraimer
|
||||
Copyright (c) 2006 The University of Chicago, as Operator of Argonne
|
||||
National Laboratory.
|
||||
Copyright (c) 2006 Deutsches Elektronen-Synchroton,
|
||||
Copyright (c) 2006 Deutsches Elektronen-Synchrotron,
|
||||
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
|
||||
Copyright (c) 2007 Control System Laboratory,
|
||||
(COSYLAB) Ljubljana Slovenia
|
||||
|
||||
@@ -580,7 +580,7 @@ WARN_LOGFILE =
|
||||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT = ../pvDataApp
|
||||
INPUT = ../include/pv
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
||||
|
||||
58
documentation/RELEASE_NOTES.html
Normal file
58
documentation/RELEASE_NOTES.html
Normal file
@@ -0,0 +1,58 @@
|
||||
<h1>Release 4.0 IN DEVELOPMENT</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>
|
||||
<li>timeStamp and valueAlarm name changes</li>
|
||||
<li>toString replaced by stream I/O </li>
|
||||
<li>union is new type.</li>
|
||||
<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.
|
||||
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>
|
||||
<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>
|
||||
<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);
|
||||
cout << buffer << endl;
|
||||
buffer.clear();
|
||||
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>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>
|
||||
<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>
|
||||
<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>
|
||||
89
documentation/RELEASE_NOTES.md
Normal file
89
documentation/RELEASE_NOTES.md
Normal file
@@ -0,0 +1,89 @@
|
||||
Release 4.0 IN DEVELOPMENT
|
||||
===========
|
||||
|
||||
The main changes since release 3.0.2 are:
|
||||
|
||||
* array semantics now enforce Copy On Write.
|
||||
* String no longer defined.
|
||||
* timeStamp and valueAlarm name changes
|
||||
* toString replaced by stream I/O
|
||||
* union is new type.
|
||||
* copy is new.
|
||||
* monitorPlugin is new.
|
||||
|
||||
New Semantics for Arrays
|
||||
--------
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
String no longer defined
|
||||
---------
|
||||
|
||||
This is replaced by std::string.
|
||||
|
||||
|
||||
timeStamp and valueAlarm name changes
|
||||
--------------
|
||||
|
||||
In timeStamp nanoSeconds is changed to nanoseconds.
|
||||
|
||||
In valueAlarm hystersis is changed to hysteresis
|
||||
|
||||
|
||||
toString replaced by stream I/O
|
||||
---------
|
||||
|
||||
pvData.h and pvIntrospect no longer defines toString
|
||||
Instead they have stream support.
|
||||
pvIntrospect uses method dump and pvData uses dumpValue.
|
||||
For example:
|
||||
|
||||
PVDoublePtr pvValue;
|
||||
String buffer;
|
||||
pvValue->toString(&buffer);
|
||||
cout << buffer << endl;
|
||||
buffer.clear();
|
||||
pvValue->getField()->toString(&buffer);
|
||||
cout << buffer << evdl;
|
||||
|
||||
is replaced by
|
||||
|
||||
PVDoublePtr pvValue;
|
||||
cout << *pvValue << endl
|
||||
cout << *pvValue->getField() << endl;
|
||||
|
||||
|
||||
union is a new basic type.
|
||||
------------
|
||||
|
||||
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>union</b> The field can any of specified set of types.
|
||||
|
||||
The field type can be dynamically changed.
|
||||
|
||||
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.
|
||||
|
||||
monitorPlugin
|
||||
-------------
|
||||
|
||||
This is for is for use by code that implements pvAccess monitors.
|
||||
This is prototype and is subject to debate.
|
||||
|
||||
Release 3.0.2
|
||||
==========
|
||||
This was the starting point for RELEASE_NOTES
|
||||
17
documentation/TODO.html
Normal file
17
documentation/TODO.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<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>
|
||||
38
documentation/TODO.md
Normal file
38
documentation/TODO.md
Normal file
@@ -0,0 +1,38 @@
|
||||
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
|
||||
---------
|
||||
|
||||
normativeTypes.html describes valueAlarm only for a value field that has type
|
||||
double.
|
||||
The implementation also supports all the numeric scalar types.
|
||||
|
||||
monitorPlugin
|
||||
-------------
|
||||
|
||||
A debate is on-going about what semantics should be.
|
||||
|
||||
679
documentation/copyandmonitor.html
Normal file
679
documentation/copyandmonitor.html
Normal file
@@ -0,0 +1,679 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||
<title>EPICS pvDataCPP: copy and monitor</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||
<style type="text/css">
|
||||
/*<![CDATA[*/
|
||||
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||
table { margin-left: auto; margin-right: auto }
|
||||
.diagram { text-align: center; margin: 2.5em 0 }
|
||||
span.opt { color: grey }
|
||||
span.nterm { font-style:italic }
|
||||
span.term { font-family:courier }
|
||||
span.user { font-family:courier }
|
||||
span.user:before { content:"<" }
|
||||
span.user:after { content:">" }
|
||||
.nonnorm { font-style:italic }
|
||||
p.ed { color: #AA0000 }
|
||||
span.ed { color: #AA0000 }
|
||||
p.ed.priv { display: inline; }
|
||||
span.ed.priv { display: inline; }
|
||||
/*]]>*/</style>
|
||||
<!-- Script that generates the Table of Contents -->
|
||||
<script type="text/javascript"
|
||||
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<div id="toc">
|
||||
<h2 class="nocount" style="page-break-before: always">Table of Contents</h2>
|
||||
</div>
|
||||
<div id="contents" class="contents">
|
||||
|
||||
<h2>support for copy and monitor</h2>
|
||||
<p><b>copy</b> and <b>monitor</b> are not used in this project.
|
||||
They are intended for use by pvAccess and by pvAccess servers.
|
||||
They are provided with this project because the code depends only on
|
||||
pvData itself.
|
||||
</p>
|
||||
<p>This document describes C++ specific code.
|
||||
<a href="http://epics-pvdata.sourceforge.net/informative/pvRequest.html">
|
||||
pvRequest.html</a>
|
||||
provides a language independent overview of <b>copy</b> and <b>monitor</b>.
|
||||
</p>
|
||||
<p>
|
||||
<b>NOTE:pvRequest.html</b> must be updated since it is based on an earlier version of pvCopy that
|
||||
had knowledge of PVRecord. The C++ version was implemented in pvDatabaseCPP
|
||||
and the Java version on pvIOCJava.
|
||||
At present only the C++ version of the new API for pvCopy is implemented.
|
||||
</p>
|
||||
<p>Copy provides:
|
||||
<dl>
|
||||
<dt>createRequest</dt>
|
||||
<dd>
|
||||
The Channel create methods in pvAccess all have an argument
|
||||
<b>PVStructure pvRequest</b>.<br />
|
||||
Given an ascii string createRequest creates a PVStructure that provides
|
||||
a pvData representation of the information from the ascii string.
|
||||
It is this structure that can be passed to the channel create methods.<br />
|
||||
The information in a pvRequest selects an arbitrary subset of the
|
||||
fields in a top level structure that resides in the server.
|
||||
In addition options can be specified. Both global and field specific
|
||||
options can be specified.
|
||||
</dd>
|
||||
<dt>pvCopy</dt>
|
||||
<dd>This is a facility used by channel providers.
|
||||
It provides client specific code that manages a copy of an arbitrary
|
||||
subset of the fields in a top level structure that resides in the
|
||||
provider. It also allows provider access to options specified
|
||||
by the client.
|
||||
</dd>
|
||||
</dl>
|
||||
Monitor provides:
|
||||
<dl>
|
||||
<dt>monitor</dt>
|
||||
<dd>This is support code for channel providers that implement channel
|
||||
monitor. It, together with the queue facility, provides support for
|
||||
monitor queues.
|
||||
</dd>
|
||||
<dt>monitorPlugin</dt>
|
||||
<dd>This is support for implementing monitor plugins.
|
||||
A monitor plugin can be developed that has no knowledge
|
||||
of pvAccess but only pvData.
|
||||
</dd>
|
||||
</dl>
|
||||
</p>
|
||||
|
||||
<h2>support for copy</h2>
|
||||
<p><b>copy</b> provides the ability to create a structure that has
|
||||
a copy of an arbitrary subset of the fields in an existing top level
|
||||
structure. In addition it allows global options and field specific options.
|
||||
It has two main components: <b>createRequest</b> and <b>pvCopy</b>.
|
||||
Given a string createRequest creates a pvRequest, which is a PVStructure
|
||||
that has the format expected by <b>pvCopy</b>.
|
||||
</p>
|
||||
|
||||
<h3>createRequest</h3>
|
||||
<p>This is mainly used by pvAccess clients. Given a request string it creates
|
||||
a pvRequest structure that can be passed to the pvAccess create methods.
|
||||
In turn pvAccess passes the pvRequest to a local channel provider which
|
||||
then passes it to pvCopy.
|
||||
</p>
|
||||
<p>The definition of the public members is:</p>
|
||||
<pre>
|
||||
class CreateRequest {
|
||||
...
|
||||
static CreateRequestPtr create();
|
||||
virtual PVStructurePtr createRequest(std::string const &request);
|
||||
std::string getMessage();
|
||||
};
|
||||
</pre>
|
||||
<p>An example of how it is used is:</p>
|
||||
<pre>
|
||||
CreateRequestPtr createRequest = CreateRequest::create();
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest==NULL) {
|
||||
std::string error = createRequest->getMessage();
|
||||
// take some action
|
||||
} else {
|
||||
//success do something
|
||||
}
|
||||
</pre>
|
||||
<h3>pvCopy</h3>
|
||||
<p>The definition of the public members is:</p>
|
||||
<pre>
|
||||
class epicsShareClass PVCopyTraverseMasterCallback
|
||||
{
|
||||
...
|
||||
virtual void nextMasterPVField(PVFieldPtr const &pvField);
|
||||
};
|
||||
|
||||
class class epicsShareClass PVCopy
|
||||
{
|
||||
...
|
||||
static PVCopyPtr create(
|
||||
PVStructurePtr const &pvMaster,
|
||||
PVStructurePtr const &pvRequest,
|
||||
std::string const & structureName);
|
||||
PVStructurePtr getPVMaster();
|
||||
void traverseMaster(PVCopyTraverseMasterCallbackPtr const & callback);
|
||||
StructureConstPtr getStructure();
|
||||
PVStructurePtr createPVStructure();
|
||||
size_t getCopyOffset(PVFieldPtr const &masterPVField);
|
||||
size_t getCopyOffset(
|
||||
PVStructurePtr const &masterPVStructure,
|
||||
PVFieldPtr const &masterPVField);
|
||||
PVFieldPtr getMasterPVField(std::size_t structureOffset);
|
||||
void initCopy(
|
||||
PVStructurePtr const &copyPVStructure,
|
||||
BitSetPtr const &bitSet);
|
||||
void updateCopySetBitSet(
|
||||
PVStructurePtr const &copyPVStructure,
|
||||
BitSetPtr const &bitSet);
|
||||
void updateCopyFromBitSet(
|
||||
PVStructurePtr const &copyPVStructure,
|
||||
BitSetPtr const &bitSet);
|
||||
void updateMaster(
|
||||
PVStructurePtr const &copyPVStructure,
|
||||
BitSetPtr const &bitSet);
|
||||
PVStructurePtr getOptions(std::size_t fieldOffset);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
where
|
||||
<dl>
|
||||
<dt>PVCopyTraverseMasterCallback::nextMasterPVField</dt>
|
||||
<dd>
|
||||
<b>PVCopyTraverseMasterCallback</b> is a callback which must
|
||||
be implemented by the code that uses pvCopy, normally
|
||||
the channel provider. It has the single method <b>nextMasterPVField</b>
|
||||
<br />
|
||||
<b>nextMasterPVField</b> is called for each field in the master
|
||||
as a result of a call to <b>traverseMaster</b>.
|
||||
</dd>
|
||||
<dt>create</dt>
|
||||
<dd>
|
||||
This is the method for creating a PVCopy instance.<br/>
|
||||
<dl>
|
||||
<dt>pvMaster</dt>
|
||||
<dd>the top level structure managed by the server.</dd>
|
||||
<dt>pvRequest</dt>
|
||||
<dd>selects the set of subfields desired
|
||||
and options for each field.</dd>
|
||||
<dt>structureName</dt>
|
||||
<dd>the name for the top level of any PVStructure created.
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt>getPVMaster</dt>
|
||||
<dd>
|
||||
Gets the top level structure from pvMaster.
|
||||
</dd>
|
||||
<dt>traverseMaster</dt>
|
||||
<dd>
|
||||
Traverse all fields of the top level structure of pvMaster.
|
||||
For each field the callback is called.
|
||||
</dd>
|
||||
<dt>getStructure</dt>
|
||||
<dd>
|
||||
Get the introspection interface for a PVStructure for e copy.
|
||||
</dd>
|
||||
<dt>createPVStructure</dt>
|
||||
<dd>Create a copy instance.
|
||||
Monitors keep a queue of monitor elements.
|
||||
Since each element needs a PVStructure, multiple top level structures
|
||||
will be created.
|
||||
</dd>
|
||||
<dt>getCopyOffset</dt>
|
||||
<dd>Given a field in pvMaster.
|
||||
return the offset in copy for the same field.
|
||||
A value of std::string::npos means that the copy does not have this field.
|
||||
Two overloaded methods are provided. The first is called if
|
||||
the field of master is not a structure. The second is for
|
||||
subfields of a structure.
|
||||
</dd>
|
||||
<dt>getMasterPVField</dt>
|
||||
<dd>
|
||||
Given a offset in the copy get the corresponding field in pvMaster.
|
||||
</dd>
|
||||
<dt>initCopy</dt>
|
||||
<dd>
|
||||
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.
|
||||
This means that bit set will have the value <b>{0}</b>.
|
||||
</dd>
|
||||
<dt>updateCopySetBitSet</dt>
|
||||
<dd>
|
||||
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.
|
||||
</dd>
|
||||
<dt>updateCopyFromBitSet</dt>
|
||||
<dd>
|
||||
For each set bit in bitSet set the field in copyPVStructure to the value
|
||||
of the corresponding field in pvMaster.
|
||||
</dd>
|
||||
<dt>updateMaster</dt>
|
||||
<dd>
|
||||
For each set bit in bitSet set the field in pvMaster to the value
|
||||
of the corresponding field in copyPVStructure.
|
||||
|
||||
</dd>
|
||||
<dt>getOptions</dt>
|
||||
<dd>
|
||||
Get the options for the field at the specified offset.
|
||||
A NULL is returned if no options were specified for the field.
|
||||
If options were specified,PVStructurePtr is
|
||||
a structure with a set of PVString subfields that specify name,value
|
||||
pairs. name is the subField name and value is the subField value.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
<h2>support for monitor</h2>
|
||||
<p>This consists of two components:
|
||||
<dl>
|
||||
<dt>monitor</dt>
|
||||
<dd>Used by code that implements pvAccess monitors.</dd>
|
||||
<dt>monitorPlugin</dt>
|
||||
<dd>Code that provides special semantics for monitors.</dd>
|
||||
</dl>
|
||||
</p>
|
||||
<h3>monitor</h3>
|
||||
<pre>
|
||||
class MonitorElement {
|
||||
MonitorElement(PVStructurePtr const & pvStructurePtr);
|
||||
PVStructurePtr pvStructurePtr;
|
||||
BitSetPtr changedBitSet;
|
||||
BitSetPtr overrunBitSet;
|
||||
};
|
||||
|
||||
class Monitor {
|
||||
virtual Status start() = 0;
|
||||
virtual Status stop() = 0;
|
||||
virtual MonitorElementPtr poll() = 0;
|
||||
virtual void release(MonitorElementPtr const & monitorElement) = 0;
|
||||
};
|
||||
|
||||
class MonitorRequester : public virtual Requester {
|
||||
virtual void monitorConnect(Status const & status,
|
||||
MonitorPtr const & monitor, StructureConstPtr const & structure) = 0;
|
||||
virtual void monitorEvent(MonitorPtr const & monitor) = 0;
|
||||
virtual void unlisten(MonitorPtr const & monitor) = 0;
|
||||
};
|
||||
</pre>
|
||||
<h4>monitorElement</h4>
|
||||
<p><b>MonitorElement</b> holds the data for one element of a monitor queue.
|
||||
It has the fields:
|
||||
<dl>
|
||||
<dt>pvStructurePtr</dt>
|
||||
<dd>A top level structure with data values at the time the monitors occurs.</dd>
|
||||
<dt>changedBitSet</dt>
|
||||
<dd>Shows which fields have changed since the previous monitor.</dd>
|
||||
<dt>overrunBitSet</dt>
|
||||
<dd>Shows which fields have changed more han once since the previous monitor.</dd>
|
||||
</dl>
|
||||
</p>
|
||||
<h4>monitorElement queue</h4>
|
||||
<p>
|
||||
A queue of monitor elements must be implemented by any channel provider that implements
|
||||
<b>Channel::createMonitor</b>.
|
||||
For an example implementation look at pvDatabaseCPP.
|
||||
It has the following:
|
||||
<pre>
|
||||
typedef Queue<MonitorElement> MonitorElementQueue;
|
||||
typedef std::tr1::shared_ptr<MonitorElementQueue> MonitorElementQueuePtr;
|
||||
|
||||
class MultipleElementQueue :
|
||||
public ElementQueue
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(MultipleElementQueue);
|
||||
virtual ~MultipleElementQueue(){}
|
||||
MultipleElementQueue(
|
||||
MonitorLocalPtr const &monitorLocal,
|
||||
MonitorElementQueuePtr const &queue,
|
||||
size_t nfields);
|
||||
virtual void destroy(){}
|
||||
virtual Status start();
|
||||
virtual Status stop();
|
||||
virtual bool dataChanged();
|
||||
virtual MonitorElementPtr poll();
|
||||
virtual void release(MonitorElementPtr const &monitorElement);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
<h4>Monitor</h4>
|
||||
<p><b>Monitor</b> must be implemented by any channel provider that implements
|
||||
<b>Channel::createMonitor</b>.
|
||||
Remote PVAccess also implements Monitor on the client side.
|
||||
Note that each client has it's own queue that is not shared with other client.
|
||||
</p>
|
||||
<p>Monitor has the following methods:</p>
|
||||
<dl>
|
||||
<dt>start</dt>
|
||||
<dd>
|
||||
Start monitoring.
|
||||
This will result in a an initial monitor that has the current value
|
||||
of all fields.
|
||||
</dd>
|
||||
<dt>stop</dt>
|
||||
<dd>
|
||||
Stop monitoring.
|
||||
</dd>
|
||||
<dt>poll</dt>
|
||||
<dd>
|
||||
Called to get a monitor element.
|
||||
If no new elements are available then a null pointer is returned.
|
||||
</dd>
|
||||
<dt>release</dt>
|
||||
<dd>
|
||||
Release the monitor element.
|
||||
The caller owns the monitor element between the calls to poll and release.
|
||||
</dd>
|
||||
<dl>
|
||||
</dl>
|
||||
<h4>MonitorRequester</h4>
|
||||
<p>This must be implemented by a pvAccess client.
|
||||
It has the methods:</p>
|
||||
<dl>
|
||||
<dt>monitorConnect</dt>
|
||||
<dd>
|
||||
A monitor has either connected of disconnected.
|
||||
</dd>
|
||||
<dt>monitorEvent</dt>
|
||||
<dd>
|
||||
A new monitor element is available.
|
||||
</dd>
|
||||
<dt>unlisten</dt>
|
||||
<dd>
|
||||
The channel is going away. The client cam no longer access the monitor.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h3>monitorPlugin</h3>
|
||||
<pre>
|
||||
class MonitorPlugin
|
||||
{
|
||||
virtual std::string const & getName() = 0;
|
||||
virtual bool causeMonitor(
|
||||
PVFieldPtr const &pvField,
|
||||
PVStructurePtr const &pvTop,
|
||||
MonitorElementPtr const &monitorElement) = 0;
|
||||
virtual void monitorDone(
|
||||
MonitorElementPtr const &monitorElement);
|
||||
virtual void startMonitoring();
|
||||
virtual void stopMonitoring();
|
||||
virtual void beginGroupPut();
|
||||
virtual void endGroupPut();
|
||||
};
|
||||
|
||||
class MonitorPluginCreator
|
||||
{
|
||||
virtual MonitorPluginPtr create(
|
||||
FieldConstPtr const &field,
|
||||
StructureConstPtr const &top,
|
||||
PVStructurePtr const &pvFieldOptions) = 0;
|
||||
virtual std::string const & getName() = 0;
|
||||
}
|
||||
|
||||
class MonitorPluginManager
|
||||
{
|
||||
static MonitorPluginManagerPtr get();
|
||||
bool addPlugin(
|
||||
std::string const &pluginName,
|
||||
MonitorPluginCreatorPtr const &creator);
|
||||
MonitorPluginCreatorPtr findPlugin(std::string const &pluginName);
|
||||
void showNames();
|
||||
};
|
||||
|
||||
</pre>
|
||||
<h4>MonitorPlugin</h4>
|
||||
<p><b>MonitorPlugin</b> must be implemented by the plugin implementation.
|
||||
It has methods:</p>
|
||||
<dl>
|
||||
<dt>getName</dt>
|
||||
<dd>Get the name of the plugin.</dd>
|
||||
<dt>causeMonitor</dt>
|
||||
<dd>
|
||||
Should the value of pvField cause a monitor to be raised.
|
||||
pvField and pvTop are fields in the top level structure
|
||||
being monitored. monitorElement has the top level structure
|
||||
for the copy</b>.
|
||||
The implementation should <b>not</b> modify the fields in the structure
|
||||
being monitored.
|
||||
Called with pvTop locked.
|
||||
</dd>
|
||||
<dt>monitorDone</dt>
|
||||
<dd>
|
||||
Called just before monitorElement will be given to client.
|
||||
The plugin can change the data values and bitSets in monitorElement.
|
||||
Called with pvTop unlocked.
|
||||
</dd>
|
||||
<dt>startMonitoring</dt>
|
||||
<dd>
|
||||
Monitoring is starting.
|
||||
</dd>
|
||||
<dt>stopMonitoring</dt>
|
||||
<dd>
|
||||
Monitoring is being stopped.
|
||||
</dd>
|
||||
<dt>beginGroupPut</dt>
|
||||
<dd>
|
||||
A set of puts is starting.
|
||||
Called with pvTop locked.
|
||||
</dd>
|
||||
<dt>endGroupPut</dt>
|
||||
<dd>
|
||||
The set of puts is complete.
|
||||
Called with pvTop locked.
|
||||
</dd>
|
||||
</dl>
|
||||
<h4>MonitorPluginCreator</h4>
|
||||
<p><b>MonitorPluginCreator</b> must also be implemented by the plugin implementation.
|
||||
It is called for each field instance that has options of the from
|
||||
<b>[plugin=name...]</b> where <b>name</b> is the name of the plugin.
|
||||
Note that a plugin instance will belong to a single client.
|
||||
It has methods:</p>
|
||||
<dl>
|
||||
<dt>getName</dt>
|
||||
<dd>Get the name of the plugin.</dd>
|
||||
<dt>create</dt>
|
||||
<dd>
|
||||
Create a new plugin instance.
|
||||
If the arguments are not compatible with the plugin a NULL shared pointer is
|
||||
returned.<br/>
|
||||
pvFieldOptions is
|
||||
a structure with a set of PVString subfields that specify <b>name,value</b>
|
||||
pairs. name is the subField name and value is the subField value.<br/>
|
||||
Note that a plugin will below to a single client.
|
||||
</dd>
|
||||
<dl>
|
||||
<h4>MonitorPluginManager</h4>
|
||||
<p><b>MonitorPluginManager</b> has the methods:</p>
|
||||
<dl>
|
||||
<dt>get</dt>
|
||||
<dd>
|
||||
MonitorPluginManager is a singleton.
|
||||
The first call to get will create the single instance.
|
||||
Further calls will return the single instance.
|
||||
</dd>
|
||||
<dt>addPlugin</dt>
|
||||
<dd>
|
||||
Add a new plugin.
|
||||
</dd>
|
||||
<dt>findPlugin</dt>
|
||||
<dd>
|
||||
Find a plugin. A NULL shared pointer is returned if it has not been added.
|
||||
</dd>
|
||||
<dt>showNames</dt>
|
||||
<dd>
|
||||
Show the names of all plugins that have been added.
|
||||
</dd>
|
||||
</dl>
|
||||
<p><b>NOTE:</b>
|
||||
Should the method <b>causeMonitor</b>
|
||||
have arguments <b>pvField</b> and <b>pvTop</b>
|
||||
be defined so that they can not be modified.
|
||||
This would be possible if the following was defined:
|
||||
<pre>
|
||||
typedef std::tr1::shared_ptr<const PVField> PVFieldConstPtr;
|
||||
typedef std::tr1::shared_ptr<const PVStructure> PVStructureConstPtr;
|
||||
</pre>
|
||||
then the definition for causeMonitor could be:
|
||||
<pre>
|
||||
virtual bool causeMonitor(
|
||||
PVFieldConstPtr const &pvField,
|
||||
PVStructureConstPtr const &pvTop,
|
||||
MonitorElementPtr const &monitorElement) = 0;
|
||||
</pre>
|
||||
But just adding these definitions is not sufficient.
|
||||
In addition all methods defined in pvDataCPP must be checked.
|
||||
In particular many of the methods in <b>Convert</b> must have
|
||||
their arguments modified.
|
||||
Big job.
|
||||
</p>
|
||||
<h2>monitorPlugin example</h2>
|
||||
<h3>Example Plugin Overview</h3>
|
||||
<p>This section describes an example plugin that:</p>
|
||||
<ul>
|
||||
<li>Only raises monitors when a field changes value.<br />
|
||||
If no plugin is provided
|
||||
the default is to raise a monitor when a put is issued to a field.</li>
|
||||
<li>Optionally a change will not raise a monitor.<br />
|
||||
The change will, however,
|
||||
appear if a put to another field raise a monitor.</li>
|
||||
</ul>
|
||||
<p>As an example assume that a channel provided by pvAccess has a top level structure
|
||||
that represents a power supply.</p>
|
||||
<pre>
|
||||
structure powerSupply
|
||||
structure alarm
|
||||
structure timeStamp
|
||||
structure power
|
||||
double value
|
||||
structure alarm
|
||||
structure display
|
||||
structure voltage
|
||||
double value
|
||||
structure alarm
|
||||
structure display
|
||||
structure current
|
||||
double value
|
||||
structure alarm
|
||||
structure display
|
||||
</pre>
|
||||
<p>A pvAccess client wants to create a monitor on the powerSupply as follows:
|
||||
The client wants a top level structure that looks like:
|
||||
<pre>
|
||||
structure powerSupply
|
||||
structure alarm
|
||||
structure timeStamp
|
||||
structure power
|
||||
double value
|
||||
structure voltage
|
||||
double value
|
||||
structure current
|
||||
double value
|
||||
</pre>
|
||||
In addition the client wants monitors to occur only when one of the monitored
|
||||
fields changes value but not just because a put occured.
|
||||
Also if only the timeStamp changes value then that should not cause a monitor.
|
||||
</p>
|
||||
<p>The example monitor plugin implements the semantics the
|
||||
client wants. It can be attached to any field via the following options:
|
||||
<pre>
|
||||
[plugin=onChange,raiseMonitor=value]
|
||||
</pre>
|
||||
This plugin will trigger a monitor for the field only if the field changes
|
||||
value. In addition <b>value</b> equals <b>false</b> means do not raise a monitor
|
||||
for changes to this field.
|
||||
But if a change to another field does cause a monitor the change to this field
|
||||
will be passed to the client.
|
||||
</p>
|
||||
<p>
|
||||
Assume that the client has already connected to the channel.
|
||||
The client can then issue the commands:</p>
|
||||
<pre>
|
||||
std::string request("field(alarm[plugin=onChange]");
|
||||
request += ",timeStamp[plugin=onChange,raiseMonitor=false]";
|
||||
request += ",power.value[plugin=onChange";
|
||||
request += ",voltage.value[plugin=onChange";
|
||||
request += ",current.value[plugin=onChange";
|
||||
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
|
||||
MonitorPtr monitor = channel->createMonitor(monitorRequester,pvRequest);
|
||||
</pre>
|
||||
<h3>Example Plugin Code</h3>
|
||||
<p>The header file to create the example has the definition:</p>
|
||||
<pre>
|
||||
class ExampleMonitorPlugin{
|
||||
public:
|
||||
static void create();
|
||||
};
|
||||
</pre>
|
||||
<p>The implementation is:</p>
|
||||
<pre>
|
||||
class OnChangePlugin : public MonitorPlugin
|
||||
{
|
||||
public:
|
||||
virtual ~OnChangePlugin(){}
|
||||
OnChangePlugin() {}
|
||||
bool init(
|
||||
FieldConstPtr const &field,
|
||||
StructureConstPtr const &top,
|
||||
PVStructurePtr const &pvFieldOptions)
|
||||
{
|
||||
pvField = getPVDataCreate()->createPVField(field);
|
||||
raiseMonitor = true;
|
||||
if(pvFieldOptions!=NULL) {
|
||||
PVStringPtr pvString =
|
||||
pvFieldOptions->getSubField<PVString>("raiseMonitor");
|
||||
if(pvString!=NULL) {
|
||||
std::string value = pvString->get();
|
||||
if(value.compare("false")==0) raiseMonitor = false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual std::string &getName(){return pluginName;}
|
||||
virtual bool causeMonitor(
|
||||
PVFieldPtr const &pvNew,
|
||||
PVStructurePtr const &pvTop,
|
||||
MonitorElementPtr const &monitorElement)
|
||||
{
|
||||
bool isSame = convert->equals(pvNew,pvField);
|
||||
if(isSame) return false;
|
||||
convert->copy(pvNew,pvField);
|
||||
return raiseMonitor;
|
||||
}
|
||||
private:
|
||||
PVFieldPtr pvField;
|
||||
bool raiseMonitor;
|
||||
};
|
||||
class OnChangePluginCreator : public MonitorPluginCreator
|
||||
{
|
||||
public:
|
||||
virtual std::string &getName(){return pluginName;}
|
||||
virtual MonitorPluginPtr create(
|
||||
FieldConstPtr const &field,
|
||||
StructureConstPtr const &top,
|
||||
PVStructurePtr const &pvFieldOptions)
|
||||
{
|
||||
OnChangePluginPtr plugin(new OnChangePlugin());
|
||||
bool result = plugin->init(field,top,pvFieldOptions);
|
||||
if(!result) return MonitorPluginPtr();
|
||||
return plugin;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void ExampleMonitorPlugin::create()
|
||||
{
|
||||
static OnChangePluginCreatorPtr plugin;
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
if(plugin==NULL) {
|
||||
plugin = OnChangePluginCreatorPtr(new OnChangePluginCreator());
|
||||
MonitorPluginManager::get()->addPlugin(pluginName,plugin);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
documentation/examples.zip
Normal file
BIN
documentation/examples.zip
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@ getFieldCreate()->createFieldBuilder()->
|
||||
createStructure();
|
||||
|
||||
// create a structure (cntd.)
|
||||
PVStructure::const_shared_pointer enum_t =
|
||||
StructureConstPtr enum_t =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId("enum_t")->
|
||||
add("index", pvInt)->
|
||||
@@ -26,13 +26,13 @@ PVStructure::const_shared_pointer enum_t =
|
||||
createStructure();
|
||||
|
||||
// create a structure (cntd.)
|
||||
PVStructure::const_shared_pointer ntEnum =
|
||||
StructureConstPtr ntEnum =
|
||||
getFieldCreate()->createFieldBuilder()->
|
||||
setId("uri:ev4:nt/2012/pwd/NTEnum")->
|
||||
setId("epics:nt/NTEnum:1.0")->
|
||||
add("value", enum_t)->
|
||||
addNestedStructure("timeStamp")->
|
||||
setId("time_t")->
|
||||
add("secsPastEpoch", pvLong)->
|
||||
add("secondsPastEpoch", pvLong)->
|
||||
add("nanoseconds", pvInt)->
|
||||
add("userTag", pvInt)->
|
||||
endNested()->
|
||||
|
||||
5537
documentation/pvDataCPP_20140501.html
Normal file
5537
documentation/pvDataCPP_20140501.html
Normal file
File diff suppressed because it is too large
Load Diff
5380
documentation/pvDataCPP_20140708.html
Normal file
5380
documentation/pvDataCPP_20140708.html
Normal file
File diff suppressed because it is too large
Load Diff
5392
documentation/pvDataCPP_20140723.html
Normal file
5392
documentation/pvDataCPP_20140723.html
Normal file
File diff suppressed because it is too large
Load Diff
5478
documentation/pvDataCPP_20141110.html
Normal file
5478
documentation/pvDataCPP_20141110.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,792 +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 pvDataDiscussion</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||
<style type="text/css">
|
||||
/*<![CDATA[*/
|
||||
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||
table { margin-left: auto; margin-right: auto }
|
||||
.diagram { text-align: center; margin: 2.5em 0 }
|
||||
span.opt { color: grey }
|
||||
span.nterm { font-style:italic }
|
||||
span.term { font-family:courier }
|
||||
span.user { font-family:courier }
|
||||
span.user:before { content:"<" }
|
||||
span.user:after { content:">" }
|
||||
.nonnorm { font-style:italic }
|
||||
p.ed { color: #AA0000 }
|
||||
span.ed { color: #AA0000 }
|
||||
p.ed.priv { display: inline; }
|
||||
span.ed.priv { display: inline; }
|
||||
/*]]>*/</style>
|
||||
<!-- Script that generates the Table of Contents -->
|
||||
<script type="text/javascript"
|
||||
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="head">
|
||||
<h1>EPICS pvDataDiscussion</h1>
|
||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
||||
|
||||
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 03-Jul-2013</h2>
|
||||
|
||||
<dl>
|
||||
<dt>Latest version:</dt>
|
||||
<dd><a
|
||||
href="http://epics-pvdata.hg.sourceforge.net/hgweb/epics-pvdata/pvDataCPP/raw-file/tip/documentation/pvDataDiscussion.html">pvDataDiscussion.html</a>
|
||||
</dd>
|
||||
<dt>This version:</dt>
|
||||
<dd>none</dd>
|
||||
<dt>Previous version:</dt>
|
||||
<dd>None</dd>
|
||||
<dt>Editors:</dt>
|
||||
<dd>Marty Kraimer, BNL<dd />
|
||||
</dl>
|
||||
|
||||
<p class="copyright">This product is made available subject to acceptance of the <a
|
||||
href="http://epics-pvdata.sourceforge.net/LICENSE.html">EPICS open source
|
||||
license.</a></p>
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
|
||||
<div id="toc">
|
||||
<h2 class="nocount" style="page-break-before: always">Table of Contents</h2>
|
||||
</div>
|
||||
<div id="contents" class="contents">
|
||||
|
||||
|
||||
<h2>Introduction</h2>
|
||||
<p>As pvDataCPP progressed PVField and derived classes accumulated
|
||||
more and more member functions.
|
||||
These member functions have nothing to do with the primary primary
|
||||
purpose for pvData:
|
||||
<blockquote>pvData (Process Variable Data) defines and implements an efficent
|
||||
way to store, access, and communicate memory resident data structures.</blockquote>
|
||||
This statement appears as the first sentence of pvDataJava.html.
|
||||
A few sentances later the document makes it clear that communication
|
||||
includes efficent network communication.
|
||||
Thus pvData provides an interface for network accessible structured data.
|
||||
The problem of adding member functions that have nothing to do with the primary purpose
|
||||
started with the Java API.
|
||||
It already had extra methods that solved problems that should have had a different solution.
|
||||
This document removes the extra methods so that when new problems arise in the future
|
||||
the solution will not involve adding new member functions to the introspection and data API.
|
||||
</p>
|
||||
<p>The introspection and data API for pvData should only encapuslate methods that support the primary purpose
|
||||
stated above.
|
||||
The interfaces for C++ and Java should be similar so that
|
||||
someone who understands the interface in one of the languages
|
||||
and knows both languages will quickly understand the interface of the other language.</p>
|
||||
<p>There is another problem with the existing API. There are methods that allow the "structure"
|
||||
to change after an pvData object is created. An example is PVField::renameField(String newName).
|
||||
Such methods should not exist.</p>
|
||||
<p>There are methods regarding immutability: setImmutable, isImmutablei, setCapacityMutable, and isCapacityMutable.
|
||||
Should they exists? For now lets assume no.
|
||||
</p>
|
||||
<p>One last issue is the interface for array data. This document proposes a simplified
|
||||
version of what currently exists. It requires that the implementation always provides storage for
|
||||
the complete raw array. The existing APIs allow the implementation to provide the data in
|
||||
"chunks". Giving up this requirement simplifies the array interfaces.
|
||||
The existing C++ implementation of PVValueArray has serious problems.
|
||||
The shared_vector that is implemented in pvDataCP-md provides the solution to fixing
|
||||
the problems. This document describes an API that is very similar to the new Java API
|
||||
except that raw arrays are replaced by shared_vector.</p>
|
||||
<p>This document will first describe changes to the existing Java interfaces
|
||||
and then the corresponding C++ API.</p>
|
||||
<h2>Java API</h2>
|
||||
<p>The following shows which methods will be removed from the existing interfaces
|
||||
and what will be added.
|
||||
The methods to be removed are in <font color = "red">red</font>
|
||||
and methods to add are in <font color = "blue">blue</font>
|
||||
Also the removed methods are at the end with a comment above.
|
||||
The new methods also have a comment.
|
||||
</p>
|
||||
<h3>Introspection Interfaces</h3>
|
||||
|
||||
<pre>interface Field extends Serializable {
|
||||
String getId();
|
||||
Type getType();
|
||||
// following will be removed
|
||||
<font color = "red">void toString(StringBuilder buf);</font>
|
||||
<font color = "red">void toString(StringBuilder buf,int indentLevel);</font>
|
||||
<font color = "red">String toString();</font>
|
||||
}
|
||||
|
||||
<font color = "blue">
|
||||
// new interface
|
||||
interface FieldToString {
|
||||
String toString(Field field);
|
||||
}</font>
|
||||
|
||||
interface Scalar extends Field {
|
||||
ScalarType getScalarType();
|
||||
}
|
||||
|
||||
interface ScalarArray extends Field {
|
||||
ScalarType getElementType();
|
||||
}
|
||||
|
||||
interface Structure extends Field {
|
||||
Field getField(String fieldName);
|
||||
int getFieldIndex(String fieldName);
|
||||
Field[] getFields();
|
||||
Field getField(int fieldIndex);
|
||||
String[] getFieldNames();
|
||||
String getFieldName(int fieldIndex)
|
||||
}
|
||||
|
||||
interface StructureArray extends Field {
|
||||
Structure getStructure();
|
||||
}
|
||||
|
||||
interface FieldCreate {
|
||||
Scalar createScalar(ScalarType scalarType);
|
||||
ScalarArray createScalarArray(ScalarType elementType);
|
||||
StructureArray createStructureArray(Structure elementStructure);
|
||||
Structure createStructure(String[] fieldNames, Field[] field);
|
||||
Structure createStructure(String id,String[] fieldNames, Field[] field);
|
||||
Structure createStructure(Structure structToClone);
|
||||
Field deserialize(ByteBuffer buffer, DeserializableControl control);
|
||||
// following will be removed
|
||||
<font color = "red">Structure appendField(Structure structure,String fieldName, Field field);</font>
|
||||
<font color = "red">Structure appendFields(Structure structure,String[] fieldNames, Field[] fields);</font>
|
||||
}
|
||||
</pre>
|
||||
<h3>Data Interfaces</h3>
|
||||
<pre>
|
||||
interface PVField extends Requester, Serializable {
|
||||
String getFieldName();
|
||||
void setRequester(Requester requester);
|
||||
int getFieldOffset();
|
||||
int getNextFieldOffset();
|
||||
int getNumberFields();
|
||||
Field getField();
|
||||
PVStructure getParent();
|
||||
void postPut();
|
||||
void setPostHandler(PostHandler postHandler);
|
||||
// following will be removed
|
||||
<font color = "red">PVAuxInfo getPVAuxInfo();</font>
|
||||
<font color = "red">boolean isImmutable();</font>
|
||||
<font color = "red">void setImmutable();</font>
|
||||
<font color = "red">void renameField(String newName);</font>
|
||||
<font color = "red">void toString(StringBuilder buf);</font>
|
||||
<font color = "red">void toString(StringBuilder buf,int indentLevel);</font>
|
||||
<font color = "red">String toString();</font>
|
||||
}
|
||||
|
||||
<font color = "blue">
|
||||
// The following is a new interface
|
||||
interface PVFieldToString {
|
||||
String toString(PVField pvField);
|
||||
void setMaxInitialArrayElements(int num);
|
||||
void setMaxFinalArrayElements(int num);
|
||||
int getMaxInitialArrayElements();
|
||||
int getMaxFinalArrayElements();
|
||||
}</font>
|
||||
|
||||
interface PVScalar extends PVField{
|
||||
Scalar getScalar();
|
||||
}
|
||||
|
||||
interface PVDouble extends PVScalar{
|
||||
double get();
|
||||
void put(double value);
|
||||
}
|
||||
// also PVBoolean, PVByte, PVShort, PVInt, PVLong, PVFloat, and PVString
|
||||
|
||||
interface PVArray extends PVField, SerializableArray {
|
||||
int getLength();
|
||||
void setLength(int length);
|
||||
int getCapacity();
|
||||
void setCapacity(int length);
|
||||
// following will be removed
|
||||
<font color = "red">boolean isCapacityMutable();</font>
|
||||
<font color = "red">void setCapacityMutable(boolean isMutable);</font>
|
||||
}
|
||||
|
||||
interface PVScalarArray extends PVArray {
|
||||
ScalarArray getScalarArray();
|
||||
}
|
||||
|
||||
<font color = "red">
|
||||
//following will be removed
|
||||
public class DoubleArrayData {
|
||||
public double[] data;
|
||||
public int offset;
|
||||
}</font>
|
||||
|
||||
interface PVDoubleArray extends PVArray {
|
||||
// following are new
|
||||
<font color = "blue"> double[] get();</font>
|
||||
<font color = "blue"> void swap(double[] value);</font>
|
||||
//following will be removed
|
||||
<font color = "red"> int get(int offset, int len, DoubleArrayData data);</font>
|
||||
<font color = "red"> int put(int offset,int len, double[] from, int fromOffset)</font>;
|
||||
<font color = "red"> void shareData(double[] from);</font>
|
||||
}
|
||||
|
||||
// also PVBooleanArray, ..., PVStringArray
|
||||
|
||||
|
||||
interface PVStructure extends PVField , BitSetSerializable{
|
||||
Structure getStructure();
|
||||
PVField[] getPVFields();
|
||||
PVField getSubField(String fieldName);
|
||||
PVField getSubField(int fieldOffset);
|
||||
// The following are convenience methods
|
||||
PVBoolean getBooleanField(String fieldName);
|
||||
PVByte getByteField(String fieldName);
|
||||
PVShort getShortField(String fieldName);
|
||||
PVInt getIntField(String fieldName);
|
||||
PVLong getLongField(String fieldName);
|
||||
PVFloat getFloatField(String fieldName);
|
||||
PVDouble getDoubleField(String fieldName);
|
||||
PVString getStringField(String fieldName);
|
||||
PVScalarArray getScalarArrayField(String fieldName);
|
||||
PVStructureArray getStructureArrayField(String fieldName);
|
||||
PVStructure getStructureField(String fieldName);
|
||||
PVArray getArrayField(String fieldName,ScalarType elementType);
|
||||
// following will be removed
|
||||
<font color = "red"> void appendPVField(String fieldName,PVField pvField);</font>
|
||||
<font color = "red"> void appendPVFields(String[] fieldNames,PVField[] pvFields);</font>
|
||||
<font color = "red"> void removePVField(String fieldName);</font>
|
||||
<font color = "red"> void replacePVField(PVField oldPVField,PVField newPVField);</font>
|
||||
<font color = "red"> String getExtendsStructureName();</font>
|
||||
<font color = "red"> boolean putExtendsStructureName(String extendsStructureName);</font>
|
||||
<font color = "red"> public boolean checkValid();</font>
|
||||
}
|
||||
|
||||
<font color = "red">
|
||||
//following will be removed
|
||||
public class StructureArrayData {
|
||||
public PVStructure[] data;
|
||||
public int offset;
|
||||
}
|
||||
</font>
|
||||
|
||||
interface PVStructureArray extends PVArray{
|
||||
StructureArray getStructureArray();
|
||||
// following are new
|
||||
<font color = "blue"> PVStructure[] get();</font>
|
||||
<font color = "blue"> void swap(PVStructure[] value);</font>
|
||||
// following will be removed
|
||||
<font color = "red"> int get(int offset, int length, StructureArrayData data);</font>
|
||||
<font color = "red"> int put(int offset,int length, PVStructure[] from, int fromOffset);</font>
|
||||
<font color = "red"> void shareData(PVStructure[] from);</font>
|
||||
}
|
||||
|
||||
|
||||
public interface PVDataCreate {
|
||||
PVField createPVField(Field field);
|
||||
PVField createPVField(PVField fieldToClone);
|
||||
PVScalar createPVScalar(Scalar scalar);
|
||||
PVScalar createPVScalar(ScalarType fieldType);
|
||||
PVScalar createPVScalar(PVScalar scalarToClone);
|
||||
PVScalarArray createPVScalarArray(ScalarArray array);
|
||||
PVScalarArray createPVScalarArray(ScalarType elementType);
|
||||
PVScalarArray createPVScalarArray(PVScalarArray arrayToClone;
|
||||
PVStructureArray createPVStructureArray(StructureArray structureArray);
|
||||
PVStructure createPVStructure(Structure structure);
|
||||
PVStructure createPVStructure(String[] fieldNames,Field[] fields);
|
||||
PVStructure createPVStructure(PVStructure structToClone);
|
||||
// following will be removed
|
||||
<font color = "red">PVField[] flattenPVStructure(PVStructure pvStructure);</font>
|
||||
}
|
||||
</pre>
|
||||
<h3>PVFieldToString</h3>
|
||||
<p>In addition to toString this has methods to limit the number of array element to display.
|
||||
The existing Java implementation of toString displayed all elements.
|
||||
For large arrays this is not desirable.
|
||||
The new methods provide a way for the client to limit the number of elements.
|
||||
The default might be set to something like display up to 10 elements with 5 fron the beginning and 5 from the end.</p>
|
||||
<p>For C++ this can be a replacement for dumpValue.</p>
|
||||
<h3>PVBooleanArray, ..., PVStructureArray</h3>
|
||||
<p>The old get and put are replaced by two new and simpler methods:
|
||||
<dl>
|
||||
<dt>get</dt>
|
||||
<dd>Returns the raw array. If the client code modifies the elements in the array then
|
||||
the client must call postPut. The client also has to realize that if the raw array held by the PVXXXArray changes
|
||||
then the client is no longer sharing data
|
||||
<dt>swap</dt>
|
||||
<dd>This exchanges the old raw data with the new raw data.</dd>
|
||||
</dl>
|
||||
</p>
|
||||
<p>
|
||||
The method <b>setCapacity</b> will always create a new raw array and copy old data from the old to the new array.
|
||||
This is not true now since the implementation does not create a new array if the old capacity is equal to the requested capacity.
|
||||
</p>
|
||||
<h2>C++ API</h2>
|
||||
<p>The C++ class definitions are similar to the Java definitions with two main exceptions:
|
||||
<dl>
|
||||
<dt>toString</dt>
|
||||
<dd>In c++ this is replaced by std::ostream.</dd>
|
||||
<dt>raw array data</dt>
|
||||
<dd>Java supports array data like <b>double[]</b>
|
||||
The C++ replacement is shared_vector<double>, which is implemented
|
||||
in pvDataCPP-md.</dd
|
||||
</dl>
|
||||
<h3>Introspection Interfaces</h3>
|
||||
|
||||
<pre>
|
||||
class Field :
|
||||
virtual public Serializable,
|
||||
public std::tr1::enable_shared_from_this<Field>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(Field);
|
||||
virtual ~Field();
|
||||
Type getType() const{return m_type;}
|
||||
virtual String getID() const = 0;
|
||||
<font color = "red">
|
||||
// following will be removed
|
||||
virtual void toString(StringBuilder buf) const{toString(buf,0);}
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
</font>
|
||||
...
|
||||
};
|
||||
<font color = "blue">
|
||||
// new function
|
||||
std::ostream &toString(Field::const_reference field, std::ostream& o);
|
||||
</font>
|
||||
|
||||
class Scalar : public Field{
|
||||
public:
|
||||
POINTER_DEFINITIONS(Scalar);
|
||||
virtual ~Scalar();
|
||||
typedef Scalar& reference;
|
||||
typedef const Scalar& const_reference;
|
||||
|
||||
ScalarType getScalarType() const {return scalarType;}
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableContol *control);
|
||||
<font color = "red">
|
||||
// following will be removed
|
||||
virtual void toString(StringBuilder buf) const{toString(buf,0);}
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
virtual String getID() const;
|
||||
</font>
|
||||
...
|
||||
};
|
||||
class ScalarArray : public Field{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ScalarArray);
|
||||
typedef ScalarArray& reference;
|
||||
typedef const ScalarArray& const_reference;
|
||||
|
||||
ScalarArray(ScalarType scalarType);
|
||||
ScalarType getElementType() const {return elementType;}
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
<font color = "red">
|
||||
// following will be removed
|
||||
virtual void toString(StringBuilder buf) const{toString(buf,0);}
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
virtual String getID() const;
|
||||
</font>
|
||||
...
|
||||
};
|
||||
|
||||
class Structure : public Field {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Structure);
|
||||
typedef Structure& reference;
|
||||
typedef const Structure& const_reference;
|
||||
|
||||
std::size_t getNumberFields() const {return numberFields;}
|
||||
FieldConstPtr getField(String const & fieldName) const;
|
||||
FieldConstPtr getField(std::size_t index) const;
|
||||
std::size_t getFieldIndex(String const &fieldName) const;
|
||||
FieldConstPtrArray const & getFields() const {return fields;}
|
||||
StringArray const & getFieldNames() const;
|
||||
String getFieldName(std::size_t fieldIndex);
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
<font color = "red">
|
||||
// following will be removed
|
||||
void renameField(std::size_t fieldIndex,String const &newName);
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
virtual String getID() const;
|
||||
</font>
|
||||
...
|
||||
};
|
||||
|
||||
class StructureArray : public Field{
|
||||
public:
|
||||
POINTER_DEFINITIONS(StructureArray);
|
||||
typedef StructureArray& reference;
|
||||
typedef const StructureArray& const_reference;
|
||||
|
||||
StructureConstPtr getStructure() const {return pstructure;}
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
<font color = "red">
|
||||
// following will be removed
|
||||
virtual void toString(StringBuilder buf,int indentLevel=0) const;
|
||||
virtual String getID() const;
|
||||
</font>
|
||||
...
|
||||
};
|
||||
|
||||
class FieldCreate {
|
||||
public:
|
||||
static FieldCreatePtr getFieldCreate();
|
||||
ScalarConstPtr createScalar(ScalarType scalarType) const
|
||||
ScalarArrayConstPtr createScalarArray(ScalarType elementType) const;
|
||||
StructureArrayConstPtr createStructureArray(StructureConstPtr const & structure) const;
|
||||
StructureConstPtr createStructure (
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
StructureConstPtr createStructure (
|
||||
String const &id,
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
FieldConstPtr deserialize(ByteBuffer* buffer, DeserializableControl* control) const;
|
||||
<font color = "red">
|
||||
// following will be removed
|
||||
StructureConstPtr appendField(
|
||||
StructureConstPtr const & structure,
|
||||
String const &fieldName, FieldConstPtr const & field) const;
|
||||
StructureConstPtr appendFields(
|
||||
StructureConstPtr const & structure,
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
</font>
|
||||
...
|
||||
};
|
||||
|
||||
extern FieldCreatePtr getFieldCreate();
|
||||
</pre>
|
||||
<h3>Data Interfaces</h3>
|
||||
<pre>
|
||||
class PVField
|
||||
: virtual public Serializable,
|
||||
public std::tr1::enable_shared_from_this<PVField>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVField);
|
||||
virtual ~PVField();
|
||||
inline const String &getFieldName() const ;
|
||||
virtual void setRequester(RequesterPtr const &prequester);
|
||||
std::size_t getFieldOffset() const;
|
||||
std::size_t getNextFieldOffset() const;
|
||||
std::size_t getNumberFields() const;
|
||||
const FieldConstPtr & getField() const ;
|
||||
PVStructure * getParent() const
|
||||
void postPut() ;
|
||||
void setPostHandler(PostHandlerPtr const &postHandler);
|
||||
// following will be removed
|
||||
<font color = "red">
|
||||
virtual void message(String message,MessageType messageType);
|
||||
void replacePVField(const PVFieldPtr& newPVField);
|
||||
String getFullName() const;
|
||||
virtual bool equals(PVField &pv);
|
||||
PVAuxInfoPtr & getPVAuxInfo()
|
||||
bool isImmutable() const;
|
||||
virtual void setImmutable();
|
||||
void replacePVField(const PVFieldPtr& newPVField);
|
||||
void renameField(String const &newName);
|
||||
virtual void toString(StringBuilder buf) ;
|
||||
virtual void toString(StringBuilder buf,int indentLevel);
|
||||
std::ostream& dumpValue(std::ostream& o) const;
|
||||
</font>
|
||||
...
|
||||
};
|
||||
|
||||
<font color = "blue">
|
||||
// The following is a new class
|
||||
class PVFieldToString {
|
||||
String toString(const PVFieldPtr &pvField);
|
||||
void setMaxInitialArrayElements(size_t num);
|
||||
void setMaxFinalArrayElements(size_t num);
|
||||
size_t getMaxInitialArrayElements();
|
||||
size_t getMaxFinalArrayElements();
|
||||
...
|
||||
}</font>
|
||||
|
||||
class PVScalar : public PVField {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVScalar);
|
||||
virtual ~PVScalar();
|
||||
typedef PVScalar &reference;
|
||||
typedef const PVScalar& const_reference;
|
||||
|
||||
const ScalarConstPtr getScalar() const ;
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
class PVScalarValue : public PVScalar {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVScalarValue);
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
|
||||
virtual ~PVScalarValue() {}
|
||||
virtual T get() const = 0;
|
||||
virtual void put(T value) = 0;
|
||||
<font color = "red">
|
||||
// following will be removed
|
||||
std::ostream& dumpValue(std::ostream& o)
|
||||
void operator>>=(T& value) const;
|
||||
void operator<<=(T value);
|
||||
</font>
|
||||
...
|
||||
}
|
||||
|
||||
// PVString is special case, since it implements SerializableArray
|
||||
class PVString : public PVScalarValue<String>, SerializableArray {
|
||||
public:
|
||||
virtual ~PVString() {}
|
||||
...
|
||||
}
|
||||
class PVArray : public PVField, public SerializableArray {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVArray);
|
||||
virtual ~PVArray();
|
||||
std::size_t getLength() const;
|
||||
virtual void setLength(std::size_t length);
|
||||
std::size_t getCapacity() const;
|
||||
virtual void setCapacity(std::size_t capacity) = 0;
|
||||
<font color = "red">
|
||||
// following will be removed
|
||||
virtual void setImmutable();
|
||||
bool isCapacityMutable() const;
|
||||
void setCapacityMutable(bool isMutable);
|
||||
virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const = 0;
|
||||
</font>
|
||||
...
|
||||
};
|
||||
|
||||
class PVScalarArray : public PVArray {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVScalarArray);
|
||||
virtual ~PVScalarArray();
|
||||
typedef PVScalarArray &reference;
|
||||
typedef const PVScalarArray& const_reference;
|
||||
|
||||
const ScalarArrayConstPtr getScalarArray() const ;
|
||||
<font color = "red">
|
||||
// following will be removed
|
||||
virtual std::ostream& dumpValue(std::ostream& o, size_t index) const = 0;
|
||||
</font>
|
||||
...
|
||||
}
|
||||
|
||||
<font color = "red">
|
||||
// following will be removed
|
||||
template<typename T>
|
||||
class PVArrayData {
|
||||
private:
|
||||
std::vector<T> init;
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVArrayData);
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
std::vector<T> & data;
|
||||
std::size_t offset;
|
||||
PVArrayData()
|
||||
: data(init)
|
||||
{}
|
||||
};
|
||||
</font>
|
||||
|
||||
template<typename T>
|
||||
class PVValueArray : public PVScalarArray {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVValueArray);
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
// following are new typeDefs
|
||||
<font color = "blue">typedef shared_vector<T> svector;</font>
|
||||
<font color = "blue">typedef shared_vector<const T> const_svector; </font>
|
||||
|
||||
virtual ~PVValueArray() {}
|
||||
// following are added
|
||||
<font color = "blue">svector get();</font>
|
||||
<font color = "blue">void swap(svector& value);</font>
|
||||
<font color = "red">
|
||||
// following are removed
|
||||
typedef PVValueArray & reference;
|
||||
typedef const PVValueArray & const_reference;
|
||||
typedef PVArrayData<T> ArrayDataType;
|
||||
typedef std::vector<T> vector;
|
||||
typedef const std::vector<T> const_vector;
|
||||
typedef std::tr1::shared_ptr<vector> shared_vector;
|
||||
|
||||
virtual std::size_t get(
|
||||
std::size_t offset, std::size_t length, ArrayDataType &data) = 0;
|
||||
virtual std::size_t put(std::size_t offset,
|
||||
std::size_t length, const_pointer from, std::size_t fromOffset) = 0;
|
||||
virtual std::size_t put(std::size_t offset,
|
||||
std::size_t length, const_vector &from, std::size_t fromOffset);
|
||||
virtual void shareData(
|
||||
shared_vector const & value,
|
||||
std::size_t capacity,
|
||||
std::size_t length) = 0;
|
||||
virtual pointer get() = 0;
|
||||
virtual pointer get() const = 0;
|
||||
virtual vector const & getVector() = 0;
|
||||
virtual shared_vector const & getSharedVector() = 0;
|
||||
std::ostream& dumpValue(std::ostream& o) const;
|
||||
std::ostream& dumpValue(std::ostream& o, size_t index) const;
|
||||
</font>
|
||||
...
|
||||
};
|
||||
|
||||
typedef PVValueArray<uint8> PVBooleanArray;
|
||||
typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
|
||||
...
|
||||
typedef PVValueArray<String> PVStringArray;
|
||||
typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
|
||||
|
||||
class PVStructure : public PVField,public BitSetSerializable {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVStructure);
|
||||
virtual ~PVStructure();
|
||||
typedef PVStructure & reference;
|
||||
typedef const PVStructure & const_reference;
|
||||
|
||||
StructureConstPtr getStructure() const;
|
||||
const PVFieldPtrArray & getPVFields() const;
|
||||
PVFieldPtr getSubField(String const &fieldName) const;
|
||||
PVFieldPtr getSubField(std::size_t fieldOffset) const;
|
||||
PVBooleanPtr getBooleanField(String const &fieldName) ;
|
||||
PVBytePtr getByteField(String const &fieldName) ;
|
||||
PVShortPtr getShortField(String const &fieldName) ;
|
||||
PVIntPtr getIntField(String const &fieldName) ;
|
||||
PVLongPtr getLongField(String const &fieldName) ;
|
||||
PVUBytePtr getUByteField(String const &fieldName) ;
|
||||
PVUShortPtr getUShortField(String const &fieldName) ;
|
||||
PVUIntPtr getUIntField(String const &fieldName) ;
|
||||
PVULongPtr getULongField(String const &fieldName) ;
|
||||
PVFloatPtr getFloatField(String const &fieldName) ;
|
||||
PVDoublePtr getDoubleField(String const &fieldName) ;
|
||||
PVStringPtr getStringField(String const &fieldName) ;
|
||||
PVStructurePtr getStructureField(String const &fieldName) ;
|
||||
PVScalarArrayPtr getScalarArrayField(
|
||||
String const &fieldName,ScalarType elementType) ;
|
||||
PVStructureArrayPtr getStructureArrayField(String const &fieldName) ;
|
||||
virtual void serialize(
|
||||
ByteBuffer *pbuffer,SerializableControl *pflusher) const ;
|
||||
virtual void deserialize(
|
||||
ByteBuffer *pbuffer,DeserializableControl *pflusher);
|
||||
virtual void serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher,BitSet *pbitSet) const;
|
||||
virtual void deserialize(ByteBuffer *pbuffer,
|
||||
DeserializableControl*pflusher,BitSet *pbitSet);
|
||||
PVStructure(StructureConstPtr const & structure);
|
||||
PVStructure(StructureConstPtr const & structure,PVFieldPtrArray const & pvFields);
|
||||
<font color = "red">
|
||||
// following are removed
|
||||
void appendPVField(
|
||||
String const &fieldName,
|
||||
PVFieldPtr const & pvField);
|
||||
void appendPVFields(
|
||||
StringArray const & fieldNames,
|
||||
PVFieldPtrArray const & pvFields);
|
||||
void removePVField(String const &fieldName);
|
||||
virtual void setImmutable();
|
||||
String getExtendsStructureName() const;
|
||||
bool putExtendsStructureName(
|
||||
String const &extendsStructureName);
|
||||
</font>
|
||||
};
|
||||
|
||||
<font color = "red">
|
||||
// following will be removed
|
||||
typedef PVArrayData<PVStructurePtr> StructureArrayData;
|
||||
</font>
|
||||
|
||||
class PVStructureArray : public PVArray
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVStructureArray);
|
||||
typedef PVStructurePtr value_type;
|
||||
typedef PVStructurePtr* pointer;
|
||||
typedef const PVStructurePtr* const_pointer;
|
||||
<font color = "blue">
|
||||
// following are new typeDefs
|
||||
typedef shared_vector<PVStructurePtr> svector;
|
||||
typedef shared_vector<const PVStructurePtr> const_svector;
|
||||
</font>
|
||||
|
||||
virtual ~PVStructureArray() {}
|
||||
virtual void setCapacity(size_t capacity);
|
||||
virtual void setLength(std::size_t length);
|
||||
virtual StructureArrayConstPtr getStructureArray() const ;
|
||||
virtual void serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher) const;
|
||||
virtual void deserialize(ByteBuffer *buffer,
|
||||
virtual void serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher, std::size_t offset, std::size_t count) const ;
|
||||
// following are new
|
||||
<font color = "blue"> svector get();</font>
|
||||
<font color = "blue"> void swap(svector & value);</font>
|
||||
<font color = "red">
|
||||
// following are removed
|
||||
typedef PVArrayData<PVStructurePtr> ArrayDataType;
|
||||
typedef std::vector<PVStructurePtr> vector;
|
||||
typedef const std::vector<PVStructurePtr> const_vector;
|
||||
typedef std::tr1::shared_ptr<vector> shared_vector;
|
||||
typedef PVStructureArray &reference;
|
||||
typedef const PVStructureArray& const_reference;
|
||||
|
||||
virtual std::size_t append(std::size_t number);
|
||||
virtual bool remove(std::size_t offset,std::size_t number);
|
||||
virtual void compress();
|
||||
virtual std::size_t get(std::size_t offset, std::size_t length,
|
||||
StructureArrayData &data);
|
||||
virtual std::size_t put(std::size_t offset,std::size_t length,
|
||||
const_vector const & from, std::size_t fromOffset);
|
||||
virtual void shareData(
|
||||
shared_vector const & value,
|
||||
std::size_t capacity,
|
||||
std::size_t length);
|
||||
virtual pointer get() { return &((*value.get())[0]); }
|
||||
virtual pointer get() const { return &((*value.get())[0]); }
|
||||
virtual vector const & getVector() {return *value;}
|
||||
virtual shared_vector const & getSharedVector() {return value;}
|
||||
</font>
|
||||
...
|
||||
};
|
||||
|
||||
class PVDataCreate {
|
||||
public:
|
||||
static PVDataCreatePtr getPVDataCreate();
|
||||
PVFieldPtr createPVField(FieldConstPtr const & field);
|
||||
PVFieldPtr createPVField(PVFieldPtr const & fieldToClone);
|
||||
PVScalarPtr createPVScalar(ScalarConstPtr const & scalar);
|
||||
PVScalarPtr createPVScalar(ScalarType scalarType);
|
||||
PVScalarPtr createPVScalar(PVScalarPtr const & scalarToClone);
|
||||
PVScalarArrayPtr createPVScalarArray(ScalarArrayConstPtr const & scalarArray);
|
||||
PVScalarArrayPtr createPVScalarArray(ScalarType elementType);
|
||||
PVScalarArrayPtr createPVScalarArray(PVScalarArrayPtr const & scalarArrayToClone);
|
||||
PVStructureArrayPtr createPVStructureArray(StructureArrayConstPtr const & structureArray);
|
||||
PVStructurePtr createPVStructure(StructureConstPtr const & structure);
|
||||
PVStructurePtr createPVStructure(
|
||||
StringArray const & fieldNames,PVFieldPtrArray const & pvFields);
|
||||
PVStructurePtr createPVStructure(PVStructurePtr const & structToClone);
|
||||
...
|
||||
};
|
||||
|
||||
extern PVDataCreatePtr getPVDataCreate();
|
||||
</pre>
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
466
pvDataCPP.files
466
pvDataCPP.files
@@ -62,42 +62,6 @@ pvDataApp/misc/timeFunction.h
|
||||
pvDataApp/misc/timer.cpp
|
||||
pvDataApp/misc/timer.h
|
||||
pvDataApp/monitor/monitor.h
|
||||
pvDataApp/O.linux-x86_64/alarm.d
|
||||
pvDataApp/O.linux-x86_64/bitSet.d
|
||||
pvDataApp/O.linux-x86_64/bitSetUtil.d
|
||||
pvDataApp/O.linux-x86_64/byteBuffer.d
|
||||
pvDataApp/O.linux-x86_64/Compare.d
|
||||
pvDataApp/O.linux-x86_64/Convert.d
|
||||
pvDataApp/O.linux-x86_64/epicsException.d
|
||||
pvDataApp/O.linux-x86_64/event.d
|
||||
pvDataApp/O.linux-x86_64/executor.d
|
||||
pvDataApp/O.linux-x86_64/FieldCreateFactory.d
|
||||
pvDataApp/O.linux-x86_64/libpvData.a
|
||||
pvDataApp/O.linux-x86_64/libpvData.so
|
||||
pvDataApp/O.linux-x86_64/localStaticLock.d
|
||||
pvDataApp/O.linux-x86_64/messageQueue.d
|
||||
pvDataApp/O.linux-x86_64/pvAlarm.d
|
||||
pvDataApp/O.linux-x86_64/PVArray.d
|
||||
pvDataApp/O.linux-x86_64/PVAuxInfoImpl.d
|
||||
pvDataApp/O.linux-x86_64/pvControl.d
|
||||
pvDataApp/O.linux-x86_64/PVDataCreateFactory.d
|
||||
pvDataApp/O.linux-x86_64/pvDisplay.d
|
||||
pvDataApp/O.linux-x86_64/pvEnumerated.d
|
||||
pvDataApp/O.linux-x86_64/PVField.d
|
||||
pvDataApp/O.linux-x86_64/PVScalar.d
|
||||
pvDataApp/O.linux-x86_64/PVScalarArray.d
|
||||
pvDataApp/O.linux-x86_64/PVStructure.d
|
||||
pvDataApp/O.linux-x86_64/PVStructureArray.d
|
||||
pvDataApp/O.linux-x86_64/pvTimeStamp.d
|
||||
pvDataApp/O.linux-x86_64/requester.d
|
||||
pvDataApp/O.linux-x86_64/serializeHelper.d
|
||||
pvDataApp/O.linux-x86_64/StandardField.d
|
||||
pvDataApp/O.linux-x86_64/StandardPVField.d
|
||||
pvDataApp/O.linux-x86_64/status.d
|
||||
pvDataApp/O.linux-x86_64/timeFunction.d
|
||||
pvDataApp/O.linux-x86_64/timer.d
|
||||
pvDataApp/O.linux-x86_64/timeStamp.d
|
||||
pvDataApp/O.linux-x86_64/TypeFunc.d
|
||||
pvDataApp/property/alarm.cpp
|
||||
pvDataApp/property/alarm.h
|
||||
pvDataApp/property/alarm.h.orig
|
||||
@@ -117,45 +81,15 @@ pvDataApp/property/timeStamp.cpp
|
||||
pvDataApp/property/timeStamp.h
|
||||
pvDataApp/property/timeStamp.h.orig
|
||||
pvDataApp/pv/convert.h
|
||||
pvDataApp/pv/convert.h.orig
|
||||
pvDataApp/pv/pvData.h
|
||||
pvDataApp/pv/pvData.h.orig
|
||||
pvDataApp/pv/pvIntrospect.h
|
||||
pvDataApp/pv/pvIntrospect.h.orig
|
||||
pvDataApp/pv/pvType.h
|
||||
pvDataApp/pv/standardField.h
|
||||
pvDataApp/pv/standardField.h.orig
|
||||
pvDataApp/pv/standardPVField.h
|
||||
pvDataApp/pv/standardPVField.h.orig
|
||||
pvDataApp/pvMisc/bitSetUtil.cpp
|
||||
pvDataApp/pvMisc/bitSetUtil.h
|
||||
testApp/capi/O.linux-x86_64/libtestc.a
|
||||
testApp/capi/O.linux-x86_64/libtestc.so
|
||||
testApp/capi/O.linux-x86_64/testc.d
|
||||
testApp/capi/testc.cpp
|
||||
testApp/capi/testc.py
|
||||
testApp/mb/O.linux-x86_64/mb_test
|
||||
testApp/mb/O.linux-x86_64/mb_test.d
|
||||
testApp/misc/O.linux-x86_64/testBaseException
|
||||
testApp/misc/O.linux-x86_64/testBaseException.d
|
||||
testApp/misc/O.linux-x86_64/testBitSet
|
||||
testApp/misc/O.linux-x86_64/testBitSet.d
|
||||
testApp/misc/O.linux-x86_64/testByteBuffer
|
||||
testApp/misc/O.linux-x86_64/testByteBuffer.d
|
||||
testApp/misc/O.linux-x86_64/testByteOrder
|
||||
testApp/misc/O.linux-x86_64/testByteOrder.d
|
||||
testApp/misc/O.linux-x86_64/testMessageQueue
|
||||
testApp/misc/O.linux-x86_64/testMessageQueue.d
|
||||
testApp/misc/O.linux-x86_64/testQueue
|
||||
testApp/misc/O.linux-x86_64/testQueue.d
|
||||
testApp/misc/O.linux-x86_64/testSerialization
|
||||
testApp/misc/O.linux-x86_64/testSerialization.d
|
||||
testApp/misc/O.linux-x86_64/testThread
|
||||
testApp/misc/O.linux-x86_64/testThread.d
|
||||
testApp/misc/O.linux-x86_64/testTimer
|
||||
testApp/misc/O.linux-x86_64/testTimer.d
|
||||
testApp/misc/O.linux-x86_64/testTimeStamp
|
||||
testApp/misc/O.linux-x86_64/testTimeStamp.d
|
||||
testApp/misc/testBaseException.cpp
|
||||
testApp/misc/testBitSet.cpp
|
||||
testApp/misc/testByteBuffer.cpp
|
||||
@@ -166,34 +100,8 @@ testApp/misc/testSerialization.cpp
|
||||
testApp/misc/testThread.cpp
|
||||
testApp/misc/testTimer.cpp
|
||||
testApp/misc/testTimeStamp.cpp
|
||||
testApp/monitor/O.linux-x86_64/testMonitor
|
||||
testApp/monitor/O.linux-x86_64/testMonitor.d
|
||||
testApp/monitor/testMonitor.cpp
|
||||
testApp/property/O.linux-x86_64/testProperty
|
||||
testApp/property/O.linux-x86_64/testProperty.d
|
||||
testApp/property/testProperty.cpp
|
||||
testApp/pv/O.linux-x86_64/testConvert
|
||||
testApp/pv/O.linux-x86_64/testConvert.d
|
||||
testApp/pv/O.linux-x86_64/testIntrospect
|
||||
testApp/pv/O.linux-x86_64/testIntrospect.d
|
||||
testApp/pv/O.linux-x86_64/testOperators
|
||||
testApp/pv/O.linux-x86_64/testOperators.d
|
||||
testApp/pv/O.linux-x86_64/testPVAppend
|
||||
testApp/pv/O.linux-x86_64/testPVAppend.d
|
||||
testApp/pv/O.linux-x86_64/testPVAuxInfo
|
||||
testApp/pv/O.linux-x86_64/testPVAuxInfo.d
|
||||
testApp/pv/O.linux-x86_64/testPVData
|
||||
testApp/pv/O.linux-x86_64/testPVData.d
|
||||
testApp/pv/O.linux-x86_64/testPVScalarArray
|
||||
testApp/pv/O.linux-x86_64/testPVScalarArray.d
|
||||
testApp/pv/O.linux-x86_64/testPVStructureArray
|
||||
testApp/pv/O.linux-x86_64/testPVStructureArray.d
|
||||
testApp/pv/O.linux-x86_64/testPVType
|
||||
testApp/pv/O.linux-x86_64/testPVType.d
|
||||
testApp/pv/O.linux-x86_64/testStandardField
|
||||
testApp/pv/O.linux-x86_64/testStandardField.d
|
||||
testApp/pv/O.linux-x86_64/testStandardPVField
|
||||
testApp/pv/O.linux-x86_64/testStandardPVField.d
|
||||
testApp/pv/testConvert.cpp
|
||||
testApp/pv/testIntrospect.cpp
|
||||
testApp/pv/testOperators.cpp
|
||||
@@ -208,4 +116,376 @@ testApp/pv/testStandardPVField.cpp
|
||||
COPYRIGHT
|
||||
Doxyfile
|
||||
LICENSE
|
||||
README.html
|
||||
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
|
||||
|
||||
@@ -3,4 +3,9 @@
|
||||
/home/msekoranja/epicsV4/pvDataCPP/pvDataApp/monitor
|
||||
/home/msekoranja/epicsV4/pvDataCPP/pvDataApp/property
|
||||
/home/msekoranja/epicsV4/pvDataCPP/pvDataApp/pv
|
||||
/home/msekoranja/epicsV4/pvDataCPP/pvDataApp/pvMisc
|
||||
/home/msekoranja/epicsV4/pvDataCPP/pvDataApp/pvMisc
|
||||
testApp/pv
|
||||
testApp/copy
|
||||
testApp/misc
|
||||
testApp
|
||||
testApp/property
|
||||
|
||||
@@ -12,6 +12,7 @@ include $(PVDATA_SRC)/misc/Makefile
|
||||
include $(PVDATA_SRC)/pv/Makefile
|
||||
include $(PVDATA_SRC)/factory/Makefile
|
||||
include $(PVDATA_SRC)/property/Makefile
|
||||
include $(PVDATA_SRC)/copy/Makefile
|
||||
include $(PVDATA_SRC)/pvMisc/Makefile
|
||||
include $(PVDATA_SRC)/monitor/Makefile
|
||||
|
||||
|
||||
9
src/copy/Makefile
Normal file
9
src/copy/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
SRC_DIRS += $(PVDATA_SRC)/copy
|
||||
|
||||
INC += createRequest.h
|
||||
INC += pvCopy.h
|
||||
|
||||
LIBSRCS += createRequest.cpp
|
||||
LIBSRCS += pvCopy.cpp
|
||||
483
src/copy/createRequest.cpp
Normal file
483
src/copy/createRequest.cpp
Normal file
@@ -0,0 +1,483 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* pvAccessCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/createRequest.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
using std::ostringstream;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
class CreateRequestImpl : public CreateRequest {
|
||||
private:
|
||||
|
||||
struct Node
|
||||
{
|
||||
string name;
|
||||
vector<Node> nodes;
|
||||
Node(string name)
|
||||
: name(name)
|
||||
{}
|
||||
};
|
||||
|
||||
struct OptionPair
|
||||
{
|
||||
string name;
|
||||
string value;
|
||||
OptionPair(string name,string value)
|
||||
: name(name),
|
||||
value(value)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
vector<OptionPair> optionList;
|
||||
string fullFieldName;
|
||||
|
||||
|
||||
public:
|
||||
CreateRequestImpl()
|
||||
{
|
||||
fullFieldName = "";
|
||||
}
|
||||
private:
|
||||
|
||||
|
||||
void removeBlanks(string& str)
|
||||
{
|
||||
while(true) {
|
||||
string::size_type pos = str.find_first_of(' ');
|
||||
if(pos==string::npos) return;
|
||||
str.erase(pos,1);
|
||||
}
|
||||
}
|
||||
|
||||
size_t findMatchingBrace(string& request, size_t index, int numOpen) {
|
||||
size_t openBrace = request.find('{', index+1);
|
||||
size_t closeBrace = request.find('}', index+1);
|
||||
if(openBrace == string::npos && closeBrace == string::npos){
|
||||
message = request + " mismatched {}";
|
||||
throw std::logic_error("message");
|
||||
}
|
||||
if (openBrace != string::npos && openBrace!=0) {
|
||||
if(openBrace<closeBrace) return findMatchingBrace(request,openBrace,numOpen+1);
|
||||
if(numOpen==1) return closeBrace;
|
||||
return findMatchingBrace(request,closeBrace,numOpen-1);
|
||||
}
|
||||
if(numOpen==1) return closeBrace;
|
||||
return findMatchingBrace(request,closeBrace,numOpen-1);
|
||||
}
|
||||
|
||||
size_t findMatchingBracket(string& request, size_t index) {
|
||||
for(size_t i=index+1; i< request.size(); ++i) {
|
||||
if(request[i] == ']') {
|
||||
if(i==index+1) {
|
||||
message = request + " mismatched []";
|
||||
throw std::logic_error("message");
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
message = request + " missing ]";
|
||||
throw std::logic_error("message");
|
||||
}
|
||||
|
||||
size_t findEndField(string& request) {
|
||||
size_t ind = 0;
|
||||
size_t maxind = request.size() -1;
|
||||
while(true) {
|
||||
if(request[ind]==',') return ind;
|
||||
if(request[ind]=='[') {
|
||||
size_t closeBracket = findMatchingBracket(request,ind);
|
||||
if(closeBracket==string::npos) return closeBracket;
|
||||
ind = closeBracket;
|
||||
continue;
|
||||
}
|
||||
if(request[ind]=='{') {
|
||||
size_t closeBrace = findMatchingBrace(request,ind,1);
|
||||
if(closeBrace==string::npos) return closeBrace;
|
||||
if(ind>=request.size()) return request.size();
|
||||
ind = closeBrace;
|
||||
continue;
|
||||
}
|
||||
if(request[ind]=='.') {
|
||||
++ind;
|
||||
continue;
|
||||
}
|
||||
if(ind>=maxind) break;
|
||||
++ind;
|
||||
}
|
||||
return request.size();
|
||||
}
|
||||
|
||||
vector<string> split(string const & commaSeparatedList) {
|
||||
string::size_type numValues = 1;
|
||||
string::size_type index=0;
|
||||
while(true) {
|
||||
string::size_type pos = commaSeparatedList.find(',',index);
|
||||
if(pos==string::npos) break;
|
||||
numValues++;
|
||||
index = pos +1;
|
||||
}
|
||||
vector<string> valueList(numValues,"");
|
||||
index=0;
|
||||
for(size_t i=0; i<numValues; i++) {
|
||||
size_t pos = commaSeparatedList.find(',',index);
|
||||
string value = commaSeparatedList.substr(index,pos-index);
|
||||
valueList[i] = value;
|
||||
index = pos +1;
|
||||
}
|
||||
return valueList;
|
||||
}
|
||||
|
||||
Node createRequestOptions(
|
||||
string const & request)
|
||||
{
|
||||
if(request.length()<=1) {
|
||||
throw std::logic_error("logic error empty options");
|
||||
}
|
||||
vector<Node> top;
|
||||
vector<string> items = split(request);
|
||||
|
||||
size_t nitems = items.size();
|
||||
for(size_t j=0; j<nitems; j++) {
|
||||
string item = items[j];
|
||||
size_t equals = item.find('=');
|
||||
if(equals==string::npos || equals==0) {
|
||||
message = item + " illegal option " + request;
|
||||
throw std::logic_error("message");
|
||||
}
|
||||
top.push_back(Node(item.substr(0,equals)));
|
||||
string name = fullFieldName + "._options." + item.substr(0,equals);
|
||||
string value = item.substr(equals+1);
|
||||
optionList.push_back(OptionPair(name,value));
|
||||
}
|
||||
Node node("_options");
|
||||
node.nodes = top;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
void createSubNode(Node &node,string const & crequest)
|
||||
{
|
||||
string request = crequest;
|
||||
size_t end = 0;
|
||||
for(size_t i=0; i<request.size(); ++i) {
|
||||
if(request[i]=='[') { end = i; break;}
|
||||
if(request[i]=='.') { end = i; break;}
|
||||
if(request[i]=='{') { end = i; break;}
|
||||
if(request[i]==',') { end = i; break;}
|
||||
}
|
||||
char chr = request[end];
|
||||
Node optionNode("");
|
||||
if(chr=='[') {
|
||||
string saveFullName = fullFieldName;
|
||||
fullFieldName += "." + request.substr(0,end);
|
||||
size_t endBracket = findMatchingBracket(request,end);
|
||||
string options = request.substr(end+1,endBracket -end -1);
|
||||
optionNode = createRequestOptions(options);
|
||||
fullFieldName = saveFullName;
|
||||
size_t next = endBracket+1;
|
||||
if(next<request.size()) {
|
||||
request = request.substr(0, end) + request.substr(endBracket+1);
|
||||
} else {
|
||||
request = request.substr(0, end);
|
||||
}
|
||||
end = 0;
|
||||
for(size_t i=0; i<request.size(); ++i) {
|
||||
if(request[i]=='.') { end = i; break;}
|
||||
if(request[i]=='{') { end = i; break;}
|
||||
if(request[i]==',') { end = i; break;}
|
||||
}
|
||||
chr = request[end];
|
||||
}
|
||||
if(end==0) end = request.size();
|
||||
string name = request.substr(0,end);
|
||||
if(name.size()<1) {
|
||||
throw std::logic_error("null field name " + request);
|
||||
}
|
||||
string saveFullName = fullFieldName;
|
||||
fullFieldName += "." + name;
|
||||
if(end==request.size()) {
|
||||
Node subNode(name);
|
||||
if(optionNode.name.size()>0) subNode.nodes.push_back(optionNode);
|
||||
node.nodes.push_back(subNode);
|
||||
fullFieldName = saveFullName;
|
||||
return;
|
||||
}
|
||||
if(chr==',') {
|
||||
Node subNode(name);
|
||||
if(optionNode.name.size()>0) subNode.nodes.push_back(optionNode);
|
||||
node.nodes.push_back(subNode);
|
||||
string rest = request.substr(end+1);
|
||||
fullFieldName = saveFullName;
|
||||
createSubNode(node,rest);
|
||||
return;
|
||||
}
|
||||
if(chr=='.') {
|
||||
request = request.substr(end+1);
|
||||
if(request.size()==string::npos || request.size()<1) {
|
||||
throw std::logic_error("null field name " + request);
|
||||
}
|
||||
Node subNode(name);
|
||||
if(optionNode.name.size()>0) subNode.nodes.push_back(optionNode);
|
||||
size_t endField = findEndField(request);
|
||||
string subRequest = request.substr(0, endField);
|
||||
createSubNode(subNode,subRequest);
|
||||
node.nodes.push_back(subNode);
|
||||
size_t next = endField+1;
|
||||
if(next>=request.size()) {
|
||||
fullFieldName = saveFullName;
|
||||
return;
|
||||
}
|
||||
request = request.substr(next);
|
||||
fullFieldName = saveFullName;
|
||||
createSubNode(node,request);
|
||||
return;
|
||||
}
|
||||
if(chr=='{') {
|
||||
size_t endBrace = findEndField(request);
|
||||
if((end+1)>=(endBrace-1)) {
|
||||
throw std::logic_error("illegal syntax " + request);
|
||||
}
|
||||
string subRequest = request.substr(end+1,endBrace-1 -end -1);
|
||||
if(subRequest.size()<1) {
|
||||
throw std::logic_error("empty {} " + request);
|
||||
}
|
||||
Node subNode(name);
|
||||
if(optionNode.name.size()>0) subNode.nodes.push_back(optionNode);
|
||||
createSubNode(subNode,subRequest);
|
||||
node.nodes.push_back(subNode);
|
||||
size_t next = endBrace + 1;
|
||||
if(next>=request.size()) {
|
||||
fullFieldName = saveFullName;
|
||||
return;
|
||||
}
|
||||
request = request.substr(next);
|
||||
fullFieldName = saveFullName;
|
||||
createSubNode(node,request);
|
||||
return;
|
||||
}
|
||||
throw std::logic_error("logic error");
|
||||
}
|
||||
|
||||
FieldConstPtr createSubStructure(vector<Node> & nodes)
|
||||
{
|
||||
size_t num = nodes.size();
|
||||
StringArray names(num);
|
||||
FieldConstPtrArray fields(num);
|
||||
for(size_t i=0; i<num; ++i) {
|
||||
Node node = nodes[i];
|
||||
names[i] = node.name;
|
||||
if(node.name.compare("_options")==0) {
|
||||
fields[i] = createOptions(node.nodes);
|
||||
} else {
|
||||
vector<Node> subNode = node.nodes;
|
||||
if(subNode.empty()) {
|
||||
fields[i] = fieldCreate->createStructure();
|
||||
} else {
|
||||
fields[i] = createSubStructure(subNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
StructureConstPtr structure = fieldCreate->createStructure(
|
||||
names, fields);
|
||||
return structure;
|
||||
}
|
||||
|
||||
StructureConstPtr createOptions(vector<Node> &nodes)
|
||||
{
|
||||
size_t num = nodes.size();
|
||||
StringArray names(num);
|
||||
FieldConstPtrArray fields(num);
|
||||
for(size_t i=0; i<num; ++i) {
|
||||
Node node = nodes[i];
|
||||
names[i] = node.name;
|
||||
fields[i] = fieldCreate->createScalar(pvString);
|
||||
}
|
||||
StructureConstPtr structure = fieldCreate->createStructure(names, fields);
|
||||
return structure;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
virtual PVStructurePtr createRequest(
|
||||
string const & crequest)
|
||||
{
|
||||
try {
|
||||
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(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();
|
||||
}
|
||||
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;
|
||||
} catch (std::exception &e) {
|
||||
message = e.what();
|
||||
return PVStructurePtr();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
CreateRequest::shared_pointer CreateRequest::create()
|
||||
{
|
||||
CreateRequest::shared_pointer createRequest(new CreateRequestImpl());
|
||||
return createRequest;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
56
src/copy/createRequest.h
Normal file
56
src/copy/createRequest.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*createRequest.h*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#ifndef CREATEREQUEST_H
|
||||
#define CREATEREQUEST_H
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/lock.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/**
|
||||
* Class to create pvRequest structures to pass to pvAccess Channel methods.
|
||||
*/
|
||||
class epicsShareClass CreateRequest {
|
||||
public:
|
||||
POINTER_DEFINITIONS(CreateRequest);
|
||||
/**
|
||||
* Create s new instance of CreateRequest
|
||||
* @returns A shared pointer to the new instance.
|
||||
*/
|
||||
static CreateRequest::shared_pointer create();
|
||||
virtual ~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.
|
||||
*/
|
||||
virtual PVStructure::shared_pointer createRequest(std::string const & request) = 0;
|
||||
/**
|
||||
* Get the error message of createRequest returns NULL
|
||||
* return the error message
|
||||
*/
|
||||
std::string getMessage() {return message;}
|
||||
protected:
|
||||
CreateRequest() {}
|
||||
std::string message;
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif /* CREATEREQUEST_H */
|
||||
|
||||
650
src/copy/pvCopy.cpp
Normal file
650
src/copy/pvCopy.cpp
Normal file
@@ -0,0 +1,650 @@
|
||||
/* pvCopy.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author Marty Kraimer
|
||||
* @date 2013.04
|
||||
*/
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <pv/thread.h>
|
||||
|
||||
#include <pv/pvCopy.h>
|
||||
#include <pv/convert.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
using std::string;
|
||||
using std::size_t;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static PVCopyPtr NULLPVCopy;
|
||||
static FieldConstPtr NULLField;
|
||||
static StructureConstPtr NULLStructure;
|
||||
static PVStructurePtr NULLPVStructure;
|
||||
static CopyNodePtr NULLCopyNode;
|
||||
static CopyMasterNodePtr NULLCopyMasterNode;
|
||||
|
||||
struct CopyNode {
|
||||
CopyNode()
|
||||
: isStructure(false),
|
||||
structureOffset(0),
|
||||
nfields(0)
|
||||
{}
|
||||
bool isStructure;
|
||||
size_t structureOffset; // In the copy
|
||||
size_t nfields;
|
||||
PVStructurePtr options;
|
||||
};
|
||||
|
||||
struct CopyMasterNode : public CopyNode{
|
||||
PVFieldPtr masterPVField;
|
||||
};
|
||||
|
||||
typedef std::vector<CopyNodePtr> CopyNodePtrArray;
|
||||
typedef std::tr1::shared_ptr<CopyNodePtrArray> CopyNodePtrArrayPtr;
|
||||
|
||||
struct CopyStructureNode : public CopyNode {
|
||||
CopyNodePtrArrayPtr nodes;
|
||||
};
|
||||
|
||||
PVCopyPtr PVCopy::create(
|
||||
PVStructurePtr const &pvMaster,
|
||||
PVStructurePtr const &pvRequest,
|
||||
string const & structureName)
|
||||
{
|
||||
PVStructurePtr pvStructure(pvRequest);
|
||||
if(structureName.size()>0) {
|
||||
if(pvRequest->getStructure()->getNumberFields()>0) {
|
||||
pvStructure = pvRequest->getStructureField(structureName);
|
||||
if(!pvStructure) return NULLPVCopy;
|
||||
}
|
||||
} else if(pvStructure->getSubField("field")) {
|
||||
pvStructure = pvRequest->getStructureField("field");
|
||||
}
|
||||
PVCopyPtr pvCopy = PVCopyPtr(new PVCopy(pvMaster));
|
||||
bool result = pvCopy->init(pvStructure);
|
||||
if(!result) pvCopy.reset();
|
||||
return pvCopy;
|
||||
}
|
||||
|
||||
PVCopy::PVCopy(
|
||||
PVStructurePtr const &pvMaster)
|
||||
: pvMaster(pvMaster)
|
||||
{
|
||||
}
|
||||
|
||||
void PVCopy::destroy()
|
||||
{
|
||||
headNode.reset();
|
||||
}
|
||||
|
||||
PVStructurePtr PVCopy::getPVMaster()
|
||||
{
|
||||
return pvMaster;
|
||||
}
|
||||
|
||||
void PVCopy::traverseMaster(CopyNodePtr const &innode, PVCopyTraverseMasterCallbackPtr const & callback)
|
||||
{
|
||||
CopyNodePtr node = innode;
|
||||
if(!node->isStructure) {
|
||||
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(node);
|
||||
callback->nextMasterPVField(masterNode->masterPVField);
|
||||
return;
|
||||
}
|
||||
CopyStructureNodePtr structNode = static_pointer_cast<CopyStructureNode>(node);
|
||||
CopyNodePtrArrayPtr nodes = structNode->nodes;
|
||||
for(size_t i=0; i< nodes->size(); i++) {
|
||||
node = (*nodes)[i];
|
||||
traverseMaster(node,callback);
|
||||
}
|
||||
}
|
||||
|
||||
StructureConstPtr PVCopy::getStructure()
|
||||
{
|
||||
return structure;
|
||||
}
|
||||
|
||||
PVStructurePtr PVCopy::createPVStructure()
|
||||
{
|
||||
if(cacheInitStructure) {
|
||||
PVStructurePtr save = cacheInitStructure;
|
||||
cacheInitStructure.reset();
|
||||
return save;
|
||||
}
|
||||
PVStructurePtr pvStructure =
|
||||
getPVDataCreate()->createPVStructure(structure);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVStructurePtr PVCopy::getOptions(std::size_t fieldOffset)
|
||||
{
|
||||
if(fieldOffset==0) return headNode->options;
|
||||
CopyNodePtr node = headNode;
|
||||
while(true) {
|
||||
if(!node->isStructure) {
|
||||
if(node->structureOffset==fieldOffset) return node->options;
|
||||
return NULLPVStructure;
|
||||
}
|
||||
CopyStructureNodePtr structNode = static_pointer_cast<CopyStructureNode>(node);
|
||||
CopyNodePtrArrayPtr nodes = structNode->nodes;
|
||||
boolean okToContinue = false;
|
||||
for(size_t i=0; i< nodes->size(); i++) {
|
||||
node = (*nodes)[i];
|
||||
size_t soff = node->structureOffset;
|
||||
if(fieldOffset>=soff && fieldOffset<soff+node->nfields) {
|
||||
if(fieldOffset==soff) return node->options;
|
||||
if(!node->isStructure) {
|
||||
return NULLPVStructure;
|
||||
}
|
||||
okToContinue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(okToContinue) continue;
|
||||
throw std::invalid_argument("fieldOffset not valid");
|
||||
}
|
||||
}
|
||||
|
||||
size_t PVCopy::getCopyOffset(PVFieldPtr const &masterPVField)
|
||||
{
|
||||
if(masterPVField->getFieldOffset()==0) return 0;
|
||||
if(!headNode->isStructure) {
|
||||
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(headNode);
|
||||
if((masterNode->masterPVField.get())==masterPVField.get()) {
|
||||
return headNode->structureOffset;
|
||||
}
|
||||
PVStructure * parent = masterPVField->getParent();
|
||||
size_t offsetParent = parent->getFieldOffset();
|
||||
size_t off = masterPVField->getFieldOffset();
|
||||
size_t offdiff = off -offsetParent;
|
||||
if(offdiff<masterNode->nfields) return headNode->structureOffset + offdiff;
|
||||
return string::npos;
|
||||
}
|
||||
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
|
||||
CopyMasterNodePtr masterNode = getCopyOffset(node,masterPVField);
|
||||
if(masterNode) return masterNode->structureOffset;
|
||||
return string::npos;
|
||||
}
|
||||
|
||||
size_t PVCopy::getCopyOffset(
|
||||
PVStructurePtr const &masterPVStructure,
|
||||
PVFieldPtr const &masterPVField)
|
||||
{
|
||||
CopyMasterNodePtr masterNode;
|
||||
if(!headNode->isStructure) {
|
||||
masterNode = static_pointer_cast<CopyMasterNode>(headNode);
|
||||
if(masterNode->masterPVField.get()!=masterPVStructure.get()) return string::npos;
|
||||
} else {
|
||||
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
|
||||
masterNode = getCopyOffset(node,masterPVField);
|
||||
}
|
||||
if(!masterNode) return string::npos;
|
||||
size_t diff = masterPVField->getFieldOffset()
|
||||
- masterPVStructure->getFieldOffset();
|
||||
return masterNode->structureOffset + diff;
|
||||
}
|
||||
|
||||
PVFieldPtr PVCopy::getMasterPVField(size_t structureOffset)
|
||||
{
|
||||
CopyMasterNodePtr masterNode;
|
||||
if(!headNode->isStructure) {
|
||||
masterNode = static_pointer_cast<CopyMasterNode>(headNode);
|
||||
} else {
|
||||
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
|
||||
masterNode = getMasterNode(node,structureOffset);
|
||||
}
|
||||
if(!masterNode) {
|
||||
throw std::invalid_argument(
|
||||
"PVCopy::getMasterPVField: setstructureOffset not valid");
|
||||
}
|
||||
size_t diff = structureOffset - masterNode->structureOffset;
|
||||
PVFieldPtr pvMasterField = masterNode->masterPVField;
|
||||
if(diff==0) return pvMasterField;
|
||||
PVStructurePtr pvStructure
|
||||
= static_pointer_cast<PVStructure>(pvMasterField);
|
||||
return pvStructure->getSubField(
|
||||
pvMasterField->getFieldOffset() + diff);
|
||||
}
|
||||
|
||||
void PVCopy::initCopy(
|
||||
PVStructurePtr const ©PVStructure,
|
||||
BitSetPtr const &bitSet)
|
||||
{
|
||||
bitSet->clear();
|
||||
bitSet->set(0);
|
||||
updateCopyFromBitSet(copyPVStructure,bitSet);
|
||||
}
|
||||
|
||||
void PVCopy::updateCopySetBitSet(
|
||||
PVStructurePtr const ©PVStructure,
|
||||
BitSetPtr const &bitSet)
|
||||
{
|
||||
if(headNode->isStructure) {
|
||||
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
|
||||
updateStructureNodeSetBitSet(copyPVStructure,node,bitSet);
|
||||
} else {
|
||||
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(headNode);
|
||||
PVFieldPtr pvMasterField= masterNode->masterPVField;
|
||||
PVFieldPtr copyPVField = copyPVStructure;
|
||||
PVFieldPtr pvField = pvMasterField;
|
||||
if(pvField->getField()->getType()==epics::pvData::structure) {
|
||||
updateSubFieldSetBitSet(copyPVField,pvMasterField,bitSet);
|
||||
return;
|
||||
}
|
||||
ConvertPtr convert = getConvert();
|
||||
bool isEqual = convert->equals(copyPVField,pvField);
|
||||
if(!isEqual) {
|
||||
convert->copy(pvField, copyPVField);
|
||||
bitSet->set(copyPVField->getFieldOffset());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PVCopy::updateCopyFromBitSet(
|
||||
PVStructurePtr const ©PVStructure,
|
||||
BitSetPtr const &bitSet)
|
||||
{
|
||||
bool doAll = bitSet->get(0);
|
||||
if(headNode->isStructure) {
|
||||
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
|
||||
updateStructureNodeFromBitSet(copyPVStructure,node,bitSet,true,doAll);
|
||||
} else {
|
||||
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(headNode);
|
||||
updateSubFieldFromBitSet(copyPVStructure, masterNode->masterPVField,bitSet, true,doAll);
|
||||
}
|
||||
}
|
||||
|
||||
void PVCopy::updateMaster(
|
||||
PVStructurePtr const ©PVStructure,
|
||||
BitSetPtr const &bitSet)
|
||||
{
|
||||
bool doAll = bitSet->get(0);
|
||||
if(headNode->isStructure) {
|
||||
CopyStructureNodePtr node =
|
||||
static_pointer_cast<CopyStructureNode>(headNode);
|
||||
updateStructureNodeFromBitSet(
|
||||
copyPVStructure,node,bitSet,false,doAll);
|
||||
} else {
|
||||
CopyMasterNodePtr masterNode =
|
||||
static_pointer_cast<CopyMasterNode>(headNode);
|
||||
updateSubFieldFromBitSet( copyPVStructure,masterNode->masterPVField,bitSet,false,doAll);
|
||||
}
|
||||
}
|
||||
|
||||
string PVCopy::dump()
|
||||
{
|
||||
string builder;
|
||||
dump(&builder,headNode,0);
|
||||
return builder;
|
||||
}
|
||||
|
||||
void PVCopy::dump(string *builder,CopyNodePtr const &node,int indentLevel)
|
||||
{
|
||||
getConvert()->newLine(builder,indentLevel);
|
||||
std::stringstream ss;
|
||||
ss << (node->isStructure ? "structureNode" : "masterNode");
|
||||
ss << " structureOffset " << node->structureOffset;
|
||||
ss << " nfields " << node->nfields;
|
||||
*builder += ss.str();
|
||||
PVStructurePtr options = node->options;
|
||||
if(options) {
|
||||
getConvert()->newLine(builder,indentLevel +1);
|
||||
|
||||
// TODO !!! ugly
|
||||
std::ostringstream oss;
|
||||
oss << *options;
|
||||
*builder += oss.str();
|
||||
|
||||
getConvert()->newLine(builder,indentLevel);
|
||||
}
|
||||
if(!node->isStructure) {
|
||||
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(node);
|
||||
string name = masterNode->masterPVField->getFullName();
|
||||
*builder += " masterField " + name;
|
||||
return;
|
||||
}
|
||||
CopyStructureNodePtr structureNode =
|
||||
static_pointer_cast<CopyStructureNode>(node);
|
||||
CopyNodePtrArrayPtr nodes = structureNode->nodes;
|
||||
for(size_t i=0; i<nodes->size(); ++i) {
|
||||
if((*nodes)[i].get()==NULL) {
|
||||
getConvert()->newLine(builder,indentLevel +1);
|
||||
ss.str("");
|
||||
ss << "node[" << i << "] is null";
|
||||
*builder += ss.str();
|
||||
continue;
|
||||
}
|
||||
dump(builder,(*nodes)[i],indentLevel+1);
|
||||
}
|
||||
}
|
||||
|
||||
bool PVCopy::init(epics::pvData::PVStructurePtr const &pvRequest)
|
||||
{
|
||||
PVStructurePtr pvMasterStructure = pvMaster;
|
||||
size_t len = pvRequest->getPVFields().size();
|
||||
bool entireMaster = false;
|
||||
if(len==string::npos) entireMaster = true;
|
||||
if(len==0) entireMaster = true;
|
||||
PVStructurePtr pvOptions;
|
||||
if(len==1 && pvRequest->getSubField("_options")) {
|
||||
pvOptions = pvRequest->getStructureField("_options");
|
||||
}
|
||||
if(entireMaster) {
|
||||
structure = pvMasterStructure->getStructure();
|
||||
CopyMasterNodePtr masterNode(new CopyMasterNode());
|
||||
headNode = masterNode;
|
||||
masterNode->options = pvOptions;
|
||||
masterNode->isStructure = false;
|
||||
masterNode->structureOffset = 0;
|
||||
masterNode->masterPVField = pvMasterStructure;
|
||||
masterNode->nfields = pvMasterStructure->getNumberFields();
|
||||
return true;
|
||||
}
|
||||
structure = createStructure(pvMasterStructure,pvRequest);
|
||||
if(!structure) return false;
|
||||
cacheInitStructure = createPVStructure();
|
||||
headNode = createStructureNodes(
|
||||
pvMaster,
|
||||
pvRequest,
|
||||
cacheInitStructure);
|
||||
return true;
|
||||
}
|
||||
|
||||
string PVCopy::dump(
|
||||
string const &value,
|
||||
CopyNodePtr const &node,
|
||||
int indentLevel)
|
||||
{
|
||||
throw std::logic_error(string("Not Implemented"));
|
||||
}
|
||||
|
||||
|
||||
StructureConstPtr PVCopy::createStructure(
|
||||
PVStructurePtr const &pvMaster,
|
||||
PVStructurePtr const &pvFromRequest)
|
||||
{
|
||||
if(pvFromRequest->getStructure()->getNumberFields()==0) {
|
||||
return pvMaster->getStructure();
|
||||
}
|
||||
PVFieldPtrArray const &pvFromRequestFields = pvFromRequest->getPVFields();
|
||||
StringArray const &fromRequestFieldNames = pvFromRequest->getStructure()->getFieldNames();
|
||||
size_t length = pvFromRequestFields.size();
|
||||
if(length==0) return NULLStructure;
|
||||
FieldConstPtrArray fields; fields.reserve(length);
|
||||
StringArray fieldNames; fields.reserve(length);
|
||||
for(size_t i=0; i<length; ++i) {
|
||||
string const &fieldName = fromRequestFieldNames[i];
|
||||
PVFieldPtr pvMasterField = pvMaster->getSubField(fieldName);
|
||||
if(!pvMasterField) continue;
|
||||
FieldConstPtr field = pvMasterField->getField();
|
||||
if(field->getType()==epics::pvData::structure) {
|
||||
PVStructurePtr pvRequestStructure = static_pointer_cast<PVStructure>(
|
||||
pvFromRequestFields[i]);
|
||||
if(pvRequestStructure->getNumberFields()>0) {
|
||||
StringArray const &names = pvRequestStructure->getStructure()->
|
||||
getFieldNames();
|
||||
size_t num = names.size();
|
||||
if(num>0 && names[0].compare("_options")==0) --num;
|
||||
if(num>0) {
|
||||
if(pvMasterField->getField()->getType()!=epics::pvData::structure) continue;
|
||||
fieldNames.push_back(fieldName);
|
||||
fields.push_back(createStructure(
|
||||
static_pointer_cast<PVStructure>(pvMasterField),
|
||||
pvRequestStructure));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
fieldNames.push_back(fieldName);
|
||||
fields.push_back(field);
|
||||
}
|
||||
size_t numsubfields = fields.size();
|
||||
if(numsubfields==0) return NULLStructure;
|
||||
return getFieldCreate()->createStructure(fieldNames, fields);
|
||||
}
|
||||
|
||||
CopyNodePtr PVCopy::createStructureNodes(
|
||||
PVStructurePtr const &pvMasterStructure,
|
||||
PVStructurePtr const &pvFromRequest,
|
||||
PVStructurePtr const &pvFromCopy)
|
||||
{
|
||||
PVFieldPtrArray const & copyPVFields = pvFromCopy->getPVFields();
|
||||
PVStructurePtr pvOptions;
|
||||
PVFieldPtr pvField = pvFromRequest->getSubField("_options");
|
||||
if(pvField) pvOptions = static_pointer_cast<PVStructure>(pvField);
|
||||
size_t number = copyPVFields.size();
|
||||
CopyNodePtrArrayPtr nodes(new CopyNodePtrArray());
|
||||
nodes->reserve(number);
|
||||
for(size_t i=0; i<number; i++) {
|
||||
PVFieldPtr copyPVField = copyPVFields[i];
|
||||
string fieldName = copyPVField->getFieldName();
|
||||
|
||||
PVStructurePtr requestPVStructure = static_pointer_cast<PVStructure>(
|
||||
pvFromRequest->getSubField(fieldName));
|
||||
PVStructurePtr pvSubFieldOptions;
|
||||
PVFieldPtr pvField = requestPVStructure->getSubField("_options");
|
||||
if(pvField) pvSubFieldOptions = static_pointer_cast<PVStructure>(pvField);
|
||||
PVFieldPtr pvMasterField;
|
||||
PVFieldPtrArray const & pvMasterFields = pvMasterStructure->getPVFields();
|
||||
for(size_t j=0; i<pvMasterFields.size(); j++ ) {
|
||||
if(pvMasterFields[j]->getFieldName().compare(fieldName)==0) {
|
||||
pvMasterField = pvMasterFields[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
size_t numberRequest = requestPVStructure->getPVFields().size();
|
||||
if(pvSubFieldOptions) numberRequest--;
|
||||
if(numberRequest>0) {
|
||||
nodes->push_back(createStructureNodes(
|
||||
static_pointer_cast<PVStructure>(pvMasterField),
|
||||
requestPVStructure,
|
||||
static_pointer_cast<PVStructure>(copyPVField)));
|
||||
continue;
|
||||
}
|
||||
CopyMasterNodePtr masterNode(new CopyMasterNode());
|
||||
masterNode->options = pvSubFieldOptions;
|
||||
masterNode->isStructure = false;
|
||||
masterNode->masterPVField = pvMasterField;
|
||||
masterNode->nfields = copyPVField->getNumberFields();
|
||||
masterNode->structureOffset = copyPVField->getFieldOffset();
|
||||
nodes->push_back(masterNode);
|
||||
}
|
||||
CopyStructureNodePtr structureNode(new CopyStructureNode());
|
||||
structureNode->isStructure = true;
|
||||
structureNode->nodes = nodes;
|
||||
structureNode->structureOffset = pvFromCopy->getFieldOffset();
|
||||
structureNode->nfields = pvFromCopy->getNumberFields();
|
||||
structureNode->options = pvOptions;
|
||||
return structureNode;
|
||||
}
|
||||
|
||||
void PVCopy::updateStructureNodeSetBitSet(
|
||||
PVStructurePtr const &pvCopy,
|
||||
CopyStructureNodePtr const &structureNode,
|
||||
epics::pvData::BitSetPtr const &bitSet)
|
||||
{
|
||||
for(size_t i=0; i<structureNode->nodes->size(); i++) {
|
||||
CopyNodePtr node = (*structureNode->nodes)[i];
|
||||
PVFieldPtr pvField = pvCopy->getSubField(node->structureOffset);
|
||||
if(node->isStructure) {
|
||||
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
|
||||
CopyStructureNodePtr yyy =
|
||||
static_pointer_cast<CopyStructureNode>(node);
|
||||
updateStructureNodeSetBitSet(xxx,yyy,bitSet);
|
||||
} else {
|
||||
CopyMasterNodePtr masterNode =
|
||||
static_pointer_cast<CopyMasterNode>(node);
|
||||
updateSubFieldSetBitSet(pvField,masterNode->masterPVField,bitSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PVCopy::updateSubFieldSetBitSet(
|
||||
PVFieldPtr const &pvCopy,
|
||||
PVFieldPtr const &pvMaster,
|
||||
BitSetPtr const &bitSet)
|
||||
{
|
||||
FieldConstPtr field = pvCopy->getField();
|
||||
Type type = field->getType();
|
||||
if(type!=epics::pvData::structure) {
|
||||
ConvertPtr convert = getConvert();
|
||||
bool isEqual = convert->equals(pvCopy,pvMaster);
|
||||
if(isEqual) {
|
||||
if(type==structureArray) {
|
||||
// always act as though a change occurred.
|
||||
// Note that array elements are shared.
|
||||
bitSet->set(pvCopy->getFieldOffset());
|
||||
}
|
||||
}
|
||||
if(isEqual) return;
|
||||
convert->copy(pvMaster, pvCopy);
|
||||
bitSet->set(pvCopy->getFieldOffset());
|
||||
return;
|
||||
}
|
||||
PVStructurePtr pvCopyStructure = static_pointer_cast<PVStructure>(pvCopy);
|
||||
PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields();
|
||||
PVStructurePtr pvMasterStructure =
|
||||
static_pointer_cast<PVStructure>(pvMaster);
|
||||
PVFieldPtrArray const & pvMasterFields =
|
||||
pvMasterStructure->getPVFields();
|
||||
size_t length = pvCopyFields.size();
|
||||
for(size_t i=0; i<length; i++) {
|
||||
updateSubFieldSetBitSet(pvCopyFields[i],pvMasterFields[i],bitSet);
|
||||
}
|
||||
}
|
||||
|
||||
void PVCopy::updateStructureNodeFromBitSet(
|
||||
PVStructurePtr const &pvCopy,
|
||||
CopyStructureNodePtr const &structureNode,
|
||||
BitSetPtr const &bitSet,
|
||||
bool toCopy,
|
||||
bool doAll)
|
||||
{
|
||||
size_t offset = structureNode->structureOffset;
|
||||
if(!doAll) {
|
||||
size_t nextSet = bitSet->nextSetBit(offset);
|
||||
if(nextSet==string::npos) return;
|
||||
}
|
||||
if(offset>=pvCopy->getNextFieldOffset()) return;
|
||||
if(!doAll) doAll = bitSet->get(offset);
|
||||
CopyNodePtrArrayPtr nodes = structureNode->nodes;
|
||||
for(size_t i=0; i<nodes->size(); i++) {
|
||||
CopyNodePtr node = (*nodes)[i];
|
||||
PVFieldPtr pvField = pvCopy->getSubField(node->structureOffset);
|
||||
if(node->isStructure) {
|
||||
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
|
||||
CopyStructureNodePtr subStructureNode =
|
||||
static_pointer_cast<CopyStructureNode>(node);
|
||||
updateStructureNodeFromBitSet(
|
||||
xxx,subStructureNode,bitSet,toCopy,doAll);
|
||||
} else {
|
||||
CopyMasterNodePtr masterNode =
|
||||
static_pointer_cast<CopyMasterNode>(node);
|
||||
updateSubFieldFromBitSet(
|
||||
pvField,masterNode->masterPVField,bitSet,toCopy,doAll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PVCopy::updateSubFieldFromBitSet(
|
||||
PVFieldPtr const &pvCopy,
|
||||
PVFieldPtr const &pvMasterField,
|
||||
BitSetPtr const &bitSet,
|
||||
bool toCopy,
|
||||
bool doAll)
|
||||
{
|
||||
if(!doAll) {
|
||||
doAll = bitSet->get(pvCopy->getFieldOffset());
|
||||
}
|
||||
if(!doAll) {
|
||||
size_t offset = pvCopy->getFieldOffset();
|
||||
size_t nextSet = bitSet->nextSetBit(offset);
|
||||
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);
|
||||
PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields();
|
||||
if(pvMasterField->getField()->getType() !=epics::pvData::structure)
|
||||
{
|
||||
throw std::logic_error(string("Logic error"));
|
||||
}
|
||||
PVStructurePtr pvMasterStructure =
|
||||
static_pointer_cast<PVStructure>(pvMasterField);
|
||||
PVFieldPtrArray const & pvMasterFields =
|
||||
pvMasterStructure->getPVFields();
|
||||
for(size_t i=0; i<pvCopyFields.size(); i++) {
|
||||
updateSubFieldFromBitSet(
|
||||
pvCopyFields[i],
|
||||
pvMasterFields[i],
|
||||
bitSet,toCopy,doAll);
|
||||
}
|
||||
} else {
|
||||
if(toCopy) {
|
||||
convert->copy(pvMasterField, pvCopy);
|
||||
} else {
|
||||
convert->copy(pvCopy, pvMasterField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CopyMasterNodePtr PVCopy::getCopyOffset(
|
||||
CopyStructureNodePtr const &structureNode,
|
||||
PVFieldPtr const &masterPVField)
|
||||
{
|
||||
size_t offset = masterPVField->getFieldOffset();
|
||||
CopyNodePtrArrayPtr nodes = structureNode->nodes;
|
||||
for(size_t i=0; i< nodes->size(); i++) {
|
||||
CopyNodePtr node = (*nodes)[i];
|
||||
if(!node->isStructure) {
|
||||
CopyMasterNodePtr masterNode =
|
||||
static_pointer_cast<CopyMasterNode>(node);
|
||||
size_t off = masterNode->masterPVField->getFieldOffset();
|
||||
size_t nextOffset = masterNode->masterPVField->getNextFieldOffset();
|
||||
if(offset>= off && offset<nextOffset) return masterNode;
|
||||
} else {
|
||||
CopyStructureNodePtr subNode =
|
||||
static_pointer_cast<CopyStructureNode>(node);
|
||||
CopyMasterNodePtr masterNode =
|
||||
getCopyOffset(subNode,masterPVField);
|
||||
if(masterNode) return masterNode;
|
||||
}
|
||||
}
|
||||
return NULLCopyMasterNode;
|
||||
}
|
||||
|
||||
CopyMasterNodePtr PVCopy::getMasterNode(
|
||||
CopyStructureNodePtr const &structureNode,
|
||||
std::size_t structureOffset)
|
||||
{
|
||||
CopyNodePtrArrayPtr nodes = structureNode->nodes;
|
||||
for(size_t i=0; i< nodes->size(); i++) {
|
||||
CopyNodePtr node = (*nodes)[i];
|
||||
if(structureOffset>=(node->structureOffset + node->nfields)) continue;
|
||||
if(!node->isStructure) {
|
||||
CopyMasterNodePtr masterNode =
|
||||
static_pointer_cast<CopyMasterNode>(node);
|
||||
return masterNode;
|
||||
}
|
||||
CopyStructureNodePtr subNode =
|
||||
static_pointer_cast<CopyStructureNode>(node);
|
||||
return getMasterNode(subNode,structureOffset);
|
||||
}
|
||||
return NULLCopyMasterNode;
|
||||
}
|
||||
|
||||
}}
|
||||
230
src/copy/pvCopy.h
Normal file
230
src/copy/pvCopy.h
Normal file
@@ -0,0 +1,230 @@
|
||||
/* pvCopy.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author Marty Kraimer
|
||||
* @date 2013.04
|
||||
*/
|
||||
#ifndef PVCOPY_H
|
||||
#define PVCOPY_H
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/bitSet.h>
|
||||
|
||||
namespace epics { namespace pvData{
|
||||
|
||||
class PVCopyTraverseMasterCallback;
|
||||
typedef std::tr1::shared_ptr<PVCopyTraverseMasterCallback> PVCopyTraverseMasterCallbackPtr;
|
||||
|
||||
/**
|
||||
* Callback for traversing master structure
|
||||
* Must be implemented by code that creates pvCopy.
|
||||
*/
|
||||
class epicsShareClass PVCopyTraverseMasterCallback
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVCopyTraverseMasterCallback);
|
||||
virtual ~PVCopyTraverseMasterCallback() {}
|
||||
/**
|
||||
* Called once for each field in master.
|
||||
* @param pvField The field in master.
|
||||
*/
|
||||
virtual void nextMasterPVField(epics::pvData::PVFieldPtr const &pvField) = 0;
|
||||
};
|
||||
|
||||
|
||||
class PVCopy;
|
||||
typedef std::tr1::shared_ptr<PVCopy> PVCopyPtr;
|
||||
|
||||
struct CopyNode;
|
||||
typedef std::tr1::shared_ptr<CopyNode> CopyNodePtr;
|
||||
struct CopyMasterNode;
|
||||
typedef std::tr1::shared_ptr<CopyMasterNode> CopyMasterNodePtr;
|
||||
struct CopyStructureNode;
|
||||
typedef std::tr1::shared_ptr<CopyStructureNode> CopyStructureNodePtr;
|
||||
|
||||
|
||||
/**
|
||||
* Class that manages one or more PVStructures that holds an arbitrary subset of the fields
|
||||
* in another PVStructure called master.
|
||||
*/
|
||||
class epicsShareClass PVCopy :
|
||||
public std::tr1::enable_shared_from_this<PVCopy>
|
||||
{
|
||||
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 pvRequest Selects the set of subfields desired and options for each field.
|
||||
* @param structureName The name for the top level of any PVStructure created.
|
||||
*/
|
||||
static PVCopyPtr create(
|
||||
PVStructurePtr const &pvMaster,
|
||||
PVStructurePtr const &pvRequest,
|
||||
std::string const & structureName);
|
||||
virtual ~PVCopy(){}
|
||||
virtual void destroy();
|
||||
/**
|
||||
* Get the top level structure of master
|
||||
* @returns The master top level structure.
|
||||
* This should not be modified.
|
||||
*/
|
||||
PVStructurePtr getPVMaster();
|
||||
/**
|
||||
* Traverse all the fields in master.
|
||||
* @param callback This is called for each field on master.
|
||||
*/
|
||||
void traverseMaster(PVCopyTraverseMasterCallbackPtr const & callback)
|
||||
{
|
||||
traverseMaster(headNode,callback);
|
||||
}
|
||||
/**
|
||||
* Get the introspection interface for a PVStructure for e copy.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
PVStructurePtr createPVStructure();
|
||||
/**
|
||||
* Given a field in pvMaster. return the offset in copy for the same field.
|
||||
* A value of std::string::npos means that the copy does not have this field.
|
||||
* @param masterPVField The field in master.
|
||||
*/
|
||||
std::size_t getCopyOffset(PVFieldPtr const &masterPVField);
|
||||
/**
|
||||
* Given a field in pvMaster. return the offset in copy for the same field.
|
||||
* A value of std::string::npos means that the copy does not have this field.
|
||||
* @param masterPVStructure A structure in master that has masterPVField.
|
||||
* @param masterPVField The field in master.
|
||||
*/
|
||||
std::size_t getCopyOffset(
|
||||
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.
|
||||
*/
|
||||
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 bitSet A bitSet for copyPVStructure.
|
||||
*/
|
||||
void initCopy(
|
||||
PVStructurePtr const ©PVStructure,
|
||||
BitSetPtr const &bitSet);
|
||||
/**
|
||||
* 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 bitSet A bitSet for copyPVStructure.
|
||||
*/
|
||||
void updateCopySetBitSet(
|
||||
PVStructurePtr const ©PVStructure,
|
||||
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.
|
||||
* @param bitSet A bitSet for copyPVStructure.
|
||||
*/
|
||||
void updateCopyFromBitSet(
|
||||
PVStructurePtr const ©PVStructure,
|
||||
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.
|
||||
* @param bitSet A bitSet for copyPVStructure.
|
||||
*/
|
||||
void updateMaster(
|
||||
PVStructurePtr const ©PVStructure,
|
||||
BitSetPtr const &bitSet);
|
||||
/**
|
||||
* Get the options for the field at the specified offset.
|
||||
* @param offset 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
|
||||
* name is the subField name and value is the subField value.
|
||||
*/
|
||||
PVStructurePtr getOptions(std::size_t fieldOffset);
|
||||
/**
|
||||
* For debugging.
|
||||
*/
|
||||
std::string dump();
|
||||
private:
|
||||
void dump(
|
||||
std::string *builder,
|
||||
CopyNodePtr const &node,
|
||||
int indentLevel);
|
||||
PVCopyPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
void traverseMaster(CopyNodePtr const &node, PVCopyTraverseMasterCallbackPtr const & callback);
|
||||
|
||||
PVStructurePtr pvMaster;
|
||||
StructureConstPtr structure;
|
||||
CopyNodePtr headNode;
|
||||
PVStructurePtr cacheInitStructure;
|
||||
PVCopy(PVStructurePtr const &pvMaster);
|
||||
friend class PVCopyMonitor;
|
||||
bool init(PVStructurePtr const &pvRequest);
|
||||
std::string dump(
|
||||
std::string const &value,
|
||||
CopyNodePtr const &node,
|
||||
int indentLevel);
|
||||
StructureConstPtr createStructure(
|
||||
PVStructurePtr const &pvMaster,
|
||||
PVStructurePtr const &pvFromRequest);
|
||||
CopyNodePtr createStructureNodes(
|
||||
PVStructurePtr const &pvMasterStructure,
|
||||
PVStructurePtr const &pvFromRequest,
|
||||
PVStructurePtr const &pvFromField);
|
||||
void updateStructureNodeSetBitSet(
|
||||
PVStructurePtr const &pvCopy,
|
||||
CopyStructureNodePtr const &structureNode,
|
||||
BitSetPtr const &bitSet);
|
||||
void updateSubFieldSetBitSet(
|
||||
PVFieldPtr const &pvCopy,
|
||||
PVFieldPtr const &pvMaster,
|
||||
BitSetPtr const &bitSet);
|
||||
void updateStructureNodeFromBitSet(
|
||||
PVStructurePtr const &pvCopy,
|
||||
CopyStructureNodePtr const &structureNode,
|
||||
BitSetPtr const &bitSet,
|
||||
bool toCopy,
|
||||
bool doAll);
|
||||
void updateSubFieldFromBitSet(
|
||||
PVFieldPtr const &pvCopy,
|
||||
PVFieldPtr const &pvMasterField,
|
||||
BitSetPtr const &bitSet,
|
||||
bool toCopy,
|
||||
bool doAll);
|
||||
CopyMasterNodePtr getCopyOffset(
|
||||
CopyStructureNodePtr const &structureNode,
|
||||
PVFieldPtr const &masterPVField);
|
||||
CopyMasterNodePtr getMasterNode(
|
||||
CopyStructureNodePtr const &structureNode,
|
||||
std::size_t structureOffset);
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* PVCOPY_H */
|
||||
@@ -7,13 +7,15 @@
|
||||
* @author mes
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/convert.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/convert.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
// Introspection object comparision
|
||||
@@ -132,6 +134,13 @@ bool operator==(const UnionArray& a, const UnionArray& b)
|
||||
return *(a.getUnion().get())==*(b.getUnion().get());
|
||||
}
|
||||
|
||||
bool operator==(const BoundedString& a, const BoundedString& b)
|
||||
{
|
||||
if(&a==&b)
|
||||
return true;
|
||||
return a.getMaximumLength()==b.getMaximumLength();
|
||||
}
|
||||
|
||||
// PVXXX object comparison
|
||||
|
||||
namespace {
|
||||
@@ -202,7 +211,7 @@ bool compareField(const PVScalarArray* left, const PVScalarArray* right)
|
||||
OP(pvLong, int64);
|
||||
OP(pvFloat, float);
|
||||
OP(pvDouble, double);
|
||||
OP(pvString, String);
|
||||
OP(pvString, string);
|
||||
#undef OP
|
||||
}
|
||||
throw std::logic_error("PVScalarArray with invalid element type!");
|
||||
@@ -242,7 +251,13 @@ bool compareField(const PVStructureArray* left, const PVStructureArray* right)
|
||||
lit!=lend;
|
||||
++lit, ++rit)
|
||||
{
|
||||
if(**lit != **rit)
|
||||
// element can be null
|
||||
if (!(*lit) || !(*rit))
|
||||
{
|
||||
if (*lit || *rit)
|
||||
return false;
|
||||
}
|
||||
else if (**lit != **rit)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -295,7 +310,13 @@ bool compareField(const PVUnionArray* left, const PVUnionArray* right)
|
||||
lit!=lend;
|
||||
++lit, ++rit)
|
||||
{
|
||||
if(**lit != **rit)
|
||||
// element can be null
|
||||
if (!(*lit) || !(*rit))
|
||||
{
|
||||
if (*lit || *rit)
|
||||
return false;
|
||||
}
|
||||
else if (**lit != **rit)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -18,41 +18,43 @@
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/printer.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::size_t;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
|
||||
static std::vector<String> split(String commaSeparatedList) {
|
||||
String::size_type numValues = 1;
|
||||
String::size_type index=0;
|
||||
static std::vector<string> split(string commaSeparatedList) {
|
||||
string::size_type numValues = 1;
|
||||
string::size_type index=0;
|
||||
while(true) {
|
||||
String::size_type pos = commaSeparatedList.find(',',index);
|
||||
if(pos==String::npos) break;
|
||||
string::size_type pos = commaSeparatedList.find(',',index);
|
||||
if(pos==string::npos) break;
|
||||
numValues++;
|
||||
index = pos +1;
|
||||
}
|
||||
std::vector<String> valueList(numValues,"");
|
||||
std::vector<string> valueList(numValues,"");
|
||||
index=0;
|
||||
for(size_t i=0; i<numValues; i++) {
|
||||
size_t pos = commaSeparatedList.find(',',index);
|
||||
String value = commaSeparatedList.substr(index,pos);
|
||||
string value = commaSeparatedList.substr(index,pos);
|
||||
valueList[i] = value;
|
||||
index = pos +1;
|
||||
}
|
||||
return valueList;
|
||||
}
|
||||
|
||||
void Convert::getString(StringBuilder buf,PVField const *pvField,int /*indentLevel*/)
|
||||
void Convert::getString(string *buf,PVField const *pvField,int /*indentLevel*/)
|
||||
{
|
||||
// TODO indextLevel ignored
|
||||
std::ostringstream strm;
|
||||
PrinterPlain p;
|
||||
p.setStream(strm);
|
||||
p.print(*pvField);
|
||||
pvField->dumpValue(strm);
|
||||
strm << std::endl;
|
||||
// PrinterPlain p;
|
||||
// p.setStream(strm);
|
||||
// p.print(*pvField);
|
||||
strm.str().swap(*buf);
|
||||
}
|
||||
|
||||
@@ -87,9 +89,9 @@ size_t Convert::fromString(PVStructurePtr const &pvStructure, StringArray const
|
||||
}
|
||||
else {
|
||||
// union, structureArray, unionArray not supported
|
||||
String message("Convert::fromString unsupported fieldType ");
|
||||
TypeFunc::toString(&message,type);
|
||||
throw std::logic_error(message);
|
||||
std::ostringstream oss;
|
||||
oss << "Convert::fromString unsupported fieldType " << type;
|
||||
throw std::logic_error(oss.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,13 +99,13 @@ size_t Convert::fromString(PVStructurePtr const &pvStructure, StringArray const
|
||||
return processed;
|
||||
}
|
||||
|
||||
size_t Convert::fromString(PVScalarArrayPtr const &pv, String from)
|
||||
size_t Convert::fromString(PVScalarArrayPtr const &pv, string from)
|
||||
{
|
||||
if(from[0]=='[' && from[from.length()]==']') {
|
||||
size_t offset = from.rfind(']');
|
||||
from = from.substr(1, offset);
|
||||
}
|
||||
std::vector<String> valueList(split(from));
|
||||
std::vector<string> valueList(split(from));
|
||||
size_t length = valueList.size();
|
||||
size_t num = fromStringArray(pv,0,length,valueList,0);
|
||||
if(num<length) length = num;
|
||||
@@ -128,7 +130,7 @@ size_t Convert::fromStringArray(PVScalarArrayPtr const &pv,
|
||||
data.begin());
|
||||
|
||||
PVStringArray::const_svector temp(freeze(data));
|
||||
pv->putFrom<String>(temp);
|
||||
pv->putFrom<string>(temp);
|
||||
return length;
|
||||
|
||||
} else {
|
||||
@@ -142,7 +144,7 @@ size_t Convert::toStringArray(PVScalarArrayPtr const & pv,
|
||||
StringArray &to, size_t toOffset)
|
||||
{
|
||||
PVStringArray::const_svector data;
|
||||
pv->getAs<String>(data);
|
||||
pv->getAs<string>(data);
|
||||
data.slice(offset, length);
|
||||
if(toOffset+data.size() > to.size())
|
||||
to.resize(toOffset+data.size());
|
||||
@@ -191,7 +193,7 @@ bool Convert::isCopyCompatible(FieldConstPtr const &from, FieldConstPtr const &t
|
||||
return isCopyUnionArrayCompatible(xxx,yyy);
|
||||
}
|
||||
}
|
||||
String message("Convert::isCopyCompatible should never get here");
|
||||
string message("Convert::isCopyCompatible should never get here");
|
||||
throw std::logic_error(message);
|
||||
}
|
||||
|
||||
@@ -258,7 +260,7 @@ void Convert::copyScalar(PVScalarPtr const & from, PVScalarPtr const & to)
|
||||
{
|
||||
if(to->isImmutable()) {
|
||||
if(from==to) return;
|
||||
String message("Convert.copyScalar destination is immutable");
|
||||
string message("Convert.copyScalar destination is immutable");
|
||||
throw std::invalid_argument(message);
|
||||
}
|
||||
to->assign(*from.get());
|
||||
@@ -348,13 +350,13 @@ void Convert::copyStructure(PVStructurePtr const & from, PVStructurePtr const &
|
||||
PVFieldPtrArray const & toDatas = to->getPVFields();
|
||||
if(from->getStructure()->getNumberFields()
|
||||
!= to->getStructure()->getNumberFields()) {
|
||||
String message("Convert.copyStructure Illegal copyStructure");
|
||||
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();
|
||||
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();
|
||||
@@ -382,7 +384,7 @@ void Convert::copyStructure(PVStructurePtr const & from, PVStructurePtr const &
|
||||
Type fromType = fromData->getField()->getType();
|
||||
Type toType = toData->getField()->getType();
|
||||
if(fromType!=toType) {
|
||||
String message("Convert.copyStructure Illegal copyStructure");
|
||||
string message("Convert.copyStructure Illegal copyStructure");
|
||||
throw std::invalid_argument(message);
|
||||
}
|
||||
if(toData->isImmutable()) {
|
||||
@@ -460,17 +462,14 @@ void Convert::copyUnion(PVUnionPtr const & from, PVUnionPtr const & to)
|
||||
PVFieldPtr fromValue = from->get();
|
||||
if (from->getUnion()->isVariant())
|
||||
{
|
||||
if (fromValue.get() == 0)
|
||||
to->set(PVFieldPtr());
|
||||
else
|
||||
to->set(getPVDataCreate()->createPVField(fromValue)); // clone value // TODO cache getPVDataCreate()
|
||||
to->set(from->get());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fromValue.get() == 0)
|
||||
to->select(PVUnion::UNDEFINED_INDEX);
|
||||
else
|
||||
copy(fromValue, to->select(from->getSelectedIndex()));
|
||||
to->set(from->getSelectedIndex(),from->get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,10 +511,10 @@ void Convert::copyUnionArray(
|
||||
to->replace(from->view());
|
||||
}
|
||||
|
||||
void Convert::newLine(StringBuilder buffer, int indentLevel)
|
||||
void Convert::newLine(string *buffer, int indentLevel)
|
||||
{
|
||||
*buffer += "\n";
|
||||
*buffer += String(indentLevel*4, ' ');
|
||||
*buffer += string(indentLevel*4, ' ');
|
||||
}
|
||||
|
||||
ConvertPtr Convert::getConvert()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,6 @@ SRC_DIRS += $(PVDATA_SRC)/factory
|
||||
INC += factory.h
|
||||
LIBSRCS += TypeFunc.cpp
|
||||
LIBSRCS += FieldCreateFactory.cpp
|
||||
LIBSRCS += PVAuxInfoImpl.cpp
|
||||
LIBSRCS += PVField.cpp
|
||||
LIBSRCS += PVScalar.cpp
|
||||
LIBSRCS += PVArray.cpp
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*PVAuxInfo.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/lock.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
|
||||
PVAuxInfo::PVAuxInfo(PVField * pvField)
|
||||
: pvField(pvField),
|
||||
pvInfos(std::map<String,std::tr1::shared_ptr<PVScalar> > ())
|
||||
{
|
||||
}
|
||||
|
||||
PVAuxInfo::~PVAuxInfo()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PVField * PVAuxInfo::getPVField() {
|
||||
return pvField;
|
||||
}
|
||||
|
||||
|
||||
PVScalarPtr PVAuxInfo::createInfo(String const & key,ScalarType scalarType)
|
||||
{
|
||||
PVInfoIter iter = pvInfos.find(key);
|
||||
if(iter!=pvInfos.end()) {
|
||||
String message = key.c_str();
|
||||
message += " already exists ";
|
||||
pvField->message(message,errorMessage);
|
||||
return nullPVScalar;
|
||||
}
|
||||
PVScalarPtr pvScalar = getPVDataCreate()->createPVScalar(scalarType);
|
||||
pvInfos.insert(PVInfoPair(key,pvScalar));
|
||||
return pvScalar;
|
||||
}
|
||||
|
||||
PVScalarPtr PVAuxInfo::getInfo(String const & key)
|
||||
{
|
||||
PVInfoIter iter;
|
||||
iter = pvInfos.find(key);
|
||||
if(iter==pvInfos.end()) return nullPVScalar;
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
PVAuxInfo::PVInfoMap & PVAuxInfo::getInfoMap()
|
||||
{
|
||||
return pvInfos;
|
||||
}
|
||||
|
||||
|
||||
void PVAuxInfo::toString(StringBuilder buf)
|
||||
{
|
||||
PVAuxInfo::toString(buf,0);
|
||||
}
|
||||
|
||||
void PVAuxInfo::toString(StringBuilder buf,int indentLevel)
|
||||
{
|
||||
if(pvInfos.size()<=0) return;
|
||||
ConvertPtr convert = getConvert();
|
||||
convert->newLine(buf,indentLevel);
|
||||
*buf += "auxInfo";
|
||||
for(PVInfoIter iter = pvInfos.begin(); iter!= pvInfos.end(); ++iter) {
|
||||
convert->newLine(buf,indentLevel+1);
|
||||
PVFieldPtr value = iter->second;
|
||||
value->toString(buf,indentLevel + 1);
|
||||
}
|
||||
}
|
||||
}}
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::size_t;
|
||||
using std::string;
|
||||
using std::min;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
@@ -43,7 +44,7 @@ template<> const ScalarType PVUInt::typeCode = pvUInt;
|
||||
template<> const ScalarType PVULong::typeCode = pvULong;
|
||||
template<> const ScalarType PVFloat::typeCode = pvFloat;
|
||||
template<> const ScalarType PVDouble::typeCode = pvDouble;
|
||||
template<> const ScalarType PVScalarValue<String>::typeCode = pvString;
|
||||
template<> const ScalarType PVScalarValue<string>::typeCode = pvString;
|
||||
|
||||
template<> const ScalarType PVBooleanArray::typeCode = pvBoolean;
|
||||
template<> const ScalarType PVByteArray::typeCode = pvByte;
|
||||
@@ -83,7 +84,7 @@ template<typename T>
|
||||
BasePVScalar<T>::BasePVScalar(ScalarConstPtr const & scalar)
|
||||
: PVScalarValue<T>(scalar),value(0)
|
||||
{}
|
||||
//Note: '0' is a suitable default for all POD types (not String)
|
||||
//Note: '0' is a suitable default for all POD types (not string)
|
||||
|
||||
template<typename T>
|
||||
BasePVScalar<T>::~BasePVScalar() {}
|
||||
@@ -128,14 +129,14 @@ typedef BasePVScalar<double> BasePVDouble;
|
||||
// BasePVString is special case, since it implements SerializableArray
|
||||
class BasePVString : public PVString {
|
||||
public:
|
||||
typedef String value_type;
|
||||
typedef String* pointer;
|
||||
typedef const String* const_pointer;
|
||||
typedef string value_type;
|
||||
typedef string* pointer;
|
||||
typedef const string* const_pointer;
|
||||
|
||||
BasePVString(ScalarConstPtr const & scalar);
|
||||
virtual ~BasePVString();
|
||||
virtual String get() const ;
|
||||
virtual void put(String val);
|
||||
virtual string get() const ;
|
||||
virtual void put(string val);
|
||||
virtual void serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher) const;
|
||||
virtual void deserialize(ByteBuffer *pbuffer,
|
||||
@@ -143,19 +144,29 @@ public:
|
||||
virtual void serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher, size_t offset, size_t count) const;
|
||||
private:
|
||||
String value;
|
||||
string value;
|
||||
std::size_t maxLength;
|
||||
};
|
||||
|
||||
BasePVString::BasePVString(ScalarConstPtr const & scalar)
|
||||
: PVString(scalar),value()
|
||||
{}
|
||||
{
|
||||
BoundedStringConstPtr boundedString = std::tr1::dynamic_pointer_cast<const BoundedString>(scalar);
|
||||
if (boundedString.get())
|
||||
maxLength = boundedString->getMaximumLength();
|
||||
else
|
||||
maxLength = 0;
|
||||
}
|
||||
|
||||
BasePVString::~BasePVString() {}
|
||||
|
||||
String BasePVString::get() const { return value;}
|
||||
string BasePVString::get() const { return value;}
|
||||
|
||||
void BasePVString::put(String val)
|
||||
void BasePVString::put(string val)
|
||||
{
|
||||
if (maxLength > 0 && val.length() > maxLength)
|
||||
throw std::overflow_error("string too long");
|
||||
|
||||
value = val;
|
||||
postPut();
|
||||
}
|
||||
@@ -189,6 +200,19 @@ void BasePVString::serialize(ByteBuffer *pbuffer,
|
||||
SerializeHelper::serializeSubstring(value, offset, count, pbuffer, pflusher);
|
||||
}
|
||||
|
||||
void PVArray::checkLength(size_t len)
|
||||
{
|
||||
Array::ArraySizeType type = getArray()->getArraySizeType();
|
||||
if (type != Array::variable)
|
||||
{
|
||||
size_t size = getArray()->getMaximumCapacity();
|
||||
if (type == Array::fixed && len != size)
|
||||
throw std::invalid_argument("invalid length for a fixed size array");
|
||||
else if (type == Array::bounded && len > size)
|
||||
throw std::invalid_argument("new array capacity too large for a bounded size array");
|
||||
}
|
||||
}
|
||||
|
||||
/** Default storage for arrays
|
||||
*/
|
||||
template<typename T>
|
||||
@@ -230,7 +254,14 @@ DefaultPVArray<T>::DefaultPVArray(ScalarArrayConstPtr const & scalarArray)
|
||||
: PVValueArray<T>(scalarArray),
|
||||
value()
|
||||
|
||||
{ }
|
||||
{
|
||||
ArrayConstPtr array = this->getArray();
|
||||
if (array->getArraySizeType() == Array::fixed)
|
||||
{
|
||||
// this->setLength(array->getMaximumCapacity());
|
||||
this->setCapacityMutable(false);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
DefaultPVArray<T>::~DefaultPVArray()
|
||||
@@ -239,18 +270,25 @@ template<typename T>
|
||||
void DefaultPVArray<T>::setCapacity(size_t capacity)
|
||||
{
|
||||
if(this->isCapacityMutable()) {
|
||||
this->checkLength(capacity);
|
||||
value.reserve(capacity);
|
||||
}
|
||||
else
|
||||
THROW_EXCEPTION2(std::logic_error, "capacity immutable");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void DefaultPVArray<T>::setLength(size_t length)
|
||||
{
|
||||
if(this->isImmutable())
|
||||
THROW_EXCEPTION2(std::logic_error,"Immutable");
|
||||
if(length == value.size())
|
||||
THROW_EXCEPTION2(std::logic_error, "immutable");
|
||||
|
||||
if (length == value.size())
|
||||
return;
|
||||
else if(length < value.size())
|
||||
|
||||
this->checkLength(length);
|
||||
|
||||
if (length < value.size())
|
||||
value.slice(0, length);
|
||||
else
|
||||
value.resize(length);
|
||||
@@ -259,6 +297,8 @@ void DefaultPVArray<T>::setLength(size_t length)
|
||||
template<typename T>
|
||||
void DefaultPVArray<T>::replace(const const_svector& next)
|
||||
{
|
||||
this->checkLength(next.size());
|
||||
|
||||
value = next;
|
||||
this->postPut();
|
||||
}
|
||||
@@ -266,8 +306,10 @@ void DefaultPVArray<T>::replace(const const_svector& next)
|
||||
template<typename T>
|
||||
void DefaultPVArray<T>::swap(const_svector &other)
|
||||
{
|
||||
if(this->isImmutable())
|
||||
THROW_EXCEPTION2(std::logic_error,"Immutable");
|
||||
if (this->isImmutable())
|
||||
THROW_EXCEPTION2(std::logic_error, "immutable");
|
||||
|
||||
// no checkLength call here
|
||||
|
||||
value.swap(other);
|
||||
}
|
||||
@@ -282,7 +324,10 @@ void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
|
||||
template<typename T>
|
||||
void DefaultPVArray<T>::deserialize(ByteBuffer *pbuffer,
|
||||
DeserializableControl *pcontrol) {
|
||||
size_t size = SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
|
||||
size_t size = this->getArray()->getArraySizeType() == Array::fixed ?
|
||||
this->getArray()->getMaximumCapacity() :
|
||||
SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
|
||||
svector nextvalue(thaw(value));
|
||||
nextvalue.resize(size); // TODO: avoid copy of stuff we will then overwrite
|
||||
@@ -320,6 +365,7 @@ void DefaultPVArray<T>::deserialize(ByteBuffer *pbuffer,
|
||||
remaining -= n2read;
|
||||
}
|
||||
value = freeze(nextvalue);
|
||||
// TODO !!!
|
||||
// inform about the change?
|
||||
PVField::postPut();
|
||||
}
|
||||
@@ -333,7 +379,11 @@ void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
|
||||
temp.slice(offset, count);
|
||||
count = temp.size();
|
||||
|
||||
SerializeHelper::writeSize(temp.size(), pbuffer, pflusher);
|
||||
ArrayConstPtr array = this->getArray();
|
||||
if (array->getArraySizeType() != Array::fixed)
|
||||
SerializeHelper::writeSize(count, pbuffer, pflusher);
|
||||
else if (count != array->getMaximumCapacity())
|
||||
throw std::length_error("fixed array cannot be partially serialized");
|
||||
|
||||
const T* cur = temp.data();
|
||||
|
||||
@@ -362,12 +412,15 @@ void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
|
||||
}
|
||||
}
|
||||
|
||||
// specializations for String
|
||||
// specializations for string
|
||||
|
||||
template<>
|
||||
void DefaultPVArray<String>::deserialize(ByteBuffer *pbuffer,
|
||||
void DefaultPVArray<string>::deserialize(ByteBuffer *pbuffer,
|
||||
DeserializableControl *pcontrol) {
|
||||
size_t size = SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
|
||||
size_t size = this->getArray()->getArraySizeType() == Array::fixed ?
|
||||
this->getArray()->getMaximumCapacity() :
|
||||
SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
|
||||
svector nextvalue(thaw(value));
|
||||
|
||||
@@ -378,7 +431,7 @@ void DefaultPVArray<String>::deserialize(ByteBuffer *pbuffer,
|
||||
nextvalue.slice(0, size);
|
||||
|
||||
|
||||
String * pvalue = nextvalue.data();
|
||||
string * pvalue = nextvalue.data();
|
||||
for(size_t i = 0; i<size; i++) {
|
||||
pvalue[i] = SerializeHelper::deserializeString(pbuffer,
|
||||
pcontrol);
|
||||
@@ -389,15 +442,17 @@ void DefaultPVArray<String>::deserialize(ByteBuffer *pbuffer,
|
||||
}
|
||||
|
||||
template<>
|
||||
void DefaultPVArray<String>::serialize(ByteBuffer *pbuffer,
|
||||
void DefaultPVArray<string>::serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher, size_t offset, size_t count) const {
|
||||
|
||||
const_svector temp(value);
|
||||
temp.slice(offset, count);
|
||||
|
||||
SerializeHelper::writeSize(temp.size(), pbuffer, pflusher);
|
||||
// TODO if fixed count == getArray()->getMaximumCapacity()
|
||||
if (this->getArray()->getArraySizeType() != Array::fixed)
|
||||
SerializeHelper::writeSize(temp.size(), pbuffer, pflusher);
|
||||
|
||||
const String * pvalue = temp.data();
|
||||
const string * pvalue = temp.data();
|
||||
for(size_t i = 0; i<temp.size(); i++) {
|
||||
SerializeHelper::serializeString(pvalue[i], pbuffer, pflusher);
|
||||
}
|
||||
@@ -414,7 +469,7 @@ typedef DefaultPVArray<uint32> BasePVUIntArray;
|
||||
typedef DefaultPVArray<uint64> BasePVULongArray;
|
||||
typedef DefaultPVArray<float> BasePVFloatArray;
|
||||
typedef DefaultPVArray<double> BasePVDoubleArray;
|
||||
typedef DefaultPVArray<String> BasePVStringArray;
|
||||
typedef DefaultPVArray<string> BasePVStringArray;
|
||||
|
||||
// Factory
|
||||
|
||||
@@ -548,16 +603,6 @@ PVScalarPtr PVDataCreate::createPVScalar(PVScalarPtr const & scalarToClone)
|
||||
ScalarType scalarType = scalarToClone->getScalar()->getScalarType();
|
||||
PVScalarPtr pvScalar = createPVScalar(scalarType);
|
||||
getConvert()->copyScalar(scalarToClone, pvScalar);
|
||||
PVAuxInfoPtr from = scalarToClone->getPVAuxInfo();
|
||||
PVAuxInfoPtr to = pvScalar->getPVAuxInfo();
|
||||
PVAuxInfo::PVInfoMap & map = from->getInfoMap();
|
||||
for(PVAuxInfo::PVInfoIter iter = map.begin(); iter!= map.end(); ++iter) {
|
||||
String key = iter->first;
|
||||
PVScalarPtr pvFrom = iter->second;
|
||||
ScalarConstPtr scalar = pvFrom->getScalar();
|
||||
PVScalarPtr pvTo = to->createInfo(key,scalar->getScalarType());
|
||||
getConvert()->copyScalar(pvFrom,pvTo);
|
||||
}
|
||||
return pvScalar;
|
||||
}
|
||||
|
||||
@@ -607,16 +652,6 @@ PVScalarArrayPtr PVDataCreate::createPVScalarArray(
|
||||
PVScalarArrayPtr pvArray = createPVScalarArray(
|
||||
arrayToClone->getScalarArray()->getElementType());
|
||||
pvArray->assign(*arrayToClone.get());
|
||||
PVAuxInfoPtr from = arrayToClone->getPVAuxInfo();
|
||||
PVAuxInfoPtr to = pvArray->getPVAuxInfo();
|
||||
PVAuxInfo::PVInfoMap & map = from->getInfoMap();
|
||||
for(PVAuxInfo::PVInfoIter iter = map.begin(); iter!= map.end(); ++iter) {
|
||||
String key = iter->first;
|
||||
PVScalarPtr pvFrom = iter->second;
|
||||
ScalarConstPtr scalar = pvFrom->getScalar();
|
||||
PVScalarPtr pvTo = to->createInfo(key,scalar->getScalarType());
|
||||
getConvert()->copyScalar(pvFrom,pvTo);
|
||||
}
|
||||
return pvArray;
|
||||
}
|
||||
|
||||
@@ -668,7 +703,7 @@ PVStructurePtr PVDataCreate::createPVStructure(
|
||||
PVStructurePtr PVDataCreate::createPVStructure(PVStructurePtr const & structToClone)
|
||||
{
|
||||
FieldConstPtrArray field;
|
||||
if(structToClone==0) {
|
||||
if(!structToClone) {
|
||||
// is this correct?!
|
||||
FieldConstPtrArray fields(0);
|
||||
StringArray fieldNames(0);
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
|
||||
using std::tr1::const_pointer_cast;
|
||||
using std::size_t;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
|
||||
PVField::PVField(FieldConstPtr field)
|
||||
: notImplemented("not implemented"),
|
||||
parent(NULL),field(field),
|
||||
@@ -35,49 +35,6 @@ PVField::PVField(FieldConstPtr field)
|
||||
PVField::~PVField()
|
||||
{ }
|
||||
|
||||
void PVField::message(
|
||||
String message,
|
||||
MessageType messageType,
|
||||
String fullFieldName)
|
||||
{
|
||||
if(parent!=NULL) {
|
||||
if(fullFieldName.length()>0) {
|
||||
fullFieldName = fieldName + '.' + fullFieldName;
|
||||
} else {
|
||||
fullFieldName = fieldName;
|
||||
}
|
||||
parent->message(message,messageType,fullFieldName);
|
||||
return;
|
||||
}
|
||||
message = fullFieldName + " " + message;
|
||||
if(requester) {
|
||||
requester->message(message,messageType);
|
||||
} else {
|
||||
printf("%s %s %s\n",
|
||||
getMessageTypeName(messageType).c_str(),
|
||||
fieldName.c_str(),
|
||||
message.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void PVField::message(String message,MessageType messageType)
|
||||
{
|
||||
PVField::message(message,messageType,"");
|
||||
}
|
||||
|
||||
void PVField::setRequester(RequesterPtr const &req)
|
||||
{
|
||||
if(parent!=NULL) {
|
||||
throw std::logic_error(
|
||||
"PVField::setRequester only legal for top level structure");
|
||||
}
|
||||
if(requester.get()!=NULL) {
|
||||
if(requester.get()==req.get()) return;
|
||||
throw std::logic_error(
|
||||
"PVField::setRequester requester is already present");
|
||||
}
|
||||
requester = req;
|
||||
}
|
||||
|
||||
size_t PVField::getFieldOffset() const
|
||||
{
|
||||
@@ -97,12 +54,6 @@ size_t PVField::getNumberFields() const
|
||||
return (nextFieldOffset - fieldOffset);
|
||||
}
|
||||
|
||||
PVAuxInfoPtr & PVField::getPVAuxInfo(){
|
||||
if(pvAuxInfo.get()==NULL) {
|
||||
pvAuxInfo = PVAuxInfoPtr(new PVAuxInfo(this));
|
||||
}
|
||||
return pvAuxInfo;
|
||||
}
|
||||
|
||||
bool PVField::isImmutable() const {return immutable;}
|
||||
|
||||
@@ -112,46 +63,6 @@ const FieldConstPtr & PVField::getField() const {return field;}
|
||||
|
||||
PVStructure *PVField::getParent() const {return parent;}
|
||||
|
||||
void PVField::replacePVField(const PVFieldPtr & newPVField)
|
||||
{
|
||||
if(parent==NULL) {
|
||||
throw std::logic_error("no parent");
|
||||
}
|
||||
PVFieldPtrArray pvFields = parent->getPVFields();
|
||||
StructureConstPtr structure = parent->getStructure();
|
||||
StringArray fieldNames = structure->getFieldNames();
|
||||
for(size_t i=0; i<fieldNames.size(); i++) {
|
||||
if(newPVField->getFieldName().compare(fieldNames[i]) == 0) {
|
||||
pvFields[i] = newPVField;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw std::logic_error("Did not find field in parent");
|
||||
}
|
||||
|
||||
void PVField::replaceField(FieldConstPtr &xxx)
|
||||
{
|
||||
field = xxx;
|
||||
}
|
||||
|
||||
void PVField::renameField(String const & newName)
|
||||
{
|
||||
if(parent==NULL) {
|
||||
throw std::logic_error("no parent");
|
||||
}
|
||||
std::tr1::shared_ptr<Structure> parentStructure = const_pointer_cast<Structure>(
|
||||
parent->getStructure());
|
||||
PVFieldPtrArray pvFields = parent->getPVFields();
|
||||
for(size_t i=0; i<pvFields.size(); i++) {
|
||||
if(pvFields[i].get()==this) {
|
||||
parentStructure->renameField(i,newName);
|
||||
fieldName = newName;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw std::logic_error("Did not find field in parent");
|
||||
}
|
||||
|
||||
void PVField::postPut()
|
||||
{
|
||||
if(postHandler.get()!=NULL) postHandler->postPut();
|
||||
@@ -168,7 +79,7 @@ void PVField::setPostHandler(PostHandlerPtr const &handler)
|
||||
postHandler = handler;
|
||||
}
|
||||
|
||||
void PVField::setParentAndName(PVStructure * xxx,String const & name)
|
||||
void PVField::setParentAndName(PVStructure * xxx,string const & name)
|
||||
{
|
||||
parent = xxx;
|
||||
fieldName = name;
|
||||
@@ -179,68 +90,19 @@ bool PVField::equals(PVField &pv)
|
||||
return pv==*this;
|
||||
}
|
||||
|
||||
void PVField::toString(StringBuilder buf)
|
||||
{
|
||||
toString(buf,0);
|
||||
}
|
||||
|
||||
void PVField::toString(StringBuilder buf,int indentLevel)
|
||||
{
|
||||
Convert().getString(buf,this,indentLevel);
|
||||
if(pvAuxInfo.get()!=NULL) pvAuxInfo->toString(buf,indentLevel);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const PVField& f)
|
||||
{
|
||||
std::ostream& ro = f.dumpValue(o);
|
||||
// TODO I do not want to call getPVAuxInfo() since it lazily creates a new instance of it
|
||||
//if (f.pvAuxInfo.get()!=NULL) ro << *(f.pvAuxInfo.get());
|
||||
return ro;
|
||||
return f.dumpValue(o);
|
||||
};
|
||||
|
||||
namespace format
|
||||
string PVField::getFullName() const
|
||||
{
|
||||
std::ostream& operator<<(std::ostream& os, indent_level const& indent)
|
||||
{
|
||||
indent_value(os) = indent.level;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, indent const&)
|
||||
{
|
||||
long il = indent_value(os);
|
||||
std::size_t spaces = static_cast<std::size_t>(il) * 4;
|
||||
return os << std::string(spaces, ' ');
|
||||
}
|
||||
|
||||
array_at_internal operator<<(std::ostream& str, array_at const& manip)
|
||||
{
|
||||
return array_at_internal(manip.index, str);
|
||||
}
|
||||
};
|
||||
|
||||
String PVField::getFullName() const
|
||||
{
|
||||
size_t size=fieldName.size();
|
||||
|
||||
string ret(fieldName);
|
||||
for(PVField *fld=getParent(); fld; fld=fld->getParent())
|
||||
{
|
||||
size+=fld->fieldName.size()+1;
|
||||
if(fld->getFieldName().size()==0) break;
|
||||
ret = fld->getFieldName() + '.' + ret;
|
||||
}
|
||||
|
||||
String ret(size, '.');
|
||||
size_t pos=size - fieldName.size();
|
||||
|
||||
ret.replace(pos, String::npos, fieldName);
|
||||
|
||||
for(PVField *fld=getParent(); fld; fld=fld->getParent())
|
||||
{
|
||||
const String& nref = fld->fieldName;
|
||||
assert(pos >= nref.size()+1);
|
||||
pos -= nref.size()+1;
|
||||
ret.replace(pos, String::npos, nref);
|
||||
}
|
||||
assert(pos==0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace epics { namespace pvData {
|
||||
template<>
|
||||
std::ostream& PVScalarValue<int8>::dumpValue(std::ostream& o) const
|
||||
{
|
||||
return o << static_cast<int>(get());
|
||||
return o << static_cast<int>(get());
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -41,4 +41,10 @@ namespace epics { namespace pvData {
|
||||
{
|
||||
return o << static_cast<unsigned int>(get());
|
||||
}
|
||||
|
||||
template<>
|
||||
std::ostream& PVScalarValue<boolean>::dumpValue(std::ostream& o) const
|
||||
{
|
||||
return o << std::boolalpha << static_cast<bool>(get());
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::size_t;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
@@ -45,7 +46,7 @@ PVUnionArrayPtr PVStructure::nullPVUnionArray;
|
||||
PVScalarArrayPtr PVStructure::nullPVScalarArray;
|
||||
|
||||
static PVFieldPtr findSubField(
|
||||
String const &fieldName,
|
||||
string const &fieldName,
|
||||
const PVStructure *pvStructure);
|
||||
|
||||
PVStructure::PVStructure(StructureConstPtr const & structurePtr)
|
||||
@@ -60,7 +61,7 @@ PVStructure::PVStructure(StructureConstPtr const & structurePtr)
|
||||
pvFields.reserve(numberFields);
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
for(size_t i=0; i<numberFields; i++) {
|
||||
pvFields.push_back(pvDataCreate->createPVField(fields[i]));
|
||||
pvFields.push_back(pvDataCreate->createPVField(fields[i]));
|
||||
}
|
||||
for(size_t i=0; i<numberFields; i++) {
|
||||
pvFields[i]->setParentAndName(this,fieldNames[i]);
|
||||
@@ -109,7 +110,7 @@ const PVFieldPtrArray & PVStructure::getPVFields() const
|
||||
return pvFields;
|
||||
}
|
||||
|
||||
PVFieldPtr PVStructure::getSubField(String const &fieldName) const
|
||||
PVFieldPtr PVStructure::getSubField(string const &fieldName) const
|
||||
{
|
||||
return findSubField(fieldName,this);
|
||||
}
|
||||
@@ -134,183 +135,79 @@ PVFieldPtr PVStructure::getSubField(size_t fieldOffset) const
|
||||
throw std::logic_error("PVStructure.getSubField: Logic error");
|
||||
}
|
||||
|
||||
void PVStructure::fixParentStructure()
|
||||
{
|
||||
PVStructure *parent = getParent();
|
||||
if(parent==NULL) return;
|
||||
StructureConstPtr parentStructure = parent->structurePtr;
|
||||
String fieldName = getFieldName();
|
||||
size_t index = parentStructure->getFieldIndex(fieldName);
|
||||
StringArray const &fieldNames = parentStructure->getFieldNames();
|
||||
size_t num = fieldNames.size();
|
||||
FieldConstPtrArray fields(num);
|
||||
FieldConstPtrArray const & oldFields = parentStructure->getFields();
|
||||
for(size_t i=0; i< num; i++) {
|
||||
if(i==index) {
|
||||
fields[i] = structurePtr;
|
||||
} else {
|
||||
fields[i] = oldFields[i];
|
||||
}
|
||||
}
|
||||
FieldConstPtr field = getFieldCreate()->createStructure(
|
||||
parentStructure->getID(),fieldNames,fields);
|
||||
parent->replaceField(field);
|
||||
parent->fixParentStructure();
|
||||
}
|
||||
|
||||
void PVStructure::appendPVField(
|
||||
String const &fieldName,
|
||||
PVFieldPtr const & pvField)
|
||||
{
|
||||
size_t origLength = pvFields.size();
|
||||
size_t newLength = origLength+1;
|
||||
PVFieldPtrArray * xxx = const_cast<PVFieldPtrArray *>(&pvFields);
|
||||
xxx->push_back(pvField);
|
||||
FieldConstPtr field = getFieldCreate()->appendField(
|
||||
structurePtr,fieldName,pvField->getField());
|
||||
replaceField(field);
|
||||
structurePtr = static_pointer_cast<const Structure>(field);
|
||||
StringArray fieldNames = structurePtr->getFieldNames();
|
||||
for(size_t i=0; i<newLength; i++) {
|
||||
pvFields[i]->setParentAndName(this,fieldNames[i]);
|
||||
}
|
||||
fixParentStructure();
|
||||
}
|
||||
|
||||
void PVStructure::appendPVFields(
|
||||
StringArray const & fieldNames,
|
||||
PVFieldPtrArray const & pvFields)
|
||||
{
|
||||
size_t origLength = this->pvFields.size();
|
||||
size_t extra = fieldNames.size();
|
||||
if(extra==0) return;
|
||||
size_t newLength = origLength + extra;
|
||||
PVFieldPtrArray * xxx = const_cast<PVFieldPtrArray *>(&this->pvFields);
|
||||
xxx->reserve(newLength);
|
||||
for(size_t i=0; i<extra; i++) {
|
||||
xxx->push_back(pvFields[i]);
|
||||
}
|
||||
FieldConstPtrArray fields;
|
||||
fields.reserve(extra);
|
||||
for(size_t i=0; i<extra; i++) fields.push_back(pvFields[i]->getField());
|
||||
FieldConstPtr field = getFieldCreate()->appendFields(
|
||||
structurePtr,fieldNames,fields);
|
||||
replaceField(field);
|
||||
structurePtr = static_pointer_cast<const Structure>(field);
|
||||
StringArray names = structurePtr->getFieldNames();
|
||||
for(size_t i=0; i<newLength; i++) {
|
||||
(*xxx)[i]->setParentAndName(this,names[i]);
|
||||
}
|
||||
fixParentStructure();
|
||||
}
|
||||
|
||||
void PVStructure::removePVField(String const &fieldName)
|
||||
{
|
||||
PVFieldPtr pvField = getSubField(fieldName);
|
||||
if(pvField.get()==NULL) {
|
||||
return;
|
||||
}
|
||||
size_t origLength = pvFields.size();
|
||||
size_t newLength = origLength - 1;
|
||||
PVFieldPtrArray const & origPVFields = pvFields;
|
||||
FieldConstPtrArray origFields = structurePtr->getFields();
|
||||
PVFieldPtrArray newPVFields;
|
||||
newPVFields.reserve(newLength);
|
||||
StringArray newFieldNames;
|
||||
newFieldNames.reserve(newLength);
|
||||
FieldConstPtrArray fields;
|
||||
fields.reserve(newLength);
|
||||
for(size_t i=0; i<origLength; i++) {
|
||||
if(origPVFields[i]!=pvField) {
|
||||
newFieldNames.push_back(origPVFields[i]->getFieldName());
|
||||
newPVFields.push_back(origPVFields[i]);
|
||||
fields.push_back(origFields[i]);
|
||||
}
|
||||
}
|
||||
PVFieldPtrArray * xxx = const_cast<PVFieldPtrArray *>(&pvFields);
|
||||
xxx->swap(newPVFields);
|
||||
FieldConstPtr field = getFieldCreate()->createStructure(
|
||||
structurePtr->getID(),newFieldNames,fields);
|
||||
replaceField(field);
|
||||
structurePtr = static_pointer_cast<const Structure>(field);
|
||||
StringArray fieldNames = structurePtr->getFieldNames();
|
||||
for(size_t i=0; i<newLength; i++) {
|
||||
pvFields[i]->setParentAndName(this,fieldNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
PVBooleanPtr PVStructure::getBooleanField(String const &fieldName)
|
||||
PVBooleanPtr PVStructure::getBooleanField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVBoolean>(fieldName);
|
||||
}
|
||||
|
||||
PVBytePtr PVStructure::getByteField(String const &fieldName)
|
||||
PVBytePtr PVStructure::getByteField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVByte>(fieldName);
|
||||
}
|
||||
|
||||
PVShortPtr PVStructure::getShortField(String const &fieldName)
|
||||
PVShortPtr PVStructure::getShortField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVShort>(fieldName);
|
||||
}
|
||||
|
||||
PVIntPtr PVStructure::getIntField(String const &fieldName)
|
||||
PVIntPtr PVStructure::getIntField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVInt>(fieldName);
|
||||
}
|
||||
|
||||
PVLongPtr PVStructure::getLongField(String const &fieldName)
|
||||
PVLongPtr PVStructure::getLongField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVLong>(fieldName);
|
||||
}
|
||||
|
||||
PVUBytePtr PVStructure::getUByteField(String const &fieldName)
|
||||
PVUBytePtr PVStructure::getUByteField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVUByte>(fieldName);
|
||||
}
|
||||
|
||||
PVUShortPtr PVStructure::getUShortField(String const &fieldName)
|
||||
PVUShortPtr PVStructure::getUShortField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVUShort>(fieldName);
|
||||
}
|
||||
|
||||
PVUIntPtr PVStructure::getUIntField(String const &fieldName)
|
||||
PVUIntPtr PVStructure::getUIntField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVUInt>(fieldName);
|
||||
}
|
||||
|
||||
PVULongPtr PVStructure::getULongField(String const &fieldName)
|
||||
PVULongPtr PVStructure::getULongField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVULong>(fieldName);
|
||||
}
|
||||
|
||||
PVFloatPtr PVStructure::getFloatField(String const &fieldName)
|
||||
PVFloatPtr PVStructure::getFloatField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVFloat>(fieldName);
|
||||
}
|
||||
|
||||
PVDoublePtr PVStructure::getDoubleField(String const &fieldName)
|
||||
PVDoublePtr PVStructure::getDoubleField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVDouble>(fieldName);
|
||||
}
|
||||
|
||||
PVStringPtr PVStructure::getStringField(String const &fieldName)
|
||||
PVStringPtr PVStructure::getStringField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVString>(fieldName);
|
||||
}
|
||||
|
||||
PVStructurePtr PVStructure::getStructureField(String const &fieldName)
|
||||
PVStructurePtr PVStructure::getStructureField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVStructure>(fieldName);
|
||||
}
|
||||
|
||||
PVUnionPtr PVStructure::getUnionField(String const &fieldName)
|
||||
PVUnionPtr PVStructure::getUnionField(string const &fieldName)
|
||||
{
|
||||
return getSubField<PVUnion>(fieldName);
|
||||
}
|
||||
|
||||
PVScalarArrayPtr PVStructure::getScalarArrayField(
|
||||
String const &fieldName,ScalarType elementType)
|
||||
string const &fieldName,ScalarType elementType)
|
||||
{
|
||||
PVFieldPtr pvField = findSubField(fieldName,this);
|
||||
if(pvField.get()==NULL) {
|
||||
@@ -330,29 +227,17 @@ PVScalarArrayPtr PVStructure::getScalarArrayField(
|
||||
}
|
||||
|
||||
PVStructureArrayPtr PVStructure::getStructureArrayField(
|
||||
String const &fieldName)
|
||||
string const &fieldName)
|
||||
{
|
||||
return getSubField<PVStructureArray>(fieldName);
|
||||
}
|
||||
|
||||
PVUnionArrayPtr PVStructure::getUnionArrayField(
|
||||
String const &fieldName)
|
||||
string const &fieldName)
|
||||
{
|
||||
return getSubField<PVUnionArray>(fieldName);
|
||||
}
|
||||
|
||||
String PVStructure::getExtendsStructureName() const
|
||||
{
|
||||
return extendsStructureName;
|
||||
}
|
||||
|
||||
bool PVStructure::putExtendsStructureName(
|
||||
String const &xxx)
|
||||
{
|
||||
if(extendsStructureName.length()!=0) return false;
|
||||
extendsStructureName = xxx;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PVStructure::serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher) const {
|
||||
@@ -444,13 +329,13 @@ void PVStructure::deserialize(ByteBuffer *pbuffer,
|
||||
}
|
||||
|
||||
static PVFieldPtr findSubField(
|
||||
String const & fieldName,
|
||||
string const & fieldName,
|
||||
PVStructure const *pvStructure)
|
||||
{
|
||||
if( fieldName.length()<1) return PVFieldPtr();
|
||||
String::size_type index = fieldName.find('.');
|
||||
String name = fieldName;
|
||||
String restOfName = String();
|
||||
string::size_type index = fieldName.find('.');
|
||||
string name = fieldName;
|
||||
string restOfName = string();
|
||||
if(index>0) {
|
||||
name = fieldName.substr(0, index);
|
||||
if(fieldName.length()>index) {
|
||||
@@ -477,10 +362,6 @@ static PVFieldPtr findSubField(
|
||||
std::ostream& PVStructure::dumpValue(std::ostream& o) const
|
||||
{
|
||||
o << format::indent() << getStructure()->getID() << ' ' << getFieldName();
|
||||
String extendsName = getExtendsStructureName();
|
||||
if(extendsName.length()>0) {
|
||||
o << " extends " << extendsName;
|
||||
}
|
||||
o << std::endl;
|
||||
{
|
||||
format::indent_scope s(o);
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace epics { namespace pvData {
|
||||
|
||||
size_t PVStructureArray::append(size_t number)
|
||||
{
|
||||
checkLength(value.size()+number);
|
||||
|
||||
svector data(reuse());
|
||||
data.resize(data.size()+number);
|
||||
|
||||
@@ -44,9 +46,11 @@ size_t PVStructureArray::append(size_t number)
|
||||
|
||||
bool PVStructureArray::remove(size_t offset,size_t number)
|
||||
{
|
||||
if(number==0)
|
||||
if (number==0)
|
||||
return true;
|
||||
else if(offset+number>getLength())
|
||||
else if (offset+number>getLength())
|
||||
return false;
|
||||
else if (getArray()->getArraySizeType() == Array::fixed)
|
||||
return false;
|
||||
|
||||
svector vec(reuse());
|
||||
@@ -65,6 +69,9 @@ bool PVStructureArray::remove(size_t offset,size_t number)
|
||||
}
|
||||
|
||||
void PVStructureArray::compress() {
|
||||
if (getArray()->getArraySizeType() == Array::fixed)
|
||||
return;
|
||||
|
||||
svector vec(reuse()); // TODO: check for first NULL before realloc
|
||||
|
||||
size_t length = vec.size();
|
||||
@@ -99,7 +106,8 @@ void PVStructureArray::compress() {
|
||||
|
||||
void PVStructureArray::setCapacity(size_t capacity)
|
||||
{
|
||||
if(this->isCapacityMutable()) {
|
||||
if (this->isCapacityMutable()) {
|
||||
checkLength(capacity);
|
||||
const_svector value;
|
||||
swap(value);
|
||||
if(value.capacity()<capacity) {
|
||||
@@ -109,17 +117,23 @@ void PVStructureArray::setCapacity(size_t capacity)
|
||||
}
|
||||
swap(value);
|
||||
}
|
||||
else
|
||||
THROW_EXCEPTION2(std::logic_error, "capacity immutable");
|
||||
}
|
||||
|
||||
void PVStructureArray::setLength(size_t length)
|
||||
{
|
||||
if(this->isImmutable())
|
||||
THROW_EXCEPTION2(std::logic_error,"Immutable");
|
||||
THROW_EXCEPTION2(std::logic_error, "immutable");
|
||||
const_svector value;
|
||||
swap(value);
|
||||
if(length == value.size()) {
|
||||
// nothing
|
||||
} else if(length < value.size()) {
|
||||
|
||||
if (length == value.size())
|
||||
return;
|
||||
|
||||
checkLength(length);
|
||||
|
||||
if (length < value.size()) {
|
||||
value.slice(0, length);
|
||||
} else {
|
||||
svector mvalue(thaw(value));
|
||||
@@ -131,8 +145,10 @@ void PVStructureArray::setLength(size_t length)
|
||||
|
||||
void PVStructureArray::swap(const_svector &other)
|
||||
{
|
||||
if(this->isImmutable())
|
||||
THROW_EXCEPTION2(std::logic_error,"Immutable");
|
||||
if (this->isImmutable())
|
||||
THROW_EXCEPTION2(std::logic_error, "immutable");
|
||||
|
||||
// no checkLength call here
|
||||
|
||||
value.swap(other);
|
||||
}
|
||||
@@ -146,7 +162,10 @@ void PVStructureArray::deserialize(ByteBuffer *pbuffer,
|
||||
DeserializableControl *pcontrol) {
|
||||
svector data(reuse());
|
||||
|
||||
size_t size = SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
size_t size = this->getArray()->getArraySizeType() == Array::fixed ?
|
||||
this->getArray()->getMaximumCapacity() :
|
||||
SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
|
||||
data.resize(size);
|
||||
|
||||
StructureConstPtr structure = structureArray->getStructure();
|
||||
@@ -175,7 +194,11 @@ void PVStructureArray::serialize(ByteBuffer *pbuffer,
|
||||
const_svector temp(view());
|
||||
temp.slice(offset, count);
|
||||
|
||||
SerializeHelper::writeSize(temp.size(), pbuffer, pflusher);
|
||||
ArrayConstPtr array = this->getArray();
|
||||
if (array->getArraySizeType() != Array::fixed)
|
||||
SerializeHelper::writeSize(temp.size(), pbuffer, pflusher);
|
||||
else if (count != array->getMaximumCapacity())
|
||||
throw std::length_error("fixed array cannot be partially serialized");
|
||||
|
||||
for(size_t i = 0; i<count; i++) {
|
||||
if(pbuffer->getRemaining()<1)
|
||||
@@ -209,8 +232,13 @@ std::ostream& PVStructureArray::dumpValue(std::ostream& o) const
|
||||
std::ostream& PVStructureArray::dumpValue(std::ostream& o, std::size_t index) const
|
||||
{
|
||||
const_svector temp(view());
|
||||
if(index<temp.size())
|
||||
o << *temp[index];
|
||||
if (index<temp.size())
|
||||
{
|
||||
if (temp[index])
|
||||
o << *temp[index];
|
||||
else
|
||||
o << format::indent() << "(none)" << std::endl;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::size_t;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
@@ -58,11 +59,11 @@ int32 PVUnion::getSelectedIndex() const
|
||||
return selector;
|
||||
}
|
||||
|
||||
String PVUnion::getSelectedFieldName() const
|
||||
string PVUnion::getSelectedFieldName() const
|
||||
{
|
||||
// no name for undefined and for variant unions
|
||||
if (selector == UNDEFINED_INDEX)
|
||||
return String();
|
||||
return string();
|
||||
else
|
||||
return unionPtr->getFieldName(selector);
|
||||
}
|
||||
@@ -91,7 +92,7 @@ PVFieldPtr PVUnion::select(int32 index)
|
||||
return value;
|
||||
}
|
||||
|
||||
PVFieldPtr PVUnion::select(String const & fieldName)
|
||||
PVFieldPtr PVUnion::select(string const & fieldName)
|
||||
{
|
||||
int32 index = variant ? -1 : static_cast<int32>(unionPtr->getFieldIndex(fieldName));
|
||||
if (index == -1)
|
||||
@@ -126,9 +127,10 @@ void PVUnion::set(int32 index, PVFieldPtr const & value)
|
||||
|
||||
selector = index;
|
||||
this->value = value;
|
||||
postPut();
|
||||
}
|
||||
|
||||
void PVUnion::set(String const & fieldName, PVFieldPtr const & value)
|
||||
void PVUnion::set(string const & fieldName, PVFieldPtr const & value)
|
||||
{
|
||||
int32 index = variant ? -1 : static_cast<int32>(unionPtr->getFieldIndex(fieldName));
|
||||
if (index == -1)
|
||||
@@ -167,7 +169,9 @@ void PVUnion::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol)
|
||||
FieldConstPtr field = pcontrol->cachedDeserialize(pbuffer);
|
||||
if (field.get())
|
||||
{
|
||||
value = getPVDataCreate()->createPVField(field);
|
||||
// try to reuse existing field instance
|
||||
if (!value.get() || *value->getField() != *field)
|
||||
value = getPVDataCreate()->createPVField(field);
|
||||
value->deserialize(pbuffer, pcontrol);
|
||||
}
|
||||
else
|
||||
@@ -175,11 +179,17 @@ void PVUnion::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol)
|
||||
}
|
||||
else
|
||||
{
|
||||
int32 previousSelector = selector;
|
||||
selector = static_cast<int32>(SerializeHelper::readSize(pbuffer, pcontrol));
|
||||
if (selector != UNDEFINED_INDEX)
|
||||
{
|
||||
FieldConstPtr field = unionPtr->getField(selector);
|
||||
value = getPVDataCreate()->createPVField(field);
|
||||
if (selector != previousSelector)
|
||||
{
|
||||
FieldConstPtr field = unionPtr->getField(selector);
|
||||
// try to reuse existing field instance
|
||||
if (!value.get() || *value->getField() != *field)
|
||||
value = getPVDataCreate()->createPVField(field);
|
||||
}
|
||||
value->deserialize(pbuffer, pcontrol);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace epics { namespace pvData {
|
||||
|
||||
size_t PVUnionArray::append(size_t number)
|
||||
{
|
||||
checkLength(value.size()+number);
|
||||
|
||||
svector data(reuse());
|
||||
data.resize(data.size()+number);
|
||||
|
||||
@@ -44,9 +46,11 @@ size_t PVUnionArray::append(size_t number)
|
||||
|
||||
bool PVUnionArray::remove(size_t offset,size_t number)
|
||||
{
|
||||
if(number==0)
|
||||
if (number==0)
|
||||
return true;
|
||||
else if(offset+number>getLength())
|
||||
else if (offset+number>getLength())
|
||||
return false;
|
||||
else if (getArray()->getArraySizeType() == Array::fixed)
|
||||
return false;
|
||||
|
||||
svector vec(reuse());
|
||||
@@ -65,6 +69,9 @@ bool PVUnionArray::remove(size_t offset,size_t number)
|
||||
}
|
||||
|
||||
void PVUnionArray::compress() {
|
||||
if (getArray()->getArraySizeType() == Array::fixed)
|
||||
return;
|
||||
|
||||
svector vec(reuse()); // TODO: check for first NULL before realloc
|
||||
|
||||
size_t length = vec.size();
|
||||
@@ -100,6 +107,7 @@ void PVUnionArray::compress() {
|
||||
void PVUnionArray::setCapacity(size_t capacity)
|
||||
{
|
||||
if(this->isCapacityMutable()) {
|
||||
checkLength(capacity);
|
||||
const_svector value;
|
||||
swap(value);
|
||||
if(value.capacity()<capacity) {
|
||||
@@ -109,17 +117,22 @@ void PVUnionArray::setCapacity(size_t capacity)
|
||||
}
|
||||
swap(value);
|
||||
}
|
||||
else
|
||||
THROW_EXCEPTION2(std::logic_error, "capacity immutable");
|
||||
}
|
||||
|
||||
void PVUnionArray::setLength(size_t length)
|
||||
{
|
||||
if(this->isImmutable())
|
||||
THROW_EXCEPTION2(std::logic_error,"Immutable");
|
||||
THROW_EXCEPTION2(std::logic_error, "immutable");
|
||||
const_svector value;
|
||||
swap(value);
|
||||
if(length == value.size()) {
|
||||
// nothing
|
||||
} else if(length < value.size()) {
|
||||
if (length == value.size())
|
||||
return;
|
||||
|
||||
checkLength(length);
|
||||
|
||||
if (length < value.size()) {
|
||||
value.slice(0, length);
|
||||
} else {
|
||||
svector mvalue(thaw(value));
|
||||
@@ -134,6 +147,8 @@ void PVUnionArray::swap(const_svector &other)
|
||||
if(this->isImmutable())
|
||||
THROW_EXCEPTION2(std::logic_error,"Immutable");
|
||||
|
||||
// no checkLength call here
|
||||
|
||||
value.swap(other);
|
||||
}
|
||||
|
||||
@@ -146,7 +161,10 @@ void PVUnionArray::deserialize(ByteBuffer *pbuffer,
|
||||
DeserializableControl *pcontrol) {
|
||||
svector data(reuse());
|
||||
|
||||
size_t size = SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
size_t size = this->getArray()->getArraySizeType() == Array::fixed ?
|
||||
this->getArray()->getMaximumCapacity() :
|
||||
SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
|
||||
data.resize(size);
|
||||
|
||||
UnionConstPtr punion = unionArray->getUnion();
|
||||
@@ -175,7 +193,11 @@ void PVUnionArray::serialize(ByteBuffer *pbuffer,
|
||||
const_svector temp(view());
|
||||
temp.slice(offset, count);
|
||||
|
||||
SerializeHelper::writeSize(temp.size(), pbuffer, pflusher);
|
||||
ArrayConstPtr array = this->getArray();
|
||||
if (array->getArraySizeType() != Array::fixed)
|
||||
SerializeHelper::writeSize(temp.size(), pbuffer, pflusher);
|
||||
else if (count != array->getMaximumCapacity())
|
||||
throw std::length_error("fixed array cannot be partially serialized");
|
||||
|
||||
for(size_t i = 0; i<count; i++) {
|
||||
if(pbuffer->getRemaining()<1)
|
||||
@@ -209,8 +231,13 @@ std::ostream& PVUnionArray::dumpValue(std::ostream& o) const
|
||||
std::ostream& PVUnionArray::dumpValue(std::ostream& o, std::size_t index) const
|
||||
{
|
||||
const_svector temp(view());
|
||||
if(index<temp.size())
|
||||
o << *temp[index];
|
||||
if (index<temp.size())
|
||||
{
|
||||
if (temp[index])
|
||||
o << *temp[index];
|
||||
else
|
||||
o << format::indent() << "(none)" << std::endl;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <pv/standardField.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
@@ -49,7 +50,7 @@ void StandardField::init()
|
||||
|
||||
StandardField::~StandardField(){}
|
||||
|
||||
StructureConstPtr StandardField::createProperties(String id,FieldConstPtr field,String properties)
|
||||
StructureConstPtr StandardField::createProperties(string id,FieldConstPtr field,string properties)
|
||||
{
|
||||
bool gotAlarm = false;
|
||||
bool gotTimeStamp = false;
|
||||
@@ -57,11 +58,11 @@ StructureConstPtr StandardField::createProperties(String id,FieldConstPtr field,
|
||||
bool gotControl = false;
|
||||
bool gotValueAlarm = false;
|
||||
int numProp = 0;
|
||||
if(properties.find("alarm")!=String::npos) { gotAlarm = true; numProp++; }
|
||||
if(properties.find("timeStamp")!=String::npos) { gotTimeStamp = true; numProp++; }
|
||||
if(properties.find("display")!=String::npos) { gotDisplay = true; numProp++; }
|
||||
if(properties.find("control")!=String::npos) { gotControl = true; numProp++; }
|
||||
if(properties.find("valueAlarm")!=String::npos) { gotValueAlarm = true; numProp++; }
|
||||
if(properties.find("alarm")!=string::npos) { gotAlarm = true; numProp++; }
|
||||
if(properties.find("timeStamp")!=string::npos) { gotTimeStamp = true; numProp++; }
|
||||
if(properties.find("display")!=string::npos) { gotDisplay = true; numProp++; }
|
||||
if(properties.find("control")!=string::npos) { gotControl = true; numProp++; }
|
||||
if(properties.find("valueAlarm")!=string::npos) { gotValueAlarm = true; numProp++; }
|
||||
StructureConstPtr valueAlarm;
|
||||
Type type= field->getType();
|
||||
while(gotValueAlarm) {
|
||||
@@ -82,7 +83,7 @@ StructureConstPtr StandardField::createProperties(String id,FieldConstPtr field,
|
||||
case pvFloat: valueAlarm = floatAlarmField; break;
|
||||
case pvDouble: valueAlarm = doubleAlarmField; break;
|
||||
case pvString:
|
||||
throw std::logic_error(String("valueAlarm property not supported for pvString"));
|
||||
throw std::logic_error(string("valueAlarm property not supported for pvString"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -93,8 +94,8 @@ StructureConstPtr StandardField::createProperties(String id,FieldConstPtr field,
|
||||
FieldConstPtrArray fields = structurePtr->getFields();
|
||||
FieldConstPtr first = fields[0];
|
||||
FieldConstPtr second = fields[1];
|
||||
String nameFirst = names[0];
|
||||
String nameSecond = names[1];
|
||||
string nameFirst = names[0];
|
||||
string nameSecond = names[1];
|
||||
int compareFirst = nameFirst.compare("index");
|
||||
int compareSecond = nameSecond.compare("choices");
|
||||
if(compareFirst==0 && compareSecond==0) {
|
||||
@@ -112,7 +113,7 @@ StructureConstPtr StandardField::createProperties(String id,FieldConstPtr field,
|
||||
}
|
||||
}
|
||||
}
|
||||
throw std::logic_error(String("valueAlarm property for illegal type"));
|
||||
throw std::logic_error(string("valueAlarm property for illegal type"));
|
||||
}
|
||||
size_t numFields = numProp+1;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
@@ -161,7 +162,7 @@ void StandardField::createTimeStamp() {
|
||||
FieldConstPtrArray fields(num);
|
||||
StringArray names(num);
|
||||
names[0] = "secondsPastEpoch";
|
||||
names[1] = "nanoSeconds";
|
||||
names[1] = "nanoseconds";
|
||||
names[2] = "userTag";
|
||||
fields[0] = fieldCreate->createScalar(pvLong);
|
||||
fields[1] = fieldCreate->createScalar(pvInt);
|
||||
@@ -227,7 +228,7 @@ void StandardField::createByteAlarm() {
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
names[9] = "hysteresis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvByte);
|
||||
fields[2] = fieldCreate->createScalar(pvByte);
|
||||
@@ -254,7 +255,7 @@ void StandardField::createShortAlarm() {
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
names[9] = "hysteresis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvShort);
|
||||
fields[2] = fieldCreate->createScalar(pvShort);
|
||||
@@ -281,7 +282,7 @@ void StandardField::createIntAlarm() {
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
names[9] = "hysteresis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvInt);
|
||||
fields[2] = fieldCreate->createScalar(pvInt);
|
||||
@@ -308,7 +309,7 @@ void StandardField::createLongAlarm() {
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
names[9] = "hysteresis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvLong);
|
||||
fields[2] = fieldCreate->createScalar(pvLong);
|
||||
@@ -335,7 +336,7 @@ void StandardField::createUByteAlarm() {
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
names[9] = "hysteresis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvUByte);
|
||||
fields[2] = fieldCreate->createScalar(pvUByte);
|
||||
@@ -362,7 +363,7 @@ void StandardField::createUShortAlarm() {
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
names[9] = "hysteresis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvUShort);
|
||||
fields[2] = fieldCreate->createScalar(pvUShort);
|
||||
@@ -389,7 +390,7 @@ void StandardField::createUIntAlarm() {
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
names[9] = "hysteresis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvUInt);
|
||||
fields[2] = fieldCreate->createScalar(pvUInt);
|
||||
@@ -416,7 +417,7 @@ void StandardField::createULongAlarm() {
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
names[9] = "hysteresis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvULong);
|
||||
fields[2] = fieldCreate->createScalar(pvULong);
|
||||
@@ -443,7 +444,7 @@ void StandardField::createFloatAlarm() {
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
names[9] = "hysteresis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvFloat);
|
||||
fields[2] = fieldCreate->createScalar(pvFloat);
|
||||
@@ -470,7 +471,7 @@ void StandardField::createDoubleAlarm() {
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
names[9] = "hysteresis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvDouble);
|
||||
fields[2] = fieldCreate->createScalar(pvDouble);
|
||||
@@ -499,26 +500,48 @@ void StandardField::createEnumeratedAlarm() {
|
||||
|
||||
|
||||
StructureConstPtr StandardField::scalar(
|
||||
ScalarType type,String const &properties)
|
||||
ScalarType type,string const &properties)
|
||||
{
|
||||
ScalarConstPtr field = fieldCreate->createScalar(type); // scalar_t
|
||||
return createProperties("uri:ev4:nt/2012/pwd:NTScalar",field,properties);
|
||||
return createProperties("epics:nt/NTScalar:1.0",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::regUnion(
|
||||
UnionConstPtr const &field,
|
||||
string const & properties)
|
||||
{
|
||||
return createProperties("epics:nt/NTUnion:1.0",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::variantUnion(
|
||||
string const & properties)
|
||||
{
|
||||
UnionConstPtr field = fieldCreate->createVariantUnion();
|
||||
return createProperties("epics:nt/NTUnion:1.0",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::scalarArray(
|
||||
ScalarType elementType, String const &properties)
|
||||
ScalarType elementType, string const &properties)
|
||||
{
|
||||
ScalarArrayConstPtr field = fieldCreate->createScalarArray(elementType); // scalar_t[]
|
||||
return createProperties("uri:ev4:nt/2012/pwd:NTScalarArray",field,properties);
|
||||
return createProperties("epics:nt/NTScalarArray:1.0",field,properties);
|
||||
}
|
||||
|
||||
|
||||
StructureConstPtr StandardField::structureArray(
|
||||
StructureConstPtr const & structure,String const &properties)
|
||||
StructureConstPtr const & structure,string const &properties)
|
||||
{
|
||||
StructureArrayConstPtr field = fieldCreate->createStructureArray(
|
||||
structure);
|
||||
return createProperties("uri:ev4:nt/2012/pwd:NTAny",field,properties);
|
||||
return createProperties("epics:nt/NTStructureArray:1.0",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::unionArray(
|
||||
UnionConstPtr const & punion,string const &properties)
|
||||
{
|
||||
UnionArrayConstPtr field = fieldCreate->createUnionArray(
|
||||
punion);
|
||||
return createProperties("epics:nt/NTUnionArray:1.0",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::enumerated()
|
||||
@@ -534,10 +557,10 @@ StructureConstPtr StandardField::enumerated()
|
||||
// NOTE: if this method is used to get NTEnum wihtout properties the ID will be wrong!
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::enumerated(String const &properties)
|
||||
StructureConstPtr StandardField::enumerated(string const &properties)
|
||||
{
|
||||
StructureConstPtr field = enumerated(); // enum_t
|
||||
return createProperties("uri:ev4:nt/2012/pwd:NTEnum",field,properties);
|
||||
return createProperties("epics:nt/NTEnum:1.0",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::alarm()
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
StandardPVField::StandardPVField()
|
||||
@@ -30,7 +32,7 @@ StandardPVField::StandardPVField()
|
||||
StandardPVField::~StandardPVField(){}
|
||||
|
||||
PVStructurePtr StandardPVField::scalar(
|
||||
ScalarType type,String const & properties)
|
||||
ScalarType type,string const & properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->scalar(type,properties);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
|
||||
@@ -38,7 +40,7 @@ PVStructurePtr StandardPVField::scalar(
|
||||
}
|
||||
|
||||
PVStructurePtr StandardPVField::scalarArray(
|
||||
ScalarType elementType, String const & properties)
|
||||
ScalarType elementType, string const & properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->scalarArray(elementType,properties);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
|
||||
@@ -46,13 +48,21 @@ PVStructurePtr StandardPVField::scalarArray(
|
||||
}
|
||||
|
||||
PVStructurePtr StandardPVField::structureArray(
|
||||
StructureConstPtr const & structure,String const & properties)
|
||||
StructureConstPtr const & structure,string const & properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->structureArray(structure,properties);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVStructurePtr StandardPVField::unionArray(
|
||||
UnionConstPtr const & punion,string const & properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->unionArray(punion,properties);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVStructurePtr StandardPVField::enumerated(StringArray const &choices)
|
||||
{
|
||||
StructureConstPtr field = standardField->enumerated();
|
||||
@@ -66,7 +76,7 @@ PVStructurePtr StandardPVField::enumerated(StringArray const &choices)
|
||||
}
|
||||
|
||||
PVStructurePtr StandardPVField::enumerated(
|
||||
StringArray const &choices,String const & properties)
|
||||
StringArray const &choices,string const & properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->enumerated(properties);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "dbDefs.h" // for NELEMENTS
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
namespace TypeFunc {
|
||||
@@ -30,11 +32,13 @@ namespace TypeFunc {
|
||||
THROW_EXCEPTION2(std::invalid_argument, "logic error unknown Type");
|
||||
return names[t];
|
||||
}
|
||||
void toString(StringBuilder buf,const Type type) {
|
||||
*buf += name(type);
|
||||
}
|
||||
} // namespace TypeFunc
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const Type& type)
|
||||
{
|
||||
return o << TypeFunc::name(type);
|
||||
}
|
||||
|
||||
|
||||
namespace ScalarTypeFunc {
|
||||
bool isInteger(ScalarType type) {
|
||||
@@ -63,7 +67,7 @@ namespace ScalarTypeFunc {
|
||||
"ubyte", "ushort", "uint", "ulong",
|
||||
"float", "double", "string",
|
||||
};
|
||||
ScalarType getScalarType(const String& pvalue) {
|
||||
ScalarType getScalarType(const string& pvalue) {
|
||||
for(size_t i=0; i<NELEMENTS(names); i++)
|
||||
if(pvalue==names[i])
|
||||
return ScalarType(i);
|
||||
@@ -76,10 +80,6 @@ namespace ScalarTypeFunc {
|
||||
return names[t];
|
||||
}
|
||||
|
||||
void toString(StringBuilder buf,const ScalarType scalarType) {
|
||||
*buf += name(scalarType);
|
||||
}
|
||||
|
||||
size_t elementSize(ScalarType id)
|
||||
{
|
||||
switch(id) {
|
||||
@@ -95,7 +95,7 @@ namespace ScalarTypeFunc {
|
||||
OP(pvLong, int64);
|
||||
OP(pvFloat, float);
|
||||
OP(pvDouble, double);
|
||||
OP(pvString, String);
|
||||
OP(pvString, string);
|
||||
#undef OP
|
||||
default:
|
||||
THROW_EXCEPTION2(std::invalid_argument, "error unknown ScalarType");
|
||||
@@ -117,7 +117,7 @@ namespace ScalarTypeFunc {
|
||||
OP(pvLong, int64);
|
||||
OP(pvFloat, float);
|
||||
OP(pvDouble, double);
|
||||
OP(pvString, String);
|
||||
OP(pvString, string);
|
||||
#undef OP
|
||||
default:
|
||||
throw std::bad_alloc();
|
||||
@@ -126,4 +126,9 @@ namespace ScalarTypeFunc {
|
||||
|
||||
} // namespace ScalarTypeFunc
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const ScalarType& scalarType)
|
||||
{
|
||||
return o << ScalarTypeFunc::name(scalarType);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/printer.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace {
|
||||
|
||||
void indentN(std::ostream& strm, size_t N)
|
||||
@@ -22,6 +24,34 @@ void indentN(std::ostream& strm, size_t N)
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
namespace format
|
||||
{
|
||||
static int indent_index = std::ios_base::xalloc();
|
||||
|
||||
long& indent_value(std::ios_base& ios)
|
||||
{
|
||||
return ios.iword(indent_index);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, indent_level const& indent)
|
||||
{
|
||||
indent_value(os) = indent.level;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, indent const&)
|
||||
{
|
||||
long il = indent_value(os);
|
||||
std::size_t spaces = static_cast<std::size_t>(il) * 4;
|
||||
return os << string(spaces, ' ');
|
||||
}
|
||||
|
||||
array_at_internal operator<<(std::ostream& str, array_at const& manip)
|
||||
{
|
||||
return array_at_internal(manip.index, str);
|
||||
}
|
||||
};
|
||||
|
||||
PrinterBase::PrinterBase()
|
||||
:strm(NULL)
|
||||
{}
|
||||
@@ -199,9 +229,6 @@ void PrinterPlain::beginStructure(const PVStructure& pv)
|
||||
{
|
||||
indentN(S(), ilvl);
|
||||
S() << pv.getStructure()->getID() << " " << pv.getFieldName();
|
||||
String ename(pv.getExtendsStructureName());
|
||||
if(!ename.empty())
|
||||
S() << " extends " << ename;
|
||||
S() << std::endl;
|
||||
ilvl++;
|
||||
}
|
||||
@@ -242,14 +269,14 @@ void PrinterPlain::encodeScalar(const PVScalar& pv)
|
||||
indentN(S(), ilvl);
|
||||
S() << pv.getScalar()->getID() << " "
|
||||
<< pv.getFieldName() << " "
|
||||
<< pv.getAs<String>() << std::endl;
|
||||
<< pv.getAs<string>() << std::endl;
|
||||
}
|
||||
|
||||
void PrinterPlain::encodeArray(const PVScalarArray& pv)
|
||||
{
|
||||
indentN(S(), ilvl);
|
||||
shared_vector<const String> temp;
|
||||
pv.getAs<String>(temp);
|
||||
shared_vector<const string> temp;
|
||||
pv.getAs<string>(temp);
|
||||
|
||||
S() << pv.getScalarArray()->getID() << " "
|
||||
<< pv.getFieldName() << " [";
|
||||
|
||||
@@ -14,31 +14,36 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvSubArrayCopy.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
template<typename T>
|
||||
void copy(
|
||||
PVValueArray<T> & pvFrom,
|
||||
size_t fromOffset,
|
||||
size_t fromStride,
|
||||
PVValueArray<T> & pvTo,
|
||||
size_t toOffset,
|
||||
size_t len)
|
||||
size_t toStride,
|
||||
size_t count)
|
||||
{
|
||||
if(pvTo.isImmutable()) {
|
||||
throw std::logic_error("pvSubArrayCopy to is immutable");
|
||||
}
|
||||
if(pvTo.isImmutable()) throw std::invalid_argument("pvSubArrayCopy: pvTo is immutable");
|
||||
if(fromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1");
|
||||
size_t fromLength = pvFrom.getLength();
|
||||
if(fromOffset+len>fromLength) {
|
||||
throw std::length_error("pvSubArrayCopy from length error");
|
||||
}
|
||||
size_t maxcount = (fromLength -fromOffset + fromStride -1)/fromStride;
|
||||
if(count>maxcount) throw std::invalid_argument("pvSubArrayCopy pvFrom length error");
|
||||
size_t newLength = toOffset + count*toStride;
|
||||
size_t capacity = pvTo.getCapacity();
|
||||
if(toOffset+len>capacity) capacity = toOffset + len;
|
||||
if(newLength>capacity) capacity = newLength;
|
||||
shared_vector<T> temp(capacity);
|
||||
typename PVValueArray<T>::const_svector vecFrom = pvFrom.view();
|
||||
typename PVValueArray<T>::const_svector vecTo = pvTo.view();
|
||||
for(size_t i=0; i<toOffset; ++i) temp[i] = vecTo[i];
|
||||
for(size_t i=0; i<len; ++i) temp[i + toOffset] = vecFrom[i + fromOffset];
|
||||
for(size_t i=len + toOffset; i<capacity; ++i) temp[i] = vecTo[i];
|
||||
for(size_t i=0; i<pvTo.getLength(); ++i) temp[i] = vecTo[i];
|
||||
for(size_t i=pvTo.getLength(); i< capacity; ++i) temp[i] = T();
|
||||
for(size_t i=0; i<count; ++i) temp[i*toStride + toOffset] = vecFrom[i*fromStride+fromOffset];
|
||||
shared_vector<const T> temp2(freeze(temp));
|
||||
pvTo.replace(temp2);
|
||||
}
|
||||
@@ -46,9 +51,11 @@ void copy(
|
||||
void copy(
|
||||
PVScalarArray & from,
|
||||
size_t fromOffset,
|
||||
size_t fromStride,
|
||||
PVScalarArray & to,
|
||||
size_t toOffset,
|
||||
size_t len)
|
||||
size_t toStride,
|
||||
size_t count)
|
||||
{
|
||||
ScalarType scalarType = from.getScalarArray()->getElementType();
|
||||
ScalarType otherType = to.getScalarArray()->getElementType();
|
||||
@@ -59,145 +66,210 @@ void copy(
|
||||
{
|
||||
case pvBoolean:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<boolean> &>(from),fromOffset,
|
||||
copy(dynamic_cast<PVValueArray<boolean> &>(from),fromOffset,fromStride,
|
||||
dynamic_cast<PVValueArray<boolean>& >(to),
|
||||
toOffset,len);
|
||||
toOffset,toStride,count);
|
||||
}
|
||||
break;
|
||||
case pvByte:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<int8> &>(from),fromOffset,
|
||||
copy(dynamic_cast<PVValueArray<int8> &>(from),fromOffset,fromStride,
|
||||
dynamic_cast<PVValueArray<int8>& >(to),
|
||||
toOffset,len);
|
||||
toOffset,toStride,count);
|
||||
}
|
||||
break;
|
||||
case pvShort:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<int16> &>(from),fromOffset,
|
||||
copy(dynamic_cast<PVValueArray<int16> &>(from),fromOffset,fromStride,
|
||||
dynamic_cast<PVValueArray<int16>& >(to),
|
||||
toOffset,len);
|
||||
toOffset,toStride,count);
|
||||
}
|
||||
break;
|
||||
case pvInt:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<int32> &>(from),fromOffset,
|
||||
copy(dynamic_cast<PVValueArray<int32> &>(from),fromOffset,fromStride,
|
||||
dynamic_cast<PVValueArray<int32>& >(to),
|
||||
toOffset,len);
|
||||
toOffset,toStride,count);
|
||||
}
|
||||
break;
|
||||
case pvLong:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<int64> &>(from),fromOffset,
|
||||
copy(dynamic_cast<PVValueArray<int64> &>(from),fromOffset,fromStride,
|
||||
dynamic_cast<PVValueArray<int64>& >(to),
|
||||
toOffset,len);
|
||||
toOffset,toStride,count);
|
||||
}
|
||||
break;
|
||||
case pvUByte:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<uint8> &>(from),fromOffset,
|
||||
copy(dynamic_cast<PVValueArray<uint8> &>(from),fromOffset,fromStride,
|
||||
dynamic_cast<PVValueArray<uint8>& >(to),
|
||||
toOffset,len);
|
||||
toOffset,toStride,count);
|
||||
}
|
||||
break;
|
||||
case pvUShort:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<uint16> &>(from),fromOffset,
|
||||
copy(dynamic_cast<PVValueArray<uint16> &>(from),fromOffset,fromStride,
|
||||
dynamic_cast<PVValueArray<uint16>& >(to),
|
||||
toOffset,len);
|
||||
toOffset,toStride,count);
|
||||
}
|
||||
break;
|
||||
case pvUInt:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<uint32> &>(from),fromOffset,
|
||||
copy(dynamic_cast<PVValueArray<uint32> &>(from),fromOffset,fromStride,
|
||||
dynamic_cast<PVValueArray<uint32>& >(to),
|
||||
toOffset,len);
|
||||
toOffset,toStride,count);
|
||||
}
|
||||
break;
|
||||
case pvULong:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<uint64> &>(from),fromOffset,
|
||||
copy(dynamic_cast<PVValueArray<uint64> &>(from),fromOffset,fromStride,
|
||||
dynamic_cast<PVValueArray<uint64>& >(to),
|
||||
toOffset,len);
|
||||
toOffset,toStride,count);
|
||||
}
|
||||
break;
|
||||
case pvFloat:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<float> &>(from),fromOffset,
|
||||
copy(dynamic_cast<PVValueArray<float> &>(from),fromOffset,fromStride,
|
||||
dynamic_cast<PVValueArray<float>& >(to),
|
||||
toOffset,len);
|
||||
toOffset,toStride,count);
|
||||
}
|
||||
break;
|
||||
case pvDouble:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<double> &>(from),fromOffset,
|
||||
copy(dynamic_cast<PVValueArray<double> &>(from),fromOffset,fromStride,
|
||||
dynamic_cast<PVValueArray<double>& >(to),
|
||||
toOffset,len);
|
||||
toOffset,toStride,count);
|
||||
}
|
||||
break;
|
||||
case pvString:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<String> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<String>& >(to),
|
||||
toOffset,len);
|
||||
copy(dynamic_cast<PVValueArray<string> &>(from),fromOffset,fromStride,
|
||||
dynamic_cast<PVValueArray<string>& >(to),
|
||||
toOffset,toStride,count);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void copy(
|
||||
PVStructureArray & from,
|
||||
size_t fromOffset,
|
||||
PVStructureArray & to,
|
||||
PVStructureArray & pvFrom,
|
||||
size_t pvFromOffset,
|
||||
size_t pvFromStride,
|
||||
PVStructureArray & pvTo,
|
||||
size_t toOffset,
|
||||
size_t len)
|
||||
size_t toStride,
|
||||
size_t count)
|
||||
{
|
||||
if(to.isImmutable()) {
|
||||
throw std::logic_error("pvSubArrayCopy to is immutable");
|
||||
if(pvTo.isImmutable()) {
|
||||
throw std::logic_error("pvSubArrayCopy pvTo is immutable");
|
||||
}
|
||||
StructureArrayConstPtr fromStructure = from.getStructureArray();
|
||||
StructureArrayConstPtr toStructure = to.getStructureArray();
|
||||
if(fromStructure!=toStructure) {
|
||||
if(pvFromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1");
|
||||
StructureArrayConstPtr pvFromStructure = pvFrom.getStructureArray();
|
||||
StructureArrayConstPtr toStructure = pvTo.getStructureArray();
|
||||
if(pvFromStructure->getStructure()!=toStructure->getStructure()) {
|
||||
throw std::invalid_argument(
|
||||
"pvSubArrayCopy structureArray to and from have different structures");
|
||||
"pvSubArrayCopy structureArray pvTo and pvFrom have different structures");
|
||||
}
|
||||
size_t fromLength = from.getLength();
|
||||
if(fromOffset+len>fromLength) {
|
||||
throw std::length_error("pvSubArrayCopy from length error");
|
||||
}
|
||||
size_t capacity = to.getCapacity();
|
||||
if(toOffset+len>capacity) capacity = toOffset+len;
|
||||
size_t pvFromLength = pvFrom.getLength();
|
||||
size_t maxcount = (pvFromLength -pvFromOffset + pvFromStride -1)/pvFromStride;
|
||||
if(count>maxcount) throw std::invalid_argument("pvSubArrayCopy pvFrom length error");
|
||||
size_t newLength = toOffset + count*toStride;
|
||||
size_t capacity = pvTo.getCapacity();
|
||||
if(newLength>capacity) capacity = newLength;
|
||||
shared_vector<PVStructurePtr> temp(capacity);
|
||||
PVValueArray<PVStructurePtr>::const_svector vecFrom = from.view();
|
||||
PVValueArray<PVStructurePtr>::const_svector vecTo = to.view();
|
||||
for(size_t i=0; i<toOffset; ++i) temp[i] = vecTo[i];
|
||||
for(size_t i=0; i<len; ++i) temp[i + toOffset] = vecFrom[i + fromOffset];
|
||||
for(size_t i=len + toOffset; i<capacity; ++i) temp[i] = vecTo[i];
|
||||
PVValueArray<PVStructurePtr>::const_svector vecFrom = pvFrom.view();
|
||||
PVValueArray<PVStructurePtr>::const_svector vecTo = pvTo.view();
|
||||
for(size_t i=0; i<pvTo.getLength(); ++i) temp[i] = vecTo[i];
|
||||
for(size_t i=pvTo.getLength(); i< capacity; ++i)
|
||||
temp[i] = getPVDataCreate()->createPVStructure(toStructure->getStructure());
|
||||
for(size_t i=0; i<count; ++i) temp[i*toStride + toOffset] = vecFrom[i*pvFromStride+pvFromOffset];
|
||||
shared_vector<const PVStructurePtr> temp2(freeze(temp));
|
||||
to.replace(temp2);
|
||||
pvTo.replace(temp2);
|
||||
}
|
||||
|
||||
void copy(
|
||||
PVArray & from,
|
||||
size_t fromOffset,
|
||||
PVArray & to,
|
||||
PVUnionArray & pvFrom,
|
||||
size_t pvFromOffset,
|
||||
size_t pvFromStride,
|
||||
PVUnionArray & pvTo,
|
||||
size_t toOffset,
|
||||
size_t len)
|
||||
size_t toStride,
|
||||
size_t count)
|
||||
{
|
||||
Type type = from.getField()->getType();
|
||||
Type otherType = to.getField()->getType();
|
||||
if(type!=otherType) {
|
||||
throw std::invalid_argument("pvSubArrayCopy types do not match");
|
||||
if(pvTo.isImmutable()) {
|
||||
throw std::logic_error("pvSubArrayCopy pvTo is immutable");
|
||||
}
|
||||
if(type==scalarArray) {
|
||||
copy(dynamic_cast<PVScalarArray &>(from) ,fromOffset,
|
||||
dynamic_cast<PVScalarArray&>(to),
|
||||
toOffset,len);
|
||||
if(pvFromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1");
|
||||
UnionArrayConstPtr pvFromUnion = pvFrom.getUnionArray();
|
||||
UnionArrayConstPtr toUnion = pvTo.getUnionArray();
|
||||
if(pvFromUnion->getUnion()!=toUnion->getUnion()) {
|
||||
throw std::invalid_argument(
|
||||
"pvSubArrayCopy unionArray pvTo and pvFrom have different unions");
|
||||
}
|
||||
if(type==structureArray) {
|
||||
copy(dynamic_cast<PVStructureArray &>(from) ,fromOffset,
|
||||
dynamic_cast<PVStructureArray&>(to),
|
||||
toOffset,len);
|
||||
size_t pvFromLength = pvFrom.getLength();
|
||||
size_t maxcount = (pvFromLength -pvFromOffset + pvFromStride -1)/pvFromStride;
|
||||
if(count>maxcount) throw std::invalid_argument("pvSubArrayCopy pvFrom length error");
|
||||
size_t newLength = toOffset + count*toStride;
|
||||
size_t capacity = pvTo.getCapacity();
|
||||
if(newLength>capacity) capacity = newLength;
|
||||
shared_vector<PVUnionPtr> temp(capacity);
|
||||
PVValueArray<PVUnionPtr>::const_svector vecFrom = pvFrom.view();
|
||||
PVValueArray<PVUnionPtr>::const_svector vecTo = pvTo.view();
|
||||
for(size_t i=0; i<pvTo.getLength(); ++i) temp[i] = vecTo[i];
|
||||
for(size_t i=pvTo.getLength(); i< capacity; ++i)
|
||||
temp[i] = getPVDataCreate()->createPVUnion(toUnion->getUnion());
|
||||
for(size_t i=0; i<count; ++i) temp[i*toStride + toOffset] = vecFrom[i*pvFromStride+pvFromOffset];
|
||||
shared_vector<const PVUnionPtr> temp2(freeze(temp));
|
||||
pvTo.replace(temp2);
|
||||
}
|
||||
|
||||
void copy(
|
||||
PVArray & pvFrom,
|
||||
size_t pvFromOffset,
|
||||
size_t pvFromStride,
|
||||
PVArray & pvTo,
|
||||
size_t pvToOffset,
|
||||
size_t pvToStride,
|
||||
size_t count)
|
||||
{
|
||||
Type pvFromType = pvFrom.getField()->getType();
|
||||
Type pvToType = pvTo.getField()->getType();
|
||||
if(pvFromType!=pvToType) throw std::invalid_argument("pvSubArrayCopy: pvFrom and pvTo different types");
|
||||
if(pvFromType==scalarArray) {
|
||||
ScalarType pvFromScalarType= static_cast<ScalarType>(pvFromType);
|
||||
ScalarType pvToScalarType = static_cast<ScalarType>(pvToType);
|
||||
if(pvFromScalarType!=pvToScalarType){
|
||||
throw std::invalid_argument("pvSubArrayCopy: pvFrom and pvTo different types");
|
||||
}
|
||||
}
|
||||
if(pvTo.isImmutable()) throw std::invalid_argument("pvSubArrayCopy: pvTo is immutable");
|
||||
if(pvFromType==scalarArray) {
|
||||
copy(dynamic_cast<PVScalarArray &>(pvFrom) ,pvFromOffset,pvFromStride,
|
||||
dynamic_cast<PVScalarArray&>(pvTo),
|
||||
pvToOffset,pvToStride,count);
|
||||
}
|
||||
if(pvFromType==structureArray) {
|
||||
copy(dynamic_cast<PVStructureArray &>(pvFrom) ,pvFromOffset,pvFromStride,
|
||||
dynamic_cast<PVStructureArray&>(pvTo),
|
||||
pvToOffset,pvToStride,count);
|
||||
}
|
||||
if(pvFromType==unionArray) {
|
||||
copy(dynamic_cast<PVUnionArray &>(pvFrom) ,pvFromOffset,pvFromStride,
|
||||
dynamic_cast<PVUnionArray&>(pvTo),
|
||||
pvToOffset,pvToStride,count);
|
||||
}
|
||||
}
|
||||
|
||||
void copy(
|
||||
PVArray::shared_pointer const & pvFrom,
|
||||
size_t pvFromOffset,
|
||||
size_t pvFromStride,
|
||||
PVArray::shared_pointer & pvTo,
|
||||
size_t pvToOffset,
|
||||
size_t pvToStride,
|
||||
size_t count)
|
||||
{
|
||||
copy(*pvFrom,pvFromOffset,pvFromStride,*pvTo,pvToOffset,pvToStride,count);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -309,21 +309,6 @@ namespace epics { namespace pvData {
|
||||
return !(*this == set);
|
||||
}
|
||||
|
||||
void BitSet::toString(StringBuilder buffer, int /*indentLevel*/) const
|
||||
{
|
||||
*buffer += '{';
|
||||
int32 i = nextSetBit(0);
|
||||
char tmp[30];
|
||||
if (i != -1) {
|
||||
sprintf(tmp,"%d",(int)i); *buffer += tmp;
|
||||
for (i = nextSetBit(i+1); i >= 0; i = nextSetBit(i+1)) {
|
||||
int32 endOfRun = nextClearBit(i);
|
||||
do { *buffer += ", "; sprintf(tmp,"%d",(int)i); *buffer += tmp; } while (++i < endOfRun);
|
||||
}
|
||||
}
|
||||
*buffer += '}';
|
||||
}
|
||||
|
||||
void BitSet::serialize(ByteBuffer* buffer, SerializableControl* flusher) const {
|
||||
|
||||
uint32 n = wordsInUse;
|
||||
@@ -374,5 +359,20 @@ namespace epics { namespace pvData {
|
||||
words[i] |= (buffer->getByte() & 0xffL) << (8 * j);
|
||||
|
||||
}
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, const BitSet& b)
|
||||
{
|
||||
o << '{';
|
||||
int32 i = b.nextSetBit(0);
|
||||
if (i != -1) {
|
||||
o << i;
|
||||
for (i = b.nextSetBit(i+1); i >= 0; i = b.nextSetBit(i+1)) {
|
||||
int32 endOfRun = b.nextClearBit(i);
|
||||
do { o << ", " << i; } while (++i < endOfRun);
|
||||
}
|
||||
}
|
||||
o << '}';
|
||||
return o;
|
||||
}
|
||||
|
||||
}};
|
||||
|
||||
@@ -225,8 +225,6 @@ namespace epics { namespace pvData {
|
||||
|
||||
bool operator!=(const BitSet &set) const;
|
||||
|
||||
void toString(StringBuilder buffer, int indentLevel = 0) const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer,
|
||||
SerializableControl *flusher) const;
|
||||
virtual void deserialize(ByteBuffer *buffer,
|
||||
@@ -317,6 +315,8 @@ namespace epics { namespace pvData {
|
||||
static uint32 bitCount(uint64 i);
|
||||
|
||||
};
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, const BitSet& b);
|
||||
|
||||
}}
|
||||
#endif /* BITSET_H */
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/epicsException.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics{ namespace pvData {
|
||||
|
||||
@@ -32,7 +34,7 @@ ExceptionMixin::print(FILE *fp) const
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string
|
||||
string
|
||||
ExceptionMixin::show() const
|
||||
{
|
||||
std::ostringstream out;
|
||||
@@ -62,7 +64,7 @@ BaseException::what() const throw()
|
||||
try{
|
||||
if (base_msg.size()==0) {
|
||||
const char *base=std::logic_error::what();
|
||||
std::string out, stack;
|
||||
string out, stack;
|
||||
|
||||
const ExceptionMixin *info=dynamic_cast<const ExceptionMixin*>(this);
|
||||
if(info) {
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include <pv/lock.h>
|
||||
#include <pv/event.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
|
||||
@@ -43,27 +45,27 @@ Event::Event(bool full)
|
||||
|
||||
void Event::signal()
|
||||
{
|
||||
if(id==0) throw std::logic_error(String("event was deleted"));
|
||||
if(id==0) throw std::logic_error(string("event was deleted"));
|
||||
epicsEventSignal(id);
|
||||
}
|
||||
|
||||
bool Event::wait ()
|
||||
{
|
||||
if(id==0) throw std::logic_error(String("event was deleted"));
|
||||
if(id==0) throw std::logic_error(string("event was deleted"));
|
||||
epicsEventWaitStatus status = epicsEventWait(id);
|
||||
return status==epicsEventWaitOK ? true : false;
|
||||
}
|
||||
|
||||
bool Event::wait ( double timeOut )
|
||||
{
|
||||
if(id==0) throw std::logic_error(String("event was deleted"));
|
||||
if(id==0) throw std::logic_error(string("event was deleted"));
|
||||
epicsEventWaitStatus status = epicsEventWaitWithTimeout(id,timeOut);
|
||||
return status==epicsEventWaitOK ? true : false;
|
||||
}
|
||||
|
||||
bool Event::tryWait ()
|
||||
{
|
||||
if(id==0) throw std::logic_error(String("event was deleted"));
|
||||
if(id==0) throw std::logic_error(string("event was deleted"));
|
||||
epicsEventWaitStatus status = epicsEventTryWait(id);
|
||||
return status==epicsEventWaitOK ? true : false;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
bool tryWait (); /* false if empty */
|
||||
private:
|
||||
epicsEventId id;
|
||||
String alreadyOn;
|
||||
std::string alreadyOn;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/executor.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
// special instance to stop the executor thread
|
||||
@@ -31,7 +33,7 @@ static
|
||||
std::tr1::shared_ptr<Command> shutdown(new ExecutorShutdown());
|
||||
|
||||
|
||||
Executor::Executor(String threadName,ThreadPriority priority)
|
||||
Executor::Executor(string const & threadName,ThreadPriority priority)
|
||||
: thread(threadName,priority,this)
|
||||
{
|
||||
}
|
||||
@@ -52,14 +54,14 @@ void Executor::run()
|
||||
{
|
||||
Lock xx(mutex);
|
||||
while(true) {
|
||||
while(head.get()==NULL) {
|
||||
while(!head.get()) {
|
||||
xx.unlock();
|
||||
moreWork.wait();
|
||||
xx.lock();
|
||||
}
|
||||
CommandPtr command = head;
|
||||
head = command->next;
|
||||
if(command.get()==NULL) continue;
|
||||
if(!command.get()) continue;
|
||||
if(command.get()==shutdown.get()) break;
|
||||
xx.unlock();
|
||||
try {
|
||||
@@ -80,13 +82,13 @@ void Executor::execute(CommandPtr const & command)
|
||||
{
|
||||
Lock xx(mutex);
|
||||
command->next.reset();
|
||||
if(head.get()==NULL) {
|
||||
if(!head.get()) {
|
||||
head = command;
|
||||
moreWork.signal();
|
||||
return;
|
||||
}
|
||||
CommandPtr tail = head;
|
||||
while(tail->next!=NULL) tail = tail->next;
|
||||
while(tail->next) tail = tail->next;
|
||||
tail->next = command;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ private:
|
||||
class epicsShareClass Executor : public Runnable{
|
||||
public:
|
||||
POINTER_DEFINITIONS(Executor);
|
||||
Executor(String threadName,ThreadPriority priority);
|
||||
Executor(std::string const & threadName,ThreadPriority priority);
|
||||
~Executor();
|
||||
void execute(CommandPtr const &node);
|
||||
virtual void run();
|
||||
|
||||
@@ -12,13 +12,15 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/messageQueue.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
MessageNode::MessageNode()
|
||||
: messageType(infoMessage)
|
||||
{}
|
||||
|
||||
String MessageNode::getMessage() const
|
||||
string MessageNode::getMessage() const
|
||||
{
|
||||
return message;
|
||||
}
|
||||
@@ -59,7 +61,7 @@ void MessageQueue::release() {
|
||||
releaseUsed(lastGet);
|
||||
lastGet.reset();
|
||||
}
|
||||
bool MessageQueue::put(String message,MessageType messageType,bool replaceLast)
|
||||
bool MessageQueue::put(string message,MessageType messageType,bool replaceLast)
|
||||
{
|
||||
MessageNodePtr node = getFree();
|
||||
if(node.get()!= NULL) {
|
||||
|
||||
@@ -31,10 +31,10 @@ typedef std::tr1::shared_ptr<MessageQueue> MessageQueuePtr;
|
||||
class epicsShareClass MessageNode {
|
||||
public:
|
||||
MessageNode();
|
||||
String getMessage() const;
|
||||
std::string getMessage() const;
|
||||
MessageType getMessageType() const;
|
||||
private:
|
||||
String message;
|
||||
std::string message;
|
||||
MessageType messageType;
|
||||
friend class MessageQueue;
|
||||
};
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
// must call release before next get
|
||||
void release();
|
||||
// return (false,true) if message (was not, was) put into queue
|
||||
bool put(String message,MessageType messageType,bool replaceLast);
|
||||
bool put(std::string message,MessageType messageType,bool replaceLast);
|
||||
bool isEmpty() ;
|
||||
bool isFull() ;
|
||||
int getClearOverrun();
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include "typeCast.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
// need to use "long long" when sizeof(int)==sizeof(long)
|
||||
#if (ULONG_MAX == 0xfffffffful) || defined(_WIN32) || defined(__rtems__)
|
||||
#if (ULONG_MAX == 0xfffffffful) || defined(_WIN32) || defined(__rtems__) || defined(__APPLE__)
|
||||
#define NEED_LONGLONG
|
||||
#endif
|
||||
|
||||
@@ -25,7 +27,7 @@
|
||||
#endif
|
||||
|
||||
#if EPICS_VERSION_INT < VERSION_INT(3,15,0,1)
|
||||
/* integer conversion primatives added to epicsStdlib.c in 3.15.0.1 */
|
||||
/* integer conversion primitives added to epicsStdlib.c in 3.15.0.1 */
|
||||
|
||||
#define S_stdlib_noConversion 1 /* No digits to convert */
|
||||
#define S_stdlib_extraneous 2 /* Extraneous characters */
|
||||
@@ -247,7 +249,18 @@ epicsParseFloat(const char *str, float *to, char **units)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(NEED_LONGLONG) && (defined(__vxworks) || defined (_WIN32))
|
||||
// MS Visual Studio 2013 defines strtoll, etc.
|
||||
#if defined(_WIN32)
|
||||
# if (_MSC_VER >= 1800)
|
||||
# define WIN_NEEDS_OLL_FUNC 0
|
||||
# else
|
||||
# define WIN_NEEDS_OLL_FUNC 1
|
||||
# endif
|
||||
#else
|
||||
# define WIN_NEEDS_OLL_FUNC 0
|
||||
#endif
|
||||
|
||||
#if defined(NEED_LONGLONG) && (defined(__vxworks) || WIN_NEEDS_OLL_FUNC)
|
||||
static
|
||||
long long strtoll(const char *ptr, char ** endp, int base)
|
||||
{
|
||||
@@ -295,6 +308,71 @@ noconvert:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__vxworks)
|
||||
/* vxworks version of std::istringstream >>uint64_t is buggy, we use out own implementation */
|
||||
static
|
||||
unsigned long long strtoull(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s = nptr;
|
||||
unsigned long long acc;
|
||||
int c;
|
||||
unsigned long long cutoff;
|
||||
int neg = 0, any, cutlim;
|
||||
|
||||
do
|
||||
c = *s++;
|
||||
while (isspace(c));
|
||||
if (c == '-')
|
||||
{
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
}
|
||||
else if (c == '+')
|
||||
c = *s++;
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X'))
|
||||
{
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
cutoff = (unsigned long long) UINT64_MAX / (unsigned long long) base;
|
||||
cutlim = (unsigned long long) UINT64_MAX % (unsigned long long) base;
|
||||
|
||||
for (acc = 0, any = 0;; c = *s++)
|
||||
{
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else
|
||||
{
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0)
|
||||
{
|
||||
acc = UINT64_MAX;
|
||||
errno = ERANGE;
|
||||
}
|
||||
else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = any ? (char *) s - 1 : (char *) nptr;
|
||||
return (acc);
|
||||
}
|
||||
#else
|
||||
static
|
||||
unsigned long long strtoull(const char *ptr, char ** endp, int base)
|
||||
{
|
||||
@@ -337,7 +415,7 @@ noconvert:
|
||||
*endp = (char*)ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* do we need long long? */
|
||||
@@ -422,18 +500,18 @@ void handleParseError(int err)
|
||||
|
||||
namespace epics { namespace pvData { namespace detail {
|
||||
|
||||
void parseToPOD(const std::string & in, boolean *out)
|
||||
void parseToPOD(const string & in, boolean *out)
|
||||
{
|
||||
if(epicsStrCaseCmp(in.c_str(),"true")==0)
|
||||
*out = 1;
|
||||
else if(epicsStrCaseCmp(in.c_str(),"false")==0)
|
||||
*out = 0;
|
||||
else
|
||||
throw std::runtime_error("parseToPOD: String no match true/false");
|
||||
throw std::runtime_error("parseToPOD: string no match true/false");
|
||||
}
|
||||
|
||||
#define INTFN(T, S) \
|
||||
void parseToPOD(const std::string& in, T *out) { \
|
||||
void parseToPOD(const string& in, T *out) { \
|
||||
epics ## S temp; \
|
||||
int err = epicsParse ## S (in.c_str(), &temp, 0, NULL); \
|
||||
if(err) handleParseError(err); \
|
||||
@@ -447,7 +525,7 @@ INTFN(uint16_t, UInt16);
|
||||
INTFN(int32_t, Int32);
|
||||
INTFN(uint32_t, UInt32);
|
||||
|
||||
void parseToPOD(const std::string& in, int64_t *out) {
|
||||
void parseToPOD(const string& in, int64_t *out) {
|
||||
#ifdef NEED_LONGLONG
|
||||
int err = epicsParseLongLong(in.c_str(), out, 0, NULL);
|
||||
#else
|
||||
@@ -456,7 +534,7 @@ void parseToPOD(const std::string& in, int64_t *out) {
|
||||
if(err) handleParseError(err);
|
||||
}
|
||||
|
||||
void parseToPOD(const std::string& in, uint64_t *out) {
|
||||
void parseToPOD(const string& in, uint64_t *out) {
|
||||
#ifdef NEED_LONGLONG
|
||||
int err = epicsParseULongLong(in.c_str(), out, 0, NULL);
|
||||
#else
|
||||
@@ -465,14 +543,34 @@ void parseToPOD(const std::string& in, uint64_t *out) {
|
||||
if(err) handleParseError(err);
|
||||
}
|
||||
|
||||
void parseToPOD(const std::string& in, float *out) {
|
||||
void parseToPOD(const string& in, float *out) {
|
||||
int err = epicsParseFloat(in.c_str(), out, NULL);
|
||||
if(err) handleParseError(err);
|
||||
}
|
||||
|
||||
void parseToPOD(const std::string& in, double *out) {
|
||||
void parseToPOD(const string& in, double *out) {
|
||||
int err = epicsParseDouble(in.c_str(), out, NULL);
|
||||
if(err) handleParseError(err);
|
||||
#if defined(__vxworks)
|
||||
/* vxWorks strtod returns [-]epicsINF when it should return ERANGE error
|
||||
* if [-]epicsINF is returned and first char is a digit then translate this into ERANGE error
|
||||
*/
|
||||
else if (*out == epicsINF || *out == -epicsINF) {
|
||||
const char* s = in.c_str();
|
||||
int c;
|
||||
|
||||
/* skip spaces and the sign */
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace(c));
|
||||
|
||||
if (c == '-' || c == '+')
|
||||
c = *s++;
|
||||
|
||||
if (isdigit(c))
|
||||
handleParseError(S_stdlib_overflow);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
@@ -14,11 +14,13 @@
|
||||
#include <pv/lock.h>
|
||||
#include <pv/requester.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static StringArray messageTypeName(MESSAGE_TYPE_COUNT);
|
||||
|
||||
String getMessageTypeName(MessageType messageType)
|
||||
string getMessageTypeName(MessageType messageType)
|
||||
{
|
||||
// TODO not thread-safe
|
||||
static Mutex mutex;
|
||||
|
||||
@@ -26,14 +26,14 @@ enum MessageType {
|
||||
};
|
||||
#define MESSAGE_TYPE_COUNT 4
|
||||
|
||||
epicsShareExtern String getMessageTypeName(MessageType messageType);
|
||||
epicsShareExtern std::string getMessageTypeName(MessageType messageType);
|
||||
|
||||
class epicsShareClass Requester {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Requester);
|
||||
virtual ~Requester(){}
|
||||
virtual String getRequesterName() = 0;
|
||||
virtual void message(String const & message,MessageType messageType) = 0;
|
||||
virtual std::string getRequesterName() = 0;
|
||||
virtual void message(std::string const & message,MessageType messageType) = 0;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -65,9 +65,10 @@ namespace epics { namespace pvData {
|
||||
};
|
||||
|
||||
|
||||
class epicsShareClass SerializableArray : virtual public Serializable {
|
||||
class epicsShareClass SerializableArray : public virtual Serializable {
|
||||
public:
|
||||
virtual ~SerializableArray(){}
|
||||
using Serializable::serialize;
|
||||
virtual void serialize(ByteBuffer *buffer,
|
||||
SerializableControl *flusher, std::size_t offset, std::size_t count) const = 0;
|
||||
};
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace epics {
|
||||
return (std::size_t)(b<0 ? b+256 : b);
|
||||
}
|
||||
|
||||
void SerializeHelper::serializeString(const String& value,
|
||||
void SerializeHelper::serializeString(const string& value,
|
||||
ByteBuffer* buffer, SerializableControl* flusher) {
|
||||
std::size_t len = value.length();
|
||||
SerializeHelper::writeSize(len, buffer, flusher);
|
||||
@@ -74,7 +74,7 @@ namespace epics {
|
||||
}
|
||||
}
|
||||
|
||||
void SerializeHelper::serializeSubstring(const String& value,
|
||||
void SerializeHelper::serializeSubstring(const string& value,
|
||||
std::size_t offset, std::size_t count, ByteBuffer* buffer,
|
||||
SerializableControl* flusher) {
|
||||
/*if(offset<0)
|
||||
@@ -97,9 +97,9 @@ namespace epics {
|
||||
}
|
||||
}
|
||||
|
||||
static String emptyString;
|
||||
static string emptyStringtring;
|
||||
|
||||
String SerializeHelper::deserializeString(ByteBuffer* buffer,
|
||||
string SerializeHelper::deserializeString(ByteBuffer* buffer,
|
||||
DeserializableControl* control) {
|
||||
|
||||
std::size_t size = SerializeHelper::readSize(buffer, control);
|
||||
@@ -109,13 +109,13 @@ namespace epics {
|
||||
{
|
||||
// entire string is in buffer, simply create a string out of it (copy)
|
||||
std::size_t pos = buffer->getPosition();
|
||||
String str(buffer->getArray()+pos, size);
|
||||
string str(buffer->getArray()+pos, size);
|
||||
buffer->setPosition(pos+size);
|
||||
return str;
|
||||
}
|
||||
else
|
||||
{
|
||||
String str;
|
||||
string str;
|
||||
str.reserve(size);
|
||||
try {
|
||||
std::size_t i = 0;
|
||||
@@ -137,7 +137,7 @@ namespace epics {
|
||||
}
|
||||
}
|
||||
else
|
||||
return emptyString;
|
||||
return emptyStringtring;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,30 +46,30 @@ namespace epics {
|
||||
DeserializableControl* control);
|
||||
|
||||
/**
|
||||
* String serialization helper method.
|
||||
* std::string serialization helper method.
|
||||
*
|
||||
* @param[in] value String to serialize
|
||||
* @param[in] value std::string to serialize
|
||||
* @param[in] buffer serialization buffer
|
||||
* @param[in] flusher flusher
|
||||
*/
|
||||
static void serializeString(const String& value, ByteBuffer* buffer,
|
||||
static void serializeString(const std::string& value, ByteBuffer* buffer,
|
||||
SerializableControl* flusher);
|
||||
|
||||
/**
|
||||
* String serialization helper method.
|
||||
* std::string serialization helper method.
|
||||
*
|
||||
* @param[in] value String to serialize
|
||||
* @param[in] value std::string to serialize
|
||||
* @param[in] offset start of the substring in {@code value}
|
||||
* @param[in] count the number of characters to write
|
||||
* @param[in] buffer serialization buffer
|
||||
* @param[in] flusher flusher
|
||||
*/
|
||||
static void serializeSubstring(const String& value, std::size_t offset,
|
||||
static void serializeSubstring(const std::string& value, std::size_t offset,
|
||||
std::size_t count, ByteBuffer* buffer,
|
||||
SerializableControl* flusher);
|
||||
|
||||
/**
|
||||
* String deserialization helper method.
|
||||
* std::string deserialization helper method.
|
||||
* TODO This method cannot return "null", but Java implementation
|
||||
* could have serialized "null" value as well. We need to decide
|
||||
* how to deserialize "null".
|
||||
@@ -82,7 +82,7 @@ namespace epics {
|
||||
* could have serialized "null" value as well. We need to decide
|
||||
* how to deserialize "null".
|
||||
*/
|
||||
static String deserializeString(ByteBuffer* buffer,
|
||||
static std::string deserializeString(ByteBuffer* buffer,
|
||||
DeserializableControl* control);
|
||||
|
||||
private:
|
||||
|
||||
@@ -44,6 +44,25 @@
|
||||
# undef SHARED_FROM_TR1
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
# undef SHARED_FROM_BOOST
|
||||
# undef SHARED_FROM_TR1
|
||||
|
||||
#include <memory>
|
||||
|
||||
// import std classes into std::tr1
|
||||
namespace std {
|
||||
namespace tr1 {
|
||||
using std::shared_ptr;
|
||||
using std::weak_ptr;
|
||||
using std::static_pointer_cast;
|
||||
using std::dynamic_pointer_cast;
|
||||
using std::const_pointer_cast;
|
||||
using std::enable_shared_from_this;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// go and get it
|
||||
|
||||
#if defined(SHARED_FROM_TR1)
|
||||
|
||||
@@ -12,10 +12,12 @@
|
||||
#include <pv/serializeHelper.h>
|
||||
#include <pv/status.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
const char* Status::StatusTypeName[] = { "OK", "WARNING", "ERROR", "FATAL" };
|
||||
epics::pvData::String Status::m_emptyString;
|
||||
string Status::m_emptyStringtring;
|
||||
|
||||
Status Status::Ok;
|
||||
|
||||
@@ -26,7 +28,7 @@ Status::Status() :
|
||||
{
|
||||
}
|
||||
|
||||
Status::Status(StatusType type, String const & message) :
|
||||
Status::Status(StatusType type, string const & message) :
|
||||
m_statusType(type), m_message(message)
|
||||
{
|
||||
if (type == STATUSTYPE_OK)
|
||||
@@ -35,7 +37,7 @@ Status::Status(StatusType type, String const & message) :
|
||||
//PVDATA_REFCOUNT_MONITOR_CONSTRUCT(status);
|
||||
}
|
||||
|
||||
Status::Status(StatusType type, String const & message, String const & stackDump) :
|
||||
Status::Status(StatusType type, string const & message, string const & stackDump) :
|
||||
m_statusType(type), m_message(message), m_stackDump(stackDump)
|
||||
{
|
||||
if (type == STATUSTYPE_OK)
|
||||
@@ -54,12 +56,12 @@ Status::StatusType Status::getType() const
|
||||
}
|
||||
|
||||
|
||||
epics::pvData::String Status::getMessage() const
|
||||
string Status::getMessage() const
|
||||
{
|
||||
return m_message;
|
||||
}
|
||||
|
||||
epics::pvData::String Status::getStackDump() const
|
||||
string Status::getStackDump() const
|
||||
{
|
||||
return m_stackDump;
|
||||
}
|
||||
@@ -100,7 +102,7 @@ void Status::deserialize(ByteBuffer *buffer, DeserializableControl *flusher)
|
||||
if (m_statusType != STATUSTYPE_OK)
|
||||
{
|
||||
m_statusType = STATUSTYPE_OK;
|
||||
m_message = m_stackDump = m_emptyString;
|
||||
m_message = m_stackDump = m_emptyStringtring;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -111,29 +113,26 @@ void Status::deserialize(ByteBuffer *buffer, DeserializableControl *flusher)
|
||||
}
|
||||
}
|
||||
|
||||
String Status::toString() const
|
||||
void Status::dump(std::ostream& o) const
|
||||
{
|
||||
String str;
|
||||
toString(&str, 0);
|
||||
return str;
|
||||
o << "Status [type=" << Status::StatusTypeName[m_statusType];
|
||||
if (!m_message.empty())
|
||||
o << ", message=" << m_message;
|
||||
if (!m_stackDump.empty())
|
||||
o << ", stackDump=" << std::endl << m_stackDump;
|
||||
o << ']';
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const Status& status)
|
||||
{
|
||||
status.dump(o);
|
||||
return o;
|
||||
}
|
||||
|
||||
void Status::toString(StringBuilder buffer, int /*indentLevel*/) const
|
||||
std::ostream& operator<<(std::ostream& o, const Status::StatusType& statusType)
|
||||
{
|
||||
*buffer += "Status [type=";
|
||||
*buffer += StatusTypeName[m_statusType];
|
||||
if (!m_message.empty())
|
||||
{
|
||||
*buffer += ", message=";
|
||||
*buffer += m_message;
|
||||
}
|
||||
if (!m_stackDump.empty())
|
||||
{
|
||||
*buffer += ", stackDump=";
|
||||
*buffer += '\n';
|
||||
*buffer += m_stackDump;
|
||||
}
|
||||
*buffer += ']';
|
||||
o << Status::StatusTypeName[statusType];
|
||||
return o;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#ifndef STATUS_H
|
||||
#define STATUS_H
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include <pv/serialize.h>
|
||||
#include <pv/byteBuffer.h>
|
||||
#include <pv/sharedPtr.h>
|
||||
@@ -51,12 +53,12 @@ namespace epics { namespace pvData {
|
||||
/**
|
||||
* Create non-OK status.
|
||||
*/
|
||||
Status(StatusType type, epics::pvData::String const & message);
|
||||
Status(StatusType type, std::string const & message);
|
||||
|
||||
/**
|
||||
* Create non-OK status.
|
||||
*/
|
||||
Status(StatusType type, epics::pvData::String const & message, epics::pvData::String const & stackDump);
|
||||
Status(StatusType type, std::string const & message, std::string const & stackDump);
|
||||
|
||||
~Status();
|
||||
|
||||
@@ -70,13 +72,13 @@ namespace epics { namespace pvData {
|
||||
* Get error message describing an error. Required if error status.
|
||||
* @return error message.
|
||||
*/
|
||||
epics::pvData::String getMessage() const;
|
||||
std::string getMessage() const;
|
||||
|
||||
/**
|
||||
* Get stack dump where error (exception) happened. Optional.
|
||||
* @return stack dump.
|
||||
*/
|
||||
epics::pvData::String getStackDump() const;
|
||||
std::string getStackDump() const;
|
||||
|
||||
/**
|
||||
* Convenient OK test. Same as <code>(getType() == StatusType.OK)</code>.
|
||||
@@ -93,20 +95,23 @@ namespace epics { namespace pvData {
|
||||
*/
|
||||
bool isSuccess() const;
|
||||
|
||||
String toString() const;
|
||||
void toString(StringBuilder buffer, int indentLevel = 0) const;
|
||||
|
||||
void serialize(ByteBuffer *buffer, SerializableControl *flusher) const;
|
||||
void deserialize(ByteBuffer *buffer, DeserializableControl *flusher);
|
||||
|
||||
void dump(std::ostream& o) const;
|
||||
|
||||
private:
|
||||
|
||||
static epics::pvData::String m_emptyString;
|
||||
static std::string m_emptyStringtring;
|
||||
|
||||
StatusType m_statusType;
|
||||
String m_message;
|
||||
String m_stackDump;
|
||||
std::string m_message;
|
||||
std::string m_stackDump;
|
||||
|
||||
};
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, const Status& status);
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, const Status::StatusType& statusType);
|
||||
|
||||
}}
|
||||
#endif /* STATUS_H */
|
||||
|
||||
@@ -50,7 +50,7 @@ typedef epicsThreadRunable Runnable;
|
||||
class epicsShareClass Thread : public epicsThread, private NoDefaultMethods {
|
||||
public:
|
||||
|
||||
Thread(String name,
|
||||
Thread(std::string name,
|
||||
ThreadPriority priority,
|
||||
Runnable *runnable,
|
||||
epicsThreadStackSizeClass stkcls=epicsThreadStackSmall)
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
}
|
||||
|
||||
Thread(Runnable &runnable,
|
||||
String name,
|
||||
std::string name,
|
||||
unsigned int stksize,
|
||||
unsigned int priority=lowestPriority)
|
||||
:epicsThread(runnable,
|
||||
|
||||
@@ -13,11 +13,14 @@
|
||||
#endif
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/convert.h>
|
||||
#include <pv/timer.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
TimerCallback::TimerCallback()
|
||||
@@ -26,7 +29,7 @@ TimerCallback::TimerCallback()
|
||||
{
|
||||
}
|
||||
|
||||
Timer::Timer(String threadName,ThreadPriority priority)
|
||||
Timer::Timer(string threadName,ThreadPriority priority)
|
||||
: waitForWork(false),
|
||||
waitForDone(false),
|
||||
alive(true),
|
||||
@@ -84,7 +87,7 @@ void Timer::cancel(TimerCallbackPtr const &timerCallback)
|
||||
prevNode = nextNode;
|
||||
nextNode = nextNode->next;
|
||||
}
|
||||
throw std::logic_error(String(""));
|
||||
throw std::logic_error(string(""));
|
||||
}
|
||||
|
||||
bool Timer::isScheduled(TimerCallbackPtr const &timerCallback)
|
||||
@@ -169,7 +172,7 @@ void Timer::schedulePeriodic(
|
||||
double period)
|
||||
{
|
||||
if(isScheduled(timerCallback)) {
|
||||
throw std::logic_error(String("already queued"));
|
||||
throw std::logic_error(string("already queued"));
|
||||
}
|
||||
{
|
||||
Lock xx(mutex);
|
||||
@@ -193,7 +196,7 @@ void Timer::schedulePeriodic(
|
||||
if(isFirst) waitForWork.signal();
|
||||
}
|
||||
|
||||
void Timer::toString(StringBuilder builder)
|
||||
void Timer::dump(std::ostream& o)
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(!alive) return;
|
||||
@@ -205,11 +208,15 @@ void Timer::toString(StringBuilder builder)
|
||||
TimeStamp timeToRun = nodeToCall->timeToRun;
|
||||
double period = nodeToCall->period;
|
||||
double diff = TimeStamp::diff(timeToRun,currentTime);
|
||||
char buffer[50];
|
||||
sprintf(buffer,"timeToRun %f period %f\n",diff,period);
|
||||
*builder += buffer;
|
||||
o << "timeToRun " << diff << " period " << period << std::endl;
|
||||
nodeToCall = nodeToCall->next;
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, Timer& timer)
|
||||
{
|
||||
timer.dump(o);
|
||||
return o;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -50,7 +50,7 @@ private:
|
||||
class epicsShareClass Timer : public Runnable {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Timer);
|
||||
Timer(String threadName, ThreadPriority priority);
|
||||
Timer(std::string threadName, ThreadPriority priority);
|
||||
virtual ~Timer();
|
||||
virtual void run();
|
||||
void scheduleAfterDelay(
|
||||
@@ -62,7 +62,9 @@ public:
|
||||
double period);
|
||||
void cancel(TimerCallbackPtr const &timerCallback);
|
||||
bool isScheduled(TimerCallbackPtr const &timerCallback);
|
||||
void toString(StringBuilder builder);
|
||||
|
||||
void dump(std::ostream& o);
|
||||
|
||||
private:
|
||||
void addElement(TimerCallbackPtr const &timerCallback);
|
||||
TimerCallbackPtr head;
|
||||
@@ -73,5 +75,7 @@ private:
|
||||
Thread thread;
|
||||
};
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, Timer& timer);
|
||||
|
||||
}}
|
||||
#endif /* TIMER_H */
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
#include "typeCast.h"
|
||||
|
||||
using epics::pvData::castUnsafe;
|
||||
using epics::pvData::String;
|
||||
using epics::pvData::ScalarType;
|
||||
using epics::pvData::pvString;
|
||||
using std::string;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -77,7 +77,7 @@ static convertfn converters[pvString+1][pvString+1] =
|
||||
&noconvert,
|
||||
&noconvert,
|
||||
&noconvert,
|
||||
&castVTyped<epics::pvData::boolean, String>,
|
||||
&castVTyped<epics::pvData::boolean, string>,
|
||||
},
|
||||
// to pvByte
|
||||
{&noconvert,
|
||||
@@ -91,7 +91,7 @@ static convertfn converters[pvString+1][pvString+1] =
|
||||
&castVTyped<int8_t, uint64_t>,
|
||||
&castVTyped<int8_t, float>,
|
||||
&castVTyped<int8_t, double>,
|
||||
&castVTyped<int8_t, String>,
|
||||
&castVTyped<int8_t, string>,
|
||||
},
|
||||
// to pvShort
|
||||
{&noconvert,
|
||||
@@ -105,7 +105,7 @@ static convertfn converters[pvString+1][pvString+1] =
|
||||
&castVTyped<int16_t, uint64_t>,
|
||||
&castVTyped<int16_t, float>,
|
||||
&castVTyped<int16_t, double>,
|
||||
&castVTyped<int16_t, String>,
|
||||
&castVTyped<int16_t, string>,
|
||||
},
|
||||
// to pvInt
|
||||
{&noconvert,
|
||||
@@ -119,7 +119,7 @@ static convertfn converters[pvString+1][pvString+1] =
|
||||
&castVTyped<int32_t, uint64_t>,
|
||||
&castVTyped<int32_t, float>,
|
||||
&castVTyped<int32_t, double>,
|
||||
&castVTyped<int32_t, String>,
|
||||
&castVTyped<int32_t, string>,
|
||||
},
|
||||
// to pvLong
|
||||
{&noconvert,
|
||||
@@ -133,7 +133,7 @@ static convertfn converters[pvString+1][pvString+1] =
|
||||
&castVTyped<int64_t, uint64_t>,
|
||||
&castVTyped<int64_t, float>,
|
||||
&castVTyped<int64_t, double>,
|
||||
&castVTyped<int64_t, String>,
|
||||
&castVTyped<int64_t, string>,
|
||||
},
|
||||
// to pvUByte
|
||||
{&noconvert,
|
||||
@@ -147,7 +147,7 @@ static convertfn converters[pvString+1][pvString+1] =
|
||||
&castVTyped<uint8_t, uint64_t>,
|
||||
&castVTyped<uint8_t, float>,
|
||||
&castVTyped<uint8_t, double>,
|
||||
&castVTyped<uint8_t, String>,
|
||||
&castVTyped<uint8_t, string>,
|
||||
},
|
||||
// to pvUShort
|
||||
{&noconvert,
|
||||
@@ -161,7 +161,7 @@ static convertfn converters[pvString+1][pvString+1] =
|
||||
&castVTyped<uint16_t, uint64_t>,
|
||||
&castVTyped<uint16_t, float>,
|
||||
&castVTyped<uint16_t, double>,
|
||||
&castVTyped<uint16_t, String>,
|
||||
&castVTyped<uint16_t, string>,
|
||||
},
|
||||
// to pvUInt
|
||||
{&noconvert,
|
||||
@@ -175,7 +175,7 @@ static convertfn converters[pvString+1][pvString+1] =
|
||||
&castVTyped<uint32_t, uint64_t>,
|
||||
&castVTyped<uint32_t, float>,
|
||||
&castVTyped<uint32_t, double>,
|
||||
&castVTyped<uint32_t, String>,
|
||||
&castVTyped<uint32_t, string>,
|
||||
},
|
||||
// to pvULong
|
||||
{&noconvert,
|
||||
@@ -189,7 +189,7 @@ static convertfn converters[pvString+1][pvString+1] =
|
||||
©V<uint64_t>,
|
||||
&castVTyped<uint64_t, float>,
|
||||
&castVTyped<uint64_t, double>,
|
||||
&castVTyped<uint64_t, String>,
|
||||
&castVTyped<uint64_t, string>,
|
||||
},
|
||||
// to pvFloat
|
||||
{&noconvert,
|
||||
@@ -203,7 +203,7 @@ static convertfn converters[pvString+1][pvString+1] =
|
||||
&castVTyped<float, uint64_t>,
|
||||
©V<float>,
|
||||
&castVTyped<float, double>,
|
||||
&castVTyped<float, String>,
|
||||
&castVTyped<float, string>,
|
||||
},
|
||||
// to pvDouble
|
||||
{&noconvert,
|
||||
@@ -217,21 +217,21 @@ static convertfn converters[pvString+1][pvString+1] =
|
||||
&castVTyped<double, uint64_t>,
|
||||
&castVTyped<double, float>,
|
||||
©V<double>,
|
||||
&castVTyped<double, String>,
|
||||
&castVTyped<double, string>,
|
||||
},
|
||||
// to pvString
|
||||
{&castVTyped<String, epics::pvData::boolean>,
|
||||
&castVTyped<String, int8_t>,
|
||||
&castVTyped<String, int16_t>,
|
||||
&castVTyped<String, int32_t>,
|
||||
&castVTyped<String, uint64_t>,
|
||||
&castVTyped<String, uint8_t>,
|
||||
&castVTyped<String, uint16_t>,
|
||||
&castVTyped<String, uint32_t>,
|
||||
&castVTyped<String, uint64_t>,
|
||||
&castVTyped<String, float>,
|
||||
&castVTyped<String, double>,
|
||||
©V<String>,
|
||||
{&castVTyped<string, epics::pvData::boolean>,
|
||||
&castVTyped<string, int8_t>,
|
||||
&castVTyped<string, int16_t>,
|
||||
&castVTyped<string, int32_t>,
|
||||
&castVTyped<string, uint64_t>,
|
||||
&castVTyped<string, uint8_t>,
|
||||
&castVTyped<string, uint16_t>,
|
||||
&castVTyped<string, uint32_t>,
|
||||
&castVTyped<string, uint64_t>,
|
||||
&castVTyped<string, float>,
|
||||
&castVTyped<string, double>,
|
||||
©V<string>,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
typedef std::string String;
|
||||
|
||||
namespace detail {
|
||||
// parseToPOD wraps the epicsParse*() functions in one name
|
||||
// and throws exceptions
|
||||
@@ -48,12 +46,12 @@ namespace detail {
|
||||
epicsShareExtern void parseToPOD(const std::string&, double *out);
|
||||
|
||||
/* want to pass POD types by value,
|
||||
* and String by const reference
|
||||
* and std::string by const reference
|
||||
*/
|
||||
template<typename ARG>
|
||||
struct cast_arg { typedef ARG arg; };
|
||||
template<>
|
||||
struct cast_arg<String> { typedef const String& arg; };
|
||||
struct cast_arg<std::string> { typedef const std::string& arg; };
|
||||
|
||||
// Handle mangling of type/value when printing
|
||||
template<typename T>
|
||||
@@ -98,10 +96,10 @@ namespace detail {
|
||||
};
|
||||
|
||||
// print POD to string
|
||||
// when String!=FROM
|
||||
// when std::string!=FROM
|
||||
template<typename FROM>
|
||||
struct cast_helper<String, FROM, typename meta::not_same_type<String,FROM>::type> {
|
||||
static String op(FROM from) {
|
||||
struct cast_helper<std::string, FROM, typename meta::not_same_type<std::string,FROM>::type> {
|
||||
static std::string op(FROM from) {
|
||||
std::ostringstream strm;
|
||||
strm << print_convolute<FROM>::op(from);
|
||||
if(strm.fail())
|
||||
@@ -111,10 +109,10 @@ namespace detail {
|
||||
};
|
||||
|
||||
// parse POD from string
|
||||
// TO!=String
|
||||
// TO!=std::string
|
||||
template<typename TO>
|
||||
struct cast_helper<TO, String, typename meta::not_same_type<TO,String>::type> {
|
||||
static FORCE_INLINE TO op(const String& from) {
|
||||
struct cast_helper<TO, std::string, typename meta::not_same_type<TO,std::string>::type> {
|
||||
static FORCE_INLINE TO op(const std::string& from) {
|
||||
TO ret;
|
||||
parseToPOD(from, &ret);
|
||||
return ret;
|
||||
@@ -127,7 +125,7 @@ namespace detail {
|
||||
*
|
||||
* Supported types: uint8_t, int8_t, uint16_t, int16_t,
|
||||
* uint32_t, int32_t, uint64_t, int64_t,
|
||||
* float, double, String
|
||||
* float, double, std::string
|
||||
*
|
||||
* As defined in pvType.h
|
||||
*
|
||||
@@ -153,9 +151,9 @@ namespace detail {
|
||||
* Conversions where invalid or out of range inputs result
|
||||
* in an exception.
|
||||
*
|
||||
* - non-String -> String
|
||||
* - String -> non-String
|
||||
* - String -> String (throws only std::bad_alloc)
|
||||
* - non-std::string -> std::string
|
||||
* - std::string -> non-std::string
|
||||
* - std::string -> std::string (throws only std::bad_alloc)
|
||||
*
|
||||
* Conversions where out of range inputs produce undefined
|
||||
* results.
|
||||
@@ -169,7 +167,7 @@ namespace detail {
|
||||
* too large to be represented by the integer type
|
||||
* is not defined.
|
||||
*
|
||||
@section stringf String formats
|
||||
@section stringf std::string formats
|
||||
*
|
||||
* - Numbers beginning with 1-9 are parsed as base-10.
|
||||
* - Numbers beginning with '0x' are parsed as base-16
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
SRC_DIRS += $(PVDATA_SRC)/monitor
|
||||
|
||||
INC += monitor.h
|
||||
INC += monitorPlugin.h
|
||||
|
||||
LIBSRCS += monitor.cpp
|
||||
|
||||
LIBSRCS += monitorPlugin.cpp
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/sharedPtr.h>
|
||||
#include <pv/bitSet.h>
|
||||
#include <pv/requester.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
|
||||
86
src/monitor/monitorPlugin.cpp
Normal file
86
src/monitor/monitorPlugin.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/* monitorPlugin.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <pv/monitorPlugin.h>
|
||||
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
MonitorPluginManagerPtr MonitorPluginManager::get()
|
||||
{
|
||||
static MonitorPluginManagerPtr pluginManager;
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
if(!pluginManager) {
|
||||
pluginManager = MonitorPluginManagerPtr(new MonitorPluginManager());
|
||||
}
|
||||
return pluginManager;
|
||||
}
|
||||
|
||||
bool MonitorPluginManager::addPlugin(
|
||||
string const &pluginName,
|
||||
MonitorPluginCreatorPtr const &creator)
|
||||
{
|
||||
mutex.lock();
|
||||
std::list<MonitorPluginCreatorPtr>::iterator iter;
|
||||
for (iter = monitorPluginList.begin();iter!=monitorPluginList.end();iter++)
|
||||
{
|
||||
if(*iter==creator)
|
||||
{
|
||||
mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
if(((*iter)->getName().compare(pluginName))==0)
|
||||
{
|
||||
mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
monitorPluginList.push_back(creator);
|
||||
mutex.unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
MonitorPluginCreatorPtr MonitorPluginManager::findPlugin(
|
||||
string const &pluginName)
|
||||
{
|
||||
mutex.lock();
|
||||
std::list<MonitorPluginCreatorPtr>::iterator iter;
|
||||
for (iter = monitorPluginList.begin();iter!=monitorPluginList.end();++iter)
|
||||
{
|
||||
if(((*iter)->getName().compare(pluginName))==0)
|
||||
{
|
||||
mutex.unlock();
|
||||
return *iter;
|
||||
}
|
||||
}
|
||||
mutex.unlock();
|
||||
return MonitorPluginCreatorPtr();
|
||||
}
|
||||
|
||||
void MonitorPluginManager::showNames()
|
||||
{
|
||||
mutex.lock();
|
||||
std::list<MonitorPluginCreatorPtr>::iterator iter;
|
||||
for (iter = monitorPluginList.begin();iter!=monitorPluginList.end();++iter)
|
||||
{
|
||||
std::cout << (*iter)->getName() << std::endl;
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
177
src/monitor/monitorPlugin.h
Normal file
177
src/monitor/monitorPlugin.h
Normal file
@@ -0,0 +1,177 @@
|
||||
/* monitorPlugin.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef MONITORPLUGIN_H
|
||||
#define MONITORPLUGIN_H
|
||||
|
||||
#include <list>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/sharedPtr.h>
|
||||
#include <pv/bitSet.h>
|
||||
#include <pv/monitor.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
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;
|
||||
* 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
|
||||
* structure.
|
||||
*/
|
||||
class epicsShareClass MonitorPlugin
|
||||
{
|
||||
public:
|
||||
virtual ~MonitorPlugin(){}
|
||||
/**
|
||||
* getName
|
||||
* @returns The name of the plugin
|
||||
*/
|
||||
virtual std::string const & getName() = 0;
|
||||
/**
|
||||
* 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.
|
||||
* @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
|
||||
* monitor.
|
||||
*/
|
||||
virtual bool causeMonitor(
|
||||
PVFieldPtr const &pvField,
|
||||
PVStructurePtr const &pvTop,
|
||||
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.
|
||||
*/
|
||||
virtual void monitorDone(
|
||||
MonitorElementPtr const &monitorElement)
|
||||
{}
|
||||
/**
|
||||
* Begin monitoring
|
||||
*/
|
||||
virtual void startMonitoring(){}
|
||||
/**
|
||||
* Stop monitoring
|
||||
*/
|
||||
virtual void stopMonitoring(){}
|
||||
/**
|
||||
* Begin a set of puts.
|
||||
*/
|
||||
virtual void beginGroupPut() {};
|
||||
/**
|
||||
* End a set of puts.
|
||||
*/
|
||||
virtual void endGroupPut() {};
|
||||
};
|
||||
|
||||
/** A class that creates a plugin.
|
||||
* Normlly a plugin is created for a single client.
|
||||
*/
|
||||
class epicsShareClass MonitorPluginCreator
|
||||
{
|
||||
public:
|
||||
virtual ~MonitorPluginCreator() {}
|
||||
/**
|
||||
* Create a monitor plugin.
|
||||
* @param field The introspection interface for the field monitored.
|
||||
* @param top The introspsction 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.
|
||||
* The subfield name is the name and the subfield value is the value.
|
||||
* @returns shared pointer to a MonitorPluginCreator.
|
||||
*/
|
||||
virtual MonitorPluginPtr create(
|
||||
FieldConstPtr const &field,
|
||||
StructureConstPtr const &top,
|
||||
PVStructurePtr const &pvFieldOptions) = 0;
|
||||
/**
|
||||
* getName
|
||||
* @returns The name of the plugin
|
||||
*/
|
||||
virtual std::string const & getName() = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This manages a set of monitor plugins.
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass MonitorPluginManager
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(MonitorPluginManager);
|
||||
/**
|
||||
* Factory to get the manager.
|
||||
* @return shared pointer to manager.
|
||||
*/
|
||||
static MonitorPluginManagerPtr get();
|
||||
/** destructor
|
||||
*/
|
||||
~MonitorPluginManager(){}
|
||||
/* add plugin
|
||||
* @param pluginName The name of the plugin.
|
||||
* @param creator The creator.
|
||||
* @returns true or false
|
||||
* false is returned if a plugin with that name is already present
|
||||
*/
|
||||
bool addPlugin(
|
||||
std::string const &pluginName,
|
||||
MonitorPluginCreatorPtr const &creator);
|
||||
/* find plugin
|
||||
*
|
||||
* @param plugin name
|
||||
* @returns share pointer to plugin creator.
|
||||
* If a plugin with that name is not found NULL is returned.
|
||||
*/
|
||||
MonitorPluginCreatorPtr findPlugin(std::string const &pluginName);
|
||||
/* showNames
|
||||
*
|
||||
*/
|
||||
void showNames();
|
||||
private:
|
||||
MonitorPluginManager(){}
|
||||
std::list<MonitorPluginCreatorPtr> monitorPluginList;
|
||||
epics::pvData::Mutex mutex;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}}
|
||||
#endif /* MONITORPLUGIN_H */
|
||||
@@ -17,12 +17,14 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/alarm.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
AlarmSeverity AlarmSeverityFunc::getSeverity(int value)
|
||||
{
|
||||
if(value<0 || value>4) {
|
||||
throw std::logic_error(String("getSeverity value is illegal"));
|
||||
throw std::logic_error(string("getSeverity value is illegal"));
|
||||
}
|
||||
switch (value) {
|
||||
case 0: return noAlarm;
|
||||
@@ -31,7 +33,7 @@ AlarmSeverity AlarmSeverityFunc::getSeverity(int value)
|
||||
case 3: return invalidAlarm;
|
||||
case 4: return undefinedAlarm;
|
||||
}
|
||||
throw std::logic_error(String("should never get here"));
|
||||
throw std::logic_error(string("should never get here"));
|
||||
}
|
||||
|
||||
StringArrayPtr AlarmSeverityFunc::getSeverityNames()
|
||||
@@ -61,13 +63,13 @@ AlarmSeverity Alarm::getSeverity() const
|
||||
case 3: return invalidAlarm;
|
||||
case 4: return undefinedAlarm;
|
||||
}
|
||||
throw std::logic_error(String("should never get here"));
|
||||
throw std::logic_error(string("should never get here"));
|
||||
}
|
||||
|
||||
AlarmStatus AlarmStatusFunc::getStatus(int value)
|
||||
{
|
||||
if(value<0 || value>7) {
|
||||
throw std::logic_error(String("getStatus value is illegal"));
|
||||
throw std::logic_error(string("getStatus value is illegal"));
|
||||
}
|
||||
switch (value) {
|
||||
case 0: return noStatus;
|
||||
@@ -79,7 +81,7 @@ AlarmStatus AlarmStatusFunc::getStatus(int value)
|
||||
case 6: return undefinedStatus;
|
||||
case 7: return clientStatus;
|
||||
}
|
||||
throw std::logic_error(String("should never get here"));
|
||||
throw std::logic_error(string("should never get here"));
|
||||
}
|
||||
|
||||
StringArrayPtr AlarmStatusFunc::getStatusNames()
|
||||
@@ -115,7 +117,7 @@ AlarmStatus Alarm::getStatus() const
|
||||
case 6: return undefinedStatus;
|
||||
case 7: return clientStatus;
|
||||
}
|
||||
throw std::logic_error(String("should never get here"));
|
||||
throw std::logic_error(string("should never get here"));
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -42,10 +42,10 @@ public:
|
||||
|
||||
class epicsShareClass Alarm {
|
||||
public:
|
||||
Alarm() : severity(0),status(0), message(String("")) {}
|
||||
Alarm() : severity(0),status(0), message(std::string("")) {}
|
||||
//default constructors and destructor are OK
|
||||
String getMessage() const {return message;}
|
||||
void setMessage(String const &value) {message = value;}
|
||||
std::string getMessage() const {return message;}
|
||||
void setMessage(std::string const &value) {message = value;}
|
||||
AlarmSeverity getSeverity() const;
|
||||
void setSeverity(AlarmSeverity value) {severity = value;}
|
||||
AlarmStatus getStatus() const;
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
private:
|
||||
int32 severity;
|
||||
int32 status;
|
||||
String message;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace epics { namespace pvData {
|
||||
|
||||
class epicsShareClass Control {
|
||||
public:
|
||||
Control() : low(0.0), high(0.0) {}
|
||||
Control() : low(0.0), high(0.0), minStep(0.0) {}
|
||||
//default constructors and destructor are OK
|
||||
double getLow() const {return low;}
|
||||
double getHigh() const {return high;}
|
||||
|
||||
@@ -22,23 +22,23 @@ namespace epics { namespace pvData {
|
||||
class epicsShareClass Display {
|
||||
public:
|
||||
Display()
|
||||
: description(String("")),format(String("")),units(String("")),
|
||||
: description(std::string("")),format(std::string("")),units(std::string("")),
|
||||
low(0.0),high(0.0) {}
|
||||
//default constructors and destructor are OK
|
||||
double getLow() const {return low;}
|
||||
double getHigh() const{ return high;}
|
||||
void setLow(double value){low = value;}
|
||||
void setHigh(double value){high = value;}
|
||||
String getDescription() const {return description;}
|
||||
void setDescription(String const & value) {description = value;}
|
||||
String getFormat() const {return format;}
|
||||
void setFormat(String const & value) {format = value;}
|
||||
String getUnits() const {return units;}
|
||||
void setUnits(String const & value) {units = value;}
|
||||
std::string getDescription() const {return description;}
|
||||
void setDescription(std::string const & value) {description = value;}
|
||||
std::string getFormat() const {return format;}
|
||||
void setFormat(std::string const & value) {format = value;}
|
||||
std::string getUnits() const {return units;}
|
||||
void setUnits(std::string const & value) {units = value;}
|
||||
private:
|
||||
String description;
|
||||
String format;
|
||||
String units;
|
||||
std::string description;
|
||||
std::string format;
|
||||
std::string units;
|
||||
double low;
|
||||
double high;
|
||||
};
|
||||
|
||||
@@ -16,34 +16,27 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvAlarm.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
String PVAlarm::noAlarmFound("No alarm structure found");
|
||||
String PVAlarm::notAttached("Not attached to an alarm structure");
|
||||
string PVAlarm::noAlarmFound("No alarm structure found");
|
||||
string PVAlarm::notAttached("Not attached to an alarm structure");
|
||||
|
||||
bool PVAlarm::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(noAlarmFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
if(pvField->getField()->getType()!=structure) return false;
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvSeverity = pvStructure->getIntField("severity");
|
||||
if(pvSeverity.get()==NULL) {
|
||||
pvField->message(noAlarmFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
if(pvSeverity.get()==NULL) return false;
|
||||
pvStatus = pvStructure->getIntField("status");
|
||||
if(pvStatus.get()==NULL) {
|
||||
pvField->message(noAlarmFound,errorMessage);
|
||||
pvSeverity.reset();
|
||||
return false;
|
||||
}
|
||||
pvMessage = pvStructure->getStringField("message");
|
||||
if(pvMessage.get()==NULL) {
|
||||
pvField->message(noAlarmFound,errorMessage);
|
||||
pvSeverity.reset();
|
||||
pvStatus.reset();
|
||||
return false;
|
||||
|
||||
@@ -37,8 +37,8 @@ private:
|
||||
PVIntPtr pvSeverity;
|
||||
PVIntPtr pvStatus;
|
||||
PVStringPtr pvMessage;
|
||||
static String noAlarmFound;
|
||||
static String notAttached;
|
||||
static std::string noAlarmFound;
|
||||
static std::string notAttached;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -19,26 +19,26 @@
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
|
||||
String PVControl::noControlFound("No control structure found");
|
||||
String PVControl::notAttached("Not attached to an control structure");
|
||||
string PVControl::noControlFound("No control structure found");
|
||||
string PVControl::notAttached("Not attached to an control structure");
|
||||
|
||||
bool PVControl::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(noControlFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
if(pvField->getField()->getType()!=structure) return false;
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvLow = pvStructure->getDoubleField("limitLow");
|
||||
if(pvLow.get()==NULL) {
|
||||
pvField->message(noControlFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvHigh = pvStructure->getDoubleField(String("limitHigh"));
|
||||
if(pvLow.get()==NULL) return false;
|
||||
pvHigh = pvStructure->getDoubleField("limitHigh");
|
||||
if(pvHigh.get()==NULL) {
|
||||
pvLow.reset();
|
||||
pvField->message(noControlFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvMinStep = pvStructure->getDoubleField("minStep");
|
||||
if(pvMinStep.get()==NULL) {
|
||||
pvLow.reset();
|
||||
pvHigh.reset();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -62,6 +62,7 @@ void PVControl::get(Control &control) const
|
||||
}
|
||||
control.setLow(pvLow->get());
|
||||
control.setHigh(pvHigh->get());
|
||||
control.setMinStep(pvMinStep->get());
|
||||
}
|
||||
|
||||
bool PVControl::set(Control const & control)
|
||||
@@ -69,9 +70,10 @@ bool PVControl::set(Control const & control)
|
||||
if(pvLow.get()==NULL) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
if(pvLow->isImmutable() || pvHigh->isImmutable()) return false;
|
||||
if(pvLow->isImmutable() || pvHigh->isImmutable() || pvMinStep->isImmutable()) return false;
|
||||
pvLow->put(control.getLow());
|
||||
pvHigh->put(control.getHigh());
|
||||
pvMinStep->put(control.getMinStep());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,9 @@ public:
|
||||
private:
|
||||
PVDoublePtr pvLow;
|
||||
PVDoublePtr pvHigh;
|
||||
static String noControlFound;
|
||||
static String notAttached;
|
||||
PVDoublePtr pvMinStep;
|
||||
static std::string noControlFound;
|
||||
static std::string notAttached;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -16,46 +16,37 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvDisplay.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
String PVDisplay::noDisplayFound("No display structure found");
|
||||
String PVDisplay::notAttached("Not attached to an display structure");
|
||||
string PVDisplay::noDisplayFound("No display structure found");
|
||||
string PVDisplay::notAttached("Not attached to an display structure");
|
||||
|
||||
bool PVDisplay::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
if(pvField->getField()->getType()!=structure) return false;
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvDescription = pvStructure->getStringField("description");
|
||||
if(pvDescription.get()==NULL) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
if(pvDescription.get()==NULL) return false;
|
||||
pvFormat = pvStructure->getStringField("format");
|
||||
if(pvFormat.get()==NULL) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
detach();
|
||||
return false;
|
||||
}
|
||||
pvUnits = pvStructure->getStringField("units");
|
||||
if(pvUnits.get()==NULL) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
detach();
|
||||
return false;
|
||||
}
|
||||
pvLow = pvStructure->getDoubleField(String("limitLow"));
|
||||
pvLow = pvStructure->getDoubleField(string("limitLow"));
|
||||
if(pvLow.get()==NULL) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
detach();
|
||||
return false;
|
||||
}
|
||||
pvHigh = pvStructure->getDoubleField(String("limitHigh"));
|
||||
pvHigh = pvStructure->getDoubleField(string("limitHigh"));
|
||||
if(pvHigh.get()==NULL) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
detach();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ public:
|
||||
void get(Display &) const;
|
||||
bool set(Display const & display);
|
||||
private:
|
||||
static String noDisplayFound;
|
||||
static String notAttached;
|
||||
static std::string noDisplayFound;
|
||||
static std::string notAttached;
|
||||
PVStringPtr pvDescription;
|
||||
PVStringPtr pvFormat;
|
||||
PVStringPtr pvUnits;
|
||||
|
||||
@@ -16,30 +16,24 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvEnumerated.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
String PVEnumerated::notFound("No enumerated structure found");
|
||||
String PVEnumerated::notAttached("Not attached to an enumerated structure");
|
||||
string PVEnumerated::notFound("No enumerated structure found");
|
||||
string PVEnumerated::notAttached("Not attached to an enumerated structure");
|
||||
|
||||
bool PVEnumerated::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(notFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
if(pvField->getField()->getType()!=structure) return false;
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvIndex = pvStructure->getIntField("index");
|
||||
if(pvIndex.get()==NULL) {
|
||||
pvField->message(notFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
if(pvIndex.get()==NULL) return false;
|
||||
PVScalarArrayPtr pvScalarArray = pvStructure->getScalarArrayField(
|
||||
"choices",pvString);
|
||||
if(pvScalarArray.get()==NULL) {
|
||||
pvIndex.reset();
|
||||
pvField->message(notFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvChoices = static_pointer_cast<PVStringArray>(pvScalarArray);
|
||||
@@ -75,7 +69,7 @@ int32 PVEnumerated::getIndex()
|
||||
return pvIndex->get();
|
||||
}
|
||||
|
||||
String PVEnumerated::getChoice()
|
||||
string PVEnumerated::getChoice()
|
||||
{
|
||||
if(pvIndex.get()==NULL ) {
|
||||
throw std::logic_error(notAttached);
|
||||
|
||||
@@ -33,14 +33,14 @@ public:
|
||||
// a set returns false if field is immutable
|
||||
bool setIndex(int32 index);
|
||||
int32 getIndex();
|
||||
String getChoice();
|
||||
std::string getChoice();
|
||||
bool choicesMutable();
|
||||
inline PVStringArray::const_svector getChoices(){return pvChoices->view();}
|
||||
int32 getNumberChoices();
|
||||
bool setChoices(const StringArray & choices);
|
||||
private:
|
||||
static String notFound;
|
||||
static String notAttached;
|
||||
static std::string notFound;
|
||||
static std::string notAttached;
|
||||
PVIntPtr pvIndex;
|
||||
PVStringArrayPtr pvChoices;
|
||||
};
|
||||
|
||||
@@ -16,26 +16,24 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
String PVTimeStamp::noTimeStamp("No timeStamp structure found");
|
||||
String PVTimeStamp::notAttached("Not attached to a timeStamp structure");
|
||||
string PVTimeStamp::noTimeStamp("No timeStamp structure found");
|
||||
string PVTimeStamp::notAttached("Not attached to a timeStamp structure");
|
||||
|
||||
bool PVTimeStamp::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(noTimeStamp,errorMessage);
|
||||
return false;
|
||||
}
|
||||
if(pvField->getField()->getType()!=structure) return false;
|
||||
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
|
||||
PVStructure* pvStructure = xxx.get();
|
||||
while(true) {
|
||||
PVLongPtr pvLong = pvStructure->getLongField("secondsPastEpoch");
|
||||
if(pvLong.get()!=NULL) {
|
||||
pvSecs = pvLong;
|
||||
pvNano = pvStructure->getIntField("nanoSeconds");
|
||||
pvNano = pvStructure->getIntField("nanoseconds");
|
||||
pvUserTag = pvStructure->getIntField("userTag");
|
||||
}
|
||||
if(pvSecs.get()!=NULL
|
||||
@@ -78,7 +76,7 @@ bool PVTimeStamp::set(TimeStamp const & timeStamp)
|
||||
if(pvSecs->isImmutable() || pvNano->isImmutable()) return false;
|
||||
pvSecs->put(timeStamp.getSecondsPastEpoch());
|
||||
pvUserTag->put(timeStamp.getUserTag());
|
||||
pvNano->put(timeStamp.getNanoSeconds());
|
||||
pvNano->put(timeStamp.getNanoseconds());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@ public:
|
||||
void get(TimeStamp &) const;
|
||||
bool set(TimeStamp const & timeStamp);
|
||||
private:
|
||||
static String noTimeStamp;
|
||||
static String notAttached;
|
||||
static std::string noTimeStamp;
|
||||
static std::string notAttached;
|
||||
PVLongPtr pvSecs;
|
||||
PVIntPtr pvUserTag;
|
||||
PVIntPtr pvNano;
|
||||
|
||||
@@ -27,21 +27,21 @@ int32 microSecPerSec = milliSecPerSec*milliSecPerSec;
|
||||
int32 nanoSecPerSec = milliSecPerSec*microSecPerSec;
|
||||
int64 posixEpochAtEpicsEpoch = POSIX_TIME_AT_EPICS_EPOCH;
|
||||
|
||||
TimeStamp::TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds,int32 userTag)
|
||||
: secondsPastEpoch(secondsPastEpoch),nanoSeconds(nanoSeconds),userTag(userTag)
|
||||
TimeStamp::TimeStamp(int64 secondsPastEpoch,int32 nanoseconds,int32 userTag)
|
||||
: secondsPastEpoch(secondsPastEpoch),nanoseconds(nanoseconds),userTag(userTag)
|
||||
{
|
||||
normalize();
|
||||
}
|
||||
|
||||
void TimeStamp::normalize()
|
||||
{
|
||||
if(nanoSeconds>=0 && nanoSeconds<nanoSecPerSec) return;
|
||||
while(nanoSeconds>=nanoSecPerSec) {
|
||||
nanoSeconds -= nanoSecPerSec;
|
||||
if(nanoseconds>=0 && nanoseconds<nanoSecPerSec) return;
|
||||
while(nanoseconds>=nanoSecPerSec) {
|
||||
nanoseconds -= nanoSecPerSec;
|
||||
secondsPastEpoch++;
|
||||
}
|
||||
while(nanoSeconds<0) {
|
||||
nanoSeconds += nanoSecPerSec;
|
||||
while(nanoseconds<0) {
|
||||
nanoseconds += nanoSecPerSec;
|
||||
secondsPastEpoch--;
|
||||
}
|
||||
}
|
||||
@@ -51,21 +51,21 @@ void TimeStamp::fromTime_t(const time_t & tt)
|
||||
epicsTimeStamp epicsTime;
|
||||
epicsTimeFromTime_t(&epicsTime,tt);
|
||||
secondsPastEpoch = epicsTime.secPastEpoch + posixEpochAtEpicsEpoch;
|
||||
nanoSeconds = epicsTime.nsec;
|
||||
nanoseconds = epicsTime.nsec;
|
||||
}
|
||||
|
||||
void TimeStamp::toTime_t(time_t &tt) const
|
||||
{
|
||||
epicsTimeStamp epicsTime;
|
||||
epicsTime.secPastEpoch = static_cast<epicsUInt32>(secondsPastEpoch-posixEpochAtEpicsEpoch);
|
||||
epicsTime.nsec = nanoSeconds;
|
||||
epicsTime.nsec = nanoseconds;
|
||||
epicsTimeToTime_t(&tt,&epicsTime);
|
||||
}
|
||||
|
||||
void TimeStamp::put(int64 milliseconds)
|
||||
{
|
||||
secondsPastEpoch = milliseconds/1000;
|
||||
nanoSeconds = (milliseconds%1000)*1000000;
|
||||
nanoseconds = (milliseconds%1000)*1000000;
|
||||
}
|
||||
|
||||
void TimeStamp::getCurrent()
|
||||
@@ -74,13 +74,13 @@ void TimeStamp::getCurrent()
|
||||
epicsTimeGetCurrent(&epicsTime);
|
||||
secondsPastEpoch = epicsTime.secPastEpoch;
|
||||
secondsPastEpoch += posixEpochAtEpicsEpoch;
|
||||
nanoSeconds = epicsTime.nsec;
|
||||
nanoseconds = epicsTime.nsec;
|
||||
}
|
||||
|
||||
double TimeStamp::toSeconds() const
|
||||
{
|
||||
double value = static_cast<double>(secondsPastEpoch);
|
||||
double nano = nanoSeconds;
|
||||
double nano = nanoseconds;
|
||||
value += nano/1e9;
|
||||
return value;
|
||||
}
|
||||
@@ -88,9 +88,9 @@ double TimeStamp::toSeconds() const
|
||||
int64 TimeStamp::diffInt(TimeStamp const & left,TimeStamp const&right )
|
||||
{
|
||||
int64 sl = left.secondsPastEpoch;
|
||||
int32 nl = left.nanoSeconds;
|
||||
int32 nl = left.nanoseconds;
|
||||
int64 sr = right.secondsPastEpoch;
|
||||
int32 nr = right.nanoSeconds;
|
||||
int32 nr = right.nanoseconds;
|
||||
int64 sdiff = sl - sr;
|
||||
sdiff *= nanoSecPerSec;
|
||||
sdiff += nl - nr;
|
||||
@@ -142,7 +142,7 @@ bool TimeStamp::operator>(TimeStamp const &right) const
|
||||
double TimeStamp::diff(TimeStamp const & a,TimeStamp const & b)
|
||||
{
|
||||
double result = static_cast<double>(a.secondsPastEpoch - b.secondsPastEpoch);
|
||||
result += (a.nanoSeconds - b.nanoSeconds)/1e9;
|
||||
result += (a.nanoseconds - b.nanoseconds)/1e9;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -163,12 +163,12 @@ TimeStamp & TimeStamp::operator+=(double seconds)
|
||||
{
|
||||
int64 secs = static_cast<int64>(seconds);
|
||||
int64 nano = static_cast<int64>((seconds - secs)*1e9);
|
||||
nanoSeconds += static_cast<int32>(nano);
|
||||
if(nanoSeconds>nanoSecPerSec) {
|
||||
nanoSeconds -= nanoSecPerSec;
|
||||
nanoseconds += static_cast<int32>(nano);
|
||||
if(nanoseconds>nanoSecPerSec) {
|
||||
nanoseconds -= nanoSecPerSec;
|
||||
secondsPastEpoch += 1;
|
||||
} else if(nanoSeconds<-nanoSecPerSec) {
|
||||
nanoSeconds += -nanoSecPerSec;
|
||||
} else if(nanoseconds<-nanoSecPerSec) {
|
||||
nanoseconds += -nanoSecPerSec;
|
||||
secondsPastEpoch -= 1;
|
||||
}
|
||||
secondsPastEpoch += secs;
|
||||
@@ -182,7 +182,7 @@ TimeStamp & TimeStamp::operator-=(double seconds)
|
||||
|
||||
int64 TimeStamp::getMilliseconds()
|
||||
{
|
||||
return secondsPastEpoch*1000 + nanoSeconds/1000000;
|
||||
return secondsPastEpoch*1000 + nanoseconds/1000000;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -38,8 +38,8 @@ epicsShareExtern int64 posixEpochAtEpicsEpoch;
|
||||
class epicsShareClass TimeStamp {
|
||||
public:
|
||||
TimeStamp()
|
||||
:secondsPastEpoch(0), nanoSeconds(0), userTag(0) {}
|
||||
TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds = 0,int32 userTag = 0);
|
||||
:secondsPastEpoch(0), nanoseconds(0), userTag(0) {}
|
||||
TimeStamp(int64 secondsPastEpoch,int32 nanoseconds = 0,int32 userTag = 0);
|
||||
//default constructors and destructor are OK
|
||||
//This class should not be extended
|
||||
void normalize();
|
||||
@@ -49,12 +49,12 @@ public:
|
||||
int64 getEpicsSecondsPastEpoch() const {
|
||||
return secondsPastEpoch - posixEpochAtEpicsEpoch;
|
||||
}
|
||||
int32 getNanoSeconds() const {return nanoSeconds;}
|
||||
int32 getNanoseconds() const {return nanoseconds;}
|
||||
int32 getUserTag() const {return userTag;}
|
||||
void setUserTag(int userTag) {this->userTag = userTag;}
|
||||
void put(int64 secondsPastEpoch,int32 nanoSeconds = 0) {
|
||||
void put(int64 secondsPastEpoch,int32 nanoseconds = 0) {
|
||||
this->secondsPastEpoch = secondsPastEpoch;
|
||||
this->nanoSeconds = nanoSeconds;
|
||||
this->nanoseconds = nanoseconds;
|
||||
normalize();
|
||||
}
|
||||
void put(int64 milliseconds);
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
private:
|
||||
static int64 diffInt(TimeStamp const &left,TimeStamp const &right );
|
||||
int64 secondsPastEpoch;
|
||||
int32 nanoSeconds;
|
||||
int32 nanoseconds;
|
||||
int32 userTag;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ 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);}
|
||||
@@ -50,6 +51,8 @@ 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);}
|
||||
|
||||
|
||||
/**
|
||||
@@ -63,12 +66,10 @@ static inline bool operator!=(const UnionArray& a, const UnionArray& b)
|
||||
* pvUByte, pvUShort, pvUInt, pvULong,
|
||||
* pvFloat, or pvDouble.</p>
|
||||
*
|
||||
* <p>getString converts any supported type to a String.
|
||||
* Code that implements a PVField interface should implement
|
||||
* method toString by calling this method.</p>
|
||||
* <p>getString converts any supported type to a std::string.</p>
|
||||
*
|
||||
* <p>fromString converts a String to a scalar.
|
||||
* fromStringArray converts an array of Strings
|
||||
* <p>fromString converts a std::string to a scalar.
|
||||
* fromStringArray converts an array of std::strings
|
||||
* to a pvArray, which must have a scaler element type.
|
||||
* 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>
|
||||
@@ -85,7 +86,7 @@ public:
|
||||
* @param builder The builder that will have the result.
|
||||
* @param pvField The pvField.
|
||||
*/
|
||||
void getFullName(StringBuilder buf,PVFieldPtr const & pvField)
|
||||
void getFullName(std::string *buf,PVFieldPtr const & pvField)
|
||||
{
|
||||
*buf = pvField->getFullName();
|
||||
}
|
||||
@@ -121,7 +122,7 @@ public:
|
||||
* If a PVField is a structure or array be prepared for a very long string.
|
||||
* @param indentLevel indentation level
|
||||
*/
|
||||
inline void getString(StringBuilder buf,PVFieldPtr const & pvField,int indentLevel)
|
||||
inline void getString(std::string *buf,PVFieldPtr const & pvField,int indentLevel)
|
||||
{getString(buf, pvField.get(), indentLevel);}
|
||||
/**
|
||||
* Convert a PVField to a string.
|
||||
@@ -129,7 +130,7 @@ public:
|
||||
* @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(StringBuilder buf,PVFieldPtr const & pvField)
|
||||
inline void getString(std::string * buf,PVFieldPtr const & pvField)
|
||||
{getString(buf, pvField.get(), 0);}
|
||||
/**
|
||||
* Convert a PVField to a string.
|
||||
@@ -138,49 +139,49 @@ public:
|
||||
* If a PVField is a structure or array be prepared for a very long string.
|
||||
* @param indentLevel indentation level
|
||||
*/
|
||||
void getString(StringBuilder buf,PVField const * pvField,int indentLevel);
|
||||
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(StringBuilder buf,PVField const * pvField)
|
||||
inline void getString(std::string * buf,PVField const * pvField)
|
||||
{getString(buf, pvField, 0);}
|
||||
/**
|
||||
* Convert from an array of String to a PVScalar
|
||||
* Convert from an array of std::string to a PVScalar
|
||||
* @param pv The PV.
|
||||
* @param from The array of String value to convert and put into a 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.
|
||||
* @throws std::logic_error if the array of String does not have a valid values.
|
||||
* @throws std::logic_error if the array of std::string does not have a valid values.
|
||||
*/
|
||||
std::size_t fromString(
|
||||
PVStructurePtr const &pv,
|
||||
StringArray const & from,
|
||||
std::size_t fromStartIndex = 0);
|
||||
/**
|
||||
* Convert from a String to a PVScalar
|
||||
* Convert from a std::string to a PVScalar
|
||||
* @param pv The PV.
|
||||
* @param from The String value to convert and put into a PV.
|
||||
* @throws std::logic_error if the String does not have a valid value.
|
||||
* @param from The std::string value to convert and put into a PV.
|
||||
* @throws std::logic_error if the std::string does not have a valid value.
|
||||
*/
|
||||
void fromString(PVScalarPtr const & pv, String const & from)
|
||||
void fromString(PVScalarPtr const & pv, std::string const & from)
|
||||
{
|
||||
pv->putFrom<String>(from);
|
||||
pv->putFrom<std::string>(from);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from a String to a PVScalarArray.
|
||||
* The String must be a comma separated set of values optionally enclosed in []
|
||||
* Convert from a std::string to a PVScalarArray.
|
||||
* The std::string must be a comma separated set of values optionally enclosed in []
|
||||
* @param pv The PV.
|
||||
* @param from The String value to convert and put into a PV.
|
||||
* @param from The std::string value to convert and put into a PV.
|
||||
* @return The number of elements converted.
|
||||
* @throws std::invalid_argument if the element Type is not a scalar.
|
||||
* @throws std::logic_error if the String does not have a valid array values.
|
||||
* @throws std::logic_error if the std::string does not have a valid array values.
|
||||
*/
|
||||
std::size_t fromString(PVScalarArrayPtr const & pv, String from);
|
||||
std::size_t fromString(PVScalarArrayPtr const & pv, std::string from);
|
||||
/**
|
||||
* Convert a PVScalarArray from a String array.
|
||||
* Convert a PVScalarArray from a std::string array.
|
||||
* The array element type must be a scalar.
|
||||
* @param pv The PV.
|
||||
* @param offset Starting element in a PV.
|
||||
@@ -189,7 +190,7 @@ public:
|
||||
* @param fromOffset Starting element in the source array.
|
||||
* @return The number of elements converted.
|
||||
* @throws std::invalid_argument if the element Type is not a scalar.
|
||||
* @throws std::logic_error if the String does not have a valid value.
|
||||
* @throws std::logic_error if the std::string does not have a valid value.
|
||||
*/
|
||||
std::size_t fromStringArray(
|
||||
PVScalarArrayPtr const & pv,
|
||||
@@ -197,11 +198,11 @@ public:
|
||||
StringArray const & from,
|
||||
std::size_t fromOffset);
|
||||
/**
|
||||
* Convert a PVScalarArray to a String array.
|
||||
* Convert a PVScalarArray to a std::string array.
|
||||
* @param pv The PV.
|
||||
* @param offset Starting element in the PV array.
|
||||
* @param length Number of elements to convert to the string array.
|
||||
* @param to String array to receive the converted PV data.
|
||||
* @param to std::string array to receive the converted PV data.
|
||||
* @param toOffset Starting element in the string array.
|
||||
* @return Number of elements converted.
|
||||
*/
|
||||
@@ -401,11 +402,11 @@ public:
|
||||
*/
|
||||
inline double toDouble(PVScalarPtr const & pv) { return pv->getAs<double>();}
|
||||
/**
|
||||
* Convert a PV to a String
|
||||
* Convert a PV to a std::string
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
*/
|
||||
inline String toString(PVScalarPtr const & pv) { return pv->getAs<String>();}
|
||||
inline std::string toString(PVScalarPtr const & pv) { return pv->getAs<std::string>();}
|
||||
/**
|
||||
* Convert a PV from a byte
|
||||
* @param pv a PV
|
||||
@@ -478,12 +479,12 @@ public:
|
||||
inline void fromDouble(PVScalarPtr const & pv, double from) { pv->putFrom<double>(from); }
|
||||
|
||||
/**
|
||||
* Convenience method for implementing toString.
|
||||
* Convenience method for implementing dump.
|
||||
* It generates a newline and inserts blanks at the beginning of the newline.
|
||||
* @param builder The StringBuilder being constructed.
|
||||
* @param builder The std::string * being constructed.
|
||||
* @param indentLevel Indent level, Each level is four spaces.
|
||||
*/
|
||||
void newLine(StringBuilder buf, int indentLevel);
|
||||
void newLine(std::string * buf, int indentLevel);
|
||||
};
|
||||
|
||||
static inline ConvertPtr getConvert() { return Convert::getConvert(); }
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define PRINTER_H
|
||||
|
||||
#include <ostream>
|
||||
#include <shareLib.h>
|
||||
|
||||
#include "pvData.h"
|
||||
|
||||
|
||||
607
src/pv/pvData.h
607
src/pv/pvData.h
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/pvType.h>
|
||||
@@ -22,14 +23,74 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
namespace format {
|
||||
|
||||
struct indent_level
|
||||
{
|
||||
long level;
|
||||
|
||||
indent_level(long l) : level(l) {}
|
||||
};
|
||||
|
||||
epicsShareExtern long& indent_value(std::ios_base& ios);
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& os, indent_level const& indent);
|
||||
|
||||
struct indent_scope
|
||||
{
|
||||
long saved_level;
|
||||
std::ios_base& stream;
|
||||
|
||||
indent_scope(std::ios_base& ios) :
|
||||
stream(ios)
|
||||
{
|
||||
long& l = indent_value(ios);
|
||||
saved_level = l;
|
||||
l = saved_level + 1;
|
||||
}
|
||||
|
||||
~indent_scope()
|
||||
{
|
||||
indent_value(stream) = saved_level;
|
||||
}
|
||||
};
|
||||
|
||||
struct indent
|
||||
{
|
||||
};
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& os, indent const&);
|
||||
|
||||
struct array_at
|
||||
{
|
||||
std::size_t index;
|
||||
|
||||
array_at(std::size_t ix) : index(ix) {}
|
||||
};
|
||||
|
||||
struct array_at_internal
|
||||
{
|
||||
std::size_t index;
|
||||
std::ostream& stream;
|
||||
|
||||
array_at_internal(std::size_t ix, std::ostream& str) : index(ix), stream(str) {}
|
||||
};
|
||||
|
||||
epicsShareExtern array_at_internal operator<<(std::ostream& str, array_at const& manip);
|
||||
|
||||
};
|
||||
|
||||
class Field;
|
||||
class Scalar;
|
||||
class Array;
|
||||
class ScalarArray;
|
||||
class Structure;
|
||||
class StructureArray;
|
||||
class Union;
|
||||
class UnionArray;
|
||||
|
||||
class BoundedString;
|
||||
|
||||
/**
|
||||
* typedef for a shared pointer to an immutable Field.
|
||||
*/
|
||||
@@ -42,6 +103,10 @@ typedef std::vector<FieldConstPtr> FieldConstPtrArray;
|
||||
* typedef for a shared pointer to an immutable Scalar.
|
||||
*/
|
||||
typedef std::tr1::shared_ptr<const Scalar> ScalarConstPtr;
|
||||
/**
|
||||
* typedef for a shared pointer to an immutable Array.
|
||||
*/
|
||||
typedef std::tr1::shared_ptr<const Array> ArrayConstPtr;
|
||||
/**
|
||||
* typedef for a shared pointer to an immutable ScalarArray.
|
||||
*/
|
||||
@@ -62,6 +127,10 @@ typedef std::tr1::shared_ptr<const Union> UnionConstPtr;
|
||||
* typedef for a shared pointer to an immutable UnionArray.
|
||||
*/
|
||||
typedef std::tr1::shared_ptr<const UnionArray> UnionArrayConstPtr;
|
||||
/**
|
||||
* typedef for a shared pointer to an immutable BoundedString.
|
||||
*/
|
||||
typedef std::tr1::shared_ptr<const BoundedString> BoundedStringConstPtr;
|
||||
|
||||
/**
|
||||
* Definition of support field types.
|
||||
@@ -103,14 +172,11 @@ namespace TypeFunc {
|
||||
* @return The name for the type.
|
||||
*/
|
||||
epicsShareExtern const char* name(Type type);
|
||||
/**
|
||||
* Convert the type to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
* @param type The type.
|
||||
*/
|
||||
epicsShareExtern void toString(StringBuilder builder,const Type type);
|
||||
};
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, const Type& type);
|
||||
|
||||
|
||||
/**
|
||||
* Definition of support scalar types.
|
||||
*/
|
||||
@@ -201,24 +267,21 @@ namespace ScalarTypeFunc {
|
||||
* @return The scalarType.
|
||||
* An exception is thrown if the name is not the name of a scalar type.
|
||||
*/
|
||||
epicsShareExtern ScalarType getScalarType(String const &value);
|
||||
epicsShareExtern ScalarType getScalarType(std::string const &value);
|
||||
/**
|
||||
* Get a name for the scalarType.
|
||||
* @param scalarType The type.
|
||||
* @return The name for the scalarType.
|
||||
*/
|
||||
epicsShareExtern const char* name(ScalarType scalarType);
|
||||
/**
|
||||
* Convert the scalarType to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
* @param scalarType The type.
|
||||
*/
|
||||
epicsShareExtern void toString(StringBuilder builder,ScalarType scalarType);
|
||||
|
||||
//! gives sizeof(T) where T depends on the scalar type id.
|
||||
epicsShareExtern size_t elementSize(ScalarType id);
|
||||
};
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, const ScalarType& scalarType);
|
||||
|
||||
|
||||
/**
|
||||
* This class implements introspection object for field.
|
||||
*/
|
||||
@@ -240,18 +303,15 @@ public:
|
||||
* Get the identification string.
|
||||
* @return The identification string, can be empty.
|
||||
*/
|
||||
virtual String getID() const = 0;
|
||||
virtual std::string getID() const = 0;
|
||||
|
||||
/**
|
||||
* Convert the scalarType to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
* Puts the string representation to the stream.
|
||||
* @param o output stream.
|
||||
* @return The output stream.
|
||||
*/
|
||||
virtual void toString(StringBuilder builder) const{toString(builder,0);}
|
||||
/**
|
||||
* Convert the scalarType to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder builder,int indentLevel) const;
|
||||
virtual std::ostream& dump(std::ostream& o) const = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Constructor
|
||||
@@ -271,6 +331,8 @@ private:
|
||||
struct Deleter{void operator()(Field *p){delete p;}};
|
||||
};
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, const Field& field);
|
||||
|
||||
|
||||
/**
|
||||
* This class implements introspection object for Scalar.
|
||||
@@ -289,19 +351,10 @@ public:
|
||||
* @return the scalarType
|
||||
*/
|
||||
ScalarType getScalarType() const {return scalarType;}
|
||||
/**
|
||||
* Convert the scalar to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf) const{toString(buf,0);}
|
||||
/**
|
||||
* Convert the scalar to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
|
||||
virtual std::string getID() const;
|
||||
|
||||
virtual String getID() const;
|
||||
virtual std::ostream& dump(std::ostream& o) const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
@@ -309,15 +362,87 @@ public:
|
||||
protected:
|
||||
Scalar(ScalarType scalarType);
|
||||
private:
|
||||
int8 getTypeCodeLUT() const;
|
||||
static int8 getTypeCodeLUT(ScalarType scalarType);
|
||||
ScalarType scalarType;
|
||||
friend class FieldCreate;
|
||||
friend class ScalarArray;
|
||||
friend class BoundedScalarArray;
|
||||
friend class FixedScalarArray;
|
||||
friend class BoundedString;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements introspection object for BoundedString.
|
||||
*/
|
||||
class epicsShareClass BoundedString : public Scalar{
|
||||
public:
|
||||
POINTER_DEFINITIONS(BoundedString);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~BoundedString();
|
||||
typedef BoundedString& reference;
|
||||
typedef const BoundedString& const_reference;
|
||||
|
||||
virtual std::string getID() const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
|
||||
std::size_t getMaximumLength() const;
|
||||
|
||||
protected:
|
||||
BoundedString(std::size_t maxStringLength);
|
||||
private:
|
||||
std::size_t maxLength;
|
||||
friend class FieldCreate;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements introspection object for field.
|
||||
* This class implements introspection object for Array.
|
||||
*/
|
||||
class epicsShareClass ScalarArray : public Field{
|
||||
class epicsShareClass Array : public Field{
|
||||
public:
|
||||
POINTER_DEFINITIONS(Array);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~Array();
|
||||
typedef Array& reference;
|
||||
typedef const Array& const_reference;
|
||||
|
||||
enum ArraySizeType { variable, fixed, bounded };
|
||||
|
||||
/**
|
||||
* Get array size type (i.e. variable/fixed/bounded size array).
|
||||
* @return array size type enum.
|
||||
*/
|
||||
virtual ArraySizeType getArraySizeType() const = 0;
|
||||
|
||||
/**
|
||||
* Get maximum capacity of the array.
|
||||
* @return maximum capacity of the array, 0 indicates variable size array.
|
||||
*/
|
||||
virtual std::size_t getMaximumCapacity() const = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Constructor
|
||||
* @param fieldName The field type.
|
||||
*/
|
||||
Array(Type type);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class implements introspection object for scalar array.
|
||||
*/
|
||||
class epicsShareClass ScalarArray : public Array{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ScalarArray);
|
||||
typedef ScalarArray& reference;
|
||||
@@ -332,20 +457,15 @@ public:
|
||||
* Get the scalarType for the elements.
|
||||
* @return the scalarType
|
||||
*/
|
||||
ScalarType getElementType() const {return elementType;}
|
||||
/**
|
||||
* Convert the scalarType to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf) const{toString(buf,0);}
|
||||
/**
|
||||
* Convert the scalarType to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
ScalarType getElementType() const {return elementType;}
|
||||
|
||||
virtual String getID() const;
|
||||
virtual ArraySizeType getArraySizeType() const {return Array::variable;}
|
||||
|
||||
virtual std::size_t getMaximumCapacity() const {return 0;}
|
||||
|
||||
virtual std::string getID() const;
|
||||
|
||||
virtual std::ostream& dump(std::ostream& o) const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
@@ -356,16 +476,89 @@ protected:
|
||||
*/
|
||||
virtual ~ScalarArray();
|
||||
private:
|
||||
int8 getTypeCodeLUT() const;
|
||||
const String getIDScalarArrayLUT() const;
|
||||
const std::string getIDScalarArrayLUT() const;
|
||||
ScalarType elementType;
|
||||
friend class FieldCreate;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class implements introspection object for bounded scalar array.
|
||||
*/
|
||||
class epicsShareClass BoundedScalarArray : public ScalarArray{
|
||||
public:
|
||||
POINTER_DEFINITIONS(BoundedScalarArray);
|
||||
typedef BoundedScalarArray& reference;
|
||||
typedef const BoundedScalarArray& const_reference;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param scalarType The scalarType for the field.
|
||||
* @param size maximum (bound) capacity.
|
||||
*/
|
||||
BoundedScalarArray(ScalarType scalarType, std::size_t size);
|
||||
|
||||
virtual ArraySizeType getArraySizeType() const {return Array::bounded;}
|
||||
|
||||
virtual std::size_t getMaximumCapacity() const {return size;}
|
||||
|
||||
virtual std::string getID() const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~BoundedScalarArray();
|
||||
private:
|
||||
std::size_t size;
|
||||
friend class FieldCreate;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements introspection object for bounded scalar array.
|
||||
*/
|
||||
class epicsShareClass FixedScalarArray : public ScalarArray{
|
||||
public:
|
||||
POINTER_DEFINITIONS(FixedScalarArray);
|
||||
typedef FixedScalarArray& reference;
|
||||
typedef const FixedScalarArray& const_reference;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param scalarType The scalarType for the field.
|
||||
* @param size maximum (bound) capacity.
|
||||
*/
|
||||
FixedScalarArray(ScalarType scalarType, std::size_t size);
|
||||
|
||||
virtual ArraySizeType getArraySizeType() const {return Array::fixed;}
|
||||
|
||||
virtual std::size_t getMaximumCapacity() const {return size;}
|
||||
|
||||
virtual std::string getID() const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~FixedScalarArray();
|
||||
private:
|
||||
std::size_t size;
|
||||
friend class FieldCreate;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class implements introspection object for a structureArray
|
||||
*/
|
||||
class epicsShareClass StructureArray : public Field{
|
||||
class epicsShareClass StructureArray : public Array{
|
||||
public:
|
||||
POINTER_DEFINITIONS(StructureArray);
|
||||
typedef StructureArray& reference;
|
||||
@@ -375,16 +568,15 @@ public:
|
||||
* Get the introspection interface for the array elements.
|
||||
* @return The introspection interface.
|
||||
*/
|
||||
StructureConstPtr getStructure() const {return pstructure;}
|
||||
StructureConstPtr getStructure() const {return pstructure;}
|
||||
|
||||
/**
|
||||
* Convert the scalarType to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel=0) const;
|
||||
|
||||
virtual String getID() const;
|
||||
virtual ArraySizeType getArraySizeType() const {return Array::variable;}
|
||||
|
||||
virtual std::size_t getMaximumCapacity() const {return 0;}
|
||||
|
||||
virtual std::string getID() const;
|
||||
|
||||
virtual std::ostream& dump(std::ostream& o) const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
@@ -407,7 +599,7 @@ private:
|
||||
/**
|
||||
* This class implements introspection object for a unionArray
|
||||
*/
|
||||
class epicsShareClass UnionArray : public Field{
|
||||
class epicsShareClass UnionArray : public Array{
|
||||
public:
|
||||
POINTER_DEFINITIONS(UnionArray);
|
||||
typedef UnionArray& reference;
|
||||
@@ -417,16 +609,15 @@ public:
|
||||
* Get the introspection interface for the array elements.
|
||||
* @return The introspection interface.
|
||||
*/
|
||||
UnionConstPtr getUnion() const {return punion;}
|
||||
UnionConstPtr getUnion() const {return punion;}
|
||||
|
||||
/**
|
||||
* Convert the scalarType to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel=0) const;
|
||||
|
||||
virtual String getID() const;
|
||||
virtual ArraySizeType getArraySizeType() const {return Array::variable;}
|
||||
|
||||
virtual std::size_t getMaximumCapacity() const {return 0;}
|
||||
|
||||
virtual std::string getID() const;
|
||||
|
||||
virtual std::ostream& dump(std::ostream& o) const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
@@ -456,7 +647,7 @@ public:
|
||||
/**
|
||||
* Default structure ID.
|
||||
*/
|
||||
static epics::pvData::String DEFAULT_ID;
|
||||
static std::string DEFAULT_ID;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@@ -476,7 +667,7 @@ public:
|
||||
* @return The introspection interface.
|
||||
* This will hold a null pointer if the field is not in the structure.
|
||||
*/
|
||||
FieldConstPtr getField(String const &fieldName) const;
|
||||
FieldConstPtr getField(std::string const &fieldName) const;
|
||||
/**
|
||||
* Get the field for the specified fieldName.
|
||||
* @param fieldName The index of the field to get;
|
||||
@@ -489,7 +680,7 @@ public:
|
||||
* @return The introspection interface.
|
||||
* This will be -1 if the field is not in the structure.
|
||||
*/
|
||||
std::size_t getFieldIndex(String const &fieldName) const;
|
||||
std::size_t getFieldIndex(std::string const &fieldName) const;
|
||||
/**
|
||||
* Get the fields in the structure.
|
||||
* @return The array of fields.
|
||||
@@ -500,40 +691,31 @@ public:
|
||||
* @return The array of fieldNames.
|
||||
*/
|
||||
StringArray const & getFieldNames() const {return fieldNames;}
|
||||
void renameField(std::size_t fieldIndex,String const & newName)
|
||||
{fieldNames[fieldIndex] = newName;}
|
||||
/**
|
||||
* Get the name of the field with the specified index;
|
||||
* @param fieldIndex The index of the desired field.
|
||||
* @return The fieldName.
|
||||
*/
|
||||
String getFieldName(std::size_t fieldIndex) const {return fieldNames[fieldIndex];}
|
||||
/**
|
||||
* Convert the structure to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf) const{toString(buf,0);}
|
||||
/**
|
||||
* Convert the structure to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
|
||||
virtual String getID() const;
|
||||
std::string getFieldName(std::size_t fieldIndex) const {return fieldNames[fieldIndex];}
|
||||
|
||||
virtual std::string getID() const;
|
||||
|
||||
virtual std::ostream& dump(std::ostream& o) const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
|
||||
protected:
|
||||
Structure(StringArray const & fieldNames, FieldConstPtrArray const & fields, String const & id = DEFAULT_ID);
|
||||
Structure(StringArray const & fieldNames, FieldConstPtrArray const & fields, std::string const & id = DEFAULT_ID);
|
||||
private:
|
||||
void toStringCommon(StringBuilder buf,int indentLevel) const;
|
||||
StringArray fieldNames;
|
||||
FieldConstPtrArray fields;
|
||||
String id;
|
||||
friend class FieldCreate;
|
||||
friend class Union;
|
||||
std::string id;
|
||||
|
||||
virtual void dumpFields(std::ostream& o) const;
|
||||
|
||||
friend class FieldCreate;
|
||||
friend class Union;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -546,12 +728,12 @@ public:
|
||||
/**
|
||||
* Default union ID.
|
||||
*/
|
||||
static epics::pvData::String DEFAULT_ID;
|
||||
static std::string DEFAULT_ID;
|
||||
|
||||
/**
|
||||
* Default variant union ID.
|
||||
*/
|
||||
static epics::pvData::String ANY_ID;
|
||||
static std::string ANY_ID;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@@ -571,7 +753,7 @@ public:
|
||||
* @return The introspection interface.
|
||||
* This will hold a null pointer if the field is not in the union.
|
||||
*/
|
||||
FieldConstPtr getField(String const &fieldName) const;
|
||||
FieldConstPtr getField(std::string const &fieldName) const;
|
||||
/**
|
||||
* Get the field for the specified fieldName.
|
||||
* @param fieldName The index of the field to get;
|
||||
@@ -584,7 +766,7 @@ public:
|
||||
* @return The introspection interface.
|
||||
* This will be -1 if the field is not in the union.
|
||||
*/
|
||||
std::size_t getFieldIndex(String const &fieldName) const;
|
||||
std::size_t getFieldIndex(std::string const &fieldName) const;
|
||||
/**
|
||||
* Get the fields in the union.
|
||||
* @return The array of fields.
|
||||
@@ -595,51 +777,39 @@ public:
|
||||
* @return The array of fieldNames.
|
||||
*/
|
||||
StringArray const & getFieldNames() const {return fieldNames;}
|
||||
void renameField(std::size_t fieldIndex,String const & newName)
|
||||
{fieldNames[fieldIndex] = newName;}
|
||||
/**
|
||||
* Get the name of the field with the specified index;
|
||||
* @param fieldIndex The index of the desired field.
|
||||
* @return The fieldName.
|
||||
*/
|
||||
String getFieldName(std::size_t fieldIndex) const {return fieldNames[fieldIndex];}
|
||||
std::string getFieldName(std::size_t fieldIndex) const {return fieldNames[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>.
|
||||
*/
|
||||
bool isVariant() const {return (fieldNames.size() == 0);}
|
||||
/**
|
||||
* Convert the union to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf) const{toString(buf,0);}
|
||||
/**
|
||||
* Convert the union to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
|
||||
virtual String getID() const;
|
||||
|
||||
virtual std::string getID() const;
|
||||
|
||||
virtual std::ostream& dump(std::ostream& o) const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
|
||||
protected:
|
||||
Union();
|
||||
Union(StringArray const & fieldNames, FieldConstPtrArray const & fields, String const & id = DEFAULT_ID);
|
||||
Union(StringArray const & fieldNames, FieldConstPtrArray const & fields, std::string const & id = DEFAULT_ID);
|
||||
private:
|
||||
void toStringCommon(StringBuilder buf,int indentLevel) const;
|
||||
StringArray fieldNames;
|
||||
FieldConstPtrArray fields;
|
||||
String id;
|
||||
StringArray fieldNames;
|
||||
FieldConstPtrArray fields;
|
||||
std::string id;
|
||||
|
||||
virtual void dumpFields(std::ostream& o) const;
|
||||
|
||||
friend class FieldCreate;
|
||||
friend class Structure;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a singlton class for creating introspection interfaces.
|
||||
*/
|
||||
class FieldCreate;
|
||||
typedef std::tr1::shared_ptr<FieldCreate> FieldCreatePtr;
|
||||
|
||||
@@ -671,6 +841,14 @@ public:
|
||||
*/
|
||||
FieldBuilderPtr add(std::string const & name, ScalarType scalarType);
|
||||
|
||||
/**
|
||||
* Add a {@code BoundedString}.
|
||||
* @param name name of the array.
|
||||
* @param maxLength a string maximum length.
|
||||
* @return this instance of a {@code FieldBuilder}.
|
||||
*/
|
||||
FieldBuilderPtr addBoundedString(std::string const & name, std::size_t maxLength);
|
||||
|
||||
/**
|
||||
* Add a {@code Field} (e.g. {@code Structure}, {@code Union}).
|
||||
* @param name name of the array.
|
||||
@@ -680,13 +858,31 @@ public:
|
||||
FieldBuilderPtr add(std::string const & name, FieldConstPtr const & field);
|
||||
|
||||
/**
|
||||
* Add array of {@code Scalar} elements.
|
||||
* Add variable size array of {@code Scalar} elements.
|
||||
* @param name name of the array.
|
||||
* @param scalarType type of a scalar element.
|
||||
* @return this instance of a {@code FieldBuilder}.
|
||||
*/
|
||||
FieldBuilderPtr addArray(std::string const & name, ScalarType scalarType);
|
||||
|
||||
/**
|
||||
* Add fixed-size array of {@code 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}.
|
||||
*/
|
||||
FieldBuilderPtr addFixedArray(std::string const & name, ScalarType scalarType, std::size_t size);
|
||||
|
||||
/**
|
||||
* Add bounded-size array of {@code 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}.
|
||||
*/
|
||||
FieldBuilderPtr addBoundedArray(std::string const & name, ScalarType scalarType, std::size_t bound);
|
||||
|
||||
/**
|
||||
* Add array of {@code Field} elements.
|
||||
* @param name name of the array.
|
||||
@@ -751,8 +947,8 @@ public:
|
||||
|
||||
/**
|
||||
* Complete the creation of a nested object.
|
||||
* @see #addNestedStructure(String)
|
||||
* @see #addNestedUnion(String)
|
||||
* @see #addNestedStructure(std::string)
|
||||
* @see #addNestedUnion(std::string)
|
||||
* @return a previous (parent) {@code FieldBuilder}.
|
||||
*/
|
||||
FieldBuilderPtr endNested();
|
||||
@@ -784,6 +980,9 @@ private:
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a singleton class for creating introspection interfaces.
|
||||
*/
|
||||
class epicsShareClass FieldCreate {
|
||||
public:
|
||||
static FieldCreatePtr getFieldCreate();
|
||||
@@ -800,11 +999,32 @@ public:
|
||||
*/
|
||||
ScalarConstPtr createScalar(ScalarType scalarType) const;
|
||||
/**
|
||||
* Create an {@code Array} field.
|
||||
* Create a {@code BoundedString}.
|
||||
* @param maxLength a string maximum length.
|
||||
* @return a {@code BoundedString} interface for the newly created object.
|
||||
* @throws An {@code 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.
|
||||
*/
|
||||
ScalarArrayConstPtr createScalarArray(ScalarType elementType) const;
|
||||
/*
|
||||
* Create an {@code Array} field, fixed size array.
|
||||
* @param elementType The {@code scalarType} for array elements
|
||||
* @param size Fixed array size.
|
||||
* @return An {@code 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.
|
||||
*/
|
||||
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
|
||||
@@ -812,6 +1032,11 @@ public:
|
||||
* @return An {@code 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.
|
||||
*/
|
||||
StructureConstPtr createStructure () const;
|
||||
/**
|
||||
* Create a {@code Structure} field.
|
||||
* @param fieldNames The array of {@code fieldNames} for the structure.
|
||||
@@ -829,7 +1054,7 @@ public:
|
||||
* @return a {@code Structure} interface for the newly created object.
|
||||
*/
|
||||
StructureConstPtr createStructure (
|
||||
String const & id,
|
||||
std::string const & id,
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
/**
|
||||
@@ -866,7 +1091,7 @@ public:
|
||||
* @return a {@code Union} interface for the newly created object.
|
||||
*/
|
||||
UnionConstPtr createUnion (
|
||||
String const & id,
|
||||
std::string const & id,
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
/**
|
||||
@@ -878,7 +1103,7 @@ public:
|
||||
*/
|
||||
StructureConstPtr appendField(
|
||||
StructureConstPtr const & structure,
|
||||
String const & fieldName, FieldConstPtr const & field) const;
|
||||
std::string const & fieldName, FieldConstPtr const & field) const;
|
||||
/**
|
||||
* Append fields to a structure.
|
||||
* @param structure The structure to which the fields appended.
|
||||
@@ -924,7 +1149,7 @@ epicsShareExtern FieldCreatePtr getFieldCreate();
|
||||
* value (eg -1).
|
||||
*/
|
||||
template<typename T>
|
||||
struct ScalarTypeID { enum {value=-1}; };
|
||||
struct ScalarTypeID {};
|
||||
|
||||
/**
|
||||
* Static mapping from ScalarType enum to value type.
|
||||
@@ -951,8 +1176,27 @@ OP(pvUInt, uint32)
|
||||
OP(pvULong, uint64)
|
||||
OP(pvFloat, float)
|
||||
OP(pvDouble, double)
|
||||
OP(pvString, String)
|
||||
OP(pvString, std::string)
|
||||
#undef OP
|
||||
|
||||
struct ScalarHashFunction {
|
||||
size_t operator() (const Scalar& scalar) const { return scalar.getScalarType(); }
|
||||
};
|
||||
|
||||
struct ScalarArrayHashFunction {
|
||||
size_t operator() (const ScalarArray& scalarArray) const { return 0x10 | scalarArray.getElementType(); }
|
||||
};
|
||||
|
||||
struct StructureHashFunction {
|
||||
size_t operator() (const Structure& /*structure*/) const { return 0; }
|
||||
// TODO hash
|
||||
// final int PRIME = 31;
|
||||
// return PRIME * Arrays.hashCode(fieldNames) + Arrays.hashCode(fields);
|
||||
};
|
||||
|
||||
struct StructureArrayHashFunction {
|
||||
size_t operator() (const StructureArray& structureArray) const { StructureHashFunction shf; return (0x10 | shf(*(structureArray.getStructure()))); }
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* PVINTROSPECT_H */
|
||||
|
||||
@@ -17,68 +17,104 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/** @brief Copy a subarray from one PVValueArray to another.
|
||||
* @warning The two PVValueArrays must both the same type
|
||||
* @param from The source
|
||||
* @param fromOffset The offset in the source
|
||||
* @param to The destination
|
||||
* @param toOffset The offset in the destination
|
||||
* @param len The total number of elements to copy
|
||||
/** @brief Copy a subarray from one scalar array to another.
|
||||
* @warning The two scalar arrays must both be PVValueArrays of the same type.
|
||||
* @param pvFrom The source array.
|
||||
* @param fromOffset The offset in the source.
|
||||
* @param fromStride The interval between elements in pvFrom.
|
||||
* @param pvTo The destination array.
|
||||
* @param toOffset The offset in the destination.
|
||||
* @param toStride The interval between elements in pvTo.
|
||||
* @param count The total number of elements to copy from pvFrom to pvTo.
|
||||
*/
|
||||
template<typename T>
|
||||
void copy(
|
||||
epicsShareExtern void copy(
|
||||
PVValueArray<T> & pvFrom,
|
||||
size_t fromOffset,
|
||||
size_t fromStride,
|
||||
PVValueArray<T> & pvTo,
|
||||
size_t toOffset,
|
||||
size_t len);
|
||||
size_t toStride,
|
||||
size_t count);
|
||||
|
||||
/** @brief Copy a subarray from one scalar array to another.
|
||||
* @warning The two scalar arrays must both be PVValueArrays of the same type
|
||||
* @param from The source
|
||||
* @param fromOffset The offset in the source
|
||||
* @param to The destination
|
||||
* @param toOffset The offset in the destination
|
||||
* @param len The total number of elements to copy
|
||||
* @warning The two scalar arrays must both be PVValueArrays of the same type.
|
||||
* @param pvFrom The source array.
|
||||
* @param fromOffset The offset in the source.
|
||||
* @param fromStride The interval between elements in pvFrom.
|
||||
* @param pvTo The destination array.
|
||||
* @param toOffset The offset in the destination.
|
||||
* @param toStride The interval between elements in pvTo.
|
||||
* @param count The total number of elements to copy from pvFrom to pvTo.
|
||||
*/
|
||||
epicsShareExtern void copy(
|
||||
PVScalarArray & from,
|
||||
PVScalarArray & pvFrom,
|
||||
size_t fromOffset,
|
||||
PVScalarArray & to,
|
||||
size_t fromStride,
|
||||
PVScalarArray & pvTo,
|
||||
size_t toOffset,
|
||||
size_t len);
|
||||
size_t toStride,
|
||||
size_t count);
|
||||
|
||||
/** @brief Copy a subarray from one structure array to another.
|
||||
* @warning The two structure arrays must have the same
|
||||
* structure introspection interface.
|
||||
* @param from The source
|
||||
* @param fromOffset The offset in the source
|
||||
* @param to The destination
|
||||
* @param toOffset The offset in the destination
|
||||
* @param len The total number of elements to copy
|
||||
* @param pvFrom The source array.
|
||||
* @param fromOffset The offset in the source.
|
||||
* @param fromStride The interval between elements in pvFrom.
|
||||
* @param pvTo The destination array.
|
||||
* @param toOffset The offset in the destination.
|
||||
* @param toStride The interval between elements in pvTo.
|
||||
* @param count The total number of elements to copy from pvFrom to pvTo.
|
||||
*/
|
||||
epicsShareExtern void copy(
|
||||
PVStructureArray & from,
|
||||
PVStructureArray & pvFrom,
|
||||
size_t fromOffset,
|
||||
PVStructureArray & to,
|
||||
size_t fromStride,
|
||||
PVStructureArray & pvToo,
|
||||
size_t toOffset,
|
||||
size_t len);
|
||||
size_t toStride,
|
||||
size_t count);
|
||||
|
||||
/** @brief Copy a subarray from one array to another.
|
||||
* @warning The two arrays must have the same
|
||||
* introspection interface.
|
||||
* @param from The source
|
||||
* @param fromOffset The offset in the source
|
||||
* @param to The destination
|
||||
* @param toOffset The offset in the destination
|
||||
* @param len The total number of elements to copy
|
||||
* @param pvFrom The source array.
|
||||
* @param fromOffset The offset in the source.
|
||||
* @param fromStride The interval between elements in pvFrom.
|
||||
* @param pvTo The destination array.
|
||||
* @param toOffset The offset in the destination.
|
||||
* @param toStride The interval between elements in pvTo.
|
||||
* @param count The total number of elements to copy from pvFrom to pvTo.
|
||||
*/
|
||||
epicsShareExtern void copy(
|
||||
PVArray & from,
|
||||
PVArray & pvFrom,
|
||||
size_t fromOffset,
|
||||
PVArray & to,
|
||||
size_t fromStride,
|
||||
PVArray & pvToo,
|
||||
size_t toOffset,
|
||||
size_t len);
|
||||
size_t toStride,
|
||||
size_t count);
|
||||
|
||||
/** @brief Copy a subarray from one array to another.
|
||||
* @warning The two arrays must have the same
|
||||
* introspection interface.
|
||||
* @param pvFrom The source array.
|
||||
* @param fromOffset The offset in the source.
|
||||
* @param fromStride The interval between elements in pvFrom.
|
||||
* @param pvTo The destination array.
|
||||
* @param toOffset The offset in the destination.
|
||||
* @param toStride The interval between elements in pvTo.
|
||||
* @param count The total number of elements to copy from pvFrom to pvTo.
|
||||
*/
|
||||
epicsShareExtern void copy(
|
||||
PVArray::shared_pointer const & pvFrom,
|
||||
size_t fromOffset,
|
||||
size_t fromStride,
|
||||
PVArray::shared_pointer & pvToo,
|
||||
size_t toOffset,
|
||||
size_t toStride,
|
||||
size_t count);
|
||||
|
||||
}}
|
||||
|
||||
|
||||
357
src/pv/pvType.h
357
src/pv/pvType.h
@@ -29,7 +29,7 @@ typedef int intptr_t;
|
||||
typedef unsigned int uintptr_t;
|
||||
#ifndef INT64_MAX
|
||||
#define INT64_MAX (0x7fffffffffffffffLL)
|
||||
#define UINT64_MAX (0xffffffffffffffffLL)
|
||||
#define UINT64_MAX (0xffffffffffffffffULL)
|
||||
#endif
|
||||
#else
|
||||
#include <stdint.h>
|
||||
@@ -93,358 +93,24 @@ typedef uint64_t uint64;
|
||||
|
||||
// float and double are types
|
||||
|
||||
/**
|
||||
* A string
|
||||
*/
|
||||
typedef std::string String;
|
||||
|
||||
/**
|
||||
* A boolean array.
|
||||
*/
|
||||
typedef std::vector<uint8> BooleanArray;
|
||||
typedef std::tr1::shared_ptr<BooleanArray> BooleanArrayPtr;
|
||||
/* get is same is ubyte*/
|
||||
typedef std::vector<uint8>::iterator BooleanArray_iterator;
|
||||
typedef std::vector<uint8>::const_iterator BooleanArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A byte array.
|
||||
*/
|
||||
typedef std::vector<int8> ByteArray;
|
||||
typedef std::tr1::shared_ptr<ByteArray> ByteArrayPtr;
|
||||
inline int8 * get(ByteArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline int8 const * get(ByteArray const &value)
|
||||
{
|
||||
return static_cast<int8 const *>(&value[0]);
|
||||
}
|
||||
inline int8 * get(ByteArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline int8 const * get(ByteArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline ByteArray & getVector(ByteArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline ByteArray const & getVector(ByteArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<int8>::iterator ByteArray_iterator;
|
||||
typedef std::vector<int8>::const_iterator ByteArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A short array.
|
||||
*/
|
||||
typedef std::vector<int16> ShortArray;
|
||||
typedef std::tr1::shared_ptr<ShortArray> ShortArrayPtr;
|
||||
inline int16 * get(ShortArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline int16 const * get(ShortArray const &value)
|
||||
{
|
||||
return static_cast<int16 const *>(&value[0]);
|
||||
}
|
||||
inline int16 * get(ShortArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline int16 const * get(ShortArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline ShortArray & getVector(ShortArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline ShortArray const & getVector(ShortArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<int16>::iterator ShortArray_iterator;
|
||||
typedef std::vector<int16>::const_iterator ShortArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A int array.
|
||||
*/
|
||||
typedef std::vector<int32> IntArray;
|
||||
typedef std::tr1::shared_ptr<IntArray> IntArrayPtr;
|
||||
inline int32 * get(IntArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline int32 const * get(IntArray const &value)
|
||||
{
|
||||
return static_cast<int32 const *>(&value[0]);
|
||||
}
|
||||
inline int32 * get(IntArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline int32 const * get(IntArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline IntArray & getVector(IntArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline IntArray const & getVector(IntArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<int32>::iterator IntArray_iterator;
|
||||
typedef std::vector<int32>::const_iterator IntArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A long array.
|
||||
*/
|
||||
typedef std::vector<int64> LongArray;
|
||||
typedef std::tr1::shared_ptr<LongArray> LongArrayPtr;
|
||||
inline int64 * get(LongArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline int64 const * get(LongArray const &value)
|
||||
{
|
||||
return static_cast<int64 const *>(&value[0]);
|
||||
}
|
||||
inline int64 * get(LongArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline int64 const * get(LongArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline LongArray & getVector(LongArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline LongArray const & getVector(LongArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<int64>::iterator LongArray_iterator;
|
||||
typedef std::vector<int64>::const_iterator LongArray_const_iterator;
|
||||
|
||||
/**
|
||||
* An unsigned byte array.
|
||||
*/
|
||||
typedef std::vector<uint8> UByteArray;
|
||||
typedef std::tr1::shared_ptr<UByteArray> UByteArrayPtr;
|
||||
inline uint8 * get(UByteArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline uint8 const * get(UByteArray const &value)
|
||||
{
|
||||
return static_cast<uint8 const *>(&value[0]);
|
||||
}
|
||||
inline uint8 * get(UByteArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline uint8 const * get(UByteArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline UByteArray & getVector(UByteArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline UByteArray const & getVector(UByteArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<uint8>::iterator UByteArray_iterator;
|
||||
typedef std::vector<uint8>::const_iterator UByteArray_const_iterator;
|
||||
|
||||
/**
|
||||
* An unsigned short array.
|
||||
*/
|
||||
typedef std::vector<uint16> UShortArray;
|
||||
typedef std::tr1::shared_ptr<UShortArray> UShortArrayPtr;
|
||||
inline uint16 * get(UShortArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline uint16 const * get(UShortArray const &value)
|
||||
{
|
||||
return static_cast<uint16 const *>(&value[0]);
|
||||
}
|
||||
inline uint16 * get(UShortArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline uint16 const * get(UShortArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline UShortArray & getVector(UShortArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline UShortArray const & getVector(UShortArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<uint16>::iterator UShortArray_iterator;
|
||||
typedef std::vector<uint16>::const_iterator UShortArray_const_iterator;
|
||||
|
||||
/**
|
||||
* An unsigned int array.
|
||||
*/
|
||||
typedef std::vector<uint32> UIntArray;
|
||||
typedef std::tr1::shared_ptr<UIntArray> UIntArrayPtr;
|
||||
inline uint32 * get(UIntArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline uint32 const * get(UIntArray const &value)
|
||||
{
|
||||
return static_cast<uint32 const *>(&value[0]);
|
||||
}
|
||||
inline uint32 * get(UIntArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline uint32 const * get(UIntArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline UIntArray & getVector(UIntArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline UIntArray const & getVector(UIntArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<uint32>::iterator UIntArray_iterator;
|
||||
typedef std::vector<uint32>::const_iterator UIntArray_const_iterator;
|
||||
|
||||
/**
|
||||
* An unsigned long array.
|
||||
*/
|
||||
typedef std::vector<uint64> ULongArray;
|
||||
typedef std::tr1::shared_ptr<ULongArray> ULongArrayPtr;
|
||||
inline uint64 * get(ULongArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline uint64 const * get(ULongArray const &value)
|
||||
{
|
||||
return static_cast<uint64 const *>(&value[0]);
|
||||
}
|
||||
inline uint64 * get(ULongArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline uint64 const * get(ULongArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline ULongArray & getVector(ULongArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline ULongArray const & getVector(ULongArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<uint64>::iterator ULongArray_iterator;
|
||||
typedef std::vector<uint64>::const_iterator ULongArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A float array.
|
||||
*/
|
||||
typedef std::vector<float> FloatArray;
|
||||
typedef std::tr1::shared_ptr<FloatArray> FloatArrayPtr;
|
||||
inline float * get(FloatArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline float const * get(FloatArray const &value)
|
||||
{
|
||||
return static_cast<float const *>(&value[0]);
|
||||
}
|
||||
inline float * get(FloatArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline float const * get(FloatArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline FloatArray & getVector(FloatArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline FloatArray const & getVector(FloatArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<float>::iterator FloatArray_iterator;
|
||||
typedef std::vector<float>::const_iterator FloatArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A double array.
|
||||
*/
|
||||
typedef std::vector<double> DoubleArray;
|
||||
typedef std::tr1::shared_ptr<DoubleArray> DoubleArrayPtr;
|
||||
inline double * get(DoubleArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline double const * get(DoubleArray const &value)
|
||||
{
|
||||
return static_cast<double const *>(&value[0]);
|
||||
}
|
||||
inline double * get(DoubleArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline double const * get(DoubleArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline DoubleArray & getVector(DoubleArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline DoubleArray const & getVector(DoubleArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<double>::iterator DoubleArray_iterator;
|
||||
typedef std::vector<double>::const_iterator DoubleArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A string array.
|
||||
*/
|
||||
typedef std::vector<String> StringArray;
|
||||
typedef std::vector<std::string> StringArray;
|
||||
typedef std::tr1::shared_ptr<StringArray> StringArrayPtr;
|
||||
inline String * get(StringArray &value)
|
||||
inline std::string * get(StringArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline String const * get(StringArray const &value)
|
||||
inline std::string const * get(StringArray const &value)
|
||||
{
|
||||
return static_cast<String const *>(&value[0]);
|
||||
return static_cast<std::string const *>(&value[0]);
|
||||
}
|
||||
inline String * get(StringArrayPtr &value)
|
||||
inline std::string * get(StringArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline String const * get(StringArrayPtr const &value)
|
||||
inline std::string const * get(StringArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
@@ -456,13 +122,8 @@ inline StringArray const & getVector(StringArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<String>::iterator StringArray_iterator;
|
||||
typedef std::vector<String>::const_iterator StringArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A convenience definition for toString methods
|
||||
*/
|
||||
typedef String * StringBuilder;
|
||||
typedef std::vector<std::string>::iterator StringArray_iterator;
|
||||
typedef std::vector<std::string>::const_iterator StringArray_const_iterator;
|
||||
|
||||
}}
|
||||
#endif /* PVTYPE_H */
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
|
||||
class StandardField;
|
||||
typedef std::tr1::shared_ptr<StandardField> StandardFieldPtr;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -34,9 +38,9 @@ namespace epics { namespace pvData {
|
||||
* For example the call:
|
||||
* {@code
|
||||
StructureConstPtr example = standardField->scalar(
|
||||
String("value"),
|
||||
std::string("value"),
|
||||
pvDouble,
|
||||
String("value,alarm,timeStamp"));
|
||||
std::string("value,alarm,timeStamp"));
|
||||
* }
|
||||
* Will result in a Field definition that has the form: {@code
|
||||
structure example
|
||||
@@ -47,7 +51,7 @@ namespace epics { namespace pvData {
|
||||
string message
|
||||
structure timeStamp
|
||||
long secondsPastEpoch
|
||||
int nanoSeconds
|
||||
int nanoseconds
|
||||
int userTag
|
||||
* }
|
||||
* In addition there are methods that create each of the property structures,
|
||||
@@ -57,42 +61,161 @@ namespace epics { namespace pvData {
|
||||
StandardField *standardField = getStandardField();
|
||||
* }
|
||||
*/
|
||||
|
||||
class StandardField;
|
||||
typedef std::tr1::shared_ptr<StandardField> StandardFieldPtr;
|
||||
|
||||
class epicsShareClass StandardField {
|
||||
public:
|
||||
/**
|
||||
* getStandardField returns the singleton.
|
||||
* @return Shared pointer to StandardField.
|
||||
*/
|
||||
static StandardFieldPtr getStandardField();
|
||||
~StandardField();
|
||||
StructureConstPtr scalar(ScalarType type,String const & properties);
|
||||
StructureConstPtr scalarArray(ScalarType elementType, String const & properties);
|
||||
StructureConstPtr structureArray(StructureConstPtr const & structure,String const & properties);
|
||||
/** Create a structure that has a scalar value field.
|
||||
* @param type The 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 scalar(ScalarType type,std::string const & properties);
|
||||
/** Create a structure that has a union value field.
|
||||
* @param punion The interface for 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 regUnion(
|
||||
UnionConstPtr const & punion,
|
||||
std::string const & properties);
|
||||
/** Create a structure that has a varient 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 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 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 structureArray(
|
||||
StructureConstPtr const & structure,
|
||||
std::string const & properties);
|
||||
/** Create a structure that has a unionArray value field.
|
||||
* @param type The type.
|
||||
* @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.
|
||||
*/
|
||||
StructureConstPtr unionArray(
|
||||
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".
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr enumerated();
|
||||
StructureConstPtr enumerated(String const & properties);
|
||||
/** Create a structure that has an enumerated structure value field
|
||||
* The id for the structure is "epics:nt/NTEnum:1.0".
|
||||
* @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 enumerated(std::string const & properties);
|
||||
/**
|
||||
* create an alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr alarm();
|
||||
/**
|
||||
* create a timeStamp structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr timeStamp();
|
||||
/**
|
||||
* create a display structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr display();
|
||||
/**
|
||||
* create a control structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr control();
|
||||
/**
|
||||
* create a boolean alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr booleanAlarm();
|
||||
/**
|
||||
* create a byte alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr byteAlarm();
|
||||
/**
|
||||
* create a unsigned byte alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr ubyteAlarm();
|
||||
/**
|
||||
* create a short alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr shortAlarm();
|
||||
/**
|
||||
* create a unsigned short alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr ushortAlarm();
|
||||
/**
|
||||
* create an int alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr intAlarm();
|
||||
/**
|
||||
* create a unsigned int alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr uintAlarm();
|
||||
/**
|
||||
* create a long alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr longAlarm();
|
||||
/**
|
||||
* create a unsigned long alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr ulongAlarm();
|
||||
/**
|
||||
* create a float alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr floatAlarm();
|
||||
/**
|
||||
* create a double alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr doubleAlarm();
|
||||
/**
|
||||
* create an enumerated alarm structure
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
StructureConstPtr enumeratedAlarm();
|
||||
private:
|
||||
StandardField();
|
||||
void init();
|
||||
StructureConstPtr createProperties(String id,FieldConstPtr field,String properties);
|
||||
StructureConstPtr createProperties(
|
||||
std::string id,FieldConstPtr field,std::string properties);
|
||||
FieldCreatePtr fieldCreate;
|
||||
String notImplemented;
|
||||
String valueFieldName;
|
||||
std::string notImplemented;
|
||||
std::string valueFieldName;
|
||||
StructureConstPtr alarmField;
|
||||
StructureConstPtr timeStampField;
|
||||
StructureConstPtr displayField;
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class StandardPVField;
|
||||
typedef std::tr1::shared_ptr<StandardPVField> StandardPVFieldPtr;
|
||||
|
||||
/**
|
||||
* StandardPVField is a class or creating standard data fields.
|
||||
* Like class StandardField it has two forms of the methods which create a fields:
|
||||
@@ -31,25 +35,67 @@ namespace epics { namespace pvData {
|
||||
StandardPVField *standardPVField = getStandardPVField();
|
||||
* }
|
||||
*/
|
||||
|
||||
class StandardPVField;
|
||||
typedef std::tr1::shared_ptr<StandardPVField> StandardPVFieldPtr;
|
||||
|
||||
class epicsShareClass StandardPVField : private NoDefaultMethods {
|
||||
public:
|
||||
/**
|
||||
* getStandardPVField returns the singleton.
|
||||
* @return Shared pointer to StandardPVField.
|
||||
*/
|
||||
static StandardPVFieldPtr getStandardPVField();
|
||||
~StandardPVField();
|
||||
PVStructurePtr scalar(ScalarType type,String const & properties);
|
||||
PVStructurePtr scalarArray(ScalarType elementType, String const & properties);
|
||||
PVStructurePtr structureArray(StructureConstPtr const &structure,String const & properties);
|
||||
/**
|
||||
* Create a structure that has a scalar value field.
|
||||
* @param type The 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.
|
||||
*/
|
||||
PVStructurePtr scalar(ScalarType type,std::string const & properties);
|
||||
/**
|
||||
* Create a structure that has a scalar array value field.
|
||||
* @param type The 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.
|
||||
*/
|
||||
PVStructurePtr scalarArray(ScalarType elementType, std::string const & properties);
|
||||
/**
|
||||
* Create a structure that has a structure array value field.
|
||||
* @param type The 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.
|
||||
*/
|
||||
PVStructurePtr structureArray(StructureConstPtr const &structure,std::string const & properties);
|
||||
/**
|
||||
* Create a structure that has a union array value field.
|
||||
* @param type The 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.
|
||||
*/
|
||||
PVStructurePtr unionArray(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".
|
||||
* @param choices This is a StringArray of choices.
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
PVStructurePtr enumerated(StringArray const &choices);
|
||||
PVStructurePtr enumerated(StringArray const &choices, String const & properties);
|
||||
/**
|
||||
* Create a structure that has an enumerated structure value field.
|
||||
* The id for the structure is "epics:nt/NTEnum:1.0".
|
||||
* @param choices This is a StringArray of choices.
|
||||
* @param properties A comma separated list of properties.
|
||||
* @return The const shared pointer to the structure.
|
||||
*/
|
||||
PVStructurePtr enumerated(StringArray const &choices, std::string const & properties);
|
||||
private:
|
||||
StandardPVField();
|
||||
StandardFieldPtr standardField;
|
||||
FieldCreatePtr fieldCreate;
|
||||
PVDataCreatePtr pvDataCreate;
|
||||
String notImplemented;
|
||||
std::string notImplemented;
|
||||
};
|
||||
|
||||
epicsShareExtern StandardPVFieldPtr getStandardPVField();
|
||||
|
||||
@@ -1,7 +1,31 @@
|
||||
# Makefile for the pvData tests
|
||||
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
DIRS += misc
|
||||
DIRS += pv
|
||||
DIRS += property
|
||||
include $(TOP)/configure/RULES_DIRS
|
||||
|
||||
PVDATA_TEST = $(TOP)/testApp
|
||||
|
||||
PROD_LIBS += pvData Com
|
||||
|
||||
include $(PVDATA_TEST)/misc/Makefile
|
||||
include $(PVDATA_TEST)/pv/Makefile
|
||||
include $(PVDATA_TEST)/property/Makefile
|
||||
include $(PVDATA_TEST)/copy/Makefile
|
||||
|
||||
# The testHarness runs all the test programs in a known working order.
|
||||
testHarness_SRCS += pvDataAllTests.c
|
||||
|
||||
PROD_vxWorks = vxTestHarness
|
||||
vxTestHarness_SRCS += $(testHarness_SRCS)
|
||||
TESTSPEC_vxWorks = vxTestHarness.$(MUNCH_SUFFIX); pvDataAllTests
|
||||
|
||||
PROD_RTEMS += rtemsTestHarness
|
||||
rtemsTestHarness_SRCS += rtemsTestHarness.c rtemsConfig.c
|
||||
rtemsTestHarness_SRCS += $(testHarness_SRCS)
|
||||
TESTSPEC_RTEMS = rtemsTestHarness.$(MUNCH_SUFFIX); pvDataAllTests
|
||||
|
||||
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
|
||||
|
||||
13
testApp/copy/Makefile
Normal file
13
testApp/copy/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
SRC_DIRS += $(PVDATA_TEST)/copy
|
||||
|
||||
TESTPROD_HOST += testCreateRequest
|
||||
testCreateRequest_SRCS = testCreateRequest.cpp
|
||||
testHarness_SRCS += testCreateRequest.cpp
|
||||
TESTS += testCreateRequest
|
||||
|
||||
TESTPROD_HOST += testPVCopy
|
||||
testPVCopy_SRCS += testPVCopy.cpp
|
||||
testHarness_SRCS += testPVCopy.cpp
|
||||
TESTS += testPVCopy
|
||||
322
testApp/copy/testCreateRequest.cpp
Normal file
322
testApp/copy/testCreateRequest.cpp
Normal file
@@ -0,0 +1,322 @@
|
||||
/* testCreateRequest.cpp */
|
||||
/* Author: Matej Sekoranja Date: 2010.12.27 */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/createRequest.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
static bool debug = false;
|
||||
|
||||
static void testCreateRequestInternal() {
|
||||
printf("testCreateRequest... \n");
|
||||
CreateRequest::shared_pointer createRequest = CreateRequest::create();
|
||||
PVStringPtr pvString;
|
||||
string sval;
|
||||
|
||||
string out;
|
||||
string request = "";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
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());
|
||||
|
||||
request = "record[]field()getField()putField()";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
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);
|
||||
testOk1(pvRequest->getSubField("getField").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = "record[a=b,x=y]field(a) putField(a),getField(a)";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
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();
|
||||
testOk(sval.compare("b")==0,"record.a = b");
|
||||
pvString = pvRequest->getSubField<PVString>("record._options.x");
|
||||
sval = pvString->get();
|
||||
testOk(sval.compare("y")==0,"record.x = y");
|
||||
testOk1(pvRequest->getSubField("field.a").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("putField.a").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.a").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = "field(a.b[x=y])";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
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();
|
||||
testOk(sval.compare("y")==0,"field.a.b._options.x = y");
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = "field(a.b{c.d})";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
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());
|
||||
|
||||
request = "field(a.b[x=y]{c.d})";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
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();
|
||||
testOk(sval.compare("y")==0,"field.a.b._options.x = y");
|
||||
testOk1(pvRequest->getSubField("field.a.b.c.d").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = "field(a.b[x=y]{c.d[x=y]})";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
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();
|
||||
testOk(sval.compare("y")==0,"field.a.b._options.x = y");
|
||||
pvString = pvRequest->getSubField<PVString>("field.a.b.c.d._options.x");
|
||||
sval = pvString->get();
|
||||
testOk(sval.compare("y")==0,"field.a.b.c.d._options.x = y");
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
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) { 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();
|
||||
testOk(sval.compare("b")==0,"field.a.a._options.a = b");
|
||||
pvString = pvRequest->getSubField<PVString>("field.a.a.a.a._options.a");
|
||||
sval = pvString->get();
|
||||
testOk(sval.compare("b")==0,"field.a.a.a.a._options.a = b");
|
||||
pvString = pvRequest->getSubField<PVString>("field.b.a._options.a");
|
||||
sval = pvString->get();
|
||||
testOk(sval.compare("b")==0,"field.b.a._options.a = b");
|
||||
testOk1(pvRequest->getSubField("field.b.a.a").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.b.a.b").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
|
||||
request = "alarm,timeStamp,power.value";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
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);
|
||||
testOk1(pvRequest->getSubField("field.power.value").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = "record[process=true]field(alarm,timeStamp,power.value)";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
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();
|
||||
testOk(sval.compare("true")==0,"record._options.process = true");
|
||||
testOk1(pvRequest->getSubField("field.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.timeStamp").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.power.value").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
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) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("record._options.process");
|
||||
sval = pvString->get();
|
||||
testOk(sval.compare("true")==0,"record._options.process = true");
|
||||
testOk1(pvRequest->getSubField("field.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.timeStamp").get()!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("field.timeStamp._options.algorithm");
|
||||
sval = pvString->get();
|
||||
testOk(sval.compare("onChange")==0,"field.timeStamp._options.algorithm = onChange");
|
||||
pvString = pvRequest->getSubField<PVString>("field.timeStamp._options.causeMonitor");
|
||||
sval = pvString->get();
|
||||
testOk(sval.compare("false")==0,"field.timeStamp._options.causeMonitor = false");
|
||||
testOk1(pvRequest->getSubField("field.power.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.power.alarm").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
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) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("record._options.int");
|
||||
sval = pvString->get();
|
||||
testOk(sval.compare("2")==0,"record._options.int = 2");
|
||||
pvString = pvRequest->getSubField<PVString>("record._options.float");
|
||||
sval = pvString->get();
|
||||
testOk(sval.compare("3.14159")==0,"record._options.float = 3.14159");
|
||||
testOk1(pvRequest->getSubField("field.alarm").get()!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("field.timeStamp._options.shareData");
|
||||
sval = pvString->get();
|
||||
testOk(sval.compare("true")==0,"field.timeStamp._options.shareData = true");
|
||||
testOk1(pvRequest->getSubField("field.power.value").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = string("record[process=true,xxx=yyy]")
|
||||
+ "putField(power.value)"
|
||||
+ "getField(alarm,timeStamp,power{value,alarm},"
|
||||
+ "current{value,alarm},voltage{value,alarm})";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
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);
|
||||
testOk1(pvRequest->getSubField("getField.timeStamp").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.power.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.power.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.current.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.current.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.voltage.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.voltage.alarm").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = string("field(alarm,timeStamp,supply{")
|
||||
+ "0{voltage.value,current.value,power.value},"
|
||||
+ "1{voltage.value,current.value,power.value}"
|
||||
+ "})";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
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);
|
||||
testOk1(pvRequest->getSubField("field.supply.0.voltage.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.supply.0.current.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.supply.0.power.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.supply.1.voltage.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.supply.1.current.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.supply.1.power.value").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = string("record[process=true,xxx=yyy]")
|
||||
+ "putField(power.value)"
|
||||
+ "getField(alarm,timeStamp,power{value,alarm},"
|
||||
+ "current{value,alarm},voltage{value,alarm},"
|
||||
+ "ps0{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}},"
|
||||
+ "ps1{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}}"
|
||||
+ ")";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
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);
|
||||
testOk1(pvRequest->getSubField("getField.timeStamp").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.power.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.power.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.current.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.current.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.voltage.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.voltage.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.timeStamp").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.power.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.power.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.current.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.current.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.voltage.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.voltage.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.timeStamp").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.power.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.power.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.current.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.current.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.voltage.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.voltage.alarm").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = "a{b{c{d}}}";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
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());
|
||||
|
||||
request = string("record[process=true,xxx=yyy]")
|
||||
+ "putField(power.value)"
|
||||
+ "getField(alarm,timeStamp,power{value,alarm},"
|
||||
+ "current{value,alarm},voltage{value,alarm},"
|
||||
+ "ps0{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}},"
|
||||
+ "ps1{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}"
|
||||
+ ")";
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
cout << endl << "Error Expected for next call!!" << endl;
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
cout << "reason " << createRequest->getMessage() << endl;
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = "record[process=true,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());
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
MAIN(testCreateRequest)
|
||||
{
|
||||
testPlan(119);
|
||||
testCreateRequestInternal();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
361
testApp/copy/testPVCopy.cpp
Normal file
361
testApp/copy/testPVCopy.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
/*testPVCopyMain.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/pvCopy.h>
|
||||
#include <pv/createRequest.h>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
|
||||
static bool debug = true;
|
||||
|
||||
static void testPVScalar(
|
||||
string const & valueNameMaster,
|
||||
string const & valueNameCopy,
|
||||
PVStructurePtr const & pvMaster,
|
||||
PVCopyPtr const & pvCopy)
|
||||
{
|
||||
PVStructurePtr pvStructureCopy;
|
||||
PVFieldPtr pvField;
|
||||
PVScalarPtr pvValueMaster;
|
||||
PVScalarPtr pvValueCopy;
|
||||
BitSetPtr bitSet;
|
||||
size_t offset;
|
||||
ConvertPtr convert = getConvert();
|
||||
|
||||
pvField = pvMaster->getSubField(valueNameMaster);
|
||||
pvValueMaster = static_pointer_cast<PVScalar>(pvField);
|
||||
convert->fromDouble(pvValueMaster,.04);
|
||||
StructureConstPtr structure = pvCopy->getStructure();
|
||||
if(debug) { cout << "structure from copy" << endl << *structure << endl; }
|
||||
pvStructureCopy = pvCopy->createPVStructure();
|
||||
pvField = pvStructureCopy->getSubField(valueNameCopy);
|
||||
pvValueCopy = static_pointer_cast<PVScalar>(pvField);
|
||||
bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
|
||||
pvCopy->initCopy(pvStructureCopy, bitSet);
|
||||
if(debug) { cout << "after initCopy pvValueCopy " << convert->toDouble(pvValueCopy); }
|
||||
if(debug) { cout << endl; }
|
||||
convert->fromDouble(pvValueMaster,.06);
|
||||
testOk1(convert->toDouble(pvValueCopy)==.04);
|
||||
pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet);
|
||||
testOk1(convert->toDouble(pvValueCopy)==.06);
|
||||
testOk1(bitSet->get(pvValueCopy->getFieldOffset()));
|
||||
if(debug) { cout << "after put(.06) pvValueCopy " << convert->toDouble(pvValueCopy); }
|
||||
if(debug) { cout << " bitSet " << *bitSet; }
|
||||
if(debug) { cout << endl; }
|
||||
offset = pvCopy->getCopyOffset(pvValueMaster);
|
||||
if(debug) { cout << "getCopyOffset() " << offset; }
|
||||
if(debug) { cout << " pvValueCopy->getOffset() " << pvValueCopy->getFieldOffset(); }
|
||||
if(debug) { cout << " pvValueMaster->getOffset() " << pvValueMaster->getFieldOffset(); }
|
||||
if(debug) { cout << " bitSet " << *bitSet; }
|
||||
if(debug) { cout << endl; }
|
||||
bitSet->clear();
|
||||
convert->fromDouble(pvValueMaster,1.0);
|
||||
if(debug) { cout << "before updateCopyFromBitSet"; }
|
||||
if(debug) { cout << " masterValue " << convert->toDouble(pvValueMaster); }
|
||||
if(debug) { cout << " copyValue " << convert->toDouble(pvValueCopy); }
|
||||
if(debug) { cout << " bitSet " << *bitSet; }
|
||||
if(debug) { cout << endl; }
|
||||
bitSet->set(0);
|
||||
testOk1(convert->toDouble(pvValueCopy)==0.06);
|
||||
pvCopy->updateCopyFromBitSet(pvStructureCopy,bitSet);
|
||||
testOk1(convert->toDouble(pvValueCopy)==1.0);
|
||||
if(debug) { cout << "after updateCopyFromBitSet"; }
|
||||
if(debug) { cout << " masterValue " << convert->toDouble(pvValueMaster); }
|
||||
if(debug) { cout << " copyValue " << convert->toDouble(pvValueCopy); }
|
||||
if(debug) { cout << " bitSet " << *bitSet; }
|
||||
if(debug) { cout << endl; }
|
||||
convert->fromDouble(pvValueCopy,2.0);
|
||||
bitSet->set(0);
|
||||
if(debug) { cout << "before updateMaster"; }
|
||||
if(debug) { cout << " masterValue " << convert->toDouble(pvValueMaster); }
|
||||
if(debug) { cout << " copyValue " << convert->toDouble(pvValueCopy); }
|
||||
if(debug) { cout << " bitSet " << *bitSet; }
|
||||
if(debug) { cout << endl; }
|
||||
testOk1(convert->toDouble(pvValueMaster)==1.0);
|
||||
pvCopy->updateMaster(pvStructureCopy,bitSet);
|
||||
testOk1(convert->toDouble(pvValueMaster)==2.0);
|
||||
if(debug) { cout << "after updateMaster"; }
|
||||
if(debug) { cout << " masterValue " << convert->toDouble(pvValueMaster); }
|
||||
if(debug) { cout << " copyValue " << convert->toDouble(pvValueCopy); }
|
||||
if(debug) { cout << " bitSet " << *bitSet; }
|
||||
if(debug) { cout << endl; }
|
||||
}
|
||||
|
||||
static void testPVScalarArray(
|
||||
ScalarType scalarType,
|
||||
string const & valueNameMaster,
|
||||
string const & valueNameCopy,
|
||||
PVStructurePtr const & pvMaster,
|
||||
PVCopyPtr const & pvCopy)
|
||||
{
|
||||
PVStructurePtr pvStructureCopy;
|
||||
PVScalarArrayPtr pvValueMaster;
|
||||
PVScalarArrayPtr pvValueCopy;
|
||||
BitSetPtr bitSet;
|
||||
size_t offset;
|
||||
size_t n = 5;
|
||||
shared_vector<double> values(n);
|
||||
shared_vector<const double> cvalues;
|
||||
|
||||
pvValueMaster = pvMaster->getScalarArrayField(valueNameMaster,scalarType);
|
||||
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);
|
||||
bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
|
||||
pvCopy->initCopy(pvStructureCopy, bitSet);
|
||||
if(debug) { cout << "after initCopy pvValueCopy " << *pvValueCopy << endl; }
|
||||
if(debug) { cout << endl; }
|
||||
values.resize(n);
|
||||
for(size_t i=0; i<n; i++) values[i] = i + .06;
|
||||
const shared_vector<const double> yyy(freeze(values));
|
||||
pvValueMaster->putFrom(yyy);
|
||||
pvValueCopy->getAs(cvalues);
|
||||
testOk1(cvalues[0]==0.0);
|
||||
pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet);
|
||||
pvValueCopy->getAs(cvalues);
|
||||
testOk1(cvalues[0]==0.06);
|
||||
if(debug) { cout << "after put(i+ .06) pvValueCopy " << *pvValueCopy << endl; }
|
||||
if(debug) { cout << " bitSet " << *bitSet; }
|
||||
if(debug) { cout << endl; }
|
||||
offset = pvCopy->getCopyOffset(pvValueMaster);
|
||||
if(debug) { cout << "getCopyOffset() " << offset; }
|
||||
if(debug) { cout << " pvValueCopy->getOffset() " << pvValueCopy->getFieldOffset(); }
|
||||
if(debug) { cout << " pvValueMaster->getOffset() " << pvValueMaster->getFieldOffset(); }
|
||||
if(debug) { cout << " bitSet " << *bitSet; }
|
||||
if(debug) { cout << endl; }
|
||||
bitSet->clear();
|
||||
values.resize(n);
|
||||
for(size_t i=0; i<n; i++) values[i] = i + 1.0;
|
||||
const shared_vector<const double> zzz(freeze(values));
|
||||
pvValueMaster->putFrom(zzz);
|
||||
if(debug) { cout << "before updateCopyFromBitSet"; }
|
||||
if(debug) { cout << " masterValue " << *pvValueMaster << endl; }
|
||||
if(debug) { cout << " copyValue " << *pvValueCopy << endl; }
|
||||
if(debug) { cout << " bitSet " << *bitSet; }
|
||||
if(debug) { cout << endl; }
|
||||
bitSet->set(0);
|
||||
pvValueCopy->getAs(cvalues);
|
||||
testOk1(cvalues[0]==0.06);
|
||||
pvCopy->updateCopyFromBitSet(pvStructureCopy,bitSet);
|
||||
pvValueCopy->getAs(cvalues);
|
||||
testOk1(cvalues[0]==1.0);
|
||||
if(debug) { cout << "after updateCopyFromBitSet"; }
|
||||
if(debug) { cout << " masterValue " << *pvValueMaster << endl; }
|
||||
if(debug) { cout << " copyValue " << *pvValueCopy << endl; }
|
||||
if(debug) { cout << " bitSet " << *bitSet; }
|
||||
if(debug) { cout << endl; }
|
||||
values.resize(n);
|
||||
for(size_t i=0; i<n; i++) values[i] = i + 2.0;
|
||||
const shared_vector<const double> ttt(freeze(values));
|
||||
pvValueMaster->putFrom(ttt);
|
||||
bitSet->set(0);
|
||||
if(debug) { cout << "before updateMaster"; }
|
||||
if(debug) { cout << " masterValue " << *pvValueMaster << endl; }
|
||||
if(debug) { cout << " copyValue " << *pvValueCopy << endl; }
|
||||
if(debug) { cout << " bitSet " << *bitSet; }
|
||||
if(debug) { cout << endl; }
|
||||
pvValueMaster->getAs(cvalues);
|
||||
testOk1(cvalues[0]==2.0);
|
||||
pvCopy->updateMaster(pvStructureCopy,bitSet);
|
||||
pvValueMaster->getAs(cvalues);
|
||||
testOk1(cvalues[0]==1.0);
|
||||
if(debug) { cout << "before updateMaster"; }
|
||||
if(debug) { cout << " masterValue " << *pvValueMaster << endl; }
|
||||
if(debug) { cout << " copyValue " << *pvValueCopy << endl; }
|
||||
if(debug) { cout << " bitSet " << *bitSet; }
|
||||
if(debug) { cout << endl; }
|
||||
}
|
||||
|
||||
static void scalarTest()
|
||||
{
|
||||
if(debug) { cout << endl << endl << "****scalarTest****" << endl; }
|
||||
PVStructurePtr pvMaster;
|
||||
string request;
|
||||
PVStructurePtr pvRequest;
|
||||
PVFieldPtr pvMasterField;
|
||||
PVCopyPtr pvCopy;
|
||||
string valueNameMaster;
|
||||
string valueNameCopy;
|
||||
|
||||
StandardPVFieldPtr standardPVField = getStandardPVField();
|
||||
pvMaster = standardPVField->scalar(pvDouble,"alarm,timeStamp,display");
|
||||
|
||||
valueNameMaster = request = "value";
|
||||
CreateRequest::shared_pointer createRequest = CreateRequest::create();
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
request = "";
|
||||
valueNameMaster = "value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
request = "alarm,timeStamp,value";
|
||||
valueNameMaster = "value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
}
|
||||
|
||||
static void arrayTest()
|
||||
{
|
||||
if(debug) { cout << endl << endl << "****arrayTest****" << endl; }
|
||||
PVStructurePtr pvMaster;
|
||||
string request;
|
||||
PVStructurePtr pvRequest;
|
||||
PVFieldPtr pvMasterField;
|
||||
PVCopyPtr pvCopy;
|
||||
string valueNameMaster;
|
||||
string valueNameCopy;
|
||||
|
||||
CreateRequest::shared_pointer createRequest = CreateRequest::create();
|
||||
StandardPVFieldPtr standardPVField = getStandardPVField();
|
||||
pvMaster = standardPVField->scalarArray(pvDouble,"alarm,timeStamp");
|
||||
valueNameMaster = request = "value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
request = "";
|
||||
valueNameMaster = "value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
request = "alarm,timeStamp,value";
|
||||
valueNameMaster = "value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
}
|
||||
|
||||
static PVStructurePtr createPowerSupply()
|
||||
{
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
StandardFieldPtr standardField = getStandardField();
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
|
||||
size_t nfields = 5;
|
||||
StringArray names;
|
||||
names.reserve(nfields);
|
||||
FieldConstPtrArray powerSupply;
|
||||
powerSupply.reserve(nfields);
|
||||
names.push_back("alarm");
|
||||
powerSupply.push_back(standardField->alarm());
|
||||
names.push_back("timeStamp");
|
||||
powerSupply.push_back(standardField->timeStamp());
|
||||
string properties("alarm,display");
|
||||
names.push_back("voltage");
|
||||
powerSupply.push_back(standardField->scalar(pvDouble,properties));
|
||||
names.push_back("power");
|
||||
powerSupply.push_back(standardField->scalar(pvDouble,properties));
|
||||
names.push_back("current");
|
||||
powerSupply.push_back(standardField->scalar(pvDouble,properties));
|
||||
return pvDataCreate->createPVStructure(
|
||||
fieldCreate->createStructure(names,powerSupply));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void powerSupplyTest()
|
||||
{
|
||||
if(debug) { cout << endl << endl << "****powerSupplyTest****" << endl; }
|
||||
PVStructurePtr pvMaster;
|
||||
string request;
|
||||
PVStructurePtr pvRequest;
|
||||
PVFieldPtr pvMasterField;
|
||||
PVCopyPtr pvCopy;
|
||||
string builder;
|
||||
string valueNameMaster;
|
||||
string valueNameCopy;
|
||||
|
||||
CreateRequest::shared_pointer createRequest = CreateRequest::create();
|
||||
pvMaster = createPowerSupply();
|
||||
valueNameMaster = request = "power.value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "power.value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
request = "";
|
||||
valueNameMaster = "power.value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "power.value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
request = "alarm,timeStamp,voltage.value,power.value,current.value";
|
||||
valueNameMaster = "power.value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "power.value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
request = "alarm,timeStamp,voltage{value,alarm},power{value,alarm,display},current.value";
|
||||
valueNameMaster = "power.value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "power.value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
}
|
||||
|
||||
MAIN(testPVCopy)
|
||||
{
|
||||
testPlan(67);
|
||||
scalarTest();
|
||||
arrayTest();
|
||||
powerSupplyTest();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -1,63 +1,66 @@
|
||||
TOP=../..
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
SRC_DIRS += $(PVDATA_TEST)/misc
|
||||
|
||||
PROD_LIBS += pvData Com
|
||||
|
||||
PROD_HOST += testThread
|
||||
TESTPROD_HOST += testThread
|
||||
testThread_SRCS += testThread.cpp
|
||||
testHarness_SRCS += testThread.cpp
|
||||
TESTS += testThread
|
||||
|
||||
PROD_HOST += testTimer
|
||||
TESTPROD_HOST += testTimer
|
||||
testTimer_SRCS += testTimer.cpp
|
||||
testHarness_SRCS += testTimer.cpp
|
||||
TESTS += testTimer
|
||||
|
||||
PROD_HOST += testBitSet
|
||||
TESTPROD_HOST += testBitSet
|
||||
testBitSet_SRCS += testBitSet.cpp
|
||||
testHarness_SRCS += testBitSet.cpp
|
||||
TESTS += testBitSet
|
||||
|
||||
PROD_HOST += testOverrunBitSet
|
||||
TESTPROD_HOST += testOverrunBitSet
|
||||
testOverrunBitSet_SRCS += testOverrunBitSet.cpp
|
||||
testHarness_SRCS += testOverrunBitSet.cpp
|
||||
TESTS += testOverrunBitSet
|
||||
|
||||
PROD_HOST += testByteOrder
|
||||
TESTPROD_HOST += testByteOrder
|
||||
testByteOrder_SRCS += testByteOrder.cpp
|
||||
|
||||
PROD_HOST += testByteBuffer
|
||||
TESTPROD_HOST += testByteBuffer
|
||||
testByteBuffer_SRCS += testByteBuffer.cpp
|
||||
testHarness_SRCS += testByteBuffer.cpp
|
||||
TESTS += testByteBuffer
|
||||
|
||||
PROD_HOST += testBaseException
|
||||
TESTPROD_HOST += testBaseException
|
||||
testBaseException_SRCS += testBaseException.cpp
|
||||
testHarness_SRCS += testBaseException.cpp
|
||||
TESTS += testBaseException
|
||||
|
||||
PROD_HOST += testSharedVector
|
||||
TESTPROD_HOST += testSharedVector
|
||||
testSharedVector_SRCS += testSharedVector.cpp
|
||||
testHarness_SRCS += testSharedVector.cpp
|
||||
TESTS += testSharedVector
|
||||
|
||||
PROD_HOST += testSerialization
|
||||
TESTPROD_HOST += testSerialization
|
||||
testSerialization_SRCS += testSerialization.cpp
|
||||
testHarness_SRCS += testSerialization.cpp
|
||||
TESTS += testSerialization
|
||||
|
||||
PROD_HOST += testTimeStamp
|
||||
TESTPROD_HOST += testTimeStamp
|
||||
testTimeStamp_SRCS += testTimeStamp.cpp
|
||||
testHarness_SRCS += testTimeStamp.cpp
|
||||
TESTS += testTimeStamp
|
||||
|
||||
PROD_HOST += testQueue
|
||||
TESTPROD_HOST += testQueue
|
||||
testQueue_SRCS += testQueue.cpp
|
||||
testHarness_SRCS += testQueue.cpp
|
||||
TESTS += testQueue
|
||||
|
||||
PROD_HOST += testMessageQueue
|
||||
TESTPROD_HOST += testMessageQueue
|
||||
testMessageQueue_SRCS += testMessageQueue.cpp
|
||||
testHarness_SRCS += testMessageQueue.cpp
|
||||
TESTS += testMessageQueue
|
||||
|
||||
PROD_HOST += testTypeCast
|
||||
TESTPROD_HOST += testTypeCast
|
||||
testTypeCast_SRCS += testTypeCast.cpp
|
||||
testHarness_SRCS += testTypeCast.cpp
|
||||
TESTS += testTypeCast
|
||||
|
||||
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ void internalTestBaseException(int /*unused*/ = 0)
|
||||
}
|
||||
}
|
||||
|
||||
void testBaseException() {
|
||||
void testBaseExceptionTest() {
|
||||
printf("testBaseException... ");
|
||||
|
||||
try {
|
||||
@@ -86,7 +86,7 @@ MAIN(testBaseException)
|
||||
testPlan(2);
|
||||
testDiag("Tests base exception");
|
||||
testLogicException();
|
||||
testBaseException();
|
||||
testBaseExceptionTest();
|
||||
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