diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html index 312e958..d352187 100644 --- a/documentation/pvDataCPP.html +++ b/documentation/pvDataCPP.html @@ -37,7 +37,7 @@

EPICS pvDataCPP

-

EPICS v4 Working Group, Working Draft, 16-May-2013

+

EPICS v4 Working Group, Working Draft, 28-Oct-2013

Latest version:
@@ -46,14 +46,16 @@
This version:
pvDataCPP_20130516.html + href="pvDataCPP_20131023.html">pvDataCPP_20131023.html
Previous version:
pvDataCPP_20121212.html + href="pvDataCPP_20130516.html">pvDataCPP_20130516.html
Editors:
Marty Kraimer, BNL
+
Michael Davidsaver, BNL
+
Matej Sekoranja, CosyLab

Abstract

-

pvDataCPP is a computer software package for the efficient -storage, access, and communication, of structured data. It is specifically the -C++ implementation of pvData, which is one part of the set of related products in the EPICS +

PVData is a computer software package for the efficient +storage, access, and communication, of structured data. +pvDataCPP is the C++ implementation of pvData. +It is one part of the set of related products in the EPICS V4 control system programming environment:
relatedDocumentsV4.html

@@ -74,54 +77,21 @@ V4 control system programming environment:

Status of this Document

-

This is the 16-May-2013 version of the C++ implementation of pvData. -Since the last version changes were made to queue and to bitSetUtil. +

This is the 28-Oct-2013 version of the C++ implementation of pvData. +This version describes the changes since the 4.3.0 release of Epics Version 4.

The text describes software which is a complete implementation of pvData as currently planned by the EPICS V4 Working Group.

-

The following is a list of unresolved issues for pvDataCPP:

+

The major changes since the 4.3.0 release are:

-
PVArray
-
The implementation of the different array types (PVBooleanArray, ..., - PVStructureArray) all store the data as a shared pointer holding a - vector. A test case should be created to make sure that vector.size() is - the same as getLength()
-
PVArray Examples
-
The following examples should be provided: 1) use all the get methods. - 2) create an example that makes data available in chunks.
-
pvType Example
-
Create an example of how to use the array typedefs
-
Convert test
-
How can this be better tested?
-
Structure and PVStructure
-
These two classes still keep data via std::vector. - Should they keep it as std::tr1::shared_ptr<std::vector<... ?
- In particular change -
-class Structure
-...
-StringArray fieldNames;
-FieldConstPtrArray fields
-
-class PVStructure
-...
-PVFieldPtrArray pvFields;
-
-To -
-class Structure
-...
-StringArrayPtr fieldNames;
-FieldConstPtrArrayPtr fields
-
-class PVStructure
-...
-PVFieldPtrArrayPtr pvFields;
-
-If these are changed several methods also change so that raw vectors are never passed as -argument or returned from methods.
+
shared_vector
+
This provides many of the features of std:vector but uses std::shared_ptr + for the raw array.
+
Arrays
+

The implementation of PVValueArray and PVStructureArray now inforce Copy On Write (COW) + and use shared_vector for the raw array.

@@ -129,13 +99,12 @@ argument or returned from methods.
-

Introduction

pvData is one of a set of related projects. It describes and implements the data that the other projects support. Thus it is not useful by itself but understanding pvData is required in order to understand the other projects. The -reader should also become familar with projects pvAccess and pvIOC, which are +reader should also become familar with project pvAccess, which is located via the same sourceforge site as this project.

The Java and C++ implementation of pvData implement the same data model but @@ -168,7 +137,7 @@ href="./html/index.html">doxygenDoc

pvDataCPP introspection and data objects are designed to be shared. They are made availiable via std::tr1::shared_ptr. In addition arrays are -implemented via std::vector. The following naming conventions are used +implemented via shared_vector. The following naming conventions are used in typedefs:

Ptr
@@ -210,9 +179,9 @@ typedef std::vector<double>::const_iterator DoubleArray_const_iterator;

Overview -

Directory pvDataApp/pv has header files that completely describe pvData. The -implementation is provided in directory pvDataApp/factory. Test programs -appears in testApp/pv.

+

Directory pvDataApp/pv has header files that completely describe pvData. +The implementation is provided in directory pvDataApp/factory. +Test programs appears in testApp/pv.

NOTES:

@@ -266,7 +235,11 @@ proper semantics for the primitive types.

pvType.h provides the proper semantics.

It has the definitions:

-
typedef uint8_t  boolean;
+
+typedef detail::pick_type<int8_t, signed char,
+     detail::pick_type<uint8_t, char, unsigned char>::type
+     >::type boolean;
+
 typedef int8_t   int8;
 typedef int16_t  int16;
 typedef int32_t  int32;
@@ -301,7 +274,8 @@ inline ByteArray const & getVector(ByteArrayPtr const &value);
 typedef std::vector<int8>::iterator ByteArray_iterator;
 typedef std::vector<int8>::const_iterator ByteArray_const_iterator;
 
-/* similar definitions are present for ALL the primitive types */
+/* similar definitions are present for ALL the primitive types */ +

where

@@ -330,6 +304,19 @@ typedef std::vector<int8>::const_iterator ByteArray_const_iterator;
typedefs are provided for an array of each of the primitive types. Note that string is treated like a primitive type/
+

TBD +

+
boolean
+
Question for Michael. Why isn't the definition of boolean just +
+typedef uint8_t boolean;
+    
+
StringBuilder
+
Should this go away?
+
Array definitions
+
These should all be removed.
+
+

pvIntrospect.h

@@ -382,6 +369,7 @@ public: ScalarType getScalarType(String const &value); const char* name(ScalarType); void toString(StringBuilder buf,ScalarType scalarType); + size_t elementSize(ScalarType id); };

Type is one of the following:

@@ -452,7 +440,21 @@ public: return the scalarType.
toString
Convert the scalar type to a string.
+
elementSize
+
Returns the size in bytes of an instance of the scalarType.
+

TBD +

+
union
+
Types pvUnion and pvUnionArray should be added
+
toString
+
Should this be changed to +
+String toString(ScalarType scalarType);
+      
+
+
+

Introspection Description

@@ -472,12 +474,16 @@ following:

A scalar has a scalarType
ScalarArray
The element type is a scalarType
+
Structure
+
Has fields that can be any of the supported types.
StructureArray
The field holds an array of structures. Each element has the same Structure interspection interface. A pvAccess client can only get/put entire PVStructure elements NOT subfields of array elements.
-
Structure
-
Has fields that can be any of the supported types.
+
Union
+
TBD
+
UnionArray
+
TBD
FieldCreate
This is an interface that provides methods to create introspection interfaces. A factory is provides to create FieldCreate.
@@ -570,8 +576,7 @@ public: std::size_t getFieldIndex(String const &fieldName) const; FieldConstPtrArray const & getFields() const {return fields;} StringArray const & getFieldNames() const; - void renameField(std::size_t fieldIndex,String const &newName); - String getFieldName(std::size_t fieldIndex); + String getFieldName(std::size_t fieldIndex) const; virtual void toString(StringBuilder buf,int indentLevel) const; virtual String getID() const; virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const; @@ -592,13 +597,6 @@ public: String const &id, StringArray const & fieldNames, FieldConstPtrArray const & fields) const; - StructureConstPtr appendField( - StructureConstPtr const & structure, - String const &fieldName, FieldConstPtr const & field) const; - StructureConstPtr appendFields( - StructureConstPtr const & structure, - StringArray const & fieldNames, - FieldConstPtrArray const & fields) const; FieldConstPtr deserialize(ByteBuffer* buffer, DeserializableControl* control) const; ... }; @@ -666,8 +664,6 @@ extern FieldCreatePtr getFieldCreate();
Get the array of introspection interfaces for the field,
getFieldNames
Get the array of field names for the subfields.
-
renameField
-
Rename the field.
getFieldName
Get the field name for the specified index.
@@ -686,13 +682,19 @@ extern FieldCreatePtr getFieldCreate(); not. The one without will result in ID "structure".
createStructureArray
Create a structure array introspection instance.
-
appendField
-
Append a field to a structure.
-
appendFields
-
Append fields to a structure.
deserialize
Deserialize from given byte buffer.
+

