diff --git a/documentation/pvDataDiscussion.html b/documentation/pvDataDiscussion.html new file mode 100644 index 0000000..08a1e45 --- /dev/null +++ b/documentation/pvDataDiscussion.html @@ -0,0 +1,792 @@ + + + + + + EPICS pvDataDiscussion + + + + + + + + +
+

EPICS pvDataDiscussion

+ + +

EPICS v4 Working Group, Working Draft, 03-Jul-2013

+ +
+
Latest version:
+
pvDataDiscussion.html +
+
This version:
+
none
+
Previous version:
+
None
+
Editors:
+
Marty Kraimer, BNL
+
+ + +
+
+ + +
+

Table of Contents

+
+
+ + +

Introduction

+

As pvDataCPP progressed PVField and derived classes accumulated +more and more member functions. +These member functions have nothing to do with the primary 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 it clear that communication +includes efficent network communication. +Thus pvData provides an interface for network accessible structured data. +The problem of adding member functions that have nothing to do with the primary purpose +started with the Java API. +It already had extra methods that solved problems that should have had a different solution. +This document removes the extra methods so that when new problems arise in the future +the solution will not involve adding new member functions to the introspection and data API. +

+

The introspection and data API for pvData should only encapuslate methods that support the primary purpose +stated above. +The interfaces for C++ and Java should be similar so that +someone who understands the interface in one of the languages +and knows both languages will quickly understand the interface of the other language.

+

There is another problem with the existing API. There are methods that allow the "structure" +to change after an pvData object is created. An example is PVField::renameField(String newName). +Such methods should not exist.

+

There are methods regarding immutability: setImmutable, isImmutablei, setCapacityMutable, and isCapacityMutable. +Should they exists? For now lets assume no. +

+

One last issue is the interface for array data. This document proposes a simplified +version of what currently exists. It requires that the implementation always provides storage for +the complete raw array. The existing APIs allow the implementation to provide the data in +"chunks". Giving up this requirement simplifies the array interfaces. +The existing C++ implementation of PVValueArray has serious problems. +The shared_vector that is implemented in pvDataCP-md provides the solution to fixing +the problems. This document describes an API that is very similar to the new Java API +except that raw arrays are replaced by shared_vector.

+

This document will first describe changes to the existing Java interfaces +and then the corresponding C++ API.

+

Java API

+

The following shows which methods will be removed from the existing interfaces +and what will be added. +The methods to be removed are in red +and methods to add are in blue +Also the removed methods are at the end with a comment above. +The new methods also have a comment. +

+

Introspection Interfaces

+ +
interface Field extends Serializable {
+    String getId();
+    Type getType();
+    // following will be removed
+    void toString(StringBuilder buf);
+    void toString(StringBuilder buf,int indentLevel);
+    String toString();
+}
+
+
+// new interface
+interface FieldToString {
+    String toString(Field field);
+}
+
+interface Scalar extends Field {
+    ScalarType getScalarType();
+}
+
+interface ScalarArray extends Field {
+    ScalarType getElementType();
+}
+
+interface Structure extends Field {
+    Field getField(String fieldName);
+    int getFieldIndex(String fieldName);
+    Field[] getFields();
+    Field getField(int fieldIndex);
+    String[] getFieldNames();
+    String getFieldName(int fieldIndex)
+}
+
+interface StructureArray extends Field {
+    Structure getStructure();
+}
+
+interface FieldCreate {
+    Scalar createScalar(ScalarType scalarType);
+    ScalarArray createScalarArray(ScalarType elementType);
+    StructureArray createStructureArray(Structure elementStructure);
+    Structure createStructure(String[] fieldNames, Field[] field);
+    Structure createStructure(String id,String[] fieldNames, Field[] field);
+    Structure createStructure(Structure structToClone);
+    Field deserialize(ByteBuffer buffer, DeserializableControl control);
+    // following will be removed
+    Structure appendField(Structure structure,String fieldName, Field field);
+    Structure appendFields(Structure structure,String[] fieldNames, Field[] fields);
+}
+
+

