From 5f52f140944eed84c19adbc78dea847642410854 Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Tue, 25 Jun 2013 12:18:38 -0400 Subject: [PATCH] comparison between implementations --- documentation/pvArray.html | 793 ++++++++++++++++++++++++++++++++++++- 1 file changed, 771 insertions(+), 22 deletions(-) diff --git a/documentation/pvArray.html b/documentation/pvArray.html index 4b21ed5..8621bb7 100644 --- a/documentation/pvArray.html +++ b/documentation/pvArray.html @@ -37,7 +37,7 @@

EPICS Array

-

EPICS v4 Working Group, Working Draft, 18-Jun-2013

+

EPICS v4 Working Group, Working Draft, 23-Jun-2013

Latest version:
@@ -68,7 +68,18 @@ license.

Introduction

This is the documentation for pvData.h as defined by pvDataCPP-md. -When complete it will be merged into pvDataCPP.html.

+When complete it will be merged into pvDataCPP.html. +This document proposes an implementation of the PVXXX interfaces that are +different than the existing pvDataCPP-md interfaces. +See the next section for a comparison of the four interface descriptions. +The main reason for proposing a different definition is the primary +purpose for pvData:
+pvData (Process Variable Data) defines and implements an efficent +way to store, access, and communicate memory resident data structures.
+This statement appears as the first sentence of pvDataJava.html. +A few sentances later the document makes clear that communication +includes network communication. +Thus it is important to keep the Java and C++ descriptions similar.

pvData provides an interface for network accessible structured data. The interfaces for C++ and Java are similar. @@ -82,7 +93,7 @@ Some differences are:

shared pointers
Java has a garbage collector. In C++ the implementation manages - memory. The primary tool is std::tr1::shared_ptr.
+ memory. An important tool is std::tr1::shared_ptr.
PVArray
The Java garbage collector allows raw data arrays, e. g. int[], to be shared. For C++ a shared_vector holds the raw data. @@ -92,8 +103,11 @@ Some differences are: For C++ operator<< replaces toString
shared_vector
This is similar to std::vector but uses a shared_ptr to wrap the raw - data and also supports a window into the raw data. It does follow - naming and other conventions for C++ standard library containers.
+ data and also supports a window into the raw data. It does follow the + naming and other conventions for C++ standard library containers. + Code that wants to use features of the C++ standard library + like iterators and algorithms can get the shared_vector. +

There is one big difference from the existing Java implelentation: The method PVValueArray::get. @@ -120,13 +134,736 @@ PVScalarArrayPtr createPVScalarArray(const PVScalarArray &, size_t offset, s

convert
This will be changed to do conversions itself instead of calling - methods like getAs. It will again support methods toXXXArray and fromXXXArray, - with a raw array replaced by a shared_vector. - Templates should be able to minimize the code required.
+ methods like getAs. It will again support methods toXXXArray and fromXXXArray. + Templates should be used to minimize the code required.
PVStructureArray
Can this also use shared_vector to hold elements?

+

PVXXX: pvDataJava, pvDataCPP, pvDataCPP-md, and proposed interface

+

The following compares the definitions of the following: PVField, +PVScalar and extensions, PVArray and extensions. +Note, however, that PVStructureArray is not discussed. +

+

PVField

+

This is the base for all the PVXXX iterfaces. +It provides basic methods for allowing network transfer and for +traversing structured data. +The pvDataJava and pvDataCPP definitions are similar. +pvDataCPP-md added method getFullName. +The proposed interface is like the existing pvDataCPP except that +the toString and dumpValue methods are replaced by the stream operator<<. +

+

Java

+
interface PVField extends Requester, Serializable {
+    String getFieldName();
+    void setRequester(Requester requester);
+    int getFieldOffset();
+    int getNextFieldOffset();
+    int getNumberFields();
+    PVAuxInfo getPVAuxInfo();
+    boolean isImmutable();
+    void setImmutable();
+    Field getField();
+    PVStructure getParent();
+    void renameField(String newName);
+    void postPut(); // calls PVRecordField.postPut if this is a field of a record
+    void setPostHandler(PostHandler postHandler);
+    void toString(StringBuilder buf);
+    void toString(StringBuilder buf,int indentLevel);
+    String toString();
+}
+

pvDataCPP

+
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 setPostHandler(PostHandlerPtr const &postHandler);
+   virtual bool equals(PVField &pv);
+   virtual void toString(StringBuilder buf) ;
+   virtual void toString(StringBuilder buf,int indentLevel);
+   std::ostream& dumpValue(std::ostream& o) const;
+ ...
+}
+
+std::ostream& operator<<(std::ostream& o, const PVFieldPtr & f);
+
+