TBD +

+
toString
+
Should all the toString methods be changed to just return String?
+
ScalarTypeTraits and ScalarTypeID
+
These seem to only be used by shared_vector. Do they need to be documented?
+
appendField and appendFields
+
These methods of FieldCreate should be removed.
+
+

standardField.h

@@ -801,6 +803,13 @@ public:
The above provide introspection interfaces for standard properties. See the section on Properties for a description of how these are defined.
+

TBD +

+
union
+
unionArray
+
When union is supported also add these.
+
+

pvData.h

@@ -811,20 +820,13 @@ showing the entire file, it will be described in parts.

These are typedefs for Array and Ptr for the various pvData class definitions, i.e. typdefs for "std::vector" and "std::tr1::shared_ptr".

-
class PVAuxInfo;
-class PostHandler;
-
+
 class PVField;
 class PVScalar;
-
 class PVScalarArray;
-
 class PVStructure;
 class PVStructureArray;
 
-typedef std::tr1::shared_ptr<PVAuxInfo> PVAuxInfoPtr;
-
-typedef std::tr1::shared_ptr<PostHandler> PostHandlerPtr;
 
 typedef std::tr1::shared_ptr<PVField> PVFieldPtr;
 typedef std::vector<PVFieldPtr> PVFieldPtrArray;
@@ -839,45 +841,108 @@ typedef std::vector<PVStructurePtr> PVStructurePtrArray;
 typedef std::vector<PVStructurePtr>::iterator PVStructurePtrArray_iterator;
 typedef std::vector<PVStructurePtr>::const_iterator PVStructurePtrArray_const__iterator;
 
-typedef std::tr1::shared_ptr<PostHandler> PostHandlerPtr
+typedef PVValueArray<PVStructurePtr> PVStructureArray; +typedef std::tr1::shared_ptr<PVStructureArray> PVStructureArrayPtr; +typedef std::vector<PVStructureArrayPtr> PVStructureArrayPtrArray; +typedef std::tr1::shared_ptr<PVStructureArrayPtrArray> PVStructureArrayPtrArrayPtr; -

PostHandler is a class that must be implemented by any code that calls -setPostHandler. It's single virtual method. postPut is called whenever -PVField::postPut is called.

-
class PostHandler 
-{
-public:
-    POINTER_DEFINITIONS(PostHandler);
-    virtual ~PostHandler(){}
-    virtual void postPut() = 0;
-};
+/** + * typedefs for the various possible scalar types. + */ +typedef PVScalarValue<boolean> 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; +class PVString; +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; +typedef std::tr1::shared_ptr<PVString> PVStringPtr; + +/** + * Definitions for the various scalarArray types. + */ +typedef PVValueArray<boolean> PVBooleanArray; +typedef PVValueArray<int8> PVByteArray; +typedef PVValueArray<int16> PVShortArray; +typedef PVValueArray<int32> PVIntArray; +typedef PVValueArray<int64> PVLongArray; +typedef PVValueArray<uint8> PVUByteArray; +typedef PVValueArray<uint16> PVUShortArray; +typedef PVValueArray<uint32> PVUIntArray; +typedef PVValueArray<uint64> PVULongArray; +typedef PVValueArray<float> PVFloatArray; +typedef PVValueArray<double> PVDoubleArray; +typedef PVValueArray<String> PVStringArray; + +typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr; +typedef std::tr1::shared_ptr<PVByteArray> PVByteArrayPtr; +typedef std::tr1::shared_ptr<PVShortArray> PVShortArrayPtr; +typedef std::tr1::shared_ptr<PVIntArray> PVIntArrayPtr; +typedef std::tr1::shared_ptr<PVLongArray> PVLongArrayPtr; +typedef std::tr1::shared_ptr<PVUByteArray> PVUByteArrayPtr; +typedef std::tr1::shared_ptr<PVUShortArray> PVUShortArrayPtr; +typedef std::tr1::shared_ptr<PVUIntArray> PVUIntArrayPtr; +typedef std::tr1::shared_ptr<PVULongArray> PVULongArrayPtr; +typedef std::tr1::shared_ptr<PVFloatArray> PVFloatArrayPtr; +typedef std::tr1::shared_ptr<PVDoubleArray> PVDoubleArrayPtr; +typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr; + +
+

TBD +

+
PVUnion
+
PVUnionArray
+
When union is supported.
+
WPtr
+
Should definitions for std::tr1::weak_ptr also be added.
+

PVField

PVField is the base interface for accessing data. A data structure consists of a top level PVStructure. Every field of every structure of every top level structure has a PVField associated with it.

-
class PVField
+
+class PostHandler
+{
+public:
+    POINTER_DEFINITIONS(PostHandler);
+    virtual ~PostHandler(){}
+    virtual void postPut() = 0;
+};
+
+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);
    String getFieldName() 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;
    virtual void setImmutable();
    const FieldConstPtr & getField() const ;
    PVStructure * getParent() const 
-   void replacePVField(const PVFieldPtr&  newPVField);
-   void renameField(String const &newName);
-   void postPut() ;
+   void postPut();
    void setPostHandler(PostHandlerPtr const &postHandler);
    virtual bool equals(PVField &pv);
    virtual void toString(StringBuilder buf) ;
@@ -891,15 +956,14 @@ public:
   
~PVField
Destructor. Since shared pointers are used it should never be called by user code.
-
message
-
Code attached to this field can call this method to report - problems.
getFieldName
Get the field name. If the field is a top level structure the field name will be an empty string.
-
setRequester
-
Sets a requester to be called when message or getRequesterName are - called. This is only legal for the top level PVField.
+
getFullName
+
Fully expand the name of this field using the + names of its parent fields with a dot '.' seperating + each name. +
getFieldOffset
Get offset of the PVField field within top level structure. Every field within the PVStructure has a unique offset. The top level structure has @@ -914,8 +978,6 @@ public:
getNumberFields
Get the total number of fields in this field. This is nextFieldOffset - fieldOffset.
-
getPVAuxInfo
-
Get the PVAuxInfo for this field. PVAuxInfo is described below.
isImmutable
Is the field immutable?
setImmutable
@@ -928,16 +990,15 @@ public:
getParent
Get the interface for the parent or null if this is the top level PVStructure.
-
replacePVField
-
Replace the data implementation for the field.
-
renameField
-
Rename the field name.
postPut
If a postHandler is registered it is called otherwise no action is taken.
setPostHandler
Set the postHandler for the record. Only a single handler can be - registered.
+ registered. + PostHandler is a class that must be implemented by any code that calls setPostHandler. + It's single virtual method. postPut is called whenever PVField::postPut is called. +
equals
Compare this field with another field. The result will be true only if the fields have exactly the same field types and if the data values are @@ -948,47 +1009,22 @@ public:
dumpValue
Method for streams I/O.
+

