25 Commits

Author SHA1 Message Date
Matej Sekoranja
72bf9f76a3 forgot to remove friend operator<< 2014-06-19 21:56:56 +02:00
Matej Sekoranja
c0c6213c7c Win32: friend incosistent linkage 2014-06-19 21:24:14 +02:00
Matej Sekoranja
652ef4bc82 merge 2014-06-19 14:29:05 +02:00
Matej Sekoranja
c6eed12139 String -> std::string, toString methods removed 2014-06-19 14:27:48 +02:00
Marty Kraimer
1132e25072 fix bug related to stride 2014-06-13 09:52:30 -04:00
Marty Kraimer
879e3a2b67 support UnionArray 2014-06-12 15:26:31 -04:00
Matej Sekoranja
6ec207141f fixed missing dllimport/dllexport on new code 2014-06-11 11:56:04 +02:00
Matej Sekoranja
45c657ce79 added missing src/copy/Makefile 2014-06-10 13:50:04 +02:00
Matej Sekoranja
888dc11c03 Added tag before_merge_changesAfter3_0_2 for changeset 40b681ffc5cd 2014-06-10 13:39:41 +02:00
Matej Sekoranja
5e3159f800 completed merge 2014-06-09 23:15:57 +02:00
Matej Sekoranja
570ec97eda flow: Closed <feature> 'changesAfter3_0_2'. 2014-06-09 22:53:59 +02:00
Matej Sekoranja
09c75823e6 byteBuffer: wrap support 2014-06-09 08:28:00 +02:00
Marty Kraimer
50c8c3b0bd more work on stride 2014-06-06 11:24:12 -04:00
Marty Kraimer
3fb44312c7 add support for stride 2014-06-05 10:20:01 -04:00
Matej Sekoranja
67bdf2ab8b bitSet <<operator(ostream) 2014-06-01 20:54:07 +02:00
Marty Kraimer
a56ed44e74 fix bugs found by tests in pvIOCJava 2014-05-24 06:47:16 -04:00
Marty Kraimer
3c912c3812 put to union field did not call postPut. 2014-05-21 16:18:38 -04:00
Matej Sekoranja
0ceb87eee1 Array IF added 2014-05-13 00:18:30 +02:00
Marty Kraimer
6510c10884 major update to pvDataCPP.html; minor updates while working on documentation 2014-05-01 10:33:01 -04:00
Marty Kraimer
20345ab0dd forgot monitor.h 2014-04-23 09:16:28 -04:00
Marty Kraimer
d5dfb3de0c added monitorPlugin; fixed bug in PVField::getFullName(); 2014-04-23 09:10:37 -04:00
Marty Kraimer
c2f22a4ad8 make testPVCopy.cpp a proper epicsUnitTest 2014-04-02 10:15:53 -04:00
Marty Kraimer
cb15a8676b remove PVData methods that change introspection interface
remove deprecated methods
move CreateRequest from pvAccessCPP to pvDataCPP
move pvCopy from pvDatabaseCPP to pvDataCPP
2014-04-01 09:35:29 -04:00
Marty Kraimer
34f2d7bc9a created feature branch 2014-03-25 07:23:14 -04:00
Marty Kraimer
fb7f1b622b flow: Created branch 'feature/changesAfter3_0_2'. 2014-03-25 07:04:59 -04:00
101 changed files with 12868 additions and 3209 deletions

View File

@@ -1,11 +1,12 @@
^QtC-
^bin/
^lib/
^doc/
^include/
^db/
^dbd/
^documentation/html
QtC-
bin/
lib/
doc/
include/
db/
dbd/
documentation/html
documentation/*.tag
envPaths
configure/.*\.local
/O\..*

View File

@@ -9,3 +9,4 @@ d70c5ad29163306f50979a95b5aebbe9a93cfe76 2.0-BETA
4cecd4b200f88ab57bbb81978c45df2a67bbece1 3.0.0
2a289ff41e2ed3a0247877306c2db7b266f3b6b8 3.0.1
58092712d092ee521d1e1c8fa596a67f7d113ee9 3.0.2
40b681ffc5cd609320e3f8ffc8eb6aa3bfdfbf19 before_merge_changesAfter3_0_2

View File

@@ -0,0 +1,47 @@
Release release/3.1 IN DEVELOPMENT
===========
The main changes since release 3.0.2 are:
* array semantics now enforce Copy On Write.
* union is new type.
* copy is new.
* monitorPlugin is new.
New Semantics for Arrays
--------
PVScalarArray, PVStructureArray, and PVUnionArray all enforce COW (Copy On Write) Semantics.
In order to limit memory usage the storage for raw data is managed via a new shared_vector facility.
This allows multiple instances of array data to use the shared raw data.
COW is implemented via shared_vectors of const data, i. e. data that can not be modified.
union is a new basic type.
------------
There are two new basic types: union_t and unionArray.
A union is like a structure that has a single subfield.
There are two flavors:
* <b>varient union</b> The field can have any type.
* <b>union</b> The field can any of specified set of types.
The field type can be dynamically changed.
copy
----
This consists of createRequest and pvCopy.
createRequest was moved from pvAccess to here.
pvCopy is moved from pvDatabaseCPP and now depends
only on pvData, i. e. it no longer has any knowledge of PVRecord.
monitorPlugin
-------------
This is for is for use by code that implements pvAccess monitors.
Release 3.0.2
==========
This was the starting point for RELEASE_NOTES

54
documentation/TODO.md Normal file
View File

@@ -0,0 +1,54 @@
TODO
===========
toString, dumpValue, printer, and streams
------------
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.
doxygen
-------
There is a lot of public code that does not have doxygen tags.
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

View File

@@ -0,0 +1,679 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>EPICS pvDataCPP: copy and monitor</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<div id="toc">
<h2 class="nocount" style="page-break-before: always">Table of Contents</h2>
</div>
<div id="contents" class="contents">
<h2>support for copy and monitor</h2>
<p><b>copy</b> and <b>monitor</b> are not used in this project.
They are intended for use by pvAccess and by pvAccess servers.
They are provided with this project because the code depends only on
pvData itself.
</p>
<p>This document describes C++ specific code.
<a href="http://epics-pvdata.sourceforge.net/informative/pvRequest.html">
pvRequest.html</a>
provides a language independent overview of <b>copy</b> and <b>monitor</b>.
</p>
<p>
<b>NOTE:pvRequest.html</b> must be updated since it is based on an earlier version of pvCopy that
had knowlege of PVRecord. The C++ version was implemented in pvDatabaseCPP
and the Java version on pvIOCJava.
At present only the C++ version of the new API for pvCopy is implemented.
</p>
<p>Copy provides:
<dl>
<dt>createRequest</dt>
<dd>
The Channel create methods in pvAccess all have an argument
<b>PVStructure pvRequest</b>.<br />
Given an ascii string createRequest creates a PVStructure that provides
a pvData representation of the information from the ascii string.
It is this structure that can be passed to the channel create methods.<br />
The information in a pvRequest selects an arbitrarary 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.
It provides client specific code that manages a copy of an arbitrary
subset of the fields in a top level structure that resides in the
provider. It also allows provider access to options specified
by the client.
</dd>
</dl>
Monitor provides:
<dl>
<dt>monitor</dt>
<dd>This is support code for channel providers that implement channel
monitor. It, together with the queue facility, provides support for
monitor queues.
</dd>
<dt>monitorPlugin</dt>
<dd>This is support for implementing monitor plugins.
A monitor plugin can be developed that has no knowledge
of pvAccess but only pvData.
</dd>
</dl>
</p>
<h2>support for copy</h2>
<p><b>copy</b> provides the ability to create a structure that has
a copy of an arbitrary subset of the fields in an existing top level
structure. In addition it allows global options and field specific options.
It has two main components: <b>createRequest</b> and <b>pvCopy</b>.
Given a string createRequest creates a pvRequest, which is a PVStructure
that has the format expected by <b>pvCopy</b>.
</p>
<h3>createRequest</h3>
<p>This is mainly used by pvAccess clients. Given a request string it creates
a pvRequest structure that can be passed to the pvAccess create methods.
In turn pvAccess passes the pvRequest to a local channel provider which
then passes it to pvCopy.
</p>
<p>The definition of the public members is:</p>
<pre>
class CreateRequest {
...
static CreateRequestPtr create();
virtual PVStructurePtr createRequest(std::string const &amp;request);
std::string getMessage();
};
</pre>
<p>An example of how it is used is:</p>
<pre>
CreateRequestPtr createRequest = CreateRequest::create();
PVStructurePtr pvRequest = createRequest-&gt;createRequest(request);
if(pvRequest==NULL) {
std::string error = createRequest-&gt;getMessage();
// take some action
} else {
//success do something
}
</pre>
<h3>pvCopy</h3>
<p>The definition of the public members is:</p>
<pre>
class epicsShareClass PVCopyTraverseMasterCallback
{
...
virtual void nextMasterPVField(PVFieldPtr const &amp;pvField);
};
class class epicsShareClass PVCopy
{
...
static PVCopyPtr create(
PVStructurePtr const &amp;pvMaster,
PVStructurePtr const &amp;pvRequest,
std::string const &amp; structureName);
PVStructurePtr getPVMaster();
void traverseMaster(PVCopyTraverseMasterCallbackPtr const &amp; callback);
StructureConstPtr getStructure();
PVStructurePtr createPVStructure();
size_t getCopyOffset(PVFieldPtr const &amp;masterPVField);
size_t getCopyOffset(
PVStructurePtr const &amp;masterPVStructure,
PVFieldPtr const &amp;masterPVField);
PVFieldPtr getMasterPVField(std::size_t structureOffset);
void initCopy(
PVStructurePtr const &amp;copyPVStructure,
BitSetPtr const &amp;bitSet);
void updateCopySetBitSet(
PVStructurePtr const &amp;copyPVStructure,
BitSetPtr const &amp;bitSet);
void updateCopyFromBitSet(
PVStructurePtr const &amp;copyPVStructure,
BitSetPtr const &amp;bitSet);
void updateMaster(
PVStructurePtr const &amp;copyPVStructure,
BitSetPtr const &amp;bitSet);
PVStructurePtr getOptions(std::size_t fieldOffset);
...
};
</pre>
where
<dl>
<dt>PVCopyTraverseMasterCallback::nextMasterPVField</dt>
<dd>
<b>PVCopyTraverseMasterCallback</b> is a callback which must
be implemented by the code that uses pvCopy, normally
the channel provider. It has the single method <b>nextMasterPVField</b>
<br />
<b>nextMasterPVField</b> is called for each field in the master
as a result of a call to <b>traverseMaster</b>.
</dd>
<dt>create</dt>
<dd>
This is the method for creating a PVCopy instance.<br/>
<dl>
<dt>pvMaster</dt>
<dd>the top level sructure managed by the server.</dd>
<dt>pvRequest</dt>
<dd>selects the set of subfields desired
and options for each field.</dd>
<dt>structureName</dt>
<dd>the name for the top level of any PVStructure created.
</dd>
</dl>
</dd>
<dt>getPVMaster</dt>
<dd>
Gets the top level structure from pvMaster.
</dd>
<dt>traverseMaster</dt>
<dd>
Traverse all fields of the top level structure of pvMaster.
For each field the callback is called.
</dd>
<dt>getStructure</dt>
<dd>
Get the introspection interface for a PVStructure for e copy.
</dd>
<dt>createPVStructure</dt>
<dd>Create a copy instance.
Monitors keep a queue of monitor elements.
Since each element needs a PVStructure, multiple top level structures
will be created.
</dd>
<dt>getCopyOffset</dt>
<dd>Given a field in pvMaster.
return the offset in copy for the same field.
A value of std::string::npos means that the copy does not have this field.
Two overloaded methods are provided. The first is called if
the field of master is not a structure. The second is for
subfields of a structure.
</dd>
<dt>getMasterPVField</dt>
<dd>
Given a offset in the copy get the corresponding field in pvMaster.
</dd>
<dt>initCopy</dt>
<dd>
Initialize the fields in copyPVStructure
by giving each field the value from the corresponding field in pvMaster.
bitSet will be set to show that all fields are changed.
This means that bit set will have the value <b>{0}</b>.
</dd>
<dt>updateCopySetBitSet</dt>
<dd>
Set all fields in copyPVStructure to the value of the corresponding field
in pvMaster. Each field that is changed has it's corresponding
bit set in bitSet.
</dd>
<dt>updateCopyFromBitSet</dt>
<dd>
For each set bit in bitSet set the field in copyPVStructure to the value
of the corrseponding 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.
</dd>
<dt>getOptions</dt>
<dd>
Get the options for the field at the specified offset.
A NULL is returned if no options were specified for the field.
If options were specified,PVStructurePtr is
a structure with a set of PVString subfields that specify name,value
pairs. name is the subField name and value is the subField value.
</dd>
</dl>
<h2>support for monitor</h2>
<p>This consists of two components:
<dl>
<dt>monitor</dt>
<dd>Used by code that implements pvAccess montors.</dd>
<dt>monitorPlugin</dt>
<dd>Code that provides special semantics for monitors.</dd>
</dl>
</p>
<h3>monitor</h3>
<pre>
class MonitorElement {
MonitorElement(PVStructurePtr const &amp; pvStructurePtr);
PVStructurePtr pvStructurePtr;
BitSetPtr changedBitSet;
BitSetPtr overrunBitSet;
};
class Monitor {
virtual Status start() = 0;
virtual Status stop() = 0;
virtual MonitorElementPtr poll() = 0;
virtual void release(MonitorElementPtr const &amp; monitorElement) = 0;
};
class MonitorRequester : public virtual Requester {
virtual void monitorConnect(Status const &amp; status,
MonitorPtr const &amp; monitor, StructureConstPtr const &amp; structure) = 0;
virtual void monitorEvent(MonitorPtr const &amp; monitor) = 0;
virtual void unlisten(MonitorPtr const &amp; monitor) = 0;
};
</pre>
<h4>monitorElement</h4>
<p><b>MonitorElement</b> holds the data for one element of a monitor queue.
It has the fields:
<dl>
<dt>pvStructurePtr</dt>
<dd>A top level structure with data values at the time the monitors occurs.</dd>
<dt>changedBitSet</dt>
<dd>Shows which fields have changed since the previous monitor.</dd>
<dt>overrunBitSet</dt>
<dd>Shows which fields have changed more han once since the previous monitor.</dd>
</dl>
</p>
<h4>monitorElement queue</h4>
<p>
A queue of monitor elements must be implemented by any channel provider that implements
<b>Channel::createMonitor</b>.
For an example implementation look at pvDatabaseCPP.
It has the following:
<pre>
typedef Queue&lt;MonitorElement&gt; MonitorElementQueue;
typedef std::tr1::shared_ptr&lt;MonitorElementQueue&gt; MonitorElementQueuePtr;
class MultipleElementQueue :
public ElementQueue
{
public:
POINTER_DEFINITIONS(MultipleElementQueue);
virtual ~MultipleElementQueue(){}
MultipleElementQueue(
MonitorLocalPtr const &amp;monitorLocal,
MonitorElementQueuePtr const &amp;queue,
size_t nfields);
virtual void destroy(){}
virtual Status start();
virtual Status stop();
virtual bool dataChanged();
virtual MonitorElementPtr poll();
virtual void release(MonitorElementPtr const &amp;monitorElement);
...
};
</pre>
<h4>Monitor</h4>
<p><b>Monitor</b> must be implemented by any channel provider that implements
<b>Channel::createMonitor</b>.
Remote PVAccess also implements Monitor on the client side.
Note that each client has it's own queue that is not shared with other client.
</p>
<p>Monitor has the following methods:</p>
<dl>
<dt>start</dt>
<dd>
Start monitoring.
This will result in a an inital monitor that has the current value
of all fields.
</dd>
<dt>stop</dt>
<dd>
Stop monitoring.
</dd>
<dt>poll</dt>
<dd>
Called to get a monitor element.
If no new elemants are available then a null pointer is returned.
</dd>
<dt>release</dt>
<dd>
Release the monotor element.
The caller owns the monitor element between the calls to poll and release.
</dd>
<dl>
</dl>
<h4>MonitorRequester</h4>
<p>This must be implemented by a pvAccess client.
It has the methods:</p>
<dl>
<dt>monitorConnect</dt>
<dd>
A monitor has either connected of disconnected.
</dd>
<dt>monitorEvent</dt>
<dd>
A new monitor element is available.
</dd>
<dt>unlisten</dt>
<dd>
The channel is going away. The client cam no longer access the monitor.
</dd>
</dl>
<h3>monitorPlugin</h3>
<pre>
class MonitorPlugin
{
virtual std::string const &amp; getName() = 0;
virtual bool causeMonitor(
PVFieldPtr const &amp;pvField,
PVStructurePtr const &amp;pvTop,
MonitorElementPtr const &amp;monitorElement) = 0;
virtual void monitorDone(
MonitorElementPtr const &amp;monitorElement);
virtual void startMonitoring();
virtual void stopMonitoring();
virtual void beginGroupPut();
virtual void endGroupPut();
};
class MonitorPluginCreator
{
virtual MonitorPluginPtr create(
FieldConstPtr const &amp;field,
StructureConstPtr const &amp;top,
PVStructurePtr const &amp;pvFieldOptions) = 0;
virtual std::string const &amp; getName() = 0;
}
class MonitorPluginManager
{
static MonitorPluginManagerPtr get();
bool addPlugin(
std::string const &amp;pluginName,
MonitorPluginCreatorPtr const &amp;creator);
MonitorPluginCreatorPtr findPlugin(std::string const &amp;pluginName);
void showNames();
};
</pre>
<h4>MonitorPlugin</h4>
<p><b>MonitorPlugin</b> must be implemented by the plugin implementation.
It has methods:</p>
<dl>
<dt>getName</dt>
<dd>Get the name of the plugin.</dd>
<dt>causeMonitor</dt>
<dd>
Should the value of pvField cause a monitor to be raised.
pvField and pvTop are fields in the top level structure
being monitored. monitorElement has the top level structure
for the copy</b>.
The implementation should <b>not</b> modify the fields in the structure
being monitored.
Called with pvTop locked.
</dd>
<dt>monitorDone</dt>
<dd>
Called just before monitorElement will be given to client.
The plugin can change the data values and bitSets in monitorElement.
Called with pvTop unlocked.
</dd>
<dt>startMonitoring</dt>
<dd>
Monitoring is starting.
</dd>
<dt>stopMonitoring</dt>
<dd>
Monitoring is being stopped.
</dd>
<dt>beginGroupPut</dt>
<dd>
A set of puts is starting.
Called with pvTop locked.
</dd>
<dt>endGroupPut</dt>
<dd>
The set of puts is complete.
Called with pvTop locked.
</dd>
</dl>
<h4>MonitorPluginCreator</h4>
<p><b>MonitorPluginCreator</b> must also be implemented by the plugin implementation.
It is called for each field instance that has options of the from
<b>[plugin=name...]</b> where <b>name</b> is the name of the plugin.
Note that a plugin instance will belong to a single client.
It has methods:</p>
<dl>
<dt>getName</dt>
<dd>Get the name of the plugin.</dd>
<dt>create</dt>
<dd>
Create a new plugin instance.
If the arguments are not compatible with the plugin a NULL shared pointer is
returned.<br/>
pvFieldOptions is
a structure with a set of PVString subfields that specify <b>name,value</b>
pairs. name is the subField name and value is the subField value.<br/>
Note that a plugin will below to a single client.
</dd>
<dl>
<h4>MonitorPluginManager</h4>
<p><b>MonitorPluginManager</b> has the methods:</p>
<dl>
<dt>get</dt>
<dd>
MonitorPluginManager is a singleton.
The first call to get will create the single instance.
Further calls will rerurn the single instance.
</dd>
<dt>addPlugin</dt>
<dd>
Add a new plugin.
</dd>
<dt>findPlugin</dt>
<dd>
Find a plugin. A NULL shared pointer is reurned if it has not been added.
</dd>
<dt>showNames</dt>
<dd>
Show the names of all puugins 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:
<pre>
typedef std::tr1::shared_ptr&lt;const PVField&gt; PVFieldConstPtr;
typedef std::tr1::shared_ptr&lt;const PVStructure&gt; PVStructureConstPtr;
</pre>
then the definition for causeMonitor could be:
<pre>
virtual bool causeMonitor(
PVFieldConstPtr const &amp;pvField,
PVStructureConstPtr const &amp;pvTop,
MonitorElementPtr const &amp;monitorElement) = 0;
</pre>
But just adding these definitions is not sufficent.
In addition all methods defined in pvDataCPP must be checked.
In particular many of the methods in <b>Convert</b> must have
their arguments modified.
Big job.
</p>
<h2>monitorPlugin example</h2>
<h3>Example Plugin Overview</h3>
<p>This section describes an example plugin that:</p>
<ul>
<li>Only raises monitors when a field changes value.<br />
If no plugin is provided
the default is to raise a monitor when a put is issued to a field.</li>
<li>Optionally a change will not raise a monitor.<br />
The change will, however,
appear if a put to another field raise a monitor.</li>
</ul>
<p>As an example assume that a channel provided by pvAccess has a top level structure
that represents a power supply.</p>
<pre>
structure powerSupply
structure alarm
structure timeStamp
structure power
double value
structure alarm
struvture display
structure voltage
double value
structure alarm
struvture display
structure current
double value
structure alarm
struvture display
</pre>
<p>A pvAccess client wants to create a monitor on the powerSupply as follows:
The client wants a top level structure that looks like:
<pre>
structure powerSupply
structure alarm
structure timeStamp
structure power
double value
structure voltage
double value
structure current
double value
</pre>
In addition the client wants monitors to occur only when one of the monitored
fields changes value but not just because a put occured.
Also if only the timeStamp changes value then that should not cause a monitor.
</p>
<p>The example monitor plugin implements the semantics the
client wants. It can be attached to any field via the following options:
<pre>
[plugin=onChange,raiseMonitor=value]
</pre>
This plugin will trigger a monitor for the field only if the field changes
value. In addition <b>value</b> equals <b>false</b> means do not raise a monotor
for changes to this field.
But if a change to another field does cause a monitor the change to this field
will be passed to the client.
</p>
<p>
Assume that the client has already connected to the channel.
The client can then issue the commands:</p>
<pre>
std::string request("field(alarm[plugin=onChange]");
request += ",timeStamp[plugin=onChange,raiseMonitor=false]";
request += ",power.value[plugin=onChange";
request += ",voltage.value[plugin=onChange";
request += ",current.value[plugin=onChange";
PVStructurePtr pvRequest = createRequest-&gt;createRequest(request);
MonitorPtr monitor = channel-&gt;createMonitor(monitorRequester,pvRequest);
</pre>
<h3>Example Plugin Code</h3>
<p>The header file to create the example has the definition:</p>
<pre>
class ExampleMonitorPlugin{
public:
static void create();
};
</pre>
<p>The implementation is:</p>
<pre>
class OnChangePlugin : public MonitorPlugin
{
public:
virtual ~OnChangePlugin(){}
OnChangePlugin() {}
bool init(
FieldConstPtr const &amp;field,
StructureConstPtr const &amp;top,
PVStructurePtr const &amp;pvFieldOptions)
{
pvField = getPVDataCreate()-&gt;createPVField(field);
raiseMonitor = true;
if(pvFieldOptions!=NULL) {
PVStringPtr pvString =
pvFieldOptions-&gt;getSubField&lt;PVString&gt;("raiseMonitor");
if(pvString!=NULL) {
std::string value = pvString-&gt;get();
if(value.compare("false")==0) raiseMonitor = false;
}
}
return true;
}
virtual std::string &amp;getName(){return pluginName;}
virtual bool causeMonitor(
PVFieldPtr const &amp;pvNew,
PVStructurePtr const &amp;pvTop,
MonitorElementPtr const &amp;monitorElement)
{
bool isSame = convert-&gt;equals(pvNew,pvField);
if(isSame) return false;
convert-&gt;copy(pvNew,pvField);
return raiseMonitor;
}
private:
PVFieldPtr pvField;
bool raiseMonitor;
};
class OnChangePluginCreator : public MonitorPluginCreator
{
public:
virtual std::string &amp;getName(){return pluginName;}
virtual MonitorPluginPtr create(
FieldConstPtr const &amp;field,
StructureConstPtr const &amp;top,
PVStructurePtr const &amp;pvFieldOptions)
{
OnChangePluginPtr plugin(new OnChangePlugin());
bool result = plugin-&gt;init(field,top,pvFieldOptions);
if(!result) return MonitorPluginPtr();
return plugin;
}
};
void ExampleMonitorPlugin::create()
{
static OnChangePluginCreatorPtr plugin;
static Mutex mutex;
Lock xx(mutex);
if(plugin==NULL) {
plugin = OnChangePluginCreatorPtr(new OnChangePluginCreator());
MonitorPluginManager::get()-&gt;addPlugin(pluginName,plugin);
}
}
</pre>
</div>
</body>
</html>

BIN
documentation/examples.zip Normal file

Binary file not shown.

View File

@@ -170,7 +170,7 @@ the dumpValue method is replaced by the stream operator&lt;&lt;.
</p>
<h4>Java</h4>
<pre>interface PVField extends Requester, Serializable {
String getFieldName();
std::string getFieldName();
void setRequester(Requester requester);
int getFieldOffset();
int getNextFieldOffset();
@@ -180,12 +180,12 @@ the dumpValue method is replaced by the stream operator&lt;&lt;.
void setImmutable();
Field getField();
PVStructure getParent();
void renameField(String newName);
void renameField(std::string newName);
void postPut(); // calls PVRecordField.postPut if this is a field of a record
void setPostHandler(PostHandler postHandler);
void toString(StringBuilder buf);
void toString(StringBuilder buf,int indentLevel);
String toString();
std::string toString();
}</pre>
<h4>pvDataCPP</h4>
<pre>class PVField
@@ -195,8 +195,8 @@ the dumpValue method is replaced by the stream operator&lt;&lt;.
public:
POINTER_DEFINITIONS(PVField);
virtual ~PVField();
virtual void message(String message,MessageType messageType);
String getFieldName() const ;
virtual void message(std::string message,MessageType messageType);
std::string getFieldName() const ;
virtual void setRequester(RequesterPtr const &amp;prequester);
std::size_t getFieldOffset() const;
std::size_t getNextFieldOffset() const;
@@ -207,7 +207,7 @@ public:
const FieldConstPtr &amp; getField() const ;
PVStructure * getParent() const
void replacePVField(const PVFieldPtr&amp; newPVField);
void renameField(String const &amp;newName);
void renameField(std::string const &amp;newName);
void postPut() ;
void setPostHandler(PostHandlerPtr const &amp;postHandler);
virtual bool equals(PVField &amp;pv);
@@ -227,8 +227,8 @@ std::ostream&amp; operator&lt;&lt;(std::ostream&amp; o, const PVFieldPtr &amp; f
public:
POINTER_DEFINITIONS(PVField);
virtual ~PVField();
virtual void message(String message,MessageType messageType);
String getFieldName() const ;
virtual void message(std::string message,MessageType messageType);
std::string getFieldName() const ;
virtual void setRequester(RequesterPtr const &amp;prequester);
std::size_t getFieldOffset() const;
std::size_t getNextFieldOffset() const;
@@ -239,7 +239,7 @@ public:
const FieldConstPtr &amp; getField() const ;
PVStructure * getParent() const
void replacePVField(const PVFieldPtr&amp; newPVField);
void renameField(String const &amp;newName);
void renameField(std::string const &amp;newName);
void postPut() ;
void setPostHandler(PostHandlerPtr const &amp;postHandler);
virtual bool equals(PVField &amp;pv);
@@ -247,7 +247,7 @@ public:
virtual void toString(StringBuilder buf,int indentLevel);
std::ostream&amp; dumpValue(std::ostream&amp; o) const;
// not in pvDataCPP
String getFullName() const;
std::string getFullName() const;
...
}
@@ -262,8 +262,8 @@ class PVField
public:
POINTER_DEFINITIONS(PVField);
virtual ~PVField();
virtual void message(String message,MessageType messageType);
const String&amp; getFieldName() const;
virtual void message(std::string message,MessageType messageType);
const std::string&amp; getFieldName() const;
virtual void setRequester(RequesterPtr const &amp;prequester);
std::size_t getFieldOffset() const;
std::size_t getNextFieldOffset() const;
@@ -274,7 +274,7 @@ public:
const FieldConstPtr &amp; getField() const;
PVStructure * getParent() const;
void replacePVField(const PVFieldPtr&amp; newPVField);
void renameField(String const &amp; newName);
void renameField(std::string const &amp; newName);
void postPut();
void setPostHandler(PostHandlerPtr const &amp;postHandler);
virtual bool equals(PVField &amp;pv);
@@ -328,8 +328,8 @@ interface PVDouble extends PVScalar {
void put(double value);
}
interface PVString extends PVScalar, SerializableArray {
String get();
void put(String value);
std::string get();
void put(std::string value);
}
</pre>
<h4>pvDataCPP</h4>
@@ -369,7 +369,7 @@ typedef std::tr1::shared_ptr<PVDouble> PVDoublePtr;
// PVString is special case, since it implements SerializableArray
class PVString : public PVScalarValue&lt;String&gt;, SerializableArray {
class PVString : public PVScalarValue&lt;std::string&gt;, SerializableArray {
public:
virtual ~PVString() {}
...
@@ -427,7 +427,7 @@ typedef std::tr1::shared_ptr<PVDouble> PVDoublePtr;
// PVString is special case, since it implements SerializableArray
class PVString : public PVScalarValue&lt;String&gt;, SerializableArray {
class PVString : public PVScalarValue&lt;std::string&gt;, SerializableArray {
public:
virtual ~PVString() {}
...
@@ -472,7 +472,7 @@ typedef std::tr1::shared_ptr&lt;PVByte&gt; PVBytePtr;
typedef std::tr1::shared_ptr&lt;PVDouble&gt; PVDoublePtr;
// PVString is special case, since it implements SerializableArray
class PVString : public PVScalarValue&lt;String&gt;, SerializableArray {
class PVString : public PVScalarValue&lt;std::string&gt;, SerializableArray {
public:
virtual ~PVString() {}
...
@@ -641,8 +641,8 @@ typedef PVArrayData&lt;uint8&gt; BooleanArrayData;
typedef PVValueArray&lt;uint8&gt; PVBooleanArray;
typedef std::tr1::shared_ptr&lt;PVBooleanArray&gt; PVBooleanArrayPtr;
...
typedef PVArrayData&lt;String&gt; StringArrayData;
typedef PVValueArray&lt;String&gt; PVStringArray;
typedef PVArrayData&lt;std::string&gt; StringArrayData;
typedef PVValueArray&lt;std::string&gt; PVStringArray;
typedef std::tr1::shared_ptr&lt;PVStringArray&gt; PVStringArrayPtr;i
</pre>
@@ -786,8 +786,8 @@ typedef PVArrayData&lt;uint8&gt; BooleanArrayData;
typedef PVValueArray&lt;uint8&gt; PVBooleanArray;
typedef std::tr1::shared_ptr&lt;PVBooleanArray&gt; PVBooleanArrayPtr;
...
typedef PVArrayData&lt;String&gt; StringArrayData;
typedef PVValueArray&lt;String&gt; PVStringArray;
typedef PVArrayData&lt;std::string&gt; StringArrayData;
typedef PVValueArray&lt;std::string&gt; PVStringArray;
typedef std::tr1::shared_ptr&lt;PVStringArray&gt; PVStringArrayPtr;i
</pre>
<h4>proposed</h4>
@@ -843,7 +843,7 @@ public:
typedef PVValueArray&lt;uint8&gt; PVBooleanArray;
typedef std::tr1::shared_ptr&lt;PVBooleanArray&gt; PVBooleanArrayPtr;
...
typedef PVValueArray&lt;String&gt; PVStringArray;
typedef PVValueArray&lt;std::string&gt; PVStringArray;
typedef std::tr1::shared_ptr&lt;PVStringArray&gt; PVStringArrayPtr;
</pre>
@@ -865,8 +865,8 @@ class PVField
public:
POINTER_DEFINITIONS(PVField);
virtual ~PVField();
virtual void message(String message,MessageType messageType);
const String&amp; getFieldName() const;
virtual void message(std::string message,MessageType messageType);
const std::string&amp; getFieldName() const;
virtual void setRequester(RequesterPtr const &amp;prequester);
std::size_t getFieldOffset() const;
std::size_t getNextFieldOffset() const;
@@ -877,7 +877,7 @@ public:
const FieldConstPtr &amp; getField() const;
PVStructure * getParent() const;
void replacePVField(const PVFieldPtr&amp; newPVField);
void renameField(String const &amp; newName);
void renameField(std::string const &amp; newName);
void postPut();
void setPostHandler(PostHandlerPtr const &amp;postHandler);
virtual bool equals(PVField &amp;pv);
@@ -1006,7 +1006,7 @@ typedef std::tr1::shared_ptr&lt;PVFloat&gt; PVFloatPtr;
typedef std::tr1::shared_ptr&lt;PVDouble&gt; PVDoublePtr;
// PVString is special case, since it implements SerializableArray
class PVString : public PVScalarValue&lt;String&gt;, SerializableArray {
class PVString : public PVScalarValue&lt;std::string&gt;, SerializableArray {
public:
virtual ~PVString() {}
...
@@ -1144,7 +1144,7 @@ typedef std::tr1::shared_ptr&lt;PVFloatArray&gt; PVFloatArrayPtr;
typedef PVValueArray&lt;double&gt; PVDoubleArray;
typedef std::tr1::shared_ptr&lt;PVDoubleArray&gt; PVDoubleArrayPtr;
typedef PVValueArray&lt;String&gt; PVStringArray;
typedef PVValueArray&lt;std::string&gt; PVStringArray;
typedef std::tr1::shared_ptr&lt;PVStringArray&gt; PVStringArrayPtr;
</pre>
@@ -1231,7 +1231,7 @@ For others the brief summary is followed by tutorial information.
<pre>
typedef shared_vector&lt;int32&gt; Int32Array;
...
static void dumpArray(String const &amp;message,Int32Array const&amp; int32Array);
static void dumpArray(std::string const &amp;message,Int32Array const&amp; int32Array);
</pre>
<p>The following:
<pre>

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@ getFieldCreate()->createFieldBuilder()->
createStructure();
// create a structure (cntd.)
PVStructure::const_shared_pointer enum_t =
StructureConstPtr enum_t =
getFieldCreate()->createFieldBuilder()->
setId("enum_t")->
add("index", pvInt)->
@@ -26,7 +26,7 @@ PVStructure::const_shared_pointer enum_t =
createStructure();
// create a structure (cntd.)
PVStructure::const_shared_pointer ntEnum =
StructureConstPtr ntEnum =
getFieldCreate()->createFieldBuilder()->
setId("uri:ev4:nt/2012/pwd/NTEnum")->
add("value", enum_t)->

File diff suppressed because it is too large Load Diff

View File

@@ -88,7 +88,7 @@ The interfaces for C++ and Java should be similar so that
someone who understands the interface in one of the languages
and knows both languages will quickly understand the interface of the other language.</p>
<p>There is another problem with the existing API. There are methods that allow the "structure"
to change after an pvData object is created. An example is PVField::renameField(String newName).
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.
@@ -114,18 +114,18 @@ The new methods also have a comment.
<h3>Introspection Interfaces</h3>
<pre>interface Field extends Serializable {
String getId();
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">String toString();</font>
<font color = "red">std::string toString();</font>
}
<font color = "blue">
// new interface
interface FieldToString {
String toString(Field field);
interface FieldTostd::string {
std::string toString(Field field);
}</font>
interface Scalar extends Field {
@@ -137,12 +137,12 @@ interface ScalarArray extends Field {
}
interface Structure extends Field {
Field getField(String fieldName);
int getFieldIndex(String fieldName);
Field getField(std::string fieldName);
int getFieldIndex(std::string fieldName);
Field[] getFields();
Field getField(int fieldIndex);
String[] getFieldNames();
String getFieldName(int fieldIndex)
std::string[] getFieldNames();
std::string getFieldName(int fieldIndex)
}
interface StructureArray extends Field {
@@ -153,19 +153,19 @@ interface FieldCreate {
Scalar createScalar(ScalarType scalarType);
ScalarArray createScalarArray(ScalarType elementType);
StructureArray createStructureArray(Structure elementStructure);
Structure createStructure(String[] fieldNames, Field[] field);
Structure createStructure(String id,String[] fieldNames, Field[] field);
Structure createStructure(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,String fieldName, Field field);</font>
<font color = "red">Structure appendFields(Structure structure,String[] fieldNames, Field[] fields);</font>
<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 {
String getFieldName();
std::string getFieldName();
void setRequester(Requester requester);
int getFieldOffset();
int getNextFieldOffset();
@@ -178,16 +178,16 @@ interface PVField extends Requester, Serializable {
<font color = "red">PVAuxInfo getPVAuxInfo();</font>
<font color = "red">boolean isImmutable();</font>
<font color = "red">void setImmutable();</font>
<font color = "red">void renameField(String newName);</font>
<font color = "red">void 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">String toString();</font>
<font color = "red">std::string toString();</font>
}
<font color = "blue">
// The following is a new interface
interface PVFieldToString {
String toString(PVField pvField);
interface PVFieldTostd::string {
std::string toString(PVField pvField);
void setMaxInitialArrayElements(int num);
void setMaxFinalArrayElements(int num);
int getMaxInitialArrayElements();
@@ -241,28 +241,28 @@ interface PVDoubleArray extends PVArray {
interface PVStructure extends PVField , BitSetSerializable{
Structure getStructure();
PVField[] getPVFields();
PVField getSubField(String fieldName);
PVField getSubField(std::string fieldName);
PVField getSubField(int fieldOffset);
// The following are convenience methods
PVBoolean getBooleanField(String fieldName);
PVByte getByteField(String fieldName);
PVShort getShortField(String fieldName);
PVInt getIntField(String fieldName);
PVLong getLongField(String fieldName);
PVFloat getFloatField(String fieldName);
PVDouble getDoubleField(String fieldName);
PVString getStringField(String fieldName);
PVScalarArray getScalarArrayField(String fieldName);
PVStructureArray getStructureArrayField(String fieldName);
PVStructure getStructureField(String fieldName);
PVArray getArrayField(String fieldName,ScalarType elementType);
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(String fieldName,PVField pvField);</font>
<font color = "red"> void appendPVFields(String[] fieldNames,PVField[] pvFields);</font>
<font color = "red"> void removePVField(String fieldName);</font>
<font color = "red"> void 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"> String getExtendsStructureName();</font>
<font color = "red"> boolean putExtendsStructureName(String extendsStructureName);</font>
<font color = "red"> std::string getExtendsStructureName();</font>
<font color = "red"> boolean putExtendsStructureName(std::string extendsStructureName);</font>
<font color = "red"> public boolean checkValid();</font>
}
@@ -297,13 +297,13 @@ public interface PVDataCreate {
PVScalarArray createPVScalarArray(PVScalarArray arrayToClone;
PVStructureArray createPVStructureArray(StructureArray structureArray);
PVStructure createPVStructure(Structure structure);
PVStructure createPVStructure(String[] fieldNames,Field[] fields);
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>PVFieldToString</h3>
<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.
@@ -346,7 +346,7 @@ public:
POINTER_DEFINITIONS(Field);
virtual ~Field();
Type getType() const{return m_type;}
virtual String getID() const = 0;
virtual std::string getID() const = 0;
<font color = "red">
// following will be removed
virtual void toString(StringBuilder buf) const{toString(buf,0);}
@@ -373,7 +373,7 @@ public:
// following will be removed
virtual void toString(StringBuilder buf) const{toString(buf,0);}
virtual void toString(StringBuilder buf,int indentLevel) const;
virtual String getID() const;
virtual std::string getID() const;
</font>
...
};
@@ -391,7 +391,7 @@ public:
// following will be removed
virtual void toString(StringBuilder buf) const{toString(buf,0);}
virtual void toString(StringBuilder buf,int indentLevel) const;
virtual String getID() const;
virtual std::string getID() const;
</font>
...
};
@@ -403,19 +403,19 @@ public:
typedef const Structure&amp; const_reference;
std::size_t getNumberFields() const {return numberFields;}
FieldConstPtr getField(String const &amp; fieldName) const;
FieldConstPtr getField(std::string const &amp; fieldName) const;
FieldConstPtr getField(std::size_t index) const;
std::size_t getFieldIndex(String const &amp;fieldName) const;
std::size_t getFieldIndex(std::string const &amp;fieldName) const;
FieldConstPtrArray const &amp; getFields() const {return fields;}
StringArray const &amp; getFieldNames() const;
String getFieldName(std::size_t fieldIndex);
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,String const &amp;newName);
void renameField(std::size_t fieldIndex,std::string const &amp;newName);
virtual void toString(StringBuilder buf,int indentLevel) const;
virtual String getID() const;
virtual std::string getID() const;
</font>
...
};
@@ -432,7 +432,7 @@ public:
<font color = "red">
// following will be removed
virtual void toString(StringBuilder buf,int indentLevel=0) const;
virtual String getID() const;
virtual std::string getID() const;
</font>
...
};
@@ -447,7 +447,7 @@ public:
StringArray const &amp; fieldNames,
FieldConstPtrArray const &amp; fields) const;
StructureConstPtr createStructure (
String const &amp;id,
std::string const &amp;id,
StringArray const &amp; fieldNames,
FieldConstPtrArray const &amp; fields) const;
FieldConstPtr deserialize(ByteBuffer* buffer, DeserializableControl* control) const;
@@ -455,7 +455,7 @@ public:
// following will be removed
StructureConstPtr appendField(
StructureConstPtr const &amp; structure,
String const &amp;fieldName, FieldConstPtr const &amp; field) const;
std::string const &amp;fieldName, FieldConstPtr const &amp; field) const;
StructureConstPtr appendFields(
StructureConstPtr const &amp; structure,
StringArray const &amp; fieldNames,
@@ -475,7 +475,7 @@ class PVField
public:
POINTER_DEFINITIONS(PVField);
virtual ~PVField();
inline const String &amp;getFieldName() const ;
inline const std::string &amp;getFieldName() const ;
virtual void setRequester(RequesterPtr const &amp;prequester);
std::size_t getFieldOffset() const;
std::size_t getNextFieldOffset() const;
@@ -486,15 +486,15 @@ public:
void setPostHandler(PostHandlerPtr const &amp;postHandler);
// following will be removed
<font color = "red">
virtual void message(String message,MessageType messageType);
virtual void message(std::string message,MessageType messageType);
void replacePVField(const PVFieldPtr&amp; newPVField);
String getFullName() const;
std::string getFullName() const;
virtual bool equals(PVField &amp;pv);
PVAuxInfoPtr &amp; getPVAuxInfo()
bool isImmutable() const;
virtual void setImmutable();
void replacePVField(const PVFieldPtr&amp; newPVField);
void renameField(String const &amp;newName);
void renameField(std::string const &amp;newName);
virtual void toString(StringBuilder buf) ;
virtual void toString(StringBuilder buf,int indentLevel);
std::ostream&amp; dumpValue(std::ostream&amp; o) const;
@@ -504,8 +504,8 @@ public:
<font color = "blue">
// The following is a new class
class PVFieldToString {
String toString(const PVFieldPtr &amp;pvField);
class PVFieldTostd::string {
std::string toString(const PVFieldPtr &amp;pvField);
void setMaxInitialArrayElements(size_t num);
void setMaxFinalArrayElements(size_t num);
size_t getMaxInitialArrayElements();
@@ -546,7 +546,7 @@ public:
}
// PVString is special case, since it implements SerializableArray
class PVString : public PVScalarValue&lt;String&gt;, SerializableArray {
class PVString : public PVScalarValue&lt;std::string&gt;, SerializableArray {
public:
virtual ~PVString() {}
...
@@ -650,7 +650,7 @@ public:
typedef PVValueArray&lt;uint8&gt; PVBooleanArray;
typedef std::tr1::shared_ptr&lt;PVBooleanArray&gt; PVBooleanArrayPtr;
...
typedef PVValueArray&lt;String&gt; PVStringArray;
typedef PVValueArray&lt;std::string&gt; PVStringArray;
typedef std::tr1::shared_ptr&lt;PVStringArray&gt; PVStringArrayPtr;
class PVStructure : public PVField,public BitSetSerializable {
@@ -662,24 +662,24 @@ public:
StructureConstPtr getStructure() const;
const PVFieldPtrArray &amp; getPVFields() const;
PVFieldPtr getSubField(String const &amp;fieldName) const;
PVFieldPtr getSubField(std::string const &amp;fieldName) const;
PVFieldPtr getSubField(std::size_t fieldOffset) const;
PVBooleanPtr getBooleanField(String const &amp;fieldName) ;
PVBytePtr getByteField(String const &amp;fieldName) ;
PVShortPtr getShortField(String const &amp;fieldName) ;
PVIntPtr getIntField(String const &amp;fieldName) ;
PVLongPtr getLongField(String const &amp;fieldName) ;
PVUBytePtr getUByteField(String const &amp;fieldName) ;
PVUShortPtr getUShortField(String const &amp;fieldName) ;
PVUIntPtr getUIntField(String const &amp;fieldName) ;
PVULongPtr getULongField(String const &amp;fieldName) ;
PVFloatPtr getFloatField(String const &amp;fieldName) ;
PVDoublePtr getDoubleField(String const &amp;fieldName) ;
PVStringPtr getStringField(String const &amp;fieldName) ;
PVStructurePtr getStructureField(String const &amp;fieldName) ;
PVBooleanPtr getBooleanField(std::string const &amp;fieldName) ;
PVBytePtr getByteField(std::string const &amp;fieldName) ;
PVShortPtr getShortField(std::string const &amp;fieldName) ;
PVIntPtr getIntField(std::string const &amp;fieldName) ;
PVLongPtr getLongField(std::string const &amp;fieldName) ;
PVUBytePtr getUByteField(std::string const &amp;fieldName) ;
PVUShortPtr getUShortField(std::string const &amp;fieldName) ;
PVUIntPtr getUIntField(std::string const &amp;fieldName) ;
PVULongPtr getULongField(std::string const &amp;fieldName) ;
PVFloatPtr getFloatField(std::string const &amp;fieldName) ;
PVDoublePtr getDoubleField(std::string const &amp;fieldName) ;
PVStringPtr getStringField(std::string const &amp;fieldName) ;
PVStructurePtr getStructureField(std::string const &amp;fieldName) ;
PVScalarArrayPtr getScalarArrayField(
String const &amp;fieldName,ScalarType elementType) ;
PVStructureArrayPtr getStructureArrayField(String const &amp;fieldName) ;
std::string const &amp;fieldName,ScalarType elementType) ;
PVStructureArrayPtr getStructureArrayField(std::string const &amp;fieldName) ;
virtual void serialize(
ByteBuffer *pbuffer,SerializableControl *pflusher) const ;
virtual void deserialize(
@@ -693,16 +693,16 @@ public:
<font color = "red">
// following are removed
void appendPVField(
String const &amp;fieldName,
std::string const &amp;fieldName,
PVFieldPtr const &amp; pvField);
void appendPVFields(
StringArray const &amp; fieldNames,
PVFieldPtrArray const &amp; pvFields);
void removePVField(String const &amp;fieldName);
void removePVField(std::string const &amp;fieldName);
virtual void setImmutable();
String getExtendsStructureName() const;
std::string getExtendsStructureName() const;
bool putExtendsStructureName(
String const &amp;extendsStructureName);
std::string const &amp;extendsStructureName);
</font>
};

View File

@@ -12,6 +12,7 @@ include $(PVDATA_SRC)/misc/Makefile
include $(PVDATA_SRC)/pv/Makefile
include $(PVDATA_SRC)/factory/Makefile
include $(PVDATA_SRC)/property/Makefile
include $(PVDATA_SRC)/copy/Makefile
include $(PVDATA_SRC)/pvMisc/Makefile
include $(PVDATA_SRC)/monitor/Makefile

9
src/copy/Makefile Normal file
View File

@@ -0,0 +1,9 @@
# This is a Makefile fragment, see ../Makefile
SRC_DIRS += $(PVDATA_SRC)/copy
INC += createRequest.h
INC += pvCopy.h
LIBSRCS += createRequest.cpp
LIBSRCS += pvCopy.cpp

533
src/copy/createRequest.cpp Normal file
View File

@@ -0,0 +1,533 @@
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* pvAccessCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <string>
#include <sstream>
#define epicsExportSharedSymbols
#include <pv/pvData.h>
#include <pv/lock.h>
#include <pv/createRequest.h>
using namespace epics::pvData;
using std::tr1::static_pointer_cast;
using std::cout;
using std::endl;
using std::string;
namespace epics { namespace pvData {
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
static FieldCreatePtr fieldCreate = getFieldCreate();
class CreateRequestImpl : public CreateRequest {
private:
void removeBlanks(string& str)
{
while(true) {
string::size_type pos = str.find_first_of(' ');
if(pos==string::npos) return;
str.erase(pos,1);
}
}
size_t findMatchingBrace(string& request, size_t index, int numOpen) {
size_t openBrace = request.find('{', index+1);
size_t closeBrace = request.find('}', index+1);
if(openBrace == string::npos && closeBrace == string::npos){
message = request + " missing }";
return string::npos;
}
if (openBrace != string::npos && openBrace!=0) {
if(openBrace<closeBrace) return findMatchingBrace(request,openBrace,numOpen+1);
if(numOpen==1) return closeBrace;
return findMatchingBrace(request,closeBrace,numOpen-1);
}
if(numOpen==1) return closeBrace;
return findMatchingBrace(request,closeBrace,numOpen-1);
}
size_t findMatchingBracket(string& request, size_t index) {
for(size_t i=index+1; i< request.size(); ++i) {
if(request[i] == ']') {
if(i==index+1) {
message = request + " illegal []";
return string::npos;
}
return i;
}
}
message = request + " missing ]";
return string::npos;
}
size_t findEndField(string& request) {
size_t ind = 0;
size_t maxind = request.size() -1;
while(true) {
if(request[ind]==',') return ind;
if(request[ind]=='[') {
size_t closeBracket = findMatchingBracket(request,ind);
if(closeBracket==string::npos) return closeBracket;
ind = closeBracket;
continue;
}
if(request[ind]=='{') {
size_t closeBrace = findMatchingBrace(request,ind,1);
if(closeBrace==string::npos) return closeBrace;
if(ind>=request.size()) return request.size();
ind = closeBrace;
continue;
}
if(ind>=maxind) break;
++ind;
}
return request.size();
}
std::vector<string> split(string const & commaSeparatedList) {
string::size_type numValues = 1;
string::size_type index=0;
while(true) {
string::size_type pos = commaSeparatedList.find(',',index);
if(pos==string::npos) break;
numValues++;
index = pos +1;
}
std::vector<string> valueList(numValues,"");
index=0;
for(size_t i=0; i<numValues; i++) {
size_t pos = commaSeparatedList.find(',',index);
string value = commaSeparatedList.substr(index,pos-index);
valueList[i] = value;
index = pos +1;
}
return valueList;
}
StructureConstPtr createRequestOptions(
string request)
{
if(request.length()<=1) return StructureConstPtr();
std::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;
}
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);
string value = item.substr(equals+1);
PVStringPtr pvValue = pvParent->getSubField<PVString>(name);
pvValue->put(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();
}
StructureConstPtr createFieldRequest(
StructureConstPtr parent,
string request)
{
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]);
}
}
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;
}
// 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));
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);
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));
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);
}
}
void initFieldOptions(
PVStructurePtr const & pvParent,
string request)
{
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;
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;
}
}
public:
virtual PVStructure::shared_pointer 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)
{
return PVStructurePtr();
}
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)
{
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 )";
return PVStructurePtr();
}
StructureConstPtr structure = fieldCreate->createStructure();
structure = createFieldRequest(structure,request.substr(openBrace+1,closeBrace-openBrace-1));
if(structure==NULL)
{
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 )";
return PVStructurePtr();
}
StructureConstPtr structure = fieldCreate->createStructure();
structure = createFieldRequest(structure,request.substr(openBrace+1,closeBrace-openBrace-1));
if(structure==NULL)
{
return PVStructurePtr();
}
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]);
}
if(pvSub!=NULL) initFieldOptions(pvSub,request.substr(openParam+1,closeParam-openParam-1));
}
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()
{
CreateRequest::shared_pointer createRequest(new CreateRequestImpl());
return createRequest;
}
}}

56
src/copy/createRequest.h Normal file
View File

@@ -0,0 +1,56 @@
/*createRequest.h*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef CREATEREQUEST_H
#define CREATEREQUEST_H
#include <string>
#include <sstream>
#include <pv/pvData.h>
#include <pv/lock.h>
#include <shareLib.h>
namespace epics { namespace pvData {
/**
* Class to create pvRequest structures to pass to pvAccess Channel methods.
*/
class epicsShareClass CreateRequest {
public:
POINTER_DEFINITIONS(CreateRequest);
/**
* Create s new instance of CreateRequest
* @returns A shared pointer to the new instance.
*/
static CreateRequest::shared_pointer create();
virtual ~CreateRequest() {};
/**
* Create a request structure for the create calls in Channel.
* See the package overview documentation for details.
* @param request The field request. See the package overview documentation for details.
* @param requester The requester;
* @return The request PVStructure if a valid request was given.
* If a NULL PVStructure is returned then getMessage will return
* the reason.
*/
virtual PVStructure::shared_pointer createRequest(std::string const & request) = 0;
/**
* Get the error message of createRequest returns NULL
* return the error message
*/
std::string getMessage() {return message;}
protected:
CreateRequest() {}
std::string message;
};
}}
#endif /* CREATEREQUEST_H */

650
src/copy/pvCopy.cpp Normal file
View File

@@ -0,0 +1,650 @@
/* pvCopy.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author Marty Kraimer
* @date 2013.04
*/
#include <string>
#include <stdexcept>
#include <memory>
#include <sstream>
#define epicsExportSharedSymbols
#include <pv/thread.h>
#include <pv/pvCopy.h>
#include <pv/convert.h>
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using std::string;
using std::size_t;
using std::cout;
using std::endl;
namespace epics { namespace pvData {
static PVCopyPtr NULLPVCopy;
static FieldConstPtr NULLField;
static StructureConstPtr NULLStructure;
static PVStructurePtr NULLPVStructure;
static CopyNodePtr NULLCopyNode;
static CopyMasterNodePtr NULLCopyMasterNode;
struct CopyNode {
CopyNode()
: isStructure(false),
structureOffset(0),
nfields(0)
{}
bool isStructure;
size_t structureOffset; // In the copy
size_t nfields;
PVStructurePtr options;
};
struct CopyMasterNode : public CopyNode{
PVFieldPtr masterPVField;
};
typedef std::vector<CopyNodePtr> CopyNodePtrArray;
typedef std::tr1::shared_ptr<CopyNodePtrArray> CopyNodePtrArrayPtr;
struct CopyStructureNode : public CopyNode {
CopyNodePtrArrayPtr nodes;
};
PVCopyPtr PVCopy::create(
PVStructurePtr const &pvMaster,
PVStructurePtr const &pvRequest,
string const & structureName)
{
PVStructurePtr pvStructure(pvRequest);
if(structureName.size()>0) {
if(pvRequest->getStructure()->getNumberFields()>0) {
pvStructure = pvRequest->getStructureField(structureName);
if(pvStructure.get()==NULL) return NULLPVCopy;
}
} else if(pvStructure->getSubField("field")!=NULL) {
pvStructure = pvRequest->getStructureField("field");
}
PVCopyPtr pvCopy = PVCopyPtr(new PVCopy(pvMaster));
bool result = pvCopy->init(pvStructure);
if(!result) pvCopy.reset();
return pvCopy;
}
PVCopy::PVCopy(
PVStructurePtr const &pvMaster)
: pvMaster(pvMaster)
{
}
void PVCopy::destroy()
{
headNode.reset();
}
PVStructurePtr PVCopy::getPVMaster()
{
return pvMaster;
}
void PVCopy::traverseMaster(CopyNodePtr const &innode, PVCopyTraverseMasterCallbackPtr const & callback)
{
CopyNodePtr node = innode;
if(!node->isStructure) {
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(node);
callback->nextMasterPVField(masterNode->masterPVField);
return;
}
CopyStructureNodePtr structNode = static_pointer_cast<CopyStructureNode>(node);
CopyNodePtrArrayPtr nodes = structNode->nodes;
for(size_t i=0; i< nodes->size(); i++) {
node = (*nodes)[i];
traverseMaster(node,callback);
}
}
StructureConstPtr PVCopy::getStructure()
{
return structure;
}
PVStructurePtr PVCopy::createPVStructure()
{
if(cacheInitStructure.get()!=NULL) {
PVStructurePtr save = cacheInitStructure;
cacheInitStructure.reset();
return save;
}
PVStructurePtr pvStructure =
getPVDataCreate()->createPVStructure(structure);
return pvStructure;
}
PVStructurePtr PVCopy::getOptions(std::size_t fieldOffset)
{
if(fieldOffset==0) return headNode->options;
CopyNodePtr node = headNode;
while(true) {
if(!node->isStructure) {
if(node->structureOffset==fieldOffset) return node->options;
return NULLPVStructure;
}
CopyStructureNodePtr structNode = static_pointer_cast<CopyStructureNode>(node);
CopyNodePtrArrayPtr nodes = structNode->nodes;
boolean okToContinue = false;
for(size_t i=0; i< nodes->size(); i++) {
node = (*nodes)[i];
size_t soff = node->structureOffset;
if(fieldOffset>=soff && fieldOffset<soff+node->nfields) {
if(fieldOffset==soff) return node->options;
if(!node->isStructure) {
return NULLPVStructure;
}
okToContinue = true;
break;
}
}
if(okToContinue) continue;
throw std::invalid_argument("fieldOffset not valid");
}
}
size_t PVCopy::getCopyOffset(PVFieldPtr const &masterPVField)
{
if(masterPVField->getFieldOffset()==0) return 0;
if(!headNode->isStructure) {
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(headNode);
if((masterNode->masterPVField.get())==masterPVField.get()) {
return headNode->structureOffset;
}
PVStructure * parent = masterPVField->getParent();
size_t offsetParent = parent->getFieldOffset();
size_t off = masterPVField->getFieldOffset();
size_t offdiff = off -offsetParent;
if(offdiff<masterNode->nfields) return headNode->structureOffset + offdiff;
return string::npos;
}
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
CopyMasterNodePtr masterNode = getCopyOffset(node,masterPVField);
if(masterNode.get()!=NULL) return masterNode->structureOffset;
return string::npos;
}
size_t PVCopy::getCopyOffset(
PVStructurePtr const &masterPVStructure,
PVFieldPtr const &masterPVField)
{
CopyMasterNodePtr masterNode;
if(!headNode->isStructure) {
masterNode = static_pointer_cast<CopyMasterNode>(headNode);
if(masterNode->masterPVField.get()!=masterPVStructure.get()) return string::npos;
} else {
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
masterNode = getCopyOffset(node,masterPVField);
}
if(masterNode.get()==NULL) return string::npos;
size_t diff = masterPVField->getFieldOffset()
- masterPVStructure->getFieldOffset();
return masterNode->structureOffset + diff;
}
PVFieldPtr PVCopy::getMasterPVField(size_t structureOffset)
{
CopyMasterNodePtr masterNode;
if(!headNode->isStructure) {
masterNode = static_pointer_cast<CopyMasterNode>(headNode);
} else {
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
masterNode = getMasterNode(node,structureOffset);
}
if(masterNode.get()==NULL) {
throw std::invalid_argument(
"PVCopy::getMasterPVField: setstructureOffset not valid");
}
size_t diff = structureOffset - masterNode->structureOffset;
PVFieldPtr pvMasterField = masterNode->masterPVField;
if(diff==0) return pvMasterField;
PVStructurePtr pvStructure
= static_pointer_cast<PVStructure>(pvMasterField);
return pvStructure->getSubField(
pvMasterField->getFieldOffset() + diff);
}
void PVCopy::initCopy(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet)
{
bitSet->clear();
bitSet->set(0);
updateCopyFromBitSet(copyPVStructure,bitSet);
}
void PVCopy::updateCopySetBitSet(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet)
{
if(headNode->isStructure) {
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
updateStructureNodeSetBitSet(copyPVStructure,node,bitSet);
} else {
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(headNode);
PVFieldPtr pvMasterField= masterNode->masterPVField;
PVFieldPtr copyPVField = copyPVStructure;
PVFieldPtr pvField = pvMasterField;
if(pvField->getField()->getType()==epics::pvData::structure) {
updateSubFieldSetBitSet(copyPVField,pvMasterField,bitSet);
return;
}
ConvertPtr convert = getConvert();
bool isEqual = convert->equals(copyPVField,pvField);
if(!isEqual) {
convert->copy(pvField, copyPVField);
bitSet->set(copyPVField->getFieldOffset());
}
}
}
void PVCopy::updateCopyFromBitSet(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet)
{
bool doAll = bitSet->get(0);
if(headNode->isStructure) {
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
updateStructureNodeFromBitSet(copyPVStructure,node,bitSet,true,doAll);
} else {
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(headNode);
updateSubFieldFromBitSet(copyPVStructure, masterNode->masterPVField,bitSet, true,doAll);
}
}
void PVCopy::updateMaster(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet)
{
bool doAll = bitSet->get(0);
if(headNode->isStructure) {
CopyStructureNodePtr node =
static_pointer_cast<CopyStructureNode>(headNode);
updateStructureNodeFromBitSet(
copyPVStructure,node,bitSet,false,doAll);
} else {
CopyMasterNodePtr masterNode =
static_pointer_cast<CopyMasterNode>(headNode);
updateSubFieldFromBitSet( copyPVStructure,masterNode->masterPVField,bitSet,false,doAll);
}
}
string PVCopy::dump()
{
string builder;
dump(&builder,headNode,0);
return builder;
}
void PVCopy::dump(string *builder,CopyNodePtr const &node,int indentLevel)
{
getConvert()->newLine(builder,indentLevel);
std::stringstream ss;
ss << (node->isStructure ? "structureNode" : "masterNode");
ss << " structureOffset " << node->structureOffset;
ss << " nfields " << node->nfields;
*builder += ss.str();
PVStructurePtr options = node->options;
if(options.get()!=NULL) {
getConvert()->newLine(builder,indentLevel +1);
// TODO !!! ugly
std::ostringstream oss;
oss << *options;
*builder += oss.str();
getConvert()->newLine(builder,indentLevel);
}
if(!node->isStructure) {
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(node);
string name = masterNode->masterPVField->getFullName();
*builder += " masterField " + name;
return;
}
CopyStructureNodePtr structureNode =
static_pointer_cast<CopyStructureNode>(node);
CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i<nodes->size(); ++i) {
if((*nodes)[i].get()==NULL) {
getConvert()->newLine(builder,indentLevel +1);
ss.str("");
ss << "node[" << i << "] is null";
*builder += ss.str();
continue;
}
dump(builder,(*nodes)[i],indentLevel+1);
}
}
bool PVCopy::init(epics::pvData::PVStructurePtr const &pvRequest)
{
PVStructurePtr pvMasterStructure = pvMaster;
size_t len = pvRequest->getPVFields().size();
bool entireMaster = false;
if(len==string::npos) entireMaster = true;
if(len==0) entireMaster = true;
PVStructurePtr pvOptions;
if(len==1 && pvRequest->getSubField("_options")!=NULL) {
pvOptions = pvRequest->getStructureField("_options");
}
if(entireMaster) {
structure = pvMasterStructure->getStructure();
CopyMasterNodePtr masterNode(new CopyMasterNode());
headNode = masterNode;
masterNode->options = pvOptions;
masterNode->isStructure = false;
masterNode->structureOffset = 0;
masterNode->masterPVField = pvMasterStructure;
masterNode->nfields = pvMasterStructure->getNumberFields();
return true;
}
structure = createStructure(pvMasterStructure,pvRequest);
if(structure==NULL) return false;
cacheInitStructure = createPVStructure();
headNode = createStructureNodes(
pvMaster,
pvRequest,
cacheInitStructure);
return true;
}
string PVCopy::dump(
string const &value,
CopyNodePtr const &node,
int indentLevel)
{
throw std::logic_error(string("Not Implemented"));
}
StructureConstPtr PVCopy::createStructure(
PVStructurePtr const &pvMaster,
PVStructurePtr const &pvFromRequest)
{
if(pvFromRequest->getStructure()->getNumberFields()==0) {
return pvMaster->getStructure();
}
PVFieldPtrArray const &pvFromRequestFields = pvFromRequest->getPVFields();
StringArray const &fromRequestFieldNames = pvFromRequest->getStructure()->getFieldNames();
size_t length = pvFromRequestFields.size();
if(length==0) return NULLStructure;
FieldConstPtrArray fields; fields.reserve(length);
StringArray fieldNames; fields.reserve(length);
for(size_t i=0; i<length; ++i) {
string const &fieldName = fromRequestFieldNames[i];
PVFieldPtr pvMasterField = pvMaster->getSubField(fieldName);
if(pvMasterField==NULL) continue;
FieldConstPtr field = pvMasterField->getField();
if(field->getType()==epics::pvData::structure) {
PVStructurePtr pvRequestStructure = static_pointer_cast<PVStructure>(
pvFromRequestFields[i]);
if(pvRequestStructure->getNumberFields()>0) {
StringArray const &names = pvRequestStructure->getStructure()->
getFieldNames();
size_t num = names.size();
if(num>0 && names[0].compare("_options")==0) --num;
if(num>0) {
if(pvMasterField->getField()->getType()!=epics::pvData::structure) continue;
fieldNames.push_back(fieldName);
fields.push_back(createStructure(
static_pointer_cast<PVStructure>(pvMasterField),
pvRequestStructure));
continue;
}
}
}
fieldNames.push_back(fieldName);
fields.push_back(field);
}
size_t numsubfields = fields.size();
if(numsubfields==0) return NULLStructure;
return getFieldCreate()->createStructure(fieldNames, fields);
}
CopyNodePtr PVCopy::createStructureNodes(
PVStructurePtr const &pvMasterStructure,
PVStructurePtr const &pvFromRequest,
PVStructurePtr const &pvFromCopy)
{
PVFieldPtrArray const & copyPVFields = pvFromCopy->getPVFields();
PVStructurePtr pvOptions;
PVFieldPtr pvField = pvFromRequest->getSubField("_options");
if(pvField!=NULL) pvOptions = static_pointer_cast<PVStructure>(pvField);
size_t number = copyPVFields.size();
CopyNodePtrArrayPtr nodes(new CopyNodePtrArray());
nodes->reserve(number);
for(size_t i=0; i<number; i++) {
PVFieldPtr copyPVField = copyPVFields[i];
string fieldName = copyPVField->getFieldName();
PVStructurePtr requestPVStructure = static_pointer_cast<PVStructure>(
pvFromRequest->getSubField(fieldName));
PVStructurePtr pvSubFieldOptions;
PVFieldPtr pvField = requestPVStructure->getSubField("_options");
if(pvField!=NULL) pvSubFieldOptions = static_pointer_cast<PVStructure>(pvField);
PVFieldPtr pvMasterField;
PVFieldPtrArray const & pvMasterFields = pvMasterStructure->getPVFields();
for(size_t j=0; i<pvMasterFields.size(); j++ ) {
if(pvMasterFields[j]->getFieldName().compare(fieldName)==0) {
pvMasterField = pvMasterFields[j];
break;
}
}
size_t numberRequest = requestPVStructure->getPVFields().size();
if(pvSubFieldOptions!=NULL) numberRequest--;
if(numberRequest>0) {
nodes->push_back(createStructureNodes(
static_pointer_cast<PVStructure>(pvMasterField),
requestPVStructure,
static_pointer_cast<PVStructure>(copyPVField)));
continue;
}
CopyMasterNodePtr masterNode(new CopyMasterNode());
masterNode->options = pvSubFieldOptions;
masterNode->isStructure = false;
masterNode->masterPVField = pvMasterField;
masterNode->nfields = copyPVField->getNumberFields();
masterNode->structureOffset = copyPVField->getFieldOffset();
nodes->push_back(masterNode);
}
CopyStructureNodePtr structureNode(new CopyStructureNode());
structureNode->isStructure = true;
structureNode->nodes = nodes;
structureNode->structureOffset = pvFromCopy->getFieldOffset();
structureNode->nfields = pvFromCopy->getNumberFields();
structureNode->options = pvOptions;
return structureNode;
}
void PVCopy::updateStructureNodeSetBitSet(
PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,
epics::pvData::BitSetPtr const &bitSet)
{
for(size_t i=0; i<structureNode->nodes->size(); i++) {
CopyNodePtr node = (*structureNode->nodes)[i];
PVFieldPtr pvField = pvCopy->getSubField(node->structureOffset);
if(node->isStructure) {
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
CopyStructureNodePtr yyy =
static_pointer_cast<CopyStructureNode>(node);
updateStructureNodeSetBitSet(xxx,yyy,bitSet);
} else {
CopyMasterNodePtr masterNode =
static_pointer_cast<CopyMasterNode>(node);
updateSubFieldSetBitSet(pvField,masterNode->masterPVField,bitSet);
}
}
}
void PVCopy::updateSubFieldSetBitSet(
PVFieldPtr const &pvCopy,
PVFieldPtr const &pvMaster,
BitSetPtr const &bitSet)
{
FieldConstPtr field = pvCopy->getField();
Type type = field->getType();
if(type!=epics::pvData::structure) {
ConvertPtr convert = getConvert();
bool isEqual = convert->equals(pvCopy,pvMaster);
if(isEqual) {
if(type==structureArray) {
// always act as though a change occurred.
// Note that array elements are shared.
bitSet->set(pvCopy->getFieldOffset());
}
}
if(isEqual) return;
convert->copy(pvMaster, pvCopy);
bitSet->set(pvCopy->getFieldOffset());
return;
}
PVStructurePtr pvCopyStructure = static_pointer_cast<PVStructure>(pvCopy);
PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields();
PVStructurePtr pvMasterStructure =
static_pointer_cast<PVStructure>(pvMaster);
PVFieldPtrArray const & pvMasterFields =
pvMasterStructure->getPVFields();
size_t length = pvCopyFields.size();
for(size_t i=0; i<length; i++) {
updateSubFieldSetBitSet(pvCopyFields[i],pvMasterFields[i],bitSet);
}
}
void PVCopy::updateStructureNodeFromBitSet(
PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,
BitSetPtr const &bitSet,
bool toCopy,
bool doAll)
{
size_t offset = structureNode->structureOffset;
if(!doAll) {
size_t nextSet = bitSet->nextSetBit(offset);
if(nextSet==string::npos) return;
}
if(offset>=pvCopy->getNextFieldOffset()) return;
if(!doAll) doAll = bitSet->get(offset);
CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i<nodes->size(); i++) {
CopyNodePtr node = (*nodes)[i];
PVFieldPtr pvField = pvCopy->getSubField(node->structureOffset);
if(node->isStructure) {
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
CopyStructureNodePtr subStructureNode =
static_pointer_cast<CopyStructureNode>(node);
updateStructureNodeFromBitSet(
xxx,subStructureNode,bitSet,toCopy,doAll);
} else {
CopyMasterNodePtr masterNode =
static_pointer_cast<CopyMasterNode>(node);
updateSubFieldFromBitSet(
pvField,masterNode->masterPVField,bitSet,toCopy,doAll);
}
}
}
void PVCopy::updateSubFieldFromBitSet(
PVFieldPtr const &pvCopy,
PVFieldPtr const &pvMasterField,
BitSetPtr const &bitSet,
bool toCopy,
bool doAll)
{
if(!doAll) {
doAll = bitSet->get(pvCopy->getFieldOffset());
}
if(!doAll) {
size_t offset = pvCopy->getFieldOffset();
size_t nextSet = bitSet->nextSetBit(offset);
if(nextSet==string::npos) return;
if(nextSet>=pvCopy->getNextFieldOffset()) return;
}
ConvertPtr convert = getConvert();
if(pvCopy->getField()->getType()==epics::pvData::structure) {
PVStructurePtr pvCopyStructure =
static_pointer_cast<PVStructure>(pvCopy);
PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields();
if(pvMasterField->getField()->getType() !=epics::pvData::structure)
{
throw std::logic_error(string("Logic error"));
}
PVStructurePtr pvMasterStructure =
static_pointer_cast<PVStructure>(pvMasterField);
PVFieldPtrArray const & pvMasterFields =
pvMasterStructure->getPVFields();
for(size_t i=0; i<pvCopyFields.size(); i++) {
updateSubFieldFromBitSet(
pvCopyFields[i],
pvMasterFields[i],
bitSet,toCopy,doAll);
}
} else {
if(toCopy) {
convert->copy(pvMasterField, pvCopy);
} else {
convert->copy(pvCopy, pvMasterField);
}
}
}
CopyMasterNodePtr PVCopy::getCopyOffset(
CopyStructureNodePtr const &structureNode,
PVFieldPtr const &masterPVField)
{
size_t offset = masterPVField->getFieldOffset();
CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i< nodes->size(); i++) {
CopyNodePtr node = (*nodes)[i];
if(!node->isStructure) {
CopyMasterNodePtr masterNode =
static_pointer_cast<CopyMasterNode>(node);
size_t off = masterNode->masterPVField->getFieldOffset();
size_t nextOffset = masterNode->masterPVField->getNextFieldOffset();
if(offset>= off && offset<nextOffset) return masterNode;
} else {
CopyStructureNodePtr subNode =
static_pointer_cast<CopyStructureNode>(node);
CopyMasterNodePtr masterNode =
getCopyOffset(subNode,masterPVField);
if(masterNode.get()!=NULL) return masterNode;
}
}
return NULLCopyMasterNode;
}
CopyMasterNodePtr PVCopy::getMasterNode(
CopyStructureNodePtr const &structureNode,
std::size_t structureOffset)
{
CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i< nodes->size(); i++) {
CopyNodePtr node = (*nodes)[i];
if(structureOffset>=(node->structureOffset + node->nfields)) continue;
if(!node->isStructure) {
CopyMasterNodePtr masterNode =
static_pointer_cast<CopyMasterNode>(node);
return masterNode;
}
CopyStructureNodePtr subNode =
static_pointer_cast<CopyStructureNode>(node);
return getMasterNode(subNode,structureOffset);
}
return NULLCopyMasterNode;
}
}}

230
src/copy/pvCopy.h Normal file
View File

@@ -0,0 +1,230 @@
/* pvCopy.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author Marty Kraimer
* @date 2013.04
*/
#ifndef PVCOPY_H
#define PVCOPY_H
#include <string>
#include <stdexcept>
#include <memory>
#include <shareLib.h>
#include <pv/pvData.h>
#include <pv/bitSet.h>
namespace epics { namespace pvData{
class PVCopyTraverseMasterCallback;
typedef std::tr1::shared_ptr<PVCopyTraverseMasterCallback> PVCopyTraverseMasterCallbackPtr;
/**
* Callback for traversing master structure
* Must be implemented by code that creates pvCopy.
*/
class epicsShareClass PVCopyTraverseMasterCallback
{
public:
POINTER_DEFINITIONS(PVCopyTraverseMasterCallback);
virtual ~PVCopyTraverseMasterCallback() {}
/**
* Called once for each field in master.
* @param pvField The field in master.
*/
virtual void nextMasterPVField(epics::pvData::PVFieldPtr const &pvField) = 0;
};
class PVCopy;
typedef std::tr1::shared_ptr<PVCopy> PVCopyPtr;
struct CopyNode;
typedef std::tr1::shared_ptr<CopyNode> CopyNodePtr;
struct CopyMasterNode;
typedef std::tr1::shared_ptr<CopyMasterNode> CopyMasterNodePtr;
struct CopyStructureNode;
typedef std::tr1::shared_ptr<CopyStructureNode> CopyStructureNodePtr;
/**
* Class that manages one or more PVStructures that holds an arbitrary subset of the fields
* in another PVStructure called master.
*/
class epicsShareClass PVCopy :
public std::tr1::enable_shared_from_this<PVCopy>
{
public:
POINTER_DEFINITIONS(PVCopy);
/**
* Create a new pvCopy
* @param pvMaster The top level sructure for which a copy of
* an arbritary subset of the fields in master will be created and managed.
* @param pvRequest Selects the set of subfields desired and options for each field.
* @param structureName The name for the top level of any PVStructure created.
*/
static PVCopyPtr create(
PVStructurePtr const &pvMaster,
PVStructurePtr const &pvRequest,
std::string const & structureName);
virtual ~PVCopy(){}
virtual void destroy();
/**
* Get the top level structure of master
* @returns The master top level structure.
* This should not be modified.
*/
PVStructurePtr getPVMaster();
/**
* Traverse all the fields in master.
* @param callback This is called for each field on master.
*/
void traverseMaster(PVCopyTraverseMasterCallbackPtr const & callback)
{
traverseMaster(headNode,callback);
}
/**
* Get the introspection interface for a PVStructure for e copy.
*/
StructureConstPtr getStructure();
/**
* Create a copy instance. Monitors keep a queue of monitor elements.
* Since each element needs a PVStructure, multiple top level structures will be created.
*/
PVStructurePtr createPVStructure();
/**
* Given a field in pvMaster. return the offset in copy for the same field.
* A value of std::string::npos means that the copy does not have this field.
* @param masterPVField The field in master.
*/
std::size_t getCopyOffset(PVFieldPtr const &masterPVField);
/**
* Given a field in pvMaster. return the offset in copy for the same field.
* A value of std::string::npos means that the copy does not have this field.
* @param masterPVStructure A structure in master that has masterPVField.
* @param masterPVField The field in master.
*/
std::size_t getCopyOffset(
PVStructurePtr const &masterPVStructure,
PVFieldPtr const &masterPVField);
/**
* Given a offset in the copy get the corresponding field in pvMaster.
* @param offset The offset in the copy.
*/
PVFieldPtr getMasterPVField(std::size_t structureOffset);
/**
* Initialize the fields in copyPVStructure by giving each field
* the value from the corresponding field in pvMaster.
* bitSet will be set to show that all fields are changed.
* @param copyPVStructure A copy top level structure.
* @param bitSet A bitSet for copyPVStructure.
*/
void initCopy(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet);
/**
* Set all fields in copyPVStructure to the value of the corresponding field in pvMaster.
* Each field that is changed has it's corresponding bit set in bitSet.
* @param copyPVStructure A copy top level structure.
* @param bitSet A bitSet for copyPVStructure.
*/
void updateCopySetBitSet(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet);
/**
* For each set bit in bitSet
* set the field in copyPVStructure to the value of the corrseponding field in pvMaster.
* @param copyPVStructure A copy top level structure.
* @param bitSet A bitSet for copyPVStructure.
*/
void updateCopyFromBitSet(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet);
/**
* For each set bit in bitSet
* set the field in pvMaster to the value of the corrseponding field in copyPVStructure
* @param copyPVStructure A copy top level structure.
* @param bitSet A bitSet for copyPVStructure.
*/
void updateMaster(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet);
/**
* Get the options for the field at the specified offset.
* @param offset the offset in copy.
* @returns A NULL is returned if no options were specified for the field.
* If options were specified,PVStructurePtr is a structures
* with a set of PVString subfields that specify name,value pairs.s
* name is the subField name and value is the subField value.
*/
PVStructurePtr getOptions(std::size_t fieldOffset);
/**
* For debugging.
*/
std::string dump();
private:
void dump(
std::string *builder,
CopyNodePtr const &node,
int indentLevel);
PVCopyPtr getPtrSelf()
{
return shared_from_this();
}
void traverseMaster(CopyNodePtr const &node, PVCopyTraverseMasterCallbackPtr const & callback);
PVStructurePtr pvMaster;
StructureConstPtr structure;
CopyNodePtr headNode;
PVStructurePtr cacheInitStructure;
PVCopy(PVStructurePtr const &pvMaster);
friend class PVCopyMonitor;
bool init(PVStructurePtr const &pvRequest);
std::string dump(
std::string const &value,
CopyNodePtr const &node,
int indentLevel);
StructureConstPtr createStructure(
PVStructurePtr const &pvMaster,
PVStructurePtr const &pvFromRequest);
CopyNodePtr createStructureNodes(
PVStructurePtr const &pvMasterStructure,
PVStructurePtr const &pvFromRequest,
PVStructurePtr const &pvFromField);
void updateStructureNodeSetBitSet(
PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,
BitSetPtr const &bitSet);
void updateSubFieldSetBitSet(
PVFieldPtr const &pvCopy,
PVFieldPtr const &pvMaster,
BitSetPtr const &bitSet);
void updateStructureNodeFromBitSet(
PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,
BitSetPtr const &bitSet,
bool toCopy,
bool doAll);
void updateSubFieldFromBitSet(
PVFieldPtr const &pvCopy,
PVFieldPtr const &pvMasterField,
BitSetPtr const &bitSet,
bool toCopy,
bool doAll);
CopyMasterNodePtr getCopyOffset(
CopyStructureNodePtr const &structureNode,
PVFieldPtr const &masterPVField);
CopyMasterNodePtr getMasterNode(
CopyStructureNodePtr const &structureNode,
std::size_t structureOffset);
};
}}
#endif /* PVCOPY_H */

View File

@@ -7,13 +7,15 @@
* @author mes
*/
#define epicsExportSharedSymbols
#include <pv/convert.h>
#include <algorithm>
#include <iterator>
#include <sstream>
#define epicsExportSharedSymbols
#include <pv/convert.h>
using std::string;
namespace epics { namespace pvData {
// Introspection object comparision
@@ -202,7 +204,7 @@ bool compareField(const PVScalarArray* left, const PVScalarArray* right)
OP(pvLong, int64);
OP(pvFloat, float);
OP(pvDouble, double);
OP(pvString, String);
OP(pvString, string);
#undef OP
}
throw std::logic_error("PVScalarArray with invalid element type!");

View File

@@ -22,37 +22,39 @@
using std::tr1::static_pointer_cast;
using std::size_t;
using std::string;
namespace epics { namespace pvData {
static std::vector<String> split(String commaSeparatedList) {
String::size_type numValues = 1;
String::size_type index=0;
static std::vector<string> split(string commaSeparatedList) {
string::size_type numValues = 1;
string::size_type index=0;
while(true) {
String::size_type pos = commaSeparatedList.find(',',index);
if(pos==String::npos) break;
string::size_type pos = commaSeparatedList.find(',',index);
if(pos==string::npos) break;
numValues++;
index = pos +1;
}
std::vector<String> valueList(numValues,"");
std::vector<string> valueList(numValues,"");
index=0;
for(size_t i=0; i<numValues; i++) {
size_t pos = commaSeparatedList.find(',',index);
String value = commaSeparatedList.substr(index,pos);
string value = commaSeparatedList.substr(index,pos);
valueList[i] = value;
index = pos +1;
}
return valueList;
}
void Convert::getString(StringBuilder buf,PVField const *pvField,int /*indentLevel*/)
void Convert::getString(string *buf,PVField const *pvField,int /*indentLevel*/)
{
// TODO indextLevel ignored
std::ostringstream strm;
PrinterPlain p;
p.setStream(strm);
p.print(*pvField);
strm << pvField->dumpValue(strm) << std::endl;
// PrinterPlain p;
// p.setStream(strm);
// p.print(*pvField);
strm.str().swap(*buf);
}
@@ -87,9 +89,9 @@ size_t Convert::fromString(PVStructurePtr const &pvStructure, StringArray const
}
else {
// union, structureArray, unionArray not supported
String message("Convert::fromString unsupported fieldType ");
TypeFunc::toString(&message,type);
throw std::logic_error(message);
std::ostringstream oss;
oss << "Convert::fromString unsupported fieldType " << type;
throw std::logic_error(oss.str());
}
}
}
@@ -97,13 +99,13 @@ size_t Convert::fromString(PVStructurePtr const &pvStructure, StringArray const
return processed;
}
size_t Convert::fromString(PVScalarArrayPtr const &pv, String from)
size_t Convert::fromString(PVScalarArrayPtr const &pv, string from)
{
if(from[0]=='[' && from[from.length()]==']') {
size_t offset = from.rfind(']');
from = from.substr(1, offset);
}
std::vector<String> valueList(split(from));
std::vector<string> valueList(split(from));
size_t length = valueList.size();
size_t num = fromStringArray(pv,0,length,valueList,0);
if(num<length) length = num;
@@ -128,7 +130,7 @@ size_t Convert::fromStringArray(PVScalarArrayPtr const &pv,
data.begin());
PVStringArray::const_svector temp(freeze(data));
pv->putFrom<String>(temp);
pv->putFrom<string>(temp);
return length;
} else {
@@ -142,7 +144,7 @@ size_t Convert::toStringArray(PVScalarArrayPtr const & pv,
StringArray &to, size_t toOffset)
{
PVStringArray::const_svector data;
pv->getAs<String>(data);
pv->getAs<string>(data);
data.slice(offset, length);
if(toOffset+data.size() > to.size())
to.resize(toOffset+data.size());
@@ -191,7 +193,7 @@ bool Convert::isCopyCompatible(FieldConstPtr const &from, FieldConstPtr const &t
return isCopyUnionArrayCompatible(xxx,yyy);
}
}
String message("Convert::isCopyCompatible should never get here");
string message("Convert::isCopyCompatible should never get here");
throw std::logic_error(message);
}
@@ -258,7 +260,7 @@ void Convert::copyScalar(PVScalarPtr const & from, PVScalarPtr const & to)
{
if(to->isImmutable()) {
if(from==to) return;
String message("Convert.copyScalar destination is immutable");
string message("Convert.copyScalar destination is immutable");
throw std::invalid_argument(message);
}
to->assign(*from.get());
@@ -348,13 +350,13 @@ void Convert::copyStructure(PVStructurePtr const & from, PVStructurePtr const &
PVFieldPtrArray const & toDatas = to->getPVFields();
if(from->getStructure()->getNumberFields()
!= to->getStructure()->getNumberFields()) {
String message("Convert.copyStructure Illegal copyStructure");
string message("Convert.copyStructure Illegal copyStructure");
throw std::invalid_argument(message);
}
size_t numberFields = from->getStructure()->getNumberFields();
if(numberFields>=2) {
String name0 = fromDatas[0]->getFieldName();
String name1 = fromDatas[1]->getFieldName();
string name0 = fromDatas[0]->getFieldName();
string name1 = fromDatas[1]->getFieldName();
// look for enumerated structure and copy choices first
if(name0.compare("index")==0 && name1.compare("choices")==0) {
FieldConstPtr fieldIndex = fromDatas[0]->getField();
@@ -382,7 +384,7 @@ void Convert::copyStructure(PVStructurePtr const & from, PVStructurePtr const &
Type fromType = fromData->getField()->getType();
Type toType = toData->getField()->getType();
if(fromType!=toType) {
String message("Convert.copyStructure Illegal copyStructure");
string message("Convert.copyStructure Illegal copyStructure");
throw std::invalid_argument(message);
}
if(toData->isImmutable()) {
@@ -470,7 +472,7 @@ void Convert::copyUnion(PVUnionPtr const & from, PVUnionPtr const & to)
if (fromValue.get() == 0)
to->select(PVUnion::UNDEFINED_INDEX);
else
copy(fromValue, to->select(from->getSelectedIndex()));
to->set(from->getSelectedFieldName(),from->get());
}
}
@@ -512,10 +514,10 @@ void Convert::copyUnionArray(
to->replace(from->view());
}
void Convert::newLine(StringBuilder buffer, int indentLevel)
void Convert::newLine(string *buffer, int indentLevel)
{
*buffer += "\n";
*buffer += String(indentLevel*4, ' ');
*buffer += string(indentLevel*4, ' ');
}
ConvertPtr Convert::getConvert()

View File

@@ -27,17 +27,12 @@
using std::tr1::static_pointer_cast;
using std::size_t;
using std::string;
namespace epics { namespace pvData {
static DebugLevel debugLevel = lowDebug;
static void newLine(StringBuilder buffer, int indentLevel)
{
*buffer += "\n";
for(int i=0; i<indentLevel; i++) *buffer += " ";
}
Field::Field(Type type)
: m_fieldType(type)
{
@@ -47,32 +42,11 @@ Field::~Field() {
}
void Field::toString(StringBuilder /*buffer*/,int /*indentLevel*/) const{
}
// TODO move all these to a header file
struct ScalarHashFunction {
size_t operator() (const Scalar& scalar) const { return scalar.getScalarType(); }
std::ostream& operator<<(std::ostream& o, const Field& f)
{
return f.dump(o);
};
struct ScalarArrayHashFunction {
size_t operator() (const ScalarArray& scalarArray) const { return 0x10 | scalarArray.getElementType(); }
};
struct StructureHashFunction {
size_t operator() (const Structure& /*structure*/) const { return 0; }
// TODO hash
// final int PRIME = 31;
// return PRIME * Arrays.hashCode(fieldNames) + Arrays.hashCode(fields);
};
struct StructureArrayHashFunction {
size_t operator() (const StructureArray& structureArray) const { StructureHashFunction shf; return (0x10 | shf(*(structureArray.getStructure()))); }
};
Scalar::Scalar(ScalarType scalarType)
: Field(scalar),scalarType(scalarType)
{
@@ -82,14 +56,14 @@ Scalar::Scalar(ScalarType scalarType)
Scalar::~Scalar(){}
void Scalar::toString(StringBuilder buffer,int /*indentLevel*/) const{
*buffer += getID();
std::ostream& Scalar::dump(std::ostream& o) const
{
return o << format::indent() << getID();
}
String Scalar::getID() const
string Scalar::getID() const
{
static const String idScalarLUT[] = {
static const string idScalarLUT[] = {
"boolean", // pvBoolean
"byte", // pvByte
"short", // pvShort
@@ -136,15 +110,15 @@ void Scalar::deserialize(ByteBuffer* /*buffer*/, DeserializableControl* /*contro
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
}
static String emptyString;
static string emptyStringtring;
static void serializeStructureField(const Structure* structure, ByteBuffer* buffer, SerializableControl* control)
{
// to optimize default (non-empty) IDs optimization
// empty IDs are not allowed
String id = structure->getID();
string id = structure->getID();
if (id == Structure::DEFAULT_ID) // TODO slow comparison
SerializeHelper::serializeString(emptyString, buffer, control);
SerializeHelper::serializeString(emptyStringtring, buffer, control);
else
SerializeHelper::serializeString(id, buffer, control);
@@ -161,7 +135,7 @@ static void serializeStructureField(const Structure* structure, ByteBuffer* buff
static StructureConstPtr deserializeStructureField(const FieldCreate* fieldCreate, ByteBuffer* buffer, DeserializableControl* control)
{
String id = SerializeHelper::deserializeString(buffer, control);
string id = SerializeHelper::deserializeString(buffer, control);
const std::size_t size = SerializeHelper::readSize(buffer, control);
FieldConstPtrArray fields; fields.reserve(size);
StringArray fieldNames; fieldNames.reserve(size);
@@ -181,9 +155,9 @@ static void serializeUnionField(const Union* punion, ByteBuffer* buffer, Seriali
{
// to optimize default (non-empty) IDs optimization
// empty IDs are not allowed
String id = punion->getID();
string id = punion->getID();
if (id == Union::DEFAULT_ID) // TODO slow comparison
SerializeHelper::serializeString(emptyString, buffer, control);
SerializeHelper::serializeString(emptyStringtring, buffer, control);
else
SerializeHelper::serializeString(id, buffer, control);
@@ -200,7 +174,7 @@ static void serializeUnionField(const Union* punion, ByteBuffer* buffer, Seriali
static UnionConstPtr deserializeUnionField(const FieldCreate* fieldCreate, ByteBuffer* buffer, DeserializableControl* control)
{
String id = SerializeHelper::deserializeString(buffer, control);
string id = SerializeHelper::deserializeString(buffer, control);
const std::size_t size = SerializeHelper::readSize(buffer, control);
FieldConstPtrArray fields; fields.reserve(size);
StringArray fieldNames; fieldNames.reserve(size);
@@ -216,8 +190,15 @@ static UnionConstPtr deserializeUnionField(const FieldCreate* fieldCreate, ByteB
return fieldCreate->createUnion(id, fieldNames, fields);
}
Array::Array(Type type)
: Field(type)
{
}
Array::~Array() {}
ScalarArray::ScalarArray(ScalarType elementType)
: Field(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");
@@ -244,9 +225,9 @@ int8 ScalarArray::getTypeCodeLUT() const
return typeCodeLUT[elementType];
}
const String ScalarArray::getIDScalarArrayLUT() const
const string ScalarArray::getIDScalarArrayLUT() const
{
static const String idScalarArrayLUT[] = {
static const string idScalarArrayLUT[] = {
"boolean[]", // pvBoolean
"byte[]", // pvByte
"short[]", // pvShort
@@ -263,13 +244,14 @@ const String ScalarArray::getIDScalarArrayLUT() const
return idScalarArrayLUT[elementType];
}
String ScalarArray::getID() const
string ScalarArray::getID() const
{
return getIDScalarArrayLUT();
}
void ScalarArray::toString(StringBuilder buffer,int /*indentLevel*/) const{
*buffer += getID();
std::ostream& ScalarArray::dump(std::ostream& o) const
{
return o << format::indent() << getID();
}
void ScalarArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
@@ -282,7 +264,7 @@ void ScalarArray::deserialize(ByteBuffer* /*buffer*/, DeserializableControl* /*c
}
StructureArray::StructureArray(StructureConstPtr const & structure)
: Field(structureArray),pstructure(structure)
: Array(structureArray),pstructure(structure)
{
}
@@ -290,15 +272,19 @@ StructureArray::~StructureArray() {
if(debugLevel==highDebug) printf("~StructureArray\n");
}
String StructureArray::getID() const
string StructureArray::getID() const
{
return pstructure->getID() + "[]";
}
void StructureArray::toString(StringBuilder buffer,int indentLevel) const {
*buffer += getID();
newLine(buffer,indentLevel + 1);
pstructure->toString(buffer,indentLevel + 1);
std::ostream& StructureArray::dump(std::ostream& o) const
{
o << format::indent() << getID() << std::endl;
{
format::indent_scope s(o);
o << *pstructure;
}
return o;
}
void StructureArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
@@ -312,7 +298,7 @@ void StructureArray::deserialize(ByteBuffer* /*buffer*/, DeserializableControl*
}
UnionArray::UnionArray(UnionConstPtr const & _punion)
: Field(unionArray),punion(_punion)
: Array(unionArray),punion(_punion)
{
}
@@ -320,15 +306,19 @@ UnionArray::~UnionArray() {
if(debugLevel==highDebug) printf("~UnionArray\n");
}
String UnionArray::getID() const
string UnionArray::getID() const
{
return punion->getID() + "[]";
}
void UnionArray::toString(StringBuilder buffer,int indentLevel) const {
*buffer += getID();
newLine(buffer,indentLevel + 1);
punion->toString(buffer,indentLevel + 1);
std::ostream& UnionArray::dump(std::ostream& o) const
{
o << format::indent() << getID() << std::endl;
{
format::indent_scope s(o);
o << *punion;
}
return o;
}
void UnionArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
@@ -349,12 +339,12 @@ void UnionArray::deserialize(ByteBuffer* /*buffer*/, DeserializableControl* /*co
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
}
String Structure::DEFAULT_ID = "structure";
string Structure::DEFAULT_ID = "structure";
Structure::Structure (
StringArray const & fieldNames,
FieldConstPtrArray const & infields,
String const & inid)
string const & inid)
: Field(structure),
fieldNames(fieldNames),
fields(infields),
@@ -368,7 +358,7 @@ Structure::Structure (
}
size_t number = fields.size();
for(size_t i=0; i<number; i++) {
const String& name = fieldNames[i];
const string& name = fieldNames[i];
if(name.empty()) {
throw std::invalid_argument("fieldNames has a zero length string");
}
@@ -376,10 +366,10 @@ Structure::Structure (
throw std::invalid_argument("Can't construct Structure with NULL Field");
// look for duplicates
for(size_t j=i+1; j<number; j++) {
String otherName = fieldNames[j];
string otherName = fieldNames[j];
int result = name.compare(otherName);
if(result==0) {
String message("duplicate fieldName ");
string message("duplicate fieldName ");
message += name;
throw std::invalid_argument(message);
}
@@ -390,12 +380,12 @@ Structure::Structure (
Structure::~Structure() { }
String Structure::getID() const
string Structure::getID() const
{
return id;
}
FieldConstPtr Structure::getField(String const & fieldName) const {
FieldConstPtr Structure::getField(string const & fieldName) const {
size_t numberFields = fields.size();
for(size_t i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
@@ -405,7 +395,7 @@ FieldConstPtr Structure::getField(String const & fieldName) const {
return FieldConstPtr();
}
size_t Structure::getFieldIndex(String const &fieldName) const {
size_t Structure::getFieldIndex(string const &fieldName) const {
size_t numberFields = fields.size();
for(size_t i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
@@ -415,17 +405,22 @@ size_t Structure::getFieldIndex(String const &fieldName) const {
return -1;
}
void Structure::toString(StringBuilder buffer,int indentLevel) const{
*buffer += getID();
toStringCommon(buffer,indentLevel+1);
std::ostream& Structure::dump(std::ostream& o) const
{
o << format::indent() << getID() << std::endl;
{
format::indent_scope s(o);
dumpFields(o);
}
return o;
}
void Structure::toStringCommon(StringBuilder buffer,int indentLevel) const{
newLine(buffer,indentLevel);
void Structure::dumpFields(std::ostream& o) const
{
size_t numberFields = fields.size();
for(size_t i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
*buffer += pfield->getID() + " " + fieldNames[i];
o << format::indent() << pfield->getID() << ' ' << fieldNames[i] << std::endl;
switch(pfield->getType()) {
case scalar:
case scalarArray:
@@ -434,26 +429,31 @@ void Structure::toStringCommon(StringBuilder buffer,int indentLevel) const{
{
Field const *xxx = pfield.get();
Structure const *pstruct = static_cast<Structure const*>(xxx);
pstruct->toStringCommon(buffer,indentLevel + 1);
format::indent_scope s(o);
pstruct->dumpFields(o);
break;
}
case structureArray:
newLine(buffer,indentLevel +1);
pfield->toString(buffer,indentLevel +1);
{
format::indent_scope s(o);
o << *pfield;
break;
}
case union_:
{
Field const *xxx = pfield.get();
Union const *pstruct = static_cast<Union const*>(xxx);
pstruct->toStringCommon(buffer,indentLevel + 1);
Union const *punion = static_cast<Union const*>(xxx);
format::indent_scope s(o);
punion->dumpFields(o);
break;
}
case unionArray:
newLine(buffer,indentLevel +1);
pfield->toString(buffer,indentLevel +1);
{
format::indent_scope s(o);
o << *pfield;
break;
}
}
if(i<numberFields-1) newLine(buffer,indentLevel);
}
}
@@ -467,10 +467,10 @@ void Structure::deserialize(ByteBuffer* /*buffer*/, DeserializableControl* /*con
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
}
String Union::DEFAULT_ID = "union";
string Union::DEFAULT_ID = "union";
#define UNION_ANY_ID "any"
String Union::ANY_ID = UNION_ANY_ID;
string Union::ANY_ID = UNION_ANY_ID;
Union::Union ()
: Field(union_),
@@ -485,7 +485,7 @@ Union::Union ()
Union::Union (
StringArray const & fieldNames,
FieldConstPtrArray const & infields,
String const & inid)
string const & inid)
: Field(union_),
fieldNames(fieldNames),
fields(infields),
@@ -503,7 +503,7 @@ Union::Union (
size_t number = fields.size();
for(size_t i=0; i<number; i++) {
const String& name = fieldNames[i];
const string& name = fieldNames[i];
if(name.empty()) {
throw std::invalid_argument("fieldNames has a zero length string");
}
@@ -511,10 +511,10 @@ Union::Union (
throw std::invalid_argument("Can't construct Union with NULL Field");
// look for duplicates
for(size_t j=i+1; j<number; j++) {
String otherName = fieldNames[j];
string otherName = fieldNames[j];
int result = name.compare(otherName);
if(result==0) {
String message("duplicate fieldName ");
string message("duplicate fieldName ");
message += name;
throw std::invalid_argument(message);
}
@@ -525,12 +525,12 @@ Union::Union (
Union::~Union() { }
String Union::getID() const
string Union::getID() const
{
return id;
}
FieldConstPtr Union::getField(String const & fieldName) const {
FieldConstPtr Union::getField(string const & fieldName) const {
size_t numberFields = fields.size();
for(size_t i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
@@ -540,7 +540,7 @@ FieldConstPtr Union::getField(String const & fieldName) const {
return FieldConstPtr();
}
size_t Union::getFieldIndex(String const &fieldName) const {
size_t Union::getFieldIndex(string const &fieldName) const {
size_t numberFields = fields.size();
for(size_t i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
@@ -550,19 +550,22 @@ size_t Union::getFieldIndex(String const &fieldName) const {
return -1;
}
void Union::toString(StringBuilder buffer,int indentLevel) const{
*buffer += getID();
toStringCommon(buffer,indentLevel+1);
std::ostream& Union::dump(std::ostream& o) const
{
o << getID() << std::endl;
{
format::indent_scope s(o);
dumpFields(o);
}
return o;
}
void Union::toStringCommon(StringBuilder buffer,int indentLevel) const{
newLine(buffer,indentLevel);
void Union::dumpFields(std::ostream& o) const
{
size_t numberFields = fields.size();
if (numberFields == 0) // variant support
return;
for(size_t i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
*buffer += pfield->getID() + " " + fieldNames[i];
o << format::indent() << pfield->getID() << ' ' << fieldNames[i] << std::endl;
switch(pfield->getType()) {
case scalar:
case scalarArray:
@@ -571,26 +574,31 @@ void Union::toStringCommon(StringBuilder buffer,int indentLevel) const{
{
Field const *xxx = pfield.get();
Structure const *pstruct = static_cast<Structure const*>(xxx);
pstruct->toStringCommon(buffer,indentLevel + 1);
format::indent_scope s(o);
pstruct->dumpFields(o);
break;
}
case structureArray:
newLine(buffer,indentLevel +1);
pfield->toString(buffer,indentLevel +1);
{
format::indent_scope s(o);
o << *pfield;
break;
}
case union_:
{
Field const *xxx = pfield.get();
Union const *pstruct = static_cast<Union const*>(xxx);
pstruct->toStringCommon(buffer,indentLevel + 1);
Union const *punion = static_cast<Union const*>(xxx);
format::indent_scope s(o);
punion->dumpFields(o);
break;
}
case unionArray:
newLine(buffer,indentLevel +1);
pfield->toString(buffer,indentLevel +1);
{
format::indent_scope s(o);
o << *pfield;
break;
}
}
if(i<numberFields-1) newLine(buffer,indentLevel);
}
}
@@ -616,7 +624,7 @@ void Union::deserialize(ByteBuffer* /*buffer*/, DeserializableControl* /*control
FieldBuilder::FieldBuilder() : fieldCreate(getFieldCreate()), idSet(false) {}
FieldBuilder::FieldBuilder(FieldBuilderPtr const & _parentBuilder,
std::string const & _nestedName,
string const & _nestedName,
Type _nestedClassToBuild, bool _nestedArray) :
fieldCreate(getFieldCreate()),
idSet(false),
@@ -634,32 +642,32 @@ void FieldBuilder::reset()
fields.clear();
}
FieldBuilderPtr FieldBuilder::setId(std::string const & id)
FieldBuilderPtr FieldBuilder::setId(string const & id)
{
this->id = id;
idSet = true;
return shared_from_this();
}
FieldBuilderPtr FieldBuilder::add(std::string const & name, ScalarType scalarType)
FieldBuilderPtr FieldBuilder::add(string const & name, ScalarType scalarType)
{
fields.push_back(fieldCreate->createScalar(scalarType)); fieldNames.push_back(name);
return shared_from_this();
}
FieldBuilderPtr FieldBuilder::add(std::string const & name, FieldConstPtr const & field)
FieldBuilderPtr FieldBuilder::add(string const & name, FieldConstPtr const & field)
{
fields.push_back(field); fieldNames.push_back(name);
return shared_from_this();
}
FieldBuilderPtr FieldBuilder::addArray(std::string const & name, ScalarType scalarType)
FieldBuilderPtr FieldBuilder::addArray(string const & name, ScalarType scalarType)
{
fields.push_back(fieldCreate->createScalarArray(scalarType)); fieldNames.push_back(name);
return shared_from_this();
}
FieldBuilderPtr FieldBuilder::addArray(std::string const & name, FieldConstPtr const & element)
FieldBuilderPtr FieldBuilder::addArray(string const & name, FieldConstPtr const & element)
{
switch (element->getType())
{
@@ -723,24 +731,24 @@ UnionConstPtr FieldBuilder::createUnion()
return field;
}
FieldBuilderPtr FieldBuilder::addNestedStructure(std::string const & name)
FieldBuilderPtr FieldBuilder::addNestedStructure(string const & name)
{
return FieldBuilderPtr(new FieldBuilder(shared_from_this(), name, structure, false));
}
FieldBuilderPtr FieldBuilder::addNestedUnion(std::string const & name)
FieldBuilderPtr FieldBuilder::addNestedUnion(string const & name)
{
return FieldBuilderPtr(new FieldBuilder(shared_from_this(), name, union_, false));
}
FieldBuilderPtr FieldBuilder::addNestedStructureArray(std::string const & name)
FieldBuilderPtr FieldBuilder::addNestedStructureArray(string const & name)
{
return FieldBuilderPtr(new FieldBuilder(shared_from_this(), name, structure, true));
}
FieldBuilderPtr FieldBuilder::addNestedUnionArray(std::string const & name)
FieldBuilderPtr FieldBuilder::addNestedUnionArray(string const & name)
{
return FieldBuilderPtr(new FieldBuilder(shared_from_this(), name, union_, true));
}
@@ -781,6 +789,13 @@ ScalarArrayConstPtr FieldCreate::createScalarArray(ScalarType elementType) const
return scalarArrays[elementType];
}
StructureConstPtr FieldCreate::createStructure () const
{
StringArray fieldNames;
FieldConstPtrArray fields;
return createStructure(fieldNames,fields);
}
StructureConstPtr FieldCreate::createStructure (
StringArray const & fieldNames,FieldConstPtrArray const & fields) const
{
@@ -790,7 +805,7 @@ StructureConstPtr FieldCreate::createStructure (
}
StructureConstPtr FieldCreate::createStructure (
String const & id,
string const & id,
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const
{
@@ -816,7 +831,7 @@ UnionConstPtr FieldCreate::createUnion (
}
UnionConstPtr FieldCreate::createUnion (
String const & id,
string const & id,
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const
{
@@ -845,7 +860,7 @@ UnionArrayConstPtr FieldCreate::createVariantUnionArray () const
StructureConstPtr FieldCreate::appendField(
StructureConstPtr const & structure,
String const & fieldName,
string const & fieldName,
FieldConstPtr const & field) const
{
StringArray oldNames = structure->getFieldNames();

View File

@@ -5,7 +5,6 @@ SRC_DIRS += $(PVDATA_SRC)/factory
INC += factory.h
LIBSRCS += TypeFunc.cpp
LIBSRCS += FieldCreateFactory.cpp
LIBSRCS += PVAuxInfoImpl.cpp
LIBSRCS += PVField.cpp
LIBSRCS += PVScalar.cpp
LIBSRCS += PVArray.cpp

View File

@@ -1,86 +0,0 @@
/*PVAuxInfo.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#define epicsExportSharedSymbols
#include <pv/noDefaultMethods.h>
#include <pv/pvData.h>
#include <pv/convert.h>
#include <pv/factory.h>
#include <pv/lock.h>
namespace epics { namespace pvData {
PVAuxInfo::PVAuxInfo(PVField * pvField)
: pvField(pvField),
pvInfos(std::map<String,std::tr1::shared_ptr<PVScalar> > ())
{
}
PVAuxInfo::~PVAuxInfo()
{
}
PVField * PVAuxInfo::getPVField() {
return pvField;
}
PVScalarPtr PVAuxInfo::createInfo(String const & key,ScalarType scalarType)
{
PVInfoIter iter = pvInfos.find(key);
if(iter!=pvInfos.end()) {
String message = key.c_str();
message += " already exists ";
pvField->message(message,errorMessage);
return nullPVScalar;
}
PVScalarPtr pvScalar = getPVDataCreate()->createPVScalar(scalarType);
pvInfos.insert(PVInfoPair(key,pvScalar));
return pvScalar;
}
PVScalarPtr PVAuxInfo::getInfo(String const & key)
{
PVInfoIter iter;
iter = pvInfos.find(key);
if(iter==pvInfos.end()) return nullPVScalar;
return iter->second;
}
PVAuxInfo::PVInfoMap & PVAuxInfo::getInfoMap()
{
return pvInfos;
}
void PVAuxInfo::toString(StringBuilder buf)
{
PVAuxInfo::toString(buf,0);
}
void PVAuxInfo::toString(StringBuilder buf,int indentLevel)
{
if(pvInfos.size()<=0) return;
ConvertPtr convert = getConvert();
convert->newLine(buf,indentLevel);
*buf += "auxInfo";
for(PVInfoIter iter = pvInfos.begin(); iter!= pvInfos.end(); ++iter) {
convert->newLine(buf,indentLevel+1);
PVFieldPtr value = iter->second;
value->toString(buf,indentLevel + 1);
}
}
}}

View File

@@ -27,6 +27,7 @@
using std::tr1::static_pointer_cast;
using std::size_t;
using std::string;
using std::min;
namespace epics { namespace pvData {
@@ -43,7 +44,7 @@ template<> const ScalarType PVUInt::typeCode = pvUInt;
template<> const ScalarType PVULong::typeCode = pvULong;
template<> const ScalarType PVFloat::typeCode = pvFloat;
template<> const ScalarType PVDouble::typeCode = pvDouble;
template<> const ScalarType PVScalarValue<String>::typeCode = pvString;
template<> const ScalarType PVScalarValue<string>::typeCode = pvString;
template<> const ScalarType PVBooleanArray::typeCode = pvBoolean;
template<> const ScalarType PVByteArray::typeCode = pvByte;
@@ -83,7 +84,7 @@ template<typename T>
BasePVScalar<T>::BasePVScalar(ScalarConstPtr const & scalar)
: PVScalarValue<T>(scalar),value(0)
{}
//Note: '0' is a suitable default for all POD types (not String)
//Note: '0' is a suitable default for all POD types (not string)
template<typename T>
BasePVScalar<T>::~BasePVScalar() {}
@@ -128,14 +129,14 @@ typedef BasePVScalar<double> BasePVDouble;
// BasePVString is special case, since it implements SerializableArray
class BasePVString : public PVString {
public:
typedef String value_type;
typedef String* pointer;
typedef const String* const_pointer;
typedef string value_type;
typedef string* pointer;
typedef const string* const_pointer;
BasePVString(ScalarConstPtr const & scalar);
virtual ~BasePVString();
virtual String get() const ;
virtual void put(String val);
virtual string get() const ;
virtual void put(string val);
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) const;
virtual void deserialize(ByteBuffer *pbuffer,
@@ -143,7 +144,7 @@ public:
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, size_t offset, size_t count) const;
private:
String value;
string value;
};
BasePVString::BasePVString(ScalarConstPtr const & scalar)
@@ -152,9 +153,9 @@ BasePVString::BasePVString(ScalarConstPtr const & scalar)
BasePVString::~BasePVString() {}
String BasePVString::get() const { return value;}
string BasePVString::get() const { return value;}
void BasePVString::put(String val)
void BasePVString::put(string val)
{
value = val;
postPut();
@@ -362,10 +363,10 @@ void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
}
}
// specializations for String
// specializations for string
template<>
void DefaultPVArray<String>::deserialize(ByteBuffer *pbuffer,
void DefaultPVArray<string>::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pcontrol) {
size_t size = SerializeHelper::readSize(pbuffer, pcontrol);
@@ -378,7 +379,7 @@ void DefaultPVArray<String>::deserialize(ByteBuffer *pbuffer,
nextvalue.slice(0, size);
String * pvalue = nextvalue.data();
string * pvalue = nextvalue.data();
for(size_t i = 0; i<size; i++) {
pvalue[i] = SerializeHelper::deserializeString(pbuffer,
pcontrol);
@@ -389,7 +390,7 @@ void DefaultPVArray<String>::deserialize(ByteBuffer *pbuffer,
}
template<>
void DefaultPVArray<String>::serialize(ByteBuffer *pbuffer,
void DefaultPVArray<string>::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, size_t offset, size_t count) const {
const_svector temp(value);
@@ -397,7 +398,7 @@ void DefaultPVArray<String>::serialize(ByteBuffer *pbuffer,
SerializeHelper::writeSize(temp.size(), pbuffer, pflusher);
const String * pvalue = temp.data();
const string * pvalue = temp.data();
for(size_t i = 0; i<temp.size(); i++) {
SerializeHelper::serializeString(pvalue[i], pbuffer, pflusher);
}
@@ -414,7 +415,7 @@ typedef DefaultPVArray<uint32> BasePVUIntArray;
typedef DefaultPVArray<uint64> BasePVULongArray;
typedef DefaultPVArray<float> BasePVFloatArray;
typedef DefaultPVArray<double> BasePVDoubleArray;
typedef DefaultPVArray<String> BasePVStringArray;
typedef DefaultPVArray<string> BasePVStringArray;
// Factory
@@ -548,16 +549,6 @@ PVScalarPtr PVDataCreate::createPVScalar(PVScalarPtr const & scalarToClone)
ScalarType scalarType = scalarToClone->getScalar()->getScalarType();
PVScalarPtr pvScalar = createPVScalar(scalarType);
getConvert()->copyScalar(scalarToClone, pvScalar);
PVAuxInfoPtr from = scalarToClone->getPVAuxInfo();
PVAuxInfoPtr to = pvScalar->getPVAuxInfo();
PVAuxInfo::PVInfoMap & map = from->getInfoMap();
for(PVAuxInfo::PVInfoIter iter = map.begin(); iter!= map.end(); ++iter) {
String key = iter->first;
PVScalarPtr pvFrom = iter->second;
ScalarConstPtr scalar = pvFrom->getScalar();
PVScalarPtr pvTo = to->createInfo(key,scalar->getScalarType());
getConvert()->copyScalar(pvFrom,pvTo);
}
return pvScalar;
}
@@ -607,16 +598,6 @@ PVScalarArrayPtr PVDataCreate::createPVScalarArray(
PVScalarArrayPtr pvArray = createPVScalarArray(
arrayToClone->getScalarArray()->getElementType());
pvArray->assign(*arrayToClone.get());
PVAuxInfoPtr from = arrayToClone->getPVAuxInfo();
PVAuxInfoPtr to = pvArray->getPVAuxInfo();
PVAuxInfo::PVInfoMap & map = from->getInfoMap();
for(PVAuxInfo::PVInfoIter iter = map.begin(); iter!= map.end(); ++iter) {
String key = iter->first;
PVScalarPtr pvFrom = iter->second;
ScalarConstPtr scalar = pvFrom->getScalar();
PVScalarPtr pvTo = to->createInfo(key,scalar->getScalarType());
getConvert()->copyScalar(pvFrom,pvTo);
}
return pvArray;
}

View File

@@ -20,10 +20,10 @@
using std::tr1::const_pointer_cast;
using std::size_t;
using std::string;
namespace epics { namespace pvData {
PVField::PVField(FieldConstPtr field)
: notImplemented("not implemented"),
parent(NULL),field(field),
@@ -35,49 +35,6 @@ PVField::PVField(FieldConstPtr field)
PVField::~PVField()
{ }
void PVField::message(
String message,
MessageType messageType,
String fullFieldName)
{
if(parent!=NULL) {
if(fullFieldName.length()>0) {
fullFieldName = fieldName + '.' + fullFieldName;
} else {
fullFieldName = fieldName;
}
parent->message(message,messageType,fullFieldName);
return;
}
message = fullFieldName + " " + message;
if(requester) {
requester->message(message,messageType);
} else {
printf("%s %s %s\n",
getMessageTypeName(messageType).c_str(),
fieldName.c_str(),
message.c_str());
}
}
void PVField::message(String message,MessageType messageType)
{
PVField::message(message,messageType,"");
}
void PVField::setRequester(RequesterPtr const &req)
{
if(parent!=NULL) {
throw std::logic_error(
"PVField::setRequester only legal for top level structure");
}
if(requester.get()!=NULL) {
if(requester.get()==req.get()) return;
throw std::logic_error(
"PVField::setRequester requester is already present");
}
requester = req;
}
size_t PVField::getFieldOffset() const
{
@@ -97,12 +54,6 @@ size_t PVField::getNumberFields() const
return (nextFieldOffset - fieldOffset);
}
PVAuxInfoPtr & PVField::getPVAuxInfo(){
if(pvAuxInfo.get()==NULL) {
pvAuxInfo = PVAuxInfoPtr(new PVAuxInfo(this));
}
return pvAuxInfo;
}
bool PVField::isImmutable() const {return immutable;}
@@ -112,46 +63,6 @@ const FieldConstPtr & PVField::getField() const {return field;}
PVStructure *PVField::getParent() const {return parent;}
void PVField::replacePVField(const PVFieldPtr & newPVField)
{
if(parent==NULL) {
throw std::logic_error("no parent");
}
PVFieldPtrArray pvFields = parent->getPVFields();
StructureConstPtr structure = parent->getStructure();
StringArray fieldNames = structure->getFieldNames();
for(size_t i=0; i<fieldNames.size(); i++) {
if(newPVField->getFieldName().compare(fieldNames[i]) == 0) {
pvFields[i] = newPVField;
return;
}
}
throw std::logic_error("Did not find field in parent");
}
void PVField::replaceField(FieldConstPtr &xxx)
{
field = xxx;
}
void PVField::renameField(String const & newName)
{
if(parent==NULL) {
throw std::logic_error("no parent");
}
std::tr1::shared_ptr<Structure> parentStructure = const_pointer_cast<Structure>(
parent->getStructure());
PVFieldPtrArray pvFields = parent->getPVFields();
for(size_t i=0; i<pvFields.size(); i++) {
if(pvFields[i].get()==this) {
parentStructure->renameField(i,newName);
fieldName = newName;
return;
}
}
throw std::logic_error("Did not find field in parent");
}
void PVField::postPut()
{
if(postHandler.get()!=NULL) postHandler->postPut();
@@ -168,7 +79,7 @@ void PVField::setPostHandler(PostHandlerPtr const &handler)
postHandler = handler;
}
void PVField::setParentAndName(PVStructure * xxx,String const & name)
void PVField::setParentAndName(PVStructure * xxx,string const & name)
{
parent = xxx;
fieldName = name;
@@ -179,68 +90,19 @@ bool PVField::equals(PVField &pv)
return pv==*this;
}
void PVField::toString(StringBuilder buf)
{
toString(buf,0);
}
void PVField::toString(StringBuilder buf,int indentLevel)
{
Convert().getString(buf,this,indentLevel);
if(pvAuxInfo.get()!=NULL) pvAuxInfo->toString(buf,indentLevel);
}
std::ostream& operator<<(std::ostream& o, const PVField& f)
{
std::ostream& ro = f.dumpValue(o);
// TODO I do not want to call getPVAuxInfo() since it lazily creates a new instance of it
//if (f.pvAuxInfo.get()!=NULL) ro << *(f.pvAuxInfo.get());
return ro;
return f.dumpValue(o);
};
namespace format
string PVField::getFullName() const
{
std::ostream& operator<<(std::ostream& os, indent_level const& indent)
{
indent_value(os) = indent.level;
return os;
}
std::ostream& operator<<(std::ostream& os, indent const&)
{
long il = indent_value(os);
std::size_t spaces = static_cast<std::size_t>(il) * 4;
return os << std::string(spaces, ' ');
}
array_at_internal operator<<(std::ostream& str, array_at const& manip)
{
return array_at_internal(manip.index, str);
}
};
String PVField::getFullName() const
{
size_t size=fieldName.size();
string ret(fieldName);
for(PVField *fld=getParent(); fld; fld=fld->getParent())
{
size+=fld->fieldName.size()+1;
if(fld->getFieldName().size()==0) break;
ret = fld->getFieldName() + '.' + ret;
}
String ret(size, '.');
size_t pos=size - fieldName.size();
ret.replace(pos, String::npos, fieldName);
for(PVField *fld=getParent(); fld; fld=fld->getParent())
{
const String& nref = fld->fieldName;
assert(pos >= nref.size()+1);
pos -= nref.size()+1;
ret.replace(pos, String::npos, nref);
}
assert(pos==0);
return ret;
}

View File

@@ -22,6 +22,7 @@
using std::tr1::static_pointer_cast;
using std::size_t;
using std::string;
namespace epics { namespace pvData {
@@ -45,7 +46,7 @@ PVUnionArrayPtr PVStructure::nullPVUnionArray;
PVScalarArrayPtr PVStructure::nullPVScalarArray;
static PVFieldPtr findSubField(
String const &fieldName,
string const &fieldName,
const PVStructure *pvStructure);
PVStructure::PVStructure(StructureConstPtr const & structurePtr)
@@ -60,7 +61,7 @@ PVStructure::PVStructure(StructureConstPtr const & structurePtr)
pvFields.reserve(numberFields);
PVDataCreatePtr pvDataCreate = getPVDataCreate();
for(size_t i=0; i<numberFields; i++) {
pvFields.push_back(pvDataCreate->createPVField(fields[i]));
pvFields.push_back(pvDataCreate->createPVField(fields[i]));
}
for(size_t i=0; i<numberFields; i++) {
pvFields[i]->setParentAndName(this,fieldNames[i]);
@@ -109,7 +110,7 @@ const PVFieldPtrArray & PVStructure::getPVFields() const
return pvFields;
}
PVFieldPtr PVStructure::getSubField(String const &fieldName) const
PVFieldPtr PVStructure::getSubField(string const &fieldName) const
{
return findSubField(fieldName,this);
}
@@ -134,183 +135,79 @@ PVFieldPtr PVStructure::getSubField(size_t fieldOffset) const
throw std::logic_error("PVStructure.getSubField: Logic error");
}
void PVStructure::fixParentStructure()
{
PVStructure *parent = getParent();
if(parent==NULL) return;
StructureConstPtr parentStructure = parent->structurePtr;
String fieldName = getFieldName();
size_t index = parentStructure->getFieldIndex(fieldName);
StringArray const &fieldNames = parentStructure->getFieldNames();
size_t num = fieldNames.size();
FieldConstPtrArray fields(num);
FieldConstPtrArray const & oldFields = parentStructure->getFields();
for(size_t i=0; i< num; i++) {
if(i==index) {
fields[i] = structurePtr;
} else {
fields[i] = oldFields[i];
}
}
FieldConstPtr field = getFieldCreate()->createStructure(
parentStructure->getID(),fieldNames,fields);
parent->replaceField(field);
parent->fixParentStructure();
}
void PVStructure::appendPVField(
String const &fieldName,
PVFieldPtr const & pvField)
{
size_t origLength = pvFields.size();
size_t newLength = origLength+1;
PVFieldPtrArray * xxx = const_cast<PVFieldPtrArray *>(&pvFields);
xxx->push_back(pvField);
FieldConstPtr field = getFieldCreate()->appendField(
structurePtr,fieldName,pvField->getField());
replaceField(field);
structurePtr = static_pointer_cast<const Structure>(field);
StringArray fieldNames = structurePtr->getFieldNames();
for(size_t i=0; i<newLength; i++) {
pvFields[i]->setParentAndName(this,fieldNames[i]);
}
fixParentStructure();
}
void PVStructure::appendPVFields(
StringArray const & fieldNames,
PVFieldPtrArray const & pvFields)
{
size_t origLength = this->pvFields.size();
size_t extra = fieldNames.size();
if(extra==0) return;
size_t newLength = origLength + extra;
PVFieldPtrArray * xxx = const_cast<PVFieldPtrArray *>(&this->pvFields);
xxx->reserve(newLength);
for(size_t i=0; i<extra; i++) {
xxx->push_back(pvFields[i]);
}
FieldConstPtrArray fields;
fields.reserve(extra);
for(size_t i=0; i<extra; i++) fields.push_back(pvFields[i]->getField());
FieldConstPtr field = getFieldCreate()->appendFields(
structurePtr,fieldNames,fields);
replaceField(field);
structurePtr = static_pointer_cast<const Structure>(field);
StringArray names = structurePtr->getFieldNames();
for(size_t i=0; i<newLength; i++) {
(*xxx)[i]->setParentAndName(this,names[i]);
}
fixParentStructure();
}
void PVStructure::removePVField(String const &fieldName)
{
PVFieldPtr pvField = getSubField(fieldName);
if(pvField.get()==NULL) {
return;
}
size_t origLength = pvFields.size();
size_t newLength = origLength - 1;
PVFieldPtrArray const & origPVFields = pvFields;
FieldConstPtrArray origFields = structurePtr->getFields();
PVFieldPtrArray newPVFields;
newPVFields.reserve(newLength);
StringArray newFieldNames;
newFieldNames.reserve(newLength);
FieldConstPtrArray fields;
fields.reserve(newLength);
for(size_t i=0; i<origLength; i++) {
if(origPVFields[i]!=pvField) {
newFieldNames.push_back(origPVFields[i]->getFieldName());
newPVFields.push_back(origPVFields[i]);
fields.push_back(origFields[i]);
}
}
PVFieldPtrArray * xxx = const_cast<PVFieldPtrArray *>(&pvFields);
xxx->swap(newPVFields);
FieldConstPtr field = getFieldCreate()->createStructure(
structurePtr->getID(),newFieldNames,fields);
replaceField(field);
structurePtr = static_pointer_cast<const Structure>(field);
StringArray fieldNames = structurePtr->getFieldNames();
for(size_t i=0; i<newLength; i++) {
pvFields[i]->setParentAndName(this,fieldNames[i]);
}
}
PVBooleanPtr PVStructure::getBooleanField(String const &fieldName)
PVBooleanPtr PVStructure::getBooleanField(string const &fieldName)
{
return getSubField<PVBoolean>(fieldName);
}
PVBytePtr PVStructure::getByteField(String const &fieldName)
PVBytePtr PVStructure::getByteField(string const &fieldName)
{
return getSubField<PVByte>(fieldName);
}
PVShortPtr PVStructure::getShortField(String const &fieldName)
PVShortPtr PVStructure::getShortField(string const &fieldName)
{
return getSubField<PVShort>(fieldName);
}
PVIntPtr PVStructure::getIntField(String const &fieldName)
PVIntPtr PVStructure::getIntField(string const &fieldName)
{
return getSubField<PVInt>(fieldName);
}
PVLongPtr PVStructure::getLongField(String const &fieldName)
PVLongPtr PVStructure::getLongField(string const &fieldName)
{
return getSubField<PVLong>(fieldName);
}
PVUBytePtr PVStructure::getUByteField(String const &fieldName)
PVUBytePtr PVStructure::getUByteField(string const &fieldName)
{
return getSubField<PVUByte>(fieldName);
}
PVUShortPtr PVStructure::getUShortField(String const &fieldName)
PVUShortPtr PVStructure::getUShortField(string const &fieldName)
{
return getSubField<PVUShort>(fieldName);
}
PVUIntPtr PVStructure::getUIntField(String const &fieldName)
PVUIntPtr PVStructure::getUIntField(string const &fieldName)
{
return getSubField<PVUInt>(fieldName);
}
PVULongPtr PVStructure::getULongField(String const &fieldName)
PVULongPtr PVStructure::getULongField(string const &fieldName)
{
return getSubField<PVULong>(fieldName);
}
PVFloatPtr PVStructure::getFloatField(String const &fieldName)
PVFloatPtr PVStructure::getFloatField(string const &fieldName)
{
return getSubField<PVFloat>(fieldName);
}
PVDoublePtr PVStructure::getDoubleField(String const &fieldName)
PVDoublePtr PVStructure::getDoubleField(string const &fieldName)
{
return getSubField<PVDouble>(fieldName);
}
PVStringPtr PVStructure::getStringField(String const &fieldName)
PVStringPtr PVStructure::getStringField(string const &fieldName)
{
return getSubField<PVString>(fieldName);
}
PVStructurePtr PVStructure::getStructureField(String const &fieldName)
PVStructurePtr PVStructure::getStructureField(string const &fieldName)
{
return getSubField<PVStructure>(fieldName);
}
PVUnionPtr PVStructure::getUnionField(String const &fieldName)
PVUnionPtr PVStructure::getUnionField(string const &fieldName)
{
return getSubField<PVUnion>(fieldName);
}
PVScalarArrayPtr PVStructure::getScalarArrayField(
String const &fieldName,ScalarType elementType)
string const &fieldName,ScalarType elementType)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
@@ -330,29 +227,17 @@ PVScalarArrayPtr PVStructure::getScalarArrayField(
}
PVStructureArrayPtr PVStructure::getStructureArrayField(
String const &fieldName)
string const &fieldName)
{
return getSubField<PVStructureArray>(fieldName);
}
PVUnionArrayPtr PVStructure::getUnionArrayField(
String const &fieldName)
string const &fieldName)
{
return getSubField<PVUnionArray>(fieldName);
}
String PVStructure::getExtendsStructureName() const
{
return extendsStructureName;
}
bool PVStructure::putExtendsStructureName(
String const &xxx)
{
if(extendsStructureName.length()!=0) return false;
extendsStructureName = xxx;
return true;
}
void PVStructure::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) const {
@@ -444,13 +329,13 @@ void PVStructure::deserialize(ByteBuffer *pbuffer,
}
static PVFieldPtr findSubField(
String const & fieldName,
string const & fieldName,
PVStructure const *pvStructure)
{
if( fieldName.length()<1) return PVFieldPtr();
String::size_type index = fieldName.find('.');
String name = fieldName;
String restOfName = String();
string::size_type index = fieldName.find('.');
string name = fieldName;
string restOfName = string();
if(index>0) {
name = fieldName.substr(0, index);
if(fieldName.length()>index) {
@@ -477,10 +362,6 @@ static PVFieldPtr findSubField(
std::ostream& PVStructure::dumpValue(std::ostream& o) const
{
o << format::indent() << getStructure()->getID() << ' ' << getFieldName();
String extendsName = getExtendsStructureName();
if(extendsName.length()>0) {
o << " extends " << extendsName;
}
o << std::endl;
{
format::indent_scope s(o);

View File

@@ -22,6 +22,7 @@
using std::tr1::static_pointer_cast;
using std::size_t;
using std::string;
namespace epics { namespace pvData {
@@ -58,11 +59,11 @@ int32 PVUnion::getSelectedIndex() const
return selector;
}
String PVUnion::getSelectedFieldName() const
string PVUnion::getSelectedFieldName() const
{
// no name for undefined and for variant unions
if (selector == UNDEFINED_INDEX)
return String();
return string();
else
return unionPtr->getFieldName(selector);
}
@@ -91,7 +92,7 @@ PVFieldPtr PVUnion::select(int32 index)
return value;
}
PVFieldPtr PVUnion::select(String const & fieldName)
PVFieldPtr PVUnion::select(string const & fieldName)
{
int32 index = variant ? -1 : static_cast<int32>(unionPtr->getFieldIndex(fieldName));
if (index == -1)
@@ -126,9 +127,10 @@ void PVUnion::set(int32 index, PVFieldPtr const & value)
selector = index;
this->value = value;
postPut();
}
void PVUnion::set(String const & fieldName, PVFieldPtr const & value)
void PVUnion::set(string const & fieldName, PVFieldPtr const & value)
{
int32 index = variant ? -1 : static_cast<int32>(unionPtr->getFieldIndex(fieldName));
if (index == -1)

View File

@@ -17,6 +17,7 @@
#include <pv/standardField.h>
using std::tr1::static_pointer_cast;
using std::string;
namespace epics { namespace pvData {
@@ -49,7 +50,7 @@ void StandardField::init()
StandardField::~StandardField(){}
StructureConstPtr StandardField::createProperties(String id,FieldConstPtr field,String properties)
StructureConstPtr StandardField::createProperties(string id,FieldConstPtr field,string properties)
{
bool gotAlarm = false;
bool gotTimeStamp = false;
@@ -57,11 +58,11 @@ StructureConstPtr StandardField::createProperties(String id,FieldConstPtr field,
bool gotControl = false;
bool gotValueAlarm = false;
int numProp = 0;
if(properties.find("alarm")!=String::npos) { gotAlarm = true; numProp++; }
if(properties.find("timeStamp")!=String::npos) { gotTimeStamp = true; numProp++; }
if(properties.find("display")!=String::npos) { gotDisplay = true; numProp++; }
if(properties.find("control")!=String::npos) { gotControl = true; numProp++; }
if(properties.find("valueAlarm")!=String::npos) { gotValueAlarm = true; numProp++; }
if(properties.find("alarm")!=string::npos) { gotAlarm = true; numProp++; }
if(properties.find("timeStamp")!=string::npos) { gotTimeStamp = true; numProp++; }
if(properties.find("display")!=string::npos) { gotDisplay = true; numProp++; }
if(properties.find("control")!=string::npos) { gotControl = true; numProp++; }
if(properties.find("valueAlarm")!=string::npos) { gotValueAlarm = true; numProp++; }
StructureConstPtr valueAlarm;
Type type= field->getType();
while(gotValueAlarm) {
@@ -82,7 +83,7 @@ StructureConstPtr StandardField::createProperties(String id,FieldConstPtr field,
case pvFloat: valueAlarm = floatAlarmField; break;
case pvDouble: valueAlarm = doubleAlarmField; break;
case pvString:
throw std::logic_error(String("valueAlarm property not supported for pvString"));
throw std::logic_error(string("valueAlarm property not supported for pvString"));
}
break;
}
@@ -93,8 +94,8 @@ StructureConstPtr StandardField::createProperties(String id,FieldConstPtr field,
FieldConstPtrArray fields = structurePtr->getFields();
FieldConstPtr first = fields[0];
FieldConstPtr second = fields[1];
String nameFirst = names[0];
String nameSecond = names[1];
string nameFirst = names[0];
string nameSecond = names[1];
int compareFirst = nameFirst.compare("index");
int compareSecond = nameSecond.compare("choices");
if(compareFirst==0 && compareSecond==0) {
@@ -112,7 +113,7 @@ StructureConstPtr StandardField::createProperties(String id,FieldConstPtr field,
}
}
}
throw std::logic_error(String("valueAlarm property for illegal type"));
throw std::logic_error(string("valueAlarm property for illegal type"));
}
size_t numFields = numProp+1;
FieldConstPtrArray fields(numFields);
@@ -499,14 +500,28 @@ void StandardField::createEnumeratedAlarm() {
StructureConstPtr StandardField::scalar(
ScalarType type,String const &properties)
ScalarType type,string const &properties)
{
ScalarConstPtr field = fieldCreate->createScalar(type); // scalar_t
return createProperties("uri:ev4:nt/2012/pwd:NTScalar",field,properties);
}
StructureConstPtr StandardField::regUnion(
UnionConstPtr const &field,
string const & properties)
{
return createProperties("uri:ev4:nt/2012/pwd:NTUnion",field,properties);
}
StructureConstPtr StandardField::variantUnion(
string const & properties)
{
UnionConstPtr field = fieldCreate->createVariantUnion();
return createProperties("uri:ev4:nt/2012/pwd:NTUnion",field,properties);
}
StructureConstPtr StandardField::scalarArray(
ScalarType elementType, String const &properties)
ScalarType elementType, string const &properties)
{
ScalarArrayConstPtr field = fieldCreate->createScalarArray(elementType); // scalar_t[]
return createProperties("uri:ev4:nt/2012/pwd:NTScalarArray",field,properties);
@@ -514,11 +529,19 @@ StructureConstPtr StandardField::scalarArray(
StructureConstPtr StandardField::structureArray(
StructureConstPtr const & structure,String const &properties)
StructureConstPtr const & structure,string const &properties)
{
StructureArrayConstPtr field = fieldCreate->createStructureArray(
structure);
return createProperties("uri:ev4:nt/2012/pwd:NTAny",field,properties);
return createProperties("uri:ev4:nt/2012/pwd:NTStructureArray",field,properties);
}
StructureConstPtr StandardField::unionArray(
UnionConstPtr const & punion,string const &properties)
{
UnionArrayConstPtr field = fieldCreate->createUnionArray(
punion);
return createProperties("uri:ev4:nt/2012/pwd:NTUnionArray",field,properties);
}
StructureConstPtr StandardField::enumerated()
@@ -534,7 +557,7 @@ StructureConstPtr StandardField::enumerated()
// NOTE: if this method is used to get NTEnum wihtout properties the ID will be wrong!
}
StructureConstPtr StandardField::enumerated(String const &properties)
StructureConstPtr StandardField::enumerated(string const &properties)
{
StructureConstPtr field = enumerated(); // enum_t
return createProperties("uri:ev4:nt/2012/pwd:NTEnum",field,properties);

View File

@@ -18,6 +18,8 @@
#include <pv/standardField.h>
#include <pv/standardPVField.h>
using std::string;
namespace epics { namespace pvData {
StandardPVField::StandardPVField()
@@ -30,7 +32,7 @@ StandardPVField::StandardPVField()
StandardPVField::~StandardPVField(){}
PVStructurePtr StandardPVField::scalar(
ScalarType type,String const & properties)
ScalarType type,string const & properties)
{
StructureConstPtr field = standardField->scalar(type,properties);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
@@ -38,7 +40,7 @@ PVStructurePtr StandardPVField::scalar(
}
PVStructurePtr StandardPVField::scalarArray(
ScalarType elementType, String const & properties)
ScalarType elementType, string const & properties)
{
StructureConstPtr field = standardField->scalarArray(elementType,properties);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
@@ -46,13 +48,21 @@ PVStructurePtr StandardPVField::scalarArray(
}
PVStructurePtr StandardPVField::structureArray(
StructureConstPtr const & structure,String const & properties)
StructureConstPtr const & structure,string const & properties)
{
StructureConstPtr field = standardField->structureArray(structure,properties);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
return pvStructure;
}
PVStructurePtr StandardPVField::unionArray(
UnionConstPtr const & punion,string const & properties)
{
StructureConstPtr field = standardField->unionArray(punion,properties);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
return pvStructure;
}
PVStructurePtr StandardPVField::enumerated(StringArray const &choices)
{
StructureConstPtr field = standardField->enumerated();
@@ -66,7 +76,7 @@ PVStructurePtr StandardPVField::enumerated(StringArray const &choices)
}
PVStructurePtr StandardPVField::enumerated(
StringArray const &choices,String const & properties)
StringArray const &choices,string const & properties)
{
StructureConstPtr field = standardField->enumerated(properties);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);

View File

@@ -19,6 +19,8 @@
#include "dbDefs.h" // for NELEMENTS
using std::string;
namespace epics { namespace pvData {
namespace TypeFunc {
@@ -30,11 +32,13 @@ namespace TypeFunc {
THROW_EXCEPTION2(std::invalid_argument, "logic error unknown Type");
return names[t];
}
void toString(StringBuilder buf,const Type type) {
*buf += name(type);
}
} // namespace TypeFunc
std::ostream& operator<<(std::ostream& o, const Type& type)
{
return o << TypeFunc::name(type);
}
namespace ScalarTypeFunc {
bool isInteger(ScalarType type) {
@@ -63,7 +67,7 @@ namespace ScalarTypeFunc {
"ubyte", "ushort", "uint", "ulong",
"float", "double", "string",
};
ScalarType getScalarType(const String& pvalue) {
ScalarType getScalarType(const string& pvalue) {
for(size_t i=0; i<NELEMENTS(names); i++)
if(pvalue==names[i])
return ScalarType(i);
@@ -76,10 +80,6 @@ namespace ScalarTypeFunc {
return names[t];
}
void toString(StringBuilder buf,const ScalarType scalarType) {
*buf += name(scalarType);
}
size_t elementSize(ScalarType id)
{
switch(id) {
@@ -95,7 +95,7 @@ namespace ScalarTypeFunc {
OP(pvLong, int64);
OP(pvFloat, float);
OP(pvDouble, double);
OP(pvString, String);
OP(pvString, string);
#undef OP
default:
THROW_EXCEPTION2(std::invalid_argument, "error unknown ScalarType");
@@ -117,7 +117,7 @@ namespace ScalarTypeFunc {
OP(pvLong, int64);
OP(pvFloat, float);
OP(pvDouble, double);
OP(pvString, String);
OP(pvString, string);
#undef OP
default:
throw std::bad_alloc();
@@ -126,4 +126,9 @@ namespace ScalarTypeFunc {
} // namespace ScalarTypeFunc
std::ostream& operator<<(std::ostream& o, const ScalarType& scalarType)
{
return o << ScalarTypeFunc::name(scalarType);
}
}}

View File

@@ -10,6 +10,8 @@
#define epicsExportSharedSymbols
#include <pv/printer.h>
using std::string;
namespace {
void indentN(std::ostream& strm, size_t N)
@@ -22,6 +24,27 @@ void indentN(std::ostream& strm, size_t N)
namespace epics { namespace pvData {
namespace format
{
std::ostream& operator<<(std::ostream& os, indent_level const& indent)
{
indent_value(os) = indent.level;
return os;
}
std::ostream& operator<<(std::ostream& os, indent const&)
{
long il = indent_value(os);
std::size_t spaces = static_cast<std::size_t>(il) * 4;
return os << string(spaces, ' ');
}
array_at_internal operator<<(std::ostream& str, array_at const& manip)
{
return array_at_internal(manip.index, str);
}
};
PrinterBase::PrinterBase()
:strm(NULL)
{}
@@ -199,9 +222,6 @@ void PrinterPlain::beginStructure(const PVStructure& pv)
{
indentN(S(), ilvl);
S() << pv.getStructure()->getID() << " " << pv.getFieldName();
String ename(pv.getExtendsStructureName());
if(!ename.empty())
S() << " extends " << ename;
S() << std::endl;
ilvl++;
}
@@ -242,14 +262,14 @@ void PrinterPlain::encodeScalar(const PVScalar& pv)
indentN(S(), ilvl);
S() << pv.getScalar()->getID() << " "
<< pv.getFieldName() << " "
<< pv.getAs<String>() << std::endl;
<< pv.getAs<string>() << std::endl;
}
void PrinterPlain::encodeArray(const PVScalarArray& pv)
{
indentN(S(), ilvl);
shared_vector<const String> temp;
pv.getAs<String>(temp);
shared_vector<const string> temp;
pv.getAs<string>(temp);
S() << pv.getScalarArray()->getID() << " "
<< pv.getFieldName() << " [";

View File

@@ -14,31 +14,36 @@
#define epicsExportSharedSymbols
#include <pv/pvSubArrayCopy.h>
using std::cout;
using std::endl;
using std::string;
namespace epics { namespace pvData {
template<typename T>
void copy(
PVValueArray<T> & pvFrom,
size_t fromOffset,
size_t fromStride,
PVValueArray<T> & pvTo,
size_t toOffset,
size_t len)
size_t toStride,
size_t count)
{
if(pvTo.isImmutable()) {
throw std::logic_error("pvSubArrayCopy to is immutable");
}
if(pvTo.isImmutable()) throw std::invalid_argument("pvSubArrayCopy: pvTo is immutable");
if(fromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1");
size_t fromLength = pvFrom.getLength();
if(fromOffset+len>fromLength) {
throw std::length_error("pvSubArrayCopy from length error");
}
size_t maxcount = (fromLength -fromOffset + fromStride -1)/fromStride;
if(count>maxcount) throw std::invalid_argument("pvSubArrayCopy pvFrom length error");
size_t newLength = toOffset + count*toStride;
size_t capacity = pvTo.getCapacity();
if(toOffset+len>capacity) capacity = toOffset + len;
if(newLength>capacity) capacity = newLength;
shared_vector<T> temp(capacity);
typename PVValueArray<T>::const_svector vecFrom = pvFrom.view();
typename PVValueArray<T>::const_svector vecTo = pvTo.view();
for(size_t i=0; i<toOffset; ++i) temp[i] = vecTo[i];
for(size_t i=0; i<len; ++i) temp[i + toOffset] = vecFrom[i + fromOffset];
for(size_t i=len + toOffset; i<capacity; ++i) temp[i] = vecTo[i];
for(size_t i=0; i<pvTo.getLength(); ++i) temp[i] = vecTo[i];
for(size_t i=pvTo.getLength(); i< capacity; ++i) temp[i] = T();
for(size_t i=0; i<count; ++i) temp[i*toStride + toOffset] = vecFrom[i*fromStride+fromOffset];
shared_vector<const T> temp2(freeze(temp));
pvTo.replace(temp2);
}
@@ -46,9 +51,11 @@ void copy(
void copy(
PVScalarArray & from,
size_t fromOffset,
size_t fromStride,
PVScalarArray & to,
size_t toOffset,
size_t len)
size_t toStride,
size_t count)
{
ScalarType scalarType = from.getScalarArray()->getElementType();
ScalarType otherType = to.getScalarArray()->getElementType();
@@ -59,145 +66,210 @@ void copy(
{
case pvBoolean:
{
copy(dynamic_cast<PVValueArray<boolean> &>(from),fromOffset,
copy(dynamic_cast<PVValueArray<boolean> &>(from),fromOffset,fromStride,
dynamic_cast<PVValueArray<boolean>& >(to),
toOffset,len);
toOffset,toStride,count);
}
break;
case pvByte:
{
copy(dynamic_cast<PVValueArray<int8> &>(from),fromOffset,
copy(dynamic_cast<PVValueArray<int8> &>(from),fromOffset,fromStride,
dynamic_cast<PVValueArray<int8>& >(to),
toOffset,len);
toOffset,toStride,count);
}
break;
case pvShort:
{
copy(dynamic_cast<PVValueArray<int16> &>(from),fromOffset,
copy(dynamic_cast<PVValueArray<int16> &>(from),fromOffset,fromStride,
dynamic_cast<PVValueArray<int16>& >(to),
toOffset,len);
toOffset,toStride,count);
}
break;
case pvInt:
{
copy(dynamic_cast<PVValueArray<int32> &>(from),fromOffset,
copy(dynamic_cast<PVValueArray<int32> &>(from),fromOffset,fromStride,
dynamic_cast<PVValueArray<int32>& >(to),
toOffset,len);
toOffset,toStride,count);
}
break;
case pvLong:
{
copy(dynamic_cast<PVValueArray<int64> &>(from),fromOffset,
copy(dynamic_cast<PVValueArray<int64> &>(from),fromOffset,fromStride,
dynamic_cast<PVValueArray<int64>& >(to),
toOffset,len);
toOffset,toStride,count);
}
break;
case pvUByte:
{
copy(dynamic_cast<PVValueArray<uint8> &>(from),fromOffset,
copy(dynamic_cast<PVValueArray<uint8> &>(from),fromOffset,fromStride,
dynamic_cast<PVValueArray<uint8>& >(to),
toOffset,len);
toOffset,toStride,count);
}
break;
case pvUShort:
{
copy(dynamic_cast<PVValueArray<uint16> &>(from),fromOffset,
copy(dynamic_cast<PVValueArray<uint16> &>(from),fromOffset,fromStride,
dynamic_cast<PVValueArray<uint16>& >(to),
toOffset,len);
toOffset,toStride,count);
}
break;
case pvUInt:
{
copy(dynamic_cast<PVValueArray<uint32> &>(from),fromOffset,
copy(dynamic_cast<PVValueArray<uint32> &>(from),fromOffset,fromStride,
dynamic_cast<PVValueArray<uint32>& >(to),
toOffset,len);
toOffset,toStride,count);
}
break;
case pvULong:
{
copy(dynamic_cast<PVValueArray<uint64> &>(from),fromOffset,
copy(dynamic_cast<PVValueArray<uint64> &>(from),fromOffset,fromStride,
dynamic_cast<PVValueArray<uint64>& >(to),
toOffset,len);
toOffset,toStride,count);
}
break;
case pvFloat:
{
copy(dynamic_cast<PVValueArray<float> &>(from),fromOffset,
copy(dynamic_cast<PVValueArray<float> &>(from),fromOffset,fromStride,
dynamic_cast<PVValueArray<float>& >(to),
toOffset,len);
toOffset,toStride,count);
}
break;
case pvDouble:
{
copy(dynamic_cast<PVValueArray<double> &>(from),fromOffset,
copy(dynamic_cast<PVValueArray<double> &>(from),fromOffset,fromStride,
dynamic_cast<PVValueArray<double>& >(to),
toOffset,len);
toOffset,toStride,count);
}
break;
case pvString:
{
copy(dynamic_cast<PVValueArray<String> &>(from),fromOffset,
dynamic_cast<PVValueArray<String>& >(to),
toOffset,len);
copy(dynamic_cast<PVValueArray<string> &>(from),fromOffset,fromStride,
dynamic_cast<PVValueArray<string>& >(to),
toOffset,toStride,count);
}
break;
}
}
void copy(
PVStructureArray & from,
size_t fromOffset,
PVStructureArray & to,
PVStructureArray & pvFrom,
size_t pvFromOffset,
size_t pvFromStride,
PVStructureArray & pvTo,
size_t toOffset,
size_t len)
size_t toStride,
size_t count)
{
if(to.isImmutable()) {
throw std::logic_error("pvSubArrayCopy to is immutable");
if(pvTo.isImmutable()) {
throw std::logic_error("pvSubArrayCopy pvTo is immutable");
}
StructureArrayConstPtr fromStructure = from.getStructureArray();
StructureArrayConstPtr toStructure = to.getStructureArray();
if(fromStructure!=toStructure) {
if(pvFromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1");
StructureArrayConstPtr pvFromStructure = pvFrom.getStructureArray();
StructureArrayConstPtr toStructure = pvTo.getStructureArray();
if(pvFromStructure->getStructure()!=toStructure->getStructure()) {
throw std::invalid_argument(
"pvSubArrayCopy structureArray to and from have different structures");
"pvSubArrayCopy structureArray pvTo and pvFrom have different structures");
}
size_t fromLength = from.getLength();
if(fromOffset+len>fromLength) {
throw std::length_error("pvSubArrayCopy from length error");
}
size_t capacity = to.getCapacity();
if(toOffset+len>capacity) capacity = toOffset+len;
size_t pvFromLength = pvFrom.getLength();
size_t maxcount = (pvFromLength -pvFromOffset + pvFromStride -1)/pvFromStride;
if(count>maxcount) throw std::invalid_argument("pvSubArrayCopy pvFrom length error");
size_t newLength = toOffset + count*toStride;
size_t capacity = pvTo.getCapacity();
if(newLength>capacity) capacity = newLength;
shared_vector<PVStructurePtr> temp(capacity);
PVValueArray<PVStructurePtr>::const_svector vecFrom = from.view();
PVValueArray<PVStructurePtr>::const_svector vecTo = to.view();
for(size_t i=0; i<toOffset; ++i) temp[i] = vecTo[i];
for(size_t i=0; i<len; ++i) temp[i + toOffset] = vecFrom[i + fromOffset];
for(size_t i=len + toOffset; i<capacity; ++i) temp[i] = vecTo[i];
PVValueArray<PVStructurePtr>::const_svector vecFrom = pvFrom.view();
PVValueArray<PVStructurePtr>::const_svector vecTo = pvTo.view();
for(size_t i=0; i<pvTo.getLength(); ++i) temp[i] = vecTo[i];
for(size_t i=pvTo.getLength(); i< capacity; ++i)
temp[i] = getPVDataCreate()->createPVStructure(toStructure->getStructure());
for(size_t i=0; i<count; ++i) temp[i*toStride + toOffset] = vecFrom[i*pvFromStride+pvFromOffset];
shared_vector<const PVStructurePtr> temp2(freeze(temp));
to.replace(temp2);
pvTo.replace(temp2);
}
void copy(
PVArray & from,
size_t fromOffset,
PVArray & to,
PVUnionArray & pvFrom,
size_t pvFromOffset,
size_t pvFromStride,
PVUnionArray & pvTo,
size_t toOffset,
size_t len)
size_t toStride,
size_t count)
{
Type type = from.getField()->getType();
Type otherType = to.getField()->getType();
if(type!=otherType) {
throw std::invalid_argument("pvSubArrayCopy types do not match");
if(pvTo.isImmutable()) {
throw std::logic_error("pvSubArrayCopy pvTo is immutable");
}
if(type==scalarArray) {
copy(dynamic_cast<PVScalarArray &>(from) ,fromOffset,
dynamic_cast<PVScalarArray&>(to),
toOffset,len);
if(pvFromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1");
UnionArrayConstPtr pvFromUnion = pvFrom.getUnionArray();
UnionArrayConstPtr toUnion = pvTo.getUnionArray();
if(pvFromUnion->getUnion()!=toUnion->getUnion()) {
throw std::invalid_argument(
"pvSubArrayCopy unionArray pvTo and pvFrom have different unions");
}
if(type==structureArray) {
copy(dynamic_cast<PVStructureArray &>(from) ,fromOffset,
dynamic_cast<PVStructureArray&>(to),
toOffset,len);
size_t pvFromLength = pvFrom.getLength();
size_t maxcount = (pvFromLength -pvFromOffset + pvFromStride -1)/pvFromStride;
if(count>maxcount) throw std::invalid_argument("pvSubArrayCopy pvFrom length error");
size_t newLength = toOffset + count*toStride;
size_t capacity = pvTo.getCapacity();
if(newLength>capacity) capacity = newLength;
shared_vector<PVUnionPtr> temp(capacity);
PVValueArray<PVUnionPtr>::const_svector vecFrom = pvFrom.view();
PVValueArray<PVUnionPtr>::const_svector vecTo = pvTo.view();
for(size_t i=0; i<pvTo.getLength(); ++i) temp[i] = vecTo[i];
for(size_t i=pvTo.getLength(); i< capacity; ++i)
temp[i] = getPVDataCreate()->createPVUnion(toUnion->getUnion());
for(size_t i=0; i<count; ++i) temp[i*toStride + toOffset] = vecFrom[i*pvFromStride+pvFromOffset];
shared_vector<const PVUnionPtr> temp2(freeze(temp));
pvTo.replace(temp2);
}
void copy(
PVArray & pvFrom,
size_t pvFromOffset,
size_t pvFromStride,
PVArray & pvTo,
size_t pvToOffset,
size_t pvToStride,
size_t count)
{
Type pvFromType = pvFrom.getField()->getType();
Type pvToType = pvTo.getField()->getType();
if(pvFromType!=pvToType) throw std::invalid_argument("pvSubArrayCopy: pvFrom and pvTo different types");
if(pvFromType==scalarArray) {
ScalarType pvFromScalarType= static_cast<ScalarType>(pvFromType);
ScalarType pvToScalarType = static_cast<ScalarType>(pvToType);
if(pvFromScalarType!=pvToScalarType){
throw std::invalid_argument("pvSubArrayCopy: pvFrom and pvTo different types");
}
}
if(pvTo.isImmutable()) throw std::invalid_argument("pvSubArrayCopy: pvTo is immutable");
if(pvFromType==scalarArray) {
copy(dynamic_cast<PVScalarArray &>(pvFrom) ,pvFromOffset,pvFromStride,
dynamic_cast<PVScalarArray&>(pvTo),
pvToOffset,pvToStride,count);
}
if(pvFromType==structureArray) {
copy(dynamic_cast<PVStructureArray &>(pvFrom) ,pvFromOffset,pvFromStride,
dynamic_cast<PVStructureArray&>(pvTo),
pvToOffset,pvToStride,count);
}
if(pvFromType==unionArray) {
copy(dynamic_cast<PVUnionArray &>(pvFrom) ,pvFromOffset,pvFromStride,
dynamic_cast<PVUnionArray&>(pvTo),
pvToOffset,pvToStride,count);
}
}
void copy(
PVArray::shared_pointer const & pvFrom,
size_t pvFromOffset,
size_t pvFromStride,
PVArray::shared_pointer & pvTo,
size_t pvToOffset,
size_t pvToStride,
size_t count)
{
copy(*pvFrom,pvFromOffset,pvFromStride,*pvTo,pvToOffset,pvToStride,count);
}
}}

View File

@@ -309,21 +309,6 @@ namespace epics { namespace pvData {
return !(*this == set);
}
void BitSet::toString(StringBuilder buffer, int /*indentLevel*/) const
{
*buffer += '{';
int32 i = nextSetBit(0);
char tmp[30];
if (i != -1) {
sprintf(tmp,"%d",(int)i); *buffer += tmp;
for (i = nextSetBit(i+1); i >= 0; i = nextSetBit(i+1)) {
int32 endOfRun = nextClearBit(i);
do { *buffer += ", "; sprintf(tmp,"%d",(int)i); *buffer += tmp; } while (++i < endOfRun);
}
}
*buffer += '}';
}
void BitSet::serialize(ByteBuffer* buffer, SerializableControl* flusher) const {
uint32 n = wordsInUse;
@@ -374,5 +359,20 @@ namespace epics { namespace pvData {
words[i] |= (buffer->getByte() & 0xffL) << (8 * j);
}
epicsShareExtern std::ostream& operator<<(std::ostream& o, const BitSet& b)
{
o << '{';
int32 i = b.nextSetBit(0);
if (i != -1) {
o << i;
for (i = b.nextSetBit(i+1); i >= 0; i = b.nextSetBit(i+1)) {
int32 endOfRun = b.nextClearBit(i);
do { o << ", " << i; } while (++i < endOfRun);
}
}
o << '}';
return o;
}
}};

View File

@@ -225,8 +225,6 @@ namespace epics { namespace pvData {
bool operator!=(const BitSet &set) const;
void toString(StringBuilder buffer, int indentLevel = 0) const;
virtual void serialize(ByteBuffer *buffer,
SerializableControl *flusher) const;
virtual void deserialize(ByteBuffer *buffer,
@@ -317,6 +315,8 @@ namespace epics { namespace pvData {
static uint32 bitCount(uint64 i);
};
epicsShareExtern std::ostream& operator<<(std::ostream& o, const BitSet& b);
}}
#endif /* BITSET_H */

View File

@@ -10,10 +10,12 @@
#include <sstream>
#include <cstdio>
#include <cstring>
#include <string>
#define epicsExportSharedSymbols
#include <pv/epicsException.h>
using std::string;
namespace epics{ namespace pvData {
@@ -32,7 +34,7 @@ ExceptionMixin::print(FILE *fp) const
#endif
}
std::string
string
ExceptionMixin::show() const
{
std::ostringstream out;
@@ -62,7 +64,7 @@ BaseException::what() const throw()
try{
if (base_msg.size()==0) {
const char *base=std::logic_error::what();
std::string out, stack;
string out, stack;
const ExceptionMixin *info=dynamic_cast<const ExceptionMixin*>(this);
if(info) {

View File

@@ -26,6 +26,8 @@
#include <pv/lock.h>
#include <pv/event.h>
using std::string;
namespace epics { namespace pvData {
@@ -43,27 +45,27 @@ Event::Event(bool full)
void Event::signal()
{
if(id==0) throw std::logic_error(String("event was deleted"));
if(id==0) throw std::logic_error(string("event was deleted"));
epicsEventSignal(id);
}
bool Event::wait ()
{
if(id==0) throw std::logic_error(String("event was deleted"));
if(id==0) throw std::logic_error(string("event was deleted"));
epicsEventWaitStatus status = epicsEventWait(id);
return status==epicsEventWaitOK ? true : false;
}
bool Event::wait ( double timeOut )
{
if(id==0) throw std::logic_error(String("event was deleted"));
if(id==0) throw std::logic_error(string("event was deleted"));
epicsEventWaitStatus status = epicsEventWaitWithTimeout(id,timeOut);
return status==epicsEventWaitOK ? true : false;
}
bool Event::tryWait ()
{
if(id==0) throw std::logic_error(String("event was deleted"));
if(id==0) throw std::logic_error(string("event was deleted"));
epicsEventWaitStatus status = epicsEventTryWait(id);
return status==epicsEventWaitOK ? true : false;
}

View File

@@ -46,7 +46,7 @@ public:
bool tryWait (); /* false if empty */
private:
epicsEventId id;
String alreadyOn;
std::string alreadyOn;
};
}}

View File

@@ -16,6 +16,8 @@
#define epicsExportSharedSymbols
#include <pv/executor.h>
using std::string;
namespace epics { namespace pvData {
// special instance to stop the executor thread
@@ -31,7 +33,7 @@ static
std::tr1::shared_ptr<Command> shutdown(new ExecutorShutdown());
Executor::Executor(String threadName,ThreadPriority priority)
Executor::Executor(string const & threadName,ThreadPriority priority)
: thread(threadName,priority,this)
{
}

View File

@@ -40,7 +40,7 @@ private:
class epicsShareClass Executor : public Runnable{
public:
POINTER_DEFINITIONS(Executor);
Executor(String threadName,ThreadPriority priority);
Executor(std::string const & threadName,ThreadPriority priority);
~Executor();
void execute(CommandPtr const &node);
virtual void run();

View File

@@ -12,13 +12,15 @@
#define epicsExportSharedSymbols
#include <pv/messageQueue.h>
using std::string;
namespace epics { namespace pvData {
MessageNode::MessageNode()
: messageType(infoMessage)
{}
String MessageNode::getMessage() const
string MessageNode::getMessage() const
{
return message;
}
@@ -59,7 +61,7 @@ void MessageQueue::release() {
releaseUsed(lastGet);
lastGet.reset();
}
bool MessageQueue::put(String message,MessageType messageType,bool replaceLast)
bool MessageQueue::put(string message,MessageType messageType,bool replaceLast)
{
MessageNodePtr node = getFree();
if(node.get()!= NULL) {

View File

@@ -31,10 +31,10 @@ typedef std::tr1::shared_ptr<MessageQueue> MessageQueuePtr;
class epicsShareClass MessageNode {
public:
MessageNode();
String getMessage() const;
std::string getMessage() const;
MessageType getMessageType() const;
private:
String message;
std::string message;
MessageType messageType;
friend class MessageQueue;
};
@@ -49,7 +49,7 @@ public:
// must call release before next get
void release();
// return (false,true) if message (was not, was) put into queue
bool put(String message,MessageType messageType,bool replaceLast);
bool put(std::string message,MessageType messageType,bool replaceLast);
bool isEmpty() ;
bool isFull() ;
int getClearOverrun();

View File

@@ -14,6 +14,8 @@
#define epicsExportSharedSymbols
#include "typeCast.h"
using std::string;
// need to use "long long" when sizeof(int)==sizeof(long)
#if (ULONG_MAX == 0xfffffffful) || defined(_WIN32) || defined(__rtems__)
#define NEED_LONGLONG
@@ -422,18 +424,18 @@ void handleParseError(int err)
namespace epics { namespace pvData { namespace detail {
void parseToPOD(const std::string & in, boolean *out)
void parseToPOD(const string & in, boolean *out)
{
if(epicsStrCaseCmp(in.c_str(),"true")==0)
*out = 1;
else if(epicsStrCaseCmp(in.c_str(),"false")==0)
*out = 0;
else
throw std::runtime_error("parseToPOD: String no match true/false");
throw std::runtime_error("parseToPOD: string no match true/false");
}
#define INTFN(T, S) \
void parseToPOD(const std::string& in, T *out) { \
void parseToPOD(const string& in, T *out) { \
epics ## S temp; \
int err = epicsParse ## S (in.c_str(), &temp, 0, NULL); \
if(err) handleParseError(err); \
@@ -447,7 +449,7 @@ INTFN(uint16_t, UInt16);
INTFN(int32_t, Int32);
INTFN(uint32_t, UInt32);
void parseToPOD(const std::string& in, int64_t *out) {
void parseToPOD(const string& in, int64_t *out) {
#ifdef NEED_LONGLONG
int err = epicsParseLongLong(in.c_str(), out, 0, NULL);
#else
@@ -456,7 +458,7 @@ void parseToPOD(const std::string& in, int64_t *out) {
if(err) handleParseError(err);
}
void parseToPOD(const std::string& in, uint64_t *out) {
void parseToPOD(const string& in, uint64_t *out) {
#ifdef NEED_LONGLONG
int err = epicsParseULongLong(in.c_str(), out, 0, NULL);
#else
@@ -465,12 +467,12 @@ void parseToPOD(const std::string& in, uint64_t *out) {
if(err) handleParseError(err);
}
void parseToPOD(const std::string& in, float *out) {
void parseToPOD(const string& in, float *out) {
int err = epicsParseFloat(in.c_str(), out, NULL);
if(err) handleParseError(err);
}
void parseToPOD(const std::string& in, double *out) {
void parseToPOD(const string& in, double *out) {
int err = epicsParseDouble(in.c_str(), out, NULL);
if(err) handleParseError(err);
}

View File

@@ -14,11 +14,13 @@
#include <pv/lock.h>
#include <pv/requester.h>
using std::string;
namespace epics { namespace pvData {
static StringArray messageTypeName(MESSAGE_TYPE_COUNT);
String getMessageTypeName(MessageType messageType)
string getMessageTypeName(MessageType messageType)
{
// TODO not thread-safe
static Mutex mutex;

View File

@@ -26,14 +26,14 @@ enum MessageType {
};
#define MESSAGE_TYPE_COUNT 4
epicsShareExtern String getMessageTypeName(MessageType messageType);
epicsShareExtern std::string getMessageTypeName(MessageType messageType);
class epicsShareClass Requester {
public:
POINTER_DEFINITIONS(Requester);
virtual ~Requester(){}
virtual String getRequesterName() = 0;
virtual void message(String const & message,MessageType messageType) = 0;
virtual std::string getRequesterName() = 0;
virtual void message(std::string const & message,MessageType messageType) = 0;
};
}}

View File

@@ -57,7 +57,7 @@ namespace epics {
return (std::size_t)(b<0 ? b+256 : b);
}
void SerializeHelper::serializeString(const String& value,
void SerializeHelper::serializeString(const string& value,
ByteBuffer* buffer, SerializableControl* flusher) {
std::size_t len = value.length();
SerializeHelper::writeSize(len, buffer, flusher);
@@ -74,7 +74,7 @@ namespace epics {
}
}
void SerializeHelper::serializeSubstring(const String& value,
void SerializeHelper::serializeSubstring(const string& value,
std::size_t offset, std::size_t count, ByteBuffer* buffer,
SerializableControl* flusher) {
/*if(offset<0)
@@ -97,9 +97,9 @@ namespace epics {
}
}
static String emptyString;
static string emptyStringtring;
String SerializeHelper::deserializeString(ByteBuffer* buffer,
string SerializeHelper::deserializeString(ByteBuffer* buffer,
DeserializableControl* control) {
std::size_t size = SerializeHelper::readSize(buffer, control);
@@ -109,13 +109,13 @@ namespace epics {
{
// entire string is in buffer, simply create a string out of it (copy)
std::size_t pos = buffer->getPosition();
String str(buffer->getArray()+pos, size);
string str(buffer->getArray()+pos, size);
buffer->setPosition(pos+size);
return str;
}
else
{
String str;
string str;
str.reserve(size);
try {
std::size_t i = 0;
@@ -137,7 +137,7 @@ namespace epics {
}
}
else
return emptyString;
return emptyStringtring;
}
}

View File

@@ -46,30 +46,30 @@ namespace epics {
DeserializableControl* control);
/**
* String serialization helper method.
* std::string serialization helper method.
*
* @param[in] value String to serialize
* @param[in] value std::string to serialize
* @param[in] buffer serialization buffer
* @param[in] flusher flusher
*/
static void serializeString(const String& value, ByteBuffer* buffer,
static void serializeString(const std::string& value, ByteBuffer* buffer,
SerializableControl* flusher);
/**
* String serialization helper method.
* std::string serialization helper method.
*
* @param[in] value String to serialize
* @param[in] value std::string to serialize
* @param[in] offset start of the substring in {@code value}
* @param[in] count the number of characters to write
* @param[in] buffer serialization buffer
* @param[in] flusher flusher
*/
static void serializeSubstring(const String& value, std::size_t offset,
static void serializeSubstring(const std::string& value, std::size_t offset,
std::size_t count, ByteBuffer* buffer,
SerializableControl* flusher);
/**
* String deserialization helper method.
* std::string deserialization helper method.
* TODO This method cannot return "null", but Java implementation
* could have serialized "null" value as well. We need to decide
* how to deserialize "null".
@@ -82,7 +82,7 @@ namespace epics {
* could have serialized "null" value as well. We need to decide
* how to deserialize "null".
*/
static String deserializeString(ByteBuffer* buffer,
static std::string deserializeString(ByteBuffer* buffer,
DeserializableControl* control);
private:

View File

@@ -12,10 +12,12 @@
#include <pv/serializeHelper.h>
#include <pv/status.h>
using std::string;
namespace epics { namespace pvData {
const char* Status::StatusTypeName[] = { "OK", "WARNING", "ERROR", "FATAL" };
epics::pvData::String Status::m_emptyString;
string Status::m_emptyStringtring;
Status Status::Ok;
@@ -26,7 +28,7 @@ Status::Status() :
{
}
Status::Status(StatusType type, String const & message) :
Status::Status(StatusType type, string const & message) :
m_statusType(type), m_message(message)
{
if (type == STATUSTYPE_OK)
@@ -35,7 +37,7 @@ Status::Status(StatusType type, String const & message) :
//PVDATA_REFCOUNT_MONITOR_CONSTRUCT(status);
}
Status::Status(StatusType type, String const & message, String const & stackDump) :
Status::Status(StatusType type, string const & message, string const & stackDump) :
m_statusType(type), m_message(message), m_stackDump(stackDump)
{
if (type == STATUSTYPE_OK)
@@ -54,12 +56,12 @@ Status::StatusType Status::getType() const
}
epics::pvData::String Status::getMessage() const
string Status::getMessage() const
{
return m_message;
}
epics::pvData::String Status::getStackDump() const
string Status::getStackDump() const
{
return m_stackDump;
}
@@ -100,7 +102,7 @@ void Status::deserialize(ByteBuffer *buffer, DeserializableControl *flusher)
if (m_statusType != STATUSTYPE_OK)
{
m_statusType = STATUSTYPE_OK;
m_message = m_stackDump = m_emptyString;
m_message = m_stackDump = m_emptyStringtring;
}
}
else
@@ -111,29 +113,26 @@ void Status::deserialize(ByteBuffer *buffer, DeserializableControl *flusher)
}
}
String Status::toString() const
void Status::dump(std::ostream& o) const
{
String str;
toString(&str, 0);
return str;
o << "Status [type=" << Status::StatusTypeName[m_statusType];
if (!m_message.empty())
o << ", message=" << m_message;
if (!m_stackDump.empty())
o << ", stackDump=" << std::endl << m_stackDump;
o << ']';
}
std::ostream& operator<<(std::ostream& o, const Status& status)
{
status.dump(o);
return o;
}
void Status::toString(StringBuilder buffer, int /*indentLevel*/) const
std::ostream& operator<<(std::ostream& o, const Status::StatusType& statusType)
{
*buffer += "Status [type=";
*buffer += StatusTypeName[m_statusType];
if (!m_message.empty())
{
*buffer += ", message=";
*buffer += m_message;
}
if (!m_stackDump.empty())
{
*buffer += ", stackDump=";
*buffer += '\n';
*buffer += m_stackDump;
}
*buffer += ']';
o << Status::StatusTypeName[statusType];
return o;
}
}}

View File

@@ -10,6 +10,8 @@
#ifndef STATUS_H
#define STATUS_H
#include <ostream>
#include <pv/serialize.h>
#include <pv/byteBuffer.h>
#include <pv/sharedPtr.h>
@@ -51,12 +53,12 @@ namespace epics { namespace pvData {
/**
* Create non-OK status.
*/
Status(StatusType type, epics::pvData::String const & message);
Status(StatusType type, std::string const & message);
/**
* Create non-OK status.
*/
Status(StatusType type, epics::pvData::String const & message, epics::pvData::String const & stackDump);
Status(StatusType type, std::string const & message, std::string const & stackDump);
~Status();
@@ -70,13 +72,13 @@ namespace epics { namespace pvData {
* Get error message describing an error. Required if error status.
* @return error message.
*/
epics::pvData::String getMessage() const;
std::string getMessage() const;
/**
* Get stack dump where error (exception) happened. Optional.
* @return stack dump.
*/
epics::pvData::String getStackDump() const;
std::string getStackDump() const;
/**
* Convenient OK test. Same as <code>(getType() == StatusType.OK)</code>.
@@ -93,20 +95,23 @@ namespace epics { namespace pvData {
*/
bool isSuccess() const;
String toString() const;
void toString(StringBuilder buffer, int indentLevel = 0) const;
void serialize(ByteBuffer *buffer, SerializableControl *flusher) const;
void deserialize(ByteBuffer *buffer, DeserializableControl *flusher);
void dump(std::ostream& o) const;
private:
static epics::pvData::String m_emptyString;
static std::string m_emptyStringtring;
StatusType m_statusType;
String m_message;
String m_stackDump;
std::string m_message;
std::string m_stackDump;
};
epicsShareExtern std::ostream& operator<<(std::ostream& o, const Status& status);
epicsShareExtern std::ostream& operator<<(std::ostream& o, const Status::StatusType& statusType);
}}
#endif /* STATUS_H */

View File

@@ -50,7 +50,7 @@ typedef epicsThreadRunable Runnable;
class epicsShareClass Thread : public epicsThread, private NoDefaultMethods {
public:
Thread(String name,
Thread(std::string name,
ThreadPriority priority,
Runnable *runnable,
epicsThreadStackSizeClass stkcls=epicsThreadStackSmall)
@@ -63,7 +63,7 @@ public:
}
Thread(Runnable &runnable,
String name,
std::string name,
unsigned int stksize,
unsigned int priority=lowestPriority)
:epicsThread(runnable,

View File

@@ -13,11 +13,14 @@
#endif
#include <stdexcept>
#include <string>
#define epicsExportSharedSymbols
#include <pv/convert.h>
#include <pv/timer.h>
using std::string;
namespace epics { namespace pvData {
TimerCallback::TimerCallback()
@@ -26,7 +29,7 @@ TimerCallback::TimerCallback()
{
}
Timer::Timer(String threadName,ThreadPriority priority)
Timer::Timer(string threadName,ThreadPriority priority)
: waitForWork(false),
waitForDone(false),
alive(true),
@@ -84,7 +87,7 @@ void Timer::cancel(TimerCallbackPtr const &timerCallback)
prevNode = nextNode;
nextNode = nextNode->next;
}
throw std::logic_error(String(""));
throw std::logic_error(string(""));
}
bool Timer::isScheduled(TimerCallbackPtr const &timerCallback)
@@ -169,7 +172,7 @@ void Timer::schedulePeriodic(
double period)
{
if(isScheduled(timerCallback)) {
throw std::logic_error(String("already queued"));
throw std::logic_error(string("already queued"));
}
{
Lock xx(mutex);
@@ -193,7 +196,7 @@ void Timer::schedulePeriodic(
if(isFirst) waitForWork.signal();
}
void Timer::toString(StringBuilder builder)
void Timer::dump(std::ostream& o)
{
Lock xx(mutex);
if(!alive) return;
@@ -205,11 +208,15 @@ void Timer::toString(StringBuilder builder)
TimeStamp timeToRun = nodeToCall->timeToRun;
double period = nodeToCall->period;
double diff = TimeStamp::diff(timeToRun,currentTime);
char buffer[50];
sprintf(buffer,"timeToRun %f period %f\n",diff,period);
*builder += buffer;
o << "timeToRun " << diff << " period " << period << std::endl;
nodeToCall = nodeToCall->next;
}
}
std::ostream& operator<<(std::ostream& o, Timer& timer)
{
timer.dump(o);
return o;
}
}}

View File

@@ -50,7 +50,7 @@ private:
class epicsShareClass Timer : public Runnable {
public:
POINTER_DEFINITIONS(Timer);
Timer(String threadName, ThreadPriority priority);
Timer(std::string threadName, ThreadPriority priority);
virtual ~Timer();
virtual void run();
void scheduleAfterDelay(
@@ -62,7 +62,9 @@ public:
double period);
void cancel(TimerCallbackPtr const &timerCallback);
bool isScheduled(TimerCallbackPtr const &timerCallback);
void toString(StringBuilder builder);
void dump(std::ostream& o);
private:
void addElement(TimerCallbackPtr const &timerCallback);
TimerCallbackPtr head;
@@ -73,5 +75,7 @@ private:
Thread thread;
};
epicsShareExtern std::ostream& operator<<(std::ostream& o, Timer& timer);
}}
#endif /* TIMER_H */

View File

@@ -11,9 +11,9 @@
#include "typeCast.h"
using epics::pvData::castUnsafe;
using epics::pvData::String;
using epics::pvData::ScalarType;
using epics::pvData::pvString;
using std::string;
namespace {
@@ -77,7 +77,7 @@ static convertfn converters[pvString+1][pvString+1] =
&noconvert,
&noconvert,
&noconvert,
&castVTyped<epics::pvData::boolean, String>,
&castVTyped<epics::pvData::boolean, string>,
},
// to pvByte
{&noconvert,
@@ -91,7 +91,7 @@ static convertfn converters[pvString+1][pvString+1] =
&castVTyped<int8_t, uint64_t>,
&castVTyped<int8_t, float>,
&castVTyped<int8_t, double>,
&castVTyped<int8_t, String>,
&castVTyped<int8_t, string>,
},
// to pvShort
{&noconvert,
@@ -105,7 +105,7 @@ static convertfn converters[pvString+1][pvString+1] =
&castVTyped<int16_t, uint64_t>,
&castVTyped<int16_t, float>,
&castVTyped<int16_t, double>,
&castVTyped<int16_t, String>,
&castVTyped<int16_t, string>,
},
// to pvInt
{&noconvert,
@@ -119,7 +119,7 @@ static convertfn converters[pvString+1][pvString+1] =
&castVTyped<int32_t, uint64_t>,
&castVTyped<int32_t, float>,
&castVTyped<int32_t, double>,
&castVTyped<int32_t, String>,
&castVTyped<int32_t, string>,
},
// to pvLong
{&noconvert,
@@ -133,7 +133,7 @@ static convertfn converters[pvString+1][pvString+1] =
&castVTyped<int64_t, uint64_t>,
&castVTyped<int64_t, float>,
&castVTyped<int64_t, double>,
&castVTyped<int64_t, String>,
&castVTyped<int64_t, string>,
},
// to pvUByte
{&noconvert,
@@ -147,7 +147,7 @@ static convertfn converters[pvString+1][pvString+1] =
&castVTyped<uint8_t, uint64_t>,
&castVTyped<uint8_t, float>,
&castVTyped<uint8_t, double>,
&castVTyped<uint8_t, String>,
&castVTyped<uint8_t, string>,
},
// to pvUShort
{&noconvert,
@@ -161,7 +161,7 @@ static convertfn converters[pvString+1][pvString+1] =
&castVTyped<uint16_t, uint64_t>,
&castVTyped<uint16_t, float>,
&castVTyped<uint16_t, double>,
&castVTyped<uint16_t, String>,
&castVTyped<uint16_t, string>,
},
// to pvUInt
{&noconvert,
@@ -175,7 +175,7 @@ static convertfn converters[pvString+1][pvString+1] =
&castVTyped<uint32_t, uint64_t>,
&castVTyped<uint32_t, float>,
&castVTyped<uint32_t, double>,
&castVTyped<uint32_t, String>,
&castVTyped<uint32_t, string>,
},
// to pvULong
{&noconvert,
@@ -189,7 +189,7 @@ static convertfn converters[pvString+1][pvString+1] =
&copyV<uint64_t>,
&castVTyped<uint64_t, float>,
&castVTyped<uint64_t, double>,
&castVTyped<uint64_t, String>,
&castVTyped<uint64_t, string>,
},
// to pvFloat
{&noconvert,
@@ -203,7 +203,7 @@ static convertfn converters[pvString+1][pvString+1] =
&castVTyped<float, uint64_t>,
&copyV<float>,
&castVTyped<float, double>,
&castVTyped<float, String>,
&castVTyped<float, string>,
},
// to pvDouble
{&noconvert,
@@ -217,21 +217,21 @@ static convertfn converters[pvString+1][pvString+1] =
&castVTyped<double, uint64_t>,
&castVTyped<double, float>,
&copyV<double>,
&castVTyped<double, String>,
&castVTyped<double, string>,
},
// to pvString
{&castVTyped<String, epics::pvData::boolean>,
&castVTyped<String, int8_t>,
&castVTyped<String, int16_t>,
&castVTyped<String, int32_t>,
&castVTyped<String, uint64_t>,
&castVTyped<String, uint8_t>,
&castVTyped<String, uint16_t>,
&castVTyped<String, uint32_t>,
&castVTyped<String, uint64_t>,
&castVTyped<String, float>,
&castVTyped<String, double>,
&copyV<String>,
{&castVTyped<string, epics::pvData::boolean>,
&castVTyped<string, int8_t>,
&castVTyped<string, int16_t>,
&castVTyped<string, int32_t>,
&castVTyped<string, uint64_t>,
&castVTyped<string, uint8_t>,
&castVTyped<string, uint16_t>,
&castVTyped<string, uint32_t>,
&castVTyped<string, uint64_t>,
&castVTyped<string, float>,
&castVTyped<string, double>,
&copyV<string>,
},
};

View File

@@ -30,8 +30,6 @@
namespace epics { namespace pvData {
typedef std::string String;
namespace detail {
// parseToPOD wraps the epicsParse*() functions in one name
// and throws exceptions
@@ -48,12 +46,12 @@ namespace detail {
epicsShareExtern void parseToPOD(const std::string&, double *out);
/* want to pass POD types by value,
* and String by const reference
* and std::string by const reference
*/
template<typename ARG>
struct cast_arg { typedef ARG arg; };
template<>
struct cast_arg<String> { typedef const String& arg; };
struct cast_arg<std::string> { typedef const std::string& arg; };
// Handle mangling of type/value when printing
template<typename T>
@@ -98,10 +96,10 @@ namespace detail {
};
// print POD to string
// when String!=FROM
// when std::string!=FROM
template<typename FROM>
struct cast_helper<String, FROM, typename meta::not_same_type<String,FROM>::type> {
static String op(FROM from) {
struct cast_helper<std::string, FROM, typename meta::not_same_type<std::string,FROM>::type> {
static std::string op(FROM from) {
std::ostringstream strm;
strm << print_convolute<FROM>::op(from);
if(strm.fail())
@@ -111,10 +109,10 @@ namespace detail {
};
// parse POD from string
// TO!=String
// TO!=std::string
template<typename TO>
struct cast_helper<TO, String, typename meta::not_same_type<TO,String>::type> {
static FORCE_INLINE TO op(const String& from) {
struct cast_helper<TO, std::string, typename meta::not_same_type<TO,std::string>::type> {
static FORCE_INLINE TO op(const std::string& from) {
TO ret;
parseToPOD(from, &ret);
return ret;
@@ -127,7 +125,7 @@ namespace detail {
*
* Supported types: uint8_t, int8_t, uint16_t, int16_t,
* uint32_t, int32_t, uint64_t, int64_t,
* float, double, String
* float, double, std::string
*
* As defined in pvType.h
*
@@ -153,9 +151,9 @@ namespace detail {
* Conversions where invalid or out of range inputs result
* in an exception.
*
* - non-String -> String
* - String -> non-String
* - String -> String (throws only std::bad_alloc)
* - non-std::string -> std::string
* - std::string -> non-std::string
* - std::string -> std::string (throws only std::bad_alloc)
*
* Conversions where out of range inputs produce undefined
* results.
@@ -169,7 +167,7 @@ namespace detail {
* too large to be represented by the integer type
* is not defined.
*
@section stringf String formats
@section stringf std::string formats
*
* - Numbers beginning with 1-9 are parsed as base-10.
* - Numbers beginning with '0x' are parsed as base-16

View File

@@ -3,6 +3,7 @@
SRC_DIRS += $(PVDATA_SRC)/monitor
INC += monitor.h
INC += monitorPlugin.h
LIBSRCS += monitor.cpp
LIBSRCS += monitorPlugin.cpp

View File

@@ -15,6 +15,7 @@
#include <pv/pvData.h>
#include <pv/sharedPtr.h>
#include <pv/bitSet.h>
#include <pv/requester.h>
#include <shareLib.h>

View File

@@ -0,0 +1,86 @@
/* monitorPlugin.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#define epicsExportSharedSymbols
#include <pv/monitorPlugin.h>
using std::string;
using std::cout;
using std::endl;
namespace epics { namespace pvData {
MonitorPluginManagerPtr MonitorPluginManager::get()
{
static MonitorPluginManagerPtr pluginManager;
static Mutex mutex;
Lock xx(mutex);
if(pluginManager==NULL) {
pluginManager = MonitorPluginManagerPtr(new MonitorPluginManager());
}
return pluginManager;
}
bool MonitorPluginManager::addPlugin(
string const &pluginName,
MonitorPluginCreatorPtr const &creator)
{
mutex.lock();
std::list<MonitorPluginCreatorPtr>::iterator iter;
for (iter = monitorPluginList.begin();iter!=monitorPluginList.end();iter++)
{
if(*iter==creator)
{
mutex.unlock();
return false;
}
if(((*iter)->getName().compare(pluginName))==0)
{
mutex.unlock();
return false;
}
}
monitorPluginList.push_back(creator);
mutex.unlock();
return true;
}
MonitorPluginCreatorPtr MonitorPluginManager::findPlugin(
string const &pluginName)
{
mutex.lock();
std::list<MonitorPluginCreatorPtr>::iterator iter;
for (iter = monitorPluginList.begin();iter!=monitorPluginList.end();++iter)
{
if(((*iter)->getName().compare(pluginName))==0)
{
mutex.unlock();
return *iter;
}
}
mutex.unlock();
return MonitorPluginCreatorPtr();
}
void MonitorPluginManager::showNames()
{
mutex.lock();
std::list<MonitorPluginCreatorPtr>::iterator iter;
for (iter = monitorPluginList.begin();iter!=monitorPluginList.end();++iter)
{
std::cout << (*iter)->getName() << std::endl;
}
mutex.unlock();
}
}}

177
src/monitor/monitorPlugin.h Normal file
View File

@@ -0,0 +1,177 @@
/* monitorPlugin.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#ifndef MONITORPLUGIN_H
#define MONITORPLUGIN_H
#include <list>
#include <pv/pvData.h>
#include <pv/sharedPtr.h>
#include <pv/bitSet.h>
#include <pv/monitor.h>
#include <shareLib.h>
namespace epics { namespace pvData {
/**
* typedef for a pointer to a MonitorPlugin
*/
class MonitorPlugin;
typedef std::tr1::shared_ptr<MonitorPlugin> MonitorPluginPtr;
/**
* typedef for a pointer to a MonitorPluginCreator
*/
class MonitorPluginCreator;
typedef std::tr1::shared_ptr<MonitorPluginCreator> MonitorPluginCreatorPtr;
/**
* typedef for a pointer to a MonitorPluginManager
*/
class MonitorPluginManager;
typedef std::tr1::shared_ptr<MonitorPluginManager> MonitorPluginManagerPtr;
/** A plugin for raising monitors;
* This is for use by pvAccess servers that support monitors.
* Since the interface has only a dependence on pvData it
* can be used for other purposes.
* A monitor is assumed to be associated with a field of a top level
* structure.
*/
class epicsShareClass MonitorPlugin
{
public:
virtual ~MonitorPlugin(){}
/**
* getName
* @returns The name of the plugin
*/
virtual std::string const & getName() = 0;
/**
* Should a monitor be raised?
* @param pvField The field being monitored.
* @param pvTop The top level sructure in which the field resides.
* @param monitorElement The client data and bitSets.
* @returns true or false.
* True is returned if the change to this field should cause a monitor.
* False is returned in a change only to this field should not cause a
* monitor.
*/
virtual bool causeMonitor(
PVFieldPtr const &pvField,
PVStructurePtr const &pvTop,
MonitorElementPtr const &monitorElement) = 0;
/**
* A monitor will be sent to the client.
* @param pvField The copy of the field being monitored.
* The plugin can modify the data.
* @param pvTop The top level sructure in which the field resides.
* @param monitorElement The data for the client.
* The plugin is allowed to change the data values.
*/
virtual void monitorDone(
MonitorElementPtr const &monitorElement)
{}
/**
* Begin monitoring
*/
virtual void startMonitoring(){}
/**
* Stop monitoring
*/
virtual void stopMonitoring(){}
/**
* Begin a set of puts.
*/
virtual void beginGroupPut() {};
/**
* End a set of puts.
*/
virtual void endGroupPut() {};
};
/** A class that creates a plugin.
* Normlly a plugin is created for a single client.
*/
class epicsShareClass MonitorPluginCreator
{
public:
virtual ~MonitorPluginCreator() {}
/**
* Create a monitor plugin.
* @param field The introspection interface for the field monitored.
* @param top The introspsction interface for the client structure.
* @param pvFieldOptions The options the client requested.
* The structure has a set of PVString subfields.
* The options are a set of name,value pairs.
* The subfield name is the name and the subfield value is the value.
* @returns shared pointer to a MonitorPluginCreator.
*/
virtual MonitorPluginPtr create(
FieldConstPtr const &field,
StructureConstPtr const &top,
PVStructurePtr const &pvFieldOptions) = 0;
/**
* getName
* @returns The name of the plugin
*/
virtual std::string const & getName() = 0;
};
/**
* This manages a set of monitor plugins.
* @author mrk
*/
class epicsShareClass MonitorPluginManager
{
public:
POINTER_DEFINITIONS(MonitorPluginManager);
/**
* Factory to get the manager.
* @return shared pointer to manager.
*/
static MonitorPluginManagerPtr get();
/** destructor
*/
~MonitorPluginManager(){}
/* add plugin
* @param pluginName The name of the plugin.
* @param creator The creator.
* @returns true or false
* false is returned if a plugin with that name is already present
*/
bool addPlugin(
std::string const &pluginName,
MonitorPluginCreatorPtr const &creator);
/* find plugin
*
* @param plugin name
* @returns share pointer to plugin creator.
* If a plugin with that name is not found NULL is returned.
*/
MonitorPluginCreatorPtr findPlugin(std::string const &pluginName);
/* showNames
*
*/
void showNames();
private:
MonitorPluginManager(){}
std::list<MonitorPluginCreatorPtr> monitorPluginList;
epics::pvData::Mutex mutex;
};
}}
#endif /* MONITORPLUGIN_H */

View File

@@ -17,12 +17,14 @@
#include <pv/pvData.h>
#include <pv/alarm.h>
using std::string;
namespace epics { namespace pvData {
AlarmSeverity AlarmSeverityFunc::getSeverity(int value)
{
if(value<0 || value>4) {
throw std::logic_error(String("getSeverity value is illegal"));
throw std::logic_error(string("getSeverity value is illegal"));
}
switch (value) {
case 0: return noAlarm;
@@ -31,7 +33,7 @@ AlarmSeverity AlarmSeverityFunc::getSeverity(int value)
case 3: return invalidAlarm;
case 4: return undefinedAlarm;
}
throw std::logic_error(String("should never get here"));
throw std::logic_error(string("should never get here"));
}
StringArrayPtr AlarmSeverityFunc::getSeverityNames()
@@ -61,13 +63,13 @@ AlarmSeverity Alarm::getSeverity() const
case 3: return invalidAlarm;
case 4: return undefinedAlarm;
}
throw std::logic_error(String("should never get here"));
throw std::logic_error(string("should never get here"));
}
AlarmStatus AlarmStatusFunc::getStatus(int value)
{
if(value<0 || value>7) {
throw std::logic_error(String("getStatus value is illegal"));
throw std::logic_error(string("getStatus value is illegal"));
}
switch (value) {
case 0: return noStatus;
@@ -79,7 +81,7 @@ AlarmStatus AlarmStatusFunc::getStatus(int value)
case 6: return undefinedStatus;
case 7: return clientStatus;
}
throw std::logic_error(String("should never get here"));
throw std::logic_error(string("should never get here"));
}
StringArrayPtr AlarmStatusFunc::getStatusNames()
@@ -115,7 +117,7 @@ AlarmStatus Alarm::getStatus() const
case 6: return undefinedStatus;
case 7: return clientStatus;
}
throw std::logic_error(String("should never get here"));
throw std::logic_error(string("should never get here"));
}
}}

View File

@@ -42,10 +42,10 @@ public:
class epicsShareClass Alarm {
public:
Alarm() : severity(0),status(0), message(String("")) {}
Alarm() : severity(0),status(0), message(std::string("")) {}
//default constructors and destructor are OK
String getMessage() const {return message;}
void setMessage(String const &value) {message = value;}
std::string getMessage() const {return message;}
void setMessage(std::string const &value) {message = value;}
AlarmSeverity getSeverity() const;
void setSeverity(AlarmSeverity value) {severity = value;}
AlarmStatus getStatus() const;
@@ -53,7 +53,7 @@ public:
private:
int32 severity;
int32 status;
String message;
std::string message;
};
}}

View File

@@ -22,23 +22,23 @@ namespace epics { namespace pvData {
class epicsShareClass Display {
public:
Display()
: description(String("")),format(String("")),units(String("")),
: description(std::string("")),format(std::string("")),units(std::string("")),
low(0.0),high(0.0) {}
//default constructors and destructor are OK
double getLow() const {return low;}
double getHigh() const{ return high;}
void setLow(double value){low = value;}
void setHigh(double value){high = value;}
String getDescription() const {return description;}
void setDescription(String const & value) {description = value;}
String getFormat() const {return format;}
void setFormat(String const & value) {format = value;}
String getUnits() const {return units;}
void setUnits(String const & value) {units = value;}
std::string getDescription() const {return description;}
void setDescription(std::string const & value) {description = value;}
std::string getFormat() const {return format;}
void setFormat(std::string const & value) {format = value;}
std::string getUnits() const {return units;}
void setUnits(std::string const & value) {units = value;}
private:
String description;
String format;
String units;
std::string description;
std::string format;
std::string units;
double low;
double high;
};

View File

@@ -16,34 +16,27 @@
#include <pv/pvData.h>
#include <pv/pvAlarm.h>
using std::tr1::static_pointer_cast;
using std::string;
namespace epics { namespace pvData {
using std::tr1::static_pointer_cast;
String PVAlarm::noAlarmFound("No alarm structure found");
String PVAlarm::notAttached("Not attached to an alarm structure");
string PVAlarm::noAlarmFound("No alarm structure found");
string PVAlarm::notAttached("Not attached to an alarm structure");
bool PVAlarm::attach(PVFieldPtr const & pvField)
{
if(pvField->getField()->getType()!=structure) {
pvField->message(noAlarmFound,errorMessage);
return false;
}
if(pvField->getField()->getType()!=structure) return false;
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
pvSeverity = pvStructure->getIntField("severity");
if(pvSeverity.get()==NULL) {
pvField->message(noAlarmFound,errorMessage);
return false;
}
if(pvSeverity.get()==NULL) return false;
pvStatus = pvStructure->getIntField("status");
if(pvStatus.get()==NULL) {
pvField->message(noAlarmFound,errorMessage);
pvSeverity.reset();
return false;
}
pvMessage = pvStructure->getStringField("message");
if(pvMessage.get()==NULL) {
pvField->message(noAlarmFound,errorMessage);
pvSeverity.reset();
pvStatus.reset();
return false;

View File

@@ -37,8 +37,8 @@ private:
PVIntPtr pvSeverity;
PVIntPtr pvStatus;
PVStringPtr pvMessage;
static String noAlarmFound;
static String notAttached;
static std::string noAlarmFound;
static std::string notAttached;
};
}}

View File

@@ -19,26 +19,20 @@
namespace epics { namespace pvData {
using std::tr1::static_pointer_cast;
using std::string;
String PVControl::noControlFound("No control structure found");
String PVControl::notAttached("Not attached to an control structure");
string PVControl::noControlFound("No control structure found");
string PVControl::notAttached("Not attached to an control structure");
bool PVControl::attach(PVFieldPtr const & pvField)
{
if(pvField->getField()->getType()!=structure) {
pvField->message(noControlFound,errorMessage);
return false;
}
if(pvField->getField()->getType()!=structure) return false;
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
pvLow = pvStructure->getDoubleField("limitLow");
if(pvLow.get()==NULL) {
pvField->message(noControlFound,errorMessage);
return false;
}
pvHigh = pvStructure->getDoubleField(String("limitHigh"));
if(pvLow.get()==NULL) return false;
pvHigh = pvStructure->getDoubleField(string("limitHigh"));
if(pvHigh.get()==NULL) {
pvLow.reset();
pvField->message(noControlFound,errorMessage);
return false;
}
return true;

View File

@@ -33,8 +33,8 @@ public:
private:
PVDoublePtr pvLow;
PVDoublePtr pvHigh;
static String noControlFound;
static String notAttached;
static std::string noControlFound;
static std::string notAttached;
};
}}

View File

@@ -16,46 +16,37 @@
#include <pv/pvData.h>
#include <pv/pvDisplay.h>
using std::tr1::static_pointer_cast;
using std::string;
namespace epics { namespace pvData {
using std::tr1::static_pointer_cast;
String PVDisplay::noDisplayFound("No display structure found");
String PVDisplay::notAttached("Not attached to an display structure");
string PVDisplay::noDisplayFound("No display structure found");
string PVDisplay::notAttached("Not attached to an display structure");
bool PVDisplay::attach(PVFieldPtr const & pvField)
{
if(pvField->getField()->getType()!=structure) {
pvField->message(noDisplayFound,errorMessage);
return false;
}
if(pvField->getField()->getType()!=structure) return false;
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
pvDescription = pvStructure->getStringField("description");
if(pvDescription.get()==NULL) {
pvField->message(noDisplayFound,errorMessage);
return false;
}
if(pvDescription.get()==NULL) return false;
pvFormat = pvStructure->getStringField("format");
if(pvFormat.get()==NULL) {
pvField->message(noDisplayFound,errorMessage);
detach();
return false;
}
pvUnits = pvStructure->getStringField("units");
if(pvUnits.get()==NULL) {
pvField->message(noDisplayFound,errorMessage);
detach();
return false;
}
pvLow = pvStructure->getDoubleField(String("limitLow"));
pvLow = pvStructure->getDoubleField(string("limitLow"));
if(pvLow.get()==NULL) {
pvField->message(noDisplayFound,errorMessage);
detach();
return false;
}
pvHigh = pvStructure->getDoubleField(String("limitHigh"));
pvHigh = pvStructure->getDoubleField(string("limitHigh"));
if(pvHigh.get()==NULL) {
pvField->message(noDisplayFound,errorMessage);
detach();
return false;
}

View File

@@ -33,8 +33,8 @@ public:
void get(Display &) const;
bool set(Display const & display);
private:
static String noDisplayFound;
static String notAttached;
static std::string noDisplayFound;
static std::string notAttached;
PVStringPtr pvDescription;
PVStringPtr pvFormat;
PVStringPtr pvUnits;

View File

@@ -16,30 +16,24 @@
#include <pv/pvData.h>
#include <pv/pvEnumerated.h>
using std::tr1::static_pointer_cast;
using std::string;
namespace epics { namespace pvData {
using std::tr1::static_pointer_cast;
String PVEnumerated::notFound("No enumerated structure found");
String PVEnumerated::notAttached("Not attached to an enumerated structure");
string PVEnumerated::notFound("No enumerated structure found");
string PVEnumerated::notAttached("Not attached to an enumerated structure");
bool PVEnumerated::attach(PVFieldPtr const & pvField)
{
if(pvField->getField()->getType()!=structure) {
pvField->message(notFound,errorMessage);
return false;
}
if(pvField->getField()->getType()!=structure) return false;
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
pvIndex = pvStructure->getIntField("index");
if(pvIndex.get()==NULL) {
pvField->message(notFound,errorMessage);
return false;
}
if(pvIndex.get()==NULL) return false;
PVScalarArrayPtr pvScalarArray = pvStructure->getScalarArrayField(
"choices",pvString);
if(pvScalarArray.get()==NULL) {
pvIndex.reset();
pvField->message(notFound,errorMessage);
return false;
}
pvChoices = static_pointer_cast<PVStringArray>(pvScalarArray);
@@ -75,7 +69,7 @@ int32 PVEnumerated::getIndex()
return pvIndex->get();
}
String PVEnumerated::getChoice()
string PVEnumerated::getChoice()
{
if(pvIndex.get()==NULL ) {
throw std::logic_error(notAttached);

View File

@@ -33,14 +33,14 @@ public:
// a set returns false if field is immutable
bool setIndex(int32 index);
int32 getIndex();
String getChoice();
std::string getChoice();
bool choicesMutable();
inline PVStringArray::const_svector getChoices(){return pvChoices->view();}
int32 getNumberChoices();
bool setChoices(const StringArray & choices);
private:
static String notFound;
static String notAttached;
static std::string notFound;
static std::string notAttached;
PVIntPtr pvIndex;
PVStringArrayPtr pvChoices;
};

View File

@@ -16,19 +16,17 @@
#include <pv/pvData.h>
#include <pv/pvTimeStamp.h>
using std::tr1::static_pointer_cast;
using std::string;
namespace epics { namespace pvData {
using std::tr1::static_pointer_cast;
String PVTimeStamp::noTimeStamp("No timeStamp structure found");
String PVTimeStamp::notAttached("Not attached to a timeStamp structure");
string PVTimeStamp::noTimeStamp("No timeStamp structure found");
string PVTimeStamp::notAttached("Not attached to a timeStamp structure");
bool PVTimeStamp::attach(PVFieldPtr const & pvField)
{
if(pvField->getField()->getType()!=structure) {
pvField->message(noTimeStamp,errorMessage);
return false;
}
if(pvField->getField()->getType()!=structure) return false;
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
PVStructure* pvStructure = xxx.get();
while(true) {

View File

@@ -36,8 +36,8 @@ public:
void get(TimeStamp &) const;
bool set(TimeStamp const & timeStamp);
private:
static String noTimeStamp;
static String notAttached;
static std::string noTimeStamp;
static std::string notAttached;
PVLongPtr pvSecs;
PVIntPtr pvUserTag;
PVIntPtr pvNano;

View File

@@ -63,12 +63,12 @@ static inline bool operator!=(const UnionArray& a, const UnionArray& b)
* pvUByte, pvUShort, pvUInt, pvULong,
* pvFloat, or pvDouble.</p>
*
* <p>getString converts any supported type to a String.
* <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>fromString converts a String to a scalar.
* fromStringArray converts an array of Strings
* <p>fromString converts a std::string to a scalar.
* fromStringArray converts an array of std::strings
* to a pvArray, which must have a scaler element type.
* A scalar field is a numeric field or pvBoolean or pvString.</p>
* <p>All from methods put data into a PVField, e.g. from means where the PVField gets it's data.</p>
@@ -85,7 +85,7 @@ public:
* @param builder The builder that will have the result.
* @param pvField The pvField.
*/
void getFullName(StringBuilder buf,PVFieldPtr const & pvField)
void getFullName(std::string *buf,PVFieldPtr const & pvField)
{
*buf = pvField->getFullName();
}
@@ -121,7 +121,7 @@ public:
* If a PVField is a structure or array be prepared for a very long string.
* @param indentLevel indentation level
*/
inline void getString(StringBuilder buf,PVFieldPtr const & pvField,int indentLevel)
inline void getString(std::string *buf,PVFieldPtr const & pvField,int indentLevel)
{getString(buf, pvField.get(), indentLevel);}
/**
* Convert a PVField to a string.
@@ -129,7 +129,7 @@ public:
* @param pv The PVField to convert to a string.
* If the PVField is a structure or array be prepared for a very long string.
*/
inline void getString(StringBuilder buf,PVFieldPtr const & pvField)
inline void getString(std::string * buf,PVFieldPtr const & pvField)
{getString(buf, pvField.get(), 0);}
/**
* Convert a PVField to a string.
@@ -138,49 +138,49 @@ public:
* If a PVField is a structure or array be prepared for a very long string.
* @param indentLevel indentation level
*/
void getString(StringBuilder buf,PVField const * pvField,int indentLevel);
void getString(std::string * buf,PVField const * pvField,int indentLevel);
/**
* Convert a PVField to a string.
* param buf buffer for the result
* @param pv The PVField to convert to a string.
* If the PVField is a structure or array be prepared for a very long string.
*/
inline void getString(StringBuilder buf,PVField const * pvField)
inline void getString(std::string * buf,PVField const * pvField)
{getString(buf, pvField, 0);}
/**
* Convert from an array of String to a PVScalar
* Convert from an array of std::string to a PVScalar
* @param pv The PV.
* @param from The array of String value to convert and put into a PV.
* @param from The array of std::string value to convert and put into a PV.
* @param fromStartIndex The first element if the array of strings.
* @throws std::logic_error if the array of String does not have a valid values.
* @throws std::logic_error if the array of std::string does not have a valid values.
*/
std::size_t fromString(
PVStructurePtr const &pv,
StringArray const & from,
std::size_t fromStartIndex = 0);
/**
* Convert from a String to a PVScalar
* Convert from a std::string to a PVScalar
* @param pv The PV.
* @param from The String value to convert and put into a PV.
* @throws std::logic_error if the String does not have a valid value.
* @param from The std::string value to convert and put into a PV.
* @throws std::logic_error if the std::string does not have a valid value.
*/
void fromString(PVScalarPtr const & pv, String const & from)
void fromString(PVScalarPtr const & pv, std::string const & from)
{
pv->putFrom<String>(from);
pv->putFrom<std::string>(from);
}
/**
* Convert from a String to a PVScalarArray.
* The String must be a comma separated set of values optionally enclosed in []
* Convert from a std::string to a PVScalarArray.
* The std::string must be a comma separated set of values optionally enclosed in []
* @param pv The PV.
* @param from The String value to convert and put into a PV.
* @param from The std::string value to convert and put into a PV.
* @return The number of elements converted.
* @throws std::invalid_argument if the element Type is not a scalar.
* @throws std::logic_error if the String does not have a valid array values.
* @throws std::logic_error if the std::string does not have a valid array values.
*/
std::size_t fromString(PVScalarArrayPtr const & pv, String from);
std::size_t fromString(PVScalarArrayPtr const & pv, std::string from);
/**
* Convert a PVScalarArray from a String array.
* Convert a PVScalarArray from a std::string array.
* The array element type must be a scalar.
* @param pv The PV.
* @param offset Starting element in a PV.
@@ -189,7 +189,7 @@ public:
* @param fromOffset Starting element in the source array.
* @return The number of elements converted.
* @throws std::invalid_argument if the element Type is not a scalar.
* @throws std::logic_error if the String does not have a valid value.
* @throws std::logic_error if the std::string does not have a valid value.
*/
std::size_t fromStringArray(
PVScalarArrayPtr const & pv,
@@ -197,11 +197,11 @@ public:
StringArray const & from,
std::size_t fromOffset);
/**
* Convert a PVScalarArray to a String array.
* Convert a PVScalarArray to a std::string array.
* @param pv The PV.
* @param offset Starting element in the PV array.
* @param length Number of elements to convert to the string array.
* @param to String array to receive the converted PV data.
* @param to std::string array to receive the converted PV data.
* @param toOffset Starting element in the string array.
* @return Number of elements converted.
*/
@@ -401,11 +401,11 @@ public:
*/
inline double toDouble(PVScalarPtr const & pv) { return pv->getAs<double>();}
/**
* Convert a PV to a String
* Convert a PV to a std::string
* @param pv a PV
* @return converted value
*/
inline String toString(PVScalarPtr const & pv) { return pv->getAs<String>();}
inline std::string toString(PVScalarPtr const & pv) { return pv->getAs<std::string>();}
/**
* Convert a PV from a byte
* @param pv a PV
@@ -480,10 +480,10 @@ public:
/**
* Convenience method for implementing toString.
* It generates a newline and inserts blanks at the beginning of the newline.
* @param builder The StringBuilder being constructed.
* @param builder The std::string * being constructed.
* @param indentLevel Indent level, Each level is four spaces.
*/
void newLine(StringBuilder buf, int indentLevel);
void newLine(std::string * buf, int indentLevel);
};
static inline ConvertPtr getConvert() { return Convert::getConvert(); }

View File

@@ -2,6 +2,7 @@
#define PRINTER_H
#include <ostream>
#include <shareLib.h>
#include "pvData.h"

View File

@@ -14,13 +14,6 @@
#define NOMINMAX
#endif
#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3
/* error attribute was introduced in gcc 4.3.x */
#define USAGE_ERROR(MSG) __attribute__((error(MSG)))
#else
#define USAGE_ERROR(MSG) { throw std::runtime_error(MSG); }
#endif
#include <string>
#include <map>
#include <stdexcept>
@@ -30,7 +23,6 @@
#include <iomanip>
#include <pv/pvIntrospect.h>
#include <pv/requester.h>
#include <pv/typeCast.h>
#include <pv/sharedVector.h>
@@ -43,70 +35,6 @@ typedef class std::ios std::ios_base;
namespace epics { namespace pvData {
namespace format {
struct indent_level
{
long 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 std::ostream& operator<<(std::ostream& os, indent_level const& indent);
struct indent_scope
{
long saved_level;
std::ios_base& stream;
indent_scope(std::ios_base& ios) :
stream(ios)
{
long& l = indent_value(ios);
saved_level = l;
l = saved_level + 1;
}
~indent_scope()
{
indent_value(stream) = saved_level;
}
};
struct indent
{
};
epicsShareExtern std::ostream& operator<<(std::ostream& os, indent const&);
struct array_at
{
std::size_t index;
array_at(std::size_t ix) : index(ix) {}
};
struct array_at_internal
{
std::size_t index;
std::ostream& stream;
array_at_internal(std::size_t ix, std::ostream& str) : index(ix), stream(str) {}
};
epicsShareExtern array_at_internal operator<<(std::ostream& str, array_at const& manip);
};
class PVAuxInfo;
class PostHandler;
class PVField;
@@ -124,11 +52,6 @@ template<typename T> class PVScalarValue;
template<typename T> class PVValueArray;
/**
* typedef for a pointer to a PVAuxInfo.
*/
typedef std::tr1::shared_ptr<PVAuxInfo> PVAuxInfoPtr;
/**
* typedef for a pointer to a PostHandler.
*/
@@ -198,67 +121,6 @@ typedef std::tr1::shared_ptr<PVUnionArrayPtrArray> PVUnionArrayPtrArrayPtr;
class PVDataCreate;
typedef std::tr1::shared_ptr<PVDataCreate> PVDataCreatePtr;
/**
* This class provides auxillary information about a PVField.
* Each item is stored as a PVScalar.
* A (key,value) is provided for accessing the items where the key is a String.
*/
class epicsShareClass PVAuxInfo : private NoDefaultMethods {
public:
typedef std::map<String,PVScalarPtr> PVInfoMap;
typedef std::map<String,PVScalarPtr>::iterator PVInfoIter;
typedef std::pair<String,PVScalarPtr> PVInfoPair;
/**
* Constructor
* @param The fields to which the Auxinfo is attached.
*/
PVAuxInfo(PVField *pvField);
/**
* Destructor
*/
~PVAuxInfo();
/**
* Get the PVField to which the Auxinfo is attached.
* @return The fields to which the Auxinfo is attached.
*/
PVField * getPVField();
/**
* Add a new auxiliary item or retrieve the interface to an existing item.
*
* @param key The key.
* @param scalarType The scalarType for the new item being added/
* @return The new PVScalar that has been added to the Auxinfo.
*/
PVScalarPtr createInfo(String const & key,ScalarType scalarType);
/**
* Get the Auxinfo with the specified key.
* @return The PVScalar or null if it does not exist.
*/
PVScalarPtr getInfo(String const & key);
/**
* Get the map for the info.
* @return The map;
*/
PVInfoMap & getInfoMap();
/**
* Convert the Auxinfo to a string and add it to builder.
* @param builder The string builder.
*/
void toString(StringBuilder buf);
/**
* Convert the Auxinfo to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
void toString(StringBuilder buf,int indentLevel);
private:
PVScalarPtr nullPVScalar;
PVField * pvField;
PVInfoMap pvInfos;
friend class PVDataCreate;
};
/**
* This class is implemented by code that calls setPostHander
*/
@@ -294,29 +156,17 @@ public:
* Destructor
*/
virtual ~PVField();
/**
* Called to report errors associated with the field.
* @param message The message.
* @param messageType The message type.
*/
virtual void message(String message,MessageType messageType) ;
/**
* Get the fieldName for this field.
* @return The name or empty string if top level field.
*/
inline const String& getFieldName() const {return fieldName;}
inline const std::string& getFieldName() const {return fieldName;}
/**
* Fully expand the name of this field using the
* names of its parent fields with a dot '.' seperating
* each name.
*/
String getFullName() const;
/**
* Register the message requester.
* At most one requester can be registered.
* @param prequester The requester.
*/
virtual void setRequester(RequesterPtr const &prequester);
std::string getFullName() const;
/**
* Get offset of the PVField field within top level structure.
* Every field within the PVStructure has a unique offset.
@@ -338,11 +188,6 @@ public:
* This is equal to nextFieldOffset - fieldOffset.
*/
std::size_t getNumberFields() const;
/**
* Get the PVAuxInfo interface for the PVField.
* @return The PVAuxInfo interface.
*/
PVAuxInfoPtr & getPVAuxInfo();
/**
* Is the field immutable, i.e. does it not allow changes.
* @return (false,true) if it (is not, is) immutable.
@@ -363,16 +208,6 @@ public:
* @return The parent interface or null if this is PVRecord
*/
PVStructure * getParent() const ;
/**
* Replace the data implementation for the field.
* @param newPVField The new implementation
*/
void replacePVField(const PVFieldPtr& newPVField);
/**
* Rename the field name.
* @param newName The new name.
*/
void renameField(String const & newName);
/**
* postPut. Called when the field is updated by the implementation.
*/
@@ -389,19 +224,6 @@ public:
* @return (false,true) if (is not,is) equal.
*/
virtual bool equals(PVField &pv);
/**
* Convert the PVField to a string.
* @param buf buffer for the result
*/
virtual void toString(StringBuilder buf) ;
/**
* Convert the PVField to a string.
* Each line is indented.
* @param buf buffer for the result
* @param indentLevel The indentation level.
*/
virtual void toString(StringBuilder buf,int indentLevel) ;
/**
* Puts the PVField raw value to the stream.
* @param o output stream.
@@ -409,28 +231,23 @@ public:
*/
virtual std::ostream& dumpValue(std::ostream& o) const = 0;
protected:
PVField::shared_pointer getPtrSelf()
{
return shared_from_this();
}
PVField(FieldConstPtr field);
void setParentAndName(PVStructure *parent, String const & fieldName);
void replaceField(FieldConstPtr &field);
void setParentAndName(PVStructure *parent, std::string const & fieldName);
private:
void message(String message,MessageType messageType,String fullFieldName);
static void computeOffset(const PVField *pvField);
static void computeOffset(const PVField *pvField,std::size_t offset);
String notImplemented;
PVAuxInfoPtr pvAuxInfo;
String fieldName;
std::string notImplemented;
std::string fieldName;
PVStructure *parent;
FieldConstPtr field;
size_t fieldOffset;
size_t nextFieldOffset;
bool immutable;
RequesterPtr requester;
PostHandlerPtr postHandler;
friend class PVDataCreate;
friend class PVStructure;
@@ -622,7 +439,7 @@ typedef std::tr1::shared_ptr<PVDouble> PVDoublePtr;
/**
* PVString is special case, since it implements SerializableArray
*/
class epicsShareClass PVString : public PVScalarValue<String>, SerializableArray {
class epicsShareClass PVString : public PVScalarValue<std::string>, SerializableArray {
public:
/**
* Destructor
@@ -630,7 +447,7 @@ public:
virtual ~PVString() {}
protected:
PVString(ScalarConstPtr const & scalar)
: PVScalarValue<String>(scalar) {}
: PVScalarValue<std::string>(scalar) {}
};
typedef std::tr1::shared_ptr<PVString> PVStringPtr;
@@ -649,6 +466,11 @@ public:
* Destructor
*/
virtual ~PVArray(){};
/**
* Get the introspection interface
* @return The interface.
*/
virtual ArrayConstPtr getArray() const = 0;
/**
* Set the field to be immutable, i. e. it can no longer be modified.
* This is permanent, i.e. once done the field can onot be made mutable.
@@ -696,31 +518,6 @@ private:
epicsShareExtern std::ostream& operator<<(format::array_at_internal const& manip, const PVArray& array);
/**
* Class provided by caller of get
*/
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;
/**
* The data array.
*/
std::vector<T> & data;
/**
* The offset. This is the offset into the actual array of the first element in data,
*/
std::size_t offset;
PVArrayData()
: data(init)
{}
};
/**
* Base class for a scalarArray.
@@ -835,10 +632,10 @@ public:
* @param fieldName The name of the field.
* @return Pointer to the field or null if field does not exist.
*/
PVFieldPtr getSubField(String const &fieldName) const;
PVFieldPtr getSubField(std::string const &fieldName) const;
template<typename PVT>
std::tr1::shared_ptr<PVT> getSubField(String const &fieldName) const
std::tr1::shared_ptr<PVT> getSubField(std::string const &fieldName) const
{
PVFieldPtr pvField = getSubField(fieldName);
if (pvField.get())
@@ -864,140 +661,128 @@ public:
return std::tr1::shared_ptr<PVT>();
}
/**
* Append a field to the structure.
* @param fieldName The name of the field to append.
* @param pvField The field to append.
*/
void appendPVField(String const &fieldName,PVFieldPtr const & pvField);
/**
* Append fields to the structure.
* @param fieldNames The names of the fields to add.
* @param pvFields The fields to append.
* @return Pointer to the field or null if field does not exist.
*/
void appendPVFields(StringArray const & fieldNames,PVFieldPtrArray const & pvFields);
/**
* Remove a field from the structure.
* @param fieldName The name of the field to remove.
*/
void removePVField(String const &fieldName);
/**
* Get a boolean field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVBooleanPtr getBooleanField(String const &fieldName) ;
PVBooleanPtr getBooleanField(std::string const &fieldName) ;
/**
* Get a byte field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVBytePtr getByteField(String const &fieldName) ;
PVBytePtr getByteField(std::string const &fieldName) ;
/**
* Get a short field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVShortPtr getShortField(String const &fieldName) ;
PVShortPtr getShortField(std::string const &fieldName) ;
/**
* Get a int field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVIntPtr getIntField(String const &fieldName) ;
PVIntPtr getIntField(std::string const &fieldName) ;
/**
* Get a long field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVLongPtr getLongField(String const &fieldName) ;
PVLongPtr getLongField(std::string const &fieldName) ;
/**
* Get an unsigned byte field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVUBytePtr getUByteField(String const &fieldName) ;
PVUBytePtr getUByteField(std::string const &fieldName) ;
/**
* Get an unsigned short field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVUShortPtr getUShortField(String const &fieldName) ;
PVUShortPtr getUShortField(std::string const &fieldName) ;
/**
* Get an unsigned int field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVUIntPtr getUIntField(String const &fieldName) ;
PVUIntPtr getUIntField(std::string const &fieldName) ;
/**
* Get an unsigned long field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVULongPtr getULongField(String const &fieldName) ;
PVULongPtr getULongField(std::string const &fieldName) ;
/**
* Get a float field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVFloatPtr getFloatField(String const &fieldName) ;
PVFloatPtr getFloatField(std::string const &fieldName) ;
/**
* Get a double field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVDoublePtr getDoubleField(String const &fieldName) ;
PVDoublePtr getDoubleField(std::string const &fieldName) ;
/**
* Get a string field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVStringPtr getStringField(String const &fieldName) ;
PVStringPtr getStringField(std::string const &fieldName) ;
/**
* Get a structure field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVStructurePtr getStructureField(String const &fieldName) ;
PVStructurePtr getStructureField(std::string const &fieldName) ;
/**
* Get a union field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVUnionPtr getUnionField(String const &fieldName) ;
PVUnionPtr getUnionField(std::string const &fieldName) ;
/**
* Get a scalarArray field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @param elementType The element type.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVScalarArrayPtr getScalarArrayField(
String const &fieldName,ScalarType elementType) ;
std::string const &fieldName,ScalarType elementType) ;
/**
* Get a structureArray field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVStructureArrayPtr getStructureArrayField(String const &fieldName) ;
PVStructureArrayPtr getStructureArrayField(std::string const &fieldName) ;
/**
* Get a unionArray field with the specified name.
* No longer needed. Use templete version of getSubField
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVUnionArrayPtr getUnionArrayField(String const &fieldName) ;
/**
* Get the name if this structure extends another structure.
* @return The string which may be null.
*/
String getExtendsStructureName() const;
/**
* Put the extends name.
* @param extendsStructureName The name.
*/
bool putExtendsStructureName(
String const &extendsStructureName);
PVUnionArrayPtr getUnionArrayField(std::string const &fieldName) ;
/**
* Serialize.
* @param pbuffer The byte buffer.
@@ -1043,7 +828,6 @@ public:
virtual std::ostream& dumpValue(std::ostream& o) const;
private:
void fixParentStructure();
static PVFieldPtr nullPVField;
static PVBooleanPtr nullPVBoolean;
static PVBytePtr nullPVByte;
@@ -1065,11 +849,14 @@ private:
PVFieldPtrArray pvFields;
StructureConstPtr structurePtr;
String extendsStructureName;
std::string extendsStructureName;
friend class PVDataCreate;
};
/**
* PVUnion has a single subfield which has a type specified by a union introspection interface.
*/
class epicsShareClass PVUnion : public PVField
{
public:
@@ -1124,10 +911,10 @@ public:
* @return corresponding PVField (of undetermined value).
* @throws {@code std::invalid_argument} if field does not exist.
*/
PVFieldPtr select(String const & fieldName);
PVFieldPtr select(std::string const & fieldName);
template<typename PVT>
std::tr1::shared_ptr<PVT> select(String const & fieldName) {
std::tr1::shared_ptr<PVT> select(std::string const & fieldName) {
return std::tr1::dynamic_pointer_cast<PVT>(select(fieldName));
}
@@ -1141,7 +928,7 @@ public:
* Get selected field name.
* @return selected field name, empty string if field does not exist.
*/
String getSelectedFieldName() const;
std::string getSelectedFieldName() const;
/**
* Set the {@code PVField} (by reference!) as selected field.
@@ -1161,12 +948,12 @@ public:
/**
* Set the {@code PVField} (by reference!) as field by given name.
* If a value is not a valid union field an {@code std::invalid_argument} exception is thrown.
* Use {@code select(String)} to put by value.
* Use {@code select(std::string)} to put by value.
* @param fieldName Name of the field to put.
* @param value the field to set.
* @see #select(String)
* @see #select(std::string)
*/
void set(String const & fieldName, PVFieldPtr const & value);
void set(std::string const & fieldName, PVFieldPtr const & value);
/**
* Serialize.
@@ -1225,12 +1012,6 @@ namespace detail {
typedef ::epics::pvData::shared_vector<T> svector;
typedef ::epics::pvData::shared_vector<const T> const_svector;
// begin deprecated
typedef PVArrayData<T> ArrayDataType;
typedef std::vector<T> vector;
typedef const std::vector<T> const_vector;
typedef std::tr1::shared_ptr<vector> shared_vector;
// end deprecated
protected:
PVVectorStorage() : Base() {}
@@ -1279,79 +1060,6 @@ namespace detail {
return thaw(result);
}
/**
* Get array elements
* @param offset The offset of the first element,
* @param length The number of elements to get.
* @param data The place where the data is placed.
*/
std::size_t get(
std::size_t offset, std::size_t length, ArrayDataType &data) EPICS_DEPRECATED
{
const_svector ref = this->view();
ref.slice(offset, length);
data.data.resize(ref.size());
data.offset = 0;
std::copy(ref.begin(), ref.end(), data.data.begin());
return ref.size();
}
/**
* Copy data into the array growing the length as needed.
* @param offset The offset of the first element,
* @param length The number of elements to get.
* @param from The new values to put into the array.
* @param fromOffset The offset in from.
* @return The number of elements put into the array.
* calls postPut()
*/
std::size_t put(std::size_t offset,
std::size_t length, const_pointer from, std::size_t fromOffset) EPICS_DEPRECATED
{
from += fromOffset;
svector temp(this->reuse());
if(temp.size() < length+offset)
temp.resize(length+offset);
else
temp.make_unique();
std::copy(from, from + length, temp.begin() + offset);
this->replace(freeze(temp));
return length;
}
std::size_t put(std::size_t offset,
std::size_t length, const_vector &from, std::size_t fromOffset) EPICS_DEPRECATED
{ return this->put(offset,length, &from[0], fromOffset); }
/**
* Share data from another source.
* @param value The data to share.
* @param capacity The capacity of the array.
* @param length The length of the array.
* Does @b not call postPut()
*/
void shareData(
shared_vector const & value,
std::size_t capacity,
std::size_t length) EPICS_DEPRECATED
{
vector& vref = *value.get();
typename svector::shared_pointer_type p(&vref[0],
detail::shared_ptr_vector_deletor<T>(value));
const_svector temp(p, 0, std::min(length, vref.size()));
this->swap(temp);
}
pointer get() const EPICS_DEPRECATED {
// evil unsafe cast!
return (pointer)this->view().data();
}
vector const & getVector() USAGE_ERROR("No longer implemented. Replace with view()");
shared_vector const & getSharedVector() USAGE_ERROR("No longer implemented. Replace with view()");
};
} // namespace detail
@@ -1368,14 +1076,6 @@ public:
typedef ::epics::pvData::shared_vector<T> svector;
typedef ::epics::pvData::shared_vector<const T> const_svector;
// begin deprecated
typedef PVArrayData<T> ArrayDataType;
typedef std::vector<T> vector;
typedef const std::vector<T> const_vector;
typedef std::tr1::shared_ptr<vector> shared_vector;
typedef PVValueArray & reference;
typedef const PVValueArray & const_reference;
// end deprecated
static const ScalarType typeCode;
@@ -1384,6 +1084,11 @@ public:
*/
virtual ~PVValueArray() {}
virtual ArrayConstPtr getArray() const
{
return std::tr1::static_pointer_cast<const Array>(this->getField());
}
std::ostream& dumpValue(std::ostream& o) const
{
const_svector v(this->view());
@@ -1421,10 +1126,6 @@ protected:
friend class PVDataCreate;
};
/**
* This is provided by code that calls get.
*/
typedef PVArrayData<PVStructurePtr> StructureArrayData;
/**
* Data class for a structureArray
@@ -1438,10 +1139,6 @@ public:
typedef PVStructurePtr value_type;
typedef PVStructurePtr* pointer;
typedef const PVStructurePtr* const_pointer;
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;
@@ -1453,6 +1150,11 @@ public:
*/
virtual ~PVValueArray() {}
virtual ArrayConstPtr getArray() const
{
return std::tr1::static_pointer_cast<const Array>(structureArray);
}
virtual size_t getLength() const {return value.size();}
virtual size_t getCapacity() const {return value.capacity();}
@@ -1519,10 +1221,6 @@ private:
};
/**
* This is provided by code that calls get.
*/
typedef PVArrayData<PVUnionPtr> UnionArrayData;
/**
* Data class for a unionArray
@@ -1536,10 +1234,6 @@ public:
typedef PVUnionPtr value_type;
typedef PVUnionPtr* pointer;
typedef const PVUnionPtr* const_pointer;
typedef PVArrayData<PVUnionPtr> ArrayDataType;
typedef std::vector<PVUnionPtr> vector;
typedef const std::vector<PVUnionPtr> const_vector;
typedef std::tr1::shared_ptr<vector> shared_vector;
typedef PVUnionArray &reference;
typedef const PVUnionArray& const_reference;
@@ -1551,6 +1245,11 @@ public:
*/
virtual ~PVValueArray() {}
virtual ArrayConstPtr getArray() const
{
return std::tr1::static_pointer_cast<const Array>(unionArray);
}
virtual size_t getLength() const {return value.size();}
virtual size_t getCapacity() const {return value.capacity();}
@@ -1620,52 +1319,40 @@ private:
/**
* Definitions for the various scalarArray types.
*/
typedef PVArrayData<boolean> BooleanArrayData;
typedef PVValueArray<boolean> PVBooleanArray;
typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
typedef PVArrayData<int8> ByteArrayData;
typedef PVValueArray<int8> PVByteArray;
typedef std::tr1::shared_ptr<PVByteArray> PVByteArrayPtr;
typedef PVArrayData<int16> ShortArrayData;
typedef PVValueArray<int16> PVShortArray;
typedef std::tr1::shared_ptr<PVShortArray> PVShortArrayPtr;
typedef PVArrayData<int32> IntArrayData;
typedef PVValueArray<int32> PVIntArray;
typedef std::tr1::shared_ptr<PVIntArray> PVIntArrayPtr;
typedef PVArrayData<int64> LongArrayData;
typedef PVValueArray<int64> PVLongArray;
typedef std::tr1::shared_ptr<PVLongArray> PVLongArrayPtr;
typedef PVArrayData<uint8> UByteArrayData;
typedef PVValueArray<uint8> PVUByteArray;
typedef std::tr1::shared_ptr<PVUByteArray> PVUByteArrayPtr;
typedef PVArrayData<uint16> UShortArrayData;
typedef PVValueArray<uint16> PVUShortArray;
typedef std::tr1::shared_ptr<PVUShortArray> PVUShortArrayPtr;
typedef PVArrayData<uint32> UIntArrayData;
typedef PVValueArray<uint32> PVUIntArray;
typedef std::tr1::shared_ptr<PVUIntArray> PVUIntArrayPtr;
typedef PVArrayData<uint64> ULongArrayData;
typedef PVValueArray<uint64> PVULongArray;
typedef std::tr1::shared_ptr<PVULongArray> PVULongArrayPtr;
typedef PVArrayData<float> FloatArrayData;
typedef PVValueArray<float> PVFloatArray;
typedef std::tr1::shared_ptr<PVFloatArray> PVFloatArrayPtr;
typedef PVArrayData<double> DoubleArrayData;
typedef PVValueArray<double> PVDoubleArray;
typedef std::tr1::shared_ptr<PVDoubleArray> PVDoubleArrayPtr;
typedef PVArrayData<String> StringArrayData;
typedef PVValueArray<String> PVStringArray;
typedef PVValueArray<std::string> PVStringArray;
typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
/**
@@ -1673,7 +1360,12 @@ typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
*/
class epicsShareClass PVDataCreate {
public:
/**
* get the singleton
* @return The PVDataCreate implementation
*/
static PVDataCreatePtr getPVDataCreate();
/**
* Create a PVField using given Field introspection data.
* @param field The introspection data to be used to create PVField.
@@ -1706,6 +1398,56 @@ public:
* @return The PVScalar implementation.
*/
PVScalarPtr createPVScalar(PVScalarPtr const & scalarToClone);
/**
* template version
* @param PVT must ve a valid pvType
* @return The PVScalar implementation.
*/
template<typename PVT>
std::tr1::shared_ptr<PVT> createPVScalar()
{
return std::tr1::static_pointer_cast<PVT>(createPVScalar(PVT::typeCode));
}
/**
* Create implementation for PVStructure.
* @param structure The introspection interface.
* @return The PVStructure implementation
*/
PVStructurePtr createPVStructure(StructureConstPtr const & structure);
/**
* Create implementation for PVStructure.
* @param fieldNames The field names.
* @param pvFields Array of PVFields
* @return The PVStructure implementation
*/
PVStructurePtr createPVStructure(
StringArray const & fieldNames,PVFieldPtrArray const & pvFields);
/**
* Create implementation for PVStructure.
* @param structToClone A structure. Each subfield and any auxInfo is cloned and added to the newly created structure.
* @return The PVStructure implementation.
*/
PVStructurePtr createPVStructure(PVStructurePtr const & structToClone);
/**
* Create implementation for PVUnion.
* @param union The introspection interface.
* @return The PVUnion implementation
*/
PVUnionPtr createPVUnion(UnionConstPtr const & punion);
/**
* Create implementation for PVUnion.
* @param unionToClone A union. Each subfield is cloned and added to the newly created union.
* @return The PVUnion implementation.
*/
PVUnionPtr createPVUnion(PVUnionPtr const & unionToClone);
/**
* Create variant union implementation.
* @return The variant PVUnion implementation.
*/
PVUnionPtr createPVVariantUnion();
/**
* Create an implementation of an array field reusing the Array introspection interface.
* @param array The introspection interface.
@@ -1726,6 +1468,17 @@ public:
* @return The PVScalarArray implementation.
*/
PVScalarArrayPtr createPVScalarArray(PVScalarArrayPtr const & scalarArrayToClone);
/**
* template version
* @param PVT must ve a valid pvType
* @return The PVScalarArray implementation.
*/
template<typename PVAT>
std::tr1::shared_ptr<PVAT> createPVScalarArray()
{
return std::tr1::static_pointer_cast<PVAT>(createPVScalarArray(PVAT::typeCode));
}
/**
* Create an implementation of an array with structure elements.
* @param structureArray The introspection interface.
@@ -1734,25 +1487,16 @@ public:
*/
PVStructureArrayPtr createPVStructureArray(StructureArrayConstPtr const & structureArray);
/**
* Create implementation for PVStructure.
* @param structure The introspection interface.
* @return The PVStructure implementation
* Create an implementation of an array with structure elements.
* @param structure The introspection interface that is used to create StructureArrayConstPtr.
* All elements share the same introspection interface.
* @return The PVStructureArray implementation.
*/
PVStructurePtr createPVStructure(StructureConstPtr const & structure);
/**
* Create implementation for PVStructure.
* @param fieldNames The field names.
* @param pvFields Array of PVFields
* @return The PVStructure implementation
*/
PVStructurePtr createPVStructure(
StringArray const & fieldNames,PVFieldPtrArray const & pvFields);
/**
* Create implementation for PVStructure.
* @param structToClone A structure. Each subfield and any auxInfo is cloned and added to the newly created structure.
* @return The PVStructure implementation.
*/
PVStructurePtr createPVStructure(PVStructurePtr const & structToClone);
PVStructureArrayPtr createPVStructureArray(StructureConstPtr const & structure)
{
return createPVStructureArray(fieldCreate->createStructureArray(structure));
}
/**
* Create an implementation of an array with union elements.
* @param unionArray The introspection interface.
@@ -1761,51 +1505,21 @@ public:
*/
PVUnionArrayPtr createPVUnionArray(UnionArrayConstPtr const & unionArray);
/**
* Create implementation for PVUnion.
* @param union The introspection interface.
* @return The PVUnion implementation
* Create an implementation of an array with union elements.
* @param punion The introspection interface tht is used to create UnionArrayConstPtr.
* All elements share the same introspection interface.
* @return The PVUnionArray implementation.
*/
PVUnionPtr createPVUnion(UnionConstPtr const & punion);
/**
* Create implementation for PVUnion.
* @param unionToClone A union. Each subfield is cloned and added to the newly created union.
* @return The PVUnion implementation.
*/
PVUnionPtr createPVUnion(PVUnionPtr const & unionToClone);
/**
* Create variant union implementation.
* @return The variant PVUnion implementation.
*/
PVUnionPtr createPVVariantUnion();
PVUnionArrayPtr createPVUnionArray(UnionConstPtr const & punion)
{
return createPVUnionArray(fieldCreate->createUnionArray(punion));
}
/**
* Create variant union array implementation.
* @return The variant PVUnionArray implementation.
*/
PVUnionArrayPtr createPVVariantUnionArray();
template<typename PVT>
std::tr1::shared_ptr<PVT> createPVScalar()
{
return std::tr1::static_pointer_cast<PVT>(createPVScalar(PVT::typeCode));
}
template<typename PVAT>
std::tr1::shared_ptr<PVAT> createPVScalarArray()
{
return std::tr1::static_pointer_cast<PVAT>(createPVScalarArray(PVAT::typeCode));
}
PVStructureArrayPtr createPVStructureArray(StructureConstPtr const & structure)
{
return createPVStructureArray(fieldCreate->createStructureArray(structure));
}
PVUnionArrayPtr createPVUnionArray(UnionConstPtr const & punion)
{
return createPVUnionArray(fieldCreate->createUnionArray(punion));
}
private:
PVDataCreate();
FieldCreatePtr fieldCreate;
@@ -1818,7 +1532,5 @@ private:
epicsShareExtern PVDataCreatePtr getPVDataCreate();
#undef USAGE_ERROR
}}
#endif /* PVDATA_H */

View File

@@ -12,6 +12,7 @@
#include <string>
#include <stdexcept>
#include <iostream>
#include <pv/noDefaultMethods.h>
#include <pv/pvType.h>
@@ -22,8 +23,70 @@
namespace epics { namespace pvData {
namespace format {
struct indent_level
{
long 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 std::ostream& operator<<(std::ostream& os, indent_level const& indent);
struct indent_scope
{
long saved_level;
std::ios_base& stream;
indent_scope(std::ios_base& ios) :
stream(ios)
{
long& l = indent_value(ios);
saved_level = l;
l = saved_level + 1;
}
~indent_scope()
{
indent_value(stream) = saved_level;
}
};
struct indent
{
};
epicsShareExtern std::ostream& operator<<(std::ostream& os, indent const&);
struct array_at
{
std::size_t index;
array_at(std::size_t ix) : index(ix) {}
};
struct array_at_internal
{
std::size_t index;
std::ostream& stream;
array_at_internal(std::size_t ix, std::ostream& str) : index(ix), stream(str) {}
};
epicsShareExtern array_at_internal operator<<(std::ostream& str, array_at const& manip);
};
class Field;
class Scalar;
class Array;
class ScalarArray;
class Structure;
class StructureArray;
@@ -42,6 +105,10 @@ typedef std::vector<FieldConstPtr> FieldConstPtrArray;
* typedef for a shared pointer to an immutable Scalar.
*/
typedef std::tr1::shared_ptr<const Scalar> ScalarConstPtr;
/**
* typedef for a shared pointer to an immutable Array.
*/
typedef std::tr1::shared_ptr<const Array> ArrayConstPtr;
/**
* typedef for a shared pointer to an immutable ScalarArray.
*/
@@ -103,14 +170,11 @@ namespace TypeFunc {
* @return The name for the type.
*/
epicsShareExtern const char* name(Type type);
/**
* Convert the type to a string and add it to builder.
* @param builder The string builder.
* @param type The type.
*/
epicsShareExtern void toString(StringBuilder builder,const Type type);
};
epicsShareExtern std::ostream& operator<<(std::ostream& o, const Type& type);
/**
* Definition of support scalar types.
*/
@@ -201,24 +265,21 @@ namespace ScalarTypeFunc {
* @return The scalarType.
* An exception is thrown if the name is not the name of a scalar type.
*/
epicsShareExtern ScalarType getScalarType(String const &value);
epicsShareExtern ScalarType getScalarType(std::string const &value);
/**
* Get a name for the scalarType.
* @param scalarType The type.
* @return The name for the scalarType.
*/
epicsShareExtern const char* name(ScalarType scalarType);
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
* @param scalarType The type.
*/
epicsShareExtern void toString(StringBuilder builder,ScalarType scalarType);
//! gives sizeof(T) where T depends on the scalar type id.
epicsShareExtern size_t elementSize(ScalarType id);
};
epicsShareExtern std::ostream& operator<<(std::ostream& o, const ScalarType& scalarType);
/**
* This class implements introspection object for field.
*/
@@ -240,18 +301,15 @@ public:
* Get the identification string.
* @return The identification string, can be empty.
*/
virtual String getID() const = 0;
virtual std::string getID() const = 0;
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
* Puts the string representation to the stream.
* @param o output stream.
* @return The output stream.
*/
virtual void toString(StringBuilder builder) const{toString(builder,0);}
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
virtual void toString(StringBuilder builder,int indentLevel) const;
virtual std::ostream& dump(std::ostream& o) const = 0;
protected:
/**
* Constructor
@@ -271,6 +329,8 @@ private:
struct Deleter{void operator()(Field *p){delete p;}};
};
epicsShareExtern std::ostream& operator<<(std::ostream& o, const Field& field);
/**
* This class implements introspection object for Scalar.
@@ -289,19 +349,10 @@ public:
* @return the scalarType
*/
ScalarType getScalarType() const {return scalarType;}
/**
* Convert the scalar to a string and add it to builder.
* @param builder The string builder.
*/
virtual void toString(StringBuilder buf) const{toString(buf,0);}
/**
* Convert the scalar to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
virtual void toString(StringBuilder buf,int indentLevel) const;
virtual std::string getID() const;
virtual String getID() const;
virtual std::ostream& dump(std::ostream& o) const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
@@ -314,10 +365,39 @@ private:
friend class FieldCreate;
};
/**
* This class implements introspection object for Array.
*/
class epicsShareClass Array : public Field{
public:
POINTER_DEFINITIONS(Array);
/**
* Destructor.
*/
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;
*/
protected:
/**
* Constructor
* @param fieldName The field type.
*/
Array(Type type);
};
/**
* This class implements introspection object for field.
*/
class epicsShareClass ScalarArray : public Field{
class epicsShareClass ScalarArray : public Array{
public:
POINTER_DEFINITIONS(ScalarArray);
typedef ScalarArray& reference;
@@ -332,20 +412,11 @@ public:
* Get the scalarType for the elements.
* @return the scalarType
*/
ScalarType getElementType() const {return elementType;}
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
*/
virtual void toString(StringBuilder buf) const{toString(buf,0);}
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
virtual void toString(StringBuilder buf,int indentLevel) const;
ScalarType getElementType() const {return elementType;}
virtual String getID() const;
virtual std::string getID() const;
virtual std::ostream& dump(std::ostream& o) const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
@@ -357,7 +428,7 @@ protected:
virtual ~ScalarArray();
private:
int8 getTypeCodeLUT() const;
const String getIDScalarArrayLUT() const;
const std::string getIDScalarArrayLUT() const;
ScalarType elementType;
friend class FieldCreate;
};
@@ -365,7 +436,7 @@ private:
/**
* This class implements introspection object for a structureArray
*/
class epicsShareClass StructureArray : public Field{
class epicsShareClass StructureArray : public Array{
public:
POINTER_DEFINITIONS(StructureArray);
typedef StructureArray& reference;
@@ -375,16 +446,11 @@ public:
* Get the introspection interface for the array elements.
* @return The introspection interface.
*/
StructureConstPtr getStructure() const {return pstructure;}
StructureConstPtr getStructure() const {return pstructure;}
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
virtual void toString(StringBuilder buf,int indentLevel=0) const;
virtual String getID() const;
virtual std::string getID() const;
virtual std::ostream& dump(std::ostream& o) const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
@@ -407,7 +473,7 @@ private:
/**
* This class implements introspection object for a unionArray
*/
class epicsShareClass UnionArray : public Field{
class epicsShareClass UnionArray : public Array{
public:
POINTER_DEFINITIONS(UnionArray);
typedef UnionArray& reference;
@@ -417,16 +483,11 @@ public:
* Get the introspection interface for the array elements.
* @return The introspection interface.
*/
UnionConstPtr getUnion() const {return punion;}
UnionConstPtr getUnion() const {return punion;}
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
virtual void toString(StringBuilder buf,int indentLevel=0) const;
virtual String getID() const;
virtual std::string getID() const;
virtual std::ostream& dump(std::ostream& o) const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
@@ -456,7 +517,7 @@ public:
/**
* Default structure ID.
*/
static epics::pvData::String DEFAULT_ID;
static std::string DEFAULT_ID;
/**
* Destructor.
@@ -476,7 +537,7 @@ public:
* @return The introspection interface.
* This will hold a null pointer if the field is not in the structure.
*/
FieldConstPtr getField(String const &fieldName) const;
FieldConstPtr getField(std::string const &fieldName) const;
/**
* Get the field for the specified fieldName.
* @param fieldName The index of the field to get;
@@ -489,7 +550,7 @@ public:
* @return The introspection interface.
* This will be -1 if the field is not in the structure.
*/
std::size_t getFieldIndex(String const &fieldName) const;
std::size_t getFieldIndex(std::string const &fieldName) const;
/**
* Get the fields in the structure.
* @return The array of fields.
@@ -500,40 +561,31 @@ public:
* @return The array of fieldNames.
*/
StringArray const & getFieldNames() const {return fieldNames;}
void renameField(std::size_t fieldIndex,String const & newName)
{fieldNames[fieldIndex] = newName;}
/**
* Get the name of the field with the specified index;
* @param fieldIndex The index of the desired field.
* @return The fieldName.
*/
String getFieldName(std::size_t fieldIndex) const {return fieldNames[fieldIndex];}
/**
* Convert the structure to a string and add it to builder.
* @param builder The string builder.
*/
virtual void toString(StringBuilder buf) const{toString(buf,0);}
/**
* Convert the structure to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
virtual void toString(StringBuilder buf,int indentLevel) const;
virtual String getID() const;
std::string getFieldName(std::size_t fieldIndex) const {return fieldNames[fieldIndex];}
virtual std::string getID() const;
virtual std::ostream& dump(std::ostream& o) const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
protected:
Structure(StringArray const & fieldNames, FieldConstPtrArray const & fields, String const & id = DEFAULT_ID);
Structure(StringArray const & fieldNames, FieldConstPtrArray const & fields, std::string const & id = DEFAULT_ID);
private:
void toStringCommon(StringBuilder buf,int indentLevel) const;
StringArray fieldNames;
FieldConstPtrArray fields;
String id;
friend class FieldCreate;
friend class Union;
std::string id;
virtual void dumpFields(std::ostream& o) const;
friend class FieldCreate;
friend class Union;
};
/**
@@ -546,12 +598,12 @@ public:
/**
* Default union ID.
*/
static epics::pvData::String DEFAULT_ID;
static std::string DEFAULT_ID;
/**
* Default variant union ID.
*/
static epics::pvData::String ANY_ID;
static std::string ANY_ID;
/**
* Destructor.
@@ -571,7 +623,7 @@ public:
* @return The introspection interface.
* This will hold a null pointer if the field is not in the union.
*/
FieldConstPtr getField(String const &fieldName) const;
FieldConstPtr getField(std::string const &fieldName) const;
/**
* Get the field for the specified fieldName.
* @param fieldName The index of the field to get;
@@ -584,7 +636,7 @@ public:
* @return The introspection interface.
* This will be -1 if the field is not in the union.
*/
std::size_t getFieldIndex(String const &fieldName) const;
std::size_t getFieldIndex(std::string const &fieldName) const;
/**
* Get the fields in the union.
* @return The array of fields.
@@ -595,51 +647,39 @@ public:
* @return The array of fieldNames.
*/
StringArray const & getFieldNames() const {return fieldNames;}
void renameField(std::size_t fieldIndex,String const & newName)
{fieldNames[fieldIndex] = newName;}
/**
* Get the name of the field with the specified index;
* @param fieldIndex The index of the desired field.
* @return The fieldName.
*/
String getFieldName(std::size_t fieldIndex) const {return fieldNames[fieldIndex];}
std::string getFieldName(std::size_t fieldIndex) const {return fieldNames[fieldIndex];}
/**
* Check if this union is variant union (aka any type).
* @return <code>true</code> if this union is variant union, otherwise <code>false</code>.
*/
bool isVariant() const {return (fieldNames.size() == 0);}
/**
* Convert the union to a string and add it to builder.
* @param builder The string builder.
*/
virtual void toString(StringBuilder buf) const{toString(buf,0);}
/**
* Convert the union to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
virtual void toString(StringBuilder buf,int indentLevel) const;
virtual String getID() const;
virtual std::string getID() const;
virtual std::ostream& dump(std::ostream& o) const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
protected:
Union();
Union(StringArray const & fieldNames, FieldConstPtrArray const & fields, String const & id = DEFAULT_ID);
Union(StringArray const & fieldNames, FieldConstPtrArray const & fields, std::string const & id = DEFAULT_ID);
private:
void toStringCommon(StringBuilder buf,int indentLevel) const;
StringArray fieldNames;
FieldConstPtrArray fields;
String id;
StringArray fieldNames;
FieldConstPtrArray fields;
std::string id;
virtual void dumpFields(std::ostream& o) const;
friend class FieldCreate;
friend class Structure;
};
/**
* This is a singlton class for creating introspection interfaces.
*/
class FieldCreate;
typedef std::tr1::shared_ptr<FieldCreate> FieldCreatePtr;
@@ -751,8 +791,8 @@ public:
/**
* Complete the creation of a nested object.
* @see #addNestedStructure(String)
* @see #addNestedUnion(String)
* @see #addNestedStructure(std::string)
* @see #addNestedUnion(std::string)
* @return a previous (parent) {@code FieldBuilder}.
*/
FieldBuilderPtr endNested();
@@ -784,6 +824,9 @@ private:
};
/**
* This is a singleton class for creating introspection interfaces.
*/
class epicsShareClass FieldCreate {
public:
static FieldCreatePtr getFieldCreate();
@@ -812,6 +855,11 @@ public:
* @return An {@code Array} Interface for the newly created object.
*/
StructureArrayConstPtr createStructureArray(StructureConstPtr const & structure) const;
/**
* Create a {@code Structure} field.
* @return a {@code Structure} interface for the newly created object.
*/
StructureConstPtr createStructure () const;
/**
* Create a {@code Structure} field.
* @param fieldNames The array of {@code fieldNames} for the structure.
@@ -829,7 +877,7 @@ public:
* @return a {@code Structure} interface for the newly created object.
*/
StructureConstPtr createStructure (
String const & id,
std::string const & id,
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const;
/**
@@ -866,7 +914,7 @@ public:
* @return a {@code Union} interface for the newly created object.
*/
UnionConstPtr createUnion (
String const & id,
std::string const & id,
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const;
/**
@@ -878,7 +926,7 @@ public:
*/
StructureConstPtr appendField(
StructureConstPtr const & structure,
String const & fieldName, FieldConstPtr const & field) const;
std::string const & fieldName, FieldConstPtr const & field) const;
/**
* Append fields to a structure.
* @param structure The structure to which the fields appended.
@@ -951,8 +999,27 @@ OP(pvUInt, uint32)
OP(pvULong, uint64)
OP(pvFloat, float)
OP(pvDouble, double)
OP(pvString, String)
OP(pvString, std::string)
#undef OP
struct ScalarHashFunction {
size_t operator() (const Scalar& scalar) const { return scalar.getScalarType(); }
};
struct ScalarArrayHashFunction {
size_t operator() (const ScalarArray& scalarArray) const { return 0x10 | scalarArray.getElementType(); }
};
struct StructureHashFunction {
size_t operator() (const Structure& /*structure*/) const { return 0; }
// TODO hash
// final int PRIME = 31;
// return PRIME * Arrays.hashCode(fieldNames) + Arrays.hashCode(fields);
};
struct StructureArrayHashFunction {
size_t operator() (const StructureArray& structureArray) const { StructureHashFunction shf; return (0x10 | shf(*(structureArray.getStructure()))); }
};
}}
#endif /* PVINTROSPECT_H */

View File

@@ -17,68 +17,104 @@
namespace epics { namespace pvData {
/** @brief Copy a subarray from one PVValueArray to another.
* @warning The two PVValueArrays must both the same type
* @param from The source
* @param fromOffset The offset in the source
* @param to The destination
* @param toOffset The offset in the destination
* @param len The total number of elements to copy
/** @brief Copy a subarray from one scalar array to another.
* @warning The two scalar arrays must both be PVValueArrays of the same type.
* @param pvFrom The source array.
* @param fromOffset The offset in the source.
* @param fromStride The interval between elements in pvFrom.
* @param pvTo The destination array.
* @param toOffset The offset in the destination.
* @param toStride The interval between elements in pvTo.
* @param count The total number of elements to copy from pvFrom to pvTo.
*/
template<typename T>
void copy(
epicsShareExtern void copy(
PVValueArray<T> & pvFrom,
size_t fromOffset,
size_t fromStride,
PVValueArray<T> & pvTo,
size_t toOffset,
size_t len);
size_t toStride,
size_t count);
/** @brief Copy a subarray from one scalar array to another.
* @warning The two scalar arrays must both be PVValueArrays of the same type
* @param from The source
* @param fromOffset The offset in the source
* @param to The destination
* @param toOffset The offset in the destination
* @param len The total number of elements to copy
* @warning The two scalar arrays must both be PVValueArrays of the same type.
* @param pvFrom The source array.
* @param fromOffset The offset in the source.
* @param fromStride The interval between elements in pvFrom.
* @param pvTo The destination array.
* @param toOffset The offset in the destination.
* @param toStride The interval between elements in pvTo.
* @param count The total number of elements to copy from pvFrom to pvTo.
*/
epicsShareExtern void copy(
PVScalarArray & from,
PVScalarArray & pvFrom,
size_t fromOffset,
PVScalarArray & to,
size_t fromStride,
PVScalarArray & pvTo,
size_t toOffset,
size_t len);
size_t toStride,
size_t count);
/** @brief Copy a subarray from one structure array to another.
* @warning The two structure arrays must have the same
* structure introspection interface.
* @param from The source
* @param fromOffset The offset in the source
* @param to The destination
* @param toOffset The offset in the destination
* @param len The total number of elements to copy
* @param pvFrom The source array.
* @param fromOffset The offset in the source.
* @param fromStride The interval between elements in pvFrom.
* @param pvTo The destination array.
* @param toOffset The offset in the destination.
* @param toStride The interval between elements in pvTo.
* @param count The total number of elements to copy from pvFrom to pvTo.
*/
epicsShareExtern void copy(
PVStructureArray & from,
PVStructureArray & pvFrom,
size_t fromOffset,
PVStructureArray & to,
size_t fromStride,
PVStructureArray & pvToo,
size_t toOffset,
size_t len);
size_t toStride,
size_t count);
/** @brief Copy a subarray from one array to another.
* @warning The two arrays must have the same
* introspection interface.
* @param from The source
* @param fromOffset The offset in the source
* @param to The destination
* @param toOffset The offset in the destination
* @param len The total number of elements to copy
* @param pvFrom The source array.
* @param fromOffset The offset in the source.
* @param fromStride The interval between elements in pvFrom.
* @param pvTo The destination array.
* @param toOffset The offset in the destination.
* @param toStride The interval between elements in pvTo.
* @param count The total number of elements to copy from pvFrom to pvTo.
*/
epicsShareExtern void copy(
PVArray & from,
PVArray & pvFrom,
size_t fromOffset,
PVArray & to,
size_t fromStride,
PVArray & pvToo,
size_t toOffset,
size_t len);
size_t toStride,
size_t count);
/** @brief Copy a subarray from one array to another.
* @warning The two arrays must have the same
* introspection interface.
* @param pvFrom The source array.
* @param fromOffset The offset in the source.
* @param fromStride The interval between elements in pvFrom.
* @param pvTo The destination array.
* @param toOffset The offset in the destination.
* @param toStride The interval between elements in pvTo.
* @param count The total number of elements to copy from pvFrom to pvTo.
*/
epicsShareExtern void copy(
PVArray::shared_pointer const & pvFrom,
size_t fromOffset,
size_t fromStride,
PVArray::shared_pointer & pvToo,
size_t toOffset,
size_t toStride,
size_t count);
}}

View File

@@ -93,358 +93,24 @@ typedef uint64_t uint64;
// float and double are types
/**
* A string
*/
typedef std::string String;
/**
* A boolean array.
*/
typedef std::vector<uint8> BooleanArray;
typedef std::tr1::shared_ptr<BooleanArray> BooleanArrayPtr;
/* get is same is ubyte*/
typedef std::vector<uint8>::iterator BooleanArray_iterator;
typedef std::vector<uint8>::const_iterator BooleanArray_const_iterator;
/**
* A byte array.
*/
typedef std::vector<int8> ByteArray;
typedef std::tr1::shared_ptr<ByteArray> ByteArrayPtr;
inline int8 * get(ByteArray &value)
{
return &value[0];
}
inline int8 const * get(ByteArray const &value)
{
return static_cast<int8 const *>(&value[0]);
}
inline int8 * get(ByteArrayPtr &value)
{
return get(*value.get());
}
inline int8 const * get(ByteArrayPtr const &value)
{
return get(*value.get());
}
inline ByteArray & getVector(ByteArrayPtr &value)
{
return *value.get();
}
inline ByteArray const & getVector(ByteArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<int8>::iterator ByteArray_iterator;
typedef std::vector<int8>::const_iterator ByteArray_const_iterator;
/**
* A short array.
*/
typedef std::vector<int16> ShortArray;
typedef std::tr1::shared_ptr<ShortArray> ShortArrayPtr;
inline int16 * get(ShortArray &value)
{
return &value[0];
}
inline int16 const * get(ShortArray const &value)
{
return static_cast<int16 const *>(&value[0]);
}
inline int16 * get(ShortArrayPtr &value)
{
return get(*value.get());
}
inline int16 const * get(ShortArrayPtr const &value)
{
return get(*value.get());
}
inline ShortArray & getVector(ShortArrayPtr &value)
{
return *value.get();
}
inline ShortArray const & getVector(ShortArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<int16>::iterator ShortArray_iterator;
typedef std::vector<int16>::const_iterator ShortArray_const_iterator;
/**
* A int array.
*/
typedef std::vector<int32> IntArray;
typedef std::tr1::shared_ptr<IntArray> IntArrayPtr;
inline int32 * get(IntArray &value)
{
return &value[0];
}
inline int32 const * get(IntArray const &value)
{
return static_cast<int32 const *>(&value[0]);
}
inline int32 * get(IntArrayPtr &value)
{
return get(*value.get());
}
inline int32 const * get(IntArrayPtr const &value)
{
return get(*value.get());
}
inline IntArray & getVector(IntArrayPtr &value)
{
return *value.get();
}
inline IntArray const & getVector(IntArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<int32>::iterator IntArray_iterator;
typedef std::vector<int32>::const_iterator IntArray_const_iterator;
/**
* A long array.
*/
typedef std::vector<int64> LongArray;
typedef std::tr1::shared_ptr<LongArray> LongArrayPtr;
inline int64 * get(LongArray &value)
{
return &value[0];
}
inline int64 const * get(LongArray const &value)
{
return static_cast<int64 const *>(&value[0]);
}
inline int64 * get(LongArrayPtr &value)
{
return get(*value.get());
}
inline int64 const * get(LongArrayPtr const &value)
{
return get(*value.get());
}
inline LongArray & getVector(LongArrayPtr &value)
{
return *value.get();
}
inline LongArray const & getVector(LongArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<int64>::iterator LongArray_iterator;
typedef std::vector<int64>::const_iterator LongArray_const_iterator;
/**
* An unsigned byte array.
*/
typedef std::vector<uint8> UByteArray;
typedef std::tr1::shared_ptr<UByteArray> UByteArrayPtr;
inline uint8 * get(UByteArray &value)
{
return &value[0];
}
inline uint8 const * get(UByteArray const &value)
{
return static_cast<uint8 const *>(&value[0]);
}
inline uint8 * get(UByteArrayPtr &value)
{
return get(*value.get());
}
inline uint8 const * get(UByteArrayPtr const &value)
{
return get(*value.get());
}
inline UByteArray & getVector(UByteArrayPtr &value)
{
return *value.get();
}
inline UByteArray const & getVector(UByteArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<uint8>::iterator UByteArray_iterator;
typedef std::vector<uint8>::const_iterator UByteArray_const_iterator;
/**
* An unsigned short array.
*/
typedef std::vector<uint16> UShortArray;
typedef std::tr1::shared_ptr<UShortArray> UShortArrayPtr;
inline uint16 * get(UShortArray &value)
{
return &value[0];
}
inline uint16 const * get(UShortArray const &value)
{
return static_cast<uint16 const *>(&value[0]);
}
inline uint16 * get(UShortArrayPtr &value)
{
return get(*value.get());
}
inline uint16 const * get(UShortArrayPtr const &value)
{
return get(*value.get());
}
inline UShortArray & getVector(UShortArrayPtr &value)
{
return *value.get();
}
inline UShortArray const & getVector(UShortArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<uint16>::iterator UShortArray_iterator;
typedef std::vector<uint16>::const_iterator UShortArray_const_iterator;
/**
* An unsigned int array.
*/
typedef std::vector<uint32> UIntArray;
typedef std::tr1::shared_ptr<UIntArray> UIntArrayPtr;
inline uint32 * get(UIntArray &value)
{
return &value[0];
}
inline uint32 const * get(UIntArray const &value)
{
return static_cast<uint32 const *>(&value[0]);
}
inline uint32 * get(UIntArrayPtr &value)
{
return get(*value.get());
}
inline uint32 const * get(UIntArrayPtr const &value)
{
return get(*value.get());
}
inline UIntArray & getVector(UIntArrayPtr &value)
{
return *value.get();
}
inline UIntArray const & getVector(UIntArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<uint32>::iterator UIntArray_iterator;
typedef std::vector<uint32>::const_iterator UIntArray_const_iterator;
/**
* An unsigned long array.
*/
typedef std::vector<uint64> ULongArray;
typedef std::tr1::shared_ptr<ULongArray> ULongArrayPtr;
inline uint64 * get(ULongArray &value)
{
return &value[0];
}
inline uint64 const * get(ULongArray const &value)
{
return static_cast<uint64 const *>(&value[0]);
}
inline uint64 * get(ULongArrayPtr &value)
{
return get(*value.get());
}
inline uint64 const * get(ULongArrayPtr const &value)
{
return get(*value.get());
}
inline ULongArray & getVector(ULongArrayPtr &value)
{
return *value.get();
}
inline ULongArray const & getVector(ULongArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<uint64>::iterator ULongArray_iterator;
typedef std::vector<uint64>::const_iterator ULongArray_const_iterator;
/**
* A float array.
*/
typedef std::vector<float> FloatArray;
typedef std::tr1::shared_ptr<FloatArray> FloatArrayPtr;
inline float * get(FloatArray &value)
{
return &value[0];
}
inline float const * get(FloatArray const &value)
{
return static_cast<float const *>(&value[0]);
}
inline float * get(FloatArrayPtr &value)
{
return get(*value.get());
}
inline float const * get(FloatArrayPtr const &value)
{
return get(*value.get());
}
inline FloatArray & getVector(FloatArrayPtr &value)
{
return *value.get();
}
inline FloatArray const & getVector(FloatArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<float>::iterator FloatArray_iterator;
typedef std::vector<float>::const_iterator FloatArray_const_iterator;
/**
* A double array.
*/
typedef std::vector<double> DoubleArray;
typedef std::tr1::shared_ptr<DoubleArray> DoubleArrayPtr;
inline double * get(DoubleArray &value)
{
return &value[0];
}
inline double const * get(DoubleArray const &value)
{
return static_cast<double const *>(&value[0]);
}
inline double * get(DoubleArrayPtr &value)
{
return get(*value.get());
}
inline double const * get(DoubleArrayPtr const &value)
{
return get(*value.get());
}
inline DoubleArray & getVector(DoubleArrayPtr &value)
{
return *value.get();
}
inline DoubleArray const & getVector(DoubleArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<double>::iterator DoubleArray_iterator;
typedef std::vector<double>::const_iterator DoubleArray_const_iterator;
/**
* A string array.
*/
typedef std::vector<String> StringArray;
typedef std::vector<std::string> StringArray;
typedef std::tr1::shared_ptr<StringArray> StringArrayPtr;
inline String * get(StringArray &value)
inline std::string * get(StringArray &value)
{
return &value[0];
}
inline String const * get(StringArray const &value)
inline std::string const * get(StringArray const &value)
{
return static_cast<String const *>(&value[0]);
return static_cast<std::string const *>(&value[0]);
}
inline String * get(StringArrayPtr &value)
inline std::string * get(StringArrayPtr &value)
{
return get(*value.get());
}
inline String const * get(StringArrayPtr const &value)
inline std::string const * get(StringArrayPtr const &value)
{
return get(*value.get());
}
@@ -456,13 +122,8 @@ inline StringArray const & getVector(StringArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<String>::iterator StringArray_iterator;
typedef std::vector<String>::const_iterator StringArray_const_iterator;
/**
* A convenience definition for toString methods
*/
typedef String * StringBuilder;
typedef std::vector<std::string>::iterator StringArray_iterator;
typedef std::vector<std::string>::const_iterator StringArray_const_iterator;
}}
#endif /* PVTYPE_H */

View File

@@ -20,6 +20,10 @@
namespace epics { namespace pvData {
class StandardField;
typedef std::tr1::shared_ptr<StandardField> StandardFieldPtr;
/**
* Standard Fields is a class or creating or sharing Field objects for standard fields.
* For each type of standard object two methods are defined:s
@@ -34,9 +38,9 @@ namespace epics { namespace pvData {
* For example the call:
* {@code
StructureConstPtr example = standardField->scalar(
String("value"),
std::string("value"),
pvDouble,
String("value,alarm,timeStamp"));
std::string("value,alarm,timeStamp"));
* }
* Will result in a Field definition that has the form: {@code
structure example
@@ -57,42 +61,161 @@ namespace epics { namespace pvData {
StandardField *standardField = getStandardField();
* }
*/
class StandardField;
typedef std::tr1::shared_ptr<StandardField> StandardFieldPtr;
class epicsShareClass StandardField {
public:
/**
* getStandardField returns the singleton.
* @return Shared pointer to StandardField.
*/
static StandardFieldPtr getStandardField();
~StandardField();
StructureConstPtr scalar(ScalarType type,String const & properties);
StructureConstPtr scalarArray(ScalarType elementType, String const & properties);
StructureConstPtr structureArray(StructureConstPtr const & structure,String const & properties);
/** Create a structure that has a scalar value field.
* @param type The type.
* @param properties A comma separated list of properties.
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
* @return The const shared pointer to the structure.
*/
StructureConstPtr scalar(ScalarType type,std::string const & properties);
/** Create a structure that has a union value field.
* @param punion The interface for value field.
* @param properties A comma separated list of properties.
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
* @return The const shared pointer to the structure.
*/
StructureConstPtr regUnion(
UnionConstPtr const & punion,
std::string const & properties);
/** Create a structure that has a varient union value field.
* @param properties A comma separated list of properties.
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
* @return The const shared pointer to the structure.
*/
StructureConstPtr variantUnion(std::string const & properties);
/** Create a structure that has a scalarArray value field.
* @param type The type.
* @param properties A comma separated list of properties.
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
* @return The const shared pointer to the structure.
*/
StructureConstPtr scalarArray(ScalarType elementType, std::string const & properties);
/** Create a structure that has a structureArray value field.
* @param type The type.
* @param properties A comma separated list of properties.
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
* @return The const shared pointer to the structure.
*/
StructureConstPtr structureArray(
StructureConstPtr const & structure,
std::string const & properties);
/** Create a structure that has a unionArray value field.
* @param type The type.
* @param properties A comma separated list of properties.
* This is some combination of "alarm,timeStamp,display,control".
* @return The const shared pointer to the structure.
*/
StructureConstPtr unionArray(
UnionConstPtr const & punion,
std::string const & properties);
/** Create a structure that has an enumerated structure value field.
* The id for the structure is "enum-t".
* @return The const shared pointer to the structure.
*/
StructureConstPtr enumerated();
StructureConstPtr enumerated(String const & properties);
/** Create a structure that has an enumerated structure value field
* The id for the structure is "uri:ev4:nt/2012/pwd:NTEnum".
* @param properties A comma separated list of properties.
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
* @return The const shared pointer to the structure.
*/
StructureConstPtr enumerated(std::string const & properties);
/**
* create an alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr alarm();
/**
* create a timeStamp structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr timeStamp();
/**
* create a display structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr display();
/**
* create a control structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr control();
/**
* create a boolean alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr booleanAlarm();
/**
* create a byte alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr byteAlarm();
/**
* create a unsigned byte alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr ubyteAlarm();
/**
* create a short alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr shortAlarm();
/**
* create a unsigned short alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr ushortAlarm();
/**
* create an int alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr intAlarm();
/**
* create a unsigned int alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr uintAlarm();
/**
* create a long alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr longAlarm();
/**
* create a unsigned long alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr ulongAlarm();
/**
* create a float alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr floatAlarm();
/**
* create a double alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr doubleAlarm();
/**
* create an enumerated alarm structure
* @return The const shared pointer to the structure.
*/
StructureConstPtr enumeratedAlarm();
private:
StandardField();
void init();
StructureConstPtr createProperties(String id,FieldConstPtr field,String properties);
StructureConstPtr createProperties(
std::string id,FieldConstPtr field,std::string properties);
FieldCreatePtr fieldCreate;
String notImplemented;
String valueFieldName;
std::string notImplemented;
std::string valueFieldName;
StructureConstPtr alarmField;
StructureConstPtr timeStampField;
StructureConstPtr displayField;

View File

@@ -20,6 +20,10 @@
#include <shareLib.h>
namespace epics { namespace pvData {
class StandardPVField;
typedef std::tr1::shared_ptr<StandardPVField> StandardPVFieldPtr;
/**
* StandardPVField is a class or creating standard data fields.
* Like class StandardField it has two forms of the methods which create a fields:
@@ -31,25 +35,67 @@ namespace epics { namespace pvData {
StandardPVField *standardPVField = getStandardPVField();
* }
*/
class StandardPVField;
typedef std::tr1::shared_ptr<StandardPVField> StandardPVFieldPtr;
class epicsShareClass StandardPVField : private NoDefaultMethods {
public:
/**
* getStandardPVField returns the singleton.
* @return Shared pointer to StandardPVField.
*/
static StandardPVFieldPtr getStandardPVField();
~StandardPVField();
PVStructurePtr scalar(ScalarType type,String const & properties);
PVStructurePtr scalarArray(ScalarType elementType, String const & properties);
PVStructurePtr structureArray(StructureConstPtr const &structure,String const & properties);
/**
* Create a structure that has a scalar value field.
* @param type The type.
* @param properties A comma separated list of properties.
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
* @return The const shared pointer to the structure.
*/
PVStructurePtr scalar(ScalarType type,std::string const & properties);
/**
* Create a structure that has a scalar array value field.
* @param type The type.
* @param properties A comma separated list of properties.
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
* @return The const shared pointer to the structure.
*/
PVStructurePtr scalarArray(ScalarType elementType, std::string const & properties);
/**
* Create a structure that has a structure array value field.
* @param type The type.
* @param properties A comma separated list of properties.
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
* @return The const shared pointer to the structure.
*/
PVStructurePtr structureArray(StructureConstPtr const &structure,std::string const & properties);
/**
* Create a structure that has a union array value field.
* @param type The type.
* @param properties A comma separated list of properties.
* This is some combination of "alarm,timeStamp,display,control,valueAlarm".
* @return The const shared pointer to the structure.
*/
PVStructurePtr unionArray(UnionConstPtr const &punion,std::string const & properties);
/**
* Create a structure that has an enumerated structure value field.
* The id for the structure is "enum_t".
* @param choices This is a StringArray of choices.
* @return The const shared pointer to the structure.
*/
PVStructurePtr enumerated(StringArray const &choices);
PVStructurePtr enumerated(StringArray const &choices, String const & properties);
/**
* Create a structure that has an enumerated structure value field.
* The id for the structure is "uri:ev4:nt/2012/pwd:NTEnum".
* @param choices This is a StringArray of choices.
* @param properties A comma separated list of properties.
* @return The const shared pointer to the structure.
*/
PVStructurePtr enumerated(StringArray const &choices, std::string const & properties);
private:
StandardPVField();
StandardFieldPtr standardField;
FieldCreatePtr fieldCreate;
PVDataCreatePtr pvDataCreate;
String notImplemented;
std::string notImplemented;
};
epicsShareExtern StandardPVFieldPtr getStandardPVField();

View File

@@ -3,5 +3,6 @@ include $(TOP)/configure/CONFIG
DIRS += misc
DIRS += pv
DIRS += property
DIRS += copy
include $(TOP)/configure/RULES_DIRS

22
testApp/copy/Makefile Normal file
View File

@@ -0,0 +1,22 @@
TOP=../..
include $(TOP)/configure/CONFIG
PROD_HOST += testCreateRequest
testCreateRequest_SRCS = testCreateRequest.cpp
testCreateRequest_LIBS = pvData Com
TESTS += testCreateRequest
PROD_HOST += testPVCopy
testPVCopy_SRCS += testPVCopy.cpp
testPVCopy_LIBS += pvData Com
TESTS += testPVCopy
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE

View File

@@ -0,0 +1,328 @@
/* testCreateRequest.cpp */
/* Author: Matej Sekoranja Date: 2010.12.27 */
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <epicsUnitTest.h>
#include <testMain.h>
#include <pv/createRequest.h>
using namespace epics::pvData;
using std::string;
using std::cout;
using std::endl;
static bool debug = false;
void testCreateRequest() {
printf("testCreateRequest... \n");
CreateRequest::shared_pointer createRequest = CreateRequest::create();
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;}
testOk1(pvRequest->getStructure()->getNumberFields()==0);
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();
testOk(sval.compare("b")==0,"record.a = b");
pvString = pvRequest->getSubField<PVString>("record.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);
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;}
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;}
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);
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;}
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);
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);
pvString = pvRequest->getSubField<PVString>("field.a.a._options.a");
sval = pvString->get();
testOk(sval.compare("b")==0,"field.a.a._options.a = b");
pvString = pvRequest->getSubField<PVString>("field.a.a.a.a._options.a");
sval = pvString->get();
testOk(sval.compare("b")==0,"field.a.a.a.a._options.a = b");
pvString = pvRequest->getSubField<PVString>("field.b.a._options.a");
sval = pvString->get();
testOk(sval.compare("b")==0,"field.b.a._options.a = b");
testOk1(pvRequest->getSubField("field.b.a.a")!=NULL);
testOk1(pvRequest->getSubField("field.b.a.b")!=NULL);
if(debug) { cout << pvRequest->dumpValue(cout) << endl;}
testPass("request %s",request.c_str());
request = "alarm,timeStamp,power.value";
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;}
testPass("request %s",request.c_str());
request = "record[process=true]field(alarm,timeStamp,power.value)";
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");
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;}
testPass("request %s",request.c_str());
request = "record[process=true]field(alarm,timeStamp[algorithm=onChange,causeMonitor=false],power{value,alarm})";
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");
sval = pvString->get();
testOk(sval.compare("true")==0,"record.process = true");
testOk1(pvRequest->getSubField("field.alarm")!=NULL);
testOk1(pvRequest->getSubField("field.timeStamp")!=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;}
testPass("request %s",request.c_str());
request = "record[int=2,float=3.14159]field(alarm,timeStamp[shareData=true],power.value)";
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");
sval = pvString->get();
testOk(sval.compare("2")==0,"record.int = 2");
pvString = pvRequest->getSubField<PVString>("record.float");
sval = pvString->get();
testOk(sval.compare("3.14159")==0,"record.float = 3.14159");
testOk1(pvRequest->getSubField("field.alarm")!=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;}
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})";
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;}
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}"
+ "})";
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;}
testPass("request %s",request.c_str());
request = string("record[process=true,xxx=yyy]")
+ "putField(power.value)"
+ "getField(alarm,timeStamp,power{value,alarm},"
+ "current{value,alarm},voltage{value,alarm},"
+ "ps0{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}},"
+ "ps1{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}}"
+ ")";
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;}
testPass("request %s",request.c_str());
request = "a{b{c{d}}}";
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;}
testPass("request %s",request.c_str());
request = string("record[process=true,xxx=yyy]")
+ "putField(power.value)"
+ "getField(alarm,timeStamp,power{value,alarm},"
+ "current{value,alarm},voltage{value,alarm},"
+ "ps0{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}},"
+ "ps1{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}"
+ ")";
if(debug) { cout << endl << "Error Expected for next call!!" << endl;}
if(debug) { cout << string("request") <<endl << request <<endl;}
pvRequest = createRequest->createRequest(request);
assert(pvRequest.get()==NULL);
if(debug) {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;}
pvRequest = createRequest->createRequest(request);
assert(pvRequest.get()==NULL);
if(debug) { cout << "reason " << createRequest->getMessage() << endl;}
testPass("request %s",request.c_str());
}
MAIN(testCreateRequest)
{
testPlan(111);
testCreateRequest();
return testDone();
}

361
testApp/copy/testPVCopy.cpp Normal file
View File

@@ -0,0 +1,361 @@
/*testPVCopyMain.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
/* Author: Marty Kraimer */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <memory>
#include <iostream>
#include <epicsUnitTest.h>
#include <testMain.h>
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/convert.h>
#include <pv/pvCopy.h>
#include <pv/createRequest.h>
using namespace std;
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
static bool debug = true;
static void testPVScalar(
string const & valueNameMaster,
string const & valueNameCopy,
PVStructurePtr const & pvMaster,
PVCopyPtr const & pvCopy)
{
PVStructurePtr pvStructureCopy;
PVFieldPtr pvField;
PVScalarPtr pvValueMaster;
PVScalarPtr pvValueCopy;
BitSetPtr bitSet;
size_t offset;
ConvertPtr convert = getConvert();
pvField = pvMaster->getSubField(valueNameMaster);
pvValueMaster = static_pointer_cast<PVScalar>(pvField);
convert->fromDouble(pvValueMaster,.04);
StructureConstPtr structure = pvCopy->getStructure();
if(debug) { cout << "structure from copy" << endl << *structure << endl; }
pvStructureCopy = pvCopy->createPVStructure();
pvField = pvStructureCopy->getSubField(valueNameCopy);
pvValueCopy = static_pointer_cast<PVScalar>(pvField);
bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
pvCopy->initCopy(pvStructureCopy, bitSet);
if(debug) { cout << "after initCopy pvValueCopy " << convert->toDouble(pvValueCopy); }
if(debug) { cout << endl; }
convert->fromDouble(pvValueMaster,.06);
testOk1(convert->toDouble(pvValueCopy)==.04);
pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet);
testOk1(convert->toDouble(pvValueCopy)==.06);
testOk1(bitSet->get(pvValueCopy->getFieldOffset()));
if(debug) { cout << "after put(.06) pvValueCopy " << convert->toDouble(pvValueCopy); }
if(debug) { cout << " bitSet " << *bitSet; }
if(debug) { cout << endl; }
offset = pvCopy->getCopyOffset(pvValueMaster);
if(debug) { cout << "getCopyOffset() " << offset; }
if(debug) { cout << " pvValueCopy->getOffset() " << pvValueCopy->getFieldOffset(); }
if(debug) { cout << " pvValueMaster->getOffset() " << pvValueMaster->getFieldOffset(); }
if(debug) { cout << " bitSet " << *bitSet; }
if(debug) { cout << endl; }
bitSet->clear();
convert->fromDouble(pvValueMaster,1.0);
if(debug) { cout << "before updateCopyFromBitSet"; }
if(debug) { cout << " masterValue " << convert->toDouble(pvValueMaster); }
if(debug) { cout << " copyValue " << convert->toDouble(pvValueCopy); }
if(debug) { cout << " bitSet " << *bitSet; }
if(debug) { cout << endl; }
bitSet->set(0);
testOk1(convert->toDouble(pvValueCopy)==0.06);
pvCopy->updateCopyFromBitSet(pvStructureCopy,bitSet);
testOk1(convert->toDouble(pvValueCopy)==1.0);
if(debug) { cout << "after updateCopyFromBitSet"; }
if(debug) { cout << " masterValue " << convert->toDouble(pvValueMaster); }
if(debug) { cout << " copyValue " << convert->toDouble(pvValueCopy); }
if(debug) { cout << " bitSet " << *bitSet; }
if(debug) { cout << endl; }
convert->fromDouble(pvValueCopy,2.0);
bitSet->set(0);
if(debug) { cout << "before updateMaster"; }
if(debug) { cout << " masterValue " << convert->toDouble(pvValueMaster); }
if(debug) { cout << " copyValue " << convert->toDouble(pvValueCopy); }
if(debug) { cout << " bitSet " << *bitSet; }
if(debug) { cout << endl; }
testOk1(convert->toDouble(pvValueMaster)==1.0);
pvCopy->updateMaster(pvStructureCopy,bitSet);
testOk1(convert->toDouble(pvValueMaster)==2.0);
if(debug) { cout << "after updateMaster"; }
if(debug) { cout << " masterValue " << convert->toDouble(pvValueMaster); }
if(debug) { cout << " copyValue " << convert->toDouble(pvValueCopy); }
if(debug) { cout << " bitSet " << *bitSet; }
if(debug) { cout << endl; }
}
static void testPVScalarArray(
ScalarType scalarType,
string const & valueNameMaster,
string const & valueNameCopy,
PVStructurePtr const & pvMaster,
PVCopyPtr const & pvCopy)
{
PVStructurePtr pvStructureCopy;
PVScalarArrayPtr pvValueMaster;
PVScalarArrayPtr pvValueCopy;
BitSetPtr bitSet;
size_t offset;
size_t n = 5;
shared_vector<double> values(n);
shared_vector<const double> cvalues;
pvValueMaster = pvMaster->getScalarArrayField(valueNameMaster,scalarType);
for(size_t i=0; i<n; i++) values[i] = i;
const shared_vector<const double> xxx(freeze(values));
pvValueMaster->putFrom(xxx);
StructureConstPtr structure = pvCopy->getStructure();
if(debug) { cout << "structure from copy" << endl << *structure << endl;}
pvStructureCopy = pvCopy->createPVStructure();
pvValueCopy = pvStructureCopy->getScalarArrayField(valueNameCopy,scalarType);
bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
pvCopy->initCopy(pvStructureCopy, bitSet);
if(debug) { cout << "after initCopy pvValueCopy " << *pvValueCopy << endl; }
if(debug) { cout << endl; }
values.resize(n);
for(size_t i=0; i<n; i++) values[i] = i + .06;
const shared_vector<const double> yyy(freeze(values));
pvValueMaster->putFrom(yyy);
pvValueCopy->getAs(cvalues);
testOk1(cvalues[0]==0.0);
pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet);
pvValueCopy->getAs(cvalues);
testOk1(cvalues[0]==0.06);
if(debug) { cout << "after put(i+ .06) pvValueCopy " << *pvValueCopy << endl; }
if(debug) { cout << " bitSet " << *bitSet; }
if(debug) { cout << endl; }
offset = pvCopy->getCopyOffset(pvValueMaster);
if(debug) { cout << "getCopyOffset() " << offset; }
if(debug) { cout << " pvValueCopy->getOffset() " << pvValueCopy->getFieldOffset(); }
if(debug) { cout << " pvValueMaster->getOffset() " << pvValueMaster->getFieldOffset(); }
if(debug) { cout << " bitSet " << *bitSet; }
if(debug) { cout << endl; }
bitSet->clear();
values.resize(n);
for(size_t i=0; i<n; i++) values[i] = i + 1.0;
const shared_vector<const double> zzz(freeze(values));
pvValueMaster->putFrom(zzz);
if(debug) { cout << "before updateCopyFromBitSet"; }
if(debug) { cout << " masterValue " << *pvValueMaster << endl; }
if(debug) { cout << " copyValue " << *pvValueCopy << endl; }
if(debug) { cout << " bitSet " << *bitSet; }
if(debug) { cout << endl; }
bitSet->set(0);
pvValueCopy->getAs(cvalues);
testOk1(cvalues[0]==0.06);
pvCopy->updateCopyFromBitSet(pvStructureCopy,bitSet);
pvValueCopy->getAs(cvalues);
testOk1(cvalues[0]==1.0);
if(debug) { cout << "after updateCopyFromBitSet"; }
if(debug) { cout << " masterValue " << *pvValueMaster << endl; }
if(debug) { cout << " copyValue " << *pvValueCopy << endl; }
if(debug) { cout << " bitSet " << *bitSet; }
if(debug) { cout << endl; }
values.resize(n);
for(size_t i=0; i<n; i++) values[i] = i + 2.0;
const shared_vector<const double> ttt(freeze(values));
pvValueMaster->putFrom(ttt);
bitSet->set(0);
if(debug) { cout << "before updateMaster"; }
if(debug) { cout << " masterValue " << *pvValueMaster << endl; }
if(debug) { cout << " copyValue " << *pvValueCopy << endl; }
if(debug) { cout << " bitSet " << *bitSet; }
if(debug) { cout << endl; }
pvValueMaster->getAs(cvalues);
testOk1(cvalues[0]==2.0);
pvCopy->updateMaster(pvStructureCopy,bitSet);
pvValueMaster->getAs(cvalues);
testOk1(cvalues[0]==1.0);
if(debug) { cout << "before updateMaster"; }
if(debug) { cout << " masterValue " << *pvValueMaster << endl; }
if(debug) { cout << " copyValue " << *pvValueCopy << endl; }
if(debug) { cout << " bitSet " << *bitSet; }
if(debug) { cout << endl; }
}
static void scalarTest()
{
if(debug) { cout << endl << endl << "****scalarTest****" << endl; }
PVStructurePtr pvMaster;
string request;
PVStructurePtr pvRequest;
PVFieldPtr pvMasterField;
PVCopyPtr pvCopy;
string valueNameMaster;
string valueNameCopy;
StandardPVFieldPtr standardPVField = getStandardPVField();
pvMaster = standardPVField->scalar(pvDouble,"alarm,timeStamp,display");
valueNameMaster = request = "value";
CreateRequest::shared_pointer createRequest = CreateRequest::create();
pvRequest = createRequest->createRequest(request);
if(debug) { cout << "request " << request << endl; }
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "";
valueNameMaster = "value";
pvRequest = createRequest->createRequest(request);
if(debug) { cout << "request " << request << endl; }
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "alarm,timeStamp,value";
valueNameMaster = "value";
pvRequest = createRequest->createRequest(request);
if(debug) { cout << "request " << request << endl; }
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
}
static void arrayTest()
{
if(debug) { cout << endl << endl << "****arrayTest****" << endl; }
PVStructurePtr pvMaster;
string request;
PVStructurePtr pvRequest;
PVFieldPtr pvMasterField;
PVCopyPtr pvCopy;
string valueNameMaster;
string valueNameCopy;
CreateRequest::shared_pointer createRequest = CreateRequest::create();
StandardPVFieldPtr standardPVField = getStandardPVField();
pvMaster = standardPVField->scalarArray(pvDouble,"alarm,timeStamp");
valueNameMaster = request = "value";
pvRequest = createRequest->createRequest(request);
if(debug) { cout << "request " << request << endl; }
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "value";
testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "";
valueNameMaster = "value";
pvRequest = createRequest->createRequest(request);
if(debug) { cout << "request " << request << endl; }
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "value";
testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "alarm,timeStamp,value";
valueNameMaster = "value";
pvRequest = createRequest->createRequest(request);
if(debug) { cout << "request " << request << endl; }
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "value";
testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy);
}
static PVStructurePtr createPowerSupply()
{
FieldCreatePtr fieldCreate = getFieldCreate();
StandardFieldPtr standardField = getStandardField();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
size_t nfields = 5;
StringArray names;
names.reserve(nfields);
FieldConstPtrArray powerSupply;
powerSupply.reserve(nfields);
names.push_back("alarm");
powerSupply.push_back(standardField->alarm());
names.push_back("timeStamp");
powerSupply.push_back(standardField->timeStamp());
string properties("alarm,display");
names.push_back("voltage");
powerSupply.push_back(standardField->scalar(pvDouble,properties));
names.push_back("power");
powerSupply.push_back(standardField->scalar(pvDouble,properties));
names.push_back("current");
powerSupply.push_back(standardField->scalar(pvDouble,properties));
return pvDataCreate->createPVStructure(
fieldCreate->createStructure(names,powerSupply));
}
static void powerSupplyTest()
{
if(debug) { cout << endl << endl << "****powerSupplyTest****" << endl; }
PVStructurePtr pvMaster;
string request;
PVStructurePtr pvRequest;
PVFieldPtr pvMasterField;
PVCopyPtr pvCopy;
string builder;
string valueNameMaster;
string valueNameCopy;
CreateRequest::shared_pointer createRequest = CreateRequest::create();
pvMaster = createPowerSupply();
valueNameMaster = request = "power.value";
pvRequest = createRequest->createRequest(request);
if(debug) { cout << "request " << request << endl; }
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "power.value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "";
valueNameMaster = "power.value";
pvRequest = createRequest->createRequest(request);
if(debug) { cout << "request " << request << endl; }
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "power.value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "alarm,timeStamp,voltage.value,power.value,current.value";
valueNameMaster = "power.value";
pvRequest = createRequest->createRequest(request);
if(debug) { cout << "request " << request << endl; }
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "power.value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "alarm,timeStamp,voltage{value,alarm},power{value,alarm,display},current.value";
valueNameMaster = "power.value";
pvRequest = createRequest->createRequest(request);
if(debug) { cout << "request " << request << endl; }
if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; }
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "power.value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
}
MAIN(testPVCopy)
{
testPlan(67);
scalarTest();
arrayTest();
powerSupplyTest();
return testDone();
}

View File

@@ -12,12 +12,22 @@
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <sstream>
#include <pv/bitSet.h>
#include <epicsUnitTest.h>
#include <testMain.h>
using namespace epics::pvData;
using std::string;
static string toString(BitSet& bitSet)
{
std::ostringstream oss;
oss << bitSet;
return oss.str();
}
static void testGetSetClearFlip()
{
@@ -28,7 +38,7 @@ static void testGetSetClearFlip()
testOk1(b1->isEmpty());
testOk1(b1->cardinality() == 0);
// to string check
std::string str; b1->toString(&str);
string str = toString(*b1);
testOk1(str == "{}");
// one
@@ -37,7 +47,7 @@ static void testGetSetClearFlip()
testOk1(!b1->isEmpty());
testOk1(b1->cardinality() == 1);
// to string check
str.clear(); b1->toString(&str);
str = toString(*b1);
testOk1(str == "{3}");
// grow
@@ -45,34 +55,34 @@ static void testGetSetClearFlip()
b1->set(67);
b1->set(68);
testOk1(b1->cardinality() == 4);
str.clear(); b1->toString(&str);
str = toString(*b1);
testOk1(str == "{3, 66, 67, 68}");
// clear one
b1->clear(67);
testOk1(b1->cardinality() == 3);
str.clear(); b1->toString(&str);
str = toString(*b1);
testOk1(str == "{3, 66, 68}");
// flip
b1->flip(66);
b1->flip(130);
testOk1(b1->cardinality() == 3);
str.clear(); b1->toString(&str);
str = toString(*b1);
testOk1(str == "{3, 68, 130}");
// flip
b1->set(130, false);
b1->set(4, true);
testOk1(b1->cardinality() == 3);
str.clear(); b1->toString(&str);
str = toString(*b1);
testOk1(str == "{3, 4, 68}");
// clear all
b1->clear();
testOk1(b1->isEmpty());
testOk1(b1->cardinality() == 0);
str.clear(); b1->toString(&str);
str = toString(*b1);
testOk1(str == "{}");
delete b1;
@@ -101,11 +111,11 @@ static void testOperators()
b2.set(106);
b2.set(105);
b1 |= b2;
std::string str; b1.toString(&str);
string str = toString(b1);
testOk1(str == "{1, 65, 105, 106}");
b1.clear();
b1 |= b2;
str.clear(); b1.toString(&str);
str = toString(b1);
testOk1(str == "{1, 65, 105, 106}");
// AND test
@@ -134,7 +144,7 @@ static void testOperators()
b2.clear(); b2.set(66); b2.set(128);
BitSet b3; b3.set(128); b3.set(520);
b1.or_and(b2, b3);
str.clear(); b1.toString(&str);
str = toString(b1);
testOk1(str == "{2, 128}");
}

View File

@@ -21,6 +21,7 @@
#include <pv/pvIntrospect.h>
using namespace epics::pvData;
using std::string;
using std::cout;
void testBasicOperations() {
@@ -197,7 +198,7 @@ void testBasicOperations() {
testOk1(buff->getPosition()==6);
testOk1(strncmp(&src[2],&dst[2],6)==0);
cout<<" First 10 characters of destination: >>"<<String(dst, 10)<<"<<\n";
cout<<" First 10 characters of destination: >>"<<string(dst, 10)<<"<<\n";
delete buff;

View File

@@ -21,6 +21,7 @@
#include <epicsAssert.h>
using namespace epics::pvData;
using std::string;
using std::cout;
using std::endl;
@@ -28,8 +29,8 @@ static StandardPVFieldPtr standardPVField = getStandardPVField();
void test()
{
String buffer;
String properties("alarm,timeStamp,display");
string buffer;
string properties("alarm,timeStamp,display");
PVStructurePtr pvStructure = standardPVField->scalar(pvDouble,properties);
PVDoublePtr pvValue = pvStructure->getDoubleField("value");
uint32 valueOffset = (uint32) pvValue->getFieldOffset();

View File

@@ -51,6 +51,7 @@
#define DOUBLE_MIN_VALUE std::numeric_limits<double>::min()
using namespace epics::pvData;
using std::string;
namespace {
@@ -135,12 +136,10 @@ void serializationTest(PVFieldPtr const & field) {
testPass("Serialization round trip OK");
else {
testFail("Serialization round trip did not match!");
std::string buf;
field->toString(&buf);
testDiag("Expected: %s", buf.c_str());
buf.clear();
deserializedField->toString(&buf);
testDiag("Found: %s", buf.c_str());
std::ostringstream oss;
oss << "Expected: " << *field << std::endl;
oss << "Found : " << *deserializedField << std::endl;
testDiag("Found: %s", oss.str().c_str());
}
}
@@ -300,15 +299,13 @@ void testScalar() {
serializationTest(pvString);
// huge string test
pvString->put(String(10000, 'a'));
pvString->put(string(10000, 'a'));
serializationTest(pvString);
}
template<typename PVT>
void testArrayType(const typename PVT::value_type* rdata, size_t len)
{
typedef typename PVT::value_type value_type;
typename PVT::svector empty(0), data(len);
std::copy(rdata, rdata+len, data.begin());
@@ -349,7 +346,7 @@ static const float fdata[] = { (float)0.0, (float)1.1, (float)2.3, (float)-1.4,
FLOAT_MAX_VALUE, FLOAT_MAX_VALUE-(float)123456.789,
FLOAT_MIN_VALUE+(float)1.1, FLOAT_MIN_VALUE };
static const String sdata[] = {
static const string sdata[] = {
"",
"a",
"a b",
@@ -357,7 +354,7 @@ static const String sdata[] = {
"test",
"smile",
"this is a little longer string... maybe a little but longer... this makes test better",
String(10000, 'b')
string(10000, 'b')
};
void testArray() {
@@ -703,10 +700,10 @@ void testIntrospectionSerialization()
}
void testStringCopy() {
String s1 = "abc";
String s2 = s1;
string s1 = "abc";
string s2 = s1;
if (s1.c_str() != s2.c_str())
testDiag("implementation of epics::pvData::String assignment operator does not share content");
testDiag("implementation of string assignment operator does not share content");
}
} // end namespace

View File

@@ -18,6 +18,8 @@
#include "pv/sharedVector.h"
using std::string;
static void testEmpty()
{
testDiag("Test empty vector");
@@ -376,7 +378,7 @@ static void testNonPOD()
{
testDiag("Test vector of non-POD types");
epics::pvData::shared_vector<std::string> strings(6);
epics::pvData::shared_vector<string> strings(6);
epics::pvData::shared_vector<std::tr1::shared_ptr<dummyStruct> > structs(5);
testOk1(strings[0].empty());
@@ -406,7 +408,7 @@ static void testVectorConvert()
epics::pvData::shared_vector<int> ints(6, 42), moreints;
epics::pvData::shared_vector<float> floats;
epics::pvData::shared_vector<std::string> strings;
epics::pvData::shared_vector<string> strings;
epics::pvData::shared_vector<void> voids;
testOk1(ints.unique());
@@ -435,7 +437,7 @@ static void testVectorConvert()
// convert from void uses shared_vector<void>::original_type()
// to find that the actual type is 'int'.
// returns a new vector
strings = epics::pvData::shared_vector_convert<std::string>(voids);
strings = epics::pvData::shared_vector_convert<string>(voids);
voids.clear();

View File

@@ -27,8 +27,9 @@
#include <pv/timeFunction.h>
using namespace epics::pvData;
using std::string;
static String actionName("action");
static string actionName("action");
class Action;
typedef std::tr1::shared_ptr<Action> ActionPtr;
@@ -101,7 +102,7 @@ private:
typedef std::tr1::shared_ptr<Basic> BasicPtr;
static void testBasic() {
ExecutorPtr executor(new Executor(String("basic"),middlePriority));
ExecutorPtr executor(new Executor(string("basic"),middlePriority));
BasicPtr basic( new Basic(executor));
basic->run();
printf("testBasic PASSED\n");
@@ -130,7 +131,7 @@ typedef std::tr1::shared_ptr<MyFunc> MyFuncPtr;
#ifdef TESTTHREADCONTEXT
static void testThreadContext() {
ExecutorPtr executor(new Executor(String("basic"),middlePriority));
ExecutorPtr executor(new Executor(string("basic"),middlePriority));
BasicPtr basic(new Basic(executor));
MyFuncPtr myFunc(new MyFunc(basic));
TimeFunctionPtr timeFunction(new TimeFunction(myFunc));

View File

@@ -15,6 +15,7 @@
#include <cstddef>
#include <string>
#include <cstdio>
#include <iostream>
#include <epicsUnitTest.h>
#include <testMain.h>
@@ -25,6 +26,7 @@
#include <pv/thread.h>
using namespace epics::pvData;
using std::string;
static TimeStamp currentTimeStamp;
static double oneDelay = 4.0;
@@ -39,7 +41,7 @@ typedef std::tr1::shared_ptr<MyCallback> MyCallbackPtr;
class MyCallback : public TimerCallback {
public:
POINTER_DEFINITIONS(MyCallback);
MyCallback(String name,EventPtr const & wait)
MyCallback(string name,EventPtr const & wait)
: name(name),
wait(wait)
{
@@ -58,7 +60,7 @@ public:
}
TimeStamp &getTimeStamp() { return timeStamp;}
private:
String name;
string name;
EventPtr wait;
TimeStamp timeStamp;
};
@@ -69,13 +71,13 @@ static void testBasic()
printf("\n\ntestBasic oneDelay %lf twoDelay %lf threeDaley %lf\n",
oneDelay,twoDelay,threeDelay);
}
String one("one");
String two("two");
String three("three");
string one("one");
string two("two");
string three("three");
EventPtr eventOne(new Event());
EventPtr eventTwo(new Event());
EventPtr eventThree(new Event());
TimerPtr timer(new Timer(String("timer"),middlePriority));
TimerPtr timer(new Timer(string("timer"),middlePriority));
MyCallbackPtr callbackOne(new MyCallback(one,eventOne));
MyCallbackPtr callbackTwo(new MyCallback(two,eventTwo));
MyCallbackPtr callbackThree(new MyCallback(three,eventThree));
@@ -91,9 +93,8 @@ static void testBasic()
if(twoDelay>.1) testOk1(timer->isScheduled(callbackTwo));
if(threeDelay>.1) testOk1(timer->isScheduled(callbackThree));
if(debug) {
String builder;
timer->toString(&builder);
printf("timerQueue\n%s",builder.c_str());
std::cout << "timerQueue" << std::endl;
std::cout << *timer;
}
eventOne->wait();
eventTwo->wait();
@@ -137,13 +138,13 @@ static void testCancel()
printf("\n\ntestCancel oneDelay %lf twoDelay %lf threeDaley %lf\n",
oneDelay,twoDelay,threeDelay);
}
String one("one");
String two("two");
String three("three");
string one("one");
string two("two");
string three("three");
EventPtr eventOne(new Event());
EventPtr eventTwo(new Event());
EventPtr eventThree(new Event());
TimerPtr timer(new Timer(String("timer"),middlePriority));
TimerPtr timer(new Timer(string("timer"),middlePriority));
MyCallbackPtr callbackOne(new MyCallback(one,eventOne));
MyCallbackPtr callbackTwo(new MyCallback(two,eventTwo));
MyCallbackPtr callbackThree(new MyCallback(three,eventThree));
@@ -160,9 +161,8 @@ static void testCancel()
testOk1(!timer->isScheduled(callbackTwo));
if(threeDelay>.1) testOk1(timer->isScheduled(callbackThree));
if(debug) {
String builder;
timer->toString(&builder);
printf("timerQueue\n%s",builder.c_str());
std::cout << "timerQueue" << std::endl;
std::cout << *timer;
}
eventOne->wait();
eventThree->wait();

View File

@@ -27,7 +27,7 @@
#include "pv/typeCast.h"
using epics::pvData::String;
using std::string;
namespace {
@@ -131,11 +131,11 @@ try {
uint64_t xuint64=0;
float xfloat=0.0;
double xdouble=0.0;
epics::pvData::String xString("0");
string xstring("0");
typedef float float_t;
typedef double double_t;
typedef epics::pvData::String String_t;
typedef string string_t;
// force all possibilities to be compiled
#define CHECK(M, N) x## M = ::epics::pvData::castUnsafe<M ##_t>(x## N); \
@@ -151,7 +151,7 @@ try {
CHECK(int8, uint64);
CHECK(int8, float);
CHECK(int8, double);
CHECK(int8, String);
CHECK(int8, string);
CHECK(uint8, int8);
CHECK(uint8, uint8);
@@ -163,7 +163,7 @@ try {
CHECK(uint8, uint64);
CHECK(uint8, float);
CHECK(uint8, double);
CHECK(uint8, String);
CHECK(uint8, string);
CHECK(int16, int8);
CHECK(int16, uint8);
@@ -175,7 +175,7 @@ try {
CHECK(int16, uint64);
CHECK(int16, float);
CHECK(int16, double);
CHECK(int16, String);
CHECK(int16, string);
CHECK(uint16, int8);
CHECK(uint16, uint8);
@@ -187,7 +187,7 @@ try {
CHECK(uint16, uint64);
CHECK(uint16, float);
CHECK(uint16, double);
CHECK(uint16, String);
CHECK(uint16, string);
CHECK(int32, int8);
CHECK(int32, uint8);
@@ -199,7 +199,7 @@ try {
CHECK(int32, uint64);
CHECK(int32, float);
CHECK(int32, double);
CHECK(int32, String);
CHECK(int32, string);
CHECK(uint32, int8);
CHECK(uint32, uint8);
@@ -211,7 +211,7 @@ try {
CHECK(uint32, uint64);
CHECK(uint32, float);
CHECK(uint32, double);
CHECK(uint32, String);
CHECK(uint32, string);
CHECK(int64, int8);
CHECK(int64, uint8);
@@ -223,7 +223,7 @@ try {
CHECK(int64, uint64);
CHECK(int64, float);
CHECK(int64, double);
//CHECK(int64, String);
//CHECK(int64, string);
CHECK(uint64, int8);
CHECK(uint64, uint8);
@@ -235,7 +235,7 @@ try {
CHECK(uint64, uint64);
CHECK(uint64, float);
CHECK(uint64, double);
//CHECK(uint64, String);
//CHECK(uint64, string);
CHECK(float, int8);
CHECK(float, uint8);
@@ -247,7 +247,7 @@ try {
CHECK(float, uint64);
CHECK(float, float);
CHECK(float, double);
CHECK(float, String);
CHECK(float, string);
CHECK(double, int8);
CHECK(double, uint8);
@@ -259,19 +259,19 @@ try {
CHECK(double, uint64);
CHECK(double, float);
CHECK(double, double);
CHECK(double, String);
CHECK(double, string);
CHECK(String, int8);
CHECK(String, uint8);
CHECK(String, int16);
CHECK(String, uint16);
CHECK(String, int32);
CHECK(String, uint32);
CHECK(String, int64);
CHECK(String, uint64);
CHECK(String, float);
CHECK(String, double);
CHECK(String, String);
CHECK(string, int8);
CHECK(string, uint8);
CHECK(string, int16);
CHECK(string, uint16);
CHECK(string, int32);
CHECK(string, uint32);
CHECK(string, int64);
CHECK(string, uint64);
CHECK(string, float);
CHECK(string, double);
CHECK(string, string);
#undef CHECK
testDiag("Integer signed <=> unsigned");
@@ -309,91 +309,91 @@ try {
TEST(int32_t, -2, float, -2.5f);
TEST(int32_t, -2, float, -2.7f);
testDiag("String Printing/parsing");
testDiag("string Printing/parsing");
TEST2(String, "1", int32_t, 1);
TEST2(String, "-1", int32_t, -1);
TEST2(String, "1", int8_t, 1);
TEST2(String, "-1", int8_t, -1);
TEST2(String, "1", uint8_t, 1);
TEST2(string, "1", int32_t, 1);
TEST2(string, "-1", int32_t, -1);
TEST2(string, "1", int8_t, 1);
TEST2(string, "-1", int8_t, -1);
TEST2(string, "1", uint8_t, 1);
TEST2(String, "127", int32_t, std::numeric_limits<int8_t>::max());
TEST2(String, "-128", int32_t, std::numeric_limits<int8_t>::min());
TEST2(String, "255", int32_t, std::numeric_limits<uint8_t>::max());
TEST2(string, "127", int32_t, std::numeric_limits<int8_t>::max());
TEST2(string, "-128", int32_t, std::numeric_limits<int8_t>::min());
TEST2(string, "255", int32_t, std::numeric_limits<uint8_t>::max());
TEST2(String, "32767", int32_t, std::numeric_limits<int16_t>::max());
TEST2(String, "-32768", int32_t, std::numeric_limits<int16_t>::min());
TEST2(String, "65535", int32_t, std::numeric_limits<uint16_t>::max());
TEST2(string, "32767", int32_t, std::numeric_limits<int16_t>::max());
TEST2(string, "-32768", int32_t, std::numeric_limits<int16_t>::min());
TEST2(string, "65535", int32_t, std::numeric_limits<uint16_t>::max());
TEST2(String, "2147483647", int32_t, std::numeric_limits<int32_t>::max());
TEST2(String, "-2147483648", int32_t, std::numeric_limits<int32_t>::min());
TEST2(String, "4294967295", uint32_t, std::numeric_limits<uint32_t>::max());
TEST2(string, "2147483647", int32_t, std::numeric_limits<int32_t>::max());
TEST2(string, "-2147483648", int32_t, std::numeric_limits<int32_t>::min());
TEST2(string, "4294967295", uint32_t, std::numeric_limits<uint32_t>::max());
TEST2(String, "9223372036854775807", int64_t, std::numeric_limits<int64_t>::max());
TEST2(String, "-9223372036854775808", int64_t, std::numeric_limits<int64_t>::min());
TEST2(String, "18446744073709551615", uint64_t, std::numeric_limits<uint64_t>::max());
TEST2(string, "9223372036854775807", int64_t, std::numeric_limits<int64_t>::max());
TEST2(string, "-9223372036854775808", int64_t, std::numeric_limits<int64_t>::min());
TEST2(string, "18446744073709551615", uint64_t, std::numeric_limits<uint64_t>::max());
TEST2(String, "1.1", double, 1.1);
TEST2(String, "1.1e+100", double, 1.1e100);
TEST2(String, "1.1e-100", double, 1.1e-100);
TEST2(string, "1.1", double, 1.1);
TEST2(string, "1.1e+100", double, 1.1e100);
TEST2(string, "1.1e-100", double, 1.1e-100);
TEST(double, 1.1e100, String, "1.1E+100");
TEST(double, 1.1e100, string, "1.1E+100");
// any non-zero value is true
TEST(String, "true", epics::pvData::boolean, 100);
TEST(string, "true", epics::pvData::boolean, 100);
TEST2(String, "true", epics::pvData::boolean, 1);
TEST2(String, "false", epics::pvData::boolean, 0);
TEST2(string, "true", epics::pvData::boolean, 1);
TEST2(string, "false", epics::pvData::boolean, 0);
// Case insensitive
TEST(epics::pvData::boolean, 1, String, "True");
TEST(epics::pvData::boolean, 0, String, "False");
TEST(epics::pvData::boolean, 1, String, "TRUE");
TEST(epics::pvData::boolean, 0, String, "FALSE");
TEST(epics::pvData::boolean, 1, string, "True");
TEST(epics::pvData::boolean, 0, string, "False");
TEST(epics::pvData::boolean, 1, string, "TRUE");
TEST(epics::pvData::boolean, 0, string, "FALSE");
testDiag("String Parsing");
testDiag("string Parsing");
TEST(int32_t, 15, String, "0xf");
TEST(int32_t, 15, String, "0xF");
TEST(int32_t, -15, String, "-0xF");
TEST(int32_t, 16, String, "0x10");
TEST(int32_t, -16, String, "-0x10");
TEST(int32_t, 15, string, "0xf");
TEST(int32_t, 15, string, "0xF");
TEST(int32_t, -15, string, "-0xF");
TEST(int32_t, 16, string, "0x10");
TEST(int32_t, -16, string, "-0x10");
TEST(int32_t, 7, String, "07");
TEST(int32_t, 8, String, "010");
TEST(int32_t, -7, String, "-07");
TEST(int32_t, -8, String, "-010");
TEST(int32_t, 7, string, "07");
TEST(int32_t, 8, string, "010");
TEST(int32_t, -7, string, "-07");
TEST(int32_t, -8, string, "-010");
TEST(int64_t, 15, String, "0xf");
TEST(int64_t, 15, String, "0xF");
TEST(int64_t, -15, String, "-0xF");
TEST(int64_t, 16, String, "0x10");
TEST(int64_t, -16, String, "-0x10");
TEST(int64_t, 15, string, "0xf");
TEST(int64_t, 15, string, "0xF");
TEST(int64_t, -15, string, "-0xF");
TEST(int64_t, 16, string, "0x10");
TEST(int64_t, -16, string, "-0x10");
TEST(int64_t, 7, String, "07");
TEST(int64_t, 8, String, "010");
TEST(int64_t, -7, String, "-07");
TEST(int64_t, -8, String, "-010");
TEST(int64_t, 7, string, "07");
TEST(int64_t, 8, string, "010");
TEST(int64_t, -7, string, "-07");
TEST(int64_t, -8, string, "-010");
testDiag("String parsing errors");
testDiag("string parsing errors");
FAIL(int32_t, String, "hello!");
FAIL(int32_t, String, "42 is the answer");
FAIL(int64_t, String, "hello!");
FAIL(int64_t, String, "42 is the answer");
FAIL(double, String, "hello!");
FAIL(double, String, "42 is the answer");
FAIL(int32_t, string, "hello!");
FAIL(int32_t, string, "42 is the answer");
FAIL(int64_t, string, "hello!");
FAIL(int64_t, string, "42 is the answer");
FAIL(double, string, "hello!");
FAIL(double, string, "42 is the answer");
FAIL(int8_t, String, "1000");
FAIL(int8_t, String, "-1000");
FAIL(int8_t, string, "1000");
FAIL(int8_t, string, "-1000");
FAIL(double, String, "1e+10000000");
FAIL(double, string, "1e+10000000");
FAIL(epics::pvData::boolean, String, "hello");
FAIL(epics::pvData::boolean, String, "1");
FAIL(epics::pvData::boolean, String, "0");
FAIL(epics::pvData::boolean, String, "T");
FAIL(epics::pvData::boolean, String, "F");
FAIL(epics::pvData::boolean, string, "hello");
FAIL(epics::pvData::boolean, string, "1");
FAIL(epics::pvData::boolean, string, "0");
FAIL(epics::pvData::boolean, string, "T");
FAIL(epics::pvData::boolean, string, "F");
testDiag("Floating point overflows");
@@ -406,10 +406,10 @@ try {
testOk(isnan( xfloat ), "Test cast double NAN to float NAN yields: %f", xfloat);
{
std::string result[3];
string result[3];
const int32_t in[3] = { 1234, 506001, 42424242 };
testDiag("Test vcast int32 -> String");
testDiag("Test vcast int32 -> string");
epics::pvData::castUnsafeV(3, epics::pvData::pvString, (void*)result,
epics::pvData::pvInt, (void*)in);
testDiag("Yields %s %s %s", result[0].c_str(), result[1].c_str(), result[2].c_str());

View File

@@ -33,6 +33,7 @@
#include <pv/pvTimeStamp.h>
using namespace epics::pvData;
using std::string;
static bool debug = false;
@@ -41,9 +42,8 @@ static PVDataCreatePtr pvDataCreate;
static StandardFieldPtr standardField;
static StandardPVFieldPtr standardPVField;
static ConvertPtr convert;
static String builder;
static String alarmTimeStamp("alarm,timeStamp");
static String allProperties("alarm,timeStamp,display,control");
static string alarmTimeStamp("alarm,timeStamp");
static string allProperties("alarm,timeStamp,display,control");
static PVStructurePtr doubleRecord;
static PVStructurePtr enumeratedRecord;
@@ -51,11 +51,8 @@ static PVStructurePtr enumeratedRecord;
static void createRecords()
{
doubleRecord = standardPVField->scalar(pvDouble,allProperties);
if(debug) {
builder.clear();
doubleRecord->toString(&builder);
printf("doubleRecord\n%s\n",builder.c_str());
}
if(debug)
std::cout << "doubleRecord" << std::endl << *doubleRecord << std::endl;
StringArray choices;
choices.reserve(4);
choices.push_back("1");
@@ -63,23 +60,14 @@ static void createRecords()
choices.push_back("3");
choices.push_back("4");
enumeratedRecord = standardPVField->enumerated(choices,alarmTimeStamp);
if(debug) {
builder.clear();
enumeratedRecord->toString(&builder);
printf("enumeratedRecord\n%s\n",builder.c_str());
}
if(debug)
std::cout << "enumeratedRecord" << std::endl << *doubleRecord << std::endl;
}
static void printRecords()
{
printf("doubleRecord\n");
builder.clear();
doubleRecord->toString(&builder);
printf("%s\n",builder.c_str());
printf("enumeratedRecord\n");
builder.clear();
enumeratedRecord->toString(&builder);
printf("%s\n",builder.c_str());
std::cout << "doubleRecord" << std::endl << *doubleRecord << std::endl;
std::cout << "enumeratedRecord" << std::endl << *doubleRecord << std::endl;
}
static void testAlarm()
@@ -88,7 +76,7 @@ static void testAlarm()
Alarm alarm;
PVAlarm pvAlarm;
bool result;
PVFieldPtr pvField = doubleRecord->getSubField(String("alarm"));
PVFieldPtr pvField = doubleRecord->getSubField(string("alarm"));
if(pvField.get()==NULL) {
printf("testAlarm ERROR did not find field alarm\n");
return;
@@ -96,7 +84,7 @@ static void testAlarm()
result = pvAlarm.attach(pvField);
testOk1(result);
Alarm al;
al.setMessage(String("testMessage"));
al.setMessage(string("testMessage"));
al.setSeverity(majorAlarm);
al.setStatus(clientStatus);
result = pvAlarm.set(al);
@@ -105,9 +93,9 @@ static void testAlarm()
testOk1(al.getMessage().compare(alarm.getMessage())==0);
testOk1(al.getSeverity()==alarm.getSeverity());
testOk1(al.getStatus()==alarm.getStatus());
String message = alarm.getMessage();
String severity = (*AlarmSeverityFunc::getSeverityNames())[alarm.getSeverity()];
String status = (*AlarmStatusFunc::getStatusNames())[alarm.getStatus()];
string message = alarm.getMessage();
string severity = (*AlarmSeverityFunc::getSeverityNames())[alarm.getSeverity()];
string status = (*AlarmStatusFunc::getStatusNames())[alarm.getStatus()];
if(debug) {
printf(" message %s severity %s status %s\n",
message.c_str(),severity.c_str(),status.c_str());
@@ -121,7 +109,7 @@ static void testTimeStamp()
TimeStamp timeStamp;
PVTimeStamp pvTimeStamp;
bool result;
PVFieldPtr pvField = doubleRecord->getSubField(String("timeStamp"));
PVFieldPtr pvField = doubleRecord->getSubField(string("timeStamp"));
if(pvField.get()==NULL) {
printf("testTimeStamp ERROR did not find field timeStamp\n");
return;
@@ -161,7 +149,7 @@ static void testControl()
Control control;
PVControl pvControl;
bool result;
PVFieldPtr pvField = doubleRecord->getSubField(String("control"));
PVFieldPtr pvField = doubleRecord->getSubField(string("control"));
if(pvField.get()==NULL) {
printf("testControl ERROR did not find field control\n");
return;
@@ -188,7 +176,7 @@ static void testDisplay()
Display display;
PVDisplay pvDisplay;
bool result;
PVFieldPtr pvField = doubleRecord->getSubField(String("display"));
PVFieldPtr pvField = doubleRecord->getSubField(string("display"));
if(pvField.get()==NULL) {
printf("testDisplay ERROR did not find field display\n");
return;
@@ -198,9 +186,9 @@ static void testDisplay()
Display dy;
dy.setLow(-10.0);
dy.setHigh(-1.0);
dy.setDescription(String("testDescription"));
dy.setFormat(String("%f10.0"));
dy.setUnits(String("volts"));
dy.setDescription(string("testDescription"));
dy.setFormat(string("%f10.0"));
dy.setUnits(string("volts"));
result = pvDisplay.set(dy);
testOk1(result);
pvDisplay.get(display);
@@ -220,7 +208,7 @@ static void testEnumerated()
if(debug) printf("testEnumerated\n");
PVEnumerated pvEnumerated;
bool result;
PVFieldPtr pvField = enumeratedRecord->getSubField(String("value"));
PVFieldPtr pvField = enumeratedRecord->getSubField(string("value"));
if(pvField.get()==NULL) {
printf("testEnumerated ERROR did not find field enumerated\n");
return;
@@ -228,7 +216,7 @@ static void testEnumerated()
result = pvEnumerated.attach(pvField);
testOk1(result);
int32 index = pvEnumerated.getIndex();
String choice = pvEnumerated.getChoice();
string choice = pvEnumerated.getChoice();
PVStringArray::const_svector choices = pvEnumerated.getChoices();
int32 numChoices = pvEnumerated.getNumberChoices();
if(debug) {

View File

@@ -12,21 +12,11 @@ testIntrospect_SRCS += testIntrospect.cpp
testIntrospect_LIBS += pvData Com
TESTS += testIntrospect
PROD_HOST += testPVAppend
testPVAppend_SRCS += testPVAppend.cpp
testPVAppend_LIBS += pvData Com
TESTS += testPVAppend
PROD_HOST += testPVType
testPVType_SRCS += testPVType.cpp
testPVType_LIBS += pvData Com
TESTS += testPVType
PROD_HOST += testPVAuxInfo
testPVAuxInfo_SRCS += testPVAuxInfo.cpp
testPVAuxInfo_LIBS += pvData Com
TESTS += testPVAuxInfo
PROD_HOST += testStandardField
testStandardField_SRCS += testStandardField.cpp
testStandardField_LIBS += pvData Com

View File

@@ -11,6 +11,7 @@
#include <cstddef>
#include <string>
#include <cstdio>
#include <sstream>
#include <epicsUnitTest.h>
#include <testMain.h>
@@ -22,6 +23,7 @@
#include <pv/standardPVField.h>
using namespace epics::pvData;
using std::string;
using std::tr1::static_pointer_cast;
static bool debug = false;
@@ -31,10 +33,11 @@ static PVDataCreatePtr pvDataCreate;
static StandardFieldPtr standardField;
static StandardPVFieldPtr standardPVField;
static ConvertPtr convert;
static String builder("");
static void test()
{
std::ostringstream oss;
if(debug) printf("\ntestBitSetUtil\n");
StringArray fieldNames;
PVFieldPtrArray pvFields;
@@ -60,19 +63,28 @@ static void test()
standardField->scalar(pvDouble,"alarm")));
PVStructurePtr pvs = pvDataCreate->createPVStructure(
fieldNames,pvFields);
builder.clear();
pvs->toString(&builder);
if(debug) printf("pvs\n%s\n",builder.c_str());
if(debug) {
oss.clear();
oss << "pvs" << std::endl;
oss << *pvs << std::endl;
std::cout << oss.str();
}
int32 nfields = (int32)pvs->getNumberFields();
BitSetPtr bitSet = BitSet::create(nfields);
for(int32 i=0; i<nfields; i++) bitSet->set(i);
builder.clear();
bitSet->toString(&builder);
if(debug) printf("bitSet\n%s\n",builder.c_str());
if(debug) {
oss.clear();
oss << "bitSet" << std::endl;
oss << *bitSet << std::endl;
std::cout << oss.str();
}
BitSetUtil::compress(bitSet,pvs);
builder.clear();
bitSet->toString(&builder);
if(debug) printf("bitSet\n%s\n",builder.c_str());
if(debug) {
oss.clear();
oss << "bitSet" << std::endl;
oss << *bitSet << std::endl;
std::cout << oss.str();
}
bitSet->clear();
PVFieldPtr pvField = pvs->getSubField("timeStamp");
int32 offsetTimeStamp = (int32)pvField->getFieldOffset();
@@ -87,15 +99,21 @@ static void test()
testOk1(bitSet->get(offsetSeconds)==true);
bitSet->set(offsetNano);
bitSet->set(offsetUserTag);
builder.clear();
bitSet->toString(&builder);
if(debug) printf("bitSet\n%s\n",builder.c_str());
if(debug) {
oss.clear();
oss << "bitSet" << std::endl;
oss << *bitSet << std::endl;
std::cout << oss.str();
}
BitSetUtil::compress(bitSet,pvs);
testOk1(bitSet->get(offsetSeconds)==false);
testOk1(bitSet->get(offsetTimeStamp)==true);
builder.clear();
bitSet->toString(&builder);
if(debug) printf("bitSet\n%s\n",builder.c_str());
if(debug) {
oss.clear();
oss << "bitSet" << std::endl;
oss << *bitSet << std::endl;
std::cout << oss.str();
}
bitSet->clear();
pvField = pvs->getSubField("current");
@@ -114,25 +132,37 @@ static void test()
bitSet->set(offsetSeverity);
bitSet->set(offsetStatus);
bitSet->set(offsetMessage);
builder.clear();
bitSet->toString(&builder);
if(debug) printf("bitSet\n%s\n",builder.c_str());
if(debug) {
oss.clear();
oss << "bitSet" << std::endl;
oss << *bitSet << std::endl;
std::cout << oss.str();
}
BitSetUtil::compress(bitSet,pvs);
builder.clear();
bitSet->toString(&builder);
if(debug) printf("bitSet\n%s\n",builder.c_str());
if(debug) {
oss.clear();
oss << "bitSet" << std::endl;
oss << *bitSet << std::endl;
std::cout << oss.str();
}
testOk1(bitSet->get(offsetCurrent)==true);
bitSet->clear();
bitSet->set(offsetSeverity);
bitSet->set(offsetStatus);
bitSet->set(offsetMessage);
builder.clear();
bitSet->toString(&builder);
if(debug) printf("bitSet\n%s\n",builder.c_str());
if(debug) {
oss.clear();
oss << "bitSet" << std::endl;
oss << *bitSet << std::endl;
std::cout << oss.str();
}
BitSetUtil::compress(bitSet,pvs);
builder.clear();
bitSet->toString(&builder);
if(debug) printf("bitSet\n%s\n",builder.c_str());
if(debug) {
oss.clear();
oss << "bitSet" << std::endl;
oss << *bitSet << std::endl;
std::cout << oss.str();
}
testOk1(bitSet->get(offsetAlarm)==true);
bitSet->clear();
printf("testBitSetUtil PASSED\n");

View File

@@ -31,7 +31,7 @@ void test_structure()
FieldBuilderPtr fb = fieldCreate->createFieldBuilder();
// test with simple (non-nested) structure
std::string ID = "testStructureID";
string ID = "testStructureID";
StructureConstPtr s = fb->setId(ID)->
add("double", pvDouble)->
addArray("intArray", pvInt)->
@@ -116,7 +116,7 @@ void test_nestedStructure()
FieldCreatePtr fieldCreate = getFieldCreate();
std::string NESTED_ID = "nestedID";
string NESTED_ID = "nestedID";
StructureConstPtr s = fieldCreate->createFieldBuilder()->
add("double", pvDouble)->
addNestedStructure("nested")->
@@ -172,7 +172,7 @@ void test_nestedStructureArray()
FieldCreatePtr fieldCreate = getFieldCreate();
std::string NESTED_ID = "nestedID";
string NESTED_ID = "nestedID";
StructureConstPtr s = fieldCreate->createFieldBuilder()->
add("double", pvDouble)->
addNestedStructureArray("nested")->

View File

@@ -11,6 +11,7 @@
#include <cstddef>
#include <string>
#include <cstdio>
#include <sstream>
#include <epicsUnitTest.h>
#include <testMain.h>
@@ -21,6 +22,7 @@
#include <pv/standardField.h>
using namespace epics::pvData;
using std::string;
static FieldCreatePtr fieldCreate;
static PVDataCreatePtr pvDataCreate;
@@ -29,13 +31,14 @@ static StandardFieldPtr standardField;
static void testScalarCommon(ScalarType stype,
bool isInteger,bool isNumeric,bool isPrimitive)
{
String builder;
ScalarConstPtr pscalar = fieldCreate->createScalar(stype);
Type type = pscalar->getType();
testOk1(type==scalar);
builder.clear();
TypeFunc::toString(&builder,type);
testOk1(builder.compare("scalar")==0);
std::ostringstream oss;
oss << type;
testOk1(oss.str().compare("scalar")==0);
ScalarType scalarType = pscalar->getScalarType();
testOk1(scalarType==stype);
testOk1(ScalarTypeFunc::isInteger(scalarType)==isInteger);
@@ -58,13 +61,14 @@ static void testScalar() {
static void testScalarArrayCommon(ScalarType stype,
bool isInteger,bool isNumeric,bool isPrimitive)
{
String builder;
ScalarArrayConstPtr pscalar = fieldCreate->createScalarArray(stype);
Type type = pscalar->getType();
testOk1(type==scalarArray);
builder.clear();
TypeFunc::toString(&builder,type);
testOk1(builder.compare("scalarArray")==0);
std::ostringstream oss;
oss << type;
testOk1(oss.str().compare("scalarArray")==0);
ScalarType scalarType = pscalar->getElementType();
testOk1(scalarType==stype);
testOk1(ScalarTypeFunc::isInteger(scalarType)==isInteger);
@@ -246,7 +250,7 @@ static void testMapping()
OP(uint64, pvULong)
OP(float, pvFloat)
OP(double, pvDouble)
OP(String, pvString)
OP(string, pvString)
#undef OP
testOk1((ScalarType)ScalarTypeID<PVField>::value==(ScalarType)-1);

View File

@@ -11,11 +11,13 @@
#include <pv/pvData.h>
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/status.h>
#include <epicsUnitTest.h>
#include <testMain.h>
using namespace epics::pvData;
using std::string;
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
static StandardFieldPtr standardField = getStandardField();
@@ -37,12 +39,12 @@ MAIN(testOperators)
testOk1(testDV == dv);
const std::string testSV = "test message";
const string testSV = "test message";
PVStringPtr pvMessage = pvStructure->getStringField("alarm.message");
*pvMessage <<= testSV;
std::string sv;
string sv;
*pvMessage >>= sv;
testOk1(testSV == sv);
@@ -54,6 +56,10 @@ MAIN(testOperators)
std::cout << *pvMessage << std::endl;
std::cout << *pvStructure << std::endl;
std::cout << *pvStructure->getStructure() << std::endl;
std::cout << Status::Ok << std::endl;
std::cout << Status::STATUSTYPE_OK << std::endl;
StringArray choices;
choices.reserve(3);

View File

@@ -1,224 +0,0 @@
/* testPVAppend.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: 2010.11 */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <epicsUnitTest.h>
#include <testMain.h>
#include <pv/requester.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/convert.h>
#include <pv/standardField.h>
#include <pv/standardPVField.h>
using namespace epics::pvData;
using std::tr1::static_pointer_cast;
using std::size_t;
static bool debug = false;
static FieldCreatePtr fieldCreate;
static PVDataCreatePtr pvDataCreate;
static StandardFieldPtr standardField;
static StandardPVFieldPtr standardPVField;
static ConvertPtr convert;
static String builder("");
static String alarmTimeStamp("alarm,timeStamp");
static String alarmTimeStampValueAlarm("alarm,timeStamp,valueAlarm");
static String allProperties("alarm,timeStamp,display,control,valueAlarm");
static void checkNameAndParent(
PVStructurePtr & pvStructure, int indentLevel)
{
builder.clear();
if(debug) {
convert->newLine(&builder,indentLevel);
printf("%s this %p indentLevel %d",
builder.c_str(),pvStructure.get(),indentLevel);
}
PVFieldPtrArray pvFields = pvStructure->getPVFields();
StringArray fieldNames = pvStructure->getStructure()->getFieldNames();
for(size_t i = 0; i<pvFields.size(); i++) {
PVFieldPtr pvField = pvFields[i];
testOk1(pvField->getParent()==pvStructure.get());
testOk1(pvField->getFieldName().compare(fieldNames[i])==0);
builder.clear();
if(debug) {
convert->newLine(&builder,indentLevel);
printf("%s this %p name %s parent %p",
builder.c_str(),
pvField.get(),
pvField->getFieldName().c_str(),
pvField->getParent());
}
if(pvField->getField()->getType()==structure) {
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
checkNameAndParent(xxx,indentLevel+1);
}
}
builder.clear();
}
static void testAppendSimple()
{
if(debug) printf("\ntestAppendSimple\n");
PVFieldPtrArray fields;
StringArray names;
PVStructurePtr pvParent = pvDataCreate->createPVStructure(names,fields);
PVStringPtr pvStringField = static_pointer_cast<PVString>(
pvDataCreate->createPVScalar(pvString));
pvStringField->put("value,timeStamp");
PVFieldPtr pvField = pvStringField;
pvParent->appendPVField("fieldlist",pvField);
pvStringField = static_pointer_cast<PVString>(
pvDataCreate->createPVScalar(pvString));
pvStringField->put("junk");
pvField = pvStringField;
pvParent->appendPVField("extra",pvField);
builder.clear();
pvParent->toString(&builder);
if(debug) printf("%s\n",builder.c_str());
printf("testAppendSimple PASSED\n");
}
static void testAppendMore()
{
if(debug) printf("\ntestAppendMore\n");
PVFieldPtrArray fields;
StringArray names;
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(names,fields);
PVStructurePtr pvChild1 = pvDataCreate->createPVStructure(names,fields);
PVStringPtr pvStringField = static_pointer_cast<PVString>(
pvDataCreate->createPVScalar(pvString));
pvStringField->put("bla");
PVFieldPtr pvField = pvStringField;
pvChild1->appendPVField("value",pvField);
pvField = pvChild1;
pvStructure->appendPVField("child1",pvField);
PVStructurePtr pvChild2 = pvDataCreate->createPVStructure(names,fields);
pvStringField = static_pointer_cast<PVString>(
pvDataCreate->createPVScalar(pvString));
pvStringField->put("blabla");
pvField = pvStringField;
pvChild2->appendPVField("value",pvField);
pvField = pvChild2;
pvStructure->appendPVField("child2",pvField);
builder.clear();
pvStructure->toString(&builder);
if(debug) printf("%s\n",builder.c_str());
checkNameAndParent(pvStructure,0);
printf("testAppendMore PASSED\n");
}
static void testAppendStructures()
{
if(debug) printf("\ntestAppendStructures\n");
PVFieldPtrArray fields;
StringArray names;
PVStructurePtr pvParent = pvDataCreate->createPVStructure(names,fields);
PVFieldPtrArray topFields;
StringArray topNames;
PVStructurePtr pvTop = pvDataCreate->createPVStructure(topNames,topFields);
pvParent->appendPVField("top",pvTop);
PVFieldPtrArray valueFields;
StringArray valueNames;
PVStructurePtr pvValue = pvDataCreate->createPVStructure(valueNames,valueFields);
pvTop->appendPVField("value",pvValue);
PVFieldPtrArray indexFields;
StringArray indexNames;
PVStructurePtr pvIndex = pvDataCreate->createPVStructure(indexNames,indexFields);
pvValue->appendPVField("index",pvIndex);
builder.clear();
pvParent->toString(&builder);
if(debug) printf("%s\n",builder.c_str());
builder.clear();
pvParent->getField()->toString(&builder);
if(debug) printf("field\n%s\n",builder.c_str());
printf("testAppendStructures PASSED\n");
}
static void append2(PVStructurePtr &pvStructure,
const char *oneName,const char *twoName,
const char *oneValue,const char *twoValue)
{
PVFieldPtrArray pvFields;
pvFields.reserve(2);
StringArray names;
names.reserve(2);
PVStringPtr pvStringField = static_pointer_cast<PVString>(
pvDataCreate->createPVScalar(pvString));
pvStringField->put(oneValue);
names.push_back(oneName);
pvFields.push_back(pvStringField);
pvStringField = static_pointer_cast<PVString>(
pvDataCreate->createPVScalar(pvString));
pvStringField->put(twoValue);
names.push_back(twoName);
pvFields.push_back(pvStringField);
pvStructure->appendPVFields(names,pvFields);
}
static void testAppends()
{
if(debug) printf("\ntestAppends\n");
PVFieldPtrArray emptyPVFields;
StringArray emptyNames;
PVFieldPtrArray pvFields;
pvFields.reserve(2);
StringArray names;
names.reserve(2);
names.push_back("child1");
PVStructurePtr pvChild = pvDataCreate->createPVStructure(
emptyNames,emptyPVFields);
append2(pvChild,"Joe","Mary","Good Guy","Good Girl");
pvFields.push_back(pvChild);
names.push_back("child2");
pvChild = pvDataCreate->createPVStructure(
emptyNames,emptyPVFields);
append2(pvChild,"Bill","Jane","Bad Guy","Bad Girl");
pvFields.push_back(pvChild);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(
names,pvFields);
builder.clear();
pvStructure->toString(&builder);
if(debug) printf("%s\n",builder.c_str());
checkNameAndParent(pvStructure,0);
PVFieldPtr pvField = pvStructure->getSubField("child2.Bill");
testOk1(pvField.get()!=NULL);
pvField->renameField("Joe");
builder.clear();
pvStructure->toString(&builder);
if(debug) printf("%s\n",builder.c_str());
pvField->getParent()->removePVField("Joe");
builder.clear();
pvStructure->toString(&builder);
if(debug) printf("%s\n",builder.c_str());
checkNameAndParent(pvStructure,0);
printf("testAppends PASSED\n");
}
MAIN(testPVAppend)
{
testPlan(31);
fieldCreate = getFieldCreate();
pvDataCreate = getPVDataCreate();
standardField = getStandardField();
standardPVField = getStandardPVField();
convert = getConvert();
testAppendStructures();
testAppendSimple();
testAppendMore();
testAppends();
return testDone();
}

View File

@@ -1,97 +0,0 @@
/* testPVAuxInfo.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: 2010.11 */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <epicsUnitTest.h>
#include <testMain.h>
#include <pv/requester.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/convert.h>
#include <pv/standardField.h>
#include <pv/standardPVField.h>
using namespace epics::pvData;
using std::tr1::static_pointer_cast;
static bool debug = false;
static FieldCreatePtr fieldCreate;
static PVDataCreatePtr pvDataCreate;
static StandardFieldPtr standardField;
static StandardPVFieldPtr standardPVField;
static ConvertPtr convert;
static String buffer;
static void printOffsets(PVStructurePtr pvStructure)
{
printf("%s offset %lu next %lu number %lu\n",
pvStructure->getFieldName().c_str(),
(long unsigned)pvStructure->getFieldOffset(),
(long unsigned)pvStructure->getNextFieldOffset(),
(long unsigned)pvStructure->getNumberFields());
PVFieldPtrArray fields = pvStructure->getPVFields();
int number = (int)pvStructure->getStructure()->getNumberFields();
for(int i=0; i<number; i++) {
PVFieldPtr pvField = fields[i];
if(pvField->getField()->getType()==structure) {
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
printOffsets(xxx);
continue;
}
printf("%s offset %lli next %lli number %lli\n",
pvField->getFieldName().c_str(),
(long long)pvField->getFieldOffset(),
(long long)pvField->getNextFieldOffset(),
(long long)pvField->getNumberFields());
}
}
static void testPVAuxInfo()
{
if(debug) printf("\ntestPVAuxInfo\n");
PVStructurePtr pvStructure = standardPVField->scalar(
pvDouble,"alarm,timeStamp,display,control");
PVStructurePtr display
= pvStructure->getStructureField("display");
testOk1(display.get()!=NULL);
PVAuxInfoPtr auxInfo = display->getPVAuxInfo();
auxInfo->createInfo("factory",pvString);
auxInfo->createInfo("junk",pvDouble);
PVScalarPtr pscalar = auxInfo->getInfo(String("factory"));
testOk1(pscalar.get()!=0);
convert->fromString(pscalar,"factoryName");
pscalar = auxInfo->getInfo("junk");
testOk1(pscalar.get()!=0);
convert->fromString(pscalar,"3.0");
buffer.clear();
pvStructure->toString(&buffer);
if(debug) printf("%s\n",buffer.c_str());
// now show field offsets
if(debug) printOffsets(pvStructure);
printf("testPVAuxInfo PASSED\n");
}
MAIN(testPVAuxInfo)
{
testPlan(3);
fieldCreate = getFieldCreate();
pvDataCreate = getPVDataCreate();
standardField = getStandardField();
standardPVField = getStandardPVField();
convert = getConvert();
testPVAuxInfo();
return testDone();
}

View File

@@ -24,6 +24,9 @@
using namespace epics::pvData;
using std::tr1::static_pointer_cast;
using std::string;
using std::cout;
using std::endl;
static bool debug = false;
@@ -32,32 +35,14 @@ static PVDataCreatePtr pvDataCreate;
static StandardFieldPtr standardField;
static StandardPVFieldPtr standardPVField;
static ConvertPtr convert;
static String builder("");
static String alarmTimeStamp("alarm,timeStamp");
static String alarmTimeStampValueAlarm("alarm,timeStamp,valueAlarm");
static String allProperties("alarm,timeStamp,display,control,valueAlarm");
static void testAppend()
{
if(debug) printf("\ntestAppend\n");
PVFieldPtrArray pvFields;
StringArray fieldNames;
PVStructurePtr pvParent = pvDataCreate->createPVStructure(
fieldNames,pvFields);
PVStringPtr pvStringField = static_pointer_cast<PVString>(
pvDataCreate->createPVScalar(pvString));
pvStringField->put(String("value,timeStamp"));
PVFieldPtr pvField = pvStringField;
pvParent->appendPVField("request",pvField);
builder.clear();
pvParent->toString(&builder);
if(debug) printf("%s\n",builder.c_str());
printf("testAppend PASSED\n");
}
static string alarmTimeStamp("alarm,timeStamp");
static string alarmTimeStampValueAlarm("alarm,timeStamp,valueAlarm");
static string allProperties("alarm,timeStamp,display,control,valueAlarm");
static void testCreatePVStructure()
{
if(debug) printf("\ntestCreatePVStructure\n");
if(debug)
std::cout << std::endl << "testCreatePVStructure" << std::endl;
PVStructurePtr pv0 = standardPVField->scalar(
pvDouble,alarmTimeStampValueAlarm);
PVScalarPtr pv1 = pvDataCreate->createPVScalar(pvString);
@@ -71,27 +56,27 @@ static void testCreatePVStructure()
pvFields.push_back(pv1);
PVStructurePtr pvParent = pvDataCreate->createPVStructure(
fieldNames,pvFields);
builder.clear();
pvParent->toString(&builder);
if(debug) printf("%s\n",builder.c_str());
printf("testCreatePVStructure PASSED\n");
if(debug)
std::cout << *pvParent << std::endl;
std::cout << "testCreatePVStructure PASSED" << std::endl;
}
static void testPVScalarCommon(String /*fieldName*/,ScalarType stype)
static void testPVScalarCommon(string /*fieldName*/,ScalarType stype)
{
PVScalarPtr pvScalar = pvDataCreate->createPVScalar(stype);
if(stype==pvBoolean) {
convert->fromString(pvScalar,String("true"));
convert->fromString(pvScalar,string("true"));
} else {
convert->fromString(pvScalar,String("10"));
convert->fromString(pvScalar,string("10"));
}
builder.clear();
pvScalar->toString(&builder);
if(debug) printf("%s\n",builder.c_str());
if(debug)
std::cout << *pvScalar << std::endl;
}
static void testPVScalarWithProperties(
String /*fieldName*/,ScalarType stype)
string /*fieldName*/,ScalarType stype)
{
PVStructurePtr pvStructure;
bool hasValueAlarm = false;
@@ -206,137 +191,138 @@ static void testPVScalarWithProperties(
pvStructure = standardPVField->scalar(
stype,alarmTimeStamp);
PVStringPtr pvField = pvStructure->getStringField("value");
pvField->put(String("this is a string"));
pvField->put(string("this is a string"));
break;
}
}
PVLongPtr seconds = pvStructure->getLongField(
String("timeStamp.secondsPastEpoch"));
string("timeStamp.secondsPastEpoch"));
testOk1(seconds!=0);
seconds->put(123456789);
PVIntPtr nano = pvStructure->getIntField(String("timeStamp.nanoSeconds"));
PVIntPtr nano = pvStructure->getIntField(string("timeStamp.nanoSeconds"));
testOk1(nano!=0);
nano->put(1000000);
PVIntPtr severity = pvStructure->getIntField(String("alarm.severity"));
PVIntPtr severity = pvStructure->getIntField(string("alarm.severity"));
testOk1(severity!=0);
severity->put(2);
PVStringPtr message = pvStructure->getStringField(String("alarm.message"));
PVStringPtr message = pvStructure->getStringField(string("alarm.message"));
testOk1(message!=0);
message->put(String("messageForAlarm"));
message->put(string("messageForAlarm"));
if(hasDisplayControl) {
PVStringPtr desc = pvStructure->getStringField(
String("display.description"));
string("display.description"));
testOk1(desc!=0);
desc->put(String("this is a description"));
desc->put(string("this is a description"));
PVStringPtr format = pvStructure->getStringField(
String("display.format"));
string("display.format"));
testOk1(format!=0);
format->put(String("f10.2"));
format->put(string("f10.2"));
PVStringPtr units = pvStructure->getStringField(
String("display.units"));
string("display.units"));
testOk1(units!=0);
units->put(String("SomeUnits"));
units->put(string("SomeUnits"));
PVDoublePtr limit = pvStructure->getDoubleField(
String("display.limitLow"));
string("display.limitLow"));
testOk1(limit!=0);
limit->put(0.0);
limit = pvStructure->getDoubleField(
String("display.limitHigh"));
string("display.limitHigh"));
testOk1(limit!=0);
limit->put(10.0);
limit = pvStructure->getDoubleField(
String("control.limitLow"));
string("control.limitLow"));
testOk1(limit!=0);
limit->put(1.0);
limit = pvStructure->getDoubleField(
String("control.limitHigh"));
string("control.limitHigh"));
testOk1(limit!=0);
limit->put(9.0);
}
if(hasValueAlarm) {
PVFieldPtr pvField = pvStructure->getSubField(
String("valueAlarm.active"));
string("valueAlarm.active"));
PVBooleanPtr pvBoolean = static_pointer_cast<PVBoolean>(pvField);
pvBoolean->put(true);
pvField = pvStructure->getSubField(
String("valueAlarm.lowAlarmLimit"));
string("valueAlarm.lowAlarmLimit"));
PVScalarPtr pvtemp = static_pointer_cast<PVScalar>(pvField);
testOk1(pvtemp.get()!=0);
convert->fromDouble(pvtemp,1.0);
pvField = pvStructure->getSubField(
String("valueAlarm.highAlarmLimit"));
string("valueAlarm.highAlarmLimit"));
pvtemp = static_pointer_cast<PVScalar>(pvField);
testOk1(pvtemp.get()!=0);
convert->fromDouble(pvtemp,9.0);
severity = pvStructure->getIntField(
String("valueAlarm.lowAlarmSeverity"));
string("valueAlarm.lowAlarmSeverity"));
testOk1(severity!=0);
severity->put(2);
severity = pvStructure->getIntField(
String("valueAlarm.highAlarmSeverity"));
string("valueAlarm.highAlarmSeverity"));
testOk1(severity!=0);
severity->put(2);
PVBooleanPtr active = pvStructure->getBooleanField(
String("valueAlarm.active"));
string("valueAlarm.active"));
testOk1(active!=0);
active->put(true);
}
if(hasBooleanAlarm) {
PVFieldPtr pvField = pvStructure->getSubField(
String("valueAlarm.active"));
string("valueAlarm.active"));
PVBooleanPtr pvBoolean = static_pointer_cast<PVBoolean>(pvField);
pvBoolean->put(true);
severity = pvStructure->getIntField(
String("valueAlarm.falseSeverity"));
string("valueAlarm.falseSeverity"));
testOk1(severity!=0);
severity->put(0);
severity = pvStructure->getIntField(
String("valueAlarm.trueSeverity"));
string("valueAlarm.trueSeverity"));
testOk1(severity!=0);
severity->put(2);
severity = pvStructure->getIntField(
String("valueAlarm.changeStateSeverity"));
string("valueAlarm.changeStateSeverity"));
testOk1(severity!=0);
severity->put(1);
}
builder.clear();
pvStructure->toString(&builder);
if(debug) printf("%s\n",builder.c_str());
if(debug)
std::cout << *pvStructure << std::endl;
}
static void testPVScalar()
{
if(debug) printf("\ntestScalar\n");
testPVScalarCommon(String("boolean"),pvByte);
testPVScalarCommon(String("byte"),pvByte);
testPVScalarCommon(String("short"),pvShort);
testPVScalarCommon(String("int"),pvInt);
testPVScalarCommon(String("long"),pvLong);
testPVScalarCommon(String("ubyte"),pvUByte);
testPVScalarCommon(String("ushort"),pvUShort);
testPVScalarCommon(String("uint"),pvUInt);
testPVScalarCommon(String("ulong"),pvULong);
testPVScalarCommon(String("float"),pvFloat);
testPVScalarCommon(String("double"),pvDouble);
testPVScalarCommon(String("string"),pvString);
if(debug)
std::cout << std::endl << "testScalar" << std::endl;
testPVScalarCommon(string("boolean"),pvByte);
testPVScalarCommon(string("byte"),pvByte);
testPVScalarCommon(string("short"),pvShort);
testPVScalarCommon(string("int"),pvInt);
testPVScalarCommon(string("long"),pvLong);
testPVScalarCommon(string("ubyte"),pvUByte);
testPVScalarCommon(string("ushort"),pvUShort);
testPVScalarCommon(string("uint"),pvUInt);
testPVScalarCommon(string("ulong"),pvULong);
testPVScalarCommon(string("float"),pvFloat);
testPVScalarCommon(string("double"),pvDouble);
testPVScalarCommon(string("string"),pvString);
testPVScalarWithProperties(String("boolean"),pvBoolean);
testPVScalarWithProperties(String("byte"),pvByte);
testPVScalarWithProperties(String("short"),pvShort);
testPVScalarWithProperties(String("int"),pvInt);
testPVScalarWithProperties(String("long"),pvLong);
testPVScalarWithProperties(String("ubyte"),pvUByte);
testPVScalarWithProperties(String("ushort"),pvUShort);
testPVScalarWithProperties(String("uint"),pvUInt);
testPVScalarWithProperties(String("ulong"),pvULong);
testPVScalarWithProperties(String("float"),pvFloat);
testPVScalarWithProperties(String("double"),pvDouble);
testPVScalarWithProperties(String("string"),pvString);
printf("testScalar PASSED\n");
testPVScalarWithProperties(string("boolean"),pvBoolean);
testPVScalarWithProperties(string("byte"),pvByte);
testPVScalarWithProperties(string("short"),pvShort);
testPVScalarWithProperties(string("int"),pvInt);
testPVScalarWithProperties(string("long"),pvLong);
testPVScalarWithProperties(string("ubyte"),pvUByte);
testPVScalarWithProperties(string("ushort"),pvUShort);
testPVScalarWithProperties(string("uint"),pvUInt);
testPVScalarWithProperties(string("ulong"),pvULong);
testPVScalarWithProperties(string("float"),pvFloat);
testPVScalarWithProperties(string("double"),pvDouble);
testPVScalarWithProperties(string("string"),pvString);
std::cout << "testPVScalar PASSED" << std::endl;
}
static void testScalarArrayCommon(String /*fieldName*/,ScalarType stype)
static void testScalarArrayCommon(string /*fieldName*/,ScalarType stype)
{
PVStructurePtr pvStructure = standardPVField->scalarArray(
stype,alarmTimeStamp);
@@ -356,39 +342,91 @@ static void testScalarArrayCommon(String /*fieldName*/,ScalarType stype)
values[2] = "2";
convert->fromStringArray(scalarArray, 0,3,values,0);
}
builder.clear();
pvStructure->toString(&builder);
if(debug) printf("%s\n",builder.c_str());
if(debug)
std::cout << *pvStructure << std::endl;
PVFieldPtr pvField = pvStructure->getSubField("alarm.status");
pvField->message("this is a test",infoMessage);
testOk1(pvField!=NULL);
}
static void testScalarArray()
{
if(debug) printf("\ntestScalarArray\n");
testScalarArrayCommon(String("boolean"),pvBoolean);
testScalarArrayCommon(String("byte"),pvByte);
testScalarArrayCommon(String("short"),pvShort);
testScalarArrayCommon(String("int"),pvInt);
testScalarArrayCommon(String("long"),pvLong);
testScalarArrayCommon(String("float"),pvFloat);
testScalarArrayCommon(String("double"),pvDouble);
testScalarArrayCommon(String("string"),pvString);
printf("testScalarArray PASSED\n");
if(debug)
std::cout << std::endl << "testScalarArray" << std::endl;
testScalarArrayCommon(string("boolean"),pvBoolean);
testScalarArrayCommon(string("byte"),pvByte);
testScalarArrayCommon(string("short"),pvShort);
testScalarArrayCommon(string("int"),pvInt);
testScalarArrayCommon(string("long"),pvLong);
testScalarArrayCommon(string("float"),pvFloat);
testScalarArrayCommon(string("double"),pvDouble);
testScalarArrayCommon(string("string"),pvString);
std::cout << "testScalarArray PASSED" << std::endl;
}
static void testRequest()
{
if(debug)
std::cout << std::endl << "testScalarArray" << std::endl;
StringArray nullNames;
FieldConstPtrArray nullFields;
StringArray optionNames(1);
FieldConstPtrArray optionFields(1);
optionNames[0] = "process";
optionFields[0] = fieldCreate->createScalar(pvString);
StringArray recordNames(1);
FieldConstPtrArray recordFields(1);
recordNames[0] = "_options";
recordFields[0] = fieldCreate->createStructure(optionNames,optionFields);
StringArray fieldNames(2);
FieldConstPtrArray fieldFields(2);
fieldNames[0] = "alarm";
fieldFields[0] = fieldCreate->createStructure(nullNames,nullFields);
fieldNames[1] = "timeStamp";
fieldFields[1] = fieldCreate->createStructure(nullNames,nullFields);
StringArray topNames(2);
FieldConstPtrArray topFields(2);
topNames[0] = "record";
topFields[0] = fieldCreate->createStructure(recordNames,recordFields);
topNames[1] = "field";
topFields[1] = fieldCreate->createStructure(fieldNames,fieldFields);
StructureConstPtr topStructure = fieldCreate->createStructure(
topNames,topFields);
cout << *topStructure << endl;
PVStructurePtr pvTop = pvDataCreate->createPVStructure(topStructure);
cout << *pvTop << endl;
cout << *pvTop->getStructure() << endl;
PVStructurePtr xxx = pvTop->getSubField<PVStructure>("record");
cout << *xxx << endl;
xxx = pvTop->getSubField<PVStructure>("field");
cout << *xxx << endl;
PVStringPtr pvString = pvTop->getSubField<PVString>("record._options.process");
pvString->put("true");
cout << *pvTop << endl;
string subName("record._options.process");
PVFieldPtr pvField = pvTop->getSubField(subName);
string fieldName = pvField->getFieldName();
string fullName = pvField->getFullName();
cout << "fieldName " << fieldName << " fullName " << fullName << endl;
testOk1(fieldName.compare("process")==0);
testOk1(fullName.compare(subName)==0);
}
MAIN(testPVData)
{
testPlan(179);
testPlan(189);
fieldCreate = getFieldCreate();
pvDataCreate = getPVDataCreate();
standardField = getStandardField();
standardPVField = getStandardPVField();
convert = getConvert();
testAppend();
testCreatePVStructure();
testPVScalar();
testScalarArray();
testRequest();
return testDone();
}

View File

@@ -26,6 +26,8 @@
using namespace epics::pvData;
using std::tr1::static_pointer_cast;
using std::cout;
using std::endl;
namespace {

View File

@@ -11,6 +11,7 @@
#include <cstddef>
#include <string>
#include <cstdio>
#include <sstream>
#include <epicsUnitTest.h>
#include <testMain.h>
@@ -23,16 +24,18 @@
using namespace epics::pvData;
using std::tr1::static_pointer_cast;
using std::string;
static bool debug = false;
static FieldCreatePtr fieldCreate = getFieldCreate();
static StandardFieldPtr standardField = getStandardField();
static String builder("");
static void print(String name)
static void print(const string& name, FieldConstPtr const & f)
{
if(debug) printf("\n%s\n%s\n",name.c_str(),builder.c_str());
if(debug) {
std::cout << std::endl << name << std::endl << *f << std::endl;
}
}
MAIN(testStandardField)
@@ -40,19 +43,13 @@ MAIN(testStandardField)
testPlan(1);
StructureConstPtr doubleValue = standardField->scalar(pvDouble,
"alarm,timeStamp,display,control,valueAlarm");
builder.clear();
doubleValue->toString(&builder);
print("doubleValue");
print("doubleValue", doubleValue);
StructureConstPtr stringArrayValue = standardField->scalarArray(pvString,
"alarm,timeStamp");
builder.clear();
stringArrayValue->toString(&builder);
print("stringArrayValue");
print("stringArrayValue", stringArrayValue);
StructureConstPtr enumeratedValue = standardField->enumerated(
"alarm,timeStamp,valueAlarm");
builder.clear();
enumeratedValue->toString(&builder);
print("enumeratedValue");
print("enumeratedValue", enumeratedValue);
FieldConstPtrArray fields;
fields.reserve(2);
fields.push_back(fieldCreate->createScalar(pvDouble));
@@ -63,9 +60,16 @@ MAIN(testStandardField)
fieldNames.push_back("arrayValue");
StructureConstPtr structure = fieldCreate->createStructure(fieldNames, fields);
StructureConstPtr structureArrayValue = standardField->structureArray(structure, "alarm,timeStamp");
builder.clear();
structureArrayValue->toString(&builder);
print("structureArrayValue");
print("structureArrayValue", structureArrayValue);
StructureConstPtr punion = standardField->regUnion(
fieldCreate->createFieldBuilder()->
add("doubleValue", pvDouble)->
add("intValue", pvInt)->
add("timeStamp",standardField->timeStamp())->
createUnion(),
"alarm,timeStamp");
print("unionValue", punion);
testPass("testStandardField");
return testDone();
}

Some files were not shown because too many files have changed in this diff Show More