pvDataCPP-md

+
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 setPostHandler(PostHandlerPtr const &postHandler);
+   virtual bool equals(PVField &pv);
+   virtual void toString(StringBuilder buf) ;
+   virtual void toString(StringBuilder buf,int indentLevel);
+   std::ostream& dumpValue(std::ostream& o) const;
+   // not in pvDataCPP
+   String getFullName() const;
+ ...
+}
+
+std::ostream& operator<<(std::ostream& o, const PVFieldPtr & f);
+
+

proposed

+
+class PVField
+: virtual public Serializable,
+  public std::tr1::enable_shared_from_this
+{
+public:
+    POINTER_DEFINITIONS(PVField);
+    virtual ~PVField();
+    virtual void message(String message,MessageType messageType);
+    const String& getFieldName() const;
+    String getFullName() const;
+    virtual void setRequester(RequesterPtr const &prequester);
+    std::size_t getFieldOffset() const;
+    std::size_t getNextFieldOffset() const;
+    std::size_t getNumberFields() const;
+    PVAuxInfoPtr & getPVAuxInfo();
+    bool isImmutable() const;
+    void setImmutable();
+    const FieldConstPtr & getField() const;
+    PVStructure * getParent() const;
+    void replacePVField(const PVFieldPtr&  newPVField);
+    void renameField(String const & newName);
+    void postPut();
+    void setPostHandler(PostHandlerPtr const &postHandler);
+    virtual bool equals(PVField &pv);
+    virtual std::ostream& operator<<(std::ostream& o) const = 0;
+    virtual std::ostream& operator<<(std::ostream& o, size_t index) const = 0;
+...
+};
+
+std::ostream& operator<<(std::ostream& o, const PVFieldPtr & f);
+std::ostream& operator<<(std::ostream& o, const PVFieldPtr & f, size_t index);
+
+

PVScalar

+

The Java and pvDataCPP versions differ in that Java has an interface definition +for each scalar type, i. e. PVBoolean, ..., PVString, +and the CPP versions provide a template PVValue for the implementation.

+

+pvDataCPP-md differs from pvDataCPP in that it implements three additional +methods: +

+
getAs
+
This is used to implement the Convert::toXXX methods. + This belongs in the Convert implementation not in PVScalar.
+
putFrom
+
This is used to implement the Convert::fromXXX scalar methods. + This belongs in the Convert implementation not in PVScalar.
+
assign
+
This does the same thing as the Convert::fromXXX methods except + that it does not go through Convert. + This belongs in the Convert implementation not in PVScalar.
+
+

+

The proposed version is like the pvDataCPP version except for dumpValue +and the stream interators.

+

pvDataJava

+
+interface PVScalar extends PVField {
+    Scalar getScalar();
+}
+
+interface PVBoolean extends PVScalar {
+    boolean get();
+    void put(boolean value);
+}
+
+interface PVByte extends PVScalar {
+    byte get();
+    void put(byte value);
+}
+...
+interface PVDouble extends PVScalar {
+    double get();
+    void put(double value);
+}
+interface PVString extends PVScalar, SerializableArray {
+    String get();
+    void put(String value);
+}
+
+

pvDataCPP