TBD -

PVAuxInfo

- -

AuxInfo (Auxillary Information) is information about a field that is -application specific. It will not be available outside the application that -implements the database. In particular it will not be made available to Channel -Access. It is used by the database itself to override the default -implementation of fields. The JavaIOC uses it for attaching support code. -Database Configuration and other tools can use it for configuration -information. Each Field and each PVField can have have an arbitrary number of -auxInfos. An auxInfo is a (key,PVScalar) pair where key is a string.

-
class PVAuxInfo : private NoDefaultMethods {
-public:
-    typedef std::map<String,PVScalarPtr> PVInfoMap;
-    typedef std::map<String,PVScalarPtr>::iterator PVInfoIter;
-    typedef std::pair<String,PVScalarPtr> PVInfoPair;
-
-    PVAuxInfo(PVField *pvField);
-    ~PVAuxInfo();
-    PVField * getPVField();
-    PVScalarPtr createInfo(String const &key,ScalarType scalarType);
-    PVScalarPtr getInfo(String const &key);
-    PVInfoMap & getInfoMap();
-    void toString(StringBuilder buf);
-    void toString(StringBuilder buf,int indentLevel);
- ...
-};
- -

where

-
getPVField
-
Get the PVField to which this PVAuxInfo is attached.
-
createInfo
-
Create a new PVScalar of type scalarType.
-
getInfo
-
Get the PVScalar with the specified key.
-
getInfoMap
-
Get the map of all the PVScalars that hold the info.
-
toString
-
Print all the auxInfos
+
getFullName
+
Should this be removed?
+
toString and dumpValue
+
Should these be replaced by: +
+virtual String toString() const;
+virtual std::ostream& operator<<(std::ostream& o) const = 0;
+
+
+
replaceField
+
This is a protected member that should be removed.
+

PVScalar

@@ -1000,6 +1036,8 @@ public: typedef PVScalar &reference; typedef const PVScalar& const_reference; const ScalarConstPtr getScalar() const ; + template<typename T> + T getAs() const; ... }
@@ -1007,6 +1045,16 @@ public:
getScalar
Get the introspection interface for the PVScalar.
+
getAs
+
Convert and return the scalar value in the requested type. + Result type is determined from the function template argument + which must be one of the ScalarType enums. + For example: +
+uint32 val = pv->getAs();
+
+
+

PVScalarValue

@@ -1019,9 +1067,18 @@ public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; + static const ScalarType typeCode; + virtual ~PVScalarValue() {} virtual T get() const = 0; virtual void put(T value) = 0; + std::ostream& dumpValue(std::ostream& o) const; + void operator>>=(T& value) const; + void operator<<=(T value); + template<typename T1> + T1 getAs() const; + template<typename T1> + void putFrom(T1 val); ... } @@ -1038,13 +1095,60 @@ public:
Get the value stored in the object.
put
Change the value stored in the object.
+
dumpValue
+
ostream method.
+
operator>>=
+
get operator. For example: +
+double value;
+PVDoublePtr pvDouble;
+...
+pvDouble>>=value;
+
+
+
operator<<=
+
put operator. For example: +
+double value;
+PVDoublePtr pvDouble;
+...
+pvDouble<<=value;
+
+
+
getAs
+
Convert and return the scalar value in the requested type. + Result type is determined from the function template argument + which must be one of the ScalarType enums. + For example: +
+int32 val = pv->getAs<pvInt>>();
+
+
+
putFrom
+
Convert the scalar value in the requested type + and put the value into this PVScalarValue. + The source type is determined from the function template argument + which must be one of the ScalarType enums. + For example: +
+int32 val;
+pv->putFrom<pvInt>(val);
+
+
+

TBD +

+
dumpvalue
+
replace this with ostream operator<<
+
+

PVArray

PVArray is the base interface for all the other PV Array interfaces. It extends PVField and provides the additional methods:

-
class PVArray : public PVField, public SerializableArray {
+
+class PVArray : public PVField, public SerializableArray {
 public:
     POINTER_DEFINITIONS(PVArray);
     virtual ~PVArray();
@@ -1055,6 +1159,7 @@ public:
     bool isCapacityMutable() const;
     void setCapacityMutable(bool isMutable);
     virtual void setCapacity(std::size_t capacity) = 0;
+    virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const;
  ...
 };
@@ -1080,49 +1185,61 @@ public:
Specify if the capacity can be changed.
setCapacity
Set the capaciity.
+
dumpValue
+
ostream method
+

TBD +

+
dumpvalue
+
replace this with ostream operator<<
+
+

-

PVArrayData

- -

This is the argument to one of the get methods of PVValueArray.

-
template<typename T>
-class PVArrayData {
-private:
-    std::vector<T> init;
-public:
-    POINTER_DEFINITIONS(PVArrayData);
-    typedef T  value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-    std::vector<T> & data;
-    std::size_t offset;
-    PVArrayData()
-    : data(init)
-    {}
-};

PVScalarArray

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.

-
class PVScalarArray : public PVArray {
+
+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;
+    template<typename T>
+    void getAs(shared_vector<const T>& out) const
+    template<typename T>
+    void putFrom(const shared_vector<const T>& inp)
+    void assign(PVScalarArray& pv);
  ...
-}
+} +

where

getScalarArray
Get the introspection interface.
-
dumpValue
-
Method for streams I/O.
+
getAs
+
Fetch the current value and convert to the requested type. + A copy is made if the requested type does not match the element type. + If the types do match then no copy is made. +
+
putFrom
+
Assign the given value after conversion. + A copy and element-wise conversion is performed unless the element type + of the PVScalarArray matches the type of the provided data. + If the types do match then a new refernce to the provided data is kept. +
+
assign
+
Assign the given PVScalarArray's value. + A copy and element-wise conversion is performed unless the element type + of the PVScalarArray matches the type of the provided data. + If the types do match then a new refernce to the provided data is kept. +

PVValueArray

@@ -1130,184 +1247,54 @@ public:

This is a template class plus instances for PVBooleanArray, ..., PVStringArray.

template<typename T>
-class PVValueArray : public PVScalarArray {
+class PVValueArray : public detail::PVVectorStorage<T,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;
+    typedef ::epics::pvData::shared_vector<T> svector;
+    typedef ::epics::pvData::shared_vector<const T> const_svector;
+    static const ScalarType typeCode;
 
     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;
+    // inherited from PVVectorStorage
+    const_svector view();
+    void swap(const_svector& other);
+    void replace(const const_svector& next);
+    svector reuse();
+    ...
 };
-
-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;
+

where

-
get( std::size_t offset, std::size_t length, ArrayDataType &data) -
-
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.
-
put(std::size_t offset, std::size_t length, const_pointer from, - std::size_t fromOffset)
-
Put data into the array. from is a raw array.
-
put(std::size_t offset, std::size_t length, const_vector &from, - std::size_t fromOffset)
-
Put data into the array from a vector holding the raw array.
-
shareData( shared_vector const & value, std::size_t capacity, - std::size_t length)
-
Make the instance share the raw data from value.
- 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.
- 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.
-
get()
-
Get the raw array.
-
getVector()
-
Get the vector holding the raw array.
-
getSharedVector()
-
Get the shared vector holding the data.
dumpValue
Method for streams I/O.
+
view
+
Fetch a read-only view of the current array data.
+
swap
+
+ Callers must ensure that postPut() is called after the last swap() operation. + Before you call this directly, consider using the reuse(), or replace() methods. +
+
replace
+
Discard current contents and replaced with the provided.
+
reuse
+
Remove and return the current array data or an unique copy if shared.
- -

