From db10bed951f2d45bb376574a19883797116fbce7 Mon Sep 17 00:00:00 2001
From: Marty Kraimer This product is made available subject to acceptance of the 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: 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. EPICS pvDataCPP
-EPICS v4 Working Group, Working Draft, 16-May-2013
+EPICS v4 Working Group, Working Draft, 28-Oct-2013
Abstract
-
relatedDocumentsV4.html
Status of this Document
-
The following is a list of unresolved issues for pvDataCPP:
+The major changes since the 4.3.0 release are:
-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.
The implementation of PVValueArray and PVStructureArray now inforce Copy On Write (COW) + and use shared_vector for the raw array.
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:
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:
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
TBD +
+typedef uint8_t boolean; ++
Type is one of the following:
@@ -452,7 +440,21 @@ public: return the scalarType.TBD +
+String toString(ScalarType scalarType); ++
TBD +
TBD +
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 +
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:
TBD -
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
+virtual String toString() const; +virtual std::ostream& operator<<(std::ostream& o) const = 0; ++
+uint32 val = pv->getAs+(); +
+double value; +PVDoublePtr pvDouble; +... +pvDouble>>=value; ++
+double value; +PVDoublePtr pvDouble; +... +pvDouble<<=value; ++
+int32 val = pv->getAs<pvInt>>(); ++
+int32 val; +pv->putFrom<pvInt>(val); ++
TBD +
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;
...
};
TBD +
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 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
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
Both get and put return the number of elements actually transfered. The -arguments are:
+TBD
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;
- }
-}
-
-
+
where
@@ -1379,20 +1358,6 @@ public:TBD +
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();
-
-There are two facilities for converting between two different PVData +objects:
+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.
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.
++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:
+An exception is thrown if:
+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.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.
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:
TBD +
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:
+
+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(size_t c); ++ This creates a shared_vector of the specified size/ +
TBD +Michael should decide if this is the correct set of methods to describe. +Also he should check for correct descriptions. +
+ +Status provides a way to pass status back to client code:
@@ -3404,6 +3600,8 @@ public:TBD Michael will explain.
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:
TBD Michael will explain.