+
class PVScalar : public PVField {
+public:
+    POINTER_DEFINITIONS(PVScalar);
+    virtual ~PVScalar();
+    typedef PVScalar &reference;
+    typedef const PVScalar& const_reference;
+    const ScalarConstPtr getScalar() const ;
+ ...
+}
+
+template<typename T>
+class PVScalarValue : public PVScalar {
+public:
+    POINTER_DEFINITIONS(PVScalarValue);
+    typedef T value_type;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+    virtual ~PVScalarValue() {}
+    virtual T get() const = 0;
+    virtual void put(T value) = 0;
+    std::ostream& dumpValue(std::ostream& o) const
+    void operator>>=(T& value) const;
+    void operator<<=(T value);
+ ...
+}
+
+typedef PVScalarValue PVBoolean;
+typedef PVScalarValue PVByte;
+...typedef PVScalarValue PVDouble;
+typedef std::tr1::shared_ptr PVBooleanPtr;
+typedef std::tr1::shared_ptr PVBytePtr;
+...
+typedef std::tr1::shared_ptr PVDoublePtr;
+
+
+// PVString is special case, since it implements SerializableArray
+class PVString : public PVScalarValue<String>, SerializableArray {
+public:
+    virtual ~PVString() {}
+ ...
+};
+ +

pvDataCPP-md

+
class PVScalar : public PVField {
+public:
+    POINTER_DEFINITIONS(PVScalar);
+    virtual ~PVScalar();
+    typedef PVScalar &reference;
+    typedef const PVScalar& const_reference;
+    const ScalarConstPtr getScalar() const ;
+
+    // not in pvDataCPP
+    template<ScalarType ID>
+    inline typename ScalarTypeTraits<ID>::type getAs() const;
+
+    virtual void getAs(void *, ScalarType) const = 0;
+    template<ScalarType ID>
+    inline void putFrom(typename ScalarTypeTraits<ID>::type val)
+
+    virtual void putFrom(const void *, ScalarType) = 0;
+    virtual void assign(const PVScalar&) = 0;
+
+ ...
+}
+
+template<typename T>
+class PVScalarValue : public PVScalar {
+public:
+    POINTER_DEFINITIONS(PVScalarValue);
+    typedef T value_type;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+    virtual ~PVScalarValue() {}
+    virtual T get() const = 0;
+    virtual void put(T value) = 0;
+    std::ostream& dumpValue(std::ostream& o) const
+    void operator>>=(T& value) const;
+    void operator<<=(T value);
+
+    // not in pvDataCPP
+    static const ScalarType typeCode;
+ ...
+}
+
+typedef PVScalarValue PVBoolean;
+typedef PVScalarValue PVByte;
+...typedef PVScalarValue PVDouble;
+typedef std::tr1::shared_ptr PVBooleanPtr;
+typedef std::tr1::shared_ptr PVBytePtr;
+...
+typedef std::tr1::shared_ptr PVDoublePtr;
+
+
+// PVString is special case, since it implements SerializableArray
+class PVString : public PVScalarValue<String>, SerializableArray {
+public:
+    virtual ~PVString() {}
+ ...
+};
+

proposed

+
+class PVScalar : public PVField {
+public:
+    POINTER_DEFINITIONS(PVScalar);
+    virtual ~PVScalar();
+
+    typedef PVScalar &reference;
+    typedef const PVScalar& const_reference;
+
+    const ScalarConstPtr getScalar() const;
+...
+};
+
+template<typename T>
+class PVScalarValue : public PVScalar {
+public:
+    POINTER_DEFINITIONS(PVScalarValue);
+    typedef T value_type;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+
+    virtual ~PVScalarValue() {}
+    virtual T get() const = 0;
+    virtual void put(T value) = 0;
+
+    void operator>>=(T& value) const;
+    void operator<<=(T value);
+    virtual std::ostream& operator<<(std::ostream& o) const
+    virtual std::ostream& operator>>(std::ostream& o, size_t index) const;
+...
+};
+typedef PVScalarValue<uint8> PVBoolean;
+typedef PVScalarValue<int8> PVByte;
+typedef PVScalarValue<double> PVDouble;
+...
+typedef std::tr1::shared_ptr<PVBoolean> PVBooleanPtr;
+typedef std::tr1::shared_ptr<PVByte> PVBytePtr;
+...
+typedef std::tr1::shared_ptr<PVDouble> PVDoublePtr;
+
+// PVString is special case, since it implements SerializableArray
+class PVString : public PVScalarValue<String>, SerializableArray {
+public:
+    virtual ~PVString() {}
+ ...
+};
+
+