Both get and put return the number of elements actually transfered. The -arguments are:

+

TBD

-
offset
-
The offset in the PV array.
-
len
-
The maximum number of elements to transfer. The number actually - transfered will be less than or equal to this value.
-
data
-
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.
-
from
-
The array from which the data is taken. This array is supplied by the - caller
-
fromOffset
-
The offset in from
+
dumpvalue
+
replace this with ostream operator<<
+
Check for completeness
+
Michael should check that PVScalarArray and PVValueArray + have the correct set of methods and that the descriptions are correct.
- -

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:

-
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;
-    }
-} 
- -

+

PVStructure

@@ -1318,18 +1305,12 @@ public: virtual ~PVStructure(); typedef PVStructure & reference; typedef const PVStructure & const_reference; + virtual void setImmutable(); StructureConstPtr getStructure() const; const PVFieldPtrArray & getPVFields() const; PVFieldPtr getSubField(String const &fieldName) const; PVFieldPtr getSubField(std::size_t fieldOffset) const; - void appendPVField( - String const &fieldName, - PVFieldPtr const & pvField); - void appendPVFields( - StringArray const & fieldNames, - PVFieldPtrArray const & pvFields); - void removePVField(String const &fieldName); PVBooleanPtr getBooleanField(String const &fieldName) ; PVBytePtr getByteField(String const &fieldName) ; PVShortPtr getShortField(String const &fieldName) ; @@ -1346,9 +1327,6 @@ public: PVScalarArrayPtr getScalarArrayField( String const &fieldName,ScalarType elementType) ; PVStructureArrayPtr getStructureArrayField(String const &fieldName) ; - String getExtendsStructureName() const; - bool putExtendsStructureName( - String const &extendsStructureName); virtual void serialize( ByteBuffer *pbuffer,SerializableControl *pflusher) const ; virtual void deserialize( @@ -1359,6 +1337,7 @@ public: DeserializableControl*pflusher,BitSet *pbitSet); PVStructure(StructureConstPtr const & structure); PVStructure(StructureConstPtr const & structure,PVFieldPtrArray const & pvFields); + virtual std::ostream& dumpValue(std::ostream& o) const; };

where

@@ -1379,20 +1358,6 @@ public:
Get the field located a fieldOffset, where fieldOffset is relative to the top level structure. This returns null if the specified field is not located within this PVStructure.
-
appendPVField
-
Append pvField to the end of this PVStructure. This should NOT be - called if any code is attached to any of the fields in the top level - structure.
-
appendPVFields
-
Append an array of pvFields to the end of this structure. Note that if - the original number of fields is 0 than pvFields replaces the original. - Thus the caller must NOT reuse pvFields after calling this method. This - should NOT be called if any code is attached to any of the fields in the - top level structure
-
removePVField
-
Remove the specified field from this structure. This should NOT be - called if any code is attached to any of the fields in the top level - structure.
getBooleanField
Look for fieldName. If found and it has the correct type return the interface. This and the following methods are convenience methods that @@ -1443,56 +1408,58 @@ public:
getStructureArrayField
Look for fieldName. If found and it has the correct type return the interface.
-
getExtendsStructureName
-
Get the name of structure that this structure extends.
-
putExtendsStructureName
-
Specify the structure that this structure extends.
+
dumpValue
+
Method for streams I/O.
+

TBD +

+
dumpvalue
+
replace this with ostream operator<<
+
+

PVStructureArray

The interface for an array of structures is:

-
typedef PVArrayData<PVStructurePtr> StructureArrayData;
-
-class PVStructureArray : public PVArray
+
+template<>
+class PVValueArray<PVStructurePtr> : public detail::PVVectorStorage<PVStructurePtr,PVArray>
 {
 public:
     POINTER_DEFINITIONS(PVStructureArray);
     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;
+    typedef ::epics::pvData::shared_vector<PVStructurePtr> svector;
+    typedef ::epics::pvData::shared_vector<const PVStructurePtr> const_svector;
 
     virtual ~PVStructureArray() {}
+    virtual size_t getLength();
+    virtual size_t getCapacity();
     virtual void setCapacity(size_t capacity);
     virtual void setLength(std::size_t length);
     virtual StructureArrayConstPtr getStructureArray() const ;
     virtual std::size_t append(std::size_t number);
     virtual bool remove(std::size_t offset,std::size_t number);
     virtual void compress();
-    virtual std::size_t get(std::size_t offset, std::size_t length,
-        StructureArrayData &data);
-    virtual std::size_t put(std::size_t offset,std::size_t length,
-        const_vector const & from, std::size_t fromOffset);
-    virtual void shareData(
-         shared_vector const & value,
-         std::size_t capacity,
-         std::size_t length);
     virtual void serialize(ByteBuffer *pbuffer,
+    virtual const_svector view() const;
+    virtual void swap(const_svector &other);
+    virtual void replace(const const_svector &other);
         SerializableControl *pflusher) const;
     virtual void deserialize(ByteBuffer *buffer,
         DeserializableControl *pflusher);
     virtual void serialize(ByteBuffer *pbuffer,
         SerializableControl *pflusher, std::size_t offset, std::size_t count) const ;
-    virtual pointer get() { return &((*value.get())[0]); }
-    virtual pointer get() const { return &((*value.get())[0]); }
-    virtual vector const & getVector() {return *value;}
-    virtual shared_vector const & getSharedVector() {return value;}
+    virtual std::ostream& dumpValue(std::ostream& o) const;
+    virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const;
+    // inherited from PVVectorStorage
+    const_svector view();
+    void swap(const_svector& other);
+    void replace(const const_svector& next);
+    svector reuse();
  ...
 }
@@ -1596,10 +1563,20 @@ public: ... } +extern StandardPVFieldPtr getStandardPVField(); +
-extern StandardPVFieldPtr getStandardPVField(); - -

convert.h

+

Conversion

+

There are two facilities for converting between two different PVData +objects:

+
+
Convert
+
This preforms all conversions except for coping subarrays.
+
PVSubArray
+
This copies a subarray from one PVArray to another. + The two arrays must have the same element type.
+
+

convert.h