Data Interfaces

+
+interface PVField extends Requester, Serializable {
+    String getFieldName();
+    void setRequester(Requester requester);
+    int getFieldOffset();
+    int getNextFieldOffset();
+    int getNumberFields();
+    Field getField();
+    PVStructure getParent();
+    void postPut();
+    void setPostHandler(PostHandler postHandler);
+    // following will be removed
+    PVAuxInfo getPVAuxInfo();
+    boolean isImmutable();
+    void setImmutable();
+    void renameField(String newName);
+    void toString(StringBuilder buf);
+    void toString(StringBuilder buf,int indentLevel);
+    String toString();
+}
+
+
+// The following is a new interface
+interface PVFieldToString {
+    String toString(PVField pvField);
+    void setMaxInitialArrayElements(int num);
+    void setMaxFinalArrayElements(int num);
+    int getMaxInitialArrayElements();
+    int getMaxFinalArrayElements();
+}
+    
+interface PVScalar extends PVField{
+    Scalar getScalar();
+}
+
+interface PVDouble extends PVScalar{
+    double get();
+    void put(double value);
+}
+// also PVBoolean, PVByte, PVShort, PVInt, PVLong, PVFloat, and PVString
+
+interface PVArray extends PVField, SerializableArray {
+    int getLength();
+    void setLength(int length);
+    int getCapacity();
+    void setCapacity(int length);
+    // following will be removed
+    boolean isCapacityMutable();
+    void setCapacityMutable(boolean isMutable);
+}
+
+interface PVScalarArray extends PVArray {
+    ScalarArray getScalarArray();
+}
+
+
+//following will be removed
+public class DoubleArrayData {
+    public double[] data;
+    public int offset;
+}
+
+interface PVDoubleArray extends PVArray {
+    // following are new
+    double[] get();
+    void swap(double[] value);
+    //following will be removed
+    int get(int offset, int len, DoubleArrayData data);
+    int put(int offset,int len, double[] from, int fromOffset);
+    void shareData(double[] from);
+}
+
+// also PVBooleanArray, ..., PVStringArray
+
+
+interface PVStructure extends PVField , BitSetSerializable{
+    Structure getStructure();
+    PVField[] getPVFields();
+    PVField getSubField(String fieldName);
+    PVField getSubField(int fieldOffset);
+    // The following are convenience methods
+    PVBoolean getBooleanField(String fieldName);
+    PVByte getByteField(String fieldName);
+    PVShort getShortField(String fieldName);
+    PVInt getIntField(String fieldName);
+    PVLong getLongField(String fieldName);
+    PVFloat getFloatField(String fieldName);
+    PVDouble getDoubleField(String fieldName);
+    PVString getStringField(String fieldName);
+    PVScalarArray getScalarArrayField(String fieldName);
+    PVStructureArray getStructureArrayField(String fieldName);
+    PVStructure getStructureField(String fieldName);
+    PVArray getArrayField(String fieldName,ScalarType elementType);
+    // following will be removed
+    void appendPVField(String fieldName,PVField pvField);
+    void appendPVFields(String[] fieldNames,PVField[] pvFields);
+    void removePVField(String fieldName);
+    void replacePVField(PVField oldPVField,PVField newPVField);
+    String getExtendsStructureName();
+    boolean putExtendsStructureName(String extendsStructureName);
+    public boolean checkValid();
+}
+ 
+
+//following will be removed
+public class StructureArrayData {
+    public PVStructure[] data;
+    public int offset;
+}
+
+
+interface PVStructureArray extends PVArray{
+    StructureArray getStructureArray();
+    // following are new
+    PVStructure[] get();
+    void swap(PVStructure[] value);
+    // following will be removed
+    int get(int offset, int length, StructureArrayData data);
+    int put(int offset,int length, PVStructure[] from, int fromOffset);
+    void shareData(PVStructure[] from);
+}
+
+
+public interface PVDataCreate {
+    PVField createPVField(Field field);
+    PVField createPVField(PVField fieldToClone);
+    PVScalar createPVScalar(Scalar scalar);
+    PVScalar createPVScalar(ScalarType fieldType);
+    PVScalar createPVScalar(PVScalar scalarToClone);
+    PVScalarArray createPVScalarArray(ScalarArray array);
+    PVScalarArray createPVScalarArray(ScalarType elementType);
+    PVScalarArray createPVScalarArray(PVScalarArray arrayToClone;
+    PVStructureArray createPVStructureArray(StructureArray structureArray);
+    PVStructure createPVStructure(Structure structure);
+    PVStructure createPVStructure(String[] fieldNames,Field[] fields);
+    PVStructure createPVStructure(PVStructure structToClone);
+    // following will be removed
+    PVField[] flattenPVStructure(PVStructure pvStructure);
+}
+
+

PVFieldToString

+

In addition to toString this has methods to limit the number of array element to display. +The existing Java implementation of toString displayed all elements. +For large arrays this is not desirable. +The new methods provide a way for the client to limit the number of elements. +The default might be set to something like display up to 10 elements with 5 fron the beginning and 5 from the end.

+

For C++ this can be a replacement for dumpValue.

+

PVBooleanArray, ..., PVStructureArray

+

The old get and put are replaced by two new and simpler methods: +

+
get
+
Returns the raw array. If the client code modifies the elements in the array then + the client must call postPut. The client also has to realize that if the raw array held by the PVXXXArray changes + then the client is no longer sharing data +
swap
+
This exchanges the old raw data with the new raw data.
+
+

+

+The method setCapacity will always create a new raw array and copy old data from the old to the new array. +This is not true now since the implementation does not create a new array if the old capacity is equal to the requested capacity. +

+

C++ API

+

The C++ class definitions are similar to the Java definitions with two main exceptions: +

+
toString
+
In c++ this is replaced by std::ostream.
+
raw array data
+
Java supports array data like double[] + The C++ replacement is shared_vector<double>, which is implemented + in pvDataCPP-md.
+

Introspection Interfaces

+ +
+class Field :
+    virtual public Serializable,
+    public std::tr1::enable_shared_from_this<Field>
+{
+public:
+    POINTER_DEFINITIONS(Field);
+    virtual ~Field();
+    Type getType() const{return m_type;}
+    virtual String getID() const = 0;
+    
+    // following will be removed
+    virtual void toString(StringBuilder buf) const{toString(buf,0);}
+    virtual void toString(StringBuilder buf,int indentLevel) const;
+    
+ ...
+};
+
+// new function
+std::ostream &toString(Field::const_reference field, std::ostream& o);
+
+
+class Scalar : public Field{
+public:
+    POINTER_DEFINITIONS(Scalar);
+    virtual ~Scalar();
+    typedef Scalar& reference;
+    typedef const Scalar& const_reference;
+
+    ScalarType getScalarType() const {return scalarType;}
+    virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
+    virtual void deserialize(ByteBuffer *buffer, DeserializableContol *control);
+    
+    // following will be removed
+    virtual void toString(StringBuilder buf) const{toString(buf,0);}
+    virtual void toString(StringBuilder buf,int indentLevel) const;
+    virtual String getID() const;
+    
+ ...
+};
+class ScalarArray : public Field{
+public:
+    POINTER_DEFINITIONS(ScalarArray);
+    typedef ScalarArray& reference;
+    typedef const ScalarArray& const_reference;
+
+    ScalarArray(ScalarType scalarType);
+    ScalarType  getElementType() const {return elementType;}
+    virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
+    virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
+    
+    // following will be removed
+    virtual void toString(StringBuilder buf) const{toString(buf,0);}
+    virtual void toString(StringBuilder buf,int indentLevel) const;
+    virtual String getID() const;
+    
+ ...
+};
+
+class Structure : public Field {
+public:
+    POINTER_DEFINITIONS(Structure);
+    typedef Structure& reference;
+    typedef const Structure& const_reference;
+
+   std::size_t getNumberFields() const {return numberFields;}
+   FieldConstPtr getField(String const & fieldName) const;
+   FieldConstPtr getField(std::size_t index) const;
+   std::size_t getFieldIndex(String const &fieldName) const;
+   FieldConstPtrArray const & getFields() const {return fields;}
+   StringArray const & getFieldNames() const;
+   String getFieldName(std::size_t fieldIndex);
+   virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
+   virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
+    
+    // following will be removed
+   void renameField(std::size_t fieldIndex,String const &newName);
+   virtual void toString(StringBuilder buf,int indentLevel) const;
+   virtual String getID() const;
+   
+ ...
+};
+
+class StructureArray : public Field{
+public:
+    POINTER_DEFINITIONS(StructureArray);
+    typedef StructureArray& reference;
+    typedef const StructureArray& const_reference;
+
+    StructureConstPtr  getStructure() const {return pstructure;}
+    virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
+    virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
+    
+    // following will be removed
+    virtual void toString(StringBuilder buf,int indentLevel=0) const;
+    virtual String getID() const;
+    
+ ...
+};
+
+class FieldCreate  {
+public:
+    static FieldCreatePtr getFieldCreate();
+    ScalarConstPtr  createScalar(ScalarType scalarType) const
+    ScalarArrayConstPtr createScalarArray(ScalarType elementType) const;
+    StructureArrayConstPtr createStructureArray(StructureConstPtr const & structure) const;
+    StructureConstPtr createStructure (
+        StringArray const & fieldNames,
+        FieldConstPtrArray const & fields) const;
+    StructureConstPtr createStructure (
+        String const &id,
+        StringArray const & fieldNames,
+        FieldConstPtrArray const & fields) const;
+    FieldConstPtr deserialize(ByteBuffer* buffer, DeserializableControl* control) const;
+    
+    // following will be removed
+    StructureConstPtr appendField(
+        StructureConstPtr const & structure,
+        String const &fieldName, FieldConstPtr const & field) const;
+    StructureConstPtr appendFields(
+        StructureConstPtr const & structure,
+        StringArray const & fieldNames,
+        FieldConstPtrArray const & fields) const;
+    
+ ...
+};
+
+extern FieldCreatePtr getFieldCreate();
+ 
+

Data Interfaces

+
+class PVField
+: virtual public Serializable,
+  public std::tr1::enable_shared_from_this<PVField>
+{
+public:
+   POINTER_DEFINITIONS(PVField);
+   virtual ~PVField();
+   inline const String &getFieldName() const ;
+   virtual void setRequester(RequesterPtr const &prequester);
+   std::size_t getFieldOffset() const;
+   std::size_t getNextFieldOffset() const;
+   std::size_t getNumberFields() const;
+   const FieldConstPtr & getField() const ;
+   PVStructure * getParent() const
+   void postPut() ;
+   void setPostHandler(PostHandlerPtr const &postHandler);
+    // following will be removed
+    
+   virtual void message(String message,MessageType messageType);
+   void replacePVField(const PVFieldPtr&  newPVField);
+   String getFullName() const;
+   virtual bool equals(PVField &pv);
+   PVAuxInfoPtr & getPVAuxInfo()
+   bool isImmutable() const;
+   virtual void setImmutable();
+   void replacePVField(const PVFieldPtr&  newPVField);
+   void renameField(String const &newName);
+   virtual void toString(StringBuilder buf) ;
+   virtual void toString(StringBuilder buf,int indentLevel);
+   std::ostream& dumpValue(std::ostream& o) const;
+   
+ ...
+};
+
+
+// The following is a new class
+class PVFieldToString {
+    String toString(const PVFieldPtr &pvField);
+    void setMaxInitialArrayElements(size_t num);
+    void setMaxFinalArrayElements(size_t num);
+    size_t getMaxInitialArrayElements();
+    size_t getMaxFinalArrayElements();
+...
+}
+
+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;
+    
+    // following will be removed
+    std::ostream& dumpValue(std::ostream& o)
+    void operator>>=(T& value) const;
+    void operator<<=(T value);
+    
+ ...
+}
+
+// PVString is special case, since it implements SerializableArray
+class PVString : public PVScalarValue<String>, SerializableArray {
+public:
+    virtual ~PVString() {}
+ ...
+}
+class PVArray : public PVField, public SerializableArray {
+public:
+    POINTER_DEFINITIONS(PVArray);
+    virtual ~PVArray();
+    std::size_t getLength() const;
+    virtual void setLength(std::size_t length);
+    std::size_t getCapacity() const;
+    virtual void setCapacity(std::size_t capacity) = 0;
+    
+    // following will be removed
+    virtual void setImmutable();
+    bool isCapacityMutable() const;
+    void setCapacityMutable(bool isMutable);
+    virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const = 0;
+    
+ ...
+};
+
+class PVScalarArray : public PVArray {
+public:
+    POINTER_DEFINITIONS(PVScalarArray);
+    virtual ~PVScalarArray();
+    typedef PVScalarArray &reference;
+    typedef const PVScalarArray& const_reference;
+
+    const ScalarArrayConstPtr getScalarArray() const ;
+    
+    // following will be removed
+    virtual std::ostream& dumpValue(std::ostream& o, size_t index) const = 0;
+    
+ ...
+}
+
+
+// following will be removed
+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)
+    {}
+};
+
+
+template<typename T>
+class PVValueArray : public PVScalarArray {
+public:
+    POINTER_DEFINITIONS(PVValueArray);
+    typedef T  value_type;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+    // following are new typeDefs
+    typedef shared_vector<T> svector;
+    typedef shared_vector<const T> const_svector; 
+
+    virtual ~PVValueArray() {}
+    // following are added
+    svector get();
+    void swap(svector& value);
+    
+    // following are removed
+    typedef PVValueArray & reference;
+    typedef const PVValueArray & const_reference;
+    typedef PVArrayData<T> ArrayDataType;
+    typedef std::vector<T> vector;
+    typedef const std::vector<T> const_vector;
+    typedef std::tr1::shared_ptr<vector> shared_vector;
+
+    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;
+    
+...
+};
+
+typedef PVValueArray<uint8> PVBooleanArray;
+typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
+...
+typedef PVValueArray<String> PVStringArray;
+typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
+
+class PVStructure : public PVField,public BitSetSerializable {
+public:
+    POINTER_DEFINITIONS(PVStructure);
+    virtual ~PVStructure();
+    typedef PVStructure & reference;
+    typedef const PVStructure & const_reference;
+
+    StructureConstPtr getStructure() const;
+    const PVFieldPtrArray & getPVFields() const;
+    PVFieldPtr getSubField(String const &fieldName) const;
+    PVFieldPtr getSubField(std::size_t fieldOffset) const;
+    PVBooleanPtr getBooleanField(String const &fieldName) ;
+    PVBytePtr getByteField(String const &fieldName) ;
+    PVShortPtr getShortField(String const &fieldName) ;
+    PVIntPtr getIntField(String const &fieldName) ;
+    PVLongPtr getLongField(String const &fieldName) ;
+    PVUBytePtr getUByteField(String const &fieldName) ;
+    PVUShortPtr getUShortField(String const &fieldName) ;
+    PVUIntPtr getUIntField(String const &fieldName) ;
+    PVULongPtr getULongField(String const &fieldName) ;
+    PVFloatPtr getFloatField(String const &fieldName) ;
+    PVDoublePtr getDoubleField(String const &fieldName) ;
+    PVStringPtr getStringField(String const &fieldName) ;
+    PVStructurePtr getStructureField(String const &fieldName) ;
+    PVScalarArrayPtr getScalarArrayField(
+        String const &fieldName,ScalarType elementType) ;
+    PVStructureArrayPtr getStructureArrayField(String const &fieldName) ;
+    virtual void serialize(
+        ByteBuffer *pbuffer,SerializableControl *pflusher) const ;
+    virtual void deserialize(
+        ByteBuffer *pbuffer,DeserializableControl *pflusher);
+    virtual void serialize(ByteBuffer *pbuffer,
+        SerializableControl *pflusher,BitSet *pbitSet) const;
+    virtual void deserialize(ByteBuffer *pbuffer,
+        DeserializableControl*pflusher,BitSet *pbitSet);
+    PVStructure(StructureConstPtr const & structure);
+    PVStructure(StructureConstPtr const & structure,PVFieldPtrArray const & pvFields);
+    
+    // following are removed
+    void appendPVField(
+        String const &fieldName,
+        PVFieldPtr const & pvField);
+    void appendPVFields(
+        StringArray const & fieldNames,
+        PVFieldPtrArray const & pvFields);
+    void removePVField(String const &fieldName);
+    virtual void setImmutable();
+    String getExtendsStructureName() const;
+    bool putExtendsStructureName(
+        String const &extendsStructureName);
+    
+};
+
+
+// following will be removed
+typedef PVArrayData<PVStructurePtr> StructureArrayData;
+
+
+class PVStructureArray : public PVArray
+{
+public:
+    POINTER_DEFINITIONS(PVStructureArray);
+    typedef PVStructurePtr  value_type;
+    typedef PVStructurePtr* pointer;
+    typedef const PVStructurePtr* const_pointer;
+    
+    // following are new typeDefs
+    typedef shared_vector<PVStructurePtr> svector;
+    typedef shared_vector<const PVStructurePtr> const_svector;
+    
+
+    virtual ~PVStructureArray() {}
+    virtual void setCapacity(size_t capacity);
+    virtual void setLength(std::size_t length);
+    virtual StructureArrayConstPtr getStructureArray() const ;
+    virtual void serialize(ByteBuffer *pbuffer,
+        SerializableControl *pflusher) const;
+    virtual void deserialize(ByteBuffer *buffer,
+    virtual void serialize(ByteBuffer *pbuffer,
+        SerializableControl *pflusher, std::size_t offset, std::size_t count) const ;
+    // following are new
+    svector get();
+    void swap(svector & value);
+    
+    // following are removed
+    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;
+    
+    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 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;}
+    
+ ...
+};
+
+class PVDataCreate {
+public:
+    static PVDataCreatePtr getPVDataCreate();
+    PVFieldPtr createPVField(FieldConstPtr const & field);
+    PVFieldPtr createPVField(PVFieldPtr const & fieldToClone);
+    PVScalarPtr createPVScalar(ScalarConstPtr const & scalar);
+    PVScalarPtr createPVScalar(ScalarType scalarType);
+    PVScalarPtr createPVScalar(PVScalarPtr const & scalarToClone);
+    PVScalarArrayPtr createPVScalarArray(ScalarArrayConstPtr const & scalarArray);
+    PVScalarArrayPtr createPVScalarArray(ScalarType elementType);
+    PVScalarArrayPtr createPVScalarArray(PVScalarArrayPtr const  & scalarArrayToClone);
+    PVStructureArrayPtr createPVStructureArray(StructureArrayConstPtr const & structureArray);
+    PVStructurePtr createPVStructure(StructureConstPtr const & structure);
+    PVStructurePtr createPVStructure(
+        StringArray const & fieldNames,PVFieldPtrArray const & pvFields);
+   PVStructurePtr createPVStructure(PVStructurePtr const & structToClone);
+ ...
+};
+
+extern PVDataCreatePtr getPVDataCreate();
+
+ + +
+ +