PVArray

+

The Java and pvDataCPP versions differ in that Java has an interface definition +for each scalarArray type, i. e. PVBooleanArray, ..., PVStringArray, +and the CPP versions provide a template PVValueArray for the implementation.

+

+pvDataCPP-md differs from pvDataCPP in that it implements additional +methods: +

+
getAs
+
This is used to implement the Convert::toXXXArray methods. + This belongs in the Convert implementation not in PVArray.
+
putFrom
+
This is used to implement the Convert::fromXXXArray scalar methods. + This belongs in the Convert implementation not in PVArray.
+
assign
+
This does the same thing as the Convert::fromXXXArray methods except + that it does not go through Convert. + This belongs in the Convert implementation not in PVArray.
+
copyOut
+
This is used to copy data to a raw array.
+
copyIn
+
This is used to copy data in from a raw array. +
+

+

The proposed version is differs from pvJava, pvDataCPP, and pvCPP-md. +It is like the Java version if the Java get method is simplified as discussed above. +For example PVDoubleArray::get becomes: +

+    double[] get();
+
+The corresponding C++ version becomes: +
+    const svector & get();
+
+

+

The remaining difference is that dumpValue is replaced by the stream operator<<.

+

The main difference from the pvDataJava version is that PVValueArray "wraps" shared_vector. +Thus shared_vector takes the place of the raw arrays in Java. +This allows the C++ interface to be more similar to Java.

+

The main difference from the pvDataCPP-md version is that it does not implement +the extra methods and allows +the client access to the shared_vector. +The client is then able to perform C++ specific things to the data. +BUT it also means that if the client modifies the shared_vector the client is also responsibel +for ensuring that the immutable and capacity related features of PVField and PVArray are +respected and the postPut is properly handled. +The new method for PVValueArray: + + void put(const svector &from); + +helps ensure that shared_vector from the client is kept in sync with the shared_vector wrapped +by PVValueArray. But the used is still responsible for making sure that +PVField::isImmutable is honored. +

+

pvDataJava

+
interface PVArray extends PVField, SerializableArray {
+    int getLength();
+    void setLength(int length);
+    int getCapacity();
+    void setCapacity(int length);
+    boolean isCapacityMutable();
+    void setCapacityMutable(boolean isMutable);
+}
+
+interface PVScalarArray extends PVArray {
+    ScalarArray getScalarArray();
+}
+

For each scalar type an associated array data interface is defined. Each has +a get and put method. For example:

+
public class DoubleArrayData {
+    public double[] data;
+    public int offset;
+}
+
+interface PVDoubleArray extends PVArray {
+    int get(int offset, int len, DoubleArrayData data);
+    int put(int offset,int len, double[] from, int fromOffset);
+    void shareData(double[] from);
+}
+

pvDataCPP