NOTE about copying immutable array fields. If an entire immutable array field is copied to another array that has the same elementType, both offsets @@ -1632,11 +1609,10 @@ Thus the source and target share the same primitive array.

  • Conversion between compatible structures.
  • A utility method the returns the full field name of a field
  • -
    bool operator==(PVField&, PVField&);
    -
    -static inline bool operator!=(PVField& a, PVField& b)
    -{return !(a==b);}
    +
    +bool operator==(PVField&, PVField&);
     
    +static bool operator!=(PVField& a, PVField& b);
     
     bool operator==(const Field&, const Field&);
     bool operator==(const Scalar&, const Scalar&);
    @@ -1644,16 +1620,12 @@ bool operator==(const ScalarArray&, const ScalarArray&);
     bool operator==(const Structure&, const Structure&);
     bool operator==(const StructureArray&, const StructureArray&);
     
    -static inline bool operator!=(const Field& a, const Field& b)
    -{return !(a==b);}
    -static inline bool operator!=(const Scalar& a, const Scalar& b)
    -{return !(a==b);}
    -static inline bool operator!=(const ScalarArray& a, const ScalarArray& b)
    -{return !(a==b);}
    -static inline bool operator!=(const Structure& a, const Structure& b)
    -{return !(a==b);}
    -static inline bool operator!=(const StructureArray& a, const StructureArray& b)
    -{return !(a==b);}
    +static inline bool operator!=(const Field& a, const Field& b);
    +static inline bool operator!=(const Scalar& a, const Scalar& b);
    +static inline bool operator!=(const ScalarArray& a, const ScalarArray& b);
    +static inline bool operator!=(const Structure& a, const Structure& b);
    +static inline bool operator!=(const StructureArray& a, const StructureArray& b);
    +
     class Convert;
     typedef std::tr1::shared_ptr<Convert> ConvertPtr;
     
    @@ -1727,133 +1699,75 @@ public:
         void fromULong(PVScalarPtr const & pv, uint64 from);
         void fromFloat(PVScalarPtr const & pv, float from);
         void fromDouble(PVScalarPtr const & pv, double from);
    -    std::size_t toByteArray(PVScalarArrayPtr const & pv,
    -        std::size_t offset,
    -        std::size_t length,
    -        int8* to,
    -        std::size_t toOffset);
    -    std::size_t toShortArray(PVScalarArrayPtr const & pv,
    -        std::size_t offset,
    -        std::size_t length,
    -        int16* to,
    -        std::size_t toOffset);
    -    std::size_t toIntArray(PVScalarArrayPtr const & pv,
    -        std::size_t offset,
    -        std::size_t length,
    -        int32* to,
    -        std::size_t toOffset);
    -    std::size_t toLongArray(PVScalarArrayPtr const & pv,
    -        std::size_t offset,
    -        std::size_t length,
    -        int64* to,
    -        std::size_t toOffset);
    -    std::size_t toUByteArray(PVScalarArrayPtr const & pv,
    -        std::size_t offset,
    -        std::size_t length,
    -        uint8* to,
    -        std::size_t toOffset);
    -    std::size_t toUShortArray(PVScalarArrayPtr const & pv,
    -        std::size_t offset,
    -        std::size_t length,
    -        uint16* to,
    -        std::size_t toOffset);
    -    std::size_t toUIntArray(
    -        PVScalarArrayPtr const & pv,
    -        std::size_t offset,
    -        std::size_t length,
    -        uint32* to,
    -        std::size_t toOffset);
    -    std::size_t toULongArray(
    -        PVScalarArrayPtr const & pv,
    -        std::size_t offset,
    -        std::size_t length,
    -        uint64* to,
    -        std::size_t toOffset);
    -    std::size_t toFloatArray(
    -        PVScalarArrayPtr const & pv,
    -        std::size_t offset,
    -        std::size_t length,
    -        float* to,
    -        std::size_t toOffset);
    -    std::size_t toDoubleArray(
    -        PVScalarArrayPtr const & pv,
    -        std::size_t offset,
    -        std::size_t length,
    -        double* to, std::size_t
    -        toOffset);
    -    std::size_t fromByteArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const int8* from, std::size_t fromOffset);
    -    std::size_t fromByteArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const ByteArray & from, std::size_t fromOffset);
    -    std::size_t fromShortArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const int16* from, std::size_t fromOffset);
    -    std::size_t fromShortArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const ShortArray & from, std::size_t fromOffset);
    -    std::size_t fromIntArray(
    -       PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -       const int32* from, std::size_t fromOffset);
    -    std::size_t fromIntArray(
    -       PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -       const IntArray & from, std::size_t fromOffset);
    -    std::size_t fromLongArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const int64* from, std::size_t fromOffset);
    -    std::size_t fromLongArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const LongArray & from, std::size_t fromOffset);
    -    std::size_t fromUByteArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const uint8* from, std::size_t fromOffset);
    -    std::size_t fromUByteArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const UByteArray & from, std::size_t fromOffset);
    -    std::size_t fromUShortArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const uint16* from, std::size_t fromOffset);
    -    std::size_t fromUShortArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const UShortArray & from, std::size_t fromOffset);
    -    std::size_t fromUIntArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const uint32* from, std::size_t fromOffset);
    -    std::size_t fromUIntArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const UIntArray & from, std::size_t fromOffset);
    -    std::size_t fromULongArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const uint64* from, std::size_t fromOffset);
    -    std::size_t fromULongArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const ULongArray & from, std::size_t fromOffset);
    -    std::size_t fromFloatArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const float* from, std::size_t fromOffset);
    -    std::size_t fromFloatArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const FloatArray & from, std::size_t fromOffset);
    -    std::size_t fromDoubleArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const double* from, std::size_t fromOffset);
    -    std::size_t fromDoubleArray(
    -        PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
    -        const DoubleArray & from, std::size_t fromOffset);
         void newLine(StringBuilder buf, int indentLevel);
      ...
     }
     
    -extern ConvertPtr getConvert();
    - -

    The array methods all return the number of elements copied or converted. -This can be less than len if the PVField array contains less than len -elements.

    - +extern ConvertPtr getConvert(); +

    newLine is a convenience method for code that implements toString It generates a newline and inserts blanks at the beginning of the newline.

    +

    pvSubArrayCopy.h

    +
    +template<typename T>
    +void copy(
    +    PVValueArray<T> & pvFrom,
    +    size_t fromOffset,
    +    PVValueArray<T> & pvTo,
    +    size_t toOffset,
    +    size_t len);
    +
    +void copy(
    +    PVScalarArray & from,
    +    size_t fromOffset,
    +    PVScalarArray & to,
    +    size_t toOffset,
    +    size_t len);
    +
    +void copy(
    +    PVStructureArray & from,
    +    size_t fromOffset,
    +    PVStructureArray & to,
    +    size_t toOffset,
    +    size_t len);
    +
    +void copy(
    +    PVArray & from,
    +    size_t fromOffset,
    +    PVArray & to,
    +    size_t toOffset,
    +    size_t len);
    +
    +

    The last copy is the only one most client need to call. +It either throws an error of the element types do not match or calls the +other copy functions. The arguments are:

    +
    +
    from
    +
    The source array.
    +
    fromOffset
    +
    The offset into the source array.
    +
    to
    +
    The destination array. The element type must be the same + as for the source array. If the element type is structure then + the introspection interface for the element types must be the same. +
    +
    toOffset
    +
    The offset into the destination array.
    +
    len
    +
    The number of elements to copy.
    +
    +

    An exception is thrown if:

    +
    +
    type mismatch
    +
    The element types for the source and destination differ.
    +
    immutable
    +
    The destination array is immutable. +
    capacity immutable
    +
    The destination array needs to have it's capacity extentended + but the capacity is immutable.
    +
    +

    pvDataApp/property

    Definition of Property

    @@ -2669,7 +2583,6 @@ FieldCreate and implements getFieldCreate.

    PVDataCreateFactory.cpp automatically creates a single instance of PVDataCreate and implements getPVDataCreate.

    -

    PVAuxInfoImpl.cpp implements auxInfo.

    Convert.cpp automatically creates a single instance of Convert and implements getConvert.

    @@ -2694,6 +2607,8 @@ implements getConvert.

    Signal and wait for an event.
    executor.h
    Provides a thread for executing commands.
    +
    localStaticLock.h
    +
    TBD Matej can You explain what this does?
    lock.h
    Support for locking and unlocking.
    messageQueue.h
    @@ -2712,8 +2627,13 @@ implements getConvert.

    More support for serializing objects.
    sharedPtr.h
    Defines POINTER_DEFINITIONS.
    +
    sharedVector.h +
    Like std::vector except that std::shared_ptr is used for + the data array.
    status.h
    A way to pass status information to a client.
    +
    templateMeta.h
    +
    TBD Michael can You provide an explaination?
    thread.h
    Provides thread support.
    timeFunction.h
    @@ -2721,6 +2641,8 @@ implements getConvert.

    timer.h
    An implementation of Timer that does not require an object to be created for each timer request.
    +
    typeCast.h
    +
    TBD Michael can You provide an explaination?

    Note that directory testApp/misc has test code for all the classes in misc. @@ -2729,9 +2651,13 @@ The test code also can be used as examples.

    bitSet.h

    This is adapted from the java.util.BitSet. bitSet.h is:

    -
    class BitSet : public Serializable {
    +
    +class BitSet;
    +typedef std::tr1::shared_ptr<BitSet> BitSetPtr;
    +
    +class BitSet : public Serializable {
     public:
    -    static BitSet::shared_pointer create(uint32 nbits);
    +    static BitSetPtr create(uint32 nbits);
         BitSet();
         BitSet(uint32 nbits);
         virtual ~BitSet();
    @@ -2754,8 +2680,12 @@ public:
         void or_and(const BitSet& set1, const BitSet& set2);
         bool operator==(const BitSet &set) const;
         bool operator!=(const BitSet &set) const;
    -    void toString(StringBuilder buffer);
    -    void toString(StringBuilder buffer, int indentLevel) const;
    +    void toString(StringBuilder buffer, int indentLevel = 0) const;
    +    virtual void serialize(
    +        ByteBuffer *buffer,SerializableControl *flusher) const;
    +    virtual void deserialize(
    +        ByteBuffer *buffer,DeserializableControl *flusher);
    +
     private:
     };
    @@ -2816,8 +2746,6 @@ private:
    Does this bitSet have the same values as the argument.
    operator!=(const BitSet &set)
    Is this bitSet different than the argument.
    -
    toString(StringBuilder buffer)
    -
    Show the current values of the bitSet.
    toString(StringBuilder buffer, int indentLevel)
    Show the current values of the bitSet.
    virtual void serialize(ByteBuffer *buffer,SerializableControl *flusher) @@ -2827,6 +2755,14 @@ private: *flusher);
    Deserialize the bitSet.
    +

    TBD +

    +
    implemantation
    +
    This should be changed so that capacity can not change.
    +
    toString
    +
    Should this change and also implement ostream operator?
    +
    +

    byteBuffer.h

    @@ -2941,8 +2877,7 @@ public: bool wait (); /* blocks until full */ bool wait ( double timeOut ); /* false if empty at time out */ bool tryWait (); /* false if empty */ -private: - epicsEventId id; +... };

    where

    @@ -2965,7 +2900,8 @@ private:

    An Executor is a thread that can execute commands. The user can request that a single command be executed.

    -
    class Command;
    +
    +class Command;
     class Executor;
     typedef std::tr1::shared_ptr<Command> CommandPtr;
     typedef std::tr1::shared_ptr<Executor> ExecutorPtr;
    @@ -3006,8 +2942,21 @@ execute.

    nothing is done. +

    localStaticLock.h

    +
    +extern epics::pvData::Mutex& getLocalStaticInitMutex();
    +
    +static class MutexInitializer {
    +  public:
    +    MutexInitializer ();
    +    ~MutexInitializer ();
    +} localStaticMutexInitializer; // Note object here in the header.
    +
    +

    TBD Matej will explain.

    +

    lock.h

    -
    typedef epicsMutex Mutex;
    +
    +typedef epicsMutex Mutex;
     
     class Lock : private NoDefaultMethods {
     public:
    @@ -3034,7 +2983,8 @@ public
         {
             Lock xx(mutex);
             ...
    -    }
    + } +

    The method will take the lock when xx is created and release the lock when the current code block completes.

    @@ -3043,10 +2993,50 @@ the current code block completes.

    once. This can be implemented as follows:

        static void init(void) {
             static Mutex mutex;
    -        Lock xx(mutex);
    +        Lock guard(mutex);
             if(alreadyInitialized) return;
             // initialization
         }
    +

    +

    Lock has a private variable: +

    +bool locked;
    +
    +and improves efficency by checking the local variable before calling the +mutex methods. This is not thread safe if any methods are called by a thread other than +the thread that created the Lock. +

    +

    It is thread safe if used as follows:

    +
    +{
    +    Lock guard(mutex);
    +    ...
    +    /* the following can optionally be called
    +    guard.unlock();
    +    guard.lock();
    +    */
    +}
    +
    +

    It is not thread safe if used as follows:

    +
    +class SomeClass
    +{
    +private:
    +    Mutex mutex;
    +    Lock lock;
    +public:
    +    SomeClass: lock(mutex) {}
    +    ...
    +    void someMethod() {
    +        lock.unlock();
    +        ...
    +    }
    +    ...
    +};
    +
    +

    It is only safe if all methods of Lock, including ~Lock(), +are called by the same thread. +

    messageQueue.h

    @@ -3141,10 +3131,11 @@ assignment contructor.

    queue.h

    -

    This provides a queue which has an immutable capacity. When the queue is +

    This provides a bounded queue. When the queue is full the user code is expected to keep using the current element until a new free element becomes avalable.

    -
    template <typename T>
    +
    +template <typename T>
     class Queue
     {   
     public:
    @@ -3224,9 +3215,16 @@ public:
     
     

    requester.h

    -

    A PVField extends Requester. Requester is present so that when database -errors are found there is someplace to send a message.

    -
    enum MessageType {
    +

    Requester is present so that when +errors are found there is someplace to send a message. +At one time PVField extended Requester but it no longer does. +Requester is, however, used by pvAccess. +

    +
    +class Requester;
    +typedef std::tr1::shared_ptr<Requester> RequesterPtr;
    +
    +enum MessageType {
        infoMessage,warningMessage,errorMessage,fatalErrorMessage
     };
     
    @@ -3255,7 +3253,8 @@ public:
     
     
     

    serialize.h

    -
        class SerializableControl;
    +
    +    class SerializableControl;
         class DeserializableControl;
         class Serializable;
         class BitSetSerializable;
    @@ -3279,7 +3278,8 @@ public:
             virtual ~DeserializableControl(){}
             virtual void ensureData(std::size_t size) =0;
             virtual void alignData(std::size_t alignment) =0;
    -        virtual std::tr1::shared_ptr<const Field> cachedDeserialize(ByteBuffer* buffer) = 0;
    +        virtual std::tr1::shared_ptr<const Field> cachedDeserialize(
    +            ByteBuffer* buffer) = 0;
         };
     
         class Serializable {
    @@ -3305,7 +3305,8 @@ public:
         public:
             virtual ~SerializableArray(){}
             virtual void serialize(ByteBuffer *buffer,
    -            SerializableControl *flusher, std::size_t offset, std::size_t count) const = 0;
    +            SerializableControl *flusher, std::size_t offset,
    +            std::size_t count) const = 0;
         };

    serializeHelper.h

    @@ -3343,12 +3344,207 @@ public:

    sharedPtr.h

    -
    #define POINTER_DEFINITIONS(clazz) \
    +
    +#define POINTER_DEFINITIONS(clazz) \
         typedef std::tr1::shared_ptr<clazz> shared_pointer; \
         typedef std::tr1::shared_ptr<const clazz> const_shared_pointer; \
         typedef std::tr1::weak_ptr<clazz> weak_pointer; \
         typedef std::tr1::weak_ptr<const clazz> const_weak_pointer;
    +

    sharedVector.h

    +

    +shared_vector is a holder for a contigious piece of memory. +Data is shared, but offset and length are not. +This allows one vector to have access to only a subset of a piece of memory. +

    +

    +shared_vector differs from std::vector as follows:

    +
    +
    Differences in behavior
    +
    + shared_vector models const-ness like shared_ptr. + An equivalent of 'const std::vector<E>' is + 'const shared_vector<const E>'. + However, it is also possible to have 'const shared_vector<E>' + analogous to 'E* const' and 'shared_vector<const E>>' + which is analogous to 'const E*'.i +
    + Copying a shared_vector, by construction or assignment, does not copy + its contents. + Modifications to one such "copy" effect all + associated shared_vector instances. +
    + std::vector::reserve(N) has no effect if N<=std::vector::capacity(). + However, like resize(), shared_vector<E>::reserve() has the side effect + of always calling make_unique(). +
    +
    Parts of std::vector interface not implemented
    +
    + Mutating methods insert(), erase(), shrink_to_fit(), emplace(), and emplace_back() are not implemented. +
    + shared_vector does not model an allocator which is bound to the object. Therefore the get_allocator() method and the allocator_type typedef are not provided. +
    + The assign() method and the related constructor are not implemented at this time. +
    + The comparison operators are not implemented at this time. +
    +
    Parts not found in std::vector
    +
    + shared_vector has additional constructors from raw pointers and shared_ptr s. + The copy constructor and assignment operator allow implicit castings + from type 'shared_vector<T>' to 'shared_vector<const T>>'. + To faciliate safe modification the methods unique() and make_unique() are provided + The slice() method selects a sub-set of the shared_vector. + The low level accessors dataPtr(), dataOffset(), dataCount(), and dataTotal(). +
    +
    + + +
    +template<typename E, class Enable = void& class shared_vector;
    +
    +template<typename E, class Enable&
    +class shared_vector : public detail::shared_vector_base<E&
    +{
    +    typedef detail::shared_vector_base<E& base_t;
    +    typedef typename detail::call_with<E&::type param_type;
    +    typedef typename meta::strip_const<E&::type _E_non_const;
    +public:
    +    typedef E value_type;
    +    typedef E& reference;
    +    typedef typename meta::decorate_const<E&::type& const_reference;
    +    typedef E* pointer;
    +    typedef typename meta::decorate_const<E&::type* const_pointer;
    +    typedef E* iterator;
    +    typedef std::reverse_iterator<iterator& reverse_iterator;
    +    typedef typename meta::decorate_const<E&::type* const_iterator;
    +    typedef std::reverse_iterator<const_iterator& const_reverse_iterator;
    +    typedef ptrdiff_t difference_type;
    +    typedef size_t size_type;
    +
    +    typedef E element_type;
    +    typedef std::tr1::shared_ptr<E& shared_pointer_type;
    +
    +    // allow specialization for all E to be friends
    +    template<typename E1, class Enable1& friend class shared_vector;
    +
    +    shared_vector() :base_t();
    +    explicit shared_vector(size_t c)
    +        :base_t(new _E_non_const[c], 0, c);
    +    shared_vector(size_t c, param_type e);
    +    template<typename A&
    +    shared_vector(A v, size_t o, size_t c) :base_t(v,o,c);
    +    template<typename E1&
    +    shared_vector(const std::tr1::shared_ptr<E1&& d, size_t o, size_t c);
    +    template<typename A, typename B&
    +    shared_vector(A d, B b, size_t o, size_t c);
    +    shared_vector(const shared_vector& o) :base_t(o);
    +    
    +    size_t max_size() const;
    +    size_t capacity() const;
    +    void reserve(size_t i);
    +    void resize(size_t i);
    +    void resize(size_t i, param_type v);
    +    void make_unique();
    +    
    +    iterator begin() const;
    +    iterator end() const;
    +    reverse_iterator rbegin() const;
    +    reverse_iterator rend() const;
    +    reference front() const;
    +    reference back() const;
    +
    +    void push_back(param_type v);
    +    void pop_back();
    +    pointer data() const;
    +    reference operator[](size_t i) const;
    +    reference at(size_t i) const;
    +    // inherited from detail
    +    shared_vector_base& operator=(const shared_vector_base& o);
    +    void swap(shared_vector_base& o);
    +    void clear();
    +    bool unique() const;
    +    size_t size() const;
    +    bool empty() const;
    +    void slice(size_t offset, size_t length=(size_t)-1);
    +    const std::tr1::shared_ptr<E&& dataPtr();
    +    size_t dataOffset() const;
    +    size_t dataCount() const;
    +    size_t dataTotal() const;
    +
    +where +
    +
    shared_vector
    +
    Several flavors of constructor are provided. The most commingly used is: +
    +shared_vector(size_t c);
    +       
    + This creates a shared_vector of the specified size/ +
    +
    max_size
    +
    The maximum size the C++ implementation allows, i.e., + the maximum possible capacity. + Note that units are number of elements not number of bytes. +
    +
    capacity
    +
    The current capacity.
    +
    reserve
    +
    Set array capacity.
    +
    resize
    +
    Grow or shrink array. + It the second argument is given it is the value to assign to + and new elements. +
    +
    make_unique
    +
    Ensure (by copying) that this shared_vector + is the sole owner of the data array. +
    +
    begin,...,rend
    +
    Standard interators.
    +
    front
    +
    Return a reference to the first element.
    +
    back
    +
    Return a reference to the last element.
    +
    push_back
    +
    Add an element to the end of the array.
    +
    pop_back
    +
    Remove an element from the end of the array.
    +
    data
    +
    Return a pointer to the raw array.
    +
    operator[](size_t i)
    +
    Return a reference to the specified element.
    +
    at
    +
    Like the previous except that it throws a range-error if + the specified element is out of range.
    +
    operator=
    +
    Copy an existing shared_vector.
    +
    swap
    +
    Swap the contents of this vector with another.
    +
    clear
    +
    Clear contents.
    +
    unique
    +
    returns (true,false) if data (is not, is) shared.
    +
    size
    +
    Number of elements visible through this vector.
    +
    empty
    +
    Is the number of elements zero?
    +
    slice
    +
    Reduce the view of this shared_vector.
    +
    dataPtr
    +
    A readonly shared_ptr to the array.
    +
    dataOffset
    +
    Offset in the data array of first visible element.
    +
    dataCount
    +
    Number of visible elements between dataOffset and end of data.
    +
    dataTotal
    +
    The total number of elements between dataOffset and the end of data
    +
    +

    TBD +Michael should decide if this is the correct set of methods to describe. +Also he should check for correct descriptions. +

    + +

    status.h

    Status provides a way to pass status back to client code:

    @@ -3404,6 +3600,8 @@ public:
    Use this method instead of Status.deserialize(), since this allows OK status optimization.
    +

    templateMeta.h

    +

    TBD Michael will explain.

    thread.h

    @@ -3419,7 +3617,12 @@ public: };

    Thread

    -
    class Runnable {
    +
    +class Thread;
    +typedef std::tr1::shared_ptr<Thread> ThreadPtr;
    +typedef std::tr1::shared_ptr<epicsThread> EpicsThreadPtr;
    +
    +class Runnable {
     public:
         virtual void run() = 0;
     };
    @@ -3590,6 +3793,8 @@ be used to schedule multiple callbacks. It has the methods:

    schedulePeriodic
    Schedule a periodic callback.
    +

    typeCast.h

    +

    TBD Michael will explain.

    pvDataApp/pvMisc

    diff --git a/pvDataApp/misc/executor.cpp b/pvDataApp/misc/executor.cpp index 7e6a6e3..da55915 100644 --- a/pvDataApp/misc/executor.cpp +++ b/pvDataApp/misc/executor.cpp @@ -57,6 +57,7 @@ void Executor::run() xx.lock(); } CommandPtr command = head; + head = command->next; if(command.get()==NULL) continue; if(command.get()==shutdown.get()) break; xx.unlock(); @@ -83,7 +84,8 @@ void Executor::execute(CommandPtr const & command) moreWork.signal(); return; } - if(tail.get()==NULL) return; + CommandPtr tail = head; + while(tail->next!=NULL) tail = tail->next; tail->next = command; } diff --git a/pvDataApp/misc/thread.h b/pvDataApp/misc/thread.h index 344c8d8..2bfaf28 100644 --- a/pvDataApp/misc/thread.h +++ b/pvDataApp/misc/thread.h @@ -27,6 +27,10 @@ enum ThreadPriority { highestPriority =epicsThreadPriorityHigh }; +class Thread; +typedef std::tr1::shared_ptr ThreadPtr; +typedef std::tr1::shared_ptr EpicsThreadPtr; + typedef epicsThreadRunable Runnable; class Thread : public epicsThread, private NoDefaultMethods { @@ -62,5 +66,6 @@ public: } }; + }} #endif /* THREAD_H */ diff --git a/testApp/misc/testMessageQueue.cpp b/testApp/misc/testMessageQueue.cpp index dac867b..c0315ac 100644 --- a/testApp/misc/testMessageQueue.cpp +++ b/testApp/misc/testMessageQueue.cpp @@ -24,13 +24,11 @@ #include #include #include -#include -#include using namespace epics::pvData; -static void testBasic(FILE * fd,FILE */*auxfd*/) { +static void testBasic(FILE * fd,FILE *auxfd) { int queueSize = 3; StringArray messages; messages.reserve(5); diff --git a/testApp/misc/testQueue.cpp b/testApp/misc/testQueue.cpp index 2f01ee1..05edd19 100644 --- a/testApp/misc/testQueue.cpp +++ b/testApp/misc/testQueue.cpp @@ -18,13 +18,12 @@ #include #include +#include #include #include #include #include -#include -#include using namespace epics::pvData; @@ -43,7 +42,7 @@ typedef Queue DataQueue; class Sink; typedef std::tr1::shared_ptr SinkPtr; -class Sink : public Runnable { +class Sink : public epicsThreadRunable { public: static SinkPtr create(DataQueue &queue,FILE *auxfd); Sink(DataQueue &queue,FILE *auxfd); @@ -59,7 +58,7 @@ private: Event *stopped; Event *waitReturn; Event *waitEmpty; - Thread *thread; + epicsThread *thread; }; SinkPtr Sink::create(DataQueue &queue,FILE *auxfd) @@ -75,8 +74,9 @@ Sink::Sink(DataQueue &queue,FILE *auxfd) stopped(new Event()), waitReturn(new Event()), waitEmpty(new Event()), - thread(new Thread(String("sink"),middlePriority,this)) + thread(new epicsThread(*this,"sink",epicsThreadGetStackSize(epicsThreadStackSmall))) { + thread->start(); } Sink::~Sink() { diff --git a/testApp/misc/testThread.cpp b/testApp/misc/testThread.cpp index 5ca2d21..0ffcdf0 100644 --- a/testApp/misc/testThread.cpp +++ b/testApp/misc/testThread.cpp @@ -27,8 +27,14 @@ using namespace epics::pvData; +static String actionName("action"); + +class Action; +typedef std::tr1::shared_ptr ActionPtr; + class Action : public Runnable { public: + virtual ~Action() {} FILE *out; bool actuallyRan; Event begin, end; @@ -42,30 +48,45 @@ public: } }; +typedef std::tr1::shared_ptr ThreadPtr; static void testThreadRun(FILE *fd) { // show that we can control thread start and stop - Action ax(fd); + ActionPtr ax(new Action(fd)); { - Thread tr("Action", lowPriority, &ax); - bool w=ax.begin.wait(); + ThreadPtr tr(new Thread(actionName,lowPriority,ax.get())); + bool w=ax->begin.wait(); fprintf(fd, "main %s\n", w?"true":"false"); - fprintf(fd, "Action is %s\n", ax.actuallyRan?"true":"false"); - ax.end.signal(); + fprintf(fd, "Action is %s\n", ax->actuallyRan?"true":"false"); + ax->end.signal(); } - fprintf(fd, "Action is %s\n", ax.actuallyRan?"true":"false"); + fprintf(fd, "Action is %s\n", ax->actuallyRan?"true":"false"); fprintf(fd,"testThreadRun PASSED\n"); } +class Basic; +typedef std::tr1::shared_ptr BasicPtr; + class Basic : public Command, public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(Basic); - Basic(ExecutorPtr const &executor); - ~Basic(); - void run(); - virtual void command(); + Basic(ExecutorPtr const &executor) + : executor(executor) {} + ~Basic() + { + } + void run() + { + executor->execute(getPtrSelf()); + bool result = wait.wait(); + if(result==false) printf("basic::run wait returned false\n"); + } + virtual void command() + { + wait.signal(); + } private: Basic::shared_pointer getPtrSelf() { @@ -77,29 +98,8 @@ private: typedef std::tr1::shared_ptr BasicPtr; -Basic::Basic(ExecutorPtr const &executor) -: executor(executor) -{ -} - -Basic::~Basic() { -} - -void Basic::run() -{ - executor->execute(getPtrSelf()); - bool result = wait.wait(); - if(result==false) printf("basic::run wait returned false\n"); -} - -void Basic::command() -{ - wait.signal(); -} - - static void testBasic(FILE *fd) { - ExecutorPtr executor( new Executor(String("basic"),middlePriority)); + ExecutorPtr executor(new Executor(String("basic"),middlePriority)); BasicPtr basic( new Basic(executor)); basic->run(); fprintf(fd,"testBasic PASSED\n"); @@ -125,6 +125,8 @@ void MyFunc::function() typedef std::tr1::shared_ptr MyFuncPtr; +#ifdef TESTTHREADCONTEXT + static void testThreadContext(FILE *fd,FILE *auxFd) { ExecutorPtr executor(new Executor(String("basic"),middlePriority)); BasicPtr basic(new Basic(executor)); @@ -135,6 +137,7 @@ static void testThreadContext(FILE *fd,FILE *auxFd) { fprintf(auxFd,"time per call %f microseconds\n",perCall); fprintf(fd,"testThreadContext PASSED\n"); } +#endif int main(int argc, char *argv[]) { char *fileName = 0; @@ -151,7 +154,8 @@ int main(int argc, char *argv[]) { } testThreadRun(fd); testBasic(fd); +#ifdef TESTTHREADCONTEXT testThreadContext(fd,auxFd); - epicsExitCallAtExits(); +#endif return 0; } diff --git a/testApp/pv/testIntrospect.cpp b/testApp/pv/testIntrospect.cpp index f9531f1..ffd9475 100644 --- a/testApp/pv/testIntrospect.cpp +++ b/testApp/pv/testIntrospect.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include #include