From 3de28e3cef76fbf2d0b234181ed5743617a1e707 Mon Sep 17 00:00:00 2001
From: Marty Kraimer This product is made available subject to acceptance of the EPICS open source
+license. This is the documentation for the scalarArray data type as defined by pvDataCPP-md.
+When complete it will be merged into pvDataCPP.html.
+Only sharedVector is currently documented.
+It is documented in the next section, but when merged into pvDataCPP.html,
+will appear in a later section.
+For now ignore the documentation in pvDataApp/pv. When NOTE EXISTING appears it means that there is a question about
+the existing shared_vector implementation. I think that all public components of sharedVector.h
+are now documented, but not all have a description or example.
+Thus the documentation needs more work.
+ A shared_vector is a container as defined by the C++ standard library.
+It is like std::vector but provides two additional features
+1) shared raw array and 2) a window into the raw array. To support these two features a shared_vector keeps the following
+private data:
+ The following subsections are organized as follows:
+ The subsections that are compatible with std::vector are organized
+and start with a brief summary modeled after Section 31.3(STL Containers) in: The comparison is always with std::vector.
+In addition it shows what is defined by by std::vector but not by
+shared_vector. Someone who already understand the C++ STL can understand shared_vector
+by just looking at the brief summarys.
+For others the brief summary is followed by tutorial information.
+ The examples all assume that the following has been defined: The following:
+ exampleSharedVector is a main program that has the code for the
+examples shown below. Brief Summary
+
+The typedefs are compatible with the STL container member types.
+These define types for various types of variables that belong to a container
+or are used to access a container. These three typedefs define the same types as the equivalent types for
+an element of the shared_vector.
+ The following is an example of code that uses the
+pointer typedef: 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: This is used to get the number of elements between two elements.
+For example: These are member types defined by std::tr1::shared_ptr.
+These are not used by any of the client methods. Brief Summary
+ The first three constructors all create a new shared_vector
+by also creating a new raw array,
+The difference is the size of the array, i.e. how many elements it contains,
+and how the elements are initalized.
+ The following:
+ NOTE EXISTING: Why did emptyArray disply the above.
+Should it be "emptyArray {0} []"?
+ These create a vector by coping the contents of an existing shared_vector
+of the same type into the newly created vector.
+Note that the complete raw array is not copied but just the std::tr1:: shared_ptr
+that holds the array. The following:
+ NOTE EXISTING: Are these constructors necessary?
+If code wants to wrap an existing raw array then
+a std::tr1::shared_ptr can first be created
+and the constructor in the next section can be called. These "wrap" an existing raw pointer.
+They allows access to a sub-array starting at offset o>
+and has size c
+The second provides a destructor and the first has a default deleter. The default deleter does the following:
+When the shared_vector is deleted, i. e. when no code references it,
+the statement "delete[] a;" is executed. An example of wrapping a raw array without using these constructors is: This is used to wrap arrays that are managed by other
+code. This should only be used if You understand the other code
+and know what your deleter has to do.
+An example, exampleShareRawArray, gives a more complete example.
+ This creates a vector from an existing smart pointer.
+Thus the vector will share reference counting with the existing smart
+pointer. This is useful for creating "windows" into the array
+that the smart pointer references. NOTE EXISTING: I do not understand how this works or what it does. This create a vector by coping the contents of an existing shared_vector
+of the same or a different but related type
+into the newly created vector.
+This constructor creates a new raw array and copies the elements from
+the existing array to the new array. Brief Summary
+ Details
+ The following:
+ Brief Summary
+
+shared_vector supports both iterators and reverse iterators as defined by the STL.
+For both constant iterators are also defined.
+A constant iterator does not allow an array elemnent to be modified. The following is an example of a constant iterator. The following is an example of a non constant iterator. Brief Summary
+ Note that:
+ NOTE EXISTING: data() should be defined to return a const_pointer.
+It is currently defined to return a plain pointer. Brief Summary
+ shared_vector does not support the standard list operations like:
+ Brief Summary
+ Swap the contents of two shared_vectors. The following code:
+ Brief Summary
+ NOTE EXISTING: The C++ standard library considers a slice to be every nth element
+of some part of an array, i. e., slice has arguments (offset,length,stride).
+shared_vector only has offset and length.
+Perhaps it should have another name like rewindow.
+ This modifies the "window" into the raw array starting at offset and of
+the specified length. The offset and length are forced to be
+within the raw array.
+Note that this method never reallocates the underlying raw array.
+ The following code:
+ The following:
+ Not yet documented Not yet documented Not yet documented INGORE REST OF DOCUMENT!!!! PVArray is the base interface for all the other PV Array interfaces. It
+extends PVField and provides the additional methods: 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. where This is a template class plus instances for PVBooleanArray, ...,
+PVStringArray. where Both get and put return the number of elements actually transfered. The
+arguments are: 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:EPICS Array
+
+
+EPICS v4 Working Group, Working Draft, 13-Jun-2013
+
+
+
+
+
+ Michael Davidsaver, BNL
+Table of Contents
+Introduction
+shared_vector
+Status
+Introduction
+
+
+Note that only m_data is shared. Thus each shared_vector has it's own window.
+
+
+
+"The C++ Programming Language, C++11, Fourth Edition", Bjarne Stroustrup,2013
+The subsection names are the same names that Stroustrup uses.
+Each subsection starts with a brief summary that is similar to
+the summary Stroustrup has at the beginnining of each subsection.shared_vector example
+
+typedef shared_vector<int32> Int32Array;
+...
+static void dumpArray(String const &message,Int32Array const& int32Array);
+
+
+Int32Array int32Array(5);
+dumpArray("example",int32Array);
+
+creates a shared vector that holds an array of five elements where each element is a
+32 bit signed integer.
+The call to dumpArray displays the message and the array elements on standard out:
+
+example 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+
+
+Member Types
+
+value_type Type of element
+size_type Unsigned type of subscripts, element counts, etc.
+difference_type Signed type of difference between iterators
+iterator Behaves like value_type*
+const_iterator Behaves like const value_type*
+reverse_iterator Behaves like value_type*
+const_reverse_iterator Behaves like const value_type*
+reference value_types&
+const_reference const_value_type&
+pointer Behaves like value_type *
+const_pointer Behaves like const value_type*
+//not part of std::vector
+element_type same as value_type
+shared_pointer_type std::tr1::shared_ptr<value_type>
+// defined by std::vector but not by shared_vector
+allocator_type
+
+
+value_type, reference, and const_reference
+
+Int32Array::value_type value;
+//is the same as
+int32 value;
+
+Int32Array::reference rvalue = value;
+//is the same as
+int32 & rvalue = value;
+
+Int32Array::const_reference rvalue = value;
+//is the same as
+const int32 & rvalue = value;
+
+
+pointer and const_pointer
+
+Int32Array int32Array(5);
+Int32Array::pointer pint32Array = int32Array.data();
+size_t len = int32Array.size();
+for(size_t i=0; i<len; ++i) pint32Array[i] = i;
+
+
+Int32Array int32Array(5);
+size_t len = int32Array.size();
+for(size_t i=0; i<len; ++i) int32Array[i] = i;
+
+
+difference_type
+
+Int32Array::difference_type pdiff = int32Array[3] - int32Array[1];
+// pdiff will have the value 2
+
+element_type and shared_pointer_type
+Constructors, Destructor, and Assignments
+
+C c(); Default constructor; c is empty.
+C c(n); c is initialized with n elementis with the value value_type{};
+ offset is 0; size is n;
+C c(n,e); Initialize c with n copies of e.
+ offset is 0; size is n;
+
+C c(c); Copy an existing shared_vector of the same type.
+ offset and taken same as v.
+ shared_ptr is copied; not the raw array
+C operator=(c) Assignment constructor.
+ shared_ptr is copied; not the raw array
+C c(c,o,n); Copy an existing std::tr1::shared_ptr<value_type>
+ offset is o; size is c;
+C c(r,o,n); Use an existing raw pointer.
+ default deleter use "delete[]" to delete.
+ offset is o; size is c;
+C c(r,d,o,n); Use an existing raw pointer and deleter d;
+ offset is o; size is c;
+
+not implemented
+~C() The C++ default destructor is used.
+C++11 specific
+&& constructor move constructor
+{} constructor uniform initializer constructor
+
+where
+
+
+
+Construct by creating new raw array
+
+shared_vector();
+shared_vector(size_t n);
+shared_vector(size_t n, value_type e);
+
+
+
+
+ cout << "***exampleConstructors***" << endl;
+ Int32Array emptyArray();
+ Int32Array zeroArray(16);
+ int32 value = 1;
+ Int32Array oneArray(8, value);
+ dumpArray("emptyArray",emptyArray);
+ dumpArray("zeroArray",zeroArray);
+ dumpArray("oneArray",oneArray);
+
+produces
+
+***exampleConstructors***
+emptyArray 1
+zeroArray {16}[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...]
+oneArray {8}[1, 1, 1, 1, 1, 1, 1, 1]
+
+Construct by sharing raw array from a shared_vector
+
+shared_vector(const shared_vector& o);
+shared_vector_base& operator=(const shared_vector_base& o);
+
+
+ cout << "***exampleCopyConstructors***" << endl;
+ size_t max = 16;
+ Int32Array int32Array(max);
+ for(size_t i=0; i<max; ++i) int32Array[i] = i+1;
+ Int32Array xxx(int32Array); //copy constructor
+ Int32Array yyy = int32Array; //copy assignment
+ cout << "dataPtr int32Array " << int32Array.dataPtr();
+ cout << " xxx " << xxx.dataPtr();
+ cout << " yyy " << yyy.dataPtr() << endl;
+ dumpArray("int32Array",emptyArray);
+ dumpArray("xxx",emptyArray);
+ dumpArray("yyy",emptyArray);
+
+produces
+
+***exampleConstructors***
+dataPtr int32Array 0x136ea90 xxx 0x136ea90 yyy 0x136ea90
+int32Array {16}[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...]
+xxx {16}[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...]
+yyy {16}[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...]
+
+Construct by wrapping an existing raw array
+
+shared_vector(A v, size_t o, size_t c)
+shared_vector(A d, B b, size_t o, size_t c)
+
+
+class Int32ArrayDeleter
+{
+//Note that this an example that does nothing.
+//But it could have private data
+public:
+ Int32ArrayDeleter() {}
+ virtual ~Int32ArrayDeleter() {}
+ void operator()(int32* a){
+ // MUST HANDLE DELETION
+ // default is "delete[] a;"
+ }
+};
+...
+int32 *pother; // something managed by other code
+size_t capacity; // size of array managed by other code
+
+Int32Array int32Array(pother,int32array_deleter,0,capacity);
+
+Create a shared_vector from an existing shared_ptr
+
+shared_vector(const std::tr1::shared_ptr<E1>& d, size_t o, size_t c)
+
+Create a shared_vector from an existing shared_vector
+
+ template<typename E1>
+ shared_vector(const shared_vector<E1>& o) :base_t(o) {}
+
+Size and Capacity
+
+size() Return the number of elements in the window
+empty() Is the window empty? this means shared_ptr is empty
+max_size() The maximum possible number of elements.
+capacity() The number of possible elements without re-allocating raw array.
+reserve(n) Reserve at least n elements in raw array; May cause reallocation.
+resize(n) Change size to n; May cause reallocation
+clear() shared_ptr is reset, Window will be empty.
+
+not implemented
+resize(n,v)
+shrink_to_fit()
+
+
+size_t size() const;
+bool empty() const;
+size_t max_size() const;
+size_t capacity() const;
+void reserve(size_t n);
+void resize(size_t n);
+void clear();
+
+
+
+
+
+static void exampleSizeEtc()
+{
+ cout << "***exampleSizeEtc***" << endl;
+ size_t max = 16;
+ Int32Array int32Array(max);
+ size_t capacity = int32Array.capacity();
+ size_t size = int32Array.size();
+ bool empty = int32Array.empty();
+ size_t max_size = int32Array.max_size();
+ cout<< "capacity" << capacity;
+ cout<< " size " << size;
+ cout<< " empty " << (empty ? true : false) ;
+ cout<< " max_size " << max_size << endl;
+}
+
+
+produces:
+
+***exampleSizeEtc***
+capacity16 size 16 empty 0 max_size 18446744073709551615
+
+
+Iterators
+
+begin() First element
+end() One past last element
+cbegin() Constant first element
+cend() Constant last element
+rbegin() First element of reverse sequence
+rend() One past last element of reverse sequence
+crbegin() Constant first element of reverse sequence
+crend() Constant last element of reverse sequence
+
+
+int32 sum = 0;
+for(Int32Array::const_iterator iter=int32Array.begin(); iter<int32Array.end(); ++iter )
+{
+ sum += *iter;
+}
+
+
+int32 value = 0;
+for(Int32Array::iterator iter=int32Array.begin(); iter<int32Array.end(); ++iter )
+{
+ *iter += ++value;
+}
+
+Element Access
+
+operator[i] random element access
+data() return the raw array
+
+implemented by std::vector but not implemented
+front()
+back()
+at()
+
+
+Int32Array::pointer pint32= int32Array.data();
+
+is NOT gauranteed to be the same as
+
+int32 * pint32 = int32Array.data();
+
+
+Stack Operations
+
+push_back(x) Add an element after the last element
+pop_back(x) Remove the last element.
+
+List operations
+
+implemented by std::vector but not by shared_vector
+
+insert(p,x) Add x before p
+...
+
+
+Other Operations
+
+operator== Do all elements of both containers compare equal.
+operator!= Does any element not compare equal.
+operator<< ostream operator
+swap(c2) Swap the contents of two shared_vectors of the same type.
+swap(c1,c2) Swap the contents of two shared_vectors of the same type.
+
+not implemented
+operator<
+operator<=
+operator>
+operator>=
+
+operators equals, not equals, and ostream
+
+template<typename A, typename B>
+bool operator==(const epics::pvData::shared_vector<A>& a,
+ const epics::pvData::shared_vector<B>& b);
+
+template<typename A, typename B>
+bool operator!=(const epics::pvData::shared_vector<A>& a,
+ const epics::pvData::shared_vector<B>& b);
+
+template<typename E>
+std::ostream& operator<<(
+ std::ostream& strm, const epics::pvData::shared_vector<E>& arr);
+
+
+swap
+
+ cout << "***exampleSwap***" << endl;
+ Int32Array first(8);
+ Int32Array second(16);
+ cout << " before swap size ";
+ cout<< "first " << first.size() << " second " << second.size() << endl;
+ first.swap(second);
+ cout << " after swap size ";
+ cout<< "first " << first.size() << " second " << second.size() << endl;
+ swap(first,second);
+ cout << " swap again size ";
+ cout<< "first " << first.size() << " second " << second.size() << endl;
+
+produces:
+
+***exampleSwap***
+ before swap size first 8 second 16
+ after swap size first 16 second 8
+ swap again size first 8 second 16
+
+
+shared_vector specific operations
+
+void make_unique() Make caller the only user of std::tr1::shared_ptr
+bool unique() Is the caller the only user of std::tr1::shared_ptr
+void slice(offset,length) Change window offset andsize
+
+// following should only be used for debugging
+const std::tr1::shared_ptr<E>&
+ dataPtr() Return const shared_ptr
+size_t dataOffset() Return offset.
+size_t dataCount() Return count which is also the size
+size_t dataTotal() Return total number of elements between
+ offset and end of the raw array
+
+// following converts from type FROM to type TO
+shared_vector
+make_unique and unique
+
+void make_unique();
+bool unique() const;
+
+
+
+slice
+
+void slice(size_t offset, size_t length=(size_t)-1);
+
+
+static void exampleSlice()
+{
+ cout << "***exampleSlice***" << endl;
+ size_t max = 16;
+ Int32Array int32Array(max);
+ int32 value = 0;
+ for(Int32Array::iterator iter = int32Array.begin(); iter!=int32Array.end(); ++iter)
+ {
+ *iter = ++value;
+ }
+ dumpArray("int32Array",int32Array);
+ size_t offset = 0;
+ size_t length = 8;
+ Int32Array window1(int32Array);
+ window1.slice(offset,length);
+ dumpArray("window1",window1);
+ offset = 8;
+ length = 8;
+ Int32Array window2(int32Array);
+ window2.slice(offset,length);
+ dumpArray("window2",window2);
+ offset = 2;
+ length = 4;
+ Int32Array window3(window2);
+ window3.slice(offset,length);
+ dumpArray("window3",window3);
+}
+
+produces the following output:
+
+***exampleSlice***
+int32Array 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+window1 1 2 3 4 5 6 7 8
+window2 9 10 11 12 13 14 15 16
+window3 11 12 13 14
+
+dataPtr, dataOffset, dataCount, and dataTotal
+
+
+
+static void exampleDataEtc()
+{
+ cout << "***exampleDataEtc***" << endl;
+ size_t max = 16;
+ Int32Array int32Array(max);
+ long use_count = int32Array.dataPtr().use_count();
+ long offset = int32Array.dataOffset();
+ long count = int32Array.dataCount();
+ long total = int32Array.dataTotal();
+ cout << "use_count " << use_count;
+ cout << " offset " << offset;
+ cout << " count " << count;
+ cout << " total " << total << endl;
+}
+
+produces:
+
+***exampleDataEtc***
+use_count 1 offset 0 count 16 total 16
+
+
+
+static_shared_vector_cast
+const_shared_vector_cast
+specialization for untyped pointers
+pvDataApp/pv
+pvData.h
+
+PVArray
+
+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;
+ ...
+};
+
+
+
+
+PVScalarArray
+
+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;
+ ...
+}
+
+
+
+
+PVValueArray
+
+template<typename T>
+class PVValueArray : public PVScalarArray {
+public:
+ POINTER_DEFINITIONS(PVValueArray);
+ typedef T value_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef PVArrayData<T> ArrayDataType;
+ typedef std::vector<T> vector;
+ typedef const std::vector<T> const_vector;
+ typedef std::tr1::shared_ptr<vector> shared_vector;
+ typedef PVValueArray & reference;
+ typedef const PVValueArray & const_reference;
+
+ virtual ~PVValueArray() {}
+ virtual std::size_t get(
+ std::size_t offset, std::size_t length, ArrayDataType &data) = 0;
+ virtual std::size_t put(std::size_t offset,
+ std::size_t length, const_pointer from, std::size_t fromOffset) = 0;
+ virtual std::size_t put(std::size_t offset,
+ std::size_t length, const_vector &from, std::size_t fromOffset);
+ virtual void shareData(
+ shared_vector const & value,
+ std::size_t capacity,
+ std::size_t length) = 0;
+ virtual pointer get() = 0;
+ virtual pointer get() const = 0;
+ virtual vector const & getVector() = 0;
+ virtual shared_vector const & getSharedVector() = 0;
+ std::ostream& dumpValue(std::ostream& o) const;
+ std::ostream& dumpValue(std::ostream& o, size_t index) const;
+protected:
+ PVValueArray(ScalarArrayConstPtr const & scalar)
+ : PVScalarArray(scalar) {}
+ friend class PVDataCreate;
+};
+
+template<typename T>
+std::size_t PVValueArray<T>::put(
+ std::size_t offset,
+ std::size_t length,
+ const_vector &from,
+ std::size_t fromOffset)
+{ return put(offset,length, &from[0], fromOffset); }
+
+/**
+ * Definitions for the various scalarArray types.
+ */
+typedef PVArrayData<uint8> BooleanArrayData;
+typedef PVValueArray<uint8> PVBooleanArray;
+typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
+
+typedef PVArrayData<int8> ByteArrayData;
+typedef PVValueArray<int8> PVByteArray;
+typedef std::tr1::shared_ptr<PVByteArray> PVByteArrayPtr;
+
+typedef PVArrayData<int16> ShortArrayData;
+typedef PVValueArray<int16> PVShortArray;
+typedef std::tr1::shared_ptr<PVShortArray> PVShortArrayPtr;
+
+typedef PVArrayData<int32> IntArrayData;
+typedef PVValueArray<int32> PVIntArray;
+typedef std::tr1::shared_ptr<PVIntArray> PVIntArrayPtr;
+
+typedef PVArrayData<int64> LongArrayData;
+typedef PVValueArray<int64> PVLongArray;
+typedef std::tr1::shared_ptr<PVLongArray> PVLongArrayPtr;
+
+typedef PVArrayData<uint8> UByteArrayData;
+typedef PVValueArray<uint8> PVUByteArray;
+typedef std::tr1::shared_ptr<PVUByteArray> PVUByteArrayPtr;
+
+typedef PVArrayData<uint16> UShortArrayData;
+typedef PVValueArray<uint16> PVUShortArray;
+typedef std::tr1::shared_ptr<PVUShortArray> PVUShortArrayPtr;
+
+typedef PVArrayData<uint32> UIntArrayData;
+typedef PVValueArray<uint32> PVUIntArray;
+typedef std::tr1::shared_ptr<PVUIntArray> PVUIntArrayPtr;
+
+typedef PVArrayData<uint64> ULongArrayData;
+typedef PVValueArray<uint64> PVULongArray;
+typedef std::tr1::shared_ptr<PVULongArray> PVULongArrayPtr;
+
+typedef PVArrayData<float> FloatArrayData;
+typedef PVValueArray<float> PVFloatArray;
+typedef std::tr1::shared_ptr<PVFloatArray> PVFloatArrayPtr;
+
+typedef PVArrayData<double> DoubleArrayData;
+typedef PVValueArray<double> PVDoubleArray;
+typedef std::tr1::shared_ptr<PVDoubleArray> PVDoubleArrayPtr;
+
+typedef PVArrayData<String> StringArrayData;
+typedef PVValueArray<String> PVStringArray;
+typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
+
+
+
+
+
+ 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.
+
+
+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;
+ }
+}
+
+
+
+EPICS Array
-EPICS v4 Working Group, Working Draft, 13-Jun-2013
+EPICS v4 Working Group, Working Draft, 18-Jun-2013
This is the documentation for the scalarArray data type as defined by pvDataCPP-md. -When complete it will be merged into pvDataCPP.html. -Only sharedVector is currently documented. -It is documented in the next section, but when merged into pvDataCPP.html, -will appear in a later section. -For now ignore the documentation in pvDataApp/pv.
-When NOTE EXISTING appears it means that there is a question about -the existing shared_vector implementation.
+This is the documentation for pvData.h as defined by pvDataCPP-md. +When complete it will be merged into pvDataCPP.html.
++pvData provides an interface for network accessible structured data. +The interfaces for C++ and Java are similar. +Thus someone who understands the interface in one of the languages +and knows both languages will quickly understand the interface of the other language. +With only a few exceptions the naming and other conventions do +not follow the C++ standard library conventions. +The definition of pvData is similar to the definition for Java. +The differences are mainly related to language differences. +Some differences are: +
There is one big difference from the existing Java implelentation: +The method PVValueArray::get. +As an example the Java definition for PVDoubleArray is currently: +
+ int get(int offset, int length, DoubleArrayData data); ++This document assumes this be replaced by: +
+ double[] get(); ++
The existing version allowed the data source to provide the array in chunks. +The new version assumes that the data source always provides contiguous storage +for the entire raw array. If this is accepted it simplifies a lot of code. +
+Three topics not discussed in this document are: +
+PVScalarArrayPtr createPVScalarArray(const PVScalarArray &, size_t offset, size_t length); ++ This will share the raw data array but allow a new window. +
This provides the interface for network accessible data. +Although templates are used to minimize the amount of code, +the interface is not meant to be extended. +Only the types defined by pvIntrospect are implemented.
+ ++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 std::ostream& operator<<(std::ostream& o) const; + std::ostream& operator<<(std::ostream& o, size_t index) const; +... +}; + +std::ostream& operator<<(std::ostream& o, const PVFieldPtr & f); +std::ostream& operator<<(std::ostream& o, const PVFieldPtr & f, size_t index); +
The public methods for PVField are:
+
+class PVScalar : public PVField {
+public:
+ POINTER_DEFINITIONS(PVScalar);
+ virtual ~PVScalar();
+
+ typedef PVScalar &reference;
+ typedef const PVScalar& const_reference;
+
+ const ScalarConstPtr getScalar() const;
+...
+};
+
+where
++template+ ++class PVScalarValue : public PVScalar { +public: + POINTER_DEFINITIONS(PVScalarValue); + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + + virtual ~PVScalarValue() {} + virtual T get() const = 0; + virtual void put(T value) = 0; + + std::ostream& operator<<(std::ostream& o) const + std::ostream& operator<<(std::ostream& o, size_t index) const; +... +}; +typedef PVScalarValue<uint8> PVBoolean; +typedef PVScalarValue<int8> PVByte; +typedef PVScalarValue<int16> PVShort; +typedef PVScalarValue<int32> PVInt; +typedef PVScalarValue<int64> PVLong; +typedef PVScalarValue<uint8> PVUByte; +typedef PVScalarValue<uint16> PVUShort; +typedef PVScalarValue<uint32> PVUInt; +typedef PVScalarValue<uint64> PVULong; +typedef PVScalarValue<float> PVFloat; +typedef PVScalarValue<double> PVDouble; +typedef std::tr1::shared_ptr<PVBoolean> PVBooleanPtr; +typedef std::tr1::shared_ptr<PVByte> PVBytePtr; +typedef std::tr1::shared_ptr<PVShort> PVShortPtr; +typedef std::tr1::shared_ptr<PVInt> PVIntPtr; +typedef std::tr1::shared_ptr<PVLong> PVLongPtr; +typedef std::tr1::shared_ptr<PVUByte> PVUBytePtr; +typedef std::tr1::shared_ptr<PVUShort> PVUShortPtr; +typedef std::tr1::shared_ptr<PVUInt> PVUIntPtr; +typedef std::tr1::shared_ptr<PVULong> PVULongPtr; +typedef std::tr1::shared_ptr<PVFloat> PVFloatPtr; +typedef std::tr1::shared_ptr<PVDouble> PVDoublePtr; + +// PVString is special case, since it implements SerializableArray +class PVString : public PVScalarValue<String>, SerializableArray { +public: + virtual ~PVString() {} + ... +}; +
where
+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 {
+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;
+ ...
+};
+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 {
+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() {}
+ ...
+};
+
+
+where
+This is a template class plus instances for PVBooleanArray, ..., +PVStringArray.
+template<typename T>
+class PVValueArray :
+public PVScalarArray
+...
+{
+public:
+ POINTER_DEFINITIONS(PVValueArray);
+ typedef T value_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef PVValueArray & reference;
+ typedef const PVValueArray & const_reference;
+
+ typedef shared_vector<T> svector;
+ typedef shared_vector<const T> const_svector;
+
+ virtual ~PVValueArray() {}
+ const_svector & get();
+ size_t put(size_t offset,size_t length, const_svector &from, size_t fromOffset);
+
+ void shareData(const_svector &from);
+
+ virtual std::ostream& operator<<(std::ostream& o) const;
+ std::ostream& operator<<(std::ostream& o, size_t index) const;
+...
+};
+
+typedef PVValueArray<uint8> PVBooleanArray;
+typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
+
+typedef PVValueArray<int8> PVByteArray;
+typedef std::tr1::shared_ptr<PVByteArray> PVByteArrayPtr;
+
+typedef PVValueArray<int16> PVShortArray;
+typedef std::tr1::shared_ptr<PVShortArray> PVShortArrayPtr;
+
+typedef PVValueArray<int32> PVIntArray;
+typedef std::tr1::shared_ptr<PVIntArray> PVIntArrayPtr;
+
+typedef PVValueArray<int64> PVLongArray;
+typedef std::tr1::shared_ptr<PVLongArray> PVLongArrayPtr;
+
+typedef PVValueArray<uint8> PVUByteArray;
+typedef std::tr1::shared_ptr<PVUByteArray> PVUByteArrayPtr;
+
+typedef PVValueArray<uint16> PVUShortArray;
+typedef std::tr1::shared_ptr<PVUShortArray> PVUShortArrayPtr;
+
+typedef PVValueArray<uint32> PVUIntArray;
+typedef std::tr1::shared_ptr<PVUIntArray> PVUIntArrayPtr;
+
+typedef PVValueArray<uint64> PVULongArray;
+typedef std::tr1::shared_ptr<PVULongArray> PVULongArrayPtr;
+
+typedef PVValueArray<float> PVFloatArray;
+typedef std::tr1::shared_ptr<PVFloatArray> PVFloatArrayPtr;
+
+typedef PVValueArray<double> PVDoubleArray;
+typedef std::tr1::shared_ptr<PVDoubleArray> PVDoubleArrayPtr;
+
+typedef PVValueArray<String> PVStringArray;
+typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
+
+
+where
+When NOTE EXISTING appears it means that there is a question about +the existing shared_vector implementation.
A shared_vector is a container as defined by the C++ standard library. It is like std::vector but provides two additional features @@ -738,260 +1124,6 @@ use_count 1 offset 0 count 16 total 16
Not yet documented
-INGORE REST OF DOCUMENT!!!!
-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 {
-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;
- ...
-};
-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 {
-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;
- ...
-}
-
-where
-This is a template class plus instances for PVBooleanArray, ..., -PVStringArray.
-template<typename T>
-class PVValueArray : public PVScalarArray {
-public:
- POINTER_DEFINITIONS(PVValueArray);
- typedef T value_type;
- typedef T* pointer;
- typedef const T* const_pointer;
- typedef PVArrayData<T> ArrayDataType;
- typedef std::vector<T> vector;
- typedef const std::vector<T> const_vector;
- typedef std::tr1::shared_ptr<vector> shared_vector;
- typedef PVValueArray & reference;
- typedef const PVValueArray & const_reference;
-
- virtual ~PVValueArray() {}
- virtual std::size_t get(
- std::size_t offset, std::size_t length, ArrayDataType &data) = 0;
- virtual std::size_t put(std::size_t offset,
- std::size_t length, const_pointer from, std::size_t fromOffset) = 0;
- virtual std::size_t put(std::size_t offset,
- std::size_t length, const_vector &from, std::size_t fromOffset);
- virtual void shareData(
- shared_vector const & value,
- std::size_t capacity,
- std::size_t length) = 0;
- virtual pointer get() = 0;
- virtual pointer get() const = 0;
- virtual vector const & getVector() = 0;
- virtual shared_vector const & getSharedVector() = 0;
- std::ostream& dumpValue(std::ostream& o) const;
- std::ostream& dumpValue(std::ostream& o, size_t index) const;
-protected:
- PVValueArray(ScalarArrayConstPtr const & scalar)
- : PVScalarArray(scalar) {}
- friend class PVDataCreate;
-};
-
-template<typename T>
-std::size_t PVValueArray<T>::put(
- std::size_t offset,
- std::size_t length,
- const_vector &from,
- std::size_t fromOffset)
-{ return put(offset,length, &from[0], fromOffset); }
-
-/**
- * Definitions for the various scalarArray types.
- */
-typedef PVArrayData<uint8> BooleanArrayData;
-typedef PVValueArray<uint8> PVBooleanArray;
-typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
-
-typedef PVArrayData<int8> ByteArrayData;
-typedef PVValueArray<int8> PVByteArray;
-typedef std::tr1::shared_ptr<PVByteArray> PVByteArrayPtr;
-
-typedef PVArrayData<int16> ShortArrayData;
-typedef PVValueArray<int16> PVShortArray;
-typedef std::tr1::shared_ptr<PVShortArray> PVShortArrayPtr;
-
-typedef PVArrayData<int32> IntArrayData;
-typedef PVValueArray<int32> PVIntArray;
-typedef std::tr1::shared_ptr<PVIntArray> PVIntArrayPtr;
-
-typedef PVArrayData<int64> LongArrayData;
-typedef PVValueArray<int64> PVLongArray;
-typedef std::tr1::shared_ptr<PVLongArray> PVLongArrayPtr;
-
-typedef PVArrayData<uint8> UByteArrayData;
-typedef PVValueArray<uint8> PVUByteArray;
-typedef std::tr1::shared_ptr<PVUByteArray> PVUByteArrayPtr;
-
-typedef PVArrayData<uint16> UShortArrayData;
-typedef PVValueArray<uint16> PVUShortArray;
-typedef std::tr1::shared_ptr<PVUShortArray> PVUShortArrayPtr;
-
-typedef PVArrayData<uint32> UIntArrayData;
-typedef PVValueArray<uint32> PVUIntArray;
-typedef std::tr1::shared_ptr<PVUIntArray> PVUIntArrayPtr;
-
-typedef PVArrayData<uint64> ULongArrayData;
-typedef PVValueArray<uint64> PVULongArray;
-typedef std::tr1::shared_ptr<PVULongArray> PVULongArrayPtr;
-
-typedef PVArrayData<float> FloatArrayData;
-typedef PVValueArray<float> PVFloatArray;
-typedef std::tr1::shared_ptr<PVFloatArray> PVFloatArrayPtr;
-
-typedef PVArrayData<double> DoubleArrayData;
-typedef PVValueArray<double> PVDoubleArray;
-typedef std::tr1::shared_ptr<PVDoubleArray> PVDoubleArrayPtr;
-
-typedef PVArrayData<String> StringArrayData;
-typedef PVValueArray<String> PVStringArray;
-typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
-
-where
-Both get and put return the number of elements actually transfered. The -arguments are:
-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;
- }
-}
-
-