+
class PVArray : public PVField, public SerializableArray {
+public:
+    POINTER_DEFINITIONS(PVArray);
+    virtual ~PVArray();
+    virtual void setImmutable();
+    std::size_t getLength() const;
+    virtual void setLength(std::size_t length);
+    std::size_t getCapacity() const;
+    bool isCapacityMutable() const;
+    void setCapacityMutable(bool isMutable);
+    virtual void setCapacity(std::size_t capacity) = 0;
+    virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const = 0;
+
+ ...
+};
+
+std::ostream& operator<<(format::array_at_internal const& manip, const PVArray& array);
+
+
+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)
+    {}
+};
+
+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>
+class PVValueArray : public detail::PVVectorStorage<T,PVScalarArray> {
+    typedef detail::PVVectorStorage<T,PVScalarArray> base_t;
+public:
+    POINTER_DEFINITIONS(PVValueArray);
+    typedef T  value_type;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+
+    typedef PVArrayData<T> ArrayDataType;
+    typedef std::vector<T> vector;
+    typedef const std::vector<T> const_vector;
+    typedef std::tr1::shared_ptr<vector> shared_vector;
+    typedef PVValueArray & reference;
+    typedef const PVValueArray & const_reference;
+
+    virtual ~PVValueArray() {}
+    virtual std::size_t get(
+         std::size_t offset, std::size_t length, ArrayDataType &data) = 0;
+    virtual std::size_t put(std::size_t offset,
+        std::size_t length, const_pointer from, std::size_t fromOffset) = 0;
+    virtual std::size_t put(std::size_t offset,
+        std::size_t length, const_vector &from, std::size_t fromOffset);
+    virtual void shareData(
+         shared_vector const & value,
+         std::size_t capacity,
+         std::size_t length) = 0;
+    virtual pointer get() = 0;
+    virtual pointer get() const = 0;
+    virtual vector const & getVector() = 0;
+    virtual shared_vector const & getSharedVector() = 0;
+    std::ostream& dumpValue(std::ostream& o) const;
+    std::ostream& dumpValue(std::ostream& o, size_t index) const;
+
+...
+};
+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<String> StringArrayData;
+typedef PVValueArray<String> PVStringArray;
+typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;i
+
+ +

pvDataCPP-md

+
class PVArray : public PVField, public SerializableArray {
+public:
+    POINTER_DEFINITIONS(PVArray);
+    virtual ~PVArray();
+    virtual void setImmutable();
+    std::size_t getLength() const;
+    virtual void setLength(std::size_t length);
+    std::size_t getCapacity() const;
+    bool isCapacityMutable() const;
+    void setCapacityMutable(bool isMutable);
+    virtual void setCapacity(std::size_t capacity) = 0;
+    virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const = 0;
+ ...
+};
+
+std::ostream& operator<<(format::array_at_internal const& manip, const PVArray& array);
+
+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)
+    {}
+};
+
+class PVScalarArray : public PVArray {
+public:
+    POINTER_DEFINITIONS(PVScalarArray);
+    virtual ~PVScalarArray();
+    typedef PVScalarArray &reference;
+    typedef const PVScalarArray& const_reference;
+    const ScalarArrayConstPtr getScalarArray() const ;
+
+    // in pvDataCPP but not in pvDataCPP=md
+    //virtual std::ostream& dumpValue(std::ostream& o, size_t index) const = 0;
+
+    // not in pvDataCPP
+    template<ScalarType ID>
+    virtual void
+    getAs(shared_vector<typename ScalarTypeTraits<ID>::type>& out) const;
+
+    virtual void
+    getAs(ScalarType, shared_vector<void>& out) const = 0;
+
+    template<ScalarType ID>
+    inline size_t copyOut(typename ScalarTypeTraits<ID>::type* inp, size_t len) const;
+
+    virtual size_t copyOut(ScalarType id, void* ptr, size_t olen) const = 0;
+
+    template<ScalarType ID>
+    inline void putFrom(const shared_vector<typename ScalarTypeTraits<ID>::type>& inp);
+
+    virtual void putFrom(ScalarType, const shared_vector<void>&) = 0;
+
+    template<ScalarType ID>
+    inline void copyIn(const typename ScalarTypeTraits<ID>::type* inp, size_t len);
+
+    virtual void copyIn(ScalarType, const void*, size_t) = 0;
+
+    virtual void assign(PVScalarArray& pv) = 0;
+    
+ ...
+}
+
+template<typename T>
+class PVValueArray : public detail::PVVectorStorage {
+    typedef detail::PVVectorStorage base_t;
+public:
+    POINTER_DEFINITIONS(PVValueArray);
+    typedef T  value_type;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+    typedef PVArrayData<T> ArrayDataType;
+    typedef std::vector<T> vector;
+    typedef const std::vector<T> const_vector;
+    typedef std::tr1::shared_ptr<vector> shared_vector;
+    typedef PVValueArray & reference;
+    typedef const PVValueArray & const_reference;
+
+    virtual ~PVValueArray() {}
+    virtual std::size_t get(
+         std::size_t offset, std::size_t length, ArrayDataType &data) = 0;
+    virtual std::size_t put(std::size_t offset,
+        std::size_t length, const_pointer from, std::size_t fromOffset) = 0;
+    virtual std::size_t put(std::size_t offset,
+        std::size_t length, const_vector &from, std::size_t fromOffset);
+    virtual void shareData(
+         shared_vector const & value,
+         std::size_t capacity,
+         std::size_t length) = 0;
+    virtual pointer get() = 0;
+    virtual pointer get() const = 0;
+    virtual vector const & getVector() = 0;
+    virtual shared_vector const & getSharedVector() = 0;
+    std::ostream& dumpValue(std::ostream& o) const;
+    std::ostream& dumpValue(std::ostream& o, size_t index) const;
+
+    /// not in pvDataCPP
+    static const ScalarType typeCode;
+    typedef ::epics::pvData::shared_vector<T> svector;
+    typedef ::epics::pvData::shared_vector<const T> const_svector;
+
+     virtual void
+    getAs(ScalarType id, ::epics::pvData::shared_vector<void>& out) const;
+    virtual size_t copyOut(ScalarType id, void* ptr, size_t olen) const;
+    virtual void
+    putFrom(ScalarType id, const ::epics::pvData::shared_vector<void>& inp);
+    virtual void copyIn(ScalarType id, const void* ptr, size_t len);
+    virtual void assign(PVScalarArray& pv);
+
+
+protected:
+    PVValueArray(ScalarArrayConstPtr const & scalar)
+    : PVScalarArray(scalar) {}
+    friend class PVDataCreate;
+};
+template<typename T>
+std::size_t PVValueArray<T>::put(
+    std::size_t offset,
+    std::size_t length,
+    const_vector &from,
+    std::size_t fromOffset)
+{ return put(offset,length, &from[0], fromOffset); }
+
+/**
+ * Definitions for the various scalarArray types.
+ */
+typedef PVArrayData<uint8> BooleanArrayData;
+typedef PVValueArray<uint8> PVBooleanArray;
+typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
+...
+typedef PVArrayData<String> StringArrayData;
+typedef PVValueArray<String> PVStringArray;
+typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;i
+
+

