Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
354fdd412f | ||
|
|
f3f6141e6a | ||
|
|
b9592eeb8c | ||
|
|
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 |
8
.hgtags
8
.hgtags
@@ -10,3 +10,11 @@ d70c5ad29163306f50979a95b5aebbe9a93cfe76 2.0-BETA
|
||||
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
|
||||
af82285f71aae5d08fa8cf333b03772c5e689aff 4.0.2
|
||||
|
||||
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
|
||||
|
||||
@@ -20,8 +20,8 @@ CHECK_RELEASE = YES
|
||||
# INSTALL_LOCATION here.
|
||||
#INSTALL_LOCATION=</path/name/to/install/top>
|
||||
|
||||
-include $(TOP)/../CONFIG_SITE.local
|
||||
-include $(TOP)/configure/CONFIG_SITE.local
|
||||
-include $(TOP)/../CONFIG.local
|
||||
|
||||
ifdef WITH_COVERAGE
|
||||
USR_CPPFLAGS += --coverage
|
||||
|
||||
@@ -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>
|
||||
@@ -1,9 +1,12 @@
|
||||
Release release/3.1 IN DEVELOPMENT
|
||||
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.
|
||||
@@ -16,6 +19,44 @@ In order to limit memory usage the storage for raw data is managed via a new sha
|
||||
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.
|
||||
------------
|
||||
|
||||
@@ -41,6 +82,7 @@ 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
|
||||
==========
|
||||
|
||||
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>
|
||||
@@ -1,33 +1,10 @@
|
||||
TODO
|
||||
===========
|
||||
|
||||
toString, dumpValue, printer, and streams
|
||||
printer
|
||||
------------
|
||||
|
||||
The way to print introspection and data instances is not consistent.
|
||||
This needs work.
|
||||
Some items that need work are:
|
||||
|
||||
* Introspection has no support for streams. Only for toString.
|
||||
* data has problems. toString is implemented by calling Convert::getString.
|
||||
It look like this was intended to use printer but that did nor properly indent fields of structures.
|
||||
|
||||
The current implementation is:
|
||||
|
||||
void Convert::getString(StringBuilder buf,PVField const *pvField,int /*indentLevel*/)
|
||||
{
|
||||
// TODO indextLevel ignored
|
||||
std::ostringstream strm;
|
||||
strm << pvField->dumpValue(strm) << std::endl;
|
||||
// PrinterPlain p;
|
||||
// p.setStream(strm);
|
||||
// p.print(*pvField);
|
||||
strm.str().swap(*buf);
|
||||
}
|
||||
|
||||
Thus it just uses dumpValue.
|
||||
What should it do?
|
||||
If printer is used it must do proper indentation.
|
||||
pv/printer.h is not used.
|
||||
|
||||
doxygen
|
||||
-------
|
||||
@@ -35,20 +12,27 @@ 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.
|
||||
|
||||
PVFieldConstPtr etc
|
||||
-------------------
|
||||
|
||||
In pvDataCPP.html look at the monoitorPlugin example.
|
||||
It has a discussion of a possible need for shared pointers that can not be used to modify data.
|
||||
This in addition to PVFieldPtr should PVFieldConstPtr exist.
|
||||
But this means that all methods defined in pvDataCPP must be checked.
|
||||
This is a BIG job.
|
||||
|
||||
Release 3.0.2
|
||||
==========
|
||||
This was the starting point for RELEASE_NOTES
|
||||
|
||||
@@ -52,7 +52,7 @@ 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 knowlege of PVRecord. The C++ version was implemented in pvDatabaseCPP
|
||||
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>
|
||||
@@ -65,13 +65,13 @@ At present only the C++ version of the new API for pvCopy is implemented.
|
||||
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 arbitrarary subset of the
|
||||
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 faculity used by channel providers.
|
||||
<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
|
||||
@@ -185,7 +185,7 @@ where
|
||||
This is the method for creating a PVCopy instance.<br/>
|
||||
<dl>
|
||||
<dt>pvMaster</dt>
|
||||
<dd>the top level sructure managed by the server.</dd>
|
||||
<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>
|
||||
@@ -241,12 +241,12 @@ where
|
||||
<dt>updateCopyFromBitSet</dt>
|
||||
<dd>
|
||||
For each set bit in bitSet set the field in copyPVStructure to the value
|
||||
of the corrseponding field in pvMaster.
|
||||
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 corrseponding field in copyPVStructure.
|
||||
of the corresponding field in copyPVStructure.
|
||||
|
||||
</dd>
|
||||
<dt>getOptions</dt>
|
||||
@@ -266,7 +266,7 @@ where
|
||||
<p>This consists of two components:
|
||||
<dl>
|
||||
<dt>monitor</dt>
|
||||
<dd>Used by code that implements pvAccess montors.</dd>
|
||||
<dd>Used by code that implements pvAccess monitors.</dd>
|
||||
<dt>monitorPlugin</dt>
|
||||
<dd>Code that provides special semantics for monitors.</dd>
|
||||
</dl>
|
||||
@@ -346,7 +346,7 @@ Note that each client has it's own queue that is not shared with other client.
|
||||
<dt>start</dt>
|
||||
<dd>
|
||||
Start monitoring.
|
||||
This will result in a an inital monitor that has the current value
|
||||
This will result in a an initial monitor that has the current value
|
||||
of all fields.
|
||||
</dd>
|
||||
<dt>stop</dt>
|
||||
@@ -356,11 +356,11 @@ Note that each client has it's own queue that is not shared with other client.
|
||||
<dt>poll</dt>
|
||||
<dd>
|
||||
Called to get a monitor element.
|
||||
If no new elemants are available then a null pointer is returned.
|
||||
If no new elements are available then a null pointer is returned.
|
||||
</dd>
|
||||
<dt>release</dt>
|
||||
<dd>
|
||||
Release the monotor element.
|
||||
Release the monitor element.
|
||||
The caller owns the monitor element between the calls to poll and release.
|
||||
</dd>
|
||||
<dl>
|
||||
@@ -488,7 +488,7 @@ It has methods:</p>
|
||||
<dd>
|
||||
MonitorPluginManager is a singleton.
|
||||
The first call to get will create the single instance.
|
||||
Further calls will rerurn the single instance.
|
||||
Further calls will return the single instance.
|
||||
</dd>
|
||||
<dt>addPlugin</dt>
|
||||
<dd>
|
||||
@@ -496,18 +496,18 @@ It has methods:</p>
|
||||
</dd>
|
||||
<dt>findPlugin</dt>
|
||||
<dd>
|
||||
Find a plugin. A NULL shared pointer is reurned if it has not been added.
|
||||
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 puugins that have been added.
|
||||
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 modfied.
|
||||
This would be posssible if the following was defined:
|
||||
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;
|
||||
@@ -519,7 +519,7 @@ virtual bool causeMonitor(
|
||||
PVStructureConstPtr const &pvTop,
|
||||
MonitorElementPtr const &monitorElement) = 0;
|
||||
</pre>
|
||||
But just adding these definitions is not sufficent.
|
||||
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.
|
||||
@@ -545,15 +545,15 @@ structure powerSupply
|
||||
structure power
|
||||
double value
|
||||
structure alarm
|
||||
struvture display
|
||||
structure display
|
||||
structure voltage
|
||||
double value
|
||||
structure alarm
|
||||
struvture display
|
||||
structure display
|
||||
structure current
|
||||
double value
|
||||
structure alarm
|
||||
struvture display
|
||||
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:
|
||||
@@ -578,7 +578,7 @@ client wants. It can be attached to any field via the following options:
|
||||
[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 monotor
|
||||
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.
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -28,11 +28,11 @@ StructureConstPtr enum_t =
|
||||
// create a structure (cntd.)
|
||||
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()->
|
||||
|
||||
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(std::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 {
|
||||
std::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">std::string toString();</font>
|
||||
}
|
||||
|
||||
<font color = "blue">
|
||||
// new interface
|
||||
interface FieldTostd::string {
|
||||
std::string toString(Field field);
|
||||
}</font>
|
||||
|
||||
interface Scalar extends Field {
|
||||
ScalarType getScalarType();
|
||||
}
|
||||
|
||||
interface ScalarArray extends Field {
|
||||
ScalarType getElementType();
|
||||
}
|
||||
|
||||
interface Structure extends Field {
|
||||
Field getField(std::string fieldName);
|
||||
int getFieldIndex(std::string fieldName);
|
||||
Field[] getFields();
|
||||
Field getField(int fieldIndex);
|
||||
std::string[] getFieldNames();
|
||||
std::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(std::string[] fieldNames, Field[] field);
|
||||
Structure createStructure(std::string id,std::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,std::string fieldName, Field field);</font>
|
||||
<font color = "red">Structure appendFields(Structure structure,std::string[] fieldNames, Field[] fields);</font>
|
||||
}
|
||||
</pre>
|
||||
<h3>Data Interfaces</h3>
|
||||
<pre>
|
||||
interface PVField extends Requester, Serializable {
|
||||
std::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(std::string newName);</font>
|
||||
<font color = "red">void toString(StringBuilder buf);</font>
|
||||
<font color = "red">void toString(StringBuilder buf,int indentLevel);</font>
|
||||
<font color = "red">std::string toString();</font>
|
||||
}
|
||||
|
||||
<font color = "blue">
|
||||
// The following is a new interface
|
||||
interface PVFieldTostd::string {
|
||||
std::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(std::string fieldName);
|
||||
PVField getSubField(int fieldOffset);
|
||||
// The following are convenience methods
|
||||
PVBoolean getBooleanField(std::string fieldName);
|
||||
PVByte getByteField(std::string fieldName);
|
||||
PVShort getShortField(std::string fieldName);
|
||||
PVInt getIntField(std::string fieldName);
|
||||
PVLong getLongField(std::string fieldName);
|
||||
PVFloat getFloatField(std::string fieldName);
|
||||
PVDouble getDoubleField(std::string fieldName);
|
||||
PVString getStringField(std::string fieldName);
|
||||
PVScalarArray getScalarArrayField(std::string fieldName);
|
||||
PVStructureArray getStructureArrayField(std::string fieldName);
|
||||
PVStructure getStructureField(std::string fieldName);
|
||||
PVArray getArrayField(std::string fieldName,ScalarType elementType);
|
||||
// following will be removed
|
||||
<font color = "red"> void appendPVField(std::string fieldName,PVField pvField);</font>
|
||||
<font color = "red"> void appendPVFields(std::string[] fieldNames,PVField[] pvFields);</font>
|
||||
<font color = "red"> void removePVField(std::string fieldName);</font>
|
||||
<font color = "red"> void replacePVField(PVField oldPVField,PVField newPVField);</font>
|
||||
<font color = "red"> std::string getExtendsStructureName();</font>
|
||||
<font color = "red"> boolean putExtendsStructureName(std::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(std::string[] fieldNames,Field[] fields);
|
||||
PVStructure createPVStructure(PVStructure structToClone);
|
||||
// following will be removed
|
||||
<font color = "red">PVField[] flattenPVStructure(PVStructure pvStructure);</font>
|
||||
}
|
||||
</pre>
|
||||
<h3>PVFieldTostd::string</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 std::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 std::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 std::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(std::string const & fieldName) const;
|
||||
FieldConstPtr getField(std::size_t index) const;
|
||||
std::size_t getFieldIndex(std::string const &fieldName) const;
|
||||
FieldConstPtrArray const & getFields() const {return fields;}
|
||||
StringArray const & getFieldNames() const;
|
||||
std::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,std::string const &newName);
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
virtual std::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 std::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 (
|
||||
std::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,
|
||||
std::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 std::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(std::string message,MessageType messageType);
|
||||
void replacePVField(const PVFieldPtr& newPVField);
|
||||
std::string getFullName() const;
|
||||
virtual bool equals(PVField &pv);
|
||||
PVAuxInfoPtr & getPVAuxInfo()
|
||||
bool isImmutable() const;
|
||||
virtual void setImmutable();
|
||||
void replacePVField(const PVFieldPtr& newPVField);
|
||||
void renameField(std::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 PVFieldTostd::string {
|
||||
std::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<std::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<std::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(std::string const &fieldName) const;
|
||||
PVFieldPtr getSubField(std::size_t fieldOffset) const;
|
||||
PVBooleanPtr getBooleanField(std::string const &fieldName) ;
|
||||
PVBytePtr getByteField(std::string const &fieldName) ;
|
||||
PVShortPtr getShortField(std::string const &fieldName) ;
|
||||
PVIntPtr getIntField(std::string const &fieldName) ;
|
||||
PVLongPtr getLongField(std::string const &fieldName) ;
|
||||
PVUBytePtr getUByteField(std::string const &fieldName) ;
|
||||
PVUShortPtr getUShortField(std::string const &fieldName) ;
|
||||
PVUIntPtr getUIntField(std::string const &fieldName) ;
|
||||
PVULongPtr getULongField(std::string const &fieldName) ;
|
||||
PVFloatPtr getFloatField(std::string const &fieldName) ;
|
||||
PVDoublePtr getDoubleField(std::string const &fieldName) ;
|
||||
PVStringPtr getStringField(std::string const &fieldName) ;
|
||||
PVStructurePtr getStructureField(std::string const &fieldName) ;
|
||||
PVScalarArrayPtr getScalarArrayField(
|
||||
std::string const &fieldName,ScalarType elementType) ;
|
||||
PVStructureArrayPtr getStructureArrayField(std::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(
|
||||
std::string const &fieldName,
|
||||
PVFieldPtr const & pvField);
|
||||
void appendPVFields(
|
||||
StringArray const & fieldNames,
|
||||
PVFieldPtrArray const & pvFields);
|
||||
void removePVField(std::string const &fieldName);
|
||||
virtual void setImmutable();
|
||||
std::string getExtendsStructureName() const;
|
||||
bool putExtendsStructureName(
|
||||
std::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
|
||||
|
||||
@@ -14,10 +14,12 @@
|
||||
#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 {
|
||||
|
||||
@@ -27,6 +29,38 @@ 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) {
|
||||
@@ -40,8 +74,8 @@ private:
|
||||
size_t openBrace = request.find('{', index+1);
|
||||
size_t closeBrace = request.find('}', index+1);
|
||||
if(openBrace == string::npos && closeBrace == string::npos){
|
||||
message = request + " missing }";
|
||||
return 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);
|
||||
@@ -56,14 +90,14 @@ private:
|
||||
for(size_t i=index+1; i< request.size(); ++i) {
|
||||
if(request[i] == ']') {
|
||||
if(i==index+1) {
|
||||
message = request + " illegal []";
|
||||
return string::npos;
|
||||
message = request + " mismatched []";
|
||||
throw std::logic_error("message");
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
message = request + " missing ]";
|
||||
return string::npos;
|
||||
message = request + " missing ]";
|
||||
throw std::logic_error("message");
|
||||
}
|
||||
|
||||
size_t findEndField(string& request) {
|
||||
@@ -84,13 +118,17 @@ private:
|
||||
ind = closeBrace;
|
||||
continue;
|
||||
}
|
||||
if(request[ind]=='.') {
|
||||
++ind;
|
||||
continue;
|
||||
}
|
||||
if(ind>=maxind) break;
|
||||
++ind;
|
||||
}
|
||||
return request.size();
|
||||
}
|
||||
|
||||
std::vector<string> split(string const & commaSeparatedList) {
|
||||
vector<string> split(string const & commaSeparatedList) {
|
||||
string::size_type numValues = 1;
|
||||
string::size_type index=0;
|
||||
while(true) {
|
||||
@@ -99,7 +137,7 @@ private:
|
||||
numValues++;
|
||||
index = pos +1;
|
||||
}
|
||||
std::vector<string> valueList(numValues,"");
|
||||
vector<string> valueList(numValues,"");
|
||||
index=0;
|
||||
for(size_t i=0; i<numValues; i++) {
|
||||
size_t pos = commaSeparatedList.find(',',index);
|
||||
@@ -110,417 +148,329 @@ private:
|
||||
return valueList;
|
||||
}
|
||||
|
||||
StructureConstPtr createRequestOptions(
|
||||
string request)
|
||||
Node createRequestOptions(
|
||||
string const & request)
|
||||
{
|
||||
if(request.length()<=1) return StructureConstPtr();
|
||||
std::vector<string> items = split(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();
|
||||
StringArray fieldNames(nitems);
|
||||
FieldConstPtrArray fields(nitems);
|
||||
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";
|
||||
StructureConstPtr xxx;
|
||||
return xxx;
|
||||
message = item + " illegal option " + request;
|
||||
throw std::logic_error("message");
|
||||
}
|
||||
fieldNames[j] = item.substr(0,equals);
|
||||
fields[j] = fieldCreate->createScalar(pvString);
|
||||
}
|
||||
return fieldCreate->createStructure(fieldNames,fields);
|
||||
}
|
||||
|
||||
void initRequestOptions(
|
||||
PVStructurePtr const & pvParent,
|
||||
string request)
|
||||
{
|
||||
if(request.length()<=1) return;
|
||||
std::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('=');
|
||||
string name = item.substr(0,equals);
|
||||
top.push_back(Node(item.substr(0,equals)));
|
||||
string name = fullFieldName + "._options." + item.substr(0,equals);
|
||||
string value = item.substr(equals+1);
|
||||
PVStringPtr pvValue = pvParent->getSubField<PVString>(name);
|
||||
pvValue->put(value);
|
||||
optionList.push_back(OptionPair(name,value));
|
||||
}
|
||||
}
|
||||
|
||||
StructureConstPtr createSubFieldRequest(
|
||||
StructureConstPtr parent,
|
||||
string request)
|
||||
{
|
||||
if(request.length()<=0) return parent;
|
||||
size_t period = request.find('.');
|
||||
size_t openBracket = request.find('[');
|
||||
size_t openBrace = request.find('{');
|
||||
|
||||
// name only
|
||||
if(period==string::npos
|
||||
&& openBracket==string::npos
|
||||
&& openBrace==string::npos)
|
||||
{
|
||||
StructureConstPtr subField = fieldCreate->createStructure();
|
||||
parent = fieldCreate->appendField(parent,request,subField);
|
||||
return parent;
|
||||
}
|
||||
|
||||
// period is first
|
||||
if(period!=string::npos
|
||||
&& (openBracket==string::npos || period<openBracket)
|
||||
&& (openBrace==string::npos || period<openBrace) )
|
||||
{
|
||||
string fieldName = request.substr(0,period);
|
||||
StructureConstPtr subField = fieldCreate->createStructure();
|
||||
subField = createSubFieldRequest(subField,request.substr(period+1));
|
||||
if(subField==NULL) return subField;
|
||||
parent = fieldCreate->appendField(parent,fieldName,subField);
|
||||
return parent;
|
||||
}
|
||||
|
||||
// brace before [ or .
|
||||
if(openBrace!=string::npos
|
||||
&& (openBracket==string::npos || openBrace<openBracket) )
|
||||
{
|
||||
string fieldName = request.substr(0,openBrace);
|
||||
size_t closeBrace = findMatchingBrace(request,openBrace,1);
|
||||
if(closeBrace==string::npos) return StructureConstPtr();
|
||||
size_t nextChar = closeBrace+1;
|
||||
if(nextChar>= request.size()) nextChar = string::npos;
|
||||
if(nextChar!=string::npos) {
|
||||
message = request + " syntax error " + request[nextChar] + " after } illegal";
|
||||
return StructureConstPtr();
|
||||
}
|
||||
StructureConstPtr subField = fieldCreate->createStructure();
|
||||
string subRequest = request.substr(openBrace+1,closeBrace-openBrace-1);
|
||||
subField = createFieldRequest(subField,subRequest);
|
||||
if(subField==NULL) return subField;
|
||||
parent = fieldCreate->appendField(parent,fieldName,subField);
|
||||
return parent;
|
||||
}
|
||||
|
||||
// [ is before brace or .
|
||||
if(openBracket!=string::npos
|
||||
&& (openBrace==string::npos || openBracket<openBrace) )
|
||||
{
|
||||
string fieldName = request.substr(0,openBracket);
|
||||
size_t closeBracket = findMatchingBracket(request,openBracket);
|
||||
if(closeBracket==string::npos) return StructureConstPtr();
|
||||
size_t nextChar = closeBracket+1;
|
||||
if(nextChar>= request.size()) nextChar = string::npos;
|
||||
if(nextChar==string::npos) {
|
||||
StringArray fieldNames(1);
|
||||
FieldConstPtrArray fields(1);
|
||||
fieldNames[0] = "_options";
|
||||
fields[0] = createRequestOptions(
|
||||
request.substr(openBracket+1,closeBracket-openBracket-1));
|
||||
StructureConstPtr subField = fieldCreate->createStructure(fieldNames,fields);
|
||||
parent = fieldCreate->appendField(parent,fieldName,subField);
|
||||
return parent;
|
||||
}
|
||||
if(request[nextChar]=='.') {
|
||||
StructureConstPtr subField = fieldCreate->createStructure();
|
||||
subField = createSubFieldRequest(subField,request.substr(nextChar+1));
|
||||
if(subField==NULL) return StructureConstPtr();
|
||||
if(subField->getNumberFields()!=1) {
|
||||
message = request + " logic error createSubFieldRequest openBracket subField";
|
||||
return StructureConstPtr();
|
||||
}
|
||||
StringArray fieldNames(2);
|
||||
FieldConstPtrArray fields(2);
|
||||
fieldNames[0] = "_options";
|
||||
fields[0] = createRequestOptions(
|
||||
request.substr(openBracket+1,closeBracket-openBracket-1));
|
||||
fieldNames[1] = subField->getFieldNames()[0];
|
||||
fields[1] = subField;
|
||||
subField = fieldCreate->createStructure(fieldNames,fields);
|
||||
parent = fieldCreate->appendField(parent,fieldName,subField);
|
||||
return parent;
|
||||
}
|
||||
if(request[nextChar]=='{') {
|
||||
size_t closeBrace = findMatchingBrace(request,openBrace,1);
|
||||
if(closeBrace==string::npos) return StructureConstPtr();
|
||||
StructureConstPtr subField = fieldCreate->createStructure();
|
||||
string subRequest = request.substr(openBrace+1,closeBrace-openBrace-1);
|
||||
subField = createFieldRequest(subField,subRequest);
|
||||
if(subField==NULL) return subField;
|
||||
size_t numSub = subField->getNumberFields();
|
||||
StringArray fieldNames(numSub + 1);
|
||||
FieldConstPtrArray fields(numSub+1);
|
||||
fieldNames[0] = "_options";
|
||||
fields[0] = createRequestOptions(
|
||||
request.substr(openBracket+1,closeBracket-openBracket-1));
|
||||
StringArray subNames = subField->getFieldNames();
|
||||
FieldConstPtrArray subFields = subField->getFields();
|
||||
for(size_t i=0; i<numSub; ++i) {
|
||||
fieldNames[i+1] = subNames[i];
|
||||
fields[i+1] = subFields[i];
|
||||
}
|
||||
subField = fieldCreate->appendFields(parent,fieldNames,fields);
|
||||
parent = fieldCreate->appendField(parent,fieldName,subField);
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
message = request + " logic error createSubFieldRequest";
|
||||
return StructureConstPtr();
|
||||
Node node("_options");
|
||||
node.nodes = top;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
StructureConstPtr createFieldRequest(
|
||||
StructureConstPtr parent,
|
||||
string request)
|
||||
void createSubNode(Node &node,string const & crequest)
|
||||
{
|
||||
size_t length = request.length();
|
||||
if(length<=0) return parent;
|
||||
size_t end = findEndField(request);
|
||||
if(end==string::npos) return StructureConstPtr();
|
||||
StringArray fieldNames;
|
||||
FieldConstPtrArray fields;
|
||||
StructureConstPtr subField = fieldCreate->createStructure();
|
||||
subField = createSubFieldRequest(subField,request.substr(0,end));
|
||||
if(subField==NULL) return subField;
|
||||
fieldNames.push_back(subField->getFieldNames()[0]);
|
||||
fields.push_back(subField->getFields()[0]);
|
||||
if(end!=length) {
|
||||
if(request[end]!=',') {
|
||||
message = request;
|
||||
message += " expected char ";
|
||||
message += length;
|
||||
message += " to be ,";
|
||||
return StructureConstPtr();
|
||||
}
|
||||
StructureConstPtr nextSubField = fieldCreate->createStructure();
|
||||
nextSubField = createFieldRequest(nextSubField,request.substr(end+1));
|
||||
if(nextSubField==NULL) return nextSubField;
|
||||
size_t numFields = nextSubField->getNumberFields();
|
||||
StringArray subNames = nextSubField->getFieldNames();
|
||||
FieldConstPtrArray subFields = nextSubField->getFields();
|
||||
for(size_t i=0; i<numFields; ++i) {
|
||||
fieldNames.push_back(subNames[i]);
|
||||
fields.push_back(subFields[i]);
|
||||
}
|
||||
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;}
|
||||
}
|
||||
parent = fieldCreate->appendFields(parent,fieldNames,fields);
|
||||
return parent;
|
||||
}
|
||||
|
||||
void initSubFieldOptions(
|
||||
PVStructurePtr const & pvParent,
|
||||
string request)
|
||||
{
|
||||
if(request.length()<=0) return;
|
||||
size_t period = request.find('.');
|
||||
size_t openBracket = request.find('[');
|
||||
size_t openBrace = request.find('{');
|
||||
// name only
|
||||
if(period==string::npos
|
||||
&& openBracket==string::npos
|
||||
&& openBrace==string::npos)
|
||||
{
|
||||
return;
|
||||
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];
|
||||
}
|
||||
|
||||
// period is first
|
||||
if(period!=string::npos
|
||||
&& (openBracket==string::npos || period<openBracket)
|
||||
&& (openBrace==string::npos || period<openBrace) )
|
||||
{
|
||||
PVStructurePtr pvSubField = static_pointer_cast<PVStructure>(pvParent->getPVFields()[0]);
|
||||
initSubFieldOptions(pvSubField,request.substr(period+1));
|
||||
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;
|
||||
}
|
||||
|
||||
// brace before [ or .
|
||||
if(openBrace!=string::npos
|
||||
&& (openBracket==string::npos || openBrace<openBracket) )
|
||||
{
|
||||
PVStructurePtr pvSubField = static_pointer_cast<PVStructure>(pvParent->getPVFields()[0]);
|
||||
size_t closeBrace = findMatchingBrace(request,openBrace,1);
|
||||
string subRequest = request.substr(openBrace+1,closeBrace-openBrace-1);
|
||||
initFieldOptions(pvSubField,subRequest);
|
||||
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;
|
||||
}
|
||||
PVStructurePtr pvOptions = pvParent->getSubField<PVStructure>("_options");
|
||||
if(pvOptions==NULL) throw std::logic_error("initSubFieldOptions pvOptions NULL");
|
||||
size_t closeBracket = findMatchingBracket(request,openBracket);
|
||||
initRequestOptions(pvOptions,request.substr(openBracket+1,closeBracket-openBracket-1));
|
||||
size_t nextChar = closeBracket+1;
|
||||
if(nextChar>= request.size()) nextChar = string::npos;
|
||||
if(nextChar==string::npos) return;
|
||||
if(request[nextChar]=='.') {
|
||||
PVStructurePtr pvSubField = static_pointer_cast<PVStructure>(pvParent->getPVFields()[1]);
|
||||
initSubFieldOptions(pvSubField,request.substr(nextChar+1));
|
||||
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(request[nextChar]!='{') throw std::logic_error("initSubFieldOptions request[nextChar]!='{'");
|
||||
size_t closeBrace = findMatchingBrace(request,openBrace,1);
|
||||
const PVFieldPtrArray &pvFields = pvParent->getPVFields();
|
||||
string subRequest = request.substr(openBrace+1,closeBrace-openBrace-1);
|
||||
for(size_t i=1; i<pvFields.size(); ++i) {
|
||||
PVStructurePtr pvSubField = static_pointer_cast<PVStructure>(pvFields[i]);
|
||||
size_t comma = subRequest.find(',');
|
||||
initSubFieldOptions(pvSubField, subRequest.substr(0,comma-1));
|
||||
subRequest = subRequest.substr(comma+1);
|
||||
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");
|
||||
}
|
||||
|
||||
void initFieldOptions(
|
||||
PVStructurePtr const & pvParent,
|
||||
string request)
|
||||
FieldConstPtr createSubStructure(vector<Node> & nodes)
|
||||
{
|
||||
if(request.find('[')==string::npos) return;
|
||||
size_t num = pvParent->getStructure()->getNumberFields();
|
||||
if(num==0) return;
|
||||
if(num==1) {
|
||||
initSubFieldOptions(pvParent,request);
|
||||
return;
|
||||
}
|
||||
size_t end = findEndField(request);
|
||||
size_t start = 0;
|
||||
size_t num = nodes.size();
|
||||
StringArray names(num);
|
||||
FieldConstPtrArray fields(num);
|
||||
for(size_t i=0; i<num; ++i) {
|
||||
PVStructurePtr pvSub = static_pointer_cast<PVStructure>(pvParent->getPVFields()[i]);
|
||||
string subRequest = request.substr(start, end - start);
|
||||
initSubFieldOptions(pvSub,subRequest);
|
||||
if(i==num-1) break;
|
||||
start = end +1;
|
||||
string xxx = request.substr(start);
|
||||
end += findEndField(xxx) + 1;
|
||||
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 PVStructure::shared_pointer createRequest(
|
||||
virtual PVStructurePtr createRequest(
|
||||
string const & crequest)
|
||||
{
|
||||
string request = crequest;
|
||||
StructureConstPtr topStructure = fieldCreate->createStructure();
|
||||
|
||||
if (!request.empty()) removeBlanks(request);
|
||||
if (request.empty())
|
||||
{
|
||||
PVFieldPtrArray pvFields;
|
||||
StringArray fieldNames;
|
||||
return pvDataCreate->createPVStructure(fieldNames,pvFields);
|
||||
}
|
||||
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(" + crequest + ")";
|
||||
offsetField = request.find("field(");
|
||||
}
|
||||
if (offsetRecord != string::npos) {
|
||||
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();
|
||||
}
|
||||
StructureConstPtr structure = createRequestOptions(
|
||||
request.substr(openBracket+1,closeBracket-openBracket-1));
|
||||
if(structure==NULL)
|
||||
try {
|
||||
string request = crequest;
|
||||
if (!request.empty()) removeBlanks(request);
|
||||
if (request.empty())
|
||||
{
|
||||
return PVStructurePtr();
|
||||
return pvDataCreate->createPVStructure(fieldCreate->createStructure());
|
||||
}
|
||||
topStructure = fieldCreate->appendField(topStructure,"record",structure);
|
||||
}
|
||||
if (offsetField != string::npos) {
|
||||
size_t openBrace = request.find('(', offsetField);
|
||||
size_t closeBrace = request.find(')', openBrace);
|
||||
if(closeBrace == string::npos) {
|
||||
message = request.substr(offsetField)
|
||||
+ " field( does not have matching )";
|
||||
return PVStructurePtr();
|
||||
}
|
||||
StructureConstPtr structure = fieldCreate->createStructure();
|
||||
structure = createFieldRequest(structure,request.substr(openBrace+1,closeBrace-openBrace-1));
|
||||
if(structure==NULL)
|
||||
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();
|
||||
}
|
||||
topStructure = fieldCreate->appendField(topStructure,"field",structure);
|
||||
}
|
||||
if (offsetPutField != string::npos) {
|
||||
size_t openBrace = request.find('(', offsetPutField);
|
||||
size_t closeBrace = request.find(')', openBrace);
|
||||
if(closeBrace == string::npos) {
|
||||
message = request.substr(offsetField)
|
||||
+ " putField( does not have matching )";
|
||||
if(numBrace!=0) {
|
||||
ostringstream oss;
|
||||
oss << "mismatched {} " << numBrace;
|
||||
message = oss.str();
|
||||
return PVStructurePtr();
|
||||
}
|
||||
StructureConstPtr structure = fieldCreate->createStructure();
|
||||
structure = createFieldRequest(structure,request.substr(openBrace+1,closeBrace-openBrace-1));
|
||||
if(structure==NULL)
|
||||
{
|
||||
if(numBracket!=0) {
|
||||
ostringstream oss;
|
||||
oss << "mismatched [] " << numBracket;
|
||||
message = oss.str();
|
||||
return PVStructurePtr();
|
||||
}
|
||||
topStructure = fieldCreate->appendField(topStructure,"putField",structure);
|
||||
}
|
||||
if (offsetGetField != string::npos) {
|
||||
size_t openBrace = request.find('(', offsetGetField);
|
||||
size_t closeBrace = request.find(')', openBrace);
|
||||
if(closeBrace == string::npos) {
|
||||
message = request.substr(offsetField)
|
||||
+ " getField( does not have matching )";
|
||||
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();
|
||||
}
|
||||
StructureConstPtr structure = fieldCreate->createStructure();
|
||||
structure = createFieldRequest(structure,request.substr(openBrace+1,closeBrace-openBrace-1));
|
||||
if(structure==NULL)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
topStructure = fieldCreate->appendField(topStructure,"getField",structure);
|
||||
}
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
|
||||
if (offsetRecord != string::npos) {
|
||||
size_t openBracket = request.find('[', offsetRecord);
|
||||
size_t closeBracket = request.find(']', openBracket);
|
||||
initRequestOptions(
|
||||
pvStructure->getSubField<PVStructure>("record"),
|
||||
request.substr(openBracket+1,closeBracket-openBracket-1));
|
||||
}
|
||||
if (offsetField != string::npos) {
|
||||
size_t openParam = request.find('(', offsetField);
|
||||
size_t closeParam = request.find(')', openParam);
|
||||
PVStructurePtr pvSub = pvStructure->getSubField<PVStructure>("field");
|
||||
if(pvSub->getStructure()->getNumberFields()==1) {
|
||||
pvSub = static_pointer_cast<PVStructure>(pvSub->getPVFields()[0]);
|
||||
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);
|
||||
}
|
||||
if(pvSub!=NULL) initFieldOptions(pvSub,request.substr(openParam+1,closeParam-openParam-1));
|
||||
optionList.clear();
|
||||
return pvStructure;
|
||||
} catch (std::exception &e) {
|
||||
message = e.what();
|
||||
return PVStructurePtr();
|
||||
}
|
||||
if (offsetPutField != string::npos) {
|
||||
size_t openParam = request.find('(', offsetPutField);
|
||||
size_t closeParam = request.find(')', openParam);
|
||||
PVStructurePtr pvSub = pvStructure->getSubField<PVStructure>("putField");
|
||||
if(pvSub->getStructure()->getNumberFields()==1) {
|
||||
pvSub = static_pointer_cast<PVStructure>(pvSub->getPVFields()[0]);
|
||||
}
|
||||
if(pvSub!=NULL) initFieldOptions(pvSub,request.substr(openParam+1,closeParam-openParam-1));
|
||||
}
|
||||
if (offsetGetField != string::npos) {
|
||||
size_t openParam = request.find('(', offsetGetField);
|
||||
size_t closeParam = request.find(')', openParam);
|
||||
PVStructurePtr pvSub = pvStructure->getSubField<PVStructure>("getField");
|
||||
if(pvSub->getStructure()->getNumberFields()==1) {
|
||||
pvSub = static_pointer_cast<PVStructure>(pvSub->getPVFields()[0]);
|
||||
}
|
||||
if(pvSub!=NULL) initFieldOptions(pvSub,request.substr(openParam+1,closeParam-openParam-1));
|
||||
}
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
CreateRequest::shared_pointer CreateRequest::create()
|
||||
|
||||
@@ -68,9 +68,9 @@ PVCopyPtr PVCopy::create(
|
||||
if(structureName.size()>0) {
|
||||
if(pvRequest->getStructure()->getNumberFields()>0) {
|
||||
pvStructure = pvRequest->getStructureField(structureName);
|
||||
if(pvStructure.get()==NULL) return NULLPVCopy;
|
||||
if(!pvStructure) return NULLPVCopy;
|
||||
}
|
||||
} else if(pvStructure->getSubField("field")!=NULL) {
|
||||
} else if(pvStructure->getSubField("field")) {
|
||||
pvStructure = pvRequest->getStructureField("field");
|
||||
}
|
||||
PVCopyPtr pvCopy = PVCopyPtr(new PVCopy(pvMaster));
|
||||
@@ -118,7 +118,7 @@ StructureConstPtr PVCopy::getStructure()
|
||||
|
||||
PVStructurePtr PVCopy::createPVStructure()
|
||||
{
|
||||
if(cacheInitStructure.get()!=NULL) {
|
||||
if(cacheInitStructure) {
|
||||
PVStructurePtr save = cacheInitStructure;
|
||||
cacheInitStructure.reset();
|
||||
return save;
|
||||
@@ -174,7 +174,7 @@ size_t PVCopy::getCopyOffset(PVFieldPtr const &masterPVField)
|
||||
}
|
||||
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
|
||||
CopyMasterNodePtr masterNode = getCopyOffset(node,masterPVField);
|
||||
if(masterNode.get()!=NULL) return masterNode->structureOffset;
|
||||
if(masterNode) return masterNode->structureOffset;
|
||||
return string::npos;
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ size_t PVCopy::getCopyOffset(
|
||||
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
|
||||
masterNode = getCopyOffset(node,masterPVField);
|
||||
}
|
||||
if(masterNode.get()==NULL) return string::npos;
|
||||
if(!masterNode) return string::npos;
|
||||
size_t diff = masterPVField->getFieldOffset()
|
||||
- masterPVStructure->getFieldOffset();
|
||||
return masterNode->structureOffset + diff;
|
||||
@@ -205,7 +205,7 @@ PVFieldPtr PVCopy::getMasterPVField(size_t structureOffset)
|
||||
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
|
||||
masterNode = getMasterNode(node,structureOffset);
|
||||
}
|
||||
if(masterNode.get()==NULL) {
|
||||
if(!masterNode) {
|
||||
throw std::invalid_argument(
|
||||
"PVCopy::getMasterPVField: setstructureOffset not valid");
|
||||
}
|
||||
@@ -299,7 +299,7 @@ void PVCopy::dump(string *builder,CopyNodePtr const &node,int indentLevel)
|
||||
ss << " nfields " << node->nfields;
|
||||
*builder += ss.str();
|
||||
PVStructurePtr options = node->options;
|
||||
if(options.get()!=NULL) {
|
||||
if(options) {
|
||||
getConvert()->newLine(builder,indentLevel +1);
|
||||
|
||||
// TODO !!! ugly
|
||||
@@ -338,7 +338,7 @@ bool PVCopy::init(epics::pvData::PVStructurePtr const &pvRequest)
|
||||
if(len==string::npos) entireMaster = true;
|
||||
if(len==0) entireMaster = true;
|
||||
PVStructurePtr pvOptions;
|
||||
if(len==1 && pvRequest->getSubField("_options")!=NULL) {
|
||||
if(len==1 && pvRequest->getSubField("_options")) {
|
||||
pvOptions = pvRequest->getStructureField("_options");
|
||||
}
|
||||
if(entireMaster) {
|
||||
@@ -353,7 +353,7 @@ bool PVCopy::init(epics::pvData::PVStructurePtr const &pvRequest)
|
||||
return true;
|
||||
}
|
||||
structure = createStructure(pvMasterStructure,pvRequest);
|
||||
if(structure==NULL) return false;
|
||||
if(!structure) return false;
|
||||
cacheInitStructure = createPVStructure();
|
||||
headNode = createStructureNodes(
|
||||
pvMaster,
|
||||
@@ -387,7 +387,7 @@ StructureConstPtr PVCopy::createStructure(
|
||||
for(size_t i=0; i<length; ++i) {
|
||||
string const &fieldName = fromRequestFieldNames[i];
|
||||
PVFieldPtr pvMasterField = pvMaster->getSubField(fieldName);
|
||||
if(pvMasterField==NULL) continue;
|
||||
if(!pvMasterField) continue;
|
||||
FieldConstPtr field = pvMasterField->getField();
|
||||
if(field->getType()==epics::pvData::structure) {
|
||||
PVStructurePtr pvRequestStructure = static_pointer_cast<PVStructure>(
|
||||
@@ -423,7 +423,7 @@ CopyNodePtr PVCopy::createStructureNodes(
|
||||
PVFieldPtrArray const & copyPVFields = pvFromCopy->getPVFields();
|
||||
PVStructurePtr pvOptions;
|
||||
PVFieldPtr pvField = pvFromRequest->getSubField("_options");
|
||||
if(pvField!=NULL) pvOptions = static_pointer_cast<PVStructure>(pvField);
|
||||
if(pvField) pvOptions = static_pointer_cast<PVStructure>(pvField);
|
||||
size_t number = copyPVFields.size();
|
||||
CopyNodePtrArrayPtr nodes(new CopyNodePtrArray());
|
||||
nodes->reserve(number);
|
||||
@@ -435,7 +435,7 @@ CopyNodePtr PVCopy::createStructureNodes(
|
||||
pvFromRequest->getSubField(fieldName));
|
||||
PVStructurePtr pvSubFieldOptions;
|
||||
PVFieldPtr pvField = requestPVStructure->getSubField("_options");
|
||||
if(pvField!=NULL) pvSubFieldOptions = static_pointer_cast<PVStructure>(pvField);
|
||||
if(pvField) pvSubFieldOptions = static_pointer_cast<PVStructure>(pvField);
|
||||
PVFieldPtr pvMasterField;
|
||||
PVFieldPtrArray const & pvMasterFields = pvMasterStructure->getPVFields();
|
||||
for(size_t j=0; i<pvMasterFields.size(); j++ ) {
|
||||
@@ -445,7 +445,7 @@ CopyNodePtr PVCopy::createStructureNodes(
|
||||
}
|
||||
}
|
||||
size_t numberRequest = requestPVStructure->getPVFields().size();
|
||||
if(pvSubFieldOptions!=NULL) numberRequest--;
|
||||
if(pvSubFieldOptions) numberRequest--;
|
||||
if(numberRequest>0) {
|
||||
nodes->push_back(createStructureNodes(
|
||||
static_pointer_cast<PVStructure>(pvMasterField),
|
||||
@@ -621,7 +621,7 @@ CopyMasterNodePtr PVCopy::getCopyOffset(
|
||||
static_pointer_cast<CopyStructureNode>(node);
|
||||
CopyMasterNodePtr masterNode =
|
||||
getCopyOffset(subNode,masterPVField);
|
||||
if(masterNode.get()!=NULL) return masterNode;
|
||||
if(masterNode) return masterNode;
|
||||
}
|
||||
}
|
||||
return NULLCopyMasterNode;
|
||||
|
||||
@@ -134,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 {
|
||||
@@ -244,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;
|
||||
@@ -297,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,7 +18,6 @@
|
||||
#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;
|
||||
@@ -51,7 +50,8 @@ void Convert::getString(string *buf,PVField const *pvField,int /*indentLevel*/)
|
||||
{
|
||||
// TODO indextLevel ignored
|
||||
std::ostringstream strm;
|
||||
strm << pvField->dumpValue(strm) << std::endl;
|
||||
pvField->dumpValue(strm);
|
||||
strm << std::endl;
|
||||
// PrinterPlain p;
|
||||
// p.setStream(strm);
|
||||
// p.print(*pvField);
|
||||
@@ -462,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
|
||||
to->set(from->getSelectedFieldName(),from->get());
|
||||
to->set(from->getSelectedIndex(),from->get());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/lock.h>
|
||||
@@ -80,7 +81,7 @@ string Scalar::getID() const
|
||||
return idScalarLUT[scalarType];
|
||||
}
|
||||
|
||||
int8 Scalar::getTypeCodeLUT() const
|
||||
int8 Scalar::getTypeCodeLUT(ScalarType scalarType)
|
||||
{
|
||||
static const int8 typeCodeLUT[] = {
|
||||
0x00, // pvBoolean
|
||||
@@ -88,10 +89,10 @@ int8 Scalar::getTypeCodeLUT() const
|
||||
0x21, // pvShort
|
||||
0x22, // pvInt
|
||||
0x23, // pvLong
|
||||
0x28, // pvUByte
|
||||
0x29, // pvUShort
|
||||
0x2A, // pvUInt
|
||||
0x2B, // pvULong
|
||||
0x24, // pvUByte
|
||||
0x25, // pvUShort
|
||||
0x26, // pvUInt
|
||||
0x27, // pvULong
|
||||
0x42, // pvFloat
|
||||
0x43, // pvDouble
|
||||
0x60 // pvString
|
||||
@@ -102,7 +103,7 @@ int8 Scalar::getTypeCodeLUT() const
|
||||
|
||||
void Scalar::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte(getTypeCodeLUT());
|
||||
buffer->putByte(getTypeCodeLUT(scalarType));
|
||||
}
|
||||
|
||||
void Scalar::deserialize(ByteBuffer* /*buffer*/, DeserializableControl* /*control*/) {
|
||||
@@ -110,6 +111,38 @@ void Scalar::deserialize(ByteBuffer* /*buffer*/, DeserializableControl* /*contro
|
||||
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
std::string BoundedString::getID() const
|
||||
{
|
||||
std::ostringstream id;
|
||||
id << Scalar::getID() << '(' << maxLength << ')';
|
||||
return id.str();
|
||||
}
|
||||
|
||||
void BoundedString::serialize(ByteBuffer *buffer, SerializableControl *control) const
|
||||
{
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte(0x83);
|
||||
SerializeHelper::writeSize(maxLength, buffer, control);
|
||||
}
|
||||
|
||||
std::size_t BoundedString::getMaximumLength() const
|
||||
{
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
BoundedString::BoundedString(std::size_t maxStringLength) :
|
||||
Scalar(pvString), maxLength(maxStringLength)
|
||||
{
|
||||
if (maxLength == 0)
|
||||
throw std::invalid_argument("maxLength == 0");
|
||||
}
|
||||
|
||||
BoundedString::~BoundedString() {}
|
||||
|
||||
|
||||
static string emptyStringtring;
|
||||
|
||||
static void serializeStructureField(const Structure* structure, ByteBuffer* buffer, SerializableControl* control)
|
||||
@@ -198,7 +231,8 @@ Array::Array(Type type)
|
||||
Array::~Array() {}
|
||||
|
||||
ScalarArray::ScalarArray(ScalarType elementType)
|
||||
: Array(scalarArray),elementType(elementType)
|
||||
: Array(scalarArray),
|
||||
elementType(elementType)
|
||||
{
|
||||
if(elementType<0 || elementType>MAX_SCALAR_TYPE)
|
||||
throw std::invalid_argument("Can't construct ScalarArray from invalid ScalarType");
|
||||
@@ -206,31 +240,12 @@ ScalarArray::ScalarArray(ScalarType elementType)
|
||||
|
||||
ScalarArray::~ScalarArray() {}
|
||||
|
||||
int8 ScalarArray::getTypeCodeLUT() const
|
||||
{
|
||||
static const int8 typeCodeLUT[] = {
|
||||
0x00, // pvBoolean
|
||||
0x20, // pvByte
|
||||
0x21, // pvShort
|
||||
0x22, // pvInt
|
||||
0x23, // pvLong
|
||||
0x28, // pvUByte
|
||||
0x29, // pvUShort
|
||||
0x2A, // pvUInt
|
||||
0x2B, // pvULong
|
||||
0x42, // pvFloat
|
||||
0x43, // pvDouble
|
||||
0x60 // pvString
|
||||
};
|
||||
return typeCodeLUT[elementType];
|
||||
}
|
||||
|
||||
const string ScalarArray::getIDScalarArrayLUT() const
|
||||
{
|
||||
static const string idScalarArrayLUT[] = {
|
||||
"boolean[]", // pvBoolean
|
||||
"byte[]", // pvByte
|
||||
"short[]", // pvShort
|
||||
"boolean[]", // pvBoolean
|
||||
"byte[]", // pvByte
|
||||
"short[]", // pvShort
|
||||
"int[]", // pvInt
|
||||
"long[]", // pvLong
|
||||
"ubyte[]", // pvUByte
|
||||
@@ -256,13 +271,59 @@ std::ostream& ScalarArray::dump(std::ostream& o) const
|
||||
|
||||
void ScalarArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte((int8)0x10 | getTypeCodeLUT());
|
||||
buffer->putByte((int8)0x08 | Scalar::getTypeCodeLUT(elementType));
|
||||
}
|
||||
|
||||
void ScalarArray::deserialize(ByteBuffer* /*buffer*/, DeserializableControl* /*control*/) {
|
||||
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
|
||||
}
|
||||
|
||||
|
||||
BoundedScalarArray::~BoundedScalarArray() {}
|
||||
|
||||
BoundedScalarArray::BoundedScalarArray(ScalarType elementType, size_t size)
|
||||
: ScalarArray(elementType),
|
||||
size(size)
|
||||
{
|
||||
}
|
||||
|
||||
string BoundedScalarArray::getID() const
|
||||
{
|
||||
char buffer[32];
|
||||
sprintf(buffer, "%s<%zu>", ScalarTypeFunc::name(getElementType()), size);
|
||||
return string(buffer);
|
||||
}
|
||||
|
||||
void BoundedScalarArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte((int8)0x10 | Scalar::getTypeCodeLUT(getElementType()));
|
||||
SerializeHelper::writeSize(size, buffer, control);
|
||||
}
|
||||
|
||||
|
||||
FixedScalarArray::~FixedScalarArray() {}
|
||||
|
||||
FixedScalarArray::FixedScalarArray(ScalarType elementType, size_t size)
|
||||
: ScalarArray(elementType),
|
||||
size(size)
|
||||
{
|
||||
}
|
||||
|
||||
string FixedScalarArray::getID() const
|
||||
{
|
||||
char buffer[32];
|
||||
sprintf(buffer, "%s[%zu]", ScalarTypeFunc::name(getElementType()), size);
|
||||
return string(buffer);
|
||||
}
|
||||
|
||||
void FixedScalarArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte((int8)0x18 | Scalar::getTypeCodeLUT(getElementType()));
|
||||
SerializeHelper::writeSize(size, buffer, control);
|
||||
}
|
||||
|
||||
|
||||
|
||||
StructureArray::StructureArray(StructureConstPtr const & structure)
|
||||
: Array(structureArray),pstructure(structure)
|
||||
{
|
||||
@@ -289,7 +350,7 @@ std::ostream& StructureArray::dump(std::ostream& o) const
|
||||
|
||||
void StructureArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte((int8)0x90);
|
||||
buffer->putByte((int8)0x88);
|
||||
control->cachedSerialize(pstructure, buffer);
|
||||
}
|
||||
|
||||
@@ -326,11 +387,11 @@ void UnionArray::serialize(ByteBuffer *buffer, SerializableControl *control) con
|
||||
if (punion->isVariant())
|
||||
{
|
||||
// unrestricted/variant union
|
||||
buffer->putByte((int8)0x92);
|
||||
buffer->putByte((int8)0x8A);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer->putByte((int8)0x91);
|
||||
buffer->putByte((int8)0x89);
|
||||
control->cachedSerialize(punion, buffer);
|
||||
}
|
||||
}
|
||||
@@ -552,7 +613,7 @@ size_t Union::getFieldIndex(string const &fieldName) const {
|
||||
|
||||
std::ostream& Union::dump(std::ostream& o) const
|
||||
{
|
||||
o << getID() << std::endl;
|
||||
o << format::indent() << getID() << std::endl;
|
||||
{
|
||||
format::indent_scope s(o);
|
||||
dumpFields(o);
|
||||
@@ -655,6 +716,12 @@ FieldBuilderPtr FieldBuilder::add(string const & name, ScalarType scalarType)
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
FieldBuilderPtr FieldBuilder::addBoundedString(std::string const & name, std::size_t maxLength)
|
||||
{
|
||||
fields.push_back(fieldCreate->createBoundedString(maxLength)); fieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
FieldBuilderPtr FieldBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
fields.push_back(field); fieldNames.push_back(name);
|
||||
@@ -667,6 +734,18 @@ FieldBuilderPtr FieldBuilder::addArray(string const & name, ScalarType scalarTyp
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
FieldBuilderPtr FieldBuilder::addFixedArray(string const & name, ScalarType scalarType, size_t size)
|
||||
{
|
||||
fields.push_back(fieldCreate->createFixedScalarArray(scalarType, size)); fieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
FieldBuilderPtr FieldBuilder::addBoundedArray(string const & name, ScalarType scalarType, size_t size)
|
||||
{
|
||||
fields.push_back(fieldCreate->createBoundedScalarArray(scalarType, size)); fieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
FieldBuilderPtr FieldBuilder::addArray(string const & name, FieldConstPtr const & element)
|
||||
{
|
||||
switch (element->getType())
|
||||
@@ -678,10 +757,17 @@ FieldBuilderPtr FieldBuilder::addArray(string const & name, FieldConstPtr const
|
||||
fields.push_back(fieldCreate->createUnionArray(static_pointer_cast<const Union>(element)));
|
||||
break;
|
||||
case scalar:
|
||||
|
||||
if (std::tr1::dynamic_pointer_cast<const BoundedString>(element).get())
|
||||
throw std::invalid_argument("bounded string arrays are not supported");
|
||||
|
||||
fields.push_back(fieldCreate->createScalarArray(static_pointer_cast<const Scalar>(element)->getScalarType()));
|
||||
break;
|
||||
// scalarArray?
|
||||
default:
|
||||
throw std::invalid_argument("unsupported array element type:" + element->getType());
|
||||
std::ostringstream msg("unsupported array element type: ");
|
||||
msg << element->getType();
|
||||
throw std::invalid_argument(msg.str());
|
||||
}
|
||||
|
||||
fieldNames.push_back(name);
|
||||
@@ -707,7 +793,11 @@ FieldConstPtr FieldBuilder::createFieldInternal(Type type)
|
||||
fieldCreate->createUnion(fieldNames, fields);
|
||||
}
|
||||
else
|
||||
throw std::invalid_argument("unsupported type: " + type);
|
||||
{
|
||||
std::ostringstream msg("unsupported type: ");
|
||||
msg << type;
|
||||
throw std::invalid_argument(msg.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -780,7 +870,15 @@ ScalarConstPtr FieldCreate::createScalar(ScalarType scalarType) const
|
||||
|
||||
return scalars[scalarType];
|
||||
}
|
||||
|
||||
|
||||
BoundedStringConstPtr FieldCreate::createBoundedString(std::size_t maxLength) const
|
||||
{
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<BoundedString> s(new BoundedString(maxLength), Field::Deleter());
|
||||
BoundedStringConstPtr sa = s;
|
||||
return sa;
|
||||
}
|
||||
|
||||
ScalarArrayConstPtr FieldCreate::createScalarArray(ScalarType elementType) const
|
||||
{
|
||||
if(elementType<0 || elementType>MAX_SCALAR_TYPE)
|
||||
@@ -789,6 +887,28 @@ ScalarArrayConstPtr FieldCreate::createScalarArray(ScalarType elementType) const
|
||||
return scalarArrays[elementType];
|
||||
}
|
||||
|
||||
ScalarArrayConstPtr FieldCreate::createFixedScalarArray(ScalarType elementType, size_t size) const
|
||||
{
|
||||
if(elementType<0 || elementType>MAX_SCALAR_TYPE)
|
||||
throw std::invalid_argument("Can't construct ScalarArray from invalid ScalarType");
|
||||
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<ScalarArray> s(new FixedScalarArray(elementType, size), Field::Deleter());
|
||||
ScalarArrayConstPtr sa = s;
|
||||
return sa;
|
||||
}
|
||||
|
||||
ScalarArrayConstPtr FieldCreate::createBoundedScalarArray(ScalarType elementType, size_t size) const
|
||||
{
|
||||
if(elementType<0 || elementType>MAX_SCALAR_TYPE)
|
||||
throw std::invalid_argument("Can't construct ScalarArray from invalid ScalarType");
|
||||
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<ScalarArray> s(new BoundedScalarArray(elementType, size), Field::Deleter());
|
||||
ScalarArrayConstPtr sa = s;
|
||||
return sa;
|
||||
}
|
||||
|
||||
StructureConstPtr FieldCreate::createStructure () const
|
||||
{
|
||||
StringArray fieldNames;
|
||||
@@ -799,8 +919,9 @@ StructureConstPtr FieldCreate::createStructure () const
|
||||
StructureConstPtr FieldCreate::createStructure (
|
||||
StringArray const & fieldNames,FieldConstPtrArray const & fields) const
|
||||
{
|
||||
StructureConstPtr structure(
|
||||
new Structure(fieldNames,fields), Field::Deleter());
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<Structure> sp(new Structure(fieldNames,fields), Field::Deleter());
|
||||
StructureConstPtr structure = sp;
|
||||
return structure;
|
||||
}
|
||||
|
||||
@@ -809,24 +930,27 @@ StructureConstPtr FieldCreate::createStructure (
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const
|
||||
{
|
||||
StructureConstPtr structure(
|
||||
new Structure(fieldNames,fields,id), Field::Deleter());
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<Structure> sp(new Structure(fieldNames,fields,id), Field::Deleter());
|
||||
StructureConstPtr structure = sp;
|
||||
return structure;
|
||||
}
|
||||
|
||||
StructureArrayConstPtr FieldCreate::createStructureArray(
|
||||
StructureConstPtr const & structure) const
|
||||
{
|
||||
StructureArrayConstPtr structureArray(
|
||||
new StructureArray(structure), Field::Deleter());
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<StructureArray> sp(new StructureArray(structure), Field::Deleter());
|
||||
StructureArrayConstPtr structureArray = sp;
|
||||
return structureArray;
|
||||
}
|
||||
|
||||
UnionConstPtr FieldCreate::createUnion (
|
||||
StringArray const & fieldNames,FieldConstPtrArray const & fields) const
|
||||
{
|
||||
UnionConstPtr punion(
|
||||
new Union(fieldNames,fields), Field::Deleter());
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<Union> sp(new Union(fieldNames,fields), Field::Deleter());
|
||||
UnionConstPtr punion = sp;
|
||||
return punion;
|
||||
}
|
||||
|
||||
@@ -835,8 +959,9 @@ UnionConstPtr FieldCreate::createUnion (
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const
|
||||
{
|
||||
UnionConstPtr punion(
|
||||
new Union(fieldNames,fields,id), Field::Deleter());
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<Union> sp(new Union(fieldNames,fields,id), Field::Deleter());
|
||||
UnionConstPtr punion = sp;
|
||||
return punion;
|
||||
}
|
||||
|
||||
@@ -848,8 +973,9 @@ UnionConstPtr FieldCreate::createVariantUnion () const
|
||||
UnionArrayConstPtr FieldCreate::createUnionArray(
|
||||
UnionConstPtr const & punion) const
|
||||
{
|
||||
UnionArrayConstPtr unionArray(
|
||||
new UnionArray(punion), Field::Deleter());
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<UnionArray> sp(new UnionArray(punion), Field::Deleter());
|
||||
UnionArrayConstPtr unionArray = sp;
|
||||
return unionArray;
|
||||
}
|
||||
|
||||
@@ -904,22 +1030,14 @@ static int decodeScalar(int8 code)
|
||||
{
|
||||
static const int integerLUT[] =
|
||||
{
|
||||
pvByte, // 8-bits
|
||||
pvShort, // 16-bits
|
||||
pvInt, // 32-bits
|
||||
pvLong, // 64-bits
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
pvByte, // 8-bits
|
||||
pvShort, // 16-bits
|
||||
pvInt, // 32-bits
|
||||
pvLong, // 64-bits
|
||||
pvUByte, // unsigned 8-bits
|
||||
pvUShort, // unsigned 16-bits
|
||||
pvUInt, // unsigned 32-bits
|
||||
pvULong, // unsigned 64-bits
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
pvULong // unsigned 64-bits
|
||||
};
|
||||
|
||||
static const int floatLUT[] =
|
||||
@@ -931,22 +1049,14 @@ static int decodeScalar(int8 code)
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
// bits 7-5
|
||||
switch (code >> 5)
|
||||
{
|
||||
case 0: return pvBoolean;
|
||||
case 1: return integerLUT[code & 0x0F];
|
||||
case 2: return floatLUT[code & 0x0F];
|
||||
case 1: return integerLUT[code & 0x07];
|
||||
case 2: return floatLUT[code & 0x07];
|
||||
case 3: return pvString;
|
||||
default: return -1;
|
||||
}
|
||||
@@ -959,8 +1069,9 @@ FieldConstPtr FieldCreate::deserialize(ByteBuffer* buffer, DeserializableControl
|
||||
if (code == -1)
|
||||
return FieldConstPtr();
|
||||
|
||||
int typeCode = code & 0xEF;
|
||||
bool notArray = ((code & 0x10) == 0);
|
||||
int typeCode = code & 0xE7;
|
||||
int scalarOrArray = code & 0x18;
|
||||
bool notArray = (scalarOrArray == 0);
|
||||
if (notArray)
|
||||
{
|
||||
if (typeCode < 0x80)
|
||||
@@ -986,33 +1097,90 @@ FieldConstPtr FieldCreate::deserialize(ByteBuffer* buffer, DeserializableControl
|
||||
// Type type = Type.union; variant union (aka any type)
|
||||
return variantUnion;
|
||||
}
|
||||
else if (typeCode == 0x83)
|
||||
{
|
||||
// TODO cache?
|
||||
// bounded string
|
||||
|
||||
size_t size = SerializeHelper::readSize(buffer, control);
|
||||
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<Field> sp(
|
||||
new BoundedString(size),
|
||||
Field::Deleter());
|
||||
FieldConstPtr p = sp;
|
||||
return p;
|
||||
}
|
||||
else
|
||||
throw std::invalid_argument("invalid type encoding");
|
||||
}
|
||||
else // array
|
||||
{
|
||||
bool isVariable = (scalarOrArray == 0x08);
|
||||
// bounded == 0x10;
|
||||
bool isFixed = (scalarOrArray == 0x18);
|
||||
|
||||
size_t size = (isVariable ? 0 : SerializeHelper::readSize(buffer, control));
|
||||
|
||||
if (typeCode < 0x80)
|
||||
{
|
||||
// Type type = Type.scalarArray;
|
||||
int scalarType = decodeScalar(code);
|
||||
if (scalarType == -1)
|
||||
throw std::invalid_argument("invalid scalarArray type encoding");
|
||||
return scalarArrays[scalarType];
|
||||
if (isVariable)
|
||||
return scalarArrays[scalarType];
|
||||
else if (isFixed)
|
||||
{
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<Field> sp(
|
||||
new FixedScalarArray(static_cast<epics::pvData::ScalarType>(scalarType), size),
|
||||
Field::Deleter());
|
||||
FieldConstPtr p = sp;
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<Field> sp(
|
||||
new BoundedScalarArray(static_cast<epics::pvData::ScalarType>(scalarType), size),
|
||||
Field::Deleter());
|
||||
FieldConstPtr p = sp;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
else if (typeCode == 0x80)
|
||||
{
|
||||
// TODO fixed and bounded array support
|
||||
if (!isVariable)
|
||||
throw std::invalid_argument("fixed and bounded structure array not supported");
|
||||
|
||||
// Type type = Type.structureArray;
|
||||
StructureConstPtr elementStructure = std::tr1::static_pointer_cast<const Structure>(control->cachedDeserialize(buffer));
|
||||
return FieldConstPtr(new StructureArray(elementStructure), Field::Deleter());
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<Field> sp(new StructureArray(elementStructure), Field::Deleter());
|
||||
FieldConstPtr p = sp;
|
||||
return p;
|
||||
}
|
||||
else if (typeCode == 0x81)
|
||||
{
|
||||
// TODO fixed and bounded array support
|
||||
if (!isVariable)
|
||||
throw std::invalid_argument("fixed and bounded structure array not supported");
|
||||
|
||||
// Type type = Type.unionArray;
|
||||
UnionConstPtr elementUnion = std::tr1::static_pointer_cast<const Union>(control->cachedDeserialize(buffer));
|
||||
return FieldConstPtr(new UnionArray(elementUnion), Field::Deleter());
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<Field> sp(new UnionArray(elementUnion), Field::Deleter());
|
||||
FieldConstPtr p = sp;
|
||||
return p;
|
||||
}
|
||||
else if (typeCode == 0x82)
|
||||
{
|
||||
// TODO fixed and bounded array support
|
||||
if (!isVariable)
|
||||
throw std::invalid_argument("fixed and bounded structure array not supported");
|
||||
|
||||
// Type type = Type.unionArray; variant union (aka any type)
|
||||
return variantUnionArray;
|
||||
}
|
||||
@@ -1037,11 +1205,24 @@ FieldCreate::FieldCreate()
|
||||
{
|
||||
for (int i = 0; i <= MAX_SCALAR_TYPE; i++)
|
||||
{
|
||||
scalars.push_back(ScalarConstPtr(new Scalar(static_cast<ScalarType>(i)), Field::Deleter()));
|
||||
scalarArrays.push_back(ScalarArrayConstPtr(new ScalarArray(static_cast<ScalarType>(i)), Field::Deleter()));
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<Scalar> sp(new Scalar(static_cast<ScalarType>(i)), Field::Deleter());
|
||||
ScalarConstPtr p = sp;
|
||||
scalars.push_back(p);
|
||||
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<ScalarArray> spa(new ScalarArray(static_cast<ScalarType>(i)), Field::Deleter());
|
||||
ScalarArrayConstPtr pa = spa;
|
||||
scalarArrays.push_back(spa);
|
||||
}
|
||||
variantUnion = UnionConstPtr(new Union(), Field::Deleter());
|
||||
variantUnionArray = UnionArrayConstPtr(new UnionArray(variantUnion), Field::Deleter());
|
||||
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<Union> su(new Union(), Field::Deleter());
|
||||
variantUnion = su;
|
||||
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<UnionArray> sua(new UnionArray(variantUnion), Field::Deleter());
|
||||
variantUnionArray = sua;
|
||||
}
|
||||
|
||||
FieldCreatePtr getFieldCreate() {
|
||||
|
||||
@@ -145,11 +145,18 @@ public:
|
||||
SerializableControl *pflusher, size_t offset, size_t count) const;
|
||||
private:
|
||||
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() {}
|
||||
|
||||
@@ -157,6 +164,9 @@ string BasePVString::get() const { return value;}
|
||||
|
||||
void BasePVString::put(string val)
|
||||
{
|
||||
if (maxLength > 0 && val.length() > maxLength)
|
||||
throw std::overflow_error("string too long");
|
||||
|
||||
value = val;
|
||||
postPut();
|
||||
}
|
||||
@@ -190,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>
|
||||
@@ -231,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()
|
||||
@@ -240,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);
|
||||
@@ -260,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();
|
||||
}
|
||||
@@ -267,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);
|
||||
}
|
||||
@@ -283,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
|
||||
@@ -321,6 +365,7 @@ void DefaultPVArray<T>::deserialize(ByteBuffer *pbuffer,
|
||||
remaining -= n2read;
|
||||
}
|
||||
value = freeze(nextvalue);
|
||||
// TODO !!!
|
||||
// inform about the change?
|
||||
PVField::postPut();
|
||||
}
|
||||
@@ -334,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();
|
||||
|
||||
@@ -368,7 +417,10 @@ void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
|
||||
template<>
|
||||
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));
|
||||
|
||||
@@ -396,7 +448,9 @@ void DefaultPVArray<string>::serialize(ByteBuffer *pbuffer,
|
||||
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();
|
||||
for(size_t i = 0; i<temp.size(); i++) {
|
||||
@@ -649,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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,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
|
||||
@@ -177,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -162,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);
|
||||
@@ -228,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);
|
||||
@@ -255,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);
|
||||
@@ -282,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);
|
||||
@@ -309,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);
|
||||
@@ -336,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);
|
||||
@@ -363,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);
|
||||
@@ -390,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);
|
||||
@@ -417,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);
|
||||
@@ -444,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);
|
||||
@@ -471,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);
|
||||
@@ -503,28 +503,28 @@ StructureConstPtr StandardField::scalar(
|
||||
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("uri:ev4:nt/2012/pwd:NTUnion",field,properties);
|
||||
return createProperties("epics:nt/NTUnion:1.0",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::variantUnion(
|
||||
string const & properties)
|
||||
{
|
||||
UnionConstPtr field = fieldCreate->createVariantUnion();
|
||||
return createProperties("uri:ev4:nt/2012/pwd:NTUnion",field,properties);
|
||||
return createProperties("epics:nt/NTUnion:1.0",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::scalarArray(
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -533,7 +533,7 @@ StructureConstPtr StandardField::structureArray(
|
||||
{
|
||||
StructureArrayConstPtr field = fieldCreate->createStructureArray(
|
||||
structure);
|
||||
return createProperties("uri:ev4:nt/2012/pwd:NTStructureArray",field,properties);
|
||||
return createProperties("epics:nt/NTStructureArray:1.0",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::unionArray(
|
||||
@@ -541,7 +541,7 @@ StructureConstPtr StandardField::unionArray(
|
||||
{
|
||||
UnionArrayConstPtr field = fieldCreate->createUnionArray(
|
||||
punion);
|
||||
return createProperties("uri:ev4:nt/2012/pwd:NTUnionArray",field,properties);
|
||||
return createProperties("epics:nt/NTUnionArray:1.0",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::enumerated()
|
||||
@@ -560,7 +560,7 @@ StructureConstPtr StandardField::enumerated()
|
||||
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()
|
||||
|
||||
@@ -26,7 +26,14 @@ namespace epics { namespace pvData {
|
||||
|
||||
namespace format
|
||||
{
|
||||
std::ostream& operator<<(std::ostream& os, indent_level const& indent)
|
||||
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;
|
||||
|
||||
@@ -54,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 {
|
||||
@@ -82,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
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
|
||||
|
||||
@@ -27,7 +27,7 @@ using std::string;
|
||||
#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 */
|
||||
@@ -249,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)
|
||||
{
|
||||
@@ -297,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)
|
||||
{
|
||||
@@ -339,7 +415,7 @@ noconvert:
|
||||
*endp = (char*)ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* do we need long long? */
|
||||
@@ -475,6 +551,26 @@ void parseToPOD(const string& in, float *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
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -23,7 +23,7 @@ MonitorPluginManagerPtr MonitorPluginManager::get()
|
||||
static MonitorPluginManagerPtr pluginManager;
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
if(pluginManager==NULL) {
|
||||
if(!pluginManager) {
|
||||
pluginManager = MonitorPluginManagerPtr(new MonitorPluginManager());
|
||||
}
|
||||
return pluginManager;
|
||||
|
||||
@@ -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;}
|
||||
|
||||
@@ -30,11 +30,17 @@ bool PVControl::attach(PVFieldPtr const & pvField)
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvLow = pvStructure->getDoubleField("limitLow");
|
||||
if(pvLow.get()==NULL) return false;
|
||||
pvHigh = pvStructure->getDoubleField(string("limitHigh"));
|
||||
pvHigh = pvStructure->getDoubleField("limitHigh");
|
||||
if(pvHigh.get()==NULL) {
|
||||
pvLow.reset();
|
||||
return false;
|
||||
}
|
||||
pvMinStep = pvStructure->getDoubleField("minStep");
|
||||
if(pvMinStep.get()==NULL) {
|
||||
pvLow.reset();
|
||||
pvHigh.reset();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -56,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)
|
||||
@@ -63,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,6 +33,7 @@ public:
|
||||
private:
|
||||
PVDoublePtr pvLow;
|
||||
PVDoublePtr pvHigh;
|
||||
PVDoublePtr pvMinStep;
|
||||
static std::string noControlFound;
|
||||
static std::string notAttached;
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@ bool PVTimeStamp::attach(PVFieldPtr const & pvField)
|
||||
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
|
||||
@@ -76,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,9 +66,7 @@ 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 std::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 std::string to a scalar.
|
||||
* fromStringArray converts an array of std::strings
|
||||
@@ -478,7 +479,7 @@ 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 std::string * being constructed.
|
||||
* @param indentLevel Indent level, Each level is four spaces.
|
||||
|
||||
@@ -507,10 +507,12 @@ public:
|
||||
*/
|
||||
virtual void setCapacity(std::size_t capacity) = 0;
|
||||
|
||||
using PVField::dumpValue;
|
||||
virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const = 0;
|
||||
|
||||
protected:
|
||||
PVArray(FieldConstPtr const & field);
|
||||
void checkLength(size_t length);
|
||||
private:
|
||||
bool capacityMutable;
|
||||
friend class PVDataCreate;
|
||||
@@ -979,7 +981,6 @@ public:
|
||||
|
||||
private:
|
||||
friend class PVDataCreate;
|
||||
|
||||
UnionConstPtr unionPtr;
|
||||
|
||||
int32 selector;
|
||||
@@ -1195,6 +1196,7 @@ public:
|
||||
virtual const_svector view() const { return value; }
|
||||
virtual void swap(const_svector &other);
|
||||
virtual void replace(const const_svector &other) {
|
||||
checkLength(other.size());
|
||||
value = other;
|
||||
PVField::postPut();
|
||||
}
|
||||
@@ -1290,6 +1292,7 @@ public:
|
||||
virtual const_svector view() const { return value; }
|
||||
virtual void swap(const_svector &other);
|
||||
virtual void replace(const const_svector &other) {
|
||||
checkLength(other.size());
|
||||
value = other;
|
||||
PVField::postPut();
|
||||
}
|
||||
|
||||
@@ -32,11 +32,7 @@ struct indent_level
|
||||
indent_level(long l) : level(l) {}
|
||||
};
|
||||
|
||||
inline long& indent_value(std::ios_base& ios)
|
||||
{
|
||||
static int indent_index = std::ios_base::xalloc();
|
||||
return ios.iword(indent_index);
|
||||
}
|
||||
epicsShareExtern long& indent_value(std::ios_base& ios);
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& os, indent_level const& indent);
|
||||
|
||||
@@ -93,6 +89,8 @@ class StructureArray;
|
||||
class Union;
|
||||
class UnionArray;
|
||||
|
||||
class BoundedString;
|
||||
|
||||
/**
|
||||
* typedef for a shared pointer to an immutable Field.
|
||||
*/
|
||||
@@ -129,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.
|
||||
@@ -360,9 +362,39 @@ 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;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -377,14 +409,21 @@ public:
|
||||
virtual ~Array();
|
||||
typedef Array& reference;
|
||||
typedef const Array& const_reference;
|
||||
|
||||
/* fixed-size array support
|
||||
// 0 not valid value, means undefined
|
||||
std::size_t getMaximumCapacity() const;
|
||||
|
||||
// 0 not valid value, means undefined
|
||||
std::size_t getFixedLength() const;
|
||||
*/
|
||||
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
|
||||
@@ -394,8 +433,14 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class implements introspection object for field.
|
||||
* This class implements introspection object for scalar array.
|
||||
*/
|
||||
class epicsShareClass ScalarArray : public Array{
|
||||
public:
|
||||
@@ -414,6 +459,10 @@ public:
|
||||
*/
|
||||
ScalarType getElementType() const {return elementType;}
|
||||
|
||||
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;
|
||||
@@ -427,12 +476,85 @@ protected:
|
||||
*/
|
||||
virtual ~ScalarArray();
|
||||
private:
|
||||
int8 getTypeCodeLUT() 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
|
||||
*/
|
||||
@@ -448,6 +570,10 @@ public:
|
||||
*/
|
||||
StructureConstPtr getStructure() const {return pstructure;}
|
||||
|
||||
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;
|
||||
@@ -485,6 +611,10 @@ public:
|
||||
*/
|
||||
UnionConstPtr getUnion() const {return punion;}
|
||||
|
||||
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;
|
||||
@@ -711,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.
|
||||
@@ -720,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.
|
||||
@@ -843,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
|
||||
@@ -972,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.
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -51,7 +51,7 @@ typedef std::tr1::shared_ptr<StandardField> StandardFieldPtr;
|
||||
string message
|
||||
structure timeStamp
|
||||
long secondsPastEpoch
|
||||
int nanoSeconds
|
||||
int nanoseconds
|
||||
int userTag
|
||||
* }
|
||||
* In addition there are methods that create each of the property structures,
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
*/
|
||||
StructureConstPtr enumerated();
|
||||
/** Create a structure that has an enumerated structure value field
|
||||
* The id for the structure is "uri:ev4:nt/2012/pwd:NTEnum".
|
||||
* 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.
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
PVStructurePtr enumerated(StringArray const &choices);
|
||||
/**
|
||||
* Create a structure that has an enumerated structure value field.
|
||||
* The id for the structure is "uri:ev4:nt/2012/pwd:NTEnum".
|
||||
* 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.
|
||||
|
||||
@@ -1,8 +1,31 @@
|
||||
# Makefile for the pvData tests
|
||||
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
DIRS += misc
|
||||
DIRS += pv
|
||||
DIRS += property
|
||||
DIRS += copy
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -1,22 +1,13 @@
|
||||
TOP=../..
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
SRC_DIRS += $(PVDATA_TEST)/copy
|
||||
|
||||
PROD_HOST += testCreateRequest
|
||||
TESTPROD_HOST += testCreateRequest
|
||||
testCreateRequest_SRCS = testCreateRequest.cpp
|
||||
testCreateRequest_LIBS = pvData Com
|
||||
testHarness_SRCS += testCreateRequest.cpp
|
||||
TESTS += testCreateRequest
|
||||
|
||||
PROD_HOST += testPVCopy
|
||||
TESTPROD_HOST += testPVCopy
|
||||
testPVCopy_SRCS += testPVCopy.cpp
|
||||
testPVCopy_LIBS += pvData Com
|
||||
testHarness_SRCS += testPVCopy.cpp
|
||||
TESTS += testPVCopy
|
||||
|
||||
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
|
||||
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
|
||||
@@ -20,101 +20,102 @@ using std::endl;
|
||||
|
||||
static bool debug = false;
|
||||
|
||||
void testCreateRequest() {
|
||||
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(debug) { cout<< createRequest->getMessage() << endl;}
|
||||
testOk1(pvRequest!=NULL);
|
||||
if(debug) { cout << pvRequest->dumpValue(cout) << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getStructure()->getNumberFields()==0);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
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)";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest==NULL) {
|
||||
cout << createRequest->getMessage() << endl;
|
||||
}
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
testOk1(pvRequest!=NULL);
|
||||
if(debug) { cout << pvRequest->dumpValue(cout) << endl;}
|
||||
PVStringPtr pvString = pvRequest->getSubField<PVString>("record.a");
|
||||
string sval = pvString->get();
|
||||
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.x");
|
||||
pvString = pvRequest->getSubField<PVString>("record._options.x");
|
||||
sval = pvString->get();
|
||||
testOk(sval.compare("y")==0,"record.x = y");
|
||||
testOk1(pvRequest->getSubField("field.a")!=NULL);
|
||||
testOk1(pvRequest->getSubField("putField.a")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.a")!=NULL);
|
||||
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])";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(pvRequest==NULL) {
|
||||
cout << createRequest->getMessage() << endl;
|
||||
}
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
testOk1(pvRequest!=NULL);
|
||||
if(debug) { cout << pvRequest->dumpValue(cout) << 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})";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
if(pvRequest==NULL) {
|
||||
cout << createRequest->getMessage() << endl;
|
||||
}
|
||||
testOk1(pvRequest!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.a.b.c.d")!=NULL);
|
||||
if(debug) { cout << pvRequest->dumpValue(cout) << 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})";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
if(pvRequest==NULL) {
|
||||
cout << createRequest->getMessage() << endl;
|
||||
}
|
||||
testOk1(pvRequest!=NULL);
|
||||
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")!=NULL);
|
||||
if(debug) { cout << pvRequest->dumpValue(cout) << endl;}
|
||||
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]})";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
if(pvRequest==NULL) {
|
||||
cout << createRequest->getMessage() << endl;
|
||||
}
|
||||
testOk1(pvRequest!=NULL);
|
||||
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");
|
||||
if(debug) { cout << pvRequest->dumpValue(cout) << endl;}
|
||||
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})";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
if(pvRequest==NULL) {
|
||||
cout << createRequest->getMessage() << endl;
|
||||
}
|
||||
testOk1(pvRequest!=NULL);
|
||||
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");
|
||||
@@ -124,126 +125,113 @@ void testCreateRequest() {
|
||||
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")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.b.a.b")!=NULL);
|
||||
if(debug) { cout << pvRequest->dumpValue(cout) << endl;}
|
||||
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(debug) { cout << endl << string("request") <<endl << request <<endl;}
|
||||
if(pvRequest==NULL) {
|
||||
cout << "reason " << createRequest->getMessage() << endl;
|
||||
}
|
||||
testOk1(pvRequest!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.timeStamp")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.power.value")!=NULL);
|
||||
if(debug) { cout << pvRequest->dumpValue(cout) << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.timeStamp").get()!=NULL);
|
||||
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(debug) { cout << endl << string("request") <<endl << request <<endl;}
|
||||
if(pvRequest==NULL) {
|
||||
cout << "reason " << createRequest->getMessage() << endl;
|
||||
}
|
||||
testOk1(pvRequest!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("record.process");
|
||||
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.process = true");
|
||||
testOk1(pvRequest->getSubField("field.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.timeStamp")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.power.value")!=NULL);
|
||||
if(debug) {cout << pvRequest->dumpValue(cout) << endl;}
|
||||
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(debug) { cout << string("request") <<endl << request <<endl;}
|
||||
if(pvRequest==NULL) {
|
||||
cout << "reason " << createRequest->getMessage() << endl;
|
||||
}
|
||||
testOk1(pvRequest!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("record.process");
|
||||
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.process = true");
|
||||
testOk1(pvRequest->getSubField("field.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.timeStamp")!=NULL);
|
||||
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")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.power.alarm")!=NULL);
|
||||
if(debug) {cout << pvRequest->dumpValue(cout) << endl;}
|
||||
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(debug) { cout << string("request") <<endl << request <<endl;}
|
||||
if(pvRequest==NULL) {
|
||||
cout << "reason " << createRequest->getMessage() << endl;
|
||||
}
|
||||
testOk1(pvRequest!=NULL);
|
||||
pvString = pvRequest->getSubField<PVString>("record.int");
|
||||
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.int = 2");
|
||||
pvString = pvRequest->getSubField<PVString>("record.float");
|
||||
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.float = 3.14159");
|
||||
testOk1(pvRequest->getSubField("field.alarm")!=NULL);
|
||||
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")!=NULL);
|
||||
if(debug) {cout << pvRequest->dumpValue(cout) << endl;}
|
||||
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(debug) { cout << string("request") <<endl << request <<endl;}
|
||||
if(pvRequest==NULL) {
|
||||
cout << "reason " << createRequest->getMessage() << endl;
|
||||
}
|
||||
testOk1(pvRequest!=NULL);
|
||||
testOk1(pvRequest->getSubField("putField.power.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.timeStamp")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.power.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.power.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.current.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.current.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.voltage.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.voltage.alarm")!=NULL);
|
||||
if(debug) {cout << pvRequest->dumpValue(cout) << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("putField.power.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.alarm").get()!=NULL);
|
||||
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(debug) { cout << string("request") <<endl << request <<endl;}
|
||||
if(pvRequest==NULL) {
|
||||
cout << "reason " << createRequest->getMessage() << endl;
|
||||
}
|
||||
testOk1(pvRequest!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.timeStamp")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.supply.0.voltage.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.supply.0.current.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.supply.0.power.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.supply.1.voltage.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.supply.1.current.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.supply.1.power.value")!=NULL);
|
||||
if(debug) {cout << pvRequest->dumpValue(cout) << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.alarm").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.timeStamp").get()!=NULL);
|
||||
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]")
|
||||
@@ -253,46 +241,45 @@ void testCreateRequest() {
|
||||
+ "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(debug) { cout << string("request") <<endl << request <<endl;}
|
||||
if(pvRequest==NULL) {
|
||||
cout << "reason " << createRequest->getMessage() << endl;
|
||||
}
|
||||
testOk1(pvRequest!=NULL);
|
||||
testOk1(pvRequest->getSubField("putField.power.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.timeStamp")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.power.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.power.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.current.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.current.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.voltage.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.voltage.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.timeStamp")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.power.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.power.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.current.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.current.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.voltage.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps0.voltage.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.timeStamp")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.power.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.power.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.current.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.current.alarm")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.voltage.value")!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.ps1.voltage.alarm")!=NULL);
|
||||
if(debug) {cout << pvRequest->dumpValue(cout) << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("putField.power.value").get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("getField.alarm").get()!=NULL);
|
||||
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(debug) { cout << string("request") <<endl << request <<endl;}
|
||||
testOk1(pvRequest!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.a.b.c.d")!=NULL);
|
||||
if(debug) {cout << pvRequest->dumpValue(cout) << endl;}
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
if(debug) { cout << *pvRequest << endl;}
|
||||
testOk1(pvRequest.get()!=NULL);
|
||||
testOk1(pvRequest->getSubField("field.a.b.c.d").get()!=NULL);
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = string("record[process=true,xxx=yyy]")
|
||||
@@ -302,26 +289,33 @@ void testCreateRequest() {
|
||||
+ "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 << endl << "Error Expected for next call!!" << endl;}
|
||||
if(debug) { cout << string("request") <<endl << request <<endl;}
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
cout << endl << "Error Expected for next call!!" << endl;
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
assert(pvRequest.get()==NULL);
|
||||
if(debug) {cout << "reason " << createRequest->getMessage() << endl;}
|
||||
cout << "reason " << createRequest->getMessage() << endl;
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = "record[process=true,power.value";
|
||||
if(debug) { cout << string("request") <<endl << request <<endl;}
|
||||
if(debug) { cout << endl << "Error Expected for next call!!" << endl;}
|
||||
if(debug) { cout << "request " << request <<endl;}
|
||||
cout << endl << "Error Expected for next call!!" << endl;
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
assert(pvRequest.get()==NULL);
|
||||
if(debug) { cout << "reason " << createRequest->getMessage() << endl;}
|
||||
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(111);
|
||||
testCreateRequest();
|
||||
testPlan(119);
|
||||
testCreateRequestInternal();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ static void scalarTest()
|
||||
CreateRequest::shared_pointer createRequest = CreateRequest::create();
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
@@ -222,7 +222,7 @@ static void scalarTest()
|
||||
valueNameMaster = "value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
@@ -230,7 +230,7 @@ static void scalarTest()
|
||||
valueNameMaster = "value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
@@ -253,7 +253,7 @@ static void arrayTest()
|
||||
valueNameMaster = request = "value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
@@ -261,7 +261,7 @@ static void arrayTest()
|
||||
valueNameMaster = "value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
@@ -269,7 +269,7 @@ static void arrayTest()
|
||||
valueNameMaster = "value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
@@ -320,7 +320,7 @@ static void powerSupplyTest()
|
||||
valueNameMaster = request = "power.value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "power.value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
@@ -328,7 +328,7 @@ static void powerSupplyTest()
|
||||
valueNameMaster = "power.value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "power.value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
@@ -336,7 +336,7 @@ static void powerSupplyTest()
|
||||
valueNameMaster = "power.value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "power.value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
@@ -344,7 +344,7 @@ static void powerSupplyTest()
|
||||
valueNameMaster = "power.value";
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(debug) { cout << "request " << request << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
|
||||
if(debug) { cout << "pvRequest\n" << *pvRequest << endl; }
|
||||
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
|
||||
valueNameCopy = "power.value";
|
||||
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#include <testMain.h>
|
||||
#include <epicsEndian.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
MAIN(testByteOrder)
|
||||
{
|
||||
printf("EPICS_BYTE_ORDER: %s\n", (EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE) ? "little" : "big");
|
||||
printf("EPICS_FLOAT_WORD_ORDER: %s\n", (EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE) ? "little" : "big");
|
||||
|
||||
@@ -41,11 +41,11 @@ void test()
|
||||
uint32 messageOffset = (uint32) pvMessage->getFieldOffset();
|
||||
PVStructurePtr pvTimeStamp = pvStructure->getStructureField("timeStamp");
|
||||
PVLongPtr pvSeconds = pvTimeStamp->getLongField("secondsPastEpoch");
|
||||
PVIntPtr pvNanoSeconds = pvTimeStamp->getIntField("nanoSeconds");
|
||||
PVIntPtr pvNanoseconds = pvTimeStamp->getIntField("nanoseconds");
|
||||
PVIntPtr pvUserTag = pvTimeStamp->getIntField("userTag");
|
||||
uint32 timeStampOffset = (uint32) pvTimeStamp->getFieldOffset();
|
||||
uint32 secondsOffset = (uint32) pvSeconds->getFieldOffset();
|
||||
uint32 nanoSecondsOffset = (uint32) pvNanoSeconds->getFieldOffset();
|
||||
uint32 nanosecondsOffset = (uint32) pvNanoseconds->getFieldOffset();
|
||||
uint32 userTagOffset = (uint32) pvUserTag->getFieldOffset();
|
||||
uint32 nfields = (uint32) pvStructure->getNumberFields();
|
||||
BitSetPtr changeBitSet = BitSet::create(nfields);
|
||||
@@ -55,7 +55,7 @@ void test()
|
||||
pvSeverity->put(2); changeBitSet->set(severityOffset);
|
||||
pvMessage->put("error"); changeBitSet->set(messageOffset);
|
||||
pvSeconds->put(1); changeBitSet->set(secondsOffset);
|
||||
pvNanoSeconds->put(1000000); changeBitSet->set(nanoSecondsOffset);
|
||||
pvNanoseconds->put(1000000); changeBitSet->set(nanosecondsOffset);
|
||||
pvUserTag->put(1); changeBitSet->set(userTagOffset);
|
||||
userOverrunBitSet->or_and(*changeBitSet.get(),*userChangeBitSet.get());
|
||||
(*userChangeBitSet)|=(*changeBitSet.get());
|
||||
@@ -64,7 +64,7 @@ void test()
|
||||
pvSeverity->put(0); changeBitSet->set(severityOffset);
|
||||
pvMessage->put(""); changeBitSet->set(messageOffset);
|
||||
pvSeconds->put(2); changeBitSet->set(secondsOffset);
|
||||
pvNanoSeconds->put(0); changeBitSet->set(nanoSecondsOffset);
|
||||
pvNanoseconds->put(0); changeBitSet->set(nanosecondsOffset);
|
||||
pvUserTag->put(0); changeBitSet->set(userTagOffset);
|
||||
userOverrunBitSet->or_and(*changeBitSet.get(),*userChangeBitSet.get());
|
||||
(*userChangeBitSet)|=(*changeBitSet.get());
|
||||
@@ -73,14 +73,14 @@ void test()
|
||||
testOk1(userChangeBitSet->get(severityOffset));
|
||||
testOk1(userChangeBitSet->get(messageOffset));
|
||||
testOk1(userChangeBitSet->get(secondsOffset));
|
||||
testOk1(userChangeBitSet->get(nanoSecondsOffset));
|
||||
testOk1(userChangeBitSet->get(nanosecondsOffset));
|
||||
testOk1(userChangeBitSet->get(userTagOffset));
|
||||
testOk1(userOverrunBitSet->cardinality()==6);
|
||||
testOk1(userOverrunBitSet->get(valueOffset));
|
||||
testOk1(userOverrunBitSet->get(severityOffset));
|
||||
testOk1(userOverrunBitSet->get(messageOffset));
|
||||
testOk1(userOverrunBitSet->get(secondsOffset));
|
||||
testOk1(userOverrunBitSet->get(nanoSecondsOffset));
|
||||
testOk1(userOverrunBitSet->get(nanosecondsOffset));
|
||||
testOk1(userOverrunBitSet->get(userTagOffset));
|
||||
|
||||
BitSetUtil::compress(userChangeBitSet,pvStructure);
|
||||
@@ -101,13 +101,13 @@ void test()
|
||||
userOverrunBitSet->clear();
|
||||
pvValue->put(1.0); changeBitSet->set(valueOffset);
|
||||
pvSeconds->put(3); changeBitSet->set(secondsOffset);
|
||||
pvNanoSeconds->put(0); changeBitSet->set(nanoSecondsOffset);
|
||||
pvNanoseconds->put(0); changeBitSet->set(nanosecondsOffset);
|
||||
userOverrunBitSet->or_and(*changeBitSet.get(),*userChangeBitSet.get());
|
||||
(*userChangeBitSet)|=(*changeBitSet.get());
|
||||
testOk1(userChangeBitSet->cardinality()==3);
|
||||
testOk1(userChangeBitSet->get(valueOffset));
|
||||
testOk1(userChangeBitSet->get(secondsOffset));
|
||||
testOk1(userChangeBitSet->get(nanoSecondsOffset));
|
||||
testOk1(userChangeBitSet->get(nanosecondsOffset));
|
||||
testOk1(userOverrunBitSet->cardinality()==0);
|
||||
|
||||
changeBitSet->clear();
|
||||
@@ -117,7 +117,7 @@ void test()
|
||||
testOk1(userChangeBitSet->cardinality()==3);
|
||||
testOk1(userChangeBitSet->get(valueOffset));
|
||||
testOk1(userChangeBitSet->get(secondsOffset));
|
||||
testOk1(userChangeBitSet->get(nanoSecondsOffset));
|
||||
testOk1(userChangeBitSet->get(nanosecondsOffset));
|
||||
testOk1(userOverrunBitSet->cardinality()==1);
|
||||
testOk1(userOverrunBitSet->get(valueOffset));
|
||||
|
||||
@@ -126,13 +126,13 @@ void test()
|
||||
testOk1(userChangeBitSet->cardinality()==3);
|
||||
testOk1(userChangeBitSet->get(valueOffset));
|
||||
testOk1(userChangeBitSet->get(secondsOffset));
|
||||
testOk1(userChangeBitSet->get(nanoSecondsOffset));
|
||||
testOk1(userChangeBitSet->get(nanosecondsOffset));
|
||||
testOk1(userOverrunBitSet->cardinality()==1);
|
||||
testOk1(userOverrunBitSet->get(valueOffset));
|
||||
}
|
||||
|
||||
|
||||
MAIN(testOverrunBitSet`)
|
||||
MAIN(testOverrunBitSet)
|
||||
{
|
||||
testPlan(41);
|
||||
testDiag("Tests for changeBitSet and overrunBitSet");
|
||||
|
||||
@@ -386,7 +386,7 @@ void testStructure() {
|
||||
testDiag("\tSimple structure serialization");
|
||||
PVStructurePtr pvStructure = factory->createPVStructure(getStandardField()->timeStamp());
|
||||
pvStructure->getLongField("secondsPastEpoch")->put(123);
|
||||
pvStructure->getIntField("nanoSeconds")->put(456);
|
||||
pvStructure->getIntField("nanoseconds")->put(456);
|
||||
pvStructure->getIntField("userTag")->put(789);
|
||||
|
||||
serializationTest(pvStructure);
|
||||
@@ -625,13 +625,13 @@ void testStructureId() {
|
||||
testOk1(structureWithNoId!=structure1);
|
||||
testOk1(structure1!=structure2);
|
||||
|
||||
//serializationTest(structure1);
|
||||
//serializationFieldTest(structure1);
|
||||
|
||||
PVStructurePtr pvStructure = getPVDataCreate()->createPVStructure(structure1);
|
||||
serializationTest(pvStructure);
|
||||
}
|
||||
|
||||
void serializatioTest(FieldConstPtr const & field)
|
||||
void serializationFieldTest(FieldConstPtr const & field)
|
||||
{
|
||||
buffer->clear();
|
||||
|
||||
@@ -660,27 +660,27 @@ void testIntrospectionSerialization()
|
||||
ScalarType scalarType = static_cast<ScalarType>(i);
|
||||
|
||||
ScalarConstPtr scalar = factory->createScalar(scalarType);
|
||||
serializatioTest(scalar);
|
||||
serializationFieldTest(scalar);
|
||||
|
||||
ScalarArrayConstPtr array = factory->createScalarArray(scalarType);
|
||||
serializatioTest(array);
|
||||
serializationFieldTest(array);
|
||||
}
|
||||
|
||||
// and a structure
|
||||
StructureConstPtr structure = getStandardField()->timeStamp();
|
||||
serializatioTest(structure);
|
||||
serializationFieldTest(structure);
|
||||
|
||||
// and a structure array
|
||||
StructureArrayConstPtr structureArray = factory->createStructureArray(structure);
|
||||
serializatioTest(structureArray);
|
||||
serializationFieldTest(structureArray);
|
||||
|
||||
// variant union
|
||||
UnionConstPtr variant = factory->createVariantUnion();
|
||||
serializatioTest(variant);
|
||||
serializationFieldTest(variant);
|
||||
|
||||
// variant array union
|
||||
UnionArrayConstPtr variantArray = factory->createVariantUnionArray();
|
||||
serializatioTest(variantArray);
|
||||
serializationFieldTest(variantArray);
|
||||
|
||||
// union
|
||||
UnionConstPtr punion = factory->createFieldBuilder()->
|
||||
@@ -692,11 +692,66 @@ void testIntrospectionSerialization()
|
||||
endNested()->
|
||||
addArray("intArray", pvInt)->
|
||||
createUnion();
|
||||
serializatioTest(punion);
|
||||
serializationFieldTest(punion);
|
||||
|
||||
// union array
|
||||
UnionArrayConstPtr punionArray = factory->createUnionArray(punion);
|
||||
serializatioTest(punionArray);
|
||||
serializationFieldTest(punionArray);
|
||||
}
|
||||
|
||||
void testArraySizeType() {
|
||||
testDiag("Testing array size types...");
|
||||
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
StructureConstPtr s = fieldCreate->createFieldBuilder()->
|
||||
addArray("variableArray", pvDouble)->
|
||||
addFixedArray("fixedArray", pvDouble, 10)->
|
||||
addBoundedArray("boundedArray", pvDouble, 1024)->
|
||||
createStructure();
|
||||
testOk1(s.get() != 0);
|
||||
testOk1(Structure::DEFAULT_ID == s->getID());
|
||||
testOk1(3 == s->getFields().size());
|
||||
|
||||
serializationFieldTest(s);
|
||||
|
||||
PVStructurePtr pvs = getPVDataCreate()->createPVStructure(s);
|
||||
PVDoubleArray::shared_pointer pvDA = pvs->getSubField<PVDoubleArray>("fixedArray");
|
||||
PVDoubleArray::svector vec(10, 42);
|
||||
pvDA->replace(freeze(vec));
|
||||
serializationTest(pvs);
|
||||
}
|
||||
|
||||
void testBoundedString() {
|
||||
testDiag("Testing bounded string...");
|
||||
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
StructureConstPtr s = fieldCreate->createFieldBuilder()->
|
||||
add("str", pvString)->
|
||||
addBoundedString("boundedStr", 8)->
|
||||
add("scalar", pvDouble)->
|
||||
createStructure();
|
||||
testOk1(s.get() != 0);
|
||||
testOk1(Structure::DEFAULT_ID == s->getID());
|
||||
testOk1(3 == s->getFields().size());
|
||||
|
||||
serializationFieldTest(s);
|
||||
PVStructurePtr pvs = getPVDataCreate()->createPVStructure(s);
|
||||
serializationTest(pvs);
|
||||
|
||||
PVStringPtr pvStr = pvs->getSubField<PVString>("boundedStr");
|
||||
pvStr->put("");
|
||||
pvStr->put("small");
|
||||
pvStr->put("exact123");
|
||||
|
||||
try {
|
||||
pvStr->put("tooLargeString");
|
||||
testFail("too large string accepted");
|
||||
} catch (std::overflow_error oe) {
|
||||
// OK
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void testStringCopy() {
|
||||
@@ -710,7 +765,7 @@ void testStringCopy() {
|
||||
|
||||
MAIN(testSerialization) {
|
||||
|
||||
testPlan(213);
|
||||
testPlan(226);
|
||||
|
||||
flusher = new SerializableControlImpl();
|
||||
control = new DeserializableControlImpl();
|
||||
@@ -724,16 +779,19 @@ MAIN(testSerialization) {
|
||||
testScalar();
|
||||
testArray();
|
||||
testStructure();
|
||||
testStructureId();
|
||||
testStructureArray();
|
||||
|
||||
testUnion();
|
||||
|
||||
testArraySizeType();
|
||||
testBoundedString();
|
||||
|
||||
|
||||
delete buffer;
|
||||
delete control;
|
||||
delete flusher;
|
||||
|
||||
epicsExitCallAtExits();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,12 @@
|
||||
#include "pv/sharedVector.h"
|
||||
|
||||
using std::string;
|
||||
using namespace epics::pvData;
|
||||
|
||||
static void testEmpty()
|
||||
{
|
||||
testDiag("Test empty vector");
|
||||
epics::pvData::shared_vector<int> empty, empty2;
|
||||
epics::pvData::shared_vector<int32> empty, empty2;
|
||||
|
||||
testOk1(empty.size()==0);
|
||||
testOk1(empty.empty());
|
||||
@@ -42,7 +43,7 @@ static void testInternalAlloc()
|
||||
{
|
||||
testDiag("Test vector alloc w/ new[]");
|
||||
|
||||
epics::pvData::shared_vector<int> internal(5);
|
||||
epics::pvData::shared_vector<int32> internal(5);
|
||||
|
||||
testOk1(internal.size()==5);
|
||||
testOk1(!internal.empty());
|
||||
@@ -57,7 +58,7 @@ static void testInternalAlloc()
|
||||
internal[2] = 42;
|
||||
testOk1(internal[2]==42);
|
||||
|
||||
epics::pvData::shared_vector<int> internal2(15, 500);
|
||||
epics::pvData::shared_vector<int32> internal2(15, 500);
|
||||
|
||||
testOk1(internal2.size()==15);
|
||||
testOk1(internal2[1]==500);
|
||||
@@ -79,8 +80,8 @@ namespace {
|
||||
//Note: STL shared_ptr requires that deletors be copy constructable
|
||||
template<typename E>
|
||||
struct callCounter {
|
||||
std::tr1::shared_ptr<int> count;
|
||||
callCounter():count(new int){*count=0;}
|
||||
std::tr1::shared_ptr<int32> count;
|
||||
callCounter():count(new int32){*count=0;}
|
||||
callCounter(const callCounter& o):count(o.count) {};
|
||||
callCounter& operator=(const callCounter& o){count=o.count;}
|
||||
void operator()(E){*count=1;}
|
||||
@@ -92,8 +93,8 @@ static void testExternalAlloc()
|
||||
testDiag("Test vector external alloc");
|
||||
|
||||
// Simulate a failed malloc() or similar
|
||||
int *oops=0;
|
||||
epics::pvData::shared_vector<int> nullPtr(oops, 42, 100);
|
||||
int32 *oops=0;
|
||||
epics::pvData::shared_vector<int32> nullPtr(oops, 42, 100);
|
||||
|
||||
testOk1(nullPtr.size()==0);
|
||||
testOk1(nullPtr.empty());
|
||||
@@ -102,8 +103,8 @@ static void testExternalAlloc()
|
||||
|
||||
testOk1(nullPtr.data()==NULL);
|
||||
|
||||
int *raw=new int[5];
|
||||
epics::pvData::shared_vector<int> newData(raw, 1, 4);
|
||||
int32 *raw=new int32[5];
|
||||
epics::pvData::shared_vector<int32> newData(raw, 1, 4);
|
||||
|
||||
testOk1(newData.size()==4);
|
||||
testOk1(!newData.empty());
|
||||
@@ -113,11 +114,11 @@ static void testExternalAlloc()
|
||||
testOk1(newData[0]==14);
|
||||
|
||||
// Check use of custom deleter
|
||||
int localVar[4] = {1,2,3,4};
|
||||
callCounter<int*> tracker;
|
||||
int32 localVar[4] = {1,2,3,4};
|
||||
callCounter<int32*> tracker;
|
||||
testOk1(*tracker.count==0);
|
||||
|
||||
epics::pvData::shared_vector<int> locvar(localVar,
|
||||
epics::pvData::shared_vector<int32> locvar(localVar,
|
||||
tracker,
|
||||
0, 4);
|
||||
|
||||
@@ -137,8 +138,8 @@ static void testShare()
|
||||
{
|
||||
testDiag("Test vector Sharing");
|
||||
|
||||
epics::pvData::shared_vector<int> one, two(15);
|
||||
epics::pvData::shared_vector<int> three(two);
|
||||
epics::pvData::shared_vector<int32> one, two(15);
|
||||
epics::pvData::shared_vector<int32> three(two);
|
||||
|
||||
testOk1(one.unique());
|
||||
testOk1(!two.unique());
|
||||
@@ -199,22 +200,22 @@ static void testConst()
|
||||
{
|
||||
testDiag("Test constant vector");
|
||||
|
||||
epics::pvData::shared_vector<int> writable(15, 100);
|
||||
epics::pvData::shared_vector<int32> writable(15, 100);
|
||||
|
||||
epics::pvData::shared_vector<int>::reference wr = writable[0];
|
||||
epics::pvData::shared_vector<int>::const_reference ror = writable[0];
|
||||
epics::pvData::shared_vector<int32>::reference wr = writable[0];
|
||||
epics::pvData::shared_vector<int32>::const_reference ror = writable[0];
|
||||
|
||||
testOk1(wr==ror);
|
||||
|
||||
int *compare = writable.data();
|
||||
int32 *compare = writable.data();
|
||||
|
||||
testOk1(writable.unique());
|
||||
|
||||
// can re-target container, but data is R/O
|
||||
epics::pvData::shared_vector<const int> rodata(freeze(writable));
|
||||
epics::pvData::shared_vector<const int32> rodata(freeze(writable));
|
||||
|
||||
epics::pvData::shared_vector<const int>::reference wcr = rodata[0];
|
||||
epics::pvData::shared_vector<const int>::const_reference rocr = rodata[0];
|
||||
epics::pvData::shared_vector<const int32>::reference wcr = rodata[0];
|
||||
epics::pvData::shared_vector<const int32>::const_reference rocr = rodata[0];
|
||||
|
||||
testOk1(wcr==rocr);
|
||||
|
||||
@@ -227,7 +228,7 @@ static void testConst()
|
||||
|
||||
testOk1(rodata.data()==compare);
|
||||
|
||||
epics::pvData::shared_vector<const int> rodata2(rodata);
|
||||
epics::pvData::shared_vector<const int32> rodata2(rodata);
|
||||
|
||||
testOk1(rodata.data()==rodata2.data());
|
||||
|
||||
@@ -240,9 +241,9 @@ static void testSlice()
|
||||
{
|
||||
testDiag("Test vector slicing");
|
||||
|
||||
epics::pvData::shared_vector<int> original(10, 100);
|
||||
epics::pvData::shared_vector<int32> original(10, 100);
|
||||
|
||||
epics::pvData::shared_vector<int> half1(original), half2(original), half2a(original);
|
||||
epics::pvData::shared_vector<int32> half1(original), half2(original), half2a(original);
|
||||
|
||||
half1.slice(0, 5);
|
||||
half2.slice(5, 5);
|
||||
@@ -290,9 +291,9 @@ static void testCapacity()
|
||||
{
|
||||
testDiag("Test vector capacity");
|
||||
|
||||
epics::pvData::shared_vector<int> vect(10, 100);
|
||||
epics::pvData::shared_vector<int32> vect(10, 100);
|
||||
|
||||
int *peek = vect.dataPtr().get();
|
||||
int32 *peek = vect.dataPtr().get();
|
||||
|
||||
vect.slice(0, 5);
|
||||
|
||||
@@ -330,7 +331,7 @@ static void testCapacity()
|
||||
|
||||
static void testPush()
|
||||
{
|
||||
epics::pvData::shared_vector<int> vect;
|
||||
epics::pvData::shared_vector<int32> vect;
|
||||
|
||||
testDiag("Test push_back optimizations");
|
||||
|
||||
@@ -357,7 +358,7 @@ static void testVoid()
|
||||
{
|
||||
testDiag("Test vecter cast to/from void");
|
||||
|
||||
epics::pvData::shared_vector<int> typed(4);
|
||||
epics::pvData::shared_vector<int32> typed(4);
|
||||
|
||||
epics::pvData::shared_vector<void> untyped2(epics::pvData::static_shared_vector_cast<void>(typed));
|
||||
|
||||
@@ -366,7 +367,7 @@ static void testVoid()
|
||||
|
||||
untyped2.slice(sizeof(int), 2*sizeof(int));
|
||||
|
||||
typed = epics::pvData::static_shared_vector_cast<int>(untyped2);
|
||||
typed = epics::pvData::static_shared_vector_cast<int32>(untyped2);
|
||||
|
||||
testOk1(typed.dataOffset()==1);
|
||||
testOk1(typed.size()==2);
|
||||
@@ -406,7 +407,7 @@ static void testVectorConvert()
|
||||
{
|
||||
testDiag("Test shared_vector_convert");
|
||||
|
||||
epics::pvData::shared_vector<int> ints(6, 42), moreints;
|
||||
epics::pvData::shared_vector<int32> ints(6, 42), moreints;
|
||||
epics::pvData::shared_vector<float> floats;
|
||||
epics::pvData::shared_vector<string> strings;
|
||||
epics::pvData::shared_vector<void> voids;
|
||||
@@ -414,7 +415,7 @@ static void testVectorConvert()
|
||||
testOk1(ints.unique());
|
||||
|
||||
// no-op convert. Just returns another reference
|
||||
moreints = epics::pvData::shared_vector_convert<int>(ints);
|
||||
moreints = epics::pvData::shared_vector_convert<int32>(ints);
|
||||
|
||||
testOk1(!ints.unique());
|
||||
moreints.clear();
|
||||
@@ -432,11 +433,12 @@ static void testVectorConvert()
|
||||
voids = epics::pvData::shared_vector_convert<void>(ints);
|
||||
|
||||
testOk1(!ints.unique());
|
||||
testOk1(voids.size()==ints.size()*sizeof(int));
|
||||
testOk1(voids.size()==ints.size()*sizeof(int32));
|
||||
|
||||
// convert from void uses shared_vector<void>::original_type()
|
||||
// to find that the actual type is 'int'.
|
||||
// to find that the actual type is 'int32'.
|
||||
// returns a new vector
|
||||
testOk1(voids.original_type()==epics::pvData::pvInt);
|
||||
strings = epics::pvData::shared_vector_convert<string>(voids);
|
||||
|
||||
voids.clear();
|
||||
@@ -450,11 +452,11 @@ static void testWeak()
|
||||
{
|
||||
testDiag("Test weak_ptr counting");
|
||||
|
||||
epics::pvData::shared_vector<int> data(6);
|
||||
epics::pvData::shared_vector<int32> data(6);
|
||||
|
||||
testOk1(data.unique());
|
||||
|
||||
std::tr1::shared_ptr<int> pdata(data.dataPtr());
|
||||
std::tr1::shared_ptr<int32> pdata(data.dataPtr());
|
||||
|
||||
testOk1(!data.unique());
|
||||
|
||||
@@ -462,7 +464,7 @@ static void testWeak()
|
||||
|
||||
testOk1(data.unique());
|
||||
|
||||
std::tr1::weak_ptr<int> wdata(data.dataPtr());
|
||||
std::tr1::weak_ptr<int32> wdata(data.dataPtr());
|
||||
|
||||
testOk1(data.unique()); // True, but I wish it wasn't!!!
|
||||
|
||||
@@ -475,10 +477,10 @@ static void testICE()
|
||||
{
|
||||
testDiag("Test freeze and thaw");
|
||||
|
||||
epics::pvData::shared_vector<int> A(6, 42), C;
|
||||
epics::pvData::shared_vector<const int> B, D;
|
||||
epics::pvData::shared_vector<int32> A(6, 42), C;
|
||||
epics::pvData::shared_vector<const int32> B, D;
|
||||
|
||||
int *check = A.data();
|
||||
int32 *check = A.data();
|
||||
|
||||
// check freeze w/ unique reference
|
||||
|
||||
@@ -537,11 +539,11 @@ static void testICE()
|
||||
|
||||
MAIN(testSharedVector)
|
||||
{
|
||||
testPlan(162);
|
||||
testPlan(163);
|
||||
testDiag("Tests for shared_vector");
|
||||
|
||||
testDiag("sizeof(shared_vector<int>)=%lu",
|
||||
(unsigned long)sizeof(epics::pvData::shared_vector<int>));
|
||||
testDiag("sizeof(shared_vector<int32>)=%lu",
|
||||
(unsigned long)sizeof(epics::pvData::shared_vector<int32>));
|
||||
|
||||
testEmpty();
|
||||
testInternalAlloc();
|
||||
|
||||
@@ -28,14 +28,14 @@ using namespace epics::pvData;
|
||||
|
||||
static bool debug = false;
|
||||
|
||||
void testTimeStamp()
|
||||
void testTimeStampInternal()
|
||||
{
|
||||
testOk1(nanoSecPerSec==1000000000);
|
||||
TimeStamp current;
|
||||
current.getCurrent();
|
||||
printf("current %lli %i milliSec %lli\n",
|
||||
(long long)current.getSecondsPastEpoch(),
|
||||
current.getNanoSeconds(),
|
||||
current.getNanoseconds(),
|
||||
(long long)current.getMilliseconds());
|
||||
time_t tt;
|
||||
current.toTime_t(tt);
|
||||
@@ -45,13 +45,13 @@ void testTimeStamp()
|
||||
"%4.4d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d %d isDst %s\n",
|
||||
ctm.tm_year+1900,ctm.tm_mon + 1,ctm.tm_mday,
|
||||
ctm.tm_hour,ctm.tm_min,ctm.tm_sec,
|
||||
current.getNanoSeconds(),
|
||||
current.getNanoseconds(),
|
||||
(ctm.tm_isdst==0) ? "false" : "true");
|
||||
tt = time(&tt);
|
||||
current.fromTime_t(tt);
|
||||
printf("fromTime_t\ncurrent %lli %i milliSec %lli\n",
|
||||
(long long)current.getSecondsPastEpoch(),
|
||||
current.getNanoSeconds(),
|
||||
current.getNanoseconds(),
|
||||
(long long)current.getMilliseconds());
|
||||
current.toTime_t(tt);
|
||||
memcpy(&ctm,localtime(&tt),sizeof(struct tm));
|
||||
@@ -59,12 +59,12 @@ void testTimeStamp()
|
||||
"%4.4d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d %d isDst %s\n",
|
||||
ctm.tm_year+1900,ctm.tm_mon + 1,ctm.tm_mday,
|
||||
ctm.tm_hour,ctm.tm_min,ctm.tm_sec,
|
||||
current.getNanoSeconds(),
|
||||
current.getNanoseconds(),
|
||||
(ctm.tm_isdst==0) ? "false" : "true");
|
||||
TimeStamp right;
|
||||
TimeStamp left;
|
||||
right.put(current.getSecondsPastEpoch(),current.getNanoSeconds());
|
||||
left.put(current.getSecondsPastEpoch(),current.getNanoSeconds());
|
||||
right.put(current.getSecondsPastEpoch(),current.getNanoseconds());
|
||||
left.put(current.getSecondsPastEpoch(),current.getNanoseconds());
|
||||
double diff;
|
||||
diff = TimeStamp::diff(left,right);
|
||||
if(debug) printf("diff %e\n",diff);
|
||||
@@ -75,7 +75,7 @@ void testTimeStamp()
|
||||
testOk1(!(left<right));
|
||||
testOk1((left>=right));
|
||||
testOk1(!(left>right));
|
||||
left.put(current.getSecondsPastEpoch()+1,current.getNanoSeconds());
|
||||
left.put(current.getSecondsPastEpoch()+1,current.getNanoseconds());
|
||||
diff = TimeStamp::diff(left,right);
|
||||
if(debug) printf("diff %e\n",diff);
|
||||
testOk1(diff==1.0);
|
||||
@@ -85,7 +85,7 @@ void testTimeStamp()
|
||||
testOk1(!(left<right));
|
||||
testOk1((left>=right));
|
||||
testOk1((left>right));
|
||||
left.put(current.getSecondsPastEpoch()-1,current.getNanoSeconds());
|
||||
left.put(current.getSecondsPastEpoch()-1,current.getNanoseconds());
|
||||
diff = TimeStamp::diff(left,right);
|
||||
if(debug) printf("diff %e\n",diff);
|
||||
testOk1(diff==-1.0);
|
||||
@@ -95,7 +95,7 @@ void testTimeStamp()
|
||||
testOk1((left<right));
|
||||
testOk1(!(left>=right));
|
||||
testOk1(!(left>right));
|
||||
left.put(current.getSecondsPastEpoch(),current.getNanoSeconds()-nanoSecPerSec);
|
||||
left.put(current.getSecondsPastEpoch(),current.getNanoseconds()-nanoSecPerSec);
|
||||
diff = TimeStamp::diff(left,right);
|
||||
if(debug) printf("diff %e\n",diff);
|
||||
testOk1(diff==-1.0);
|
||||
@@ -105,7 +105,7 @@ void testTimeStamp()
|
||||
testOk1((left<right));
|
||||
testOk1(!(left>=right));
|
||||
testOk1(!(left>right));
|
||||
left.put(current.getSecondsPastEpoch(),current.getNanoSeconds()-1);
|
||||
left.put(current.getSecondsPastEpoch(),current.getNanoseconds()-1);
|
||||
diff = TimeStamp::diff(left,right);
|
||||
if(debug) printf("diff %e\n",diff);
|
||||
testOk1(diff<0.0);
|
||||
@@ -115,11 +115,11 @@ void testTimeStamp()
|
||||
testOk1((left<right));
|
||||
testOk1(!(left>=right));
|
||||
testOk1(!(left>right));
|
||||
left.put(current.getSecondsPastEpoch(),current.getNanoSeconds());
|
||||
left.put(current.getSecondsPastEpoch(),current.getNanoseconds());
|
||||
left += .1;
|
||||
diff = TimeStamp::diff(left,right);
|
||||
if(debug) printf("diff %e\n",diff);
|
||||
left.put(current.getSecondsPastEpoch(),current.getNanoSeconds());
|
||||
left.put(current.getSecondsPastEpoch(),current.getNanoseconds());
|
||||
int64 inc = -1;
|
||||
left += inc;
|
||||
diff = TimeStamp::diff(left,right);
|
||||
@@ -131,6 +131,6 @@ MAIN(testTimeStamp)
|
||||
{
|
||||
testPlan(37);
|
||||
testDiag("Tests timeStamp");
|
||||
testTimeStamp();
|
||||
testTimeStampInternal();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ namespace {
|
||||
};
|
||||
template<>
|
||||
struct testequal<double> {
|
||||
static bool op(double A, double B) {return fabs(A-B)<1e-300; }
|
||||
static bool op(double A, double B) {return fabs(A-B)<1e-15; }
|
||||
};
|
||||
template<>
|
||||
struct testequal<float> {
|
||||
static bool op(float A, float B) {return fabs(A-B)<1e-30; }
|
||||
static bool op(float A, float B) {return fabs(A-B)<1e-7; }
|
||||
};
|
||||
|
||||
template<typename TO, typename FROM>
|
||||
@@ -117,7 +117,7 @@ namespace {
|
||||
|
||||
MAIN(testTypeCast)
|
||||
{
|
||||
testPlan(122);
|
||||
testPlan(123);
|
||||
|
||||
try {
|
||||
|
||||
@@ -387,7 +387,8 @@ try {
|
||||
FAIL(int8_t, string, "1000");
|
||||
FAIL(int8_t, string, "-1000");
|
||||
|
||||
FAIL(double, string, "1e+10000000");
|
||||
FAIL(double, string, "1e+1000");
|
||||
FAIL(double, string, "-1e+1000");
|
||||
|
||||
FAIL(epics::pvData::boolean, string, "hello");
|
||||
FAIL(epics::pvData::boolean, string, "1");
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
TOP=../..
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
SRC_DIRS += $(PVDATA_TEST)/property
|
||||
|
||||
TESTPROD_HOST += testProperty
|
||||
testProperty_SRCS += testProperty.cpp
|
||||
testHarness_SRCS += testProperty.cpp
|
||||
TESTS += testProperty
|
||||
|
||||
testProperty_LIBS += pvData Com
|
||||
|
||||
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
|
||||
@@ -48,11 +48,15 @@ static string allProperties("alarm,timeStamp,display,control");
|
||||
static PVStructurePtr doubleRecord;
|
||||
static PVStructurePtr enumeratedRecord;
|
||||
|
||||
static void printRecords()
|
||||
{
|
||||
std::cout << "doubleRecord" << std::endl << *doubleRecord << std::endl;
|
||||
std::cout << "enumeratedRecord" << std::endl << *enumeratedRecord << std::endl;
|
||||
}
|
||||
|
||||
static void createRecords()
|
||||
{
|
||||
doubleRecord = standardPVField->scalar(pvDouble,allProperties);
|
||||
if(debug)
|
||||
std::cout << "doubleRecord" << std::endl << *doubleRecord << std::endl;
|
||||
StringArray choices;
|
||||
choices.reserve(4);
|
||||
choices.push_back("1");
|
||||
@@ -60,14 +64,7 @@ static void createRecords()
|
||||
choices.push_back("3");
|
||||
choices.push_back("4");
|
||||
enumeratedRecord = standardPVField->enumerated(choices,alarmTimeStamp);
|
||||
if(debug)
|
||||
std::cout << "enumeratedRecord" << std::endl << *doubleRecord << std::endl;
|
||||
}
|
||||
|
||||
static void printRecords()
|
||||
{
|
||||
std::cout << "doubleRecord" << std::endl << *doubleRecord << std::endl;
|
||||
std::cout << "enumeratedRecord" << std::endl << *doubleRecord << std::endl;
|
||||
if(debug) printRecords();
|
||||
}
|
||||
|
||||
static void testAlarm()
|
||||
@@ -123,7 +120,7 @@ static void testTimeStamp()
|
||||
testOk1(result);
|
||||
pvTimeStamp.get(timeStamp);
|
||||
testOk1(ts.getSecondsPastEpoch()==timeStamp.getSecondsPastEpoch());
|
||||
testOk1(ts.getNanoSeconds()==timeStamp.getNanoSeconds());
|
||||
testOk1(ts.getNanoseconds()==timeStamp.getNanoseconds());
|
||||
testOk1(ts.getUserTag()==timeStamp.getUserTag());
|
||||
time_t tt;
|
||||
timeStamp.toTime_t(tt);
|
||||
@@ -131,10 +128,10 @@ static void testTimeStamp()
|
||||
memcpy(&ctm,localtime(&tt),sizeof(struct tm));
|
||||
if(debug) {
|
||||
printf(
|
||||
"%4.4d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d %d nanoSeconds isDst %s userTag %d\n",
|
||||
"%4.4d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d %d nanoseconds isDst %s userTag %d\n",
|
||||
ctm.tm_year+1900,ctm.tm_mon + 1,ctm.tm_mday,
|
||||
ctm.tm_hour,ctm.tm_min,ctm.tm_sec,
|
||||
timeStamp.getNanoSeconds(),
|
||||
timeStamp.getNanoseconds(),
|
||||
(ctm.tm_isdst==0) ? "false" : "true",
|
||||
timeStamp.getUserTag());
|
||||
}
|
||||
|
||||
@@ -1,65 +1,63 @@
|
||||
TOP=../..
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
SRC_DIRS += $(PVDATA_TEST)/pv
|
||||
|
||||
PROD_HOST += testBitSetUtil
|
||||
TESTPROD_HOST += testBitSetUtil
|
||||
testBitSetUtil_SRCS += testBitSetUtil.cpp
|
||||
testBitSetUtil_LIBS += pvData Com
|
||||
testHarness_SRCS += testBitSetUtil.cpp
|
||||
TESTS += testBitSetUtil
|
||||
|
||||
PROD_HOST += testIntrospect
|
||||
TESTPROD_HOST += testIntrospect
|
||||
testIntrospect_SRCS += testIntrospect.cpp
|
||||
testIntrospect_LIBS += pvData Com
|
||||
testHarness_SRCS += testIntrospect.cpp
|
||||
TESTS += testIntrospect
|
||||
|
||||
PROD_HOST += testPVType
|
||||
TESTPROD_HOST += testPVType
|
||||
testPVType_SRCS += testPVType.cpp
|
||||
testPVType_LIBS += pvData Com
|
||||
testHarness_SRCS += testPVType.cpp
|
||||
TESTS += testPVType
|
||||
|
||||
PROD_HOST += testStandardField
|
||||
TESTPROD_HOST += testStandardField
|
||||
testStandardField_SRCS += testStandardField.cpp
|
||||
testStandardField_LIBS += pvData Com
|
||||
testHarness_SRCS += testStandardField.cpp
|
||||
TESTS += testStandardField
|
||||
|
||||
PROD_HOST += testStandardPVField
|
||||
TESTPROD_HOST += testStandardPVField
|
||||
testStandardPVField_SRCS += testStandardPVField.cpp
|
||||
testStandardPVField_LIBS += pvData Com
|
||||
testHarness_SRCS += testStandardPVField.cpp
|
||||
TESTS += testStandardPVField
|
||||
|
||||
PROD_HOST += testPVData
|
||||
TESTPROD_HOST += testPVData
|
||||
testPVData_SRCS += testPVData.cpp
|
||||
testPVData_LIBS += pvData Com
|
||||
testHarness_SRCS += testPVData.cpp
|
||||
TESTS += testPVData
|
||||
|
||||
PROD_HOST += testConvert
|
||||
TESTPROD_HOST += testPVUnion
|
||||
testPVUnion_SRCS += testPVUnion.cpp
|
||||
testHarness_SRCS += testPVUnion.cpp
|
||||
TESTS += testPVUnion
|
||||
|
||||
TESTPROD_HOST += testConvert
|
||||
testConvert_SRCS += testConvert.cpp
|
||||
testConvert_LIBS += pvData Com
|
||||
testHarness_SRCS += testConvert.cpp
|
||||
TESTS += testConvert
|
||||
|
||||
PROD_HOST += testPVScalarArray
|
||||
TESTPROD_HOST += testPVScalarArray
|
||||
testPVScalarArray_SRCS += testPVScalarArray.cpp
|
||||
testPVScalarArray_LIBS += pvData Com
|
||||
testHarness_SRCS += testPVScalarArray.cpp
|
||||
TESTS += testPVScalarArray
|
||||
|
||||
PROD_HOST += testPVStructureArray
|
||||
TESTPROD_HOST += testPVStructureArray
|
||||
testPVStructureArray_SRCS += testPVStructureArray.cpp
|
||||
testPVStructureArray_LIBS += pvData Com
|
||||
testHarness_SRCS += testPVStructureArray.cpp
|
||||
TESTS += testPVStructureArray
|
||||
|
||||
PROD_HOST += testOperators
|
||||
TESTPROD_HOST += testOperators
|
||||
testOperators_SRCS += testOperators.cpp
|
||||
testOperators_LIBS += pvData Com
|
||||
testHarness_SRCS += testOperators.cpp
|
||||
TESTS += testOperators
|
||||
|
||||
PROD_HOST += testFieldBuilder
|
||||
TESTPROD_HOST += testFieldBuilder
|
||||
testFieldBuilder_SRCS += testFieldBuilder.cpp
|
||||
testFieldBuilder_LIBS += pvData Com
|
||||
testHarness_SRCS += testFieldBuilder.cpp
|
||||
TESTS += testFieldBuilder
|
||||
|
||||
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ static void test()
|
||||
int32 offsetTimeStamp = (int32)pvField->getFieldOffset();
|
||||
pvField = pvs->getSubField("timeStamp.secondsPastEpoch");
|
||||
int32 offsetSeconds = (int32)pvField->getFieldOffset();
|
||||
pvField = pvs->getSubField("timeStamp.nanoSeconds");
|
||||
pvField = pvs->getSubField("timeStamp.nanoseconds");
|
||||
int32 offsetNano = (int32)pvField->getFieldOffset();
|
||||
pvField = pvs->getSubField("timeStamp.userTag");
|
||||
int32 offsetUserTag = (int32)pvField->getFieldOffset();
|
||||
|
||||
@@ -60,7 +60,7 @@ void test_structure()
|
||||
StructureConstPtr s2 = fb->add("s", s)->
|
||||
addArray("sArray", s)->
|
||||
createStructure();
|
||||
testOk1(s2 != 0);
|
||||
testOk1(s2.get()!=0);
|
||||
testOk1(Structure::DEFAULT_ID == s2->getID());
|
||||
testOk1(2 == s2->getFields().size());
|
||||
|
||||
@@ -110,6 +110,23 @@ void test_invalid()
|
||||
}
|
||||
|
||||
|
||||
void test_arraySizeTypes()
|
||||
{
|
||||
testDiag("Test test_arraySizeTypes()");
|
||||
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
StructureConstPtr s = fieldCreate->createFieldBuilder()->
|
||||
addArray("variableArray", pvDouble)->
|
||||
addFixedArray("fixedArray", pvDouble, 10)->
|
||||
addBoundedArray("boundedArray", pvDouble, 1024)->
|
||||
createStructure();
|
||||
testOk1(s.get() != 0);
|
||||
testOk1(Structure::DEFAULT_ID == s->getID());
|
||||
testOk1(3 == s->getFields().size());
|
||||
}
|
||||
|
||||
|
||||
void test_nestedStructure()
|
||||
{
|
||||
testDiag("Test test_nestedStructure()");
|
||||
@@ -224,11 +241,12 @@ void test_nestedStructureArray()
|
||||
|
||||
MAIN(testFieldBuilder)
|
||||
{
|
||||
testPlan(65);
|
||||
testPlan(68);
|
||||
testDiag("Tests for FieldBuilder");
|
||||
|
||||
test_factory();
|
||||
test_structure();
|
||||
test_arraySizeTypes();
|
||||
test_nestedStructure();
|
||||
test_nestedStructureArray();
|
||||
|
||||
|
||||
@@ -59,9 +59,26 @@ static void testScalar() {
|
||||
}
|
||||
|
||||
static void testScalarArrayCommon(ScalarType stype,
|
||||
bool isInteger,bool isNumeric,bool isPrimitive)
|
||||
bool isInteger,bool isNumeric,bool isPrimitive,
|
||||
Array::ArraySizeType sizeType = Array::variable, size_t size = 0)
|
||||
{
|
||||
ScalarArrayConstPtr pscalar = fieldCreate->createScalarArray(stype);
|
||||
ScalarArrayConstPtr pscalar;
|
||||
switch (sizeType)
|
||||
{
|
||||
case Array::variable:
|
||||
pscalar = fieldCreate->createScalarArray(stype);
|
||||
size = 0;
|
||||
break;
|
||||
case Array::bounded:
|
||||
pscalar = fieldCreate->createBoundedScalarArray(stype, size);
|
||||
break;
|
||||
case Array::fixed:
|
||||
pscalar = fieldCreate->createFixedScalarArray(stype, size);
|
||||
break;
|
||||
default:
|
||||
throw std::invalid_argument("unsupported array size type");
|
||||
}
|
||||
|
||||
Type type = pscalar->getType();
|
||||
testOk1(type==scalarArray);
|
||||
|
||||
@@ -69,6 +86,9 @@ static void testScalarArrayCommon(ScalarType stype,
|
||||
oss << type;
|
||||
testOk1(oss.str().compare("scalarArray")==0);
|
||||
|
||||
testOk1(pscalar->getArraySizeType()==sizeType);
|
||||
testOk1(pscalar->getMaximumCapacity()==size);
|
||||
|
||||
ScalarType scalarType = pscalar->getElementType();
|
||||
testOk1(scalarType==stype);
|
||||
testOk1(ScalarTypeFunc::isInteger(scalarType)==isInteger);
|
||||
@@ -86,6 +106,24 @@ static void testScalarArray() {
|
||||
testScalarArrayCommon(pvFloat,false,true,true);
|
||||
testScalarArrayCommon(pvDouble,false,true,true);
|
||||
testScalarArrayCommon(pvString,false,false,false);
|
||||
|
||||
testScalarArrayCommon(pvBoolean,false,false,true,Array::bounded,10);
|
||||
testScalarArrayCommon(pvByte,true,true,true,Array::bounded,10);
|
||||
testScalarArrayCommon(pvShort,true,true,true,Array::bounded,10);
|
||||
testScalarArrayCommon(pvInt,true,true,true,Array::bounded,10);
|
||||
testScalarArrayCommon(pvLong,true,true,true,Array::bounded,10);
|
||||
testScalarArrayCommon(pvFloat,false,true,true,Array::bounded,10);
|
||||
testScalarArrayCommon(pvDouble,false,true,true,Array::bounded,10);
|
||||
testScalarArrayCommon(pvString,false,false,false,Array::bounded,10);
|
||||
|
||||
testScalarArrayCommon(pvBoolean,false,false,true,Array::fixed,16);
|
||||
testScalarArrayCommon(pvByte,true,true,true,Array::fixed,16);
|
||||
testScalarArrayCommon(pvShort,true,true,true,Array::fixed,16);
|
||||
testScalarArrayCommon(pvInt,true,true,true,Array::fixed,16);
|
||||
testScalarArrayCommon(pvLong,true,true,true,Array::fixed,16);
|
||||
testScalarArrayCommon(pvFloat,false,true,true,Array::fixed,16);
|
||||
testScalarArrayCommon(pvDouble,false,true,true,Array::fixed,16);
|
||||
testScalarArrayCommon(pvString,false,false,false,Array::fixed,16);
|
||||
}
|
||||
|
||||
static void testStructure()
|
||||
@@ -187,6 +225,21 @@ static void testUnion()
|
||||
|
||||
}
|
||||
|
||||
static void testBoundedString()
|
||||
{
|
||||
testDiag("testBoundedString");
|
||||
|
||||
BoundedStringConstPtr bs = fieldCreate->createBoundedString(8);
|
||||
|
||||
Type type = bs->getType();
|
||||
testOk1(type==scalar);
|
||||
|
||||
ScalarType scalarType = bs->getScalarType();
|
||||
testOk1(scalarType==pvString);
|
||||
|
||||
testOk1(bs->getMaximumLength()==8);
|
||||
}
|
||||
|
||||
|
||||
#define testExcept(EXCEPT, CMD) try{ CMD; testFail( "No exception from: " #CMD); } \
|
||||
catch(EXCEPT& e) {testPass("Got expected exception from: " #CMD);} \
|
||||
@@ -236,6 +289,9 @@ static void testError()
|
||||
static void testMapping()
|
||||
{
|
||||
#define OP(TYPE, ENUM) \
|
||||
printf(#TYPE ": sizeof %u typeid '%s' ScalarTypeID %d\n",\
|
||||
(unsigned)sizeof(TYPE), typeid(TYPE).name(),\
|
||||
epics::pvData::ScalarTypeID<TYPE>::value);\
|
||||
testOk1(typeid(ScalarTypeTraits<ENUM>::type)==typeid(TYPE)); \
|
||||
testOk1(ENUM==(ScalarType)ScalarTypeID<TYPE>::value); \
|
||||
testOk1(ENUM==(ScalarType)ScalarTypeID<const TYPE>::value);
|
||||
@@ -253,12 +309,11 @@ static void testMapping()
|
||||
OP(string, pvString)
|
||||
#undef OP
|
||||
|
||||
testOk1((ScalarType)ScalarTypeID<PVField>::value==(ScalarType)-1);
|
||||
}
|
||||
|
||||
MAIN(testIntrospect)
|
||||
{
|
||||
testPlan(180);
|
||||
testPlan(326);
|
||||
fieldCreate = getFieldCreate();
|
||||
pvDataCreate = getPVDataCreate();
|
||||
standardField = getStandardField();
|
||||
@@ -266,6 +321,7 @@ MAIN(testIntrospect)
|
||||
testScalarArray();
|
||||
testStructure();
|
||||
testUnion();
|
||||
testBoundedString();
|
||||
testError();
|
||||
testMapping();
|
||||
return testDone();
|
||||
|
||||
@@ -197,45 +197,45 @@ static void testPVScalarWithProperties(
|
||||
}
|
||||
PVLongPtr seconds = pvStructure->getLongField(
|
||||
string("timeStamp.secondsPastEpoch"));
|
||||
testOk1(seconds!=0);
|
||||
testOk1(seconds.get()!=0);
|
||||
seconds->put(123456789);
|
||||
PVIntPtr nano = pvStructure->getIntField(string("timeStamp.nanoSeconds"));
|
||||
testOk1(nano!=0);
|
||||
PVIntPtr nano = pvStructure->getIntField(string("timeStamp.nanoseconds"));
|
||||
testOk1(nano.get()!=0);
|
||||
nano->put(1000000);
|
||||
PVIntPtr severity = pvStructure->getIntField(string("alarm.severity"));
|
||||
testOk1(severity!=0);
|
||||
testOk1(severity.get()!=0);
|
||||
severity->put(2);
|
||||
PVStringPtr message = pvStructure->getStringField(string("alarm.message"));
|
||||
testOk1(message!=0);
|
||||
testOk1(message.get()!=0);
|
||||
message->put(string("messageForAlarm"));
|
||||
if(hasDisplayControl) {
|
||||
PVStringPtr desc = pvStructure->getStringField(
|
||||
string("display.description"));
|
||||
testOk1(desc!=0);
|
||||
testOk1(desc.get()!=0);
|
||||
desc->put(string("this is a description"));
|
||||
PVStringPtr format = pvStructure->getStringField(
|
||||
string("display.format"));
|
||||
testOk1(format!=0);
|
||||
testOk1(format.get()!=0);
|
||||
format->put(string("f10.2"));
|
||||
PVStringPtr units = pvStructure->getStringField(
|
||||
string("display.units"));
|
||||
testOk1(units!=0);
|
||||
testOk1(units.get()!=0);
|
||||
units->put(string("SomeUnits"));
|
||||
PVDoublePtr limit = pvStructure->getDoubleField(
|
||||
string("display.limitLow"));
|
||||
testOk1(limit!=0);
|
||||
testOk1(limit.get()!=0);
|
||||
limit->put(0.0);
|
||||
limit = pvStructure->getDoubleField(
|
||||
string("display.limitHigh"));
|
||||
testOk1(limit!=0);
|
||||
testOk1(limit.get()!=0);
|
||||
limit->put(10.0);
|
||||
limit = pvStructure->getDoubleField(
|
||||
string("control.limitLow"));
|
||||
testOk1(limit!=0);
|
||||
testOk1(limit.get()!=0);
|
||||
limit->put(1.0);
|
||||
limit = pvStructure->getDoubleField(
|
||||
string("control.limitHigh"));
|
||||
testOk1(limit!=0);
|
||||
testOk1(limit.get()!=0);
|
||||
limit->put(9.0);
|
||||
}
|
||||
if(hasValueAlarm) {
|
||||
@@ -255,15 +255,15 @@ static void testPVScalarWithProperties(
|
||||
convert->fromDouble(pvtemp,9.0);
|
||||
severity = pvStructure->getIntField(
|
||||
string("valueAlarm.lowAlarmSeverity"));
|
||||
testOk1(severity!=0);
|
||||
testOk1(severity.get()!=0);
|
||||
severity->put(2);
|
||||
severity = pvStructure->getIntField(
|
||||
string("valueAlarm.highAlarmSeverity"));
|
||||
testOk1(severity!=0);
|
||||
testOk1(severity.get()!=0);
|
||||
severity->put(2);
|
||||
PVBooleanPtr active = pvStructure->getBooleanField(
|
||||
string("valueAlarm.active"));
|
||||
testOk1(active!=0);
|
||||
testOk1(active.get()!=0);
|
||||
active->put(true);
|
||||
}
|
||||
if(hasBooleanAlarm) {
|
||||
@@ -273,15 +273,15 @@ static void testPVScalarWithProperties(
|
||||
pvBoolean->put(true);
|
||||
severity = pvStructure->getIntField(
|
||||
string("valueAlarm.falseSeverity"));
|
||||
testOk1(severity!=0);
|
||||
testOk1(severity.get()!=0);
|
||||
severity->put(0);
|
||||
severity = pvStructure->getIntField(
|
||||
string("valueAlarm.trueSeverity"));
|
||||
testOk1(severity!=0);
|
||||
testOk1(severity.get()!=0);
|
||||
severity->put(2);
|
||||
severity = pvStructure->getIntField(
|
||||
string("valueAlarm.changeStateSeverity"));
|
||||
testOk1(severity!=0);
|
||||
testOk1(severity.get()!=0);
|
||||
severity->put(1);
|
||||
}
|
||||
if(debug)
|
||||
@@ -345,7 +345,7 @@ static void testScalarArrayCommon(string /*fieldName*/,ScalarType stype)
|
||||
if(debug)
|
||||
std::cout << *pvStructure << std::endl;
|
||||
PVFieldPtr pvField = pvStructure->getSubField("alarm.status");
|
||||
testOk1(pvField!=NULL);
|
||||
testOk1(pvField.get()!=0);
|
||||
}
|
||||
|
||||
static void testScalarArray()
|
||||
|
||||
@@ -108,7 +108,7 @@ static void testBasic()
|
||||
|
||||
{
|
||||
typename PVT::const_svector avoid;
|
||||
arr1->PVScalarArray::getAs<typename PVT::value_type>(avoid);
|
||||
arr1->PVScalarArray::template getAs<typename PVT::value_type>(avoid);
|
||||
testOk1(avoid.data()==cdata.data());
|
||||
testOk1(avoid.data()==arr1->view().data());
|
||||
}
|
||||
@@ -133,7 +133,7 @@ static void testBasic()
|
||||
testOk1(cdata.size()==arr1->getLength());
|
||||
|
||||
PVIntArray::const_svector idata;
|
||||
arr1->PVScalarArray::getAs<int32>(idata);
|
||||
arr1->PVScalarArray::template getAs<int32>(idata);
|
||||
|
||||
testOk1(idata.at(1)==10);
|
||||
|
||||
@@ -143,7 +143,7 @@ static void testBasic()
|
||||
|
||||
idata = freeze(wdata);
|
||||
|
||||
arr1->PVScalarArray::putFrom<int32>(idata);
|
||||
arr1->PVScalarArray::template putFrom<int32>(idata);
|
||||
|
||||
testOk1(castUnsafe<PVIntArray::value_type>(arr1->view()[1])==42);
|
||||
}
|
||||
|
||||
125
testApp/pv/testPVUnion.cpp
Normal file
125
testApp/pv/testPVUnion.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/* testPVUnion.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: 2014.07 */
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
static bool debug = false;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
static StandardFieldPtr standardField = getStandardField();
|
||||
static StandardPVFieldPtr standardPVField = getStandardPVField();
|
||||
static ConvertPtr convert = getConvert();
|
||||
|
||||
static void testPVUnionType()
|
||||
{
|
||||
if(debug)
|
||||
std::cout << std::endl << "testPVUnion" << std::endl;
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(
|
||||
standardField->regUnion(
|
||||
fieldCreate->createFieldBuilder()->
|
||||
add("doubleValue", pvDouble)->
|
||||
add("intValue", pvInt)->
|
||||
add("timeStamp",standardField->timeStamp())->
|
||||
createUnion(),
|
||||
"alarm,timeStamp"));
|
||||
PVUnionPtr pvValue = pvStructure->getSubField<PVUnion>("value");
|
||||
PVStructurePtr pvTime= pvValue->select<PVStructure>(2);
|
||||
TimeStamp timeStamp;
|
||||
timeStamp.getCurrent();
|
||||
PVTimeStamp pvTimeStamp;
|
||||
pvTimeStamp.attach(pvTime);
|
||||
pvTimeStamp.set(timeStamp);
|
||||
testOk1(
|
||||
pvTime->getSubField<PVLong>("secondsPastEpoch")->get()
|
||||
==
|
||||
pvValue->get<PVStructure>()->getSubField<PVLong>("secondsPastEpoch")->get()
|
||||
);
|
||||
PVDoublePtr pvDouble = pvValue->select<PVDouble>("doubleValue");
|
||||
pvDouble->put(1e5);
|
||||
testOk1(pvDouble->get()==pvValue->get<PVDouble>()->get());
|
||||
PVIntPtr pvInt = pvValue->select<PVInt>("intValue");
|
||||
pvInt->put(15);
|
||||
testOk1(pvInt->get()==pvValue->get<PVInt>()->get());
|
||||
std::cout << "testPVUnion PASSED" << std::endl;
|
||||
}
|
||||
|
||||
static void testPVUnionArray()
|
||||
{
|
||||
if(debug)
|
||||
std::cout << std::endl << "testPVUnion" << std::endl;
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(
|
||||
standardField->unionArray(
|
||||
fieldCreate->createFieldBuilder()->
|
||||
add("doubleValue", pvDouble)->
|
||||
add("intValue", pvInt)->
|
||||
add("timeStamp",standardField->timeStamp())->
|
||||
createUnion(),
|
||||
"alarm,timeStamp"));
|
||||
PVUnionArrayPtr pvValue = pvStructure->getSubField<PVUnionArray>("value");
|
||||
size_t num = 3;
|
||||
shared_vector<PVUnionPtr> unions(3);
|
||||
for(size_t i=0; i<num; ++i)
|
||||
{
|
||||
unions[i] = pvDataCreate->createPVUnion(pvValue->getUnionArray()->getUnion());
|
||||
}
|
||||
unions[0]->select("doubleValue");
|
||||
unions[1]->select("intValue");
|
||||
unions[2]->select("timeStamp");
|
||||
PVDoublePtr pvDouble = unions[0]->get<PVDouble>();
|
||||
pvDouble->put(1.235);
|
||||
PVIntPtr pvInt = unions[1]->get<PVInt>();
|
||||
pvInt->put(5);
|
||||
PVStructurePtr pvTime = unions[2]->get<PVStructure>();
|
||||
TimeStamp timeStamp;
|
||||
timeStamp.getCurrent();
|
||||
PVTimeStamp pvTimeStamp;
|
||||
pvTimeStamp.attach(pvTime);
|
||||
pvTimeStamp.set(timeStamp);
|
||||
pvValue->replace(freeze(unions));
|
||||
shared_vector<const PVUnionPtr> sharedUnions = pvValue->view();
|
||||
testOk1(pvDouble->get()==sharedUnions[0]->get<PVDouble>()->get());
|
||||
testOk1(pvInt->get()==sharedUnions[1]->get<PVInt>()->get());
|
||||
testOk1(
|
||||
pvTime->getSubField<PVLong>("secondsPastEpoch")->get()
|
||||
==
|
||||
sharedUnions[2]->get<PVStructure>()->getSubField<PVLong>("secondsPastEpoch")->get()
|
||||
);
|
||||
std::cout << "testPVUnionArray PASSED" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
MAIN(testPVUnion)
|
||||
{
|
||||
testPlan(6);
|
||||
testPVUnionType();
|
||||
testPVUnionArray();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
86
testApp/pvDataAllTests.c
Normal file
86
testApp/pvDataAllTests.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Run pvData tests as a batch.
|
||||
*
|
||||
* Do *not* include performance measurements here, they don't help to
|
||||
* prove functionality (which is the point of this convenience routine).
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <epicsThread.h>
|
||||
#include <epicsUnitTest.h>
|
||||
|
||||
/* copy */
|
||||
int testCreateRequest(void);
|
||||
int testPVCopy(void);
|
||||
|
||||
/* misc */
|
||||
int testBaseException(void);
|
||||
int testBitSet(void);
|
||||
int testByteBuffer(void);
|
||||
int testMessageQueue(void);
|
||||
int testOverrunBitSet(void);
|
||||
int testQueue(void);
|
||||
int testSerialization(void);
|
||||
int testSharedVector(void);
|
||||
int testThread(void);
|
||||
int testTimeStamp(void);
|
||||
int testTimer(void);
|
||||
int testTypeCast(void);
|
||||
|
||||
/* property */
|
||||
int testCreateRequest(void);
|
||||
|
||||
/* pv */
|
||||
int testBitSetUtil(void);
|
||||
int testConvert(void);
|
||||
int testFieldBuilder(void);
|
||||
int testIntrospect(void);
|
||||
int testOperators(void);
|
||||
int testPVData(void);
|
||||
int testPVScalarArray(void);
|
||||
int testPVStructureArray(void);
|
||||
int testPVType(void);
|
||||
int testPVUnion(void);
|
||||
int testStandardField(void);
|
||||
int testStandardPVField(void);
|
||||
|
||||
void pvDataAllTests(void)
|
||||
{
|
||||
testHarness();
|
||||
|
||||
/* pv */
|
||||
runTest(testBitSetUtil);
|
||||
runTest(testConvert);
|
||||
runTest(testFieldBuilder);
|
||||
runTest(testIntrospect);
|
||||
runTest(testOperators);
|
||||
runTest(testPVData);
|
||||
runTest(testPVScalarArray);
|
||||
runTest(testPVStructureArray);
|
||||
runTest(testPVType);
|
||||
runTest(testPVUnion);
|
||||
runTest(testStandardField);
|
||||
runTest(testStandardPVField);
|
||||
|
||||
/* misc */
|
||||
runTest(testBaseException);
|
||||
runTest(testBitSet);
|
||||
runTest(testByteBuffer);
|
||||
runTest(testMessageQueue);
|
||||
runTest(testOverrunBitSet);
|
||||
runTest(testQueue);
|
||||
runTest(testSerialization);
|
||||
runTest(testSharedVector);
|
||||
runTest(testThread);
|
||||
runTest(testTimeStamp);
|
||||
runTest(testTimer);
|
||||
runTest(testTypeCast);
|
||||
|
||||
/* copy */
|
||||
runTest(testCreateRequest);
|
||||
runTest(testPVCopy);
|
||||
|
||||
/* property */
|
||||
runTest(testCreateRequest);
|
||||
}
|
||||
|
||||
1
testApp/qemuRunTest.sh
Executable file
1
testApp/qemuRunTest.sh
Executable file
@@ -0,0 +1 @@
|
||||
qemu-system-i386 --kernel O.RTEMS-pc386/rtemsTestHarness -netdev user,id=mynet0 -device ne2k_isa,netdev=mynet0 -redir tcp:5075::5075 -redir udp:5076::5076 -m 1024 --no-reboot -curses
|
||||
72
testApp/rtemsConfig.c
Normal file
72
testApp/rtemsConfig.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* RTEMS configuration for EPICS
|
||||
* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
* Author: W. Eric Norum
|
||||
* norume@aps.anl.gov
|
||||
* (630) 252-4793
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* RTEMS CONFIGURATION *
|
||||
***********************************************************************
|
||||
*/
|
||||
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||
|
||||
#if __RTEMS_MAJOR__>4 || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99)
|
||||
# define CONFIGURE_UNIFIED_WORK_AREAS
|
||||
#else
|
||||
# define CONFIGURE_EXECUTIVE_RAM_SIZE (2000*1024)
|
||||
#endif
|
||||
|
||||
#define CONFIGURE_MAXIMUM_TASKS rtems_resource_unlimited(30)
|
||||
#define CONFIGURE_MAXIMUM_SEMAPHORES rtems_resource_unlimited(500)
|
||||
#define CONFIGURE_MAXIMUM_TIMERS rtems_resource_unlimited(20)
|
||||
#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES rtems_resource_unlimited(5)
|
||||
#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
|
||||
|
||||
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 150
|
||||
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
|
||||
#define CONFIGURE_MAXIMUM_DRIVERS 8
|
||||
|
||||
#define CONFIGURE_MICROSECONDS_PER_TICK 20000
|
||||
|
||||
#define CONFIGURE_INIT_TASK_PRIORITY 80
|
||||
|
||||
#define CONFIGURE_MALLOC_STATISTICS 1
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
#define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | \
|
||||
RTEMS_NO_TIMESLICE | \
|
||||
RTEMS_NO_ASR | \
|
||||
RTEMS_INTERRUPT_LEVEL(0))
|
||||
#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_FLOATING_POINT | RTEMS_LOCAL)
|
||||
#define CONFIGURE_INIT_TASK_STACK_SIZE (16*1024)
|
||||
rtems_task Init (rtems_task_argument argument);
|
||||
|
||||
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
||||
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||
|
||||
#define CONFIGURE_FILESYSTEM_NFS
|
||||
#define CONFIGURE_FILESYSTEM_IMFS
|
||||
|
||||
/*
|
||||
* This should be made BSP dependent, not CPU dependent but I know of no
|
||||
* appropriate conditionals to use.
|
||||
* The new general time support makes including the RTC driverr less important.
|
||||
*/
|
||||
#if !defined(mpc604) && !defined(__mc68040__) && !defined(__mcf5200__) && !defined(mpc7455) && !defined(__arm__) /* don't have RTC code */
|
||||
#define CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER
|
||||
#endif
|
||||
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/confdefs.h>
|
||||
294
testApp/rtemsNetworking.h
Normal file
294
testApp/rtemsNetworking.h
Normal file
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Network configuration -- QEMU NOT using DHCP
|
||||
*
|
||||
************************************************************
|
||||
* EDIT THIS FILE TO REFLECT YOUR NETWORK CONFIGURATION *
|
||||
* BEFORE RUNNING ANY RTEMS PROGRAMS WHICH USE THE NETWORK! *
|
||||
************************************************************
|
||||
*
|
||||
* The dynamic probing is based upon the EPICS network
|
||||
* configuration file written by:
|
||||
* W. Eric Norum
|
||||
* eric.norum@usask.ca
|
||||
* (306) 966-5394
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_NETWORKCONFIG_H_
|
||||
#define _RTEMS_NETWORKCONFIG_H_
|
||||
|
||||
/* #define USE_LIBBSDPORT */
|
||||
|
||||
#if defined(USE_LIBBSDPORT)
|
||||
#include <bsp/libbsdport_api.h>
|
||||
#define CONFIGURE_MAXIMUM_TIMERS 10
|
||||
#endif
|
||||
/*
|
||||
* For TFTP test application
|
||||
*/
|
||||
#if (defined (RTEMS_USE_BOOTP))
|
||||
#define RTEMS_TFTP_TEST_HOST_NAME "BOOTP_HOST"
|
||||
#define RTEMS_TFTP_TEST_FILE_NAME "BOOTP_FILE"
|
||||
#else
|
||||
#define RTEMS_TFTP_TEST_HOST_NAME "XXX.YYY.ZZZ.XYZ"
|
||||
#define RTEMS_TFTP_TEST_FILE_NAME "tftptest"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For NFS test application
|
||||
*
|
||||
* NFS mount and a directory to ls once mounted
|
||||
*/
|
||||
#define RTEMS_NFS_SERVER "192.168.1.210"
|
||||
#define RTEMS_NFS_SERVER_PATH "/home"
|
||||
#define RTEMS_NFS_LS_PATH "/mnt/nfstest"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This file can be copied to an application source dirctory
|
||||
* and modified to override the values shown below.
|
||||
*
|
||||
* The following CPP symbols may be passed from the Makefile:
|
||||
*
|
||||
* symbol default description
|
||||
*
|
||||
* NETWORK_TASK_PRIORITY 150 can be read by app from public
|
||||
* var 'gesysNetworkTaskPriority'
|
||||
* FIXED_IP_ADDR <undefined> hardcoded IP address (e.g.,
|
||||
* "192.168.0.10"); disables BOOTP;
|
||||
* must also define FIXED_NETMASK
|
||||
* FIXED_NETMASK <undefined> IP netmask string
|
||||
* (e.g. "255.255.255.0")
|
||||
* MULTI_NETDRIVER <undefined> ugly hack; if defined try to probe
|
||||
* a variety of PCI and ISA drivers
|
||||
* (i386 ONLY) use is discouraged!
|
||||
* NIC_NAME <undefined> Ethernet driver name (e.g. "pcn1");
|
||||
* must also define NIC_ATTACH
|
||||
* NIC_ATTACH <undefined> Ethernet driver attach function
|
||||
* (e.g., rtems_fxp_attach).
|
||||
* If these are undefined then
|
||||
* a) MULTI_NETDRIVER is used
|
||||
* (if defined)
|
||||
* b) RTEMS_BSP_NETWORK_DRIVER_NAME/
|
||||
* RTEMS_BSP_NETWORK_DRIVER_ATTACH
|
||||
* are tried
|
||||
* MEMORY_CUSTOM <undefined> Allocate the defined amount of
|
||||
* memory for mbufs and mbuf clusters,
|
||||
* respectively. Define to a comma ','
|
||||
* separated pair of two numerical
|
||||
* values, e.g: 100*1024,200*1024
|
||||
* MEMORY_SCARCE <undefined> Allocate few memory for mbufs
|
||||
* (hint for how much memory the
|
||||
* board has)
|
||||
* MEMORY_HUGE <undefined> Allocate a lot of memory for mbufs
|
||||
* (hint for how much memory the
|
||||
* board has)
|
||||
* If none of MEMORY_CUSTOM/
|
||||
* MEMORY_SCARCE/MEMORY_HUGE are
|
||||
* defined then a medium amount of
|
||||
* memory is allocated for mbufs.
|
||||
*/
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
#include <bsp.h>
|
||||
#include <rtems/rtems_bsdnet.h>
|
||||
|
||||
#if 0
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#else
|
||||
#include "verscheck.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//#define MULTI_NETDRIVER
|
||||
//#define RTEMS_BSP_NETWORK_DRIVER_NAME 1
|
||||
|
||||
#define FIXED_IP_ADDR "192.168.1.249"
|
||||
#define FIXED_NETMASK "255.255.255.0"
|
||||
|
||||
#ifndef NETWORK_TASK_PRIORITY
|
||||
#define NETWORK_TASK_PRIORITY 150 /* within EPICS' range */
|
||||
#endif
|
||||
|
||||
/* make publicily available for startup scripts... */
|
||||
const int gesysNetworkTaskPriority = NETWORK_TASK_PRIORITY;
|
||||
|
||||
#ifdef FIXED_IP_ADDR
|
||||
#define RTEMS_DO_BOOTP 0
|
||||
#else
|
||||
#define RTEMS_DO_BOOTP rtems_bsdnet_do_bootp
|
||||
#define FIXED_IP_ADDR 0
|
||||
#undef FIXED_NETMASK
|
||||
#define FIXED_NETMASK 0
|
||||
#endif
|
||||
|
||||
#if !defined(NIC_NAME)
|
||||
|
||||
#ifdef MULTI_NETDRIVER
|
||||
|
||||
#if 0
|
||||
#if RTEMS_VERSION_ATLEAST(4,6,99)
|
||||
#define pcib_init pci_initialize
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern int rtems_3c509_driver_attach (struct rtems_bsdnet_ifconfig *, int);
|
||||
extern int rtems_fxp_attach (struct rtems_bsdnet_ifconfig *, int);
|
||||
extern int rtems_elnk_driver_attach (struct rtems_bsdnet_ifconfig *, int);
|
||||
extern int rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *, int);
|
||||
|
||||
/* these don't probe and will be used even if there's no device :-( */
|
||||
extern int rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *, int);
|
||||
extern int rtems_wd_driver_attach (struct rtems_bsdnet_ifconfig *, int);
|
||||
|
||||
static struct rtems_bsdnet_ifconfig isa_netdriver_config[] = {
|
||||
{
|
||||
"ep0", rtems_3c509_driver_attach, isa_netdriver_config + 1,
|
||||
},
|
||||
{
|
||||
"ne1", rtems_ne_driver_attach, 0, irno: 9 /* qemu cannot configure irq-no :-(; has it hardwired to 9 */
|
||||
},
|
||||
};
|
||||
|
||||
static struct rtems_bsdnet_ifconfig pci_netdriver_config[]={
|
||||
{
|
||||
"dc1", rtems_dec21140_driver_attach, pci_netdriver_config+1,
|
||||
},
|
||||
#if !defined(USE_LIBBSDPORT)
|
||||
{
|
||||
"fxp1", rtems_fxp_attach, pci_netdriver_config+2,
|
||||
},
|
||||
#else
|
||||
{
|
||||
"", libbsdport_netdriver_attach, pci_netdriver_config+2,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
"elnk1", rtems_elnk_driver_attach, isa_netdriver_config,
|
||||
},
|
||||
};
|
||||
|
||||
static int pci_check(struct rtems_bsdnet_ifconfig *ocfg, int attaching)
|
||||
{
|
||||
struct rtems_bsdnet_ifconfig *cfg;
|
||||
int if_index_pre;
|
||||
extern int if_index;
|
||||
if ( attaching ) {
|
||||
cfg = pci_initialize() ?
|
||||
isa_netdriver_config : pci_netdriver_config;
|
||||
}
|
||||
while ( cfg ) {
|
||||
printk("Probing '%s'", cfg->name);
|
||||
/* unfortunately, the return value is unreliable - some drivers report
|
||||
* success even if they fail.
|
||||
* Check if they chained an interface (ifnet) structure instead
|
||||
*/
|
||||
if_index_pre = if_index;
|
||||
cfg->attach(cfg, attaching);
|
||||
if ( if_index > if_index_pre ) {
|
||||
/* assume success */
|
||||
printk(" .. seemed to work\n");
|
||||
ocfg->name = cfg->name;
|
||||
ocfg->attach = cfg->attach;
|
||||
return 0;
|
||||
}
|
||||
printk(" .. failed\n");
|
||||
cfg = cfg->next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#define NIC_NAME "dummy"
|
||||
#define NIC_ATTACH pci_check
|
||||
|
||||
#else
|
||||
|
||||
#if defined(RTEMS_BSP_NETWORK_DRIVER_NAME) /* Use NIC provided by BSP */
|
||||
|
||||
/* force ne2k_isa on i386 for qemu */
|
||||
#if defined(__i386__)
|
||||
# define NIC_NAME BSP_NE2000_NETWORK_DRIVER_NAME
|
||||
# define NIC_ATTACH BSP_NE2000_NETWORK_DRIVER_ATTACH
|
||||
|
||||
#else
|
||||
|
||||
# define NIC_NAME RTEMS_BSP_NETWORK_DRIVER_NAME
|
||||
# define NIC_ATTACH RTEMS_BSP_NETWORK_DRIVER_ATTACH
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ifdef MULTI_NETDRIVER */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef NIC_NAME
|
||||
|
||||
extern int NIC_ATTACH();
|
||||
|
||||
#if RTEMS_BSP_NETWORK_DRIVER_ATTACH == BSP_NE2000_NETWORK_DRIVER_ATTACH
|
||||
static char ethernet_address[6] = { 0x00, 0xab, 0xcd, 0xef, 0x12, 0x34 };
|
||||
#endif
|
||||
|
||||
static struct rtems_bsdnet_ifconfig netdriver_config[1] = {{
|
||||
NIC_NAME, /* name */
|
||||
(int (*)(struct rtems_bsdnet_ifconfig*,int))NIC_ATTACH, /* attach function */
|
||||
0, /* link to next interface */
|
||||
FIXED_IP_ADDR,
|
||||
FIXED_NETMASK
|
||||
#if RTEMS_BSP_NETWORK_DRIVER_ATTACH == BSP_NE2000_NETWORK_DRIVER_ATTACH
|
||||
,
|
||||
ethernet_address,
|
||||
irno:9,
|
||||
port:0xc100
|
||||
#endif
|
||||
}};
|
||||
#else
|
||||
#warning "NO KNOWN NETWORK DRIVER FOR THIS BSP -- YOU MAY HAVE TO EDIT networkconfig.h"
|
||||
#endif
|
||||
|
||||
struct rtems_bsdnet_config rtems_bsdnet_config = {
|
||||
#ifdef NIC_NAME
|
||||
netdriver_config, /* link to next interface */
|
||||
RTEMS_DO_BOOTP, /* Use BOOTP to get network configuration */
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif
|
||||
NETWORK_TASK_PRIORITY, /* Network task priority */
|
||||
#if defined(MEMORY_CUSTOM)
|
||||
MEMORY_CUSTOM,
|
||||
#elif defined(MEMORY_SCARCE)
|
||||
100*1024, /* MBUF space */
|
||||
200*1024, /* MBUF cluster space */
|
||||
#elif defined(MEMORY_HUGE)
|
||||
2*1024*1024, /* MBUF space */
|
||||
5*1024*1024, /* MBUF cluster space */
|
||||
#else
|
||||
180*1024, /* MBUF space */
|
||||
350*1024, /* MBUF cluster space */
|
||||
#endif
|
||||
#if (!defined (RTEMS_USE_BOOTP)) && defined(ON_RTEMS_LAB_WINSYSTEMS)
|
||||
"rtems", /* Host name */
|
||||
"nodomain.com", /* Domain name */
|
||||
"192.168.1.14", /* Gateway */
|
||||
"192.168.1.1", /* Log host */
|
||||
{"89.212.75.6" }, /* Name server(s) */
|
||||
{"192.168.1.1" }, /* NTP server(s) */
|
||||
#else
|
||||
NULL, /* Host name */
|
||||
NULL, /* Domain name */
|
||||
NULL, /* Gateway */
|
||||
NULL, /* Log host */
|
||||
{ NULL }, /* Name server(s) */
|
||||
{ NULL }, /* NTP server(s) */
|
||||
#endif /* !RTEMS_USE_BOOTP */
|
||||
0, /* efficiency */
|
||||
0, /* udp TX buffer */
|
||||
0, /* udp RX buffer */
|
||||
0, /* tcp TX buffer */
|
||||
0, /* tcp RX buffer */
|
||||
};
|
||||
#endif /* _RTEMS_NETWORKCONFIG_H_ */
|
||||
37
testApp/rtemsTestHarness.c
Normal file
37
testApp/rtemsTestHarness.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <rtems/rtems_bsdnet.h>
|
||||
#include <rtems/error.h>
|
||||
|
||||
#include "rtemsNetworking.h"
|
||||
|
||||
#include <epicsExit.h>
|
||||
#include <osdTime.h>
|
||||
|
||||
rtems_task
|
||||
Init (rtems_task_argument ignored)
|
||||
{
|
||||
rtems_bsdnet_initialize_network ();
|
||||
//rtems_bsdnet_show_if_stats ();
|
||||
|
||||
rtems_time_of_day timeOfDay;
|
||||
if (rtems_clock_get(RTEMS_CLOCK_GET_TOD,&timeOfDay) != RTEMS_SUCCESSFUL) {
|
||||
timeOfDay.year = 2014;
|
||||
timeOfDay.month = 1;
|
||||
timeOfDay.day = 1;
|
||||
timeOfDay.hour = 0;
|
||||
timeOfDay.minute = 0;
|
||||
timeOfDay.second = 0;
|
||||
timeOfDay.ticks = 0;
|
||||
|
||||
rtems_status_code ret = rtems_clock_set(&timeOfDay);
|
||||
if (ret != RTEMS_SUCCESSFUL) {
|
||||
printf("**** Can't set time %s\n", rtems_status_text(ret));
|
||||
}
|
||||
}
|
||||
osdTimeRegister();
|
||||
|
||||
extern void pvDataAllTests(void);
|
||||
pvDataAllTests();
|
||||
epicsExit(0);
|
||||
}
|
||||
Reference in New Issue
Block a user