Proposed pvData.h interface
This commit is contained in:
@@ -37,7 +37,7 @@
|
||||
<h1>EPICS Array</h1>
|
||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
||||
|
||||
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 13-Jun-2013</h2>
|
||||
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 18-Jun-2013</h2>
|
||||
|
||||
<dl>
|
||||
<dt>Latest version:</dt>
|
||||
@@ -67,14 +67,398 @@ license.</a></p>
|
||||
|
||||
|
||||
<h2>Introduction</h2>
|
||||
<p>This is the documentation for the scalarArray data type as defined by pvDataCPP-md.
|
||||
When complete it will be merged into pvDataCPP.html.
|
||||
Only sharedVector is currently documented.
|
||||
It is documented in the next section, but when merged into pvDataCPP.html,
|
||||
will appear in a later section.
|
||||
For now ignore the documentation in pvDataApp/pv.</p>
|
||||
<p>When <b>NOTE EXISTING</b> appears it means that there is a question about
|
||||
the existing shared_vector implementation.</p>
|
||||
<p>This is the documentation for pvData.h as defined by pvDataCPP-md.
|
||||
When complete it will be merged into pvDataCPP.html.</p>
|
||||
<p>
|
||||
pvData provides an interface for network accessible structured data.
|
||||
The interfaces for C++ and Java are similar.
|
||||
Thus someone who understands the interface in one of the languages
|
||||
and knows both languages will quickly understand the interface of the other language.
|
||||
With only a few exceptions the naming and other conventions do
|
||||
not follow the C++ standard library conventions.
|
||||
The definition of pvData is similar to the definition for Java.
|
||||
The differences are mainly related to language differences.
|
||||
Some differences are:
|
||||
<dl>
|
||||
<dt>shared pointers</dt>
|
||||
<dd>Java has a garbage collector. In C++ the implementation manages
|
||||
memory. The primary tool is std::tr1::shared_ptr.</dd>
|
||||
<dt>PVArray</dt>
|
||||
<dd>The Java garbage collector allows raw data arrays, e. g. int[],
|
||||
to be shared. For C++ a shared_vector holds the raw data.
|
||||
</dd>
|
||||
<dt>ostream replaces toString</dt>
|
||||
<dd>In Java every object has method toString.
|
||||
For C++ operator<< replaces toString</dd>
|
||||
<dt>shared_vector</dt>
|
||||
<dd>This is similar to std::vector but uses a shared_ptr to wrap the raw
|
||||
data and also supports a window into the raw data. It does follow
|
||||
naming and other conventions for C++ standard library containers.</dd>
|
||||
</dl>
|
||||
<p>There is one big difference from the existing Java implelentation:
|
||||
The method PVValueArray::get.
|
||||
As an example the Java definition for PVDoubleArray is currently:
|
||||
<pre>
|
||||
int get(int offset, int length, DoubleArrayData data);
|
||||
</pre>
|
||||
This document assumes this be replaced by:
|
||||
<pre>
|
||||
double[] get();
|
||||
</pre>
|
||||
<p>The existing version allowed the data source to provide the array in chunks.
|
||||
The new version assumes that the data source always provides contiguous storage
|
||||
for the entire raw array. If this is accepted it simplifies a lot of code.
|
||||
</p>
|
||||
<p>Three topics not discussed in this document are:
|
||||
<dl>
|
||||
<dt>pvDataCreate</dt>
|
||||
<dd>There should be a new method something like:
|
||||
<pre>
|
||||
PVScalarArrayPtr createPVScalarArray(const PVScalarArray &, size_t offset, size_t length);
|
||||
</pre>
|
||||
This will share the raw data array but allow a new window.
|
||||
</dd>
|
||||
<dt>convert</dt>
|
||||
<dd>This will be changed to do conversions itself instead of calling
|
||||
methods like getAs. It will again support methods toXXXArray and fromXXXArray,
|
||||
with a raw array replaced by a shared_vector.
|
||||
Templates should be able to minimize the code required.</dd>
|
||||
<dt>PVStructureArray</dt>
|
||||
<dd>Can this also use shared_vector to hold elements?</dd>
|
||||
</dl>
|
||||
</p>
|
||||
<h2>pvDataApp/pv</h2>
|
||||
<h3>pvData.h</h3>
|
||||
<p>This provides the interface for network accessible data.
|
||||
Although templates are used to minimize the amount of code,
|
||||
the interface is <b>not</b> meant to be extended.
|
||||
Only the types defined by pvIntrospect are implemented.</p>
|
||||
|
||||
<h4>PVField</h4>
|
||||
<pre>
|
||||
class PVField
|
||||
: virtual public Serializable,
|
||||
public std::tr1::enable_shared_from_this<PVField>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVField);
|
||||
virtual ~PVField();
|
||||
virtual void message(String message,MessageType messageType);
|
||||
const String& getFieldName() const;
|
||||
String getFullName() const;
|
||||
virtual void setRequester(RequesterPtr const &prequester);
|
||||
std::size_t getFieldOffset() const;
|
||||
std::size_t getNextFieldOffset() const;
|
||||
std::size_t getNumberFields() const;
|
||||
PVAuxInfoPtr & getPVAuxInfo();
|
||||
bool isImmutable() const;
|
||||
void setImmutable();
|
||||
const FieldConstPtr & getField() const;
|
||||
PVStructure * getParent() const;
|
||||
void replacePVField(const PVFieldPtr& newPVField);
|
||||
void renameField(String const & newName);
|
||||
void postPut();
|
||||
void setPostHandler(PostHandlerPtr const &postHandler);
|
||||
virtual std::ostream& operator<<(std::ostream& o) const;
|
||||
std::ostream& operator<<(std::ostream& o, size_t index) const;
|
||||
...
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const PVFieldPtr & f);
|
||||
std::ostream& operator<<(std::ostream& o, const PVFieldPtr & f, size_t index);
|
||||
</pre>
|
||||
<p>The public methods for PVField are:</p>
|
||||
<dl>
|
||||
<dt>~PVField</dt>
|
||||
<dd>Destructor. Since shared pointers are used it should never be called by
|
||||
user code.</dd>
|
||||
<dt>message</dt>
|
||||
<dd>Code attached to this field can call this method to report
|
||||
problems.</dd>
|
||||
<dt>getFieldName</dt>
|
||||
<dd>Get the field name. If the field is a top level structure the field
|
||||
name will be an empty string.</dd>
|
||||
<dt>setRequester</dt>
|
||||
<dd>Sets a requester to be called when message or getRequesterName are
|
||||
called. This is only legal for the top level PVField. </dd>
|
||||
<dt>getFieldOffset</dt>
|
||||
<dd>Get offset of the PVField field within top level structure. Every field
|
||||
within the PVStructure has a unique offset. The top level structure has
|
||||
an offset of 0. The first field within the structure has offset equal to
|
||||
1. The other offsets are determined by recursively traversing each
|
||||
structure of the tree. </dd>
|
||||
<dt>getNextFieldOffset</dt>
|
||||
<dd>Get the next offset. If the field is a scalar or array field then this
|
||||
is just offset + 1. If the field is a structure it is the offset of the
|
||||
next field after this structure. Thus (nextOffset - offset) is always
|
||||
equal to the total number of fields within the field. </dd>
|
||||
<dt>getNumberFields</dt>
|
||||
<dd>Get the total number of fields in this field. This is nextFieldOffset -
|
||||
fieldOffset. </dd>
|
||||
<dt>getPVAuxInfo</dt>
|
||||
<dd>Get the PVAuxInfo for this field. PVAuxInfo is described below.</dd>
|
||||
<dt>isImmutable</dt>
|
||||
<dd>Is the field immutable?</dd>
|
||||
<dt>setImmutable</dt>
|
||||
<dd>Make the field immutable. Once a field is immutable it can never be
|
||||
changed since there is no method to again make it mutable. This is an
|
||||
important design decision since it allows immutable array fields to share
|
||||
the internal primitive data array.</dd>
|
||||
<dt>getField</dt>
|
||||
<dd>Get the reflection interface for the data.</dd>
|
||||
<dt>getParent</dt>
|
||||
<dd>Get the interface for the parent or null if this is the top level
|
||||
PVStructure.</dd>
|
||||
<dt>replacePVField</dt>
|
||||
<dd>Replace the data implementation for the field.</dd>
|
||||
<dt>renameField</dt>
|
||||
<dd>Rename the field name. </dd>
|
||||
<dt>postPut</dt>
|
||||
<dd>If a postHandler is registered it is called otherwise no action is
|
||||
taken.</dd>
|
||||
<dt>setPostHandler</dt>
|
||||
<dd>Set the postHandler for the record. Only a single handler can be
|
||||
registered.</dd>
|
||||
<dt>operator<<</dt>
|
||||
<dd>Stream output</dt>
|
||||
</dl>
|
||||
<h4>PVScalar</h4>
|
||||
<pre>
|
||||
class PVScalar : public PVField {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVScalar);
|
||||
virtual ~PVScalar();
|
||||
|
||||
typedef PVScalar &reference;
|
||||
typedef const PVScalar& const_reference;
|
||||
|
||||
const ScalarConstPtr getScalar() const;
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
<p>where</p>
|
||||
<dl>
|
||||
<dt>getScalar</dt>
|
||||
<dd>Get the introspection interface for the PVScalar.</dd>
|
||||
</dl>
|
||||
|
||||
<h4>PVScalarValue</h4>
|
||||
<pre>
|
||||
template<typename T>
|
||||
class PVScalarValue : public PVScalar {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVScalarValue);
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
|
||||
virtual ~PVScalarValue() {}
|
||||
virtual T get() const = 0;
|
||||
virtual void put(T value) = 0;
|
||||
|
||||
std::ostream& operator<<(std::ostream& o) const
|
||||
std::ostream& operator<<(std::ostream& o, size_t index) const;
|
||||
...
|
||||
};
|
||||
typedef PVScalarValue<uint8> PVBoolean;
|
||||
typedef PVScalarValue<int8> PVByte;
|
||||
typedef PVScalarValue<int16> PVShort;
|
||||
typedef PVScalarValue<int32> PVInt;
|
||||
typedef PVScalarValue<int64> PVLong;
|
||||
typedef PVScalarValue<uint8> PVUByte;
|
||||
typedef PVScalarValue<uint16> PVUShort;
|
||||
typedef PVScalarValue<uint32> PVUInt;
|
||||
typedef PVScalarValue<uint64> PVULong;
|
||||
typedef PVScalarValue<float> PVFloat;
|
||||
typedef PVScalarValue<double> PVDouble;
|
||||
typedef std::tr1::shared_ptr<PVBoolean> PVBooleanPtr;
|
||||
typedef std::tr1::shared_ptr<PVByte> PVBytePtr;
|
||||
typedef std::tr1::shared_ptr<PVShort> PVShortPtr;
|
||||
typedef std::tr1::shared_ptr<PVInt> PVIntPtr;
|
||||
typedef std::tr1::shared_ptr<PVLong> PVLongPtr;
|
||||
typedef std::tr1::shared_ptr<PVUByte> PVUBytePtr;
|
||||
typedef std::tr1::shared_ptr<PVUShort> PVUShortPtr;
|
||||
typedef std::tr1::shared_ptr<PVUInt> PVUIntPtr;
|
||||
typedef std::tr1::shared_ptr<PVULong> PVULongPtr;
|
||||
typedef std::tr1::shared_ptr<PVFloat> PVFloatPtr;
|
||||
typedef std::tr1::shared_ptr<PVDouble> PVDoublePtr;
|
||||
|
||||
// PVString is special case, since it implements SerializableArray
|
||||
class PVString : public PVScalarValue<String>, SerializableArray {
|
||||
public:
|
||||
virtual ~PVString() {}
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
|
||||
<p>where</p>
|
||||
<dl>
|
||||
<dt>get</dt>
|
||||
<dd>Get the value stored in the object.</dd>
|
||||
<dt>put</dt>
|
||||
<dd>Change the value stored in the object.</dd>
|
||||
<dt>operator<<</dt>
|
||||
<dd>Methods for stream I/O.</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<h4>PVArray</h4>
|
||||
|
||||
<p>PVArray is the base interface for all the other PV Array interfaces. It
|
||||
extends PVField and provides the additional methods:</p>
|
||||
<pre>class PVArray : public PVField, public SerializableArray {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVArray);
|
||||
virtual ~PVArray();
|
||||
virtual std::size_t getLength() const = 0;
|
||||
virtual void setLength(std::size_t length) = 0;
|
||||
bool isCapacityMutable() const;
|
||||
void setCapacityMutable(bool isMutable);
|
||||
virtual std::size_t getCapacity() const = 0;
|
||||
virtual void setCapacity(std::size_t capacity) = 0;
|
||||
...
|
||||
};</pre>
|
||||
<dl>
|
||||
<dt>getLength</dt>
|
||||
<dd>Get the current length. This is less than or equal to the capacity.</dd>
|
||||
<dt>setLength</dt>
|
||||
<dd>Set the length. If the PVField is not mutable then an exception is
|
||||
thrown. If this is greater than the capacity setCapacity is called.</dd>
|
||||
<dt>isCapacityMutable</dt>
|
||||
<dd>Is the capacity mutable</dd>
|
||||
<dt>setCapacityMutable</dt>
|
||||
<dd>Specify if the capacity can be changed.</dd>
|
||||
<dt>getCapacity</dt>
|
||||
<dd>Get the capacity, i.e. this is the size of the underlying data
|
||||
array.</dd>
|
||||
<dt>setCapacity</dt>
|
||||
<dd>Set the capacity. The semantics are implementation dependent but
|
||||
typical semantics are as follows: If the capacity is not mutable an
|
||||
exception is thrown. A new data array is created and data is copied from
|
||||
the old array to the new array. </dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<h4>PVScalarArray</h4>
|
||||
|
||||
<p>PVScalarArray is the base class for scalar array data. PVValueArray is a
|
||||
templete for the various scalar array data classes. There is a class for each
|
||||
possible scalar type, i. e. PVBooleanArray, ..., PVStringArray.</p>
|
||||
<pre>class PVScalarArray : public PVArray {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVScalarArray);
|
||||
typedef PVScalarArray &reference;
|
||||
typedef const PVScalarArray& const_reference;
|
||||
|
||||
virtual ~PVScalarArray();
|
||||
const ScalarArrayConstPtr getScalarArray() const;
|
||||
...
|
||||
};
|
||||
|
||||
// PVString is special case, since it implements SerializableArray
|
||||
class PVString : public PVScalarValue<String>, SerializableArray {
|
||||
public:
|
||||
virtual ~PVString() {}
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
|
||||
<p>where</p>
|
||||
<dl>
|
||||
<dt>getScalarArray</dt>
|
||||
<dd>Get the introspection interface.</dd>
|
||||
</dl>
|
||||
|
||||
<h4>PVValueArray</h4>
|
||||
|
||||
<p>This is a template class plus instances for PVBooleanArray, ...,
|
||||
PVStringArray.</p>
|
||||
<pre>template<typename T>
|
||||
class PVValueArray :
|
||||
public PVScalarArray
|
||||
...
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVValueArray);
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef PVValueArray & reference;
|
||||
typedef const PVValueArray & const_reference;
|
||||
|
||||
typedef shared_vector<T> svector;
|
||||
typedef shared_vector<const T> const_svector;
|
||||
|
||||
virtual ~PVValueArray() {}
|
||||
const_svector & get();
|
||||
size_t put(size_t offset,size_t length, const_svector &from, size_t fromOffset);
|
||||
|
||||
void shareData(const_svector &from);
|
||||
|
||||
virtual std::ostream& operator<<(std::ostream& o) const;
|
||||
std::ostream& operator<<(std::ostream& o, size_t index) const;
|
||||
...
|
||||
};
|
||||
|
||||
typedef PVValueArray<uint8> PVBooleanArray;
|
||||
typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
|
||||
|
||||
typedef PVValueArray<int8> PVByteArray;
|
||||
typedef std::tr1::shared_ptr<PVByteArray> PVByteArrayPtr;
|
||||
|
||||
typedef PVValueArray<int16> PVShortArray;
|
||||
typedef std::tr1::shared_ptr<PVShortArray> PVShortArrayPtr;
|
||||
|
||||
typedef PVValueArray<int32> PVIntArray;
|
||||
typedef std::tr1::shared_ptr<PVIntArray> PVIntArrayPtr;
|
||||
|
||||
typedef PVValueArray<int64> PVLongArray;
|
||||
typedef std::tr1::shared_ptr<PVLongArray> PVLongArrayPtr;
|
||||
|
||||
typedef PVValueArray<uint8> PVUByteArray;
|
||||
typedef std::tr1::shared_ptr<PVUByteArray> PVUByteArrayPtr;
|
||||
|
||||
typedef PVValueArray<uint16> PVUShortArray;
|
||||
typedef std::tr1::shared_ptr<PVUShortArray> PVUShortArrayPtr;
|
||||
|
||||
typedef PVValueArray<uint32> PVUIntArray;
|
||||
typedef std::tr1::shared_ptr<PVUIntArray> PVUIntArrayPtr;
|
||||
|
||||
typedef PVValueArray<uint64> PVULongArray;
|
||||
typedef std::tr1::shared_ptr<PVULongArray> PVULongArrayPtr;
|
||||
|
||||
typedef PVValueArray<float> PVFloatArray;
|
||||
typedef std::tr1::shared_ptr<PVFloatArray> PVFloatArrayPtr;
|
||||
|
||||
typedef PVValueArray<double> PVDoubleArray;
|
||||
typedef std::tr1::shared_ptr<PVDoubleArray> PVDoubleArrayPtr;
|
||||
|
||||
typedef PVValueArray<String> PVStringArray;
|
||||
typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
|
||||
</pre>
|
||||
|
||||
<p>where</p>
|
||||
<dl>
|
||||
<dt>get</dt>
|
||||
<dd>Get the shared_vector that holds the data.
|
||||
Code that calls this is able to modify the array elements
|
||||
but should be very careful if it does.
|
||||
For example it must call postPut after modifying the array elements.
|
||||
It must also respect isImmutable().
|
||||
</dd>
|
||||
<dt>put</dt>
|
||||
<dd>This is the recommended method for modifying the array elements.
|
||||
It may change the capacity if len asks for more elements
|
||||
than the cureent capacity allows.
|
||||
It does not change the current length.
|
||||
</dd>
|
||||
<dt>shareData</dt>
|
||||
<dd>Share data with an existing shared_vector.
|
||||
Note that if capacity is every changed then data will no
|
||||
longer be shared.</dd>
|
||||
<dt>operator<<</dt>
|
||||
<dd>Methods for stream I/O.</dd>
|
||||
</dl>
|
||||
|
||||
<h2>shared_vector</h2>
|
||||
<h3>Status</h3>
|
||||
@@ -82,6 +466,8 @@ the existing shared_vector implementation.</p>
|
||||
are now documented, but not all have a description or example.
|
||||
Thus the documentation needs more work.
|
||||
</p>
|
||||
<p>When <b>NOTE EXISTING</b> appears it means that there is a question about
|
||||
the existing shared_vector implementation.</p>
|
||||
<h3>Introduction</h3>
|
||||
<p>A shared_vector is a container as defined by the C++ standard library.
|
||||
It is like std::vector but provides two additional features
|
||||
@@ -738,260 +1124,6 @@ use_count 1 offset 0 count 16 total 16
|
||||
<h4>specialization for untyped pointers</h4>
|
||||
<p>Not yet documented</p>
|
||||
|
||||
<h2>pvDataApp/pv</h2>
|
||||
<p><b>INGORE REST OF DOCUMENT!!!!</b></p>
|
||||
<h3>pvData.h</h3>
|
||||
|
||||
<h4>PVArray</h4>
|
||||
|
||||
<p>PVArray is the base interface for all the other PV Array interfaces. It
|
||||
extends PVField and provides the additional methods:</p>
|
||||
<pre>class PVArray : public PVField, public SerializableArray {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVArray);
|
||||
virtual ~PVArray();
|
||||
virtual void setImmutable();
|
||||
std::size_t getLength() const;
|
||||
virtual void setLength(std::size_t length);
|
||||
std::size_t getCapacity() const;
|
||||
bool isCapacityMutable() const;
|
||||
void setCapacityMutable(bool isMutable);
|
||||
virtual void setCapacity(std::size_t capacity) = 0;
|
||||
...
|
||||
};</pre>
|
||||
<dl>
|
||||
<dt>setImmutable</dt>
|
||||
<dd>Set the data immutable. Note that this is permanent since there is no
|
||||
methods to make it mutable.</dd>
|
||||
<dt>getLength</dt>
|
||||
<dd>Get the current length. This is less than or equal to the capacity.</dd>
|
||||
<dt>setLength</dt>
|
||||
<dd>Set the length. If the PVField is not mutable then an exception is
|
||||
thrown. If this is greater than the capacity setCapacity is called.</dd>
|
||||
<dt>getCapacity</dt>
|
||||
<dd>Get the capacity, i.e. this is the size of the underlying data
|
||||
array.</dd>
|
||||
<dt>setCapacity</dt>
|
||||
<dd>Set the capacity. The semantics are implementation dependent but
|
||||
typical semantics are as follows: If the capacity is not mutable an
|
||||
exception is thrown. A new data array is created and data is copied from
|
||||
the old array to the new array. </dd>
|
||||
<dt>isCapacityMutable</dt>
|
||||
<dd>Is the capacity mutable</dd>
|
||||
<dt>setCapacityMutable</dt>
|
||||
<dd>Specify if the capacity can be changed.</dd>
|
||||
<dt>setCapacity</dt>
|
||||
<dd>Set the capaciity.</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<h4>PVScalarArray</h4>
|
||||
|
||||
<p>PVScalarArray is the base class for scalar array data. PVValueArray is a
|
||||
templete for the various scalar array data classes. There is a class for each
|
||||
possible scalar type, i. e. PVBooleanArray, ..., PVStringArray.</p>
|
||||
<pre>class PVScalarArray : public PVArray {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVScalarArray);
|
||||
virtual ~PVScalarArray();
|
||||
typedef PVScalarArray &reference;
|
||||
typedef const PVScalarArray& const_reference;
|
||||
const ScalarArrayConstPtr getScalarArray() const ;
|
||||
virtual std::ostream& dumpValue(std::ostream& o, size_t index) const = 0;
|
||||
...
|
||||
}</pre>
|
||||
|
||||
<p>where</p>
|
||||
<dl>
|
||||
<dt>getScalarArray</dt>
|
||||
<dd>Get the introspection interface.</dd>
|
||||
<dt>dumpValue</dt>
|
||||
<dd>Method for streams I/O.</dd>
|
||||
</dl>
|
||||
|
||||
<h4>PVValueArray</h4>
|
||||
|
||||
<p>This is a template class plus instances for PVBooleanArray, ...,
|
||||
PVStringArray.</p>
|
||||
<pre>template<typename T>
|
||||
class PVValueArray : public PVScalarArray {
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVValueArray);
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
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;
|
||||
|
||||
virtual ~PVValueArray() {}
|
||||
virtual std::size_t get(
|
||||
std::size_t offset, std::size_t length, ArrayDataType &data) = 0;
|
||||
virtual std::size_t put(std::size_t offset,
|
||||
std::size_t length, const_pointer from, std::size_t fromOffset) = 0;
|
||||
virtual std::size_t put(std::size_t offset,
|
||||
std::size_t length, const_vector &from, std::size_t fromOffset);
|
||||
virtual void shareData(
|
||||
shared_vector const & value,
|
||||
std::size_t capacity,
|
||||
std::size_t length) = 0;
|
||||
virtual pointer get() = 0;
|
||||
virtual pointer get() const = 0;
|
||||
virtual vector const & getVector() = 0;
|
||||
virtual shared_vector const & getSharedVector() = 0;
|
||||
std::ostream& dumpValue(std::ostream& o) const;
|
||||
std::ostream& dumpValue(std::ostream& o, size_t index) const;
|
||||
protected:
|
||||
PVValueArray(ScalarArrayConstPtr const & scalar)
|
||||
: PVScalarArray(scalar) {}
|
||||
friend class PVDataCreate;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
std::size_t PVValueArray<T>::put(
|
||||
std::size_t offset,
|
||||
std::size_t length,
|
||||
const_vector &from,
|
||||
std::size_t fromOffset)
|
||||
{ return put(offset,length, &from[0], fromOffset); }
|
||||
|
||||
/**
|
||||
* Definitions for the various scalarArray types.
|
||||
*/
|
||||
typedef PVArrayData<uint8> BooleanArrayData;
|
||||
typedef PVValueArray<uint8> 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 std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;</pre>
|
||||
|
||||
<p>where</p>
|
||||
<dl>
|
||||
<dt>get( std::size_t offset, std::size_t length, ArrayDataType &data)
|
||||
</dt>
|
||||
<dd>This method "exposes" it's internal array by setting data.data and
|
||||
data.offset. The caller is responsible for copying the array elements.
|
||||
This violates the principle that objects should not expose their internal
|
||||
data but is done for efficency. For example it makes it possible to copy
|
||||
between arrays with identical element types without requiring an
|
||||
intermediate array.</dd>
|
||||
<dt>put(std::size_t offset, std::size_t length, const_pointer from,
|
||||
std::size_t fromOffset)</dt>
|
||||
<dd>Put data into the array. from is a raw array.</dd>
|
||||
<dt>put(std::size_t offset, std::size_t length, const_vector &from,
|
||||
std::size_t fromOffset)</dt>
|
||||
<dd>Put data into the array from a vector holding the raw array.</dd>
|
||||
<dt>shareData( shared_vector const & value, std::size_t capacity,
|
||||
std::size_t length)</dt>
|
||||
<dd>Make the instance share the raw data from value.<br />
|
||||
One use is
|
||||
for immutable arrays. In this case the caller must set the PVArray to be
|
||||
immutable. In the PVArray is not immutable then it is the applications
|
||||
responsibility to coordinate access to the array. Again this violates the
|
||||
principle that objects should not expose their internal data but is
|
||||
important for immutable arrays. For example pvData and the javaIOC define
|
||||
many enumerated structures where an enumerated structure has two fields:
|
||||
index and choices. Choices is a PVStringArray that holds the enumerated
|
||||
choices. Index is a PVInt that is the index of the currently selected
|
||||
choice. For many enumerated structures choices is immutable. Allowing the
|
||||
choices internal String[] to be shared between all the instances of an
|
||||
enumerated structure saves on storage.<br />
|
||||
Another use for shared data is an application which processes an
|
||||
array via multiple modules. Each accesses the internal data array of a
|
||||
PVArray. In this case it is the applications responsibility
|
||||
to coordinate access to the array.</dd>
|
||||
<dt>get()</dt>
|
||||
<dd>Get the raw array.</dd>
|
||||
<dt>getVector()</dt>
|
||||
<dd>Get the vector holding the raw array.</dd>
|
||||
<dt>getSharedVector()</dt>
|
||||
<dd>Get the shared vector holding the data.</dd>
|
||||
<dt>dumpValue</dt>
|
||||
<dd>Method for streams I/O.</dd>
|
||||
</dl>
|
||||
|
||||
<p>Both get and put return the number of elements actually transfered. The
|
||||
arguments are:</p>
|
||||
<dl>
|
||||
<dt>offset</dt>
|
||||
<dd>The offset in the PV array.</dd>
|
||||
<dt>len</dt>
|
||||
<dd>The maximum number of elements to transfer. The number actually
|
||||
transfered will be less than or equal to this value.</dd>
|
||||
<dt>data</dt>
|
||||
<dd>Get sets data.data to it's internal array and data.offset to the offset
|
||||
into the array. The caller is responsible for the actual data
|
||||
transfer.</dd>
|
||||
<dt>from</dt>
|
||||
<dd>The array from which the data is taken. This array is supplied by the
|
||||
caller</dd>
|
||||
<dt>fromOffset</dt>
|
||||
<dd>The offset in from</dd>
|
||||
</dl>
|
||||
|
||||
<p>The caller must be prepared to make multiple calls to retrieve or put an
|
||||
entire array. A caller should accept or put partial arrays. For example the
|
||||
following reads an entire array:</p>
|
||||
<pre>void getArray(PVDoubleArrayPtr & pv,DoubleArray const & to)
|
||||
{
|
||||
size_t len = pv->getLength();
|
||||
if(to.size()<len) to.resize(len);
|
||||
DoubleArrayData data;
|
||||
size_t offset = 0;
|
||||
while(offset<len) {
|
||||
size_t num = pv->get(offset,(len-offset),data);
|
||||
DoubleArray &from = data.data;
|
||||
size_t fromOffset = data.offset;
|
||||
for(size_t i=0; i<num; i++) to[i+offset] = from[i + fromOffset];
|
||||
offset += num;
|
||||
}
|
||||
} </pre>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user