proposed

+
class PVArray : public PVField, public SerializableArray {
+public:
+    POINTER_DEFINITIONS(PVArray);
+    virtual ~PVArray();
+    virtual std::size_t getLength() const = 0;
+    virtual void setLength(std::size_t length) = 0;
+    bool isCapacityMutable() const;
+    void setCapacityMutable(bool isMutable);
+    virtual std::size_t getCapacity() const = 0;
+    virtual void setCapacity(std::size_t capacity) = 0;
+ ...
+};
+
+
+class PVScalarArray : public PVArray {
+public:
+    POINTER_DEFINITIONS(PVScalarArray);
+    typedef PVScalarArray &reference;
+    typedef const PVScalarArray& const_reference;
+
+    virtual ~PVScalarArray();
+    const ScalarArrayConstPtr getScalarArray() const;
+ ...
+};
+
+// PVString is special case, since it implements SerializableArray
+class PVString : public PVScalarValue<String>, SerializableArray {
+public:
+    virtual ~PVString() {}
+ ...
+};
+
+template<typename T>
+class PVValueArray :
+public PVScalarArray
+...
+{
+public:
+    POINTER_DEFINITIONS(PVValueArray);
+    typedef T  value_type;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+    typedef PVValueArray & reference;
+    typedef const PVValueArray & const_reference;
+
+    typedef shared_vector<T> svector;
+    typedef shared_vector<const T> const_svector;
+
+    virtual ~PVValueArray() {}
+    const svector & get() const;
+    size_t put(size_t offset,size_t length, const_pointer from, size_t fromOffset);
+    void put(const svector & from);
+
+    void shareData(const svector &from);
+    virtual std::ostream& operator<<(std::ostream& o) const;
+    virtual std::ostream& operator<<(std::ostream& o, size_t index) const;
+
+...
+};
+
+typedef PVValueArray<uint8> PVBooleanArray;
+typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
+...
+typedef PVValueArray<String> PVStringArray;
+typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
+
+ + +

