Files
pvData/src/pv/pvIntrospect.h

1207 lines
34 KiB
C++

/* pvIntrospect.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk and Michael Davidsaver
*/
#ifndef PVINTROSPECT_H
#define PVINTROSPECT_H
#include <string>
#include <stdexcept>
#include <iostream>
#include <pv/noDefaultMethods.h>
#include <pv/pvType.h>
#include <pv/byteBuffer.h>
#include <pv/serialize.h>
#include <shareLib.h>
namespace epics { namespace pvData {
namespace format {
struct indent_level
{
long level;
indent_level(long l) : level(l) {}
};
inline long& indent_value(std::ios_base& ios)
{
static int indent_index = std::ios_base::xalloc();
return ios.iword(indent_index);
}
epicsShareExtern std::ostream& operator<<(std::ostream& os, indent_level const& indent);
struct indent_scope
{
long saved_level;
std::ios_base& stream;
indent_scope(std::ios_base& ios) :
stream(ios)
{
long& l = indent_value(ios);
saved_level = l;
l = saved_level + 1;
}
~indent_scope()
{
indent_value(stream) = saved_level;
}
};
struct indent
{
};
epicsShareExtern std::ostream& operator<<(std::ostream& os, indent const&);
struct array_at
{
std::size_t index;
array_at(std::size_t ix) : index(ix) {}
};
struct array_at_internal
{
std::size_t index;
std::ostream& stream;
array_at_internal(std::size_t ix, std::ostream& str) : index(ix), stream(str) {}
};
epicsShareExtern array_at_internal operator<<(std::ostream& str, array_at const& manip);
};
class Field;
class Scalar;
class Array;
class ScalarArray;
class Structure;
class StructureArray;
class Union;
class UnionArray;
class BoundedString;
/**
* typedef for a shared pointer to an immutable Field.
*/
typedef std::tr1::shared_ptr<const Field> FieldConstPtr;
/**
* typedef for an array of shared pointer to an immutable Field.
*/
typedef std::vector<FieldConstPtr> FieldConstPtrArray;
/**
* typedef for a shared pointer to an immutable Scalar.
*/
typedef std::tr1::shared_ptr<const Scalar> ScalarConstPtr;
/**
* typedef for a shared pointer to an immutable Array.
*/
typedef std::tr1::shared_ptr<const Array> ArrayConstPtr;
/**
* typedef for a shared pointer to an immutable ScalarArray.
*/
typedef std::tr1::shared_ptr<const ScalarArray> ScalarArrayConstPtr;
/**
* typedef for a shared pointer to an immutable Structure.
*/
typedef std::tr1::shared_ptr<const Structure> StructureConstPtr;
/**
* typedef for a shared pointer to an immutable StructureArray.
*/
typedef std::tr1::shared_ptr<const StructureArray> StructureArrayConstPtr;
/**
* typedef for a shared pointer to an immutable Union.
*/
typedef std::tr1::shared_ptr<const Union> UnionConstPtr;
/**
* typedef for a shared pointer to an immutable UnionArray.
*/
typedef std::tr1::shared_ptr<const UnionArray> UnionArrayConstPtr;
/**
* typedef for a shared pointer to an immutable BoundedString.
*/
typedef std::tr1::shared_ptr<const BoundedString> BoundedStringConstPtr;
/**
* Definition of support field types.
*/
enum Type {
/**
* The type is scalar. It has a scalarType
*/
scalar,
/**
* The type is scalarArray. Each element is a scalar of the same scalarType.
*/
scalarArray,
/**
* The type is structure.
*/
structure,
/**
* The type is structureArray. Each element is a structure.
*/
structureArray,
/**
* The type is an union.
*/
union_,
/**
* The type is an array of unions.
*/
unionArray
};
/**
* Convenience functions for Type.
*/
namespace TypeFunc {
/**
* Get a name for the type.
* @param type The type.
* @return The name for the type.
*/
epicsShareExtern const char* name(Type type);
};
epicsShareExtern std::ostream& operator<<(std::ostream& o, const Type& type);
/**
* Definition of support scalar types.
*/
enum ScalarType {
/**
* The type is boolean, i. e. value can be {@code false} or {@code true}
*/
pvBoolean,
/**
* The type is byte, i. e. a 8 bit signed integer.
*/
pvByte,
/**
* The type is short, i. e. a 16 bit signed integer.
*/
pvShort,
/**
* The type is int, i. e. a 32 bit signed integer.
*/
pvInt,
/**
* The type is long, i. e. a 64 bit signed integer.
*/
pvLong,
/**
* The type is unsigned byte, i. e. a 8 bit unsigned integer.
*/
pvUByte,
/**
* The type is unsigned short, i. e. a 16 bit unsigned integer.
*/
pvUShort,
/**
* The type is unsigned int, i. e. a 32 bit unsigned integer.
*/
pvUInt,
/**
* The type is unsigned long, i. e. a 64 bit unsigned integer.
*/
pvULong,
/**
* The type is float, i. e. 32 bit IEEE floating point,
*/
pvFloat,
/**
* The type is float, i. e. 64 bit IEEE floating point,
*/
pvDouble,
/**
* The type is string, i. e. a UTF8 character string.
*/
pvString
};
#define MAX_SCALAR_TYPE pvString
/**
* Convenience functions for ScalarType.
*/
namespace ScalarTypeFunc {
/**
* Is the type an integer, i. e. is it one of byte,...ulong
* @param scalarType The type.
* @return (false,true) if the scalarType is an integer.
*/
epicsShareExtern bool isInteger(ScalarType scalarType);
/**
* Is the type an unsigned integer, i. e. is it one of ubyte,...ulong
* @param scalarType The type.
* @return (false,true) if the scalarType is an integer.
*/
epicsShareExtern bool isUInteger(ScalarType scalarType);
/**
* Is the type numeric, i. e. is it one of byte,...,double
* @param scalarType The type.
* @return (false,true) if the scalarType is a numeric
*/
epicsShareExtern bool isNumeric(ScalarType scalarType);
/**
* Is the type primitive, i. e. not string
* @param scalarType The type.
* @return (false,true) if the scalarType is primitive.
*/
epicsShareExtern bool isPrimitive(ScalarType scalarType);
/**
* Get the scalarType for value.
* @param value The name of the scalar type.
* @return The scalarType.
* An exception is thrown if the name is not the name of a scalar type.
*/
epicsShareExtern ScalarType getScalarType(std::string const &value);
/**
* Get a name for the scalarType.
* @param scalarType The type.
* @return The name for the scalarType.
*/
epicsShareExtern const char* name(ScalarType scalarType);
//! gives sizeof(T) where T depends on the scalar type id.
epicsShareExtern size_t elementSize(ScalarType id);
};
epicsShareExtern std::ostream& operator<<(std::ostream& o, const ScalarType& scalarType);
/**
* This class implements introspection object for field.
*/
class epicsShareClass Field :
virtual public Serializable,
public std::tr1::enable_shared_from_this<Field> {
public:
POINTER_DEFINITIONS(Field);
/**
* Destructor.
*/
virtual ~Field();
/**
* Get the field type.
* @return The type.
*/
Type getType() const{return m_fieldType;}
/**
* Get the identification string.
* @return The identification string, can be empty.
*/
virtual std::string getID() const = 0;
/**
* Puts the string representation to the stream.
* @param o output stream.
* @return The output stream.
*/
virtual std::ostream& dump(std::ostream& o) const = 0;
protected:
/**
* Constructor
* @param fieldName The field type.
*/
Field(Type type);
private:
Type m_fieldType;
friend class StructureArray;
friend class Structure;
friend class PVFieldPvt;
friend class StandardField;
friend class BasePVStructureArray;
friend class FieldCreate;
struct Deleter{void operator()(Field *p){delete p;}};
};
epicsShareExtern std::ostream& operator<<(std::ostream& o, const Field& field);
/**
* This class implements introspection object for Scalar.
*/
class epicsShareClass Scalar : public Field{
public:
POINTER_DEFINITIONS(Scalar);
/**
* Destructor.
*/
virtual ~Scalar();
typedef Scalar& reference;
typedef const Scalar& const_reference;
/**
* Get the scalarType
* @return the scalarType
*/
ScalarType getScalarType() const {return scalarType;}
virtual std::string getID() const;
virtual std::ostream& dump(std::ostream& o) const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
protected:
Scalar(ScalarType scalarType);
private:
static int8 getTypeCodeLUT(ScalarType scalarType);
ScalarType scalarType;
friend class FieldCreate;
friend class ScalarArray;
friend class BoundedScalarArray;
friend class FixedScalarArray;
friend class BoundedString;
};
/**
* This class implements introspection object for BoundedString.
*/
class epicsShareClass BoundedString : public Scalar{
public:
POINTER_DEFINITIONS(BoundedString);
/**
* Destructor.
*/
virtual ~BoundedString();
typedef BoundedString& reference;
typedef const BoundedString& const_reference;
virtual std::string getID() const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
std::size_t getMaximumLength() const;
protected:
BoundedString(std::size_t maxStringLength);
private:
std::size_t maxLength;
friend class FieldCreate;
};
/**
* This class implements introspection object for Array.
*/
class epicsShareClass Array : public Field{
public:
POINTER_DEFINITIONS(Array);
/**
* Destructor.
*/
virtual ~Array();
typedef Array& reference;
typedef const Array& const_reference;
enum ArraySizeType { variable, fixed, bounded };
/**
* Get array size type (i.e. variable/fixed/bounded size array).
* @return array size type enum.
*/
virtual ArraySizeType getArraySizeType() const = 0;
/**
* Get maximum capacity of the array.
* @return maximum capacity of the array, 0 indicates variable size array.
*/
virtual std::size_t getMaximumCapacity() const = 0;
protected:
/**
* Constructor
* @param fieldName The field type.
*/
Array(Type type);
};
/**
* This class implements introspection object for scalar array.
*/
class epicsShareClass ScalarArray : public Array{
public:
POINTER_DEFINITIONS(ScalarArray);
typedef ScalarArray& reference;
typedef const ScalarArray& const_reference;
/**
* Constructor
* @param scalarType The scalarType for the field.
*/
ScalarArray(ScalarType scalarType);
/**
* Get the scalarType for the elements.
* @return the scalarType
*/
ScalarType getElementType() const {return elementType;}
virtual ArraySizeType getArraySizeType() const {return Array::variable;}
virtual std::size_t getMaximumCapacity() const {return 0;}
virtual std::string getID() const;
virtual std::ostream& dump(std::ostream& o) const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
protected:
/**
* Destructor.
*/
virtual ~ScalarArray();
private:
const std::string getIDScalarArrayLUT() const;
ScalarType elementType;
friend class FieldCreate;
};
/**
* This class implements introspection object for bounded scalar array.
*/
class epicsShareClass BoundedScalarArray : public ScalarArray{
public:
POINTER_DEFINITIONS(BoundedScalarArray);
typedef BoundedScalarArray& reference;
typedef const BoundedScalarArray& const_reference;
/**
* Constructor
* @param scalarType The scalarType for the field.
* @param size maximum (bound) capacity.
*/
BoundedScalarArray(ScalarType scalarType, std::size_t size);
virtual ArraySizeType getArraySizeType() const {return Array::bounded;}
virtual std::size_t getMaximumCapacity() const {return size;}
virtual std::string getID() const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
protected:
/**
* Destructor.
*/
virtual ~BoundedScalarArray();
private:
std::size_t size;
friend class FieldCreate;
};
/**
* This class implements introspection object for bounded scalar array.
*/
class epicsShareClass FixedScalarArray : public ScalarArray{
public:
POINTER_DEFINITIONS(FixedScalarArray);
typedef FixedScalarArray& reference;
typedef const FixedScalarArray& const_reference;
/**
* Constructor
* @param scalarType The scalarType for the field.
* @param size maximum (bound) capacity.
*/
FixedScalarArray(ScalarType scalarType, std::size_t size);
virtual ArraySizeType getArraySizeType() const {return Array::fixed;}
virtual std::size_t getMaximumCapacity() const {return size;}
virtual std::string getID() const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
protected:
/**
* Destructor.
*/
virtual ~FixedScalarArray();
private:
std::size_t size;
friend class FieldCreate;
};
/**
* This class implements introspection object for a structureArray
*/
class epicsShareClass StructureArray : public Array{
public:
POINTER_DEFINITIONS(StructureArray);
typedef StructureArray& reference;
typedef const StructureArray& const_reference;
/**
* Get the introspection interface for the array elements.
* @return The introspection interface.
*/
StructureConstPtr getStructure() const {return pstructure;}
virtual ArraySizeType getArraySizeType() const {return Array::variable;}
virtual std::size_t getMaximumCapacity() const {return 0;}
virtual std::string getID() const;
virtual std::ostream& dump(std::ostream& o) const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
protected:
/**
* Constructor.
* @param structure The introspection interface for the elements.
*/
StructureArray(StructureConstPtr const & structure);
/**
* Destructor.
*/
virtual ~StructureArray();
private:
StructureConstPtr pstructure;
friend class FieldCreate;
};
/**
* This class implements introspection object for a unionArray
*/
class epicsShareClass UnionArray : public Array{
public:
POINTER_DEFINITIONS(UnionArray);
typedef UnionArray& reference;
typedef const UnionArray& const_reference;
/**
* Get the introspection interface for the array elements.
* @return The introspection interface.
*/
UnionConstPtr getUnion() const {return punion;}
virtual ArraySizeType getArraySizeType() const {return Array::variable;}
virtual std::size_t getMaximumCapacity() const {return 0;}
virtual std::string getID() const;
virtual std::ostream& dump(std::ostream& o) const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
protected:
/**
* Constructor.
* @param union The introspection interface for the elements.
*/
UnionArray(UnionConstPtr const & _punion);
/**
* Destructor.
*/
virtual ~UnionArray();
private:
UnionConstPtr punion;
friend class FieldCreate;
};
/**
* This class implements introspection object for a structure.
*/
class epicsShareClass Structure : public Field {
public:
POINTER_DEFINITIONS(Structure);
/**
* Default structure ID.
*/
static std::string DEFAULT_ID;
/**
* Destructor.
*/
virtual ~Structure();
typedef Structure& reference;
typedef const Structure& const_reference;
/**
* Get the number of immediate subfields in the structure.
* @return The number of fields.
*/
std::size_t getNumberFields() const {return fieldNames.size();}
/**
* Get the field for the specified fieldName.
* @param fieldName The name of the field to get;
* @return The introspection interface.
* This will hold a null pointer if the field is not in the structure.
*/
FieldConstPtr getField(std::string const &fieldName) const;
/**
* Get the field for the specified fieldName.
* @param fieldName The index of the field to get;
* @return The introspection interface.
* This will hold a null pointer if the field is not in the structure.
*/
FieldConstPtr getField(std::size_t index) const {return fields[index];}
/**
* Get the field index for the specified fieldName.
* @return The introspection interface.
* This will be -1 if the field is not in the structure.
*/
std::size_t getFieldIndex(std::string const &fieldName) const;
/**
* Get the fields in the structure.
* @return The array of fields.
*/
FieldConstPtrArray const & getFields() const {return fields;}
/**
* Get the names of the fields in the structure.
* @return The array of fieldNames.
*/
StringArray const & getFieldNames() const {return fieldNames;}
/**
* Get the name of the field with the specified index;
* @param fieldIndex The index of the desired field.
* @return The fieldName.
*/
std::string getFieldName(std::size_t fieldIndex) const {return fieldNames[fieldIndex];}
virtual std::string getID() const;
virtual std::ostream& dump(std::ostream& o) const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
protected:
Structure(StringArray const & fieldNames, FieldConstPtrArray const & fields, std::string const & id = DEFAULT_ID);
private:
StringArray fieldNames;
FieldConstPtrArray fields;
std::string id;
virtual void dumpFields(std::ostream& o) const;
friend class FieldCreate;
friend class Union;
};
/**
* This class implements introspection object for a union.
*/
class epicsShareClass Union : public Field {
public:
POINTER_DEFINITIONS(Union);
/**
* Default union ID.
*/
static std::string DEFAULT_ID;
/**
* Default variant union ID.
*/
static std::string ANY_ID;
/**
* Destructor.
*/
virtual ~Union();
typedef Union& reference;
typedef const Union& const_reference;
/**
* Get the number of immediate subfields in the union.
* @return The number of fields.
*/
std::size_t getNumberFields() const {return fieldNames.size();}
/**
* Get the field for the specified fieldName.
* @param fieldName The name of the field to get;
* @return The introspection interface.
* This will hold a null pointer if the field is not in the union.
*/
FieldConstPtr getField(std::string const &fieldName) const;
/**
* Get the field for the specified fieldName.
* @param fieldName The index of the field to get;
* @return The introspection interface.
* This will hold a null pointer if the field is not in the union.
*/
FieldConstPtr getField(std::size_t index) const {return fields[index];}
/**
* Get the field index for the specified fieldName.
* @return The introspection interface.
* This will be -1 if the field is not in the union.
*/
std::size_t getFieldIndex(std::string const &fieldName) const;
/**
* Get the fields in the union.
* @return The array of fields.
*/
FieldConstPtrArray const & getFields() const {return fields;}
/**
* Get the names of the fields in the union.
* @return The array of fieldNames.
*/
StringArray const & getFieldNames() const {return fieldNames;}
/**
* Get the name of the field with the specified index;
* @param fieldIndex The index of the desired field.
* @return The fieldName.
*/
std::string getFieldName(std::size_t fieldIndex) const {return fieldNames[fieldIndex];}
/**
* Check if this union is variant union (aka any type).
* @return <code>true</code> if this union is variant union, otherwise <code>false</code>.
*/
bool isVariant() const {return (fieldNames.size() == 0);}
virtual std::string getID() const;
virtual std::ostream& dump(std::ostream& o) const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
protected:
Union();
Union(StringArray const & fieldNames, FieldConstPtrArray const & fields, std::string const & id = DEFAULT_ID);
private:
StringArray fieldNames;
FieldConstPtrArray fields;
std::string id;
virtual void dumpFields(std::ostream& o) const;
friend class FieldCreate;
friend class Structure;
};
class FieldCreate;
typedef std::tr1::shared_ptr<FieldCreate> FieldCreatePtr;
class FieldBuilder;
typedef std::tr1::shared_ptr<FieldBuilder> FieldBuilderPtr;
/**
* Interface for in-line creating of introspection interfaces.
* One instance can be used to create multiple {@code Field} instances.
* An instance of this object must not be used concurrently (an object has a state).
* @author mse
*/
class epicsShareClass FieldBuilder :
public std::tr1::enable_shared_from_this<FieldBuilder>
{
public:
/**
* Set ID of an object to be created.
* @param id id to be set.
* @return this instance of a {@code FieldBuilder}.
*/
FieldBuilderPtr setId(std::string const & id);
/**
* Add a {@code Scalar}.
* @param name name of the array.
* @param scalarType type of a scalar to add.
* @return this instance of a {@code FieldBuilder}.
*/
FieldBuilderPtr add(std::string const & name, ScalarType scalarType);
/**
* Add a {@code BoundedString}.
* @param name name of the array.
* @param maxLength a string maximum length.
* @return this instance of a {@code FieldBuilder}.
*/
FieldBuilderPtr addBoundedString(std::string const & name, std::size_t maxLength);
/**
* Add a {@code Field} (e.g. {@code Structure}, {@code Union}).
* @param name name of the array.
* @param field a field to add.
* @return this instance of a {@code FieldBuilder}.
*/
FieldBuilderPtr add(std::string const & name, FieldConstPtr const & field);
/**
* Add variable size array of {@code Scalar} elements.
* @param name name of the array.
* @param scalarType type of a scalar element.
* @return this instance of a {@code FieldBuilder}.
*/
FieldBuilderPtr addArray(std::string const & name, ScalarType scalarType);
/**
* Add fixed-size array of {@code Scalar} elements.
* @param name name of the array.
* @param scalarType type of a scalar element.
* @param size Array fixed size.
* @return this instance of a {@code FieldBuilder}.
*/
FieldBuilderPtr addFixedArray(std::string const & name, ScalarType scalarType, std::size_t size);
/**
* Add bounded-size array of {@code Scalar} elements.
* @param name name of the array.
* @param scalarType type of a scalar element.
* @param bound Array maximum capacity (size).
* @return this instance of a {@code FieldBuilder}.
*/
FieldBuilderPtr addBoundedArray(std::string const & name, ScalarType scalarType, std::size_t bound);
/**
* Add array of {@code Field} elements.
* @param name name of the array.
* @param field a type of an array element.
* @return this instance of a {@code FieldBuilder}.
*/
FieldBuilderPtr addArray(std::string const & name, FieldConstPtr const & element);
/**
* Create a {@code Structure}.
* This resets this instance state and allows new {@code Field} instance to be created.
* @return a new instance of a {@code Structure}.
*/
StructureConstPtr createStructure();
/**
* Create an {@code Union}.
* This resets this instance state and allows new {@code Field} instance to be created.
* @return a new instance of an {@code Union}.
*/
UnionConstPtr createUnion();
/**
* Add new nested {@code Structure}.
* {@code endNested()} method must be called
* to complete creation of the nested {@code Structure}.
* @param name nested structure name.
* @return a new instance of a {@code FieldBuilder} is returned.
* @see #endNested()
*/
FieldBuilderPtr addNestedStructure(std::string const & name);
/**
* Add new nested {@code Union}.
* {@code endNested()} method must be called
* to complete creation of the nested {@code Union}.
* @param name nested union name.
* @return a new instance of a {@code FieldBuilder} is returned.
* @see #endNested()
*/
FieldBuilderPtr addNestedUnion(std::string const & name);
/**
* Add new nested {@code Structure[]}.
* {@code endNested()} method must be called
* to complete creation of the nested {@code Structure}.
* @param name nested structure name.
* @return a new instance of a {@code FieldBuilder} is returned.
* @see #endNested()
*/
FieldBuilderPtr addNestedStructureArray(std::string const & name);
/**
* Add new nested {@code Union[]}.
* {@code endNested()} method must be called
* to complete creation of the nested {@code Union}.
* @param name nested union name.
* @return a new instance of a {@code FieldBuilder} is returned.
* @see #endNested()
*/
FieldBuilderPtr addNestedUnionArray(std::string const & name);
/**
* Complete the creation of a nested object.
* @see #addNestedStructure(std::string)
* @see #addNestedUnion(std::string)
* @return a previous (parent) {@code FieldBuilder}.
*/
FieldBuilderPtr endNested();
private:
FieldBuilder();
FieldBuilder(FieldBuilderPtr const & parentBuilder,
std::string const & nestedName,
Type nestedClassToBuild, bool nestedArray);
void reset();
FieldConstPtr createFieldInternal(Type type);
friend class FieldCreate;
FieldCreatePtr fieldCreate;
std::string id;
bool idSet;
// NOTE: this preserves order, however it does not handle duplicates
StringArray fieldNames;
FieldConstPtrArray fields;
FieldBuilderPtr parentBuilder;
Type nestedClassToBuild;
std::string nestedName;
bool nestedArray;
};
/**
* This is a singleton class for creating introspection interfaces.
*/
class epicsShareClass FieldCreate {
public:
static FieldCreatePtr getFieldCreate();
/**
* Create a new instance of in-line {@code Field} builder.
* @return a new instance of a {@code FieldBuilder}.
*/
FieldBuilderPtr createFieldBuilder() const;
/**
* Create a {@code ScalarField}.
* @param scalarType The scalar type.
* @return a {@code Scalar} interface for the newly created object.
* @throws An {@code IllegalArgumentException} if an illegal type is specified.
*/
ScalarConstPtr createScalar(ScalarType scalarType) const;
/**
* Create a {@code BoundedString}.
* @param maxLength a string maximum length.
* @return a {@code BoundedString} interface for the newly created object.
* @throws An {@code IllegalArgumentException} if maxLength == 0.
*/
BoundedStringConstPtr createBoundedString(std::size_t maxLength) const;
/**
* Create an {@code Array} field, variable size array.
* @param elementType The {@code scalarType} for array elements
* @return An {@code Array} Interface for the newly created object.
*/
ScalarArrayConstPtr createScalarArray(ScalarType elementType) const;
/*
* Create an {@code Array} field, fixed size array.
* @param elementType The {@code scalarType} for array elements
* @param size Fixed array size.
* @return An {@code Array} Interface for the newly created object.
*/
ScalarArrayConstPtr createFixedScalarArray(ScalarType elementType, std::size_t size) const;
/**
* Create an {@code Array} field, bounded size array.
* @param elementType The {@code scalarType} for array elements
* @param size Array maximum capacity (bound).
* @return An {@code Array} Interface for the newly created object.
*/
ScalarArrayConstPtr createBoundedScalarArray(ScalarType elementType, std::size_t bound) const;
/**
* Create an {@code Array} field that is has element type <i>Structure</i>
* @param fieldName The field name
* @param elementStructure The {@code Structure} for each array element.
* @return An {@code Array} Interface for the newly created object.
*/
StructureArrayConstPtr createStructureArray(StructureConstPtr const & structure) const;
/**
* Create a {@code Structure} field.
* @return a {@code Structure} interface for the newly created object.
*/
StructureConstPtr createStructure () const;
/**
* Create a {@code Structure} field.
* @param fieldNames The array of {@code fieldNames} for the structure.
* @param fields The array of {@code fields} for the structure.
* @return a {@code Structure} interface for the newly created object.
*/
StructureConstPtr createStructure (
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const;
/**
* Create a {@code Structure} field with identification string.
* @param id The identification string for the structure.
* @param fieldNames The array of {@code fieldNames} for the structure.
* @param fields The array of {@code fields} for the structure.
* @return a {@code Structure} interface for the newly created object.
*/
StructureConstPtr createStructure (
std::string const & id,
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const;
/**
* Create an {@code Array} field that is has element type <i>Union</i>
* @param fieldName The field name
* @param elementUnion The {@code Union} for each array element.
* @return An {@code Array} Interface for the newly created object.
*/
UnionArrayConstPtr createUnionArray(UnionConstPtr const & punion) const;
/**
* Create a variant {@code UnionArray} (aka any type) field.
* @return a {@code UnionArray} interface for the newly created object.
*/
UnionArrayConstPtr createVariantUnionArray() const;
/**
* Create a variant {@code Union} (aka any type) field.
* @return a {@code Union} interface for the newly created object.
*/
UnionConstPtr createVariantUnion() const;
/**
* Create a {@code Union} field.
* @param fieldNames The array of {@code fieldNames} for the union.
* @param fields The array of {@code fields} for the union.
* @return a {@code Union} interface for the newly created object.
*/
UnionConstPtr createUnion (
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const;
/**
* Create a {@code Union} field with identification string.
* @param id The identification string for the union.
* @param fieldNames The array of {@code fieldNames} for the union.
* @param fields The array of {@code fields} for the union.
* @return a {@code Union} interface for the newly created object.
*/
UnionConstPtr createUnion (
std::string const & id,
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const;
/**
* Append a field to a structure.
* @param structure The structure to which the field is appended.
* @param fieldName The name of the field.
* @param field The field.
* @return a {@code Structure} interface for the newly created object.
*/
StructureConstPtr appendField(
StructureConstPtr const & structure,
std::string const & fieldName, FieldConstPtr const & field) const;
/**
* Append fields to a structure.
* @param structure The structure to which the fields appended.
* @param fieldName The names of the fields.
* @param field The fields.
* @return a {@code Structure} interface for the newly created object.
*/
StructureConstPtr appendFields(
StructureConstPtr const & structure,
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const;
/**
* Deserialize {@code Field} instance from given byte buffer.
* @param buffer Buffer containing serialized {@code Field} instance.
* @param control Deserialization control instance.
* @return a deserialized {@code Field} instance.
*/
FieldConstPtr deserialize(ByteBuffer* buffer, DeserializableControl* control) const;
private:
FieldCreate();
std::vector<ScalarConstPtr> scalars;
std::vector<ScalarArrayConstPtr> scalarArrays;
UnionConstPtr variantUnion;
UnionArrayConstPtr variantUnionArray;
};
/**
* Get the single class that implemnents FieldCreate,
* @param The fieldCreate factory.
*/
epicsShareExtern FieldCreatePtr getFieldCreate();
/** Define a compile time mapping from
* type to enum value.
@code
ScalarType code = (ScalarType)ScalarTypeID<int8>::value;
assert(code==pvByte);
@endcode
*
* For unspecified types this evaluates to an invalid ScalarType
* value (eg -1).
*/
template<typename T>
struct ScalarTypeID {};
/**
* Static mapping from ScalarType enum to value type.
@code
typename ScalarTypeTraits<pvByte>::type value = 4;
@endcode
*/
template<ScalarType ID>
struct ScalarTypeTraits {};
#define OP(ENUM, TYPE) \
template<> struct ScalarTypeTraits<ENUM> {typedef TYPE type;}; \
template<> struct ScalarTypeID<TYPE> { enum {value=ENUM}; }; \
template<> struct ScalarTypeID<const TYPE> { enum {value=ENUM}; };
OP(pvBoolean, boolean)
OP(pvByte, int8)
OP(pvShort, int16)
OP(pvInt, int32)
OP(pvLong, int64)
OP(pvUByte, uint8)
OP(pvUShort, uint16)
OP(pvUInt, uint32)
OP(pvULong, uint64)
OP(pvFloat, float)
OP(pvDouble, double)
OP(pvString, std::string)
#undef OP
struct ScalarHashFunction {
size_t operator() (const Scalar& scalar) const { return scalar.getScalarType(); }
};
struct ScalarArrayHashFunction {
size_t operator() (const ScalarArray& scalarArray) const { return 0x10 | scalarArray.getElementType(); }
};
struct StructureHashFunction {
size_t operator() (const Structure& /*structure*/) const { return 0; }
// TODO hash
// final int PRIME = 31;
// return PRIME * Arrays.hashCode(fieldNames) + Arrays.hashCode(fields);
};
struct StructureArrayHashFunction {
size_t operator() (const StructureArray& structureArray) const { StructureHashFunction shf; return (0x10 | shf(*(structureArray.getStructure()))); }
};
}}
#endif /* PVINTROSPECT_H */