pvDataApp/pv

pvData.h

This provides the interface for network accessible data. @@ -159,8 +896,9 @@ public: void renameField(String const & newName); void postPut(); void setPostHandler(PostHandlerPtr const &postHandler); - virtual std::ostream& operator<<(std::ostream& o) const; - std::ostream& operator<<(std::ostream& o, size_t index) const; + virtual bool equals(PVField &pv); + virtual std::ostream& operator<<(std::ostream& o) const = 0; + virtual std::ostream& operator<<(std::ostream& o, size_t index) const = 0; ... }; @@ -255,9 +993,11 @@ public: virtual ~PVScalarValue() {} virtual T get() const = 0; virtual void put(T value) = 0; + void operator>>=(T& value) const; + void operator<<=(T value); - std::ostream& operator<<(std::ostream& o) const - std::ostream& operator<<(std::ostream& o, size_t index) const; + virtual std::ostream& operator<<(std::ostream& o) const + virtual std::ostream& operator<<(std::ostream& o, size_t index) const; ... }; typedef PVScalarValue<uint8> PVBoolean; @@ -298,6 +1038,7 @@ public:

put
Change the value stored in the object.
operator<<
+
operator>>
Methods for stream I/O.
@@ -390,13 +1131,14 @@ public: typedef shared_vector<const T> const_svector; virtual ~PVValueArray() {} - const_svector & get(); - size_t put(size_t offset,size_t length, const_svector &from, size_t fromOffset); + const svector & get() const; + size_t put(size_t offset,size_t length, const_pointer from, size_t fromOffset); + void put(const svector & from); - void shareData(const_svector &from); + void shareData(const svector &from); - virtual std::ostream& operator<<(std::ostream& o) const; - std::ostream& operator<<(std::ostream& o, size_t index) const; + virtual std::ostream& operator<<(std::ostream& o) const + virtual std::ostream& operator<<(std::ostream& o, size_t index) const; ... }; @@ -446,17 +1188,25 @@ typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr; For example it must call postPut after modifying the array elements. It must also respect isImmutable(). +
size_t put(size_t offset,size_t length, const_pointer from, size_t fromOffset);
put
This is the recommended method for modifying the array elements. It may change the capacity if len asks for more elements than the cureent capacity allows. It does not change the current length.
+
void put(const svector & from);
+
This puts data into the PVValueArray from the shared_vector. + If the shared_vector holds the same raw array as the PVValueArray then + the shared_vector held by the PVValueArray is put in sync with from. + If not the shared_vector will share the data. + potsPut will always be called.
shareData
Share data with an existing shared_vector. - Note that if capacity is every changed then data will no + Note that if capacity is ever changed then data will no longer be shared.
operator<<
+
operator>>
Methods for stream I/O.
@@ -587,8 +1337,7 @@ for(size_t i=0; i<len; ++i) pint32Array[i] = i;

A const_pointer is like a pointer except that only read access to the array elements is allowed.

-

Dangorous: data should not be used unless it is necessary to -call C code. The above code should be:

+

NOTE: data The above code is better implemented as:

 Int32Array int32Array(5);
 size_t len = int32Array.size();
@@ -826,7 +1575,7 @@ void clear();
      
(true,false) if size is (0,>0)
max_size
Maximum possible number of elements. -NOTE EXISTING; Should this be sizof(W)/(size_t -1) ? +NOTE EXISTING; Should be ((size_t)-1)/sizeof(T)
capacity
The maximum size the window can be without reallocating raw array
@@ -913,7 +1662,7 @@ at()
 Int32Array::pointer pint32= int32Array.data();
 
-is NOT gauranteed to be the same as +is guaranteed to be the same as
 int32 * pint32 = int32Array.data();